author | Daniel Holbert <dholbert@cs.stanford.edu> |
Thu, 26 Feb 2015 12:07:05 -0800 | |
changeset 231128 | dcb4cdcbb5c22491035e0974bfd47f79f15056b3 |
parent 231127 | dc3c7c5d75a7f56e4eba25acc9bdbd8494639362 |
child 231129 | f008bde94e233f84f7240fdce6bbebaa39493598 |
push id | 28344 |
push user | ryanvm@gmail.com |
push date | Fri, 27 Feb 2015 18:20:08 +0000 |
treeherder | mozilla-central@9dd9d1e5b43c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dbaron |
bugs | 1107378 |
milestone | 39.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -532,16 +532,18 @@ @BINPATH@/components/satchel.manifest @BINPATH@/components/nsFormAutoComplete.js @BINPATH@/components/nsFormHistory.js @BINPATH@/components/FormHistoryStartup.js @BINPATH@/components/nsInputListAutoComplete.js @BINPATH@/components/formautofill.manifest @BINPATH@/components/FormAutofillContentService.js @BINPATH@/components/FormAutofillStartup.js +@BINPATH@/components/CSSUnprefixingService.js +@BINPATH@/components/CSSUnprefixingService.manifest @BINPATH@/components/contentAreaDropListener.manifest @BINPATH@/components/contentAreaDropListener.js @BINPATH@/components/messageWakeupService.js @BINPATH@/components/messageWakeupService.manifest @BINPATH@/components/SettingsManager.js @BINPATH@/components/SettingsManager.manifest @BINPATH@/components/SettingsService.js @BINPATH@/components/SettingsService.manifest
--- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -471,16 +471,18 @@ @RESPATH@/components/satchel.manifest @RESPATH@/components/nsFormAutoComplete.js @RESPATH@/components/nsFormHistory.js @RESPATH@/components/FormHistoryStartup.js @RESPATH@/components/nsInputListAutoComplete.js @RESPATH@/components/formautofill.manifest @RESPATH@/components/FormAutofillContentService.js @RESPATH@/components/FormAutofillStartup.js +@RESPATH@/components/CSSUnprefixingService.js +@RESPATH@/components/CSSUnprefixingService.manifest @RESPATH@/components/contentAreaDropListener.manifest @RESPATH@/components/contentAreaDropListener.js @RESPATH@/browser/components/BrowserProfileMigrators.manifest @RESPATH@/browser/components/ProfileMigrator.js @RESPATH@/browser/components/ChromeProfileMigrator.js @RESPATH@/browser/components/FirefoxProfileMigrator.js #ifdef XP_WIN @RESPATH@/browser/components/IEProfileMigrator.js
new file mode 100644 --- /dev/null +++ b/layout/style/CSSUnprefixingService.js @@ -0,0 +1,157 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- / +/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Implementation of a service that converts certain vendor-prefixed CSS + properties to their unprefixed equivalents, for sites on a whitelist. */ +// XXXdholbert whitelist is coming in bug 1132743 + +"use strict"; + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +function CSSUnprefixingService() { +} + +CSSUnprefixingService.prototype = { + // Boilerplate: + classID: Components.ID("{f0729490-e15c-4a2f-a3fb-99e1cc946b42}"), + _xpcom_factory: XPCOMUtils.generateSingletonFactory(CSSUnprefixingService), + QueryInterface: XPCOMUtils.generateQI([Ci.nsICSSUnprefixingService]), + + // See documentation in nsICSSUnprefixingService.idl + generateUnprefixedDeclaration: function(aPropName, aRightHalfOfDecl, + aUnprefixedDecl /*out*/) { + + // Convert our input strings to lower-case, for easier string-matching. + // (NOTE: If we ever need to add support for unprefixing properties that + // have case-sensitive parts, then we should do these toLowerCase() + // conversions in a more targeted way, to avoid breaking those properties.) + aPropName = aPropName.toLowerCase(); + aRightHalfOfDecl = aRightHalfOfDecl.toLowerCase(); + + // We have several groups of supported properties: + // FIRST GROUP: Properties that can just be handled as aliases: + // ============================================================ + const propertiesThatAreJustAliases = { + "-webkit-background-size": "background-size", + "-webkit-box-flex": "flex-grow", + "-webkit-box-ordinal-group": "order", + "-webkit-box-sizing": "box-sizing", + "-webkit-transform": "transform", + }; + + let unprefixedPropName = propertiesThatAreJustAliases[aPropName]; + if (unprefixedPropName !== undefined) { + aUnprefixedDecl.value = unprefixedPropName + ":" + aRightHalfOfDecl; + return true; + } + + // SECOND GROUP: Properties that take a single keyword, where the + // unprefixed version takes a different (but analogous) set of keywords: + // ===================================================================== + const propertiesThatNeedKeywordMapping = { + "-webkit-box-align" : { + unprefixedPropName : "align-items", + valueMap : { + "start" : "flex-start", + "center" : "center", + "end" : "flex-end", + "baseline" : "baseline", + "stretch" : "stretch" + } + }, + "-webkit-box-orient" : { + unprefixedPropName : "flex-direction", + valueMap : { + "horizontal" : "row", + "inline-axis" : "row", + "vertical" : "column", + "block-axis" : "column" + } + }, + "-webkit-box-pack" : { + unprefixedPropName : "justify-content", + valueMap : { + "start" : "flex-start", + "center" : "center", + "end" : "flex-end", + "justify" : "space-between" + } + }, + }; + + let propInfo = propertiesThatNeedKeywordMapping[aPropName]; + if (typeof(propInfo) != "undefined") { + // Regexp for parsing the right half of a declaration, for keyword-valued + // properties. Divides the right half of the declaration into: + // 1) any leading whitespace + // 2) the property value (one or more alphabetical character or hyphen) + // 3) anything after that (e.g. "!important", ";") + // Then we can look up the appropriate unprefixed-property value for the + // value (part 2), and splice that together with the other parts and with + // the unprefixed property-name to make the final declaration. + const keywordValuedPropertyRegexp = /^(\s*)([a-z\-]+)(.*)/; + let parts = keywordValuedPropertyRegexp.exec(aRightHalfOfDecl); + if (!parts) { + // Failed to parse a keyword out of aRightHalfOfDecl. (It probably has + // no alphabetical characters.) + return false; + } + + let mappedKeyword = propInfo.valueMap[parts[2]]; + if (mappedKeyword === undefined) { + // We found a keyword in aRightHalfOfDecl, but we don't have a mapping + // to an equivalent keyword for the unprefixed version of the property. + return false; + } + + aUnprefixedDecl.value = propInfo.unprefixedPropName + ":" + + parts[1] + // any leading whitespace + mappedKeyword + + parts[3]; // any trailing text (e.g. !important, semicolon, etc) + + return true; + } + + // THIRD GROUP: Properties that may need arbitrary string-replacement: + // =================================================================== + const propertiesThatNeedStringReplacement = { + // "-webkit-transition" takes a multi-part value. If "-webkit-transform" + // appears as part of that value, replace it w/ "transform". + // And regardless, we unprefix the "-webkit-transition" property-name. + // (We could handle other prefixed properties in addition to 'transform' + // here, but in practice "-webkit-transform" is the main one that's + // likely to be transitioned & that we're concerned about supporting.) + "-webkit-transition": { + unprefixedPropName : "transition", + stringMap : { + "-webkit-transform" : "transform", + } + }, + }; + + propInfo = propertiesThatNeedStringReplacement[aPropName]; + if (typeof(propInfo) != "undefined") { + let newRightHalf = aRightHalfOfDecl; + for (let strToReplace in propInfo.stringMap) { + let replacement = propInfo.stringMap[strToReplace]; + newRightHalf = newRightHalf.replace(strToReplace, replacement, "g"); + } + aUnprefixedDecl.value = propInfo.unprefixedPropName + ":" + newRightHalf; + + return true; + } + + // No known mapping for property aPropName. + return false; + }, +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([CSSUnprefixingService]);
new file mode 100644 --- /dev/null +++ b/layout/style/CSSUnprefixingService.manifest @@ -0,0 +1,2 @@ +component {f0729490-e15c-4a2f-a3fb-99e1cc946b42} CSSUnprefixingService.js +contract @mozilla.org/css-unprefixing-service;1 {f0729490-e15c-4a2f-a3fb-99e1cc946b42}
--- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -2,16 +2,22 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. DIRS += ['xbl-marquee'] TEST_DIRS += ['test'] +XPIDL_SOURCES += [ + 'nsICSSUnprefixingService.idl', +] + +XPIDL_MODULE = 'layout_base' + EXPORTS += [ 'AnimationCommon.h', 'CounterStyleManager.h', 'nsAnimationManager.h', 'nsComputedDOMStylePropertyList.h', 'nsCSSAnonBoxes.h', 'nsCSSAnonBoxList.h', 'nsCSSCounterDescList.h', @@ -142,16 +148,21 @@ UNIFIED_SOURCES += [ # FontFaceSet.cpp needs to be built separately because it redefines LOG. # nsCSSRuleProcessor.cpp needs to be built separately because it uses plarena.h. SOURCES += [ 'FontFaceSet.cpp', 'nsCSSRuleProcessor.cpp', ] +EXTRA_COMPONENTS += [ + 'CSSUnprefixingService.js', + 'CSSUnprefixingService.manifest', +] + FAIL_ON_WARNINGS = True MSVC_ENABLE_PGO = True include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'xul'
new file mode 100644 --- /dev/null +++ b/layout/style/nsICSSUnprefixingService.idl @@ -0,0 +1,48 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* interface for a service that converts certain vendor-prefixed CSS properties + to their unprefixed equivalents */ + +#include "nsISupports.idl" + +[scriptable, uuid(927a5c60-0378-4bcb-a50d-99e6d1fe6063)] +interface nsICSSUnprefixingService : nsISupports +{ + /** + * This function helps to convert unsupported vendor-prefixed CSS into + * supported unprefixed CSS. Given a vendor-prefixed property name and a + * value (or e.g. value + trailing junk like " !important;}"), this function + * will attempt to produce an equivalent CSS declaration that uses a + * supported unprefixed CSS property. + * + * @param aPropName + * The vendor-prefixed property name. + * + * @param aRightHalfOfDecl + * Everything after the ":" in the CSS declaration. This includes + * the property's value, along with possibly some leading whitespace + * and trailing text like "!important", and possibly a ';' and/or + * '}' (along with any other bogus text the author happens to + * include before those, which will probably make the decl invalid). + * + * @param aUnprefixedDecl[out] + * The resulting unprefixed declaration, if we return true. + * + * @return true if we were able to unprefix -- i.e. if we were able to + * convert the property to a known unprefixed equivalent, and we also + * performed any known-to-be-necessary fixup on the value, and we put + * the result in aUnprefixedDecl. + * Otherwise, this function returns false. + */ + boolean generateUnprefixedDeclaration(in AString aPropName, + in AString aRightHalfOfDecl, + out AString aUnprefixedDecl); +}; + +%{C++ +#define NS_CSSUNPREFIXINGSERVICE_CONTRACTID \ + "@mozilla.org/css-unprefixing-service;1" +%}
--- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -386,16 +386,18 @@ @BINPATH@/components/satchel.manifest @BINPATH@/components/nsFormAutoComplete.js @BINPATH@/components/nsFormHistory.js @BINPATH@/components/FormHistoryStartup.js @BINPATH@/components/nsInputListAutoComplete.js @BINPATH@/components/formautofill.manifest @BINPATH@/components/FormAutofillContentService.js @BINPATH@/components/FormAutofillStartup.js +@BINPATH@/components/CSSUnprefixingService.js +@BINPATH@/components/CSSUnprefixingService.manifest @BINPATH@/components/contentAreaDropListener.manifest @BINPATH@/components/contentAreaDropListener.js @BINPATH@/components/messageWakeupService.js @BINPATH@/components/messageWakeupService.manifest #ifdef MOZ_ENABLE_DBUS @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@ #endif @BINPATH@/components/nsINIProcessor.manifest