diff --git a/addon-sdk/source/python-lib/cuddlefish/prefs.py b/addon-sdk/source/python-lib/cuddlefish/prefs.py index 3ba611dad16f..73ab41d4e588 100644 --- a/addon-sdk/source/python-lib/cuddlefish/prefs.py +++ b/addon-sdk/source/python-lib/cuddlefish/prefs.py @@ -55,12 +55,13 @@ DEFAULT_NO_CONNECTIONS_PREFS = { 'browser.newtab.url' : 'about:blank', 'browser.search.update': False, 'browser.search.suggest.enabled' : False, + 'browser.safebrowsing.downloads.remote.url': 'http://localhost/safebrowsing-dummy/downloads', + 'browser.safebrowsing.malware.enabled' : False, 'browser.safebrowsing.phishing.enabled' : False, 'browser.safebrowsing.provider.google.updateURL': 'http://localhost/safebrowsing-dummy/update', 'browser.safebrowsing.provider.google.gethashURL': 'http://localhost/safebrowsing-dummy/gethash', 'browser.safebrowsing.provider.google4.updateURL': 'http://localhost/safebrowsing4-dummy/update', 'browser.safebrowsing.provider.google4.gethashURL': 'http://localhost/safebrowsing4-dummy/gethash', - 'browser.safebrowsing.malware.reportURL': 'http://localhost/safebrowsing-dummy/malwarereport', 'browser.selfsupport.url': 'https://localhost/selfsupport-dummy', 'browser.safebrowsing.provider.mozilla.gethashURL': 'http://localhost/safebrowsing-dummy/gethash', 'browser.safebrowsing.provider.mozilla.updateURL': 'http://localhost/safebrowsing-dummy/update', @@ -118,6 +119,7 @@ DEFAULT_FIREFOX_PREFS = { # Make url-classifier updates so rare that they won't affect tests. 'urlclassifier.updateinterval' : 172800, # Point the url-classifier to a nonexistent local URL for fast failures. + 'browser.safebrowsing.downloads.remote.url': 'http://localhost/safebrowsing-dummy/downloads', 'browser.safebrowsing.provider.google.gethashURL' : 'http://localhost/safebrowsing-dummy/gethash', 'browser.safebrowsing.provider.google.updateURL' : 'http://localhost/safebrowsing-dummy/update', 'browser.safebrowsing.provider.google4.gethashURL' : 'http://localhost/safebrowsing4-dummy/gethash', diff --git a/addon-sdk/source/test/preferences/no-connections.json b/addon-sdk/source/test/preferences/no-connections.json index 1bb62dbedc25..24aa94683c6d 100644 --- a/addon-sdk/source/test/preferences/no-connections.json +++ b/addon-sdk/source/test/preferences/no-connections.json @@ -15,6 +15,8 @@ "browser.newtab.url": "about:blank", "browser.search.update": false, "browser.search.suggest.enabled": false, + "browser.safebrowsing.downloads.remote.url": "http://localhost/safebrowsing-dummy/downloads", + "browser.safebrowsing.malware.enabled": false, "browser.safebrowsing.phishing.enabled": false, "browser.safebrowsing.provider.google.updateURL": "http://localhost/safebrowsing-dummy/update", "browser.safebrowsing.provider.google.gethashURL": "http://localhost/safebrowsing-dummy/gethash", diff --git a/browser/base/content/aboutDialog-appUpdater.js b/browser/base/content/aboutDialog-appUpdater.js index 3ce4bf8fa49a..e0bd4d77ab27 100644 --- a/browser/base/content/aboutDialog-appUpdater.js +++ b/browser/base/content/aboutDialog-appUpdater.js @@ -175,6 +175,14 @@ appUpdater.prototype = if (button) { if (aChildID == "downloadAndInstall") { let updateVersion = gAppUpdater.update.displayVersion; + // Include the build ID if this is an "a#" (nightly or aurora) build + if (/a\d+$/.test(updateVersion)) { + let buildID = gAppUpdater.update.buildID; + let year = buildID.slice(0, 4); + let month = buildID.slice(4, 6); + let day = buildID.slice(6, 8); + updateVersion += ` (${year}-${month}-${day})`; + } button.label = this.bundle.formatStringFromName("update.downloadAndInstallButton.label", [updateVersion], 1); button.accessKey = this.bundle.GetStringFromName("update.downloadAndInstallButton.accesskey"); } diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js index 6b4697ec03a7..6a7ad60b998d 100644 --- a/browser/base/content/browser-places.js +++ b/browser/base/content/browser-places.js @@ -482,7 +482,7 @@ var PlacesCommandHook = { try { info.title = docInfo.isErrorPage ? - (await PlacesUtils.promisePlaceInfo(aBrowser.currentURI)).title : + (await PlacesUtils.history.fetch(aBrowser.currentURI)).title : aBrowser.contentTitle; info.title = info.title || url.href; description = docInfo.description; diff --git a/browser/base/content/moz.build b/browser/base/content/moz.build index ce1e2ec93551..b85cd710a886 100644 --- a/browser/base/content/moz.build +++ b/browser/base/content/moz.build @@ -25,9 +25,6 @@ with Files("newtab/**"): with Files("pageinfo/**"): BUG_COMPONENT = ("Firefox", "Page Info Window") -with Files("sync/**"): - BUG_COMPONENT = ("Firefox", "Sync") - with Files("test/alerts/**"): BUG_COMPONENT = ("Toolkit", "Notifications and Alerts") diff --git a/browser/base/content/sync/aboutSyncTabs-bindings.xml b/browser/base/content/sync/aboutSyncTabs-bindings.xml deleted file mode 100644 index 60cf18607423..000000000000 --- a/browser/base/content/sync/aboutSyncTabs-bindings.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/browser/base/content/sync/aboutSyncTabs.css b/browser/base/content/sync/aboutSyncTabs.css deleted file mode 100644 index 5a353175b1ef..000000000000 --- a/browser/base/content/sync/aboutSyncTabs.css +++ /dev/null @@ -1,11 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -richlistitem[type="tab"] { - -moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#tab-listing); -} - -richlistitem[type="client"] { - -moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#client-listing); -} diff --git a/browser/base/content/sync/aboutSyncTabs.js b/browser/base/content/sync/aboutSyncTabs.js deleted file mode 100644 index fb9e5c57cb32..000000000000 --- a/browser/base/content/sync/aboutSyncTabs.js +++ /dev/null @@ -1,305 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* import-globals-from ../utilityOverlay.js */ - -var Cu = Components.utils; - -Cu.import("resource://services-common/utils.js"); -Cu.import("resource://services-sync/main.js"); -Cu.import("resource:///modules/PlacesUIUtils.jsm"); -Cu.import("resource://gre/modules/AppConstants.jsm"); -Cu.import("resource://gre/modules/PlacesUtils.jsm", this); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource://gre/modules/Promise.jsm"); - -var RemoteTabViewer = { - _tabsList: null, - - init() { - Services.obs.addObserver(this, "weave:service:login:finish"); - Services.obs.addObserver(this, "weave:engine:sync:finish"); - - this._tabsList = document.getElementById("tabsList"); - - this.buildList(true); - }, - - uninit() { - Services.obs.removeObserver(this, "weave:service:login:finish"); - Services.obs.removeObserver(this, "weave:engine:sync:finish"); - }, - - createItem(attrs) { - let item = document.createElement("richlistitem"); - - // Copy the attributes from the argument into the item. - for (let attr in attrs) { - item.setAttribute(attr, attrs[attr]); - } - - if (attrs["type"] == "tab") { - item.label = attrs.title != "" ? attrs.title : attrs.url; - } - - return item; - }, - - filterTabs(event) { - let val = event.target.value.toLowerCase(); - let numTabs = this._tabsList.getRowCount(); - let clientTabs = 0; - let currentClient = null; - - for (let i = 0; i < numTabs; i++) { - let item = this._tabsList.getItemAtIndex(i); - let hide = false; - if (item.getAttribute("type") == "tab") { - if (!item.getAttribute("url").toLowerCase().includes(val) && - !item.getAttribute("title").toLowerCase().includes(val)) { - hide = true; - } else { - clientTabs++; - } - } else if (item.getAttribute("type") == "client") { - if (currentClient) { - if (clientTabs == 0) { - currentClient.hidden = true; - } - } - currentClient = item; - clientTabs = 0; - } - item.hidden = hide; - } - if (clientTabs == 0) { - currentClient.hidden = true; - } - }, - - openSelected() { - let items = this._tabsList.selectedItems; - let urls = []; - for (let i = 0; i < items.length; i++) { - if (items[i].getAttribute("type") == "tab") { - urls.push(items[i].getAttribute("url")); - let index = this._tabsList.getIndexOfItem(items[i]); - this._tabsList.removeItemAt(index); - } - } - if (urls.length) { - getTopWin().gBrowser.loadTabs(urls); - this._tabsList.clearSelection(); - } - }, - - bookmarkSingleTab() { - let item = this._tabsList.selectedItems[0]; - let uri = Weave.Utils.makeURI(item.getAttribute("url")); - let title = item.getAttribute("title"); - PlacesUIUtils.showBookmarkDialog({ action: "add" - , type: "bookmark" - , uri - , title - , hiddenRows: [ "description" - , "location" - , "loadInSidebar" - , "keyword" ] - }, window.top); - }, - - bookmarkSelectedTabs() { - let items = this._tabsList.selectedItems; - let URIs = []; - for (let i = 0; i < items.length; i++) { - if (items[i].getAttribute("type") == "tab") { - let uri = Weave.Utils.makeURI(items[i].getAttribute("url")); - if (!uri) { - continue; - } - - URIs.push(uri); - } - } - if (URIs.length) { - PlacesUIUtils.showBookmarkDialog({ action: "add" - , type: "folder" - , URIList: URIs - , hiddenRows: [ "description" ] - }, window.top); - } - }, - - getIcon(iconUri, defaultIcon) { - try { - let iconURI = Weave.Utils.makeURI(iconUri); - return PlacesUtils.favicons.getFaviconLinkForIcon(iconURI).spec; - } catch (ex) { - // Do nothing. - } - - // Just give the provided default icon or the system's default. - return defaultIcon || PlacesUtils.favicons.defaultFavicon.spec; - }, - - _waitingForBuildList: false, - - _buildListRequested: false, - - buildList(forceSync) { - if (this._waitingForBuildList) { - this._buildListRequested = true; - return; - } - - this._waitingForBuildList = true; - this._buildListRequested = false; - - this._clearTabList(); - - if (Weave.Service.isLoggedIn) { - this._refetchTabs(forceSync); - this._generateWeaveTabList(); - } else { - // XXXzpao We should say something about not being logged in & not having data - // or tell the appropriate condition. (bug 583344) - } - - this._waitingForBuildList = false; - if (this._buildListRequested) { - CommonUtils.nextTick(this.buildList, this); - } - }, - - _clearTabList() { - let list = this._tabsList; - - // Clear out existing richlistitems. - let count = list.getRowCount(); - if (count > 0) { - for (let i = count - 1; i >= 0; i--) { - list.removeItemAt(i); - } - } - }, - - _generateWeaveTabList() { - let engine = Weave.Service.engineManager.get("tabs"); - let list = this._tabsList; - - let seenURLs = new Set(); - let localURLs = engine.getOpenURLs(); - - for (let [, client] of Object.entries(engine.getAllClients())) { - // Create the client node, but don't add it in-case we don't show any tabs - let appendClient = true; - - client.tabs.forEach(function({title, urlHistory, icon}) { - let url = urlHistory[0]; - if (!url || localURLs.has(url) || seenURLs.has(url)) { - return; - } - seenURLs.add(url); - - if (appendClient) { - let attrs = { - type: "client", - clientName: client.clientName, - class: Weave.Service.clientsEngine.isMobile(client.id) ? "mobile" : "desktop" - }; - let clientEnt = this.createItem(attrs); - list.appendChild(clientEnt); - appendClient = false; - clientEnt.disabled = true; - } - let attrs = { - type: "tab", - title: title || url, - url, - icon: this.getIcon(icon), - } - let tab = this.createItem(attrs); - list.appendChild(tab); - }, this); - } - }, - - adjustContextMenu(event) { - let mode = "all"; - switch (this._tabsList.selectedItems.length) { - case 0: - break; - case 1: - mode = "single" - break; - default: - mode = "multiple"; - break; - } - - let menu = document.getElementById("tabListContext"); - let el = menu.firstChild; - while (el) { - let showFor = el.getAttribute("showFor"); - if (showFor) { - el.hidden = showFor != mode && showFor != "all"; - } - - el = el.nextSibling; - } - }, - - _refetchTabs(force) { - if (!force) { - // Don't bother refetching tabs if we already did so recently - let lastFetch = Services.prefs.getIntPref("services.sync.lastTabFetch", 0); - - let now = Math.floor(Date.now() / 1000); - if (now - lastFetch < 30) { - return false; - } - } - - // Ask Sync to just do the tabs engine if it can. - Weave.Service.sync(["tabs"]); - Services.prefs.setIntPref("services.sync.lastTabFetch", - Math.floor(Date.now() / 1000)); - - return true; - }, - - observe(subject, topic, data) { - switch (topic) { - case "weave:service:login:finish": - // A login has finished, which means that a Sync is about to start and - // we will eventually get to the "tabs" engine - but try and force the - // tab engine to sync first by passing |true| for the forceSync param. - this.buildList(true); - break; - case "weave:engine:sync:finish": - if (data == "tabs") { - // The tabs engine just finished, so re-build the list without - // forcing a new sync of the tabs engine. - this.buildList(false); - } - break; - } - }, - - handleClick(event) { - if (event.target.getAttribute("type") != "tab") { - return; - } - - if (event.button == 1) { - let url = event.target.getAttribute("url"); - openUILink(url, event); - let index = this._tabsList.getIndexOfItem(event.target); - this._tabsList.removeItemAt(index); - } - } -} diff --git a/browser/base/content/sync/aboutSyncTabs.xul b/browser/base/content/sync/aboutSyncTabs.xul deleted file mode 100644 index 4247fd7e6475..000000000000 --- a/browser/base/content/sync/aboutSyncTabs.xul +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - %aboutSyncTabsDTD; -]> - - - + + + + + + + + diff --git a/devtools/client/styleeditor/StyleSheetEditor.jsm b/devtools/client/styleeditor/StyleSheetEditor.jsm index 804c58bc7da5..439d3a58948b 100644 --- a/devtools/client/styleeditor/StyleSheetEditor.jsm +++ b/devtools/client/styleeditor/StyleSheetEditor.jsm @@ -21,7 +21,7 @@ const EventEmitter = require("devtools/shared/event-emitter"); const {Task} = require("devtools/shared/task"); const {FileUtils} = require("resource://gre/modules/FileUtils.jsm"); const {NetUtil} = require("resource://gre/modules/NetUtil.jsm"); -const {TextDecoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); +const {OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); const { getString, showFilePicker, diff --git a/devtools/client/webconsole/console-output.js b/devtools/client/webconsole/console-output.js index a3ce9fe88348..a87f742e22ba 100644 --- a/devtools/client/webconsole/console-output.js +++ b/devtools/client/webconsole/console-output.js @@ -19,12 +19,11 @@ loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/main", tr const { extend } = require("sdk/core/heritage"); const XHTML_NS = "http://www.w3.org/1999/xhtml"; const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; -const STRINGS_URI = "devtools/client/locales/webconsole.properties"; const WebConsoleUtils = require("devtools/client/webconsole/utils").Utils; const { getSourceNames } = require("devtools/client/shared/source-utils"); const {Task} = require("devtools/shared/task"); -const l10n = new WebConsoleUtils.L10n(STRINGS_URI); +const l10n = require("devtools/client/webconsole/webconsole-l10n"); const nodeConstants = require("devtools/shared/dom-node-constants"); const {PluralForm} = require("devtools/shared/plural-form"); @@ -3556,9 +3555,12 @@ Widgets.Stacktrace.prototype = extend(Widgets.BaseWidget.prototype, { result.className = "stacktrace devtools-monospace"; if (this.stacktrace) { + const target = this.message.output.toolboxTarget; + const toolbox = gDevTools.getToolbox(target); this.output.owner.ReactDOM.render(this.output.owner.StackTraceView({ stacktrace: this.stacktrace, - onViewSourceInDebugger: frame => this.output.openLocationInDebugger(frame) + onViewSourceInDebugger: frame => this.output.openLocationInDebugger(frame), + sourceMapService: toolbox ? toolbox.sourceMapURLService : null, }), result); } diff --git a/devtools/client/webconsole/hudservice.js b/devtools/client/webconsole/hudservice.js index 2c3e9f6fabfe..b36658900842 100644 --- a/devtools/client/webconsole/hudservice.js +++ b/devtools/client/webconsole/hudservice.js @@ -22,8 +22,7 @@ loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", loader.lazyRequireGetter(this, "showDoorhanger", "devtools/client/shared/doorhanger", true); loader.lazyRequireGetter(this, "viewSource", "devtools/client/shared/view-source"); -const STRINGS_URI = "devtools/client/locales/webconsole.properties"; -var l10n = new WebConsoleUtils.L10n(STRINGS_URI); +const l10n = require("devtools/client/webconsole/webconsole-l10n"); const BROWSER_CONSOLE_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no"; diff --git a/devtools/client/webconsole/jsterm.js b/devtools/client/webconsole/jsterm.js index 0da5a905a677..ddf9853b4c5e 100644 --- a/devtools/client/webconsole/jsterm.js +++ b/devtools/client/webconsole/jsterm.js @@ -27,8 +27,7 @@ loader.lazyImporter(this, "VariablesView", "resource://devtools/client/shared/wi loader.lazyImporter(this, "VariablesViewController", "resource://devtools/client/shared/widgets/VariablesViewController.jsm"); loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true); -const STRINGS_URI = "devtools/client/locales/webconsole.properties"; -var l10n = new WebConsoleUtils.L10n(STRINGS_URI); +const l10n = require("devtools/client/webconsole/webconsole-l10n"); // Constants used for defining the direction of JSTerm input history navigation. const HISTORY_BACK = -1; diff --git a/devtools/client/webconsole/moz.build b/devtools/client/webconsole/moz.build index da24b4b99a46..56c3cb89dae3 100644 --- a/devtools/client/webconsole/moz.build +++ b/devtools/client/webconsole/moz.build @@ -19,8 +19,9 @@ DevToolsModules( 'panel.js', 'utils.js', 'webconsole-connection-proxy.js', + 'webconsole-l10n.js', 'webconsole.js', ) -with Files('**'): - BUG_COMPONENT = ('Firefox', 'Developer Tools: Console') +with Files('**'): + BUG_COMPONENT = ('Firefox', 'Developer Tools: Console') diff --git a/devtools/client/webconsole/net/components/net-info-body.js b/devtools/client/webconsole/net/components/net-info-body.js index 0e18082f006f..e9f99f352798 100644 --- a/devtools/client/webconsole/net/components/net-info-body.js +++ b/devtools/client/webconsole/net/components/net-info-body.js @@ -38,7 +38,9 @@ var NetInfoBody = React.createClass({ data: PropTypes.shape({ request: PropTypes.object.isRequired, response: PropTypes.object.isRequired - }) + }), + // Service to enable the source map feature. + sourceMapService: PropTypes.object, }, displayName: "NetInfoBody", @@ -76,7 +78,7 @@ var NetInfoBody = React.createClass({ }, getTabPanels() { - let actions = this.props.actions; + let { actions, sourceMapService } = this.props; let data = this.state.data; let {request} = data; @@ -153,7 +155,8 @@ var NetInfoBody = React.createClass({ title: Locale.$STR("netRequest.callstack")}, StackTraceTab({ data: data, - actions: actions + actions: actions, + sourceMapService: sourceMapService, }) ) ); diff --git a/devtools/client/webconsole/net/components/stacktrace-tab.js b/devtools/client/webconsole/net/components/stacktrace-tab.js index 51eb7689baae..367729e66a7a 100644 --- a/devtools/client/webconsole/net/components/stacktrace-tab.js +++ b/devtools/client/webconsole/net/components/stacktrace-tab.js @@ -13,15 +13,17 @@ const StackTraceTab = createClass({ data: PropTypes.object.isRequired, actions: PropTypes.shape({ onViewSourceInDebugger: PropTypes.func.isRequired - }) + }), + // Service to enable the source map feature. + sourceMapService: PropTypes.object, }, render() { let { stacktrace } = this.props.data.cause; - let { actions } = this.props; + let { actions, sourceMapService } = this.props; let onViewSourceInDebugger = actions.onViewSourceInDebugger.bind(actions); - return StackTrace({ stacktrace, onViewSourceInDebugger }); + return StackTrace({ stacktrace, onViewSourceInDebugger, sourceMapService }); } }); diff --git a/devtools/client/webconsole/net/net-request.js b/devtools/client/webconsole/net/net-request.js index a2275467f7db..15879d01bf04 100644 --- a/devtools/client/webconsole/net/net-request.js +++ b/devtools/client/webconsole/net/net-request.js @@ -163,7 +163,8 @@ NetRequest.prototype = { // As soon as Redux is in place state and actions will come from // separate modules. let body = NetInfoBody({ - actions: this + actions: this, + sourceMapService: this.owner.sourceMapURLService, }); // Render net info body! diff --git a/devtools/client/webconsole/new-console-output/components/console-output.js b/devtools/client/webconsole/new-console-output/components/console-output.js index f5240d8328c6..7cbec18b117a 100644 --- a/devtools/client/webconsole/new-console-output/components/console-output.js +++ b/devtools/client/webconsole/new-console-output/components/console-output.js @@ -30,6 +30,7 @@ const ConsoleOutput = createClass({ serviceContainer: PropTypes.shape({ attachRefToHud: PropTypes.func.isRequired, openContextMenu: PropTypes.func.isRequired, + sourceMapService: PropTypes.object, }), autoscroll: PropTypes.bool.isRequired, dispatch: PropTypes.func.isRequired, diff --git a/devtools/client/webconsole/new-console-output/components/filter-bar.js b/devtools/client/webconsole/new-console-output/components/filter-bar.js index 811e2827ee41..6233d39ac046 100644 --- a/devtools/client/webconsole/new-console-output/components/filter-bar.js +++ b/devtools/client/webconsole/new-console-output/components/filter-bar.js @@ -13,7 +13,6 @@ const { getAllFilters } = require("devtools/client/webconsole/new-console-output const { getAllUi } = require("devtools/client/webconsole/new-console-output/selectors/ui"); const { filterTextSet, - filtersClear, filterBarToggle, messagesClear } = require("devtools/client/webconsole/new-console-output/actions/index"); @@ -49,10 +48,6 @@ const FilterBar = createClass({ this.props.dispatch(filterBarToggle()); }, - onClickFiltersClear: function () { - this.props.dispatch(filtersClear()); - }, - onSearchInput: function (e) { this.props.dispatch(filterTextSet(e.target.value)); }, diff --git a/devtools/client/webconsole/new-console-output/components/message-types/console-command.js b/devtools/client/webconsole/new-console-output/components/message-types/console-command.js index e70b352a680c..fe3fe2bcc13c 100644 --- a/devtools/client/webconsole/new-console-output/components/message-types/console-command.js +++ b/devtools/client/webconsole/new-console-output/components/message-types/console-command.js @@ -20,6 +20,7 @@ ConsoleCommand.propTypes = { autoscroll: PropTypes.bool.isRequired, indent: PropTypes.number.isRequired, timestampsVisible: PropTypes.bool.isRequired, + serviceContainer: PropTypes.object, }; ConsoleCommand.defaultProps = { @@ -35,6 +36,7 @@ function ConsoleCommand(props) { indent, message, timestampsVisible, + serviceContainer, } = props; const { @@ -44,10 +46,6 @@ function ConsoleCommand(props) { messageText: messageBody, } = message; - const { - serviceContainer, - } = props; - return Message({ source, type, diff --git a/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js b/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js index 09c81458d94a..484e667bcd16 100644 --- a/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js +++ b/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js @@ -20,6 +20,7 @@ EvaluationResult.propTypes = { message: PropTypes.object.isRequired, indent: PropTypes.number.isRequired, timestampsVisible: PropTypes.bool.isRequired, + serviceContainer: PropTypes.object, }; EvaluationResult.defaultProps = { diff --git a/devtools/client/webconsole/new-console-output/components/message-types/page-error.js b/devtools/client/webconsole/new-console-output/components/message-types/page-error.js index 91006841330b..39089bdec075 100644 --- a/devtools/client/webconsole/new-console-output/components/message-types/page-error.js +++ b/devtools/client/webconsole/new-console-output/components/message-types/page-error.js @@ -20,6 +20,7 @@ PageError.propTypes = { open: PropTypes.bool, indent: PropTypes.number.isRequired, timestampsVisible: PropTypes.bool.isRequired, + serviceContainer: PropTypes.object, }; PageError.defaultProps = { diff --git a/devtools/client/webconsole/new-console-output/components/message.js b/devtools/client/webconsole/new-console-output/components/message.js index cdbc5fb23b15..a0bb793abcad 100644 --- a/devtools/client/webconsole/new-console-output/components/message.js +++ b/devtools/client/webconsole/new-console-output/components/message.js @@ -148,6 +148,7 @@ const Message = createClass({ stacktrace: stacktrace, onViewSourceInDebugger: serviceContainer.onViewSourceInDebugger, onViewSourceInScratchpad: serviceContainer.onViewSourceInScratchpad, + sourceMapService: serviceContainer.sourceMapService, }) ); } diff --git a/devtools/client/webconsole/new-console-output/selectors/messages.js b/devtools/client/webconsole/new-console-output/selectors/messages.js index c522ec3a04d1..b7a76fd53f64 100644 --- a/devtools/client/webconsole/new-console-output/selectors/messages.js +++ b/devtools/client/webconsole/new-console-output/selectors/messages.js @@ -9,6 +9,7 @@ const { l10n } = require("devtools/client/webconsole/new-console-output/utils/me const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters"); const { getLogLimit } = require("devtools/client/webconsole/new-console-output/selectors/prefs"); const { getGripPreviewItems } = require("devtools/client/shared/components/reps/reps"); +const { getSourceNames } = require("devtools/client/shared/source-utils"); const { MESSAGE_TYPE, MESSAGE_SOURCE @@ -131,8 +132,9 @@ function isTextInFrame(text, frame) { if (!frame) { return false; } - return Object.values(frame) - .join(":") + + const { short } = getSourceNames(frame.source); + return `${short}:${frame.line}:${frame.column}` .toLocaleLowerCase() .includes(text.toLocaleLowerCase()); } diff --git a/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js b/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js index bcf353329b5d..78125dceea92 100644 --- a/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js +++ b/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js @@ -99,8 +99,7 @@ describe("ConsoleAPICall component:", () => { serviceContainer, timestampsVisible: true, })); - const L10n = require("devtools/client/webconsole/new-console-output/test/fixtures/L10n"); - const { timestampString } = new L10n(); + const { timestampString } = require("devtools/client/webconsole/webconsole-l10n"); expect(wrapper.find(".timestamp").text()).toBe(timestampString(message.timeStamp)); }); diff --git a/devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js b/devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js index 742e48675cf0..d334ba8995fa 100644 --- a/devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js +++ b/devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js @@ -97,8 +97,7 @@ describe("EvaluationResult component:", () => { message, timestampsVisible: true, })); - const L10n = require("devtools/client/webconsole/new-console-output/test/fixtures/L10n"); - const { timestampString } = new L10n(); + const { timestampString } = require("devtools/client/webconsole/webconsole-l10n"); expect(wrapper.find(".timestamp").text()).toBe(timestampString(message.timeStamp)); }); diff --git a/devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js b/devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js index 02aa0103a1bf..20cfa5079e80 100644 --- a/devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js +++ b/devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js @@ -29,8 +29,7 @@ describe("NetworkEventMessage component:", () => { serviceContainer, timestampsVisible: true, })); - const L10n = require("devtools/client/webconsole/new-console-output/test/fixtures/L10n"); - const { timestampString } = new L10n(); + const { timestampString } = require("devtools/client/webconsole/webconsole-l10n"); expect(wrapper.find(".timestamp").text()).toBe(timestampString(message.timeStamp)); expect(wrapper.find(".message-body .method").text()).toBe("GET"); diff --git a/devtools/client/webconsole/new-console-output/test/components/page-error.test.js b/devtools/client/webconsole/new-console-output/test/components/page-error.test.js index 8b6a4c497f55..fda157bea969 100644 --- a/devtools/client/webconsole/new-console-output/test/components/page-error.test.js +++ b/devtools/client/webconsole/new-console-output/test/components/page-error.test.js @@ -32,8 +32,7 @@ describe("PageError component:", () => { serviceContainer, timestampsVisible: true, })); - const L10n = require("devtools/client/webconsole/new-console-output/test/fixtures/L10n"); - const { timestampString } = new L10n(); + const { timestampString } = require("devtools/client/webconsole/webconsole-l10n"); expect(wrapper.find(".timestamp").text()).toBe(timestampString(message.timeStamp)); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/head.js b/devtools/client/webconsole/new-console-output/test/mochitest/head.js index 4ef934e1f043..46d974c2e7b4 100644 --- a/devtools/client/webconsole/new-console-output/test/mochitest/head.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/head.js @@ -14,9 +14,7 @@ Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this); -var {Utils: WebConsoleUtils} = require("devtools/client/webconsole/utils"); -const WEBCONSOLE_STRINGS_URI = "devtools/client/locales/webconsole.properties"; -var WCUL10n = new WebConsoleUtils.L10n(WEBCONSOLE_STRINGS_URI); +var WCUL10n = require("devtools/client/webconsole/webconsole-l10n"); Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", true); registerCleanupFunction(function* () { diff --git a/devtools/client/webconsole/new-console-output/test/require-helper.js b/devtools/client/webconsole/new-console-output/test/require-helper.js index 5d9a380aba51..fdb2c98983f4 100644 --- a/devtools/client/webconsole/new-console-output/test/require-helper.js +++ b/devtools/client/webconsole/new-console-output/test/require-helper.js @@ -27,8 +27,6 @@ requireHacker.global_hook("default", path => { // Some modules depend on Chrome APIs which don't work in mocha. When such a module // is required, replace it with a mock version. switch (path) { - case "devtools/client/webconsole/utils": - return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/WebConsoleUtils")`; case "devtools/shared/l10n": return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/LocalizationHelper")`; case "devtools/shared/plural-form": diff --git a/devtools/client/webconsole/new-console-output/test/store/search.test.js b/devtools/client/webconsole/new-console-output/test/store/search.test.js index e748c665b831..2c3c69dbf301 100644 --- a/devtools/client/webconsole/new-console-output/test/store/search.test.js +++ b/devtools/client/webconsole/new-console-output/test/store/search.test.js @@ -66,6 +66,18 @@ describe("Searching in grips", () => { expect(getAllMessages(store.getState()).size).toEqual(1); }); }); + + describe("Search in frame", () => { + it("matches on file name", () => { + store.dispatch(actions.filterTextSet("test-console-api.html:1:27")); + expect(getAllMessages(store.getState()).size).toEqual(7); + }); + + it("do not match on full url", () => { + store.dispatch(actions.filterTextSet("http://example.com/browser/devtools")); + expect(getAllMessages(store.getState()).size).toEqual(0); + }); + }); }); function prepareBaseStore() { diff --git a/devtools/client/webconsole/new-console-output/utils/messages.js b/devtools/client/webconsole/new-console-output/utils/messages.js index 32b1b6d26bf4..536773ce4eb7 100644 --- a/devtools/client/webconsole/new-console-output/utils/messages.js +++ b/devtools/client/webconsole/new-console-output/utils/messages.js @@ -6,9 +6,7 @@ "use strict"; -const WebConsoleUtils = require("devtools/client/webconsole/utils").Utils; -const STRINGS_URI = "devtools/client/locales/webconsole.properties"; -const l10n = new WebConsoleUtils.L10n(STRINGS_URI); +const l10n = require("devtools/client/webconsole/webconsole-l10n"); const { MESSAGE_SOURCE, diff --git a/devtools/client/webconsole/test/head.js b/devtools/client/webconsole/test/head.js index f46b85f558fc..f997c654c604 100644 --- a/devtools/client/webconsole/test/head.js +++ b/devtools/client/webconsole/test/head.js @@ -37,8 +37,7 @@ const SEVERITY_LOG = 3; // The indent of a console group in pixels. const GROUP_INDENT = 12; -const WEBCONSOLE_STRINGS_URI = "devtools/client/locales/webconsole.properties"; -var WCUL10n = new WebConsoleUtils.L10n(WEBCONSOLE_STRINGS_URI); +var WCUL10n = require("devtools/client/webconsole/webconsole-l10n"); const DOCS_GA_PARAMS = "?utm_source=mozilla" + "&utm_medium=firefox-console-errors" + diff --git a/devtools/client/webconsole/utils.js b/devtools/client/webconsole/utils.js index 8f9ce52e8475..ccf836df48a0 100644 --- a/devtools/client/webconsole/utils.js +++ b/devtools/client/webconsole/utils.js @@ -8,7 +8,6 @@ const {Cc, Ci} = require("chrome"); const Services = require("Services"); -const {LocalizationHelper} = require("devtools/shared/l10n"); // Match the function name from the result of toString() or toSource(). // @@ -285,65 +284,3 @@ var WebConsoleUtils = { exports.Utils = WebConsoleUtils; -// Localization - -WebConsoleUtils.L10n = function (bundleURI) { - this._helper = new LocalizationHelper(bundleURI); -}; - -WebConsoleUtils.L10n.prototype = { - /** - * Generates a formatted timestamp string for displaying in console messages. - * - * @param integer [milliseconds] - * Optional, allows you to specify the timestamp in milliseconds since - * the UNIX epoch. - * @return string - * The timestamp formatted for display. - */ - timestampString: function (milliseconds) { - let d = new Date(milliseconds ? milliseconds : null); - let hours = d.getHours(), minutes = d.getMinutes(); - let seconds = d.getSeconds(); - milliseconds = d.getMilliseconds(); - let parameters = [hours, minutes, seconds, milliseconds]; - return this.getFormatStr("timestampFormat", parameters); - }, - - /** - * Retrieve a localized string. - * - * @param string name - * The string name you want from the Web Console string bundle. - * @return string - * The localized string. - */ - getStr: function (name) { - try { - return this._helper.getStr(name); - } catch (ex) { - console.error("Failed to get string: " + name); - throw ex; - } - }, - - /** - * Retrieve a localized string formatted with values coming from the given - * array. - * - * @param string name - * The string name you want from the Web Console string bundle. - * @param array array - * The array of values you want in the formatted string. - * @return string - * The formatted local string. - */ - getFormatStr: function (name, array) { - try { - return this._helper.getFormatStr(name, ...array); - } catch (ex) { - console.error("Failed to format string: " + name); - throw ex; - } - }, -}; diff --git a/devtools/client/webconsole/webconsole-connection-proxy.js b/devtools/client/webconsole/webconsole-connection-proxy.js index bfeed32d68ec..263e2b10da35 100644 --- a/devtools/client/webconsole/webconsole-connection-proxy.js +++ b/devtools/client/webconsole/webconsole-connection-proxy.js @@ -10,8 +10,7 @@ const {Utils: WebConsoleUtils} = require("devtools/client/webconsole/utils"); const defer = require("devtools/shared/defer"); const Services = require("Services"); -const STRINGS_URI = "devtools/client/locales/webconsole.properties"; -var l10n = new WebConsoleUtils.L10n(STRINGS_URI); +const l10n = require("devtools/client/webconsole/webconsole-l10n"); const PREF_CONNECTION_TIMEOUT = "devtools.debugger.remote-timeout"; // Web Console connection proxy diff --git a/devtools/client/webconsole/webconsole-l10n.js b/devtools/client/webconsole/webconsole-l10n.js new file mode 100644 index 000000000000..58efe4ed97aa --- /dev/null +++ b/devtools/client/webconsole/webconsole-l10n.js @@ -0,0 +1,70 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const {LocalizationHelper} = require("devtools/shared/l10n"); +const helper = new LocalizationHelper("devtools/client/locales/webconsole.properties"); + +const l10n = { + + /** + * Generates a formatted timestamp string for displaying in console messages. + * + * @param integer [milliseconds] + * Optional, allows you to specify the timestamp in milliseconds since + * the UNIX epoch. + * @return string + * The timestamp formatted for display. + */ + timestampString: function (milliseconds) { + let d = new Date(milliseconds ? milliseconds : null); + let hours = d.getHours(), minutes = d.getMinutes(); + let seconds = d.getSeconds(); + milliseconds = d.getMilliseconds(); + let parameters = [hours, minutes, seconds, milliseconds]; + return l10n.getFormatStr("timestampFormat", parameters); + }, + + /** + * Retrieve a localized string. + * + * @param string name + * The string name you want from the Web Console string bundle. + * @return string + * The localized string. + */ + getStr: function (name) { + try { + return helper.getStr(name); + } catch (ex) { + console.error("Failed to get string: " + name); + throw ex; + } + }, + + /** + * Retrieve a localized string formatted with values coming from the given + * array. + * + * @param string name + * The string name you want from the Web Console string bundle. + * @param array array + * The array of values you want in the formatted string. + * @return string + * The formatted local string. + */ + getFormatStr: function (name, array) { + try { + return helper.getFormatStr(name, ...array); + } catch (ex) { + console.error("Failed to format string: " + name); + throw ex; + } + }, +}; + +module.exports = l10n; diff --git a/devtools/client/webconsole/webconsole.js b/devtools/client/webconsole/webconsole.js index d17f1dc33aa1..935f80e4a35a 100644 --- a/devtools/client/webconsole/webconsole.js +++ b/devtools/client/webconsole/webconsole.js @@ -38,8 +38,7 @@ loader.lazyRequireGetter(this, "ZoomKeys", "devtools/client/shared/zoom-keys"); loader.lazyRequireGetter(this, "WebConsoleConnectionProxy", "devtools/client/webconsole/webconsole-connection-proxy", true); const {PluralForm} = require("devtools/shared/plural-form"); -const STRINGS_URI = "devtools/client/locales/webconsole.properties"; -var l10n = new WebConsoleUtils.L10n(STRINGS_URI); +const l10n = require("devtools/client/webconsole/webconsole-l10n"); const XHTML_NS = "http://www.w3.org/1999/xhtml"; diff --git a/devtools/client/webconsole/webpack.config.js b/devtools/client/webconsole/webpack.config.js index 9992feabe712..703232f39eee 100644 --- a/devtools/client/webconsole/webpack.config.js +++ b/devtools/client/webconsole/webpack.config.js @@ -49,6 +49,7 @@ webpackConfig.resolve = { "devtools/client/webconsole/utils": path.join(__dirname, "new-console-output/test/fixtures/WebConsoleUtils"), "devtools/client/webconsole/new-console-output": path.join(__dirname, "new-console-output"), "devtools/client/webconsole/webconsole-connection-proxy": path.join(__dirname, "webconsole-connection-proxy"), + "devtools/client/webconsole/webconsole-l10n": path.join(__dirname, "webconsole-l10n"), "react": path.join(__dirname, "node_modules/react"), "devtools/client/shared/vendor/immutable": "immutable", diff --git a/devtools/client/webide/modules/app-manager.js b/devtools/client/webide/modules/app-manager.js index 0f4f6dbd7336..30da3d70f70e 100644 --- a/devtools/client/webide/modules/app-manager.js +++ b/devtools/client/webide/modules/app-manager.js @@ -9,7 +9,7 @@ const {TargetFactory} = require("devtools/client/framework/target"); const Services = require("Services"); const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); const EventEmitter = require("devtools/shared/event-emitter"); -const {TextEncoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); +const {OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); const {AppProjects} = require("devtools/client/webide/modules/app-projects"); const TabStore = require("devtools/client/webide/modules/tab-store"); const {AppValidator} = require("devtools/client/webide/modules/app-validator"); diff --git a/devtools/client/webide/modules/build.js b/devtools/client/webide/modules/build.js index 34cbcc0b7571..75e30d66b340 100644 --- a/devtools/client/webide/modules/build.js +++ b/devtools/client/webide/modules/build.js @@ -6,7 +6,7 @@ const {Cu, Cc, Ci} = require("chrome"); const promise = require("promise"); const { Task } = require("devtools/shared/task"); -const { TextDecoder, OS } = Cu.import("resource://gre/modules/osfile.jsm", {}); +const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {}); const Subprocess = require("sdk/system/child_process/subprocess"); const ProjectBuilding = exports.ProjectBuilding = { diff --git a/devtools/client/webide/test/test_build.html b/devtools/client/webide/test/test_build.html index d6208b3d909b..fc44546b98b4 100644 --- a/devtools/client/webide/test/test_build.html +++ b/devtools/client/webide/test/test_build.html @@ -18,7 +18,7 @@ window.onload = function() { SimpleTest.waitForExplicitFinish(); - let {TextDecoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); + let {OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); let {ProjectBuilding} = require("devtools/client/webide/modules/build"); Task.spawn(function* () { diff --git a/devtools/client/webide/test/test_manifestUpdate.html b/devtools/client/webide/test/test_manifestUpdate.html index 0e37610be59f..d8e7b3afd766 100644 --- a/devtools/client/webide/test/test_manifestUpdate.html +++ b/devtools/client/webide/test/test_manifestUpdate.html @@ -18,7 +18,7 @@ window.onload = function() { SimpleTest.waitForExplicitFinish(); - let {TextDecoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); + let {OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); Task.spawn(function* () { let win = yield openWebIDE(); diff --git a/devtools/server/actors/highlighters/utils/markup.js b/devtools/server/actors/highlighters/utils/markup.js index 3537fc6ea3bc..1666a6da340b 100644 --- a/devtools/server/actors/highlighters/utils/markup.js +++ b/devtools/server/actors/highlighters/utils/markup.js @@ -4,7 +4,7 @@ "use strict"; -const { Cc, Ci, Cu } = require("chrome"); +const { Cc, Ci, Cu, Cr } = require("chrome"); const { getCurrentZoom, getWindowDimensions, getViewportDimensions, getRootBindingParent, loadSheet } = require("devtools/shared/layout/utils"); const { on, emit } = require("sdk/event/core"); @@ -270,7 +270,23 @@ CanvasFrameAnonymousContentHelper.prototype = { // at least on desktop. Therefore, removing the code that was dealing with // that scenario, fixes when we're adding anonymous content in a tab that // is not the active one (see bug 1260043 and bug 1260044) - this._content = doc.insertAnonymousContent(node); + try { + this._content = doc.insertAnonymousContent(node); + } catch (e) { + // If the `insertAnonymousContent` fails throwing a `NS_ERROR_UNEXPECTED`, it means + // we don't have access to a `CustomContentContainer` yet (see bug 1365075). + // At this point, it could only happen on document's interactive state, and we + // need to wait until the `complete` state before inserting the anonymous content + // again. + if (e.result === Cr.NS_ERROR_UNEXPECTED && doc.readyState === "interactive") { + // The next state change will be "complete" since the current is "interactive" + doc.addEventListener("readystatechange", () => { + this._content = doc.insertAnonymousContent(node); + }, { once: true }); + } else { + throw e; + } + } }, _remove() { diff --git a/devtools/shared/DevToolsUtils.js b/devtools/shared/DevToolsUtils.js index 8e5e4e9149cb..52f841df79d3 100644 --- a/devtools/shared/DevToolsUtils.js +++ b/devtools/shared/DevToolsUtils.js @@ -363,10 +363,6 @@ DevToolsUtils.defineLazyGetter(this, "OS", () => { return Cu.import("resource://gre/modules/osfile.jsm", {}).OS; }); -DevToolsUtils.defineLazyGetter(this, "TextDecoder", () => { - return Cu.import("resource://gre/modules/osfile.jsm", {}).TextDecoder; -}); - DevToolsUtils.defineLazyGetter(this, "NetworkHelper", () => { return require("devtools/shared/webconsole/network-helper"); }); diff --git a/devtools/shared/builtin-modules.js b/devtools/shared/builtin-modules.js index 2af9f0f8b36e..56c631d8e64a 100644 --- a/devtools/shared/builtin-modules.js +++ b/devtools/shared/builtin-modules.js @@ -20,7 +20,7 @@ const jsmScope = Cu.import("resource://gre/modules/Services.jsm", {}); const { Services } = jsmScope; // Steal various globals only available in JSM scope (and not Sandbox one) const { PromiseDebugging, ChromeUtils, ThreadSafeChromeUtils, HeapSnapshot, - atob, btoa } = jsmScope; + atob, btoa, TextEncoder, TextDecoder } = jsmScope; const { URL } = Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(), {wantGlobalProperties: ["URL"]}); @@ -215,6 +215,8 @@ exports.globals = { reportError: Cu.reportError, atob: atob, btoa: btoa, + TextEncoder: TextEncoder, + TextDecoder: TextDecoder, URL, loader: { lazyGetter: defineLazyGetter, diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index bde473d34d51..8da8d7417aff 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -1234,6 +1234,8 @@ exports.CSS_PROPERTIES = { "supports": [], "values": [ "ignore", + "ignore-horizontal", + "ignore-vertical", "inherit", "initial", "stretch-to-fit", @@ -3402,6 +3404,8 @@ exports.CSS_PROPERTIES = { "icon", "ideographic", "ignore", + "ignore-horizontal", + "ignore-vertical", "inactive", "infinite", "inherit", diff --git a/devtools/shared/gcli/commands/cmd.js b/devtools/shared/gcli/commands/cmd.js index 23960fc5b644..221cc2912074 100644 --- a/devtools/shared/gcli/commands/cmd.js +++ b/devtools/shared/gcli/commands/cmd.js @@ -5,7 +5,7 @@ "use strict"; const { Cc, Ci, Cu } = require("chrome"); -const { OS, TextDecoder } = Cu.import("resource://gre/modules/osfile.jsm", {}); +const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {}); const { Task } = require("devtools/shared/task"); const gcli = require("gcli/index"); diff --git a/dom/base/AnonymousContent.cpp b/dom/base/AnonymousContent.cpp index 3d26f121c968..448ce0ad1afe 100644 --- a/dom/base/AnonymousContent.cpp +++ b/dom/base/AnonymousContent.cpp @@ -228,7 +228,8 @@ AnonymousContent::GetComputedStylePropertyValue(const nsAString& aElementId, } RefPtr cs = - new nsComputedDOMStyle(element, NS_LITERAL_STRING(""), shell); + new nsComputedDOMStyle(element, NS_LITERAL_STRING(""), shell, + nsComputedDOMStyle::eAll); aRv = cs->GetPropertyValue(aPropertyName, aResult); } diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 50b347acb436..ad9bf503b926 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -2299,13 +2299,15 @@ Element::MaybeCheckSameAttrVal(int32_t aNamespaceID, bool aNotify, nsAttrValue& aOldValue, uint8_t* aModType, - bool* aHasListeners) + bool* aHasListeners, + bool* aOldValueSet) { bool modification = false; *aHasListeners = aNotify && nsContentUtils::HasMutationListeners(this, NS_EVENT_BITS_MUTATION_ATTRMODIFIED, this); + *aOldValueSet = false; // If we have no listeners and aNotify is false, we are almost certainly // coming from the content sink and will almost certainly have no previous @@ -2330,6 +2332,7 @@ Element::MaybeCheckSameAttrVal(int32_t aNamespaceID, // We have to serialize the value anyway in order to create the // mutation event so there's no cost in doing it now. aOldValue.SetToSerialized(*info.mValue); + *aOldValueSet = true; } bool valueMatches = aValue.EqualsAsStrings(*info.mValue); if (valueMatches && aPrefix == info.mName->GetPrefix()) { @@ -2349,10 +2352,12 @@ Element::OnlyNotifySameValueSet(int32_t aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix, const nsAttrValueOrString& aValue, bool aNotify, nsAttrValue& aOldValue, - uint8_t* aModType, bool* aHasListeners) + uint8_t* aModType, bool* aHasListeners, + bool* aOldValueSet) { if (!MaybeCheckSameAttrVal(aNamespaceID, aName, aPrefix, aValue, aNotify, - aOldValue, aModType, aHasListeners)) { + aOldValue, aModType, aHasListeners, + aOldValueSet)) { return false; } @@ -2383,9 +2388,10 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName, // OnlyNotifySameValueSet call. nsAttrValueOrString value(aValue); nsAttrValue oldValue; + bool oldValueSet; if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify, - oldValue, &modType, &hasListeners)) { + oldValue, &modType, &hasListeners, &oldValueSet)) { return NS_OK; } @@ -2418,7 +2424,8 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName, attrValue.SetTo(aValue); } - return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue, + return SetAttrAndNotify(aNamespaceID, aName, aPrefix, + oldValueSet ? &oldValue : nullptr, attrValue, modType, hasListeners, aNotify, kCallAfterSetAttr, document, updateBatch); } @@ -2443,9 +2450,10 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName, bool hasListeners; nsAttrValueOrString value(aParsedValue); nsAttrValue oldValue; + bool oldValueSet; if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify, - oldValue, &modType, &hasListeners)) { + oldValue, &modType, &hasListeners, &oldValueSet)) { return NS_OK; } @@ -2459,7 +2467,8 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName, nsIDocument* document = GetComposedDoc(); mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); - return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue, + return SetAttrAndNotify(aNamespaceID, aName, aPrefix, + oldValueSet ? &oldValue : nullptr, aParsedValue, modType, hasListeners, aNotify, kCallAfterSetAttr, document, updateBatch); } @@ -2468,7 +2477,7 @@ nsresult Element::SetAttrAndNotify(int32_t aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix, - const nsAttrValue& aOldValue, + const nsAttrValue* aOldValue, nsAttrValue& aParsedValue, uint8_t aModType, bool aFireMutation, @@ -2489,6 +2498,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, bool hadValidDir = false; bool hadDirAuto = false; + bool oldValueSet; if (aNamespaceID == kNameSpaceID_None) { if (aName == nsGkAtoms::dir) { @@ -2499,8 +2509,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, // XXXbz Perhaps we should push up the attribute mapping function // stuff to Element? if (!IsAttributeMapped(aName) || - !SetMappedAttribute(aName, aParsedValue, &rv)) { - rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue); + !SetAndSwapMappedAttribute(aName, aParsedValue, &oldValueSet, &rv)) { + rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue, &oldValueSet); } } else { @@ -2509,14 +2519,24 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, aNamespaceID, nsIDOMNode::ATTRIBUTE_NODE); - rv = mAttrsAndChildren.SetAndSwapAttr(ni, aParsedValue); + rv = mAttrsAndChildren.SetAndSwapAttr(ni, aParsedValue, &oldValueSet); } + NS_ENSURE_SUCCESS(rv, rv); // If the old value owns its own data, we know it is OK to keep using it. - const nsAttrValue* oldValue = - aParsedValue.StoresOwnData() ? &aParsedValue : &aOldValue; - - NS_ENSURE_SUCCESS(rv, rv); + // oldValue will be null if there was no previously set value + const nsAttrValue* oldValue; + if (aParsedValue.StoresOwnData()) { + if (oldValueSet) { + oldValue = &aParsedValue; + } else { + oldValue = nullptr; + } + } else { + // No need to conditionally assign null here. If there was no previously + // set value for the attribute, aOldValue will already be null. + oldValue = aOldValue; + } if (aComposedDocument || HasFlag(NODE_FORCE_XBL_BINDINGS)) { RefPtr binding = GetXBLBinding(); @@ -2527,7 +2547,14 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, nsIDocument* ownerDoc = OwnerDoc(); if (ownerDoc && GetCustomElementData()) { - nsCOMPtr oldValueAtom = oldValue->GetAsAtom(); + nsCOMPtr oldValueAtom; + if (oldValue) { + oldValueAtom = oldValue->GetAsAtom(); + } else { + // If there is no old value, get the value of the uninitialized attribute + // that was swapped with aParsedValue. + oldValueAtom = aParsedValue.GetAsAtom(); + } nsCOMPtr newValueAtom = valueForAfterSetAttr.GetAsAtom(); LifecycleCallbackArgs args = { nsDependentAtomString(aName), @@ -2541,7 +2568,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, } if (aCallAfterSetAttr) { - rv = AfterSetAttr(aNamespaceID, aName, &valueForAfterSetAttr, aNotify); + rv = AfterSetAttr(aNamespaceID, aName, &valueForAfterSetAttr, oldValue, + aNotify); NS_ENSURE_SUCCESS(rv, rv); if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) { @@ -2557,7 +2585,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, // Callers only compute aOldValue under certain conditions which may not // be triggered by all nsIMutationObservers. nsNodeUtils::AttributeChanged(this, aNamespaceID, aName, aModType, - oldValue == &aParsedValue ? &aParsedValue : nullptr); + aParsedValue.StoresOwnData() ? &aParsedValue : nullptr); } if (aFireMutation) { @@ -2575,7 +2603,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, if (!newValue.IsEmpty()) { mutation.mNewAttrValue = NS_Atomize(newValue); } - if (!oldValue->IsEmptyString()) { + if (oldValue && !oldValue->IsEmptyString()) { mutation.mPrevAttrValue = oldValue->GetAsAtom(); } mutation.mAttrChange = aModType; @@ -2618,9 +2646,10 @@ Element::ParseAttribute(int32_t aNamespaceID, } bool -Element::SetMappedAttribute(nsIAtom* aName, - nsAttrValue& aValue, - nsresult* aRetval) +Element::SetAndSwapMappedAttribute(nsIAtom* aName, + nsAttrValue& aValue, + bool* aValueWasSet, + nsresult* aRetval) { *aRetval = NS_OK; return false; @@ -2775,7 +2804,7 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName, ownerDoc, nsIDocument::eAttributeChanged, this, &args); } - rv = AfterSetAttr(aNameSpaceID, aName, nullptr, aNotify); + rv = AfterSetAttr(aNameSpaceID, aName, nullptr, &oldValue, aNotify); NS_ENSURE_SUCCESS(rv, rv); UpdateState(aNotify); diff --git a/dom/base/Element.h b/dom/base/Element.h index 79ee804f9346..3b76cdc223ea 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -631,25 +631,49 @@ public: * values will not actually be compared if we aren't notifying and we don't * have mutation listeners (in which case it's cheap to just return false * and let the caller go ahead and set the value). - * @param aOldValue Set to the old value of the attribute, but only if there - * are event listeners. If set, the type of aOldValue will be either + * @param aOldValue [out] Set to the old value of the attribute, but only if + * there are event listeners. If set, the type of aOldValue will be either * nsAttrValue::eString or nsAttrValue::eAtom. - * @param aModType Set to nsIDOMMutationEvent::MODIFICATION or to + * @param aModType [out] Set to nsIDOMMutationEvent::MODIFICATION or to * nsIDOMMutationEvent::ADDITION, but only if this helper returns true - * @param aHasListeners Set to true if there are mutation event listeners - * listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED + * @param aHasListeners [out] Set to true if there are mutation event + * listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED + * @param aOldValueSet [out] Indicates whether an old attribute value has been + * stored in aOldValue. The bool will be set to true if a value was stored. */ bool MaybeCheckSameAttrVal(int32_t aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix, const nsAttrValueOrString& aValue, bool aNotify, nsAttrValue& aOldValue, - uint8_t* aModType, bool* aHasListeners); + uint8_t* aModType, bool* aHasListeners, + bool* aOldValueSet); + /** + * Notifies mutation listeners if aNotify is true, there are mutation + * listeners, and the attribute value is changing. + * + * @param aNamespaceID The namespace of the attribute + * @param aName The local name of the attribute + * @param aPrefix The prefix of the attribute + * @param aValue The value that the attribute is being changed to + * @param aNotify If true, mutation listeners will be notified if they exist + * and the attribute value is changing + * @param aOldValue [out] Set to the old value of the attribute, but only if + * there are event listeners. If set, the type of aOldValue will be either + * nsAttrValue::eString or nsAttrValue::eAtom. + * @param aModType [out] Set to nsIDOMMutationEvent::MODIFICATION or to + * nsIDOMMutationEvent::ADDITION, but only if this helper returns true + * @param aHasListeners [out] Set to true if there are mutation event + * listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED + * @param aOldValueSet [out] Indicates whether an old attribute value has been + * stored in aOldValue. The bool will be set to true if a value was stored. + */ bool OnlyNotifySameValueSet(int32_t aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix, const nsAttrValueOrString& aValue, bool aNotify, nsAttrValue& aOldValue, - uint8_t* aModType, bool* aHasListeners); + uint8_t* aModType, bool* aHasListeners, + bool* aOldValueSet); virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix, const nsAString& aValue, bool aNotify) override; @@ -1352,7 +1376,10 @@ protected: * its current value) is !StoresOwnData() --- in which * case the current value is probably already useless. * If the current value is StoresOwnData() (or absent), - * aOldValue will not be used. + * aOldValue will not be used. aOldValue will only be set + * in certain circumstances (there are mutation + * listeners, element is a custom element, attribute was + * not previously unset). Otherwise it will be null. * @param aParsedValue parsed new value of attribute. Replaced by the * old value of the attribute. This old value is only * useful if either it or the new value is StoresOwnData. @@ -1366,7 +1393,7 @@ protected: nsresult SetAttrAndNotify(int32_t aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix, - const nsAttrValue& aOldValue, + const nsAttrValue* aOldValue, nsAttrValue& aParsedValue, uint8_t aModType, bool aFireMutation, @@ -1410,13 +1437,20 @@ protected: * returns true (the value of aRetval does not matter for that purpose). * * @param aName the name of the attribute - * @param aValue the nsAttrValue to set + * @param aValue the nsAttrValue to set. Will be swapped with the existing + * value of the attribute if the attribute already exists. + * @param [out] aValueWasSet If the attribute was not set previously, + * aValue will be swapped with an empty attribute + * and aValueWasSet will be set to false. Otherwise, + * aValueWasSet will be set to true and aValue will + * contain the previous value set. * @param [out] aRetval the nsresult status of the operation, if any. * @return true if the setting was attempted, false otherwise. */ - virtual bool SetMappedAttribute(nsIAtom* aName, - nsAttrValue& aValue, - nsresult* aRetval); + virtual bool SetAndSwapMappedAttribute(nsIAtom* aName, + nsAttrValue& aValue, + bool* aValueWasSet, + nsresult* aRetval); /** * Hook that is called by Element::SetAttr to allow subclasses to @@ -1444,19 +1478,24 @@ protected: /** * Hook that is called by Element::SetAttr to allow subclasses to * deal with attribute sets. This will only be called after we have called - * SetAndTakeAttr and AttributeChanged (that is, after we have actually set - * the attr). It will always be called under a scriptblocker. + * SetAndSwapAttr (that is, after we have actually set the attr). It will + * always be called under a scriptblocker. * * @param aNamespaceID the namespace of the attr being set * @param aName the localname of the attribute being set * @param aValue the value it's being set to. If null, the attr is being * removed. + * @param aOldValue the value that the attribute had previously. If null, + * the attr was not previously set. This argument may not have the + * correct value for SVG elements, or other cases in which the + * attribute value doesn't store its own data * @param aNotify Whether we plan to notify document observers. */ // Note that this is inlined so that when subclasses call it it gets // inlined. Those calls don't go through a vtable. virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { return NS_OK; } diff --git a/dom/base/nsAttrAndChildArray.cpp b/dom/base/nsAttrAndChildArray.cpp index d229d1e88b33..40159373eabe 100644 --- a/dom/base/nsAttrAndChildArray.cpp +++ b/dom/base/nsAttrAndChildArray.cpp @@ -389,12 +389,15 @@ nsAttrAndChildArray::AttrAt(uint32_t aPos) const } nsresult -nsAttrAndChildArray::SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue) +nsAttrAndChildArray::SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue, + bool* aHadValue) { + *aHadValue = false; uint32_t i, slotCount = AttrSlotCount(); for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) { ATTRS(mImpl)[i].mValue.SwapValueWith(aValue); + *aHadValue = true; return NS_OK; } } @@ -414,21 +417,22 @@ nsAttrAndChildArray::SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue) } nsresult -nsAttrAndChildArray::SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue) +nsAttrAndChildArray::SetAndSwapAttr(mozilla::dom::NodeInfo* aName, + nsAttrValue& aValue, bool* aHadValue) { int32_t namespaceID = aName->NamespaceID(); nsIAtom* localName = aName->NameAtom(); if (namespaceID == kNameSpaceID_None) { - return SetAndSwapAttr(localName, aValue); + return SetAndSwapAttr(localName, aValue, aHadValue); } + *aHadValue = false; uint32_t i, slotCount = AttrSlotCount(); for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(localName, namespaceID)) { ATTRS(mImpl)[i].mName.SetTo(aName); - ATTRS(mImpl)[i].mValue.Reset(); ATTRS(mImpl)[i].mValue.SwapValueWith(aValue); - + *aHadValue = true; return NS_OK; } } @@ -583,10 +587,11 @@ nsAttrAndChildArray::IndexOfAttr(nsIAtom* aLocalName, int32_t aNamespaceID) cons } nsresult -nsAttrAndChildArray::SetAndTakeMappedAttr(nsIAtom* aLocalName, +nsAttrAndChildArray::SetAndSwapMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue, nsMappedAttributeElement* aContent, - nsHTMLStyleSheet* aSheet) + nsHTMLStyleSheet* aSheet, + bool* aHadValue) { bool willAdd = true; if (mImpl && mImpl->mMappedAttrs) { @@ -596,7 +601,7 @@ nsAttrAndChildArray::SetAndTakeMappedAttr(nsIAtom* aLocalName, RefPtr mapped = GetModifiableMapped(aContent, aSheet, willAdd); - mapped->SetAndTakeAttr(aLocalName, aValue); + mapped->SetAndSwapAttr(aLocalName, aValue, aHadValue); return MakeMappedUnique(mapped); } diff --git a/dom/base/nsAttrAndChildArray.h b/dom/base/nsAttrAndChildArray.h index a1deab1f3854..2a5193fa5fbd 100644 --- a/dom/base/nsAttrAndChildArray.h +++ b/dom/base/nsAttrAndChildArray.h @@ -91,8 +91,13 @@ public: nsCaseTreatment aCaseSensitive) const; const nsAttrValue* AttrAt(uint32_t aPos) const; // SetAndSwapAttr swaps the current attribute value with aValue. - nsresult SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue); - nsresult SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue); + // If the attribute was unset, an empty value will be swapped into aValue + // and aHadValue will be set to false. Otherwise, aHadValue will be set to + // true. + nsresult SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue, + bool* aHadValue); + nsresult SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue, + bool* aHadValue); // Remove the attr at position aPos. The value of the attr is placed in // aValue; any value that was already in aValue is destroyed. @@ -110,9 +115,14 @@ public: const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const; int32_t IndexOfAttr(nsIAtom* aLocalName, int32_t aNamespaceID = kNameSpaceID_None) const; - nsresult SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue, + // SetAndSwapMappedAttr swaps the current attribute value with aValue. + // If the attribute was unset, an empty value will be swapped into aValue + // and aHadValue will be set to false. Otherwise, aHadValue will be set to + // true. + nsresult SetAndSwapMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue, nsMappedAttributeElement* aContent, - nsHTMLStyleSheet* aSheet); + nsHTMLStyleSheet* aSheet, + bool* aHadValue); nsresult SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet) { if (!mImpl || !mImpl->mMappedAttrs) { return NS_OK; diff --git a/dom/base/nsDOMCID.h b/dom/base/nsDOMCID.h index 97dffb492fbc..9f819a92f0e3 100644 --- a/dom/base/nsDOMCID.h +++ b/dom/base/nsDOMCID.h @@ -21,13 +21,6 @@ 0x45f27d10, 0x987b, 0x11d2, \ {0xbd, 0x40, 0x00, 0x10, 0x5a, 0xa4, 0x5e, 0x89} } -//The dom cannot provide the crypto or pkcs11 classes that -//were used in older days, so if someone wants to provide -//the service they must implement an object and give it -//this class ID -#define NS_CRYPTO_CONTRACTID "@mozilla.org/security/crypto;1" -#define NS_PKCS11_CONTRACTID "@mozilla.org/security/pkcs11;1" - #define NS_XPATH_EVALUATOR_CONTRACTID "@mozilla.org/dom/xpath-evaluator;1" #endif /* nsDOMCID_h__ */ diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 69d9f3440f2c..19ac38a85d85 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2807,6 +2807,7 @@ nsDOMWindowUtils::GetUnanimatedComputedStyle(nsIDOMElement* aElement, RefPtr computedStyle = NS_NewComputedDOMStyle( element, aPseudoElement, shell, + nsComputedDOMStyle::StyleType::eAll, nsComputedDOMStyle::AnimationFlag::eWithoutAnimation); computedStyle->GetPropertyValue(propertyID, aResult); return NS_OK; diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index d296df747322..777929766652 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -11079,13 +11079,46 @@ nsGlobalWindow::GetComputedStyle(Element& aElt, const nsAString& aPseudoElt, ErrorResult& aError) { MOZ_ASSERT(IsInnerWindow()); - FORWARD_TO_OUTER_OR_THROW(GetComputedStyleOuter, - (aElt, aPseudoElt), aError, nullptr); + return GetComputedStyleHelper(aElt, aPseudoElt, false, aError); } already_AddRefed -nsGlobalWindow::GetComputedStyleOuter(Element& aElt, - const nsAString& aPseudoElt) +nsGlobalWindow::GetDefaultComputedStyle(Element& aElt, + const nsAString& aPseudoElt, + ErrorResult& aError) +{ + MOZ_ASSERT(IsInnerWindow()); + return GetComputedStyleHelper(aElt, aPseudoElt, true, aError); +} + +nsresult +nsGlobalWindow::GetComputedStyleHelper(nsIDOMElement* aElt, + const nsAString& aPseudoElt, + bool aDefaultStylesOnly, + nsIDOMCSSStyleDeclaration** aReturn) +{ + MOZ_ASSERT(IsInnerWindow()); + + NS_ENSURE_ARG_POINTER(aReturn); + *aReturn = nullptr; + + nsCOMPtr element = do_QueryInterface(aElt); + if (!element) { + return NS_ERROR_DOM_NOT_SUPPORTED_ERR; + } + + ErrorResult rv; + nsCOMPtr declaration = + GetComputedStyleHelper(*element, aPseudoElt, aDefaultStylesOnly, rv); + declaration.forget(aReturn); + + return rv.StealNSResult(); +} + +already_AddRefed +nsGlobalWindow::GetComputedStyleHelperOuter(Element& aElt, + const nsAString& aPseudoElt, + bool aDefaultStylesOnly) { MOZ_RELEASE_ASSERT(IsOuterWindow()); @@ -11117,11 +11150,24 @@ nsGlobalWindow::GetComputedStyleOuter(Element& aElt, } RefPtr compStyle = - NS_NewComputedDOMStyle(&aElt, aPseudoElt, presShell); + NS_NewComputedDOMStyle(&aElt, aPseudoElt, presShell, + aDefaultStylesOnly ? nsComputedDOMStyle::eDefaultOnly : + nsComputedDOMStyle::eAll); return compStyle.forget(); } +already_AddRefed +nsGlobalWindow::GetComputedStyleHelper(Element& aElt, + const nsAString& aPseudoElt, + bool aDefaultStylesOnly, + ErrorResult& aError) +{ + FORWARD_TO_OUTER_OR_THROW(GetComputedStyleHelperOuter, + (aElt, aPseudoElt, aDefaultStylesOnly), + aError, nullptr); +} + Storage* nsGlobalWindow::GetSessionStorage(ErrorResult& aError) { diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 5ead53320654..fb76bd39b68e 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -1153,6 +1153,10 @@ public: GetSpeechSynthesis(mozilla::ErrorResult& aError); bool HasActiveSpeechSynthesis(); #endif + already_AddRefed + GetDefaultComputedStyle(mozilla::dom::Element& aElt, + const nsAString& aPseudoElt, + mozilla::ErrorResult& aError); void SizeToContentOuter(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError); void SizeToContent(mozilla::dom::CallerType aCallerType, @@ -1731,9 +1735,20 @@ public: nsDOMWindowList* GetWindowList(); protected: + // Helper for getComputedStyle and getDefaultComputedStyle already_AddRefed - GetComputedStyleOuter(mozilla::dom::Element& aElt, - const nsAString& aPseudoElt); + GetComputedStyleHelperOuter(mozilla::dom::Element& aElt, + const nsAString& aPseudoElt, + bool aDefaultStylesOnly); + already_AddRefed + GetComputedStyleHelper(mozilla::dom::Element& aElt, + const nsAString& aPseudoElt, + bool aDefaultStylesOnly, + mozilla::ErrorResult& aError); + nsresult GetComputedStyleHelper(nsIDOMElement* aElt, + const nsAString& aPseudoElt, + bool aDefaultStylesOnly, + nsIDOMCSSStyleDeclaration** aReturn); // Outer windows only. void PreloadLocalStorage(); diff --git a/dom/base/nsMappedAttributeElement.cpp b/dom/base/nsMappedAttributeElement.cpp index 1408c1f4ba0a..bdbe553ff204 100644 --- a/dom/base/nsMappedAttributeElement.cpp +++ b/dom/base/nsMappedAttributeElement.cpp @@ -15,13 +15,14 @@ nsMappedAttributeElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker) } bool -nsMappedAttributeElement::SetMappedAttribute(nsIAtom* aName, - nsAttrValue& aValue, - nsresult* aRetval) +nsMappedAttributeElement::SetAndSwapMappedAttribute(nsIAtom* aName, + nsAttrValue& aValue, + bool* aValueWasSet, + nsresult* aRetval) { nsHTMLStyleSheet* sheet = OwnerDoc()->GetAttributeStyleSheet(); - *aRetval = mAttrsAndChildren.SetAndTakeMappedAttr(aName, aValue, - this, sheet); + *aRetval = mAttrsAndChildren.SetAndSwapMappedAttr(aName, aValue, + this, sheet, aValueWasSet); return true; } diff --git a/dom/base/nsMappedAttributeElement.h b/dom/base/nsMappedAttributeElement.h index 0af7a652cc05..cec025dfc68d 100644 --- a/dom/base/nsMappedAttributeElement.h +++ b/dom/base/nsMappedAttributeElement.h @@ -40,9 +40,10 @@ public: mozilla::GenericSpecifiedValues* aGenericData); NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override; - virtual bool SetMappedAttribute(nsIAtom* aName, - nsAttrValue& aValue, - nsresult* aRetval) override; + virtual bool SetAndSwapMappedAttribute(nsIAtom* aName, + nsAttrValue& aValue, + bool* aValueWasSet, + nsresult* aRetval) override; virtual void NodeInfoChanged(nsIDocument* aOldDoc) override; }; diff --git a/dom/base/nsMappedAttributes.cpp b/dom/base/nsMappedAttributes.cpp index e6e25337628d..0c5d6f0c615b 100644 --- a/dom/base/nsMappedAttributes.cpp +++ b/dom/base/nsMappedAttributes.cpp @@ -156,14 +156,16 @@ NS_IMPL_QUERY_INTERFACE(nsMappedAttributes, nsIStyleRule) void -nsMappedAttributes::SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue) +nsMappedAttributes::SetAndSwapAttr(nsIAtom* aAttrName, nsAttrValue& aValue, + bool* aValueWasSet) { NS_PRECONDITION(aAttrName, "null name"); + *aValueWasSet = false; uint32_t i; for (i = 0; i < mAttrCount && !Attrs()[i].mName.IsSmaller(aAttrName); ++i) { if (Attrs()[i].mName.Equals(aAttrName)) { - Attrs()[i].mValue.Reset(); Attrs()[i].mValue.SwapValueWith(aValue); + *aValueWasSet = true; return; } } diff --git a/dom/base/nsMappedAttributes.h b/dom/base/nsMappedAttributes.h index 2799895f9212..3c1d2707247c 100644 --- a/dom/base/nsMappedAttributes.h +++ b/dom/base/nsMappedAttributes.h @@ -34,7 +34,8 @@ public: NS_DECL_ISUPPORTS - void SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue); + void SetAndSwapAttr(nsIAtom* aAttrName, nsAttrValue& aValue, + bool* aValueWasSet); const nsAttrValue* GetAttr(nsIAtom* aAttrName) const; const nsAttrValue* GetAttr(const nsAString& aAttrName) const; diff --git a/dom/base/nsStyledElement.cpp b/dom/base/nsStyledElement.cpp index f01af30bde33..228d3993d32a 100644 --- a/dom/base/nsStyledElement.cpp +++ b/dom/base/nsStyledElement.cpp @@ -57,6 +57,7 @@ nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration, SetMayHaveStyle(); bool modification = false; nsAttrValue oldValue; + bool oldValueSet = false; bool hasListeners = aNotify && nsContentUtils::HasMutationListeners(this, @@ -74,6 +75,7 @@ nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration, oldValueStr); if (modification) { oldValue.SetTo(oldValueStr); + oldValueSet = true; } } else if (aNotify && IsInUncomposedDoc()) { @@ -90,9 +92,9 @@ nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration, nsIDocument* document = GetComposedDoc(); mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify); return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr, - oldValue, attrValue, modType, hasListeners, - aNotify, kDontCallAfterSetAttr, document, - updateBatch); + oldValueSet ? &oldValue : nullptr, attrValue, modType, + hasListeners, aNotify, kDontCallAfterSetAttr, + document, updateBatch); } // --------------------------------------------------------------- @@ -128,7 +130,9 @@ nsStyledElement::ReparseStyleAttribute(bool aForceInDataDoc, bool aForceIfAlread ParseStyleAttribute(stringValue, attrValue, aForceInDataDoc); // Don't bother going through SetInlineStyleDeclaration; we don't // want to fire off mutation events or document notifications anyway - nsresult rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue); + bool oldValueSet; + nsresult rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue, + &oldValueSet); NS_ENSURE_SUCCESS(rv, rv); } diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 53df2bbf2e7f..ae5a3a594c97 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -217,16 +217,6 @@ DOMInterfaces = { 'nativeType': 'mozilla::css::ImportRule', }, -'CSSKeyframeRule': { - 'nativeType': 'nsCSSKeyframeRule', - 'headerFile': 'nsCSSRules.h', -}, - -'CSSKeyframesRule': { - 'nativeType': 'nsCSSKeyframesRule', - 'headerFile': 'nsCSSRules.h', -}, - 'CSSLexer': { 'wrapperCache': False }, diff --git a/dom/html/HTMLBodyElement.cpp b/dom/html/HTMLBodyElement.cpp index f0e6513735aa..424355e96c5c 100644 --- a/dom/html/HTMLBodyElement.cpp +++ b/dom/html/HTMLBodyElement.cpp @@ -442,10 +442,11 @@ HTMLBodyElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsresult HTMLBodyElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, - bool aNotify) + const nsAttrValue* aOldValue, bool aNotify) { nsresult rv = nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, - aName, aValue, aNotify); + aName, aValue, aOldValue, + aNotify); NS_ENSURE_SUCCESS(rv, rv); // if the last mapped attribute was removed, don't clear the // nsMappedAttributes, our style can still depend on the containing frame element diff --git a/dom/html/HTMLBodyElement.h b/dom/html/HTMLBodyElement.h index 0f96b590d78d..cf24bcf2d0f0 100644 --- a/dom/html/HTMLBodyElement.h +++ b/dom/html/HTMLBodyElement.h @@ -119,7 +119,9 @@ public: * Called when an attribute has just been changed */ virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) override; + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + bool aNotify) override; protected: virtual ~HTMLBodyElement(); diff --git a/dom/html/HTMLButtonElement.cpp b/dom/html/HTMLButtonElement.cpp index eacaa05f5573..51d21ee51d88 100644 --- a/dom/html/HTMLButtonElement.cpp +++ b/dom/html/HTMLButtonElement.cpp @@ -428,7 +428,8 @@ HTMLButtonElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsresult HTMLButtonElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None) { if (aName == nsGkAtoms::type) { @@ -445,7 +446,8 @@ HTMLButtonElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } return nsGenericHTMLFormElementWithState::AfterSetAttr(aNameSpaceID, aName, - aValue, aNotify); + aValue, aOldValue, + aNotify); } NS_IMETHODIMP diff --git a/dom/html/HTMLButtonElement.h b/dom/html/HTMLButtonElement.h index 3a05906ef126..0ef5ac27b33f 100644 --- a/dom/html/HTMLButtonElement.h +++ b/dom/html/HTMLButtonElement.h @@ -86,8 +86,10 @@ public: /** * Called when an attribute has just been changed */ - nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) override; + virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + bool aNotify) override; virtual bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, diff --git a/dom/html/HTMLFieldSetElement.cpp b/dom/html/HTMLFieldSetElement.cpp index b6bfca950b47..723a7d55fc77 100644 --- a/dom/html/HTMLFieldSetElement.cpp +++ b/dom/html/HTMLFieldSetElement.cpp @@ -83,7 +83,8 @@ HTMLFieldSetElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) nsresult HTMLFieldSetElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled && nsINode::GetFirstChild()) { @@ -100,7 +101,7 @@ HTMLFieldSetElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName, - aValue, aNotify); + aValue, aOldValue, aNotify); } // nsIDOMHTMLFieldSetElement diff --git a/dom/html/HTMLFieldSetElement.h b/dom/html/HTMLFieldSetElement.h index 66627d5062b0..5d64d192807a 100644 --- a/dom/html/HTMLFieldSetElement.h +++ b/dom/html/HTMLFieldSetElement.h @@ -43,7 +43,9 @@ public: virtual nsresult GetEventTargetParent( EventChainPreVisitor& aVisitor) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) override; + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + bool aNotify) override; virtual nsresult InsertChildAt(nsIContent* aChild, uint32_t aIndex, bool aNotify) override; diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp index 84afd47205d6..5427b03a9d56 100644 --- a/dom/html/HTMLFormElement.cpp +++ b/dom/html/HTMLFormElement.cpp @@ -215,7 +215,8 @@ HTMLFormElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsresult HTMLFormElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aName == nsGkAtoms::novalidate && aNameSpaceID == kNameSpaceID_None) { // Update all form elements states because they might be [no longer] @@ -231,7 +232,8 @@ HTMLFormElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } } - return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, aNotify); + return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, + aOldValue, aNotify); } NS_IMPL_STRING_ATTR(HTMLFormElement, AcceptCharset, acceptcharset) diff --git a/dom/html/HTMLFormElement.h b/dom/html/HTMLFormElement.h index cabbf39d6b71..9fec37e69345 100644 --- a/dom/html/HTMLFormElement.h +++ b/dom/html/HTMLFormElement.h @@ -114,7 +114,9 @@ public: nsIAtom* aPrefix, const nsAString& aValue, bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) override; + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + bool aNotify) override; /** * Forget all information about the current submission (and the fact that we diff --git a/dom/html/HTMLIFrameElement.cpp b/dom/html/HTMLIFrameElement.cpp index 772fadb2790f..6e4cd2b72e14 100644 --- a/dom/html/HTMLIFrameElement.cpp +++ b/dom/html/HTMLIFrameElement.cpp @@ -174,7 +174,7 @@ HTMLIFrameElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsresult HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, - bool aNotify) + const nsAttrValue* aOldValue, bool aNotify) { if (aName == nsGkAtoms::sandbox && aNameSpaceID == kNameSpaceID_None && mFrameLoader) { @@ -184,7 +184,7 @@ HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, mFrameLoader->ApplySandboxFlags(GetSandboxFlags()); } return nsGenericHTMLFrameElement::AfterSetAttr(aNameSpaceID, aName, aValue, - aNotify); + aOldValue, aNotify); } nsresult diff --git a/dom/html/HTMLIFrameElement.h b/dom/html/HTMLIFrameElement.h index b662950dfc83..047f5f505844 100644 --- a/dom/html/HTMLIFrameElement.h +++ b/dom/html/HTMLIFrameElement.h @@ -57,6 +57,7 @@ public: bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) override; virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, bool aNotify) override; diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp index 808882addf12..bf0d4f1e0fa6 100644 --- a/dom/html/HTMLImageElement.cpp +++ b/dom/html/HTMLImageElement.cpp @@ -396,7 +396,8 @@ HTMLImageElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsresult HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None && mForm && (aName == nsGkAtoms::name || aName == nsGkAtoms::id) && @@ -450,7 +451,7 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, - aValue, aNotify); + aValue, aOldValue, aNotify); } nsresult diff --git a/dom/html/HTMLImageElement.h b/dom/html/HTMLImageElement.h index 379d07663ce4..5a34646745df 100644 --- a/dom/html/HTMLImageElement.h +++ b/dom/html/HTMLImageElement.h @@ -349,7 +349,9 @@ protected: bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) override; + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + bool aNotify) override; // Override for nsImageLoadingContent. nsIContent* AsContent() override { return this; } diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index 970cf8bdd64c..aaa2d7b673d9 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -1398,7 +1398,8 @@ HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsresult HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None) { // @@ -1521,7 +1522,8 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } return nsGenericHTMLFormElementWithState::AfterSetAttr(aNameSpaceID, aName, - aValue, aNotify); + aValue, aOldValue, + aNotify); } void diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index 86d7542e3ce8..2efda3208ddc 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -975,7 +975,9 @@ protected: * Called when an attribute has just been changed */ virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) override; + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + bool aNotify) override; virtual void BeforeSetForm(bool aBindToTree) override; diff --git a/dom/html/HTMLLinkElement.cpp b/dom/html/HTMLLinkElement.cpp index 611f5c90c778..788ded15ec47 100644 --- a/dom/html/HTMLLinkElement.cpp +++ b/dom/html/HTMLLinkElement.cpp @@ -346,7 +346,8 @@ HTMLLinkElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsresult HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { // It's safe to call ResetLinkState here because our new attr value has // already been set or unset. ResetLinkState needs the updated attribute @@ -415,7 +416,7 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, - aNotify); + aOldValue, aNotify); } nsresult diff --git a/dom/html/HTMLLinkElement.h b/dom/html/HTMLLinkElement.h index a779ce156257..6ff2fff89a09 100644 --- a/dom/html/HTMLLinkElement.h +++ b/dom/html/HTMLLinkElement.h @@ -67,6 +67,7 @@ public: bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) override; virtual bool IsLink(nsIURI** aURI) const override; virtual already_AddRefed GetHrefURI() const override; diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 4636fafa944c..5a0cce5a55ac 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -4235,7 +4235,8 @@ nsresult HTMLMediaElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr, nsresult HTMLMediaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) { mSrcMediaSource = nullptr; @@ -4257,7 +4258,7 @@ HTMLMediaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, - aValue, aNotify); + aValue, aOldValue, aNotify); } nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, @@ -4612,7 +4613,6 @@ nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel, nsIStreamListener** aListener) { NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set"); - NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder"); nsAutoCString mimeType; @@ -5280,10 +5280,6 @@ void HTMLMediaElement::DecodeError(const MediaResult& aError) AudioTracks()->EmptyTracks(); VideoTracks()->EmptyTracks(); if (mIsLoadingFromSourceChildren) { - if (mDecoder) { - // Shut down the exiting decoder before loading the next source child. - ShutdownDecoder(); - } mErrorSink->ResetError(); if (mSourceLoadCandidate) { DispatchAsyncSourceError(mSourceLoadCandidate); diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index e023d86543f8..70de2c0c6960 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -140,6 +140,7 @@ public: bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) override; virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, diff --git a/dom/html/HTMLMenuElement.cpp b/dom/html/HTMLMenuElement.cpp index 8e47505c8729..7944e6a9c42c 100644 --- a/dom/html/HTMLMenuElement.cpp +++ b/dom/html/HTMLMenuElement.cpp @@ -115,7 +115,8 @@ HTMLMenuElement::Build(nsIMenuBuilder* aBuilder) nsresult HTMLMenuElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::type) { if (aValue) { @@ -126,7 +127,7 @@ HTMLMenuElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, - aNotify); + aOldValue, aNotify); } bool diff --git a/dom/html/HTMLMenuElement.h b/dom/html/HTMLMenuElement.h index a7d13f8a9424..df44db74a4db 100644 --- a/dom/html/HTMLMenuElement.h +++ b/dom/html/HTMLMenuElement.h @@ -30,8 +30,10 @@ public: // nsIDOMHTMLMenuElement NS_DECL_NSIDOMHTMLMENUELEMENT - nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) override; + virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + bool aNotify) override; virtual bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, diff --git a/dom/html/HTMLMenuItemElement.cpp b/dom/html/HTMLMenuItemElement.cpp index c6d976bad00e..e29f551fb184 100644 --- a/dom/html/HTMLMenuItemElement.cpp +++ b/dom/html/HTMLMenuItemElement.cpp @@ -374,7 +374,8 @@ HTMLMenuItemElement::GetText(nsAString& aText) nsresult HTMLMenuItemElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None) { // Handle type changes first, since some of the later conditions in this @@ -408,7 +409,7 @@ HTMLMenuItemElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, - aNotify); + aOldValue, aNotify); } void diff --git a/dom/html/HTMLMenuItemElement.h b/dom/html/HTMLMenuItemElement.h index 92130749868b..2f40369f368b 100644 --- a/dom/html/HTMLMenuItemElement.h +++ b/dom/html/HTMLMenuItemElement.h @@ -126,7 +126,9 @@ protected: protected: virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) override; + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + bool aNotify) override; void WalkRadioGroup(Visitor* aVisitor); diff --git a/dom/html/HTMLMetaElement.cpp b/dom/html/HTMLMetaElement.cpp index 47effa2bc5fa..833c3177a763 100644 --- a/dom/html/HTMLMetaElement.cpp +++ b/dom/html/HTMLMetaElement.cpp @@ -60,7 +60,8 @@ HTMLMetaElement::SetMetaReferrer(nsIDocument* aDocument) nsresult HTMLMetaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None) { nsIDocument *document = GetUncomposedDoc(); @@ -82,7 +83,7 @@ HTMLMetaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, - aNotify); + aOldValue, aNotify); } nsresult diff --git a/dom/html/HTMLMetaElement.h b/dom/html/HTMLMetaElement.h index 0c92ad16ad09..d2edacfa850e 100644 --- a/dom/html/HTMLMetaElement.h +++ b/dom/html/HTMLMetaElement.h @@ -33,7 +33,9 @@ public: bool aNullParent = true) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) override; + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, + bool aNotify) override; void CreateAndDispatchEvent(nsIDocument* aDoc, const nsAString& aEventName); diff --git a/dom/html/HTMLOptGroupElement.cpp b/dom/html/HTMLOptGroupElement.cpp index 73f51acf9730..7467c5da38b0 100644 --- a/dom/html/HTMLOptGroupElement.cpp +++ b/dom/html/HTMLOptGroupElement.cpp @@ -102,7 +102,8 @@ HTMLOptGroupElement::RemoveChildAt(uint32_t aIndex, bool aNotify) nsresult HTMLOptGroupElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValue* aValue, bool aNotify) + const nsAttrValue* aValue, + const nsAttrValue* aOldValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled) { // All our children