diff --git a/.taskcluster.yml b/.taskcluster.yml new file mode 100644 index 000000000000..5afaed0ae775 --- /dev/null +++ b/.taskcluster.yml @@ -0,0 +1,118 @@ +--- +version: 0 +metadata: + name: 'Taskcluster tasks for Gecko' + description: "The taskcluster task graph for Gecko trees" + owner: mozilla-taskcluster-maintenance@mozilla.com + source: {{{source}}} + +scopes: + # Note the below scopes are insecure however these get overriden on the server + # side to whatever scopes are set by mozilla-taskcluster. + - queue:* + - docker-worker:* + - scheduler:* + +# Available mustache parameters (see the mozilla-taskcluster source): +# +# - owner: push user (email address) +# - source: URL of this YAML file +# - url: repository URL +# - project: alias for the destination repository (basename of +# the repo url) +# - level: SCM level of the destination repository +# (1 = try, 3 = core) +# - revision: (short) hg revision of the head of the push +# - revision_hash: (long) hg revision of the head of the push +# - comment: comment of the push +# - pushlog_id: id in the pushlog table of the repository +# +# and functions: +# - as_slugid: convert a label into a slugId +# - from_now: generate a timestamp at a fixed offset from now + +tasks: + - taskId: '{{#as_slugid}}decision task{{/as_slugid}}' + reruns: 3 + task: + created: '{{now}}' + deadline: '{{#from_now}}1 day{{/from_now}}' + expires: '{{#from_now}}14 day{{/from_now}}' + metadata: + owner: mozilla-taskcluster-maintenance@mozilla.com + source: {{{source}}} + name: "Gecko Decision Task" + description: | + The task that creates all of the other tasks in the task graph + + workerType: "gecko-decision" + provisionerId: "aws-provisioner-v1" + + tags: + createdForUser: {{owner}} + + scopes: + # Bug 1269443: cache scopes, etc. must be listed explicitly + - "docker-worker:cache:level-1-*" + - "docker-worker:cache:tooltool-cache" + - "secrets:get:project/taskcluster/gecko/hgfingerprint" + - "assume:repo:hg.mozilla.org/try:*" + + routes: + - "index.gecko.v2.{{project}}.latest.firefox.decision" + - "tc-treeherder.{{project}}.{{revision_hash}}" + - "tc-treeherder-stage.{{project}}.{{revision_hash}}" + + payload: + env: + # checkout-gecko uses these to check out the source; the inputs + # to `mach taskgraph decision` are all on the command line. + GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-central' + GECKO_HEAD_REPOSITORY: '{{{url}}}' + GECKO_HEAD_REF: '{{revision}}' + GECKO_HEAD_REV: '{{revision}}' + + cache: + level-{{level}}-{{project}}-tc-vcs-public-sources: /home/worker/.tc-vcs/ + level-{{level}}-{{project}}-gecko-decision: /home/worker/workspace + + features: + taskclusterProxy: true + + # Note: This task is built server side without the context or tooling that + # exist in tree so we must hard code the version + image: 'taskcluster/decision:0.1.0' + + maxRunTime: 1800 + + command: + - /bin/bash + - -cx + - > + mkdir -p /home/worker/artifacts && + checkout-gecko workspace && + cd workspace/gecko && + ln -s /home/worker/artifacts artifacts && + ./mach taskgraph decision + --pushlog-id='{{pushlog_id}}' + --project='{{project}}' + --message='{{comment}}' + --owner='{{owner}}' + --level='{{level}}' + --base-repository='https://hg.mozilla.org/mozilla-central' + --head-repository='{{{url}}}' + --head-ref='{{revision}}' + --head-rev='{{revision}}' + --revision-hash='{{revision_hash}}' + + artifacts: + 'public': + type: 'directory' + path: '/home/worker/artifacts' + expires: '{{#from_now}}7 days{{/from_now}}' + + extra: + treeherder: + symbol: D + revision: '{{revision}}' + revision_hash: '{{revision_hash}}' diff --git a/accessible/generic/DocAccessible-inl.h b/accessible/generic/DocAccessible-inl.h index cf7e0758de16..89c02852d92b 100644 --- a/accessible/generic/DocAccessible-inl.h +++ b/accessible/generic/DocAccessible-inl.h @@ -170,6 +170,17 @@ DocAccessible::CreateSubtree(Accessible* aChild) Accessible* focusedAcc = nullptr; CacheChildrenInSubtree(aChild, &focusedAcc); + // Fire events for ARIA elements. + if (aChild->HasARIARole()) { + roles::Role role = aChild->ARIARole(); + if (role == roles::MENUPOPUP) { + FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aChild); + } + else if (role == roles::ALERT) { + FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aChild); + } + } + // XXX: do we really want to send focus to focused DOM node not taking into // account active item? if (focusedAcc) { diff --git a/accessible/generic/DocAccessible.cpp b/accessible/generic/DocAccessible.cpp index e69de69e7403..66d87c5208a6 100644 --- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -2181,19 +2181,9 @@ DocAccessible::CacheChildrenInSubtree(Accessible* aRoot, return; } - roles::Role role = aRoot->ARIARole(); - if (role == roles::MENUPOPUP) { - FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aRoot); - return; - } - - if (role == roles::ALERT) { - FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aRoot); - return; - } - // XXX: we should delay document load complete event if the ARIA document // has aria-busy. + roles::Role role = aRoot->ARIARole(); if (!aRoot->IsDoc() && (role == roles::DIALOG || role == roles::DOCUMENT)) { FireDelayedEvent(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE, aRoot); } diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 14d03fcc0ae3..2c4ec55e094e 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -4030,8 +4030,11 @@ function openNewUserContextTab(event) */ function updateUserContextUIVisibility() { - let userContextEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled"); - document.getElementById("menu_newUserContext").hidden = !userContextEnabled; + let menu = document.getElementById("menu_newUserContext"); + menu.hidden = !Services.prefs.getBoolPref("privacy.userContext.enabled"); + if (PrivateBrowsingUtils.isWindowPrivate(window)) { + menu.setAttribute("disabled", "true"); + } } /** diff --git a/browser/base/content/nsContextMenu.js b/browser/base/content/nsContextMenu.js index fd2592439a12..ab84d5103b68 100644 --- a/browser/base/content/nsContextMenu.js +++ b/browser/base/content/nsContextMenu.js @@ -149,7 +149,7 @@ nsContextMenu.prototype = { this.showItem("context-openlink", shouldShow && !isWindowPrivate); this.showItem("context-openlinkprivate", shouldShow); this.showItem("context-openlinkintab", shouldShow); - this.showItem("context-openlinkinusercontext-menu", shouldShow && showContainers); + this.showItem("context-openlinkinusercontext-menu", shouldShow && !isWindowPrivate && showContainers); this.showItem("context-openlinkincurrent", this.onPlainTextLink); this.showItem("context-sep-open", shouldShow); }, diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 044ddc2107cb..f1eb34625d41 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -6604,7 +6604,12 @@ let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled"); document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled; - document.getElementById("alltabs_containersTab").hidden = !containersEnabled; + let containersTab = document.getElementById("alltabs_containersTab"); + + containersTab.hidden = !containersEnabled; + if (PrivateBrowsingUtils.isWindowPrivate(window)) { + containersTab.setAttribute("disabled", "true"); + } document.getElementById("alltabs_undoCloseTab").disabled = SessionStore.getClosedTabCount(window) == 0; diff --git a/browser/components/contextualidentity/ContextualIdentityService.jsm b/browser/components/contextualidentity/ContextualIdentityService.jsm index 8febe216a488..bc743031f164 100644 --- a/browser/components/contextualidentity/ContextualIdentityService.jsm +++ b/browser/components/contextualidentity/ContextualIdentityService.jsm @@ -26,7 +26,7 @@ this.ContextualIdentityService = { label: "userContextWork.label", accessKey: "userContextWork.accesskey" }, { userContextId: 3, - icon: "chome://browser/skin/usercontext/banking.svg", + icon: "chrome://browser/skin/usercontext/banking.svg", color: "#7dc14c", label: "userContextBanking.label", accessKey: "userContextBanking.accesskey" }, diff --git a/browser/components/customizableui/CustomizableWidgets.jsm b/browser/components/customizableui/CustomizableWidgets.jsm index a8b1a7a6aa47..8fe86b778eee 100644 --- a/browser/components/customizableui/CustomizableWidgets.jsm +++ b/browser/components/customizableui/CustomizableWidgets.jsm @@ -1116,6 +1116,10 @@ if (Services.prefs.getBoolPref("privacy.userContext.enabled")) { win.openUILinkIn(win.BROWSER_NEW_TAB_URL, "tab", {userContextId}); }; items.addEventListener("command", onItemCommand); + + if (PrivateBrowsingUtils.isWindowPrivate(win)) { + aNode.setAttribute("disabled", "true"); + } }, onViewShowing: function(aEvent) { let doc = aEvent.detail.ownerDocument; diff --git a/browser/components/uitour/UITour.jsm b/browser/components/uitour/UITour.jsm index 036bbc14b4aa..c80df0e9fcf4 100644 --- a/browser/components/uitour/UITour.jsm +++ b/browser/components/uitour/UITour.jsm @@ -622,7 +622,9 @@ this.UITour = { case "resetFirefox": { // Open a reset profile dialog window. - ResetProfile.openConfirmationDialog(window); + if (ResetProfile.resetSupported()) { + ResetProfile.openConfirmationDialog(window); + } break; } @@ -1939,6 +1941,9 @@ this.UITour = { setup: Services.prefs.prefHasUserValue("services.sync.username"), }); break; + case "canReset": + this.sendPageCallback(aMessageManager, aCallbackID, ResetProfile.resetSupported()); + break; default: log.error("getConfiguration: Unknown configuration requested: " + aConfiguration); break; diff --git a/browser/components/uitour/test/browser_UITour_resetProfile.js b/browser/components/uitour/test/browser_UITour_resetProfile.js index 00f59eff9646..c91d0a4f270f 100644 --- a/browser/components/uitour/test/browser_UITour_resetProfile.js +++ b/browser/components/uitour/test/browser_UITour_resetProfile.js @@ -8,6 +8,8 @@ add_task(setup_UITourTest); // Test that a reset profile dialog appears when "resetFirefox" event is triggered add_UITour_task(function* test_resetFirefox() { + let canReset = yield getConfigurationPromise("canReset"); + ok(!canReset, "Shouldn't be able to reset from mochitest's temporary profile."); let dialogPromise = new Promise((resolve) => { let winWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"]. getService(Ci.nsIWindowWatcher); @@ -28,7 +30,19 @@ add_UITour_task(function* test_resetFirefox() { } }); }); + + // make reset possible. + let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]. + getService(Ci.nsIToolkitProfileService); + let currentProfileDir = Services.dirsvc.get("ProfD", Ci.nsIFile); + let profileName = "mochitest-test-profile-temp-" + Date.now(); + let tempProfile = profileService.createProfile(currentProfileDir, profileName); + canReset = yield getConfigurationPromise("canReset"); + ok(canReset, "Should be able to reset from mochitest's temporary profile once it's in the profile manager."); yield gContentAPI.resetFirefox(); yield dialogPromise; + tempProfile.remove(false); + canReset = yield getConfigurationPromise("canReset"); + ok(!canReset, "Shouldn't be able to reset from mochitest's temporary profile once removed from the profile manager."); }); diff --git a/build/autoconf/android.m4 b/build/autoconf/android.m4 index ac223077a07f..58a70d59c7db 100644 --- a/build/autoconf/android.m4 +++ b/build/autoconf/android.m4 @@ -9,7 +9,7 @@ MOZ_ARG_WITH_STRING(android-cxx-stl, [ --with-android-cxx-stl=VALUE use the specified C++ STL (stlport, libstdc++, libc++)], android_cxx_stl=$withval, - android_cxx_stl=mozstlport) + android_cxx_stl=libc++) define([MIN_ANDROID_VERSION], [9]) android_version=MIN_ANDROID_VERSION diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 19eecf318cf1..d140c0fbfd88 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -5230,24 +5230,21 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL, // Create a URL to pass all the error information through to the page. #undef SAFE_ESCAPE -#define SAFE_ESCAPE(cstring, escArg1, escArg2) \ - { \ - char* s = nsEscape(escArg1, escArg2); \ - if (!s) \ - return NS_ERROR_OUT_OF_MEMORY; \ - cstring.Adopt(s); \ +#define SAFE_ESCAPE(output, input, params) \ + if (NS_WARN_IF(!NS_Escape(input, output, params))) { \ + return NS_ERROR_OUT_OF_MEMORY; \ } nsCString escapedUrl, escapedCharset, escapedError, escapedDescription, escapedCSSClass; - SAFE_ESCAPE(escapedUrl, url.get(), url_Path); - SAFE_ESCAPE(escapedCharset, charset.get(), url_Path); - SAFE_ESCAPE(escapedError, - NS_ConvertUTF16toUTF8(aErrorType).get(), url_Path); + SAFE_ESCAPE(escapedUrl, url, url_Path); + SAFE_ESCAPE(escapedCharset, charset, url_Path); + SAFE_ESCAPE(escapedError, NS_ConvertUTF16toUTF8(aErrorType), url_Path); SAFE_ESCAPE(escapedDescription, - NS_ConvertUTF16toUTF8(aDescription).get(), url_Path); + NS_ConvertUTF16toUTF8(aDescription), url_Path); if (aCSSClass) { - SAFE_ESCAPE(escapedCSSClass, aCSSClass, url_Path); + nsCString cssClass(aCSSClass); + SAFE_ESCAPE(escapedCSSClass, cssClass, url_Path); } nsCString errorPageUrl("about:"); errorPageUrl.AppendASCII(aErrorPage); @@ -5276,9 +5273,7 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL, nsresult rv = GetAppManifestURL(manifestURL); if (manifestURL.Length() > 0) { nsCString manifestParam; - SAFE_ESCAPE(manifestParam, - NS_ConvertUTF16toUTF8(manifestURL).get(), - url_Path); + SAFE_ESCAPE(manifestParam, NS_ConvertUTF16toUTF8(manifestURL), url_Path); errorPageUrl.AppendLiteral("&m="); errorPageUrl.AppendASCII(manifestParam.get()); } diff --git a/dom/animation/test/chrome/test_animation_performance_warning.html b/dom/animation/test/chrome/test_animation_performance_warning.html index 72448917d8a2..62e331868829 100644 --- a/dom/animation/test/chrome/test_animation_performance_warning.html +++ b/dom/animation/test/chrome/test_animation_performance_warning.html @@ -172,50 +172,69 @@ var gAnimationsTests = [ } ] }, +]; + +// Test cases that check results of adding/removing a 'width' property on the +// same animation object. +var gAnimationWithGeometricKeyframeTests = [ { - // FIXME: Once we have KeyframeEffect.setFrames, we should rewrite - // this test case to check that runningOnCompositor is restored to true - // after 'width' keyframe is removed from the keyframes. - desc: 'transform on compositor with animation of geometric properties', + desc: 'transform', frames: { - width: ['100px', '200px'], transform: ['translate(0px)', 'translate(100px)'] }, - expected: [ - { - property: 'width', - runningOnCompositor: false - }, - { - property: 'transform', - runningOnCompositor: false, - warning: 'AnimationWarningTransformWithGeometricProperties' - } - ] + expected: { + withoutGeometric: [ + { + property: 'transform', + runningOnCompositor: true + } + ], + withGeometric: [ + { + property: 'width', + runningOnCompositor: false + }, + { + property: 'transform', + runningOnCompositor: false, + warning: 'AnimationWarningTransformWithGeometricProperties' + } + ] + } }, { - desc: 'opacity and transform on compositor with animation of geometric ' + - 'properties', + desc: 'opacity and transform', frames: { - width: ['100px', '200px'], opacity: [0, 1], transform: ['translate(0px)', 'translate(100px)'] }, - expected: [ - { - property: 'width', - runningOnCompositor: false - }, - { - property: 'opacity', - runningOnCompositor: true - }, - { - property: 'transform', - runningOnCompositor: false, - warning: 'AnimationWarningTransformWithGeometricProperties' - } - ] + expected: { + withoutGeometric: [ + { + property: 'opacity', + runningOnCompositor: true + }, + { + property: 'transform', + runningOnCompositor: true + } + ], + withGeometric: [ + { + property: 'width', + runningOnCompositor: false + }, + { + property: 'opacity', + runningOnCompositor: true + }, + { + property: 'transform', + runningOnCompositor: false, + warning: 'AnimationWarningTransformWithGeometricProperties' + } + ] + } }, ]; @@ -349,75 +368,106 @@ var gMultipleAsyncAnimationsTests = [ }, ]; -// FIXME: Once we have KeyframeEffect.setFrames, we should rewrite -// these test cases to check that runningOnCompositor is restored to true -// after 'width' keyframe is removed from the keyframes. +// Test cases that check results of adding/removing a 'width' keyframe on the +// same animation object, where multiple animation objects belong to the same +// element. +// The 'width' property is added to animations[1]. var gMultipleAsyncAnimationsWithGeometricKeyframeTests = [ { - desc: 'transform and opacity with animation of geometric properties', + desc: 'transform and opacity with geometric keyframes', animations: [ { frames: { transform: ['translate(0px)', 'translate(100px)'] }, - expected: [ - { - property: 'transform', - runningOnCompositor: false, - warning: 'AnimationWarningTransformWithGeometricProperties' - } - ] + expected: { + withoutGeometric: [ + { + property: 'transform', + runningOnCompositor: true + } + ], + withGeometric: [ + { + property: 'transform', + runningOnCompositor: false, + warning: 'AnimationWarningTransformWithGeometricProperties' + } + ] + } }, { frames: { - width: ['100px', '200px'], opacity: [0, 1] }, - expected: [ - { - property: 'width', - runningOnCompositor: false, - }, - { - property: 'opacity', - runningOnCompositor: true, - } - ] + expected: { + withoutGeometric: [ + { + property: 'opacity', + runningOnCompositor: true, + } + ], + withGeometric: [ + { + property: 'width', + runningOnCompositor: false, + }, + { + property: 'opacity', + runningOnCompositor: true, + } + ] + } } ], }, { - desc: 'opacity and transform with animation of geometric properties', + desc: 'opacity and transform with geometric keyframes', animations: [ - { - frames: { - width: ['100px', '200px'], - transform: ['translate(0px)', 'translate(100px)'] - }, - expected: [ - { - property: 'width', - runningOnCompositor: false, - }, - { - property: 'transform', - runningOnCompositor: false, - warning: 'AnimationWarningTransformWithGeometricProperties' - } - ] - }, { frames: { opacity: [0, 1] }, - expected: [ - { - property: 'opacity', - runningOnCompositor: true, - } - ] + expected: { + withoutGeometric: [ + { + property: 'opacity', + runningOnCompositor: true, + } + ], + withGeometric: [ + { + property: 'opacity', + runningOnCompositor: true, + } + ] + } + }, + { + frames: { + transform: ['translate(0px)', 'translate(100px)'] + }, + expected: { + withoutGeometric: [ + { + property: 'transform', + runningOnCompositor: true + } + ], + withGeometric: [ + { + property: 'width', + runningOnCompositor: false, + }, + { + property: 'transform', + runningOnCompositor: false, + warning: 'AnimationWarningTransformWithGeometricProperties' + } + ] + } } - ], + ] }, ]; @@ -544,6 +594,49 @@ function start() { }, subtest.desc); }); + gAnimationWithGeometricKeyframeTests.forEach(function(subtest) { + promise_test(function(t) { + var animation = addDivAndAnimate(t, + { class: 'compositable' }, + subtest.frames, 100 * MS_PER_SEC); + return animation.ready.then(function() { + // First, a transform animation is running on compositor. + assert_animation_property_state_equals( + animation.effect.getProperties(), + subtest.expected.withoutGeometric); + }).then(function() { + // Add a 'width' property. + var keyframes = animation.effect.getKeyframes(); + + keyframes[0].width = '100px'; + keyframes[1].width = '200px'; + + animation.effect.setKeyframes(keyframes); + return waitForFrame(); + }).then(function() { + // Now the transform animation is not running on compositor because of + // the 'width' property. + assert_animation_property_state_equals( + animation.effect.getProperties(), + subtest.expected.withGeometric); + }).then(function() { + // Remove the 'width' property. + var keyframes = animation.effect.getKeyframes(); + + delete keyframes[0].width; + delete keyframes[1].width; + + animation.effect.setKeyframes(keyframes); + return waitForFrame(); + }).then(function() { + // Finally, the transform animation is running on compositor. + assert_animation_property_state_equals( + animation.effect.getProperties(), + subtest.expected.withoutGeometric); + }); + }, 'An animation has: ' + subtest.desc); + }); + gPerformanceWarningTests.forEach(function(subtest) { promise_test(function(t) { var animation = addDivAndAnimate(t, @@ -616,10 +709,44 @@ function start() { return animation; }); return waitForAllAnimations(animations).then(function() { + // First, all animations are running on compositor. animations.forEach(function(anim) { assert_animation_property_state_equals( anim.effect.getProperties(), - anim.expected); + anim.expected.withoutGeometric); + }); + }).then(function() { + // Add a 'width' property to animations[1]. + var keyframes = animations[1].effect.getKeyframes(); + + keyframes[0].width = '100px'; + keyframes[1].width = '200px'; + + animations[1].effect.setKeyframes(keyframes); + return waitForFrame(); + }).then(function() { + // Now the transform animation is not running on compositor because of + // the 'width' property. + animations.forEach(function(anim) { + assert_animation_property_state_equals( + anim.effect.getProperties(), + anim.expected.withGeometric); + }); + }).then(function() { + // Remove the 'width' property from animations[1]. + var keyframes = animations[1].effect.getKeyframes(); + + delete keyframes[0].width; + delete keyframes[1].width; + + animations[1].effect.setKeyframes(keyframes); + return waitForFrame(); + }).then(function() { + // Finally, all animations are running on compositor. + animations.forEach(function(anim) { + assert_animation_property_state_equals( + anim.effect.getProperties(), + anim.expected.withoutGeometric); }); }); }, 'Multiple animations with geometric property: ' + subtest.desc); diff --git a/dom/animation/test/mochitest.ini b/dom/animation/test/mochitest.ini index 63ad6c17b390..a14062027bb9 100644 --- a/dom/animation/test/mochitest.ini +++ b/dom/animation/test/mochitest.ini @@ -39,6 +39,8 @@ support-files = mozilla/file_disabled_properties.html mozilla/file_hide_and_show.html mozilla/file_partial_keyframes.html + style/file_animation-seeking-with-current-time.html + style/file_animation-seeking-with-start-time.html testcommon.js [css-animations/test_animations-dynamic-changes.html] @@ -82,3 +84,5 @@ skip-if = (toolkit == 'gonk' && debug) [mozilla/test_disabled_properties.html] [mozilla/test_hide_and_show.html] [mozilla/test_partial_keyframes.html] +[style/test_animation-seeking-with-current-time.html] +[style/test_animation-seeking-with-start-time.html] diff --git a/dom/animation/test/style/file_animation-seeking-with-current-time.html b/dom/animation/test/style/file_animation-seeking-with-current-time.html new file mode 100644 index 000000000000..c3a5903948ec --- /dev/null +++ b/dom/animation/test/style/file_animation-seeking-with-current-time.html @@ -0,0 +1,121 @@ + + + + + Tests for seeking using Animation.currentTime + + + + + + + diff --git a/dom/animation/test/style/file_animation-seeking-with-start-time.html b/dom/animation/test/style/file_animation-seeking-with-start-time.html new file mode 100644 index 000000000000..ba09827c6303 --- /dev/null +++ b/dom/animation/test/style/file_animation-seeking-with-start-time.html @@ -0,0 +1,121 @@ + + + + + Tests for seeking using Animation.startTime + + + + + + + diff --git a/dom/animation/test/style/test_animation-seeking-with-current-time.html b/dom/animation/test/style/test_animation-seeking-with-current-time.html new file mode 100644 index 000000000000..386e57788644 --- /dev/null +++ b/dom/animation/test/style/test_animation-seeking-with-current-time.html @@ -0,0 +1,15 @@ + + + + +
+ + diff --git a/dom/animation/test/style/test_animation-seeking-with-start-time.html b/dom/animation/test/style/test_animation-seeking-with-start-time.html new file mode 100644 index 000000000000..0a1691a0827d --- /dev/null +++ b/dom/animation/test/style/test_animation-seeking-with-start-time.html @@ -0,0 +1,15 @@ + + + + +
+ + diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index d358fb373977..c6b9de4fcd37 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -2181,6 +2181,13 @@ GK_ATOM(TypingTxnName, "Typing") GK_ATOM(IMETxnName, "IME") GK_ATOM(DeleteTxnName, "Deleting") +// Font families +GK_ATOM(serif, "serif") +GK_ATOM(sans_serif, "sans-serif") +GK_ATOM(cursive, "cursive") +GK_ATOM(fantasy, "fantasy") +GK_ATOM(monospace, "monospace") + // IPC stuff GK_ATOM(Remote, "remote") GK_ATOM(RemoteId, "_remote_id") @@ -2433,3 +2440,15 @@ GK_ATOM(vr_state, "vr-state") // Contextual Identity / Containers GK_ATOM(usercontextid, "usercontextid") + +// Namespaces +GK_ATOM(nsuri_xmlns, "http://www.w3.org/2000/xmlns/") +GK_ATOM(nsuri_xml, "http://www.w3.org/XML/1998/namespace") +GK_ATOM(nsuri_xhtml, "http://www.w3.org/1999/xhtml") +GK_ATOM(nsuri_xlink, "http://www.w3.org/1999/xlink") +GK_ATOM(nsuri_xslt, "http://www.w3.org/1999/XSL/Transform") +GK_ATOM(nsuri_xbl, "http://www.mozilla.org/xbl") +GK_ATOM(nsuri_mathml, "http://www.w3.org/1998/Math/MathML") +GK_ATOM(nsuri_rdf, "http://www.w3.org/1999/02/22-rdf-syntax-ns#") +GK_ATOM(nsuri_xul, "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") +GK_ATOM(nsuri_svg, "http://www.w3.org/2000/svg") diff --git a/dom/base/nsNameSpaceManager.cpp b/dom/base/nsNameSpaceManager.cpp index 7ab99698130f..aedbf45a704a 100644 --- a/dom/base/nsNameSpaceManager.cpp +++ b/dom/base/nsNameSpaceManager.cpp @@ -16,6 +16,7 @@ #include "mozilla/dom/NodeInfo.h" #include "nsCOMArray.h" #include "nsContentCreatorFunctions.h" +#include "nsGkAtoms.h" #include "nsString.h" #include "mozilla/dom/NodeInfo.h" #include "mozilla/ClearOnShutdown.h" @@ -25,17 +26,6 @@ using namespace mozilla; using namespace mozilla::dom; -#define kXMLNSNameSpaceURI "http://www.w3.org/2000/xmlns/" -#define kXMLNameSpaceURI "http://www.w3.org/XML/1998/namespace" -#define kXHTMLNameSpaceURI "http://www.w3.org/1999/xhtml" -#define kXLinkNameSpaceURI "http://www.w3.org/1999/xlink" -#define kXSLTNameSpaceURI "http://www.w3.org/1999/XSL/Transform" -#define kXBLNameSpaceURI "http://www.mozilla.org/xbl" -#define kMathMLNameSpaceURI "http://www.w3.org/1998/Math/MathML" -#define kRDFNameSpaceURI "http://www.w3.org/1999/02/22-rdf-syntax-ns#" -#define kXULNameSpaceURI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" -#define kSVGNameSpaceURI "http://www.w3.org/2000/svg" - StaticAutoPtr nsNameSpaceManager::sInstance; /* static */ nsNameSpaceManager* @@ -57,20 +47,20 @@ bool nsNameSpaceManager::Init() { nsresult rv; #define REGISTER_NAMESPACE(uri, id) \ - rv = AddNameSpace(NS_LITERAL_STRING(uri), id); \ + rv = AddNameSpace(dont_AddRef(uri), id); \ NS_ENSURE_SUCCESS(rv, false) // Need to be ordered according to ID. - REGISTER_NAMESPACE(kXMLNSNameSpaceURI, kNameSpaceID_XMLNS); - REGISTER_NAMESPACE(kXMLNameSpaceURI, kNameSpaceID_XML); - REGISTER_NAMESPACE(kXHTMLNameSpaceURI, kNameSpaceID_XHTML); - REGISTER_NAMESPACE(kXLinkNameSpaceURI, kNameSpaceID_XLink); - REGISTER_NAMESPACE(kXSLTNameSpaceURI, kNameSpaceID_XSLT); - REGISTER_NAMESPACE(kXBLNameSpaceURI, kNameSpaceID_XBL); - REGISTER_NAMESPACE(kMathMLNameSpaceURI, kNameSpaceID_MathML); - REGISTER_NAMESPACE(kRDFNameSpaceURI, kNameSpaceID_RDF); - REGISTER_NAMESPACE(kXULNameSpaceURI, kNameSpaceID_XUL); - REGISTER_NAMESPACE(kSVGNameSpaceURI, kNameSpaceID_SVG); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_xmlns, kNameSpaceID_XMLNS); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_xml, kNameSpaceID_XML); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_xhtml, kNameSpaceID_XHTML); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_xlink, kNameSpaceID_XLink); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_xslt, kNameSpaceID_XSLT); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_xbl, kNameSpaceID_XBL); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_mathml, kNameSpaceID_MathML); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_rdf, kNameSpaceID_RDF); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_xul, kNameSpaceID_XUL); + REGISTER_NAMESPACE(nsGkAtoms::nsuri_svg, kNameSpaceID_SVG); #undef REGISTER_NAMESPACE @@ -87,11 +77,12 @@ nsNameSpaceManager::RegisterNameSpace(const nsAString& aURI, return NS_OK; } + nsCOMPtr atom = NS_Atomize(aURI); nsresult rv = NS_OK; - if (!mURIToIDTable.Get(&aURI, &aNameSpaceID)) { + if (!mURIToIDTable.Get(atom, &aNameSpaceID)) { aNameSpaceID = mURIArray.Length() + 1; // id is index + 1 - rv = AddNameSpace(aURI, aNameSpaceID); + rv = AddNameSpace(atom.forget(), aNameSpaceID); if (NS_FAILED(rv)) { aNameSpaceID = kNameSpaceID_Unknown; } @@ -114,7 +105,7 @@ nsNameSpaceManager::GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI) return NS_ERROR_ILLEGAL_VALUE; } - aURI = *mURIArray.ElementAt(index); + mURIArray.ElementAt(index)->ToString(aURI); return NS_OK; } @@ -128,7 +119,8 @@ nsNameSpaceManager::GetNameSpaceID(const nsAString& aURI) int32_t nameSpaceID; - if (mURIToIDTable.Get(&aURI, &nameSpaceID)) { + nsCOMPtr atom = NS_Atomize(aURI); + if (mURIToIDTable.Get(atom, &nameSpaceID)) { NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID"); return nameSpaceID; } @@ -177,9 +169,10 @@ nsNameSpaceManager::HasElementCreator(int32_t aNameSpaceID) false; } -nsresult nsNameSpaceManager::AddNameSpace(const nsAString& aURI, +nsresult nsNameSpaceManager::AddNameSpace(already_AddRefed aURI, const int32_t aNameSpaceID) { + nsCOMPtr uri = aURI; if (aNameSpaceID < 0) { // We've wrapped... Can't do anything else here; just bail. return NS_ERROR_OUT_OF_MEMORY; @@ -188,13 +181,8 @@ nsresult nsNameSpaceManager::AddNameSpace(const nsAString& aURI, NS_ASSERTION(aNameSpaceID - 1 == (int32_t) mURIArray.Length(), "BAD! AddNameSpace not called in right order!"); - nsString* uri = new nsString(aURI); - if (!mURIArray.AppendElement(uri)) { - delete uri; - return NS_ERROR_OUT_OF_MEMORY; - } - - mURIToIDTable.Put(uri, aNameSpaceID); + mURIArray.AppendElement(uri.forget()); + mURIToIDTable.Put(mURIArray.LastElement(), aNameSpaceID); return NS_OK; } diff --git a/dom/base/nsNameSpaceManager.h b/dom/base/nsNameSpaceManager.h index 6cbe54a43a87..be5e856c1739 100644 --- a/dom/base/nsNameSpaceManager.h +++ b/dom/base/nsNameSpaceManager.h @@ -8,50 +8,14 @@ #define nsNameSpaceManager_h___ #include "nsDataHashtable.h" +#include "nsHashKeys.h" +#include "nsIAtom.h" #include "nsTArray.h" #include "mozilla/StaticPtr.h" class nsAString; -class nsNameSpaceKey : public PLDHashEntryHdr -{ -public: - typedef const nsAString* KeyType; - typedef const nsAString* KeyTypePointer; - - explicit nsNameSpaceKey(KeyTypePointer aKey) : mKey(aKey) - { - } - nsNameSpaceKey(const nsNameSpaceKey& toCopy) : mKey(toCopy.mKey) - { - } - - KeyType GetKey() const - { - return mKey; - } - bool KeyEquals(KeyType aKey) const - { - return mKey->Equals(*aKey); - } - - static KeyTypePointer KeyToPointer(KeyType aKey) - { - return aKey; - } - static PLDHashNumber HashKey(KeyTypePointer aKey) { - return mozilla::HashString(*aKey); - } - - enum { - ALLOW_MEMMOVE = true - }; - -private: - const nsAString* mKey; -}; - /** * The Name Space Manager tracks the association between a NameSpace * URI and the int32_t runtime id. Mappings between NameSpaces and @@ -75,6 +39,12 @@ public: int32_t& aNameSpaceID); virtual nsresult GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI); + + nsIAtom* NameSpaceURIAtom(int32_t aNameSpaceID) { + MOZ_ASSERT(aNameSpaceID > 0 && (int64_t) aNameSpaceID <= (int64_t) mURIArray.Length()); + return mURIArray.ElementAt(aNameSpaceID - 1); // id is index + 1 + } + virtual int32_t GetNameSpaceID(const nsAString& aURI); virtual bool HasElementCreator(int32_t aNameSpaceID); @@ -82,10 +52,10 @@ public: static nsNameSpaceManager* GetInstance(); private: bool Init(); - nsresult AddNameSpace(const nsAString& aURI, const int32_t aNameSpaceID); + nsresult AddNameSpace(already_AddRefed aURI, const int32_t aNameSpaceID); - nsDataHashtable mURIToIDTable; - nsTArray< nsAutoPtr > mURIArray; + nsDataHashtable mURIToIDTable; + nsTArray> mURIArray; static mozilla::StaticAutoPtr sInstance; }; diff --git a/dom/base/nsXHTMLContentSerializer.cpp b/dom/base/nsXHTMLContentSerializer.cpp index ed3bb84f76c3..83cae4dc8f0f 100644 --- a/dom/base/nsXHTMLContentSerializer.cpp +++ b/dom/base/nsXHTMLContentSerializer.cpp @@ -194,9 +194,9 @@ nsXHTMLContentSerializer::EscapeURI(nsIContent* aContent, const nsAString& aURI, if (textToSubURI && !IsASCII(part)) { rv = textToSubURI->ConvertAndEscape(mCharset.get(), part.get(), getter_Copies(escapedURI)); NS_ENSURE_SUCCESS(rv, rv); - } - else { - escapedURI.Adopt(nsEscape(NS_ConvertUTF16toUTF8(part).get(), url_Path)); + } else if (NS_WARN_IF(!NS_Escape(NS_ConvertUTF16toUTF8(part), escapedURI, + url_Path))) { + return NS_ERROR_OUT_OF_MEMORY; } AppendASCIItoUTF16(escapedURI, aEscapedURI); @@ -212,9 +212,9 @@ nsXHTMLContentSerializer::EscapeURI(nsIContent* aContent, const nsAString& aURI, if (textToSubURI) { rv = textToSubURI->ConvertAndEscape(mCharset.get(), part.get(), getter_Copies(escapedURI)); NS_ENSURE_SUCCESS(rv, rv); - } - else { - escapedURI.Adopt(nsEscape(NS_ConvertUTF16toUTF8(part).get(), url_Path)); + } else if (NS_WARN_IF(!NS_Escape(NS_ConvertUTF16toUTF8(part), escapedURI, + url_Path))) { + return NS_ERROR_OUT_OF_MEMORY; } AppendASCIItoUTF16(escapedURI, aEscapedURI); } diff --git a/dom/base/test/mozbrowser_api_utils.js b/dom/base/test/mozbrowser_api_utils.js index 420fdba1f712..25845df2afb9 100644 --- a/dom/base/test/mozbrowser_api_utils.js +++ b/dom/base/test/mozbrowser_api_utils.js @@ -26,7 +26,6 @@ const METHODS = { findNext: {}, clearMatch: {}, executeScript: { alwaysFails: true }, // needs browser:universalxss - getStructuredData: {}, getWebManifest: {}, mute: {}, unmute: {}, diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index 05241910c337..98190c7c7a84 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -13,7 +13,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/BrowserElementPromptService.jsm"); Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/Microformats.js"); Cu.import("resource://gre/modules/ExtensionContent.jsm"); XPCOMUtils.defineLazyServiceGetter(this, "acs", @@ -285,7 +284,6 @@ BrowserElementChild.prototype = { "get-audio-channel-muted": this._recvGetAudioChannelMuted, "set-audio-channel-muted": this._recvSetAudioChannelMuted, "get-is-audio-channel-active": this._recvIsAudioChannelActive, - "get-structured-data": this._recvGetStructuredData, "get-web-manifest": this._recvGetWebManifest, } @@ -1546,300 +1544,6 @@ BrowserElementChild.prototype = { sendAsyncMsg('got-set-input-method-active', msgData); }, - _processMicroformatValue(field, value) { - if (['node', 'resolvedNode', 'semanticType'].includes(field)) { - return null; - } else if (Array.isArray(value)) { - var result = value.map(i => this._processMicroformatValue(field, i)) - .filter(i => i !== null); - return result.length ? result : null; - } else if (typeof value == 'string') { - return value; - } else if (typeof value == 'object' && value !== null) { - return this._processMicroformatItem(value); - } - return null; - }, - - // This function takes legacy Microformat data (hCard and hCalendar) - // and produces the same result that the equivalent Microdata data - // would produce. - _processMicroformatItem(microformatData) { - var result = {}; - - if (microformatData.semanticType == 'geo') { - return microformatData.latitude + ';' + microformatData.longitude; - } - - if (microformatData.semanticType == 'hCard') { - result.type = ["http://microformats.org/profile/hcard"]; - } else if (microformatData.semanticType == 'hCalendar') { - result.type = ["http://microformats.org/profile/hcalendar#vevent"]; - } - - for (let field of Object.getOwnPropertyNames(microformatData)) { - var processed = this._processMicroformatValue(field, microformatData[field]); - if (processed === null) { - continue; - } - if (!result.properties) { - result.properties = {}; - } - if (Array.isArray(processed)) { - result.properties[field] = processed; - } else { - result.properties[field] = [processed]; - } - } - - return result; - }, - - _findItemProperties: function(node, properties, alreadyProcessed) { - if (node.itemProp) { - var value; - - if (node.itemScope) { - value = this._processItem(node, alreadyProcessed); - } else { - value = node.itemValue; - } - - for (let i = 0; i < node.itemProp.length; ++i) { - var property = node.itemProp[i]; - if (!properties[property]) { - properties[property] = []; - } - - properties[property].push(value); - } - } - - if (!node.itemScope) { - var childNodes = node.childNodes; - for (var childNode of childNodes) { - this._findItemProperties(childNode, properties, alreadyProcessed); - } - } - }, - - _processItem: function(node, alreadyProcessed = []) { - if (alreadyProcessed.includes(node)) { - return "ERROR"; - } - - alreadyProcessed.push(node); - - var result = {}; - - if (node.itemId) { - result.id = node.itemId; - } - if (node.itemType) { - result.type = []; - for (let i = 0; i < node.itemType.length; ++i) { - result.type.push(node.itemType[i]); - } - } - - var properties = {}; - - var childNodes = node.childNodes; - for (var childNode of childNodes) { - this._findItemProperties(childNode, properties, alreadyProcessed); - } - - if (node.itemRef) { - for (let i = 0; i < node.itemRef.length; ++i) { - var refNode = content.document.getElementById(node.itemRef[i]); - this._findItemProperties(refNode, properties, alreadyProcessed); - } - } - - result.properties = properties; - return result; - }, - - _recvGetStructuredData: function(data) { - var result = { - items: [] - }; - - var microdataItems = content.document.getItems(); - - for (let microdataItem of microdataItems) { - result.items.push(this._processItem(microdataItem)); - } - - var hCardItems = Microformats.get("hCard", content.document); - for (let hCardItem of hCardItems) { - if (!hCardItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat - result.items.push(this._processMicroformatItem(hCardItem)); - } - } - - var hCalendarItems = Microformats.get("hCalendar", content.document); - for (let hCalendarItem of hCalendarItems) { - if (!hCalendarItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat - result.items.push(this._processMicroformatItem(hCalendarItem)); - } - } - - var resultString = JSON.stringify(result); - - sendAsyncMsg('got-structured-data', { - id: data.json.id, - successRv: resultString - }); - }, - - _processMicroformatValue(field, value) { - if (['node', 'resolvedNode', 'semanticType'].includes(field)) { - return null; - } else if (Array.isArray(value)) { - var result = value.map(i => this._processMicroformatValue(field, i)) - .filter(i => i !== null); - return result.length ? result : null; - } else if (typeof value == 'string') { - return value; - } else if (typeof value == 'object' && value !== null) { - return this._processMicroformatItem(value); - } - return null; - }, - - // This function takes legacy Microformat data (hCard and hCalendar) - // and produces the same result that the equivalent Microdata data - // would produce. - _processMicroformatItem(microformatData) { - var result = {}; - - if (microformatData.semanticType == 'geo') { - return microformatData.latitude + ';' + microformatData.longitude; - } - - if (microformatData.semanticType == 'hCard') { - result.type = ["http://microformats.org/profile/hcard"]; - } else if (microformatData.semanticType == 'hCalendar') { - result.type = ["http://microformats.org/profile/hcalendar#vevent"]; - } - - for (let field of Object.getOwnPropertyNames(microformatData)) { - var processed = this._processMicroformatValue(field, microformatData[field]); - if (processed === null) { - continue; - } - if (!result.properties) { - result.properties = {}; - } - if (Array.isArray(processed)) { - result.properties[field] = processed; - } else { - result.properties[field] = [processed]; - } - } - - return result; - }, - - _findItemProperties: function(node, properties, alreadyProcessed) { - if (node.itemProp) { - var value; - - if (node.itemScope) { - value = this._processItem(node, alreadyProcessed); - } else { - value = node.itemValue; - } - - for (let i = 0; i < node.itemProp.length; ++i) { - var property = node.itemProp[i]; - if (!properties[property]) { - properties[property] = []; - } - - properties[property].push(value); - } - } - - if (!node.itemScope) { - var childNodes = node.childNodes; - for (var childNode of childNodes) { - this._findItemProperties(childNode, properties, alreadyProcessed); - } - } - }, - - _processItem: function(node, alreadyProcessed = []) { - if (alreadyProcessed.includes(node)) { - return "ERROR"; - } - - alreadyProcessed.push(node); - - var result = {}; - - if (node.itemId) { - result.id = node.itemId; - } - if (node.itemType) { - result.type = []; - for (let i = 0; i < node.itemType.length; ++i) { - result.type.push(node.itemType[i]); - } - } - - var properties = {}; - - var childNodes = node.childNodes; - for (var childNode of childNodes) { - this._findItemProperties(childNode, properties, alreadyProcessed); - } - - if (node.itemRef) { - for (let i = 0; i < node.itemRef.length; ++i) { - var refNode = content.document.getElementById(node.itemRef[i]); - this._findItemProperties(refNode, properties, alreadyProcessed); - } - } - - result.properties = properties; - return result; - }, - - _recvGetStructuredData: function(data) { - var result = { - items: [] - }; - - var microdataItems = content.document.getItems(); - - for (let microdataItem of microdataItems) { - result.items.push(this._processItem(microdataItem)); - } - - var hCardItems = Microformats.get("hCard", content.document); - for (let hCardItem of hCardItems) { - if (!hCardItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat - result.items.push(this._processMicroformatItem(hCardItem)); - } - } - - var hCalendarItems = Microformats.get("hCalendar", content.document); - for (let hCalendarItem of hCalendarItems) { - if (!hCalendarItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat - result.items.push(this._processMicroformatItem(hCalendarItem)); - } - } - - var resultString = JSON.stringify(result); - - sendAsyncMsg('got-structured-data', { - id: data.json.id, - successRv: resultString - }); - }, - // The docShell keeps a weak reference to the progress listener, so we need // to keep a strong ref to it ourselves. _progressListener: { diff --git a/dom/browser-element/BrowserElementParent.js b/dom/browser-element/BrowserElementParent.js index ab9700cd4f9e..58f6834a293f 100644 --- a/dom/browser-element/BrowserElementParent.js +++ b/dom/browser-element/BrowserElementParent.js @@ -389,7 +389,6 @@ BrowserElementParent.prototype = { "got-audio-channel-muted": this._gotDOMRequestResult, "got-set-audio-channel-muted": this._gotDOMRequestResult, "got-is-audio-channel-active": this._gotDOMRequestResult, - "got-structured-data": this._gotDOMRequestResult, "got-web-manifest": this._gotDOMRequestResult, }; @@ -1208,8 +1207,6 @@ BrowserElementParent.prototype = { return req; }, - getStructuredData: defineDOMRequestMethod('get-structured-data'), - getWebManifest: defineDOMRequestMethod('get-web-manifest'), /** * Called when the visibility of the window which owns this iframe changes. diff --git a/dom/browser-element/mochitest/browserElement_getStructuredData.js b/dom/browser-element/mochitest/browserElement_getStructuredData.js deleted file mode 100644 index 9d366abddf7a..000000000000 --- a/dom/browser-element/mochitest/browserElement_getStructuredData.js +++ /dev/null @@ -1,111 +0,0 @@ -/* Any copyright is dedicated to the public domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -/*globals async, is, SimpleTest, browserElementTestHelpers*/ - -// Bug 119580 - getStructuredData tests -'use strict'; -SimpleTest.waitForExplicitFinish(); -browserElementTestHelpers.setEnabledPref(true); -browserElementTestHelpers.addPermission(); - -const EMPTY_URL = 'file_empty.html'; -const MICRODATA_URL = 'file_microdata.html'; -const MICRODATA_ITEMREF_URL = 'file_microdata_itemref.html'; -const MICRODATA_BAD_ITEMREF_URL = 'file_microdata_bad_itemref.html'; -const MICROFORMATS_URL = 'file_microformats.html'; - -var test1 = async(function* () { - var structuredData = yield requestStructuredData(EMPTY_URL); - is(structuredData.items && structuredData.items.length, 0, - 'There should be 0 items.'); -}); - -var test2 = async(function* () { - var structuredData = yield requestStructuredData(MICRODATA_URL); - is(structuredData.items && structuredData.items.length, 2, - 'There should be two items.'); - is(structuredData.items[0].type[0], 'http://schema.org/Recipe', - 'Can get item type.'); - is(structuredData.items[0].properties['datePublished'][0], '2009-05-08', - 'Can get item property.'); - is(structuredData.items[1] - .properties["aggregateRating"][0] - .properties["ratingValue"][0], - '4', 'Can get nested item property.'); -}); - -var test3 = async(function* () { - var structuredData = yield requestStructuredData(MICROFORMATS_URL); - is(structuredData.items && structuredData.items.length, 2, - 'There should be two items.'); - is(structuredData.items[0].type[0], 'http://microformats.org/profile/hcard', - 'Got hCard object.'); - is(structuredData.items[0] - .properties["adr"][0] - .properties["country-name"][0], - 'France', 'Can read hCard properties.'); - is(structuredData.items[0] - .properties["adr"][0] - .properties["type"] - .includes('home') && - structuredData.items[0] - .properties["adr"][0] - .properties["type"] - .includes('postal'), - true, 'Property can contain multiple values.'); - is(structuredData.items[0] - .properties["geo"][0], - '48.816667;2.366667', 'Geo value is formatted as per WHATWG spec.'); - - is(structuredData.items[1].type[0], - 'http://microformats.org/profile/hcalendar#vevent', - 'Got hCalendar object.'); - is(structuredData.items[1] - .properties["dtstart"][0], - '2005-10-05', 'Can read hCalendar properties'); -}); - -var test4 = async(function* () { - var structuredData = yield requestStructuredData(MICRODATA_ITEMREF_URL); - is(structuredData.items[0].properties["license"][0], - 'http://www.opensource.org/licenses/mit-license.php', 'itemref works.'); - is(structuredData.items[1].properties["license"][0], - 'http://www.opensource.org/licenses/mit-license.php', - 'Two items can successfully share an itemref.'); -}); - -var test5 = async(function* () { - var structuredData = yield requestStructuredData(MICRODATA_BAD_ITEMREF_URL); - is(structuredData.items[0] - .properties["band"][0] - .properties["cycle"][0] - .properties["band"][0], - 'ERROR', 'Cyclic reference should be detected as an error.'); -}); - -Promise - .all([test1(), test2(), test3(), test4(), test5()]) - .then(SimpleTest.finish); - -function requestStructuredData(url) { - var iframe = document.createElement('iframe'); - iframe.setAttribute('mozbrowser', 'true'); - iframe.src = url; - document.body.appendChild(iframe); - return new Promise((resolve, reject) => { - iframe.addEventListener('mozbrowserloadend', function loadend() { - iframe.removeEventListener('mozbrowserloadend', loadend); - SimpleTest.executeSoon(() => { - var req = iframe.getStructuredData(); - req.onsuccess = (ev) => { - document.body.removeChild(iframe); - resolve(JSON.parse(req.result)); - }; - req.onerror = (ev) => { - document.body.removeChild(iframe); - reject(new Error(req.error)); - }; - }); - }); - }); -} diff --git a/dom/browser-element/mochitest/mochitest-oop.ini b/dom/browser-element/mochitest/mochitest-oop.ini index 9da72990082b..f0d5dcc1ff78 100644 --- a/dom/browser-element/mochitest/mochitest-oop.ini +++ b/dom/browser-element/mochitest/mochitest-oop.ini @@ -14,7 +14,6 @@ support-files = [test_browserElement_oop_AudioChannelSeeking.html] tags = audiochannel -[test_browserElement_oop_getStructuredData.html] [test_browserElement_oop_Viewmode.html] [test_browserElement_oop_ThemeColor.html] [test_browserElement_inproc_ErrorSecurity.html] diff --git a/dom/browser-element/mochitest/mochitest.ini b/dom/browser-element/mochitest/mochitest.ini index 948ef3be2a6e..5def51dea914 100644 --- a/dom/browser-element/mochitest/mochitest.ini +++ b/dom/browser-element/mochitest/mochitest.ini @@ -41,7 +41,6 @@ support-files = browserElement_FrameWrongURI.js browserElement_GetScreenshot.js browserElement_GetScreenshotDppx.js - browserElement_getStructuredData.js browserElement_getWebManifest.js browserElement_Iconchange.js browserElement_LoadEvents.js @@ -265,7 +264,6 @@ tags = audiochannel [test_browserElement_inproc_AudioChannel_nested.html] tags = audiochannel [test_browserElement_inproc_SetNFCFocus.html] -[test_browserElement_inproc_getStructuredData.html] [test_browserElement_inproc_OpenWindowEmpty.html] skip-if = (toolkit == 'gonk') # Test doesn't work on B2G emulator [test_browserElement_inproc_ActiveStateChangeOnChangingMutedOrVolume.html] diff --git a/dom/browser-element/mochitest/test_browserElement_inproc_getStructuredData.html b/dom/browser-element/mochitest/test_browserElement_inproc_getStructuredData.html deleted file mode 100644 index 12fb129240a8..000000000000 --- a/dom/browser-element/mochitest/test_browserElement_inproc_getStructuredData.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - Test for Bug 1195801 - - - - - - - - - - diff --git a/dom/browser-element/mochitest/test_browserElement_oop_getStructuredData.html b/dom/browser-element/mochitest/test_browserElement_oop_getStructuredData.html deleted file mode 100644 index 12fb129240a8..000000000000 --- a/dom/browser-element/mochitest/test_browserElement_oop_getStructuredData.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - Test for Bug 1195801 - - - - - - - - - - diff --git a/dom/browser-element/nsIBrowserElementAPI.idl b/dom/browser-element/nsIBrowserElementAPI.idl index a97a118e6d04..6535f104eca8 100644 --- a/dom/browser-element/nsIBrowserElementAPI.idl +++ b/dom/browser-element/nsIBrowserElementAPI.idl @@ -110,16 +110,4 @@ interface nsIBrowserElementAPI : nsISupports * http://w3c.github.io/manifest/ */ nsIDOMDOMRequest getWebManifest(); - - /** - * Returns a JSON string representing Microdata objects on the page. - * Format is described at: - * https://html.spec.whatwg.org/multipage/microdata.html#json - * - * Also contains hCard and hCalendar objects after converting them - * to equivalent Microdata objects described at: - * https://html.spec.whatwg.org/multipage/microdata.html#vcard - * https://html.spec.whatwg.org/multipage/microdata.html#vevent - */ - nsIDOMDOMRequest getStructuredData(); }; diff --git a/dom/camera/GonkCameraControl.cpp b/dom/camera/GonkCameraControl.cpp index ae61d6243b1c..32a66ebdb76f 100644 --- a/dom/camera/GonkCameraControl.cpp +++ b/dom/camera/GonkCameraControl.cpp @@ -572,7 +572,7 @@ nsGonkCameraControl::PushParameters() if (NS_GetCurrentThread() != mCameraThread) { DOM_CAMERA_LOGT("%s:%d - dispatching to Camera Thread\n", __func__, __LINE__); nsCOMPtr pushParametersTask = - NS_NewRunnableMethod(this, &nsGonkCameraControl::PushParametersImpl); + NewRunnableMethod(this, &nsGonkCameraControl::PushParametersImpl); return mCameraThread->Dispatch(pushParametersTask, NS_DISPATCH_NORMAL); } diff --git a/dom/html/HTMLLinkElement.cpp b/dom/html/HTMLLinkElement.cpp index 08ae4dbeadf5..ab95354964c3 100644 --- a/dom/html/HTMLLinkElement.cpp +++ b/dom/html/HTMLLinkElement.cpp @@ -470,6 +470,7 @@ static const DOMTokenListSupportedToken sSupportedRelValues[] = { "alternate", "preconnect", "icon", + "search", nullptr }; diff --git a/dom/html/nsBrowserElement.cpp b/dom/html/nsBrowserElement.cpp index cf652b12d568..d75f1d1c05ac 100644 --- a/dom/html/nsBrowserElement.cpp +++ b/dom/html/nsBrowserElement.cpp @@ -785,22 +785,6 @@ nsBrowserElement::ExecuteScript(const nsAString& aScript, return req.forget().downcast(); } -already_AddRefed -nsBrowserElement::GetStructuredData(ErrorResult& aRv) -{ - NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr); - - nsCOMPtr req; - nsresult rv = mBrowserElementAPI->GetStructuredData(getter_AddRefs(req)); - - if (NS_WARN_IF(NS_FAILED(rv))) { - aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); - return nullptr; - } - - return req.forget().downcast(); -} - already_AddRefed nsBrowserElement::GetWebManifest(ErrorResult& aRv) { diff --git a/dom/html/nsBrowserElement.h b/dom/html/nsBrowserElement.h index 8c54f71e6dc9..4b0596b9d643 100644 --- a/dom/html/nsBrowserElement.h +++ b/dom/html/nsBrowserElement.h @@ -112,8 +112,6 @@ public: const dom::BrowserElementExecuteScriptOptions& aOptions, ErrorResult& aRv); - already_AddRefed GetStructuredData(ErrorResult& aRv); - already_AddRefed GetWebManifest(ErrorResult& aRv); void SetNFCFocus(bool isFocus, diff --git a/dom/html/nsFormSubmission.cpp b/dom/html/nsFormSubmission.cpp index 75515227e9d2..2acb50d85b20 100644 --- a/dom/html/nsFormSubmission.cpp +++ b/dom/html/nsFormSubmission.cpp @@ -281,8 +281,10 @@ nsFSURLEncoded::GetEncodedSubmission(nsIURI* aURI, HandleMailtoSubject(path); // Append the body to and force-plain-text args to the mailto line - nsCString escapedBody; - escapedBody.Adopt(nsEscape(mQueryString.get(), url_XAlphas)); + nsAutoCString escapedBody; + if (NS_WARN_IF(!NS_Escape(mQueryString, escapedBody, url_XAlphas))) { + return NS_ERROR_OUT_OF_MEMORY; + } path += NS_LITERAL_CSTRING("&force-plain-text=Y&body=") + escapedBody; @@ -666,11 +668,11 @@ nsFSTextPlain::GetEncodedSubmission(nsIURI* aURI, HandleMailtoSubject(path); // Append the body to and force-plain-text args to the mailto line - char* escapedBuf = nsEscape(NS_ConvertUTF16toUTF8(mBody).get(), - url_XAlphas); - NS_ENSURE_TRUE(escapedBuf, NS_ERROR_OUT_OF_MEMORY); - nsCString escapedBody; - escapedBody.Adopt(escapedBuf); + nsAutoCString escapedBody; + if (NS_WARN_IF(!NS_Escape(NS_ConvertUTF16toUTF8(mBody), escapedBody, + url_XAlphas))) { + return NS_ERROR_OUT_OF_MEMORY; + } path += NS_LITERAL_CSTRING("&force-plain-text=Y&body=") + escapedBody; diff --git a/dom/ipc/NuwaParent.cpp b/dom/ipc/NuwaParent.cpp index 3bec7be10a56..48601cd0e83c 100644 --- a/dom/ipc/NuwaParent.cpp +++ b/dom/ipc/NuwaParent.cpp @@ -169,7 +169,7 @@ NuwaParent::RecvNotifyReady() // mContentParent have to go the the main thread. The mContentParent will // be alive when the runnable runs. nsCOMPtr runnable = - NS_NewNonOwningRunnableMethod(mContentParent.get(), + NewNonOwningRunnableMethod(mContentParent.get(), &ContentParent::OnNuwaReady); MOZ_ASSERT(runnable); MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable)); @@ -200,7 +200,7 @@ NuwaParent::RecvAddNewProcess(const uint32_t& aPid, mBlocked = false; } else { nsCOMPtr runnable = - NS_NewNonOwningRunnableMethodWithArgs< + NewNonOwningRunnableMethod< uint32_t, UniquePtr>&& >( mContentParent.get(), diff --git a/dom/ipc/PreallocatedProcessManager.cpp b/dom/ipc/PreallocatedProcessManager.cpp index 6ba07bd0ccb1..296d7d1510f9 100644 --- a/dom/ipc/PreallocatedProcessManager.cpp +++ b/dom/ipc/PreallocatedProcessManager.cpp @@ -242,7 +242,7 @@ PreallocatedProcessManagerImpl::ScheduleDelayedNuwaFork() return; } - RefPtr task = NS_NewCancelableRunnableMethod( + RefPtr task = NewCancelableRunnableMethod( this, &PreallocatedProcessManagerImpl::DelayedNuwaFork); mPreallocateAppProcessTask = task; MessageLoop::current()->PostDelayedTask(task.forget(), diff --git a/dom/media/MediaDataDemuxer.h b/dom/media/MediaDataDemuxer.h index 59c72689961e..4d22ec2b9618 100644 --- a/dom/media/MediaDataDemuxer.h +++ b/dom/media/MediaDataDemuxer.h @@ -201,6 +201,13 @@ public: virtual media::TimeIntervals GetBuffered() = 0; + // By default, it is assumed that the entire resource can be evicted once + // all samples have been demuxed. + virtual int64_t GetEvictionOffset(const media::TimeUnit& aTime) + { + return INT64_MAX; + } + // If the MediaTrackDemuxer and MediaDataDemuxer hold cross references. // BreakCycles must be overridden. virtual void BreakCycles() diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index 0f348ce6e029..92b70b19678b 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -1269,9 +1269,21 @@ TrackBuffersManager::CompleteCodedFrameProcessing() // 6. Remove the media segment bytes from the beginning of the input buffer. // Clear our demuxer from any already processed data. - // As we have handled a complete media segment, it is safe to evict all data - // from the resource. - mCurrentInputBuffer->EvictAll(); + int64_t safeToEvict = std::min( + HasVideo() + ? mVideoTracks.mDemuxer->GetEvictionOffset(mVideoTracks.mLastParsedEndTime) + : INT64_MAX, + HasAudio() + ? mAudioTracks.mDemuxer->GetEvictionOffset(mAudioTracks.mLastParsedEndTime) + : INT64_MAX); + ErrorResult rv; + mCurrentInputBuffer->EvictBefore(safeToEvict, rv); + if (rv.Failed()) { + rv.SuppressException(); + RejectProcessing(NS_ERROR_OUT_OF_MEMORY, __func__); + return; + } + mInputDemuxer->NotifyDataRemoved(); RecreateParser(true); @@ -1642,9 +1654,11 @@ TrackBuffersManager::InsertFrames(TrackBuffer& aSamples, // We allow a fuzz factor in our interval of half a frame length, // as fuzz is +/- value, giving an effective leeway of a full frame // length. - TimeIntervals range(aIntervals); - range.SetFuzz(trackBuffer.mLongestFrameDuration / 2); - trackBuffer.mSanitizedBufferedRanges += range; + if (aIntervals.Length()) { + TimeIntervals range(aIntervals); + range.SetFuzz(trackBuffer.mLongestFrameDuration / 2); + trackBuffer.mSanitizedBufferedRanges += range; + } } void diff --git a/dom/media/omx/MediaOmxCommonReader.cpp b/dom/media/omx/MediaOmxCommonReader.cpp index 2926ea940c10..aa0294f216ea 100644 --- a/dom/media/omx/MediaOmxCommonReader.cpp +++ b/dom/media/omx/MediaOmxCommonReader.cpp @@ -11,7 +11,7 @@ #include "AbstractMediaDecoder.h" #include "AudioChannelService.h" #include "MediaStreamSource.h" -#include "gfxPrefs.h" +#include "MediaPrefs.h" #ifdef MOZ_AUDIO_OFFLOAD #include @@ -35,7 +35,7 @@ MediaOmxCommonReader::MediaOmxCommonReader(AbstractMediaDecoder *aDecoder) bool MediaOmxCommonReader::IsMonoAudioEnabled() { - return gfxPrefs::MonoAudio(); + return MediaPrefs::MonoAudio(); } #ifdef MOZ_AUDIO_OFFLOAD diff --git a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp index b38659abcdd1..ce275337107a 100644 --- a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp +++ b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp @@ -59,9 +59,7 @@ AgnosticDecoderModule::CreateAudioDecoder(const AudioInfo& aConfig, aAudioTaskQueue, aCallback); } else if (WaveDataDecoder::IsWave(aConfig.mMimeType)) { - m = new WaveDataDecoder(*aConfig.GetAsAudioInfo(), - aAudioTaskQueue, - aCallback); + m = new WaveDataDecoder(*aConfig.GetAsAudioInfo(), aCallback); } return m.forget(); diff --git a/dom/media/platforms/agnostic/WAVDecoder.cpp b/dom/media/platforms/agnostic/WAVDecoder.cpp index b91a0260b7db..855dda39d1ae 100644 --- a/dom/media/platforms/agnostic/WAVDecoder.cpp +++ b/dom/media/platforms/agnostic/WAVDecoder.cpp @@ -47,13 +47,9 @@ DecodeULawSample(uint8_t aValue) } WaveDataDecoder::WaveDataDecoder(const AudioInfo& aConfig, - TaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback) : mInfo(aConfig) - , mTaskQueue(aTaskQueue) , mCallback(aCallback) - , mIsFlushing(false) - , mFrames(0) { } @@ -72,32 +68,15 @@ WaveDataDecoder::Init() nsresult WaveDataDecoder::Input(MediaRawData* aSample) { - MOZ_ASSERT(mCallback->OnReaderTaskQueue()); - mTaskQueue->Dispatch(NewRunnableMethod>( - this, &WaveDataDecoder::ProcessDecode, aSample)); - - return NS_OK; -} - -void -WaveDataDecoder::ProcessDecode(MediaRawData* aSample) -{ - MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); - if (mIsFlushing) { - return; - } if (!DoDecode(aSample)) { mCallback->Error(); - } else if (mTaskQueue->IsEmpty()) { - mCallback->InputExhausted(); } + return NS_OK; } bool WaveDataDecoder::DoDecode(MediaRawData* aSample) { - MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); - size_t aLength = aSample->Size(); ByteReader aReader = ByteReader(aSample->Data(), aLength); int64_t aOffset = aSample->mOffset; @@ -150,36 +129,20 @@ WaveDataDecoder::DoDecode(MediaRawData* aSample) Move(buffer), mInfo.mChannels, mInfo.mRate)); - mFrames += frames; return true; } -void -WaveDataDecoder::ProcessDrain() -{ - MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); - mCallback->DrainComplete(); -} - nsresult WaveDataDecoder::Drain() { - MOZ_ASSERT(mCallback->OnReaderTaskQueue()); - mTaskQueue->Dispatch(NewRunnableMethod(this, &WaveDataDecoder::ProcessDrain)); + mCallback->DrainComplete(); return NS_OK; } nsresult WaveDataDecoder::Flush() { - MOZ_ASSERT(mCallback->OnReaderTaskQueue()); - mIsFlushing = true; - nsCOMPtr r = NS_NewRunnableFunction([this] () { - mFrames = 0; - }); - SyncRunnable::DispatchToThread(mTaskQueue, r); - mIsFlushing = false; return NS_OK; } diff --git a/dom/media/platforms/agnostic/WAVDecoder.h b/dom/media/platforms/agnostic/WAVDecoder.h index e7c93c568b3f..6e1b2d044bc1 100644 --- a/dom/media/platforms/agnostic/WAVDecoder.h +++ b/dom/media/platforms/agnostic/WAVDecoder.h @@ -16,7 +16,6 @@ class WaveDataDecoder : public MediaDataDecoder { public: WaveDataDecoder(const AudioInfo& aConfig, - TaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback); // Return true if mimetype is Wave @@ -33,16 +32,10 @@ private: return "wave audio decoder"; } - void ProcessDecode(MediaRawData* aSample); bool DoDecode(MediaRawData* aSample); - void ProcessDrain(); const AudioInfo& mInfo; - const RefPtr mTaskQueue; MediaDataDecoderCallback* mCallback; - Atomic mIsFlushing; - - int64_t mFrames; }; } // namespace mozilla diff --git a/dom/media/platforms/android/AndroidDecoderModule.cpp b/dom/media/platforms/android/AndroidDecoderModule.cpp index f878f493549f..3afc96aaaa1e 100644 --- a/dom/media/platforms/android/AndroidDecoderModule.cpp +++ b/dom/media/platforms/android/AndroidDecoderModule.cpp @@ -549,11 +549,13 @@ MediaCodecDataDecoder::HandleEOS(int32_t aOutputStatus) mDecoder->ReleaseOutputBuffer(aOutputStatus, false); } -TimeUnit +Maybe MediaCodecDataDecoder::GetOutputDuration() { - MOZ_ASSERT(!mDurations.empty(), "Should have had a duration queued"); - const TimeUnit duration = mDurations.front(); + if (mDurations.empty()) { + return Nothing(); + } + const Maybe duration = Some(mDurations.front()); mDurations.pop_front(); return duration; } @@ -564,19 +566,26 @@ MediaCodecDataDecoder::ProcessOutput( { AutoLocalJNIFrame frame(jni::GetEnvForThread(), 1); - const TimeUnit duration = GetOutputDuration(); + const Maybe duration = GetOutputDuration(); + if (!duration) { + // Some devices report failure in QueueSample while actually succeeding at + // it, in which case we get an output buffer without having a cached duration + // (bug 1273523). + return NS_OK; + } + const auto buffer = jni::Object::LocalRef::Adopt( frame.GetEnv()->GetObjectArrayElement(mOutputBuffers.Get(), aStatus)); if (buffer) { // The buffer will be null on Android L if we are decoding to a Surface. void* directBuffer = frame.GetEnv()->GetDirectBufferAddress(buffer.Get()); - Output(aInfo, directBuffer, aFormat, duration); + Output(aInfo, directBuffer, aFormat, duration.value()); } // The Surface will be updated at this point (for video). mDecoder->ReleaseOutputBuffer(aStatus, true); - PostOutput(aInfo, aFormat, duration); + PostOutput(aInfo, aFormat, duration.value()); return NS_OK; } diff --git a/dom/media/platforms/android/AndroidDecoderModule.h b/dom/media/platforms/android/AndroidDecoderModule.h index f6bd0030e0aa..637d33e4f228 100644 --- a/dom/media/platforms/android/AndroidDecoderModule.h +++ b/dom/media/platforms/android/AndroidDecoderModule.h @@ -11,6 +11,7 @@ #include "SurfaceTexture.h" #include "TimeUnits.h" #include "mozilla/Monitor.h" +#include "mozilla/Maybe.h" #include @@ -105,7 +106,7 @@ protected: nsresult QueueSample(const MediaRawData* aSample); nsresult QueueEOS(); void HandleEOS(int32_t aOutputStatus); - media::TimeUnit GetOutputDuration(); + Maybe GetOutputDuration(); nsresult ProcessOutput(widget::sdk::BufferInfo::Param aInfo, widget::sdk::MediaFormat::Param aFormat, int32_t aStatus); diff --git a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp index 82ce15b6aefb..49489c1dd7e4 100644 --- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp +++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp @@ -14,10 +14,12 @@ #include "DXVA2Manager.h" #include "nsThreadUtils.h" #include "Layers.h" +#include "mozilla/ClearOnShutdown.h" #include "mozilla/layers/LayersTypes.h" #include "MediaInfo.h" #include "MediaPrefs.h" #include "mozilla/Logging.h" +#include "mozilla/Preferences.h" #include "nsWindowsHelpers.h" #include "gfx2DGlue.h" #include "gfxWindowsPlatform.h" @@ -26,6 +28,7 @@ #include "mozilla/Telemetry.h" #include "nsPrintfCString.h" #include "MediaTelemetryConstants.h" +#include "GMPUtils.h" // For SplitAt. TODO: Move SplitAt to a central place. extern mozilla::LogModule* GetPDMLog(); #define LOG(...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, (__VA_ARGS__)) @@ -151,91 +154,125 @@ WMFVideoMFTManager::GetMediaSubtypeGUID() }; } -struct BlacklistedD3D11DLL +struct D3D11BlacklistingCache { - constexpr - BlacklistedD3D11DLL(LPCWSTR aName, DWORD a, DWORD b, DWORD c, DWORD d) - : name(aName), ms((a << 16) | b), ls((c << 16) | d) - {} - LPCWSTR name; - DWORD ms; - DWORD ls; -}; -static constexpr BlacklistedD3D11DLL sBlacklistedD3D11DLL[] = -{ - // Keep same DLL names together. - BlacklistedD3D11DLL(L"igd10umd32.dll", 9,17,10,2857), - BlacklistedD3D11DLL(L"isonyvideoprocessor.dll", 4,1,2247,8090), - BlacklistedD3D11DLL(L"isonyvideoprocessor.dll", 4,1,2153,6200), - BlacklistedD3D11DLL(L"tosqep.dll", 1,2,15,526), - BlacklistedD3D11DLL(L"tosqep.dll", 1,1,12,201), - BlacklistedD3D11DLL(L"tosqep.dll", 1,0,11,318), - BlacklistedD3D11DLL(L"tosqep.dll", 1,0,11,215), - BlacklistedD3D11DLL(L"tosqep64.dll", 1,1,12,201), - BlacklistedD3D11DLL(L"tosqep64.dll", 1,0,11,215), - // Keep this last. - BlacklistedD3D11DLL(nullptr, 0,0,0,0) + // D3D11-blacklist pref last seen. + nsCString mBlacklistPref; + // Non-empty if a D3D11-blacklisted DLL was found. + nsCString mBlacklistedDLL; }; +StaticAutoPtr sD3D11BlacklistingCache; -// If a blacklisted DLL is found, return its information, otherwise nullptr. -static const BlacklistedD3D11DLL* -IsD3D11DLLBlacklisted() +// If a blacklisted DLL is found, return its information, otherwise "". +static const nsACString& +FindD3D11BlacklistedDLL() { NS_ASSERTION(NS_IsMainThread(), "Must be on main thread."); - // Cache the result, so we only check DLLs once per browser run. - static const BlacklistedD3D11DLL* sAlreadySearched = nullptr; - if (sAlreadySearched) { - // If we point at the last empty entry, there's no actual blacklisting. - return sAlreadySearched->name ? sAlreadySearched : nullptr; + + if (!sD3D11BlacklistingCache) { + // First time here, create persistent data that will be reused in all + // D3D11-blacklisting checks. + sD3D11BlacklistingCache = new D3D11BlacklistingCache(); + ClearOnShutdown(&sD3D11BlacklistingCache); } - WCHAR systemPath[MAX_PATH + 1]; - LPCWSTR previousDLLName = L""; - VS_FIXEDFILEINFO *vInfo = nullptr; - // vInfo is a pointer into infoData, that's why we keep it outside of the loop. - UniquePtr infoData; + nsAdoptingCString blacklist = + Preferences::GetCString("media.wmf.disable-d3d11-for-dlls"); + if (blacklist.IsEmpty()) { + // Empty blacklist -> No blacklisting. + sD3D11BlacklistingCache->mBlacklistPref.SetLength(0); + sD3D11BlacklistingCache->mBlacklistedDLL.SetLength(0); + return sD3D11BlacklistingCache->mBlacklistedDLL; + } - for (const BlacklistedD3D11DLL* dll = sBlacklistedD3D11DLL; ; ++dll) { - if (!dll->name) { - // End of list, no blacklisting. - sAlreadySearched = dll; - return nullptr; - } - // Check if we need to check another DLL (compare by pointer to name string) - if (wcscmp(previousDLLName, dll->name) != 0) { - previousDLLName = dll->name; - vInfo = nullptr; - infoData = nullptr; - if (!ConstructSystem32Path(dll->name, systemPath, MAX_PATH + 1)) { - // Cannot build path -> Assume it's not the blacklisted DLL. - continue; - } + // Detect changes in pref. + if (sD3D11BlacklistingCache->mBlacklistPref.Equals(blacklist)) { + // Same blacklist -> Return same result (i.e., don't check DLLs again). + return sD3D11BlacklistingCache->mBlacklistedDLL; + } + // Adopt new pref now, so we don't work on it again. + sD3D11BlacklistingCache->mBlacklistPref = blacklist; - DWORD zero; - DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero); - if (infoSize == 0) { - // Can't get file info -> Assume we don't have the blacklisted DLL. - continue; - } - infoData = MakeUnique(infoSize); - UINT vInfoLen; - if (!GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get()) - || !VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen)) { - // Can't find version -> Assume it's not blacklisted. - vInfo = nullptr; - infoData = nullptr; - continue; - } + // media.wmf.disable-d3d11-for-dlls format: (whitespace is trimmed) + // "dll1.dll: 1.2.3.4[, more versions...][; more dlls...]" + nsTArray dlls; + SplitAt(";", blacklist, dlls); + for (const auto& dll : dlls) { + nsTArray nameAndVersions; + SplitAt(":", dll, nameAndVersions); + if (nameAndVersions.Length() != 2) { + NS_WARNING("Skipping incorrect 'media.wmf.disable-d3d11-for-dlls' dll:versions format"); + continue; } - if (vInfo - && vInfo->dwFileVersionMS == dll->ms - && vInfo->dwFileVersionLS == dll->ls) { - // Blacklisted! Keep pointer to bad DLL. - sAlreadySearched = dll; - return dll; + nameAndVersions[0].CompressWhitespace(); + NS_ConvertUTF8toUTF16 name(nameAndVersions[0]); + WCHAR systemPath[MAX_PATH + 1]; + if (!ConstructSystem32Path(name.get(), systemPath, MAX_PATH + 1)) { + // Cannot build path -> Assume it's not the blacklisted DLL. + continue; + } + + DWORD zero; + DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero); + if (infoSize == 0) { + // Can't get file info -> Assume we don't have the blacklisted DLL. + continue; + } + // vInfo is a pointer into infoData, that's why we keep it outside of the loop. + auto infoData = MakeUnique(infoSize); + VS_FIXEDFILEINFO *vInfo; + UINT vInfoLen; + if (!GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get()) + || !VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen) + || !vInfo) { + // Can't find version -> Assume it's not blacklisted. + continue; + } + + nsTArray versions; + SplitAt(",", nameAndVersions[1], versions); + for (const auto& version : versions) { + nsTArray numberStrings; + SplitAt(".", version, numberStrings); + if (numberStrings.Length() != 4) { + NS_WARNING("Skipping incorrect 'media.wmf.disable-d3d11-for-dlls' a.b.c.d version format"); + continue; + } + DWORD numbers[4]; + nsresult errorCode = NS_OK; + for (int i = 0; i < 4; ++i) { + numberStrings[i].CompressWhitespace(); + numbers[i] = DWORD(numberStrings[i].ToInteger(&errorCode)); + if (NS_FAILED(errorCode)) { + break; + } + if (numbers[i] > UINT16_MAX) { + errorCode = NS_ERROR_FAILURE; + break; + } + } + + if (NS_FAILED(errorCode)) { + NS_WARNING("Skipping incorrect 'media.wmf.disable-d3d11-for-dlls' a.b.c.d version format"); + continue; + } + + if (vInfo->dwFileVersionMS == ((numbers[0] << 16) | numbers[1]) + && vInfo->dwFileVersionLS == ((numbers[2] << 16) | numbers[3])) { + // Blacklisted! Record bad DLL. + sD3D11BlacklistingCache->mBlacklistedDLL.SetLength(0); + sD3D11BlacklistingCache->mBlacklistedDLL.AppendPrintf( + "%s (%lu.%lu.%lu.%lu)", + nameAndVersions[0].get(), numbers[0], numbers[1], numbers[2], numbers[3]); + return sD3D11BlacklistingCache->mBlacklistedDLL; + } } } + + // No blacklisted DLL. + sD3D11BlacklistingCache->mBlacklistedDLL.SetLength(0); + return sD3D11BlacklistingCache->mBlacklistedDLL; } class CreateDXVAManagerEvent : public Runnable { @@ -251,13 +288,10 @@ public: nsCString secondFailureReason; if (mBackend == LayersBackend::LAYERS_D3D11 && MediaPrefs::PDMWMFAllowD3D11() && IsWin8OrLater()) { - const BlacklistedD3D11DLL* blacklistedDLL = IsD3D11DLLBlacklisted(); - if (blacklistedDLL) { - failureReason->AppendPrintf( - "D3D11 blacklisted with DLL %s (%u.%u.%u.%u)", - blacklistedDLL->name, - blacklistedDLL->ms >> 16, blacklistedDLL->ms & 0xFFu, - blacklistedDLL->ls >> 16, blacklistedDLL->ls & 0xFFu); + const nsACString& blacklistedDLL = FindD3D11BlacklistedDLL(); + if (!blacklistedDLL.IsEmpty()) { + failureReason->AppendPrintf("D3D11 blacklisted with DLL %s", + blacklistedDLL); } else { mDXVA2Manager = DXVA2Manager::CreateD3D11DXVA(*failureReason); if (mDXVA2Manager) { @@ -298,7 +332,9 @@ WMFVideoMFTManager::InitializeDXVA(bool aForceD3D9) // The DXVA manager must be created on the main thread. RefPtr event = - new CreateDXVAManagerEvent(aForceD3D9 ? LayersBackend::LAYERS_D3D9 : mLayersBackend, mDXVAFailureReason); + new CreateDXVAManagerEvent(aForceD3D9 ? LayersBackend::LAYERS_D3D9 + : mLayersBackend, + mDXVAFailureReason); if (NS_IsMainThread()) { event->Run(); diff --git a/dom/media/webm/NesteggPacketHolder.h b/dom/media/webm/NesteggPacketHolder.h index f786e66a175f..c1d0b646f207 100644 --- a/dom/media/webm/NesteggPacketHolder.h +++ b/dom/media/webm/NesteggPacketHolder.h @@ -19,7 +19,12 @@ namespace mozilla { class NesteggPacketHolder { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder) - NesteggPacketHolder() : mPacket(nullptr), mOffset(-1), mTimestamp(-1), mIsKeyframe(false) {} + NesteggPacketHolder() + : mPacket(nullptr) + , mOffset(-1) + , mTimestamp(-1) + , mDuration(-1) + , mIsKeyframe(false) {} bool Init(nestegg_packet* aPacket, int64_t aOffset, unsigned aTrack, bool aIsKeyframe) { @@ -36,12 +41,17 @@ public: mTrack = aTrack; mIsKeyframe = aIsKeyframe; + uint64_t duration_ns; + if (!nestegg_packet_duration(aPacket, &duration_ns)) { + mDuration = duration_ns / 1000; + } return true; } nestegg_packet* Packet() { MOZ_ASSERT(IsInitialized()); return mPacket; } int64_t Offset() { MOZ_ASSERT(IsInitialized()); return mOffset; } int64_t Timestamp() { MOZ_ASSERT(IsInitialized()); return mTimestamp; } + int64_t Duration() { MOZ_ASSERT(IsInitialized()); return mDuration; } unsigned Track() { MOZ_ASSERT(IsInitialized()); return mTrack; } bool IsKeyframe() { MOZ_ASSERT(IsInitialized()); return mIsKeyframe; } @@ -62,6 +72,9 @@ private: // Packet presentation timestamp in microseconds. int64_t mTimestamp; + // Packet duration in microseconds; -1 if unknown or retrieval failed. + int64_t mDuration; + // Track ID. unsigned mTrack; diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp index fb983ed191f0..c3a8c8777db6 100644 --- a/dom/media/webm/WebMDemuxer.cpp +++ b/dom/media/webm/WebMDemuxer.cpp @@ -510,8 +510,9 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl return false; } int64_t tstamp = holder->Timestamp(); + int64_t duration = holder->Duration(); - // The end time of this frame is the start time of the next frame. Fetch + // The end time of this frame is the start time of the next frame. Fetch // the timestamp of the next packet for this track. If we've reached the // end of the resource, use the file's duration as the end time of this // video frame. @@ -521,6 +522,8 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl if (next_holder) { next_tstamp = next_holder->Timestamp(); PushAudioPacket(next_holder); + } else if (duration >= 0) { + next_tstamp = tstamp + duration; } else if (!mIsMediaSource || (mIsMediaSource && mLastAudioFrameTime.isSome())) { next_tstamp = tstamp; @@ -534,6 +537,8 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl if (next_holder) { next_tstamp = next_holder->Timestamp(); PushVideoPacket(next_holder); + } else if (duration >= 0) { + next_tstamp = tstamp + duration; } else if (!mIsMediaSource || (mIsMediaSource && mLastVideoFrameTime.isSome())) { next_tstamp = tstamp; @@ -665,7 +670,10 @@ WebMDemuxer::DemuxPacket() { nestegg_packet* packet; int r = nestegg_read_packet(mContext, &packet); - if (r <= 0) { + if (r == 0) { + nestegg_read_reset(mContext); + return nullptr; + } else if (r < 0) { return nullptr; } @@ -892,7 +900,7 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples) void WebMTrackDemuxer::SetNextKeyFrameTime() { - if (mType != TrackInfo::kVideoTrack) { + if (mType != TrackInfo::kVideoTrack || mParent->IsMediaSource()) { return; } @@ -991,11 +999,13 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold) uint32_t parsed = 0; bool found = false; RefPtr sample; + int64_t sampleTime; WEBM_DEBUG("TimeThreshold: %f", aTimeThreshold.ToSeconds()); while (!found && (sample = NextSample())) { parsed++; - if (sample->mKeyframe && sample->mTime >= aTimeThreshold.ToMicroseconds()) { + sampleTime = sample->mTime; + if (sample->mKeyframe && sampleTime >= aTimeThreshold.ToMicroseconds()) { found = true; mSamples.Reset(); mSamples.PushFront(sample.forget()); @@ -1004,7 +1014,7 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold) SetNextKeyFrameTime(); if (found) { WEBM_DEBUG("next sample: %f (parsed: %d)", - media::TimeUnit::FromMicroseconds(sample->mTime).ToSeconds(), + media::TimeUnit::FromMicroseconds(sampleTime).ToSeconds(), parsed); return SkipAccessPointPromise::CreateAndResolve(parsed, __func__); } else { @@ -1025,5 +1035,16 @@ WebMTrackDemuxer::BreakCycles() mParent = nullptr; } +int64_t +WebMTrackDemuxer::GetEvictionOffset(const media::TimeUnit& aTime) +{ + int64_t offset; + if (!mParent->GetOffsetForTime(aTime.ToNanoseconds(), &offset)) { + return 0; + } + + return offset; +} + #undef WEBM_DEBUG } // namespace mozilla diff --git a/dom/media/webm/WebMDemuxer.h b/dom/media/webm/WebMDemuxer.h index d54043bc964e..667c097873da 100644 --- a/dom/media/webm/WebMDemuxer.h +++ b/dom/media/webm/WebMDemuxer.h @@ -230,6 +230,8 @@ public: media::TimeIntervals GetBuffered() override; + int64_t GetEvictionOffset(const media::TimeUnit& aTime) override; + void BreakCycles() override; private: diff --git a/dom/media/webspeech/recognition/PocketSphinxSpeechRecognitionService.cpp b/dom/media/webspeech/recognition/PocketSphinxSpeechRecognitionService.cpp index 7f679005af24..7e1adf42e88f 100644 --- a/dom/media/webspeech/recognition/PocketSphinxSpeechRecognitionService.cpp +++ b/dom/media/webspeech/recognition/PocketSphinxSpeechRecognitionService.cpp @@ -14,6 +14,7 @@ #include "SpeechRecognitionResult.h" #include "SpeechRecognitionResultList.h" #include "nsIObserverService.h" +#include "MediaPrefs.h" #include "mozilla/Services.h" #include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceUtils.h" @@ -302,7 +303,7 @@ PocketSphinxSpeechRecognitionService::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) { - MOZ_ASSERT(mRecognition->mTestConfig.mFakeRecognitionService, + MOZ_ASSERT(MediaPrefs::WebSpeechFakeRecognitionService(), "Got request to fake recognition service event, " "but " TEST_PREFERENCE_FAKE_RECOGNITION_SERVICE " is not set"); diff --git a/dom/moz.build b/dom/moz.build index be3661b7a89e..ca2b28c488d1 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -32,11 +32,9 @@ interfaces = [ 'smil', 'apps', 'gamepad', + 'push', ] -if not CONFIG['MOZ_SIMPLEPUSH']: - interfaces += ['push'] - DIRS += ['interfaces/' + i for i in interfaces] DIRS += [ diff --git a/dom/system/gonk/AutoMounter.cpp b/dom/system/gonk/AutoMounter.cpp index 3e87726a2c44..b29707c328c6 100644 --- a/dom/system/gonk/AutoMounter.cpp +++ b/dom/system/gonk/AutoMounter.cpp @@ -23,6 +23,7 @@ #include "nsVolumeService.h" #include "AutoMounterSetting.h" #include "base/message_loop.h" +#include "base/task.h" #include "mozilla/AutoRestore.h" #include "mozilla/FileUtils.h" #include "mozilla/Hal.h" diff --git a/dom/system/gonk/GonkGPSGeolocationProvider.cpp b/dom/system/gonk/GonkGPSGeolocationProvider.cpp index 6d8d4c55ee17..dfe85d9526d4 100644 --- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp +++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp @@ -20,6 +20,7 @@ #include #include +#include "base/task.h" #include "GeolocationUtil.h" #include "mozstumbler/MozStumbler.h" #include "mozilla/Preferences.h" @@ -813,7 +814,7 @@ GonkGPSGeolocationProvider::Init() } #endif - NS_DispatchToMainThread(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::StartGPS)); + NS_DispatchToMainThread(NewRunnableMethod(this, &GonkGPSGeolocationProvider::StartGPS)); } void @@ -1001,7 +1002,7 @@ GonkGPSGeolocationProvider::Startup() NS_ENSURE_SUCCESS(rv, rv); } - mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::Init), + mInitThread->Dispatch(NewRunnableMethod(this, &GonkGPSGeolocationProvider::Init), NS_DISPATCH_NORMAL); mNetworkLocationProvider = do_CreateInstance("@mozilla.org/geolocation/mls-provider;1"); @@ -1063,7 +1064,7 @@ GonkGPSGeolocationProvider::Shutdown() } } - mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownGPS), + mInitThread->Dispatch(NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownGPS), NS_DISPATCH_NORMAL); return NS_OK; diff --git a/dom/system/gonk/NetworkUtils.cpp b/dom/system/gonk/NetworkUtils.cpp index 7147347c03b9..f683772e5f8c 100644 --- a/dom/system/gonk/NetworkUtils.cpp +++ b/dom/system/gonk/NetworkUtils.cpp @@ -22,6 +22,7 @@ #include #include "mozilla/dom/network/NetUtils.h" #include "mozilla/fallible.h" +#include "base/task.h" #include #include diff --git a/dom/system/gonk/VolumeManager.cpp b/dom/system/gonk/VolumeManager.cpp index bd0b7d77615e..ddfa7af09ee2 100644 --- a/dom/system/gonk/VolumeManager.cpp +++ b/dom/system/gonk/VolumeManager.cpp @@ -13,6 +13,7 @@ #include "nsXULAppAPI.h" #include "base/message_loop.h" +#include "base/task.h" #include "mozilla/Scoped.h" #include "mozilla/StaticPtr.h" diff --git a/dom/system/gonk/nsVolume.cpp b/dom/system/gonk/nsVolume.cpp index e98225cc64c9..77a1628e43bc 100644 --- a/dom/system/gonk/nsVolume.cpp +++ b/dom/system/gonk/nsVolume.cpp @@ -5,6 +5,7 @@ #include "nsVolume.h" #include "base/message_loop.h" +#include "base/task.h" #include "nsIPowerManagerService.h" #include "nsISupportsUtils.h" #include "nsIVolume.h" diff --git a/dom/system/gonk/nsVolumeService.cpp b/dom/system/gonk/nsVolumeService.cpp index 07fd4ff3ed95..5877207d91b8 100644 --- a/dom/system/gonk/nsVolumeService.cpp +++ b/dom/system/gonk/nsVolumeService.cpp @@ -29,6 +29,7 @@ #include "nsXULAppAPI.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/Services.h" +#include "base/task.h" #undef VOLUME_MANAGER_LOG_TAG #define VOLUME_MANAGER_LOG_TAG "nsVolumeService" diff --git a/dom/webidl/BrowserElement.webidl b/dom/webidl/BrowserElement.webidl index d889bd5f55e6..3ec8fcf14ac6 100644 --- a/dom/webidl/BrowserElement.webidl +++ b/dom/webidl/BrowserElement.webidl @@ -175,11 +175,6 @@ interface BrowserElementPrivileged { DOMRequest executeScript(DOMString script, optional BrowserElementExecuteScriptOptions options); - [Throws, - Pref="dom.mozBrowserFramesEnabled", - CheckAllPermissions="browser"] - DOMRequest getStructuredData(); - [Throws, Pref="dom.mozBrowserFramesEnabled", CheckAllPermissions="browser"] diff --git a/dom/xbl/nsXBLBinding.cpp b/dom/xbl/nsXBLBinding.cpp index 004db9d01847..9c463284f6d4 100644 --- a/dom/xbl/nsXBLBinding.cpp +++ b/dom/xbl/nsXBLBinding.cpp @@ -957,6 +957,15 @@ GetOrCreateMapEntryForPrototype(JSContext *cx, JS::Handle proto) return entry; } +static +nsXBLPrototypeBinding* +GetProtoBindingFromClassObject(JSObject* obj) +{ + MOZ_ASSERT(JS_GetClass(obj) == &gPrototypeJSClass); + return static_cast(::JS_GetReservedSlot(obj, 0).toPrivate()); +} + + // static nsresult nsXBLBinding::DoInitJSClass(JSContext *cx, @@ -1012,7 +1021,9 @@ nsXBLBinding::DoInitJSClass(JSContext *cx, *aNew = !desc.object(); if (desc.object()) { proto = &desc.value().toObject(); - MOZ_ASSERT(JS_GetClass(js::UncheckedUnwrap(proto)) == &gPrototypeJSClass); + DebugOnly cachedBinding = + GetProtoBindingFromClassObject(js::UncheckedUnwrap(proto)); + MOZ_ASSERT(cachedBinding == aProtoBinding); } else { // We need to create the prototype. First, enter the compartment where it's diff --git a/dom/xbl/nsXBLService.cpp b/dom/xbl/nsXBLService.cpp index d37bca722453..fdc1445216a8 100644 --- a/dom/xbl/nsXBLService.cpp +++ b/dom/xbl/nsXBLService.cpp @@ -858,119 +858,120 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsresult rv = aBindingURI->CloneIgnoringRef(getter_AddRefs(documentURI)); NS_ENSURE_SUCCESS(rv, rv); + nsBindingManager *bindingManager = nullptr; + + // The first thing to check is the binding manager, which (if it exists) + // should have a reference to the nsXBLDocumentInfo if this document + // has ever loaded this binding before. + if (aBoundDocument) { + bindingManager = aBoundDocument->BindingManager(); + info = bindingManager->GetXBLDocumentInfo(documentURI); + if (aBoundDocument->IsStaticDocument() && + IsChromeOrResourceURI(aBindingURI)) { + aForceSyncLoad = true; + } + } + + // It's possible the document is already being loaded. If so, there's no + // document yet, but we need to glom on our request so that it will be + // processed whenever the doc does finish loading. + NodeInfo *ni = nullptr; + if (aBoundElement) + ni = aBoundElement->NodeInfo(); + + if (!info && bindingManager && + (!ni || !(ni->Equals(nsGkAtoms::scrollbar, kNameSpaceID_XUL) || + ni->Equals(nsGkAtoms::thumb, kNameSpaceID_XUL) || + ((ni->Equals(nsGkAtoms::input) || + ni->Equals(nsGkAtoms::select)) && + aBoundElement->IsHTMLElement()))) && !aForceSyncLoad) { + nsCOMPtr listener; + if (bindingManager) + listener = bindingManager->GetLoadingDocListener(documentURI); + if (listener) { + nsXBLStreamListener* xblListener = + static_cast(listener.get()); + // Create a new load observer. + if (!xblListener->HasRequest(aBindingURI, aBoundElement)) { + nsXBLBindingRequest* req = new nsXBLBindingRequest(aBindingURI, aBoundElement); + xblListener->AddRequest(req); + } + return NS_OK; + } + } + #ifdef MOZ_XUL - // We've got a file. Check our XBL document cache. + // The second line of defense is the global nsXULPrototypeCache, + // if it's being used. nsXULPrototypeCache* cache = nsXULPrototypeCache::GetInstance(); bool useXULCache = cache && cache->IsEnabled(); - if (useXULCache) { - // The first line of defense is the chrome cache. + if (!info && useXULCache) { // This cache crosses the entire product, so that any XBL bindings that are // part of chrome will be reused across all XUL documents. info = cache->GetXBLDocumentInfo(documentURI); } -#endif + + bool useStartupCache = useXULCache && IsChromeOrResourceURI(documentURI); if (!info) { - // The second line of defense is the binding manager's document table. - nsBindingManager *bindingManager = nullptr; - - if (aBoundDocument) { - bindingManager = aBoundDocument->BindingManager(); - info = bindingManager->GetXBLDocumentInfo(documentURI); - if (aBoundDocument->IsStaticDocument() && - IsChromeOrResourceURI(aBindingURI)) { - aForceSyncLoad = true; - } - } - - NodeInfo *ni = nullptr; - if (aBoundElement) - ni = aBoundElement->NodeInfo(); - - if (!info && bindingManager && - (!ni || !(ni->Equals(nsGkAtoms::scrollbar, kNameSpaceID_XUL) || - ni->Equals(nsGkAtoms::thumb, kNameSpaceID_XUL) || - ((ni->Equals(nsGkAtoms::input) || - ni->Equals(nsGkAtoms::select)) && - aBoundElement->IsHTMLElement()))) && !aForceSyncLoad) { - // The third line of defense is to investigate whether or not the - // document is currently being loaded asynchronously. If so, there's no - // document yet, but we need to glom on our request so that it will be - // processed whenever the doc does finish loading. - nsCOMPtr listener; - if (bindingManager) - listener = bindingManager->GetLoadingDocListener(documentURI); - if (listener) { - nsXBLStreamListener* xblListener = - static_cast(listener.get()); - // Create a new load observer. - if (!xblListener->HasRequest(aBindingURI, aBoundElement)) { - nsXBLBindingRequest* req = new nsXBLBindingRequest(aBindingURI, aBoundElement); - xblListener->AddRequest(req); - } - return NS_OK; - } - } - -#ifdef MOZ_XUL // Next, look in the startup cache - bool useStartupCache = useXULCache && IsChromeOrResourceURI(documentURI); if (!info && useStartupCache) { rv = nsXBLDocumentInfo::ReadPrototypeBindings(documentURI, getter_AddRefs(info)); if (NS_SUCCEEDED(rv)) { cache->PutXBLDocumentInfo(info); - - if (bindingManager) { - // Cache it in our binding manager's document table. - bindingManager->PutXBLDocumentInfo(info); - } } } + } #endif - if (!info) { - // Finally, if all lines of defense fail, we go and fetch the binding - // document. + if (!info) { + // Finally, if all lines of defense fail, we go and fetch the binding + // document. - // Always load chrome synchronously - bool chrome; - if (NS_SUCCEEDED(documentURI->SchemeIs("chrome", &chrome)) && chrome) - aForceSyncLoad = true; + // Always load chrome synchronously + bool chrome; + if (NS_SUCCEEDED(documentURI->SchemeIs("chrome", &chrome)) && chrome) + aForceSyncLoad = true; - nsCOMPtr document; - rv = FetchBindingDocument(aBoundElement, aBoundDocument, documentURI, - aBindingURI, aOriginPrincipal, aForceSyncLoad, - getter_AddRefs(document)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr document; + rv = FetchBindingDocument(aBoundElement, aBoundDocument, documentURI, + aBindingURI, aOriginPrincipal, aForceSyncLoad, + getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, rv); - if (document) { - nsBindingManager *xblDocBindingManager = document->BindingManager(); - info = xblDocBindingManager->GetXBLDocumentInfo(documentURI); - if (!info) { - NS_ERROR("An XBL file is malformed. Did you forget the XBL namespace on the bindings tag?"); - return NS_ERROR_FAILURE; - } - xblDocBindingManager->RemoveXBLDocumentInfo(info); // Break the self-imposed cycle. + if (document) { + nsBindingManager *xblDocBindingManager = document->BindingManager(); + info = xblDocBindingManager->GetXBLDocumentInfo(documentURI); + if (!info) { + NS_ERROR("An XBL file is malformed. Did you forget the XBL namespace on the bindings tag?"); + return NS_ERROR_FAILURE; + } + xblDocBindingManager->RemoveXBLDocumentInfo(info); // Break the self-imposed cycle. - // If the doc is a chrome URI, then we put it into the XUL cache. + // If the doc is a chrome URI, then we put it into the XUL cache. #ifdef MOZ_XUL - if (useStartupCache) { - cache->PutXBLDocumentInfo(info); + if (useStartupCache) { + cache->PutXBLDocumentInfo(info); - // now write the bindings into the startup cache - info->WritePrototypeBindings(); - } -#endif - - if (bindingManager) { - // Also put it in our binding manager's document table. - bindingManager->PutXBLDocumentInfo(info); - } + // now write the bindings into the startup cache + info->WritePrototypeBindings(); } +#endif } } + if (info && bindingManager) { + // Cache it in our binding manager's document table. This way, + // we can ensure that if the document has loaded this binding + // before, it can continue to use it even if the XUL prototype + // cache gets flushed. That way, if a flush does occur, we + // don't get into a weird state where we're using different + // XBLDocumentInfos for the same XBL document in a single + // document that has loaded some bindings. + bindingManager->PutXBLDocumentInfo(info); + } + info.forget(aResult); return NS_OK; diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index 88e75df3c375..5dc6f0c95c05 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -136,7 +136,7 @@ DrawTargetSkia::DrawTargetSkia() : mSnapshot(nullptr) #ifdef MOZ_WIDGET_COCOA , mCG(nullptr) - , mColorSpace(CGColorSpaceCreateDeviceRGB()) + , mColorSpace(nullptr) , mCanvasData(nullptr) , mCGSize(0, 0) #endif @@ -147,10 +147,14 @@ DrawTargetSkia::~DrawTargetSkia() { #ifdef MOZ_WIDGET_COCOA if (mCG) { - CGColorSpaceRelease(mColorSpace); CGContextRelease(mCG); mCG = nullptr; } + + if (mColorSpace) { + CGColorSpaceRelease(mColorSpace); + mColorSpace = nullptr; + } #endif } @@ -844,6 +848,10 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions) return mCG; } + if (!mColorSpace) { + mColorSpace = CGColorSpaceCreateDeviceRGB(); + } + if (mCG) { // Release the old CG context since it's no longer valid. CGContextRelease(mCG); @@ -923,6 +931,7 @@ DrawTargetSkia::FillGlyphsWithCG(ScaledFont *aFont, Vector glyphs; Vector positions; if (!SetupCGGlyphs(cgContext, aBuffer, glyphs, positions)) { + ReturnCGContext(cgContext); return false; } diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 2ff04f4d5172..f00fc68c1fc5 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -141,6 +141,7 @@ enum class LogReason : int { InvalidCommandList, AsyncTransactionTimeout, // 30 TextureCreation, + InvalidCacheSurface, // End MustBeLessThanThis = 101, }; diff --git a/gfx/graphite2/src/moz.build b/gfx/graphite2/src/moz.build index 4008b77063d9..c18c6f497407 100644 --- a/gfx/graphite2/src/moz.build +++ b/gfx/graphite2/src/moz.build @@ -45,7 +45,6 @@ UNIFIED_SOURCES += [ 'Intervals.cpp', 'json.cpp', 'Justifier.cpp', - 'NameTable.cpp', 'Pass.cpp', 'Position.cpp', 'SegCache.cpp', @@ -59,6 +58,12 @@ UNIFIED_SOURCES += [ 'UtfCodec.cpp', ] +# Excluded from UNIFIED_SOURCES because from other files breaks it, +# see bug 1272647. +SOURCES += [ + 'NameTable.cpp', +] + # tell graphite2 not to export symbols, we'll be linking it directly with # thebes DEFINES['GRAPHITE2_STATIC'] = True diff --git a/gfx/src/nsThemeConstants.h b/gfx/src/nsThemeConstants.h index 0c3f40a6d630..1dbcd6ecfc83 100644 --- a/gfx/src/nsThemeConstants.h +++ b/gfx/src/nsThemeConstants.h @@ -28,13 +28,13 @@ #define NS_THEME_TOOLBAR 12 // A single toolbar button (with no associated dropdown) -#define NS_THEME_TOOLBAR_BUTTON 13 +#define NS_THEME_TOOLBARBUTTON 13 // A dual toolbar button (e.g., a Back button with a dropdown) -#define NS_THEME_TOOLBAR_DUAL_BUTTON 14 +#define NS_THEME_DUALBUTTON 14 // The dropdown portion of a toolbar button -#define NS_THEME_TOOLBAR_BUTTON_DROPDOWN 15 +#define NS_THEME_TOOLBARBUTTON_DROPDOWN 15 // Various arrows that go in buttons #define NS_THEME_BUTTON_ARROW_UP 16 @@ -43,10 +43,10 @@ #define NS_THEME_BUTTON_ARROW_PREVIOUS 19 // A separator. Can be horizontal or vertical. -#define NS_THEME_TOOLBAR_SEPARATOR 20 +#define NS_THEME_SEPARATOR 20 // The gripper for a toolbar. -#define NS_THEME_TOOLBAR_GRIPPER 21 +#define NS_THEME_TOOLBARGRIPPER 21 // A splitter. Can be horizontal or vertical. #define NS_THEME_SPLITTER 22 @@ -55,11 +55,11 @@ #define NS_THEME_STATUSBAR 23 // A single pane of a status bar. -#define NS_THEME_STATUSBAR_PANEL 24 +#define NS_THEME_STATUSBARPANEL 24 // The resizer background area in a status bar // for the resizer widget in the corner of a window. -#define NS_THEME_STATUSBAR_RESIZER_PANEL 25 +#define NS_THEME_RESIZER_PANEL 25 // The resizer itself. #define NS_THEME_RESIZER 26 @@ -68,62 +68,62 @@ #define NS_THEME_LISTBOX 31 // A listbox item -#define NS_THEME_LISTBOX_LISTITEM 32 +#define NS_THEME_LISTITEM 32 // A tree widget #define NS_THEME_TREEVIEW 41 // A tree item -#define NS_THEME_TREEVIEW_TREEITEM 42 +#define NS_THEME_TREEITEM 42 // A tree widget twisty -#define NS_THEME_TREEVIEW_TWISTY 43 +#define NS_THEME_TREETWISTY 43 // A tree widget branch line -#define NS_THEME_TREEVIEW_LINE 44 +#define NS_THEME_TREELINE 44 // A listbox or tree widget header -#define NS_THEME_TREEVIEW_HEADER 45 +#define NS_THEME_TREEHEADER 45 // An individual header cell -#define NS_THEME_TREEVIEW_HEADER_CELL 46 +#define NS_THEME_TREEHEADERCELL 46 // The sort arrow for a header. -#define NS_THEME_TREEVIEW_HEADER_SORTARROW 47 +#define NS_THEME_TREEHEADERSORTARROW 47 // Open tree widget twisty -#define NS_THEME_TREEVIEW_TWISTY_OPEN 48 +#define NS_THEME_TREETWISTYOPEN 48 // A horizontal progress bar. #define NS_THEME_PROGRESSBAR 51 // The progress bar's progress indicator -#define NS_THEME_PROGRESSBAR_CHUNK 52 +#define NS_THEME_PROGRESSCHUNK 52 // A vertical progress bar. #define NS_THEME_PROGRESSBAR_VERTICAL 53 // A vertical progress chunk -#define NS_THEME_PROGRESSBAR_CHUNK_VERTICAL 54 +#define NS_THEME_PROGRESSCHUNK_VERTICAL 54 // A horizontal meter bar. #define NS_THEME_METERBAR 55 // The meter bar's meter indicator -#define NS_THEME_METERBAR_CHUNK 56 +#define NS_THEME_METERCHUNK 56 // A single tab in a tab widget. #define NS_THEME_TAB 61 // A single pane (inside the tabpanels container) -#define NS_THEME_TAB_PANEL 62 +#define NS_THEME_TABPANEL 62 // The tab panels container. -#define NS_THEME_TAB_PANELS 65 +#define NS_THEME_TABPANELS 65 // The tabs scroll arrows (left/right) -#define NS_THEME_TAB_SCROLLARROW_BACK 66 -#define NS_THEME_TAB_SCROLLARROW_FORWARD 67 +#define NS_THEME_TAB_SCROLL_ARROW_BACK 66 +#define NS_THEME_TAB_SCROLL_ARROW_FORWARD 67 // A tooltip #define NS_THEME_TOOLTIP 71 @@ -132,10 +132,10 @@ #define NS_THEME_SPINNER 72 // The up button of a spin control -#define NS_THEME_SPINNER_UP_BUTTON 73 +#define NS_THEME_SPINNER_UPBUTTON 73 // The down button of a spin control -#define NS_THEME_SPINNER_DOWN_BUTTON 74 +#define NS_THEME_SPINNER_DOWNBUTTON 74 // The textfield of a spin control #define NS_THEME_SPINNER_TEXTFIELD 75 @@ -154,18 +154,18 @@ #define NS_THEME_SCROLLBAR_VERTICAL 83 // A scrollbar button (up/down/left/right) -#define NS_THEME_SCROLLBAR_BUTTON_UP 84 -#define NS_THEME_SCROLLBAR_BUTTON_DOWN 85 -#define NS_THEME_SCROLLBAR_BUTTON_LEFT 86 -#define NS_THEME_SCROLLBAR_BUTTON_RIGHT 87 +#define NS_THEME_SCROLLBARBUTTON_UP 84 +#define NS_THEME_SCROLLBARBUTTON_DOWN 85 +#define NS_THEME_SCROLLBARBUTTON_LEFT 86 +#define NS_THEME_SCROLLBARBUTTON_RIGHT 87 // The scrollbar track -#define NS_THEME_SCROLLBAR_TRACK_HORIZONTAL 88 -#define NS_THEME_SCROLLBAR_TRACK_VERTICAL 89 +#define NS_THEME_SCROLLBARTRACK_HORIZONTAL 88 +#define NS_THEME_SCROLLBARTRACK_VERTICAL 89 // The scrollbar thumb -#define NS_THEME_SCROLLBAR_THUMB_HORIZONTAL 90 -#define NS_THEME_SCROLLBAR_THUMB_VERTICAL 91 +#define NS_THEME_SCROLLBARTHUMB_HORIZONTAL 90 +#define NS_THEME_SCROLLBARTHUMB_VERTICAL 91 // A non-disappearing scrollbar. #define NS_THEME_SCROLLBAR_NON_DISAPPEARING 92 @@ -183,36 +183,36 @@ #define NS_THEME_SEARCHFIELD 98 // A dropdown list. -#define NS_THEME_DROPDOWN 101 +#define NS_THEME_MENULIST 101 // The dropdown button(s) that open up a dropdown list. -#define NS_THEME_DROPDOWN_BUTTON 102 +#define NS_THEME_MENULIST_BUTTON 102 // The text part of a dropdown list, to left of button -#define NS_THEME_DROPDOWN_TEXT 103 +#define NS_THEME_MENULIST_TEXT 103 // An editable textfield with a dropdown list (a combobox) -#define NS_THEME_DROPDOWN_TEXTFIELD 104 +#define NS_THEME_MENULIST_TEXTFIELD 104 // A slider -#define NS_THEME_SCALE_HORIZONTAL 111 -#define NS_THEME_SCALE_VERTICAL 112 +#define NS_THEME_SCALE_HORIZONTAL 111 +#define NS_THEME_SCALE_VERTICAL 112 // A slider's thumb -#define NS_THEME_SCALE_THUMB_HORIZONTAL 113 -#define NS_THEME_SCALE_THUMB_VERTICAL 114 +#define NS_THEME_SCALETHUMB_HORIZONTAL 113 +#define NS_THEME_SCALETHUMB_VERTICAL 114 // If the platform supports it, the left/right chunks // of the slider thumb -#define NS_THEME_SCALE_THUMB_START 115 -#define NS_THEME_SCALE_THUMB_END 116 +#define NS_THEME_SCALETHUMBSTART 115 +#define NS_THEME_SCALETHUMBEND 116 // The ticks for a slider. -#define NS_THEME_SCALE_TICK 117 +#define NS_THEME_SCALETHUMBTICK 117 // nsRangeFrame and its subparts -#define NS_THEME_RANGE 120 -#define NS_THEME_RANGE_THUMB 121 +#define NS_THEME_RANGE 120 +#define NS_THEME_RANGE_THUMB 121 // A groupbox #define NS_THEME_GROUPBOX 149 @@ -257,13 +257,13 @@ // Vista Rebars #define NS_THEME_WIN_COMMUNICATIONS_TOOLBOX 221 #define NS_THEME_WIN_MEDIA_TOOLBOX 222 -#define NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX 223 +#define NS_THEME_WIN_BROWSERTABBAR_TOOLBOX 223 // Titlebar elements on the Mac -#define NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON 226 +#define NS_THEME_MAC_FULLSCREEN_BUTTON 226 // Mac help button -#define NS_THEME_MOZ_MAC_HELP_BUTTON 227 +#define NS_THEME_MAC_HELP_BUTTON 227 // Vista glass #define NS_THEME_WIN_BORDERLESS_GLASS 229 diff --git a/gfx/thebes/gfxGraphiteShaper.cpp b/gfx/thebes/gfxGraphiteShaper.cpp index 8505a8ef1301..c59676d2ee3f 100644 --- a/gfx/thebes/gfxGraphiteShaper.cpp +++ b/gfx/thebes/gfxGraphiteShaper.cpp @@ -262,6 +262,11 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget, NS_ASSERTION(cIndex < aLength, "cIndex beyond word length"); ++clusters[cIndex].nGlyphs; + // bump |after| index if it falls in the middle of a surrogate pair + if (NS_IS_HIGH_SURROGATE(aText[after]) && after < aLength - 1 && + NS_IS_LOW_SURROGATE(aText[after + 1])) { + after++; + } // extend cluster if necessary to reach the glyph's "after" index if (clusters[cIndex].baseChar + clusters[cIndex].nChars < after + 1) { clusters[cIndex].nChars = after + 1 - clusters[cIndex].baseChar; diff --git a/hal/gonk/GonkDiskSpaceWatcher.cpp b/hal/gonk/GonkDiskSpaceWatcher.cpp index 048fccf13786..5b070b3011f3 100644 --- a/hal/gonk/GonkDiskSpaceWatcher.cpp +++ b/hal/gonk/GonkDiskSpaceWatcher.cpp @@ -8,6 +8,7 @@ #include #include #include "base/message_loop.h" +#include "base/task.h" #include "DiskSpaceWatcher.h" #include "fanotify.h" #include "nsIObserverService.h" @@ -24,13 +25,6 @@ namespace mozilla { namespace hal_impl { class GonkDiskSpaceWatcher; } } using namespace mozilla::hal_impl; -template<> -struct RunnableMethodTraits -{ - static void RetainCallee(GonkDiskSpaceWatcher* obj) { } - static void ReleaseCallee(GonkDiskSpaceWatcher* obj) { } -}; - namespace mozilla { namespace hal_impl { @@ -311,7 +305,7 @@ StartDiskSpaceWatcher() gHalDiskSpaceWatcher = new GonkDiskSpaceWatcher(); XRE_GetIOMessageLoop()->PostTask( - NewRunnableMethod(gHalDiskSpaceWatcher, &GonkDiskSpaceWatcher::DoStart)); + NewNonOwningRunnableMethod(gHalDiskSpaceWatcher, &GonkDiskSpaceWatcher::DoStart)); } void @@ -323,7 +317,7 @@ StopDiskSpaceWatcher() } XRE_GetIOMessageLoop()->PostTask( - NewRunnableMethod(gHalDiskSpaceWatcher, &GonkDiskSpaceWatcher::DoStop)); + NewNonOwningRunnableMethod(gHalDiskSpaceWatcher, &GonkDiskSpaceWatcher::DoStop)); } } // namespace hal_impl diff --git a/hal/gonk/GonkHal.cpp b/hal/gonk/GonkHal.cpp index d3955261851f..483081d904cc 100644 --- a/hal/gonk/GonkHal.cpp +++ b/hal/gonk/GonkHal.cpp @@ -43,6 +43,7 @@ #include "utils/threads.h" #include "base/message_loop.h" +#include "base/task.h" #include "Hal.h" #include "HalImpl.h" diff --git a/hal/gonk/GonkSensor.cpp b/hal/gonk/GonkSensor.cpp index 3d2135dc9e49..abf155f89ba6 100644 --- a/hal/gonk/GonkSensor.cpp +++ b/hal/gonk/GonkSensor.cpp @@ -22,6 +22,7 @@ #include "base/basictypes.h" #include "base/thread.h" +#include "base/task.h" #include "GonkSensorsInterface.h" #include "GonkSensorsPollInterface.h" diff --git a/hal/gonk/GonkSwitch.cpp b/hal/gonk/GonkSwitch.cpp index 9aaa80cad51e..8eae1b04b3b1 100644 --- a/hal/gonk/GonkSwitch.cpp +++ b/hal/gonk/GonkSwitch.cpp @@ -18,6 +18,7 @@ #include #include "base/message_loop.h" +#include "base/task.h" #include "Hal.h" #include "HalLog.h" diff --git a/hal/gonk/UeventPoller.cpp b/hal/gonk/UeventPoller.cpp index 447c998df04c..3fbe850ed53a 100644 --- a/hal/gonk/UeventPoller.cpp +++ b/hal/gonk/UeventPoller.cpp @@ -31,6 +31,7 @@ #include "HalLog.h" #include "nsDebug.h" #include "base/message_loop.h" +#include "base/task.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/FileUtils.h" #include "mozilla/Monitor.h" diff --git a/image/SurfaceCache.cpp b/image/SurfaceCache.cpp index b4063f08f395..b607077985d3 100644 --- a/image/SurfaceCache.cpp +++ b/image/SurfaceCache.cpp @@ -1036,7 +1036,8 @@ SurfaceCache::Insert(imgFrame* aSurface, // Refuse null surfaces. if (!aSurface) { - MOZ_CRASH("Don't pass null surfaces to SurfaceCache::Insert"); + gfxDevCrash(LogReason::InvalidCacheSurface) << "Null surface in SurfaceCache::Insert"; + return InsertOutcome::FAILURE; } MutexAutoLock lock(sInstance->GetMutex()); diff --git a/intl/uconv/nsTextToSubURI.cpp b/intl/uconv/nsTextToSubURI.cpp index b438f4d50d9a..7006779bb828 100644 --- a/intl/uconv/nsTextToSubURI.cpp +++ b/intl/uconv/nsTextToSubURI.cpp @@ -87,8 +87,7 @@ NS_IMETHODIMP nsTextToSubURI::ConvertAndEscape( outlen += finLen; } } - pBuf[outlen] = '\0'; - *_retval = nsEscape(pBuf, url_XPAlphas); + *_retval = nsEscape(pBuf, outlen, nullptr, url_XPAlphas); if (nullptr == *_retval) { rv = NS_ERROR_OUT_OF_MEMORY; } diff --git a/ipc/netd/Netd.cpp b/ipc/netd/Netd.cpp index c8add38ac51b..e690224dcd4b 100644 --- a/ipc/netd/Netd.cpp +++ b/ipc/netd/Netd.cpp @@ -9,6 +9,7 @@ #include #include "android/log.h" +#include "base/task.h" #include "nsWhitespaceTokenizer.h" #include "nsXULAppAPI.h" diff --git a/js/public/HeapAPI.h b/js/public/HeapAPI.h index 3d5cb547473a..75b7621dca3e 100644 --- a/js/public/HeapAPI.h +++ b/js/public/HeapAPI.h @@ -114,13 +114,21 @@ struct Zone JSTracer* const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|. public: + // Stack GC roots for Rooted GC pointers. + js::RootedListHeads stackRoots_; + template friend class JS::Rooted; + bool needsIncrementalBarrier_; Zone(JSRuntime* runtime, JSTracer* barrierTracerArg) : runtime_(runtime), barrierTracer_(barrierTracerArg), needsIncrementalBarrier_(false) - {} + { + for (auto& stackRootPtr : stackRoots_) { + stackRootPtr = nullptr; + } + } bool needsIncrementalBarrier() const { return needsIncrementalBarrier_; @@ -143,7 +151,7 @@ struct Zone return runtime_; } - static JS::shadow::Zone* asShadowZone(JS::Zone* zone) { + static MOZ_ALWAYS_INLINE JS::shadow::Zone* asShadowZone(JS::Zone* zone) { return reinterpret_cast(zone); } }; diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index ccea2bbe07b9..4a225f9a34de 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -634,18 +634,25 @@ namespace JS { template class MOZ_RAII Rooted : public js::RootedBase { - /* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */ - void registerWithRootLists(js::RootLists& roots) { - this->stack = &roots.stackRoots_[JS::MapTypeToRootKind::kind]; + inline void registerWithRootLists(js::RootedListHeads& roots) { + this->stack = &roots[JS::MapTypeToRootKind::kind]; this->prev = *stack; *stack = reinterpret_cast*>(this); } - js::RootLists& rootLists(js::ContextFriendFields* cx) { return cx->roots; } - js::RootLists& rootLists(JSContext* cx) { return js::ContextFriendFields::get(cx)->roots; } - js::RootLists& rootLists(js::PerThreadDataFriendFields* pt) { return pt->roots; } - js::RootLists& rootLists(JSRuntime* rt) { - return js::PerThreadDataFriendFields::getMainThread(rt)->roots; + inline js::RootedListHeads& rootLists(js::ContextFriendFields* cx) { + return rootLists(reinterpret_cast(cx)); + } + inline js::RootedListHeads& rootLists(JSContext* cx) { + if (JS::Zone* zone = js::GetContextZone(cx)) + return JS::shadow::Zone::asShadowZone(zone)->stackRoots_; + return rootLists(js::GetRuntime(cx)); + } + inline js::RootedListHeads& rootLists(js::PerThreadDataFriendFields* pt) { + return pt->roots.stackRoots_; + } + inline js::RootedListHeads& rootLists(JSRuntime* rt) { + return js::PerThreadDataFriendFields::getMainThread(rt)->roots.stackRoots_; } public: diff --git a/js/public/TraceKind.h b/js/public/TraceKind.h index 3a2cce9c5c61..3f2f18e6aef9 100644 --- a/js/public/TraceKind.h +++ b/js/public/TraceKind.h @@ -98,15 +98,10 @@ JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); enum class RootKind : int8_t { // These map 1:1 with trace kinds. - BaseShape = 0, - JitCode, - LazyScript, - Object, - ObjectGroup, - Script, - Shape, - String, - Symbol, +#define EXPAND_ROOT_KIND(name, _0, _1) \ + name, +JS_FOR_EACH_TRACEKIND(EXPAND_ROOT_KIND) +#undef EXPAND_ROOT_KIND // These tagged pointers are special-cased for performance. Id, diff --git a/js/src/asmjs/Wasm.cpp b/js/src/asmjs/Wasm.cpp index b028e03f67ed..b789a5cc791b 100644 --- a/js/src/asmjs/Wasm.cpp +++ b/js/src/asmjs/Wasm.cpp @@ -53,7 +53,7 @@ Fail(JSContext* cx, const char* str) } static bool -Fail(JSContext* cx, Decoder& d, const char* str) +Fail(JSContext* cx, const Decoder& d, const char* str) { uint32_t offset = d.currentOffset(); char offsetStr[sizeof "4294967295"]; @@ -83,7 +83,7 @@ class ValidatingPolicy : public ExprIterPolicy static const bool Validate = true; // Fail by printing a message, using the contains JSContext. - bool fail(const char* str, Decoder& d) { + bool fail(const char* str, const Decoder& d) { return Fail(cx_, d, str); } @@ -97,20 +97,17 @@ class FunctionDecoder const ModuleGenerator& mg_; ValidatingExprIter iter_; const ValTypeVector& locals_; - const DeclaredSig& sig_; public: FunctionDecoder(JSContext* cx, const ModuleGenerator& mg, Decoder& d, - uint32_t funcIndex, const ValTypeVector& locals) + const ValTypeVector& locals) : mg_(mg), iter_(ValidatingPolicy(cx), d), - locals_(locals), - sig_(mg.funcSig(funcIndex)) + locals_(locals) {} const ModuleGenerator& mg() const { return mg_; } ValidatingExprIter& iter() { return iter_; } const ValTypeVector& locals() const { return locals_; } - const DeclaredSig& sig() const { return sig_; } bool checkI64Support() { if (!IsI64Implemented()) @@ -790,19 +787,23 @@ DecodeMemorySection(JSContext* cx, Decoder& d, ModuleGenerator& mg, MutableHandl if (!d.readVarU32(&initialSizePages)) return Fail(cx, d, "expected initial memory size"); - CheckedInt initialSize = initialSizePages; + CheckedInt initialSize = initialSizePages; initialSize *= PageSize; if (!initialSize.isValid()) return Fail(cx, d, "initial memory size too big"); + // ArrayBufferObject can't currently allocate more than INT32_MAX bytes. + if (initialSize.value() > uint32_t(INT32_MAX)) + return false; + uint32_t maxSizePages; if (!d.readVarU32(&maxSizePages)) return Fail(cx, d, "expected initial memory size"); - CheckedInt maxSize = maxSizePages; + CheckedInt maxSize = maxSizePages; maxSize *= PageSize; if (!maxSize.isValid()) - return Fail(cx, d, "initial memory size too big"); + return Fail(cx, d, "maximum memory size too big"); uint8_t exported; if (!d.readFixedU8(&exported)) @@ -932,7 +933,8 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func return false; ValTypeVector locals; - if (!locals.appendAll(mg.funcSig(funcIndex).args())) + const DeclaredSig& sig = mg.funcSig(funcIndex); + if (!locals.appendAll(sig.args())) return false; if (!DecodeLocalEntries(d, &locals)) @@ -943,7 +945,7 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func return false; } - FunctionDecoder f(cx, mg, d, funcIndex, locals); + FunctionDecoder f(cx, mg, d, locals); if (!f.iter().readFunctionStart()) return false; @@ -953,7 +955,7 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func return false; } - if (!f.iter().readFunctionEnd(f.sig().ret(), nullptr)) + if (!f.iter().readFunctionEnd(sig.ret(), nullptr)) return false; if (d.currentPosition() != bodyEnd) diff --git a/js/src/asmjs/WasmBinary.h b/js/src/asmjs/WasmBinary.h index c481af2c7b7a..92476d77efd6 100644 --- a/js/src/asmjs/WasmBinary.h +++ b/js/src/asmjs/WasmBinary.h @@ -664,9 +664,9 @@ class Decoder return cur_ == end_; } - uintptr_t bytesRemain() const { + size_t bytesRemain() const { MOZ_ASSERT(end_ >= cur_); - return uintptr_t(end_ - cur_); + return size_t(end_ - cur_); } const uint8_t* currentPosition() const { return cur_; diff --git a/js/src/asmjs/WasmBinaryIterator.h b/js/src/asmjs/WasmBinaryIterator.h index 931fb65677cc..e0ffba54888f 100644 --- a/js/src/asmjs/WasmBinaryIterator.h +++ b/js/src/asmjs/WasmBinaryIterator.h @@ -205,7 +205,7 @@ struct ExprIterPolicy static const bool Output = false; // This function is called to report failures. - static bool fail(const char*, Decoder&) { + static bool fail(const char*, const Decoder&) { MOZ_CRASH("unexpected validation failure"); return false; } @@ -666,7 +666,7 @@ ExprIter::readReturn(Value* value) uint32_t arity; if (!readVarU32(&arity)) return fail("failed to read return arity"); - if (arity > 1) + if (Validate && arity > 1) return fail("return arity too big"); TypeAndValue tv; @@ -880,7 +880,7 @@ ExprIter::readBr(uint32_t* relativeDepth, ExprType* type, Value* value) uint32_t arity; if (!readVarU32(&arity)) return fail("unable to read br arity"); - if (arity > 1) + if (Validate && arity > 1) return fail("br arity too big"); uint32_t validateRelativeDepth; @@ -919,7 +919,7 @@ ExprIter::readBrIf(uint32_t* relativeDepth, ExprType* type, Value* value uint32_t arity; if (!readVarU32(&arity)) return fail("unable to read br_if arity"); - if (arity > 1) + if (Validate && arity > 1) return fail("br_if arity too big"); uint32_t validateRelativeDepth; @@ -964,7 +964,7 @@ ExprIter::readBrTable(uint32_t* tableLength, ExprType* type, uint32_t arity; if (!readVarU32(&arity)) return fail("unable to read br_table arity"); - if (arity > 1) + if (Validate && arity > 1) return fail("br_table arity too big"); TypeAndValue tv; diff --git a/js/src/devtools/automation/autospider.sh b/js/src/devtools/automation/autospider.sh index 27716b57bbe9..73c6dca48477 100755 --- a/js/src/devtools/automation/autospider.sh +++ b/js/src/devtools/automation/autospider.sh @@ -55,6 +55,11 @@ if [ ! -f "$ABSDIR/variants/$VARIANT" ]; then exit 1 fi +if [[ "$VARIANT" = "nonunified" ]]; then + # Hack the moz.build files to turn off unified compilation. + find "$SOURCE/js/src" -name moz.build -exec sed -i 's/UNIFIED_SOURCES/SOURCES/' '{}' ';' +fi + (cd "$SOURCE/js/src"; autoconf-2.13 || autoconf2.13 || autoconf213) TRY_OVERRIDE=$SOURCE/js/src/config.try @@ -216,6 +221,10 @@ elif [[ "$VARIANT" = "arm-sim" || "$VARIANT" = "arm-sim-osx" || "$VARIANT" = "plaindebug" ]]; then export JSTESTS_EXTRA_ARGS=--jitflags=debug +elif [[ "$VARIANT" = "nonunified" ]]; then + RUN_JSTESTS=false + RUN_JITTEST=false + RUN_JSAPITESTS=false elif [[ "$VARIANT" = arm64* ]]; then # The ARM64 simulator is slow, so some tests are timing out. # Run a reduced set of test cases so this doesn't take hours. diff --git a/js/src/devtools/automation/variants/nonunified b/js/src/devtools/automation/variants/nonunified new file mode 100644 index 000000000000..dfc858b7c145 --- /dev/null +++ b/js/src/devtools/automation/variants/nonunified @@ -0,0 +1 @@ +--enable-debug diff --git a/js/src/gc/Allocator.cpp b/js/src/gc/Allocator.cpp index 068340603824..e60a4abfa9f8 100644 --- a/js/src/gc/Allocator.cpp +++ b/js/src/gc/Allocator.cpp @@ -217,23 +217,10 @@ js::Allocate(ExclusiveContext* cx) return GCRuntime::tryNewTenuredThing(cx, kind, thingSize); } -#define FOR_ALL_NON_OBJECT_GC_LAYOUTS(macro) \ - macro(JS::Symbol) \ - macro(JSExternalString) \ - macro(JSFatInlineString) \ - macro(JSScript) \ - macro(JSString) \ - macro(js::AccessorShape) \ - macro(js::BaseShape) \ - macro(js::LazyScript) \ - macro(js::ObjectGroup) \ - macro(js::Shape) \ - macro(js::jit::JitCode) - -#define DECL_ALLOCATOR_INSTANCES(type) \ +#define DECL_ALLOCATOR_INSTANCES(allocKind, traceKind, type, sizedType) \ template type* js::Allocate(ExclusiveContext* cx);\ template type* js::Allocate(ExclusiveContext* cx); -FOR_ALL_NON_OBJECT_GC_LAYOUTS(DECL_ALLOCATOR_INSTANCES) +FOR_EACH_NONOBJECT_ALLOCKIND(DECL_ALLOCATOR_INSTANCES) #undef DECL_ALLOCATOR_INSTANCES template diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index 7d43023002f6..9a3faca2fbda 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -114,39 +114,60 @@ enum class AllocKind { LAST = LIMIT - 1 }; +// Macro to enumerate the different allocation kinds supplying information about +// the trace kind, C++ type and allocation size. +#define FOR_EACH_OBJECT_ALLOCKIND(D) \ + /* AllocKind TraceKind TypeName SizedType */ \ + D(FUNCTION, Object, JSObject, JSFunction) \ + D(FUNCTION_EXTENDED, Object, JSObject, FunctionExtended) \ + D(OBJECT0, Object, JSObject, JSObject_Slots0) \ + D(OBJECT0_BACKGROUND, Object, JSObject, JSObject_Slots0) \ + D(OBJECT2, Object, JSObject, JSObject_Slots2) \ + D(OBJECT2_BACKGROUND, Object, JSObject, JSObject_Slots2) \ + D(OBJECT4, Object, JSObject, JSObject_Slots4) \ + D(OBJECT4_BACKGROUND, Object, JSObject, JSObject_Slots4) \ + D(OBJECT8, Object, JSObject, JSObject_Slots8) \ + D(OBJECT8_BACKGROUND, Object, JSObject, JSObject_Slots8) \ + D(OBJECT12, Object, JSObject, JSObject_Slots12) \ + D(OBJECT12_BACKGROUND, Object, JSObject, JSObject_Slots12) \ + D(OBJECT16, Object, JSObject, JSObject_Slots16) \ + D(OBJECT16_BACKGROUND, Object, JSObject, JSObject_Slots16) + +#define FOR_EACH_NONOBJECT_ALLOCKIND(D) \ + /* AllocKind TraceKind TypeName SizedType */ \ + D(SCRIPT, Script, JSScript, JSScript) \ + D(LAZY_SCRIPT, LazyScript, js::LazyScript, js::LazyScript) \ + D(SHAPE, Shape, js::Shape, js::Shape) \ + D(ACCESSOR_SHAPE, Shape, js::AccessorShape, js::AccessorShape) \ + D(BASE_SHAPE, BaseShape, js::BaseShape, js::BaseShape) \ + D(OBJECT_GROUP, ObjectGroup, js::ObjectGroup, js::ObjectGroup) \ + D(FAT_INLINE_STRING, String, JSFatInlineString, JSFatInlineString) \ + D(STRING, String, JSString, JSString) \ + D(EXTERNAL_STRING, String, JSExternalString, JSExternalString) \ + D(SYMBOL, Symbol, JS::Symbol, JS::Symbol) \ + D(JITCODE, JitCode, js::jit::JitCode, js::jit::JitCode) + #define FOR_EACH_ALLOCKIND(D) \ - /* PrettyName TypeName */ \ - D(FUNCTION, JSFunction) \ - D(FUNCTION_EXTENDED, JSFunction) \ - D(OBJECT0, JSObject) \ - D(OBJECT0_BACKGROUND, JSObject) \ - D(OBJECT2, JSObject) \ - D(OBJECT2_BACKGROUND, JSObject) \ - D(OBJECT4, JSObject) \ - D(OBJECT4_BACKGROUND, JSObject) \ - D(OBJECT8, JSObject) \ - D(OBJECT8_BACKGROUND, JSObject) \ - D(OBJECT12, JSObject) \ - D(OBJECT12_BACKGROUND, JSObject) \ - D(OBJECT16, JSObject) \ - D(OBJECT16_BACKGROUND, JSObject) \ - D(SCRIPT, JSScript) \ - D(LAZY_SCRIPT, js::LazyScript) \ - D(SHAPE, js::Shape) \ - D(ACCESSOR_SHAPE, js::AccessorShape) \ - D(BASE_SHAPE, js::BaseShape) \ - D(OBJECT_GROUP, js::ObjectGroup) \ - D(FAT_INLINE_STRING, JSFatInlineString) \ - D(STRING, JSString) \ - D(EXTERNAL_STRING, JSExternalString) \ - D(SYMBOL, JS::Symbol) \ - D(JITCODE, js::JitCode) + FOR_EACH_OBJECT_ALLOCKIND(D) \ + FOR_EACH_NONOBJECT_ALLOCKIND(D) static_assert(int(AllocKind::FIRST) == 0, "Various places depend on AllocKind starting at 0, " "please audit them carefully!"); static_assert(int(AllocKind::OBJECT_FIRST) == 0, "Various places depend on AllocKind::OBJECT_FIRST " "being 0, please audit them carefully!"); +inline bool +IsAllocKind(AllocKind kind) +{ + return kind >= AllocKind::FIRST && kind <= AllocKind::LIMIT; +} + +inline bool +IsValidAllocKind(AllocKind kind) +{ + return kind >= AllocKind::FIRST && kind <= AllocKind::LAST; +} + inline bool IsObjectAllocKind(AllocKind kind) { @@ -159,17 +180,6 @@ IsShapeAllocKind(AllocKind kind) return kind == AllocKind::SHAPE || kind == AllocKind::ACCESSOR_SHAPE; } -inline bool -IsValidAllocKind(AllocKind kind) -{ - return kind >= AllocKind::FIRST && kind <= AllocKind::LAST; -} - -inline bool IsAllocKind(AllocKind kind) -{ - return kind >= AllocKind::FIRST && kind <= AllocKind::LIMIT; -} - // Returns a sequence for use in a range-based for loop, // to iterate over all alloc kinds. inline decltype(mozilla::MakeEnumeratedRange(AllocKind::FIRST, AllocKind::LIMIT)) @@ -210,31 +220,10 @@ static inline JS::TraceKind MapAllocToTraceKind(AllocKind kind) { static const JS::TraceKind map[] = { - JS::TraceKind::Object, /* AllocKind::FUNCTION */ - JS::TraceKind::Object, /* AllocKind::FUNCTION_EXTENDED */ - JS::TraceKind::Object, /* AllocKind::OBJECT0 */ - JS::TraceKind::Object, /* AllocKind::OBJECT0_BACKGROUND */ - JS::TraceKind::Object, /* AllocKind::OBJECT2 */ - JS::TraceKind::Object, /* AllocKind::OBJECT2_BACKGROUND */ - JS::TraceKind::Object, /* AllocKind::OBJECT4 */ - JS::TraceKind::Object, /* AllocKind::OBJECT4_BACKGROUND */ - JS::TraceKind::Object, /* AllocKind::OBJECT8 */ - JS::TraceKind::Object, /* AllocKind::OBJECT8_BACKGROUND */ - JS::TraceKind::Object, /* AllocKind::OBJECT12 */ - JS::TraceKind::Object, /* AllocKind::OBJECT12_BACKGROUND */ - JS::TraceKind::Object, /* AllocKind::OBJECT16 */ - JS::TraceKind::Object, /* AllocKind::OBJECT16_BACKGROUND */ - JS::TraceKind::Script, /* AllocKind::SCRIPT */ - JS::TraceKind::LazyScript, /* AllocKind::LAZY_SCRIPT */ - JS::TraceKind::Shape, /* AllocKind::SHAPE */ - JS::TraceKind::Shape, /* AllocKind::ACCESSOR_SHAPE */ - JS::TraceKind::BaseShape, /* AllocKind::BASE_SHAPE */ - JS::TraceKind::ObjectGroup, /* AllocKind::OBJECT_GROUP */ - JS::TraceKind::String, /* AllocKind::FAT_INLINE_STRING */ - JS::TraceKind::String, /* AllocKind::STRING */ - JS::TraceKind::String, /* AllocKind::EXTERNAL_STRING */ - JS::TraceKind::Symbol, /* AllocKind::SYMBOL */ - JS::TraceKind::JitCode, /* AllocKind::JITCODE */ +#define EXPAND_ELEMENT(allocKind, traceKind, type, sizedType) \ + JS::TraceKind::traceKind, +FOR_EACH_ALLOCKIND(EXPAND_ELEMENT) +#undef EXPAND_ELEMENT }; static_assert(MOZ_ARRAY_LENGTH(map) == size_t(AllocKind::LIMIT), @@ -326,6 +315,9 @@ class TenuredCell : public Cell static MOZ_ALWAYS_INLINE void writeBarrierPost(void* cellp, TenuredCell* prior, TenuredCell* next); + // Default implementation for kinds that don't require fixup. + void fixupAfterMovingGC() {} + #ifdef DEBUG inline bool isAligned() const; #endif diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 969ba744173e..8b54a41dc281 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -350,6 +350,9 @@ AssertRootMarkingPhase(JSTracer* trc) // statically select the correct Cell layout for marking. Below, we instantiate // each override with a declaration of the most derived layout type. // +// The use of TraceKind::Null for the case where the type is not matched +// generates a compile error as no template instantiated for that kind. +// // Usage: // BaseGCType::type // @@ -357,16 +360,13 @@ AssertRootMarkingPhase(JSTracer* trc) // BaseGCType::type => JSObject // BaseGCType::type => BaseShape // etc. -template ::value ? JS::TraceKind::Object - : IsBaseOf::value ? JS::TraceKind::String - : IsBaseOf::value ? JS::TraceKind::Symbol - : IsBaseOf::value ? JS::TraceKind::Script - : IsBaseOf::value ? JS::TraceKind::Shape - : IsBaseOf::value ? JS::TraceKind::BaseShape - : IsBaseOf::value ? JS::TraceKind::JitCode - : IsBaseOf::value ? JS::TraceKind::LazyScript - : JS::TraceKind::ObjectGroup> +template ::value ? JS::TraceKind::name : +JS_FOR_EACH_TRACEKIND(EXPAND_MATCH_TYPE) +#undef EXPAND_MATCH_TYPE + JS::TraceKind::Null> + struct BaseGCType; #define IMPL_BASE_GC_TYPE(name, type_, _) \ template struct BaseGCType { typedef type_ type; }; diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index bab858ad02a0..aec94d86395f 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -65,25 +65,31 @@ MarkExactStackRootList(JSTracer* trc, JS::Rooted* rooter, const char* nam } } +static inline void +TraceStackRoots(JSTracer* trc, RootedListHeads& stackRoots) +{ +#define MARK_ROOTS(name, type, _) \ + MarkExactStackRootList(trc, stackRoots[JS::RootKind::name], "exact-" #name); +JS_FOR_EACH_TRACEKIND(MARK_ROOTS) +#undef MARK_ROOTS + MarkExactStackRootList(trc, stackRoots[JS::RootKind::Id], "exact-id"); + MarkExactStackRootList(trc, stackRoots[JS::RootKind::Value], "exact-value"); + MarkExactStackRootList::TraceWrapped>( + trc, stackRoots[JS::RootKind::Traceable], "Traceable"); +} + void js::RootLists::traceStackRoots(JSTracer* trc) { -#define MARK_ROOTS(name, type, _) \ - MarkExactStackRootList(trc, stackRoots_[JS::RootKind::name], "exact-" #name); -JS_FOR_EACH_TRACEKIND(MARK_ROOTS) -#undef MARK_ROOTS - MarkExactStackRootList(trc, stackRoots_[JS::RootKind::Id], "exact-id"); - MarkExactStackRootList(trc, stackRoots_[JS::RootKind::Value], "exact-value"); - MarkExactStackRootList::TraceWrapped>( - trc, stackRoots_[JS::RootKind::Traceable], "Traceable"); + TraceStackRoots(trc, stackRoots_); } static void MarkExactStackRoots(JSRuntime* rt, JSTracer* trc) { - for (ContextIter cx(rt); !cx.done(); cx.next()) - cx->roots.traceStackRoots(trc); + for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) + TraceStackRoots(trc, zone->stackRoots_); rt->mainThread.roots.traceStackRoots(trc); } @@ -113,8 +119,6 @@ JS_FOR_EACH_TRACEKIND(MARK_ROOTS) static void MarkPersistentRooted(JSRuntime* rt, JSTracer* trc) { - for (ContextIter cx(rt); !cx.done(); cx.next()) - cx->roots.tracePersistentRoots(trc); rt->mainThread.roots.tracePersistentRoots(trc); } diff --git a/js/src/jit-test/tests/auto-regress/bug1269074.js b/js/src/jit-test/tests/auto-regress/bug1269074.js new file mode 100644 index 000000000000..40c67c6e5669 --- /dev/null +++ b/js/src/jit-test/tests/auto-regress/bug1269074.js @@ -0,0 +1,6 @@ +// |jit-test| allow-oom + +if (!('oomTest' in this)) + quit(); + +evalcx('oomTest(function() { Array(...""); })', newGlobal()); diff --git a/js/src/jit-test/tests/wasm/basic-memory.js b/js/src/jit-test/tests/wasm/basic-memory.js index cbf083f7f8de..ac1536a61ca7 100644 --- a/js/src/jit-test/tests/wasm/basic-memory.js +++ b/js/src/jit-test/tests/wasm/basic-memory.js @@ -163,3 +163,6 @@ assertErrorMessage(() => wasmEvalText('(module (memory 1) (func (f32.store offse assertErrorMessage(() => wasmEvalText('(module (memory 1) (func (i32.store offset=0 (i32.const 0) (f32.const 0))))'), TypeError, mismatchError("f32", "i32")); assertErrorMessage(() => wasmEvalText('(module (memory 1) (func (i32.store offset=0 (i32.const 0) (f64.const 0))))'), TypeError, mismatchError("f64", "i32")); + +wasmEvalText('(module (memory 0 65535))') +assertErrorMessage(() => wasmEvalText('(module (memory 0 65536))'), TypeError, /maximum memory size too big/); diff --git a/js/src/jit-test/tests/wasm/basic.js b/js/src/jit-test/tests/wasm/basic.js index 4b4fd03c233f..1c3ea8302eb1 100644 --- a/js/src/jit-test/tests/wasm/basic.js +++ b/js/src/jit-test/tests/wasm/basic.js @@ -147,11 +147,10 @@ wasmEvalText('(module (import $foo "a" "" (result f64)))', {a: ()=> {}}); wasmEvalText('(module (memory 0))'); wasmEvalText('(module (memory 1))'); assertErrorMessage(() => wasmEvalText('(module (memory 65536))'), TypeError, /initial memory size too big/); -assertErrorMessage(() => wasmEvalText('(module (memory 32768))'), TypeError, /initial memory size too big/); // May OOM, but must not crash: try { - wasmEvalText('(module (memory 32767))'); + wasmEvalText('(module (memory 65535))'); } catch (e) { print(e); assertEq(String(e).indexOf("out of memory") != -1, true); diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index 51b82a60106f..c8b1e9c62bfa 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -114,7 +114,6 @@ class JitCode : public gc::TenuredCell void traceChildren(JSTracer* trc); void finalize(FreeOp* fop); - void fixupAfterMovingGC() {} void setInvalidated() { invalidated_ = true; } diff --git a/js/src/js.msg b/js/src/js.msg index c0dc5de15e91..42e1ef6c9613 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -493,6 +493,7 @@ MSG_DEF(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected ArrayBuff MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_RANGEERR, "argument {0} must be >= 0") MSG_DEF(JSMSG_TYPED_ARRAY_DETACHED, 0, JSEXN_TYPEERR, "attempting to access detached ArrayBuffer") +MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS, 0, JSEXN_RANGEERR, "attempting to construct out-of-bounds TypedArray on ArrayBuffer") // Shared array buffer MSG_DEF(JSMSG_SHARED_ARRAY_BAD_LENGTH, 0, JSEXN_RANGEERR, "length argument out of range") diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 3a45d96ed77b..8d49930d09d4 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -6447,19 +6447,67 @@ DescribeScriptedCaller(JSContext* cx, AutoFilename* filename, unsigned* lineno, return true; } +// Fast path to get the activation to use for GetScriptedCallerGlobal. If this +// returns false, the fast path didn't work out and the caller has to use the +// (much slower) NonBuiltinFrameIter path. +// +// The optimization here is that we skip Ion-inlined frames and only look at +// 'outer' frames. That's fine: each activation is tied to a single compartment, +// so if an activation contains at least one non-self-hosted frame, we can use +// the activation's global for GetScriptedCallerGlobal. If, however, all 'outer' +// frames are self-hosted, it's possible Ion inlined a non-self-hosted script, +// so we must return false and use the slower path. +static bool +GetScriptedCallerActivationFast(JSContext* cx, Activation** activation) +{ + ActivationIterator activationIter(cx->runtime()); + + while (!activationIter.done() && activationIter->cx() != cx) + ++activationIter; + + if (activationIter.done()) { + *activation = nullptr; + return true; + } + + *activation = activationIter.activation(); + + if (activationIter->isJit()) { + for (jit::JitFrameIterator iter(activationIter); !iter.done(); ++iter) { + if (iter.isScripted() && !iter.script()->selfHosted()) + return true; + } + } else if (activationIter->isInterpreter()) { + for (InterpreterFrameIterator iter((*activation)->asInterpreter()); !iter.done(); ++iter) { + if (!iter.frame()->script()->selfHosted()) + return true; + } + } + + return false; +} + JS_PUBLIC_API(JSObject*) GetScriptedCallerGlobal(JSContext* cx) { - NonBuiltinFrameIter i(cx); - if (i.done()) - return nullptr; + Activation* activation; + + if (GetScriptedCallerActivationFast(cx, &activation)) { + if (!activation) + return nullptr; + } else { + NonBuiltinFrameIter i(cx); + if (i.done()) + return nullptr; + activation = i.activation(); + } // If the caller is hidden, the embedding wants us to return null here so // that it can check its own stack (see HideScriptedCaller). - if (i.activation()->scriptedCallerIsHidden()) + if (activation->scriptedCallerIsHidden()) return nullptr; - GlobalObject* global = i.activation()->compartment()->maybeGlobal(); + GlobalObject* global = activation->compartment()->maybeGlobal(); // Noone should be running code in the atoms compartment or running code in // a compartment without any live objects, so there should definitely be a diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 23e9026c4e47..a33bff7f9b34 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -261,52 +261,22 @@ const AllocKind gc::slotsToThingKind[] = { static_assert(JS_ARRAY_LENGTH(slotsToThingKind) == SLOTS_TO_THING_KIND_LIMIT, "We have defined a slot count for each kind."); -// Assert that SortedArenaList::MinThingSize and sizeof(FreeSpan) are <= the -// real minimum thing size. Also assert each size is a multiple of CellSize. -#define CHECK_THING_SIZE_INNER(x_) \ - static_assert(x_ >= SortedArenaList::MinThingSize, \ - #x_ " is less than SortedArenaList::MinThingSize!"); \ - static_assert(x_ >= sizeof(FreeSpan), \ - #x_ " is less than sizeof(FreeSpan)"); \ - static_assert(x_ % CellSize == 0, \ - #x_ " not a multiple of CellSize"); +#define CHECK_THING_SIZE(allocKind, traceKind, type, sizedType) \ + static_assert(sizeof(sizedType) >= SortedArenaList::MinThingSize, \ + #sizedType " is smaller than SortedArenaList::MinThingSize!"); \ + static_assert(sizeof(sizedType) >= sizeof(FreeSpan), \ + #sizedType " is smaller than FreeSpan"); \ + static_assert(sizeof(sizedType) % CellSize == 0, \ + "Size of " #sizedType " is not a multiple of CellSize"); +FOR_EACH_ALLOCKIND(CHECK_THING_SIZE); +#undef CHECK_THING_SIZE -#define CHECK_THING_SIZE(...) { __VA_ARGS__ }; /* Define the array. */ \ - MOZ_FOR_EACH(CHECK_THING_SIZE_INNER, (), (__VA_ARGS__ 0x20)) - -#define CHECK_ZEAL(name, value) \ - static_assert(ZealMode::Limit >= ZealMode::name, \ - "ZealMode::Limit shouldn't be smaller than " #name); -JS_FOR_EACH_ZEAL_MODE(CHECK_ZEAL) -#undef CHECK_ZEAL - -const uint32_t Arena::ThingSizes[] = CHECK_THING_SIZE( - sizeof(JSFunction), /* AllocKind::FUNCTION */ - sizeof(FunctionExtended), /* AllocKind::FUNCTION_EXTENDED */ - sizeof(JSObject_Slots0), /* AllocKind::OBJECT0 */ - sizeof(JSObject_Slots0), /* AllocKind::OBJECT0_BACKGROUND */ - sizeof(JSObject_Slots2), /* AllocKind::OBJECT2 */ - sizeof(JSObject_Slots2), /* AllocKind::OBJECT2_BACKGROUND */ - sizeof(JSObject_Slots4), /* AllocKind::OBJECT4 */ - sizeof(JSObject_Slots4), /* AllocKind::OBJECT4_BACKGROUND */ - sizeof(JSObject_Slots8), /* AllocKind::OBJECT8 */ - sizeof(JSObject_Slots8), /* AllocKind::OBJECT8_BACKGROUND */ - sizeof(JSObject_Slots12), /* AllocKind::OBJECT12 */ - sizeof(JSObject_Slots12), /* AllocKind::OBJECT12_BACKGROUND */ - sizeof(JSObject_Slots16), /* AllocKind::OBJECT16 */ - sizeof(JSObject_Slots16), /* AllocKind::OBJECT16_BACKGROUND */ - sizeof(JSScript), /* AllocKind::SCRIPT */ - sizeof(LazyScript), /* AllocKind::LAZY_SCRIPT */ - sizeof(Shape), /* AllocKind::SHAPE */ - sizeof(AccessorShape), /* AllocKind::ACCESSOR_SHAPE */ - sizeof(BaseShape), /* AllocKind::BASE_SHAPE */ - sizeof(ObjectGroup), /* AllocKind::OBJECT_GROUP */ - sizeof(JSFatInlineString), /* AllocKind::FAT_INLINE_STRING */ - sizeof(JSString), /* AllocKind::STRING */ - sizeof(JSExternalString), /* AllocKind::EXTERNAL_STRING */ - sizeof(JS::Symbol), /* AllocKind::SYMBOL */ - sizeof(jit::JitCode), /* AllocKind::JITCODE */ -); +const uint32_t Arena::ThingSizes[] = { +#define EXPAND_THING_SIZE(allocKind, traceKind, type, sizedType) \ + sizeof(sizedType), +FOR_EACH_ALLOCKIND(EXPAND_THING_SIZE) +#undef EXPAND_THING_SIZE + }; FreeSpan ArenaLists::placeholder; @@ -316,31 +286,10 @@ FreeSpan ArenaLists::placeholder; #define OFFSET(type) uint32_t(ArenaHeaderSize + (ArenaSize - ArenaHeaderSize) % sizeof(type)) const uint32_t Arena::FirstThingOffsets[] = { - OFFSET(JSFunction), /* AllocKind::FUNCTION */ - OFFSET(FunctionExtended), /* AllocKind::FUNCTION_EXTENDED */ - OFFSET(JSObject_Slots0), /* AllocKind::OBJECT0 */ - OFFSET(JSObject_Slots0), /* AllocKind::OBJECT0_BACKGROUND */ - OFFSET(JSObject_Slots2), /* AllocKind::OBJECT2 */ - OFFSET(JSObject_Slots2), /* AllocKind::OBJECT2_BACKGROUND */ - OFFSET(JSObject_Slots4), /* AllocKind::OBJECT4 */ - OFFSET(JSObject_Slots4), /* AllocKind::OBJECT4_BACKGROUND */ - OFFSET(JSObject_Slots8), /* AllocKind::OBJECT8 */ - OFFSET(JSObject_Slots8), /* AllocKind::OBJECT8_BACKGROUND */ - OFFSET(JSObject_Slots12), /* AllocKind::OBJECT12 */ - OFFSET(JSObject_Slots12), /* AllocKind::OBJECT12_BACKGROUND */ - OFFSET(JSObject_Slots16), /* AllocKind::OBJECT16 */ - OFFSET(JSObject_Slots16), /* AllocKind::OBJECT16_BACKGROUND */ - OFFSET(JSScript), /* AllocKind::SCRIPT */ - OFFSET(LazyScript), /* AllocKind::LAZY_SCRIPT */ - OFFSET(Shape), /* AllocKind::SHAPE */ - OFFSET(AccessorShape), /* AllocKind::ACCESSOR_SHAPE */ - OFFSET(BaseShape), /* AllocKind::BASE_SHAPE */ - OFFSET(ObjectGroup), /* AllocKind::OBJECT_GROUP */ - OFFSET(JSFatInlineString), /* AllocKind::FAT_INLINE_STRING */ - OFFSET(JSString), /* AllocKind::STRING */ - OFFSET(JSExternalString), /* AllocKind::EXTERNAL_STRING */ - OFFSET(JS::Symbol), /* AllocKind::SYMBOL */ - OFFSET(jit::JitCode), /* AllocKind::JITCODE */ +#define EXPAND_FIRST_THING_OFFSET(allocKind, traceKind, type, sizedType) \ + OFFSET(sizedType), +FOR_EACH_ALLOCKIND(EXPAND_FIRST_THING_OFFSET) +#undef EXPAND_FIRST_THING_OFFSET }; #undef OFFSET @@ -348,31 +297,10 @@ const uint32_t Arena::FirstThingOffsets[] = { #define COUNT(type) uint32_t((ArenaSize - ArenaHeaderSize) / sizeof(type)) const uint32_t Arena::ThingsPerArena[] = { - COUNT(JSFunction), /* AllocKind::FUNCTION */ - COUNT(FunctionExtended), /* AllocKind::FUNCTION_EXTENDED */ - COUNT(JSObject_Slots0), /* AllocKind::OBJECT0 */ - COUNT(JSObject_Slots0), /* AllocKind::OBJECT0_BACKGROUND */ - COUNT(JSObject_Slots2), /* AllocKind::OBJECT2 */ - COUNT(JSObject_Slots2), /* AllocKind::OBJECT2_BACKGROUND */ - COUNT(JSObject_Slots4), /* AllocKind::OBJECT4 */ - COUNT(JSObject_Slots4), /* AllocKind::OBJECT4_BACKGROUND */ - COUNT(JSObject_Slots8), /* AllocKind::OBJECT8 */ - COUNT(JSObject_Slots8), /* AllocKind::OBJECT8_BACKGROUND */ - COUNT(JSObject_Slots12), /* AllocKind::OBJECT12 */ - COUNT(JSObject_Slots12), /* AllocKind::OBJECT12_BACKGROUND */ - COUNT(JSObject_Slots16), /* AllocKind::OBJECT16 */ - COUNT(JSObject_Slots16), /* AllocKind::OBJECT16_BACKGROUND */ - COUNT(JSScript), /* AllocKind::SCRIPT */ - COUNT(LazyScript), /* AllocKind::LAZY_SCRIPT */ - COUNT(Shape), /* AllocKind::SHAPE */ - COUNT(AccessorShape), /* AllocKind::ACCESSOR_SHAPE */ - COUNT(BaseShape), /* AllocKind::BASE_SHAPE */ - COUNT(ObjectGroup), /* AllocKind::OBJECT_GROUP */ - COUNT(JSFatInlineString), /* AllocKind::FAT_INLINE_STRING */ - COUNT(JSString), /* AllocKind::STRING */ - COUNT(JSExternalString), /* AllocKind::EXTERNAL_STRING */ - COUNT(JS::Symbol), /* AllocKind::SYMBOL */ - COUNT(jit::JitCode), /* AllocKind::JITCODE */ +#define EXPAND_THINGS_PER_ARENA(allocKind, traceKind, type, sizedType) \ + COUNT(sizedType), +FOR_EACH_ALLOCKIND(EXPAND_THINGS_PER_ARENA) +#undef EXPAND_THINGS_PER_ARENA }; #undef COUNT @@ -604,43 +532,12 @@ FinalizeArenas(FreeOp* fop, ArenaLists::KeepArenasEnum keepArenas) { switch (thingKind) { - case AllocKind::FUNCTION: - case AllocKind::FUNCTION_EXTENDED: - case AllocKind::OBJECT0: - case AllocKind::OBJECT0_BACKGROUND: - case AllocKind::OBJECT2: - case AllocKind::OBJECT2_BACKGROUND: - case AllocKind::OBJECT4: - case AllocKind::OBJECT4_BACKGROUND: - case AllocKind::OBJECT8: - case AllocKind::OBJECT8_BACKGROUND: - case AllocKind::OBJECT12: - case AllocKind::OBJECT12_BACKGROUND: - case AllocKind::OBJECT16: - case AllocKind::OBJECT16_BACKGROUND: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::SCRIPT: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::LAZY_SCRIPT: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::SHAPE: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::ACCESSOR_SHAPE: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::BASE_SHAPE: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::OBJECT_GROUP: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::STRING: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::FAT_INLINE_STRING: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::EXTERNAL_STRING: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::SYMBOL: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::JITCODE: - return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); +#define EXPAND_CASE(allocKind, traceKind, type, sizedType) \ + case AllocKind::allocKind: \ + return FinalizeTypedArenas(fop, src, dest, thingKind, budget, keepArenas); +FOR_EACH_ALLOCKIND(EXPAND_CASE) +#undef EXPAND_CASE + default: MOZ_CRASH("Invalid alloc kind"); } @@ -2543,49 +2440,15 @@ static void UpdateArenaPointers(MovingTracer* trc, Arena* arena) { AllocKind kind = arena->getAllocKind(); - JS::TraceKind traceKind = MapAllocToTraceKind(kind); switch (kind) { - case AllocKind::FUNCTION: - case AllocKind::FUNCTION_EXTENDED: - case AllocKind::OBJECT0: - case AllocKind::OBJECT0_BACKGROUND: - case AllocKind::OBJECT2: - case AllocKind::OBJECT2_BACKGROUND: - case AllocKind::OBJECT4: - case AllocKind::OBJECT4_BACKGROUND: - case AllocKind::OBJECT8: - case AllocKind::OBJECT8_BACKGROUND: - case AllocKind::OBJECT12: - case AllocKind::OBJECT12_BACKGROUND: - case AllocKind::OBJECT16: - case AllocKind::OBJECT16_BACKGROUND: - UpdateArenaPointersTyped(trc, arena, traceKind); - return; - case AllocKind::SCRIPT: - UpdateArenaPointersTyped(trc, arena, traceKind); - return; - case AllocKind::LAZY_SCRIPT: - UpdateArenaPointersTyped(trc, arena, traceKind); - return; - case AllocKind::SHAPE: - UpdateArenaPointersTyped(trc, arena, traceKind); - return; - case AllocKind::ACCESSOR_SHAPE: - UpdateArenaPointersTyped(trc, arena, traceKind); - return; - case AllocKind::BASE_SHAPE: - UpdateArenaPointersTyped(trc, arena, traceKind); - return; - case AllocKind::OBJECT_GROUP: - UpdateArenaPointersTyped(trc, arena, traceKind); - return; - case AllocKind::STRING: - UpdateArenaPointersTyped(trc, arena, traceKind); - return; - case AllocKind::JITCODE: - UpdateArenaPointersTyped(trc, arena, traceKind); +#define EXPAND_CASE(allocKind, traceKind, type, sizedType) \ + case AllocKind::allocKind: \ + UpdateArenaPointersTyped(trc, arena, JS::TraceKind::traceKind); \ return; +FOR_EACH_ALLOCKIND(EXPAND_CASE) +#undef EXPAND_CASE + default: MOZ_CRASH("Invalid alloc kind for UpdateArenaPointers"); } @@ -3961,11 +3824,13 @@ static const char* AllocKindToAscii(AllocKind kind) { switch(kind) { -#define MAKE_CASE(name, _) case AllocKind:: name: return #name; - FOR_EACH_ALLOCKIND(MAKE_CASE) +#define MAKE_CASE(allocKind, traceKind, type, sizedType) \ + case AllocKind:: allocKind: return #allocKind; +FOR_EACH_ALLOCKIND(MAKE_CASE) #undef MAKE_CASE - case AllocKind::LIMIT: MOZ_FALLTHROUGH; - default: MOZ_CRASH("Unknown AllocKind in AllocKindToAscii"); + + default: + MOZ_CRASH("Unknown AllocKind in AllocKindToAscii"); } } #endif // DEBUG diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 3726d6262a91..21e604863b02 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -53,19 +53,19 @@ enum State { NUM_STATES }; -/* Map from C++ type to alloc kind. JSObject does not have a 1:1 mapping, so must use Arena::thingSize. */ +/* + * Map from C++ type to alloc kind for non-object types. JSObject does not have + * a 1:1 mapping, so must use Arena::thingSize. + * + * The AllocKind is available as MapTypeToFinalizeKind::kind. + */ template struct MapTypeToFinalizeKind {}; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::SCRIPT; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::LAZY_SCRIPT; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::SHAPE; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::ACCESSOR_SHAPE; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::BASE_SHAPE; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::OBJECT_GROUP; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::FAT_INLINE_STRING; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::STRING; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::EXTERNAL_STRING; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::SYMBOL; }; -template <> struct MapTypeToFinalizeKind { static const AllocKind kind = AllocKind::JITCODE; }; +#define EXPAND_MAPTYPETOFINALIZEKIND(allocKind, traceKind, type, sizedType) \ + template <> struct MapTypeToFinalizeKind { \ + static const AllocKind kind = AllocKind::allocKind; \ + }; +FOR_EACH_NONOBJECT_ALLOCKIND(EXPAND_MAPTYPETOFINALIZEKIND) +#undef EXPAND_MAPTYPETOFINALIZEKIND template struct ParticipatesInCC {}; #define EXPAND_PARTICIPATES_IN_CC(_, type, addToCCKind) \ diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index b7ded95473b2..ebd7df5b7be5 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -265,12 +265,15 @@ enum StackKind StackKindCount }; +using RootedListHeads = mozilla::EnumeratedArray*>; + // Abstracts JS rooting mechanisms so they can be shared between the JSContext // and JSRuntime. class RootLists { // Stack GC roots for Rooted GC heap pointers. - mozilla::EnumeratedArray*> stackRoots_; + RootedListHeads stackRoots_; template friend class JS::Rooted; // Stack GC roots for AutoFooRooter classes. diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 56551c139958..c2fb4ecc6b84 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -1942,7 +1942,6 @@ class JSScript : public js::gc::TenuredCell #endif void finalize(js::FreeOp* fop); - void fixupAfterMovingGC() {} static const JS::TraceKind TraceKind = JS::TraceKind::Script; @@ -2397,7 +2396,6 @@ class LazyScript : public gc::TenuredCell friend class GCMarker; void traceChildren(JSTracer* trc); void finalize(js::FreeOp* fop); - void fixupAfterMovingGC() {} static const JS::TraceKind TraceKind = JS::TraceKind::LazyScript; diff --git a/js/src/old-configure.in b/js/src/old-configure.in index 50eb7d23dd04..cd4380edf87b 100644 --- a/js/src/old-configure.in +++ b/js/src/old-configure.in @@ -982,10 +982,16 @@ case "$target" in _DEFINES_CXXFLAGS='-FI $(topobjdir)/js/src/js-confdefs.h -DMOZILLA_CLIENT' CFLAGS="$CFLAGS -W3 -Gy" CXXFLAGS="$CXXFLAGS -W3 -Gy" - if test "$CPU_ARCH" = "x86"; then - dnl VS2012+ defaults to -arch:SSE2. - CFLAGS="$CFLAGS -arch:IA32" - CXXFLAGS="$CXXFLAGS -arch:IA32" + if test "$CPU_ARCH" = "x86";then + dnl VS2012+ defaults to -arch:SSE2. We want to target nothing + dnl more recent, so set that explicitly here unless another + dnl target arch has already been set. + if test -z `echo $CFLAGS | grep -i [-/]arch:` ; then + CFLAGS="$CFLAGS -arch:SSE2" + fi + if test -z `echo $CXXFLAGS | grep -i [-/]arch:` ; then + CXXFLAGS="$CXXFLAGS -arch:SSE2" + fi fi dnl VS2013+ requires -FS when parallel building by make -jN. dnl If nothing, compiler sometimes causes C1041 error. diff --git a/js/src/tests/ecma_6/TypedArray/constructor_bad-args.js b/js/src/tests/ecma_6/TypedArray/constructor_bad-args.js new file mode 100644 index 000000000000..00bbf884c603 --- /dev/null +++ b/js/src/tests/ecma_6/TypedArray/constructor_bad-args.js @@ -0,0 +1,13 @@ +// Bug 1227207 + +var AB = new ArrayBuffer(12); // Length divides 4 +var BC = new ArrayBuffer(14); // Length does not divide 4 + +assertThrowsInstanceOf(() => new Int32Array(AB, -1), RangeError); // 22.2.4.5 #8 +assertThrowsInstanceOf(() => new Int32Array(AB, 2), RangeError); // 22.2.4.5 #10 +assertThrowsInstanceOf(() => new Int32Array(BC), RangeError); // 22.2.4.5 #13.a +assertThrowsInstanceOf(() => new Int32Array(AB, 16), RangeError); // 22.2.4.5 #13.c +assertThrowsInstanceOf(() => new Int32Array(AB, 0, 4), RangeError); // 22.2.4.5 #14.c + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/extensions/sharedtypedarray.js b/js/src/tests/js1_8_5/extensions/sharedtypedarray.js index 261499e5df4e..7cc72b0434c9 100644 --- a/js/src/tests/js1_8_5/extensions/sharedtypedarray.js +++ b/js/src/tests/js1_8_5/extensions/sharedtypedarray.js @@ -82,13 +82,13 @@ function testSharedTypedArray() { assertThrowsInstanceOf(() => new Int8Array(b, -7), RangeError); // not congruent mod element size - assertThrowsInstanceOf(() => new Int32Array(b, 3), TypeError); // Bug 1227207: should be RangeError + assertThrowsInstanceOf(() => new Int32Array(b, 3), RangeError); // start out of range - assertThrowsInstanceOf(() => new Int32Array(b, 4104), TypeError); // Ditto + assertThrowsInstanceOf(() => new Int32Array(b, 4104), RangeError); // end out of range - assertThrowsInstanceOf(() => new Int32Array(b, 4092, 2), TypeError); // Ditto + assertThrowsInstanceOf(() => new Int32Array(b, 4092, 2), RangeError); // Views alias the storage x2[0] = -1; diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 6ebff11ed4a7..a06dfa1f3b26 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -7715,12 +7715,11 @@ DebuggerObject_checkThis(JSContext* cx, const CallArgs& args, const char* fnname return nthisobj; } -#define THIS_DEBUGOBJECT(cx, argc, vp, fnname, args, obj, object) \ - CallArgs args = CallArgsFromVp(argc, vp); \ - RootedObject obj(cx, DebuggerObject_checkThis(cx, args, fnname)); \ - if (!obj) \ - return false; \ - DebuggerObject& object = obj->as(); \ +#define THIS_DEBUGOBJECT(cx, argc, vp, fnname, object) \ + CallArgs args = CallArgsFromVp(argc, vp); \ + Rooted object(cx, DebuggerObject_checkThis(cx, args, fnname)); \ + if (!object) \ + return false; \ #define THIS_DEBUGOBJECT_REFERENT(cx, argc, vp, fnname, args, obj) \ CallArgs args = CallArgsFromVp(argc, vp); \ @@ -8505,13 +8504,27 @@ DebuggerObject_preventExtensions(JSContext* cx, unsigned argc, Value* vp) } static bool -DebuggerObject_isSealed(JSContext* cx, unsigned argc, Value* vp) +DebuggerObject_isExtensible(JSContext* cx, unsigned argc, Value* vp) { - THIS_DEBUGOBJECT(cx, argc, vp, "isSealed", args, obj, object); + THIS_DEBUGOBJECT(cx, argc, vp, "isExtensible", object) bool result; - if (!object.isSealed(cx, &result)) - return false; + if (!DebuggerObject::isExtensible(cx, object, result)) + return false; + + args.rval().setBoolean(result); + return true; +} + +static bool +DebuggerObject_isSealed(JSContext* cx, unsigned argc, Value* vp) +{ + THIS_DEBUGOBJECT(cx, argc, vp, "isSealed", object) + + bool result; + if (!DebuggerObject::isSealed(cx, object, result)) + return false; + args.rval().setBoolean(result); return true; } @@ -8519,23 +8532,12 @@ DebuggerObject_isSealed(JSContext* cx, unsigned argc, Value* vp) static bool DebuggerObject_isFrozen(JSContext* cx, unsigned argc, Value* vp) { - THIS_DEBUGOBJECT(cx, argc, vp, "isFrozen", args, obj, object); + THIS_DEBUGOBJECT(cx, argc, vp, "isFrozen", object) bool result; - if (!object.isFrozen(cx, &result)) - return false; - args.rval().setBoolean(result); - return true; -} + if (!DebuggerObject::isFrozen(cx, object, result)) + return false; -static bool -DebuggerObject_isExtensible(JSContext* cx, unsigned argc, Value* vp) -{ - THIS_DEBUGOBJECT(cx, argc, vp, "isExtensible", args, obj, object); - - bool result; - if (!object.isExtensible(cx, &result)) - return false; args.rval().setBoolean(result); return true; } @@ -8885,10 +8887,10 @@ const JSFunctionSpec DebuggerObject::methods_[] = { JS_FN("seal", DebuggerObject_seal, 0, 0), JS_FN("freeze", DebuggerObject_freeze, 0, 0), JS_FN("preventExtensions", DebuggerObject_preventExtensions, 0, 0), - JS_FN("isSealed", DebuggerObject_isSealed, 0, 0), JS_FN("forceLexicalInitializationByName", DebuggerObject_forceLexicalInitializationByName, 1, 0), - JS_FN("isFrozen", DebuggerObject_isFrozen, 0, 0), JS_FN("isExtensible", DebuggerObject_isExtensible, 0, 0), + JS_FN("isSealed", DebuggerObject_isSealed, 0, 0), + JS_FN("isFrozen", DebuggerObject_isFrozen, 0, 0), JS_FN("apply", DebuggerObject_apply, 0, 0), JS_FN("call", DebuggerObject_call, 0, 0), JS_FN("makeDebuggeeValue", DebuggerObject_makeDebuggeeValue, 1, 0), @@ -8933,34 +8935,37 @@ DebuggerObject::create(JSContext* cx, HandleObject proto, HandleObject referent, return &object; } -bool -DebuggerObject::isExtensible(JSContext* cx, bool* result) const +/* static */ bool +DebuggerObject::isExtensible(JSContext* cx, Handle object, bool& result) { - RootedObject obj(cx, referent()); - - Maybe ac; - ac.emplace(cx, obj); - ErrorCopier ec(ac); - return IsExtensible(cx, obj, result); -} - -bool -DebuggerObject::isSealedHelper(JSContext* cx, SealHelperOp op, const char* name, - bool* result) const -{ - RootedObject obj(cx, referent()); + RootedObject referent(cx, object->referent()); Maybe ac; - ac.emplace(cx, obj); + ac.emplace(cx, referent); ErrorCopier ec(ac); - if (op == OpSeal) { - if (!TestIntegrityLevel(cx, obj, IntegrityLevel::Sealed, result)) - return false; - } else { - if (!TestIntegrityLevel(cx, obj, IntegrityLevel::Frozen, result)) - return false; - } - return true; + return IsExtensible(cx, referent, &result); +} + +/* static */ bool +DebuggerObject::isSealed(JSContext* cx, Handle object, bool& result) +{ + RootedObject referent(cx, object->referent()); + + Maybe ac; + ac.emplace(cx, referent); + ErrorCopier ec(ac); + return TestIntegrityLevel(cx, referent, IntegrityLevel::Sealed, &result); +} + +/* static */ bool +DebuggerObject::isFrozen(JSContext* cx, Handle object, bool& result) +{ + RootedObject referent(cx, object->referent()); + + Maybe ac; + ac.emplace(cx, referent); + ErrorCopier ec(ac); + return TestIntegrityLevel(cx, referent, IntegrityLevel::Frozen, &result); } diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index 9535c5e5a07a..d4eede129194 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -1033,20 +1033,13 @@ class DebuggerObject : public NativeObject public: static const Class class_; - static NativeObject* initClass(JSContext* cx, HandleObject obj, HandleObject debuggerCtor); - + static NativeObject* initClass(JSContext* cx, HandleObject obj, HandleObject debugCtor); static DebuggerObject* create(JSContext* cx, HandleObject proto, HandleObject obj, HandleNativeObject debugger); - bool isExtensible(JSContext* cx, bool* result) const; - - bool isSealed(JSContext* cx, bool* result) const { - return isSealedHelper(cx, OpSeal, "isSealed", result); - } - - bool isFrozen(JSContext* cx, bool* result) const { - return isSealedHelper(cx, OpFreeze, "isFrozen", result); - } + static bool isExtensible(JSContext* cx, Handle object, bool& result); + static bool isSealed(JSContext* cx, Handle object, bool& result); + static bool isFrozen(JSContext* cx, Handle object, bool& result); private: static const unsigned RESERVED_SLOTS = 1; @@ -1062,10 +1055,6 @@ class DebuggerObject : public NativeObject MOZ_ASSERT(obj); return obj; } - - enum SealHelperOp { OpSeal, OpFreeze }; - - bool isSealedHelper(JSContext* cx, SealHelperOp op, const char* name, bool* result) const; }; class BreakpointSite { diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 61367ed35f39..c6a37c9b9b23 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -176,6 +176,8 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle global, JS // Ok, we're doing it with a class spec. // + bool isObjectOrFunction = key == JSProto_Function || key == JSProto_Object; + // We need to create the prototype first, and immediately stash it in the // slot. This is so the following bootstrap ordering is possible: // * Object.prototype @@ -185,9 +187,9 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle global, JS // // We get the above when Object is resolved before Function. If Function // is resolved before Object, we'll end up re-entering resolveConstructor - // for Function, which is a problem. So if Function is being resolved before - // Object.prototype exists, we just resolve Object instead, since we know that - // Function will also be resolved before we return. + // for Function, which is a problem. So if Function is being resolved + // before Object.prototype exists, we just resolve Object instead, since we + // know that Function will also be resolved before we return. if (key == JSProto_Function && global->getPrototype(JSProto_Object).isUndefined()) return resolveConstructor(cx, global, JSProto_Object); @@ -200,14 +202,16 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle global, JS if (!proto) return false; - // Make sure that creating the prototype didn't recursively resolve our - // own constructor. We can't just assert that there's no prototype; OOMs - // can result in incomplete resolutions in which the prototype is saved - // but not the constructor. So use the same criteria that protects entry - // into this function. - MOZ_ASSERT(!global->isStandardClassResolved(key)); + if (isObjectOrFunction) { + // Make sure that creating the prototype didn't recursively resolve + // our own constructor. We can't just assert that there's no + // prototype; OOMs can result in incomplete resolutions in which + // the prototype is saved but not the constructor. So use the same + // criteria that protects entry into this function. + MOZ_ASSERT(!global->isStandardClassResolved(key)); - global->setPrototype(key, ObjectValue(*proto)); + global->setPrototype(key, ObjectValue(*proto)); + } } // Create the constructor. @@ -216,37 +220,16 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle global, JS return false; RootedId id(cx, NameToId(ClassName(key, cx))); - if (clasp->specShouldDefineConstructor()) { - if (!global->addDataProperty(cx, id, constructorPropertySlot(key), 0)) - return false; + if (isObjectOrFunction) { + if (clasp->specShouldDefineConstructor()) { + if (!global->addDataProperty(cx, id, constructorPropertySlot(key), 0)) + return false; + } + + global->setConstructor(key, ObjectValue(*ctor)); + global->setConstructorPropertySlot(key, ObjectValue(*ctor)); } - // Set the constructor slot here to make it usable from JS_DefineFunctions, - // especially with JSProto_Function, as Function.prototype.toString is also - // a function. - // All failure cases from here should reset them to undefined, to avoid - // leaving partially initiallized object in the constructor slot. - global->setConstructor(key, ObjectValue(*ctor)); - global->setConstructorPropertySlot(key, ObjectValue(*ctor)); - - if (!defineConstructorPropertiesAndLinkPrototype(cx, global, key, clasp, id, - ctor, proto)) - { - global->setConstructor(key, UndefinedValue()); - global->setConstructorPropertySlot(key, UndefinedValue()); - return false; - } - - return true; -} - -/* static */ bool -GlobalObject::defineConstructorPropertiesAndLinkPrototype(JSContext* cx, - Handle global, - JSProtoKey key, const Class* clasp, - HandleId id, HandleObject ctor, - HandleObject proto) -{ // Define any specified functions and properties, unless we're a dependent // standard class (in which case they live on the prototype), or we're // operating on the self-hosting global, in which case we don't want any @@ -280,6 +263,23 @@ GlobalObject::defineConstructorPropertiesAndLinkPrototype(JSContext* cx, return false; } + if (!isObjectOrFunction) { + // Any operations that modifies the global object should be placed + // after any other fallible operations. + + // Fallible operation that modifies the global object. + if (clasp->specShouldDefineConstructor()) { + if (!global->addDataProperty(cx, id, constructorPropertySlot(key), 0)) + return false; + } + + // Infallible operations that modify the global object. + global->setConstructor(key, ObjectValue(*ctor)); + global->setConstructorPropertySlot(key, ObjectValue(*ctor)); + if (proto) + global->setPrototype(key, ObjectValue(*proto)); + } + if (clasp->specShouldDefineConstructor()) { // Stash type information, so that what we do here is equivalent to // initBuiltinConstructor. diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h index 65a1391db619..480a7fb588a2 100644 --- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -241,12 +241,6 @@ class GlobalObject : public NativeObject } private: - static bool defineConstructorPropertiesAndLinkPrototype(JSContext* cx, - Handle global, - JSProtoKey key, const Class* clasp, - HandleId id, HandleObject ctor, - HandleObject proto); - bool arrayClassInitialized() const { return classIsInitialized(JSProto_Array); } @@ -278,7 +272,6 @@ class GlobalObject : public NativeObject Value createArrayFromBufferHelper(uint32_t slot) const { MOZ_ASSERT(FROM_BUFFER_UINT8 <= slot && slot <= FROM_BUFFER_UINT8CLAMPED); - MOZ_ASSERT(!getSlot(slot).isUndefined()); return getSlot(slot); } diff --git a/js/src/vm/ObjectGroup.h b/js/src/vm/ObjectGroup.h index 82befe49c4e7..9bd31c9c05e1 100644 --- a/js/src/vm/ObjectGroup.h +++ b/js/src/vm/ObjectGroup.h @@ -424,7 +424,6 @@ class ObjectGroup : public gc::TenuredCell size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; void finalize(FreeOp* fop); - void fixupAfterMovingGC() {} static const JS::TraceKind TraceKind = JS::TraceKind::ObjectGroup; diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 6bc37057f2c8..fc49d846318a 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -1172,7 +1172,7 @@ intrinsic_MoveTypedArrayElements(JSContext* cx, unsigned argc, Value* vp) "the not-detached requirement is wrong"); if (tarray->hasDetachedBuffer()) { - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS); + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED); return false; } diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index 28b99d334b78..a1339d199a2a 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -454,8 +454,6 @@ class BaseShape : public gc::TenuredCell void traceChildren(JSTracer* trc); void traceChildrenSkipShapeTable(JSTracer* trc); - void fixupAfterMovingGC() {} - private: static void staticAsserts() { JS_STATIC_ASSERT(offsetof(BaseShape, clasp_) == offsetof(js::shadow::BaseShape, clasp_)); diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index 082f69da5959..f426828b3819 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -944,7 +944,7 @@ AutoStableStringChars::allocOwnChars(JSContext* cx, size_t count) static_assert((JSString::MAX_LENGTH & mozilla::tl::MulOverflowMask::value) == 0, "Size calculation can overflow"); - MOZ_ASSERT(count <= JSString::MAX_LENGTH); + MOZ_ASSERT(count <= (JSString::MAX_LENGTH + 1)); size_t size = sizeof(T) * count; ownChars_.emplace(cx); diff --git a/js/src/vm/String.h b/js/src/vm/String.h index 15a2292239de..e618c36f06eb 100644 --- a/js/src/vm/String.h +++ b/js/src/vm/String.h @@ -474,8 +474,6 @@ class JSString : public js::gc::TenuredCell inline void finalize(js::FreeOp* fop); - void fixupAfterMovingGC() {} - /* Gets the number of bytes that the chars take on the heap. */ size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf); diff --git a/js/src/vm/Symbol.cpp b/js/src/vm/Symbol.cpp index dfe6278d1400..064e8473c3f3 100644 --- a/js/src/vm/Symbol.cpp +++ b/js/src/vm/Symbol.cpp @@ -37,7 +37,7 @@ Symbol::newInternal(ExclusiveContext* cx, JS::SymbolCode code, JSAtom* descripti Symbol* Symbol::new_(ExclusiveContext* cx, JS::SymbolCode code, JSString* description) { - RootedAtom atom(cx); + JSAtom* atom = nullptr; if (description) { atom = AtomizeString(cx, description); if (!atom) diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 898201dfbeb8..27757f7c3eca 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -248,6 +248,18 @@ class TypedArrayObjectTemplate : public TypedArrayObject { return false; } + return true; + } + + static bool + getOrCreateCreateArrayFromBufferFunction(JSContext* cx, MutableHandleValue fval) + { + RootedValue cache(cx, cx->global()->createArrayFromBuffer()); + if (cache.isObject()) { + MOZ_ASSERT(cache.toObject().is()); + fval.set(cache); + return true; + } RootedFunction fun(cx); fun = NewNativeFunction(cx, ArrayBufferObject::createTypedArrayFromBuffer, @@ -256,6 +268,8 @@ class TypedArrayObjectTemplate : public TypedArrayObject return false; cx->global()->setCreateArrayFromBuffer(fun); + + fval.setObject(*fun); return true; } @@ -576,7 +590,10 @@ class TypedArrayObjectTemplate : public TypedArrayObject args[1].setInt32(lengthInt); args[2].setObject(*protoRoot); - RootedValue fval(cx, cx->global()->createArrayFromBuffer()); + RootedValue fval(cx); + if (!getOrCreateCreateArrayFromBufferFunction(cx, &fval)) + return nullptr; + RootedValue thisv(cx, ObjectValue(*bufobj)); RootedValue rval(cx); if (!js::Call(cx, fval, thisv, args, &rval)) @@ -605,7 +622,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject } if (byteOffset > buffer->byteLength() || byteOffset % sizeof(NativeType) != 0) { - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS); + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS); return nullptr; // invalid byteOffset } @@ -614,7 +631,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject len = (buffer->byteLength() - byteOffset) / sizeof(NativeType); if (len * sizeof(NativeType) != buffer->byteLength() - byteOffset) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - JSMSG_TYPED_ARRAY_BAD_ARGS); + JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS); return nullptr; // given byte array doesn't map exactly to sizeof(NativeType) * N } } else { @@ -624,12 +641,12 @@ class TypedArrayObjectTemplate : public TypedArrayObject // Go slowly and check for overflow. uint32_t arrayByteLength = len * sizeof(NativeType); if (len >= INT32_MAX / sizeof(NativeType) || byteOffset >= INT32_MAX - arrayByteLength) { - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS); + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS); return nullptr; // overflow when calculating byteOffset + len * sizeof(NativeType) } if (arrayByteLength + byteOffset > buffer->byteLength()) { - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS); + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS); return nullptr; // byteOffset + len is too big for the arraybuffer } diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index af2ce684a82a..d7ebaf21b04f 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -2512,9 +2512,9 @@ ContainerState::FindOpaqueBackgroundColorInLayer(const PaintedLayerData* aData, return NS_RGBA(0,0,0,0); } - nscolor color; - if (item->IsUniform(mBuilder, &color) && NS_GET_A(color) == 255) - return color; + Maybe color = item->IsUniform(mBuilder); + if (color && NS_GET_A(*color) == 255) + return *color; return NS_RGBA(0,0,0,0); } @@ -3422,34 +3422,33 @@ PaintedLayerData::Accumulate(ContainerState* aState, } } - nscolor uniformColor; - bool isUniform = aItem->IsUniform(aState->mBuilder, &uniformColor); + Maybe uniformColor = aItem->IsUniform(aState->mBuilder); // Some display items have to exist (so they can set forceTransparentSurface // below) but don't draw anything. They'll return true for isUniform but // a color with opacity 0. - if (!isUniform || NS_GET_A(uniformColor) > 0) { + if (!uniformColor || NS_GET_A(*uniformColor) > 0) { // Make sure that the visible area is covered by uniform pixels. In // particular this excludes cases where the edges of the item are not // pixel-aligned (thus the item will not be truly uniform). - if (isUniform) { + if (uniformColor) { bool snap; nsRect bounds = aItem->GetBounds(aState->mBuilder, &snap); if (!aState->ScaleToInsidePixels(bounds, snap).Contains(aVisibleRect)) { - isUniform = false; + uniformColor = Nothing(); FLB_LOG_PAINTED_LAYER_DECISION(this, " Display item does not cover the visible rect\n"); } } - if (isUniform) { + if (uniformColor) { if (isFirstVisibleItem) { // This color is all we have - mSolidColor = uniformColor; + mSolidColor = *uniformColor; mIsSolidColorInVisibleRegion = true; } else if (mIsSolidColorInVisibleRegion && mVisibleRegion.IsEqual(nsIntRegion(aVisibleRect)) && clipMatches) { // we can just blend the colors together - mSolidColor = NS_ComposeColors(mSolidColor, uniformColor); + mSolidColor = NS_ComposeColors(mSolidColor, *uniformColor); } else { FLB_LOG_PAINTED_LAYER_DECISION(this, " Layer not a solid color: Can't blend colors togethers\n"); mIsSolidColorInVisibleRegion = false; @@ -3903,7 +3902,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList) } nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap); bool prerenderedTransform = itemType == nsDisplayItem::TYPE_TRANSFORM && - static_cast(item)->ShouldPrerender(mBuilder); + static_cast(item)->MayBeAnimated(mBuilder); ParentLayerIntRect clipRect; const DisplayItemClip& itemClip = item->GetClip(); if (itemClip.HasClip()) { diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 3b74676fb9b8..b6f8ee25042d 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -217,8 +217,6 @@ public: void DidEndTransaction(); enum { - CONTAINER_NOT_CLIPPED_BY_ANCESTORS = 0x01, - /** * Set this when pulling an opaque background color from behind the * container layer into the container doesn't change the visual results, @@ -226,7 +224,7 @@ public: * For example, this is compatible with opacity or clipping/masking, but * not with non-OVER blend modes or filters. */ - CONTAINER_ALLOW_PULL_BACKGROUND_COLOR = 0x02 + CONTAINER_ALLOW_PULL_BACKGROUND_COLOR = 0x01 }; /** * Build a container layer for a display item that contains a child diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 2642373c4d3b..96613f9f5698 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -1641,46 +1641,79 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, } } +/* static */ +nsCSSRendering::PaintBGParams +nsCSSRendering::PaintBGParams::ForAllLayers(nsPresContext& aPresCtx, + nsRenderingContext& aRenderingCtx, + const nsRect& aDirtyRect, + const nsRect& aBorderArea, + nsIFrame *aFrame, + uint32_t aPaintFlags) +{ + MOZ_ASSERT(aFrame); + + PaintBGParams result(aPresCtx, aRenderingCtx, aDirtyRect, aBorderArea); + + result.frame = aFrame; + result.paintFlags = aPaintFlags; + result.layer = -1; + + return result; +} + +/* static */ +nsCSSRendering::PaintBGParams +nsCSSRendering::PaintBGParams::ForSingleLayer(nsPresContext& aPresCtx, + nsRenderingContext& aRenderingCtx, + const nsRect& aDirtyRect, + const nsRect& aBorderArea, + nsIFrame *aFrame, + uint32_t aPaintFlags, + int32_t aLayer, + CompositionOp aCompositionOp) +{ + MOZ_ASSERT(aFrame && (aLayer != -1)); + + PaintBGParams result(aPresCtx, aRenderingCtx, aDirtyRect, aBorderArea); + + result.frame = aFrame; + result.paintFlags = aPaintFlags; + + result.layer = aLayer; + result.compositionOp = aCompositionOp; + + return result; +} + DrawResult -nsCSSRendering::PaintBackground(nsPresContext* aPresContext, - nsRenderingContext& aRenderingContext, - nsIFrame* aForFrame, - const nsRect& aDirtyRect, - const nsRect& aBorderArea, - uint32_t aFlags, - nsRect* aBGClipRect, - int32_t aLayer, - CompositionOp aCompositonOp) +nsCSSRendering::PaintBackground(const PaintBGParams& aParams) { PROFILER_LABEL("nsCSSRendering", "PaintBackground", js::ProfileEntry::Category::GRAPHICS); - NS_PRECONDITION(aForFrame, + NS_PRECONDITION(aParams.frame, "Frame is expected to be provided to PaintBackground"); nsStyleContext *sc; - if (!FindBackground(aForFrame, &sc)) { + if (!FindBackground(aParams.frame, &sc)) { // We don't want to bail out if moz-appearance is set on a root // node. If it has a parent content node, bail because it's not // a root, otherwise keep going in order to let the theme stuff // draw the background. The canvas really should be drawing the // bg, but there's no way to hook that up via css. - if (!aForFrame->StyleDisplay()->mAppearance) { + if (!aParams.frame->StyleDisplay()->mAppearance) { return DrawResult::SUCCESS; } - nsIContent* content = aForFrame->GetContent(); + nsIContent* content = aParams.frame->GetContent(); if (!content || content->GetParent()) { return DrawResult::SUCCESS; } - sc = aForFrame->StyleContext(); + sc = aParams.frame->StyleContext(); } - return PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame, - aDirtyRect, aBorderArea, sc, - *aForFrame->StyleBorder(), aFlags, - aBGClipRect, aLayer, aCompositonOp); + return PaintBackgroundWithSC(aParams, sc, *aParams.frame->StyleBorder()); } static bool @@ -2855,41 +2888,36 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext, } DrawResult -nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, - nsRenderingContext& aRenderingContext, - nsIFrame* aForFrame, - const nsRect& aDirtyRect, - const nsRect& aBorderArea, - nsStyleContext* aBackgroundSC, - const nsStyleBorder& aBorder, - uint32_t aFlags, - nsRect* aBGClipRect, - int32_t aLayer, - CompositionOp aCompositonOp) +nsCSSRendering::PaintBackgroundWithSC(const PaintBGParams& aParams, + nsStyleContext *aBackgroundSC, + const nsStyleBorder& aBorder) { - NS_PRECONDITION(aForFrame, + NS_PRECONDITION(aParams.frame, "Frame is expected to be provided to PaintBackground"); // If we're drawing all layers, aCompositonOp is ignored, so make sure that // it was left at its default value. - MOZ_ASSERT_IF(aLayer == -1, aCompositonOp == CompositionOp::OP_OVER); + MOZ_ASSERT_IF(aParams.layer == -1, + aParams.compositionOp == CompositionOp::OP_OVER); DrawResult result = DrawResult::SUCCESS; // Check to see if we have an appearance defined. If so, we let the theme // renderer draw the background and bail out. - // XXXzw this ignores aBGClipRect. - const nsStyleDisplay* displayData = aForFrame->StyleDisplay(); + // XXXzw this ignores aParams.bgClipRect. + const nsStyleDisplay* displayData = aParams.frame->StyleDisplay(); if (displayData->mAppearance) { - nsITheme *theme = aPresContext->GetTheme(); - if (theme && theme->ThemeSupportsWidget(aPresContext, aForFrame, + nsITheme *theme = aParams.presCtx.GetTheme(); + if (theme && theme->ThemeSupportsWidget(&aParams.presCtx, + aParams.frame, displayData->mAppearance)) { - nsRect drawing(aBorderArea); - theme->GetWidgetOverflow(aPresContext->DeviceContext(), - aForFrame, displayData->mAppearance, &drawing); - drawing.IntersectRect(drawing, aDirtyRect); - theme->DrawWidgetBackground(&aRenderingContext, aForFrame, - displayData->mAppearance, aBorderArea, + nsRect drawing(aParams.borderArea); + theme->GetWidgetOverflow(aParams.presCtx.DeviceContext(), + aParams.frame, displayData->mAppearance, + &drawing); + drawing.IntersectRect(drawing, aParams.dirtyRect); + theme->DrawWidgetBackground(&aParams.renderingCtx, aParams.frame, + displayData->mAppearance, aParams.borderArea, drawing); return DrawResult::SUCCESS; } @@ -2902,26 +2930,26 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, // nsPresShell::AddCanvasBackgroundColorItem, and painted by // nsDisplayCanvasBackground directly.) Either way we don't need to // paint the background color here. - bool isCanvasFrame = IsCanvasFrame(aForFrame); + bool isCanvasFrame = IsCanvasFrame(aParams.frame); // Determine whether we are drawing background images and/or // background colors. bool drawBackgroundImage; bool drawBackgroundColor; - nscolor bgColor = DetermineBackgroundColor(aPresContext, + nscolor bgColor = DetermineBackgroundColor(&aParams.presCtx, aBackgroundSC, - aForFrame, + aParams.frame, drawBackgroundImage, drawBackgroundColor); - bool paintMask = (aFlags & PAINTBG_MASK_IMAGE); + bool paintMask = (aParams.paintFlags & PAINTBG_MASK_IMAGE); const nsStyleImageLayers& layers = paintMask ? aBackgroundSC->StyleSVGReset()->mMask : aBackgroundSC->StyleBackground()->mImage; // If we're drawing a specific layer, we don't want to draw the // background color. - if ((drawBackgroundColor && aLayer >= 0) || paintMask) { + if ((drawBackgroundColor && aParams.layer >= 0) || paintMask) { drawBackgroundColor = false; } @@ -2932,32 +2960,35 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, return DrawResult::SUCCESS; // Compute the outermost boundary of the area that might be painted. - // Same coordinate space as aBorderArea & aBGClipRect. - Sides skipSides = aForFrame->GetSkipSides(); + // Same coordinate space as aParams.borderArea & aParams.bgClipRect. + Sides skipSides = aParams.frame->GetSkipSides(); nsRect paintBorderArea = - ::BoxDecorationRectForBackground(aForFrame, aBorderArea, skipSides, &aBorder); + ::BoxDecorationRectForBackground(aParams.frame, aParams.borderArea, + skipSides, &aBorder); nsRect clipBorderArea = - ::BoxDecorationRectForBorder(aForFrame, aBorderArea, skipSides, &aBorder); + ::BoxDecorationRectForBorder(aParams.frame, aParams.borderArea, + skipSides, &aBorder); // The 'bgClipArea' (used only by the image tiling logic, far below) - // is the caller-provided aBGClipRect if any, or else the area + // is the caller-provided aParams.bgClipRect if any, or else the area // determined by the value of 'background-clip' in // SetupCurrentBackgroundClip. (Arguably it should be the // intersection, but that breaks the table painter -- in particular, // taking the intersection breaks reftests/bugs/403249-1[ab].) - gfxContext* ctx = aRenderingContext.ThebesContext(); - nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel(); + gfxContext* ctx = aParams.renderingCtx.ThebesContext(); + nscoord appUnitsPerPixel = aParams.presCtx.AppUnitsPerDevPixel(); ImageLayerClipState clipState; - if (aBGClipRect) { - clipState.mBGClipArea = *aBGClipRect; + if (aParams.bgClipRect) { + clipState.mBGClipArea = *aParams.bgClipRect; clipState.mCustomClip = true; clipState.mHasRoundedCorners = false; - SetupDirtyRects(clipState.mBGClipArea, aDirtyRect, appUnitsPerPixel, + SetupDirtyRects(clipState.mBGClipArea, aParams.dirtyRect, appUnitsPerPixel, &clipState.mDirtyRect, &clipState.mDirtyRectGfx); } else { GetImageLayerClip(layers.BottomLayer(), - aForFrame, aBorder, aBorderArea, - aDirtyRect, (aFlags & PAINTBG_WILL_PAINT_BORDER), + aParams.frame, aBorder, aParams.borderArea, + aParams.dirtyRect, + (aParams.paintFlags & PAINTBG_WILL_PAINT_BORDER), appUnitsPerPixel, &clipState); } @@ -2987,7 +3018,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, } // Validate the layer range before we start iterating. - int32_t startLayer = aLayer; + int32_t startLayer = aParams.layer; int32_t nLayers = 1; if (startLayer < 0) { startLayer = (int32_t)layers.mImageCount - 1; @@ -2997,9 +3028,10 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, // Ensure we get invalidated for loads of the image. We need to do // this here because this might be the only code that knows about the // association of the style data with the frame. - if (aBackgroundSC != aForFrame->StyleContext()) { + if (aBackgroundSC != aParams.frame->StyleContext()) { NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(i, layers, startLayer, nLayers) { - aForFrame->AssociateImage(layers.mLayers[i].mImage, aPresContext); + aParams.frame->AssociateImage(layers.mLayers[i].mImage, + &aParams.presCtx); } } @@ -3016,7 +3048,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, nLayers + (layers.mImageCount - startLayer - 1)) { const nsStyleImageLayers::Layer& layer = layers.mLayers[i]; - if (!aBGClipRect) { + if (!aParams.bgClipRect) { if (currentBackgroundClip != layer.mClip || !clipSet) { currentBackgroundClip = layer.mClip; // If clipSet is false that means this is the bottom layer and we @@ -3024,17 +3056,18 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, // in clipState. if (clipSet) { autoSR.Restore(); // reset the previous one - GetImageLayerClip(layer, aForFrame, - aBorder, aBorderArea, aDirtyRect, (aFlags & PAINTBG_WILL_PAINT_BORDER), + GetImageLayerClip(layer, aParams.frame, + aBorder, aParams.borderArea, aParams.dirtyRect, + (aParams.paintFlags & PAINTBG_WILL_PAINT_BORDER), appUnitsPerPixel, &clipState); } SetupImageLayerClip(clipState, ctx, appUnitsPerPixel, &autoSR); clipSet = true; - if (!clipBorderArea.IsEqualEdges(aBorderArea)) { + if (!clipBorderArea.IsEqualEdges(aParams.borderArea)) { // We're drawing the background for the joined continuation boxes // so we need to clip that to the slice that we want for this frame. gfxRect clip = - nsLayoutUtils::RectToGfxRect(aBorderArea, appUnitsPerPixel); + nsLayoutUtils::RectToGfxRect(aParams.borderArea, appUnitsPerPixel); autoSR.EnsureSaved(ctx); ctx->NewPath(); ctx->SnappedRectangle(clip); @@ -3042,16 +3075,16 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, } } } - if ((aLayer < 0 || i == (uint32_t)startLayer) && + if ((aParams.layer < 0 || i == (uint32_t)startLayer) && !clipState.mDirtyRectGfx.IsEmpty()) { // When we're drawing a single layer, use the specified composition op, // otherwise get the compositon op from the image layer. - CompositionOp co = (aLayer >= 0) ? aCompositonOp : + CompositionOp co = (aParams.layer >= 0) ? aParams.compositionOp : (paintMask ? GetGFXCompositeMode(layer.mComposite) : GetGFXBlendMode(layer.mBlendMode)); nsBackgroundLayerState state = - PrepareImageLayer(aPresContext, aForFrame, - aFlags, paintBorderArea, clipState.mBGClipArea, + PrepareImageLayer(&aParams.presCtx, aParams.frame, + aParams.paintFlags, paintBorderArea, clipState.mBGClipArea, layer, nullptr, co); result &= state.mImageRenderer.PrepareResult(); if (!state.mFillArea.IsEmpty()) { @@ -3065,7 +3098,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, } result &= - state.mImageRenderer.DrawBackground(aPresContext, aRenderingContext, + state.mImageRenderer.DrawBackground(&aParams.presCtx, + aParams.renderingCtx, state.mDestArea, state.mFillArea, state.mAnchor + paintBorderArea.TopLeft(), clipState.mDirtyRect); diff --git a/layout/base/nsCSSRendering.h b/layout/base/nsCSSRendering.h index 6d4144490c0f..bfe062eec725 100644 --- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -589,15 +589,47 @@ struct nsCSSRendering { */ PAINTBG_MASK_IMAGE = 0x08 }; - static DrawResult PaintBackground(nsPresContext* aPresContext, - nsRenderingContext& aRenderingContext, - nsIFrame* aForFrame, - const nsRect& aDirtyRect, - const nsRect& aBorderArea, - uint32_t aFlags, - nsRect* aBGClipRect = nullptr, - int32_t aLayer = -1, - CompositionOp aCompositionOp = CompositionOp::OP_OVER); + + struct PaintBGParams { + nsPresContext& presCtx; + nsRenderingContext& renderingCtx; + nsRect dirtyRect; + nsRect borderArea; + nsIFrame* frame; + uint32_t paintFlags = 0; + nsRect* bgClipRect = nullptr; + int32_t layer; // -1 means painting all layers; other + // value means painting one specific + // layer only. + CompositionOp compositionOp = CompositionOp::OP_OVER; + + static PaintBGParams ForAllLayers(nsPresContext& aPresCtx, + nsRenderingContext& aRenderingCtx, + const nsRect& aDirtyRect, + const nsRect& aBorderArea, + nsIFrame *aFrame, + uint32_t aPaintFlags); + static PaintBGParams ForSingleLayer(nsPresContext& aPresCtx, + nsRenderingContext& aRenderingCtx, + const nsRect& aDirtyRect, + const nsRect& aBorderArea, + nsIFrame *aFrame, + uint32_t aPaintFlags, + int32_t aLayer, + CompositionOp aCompositionOp = CompositionOp::OP_OVER); + + private: + PaintBGParams(nsPresContext& aPresCtx, + nsRenderingContext& aRenderingCtx, + const nsRect& aDirtyRect, + const nsRect& aBorderArea) + : presCtx(aPresCtx), + renderingCtx(aRenderingCtx), + dirtyRect(aDirtyRect), + borderArea(aBorderArea) { } + }; + + static DrawResult PaintBackground(const PaintBGParams& aParams); /** @@ -612,17 +644,9 @@ struct nsCSSRendering { * If all layers are painted, the image layer's blend mode (or the mask * layer's composition mode) will be used. */ - static DrawResult PaintBackgroundWithSC(nsPresContext* aPresContext, - nsRenderingContext& aRenderingContext, - nsIFrame* aForFrame, - const nsRect& aDirtyRect, - const nsRect& aBorderArea, - nsStyleContext *aStyleContext, - const nsStyleBorder& aBorder, - uint32_t aFlags, - nsRect* aBGClipRect = nullptr, - int32_t aLayer = -1, - CompositionOp aCompositionOp = CompositionOp::OP_OVER); + static DrawResult PaintBackgroundWithSC(const PaintBGParams& aParams, + nsStyleContext *mBackgroundSC, + const nsStyleBorder& aBorder); /** * Returns the rectangle covered by the given background layer image, taking diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 32222e7965be..c119826b1aad 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2883,13 +2883,12 @@ nsDisplayBackgroundImage::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, return result; } -bool -nsDisplayBackgroundImage::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { +Maybe +nsDisplayBackgroundImage::IsUniform(nsDisplayListBuilder* aBuilder) { if (!mBackgroundStyle) { - *aColor = NS_RGBA(0,0,0,0); - return true; + return Some(NS_RGBA(0,0,0,0)); } - return false; + return Nothing(); } nsRect @@ -2961,12 +2960,15 @@ nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder, GenerateAndPushTextMask(mFrame, aCtx, mBackgroundRect); } + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForSingleLayer(*mFrame->PresContext(), + *aCtx, + aBounds, mBackgroundRect, + mFrame, flags, mLayer, + CompositionOp::OP_OVER); + params.bgClipRect = aClipRect; image::DrawResult result = - nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame, - aBounds, - mBackgroundRect, - flags, aClipRect, mLayer, - CompositionOp::OP_OVER); + nsCSSRendering::PaintBackground(params); if (clip == NS_STYLE_IMAGELAYER_CLIP_TEXT) { ctx->PopGroupAndBlend(); @@ -3131,14 +3133,13 @@ nsDisplayThemedBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, return result; } -bool -nsDisplayThemedBackground::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { +Maybe +nsDisplayThemedBackground::IsUniform(nsDisplayListBuilder* aBuilder) { if (mAppearance == NS_THEME_WIN_BORDERLESS_GLASS || mAppearance == NS_THEME_WIN_GLASS) { - *aColor = NS_RGBA(0,0,0,0); - return true; + return Some(NS_RGBA(0,0,0,0)); } - return false; + return Nothing(); } bool @@ -3429,11 +3430,10 @@ nsDisplayBackgroundColor::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, mBackgroundRect, mBackgroundRect); } -bool -nsDisplayBackgroundColor::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) +Maybe +nsDisplayBackgroundColor::IsUniform(nsDisplayListBuilder* aBuilder) { - *aColor = mColor.ToABGR(); - return true; + return Some(mColor.ToABGR()); } void @@ -4093,9 +4093,10 @@ nsDisplayWrapList::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, return result; } -bool nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { - // We could try to do something but let's conservatively just return false. - return false; +Maybe +nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder) { + // We could try to do something but let's conservatively just return Nothing. + return Nothing(); } void nsDisplayWrapList::Paint(nsDisplayListBuilder* aBuilder, @@ -4309,7 +4310,7 @@ nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder, static bool IsItemTooSmallForActiveLayer(nsDisplayItem* aItem) { - nsIntRect visibleDevPixels = aItem->GetVisibleRect().ToOutsidePixels( + nsIntRect visibleDevPixels = aItem->Frame()->GetVisualOverflowRectRelativeToSelf().ToOutsidePixels( aItem->Frame()->PresContext()->AppUnitsPerDevPixel()); static const int MIN_ACTIVE_LAYER_SIZE_DEV_PIXELS = 16; return visibleDevPixels.Size() < @@ -4322,7 +4323,7 @@ SetAnimationPerformanceWarningForTooSmallItem(nsDisplayItem* aItem, { // We use ToNearestPixels() here since ToOutsidePixels causes some sort of // errors. See https://bugzilla.mozilla.org/show_bug.cgi?id=1258904#c19 - nsIntRect visibleDevPixels = aItem->GetVisibleRect().ToNearestPixels( + nsIntRect visibleDevPixels = aItem->Frame()->GetVisualOverflowRectRelativeToSelf().ToNearestPixels( aItem->Frame()->PresContext()->AppUnitsPerDevPixel()); // Set performance warning only if the visible dev pixels is not empty @@ -5273,6 +5274,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, , mNoExtendContext(false) , mIsTransformSeparator(false) , mTransformPreserves3DInited(false) + , mIsFullyVisible(false) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); @@ -5322,24 +5324,13 @@ nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder) mHasBounds = false; mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip()); mStoredList.SetVisibleRect(mChildrenVisibleRect); - mMaybePrerender = ShouldPrerenderTransformedContent(aBuilder, mFrame); - - const nsStyleDisplay* disp = mFrame->StyleDisplay(); - if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { - // We will only pre-render if this will-change is on budget. - mMaybePrerender = true; - } - - if (mMaybePrerender) { - bool snap; - mVisibleRect = GetBounds(aBuilder, &snap); - } } nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, nsDisplayList *aList, const nsRect& aChildrenVisibleRect, - uint32_t aIndex) + uint32_t aIndex, + bool aIsFullyVisible) : nsDisplayItem(aBuilder, aFrame) , mStoredList(aBuilder, aFrame, aList) , mTransformGetter(nullptr) @@ -5350,6 +5341,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, , mNoExtendContext(false) , mIsTransformSeparator(false) , mTransformPreserves3DInited(false) + , mIsFullyVisible(aIsFullyVisible) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); @@ -5372,6 +5364,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, , mNoExtendContext(false) , mIsTransformSeparator(false) , mTransformPreserves3DInited(false) + , mIsFullyVisible(false) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); @@ -5395,6 +5388,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, , mNoExtendContext(false) , mIsTransformSeparator(true) , mTransformPreserves3DInited(false) + , mIsFullyVisible(false) { MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_ASSERT(aFrame, "Must have a frame!"); @@ -5795,36 +5789,10 @@ nsDisplayOpacity::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) return false; } -bool -nsDisplayTransform::ShouldPrerender(nsDisplayListBuilder* aBuilder) { - if (!mMaybePrerender) { - return false; - } - - if (ShouldPrerenderTransformedContent(aBuilder, mFrame)) { - return true; - } - - const nsStyleDisplay* disp = mFrame->StyleDisplay(); - if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) && - aBuilder->IsInWillChangeBudget(mFrame, mFrame->GetSize())) { - return true; - } - - return false; -} - bool nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) { - if (mMaybePrerender) { - // TODO We need to make sure that if we use async animation we actually - // pre-render even if we're out of will change budget. - return true; - } - DebugOnly prerender = ShouldPrerenderTransformedContent(aBuilder, mFrame); - NS_ASSERTION(!prerender, "Something changed under us!"); - return false; + return mIsFullyVisible; } /* static */ bool @@ -5968,7 +5936,7 @@ nsDisplayTransform::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuild // The visible rect of a Preserves-3D frame is just an intermediate // result. It should always build a layer to make sure it is // rendering correctly. - return ShouldPrerender(aBuilder) || mFrame->Combines3DTransformWithAncestors(); + return MayBeAnimated(aBuilder) || mFrame->Combines3DTransformWithAncestors(); } already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBuilder, @@ -5981,9 +5949,7 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu */ const Matrix4x4& newTransformMatrix = GetTransformForRendering(); - uint32_t flags = ShouldPrerender(aBuilder) ? - FrameLayerBuilder::CONTAINER_NOT_CLIPPED_BY_ANCESTORS : 0; - flags |= FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR; + uint32_t flags = FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR; RefPtr container = aManager->GetLayerBuilder()-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mStoredList.GetChildren(), aContainerParameters, &newTransformMatrix, flags); @@ -6003,14 +5969,12 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder, this, mFrame, eCSSProperty_transform); - if (ShouldPrerender(aBuilder)) { - if (MayBeAnimated(aBuilder)) { - // Only allow async updates to the transform if we're an animated layer, since that's what - // triggers us to set the correct AGR in the constructor and makes sure FrameLayerBuilder - // won't compute occlusions for this layer. - container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(), - /*the value is irrelevant*/nullptr); - } + if (mIsFullyVisible && MayBeAnimated(aBuilder)) { + // Only allow async updates to the transform if we're an animated layer, since that's what + // triggers us to set the correct AGR in the constructor and makes sure FrameLayerBuilder + // won't compute occlusions for this layer. + container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(), + /*the value is irrelevant*/nullptr); container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_MAY_CHANGE_TRANSFORM); } else { container->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey()); @@ -6055,11 +6019,6 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder, return LAYER_ACTIVE_FORCE; } - const nsStyleDisplay* disp = mFrame->StyleDisplay(); - if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { - return LAYER_ACTIVE; - } - // Expect the child display items to have this frame as their animated // geometry root (since it will be their reference frame). If they have a // different animated geometry root, we'll make this an active layer so the @@ -6076,8 +6035,7 @@ bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder, * think that it's painting in its original rectangular coordinate space. * If we can't untransform, take the entire overflow rect */ nsRect untransformedVisibleRect; - if (ShouldPrerender(aBuilder) || - !UntransformVisibleRect(aBuilder, &untransformedVisibleRect)) + if (!UntransformVisibleRect(aBuilder, &untransformedVisibleRect)) { untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf(); } @@ -6222,9 +6180,7 @@ nsDisplayTransform::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) return nsRect(); } - nsRect untransformedBounds = MaybePrerender() ? - mFrame->GetVisualOverflowRectRelativeToSelf() : - mStoredList.GetBounds(aBuilder, aSnap); + nsRect untransformedBounds = mStoredList.GetBounds(aBuilder, aSnap); // GetTransform always operates in dev pixels. float factor = mFrame->PresContext()->AppUnitsPerDevPixel(); mBounds = nsLayoutUtils::MatrixTransformRect(untransformedBounds, @@ -6261,9 +6217,7 @@ nsDisplayTransform::ComputeBounds(nsDisplayListBuilder* aBuilder) * nsDisplayListBuilder. */ bool snap; - nsRect untransformedBounds = MaybePrerender() ? - mFrame->GetVisualOverflowRectRelativeToSelf() : - mStoredList.GetBounds(aBuilder, &snap); + nsRect untransformedBounds = mStoredList.GetBounds(aBuilder, &snap); // GetTransform always operates in dev pixels. float factor = mFrame->PresContext()->AppUnitsPerDevPixel(); nsRect rect = @@ -6295,14 +6249,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder, { *aSnap = false; nsRect untransformedVisible; - // If we're going to prerender all our content, pretend like we - // don't have opqaue content so that everything under us is rendered - // as well. That will increase graphics memory usage if our frame - // covers the entire window, but it allows our transform to be - // updated extremely cheaply, without invalidating any other - // content. - if (MaybePrerender() || - !UntransformVisibleRect(aBuilder, &untransformedVisible)) { + if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) { return nsRegion(); } @@ -6323,19 +6270,23 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder, * wrapped list is uniform. See GetOpaqueRegion for discussion of why this * works. */ -bool nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor) +Maybe +nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder) { nsRect untransformedVisible; if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) { - return false; + return Nothing(); } const Matrix4x4& matrix = GetTransform(); Matrix matrix2d; - return matrix.Is2D(&matrix2d) && - matrix2d.PreservesAxisAlignedRectangles() && - mStoredList.GetVisibleRect().Contains(untransformedVisible) && - mStoredList.IsUniform(aBuilder, aColor); + if (matrix.Is2D(&matrix2d) && + matrix2d.PreservesAxisAlignedRectangles() && + mStoredList.GetVisibleRect().Contains(untransformedVisible)) { + return mStoredList.IsUniform(aBuilder); + } + + return Nothing(); } /* If UNIFIED_CONTINUATIONS is defined, we can merge two display lists that @@ -6630,8 +6581,7 @@ nsDisplayVR::BuildLayer(nsDisplayListBuilder* aBuilder, const ContainerLayerParameters& aContainerParameters) { ContainerLayerParameters newContainerParameters = aContainerParameters; - uint32_t flags = FrameLayerBuilder::CONTAINER_NOT_CLIPPED_BY_ANCESTORS | - FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR; + uint32_t flags = FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR; RefPtr container = aManager->GetLayerBuilder()-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList, newContainerParameters, nullptr, flags); @@ -6667,10 +6617,12 @@ nsDisplaySVGEffects::PaintAsLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager) { nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize()); - nsSVGIntegrationUtils::PaintFramesWithEffects(*aCtx->ThebesContext(), mFrame, - mVisibleRect, - borderArea, - aBuilder, aManager); + nsSVGIntegrationUtils::PaintFramesParams params(*aCtx->ThebesContext(), + mFrame, mVisibleRect, + borderArea, aBuilder, + aManager); + + nsSVGIntegrationUtils::PaintFramesWithEffects(params); } LayerState @@ -6727,6 +6679,21 @@ nsDisplaySVGEffects::BuildLayer(nsDisplayListBuilder* aBuilder, return container.forget(); } +nsRect +nsDisplaySVGEffects::GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) +{ + nsIFrame* firstFrame = + nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame); + nsSVGEffects::EffectProperties effectProperties = + nsSVGEffects::GetEffectProperties(firstFrame); + + if (effectProperties.HasValidFilter()) { + return nsRect(); + } + + return nsDisplayWrapList::GetComponentAlphaBounds(aBuilder); +} + bool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion) { nsPoint offset = ToReferenceFrame(); @@ -6835,7 +6802,7 @@ nsDisplaySVGEffects::PrintEffects(nsACString& aTo) aTo += "filter"; first = false; } - if (effectProperties.GetMaskFrame(&isOK)) { + if (effectProperties.GetFirstMaskFrame()) { if (!first) { aTo += ", "; } diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index dc383f15e2db..97d98107822b 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -1559,11 +1559,11 @@ public: return nsRegion(); } /** - * If this returns true, then aColor is set to the uniform color - * @return true if the item is guaranteed to paint every pixel in its + * @return Some(nscolor) if the item is guaranteed to paint every pixel in its * bounds with the same (possibly translucent) color */ - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { return false; } + virtual mozilla::Maybe IsUniform(nsDisplayListBuilder* aBuilder) + { return mozilla::Nothing(); } /** * @return true if the contents of this item are rendered fixed relative * to the nearest viewport. @@ -2621,10 +2621,9 @@ public: return result; } - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override + virtual mozilla::Maybe IsUniform(nsDisplayListBuilder* aBuilder) override { - *aColor = mColor; - return true; + return mozilla::Some(mColor); } protected: @@ -2701,7 +2700,7 @@ public: nsRegion* aVisibleRegion) override; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) override; - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override; + virtual mozilla::Maybe IsUniform(nsDisplayListBuilder* aBuilder) override; /** * GetBounds() returns the background painting area. */ @@ -2797,7 +2796,7 @@ public: HitTestState* aState, nsTArray *aOutFrames) override; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) override; - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override; + virtual mozilla::Maybe IsUniform(nsDisplayListBuilder* aBuilder) override; virtual bool ProvidesFontSmoothingBackgroundColor(nscolor* aColor) override; /** @@ -2861,7 +2860,7 @@ public: virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) override; - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override; + virtual mozilla::Maybe IsUniform(nsDisplayListBuilder* aBuilder) override; virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState, nsTArray *aOutFrames) override; @@ -2922,10 +2921,9 @@ public: return GetBounds(aBuilder, aSnap); } - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override + virtual mozilla::Maybe IsUniform(nsDisplayListBuilder* aBuilder) override { - *aColor = NS_RGBA(0, 0, 0, 0); - return true; + return mozilla::Some(NS_RGBA(0, 0, 0, 0)); } virtual bool ClearsBackground() override @@ -3233,7 +3231,7 @@ public: virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) override; - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override; + virtual mozilla::Maybe IsUniform(nsDisplayListBuilder* aBuilder) override; virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion) override; @@ -3797,6 +3795,7 @@ public: *aSnap = false; return mEffectsBounds + ToReferenceFrame(); } + virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) override; virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion) override; virtual bool TryMerge(nsDisplayItem* aItem) override; @@ -3898,7 +3897,7 @@ public: */ nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, nsDisplayList *aList, const nsRect& aChildrenVisibleRect, - uint32_t aIndex = 0); + uint32_t aIndex = 0, bool aIsFullyVisible = false); nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, nsDisplayItem *aItem, const nsRect& aChildrenVisibleRect, uint32_t aIndex = 0); @@ -3933,7 +3932,7 @@ public: virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap) override; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder, bool* aSnap) override; - virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor) override; + virtual mozilla::Maybe IsUniform(nsDisplayListBuilder *aBuilder) override; virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerLayerParameters& aParameters) override; @@ -4116,17 +4115,6 @@ public: bool MayBeAnimated(nsDisplayListBuilder* aBuilder); - /** - * This will return if it's possible for this element to be prerendered. - * This should never return false if we're going to prerender. - */ - bool MaybePrerender() const { return mMaybePrerender; } - /** - * Check if this element will be prerendered. This must be done after the - * display list has been fully built. - */ - bool ShouldPrerender(nsDisplayListBuilder* aBuilder); - virtual void WriteDebugInfo(std::stringstream& aStream) override; // Force the layer created for this item not to extend 3D context. @@ -4211,9 +4199,6 @@ private: nsRect mBounds; // True for mBounds is valid. bool mHasBounds; - // We wont know if we pre-render until the layer building phase where we can - // check layers will-change budget. - bool mMaybePrerender; // Be forced not to extend 3D context. Since we don't create a // transform item, a container layer, for every frames in a // preserves3d context, the transform items of a child preserves3d @@ -4226,6 +4211,9 @@ private: bool mIsTransformSeparator; // True if mTransformPreserves3D have been initialized. bool mTransformPreserves3DInited; + // True if the entire untransformed area has been treated as + // visible during display list construction. + bool mIsFullyVisible; }; /* A display item that applies a perspective transformation to a single @@ -4268,9 +4256,9 @@ public: return mList.GetOpaqueRegion(aBuilder, aSnap); } - virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override + virtual mozilla::Maybe IsUniform(nsDisplayListBuilder* aBuilder) override { - return mList.IsUniform(aBuilder, aColor); + return mList.IsUniform(aBuilder); } virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index 83f285e6582c..49abbca32f53 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -134,7 +134,6 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, bool snap; nsRect rect = aItem->GetBounds(aBuilder, &snap); nsRect layerRect = rect - (*aItem->GetAnimatedGeometryRoot())->GetOffsetToCrossDoc(aItem->ReferenceFrame()); - nscolor color; nsRect vis = aItem->GetVisibleRect(); nsRect component = aItem->GetComponentAlphaBounds(aBuilder); nsDisplayList* list = aItem->GetChildren(); @@ -159,7 +158,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, component.x, component.y, component.width, component.height, clip.ToString().get(), DisplayItemScrollClip::ToString(aItem->ScrollClip()).get(), - aItem->IsUniform(aBuilder, &color) ? " uniform" : "", + aItem->IsUniform(aBuilder) ? " uniform" : "", aItem->ReferenceFrame(), aItem->GetAnimatedGeometryRoot()->mFrame); for (auto iter = opaque.RectIter(); !iter.Done(); iter.Next()) { diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index c9c345ad5c6c..6e711b0bc898 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1830,8 +1830,6 @@ nsresult PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight) { NS_PRECONDITION(!mIsReflowing, "Shouldn't be in reflow here!"); - NS_PRECONDITION(aWidth != NS_UNCONSTRAINEDSIZE, - "shouldn't use unconstrained widths anymore"); // If we don't have a root frame yet, that means we haven't had our initial // reflow... If that's the case, and aWidth or aHeight is unconstrained, @@ -1843,9 +1841,7 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight) return NS_ERROR_NOT_AVAILABLE; } - const bool isHeightChanging = - (mPresContext->GetVisibleArea().height != aHeight); - + nsSize oldVisibleSize = mPresContext->GetVisibleArea().Size(); mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight)); // There isn't anything useful we can do if the initial reflow hasn't happened. @@ -1853,6 +1849,14 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight) return NS_OK; } + WritingMode wm = rootFrame->GetWritingMode(); + NS_PRECONDITION((wm.IsVertical() ? aHeight : aWidth) != NS_UNCONSTRAINEDSIZE, + "shouldn't use unconstrained isize anymore"); + + const bool isBSizeChanging = wm.IsVertical() + ? oldVisibleSize.width != aWidth + : oldVisibleSize.height != aHeight; + RefPtr viewManagerDeathGrip = mViewManager; // Take this ref after viewManager so it'll make sure to go away first. nsCOMPtr kungFuDeathGrip(this); @@ -1873,7 +1877,7 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight) // XXX Do a full invalidate at the beginning so that invalidates along // the way don't have region accumulation issues? - if (isHeightChanging) { + if (isBSizeChanging) { // For BSize changes driven by style, RestyleManager handles this. // For height:auto BSizes (i.e. layout-controlled), descendant // intrinsic sizes can't depend on them. So the only other case is @@ -1898,9 +1902,19 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight) } rootFrame = mFrameConstructor->GetRootFrame(); - if (aHeight == NS_UNCONSTRAINEDSIZE && rootFrame) { - mPresContext->SetVisibleArea( - nsRect(0, 0, aWidth, rootFrame->GetRect().height)); + if (rootFrame) { + wm = rootFrame->GetWritingMode(); + if (wm.IsVertical()) { + if (aWidth == NS_UNCONSTRAINEDSIZE) { + mPresContext->SetVisibleArea( + nsRect(0, 0, rootFrame->GetRect().width, aHeight)); + } + } else { + if (aHeight == NS_UNCONSTRAINEDSIZE) { + mPresContext->SetVisibleArea( + nsRect(0, 0, aWidth, rootFrame->GetRect().height)); + } + } } if (!mIsDestroying && !mResizeEvent.IsPending() && @@ -9527,7 +9541,7 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible) bool hasUnconstrainedBSize = size.BSize(wm) == NS_UNCONSTRAINEDSIZE; if (hasUnconstrainedBSize || mLastRootReflowHadUnconstrainedBSize) { - reflowState.SetVResize(true); + reflowState.SetBResize(true); } mLastRootReflowHadUnconstrainedBSize = hasUnconstrainedBSize; diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 1f74c70fc5e9..6390844c6992 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -595,8 +595,8 @@ nsComboboxControlFrame::GetAvailableDropdownSpace(WritingMode aWM, containerSize); mLastDropDownAfterScreenBCoord = thisScreenRect.BEnd(aWM) + aTranslation->B(aWM); - mLastDropDownBeforeScreenBCoord = thisScreenRect.BEnd(aWM) + - aTranslation->B(aWM); + mLastDropDownBeforeScreenBCoord = thisScreenRect.BStart(aWM) + + aTranslation->B(aWM); } nscoord minBCoord; diff --git a/layout/forms/nsMeterFrame.cpp b/layout/forms/nsMeterFrame.cpp index 16ecf18e3b71..0827f54fc10b 100644 --- a/layout/forms/nsMeterFrame.cpp +++ b/layout/forms/nsMeterFrame.cpp @@ -281,7 +281,7 @@ nsMeterFrame::ShouldUseNativeStyle() const !PresContext()->HasAuthorSpecifiedRules(this, NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND) && barFrame && - barFrame->StyleDisplay()->mAppearance == NS_THEME_METERBAR_CHUNK && + barFrame->StyleDisplay()->mAppearance == NS_THEME_METERCHUNK && !PresContext()->HasAuthorSpecifiedRules(barFrame, NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND); } diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index d671edf58f71..d59a34ef2e0d 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -705,11 +705,11 @@ nsNumberControlFrame::ShouldUseNativeStyleForSpinner() const nsIFrame* spinDownFrame = mSpinDown->GetPrimaryFrame(); return spinUpFrame && - spinUpFrame->StyleDisplay()->mAppearance == NS_THEME_SPINNER_UP_BUTTON && + spinUpFrame->StyleDisplay()->mAppearance == NS_THEME_SPINNER_UPBUTTON && !PresContext()->HasAuthorSpecifiedRules(spinUpFrame, STYLES_DISABLING_NATIVE_THEMING) && spinDownFrame && - spinDownFrame->StyleDisplay()->mAppearance == NS_THEME_SPINNER_DOWN_BUTTON && + spinDownFrame->StyleDisplay()->mAppearance == NS_THEME_SPINNER_DOWNBUTTON && !PresContext()->HasAuthorSpecifiedRules(spinDownFrame, STYLES_DISABLING_NATIVE_THEMING); } diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp index 0ecb1d250ab9..c2909e49df14 100644 --- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -289,7 +289,7 @@ nsProgressFrame::ShouldUseNativeStyle() const !PresContext()->HasAuthorSpecifiedRules(this, NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND) && barFrame && - barFrame->StyleDisplay()->mAppearance == NS_THEME_PROGRESSBAR_CHUNK && + barFrame->StyleDisplay()->mAppearance == NS_THEME_PROGRESSCHUNK && !PresContext()->HasAuthorSpecifiedRules(barFrame, NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND); } diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index 864a5a2441c4..91a35605648d 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -264,13 +264,13 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame, const nsStyleBorder* borderStyle = aFrame->StyleBorder(); switch (borderStyle->mFloatEdge) { default: - case NS_STYLE_FLOAT_EDGE_CONTENT: // content and only content does runaround of floats + case NS_STYLE_FLOAT_EDGE_CONTENT_BOX: // content and only content does runaround of floats // The child block will flow around the float. Therefore // give it all of the available space. aResult.IStart(wm) = mContentArea.IStart(wm); aResult.ISize(wm) = mContentArea.ISize(wm); break; - case NS_STYLE_FLOAT_EDGE_MARGIN: + case NS_STYLE_FLOAT_EDGE_MARGIN_BOX: { // The child block's margins should be placed adjacent to, // but not overlap the float. @@ -719,8 +719,6 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat) // placement are for the float only, not for any non-floating // content. AutoRestore restoreBCoord(mBCoord); - // FIXME: Should give AutoRestore a getter for the value to avoid this. - const nscoord saveBCoord = mBCoord; // Grab the float's display information const nsStyleDisplay* floatDisplay = aFloat->StyleDisplay(); @@ -904,7 +902,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat) // Reflow the float after computing its vertical position so it knows // where to break. if (!earlyFloatReflow) { - bool pushedDown = mBCoord != saveBCoord; + bool pushedDown = mBCoord != restoreBCoord.SavedValue(); mBlock->ReflowFloat(*this, adjustedAvailableSpace, aFloat, floatMargin, floatOffsets, pushedDown, reflowStatus); } diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index dd018e03c92e..775e3ee1113a 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -624,7 +624,7 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext, kidReflowState(aPresContext, aReflowState, kidFrame, aReflowState.AvailableSize(kidFrame->GetWritingMode())); - if (aReflowState.IsBResize() && + if (aReflowState.IsBResizeForWM(kidReflowState.GetWritingMode()) && (kidFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE)) { // Tell our kid it's being block-dir resized too. Bit of a // hack for framesets. diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 09874ebd8770..639bf2d58add 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2513,8 +2513,12 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, if (!aBuilder->IsForGenerateGlyphMask() && !aBuilder->IsForPaintingSelectionBG()) { + bool isFullyVisible = + dirtyRectOutsideSVGEffects.Contains(GetVisualOverflowRectRelativeToSelf()); nsDisplayTransform *transformItem = - new (aBuilder) nsDisplayTransform(aBuilder, this, &resultList, dirtyRect); + new (aBuilder) nsDisplayTransform(aBuilder, this, + &resultList, dirtyRect, 0, + isFullyVisible); resultList.AppendNewToTop(transformItem); } @@ -9176,8 +9180,9 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState, AddStateBits(NS_FRAME_IS_DIRTY); } } - if (metrics->mLastSize.height != aHeight) + if (metrics->mLastSize.height != aHeight) { reflowState.SetVResize(true); + } #ifdef DEBUG_REFLOW nsAdaptorAddIndents(); diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 023eb463fd0d..a17349ca5e36 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -522,7 +522,7 @@ nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState* aState, kidReflowState.SetComputedBSize(computedBSize); kidReflowState.ComputedMinBSize() = computedMinBSize; kidReflowState.ComputedMaxBSize() = computedMaxBSize; - if (aState->mReflowState.IsBResize()) { + if (aState->mReflowState.IsBResizeForWM(kidReflowState.GetWritingMode())) { kidReflowState.SetBResize(true); } diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index 70b6529f0c3f..6cd8f936412f 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -329,7 +329,8 @@ nsHTMLReflowState::SetComputedWidth(nscoord aComputedWidth) if (ComputedWidth() != aComputedWidth) { ComputedWidth() = aComputedWidth; nsIAtom* frameType = frame->GetType(); - if (frameType != nsGkAtoms::viewportFrame) { // Or check GetParent()? + if (frameType != nsGkAtoms::viewportFrame || // Or check GetParent()? + mWritingMode.IsVertical()) { InitResizeFlags(frame->PresContext(), frameType); } } @@ -351,7 +352,10 @@ nsHTMLReflowState::SetComputedHeight(nscoord aComputedHeight) NS_PRECONDITION(aComputedHeight >= 0, "Invalid computed height"); if (ComputedHeight() != aComputedHeight) { ComputedHeight() = aComputedHeight; - InitResizeFlags(frame->PresContext(), frame->GetType()); + nsIAtom* frameType = frame->GetType(); + if (frameType != nsGkAtoms::viewportFrame || !mWritingMode.IsVertical()) { + InitResizeFlags(frame->PresContext(), frameType); + } } } @@ -641,7 +645,7 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT // as containing block for absolutely positioned elements? // Possibly; in that case we should at least be checking // NS_SUBTREE_DIRTY, I'd think. - SetBResize(mCBReflowState->IsBResize()); + SetBResize(mCBReflowState->IsBResizeForWM(wm)); } else if (mCBReflowState && !nsLayoutUtils::GetAsBlock(frame)) { // Some non-block frames (e.g. table frames) aggressively optimize out their // BSize recomputation when they don't have the BResize flag set. This @@ -661,14 +665,14 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT // Note that we _also_ need to set the BResize flag if we have auto // ComputedBSize() and a dirty subtree, since that might require us to // change BSize due to kids having been added or removed. - SetBResize(mCBReflowState->IsBResize()); + SetBResize(mCBReflowState->IsBResizeForWM(wm)); if (ComputedBSize() == NS_AUTOHEIGHT) { SetBResize(IsBResize() || NS_SUBTREE_DIRTY(frame)); } } else if (ComputedBSize() == NS_AUTOHEIGHT) { if (eCompatibility_NavQuirks == aPresContext->CompatibilityMode() && mCBReflowState) { - SetBResize(mCBReflowState->IsBResize()); + SetBResize(mCBReflowState->IsBResizeForWM(wm)); } else { SetBResize(IsIResize()); } diff --git a/layout/generic/nsHTMLReflowState.h b/layout/generic/nsHTMLReflowState.h index 9dbcdb5d57e3..efd5ed151d8e 100644 --- a/layout/generic/nsHTMLReflowState.h +++ b/layout/generic/nsHTMLReflowState.h @@ -558,13 +558,13 @@ public: uint16_t mAssumingVScrollbar:1; // parent frame is an nsIScrollableFrame and it // is assuming a vertical scrollbar - uint16_t mIsHResize:1; // Is frame (a) not dirty and (b) a - // different width than before? + uint16_t mIsIResize:1; // Is frame (a) not dirty and (b) a + // different inline-size than before? - uint16_t mIsVResize:1; // Is frame (a) not dirty and (b) a - // different height than before or + uint16_t mIsBResize:1; // Is frame (a) not dirty and (b) a + // different block-size than before or // (potentially) in a context where - // percent heights have a different + // percent block-sizes have a different // basis? uint16_t mTableIsSplittable:1; // tables are splittable, this should happen only inside a page // and never insider a column frame @@ -592,36 +592,40 @@ public: // via these accessors, so that in due course we can change the storage from // physical to logical. bool IsHResize() const { - return mFlags.mIsHResize; + return mWritingMode.IsVertical() ? mFlags.mIsBResize : mFlags.mIsIResize; } bool IsVResize() const { - return mFlags.mIsVResize; + return mWritingMode.IsVertical() ? mFlags.mIsIResize : mFlags.mIsBResize; } bool IsIResize() const { - return mWritingMode.IsVertical() ? mFlags.mIsVResize : mFlags.mIsHResize; + return mFlags.mIsIResize; } bool IsBResize() const { - return mWritingMode.IsVertical() ? mFlags.mIsHResize : mFlags.mIsVResize; + return mFlags.mIsBResize; + } + bool IsBResizeForWM(mozilla::WritingMode aWM) const { + return aWM.IsOrthogonalTo(mWritingMode) ? mFlags.mIsIResize + : mFlags.mIsBResize; } void SetHResize(bool aValue) { - mFlags.mIsHResize = aValue; + if (mWritingMode.IsVertical()) { + mFlags.mIsBResize = aValue; + } else { + mFlags.mIsIResize = aValue; + } } void SetVResize(bool aValue) { - mFlags.mIsVResize = aValue; + if (mWritingMode.IsVertical()) { + mFlags.mIsIResize = aValue; + } else { + mFlags.mIsBResize = aValue; + } } void SetIResize(bool aValue) { - if (mWritingMode.IsVertical()) { - mFlags.mIsVResize = aValue; - } else { - mFlags.mIsHResize = aValue; - } + mFlags.mIsIResize = aValue; } void SetBResize(bool aValue) { - if (mWritingMode.IsVertical()) { - mFlags.mIsHResize = aValue; - } else { - mFlags.mIsVResize = aValue; - } + mFlags.mIsBResize = aValue; } // Note: The copy constructor is written by the compiler automatically. You @@ -835,12 +839,12 @@ public: } } - void SetComputedHeightWithoutResettingResizeFlags(nscoord aComputedHeight) { - // Viewport frames reset the computed height on a copy of their reflow + void SetComputedBSizeWithoutResettingResizeFlags(nscoord aComputedBSize) { + // Viewport frames reset the computed block size on a copy of their reflow // state when reflowing fixed-pos kids. In that case we actually don't // want to mess with the resize flags, because comparing the frame's rect - // to the munged computed width is pointless. - ComputedHeight() = aComputedHeight; + // to the munged computed isize is pointless. + ComputedBSize() = aComputedBSize; } void SetTruncated(const nsHTMLReflowMetrics& aMetrics, nsReflowStatus* aStatus) const; diff --git a/layout/generic/nsViewportFrame.cpp b/layout/generic/nsViewportFrame.cpp index 5f2891736976..15b0760faf2f 100644 --- a/layout/generic/nsViewportFrame.cpp +++ b/layout/generic/nsViewportFrame.cpp @@ -230,13 +230,14 @@ ViewportFrame::AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) c nsIScrollableFrame* scrollingFrame = do_QueryFrame(kidFrame); if (scrollingFrame) { - nsMargin scrollbars = scrollingFrame->GetActualScrollbarSizes(); - aReflowState->SetComputedWidth(aReflowState->ComputedWidth() - - scrollbars.LeftRight()); - aReflowState->AvailableWidth() -= scrollbars.LeftRight(); - aReflowState->SetComputedHeightWithoutResettingResizeFlags( - aReflowState->ComputedHeight() - scrollbars.TopBottom()); - return nsPoint(scrollbars.left, scrollbars.top); + WritingMode wm = aReflowState->GetWritingMode(); + LogicalMargin scrollbars(wm, scrollingFrame->GetActualScrollbarSizes()); + aReflowState->SetComputedISize(aReflowState->ComputedISize() - + scrollbars.IStartEnd(wm)); + aReflowState->AvailableISize() -= scrollbars.IStartEnd(wm); + aReflowState->SetComputedBSizeWithoutResettingResizeFlags( + aReflowState->ComputedBSize() - scrollbars.BStartEnd(wm)); + return nsPoint(scrollbars.Left(wm), scrollbars.Top(wm)); } return nsPoint(0, 0); } @@ -298,7 +299,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext, // Deal with a non-incremental reflow or an incremental reflow // targeted at our one-and-only principal child frame. if (aReflowState.ShouldReflowAllKids() || - aReflowState.IsVResize() || + aReflowState.IsBResize() || NS_SUBTREE_DIRTY(mFrames.FirstChild())) { // Reflow our one-and-only principal child frame nsIFrame* kidFrame = mFrames.FirstChild(); diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp index 6f588647c66c..079b473b345d 100644 --- a/layout/mathml/nsMathMLChar.cpp +++ b/layout/mathml/nsMathMLChar.cpp @@ -1914,12 +1914,12 @@ void nsDisplayMathMLCharBackground::Paint(nsDisplayListBuilder* aBuilder, { const nsStyleBorder* border = mStyleContext->StyleBorder(); nsRect rect(mRect + ToReferenceFrame()); - + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForAllLayers(*mFrame->PresContext(), *aCtx, + mVisibleRect, rect, mFrame, + aBuilder->GetBackgroundPaintFlags()); DrawResult result = - nsCSSRendering::PaintBackgroundWithSC(mFrame->PresContext(), *aCtx, mFrame, - mVisibleRect, rect, - mStyleContext, *border, - aBuilder->GetBackgroundPaintFlags()); + nsCSSRendering::PaintBackgroundWithSC(params, mStyleContext, *border); nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result); } diff --git a/layout/reftests/bugs/1272997-1-ref.html b/layout/reftests/bugs/1272997-1-ref.html new file mode 100644 index 000000000000..1465dbf1f7d6 --- /dev/null +++ b/layout/reftests/bugs/1272997-1-ref.html @@ -0,0 +1,15 @@ + + + + + + diff --git a/layout/reftests/bugs/1272997-1.html b/layout/reftests/bugs/1272997-1.html new file mode 100644 index 000000000000..fee818bccc45 --- /dev/null +++ b/layout/reftests/bugs/1272997-1.html @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 7907b6f6f29d..e4b6c886128f 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1951,3 +1951,4 @@ fuzzy(100,2000) == 1239564.html 1239564-ref.html == 1242172-2.html 1242172-2-ref.html == 1263845.html 1263845-ref.html == 1260543-1.html 1260543-1-ref.html +== 1272997-1.html 1272997-1-ref.html diff --git a/layout/reftests/fonts/MiaoUnicode-Regular.ttf b/layout/reftests/fonts/MiaoUnicode-Regular.ttf new file mode 100644 index 000000000000..f8e81f9cf55f Binary files /dev/null and b/layout/reftests/fonts/MiaoUnicode-Regular.ttf differ diff --git a/layout/reftests/text/graphite-surrogate-selection-ref.html b/layout/reftests/text/graphite-surrogate-selection-ref.html new file mode 100644 index 000000000000..5d2c88cb7255 --- /dev/null +++ b/layout/reftests/text/graphite-surrogate-selection-ref.html @@ -0,0 +1,23 @@ + + + +Bug 1260825 reference + + + + +All lines should show the same single glyph & background area: +
+𖽐
+𖽐
+𖽐
+𖽐
+𖽐
+
+ + diff --git a/layout/reftests/text/graphite-surrogate-selection.html b/layout/reftests/text/graphite-surrogate-selection.html new file mode 100644 index 000000000000..f086b3fa4fce --- /dev/null +++ b/layout/reftests/text/graphite-surrogate-selection.html @@ -0,0 +1,23 @@ + + + +Bug 1260825 testcase + + + + +All lines should show the same single glyph & background area: +
+𖽐
+𖽐𖽐
+𖽐𖽐𖽐
+𖽐𖼊
+𖽐𖼊𖽪
+
+ + diff --git a/layout/reftests/text/reftest.list b/layout/reftests/text/reftest.list index 9155d9f7b7c6..1a085f5ca738 100644 --- a/layout/reftests/text/reftest.list +++ b/layout/reftests/text/reftest.list @@ -228,6 +228,8 @@ pref(gfx.font_rendering.graphite.enabled,true) HTTP(..) == glyph-decomposition-g # test for bidi bug in graphite 1.3.2, fixed in 1.3.3 (bug 1207061) HTTP(..) == graphite-bidi-1.html graphite-bidi-1-ref.html +HTTP(..) == graphite-surrogate-selection.html graphite-surrogate-selection-ref.html + # Tests for hyphenation with hyphens property == auto-hyphenation-1.html auto-hyphenation-1-ref.html != auto-hyphenation-1.html auto-hyphenation-1-notref.html diff --git a/layout/reftests/w3c-css/submitted/masking/mask-image-3-ref.html b/layout/reftests/w3c-css/submitted/masking/mask-image-3-ref.html new file mode 100644 index 000000000000..660a7ef4ad27 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/masking/mask-image-3-ref.html @@ -0,0 +1,28 @@ + + + + + CSS Masking: mask-image: multiple SVG masks + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/w3c-css/submitted/masking/mask-image-3a.html b/layout/reftests/w3c-css/submitted/masking/mask-image-3a.html new file mode 100644 index 000000000000..3da2528fec9d --- /dev/null +++ b/layout/reftests/w3c-css/submitted/masking/mask-image-3a.html @@ -0,0 +1,30 @@ + + + + + CSS Masking: mask-image: multiple SVG masks + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/w3c-css/submitted/masking/mask-image-3b.html b/layout/reftests/w3c-css/submitted/masking/mask-image-3b.html new file mode 100644 index 000000000000..9f05b9509bf0 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/masking/mask-image-3b.html @@ -0,0 +1,28 @@ + + + + + CSS Masking: mask-image: interleave SVG mask with image mask + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/w3c-css/submitted/masking/mask-image-3c.html b/layout/reftests/w3c-css/submitted/masking/mask-image-3c.html new file mode 100644 index 000000000000..aefeececb102 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/masking/mask-image-3c.html @@ -0,0 +1,28 @@ + + + + + CSS Masking: mask-image: interleave SVG mask with image mask + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/w3c-css/submitted/masking/mask-image-3d.html b/layout/reftests/w3c-css/submitted/masking/mask-image-3d.html new file mode 100644 index 000000000000..49cf469e1bde --- /dev/null +++ b/layout/reftests/w3c-css/submitted/masking/mask-image-3d.html @@ -0,0 +1,28 @@ + + + + + CSS Masking: mask-image: interleave SVG mask with image mask + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/w3c-css/submitted/masking/mask-image-3e.html b/layout/reftests/w3c-css/submitted/masking/mask-image-3e.html new file mode 100644 index 000000000000..8ee75c63fbc3 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/masking/mask-image-3e.html @@ -0,0 +1,38 @@ + + + + + CSS Masking: mask-image: interleave SVG mask with image mask + + + + + + + + + + + +
+
+
+ + diff --git a/layout/reftests/w3c-css/submitted/masking/reftest.list b/layout/reftests/w3c-css/submitted/masking/reftest.list index aec678bc100d..23b6bbf664f6 100644 --- a/layout/reftests/w3c-css/submitted/masking/reftest.list +++ b/layout/reftests/w3c-css/submitted/masking/reftest.list @@ -17,6 +17,11 @@ fails == mask-image-1a.html mask-image-1-ref.html fails == mask-image-1b.html mask-image-1-ref.html fails == mask-image-1c.html mask-image-1-ref.html fails == mask-image-2.html mask-image-2-ref.html +fails == mask-image-3a.html mask-image-3-ref.html +fails == mask-image-3b.html mask-image-3-ref.html +fails == mask-image-3c.html mask-image-3-ref.html +fails == mask-image-3d.html mask-image-3-ref.html +fails == mask-image-3e.html mask-image-3-ref.html # mask-clip test cases fails == mask-clip-1.html mask-clip-1-ref.html diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index 593bab372c62..26241fe62671 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -139,6 +139,19 @@ Gecko_IsRootElement(RawGeckoElement* aElement) return aElement->OwnerDoc()->GetRootElement() == aElement; } +nsIAtom* +Gecko_LocalName(RawGeckoElement* aElement) +{ + return aElement->NodeInfo()->NameAtom(); +} + +nsIAtom* +Gecko_Namespace(RawGeckoElement* aElement) +{ + int32_t id = aElement->NodeInfo()->NamespaceID(); + return nsContentUtils::NameSpaceManager()->NameSpaceURIAtom(id); +} + ServoNodeData* Gecko_GetNodeData(RawGeckoNode* aNode) { @@ -151,6 +164,70 @@ Gecko_SetNodeData(RawGeckoNode* aNode, ServoNodeData* aData) aNode->SetServoNodeData(aData); } +nsIAtom* +Gecko_Atomize(const char* aString, uint32_t aLength) +{ + // XXXbholley: This isn't yet threadsafe, but will probably need to be. + MOZ_ASSERT(NS_IsMainThread()); + return NS_Atomize(nsDependentCSubstring(aString, aLength)).take(); +} + +void +Gecko_AddRefAtom(nsIAtom* aAtom) +{ + // XXXbholley: This isn't yet threadsafe, but will probably need to be. + MOZ_ASSERT(NS_IsMainThread()); + NS_ADDREF(aAtom); +} + +void +Gecko_ReleaseAtom(nsIAtom* aAtom) +{ + // XXXbholley: This isn't yet threadsafe, but will probably need to be. + MOZ_ASSERT(NS_IsMainThread()); + NS_RELEASE(aAtom); +} + +uint32_t +Gecko_HashAtom(nsIAtom* aAtom) +{ + return aAtom->hash(); +} + +const uint16_t* +Gecko_GetAtomAsUTF16(nsIAtom* aAtom, uint32_t* aLength) +{ + static_assert(sizeof(char16_t) == sizeof(uint16_t), "Servo doesn't know what a char16_t is"); + MOZ_ASSERT(aAtom); + *aLength = aAtom->GetLength(); + + // We need to manually cast from char16ptr_t to const char16_t* to handle the + // MOZ_USE_CHAR16_WRAPPER we use on WIndows. + return reinterpret_cast(static_cast(aAtom->GetUTF16String())); +} + +bool +Gecko_AtomEqualsUTF8(nsIAtom* aAtom, const char* aString, uint32_t aLength) +{ + // XXXbholley: We should be able to do this without converting, I just can't + // find the right thing to call. + nsAutoString atomStr; + aAtom->ToString(atomStr); + NS_ConvertUTF8toUTF16 inStr(nsDependentCSubstring(aString, aLength)); + return atomStr.Equals(inStr); +} + +bool +Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* aAtom, const char* aString, uint32_t aLength) +{ + // XXXbholley: We should be able to do this without converting, I just can't + // find the right thing to call. + nsAutoString atomStr; + aAtom->ToString(atomStr); + NS_ConvertUTF8toUTF16 inStr(nsDependentCSubstring(aString, aLength)); + return nsContentUtils::EqualsIgnoreASCIICase(atomStr, inStr); +} + void Gecko_SetListStyleType(nsStyleList* style_struct, uint32_t type) { diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index 601dde52f4ad..c58631f5c557 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -56,12 +56,23 @@ bool Gecko_IsTextNode(RawGeckoNode* node); bool Gecko_IsVisitedLink(RawGeckoElement* element); bool Gecko_IsUnvisitedLink(RawGeckoElement* element); bool Gecko_IsRootElement(RawGeckoElement* element); +nsIAtom* Gecko_LocalName(RawGeckoElement* element); +nsIAtom* Gecko_Namespace(RawGeckoElement* element); // Node data. ServoNodeData* Gecko_GetNodeData(RawGeckoNode* node); void Gecko_SetNodeData(RawGeckoNode* node, ServoNodeData* data); void Servo_DropNodeData(ServoNodeData* data); +// Atoms. +nsIAtom* Gecko_Atomize(const char* aString, uint32_t aLength); +void Gecko_AddRefAtom(nsIAtom* aAtom); +void Gecko_ReleaseAtom(nsIAtom* aAtom); +uint32_t Gecko_HashAtom(nsIAtom* aAtom); +const uint16_t* Gecko_GetAtomAsUTF16(nsIAtom* aAtom, uint32_t* aLength); +bool Gecko_AtomEqualsUTF8(nsIAtom* aAtom, const char* aString, uint32_t aLength); +bool Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* aAtom, const char* aString, uint32_t aLength); + // Counter style. struct nsStyleList; void Gecko_SetListStyleType(nsStyleList* style_struct, uint32_t type); diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index acb796ef6390..46390431a2f8 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -754,76 +754,76 @@ const KTableEntry nsCSSProps::kAppearanceKTable[] = { { eCSSKeyword_button_bevel, NS_THEME_BUTTON_BEVEL }, { eCSSKeyword_toolbox, NS_THEME_TOOLBOX }, { eCSSKeyword_toolbar, NS_THEME_TOOLBAR }, - { eCSSKeyword_toolbarbutton, NS_THEME_TOOLBAR_BUTTON }, - { eCSSKeyword_toolbargripper, NS_THEME_TOOLBAR_GRIPPER }, - { eCSSKeyword_dualbutton, NS_THEME_TOOLBAR_DUAL_BUTTON }, - { eCSSKeyword_toolbarbutton_dropdown, NS_THEME_TOOLBAR_BUTTON_DROPDOWN }, + { eCSSKeyword_toolbarbutton, NS_THEME_TOOLBARBUTTON }, + { eCSSKeyword_toolbargripper, NS_THEME_TOOLBARGRIPPER }, + { eCSSKeyword_dualbutton, NS_THEME_DUALBUTTON }, + { eCSSKeyword_toolbarbutton_dropdown, NS_THEME_TOOLBARBUTTON_DROPDOWN }, { eCSSKeyword_button_arrow_up, NS_THEME_BUTTON_ARROW_UP }, { eCSSKeyword_button_arrow_down, NS_THEME_BUTTON_ARROW_DOWN }, { eCSSKeyword_button_arrow_next, NS_THEME_BUTTON_ARROW_NEXT }, { eCSSKeyword_button_arrow_previous, NS_THEME_BUTTON_ARROW_PREVIOUS }, { eCSSKeyword_meterbar, NS_THEME_METERBAR }, - { eCSSKeyword_meterchunk, NS_THEME_METERBAR_CHUNK }, + { eCSSKeyword_meterchunk, NS_THEME_METERCHUNK }, { eCSSKeyword_number_input, NS_THEME_NUMBER_INPUT }, - { eCSSKeyword_separator, NS_THEME_TOOLBAR_SEPARATOR }, + { eCSSKeyword_separator, NS_THEME_SEPARATOR }, { eCSSKeyword_splitter, NS_THEME_SPLITTER }, { eCSSKeyword_statusbar, NS_THEME_STATUSBAR }, - { eCSSKeyword_statusbarpanel, NS_THEME_STATUSBAR_PANEL }, - { eCSSKeyword_resizerpanel, NS_THEME_STATUSBAR_RESIZER_PANEL }, + { eCSSKeyword_statusbarpanel, NS_THEME_STATUSBARPANEL }, + { eCSSKeyword_resizerpanel, NS_THEME_RESIZER_PANEL }, { eCSSKeyword_resizer, NS_THEME_RESIZER }, { eCSSKeyword_listbox, NS_THEME_LISTBOX }, - { eCSSKeyword_listitem, NS_THEME_LISTBOX_LISTITEM }, + { eCSSKeyword_listitem, NS_THEME_LISTITEM }, { eCSSKeyword_treeview, NS_THEME_TREEVIEW }, - { eCSSKeyword_treeitem, NS_THEME_TREEVIEW_TREEITEM }, - { eCSSKeyword_treetwisty, NS_THEME_TREEVIEW_TWISTY }, - { eCSSKeyword_treetwistyopen, NS_THEME_TREEVIEW_TWISTY_OPEN }, - { eCSSKeyword_treeline, NS_THEME_TREEVIEW_LINE }, - { eCSSKeyword_treeheader, NS_THEME_TREEVIEW_HEADER }, - { eCSSKeyword_treeheadercell, NS_THEME_TREEVIEW_HEADER_CELL }, - { eCSSKeyword_treeheadersortarrow, NS_THEME_TREEVIEW_HEADER_SORTARROW }, + { eCSSKeyword_treeitem, NS_THEME_TREEITEM }, + { eCSSKeyword_treetwisty, NS_THEME_TREETWISTY }, + { eCSSKeyword_treetwistyopen, NS_THEME_TREETWISTYOPEN }, + { eCSSKeyword_treeline, NS_THEME_TREELINE }, + { eCSSKeyword_treeheader, NS_THEME_TREEHEADER }, + { eCSSKeyword_treeheadercell, NS_THEME_TREEHEADERCELL }, + { eCSSKeyword_treeheadersortarrow, NS_THEME_TREEHEADERSORTARROW }, { eCSSKeyword_progressbar, NS_THEME_PROGRESSBAR }, - { eCSSKeyword_progresschunk, NS_THEME_PROGRESSBAR_CHUNK }, + { eCSSKeyword_progresschunk, NS_THEME_PROGRESSCHUNK }, { eCSSKeyword_progressbar_vertical, NS_THEME_PROGRESSBAR_VERTICAL }, - { eCSSKeyword_progresschunk_vertical, NS_THEME_PROGRESSBAR_CHUNK_VERTICAL }, + { eCSSKeyword_progresschunk_vertical, NS_THEME_PROGRESSCHUNK_VERTICAL }, { eCSSKeyword_tab, NS_THEME_TAB }, - { eCSSKeyword_tabpanels, NS_THEME_TAB_PANELS }, - { eCSSKeyword_tabpanel, NS_THEME_TAB_PANEL }, - { eCSSKeyword_tab_scroll_arrow_back, NS_THEME_TAB_SCROLLARROW_BACK }, - { eCSSKeyword_tab_scroll_arrow_forward, NS_THEME_TAB_SCROLLARROW_FORWARD }, + { eCSSKeyword_tabpanels, NS_THEME_TABPANELS }, + { eCSSKeyword_tabpanel, NS_THEME_TABPANEL }, + { eCSSKeyword_tab_scroll_arrow_back, NS_THEME_TAB_SCROLL_ARROW_BACK }, + { eCSSKeyword_tab_scroll_arrow_forward, NS_THEME_TAB_SCROLL_ARROW_FORWARD }, { eCSSKeyword_tooltip, NS_THEME_TOOLTIP }, { eCSSKeyword_spinner, NS_THEME_SPINNER }, - { eCSSKeyword_spinner_upbutton, NS_THEME_SPINNER_UP_BUTTON }, - { eCSSKeyword_spinner_downbutton, NS_THEME_SPINNER_DOWN_BUTTON }, + { eCSSKeyword_spinner_upbutton, NS_THEME_SPINNER_UPBUTTON }, + { eCSSKeyword_spinner_downbutton, NS_THEME_SPINNER_DOWNBUTTON }, { eCSSKeyword_spinner_textfield, NS_THEME_SPINNER_TEXTFIELD }, { eCSSKeyword_scrollbar, NS_THEME_SCROLLBAR }, { eCSSKeyword_scrollbar_small, NS_THEME_SCROLLBAR_SMALL }, { eCSSKeyword_scrollbar_horizontal, NS_THEME_SCROLLBAR_HORIZONTAL }, { eCSSKeyword_scrollbar_vertical, NS_THEME_SCROLLBAR_VERTICAL }, - { eCSSKeyword_scrollbarbutton_up, NS_THEME_SCROLLBAR_BUTTON_UP }, - { eCSSKeyword_scrollbarbutton_down, NS_THEME_SCROLLBAR_BUTTON_DOWN }, - { eCSSKeyword_scrollbarbutton_left, NS_THEME_SCROLLBAR_BUTTON_LEFT }, - { eCSSKeyword_scrollbarbutton_right, NS_THEME_SCROLLBAR_BUTTON_RIGHT }, - { eCSSKeyword_scrollbartrack_horizontal, NS_THEME_SCROLLBAR_TRACK_HORIZONTAL }, - { eCSSKeyword_scrollbartrack_vertical, NS_THEME_SCROLLBAR_TRACK_VERTICAL }, - { eCSSKeyword_scrollbarthumb_horizontal, NS_THEME_SCROLLBAR_THUMB_HORIZONTAL }, - { eCSSKeyword_scrollbarthumb_vertical, NS_THEME_SCROLLBAR_THUMB_VERTICAL }, + { eCSSKeyword_scrollbarbutton_up, NS_THEME_SCROLLBARBUTTON_UP }, + { eCSSKeyword_scrollbarbutton_down, NS_THEME_SCROLLBARBUTTON_DOWN }, + { eCSSKeyword_scrollbarbutton_left, NS_THEME_SCROLLBARBUTTON_LEFT }, + { eCSSKeyword_scrollbarbutton_right, NS_THEME_SCROLLBARBUTTON_RIGHT }, + { eCSSKeyword_scrollbartrack_horizontal, NS_THEME_SCROLLBARTRACK_HORIZONTAL }, + { eCSSKeyword_scrollbartrack_vertical, NS_THEME_SCROLLBARTRACK_VERTICAL }, + { eCSSKeyword_scrollbarthumb_horizontal, NS_THEME_SCROLLBARTHUMB_HORIZONTAL }, + { eCSSKeyword_scrollbarthumb_vertical, NS_THEME_SCROLLBARTHUMB_VERTICAL }, { eCSSKeyword_textfield, NS_THEME_TEXTFIELD }, { eCSSKeyword_textfield_multiline, NS_THEME_TEXTFIELD_MULTILINE }, { eCSSKeyword_caret, NS_THEME_TEXTFIELD_CARET }, { eCSSKeyword_searchfield, NS_THEME_SEARCHFIELD }, - { eCSSKeyword_menulist, NS_THEME_DROPDOWN }, - { eCSSKeyword_menulist_button, NS_THEME_DROPDOWN_BUTTON }, - { eCSSKeyword_menulist_text, NS_THEME_DROPDOWN_TEXT }, - { eCSSKeyword_menulist_textfield, NS_THEME_DROPDOWN_TEXTFIELD }, + { eCSSKeyword_menulist, NS_THEME_MENULIST }, + { eCSSKeyword_menulist_button, NS_THEME_MENULIST_BUTTON }, + { eCSSKeyword_menulist_text, NS_THEME_MENULIST_TEXT }, + { eCSSKeyword_menulist_textfield, NS_THEME_MENULIST_TEXTFIELD }, { eCSSKeyword_range, NS_THEME_RANGE }, { eCSSKeyword_range_thumb, NS_THEME_RANGE_THUMB }, { eCSSKeyword_scale_horizontal, NS_THEME_SCALE_HORIZONTAL }, { eCSSKeyword_scale_vertical, NS_THEME_SCALE_VERTICAL }, - { eCSSKeyword_scalethumb_horizontal, NS_THEME_SCALE_THUMB_HORIZONTAL }, - { eCSSKeyword_scalethumb_vertical, NS_THEME_SCALE_THUMB_VERTICAL }, - { eCSSKeyword_scalethumbstart, NS_THEME_SCALE_THUMB_START }, - { eCSSKeyword_scalethumbend, NS_THEME_SCALE_THUMB_END }, - { eCSSKeyword_scalethumbtick, NS_THEME_SCALE_TICK }, + { eCSSKeyword_scalethumb_horizontal, NS_THEME_SCALETHUMB_HORIZONTAL }, + { eCSSKeyword_scalethumb_vertical, NS_THEME_SCALETHUMB_VERTICAL }, + { eCSSKeyword_scalethumbstart, NS_THEME_SCALETHUMBSTART }, + { eCSSKeyword_scalethumbend, NS_THEME_SCALETHUMBEND }, + { eCSSKeyword_scalethumbtick, NS_THEME_SCALETHUMBTICK }, { eCSSKeyword_groupbox, NS_THEME_GROUPBOX }, { eCSSKeyword_checkbox_container, NS_THEME_CHECKBOX_CONTAINER }, { eCSSKeyword_radio_container, NS_THEME_RADIO_CONTAINER }, @@ -845,11 +845,11 @@ const KTableEntry nsCSSProps::kAppearanceKTable[] = { { eCSSKeyword_menuitemtext, NS_THEME_MENUITEMTEXT }, { eCSSKeyword__moz_win_media_toolbox, NS_THEME_WIN_MEDIA_TOOLBOX }, { eCSSKeyword__moz_win_communications_toolbox, NS_THEME_WIN_COMMUNICATIONS_TOOLBOX }, - { eCSSKeyword__moz_win_browsertabbar_toolbox, NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX }, + { eCSSKeyword__moz_win_browsertabbar_toolbox, NS_THEME_WIN_BROWSERTABBAR_TOOLBOX }, { eCSSKeyword__moz_win_glass, NS_THEME_WIN_GLASS }, { eCSSKeyword__moz_win_borderless_glass, NS_THEME_WIN_BORDERLESS_GLASS }, - { eCSSKeyword__moz_mac_fullscreen_button, NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON }, - { eCSSKeyword__moz_mac_help_button, NS_THEME_MOZ_MAC_HELP_BUTTON }, + { eCSSKeyword__moz_mac_fullscreen_button, NS_THEME_MAC_FULLSCREEN_BUTTON }, + { eCSSKeyword__moz_mac_help_button, NS_THEME_MAC_HELP_BUTTON }, { eCSSKeyword__moz_window_titlebar, NS_THEME_WINDOW_TITLEBAR }, { eCSSKeyword__moz_window_titlebar_maximized, NS_THEME_WINDOW_TITLEBAR_MAXIMIZED }, { eCSSKeyword__moz_window_frame_left, NS_THEME_WINDOW_FRAME_LEFT }, @@ -1486,8 +1486,8 @@ KTableEntry nsCSSProps::kFloatKTable[] = { }; const KTableEntry nsCSSProps::kFloatEdgeKTable[] = { - { eCSSKeyword_content_box, NS_STYLE_FLOAT_EDGE_CONTENT }, - { eCSSKeyword_margin_box, NS_STYLE_FLOAT_EDGE_MARGIN }, + { eCSSKeyword_content_box, NS_STYLE_FLOAT_EDGE_CONTENT_BOX }, + { eCSSKeyword_margin_box, NS_STYLE_FLOAT_EDGE_MARGIN_BOX }, { eCSSKeyword_UNKNOWN, -1 } }; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 779d1b8782ba..c90d15e05250 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -7518,7 +7518,7 @@ nsRuleNode::ComputeBorderData(void* aStartStruct, border->mFloatEdge, conditions, SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, parentBorder->mFloatEdge, - NS_STYLE_FLOAT_EDGE_CONTENT, 0, 0, 0, 0); + NS_STYLE_FLOAT_EDGE_CONTENT_BOX, 0, 0, 0, 0); // border-image-source const nsCSSValue* borderImageSource = aRuleData->ValueForBorderImageSource(); diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index e54a68b042d3..93661d4d3546 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -82,8 +82,8 @@ enum class StyleBoxSizing : uint8_t { #define NS_STYLE_BOX_SHADOW_INSET 0 // float-edge -#define NS_STYLE_FLOAT_EDGE_CONTENT 0 -#define NS_STYLE_FLOAT_EDGE_MARGIN 1 +#define NS_STYLE_FLOAT_EDGE_CONTENT_BOX 0 +#define NS_STYLE_FLOAT_EDGE_MARGIN_BOX 1 // user-focus #define NS_STYLE_USER_FOCUS_NONE 0 diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 6266a9796ca6..29b2c61209f3 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -328,7 +328,7 @@ nsStyleBorder::nsStyleBorder(StyleStructContext aContext) mBorderImageFill(NS_STYLE_BORDER_IMAGE_SLICE_NOFILL), mBorderImageRepeatH(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH), mBorderImageRepeatV(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH), - mFloatEdge(NS_STYLE_FLOAT_EDGE_CONTENT), + mFloatEdge(NS_STYLE_FLOAT_EDGE_CONTENT_BOX), mBoxDecorationBreak(NS_STYLE_BOX_DECORATION_BREAK_SLICE), mComputedBorder(0, 0, 0, 0) { diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index f7f7df44d368..eb46cbdb42a5 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -4176,8 +4176,8 @@ SVGTextFrame::GetSubStringLength(nsIContent* aContent, // Find each rendered run that intersects with the range defined // by charnum/nchars. nscoord textLength = 0; - TextRenderedRunIterator it(this, TextRenderedRunIterator::eAllFrames); - TextRenderedRun run = it.Current(); + TextRenderedRunIterator runIter(this, TextRenderedRunIterator::eAllFrames); + TextRenderedRun run = runIter.Current(); while (run.mFrame) { // If this rendered run is past the substring we are interested in, we // are done. @@ -4195,16 +4195,16 @@ SVGTextFrame::GetSubStringLength(nsIContent* aContent, // Convert offset into an index into the frame. offset += run.mTextFrameContentOffset - run.mTextElementCharIndex; - gfxSkipCharsIterator it = + gfxSkipCharsIterator skipCharsIter = run.mFrame->EnsureTextRun(nsTextFrame::eInflated); gfxTextRun* textRun = run.mFrame->GetTextRun(nsTextFrame::eInflated); - Range range = ConvertOriginalToSkipped(it, offset, length); + Range range = ConvertOriginalToSkipped(skipCharsIter, offset, length); // Accumulate the advance. textLength += textRun->GetAdvanceWidth(range, nullptr); } - run = it.Next(); + run = runIter.Next(); } nsPresContext* presContext = PresContext(); @@ -5720,4 +5720,3 @@ SVGTextFrame::TransformFrameRectFromTextChild(const nsRect& aRect, return result - framePosition; } - diff --git a/layout/svg/moz.build b/layout/svg/moz.build index 69b088289cc2..ae58b0a62088 100644 --- a/layout/svg/moz.build +++ b/layout/svg/moz.build @@ -69,6 +69,3 @@ LOCAL_INCLUDES += [ RESOURCE_FILES += [ 'svg.css', ] - -if CONFIG['GNU_CXX']: - CXXFLAGS += ['-Wno-error=shadow'] diff --git a/layout/svg/nsSVGClipPathFrame.cpp b/layout/svg/nsSVGClipPathFrame.cpp index 0f4d34843b3e..227ff37040bb 100644 --- a/layout/svg/nsSVGClipPathFrame.cpp +++ b/layout/svg/nsSVGClipPathFrame.cpp @@ -380,25 +380,27 @@ nsSVGClipPathFrame::IsValid() for (nsIFrame* kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) { - nsIAtom *type = kid->GetType(); + nsIAtom* kidType = kid->GetType(); - if (type == nsGkAtoms::svgUseFrame) { + if (kidType == nsGkAtoms::svgUseFrame) { for (nsIFrame* grandKid : kid->PrincipalChildList()) { - nsIAtom *type = grandKid->GetType(); + nsIAtom* grandKidType = grandKid->GetType(); - if (type != nsGkAtoms::svgPathGeometryFrame && - type != nsGkAtoms::svgTextFrame) { + if (grandKidType != nsGkAtoms::svgPathGeometryFrame && + grandKidType != nsGkAtoms::svgTextFrame) { return false; } } continue; } - if (type != nsGkAtoms::svgPathGeometryFrame && - type != nsGkAtoms::svgTextFrame) { + + if (kidType != nsGkAtoms::svgPathGeometryFrame && + kidType != nsGkAtoms::svgTextFrame) { return false; } } + return true; } diff --git a/layout/svg/nsSVGEffects.cpp b/layout/svg/nsSVGEffects.cpp index d86d5833bc72..def09740d484 100644 --- a/layout/svg/nsSVGEffects.cpp +++ b/layout/svg/nsSVGEffects.cpp @@ -364,6 +364,20 @@ nsSVGMarkerProperty::DoUpdate() frame->GetContent()->AsElement(), nsRestyleHint(0), changeHint); } +NS_IMPL_ISUPPORTS(nsSVGMaskProperty, nsISupports) + +nsSVGMaskProperty::nsSVGMaskProperty(nsIFrame* aFrame) +{ + const nsStyleSVGReset *svgReset = aFrame->StyleSVGReset(); + + for (uint32_t i = 0; i < svgReset->mMask.mImageCount; i++) { + nsSVGPaintingProperty* prop = + new nsSVGPaintingProperty(svgReset->mMask.mLayers[i].mSourceURI, aFrame, + false); + mProperties.AppendElement(prop); + } +} + bool nsSVGTextPathProperty::TargetIsValid() { @@ -461,8 +475,6 @@ GetEffectProperty(nsIURI *aURI, nsIFrame *aFrame, if (prop) return prop; prop = aCreate(aURI, aFrame, false); - if (!prop) - return nullptr; NS_ADDREF(prop); props.Set(aProperty, static_cast(prop)); return prop; @@ -480,13 +492,25 @@ GetOrCreateFilterProperty(nsIFrame *aFrame) if (prop) return prop; prop = new nsSVGFilterProperty(effects->mFilters, aFrame); - if (!prop) - return nullptr; NS_ADDREF(prop); props.Set(nsSVGEffects::FilterProperty(), prop); return prop; } +static nsSVGMaskProperty* +GetOrCreateMaskProperty(nsIFrame *aFrame) +{ + FrameProperties props = aFrame->Properties(); + nsSVGMaskProperty *prop = props.Get(nsSVGEffects::MaskProperty()); + if (prop) + return prop; + + prop = new nsSVGMaskProperty(aFrame); + NS_ADDREF(prop); + props.Set(nsSVGEffects::MaskProperty(), prop); + return prop; +} + nsSVGMarkerProperty * nsSVGEffects::GetMarkerProperty(nsIURI *aURI, nsIFrame *aFrame, ObserverPropertyDescriptor aProp) @@ -553,7 +577,9 @@ nsSVGEffects::GetEffectProperties(nsIFrame *aFrame) EffectProperties result; const nsStyleSVGReset *style = aFrame->StyleSVGReset(); + result.mFilter = GetOrCreateFilterProperty(aFrame); + if (style->mClipPath.GetType() == NS_STYLE_CLIP_PATH_URL) { result.mClipPath = GetPaintingProperty(style->mClipPath.GetURL(), aFrame, ClipPathProperty()); @@ -561,12 +587,9 @@ nsSVGEffects::GetEffectProperties(nsIFrame *aFrame) result.mClipPath = nullptr; } - // FIXME: Bug 1228280. - // Before fixing bug 1228280, we support only single svg mask as before. MOZ_ASSERT(style->mMask.mImageCount > 0); - nsCOMPtr uri = style->mMask.mLayers[0].mSourceURI; - result.mMask = uri ? GetPaintingProperty(uri, aFrame, MaskProperty()) : - nullptr; + result.mMask = style->mMask.HasLayerWithImage() + ? GetOrCreateMaskProperty(aFrame) : nullptr; return result; } @@ -621,12 +644,39 @@ nsSVGEffects::EffectProperties::GetClipPathFrame(bool *aOK) } nsSVGMaskFrame * -nsSVGEffects::EffectProperties::GetMaskFrame(bool *aOK) +nsSVGEffects::EffectProperties::GetFirstMaskFrame(bool *aOK) { - if (!mMask) + if (!mMask) { return nullptr; + } + + const nsTArray>& props = mMask->GetProps(); + + if (props.IsEmpty()) { + return nullptr; + } + return static_cast - (mMask->GetReferencedFrame(nsGkAtoms::svgMaskFrame, aOK)); + (props[0]->GetReferencedFrame(nsGkAtoms::svgMaskFrame, aOK)); +} + +nsTArray +nsSVGEffects::EffectProperties::GetMaskFrames() +{ + nsTArray result; + if (!mMask) + return result; + + bool ok = false; + const nsTArray>& props = mMask->GetProps(); + for (size_t i = 0; i < props.Length(); i++) { + nsSVGMaskFrame* maskFrame = + static_cast(props[i]->GetReferencedFrame( + nsGkAtoms::svgMaskFrame, &ok)); + result.AppendElement(maskFrame); + } + + return result; } void diff --git a/layout/svg/nsSVGEffects.h b/layout/svg/nsSVGEffects.h index 9c7934e8c359..282cc9647e1b 100644 --- a/layout/svg/nsSVGEffects.h +++ b/layout/svg/nsSVGEffects.h @@ -43,7 +43,8 @@ class nsSVGFilterChainObserver; * constructor and destructor, which should call StartListening and * StopListening, respectively. */ -class nsSVGRenderingObserver : public nsStubMutationObserver { +class nsSVGRenderingObserver : public nsStubMutationObserver +{ protected: virtual ~nsSVGRenderingObserver() @@ -108,7 +109,8 @@ protected: * object derived from nsSVGIDRenderingObserver to manage the relationship. The * property object is attached to the referencing frame. */ -class nsSVGIDRenderingObserver : public nsSVGRenderingObserver { +class nsSVGIDRenderingObserver : public nsSVGRenderingObserver +{ public: typedef mozilla::dom::Element Element; nsSVGIDRenderingObserver(nsIURI* aURI, nsIContent* aObservingContent, @@ -121,7 +123,8 @@ protected: // This is called when the referenced resource changes. virtual void DoUpdate() override; - class SourceReference : public nsReferencedElement { + class SourceReference : public nsReferencedElement + { public: explicit SourceReference(nsSVGIDRenderingObserver* aContainer) : mContainer(aContainer) {} protected: @@ -169,7 +172,8 @@ private: nsIPresShell *mFramePresShell; }; -class nsSVGRenderingObserverProperty : public nsSVGIDRenderingObserver { +class nsSVGRenderingObserverProperty : public nsSVGIDRenderingObserver +{ public: NS_DECL_ISUPPORTS @@ -200,7 +204,8 @@ protected: * The nsSVGFilterChainObserver class manages a list of nsSVGFilterReferences. */ class nsSVGFilterReference final : public nsSVGIDRenderingObserver - , public nsISVGFilterReference { + , public nsISVGFilterReference +{ public: nsSVGFilterReference(nsIURI* aURI, nsIContent* aObservingContent, @@ -246,7 +251,8 @@ private: * "blur(10px)" don't reference filter elements, so they don't need an * nsSVGFilterReference. The style system invalidates changes to CSS filters. */ -class nsSVGFilterChainObserver : public nsISupports { +class nsSVGFilterChainObserver : public nsISupports +{ public: nsSVGFilterChainObserver(const nsTArray& aFilters, nsIContent* aFilteredElement); @@ -268,7 +274,8 @@ private: nsTArray> mReferences; }; -class nsSVGFilterProperty : public nsSVGFilterChainObserver { +class nsSVGFilterProperty : public nsSVGFilterChainObserver +{ public: nsSVGFilterProperty(const nsTArray &aFilters, nsIFrame *aFilteredFrame) @@ -284,7 +291,8 @@ protected: nsSVGFrameReferenceFromProperty mFrameReference; }; -class nsSVGMarkerProperty final : public nsSVGRenderingObserverProperty { +class nsSVGMarkerProperty final: public nsSVGRenderingObserverProperty +{ public: nsSVGMarkerProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage) : nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage) {} @@ -293,7 +301,8 @@ protected: virtual void DoUpdate() override; }; -class nsSVGTextPathProperty final : public nsSVGRenderingObserverProperty { +class nsSVGTextPathProperty final : public nsSVGRenderingObserverProperty +{ public: nsSVGTextPathProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage) : nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage) @@ -313,7 +322,8 @@ private: bool mValid; }; -class nsSVGPaintingProperty final : public nsSVGRenderingObserverProperty { +class nsSVGPaintingProperty final : public nsSVGRenderingObserverProperty +{ public: nsSVGPaintingProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage) : nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage) {} @@ -322,6 +332,24 @@ protected: virtual void DoUpdate() override; }; +class nsSVGMaskProperty final : public nsISupports +{ +public: + explicit nsSVGMaskProperty(nsIFrame* aFrame); + + // nsISupports + NS_DECL_ISUPPORTS + + const nsTArray>& GetProps() const + { + return mProperties; + } + +private: + virtual ~nsSVGMaskProperty() {} + nsTArray> mProperties; +}; + /** * A manager for one-shot nsSVGRenderingObserver tracking. * nsSVGRenderingObservers can be added or removed. They are not strongly @@ -338,7 +366,8 @@ protected: * via nsSVGContainerFrame::RemoveFrame, since only frames in the frame * tree should be referenced. */ -class nsSVGRenderingObserverList { +class nsSVGRenderingObserverList +{ public: nsSVGRenderingObserverList() : mObservers(4) @@ -384,7 +413,8 @@ private: nsTHashtable > mObservers; }; -class nsSVGEffects { +class nsSVGEffects +{ public: typedef mozilla::dom::Element Element; typedef nsInterfaceHashtable @@ -407,7 +437,7 @@ public: NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(FilterProperty, nsSVGFilterProperty, DestroyFilterProperty) - NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MaskProperty, nsISupports) + NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MaskProperty, nsSVGMaskProperty) NS_DECLARE_FRAME_PROPERTY_RELEASABLE(ClipPathProperty, nsISupports) NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerBeginProperty, nsISupports) NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerMiddleProperty, nsISupports) @@ -427,7 +457,7 @@ public: struct EffectProperties { nsSVGFilterProperty* mFilter; - nsSVGPaintingProperty* mMask; + nsSVGMaskProperty* mMask; nsSVGPaintingProperty* mClipPath; /** @@ -438,12 +468,17 @@ public: */ nsSVGClipPathFrame *GetClipPathFrame(bool *aOK); /** - * @return the mask frame, or null if there is no mask frame + * @return the first mask frame, or null if there is no mask frame * @param aOK if a mask was specified and the designated element * exists but is an element of the wrong type, *aOK is set to false. * Otherwise *aOK is untouched. */ - nsSVGMaskFrame *GetMaskFrame(bool *aOK); + nsSVGMaskFrame *GetFirstMaskFrame(bool *aOK = nullptr); + + /** + * @return an array which contains all SVG mask frames. + */ + nsTArray GetMaskFrames(); bool HasValidFilter() { return mFilter && mFilter->ReferencesValidResources(); diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index a812c0b9e231..876d471f0077 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -409,18 +409,132 @@ private: nsPoint mOffset; }; +static bool +HasMaskToDraw(const nsStyleSVGReset* aSVGReset, + nsSVGEffects::EffectProperties& aEffectProperties) +{ + nsTArray svgMaskFrames = aEffectProperties.GetMaskFrames(); + for (int i = svgMaskFrames.Length() - 1; i >= 0 ; i--) { + nsSVGMaskFrame *maskFrame = svgMaskFrames[i]; + + // We found a SVG mask or an image mask. + if (maskFrame || !aSVGReset->mMask.mLayers[i].mImage.IsEmpty()) { + return true; + } + } + + return false; +} + +static void +GenerateMaskSurface(const nsSVGIntegrationUtils::PaintFramesParams& aParams, + float aOpacity, nsStyleContext* aSC, + nsSVGEffects::EffectProperties& aEffectProperties, + const gfxPoint& aOffest, Matrix& aOutMaskTransform, + RefPtr& aOutMaskSurface) +{ + const nsStyleSVGReset *svgReset = aSC->StyleSVGReset(); + MOZ_ASSERT(HasMaskToDraw(svgReset, aEffectProperties)); + + nsTArray svgMaskFrames = aEffectProperties.GetMaskFrames(); + MOZ_ASSERT(svgMaskFrames.Length() == svgReset->mMask.mImageCount); + + gfxMatrix cssPxToDevPxMatrix = + nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(aParams.frame); + + gfxContext& ctx = aParams.ctx; + + // There is only one mask. And that mask is a SVG mask. + if ((svgMaskFrames.Length() == 1) && svgMaskFrames[0]) { + aOutMaskSurface = + svgMaskFrames[0]->GetMaskForMaskedFrame(&ctx, aParams.frame, + cssPxToDevPxMatrix, aOpacity, + &aOutMaskTransform, + svgReset->mMask.mLayers[0].mMaskMode); + return; + } + + ctx.Save(); + ctx.SetMatrix(gfxMatrix()); + gfxRect clipExtents = ctx.GetClipExtents(); + IntRect maskSurfaceRect = RoundedOut(ToRect(clipExtents)); + ctx.Restore(); + + // Mask composition result on CoreGraphic::A8 surface is not correct + // when mask-mode is not add(source over). Switch to skia when CG backend + // detected. + RefPtr maskDT = + (ctx.GetDrawTarget()->GetBackendType() == BackendType::COREGRAPHICS) + ? Factory::CreateDrawTarget(BackendType::SKIA, maskSurfaceRect.Size(), + SurfaceFormat::A8) + : ctx.GetDrawTarget()->CreateSimilarDrawTarget(maskSurfaceRect.Size(), + SurfaceFormat::A8); + RefPtr maskContext = gfxContext::ForDrawTarget(maskDT); + + // Set ctx's matrix on maskContext, offset by the maskSurfaceRect's position. + // This makes sure that we combine the masks in device space. + gfxMatrix maskSurfaceMatrix = + ctx.CurrentMatrix() * gfxMatrix::Translation(-maskSurfaceRect.TopLeft()); + maskContext->SetMatrix(maskSurfaceMatrix); + + // Multiple SVG masks interleave with image mask. Paint each layer onto maskDT + // one at a time. + for (int i = svgMaskFrames.Length() - 1; i >= 0 ; i--) { + nsSVGMaskFrame *maskFrame = svgMaskFrames[i]; + + // maskFrame != nullptr means we get a SVG mask. + // maskFrame == nullptr means we get an image mask. + if (maskFrame) { + Matrix svgMaskMatrix; + RefPtr svgMask = + maskFrame->GetMaskForMaskedFrame(maskContext, aParams.frame, + cssPxToDevPxMatrix, aOpacity, + &svgMaskMatrix, + svgReset->mMask.mLayers[i].mMaskMode); + if (svgMask) { + gfxContextMatrixAutoSaveRestore matRestore(maskContext); + + maskContext->Multiply(ThebesMatrix(svgMaskMatrix)); + Rect drawRect = IntRectToRect(IntRect(IntPoint(0, 0), svgMask->GetSize())); + maskDT->DrawSurface(svgMask, drawRect, drawRect); + } + } else { + gfxContextMatrixAutoSaveRestore matRestore(maskContext); + + maskContext->Multiply(gfxMatrix::Translation(-aOffest)); + CompositionOp compositionOp = + nsCSSRendering::GetGFXCompositeMode(svgReset->mMask.mLayers[i].mComposite); + nsRenderingContext rc(maskContext); + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForSingleLayer(*aParams.frame->PresContext(), + rc, aParams.dirtyRect, + aParams.borderArea, + aParams.frame, + aParams.builder->GetBackgroundPaintFlags() | + nsCSSRendering::PAINTBG_MASK_IMAGE, + i, compositionOp); + + // FIXME We should use the return value, see bug 1258510. + Unused << nsCSSRendering::PaintBackgroundWithSC(params, aSC, + *aParams.frame->StyleBorder()); + } + } + + aOutMaskTransform = ToMatrix(maskSurfaceMatrix); + if (!aOutMaskTransform.Invert()) { + return; + } + + aOutMaskSurface = maskDT->Snapshot(); +} + void -nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext, - nsIFrame* aFrame, - const nsRect& aDirtyRect, - const nsRect& aBorderArea, - nsDisplayListBuilder* aBuilder, - LayerManager *aLayerManager) +nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams) { #ifdef DEBUG - NS_ASSERTION(!(aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) || + NS_ASSERTION(!(aParams.frame->GetStateBits() & NS_FRAME_SVG_LAYOUT) || (NS_SVGDisplayListPaintingEnabled() && - !(aFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY)), + !(aParams.frame->GetStateBits() & NS_FRAME_IS_NONDISPLAY)), "Should not use nsSVGIntegrationUtils on this SVG frame"); #endif @@ -437,12 +551,12 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext, * * + Merge opacity and masking if both used together. */ - - const nsIContent* content = aFrame->GetContent(); - bool hasSVGLayout = (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT); + nsIFrame* frame = aParams.frame; + const nsIContent* content = frame->GetContent(); + bool hasSVGLayout = (frame->GetStateBits() & NS_FRAME_SVG_LAYOUT); if (hasSVGLayout) { - nsISVGChildFrame *svgChildFrame = do_QueryFrame(aFrame); - if (!svgChildFrame || !aFrame->GetContent()->IsSVGElement()) { + nsISVGChildFrame *svgChildFrame = do_QueryFrame(frame); + if (!svgChildFrame || !frame->GetContent()->IsSVGElement()) { NS_ASSERTION(false, "why?"); return; } @@ -451,19 +565,19 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext, } } - float opacity = aFrame->StyleEffects()->mOpacity; + float opacity = frame->StyleEffects()->mOpacity; if (opacity == 0.0f) { return; } if (opacity != 1.0f && - hasSVGLayout && nsSVGUtils::CanOptimizeOpacity(aFrame)) { + hasSVGLayout && nsSVGUtils::CanOptimizeOpacity(frame)) { opacity = 1.0f; } /* Properties are added lazily and may have been removed by a restyle, so make sure all applicable ones are set again. */ nsIFrame* firstFrame = - nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame); + nsLayoutUtils::FirstContinuationOrIBSplitSibling(frame); nsSVGEffects::EffectProperties effectProperties = nsSVGEffects::GetEffectProperties(firstFrame); @@ -471,22 +585,22 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext, nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK); bool isTrivialClip = clipPathFrame ? clipPathFrame->IsTrivial() : true; - - DrawTarget* drawTarget = aContext.GetDrawTarget(); - gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(&aContext); + gfxContext& context = aParams.ctx; + DrawTarget* drawTarget = context.GetDrawTarget(); + gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(&context); nsPoint firstFrameOffset = GetOffsetToBoundingBox(firstFrame); - nsPoint offsetToBoundingBox = aBuilder->ToReferenceFrame(firstFrame) - firstFrameOffset; + nsPoint offsetToBoundingBox = aParams.builder->ToReferenceFrame(firstFrame) - firstFrameOffset; if (!firstFrame->IsFrameOfType(nsIFrame::eSVG)) { /* Snap the offset if the reference frame is not a SVG frame, * since other frames will be snapped to pixel when rendering. */ offsetToBoundingBox = nsPoint( - aFrame->PresContext()->RoundAppUnitsToNearestDevPixels(offsetToBoundingBox.x), - aFrame->PresContext()->RoundAppUnitsToNearestDevPixels(offsetToBoundingBox.y)); + frame->PresContext()->RoundAppUnitsToNearestDevPixels(offsetToBoundingBox.x), + frame->PresContext()->RoundAppUnitsToNearestDevPixels(offsetToBoundingBox.y)); } // After applying only "offsetToBoundingBox", aCtx would have its origin at - // the top left corner of aFrame's bounding box (over all continuations). + // the top left corner of frame's bounding box (over all continuations). // However, SVG painting needs the origin to be located at the origin of the // SVG frame's "user space", i.e. the space in which, for example, the // frame's BBox lives. @@ -496,7 +610,7 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext, // frame's position so that SVG painting can later add it again and the // frame is painted in the right place. - gfxPoint toUserSpaceGfx = nsSVGUtils::FrameSpaceInCSSPxToUserSpaceOffset(aFrame); + gfxPoint toUserSpaceGfx = nsSVGUtils::FrameSpaceInCSSPxToUserSpaceOffset(frame); nsPoint toUserSpace(nsPresContext::CSSPixelsToAppUnits(float(toUserSpaceGfx.x)), nsPresContext::CSSPixelsToAppUnits(float(toUserSpaceGfx.y))); nsPoint offsetToUserSpace = offsetToBoundingBox - toUserSpace; @@ -506,141 +620,74 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext, gfxPoint devPixelOffsetToUserSpace = nsLayoutUtils::PointToGfxPoint(offsetToUserSpace, - aFrame->PresContext()->AppUnitsPerDevPixel()); - aContext.SetMatrix(aContext.CurrentMatrix().Translate(devPixelOffsetToUserSpace)); + frame->PresContext()->AppUnitsPerDevPixel()); + context.SetMatrix(context.CurrentMatrix().Translate(devPixelOffsetToUserSpace)); - gfxMatrix cssPxToDevPxMatrix = GetCSSPxToDevPxMatrix(aFrame); + gfxMatrix cssPxToDevPxMatrix = GetCSSPxToDevPxMatrix(frame); const nsStyleSVGReset *svgReset = firstFrame->StyleSVGReset(); - // Keep moving forward even if svgMaskFrame is nullptr or isOK is false. - // This source is not a svg mask, but it still can be a correct mask image. - nsSVGMaskFrame *svgMaskFrame = effectProperties.GetMaskFrame(&isOK); + bool hasMaskToDraw = HasMaskToDraw(svgReset, effectProperties); // These are used if we require a temporary surface for a custom blend mode. - RefPtr target = &aContext; + RefPtr target = &aParams.ctx; IntPoint targetOffset; - // hasMaskToDraw is true means we have at least one drawable mask resource. - // We need to apply mask only if hasMaskToDraw is true. - bool hasMaskToDraw = (svgMaskFrame != nullptr); - if (!hasMaskToDraw) { - NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, svgReset->mMask) { - if (!svgReset->mMask.mLayers[i].mImage.IsEmpty()) { - hasMaskToDraw = true; - break; - } - } - } - bool complexEffects = false; /* Check if we need to do additional operations on this child's * rendering, which necessitates rendering into another surface. */ if (opacity != 1.0f || (clipPathFrame && !isTrivialClip) - || aFrame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL + || frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL || hasMaskToDraw) { complexEffects = true; - aContext.Save(); + context.Save(); nsRect clipRect = - aFrame->GetVisualOverflowRectRelativeToSelf() + toUserSpace; - aContext.Clip(NSRectToSnappedRect(clipRect, - aFrame->PresContext()->AppUnitsPerDevPixel(), + frame->GetVisualOverflowRectRelativeToSelf() + toUserSpace; + context.Clip(NSRectToSnappedRect(clipRect, + frame->PresContext()->AppUnitsPerDevPixel(), *drawTarget)); - Matrix maskTransform; RefPtr maskSurface; - if (svgMaskFrame) { - // Generate maskSurface from a SVG mask. - maskSurface = svgMaskFrame->GetMaskForMaskedFrame(&aContext, - aFrame, - cssPxToDevPxMatrix, - opacity, - &maskTransform, - svgReset->mMask.mLayers[0].mMaskMode); - } else if (hasMaskToDraw) { - // Create maskSuface. - gfxRect clipRect = aContext.GetClipExtents(); - { - gfxContextMatrixAutoSaveRestore matRestore(&aContext); - aContext.SetMatrix(gfxMatrix()); - clipRect = aContext.GetClipExtents(); - } - IntRect drawRect = RoundedOut(ToRect(clipRect)); - - // Mask composition result on CoreGraphic::A8 surface is not correct - // when mask-mode is not add(source over). Switch to skia when CG backend - // detected. - RefPtr targetDT = - (aContext.GetDrawTarget()->GetBackendType() == BackendType::COREGRAPHICS) ? - Factory::CreateDrawTarget(BackendType::SKIA, drawRect.Size(), - SurfaceFormat::A8) : - aContext.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), - SurfaceFormat::A8); - - if (!targetDT || !targetDT->IsValid()) { - aContext.Restore(); - return; - } - - RefPtr target = gfxContext::ForDrawTarget(targetDT); - MOZ_ASSERT(target); // alrady checked the draw target above - target->SetMatrix(matrixAutoSaveRestore.Matrix() * gfxMatrix::Translation(-drawRect.TopLeft())); - - // Compose all mask-images onto maskSurface. - uint32_t flags = aBuilder->GetBackgroundPaintFlags() | - nsCSSRendering::PAINTBG_MASK_IMAGE; - nsRenderingContext rc(target); - // FIXME We should use the return value, see bug 1258510. - Unused << nsCSSRendering::PaintBackgroundWithSC(aFrame->PresContext(), - rc, - aFrame, - aDirtyRect, - aBorderArea, - firstFrame->StyleContext(), - *aFrame->StyleBorder(), - flags); - maskSurface = targetDT->Snapshot(); - - // Compute mask transform. - Matrix mat = ToMatrix(aContext.CurrentMatrix()); - mat.Invert(); - maskTransform = Matrix::Translation(drawRect.x, drawRect.y) * mat; + if (hasMaskToDraw) { + GenerateMaskSurface(aParams, opacity, firstFrame->StyleContext(), + effectProperties, devPixelOffsetToUserSpace, + maskTransform, maskSurface); } if (hasMaskToDraw && !maskSurface) { // Entire surface is clipped out. - aContext.Restore(); + context.Restore(); return; } - if (aFrame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) { + if (frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) { // Create a temporary context to draw to so we can blend it back with // another operator. gfxRect clipRect; { - gfxContextMatrixAutoSaveRestore matRestore(&aContext); + gfxContextMatrixAutoSaveRestore matRestore(&context); - aContext.SetMatrix(gfxMatrix()); - clipRect = aContext.GetClipExtents(); + context.SetMatrix(gfxMatrix()); + clipRect = context.GetClipExtents(); } IntRect drawRect = RoundedOut(ToRect(clipRect)); - RefPtr targetDT = aContext.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), SurfaceFormat::B8G8R8A8); + RefPtr targetDT = context.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), SurfaceFormat::B8G8R8A8); if (!targetDT || !targetDT->IsValid()) { - aContext.Restore(); + context.Restore(); return; } target = gfxContext::ForDrawTarget(targetDT); MOZ_ASSERT(target); // already checked the draw target above - target->SetMatrix(aContext.CurrentMatrix() * gfxMatrix::Translation(-drawRect.TopLeft())); + target->SetMatrix(context.CurrentMatrix() * gfxMatrix::Translation(-drawRect.TopLeft())); targetOffset = drawRect.TopLeft(); } if (clipPathFrame && !isTrivialClip) { Matrix clippedMaskTransform; - RefPtr clipMaskSurface = clipPathFrame->GetClipMask(aContext, aFrame, cssPxToDevPxMatrix, + RefPtr clipMaskSurface = clipPathFrame->GetClipMask(context, frame, cssPxToDevPxMatrix, &clippedMaskTransform, maskSurface, maskTransform); if (clipMaskSurface) { @@ -658,34 +705,35 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext, * we can just do normal painting and get it clipped appropriately. */ if (clipPathFrame && isTrivialClip) { - aContext.Save(); - clipPathFrame->ApplyClipPath(aContext, aFrame, cssPxToDevPxMatrix); + context.Save(); + clipPathFrame->ApplyClipPath(context, frame, cssPxToDevPxMatrix); } else if (!clipPathFrame && svgReset->HasClipPath()) { - aContext.Save(); - nsCSSClipPathInstance::ApplyBasicShapeClip(aContext, aFrame); + context.Save(); + nsCSSClipPathInstance::ApplyBasicShapeClip(context, frame); } /* Paint the child */ if (effectProperties.HasValidFilter()) { - RegularFramePaintCallback callback(aBuilder, aLayerManager, + RegularFramePaintCallback callback(aParams.builder, aParams.layerManager, offsetToUserSpace); - nsRegion dirtyRegion = aDirtyRect - offsetToBoundingBox; - gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(aFrame); - nsFilterInstance::PaintFilteredFrame(aFrame, target->GetDrawTarget(), + nsRegion dirtyRegion = aParams.dirtyRect - offsetToBoundingBox; + gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(frame); + nsFilterInstance::PaintFilteredFrame(frame, target->GetDrawTarget(), tm, &callback, &dirtyRegion); } else { target->SetMatrix(matrixAutoSaveRestore.Matrix()); - BasicLayerManager* basic = static_cast(aLayerManager); + BasicLayerManager* basic = static_cast(aParams.layerManager); RefPtr oldCtx = basic->GetTarget(); basic->SetTarget(target); - aLayerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, aBuilder); + aParams.layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, + aParams.builder); basic->SetTarget(oldCtx); } if ((clipPathFrame && isTrivialClip) || (!clipPathFrame && svgReset->HasClipPath())) { - aContext.Restore(); + context.Restore(); } /* No more effects, we're done. */ @@ -697,18 +745,18 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext, target->PopGroupAndBlend(); } - if (aFrame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) { + if (frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) { RefPtr targetDT = target->GetDrawTarget(); target = nullptr; RefPtr targetSurf = targetDT->Snapshot(); - aContext.SetMatrix(gfxMatrix()); // This will be restored right after. + context.SetMatrix(gfxMatrix()); // This will be restored right after. RefPtr pattern = new gfxPattern(targetSurf, Matrix::Translation(targetOffset.x, targetOffset.y)); - aContext.SetPattern(pattern); - aContext.Paint(); + context.SetPattern(pattern); + context.Paint(); } - aContext.Restore(); + context.Restore(); } gfxMatrix diff --git a/layout/svg/nsSVGIntegrationUtils.h b/layout/svg/nsSVGIntegrationUtils.h index c15fd1384e37..fb2b575044fb 100644 --- a/layout/svg/nsSVGIntegrationUtils.h +++ b/layout/svg/nsSVGIntegrationUtils.h @@ -123,15 +123,29 @@ public: static bool HitTestFrameForEffects(nsIFrame* aFrame, const nsPoint& aPt); + struct PaintFramesParams { + gfxContext& ctx; + nsIFrame* frame; + const nsRect& dirtyRect; + const nsRect& borderArea; + nsDisplayListBuilder* builder; + mozilla::layers::LayerManager* layerManager; + explicit PaintFramesParams(gfxContext& aCtx, nsIFrame* aFrame, + const nsRect& aDirtyRect, + const nsRect& aBorderArea, + nsDisplayListBuilder* aBuilder, + mozilla::layers::LayerManager* aLayerManager) + : ctx(aCtx), frame(aFrame), dirtyRect(aDirtyRect), + borderArea(aBorderArea), builder(aBuilder), + layerManager(aLayerManager) + { } + }; + /** * Paint non-SVG frame with SVG effects. */ static void - PaintFramesWithEffects(gfxContext& aCtx, - nsIFrame* aFrame, const nsRect& aDirtyRect, - const nsRect& aBorderArea, - nsDisplayListBuilder* aBuilder, - mozilla::layers::LayerManager* aManager); + PaintFramesWithEffects(const PaintFramesParams& aParams); /** * SVG frames expect to paint in SVG user units, which are equal to CSS px diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 61dbca5c3329..9614fb837439 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -577,7 +577,7 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame, bool complexEffects = false; nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK); - nsSVGMaskFrame *maskFrame = effectProperties.GetMaskFrame(&isOK); + nsSVGMaskFrame *maskFrame = effectProperties.GetFirstMaskFrame(&isOK); bool isTrivialClip = clipPathFrame ? clipPathFrame->IsTrivial() : true; diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 2c8eca96c988..e4ca407ed097 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -372,8 +372,12 @@ nsTableCellFrame::PaintBackground(nsRenderingContext& aRenderingContext, uint32_t aFlags) { nsRect rect(aPt, GetSize()); - return nsCSSRendering::PaintBackground(PresContext(), aRenderingContext, this, - aDirtyRect, rect, aFlags); + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForAllLayers(*PresContext(), + aRenderingContext, + aDirtyRect, rect, + this, aFlags); + return nsCSSRendering::PaintBackground(params); } // Called by nsTablePainter @@ -1218,11 +1222,13 @@ nsBCTableCellFrame::PaintBackground(nsRenderingContext& aRenderingContext, myBorder.SetBorderWidth(side, borderWidth.Side(side)); } - nsRect rect(aPt, GetSize()); // bypassing nsCSSRendering::PaintBackground is safe because this kind // of frame cannot be used for the root element - return nsCSSRendering::PaintBackgroundWithSC(PresContext(), aRenderingContext, - this, aDirtyRect, rect, - StyleContext(), myBorder, - aFlags, nullptr); + nsRect rect(aPt, GetSize()); + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForAllLayers(*PresContext(), + aRenderingContext, aDirtyRect, + rect, this, + aFlags); + return nsCSSRendering::PaintBackgroundWithSC(params, StyleContext(), myBorder); } diff --git a/layout/tables/nsTablePainter.cpp b/layout/tables/nsTablePainter.cpp index cf0565a91ba3..bfe2a7d4293a 100644 --- a/layout/tables/nsTablePainter.cpp +++ b/layout/tables/nsTablePainter.cpp @@ -230,13 +230,18 @@ TableBackgroundPainter::PaintTableFrame(nsTableFrame* aTableFrame, DrawResult result = DrawResult::SUCCESS; if (tableData.IsVisible()) { + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext, + mRenderingContext, + mDirtyRect, + tableData.mRect + mRenderPt, + tableData.mFrame, + mBGPaintFlags); + result &= - nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext, - tableData.mFrame, mDirtyRect, - tableData.mRect + mRenderPt, + nsCSSRendering::PaintBackgroundWithSC(params, tableData.mFrame->StyleContext(), - tableData.StyleBorder(mZeroBorder), - mBGPaintFlags); + tableData.StyleBorder(mZeroBorder)); } return result; @@ -567,46 +572,60 @@ TableBackgroundPainter::PaintCell(nsTableCellFrame* aCell, //Paint column group background if (haveColumns && mCols[colIndex].mColGroup.IsVisible()) { + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext, mRenderingContext, + mDirtyRect, + mCols[colIndex].mColGroup.mRect + mRenderPt, + mCols[colIndex].mColGroup.mFrame, + mBGPaintFlags); + params.bgClipRect = &aColBGRect; result &= - nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext, - mCols[colIndex].mColGroup.mFrame, mDirtyRect, - mCols[colIndex].mColGroup.mRect + mRenderPt, + nsCSSRendering::PaintBackgroundWithSC(params, mCols[colIndex].mColGroup.mFrame->StyleContext(), - mCols[colIndex].mColGroup.StyleBorder(mZeroBorder), - mBGPaintFlags, &aColBGRect); + mCols[colIndex].mColGroup.StyleBorder(mZeroBorder)); } //Paint column background if (haveColumns && mCols[colIndex].mCol.IsVisible()) { + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext, mRenderingContext, + mDirtyRect, + mCols[colIndex].mCol.mRect + mRenderPt, + mCols[colIndex].mCol.mFrame, + mBGPaintFlags); + params.bgClipRect = &aColBGRect; result &= - nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext, - mCols[colIndex].mCol.mFrame, mDirtyRect, - mCols[colIndex].mCol.mRect + mRenderPt, + nsCSSRendering::PaintBackgroundWithSC(params, mCols[colIndex].mCol.mFrame->StyleContext(), - mCols[colIndex].mCol.StyleBorder(mZeroBorder), - mBGPaintFlags, &aColBGRect); + mCols[colIndex].mCol.StyleBorder(mZeroBorder)); } //Paint row group background if (aRowGroupBGData.IsVisible()) { + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext, mRenderingContext, + mDirtyRect, + aRowGroupBGData.mRect + mRenderPt, + aRowGroupBGData.mFrame, mBGPaintFlags); + params.bgClipRect = &aRowGroupBGRect; result &= - nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext, - aRowGroupBGData.mFrame, mDirtyRect, - aRowGroupBGData.mRect + mRenderPt, + nsCSSRendering::PaintBackgroundWithSC(params, aRowGroupBGData.mFrame->StyleContext(), - aRowGroupBGData.StyleBorder(mZeroBorder), - mBGPaintFlags, &aRowGroupBGRect); + aRowGroupBGData.StyleBorder(mZeroBorder)); } //Paint row background if (aRowBGData.IsVisible()) { + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext, mRenderingContext, + mDirtyRect, + aRowBGData.mRect + mRenderPt, + aRowBGData.mFrame, mBGPaintFlags); + params.bgClipRect = &aRowBGRect; result &= - nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext, - aRowBGData.mFrame, mDirtyRect, - aRowBGData.mRect + mRenderPt, + nsCSSRendering::PaintBackgroundWithSC(params, aRowBGData.mFrame->StyleContext(), - aRowBGData.StyleBorder(mZeroBorder), - mBGPaintFlags, &aRowBGRect); + aRowBGData.StyleBorder(mZeroBorder)); } //Paint cell background in border-collapse unless we're just passing diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp index a4460c17ffc5..f12abeb414bf 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -4087,12 +4087,12 @@ nsTreeBodyFrame::PaintBackgroundLayer(nsStyleContext* aStyleContext, const nsRect& aDirtyRect) { const nsStyleBorder* myBorder = aStyleContext->StyleBorder(); - + nsCSSRendering::PaintBGParams params = + nsCSSRendering::PaintBGParams::ForAllLayers(*aPresContext, aRenderingContext, + aDirtyRect, aRect, this, + nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES); DrawResult result = - nsCSSRendering::PaintBackgroundWithSC(aPresContext, aRenderingContext, - this, aDirtyRect, aRect, - aStyleContext, *myBorder, - nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES); + nsCSSRendering::PaintBackgroundWithSC(params, aStyleContext, *myBorder); result &= nsCSSRendering::PaintBorderWithStyleBorder(aPresContext, aRenderingContext, diff --git a/media/libnestegg/README_MOZILLA b/media/libnestegg/README_MOZILLA index dd0778d72bbf..89e68a8f50f6 100644 --- a/media/libnestegg/README_MOZILLA +++ b/media/libnestegg/README_MOZILLA @@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system. The nestegg git repository is: git://github.com/kinetiknz/nestegg.git -The git commit ID used was 764a4ca95f1f0b7713c42516970dd62177ec3c22. +The git commit ID used was 39f7bf7ce5aaa11d4ebe2fb54e66e6f1a2ce4150. diff --git a/media/libnestegg/include/nestegg.h b/media/libnestegg/include/nestegg.h index 83320826b817..cf73587b05f6 100644 --- a/media/libnestegg/include/nestegg.h +++ b/media/libnestegg/include/nestegg.h @@ -89,6 +89,10 @@ extern "C" { #define NESTEGG_LOG_ERROR 1000 /**< Error level log message. */ #define NESTEGG_LOG_CRITICAL 10000 /**< Critical level log message. */ +#define NESTEGG_PACKET_HAS_KEYFRAME_FALSE 0 /**< Packet contains only keyframes. */ +#define NESTEGG_PACKET_HAS_KEYFRAME_TRUE 1 /**< Packet does not contain any keyframes */ +#define NESTEGG_PACKET_HAS_KEYFRAME_UNKNOWN 2 /**< Packet may or may not contain keyframes */ + typedef struct nestegg nestegg; /**< Opaque handle referencing the stream state. */ typedef struct nestegg_packet nestegg_packet; /**< Opaque handle referencing a packet of data. */ @@ -294,6 +298,12 @@ int nestegg_track_audio_params(nestegg * context, unsigned int track, int nestegg_track_default_duration(nestegg * context, unsigned int track, uint64_t * duration); +/** Reset parser state to the last valid state before nestegg_read_packet failed. + @param context Stream context initialized by #nestegg_init. + @retval 0 Success. + @retval -1 Error. */ +int nestegg_read_reset(nestegg * context); + /** Read a packet of media data. A packet consists of one or more chunks of data associated with a single track. nestegg_read_packet should be called in a loop while the return value is 1 to drive the stream parser @@ -309,6 +319,14 @@ int nestegg_read_packet(nestegg * context, nestegg_packet ** packet); @param packet #nestegg_packet to be freed. @see nestegg_read_packet */ void nestegg_free_packet(nestegg_packet * packet); +/** Query the keyframe status for a given packet. + @param packet Packet initialized by #nestegg_read_packet. + @retval #NESTEGG_PACKET_HAS_KEYFRAME_FALSE Packet contains no keyframes. + @retval #NESTEGG_PACKET_HAS_KEYFRAME_TRUE Packet contains keyframes. + @retval #NESTEGG_PACKET_HAS_KEYFRAME_UNKNOWN Unknown packet keyframe content. + @retval -1 Error. */ +int nestegg_packet_has_keyframe(nestegg_packet * packet); + /** Query the track number of @a packet. @param packet Packet initialized by #nestegg_read_packet. @param track Storage for the queried zero based track index. @@ -369,6 +387,14 @@ int nestegg_packet_additional_data(nestegg_packet * packet, unsigned int id, int nestegg_packet_discard_padding(nestegg_packet * packet, int64_t * discard_padding); +/** Returns reference_block given packet + @param packet Packet initialized by #nestegg_read_packet. + @param reference_block pointer to store reference block in. + @retval 0 Success. + @retval -1 Error. */ +int nestegg_packet_reference_block(nestegg_packet * packet, + int64_t * reference_block); + /** Query the presence of cues. @param context Stream context initialized by #nestegg_init. @retval 0 The media has no cues. diff --git a/media/libnestegg/src/nestegg.c b/media/libnestegg/src/nestegg.c index b13b2ae2259d..1fda0811c8d4 100644 --- a/media/libnestegg/src/nestegg.c +++ b/media/libnestegg/src/nestegg.c @@ -126,7 +126,8 @@ enum ebml_type_enum { #define DESC_FLAG_OFFSET (1 << 2) /* Block Header Flags */ -#define BLOCK_FLAGS_LACING 6 +#define SIMPLE_BLOCK_FLAGS_KEYFRAME (1 << 7) +#define BLOCK_FLAGS_LACING 6 /* Lacing Constants */ #define LACING_NONE 0 @@ -203,10 +204,6 @@ struct info { struct ebml_type duration; }; -struct cluster { - struct ebml_type timecode; -}; - struct video { struct ebml_type stereo_mode; struct ebml_type alpha_mode; @@ -266,7 +263,6 @@ struct cues { struct segment { struct ebml_list seek_head; struct info info; - struct ebml_list cluster; struct tracks tracks; struct cues cues; }; @@ -284,7 +280,6 @@ struct list_node { struct saved_state { int64_t stream_offset; - struct list_node * ancestor; uint64_t last_id; uint64_t last_size; int last_valid; @@ -316,6 +311,10 @@ struct nestegg { struct segment segment; int64_t segment_offset; unsigned int track_count; + /* Last read cluster. */ + uint64_t cluster_timecode; + int read_cluster_timecode; + struct saved_state saved; }; struct nestegg_packet { @@ -327,6 +326,9 @@ struct nestegg_packet { struct block_additional * block_additional; int64_t discard_padding; int read_discard_padding; + int64_t reference_block; + int read_reference_block; + uint8_t keyframe; }; /* Element Descriptor */ @@ -386,13 +388,6 @@ static struct ebml_element_desc ne_info_elements[] = { E_LAST }; -static struct ebml_element_desc ne_cluster_elements[] = { - E_FIELD(ID_TIMECODE, TYPE_UINT, struct cluster, timecode), - E_SUSPEND(ID_BLOCK_GROUP, TYPE_MASTER), - E_SUSPEND(ID_SIMPLE_BLOCK, TYPE_BINARY), - E_LAST -}; - static struct ebml_element_desc ne_video_elements[] = { E_FIELD(ID_STEREO_MODE, TYPE_UINT, struct video, stereo_mode), E_FIELD(ID_ALPHA_MODE, TYPE_UINT, struct video, alpha_mode), @@ -459,7 +454,7 @@ static struct ebml_element_desc ne_cues_elements[] = { static struct ebml_element_desc ne_segment_elements[] = { E_MASTER(ID_SEEK_HEAD, TYPE_MASTER, struct segment, seek_head), E_SINGLE_MASTER(ID_INFO, TYPE_MASTER, struct segment, info), - E_MASTER(ID_CLUSTER, TYPE_MASTER, struct segment, cluster), + E_SUSPEND(ID_CLUSTER, TYPE_MASTER), E_SINGLE_MASTER(ID_TRACKS, TYPE_MASTER, struct segment, tracks), E_SINGLE_MASTER(ID_CUES, TYPE_MASTER, struct segment, cues), E_LAST @@ -829,7 +824,6 @@ ne_ctx_save(nestegg * ctx, struct saved_state * s) s->stream_offset = ne_io_tell(ctx->io); if (s->stream_offset < 0) return -1; - s->ancestor = ctx->ancestor; s->last_id = ctx->last_id; s->last_size = ctx->last_size; s->last_valid = ctx->last_valid; @@ -841,10 +835,11 @@ ne_ctx_restore(nestegg * ctx, struct saved_state * s) { int r; + if (s->stream_offset < 0) + return -1; r = ne_io_seek(ctx->io, s->stream_offset, NESTEGG_SEEK_SET); if (r != 0) return -1; - ctx->ancestor = s->ancestor; ctx->last_id = s->last_id; ctx->last_size = s->last_size; ctx->last_valid = s->last_valid; @@ -999,8 +994,7 @@ ne_parse(nestegg * ctx, struct ebml_element_desc * top_level, int64_t max_offset uint64_t id, size, peeked_id; struct ebml_element_desc * element; - if (!ctx->ancestor) - return -1; + assert(ctx->ancestor); for (;;) { if (max_offset > 0 && ne_io_tell(ctx->io) >= max_offset) { @@ -1016,8 +1010,7 @@ ne_parse(nestegg * ctx, struct ebml_element_desc * top_level, int64_t max_offset element = ne_find_element(id, ctx->ancestor->node); if (element) { if (element->flags & DESC_FLAG_SUSPEND) { - assert((element->id == ID_SIMPLE_BLOCK && element->type == TYPE_BINARY) || - (element->id == ID_BLOCK_GROUP && element->type == TYPE_MASTER)); + assert(element->id == ID_CLUSTER && element->type == TYPE_MASTER); ctx->log(ctx, NESTEGG_LOG_DEBUG, "suspend parse at %llx", id); r = 1; break; @@ -1228,12 +1221,12 @@ ne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_pac int r; int64_t timecode, abs_timecode; nestegg_packet * pkt; - struct cluster * cluster; struct frame * f, * last; struct track_entry * entry; double track_scale; uint64_t track_number, length, frame_sizes[256], cluster_tc, flags, frames, tc_scale, total; unsigned int i, lacing, track; + uint8_t keyframe = NESTEGG_PACKET_HAS_KEYFRAME_UNKNOWN; size_t consumed = 0; *data = NULL; @@ -1264,6 +1257,12 @@ ne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_pac frames = 0; + /* Simple blocks have an explicit flag for if the contents a keyframes*/ + if (block_id == ID_SIMPLE_BLOCK) + keyframe = (flags & SIMPLE_BLOCK_FLAGS_KEYFRAME) == SIMPLE_BLOCK_FLAGS_KEYFRAME ? + NESTEGG_PACKET_HAS_KEYFRAME_TRUE : + NESTEGG_PACKET_HAS_KEYFRAME_FALSE; + /* Flags are different between Block and SimpleBlock, but lacing is encoded the same way. */ lacing = (flags & BLOCK_FLAGS_LACING) >> 1; @@ -1329,10 +1328,9 @@ ne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_pac tc_scale = ne_get_timecode_scale(ctx); - assert(ctx->segment.cluster.tail->id == ID_CLUSTER); - cluster = ctx->segment.cluster.tail->data; - if (ne_get_uint(cluster->timecode, &cluster_tc) != 0) + if (!ctx->read_cluster_timecode) return -1; + cluster_tc = ctx->cluster_timecode; abs_timecode = timecode + cluster_tc; if (abs_timecode < 0) @@ -1343,6 +1341,7 @@ ne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_pac return -1; pkt->track = track; pkt->timecode = abs_timecode * tc_scale * track_scale; + pkt->keyframe = keyframe; ctx->log(ctx, NESTEGG_LOG_DEBUG, "%sblock t %lld pts %f f %llx frames: %llu", block_id == ID_BLOCK ? "" : "simple", pkt->track, pkt->timecode / 1e9, flags, frames); @@ -1370,7 +1369,7 @@ ne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_pac free(f->data); free(f); nestegg_free_packet(pkt); - return -1; + return r; } if (!last) @@ -1386,7 +1385,7 @@ ne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_pac } static int -ne_read_block_additions(nestegg * ctx, uint64_t block_id, uint64_t block_size, struct block_additional ** pkt_block_additional) +ne_read_block_additions(nestegg * ctx, uint64_t block_size, struct block_additional ** pkt_block_additional) { int r; uint64_t id, size, data_size; @@ -1398,9 +1397,6 @@ ne_read_block_additions(nestegg * ctx, uint64_t block_id, uint64_t block_size, s assert(*pkt_block_additional == NULL); - if (block_id != ID_BLOCK_ADDITIONS) - return 1; - block_additions_end = ne_io_tell(ctx->io) + block_size; while (ne_io_tell(ctx->io) < block_additions_end) { @@ -1409,14 +1405,16 @@ ne_read_block_additions(nestegg * ctx, uint64_t block_id, uint64_t block_size, s has_data = 0; r = ne_read_element(ctx, &id, &size); if (r != 1) - return -1; + return r; if (id != ID_BLOCK_MORE) { /* We don't know what this element is, so skip over it */ if (id != ID_VOID && id != ID_CRC32) ctx->log(ctx, NESTEGG_LOG_DEBUG, "unknown element %llx in BlockAdditions", id); - ne_io_read_skip(ctx->io, size); + r = ne_io_read_skip(ctx->io, size); + if (r != 1) + return r; continue; } @@ -1468,7 +1466,11 @@ ne_read_block_additions(nestegg * ctx, uint64_t block_id, uint64_t block_size, s if (id != ID_VOID && id != ID_CRC32) ctx->log(ctx, NESTEGG_LOG_DEBUG, "unknown element %llx in BlockMore", id); - ne_io_read_skip(ctx->io, size); + r = ne_io_read_skip(ctx->io, size); + if (r != 1) { + free(data); + return r; + } } } @@ -1582,14 +1584,6 @@ ne_find_cue_point_for_tstamp(nestegg * ctx, struct ebml_list_node * cue_point, u return prev; } -static int -ne_is_suspend_element(uint64_t id) -{ - if (id == ID_SIMPLE_BLOCK || id == ID_BLOCK_GROUP) - return 1; - return 0; -} - static void ne_null_log_callback(nestegg * ctx, unsigned int severity, char const * fmt, ...) { @@ -1634,7 +1628,7 @@ ne_init_cue_points(nestegg * ctx, int64_t max_offset) if (id != ID_CUES) return -1; - ctx->ancestor = NULL; + assert(ctx->ancestor == NULL); if (ne_ctx_push(ctx, ne_top_level_elements, ctx) < 0) return -1; if (ne_ctx_push(ctx, ne_segment_elements, &ctx->segment) < 0) @@ -1764,6 +1758,8 @@ ne_match_webm(nestegg_io io, int64_t max_offset) max_offset is not on a valid element end point. We only want to check the EBML ID and that the doctype is "webm". */ ne_parse(ctx, NULL, max_offset); + while (ctx->ancestor) + ne_ctx_pop(ctx); if (ne_get_string(ctx->ebml.doctype, &doctype) != 0 || strcmp(doctype, "webm") != 0) { @@ -1824,6 +1820,8 @@ nestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback, int64_t ma ne_ctx_push(ctx, ne_top_level_elements, ctx); r = ne_parse(ctx, NULL, max_offset); + while (ctx->ancestor) + ne_ctx_pop(ctx); if (r != 1) { nestegg_destroy(ctx); @@ -1864,6 +1862,12 @@ nestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback, int64_t ma track = track->next; } + r = ne_ctx_save(ctx, &ctx->saved); + if (r != 0) { + nestegg_destroy(ctx); + return -1; + } + *context = ctx; return 0; @@ -1872,8 +1876,7 @@ nestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback, int64_t ma void nestegg_destroy(nestegg * ctx) { - while (ctx->ancestor) - ne_ctx_pop(ctx); + assert(ctx->ancestor == NULL); ne_pool_destroy(ctx->alloc_pool); free(ctx->io); free(ctx); @@ -1890,6 +1893,9 @@ nestegg_duration(nestegg * ctx, uint64_t * duration) tc_scale = ne_get_timecode_scale(ctx); + if (unscaled_duration < 0 || unscaled_duration > UINT64_MAX / tc_scale) + return -1; + *duration = (uint64_t) (unscaled_duration * tc_scale); return 0; } @@ -1993,16 +1999,7 @@ nestegg_offset_seek(nestegg * ctx, uint64_t offset) return -1; ctx->last_valid = 0; - while (ctx->ancestor) - ne_ctx_pop(ctx); - - ne_ctx_push(ctx, ne_top_level_elements, ctx); - ne_ctx_push(ctx, ne_segment_elements, &ctx->segment); - - ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cluster elements"); - r = ne_parse(ctx, NULL, -1); - if (r != 1) - return -1; + assert(ctx->ancestor == NULL); return 0; } @@ -2037,14 +2034,11 @@ nestegg_track_seek(nestegg * ctx, unsigned int track, uint64_t tstamp) if (ne_get_uint(pos->cluster_position, &seek_pos) != 0) return -1; - /* Seek and set up parser state for segment-level element (Cluster). */ + /* Seek to (we assume) the start of a Cluster element. */ r = nestegg_offset_seek(ctx, ctx->segment_offset + seek_pos); if (r != 0) return -1; - if (!ne_is_suspend_element(ctx->last_id)) - return -1; - return 0; } @@ -2325,6 +2319,13 @@ nestegg_track_default_duration(nestegg * ctx, unsigned int track, return 0; } +int +nestegg_read_reset(nestegg * ctx) +{ + assert(ctx->ancestor == NULL); + return ne_ctx_restore(ctx, &ctx->saved); +} + int nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt) { @@ -2333,106 +2334,131 @@ nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt) *pkt = NULL; - for (;;) { - r = ne_peek_element(ctx, &id, &size); + assert(ctx->ancestor == NULL); + + /* Prepare for read_reset to resume parsing from this point upon error. */ + r = ne_ctx_save(ctx, &ctx->saved); + if (r != 0) + return -1; + + while (!read_block) { + r = ne_read_element(ctx, &id, &size); if (r != 1) return r; - /* Any DESC_FLAG_SUSPEND fields must be handled here. */ - if (ne_is_suspend_element(id)) { + switch (id) { + case ID_CLUSTER: { r = ne_read_element(ctx, &id, &size); if (r != 1) return r; - /* The only DESC_FLAG_SUSPEND fields are BlocksGroups and SimpleBlocks, which we - handle directly. */ - if (id == ID_SIMPLE_BLOCK) { - r = ne_read_block(ctx, id, size, pkt); + /* Timecode must be the first element in a Cluster, per spec. */ + if (id != ID_TIMECODE) + return -1; + + r = ne_read_uint(ctx->io, &ctx->cluster_timecode, size); + if (r != 1) + return r; + ctx->read_cluster_timecode = 1; + break; + } + case ID_SIMPLE_BLOCK: + r = ne_read_block(ctx, id, size, pkt); + if (r != 1) + return r; + + read_block = 1; + break; + case ID_BLOCK_GROUP: { + int64_t block_group_end; + uint64_t block_duration = 0; + int read_block_duration = 0; + int64_t discard_padding = 0; + int read_discard_padding = 0; + int64_t reference_block = 0; + int read_reference_block = 0; + struct block_additional * block_additional = NULL; + + block_group_end = ne_io_tell(ctx->io) + size; + + /* Read the entire BlockGroup manually. */ + while (ne_io_tell(ctx->io) < block_group_end) { + r = ne_read_element(ctx, &id, &size); if (r != 1) return r; - read_block = 1; - } else { - int64_t block_group_end; - uint64_t block_duration = 0; - int read_block_duration = 0; - int64_t discard_padding = 0; - int read_discard_padding = 0; - struct block_additional * block_additional = NULL; - - assert(id == ID_BLOCK_GROUP); - - /* This makes ne_read_element read the next element instead of returning - information about the already "peeked" one. */ - ctx->last_valid = 0; - - block_group_end = ne_io_tell(ctx->io) + size; - - /* Read the entire BlockGroup manually. */ - while (ne_io_tell(ctx->io) < block_group_end) { - r = ne_read_element(ctx, &id, &size); + switch (id) { + case ID_BLOCK: { + r = ne_read_block(ctx, id, size, pkt); if (r != 1) return r; - switch (id) { - case ID_BLOCK: { - r = ne_read_block(ctx, id, size, pkt); - if (r != 1) - return r; - - read_block = 1; - break; - } - case ID_BLOCK_DURATION: { - r = ne_read_uint(ctx->io, &block_duration, size); - if (r < 0) - return r; - block_duration *= ne_get_timecode_scale(ctx); - read_block_duration = 1; - break; - } - case ID_DISCARD_PADDING: { - r = ne_read_int(ctx->io, &discard_padding, size); - if (r < 0) - return r; - read_discard_padding = 1; - break; - } - case ID_BLOCK_ADDITIONS: { - r = ne_read_block_additions(ctx, id, size, &block_additional); - if (r < 0) - return r; - break; - } - default: - /* We don't know what this element is, so skip over it */ - if (id != ID_VOID && id != ID_CRC32) - ctx->log(ctx, NESTEGG_LOG_DEBUG, - "unknown element %llx in BlockGroup", id); - ne_io_read_skip(ctx->io, size); - } + read_block = 1; + break; } - - assert(read_block == (pkt != NULL)); - if (*pkt) { - (*pkt)->duration = block_duration; - (*pkt)->read_duration = read_block_duration; - (*pkt)->discard_padding = discard_padding; - (*pkt)->read_discard_padding = read_discard_padding; - (*pkt)->block_additional = block_additional; - } else { - free(block_additional); + case ID_BLOCK_DURATION: { + r = ne_read_uint(ctx->io, &block_duration, size); + if (r != 1) + return r; + block_duration *= ne_get_timecode_scale(ctx); + read_block_duration = 1; + break; + } + case ID_DISCARD_PADDING: { + r = ne_read_int(ctx->io, &discard_padding, size); + if (r != 1) + return r; + read_discard_padding = 1; + break; + } + case ID_BLOCK_ADDITIONS: { + r = ne_read_block_additions(ctx, size, &block_additional); + if (r != 1) + return r; + break; + } + case ID_REFERENCE_BLOCK: { + r = ne_read_int(ctx->io, &reference_block, size); + if (r != 1) + return r; + read_reference_block = 1; + break; + } + default: + /* We don't know what this element is, so skip over it */ + if (id != ID_VOID && id != ID_CRC32) + ctx->log(ctx, NESTEGG_LOG_DEBUG, + "read_packet: unknown element %llx in BlockGroup", id); + r = ne_io_read_skip(ctx->io, size); + if (r != 1) + return r; } } - /* If we have read a block and hit EOS when reading optional block - subelements, don't report EOS until the next call. */ - return read_block; + assert(read_block == (*pkt != NULL)); + if (*pkt) { + (*pkt)->duration = block_duration; + (*pkt)->read_duration = read_block_duration; + (*pkt)->discard_padding = discard_padding; + (*pkt)->read_discard_padding = read_discard_padding; + (*pkt)->reference_block = reference_block; + (*pkt)->read_reference_block = read_reference_block; + (*pkt)->block_additional = block_additional; + if ((*pkt)->read_reference_block) + /* If a packet has a reference block it contains + predictive frames and no keyframes */ + (*pkt)->keyframe = NESTEGG_PACKET_HAS_KEYFRAME_FALSE; + } else { + free(block_additional); + } + break; + } + default: + ctx->log(ctx, NESTEGG_LOG_DEBUG, "read_packet: unknown element %llx", id); + r = ne_io_read_skip(ctx->io, size); + if (r != 1) + return r; } - - r = ne_parse(ctx, NULL, -1); - if (r != 1) - return r; } return 1; @@ -2461,6 +2487,12 @@ nestegg_free_packet(nestegg_packet * pkt) free(pkt); } +int +nestegg_packet_has_keyframe(nestegg_packet * pkt) +{ + return pkt->keyframe; +} + int nestegg_packet_track(nestegg_packet * pkt, unsigned int * track) { @@ -2493,6 +2525,15 @@ nestegg_packet_discard_padding(nestegg_packet * pkt, int64_t * discard_padding) return 0; } +int +nestegg_packet_reference_block(nestegg_packet * pkt, int64_t * reference_block) +{ + if (!pkt->read_reference_block) + return -1; + *reference_block = pkt->reference_block; + return 0; +} + int nestegg_packet_count(nestegg_packet * pkt, unsigned int * count) { diff --git a/media/libnestegg/update.sh b/media/libnestegg/update.sh index 48966498f350..2d97f3eaec48 100755 --- a/media/libnestegg/update.sh +++ b/media/libnestegg/update.sh @@ -24,5 +24,4 @@ if [ -n "$rev" ]; then else echo "Remember to update README_MOZILLA with the version details." fi -patch -p3 < ./bug1271866.patch diff --git a/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp b/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp index 315e18e74dd6..7b37b61ab4ae 100644 --- a/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp +++ b/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp @@ -942,9 +942,8 @@ MediaPipelineFactory::EnsureExternalCodec(VideoSessionConduit& aConduit, encoder = MediaCodecVideoCodec::CreateEncoder(MediaCodecVideoCodec::CodecType::CODEC_VP8); if (encoder) { return aConduit.SetExternalSendCodec(aConfig, encoder); - } else { - return kMediaConduitNoError; } + return kMediaConduitNoError; } } } @@ -968,9 +967,8 @@ MediaPipelineFactory::EnsureExternalCodec(VideoSessionConduit& aConduit, decoder = MediaCodecVideoCodec::CreateDecoder(MediaCodecVideoCodec::CodecType::CODEC_VP8); if (decoder) { return aConduit.SetExternalRecvCodec(aConfig, decoder); - } else { - return kMediaConduitNoError; } + return kMediaConduitNoError; } } } @@ -978,9 +976,11 @@ MediaPipelineFactory::EnsureExternalCodec(VideoSessionConduit& aConduit, } #endif return kMediaConduitNoError; - } else if (aConfig->mName == "VP9") { + } + if (aConfig->mName == "VP9") { return kMediaConduitNoError; - } else if (aConfig->mName == "H264") { + } + if (aConfig->mName == "H264") { if (aConduit.CodecPluginID() != 0) { return kMediaConduitNoError; } @@ -995,32 +995,25 @@ MediaPipelineFactory::EnsureExternalCodec(VideoSessionConduit& aConduit, #endif if (encoder) { return aConduit.SetExternalSendCodec(aConfig, encoder); - } else { - return kMediaConduitInvalidSendCodec; - } - } else { - VideoDecoder* decoder = nullptr; -#ifdef MOZ_WEBRTC_OMX - decoder = - OMXVideoCodec::CreateDecoder(OMXVideoCodec::CodecType::CODEC_H264); -#else - decoder = GmpVideoCodec::CreateDecoder(); -#endif - if (decoder) { - return aConduit.SetExternalRecvCodec(aConfig, decoder); - } else { - return kMediaConduitInvalidReceiveCodec; } + return kMediaConduitInvalidSendCodec; } - NS_NOTREACHED("Shouldn't get here!"); - } else { - MOZ_MTLOG(ML_ERROR, - "Invalid video codec configured: " << aConfig->mName.c_str()); - return aIsSend ? kMediaConduitInvalidSendCodec - : kMediaConduitInvalidReceiveCodec; + VideoDecoder* decoder = nullptr; +#ifdef MOZ_WEBRTC_OMX + decoder = + OMXVideoCodec::CreateDecoder(OMXVideoCodec::CodecType::CODEC_H264); +#else + decoder = GmpVideoCodec::CreateDecoder(); +#endif + if (decoder) { + return aConduit.SetExternalRecvCodec(aConfig, decoder); + } + return kMediaConduitInvalidReceiveCodec; } - - NS_NOTREACHED("Shouldn't get here!"); + MOZ_MTLOG(ML_ERROR, + "Invalid video codec configured: " << aConfig->mName.c_str()); + return aIsSend ? kMediaConduitInvalidSendCodec + : kMediaConduitInvalidReceiveCodec; } } // namespace mozilla diff --git a/mobile/android/base/java/org/mozilla/gecko/CrashReporter.java b/mobile/android/base/java/org/mozilla/gecko/CrashReporter.java index 087163d1f713..ce2384a4d4d4 100644 --- a/mobile/android/base/java/org/mozilla/gecko/CrashReporter.java +++ b/mobile/android/base/java/org/mozilla/gecko/CrashReporter.java @@ -46,6 +46,7 @@ public class CrashReporter extends AppCompatActivity private static final String LOGTAG = "GeckoCrashReporter"; private static final String PASSED_MINI_DUMP_KEY = "minidumpPath"; + private static final String PASSED_MINI_DUMP_SUCCESS_KEY = "minidumpSuccess"; private static final String MINI_DUMP_PATH_KEY = "upload_file_minidump"; private static final String PAGE_URL_KEY = "URL"; private static final String NOTES_KEY = "Notes"; @@ -65,6 +66,7 @@ public class CrashReporter extends AppCompatActivity private File mPendingMinidumpFile; private File mPendingExtrasFile; private HashMap mExtrasStringMap; + private boolean mMinidumpSucceeded; private boolean moveFile(File inFile, File outFile) { Log.i(LOGTAG, "moving " + inFile + " to " + outFile); @@ -121,6 +123,10 @@ public class CrashReporter extends AppCompatActivity mProgressDialog = new ProgressDialog(this); mProgressDialog.setMessage(getString(R.string.sending_crash_report)); + mMinidumpSucceeded = getIntent().getBooleanExtra(PASSED_MINI_DUMP_SUCCESS_KEY, false); + if (!mMinidumpSucceeded) { + Log.i(LOGTAG, "Failed to get minidump."); + } String passedMinidumpPath = getIntent().getStringExtra(PASSED_MINI_DUMP_KEY); File passedMinidumpFile = new File(passedMinidumpPath); File pendingDir = new File(getFilesDir(), PENDING_SUFFIX); @@ -422,6 +428,7 @@ public class CrashReporter extends AppCompatActivity sendPart(os, boundary, "Email", email); } + sendPart(os, boundary, PASSED_MINI_DUMP_SUCCESS_KEY, mMinidumpSucceeded ? "True" : "False"); sendFile(os, boundary, MINI_DUMP_PATH_KEY, minidumpFile); os.write(("\r\n--" + boundary + "--\r\n").getBytes()); os.flush(); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 8994d93b0b7d..48ecdfc6305b 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -318,6 +318,7 @@ pref("media.wmf.decoder.thread-count", -1); pref("media.wmf.low-latency.enabled", false); pref("media.wmf.skip-blacklist", false); pref("media.windows-media-foundation.allow-d3d11-dxva", true); +pref("media.wmf.disable-d3d11-for-dlls", "igd10iumd32.dll: 20.19.15.4444, 20.19.15.4424, 20.19.15.4409, 20.19.15.4380, 20.19.15.4360, 20.19.15.4390, 20.19.15.4331, 10.18.15.4281, 10.18.15.4279, 10.18.15.4256, 10.18.10.4358, 10.18.10.4276, 10.18.10.4252, 10.18.14.4112, 10.18.10.3496, 10.18.10.3308; igd10umd32.dll: 9.17.10.4229, 9.17.10.2857; igd10umd64.dll: 9.17.10.4229; isonyvideoprocessor.dll: 4.1.2247.8090, 4.1.2153.6200; tosqep.dll: 1.2.15.526, 1.1.12.201, 1.0.11.318, 1.0.11.215, 1.0.10.1224; tosqep64.dll: 1.1.12.201, 1.0.11.215"); #endif #if defined(MOZ_FFMPEG) #if defined(XP_MACOSX) diff --git a/netwerk/base/nsDirectoryIndexStream.cpp b/netwerk/base/nsDirectoryIndexStream.cpp index 135a11d1de4d..87a57fd579c2 100644 --- a/netwerk/base/nsDirectoryIndexStream.cpp +++ b/netwerk/base/nsDirectoryIndexStream.cpp @@ -269,24 +269,28 @@ nsDirectoryIndexStream::Read(char* aBuf, uint32_t aCount, uint32_t* aReadCount) mBuf.AppendLiteral("201: "); // The "filename" field - char* escaped = nullptr; if (!NS_IsNativeUTF8()) { nsAutoString leafname; rv = current->GetLeafName(leafname); if (NS_FAILED(rv)) return rv; - if (!leafname.IsEmpty()) - escaped = nsEscape(NS_ConvertUTF16toUTF8(leafname).get(), url_Path); + + nsAutoCString escaped; + if (!leafname.IsEmpty() && + NS_Escape(NS_ConvertUTF16toUTF8(leafname), escaped, url_Path)) { + mBuf.Append(escaped); + mBuf.Append(' '); + } } else { nsAutoCString leafname; rv = current->GetNativeLeafName(leafname); if (NS_FAILED(rv)) return rv; - if (!leafname.IsEmpty()) - escaped = nsEscape(leafname.get(), url_Path); - } - if (escaped) { - mBuf += escaped; - mBuf.Append(' '); - free(escaped); + + nsAutoCString escaped; + if (!leafname.IsEmpty() && + NS_Escape(leafname, escaped, url_Path)) { + mBuf.Append(escaped); + mBuf.Append(' '); + } } // The "content-length" field diff --git a/netwerk/streamconv/converters/nsFTPDirListingConv.cpp b/netwerk/streamconv/converters/nsFTPDirListingConv.cpp index f639f318c8dd..4e8ca96a422e 100644 --- a/netwerk/streamconv/converters/nsFTPDirListingConv.cpp +++ b/netwerk/streamconv/converters/nsFTPDirListingConv.cpp @@ -307,9 +307,9 @@ nsFTPDirListingConv::DigestBufferLines(char *aBuffer, nsCString &aString) { PR_FormatTimeUSEnglish(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S", &result.fe_time ); - char *escapedDate = nsEscape(buffer, url_Path); - aString.Append(escapedDate); - free(escapedDate); + nsAutoCString escaped; + NS_WARN_IF(!NS_Escape(nsDependentCString(buffer), escaped, url_Path)); + aString.Append(escaped); aString.Append(' '); // ENTRY TYPE diff --git a/netwerk/system/linux/nsNotifyAddrListener_Linux.cpp b/netwerk/system/linux/nsNotifyAddrListener_Linux.cpp index 6fd6faf2c608..ec478153b5ef 100644 --- a/netwerk/system/linux/nsNotifyAddrListener_Linux.cpp +++ b/netwerk/system/linux/nsNotifyAddrListener_Linux.cpp @@ -143,11 +143,11 @@ void nsNotifyAddrListener::calculateNetworkId(void) if (gw) { /* create a string to search for in the arp table */ char searchfor[16]; - sprintf(searchfor, "%d.%d.%d.%d", - gw & 0xff, - (gw >> 8) & 0xff, - (gw >> 16) & 0xff, - gw >> 24); + snprintf(searchfor, sizeof(searchfor), "%d.%d.%d.%d", + gw & 0xff, + (gw >> 8) & 0xff, + (gw >> 16) & 0xff, + gw >> 24); FILE *farp = fopen(kProcArp, "r"); if (farp) { diff --git a/old-configure.in b/old-configure.in index a267c8f786b6..bfc46b52c644 100644 --- a/old-configure.in +++ b/old-configure.in @@ -1378,9 +1378,15 @@ case "$target" in CFLAGS="$CFLAGS -W3 -Gy" CXXFLAGS="$CXXFLAGS -W3 -Gy" if test "$CPU_ARCH" = "x86"; then - dnl VS2012+ defaults to -arch:SSE2. - CFLAGS="$CFLAGS -arch:IA32" - CXXFLAGS="$CXXFLAGS -arch:IA32" + dnl VS2012+ defaults to -arch:SSE2. We want to target nothing + dnl more recent, so set that explicitly here unless another + dnl target arch has already been set. + if test -z `echo $CFLAGS | grep -i [-/]arch:`; then + CFLAGS="$CFLAGS -arch:SSE2" + fi + if test -z `echo $CXXFLAGS | grep -i [-/]arch:`; then + CXXFLAGS="$CXXFLAGS -arch:SSE2" + fi SSE_FLAGS="-arch:SSE" SSE2_FLAGS="-arch:SSE2" dnl MSVC allows the use of intrinsics without any flags diff --git a/python/mozlint/mozlint/roller.py b/python/mozlint/mozlint/roller.py index 04567dd937fb..982617e62320 100644 --- a/python/mozlint/mozlint/roller.py +++ b/python/mozlint/mozlint/roller.py @@ -25,8 +25,13 @@ def _run_linters(queue, paths, **lintargs): while True: try: + # The astute reader may wonder what is preventing the worker from + # grabbing the next linter from the queue after a SIGINT. Because + # this is a Manager.Queue(), it is itself in a child process which + # also received SIGINT. By the time the worker gets back here, the + # Queue is dead and IOError is raised. linter_path = queue.get(False) - except Empty: + except (Empty, IOError): return results # Ideally we would pass the entire LINTER definition as an argument @@ -47,7 +52,9 @@ def _run_linters(queue, paths, **lintargs): def _run_worker(*args, **lintargs): try: return _run_linters(*args, **lintargs) - except: + except Exception: + # multiprocessing seems to munge worker exceptions, print + # it here so it isn't lost. traceback.print_exc() raise @@ -96,21 +103,21 @@ class LintRoller(object): num_procs = num_procs or cpu_count() num_procs = min(num_procs, len(self.linters)) - - # ensure child processes ignore SIGINT so it reaches parent - orig = signal.signal(signal.SIGINT, signal.SIG_IGN) pool = Pool(num_procs) - signal.signal(signal.SIGINT, orig) all_results = defaultdict(list) - results = [] + workers = [] for i in range(num_procs): - results.append( + workers.append( pool.apply_async(_run_worker, args=(queue, paths), kwds=self.lintargs)) + pool.close() - for res in results: - # parent process blocks on res.get() - for k, v in res.get().iteritems(): + # ignore SIGINT in parent so we can still get partial results + # from child processes. These should shutdown quickly anyway. + signal.signal(signal.SIGINT, signal.SIG_IGN) + for worker in workers: + # parent process blocks on worker.get() + for k, v in worker.get().iteritems(): all_results[k].extend(v) return all_results diff --git a/python/mozlint/mozlint/types.py b/python/mozlint/mozlint/types.py index 15d73804d412..67e9dee9c6f3 100644 --- a/python/mozlint/mozlint/types.py +++ b/python/mozlint/mozlint/types.py @@ -38,10 +38,13 @@ class BaseType(object): return self._lint(paths, linter, **lintargs) errors = [] - for p in paths: - result = self._lint(p, linter, **lintargs) - if result: - errors.extend(result) + try: + for p in paths: + result = self._lint(p, linter, **lintargs) + if result: + errors.extend(result) + except KeyboardInterrupt: + pass return errors @abstractmethod diff --git a/rdf/datasource/nsFileSystemDataSource.cpp b/rdf/datasource/nsFileSystemDataSource.cpp index 4fb1d98bcb8e..5dbf4ed9ace7 100644 --- a/rdf/datasource/nsFileSystemDataSource.cpp +++ b/rdf/datasource/nsFileSystemDataSource.cpp @@ -1007,16 +1007,14 @@ FileSystemDataSource::GetFolderList(nsIRDFResource *source, bool allowHidden, fullURI.Append('/'); } - char *escLeafStr = nsEscape(NS_ConvertUTF16toUTF8(leafStr).get(), url_Path); + nsAutoCString leaf; + bool escaped = NS_Escape(NS_ConvertUTF16toUTF8(leafStr), leaf, url_Path); leafStr.Truncate(); - if (!escLeafStr) + if (!escaped) { continue; + } - nsAutoCString leaf(escLeafStr); - free(escLeafStr); - escLeafStr = nullptr; - // using nsEscape() [above] doesn't escape slashes, so do that by hand int32_t aOffset; while ((aOffset = leaf.FindChar('/')) >= 0) diff --git a/security/sandbox/win/wow_helper/Makefile.in b/security/sandbox/win/wow_helper/Makefile.in index 44cad8f7964e..aee81f3fe469 100644 --- a/security/sandbox/win/wow_helper/Makefile.in +++ b/security/sandbox/win/wow_helper/Makefile.in @@ -32,7 +32,7 @@ include $(topsrcdir)/config/config.mk # compiler path above. LIB = $(call lazy,LIB,$$(shell python -c 'import os; print ";".join(s.lower().replace(os.sep, "/").replace("/vc/lib", "/vc/lib/amd64").replace("/um/x86", "/um/x64").replace("/ucrt/x86", "/ucrt/x64") for s in os.environ["LIB"].split(";"))')) -CXXFLAGS := $(filter-out -arch:IA32,$(CXXFLAGS)) +CXXFLAGS := $(filter-out -arch:%,$(CXXFLAGS)) # OS_COMPILE_CXXFLAGS includes mozilla-config.h, which contains x86-specific # defines breaking the build. diff --git a/startupcache/StartupCacheUtils.cpp b/startupcache/StartupCacheUtils.cpp index 120978c2bb10..d56066cb3965 100644 --- a/startupcache/StartupCacheUtils.cpp +++ b/startupcache/StartupCacheUtils.cpp @@ -236,7 +236,6 @@ PathifyURI(nsIURI *in, nsACString &out) out.Append('/'); out.Append(path); } else { // Very unlikely - nsAutoCString spec; rv = uri->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); diff --git a/taskcluster/mach_commands.py b/taskcluster/mach_commands.py index 733b9a502267..8e59c175fe2e 100644 --- a/taskcluster/mach_commands.py +++ b/taskcluster/mach_commands.py @@ -6,6 +6,7 @@ from __future__ import absolute_import, print_function, unicode_literals +import logging import sys import traceback @@ -27,6 +28,10 @@ class ShowTaskGraphSubCommand(SubCommand): args = [ CommandArgument('--root', '-r', default='taskcluster/ci', help="root of the taskgraph definition relative to topsrcdir"), + CommandArgument('--quiet', '-q', action="store_true", + help="suppress all logging output"), + CommandArgument('--verbose', '-v', action="store_true", + help="include debug-level logging output"), CommandArgument('--parameters', '-p', required=True, help="parameters file (.yml or .json; see " "`taskcluster/docs/parameters.rst`)`"), @@ -137,24 +142,44 @@ class MachCommands(MachCommandBase): import taskgraph.decision try: - return taskgraph.decision.taskgraph_decision(self.log, options) + self.setup_logging() + return taskgraph.decision.taskgraph_decision(options) except Exception as e: traceback.print_exc() sys.exit(1) + + def setup_logging(self, quiet=False, verbose=True): + """ + Set up Python logging for all loggers, sending results to stderr (so + that command output can be redirected easily) and adding the typical + mach timestamp. + """ + # remove the old terminal handler + self.log_manager.replace_terminal_handler(None) + + # re-add it, with level and fh set appropriately + if not quiet: + level = logging.DEBUG if verbose else logging.INFO + self.log_manager.add_terminal_logging(fh=sys.stderr, level=level) + + # all of the taskgraph logging is unstructured logging + self.log_manager.enable_unstructured() + + def show_taskgraph(self, graph_attr, options): import taskgraph.parameters import taskgraph.target_tasks import taskgraph.generator try: + self.setup_logging(quiet=options['quiet'], verbose=options['verbose']) parameters = taskgraph.parameters.load_parameters_file(options) target_tasks_method = parameters.get('target_tasks_method', 'all_tasks') target_tasks_method = taskgraph.target_tasks.get_method(target_tasks_method) tgg = taskgraph.generator.TaskGraphGenerator( root_dir=options['root'], - log=self.log, parameters=parameters, target_tasks_method=target_tasks_method) diff --git a/taskcluster/taskgraph/create.py b/taskcluster/taskgraph/create.py index bda9a1498a80..8984e947db6f 100644 --- a/taskcluster/taskgraph/create.py +++ b/taskcluster/taskgraph/create.py @@ -7,9 +7,12 @@ from __future__ import absolute_import, print_function, unicode_literals import requests import json import collections +import logging from slugid import nice as slugid +logger = logging.getLogger(__name__) + def create_tasks(taskgraph): # TODO: use the taskGroupId of the decision task task_group_id = slugid() @@ -33,11 +36,11 @@ def create_tasks(taskgraph): def _create_task(session, task_id, label, task_def): # create the task using 'http://taskcluster/queue', which is proxied to the queue service # with credentials appropriate to this job. - print("Creating task with taskId {} for {}".format(task_id, label)) + logger.debug("Creating task with taskId {} for {}".format(task_id, label)) res = session.put('http://taskcluster/queue/v1/task/{}'.format(task_id), data=json.dumps(task_def)) if res.status_code != 200: try: - print(res.json()['message']) + logger.error(res.json()['message']) except: - print(res.text) + logger.error(res.text) res.raise_for_status() diff --git a/taskcluster/taskgraph/decision.py b/taskcluster/taskgraph/decision.py index 80ff6ce6bb8d..2509b45f3d92 100644 --- a/taskcluster/taskgraph/decision.py +++ b/taskcluster/taskgraph/decision.py @@ -13,13 +13,29 @@ import yaml from .generator import TaskGraphGenerator from .create import create_tasks -from .parameters import get_decision_parameters +from .parameters import Parameters from .target_tasks import get_method +logger = logging.getLogger(__name__) ARTIFACTS_DIR = 'artifacts' +logger = logging.getLogger(__name__) -def taskgraph_decision(log, options): +# For each project, this gives a set of parameters specific to the project. +# See `taskcluster/docs/parameters.rst` for information on parameters. +PER_PROJECT_PARAMETERS = { + 'try': { + 'target_tasks_method': 'try_option_syntax', + }, + + # the default parameters are used for projects that do not match above. + 'default': { + 'target_tasks_method': 'all_tasks', + } +} + + +def taskgraph_decision(options): """ Run the decision task. This function implements `mach taskgraph decision`, and is responsible for @@ -38,32 +54,60 @@ def taskgraph_decision(log, options): target_tasks_method = get_method(target_tasks_method) tgg = TaskGraphGenerator( root_dir=options['root'], - log=log, parameters=parameters, target_tasks_method=target_tasks_method) # write out the parameters used to generate this graph - write_artifact('parameters.yml', dict(**parameters), log) + write_artifact('parameters.yml', dict(**parameters)) # write out the full graph for reference write_artifact('full-task-graph.json', - taskgraph_to_json(tgg.full_task_graph), - log) + taskgraph_to_json(tgg.full_task_graph)) # write out the target task set to allow reproducing this as input write_artifact('target_tasks.json', - tgg.target_task_set.tasks.keys(), - log) + tgg.target_task_set.tasks.keys()) # write out the optimized task graph to describe what will happen write_artifact('task-graph.json', - taskgraph_to_json(tgg.optimized_task_graph), - log) + taskgraph_to_json(tgg.optimized_task_graph)) # actually create the graph create_tasks(tgg.optimized_task_graph) +def get_decision_parameters(options): + """ + Load parameters from the command-line options for 'taskgraph decision'. + This also applies per-project parameters, based on the given project. + + """ + parameters = {n: options[n] for n in [ + 'base_repository', + 'head_repository', + 'head_rev', + 'head_ref', + 'revision_hash', + 'message', + 'project', + 'pushlog_id', + 'owner', + 'level', + 'target_tasks_method', + ] if n in options} + + project = parameters['project'] + try: + parameters.update(PER_PROJECT_PARAMETERS[project]) + except KeyError: + logger.warning("using default project parameters; add {} to " + "PER_PROJECT_PARAMETERS in {} to customize behavior " + "for this project".format(project, __file__)) + parameters.update(PER_PROJECT_PARAMETERS['default']) + + return Parameters(parameters) + + def taskgraph_to_json(taskgraph): tasks = taskgraph.tasks @@ -82,10 +126,8 @@ def taskgraph_to_json(taskgraph): return rv -def write_artifact(filename, data, log): - log(logging.INFO, 'writing-artifact', { - 'filename': filename, - }, 'writing artifact file `{filename}`') +def write_artifact(filename, data): + logger.info('writing artifact file `{}`'.format(filename)) if not os.path.isdir(ARTIFACTS_DIR): os.mkdir(ARTIFACTS_DIR) path = os.path.join(ARTIFACTS_DIR, filename) diff --git a/taskcluster/taskgraph/generator.py b/taskcluster/taskgraph/generator.py index f5af1c885ff8..299462099cf8 100644 --- a/taskcluster/taskgraph/generator.py +++ b/taskcluster/taskgraph/generator.py @@ -10,6 +10,8 @@ import yaml from .graph import Graph from .types import TaskGraph +logger = logging.getLogger(__name__) + class TaskGraphGenerator(object): """ The central controller for taskgraph. This handles all phases of graph @@ -25,11 +27,10 @@ class TaskGraphGenerator(object): # each "phase" of generation. This allows some mach subcommands to short- # circuit generation of the entire graph by never completing the generator. - def __init__(self, root_dir, log, parameters, + def __init__(self, root_dir, parameters, target_tasks_method): """ @param root_dir: root directory, with subdirectories for each kind - @param log: Mach log function @param parameters: parameters for this task-graph generation @type parameters: dict @param target_tasks_method: function to determine the target_task_set; @@ -38,7 +39,6 @@ class TaskGraphGenerator(object): """ self.root_dir = root_dir - self.log = log self.parameters = parameters self.target_tasks_method = target_tasks_method @@ -105,10 +105,7 @@ class TaskGraphGenerator(object): if not os.path.isdir(path): continue name = os.path.basename(path) - self.log(logging.DEBUG, 'loading-kind', { - 'name': name, - 'path': path, - }, "loading kind `{name}` from {path}") + logger.debug("loading kind `{}` from `{}`".format(name, path)) kind_yml = os.path.join(path, 'kind.yml') with open(kind_yml) as f: @@ -130,9 +127,10 @@ class TaskGraphGenerator(object): for a in impl_object.split('.'): impl_class = getattr(impl_class, a) - yield impl_class(path, config, self.log) + yield impl_class(path, config) def _run(self): + logger.info("Generating full task set") all_tasks = {} for kind in self._load_kinds(): for task in kind.load_tasks(self.parameters): @@ -143,6 +141,7 @@ class TaskGraphGenerator(object): full_task_set = TaskGraph(all_tasks, Graph(set(all_tasks), set())) yield 'full_task_set', full_task_set + logger.info("Generating full task graph") edges = set() for t in full_task_set: for dep, depname in t.kind.get_task_dependencies(t, full_task_set): @@ -152,13 +151,14 @@ class TaskGraphGenerator(object): Graph(full_task_set.graph.nodes, edges)) yield 'full_task_graph', full_task_graph + logger.info("Generating target task set") target_tasks = set(self.target_tasks_method(full_task_graph, self.parameters)) - target_task_set = TaskGraph( {l: all_tasks[l] for l in target_tasks}, Graph(target_tasks, set())) yield 'target_task_set', target_task_set + logger.info("Generating target task graph") target_graph = full_task_graph.graph.transitive_closure(target_tasks) target_task_graph = TaskGraph( {l: all_tasks[l] for l in target_graph.nodes}, @@ -167,6 +167,7 @@ class TaskGraphGenerator(object): # optimization is not yet implemented + logger.info("Generating optimized task graph") yield 'optimized_task_graph', target_task_graph def _run_until(self, name): diff --git a/taskcluster/taskgraph/kind/base.py b/taskcluster/taskgraph/kind/base.py index 44f1d9d273d6..0d8810f24f90 100644 --- a/taskcluster/taskgraph/kind/base.py +++ b/taskcluster/taskgraph/kind/base.py @@ -16,11 +16,10 @@ class Kind(object): """ __metaclass__ = abc.ABCMeta - def __init__(self, path, config, log): + def __init__(self, path, config): self.name = os.path.basename(path) self.path = path self.config = config - self.log = log @abc.abstractmethod def load_tasks(self, parameters): diff --git a/taskcluster/taskgraph/kind/legacy.py b/taskcluster/taskgraph/kind/legacy.py index cc83921d3bc4..4fd0967d95e6 100644 --- a/taskcluster/taskgraph/kind/legacy.py +++ b/taskcluster/taskgraph/kind/legacy.py @@ -54,6 +54,8 @@ DEFAULT_JOB_PATH = os.path.join( # time after which a try build's results will expire TRY_EXPIRATION = "14 days" +logger = logging.getLogger(__name__) + def mklabel(): return TASKID_PLACEHOLDER.format(slugid()) @@ -108,13 +110,11 @@ class LegacyKind(base.Kind): if vcs_info: pushdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(vcs_info.pushdate)) - self.log(logging.DEBUG, 'vcs-info', {}, - '%d commits influencing task scheduling:\n' % len(vcs_info.changesets)) + logger.debug('{} commits influencing task scheduling:'.format(len(vcs_info.changesets))) for c in vcs_info.changesets: - self.log(logging.DEBUG, 'vcs-relevant-commit', { - 'cset': c['node'][0:12], - 'desc': c['desc'].splitlines()[0].encode('ascii', 'ignore'), - }, "{cset} {desc}") + logger.debug("{cset} {desc}".format( + cset=c['node'][0:12], + desc=c['desc'].splitlines()[0].encode('ascii', 'ignore'))) changed_files |= set(c['files']) # Template parameters used when expanding the graph @@ -190,20 +190,19 @@ class LegacyKind(base.Kind): for pattern in file_patterns: for path in changed_files: if mozpackmatch(path, pattern): - self.log(logging.DEBUG, 'schedule-task', { - 'schedule': True, + logger.debug('scheduling {task} because pattern {pattern} ' + 'matches {path}', format({ 'task': task['task'], 'pattern': pattern, 'path': path, - }, 'scheduling {task} because pattern {pattern} ' - 'matches {path}') + })) return True # No file patterns matched. Discard task. - self.log(logging.DEBUG, 'schedule-task', { - 'schedule': False, - 'task': task['task'], - }, 'discarding {task} because no relevant files changed') + logger.debug('discarding {task} because no relevant files changed'.format( + task=task['task'], + pattern=pattern, + path=path)) return False return True @@ -213,9 +212,7 @@ class LegacyKind(base.Kind): all_routes = {} for build in job_graph: - self.log(logging.DEBUG, 'load-task', { - 'task': build['task'], - }, 'loading task {task}') + logging.debug("loading build task {}".format(build['task'])) interactive = cmdline_interactive or build["interactive"] build_parameters = merge_dicts(parameters, build['additional-parameters']) build_parameters['build_slugid'] = mklabel() diff --git a/taskcluster/taskgraph/parameters.py b/taskcluster/taskgraph/parameters.py index 767dfb7b9687..15a8b655693b 100644 --- a/taskcluster/taskgraph/parameters.py +++ b/taskcluster/taskgraph/parameters.py @@ -34,21 +34,3 @@ def load_parameters_file(options): return Parameters(**json.load(f)) else: raise TypeError("Parameters file `{}` is not JSON or YAML".format(filename)) - -def get_decision_parameters(options): - """ - Load parameters from the command-line options for 'taskgraph decision'. - """ - return Parameters({n: options[n] for n in [ - 'base_repository', - 'head_repository', - 'head_rev', - 'head_ref', - 'revision_hash', - 'message', - 'project', - 'pushlog_id', - 'owner', - 'level', - 'target_tasks_method', - ] if n in options}) diff --git a/taskcluster/taskgraph/test/test_decision.py b/taskcluster/taskgraph/test/test_decision.py index a231c531816c..6d88b0149c79 100644 --- a/taskcluster/taskgraph/test/test_decision.py +++ b/taskcluster/taskgraph/test/test_decision.py @@ -47,7 +47,7 @@ class TestDecision(unittest.TestCase): tmpdir = tempfile.mkdtemp() try: decision.ARTIFACTS_DIR = os.path.join(tmpdir, "artifacts") - decision.write_artifact("artifact.json", data, lambda *args: None) + decision.write_artifact("artifact.json", data) with open(os.path.join(decision.ARTIFACTS_DIR, "artifact.json")) as f: self.assertEqual(json.load(f), data) finally: @@ -61,7 +61,7 @@ class TestDecision(unittest.TestCase): tmpdir = tempfile.mkdtemp() try: decision.ARTIFACTS_DIR = os.path.join(tmpdir, "artifacts") - decision.write_artifact("artifact.yml", data, lambda *args: None) + decision.write_artifact("artifact.yml", data) with open(os.path.join(decision.ARTIFACTS_DIR, "artifact.yml")) as f: self.assertEqual(yaml.safe_load(f), data) finally: diff --git a/taskcluster/taskgraph/test/test_generator.py b/taskcluster/taskgraph/test/test_generator.py index 30e2f000582c..c3ebf4254da9 100644 --- a/taskcluster/taskgraph/test/test_generator.py +++ b/taskcluster/taskgraph/test/test_generator.py @@ -43,13 +43,11 @@ class WithFakeKind(TaskGraphGenerator): class TestGenerator(unittest.TestCase): def setUp(self): - def log(level, name, data, message): - pass self.target_tasks = [] def target_tasks_method(full_task_graph, parameters): return self.target_tasks - self.tgg = WithFakeKind('/root', log, {}, target_tasks_method) + self.tgg = WithFakeKind('/root', {}, target_tasks_method) def test_full_task_set(self): "The full_task_set property has all tasks" diff --git a/taskcluster/taskgraph/test/test_kind_legacy.py b/taskcluster/taskgraph/test/test_kind_legacy.py index faa19f2754b2..f5debf86bfab 100644 --- a/taskcluster/taskgraph/test/test_kind_legacy.py +++ b/taskcluster/taskgraph/test/test_kind_legacy.py @@ -17,9 +17,7 @@ class TestLegacyKind(unittest.TestCase): # attempt to test the entire class. def setUp(self): - def log(level, name, data, message): - pass - self.kind = LegacyKind('/root', {}, log) + self.kind = LegacyKind('/root', {}) def test_get_task_definition_artifact_sub(self): "get_task_definition correctly substiatutes artifact URLs" diff --git a/testing/marionette/driver.js b/testing/marionette/driver.js index 57632e45846b..290ac5d0682d 100644 --- a/testing/marionette/driver.js +++ b/testing/marionette/driver.js @@ -2448,8 +2448,8 @@ GeckoDriver.prototype.setWindowSize = function(cmd, resp) { let height = parseInt(cmd.parameters.height); let win = this.getCurrentWindow(); - if (width >= win.screen.availWidth && height >= win.screen.availHeight) { - throw new UnsupportedOperationError("Invalid requested size, cannot maximize"); + if (width >= win.screen.availWidth || height >= win.screen.availHeight) { + throw new UnsupportedOperationError("Requested size exceeds screen size") } win.resizeTo(width, height); diff --git a/testing/marionette/harness/marionette/tests/unit/test_set_window_size.py b/testing/marionette/harness/marionette/tests/unit/test_set_window_size.py index c6609d77bb08..5ad678e08898 100644 --- a/testing/marionette/harness/marionette/tests/unit/test_set_window_size.py +++ b/testing/marionette/harness/marionette/tests/unit/test_set_window_size.py @@ -2,9 +2,10 @@ # 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/. -from marionette_driver.errors import MarionetteException +from marionette_driver.errors import UnsupportedOperationException from marionette import MarionetteTestCase + class TestSetWindowSize(MarionetteTestCase): def setUp(self): super(MarionetteTestCase, self).setUp() @@ -48,7 +49,7 @@ class TestSetWindowSize(MarionetteTestCase): height = self.max_height - 100 self.marionette.set_window_size(width, height) # invalid size (cannot maximize) - with self.assertRaisesRegexp(MarionetteException, "Invalid requested size"): + with self.assertRaisesRegexp(UnsupportedOperationException, "Requested size exceeds screen size"): self.marionette.set_window_size(self.max_width, self.max_height) size = self.marionette.window_size self.assertEqual(size['width'], width, "Window width should not have changed") diff --git a/testing/mochitest/mochitest_options.py b/testing/mochitest/mochitest_options.py index f94bc53591ed..3c1968b2e87b 100644 --- a/testing/mochitest/mochitest_options.py +++ b/testing/mochitest/mochitest_options.py @@ -789,12 +789,6 @@ class MochitestArguments(ArgumentContainer): if options.nested_oop: options.e10s = True - # a11y and chrome tests don't run with e10s enabled in CI - if options.a11y or options.chrome: - options.e10s = False - - mozinfo.update({"e10s": options.e10s}) # for test manifest parsing. - options.leakThresholds = { "default": options.defaultLeakThreshold, "tab": 10000, # See dependencies of bug 1051230. diff --git a/testing/mochitest/runtests.py b/testing/mochitest/runtests.py index 5fd38785d6e6..88d2bb5f94a6 100644 --- a/testing/mochitest/runtests.py +++ b/testing/mochitest/runtests.py @@ -2190,6 +2190,12 @@ class MochitestDesktop(MochitestBase): def runTests(self, options): """ Prepare, configure, run tests and cleanup """ + # a11y and chrome tests don't run with e10s enabled in CI. Need to set + # this here since |mach mochitest| sets the flavor after argument parsing. + if options.a11y or options.chrome: + options.e10s = False + mozinfo.update({"e10s": options.e10s}) # for test manifest parsing. + self.setTestRoot(options) # Despite our efforts to clean up servers started by this script, in practice diff --git a/testing/puppeteer/firefox/docs/index.rst b/testing/puppeteer/firefox/docs/index.rst index 8dba59ef2159..7e64a6ed2a98 100644 --- a/testing/puppeteer/firefox/docs/index.rst +++ b/testing/puppeteer/firefox/docs/index.rst @@ -32,6 +32,23 @@ In both cases all necessary files including all dependencies will be installed. .. _Python package: https://pypi.python.org/pypi/firefox-puppeteer .. _mozilla-central: https://hg.mozilla.org/mozilla-central +Versioning +---------- + +Puppeteer versions as regularly released from the Python source code, will follow +a specific versioning schema. It means the major version number will always +be identical with the supported Firefox version. Minor releases - the second part +of the version number - are done throughout the life-cycle of a Firefox version +when Puppeteer itself needs API changes for back-end and front-end modules. The +last part of the version number is the patch level, and is only used for bugfix +releases without any API changes. + +Examples: + + firefox_puppeteer_45.0.0 - First release for Firefox 45.0 and Firefox 45.xESR + firefox_puppeteer_46.2.0 - Second release for Firefox 46.0 caused by API changes + firefox_puppeteer_47.0.1 - First bugfix release for the new Firefox 47.0 support + Libraries --------- diff --git a/testing/talos/talos/pageloader/chrome/pageloader.js b/testing/talos/talos/pageloader/chrome/pageloader.js index 19607b2ec40e..e53ce2509f9c 100644 --- a/testing/talos/talos/pageloader/chrome/pageloader.js +++ b/testing/talos/talos/pageloader/chrome/pageloader.js @@ -254,6 +254,12 @@ function plInit() { browserWindow.focus(); content = browserWindow.getBrowser(); + if (content.selectedBrowser) { + content.selectedBrowser.focus(); + } else { + dump("WARNING: cannot focus content area\n"); + } + gUseE10S = !gDisableE10S || (plPageFlags() & EXECUTE_SCROLL_TEST) || (content.selectedBrowser && content.selectedBrowser.getAttribute("remote") == "true") diff --git a/testing/talos/talos/pageloader/install.rdf b/testing/talos/talos/pageloader/install.rdf index 95bc4ab8f452..352f1d8efc38 100644 --- a/testing/talos/talos/pageloader/install.rdf +++ b/testing/talos/talos/pageloader/install.rdf @@ -4,7 +4,7 @@ xmlns:em="http://www.mozilla.org/2004/em-rdf#"> pageloader@mozilla.org - 1.0.5 + 1.0.6 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} diff --git a/testing/talos/talos/pageloader/pageloader-signed.xpi b/testing/talos/talos/pageloader/pageloader-signed.xpi index 8d55f65cb9a7..7f4096adbdaa 100644 Binary files a/testing/talos/talos/pageloader/pageloader-signed.xpi and b/testing/talos/talos/pageloader/pageloader-signed.xpi differ diff --git a/testing/taskcluster/taskcluster_graph/image_builder.py b/testing/taskcluster/taskcluster_graph/image_builder.py index 3bb060c0d9ba..c2d6d03c18b0 100644 --- a/testing/taskcluster/taskcluster_graph/image_builder.py +++ b/testing/taskcluster/taskcluster_graph/image_builder.py @@ -221,6 +221,10 @@ def normalize_image_details(graph, task, seen_images, params, decision_task_id): get_json_routes(), image_parameters) + image_task['attributes'] = { + 'kind': 'legacy', + } + graph['tasks'].append(image_task); task['requires'].append(details['taskId']) diff --git a/testing/taskcluster/taskcluster_graph/mach_util.py b/testing/taskcluster/taskcluster_graph/mach_util.py index 35ea00056f72..b6436f1b5e28 100644 --- a/testing/taskcluster/taskcluster_graph/mach_util.py +++ b/testing/taskcluster/taskcluster_graph/mach_util.py @@ -10,11 +10,14 @@ import copy import re import sys import time +import logging from collections import namedtuple ROOT = os.path.dirname(os.path.realpath(__file__)) GECKO = os.path.realpath(os.path.join(ROOT, '..', '..', '..')) +logger = logging.getLogger(__name__) + def merge_dicts(*dicts): merged_dict = {} for dictionary in dicts: @@ -130,7 +133,7 @@ def query_vcs_info(repository, revision): similar. It may or may not work for other hg repositories. """ if not repository or not revision: - sys.stderr.write('cannot query vcs info because vcs info not provided\n') + logger.warning('cannot query vcs info because vcs info not provided') return None VCSInfo = namedtuple('VCSInfo', ['pushid', 'pushdate', 'changesets']) @@ -139,7 +142,7 @@ def query_vcs_info(repository, revision): import requests url = '%s/json-automationrelevance/%s' % (repository.rstrip('/'), revision) - sys.stderr.write("Querying version control for metadata: %s\n" % url) + logger.debug("Querying version control for metadata: %s" % url) contents = requests.get(url).json() changesets = [] @@ -152,8 +155,8 @@ def query_vcs_info(repository, revision): return VCSInfo(pushid, pushdate, changesets) except Exception: - sys.stderr.write( - "Error querying VCS info for '%s' revision '%s'\n" % ( + logger.exception( + "Error querying VCS info for '%s' revision '%s'" % ( repository, revision, ) ) diff --git a/testing/taskcluster/tasks/branches/base_jobs.yml b/testing/taskcluster/tasks/branches/base_jobs.yml index 1fe1edfce040..b1c0972cd567 100644 --- a/testing/taskcluster/tasks/branches/base_jobs.yml +++ b/testing/taskcluster/tasks/branches/base_jobs.yml @@ -49,6 +49,7 @@ builds: - Linux64 extra-builds: # see RIDEALONG_BUILDS in `mach taskgraph` - sm-plain + - sm-nonunified - sm-arm-sim - sm-compacting - sm-rootanalysis @@ -81,6 +82,10 @@ builds: types: debug: task: tasks/builds/haz_shell_linux.yml + when: + file_patterns: + - js/public/** + - js/src/** linux64-pgo: platforms: - Linux64 PGO @@ -119,6 +124,16 @@ builds: file_patterns: - js/public/** - js/src/** + sm-nonunified: + platforms: + - Linux64 + types: + debug: + task: tasks/builds/sm_nonunified.yml + when: + file_patterns: + - js/public/** + - js/src/** sm-arm-sim: platforms: - Linux64 diff --git a/testing/taskcluster/tasks/builds/sm_nonunified.yml b/testing/taskcluster/tasks/builds/sm_nonunified.yml new file mode 100644 index 000000000000..320d5201b966 --- /dev/null +++ b/testing/taskcluster/tasks/builds/sm_nonunified.yml @@ -0,0 +1,18 @@ +$inherits: + from: 'tasks/builds/sm_base.yml' + variables: + build_name: 'sm-nonunified' + build_type: 'debug' +task: + payload: + env: + SPIDERMONKEY_VARIANT: 'nonunified' + metadata: + name: '[TC] Spidermonkey Non-Unified Debug' + description: 'Spidermonkey Non-Unified Debug' + extra: + treeherder: + symbol: nu + collection: + debug: true + tier: 3 diff --git a/testing/taskcluster/tasks/tests/fx_test_base.yml b/testing/taskcluster/tasks/tests/fx_test_base.yml index c40a95d6b683..c4fe8fe52dd3 100644 --- a/testing/taskcluster/tasks/tests/fx_test_base.yml +++ b/testing/taskcluster/tasks/tests/fx_test_base.yml @@ -15,6 +15,7 @@ task: NEED_PULSEAUDIO: true GECKO_HEAD_REPOSITORY: '{{{head_repository}}}' GECKO_HEAD_REV: '{{{head_rev}}}' + MOZ_NODE_PATH: '/usr/local/bin/node' cache: # put the workspace and /tmp on a cache, less for inter-task caching than diff --git a/toolkit/content/TopLevelVideoDocument.js b/toolkit/content/TopLevelVideoDocument.js index 0642da258d0e..5a2b8a857c44 100644 --- a/toolkit/content/TopLevelVideoDocument.js +++ b/toolkit/content/TopLevelVideoDocument.js @@ -29,10 +29,10 @@ document.addEventListener("keypress", ev => { ev.preventDefault(); ev.stopPropagation(); - if (!document.fullscreenElement) { - videoElement.requestFullscreen(); + if (!document.mozFullScreenElement) { + videoElement.mozRequestFullScreen(); } else { - document.exitFullscreen(); + document.mozCancelFullScreen(); } return; } diff --git a/toolkit/content/tests/widgets/test_videocontrols.html b/toolkit/content/tests/widgets/test_videocontrols.html index 2e4954a9ee51..1901bdd93568 100644 --- a/toolkit/content/tests/widgets/test_videocontrols.html +++ b/toolkit/content/tests/widgets/test_videocontrols.html @@ -304,7 +304,7 @@ function runTest(event) { break; case 24: - is(event.type, "fullscreenchange", "checking event type"); + is(event.type, "mozfullscreenchange", "checking event type"); is(video.volume, 0.6, "Volume should still be 0.6"); isVolumeSliderShowingCorrectVolume(video.volume); @@ -312,7 +312,7 @@ function runTest(event) { break; case 25: - is(event.type, "fullscreenchange", "checking event type"); + is(event.type, "mozfullscreenchange", "checking event type"); is(video.volume, 0.6, "Volume should still be 0.6"); isVolumeSliderShowingCorrectVolume(video.volume); @@ -336,7 +336,7 @@ function canplaythroughevent(event) { video.addEventListener("volumechange", runTest, false); video.addEventListener("seeking", runTest, false); video.addEventListener("seeked", runTest, false); - document.addEventListener("fullscreenchange", runTest, false); + document.addEventListener("mozfullscreenchange", runTest, false); // Begin the test. runTest(event); } diff --git a/toolkit/content/widgets/videocontrols.xml b/toolkit/content/widgets/videocontrols.xml index 56adea744080..3cbe71edb5d1 100644 --- a/toolkit/content/widgets/videocontrols.xml +++ b/toolkit/content/widgets/videocontrols.xml @@ -1007,7 +1007,7 @@ } else { element.setAttribute("fadeout", true); if (element.classList.contains("controlBar") && !this.hasError() && - document.fullscreenElement == this.video) + document.mozFullScreenElement == this.video) this.controlsSpacer.setAttribute("hideCursor", true); } @@ -1065,17 +1065,17 @@ }, isVideoInFullScreen : function () { - return document.fullscreenElement == this.video; + return document.mozFullScreenElement == this.video; }, toggleFullscreen : function () { this.isVideoInFullScreen() ? - document.exitFullscreen() : - this.video.requestFullscreen(); + document.mozCancelFullScreen() : + this.video.mozRequestFullScreen(); }, setFullscreenButtonState : function () { - if (this.isAudioOnly || !document.fullscreenEnabled) { + if (this.isAudioOnly || !document.mozFullScreenEnabled) { this.controlBar.setAttribute("fullscreen-unavailable", true); this.adjustControlSize(); return; @@ -1525,7 +1525,7 @@ addListener(this.videocontrols, "resizevideocontrols", this.adjustControlSize); addListener(this.videocontrols, "transitionend", this.onTransitionEnd); - addListener(this.video.ownerDocument, "fullscreenchange", this.onFullscreenChange); + addListener(this.video.ownerDocument, "mozfullscreenchange", this.onFullscreenChange); addListener(this.video, "keypress", this.keyHandler); addListener(this.videocontrols, "dragstart", function(event) { diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp b/toolkit/crashreporter/nsExceptionHandler.cpp index db79bbc36451..02d190058fd2 100644 --- a/toolkit/crashreporter/nsExceptionHandler.cpp +++ b/toolkit/crashreporter/nsExceptionHandler.cpp @@ -344,7 +344,7 @@ nsTArray >* gDelayedAnnotations; #if defined(XP_WIN) // the following are used to prevent other DLLs reverting the last chance -// exception handler to the windows default. Any attempt to change the +// exception handler to the windows default. Any attempt to change the // unhandled exception filter or to reset it is ignored and our crash // reporter is loaded instead (in case it became unloaded somehow) typedef LPTOP_LEVEL_EXCEPTION_FILTER (WINAPI *SetUnhandledExceptionFilter_func) @@ -1103,6 +1103,7 @@ bool MinidumpCallback( "-a", "org.mozilla.gecko.reportCrash", "-n", crashReporterPath, "--es", "minidumpPath", minidumpPath, + "--ez", "minidumpSuccess", succeeded ? "true" : "false", (char*)0); } else { Unused << execlp("/system/bin/am", @@ -1111,6 +1112,7 @@ bool MinidumpCallback( "-a", "org.mozilla.gecko.reportCrash", "-n", crashReporterPath, "--es", "minidumpPath", minidumpPath, + "--ez", "minidumpSuccess", succeeded ? "true" : "false", (char*)0); } #endif @@ -1618,7 +1620,7 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory, #ifdef XP_WIN gExceptionHandler->set_handle_debug_exceptions(true); - + #ifdef _WIN64 // Tell JS about the new filter before we disable SetUnhandledExceptionFilter sUnhandledExceptionFilter = GetUnhandledExceptionFilter(); @@ -2095,7 +2097,7 @@ class DelayedNote AppendAppNotesToCrashReport(mData); } } - + private: nsCString mKey; nsCString mData; @@ -2443,7 +2445,7 @@ static nsresult PrefSubmitReports(bool* aSubmitReports, bool writePref) // We need to ensure the registry keys are created so we can properly // write values to it - + // Create appVendor key if(!appVendor.IsEmpty()) { regPath.Append(appVendor); @@ -2504,7 +2506,7 @@ static nsresult PrefSubmitReports(bool* aSubmitReports, bool writePref) *aSubmitReports = true; return NS_OK; } - + rv = regKey->ReadIntValue(NS_LITERAL_STRING("SubmitCrashReport"), &value); // default to true on failure if (NS_FAILED(rv)) { @@ -2582,7 +2584,7 @@ static nsresult PrefSubmitReports(bool* aSubmitReports, bool writePref) rv = iniWriter->WriteFile(nullptr, 0); return rv; } - + nsAutoCString submitReportValue; rv = iniParser->GetString(NS_LITERAL_CSTRING("Crash Reporter"), NS_LITERAL_CSTRING("SubmitReport"), @@ -2816,7 +2818,7 @@ GetPendingDir(nsIFile** dir) // The "limbo" dir is where minidumps go to wait for something else to // use them. If we're |ShouldReport()|, then the "something else" is -// a minidump submitter, and they're coming from the +// a minidump submitter, and they're coming from the // Crash Reports/pending/ dir. Otherwise, we don't know what the // "somthing else" is, but the minidumps stay in [profile]/minidumps/ // limbo. @@ -2858,7 +2860,7 @@ GetMinidumpForID(const nsAString& id, nsIFile** minidump) { if (!GetMinidumpLimboDir(minidump)) return false; - (*minidump)->Append(id + NS_LITERAL_STRING(".dmp")); + (*minidump)->Append(id + NS_LITERAL_STRING(".dmp")); return true; } @@ -3863,7 +3865,7 @@ CreateMinidumpsAndPair(ProcessHandle aTargetPid, } else { incomingDump = aIncomingDumpToPair; } - + RenameAdditionalHangMinidump(incomingDump, targetMinidump, aIncomingPairName); if (ShouldReport()) { diff --git a/tools/lint/flake8.lint b/tools/lint/flake8.lint index 46533009fef8..54acdba0b331 100644 --- a/tools/lint/flake8.lint +++ b/tools/lint/flake8.lint @@ -6,7 +6,10 @@ import json import os -import subprocess +import signal + +import which +from mozprocess import ProcessHandler from mozlint import result @@ -42,10 +45,26 @@ The offset is of the form (lineno_offset, num_lines) and is passed to the lineoffset property of `ResultContainer`. """ +results = [] + + +def process_line(line): + try: + res = json.loads(line) + except ValueError: + return + + if 'code' in res: + if res['code'].startswith('W'): + res['level'] = 'warning' + + if res['code'] in LINE_OFFSETS: + res['lineoffset'] = LINE_OFFSETS[res['code']] + + results.append(result.from_linter(LINTER, **res)) + def lint(files, **lintargs): - import which - binary = os.environ.get('FLAKE8') if not binary: try: @@ -69,27 +88,18 @@ def lint(files, **lintargs): cmdargs += files - proc = subprocess.Popen(cmdargs, stdout=subprocess.PIPE, env=os.environ) - output = proc.communicate()[0] + # flake8 seems to handle SIGINT poorly. Handle it here instead + # so we can kill the process without a cryptic traceback. + orig = signal.signal(signal.SIGINT, signal.SIG_IGN) + proc = ProcessHandler(cmdargs, env=os.environ, + processOutputLine=process_line) + proc.run() + signal.signal(signal.SIGINT, orig) - if not output: - return [] - - results = [] - for line in output.splitlines(): - try: - res = json.loads(line) - except ValueError: - continue - - if 'code' in res: - if res['code'].startswith('W'): - res['level'] = 'warning' - - if res['code'] in LINE_OFFSETS: - res['lineoffset'] = LINE_OFFSETS[res['code']] - - results.append(result.from_linter(LINTER, **res)) + try: + proc.wait() + except KeyboardInterrupt: + proc.kill() return results diff --git a/widget/WidgetUtils.cpp b/widget/WidgetUtils.cpp index 95bbb8475f43..c174548f6897 100644 --- a/widget/WidgetUtils.cpp +++ b/widget/WidgetUtils.cpp @@ -6,6 +6,11 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/WidgetUtils.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/unused.h" +#include "nsContentUtils.h" +#include "nsIBidiKeyboard.h" +#include "nsTArray.h" #ifdef XP_WIN #include "WinUtils.h" #endif @@ -109,5 +114,26 @@ WidgetUtils::IsTouchDeviceSupportPresent() #endif } +// static +void +WidgetUtils::SendBidiKeyboardInfoToContent() +{ + nsCOMPtr bidiKeyboard = nsContentUtils::GetBidiKeyboard(); + if (!bidiKeyboard) { + return; + } + + bool rtl; + if (NS_FAILED(bidiKeyboard->IsLangRTL(&rtl))) { + return; + } + + nsTArray children; + dom::ContentParent::GetAll(children); + for (uint32_t i = 0; i < children.Length(); i++) { + Unused << children[i]->SendBidiKeyboardNotify(rtl); + } +} + } // namespace widget } // namespace mozilla diff --git a/widget/WidgetUtils.h b/widget/WidgetUtils.h index 6e4d98b6ca25..c61873e47fa7 100644 --- a/widget/WidgetUtils.h +++ b/widget/WidgetUtils.h @@ -86,6 +86,11 @@ public: * Does device have touch support */ static uint32_t IsTouchDeviceSupportPresent(); + + /** + * Send bidi keyboard information to content process + */ + static void SendBidiKeyboardInfoToContent(); }; } // namespace widget diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index d2b3bb151d93..e9f1dcd754f2 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -22,8 +22,6 @@ #include "nsCocoaUtils.h" #include "WidgetUtils.h" #include "nsPrintfCString.h" -#include "mozilla/unused.h" -#include "mozilla/dom/ContentParent.h" #include "ComplexTextInputPanel.h" using namespace mozilla; @@ -2424,11 +2422,7 @@ IMEInputHandler::OnCurrentTextInputSourceChange(CFNotificationCenterRef aCenter, * by the general case (sCachedIsForRTLLangage is initially false) */ if (sCachedIsForRTLLangage != tis.IsForRTLLanguage()) { - nsTArray children; - dom::ContentParent::GetAll(children); - for (uint32_t i = 0; i < children.Length(); i++) { - Unused << children[i]->SendBidiKeyboardNotify(tis.IsForRTLLanguage()); - } + WidgetUtils::SendBidiKeyboardInfoToContent(); sCachedIsForRTLLangage = tis.IsForRTLLanguage(); } } diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 94d72c3af309..073a5a310611 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -1101,6 +1101,10 @@ nsNativeThemeCocoa::DrawSearchField(CGContextRef cgContext, const HIRect& inBoxR // NOTE: this could probably use inState [cell setShowsFirstResponder:IsFocused(aFrame)]; + // When using the 10.11 SDK, the default string will be shown if we don't + // set the placeholder string. + [cell setPlaceholderString:@""]; + DrawCellWithSnapping(cell, cgContext, inBoxRect, searchFieldSettings, VerticalAlignFactor(aFrame), mCellDrawView, IsFrameRTL(aFrame)); @@ -1226,7 +1230,7 @@ nsNativeThemeCocoa::DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRe BOOL isDisabled = IsDisabled(aFrame, inState); NSButtonCell* cell = (aWidgetType == NS_THEME_BUTTON) ? mPushButtonCell : - (aWidgetType == NS_THEME_MOZ_MAC_HELP_BUTTON) ? mHelpButtonCell : mDisclosureButtonCell; + (aWidgetType == NS_THEME_MAC_HELP_BUTTON) ? mHelpButtonCell : mDisclosureButtonCell; [cell setEnabled:!isDisabled]; [cell setHighlighted:isActive && inState.HasAllStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_HOVER)]; @@ -1234,7 +1238,7 @@ nsNativeThemeCocoa::DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRe if (aWidgetType != NS_THEME_BUTTON) { // Help button or disclosure button. NSSize buttonSize = NSMakeSize(0, 0); - if (aWidgetType == NS_THEME_MOZ_MAC_HELP_BUTTON) { + if (aWidgetType == NS_THEME_MAC_HELP_BUTTON) { buttonSize = kHelpButtonSize; } else { // Disclosure button. buttonSize = kDisclosureButtonSize; @@ -1517,7 +1521,7 @@ nsNativeThemeCocoa::DrawDropdown(CGContextRef cgContext, const HIRect& inBoxRect [mDropdownCell setPullsDown:(aWidgetType == NS_THEME_BUTTON)]; - BOOL isEditable = (aWidgetType == NS_THEME_DROPDOWN_TEXTFIELD); + BOOL isEditable = (aWidgetType == NS_THEME_MENULIST_TEXTFIELD); NSCell* cell = isEditable ? (NSCell*)mComboBoxCell : (NSCell*)mDropdownCell; [cell setEnabled:!IsDisabled(aFrame, inState)]; @@ -1593,8 +1597,8 @@ nsNativeThemeCocoa::DrawSpinButton(CGContextRef cgContext, { NS_OBJC_BEGIN_TRY_ABORT_BLOCK; - MOZ_ASSERT(aWidgetType == NS_THEME_SPINNER_UP_BUTTON || - aWidgetType == NS_THEME_SPINNER_DOWN_BUTTON); + MOZ_ASSERT(aWidgetType == NS_THEME_SPINNER_UPBUTTON || + aWidgetType == NS_THEME_SPINNER_DOWNBUTTON); HIThemeButtonDrawInfo bdi; bdi.version = 0; @@ -1613,7 +1617,7 @@ nsNativeThemeCocoa::DrawSpinButton(CGContextRef cgContext, // both buttons, using clip to hide the one we don't want to paint. HIRect drawRect = inBoxRect; drawRect.size.height *= 2; - if (aWidgetType == NS_THEME_SPINNER_DOWN_BUTTON) { + if (aWidgetType == NS_THEME_SPINNER_DOWNBUTTON) { drawRect.origin.y -= inBoxRect.size.height; } @@ -2619,7 +2623,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, DrawFocusOutline(cgContext, macRect, eventState, aWidgetType, aFrame); break; - case NS_THEME_MOZ_MAC_HELP_BUTTON: + case NS_THEME_MAC_HELP_BUTTON: case NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN: case NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED: DrawPushButton(cgContext, macRect, eventState, aWidgetType, aFrame); @@ -2654,8 +2658,8 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, } break; - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: { + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: { nsNumberControlFrame* numberControlFrame = nsNumberControlFrame::GetNumberControlFrameForSpinButton(aFrame); if (numberControlFrame) { @@ -2671,11 +2675,11 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, } break; - case NS_THEME_TOOLBAR_BUTTON: + case NS_THEME_TOOLBARBUTTON: DrawSegment(cgContext, macRect, eventState, aFrame, toolbarButtonRenderSettings); break; - case NS_THEME_TOOLBAR_SEPARATOR: { + case NS_THEME_SEPARATOR: { HIThemeSeparatorDrawInfo sdi = { 0, kThemeStateActive }; HIThemeDrawSeparator(&macRect, &sdi, cgContext, HITHEME_ORIENTATION); } @@ -2719,12 +2723,12 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, DrawStatusBar(cgContext, macRect, aFrame); break; - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_TEXTFIELD: DrawDropdown(cgContext, macRect, eventState, aWidgetType, aFrame); break; - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST_BUTTON: DrawButton(cgContext, kThemeArrowButton, macRect, false, kThemeButtonOn, kThemeAdornmentArrowDownArrow, eventState, aFrame); break; @@ -2784,23 +2788,23 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, DrawMeter(cgContext, macRect, aFrame); break; - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: - case NS_THEME_METERBAR_CHUNK: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: + case NS_THEME_METERCHUNK: // Do nothing: progress and meter bars cases will draw chunks. break; - case NS_THEME_TREEVIEW_TWISTY: + case NS_THEME_TREETWISTY: DrawButton(cgContext, kThemeDisclosureButton, macRect, false, kThemeDisclosureRight, kThemeAdornmentNone, eventState, aFrame); break; - case NS_THEME_TREEVIEW_TWISTY_OPEN: + case NS_THEME_TREETWISTYOPEN: DrawButton(cgContext, kThemeDisclosureButton, macRect, false, kThemeDisclosureDown, kThemeAdornmentNone, eventState, aFrame); break; - case NS_THEME_TREEVIEW_HEADER_CELL: { + case NS_THEME_TREEHEADERCELL: { TreeSortDirection sortDirection = GetTreeSortDirection(aFrame); DrawButton(cgContext, kThemeListHeaderButton, macRect, false, sortDirection == eTreeSortDirection_Natural ? kThemeButtonOff : kThemeButtonOn, @@ -2809,7 +2813,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, } break; - case NS_THEME_TREEVIEW_TREEITEM: + case NS_THEME_TREEITEM: case NS_THEME_TREEVIEW: // HIThemeSetFill is not available on 10.3 // HIThemeSetFill(kThemeBrushWhite, NULL, cgContext, HITHEME_ORIENTATION); @@ -2817,11 +2821,11 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, CGContextFillRect(cgContext, macRect); break; - case NS_THEME_TREEVIEW_HEADER: + case NS_THEME_TREEHEADER: // do nothing, taken care of by individual header cells - case NS_THEME_TREEVIEW_HEADER_SORTARROW: + case NS_THEME_TREEHEADERSORTARROW: // do nothing, taken care of by treeview header - case NS_THEME_TREEVIEW_LINE: + case NS_THEME_TREELINE: // do nothing, these lines don't exist on macos break; @@ -2842,8 +2846,8 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, } break; - case NS_THEME_SCALE_THUMB_HORIZONTAL: - case NS_THEME_SCALE_THUMB_VERTICAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_VERTICAL: // do nothing, drawn by scale break; @@ -2870,11 +2874,11 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, DrawScrollbar(cgContext, macRect, aFrame); } break; - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: if (ScrollbarTrackAndThumbDrawSeparately()) { BOOL isOverlay = nsLookAndFeel::UseOverlayScrollbars(); - BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL); + BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL); BOOL isRolledOver = IsParentScrollbarRolledOver(aFrame); nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame); bool isSmall = (scrollbarFrame && scrollbarFrame->StyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL); @@ -2907,26 +2911,26 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, true); } break; - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_LEFT: #if SCROLLBARS_VISUAL_DEBUG CGContextSetRGBFillColor(cgContext, 1.0, 0, 0, 0.6); CGContextFillRect(cgContext, macRect); #endif break; - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_RIGHT: #if SCROLLBARS_VISUAL_DEBUG CGContextSetRGBFillColor(cgContext, 0, 1.0, 0, 0.6); CGContextFillRect(cgContext, macRect); #endif break; - case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: - case NS_THEME_SCROLLBAR_TRACK_VERTICAL: + case NS_THEME_SCROLLBARTRACK_HORIZONTAL: + case NS_THEME_SCROLLBARTRACK_VERTICAL: if (ScrollbarTrackAndThumbDrawSeparately()) { BOOL isOverlay = nsLookAndFeel::UseOverlayScrollbars(); if (!isOverlay || IsParentScrollbarRolledOver(aFrame)) { - BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL); + BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBARTRACK_HORIZONTAL); nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame); bool isSmall = (scrollbarFrame && scrollbarFrame->StyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL); if (isOverlay && !nsCocoaFeatures::OnMountainLionOrLater()) { @@ -3036,7 +3040,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, DrawSegment(cgContext, macRect, eventState, aFrame, tabRenderSettings); break; - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANELS: DrawTabPanel(cgContext, macRect, aFrame); break; @@ -3102,7 +3106,7 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext, break; } - case NS_THEME_TOOLBAR_BUTTON: + case NS_THEME_TOOLBARBUTTON: { *aResult = DirectionAwareMargin(nsIntMargin(1, 4, 1, 4), aFrame); break; @@ -3117,12 +3121,12 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext, break; } - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_BUTTON: *aResult = DirectionAwareMargin(kAquaDropdownBorder, aFrame); break; - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST_TEXTFIELD: *aResult = DirectionAwareMargin(kAquaComboboxBorder, aFrame); break; @@ -3157,10 +3161,10 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext, break; } - case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: - case NS_THEME_SCROLLBAR_TRACK_VERTICAL: + case NS_THEME_SCROLLBARTRACK_HORIZONTAL: + case NS_THEME_SCROLLBARTRACK_VERTICAL: { - bool isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL); + bool isHorizontal = (aWidgetType == NS_THEME_SCROLLBARTRACK_HORIZONTAL); // On Lion and later, scrollbars have no arrows. if (!nsCocoaFeatures::OnLionOrLater()) { @@ -3240,16 +3244,16 @@ nsNativeThemeCocoa::GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFram case NS_THEME_BUTTON: case NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN: case NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED: - case NS_THEME_MOZ_MAC_HELP_BUTTON: - case NS_THEME_TOOLBAR_BUTTON: + case NS_THEME_MAC_HELP_BUTTON: + case NS_THEME_TOOLBARBUTTON: case NS_THEME_NUMBER_INPUT: case NS_THEME_TEXTFIELD: case NS_THEME_TEXTFIELD_MULTILINE: case NS_THEME_SEARCHFIELD: case NS_THEME_LISTBOX: - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_BUTTON: - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_BUTTON: + case NS_THEME_MENULIST_TEXTFIELD: case NS_THEME_CHECKBOX: case NS_THEME_RADIO: case NS_THEME_TAB: @@ -3330,22 +3334,22 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, break; } - case NS_THEME_MOZ_MAC_HELP_BUTTON: + case NS_THEME_MAC_HELP_BUTTON: { aResult->SizeTo(kHelpButtonSize.width, kHelpButtonSize.height); *aIsOverridable = false; break; } - case NS_THEME_TOOLBAR_BUTTON: + case NS_THEME_TOOLBARBUTTON: { aResult->SizeTo(0, toolbarButtonHeights[miniControlSize]); break; } case NS_THEME_SPINNER: - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: { SInt32 buttonHeight = 0, buttonWidth = 0; if (aFrame->GetContent()->IsXULElement()) { @@ -3366,8 +3370,8 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, break; } - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_BUTTON: { SInt32 popupHeight = 0; ::GetThemeMetric(kThemeMetricPopupButtonHeight, &popupHeight); @@ -3394,7 +3398,7 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, break; } - case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON: { + case NS_THEME_MAC_FULLSCREEN_BUTTON: { if ([NativeWindowForFrame(aFrame) respondsToSelector:@selector(toggleFullScreen:)] && !nsCocoaFeatures::OnYosemiteOrLater()) { // This value is hardcoded because it's needed before we can measure the @@ -3413,8 +3417,8 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, break; } - case NS_THEME_TREEVIEW_TWISTY: - case NS_THEME_TREEVIEW_TWISTY_OPEN: + case NS_THEME_TREETWISTY: + case NS_THEME_TREETWISTYOPEN: { SInt32 twistyHeight = 0, twistyWidth = 0; ::GetThemeMetric(kThemeMetricDisclosureButtonWidth, &twistyWidth); @@ -3424,8 +3428,8 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, break; } - case NS_THEME_TREEVIEW_HEADER: - case NS_THEME_TREEVIEW_HEADER_CELL: + case NS_THEME_TREEHEADER: + case NS_THEME_TREEHEADERCELL: { SInt32 headerHeight = 0; ::GetThemeMetric(kThemeMetricListHeaderHeight, &headerHeight); @@ -3486,8 +3490,8 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, break; } - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: { // Find our parent scrollbar frame in order to find out whether we're in // a small or a large scrollbar. @@ -3496,7 +3500,7 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, return NS_ERROR_FAILURE; bool isSmall = (scrollbarFrame->StyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL); - bool isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL); + bool isHorizontal = (aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL); int32_t& minSize = isHorizontal ? aResult->width : aResult->height; minSize = isSmall ? kSmallScrollbarThumbMinSize : kRegularScrollbarThumbMinSize; break; @@ -3504,8 +3508,8 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, case NS_THEME_SCROLLBAR: case NS_THEME_SCROLLBAR_SMALL: - case NS_THEME_SCROLLBAR_TRACK_VERTICAL: - case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: + case NS_THEME_SCROLLBARTRACK_VERTICAL: + case NS_THEME_SCROLLBARTRACK_HORIZONTAL: { *aIsOverridable = false; @@ -3562,15 +3566,15 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, break; } - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: { nsIFrame *scrollbarFrame = GetParentScrollbarFrame(aFrame); if (!scrollbarFrame) return NS_ERROR_FAILURE; - // Since there is no NS_THEME_SCROLLBAR_BUTTON_UP_SMALL we need to ask the parent what appearance style it has. + // Since there is no NS_THEME_SCROLLBARBUTTON_UP_SMALL we need to ask the parent what appearance style it has. int32_t themeMetric = (scrollbarFrame->StyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL) ? kThemeMetricSmallScrollBarWidth : kThemeMetricScrollBarWidth; @@ -3578,7 +3582,7 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, ::GetThemeMetric(themeMetric, &scrollbarWidth); // It seems that for both sizes of scrollbar, the buttons are one pixel "longer". - if (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT || aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT) + if (aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT || aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT) aResult->SizeTo(scrollbarWidth+1, scrollbarWidth); else aResult->SizeTo(scrollbarWidth, scrollbarWidth+1); @@ -3622,20 +3626,20 @@ nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, case NS_THEME_TOOLBOX: case NS_THEME_TOOLBAR: case NS_THEME_STATUSBAR: - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: case NS_THEME_TOOLTIP: - case NS_THEME_TAB_PANELS: - case NS_THEME_TAB_PANEL: + case NS_THEME_TABPANELS: + case NS_THEME_TABPANEL: case NS_THEME_DIALOG: case NS_THEME_MENUPOPUP: case NS_THEME_GROUPBOX: - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: case NS_THEME_PROGRESSBAR: case NS_THEME_PROGRESSBAR_VERTICAL: case NS_THEME_METERBAR: - case NS_THEME_METERBAR_CHUNK: + case NS_THEME_METERCHUNK: case NS_THEME_MAC_VIBRANCY_LIGHT: case NS_THEME_MAC_VIBRANCY_DARK: *aShouldRepaint = false; @@ -3699,7 +3703,7 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a return false; // if this is a dropdown button in a combobox the answer is always no - if (aWidgetType == NS_THEME_DROPDOWN_BUTTON) { + if (aWidgetType == NS_THEME_MENULIST_BUTTON) { nsIFrame* parentFrame = aFrame->GetParent(); if (parentFrame && (parentFrame->GetType() == nsGkAtoms::comboboxControlFrame)) return false; @@ -3707,10 +3711,10 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a switch (aWidgetType) { // Combobox dropdowns don't support native theming in vertical mode. - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_BUTTON: - case NS_THEME_DROPDOWN_TEXT: - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_BUTTON: + case NS_THEME_MENULIST_TEXT: + case NS_THEME_MENULIST_TEXTFIELD: if (aFrame && aFrame->GetWritingMode().IsVertical()) { return false; } @@ -3727,7 +3731,7 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a case NS_THEME_MENUARROW: case NS_THEME_MENUITEM: case NS_THEME_MENUSEPARATOR: - case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON: + case NS_THEME_MAC_FULLSCREEN_BUTTON: case NS_THEME_TOOLTIP: case NS_THEME_CHECKBOX: @@ -3735,17 +3739,17 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a case NS_THEME_RADIO: case NS_THEME_RADIO_CONTAINER: case NS_THEME_GROUPBOX: - case NS_THEME_MOZ_MAC_HELP_BUTTON: + case NS_THEME_MAC_HELP_BUTTON: case NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN: case NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED: case NS_THEME_BUTTON: case NS_THEME_BUTTON_ARROW_UP: case NS_THEME_BUTTON_ARROW_DOWN: case NS_THEME_BUTTON_BEVEL: - case NS_THEME_TOOLBAR_BUTTON: + case NS_THEME_TOOLBARBUTTON: case NS_THEME_SPINNER: - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: case NS_THEME_TOOLBAR: case NS_THEME_STATUSBAR: case NS_THEME_NUMBER_INPUT: @@ -3753,45 +3757,45 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a case NS_THEME_TEXTFIELD_MULTILINE: case NS_THEME_SEARCHFIELD: case NS_THEME_TOOLBOX: - //case NS_THEME_TOOLBAR_BUTTON: + //case NS_THEME_TOOLBARBUTTON: case NS_THEME_PROGRESSBAR: case NS_THEME_PROGRESSBAR_VERTICAL: - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: case NS_THEME_METERBAR: - case NS_THEME_METERBAR_CHUNK: - case NS_THEME_TOOLBAR_SEPARATOR: + case NS_THEME_METERCHUNK: + case NS_THEME_SEPARATOR: - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANELS: case NS_THEME_TAB: - case NS_THEME_TREEVIEW_TWISTY: - case NS_THEME_TREEVIEW_TWISTY_OPEN: + case NS_THEME_TREETWISTY: + case NS_THEME_TREETWISTYOPEN: case NS_THEME_TREEVIEW: - case NS_THEME_TREEVIEW_HEADER: - case NS_THEME_TREEVIEW_HEADER_CELL: - case NS_THEME_TREEVIEW_HEADER_SORTARROW: - case NS_THEME_TREEVIEW_TREEITEM: - case NS_THEME_TREEVIEW_LINE: + case NS_THEME_TREEHEADER: + case NS_THEME_TREEHEADERCELL: + case NS_THEME_TREEHEADERSORTARROW: + case NS_THEME_TREEITEM: + case NS_THEME_TREELINE: case NS_THEME_MAC_SOURCE_LIST: case NS_THEME_RANGE: case NS_THEME_SCALE_HORIZONTAL: - case NS_THEME_SCALE_THUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: case NS_THEME_SCALE_VERTICAL: - case NS_THEME_SCALE_THUMB_VERTICAL: + case NS_THEME_SCALETHUMB_VERTICAL: case NS_THEME_SCROLLBAR: case NS_THEME_SCROLLBAR_SMALL: - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: - case NS_THEME_SCROLLBAR_TRACK_VERTICAL: - case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: + case NS_THEME_SCROLLBARTRACK_VERTICAL: + case NS_THEME_SCROLLBARTRACK_HORIZONTAL: case NS_THEME_SCROLLBAR_NON_DISAPPEARING: return !IsWidgetStyled(aPresContext, aFrame, aWidgetType); @@ -3827,13 +3831,13 @@ nsNativeThemeCocoa::WidgetIsContainer(uint8_t aWidgetType) { // flesh this out at some point switch (aWidgetType) { - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST_BUTTON: case NS_THEME_RADIO: case NS_THEME_CHECKBOX: case NS_THEME_PROGRESSBAR: case NS_THEME_METERBAR: case NS_THEME_RANGE: - case NS_THEME_MOZ_MAC_HELP_BUTTON: + case NS_THEME_MAC_HELP_BUTTON: case NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN: case NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED: return false; @@ -3844,10 +3848,10 @@ nsNativeThemeCocoa::WidgetIsContainer(uint8_t aWidgetType) bool nsNativeThemeCocoa::ThemeDrawsFocusForWidget(uint8_t aWidgetType) { - if (aWidgetType == NS_THEME_DROPDOWN || - aWidgetType == NS_THEME_DROPDOWN_TEXTFIELD || + if (aWidgetType == NS_THEME_MENULIST || + aWidgetType == NS_THEME_MENULIST_TEXTFIELD || aWidgetType == NS_THEME_BUTTON || - aWidgetType == NS_THEME_MOZ_MAC_HELP_BUTTON || + aWidgetType == NS_THEME_MAC_HELP_BUTTON || aWidgetType == NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN || aWidgetType == NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED || aWidgetType == NS_THEME_RADIO || @@ -3870,7 +3874,7 @@ nsNativeThemeCocoa::WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType) switch (aWidgetType) { case NS_THEME_DIALOG: case NS_THEME_GROUPBOX: - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANELS: case NS_THEME_BUTTON_ARROW_UP: case NS_THEME_BUTTON_ARROW_DOWN: case NS_THEME_CHECKMENUITEM: @@ -3880,14 +3884,14 @@ nsNativeThemeCocoa::WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType) case NS_THEME_MENUSEPARATOR: case NS_THEME_TOOLTIP: case NS_THEME_SPINNER: - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: - case NS_THEME_TOOLBAR_SEPARATOR: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: + case NS_THEME_SEPARATOR: case NS_THEME_TOOLBOX: case NS_THEME_NUMBER_INPUT: case NS_THEME_TEXTFIELD: case NS_THEME_TREEVIEW: - case NS_THEME_TREEVIEW_LINE: + case NS_THEME_TREELINE: case NS_THEME_TEXTFIELD_MULTILINE: case NS_THEME_LISTBOX: case NS_THEME_RESIZER: @@ -3982,7 +3986,7 @@ nsNativeThemeCocoa::ThemeGeometryTypeForWidget(nsIFrame* aFrame, uint8_t aWidget return eThemeGeometryTypeToolbox; case NS_THEME_WINDOW_BUTTON_BOX: return eThemeGeometryTypeWindowButtons; - case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON: + case NS_THEME_MAC_FULLSCREEN_BUTTON: return eThemeGeometryTypeFullscreenButton; case NS_THEME_MAC_VIBRANCY_LIGHT: return eThemeGeometryTypeVibrancyLight; diff --git a/widget/gonk/GeckoTouchDispatcher.cpp b/widget/gonk/GeckoTouchDispatcher.cpp index 75ef6c1c759b..3f852fdd0edf 100644 --- a/widget/gonk/GeckoTouchDispatcher.cpp +++ b/widget/gonk/GeckoTouchDispatcher.cpp @@ -115,7 +115,7 @@ GeckoTouchDispatcher::NotifyTouch(MultiTouchInput& aTouch, TimeStamp aEventTime) // move events because we might end up dispatching events out of order. // Instead, fall back to a non-resampling in-order dispatch until we're // done processing the non-move events. - layers::APZThreadUtils::RunOnControllerThread(NewRunnableMethod( + layers::APZThreadUtils::RunOnControllerThread(NewRunnableMethod( this, &GeckoTouchDispatcher::DispatchTouchEvent, aTouch)); return; } @@ -127,7 +127,7 @@ GeckoTouchDispatcher::NotifyTouch(MultiTouchInput& aTouch, TimeStamp aEventTime) MutexAutoLock lock(mTouchQueueLock); mInflightNonMoveEvents++; } - layers::APZThreadUtils::RunOnControllerThread(NewRunnableMethod( + layers::APZThreadUtils::RunOnControllerThread(NewRunnableMethod( this, &GeckoTouchDispatcher::DispatchTouchNonMoveEvent, aTouch)); } } diff --git a/widget/gonk/nativewindow/FakeSurfaceComposer.cpp b/widget/gonk/nativewindow/FakeSurfaceComposer.cpp index e8b6521b509c..7e4a2a9d8659 100644 --- a/widget/gonk/nativewindow/FakeSurfaceComposer.cpp +++ b/widget/gonk/nativewindow/FakeSurfaceComposer.cpp @@ -42,6 +42,7 @@ #include "MainThreadUtils.h" #include "mozilla/Assertions.h" #include "mozilla/layers/CompositorBridgeParent.h" +#include "mozilla/layers/CompositorThread.h" #include "nsProxyRelease.h" #include "nsThreadUtils.h" @@ -525,7 +526,7 @@ FakeSurfaceComposer::captureScreenImp(const sp& producer NS_ReleaseOnMainThread(screenAlias.forget()); }); - mozilla::layers::CompositorBridgeParent::CompositorLoop()->PostTask( + layers::CompositorThreadHolder::Loop()->PostTask( MakeAndAddRef(runnable)); } diff --git a/widget/gonk/nsScreenManagerGonk.cpp b/widget/gonk/nsScreenManagerGonk.cpp index 1cb9cb570c34..26a9adcc683f 100644 --- a/widget/gonk/nsScreenManagerGonk.cpp +++ b/widget/gonk/nsScreenManagerGonk.cpp @@ -29,6 +29,7 @@ #include "nsWindow.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/layers/CompositorBridgeParent.h" +#include "mozilla/layers/CompositorThread.h" #include "mozilla/Services.h" #include "mozilla/ProcessPriorityManager.h" #include "nsIdleService.h" @@ -152,8 +153,9 @@ nsScreenGonk::nsScreenGonk(uint32_t aId, } static void -ReleaseGLContextSync(mozilla::gl::GLContext* aGLContext) { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); +ReleaseGLContextSync(mozilla::gl::GLContext* aGLContext) +{ + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); aGLContext->Release(); } @@ -161,7 +163,7 @@ nsScreenGonk::~nsScreenGonk() { // Release GLContext on compositor thread if (mGLContext) { - CompositorBridgeParent::CompositorLoop()->PostTask( + CompositorThreadHolder::Loop()->PostTask( NewRunnableFunction(&ReleaseGLContextSync, mGLContext.forget().take())); mGLContext = nullptr; @@ -422,7 +424,7 @@ NeedsRBSwap(int aHalFormat) already_AddRefed nsScreenGonk::StartRemoteDrawing() { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); MOZ_ASSERT(!mFramebuffer); MOZ_ASSERT(!mMappedBuffer); @@ -460,7 +462,7 @@ nsScreenGonk::StartRemoteDrawing() void nsScreenGonk::EndRemoteDrawing() { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); if (mFramebufferTarget && mFramebuffer) { IntSize size = mFramebufferTarget->GetSize(); @@ -527,7 +529,7 @@ nsScreenGonk::QueueBuffer(ANativeWindowBuffer* buf) nsresult nsScreenGonk::MakeSnapshot(ANativeWindowBuffer* aBuffer) { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); MOZ_ASSERT(aBuffer); layers::CompositorBridgeParent* compositorParent = mCompositorBridgeParent; @@ -609,7 +611,7 @@ nsScreenGonk::SetEGLInfo(hwc_display_t aDisplay, hwc_surface_t aSurface, gl::GLContext* aGLContext) { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); mEGLDisplay = aDisplay; mEGLSurface = aSurface; mGLContext = aGLContext; @@ -618,21 +620,21 @@ nsScreenGonk::SetEGLInfo(hwc_display_t aDisplay, hwc_display_t nsScreenGonk::GetEGLDisplay() { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); return mEGLDisplay; } hwc_surface_t nsScreenGonk::GetEGLSurface() { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); return mEGLSurface; } already_AddRefed nsScreenGonk::GetGLContext() { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); RefPtrglContext = mGLContext; return glContext.forget(); } @@ -640,7 +642,7 @@ nsScreenGonk::GetGLContext() static void UpdateMirroringWidgetSync(nsMainThreadPtrHandle&& aScreen, nsWindow* aWindow) { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); already_AddRefed window(aWindow); aScreen->UpdateMirroringWidget(window); } @@ -667,7 +669,7 @@ nsScreenGonk::EnableMirroring() // Update mMirroringWidget on compositor thread nsMainThreadPtrHandle primary = nsMainThreadPtrHandle(new nsMainThreadPtrHolder(primaryScreen, false)); - CompositorBridgeParent::CompositorLoop()->PostTask( + CompositorThreadHolder::Loop()->PostTask( NewRunnableFunction(&UpdateMirroringWidgetSync, primary, window.forget().take())); @@ -692,7 +694,7 @@ nsScreenGonk::DisableMirroring() // Update mMirroringWidget on compositor thread nsMainThreadPtrHandle primary = nsMainThreadPtrHandle(new nsMainThreadPtrHolder(primaryScreen, false)); - CompositorBridgeParent::CompositorLoop()->PostTask( + CompositorThreadHolder::Loop()->PostTask( NewRunnableFunction(&UpdateMirroringWidgetSync, primary, nullptr)); @@ -728,7 +730,7 @@ nsScreenGonk::ClearMirroringScreen(nsScreenGonk* aScreen) void nsScreenGonk::UpdateMirroringWidget(already_AddRefed& aWindow) { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); MOZ_ASSERT(IsPrimaryScreen()); if (mMirroringWidget) { @@ -741,7 +743,7 @@ nsScreenGonk::UpdateMirroringWidget(already_AddRefed& aWindow) nsWindow* nsScreenGonk::GetMirroringWidget() { - MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread()); + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); MOZ_ASSERT(IsPrimaryScreen()); return mMirroringWidget; @@ -900,9 +902,9 @@ nsScreenManagerGonk::VsyncControl(bool aEnabled) { if (!NS_IsMainThread()) { NS_DispatchToMainThread( - NS_NewRunnableMethodWithArgs(this, - &nsScreenManagerGonk::VsyncControl, - aEnabled)); + NewRunnableMethod(this, + &nsScreenManagerGonk::VsyncControl, + aEnabled)); return; } diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index da04b81b8384..ed05043e6d4d 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -44,6 +44,7 @@ #include "mozilla/layers/APZCTreeManager.h" #include "mozilla/layers/APZThreadUtils.h" #include "mozilla/layers/CompositorBridgeParent.h" +#include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/CompositorSession.h" #include "mozilla/TouchEvents.h" #include "HwcComposer2D.h" @@ -132,7 +133,7 @@ nsWindow::DoDraw(void) void nsWindow::ConfigureAPZControllerThread() { - APZThreadUtils::SetControllerThread(CompositorBridgeParent::CompositorLoop()); + APZThreadUtils::SetControllerThread(CompositorThreadHolder::Loop()); } /*static*/ nsEventStatus diff --git a/widget/gtk/nsNativeThemeGTK.cpp b/widget/gtk/nsNativeThemeGTK.cpp index e173f79e585d..4ba4d8ab3319 100644 --- a/widget/gtk/nsNativeThemeGTK.cpp +++ b/widget/gtk/nsNativeThemeGTK.cpp @@ -180,10 +180,10 @@ nsNativeThemeGTK::GetTabMarginPixels(nsIFrame* aFrame) static bool ShouldScrollbarButtonBeDisabled(int32_t aCurpos, int32_t aMaxpos, uint8_t aWidgetType) { - return ((aCurpos == 0 && (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_UP || - aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT)) - || (aCurpos == aMaxpos && (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_DOWN || - aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT))); + return ((aCurpos == 0 && (aWidgetType == NS_THEME_SCROLLBARBUTTON_UP || + aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT)) + || (aCurpos == aMaxpos && (aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN || + aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT))); } bool @@ -240,8 +240,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, *aWidgetFlags |= MOZ_GTK_WIDGET_INCONSISTENT; } } - } else if (aWidgetType == NS_THEME_TOOLBAR_BUTTON_DROPDOWN || - aWidgetType == NS_THEME_TREEVIEW_HEADER_SORTARROW || + } else if (aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || + aWidgetType == NS_THEME_TREEHEADERSORTARROW || aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS || aWidgetType == NS_THEME_BUTTON_ARROW_NEXT || aWidgetType == NS_THEME_BUTTON_ARROW_UP || @@ -270,11 +270,11 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, aState->focused = TRUE; aState->depressed = TRUE; // see moz_gtk_entry_paint() } else if (aWidgetType == NS_THEME_BUTTON || - aWidgetType == NS_THEME_TOOLBAR_BUTTON || - aWidgetType == NS_THEME_TOOLBAR_DUAL_BUTTON || - aWidgetType == NS_THEME_TOOLBAR_BUTTON_DROPDOWN || - aWidgetType == NS_THEME_DROPDOWN || - aWidgetType == NS_THEME_DROPDOWN_BUTTON) { + aWidgetType == NS_THEME_TOOLBARBUTTON || + aWidgetType == NS_THEME_DUALBUTTON || + aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || + aWidgetType == NS_THEME_MENULIST || + aWidgetType == NS_THEME_MENULIST_BUTTON) { aState->active &= aState->inHover; } @@ -285,7 +285,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, if (aWidgetType == NS_THEME_NUMBER_INPUT || aWidgetType == NS_THEME_TEXTFIELD || aWidgetType == NS_THEME_TEXTFIELD_MULTILINE || - aWidgetType == NS_THEME_DROPDOWN_TEXTFIELD || + aWidgetType == NS_THEME_MENULIST_TEXTFIELD || aWidgetType == NS_THEME_SPINNER_TEXTFIELD || aWidgetType == NS_THEME_RADIO_CONTAINER || aWidgetType == NS_THEME_RADIO_LABEL) { @@ -296,8 +296,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, aState->focused = FALSE; } - if (aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL || - aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) { + if (aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL || + aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) { // for scrollbars we need to go up two to go from the thumb to // the slider to the actual scrollbar object nsIFrame *tmpFrame = aFrame->GetParent()->GetParent(); @@ -310,10 +310,10 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, } } - if (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_UP || - aWidgetType == NS_THEME_SCROLLBAR_BUTTON_DOWN || - aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT || - aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT) { + if (aWidgetType == NS_THEME_SCROLLBARBUTTON_UP || + aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN || + aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT || + aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT) { // set the state to disabled when the scrollbar is scrolled to // the beginning or the end, depending on the button type. int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0); @@ -331,7 +331,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, if (aWidgetFlags) { *aWidgetFlags = GetScrollbarButtonType(aFrame); - if (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP < 2) + if (aWidgetType - NS_THEME_SCROLLBARBUTTON_UP < 2) *aWidgetFlags |= MOZ_GTK_STEPPER_VERTICAL; } } @@ -376,11 +376,11 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, // A button with drop down menu open or an activated toggle button // should always appear depressed. if (aWidgetType == NS_THEME_BUTTON || - aWidgetType == NS_THEME_TOOLBAR_BUTTON || - aWidgetType == NS_THEME_TOOLBAR_DUAL_BUTTON || - aWidgetType == NS_THEME_TOOLBAR_BUTTON_DROPDOWN || - aWidgetType == NS_THEME_DROPDOWN || - aWidgetType == NS_THEME_DROPDOWN_BUTTON) { + aWidgetType == NS_THEME_TOOLBARBUTTON || + aWidgetType == NS_THEME_DUALBUTTON || + aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || + aWidgetType == NS_THEME_MENULIST || + aWidgetType == NS_THEME_MENULIST_BUTTON) { bool menuOpen = IsOpenButton(aFrame); aState->depressed = IsCheckedButton(aFrame) || menuOpen; // we must not highlight buttons with open drop down menus on hover. @@ -389,7 +389,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, // When the input field of the drop down button has focus, some themes // should draw focus for the drop down button as well. - if (aWidgetType == NS_THEME_DROPDOWN_BUTTON && aWidgetFlags) { + if (aWidgetType == NS_THEME_MENULIST_BUTTON && aWidgetFlags) { *aWidgetFlags = CheckBooleanAttr(aFrame, nsGkAtoms::parentfocused); } } @@ -402,8 +402,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, *aWidgetFlags = GTK_RELIEF_NORMAL; aGtkWidgetType = MOZ_GTK_BUTTON; break; - case NS_THEME_TOOLBAR_BUTTON: - case NS_THEME_TOOLBAR_DUAL_BUTTON: + case NS_THEME_TOOLBARBUTTON: + case NS_THEME_DUALBUTTON: if (aWidgetFlags) *aWidgetFlags = GTK_RELIEF_NONE; aGtkWidgetType = MOZ_GTK_TOOLBAR_BUTTON; @@ -415,10 +415,10 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, case NS_THEME_RADIO: aGtkWidgetType = (aWidgetType == NS_THEME_RADIO) ? MOZ_GTK_RADIOBUTTON : MOZ_GTK_CHECKBUTTON; break; - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: aGtkWidgetType = MOZ_GTK_SCROLLBAR_BUTTON; break; case NS_THEME_SCROLLBAR_VERTICAL: @@ -435,19 +435,19 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, else *aWidgetFlags = 0; break; - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: aGtkWidgetType = MOZ_GTK_SCROLLBAR_THUMB_VERTICAL; break; - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: aGtkWidgetType = MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL; break; case NS_THEME_SPINNER: aGtkWidgetType = MOZ_GTK_SPINBUTTON; break; - case NS_THEME_SPINNER_UP_BUTTON: + case NS_THEME_SPINNER_UPBUTTON: aGtkWidgetType = MOZ_GTK_SPINBUTTON_UP; break; - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: aGtkWidgetType = MOZ_GTK_SPINBUTTON_DOWN; break; case NS_THEME_SPINNER_TEXTFIELD: @@ -484,7 +484,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, *aWidgetFlags = GTK_ORIENTATION_HORIZONTAL; aGtkWidgetType = MOZ_GTK_SCALE_HORIZONTAL; break; - case NS_THEME_SCALE_THUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: if (aWidgetFlags) *aWidgetFlags = GTK_ORIENTATION_HORIZONTAL; aGtkWidgetType = MOZ_GTK_SCALE_THUMB_HORIZONTAL; @@ -494,15 +494,15 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, *aWidgetFlags = GTK_ORIENTATION_VERTICAL; aGtkWidgetType = MOZ_GTK_SCALE_VERTICAL; break; - case NS_THEME_TOOLBAR_SEPARATOR: + case NS_THEME_SEPARATOR: aGtkWidgetType = MOZ_GTK_TOOLBAR_SEPARATOR; break; - case NS_THEME_SCALE_THUMB_VERTICAL: + case NS_THEME_SCALETHUMB_VERTICAL: if (aWidgetFlags) *aWidgetFlags = GTK_ORIENTATION_VERTICAL; aGtkWidgetType = MOZ_GTK_SCALE_THUMB_VERTICAL; break; - case NS_THEME_TOOLBAR_GRIPPER: + case NS_THEME_TOOLBARGRIPPER: aGtkWidgetType = MOZ_GTK_GRIPPER; break; case NS_THEME_RESIZER: @@ -523,7 +523,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, case NS_THEME_TREEVIEW: aGtkWidgetType = MOZ_GTK_TREEVIEW; break; - case NS_THEME_TREEVIEW_HEADER_CELL: + case NS_THEME_TREEHEADERCELL: if (aWidgetFlags) { // In this case, the flag denotes whether the header is the sorted one or not if (GetTreeSortDirection(aFrame) == eTreeSortDirection_Natural) @@ -533,7 +533,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, } aGtkWidgetType = MOZ_GTK_TREE_HEADER_CELL; break; - case NS_THEME_TREEVIEW_HEADER_SORTARROW: + case NS_THEME_TREEHEADERSORTARROW: if (aWidgetFlags) { switch (GetTreeSortDirection(aFrame)) { case eTreeSortDirection_Ascending: @@ -553,30 +553,30 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, } aGtkWidgetType = MOZ_GTK_TREE_HEADER_SORTARROW; break; - case NS_THEME_TREEVIEW_TWISTY: + case NS_THEME_TREETWISTY: aGtkWidgetType = MOZ_GTK_TREEVIEW_EXPANDER; if (aWidgetFlags) *aWidgetFlags = GTK_EXPANDER_COLLAPSED; break; - case NS_THEME_TREEVIEW_TWISTY_OPEN: + case NS_THEME_TREETWISTYOPEN: aGtkWidgetType = MOZ_GTK_TREEVIEW_EXPANDER; if (aWidgetFlags) *aWidgetFlags = GTK_EXPANDER_EXPANDED; break; - case NS_THEME_DROPDOWN: + case NS_THEME_MENULIST: aGtkWidgetType = MOZ_GTK_DROPDOWN; if (aWidgetFlags) *aWidgetFlags = IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XHTML); break; - case NS_THEME_DROPDOWN_TEXT: + case NS_THEME_MENULIST_TEXT: return false; // nothing to do, but prevents the bg from being drawn - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST_TEXTFIELD: aGtkWidgetType = MOZ_GTK_DROPDOWN_ENTRY; break; - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST_BUTTON: aGtkWidgetType = MOZ_GTK_DROPDOWN_ARROW; break; - case NS_THEME_TOOLBAR_BUTTON_DROPDOWN: + case NS_THEME_TOOLBARBUTTON_DROPDOWN: case NS_THEME_BUTTON_ARROW_DOWN: case NS_THEME_BUTTON_ARROW_UP: case NS_THEME_BUTTON_ARROW_NEXT: @@ -611,16 +611,16 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, case NS_THEME_TOOLTIP: aGtkWidgetType = MOZ_GTK_TOOLTIP; break; - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: aGtkWidgetType = MOZ_GTK_FRAME; break; case NS_THEME_PROGRESSBAR: case NS_THEME_PROGRESSBAR_VERTICAL: aGtkWidgetType = MOZ_GTK_PROGRESSBAR; break; - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: { nsIFrame* stateFrame = aFrame->GetParent(); EventStates eventStates = GetContentState(stateFrame, aWidgetType); @@ -632,14 +632,14 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, : MOZ_GTK_PROGRESS_CHUNK; } break; - case NS_THEME_TAB_SCROLLARROW_BACK: - case NS_THEME_TAB_SCROLLARROW_FORWARD: + case NS_THEME_TAB_SCROLL_ARROW_BACK: + case NS_THEME_TAB_SCROLL_ARROW_FORWARD: if (aWidgetFlags) - *aWidgetFlags = aWidgetType == NS_THEME_TAB_SCROLLARROW_BACK ? + *aWidgetFlags = aWidgetType == NS_THEME_TAB_SCROLL_ARROW_BACK ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT; aGtkWidgetType = MOZ_GTK_TAB_SCROLLARROW; break; - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANELS: aGtkWidgetType = MOZ_GTK_TABPANELS; break; case NS_THEME_TAB: @@ -1003,10 +1003,10 @@ nsNativeThemeGTK::GetExtraSizeForWidget(nsIFrame* aFrame, uint8_t aWidgetType, // GTK2 themes (Ximian Industrial, Bluecurve, Misty, at least); // We modify the frame's overflow area. See bug 297508. switch (aWidgetType) { - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: aExtra->top = aExtra->bottom = 1; break; - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: aExtra->left = aExtra->right = 1; break; @@ -1234,7 +1234,7 @@ nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, aResult->top = aResult->left = aResult->right = aResult->bottom = 0; switch (aWidgetType) { case NS_THEME_SCROLLBAR_VERTICAL: - case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: + case NS_THEME_SCROLLBARTRACK_HORIZONTAL: { MozGtkScrollbarMetrics metrics; moz_gtk_get_scrollbar_metrics(&metrics); @@ -1244,7 +1244,7 @@ nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, } break; case NS_THEME_SCROLLBAR_HORIZONTAL: - case NS_THEME_SCROLLBAR_TRACK_VERTICAL: + case NS_THEME_SCROLLBARTRACK_VERTICAL: { MozGtkScrollbarMetrics metrics; moz_gtk_get_scrollbar_metrics(&metrics); @@ -1256,7 +1256,7 @@ nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, // gtk's 'toolbar' for purposes of painting the widget background, // we don't use the toolbar border for toolbox. break; - case NS_THEME_TOOLBAR_DUAL_BUTTON: + case NS_THEME_DUALBUTTON: // TOOLBAR_DUAL_BUTTON is an interesting case. We want a border to draw // around the entire button + dropdown, and also an inner border if you're // over the button part. But, we want the inner button to be right up @@ -1314,12 +1314,12 @@ nsNativeThemeGTK::GetWidgetPadding(nsDeviceContext* aContext, { switch (aWidgetType) { case NS_THEME_BUTTON_FOCUS: - case NS_THEME_TOOLBAR_BUTTON: - case NS_THEME_TOOLBAR_DUAL_BUTTON: - case NS_THEME_TAB_SCROLLARROW_BACK: - case NS_THEME_TAB_SCROLLARROW_FORWARD: - case NS_THEME_DROPDOWN_BUTTON: - case NS_THEME_TOOLBAR_BUTTON_DROPDOWN: + case NS_THEME_TOOLBARBUTTON: + case NS_THEME_DUALBUTTON: + case NS_THEME_TAB_SCROLL_ARROW_BACK: + case NS_THEME_TAB_SCROLL_ARROW_FORWARD: + case NS_THEME_MENULIST_BUTTON: + case NS_THEME_TOOLBARBUTTON_DROPDOWN: case NS_THEME_BUTTON_ARROW_UP: case NS_THEME_BUTTON_ARROW_DOWN: case NS_THEME_BUTTON_ARROW_NEXT: @@ -1401,8 +1401,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, *aIsOverridable = true; switch (aWidgetType) { - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: { MozGtkScrollbarMetrics metrics; moz_gtk_get_scrollbar_metrics(&metrics); @@ -1412,8 +1412,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, *aIsOverridable = false; } break; - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: { MozGtkScrollbarMetrics metrics; moz_gtk_get_scrollbar_metrics(&metrics); @@ -1465,13 +1465,13 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, *aIsOverridable = false; } break; - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: { MozGtkScrollbarMetrics metrics; moz_gtk_get_scrollbar_metrics(&metrics); - if (aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL) { + if (aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL) { aResult->width = metrics.slider_width; aResult->height = metrics.min_slider_size; } else { @@ -1510,12 +1510,12 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, *aIsOverridable = true; } break; - case NS_THEME_SCALE_THUMB_HORIZONTAL: - case NS_THEME_SCALE_THUMB_VERTICAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_VERTICAL: { gint thumb_length, thumb_height; - if (aWidgetType == NS_THEME_SCALE_THUMB_VERTICAL) { + if (aWidgetType == NS_THEME_SCALETHUMB_VERTICAL) { moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_VERTICAL, &thumb_length, &thumb_height); aResult->width = thumb_height; aResult->height = thumb_length; @@ -1528,14 +1528,14 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, *aIsOverridable = false; } break; - case NS_THEME_TAB_SCROLLARROW_BACK: - case NS_THEME_TAB_SCROLLARROW_FORWARD: + case NS_THEME_TAB_SCROLL_ARROW_BACK: + case NS_THEME_TAB_SCROLL_ARROW_FORWARD: { moz_gtk_get_tab_scroll_arrow_size(&aResult->width, &aResult->height); *aIsOverridable = false; } break; - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST_BUTTON: { moz_gtk_get_combo_box_entry_button_size(&aResult->width, &aResult->height); @@ -1568,7 +1568,7 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, aResult->height = indicator_size; } break; - case NS_THEME_TOOLBAR_BUTTON_DROPDOWN: + case NS_THEME_TOOLBARBUTTON_DROPDOWN: case NS_THEME_BUTTON_ARROW_UP: case NS_THEME_BUTTON_ARROW_DOWN: case NS_THEME_BUTTON_ARROW_NEXT: @@ -1584,11 +1584,11 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, case NS_THEME_CHECKBOX_LABEL: case NS_THEME_RADIO_LABEL: case NS_THEME_BUTTON: - case NS_THEME_DROPDOWN: - case NS_THEME_TOOLBAR_BUTTON: - case NS_THEME_TREEVIEW_HEADER_CELL: + case NS_THEME_MENULIST: + case NS_THEME_TOOLBARBUTTON: + case NS_THEME_TREEHEADERCELL: { - if (aWidgetType == NS_THEME_DROPDOWN) { + if (aWidgetType == NS_THEME_MENULIST) { // Include the arrow size. moz_gtk_get_arrow_size(MOZ_GTK_DROPDOWN, &aResult->width, &aResult->height); @@ -1612,7 +1612,7 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, } break; #endif - case NS_THEME_TOOLBAR_SEPARATOR: + case NS_THEME_SEPARATOR: { gint separator_width; @@ -1626,9 +1626,9 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, aResult->width = 14; aResult->height = 26; break; - case NS_THEME_TREEVIEW_HEADER_SORTARROW: - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_TREEHEADERSORTARROW: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: // hard code these sizes aResult->width = 14; aResult->height = 13; @@ -1638,8 +1638,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, aResult->width = aResult->height = 15; *aIsOverridable = false; break; - case NS_THEME_TREEVIEW_TWISTY: - case NS_THEME_TREEVIEW_TWISTY_OPEN: + case NS_THEME_TREETWISTY: + case NS_THEME_TREETWISTYOPEN: { gint expander_size; @@ -1664,10 +1664,10 @@ nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, if (aWidgetType == NS_THEME_TOOLBOX || aWidgetType == NS_THEME_TOOLBAR || aWidgetType == NS_THEME_STATUSBAR || - aWidgetType == NS_THEME_STATUSBAR_PANEL || - aWidgetType == NS_THEME_STATUSBAR_RESIZER_PANEL || - aWidgetType == NS_THEME_PROGRESSBAR_CHUNK || - aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL || + aWidgetType == NS_THEME_STATUSBARPANEL || + aWidgetType == NS_THEME_RESIZER_PANEL || + aWidgetType == NS_THEME_PROGRESSCHUNK || + aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL || aWidgetType == NS_THEME_PROGRESSBAR || aWidgetType == NS_THEME_PROGRESSBAR_VERTICAL || aWidgetType == NS_THEME_MENUBAR || @@ -1680,17 +1680,17 @@ nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, return NS_OK; } - if ((aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL || - aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) && + if ((aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL || + aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) && aAttribute == nsGkAtoms::active) { *aShouldRepaint = true; return NS_OK; } - if ((aWidgetType == NS_THEME_SCROLLBAR_BUTTON_UP || - aWidgetType == NS_THEME_SCROLLBAR_BUTTON_DOWN || - aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT || - aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT) && + if ((aWidgetType == NS_THEME_SCROLLBARBUTTON_UP || + aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN || + aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT || + aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT) && (aAttribute == nsGkAtoms::curpos || aAttribute == nsGkAtoms::maxpos)) { // If 'curpos' has changed and we are passed its old value, we can @@ -1759,9 +1759,9 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext, switch (aWidgetType) { // Combobox dropdowns don't support native theming in vertical mode. - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_TEXT: - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_TEXT: + case NS_THEME_MENULIST_TEXTFIELD: if (aFrame && aFrame->GetWritingMode().IsVertical()) { return false; } @@ -1773,67 +1773,67 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext, case NS_THEME_CHECKBOX: case NS_THEME_TOOLBOX: // N/A case NS_THEME_TOOLBAR: - case NS_THEME_TOOLBAR_BUTTON: - case NS_THEME_TOOLBAR_DUAL_BUTTON: // so we can override the border with 0 - case NS_THEME_TOOLBAR_BUTTON_DROPDOWN: + case NS_THEME_TOOLBARBUTTON: + case NS_THEME_DUALBUTTON: // so we can override the border with 0 + case NS_THEME_TOOLBARBUTTON_DROPDOWN: case NS_THEME_BUTTON_ARROW_UP: case NS_THEME_BUTTON_ARROW_DOWN: case NS_THEME_BUTTON_ARROW_NEXT: case NS_THEME_BUTTON_ARROW_PREVIOUS: - case NS_THEME_TOOLBAR_SEPARATOR: - case NS_THEME_TOOLBAR_GRIPPER: + case NS_THEME_SEPARATOR: + case NS_THEME_TOOLBARGRIPPER: case NS_THEME_STATUSBAR: - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: case NS_THEME_RESIZER: case NS_THEME_LISTBOX: - // case NS_THEME_LISTBOX_LISTITEM: + // case NS_THEME_LISTITEM: case NS_THEME_TREEVIEW: - // case NS_THEME_TREEVIEW_TREEITEM: - case NS_THEME_TREEVIEW_TWISTY: - // case NS_THEME_TREEVIEW_LINE: - // case NS_THEME_TREEVIEW_HEADER: - case NS_THEME_TREEVIEW_HEADER_CELL: - case NS_THEME_TREEVIEW_HEADER_SORTARROW: - case NS_THEME_TREEVIEW_TWISTY_OPEN: + // case NS_THEME_TREEITEM: + case NS_THEME_TREETWISTY: + // case NS_THEME_TREELINE: + // case NS_THEME_TREEHEADER: + case NS_THEME_TREEHEADERCELL: + case NS_THEME_TREEHEADERSORTARROW: + case NS_THEME_TREETWISTYOPEN: case NS_THEME_PROGRESSBAR: - case NS_THEME_PROGRESSBAR_CHUNK: + case NS_THEME_PROGRESSCHUNK: case NS_THEME_PROGRESSBAR_VERTICAL: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_PROGRESSCHUNK_VERTICAL: case NS_THEME_TAB: - // case NS_THEME_TAB_PANEL: - case NS_THEME_TAB_PANELS: - case NS_THEME_TAB_SCROLLARROW_BACK: - case NS_THEME_TAB_SCROLLARROW_FORWARD: + // case NS_THEME_TABPANEL: + case NS_THEME_TABPANELS: + case NS_THEME_TAB_SCROLL_ARROW_BACK: + case NS_THEME_TAB_SCROLL_ARROW_FORWARD: case NS_THEME_TOOLTIP: case NS_THEME_SPINNER: - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: case NS_THEME_SPINNER_TEXTFIELD: // case NS_THEME_SCROLLBAR: (n/a for gtk) // case NS_THEME_SCROLLBAR_SMALL: (n/a for gtk) - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: case NS_THEME_SCROLLBAR_HORIZONTAL: case NS_THEME_SCROLLBAR_VERTICAL: - case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: - case NS_THEME_SCROLLBAR_TRACK_VERTICAL: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + case NS_THEME_SCROLLBARTRACK_HORIZONTAL: + case NS_THEME_SCROLLBARTRACK_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: case NS_THEME_NUMBER_INPUT: case NS_THEME_TEXTFIELD: case NS_THEME_TEXTFIELD_MULTILINE: case NS_THEME_RANGE: case NS_THEME_RANGE_THUMB: case NS_THEME_SCALE_HORIZONTAL: - case NS_THEME_SCALE_THUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: case NS_THEME_SCALE_VERTICAL: - case NS_THEME_SCALE_THUMB_VERTICAL: - // case NS_THEME_SCALE_THUMB_START: - // case NS_THEME_SCALE_THUMB_END: - // case NS_THEME_SCALE_TICK: + case NS_THEME_SCALETHUMB_VERTICAL: + // case NS_THEME_SCALETHUMBSTART: + // case NS_THEME_SCALETHUMBEND: + // case NS_THEME_SCALETHUMBTICK: case NS_THEME_CHECKBOX_CONTAINER: case NS_THEME_RADIO_CONTAINER: case NS_THEME_CHECKBOX_LABEL: @@ -1853,7 +1853,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext, #endif return !IsWidgetStyled(aPresContext, aFrame, aWidgetType); - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST_BUTTON: if (aFrame && aFrame->GetWritingMode().IsVertical()) { return false; } @@ -1873,12 +1873,12 @@ NS_IMETHODIMP_(bool) nsNativeThemeGTK::WidgetIsContainer(uint8_t aWidgetType) { // XXXdwh At some point flesh all of this out. - if (aWidgetType == NS_THEME_DROPDOWN_BUTTON || + if (aWidgetType == NS_THEME_MENULIST_BUTTON || aWidgetType == NS_THEME_RADIO || aWidgetType == NS_THEME_RANGE_THUMB || aWidgetType == NS_THEME_CHECKBOX || - aWidgetType == NS_THEME_TAB_SCROLLARROW_BACK || - aWidgetType == NS_THEME_TAB_SCROLLARROW_FORWARD || + aWidgetType == NS_THEME_TAB_SCROLL_ARROW_BACK || + aWidgetType == NS_THEME_TAB_SCROLL_ARROW_FORWARD || aWidgetType == NS_THEME_BUTTON_ARROW_UP || aWidgetType == NS_THEME_BUTTON_ARROW_DOWN || aWidgetType == NS_THEME_BUTTON_ARROW_NEXT || @@ -1890,9 +1890,9 @@ nsNativeThemeGTK::WidgetIsContainer(uint8_t aWidgetType) bool nsNativeThemeGTK::ThemeDrawsFocusForWidget(uint8_t aWidgetType) { - if (aWidgetType == NS_THEME_DROPDOWN || + if (aWidgetType == NS_THEME_MENULIST || aWidgetType == NS_THEME_BUTTON || - aWidgetType == NS_THEME_TREEVIEW_HEADER_CELL) + aWidgetType == NS_THEME_TREEHEADERCELL) return true; return false; diff --git a/widget/nsNativeTheme.cpp b/widget/nsNativeTheme.cpp index 5e340ee93f75..0b2fa4a1fb0d 100644 --- a/widget/nsNativeTheme.cpp +++ b/widget/nsNativeTheme.cpp @@ -231,7 +231,7 @@ nsNativeTheme::IsButtonTypeMenu(nsIFrame* aFrame) bool nsNativeTheme::IsPressedButton(nsIFrame* aFrame) { - EventStates eventState = GetContentState(aFrame, NS_THEME_TOOLBAR_BUTTON); + EventStates eventState = GetContentState(aFrame, NS_THEME_TOOLBARBUTTON); if (IsDisabled(aFrame, eventState)) return false; @@ -295,9 +295,9 @@ nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame, * Progress bar appearance should be the same for the bar and the container * frame. nsProgressFrame owns the logic and will tell us what we should do. */ - if (aWidgetType == NS_THEME_PROGRESSBAR_CHUNK || + if (aWidgetType == NS_THEME_PROGRESSCHUNK || aWidgetType == NS_THEME_PROGRESSBAR) { - nsProgressFrame* progressFrame = do_QueryFrame(aWidgetType == NS_THEME_PROGRESSBAR_CHUNK + nsProgressFrame* progressFrame = do_QueryFrame(aWidgetType == NS_THEME_PROGRESSCHUNK ? aFrame->GetParent() : aFrame); if (progressFrame) { return !progressFrame->ShouldUseNativeStyle(); @@ -308,9 +308,9 @@ nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame, * Meter bar appearance should be the same for the bar and the container * frame. nsMeterFrame owns the logic and will tell us what we should do. */ - if (aWidgetType == NS_THEME_METERBAR_CHUNK || + if (aWidgetType == NS_THEME_METERCHUNK || aWidgetType == NS_THEME_METERBAR) { - nsMeterFrame* meterFrame = do_QueryFrame(aWidgetType == NS_THEME_METERBAR_CHUNK + nsMeterFrame* meterFrame = do_QueryFrame(aWidgetType == NS_THEME_METERCHUNK ? aFrame->GetParent() : aFrame); if (meterFrame) { return !meterFrame->ShouldUseNativeStyle(); @@ -332,8 +332,8 @@ nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame, } } - if (aWidgetType == NS_THEME_SPINNER_UP_BUTTON || - aWidgetType == NS_THEME_SPINNER_DOWN_BUTTON) { + if (aWidgetType == NS_THEME_SPINNER_UPBUTTON || + aWidgetType == NS_THEME_SPINNER_DOWNBUTTON) { nsNumberControlFrame* numberControlFrame = nsNumberControlFrame::GetNumberControlFrameForSpinButton(aFrame); if (numberControlFrame) { @@ -346,7 +346,7 @@ nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame, aWidgetType == NS_THEME_TEXTFIELD || aWidgetType == NS_THEME_TEXTFIELD_MULTILINE || aWidgetType == NS_THEME_LISTBOX || - aWidgetType == NS_THEME_DROPDOWN) && + aWidgetType == NS_THEME_MENULIST) && aFrame->GetContent()->IsHTMLElement() && aPresContext->HasAuthorSpecifiedRules(aFrame, NS_AUTHOR_SPECIFIED_BORDER | diff --git a/widget/windows/nsBidiKeyboard.cpp b/widget/windows/nsBidiKeyboard.cpp index c186679d9378..1fac24d6c55f 100644 --- a/widget/windows/nsBidiKeyboard.cpp +++ b/widget/windows/nsBidiKeyboard.cpp @@ -6,11 +6,8 @@ #include #include "nsBidiKeyboard.h" +#include "WidgetUtils.h" #include "prmem.h" -#include "nsServiceManagerUtils.h" -#include "nsTArray.h" -#include "nsContentUtils.h" -#include "mozilla/dom/ContentParent.h" #include NS_IMPL_ISUPPORTS(nsBidiKeyboard, nsIBidiKeyboard) @@ -186,19 +183,5 @@ bool nsBidiKeyboard::IsRTLLanguage(HKL aLocale) void nsBidiKeyboard::OnLayoutChange() { - nsCOMPtr bidiKeyboard = nsContentUtils::GetBidiKeyboard(); - if (!bidiKeyboard) { - return; - } - - bool rtl; - if (NS_FAILED(bidiKeyboard->IsLangRTL(&rtl))) { - return; - } - - nsTArray children; - mozilla::dom::ContentParent::GetAll(children); - for (uint32_t i = 0; i < children.Length(); i++) { - children[i]->SendBidiKeyboardNotify(rtl); - } + mozilla::widget::WidgetUtils::SendBidiKeyboardInfoToContent(); } diff --git a/widget/windows/nsNativeThemeWin.cpp b/widget/windows/nsNativeThemeWin.cpp index b402e9a404d7..9f89dae8265b 100644 --- a/widget/windows/nsNativeThemeWin.cpp +++ b/widget/windows/nsNativeThemeWin.cpp @@ -680,7 +680,7 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType, EventStates eventStates = GetContentState(parentFrame, aWidgetType); bool vertical = IsVerticalProgress(parentFrame) || - aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL; + aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL; bool indeterminate = IsIndeterminateProgress(parentFrame, eventStates); bool animate = indeterminate; @@ -728,7 +728,7 @@ nsNativeThemeWin::GetTheme(uint8_t aWidgetType) // doing it the right way works fine with the MS themes, // but breaks on a lot of custom themes (presumably because MS // apps do the textfield border business as well). - if (aWidgetType == NS_THEME_DROPDOWN) + if (aWidgetType == NS_THEME_MENULIST) aWidgetType = NS_THEME_TEXTFIELD; } @@ -753,58 +753,58 @@ nsNativeThemeWin::GetTheme(uint8_t aWidgetType) return nsUXThemeData::GetTheme(eUXMediaRebar); case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX: return nsUXThemeData::GetTheme(eUXCommunicationsRebar); - case NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX: + case NS_THEME_WIN_BROWSERTABBAR_TOOLBOX: return nsUXThemeData::GetTheme(eUXBrowserTabBarRebar); case NS_THEME_TOOLBAR: - case NS_THEME_TOOLBAR_BUTTON: - case NS_THEME_TOOLBAR_SEPARATOR: + case NS_THEME_TOOLBARBUTTON: + case NS_THEME_SEPARATOR: return nsUXThemeData::GetTheme(eUXToolbar); case NS_THEME_PROGRESSBAR: case NS_THEME_PROGRESSBAR_VERTICAL: - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: return nsUXThemeData::GetTheme(eUXProgress); case NS_THEME_TAB: - case NS_THEME_TAB_PANEL: - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANEL: + case NS_THEME_TABPANELS: return nsUXThemeData::GetTheme(eUXTab); case NS_THEME_SCROLLBAR: case NS_THEME_SCROLLBAR_SMALL: case NS_THEME_SCROLLBAR_VERTICAL: case NS_THEME_SCROLLBAR_HORIZONTAL: - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: return nsUXThemeData::GetTheme(eUXScrollbar); case NS_THEME_RANGE: case NS_THEME_RANGE_THUMB: case NS_THEME_SCALE_HORIZONTAL: case NS_THEME_SCALE_VERTICAL: - case NS_THEME_SCALE_THUMB_HORIZONTAL: - case NS_THEME_SCALE_THUMB_VERTICAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_VERTICAL: return nsUXThemeData::GetTheme(eUXTrackbar); - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: return nsUXThemeData::GetTheme(eUXSpin); case NS_THEME_STATUSBAR: - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: case NS_THEME_RESIZER: return nsUXThemeData::GetTheme(eUXStatus); - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_BUTTON: return nsUXThemeData::GetTheme(eUXCombobox); - case NS_THEME_TREEVIEW_HEADER_CELL: - case NS_THEME_TREEVIEW_HEADER_SORTARROW: + case NS_THEME_TREEHEADERCELL: + case NS_THEME_TREEHEADERSORTARROW: return nsUXThemeData::GetTheme(eUXHeader); case NS_THEME_LISTBOX: - case NS_THEME_LISTBOX_LISTITEM: + case NS_THEME_LISTITEM: case NS_THEME_TREEVIEW: - case NS_THEME_TREEVIEW_TWISTY_OPEN: - case NS_THEME_TREEVIEW_TREEITEM: + case NS_THEME_TREETWISTYOPEN: + case NS_THEME_TREEITEM: return nsUXThemeData::GetTheme(eUXListview); case NS_THEME_MENUBAR: case NS_THEME_MENUPOPUP: @@ -875,7 +875,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, { if (!IsVistaOrLater()) { // See GetTheme - if (aWidgetType == NS_THEME_DROPDOWN) + if (aWidgetType == NS_THEME_MENULIST) aWidgetType = NS_THEME_TEXTFIELD; } @@ -1026,10 +1026,10 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, aState = PBBS_NORMAL; return NS_OK; } - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: { + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: { nsIFrame* parentFrame = aFrame->GetParent(); - if (aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL || + if (aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL || IsVerticalProgress(parentFrame)) { aPart = IsVistaOrLater() ? PP_FILLVERT : PP_CHUNKVERT; @@ -1041,7 +1041,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, aState = PBBVS_NORMAL; return NS_OK; } - case NS_THEME_TOOLBAR_BUTTON: { + case NS_THEME_TOOLBARBUTTON: { aPart = BP_BUTTON; if (!aFrame) { aState = TS_NORMAL; @@ -1075,17 +1075,17 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, return NS_OK; } - case NS_THEME_TOOLBAR_SEPARATOR: { + case NS_THEME_SEPARATOR: { aPart = TP_SEPARATOR; aState = TS_NORMAL; return NS_OK; } - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: { + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: { aPart = SP_BUTTON; - aState = (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP)*4; + aState = (aWidgetType - NS_THEME_SCROLLBARBUTTON_UP)*4; EventStates eventState = GetContentState(aFrame, aWidgetType); if (!aFrame) aState += TS_NORMAL; @@ -1101,7 +1101,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, aState += TS_HOVER; else if (IsVistaOrLater() && parentState.HasState(NS_EVENT_STATE_HOVER)) - aState = (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP) + SP_BUTTON_IMPLICIT_HOVER_BASE; + aState = (aWidgetType - NS_THEME_SCROLLBARBUTTON_UP) + SP_BUTTON_IMPLICIT_HOVER_BASE; else aState += TS_NORMAL; } @@ -1114,9 +1114,9 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, aState = TS_NORMAL; return NS_OK; } - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: { - aPart = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) ? + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: { + aPart = (aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) ? SP_THUMBHOR : SP_THUMBVERT; EventStates eventState = GetContentState(aFrame, aWidgetType); if (!aFrame) @@ -1150,8 +1150,8 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, return NS_OK; } case NS_THEME_RANGE_THUMB: - case NS_THEME_SCALE_THUMB_HORIZONTAL: - case NS_THEME_SCALE_THUMB_VERTICAL: { + case NS_THEME_SCALETHUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_VERTICAL: { if (aWidgetType == NS_THEME_RANGE_THUMB) { if (IsRangeHorizontal(aFrame)) { aPart = TKP_THUMBBOTTOM; @@ -1159,7 +1159,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, aPart = IsFrameRTL(aFrame) ? TKP_THUMBLEFT : TKP_THUMBRIGHT; } } else { - aPart = (aWidgetType == NS_THEME_SCALE_THUMB_HORIZONTAL) ? + aPart = (aWidgetType == NS_THEME_SCALETHUMB_HORIZONTAL) ? TKP_THUMB : TKP_THUMBVERT; } EventStates eventState = GetContentState(aFrame, aWidgetType); @@ -1182,9 +1182,9 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, } return NS_OK; } - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: { - aPart = (aWidgetType == NS_THEME_SPINNER_UP_BUTTON) ? + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: { + aPart = (aWidgetType == NS_THEME_SPINNER_UPBUTTON) ? SPNP_UP : SPNP_DOWN; EventStates eventState = GetContentState(aFrame, aWidgetType); if (!aFrame) @@ -1198,7 +1198,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, case NS_THEME_TOOLBOX: case NS_THEME_WIN_MEDIA_TOOLBOX: case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX: - case NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX: + case NS_THEME_WIN_BROWSERTABBAR_TOOLBOX: case NS_THEME_STATUSBAR: case NS_THEME_SCROLLBAR: case NS_THEME_SCROLLBAR_SMALL: { @@ -1229,10 +1229,10 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, } return NS_OK; } - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: case NS_THEME_RESIZER: { - aPart = (aWidgetType - NS_THEME_STATUSBAR_PANEL) + 1; + aPart = (aWidgetType - NS_THEME_STATUSBARPANEL) + 1; aState = TS_NORMAL; return NS_OK; } @@ -1242,12 +1242,12 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, aState = TS_NORMAL; return NS_OK; } - case NS_THEME_TAB_PANELS: { + case NS_THEME_TABPANELS: { aPart = TABP_PANELS; aState = TS_NORMAL; return NS_OK; } - case NS_THEME_TAB_PANEL: { + case NS_THEME_TABPANEL: { aPart = TABP_PANEL; aState = TS_NORMAL; return NS_OK; @@ -1274,13 +1274,13 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, return NS_OK; } - case NS_THEME_TREEVIEW_HEADER_SORTARROW: { + case NS_THEME_TREEHEADERSORTARROW: { // XXX Probably will never work due to a bug in the Luna theme. aPart = 4; aState = 1; return NS_OK; } - case NS_THEME_TREEVIEW_HEADER_CELL: { + case NS_THEME_TREEHEADERCELL: { aPart = 1; if (!aFrame) { aState = TS_NORMAL; @@ -1291,7 +1291,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, return NS_OK; } - case NS_THEME_DROPDOWN: { + case NS_THEME_MENULIST: { nsIContent* content = aFrame->GetContent(); bool isHTML = content && content->IsHTMLElement(); bool useDropBorder = isHTML || IsMenuListEditable(aFrame); @@ -1324,7 +1324,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, return NS_OK; } - case NS_THEME_DROPDOWN_BUTTON: { + case NS_THEME_MENULIST_BUTTON: { bool isHTML = IsHTMLContent(aFrame); nsIFrame* parentFrame = aFrame->GetParent(); bool isMenulist = !isHTML && parentFrame->GetType() == nsGkAtoms::menuFrame; @@ -1341,7 +1341,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, // For HTML controls with author styling, we should fall // back to the old dropmarker style to avoid clashes with // author-specified backgrounds and borders (bug #441034) - if (isHTML && IsWidgetStyled(aFrame->PresContext(), aFrame, NS_THEME_DROPDOWN)) + if (isHTML && IsWidgetStyled(aFrame->PresContext(), aFrame, NS_THEME_MENULIST)) aPart = CBP_DROPMARKER; if (IsDisabled(aFrame, eventState)) { @@ -1848,7 +1848,7 @@ RENDER_AGAIN: } // The following widgets need to be RTL-aware else if (aWidgetType == NS_THEME_RESIZER || - aWidgetType == NS_THEME_DROPDOWN_BUTTON) + aWidgetType == NS_THEME_MENULIST_BUTTON) { DrawThemeBGRTLAware(theme, hdc, part, state, &widgetRect, &clipRect, IsFrameRTL(aFrame)); @@ -1875,8 +1875,8 @@ RENDER_AGAIN: SetPixel(hdc, widgetRect.right-1, widgetRect.bottom-1, color); SetPixel(hdc, widgetRect.left, widgetRect.bottom-1, color); } - else if (aWidgetType == NS_THEME_PROGRESSBAR_CHUNK || - aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL) { + else if (aWidgetType == NS_THEME_PROGRESSCHUNK || + aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL) { DrawThemedProgressMeter(aFrame, aWidgetType, theme, hdc, part, state, &widgetRect, &clipRect, p2a); } @@ -1966,14 +1966,14 @@ RENDER_AGAIN: widgetRect.bottom = widgetRect.top + TB_SEPARATOR_HEIGHT; DrawThemeEdge(theme, hdc, RP_BAND, 0, &widgetRect, EDGE_ETCHED, BF_TOP, nullptr); } - else if (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL || - aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL) + else if (aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL || + aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL) { // Draw the decorative gripper for the scrollbar thumb button, if it fits SIZE gripSize; MARGINS thumbMgns; - int gripPart = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) ? + int gripPart = (aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) ? SP_GRIPPERHOR : SP_GRIPPERVERT; if (GetThemePartSize(theme, hdc, gripPart, state, nullptr, TS_TRUE, &gripSize) == S_OK && @@ -2037,15 +2037,15 @@ nsNativeThemeWin::GetWidgetBorder(nsDeviceContext* aContext, aWidgetType == NS_THEME_TOOLBOX || aWidgetType == NS_THEME_WIN_MEDIA_TOOLBOX || aWidgetType == NS_THEME_WIN_COMMUNICATIONS_TOOLBOX || - aWidgetType == NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX || + aWidgetType == NS_THEME_WIN_BROWSERTABBAR_TOOLBOX || aWidgetType == NS_THEME_STATUSBAR || - aWidgetType == NS_THEME_RESIZER || aWidgetType == NS_THEME_TAB_PANEL || + aWidgetType == NS_THEME_RESIZER || aWidgetType == NS_THEME_TABPANEL || aWidgetType == NS_THEME_SCROLLBAR_HORIZONTAL || aWidgetType == NS_THEME_SCROLLBAR_VERTICAL || aWidgetType == NS_THEME_MENUITEM || aWidgetType == NS_THEME_CHECKMENUITEM || aWidgetType == NS_THEME_RADIOMENUITEM || aWidgetType == NS_THEME_MENUPOPUP || aWidgetType == NS_THEME_MENUIMAGE || aWidgetType == NS_THEME_MENUITEMTEXT || - aWidgetType == NS_THEME_TOOLBAR_SEPARATOR || + aWidgetType == NS_THEME_SEPARATOR || aWidgetType == NS_THEME_WINDOW_TITLEBAR || aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED || aWidgetType == NS_THEME_WIN_GLASS || aWidgetType == NS_THEME_WIN_BORDERLESS_GLASS) @@ -2176,7 +2176,7 @@ nsNativeThemeWin::GetWidgetPadding(nsDeviceContext* aContext, if (aWidgetType == NS_THEME_NUMBER_INPUT || aWidgetType == NS_THEME_TEXTFIELD || aWidgetType == NS_THEME_TEXTFIELD_MULTILINE || - aWidgetType == NS_THEME_DROPDOWN) + aWidgetType == NS_THEME_MENULIST) { /* If we have author-specified padding for these elements, don't do the fixups below */ if (aFrame->PresContext()->HasAuthorSpecifiedRules(aFrame, NS_AUTHOR_SPECIFIED_PADDING)) @@ -2196,7 +2196,7 @@ nsNativeThemeWin::GetWidgetPadding(nsDeviceContext* aContext, aResult->left = aResult->right = 2; ScaleForFrameDPI(aResult, aFrame); return ok; - } else if (IsHTMLContent(aFrame) && aWidgetType == NS_THEME_DROPDOWN) { + } else if (IsHTMLContent(aFrame) && aWidgetType == NS_THEME_MENULIST) { /* For content menulist controls, we need an extra pixel so * that we have room to draw our focus rectangle stuff. * Otherwise, the focus rect might overlap the control's @@ -2276,11 +2276,11 @@ nsNativeThemeWin::GetWidgetOverflow(nsDeviceContext* aContext, * up, right, and bottom so that they overlap the dropdown's border * like they're supposed to. */ - if (aWidgetType == NS_THEME_DROPDOWN_BUTTON && + if (aWidgetType == NS_THEME_MENULIST_BUTTON && IsHTMLContent(aFrame) && !IsWidgetStyled(aFrame->GetParent()->PresContext(), aFrame->GetParent(), - NS_THEME_DROPDOWN)) + NS_THEME_MENULIST)) { int32_t p2a = aContext->AppUnitsPerDevPixel(); /* Note: no overflow on the left */ @@ -2330,13 +2330,13 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF case NS_THEME_TOOLBOX: case NS_THEME_WIN_MEDIA_TOOLBOX: case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX: - case NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX: + case NS_THEME_WIN_BROWSERTABBAR_TOOLBOX: case NS_THEME_TOOLBAR: case NS_THEME_STATUSBAR: - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: - case NS_THEME_TAB_PANELS: - case NS_THEME_TAB_PANEL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: + case NS_THEME_TABPANELS: + case NS_THEME_TABPANEL: case NS_THEME_LISTBOX: case NS_THEME_TREEVIEW: case NS_THEME_MENUITEMTEXT: @@ -2353,15 +2353,15 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF // Windows appears to always use metrics when drawing standard scrollbars) THEMESIZE sizeReq = TS_TRUE; // Best-fit size switch (aWidgetType) { - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: case NS_THEME_SCROLLBAR_HORIZONTAL: case NS_THEME_SCROLLBAR_VERTICAL: - case NS_THEME_DROPDOWN_BUTTON: { + case NS_THEME_MENULIST_BUTTON: { rv = ClassicGetMinimumWidgetSize(aFrame, aWidgetType, aResult, aIsOverridable); ScaleForFrameDPI(aResult, aFrame); return rv; @@ -2407,14 +2407,14 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF break; case NS_THEME_RANGE_THUMB: - case NS_THEME_SCALE_THUMB_HORIZONTAL: - case NS_THEME_SCALE_THUMB_VERTICAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_VERTICAL: { *aIsOverridable = false; // on Vista, GetThemePartAndState returns odd values for // scale thumbs, so use a hardcoded size instead. if (IsVistaOrLater()) { - if (aWidgetType == NS_THEME_SCALE_THUMB_HORIZONTAL || + if (aWidgetType == NS_THEME_SCALETHUMB_HORIZONTAL || (aWidgetType == NS_THEME_RANGE_THUMB && IsRangeHorizontal(aFrame))) { aResult->width = 12; aResult->height = 20; @@ -2441,7 +2441,7 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF break; } - case NS_THEME_TOOLBAR_SEPARATOR: + case NS_THEME_SEPARATOR: // that's 2px left margin, 2px right margin and 2px separator // (the margin is drawn as part of the separator, though) aResult->width = 6; @@ -2553,8 +2553,8 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF aResult->height = sz.cy; switch(aWidgetType) { - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: aResult->width++; aResult->height = aResult->height / 2 + 1; break; @@ -2590,18 +2590,18 @@ nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, if (aWidgetType == NS_THEME_TOOLBOX || aWidgetType == NS_THEME_WIN_MEDIA_TOOLBOX || aWidgetType == NS_THEME_WIN_COMMUNICATIONS_TOOLBOX || - aWidgetType == NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX || + aWidgetType == NS_THEME_WIN_BROWSERTABBAR_TOOLBOX || aWidgetType == NS_THEME_TOOLBAR || - aWidgetType == NS_THEME_STATUSBAR || aWidgetType == NS_THEME_STATUSBAR_PANEL || - aWidgetType == NS_THEME_STATUSBAR_RESIZER_PANEL || - aWidgetType == NS_THEME_PROGRESSBAR_CHUNK || - aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL || + aWidgetType == NS_THEME_STATUSBAR || aWidgetType == NS_THEME_STATUSBARPANEL || + aWidgetType == NS_THEME_RESIZER_PANEL || + aWidgetType == NS_THEME_PROGRESSCHUNK || + aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL || aWidgetType == NS_THEME_PROGRESSBAR || aWidgetType == NS_THEME_PROGRESSBAR_VERTICAL || aWidgetType == NS_THEME_TOOLTIP || - aWidgetType == NS_THEME_TAB_PANELS || - aWidgetType == NS_THEME_TAB_PANEL || - aWidgetType == NS_THEME_TOOLBAR_SEPARATOR || + aWidgetType == NS_THEME_TABPANELS || + aWidgetType == NS_THEME_TABPANEL || + aWidgetType == NS_THEME_SEPARATOR || aWidgetType == NS_THEME_WIN_GLASS || aWidgetType == NS_THEME_WIN_BORDERLESS_GLASS) { *aShouldRepaint = false; @@ -2632,7 +2632,7 @@ nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, // We need to repaint the dropdown arrow in vista HTML combobox controls when // the control is closed to get rid of the hover effect. if (IsVistaOrLater() && - (aWidgetType == NS_THEME_DROPDOWN || aWidgetType == NS_THEME_DROPDOWN_BUTTON) && + (aWidgetType == NS_THEME_MENULIST || aWidgetType == NS_THEME_MENULIST_BUTTON) && IsHTMLContent(aFrame)) { *aShouldRepaint = true; @@ -2708,7 +2708,7 @@ bool nsNativeThemeWin::WidgetIsContainer(uint8_t aWidgetType) { // XXXdwh At some point flesh all of this out. - if (aWidgetType == NS_THEME_DROPDOWN_BUTTON || + if (aWidgetType == NS_THEME_MENULIST_BUTTON || aWidgetType == NS_THEME_RADIO || aWidgetType == NS_THEME_CHECKBOX) return false; @@ -2783,8 +2783,8 @@ nsNativeThemeWin::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) case NS_THEME_SCALE_VERTICAL: case NS_THEME_PROGRESSBAR: case NS_THEME_PROGRESSBAR_VERTICAL: - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: case NS_THEME_RANGE: return eTransparent; } @@ -2844,37 +2844,37 @@ nsNativeThemeWin::ClassicThemeSupportsWidget(nsIFrame* aFrame, case NS_THEME_RANGE: case NS_THEME_RANGE_THUMB: case NS_THEME_GROUPBOX: - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: case NS_THEME_SCROLLBAR_VERTICAL: case NS_THEME_SCROLLBAR_HORIZONTAL: case NS_THEME_SCROLLBAR_NON_DISAPPEARING: case NS_THEME_SCALE_HORIZONTAL: case NS_THEME_SCALE_VERTICAL: - case NS_THEME_SCALE_THUMB_HORIZONTAL: - case NS_THEME_SCALE_THUMB_VERTICAL: - case NS_THEME_DROPDOWN_BUTTON: - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SCALETHUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_VERTICAL: + case NS_THEME_MENULIST_BUTTON: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: case NS_THEME_LISTBOX: case NS_THEME_TREEVIEW: - case NS_THEME_DROPDOWN_TEXTFIELD: - case NS_THEME_DROPDOWN: + case NS_THEME_MENULIST_TEXTFIELD: + case NS_THEME_MENULIST: case NS_THEME_TOOLTIP: case NS_THEME_STATUSBAR: - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: case NS_THEME_PROGRESSBAR: case NS_THEME_PROGRESSBAR_VERTICAL: - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: case NS_THEME_TAB: - case NS_THEME_TAB_PANEL: - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANEL: + case NS_THEME_TABPANELS: case NS_THEME_MENUITEM: case NS_THEME_CHECKMENUITEM: case NS_THEME_RADIOMENUITEM: @@ -2916,8 +2916,8 @@ nsNativeThemeWin::ClassicGetWidgetBorder(nsDeviceContext* aContext, break; case NS_THEME_LISTBOX: case NS_THEME_TREEVIEW: - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_TEXTFIELD: case NS_THEME_TAB: case NS_THEME_NUMBER_INPUT: case NS_THEME_TEXTFIELD: @@ -2925,8 +2925,8 @@ nsNativeThemeWin::ClassicGetWidgetBorder(nsDeviceContext* aContext, case NS_THEME_FOCUS_OUTLINE: (*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 2; break; - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: { + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: { (*aResult).top = 1; (*aResult).left = 1; (*aResult).bottom = 1; @@ -3013,20 +3013,20 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIFrame* aFrame, (*aResult).width = ::GetSystemMetrics(SM_CXMENUCHECK); (*aResult).height = ::GetSystemMetrics(SM_CYMENUCHECK); break; - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: (*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL); (*aResult).height = 8; // No good metrics available for this *aIsOverridable = false; break; - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: (*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL); (*aResult).height = ::GetSystemMetrics(SM_CYVSCROLL); *aIsOverridable = false; break; - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: (*aResult).width = ::GetSystemMetrics(SM_CXHSCROLL); (*aResult).height = ::GetSystemMetrics(SM_CYHSCROLL); *aIsOverridable = false; @@ -3055,20 +3055,20 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIFrame* aFrame, *aIsOverridable = false; break; } - case NS_THEME_SCALE_THUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: (*aResult).width = 12; (*aResult).height = 20; *aIsOverridable = false; break; - case NS_THEME_SCALE_THUMB_VERTICAL: + case NS_THEME_SCALETHUMB_VERTICAL: (*aResult).width = 20; (*aResult).height = 12; *aIsOverridable = false; break; - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST_BUTTON: (*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL); break; - case NS_THEME_DROPDOWN: + case NS_THEME_MENULIST: case NS_THEME_BUTTON: case NS_THEME_GROUPBOX: case NS_THEME_LISTBOX: @@ -3076,18 +3076,18 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIFrame* aFrame, case NS_THEME_NUMBER_INPUT: case NS_THEME_TEXTFIELD: case NS_THEME_TEXTFIELD_MULTILINE: - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST_TEXTFIELD: case NS_THEME_STATUSBAR: - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: case NS_THEME_TOOLTIP: case NS_THEME_PROGRESSBAR: case NS_THEME_PROGRESSBAR_VERTICAL: case NS_THEME_TAB: - case NS_THEME_TAB_PANEL: - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANEL: + case NS_THEME_TABPANELS: // no minimum widget size break; case NS_THEME_RESIZER: { @@ -3099,7 +3099,7 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIFrame* aFrame, (*aResult).width = (*aResult).height = 15; *aIsOverridable = false; break; - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: (*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL); (*aResult).height = ::GetSystemMetrics(SM_CYVTHUMB); // Without theming, divide the thumb size by two in order to look more @@ -3108,7 +3108,7 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIFrame* aFrame, (*aResult).height >>= 1; *aIsOverridable = false; break; - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: (*aResult).width = ::GetSystemMetrics(SM_CXHTHUMB); (*aResult).height = ::GetSystemMetrics(SM_CYHSCROLL); // Without theming, divide the thumb size by two in order to look more @@ -3316,35 +3316,35 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, uint8_t case NS_THEME_FOCUS_OUTLINE: case NS_THEME_TEXTFIELD: case NS_THEME_TEXTFIELD_MULTILINE: - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_TEXTFIELD: case NS_THEME_RANGE: case NS_THEME_RANGE_THUMB: - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: case NS_THEME_SCROLLBAR_VERTICAL: case NS_THEME_SCROLLBAR_HORIZONTAL: case NS_THEME_SCALE_HORIZONTAL: case NS_THEME_SCALE_VERTICAL: - case NS_THEME_SCALE_THUMB_HORIZONTAL: - case NS_THEME_SCALE_THUMB_VERTICAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_VERTICAL: case NS_THEME_STATUSBAR: - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: case NS_THEME_TOOLTIP: case NS_THEME_PROGRESSBAR: case NS_THEME_PROGRESSBAR_VERTICAL: case NS_THEME_TAB: - case NS_THEME_TAB_PANEL: - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANEL: + case NS_THEME_TABPANELS: case NS_THEME_MENUBAR: case NS_THEME_MENUPOPUP: case NS_THEME_GROUPBOX: // these don't use DrawFrameControl return NS_OK; - case NS_THEME_DROPDOWN_BUTTON: { + case NS_THEME_MENULIST_BUTTON: { aPart = DFC_SCROLL; aState = DFCS_SCROLLCOMBOBOX; @@ -3383,24 +3383,24 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, uint8_t return NS_OK; } - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: { + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: { EventStates contentState = GetContentState(aFrame, aWidgetType); aPart = DFC_SCROLL; switch (aWidgetType) { - case NS_THEME_SCROLLBAR_BUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_UP: aState = DFCS_SCROLLUP; break; - case NS_THEME_SCROLLBAR_BUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_DOWN: aState = DFCS_SCROLLDOWN; break; - case NS_THEME_SCROLLBAR_BUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_LEFT: aState = DFCS_SCROLLLEFT; break; - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: aState = DFCS_SCROLLRIGHT; break; } @@ -3414,16 +3414,16 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, uint8_t return NS_OK; } - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: { + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: { EventStates contentState = GetContentState(aFrame, aWidgetType); aPart = DFC_SCROLL; switch (aWidgetType) { - case NS_THEME_SPINNER_UP_BUTTON: + case NS_THEME_SPINNER_UPBUTTON: aState = DFCS_SCROLLUP; break; - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: aState = DFCS_SCROLLDOWN; break; } @@ -3719,13 +3719,13 @@ RENDER_AGAIN: // Draw controls supported by DrawFrameControl case NS_THEME_CHECKBOX: case NS_THEME_RADIO: - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: + case NS_THEME_MENULIST_BUTTON: case NS_THEME_RESIZER: { int32_t oldTA; // setup DC to make DrawFrameControl draw correctly @@ -3753,8 +3753,8 @@ RENDER_AGAIN: case NS_THEME_TEXTFIELD: case NS_THEME_TEXTFIELD_MULTILINE: case NS_THEME_LISTBOX: - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_TEXTFIELD: { + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_TEXTFIELD: { // Draw inset edge ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); EventStates eventState = GetContentState(aFrame, aWidgetType); @@ -3796,15 +3796,15 @@ RENDER_AGAIN: ::DrawEdge(hdc, &widgetRect, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE); InflateRect(&widgetRect, -1, -1); // fall through - case NS_THEME_TAB_PANEL: + case NS_THEME_TABPANEL: case NS_THEME_STATUSBAR: - case NS_THEME_STATUSBAR_RESIZER_PANEL: { + case NS_THEME_RESIZER_PANEL: { ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_BTNFACE+1)); break; } // Draw 3D inset statusbar panel - case NS_THEME_STATUSBAR_PANEL: { + case NS_THEME_STATUSBARPANEL: { if (aFrame->GetNextSibling()) widgetRect.right -= 2; // space between sibling status panels @@ -3813,14 +3813,14 @@ RENDER_AGAIN: break; } // Draw scrollbar thumb - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_MIDDLE); break; case NS_THEME_RANGE_THUMB: - case NS_THEME_SCALE_THUMB_VERTICAL: - case NS_THEME_SCALE_THUMB_HORIZONTAL: { + case NS_THEME_SCALETHUMB_VERTICAL: + case NS_THEME_SCALETHUMB_HORIZONTAL: { EventStates eventState = GetContentState(aFrame, aWidgetType); ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST); @@ -3883,17 +3883,17 @@ RENDER_AGAIN: break; } - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_PROGRESSCHUNK_VERTICAL: ::FillRect(hdc, &widgetRect, (HBRUSH) (COLOR_HIGHLIGHT+1)); break; - case NS_THEME_PROGRESSBAR_CHUNK: { + case NS_THEME_PROGRESSCHUNK: { nsIFrame* stateFrame = aFrame->GetParent(); EventStates eventStates = GetContentState(stateFrame, aWidgetType); bool indeterminate = IsIndeterminateProgress(stateFrame, eventStates); bool vertical = IsVerticalProgress(stateFrame) || - aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL; + aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL; nsIContent* content = aFrame->GetContent(); if (!indeterminate || !content) { @@ -3923,7 +3923,7 @@ RENDER_AGAIN: break; } - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANELS: ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_SOFT | BF_MIDDLE | BF_LEFT | BF_RIGHT | BF_BOTTOM); @@ -4119,8 +4119,8 @@ nsNativeThemeWin::GetWidgetNativeDrawingFlags(uint8_t aWidgetType) case NS_THEME_TEXTFIELD: case NS_THEME_TEXTFIELD_MULTILINE: - case NS_THEME_DROPDOWN: - case NS_THEME_DROPDOWN_TEXTFIELD: + case NS_THEME_MENULIST: + case NS_THEME_MENULIST_TEXTFIELD: return gfxWindowsNativeDrawing::CANNOT_DRAW_TO_COLOR_ALPHA | gfxWindowsNativeDrawing::CAN_AXIS_ALIGNED_SCALE | @@ -4129,34 +4129,34 @@ nsNativeThemeWin::GetWidgetNativeDrawingFlags(uint8_t aWidgetType) // need to check these others case NS_THEME_RANGE: case NS_THEME_RANGE_THUMB: - case NS_THEME_SCROLLBAR_BUTTON_UP: - case NS_THEME_SCROLLBAR_BUTTON_DOWN: - case NS_THEME_SCROLLBAR_BUTTON_LEFT: - case NS_THEME_SCROLLBAR_BUTTON_RIGHT: - case NS_THEME_SCROLLBAR_THUMB_VERTICAL: - case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBARBUTTON_UP: + case NS_THEME_SCROLLBARBUTTON_DOWN: + case NS_THEME_SCROLLBARBUTTON_LEFT: + case NS_THEME_SCROLLBARBUTTON_RIGHT: + case NS_THEME_SCROLLBARTHUMB_VERTICAL: + case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: case NS_THEME_SCROLLBAR_VERTICAL: case NS_THEME_SCROLLBAR_HORIZONTAL: case NS_THEME_SCALE_HORIZONTAL: case NS_THEME_SCALE_VERTICAL: - case NS_THEME_SCALE_THUMB_HORIZONTAL: - case NS_THEME_SCALE_THUMB_VERTICAL: - case NS_THEME_SPINNER_UP_BUTTON: - case NS_THEME_SPINNER_DOWN_BUTTON: + case NS_THEME_SCALETHUMB_HORIZONTAL: + case NS_THEME_SCALETHUMB_VERTICAL: + case NS_THEME_SPINNER_UPBUTTON: + case NS_THEME_SPINNER_DOWNBUTTON: case NS_THEME_LISTBOX: case NS_THEME_TREEVIEW: case NS_THEME_TOOLTIP: case NS_THEME_STATUSBAR: - case NS_THEME_STATUSBAR_PANEL: - case NS_THEME_STATUSBAR_RESIZER_PANEL: + case NS_THEME_STATUSBARPANEL: + case NS_THEME_RESIZER_PANEL: case NS_THEME_RESIZER: case NS_THEME_PROGRESSBAR: case NS_THEME_PROGRESSBAR_VERTICAL: - case NS_THEME_PROGRESSBAR_CHUNK: - case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: + case NS_THEME_PROGRESSCHUNK: + case NS_THEME_PROGRESSCHUNK_VERTICAL: case NS_THEME_TAB: - case NS_THEME_TAB_PANEL: - case NS_THEME_TAB_PANELS: + case NS_THEME_TABPANEL: + case NS_THEME_TABPANELS: case NS_THEME_MENUBAR: case NS_THEME_MENUPOPUP: case NS_THEME_MENUITEM: @@ -4165,7 +4165,7 @@ nsNativeThemeWin::GetWidgetNativeDrawingFlags(uint8_t aWidgetType) // the dropdown button /almost/ renders correctly with scaling, // except that the graphic in the dropdown button (the downward arrow) // doesn't get scaled up. - case NS_THEME_DROPDOWN_BUTTON: + case NS_THEME_MENULIST_BUTTON: // these are definitely no; they're all graphics that don't get scaled up case NS_THEME_CHECKBOX: case NS_THEME_RADIO: diff --git a/xpcom/glue/AutoRestore.h b/xpcom/glue/AutoRestore.h index 9ea790035c00..20909c92c305 100644 --- a/xpcom/glue/AutoRestore.h +++ b/xpcom/glue/AutoRestore.h @@ -44,6 +44,10 @@ public: { mLocation = mValue; } + T SavedValue() const + { + return mValue; + } }; } // namespace mozilla diff --git a/xpcom/io/Base64.cpp b/xpcom/io/Base64.cpp index 174671f58bd5..88bb445282ac 100644 --- a/xpcom/io/Base64.cpp +++ b/xpcom/io/Base64.cpp @@ -282,139 +282,178 @@ Base64EncodeInputStream(nsIInputStream* aInputStream, } nsresult -Base64Encode(const nsACString& aBinaryData, nsACString& aString) +Base64Encode(const char* aBinary, uint32_t aBinaryLen, char** aBase64) { // Check for overflow. - if (aBinaryData.Length() > (UINT32_MAX / 4) * 3) { + if (aBinaryLen > (UINT32_MAX / 4) * 3) { return NS_ERROR_FAILURE; } - // Don't ask PR_Base64Encode to encode empty strings - if (aBinaryData.IsEmpty()) { - aString.Truncate(); + // Don't ask PR_Base64Encode to encode empty strings. + if (aBinaryLen == 0) { + char* base64 = (char*)moz_xmalloc(1); + base64[0] = '\0'; + *aBase64 = base64; return NS_OK; } - uint32_t stringLen = ((aBinaryData.Length() + 2) / 3) * 4; - - char* buffer; + uint32_t base64Len = ((aBinaryLen + 2) / 3) * 4; // Add one byte for null termination. - if (aString.SetCapacity(stringLen + 1, fallible) && - (buffer = aString.BeginWriting()) && - PL_Base64Encode(aBinaryData.BeginReading(), aBinaryData.Length(), buffer)) { - // PL_Base64Encode doesn't null terminate the buffer for us when we pass - // the buffer in. Do that manually. - buffer[stringLen] = '\0'; - - aString.SetLength(stringLen); - return NS_OK; + char* base64 = (char*)malloc(base64Len + 1); + if (!base64) { + return NS_ERROR_OUT_OF_MEMORY; } - aString.Truncate(); - return NS_ERROR_INVALID_ARG; + if (!PL_Base64Encode(aBinary, aBinaryLen, base64)) { + free(base64); + return NS_ERROR_INVALID_ARG; + } + + // PL_Base64Encode doesn't null terminate the buffer for us when we pass + // the buffer in. Do that manually. + base64[base64Len] = '\0'; + + *aBase64 = base64; + return NS_OK; } nsresult -Base64Encode(const nsAString& aString, nsAString& aBinaryData) +Base64Encode(const nsACString& aBinary, nsACString& aBase64) { - NS_LossyConvertUTF16toASCII string(aString); - nsAutoCString binaryData; + // Check for overflow. + if (aBinary.Length() > (UINT32_MAX / 4) * 3) { + return NS_ERROR_FAILURE; + } - nsresult rv = Base64Encode(string, binaryData); + // Don't ask PR_Base64Encode to encode empty strings. + if (aBinary.IsEmpty()) { + aBase64.Truncate(); + return NS_OK; + } + + uint32_t base64Len = ((aBinary.Length() + 2) / 3) * 4; + + // Add one byte for null termination. + if (!aBase64.SetCapacity(base64Len + 1, fallible)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + char* base64 = aBase64.BeginWriting(); + if (!base64 || + !PL_Base64Encode(aBinary.BeginReading(), aBinary.Length(), base64)) { + aBase64.Truncate(); + return NS_ERROR_INVALID_ARG; + } + + // PL_Base64Encode doesn't null terminate the buffer for us when we pass + // the buffer in. Do that manually. + base64[base64Len] = '\0'; + + aBase64.SetLength(base64Len); + return NS_OK; +} + +nsresult +Base64Encode(const nsAString& aBinary, nsAString& aBase64) +{ + NS_LossyConvertUTF16toASCII binary(aBinary); + nsAutoCString base64; + + nsresult rv = Base64Encode(binary, base64); if (NS_SUCCEEDED(rv)) { - CopyASCIItoUTF16(binaryData, aBinaryData); + CopyASCIItoUTF16(base64, aBase64); } else { - aBinaryData.Truncate(); + aBase64.Truncate(); } return rv; } nsresult -Base64Decode(const nsACString& aString, nsACString& aBinaryData) +Base64Decode(const nsACString& aBase64, nsACString& aBinary) { // Check for overflow. - if (aString.Length() > UINT32_MAX / 3) { + if (aBase64.Length() > UINT32_MAX / 3) { return NS_ERROR_FAILURE; } // Don't ask PR_Base64Decode to decode the empty string - if (aString.IsEmpty()) { - aBinaryData.Truncate(); + if (aBase64.IsEmpty()) { + aBinary.Truncate(); return NS_OK; } - uint32_t binaryDataLen = ((aString.Length() * 3) / 4); + uint32_t binaryLen = ((aBase64.Length() * 3) / 4); - char* buffer; + char* binary; // Add one byte for null termination. - if (aBinaryData.SetCapacity(binaryDataLen + 1, fallible) && - (buffer = aBinaryData.BeginWriting()) && - PL_Base64Decode(aString.BeginReading(), aString.Length(), buffer)) { + if (aBinary.SetCapacity(binaryLen + 1, fallible) && + (binary = aBinary.BeginWriting()) && + PL_Base64Decode(aBase64.BeginReading(), aBase64.Length(), binary)) { // PL_Base64Decode doesn't null terminate the buffer for us when we pass // the buffer in. Do that manually, taking into account the number of '=' // characters we were passed. - if (!aString.IsEmpty() && aString[aString.Length() - 1] == '=') { - if (aString.Length() > 1 && aString[aString.Length() - 2] == '=') { - binaryDataLen -= 2; + if (!aBase64.IsEmpty() && aBase64[aBase64.Length() - 1] == '=') { + if (aBase64.Length() > 1 && aBase64[aBase64.Length() - 2] == '=') { + binaryLen -= 2; } else { - binaryDataLen -= 1; + binaryLen -= 1; } } - buffer[binaryDataLen] = '\0'; + binary[binaryLen] = '\0'; - aBinaryData.SetLength(binaryDataLen); + aBinary.SetLength(binaryLen); return NS_OK; } - aBinaryData.Truncate(); + aBinary.Truncate(); return NS_ERROR_INVALID_ARG; } nsresult -Base64Decode(const nsAString& aBinaryData, nsAString& aString) +Base64Decode(const nsAString& aBase64, nsAString& aBinary) { - NS_LossyConvertUTF16toASCII binaryData(aBinaryData); - nsAutoCString string; + NS_LossyConvertUTF16toASCII base64(aBase64); + nsAutoCString binary; - nsresult rv = Base64Decode(binaryData, string); + nsresult rv = Base64Decode(base64, binary); if (NS_SUCCEEDED(rv)) { - CopyASCIItoUTF16(string, aString); + CopyASCIItoUTF16(binary, aBinary); } else { - aString.Truncate(); + aBinary.Truncate(); } return rv; } nsresult -Base64URLDecode(const nsACString& aString, +Base64URLDecode(const nsACString& aBase64, Base64URLDecodePaddingPolicy aPaddingPolicy, - FallibleTArray& aOutput) + FallibleTArray& aBinary) { // Don't decode empty strings. - if (aString.IsEmpty()) { - aOutput.Clear(); + if (aBase64.IsEmpty()) { + aBinary.Clear(); return NS_OK; } // Check for overflow. - uint32_t sourceLength = aString.Length(); - if (sourceLength > UINT32_MAX / 3) { + uint32_t base64Len = aBase64.Length(); + if (base64Len > UINT32_MAX / 3) { return NS_ERROR_FAILURE; } - const char* source = aString.BeginReading(); + const char* base64 = aBase64.BeginReading(); // The decoded length may be 1-2 bytes over, depending on the final quantum. - uint32_t decodedLength = (sourceLength * 3) / 4; + uint32_t binaryLen = (base64Len * 3) / 4; // Determine whether to check for and ignore trailing padding. bool maybePadded = false; switch (aPaddingPolicy) { case Base64URLDecodePaddingPolicy::Require: - if (sourceLength % 4) { + if (base64Len % 4) { // Padded input length must be a multiple of 4. return NS_ERROR_INVALID_ARG; } @@ -423,7 +462,7 @@ Base64URLDecode(const nsACString& aString, case Base64URLDecodePaddingPolicy::Ignore: // Check for padding only if the length is a multiple of 4. - maybePadded = !(sourceLength % 4); + maybePadded = !(base64Len % 4); break; // If we're expecting unpadded input, no need for additional checks. @@ -433,113 +472,113 @@ Base64URLDecode(const nsACString& aString, case Base64URLDecodePaddingPolicy::Reject: break; } - if (maybePadded && source[sourceLength - 1] == '=') { - if (source[sourceLength - 2] == '=') { - sourceLength -= 2; + if (maybePadded && base64[base64Len - 1] == '=') { + if (base64[base64Len - 2] == '=') { + base64Len -= 2; } else { - sourceLength -= 1; + base64Len -= 1; } } - if (NS_WARN_IF(!aOutput.SetCapacity(decodedLength, mozilla::fallible))) { + if (NS_WARN_IF(!aBinary.SetCapacity(binaryLen, mozilla::fallible))) { return NS_ERROR_OUT_OF_MEMORY; } - aOutput.SetLengthAndRetainStorage(decodedLength); - uint8_t* output = aOutput.Elements(); + aBinary.SetLengthAndRetainStorage(binaryLen); + uint8_t* binary = aBinary.Elements(); - for (; sourceLength >= 4; sourceLength -= 4) { + for (; base64Len >= 4; base64Len -= 4) { uint8_t w, x, y, z; - if (!Base64URLCharToValue(*source++, &w) || - !Base64URLCharToValue(*source++, &x) || - !Base64URLCharToValue(*source++, &y) || - !Base64URLCharToValue(*source++, &z)) { + if (!Base64URLCharToValue(*base64++, &w) || + !Base64URLCharToValue(*base64++, &x) || + !Base64URLCharToValue(*base64++, &y) || + !Base64URLCharToValue(*base64++, &z)) { return NS_ERROR_INVALID_ARG; } - *output++ = w << 2 | x >> 4; - *output++ = x << 4 | y >> 2; - *output++ = y << 6 | z; + *binary++ = w << 2 | x >> 4; + *binary++ = x << 4 | y >> 2; + *binary++ = y << 6 | z; } - if (sourceLength == 3) { + if (base64Len == 3) { uint8_t w, x, y; - if (!Base64URLCharToValue(*source++, &w) || - !Base64URLCharToValue(*source++, &x) || - !Base64URLCharToValue(*source++, &y)) { + if (!Base64URLCharToValue(*base64++, &w) || + !Base64URLCharToValue(*base64++, &x) || + !Base64URLCharToValue(*base64++, &y)) { return NS_ERROR_INVALID_ARG; } - *output++ = w << 2 | x >> 4; - *output++ = x << 4 | y >> 2; - } else if (sourceLength == 2) { + *binary++ = w << 2 | x >> 4; + *binary++ = x << 4 | y >> 2; + } else if (base64Len == 2) { uint8_t w, x; - if (!Base64URLCharToValue(*source++, &w) || - !Base64URLCharToValue(*source++, &x)) { + if (!Base64URLCharToValue(*base64++, &w) || + !Base64URLCharToValue(*base64++, &x)) { return NS_ERROR_INVALID_ARG; } - *output++ = w << 2 | x >> 4; - } else if (sourceLength) { + *binary++ = w << 2 | x >> 4; + } else if (base64Len) { return NS_ERROR_INVALID_ARG; } // Set the length to the actual number of decoded bytes. - aOutput.TruncateLength(output - aOutput.Elements()); + aBinary.TruncateLength(binary - aBinary.Elements()); return NS_OK; } nsresult -Base64URLEncode(uint32_t aLength, const uint8_t* aData, +Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, Base64URLEncodePaddingPolicy aPaddingPolicy, - nsACString& aString) + nsACString& aBase64) { // Don't encode empty strings. - if (aLength == 0) { - aString.Truncate(); + if (aBinaryLen == 0) { + aBase64.Truncate(); return NS_OK; } // Check for overflow. - if (aLength > (UINT32_MAX / 4) * 3) { + if (aBinaryLen > (UINT32_MAX / 4) * 3) { return NS_ERROR_FAILURE; } // Allocate a buffer large enough to hold the encoded string with padding. // Add one byte for null termination. - uint32_t encodedLength = ((aLength + 2) / 3) * 4; - if (NS_WARN_IF(!aString.SetCapacity(encodedLength + 1, fallible))) { - aString.Truncate(); + uint32_t base64Len = ((aBinaryLen + 2) / 3) * 4; + if (NS_WARN_IF(!aBase64.SetCapacity(base64Len + 1, fallible))) { + aBase64.Truncate(); return NS_ERROR_FAILURE; } - char* rawBuffer = aString.BeginWriting(); + char* base64 = aBase64.BeginWriting(); uint32_t index = 0; - for (; index + 3 <= aLength; index += 3) { - *rawBuffer++ = kBase64URLAlphabet[aData[index] >> 2]; - *rawBuffer++ = kBase64URLAlphabet[((aData[index] & 0x3) << 4) | - (aData[index + 1] >> 4)]; - *rawBuffer++ = kBase64URLAlphabet[((aData[index + 1] & 0xf) << 2) | - (aData[index + 2] >> 6)]; - *rawBuffer++ = kBase64URLAlphabet[aData[index + 2] & 0x3f]; + for (; index + 3 <= aBinaryLen; index += 3) { + *base64++ = kBase64URLAlphabet[aBinary[index] >> 2]; + *base64++ = kBase64URLAlphabet[((aBinary[index] & 0x3) << 4) | + (aBinary[index + 1] >> 4)]; + *base64++ = kBase64URLAlphabet[((aBinary[index + 1] & 0xf) << 2) | + (aBinary[index + 2] >> 6)]; + *base64++ = kBase64URLAlphabet[aBinary[index + 2] & 0x3f]; } - uint32_t remaining = aLength - index; + uint32_t remaining = aBinaryLen - index; if (remaining == 1) { - *rawBuffer++ = kBase64URLAlphabet[aData[index] >> 2]; - *rawBuffer++ = kBase64URLAlphabet[((aData[index] & 0x3) << 4)]; + *base64++ = kBase64URLAlphabet[aBinary[index] >> 2]; + *base64++ = kBase64URLAlphabet[((aBinary[index] & 0x3) << 4)]; } else if (remaining == 2) { - *rawBuffer++ = kBase64URLAlphabet[aData[index] >> 2]; - *rawBuffer++ = kBase64URLAlphabet[((aData[index] & 0x3) << 4) | - (aData[index + 1] >> 4)]; - *rawBuffer++ = kBase64URLAlphabet[((aData[index + 1] & 0xf) << 2)]; + *base64++ = kBase64URLAlphabet[aBinary[index] >> 2]; + *base64++ = kBase64URLAlphabet[((aBinary[index] & 0x3) << 4) | + (aBinary[index + 1] >> 4)]; + *base64++ = kBase64URLAlphabet[((aBinary[index + 1] & 0xf) << 2)]; } - uint32_t length = rawBuffer - aString.BeginWriting(); + uint32_t length = base64 - aBase64.BeginWriting(); if (aPaddingPolicy == Base64URLEncodePaddingPolicy::Include) { if (length % 4 == 2) { - *rawBuffer++ = '='; - *rawBuffer++ = '='; + *base64++ = '='; + *base64++ = '='; length += 2; } else if (length % 4 == 3) { - *rawBuffer++ = '='; + *base64++ = '='; length += 1; } } else { @@ -548,8 +587,8 @@ Base64URLEncode(uint32_t aLength, const uint8_t* aData, } // Null terminate and truncate to the actual number of characters. - *rawBuffer = '\0'; - aString.SetLength(length); + *base64 = '\0'; + aBase64.SetLength(length); return NS_OK; } diff --git a/xpcom/io/Base64.h b/xpcom/io/Base64.h index 590c365797e7..e5c930d8fa19 100644 --- a/xpcom/io/Base64.h +++ b/xpcom/io/Base64.h @@ -25,14 +25,16 @@ Base64EncodeInputStream(nsIInputStream* aInputStream, uint32_t aOffset = 0); nsresult -Base64Encode(const nsACString& aString, nsACString& aBinary); +Base64Encode(const char* aBinary, uint32_t aBinaryLen, char** aBase64); nsresult -Base64Encode(const nsAString& aString, nsAString& aBinaryData); +Base64Encode(const nsACString& aBinary, nsACString& aBase64); +nsresult +Base64Encode(const nsAString& aBinary, nsAString& aBase64); nsresult -Base64Decode(const nsACString& aBinaryData, nsACString& aString); +Base64Decode(const nsACString& aBase64, nsACString& aBinary); nsresult -Base64Decode(const nsAString& aBinaryData, nsAString& aString); +Base64Decode(const nsAString& aBase64, nsAString& aBinary); enum class Base64URLEncodePaddingPolicy { Include, @@ -40,14 +42,14 @@ enum class Base64URLEncodePaddingPolicy { }; /** - * Converts |aData| to an unpadded, Base64 URL-encoded string per RFC 4648. + * Converts |aBinary| to an unpadded, Base64 URL-encoded string per RFC 4648. * Aims to encode the data in constant time. The caller retains ownership - * of |aData|. + * of |aBinary|. */ nsresult -Base64URLEncode(uint32_t aLength, const uint8_t* aData, +Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, Base64URLEncodePaddingPolicy aPaddingPolicy, - nsACString& aString); + nsACString& aBase64); enum class Base64URLDecodePaddingPolicy { Require, @@ -56,12 +58,12 @@ enum class Base64URLDecodePaddingPolicy { }; /** - * Decodes a Base64 URL-encoded |aString| into |aOutput|. + * Decodes a Base64 URL-encoded |aBase64| into |aBinary|. */ nsresult -Base64URLDecode(const nsACString& aString, +Base64URLDecode(const nsACString& aBase64, Base64URLDecodePaddingPolicy aPaddingPolicy, - FallibleTArray& aOutput); + FallibleTArray& aBinary); } // namespace mozilla diff --git a/xpcom/io/nsEscape.cpp b/xpcom/io/nsEscape.cpp index fa50faf7169d..dca723cd67db 100644 --- a/xpcom/io/nsEscape.cpp +++ b/xpcom/io/nsEscape.cpp @@ -74,20 +74,8 @@ AppendPercentHex(char16_t* aBuffer, char16_t aChar) //---------------------------------------------------------------------------------------- char* -nsEscape(const char* aStr, nsEscapeMask aFlags) -//---------------------------------------------------------------------------------------- -{ - if (!aStr) { - return nullptr; - } - - return nsEscapeWithLength(aStr, strlen(aStr), nullptr, aFlags); -} - -//---------------------------------------------------------------------------------------- -char* -nsEscapeWithLength(const char* aStr, size_t aLength, size_t* aOutputLength, - nsEscapeMask aFlags) +nsEscape(const char* aStr, size_t aLength, size_t* aOutputLength, + nsEscapeMask aFlags) //---------------------------------------------------------------------------------------- { if (!aStr) { diff --git a/xpcom/io/nsEscape.h b/xpcom/io/nsEscape.h index 29394f515462..3bf7280f813f 100644 --- a/xpcom/io/nsEscape.h +++ b/xpcom/io/nsEscape.h @@ -38,18 +38,10 @@ extern "C" { * @param aMask How to escape the string * @return A newly allocated escaped string that must be free'd with * nsCRT::free, or null on failure + * @note: Please, don't use this function. Use NS_Escape instead! */ -char* nsEscapeWithLength(const char* aStr, size_t aLength, size_t* aOutputLen, - nsEscapeMask aMask); - -/** - * Escape the given string according to mask - * @param aStr The string to escape - * @param aMask How to escape the string - * @return A newly allocated escaped string that must be free'd with - * nsCRT::free, or null on failure - */ -char* nsEscape(const char* aStr, nsEscapeMask aMask); +char* nsEscape(const char* aStr, size_t aLength, size_t* aOutputLen, + nsEscapeMask aMask); char* nsUnescape(char* aStr); /* decode % escaped hex codes into character values, @@ -201,8 +193,8 @@ NS_Escape(const nsACString& aOriginal, nsACString& aEscaped, nsEscapeMask aMask) { size_t escLen = 0; - char* esc = nsEscapeWithLength(aOriginal.BeginReading(), aOriginal.Length(), - &escLen, aMask); + char* esc = nsEscape(aOriginal.BeginReading(), aOriginal.Length(), &escLen, + aMask); if (! esc) { return false; }