diff --git a/accessible/jsat/AccessFu.css b/accessible/jsat/AccessFu.css index 89514de60a1e..10b91a3472c3 100644 --- a/accessible/jsat/AccessFu.css +++ b/accessible/jsat/AccessFu.css @@ -9,9 +9,14 @@ display: none; border-radius: 2px; box-shadow: 1px 1px 1px #444; + display: none; } -#virtual-cursor-inset { +#virtual-cursor-box.show { + display: block; +} + +#virtual-cursor-box > div { border-radius: 1px; box-shadow: inset 1px 1px 1px #444; display: block; diff --git a/accessible/jsat/AccessFu.jsm b/accessible/jsat/AccessFu.jsm index 8fa83f35df79..3e738863dbba 100644 --- a/accessible/jsat/AccessFu.jsm +++ b/accessible/jsat/AccessFu.jsm @@ -394,23 +394,19 @@ this.AccessFu = { // jshint ignore:line _processedMessageManagers: [], /** - * Adjusts the given bounds relative to the given browser. Converts from - * screen or device pixels to either device or CSS pixels. + * Adjusts the given bounds relative to the given browser. * @param {Rect} aJsonBounds the bounds to adjust * @param {browser} aBrowser the browser we want the bounds relative to * @param {bool} aToCSSPixels whether to convert to CSS pixels (as opposed to * device pixels) - * @param {bool} aFromDevicePixels whether to convert from device pixels (as - * opposed to screen pixels) */ adjustContentBounds: - function(aJsonBounds, aBrowser, aToCSSPixels, aFromDevicePixels) { + function(aJsonBounds, aBrowser, aToCSSPixels) { let bounds = new Rect(aJsonBounds.left, aJsonBounds.top, aJsonBounds.right - aJsonBounds.left, aJsonBounds.bottom - aJsonBounds.top); let win = Utils.win; let dpr = win.devicePixelRatio; - let vp = Utils.getViewport(win); let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY }; if (!aBrowser.contentWindow) { @@ -421,16 +417,6 @@ this.AccessFu = { // jshint ignore:line offset.left += clientRect.left + win.mozInnerScreenX; offset.top += clientRect.top + win.mozInnerScreenY; } - - // Here we scale from screen pixels to layout device pixels by dividing by - // the resolution (caused by pinch-zooming). The resolution is the - // viewport zoom divided by the devicePixelRatio. If there's no viewport, - // then we're on a platform without pinch-zooming and we can just ignore - // this. - if (!aFromDevicePixels && vp) { - bounds = bounds.scale(vp.zoom / dpr, vp.zoom / dpr); - } - // Add the offset; the offset is in CSS pixels, so multiply the // devicePixelRatio back in before adding to preserve unit consistency. bounds = bounds.translate(offset.left * dpr, offset.top * dpr); @@ -545,11 +531,10 @@ var Output = { highlightBox.id = 'virtual-cursor-box'; // Add highlight inset for inner shadow - let inset = Utils.win.document. - createElementNS('http://www.w3.org/1999/xhtml', 'div'); - inset.id = 'virtual-cursor-inset'; + highlightBox.appendChild( + Utils.win.document.createElementNS( + 'http://www.w3.org/1999/xhtml', 'div')); - highlightBox.appendChild(inset); this.highlightBox = Cu.getWeakReference(highlightBox); } else { highlightBox = this.highlightBox.get(); @@ -559,12 +544,12 @@ var Output = { let r = AccessFu.adjustContentBounds(aDetail.bounds, aBrowser, true); // First hide it to avoid flickering when changing the style. - highlightBox.style.display = 'none'; + highlightBox.classList.remove('show'); highlightBox.style.top = (r.top - padding) + 'px'; highlightBox.style.left = (r.left - padding) + 'px'; highlightBox.style.width = (r.width + padding*2) + 'px'; highlightBox.style.height = (r.height + padding*2) + 'px'; - highlightBox.style.display = 'block'; + highlightBox.classList.add('show'); break; } @@ -572,7 +557,7 @@ var Output = { { let highlightBox = this.highlightBox ? this.highlightBox.get() : null; if (highlightBox) { - highlightBox.style.display = 'none'; + highlightBox.classList.remove('show'); } break; } @@ -889,8 +874,7 @@ var Input = { activateContextMenu: function activateContextMenu(aDetails) { if (Utils.MozBuildApp === 'mobile/android') { let p = AccessFu.adjustContentBounds(aDetails.bounds, - Utils.CurrentBrowser, - true, true).center(); + Utils.CurrentBrowser, true).center(); Services.obs.notifyObservers(null, 'Gesture:LongPress', JSON.stringify({x: p.x, y: p.y})); } @@ -915,8 +899,8 @@ var Input = { doScroll: function doScroll(aDetails) { let horizontal = aDetails.horizontal; let page = aDetails.page; - let p = AccessFu.adjustContentBounds(aDetails.bounds, Utils.CurrentBrowser, - true, true).center(); + let p = AccessFu.adjustContentBounds( + aDetails.bounds, Utils.CurrentBrowser, true).center(); Utils.winUtils.sendWheelEvent(p.x, p.y, horizontal ? page : 0, horizontal ? 0 : page, 0, Utils.win.WheelEvent.DOM_DELTA_PAGE, 0, 0, 0, 0); diff --git a/accessible/jsat/Utils.jsm b/accessible/jsat/Utils.jsm index 57ab6c5176d3..2ef4a2dfe83a 100644 --- a/accessible/jsat/Utils.jsm +++ b/accessible/jsat/Utils.jsm @@ -255,15 +255,6 @@ this.Utils = { // jshint ignore:line } }, - getViewport: function getViewport(aWindow) { - switch (this.MozBuildApp) { - case 'mobile/android': - return aWindow.BrowserApp.selectedTab.getViewport(); - default: - return null; - } - }, - getState: function getState(aAccessibleOrEvent) { if (aAccessibleOrEvent instanceof Ci.nsIAccessibleStateChangeEvent) { return new State( @@ -302,18 +293,37 @@ this.Utils = { // jshint ignore:line return doc.QueryInterface(Ci.nsIAccessibleDocument).virtualCursor; }, - getBounds: function getBounds(aAccessible) { - let objX = {}, objY = {}, objW = {}, objH = {}; - aAccessible.getBounds(objX, objY, objW, objH); - return new Rect(objX.value, objY.value, objW.value, objH.value); + getContentResolution: function _getContentResolution(aAccessible) { + let resX = { value: 1 }, resY = { value: 1 }; + aAccessible.document.window.QueryInterface( + Ci.nsIInterfaceRequestor).getInterface( + Ci.nsIDOMWindowUtils).getResolution(resX, resY); + return [resX.value, resY.value]; }, - getTextBounds: function getTextBounds(aAccessible, aStart, aEnd) { - let accText = aAccessible.QueryInterface(Ci.nsIAccessibleText); - let objX = {}, objY = {}, objW = {}, objH = {}; - accText.getRangeExtents(aStart, aEnd, objX, objY, objW, objH, - Ci.nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE); - return new Rect(objX.value, objY.value, objW.value, objH.value); + getBounds: function getBounds(aAccessible, aPreserveContentScale) { + let objX = {}, objY = {}, objW = {}, objH = {}; + aAccessible.getBounds(objX, objY, objW, objH); + + let [scaleX, scaleY] = aPreserveContentScale ? [1, 1] : + this.getContentResolution(aAccessible); + + return new Rect(objX.value, objY.value, objW.value, objH.value).scale( + scaleX, scaleY); + }, + + getTextBounds: function getTextBounds(aAccessible, aStart, aEnd, + aPreserveContentScale) { + let accText = aAccessible.QueryInterface(Ci.nsIAccessibleText); + let objX = {}, objY = {}, objW = {}, objH = {}; + accText.getRangeExtents(aStart, aEnd, objX, objY, objW, objH, + Ci.nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE); + + let [scaleX, scaleY] = aPreserveContentScale ? [1, 1] : + this.getContentResolution(aAccessible); + + return new Rect(objX.value, objY.value, objW.value, objH.value).scale( + scaleX, scaleY); }, /** diff --git a/accessible/jsat/content-script.js b/accessible/jsat/content-script.js index 1dd0d4cd2b9b..c9a991aa5fd4 100644 --- a/accessible/jsat/content-script.js +++ b/accessible/jsat/content-script.js @@ -65,14 +65,10 @@ function forwardToChild(aMessage, aListener, aVCPosition) { } function activateContextMenu(aMessage) { - function sendContextMenuCoordinates(aAccessible) { - let bounds = Utils.getBounds(aAccessible); - sendAsyncMessage('AccessFu:ActivateContextMenu', {bounds: bounds}); - } - let position = Utils.getVirtualCursor(content.document).position; if (!forwardToChild(aMessage, activateContextMenu, position)) { - sendContextMenuCoordinates(position); + sendAsyncMessage('AccessFu:ActivateContextMenu', + { bounds: Utils.getBounds(position, true) }); } } @@ -85,16 +81,12 @@ function presentCaretChange(aText, aOldOffset, aNewOffset) { } function scroll(aMessage) { - function sendScrollCoordinates(aAccessible) { - let bounds = Utils.getBounds(aAccessible); - sendAsyncMessage('AccessFu:DoScroll', - { bounds: bounds, - page: aMessage.json.page, - horizontal: aMessage.json.horizontal }); - } - let position = Utils.getVirtualCursor(content.document).position; if (!forwardToChild(aMessage, scroll, position)) { + sendAsyncMessage('AccessFu:DoScroll', + { bounds: Utils.getBounds(position, true), + page: aMessage.json.page, + horizontal: aMessage.json.horizontal }); sendScrollCoordinates(position); } } diff --git a/addon-sdk/source/lib/toolkit/loader.js b/addon-sdk/source/lib/toolkit/loader.js index d2b17a1ab038..02370f8bdce7 100644 --- a/addon-sdk/source/lib/toolkit/loader.js +++ b/addon-sdk/source/lib/toolkit/loader.js @@ -407,18 +407,18 @@ const nodeResolve = iced(function nodeResolve(id, requirer, { rootURI }) { let fullId = join(rootURI, id); let resolvedPath; - if (resolvedPath = loadAsFile(fullId)) + if ((resolvedPath = loadAsFile(fullId))) return stripBase(rootURI, resolvedPath); - else if (resolvedPath = loadAsDirectory(fullId)) + else if ((resolvedPath = loadAsDirectory(fullId))) return stripBase(rootURI, resolvedPath); // If manifest has dependencies, attempt to look up node modules // in the `dependencies` list else { let dirs = getNodeModulePaths(dirname(join(rootURI, requirer))).map(dir => join(dir, id)); for (let i = 0; i < dirs.length; i++) { - if (resolvedPath = loadAsFile(dirs[i])) + if ((resolvedPath = loadAsFile(dirs[i]))) return stripBase(rootURI, resolvedPath); - if (resolvedPath = loadAsDirectory(dirs[i])) + if ((resolvedPath = loadAsDirectory(dirs[i]))) return stripBase(rootURI, resolvedPath); } } @@ -459,7 +459,7 @@ function loadAsDirectory (path) { let main = getManifestMain(JSON.parse(readURI(path + '/package.json'))); if (main != null) { let tmpPath = join(path, main); - if (found = loadAsFile(tmpPath)) + if ((found = loadAsFile(tmpPath))) return found } try { diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index 9eb3444fddce..147326a5034b 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -1201,8 +1201,7 @@ const kTransferContractId = "@mozilla.org/transfer;1"; // Override Toolkit's nsITransfer implementation with the one from the // JavaScript API for downloads. This will eventually be removed when -// nsIDownloadManager will not be available anymore (bug 851471). The -// old code in this module will be removed in bug 899110. +// nsIDownloadManager will not be available anymore (bug 851471). Components.manager.QueryInterface(Ci.nsIComponentRegistrar) .registerFactory(kTransferCid, "", kTransferContractId, null); diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index a15e38aeaa59..24d083f129ca 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -980,7 +980,11 @@ pref("browser.safebrowsing.reportMalwareURL", "http://%LOCALE%.malware-report.mo pref("browser.safebrowsing.reportMalwareErrorURL", "http://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%"); pref("browser.safebrowsing.malware.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site="); + +// Turn off remote lookups in beta and stable channel. +#ifndef RELEASE_BUILD pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%"); +#endif #ifdef MOZILLA_OFFICIAL // Normally the "client ID" sent in updates is appinfo.name, but for diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index de7685e242d5..1f5fecc12faf 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -438,6 +438,13 @@ var gPopupBlockerObserver = { // Hide the icon in the location bar (if the location bar exists) if (gURLBar) this._reportButton.hidden = true; + + // Hide the notification box (if it's visible). + var notificationBox = gBrowser.getNotificationBox(); + var notification = notificationBox.getNotificationWithValue("popup-blocked"); + if (notification) { + notificationBox.removeNotification(notification, false); + } return; } diff --git a/browser/devtools/shared/AppCacheUtils.jsm b/browser/devtools/shared/AppCacheUtils.jsm index 894be888bd6c..49c9630d1f2d 100644 --- a/browser/devtools/shared/AppCacheUtils.jsm +++ b/browser/devtools/shared/AppCacheUtils.jsm @@ -293,7 +293,14 @@ AppCacheUtils.prototype = { }, clearAll: function ACU_clearAll() { - Services.cache.evictEntries(Ci.nsICache.STORE_OFFLINE); + if (!Services.prefs.getBoolPref("browser.cache.disk.enable")) { + throw new Error(l10n.GetStringFromName("cacheDisabled")); + } + + let appCacheStorage = Services.cache2.appCacheStorage(LoadContextInfo.default, null); + appCacheStorage.asyncEvictStorage({ + onCacheEntryDoomed: function(result) {} + }); }, _getManifestURI: function ACU__getManifestURI() { diff --git a/browser/devtools/styleinspector/test/browser_computedview_select-and-copy-styles.js b/browser/devtools/styleinspector/test/browser_computedview_select-and-copy-styles.js index 294ee97287d4..b7e030d94314 100644 --- a/browser/devtools/styleinspector/test/browser_computedview_select-and-copy-styles.js +++ b/browser/devtools/styleinspector/test/browser_computedview_select-and-copy-styles.js @@ -15,7 +15,7 @@ let test = asyncTest(function*() { info("Creating the test document"); content.document.body.innerHTML = '
\n' + '

Some header text

\n' + @@ -58,7 +58,7 @@ function checkCopySelection(view) { let expectedPattern = "font-family: helvetica,sans-serif;[\\r\\n]+" + "font-size: 16px;[\\r\\n]+" + - "font-variant: small-caps;[\\r\\n]*"; + "font-variant-caps: small-caps;[\\r\\n]*"; return waitForClipboard(() => { fireCopyEvent(props[0]); @@ -80,7 +80,7 @@ function checkSelectAll(view) { let expectedPattern = "color: #FF0;[\\r\\n]+" + "font-family: helvetica,sans-serif;[\\r\\n]+" + "font-size: 16px;[\\r\\n]+" + - "font-variant: small-caps;[\\r\\n]*"; + "font-variant-caps: small-caps;[\\r\\n]*"; return waitForClipboard(() => { fireCopyEvent(prop); diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 3eef152bc430..2ec4f3481f73 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -816,6 +816,7 @@ bin/libfreebl_32int64_3.so @BINPATH@/webapprt/components/PaymentUIGlue.js @BINPATH@/webapprt/components/components.manifest @BINPATH@/webapprt/defaults/preferences/prefs.js +@BINPATH@/webapprt/modules/DownloadView.jsm @BINPATH@/webapprt/modules/Startup.jsm @BINPATH@/webapprt/modules/WebappRT.jsm @BINPATH@/webapprt/modules/WebappManager.jsm diff --git a/build/sanitizers/lsan_suppressions.txt b/build/sanitizers/lsan_suppressions.txt index e5e1e381861f..c075a2bfa52c 100644 --- a/build/sanitizers/lsan_suppressions.txt +++ b/build/sanitizers/lsan_suppressions.txt @@ -28,12 +28,43 @@ leak:GI___strdup ### -### Many leaks only affect some test suites. The suite annotations are not checked. +### Bug 979928 - WebRTC leaks. m2, m3. ### -# Bug 979928 - WebRTC is leaky. m2, m3 -leak:/media/mtransport/ -leak:/media/webrtc/signaling/ +# WebRTC leaks added for Mochitest 2. +leak:NR_reg_init +leak:fsmdef_init +leak:r_log_register +leak:nr_reg_set +leak:ccsnap_device_init +leak:ccsnap_line_init +leak:media/webrtc/signaling/src/sipcc/core/common/init.c +leak:cprPostMessage +leak:mozilla::NrIceStunServer::Create + +# Additional WebRTC leak suppressions added for Mochitest 3. +leak:mozilla::TransportLayerDtls::Setup +leak:mozilla::NrIceTurnServer::Create +# There are about 228KB of leaks from the call to |pmsg->sdp = cpr_malloc(sdp_size);| +# in send_message_helper. +leak:send_message_helper +leak:fsmdef_ev_createoffer +leak:fsmdef_ev_setremotedesc +leak:fsmdef_ev_setlocaldesc +leak:fsmdef_ev_createanswer +# About 70KB of leaks under this stack. +leak:vcmRxAllocICE_s +leak:vcmRxStartICE_m +# About 50KB of leaks under this stack. +leak:ccsnap_EscapeStrToLocaleStr +leak:gsmsdp_add_default_audio_formats_to_local_sdp +leak:gsmsdp_add_default_video_formats_to_local_sdp +leak:CCAPI_CallInfo_getMediaStreams + + +### +### Many leaks only affect some test suites. The suite annotations are not checked. +### # Bug 981195 - Small leak in the parser. m4 leak:TypeCompartment::fixObjectType diff --git a/content/base/public/Element.h b/content/base/public/Element.h index 881ec04ce43d..3944913c5d3e 100644 --- a/content/base/public/Element.h +++ b/content/base/public/Element.h @@ -728,7 +728,7 @@ public: int32_t ScrollTop() { nsIScrollableFrame* sf = GetScrollFrame(); - return sf ? sf->GetScrollPositionCSSPixels().y : 0; + return sf ? sf->GetScrollPositionCSSPixels().y.value : 0; } void SetScrollTop(int32_t aScrollTop) { @@ -741,7 +741,7 @@ public: int32_t ScrollLeft() { nsIScrollableFrame* sf = GetScrollFrame(); - return sf ? sf->GetScrollPositionCSSPixels().x : 0; + return sf ? sf->GetScrollPositionCSSPixels().x.value : 0; } void SetScrollLeft(int32_t aScrollLeft) { diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index be418e725b86..8297817083ac 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -405,15 +405,6 @@ public: static bool CanCallerAccess(nsPIDOMWindow* aWindow); /** - * Get the window through the JS context that's currently on the stack. - * If there's no JS context currently on the stack, returns null. - */ - static nsPIDOMWindow *GetWindowFromCaller(); - - /** - * The two GetDocumentFrom* functions below allow a caller to get at a - * document that is relevant to the currently executing script. - * * GetDocumentFromCaller gets its document by looking at the last called * function and finding the document that the function itself relates to. * For example, consider two windows A and B in the same origin. B has a @@ -421,28 +412,10 @@ public: * If a script in window A were to call B's function, GetDocumentFromCaller * would find that function (in B) and return B's document. * - * GetDocumentFromContext gets its document by looking at the currently - * executing context's global object and returning its document. Thus, - * given the example above, GetDocumentFromCaller would see that the - * currently executing script was in window A, and return A's document. - */ - /** - * Get the document from the currently executing function. This will return - * the document that the currently executing function is in/from. - * * @return The document or null if no JS Context. */ static nsIDocument* GetDocumentFromCaller(); - /** - * Get the document through the JS context that's currently on the stack. - * If there's no JS context currently on the stack it will return null. - * This will return the document of the calling script. - * - * @return The document or null if no JS context - */ - static nsIDocument* GetDocumentFromContext(); - // Check if a node is in the document prolog, i.e. before the document // element. static bool InProlog(nsINode *aNode); @@ -2279,9 +2252,7 @@ private: static bool sInitialized; static uint32_t sScriptBlockerCount; -#ifdef DEBUG static uint32_t sDOMNodeRemovedSuppressCount; -#endif static uint32_t sMicroTaskLevel; // Not an nsCOMArray because removing elements from those is slower static nsTArray< nsCOMPtr >* sBlockedScriptRunners; @@ -2338,14 +2309,10 @@ class MOZ_STACK_CLASS nsAutoScriptBlockerSuppressNodeRemoved : public nsAutoScriptBlocker { public: nsAutoScriptBlockerSuppressNodeRemoved() { -#ifdef DEBUG ++nsContentUtils::sDOMNodeRemovedSuppressCount; -#endif } ~nsAutoScriptBlockerSuppressNodeRemoved() { -#ifdef DEBUG --nsContentUtils::sDOMNodeRemovedSuppressCount; -#endif } }; diff --git a/content/base/src/WebSocket.cpp b/content/base/src/WebSocket.cpp index 060d51580632..93b2ec62a275 100644 --- a/content/base/src/WebSocket.cpp +++ b/content/base/src/WebSocket.cpp @@ -686,7 +686,7 @@ WebSocket::Init(JSContext* aCx, // Confirmed we are opening plain ws:// and want to prevent this from a // secure context (e.g. https). Check the principal's uri to determine if // we were loaded from https. - nsCOMPtr globalObject(BrokenGetEntryGlobal()); + nsCOMPtr globalObject(GetEntryGlobal()); if (globalObject) { nsCOMPtr principal(globalObject->PrincipalOrNull()); if (principal) { diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 1029a0925826..b1e96b3d1f52 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -214,9 +214,7 @@ nsILineBreaker *nsContentUtils::sLineBreaker; nsIWordBreaker *nsContentUtils::sWordBreaker; nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nullptr; uint32_t nsContentUtils::sScriptBlockerCount = 0; -#ifdef DEBUG uint32_t nsContentUtils::sDOMNodeRemovedSuppressCount = 0; -#endif uint32_t nsContentUtils::sMicroTaskLevel = 0; nsTArray< nsCOMPtr >* nsContentUtils::sBlockedScriptRunners = nullptr; uint32_t nsContentUtils::sRunnersCountAtFirstBlocker = 0; @@ -1953,19 +1951,6 @@ nsContentUtils::TraceSafeJSContext(JSTracer* aTrc) } } -nsPIDOMWindow * -nsContentUtils::GetWindowFromCaller() -{ - JSContext *cx = GetCurrentJSContext(); - if (cx) { - nsCOMPtr win = - do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx)); - return win; - } - - return nullptr; -} - nsIDocument* nsContentUtils::GetDocumentFromCaller() { @@ -1980,24 +1965,6 @@ nsContentUtils::GetDocumentFromCaller() return win->GetExtantDoc(); } -nsIDocument* -nsContentUtils::GetDocumentFromContext() -{ - JSContext *cx = GetCurrentJSContext(); - if (cx) { - nsIScriptGlobalObject *sgo = nsJSUtils::GetDynamicScriptGlobal(cx); - - if (sgo) { - nsCOMPtr pwin = do_QueryInterface(sgo); - if (pwin) { - return pwin->GetExtantDoc(); - } - } - } - - return nullptr; -} - bool nsContentUtils::IsCallerChrome() { @@ -3920,30 +3887,27 @@ nsContentUtils::MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent, NS_PRECONDITION(aChild->GetParentNode() == aParent, "Wrong parent"); NS_PRECONDITION(aChild->OwnerDoc() == aOwnerDoc, "Wrong owner-doc"); - // This checks that IsSafeToRunScript is true since we don't want to fire - // events when that is false. We can't rely on EventDispatcher to assert - // this in this situation since most of the time there are no mutation - // event listeners, in which case we won't even attempt to dispatch events. - // However this also allows for two exceptions. First off, we don't assert - // if the mutation happens to native anonymous content since we never fire - // mutation events on such content anyway. - // Second, we don't assert if sDOMNodeRemovedSuppressCount is true since - // that is a know case when we'd normally fire a mutation event, but can't - // make that safe and so we suppress it at this time. Ideally this should - // go away eventually. - NS_ASSERTION((aChild->IsNodeOfType(nsINode::eCONTENT) && - static_cast(aChild)-> - IsInNativeAnonymousSubtree()) || - IsSafeToRunScript() || - sDOMNodeRemovedSuppressCount, - "Want to fire DOMNodeRemoved event, but it's not safe"); - // Having an explicit check here since it's an easy mistake to fall into, // and there might be existing code with problems. We'd rather be safe // than fire DOMNodeRemoved in all corner cases. We also rely on it for // nsAutoScriptBlockerSuppressNodeRemoved. if (!IsSafeToRunScript()) { - WarnScriptWasIgnored(aOwnerDoc); + // This checks that IsSafeToRunScript is true since we don't want to fire + // events when that is false. We can't rely on EventDispatcher to assert + // this in this situation since most of the time there are no mutation + // event listeners, in which case we won't even attempt to dispatch events. + // However this also allows for two exceptions. First off, we don't assert + // if the mutation happens to native anonymous content since we never fire + // mutation events on such content anyway. + // Second, we don't assert if sDOMNodeRemovedSuppressCount is true since + // that is a know case when we'd normally fire a mutation event, but can't + // make that safe and so we suppress it at this time. Ideally this should + // go away eventually. + if (!(aChild->IsContent() && aChild->AsContent()->IsInNativeAnonymousSubtree()) && + !sDOMNodeRemovedSuppressCount) { + NS_ERROR("Want to fire DOMNodeRemoved event, but it's not safe"); + WarnScriptWasIgnored(aOwnerDoc); + } return; } diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 629d55e40252..d49047480262 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -1429,10 +1429,10 @@ nsHTMLDocument::Open(JSContext* cx, return ret.forget(); } - // Note: We want to use GetDocumentFromContext here because this document + // Note: We want to use GetEntryDocument here because this document // should inherit the security information of the document that's opening us, // (since if it's secure, then it's presumably trusted). - nsCOMPtr callerDoc = nsContentUtils::GetDocumentFromContext(); + nsCOMPtr callerDoc = GetEntryDocument(); if (!callerDoc) { // If we're called from C++ or in some other way without an originating // document we can't do a document.open w/o changing the principal of the diff --git a/content/media/gmp/GMPChild.cpp b/content/media/gmp/GMPChild.cpp index f93ef31bdaf9..344b4b70d63e 100644 --- a/content/media/gmp/GMPChild.cpp +++ b/content/media/gmp/GMPChild.cpp @@ -128,14 +128,15 @@ GMPChild::Init(const std::string& aPluginPath, return false; } +#ifdef MOZ_CRASHREPORTER + SendPCrashReporterConstructor(CrashReporter::CurrentThreadId()); +#endif + #if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) mPluginPath = aPluginPath; return true; #endif -#ifdef MOZ_CRASHREPORTER - SendPCrashReporterConstructor(CrashReporter::CurrentThreadId()); -#endif #if defined(XP_WIN) mozilla::SandboxTarget::Instance()->StartSandbox(); #endif diff --git a/content/media/mediasource/SourceBufferResource.h b/content/media/mediasource/SourceBufferResource.h index f7007e4447a5..5ef220dc5a52 100644 --- a/content/media/mediasource/SourceBufferResource.h +++ b/content/media/mediasource/SourceBufferResource.h @@ -75,6 +75,7 @@ private: public: ResourceQueue() : nsDeque(new ResourceQueueDeallocator()), + mLogicalLength(0), mOffset(0) { } @@ -87,12 +88,7 @@ private: // Returns the length of all items in the queue plus the offset. // This is the logical length of the resource. inline uint64_t GetLength() { - uint64_t s = mOffset; - for (uint32_t i = 0; i < GetSize(); ++i) { - ResourceItem* item = ResourceAt(i); - s += item->mData.Length(); - } - return s; + return mLogicalLength; } // Copies aCount bytes from aOffset in the queue into aDest. @@ -113,6 +109,7 @@ private: } inline void PushBack(ResourceItem* aItem) { + mLogicalLength += aItem->mData.Length(); nsDeque::Push(aItem); } @@ -184,8 +181,10 @@ private: return static_cast(nsDeque::PopFront()); } - // Logical offset into the resource of the first element - // in the queue. + // Logical length of the resource. + uint64_t mLogicalLength; + + // Logical offset into the resource of the first element in the queue. uint64_t mOffset; }; diff --git a/content/media/moz.build b/content/media/moz.build index 36cda1091ebf..83f40041131e 100644 --- a/content/media/moz.build +++ b/content/media/moz.build @@ -67,9 +67,6 @@ EXPORTS += [ 'AudioCompactor.h', 'AudioEventTimeline.h', 'AudioMixer.h', - 'AudioNodeEngine.h', - 'AudioNodeExternalInputStream.h', - 'AudioNodeStream.h', 'AudioSampleFormat.h', 'AudioSegment.h', 'AudioStream.h', @@ -130,9 +127,6 @@ EXPORTS.mozilla.dom += [ UNIFIED_SOURCES += [ 'AudioChannelFormat.cpp', 'AudioCompactor.cpp', - 'AudioNodeEngine.cpp', - 'AudioNodeExternalInputStream.cpp', - 'AudioNodeStream.cpp', 'AudioSegment.cpp', 'AudioSink.cpp', 'AudioStream.cpp', @@ -185,10 +179,6 @@ SOURCES += [ FAIL_ON_WARNINGS = True -if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']: - SOURCES += ['AudioNodeEngineNEON.cpp'] - SOURCES['AudioNodeEngineNEON.cpp'].flags += ['-mfpu=neon'] - MSVC_ENABLE_PGO = True include('/ipc/chromium/chromium-config.mozbuild') diff --git a/content/media/AudioNodeEngine.cpp b/content/media/webaudio/AudioNodeEngine.cpp similarity index 100% rename from content/media/AudioNodeEngine.cpp rename to content/media/webaudio/AudioNodeEngine.cpp diff --git a/content/media/AudioNodeEngine.h b/content/media/webaudio/AudioNodeEngine.h similarity index 100% rename from content/media/AudioNodeEngine.h rename to content/media/webaudio/AudioNodeEngine.h diff --git a/content/media/AudioNodeEngineNEON.cpp b/content/media/webaudio/AudioNodeEngineNEON.cpp similarity index 100% rename from content/media/AudioNodeEngineNEON.cpp rename to content/media/webaudio/AudioNodeEngineNEON.cpp diff --git a/content/media/AudioNodeEngineNEON.h b/content/media/webaudio/AudioNodeEngineNEON.h similarity index 100% rename from content/media/AudioNodeEngineNEON.h rename to content/media/webaudio/AudioNodeEngineNEON.h diff --git a/content/media/AudioNodeExternalInputStream.cpp b/content/media/webaudio/AudioNodeExternalInputStream.cpp similarity index 100% rename from content/media/AudioNodeExternalInputStream.cpp rename to content/media/webaudio/AudioNodeExternalInputStream.cpp diff --git a/content/media/AudioNodeExternalInputStream.h b/content/media/webaudio/AudioNodeExternalInputStream.h similarity index 100% rename from content/media/AudioNodeExternalInputStream.h rename to content/media/webaudio/AudioNodeExternalInputStream.h diff --git a/content/media/AudioNodeStream.cpp b/content/media/webaudio/AudioNodeStream.cpp similarity index 100% rename from content/media/AudioNodeStream.cpp rename to content/media/webaudio/AudioNodeStream.cpp diff --git a/content/media/AudioNodeStream.h b/content/media/webaudio/AudioNodeStream.h similarity index 100% rename from content/media/AudioNodeStream.h rename to content/media/webaudio/AudioNodeStream.h diff --git a/content/media/webaudio/moz.build b/content/media/webaudio/moz.build index 42371e593697..6751e377c797 100644 --- a/content/media/webaudio/moz.build +++ b/content/media/webaudio/moz.build @@ -19,6 +19,9 @@ BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] EXPORTS += [ 'AudioContext.h', + 'AudioNodeEngine.h', + 'AudioNodeExternalInputStream.h', + 'AudioNodeStream.h', 'AudioParamTimeline.h', 'MediaBufferDecoder.h', 'ThreeDPoint.h', @@ -65,6 +68,9 @@ UNIFIED_SOURCES += [ 'AudioDestinationNode.cpp', 'AudioListener.cpp', 'AudioNode.cpp', + 'AudioNodeEngine.cpp', + 'AudioNodeExternalInputStream.cpp', + 'AudioNodeStream.cpp', 'AudioParam.cpp', 'AudioProcessingEvent.cpp', 'BiquadFilterNode.cpp', @@ -90,8 +96,15 @@ UNIFIED_SOURCES += [ 'WebAudioUtils.cpp', ] +if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']: + SOURCES += ['AudioNodeEngineNEON.cpp'] + SOURCES['AudioNodeEngineNEON.cpp'].flags += ['-mfpu=neon'] + FAIL_ON_WARNINGS = True include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'xul' +LOCAL_INCLUDES += [ + '..' +] diff --git a/content/media/webaudio/test/mochitest.ini b/content/media/webaudio/test/mochitest.ini index 22783d98d60c..e66d5661f83c 100644 --- a/content/media/webaudio/test/mochitest.ini +++ b/content/media/webaudio/test/mochitest.ini @@ -128,6 +128,7 @@ skip-if = (toolkit == 'gonk' && !debug) [test_periodicWave.html] [test_scriptProcessorNode.html] [test_scriptProcessorNodeChannelCount.html] +[test_scriptProcessorNodePassThrough.html] [test_scriptProcessorNode_playbackTime1.html] [test_scriptProcessorNodeZeroInputOutput.html] [test_scriptProcessorNodeNotConnected.html] diff --git a/content/media/webaudio/test/test_scriptProcessorNode.html b/content/media/webaudio/test/test_scriptProcessorNode.html index 4a5ebeb793dd..7cfb3d96e5a1 100644 --- a/content/media/webaudio/test/test_scriptProcessorNode.html +++ b/content/media/webaudio/test/test_scriptProcessorNode.html @@ -26,7 +26,7 @@ addLoadEvent(function() { for (var i = 0; i < 2048; ++i) { // Make sure our first sample won't be zero e.outputBuffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * (i + 1) / context.sampleRate); - e.outputBuffer.getChannelData(0)[i] = Math.sin(880 * 2 * Math.PI * (i + 1) / context.sampleRate); + e.outputBuffer.getChannelData(1)[i] = Math.sin(880 * 2 * Math.PI * (i + 1) / context.sampleRate); } // Remember our generated audio buffer = e.outputBuffer; diff --git a/content/media/webaudio/test/test_scriptProcessorNodePassThrough.html b/content/media/webaudio/test/test_scriptProcessorNodePassThrough.html new file mode 100644 index 000000000000..8352a331da71 --- /dev/null +++ b/content/media/webaudio/test/test_scriptProcessorNodePassThrough.html @@ -0,0 +1,103 @@ + + + + Test ScriptProcessorNode with passthrough + + + + + +
+
+
+ + diff --git a/content/media/webm/WebMBufferedParser.cpp b/content/media/webm/WebMBufferedParser.cpp index 9a2a4aa9d631..d2ce8b80af4e 100644 --- a/content/media/webm/WebMBufferedParser.cpp +++ b/content/media/webm/WebMBufferedParser.cpp @@ -60,7 +60,7 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength, // and return to CLUSTER_SYNC. if (mClusterIDPos == sizeof(CLUSTER_ID)) { mClusterIDPos = 0; - mClusterOffset = mCurrentOffset + (p - aBuffer) - 1; + mClusterOffset = mCurrentOffset + (p - aBuffer) - sizeof(CLUSTER_ID); mState = READ_VINT; mNextState = TIMECODE_SYNC; } diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index c39aafc1808d..b8aa1166903c 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -1965,16 +1965,16 @@ Navigator::GetMozCameras(ErrorResult& aRv) return mCameraManager; } -already_AddRefed +already_AddRefed Navigator::ServiceWorker() { MOZ_ASSERT(mWindow); if (!mServiceWorkerContainer) { - mServiceWorkerContainer = new workers::ServiceWorkerContainer(mWindow); + mServiceWorkerContainer = new ServiceWorkerContainer(mWindow); } - nsRefPtr ref = mServiceWorkerContainer; + nsRefPtr ref = mServiceWorkerContainer; return ref.forget(); } diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index c676673e095b..b97259cc9d40 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -36,6 +36,7 @@ struct MediaStreamConstraints; class WakeLock; class ArrayBufferViewOrBlobOrStringOrFormData; struct MobileIdOptions; +class ServiceWorkerContainer; } } @@ -104,10 +105,6 @@ class AudioChannelManager; #endif } // namespace system -namespace workers { -class ServiceWorkerContainer; -} // namespace workers - class Navigator : public nsIDOMNavigator , public nsIMozNavigatorNetwork , public nsWrapperCache @@ -262,7 +259,7 @@ public: ErrorResult& aRv); #endif // MOZ_MEDIA_NAVIGATOR - already_AddRefed ServiceWorker(); + already_AddRefed ServiceWorker(); bool DoNewResolve(JSContext* aCx, JS::Handle aObject, JS::Handle aId, @@ -340,7 +337,7 @@ private: nsCOMPtr mMessagesManager; nsTArray > mDeviceStorageStores; nsRefPtr mTimeManager; - nsRefPtr mServiceWorkerContainer; + nsRefPtr mServiceWorkerContainer; nsCOMPtr mWindow; // Hashtable for saving cached objects newresolve created, so we don't create diff --git a/dom/base/ScriptSettings.cpp b/dom/base/ScriptSettings.cpp index 5f7657149103..5c0daafb7203 100644 --- a/dom/base/ScriptSettings.cpp +++ b/dom/base/ScriptSettings.cpp @@ -122,27 +122,18 @@ ScriptSettingsStackEntry::~ScriptSettingsStackEntry() ScriptSettingsStack::Pop(this); } -// This mostly gets the entry global, but doesn't entirely match the spec in -// certain edge cases. It's good enough for some purposes, but not others. If -// you want to call this function, ping bholley and describe your use-case. nsIGlobalObject* -BrokenGetEntryGlobal() +GetEntryGlobal() { - // We need the current JSContext in order to check the JS for - // scripted frames that may have appeared since anyone last - // manipulated the stack. If it's null, that means that there - // must be no entry global on the stack. - JSContext *cx = nsContentUtils::GetCurrentJSContextForThread(); - if (!cx) { - MOZ_ASSERT(ScriptSettingsStack::EntryGlobal() == nullptr); - return nullptr; - } - - return nsJSUtils::GetDynamicScriptGlobal(cx); + return ScriptSettingsStack::EntryGlobal(); } -// Note: When we're ready to expose it, GetEntryGlobal will look similar to -// GetIncumbentGlobal below. +nsIDocument* +GetEntryDocument() +{ + nsCOMPtr entryWin = do_QueryInterface(GetEntryGlobal()); + return entryWin ? entryWin->GetExtantDoc() : nullptr; +} nsIGlobalObject* GetIncumbentGlobal() @@ -171,6 +162,22 @@ GetIncumbentGlobal() return ScriptSettingsStack::IncumbentGlobal(); } +nsIGlobalObject* +GetCurrentGlobal() +{ + JSContext *cx = nsContentUtils::GetCurrentJSContextForThread(); + if (!cx) { + return nullptr; + } + + JSObject *global = JS::CurrentGlobalOrNull(cx); + if (!global) { + return nullptr; + } + + return xpc::GetNativeForGlobal(global); +} + nsIPrincipal* GetWebIDLCallerPrincipal() { diff --git a/dom/base/ScriptSettings.h b/dom/base/ScriptSettings.h index 8e5dc63630d4..637aa7436ea4 100644 --- a/dom/base/ScriptSettings.h +++ b/dom/base/ScriptSettings.h @@ -20,6 +20,7 @@ class nsPIDOMWindow; class nsGlobalWindow; class nsIScriptContext; +class nsIDocument; namespace mozilla { namespace dom { @@ -63,17 +64,57 @@ private: void InitScriptSettings(); void DestroyScriptSettings(); -// This mostly gets the entry global, but doesn't entirely match the spec in -// certain edge cases. It's good enough for some purposes, but not others. If -// you want to call this function, ping bholley and describe your use-case. -nsIGlobalObject* BrokenGetEntryGlobal(); +// To implement a web-compatible browser, it is often necessary to obtain the +// global object that is "associated" with the currently-running code. This +// process is made more complicated by the fact that, historically, different +// algorithms have operated with different definitions of the "associated" +// global. +// +// HTML5 formalizes this into two concepts: the "incumbent global" and the +// "entry global". The incumbent global corresponds to the global of the +// current script being executed, whereas the entry global corresponds to the +// global of the script where the current JS execution began. +// +// There is also a potentially-distinct third global that is determined by the +// current compartment. This roughly corresponds with the notion of Realms in +// ECMAScript. +// +// Suppose some event triggers an event listener in window |A|, which invokes a +// scripted function in window |B|, which invokes the |window.location.href| +// setter in window |C|. The entry global would be |A|, the incumbent global +// would be |B|, and the current compartment would be that of |C|. +// +// In general, it's best to use to use the most-closely-associated global +// unless the spec says to do otherwise. In 95% of the cases, the global of +// the current compartment (GetCurrentGlobal()) is the right thing. For +// example, WebIDL constructors (new C.XMLHttpRequest()) are initialized with +// the global of the current compartment (i.e. |C|). +// +// The incumbent global is very similar, but differs in a few edge cases. For +// example, if window |B| does |C.location.href = "..."|, the incumbent global +// used for the navigation algorithm is B, because no script from |C| was ever run. +// +// The entry global is used for various things like computing base URIs, mostly +// for historical reasons. +// +// Note that all of these functions return bonafide global objects. This means +// that, for Windows, they always return the inner. -// Note: We don't yet expose GetEntryGlobal, because in order for it to be -// correct, we first need to replace a bunch of explicit cx pushing in the -// browser with AutoEntryScript. But GetIncumbentGlobal is simpler, because it -// can mostly be inferred from the JS stack. +// Returns the global associated with the top-most Candidate Entry Point on +// the Script Settings Stack. See the HTML spec. This may be null. +nsIGlobalObject* GetEntryGlobal(); + +// If the entry global is a window, returns its extant document. Otherwise, +// returns null. +nsIDocument* GetEntryDocument(); + +// Returns the global associated with the top-most entry of the the Script +// Settings Stack. See the HTML spec. This may be null. nsIGlobalObject* GetIncumbentGlobal(); +// Returns the global associated with the current compartment. This may be null. +nsIGlobalObject* GetCurrentGlobal(); + // JS-implemented WebIDL presents an interesting situation with respect to the // subject principal. A regular C++-implemented API can simply examine the // compartment of the most-recently-executed script, and use that to infer the diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index cc3ae9045729..bc21c8409b23 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -2501,11 +2501,6 @@ OldBindingConstructorEnabled(const nsGlobalNameStruct *aStruct, } } - // Don't expose CSSFontFeatureValuesRule unless the pref is enabled - if (aStruct->mDOMClassInfoID == eDOMClassInfo_CSSFontFeatureValuesRule_id) { - return nsCSSFontFeatureValuesRule::PrefEnabled(); - } - return true; } diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 720114996a5f..3307075ef93f 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -420,7 +420,7 @@ nsFocusManager::GetLastFocusMethod(nsIDOMWindow* aWindow, uint32_t* aLastFocusMe { // the focus method is stored on the inner window nsCOMPtr window(do_QueryInterface(aWindow)); - if (window) + if (window && window->IsOuterWindow()) window = window->GetCurrentInnerWindow(); if (!window) window = mFocusedWindow; diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 302deea54bb3..4a6cb7b858fc 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1482,10 +1482,11 @@ nsGlobalWindow::CleanUp() mChromeEventHandler = nullptr; // Forces Release mParentTarget = nullptr; - nsGlobalWindow *inner = GetCurrentInnerWindowInternal(); - - if (inner) { - inner->CleanUp(); + if (IsOuterWindow()) { + nsGlobalWindow* inner = GetCurrentInnerWindowInternal(); + if (inner) { + inner->CleanUp(); + } } if (IsInnerWindow()) { @@ -5915,15 +5916,8 @@ nsGlobalWindow::RefreshCompartmentPrincipal() static already_AddRefed GetCallerDocShellTreeItem() { - JSContext *cx = nsContentUtils::GetCurrentJSContext(); - nsCOMPtr callerItem; - - if (cx) { - nsCOMPtr callerWebNav = - do_GetInterface(nsJSUtils::GetDynamicScriptGlobal(cx)); - - callerItem = do_QueryInterface(callerWebNav); - } + nsCOMPtr callerWebNav = do_GetInterface(GetEntryGlobal()); + nsCOMPtr callerItem = do_QueryInterface(callerWebNav); return callerItem.forget(); } @@ -6557,7 +6551,7 @@ nsGlobalWindow::Focus(ErrorResult& aError) return; } - nsIDOMWindow *caller = nsContentUtils::GetWindowFromCaller(); + nsCOMPtr caller = do_QueryInterface(GetEntryGlobal()); nsCOMPtr opener; GetOpener(getter_AddRefs(opener)); @@ -7535,20 +7529,7 @@ nsGlobalWindow::FireAbuseEvents(bool aBlocked, bool aWindow, nsIURI *baseURL = nullptr; - JSContext *cx = nsContentUtils::GetCurrentJSContext(); - nsCOMPtr contextWindow; - - if (cx) { - nsIScriptContext *currentCX = nsJSUtils::GetDynamicScriptContext(cx); - if (currentCX) { - contextWindow = do_QueryInterface(currentCX->GetGlobalObject()); - } - } - if (!contextWindow) { - contextWindow = this; - } - - nsCOMPtr doc = contextWindow->GetDoc(); + nsCOMPtr doc = GetEntryDocument(); if (doc) baseURL = doc->GetDocBaseURI(); @@ -8253,7 +8234,7 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle aMessage, nsCOMPtr providedPrincipal; if (aTargetOrigin.EqualsASCII("/")) { - providedPrincipal = BrokenGetEntryGlobal()->PrincipalOrNull(); + providedPrincipal = GetEntryGlobal()->PrincipalOrNull(); if (NS_WARN_IF(!providedPrincipal)) return; } @@ -12803,11 +12784,7 @@ nsGlobalWindow::GetScrollFrame() nsresult nsGlobalWindow::SecurityCheckURL(const char *aURL) { - nsCOMPtr sourceWindow; - JSContext* topCx = nsContentUtils::GetCurrentJSContext(); - if (topCx) { - sourceWindow = do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(topCx)); - } + nsCOMPtr sourceWindow = do_QueryInterface(GetEntryGlobal()); if (!sourceWindow) { sourceWindow = this; } diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 850564da70de..a47dd8b8a0c0 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -599,6 +599,7 @@ public: nsGlobalWindow *GetCurrentInnerWindowInternal() const { + MOZ_ASSERT(IsOuterWindow()); return static_cast(mInnerWindow); } diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 7ae1c32bb6dc..7f4c0fd37b02 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -557,46 +557,38 @@ NS_ScriptErrorReporter(JSContext *cx, } } - // XXX this means we are not going to get error reports on non DOM contexts - nsIScriptContext *context = nsJSUtils::GetDynamicScriptContext(cx); - JS::Rooted exception(cx); ::JS_GetPendingException(cx, &exception); - // Note: we must do this before running any more code on cx (if cx is the - // dynamic script context). + // Note: we must do this before running any more code on cx. ::JS_ClearPendingException(cx); - if (context) { - nsIScriptGlobalObject *globalObject = context->GetGlobalObject(); + MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext()); + nsCOMPtr globalObject = GetEntryGlobal(); + if (globalObject) { - if (globalObject) { - - nsCOMPtr win = do_QueryInterface(globalObject); - if (win) { - win = win->GetCurrentInnerWindow(); - } - nsCOMPtr scriptPrincipal = - do_QueryInterface(globalObject); - NS_ASSERTION(scriptPrincipal, "Global objects must implement " - "nsIScriptObjectPrincipal"); - nsContentUtils::AddScriptRunner( - new ScriptErrorEvent(JS_GetRuntime(cx), - report, - message, - nsJSPrincipals::get(report->originPrincipals), - scriptPrincipal->GetPrincipal(), - win, - exception, - /* We do not try to report Out Of Memory via a dom - * event because the dom event handler would - * encounter an OOM exception trying to process the - * event, and then we'd need to generate a new OOM - * event for that new OOM instance -- this isn't - * pretty. - */ - report->errorNumber != JSMSG_OUT_OF_MEMORY)); - } + nsCOMPtr win = do_QueryInterface(globalObject); + MOZ_ASSERT_IF(win, win->IsInnerWindow()); + nsCOMPtr scriptPrincipal = + do_QueryInterface(globalObject); + NS_ASSERTION(scriptPrincipal, "Global objects must implement " + "nsIScriptObjectPrincipal"); + nsContentUtils::AddScriptRunner( + new ScriptErrorEvent(JS_GetRuntime(cx), + report, + message, + nsJSPrincipals::get(report->originPrincipals), + scriptPrincipal->GetPrincipal(), + win, + exception, + /* We do not try to report Out Of Memory via a dom + * event because the dom event handler would + * encounter an OOM exception trying to process the + * event, and then we'd need to generate a new OOM + * event for that new OOM instance -- this isn't + * pretty. + */ + report->errorNumber != JSMSG_OUT_OF_MEMORY)); } if (nsContentUtils::DOMWindowDumpEnabled()) { diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp index d5c47f687a40..acbfa3994548 100644 --- a/dom/base/nsJSUtils.cpp +++ b/dom/base/nsJSUtils.cpp @@ -63,21 +63,6 @@ nsJSUtils::GetStaticScriptContext(JSObject* aObj) return nativeGlobal->GetScriptContext(); } -nsIScriptGlobalObject * -nsJSUtils::GetDynamicScriptGlobal(JSContext* aContext) -{ - nsIScriptContext *scriptCX = GetDynamicScriptContext(aContext); - if (!scriptCX) - return nullptr; - return scriptCX->GetGlobalObject(); -} - -nsIScriptContext * -nsJSUtils::GetDynamicScriptContext(JSContext *aContext) -{ - return GetScriptContextFromJSContext(aContext); -} - uint64_t nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext) { diff --git a/dom/base/nsJSUtils.h b/dom/base/nsJSUtils.h index d781609446ea..18f7864fa842 100644 --- a/dom/base/nsJSUtils.h +++ b/dom/base/nsJSUtils.h @@ -32,10 +32,6 @@ public: static nsIScriptContext *GetStaticScriptContext(JSObject* aObj); - static nsIScriptGlobalObject *GetDynamicScriptGlobal(JSContext *aContext); - - static nsIScriptContext *GetDynamicScriptContext(JSContext *aContext); - /** * Retrieve the inner window ID based on the given JSContext. * diff --git a/dom/base/nsLocation.cpp b/dom/base/nsLocation.cpp index d16e6c720804..2c9a92d4f339 100644 --- a/dom/base/nsLocation.cpp +++ b/dom/base/nsLocation.cpp @@ -28,6 +28,7 @@ #include "nsITextToSubURI.h" #include "nsJSUtils.h" #include "nsContentUtils.h" +#include "nsGlobalWindow.h" #include "mozilla/Likely.h" #include "nsCycleCollectionParticipant.h" #include "nsNullPrincipal.h" @@ -42,15 +43,8 @@ GetDocumentCharacterSetForURI(const nsAString& aHref, nsACString& aCharset) { aCharset.Truncate(); - JSContext *cx = nsContentUtils::GetCurrentJSContext(); - if (cx) { - nsCOMPtr window = - do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx)); - NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); - - if (nsIDocument* doc = window->GetDoc()) { - aCharset = doc->GetDocumentCharacterSet(); - } + if (nsIDocument* doc = GetEntryDocument()) { + aCharset = doc->GetDocumentCharacterSet(); } return NS_OK; @@ -545,23 +539,23 @@ nsLocation::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase, * anywhere else. This is part of solution for bug # 39938, 72197 * */ - bool inScriptTag=false; - JSContext *cx = nsContentUtils::GetCurrentJSContext(); - if (cx) { - nsIScriptContext *scriptContext = - nsJSUtils::GetDynamicScriptContext(cx); + bool inScriptTag = false; + nsIScriptContext* scriptContext = nullptr; + nsCOMPtr win = do_QueryInterface(GetEntryGlobal()); + if (win) { + scriptContext = static_cast(win.get())->GetContextInternal(); + } - if (scriptContext) { - if (scriptContext->GetProcessingScriptTag()) { - // Now check to make sure that the script is running in our window, - // since we only want to replace if the location is set by a - // + + + + +Mozilla Bug 1036214 +

+ +
+
+ + + diff --git a/dom/bindings/test/test_bug923904.html b/dom/bindings/test/test_bug923904.html deleted file mode 100644 index 6700097ef1b7..000000000000 --- a/dom/bindings/test/test_bug923904.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - Test for Bug 923904 - - - - - -Mozilla Bug 923904 -

- -
-
- - diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index a022ba086dee..19e8e943252a 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -1985,7 +1985,7 @@ CanvasRenderingContext2D::ArcTo(double x1, double y1, double x2, } // Check for colinearity - dir = (p2.x - p1.x) * (p0.y - p1.y) + (p2.y - p1.y) * (p1.x - p0.x); + dir = (p2.x - p1.x).value * (p0.y - p1.y).value + (p2.y - p1.y).value * (p1.x - p0.x).value; if (dir == 0) { LineTo(p1.x, p1.y); return; @@ -4500,7 +4500,7 @@ CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius, } // Check for colinearity - dir = (p2.x - p1.x) * (p0.y - p1.y) + (p2.y - p1.y) * (p1.x - p0.x); + dir = (p2.x - p1.x).value * (p0.y - p1.y).value + (p2.y - p1.y).value * (p1.x - p0.x).value; if (dir == 0) { LineTo(p1.x, p1.y); return; diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index 9f9d784bfedc..f6ae0d13a2c0 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -790,7 +790,7 @@ protected: // The spec says we should not draw shadows if the operator is OVER. // If it's over and the alpha value is zero, nothing needs to be drawn. return NS_GET_A(state.shadowColor) != 0 && - (state.shadowBlur != 0 || state.shadowOffset.x != 0 || state.shadowOffset.y != 0); + (state.shadowBlur != 0.f || state.shadowOffset.x != 0.f || state.shadowOffset.y != 0.f); } mozilla::gfx::CompositionOp UsedOperation() diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 40905adb4225..451e692a8e9a 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -1595,8 +1595,9 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext, // fire drag gesture if mouse has moved enough LayoutDeviceIntPoint pt = aEvent->refPoint + LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset()); - if (DeprecatedAbs(pt.x - mGestureDownPoint.x) > pixelThresholdX || - DeprecatedAbs(pt.y - mGestureDownPoint.y) > pixelThresholdY) { + LayoutDeviceIntPoint distance = pt - mGestureDownPoint; + if (Abs(distance.x.value) > SafeCast(pixelThresholdX) || + Abs(distance.y.value) > SafeCast(pixelThresholdY)) { if (Prefs::ClickHoldContextMenu()) { // stop the click-hold before we fire off the drag gesture, in case // it takes a long time diff --git a/dom/interfaces/base/nsIServiceWorkerManager.idl b/dom/interfaces/base/nsIServiceWorkerManager.idl index 09563769dd6e..d47480444e64 100644 --- a/dom/interfaces/base/nsIServiceWorkerManager.idl +++ b/dom/interfaces/base/nsIServiceWorkerManager.idl @@ -8,7 +8,7 @@ interface nsIDocument; interface nsIURI; -[uuid(cc539f1e-1ce6-4af5-bf94-195b30bde010)] +[uuid(9b5acea4-2601-4ac7-8836-4352ceb88178)] interface nsIServiceWorkerManager : nsISupports { // Returns a Promise @@ -17,9 +17,9 @@ interface nsIServiceWorkerManager : nsISupports // Returns a Promise nsISupports unregister(in nsIDOMWindow aWindow, in DOMString aScope); - // aTarget MUST be a ServiceWorkerContainer. - [noscript] void AddContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget); - [noscript] void RemoveContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget); + // aTarget MUST be a ServiceWorkerRegistration. + [noscript] void AddRegistrationEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget); + [noscript] void RemoveRegistrationEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget); /** * Call this to request that document `aDoc` be controlled by a ServiceWorker diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index 4e6e8af82a1f..92de646b3faf 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -2102,12 +2102,12 @@ MediaManager::MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVide // results. nsCOMPtr piWin = do_QueryInterface(aWindow); if (piWin) { - if (piWin->GetCurrentInnerWindow() || piWin->IsInnerWindow()) { + if (piWin->IsInnerWindow() || piWin->GetCurrentInnerWindow()) { uint64_t windowID; - if (piWin->GetCurrentInnerWindow()) { - windowID = piWin->GetCurrentInnerWindow()->WindowID(); - } else { + if (piWin->IsInnerWindow()) { windowID = piWin->WindowID(); + } else { + windowID = piWin->GetCurrentInnerWindow()->WindowID(); } StreamListeners* listeners = GetActiveWindows()->Get(windowID); if (listeners) { diff --git a/dom/smil/test/smilTestUtils.js b/dom/smil/test/smilTestUtils.js index 02775de7013d..60ff7aaab9bf 100644 --- a/dom/smil/test/smilTestUtils.js +++ b/dom/smil/test/smilTestUtils.js @@ -55,14 +55,14 @@ var SMILUtil = }, // Smart wrapper for getComputedStyle, which will generate a "fake" computed - // style for recognized shorthand properties (font, overflow, marker) + // style for recognized shorthand properties (font, font-variant, overflow, marker) getComputedStyleWrapper : function(elem, propName) { // Special cases for shorthand properties (which aren't directly queriable // via getComputedStyle) var computedStyle; if (propName == "font") { - var subProps = ["font-style", "font-variant", "font-weight", + var subProps = ["font-style", "font-variant-caps", "font-weight", "font-size", "line-height", "font-family"]; for (var i in subProps) { var subPropStyle = SMILUtil.getComputedStyleSimple(elem, subProps[i]); @@ -78,6 +78,10 @@ var SMILUtil = } } } + } else if (propName == "font-variant") { + // xxx - this isn't completely correct but it's sufficient for what's + // being tested here + computedStyle = SMILUtil.getComputedStyleSimple(elem, "font-variant-caps"); } else if (propName == "marker") { var subProps = ["marker-end", "marker-mid", "marker-start"]; for (var i in subProps) { diff --git a/dom/webidl/ServiceWorkerContainer.webidl b/dom/webidl/ServiceWorkerContainer.webidl index 126db64620ae..9364a059dc0e 100644 --- a/dom/webidl/ServiceWorkerContainer.webidl +++ b/dom/webidl/ServiceWorkerContainer.webidl @@ -8,29 +8,27 @@ * */ -[Pref="dom.serviceWorkers.enabled"] -interface ServiceWorkerContainer { +[Pref="dom.serviceWorkers.enabled", + Exposed=Window] +interface ServiceWorkerContainer : EventTarget { // FIXME(nsm): // https://github.com/slightlyoff/ServiceWorker/issues/198 // and discussion at https://etherpad.mozilla.org/serviceworker07apr - [Unforgeable] readonly attribute ServiceWorker? installing; - [Unforgeable] readonly attribute ServiceWorker? waiting; - [Unforgeable] readonly attribute ServiceWorker? active; [Unforgeable] readonly attribute ServiceWorker? controller; [Throws] - readonly attribute Promise ready; + readonly attribute Promise ready; [Throws] - Promise getAll(); + Promise register(ScalarValueString scriptURL, + optional RegistrationOptionList options); [Throws] - Promise register(DOMString url, optional RegistrationOptionList options); + Promise getRegistration(optional ScalarValueString documentURL = ""); [Throws] - Promise unregister(DOMString? scope); + Promise> getRegistrations(); - attribute EventHandler onupdatefound; attribute EventHandler oncontrollerchange; attribute EventHandler onreloadpage; attribute EventHandler onerror; @@ -49,5 +47,5 @@ partial interface ServiceWorkerContainer { }; dictionary RegistrationOptionList { - DOMString scope = "/*"; + ScalarValueString scope = "/*"; }; diff --git a/dom/webidl/ServiceWorkerRegistration.webidl b/dom/webidl/ServiceWorkerRegistration.webidl new file mode 100644 index 000000000000..7463765c512f --- /dev/null +++ b/dom/webidl/ServiceWorkerRegistration.webidl @@ -0,0 +1,25 @@ +/* -*- 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/. + * + * The origin of this IDL file is + * http://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html + * + */ + +[Pref="dom.serviceWorkers.enabled", + Exposed=Window] +interface ServiceWorkerRegistration : EventTarget { + [Unforgeable] readonly attribute ServiceWorker? installing; + [Unforgeable] readonly attribute ServiceWorker? waiting; + [Unforgeable] readonly attribute ServiceWorker? active; + + readonly attribute ScalarValueString scope; + + [Throws] + Promise unregister(); + + // event + attribute EventHandler onupdatefound; +}; diff --git a/dom/webidl/TestInterfaceJS.webidl b/dom/webidl/TestInterfaceJS.webidl index f5e913860b87..77cb253d3344 100644 --- a/dom/webidl/TestInterfaceJS.webidl +++ b/dom/webidl/TestInterfaceJS.webidl @@ -4,16 +4,29 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ +dictionary TestInterfaceJSUnionableDictionary { + object objectMember; + any anyMember; +}; + [JSImplementation="@mozilla.org/dom/test-interface-js;1", Pref="dom.expose_test_interfaces", - Constructor(optional any anyArg, optional object objectArg)] + Constructor(optional any anyArg, optional object objectArg, optional TestInterfaceJSDictionary dictionaryArg)] interface TestInterfaceJS { readonly attribute any anyArg; readonly attribute object objectArg; + [Cached, Pure] readonly attribute TestInterfaceJSDictionary dictionaryArg; attribute any anyAttr; attribute object objectAttr; + [Cached, Pure] attribute TestInterfaceJSDictionary dictionaryAttr; any pingPongAny(any arg); - object pingPongObject(any obj); + object pingPongObject(object obj); + any pingPongObjectOrString((object or DOMString) objOrString); + TestInterfaceJSDictionary pingPongDictionary(optional TestInterfaceJSDictionary dict); + long pingPongDictionaryOrLong(optional (TestInterfaceJSUnionableDictionary or long) dictOrLong); + DOMString pingPongMap(MozMap map); + long objectSequenceLength(sequence seq); + long anySequenceLength(sequence seq); // For testing bug 968335. DOMString getCallerPrincipal(); diff --git a/dom/webidl/TestInterfaceJSDictionaries.webidl b/dom/webidl/TestInterfaceJSDictionaries.webidl new file mode 100644 index 000000000000..366864a8d4f8 --- /dev/null +++ b/dom/webidl/TestInterfaceJSDictionaries.webidl @@ -0,0 +1,27 @@ +/* -*- 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/. + */ + +// +// These dictionaries are in a separate WebIDL file to avoid circular include +// problems. One of the dictionary includes a union as a member, so that +// dictionary's header needs to include UnionTypes.h. But the API in +// TestInterfaceJS also declares a union of dictionaries, so _that_ +// dictionary's header needs to be included _by_ UnionTypes.h. The solution +// is to separate those two dictionaries into separate header files. +// + +dictionary TestInterfaceJSDictionary2 { + object innerObject; +}; + +dictionary TestInterfaceJSDictionary { + TestInterfaceJSDictionary2 innerDictionary; + object objectMember; + any anyMember; + (object or DOMString) objectOrStringMember; + sequence anySequenceMember; +}; + diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 8e179f12e6fa..8251b148552b 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -326,6 +326,7 @@ WEBIDL_FILES = [ 'ServiceWorker.webidl', 'ServiceWorkerContainer.webidl', 'ServiceWorkerGlobalScope.webidl', + 'ServiceWorkerRegistration.webidl', 'SettingsManager.webidl', 'ShadowRoot.webidl', 'SharedWorker.webidl', @@ -563,7 +564,7 @@ WEBIDL_FILES += [ # We only expose our prefable test interfaces in debug builds, just to be on # the safe side. if CONFIG['MOZ_DEBUG']: - WEBIDL_FILES += ['TestInterfaceJS.webidl'] + WEBIDL_FILES += ['TestInterfaceJS.webidl', 'TestInterfaceJSDictionaries.webidl'] if CONFIG['MOZ_B2G_BT']: if CONFIG['MOZ_B2G_BT_API_V2']: diff --git a/dom/workers/ServiceWorkerCommon.h b/dom/workers/ServiceWorkerCommon.h new file mode 100644 index 000000000000..e9082bbc651c --- /dev/null +++ b/dom/workers/ServiceWorkerCommon.h @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_dom_ServiceWorkerCommon_h +#define mozilla_dom_ServiceWorkerCommon_h + +namespace mozilla { +namespace dom { + +// Use multiples of 2 since they can be bitwise ORed when calling +// InvalidateServiceWorkerRegistrationWorker. +MOZ_BEGIN_ENUM_CLASS(WhichServiceWorker) + INSTALLING_WORKER = 1, + WAITING_WORKER = 2, + ACTIVE_WORKER = 4, +MOZ_END_ENUM_CLASS(WhichServiceWorker) +MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(WhichServiceWorker) + +} // dom namespace +} // mozilla namespace + +#endif // mozilla_dom_ServiceWorkerCommon_h diff --git a/dom/workers/ServiceWorkerContainer.cpp b/dom/workers/ServiceWorkerContainer.cpp index 4c49e0f75965..fa80a02ce793 100644 --- a/dom/workers/ServiceWorkerContainer.cpp +++ b/dom/workers/ServiceWorkerContainer.cpp @@ -22,7 +22,6 @@ namespace mozilla { namespace dom { -namespace workers { NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerContainer) NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) @@ -31,21 +30,16 @@ NS_IMPL_ADDREF_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper, - mInstallingWorker, - mWaitingWorker, - mActiveWorker, mControllerWorker) ServiceWorkerContainer::ServiceWorkerContainer(nsPIDOMWindow* aWindow) : mWindow(aWindow) { SetIsDOMBinding(); - StartListeningForEvents(); } ServiceWorkerContainer::~ServiceWorkerContainer() { - StopListeningForEvents(); } JSObject* @@ -77,61 +71,6 @@ ServiceWorkerContainer::Register(const nsAString& aScriptURL, return ret.forget(); } -already_AddRefed -ServiceWorkerContainer::Unregister(const nsAString& aScope, - ErrorResult& aRv) -{ - nsCOMPtr promise; - - nsCOMPtr swm = mozilla::services::GetServiceWorkerManager(); - if (!swm) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - aRv = swm->Unregister(mWindow, aScope, getter_AddRefs(promise)); - if (aRv.Failed()) { - return nullptr; - } - - nsRefPtr ret = static_cast(promise.get()); - MOZ_ASSERT(ret); - return ret.forget(); -} - -already_AddRefed -ServiceWorkerContainer::GetInstalling() -{ - if (!mInstallingWorker) { - mInstallingWorker = GetWorkerReference(WhichServiceWorker::INSTALLING_WORKER); - } - - nsRefPtr ret = mInstallingWorker; - return ret.forget(); -} - -already_AddRefed -ServiceWorkerContainer::GetWaiting() -{ - if (!mWaitingWorker) { - mWaitingWorker = GetWorkerReference(WhichServiceWorker::WAITING_WORKER); - } - - nsRefPtr ret = mWaitingWorker; - return ret.forget(); -} - -already_AddRefed -ServiceWorkerContainer::GetActive() -{ - if (!mActiveWorker) { - mActiveWorker = GetWorkerReference(WhichServiceWorker::ACTIVE_WORKER); - } - - nsRefPtr ret = mActiveWorker; - return ret.forget(); -} - already_AddRefed ServiceWorkerContainer::GetController() { @@ -148,15 +87,25 @@ ServiceWorkerContainer::GetController() return nullptr; } - mControllerWorker = static_cast(serviceWorker.get()); + mControllerWorker = + static_cast(serviceWorker.get()); } - nsRefPtr ref = mControllerWorker; + nsRefPtr ref = mControllerWorker; return ref.forget(); } already_AddRefed -ServiceWorkerContainer::GetAll(ErrorResult& aRv) +ServiceWorkerContainer::GetRegistrations(ErrorResult& aRv) +{ + // FIXME(nsm): Bug 1002571 + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return nullptr; +} + +already_AddRefed +ServiceWorkerContainer::GetRegistration(const nsAString& aDocumentURL, + ErrorResult& aRv) { // FIXME(nsm): Bug 1002571 aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); @@ -171,74 +120,6 @@ ServiceWorkerContainer::GetReady(ErrorResult& aRv) return Promise::Create(global, aRv); } -// XXXnsm, maybe this can be optimized to only add when a event handler is -// registered. -void -ServiceWorkerContainer::StartListeningForEvents() -{ - nsCOMPtr swm = mozilla::services::GetServiceWorkerManager(); - if (swm) { - swm->AddContainerEventListener(mWindow->GetDocumentURI(), this); - } -} - -void -ServiceWorkerContainer::StopListeningForEvents() -{ - nsCOMPtr swm = mozilla::services::GetServiceWorkerManager(); - if (swm) { - swm->RemoveContainerEventListener(mWindow->GetDocumentURI(), this); - } -} - -void -ServiceWorkerContainer::InvalidateWorkerReference(WhichServiceWorker aWhichOnes) -{ - if (aWhichOnes & WhichServiceWorker::INSTALLING_WORKER) { - mInstallingWorker = nullptr; - } - - if (aWhichOnes & WhichServiceWorker::WAITING_WORKER) { - mWaitingWorker = nullptr; - } - - if (aWhichOnes & WhichServiceWorker::ACTIVE_WORKER) { - mActiveWorker = nullptr; - } -} - -already_AddRefed -ServiceWorkerContainer::GetWorkerReference(WhichServiceWorker aWhichOne) -{ - nsresult rv; - nsCOMPtr swm = mozilla::services::GetServiceWorkerManager(); - if (!swm) { - return nullptr; - } - - nsCOMPtr serviceWorker; - switch(aWhichOne) { - case WhichServiceWorker::INSTALLING_WORKER: - rv = swm->GetInstalling(mWindow, getter_AddRefs(serviceWorker)); - break; - case WhichServiceWorker::WAITING_WORKER: - rv = swm->GetWaiting(mWindow, getter_AddRefs(serviceWorker)); - break; - case WhichServiceWorker::ACTIVE_WORKER: - rv = swm->GetActive(mWindow, getter_AddRefs(serviceWorker)); - break; - default: - MOZ_CRASH("Invalid enum value"); - } - - if (NS_WARN_IF(NS_FAILED(rv))) { - return nullptr; - } - - nsRefPtr ref = static_cast(serviceWorker.get()); - return ref.forget(); -} - // Testing only. already_AddRefed ServiceWorkerContainer::ClearAllServiceWorkerData(ErrorResult& aRv) @@ -271,6 +152,5 @@ ServiceWorkerContainer::GetControllingWorkerScriptURLForPath( { aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); } -} // namespace workers } // namespace dom } // namespace mozilla diff --git a/dom/workers/ServiceWorkerContainer.h b/dom/workers/ServiceWorkerContainer.h index 5fc3ec1603c0..b8b2706b127f 100644 --- a/dom/workers/ServiceWorkerContainer.h +++ b/dom/workers/ServiceWorkerContainer.h @@ -4,13 +4,11 @@ * 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/. */ -#ifndef mozilla_dom_workers_serviceworkercontainer_h__ -#define mozilla_dom_workers_serviceworkercontainer_h__ +#ifndef mozilla_dom_serviceworkercontainer_h__ +#define mozilla_dom_serviceworkercontainer_h__ #include "mozilla/DOMEventTargetHelper.h" -#include "ServiceWorkerManager.h" - class nsPIDOMWindow; namespace mozilla { @@ -20,8 +18,8 @@ class Promise; struct RegistrationOptionList; namespace workers { - class ServiceWorker; +} // Lightweight serviceWorker APIs collection. class ServiceWorkerContainer MOZ_FINAL : public DOMEventTargetHelper @@ -30,7 +28,6 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper) - IMPL_EVENT_HANDLER(updatefound) IMPL_EVENT_HANDLER(controllerchange) IMPL_EVENT_HANDLER(reloadpage) IMPL_EVENT_HANDLER(error) @@ -51,39 +48,19 @@ public: const RegistrationOptionList& aOptions, ErrorResult& aRv); - already_AddRefed - Unregister(const nsAString& scope, ErrorResult& aRv); - - already_AddRefed - GetInstalling(); - - already_AddRefed - GetWaiting(); - - already_AddRefed - GetActive(); - - already_AddRefed + already_AddRefed GetController(); already_AddRefed - GetAll(ErrorResult& aRv); + GetRegistration(const nsAString& aDocumentURL, + ErrorResult& aRv); + + already_AddRefed + GetRegistrations(ErrorResult& aRv); already_AddRefed GetReady(ErrorResult& aRv); - nsIURI* - GetDocumentURI() const - { - return mWindow->GetDocumentURI(); - } - - void - InvalidateWorkerReference(WhichServiceWorker aWhichOnes); - - already_AddRefed - GetWorkerReference(WhichServiceWorker aWhichOne); - // Testing only. already_AddRefed ClearAllServiceWorkerData(ErrorResult& aRv); @@ -100,28 +77,14 @@ public: private: ~ServiceWorkerContainer(); - void - StartListeningForEvents(); - - void - StopListeningForEvents(); - nsCOMPtr mWindow; - // The following properties are cached here to ensure JS equality is satisfied - // instead of acquiring a new worker instance from the ServiceWorkerManager - // for every access. A null value is considered a cache miss. - // These three may change to a new worker at any time. - nsRefPtr mInstallingWorker; - nsRefPtr mWaitingWorker; - nsRefPtr mActiveWorker; // This only changes when a worker hijacks everything in its scope by calling // replace(). // FIXME(nsm): Bug 982711. Provide API to let SWM invalidate this. - nsRefPtr mControllerWorker; + nsRefPtr mControllerWorker; }; -} // namespace workers } // namespace dom } // namespace mozilla diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index f049d4f3b31a..72129914179c 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -24,7 +24,7 @@ #include "RuntimeService.h" #include "ServiceWorker.h" -#include "ServiceWorkerContainer.h" +#include "ServiceWorkerRegistration.h" #include "ServiceWorkerEvents.h" #include "WorkerInlines.h" #include "WorkerPrivate.h" @@ -36,7 +36,7 @@ using namespace mozilla::dom; BEGIN_WORKERS_NAMESPACE -NS_IMPL_ISUPPORTS0(ServiceWorkerRegistration) +NS_IMPL_ISUPPORTS0(ServiceWorkerRegistrationInfo) UpdatePromise::UpdatePromise() : mState(Pending) @@ -80,6 +80,7 @@ UpdatePromise::ResolveAllPromises(const nsACString& aScriptSpec, const nsACStrin GlobalObject domGlobal(cx, global); + // The service worker is created and kept alive as a SharedWorker. nsRefPtr serviceWorker; nsresult rv = rs->CreateServiceWorker(domGlobal, NS_ConvertUTF8toUTF16(aScriptSpec), @@ -90,7 +91,14 @@ UpdatePromise::ResolveAllPromises(const nsACString& aScriptSpec, const nsACStrin continue; } - pendingPromise->MaybeResolve(serviceWorker); + // Since ServiceWorkerRegistration is only exposed to windows we can be + // certain about this cast. + nsCOMPtr window = + do_QueryInterface(pendingPromise->GetParentObject()); + nsRefPtr swr = + new ServiceWorkerRegistration(window, NS_ConvertUTF8toUTF16(aScope)); + + pendingPromise->MaybeResolve(swr); } } } @@ -107,7 +115,7 @@ UpdatePromise::RejectAllPromises(nsresult aRv) for (uint32_t i = 0; i < array.Length(); ++i) { WeakPtr& pendingPromise = array.ElementAt(i); if (pendingPromise) { - // Since ServiceWorkerContainer is only exposed to windows we can be + // Since ServiceWorkerRegistration is only exposed to windows we can be // certain about this cast. nsCOMPtr window = do_QueryInterface(pendingPromise->GetParentObject()); @@ -129,7 +137,7 @@ UpdatePromise::RejectAllPromises(const ErrorEventInit& aErrorDesc) for (uint32_t i = 0; i < array.Length(); ++i) { WeakPtr& pendingPromise = array.ElementAt(i); if (pendingPromise) { - // Since ServiceWorkerContainer is only exposed to windows we can be + // Since ServiceWorkerRegistration is only exposed to windows we can be // certain about this cast. nsCOMPtr go = do_QueryInterface(pendingPromise->GetParentObject()); MOZ_ASSERT(go); @@ -208,7 +216,7 @@ public: class ServiceWorkerUpdateInstance MOZ_FINAL : public nsISupports { // Owner of this instance. - ServiceWorkerRegistration* mRegistration; + ServiceWorkerRegistrationInfo* mRegistration; nsCString mScriptSpec; nsCOMPtr mWindow; @@ -219,7 +227,7 @@ class ServiceWorkerUpdateInstance MOZ_FINAL : public nsISupports public: NS_DECL_ISUPPORTS - ServiceWorkerUpdateInstance(ServiceWorkerRegistration *aRegistration, + ServiceWorkerUpdateInstance(ServiceWorkerRegistrationInfo *aRegistration, nsPIDOMWindow* aWindow) : mRegistration(aRegistration), // Capture the current script spec in case register() gets called. @@ -297,13 +305,13 @@ FinishFetchOnMainThreadRunnable::Run() return NS_OK; } -ServiceWorkerRegistration::ServiceWorkerRegistration(const nsACString& aScope) +ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(const nsACString& aScope) : mControlledDocumentsCounter(0), mScope(aScope), mPendingUninstall(false) { } -ServiceWorkerRegistration::~ServiceWorkerRegistration() +ServiceWorkerRegistrationInfo::~ServiceWorkerRegistrationInfo() { MOZ_ASSERT(!IsControllingDocuments()); } @@ -339,7 +347,7 @@ ServiceWorkerManager::CleanupServiceWorkerInformation(const nsACString& aDomain, ServiceWorkerDomainInfo* aDomainInfo, void *aUnused) { - aDomainInfo->mServiceWorkerRegistrations.Clear(); + aDomainInfo->mServiceWorkerRegistrationInfos.Clear(); return PL_DHASH_NEXT; } @@ -376,7 +384,7 @@ public: swm->mDomainMap.Put(domain, domainInfo); } - nsRefPtr registration = + nsRefPtr registration = domainInfo->GetRegistration(mScope); nsCString spec; @@ -412,7 +420,11 @@ public: return NS_ERROR_FAILURE; } - mPromise->MaybeResolve(serviceWorker); + nsRefPtr swr = + new ServiceWorkerRegistration(mWindow, + NS_ConvertUTF8toUTF16(registration->mScope)); + + mPromise->MaybeResolve(swr); return NS_OK; } } @@ -528,7 +540,7 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow, const nsAString& aScope, } void -ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistration* aRegistration, +ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration, nsresult aRv) { AssertIsOnMainThread(); @@ -538,7 +550,7 @@ ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistration* aR } void -ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistration* aRegistration, +ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration, const ErrorEventInit& aErrorDesc) { AssertIsOnMainThread(); @@ -552,7 +564,7 @@ ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistration* aR * may access the registration's (new) Promise after calling this method. */ NS_IMETHODIMP -ServiceWorkerManager::Update(ServiceWorkerRegistration* aRegistration, +ServiceWorkerManager::Update(ServiceWorkerRegistrationInfo* aRegistration, nsPIDOMWindow* aWindow) { if (aRegistration->HasUpdatePromise()) { @@ -571,8 +583,8 @@ ServiceWorkerManager::Update(ServiceWorkerRegistration* aRegistration, // instance. // FIXME(nsm): Fire "statechange" on installing worker instance. aRegistration->mInstallingWorker = nullptr; - InvalidateServiceWorkerContainerWorker(aRegistration, - WhichServiceWorker::INSTALLING_WORKER); + InvalidateServiceWorkerRegistrationWorker(aRegistration, + WhichServiceWorker::INSTALLING_WORKER); } aRegistration->mUpdatePromise = new UpdatePromise(); @@ -587,7 +599,7 @@ ServiceWorkerManager::Update(ServiceWorkerRegistration* aRegistration, return NS_OK; } -// If we return an error, ServiceWorkerContainer will reject the Promise. +// If we return an error, ServiceWorkerREgistration will reject the Promise. NS_IMETHODIMP ServiceWorkerManager::Unregister(nsIDOMWindow* aWindow, const nsAString& aScope, nsISupports** aPromise) @@ -613,7 +625,7 @@ ServiceWorkerManager::GetInstance() } void -ServiceWorkerManager::ResolveRegisterPromises(ServiceWorkerRegistration* aRegistration, +ServiceWorkerManager::ResolveRegisterPromises(ServiceWorkerRegistrationInfo* aRegistration, const nsACString& aWorkerScriptSpec) { AssertIsOnMainThread(); @@ -630,7 +642,7 @@ ServiceWorkerManager::ResolveRegisterPromises(ServiceWorkerRegistration* aRegist // Must NS_Free() aString void -ServiceWorkerManager::FinishFetch(ServiceWorkerRegistration* aRegistration, +ServiceWorkerManager::FinishFetch(ServiceWorkerRegistrationInfo* aRegistration, nsPIDOMWindow* aWindow) { AssertIsOnMainThread(); @@ -688,7 +700,7 @@ ServiceWorkerManager::HandleError(JSContext* aCx, nsCString scope; scope.Assign(aScope); - nsRefPtr registration = domainInfo->GetRegistration(scope); + nsRefPtr registration = domainInfo->GetRegistration(scope); MOZ_ASSERT(registration); RootedDictionary init(aCx); @@ -717,11 +729,11 @@ ServiceWorkerManager::HandleError(JSContext* aCx, class FinishInstallRunnable MOZ_FINAL : public nsRunnable { - nsMainThreadPtrHandle mRegistration; + nsMainThreadPtrHandle mRegistration; public: explicit FinishInstallRunnable( - const nsMainThreadPtrHandle& aRegistration) + const nsMainThreadPtrHandle& aRegistration) : mRegistration(aRegistration) { MOZ_ASSERT(!NS_IsMainThread()); @@ -740,10 +752,10 @@ public: class FinishActivationRunnable : public nsRunnable { - nsMainThreadPtrHandle mRegistration; + nsMainThreadPtrHandle mRegistration; public: - FinishActivationRunnable(const nsMainThreadPtrHandle& aRegistration) + FinishActivationRunnable(const nsMainThreadPtrHandle& aRegistration) : mRegistration(aRegistration) { MOZ_ASSERT(!NS_IsMainThread()); @@ -763,11 +775,11 @@ public: class CancelServiceWorkerInstallationRunnable MOZ_FINAL : public nsRunnable { - nsMainThreadPtrHandle mRegistration; + nsMainThreadPtrHandle mRegistration; public: explicit CancelServiceWorkerInstallationRunnable( - const nsMainThreadPtrHandle& aRegistration) + const nsMainThreadPtrHandle& aRegistration) : mRegistration(aRegistration) { } @@ -780,8 +792,8 @@ public: // FIXME(nsm): Fire statechange. mRegistration->mInstallingWorker = nullptr; nsRefPtr swm = ServiceWorkerManager::GetInstance(); - swm->InvalidateServiceWorkerContainerWorker(mRegistration, - WhichServiceWorker::INSTALLING_WORKER); + swm->InvalidateServiceWorkerRegistrationWorker(mRegistration, + WhichServiceWorker::INSTALLING_WORKER); return NS_OK; } }; @@ -791,7 +803,7 @@ public: */ class FinishInstallHandler MOZ_FINAL : public PromiseNativeHandler { - nsMainThreadPtrHandle mRegistration; + nsMainThreadPtrHandle mRegistration; virtual ~FinishInstallHandler() @@ -799,7 +811,7 @@ class FinishInstallHandler MOZ_FINAL : public PromiseNativeHandler public: explicit FinishInstallHandler( - const nsMainThreadPtrHandle& aRegistration) + const nsMainThreadPtrHandle& aRegistration) : mRegistration(aRegistration) { MOZ_ASSERT(!NS_IsMainThread()); @@ -827,10 +839,10 @@ public: class FinishActivateHandler : public PromiseNativeHandler { - nsMainThreadPtrHandle mRegistration; + nsMainThreadPtrHandle mRegistration; public: - FinishActivateHandler(const nsMainThreadPtrHandle& aRegistration) + FinishActivateHandler(const nsMainThreadPtrHandle& aRegistration) : mRegistration(aRegistration) { MOZ_ASSERT(!NS_IsMainThread()); @@ -866,13 +878,13 @@ public: */ class InstallEventRunnable MOZ_FINAL : public WorkerRunnable { - nsMainThreadPtrHandle mRegistration; + nsMainThreadPtrHandle mRegistration; nsCString mScope; public: InstallEventRunnable( WorkerPrivate* aWorkerPrivate, - const nsMainThreadPtrHandle& aRegistration) + const nsMainThreadPtrHandle& aRegistration) : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount), mRegistration(aRegistration), mScope(aRegistration.get()->mScope) // copied for access on worker thread. @@ -935,11 +947,11 @@ private: class ActivateEventRunnable : public WorkerRunnable { - nsMainThreadPtrHandle mRegistration; + nsMainThreadPtrHandle mRegistration; public: ActivateEventRunnable(WorkerPrivate* aWorkerPrivate, - const nsMainThreadPtrHandle& aRegistration) + const nsMainThreadPtrHandle& aRegistration) : WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount), mRegistration(aRegistration) { @@ -998,17 +1010,17 @@ private: }; void -ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration, +ServiceWorkerManager::Install(ServiceWorkerRegistrationInfo* aRegistration, ServiceWorkerInfo* aServiceWorkerInfo) { AssertIsOnMainThread(); aRegistration->mInstallingWorker = aServiceWorkerInfo; MOZ_ASSERT(aRegistration->mInstallingWorker); - InvalidateServiceWorkerContainerWorker(aRegistration, - WhichServiceWorker::INSTALLING_WORKER); + InvalidateServiceWorkerRegistrationWorker(aRegistration, + WhichServiceWorker::INSTALLING_WORKER); - nsMainThreadPtrHandle handle( - new nsMainThreadPtrHolder(aRegistration)); + nsMainThreadPtrHandle handle( + new nsMainThreadPtrHolder(aRegistration)); nsRefPtr serviceWorker; nsresult rv = @@ -1042,15 +1054,15 @@ ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration, // a wait is likely to be required only when performing networking or storage // transactions in the first place. - FireEventOnServiceWorkerContainers(aRegistration, - NS_LITERAL_STRING("updatefound")); + FireEventOnServiceWorkerRegistrations(aRegistration, + NS_LITERAL_STRING("updatefound")); } class ActivationRunnable : public nsRunnable { - nsRefPtr mRegistration; + nsRefPtr mRegistration; public: - explicit ActivationRunnable(ServiceWorkerRegistration* aRegistration) + explicit ActivationRunnable(ServiceWorkerRegistrationInfo* aRegistration) : mRegistration(aRegistration) { } @@ -1065,13 +1077,13 @@ public: mRegistration->mCurrentWorker = mRegistration->mWaitingWorker.forget(); nsRefPtr swm = ServiceWorkerManager::GetInstance(); - swm->InvalidateServiceWorkerContainerWorker(mRegistration, - WhichServiceWorker::ACTIVE_WORKER | WhichServiceWorker::WAITING_WORKER); + swm->InvalidateServiceWorkerRegistrationWorker(mRegistration, + WhichServiceWorker::ACTIVE_WORKER | WhichServiceWorker::WAITING_WORKER); // FIXME(nsm): Steps 7 of the algorithm. - swm->FireEventOnServiceWorkerContainers(mRegistration, - NS_LITERAL_STRING("controllerchange")); + swm->FireEventOnServiceWorkerRegistrations(mRegistration, + NS_LITERAL_STRING("controllerchange")); MOZ_ASSERT(mRegistration->mCurrentWorker); nsRefPtr serviceWorker; @@ -1083,8 +1095,8 @@ public: return rv; } - nsMainThreadPtrHandle handle( - new nsMainThreadPtrHolder(mRegistration)); + nsMainThreadPtrHandle handle( + new nsMainThreadPtrHolder(mRegistration)); nsRefPtr r = new ActivateEventRunnable(serviceWorker->GetWorkerPrivate(), handle); @@ -1099,7 +1111,7 @@ public: }; void -ServiceWorkerManager::FinishInstall(ServiceWorkerRegistration* aRegistration) +ServiceWorkerManager::FinishInstall(ServiceWorkerRegistrationInfo* aRegistration) { AssertIsOnMainThread(); @@ -1118,8 +1130,8 @@ ServiceWorkerManager::FinishInstall(ServiceWorkerRegistration* aRegistration) aRegistration->mWaitingWorker = aRegistration->mInstallingWorker.forget(); MOZ_ASSERT(aRegistration->mWaitingWorker); - InvalidateServiceWorkerContainerWorker(aRegistration, - WhichServiceWorker::WAITING_WORKER | WhichServiceWorker::INSTALLING_WORKER); + InvalidateServiceWorkerRegistrationWorker(aRegistration, + WhichServiceWorker::WAITING_WORKER | WhichServiceWorker::INSTALLING_WORKER); // FIXME(nsm): Actually update state of active ServiceWorker instances to // installed. @@ -1140,7 +1152,7 @@ ServiceWorkerManager::FinishInstall(ServiceWorkerRegistration* aRegistration) } void -ServiceWorkerManager::FinishActivate(ServiceWorkerRegistration* aRegistration) +ServiceWorkerManager::FinishActivate(ServiceWorkerRegistrationInfo* aRegistration) { // FIXME(nsm): Set aRegistration->mCurrentWorker state to activated. // Fire statechange. @@ -1178,22 +1190,22 @@ ServiceWorkerManager::CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow, return rv; } -already_AddRefed -ServiceWorkerManager::GetServiceWorkerRegistration(nsPIDOMWindow* aWindow) +already_AddRefed +ServiceWorkerManager::GetServiceWorkerRegistrationInfo(nsPIDOMWindow* aWindow) { nsCOMPtr document = aWindow->GetExtantDoc(); - return GetServiceWorkerRegistration(document); + return GetServiceWorkerRegistrationInfo(document); } -already_AddRefed -ServiceWorkerManager::GetServiceWorkerRegistration(nsIDocument* aDoc) +already_AddRefed +ServiceWorkerManager::GetServiceWorkerRegistrationInfo(nsIDocument* aDoc) { nsCOMPtr documentURI = aDoc->GetDocumentURI(); - return GetServiceWorkerRegistration(documentURI); + return GetServiceWorkerRegistrationInfo(documentURI); } -already_AddRefed -ServiceWorkerManager::GetServiceWorkerRegistration(nsIURI* aURI) +already_AddRefed +ServiceWorkerManager::GetServiceWorkerRegistrationInfo(nsIURI* aURI) { nsRefPtr domainInfo = GetDomainInfo(aURI); if (!domainInfo) { @@ -1211,8 +1223,8 @@ ServiceWorkerManager::GetServiceWorkerRegistration(nsIURI* aURI) return nullptr; } - nsRefPtr registration; - domainInfo->mServiceWorkerRegistrations.Get(scope, getter_AddRefs(registration)); + nsRefPtr registration; + domainInfo->mServiceWorkerRegistrationInfos.Get(scope, getter_AddRefs(registration)); // ordered scopes and registrations better be in sync. MOZ_ASSERT(registration); @@ -1357,8 +1369,8 @@ ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc) return; } - nsRefPtr registration = - GetServiceWorkerRegistration(aDoc); + nsRefPtr registration = + GetServiceWorkerRegistrationInfo(aDoc); if (registration && registration->mCurrentWorker) { MOZ_ASSERT(!domainInfo->mControlledDocuments.Contains(aDoc)); registration->StartControllingADocument(); @@ -1381,7 +1393,7 @@ ServiceWorkerManager::MaybeStopControlling(nsIDocument* aDoc) return; } - nsRefPtr registration; + nsRefPtr registration; domainInfo->mControlledDocuments.Remove(aDoc, getter_AddRefs(registration)); // A document which was uncontrolled does not maintain that state itself, so // it will always call MaybeStopControlling() even if there isn't an @@ -1400,7 +1412,7 @@ ServiceWorkerManager::GetScopeForUrl(const nsAString& aUrl, nsAString& aScope) return NS_ERROR_FAILURE; } - nsRefPtr r = GetServiceWorkerRegistration(uri); + nsRefPtr r = GetServiceWorkerRegistrationInfo(uri); if (!r) { return NS_ERROR_FAILURE; } @@ -1410,7 +1422,7 @@ ServiceWorkerManager::GetScopeForUrl(const nsAString& aUrl, nsAString& aScope) } NS_IMETHODIMP -ServiceWorkerManager::AddContainerEventListener(nsIURI* aDocumentURI, nsIDOMEventTarget* aListener) +ServiceWorkerManager::AddRegistrationEventListener(nsIURI* aDocumentURI, nsIDOMEventTarget* aListener) { MOZ_ASSERT(aDocumentURI); nsRefPtr domainInfo = GetDomainInfo(aDocumentURI); @@ -1427,13 +1439,14 @@ ServiceWorkerManager::AddContainerEventListener(nsIURI* aDocumentURI, nsIDOMEven MOZ_ASSERT(domainInfo); - ServiceWorkerContainer* container = static_cast(aListener); - domainInfo->mServiceWorkerContainers.AppendElement(container); + // TODO: this is very very bad: + ServiceWorkerRegistration* registration = static_cast(aListener); + domainInfo->mServiceWorkerRegistrations.AppendElement(registration); return NS_OK; } NS_IMETHODIMP -ServiceWorkerManager::RemoveContainerEventListener(nsIURI* aDocumentURI, nsIDOMEventTarget* aListener) +ServiceWorkerManager::RemoveRegistrationEventListener(nsIURI* aDocumentURI, nsIDOMEventTarget* aListener) { MOZ_ASSERT(aDocumentURI); nsRefPtr domainInfo = GetDomainInfo(aDocumentURI); @@ -1441,14 +1454,14 @@ ServiceWorkerManager::RemoveContainerEventListener(nsIURI* aDocumentURI, nsIDOME return NS_OK; } - ServiceWorkerContainer* container = static_cast(aListener); - domainInfo->mServiceWorkerContainers.RemoveElement(container); + ServiceWorkerRegistration* registration = static_cast(aListener); + domainInfo->mServiceWorkerRegistrations.RemoveElement(registration); return NS_OK; } void -ServiceWorkerManager::FireEventOnServiceWorkerContainers( - ServiceWorkerRegistration* aRegistration, +ServiceWorkerManager::FireEventOnServiceWorkerRegistrations( + ServiceWorkerRegistrationInfo* aRegistration, const nsAString& aName) { AssertIsOnMainThread(); @@ -1456,9 +1469,9 @@ ServiceWorkerManager::FireEventOnServiceWorkerContainers( GetDomainInfo(aRegistration->mScriptSpec); if (domainInfo) { - nsTObserverArray::ForwardIterator it(domainInfo->mServiceWorkerContainers); + nsTObserverArray::ForwardIterator it(domainInfo->mServiceWorkerRegistrations); while (it.HasMore()) { - nsRefPtr target = it.GetNext(); + nsRefPtr target = it.GetNext(); nsIURI* targetURI = target->GetDocumentURI(); if (!targetURI) { NS_WARNING("Controlled domain cannot have page with null URI!"); @@ -1494,8 +1507,8 @@ ServiceWorkerManager::GetServiceWorkerForWindow(nsIDOMWindow* aWindow, nsCOMPtr window = do_QueryInterface(aWindow); MOZ_ASSERT(window); - nsRefPtr registration = - GetServiceWorkerRegistration(window); + nsRefPtr registration = + GetServiceWorkerRegistrationInfo(window); if (!registration) { return NS_ERROR_FAILURE; @@ -1549,7 +1562,7 @@ ServiceWorkerManager::GetDocumentController(nsIDOMWindow* aWindow, nsISupports** return NS_ERROR_FAILURE; } - nsRefPtr registration; + nsRefPtr registration; if (!domainInfo->mControlledDocuments.Get(doc, getter_AddRefs(registration))) { return NS_ERROR_FAILURE; } @@ -1615,7 +1628,7 @@ ServiceWorkerManager::CreateServiceWorker(const nsACString& aScriptSpec, // FIXME(nsm): Create correct principal based on app-ness. // Would it make sense to store the nsIPrincipal of the first register() in - // the ServiceWorkerRegistration and use that? + // the ServiceWorkerRegistrationInfo and use that? nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); rv = ssm->GetNoAppCodebasePrincipal(info.mBaseURI, getter_AddRefs(info.mPrincipal)); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -1642,17 +1655,17 @@ ServiceWorkerManager::CreateServiceWorker(const nsACString& aScriptSpec, } void -ServiceWorkerManager::InvalidateServiceWorkerContainerWorker(ServiceWorkerRegistration* aRegistration, - WhichServiceWorker aWhichOnes) +ServiceWorkerManager::InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration, + WhichServiceWorker aWhichOnes) { AssertIsOnMainThread(); nsRefPtr domainInfo = GetDomainInfo(aRegistration->mScriptSpec); if (domainInfo) { - nsTObserverArray::ForwardIterator it(domainInfo->mServiceWorkerContainers); + nsTObserverArray::ForwardIterator it(domainInfo->mServiceWorkerRegistrations); while (it.HasMore()) { - nsRefPtr target = it.GetNext(); + nsRefPtr target = it.GetNext(); nsIURI* targetURI = target->GetDocumentURI(); nsCString path; diff --git a/dom/workers/ServiceWorkerManager.h b/dom/workers/ServiceWorkerManager.h index 3693f562dceb..0411eedc51f2 100644 --- a/dom/workers/ServiceWorkerManager.h +++ b/dom/workers/ServiceWorkerManager.h @@ -16,6 +16,7 @@ #include "mozilla/WeakPtr.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/Promise.h" +#include "mozilla/dom/ServiceWorkerCommon.h" #include "nsRefPtrHashtable.h" #include "nsTArrayForwardDeclare.h" #include "nsTObserverArray.h" @@ -24,10 +25,12 @@ class nsIScriptError; namespace mozilla { namespace dom { + +class ServiceWorkerRegistration; + namespace workers { class ServiceWorker; -class ServiceWorkerContainer; class ServiceWorkerUpdateInstance; /** @@ -95,22 +98,13 @@ public: { } }; -// Use multiples of 2 since they can be bitwise ORed when calling -// InvalidateServiceWorkerContainerWorker. -MOZ_BEGIN_ENUM_CLASS(WhichServiceWorker) - INSTALLING_WORKER = 1, - WAITING_WORKER = 2, - ACTIVE_WORKER = 4, -MOZ_END_ENUM_CLASS(WhichServiceWorker) -MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(WhichServiceWorker) - // Needs to inherit from nsISupports because NS_ProxyRelease() does not support // non-ISupports classes. -class ServiceWorkerRegistration MOZ_FINAL : public nsISupports +class ServiceWorkerRegistrationInfo MOZ_FINAL : public nsISupports { uint32_t mControlledDocumentsCounter; - virtual ~ServiceWorkerRegistration(); + virtual ~ServiceWorkerRegistrationInfo(); public: NS_DECL_ISUPPORTS @@ -145,7 +139,7 @@ public: // pendingUninstall and when all controlling documents go away, removed. bool mPendingUninstall; - explicit ServiceWorkerRegistration(const nsACString& aScope); + explicit ServiceWorkerRegistrationInfo(const nsACString& aScope); already_AddRefed Newest() @@ -236,35 +230,35 @@ public: nsTArray mOrderedScopes; // Scope to registration. - nsRefPtrHashtable mServiceWorkerRegistrations; + nsRefPtrHashtable mServiceWorkerRegistrationInfos; // This array can't be stored in ServiceWorkerRegistration because one may // not exist when a certain window is opened, but we still want that // window's container to be notified if it's in scope. // The containers inform the SWM on creation and destruction. - nsTObserverArray mServiceWorkerContainers; + nsTObserverArray mServiceWorkerRegistrations; - nsRefPtrHashtable mControlledDocuments; + nsRefPtrHashtable mControlledDocuments; ServiceWorkerDomainInfo() { } - already_AddRefed + already_AddRefed GetRegistration(const nsCString& aScope) const { - nsRefPtr reg; - mServiceWorkerRegistrations.Get(aScope, getter_AddRefs(reg)); + nsRefPtr reg; + mServiceWorkerRegistrationInfos.Get(aScope, getter_AddRefs(reg)); return reg.forget(); } - ServiceWorkerRegistration* + ServiceWorkerRegistrationInfo* CreateNewRegistration(const nsCString& aScope) { - ServiceWorkerRegistration* registration = - new ServiceWorkerRegistration(aScope); + ServiceWorkerRegistrationInfo* registration = + new ServiceWorkerRegistrationInfo(aScope); // From now on ownership of registration is with - // mServiceWorkerRegistrations. - mServiceWorkerRegistrations.Put(aScope, registration); + // mServiceWorkerRegistrationInfos. + mServiceWorkerRegistrationInfos.Put(aScope, registration); ServiceWorkerManager::AddScope(mOrderedScopes, aScope); return registration; } @@ -279,26 +273,26 @@ public: nsRefPtrHashtable mDomainMap; void - ResolveRegisterPromises(ServiceWorkerRegistration* aRegistration, + ResolveRegisterPromises(ServiceWorkerRegistrationInfo* aRegistration, const nsACString& aWorkerScriptSpec); void - RejectUpdatePromiseObservers(ServiceWorkerRegistration* aRegistration, + RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration, nsresult aResult); void - RejectUpdatePromiseObservers(ServiceWorkerRegistration* aRegistration, + RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration, const ErrorEventInit& aErrorDesc); void - FinishFetch(ServiceWorkerRegistration* aRegistration, + FinishFetch(ServiceWorkerRegistrationInfo* aRegistration, nsPIDOMWindow* aWindow); void - FinishInstall(ServiceWorkerRegistration* aRegistration); + FinishInstall(ServiceWorkerRegistrationInfo* aRegistration); void - FinishActivate(ServiceWorkerRegistration* aRegistration); + FinishActivate(ServiceWorkerRegistrationInfo* aRegistration); void HandleError(JSContext* aCx, @@ -319,10 +313,10 @@ private: ~ServiceWorkerManager(); NS_IMETHOD - Update(ServiceWorkerRegistration* aRegistration, nsPIDOMWindow* aWindow); + Update(ServiceWorkerRegistrationInfo* aRegistration, nsPIDOMWindow* aWindow); void - Install(ServiceWorkerRegistration* aRegistration, + Install(ServiceWorkerRegistrationInfo* aRegistration, ServiceWorkerInfo* aServiceWorkerInfo); NS_IMETHOD @@ -356,17 +350,17 @@ private: nsISupports** aServiceWorker); void - InvalidateServiceWorkerContainerWorker(ServiceWorkerRegistration* aRegistration, - WhichServiceWorker aWhichOnes); + InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration, + WhichServiceWorker aWhichOnes); - already_AddRefed - GetServiceWorkerRegistration(nsPIDOMWindow* aWindow); + already_AddRefed + GetServiceWorkerRegistrationInfo(nsPIDOMWindow* aWindow); - already_AddRefed - GetServiceWorkerRegistration(nsIDocument* aDoc); + already_AddRefed + GetServiceWorkerRegistrationInfo(nsIDocument* aDoc); - already_AddRefed - GetServiceWorkerRegistration(nsIURI* aURI); + already_AddRefed + GetServiceWorkerRegistrationInfo(nsIURI* aURI); static void AddScope(nsTArray& aList, const nsACString& aScope); @@ -378,8 +372,8 @@ private: RemoveScope(nsTArray& aList, const nsACString& aScope); void - FireEventOnServiceWorkerContainers(ServiceWorkerRegistration* aRegistration, - const nsAString& aName); + FireEventOnServiceWorkerRegistrations(ServiceWorkerRegistrationInfo* aRegistration, + const nsAString& aName); }; diff --git a/dom/workers/ServiceWorkerRegistration.cpp b/dom/workers/ServiceWorkerRegistration.cpp new file mode 100644 index 000000000000..14c017156a9d --- /dev/null +++ b/dom/workers/ServiceWorkerRegistration.cpp @@ -0,0 +1,197 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "ServiceWorkerRegistration.h" + +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/ServiceWorkerRegistrationBinding.h" +#include "nsCycleCollectionParticipant.h" +#include "nsServiceManagerUtils.h" +#include "ServiceWorker.h" + +#include "nsIServiceWorkerManager.h" +#include "nsPIDOMWindow.h" + +using namespace mozilla::dom::workers; + +namespace mozilla { +namespace dom { + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistration) +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) + +NS_IMPL_ADDREF_INHERITED(ServiceWorkerRegistration, DOMEventTargetHelper) +NS_IMPL_RELEASE_INHERITED(ServiceWorkerRegistration, DOMEventTargetHelper) + +NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistration, + DOMEventTargetHelper, + mWindow, + mInstallingWorker, + mWaitingWorker, + mActiveWorker) + +ServiceWorkerRegistration::ServiceWorkerRegistration(nsPIDOMWindow* aWindow, + const nsAString& aScope) + : mWindow(aWindow) + , mScope(aScope) +{ + MOZ_ASSERT(aWindow); + + SetIsDOMBinding(); + StartListeningForEvents(); +} + +ServiceWorkerRegistration::~ServiceWorkerRegistration() +{ + StopListeningForEvents(); +} + +JSObject* +ServiceWorkerRegistration::WrapObject(JSContext* aCx) +{ + return ServiceWorkerRegistrationBinding::Wrap(aCx, this); +} + +already_AddRefed +ServiceWorkerRegistration::GetInstalling() +{ + if (!mInstallingWorker) { + mInstallingWorker = GetWorkerReference(WhichServiceWorker::INSTALLING_WORKER); + } + + nsRefPtr ret = mInstallingWorker; + return ret.forget(); +} + +already_AddRefed +ServiceWorkerRegistration::GetWaiting() +{ + if (!mWaitingWorker) { + mWaitingWorker = GetWorkerReference(WhichServiceWorker::WAITING_WORKER); + } + + nsRefPtr ret = mWaitingWorker; + return ret.forget(); +} + +already_AddRefed +ServiceWorkerRegistration::GetActive() +{ + if (!mActiveWorker) { + mActiveWorker = GetWorkerReference(WhichServiceWorker::ACTIVE_WORKER); + } + + nsRefPtr ret = mActiveWorker; + return ret.forget(); +} + +already_AddRefed +ServiceWorkerRegistration::Unregister(ErrorResult& aRv) +{ + nsCOMPtr promise; + + nsresult rv; + nsCOMPtr swm = + do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return nullptr; + } + + aRv = swm->Unregister(mWindow, mScope, getter_AddRefs(promise)); + if (aRv.Failed()) { + return nullptr; + } + + nsRefPtr ret = static_cast(promise.get()); + MOZ_ASSERT(ret); + return ret.forget(); +} + +already_AddRefed +ServiceWorkerRegistration::GetWorkerReference(WhichServiceWorker aWhichOne) +{ + nsresult rv; + nsCOMPtr swm = + do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + nsCOMPtr serviceWorker; + switch(aWhichOne) { + case WhichServiceWorker::INSTALLING_WORKER: + rv = swm->GetInstalling(mWindow, getter_AddRefs(serviceWorker)); + break; + case WhichServiceWorker::WAITING_WORKER: + rv = swm->GetWaiting(mWindow, getter_AddRefs(serviceWorker)); + break; + case WhichServiceWorker::ACTIVE_WORKER: + rv = swm->GetActive(mWindow, getter_AddRefs(serviceWorker)); + break; + default: + MOZ_CRASH("Invalid enum value"); + } + + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + nsRefPtr ref = + static_cast(serviceWorker.get()); + return ref.forget(); +} + +void +ServiceWorkerRegistration::InvalidateWorkerReference(WhichServiceWorker aWhichOnes) +{ + if (aWhichOnes & WhichServiceWorker::INSTALLING_WORKER) { + mInstallingWorker = nullptr; + } + + if (aWhichOnes & WhichServiceWorker::WAITING_WORKER) { + mWaitingWorker = nullptr; + } + + if (aWhichOnes & WhichServiceWorker::ACTIVE_WORKER) { + mActiveWorker = nullptr; + } +} + +// XXXnsm, maybe this can be optimized to only add when a event handler is +// registered. +void +ServiceWorkerRegistration::StartListeningForEvents() +{ + nsCOMPtr swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID); + MOZ_ASSERT(mWindow); + + if (swm) { + swm->AddRegistrationEventListener(GetDocumentURI(), this); + } +} + +void +ServiceWorkerRegistration::StopListeningForEvents() +{ + nsCOMPtr swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID); + + // StopListeningForEvents is called in the dtor, and it can happen that + // SnowWhite had already set to null mWindow. + if (swm && mWindow) { + swm->RemoveRegistrationEventListener(GetDocumentURI(), this); + } +} + +nsIURI* +ServiceWorkerRegistration::GetDocumentURI() const +{ + MOZ_ASSERT(mWindow); + return mWindow->GetDocumentURI(); +} + +} // dom namespace +} // mozilla namespace diff --git a/dom/workers/ServiceWorkerRegistration.h b/dom/workers/ServiceWorkerRegistration.h new file mode 100644 index 000000000000..2ebfc26c0d05 --- /dev/null +++ b/dom/workers/ServiceWorkerRegistration.h @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_dom_ServiceWorkerRegistration_h +#define mozilla_dom_ServiceWorkerRegistration_h + +#include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/dom/ServiceWorkerCommon.h" + +class nsPIDOMWindow; + +namespace mozilla { +namespace dom { + +class Promise; + +namespace workers { +class ServiceWorker; +} + +class ServiceWorkerRegistration MOZ_FINAL : public DOMEventTargetHelper +{ +public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistration, + DOMEventTargetHelper) + + IMPL_EVENT_HANDLER(updatefound) + + ServiceWorkerRegistration(nsPIDOMWindow* aWindow, + const nsAString& aScope); + + nsPIDOMWindow* + GetParentObject() const + { + return mWindow; + } + + JSObject* + WrapObject(JSContext* aCx); + + already_AddRefed + GetInstalling(); + + already_AddRefed + GetWaiting(); + + already_AddRefed + GetActive(); + + void + GetScope(nsAString& aScope) const + { + aScope = mScope; + } + + already_AddRefed + Unregister(ErrorResult& aRv); + + // Useful methods for ServiceWorkerManager: + + nsIURI* + GetDocumentURI() const; + + void + InvalidateWorkerReference(WhichServiceWorker aWhichOnes); + +private: + ~ServiceWorkerRegistration(); + + already_AddRefed + GetWorkerReference(WhichServiceWorker aWhichOne); + + void + StartListeningForEvents(); + + void + StopListeningForEvents(); + + nsCOMPtr mWindow; + + // The following properties are cached here to ensure JS equality is satisfied + // instead of acquiring a new worker instance from the ServiceWorkerManager + // for every access. A null value is considered a cache miss. + // These three may change to a new worker at any time. + nsRefPtr mInstallingWorker; + nsRefPtr mWaitingWorker; + nsRefPtr mActiveWorker; + + const nsString mScope; +}; + +} // namespace dom +} // namespace mozilla + +#endif /* mozilla_dom_ServiceWorkerRegistration_h */ diff --git a/dom/workers/moz.build b/dom/workers/moz.build index eee48316a6a8..1bb0b2dae9f7 100644 --- a/dom/workers/moz.build +++ b/dom/workers/moz.build @@ -6,7 +6,9 @@ # Public stuff. EXPORTS.mozilla.dom += [ + 'ServiceWorkerCommon.h', 'ServiceWorkerContainer.h', + 'ServiceWorkerRegistration.h', 'WorkerPrivate.h', 'WorkerRunnable.h', 'WorkerScope.h', @@ -50,6 +52,7 @@ SOURCES += [ 'ServiceWorkerContainer.cpp', 'ServiceWorkerEvents.cpp', 'ServiceWorkerManager.cpp', + 'ServiceWorkerRegistration.cpp', 'SharedWorker.cpp', 'URL.cpp', 'WorkerPrivate.cpp', diff --git a/dom/workers/test/serviceworkers/controller/index.html b/dom/workers/test/serviceworkers/controller/index.html index da15814e0e18..11907dbc9bad 100644 --- a/dom/workers/test/serviceworkers/controller/index.html +++ b/dom/workers/test/serviceworkers/controller/index.html @@ -32,9 +32,21 @@ // We are controlled. // Register a new worker for this sub-scope. After that, controller should still be for upper level, but active should change to be this scope's. navigator.serviceWorker.register("../worker2.js", { scope: "./*" }).then(function(e) { - my_ok(navigator.serviceWorker.installing && - navigator.serviceWorker.installing.scope.match(/controller\/\*$/), + my_ok("installing" in e, "ServiceWorkerRegistration.installing exists."); + my_ok(e.installing instanceof ServiceWorker, "ServiceWorkerRegistration.installing is a ServiceWorker."); + + my_ok("waiting" in e, "ServiceWorkerRegistration.waiting exists."); + my_ok("active" in e, "ServiceWorkerRegistration.active exists."); + + my_ok(e.installing && + e.installing.scope.match(/controller\/\*$/), "Installing is serviceworker/controller/*"); + + my_ok("scope" in e, "ServiceWorkerRegistration.scope exists."); + my_ok(e.scope.match(/serviceworkers\/controller\/\*$/), "Scope is serviceworker/*: " + e.scope); + + my_ok("unregister" in e, "ServiceWorkerRegistration.unregister exists."); + my_ok(navigator.serviceWorker.controller.scope.match(/serviceworkers\/control\*$/), "Controller is still serviceworker/*"); finish(); diff --git a/dom/workers/test/serviceworkers/test_install_event.html b/dom/workers/test/serviceworkers/test_install_event.html index dcea3d78adcf..a5f5aec97cd0 100644 --- a/dom/workers/test/serviceworkers/test_install_event.html +++ b/dom/workers/test/serviceworkers/test_install_event.html @@ -20,11 +20,11 @@ return p; } - function nextRegister() { + function nextRegister(reg) { var p = navigator.serviceWorker.register("install_event_worker.js", { scope: "./*" }); return new Promise(function(resolve, reject) { - navigator.serviceWorker.onupdatefound = function(e) { + reg.onupdatefound = function(e) { ok(true, "Received onupdatefound"); resolve(); }; diff --git a/dom/workers/test/serviceworkers/test_installation_simple.html b/dom/workers/test/serviceworkers/test_installation_simple.html index ed80fcc21d4d..c0721b0a5d13 100644 --- a/dom/workers/test/serviceworkers/test_installation_simple.html +++ b/dom/workers/test/serviceworkers/test_installation_simple.html @@ -57,11 +57,12 @@ function realWorker() { var p = navigator.serviceWorker.register("worker.js", { scope: "realworker*" }); - return p.then(function(w) { - ok(w instanceof ServiceWorker, "Register a ServiceWorker"); - info(w.scope); - ok(w.scope == (new URL("realworker*", document.baseURI)).href, "Scope should match"); - ok(w.url == (new URL("worker.js", document.baseURI)).href, "URL should be of the worker"); + return p.then(function(wr) { + ok(wr instanceof ServiceWorkerRegistration, "Register a ServiceWorker"); + + info(wr.scope); + ok(wr.scope == (new URL("realworker*", document.baseURI)).href, "Scope should match"); + }, function(e) { info("Error: " + e.name); ok(false, "realWorker Registration should have succeeded!"); @@ -73,14 +74,14 @@ var q = navigator.serviceWorker.register("worker3.js", { scope: "foo/*" }); return Promise.all([ - p.then(function(w) { + p.then(function(wr) { ok(false, "First registration should fail with AbortError"); }, function(e) { ok(e.name === "AbortError", "First registration should fail with AbortError"); }), - q.then(function(w) { - ok(w instanceof ServiceWorker, "Second registration should succeed"); + q.then(function(wr) { + ok(wr instanceof ServiceWorkerRegistration, "Second registration should succeed"); }, function(e) { ok(false, "Second registration should succeed"); }) @@ -97,7 +98,7 @@ function parseError() { var p = navigator.serviceWorker.register("parse_error_worker.js"); - return p.then(function(w) { + return p.then(function(wr) { ok(false, "Registration should fail with parse error"); }, function(e) { info("NSM " + e.name); @@ -107,6 +108,7 @@ // FIXME(nsm): test for parse error when Update step doesn't happen (directly from register). + /* FIXME bug 1002571 - re-enable this test when GetRegistration is implemented. function updatefound() { var frame = document.createElement("iframe"); frame.setAttribute("id", "simpleregister-frame"); @@ -137,6 +139,7 @@ } return p; } + */ function runTest() { simpleRegister() @@ -147,7 +150,6 @@ .then(abortPrevious) .then(networkError404) .then(parseError) - .then(updatefound) // put more tests here. .then(function() { SimpleTest.finish(); diff --git a/dom/workers/test/serviceworkers/test_navigator.html b/dom/workers/test/serviceworkers/test_navigator.html index 0f4c1391deda..cb8936e22bcc 100644 --- a/dom/workers/test/serviceworkers/test_navigator.html +++ b/dom/workers/test/serviceworkers/test_navigator.html @@ -18,12 +18,9 @@ function checkEnabled() { ok(navigator.serviceWorker, "navigator.serviceWorker should exist when ServiceWorkers are enabled."); ok(typeof navigator.serviceWorker.register === "function", "navigator.serviceWorker.register() should be a function."); - ok(typeof navigator.serviceWorker.unregister === "function", "navigator.serviceWorker.unregister() should be a function."); - ok(typeof navigator.serviceWorker.getAll === "function", "navigator.serviceWorker.getAll() should be a function."); + ok(typeof navigator.serviceWorker.getRegistration === "function", "navigator.serviceWorker.getAll() should be a function."); + ok(typeof navigator.serviceWorker.getRegistrations === "function", "navigator.serviceWorker.getAll() should be a function."); ok(navigator.serviceWorker.ready instanceof Promise, "navigator.serviceWorker.ready should be a Promise."); - ok(navigator.serviceWorker.installing === null, "There should be no installing worker for an uncontrolled scope."); - ok(navigator.serviceWorker.waiting === null, "There should be no waiting worker for an uncontrolled scope."); - // ok(navigator.serviceWorker.active === null, "There should be no active worker for an uncontrolled scope."); ok(navigator.serviceWorker.controller === null, "There should be no controller worker for an uncontrolled document."); } diff --git a/dom/xml/XMLDocument.cpp b/dom/xml/XMLDocument.cpp index 6221c63e0c9f..30d743009223 100644 --- a/dom/xml/XMLDocument.cpp +++ b/dom/xml/XMLDocument.cpp @@ -302,8 +302,7 @@ XMLDocument::Load(const nsAString& aUrl, ErrorResult& aRv) WarnOnceAbout(nsIDocument::eUseOfDOM3LoadMethod); - nsCOMPtr callingDoc = nsContentUtils::GetDocumentFromContext(); - + nsCOMPtr callingDoc = GetEntryDocument(); nsIURI *baseURI = mDocumentURI; nsAutoCString charset; diff --git a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp index 5c42e0841ca8..4aa435cd83eb 100644 --- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp +++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp @@ -65,6 +65,7 @@ #endif using namespace mozilla; +using namespace mozilla::dom; /**************************************************************** ******************** nsWatcherWindowEntry ********************** @@ -886,7 +887,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent, } nsCOMPtr referrerWindow = - do_QueryInterface(dom::BrokenGetEntryGlobal()); + do_QueryInterface(GetEntryGlobal()); if (!referrerWindow) { referrerWindow = do_QueryInterface(aParent); } @@ -1345,18 +1346,8 @@ nsWindowWatcher::URIfromURL(const char *aURL, nsIDOMWindow *aParent, nsIURI **aURI) { - nsCOMPtr baseWindow; - - /* build the URI relative to the calling JS Context, if any. - (note this is the same context used to make the security check - in nsGlobalWindow.cpp.) */ - JSContext *cx = nsContentUtils::GetCurrentJSContext(); - if (cx) { - nsIScriptContext *scriptcx = nsJSUtils::GetDynamicScriptContext(cx); - if (scriptcx) { - baseWindow = do_QueryInterface(scriptcx->GetGlobalObject()); - } - } + // Build the URI relative to the entry global. + nsCOMPtr baseWindow = do_QueryInterface(GetEntryGlobal()); // failing that, build it relative to the parent window, if possible if (!baseWindow) @@ -1726,16 +1717,8 @@ nsWindowWatcher::FindItemWithName(const char16_t* aName, already_AddRefed nsWindowWatcher::GetCallerTreeItem(nsIDocShellTreeItem* aParentItem) { - JSContext *cx = nsContentUtils::GetCurrentJSContext(); - nsCOMPtr callerItem; - - if (cx) { - nsCOMPtr callerWebNav = - do_GetInterface(nsJSUtils::GetDynamicScriptGlobal(cx)); - - callerItem = do_QueryInterface(callerWebNav); - } - + nsCOMPtr callerWebNav = do_GetInterface(GetEntryGlobal()); + nsCOMPtr callerItem = do_QueryInterface(callerWebNav); if (!callerItem) { callerItem = aParentItem; } diff --git a/gfx/2d/BaseCoord.h b/gfx/2d/BaseCoord.h new file mode 100644 index 000000000000..bbccbc7ae64a --- /dev/null +++ b/gfx/2d/BaseCoord.h @@ -0,0 +1,110 @@ +/* -*- Mode: C++; 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/. */ + +#ifndef MOZILLA_GFX_BASECOORD_H_ +#define MOZILLA_GFX_BASECOORD_H_ + +#include "mozilla/Attributes.h" + +namespace mozilla { +namespace gfx { + +/** + * Do not use this class directly. Subclass it, pass that subclass as the + * Sub parameter, and only use that subclass. This allows methods to safely + * cast 'this' to 'Sub*'. + */ +template +struct BaseCoord { + T value; + + // Constructors + MOZ_CONSTEXPR BaseCoord() : value(0) {} + explicit MOZ_CONSTEXPR BaseCoord(T aValue) : value(aValue) {} + + // Note that '=' isn't defined so we'll get the + // compiler generated default assignment operator + + operator T() const { return value; } + + friend bool operator==(Sub aA, Sub aB) { + return aA.value == aB.value; + } + friend bool operator!=(Sub aA, Sub aB) { + return aA.value != aB.value; + } + + friend Sub operator+(Sub aA, Sub aB) { + return Sub(aA.value + aB.value); + } + friend Sub operator-(Sub aA, Sub aB) { + return Sub(aA.value - aB.value); + } + friend Sub operator*(Sub aCoord, T aScale) { + return Sub(aCoord.value * aScale); + } + friend Sub operator*(T aScale, Sub aCoord) { + return Sub(aScale * aCoord.value); + } + friend Sub operator/(Sub aCoord, T aScale) { + return Sub(aCoord.value / aScale); + } + // 'scale / coord' is intentionally omitted because it doesn't make sense. + + Sub& operator+=(Sub aCoord) { + value += aCoord.value; + return *static_cast(this); + } + Sub& operator-=(Sub aCoord) { + value -= aCoord.value; + return *static_cast(this); + } + Sub& operator*=(T aScale) { + value *= aScale; + return *static_cast(this); + } + Sub& operator/=(T aScale) { + value /= aScale; + return *static_cast(this); + } + + // Since BaseCoord is implicitly convertible to its value type T, we need + // mixed-type operator overloads to avoid ambiguities at mixed-type call + // sites. As we transition more of our code to strongly-typed classes, we + // may be able to remove some or all of these overloads. + friend bool operator==(Sub aA, T aB) { + return aA.value == aB; + } + friend bool operator==(T aA, Sub aB) { + return aA == aB.value; + } + friend bool operator!=(Sub aA, T aB) { + return aA.value != aB; + } + friend bool operator!=(T aA, Sub aB) { + return aA != aB.value; + } + friend T operator+(Sub aA, T aB) { + return aA.value + aB; + } + friend T operator+(T aA, Sub aB) { + return aA + aB.value; + } + friend T operator-(Sub aA, T aB) { + return aA.value - aB; + } + friend T operator-(T aA, Sub aB) { + return aA - aB.value; + } + + Sub operator-() const { + return Sub(-value); + } +}; + +} +} + +#endif /* MOZILLA_GFX_BASECOORD_H_ */ diff --git a/gfx/2d/BasePoint.h b/gfx/2d/BasePoint.h index 9323c2e4fb2f..d9607a258b92 100644 --- a/gfx/2d/BasePoint.h +++ b/gfx/2d/BasePoint.h @@ -17,13 +17,13 @@ namespace gfx { * Sub parameter, and only use that subclass. This allows methods to safely * cast 'this' to 'Sub*'. */ -template +template struct BasePoint { - T x, y; + Coord x, y; // Constructors MOZ_CONSTEXPR BasePoint() : x(0), y(0) {} - MOZ_CONSTEXPR BasePoint(T aX, T aY) : x(aX), y(aY) {} + MOZ_CONSTEXPR BasePoint(Coord aX, Coord aY) : x(aX), y(aY) {} void MoveTo(T aX, T aY) { x = aX; y = aY; } void MoveBy(T aDx, T aDy) { x += aDx; y += aDy; } @@ -67,15 +67,15 @@ struct BasePoint { } T Length() const { - return hypot(x, y); + return hypot(x.value, y.value); } // Round() is *not* rounding to nearest integer if the values are negative. // They are always rounding as floor(n + 0.5). // See https://bugzilla.mozilla.org/show_bug.cgi?id=410748#c14 Sub& Round() { - x = static_cast(floor(x + 0.5)); - y = static_cast(floor(y + 0.5)); + x = Coord(floor(T(x) + T(0.5))); + y = Coord(floor(T(y) + T(0.5))); return *static_cast(this); } diff --git a/gfx/2d/Blur.cpp b/gfx/2d/Blur.cpp index 9b99c1a8389f..82db8dfeb7f8 100644 --- a/gfx/2d/Blur.cpp +++ b/gfx/2d/Blur.cpp @@ -734,8 +734,8 @@ static const Float GAUSSIAN_SCALE_FACTOR = Float((3 * sqrt(2 * M_PI) / 4) * 1.5) IntSize AlphaBoxBlur::CalculateBlurRadius(const Point& aStd) { - IntSize size(static_cast(floor(aStd.x * GAUSSIAN_SCALE_FACTOR + 0.5)), - static_cast(floor(aStd.y * GAUSSIAN_SCALE_FACTOR + 0.5))); + IntSize size(static_cast(floor(aStd.x * GAUSSIAN_SCALE_FACTOR + 0.5f)), + static_cast(floor(aStd.y * GAUSSIAN_SCALE_FACTOR + 0.5f))); return size; } diff --git a/gfx/2d/Coord.h b/gfx/2d/Coord.h new file mode 100644 index 000000000000..ac94a73a7f02 --- /dev/null +++ b/gfx/2d/Coord.h @@ -0,0 +1,142 @@ +/* -*- Mode: C++; tab-width: 20; 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/. */ + +#ifndef MOZILLA_GFX_COORD_H_ +#define MOZILLA_GFX_COORD_H_ + +#include "mozilla/Attributes.h" +#include "Types.h" +#include "BaseCoord.h" + +#include + +namespace mozilla { + +template struct IsPixel; + +namespace gfx { + +template struct IntCoordTyped; +template struct CoordTyped; + +// CommonType is a metafunction that returns the type of the +// result of an arithmetic operation on the underlying type of a strongly-typed +// coordinate type 'coord', and a primitive type 'primitive'. C++ rules for +// arithmetic conversions are designed to avoid losing information - for +// example, the result of adding an int and a float is a float - and we want +// the same behaviour when mixing our coordinate types with primitive types. +// We get C++ to compute the desired result type using 'decltype'. + +template +struct CommonType; + +template +struct CommonType, primitive> { + typedef decltype(int32_t() + primitive()) type; +}; + +template +struct CommonType, primitive> { + typedef decltype(Float() + primitive()) type; +}; + +// This is a base class that provides mixed-type operator overloads between +// a strongly-typed Coord and a primitive value. It is needed to avoid +// ambiguities at mixed-type call sites, because Coord classes are implicitly +// convertible to their underlying value type. As we transition more of our code +// to strongly-typed classes, we may be able to remove some or all of these +// overloads. +template +struct CoordOperatorsHelper { + friend bool operator==(coord aA, primitive aB) { + return aA.value == aB; + } + friend bool operator==(primitive aA, coord aB) { + return aA == aB.value; + } + friend bool operator!=(coord aA, primitive aB) { + return aA.value != aB; + } + friend bool operator!=(primitive aA, coord aB) { + return aA != aB.value; + } + + typedef typename CommonType::type result_type; + + friend result_type operator+(coord aA, primitive aB) { + return aA.value + aB; + } + friend result_type operator+(primitive aA, coord aB) { + return aA + aB.value; + } + friend result_type operator-(coord aA, primitive aB) { + return aA.value - aB; + } + friend result_type operator-(primitive aA, coord aB) { + return aA - aB.value; + } + friend result_type operator*(coord aCoord, primitive aScale) { + return aCoord.value * aScale; + } + friend result_type operator*(primitive aScale, coord aCoord) { + return aScale * aCoord.value; + } + friend result_type operator/(coord aCoord, primitive aScale) { + return aCoord.value / aScale; + } + // 'scale / coord' is intentionally omitted because it doesn't make sense. +}; + +// Note: 'IntCoordTyped' and 'CoordTyped' do not derive from +// 'units' to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61959. + +template +struct IntCoordTyped : + public BaseCoord< int32_t, IntCoordTyped >, + public CoordOperatorsHelper< IntCoordTyped, float >, + public CoordOperatorsHelper< IntCoordTyped, double > { + static_assert(IsPixel::value, + "'units' must be a coordinate system tag"); + + typedef BaseCoord< int32_t, IntCoordTyped > Super; + + MOZ_CONSTEXPR IntCoordTyped() : Super() {} + MOZ_CONSTEXPR IntCoordTyped(int32_t aValue) : Super(aValue) {} +}; + +template +struct CoordTyped : + public BaseCoord< Float, CoordTyped >, + public CoordOperatorsHelper< CoordTyped, int32_t >, + public CoordOperatorsHelper< CoordTyped, uint32_t >, + public CoordOperatorsHelper< CoordTyped, double > { + static_assert(IsPixel::value, + "'units' must be a coordinate system tag"); + + typedef BaseCoord< Float, CoordTyped > Super; + + MOZ_CONSTEXPR CoordTyped() : Super() {} + MOZ_CONSTEXPR CoordTyped(Float aValue) : Super(aValue) {} + explicit MOZ_CONSTEXPR CoordTyped(const IntCoordTyped& aCoord) : Super(float(aCoord.value)) {} + + void Round() { + this->value = floor(this->value + 0.5); + } + void Truncate() { + this->value = int32_t(this->value); + } + + IntCoordTyped Rounded() const { + return IntCoordTyped(int32_t(floor(this->value + 0.5))); + } + IntCoordTyped Truncated() const { + return IntCoordTyped(int32_t(this->value)); + } +}; + +} +} + +#endif /* MOZILLA_GFX_COORD_H_ */ diff --git a/gfx/2d/DrawTargetD2D.cpp b/gfx/2d/DrawTargetD2D.cpp index 768197a73138..bee062c33347 100644 --- a/gfx/2d/DrawTargetD2D.cpp +++ b/gfx/2d/DrawTargetD2D.cpp @@ -2599,7 +2599,7 @@ DrawTargetD2D::SetupEffectForRadialGradient(const RadialGradientPattern *aPatter mPrivateData->mEffect->GetVariableByName("DeviceSpaceToUserSpace")-> AsMatrix()->SetMatrix(matrix); - float A = dc.x * dc.x + dc.y * dc.y - dr * dr; + float A = dc.x.value * dc.x.value + dc.y.value * dc.y.value - dr * dr; uint32_t offset = 0; switch (stops->mStopCollection->GetExtendMode()) { diff --git a/gfx/2d/DrawTargetTiled.cpp b/gfx/2d/DrawTargetTiled.cpp index 34370a34b6ac..d4a072431a60 100644 --- a/gfx/2d/DrawTargetTiled.cpp +++ b/gfx/2d/DrawTargetTiled.cpp @@ -35,8 +35,8 @@ DrawTargetTiled::Init(const TileSet& aTiles) mTiles[i].mTileOrigin.x + mTiles[i].mDrawTarget->GetSize().width); uint32_t newYMost = max(mRect.YMost(), mTiles[i].mTileOrigin.y + mTiles[i].mDrawTarget->GetSize().height); - mRect.x = min(mRect.x, mTiles[i].mTileOrigin.x); - mRect.y = min(mRect.y, mTiles[i].mTileOrigin.y); + mRect.x = min(mRect.x, mTiles[i].mTileOrigin.x.value); + mRect.y = min(mRect.y, mTiles[i].mTileOrigin.y.value); mRect.width = newXMost - mRect.x; mRect.height = newYMost - mRect.y; } diff --git a/gfx/2d/HelpersD2D.h b/gfx/2d/HelpersD2D.h index ecb792633549..941c92912f43 100644 --- a/gfx/2d/HelpersD2D.h +++ b/gfx/2d/HelpersD2D.h @@ -239,7 +239,7 @@ static inline bool IsPatternSupportedByD2D(const Pattern &aPattern) Point diff = pat->mCenter2 - pat->mCenter1; - if (sqrt(diff.x * diff.x + diff.y * diff.y) >= pat->mRadius2) { + if (sqrt(diff.x.value * diff.x.value + diff.y.value * diff.y.value) >= pat->mRadius2) { // Inner point lies outside the circle. return false; } diff --git a/gfx/2d/Path.cpp b/gfx/2d/Path.cpp index 268e8b810110..3540b6f25615 100644 --- a/gfx/2d/Path.cpp +++ b/gfx/2d/Path.cpp @@ -107,7 +107,7 @@ FlattenedPath::QuadraticBezierTo(const Point &aCP1, const Point &aCP2) { MOZ_ASSERT(!mCalculatedLength); - // We need to elevate the degree of this quadratic Bézier to cubic, so we're + // We need to elevate the degree of this quadratic B�zier to cubic, so we're // going to add an intermediate control point, and recompute control point 1. // The first and last control points remain the same. // This formula can be found on http://fontforge.sourceforge.net/bezier.html @@ -250,7 +250,7 @@ FlattenBezierCurveSegment(const BezierControlPoints &aControlPoints, Point cp21 = currentCP.mCP2 - currentCP.mCP3; Point cp31 = currentCP.mCP3 - currentCP.mCP1; - Float s3 = (cp31.x * cp21.y - cp31.y * cp21.x) / hypotf(cp21.x, cp21.y); + Float s3 = (cp31.x.value * cp21.y.value - cp31.y.value * cp21.x.value) / hypotf(cp21.x, cp21.y); t = 2 * Float(sqrt(aTolerance / (3. * abs(s3)))); @@ -276,7 +276,7 @@ FindInflectionApproximationRange(BezierControlPoints aControlPoints, Point cp21 = aControlPoints.mCP2 - aControlPoints.mCP1; Point cp41 = aControlPoints.mCP4 - aControlPoints.mCP1; - if (cp21.x == 0 && cp21.y == 0) { + if (cp21.x == 0.f && cp21.y == 0.f) { // In this case s3 becomes lim[n->0] (cp41.x * n) / n - (cp41.y * n) / n = cp41.x - cp41.y. // Use the absolute value so that Min and Max will correspond with the @@ -286,7 +286,7 @@ FindInflectionApproximationRange(BezierControlPoints aControlPoints, return; } - Float s3 = (cp41.x * cp21.y - cp41.y * cp21.x) / hypotf(cp21.x, cp21.y); + Float s3 = (cp41.x.value * cp21.y.value - cp41.y.value * cp21.x.value) / hypotf(cp21.x, cp21.y); if (s3 == 0) { // This means within the precision we have it can be approximated diff --git a/gfx/2d/PathHelpers.h b/gfx/2d/PathHelpers.h index 56d493e4d315..80963cd1af4f 100644 --- a/gfx/2d/PathHelpers.h +++ b/gfx/2d/PathHelpers.h @@ -16,8 +16,8 @@ template void ArcToBezier(T* aSink, const Point &aOrigin, const Size &aRadius, float aStartAngle, float aEndAngle, bool aAntiClockwise) { - Point startPoint(aOrigin.x + cos(aStartAngle) * aRadius.width, - aOrigin.y + sin(aStartAngle) * aRadius.height); + Point startPoint(aOrigin.x + cosf(aStartAngle) * aRadius.width, + aOrigin.y + sinf(aStartAngle) * aRadius.height); aSink->LineTo(startPoint); @@ -56,10 +56,10 @@ void ArcToBezier(T* aSink, const Point &aOrigin, const Size &aRadius, currentEndAngle = currentStartAngle + arcSweepLeft * sweepDirection; } - Point currentStartPoint(aOrigin.x + cos(currentStartAngle) * aRadius.width, - aOrigin.y + sin(currentStartAngle) * aRadius.height); - Point currentEndPoint(aOrigin.x + cos(currentEndAngle) * aRadius.width, - aOrigin.y + sin(currentEndAngle) * aRadius.height); + Point currentStartPoint(aOrigin.x + cosf(currentStartAngle) * aRadius.width, + aOrigin.y + sinf(currentStartAngle) * aRadius.height); + Point currentEndPoint(aOrigin.x + cosf(currentEndAngle) * aRadius.width, + aOrigin.y + sinf(currentEndAngle) * aRadius.height); // Calculate kappa constant for partial curve. The sign of angle in the // tangent will actually ensure this is negative for a counter clockwise diff --git a/gfx/2d/PathSkia.cpp b/gfx/2d/PathSkia.cpp index 83ab501fbae2..efa0c6f56b45 100644 --- a/gfx/2d/PathSkia.cpp +++ b/gfx/2d/PathSkia.cpp @@ -141,10 +141,10 @@ PathSkia::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const } SkRegion pointRect; - pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1)), - int32_t(SkFloatToScalar(transformed.y - 1)), - int32_t(SkFloatToScalar(transformed.x + 1)), - int32_t(SkFloatToScalar(transformed.y + 1))); + pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1.f)), + int32_t(SkFloatToScalar(transformed.y - 1.f)), + int32_t(SkFloatToScalar(transformed.x + 1.f)), + int32_t(SkFloatToScalar(transformed.y + 1.f))); SkRegion pathRegion; @@ -174,10 +174,10 @@ PathSkia::StrokeContainsPoint(const StrokeOptions &aStrokeOptions, } SkRegion pointRect; - pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1)), - int32_t(SkFloatToScalar(transformed.y - 1)), - int32_t(SkFloatToScalar(transformed.x + 1)), - int32_t(SkFloatToScalar(transformed.y + 1))); + pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1.f)), + int32_t(SkFloatToScalar(transformed.y - 1.f)), + int32_t(SkFloatToScalar(transformed.x + 1.f)), + int32_t(SkFloatToScalar(transformed.y + 1.f))); SkRegion pathRegion; diff --git a/gfx/2d/Point.h b/gfx/2d/Point.h index 26e13c4acf6e..423ee7f401ea 100644 --- a/gfx/2d/Point.h +++ b/gfx/2d/Point.h @@ -8,6 +8,8 @@ #include "mozilla/Attributes.h" #include "Types.h" +#include "Coord.h" +#include "BaseCoord.h" #include "BasePoint.h" #include "BasePoint3D.h" #include "BasePoint4D.h" @@ -33,15 +35,21 @@ namespace gfx { template struct IntPointTyped : - public BasePoint< int32_t, IntPointTyped >, + public BasePoint< int32_t, IntPointTyped, IntCoordTyped >, public units { static_assert(IsPixel::value, "'units' must be a coordinate system tag"); - typedef BasePoint< int32_t, IntPointTyped > Super; + typedef IntCoordTyped Coord; + typedef BasePoint< int32_t, IntPointTyped, IntCoordTyped > Super; MOZ_CONSTEXPR IntPointTyped() : Super() {} - MOZ_CONSTEXPR IntPointTyped(int32_t aX, int32_t aY) : Super(aX, aY) {} + MOZ_CONSTEXPR IntPointTyped(int32_t aX, int32_t aY) : Super(Coord(aX), Coord(aY)) {} + // The mixed-type constructors (int, Coord) and (Coord, int) are needed to + // avoid ambiguities because Coord is implicitly convertible to int. + MOZ_CONSTEXPR IntPointTyped(int32_t aX, Coord aY) : Super(Coord(aX), aY) {} + MOZ_CONSTEXPR IntPointTyped(Coord aX, int32_t aY) : Super(aX, Coord(aY)) {} + MOZ_CONSTEXPR IntPointTyped(Coord aX, Coord aY) : Super(aX, aY) {} // XXX When all of the code is ported, the following functions to convert to and from // unknown types should be removed. @@ -58,15 +66,21 @@ typedef IntPointTyped IntPoint; template struct PointTyped : - public BasePoint< Float, PointTyped >, + public BasePoint< Float, PointTyped, CoordTyped >, public units { static_assert(IsPixel::value, "'units' must be a coordinate system tag"); - typedef BasePoint< Float, PointTyped > Super; + typedef CoordTyped Coord; + typedef BasePoint< Float, PointTyped, CoordTyped > Super; MOZ_CONSTEXPR PointTyped() : Super() {} - MOZ_CONSTEXPR PointTyped(Float aX, Float aY) : Super(aX, aY) {} + MOZ_CONSTEXPR PointTyped(Float aX, Float aY) : Super(Coord(aX), Coord(aY)) {} + // The mixed-type constructors (Float, Coord) and (Coord, Float) are needed to + // avoid ambiguities because Coord is implicitly convertible to Float. + MOZ_CONSTEXPR PointTyped(Float aX, Coord aY) : Super(Coord(aX), aY) {} + MOZ_CONSTEXPR PointTyped(Coord aX, Float aY) : Super(aX, Coord(aY)) {} + MOZ_CONSTEXPR PointTyped(Coord aX, Coord aY) : Super(aX.value, aY.value) {} MOZ_CONSTEXPR MOZ_IMPLICIT PointTyped(const IntPointTyped& point) : Super(float(point.x), float(point.y)) {} // XXX When all of the code is ported, the following functions to convert to and from @@ -84,8 +98,14 @@ typedef PointTyped Point; template IntPointTyped RoundedToInt(const PointTyped& aPoint) { - return IntPointTyped(int32_t(floorf(aPoint.x + 0.5f)), - int32_t(floorf(aPoint.y + 0.5f))); + return IntPointTyped(aPoint.x.Rounded(), + aPoint.y.Rounded()); +} + +template +IntPointTyped TruncatedToInt(const PointTyped& aPoint) { + return IntPointTyped(aPoint.x.Truncated(), + aPoint.y.Truncated()); } template diff --git a/gfx/2d/SVGTurbulenceRenderer-inl.h b/gfx/2d/SVGTurbulenceRenderer-inl.h index de3b4e3bd9fe..5a5489e336bf 100644 --- a/gfx/2d/SVGTurbulenceRenderer-inl.h +++ b/gfx/2d/SVGTurbulenceRenderer-inl.h @@ -240,15 +240,15 @@ SVGTurbulenceRenderer::Noise2(Point aVec, c uint8_t i = mLatticeSelector[b0.x & sBM]; uint8_t j = mLatticeSelector[b1.x & sBM]; - const f32x4_t* qua = mGradient[(i + b0.y) & sBM]; - const f32x4_t* qub = mGradient[(i + b1.y) & sBM]; - const f32x4_t* qva = mGradient[(j + b0.y) & sBM]; - const f32x4_t* qvb = mGradient[(j + b1.y) & sBM]; + const f32x4_t* qua = mGradient[(i + b0.y.value) & sBM]; + const f32x4_t* qub = mGradient[(i + b1.y.value) & sBM]; + const f32x4_t* qva = mGradient[(j + b0.y.value) & sBM]; + const f32x4_t* qvb = mGradient[(j + b1.y.value) & sBM]; return BiMix(simd::WSumF32(qua[0], qua[1], r.x, r.y), - simd::WSumF32(qva[0], qva[1], r.x - 1, r.y), - simd::WSumF32(qub[0], qub[1], r.x, r.y - 1), - simd::WSumF32(qvb[0], qvb[1], r.x - 1, r.y - 1), + simd::WSumF32(qva[0], qva[1], r.x - 1.f, r.y), + simd::WSumF32(qub[0], qub[1], r.x, r.y - 1.f), + simd::WSumF32(qvb[0], qvb[1], r.x - 1.f, r.y - 1.f), SCurve(r)); } diff --git a/gfx/2d/moz.build b/gfx/2d/moz.build index 712085ae5527..6893089db95e 100644 --- a/gfx/2d/moz.build +++ b/gfx/2d/moz.build @@ -10,6 +10,7 @@ EXPORTS.mozilla += [ EXPORTS.mozilla.gfx += [ '2D.h', + 'BaseCoord.h', 'BaseMargin.h', 'BasePoint.h', 'BasePoint3D.h', @@ -18,6 +19,7 @@ EXPORTS.mozilla.gfx += [ 'BaseSize.h', 'Blur.h', 'BorrowedContext.h', + 'Coord.h', 'DataSurfaceHelpers.h', 'Filters.h', 'Helpers.h', diff --git a/gfx/2d/unittest/TestPoint.cpp b/gfx/2d/unittest/TestPoint.cpp index d16fcb4f2a5e..6aa2b6a35cbd 100644 --- a/gfx/2d/unittest/TestPoint.cpp +++ b/gfx/2d/unittest/TestPoint.cpp @@ -26,8 +26,8 @@ TestPoint::Addition() a += b; - VERIFY(a.x == 7); - VERIFY(a.y == -3); + VERIFY(a.x == 7.f); + VERIFY(a.y == -3.f); } void @@ -41,6 +41,6 @@ TestPoint::Subtraction() a -= b; - VERIFY(a.x == -3); - VERIFY(a.y == 7); + VERIFY(a.x == -3.f); + VERIFY(a.y == 7.f); } diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index 8a5345d24fb4..64b644c846fa 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -507,6 +507,38 @@ struct ParamTraits } }; +template +struct ParamTraits< mozilla::gfx::CoordTyped > +{ + typedef mozilla::gfx::CoordTyped paramType; + + static void Write(Message* msg, const paramType& param) + { + WriteParam(msg, param.value); + } + + static bool Read(const Message* msg, void** iter, paramType* result) + { + return (ReadParam(msg, iter, &result->value)); + } +}; + +template +struct ParamTraits< mozilla::gfx::IntCoordTyped > +{ + typedef mozilla::gfx::IntCoordTyped paramType; + + static void Write(Message* msg, const paramType& param) + { + WriteParam(msg, param.value); + } + + static bool Read(const Message* msg, void** iter, paramType* result) + { + return (ReadParam(msg, iter, &result->value)); + } +}; + template struct ParamTraits< mozilla::gfx::ScaleFactor > { diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index d3901b9c068b..c9b0aa6ffbe9 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -197,7 +197,7 @@ protected: public: NS_INLINE_DECL_REFCOUNTING(Compositor) - Compositor(PCompositorParent* aParent = nullptr) + explicit Compositor(PCompositorParent* aParent = nullptr) : mCompositorID(0) , mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC) , mParent(aParent) diff --git a/gfx/layers/Effects.h b/gfx/layers/Effects.h index e52ecdc41f1b..24272b18be74 100644 --- a/gfx/layers/Effects.h +++ b/gfx/layers/Effects.h @@ -42,7 +42,7 @@ struct Effect { NS_INLINE_DECL_REFCOUNTING(Effect) - Effect(EffectTypes aType) : mType(aType) {} + explicit Effect(EffectTypes aType) : mType(aType) {} EffectTypes mType; @@ -98,7 +98,7 @@ struct EffectMask : public Effect struct EffectBlendMode : public Effect { - EffectBlendMode(gfx::CompositionOp aBlendMode) + explicit EffectBlendMode(gfx::CompositionOp aBlendMode) : Effect(EffectTypes::BLEND_MODE) , mBlendMode(aBlendMode) { } @@ -112,7 +112,7 @@ struct EffectBlendMode : public Effect // Render to a render target rather than the screen. struct EffectRenderTarget : public TexturedEffect { - EffectRenderTarget(CompositingRenderTarget *aRenderTarget) + explicit EffectRenderTarget(CompositingRenderTarget *aRenderTarget) : TexturedEffect(EffectTypes::RENDER_TARGET, aRenderTarget, true, gfx::Filter::LINEAR) , mRenderTarget(aRenderTarget) {} @@ -183,7 +183,7 @@ struct EffectComponentAlpha : public TexturedEffect struct EffectSolidColor : public Effect { - EffectSolidColor(const gfx::Color &aColor) + explicit EffectSolidColor(const gfx::Color &aColor) : Effect(EffectTypes::SOLID_COLOR) , mColor(aColor) {} diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index dec598332083..be0bd2a50763 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -563,6 +563,22 @@ struct ScrollableLayerGuid { { return !(*this == other); } + + bool operator<(const ScrollableLayerGuid& other) const + { + if (mLayersId < other.mLayersId) { + return true; + } + if (mLayersId == other.mLayersId) { + if (mPresShellId < other.mPresShellId) { + return true; + } + if (mPresShellId == other.mPresShellId) { + return mScrollId < other.mScrollId; + } + } + return false; + } }; template diff --git a/gfx/layers/ImageContainer.h b/gfx/layers/ImageContainer.h index 0be6b5b0c2f5..53f97c8ebd95 100644 --- a/gfx/layers/ImageContainer.h +++ b/gfx/layers/ImageContainer.h @@ -57,7 +57,7 @@ public: */ class SurfaceReleaser : public nsRunnable { public: - SurfaceReleaser(RawRef aRef) : mRef(aRef) {} + explicit SurfaceReleaser(RawRef aRef) : mRef(aRef) {} NS_IMETHOD Run() { mRef->Release(); return NS_OK; @@ -350,7 +350,7 @@ public: enum { DISABLE_ASYNC = 0x0, ENABLE_ASYNC = 0x01 }; - ImageContainer(int flag = 0); + explicit ImageContainer(int flag = 0); /** * Create an Image in one of the given formats. @@ -666,7 +666,7 @@ private: class AutoLockImage { public: - AutoLockImage(ImageContainer *aContainer) : mContainer(aContainer) { mImage = mContainer->LockCurrentImage(); } + explicit AutoLockImage(ImageContainer *aContainer) : mContainer(aContainer) { mImage = mContainer->LockCurrentImage(); } AutoLockImage(ImageContainer *aContainer, RefPtr *aSurface) : mContainer(aContainer) { *aSurface = mContainer->LockCurrentAsSourceSurface(&mSize, getter_AddRefs(mImage)); } @@ -821,7 +821,7 @@ public: virtual gfx::IntSize GetSize() { return mSize; } - PlanarYCbCrImage(BufferRecycleBin *aRecycleBin); + explicit PlanarYCbCrImage(BufferRecycleBin *aRecycleBin); virtual SharedPlanarYCbCrImage *AsSharedPlanarYCbCrImage() { return nullptr; } diff --git a/gfx/layers/LayerScope.cpp b/gfx/layers/LayerScope.cpp index 461188e6930d..649dbbdf702e 100644 --- a/gfx/layers/LayerScope.cpp +++ b/gfx/layers/LayerScope.cpp @@ -366,7 +366,7 @@ StaticAutoPtr WebSocketHelper::sWebSocketManager; */ class DebugGLData: public LinkedListElement { public: - DebugGLData(Packet::DataType aDataType) + explicit DebugGLData(Packet::DataType aDataType) : mDataType(aDataType) { } @@ -399,7 +399,7 @@ public: mFrameStamp(aValue) { } - DebugGLFrameStatusData(Packet::DataType aDataType) + explicit DebugGLFrameStatusData(Packet::DataType aDataType) : DebugGLData(aDataType), mFrameStamp(0) { } @@ -547,7 +547,7 @@ protected: class DebugGLLayersData : public DebugGLData { public: - DebugGLLayersData(UniquePtr aPacket) + explicit DebugGLLayersData(UniquePtr aPacket) : DebugGLData(Packet::LAYERS), mPacket(Move(aPacket)) { } diff --git a/gfx/layers/LayerScope.h b/gfx/layers/LayerScope.h index 75af91851525..420370ab714c 100644 --- a/gfx/layers/LayerScope.h +++ b/gfx/layers/LayerScope.h @@ -41,7 +41,7 @@ public: // Perform BeginFrame and EndFrame automatically class LayerScopeAutoFrame { public: - LayerScopeAutoFrame(int64_t aFrameStamp); + explicit LayerScopeAutoFrame(int64_t aFrameStamp); ~LayerScopeAutoFrame(); private: diff --git a/gfx/layers/LayerTreeInvalidation.cpp b/gfx/layers/LayerTreeInvalidation.cpp index d2bba6b3db30..f5b676a1745f 100644 --- a/gfx/layers/LayerTreeInvalidation.cpp +++ b/gfx/layers/LayerTreeInvalidation.cpp @@ -98,7 +98,7 @@ NotifySubdocumentInvalidationRecursive(Layer* aLayer, NotifySubDocInvalidationFu struct LayerPropertiesBase : public LayerProperties { - LayerPropertiesBase(Layer* aLayer) + explicit LayerPropertiesBase(Layer* aLayer) : mLayer(aLayer) , mMaskLayer(nullptr) , mVisibleRegion(aLayer->GetVisibleRegion()) @@ -212,7 +212,7 @@ struct LayerPropertiesBase : public LayerProperties struct ContainerLayerProperties : public LayerPropertiesBase { - ContainerLayerProperties(ContainerLayer* aLayer) + explicit ContainerLayerProperties(ContainerLayer* aLayer) : LayerPropertiesBase(aLayer) , mPreXScale(aLayer->GetPreXScale()) , mPreYScale(aLayer->GetPreYScale()) @@ -322,7 +322,7 @@ struct ContainerLayerProperties : public LayerPropertiesBase struct ColorLayerProperties : public LayerPropertiesBase { - ColorLayerProperties(ColorLayer *aLayer) + explicit ColorLayerProperties(ColorLayer *aLayer) : LayerPropertiesBase(aLayer) , mColor(aLayer->GetColor()) { } @@ -345,7 +345,7 @@ struct ColorLayerProperties : public LayerPropertiesBase struct ImageLayerProperties : public LayerPropertiesBase { - ImageLayerProperties(ImageLayer* aImage) + explicit ImageLayerProperties(ImageLayer* aImage) : LayerPropertiesBase(aImage) , mContainer(aImage->GetContainer()) , mFilter(aImage->GetFilter()) diff --git a/gfx/layers/RotatedBuffer.h b/gfx/layers/RotatedBuffer.h index 0c7c4ba9ade2..c2e098ee6bd2 100644 --- a/gfx/layers/RotatedBuffer.h +++ b/gfx/layers/RotatedBuffer.h @@ -190,7 +190,7 @@ public: ContainsVisibleBounds }; - RotatedContentBuffer(BufferSizePolicy aBufferSizePolicy) + explicit RotatedContentBuffer(BufferSizePolicy aBufferSizePolicy) : mBufferProvider(nullptr) , mBufferProviderOnWhite(nullptr) , mBufferSizePolicy(aBufferSizePolicy) diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 022a125bcbde..469b06571d6f 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -23,6 +23,7 @@ #include "UnitTransforms.h" // for ViewAs #include "gfxPrefs.h" // for gfxPrefs #include "OverscrollHandoffChain.h" // for OverscrollHandoffChain +#include "LayersLogging.h" // for Stringify #define APZCTM_LOG(...) // #define APZCTM_LOG(...) printf_stderr("APZCTM: " __VA_ARGS__) @@ -136,13 +137,15 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, if (aRoot) { mApzcTreeLog << "[start]\n"; + std::map apzcMap; UpdatePanZoomControllerTree(aCompositor, aRoot, // aCompositor is null in gtest scenarios aCompositor ? aCompositor->RootLayerTreeId() : 0, Matrix4x4(), nullptr, nullptr, aIsFirstPaint, aOriginatingLayersId, - paintLogger, &apzcsToDestroy, nsIntRegion()); + paintLogger, &apzcsToDestroy, apzcMap, + nsIntRegion()); mApzcTreeLog << "[end]\n"; } @@ -152,22 +155,52 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, } } +static nsIntRegion +ComputeTouchSensitiveRegion(GeckoContentController* aController, + const FrameMetrics& aMetrics, + const nsIntRegion& aObscured) +{ + // Use the composition bounds as the hit test region. + // Optionally, the GeckoContentController can provide a touch-sensitive + // region that constrains all frames associated with the controller. + // In this case we intersect the composition bounds with that region. + ParentLayerRect visible(aMetrics.mCompositionBounds); + CSSRect touchSensitiveRegion; + if (aController->GetTouchSensitiveRegion(&touchSensitiveRegion)) { + // Note: we assume here that touchSensitiveRegion is in the CSS pixels + // of our parent layer, which makes this coordinate conversion + // correct. + visible = visible.Intersect(touchSensitiveRegion + * aMetrics.mDevPixelsPerCSSPixel + * aMetrics.GetParentResolution()); + } + + // Not sure what rounding option is the most correct here, but if we ever + // figure it out we can change this. For now I'm rounding in to minimize + // the chances of getting a complex region. + ParentLayerIntRect roundedVisible = RoundedIn(visible); + nsIntRegion unobscured; + unobscured.Sub(nsIntRect(roundedVisible.x, roundedVisible.y, + roundedVisible.width, roundedVisible.height), + aObscured); + return unobscured; +} + AsyncPanZoomController* APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, Layer* aLayer, uint64_t aLayersId, - Matrix4x4 aTransform, + const Matrix4x4& aAncestorTransform, AsyncPanZoomController* aParent, AsyncPanZoomController* aNextSibling, bool aIsFirstPaint, uint64_t aOriginatingLayersId, const APZPaintLogHelper& aPaintLogger, nsTArray< nsRefPtr >* aApzcsToDestroy, + std::map& aApzcMap, const nsIntRegion& aObscured) { mTreeLock.AssertCurrentThreadOwns(); - Matrix4x4 transform = aLayer->GetTransform(); - AsyncPanZoomController* apzc = nullptr; mApzcTreeLog << aLayer->Name() << '\t'; @@ -179,136 +212,148 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, // has registered a GeckoContentController for it, so we need to ensure // it has an APZC instance to manage its scrolling. - apzc = aLayer->GetAsyncPanZoomController(); - - // If the content represented by the scrollable layer has changed (which may - // be possible because of DLBI heuristics) then we don't want to keep using - // the same old APZC for the new content. Null it out so we run through the - // code to find another one or create one. + // aApzcMap allows reusing the exact same APZC instance for different layers + // with the same FrameMetrics data. This is needed because in some cases content + // that is supposed to scroll together is split into multiple layers because of + // e.g. non-scrolling content interleaved in z-index order. ScrollableLayerGuid guid(aLayersId, metrics); - if (apzc && !apzc->Matches(guid)) { - apzc = nullptr; + auto insertResult = aApzcMap.insert(std::make_pair(guid, static_cast(nullptr))); + if (!insertResult.second) { + apzc = insertResult.first->second; } + APZCTM_LOG("Found APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, guid.mLayersId, guid.mScrollId); - // If the layer doesn't have an APZC already, try to find one of our - // pre-existing ones that matches. In particular, if we find an APZC whose - // ScrollableLayerGuid is the same, then we know what happened is that the - // layout of the page changed causing the layer tree to be rebuilt, but the - // underlying content for which the APZC was originally created is still - // there. So it makes sense to pick up that APZC instance again and use it here. + // If we haven't encountered a layer already with the same metrics, then we need to + // do the full reuse-or-make-an-APZC algorithm, which is contained inside the block + // below. if (apzc == nullptr) { - for (size_t i = 0; i < aApzcsToDestroy->Length(); i++) { - if (aApzcsToDestroy->ElementAt(i)->Matches(guid)) { - apzc = aApzcsToDestroy->ElementAt(i); - break; + apzc = aLayer->GetAsyncPanZoomController(); + + // If the content represented by the scrollable layer has changed (which may + // be possible because of DLBI heuristics) then we don't want to keep using + // the same old APZC for the new content. Null it out so we run through the + // code to find another one or create one. + if (apzc && !apzc->Matches(guid)) { + apzc = nullptr; + } + + // If the layer doesn't have an APZC already, try to find one of our + // pre-existing ones that matches. In particular, if we find an APZC whose + // ScrollableLayerGuid is the same, then we know what happened is that the + // layout of the page changed causing the layer tree to be rebuilt, but the + // underlying content for which the APZC was originally created is still + // there. So it makes sense to pick up that APZC instance again and use it here. + if (apzc == nullptr) { + for (size_t i = 0; i < aApzcsToDestroy->Length(); i++) { + if (aApzcsToDestroy->ElementAt(i)->Matches(guid)) { + apzc = aApzcsToDestroy->ElementAt(i); + break; + } } } - } - // The APZC we get off the layer may have been destroyed previously if the layer was inactive - // or omitted from the layer tree for whatever reason from a layers update. If it later comes - // back it will have a reference to a destroyed APZC and so we need to throw that out and make - // a new one. - bool newApzc = (apzc == nullptr || apzc->IsDestroyed()); - if (newApzc) { - apzc = new AsyncPanZoomController(aLayersId, this, state->mController, - AsyncPanZoomController::USE_GESTURE_DETECTOR); - apzc->SetCompositorParent(aCompositor); - if (state->mCrossProcessParent != nullptr) { - apzc->ShareFrameMetricsAcrossProcesses(); - } - } else { - // If there was already an APZC for the layer clear the tree pointers - // so that it doesn't continue pointing to APZCs that should no longer - // be in the tree. These pointers will get reset properly as we continue - // building the tree. Also remove it from the set of APZCs that are going - // to be destroyed, because it's going to remain active. - aApzcsToDestroy->RemoveElement(apzc); - apzc->SetPrevSibling(nullptr); - apzc->SetLastChild(nullptr); - } - APZCTM_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, metrics.GetScrollId()); - - apzc->NotifyLayersUpdated(metrics, - aIsFirstPaint && (aLayersId == aOriginatingLayersId)); - apzc->SetScrollHandoffParentId(aLayer->GetScrollHandoffParentId()); - - // Use the composition bounds as the hit test region. - // Optionally, the GeckoContentController can provide a touch-sensitive - // region that constrains all frames associated with the controller. - // In this case we intersect the composition bounds with that region. - ParentLayerRect visible(metrics.mCompositionBounds); - CSSRect touchSensitiveRegion; - if (state->mController->GetTouchSensitiveRegion(&touchSensitiveRegion)) { - // Note: we assume here that touchSensitiveRegion is in the CSS pixels - // of our parent layer, which makes this coordinate conversion - // correct. - visible = visible.Intersect(touchSensitiveRegion - * metrics.mDevPixelsPerCSSPixel - * metrics.GetParentResolution()); - } - - // Not sure what rounding option is the most correct here, but if we ever - // figure it out we can change this. For now I'm rounding in to minimize - // the chances of getting a complex region. - ParentLayerIntRect roundedVisible = RoundedIn(visible); - nsIntRegion unobscured; - unobscured.Sub(nsIntRect(roundedVisible.x, roundedVisible.y, - roundedVisible.width, roundedVisible.height), - aObscured); - - apzc->SetLayerHitTestData(unobscured, aTransform, transform); - APZCTM_LOG("Setting rect(%f %f %f %f) as visible region for APZC %p\n", visible.x, visible.y, - visible.width, visible.height, - apzc); - - mApzcTreeLog << "APZC " << guid - << "\tcb=" << visible - << "\tsr=" << metrics.mScrollableRect - << (aLayer->GetVisibleRegion().IsEmpty() ? "\tscrollinfo" : "") - << (apzc->HasScrollgrab() ? "\tscrollgrab" : "") - << "\t" << aLayer->GetContentDescription(); - - // Bind the APZC instance into the tree of APZCs - if (aNextSibling) { - aNextSibling->SetPrevSibling(apzc); - } else if (aParent) { - aParent->SetLastChild(apzc); - } else { - mRootApzc = apzc; - apzc->MakeRoot(); - } - - // For testing, log the parent scroll id of every APZC that has a - // parent. This allows test code to reconstruct the APZC tree. - // Note that we currently only do this for APZCs in the layer tree - // that originated the update, because the only identifying information - // we are logging about APZCs is the scroll id, and otherwise we could - // confuse APZCs from different layer trees with the same scroll id. - if (aLayersId == aOriginatingLayersId && apzc->GetParent()) { - aPaintLogger.LogTestData(metrics.GetScrollId(), "parentScrollId", - apzc->GetParent()->GetGuid().mScrollId); - } - - // Let this apzc be the parent of other controllers when we recurse downwards - aParent = apzc; - - if (newApzc) { - if (apzc->IsRootForLayersId()) { - // If we just created a new apzc that is the root for its layers ID, then - // we need to update its zoom constraints which might have arrived before this - // was created - ZoomConstraints constraints; - if (state->mController->GetRootZoomConstraints(&constraints)) { - apzc->UpdateZoomConstraints(constraints); + // The APZC we get off the layer may have been destroyed previously if the layer was inactive + // or omitted from the layer tree for whatever reason from a layers update. If it later comes + // back it will have a reference to a destroyed APZC and so we need to throw that out and make + // a new one. + bool newApzc = (apzc == nullptr || apzc->IsDestroyed()); + if (newApzc) { + apzc = new AsyncPanZoomController(aLayersId, this, state->mController, + AsyncPanZoomController::USE_GESTURE_DETECTOR); + apzc->SetCompositorParent(aCompositor); + if (state->mCrossProcessParent != nullptr) { + apzc->ShareFrameMetricsAcrossProcesses(); } } else { - // For an apzc that is not the root for its layers ID, we give it the - // same zoom constraints as its parent. This ensures that if e.g. - // user-scalable=no was specified, none of the APZCs allow double-tap - // to zoom. - apzc->UpdateZoomConstraints(apzc->GetParent()->GetZoomConstraints()); + // If there was already an APZC for the layer clear the tree pointers + // so that it doesn't continue pointing to APZCs that should no longer + // be in the tree. These pointers will get reset properly as we continue + // building the tree. Also remove it from the set of APZCs that are going + // to be destroyed, because it's going to remain active. + aApzcsToDestroy->RemoveElement(apzc); + apzc->SetPrevSibling(nullptr); + apzc->SetLastChild(nullptr); } + APZCTM_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, metrics.GetScrollId()); + + apzc->NotifyLayersUpdated(metrics, + aIsFirstPaint && (aLayersId == aOriginatingLayersId)); + apzc->SetScrollHandoffParentId(aLayer->GetScrollHandoffParentId()); + + nsIntRegion unobscured = ComputeTouchSensitiveRegion(state->mController, metrics, aObscured); + apzc->SetLayerHitTestData(unobscured, aAncestorTransform); + APZCTM_LOG("Setting region %s as visible region for APZC %p\n", + Stringify(unobscured).c_str(), apzc); + + mApzcTreeLog << "APZC " << guid + << "\tcb=" << metrics.mCompositionBounds + << "\tsr=" << metrics.mScrollableRect + << (aLayer->GetVisibleRegion().IsEmpty() ? "\tscrollinfo" : "") + << (apzc->HasScrollgrab() ? "\tscrollgrab" : "") + << "\t" << aLayer->GetContentDescription(); + + // Bind the APZC instance into the tree of APZCs + if (aNextSibling) { + aNextSibling->SetPrevSibling(apzc); + } else if (aParent) { + aParent->SetLastChild(apzc); + } else { + mRootApzc = apzc; + apzc->MakeRoot(); + } + + // For testing, log the parent scroll id of every APZC that has a + // parent. This allows test code to reconstruct the APZC tree. + // Note that we currently only do this for APZCs in the layer tree + // that originated the update, because the only identifying information + // we are logging about APZCs is the scroll id, and otherwise we could + // confuse APZCs from different layer trees with the same scroll id. + if (aLayersId == aOriginatingLayersId && apzc->GetParent()) { + aPaintLogger.LogTestData(metrics.GetScrollId(), "parentScrollId", + apzc->GetParent()->GetGuid().mScrollId); + } + + // Let this apzc be the parent of other controllers when we recurse downwards + aParent = apzc; + + if (newApzc) { + if (apzc->IsRootForLayersId()) { + // If we just created a new apzc that is the root for its layers ID, then + // we need to update its zoom constraints which might have arrived before this + // was created + ZoomConstraints constraints; + if (state->mController->GetRootZoomConstraints(&constraints)) { + apzc->UpdateZoomConstraints(constraints); + } + } else { + // For an apzc that is not the root for its layers ID, we give it the + // same zoom constraints as its parent. This ensures that if e.g. + // user-scalable=no was specified, none of the APZCs allow double-tap + // to zoom. + apzc->UpdateZoomConstraints(apzc->GetParent()->GetZoomConstraints()); + } + } + + insertResult.first->second = apzc; + } else { + // We already built an APZC earlier in this tree walk, but we have another layer + // now that will also be using that APZC. The hit-test region on the APZC needs + // to be updated to deal with the new layer's hit region. + // FIXME: Combining this hit test region to the existing hit test region has a bit + // of a problem, because it assumes the z-index of this new region is the same as + // the z-index of the old region (from the previous layer with the same scrollid) + // when in fact that may not be the case. + // Consider the case where we have three layers: A, B, and C. A is at the top in + // z-order and C is at the bottom. A and C share a scrollid and scroll together; but + // B has a different scrollid and scrolls independently. Depending on how B moves + // and the async transform on it, a larger/smaller area of C may be unobscured. + // However, when we combine the hit regions of A and C here we are ignoring the async + // async transform and so we basically assume the same amount of C is always visible + // on top of B. Fixing this doesn't appear to be very easy so I'm leaving it for + // now in the hopes that we won't run into this problem a lot. + nsIntRegion unobscured = ComputeTouchSensitiveRegion(state->mController, metrics, aObscured); + apzc->AddHitTestRegion(unobscured); + APZCTM_LOG("Adding region %s to visible region of APZC %p\n", Stringify(unobscured).c_str(), apzc); } } } @@ -317,13 +362,17 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, mApzcTreeLog << '\n'; - // Accumulate the CSS transform between layers that have an APZC, but exclude any - // any layers that do have an APZC, and reset the accumulation at those layers. - if (apzc) { - aTransform = Matrix4x4(); - } else { - // Multiply child layer transforms on the left so they get applied first - aTransform = transform * aTransform; + // Accumulate the CSS transform between layers that have an APZC. + // In the terminology of the big comment above APZCTreeManager::GetInputTransforms, if + // we are at layer M, then aAncestorTransform is NC * OC * PC, and we left-multiply MC and + // compute ancestorTransform to be MC * NC * OC * PC. This gets passed down as the ancestor + // transform to layer L when we recurse into the children below. If we are at a layer + // with an APZC, such as P, then we reset the ancestorTransform to just PC, to start + // the new accumulation as we go down. + Matrix4x4 transform = aLayer->GetTransform(); + Matrix4x4 ancestorTransform = transform; + if (!apzc) { + ancestorTransform = ancestorTransform * aAncestorTransform; } uint64_t childLayersId = (aLayer->AsRefLayer() ? aLayer->AsRefLayer()->GetReferentId() : aLayersId); @@ -350,9 +399,9 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, AsyncPanZoomController* next = apzc ? nullptr : aNextSibling; for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) { gfx::TreeAutoIndent indent(mApzcTreeLog); - next = UpdatePanZoomControllerTree(aCompositor, child, childLayersId, aTransform, aParent, next, + next = UpdatePanZoomControllerTree(aCompositor, child, childLayersId, ancestorTransform, aParent, next, aIsFirstPaint, aOriginatingLayersId, - aPaintLogger, aApzcsToDestroy, obscured); + aPaintLogger, aApzcsToDestroy, aApzcMap, obscured); // Each layer obscures its previous siblings, so we augment the obscured // region as we loop backwards through the children. @@ -382,16 +431,14 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, ApplyTransform(gfx::PointTyped* aPoint, const Matrix4x4& aMatrix) { Point result = aMatrix * aPoint->ToUnknownPoint(); - aPoint->x = result.x; - aPoint->y = result.y; + *aPoint = ViewAs(result); } /*static*/ template void ApplyTransform(gfx::IntPointTyped* aPoint, const Matrix4x4& aMatrix) { Point result = aMatrix * aPoint->ToUnknownPoint(); - aPoint->x = result.x; - aPoint->y = result.y; + *aPoint = TruncatedToInt(ViewAs(result)); } /*static*/ void @@ -635,9 +682,7 @@ APZCTreeManager::TransformCoordinateToGecko(const ScreenIntPoint& aPoint, Matrix4x4 transformToGecko; GetInputTransforms(apzc, transformToApzc, transformToGecko); Matrix4x4 outTransform = transformToApzc * transformToGecko; - aOutTransformedPoint->x = aPoint.x; - aOutTransformedPoint->y = aPoint.y; - ApplyTransform(aOutTransformedPoint, outTransform); + *aOutTransformedPoint = TransformTo(outTransform, aPoint); } } @@ -1054,10 +1099,10 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, // comments explain what values are stored in the variables at these two levels. All the comments // use standard matrix notation where the leftmost matrix in a multiplication is applied first. - // ancestorUntransform takes points from aApzc's parent APZC's layer coordinates + // ancestorUntransform takes points from aApzc's parent APZC's CSS-transformed layer coordinates // to aApzc's parent layer's layer coordinates. - // It is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L, - // and RC.Inverse() * QC.Inverse() at recursion level for P. + // It is PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L, + // and RC.Inverse() * QC.Inverse() at recursion level for P. Matrix4x4 ancestorUntransform = aApzc->GetAncestorTransform(); ancestorUntransform.Invert(); @@ -1069,15 +1114,13 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, aHitTestPoint.x, aHitTestPoint.y, hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc); - // childUntransform takes points from aApzc's parent APZC's layer coordinates - // to aApzc's layer coordinates (which are aApzc's children's ParentLayer coordinates). - // It is OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LA.Inverse() at L - // and RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() at P. - Matrix4x4 cssUntransform = aApzc->GetCSSTransform(); - cssUntransform.Invert(); + // childUntransform takes points from aApzc's parent APZC's CSS-transformed layer coordinates + // to aApzc's CSS-transformed layer coordinates. + // It is PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() * LA.Inverse() at L + // and RC.Inverse() * QC.Inverse() * PA.Inverse() at P. Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform(); asyncUntransform.Invert(); - Matrix4x4 childUntransform = ancestorUntransform * cssUntransform * asyncUntransform; + Matrix4x4 childUntransform = ancestorUntransform * asyncUntransform; gfxPointH3D hitTestPointForChildLayers = To3DMatrix(childUntransform).ProjectPoint(aHitTestPoint); APZCTM_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n", aHitTestPoint.x, aHitTestPoint.y, @@ -1125,34 +1168,32 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, When layer L is displayed to the screen by the compositor, the set of transforms that are applied to L are (in order from top to bottom): - L's transient async transform (hereafter referred to as transform matrix LT) - L's nontransient async transform (hereafter referred to as transform matrix LN) L's CSS transform (hereafter referred to as transform matrix LC) - M's transient async transform (hereafter referred to as transform matrix MT) - M's nontransient async transform (hereafter referred to as transform matrix MN) + L's nontransient async transform (hereafter referred to as transform matrix LN) + L's transient async transform (hereafter referred to as transform matrix LT) M's CSS transform (hereafter referred to as transform matrix MC) + M's nontransient async transform (hereafter referred to as transform matrix MN) + M's transient async transform (hereafter referred to as transform matrix MT) ... - R's transient async transform (hereafter referred to as transform matrix RT) - R's nontransient async transform (hereafter referred to as transform matrix RN) R's CSS transform (hereafter referred to as transform matrix RC) + R's nontransient async transform (hereafter referred to as transform matrix RN) + R's transient async transform (hereafter referred to as transform matrix RT) Also, for any layer, the async transform is the combination of its transient and non-transient parts. That is, for any layer L: - LA === LT * LN - LA.Inverse() === LN.Inverse() * LT.Inverse() + LA === LN * LT + LA.Inverse() === LT.Inverse() * LN.Inverse() If we want user input to modify L's transient async transform, we have to first convert user input from screen space to the coordinate space of L's transient async transform. Doing this involves applying the following transforms (in order from top to bottom): - RC.Inverse() - RN.Inverse() RT.Inverse() + RN.Inverse() + RC.Inverse() ... - MC.Inverse() - MN.Inverse() MT.Inverse() - LC.Inverse() - LN.Inverse() + MN.Inverse() + MC.Inverse() This combined transformation is returned in the aTransformToApzcOut out-parameter. Next, if we want user inputs sent to gecko for event-dispatching, we will need to strip @@ -1167,35 +1208,34 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, transform be represented by LD, MD, ... RD. Therefore, given a user input in screen space, the following transforms need to be applied (in order from top to bottom): - RC.Inverse() - RN.Inverse() RT.Inverse() + RN.Inverse() + RC.Inverse() ... - MC.Inverse() - MN.Inverse() MT.Inverse() - LC.Inverse() - LN.Inverse() + MN.Inverse() + MC.Inverse() LT.Inverse() - LD + LN.Inverse() + LC.Inverse() LC - MD + LD MC + MD ... - RD RC + RD This sequence can be simplified and refactored to the following: aTransformToApzcOut - LT.Inverse() + LA.Inverse() LD - LC - MD MC + MD ... - RD RC + RD Since aTransformToApzcOut is already one of the out-parameters, we set aTransformToGeckoOut - to the remaining transforms (LT.Inverse() * LD * ... * RC), so that the caller code can + to the remaining transforms (LA.Inverse() * LD * ... * RD), so that the caller code can combine it with aTransformToApzcOut to get the final transform required in this case. Note that for many of these layers, there will be no AsyncPanZoomController attached, and @@ -1222,25 +1262,17 @@ APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, Matrix4x4& aT // in the variables at these two levels. All the comments use standard matrix notation where the // leftmost matrix in a multiplication is applied first. - // ancestorUntransform is OC.Inverse() * NC.Inverse() * MC.Inverse() + // ancestorUntransform is PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() Matrix4x4 ancestorUntransform = aApzc->GetAncestorTransform(); ancestorUntransform.Invert(); // asyncUntransform is LA.Inverse() Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform(); asyncUntransform.Invert(); - // nontransientAsyncTransform is LN - Matrix4x4 nontransientAsyncTransform = aApzc->GetNontransientAsyncTransform(); - // transientAsyncUntransform is LT.Inverse() - Matrix4x4 transientAsyncUntransform = nontransientAsyncTransform * asyncUntransform; - // aTransformToApzcOut is initialized to OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse() - Matrix4x4 cssUntransform = aApzc->GetCSSTransform(); - cssUntransform.Invert(); - Matrix4x4 nontransientAsyncUntransform = nontransientAsyncTransform; - nontransientAsyncUntransform.Invert(); - aTransformToApzcOut = ancestorUntransform * cssUntransform * nontransientAsyncUntransform; - // aTransformToGeckoOut is initialized to LT.Inverse() * LD * LC * MC * NC * OC - aTransformToGeckoOut = transientAsyncUntransform * aApzc->GetTransformToLastDispatchedPaint() * aApzc->GetCSSTransform() * aApzc->GetAncestorTransform(); + // aTransformToApzcOut is initialized to PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() + aTransformToApzcOut = ancestorUntransform; + // aTransformToGeckoOut is initialized to LA.Inverse() * LD * MC * NC * OC * PC + aTransformToGeckoOut = asyncUntransform * aApzc->GetTransformToLastDispatchedPaint() * aApzc->GetAncestorTransform(); for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) { // ancestorUntransform is updated to RC.Inverse() * QC.Inverse() when parent == P @@ -1249,15 +1281,13 @@ APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, Matrix4x4& aT // asyncUntransform is updated to PA.Inverse() when parent == P asyncUntransform = parent->GetCurrentAsyncTransform(); asyncUntransform.Invert(); - // untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() - cssUntransform = parent->GetCSSTransform(); - cssUntransform.Invert(); - Matrix4x4 untransformSinceLastApzc = ancestorUntransform * cssUntransform * asyncUntransform; + // untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PA.Inverse() + Matrix4x4 untransformSinceLastApzc = ancestorUntransform * asyncUntransform; - // aTransformToApzcOut is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse() + // aTransformToApzcOut is RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() aTransformToApzcOut = untransformSinceLastApzc * aTransformToApzcOut; - // aTransformToGeckoOut is LT.Inverse() * LD * LC * MC * NC * OC * PD * PC * QC * RC - aTransformToGeckoOut = aTransformToGeckoOut * parent->GetTransformToLastDispatchedPaint() * parent->GetCSSTransform() * parent->GetAncestorTransform(); + // aTransformToGeckoOut is LA.Inverse() * LD * MC * NC * OC * PC * PD * QC * RC + aTransformToGeckoOut = aTransformToGeckoOut * parent->GetTransformToLastDispatchedPaint() * parent->GetAncestorTransform(); // The above values for aTransformToApzcOut and aTransformToGeckoOut when parent == P match // the required output as explained in the comment above this method. Note that any missing diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h index d2afd24dfb47..c29b309d92a0 100644 --- a/gfx/layers/apz/src/APZCTreeManager.h +++ b/gfx/layers/apz/src/APZCTreeManager.h @@ -7,6 +7,7 @@ #define mozilla_layers_APZCTreeManager_h #include // for uint64_t, uint32_t +#include // for std::map #include "FrameMetrics.h" // for FrameMetrics, etc #include "Units.h" // for CSSPoint, CSSRect, etc #include "gfxPoint.h" // for gfxPoint @@ -277,8 +278,6 @@ public: * handoff chain that should be scrolled. * * Returns true iff. some APZC accepted the scroll and scrolled. - * This is to allow the sending APZC to go into an overscrolled state if - * no APZC further up in the handoff chain accepted the overscroll. * * The way this method works is best illustrated with an example. * Consider three nested APZCs, A, B, and C, with C being the innermost one. @@ -371,13 +370,14 @@ private: */ AsyncPanZoomController* UpdatePanZoomControllerTree(CompositorParent* aCompositor, Layer* aLayer, uint64_t aLayersId, - gfx::Matrix4x4 aTransform, + const gfx::Matrix4x4& aAncestorTransform, AsyncPanZoomController* aParent, AsyncPanZoomController* aNextSibling, bool aIsFirstPaint, uint64_t aOriginatingLayersId, const APZPaintLogHelper& aPaintLogger, nsTArray< nsRefPtr >* aApzcsToDestroy, + std::map& aApzcMap, const nsIntRegion& aObscured); private: diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index 829b78d48009..1af97417d311 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -379,8 +379,8 @@ static bool IsCloseToVertical(float aAngle, float aThreshold) template static bool IsZero(const gfx::PointTyped& aPoint) { - return FuzzyEqualsMultiplicative(aPoint.x, 0.0f) - && FuzzyEqualsMultiplicative(aPoint.y, 0.0f); + return FuzzyEqualsMultiplicative(aPoint.x.value, 0.0f) + && FuzzyEqualsMultiplicative(aPoint.y.value, 0.0f); } static inline void LogRendertraceRect(const ScrollableLayerGuid& aGuid, const char* aDesc, const char* aColor, const CSSRect& aRect) @@ -538,9 +538,9 @@ public: // We may have reached the end of the scroll range along one axis but // not the other. In such a case we only want to hand off the relevant // component of the fling. - if (FuzzyEqualsAdditive(overscroll.x, 0.0f, COORDINATE_EPSILON)) { + if (FuzzyEqualsAdditive(overscroll.x.value, 0.0f, COORDINATE_EPSILON)) { velocity.x = 0; - } else if (FuzzyEqualsAdditive(overscroll.y, 0.0f, COORDINATE_EPSILON)) { + } else if (FuzzyEqualsAdditive(overscroll.y.value, 0.0f, COORDINATE_EPSILON)) { velocity.y = 0; } @@ -610,7 +610,7 @@ public: // Sample the zoom at the current time point. The sampled zoom // will affect the final computed resolution. - double sampledPosition = gComputedTimingFunction->GetValue(animPosition); + float sampledPosition = gComputedTimingFunction->GetValue(animPosition); // We scale the scrollOffset linearly with sampledPosition, so the zoom // needs to scale inversely to match. @@ -646,7 +646,7 @@ private: class OverscrollSnapBackAnimation: public AsyncPanZoomAnimation { public: - OverscrollSnapBackAnimation(AsyncPanZoomController& aApzc) + explicit OverscrollSnapBackAnimation(AsyncPanZoomController& aApzc) : mApzc(aApzc) { // Make sure the initial velocity is zero. This is normally the case @@ -1337,8 +1337,8 @@ AsyncPanZoomController::ConvertToGecko(const ScreenPoint& aPoint, CSSPoint* aOut nsEventStatus AsyncPanZoomController::OnPanMayBegin(const PanGestureInput& aEvent) { APZC_LOG("%p got a pan-maybegin in state %d\n", this, mState); - mX.StartTouch(aEvent.mPanStartPoint.x, aEvent.mTime); - mY.StartTouch(aEvent.mPanStartPoint.y, aEvent.mTime); + mX.StartTouch(aEvent.mPanStartPoint.x.Truncated(), aEvent.mTime); + mY.StartTouch(aEvent.mPanStartPoint.y.Truncated(), aEvent.mTime); if (mPanGestureState) { mPanGestureState->GetOverscrollHandoffChain()->CancelAnimations(); } else { @@ -1363,8 +1363,8 @@ nsEventStatus AsyncPanZoomController::OnPanBegin(const PanGestureInput& aEvent) mPanGestureState = MakeUnique(BuildOverscrollHandoffChain()); - mX.StartTouch(aEvent.mPanStartPoint.x, aEvent.mTime); - mY.StartTouch(aEvent.mPanStartPoint.y, aEvent.mTime); + mX.StartTouch(aEvent.mPanStartPoint.x.Truncated(), aEvent.mTime); + mY.StartTouch(aEvent.mPanStartPoint.y.Truncated(), aEvent.mTime); if (GetAxisLockMode() == FREE) { SetState(PANNING); @@ -1387,8 +1387,8 @@ nsEventStatus AsyncPanZoomController::OnPan(const PanGestureInput& aEvent, bool // size and position. We need to do so even if this is a momentum pan (i.e. // aFingersOnTouchpad == false); in that case the "with touch" part is not // really appropriate, so we may want to rethink this at some point. - mX.UpdateWithTouchAtDevicePoint(aEvent.mPanStartPoint.x, aEvent.mTime); - mY.UpdateWithTouchAtDevicePoint(aEvent.mPanStartPoint.y, aEvent.mTime); + mX.UpdateWithTouchAtDevicePoint(aEvent.mPanStartPoint.x.Truncated(), aEvent.mTime); + mY.UpdateWithTouchAtDevicePoint(aEvent.mPanStartPoint.y.Truncated(), aEvent.mTime); HandlePanningUpdate(aEvent.mPanDisplacement.x, aEvent.mPanDisplacement.y); @@ -1718,21 +1718,12 @@ bool AsyncPanZoomController::AttemptScroll(const ScreenPoint& aStartPoint, return true; } - // If there is overscroll, first try to hand it off to an APZC later - // in the handoff chain to consume (either as a normal scroll or as - // overscroll). + // If there is overscroll, try to hand it off to an APZC later + // in the handoff chain to consume. // Note: "+ overscroll" rather than "- overscroll" because "overscroll" // is what's left of "displacement", and "displacement" is "start - end". - if (CallDispatchScroll(aEndPoint + overscroll, aEndPoint, - aOverscrollHandoffChain, aOverscrollHandoffChainIndex + 1)) { - return true; - } - - // If there is no APZC later in the handoff chain that accepted the - // overscroll, try to accept it ourselves. We only accept it if we - // are pannable. - APZC_LOG("%p taking overscroll during panning\n", this); - return OverscrollBy(cssOverscroll); + return CallDispatchScroll(aEndPoint + overscroll, aEndPoint, + aOverscrollHandoffChain, aOverscrollHandoffChainIndex + 1); } bool AsyncPanZoomController::OverscrollBy(const CSSPoint& aOverscroll) { @@ -2122,8 +2113,18 @@ AsyncPanZoomController::FireAsyncScrollOnTimeout() bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime, Vector* aOutDeferredTasks) { + // This function may get called multiple with the same sample time, because + // there may be multiple layers with this APZC, and each layer invokes this + // function during composition. However we only want to do one animation step + // per composition so we need to deduplicate these calls first. + if (mLastSampleTime == aSampleTime) { + return false; + } + TimeDuration sampleTimeDelta = aSampleTime - mLastSampleTime; + mLastSampleTime = aSampleTime; + if (mAnimation) { - bool continueAnimation = mAnimation->Sample(mFrameMetrics, aSampleTime - mLastSampleTime); + bool continueAnimation = mAnimation->Sample(mFrameMetrics, sampleTimeDelta); *aOutDeferredTasks = mAnimation->TakeDeferredTasks(); if (continueAnimation) { if (mPaintThrottler.TimeSinceLastRequest(aSampleTime) > @@ -2137,7 +2138,6 @@ bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime, RequestContentRepaint(); } UpdateSharedCompositorFrameMetrics(); - mLastSampleTime = aSampleTime; return true; } return false; @@ -2224,20 +2224,13 @@ void AsyncPanZoomController::GetOverscrollTransform(ViewTransform* aTransform) c float scale = 1 - (kZEffect * spaceProp); - // In a ViewTransform, the translation is applied before the scale. We want - // to apply our translation after our scale, so we compensate for that here. - translation.x /= scale; - translation.y /= scale; - // Finally, apply the transformations. aTransform->mScale.scale *= scale; - aTransform->mTranslation += translation * mFrameMetrics.LayersPixelsPerCSSPixel(); + aTransform->mTranslation += translation * mFrameMetrics.GetZoom(); } -bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSampleTime, - ViewTransform* aOutTransform, - ScreenPoint& aScrollOffset, - ViewTransform* aOutOverscrollTransform) { +bool AsyncPanZoomController::AdvanceAnimations(const TimeStamp& aSampleTime) +{ // The eventual return value of this function. The compositor needs to know // whether or not to advance by a frame as soon as it can. For example, if a // fling is happening, it has to keep compositing so that the animation is @@ -2251,25 +2244,6 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa requestAnimationFrame = UpdateAnimation(aSampleTime, &deferredTasks); - aScrollOffset = mFrameMetrics.GetScrollOffset() * mFrameMetrics.GetZoom(); - *aOutTransform = GetCurrentAsyncTransform(); - - // If we are overscrolled, we would like the compositor to apply an - // additional transform that produces an overscroll effect. - if (aOutOverscrollTransform && IsOverscrolled()) { - GetOverscrollTransform(aOutOverscrollTransform); - - // Since the caller will apply aOverscrollTransform after aNewTransform, - // aOverscrollTransform's translation will be not be scaled by - // aNewTransform's scale. Since the resulting transform is then - // multiplied by the CSS transform, which cancels out the non-transient - // part of aNewTransform->mScale, this results in an overscroll - // translation whose magnitude varies with the zoom. To avoid this, - // we adjust for that here. - aOutOverscrollTransform->mTranslation.x *= aOutTransform->mScale.scale; - aOutOverscrollTransform->mTranslation.y *= aOutTransform->mScale.scale; - } - LogRendertraceRect(GetGuid(), "viewport", "red", CSSRect(mFrameMetrics.GetScrollOffset(), mFrameMetrics.CalculateCompositedSizeInCssPixels())); @@ -2304,8 +2278,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa mLastAsyncScrollTime = aSampleTime; mLastAsyncScrollOffset = mCurrentAsyncScrollOffset; SendAsyncScrollEvent(); - } - else { + } else { mAsyncScrollTimeoutTask = NewRunnableMethod(this, &AsyncPanZoomController::FireAsyncScrollOnTimeout); MessageLoop::current()->PostDelayedTask(FROM_HERE, @@ -2316,6 +2289,22 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa return requestAnimationFrame; } +void AsyncPanZoomController::SampleContentTransformForFrame(ViewTransform* aOutTransform, + ScreenPoint& aScrollOffset, + ViewTransform* aOutOverscrollTransform) +{ + ReentrantMonitorAutoEnter lock(mMonitor); + + aScrollOffset = mFrameMetrics.GetScrollOffset() * mFrameMetrics.GetZoom(); + *aOutTransform = GetCurrentAsyncTransform(); + + // If we are overscrolled, we would like the compositor to apply an + // additional transform that produces an overscroll effect. + if (aOutOverscrollTransform && IsOverscrolled()) { + GetOverscrollTransform(aOutOverscrollTransform); + } +} + ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() { ReentrantMonitorAutoEnter lock(mMonitor); @@ -2345,13 +2334,13 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() { } } - LayerPoint translation = (currentScrollOffset - lastPaintScrollOffset) - * mLastContentPaintMetrics.LayersPixelsPerCSSPixel(); + ParentLayerToScreenScale scale = mFrameMetrics.GetZoom() + / mLastContentPaintMetrics.mDevPixelsPerCSSPixel + / mFrameMetrics.GetParentResolution(); + ScreenPoint translation = (currentScrollOffset - lastPaintScrollOffset) + * mFrameMetrics.GetZoom(); - return ViewTransform(-translation, - mFrameMetrics.GetZoom() - / mLastContentPaintMetrics.mDevPixelsPerCSSPixel - / mFrameMetrics.GetParentResolution()); + return ViewTransform(scale, -translation); } Matrix4x4 AsyncPanZoomController::GetNontransientAsyncTransform() { @@ -2915,16 +2904,16 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() { ParentLayerPoint AsyncPanZoomController::ToParentLayerCoords(const ScreenPoint& aPoint) { - return TransformTo(To3DMatrix(GetNontransientAsyncTransform() * GetCSSTransform()), aPoint); + // The parent layer pixel space and the screen space for a given layer are the + // same as of bug 1052063. FIXME: Unify these two coordinate systems. + return ParentLayerPoint(aPoint.x, aPoint.y); } void AsyncPanZoomController::UpdateTransformScale() { - Matrix4x4 nontransientTransforms = GetNontransientAsyncTransform() * GetCSSTransform(); - if (!FuzzyEqualsMultiplicative(nontransientTransforms._11, nontransientTransforms._22)) { - NS_WARNING("The x- and y-scales of the nontransient transforms should be equal"); - } - mFrameMetrics.mTransformScale.scale = nontransientTransforms._11; + // The parent layer pixel space and the screen space for a given layer are the + // same as of bug 1052063. FIXME: Unify these two coordinate systems. + mFrameMetrics.mTransformScale.scale = 1; } } diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index abd9b65cf89b..3bc6eb857482 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -149,14 +149,21 @@ public: // These methods must only be called on the compositor thread. // + /** + * Advances any animations currently running to the given timestamp. + * This may be called multiple times with the same timestamp. + * + * The return value indicates whether or not any currently running animation + * should continue. If true, the compositor should schedule another composite. + */ + bool AdvanceAnimations(const TimeStamp& aSampleTime); + bool UpdateAnimation(const TimeStamp& aSampleTime, Vector* aOutDeferredTasks); /** - * RQuery the transforms that should be applied to the layer corresponding + * Query the transforms that should be applied to the layer corresponding * to this APZC due to asynchronous panning and zooming. - * |aSampleTime| is the time that this is sampled at; this is used for - * interpolating animations. * This function returns two transforms via out parameters: * |aOutTransform| is the transform due to regular panning and zooming * |aOverscrollTransform| is the transform due to overscrolling @@ -165,14 +172,10 @@ public: * overscroll transform parameter may be nullptr). Clients who do not want * to ignore the overscroll transform should multiply the two transforms * together. - * - * The return value indicates whether or not any currently running animation - * should continue. If true, the compositor should schedule another composite. */ - bool SampleContentTransformForFrame(const TimeStamp& aSampleTime, - ViewTransform* aOutTransform, + void SampleContentTransformForFrame(ViewTransform* aOutTransform, ScreenPoint& aScrollOffset, - ViewTransform* aOutOverscrollTransform = nullptr); + ViewTransform* aOutOverscrollTransform); /** * A shadow layer update has arrived. |aLayerMetrics| is the new FrameMetrics @@ -911,9 +914,7 @@ public: * to; this function increments the chain and the index and passes it on to * APZCTreeManager::DispatchScroll() in the event of overscroll. * Returns true iff. this APZC, or an APZC further down the - * handoff chain, accepted the scroll (possibly entering an overscrolled - * state). If this return false, the caller APZC knows that it should enter - * an overscrolled state itself if it can. + * handoff chain, accepted the scroll. */ bool AttemptScroll(const ScreenPoint& aStartPoint, const ScreenPoint& aEndPoint, const OverscrollHandoffChain& aOverscrollHandoffChain, @@ -975,22 +976,19 @@ private: * hit-testing to see which APZC instance should handle touch events. */ public: - void SetLayerHitTestData(const nsIntRegion& aRegion, const Matrix4x4& aTransformToLayer, - const Matrix4x4& aTransformForLayer) { + void SetLayerHitTestData(const nsIntRegion& aRegion, const Matrix4x4& aTransformToLayer) { mVisibleRegion = aRegion; mAncestorTransform = aTransformToLayer; - mCSSTransform = aTransformForLayer; - UpdateTransformScale(); + } + + void AddHitTestRegion(const nsIntRegion& aRegion) { + mVisibleRegion.OrWith(aRegion); } Matrix4x4 GetAncestorTransform() const { return mAncestorTransform; } - Matrix4x4 GetCSSTransform() const { - return mCSSTransform; - } - bool VisibleRegionContains(const ParentLayerPoint& aPoint) const { ParentLayerIntPoint point = RoundedToInt(aPoint); return mVisibleRegion.Contains(point.x, point.y); @@ -1001,15 +999,14 @@ public: } private: - /* This is the visible region of the layer that this APZC corresponds to, in - * that layer's screen pixels (the same coordinate system in which this APZC - * receives events in ReceiveInputEvent()). */ + /* This is the union of the visible regions of the layers that this APZC + * corresponds to, in the screen pixels of those layers. (This is the same + * coordinate system in which this APZC receives events in + * ReceiveInputEvent()). */ nsIntRegion mVisibleRegion; - /* This is the cumulative CSS transform for all the layers between the parent - * APZC and this one (not inclusive) */ + /* This is the cumulative CSS transform for all the layers from (and including) + * the parent APZC down to (but excluding) this one. */ Matrix4x4 mAncestorTransform; - /* This is the CSS transform for this APZC's layer. */ - Matrix4x4 mCSSTransform; /* =================================================================== @@ -1077,8 +1074,8 @@ class AsyncPanZoomAnimation { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomAnimation) public: - AsyncPanZoomAnimation(const TimeDuration& aRepaintInterval = - TimeDuration::Forever()) + explicit AsyncPanZoomAnimation(const TimeDuration& aRepaintInterval = + TimeDuration::Forever()) : mRepaintInterval(aRepaintInterval) { } diff --git a/gfx/layers/apz/src/Axis.cpp b/gfx/layers/apz/src/Axis.cpp index 2173df7a6a15..ed1419fe82ff 100644 --- a/gfx/layers/apz/src/Axis.cpp +++ b/gfx/layers/apz/src/Axis.cpp @@ -33,7 +33,7 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController) { } -void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, uint32_t aTimestampMs) { +void Axis::UpdateWithTouchAtDevicePoint(ScreenIntCoord aPos, uint32_t aTimestampMs) { // mVelocityQueue is controller-thread only AsyncPanZoomController::AssertOnControllerThread(); @@ -62,16 +62,16 @@ void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, uint32_t aTimestampMs) { } } -void Axis::StartTouch(int32_t aPos, uint32_t aTimestampMs) { +void Axis::StartTouch(ScreenIntCoord aPos, uint32_t aTimestampMs) { mStartPos = aPos; mPos = aPos; mPosTimeMs = aTimestampMs; mAxisLocked = false; } -bool Axis::AdjustDisplacement(float aDisplacement, - float& aDisplacementOut, - float& aOverscrollAmountOut) +bool Axis::AdjustDisplacement(CSSCoord aDisplacement, + CSSCoord& aDisplacementOut, + CSSCoord& aOverscrollAmountOut) { if (mAxisLocked) { aOverscrollAmountOut = 0; @@ -79,14 +79,14 @@ bool Axis::AdjustDisplacement(float aDisplacement, return false; } - float displacement = aDisplacement; + CSSCoord displacement = aDisplacement; // First consume any overscroll in the opposite direction along this axis. - float consumedOverscroll = 0; + CSSCoord consumedOverscroll = 0; if (mOverscroll > 0 && aDisplacement < 0) { consumedOverscroll = std::min(mOverscroll, -aDisplacement); } else if (mOverscroll < 0 && aDisplacement > 0) { - consumedOverscroll = 0 - std::min(-mOverscroll, aDisplacement); + consumedOverscroll = 0.f - std::min(-mOverscroll, aDisplacement); } mOverscroll -= consumedOverscroll; displacement += consumedOverscroll; @@ -104,7 +104,7 @@ bool Axis::AdjustDisplacement(float aDisplacement, return fabsf(consumedOverscroll) > EPSILON; } -float Axis::ApplyResistance(float aRequestedOverscroll) const { +CSSCoord Axis::ApplyResistance(CSSCoord aRequestedOverscroll) const { // 'resistanceFactor' is a value between 0 and 1, which: // - tends to 1 as the existing overscroll tends to 0 // - tends to 0 as the existing overscroll tends to the composition length @@ -112,23 +112,23 @@ float Axis::ApplyResistance(float aRequestedOverscroll) const { // factor; this should prevent overscrolling by more than the composition // length. float resistanceFactor = 1 - fabsf(mOverscroll) / GetCompositionLength(); - return resistanceFactor < 0 ? 0 : aRequestedOverscroll * resistanceFactor; + return resistanceFactor < 0 ? CSSCoord(0) : aRequestedOverscroll * resistanceFactor; } -void Axis::OverscrollBy(float aOverscroll) { +void Axis::OverscrollBy(CSSCoord aOverscroll) { MOZ_ASSERT(CanScroll()); aOverscroll = ApplyResistance(aOverscroll); if (aOverscroll > 0) { - MOZ_ASSERT(FuzzyEqualsAdditive(GetCompositionEnd(), GetPageEnd(), COORDINATE_EPSILON)); + MOZ_ASSERT(FuzzyEqualsAdditive(GetCompositionEnd().value, GetPageEnd().value, COORDINATE_EPSILON)); MOZ_ASSERT(mOverscroll >= 0); } else if (aOverscroll < 0) { - MOZ_ASSERT(FuzzyEqualsAdditive(GetOrigin(), GetPageStart(), COORDINATE_EPSILON)); + MOZ_ASSERT(FuzzyEqualsAdditive(GetOrigin().value, GetPageStart().value, COORDINATE_EPSILON)); MOZ_ASSERT(mOverscroll <= 0); } mOverscroll += aOverscroll; } -float Axis::GetOverscroll() const { +CSSCoord Axis::GetOverscroll() const { return mOverscroll; } @@ -162,7 +162,7 @@ bool Axis::SampleSnapBack(const TimeDuration& aDelta) { } mOverscroll = std::max(mOverscroll + cssDisplacement, 0.0f); // Overscroll relieved, do not continue animation. - if (mOverscroll == 0) { + if (mOverscroll == 0.f) { mVelocity = 0; return false; } @@ -174,7 +174,7 @@ bool Axis::SampleSnapBack(const TimeDuration& aDelta) { } mOverscroll = std::min(mOverscroll + cssDisplacement, 0.0f); // Overscroll relieved, do not continue animation. - if (mOverscroll == 0) { + if (mOverscroll == 0.f) { mVelocity = 0; return false; } @@ -185,7 +185,7 @@ bool Axis::SampleSnapBack(const TimeDuration& aDelta) { } bool Axis::IsOverscrolled() const { - return mOverscroll != 0; + return mOverscroll != 0.f; } void Axis::ClearOverscroll() { @@ -193,11 +193,11 @@ void Axis::ClearOverscroll() { } float Axis::PanDistance() { - return fabsf(mPos - mStartPos); + return fabsf((mPos - mStartPos).value); } -float Axis::PanDistance(float aPos) { - return fabsf(aPos - mStartPos); +float Axis::PanDistance(ScreenIntCoord aPos) { + return fabsf((aPos - mStartPos).value); } void Axis::EndTouch(uint32_t aTimestampMs) { @@ -252,7 +252,7 @@ bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta, return true; } -Axis::Overscroll Axis::DisplacementWillOverscroll(float aDisplacement) { +Axis::Overscroll Axis::DisplacementWillOverscroll(CSSCoord aDisplacement) { // If the current pan plus a displacement takes the window to the left of or // above the current page rect. bool minus = GetOrigin() + aDisplacement < GetPageStart(); @@ -271,7 +271,7 @@ Axis::Overscroll Axis::DisplacementWillOverscroll(float aDisplacement) { return OVERSCROLL_NONE; } -float Axis::DisplacementWillOverscrollAmount(float aDisplacement) { +CSSCoord Axis::DisplacementWillOverscrollAmount(CSSCoord aDisplacement) { switch (DisplacementWillOverscroll(aDisplacement)) { case OVERSCROLL_MINUS: return (GetOrigin() + aDisplacement) - GetPageStart(); case OVERSCROLL_PLUS: return (GetCompositionEnd() + aDisplacement) - GetPageEnd(); @@ -281,8 +281,8 @@ float Axis::DisplacementWillOverscrollAmount(float aDisplacement) { } } -float Axis::ScaleWillOverscrollAmount(float aScale, float aFocus) { - float originAfterScale = (GetOrigin() + aFocus) - (aFocus / aScale); +CSSCoord Axis::ScaleWillOverscrollAmount(float aScale, CSSCoord aFocus) { + CSSCoord originAfterScale = (GetOrigin() + aFocus) - (aFocus / aScale); bool both = ScaleWillOverscrollBothSides(aScale); bool minus = GetPageStart() - originAfterScale > COORDINATE_EPSILON; @@ -310,29 +310,29 @@ void Axis::SetVelocity(float aVelocity) { mVelocity = aVelocity; } -float Axis::GetCompositionEnd() const { +CSSCoord Axis::GetCompositionEnd() const { return GetOrigin() + GetCompositionLength(); } -float Axis::GetPageEnd() const { +CSSCoord Axis::GetPageEnd() const { return GetPageStart() + GetPageLength(); } -float Axis::GetOrigin() const { +CSSCoord Axis::GetOrigin() const { CSSPoint origin = GetFrameMetrics().GetScrollOffset(); return GetPointOffset(origin); } -float Axis::GetCompositionLength() const { +CSSCoord Axis::GetCompositionLength() const { return GetRectLength(GetFrameMetrics().CalculateCompositedRectInCssPixels()); } -float Axis::GetPageStart() const { +CSSCoord Axis::GetPageStart() const { CSSRect pageRect = GetFrameMetrics().GetExpandedScrollableRect(); return GetRectOffset(pageRect); } -float Axis::GetPageLength() const { +CSSCoord Axis::GetPageLength() const { CSSRect pageRect = GetFrameMetrics().GetExpandedScrollableRect(); return GetRectLength(pageRect); } @@ -357,17 +357,17 @@ AxisX::AxisX(AsyncPanZoomController* aAsyncPanZoomController) } -float AxisX::GetPointOffset(const CSSPoint& aPoint) const +CSSCoord AxisX::GetPointOffset(const CSSPoint& aPoint) const { return aPoint.x; } -float AxisX::GetRectLength(const CSSRect& aRect) const +CSSCoord AxisX::GetRectLength(const CSSRect& aRect) const { return aRect.width; } -float AxisX::GetRectOffset(const CSSRect& aRect) const +CSSCoord AxisX::GetRectOffset(const CSSRect& aRect) const { return aRect.x; } @@ -378,17 +378,17 @@ AxisY::AxisY(AsyncPanZoomController* aAsyncPanZoomController) } -float AxisY::GetPointOffset(const CSSPoint& aPoint) const +CSSCoord AxisY::GetPointOffset(const CSSPoint& aPoint) const { return aPoint.y; } -float AxisY::GetRectLength(const CSSRect& aRect) const +CSSCoord AxisY::GetRectLength(const CSSRect& aRect) const { return aRect.height; } -float AxisY::GetRectOffset(const CSSRect& aRect) const +CSSCoord AxisY::GetRectOffset(const CSSRect& aRect) const { return aRect.y; } diff --git a/gfx/layers/apz/src/Axis.h b/gfx/layers/apz/src/Axis.h index 759e230c5641..d365f754b3a2 100644 --- a/gfx/layers/apz/src/Axis.h +++ b/gfx/layers/apz/src/Axis.h @@ -35,7 +35,7 @@ class AsyncPanZoomController; */ class Axis { public: - Axis(AsyncPanZoomController* aAsyncPanZoomController); + explicit Axis(AsyncPanZoomController* aAsyncPanZoomController); enum Overscroll { // Overscroll is not happening at all. @@ -55,13 +55,13 @@ public: * Notify this Axis that a new touch has been received, including a timestamp * for when the touch was received. This triggers a recalculation of velocity. */ - void UpdateWithTouchAtDevicePoint(int32_t aPos, uint32_t aTimestampMs); + void UpdateWithTouchAtDevicePoint(ScreenIntCoord aPos, uint32_t aTimestampMs); /** * Notify this Axis that a touch has begun, i.e. the user has put their finger * on the screen but has not yet tried to pan. */ - void StartTouch(int32_t aPos, uint32_t aTimestampMs); + void StartTouch(ScreenIntCoord aPos, uint32_t aTimestampMs); /** * Notify this Axis that a touch has ended gracefully. This may perform @@ -87,20 +87,20 @@ public: * displacement, and the function returns true iff internal overscroll amounts * were changed. */ - bool AdjustDisplacement(float aDisplacement, - float& aDisplacementOut, - float& aOverscrollAmountOut); + bool AdjustDisplacement(CSSCoord aDisplacement, + CSSCoord& aDisplacementOut, + CSSCoord& aOverscrollAmountOut); /** * Overscrolls this axis by the requested amount in the requested direction. * The axis must be at the end of its scroll range in this direction. */ - void OverscrollBy(float aOverscroll); + void OverscrollBy(CSSCoord aOverscroll); /** * Return the amount of overscroll on this axis, in CSS pixels. */ - float GetOverscroll() const; + CSSCoord GetOverscroll() const; /** * Sample the snap-back animation to relieve overscroll. @@ -129,7 +129,7 @@ public: * Gets the distance between the starting position of the touch supplied in * startTouch() and the supplied position. */ - float PanDistance(float aPos); + float PanDistance(ScreenIntCoord aPos); /** * Applies friction during a fling, or cancels the fling if the velocity is @@ -177,13 +177,13 @@ public: * That is to say, if the given displacement is applied, this will tell you * whether or not it will overscroll, and in what direction. */ - Overscroll DisplacementWillOverscroll(float aDisplacement); + Overscroll DisplacementWillOverscroll(CSSCoord aDisplacement); /** * If a displacement will overscroll the axis, this returns the amount and in * what direction. Similar to GetExcess() but takes a displacement to apply. */ - float DisplacementWillOverscrollAmount(float aDisplacement); + CSSCoord DisplacementWillOverscrollAmount(CSSCoord aDisplacement); /** * If a scale will overscroll the axis, this returns the amount and in what @@ -193,7 +193,7 @@ public: * scroll offset in such a way that it remains in the same place on the page * relative. */ - float ScaleWillOverscrollAmount(float aScale, float aFocus); + CSSCoord ScaleWillOverscrollAmount(float aScale, CSSCoord aFocus); /** * Checks if an axis will overscroll in both directions by computing the @@ -204,23 +204,23 @@ public: */ bool ScaleWillOverscrollBothSides(float aScale); - float GetOrigin() const; - float GetCompositionLength() const; - float GetPageStart() const; - float GetPageLength() const; - float GetCompositionEnd() const; - float GetPageEnd() const; + CSSCoord GetOrigin() const; + CSSCoord GetCompositionLength() const; + CSSCoord GetPageStart() const; + CSSCoord GetPageLength() const; + CSSCoord GetCompositionEnd() const; + CSSCoord GetPageEnd() const; - int32_t GetPos() const { return mPos; } + ScreenIntCoord GetPos() const { return mPos; } - virtual float GetPointOffset(const CSSPoint& aPoint) const = 0; - virtual float GetRectLength(const CSSRect& aRect) const = 0; - virtual float GetRectOffset(const CSSRect& aRect) const = 0; + virtual CSSCoord GetPointOffset(const CSSPoint& aPoint) const = 0; + virtual CSSCoord GetRectLength(const CSSRect& aRect) const = 0; + virtual CSSCoord GetRectOffset(const CSSRect& aRect) const = 0; protected: - int32_t mPos; + ScreenIntCoord mPos; uint32_t mPosTimeMs; - int32_t mStartPos; + ScreenIntCoord mStartPos; float mVelocity; bool mAxisLocked; // Whether movement on this axis is locked. AsyncPanZoomController* mAsyncPanZoomController; @@ -230,7 +230,7 @@ protected: // extreme allowed value in the relevant direction (that is, it must be at // its maximum value if mOverscroll is positive, and at its minimum value // if mOverscroll is negative). - float mOverscroll; + CSSCoord mOverscroll; // A queue of (timestamp, velocity) pairs; these are the historical // velocities at the given timestamps. Timestamps are in milliseconds, // velocities are in screen pixels per ms. This member can only be @@ -241,23 +241,23 @@ protected: // Adjust a requested overscroll amount for resistance, yielding a smaller // actual overscroll amount. - float ApplyResistance(float aOverscroll) const; + CSSCoord ApplyResistance(CSSCoord aOverscroll) const; }; class AxisX : public Axis { public: - AxisX(AsyncPanZoomController* mAsyncPanZoomController); - virtual float GetPointOffset(const CSSPoint& aPoint) const; - virtual float GetRectLength(const CSSRect& aRect) const; - virtual float GetRectOffset(const CSSRect& aRect) const; + explicit AxisX(AsyncPanZoomController* mAsyncPanZoomController); + virtual CSSCoord GetPointOffset(const CSSPoint& aPoint) const; + virtual CSSCoord GetRectLength(const CSSRect& aRect) const; + virtual CSSCoord GetRectOffset(const CSSRect& aRect) const; }; class AxisY : public Axis { public: - AxisY(AsyncPanZoomController* mAsyncPanZoomController); - virtual float GetPointOffset(const CSSPoint& aPoint) const; - virtual float GetRectLength(const CSSRect& aRect) const; - virtual float GetRectOffset(const CSSRect& aRect) const; + explicit AxisY(AsyncPanZoomController* mAsyncPanZoomController); + virtual CSSCoord GetPointOffset(const CSSPoint& aPoint) const; + virtual CSSCoord GetRectLength(const CSSRect& aRect) const; + virtual CSSCoord GetRectOffset(const CSSRect& aRect) const; }; } diff --git a/gfx/layers/apz/src/GestureEventListener.h b/gfx/layers/apz/src/GestureEventListener.h index 5a12417eca67..fc5e31049994 100644 --- a/gfx/layers/apz/src/GestureEventListener.h +++ b/gfx/layers/apz/src/GestureEventListener.h @@ -40,7 +40,7 @@ class GestureEventListener MOZ_FINAL { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GestureEventListener) - GestureEventListener(AsyncPanZoomController* aAsyncPanZoomController); + explicit GestureEventListener(AsyncPanZoomController* aAsyncPanZoomController); // -------------------------------------------------------------------------- // These methods must only be called on the controller/UI thread. diff --git a/gfx/layers/basic/BasicCanvasLayer.h b/gfx/layers/basic/BasicCanvasLayer.h index d3fb3a7ce187..f76e593912bf 100644 --- a/gfx/layers/basic/BasicCanvasLayer.h +++ b/gfx/layers/basic/BasicCanvasLayer.h @@ -22,7 +22,7 @@ class BasicCanvasLayer : public CopyableCanvasLayer, public BasicImplData { public: - BasicCanvasLayer(BasicLayerManager* aLayerManager) : + explicit BasicCanvasLayer(BasicLayerManager* aLayerManager) : CopyableCanvasLayer(aLayerManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())) { } diff --git a/gfx/layers/basic/BasicColorLayer.cpp b/gfx/layers/basic/BasicColorLayer.cpp index d5633efd717d..bcca4656a712 100644 --- a/gfx/layers/basic/BasicColorLayer.cpp +++ b/gfx/layers/basic/BasicColorLayer.cpp @@ -26,7 +26,7 @@ namespace layers { class BasicColorLayer : public ColorLayer, public BasicImplData { public: - BasicColorLayer(BasicLayerManager* aLayerManager) : + explicit BasicColorLayer(BasicLayerManager* aLayerManager) : ColorLayer(aLayerManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())) { diff --git a/gfx/layers/basic/BasicCompositor.h b/gfx/layers/basic/BasicCompositor.h index 0c0c5ef25342..f09192ee0294 100644 --- a/gfx/layers/basic/BasicCompositor.h +++ b/gfx/layers/basic/BasicCompositor.h @@ -40,7 +40,7 @@ public: class BasicCompositor : public Compositor { public: - BasicCompositor(nsIWidget *aWidget); + explicit BasicCompositor(nsIWidget *aWidget); protected: virtual ~BasicCompositor(); diff --git a/gfx/layers/basic/BasicContainerLayer.h b/gfx/layers/basic/BasicContainerLayer.h index f18d635dc363..7cc2f6dbcab8 100644 --- a/gfx/layers/basic/BasicContainerLayer.h +++ b/gfx/layers/basic/BasicContainerLayer.h @@ -19,7 +19,7 @@ namespace layers { class BasicContainerLayer : public ContainerLayer, public BasicImplData { public: - BasicContainerLayer(BasicLayerManager* aManager) : + explicit BasicContainerLayer(BasicLayerManager* aManager) : ContainerLayer(aManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())) { diff --git a/gfx/layers/basic/BasicImageLayer.cpp b/gfx/layers/basic/BasicImageLayer.cpp index 32220b35a105..8f027f88fb8f 100644 --- a/gfx/layers/basic/BasicImageLayer.cpp +++ b/gfx/layers/basic/BasicImageLayer.cpp @@ -25,7 +25,7 @@ namespace layers { class BasicImageLayer : public ImageLayer, public BasicImplData { public: - BasicImageLayer(BasicLayerManager* aLayerManager) : + explicit BasicImageLayer(BasicLayerManager* aLayerManager) : ImageLayer(aLayerManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())), mSize(-1, -1) diff --git a/gfx/layers/basic/BasicLayers.h b/gfx/layers/basic/BasicLayers.h index d95f93fb6fd0..215c8279580d 100644 --- a/gfx/layers/basic/BasicLayers.h +++ b/gfx/layers/basic/BasicLayers.h @@ -56,7 +56,7 @@ public: * must be called for any rendering to happen. ThebesLayers will not * be retained. */ - BasicLayerManager(BasicLayerManagerType aType); + explicit BasicLayerManager(BasicLayerManagerType aType); /** * Construct a BasicLayerManager which will have no default * target context. SetDefaultTarget or BeginTransactionWithTarget @@ -72,7 +72,7 @@ public: * must ensure that the widget outlives the layer manager or call * ClearWidget before the widget dies. */ - BasicLayerManager(nsIWidget* aWidget); + explicit BasicLayerManager(nsIWidget* aWidget); protected: virtual ~BasicLayerManager(); diff --git a/gfx/layers/basic/BasicLayersImpl.h b/gfx/layers/basic/BasicLayersImpl.h index 2fba7224f738..7a5926b4475e 100644 --- a/gfx/layers/basic/BasicLayersImpl.h +++ b/gfx/layers/basic/BasicLayersImpl.h @@ -49,7 +49,7 @@ class BasicReadbackLayer : public ReadbackLayer, public BasicImplData { public: - BasicReadbackLayer(BasicLayerManager* aLayerManager) : + explicit BasicReadbackLayer(BasicLayerManager* aLayerManager) : ReadbackLayer(aLayerManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())) { diff --git a/gfx/layers/basic/BasicThebesLayer.h b/gfx/layers/basic/BasicThebesLayer.h index 0a2b0a0b85ec..ffbbe8259b27 100644 --- a/gfx/layers/basic/BasicThebesLayer.h +++ b/gfx/layers/basic/BasicThebesLayer.h @@ -30,7 +30,7 @@ public: typedef RotatedContentBuffer::PaintState PaintState; typedef RotatedContentBuffer::ContentType ContentType; - BasicThebesLayer(BasicLayerManager* aLayerManager) : + explicit BasicThebesLayer(BasicLayerManager* aLayerManager) : ThebesLayer(aLayerManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())), mContentClient(nullptr) diff --git a/gfx/layers/client/ClientCanvasLayer.h b/gfx/layers/client/ClientCanvasLayer.h index 591319f4bce0..b9de0fce0da7 100644 --- a/gfx/layers/client/ClientCanvasLayer.h +++ b/gfx/layers/client/ClientCanvasLayer.h @@ -36,7 +36,7 @@ class ClientCanvasLayer : public CopyableCanvasLayer, { typedef CanvasClient::CanvasClientType CanvasClientType; public: - ClientCanvasLayer(ClientLayerManager* aLayerManager) : + explicit ClientCanvasLayer(ClientLayerManager* aLayerManager) : CopyableCanvasLayer(aLayerManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())) , mTextureSurface(nullptr) diff --git a/gfx/layers/client/ClientColorLayer.cpp b/gfx/layers/client/ClientColorLayer.cpp index 1b49c07f2129..29038de37e7f 100644 --- a/gfx/layers/client/ClientColorLayer.cpp +++ b/gfx/layers/client/ClientColorLayer.cpp @@ -21,7 +21,7 @@ using namespace mozilla::gfx; class ClientColorLayer : public ColorLayer, public ClientLayer { public: - ClientColorLayer(ClientLayerManager* aLayerManager) : + explicit ClientColorLayer(ClientLayerManager* aLayerManager) : ColorLayer(aLayerManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())) { diff --git a/gfx/layers/client/ClientContainerLayer.h b/gfx/layers/client/ClientContainerLayer.h index 23329689c0a2..f82e65f166b6 100644 --- a/gfx/layers/client/ClientContainerLayer.h +++ b/gfx/layers/client/ClientContainerLayer.h @@ -27,7 +27,7 @@ class ClientContainerLayer : public ContainerLayer, public ClientLayer { public: - ClientContainerLayer(ClientLayerManager* aManager) : + explicit ClientContainerLayer(ClientLayerManager* aManager) : ContainerLayer(aManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())) { @@ -150,7 +150,7 @@ protected: class ClientRefLayer : public RefLayer, public ClientLayer { public: - ClientRefLayer(ClientLayerManager* aManager) : + explicit ClientRefLayer(ClientLayerManager* aManager) : RefLayer(aManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())) { diff --git a/gfx/layers/client/ClientImageLayer.cpp b/gfx/layers/client/ClientImageLayer.cpp index e016ba521134..2d348d7d3691 100644 --- a/gfx/layers/client/ClientImageLayer.cpp +++ b/gfx/layers/client/ClientImageLayer.cpp @@ -26,7 +26,7 @@ using namespace mozilla::gfx; class ClientImageLayer : public ImageLayer, public ClientLayer { public: - ClientImageLayer(ClientLayerManager* aLayerManager) + explicit ClientImageLayer(ClientLayerManager* aLayerManager) : ImageLayer(aLayerManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST())) , mImageClientTypeContainer(CompositableType::BUFFER_UNKNOWN) diff --git a/gfx/layers/client/ClientLayerManager.h b/gfx/layers/client/ClientLayerManager.h index f5dd326738ae..dfdfa39724f9 100644 --- a/gfx/layers/client/ClientLayerManager.h +++ b/gfx/layers/client/ClientLayerManager.h @@ -43,7 +43,7 @@ class ClientLayerManager : public LayerManager typedef nsTArray > LayerRefArray; public: - ClientLayerManager(nsIWidget* aWidget); + explicit ClientLayerManager(nsIWidget* aWidget); protected: virtual ~ClientLayerManager(); diff --git a/gfx/layers/client/ClientReadbackLayer.h b/gfx/layers/client/ClientReadbackLayer.h index f3046fea8115..89e673306088 100644 --- a/gfx/layers/client/ClientReadbackLayer.h +++ b/gfx/layers/client/ClientReadbackLayer.h @@ -17,7 +17,7 @@ class ClientReadbackLayer : public ClientLayer { public: - ClientReadbackLayer(ClientLayerManager *aManager) + explicit ClientReadbackLayer(ClientLayerManager *aManager) : ReadbackLayer(aManager, nullptr) { mImplData = static_cast(this); diff --git a/gfx/layers/client/ClientThebesLayer.h b/gfx/layers/client/ClientThebesLayer.h index b5864ef448f4..01b7513973d7 100644 --- a/gfx/layers/client/ClientThebesLayer.h +++ b/gfx/layers/client/ClientThebesLayer.h @@ -33,8 +33,8 @@ public: typedef RotatedContentBuffer::PaintState PaintState; typedef RotatedContentBuffer::ContentType ContentType; - ClientThebesLayer(ClientLayerManager* aLayerManager, - LayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE) : + explicit ClientThebesLayer(ClientLayerManager* aLayerManager, + LayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE) : ThebesLayer(aLayerManager, static_cast(MOZ_THIS_IN_INITIALIZER_LIST()), aCreationHint), diff --git a/gfx/layers/client/ClientTiledThebesLayer.cpp b/gfx/layers/client/ClientTiledThebesLayer.cpp index 0d98719f13ce..ee40a0d44775 100644 --- a/gfx/layers/client/ClientTiledThebesLayer.cpp +++ b/gfx/layers/client/ClientTiledThebesLayer.cpp @@ -59,7 +59,7 @@ ClientTiledThebesLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs) static LayerRect ApplyParentLayerToLayerTransform(const gfx::Matrix4x4& aTransform, const ParentLayerRect& aParentLayerRect) { - return TransformTo(gfx::To3DMatrix(aTransform), aParentLayerRect); + return TransformTo(aTransform, aParentLayerRect); } static gfx::Matrix4x4 @@ -68,12 +68,11 @@ GetTransformToAncestorsParentLayer(Layer* aStart, Layer* aAncestor) gfx::Matrix4x4 transform; Layer* ancestorParent = aAncestor->GetParent(); for (Layer* iter = aStart; iter != ancestorParent; iter = iter->GetParent()) { + transform = transform * iter->GetTransform(); // If the layer has a non-transient async transform then we need to apply it here // because it will get applied by the APZ in the compositor as well const FrameMetrics& metrics = iter->GetFrameMetrics(); transform = transform * gfx::Matrix4x4().Scale(metrics.mResolution.scale, metrics.mResolution.scale, 1.f); - - transform = transform * iter->GetTransform(); } return transform; } diff --git a/gfx/layers/client/ClientTiledThebesLayer.h b/gfx/layers/client/ClientTiledThebesLayer.h index da3fe6a75913..f4539ee3fc49 100644 --- a/gfx/layers/client/ClientTiledThebesLayer.h +++ b/gfx/layers/client/ClientTiledThebesLayer.h @@ -41,8 +41,8 @@ class ClientTiledThebesLayer : public ThebesLayer, typedef ThebesLayer Base; public: - ClientTiledThebesLayer(ClientLayerManager* const aManager, - ClientLayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE); + explicit ClientTiledThebesLayer(ClientLayerManager* const aManager, + ClientLayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE); protected: ~ClientTiledThebesLayer(); diff --git a/gfx/layers/client/CompositableClient.h b/gfx/layers/client/CompositableClient.h index 63293c88f66e..9efa601865ef 100644 --- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -123,7 +123,7 @@ protected: public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableClient) - CompositableClient(CompositableForwarder* aForwarder, TextureFlags aFlags = TextureFlags::NO_FLAGS); + explicit CompositableClient(CompositableForwarder* aForwarder, TextureFlags aFlags = TextureFlags::NO_FLAGS); virtual TextureInfo GetTextureInfo() const = 0; @@ -246,8 +246,8 @@ protected: */ struct AutoRemoveTexture { - AutoRemoveTexture(CompositableClient* aCompositable, - TextureClient* aTexture = nullptr) + explicit AutoRemoveTexture(CompositableClient* aCompositable, + TextureClient* aTexture = nullptr) : mTexture(aTexture) , mCompositable(aCompositable) {} diff --git a/gfx/layers/client/ContentClient.h b/gfx/layers/client/ContentClient.h index a31a3eaea474..0fd083c15190 100644 --- a/gfx/layers/client/ContentClient.h +++ b/gfx/layers/client/ContentClient.h @@ -83,7 +83,7 @@ public: */ static TemporaryRef CreateContentClient(CompositableForwarder* aFwd); - ContentClient(CompositableForwarder* aForwarder) + explicit ContentClient(CompositableForwarder* aForwarder) : CompositableClient(aForwarder) {} virtual ~ContentClient() @@ -113,7 +113,7 @@ public: class ContentClientRemote : public ContentClient { public: - ContentClientRemote(CompositableForwarder* aForwarder) + explicit ContentClientRemote(CompositableForwarder* aForwarder) : ContentClient(aForwarder) {} @@ -190,7 +190,7 @@ class ContentClientRemoteBuffer : public ContentClientRemote using RotatedContentBuffer::BufferRect; using RotatedContentBuffer::BufferRotation; public: - ContentClientRemoteBuffer(CompositableForwarder* aForwarder) + explicit ContentClientRemoteBuffer(CompositableForwarder* aForwarder) : ContentClientRemote(aForwarder) , RotatedContentBuffer(ContainsVisibleBounds) , mIsNewBuffer(false) @@ -315,7 +315,7 @@ protected: class ContentClientDoubleBuffered : public ContentClientRemoteBuffer { public: - ContentClientDoubleBuffered(CompositableForwarder* aFwd) + explicit ContentClientDoubleBuffered(CompositableForwarder* aFwd) : ContentClientRemoteBuffer(aFwd) { mTextureInfo.mCompositableType = CompositableType::CONTENT_DOUBLE; @@ -374,7 +374,7 @@ private: class ContentClientSingleBuffered : public ContentClientRemoteBuffer { public: - ContentClientSingleBuffered(CompositableForwarder* aFwd) + explicit ContentClientSingleBuffered(CompositableForwarder* aFwd) : ContentClientRemoteBuffer(aFwd) { mTextureInfo.mCompositableType = CompositableType::CONTENT_SINGLE; @@ -394,7 +394,7 @@ class ContentClientIncremental : public ContentClientRemote , public BorrowDrawTarget { public: - ContentClientIncremental(CompositableForwarder* aFwd) + explicit ContentClientIncremental(CompositableForwarder* aFwd) : ContentClientRemote(aFwd) , mContentType(gfxContentType::COLOR_ALPHA) , mHasBuffer(false) diff --git a/gfx/layers/client/SimpleTiledContentClient.h b/gfx/layers/client/SimpleTiledContentClient.h index 0eea5458199d..31d43d9f68f9 100644 --- a/gfx/layers/client/SimpleTiledContentClient.h +++ b/gfx/layers/client/SimpleTiledContentClient.h @@ -163,8 +163,8 @@ class SimpleClientTiledThebesLayer : public ThebesLayer, typedef ThebesLayer Base; public: - SimpleClientTiledThebesLayer(ClientLayerManager* const aManager, - ClientLayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE); + explicit SimpleClientTiledThebesLayer(ClientLayerManager* const aManager, + ClientLayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE); protected: ~SimpleClientTiledThebesLayer(); diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index f87152d57782..5c344caea826 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -137,7 +137,7 @@ class TextureClient : public AtomicRefCountedWithFinalize { public: - TextureClient(TextureFlags aFlags = TextureFlags::DEFAULT); + explicit TextureClient(TextureFlags aFlags = TextureFlags::DEFAULT); virtual ~TextureClient(); // Creates and allocates a TextureClient usable with Moz2D. @@ -465,7 +465,7 @@ protected: class TextureClientReleaseTask : public Task { public: - TextureClientReleaseTask(TextureClient* aClient) + explicit TextureClientReleaseTask(TextureClient* aClient) : mTextureClient(aClient) { } @@ -620,7 +620,7 @@ protected: class StreamTextureClient : public TextureClient { public: - StreamTextureClient(TextureFlags aFlags); + explicit StreamTextureClient(TextureFlags aFlags); protected: ~StreamTextureClient(); @@ -669,7 +669,7 @@ struct TextureClientAutoUnlock { TextureClient* mTexture; - TextureClientAutoUnlock(TextureClient* aTexture) + explicit TextureClientAutoUnlock(TextureClient* aTexture) : mTexture(aTexture) {} ~TextureClientAutoUnlock() @@ -688,7 +688,7 @@ template class TKeepAlive : public KeepAlive { public: - TKeepAlive(T* aData) : mData(aData) {} + explicit TKeepAlive(T* aData) : mData(aData) {} protected: RefPtr mData; }; diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 5bc89806f06b..6dd26d9fd9c6 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -148,12 +148,12 @@ ComputeViewTransform(const FrameMetrics& aContentMetrics, const FrameMetrics& aC // but with aContentMetrics used in place of mLastContentPaintMetrics, because they // should be equivalent, modulo race conditions while transactions are inflight. - LayerPoint translation = (aCompositorMetrics.GetScrollOffset() - aContentMetrics.GetScrollOffset()) - * aContentMetrics.LayersPixelsPerCSSPixel(); - return ViewTransform(-translation, - aCompositorMetrics.GetZoom() + ParentLayerToScreenScale scale = aCompositorMetrics.GetZoom() / aContentMetrics.mDevPixelsPerCSSPixel - / aCompositorMetrics.GetParentResolution()); + / aCompositorMetrics.GetParentResolution(); + ScreenPoint translation = (aCompositorMetrics.GetScrollOffset() - aContentMetrics.GetScrollOffset()) + * aCompositorMetrics.GetZoom(); + return ViewTransform(scale, -translation); } bool @@ -1338,22 +1338,16 @@ GetCompositorSideCompositionBounds(Layer* aScrollAncestor, 1.f); nonTransientAPZUntransform.Invert(); - Matrix4x4 layerTransform = aScrollAncestor->GetTransform(); - Matrix4x4 layerUntransform = layerTransform; - layerUntransform.Invert(); + // Take off the last "term" of aTransformToCompBounds, which + // is the APZ's nontransient async transform. Replace it with + // the APZ's async transform (this includes the nontransient + // component as well). + Matrix4x4 transform = aTransformToCompBounds + * nonTransientAPZUntransform + * Matrix4x4(aAPZTransform); + transform.Invert(); - // First take off the last two "terms" of aTransformToCompBounds, which - // are the scroll ancestor's local transform and the APZ's nontransient async - // transform. - Matrix4x4 transform = aTransformToCompBounds * layerUntransform * nonTransientAPZUntransform; - - // Next, apply the APZ's async transform (this includes the nontransient component - // as well). - transform = transform * Matrix4x4(aAPZTransform); - - // Finally, put back the scroll ancestor's local transform. - transform = transform * layerTransform; - return TransformTo(To3DMatrix(transform).Inverse(), + return TransformTo(transform, aScrollAncestor->GetFrameMetrics().mCompositionBounds); } diff --git a/gfx/layers/client/TiledContentClient.h b/gfx/layers/client/TiledContentClient.h index cf62128274a5..dba6a3836ced 100644 --- a/gfx/layers/client/TiledContentClient.h +++ b/gfx/layers/client/TiledContentClient.h @@ -97,7 +97,7 @@ private: }; public: - gfxShmSharedReadLock(ISurfaceAllocator* aAllocator); + explicit gfxShmSharedReadLock(ISurfaceAllocator* aAllocator); protected: ~gfxShmSharedReadLock(); diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index 977e258bb786..24f52f6bc893 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -505,6 +505,22 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint) return activeAnimations; } +static bool +SampleAPZAnimations(Layer* aLayer, TimeStamp aPoint) +{ + bool activeAnimations = false; + for (Layer* child = aLayer->GetFirstChild(); child; + child = child->GetNextSibling()) { + activeAnimations |= SampleAPZAnimations(child, aPoint); + } + + if (AsyncPanZoomController* apzc = aLayer->GetAsyncPanZoomController()) { + activeAnimations |= apzc->AdvanceAnimations(aPoint); + } + + return activeAnimations; +} + Matrix4x4 AdjustAndCombineWithCSSTransform(const Matrix4x4& asyncTransform, Layer* aLayer) { @@ -523,20 +539,18 @@ AdjustAndCombineWithCSSTransform(const Matrix4x4& asyncTransform, Layer* aLayer) } // Combine the async transform with the layer's CSS transform. - result = result * aLayer->GetTransform(); + result = aLayer->GetTransform() * result; return result; } bool -AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame, - Layer *aLayer, - bool* aWantNextFrame) +AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer) { bool appliedTransform = false; for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { appliedTransform |= - ApplyAsyncContentTransformToTree(aCurrentFrame, child, aWantNextFrame); + ApplyAsyncContentTransformToTree(child); } if (AsyncPanZoomController* controller = aLayer->GetAsyncPanZoomController()) { @@ -545,11 +559,9 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram ViewTransform asyncTransformWithoutOverscroll, overscrollTransform; ScreenPoint scrollOffset; - *aWantNextFrame |= - controller->SampleContentTransformForFrame(aCurrentFrame, - &asyncTransformWithoutOverscroll, - scrollOffset, - &overscrollTransform); + controller->SampleContentTransformForFrame(&asyncTransformWithoutOverscroll, + scrollOffset, + &overscrollTransform); const FrameMetrics& metrics = aLayer->GetFrameMetrics(); CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel(); @@ -603,7 +615,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram } if (aLayer->AsContainerLayer() && aLayer->GetScrollbarDirection() != Layer::NONE) { - ApplyAsyncTransformToScrollbar(aCurrentFrame, aLayer->AsContainerLayer()); + ApplyAsyncTransformToScrollbar(aLayer->AsContainerLayer()); } return appliedTransform; } @@ -637,7 +649,7 @@ LayerIsScrollbarTarget(Layer* aTarget, ContainerLayer* aScrollbar) } static void -ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer* aScrollbar, +ApplyAsyncTransformToScrollbarForContent(ContainerLayer* aScrollbar, Layer* aContent, bool aScrollbarIsChild) { // We only apply the transform if the scroll-target layer has non-container @@ -653,18 +665,6 @@ ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer const FrameMetrics& metrics = aContent->GetFrameMetrics(); AsyncPanZoomController* apzc = aContent->GetAsyncPanZoomController(); - if (aScrollbarIsChild) { - // Because we try to apply the scrollbar transform before we apply the async transform on - // the actual content, we need to ensure that the APZC has updated any pending animations - // to the current frame timestamp before we extract the transforms from it. The code in this - // block accomplishes that and throws away the temp variables. - // TODO: it might be cleaner to do a pass through the layer tree to advance all the APZC - // transforms before updating the layer shadow transforms. That will allow removal of this code. - ViewTransform asyncTransform; - ScreenPoint scrollOffset; - apzc->SampleContentTransformForFrame(aCurrentFrame, &asyncTransform, scrollOffset); - } - Matrix4x4 asyncTransform = apzc->GetCurrentAsyncTransform(); Matrix4x4 nontransientTransform = apzc->GetNontransientAsyncTransform(); Matrix4x4 nontransientUntransform = nontransientTransform; @@ -751,7 +751,7 @@ FindScrolledLayerForScrollbar(ContainerLayer* aLayer, bool* aOutIsAncestor) } void -AsyncCompositionManager::ApplyAsyncTransformToScrollbar(TimeStamp aCurrentFrame, ContainerLayer* aLayer) +AsyncCompositionManager::ApplyAsyncTransformToScrollbar(ContainerLayer* aLayer) { // If this layer corresponds to a scrollbar, then there should be a layer that // is a previous sibling or a parent that has a matching ViewID on its FrameMetrics. @@ -763,8 +763,7 @@ AsyncCompositionManager::ApplyAsyncTransformToScrollbar(TimeStamp aCurrentFrame, bool isAncestor = false; Layer* scrollTarget = FindScrolledLayerForScrollbar(aLayer, &isAncestor); if (scrollTarget) { - ApplyAsyncTransformToScrollbarForContent(aCurrentFrame, aLayer, scrollTarget, - isAncestor); + ApplyAsyncTransformToScrollbarForContent(aLayer, scrollTarget, isAncestor); } } @@ -827,23 +826,20 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer) // primary scrollable layer. We compare this to the user zoom and scroll // offset in the view transform we obtained from Java in order to compute the // transformation we need to apply. - LayerToScreenScale zoomAdjust = userZoom / geckoZoom; - - LayerPoint geckoScroll(0, 0); + ScreenPoint geckoScroll(0, 0); if (metrics.IsScrollable()) { - geckoScroll = metrics.GetScrollOffset() * geckoZoom; + geckoScroll = metrics.GetScrollOffset() * userZoom; } - - LayerPoint translation = (userScroll / zoomAdjust) - geckoScroll; - Matrix4x4 treeTransform = ViewTransform(-translation, - userZoom - / metrics.mDevPixelsPerCSSPixel - / metrics.GetParentResolution()); + ParentLayerToScreenScale scale = userZoom + / metrics.mDevPixelsPerCSSPixel + / metrics.GetParentResolution(); + ScreenPoint translation = userScroll - geckoScroll; + Matrix4x4 treeTransform = ViewTransform(scale, -translation); // The transform already takes the resolution scale into account. Since we // will apply the resolution scale again when computing the effective // transform, we must apply the inverse resolution scale here. - Matrix4x4 computedTransform = treeTransform * oldTransform; + Matrix4x4 computedTransform = oldTransform * treeTransform; if (ContainerLayer* container = aLayer->AsContainerLayer()) { computedTransform.Scale(1.0f/container->GetPreXScale(), 1.0f/container->GetPreYScale(), @@ -944,7 +940,8 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame) // code also includes Fennec which is rendered async. Fennec uses // its own platform-specific async rendering that is done partially // in Gecko and partially in Java. - if (!ApplyAsyncContentTransformToTree(aCurrentFrame, root, &wantNextFrame)) { + wantNextFrame |= SampleAPZAnimations(root, aCurrentFrame); + if (!ApplyAsyncContentTransformToTree(root)) { nsAutoTArray scrollableLayers; #ifdef MOZ_WIDGET_ANDROID scrollableLayers.AppendElement(mLayerManager->GetPrimaryScrollableLayer()); diff --git a/gfx/layers/composite/AsyncCompositionManager.h b/gfx/layers/composite/AsyncCompositionManager.h index becfe0188147..17af6acf27c6 100644 --- a/gfx/layers/composite/AsyncCompositionManager.h +++ b/gfx/layers/composite/AsyncCompositionManager.h @@ -6,7 +6,7 @@ #ifndef GFX_ASYNCCOMPOSITIONMANAGER_H #define GFX_ASYNCCOMPOSITIONMANAGER_H -#include "Units.h" // for LayerPoint, etc +#include "Units.h" // for ScreenPoint, etc #include "mozilla/layers/LayerManagerComposite.h" // for LayerManagerComposite #include "mozilla/Attributes.h" // for MOZ_DELETE, MOZ_FINAL, etc #include "mozilla/RefPtr.h" // for RefCounted @@ -28,17 +28,17 @@ class AutoResolveRefLayers; // Represents (affine) transforms that are calculated from a content view. struct ViewTransform { - ViewTransform(LayerPoint aTranslation = LayerPoint(), - ParentLayerToScreenScale aScale = ParentLayerToScreenScale()) - : mTranslation(aTranslation) - , mScale(aScale) + explicit ViewTransform(ParentLayerToScreenScale aScale = ParentLayerToScreenScale(), + ScreenPoint aTranslation = ScreenPoint()) + : mScale(aScale) + , mTranslation(aTranslation) {} operator gfx::Matrix4x4() const { return - gfx::Matrix4x4().Translate(mTranslation.x, mTranslation.y, 0) * - gfx::Matrix4x4().Scale(mScale.scale, mScale.scale, 1); + gfx::Matrix4x4().Scale(mScale.scale, mScale.scale, 1) + .PostTranslate(mTranslation.x, mTranslation.y, 0); } // For convenience, to avoid writing the cumbersome @@ -55,8 +55,8 @@ struct ViewTransform { return !(*this == rhs); } - LayerPoint mTranslation; ParentLayerToScreenScale mScale; + ScreenPoint mTranslation; }; /** @@ -76,7 +76,7 @@ class AsyncCompositionManager MOZ_FINAL public: NS_INLINE_DECL_REFCOUNTING(AsyncCompositionManager) - AsyncCompositionManager(LayerManagerComposite* aManager) + explicit AsyncCompositionManager(LayerManagerComposite* aManager) : mLayerManager(aManager) , mIsFirstPaint(false) , mLayersUpdated(false) @@ -124,15 +124,13 @@ public: private: void TransformScrollableLayer(Layer* aLayer); // Return true if an AsyncPanZoomController content transform was - // applied for |aLayer|. *aWantNextFrame is set to true if the - // controller wants another animation frame. - bool ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame, Layer* aLayer, - bool* aWantNextFrame); + // applied for |aLayer|. + bool ApplyAsyncContentTransformToTree(Layer* aLayer); /** * Update the shadow transform for aLayer assuming that is a scrollbar, * so that it stays in sync with the content that is being scrolled by APZ. */ - void ApplyAsyncTransformToScrollbar(TimeStamp aCurrentFrame, ContainerLayer* aLayer); + void ApplyAsyncTransformToScrollbar(ContainerLayer* aLayer); void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, @@ -209,7 +207,7 @@ private: class MOZ_STACK_CLASS AutoResolveRefLayers { public: - AutoResolveRefLayers(AsyncCompositionManager* aManager) : mManager(aManager) + explicit AutoResolveRefLayers(AsyncCompositionManager* aManager) : mManager(aManager) { if (mManager) { mManager->ResolveRefLayers(); diff --git a/gfx/layers/composite/CanvasLayerComposite.h b/gfx/layers/composite/CanvasLayerComposite.h index 70f54fa223d4..6051d974ae1f 100644 --- a/gfx/layers/composite/CanvasLayerComposite.h +++ b/gfx/layers/composite/CanvasLayerComposite.h @@ -28,7 +28,7 @@ class CanvasLayerComposite : public CanvasLayer, public LayerComposite { public: - CanvasLayerComposite(LayerManagerComposite* aManager); + explicit CanvasLayerComposite(LayerManagerComposite* aManager); protected: virtual ~CanvasLayerComposite(); diff --git a/gfx/layers/composite/ColorLayerComposite.h b/gfx/layers/composite/ColorLayerComposite.h index 31ec0459d709..8414e8a30363 100644 --- a/gfx/layers/composite/ColorLayerComposite.h +++ b/gfx/layers/composite/ColorLayerComposite.h @@ -23,7 +23,7 @@ class ColorLayerComposite : public ColorLayer, public LayerComposite { public: - ColorLayerComposite(LayerManagerComposite *aManager) + explicit ColorLayerComposite(LayerManagerComposite *aManager) : ColorLayer(aManager, nullptr) , LayerComposite(aManager) { diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index 33a2f4b16efe..f4613c3b0c38 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -88,7 +88,7 @@ protected: public: NS_INLINE_DECL_REFCOUNTING(CompositableHost) - CompositableHost(const TextureInfo& aTextureInfo); + explicit CompositableHost(const TextureInfo& aTextureInfo); static TemporaryRef Create(const TextureInfo& aTextureInfo); @@ -304,7 +304,7 @@ protected: class AutoLockCompositableHost MOZ_FINAL { public: - AutoLockCompositableHost(CompositableHost* aHost) + explicit AutoLockCompositableHost(CompositableHost* aHost) : mHost(aHost) { mSucceeded = mHost->Lock(); diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index cd418c0fa2c7..c3c71a103f9e 100644 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -227,8 +227,8 @@ static void DrawVelGraph(const nsIntRect& aClipRect, for (int32_t i = (int32_t)velocityData->mData.size() - 2; i >= 0; i--) { const gfx::Point& p1 = velocityData->mData[i+1].mPoint; const gfx::Point& p2 = velocityData->mData[i].mPoint; - int vel = sqrt((p1.x - p2.x) * (p1.x - p2.x) + - (p1.y - p2.y) * (p1.y - p2.y)); + int vel = sqrt((p1.x - p2.x).value * (p1.x - p2.x).value + + (p1.y - p2.y).value * (p1.y - p2.y).value); Point next = Point(graphRect.width / circularBufferSize * i, graphRect.height - vel/yScaleFactor); if (first) { @@ -270,11 +270,9 @@ static void PrintUniformityInfo(Layer* aLayer) return; } - LayerIntPoint scrollOffset = RoundedToInt(frameMetrics.GetScrollOffsetInLayerPixels()); + const LayerPoint scrollOffset = frameMetrics.GetScrollOffsetInLayerPixels(); const gfx::Point layerTransform = GetScrollData(aLayer); - gfx::Point layerScroll; - layerScroll.x = scrollOffset.x - layerTransform.x; - layerScroll.y = scrollOffset.y - layerTransform.y; + const gfx::Point layerScroll = scrollOffset.ToUnknownPoint() - layerTransform; printf_stderr("UniformityInfo Layer_Move %llu %p %f, %f\n", TimeStamp::Now(), aLayer, layerScroll.x, layerScroll.y); diff --git a/gfx/layers/composite/ContainerLayerComposite.h b/gfx/layers/composite/ContainerLayerComposite.h index c3cbc594f301..15518617de35 100644 --- a/gfx/layers/composite/ContainerLayerComposite.h +++ b/gfx/layers/composite/ContainerLayerComposite.h @@ -53,7 +53,7 @@ class ContainerLayerComposite : public ContainerLayer, const nsIntRect& aClipRect); public: - ContainerLayerComposite(LayerManagerComposite *aManager); + explicit ContainerLayerComposite(LayerManagerComposite *aManager); protected: ~ContainerLayerComposite(); @@ -117,7 +117,7 @@ class RefLayerComposite : public RefLayer, const nsIntRect& aClipRect); public: - RefLayerComposite(LayerManagerComposite *aManager); + explicit RefLayerComposite(LayerManagerComposite *aManager); protected: ~RefLayerComposite(); diff --git a/gfx/layers/composite/ContentHost.h b/gfx/layers/composite/ContentHost.h index e5aa7156aa9d..8270e79d18f1 100644 --- a/gfx/layers/composite/ContentHost.h +++ b/gfx/layers/composite/ContentHost.h @@ -68,7 +68,7 @@ public: bool PaintWillResample() { return mPaintWillResample; } protected: - ContentHost(const TextureInfo& aTextureInfo) + explicit ContentHost(const TextureInfo& aTextureInfo) : CompositableHost(aTextureInfo) , mPaintWillResample(false) {} @@ -93,7 +93,7 @@ public: typedef RotatedContentBuffer::ContentType ContentType; typedef RotatedContentBuffer::PaintState PaintState; - ContentHostBase(const TextureInfo& aTextureInfo); + explicit ContentHostBase(const TextureInfo& aTextureInfo); virtual ~ContentHostBase(); virtual void Composite(EffectChain& aEffectChain, @@ -127,7 +127,7 @@ protected: class ContentHostTexture : public ContentHostBase { public: - ContentHostTexture(const TextureInfo& aTextureInfo) + explicit ContentHostTexture(const TextureInfo& aTextureInfo) : ContentHostBase(aTextureInfo) , mLocked(false) { } @@ -201,7 +201,7 @@ protected: class ContentHostDoubleBuffered : public ContentHostTexture { public: - ContentHostDoubleBuffered(const TextureInfo& aTextureInfo) + explicit ContentHostDoubleBuffered(const TextureInfo& aTextureInfo) : ContentHostTexture(aTextureInfo) {} @@ -225,7 +225,7 @@ protected: class ContentHostSingleBuffered : public ContentHostTexture { public: - ContentHostSingleBuffered(const TextureInfo& aTextureInfo) + explicit ContentHostSingleBuffered(const TextureInfo& aTextureInfo) : ContentHostTexture(aTextureInfo) {} virtual ~ContentHostSingleBuffered() {} @@ -251,7 +251,7 @@ public: class ContentHostIncremental : public ContentHostBase { public: - ContentHostIncremental(const TextureInfo& aTextureInfo); + explicit ContentHostIncremental(const TextureInfo& aTextureInfo); ~ContentHostIncremental(); virtual CompositableType GetType() { return CompositableType::BUFFER_CONTENT_INC; } diff --git a/gfx/layers/composite/FPSCounter.h b/gfx/layers/composite/FPSCounter.h index e07b9d6df821..2a493d3e4f01 100644 --- a/gfx/layers/composite/FPSCounter.h +++ b/gfx/layers/composite/FPSCounter.h @@ -58,7 +58,7 @@ const int kMaxFrames = 2400; */ class FPSCounter { public: - FPSCounter(const char* aName); + explicit FPSCounter(const char* aName); ~FPSCounter(); void AddFrame(TimeStamp aTimestamp); diff --git a/gfx/layers/composite/ImageHost.h b/gfx/layers/composite/ImageHost.h index bae8ed772072..79f249b7a90f 100644 --- a/gfx/layers/composite/ImageHost.h +++ b/gfx/layers/composite/ImageHost.h @@ -40,7 +40,7 @@ struct EffectChain; class ImageHost : public CompositableHost { public: - ImageHost(const TextureInfo& aTextureInfo); + explicit ImageHost(const TextureInfo& aTextureInfo); ~ImageHost(); virtual CompositableType GetType() { return mTextureInfo.mCompositableType; } diff --git a/gfx/layers/composite/ImageLayerComposite.h b/gfx/layers/composite/ImageLayerComposite.h index 50dd30a12b31..faded30bbac2 100644 --- a/gfx/layers/composite/ImageLayerComposite.h +++ b/gfx/layers/composite/ImageLayerComposite.h @@ -31,7 +31,7 @@ class ImageLayerComposite : public ImageLayer, typedef gl::TextureImage TextureImage; public: - ImageLayerComposite(LayerManagerComposite* aManager); + explicit ImageLayerComposite(LayerManagerComposite* aManager); protected: virtual ~ImageLayerComposite(); diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index b7589c635984..901c8bf6fdda 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -73,7 +73,7 @@ class LayerManagerComposite : public LayerManager typedef mozilla::gfx::SurfaceFormat SurfaceFormat; public: - LayerManagerComposite(Compositor* aCompositor); + explicit LayerManagerComposite(Compositor* aCompositor); ~LayerManagerComposite(); virtual void Destroy() MOZ_OVERRIDE; @@ -315,7 +315,7 @@ private: class LayerComposite { public: - LayerComposite(LayerManagerComposite* aManager); + explicit LayerComposite(LayerManagerComposite* aManager); virtual ~LayerComposite(); diff --git a/gfx/layers/composite/TextRenderer.h b/gfx/layers/composite/TextRenderer.h index 97031c9ecfb1..30cb22cfccfa 100644 --- a/gfx/layers/composite/TextRenderer.h +++ b/gfx/layers/composite/TextRenderer.h @@ -22,7 +22,7 @@ class TextRenderer public: NS_INLINE_DECL_REFCOUNTING(TextRenderer) - TextRenderer(Compositor *aCompositor) + explicit TextRenderer(Compositor *aCompositor) : mCompositor(aCompositor) { } diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index ed22f1fa7dab..a0b2044f5770 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -71,7 +71,7 @@ namespace layers { class TextureParent : public PTextureParent { public: - TextureParent(CompositableParentManager* aManager); + explicit TextureParent(CompositableParentManager* aManager); ~TextureParent(); diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index e22f0b2963c8..4cb8455fc7b8 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -286,7 +286,7 @@ class TextureHost friend class AtomicRefCountedWithFinalize; public: - TextureHost(TextureFlags aFlags); + explicit TextureHost(TextureFlags aFlags); protected: virtual ~TextureHost(); @@ -652,7 +652,7 @@ protected: class MOZ_STACK_CLASS AutoLockTextureHost { public: - AutoLockTextureHost(TextureHost* aTexture) + explicit AutoLockTextureHost(TextureHost* aTexture) : mTexture(aTexture) { mLocked = mTexture ? mTexture->Lock() : false; @@ -679,7 +679,7 @@ private: class CompositingRenderTarget : public TextureSource { public: - CompositingRenderTarget(const gfx::IntPoint& aOrigin) + explicit CompositingRenderTarget(const gfx::IntPoint& aOrigin) : mOrigin(aOrigin) {} virtual ~CompositingRenderTarget() {} diff --git a/gfx/layers/composite/ThebesLayerComposite.h b/gfx/layers/composite/ThebesLayerComposite.h index 0a09112cf82a..5d64fbc4c863 100644 --- a/gfx/layers/composite/ThebesLayerComposite.h +++ b/gfx/layers/composite/ThebesLayerComposite.h @@ -37,7 +37,7 @@ class ThebesLayerComposite : public ThebesLayer, public LayerComposite { public: - ThebesLayerComposite(LayerManagerComposite *aManager); + explicit ThebesLayerComposite(LayerManagerComposite *aManager); protected: virtual ~ThebesLayerComposite(); diff --git a/gfx/layers/composite/TiledContentHost.h b/gfx/layers/composite/TiledContentHost.h index 1c29651a4551..dfeb45070272 100644 --- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -189,7 +189,7 @@ class TiledContentHost : public ContentHost, public TiledLayerComposer { public: - TiledContentHost(const TextureInfo& aTextureInfo); + explicit TiledContentHost(const TextureInfo& aTextureInfo); protected: ~TiledContentHost(); diff --git a/gfx/layers/ipc/AsyncTransactionTracker.h b/gfx/layers/ipc/AsyncTransactionTracker.h index 5fb6cd6eebd0..8ea40e58b7f1 100644 --- a/gfx/layers/ipc/AsyncTransactionTracker.h +++ b/gfx/layers/ipc/AsyncTransactionTracker.h @@ -190,7 +190,7 @@ protected: */ class FenceDeliveryTracker : public AsyncTransactionTracker { public: - FenceDeliveryTracker(FenceHandle& aFenceHandle) + explicit FenceDeliveryTracker(FenceHandle& aFenceHandle) : mFenceHandle(aFenceHandle) { MOZ_COUNT_CTOR(FenceDeliveryTracker); diff --git a/gfx/layers/ipc/CompositorChild.h b/gfx/layers/ipc/CompositorChild.h index 602d44bcbd61..e4d091caaa46 100644 --- a/gfx/layers/ipc/CompositorChild.h +++ b/gfx/layers/ipc/CompositorChild.h @@ -41,7 +41,7 @@ class CompositorChild MOZ_FINAL : public PCompositorChild NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorChild) public: - CompositorChild(ClientLayerManager *aLayerManager); + explicit CompositorChild(ClientLayerManager *aLayerManager); void Destroy(); diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 5bbaa2d1dd95..2dc7e73efe40 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -93,9 +93,9 @@ class CompositorParent : public PCompositorParent, NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent) public: - CompositorParent(nsIWidget* aWidget, - bool aUseExternalSurfaceSize = false, - int aSurfaceWidth = -1, int aSurfaceHeight = -1); + explicit CompositorParent(nsIWidget* aWidget, + bool aUseExternalSurfaceSize = false, + int aSurfaceWidth = -1, int aSurfaceHeight = -1); // IToplevelProtocol::CloneToplevel() virtual IToplevelProtocol* diff --git a/gfx/layers/ipc/FenceUtils.h b/gfx/layers/ipc/FenceUtils.h index 63f58436ea58..82c2498aaf54 100644 --- a/gfx/layers/ipc/FenceUtils.h +++ b/gfx/layers/ipc/FenceUtils.h @@ -23,14 +23,14 @@ struct FenceHandleFromChild; struct FenceHandle { FenceHandle() {} - FenceHandle(const FenceHandleFromChild& aFenceHandle) {} + explicit FenceHandle(const FenceHandleFromChild& aFenceHandle) {} bool operator==(const FenceHandle&) const { return false; } bool IsValid() const { return false; } }; struct FenceHandleFromChild { FenceHandleFromChild() {} - FenceHandleFromChild(const FenceHandle& aFence) {} + explicit FenceHandleFromChild(const FenceHandle& aFence) {} bool operator==(const FenceHandle&) const { return false; } bool operator==(const FenceHandleFromChild&) const { return false; } bool IsValid() const { return false; } diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index a2172c537dba..85cc57696768 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -101,7 +101,7 @@ struct CompositableTransaction }; struct AutoEndTransaction { - AutoEndTransaction(CompositableTransaction* aTxn) : mTxn(aTxn) {} + explicit AutoEndTransaction(CompositableTransaction* aTxn) : mTxn(aTxn) {} ~AutoEndTransaction() { mTxn->End(); } CompositableTransaction* mTxn; }; @@ -464,7 +464,7 @@ ImageBridgeChild::BeginTransaction() class MOZ_STACK_CLASS AutoRemoveTextures { public: - AutoRemoveTextures(ImageBridgeChild* aImageBridge) + explicit AutoRemoveTextures(ImageBridgeChild* aImageBridge) : mImageBridge(aImageBridge) {} ~AutoRemoveTextures() diff --git a/gfx/layers/ipc/ShadowLayerChild.h b/gfx/layers/ipc/ShadowLayerChild.h index 71b36931ed57..ea7317a08d4e 100644 --- a/gfx/layers/ipc/ShadowLayerChild.h +++ b/gfx/layers/ipc/ShadowLayerChild.h @@ -20,7 +20,7 @@ class ShadowableLayer; class ShadowLayerChild : public PLayerChild { public: - ShadowLayerChild(ShadowableLayer* aLayer); + explicit ShadowLayerChild(ShadowableLayer* aLayer); virtual ~ShadowLayerChild(); ShadowableLayer* layer() const { return mLayer; } diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index c9a15a4287cc..166660f6eba8 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -154,7 +154,7 @@ private: Transaction& operator=(const Transaction&); }; struct AutoTxnEnd { - AutoTxnEnd(Transaction* aTxn) : mTxn(aTxn) {} + explicit AutoTxnEnd(Transaction* aTxn) : mTxn(aTxn) {} ~AutoTxnEnd() { mTxn->End(); } Transaction* mTxn; }; diff --git a/gfx/layers/ipc/SharedBufferManagerParent.cpp b/gfx/layers/ipc/SharedBufferManagerParent.cpp index d1a3e022be93..69c2e1a9a32b 100644 --- a/gfx/layers/ipc/SharedBufferManagerParent.cpp +++ b/gfx/layers/ipc/SharedBufferManagerParent.cpp @@ -108,7 +108,7 @@ void InitGralloc() { class DeleteSharedBufferManagerParentTask : public Task { public: - DeleteSharedBufferManagerParentTask(UniquePtr aSharedBufferManager) + explicit DeleteSharedBufferManagerParentTask(UniquePtr aSharedBufferManager) : mSharedBufferManager(Move(aSharedBufferManager)) { } virtual void Run() MOZ_OVERRIDE {} diff --git a/gfx/layers/ipc/SharedPlanarYCbCrImage.h b/gfx/layers/ipc/SharedPlanarYCbCrImage.h index 23f03a3a4147..483e40c1c586 100644 --- a/gfx/layers/ipc/SharedPlanarYCbCrImage.h +++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.h @@ -28,7 +28,7 @@ class SharedPlanarYCbCrImage : public PlanarYCbCrImage , public ISharedImage { public: - SharedPlanarYCbCrImage(ImageClient* aCompositable); + explicit SharedPlanarYCbCrImage(ImageClient* aCompositable); protected: ~SharedPlanarYCbCrImage(); diff --git a/gfx/layers/ipc/SharedRGBImage.h b/gfx/layers/ipc/SharedRGBImage.h index 69a919389220..e9aee420d375 100644 --- a/gfx/layers/ipc/SharedRGBImage.h +++ b/gfx/layers/ipc/SharedRGBImage.h @@ -40,7 +40,7 @@ class SharedRGBImage : public Image , public ISharedImage { public: - SharedRGBImage(ImageClient* aCompositable); + explicit SharedRGBImage(ImageClient* aCompositable); protected: ~SharedRGBImage(); diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 648e79c45d26..a68a3f291fb3 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -474,8 +474,8 @@ DecomposeIntoNoRepeatRects(const Rect& aRect, // If we are dealing with wrapping br.x and br.y are greater than 1.0 so // wrap them here as well. - br = Point(xwrap ? WrapTexCoord(br.x) : br.x, - ywrap ? WrapTexCoord(br.y) : br.y); + br = Point(xwrap ? WrapTexCoord(br.x) : br.x.value, + ywrap ? WrapTexCoord(br.y) : br.y.value); // If we wrap around along the x axis, we will draw first from // tl.x .. 1.0 and then from 0.0 .. br.x (which we just wrapped above). @@ -759,8 +759,7 @@ CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion, // UI for its dynamic toolbar. IntPoint origin; if (!mTarget) { - origin.x = -mRenderOffset.x; - origin.y = -mRenderOffset.y; + origin = -TruncatedToInt(mRenderOffset.ToUnknownPoint()); } mCurrentRenderTarget = diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 4e959c06fa67..d858fa004533 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -85,7 +85,7 @@ public: class PerUnitTexturePoolOGL : public CompositorTexturePoolOGL { public: - PerUnitTexturePoolOGL(gl::GLContext* aGL) + explicit PerUnitTexturePoolOGL(gl::GLContext* aGL) : mTextureTarget(0) // zero is never a valid texture target , mGL(aGL) {} @@ -124,7 +124,7 @@ protected: class PerFrameTexturePoolOGL : public CompositorTexturePoolOGL { public: - PerFrameTexturePoolOGL(gl::GLContext* aGL) + explicit PerFrameTexturePoolOGL(gl::GLContext* aGL) : mTextureTarget(0) // zero is never a valid texture target , mGL(aGL) {} @@ -162,8 +162,8 @@ class CompositorOGL MOZ_FINAL : public Compositor std::map mPrograms; public: - CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth = -1, int aSurfaceHeight = -1, - bool aUseExternalSurfaceSize = false); + explicit CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth = -1, int aSurfaceHeight = -1, + bool aUseExternalSurfaceSize = false); protected: virtual ~CompositorOGL(); diff --git a/gfx/layers/opengl/GLManager.cpp b/gfx/layers/opengl/GLManager.cpp index 803aa4f18f5b..a1bd66af69b6 100644 --- a/gfx/layers/opengl/GLManager.cpp +++ b/gfx/layers/opengl/GLManager.cpp @@ -23,7 +23,7 @@ namespace layers { class GLManagerCompositor : public GLManager { public: - GLManagerCompositor(CompositorOGL* aCompositor) + explicit GLManagerCompositor(CompositorOGL* aCompositor) : mImpl(aCompositor) {} diff --git a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h index db838bd491c4..b7353464337a 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h +++ b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h @@ -16,7 +16,7 @@ namespace layers { class MacIOSurfaceTextureClientOGL : public TextureClient { public: - MacIOSurfaceTextureClientOGL(TextureFlags aFlags); + explicit MacIOSurfaceTextureClientOGL(TextureFlags aFlags); virtual ~MacIOSurfaceTextureClientOGL(); diff --git a/gfx/layers/opengl/TextureClientOGL.h b/gfx/layers/opengl/TextureClientOGL.h index f506854fea2c..97436ef52745 100644 --- a/gfx/layers/opengl/TextureClientOGL.h +++ b/gfx/layers/opengl/TextureClientOGL.h @@ -32,7 +32,7 @@ class CompositableForwarder; class SharedTextureClientOGL : public TextureClient { public: - SharedTextureClientOGL(TextureFlags aFlags); + explicit SharedTextureClientOGL(TextureFlags aFlags); ~SharedTextureClientOGL(); diff --git a/gfx/layers/opengl/TextureHostOGL.h b/gfx/layers/opengl/TextureHostOGL.h index b9398ee77727..afaaab398454 100644 --- a/gfx/layers/opengl/TextureHostOGL.h +++ b/gfx/layers/opengl/TextureHostOGL.h @@ -212,8 +212,8 @@ class TextureImageTextureSourceOGL : public DataTextureSource , public BigImageIterator { public: - TextureImageTextureSourceOGL(gl::GLContext* aGL, - TextureFlags aFlags = TextureFlags::DEFAULT) + explicit TextureImageTextureSourceOGL(gl::GLContext* aGL, + TextureFlags aFlags = TextureFlags::DEFAULT) : mGL(aGL) , mFlags(aFlags) , mIterating(false) diff --git a/gfx/src/nsFont.cpp b/gfx/src/nsFont.cpp index 1b0819f6947e..a51d9d7e37fe 100644 --- a/gfx/src/nsFont.cpp +++ b/gfx/src/nsFont.cpp @@ -19,27 +19,25 @@ using namespace mozilla; nsFont::nsFont(const FontFamilyList& aFontlist, uint8_t aStyle, - uint8_t aVariant, uint16_t aWeight, int16_t aStretch, + uint16_t aWeight, int16_t aStretch, uint8_t aDecoration, nscoord aSize) : fontlist(aFontlist) { Init(); style = aStyle; - variant = aVariant; weight = aWeight; stretch = aStretch; decorations = aDecoration; size = aSize; } -nsFont::nsFont(FontFamilyType aGenericType, uint8_t aStyle, uint8_t aVariant, +nsFont::nsFont(FontFamilyType aGenericType, uint8_t aStyle, uint16_t aWeight, int16_t aStretch, uint8_t aDecoration, nscoord aSize) : fontlist(aGenericType) { Init(); style = aStyle; - variant = aVariant; weight = aWeight; stretch = aStretch; decorations = aDecoration; @@ -68,7 +66,6 @@ nsFont::nsFont(const nsFont& aOther) { style = aOther.style; systemFont = aOther.systemFont; - variant = aOther.variant; weight = aOther.weight; stretch = aOther.stretch; decorations = aOther.decorations; @@ -110,7 +107,6 @@ bool nsFont::BaseEquals(const nsFont& aOther) const (synthesis == aOther.synthesis) && (fontFeatureSettings == aOther.fontFeatureSettings) && (languageOverride == aOther.languageOverride) && - (variant == aOther.variant) && (variantAlternates == aOther.variantAlternates) && (variantCaps == aOther.variantCaps) && (variantEastAsian == aOther.variantEastAsian) && @@ -139,7 +135,6 @@ nsFont& nsFont::operator=(const nsFont& aOther) fontlist = aOther.fontlist; style = aOther.style; systemFont = aOther.systemFont; - variant = aOther.variant; weight = aOther.weight; stretch = aOther.stretch; decorations = aOther.decorations; @@ -274,14 +269,7 @@ void nsFont::AddFontFeaturesToStyle(gfxFontStyle *aStyle) const aStyle->featureValueLookup = featureValueLookup; // -- caps - // passed into gfxFontStyle to deal with appropriate fallback. - // for now, font-variant setting overrides font-variant-caps - // when font-variant becomes a shorthand, this will be removed - if (variant == NS_FONT_VARIANT_SMALL_CAPS) { - aStyle->variantCaps = NS_FONT_VARIANT_CAPS_SMALLCAPS; - } else { - aStyle->variantCaps = variantCaps; - } + aStyle->variantCaps = variantCaps; // -- east-asian if (variantEastAsian) { diff --git a/gfx/src/nsFont.h b/gfx/src/nsFont.h index 8efece82fd07..fc076365f8cc 100644 --- a/gfx/src/nsFont.h +++ b/gfx/src/nsFont.h @@ -52,11 +52,7 @@ struct NS_GFX nsFont { // the name is the same as a CSS generic font family. bool systemFont; - // The variant of the font (normal, small-caps) - uint8_t variant; - // Variant subproperties - // (currently -moz- versions, will replace variant above eventually) uint8_t variantCaps; uint8_t variantNumeric; uint8_t variantPosition; @@ -116,11 +112,11 @@ struct NS_GFX nsFont { // initialize the font with a fontlist nsFont(const mozilla::FontFamilyList& aFontlist, uint8_t aStyle, - uint8_t aVariant, uint16_t aWeight, int16_t aStretch, + uint16_t aWeight, int16_t aStretch, uint8_t aDecoration, nscoord aSize); // initialize the font with a single generic - nsFont(mozilla::FontFamilyType aGenericType, uint8_t aStyle, uint8_t aVariant, + nsFont(mozilla::FontFamilyType aGenericType, uint8_t aStyle, uint16_t aWeight, int16_t aStretch, uint8_t aDecoration, nscoord aSize); diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 58e5f78825ce..4762bede2712 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -30,14 +30,6 @@ using ::testing::InSequence; class Task; -class APZCTreeManagerTester : public ::testing::Test { -protected: - virtual void SetUp() { - gfxPrefs::GetSingleton(); - AsyncPanZoomController::SetThreadAssertionsEnabled(false); - } -}; - template class ScopedGfxPref { public: @@ -152,6 +144,16 @@ public: ReentrantMonitorAutoEnter lock(mMonitor); EXPECT_EQ(NOTHING, mState); } + + bool SampleContentTransformForFrame(const TimeStamp& aSampleTime, + ViewTransform* aOutTransform, + ScreenPoint& aScrollOffset, + ViewTransform* aOutOverscrollTransform = nullptr) { + bool ret = AdvanceAnimations(aSampleTime); + AsyncPanZoomController::SampleContentTransformForFrame( + aOutTransform, aScrollOffset, aOutOverscrollTransform); + return ret; + } }; class TestAPZCTreeManager : public APZCTreeManager { @@ -721,39 +723,39 @@ TEST_F(APZCBasicTester, ComplexTransform) { apzc->SetFrameMetrics(metrics); apzc->NotifyLayersUpdated(metrics, true); apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut); - EXPECT_EQ(ViewTransform(LayerPoint(), ParentLayerToScreenScale(2)), viewTransformOut); + EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(2), ScreenPoint()), viewTransformOut); EXPECT_EQ(ScreenPoint(60, 60), pointOut); childApzc->SetFrameMetrics(childMetrics); childApzc->NotifyLayersUpdated(childMetrics, true); childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut); - EXPECT_EQ(ViewTransform(LayerPoint(), ParentLayerToScreenScale(2)), viewTransformOut); + EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(2), ScreenPoint()), viewTransformOut); EXPECT_EQ(ScreenPoint(60, 60), pointOut); // do an async scroll by 5 pixels and check the transform metrics.ScrollBy(CSSPoint(5, 0)); apzc->SetFrameMetrics(metrics); apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut); - EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(2)), viewTransformOut); + EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(2), ScreenPoint(-30, 0)), viewTransformOut); EXPECT_EQ(ScreenPoint(90, 60), pointOut); childMetrics.ScrollBy(CSSPoint(5, 0)); childApzc->SetFrameMetrics(childMetrics); childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut); - EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(2)), viewTransformOut); + EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(2), ScreenPoint(-30, 0)), viewTransformOut); EXPECT_EQ(ScreenPoint(90, 60), pointOut); // do an async zoom of 1.5x and check the transform metrics.ZoomBy(1.5f); apzc->SetFrameMetrics(metrics); apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut); - EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(3)), viewTransformOut); + EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(3), ScreenPoint(-45, 0)), viewTransformOut); EXPECT_EQ(ScreenPoint(135, 90), pointOut); childMetrics.ZoomBy(1.5f); childApzc->SetFrameMetrics(childMetrics); childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut); - EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(3)), viewTransformOut); + EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(3), ScreenPoint(-45, 0)), viewTransformOut); EXPECT_EQ(ScreenPoint(135, 90), pointOut); } @@ -1000,92 +1002,6 @@ TEST_F(APZCFlingStopTester, FlingStopPreventDefault) { DoFlingStopWithSlowListener(true); } -TEST_F(APZCBasicTester, OverScrollPanning) { - SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true); - - // Pan sufficiently to hit overscroll behavior - int time = 0; - int touchStart = 500; - int touchEnd = 10; - ApzcPan(apzc, time, touchStart, touchEnd); - EXPECT_TRUE(apzc->IsOverscrolled()); - - // Note that in the calls to SampleContentTransformForFrame below, the time - // increment used is sufficiently large for the animation to have completed. However, - // any single call to SampleContentTransformForFrame will not finish an animation - // *and* also proceed through the following animation, if there is one. - // Therefore the minimum number of calls to go from an overscroll-inducing pan - // to a reset state is 3; these are documented further below. - - ScreenPoint pointOut; - ViewTransform viewTransformOut; - - // This sample will run to the end of the non-overscrolling fling animation - // and will schedule the overscrolling fling animation. - apzc->SampleContentTransformForFrame(testStartTime + TimeDuration::FromMilliseconds(10000), &viewTransformOut, pointOut); - EXPECT_EQ(ScreenPoint(0, 90), pointOut); - EXPECT_TRUE(apzc->IsOverscrolled()); - - // This sample will run to the end of the overscrolling fling animation and - // will schedule the snapback animation. - apzc->SampleContentTransformForFrame(testStartTime + TimeDuration::FromMilliseconds(20000), &viewTransformOut, pointOut); - EXPECT_EQ(ScreenPoint(0, 90), pointOut); - EXPECT_TRUE(apzc->IsOverscrolled()); - - // This sample will run to the end of the snapback animation and reset the state. - apzc->SampleContentTransformForFrame(testStartTime + TimeDuration::FromMilliseconds(30000), &viewTransformOut, pointOut); - EXPECT_EQ(ScreenPoint(0, 90), pointOut); - EXPECT_FALSE(apzc->IsOverscrolled()); - - apzc->AssertStateIsReset(); -} - -TEST_F(APZCBasicTester, OverScrollAbort) { - SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true); - - // Pan sufficiently to hit overscroll behavior - int time = 0; - int touchStart = 500; - int touchEnd = 10; - ApzcPan(apzc, time, touchStart, touchEnd); - EXPECT_TRUE(apzc->IsOverscrolled()); - - ScreenPoint pointOut; - ViewTransform viewTransformOut; - - // This sample call will run to the end of the non-overscrolling fling animation - // and will schedule the overscrolling fling animation (see comment in OverScrollPanning - // above for more explanation). - apzc->SampleContentTransformForFrame(testStartTime + TimeDuration::FromMilliseconds(10000), &viewTransformOut, pointOut); - EXPECT_TRUE(apzc->IsOverscrolled()); - - // At this point, we have an active overscrolling fling animation. - // Check that cancelling the animation clears the overscroll. - apzc->CancelAnimation(); - EXPECT_FALSE(apzc->IsOverscrolled()); - apzc->AssertStateIsReset(); -} - -TEST_F(APZCBasicTester, OverScrollPanningAbort) { - SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true); - - // Pan sufficiently to hit overscroll behaviour. Keep the finger down so - // the pan does not end. - int time = 0; - int touchStart = 500; - int touchEnd = 10; - ApzcPan(apzc, time, touchStart, touchEnd, - true); // keep finger down - EXPECT_TRUE(apzc->IsOverscrolled()); - - // Check that calling CancelAnimation() while the user is still panning - // (and thus no fling or snap-back animation has had a chance to start) - // clears the overscroll. - apzc->CancelAnimation(); - EXPECT_FALSE(apzc->IsOverscrolled()); - apzc->AssertStateIsReset(); -} - TEST_F(APZCGestureDetectorTester, ShortPress) { MakeApzcUnzoomable(); @@ -1399,92 +1315,139 @@ TEST_F(APZCGestureDetectorTester, DoubleTapPreventDefaultBoth) { apzc->AssertStateIsReset(); } -// Layer tree for HitTesting1 -static already_AddRefed -CreateTestLayerTree1(nsRefPtr& aLayerManager, nsTArray >& aLayers) { - const char* layerTreeSyntax = "c(ttcc)"; - // LayerID 0 1234 - nsIntRegion layerVisibleRegion[] = { - nsIntRegion(nsIntRect(0,0,100,100)), - nsIntRegion(nsIntRect(0,0,100,100)), - nsIntRegion(nsIntRect(10,10,20,20)), - nsIntRegion(nsIntRect(10,10,20,20)), - nsIntRegion(nsIntRect(5,5,20,20)), - }; - Matrix4x4 transforms[] = { - Matrix4x4(), - Matrix4x4(), - Matrix4x4(), - Matrix4x4(), - Matrix4x4(), - }; - return CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, aLayerManager, aLayers); -} +class APZCTreeManagerTester : public ::testing::Test { +protected: + virtual void SetUp() { + gfxPrefs::GetSingleton(); + AsyncPanZoomController::SetThreadAssertionsEnabled(false); -// Layer Tree for HitTesting2 -static already_AddRefed -CreateTestLayerTree2(nsRefPtr& aLayerManager, nsTArray >& aLayers) { - const char* layerTreeSyntax = "c(cc(c))"; - // LayerID 0 12 3 - nsIntRegion layerVisibleRegion[] = { - nsIntRegion(nsIntRect(0,0,100,100)), - nsIntRegion(nsIntRect(10,10,40,40)), - nsIntRegion(nsIntRect(10,60,40,40)), - nsIntRegion(nsIntRect(10,60,40,40)), - }; - Matrix4x4 transforms[] = { - Matrix4x4(), - Matrix4x4(), - Matrix4x4(), - Matrix4x4(), - }; - return CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, aLayerManager, aLayers); -} + TimeStamp testStartTime = TimeStamp::Now(); + AsyncPanZoomController::SetFrameTime(testStartTime); -static void -SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId, - // The scrollable rect is only used in HitTesting2, - // HitTesting1 doesn't care about it. - CSSRect aScrollableRect = CSSRect(-1, -1, -1, -1)) -{ - FrameMetrics metrics; - metrics.SetScrollId(aScrollId); - nsIntRect layerBound = aLayer->GetVisibleRegion().GetBounds(); - metrics.mCompositionBounds = ParentLayerRect(layerBound.x, layerBound.y, - layerBound.width, layerBound.height); - metrics.mScrollableRect = aScrollableRect; - metrics.SetScrollOffset(CSSPoint(0, 0)); - aLayer->SetFrameMetrics(metrics); -} - -static already_AddRefed -GetTargetAPZC(APZCTreeManager* manager, const ScreenPoint& aPoint, - Matrix4x4& aTransformToApzcOut, Matrix4x4& aTransformToGeckoOut) -{ - nsRefPtr hit = manager->GetTargetAPZC(aPoint, nullptr); - if (hit) { - manager->GetInputTransforms(hit.get(), aTransformToApzcOut, aTransformToGeckoOut); + mcc = new NiceMock(); + manager = new TestAPZCTreeManager(); } - return hit.forget(); -} -// A simple hit testing test that doesn't involve any transforms on layers. -TEST_F(APZCTreeManagerTester, HitTesting1) { + virtual void TearDown() { + manager->ClearTree(); + } + + TimeStamp testStartTime; + nsRefPtr mcc; + nsTArray > layers; nsRefPtr lm; - nsRefPtr root = CreateTestLayerTree1(lm, layers); + nsRefPtr root; - TimeStamp testStartTime = TimeStamp::Now(); - AsyncPanZoomController::SetFrameTime(testStartTime); - nsRefPtr mcc = new NiceMock(); - ScopedLayerTreeRegistration controller(0, root, mcc); + nsRefPtr manager; - nsRefPtr manager = new TestAPZCTreeManager(); +protected: + static void SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId, + // The scrollable rect is only used in HitTesting2, + // HitTesting1 doesn't care about it. + CSSRect aScrollableRect = CSSRect(-1, -1, -1, -1)) { + FrameMetrics metrics; + metrics.SetScrollId(aScrollId); + nsIntRect layerBound = aLayer->GetVisibleRegion().GetBounds(); + metrics.mCompositionBounds = ParentLayerRect(layerBound.x, layerBound.y, + layerBound.width, layerBound.height); + metrics.mScrollableRect = aScrollableRect; + metrics.SetScrollOffset(CSSPoint(0, 0)); + aLayer->SetFrameMetrics(metrics); + } + + void CreateSimpleMultiLayerTree() { + const char* layerTreeSyntax = "c(tt)"; + // LayerID 0 12 + nsIntRegion layerVisibleRegion[] = { + nsIntRegion(nsIntRect(0,0,100,100)), + nsIntRegion(nsIntRect(0,0,100,50)), + nsIntRegion(nsIntRect(0,50,100,50)), + }; + root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers); + } +}; + +class APZHitTestingTester : public APZCTreeManagerTester { +protected: Matrix4x4 transformToApzc; Matrix4x4 transformToGecko; + already_AddRefed GetTargetAPZC(const ScreenPoint& aPoint) { + nsRefPtr hit = manager->GetTargetAPZC(aPoint, nullptr); + if (hit) { + manager->GetInputTransforms(hit.get(), transformToApzc, transformToGecko); + } + return hit.forget(); + } + +protected: + void CreateHitTesting1LayerTree() { + const char* layerTreeSyntax = "c(ttcc)"; + // LayerID 0 1234 + nsIntRegion layerVisibleRegion[] = { + nsIntRegion(nsIntRect(0,0,100,100)), + nsIntRegion(nsIntRect(0,0,100,100)), + nsIntRegion(nsIntRect(10,10,20,20)), + nsIntRegion(nsIntRect(10,10,20,20)), + nsIntRegion(nsIntRect(5,5,20,20)), + }; + root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers); + } + + void CreateHitTesting2LayerTree() { + const char* layerTreeSyntax = "c(cc(c))"; + // LayerID 0 12 3 + nsIntRegion layerVisibleRegion[] = { + nsIntRegion(nsIntRect(0,0,100,100)), + nsIntRegion(nsIntRect(10,10,40,40)), + nsIntRegion(nsIntRect(10,60,40,40)), + nsIntRegion(nsIntRect(10,60,40,40)), + }; + Matrix4x4 transforms[] = { + Matrix4x4(), + Matrix4x4(), + Matrix4x4().Scale(2, 1, 1), + Matrix4x4(), + }; + root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, lm, layers); + + SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200)); + SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80)); + SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 80, 80)); + } + + void CreateComplexMultiLayerTree() { + const char* layerTreeSyntax = "c(tc(t)tc(c(t)t))"; + // LayerID 0 12 3 45 6 7 8 + nsIntRegion layerVisibleRegion[] = { + nsIntRegion(nsIntRect(0,0,300,400)), // root(0) + nsIntRegion(nsIntRect(0,0,100,100)), // thebes(1) in top-left + nsIntRegion(nsIntRect(50,50,200,300)), // container(2) centered in root(0) + nsIntRegion(nsIntRect(50,50,200,300)), // thebes(3) fully occupying parent container(2) + nsIntRegion(nsIntRect(0,200,100,100)), // thebes(4) in bottom-left + nsIntRegion(nsIntRect(200,0,100,400)), // container(5) along the right 100px of root(0) + nsIntRegion(nsIntRect(200,0,100,200)), // container(6) taking up the top half of parent container(5) + nsIntRegion(nsIntRect(200,0,100,200)), // thebes(7) fully occupying parent container(6) + nsIntRegion(nsIntRect(200,200,100,200)), // thebes(8) in bottom-right + }; + root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, nullptr, lm, layers); + SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID); + SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID); + SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1); + SetScrollableFrameMetrics(layers[6], FrameMetrics::START_SCROLL_ID + 1); + SetScrollableFrameMetrics(layers[7], FrameMetrics::START_SCROLL_ID + 2); + SetScrollableFrameMetrics(layers[8], FrameMetrics::START_SCROLL_ID + 3); + } +}; + +// A simple hit testing test that doesn't involve any transforms on layers. +TEST_F(APZHitTestingTester, HitTesting1) { + CreateHitTesting1LayerTree(); + ScopedLayerTreeRegistration registration(0, root, mcc); + // No APZC attached so hit testing will return no APZC at (20,20) - nsRefPtr hit = GetTargetAPZC(manager, ScreenPoint(20, 20), transformToApzc, transformToGecko); + nsRefPtr hit = GetTargetAPZC(ScreenPoint(20, 20)); AsyncPanZoomController* nullAPZC = nullptr; EXPECT_EQ(nullAPZC, hit.get()); EXPECT_EQ(Matrix4x4(), transformToApzc); @@ -1495,7 +1458,7 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { // Now we have a root APZC that will match the page SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID); manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, paintSequenceNumber++); - hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(15, 15)); EXPECT_EQ(root->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15)); @@ -1505,7 +1468,7 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1); manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, paintSequenceNumber++); EXPECT_NE(root->GetAsyncPanZoomController(), layers[3]->GetAsyncPanZoomController()); - hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(25, 25)); EXPECT_EQ(layers[3]->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(25, 25) EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25)); @@ -1513,63 +1476,40 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { // At this point, layers[4] obscures layers[3] at the point (15, 15) so // hitting there should hit the root APZC - hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(15, 15)); EXPECT_EQ(root->GetAsyncPanZoomController(), hit.get()); // Now test hit testing when we have two scrollable layers SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 2); manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, paintSequenceNumber++); - hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(15, 15)); EXPECT_EQ(layers[4]->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15)); EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15)); // Hit test ouside the reach of layer[3,4] but inside root - hit = GetTargetAPZC(manager, ScreenPoint(90, 90), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(90, 90)); EXPECT_EQ(root->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(90, 90) EXPECT_EQ(Point(90, 90), transformToApzc * Point(90, 90)); EXPECT_EQ(Point(90, 90), transformToGecko * Point(90, 90)); // Hit test ouside the reach of any layer - hit = GetTargetAPZC(manager, ScreenPoint(1000, 10), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(1000, 10)); EXPECT_EQ(nullAPZC, hit.get()); EXPECT_EQ(Matrix4x4(), transformToApzc); EXPECT_EQ(Matrix4x4(), transformToGecko); - hit = GetTargetAPZC(manager, ScreenPoint(-1000, 10), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(-1000, 10)); EXPECT_EQ(nullAPZC, hit.get()); EXPECT_EQ(Matrix4x4(), transformToApzc); EXPECT_EQ(Matrix4x4(), transformToGecko); - - manager->ClearTree(); } // A more involved hit testing test that involves css and async transforms. -TEST_F(APZCTreeManagerTester, HitTesting2) { - nsTArray > layers; - nsRefPtr lm; - nsRefPtr root = CreateTestLayerTree2(lm, layers); - - TimeStamp testStartTime = TimeStamp::Now(); - AsyncPanZoomController::SetFrameTime(testStartTime); - nsRefPtr mcc = new NiceMock(); - ScopedLayerTreeRegistration controller(0, root, mcc); - - nsRefPtr manager = new TestAPZCTreeManager(); - nsRefPtr hit; - Matrix4x4 transformToApzc; - Matrix4x4 transformToGecko; - - // Set a CSS transform on one of the layers. - Matrix4x4 transform; - transform = transform * Matrix4x4().Scale(2, 1, 1); - layers[2]->SetBaseTransform(transform); - - // Make some other layers scrollable. - SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200)); - SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80)); - SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 80, 80)); +TEST_F(APZHitTestingTester, HitTesting2) { + CreateHitTesting2LayerTree(); + ScopedLayerTreeRegistration registration(0, root, mcc); manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, 0); @@ -1584,7 +1524,7 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { AsyncPanZoomController* apzc3 = layers[3]->GetAsyncPanZoomController(); // Hit an area that's clearly on the root layer but not any of the child layers. - hit = GetTargetAPZC(manager, ScreenPoint(75, 25), transformToApzc, transformToGecko); + nsRefPtr hit = GetTargetAPZC(ScreenPoint(75, 25)); EXPECT_EQ(apzcroot, hit.get()); EXPECT_EQ(Point(75, 25), transformToApzc * Point(75, 25)); EXPECT_EQ(Point(75, 25), transformToGecko * Point(75, 25)); @@ -1596,19 +1536,19 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { // scale-only transform that we set on layers[2] would be invalid because // it would place the layer into overscroll, as its composition bounds // start at x=10 but its content at x=20). - hit = GetTargetAPZC(manager, ScreenPoint(15, 75), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(15, 75)); EXPECT_EQ(apzcroot, hit.get()); EXPECT_EQ(Point(15, 75), transformToApzc * Point(15, 75)); EXPECT_EQ(Point(15, 75), transformToGecko * Point(15, 75)); // Hit an area on layers[1]. - hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(25, 25)); EXPECT_EQ(apzc1, hit.get()); EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25)); EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25)); // Hit an area on layers[3]. - hit = GetTargetAPZC(manager, ScreenPoint(25, 75), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(25, 75)); EXPECT_EQ(apzc3, hit.get()); // transformToApzc should unapply layers[2]'s transform EXPECT_EQ(Point(12.5, 75), transformToApzc * Point(25, 75)); @@ -1617,7 +1557,7 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { // Hit an area on layers[3] that would be on the root if layers[2] // weren't transformed. - hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(75, 75)); EXPECT_EQ(apzc3, hit.get()); // transformToApzc should unapply layers[2]'s transform EXPECT_EQ(Point(37.5, 75), transformToApzc * Point(75, 75)); @@ -1639,7 +1579,7 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { ApzcPanNoFling(apzcroot, time, 100, 50); // Hit where layers[3] used to be. It should now hit the root. - hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(75, 75)); EXPECT_EQ(apzcroot, hit.get()); // transformToApzc doesn't unapply the root's own async transform EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75)); @@ -1649,7 +1589,7 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { EXPECT_EQ(Point(75, 75), transformToGecko * Point(75, 75)); // Hit where layers[1] used to be and where layers[3] should now be. - hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(25, 25)); EXPECT_EQ(apzc3, hit.get()); // transformToApzc unapplies both layers[2]'s css transform and the root's // async transform @@ -1665,7 +1605,7 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { ApzcPanNoFling(apzcroot, time, 100, 50); // Hit where layers[3] used to be. It should now hit the root. - hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(75, 75)); EXPECT_EQ(apzcroot, hit.get()); // transformToApzc doesn't unapply the root's own async transform EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75)); @@ -1674,15 +1614,76 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { EXPECT_EQ(Point(75, 125), transformToGecko * Point(75, 75)); // Hit where layers[1] used to be. It should now hit the root. - hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); + hit = GetTargetAPZC(ScreenPoint(25, 25)); EXPECT_EQ(apzcroot, hit.get()); // transformToApzc doesn't unapply the root's own async transform EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25)); // transformToGecko unapplies the full async transform of -100 pixels, and then // reapplies the "D" transform of -50 leading to an overall adjustment of +50 EXPECT_EQ(Point(25, 75), transformToGecko * Point(25, 25)); +} - manager->ClearTree(); +TEST_F(APZCTreeManagerTester, ScrollableThebesLayers) { + CreateSimpleMultiLayerTree(); + ScopedLayerTreeRegistration registration(0, root, mcc); + + // both layers have the same scrollId + SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID); + SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, 0); + + AsyncPanZoomController* nullAPZC = nullptr; + // so they should have the same APZC + EXPECT_EQ(nullAPZC, layers[0]->GetAsyncPanZoomController()); + EXPECT_NE(nullAPZC, layers[1]->GetAsyncPanZoomController()); + EXPECT_NE(nullAPZC, layers[2]->GetAsyncPanZoomController()); + EXPECT_EQ(layers[1]->GetAsyncPanZoomController(), layers[2]->GetAsyncPanZoomController()); + + // Change the scrollId of layers[1], and verify the APZC changes + SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, 0); + EXPECT_NE(layers[1]->GetAsyncPanZoomController(), layers[2]->GetAsyncPanZoomController()); + + // Change the scrollId of layers[2] to match that of layers[1], ensure we get the same + // APZC for both again + SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 1); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, 0); + EXPECT_EQ(layers[1]->GetAsyncPanZoomController(), layers[2]->GetAsyncPanZoomController()); +} + +TEST_F(APZHitTestingTester, ComplexMultiLayerTree) { + CreateComplexMultiLayerTree(); + ScopedLayerTreeRegistration registration(0, root, mcc); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, 0); + + AsyncPanZoomController* nullAPZC = nullptr; + // Ensure all the scrollable layers have an APZC + EXPECT_EQ(nullAPZC, layers[0]->GetAsyncPanZoomController()); + EXPECT_NE(nullAPZC, layers[1]->GetAsyncPanZoomController()); + EXPECT_NE(nullAPZC, layers[2]->GetAsyncPanZoomController()); + EXPECT_EQ(nullAPZC, layers[3]->GetAsyncPanZoomController()); + EXPECT_NE(nullAPZC, layers[4]->GetAsyncPanZoomController()); + EXPECT_EQ(nullAPZC, layers[5]->GetAsyncPanZoomController()); + EXPECT_NE(nullAPZC, layers[6]->GetAsyncPanZoomController()); + EXPECT_NE(nullAPZC, layers[7]->GetAsyncPanZoomController()); + EXPECT_NE(nullAPZC, layers[8]->GetAsyncPanZoomController()); + // Ensure those that scroll together have the same APZCs + EXPECT_EQ(layers[1]->GetAsyncPanZoomController(), layers[2]->GetAsyncPanZoomController()); + EXPECT_EQ(layers[4]->GetAsyncPanZoomController(), layers[6]->GetAsyncPanZoomController()); + // Ensure those that don't scroll together have different APZCs + EXPECT_NE(layers[1]->GetAsyncPanZoomController(), layers[4]->GetAsyncPanZoomController()); + EXPECT_NE(layers[1]->GetAsyncPanZoomController(), layers[7]->GetAsyncPanZoomController()); + EXPECT_NE(layers[1]->GetAsyncPanZoomController(), layers[8]->GetAsyncPanZoomController()); + EXPECT_NE(layers[4]->GetAsyncPanZoomController(), layers[7]->GetAsyncPanZoomController()); + EXPECT_NE(layers[4]->GetAsyncPanZoomController(), layers[8]->GetAsyncPanZoomController()); + EXPECT_NE(layers[7]->GetAsyncPanZoomController(), layers[8]->GetAsyncPanZoomController()); + + nsRefPtr hit = GetTargetAPZC(ScreenPoint(25, 25)); + EXPECT_EQ(layers[1]->GetAsyncPanZoomController(), hit.get()); + hit = GetTargetAPZC(ScreenPoint(275, 375)); + EXPECT_EQ(layers[8]->GetAsyncPanZoomController(), hit.get()); + hit = GetTargetAPZC(ScreenPoint(250, 100)); + EXPECT_EQ(layers[7]->GetAsyncPanZoomController(), hit.get()); } class TaskRunMetrics { diff --git a/gfx/thebes/gfxPlatformMac.cpp b/gfx/thebes/gfxPlatformMac.cpp index 049012207067..8aead2a4bb25 100644 --- a/gfx/thebes/gfxPlatformMac.cpp +++ b/gfx/thebes/gfxPlatformMac.cpp @@ -303,11 +303,11 @@ gfxPlatformMac::GetCommonFallbackFonts(const uint32_t aCh, case 0x2a: case 0x2b: case 0x2e: + aFontList.AppendElement(kFontHiraginoKakuGothic); aFontList.AppendElement(kFontAppleSymbols); aFontList.AppendElement(kFontMenlo); aFontList.AppendElement(kFontSTIXGeneral); aFontList.AppendElement(kFontGeneva); - aFontList.AppendElement(kFontHiraginoKakuGothic); aFontList.AppendElement(kFontAppleColorEmoji); break; case 0x2c: diff --git a/image/src/imgFrame.cpp b/image/src/imgFrame.cpp index 662218f2b36f..b46b942f342c 100644 --- a/image/src/imgFrame.cpp +++ b/image/src/imgFrame.cpp @@ -181,6 +181,11 @@ nsresult imgFrame::Init(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, if (!mVBuf) { return NS_ERROR_OUT_OF_MEMORY; } + if (mVBuf->OnHeap()) { + int32_t stride = VolatileSurfaceStride(mSize, mFormat); + VolatileBufferPtr ptr(mVBuf); + memset(ptr, 0, stride * mSize.height); + } mImageSurface = CreateLockedSurface(mVBuf, mSize, mFormat); } diff --git a/js/public/Value.h b/js/public/Value.h index e0dd6c335b5f..d8ec20f38f79 100644 --- a/js/public/Value.h +++ b/js/public/Value.h @@ -1693,7 +1693,7 @@ class ValueOperations JS::Symbol *toSymbol() const { return value()->toSymbol(); } JSObject &toObject() const { return value()->toObject(); } JSObject *toObjectOrNull() const { return value()->toObjectOrNull(); } - void *toGCThing() const { return value()->toGCThing(); } + gc::Cell *toGCThing() const { return value()->toGCThing(); } uint64_t asRawBits() const { return value()->asRawBits(); } JSValueType extractNonDoubleType() const { return value()->extractNonDoubleType(); } diff --git a/js/src/builtin/Object.js b/js/src/builtin/Object.js index adafe0bf5358..d3ecc3dbb11d 100644 --- a/js/src/builtin/Object.js +++ b/js/src/builtin/Object.js @@ -14,8 +14,14 @@ function ObjectStaticAssign(target, firstSource) { // Step 4. var i = 1; do { - // Step 5.a-b. + // Step 5.a-b, plus an unspecified flourish to skip null/undefined, so + // any site depending on agreed-upon (but not-yet-drafted) semantics + // from TC39 meeting minutes will work. (Yes, implausibly, such a site + // exists. See bug 1054426.) var nextSource = arguments[i]; + if (nextSource === null || nextSource === undefined) + continue; + var from = ToObject(nextSource); // Step 5.c-d. @@ -58,8 +64,7 @@ function ObjectStaticAssign(target, firstSource) { // Step 5.k. if (pendingException !== MISSING) throw pendingException; - i++; - } while (i < arguments.length); + } while (++i < arguments.length); // Step 6. return to; diff --git a/js/src/doc/Debugger/Debugger-API.md b/js/src/doc/Debugger/Debugger-API.md index 84a581688a66..a9afe253e88a 100644 --- a/js/src/doc/Debugger/Debugger-API.md +++ b/js/src/doc/Debugger/Debugger-API.md @@ -84,6 +84,9 @@ full copy of its source code, and explain how the code entered the system, whether via a call to `eval`, a ` + + + + +
+ + + diff --git a/layout/reftests/font-features/font-variant.html b/layout/reftests/font-features/font-variant.html new file mode 100644 index 000000000000..bde0cd6c272d --- /dev/null +++ b/layout/reftests/font-features/font-variant.html @@ -0,0 +1,16 @@ + + + +font-variant shorthand test + + + + + + +
+ + + diff --git a/layout/reftests/font-features/fwid-spaces.html b/layout/reftests/font-features/fwid-spaces.html index b92ba33c7dbc..5715886d2585 100644 --- a/layout/reftests/font-features/fwid-spaces.html +++ b/layout/reftests/font-features/fwid-spaces.html @@ -12,7 +12,6 @@ body { #test, #test pre { font: 150% Hiragino Kaku Gothic ProN, Meiryo, sans-serif; - -moz-font-feature-settings: "fwid" on; -webkit-font-feature-settings: "fwid" on; font-feature-settings: "fwid" on; } diff --git a/layout/reftests/font-features/kerning-sanity-check-kern.html b/layout/reftests/font-features/kerning-sanity-check-kern.html index 503fe466d022..66225cd372fa 100644 --- a/layout/reftests/font-features/kerning-sanity-check-kern.html +++ b/layout/reftests/font-features/kerning-sanity-check-kern.html @@ -19,7 +19,6 @@ div#test, div#test pre { font-family: Arial, LinuxLibertine, sans-serif; font-size: 300%; line-height: 1.1em; - -moz-font-feature-settings: "kern" on; -webkit-font-feature-settings: "kern" on; font-feature-settings: "kern" on; } diff --git a/layout/reftests/font-features/kerning-sanity-check-nokern.html b/layout/reftests/font-features/kerning-sanity-check-nokern.html index 2d84c74540f2..1b49441f526e 100644 --- a/layout/reftests/font-features/kerning-sanity-check-nokern.html +++ b/layout/reftests/font-features/kerning-sanity-check-nokern.html @@ -19,7 +19,6 @@ div#test, div#test pre { font-family: Arial, LinuxLibertine, sans-serif; font-size: 300%; line-height: 1.1em; - -moz-font-feature-settings: "kern" off; -webkit-font-feature-settings: "kern" off; font-feature-settings: "kern" off; } diff --git a/layout/reftests/font-features/kerning-spaces-arial-kern.html b/layout/reftests/font-features/kerning-spaces-arial-kern.html index afc2963e1c9a..7b859073d8a3 100644 --- a/layout/reftests/font-features/kerning-spaces-arial-kern.html +++ b/layout/reftests/font-features/kerning-spaces-arial-kern.html @@ -14,7 +14,6 @@ div#test, div#test pre { font-family: Arial, sans-serif; font-size: 150%; line-height: 1.1em; - -moz-font-feature-settings: "kern" on; -webkit-font-feature-settings: "kern" on; font-feature-settings: "kern" on; } diff --git a/layout/reftests/font-features/kerning-spaces-arial-nokern.html b/layout/reftests/font-features/kerning-spaces-arial-nokern.html index b58e12db8511..d73007baccc5 100644 --- a/layout/reftests/font-features/kerning-spaces-arial-nokern.html +++ b/layout/reftests/font-features/kerning-spaces-arial-nokern.html @@ -14,7 +14,6 @@ div#test, div#test pre { font-family: Arial, sans-serif; font-size: 150%; line-height: 1.1em; - -moz-font-feature-settings: "kern" off; -webkit-font-feature-settings: "kern" off; font-feature-settings: "kern" off; } diff --git a/layout/reftests/font-features/kerning-spaces-tnr-kern.html b/layout/reftests/font-features/kerning-spaces-tnr-kern.html index 2bc22c3d8d7e..18dbc186189d 100644 --- a/layout/reftests/font-features/kerning-spaces-tnr-kern.html +++ b/layout/reftests/font-features/kerning-spaces-tnr-kern.html @@ -14,7 +14,6 @@ div#test, div#test pre { font-family: Times New Roman, sans-serif; font-size: 150%; line-height: 1.1em; - -moz-font-feature-settings: "kern" on; -webkit-font-feature-settings: "kern" on; font-feature-settings: "kern" on; } diff --git a/layout/reftests/font-features/kerning-spaces-tnr-nokern.html b/layout/reftests/font-features/kerning-spaces-tnr-nokern.html index b813fbea80b3..0e033454c01f 100644 --- a/layout/reftests/font-features/kerning-spaces-tnr-nokern.html +++ b/layout/reftests/font-features/kerning-spaces-tnr-nokern.html @@ -14,7 +14,6 @@ div#test, div#test pre { font-family: Times New Roman, sans-serif; font-size: 150%; line-height: 1.1em; - -moz-font-feature-settings: "kern" off; -webkit-font-feature-settings: "kern" off; font-feature-settings: "kern" off; } diff --git a/layout/reftests/font-features/reftest.list b/layout/reftests/font-features/reftest.list index d22675c8a6ca..048f56d0d662 100644 --- a/layout/reftests/font-features/reftest.list +++ b/layout/reftests/font-features/reftest.list @@ -27,22 +27,16 @@ HTTP(..) == font-features-turkish.html font-features-noliga.html HTTP(..) == font-features-hlig-2.html font-features-hlig.html HTTP(..) == font-features-hlig-4.html font-features-hlig.html HTTP(..) != font-features-hlig-5.html font-features-hlig.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-features-ligatures-none.html font-features-noliga.html +HTTP(..) == font-features-ligatures-none.html font-features-noliga.html # check that feature in style rule overrides @font-face skip-if(B2G) HTTP(..) == font-features-hlig-3.html font-features-noliga.html # bug 773482 -# make sure old syntax usage never interferes with new syntax usage -HTTP(..) == font-features-oldsyntax-1.html font-features-ref.html -HTTP(..) == font-features-oldsyntax-2.html font-features-ref.html -HTTP(..) == font-features-oldsyntax-3.html font-features-hlig.html -HTTP(..) == font-features-oldsyntax-4.html font-features-hlig.html - -# compare -moz-font-language-override rendering to lang-tagged rendering +# compare font-language-override rendering to lang-tagged rendering skip-if(B2G) HTTP(..) == font-features-turkish-override-1.html font-features-turkish.html # bug 773482 HTTP(..) == font-features-turkish-override-2.html font-features-turkish.html -# check use of -moz-font-language-override to override explicit lang tag +# check use of font-language-override to override explicit lang tag HTTP(..) == font-features-turkish-override-3.html font-features-ref.html HTTP(..) == font-features-turkish-override-4.html font-features-ref.html skip-if(B2G) HTTP(..) == font-features-turkish-override-5.html font-features-turkish.html # bug 773482 @@ -53,35 +47,35 @@ HTTP(..) == font-features-order-2.html font-features-noliga.html # check priority of feature settings vs. font-variant subproperty HTTP(..) == font-features-order-3.html font-features-noliga.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-features-order-4.html font-features-noliga.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-features-order-5.html font-features-hlig.html +HTTP(..) == font-features-order-4.html font-features-noliga.html +HTTP(..) == font-features-order-5.html font-features-hlig.html # check priority involving feature settings and font-variant-alternates -pref(layout.css.font-features.enabled,true) HTTP(..) == alternates-order.html alternates-order-ref.html +HTTP(..) == alternates-order.html alternates-order-ref.html # check that font-specific values line up with @font-face feature settings -pref(layout.css.font-features.enabled,true) HTTP(..) == annotations.html annotations-ref.html +HTTP(..) == annotations.html annotations-ref.html # font-variant subproperties # test for specific features being on and others off, based on prop values # (debug problems with font-variant-debug.html which displays all props) -pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-alternates.html font-variant-alternates-ref.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-caps.html font-variant-caps-ref.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-east-asian.html font-variant-east-asian-ref.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-ligatures.html font-variant-ligatures-ref.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-numeric.html font-variant-numeric-ref.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-position.html font-variant-position-ref.html +HTTP(..) == font-variant-alternates.html font-variant-alternates-ref.html +HTTP(..) == font-variant-caps.html font-variant-caps-ref.html +HTTP(..) == font-variant-east-asian.html font-variant-east-asian-ref.html +HTTP(..) == font-variant-ligatures.html font-variant-ligatures-ref.html +HTTP(..) == font-variant-numeric.html font-variant-numeric-ref.html +HTTP(..) == font-variant-position.html font-variant-position-ref.html # font-kerning -pref(layout.css.font-features.enabled,true) HTTP(..) != font-kerning-normal.html font-kerning-none.html -pref(layout.css.font-features.enabled,true) HTTP(..) != font-kerning-auto.html font-kerning-none.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-auto.html font-kerning-normal.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-normal.html font-kerning-kern.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-none.html font-kerning-nokern.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-1.html font-kerning-none.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-2.html font-kerning-normal.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-3.html font-kerning-none.html -pref(layout.css.font-features.enabled,true) HTTP(..) != font-kerning-table-none.html font-kerning-table-normal.html +HTTP(..) != font-kerning-normal.html font-kerning-none.html +HTTP(..) != font-kerning-auto.html font-kerning-none.html +HTTP(..) == font-kerning-auto.html font-kerning-normal.html +HTTP(..) == font-kerning-normal.html font-kerning-kern.html +HTTP(..) == font-kerning-none.html font-kerning-nokern.html +HTTP(..) == font-kerning-1.html font-kerning-none.html +HTTP(..) == font-kerning-2.html font-kerning-normal.html +HTTP(..) == font-kerning-3.html font-kerning-none.html +HTTP(..) != font-kerning-table-none.html font-kerning-table-normal.html # sanity check for kerning - with no spaces, kerning should occur HTTP(..) == kerning-sanity-check-kern.html kerning-sanity-check-default.html @@ -102,24 +96,24 @@ random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) random-if(/ # font-variant-caps fallback # -- sanity check - none of these should look like the default rendering -pref(layout.css.font-features.enabled,true) HTTP(..) != caps-fallback-smallcaps1.html caps-fallback-default.html -pref(layout.css.font-features.enabled,true) HTTP(..) != caps-fallback-smallcaps2.html caps-fallback-default.html -pref(layout.css.font-features.enabled,true) HTTP(..) != caps-fallback-petitecaps.html caps-fallback-default.html -pref(layout.css.font-features.enabled,true) HTTP(..) != caps-fallback-allsmallcaps.html caps-fallback-default.html -pref(layout.css.font-features.enabled,true) HTTP(..) != caps-fallback-allpetitecaps.html caps-fallback-default.html +HTTP(..) != caps-fallback-smallcaps1.html caps-fallback-default.html +HTTP(..) != caps-fallback-smallcaps2.html caps-fallback-default.html +HTTP(..) != caps-fallback-petitecaps.html caps-fallback-default.html +HTTP(..) != caps-fallback-allsmallcaps.html caps-fallback-default.html +HTTP(..) != caps-fallback-allpetitecaps.html caps-fallback-default.html # -- normal or fallback rendering -pref(layout.css.font-features.enabled,true) HTTP(..) == caps-fallback-smallcaps1.html caps-fallback-smcp.html -pref(layout.css.font-features.enabled,true) HTTP(..) == caps-fallback-smallcaps2.html caps-fallback-smcp.html -pref(layout.css.font-features.enabled,true) HTTP(..) == caps-fallback-petitecaps.html caps-fallback-smcp.html -pref(layout.css.font-features.enabled,true) HTTP(..) == caps-fallback-allsmallcaps.html caps-fallback-smcpc2sc.html -pref(layout.css.font-features.enabled,true) HTTP(..) == caps-fallback-allpetitecaps.html caps-fallback-smcpc2sc.html +HTTP(..) == caps-fallback-smallcaps1.html caps-fallback-smcp.html +HTTP(..) == caps-fallback-smallcaps2.html caps-fallback-smcp.html +HTTP(..) == caps-fallback-petitecaps.html caps-fallback-smcp.html +HTTP(..) == caps-fallback-allsmallcaps.html caps-fallback-smcpc2sc.html +HTTP(..) == caps-fallback-allpetitecaps.html caps-fallback-smcpc2sc.html # font-variant-position fallback -pref(layout.css.font-features.enabled,true) HTTP(..) == subsuper-fallback.html subsuper-fallback-ref.html -pref(layout.css.font-features.enabled,true) HTTP(..) != subsuper-fallback.html subsuper-fallback-notref1.html -pref(layout.css.font-features.enabled,true) HTTP(..) != subsuper-fallback.html subsuper-fallback-notref2.html -pref(layout.css.font-features.enabled,true) HTTP(..) != subsuper-fallback.html subsuper-fallback-notref3.html -pref(layout.css.font-features.enabled,true) HTTP(..) != subsuper-fallback-omega.html subsuper-fallback-omega-notref.html -pref(layout.css.font-features.enabled,true) HTTP(..) == subsuper-nofallback.html subsuper-nofallback-ref1.html -pref(layout.css.font-features.enabled,true) HTTP(..) == subsuper-nofallback.html subsuper-nofallback-ref2.html -pref(layout.css.font-features.enabled,true) HTTP(..) != subsuper-nofallback.html subsuper-nofallback-notref.html +HTTP(..) == subsuper-fallback.html subsuper-fallback-ref.html +HTTP(..) != subsuper-fallback.html subsuper-fallback-notref1.html +HTTP(..) != subsuper-fallback.html subsuper-fallback-notref2.html +HTTP(..) != subsuper-fallback.html subsuper-fallback-notref3.html +HTTP(..) != subsuper-fallback-omega.html subsuper-fallback-omega-notref.html +HTTP(..) == subsuper-nofallback.html subsuper-nofallback-ref1.html +HTTP(..) == subsuper-nofallback.html subsuper-nofallback-ref2.html +HTTP(..) != subsuper-nofallback.html subsuper-nofallback-notref.html diff --git a/layout/reftests/font-features/spacelookups-wordcache-ref.html b/layout/reftests/font-features/spacelookups-wordcache-ref.html index f7b1b9775220..cd6af0cf4354 100644 --- a/layout/reftests/font-features/spacelookups-wordcache-ref.html +++ b/layout/reftests/font-features/spacelookups-wordcache-ref.html @@ -54,13 +54,11 @@ p { margin: 0; line-height: 1.2; } p.kern { -webkit-font-feature-settings: "liga" on, "kern" on; - -moz-font-feature-settings: "liga" on, "kern" on; font-feature-settings: "liga" on, "kern" on; } p.nokern { -webkit-font-feature-settings: "liga" on, "kern" off; - -moz-font-feature-settings: "liga" on, "kern" off; font-feature-settings: "liga" on, "kern" off; } diff --git a/layout/reftests/font-features/spacelookups-wordcache.html b/layout/reftests/font-features/spacelookups-wordcache.html index 437696e4d1b7..a3bd642b260a 100644 --- a/layout/reftests/font-features/spacelookups-wordcache.html +++ b/layout/reftests/font-features/spacelookups-wordcache.html @@ -55,7 +55,6 @@ p { margin: 0; line-height: 1.2; } .dlig { -webkit-font-feature-settings: "dlig" on; - -moz-font-feature-settings: "dlig" on; font-feature-settings: "dlig" on; } diff --git a/layout/reftests/font-features/spacelookups.html b/layout/reftests/font-features/spacelookups.html index a3bf6b979b7d..ab22ac97995b 100644 --- a/layout/reftests/font-features/spacelookups.html +++ b/layout/reftests/font-features/spacelookups.html @@ -64,7 +64,6 @@ div { font-size: 400%; } .dlig { -webkit-font-feature-settings: "dlig" on; - -moz-font-feature-settings: "dlig" on; font-feature-settings: "dlig" on; } diff --git a/layout/reftests/font-features/subsuper-nofallback-ref1.html b/layout/reftests/font-features/subsuper-nofallback-ref1.html index e35760fe829c..2c015d026f44 100644 --- a/layout/reftests/font-features/subsuper-nofallback-ref1.html +++ b/layout/reftests/font-features/subsuper-nofallback-ref1.html @@ -22,12 +22,10 @@ p { } h4 { font-weight: normal } span.super { - -moz-font-feature-settings: "sups" on; -webkit-font-feature-settings: "sups" on; font-feature-settings: "sups" on; } span.sub { - -moz-font-feature-settings: "subs" on; -webkit-font-feature-settings: "subs" on; font-feature-settings: "subs" on; } diff --git a/layout/reftests/font-matching/reftest.list b/layout/reftests/font-matching/reftest.list index 5844cdf041da..e3271cfdfebb 100644 --- a/layout/reftests/font-matching/reftest.list +++ b/layout/reftests/font-matching/reftest.list @@ -91,5 +91,5 @@ random-if(!(cocoaWidget||winWidget)) == arial-arabic.html arial-arabic-ref.html != syntheticbold-rotated.html syntheticbold-rotated-ref.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-synthesis-1.html font-synthesis-1-ref.html -pref(layout.css.font-features.enabled,true) HTTP(..) == font-synthesis-2.html font-synthesis-2-ref.html +HTTP(..) == font-synthesis-1.html font-synthesis-1-ref.html +HTTP(..) == font-synthesis-2.html font-synthesis-2-ref.html diff --git a/layout/reftests/mathml/mathscript-1.html b/layout/reftests/mathml/mathscript-1.html index 7a6e2ae0a19c..7685fcc3037b 100644 --- a/layout/reftests/mathml/mathscript-1.html +++ b/layout/reftests/mathml/mathscript-1.html @@ -11,24 +11,24 @@
A
+ font-feature-settings: 'ssty' 1">A
A
+ font-feature-settings: 'ssty' 2">A - A - A - A + A + A + A

- + A A A diff --git a/layout/reftests/mathml/mathscript-2.html b/layout/reftests/mathml/mathscript-2.html index ed6ea014f13c..862be8599446 100644 --- a/layout/reftests/mathml/mathscript-2.html +++ b/layout/reftests/mathml/mathscript-2.html @@ -14,11 +14,11 @@

A
+ font-feature-settings: 'ssty' " id="div0">A - + A diff --git a/layout/reftests/mathml/ssty-1.html b/layout/reftests/mathml/ssty-1.html index 79a58a72bca3..bbeeed1253b8 100644 --- a/layout/reftests/mathml/ssty-1.html +++ b/layout/reftests/mathml/ssty-1.html @@ -280,7 +280,7 @@ A - A + A A @@ -288,7 +288,7 @@ A - A + A A @@ -296,12 +296,12 @@ A - A + A A A - A + A A A @@ -310,12 +310,12 @@ A - A + A A A - A + A A A diff --git a/layout/reftests/mathml/ssty-4-ref.html b/layout/reftests/mathml/ssty-4-ref.html index 3e25b44acf49..7d4b5dc5d83b 100644 --- a/layout/reftests/mathml/ssty-4-ref.html +++ b/layout/reftests/mathml/ssty-4-ref.html @@ -139,7 +139,7 @@

- + D diff --git a/layout/reftests/mathml/ssty-4.html b/layout/reftests/mathml/ssty-4.html index 4dce9a1caa84..5b2a662c0f6a 100644 --- a/layout/reftests/mathml/ssty-4.html +++ b/layout/reftests/mathml/ssty-4.html @@ -119,7 +119,7 @@

- + A @@ -176,7 +176,7 @@ "style", "font-family: 'sstyfont';") // setting an explicit ssty font feature document.getElementById("mstyle5").setAttribute( - "style" , "font-family: 'sstyfont'; -moz-font-feature-settings: 'ssty' 0") + "style" , "font-family: 'sstyfont'; font-feature-settings: 'ssty' 0") document.documentElement.removeAttribute("class"); } diff --git a/layout/reftests/text-transform/graphite-small-caps-1-ref.html b/layout/reftests/text-transform/graphite-small-caps-1-ref.html index f479b5edc91e..0d553460af42 100644 --- a/layout/reftests/text-transform/graphite-small-caps-1-ref.html +++ b/layout/reftests/text-transform/graphite-small-caps-1-ref.html @@ -12,7 +12,6 @@ body { font: 100px test; } div { - -moz-font-feature-settings: 'smcp' on; font-feature-settings: 'smcp' on; } diff --git a/layout/reftests/text-transform/opentype-small-caps-1-ref.html b/layout/reftests/text-transform/opentype-small-caps-1-ref.html index 466b4efecea4..ead0ecec888d 100644 --- a/layout/reftests/text-transform/opentype-small-caps-1-ref.html +++ b/layout/reftests/text-transform/opentype-small-caps-1-ref.html @@ -12,7 +12,6 @@ body { font: 100px test; } div { - -moz-font-feature-settings: 'smcp' on; font-feature-settings: 'smcp' on; } diff --git a/layout/reftests/text/auto-hyphenation-pl-1-ref.html b/layout/reftests/text/auto-hyphenation-pl-1-ref.html index 69bc8f70993e..0c571f148180 100644 --- a/layout/reftests/text/auto-hyphenation-pl-1-ref.html +++ b/layout/reftests/text/auto-hyphenation-pl-1-ref.html @@ -6,7 +6,6 @@ diff --git a/layout/reftests/text/auto-hyphenation-pl-1.html b/layout/reftests/text/auto-hyphenation-pl-1.html index ca6219e2435f..9d371f82d6de 100644 --- a/layout/reftests/text/auto-hyphenation-pl-1.html +++ b/layout/reftests/text/auto-hyphenation-pl-1.html @@ -6,7 +6,6 @@ diff --git a/layout/reftests/text/graphite-03b.html b/layout/reftests/text/graphite-03b.html index d3f8f853e2d0..c584612e242c 100644 --- a/layout/reftests/text/graphite-03b.html +++ b/layout/reftests/text/graphite-03b.html @@ -10,7 +10,6 @@ body { font: 34px padauk; - -moz-font-feature-settings: "kdot" on; font-feature-settings: "kdot" on; /* check that setting an optional graphite feature affects rendering: * this adds "dots" to the ends of a number of curved strokes diff --git a/layout/reftests/text/graphite-05-feat.html b/layout/reftests/text/graphite-05-feat.html index 83dc2d59b7df..f4082dde0815 100644 --- a/layout/reftests/text/graphite-05-feat.html +++ b/layout/reftests/text/graphite-05-feat.html @@ -10,7 +10,7 @@ body { margin: 20px; font: 100px test; - -moz-font-feature-settings: "TST1", "FTP2"; + font-feature-settings: "TST1", "FTP2"; } p { margin: 0; padding: 0; } diff --git a/layout/reftests/text/graphite-05-lang.html b/layout/reftests/text/graphite-05-lang.html index a02eb58a9652..c4a8cb0ddc7b 100644 --- a/layout/reftests/text/graphite-05-lang.html +++ b/layout/reftests/text/graphite-05-lang.html @@ -10,7 +10,7 @@ body { margin: 20px; font: 100px test; - -moz-font-feature-settings: "TST1"; + font-feature-settings: "TST1"; } p { margin: 0; padding: 0; } diff --git a/layout/reftests/text/graphite-05-multipass.html b/layout/reftests/text/graphite-05-multipass.html index 1667b2228e12..b3e2522cde7f 100644 --- a/layout/reftests/text/graphite-05-multipass.html +++ b/layout/reftests/text/graphite-05-multipass.html @@ -10,7 +10,7 @@ body { margin: 20px; font: 100px test; - -moz-font-feature-settings: "TST1"; + font-feature-settings: "TST1"; } p { margin: 0; padding: 0; } diff --git a/layout/reftests/text/graphite-05-ot-only.html b/layout/reftests/text/graphite-05-ot-only.html index d5f6d1879f3b..ae4d046cab2a 100644 --- a/layout/reftests/text/graphite-05-ot-only.html +++ b/layout/reftests/text/graphite-05-ot-only.html @@ -10,7 +10,7 @@ body { margin: 20px; font: 100px test; - -moz-font-feature-settings: "TST1"; + font-feature-settings: "TST1"; } p { margin: 0; padding: 0; } diff --git a/layout/reftests/text/graphite-05-simple.html b/layout/reftests/text/graphite-05-simple.html index 21a065c2c982..aa126ede851d 100644 --- a/layout/reftests/text/graphite-05-simple.html +++ b/layout/reftests/text/graphite-05-simple.html @@ -10,7 +10,7 @@ body { margin: 20px; font: 100px test; - -moz-font-feature-settings: "TST1"; + font-feature-settings: "TST1"; } p { margin: 0; padding: 0; } diff --git a/layout/reftests/transform-3d/backface-visibility-3-ref.html b/layout/reftests/transform-3d/backface-visibility-3-ref.html new file mode 100644 index 000000000000..b75cb6def5a5 --- /dev/null +++ b/layout/reftests/transform-3d/backface-visibility-3-ref.html @@ -0,0 +1,21 @@ + + + + + + +

+ + + + diff --git a/layout/reftests/transform-3d/backface-visibility-3.html b/layout/reftests/transform-3d/backface-visibility-3.html new file mode 100644 index 000000000000..ec8d648de9c6 --- /dev/null +++ b/layout/reftests/transform-3d/backface-visibility-3.html @@ -0,0 +1,33 @@ + + + + + + +
+
+
+ + + + diff --git a/layout/reftests/transform-3d/reftest.list b/layout/reftests/transform-3d/reftest.list index 72cb19505ad8..344d5fa1364c 100644 --- a/layout/reftests/transform-3d/reftest.list +++ b/layout/reftests/transform-3d/reftest.list @@ -36,6 +36,7 @@ fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fuzzy-if(OSX==10.8,224,924) fu == backface-visibility-1b.html about:blank == backface-visibility-1c.html about:blank == backface-visibility-2.html backface-visibility-2-ref.html +== backface-visibility-3.html backface-visibility-3-ref.html != perspective-origin-1a.html rotatex-perspective-1a.html random-if(Android&&AndroidVersion==17) == perspective-origin-1b.html perspective-origin-1a.html random-if(Android&&!browserIsRemote) == perspective-origin-2a.html perspective-origin-2-ref.html # bug 732568 diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index fb56f95c1560..2c6f3c2e0911 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -38,7 +38,7 @@ bool IsGeometricProperty(nsCSSProperty aProperty); class CommonAnimationManager : public nsIStyleRuleProcessor, public nsARefreshObserver { public: - CommonAnimationManager(nsPresContext *aPresContext); + explicit CommonAnimationManager(nsPresContext *aPresContext); // nsISupports NS_DECL_ISUPPORTS diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 610c8ac660ef..3888862d185e 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -599,8 +599,6 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, data->ValueFor(eCSSProperty__x_system_font); const nsCSSValue *style = data->ValueFor(eCSSProperty_font_style); - const nsCSSValue *variant = - data->ValueFor(eCSSProperty_font_variant); const nsCSSValue *weight = data->ValueFor(eCSSProperty_font_weight); const nsCSSValue *size = @@ -634,17 +632,10 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, const nsCSSValue *fontVariantPosition = data->ValueFor(eCSSProperty_font_variant_position); - // if font features are not enabled, pointers for fontVariant - // values above may be null since the shorthand check ignores them - // font-variant-alternates enabled ==> layout.css.font-features.enabled is true - bool fontFeaturesEnabled = - nsCSSProps::IsEnabled(eCSSProperty_font_variant_alternates); - if (systemFont && systemFont->GetUnit() != eCSSUnit_None && systemFont->GetUnit() != eCSSUnit_Null) { if (style->GetUnit() != eCSSUnit_System_Font || - variant->GetUnit() != eCSSUnit_System_Font || weight->GetUnit() != eCSSUnit_System_Font || size->GetUnit() != eCSSUnit_System_Font || lh->GetUnit() != eCSSUnit_System_Font || @@ -653,15 +644,14 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, sizeAdjust->GetUnit() != eCSSUnit_System_Font || featureSettings->GetUnit() != eCSSUnit_System_Font || languageOverride->GetUnit() != eCSSUnit_System_Font || - (fontFeaturesEnabled && - (fontKerning->GetUnit() != eCSSUnit_System_Font || - fontSynthesis->GetUnit() != eCSSUnit_System_Font || - fontVariantAlternates->GetUnit() != eCSSUnit_System_Font || - fontVariantCaps->GetUnit() != eCSSUnit_System_Font || - fontVariantEastAsian->GetUnit() != eCSSUnit_System_Font || - fontVariantLigatures->GetUnit() != eCSSUnit_System_Font || - fontVariantNumeric->GetUnit() != eCSSUnit_System_Font || - fontVariantPosition->GetUnit() != eCSSUnit_System_Font))) { + fontKerning->GetUnit() != eCSSUnit_System_Font || + fontSynthesis->GetUnit() != eCSSUnit_System_Font || + fontVariantAlternates->GetUnit() != eCSSUnit_System_Font || + fontVariantCaps->GetUnit() != eCSSUnit_System_Font || + fontVariantEastAsian->GetUnit() != eCSSUnit_System_Font || + fontVariantLigatures->GetUnit() != eCSSUnit_System_Font || + fontVariantNumeric->GetUnit() != eCSSUnit_System_Font || + fontVariantPosition->GetUnit() != eCSSUnit_System_Font) { // This can't be represented as a shorthand. return; } @@ -675,17 +665,23 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, sizeAdjust->GetUnit() != eCSSUnit_None || featureSettings->GetUnit() != eCSSUnit_Normal || languageOverride->GetUnit() != eCSSUnit_Normal || - (fontFeaturesEnabled && - (fontKerning->GetIntValue() != NS_FONT_KERNING_AUTO || - fontSynthesis->GetUnit() != eCSSUnit_Enumerated || - fontSynthesis->GetIntValue() != - (NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE) || - fontVariantAlternates->GetUnit() != eCSSUnit_Normal || - fontVariantCaps->GetUnit() != eCSSUnit_Normal || - fontVariantEastAsian->GetUnit() != eCSSUnit_Normal || - fontVariantLigatures->GetUnit() != eCSSUnit_Normal || - fontVariantNumeric->GetUnit() != eCSSUnit_Normal || - fontVariantPosition->GetUnit() != eCSSUnit_Normal))) { + fontKerning->GetIntValue() != NS_FONT_KERNING_AUTO || + fontSynthesis->GetUnit() != eCSSUnit_Enumerated || + fontSynthesis->GetIntValue() != + (NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE) || + fontVariantAlternates->GetUnit() != eCSSUnit_Normal || + fontVariantEastAsian->GetUnit() != eCSSUnit_Normal || + fontVariantLigatures->GetUnit() != eCSSUnit_Normal || + fontVariantNumeric->GetUnit() != eCSSUnit_Normal || + fontVariantPosition->GetUnit() != eCSSUnit_Normal) { + return; + } + + // only a normal or small-caps values of font-variant-caps can + // be represented in the font shorthand + if (fontVariantCaps->GetUnit() != eCSSUnit_Normal && + (fontVariantCaps->GetUnit() != eCSSUnit_Enumerated || + fontVariantCaps->GetIntValue() != NS_FONT_VARIANT_CAPS_SMALLCAPS)) { return; } @@ -695,9 +691,8 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, aSerialization); aValue.Append(char16_t(' ')); } - if (variant->GetUnit() != eCSSUnit_Enumerated || - variant->GetIntValue() != NS_FONT_VARIANT_NORMAL) { - variant->AppendToString(eCSSProperty_font_variant, aValue, + if (fontVariantCaps->GetUnit() != eCSSUnit_Normal) { + fontVariantCaps->AppendToString(eCSSProperty_font_variant_caps, aValue, aSerialization); aValue.Append(char16_t(' ')); } @@ -718,6 +713,60 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, } break; } + case eCSSProperty_font_variant: { + const nsCSSProperty *subprops = + nsCSSProps::SubpropertyEntryFor(aProperty); + const nsCSSValue *fontVariantLigatures = + data->ValueFor(eCSSProperty_font_variant_ligatures); + + // all subproperty values normal? system font? + bool normalLigs = true, normalNonLigs = true, systemFont = true, + hasSystem = false; + for (const nsCSSProperty *sp = subprops; *sp != eCSSProperty_UNKNOWN; sp++) { + const nsCSSValue *spVal = data->ValueFor(*sp); + bool isNormal = (spVal->GetUnit() == eCSSUnit_Normal); + if (*sp == eCSSProperty_font_variant_ligatures) { + normalLigs = normalLigs && isNormal; + } else { + normalNonLigs = normalNonLigs && isNormal; + } + bool isSystem = (spVal->GetUnit() == eCSSUnit_System_Font); + systemFont = systemFont && isSystem; + hasSystem = hasSystem || isSystem; + } + + bool ligsNone = + fontVariantLigatures->GetUnit() == eCSSUnit_None; + + // normal, none, or system font ==> single value + if ((normalLigs && normalNonLigs) || + (normalNonLigs && ligsNone) || + systemFont) { + fontVariantLigatures->AppendToString(eCSSProperty_font_variant_ligatures, + aValue, + aSerialization); + } else if (ligsNone || hasSystem) { + // ligatures none but other values are non-normal ==> empty + // at least one but not all values are system font ==> empty + return; + } else { + // iterate over and append non-normal values + bool appendSpace = false; + for (const nsCSSProperty *sp = subprops; + *sp != eCSSProperty_UNKNOWN; sp++) { + const nsCSSValue *spVal = data->ValueFor(*sp); + if (spVal && spVal->GetUnit() != eCSSUnit_Normal) { + if (appendSpace) { + aValue.Append(char16_t(' ')); + } else { + appendSpace = true; + } + spVal->AppendToString(*sp, aValue, aSerialization); + } + } + } + break; + } case eCSSProperty_list_style: if (AppendValueToString(eCSSProperty_list_style_position, aValue, aSerialization)) { @@ -1294,9 +1343,17 @@ Declaration::ToString(nsAString& aString) const // least, which is exactly the order we want to test them. nsCSSProperty shorthand = *shorthands; + GetValue(shorthand, value); + + // in the system font case, skip over font-variant shorthand, since all + // subproperties are already dealt with via the font shorthand + if (shorthand == eCSSProperty_font_variant && + value.EqualsLiteral("-moz-use-system-font")) { + continue; + } + // If GetValue gives us a non-empty string back, we can use that // value; otherwise it's not possible to use this shorthand. - GetValue(shorthand, value); if (!value.IsEmpty()) { AppendPropertyAndValueToString(shorthand, value, aString); shorthandsUsed.AppendElement(shorthand); @@ -1304,9 +1361,6 @@ Declaration::ToString(nsAString& aString) const break; } - NS_ABORT_IF_FALSE(shorthand != eCSSProperty_font || - *(shorthands + 1) == eCSSProperty_UNKNOWN, - "font should always be the only containing shorthand"); if (shorthand == eCSSProperty_font) { if (haveSystemFont && !didSystemFont) { // Output the shorthand font declaration that we will @@ -1329,6 +1383,7 @@ Declaration::ToString(nsAString& aString) const if (property == eCSSProperty__x_system_font || (haveSystemFont && val && val->GetUnit() == eCSSUnit_System_Font)) { doneProperty = true; + break; } } } diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index 9b84f22a7630..4a74ffd76c6c 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -30,8 +30,8 @@ class CSSStyleSheet; struct nsAtomList { public: - nsAtomList(nsIAtom* aAtom); - nsAtomList(const nsString& aAtomValue); + explicit nsAtomList(nsIAtom* aAtom); + explicit nsAtomList(const nsString& aAtomValue); ~nsAtomList(void); /** Do a deep clone. Should be used only on the first in the linked list. */ @@ -50,7 +50,7 @@ private: struct nsPseudoClassList { public: - nsPseudoClassList(nsCSSPseudoClasses::Type aType); + explicit nsPseudoClassList(nsCSSPseudoClasses::Type aType); nsPseudoClassList(nsCSSPseudoClasses::Type aType, const char16_t *aString); nsPseudoClassList(nsCSSPseudoClasses::Type aType, const int32_t *aIntPair); nsPseudoClassList(nsCSSPseudoClasses::Type aType, @@ -284,7 +284,7 @@ class StyleRule; class ImportantRule : public nsIStyleRule { public: - ImportantRule(Declaration *aDeclaration); + explicit ImportantRule(Declaration *aDeclaration); NS_DECL_ISUPPORTS diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 791305232eae..5244436c9d87 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -52,7 +52,7 @@ class nsAnimationManager MOZ_FINAL : public mozilla::css::CommonAnimationManager { public: - nsAnimationManager(nsPresContext *aPresContext) + explicit nsAnimationManager(nsPresContext *aPresContext) : mozilla::css::CommonAnimationManager(aPresContext) , mObservingRefreshDriver(false) { diff --git a/layout/style/nsCSSFontDescList.h b/layout/style/nsCSSFontDescList.h index cbbaeab630ba..f4255fc61df5 100644 --- a/layout/style/nsCSSFontDescList.h +++ b/layout/style/nsCSSFontDescList.h @@ -9,8 +9,5 @@ CSS_FONT_DESC(font-weight, Weight) CSS_FONT_DESC(font-stretch, Stretch) CSS_FONT_DESC(src, Src) CSS_FONT_DESC(unicode-range, UnicodeRange) - -/* Note: the parsing code explicitly also accepts font-feature-settings - and font-language-override. */ -CSS_FONT_DESC(-moz-font-feature-settings, FontFeatureSettings) -CSS_FONT_DESC(-moz-font-language-override, FontLanguageOverride) +CSS_FONT_DESC(font-feature-settings, FontFeatureSettings) +CSS_FONT_DESC(font-language-override, FontLanguageOverride) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 50cbe9e9ac55..645cd9a6ea67 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -757,12 +757,15 @@ protected: bool ParseFontSynthesis(nsCSSValue& aValue); bool ParseSingleAlternate(int32_t& aWhichFeature, nsCSSValue& aValue); bool ParseFontVariantAlternates(nsCSSValue& aValue); + bool MergeBitmaskValue(int32_t aNewValue, const int32_t aMasks[], + int32_t& aMergedValue); bool ParseBitmaskValues(nsCSSValue& aValue, const KTableValue aKeywordTable[], const int32_t aMasks[]); bool ParseFontVariantEastAsian(nsCSSValue& aValue); bool ParseFontVariantLigatures(nsCSSValue& aValue); bool ParseFontVariantNumeric(nsCSSValue& aValue); + bool ParseFontVariant(); bool ParseFontWeight(nsCSSValue& aValue); bool ParseOneFamily(nsAString& aFamily, bool& aOneKeyword, bool& aQuoted); bool ParseFamily(nsCSSValue& aValue); @@ -2752,8 +2755,7 @@ CSSParserImpl::ParseAtRule(RuleAppendFunc aAppendFunc, parseFunc = &CSSParserImpl::ParseFontFaceRule; newSection = eCSSSection_General; - } else if (mToken.mIdent.LowerCaseEqualsLiteral("font-feature-values") && - nsCSSFontFeatureValuesRule::PrefEnabled()) { + } else if (mToken.mIdent.LowerCaseEqualsLiteral("font-feature-values")) { parseFunc = &CSSParserImpl::ParseFontFeatureValuesRule; newSection = eCSSSection_General; @@ -9738,6 +9740,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID) return ParseFlexFlow(); case eCSSProperty_font: return ParseFont(); + case eCSSProperty_font_variant: + return ParseFontVariant(); case eCSSProperty_grid_auto_flow: return ParseGridAutoFlow(); case eCSSProperty_grid_auto_columns: @@ -11727,13 +11731,10 @@ CSSParserImpl::ParseFont() { static const nsCSSProperty fontIDs[] = { eCSSProperty_font_style, - eCSSProperty_font_variant, + eCSSProperty_font_variant_caps, eCSSProperty_font_weight }; - // font-variant-alternates enabled ==> layout.css.font-features.enabled is true - bool featuresEnabled = - nsCSSProps::IsEnabled(eCSSProperty_font_variant_alternates); nsCSSValue family; if (ParseVariant(family, VARIANT_HK, nsCSSProps::kFontKTable)) { if (eCSSUnit_Inherit == family.GetUnit() || @@ -11742,7 +11743,6 @@ CSSParserImpl::ParseFont() AppendValue(eCSSProperty__x_system_font, nsCSSValue(eCSSUnit_None)); AppendValue(eCSSProperty_font_family, family); AppendValue(eCSSProperty_font_style, family); - AppendValue(eCSSProperty_font_variant, family); AppendValue(eCSSProperty_font_weight, family); AppendValue(eCSSProperty_font_size, family); AppendValue(eCSSProperty_line_height, family); @@ -11750,23 +11750,20 @@ CSSParserImpl::ParseFont() AppendValue(eCSSProperty_font_size_adjust, family); AppendValue(eCSSProperty_font_feature_settings, family); AppendValue(eCSSProperty_font_language_override, family); - if (featuresEnabled) { - AppendValue(eCSSProperty_font_kerning, family); - AppendValue(eCSSProperty_font_synthesis, family); - AppendValue(eCSSProperty_font_variant_alternates, family); - AppendValue(eCSSProperty_font_variant_caps, family); - AppendValue(eCSSProperty_font_variant_east_asian, family); - AppendValue(eCSSProperty_font_variant_ligatures, family); - AppendValue(eCSSProperty_font_variant_numeric, family); - AppendValue(eCSSProperty_font_variant_position, family); - } + AppendValue(eCSSProperty_font_kerning, family); + AppendValue(eCSSProperty_font_synthesis, family); + AppendValue(eCSSProperty_font_variant_alternates, family); + AppendValue(eCSSProperty_font_variant_caps, family); + AppendValue(eCSSProperty_font_variant_east_asian, family); + AppendValue(eCSSProperty_font_variant_ligatures, family); + AppendValue(eCSSProperty_font_variant_numeric, family); + AppendValue(eCSSProperty_font_variant_position, family); } else { AppendValue(eCSSProperty__x_system_font, family); nsCSSValue systemFont(eCSSUnit_System_Font); AppendValue(eCSSProperty_font_family, systemFont); AppendValue(eCSSProperty_font_style, systemFont); - AppendValue(eCSSProperty_font_variant, systemFont); AppendValue(eCSSProperty_font_weight, systemFont); AppendValue(eCSSProperty_font_size, systemFont); AppendValue(eCSSProperty_line_height, systemFont); @@ -11774,16 +11771,14 @@ CSSParserImpl::ParseFont() AppendValue(eCSSProperty_font_size_adjust, systemFont); AppendValue(eCSSProperty_font_feature_settings, systemFont); AppendValue(eCSSProperty_font_language_override, systemFont); - if (featuresEnabled) { - AppendValue(eCSSProperty_font_kerning, systemFont); - AppendValue(eCSSProperty_font_synthesis, systemFont); - AppendValue(eCSSProperty_font_variant_alternates, systemFont); - AppendValue(eCSSProperty_font_variant_caps, systemFont); - AppendValue(eCSSProperty_font_variant_east_asian, systemFont); - AppendValue(eCSSProperty_font_variant_ligatures, systemFont); - AppendValue(eCSSProperty_font_variant_numeric, systemFont); - AppendValue(eCSSProperty_font_variant_position, systemFont); - } + AppendValue(eCSSProperty_font_kerning, systemFont); + AppendValue(eCSSProperty_font_synthesis, systemFont); + AppendValue(eCSSProperty_font_variant_alternates, systemFont); + AppendValue(eCSSProperty_font_variant_caps, systemFont); + AppendValue(eCSSProperty_font_variant_east_asian, systemFont); + AppendValue(eCSSProperty_font_variant_ligatures, systemFont); + AppendValue(eCSSProperty_font_variant_numeric, systemFont); + AppendValue(eCSSProperty_font_variant_position, systemFont); } return true; } @@ -11804,7 +11799,15 @@ CSSParserImpl::ParseFont() } if ((found & 2) == 0) { // Provide default font-variant - values[1].SetIntValue(NS_FONT_VARIANT_NORMAL, eCSSUnit_Enumerated); + values[1].SetNormalValue(); + } else { + if (values[1].GetUnit() == eCSSUnit_Enumerated && + !values[1].GetIntValue() == NS_FONT_VARIANT_CAPS_SMALLCAPS) { + // only normal or small-caps is allowed in font shorthand + // this also assumes other values for font-variant-caps never overlap + // possible values for style or weight + return false; + } } if ((found & 4) == 0) { // Provide default font-weight @@ -11840,7 +11843,7 @@ CSSParserImpl::ParseFont() AppendValue(eCSSProperty__x_system_font, nsCSSValue(eCSSUnit_None)); AppendValue(eCSSProperty_font_family, family); AppendValue(eCSSProperty_font_style, values[0]); - AppendValue(eCSSProperty_font_variant, values[1]); + AppendValue(eCSSProperty_font_variant_caps, values[1]); AppendValue(eCSSProperty_font_weight, values[2]); AppendValue(eCSSProperty_font_size, size); AppendValue(eCSSProperty_line_height, lineHeight); @@ -11849,24 +11852,21 @@ CSSParserImpl::ParseFont() AppendValue(eCSSProperty_font_size_adjust, nsCSSValue(eCSSUnit_None)); AppendValue(eCSSProperty_font_feature_settings, nsCSSValue(eCSSUnit_Normal)); AppendValue(eCSSProperty_font_language_override, nsCSSValue(eCSSUnit_Normal)); - if (featuresEnabled) { - AppendValue(eCSSProperty_font_kerning, - nsCSSValue(NS_FONT_KERNING_AUTO, eCSSUnit_Enumerated)); - AppendValue(eCSSProperty_font_synthesis, - nsCSSValue(NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE, - eCSSUnit_Enumerated)); - AppendValue(eCSSProperty_font_variant_alternates, - nsCSSValue(eCSSUnit_Normal)); - AppendValue(eCSSProperty_font_variant_caps, nsCSSValue(eCSSUnit_Normal)); - AppendValue(eCSSProperty_font_variant_east_asian, - nsCSSValue(eCSSUnit_Normal)); - AppendValue(eCSSProperty_font_variant_ligatures, - nsCSSValue(eCSSUnit_Normal)); - AppendValue(eCSSProperty_font_variant_numeric, - nsCSSValue(eCSSUnit_Normal)); - AppendValue(eCSSProperty_font_variant_position, - nsCSSValue(eCSSUnit_Normal)); - } + AppendValue(eCSSProperty_font_kerning, + nsCSSValue(NS_FONT_KERNING_AUTO, eCSSUnit_Enumerated)); + AppendValue(eCSSProperty_font_synthesis, + nsCSSValue(NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE, + eCSSUnit_Enumerated)); + AppendValue(eCSSProperty_font_variant_alternates, + nsCSSValue(eCSSUnit_Normal)); + AppendValue(eCSSProperty_font_variant_east_asian, + nsCSSValue(eCSSUnit_Normal)); + AppendValue(eCSSProperty_font_variant_ligatures, + nsCSSValue(eCSSUnit_Normal)); + AppendValue(eCSSProperty_font_variant_numeric, + nsCSSValue(eCSSUnit_Normal)); + AppendValue(eCSSProperty_font_variant_position, + nsCSSValue(eCSSUnit_Normal)); return true; } } @@ -11910,7 +11910,7 @@ CSSParserImpl::ParseFontSynthesis(nsCSSValue& aValue) // parameter lists with one or more idents which are later resolved // based on values defined in @font-feature-value rules. // -// font-variant-alternates: swash(flowing), historical-forms, styleset(alt-g, alt-m); +// font-variant-alternates: swash(flowing) historical-forms styleset(alt-g, alt-m); // // So for this the nsCSSValue is set to a pair value, with one // value for a bitmask of both simple and functional property values @@ -11932,6 +11932,17 @@ CSSParserImpl::ParseFontSynthesis(nsCSSValue& aValue) #define MAX_ALLOWED_FEATURES 512 +static uint16_t +MaxElementsForAlternateType(nsCSSKeyword keyword) +{ + uint16_t maxElems = 1; + if (keyword == eCSSKeyword_styleset || + keyword == eCSSKeyword_character_variant) { + maxElems = MAX_ALLOWED_FEATURES; + } + return maxElems; +} + bool CSSParserImpl::ParseSingleAlternate(int32_t& aWhichFeature, nsCSSValue& aValue) @@ -11967,13 +11978,8 @@ CSSParserImpl::ParseSingleAlternate(int32_t& aWhichFeature, return true; } - uint16_t maxElems = 1; - if (keyword == eCSSKeyword_styleset || - keyword == eCSSKeyword_character_variant) { - maxElems = MAX_ALLOWED_FEATURES; - } return ParseFunction(keyword, nullptr, VARIANT_IDENTIFIER, - 1, maxElems, aValue); + 1, MaxElementsForAlternateType(keyword), aValue); } bool @@ -12026,6 +12032,35 @@ CSSParserImpl::ParseFontVariantAlternates(nsCSSValue& aValue) return true; } +bool +CSSParserImpl::MergeBitmaskValue(int32_t aNewValue, + const int32_t aMasks[], + int32_t& aMergedValue) +{ + // check to make sure value not already set + if (aNewValue & aMergedValue) { + return false; + } + + const int32_t *m = aMasks; + int32_t c = 0; + + while (*m != MASK_END_VALUE) { + if (*m & aNewValue) { + c = aMergedValue & *m; + break; + } + m++; + } + + if (c) { + return false; + } + + aMergedValue |= aNewValue; + return true; +} + // aMasks - array of masks for mutually-exclusive property values, // e.g. proportial-nums, tabular-nums @@ -12045,29 +12080,9 @@ CSSParserImpl::ParseBitmaskValues(nsCSSValue& aValue, while (ParseEnum(nextValue, aKeywordTable)) { - int32_t nextIntValue = nextValue.GetIntValue(); - - // check to make sure value not already set - if (nextIntValue & mergedValue) { + if (!MergeBitmaskValue(nextValue.GetIntValue(), aMasks, mergedValue)) { return false; } - - const int32_t *m = aMasks; - int32_t c = 0; - - while (*m != MASK_END_VALUE) { - if (*m & nextIntValue) { - c = mergedValue & *m; - break; - } - m++; - } - - if (c) { - return false; - } - - mergedValue |= nextIntValue; } aValue.SetIntValue(mergedValue, eCSSUnit_Enumerated); @@ -12107,7 +12122,9 @@ static const int32_t maskLigatures[] = { bool CSSParserImpl::ParseFontVariantLigatures(nsCSSValue& aValue) { - if (ParseVariant(aValue, VARIANT_INHERIT | VARIANT_NORMAL, nullptr)) { + if (ParseVariant(aValue, + VARIANT_INHERIT | VARIANT_NORMAL | VARIANT_NONE, + nullptr)) { return true; } @@ -12115,20 +12132,8 @@ CSSParserImpl::ParseFontVariantLigatures(nsCSSValue& aValue) MASK_END_VALUE, "incorrectly terminated array"); - bool parsed = - ParseBitmaskValues(aValue, nsCSSProps::kFontVariantLigaturesKTable, - maskLigatures); - - // if none value included, no other values are possible - if (parsed && eCSSUnit_Enumerated == aValue.GetUnit()) { - int32_t val = aValue.GetIntValue(); - if ((val & NS_FONT_VARIANT_LIGATURES_NONE) && - (val & ~int32_t(NS_FONT_VARIANT_LIGATURES_NONE))) { - parsed = false; - } - } - - return parsed; + return ParseBitmaskValues(aValue, nsCSSProps::kFontVariantLigaturesKTable, + maskLigatures); } static const int32_t maskNumeric[] = { @@ -12153,6 +12158,194 @@ CSSParserImpl::ParseFontVariantNumeric(nsCSSValue& aValue) maskNumeric); } +bool +CSSParserImpl::ParseFontVariant() +{ + // parse single values - normal/inherit/none + nsCSSValue value; + nsCSSValue normal(eCSSUnit_Normal); + + if (ParseVariant(value, + VARIANT_INHERIT | VARIANT_NORMAL | VARIANT_NONE, + nullptr)) { + AppendValue(eCSSProperty_font_variant_ligatures, value); + if (eCSSUnit_None == value.GetUnit()) { + // 'none' applies the value 'normal' to all properties other + // than 'font-variant-ligatures' + value.SetNormalValue(); + } + AppendValue(eCSSProperty_font_variant_alternates, value); + AppendValue(eCSSProperty_font_variant_caps, value); + AppendValue(eCSSProperty_font_variant_east_asian, value); + AppendValue(eCSSProperty_font_variant_numeric, value); + AppendValue(eCSSProperty_font_variant_position, value); + return true; + } + + // set each of the individual subproperties + int32_t altFeatures = 0, capsFeatures = 0, eastAsianFeatures = 0, + ligFeatures = 0, numericFeatures = 0, posFeatures = 0; + nsCSSValue altListValue; + nsCSSValueList* altList = nullptr; + + // if no functional values, this may be a list with a single, unused element + altListValue.SetListValue(); + + bool foundValid = false; // found at least one proper value + while (GetToken(true)) { + // only an ident or a function at this point + bool isFunction = (mToken.mType == eCSSToken_Function); + if (mToken.mType != eCSSToken_Ident && !isFunction) { + UngetToken(); + break; + } + + nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent); + if (keyword == eCSSKeyword_UNKNOWN) { + UngetToken(); + return false; + } + + int32_t feature; + + // function? ==> font-variant-alternates + if (isFunction) { + if (!nsCSSProps::FindKeyword(keyword, + nsCSSProps::kFontVariantAlternatesFuncsKTable, + feature) || + (feature & altFeatures)) { + UngetToken(); + return false; + } + + altFeatures |= feature; + nsCSSValue funcValue; + if (!ParseFunction(keyword, nullptr, VARIANT_IDENTIFIER, 1, + MaxElementsForAlternateType(keyword), funcValue) || + funcValue.GetUnit() != eCSSUnit_Function) { + UngetToken(); + return false; + } + + if (!altList) { + altList = altListValue.GetListValue(); + } else { + altList->mNext = new nsCSSValueList; + altList = altList->mNext; + } + altList->mValue = funcValue; + } else if (nsCSSProps::FindKeyword(keyword, + nsCSSProps::kFontVariantCapsKTable, + feature)) { + if (capsFeatures != 0) { + // multiple values for font-variant-caps + UngetToken(); + return false; + } + capsFeatures = feature; + } else if (nsCSSProps::FindKeyword(keyword, + nsCSSProps::kFontVariantAlternatesKTable, + feature)) { + if (feature & altFeatures) { + // same value repeated + UngetToken(); + return false; + } + altFeatures |= feature; + } else if (nsCSSProps::FindKeyword(keyword, + nsCSSProps::kFontVariantEastAsianKTable, + feature)) { + if (!MergeBitmaskValue(feature, maskEastAsian, eastAsianFeatures)) { + // multiple mutually exclusive values + UngetToken(); + return false; + } + } else if (nsCSSProps::FindKeyword(keyword, + nsCSSProps::kFontVariantLigaturesKTable, + feature)) { + if (keyword == eCSSKeyword_none || + !MergeBitmaskValue(feature, maskLigatures, ligFeatures)) { + // none or multiple mutually exclusive values + UngetToken(); + return false; + } + } else if (nsCSSProps::FindKeyword(keyword, + nsCSSProps::kFontVariantNumericKTable, + feature)) { + if (!MergeBitmaskValue(feature, maskNumeric, numericFeatures)) { + // multiple mutually exclusive values + UngetToken(); + return false; + } + } else if (nsCSSProps::FindKeyword(keyword, + nsCSSProps::kFontVariantPositionKTable, + feature)) { + if (posFeatures != 0) { + // multiple values for font-variant-caps + UngetToken(); + return false; + } + posFeatures = feature; + } else { + // bogus keyword, bail... + UngetToken(); + return false; + } + + foundValid = true; + } + + if (!foundValid) { + return false; + } + + if (altFeatures) { + nsCSSValue featureValue; + featureValue.SetIntValue(altFeatures, eCSSUnit_Enumerated); + value.SetPairValue(featureValue, altListValue); + AppendValue(eCSSProperty_font_variant_alternates, value); + } else { + AppendValue(eCSSProperty_font_variant_alternates, normal); + } + + if (capsFeatures) { + value.SetIntValue(capsFeatures, eCSSUnit_Enumerated); + AppendValue(eCSSProperty_font_variant_caps, value); + } else { + AppendValue(eCSSProperty_font_variant_caps, normal); + } + + if (eastAsianFeatures) { + value.SetIntValue(eastAsianFeatures, eCSSUnit_Enumerated); + AppendValue(eCSSProperty_font_variant_east_asian, value); + } else { + AppendValue(eCSSProperty_font_variant_east_asian, normal); + } + + if (ligFeatures) { + value.SetIntValue(ligFeatures, eCSSUnit_Enumerated); + AppendValue(eCSSProperty_font_variant_ligatures, value); + } else { + AppendValue(eCSSProperty_font_variant_ligatures, normal); + } + + if (numericFeatures) { + value.SetIntValue(numericFeatures, eCSSUnit_Enumerated); + AppendValue(eCSSProperty_font_variant_numeric, value); + } else { + AppendValue(eCSSProperty_font_variant_numeric, normal); + } + + if (posFeatures) { + value.SetIntValue(posFeatures, eCSSUnit_Enumerated); + AppendValue(eCSSProperty_font_variant_position, value); + } else { + AppendValue(eCSSProperty_font_variant_position, normal); + } + + return true; +} + bool CSSParserImpl::ParseFontWeight(nsCSSValue& aValue) { diff --git a/layout/style/nsCSSPropAliasList.h b/layout/style/nsCSSPropAliasList.h index 6c37268f1bc3..4bc9625d6a5a 100644 --- a/layout/style/nsCSSPropAliasList.h +++ b/layout/style/nsCSSPropAliasList.h @@ -119,11 +119,11 @@ CSS_PROP_ALIAS(-moz-box-sizing, box_sizing, MozBoxSizing, "layout.css.prefixes.box-sizing") -CSS_PROP_ALIAS(font-feature-settings, +CSS_PROP_ALIAS(-moz-font-feature-settings, font_feature_settings, - FontFeatureSettings, - "layout.css.font-features.enabled") -CSS_PROP_ALIAS(font-language-override, + MozFontFeatureSettings, + "layout.css.prefixes.font-features") +CSS_PROP_ALIAS(-moz-font-language-override, font_language_override, - FontLanguageOverride, - "layout.css.font-features.enabled") + MozFontLanguageOverride, + "layout.css.prefixes.font-features") diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 54786eeb8fd3..e2eb0b69facc 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1775,9 +1775,9 @@ CSS_PROP_FONT( CSS_PROP_NO_OFFSET, eStyleAnimType_None) CSS_PROP_FONT( - -moz-font-feature-settings, + font-feature-settings, font_feature_settings, - CSS_PROP_DOMPROP_PREFIXED(FontFeatureSettings), + FontFeatureSettings, CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_PARSER_FUNCTION | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | @@ -1794,15 +1794,15 @@ CSS_PROP_FONT( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, - "layout.css.font-features.enabled", + "", VARIANT_HK, kFontKerningKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) CSS_PROP_FONT( - -moz-font-language-override, + font-language-override, font_language_override, - CSS_PROP_DOMPROP_PREFIXED(FontLanguageOverride), + FontLanguageOverride, CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, @@ -1884,23 +1884,17 @@ CSS_PROP_FONT( CSS_PROPERTY_VALUE_PARSER_FUNCTION | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, - "layout.css.font-features.enabled", + "", 0, kFontSynthesisKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_FONT( +CSS_PROP_SHORTHAND( font-variant, font_variant, FontVariant, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | - CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, - "", - VARIANT_HK | VARIANT_SYSFONT, - kFontVariantKTable, - offsetof(nsStyleFont, mFont.variant), - eStyleAnimType_EnumU8) + CSS_PROPERTY_PARSE_FUNCTION, + "") CSS_PROP_FONT( font-variant-alternates, font_variant_alternates, @@ -1909,8 +1903,8 @@ CSS_PROP_FONT( CSS_PROPERTY_VALUE_PARSER_FUNCTION | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, - "layout.css.font-features.enabled", - VARIANT_HK, + "", + 0, kFontVariantAlternatesKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) @@ -1921,7 +1915,7 @@ CSS_PROP_FONT( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, - "layout.css.font-features.enabled", + "", VARIANT_HMK, kFontVariantCapsKTable, CSS_PROP_NO_OFFSET, @@ -1934,7 +1928,7 @@ CSS_PROP_FONT( CSS_PROPERTY_VALUE_PARSER_FUNCTION | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, - "layout.css.font-features.enabled", + "", 0, kFontVariantEastAsianKTable, CSS_PROP_NO_OFFSET, @@ -1947,7 +1941,7 @@ CSS_PROP_FONT( CSS_PROPERTY_VALUE_PARSER_FUNCTION | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, - "layout.css.font-features.enabled", + "", 0, kFontVariantLigaturesKTable, CSS_PROP_NO_OFFSET, @@ -1960,7 +1954,7 @@ CSS_PROP_FONT( CSS_PROPERTY_VALUE_PARSER_FUNCTION | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, - "layout.css.font-features.enabled", + "", 0, kFontVariantNumericKTable, CSS_PROP_NO_OFFSET, @@ -1972,7 +1966,7 @@ CSS_PROP_FONT( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER, - "layout.css.font-features.enabled", + "", VARIANT_HMK, kFontVariantPositionKTable, CSS_PROP_NO_OFFSET, diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index d03c3e146f38..594798ed5ef8 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -476,12 +476,8 @@ nsCSSProps::LookupFontDesc(const nsAString& aFontDesc) NS_ABORT_IF_FALSE(gFontDescTable, "no lookup table, needs addref"); nsCSSFontDesc which = nsCSSFontDesc(gFontDescTable->Lookup(aFontDesc)); - // font-variant-alternates enabled ==> layout.css.font-features.enabled is true - bool fontFeaturesEnabled = - nsCSSProps::IsEnabled(eCSSProperty_font_variant_alternates); - // check for unprefixed font-feature-settings/font-language-override - if (which == eCSSFontDesc_UNKNOWN && fontFeaturesEnabled) { + if (which == eCSSFontDesc_UNKNOWN) { nsAutoString prefixedProp; prefixedProp.AppendLiteral("-moz-"); prefixedProp.Append(aFontDesc); @@ -1246,13 +1242,6 @@ const KTableValue nsCSSProps::kFontSynthesisKTable[] = { eCSSKeyword_UNKNOWN,-1 }; - -const KTableValue nsCSSProps::kFontVariantKTable[] = { - eCSSKeyword_normal, NS_STYLE_FONT_VARIANT_NORMAL, - eCSSKeyword_small_caps, NS_STYLE_FONT_VARIANT_SMALL_CAPS, - eCSSKeyword_UNKNOWN,-1 -}; - const KTableValue nsCSSProps::kFontVariantAlternatesKTable[] = { eCSSKeyword_historical_forms, NS_FONT_VARIANT_ALTERNATES_HISTORICAL, eCSSKeyword_UNKNOWN,-1 @@ -1292,7 +1281,6 @@ const KTableValue nsCSSProps::kFontVariantEastAsianKTable[] = { }; const KTableValue nsCSSProps::kFontVariantLigaturesKTable[] = { - eCSSKeyword_none, NS_FONT_VARIANT_LIGATURES_NONE, eCSSKeyword_common_ligatures, NS_FONT_VARIANT_LIGATURES_COMMON, eCSSKeyword_no_common_ligatures, NS_FONT_VARIANT_LIGATURES_NO_COMMON, eCSSKeyword_discretionary_ligatures, NS_FONT_VARIANT_LIGATURES_DISCRETIONARY, @@ -2470,7 +2458,6 @@ static const nsCSSProperty gBorderEndWidthSubpropTable[] = { static const nsCSSProperty gFontSubpropTable[] = { eCSSProperty_font_family, eCSSProperty_font_style, - eCSSProperty_font_variant, eCSSProperty_font_weight, eCSSProperty_font_size, eCSSProperty_line_height, @@ -2490,6 +2477,16 @@ static const nsCSSProperty gFontSubpropTable[] = { eCSSProperty_UNKNOWN }; +static const nsCSSProperty gFontVariantSubpropTable[] = { + eCSSProperty_font_variant_alternates, + eCSSProperty_font_variant_caps, + eCSSProperty_font_variant_east_asian, + eCSSProperty_font_variant_ligatures, + eCSSProperty_font_variant_numeric, + eCSSProperty_font_variant_position, + eCSSProperty_UNKNOWN +}; + static const nsCSSProperty gListStyleSubpropTable[] = { eCSSProperty_list_style_type, eCSSProperty_list_style_image, diff --git a/layout/style/nsCSSRules.h b/layout/style/nsCSSRules.h index 6cbd924f2966..03308d301711 100644 --- a/layout/style/nsCSSRules.h +++ b/layout/style/nsCSSRules.h @@ -338,15 +338,6 @@ public: virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE; - static bool PrefEnabled() - { - // font-variant-alternates enabled ==> layout.css.font-features.enabled is true - bool fontFeaturesEnabled = - nsCSSProps::IsEnabled(eCSSProperty_font_variant_alternates); - - return fontFeaturesEnabled; - } - protected: ~nsCSSFontFeatureValuesRule() {} diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 31f34a15f87d..b28a926e6a2e 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1469,16 +1469,6 @@ nsComputedDOMStyle::DoGetFontWeight() return val; } -CSSValue* -nsComputedDOMStyle::DoGetFontVariant() -{ - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; - val->SetIdent( - nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.variant, - nsCSSProps::kFontVariantKTable)); - return val; -} - CSSValue* nsComputedDOMStyle::DoGetFontFeatureSettings() { @@ -1543,6 +1533,37 @@ nsComputedDOMStyle::DoGetFontSynthesis() return val; } +// return a value *only* for valid longhand values from CSS 2.1, either +// normal or small-caps only +CSSValue* +nsComputedDOMStyle::DoGetFontVariant() +{ + const nsFont& f = StyleFont()->mFont; + + // if any of the other font-variant subproperties other than + // font-variant-caps are not normal then can't calculate a computed value + if (f.variantAlternates || f.variantEastAsian || f.variantLigatures || + f.variantNumeric || f.variantPosition) { + return nullptr; + } + + nsCSSKeyword keyword; + switch (f.variantCaps) { + case 0: + keyword = eCSSKeyword_normal; + break; + case NS_FONT_VARIANT_CAPS_SMALLCAPS: + keyword = eCSSKeyword_small_caps; + break; + default: + return nullptr; + } + + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + val->SetIdent(keyword); + return val; +} + CSSValue* nsComputedDOMStyle::DoGetFontVariantAlternates() { @@ -1573,7 +1594,6 @@ nsComputedDOMStyle::DoGetFontVariantAlternates() return val; } - CSSValue* nsComputedDOMStyle::DoGetFontVariantCaps() { @@ -1622,6 +1642,8 @@ nsComputedDOMStyle::DoGetFontVariantLigatures() if (0 == intValue) { val->SetIdent(eCSSKeyword_normal); + } else if (NS_FONT_VARIANT_LIGATURES_NONE == intValue) { + val->SetIdent(eCSSKeyword_none); } else { nsAutoString valueStr; diff --git a/layout/style/nsComputedDOMStylePropertyList.h b/layout/style/nsComputedDOMStylePropertyList.h index 335f2e816dc7..7f3f38da258e 100644 --- a/layout/style/nsComputedDOMStylePropertyList.h +++ b/layout/style/nsComputedDOMStylePropertyList.h @@ -117,7 +117,9 @@ COMPUTED_STYLE_PROP(flex_wrap, FlexWrap) COMPUTED_STYLE_PROP(float, Float) //// COMPUTED_STYLE_PROP(font, Font) COMPUTED_STYLE_PROP(font_family, FontFamily) +COMPUTED_STYLE_PROP(font_feature_settings, FontFeatureSettings) COMPUTED_STYLE_PROP(font_kerning, FontKerning) +COMPUTED_STYLE_PROP(font_language_override, FontLanguageOverride) COMPUTED_STYLE_PROP(font_size, FontSize) COMPUTED_STYLE_PROP(font_size_adjust, FontSizeAdjust) COMPUTED_STYLE_PROP(font_stretch, FontStretch) @@ -250,8 +252,6 @@ COMPUTED_STYLE_PROP(_moz_column_rule_style, ColumnRuleStyle) COMPUTED_STYLE_PROP(_moz_column_rule_width, ColumnRuleWidth) COMPUTED_STYLE_PROP(_moz_column_width, ColumnWidth) COMPUTED_STYLE_PROP(float_edge, FloatEdge) -COMPUTED_STYLE_PROP(font_feature_settings, FontFeatureSettings) -COMPUTED_STYLE_PROP(font_language_override, FontLanguageOverride) COMPUTED_STYLE_PROP(force_broken_image_icon, ForceBrokenImageIcon) COMPUTED_STYLE_PROP(hyphens, Hyphens) COMPUTED_STYLE_PROP(image_region, ImageRegion) diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index d4ee5a763004..547b067db9de 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -3332,7 +3332,6 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext, systemFont.fontlist.SetDefaultFontType(eFamily_none); systemFont.style = fontStyle.style; systemFont.systemFont = fontStyle.systemFont; - systemFont.variant = NS_FONT_VARIANT_NORMAL; systemFont.weight = fontStyle.weight; systemFont.stretch = fontStyle.stretch; systemFont.decorations = NS_FONT_DECORATION_NONE; @@ -3456,14 +3455,6 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext, 0, 0, 0, systemFont.style); } - // font-variant: enum, inherit, initial, -moz-system-font - SetDiscrete(*aRuleData->ValueForFontVariant(), - aFont->mFont.variant, aCanStoreInRuleTree, - SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT | SETDSC_UNSET_INHERIT, - aParentFont->mFont.variant, - defaultVariableFont->variant, - 0, 0, 0, systemFont.variant); - // font-weight: int, enum, inherit, initial, -moz-system-font // special handling for enum const nsCSSValue* weightValue = aRuleData->ValueForFontWeight(); @@ -3647,15 +3638,15 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext, defaultVariableFont->variantEastAsian, 0, 0, 0, systemFont.variantEastAsian); - // font-variant-ligatures: normal, enum (bit field), inherit, initial, + // font-variant-ligatures: normal, none, enum (bit field), inherit, initial, // -moz-system-font SetDiscrete(*aRuleData->ValueForFontVariantLigatures(), aFont->mFont.variantLigatures, aCanStoreInRuleTree, - SETDSC_NORMAL | SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT | - SETDSC_UNSET_INHERIT, + SETDSC_NORMAL | SETDSC_NONE | SETDSC_ENUMERATED | + SETDSC_SYSTEM_FONT | SETDSC_UNSET_INHERIT, aParentFont->mFont.variantLigatures, defaultVariableFont->variantLigatures, - 0, 0, 0, systemFont.variantLigatures); + 0, NS_FONT_VARIANT_LIGATURES_NONE, 0, systemFont.variantLigatures); // font-variant-numeric: normal, enum (bit field), inherit, initial, // -moz-system-font diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 41bbf75b8561..f1224ac01253 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -494,11 +494,6 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_STYLE_FONT_STYLE_ITALIC NS_FONT_STYLE_ITALIC #define NS_STYLE_FONT_STYLE_OBLIQUE NS_FONT_STYLE_OBLIQUE -// See nsStyleFont -// We should eventually stop using the NS_STYLE_* variants here. -#define NS_STYLE_FONT_VARIANT_NORMAL NS_FONT_VARIANT_NORMAL -#define NS_STYLE_FONT_VARIANT_SMALL_CAPS NS_FONT_VARIANT_SMALL_CAPS - // See nsStyleFont // We should eventually stop using the NS_STYLE_* variants here. #define NS_STYLE_FONT_WEIGHT_NORMAL NS_FONT_WEIGHT_NORMAL diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index e90da88566ad..05251525f580 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -214,7 +214,6 @@ nsChangeHint nsStyleFont::CalcFontDifference(const nsFont& aFont1, const nsFont& if ((aFont1.size == aFont2.size) && (aFont1.sizeAdjust == aFont2.sizeAdjust) && (aFont1.style == aFont2.style) && - (aFont1.variant == aFont2.variant) && (aFont1.weight == aFont2.weight) && (aFont1.stretch == aFont2.stretch) && (aFont1.smoothing == aFont2.smoothing) && diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index fffa1421d270..4a6da740bf7b 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -2429,7 +2429,10 @@ var gCSSProperties = { domProp: "font", inherited: true, type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ "font-style", "font-variant", "font-weight", "font-size", "line-height", "font-family", "font-stretch", "font-size-adjust", "-moz-font-feature-settings", "-moz-font-language-override" ], + subproperties: [ "font-style", "font-variant", "font-weight", "font-size", "line-height", "font-family", "font-stretch", + "font-size-adjust", "font-feature-settings", "font-language-override", + "font-kerning", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", + "font-variant-ligatures", "font-variant-numeric", "font-variant-position" ], initial_values: [ (gInitialFontFamilyIsSansSerif ? "medium sans-serif" : "medium serif") ], other_values: [ "large serif", "9px fantasy", "bold italic small-caps 24px/1.4 Times New Roman, serif", "small inherit roman", "small roman inherit", // system fonts @@ -2447,8 +2450,8 @@ var gCSSProperties = { other_values: [ (gInitialFontFamilyIsSansSerif ? "serif" : "sans-serif"), "Times New Roman, serif", "'Times New Roman', serif", "cursive", "fantasy", "\\\"Times New Roman", "\"Times New Roman\"", "Times, \\\"Times New Roman", "Times, \"Times New Roman\"", "-no-such-font-installed", "inherit roman", "roman inherit", "Times, inherit roman", "inherit roman, Times", "roman inherit, Times", "Times, roman inherit" ], invalid_values: [ "\"Times New\" Roman", "\"Times New Roman\n", "Times, \"Times New Roman\n" ] }, - "-moz-font-feature-settings": { - domProp: "MozFontFeatureSettings", + "font-feature-settings": { + domProp: "fontFeatureSettings", inherited: true, type: CSS_TYPE_LONGHAND, initial_values: [ "normal" ], @@ -2466,8 +2469,16 @@ var gCSSProperties = { '"liga" 1 off', '"liga" on off', '"liga" , 0 "smcp"', '"liga" "smcp"' ] }, - "-moz-font-language-override": { - domProp: "MozFontLanguageOverride", + "font-kerning": { + domProp: "fontKerning", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "auto" ], + other_values: [ "normal", "none" ], + invalid_values: [ "on" ] + }, + "font-language-override": { + domProp: "fontLanguageOverride", inherited: true, type: CSS_TYPE_LONGHAND, initial_values: [ "normal" ], @@ -2519,13 +2530,94 @@ var gCSSProperties = { other_values: [ "italic", "oblique" ], invalid_values: [] }, + "font-synthesis": { + domProp: "fontSynthesis", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "weight style" ], + other_values: [ "none", "weight", "style" ], + invalid_values: [ "weight none", "style none", "none style", "weight 10px", "weight weight", "style style" ] + }, "font-variant": { domProp: "fontVariant", inherited: true, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position" ], + initial_values: [ "normal" ], + other_values: [ "small-caps", "none", "traditional oldstyle-nums", "all-small-caps", "common-ligatures no-discretionary-ligatures", + "proportional-nums oldstyle-nums", "proportional-nums slashed-zero diagonal-fractions oldstyle-nums ordinal", + "traditional historical-forms styleset(ok-alt-a, ok-alt-b)", "styleset(potato)" ], + invalid_values: [ "small-caps normal", "small-caps small-caps", "none common-ligatures", "common-ligatures none", "small-caps potato", + "small-caps jis83 all-small-caps", "super historical-ligatures sub", "stacked-fractions diagonal-fractions historical-ligatures", + "common-ligatures traditional common-ligatures", "lining-nums traditional slashed-zero ordinal normal", + "traditional historical-forms styleset(ok-alt-a, ok-alt-b) historical-forms", + "historical-forms styleset(ok-alt-a, ok-alt-b) traditional styleset(potato)", "annotation(a,b,c)" ] + }, + "font-variant-alternates": { + domProp: "fontVariantAlternates", + inherited: true, type: CSS_TYPE_LONGHAND, initial_values: [ "normal" ], - other_values: [ "small-caps" ], - invalid_values: [ "small-caps normal" ] + other_values: [ "historical-forms", + "styleset(alt-a, alt-b)", "character-variant(a, b, c)", "annotation(circled)", + "swash(squishy)", "styleset(complex\\ blob, a)", "annotation(\\62 lah)" ], + invalid_values: [ "historical-forms normal", "historical-forms historical-forms", + "swash", "swash(3)", "annotation(a, b)", "ornaments(a,b)", + "styleset(1234blah)", "annotation(a), annotation(b)", "annotation(a) normal" ] + }, + "font-variant-caps": { + domProp: "fontVariantCaps", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "titling-caps", "unicase" ], + invalid_values: [ "normal small-caps", "petite-caps normal", "unicase unicase" ] + }, + "font-variant-east-asian": { + domProp: "fontVariantEastAsian", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "jis78", "jis83", "jis90", "jis04", "simplified", "traditional", "full-width", "proportional-width", "ruby", + "jis78 full-width", "jis78 full-width ruby", "simplified proportional-width", "ruby simplified" ], + invalid_values: [ "jis78 normal", "jis90 jis04", "simplified traditional", "full-width proportional-width", + "ruby simplified ruby", "jis78 ruby simplified" ] + }, + "font-variant-ligatures": { + domProp: "fontVariantLigatures", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "none", "common-ligatures", "no-common-ligatures", "discretionary-ligatures", "no-discretionary-ligatures", + "historical-ligatures", "no-historical-ligatures", "contextual", "no-contextual", + "common-ligatures no-discretionary-ligatures", "contextual no-discretionary-ligatures", + "historical-ligatures no-common-ligatures", "no-historical-ligatures discretionary-ligatures", + "common-ligatures no-discretionary-ligatures historical-ligatures no-contextual" ], + invalid_values: [ "common-ligatures normal", "common-ligatures no-common-ligatures", "common-ligatures common-ligatures", + "no-historical-ligatures historical-ligatures", "no-discretionary-ligatures discretionary-ligatures", + "no-contextual contextual", "common-ligatures no-discretionary-ligatures no-common-ligatures", + "common-ligatures none", "no-discretionary-ligatures none", "none common-ligatures" ] + }, + "font-variant-numeric": { + domProp: "fontVariantNumeric", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "lining-nums", "oldstyle-nums", "proportional-nums", "tabular-nums", "diagonal-fractions", + "stacked-fractions", "slashed-zero", "ordinal", "lining-nums diagonal-fractions", + "tabular-nums stacked-fractions", "tabular-nums slashed-zero stacked-fractions", + "proportional-nums slashed-zero diagonal-fractions oldstyle-nums ordinal" ], + invalid_values: [ "lining-nums normal", "lining-nums oldstyle-nums", "lining-nums normal slashed-zero ordinal", + "proportional-nums tabular-nums", "diagonal-fractions stacked-fractions", "slashed-zero diagonal-fractions slashed-zero", + "lining-nums slashed-zero diagonal-fractions oldstyle-nums", "diagonal-fractions diagonal-fractions" ] + }, + "font-variant-position": { + domProp: "fontVariantPosition", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "super", "sub" ], + invalid_values: [ "normal sub", "super sub" ] }, "font-weight": { domProp: "fontWeight", @@ -4334,6 +4426,37 @@ var gCSSProperties = { initial_values: [ "ease", "cubic-bezier(0.25, 0.1, 0.25, 1.0)" ], other_values: [ "linear", "ease-in", "ease-out", "ease-in-out", "linear, ease-in, cubic-bezier(0.1, 0.2, 0.8, 0.9)", "cubic-bezier(0.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.25, 1.5, 0.75, -0.5)", "step-start", "step-end", "steps(1)", "steps(2, start)", "steps(386)", "steps(3, end)" ], invalid_values: [ "none", "auto", "cubic-bezier(0.25, 0.1, 0.25)", "cubic-bezier(0.25, 0.1, 0.25, 0.25, 1.0)", "cubic-bezier(-0.5, 0.5, 0.5, 0.5)", "cubic-bezier(1.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.5, 0.5, -0.5, 0.5)", "cubic-bezier(0.5, 0.5, 1.5, 0.5)", "steps(2, step-end)", "steps(0)", "steps(-2)", "steps(0, step-end, 1)" ] + }, + "-moz-font-feature-settings": { + domProp: "MozFontFeatureSettings", + inherited: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + alias_for: "font-feature-settings", + subproperties: [ "font-feature-settings" ], + initial_values: [ "normal" ], + other_values: [ + "'liga' on", "'liga'", "\"liga\" 1", "'liga', 'clig' 1", + "\"liga\" off", "\"liga\" 0", '"cv01" 3, "cv02" 4', + '"cswh", "smcp" off, "salt" 4', '"cswh" 1, "smcp" off, "salt" 4', + '"cswh" 0, \'blah\', "liga", "smcp" off, "salt" 4', + '"liga" ,"smcp" 0 , "blah"' + ], + invalid_values: [ + 'liga', 'liga 1', 'liga normal', '"liga" normal', 'normal liga', + 'normal "liga"', 'normal, "liga"', '"liga=1"', "'foobar' on", + '"blahblah" 0', '"liga" 3.14', '"liga" 1 3.14', '"liga" 1 normal', + '"liga" 1 off', '"liga" on off', '"liga" , 0 "smcp"', '"liga" "smcp"' + ] + }, + "-moz-font-language-override": { + domProp: "MozFontLanguageOverride", + inherited: true, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + alias_for: "font-language-override", + subproperties: [ "font-language-override" ], + initial_values: [ "normal" ], + other_values: [ "'ENG'", "'TRK'", "\"TRK\"", "'N\\'Ko'" ], + invalid_values: [ "TRK", "ja" ] } } @@ -4423,130 +4546,6 @@ if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) { } } -if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) { - var fontFeatureProperties = { - "font-kerning": { - domProp: "fontKerning", - inherited: true, - type: CSS_TYPE_LONGHAND, - initial_values: [ "auto" ], - other_values: [ "normal", "none" ], - invalid_values: [ "on" ] - }, - "font-variant-alternates": { - domProp: "fontVariantAlternates", - inherited: true, - type: CSS_TYPE_LONGHAND, - initial_values: [ "normal" ], - other_values: [ "historical-forms", - "styleset(alt-a, alt-b)", "character-variant(a, b, c)", "annotation(circled)", - "swash(squishy)", "styleset(complex\\ blob, a)", "annotation(\\62 lah)" ], - invalid_values: [ "historical-forms normal", "historical-forms historical-forms", - "swash", "swash(3)", "annotation(a, b)", "ornaments(a,b)", - "styleset(1234blah)", "annotation(a), annotation(b)", "annotation(a) normal" ] - }, - "font-variant-caps": { - domProp: "fontVariantCaps", - inherited: true, - type: CSS_TYPE_LONGHAND, - initial_values: [ "normal" ], - other_values: [ "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "titling-caps", "unicase" ], - invalid_values: [ "normal small-caps", "petite-caps normal", "unicase unicase" ] - }, - "font-variant-east-asian": { - domProp: "fontVariantEastAsian", - inherited: true, - type: CSS_TYPE_LONGHAND, - initial_values: [ "normal" ], - other_values: [ "jis78", "jis83", "jis90", "jis04", "simplified", "traditional", "full-width", "proportional-width", "ruby", - "jis78 full-width", "jis78 full-width ruby", "simplified proportional-width", "ruby simplified" ], - invalid_values: [ "jis78 normal", "jis90 jis04", "simplified traditional", "full-width proportional-width", - "ruby simplified ruby", "jis78 ruby simplified" ] - }, - "font-variant-ligatures": { - domProp: "fontVariantLigatures", - inherited: true, - type: CSS_TYPE_LONGHAND, - initial_values: [ "normal" ], - other_values: [ "none", "common-ligatures", "no-common-ligatures", "discretionary-ligatures", "no-discretionary-ligatures", - "historical-ligatures", "no-historical-ligatures", "contextual", "no-contextual", - "common-ligatures no-discretionary-ligatures", "contextual no-discretionary-ligatures", - "historical-ligatures no-common-ligatures", "no-historical-ligatures discretionary-ligatures", - "common-ligatures no-discretionary-ligatures historical-ligatures no-contextual" ], - invalid_values: [ "common-ligatures normal", "common-ligatures no-common-ligatures", "common-ligatures common-ligatures", - "no-historical-ligatures historical-ligatures", "no-discretionary-ligatures discretionary-ligatures", - "no-contextual contextual", "common-ligatures no-discretionary-ligatures no-common-ligatures", - "common-ligatures none", "no-discretionary-ligatures none", "none common-ligatures" ] - }, - "font-variant-numeric": { - domProp: "fontVariantNumeric", - inherited: true, - type: CSS_TYPE_LONGHAND, - initial_values: [ "normal" ], - other_values: [ "lining-nums", "oldstyle-nums", "proportional-nums", "tabular-nums", "diagonal-fractions", - "stacked-fractions", "slashed-zero", "ordinal", "lining-nums diagonal-fractions", - "tabular-nums stacked-fractions", "tabular-nums slashed-zero stacked-fractions", - "proportional-nums slashed-zero diagonal-fractions oldstyle-nums ordinal" ], - invalid_values: [ "lining-nums normal", "lining-nums oldstyle-nums", "lining-nums normal slashed-zero ordinal", - "proportional-nums tabular-nums", "diagonal-fractions stacked-fractions", "slashed-zero diagonal-fractions slashed-zero", - "lining-nums slashed-zero diagonal-fractions oldstyle-nums", "diagonal-fractions diagonal-fractions" ] - }, - "font-variant-position": { - domProp: "fontVariantPosition", - inherited: true, - type: CSS_TYPE_LONGHAND, - initial_values: [ "normal" ], - other_values: [ "super", "sub" ], - invalid_values: [ "normal sub", "super sub" ] - }, - "font-synthesis": { - domProp: "fontSynthesis", - inherited: true, - type: CSS_TYPE_LONGHAND, - initial_values: [ "weight style" ], - other_values: [ "none", "weight", "style" ], - invalid_values: [ "weight none", "style none", "none style", "weight 10px", "weight weight", "style style" ] - }, - // aliases for prefixed properties - "font-feature-settings": { - domProp: "fontFeatureSettings", - inherited: true, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-font-feature-settings", - subproperties: [ "-moz-font-feature-settings" ], - initial_values: [ "normal" ], - other_values: [ - "'liga' on", "'liga'", "\"liga\" 1", "'liga', 'clig' 1", - "\"liga\" off", "\"liga\" 0", '"cv01" 3, "cv02" 4', - '"cswh", "smcp" off, "salt" 4', '"cswh" 1, "smcp" off, "salt" 4', - '"cswh" 0, \'blah\', "liga", "smcp" off, "salt" 4', - '"liga" ,"smcp" 0 , "blah"' - ], - invalid_values: [ - 'liga', 'liga 1', 'liga normal', '"liga" normal', 'normal liga', - 'normal "liga"', 'normal, "liga"', '"liga=1"', "'foobar' on", - '"blahblah" 0', '"liga" 3.14', '"liga" 1 3.14', '"liga" 1 normal', - '"liga" 1 off', '"liga" on off', '"liga" , 0 "smcp"', '"liga" "smcp"' - ] - }, - "font-language-override": { - domProp: "fontLanguageOverride", - inherited: true, - type: CSS_TYPE_SHORTHAND_AND_LONGHAND, - alias_for: "-moz-font-language-override", - subproperties: [ "-moz-font-language-override" ], - initial_values: [ "normal" ], - other_values: [ "'ENG'", "'TRK'", "\"TRK\"", "'N\\'Ko'" ], - invalid_values: [ "TRK", "ja" ] - } - }; - for (var prop in fontFeatureProperties) { - gCSSProperties[prop] = fontFeatureProperties[prop]; - } - var fontAdditions = [ "font-kerning", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position" ]; - gCSSProperties["font"].subproperties = gCSSProperties["font"].subproperties.concat(fontAdditions); -} - if (SpecialPowers.getBoolPref("layout.css.masking.enabled")) { gCSSProperties["mask-type"] = { domProp: "maskType", diff --git a/layout/style/test/test_bug377947.html b/layout/style/test/test_bug377947.html index 2bcea156fa69..00946bf2fe6e 100644 --- a/layout/style/test/test_bug377947.html +++ b/layout/style/test/test_bug377947.html @@ -58,24 +58,18 @@ var all_but_one = { "font-size": "small", "font-size-adjust": "none", // has to be default value "font-stretch": "normal", // has to be default value - "-moz-font-feature-settings": "normal", // has to be default value - "-moz-font-language-override": "normal" // has to be default value + "font-feature-settings": "normal", // has to be default value + "font-language-override": "normal", // has to be default value + "font-kerning": "auto", // has to be default value + "font-synthesis": "weight style", // has to be default value + "font-variant-alternates": "normal", // has to be default value + "font-variant-caps": "normal", // has to be default value + "font-variant-east-asian": "normal", // has to be default value + "font-variant-ligatures": "normal", // has to be default value + "font-variant-numeric": "normal", // has to be default value + "font-variant-position": "normal" // has to be default value }; -if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) { - var featureDefs = { - "font-kerning": "auto", // has to be default value - "font-synthesis": "weight style", // has to be default value - "font-variant-alternates": "normal", // has to be default value - "font-variant-caps": "normal", // has to be default value - "font-variant-east-asian": "normal", // has to be default value - "font-variant-ligatures": "normal", // has to be default value - "font-variant-numeric": "normal", // has to be default value - "font-variant-position": "normal" // has to be default value - }; - for (var prop in featureDefs) { - all_but_one[prop] = featureDefs[prop]; - } -} + for (var prop in all_but_one) { s.setProperty(prop, all_but_one[prop], ""); } diff --git a/layout/style/test/test_bug892929.html b/layout/style/test/test_bug892929.html index 4868dac0017d..a67db56ee32f 100644 --- a/layout/style/test/test_bug892929.html +++ b/layout/style/test/test_bug892929.html @@ -5,7 +5,7 @@ Bug 892929 test - +