diff --git a/browser/components/customizableui/src/CustomizableWidgets.jsm b/browser/components/customizableui/src/CustomizableWidgets.jsm index 66bf543e105..5f4391e4163 100644 --- a/browser/components/customizableui/src/CustomizableWidgets.jsm +++ b/browser/components/customizableui/src/CustomizableWidgets.jsm @@ -291,7 +291,9 @@ const CustomizableWidgets = [{ defaultArea: CustomizableUI.AREA_PANEL, onBuild: function(aDocument) { const kPanelId = "PanelUI-popup"; - let inPanel = (this.currentArea == CustomizableUI.AREA_PANEL); + let areaType = CustomizableUI.getAreaType(this.currentArea); + let inPanel = areaType == CustomizableUI.TYPE_MENU_PANEL; + let inToolbar = areaType == CustomizableUI.TYPE_TOOLBAR; let noautoclose = inPanel ? "true" : null; let cls = inPanel ? "panel-combined-button" : "toolbarbutton-1"; @@ -358,10 +360,14 @@ const CustomizableWidgets = [{ Services.obs.addObserver(updateZoomResetButton, "browser-fullZoom:zoomChange", false); Services.obs.addObserver(updateZoomResetButton, "browser-fullZoom:zoomReset", false); - if (inPanel && this.currentArea) { + if (inPanel) { let panel = aDocument.getElementById(kPanelId); panel.addEventListener("popupshowing", updateZoomResetButton); } else { + if (inToolbar) { + let container = window.gBrowser.tabContainer; + container.addEventListener("TabSelect", updateZoomResetButton); + } updateZoomResetButton(); } @@ -373,9 +379,13 @@ const CustomizableWidgets = [{ updateCombinedWidgetStyle(node, aArea, true); updateZoomResetButton(); - if (aArea == CustomizableUI.AREA_PANEL) { + let areaType = CustomizableUI.getAreaType(aArea); + if (areaType == CustomizableUI.TYPE_MENU_PANEL) { let panel = aDocument.getElementById(kPanelId); panel.addEventListener("popupshowing", updateZoomResetButton); + } else if (areaType == CustomizableUI.TYPE_TOOLBAR) { + let container = window.gBrowser.tabContainer; + container.addEventListener("TabSelect", updateZoomResetButton); } }.bind(this), @@ -383,9 +393,13 @@ const CustomizableWidgets = [{ if (aWidgetId != this.id) return; - if (aPrevArea == CustomizableUI.AREA_PANEL) { + let areaType = CustomizableUI.getAreaType(aPrevArea); + if (areaType == CustomizableUI.TYPE_MENU_PANEL) { let panel = aDocument.getElementById(kPanelId); panel.removeEventListener("popupshowing", updateZoomResetButton); + } else if (areaType == CustomizableUI.TYPE_TOOLBAR) { + let container = window.gBrowser.tabContainer; + container.removeEventListener("TabSelect", updateZoomResetButton); } // When a widget is demoted to the palette ('removed'), it's visual @@ -417,6 +431,8 @@ const CustomizableWidgets = [{ Services.obs.removeObserver(updateZoomResetButton, "browser-fullZoom:zoomReset"); let panel = aDoc.getElementById(kPanelId); panel.removeEventListener("popupshowing", updateZoomResetButton); + let container = aDoc.defaultView.gBrowser.tabContainer; + container.removeEventListener("TabSelect", updateZoomResetButton); }.bind(this), onWidgetDrag: function(aWidgetId, aArea) { diff --git a/browser/components/customizableui/test/browser.ini b/browser/components/customizableui/test/browser.ini index 3278e5b7937..87612bd56a6 100644 --- a/browser/components/customizableui/test/browser.ini +++ b/browser/components/customizableui/test/browser.ini @@ -38,6 +38,7 @@ skip-if = true # Because this test is about the menubar, it can't be run on mac skip-if = os == "mac" +[browser_934951_zoom_in_toolbar.js] [browser_938980_navbar_collapsed.js] [browser_938995_indefaultstate_nonremovable.js] [browser_940013_registerToolbarNode_calls_registerArea.js] diff --git a/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js b/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js new file mode 100644 index 00000000000..d4b9e0d317c --- /dev/null +++ b/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js @@ -0,0 +1,68 @@ +/* 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 kTimeoutInMS = 20000; + +// Bug 934951 - Zoom controls percentage label doesn't update when it's in the toolbar and you navigate. +add_task(function() { + CustomizableUI.addWidgetToArea("zoom-controls", CustomizableUI.AREA_NAVBAR); + let tab1 = gBrowser.addTab("about:mozilla"); + let tab2 = gBrowser.addTab("about:newtab"); + gBrowser.selectedTab = tab1; + let zoomResetButton = document.getElementById("zoom-reset-button"); + + is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:mozilla"); + let zoomChangePromise = promiseObserverNotification("browser-fullZoom:zoomChange"); + FullZoom.enlarge(); + yield zoomChangePromise; + is(parseInt(zoomResetButton.label, 10), 110, "Zoom is changed to 110% for about:mozilla"); + + let tabSelectPromise = promiseTabSelect(); + gBrowser.selectedTab = tab2; + yield tabSelectPromise; + is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:newtab"); + + gBrowser.selectedTab = tab1; + let zoomResetPromise = promiseObserverNotification("browser-fullZoom:zoomReset"); + FullZoom.reset(); + yield zoomResetPromise; + is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:mozilla"); + + CustomizableUI.reset(); + gBrowser.removeTab(tab2); + gBrowser.removeTab(tab1); +}); + +function promiseObserverNotification(aObserver) { + let deferred = Promise.defer(); + function notificationCallback(e) { + Services.obs.removeObserver(notificationCallback, aObserver, false); + clearTimeout(timeoutId); + deferred.resolve(); + }; + let timeoutId = setTimeout(() => { + Services.obs.removeObserver(notificationCallback, aObserver, false); + deferred.reject("Notification '" + aObserver + "' did not happen within 20 seconds."); + }, kTimeoutInMS); + Services.obs.addObserver(notificationCallback, aObserver, false); + return deferred.promise; +} + +function promiseTabSelect() { + let deferred = Promise.defer(); + let container = window.gBrowser.tabContainer; + let timeoutId = setTimeout(() => { + container.removeEventListener("TabSelect", callback); + deferred.reject("TabSelect did not happen within 20 seconds"); + }, kTimeoutInMS); + function callback(e) { + container.removeEventListener("TabSelect", callback); + clearTimeout(timeoutId); + executeSoon(deferred.resolve); + }; + container.addEventListener("TabSelect", callback); + return deferred.promise; +} diff --git a/browser/modules/BrowserUITelemetry.jsm b/browser/modules/BrowserUITelemetry.jsm index 5bfae91f630..17f07dd8ccb 100644 --- a/browser/modules/BrowserUITelemetry.jsm +++ b/browser/modules/BrowserUITelemetry.jsm @@ -130,12 +130,18 @@ this.BrowserUITelemetry = { init: function() { UITelemetry.addSimpleMeasureFunction("toolbars", this.getToolbarMeasures.bind(this)); + Services.obs.addObserver(this, "sessionstore-windows-restored", false); Services.obs.addObserver(this, "browser-delayed-startup-finished", false); }, observe: function(aSubject, aTopic, aData) { - if (aTopic == "browser-delayed-startup-finished") { - this._registerWindow(aSubject); + switch(aTopic) { + case "sessionstore-windows-restored": + this._gatherFirstWindowMeasurements(); + break; + case "browser-delayed-startup-finished": + this._registerWindow(aSubject); + break; } }, @@ -200,16 +206,23 @@ this.BrowserUITelemetry = { }, _firstWindowMeasurements: null, - _registerWindow: function(aWindow) { - // We'll gather measurements on the first non-popup window that opens - // after it has painted. We do this here instead of waiting for - // UITelemetry to ask for our measurements because at that point - // all browser windows have probably been closed, since the vast - // majority of saved-session pings are gathered during shutdown. - if (!this._firstWindowMeasurements && aWindow.toolbar.visible) { - this._firstWindowMeasurements = this._getWindowMeasurements(aWindow); - } + _gatherFirstWindowMeasurements: function() { + // We'll gather measurements as soon as the session has restored. + // We do this here instead of waiting for UITelemetry to ask for + // our measurements because at that point all browser windows have + // probably been closed, since the vast majority of saved-session + // pings are gathered during shutdown. + let win = RecentWindow.getMostRecentBrowserWindow({ + private: false, + allowPopups: false, + }); + // If there are no such windows, we're out of luck. :( + this._firstWindowMeasurements = win ? this._getWindowMeasurements(win) + : {}; + }, + + _registerWindow: function(aWindow) { aWindow.addEventListener("unload", this); let document = aWindow.document; @@ -419,4 +432,4 @@ function getIDBasedOnFirstIDedAncestor(aNode) { } return aNode.id; -} \ No newline at end of file +} diff --git a/browser/themes/shared/browser.inc b/browser/themes/shared/browser.inc index ecb77a83db8..d705e52a9bb 100644 --- a/browser/themes/shared/browser.inc +++ b/browser/themes/shared/browser.inc @@ -1,4 +1,4 @@ %filter substitution -%define primaryToolbarButtons #back-button, #forward-button, #home-button, #print-button, #downloads-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-reset-button, #zoom-in-button, #sync-button, #feed-button, #tabview-button, #webrtc-status-button, #social-share-button, #open-file-button, #find-button, #developer-button, #preferences-button, #privatebrowsing-button, #save-page-button, #switch-to-metro-button, #add-ons-button, #history-panelmenu, #nav-bar-overflow-button, #PanelUI-menu-button, #characterencoding-button, #email-link-button +%define primaryToolbarButtons #back-button, #forward-button, #home-button, #print-button, #downloads-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-reset-button, #zoom-in-button, #sync-button, #feed-button, #webrtc-status-button, #social-share-button, #open-file-button, #find-button, #developer-button, #preferences-button, #privatebrowsing-button, #save-page-button, #switch-to-metro-button, #add-ons-button, #history-panelmenu, #nav-bar-overflow-button, #PanelUI-menu-button, #characterencoding-button, #email-link-button %define inAnyPanel :-moz-any(:not([cui-areatype="toolbar"]),.overflowedItem) diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 4f8ec6ec8c4..799793bacb6 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -258,29 +258,32 @@ static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID); static PLDHashTable sEventListenerManagersHash; -class DOMEventListenerManagersHashReporter MOZ_FINAL : public MemoryUniReporter +class DOMEventListenerManagersHashReporter MOZ_FINAL : public nsIMemoryReporter { -public: - DOMEventListenerManagersHashReporter() - : MemoryUniReporter( - "explicit/dom/event-listener-managers-hash", - KIND_HEAP, - UNITS_BYTES, - "Memory used by the event listener manager's hash table.") - {} + MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf) -private: - int64_t Amount() +public: + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) { // We don't measure the |nsEventListenerManager| objects pointed to by the // entries because those references are non-owning. - return sEventListenerManagersHash.ops - ? PL_DHashTableSizeOfExcludingThis(&sEventListenerManagersHash, - nullptr, MallocSizeOf) - : 0; + int64_t amount = sEventListenerManagersHash.ops + ? PL_DHashTableSizeOfExcludingThis( + &sEventListenerManagersHash, nullptr, MallocSizeOf) + : 0; + + return MOZ_COLLECT_REPORT( + "explicit/dom/event-listener-managers-hash", KIND_HEAP, UNITS_BYTES, + amount, + "Memory used by the event listener manager's hash table."); } }; +NS_IMPL_ISUPPORTS1(DOMEventListenerManagersHashReporter, nsIMemoryReporter) + class EventListenerManagerMapEntry : public PLDHashEntryHdr { public: diff --git a/content/base/src/nsDOMFile.cpp b/content/base/src/nsDOMFile.cpp index 01818e9c3ca..3985e9d98a3 100644 --- a/content/base/src/nsDOMFile.cpp +++ b/content/base/src/nsDOMFile.cpp @@ -688,9 +688,7 @@ public: nsPrintfCString( "explicit/dom/memory-file-data/large/file(length=%llu, sha1=%s)", owner->mLength, digestString.get()), - nsIMemoryReporter::KIND_HEAP, - nsIMemoryReporter::UNITS_BYTES, - size, + KIND_HEAP, UNITS_BYTES, size, nsPrintfCString( "Memory used to back a memory file of length %llu bytes. The file " "has a sha1 of %s.\n\n" @@ -707,9 +705,7 @@ public: nsresult rv = aCallback->Callback( /* process */ NS_LITERAL_CSTRING(""), NS_LITERAL_CSTRING("explicit/dom/memory-file-data/small"), - nsIMemoryReporter::KIND_HEAP, - nsIMemoryReporter::UNITS_BYTES, - smallObjectsTotal, + KIND_HEAP, UNITS_BYTES, smallObjectsTotal, nsPrintfCString( "Memory used to back small memory files (less than %d bytes each).\n\n" "Note that the allocator may round up a memory file's length -- " diff --git a/content/base/src/nsHostObjectProtocolHandler.cpp b/content/base/src/nsHostObjectProtocolHandler.cpp index 1beee3b14a2..39f12b06187 100644 --- a/content/base/src/nsHostObjectProtocolHandler.cpp +++ b/content/base/src/nsHostObjectProtocolHandler.cpp @@ -29,22 +29,24 @@ static nsClassHashtable* gDataTable; // Memory reporting for the hash table. namespace mozilla { -class HostObjectURLsReporter MOZ_FINAL : public MemoryUniReporter +class HostObjectURLsReporter MOZ_FINAL : public nsIMemoryReporter { public: - HostObjectURLsReporter() - : MemoryUniReporter("host-object-urls", - KIND_OTHER, UNITS_COUNT, - "The number of host objects stored for access via URLs " - "(e.g. blobs passed to URL.createObjectURL).") - {} - private: - int64_t Amount() MOZ_OVERRIDE + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) { - return gDataTable ? gDataTable->Count() : 0; + return MOZ_COLLECT_REPORT( + "host-object-urls", KIND_OTHER, UNITS_COUNT, + gDataTable ? gDataTable->Count() : 0, + "The number of host objects stored for access via URLs " + "(e.g. blobs passed to URL.createObjectURL)."); } }; +NS_IMPL_ISUPPORTS1(HostObjectURLsReporter, nsIMemoryReporter) + } nsHostObjectProtocolHandler::nsHostObjectProtocolHandler() diff --git a/content/canvas/src/CanvasRenderingContext2D.cpp b/content/canvas/src/CanvasRenderingContext2D.cpp index 66be67f3b5d..ed56d6d2e98 100644 --- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -136,17 +136,24 @@ static int64_t gCanvasAzureMemoryUsed = 0; // This is KIND_OTHER because it's not always clear where in memory the pixels // of a canvas are stored. Furthermore, this memory will be tracked by the // underlying surface implementations. See bug 655638 for details. -class Canvas2dPixelsReporter MOZ_FINAL : public MemoryUniReporter +class Canvas2dPixelsReporter MOZ_FINAL : public nsIMemoryReporter { - public: - Canvas2dPixelsReporter() - : MemoryUniReporter("canvas-2d-pixels", KIND_OTHER, UNITS_BYTES, -"Memory used by 2D canvases. Each canvas requires (width * height * 4) bytes.") - {} -private: - int64_t Amount() MOZ_OVERRIDE { return gCanvasAzureMemoryUsed; } +public: + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) + { + return MOZ_COLLECT_REPORT( + "canvas-2d-pixels", KIND_OTHER, UNITS_BYTES, + gCanvasAzureMemoryUsed, + "Memory used by 2D canvases. Each canvas requires " + "(width * height * 4) bytes."); + } }; +NS_IMPL_ISUPPORTS1(Canvas2dPixelsReporter, nsIMemoryReporter) + class CanvasRadialGradient : public CanvasGradient { public: @@ -583,7 +590,7 @@ CanvasRenderingContext2D::ParseColor(const nsAString& aString, return false; } - if (value.GetUnit() == eCSSUnit_Color) { + if (value.IsNumericColorUnit()) { // if we already have a color we can just use it directly *aColor = value.GetColorValue(); } else { diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index 00d886eeba4..6a01287b7b5 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -116,17 +116,14 @@ GlobalNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, return true; } -NS_IMPL_ISUPPORTS_INHERITED2( +NS_IMPL_ISUPPORTS3( nsScriptNameSpaceManager, - MemoryUniReporter, nsIObserver, - nsISupportsWeakReference) + nsISupportsWeakReference, + nsIMemoryReporter) nsScriptNameSpaceManager::nsScriptNameSpaceManager() - : MemoryUniReporter("explicit/script-namespace-manager", - KIND_HEAP, UNITS_BYTES, - "Memory used for the script namespace manager.") - , mIsInitialized(false) + : mIsInitialized(false) { MOZ_COUNT_CTOR(nsScriptNameSpaceManager); } @@ -863,14 +860,20 @@ static size_t SizeOfEntryExcludingThis(PLDHashEntryHdr *aHdr, MallocSizeOf aMallocSizeOf, void *aArg) { - GlobalNameMapEntry* entry = static_cast(aHdr); - return entry->SizeOfExcludingThis(aMallocSizeOf); + GlobalNameMapEntry* entry = static_cast(aHdr); + return entry->SizeOfExcludingThis(aMallocSizeOf); } -int64_t -nsScriptNameSpaceManager::Amount() +MOZ_DEFINE_MALLOC_SIZE_OF(ScriptNameSpaceManagerMallocSizeOf) + +NS_IMETHODIMP +nsScriptNameSpaceManager::CollectReports( + nsIHandleReportCallback* aHandleReport, nsISupports* aData) { - return SizeOfIncludingThis(MallocSizeOf); + return MOZ_COLLECT_REPORT( + "explicit/script-namespace-manager", KIND_HEAP, UNITS_BYTES, + SizeOfIncludingThis(ScriptNameSpaceManagerMallocSizeOf), + "Memory used for the script namespace manager."); } size_t diff --git a/dom/base/nsScriptNameSpaceManager.h b/dom/base/nsScriptNameSpaceManager.h index 82d2e960d80..8517a3eb84a 100644 --- a/dom/base/nsScriptNameSpaceManager.h +++ b/dom/base/nsScriptNameSpaceManager.h @@ -88,13 +88,14 @@ class nsICategoryManager; class GlobalNameMapEntry; -class nsScriptNameSpaceManager : public mozilla::MemoryUniReporter, - public nsIObserver, - public nsSupportsWeakReference +class nsScriptNameSpaceManager : public nsIObserver, + public nsSupportsWeakReference, + public nsIMemoryReporter { public: NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER + NS_DECL_NSIMEMORYREPORTER nsScriptNameSpaceManager(); virtual ~nsScriptNameSpaceManager(); @@ -163,7 +164,6 @@ public: void EnumerateNavigatorNames(NameEnumerator aEnumerator, void* aClosure); - int64_t Amount() MOZ_OVERRIDE; size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); private: diff --git a/dom/base/nsWindowMemoryReporter.cpp b/dom/base/nsWindowMemoryReporter.cpp index aec88a836e9..e376eec61f1 100644 --- a/dom/base/nsWindowMemoryReporter.cpp +++ b/dom/base/nsWindowMemoryReporter.cpp @@ -500,8 +500,7 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb, do { \ nsresult rv; \ rv = aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \ - nsIMemoryReporter::KIND_OTHER, \ - nsIMemoryReporter::UNITS_BYTES, _amount, \ + KIND_OTHER, UNITS_BYTES, _amount, \ NS_LITERAL_CSTRING(_desc), aClosure); \ NS_ENSURE_SUCCESS(rv, rv); \ } while (0) @@ -801,6 +800,9 @@ nsWindowMemoryReporter::CheckForGhostWindows( &ghostEnumData); } +NS_IMPL_ISUPPORTS1(nsWindowMemoryReporter::GhostWindowsReporter, + nsIMemoryReporter) + /* static */ int64_t nsWindowMemoryReporter::GhostWindowsReporter::DistinguishedAmount() { diff --git a/dom/base/nsWindowMemoryReporter.h b/dom/base/nsWindowMemoryReporter.h index 1691a21402b..d63d11abbc6 100644 --- a/dom/base/nsWindowMemoryReporter.h +++ b/dom/base/nsWindowMemoryReporter.h @@ -151,11 +151,18 @@ private: * nsGhostWindowReporter generates the "ghost-windows" report, which counts * the number of ghost windows present. */ - class GhostWindowsReporter MOZ_FINAL : public mozilla::MemoryUniReporter + class GhostWindowsReporter MOZ_FINAL : public nsIMemoryReporter { public: - GhostWindowsReporter() - : MemoryUniReporter("ghost-windows", KIND_OTHER, UNITS_COUNT, + NS_DECL_ISUPPORTS + + static int64_t DistinguishedAmount(); + + NS_IMETHOD + CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData) + { + return MOZ_COLLECT_REPORT( + "ghost-windows", KIND_OTHER, UNITS_COUNT, DistinguishedAmount(), "The number of ghost windows present (the number of nodes underneath " "explicit/window-objects/top(none)/ghost, modulo race conditions). A ghost " "window is not shown in any tab, does not share a domain with any non-detached " @@ -163,13 +170,8 @@ private: "memory.ghost_window_timeout_seconds, or has survived a round of " "about:memory's minimize memory usage button.\n\n" "Ghost windows can happen legitimately, but they are often indicative of " -"leaks in the browser or add-ons.") - {} - - static int64_t DistinguishedAmount(); - - private: - int64_t Amount() MOZ_OVERRIDE { return DistinguishedAmount(); } +"leaks in the browser or add-ons."); + } }; // Protect ctor, use Init() instead. diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 69fb35423e9..0a6336614a4 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -246,8 +246,8 @@ ContentParentsMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb, nsresult rv = cb->Callback(/* process */ EmptyCString(), path, - nsIMemoryReporter::KIND_OTHER, - nsIMemoryReporter::UNITS_COUNT, + KIND_OTHER, + UNITS_COUNT, numQueuedMessages, desc, aClosure); diff --git a/dom/webidl/CSSStyleDeclaration.webidl b/dom/webidl/CSSStyleDeclaration.webidl index 58477233d99..594f575bb41 100644 --- a/dom/webidl/CSSStyleDeclaration.webidl +++ b/dom/webidl/CSSStyleDeclaration.webidl @@ -29,3 +29,9 @@ interface CSSStyleDeclaration { readonly attribute CSSRule? parentRule; }; + +// Mozilla extensions +partial interface CSSStyleDeclaration { + [ChromeOnly,Throws] + DOMString getAuthoredPropertyValue(DOMString property); +}; diff --git a/extensions/spellcheck/hunspell/src/mozHunspell.cpp b/extensions/spellcheck/hunspell/src/mozHunspell.cpp index 14c6d5e8cdc..be5085979ec 100644 --- a/extensions/spellcheck/hunspell/src/mozHunspell.cpp +++ b/extensions/spellcheck/hunspell/src/mozHunspell.cpp @@ -83,10 +83,10 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(mozHunspell) NS_IMPL_CYCLE_COLLECTING_RELEASE(mozHunspell) NS_INTERFACE_MAP_BEGIN(mozHunspell) - NS_INTERFACE_MAP_ENTRY(nsIMemoryReporter) NS_INTERFACE_MAP_ENTRY(mozISpellCheckingEngine) NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY(nsIMemoryReporter) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellCheckingEngine) NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozHunspell) NS_INTERFACE_MAP_END @@ -107,9 +107,7 @@ void HunspellReportMemoryDeallocation(void* ptr) { } mozHunspell::mozHunspell() - : MemoryUniReporter("explicit/spell-check", KIND_HEAP, UNITS_BYTES, -"Memory used by the spell-checking engine's internal data structures."), - mHunspell(nullptr) + : mHunspell(nullptr) { #ifdef DEBUG // There must be only one instance of this class, due to |sAmount| @@ -131,14 +129,14 @@ mozHunspell::Init() obs->AddObserver(this, "profile-after-change", true); } - RegisterWeakMemoryReporter(this); + mozilla::RegisterWeakMemoryReporter(this); return NS_OK; } mozHunspell::~mozHunspell() { - UnregisterWeakMemoryReporter(this); + mozilla::UnregisterWeakMemoryReporter(this); mPersonalDictionary = nullptr; delete mHunspell; diff --git a/extensions/spellcheck/hunspell/src/mozHunspell.h b/extensions/spellcheck/hunspell/src/mozHunspell.h index 029d733a639..5fc7808accf 100644 --- a/extensions/spellcheck/hunspell/src/mozHunspell.h +++ b/extensions/spellcheck/hunspell/src/mozHunspell.h @@ -80,10 +80,10 @@ { 0x56c778e4, 0x1bee, 0x45f3, \ { 0xa6, 0x89, 0x88, 0x66, 0x92, 0xa9, 0x7f, 0xe7 } } -class mozHunspell : public mozilla::MemoryUniReporter, - public mozISpellCheckingEngine, +class mozHunspell : public mozISpellCheckingEngine, public nsIObserver, - public nsSupportsWeakReference + public nsSupportsWeakReference, + public nsIMemoryReporter { public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS @@ -101,10 +101,19 @@ public: // helper method for converting a word to the charset of the dictionary nsresult ConvertCharset(const PRUnichar* aStr, char ** aDst); + MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc) + MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree) + static void OnAlloc(void* ptr) { sAmount += MallocSizeOfOnAlloc(ptr); } static void OnFree (void* ptr) { sAmount -= MallocSizeOfOnFree (ptr); } - int64_t Amount() MOZ_OVERRIDE { return sAmount; } + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) + { + return MOZ_COLLECT_REPORT( + "explicit/spell-check", KIND_HEAP, UNITS_BYTES, sAmount, + "Memory used by the spell-checking engine."); + } protected: diff --git a/gfx/gl/GfxTexturesReporter.cpp b/gfx/gl/GfxTexturesReporter.cpp index de9ce51c6f2..6da12bc3e66 100644 --- a/gfx/gl/GfxTexturesReporter.cpp +++ b/gfx/gl/GfxTexturesReporter.cpp @@ -10,6 +10,8 @@ using namespace mozilla; using namespace mozilla::gl; +NS_IMPL_ISUPPORTS1(GfxTexturesReporter, nsIMemoryReporter) + int64_t GfxTexturesReporter::sAmount = 0; static uint32_t GetBitsPerTexel(GLenum format, GLenum type) diff --git a/gfx/gl/GfxTexturesReporter.h b/gfx/gl/GfxTexturesReporter.h index 9ba04f02702..5df5c695c56 100644 --- a/gfx/gl/GfxTexturesReporter.h +++ b/gfx/gl/GfxTexturesReporter.h @@ -13,12 +13,12 @@ namespace mozilla { namespace gl { -class GfxTexturesReporter MOZ_FINAL : public MemoryUniReporter +class GfxTexturesReporter MOZ_FINAL : public nsIMemoryReporter { public: + NS_DECL_ISUPPORTS + GfxTexturesReporter() - : MemoryUniReporter("gfx-textures", KIND_OTHER, UNITS_BYTES, - "Memory used for storing GL textures.") { #ifdef DEBUG // There must be only one instance of this class, due to |sAmount| @@ -41,9 +41,15 @@ public: static void UpdateAmount(MemoryUse action, GLenum format, GLenum type, uint16_t tileSize); -private: - int64_t Amount() MOZ_OVERRIDE { return sAmount; } + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) + { + return MOZ_COLLECT_REPORT( + "gfx-textures", KIND_OTHER, UNITS_BYTES, sAmount, + "Memory used for storing GL textures."); + } +private: static int64_t sAmount; }; diff --git a/gfx/layers/ipc/ISurfaceAllocator.cpp b/gfx/layers/ipc/ISurfaceAllocator.cpp index 116b088e58f..bbe63edba7c 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.cpp +++ b/gfx/layers/ipc/ISurfaceAllocator.cpp @@ -28,6 +28,8 @@ using namespace mozilla::ipc; namespace mozilla { namespace layers { +NS_IMPL_ISUPPORTS1(GfxMemoryImageReporter, nsIMemoryReporter) + mozilla::Atomic GfxMemoryImageReporter::sAmount(0); mozilla::ipc::SharedMemory::SharedMemoryType OptimalShmemType() diff --git a/gfx/layers/ipc/ISurfaceAllocator.h b/gfx/layers/ipc/ISurfaceAllocator.h index 2a077d7d9c3..6c9f5b2e013 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.h +++ b/gfx/layers/ipc/ISurfaceAllocator.h @@ -12,7 +12,7 @@ #include "mozilla/gfx/Point.h" // for IntSize #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc #include "mozilla/RefPtr.h" -#include "nsIMemoryReporter.h" // for MemoryUniReporter +#include "nsIMemoryReporter.h" // for nsIMemoryReporter #include "mozilla/Atomics.h" // for Atomic /* @@ -145,12 +145,12 @@ protected: friend class detail::RefCounted; }; -class GfxMemoryImageReporter MOZ_FINAL : public mozilla::MemoryUniReporter +class GfxMemoryImageReporter MOZ_FINAL : public nsIMemoryReporter { public: + NS_DECL_ISUPPORTS + GfxMemoryImageReporter() - : MemoryUniReporter("explicit/gfx/heap-textures", KIND_HEAP, UNITS_BYTES, - "Heap memory shared between threads by texture clients and hosts.") { #ifdef DEBUG // There must be only one instance of this class, due to |sAmount| @@ -161,6 +161,9 @@ public: #endif } + MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc) + MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree) + static void DidAlloc(void* aPointer) { sAmount += MallocSizeOfOnAlloc(aPointer); @@ -171,9 +174,15 @@ public: sAmount -= MallocSizeOfOnFree(aPointer); } -private: - int64_t Amount() MOZ_OVERRIDE { return sAmount; } + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) + { + return MOZ_COLLECT_REPORT( + "explicit/gfx/heap-textures", KIND_HEAP, UNITS_BYTES, sAmount, + "Heap memory shared between threads by texture clients and hosts."); + } +private: static mozilla::Atomic sAmount; }; diff --git a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp index 04e6cfd47a2..09565a1f9f2 100644 --- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp +++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp @@ -189,18 +189,14 @@ ContentTypeFromPixelFormat(android::PixelFormat aFormat) return gfxASurface::ContentFromFormat(ImageFormatForPixelFormat(aFormat)); } -class GrallocReporter MOZ_FINAL : public MemoryUniReporter +class GrallocReporter MOZ_FINAL : public nsIMemoryReporter { friend class GrallocBufferActor; public: + NS_DECL_ISUPPORTS + GrallocReporter() - : MemoryUniReporter("gralloc", KIND_OTHER, UNITS_BYTES, -"Special RAM that can be shared between processes and directly accessed by " -"both the CPU and GPU. Gralloc memory is usually a relatively precious " -"resource, with much less available than generic RAM. When it's exhausted, " -"graphics performance can suffer. This value can be incorrect because of race " -"conditions.") { #ifdef DEBUG // There must be only one instance of this class, due to |sAmount| @@ -211,12 +207,24 @@ public: #endif } -private: - int64_t Amount() MOZ_OVERRIDE { return sAmount; } + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) + { + return MOZ_COLLECT_REPORT( + "gralloc", KIND_OTHER, UNITS_BYTES, sAmount, +"Special RAM that can be shared between processes and directly accessed by " +"both the CPU and GPU. Gralloc memory is usually a relatively precious " +"resource, with much less available than generic RAM. When it's exhausted, " +"graphics performance can suffer. This value can be incorrect because of race " +"conditions."); + } +private: static int64_t sAmount; }; +NS_IMPL_ISUPPORTS1(GrallocReporter, nsIMemoryReporter) + int64_t GrallocReporter::sAmount = 0; GrallocBufferActor::GrallocBufferActor() diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index e6a7fb5bb9d..92655c5afc5 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -31,12 +31,12 @@ using namespace mozilla::gfx; static FT_Library gPlatformFTLibrary = nullptr; -class FreetypeReporter MOZ_FINAL : public MemoryUniReporter +class FreetypeReporter MOZ_FINAL : public nsIMemoryReporter { public: + NS_DECL_ISUPPORTS + FreetypeReporter() - : MemoryUniReporter("explicit/freetype", KIND_HEAP, UNITS_BYTES, - "Memory used by Freetype.") { #ifdef DEBUG // There must be only one instance of this class, due to |sAmount| @@ -47,6 +47,9 @@ public: #endif } + MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc) + MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree) + static void* CountingAlloc(FT_Memory, long size) { void *p = malloc(size); @@ -74,12 +77,20 @@ public: return pnew; } -private: - int64_t Amount() MOZ_OVERRIDE { return sAmount; } + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) + { + return MOZ_COLLECT_REPORT( + "explicit/freetype", KIND_HEAP, UNITS_BYTES, sAmount, + "Memory used by Freetype."); + } +private: static int64_t sAmount; }; +NS_IMPL_ISUPPORTS1(FreetypeReporter, nsIMemoryReporter) + int64_t FreetypeReporter::sAmount = 0; static FT_MemoryRec_ sFreetypeMemoryRecord; diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 5a47ce506b8..22082ae8332 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -1376,15 +1376,13 @@ gfxFontCache::MemoryReporter::CollectReports aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING("explicit/gfx/font-cache"), - nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, - sizes.mFontInstances, + KIND_HEAP, UNITS_BYTES, sizes.mFontInstances, NS_LITERAL_CSTRING("Memory used for active font instances."), aClosure); aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING("explicit/gfx/font-shaped-words"), - nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, - sizes.mShapedWords, + KIND_HEAP, UNITS_BYTES, sizes.mShapedWords, NS_LITERAL_CSTRING("Memory used to cache shaped glyph data."), aClosure); diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 130cbe7af74..25ff9f942a6 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -77,20 +77,36 @@ static const int kSupportedFeatureLevels[] = { D3D10_FEATURE_LEVEL_10_1, D3D10_FEATURE_LEVEL_10_0, D3D10_FEATURE_LEVEL_9_3 }; -class GfxD2DSurfaceCacheReporter MOZ_FINAL : public MemoryUniReporter +class GfxD2DSurfaceReporter MOZ_FINAL : public nsIMemoryReporter { public: - GfxD2DSurfaceCacheReporter() - : MemoryUniReporter("gfx-d2d-surface-cache", KIND_OTHER, UNITS_BYTES, -"Memory used by the Direct2D internal surface cache.") - {} -private: - int64_t Amount() MOZ_OVERRIDE + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) { - return cairo_d2d_get_image_surface_cache_usage(); + nsresult rv; + + int64_t amount = cairo_d2d_get_image_surface_cache_usage(); + rv = MOZ_COLLECT_REPORT( + "gfx-d2d-surface-cache", KIND_OTHER, UNITS_BYTES, amount, + "Memory used by the Direct2D internal surface cache."); + NS_ENSURE_SUCCESS(rv, rv); + + cairo_device_t *device = + gfxWindowsPlatform::GetPlatform()->GetD2DDevice(); + amount = device ? cairo_d2d_get_surface_vram_usage(device) : 0; + rv = MOZ_COLLECT_REPORT( + "gfx-d2d-surface-vram", KIND_OTHER, UNITS_BYTES, amount, + "Video memory used by D2D surfaces."); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; } }; +NS_IMPL_ISUPPORTS1(GfxD2DSurfaceReporter, nsIMemoryReporter) + namespace { @@ -114,51 +130,35 @@ bool OncePreferenceDirect2DForceEnabled() } // anonymous namespace -class GfxD2DSurfaceVramReporter MOZ_FINAL : public MemoryUniReporter -{ -public: - GfxD2DSurfaceVramReporter() - : MemoryUniReporter("gfx-d2d-surface-vram", KIND_OTHER, UNITS_BYTES, - "Video memory used by D2D surfaces.") - {} -private: - int64_t Amount() MOZ_OVERRIDE { - cairo_device_t *device = - gfxWindowsPlatform::GetPlatform()->GetD2DDevice(); - return device ? cairo_d2d_get_surface_vram_usage(device) : 0; - } -}; - #endif -class GfxD2DVramDrawTargetReporter MOZ_FINAL : public MemoryUniReporter +class GfxD2DVramReporter MOZ_FINAL : public nsIMemoryReporter { public: - GfxD2DVramDrawTargetReporter() - : MemoryUniReporter("gfx-d2d-vram-draw-target", KIND_OTHER, UNITS_BYTES, - "Video memory used by D2D DrawTargets.") - {} -private: - int64_t Amount() MOZ_OVERRIDE + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) { - return Factory::GetD2DVRAMUsageDrawTarget(); + nsresult rv; + + rv = MOZ_COLLECT_REPORT( + "gfx-d2d-vram-draw-target", KIND_OTHER, UNITS_BYTES, + Factory::GetD2DVRAMUsageDrawTarget(), + "Video memory used by D2D DrawTargets."); + NS_ENSURE_SUCCESS(rv, rv); + + rv = MOZ_COLLECT_REPORT( + "gfx-d2d-vram-source-surface", KIND_OTHER, UNITS_BYTES, + Factory::GetD2DVRAMUsageSourceSurface(), + "Video memory used by D2D SourceSurfaces."); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; } }; -class GfxD2DVramSourceSurfaceReporter MOZ_FINAL : public MemoryUniReporter -{ -public: - GfxD2DVramSourceSurfaceReporter() - : MemoryUniReporter("gfx-d2d-vram-source-surface", - KIND_OTHER, UNITS_BYTES, - "Video memory used by D2D SourceSurfaces.") - {} -private: - int64_t Amount() MOZ_OVERRIDE - { - return Factory::GetD2DVRAMUsageSourceSurface(); - } -}; +NS_IMPL_ISUPPORTS1(GfxD2DVramReporter, nsIMemoryReporter) #define GFX_USE_CLEARTYPE_ALWAYS "gfx.font_rendering.cleartype.always_use_for_content" #define GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE "gfx.font_rendering.cleartype.use_for_downloadable_fonts" @@ -318,8 +318,7 @@ public: do { \ nsresult rv; \ rv = aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \ - nsIMemoryReporter::KIND_OTHER, \ - nsIMemoryReporter::UNITS_BYTES, _amount, \ + KIND_OTHER, UNITS_BYTES, _amount, \ NS_LITERAL_CSTRING(_desc), aClosure); \ NS_ENSURE_SUCCESS(rv, rv); \ } while (0) @@ -365,12 +364,10 @@ gfxWindowsPlatform::gfxWindowsPlatform() CoInitialize(nullptr); #ifdef CAIRO_HAS_D2D_SURFACE - RegisterStrongMemoryReporter(new GfxD2DSurfaceCacheReporter()); - RegisterStrongMemoryReporter(new GfxD2DSurfaceVramReporter()); + RegisterStrongMemoryReporter(new GfxD2DSurfaceReporter()); mD2DDevice = nullptr; #endif - RegisterStrongMemoryReporter(new GfxD2DVramDrawTargetReporter()); - RegisterStrongMemoryReporter(new GfxD2DVramSourceSurfaceReporter()); + RegisterStrongMemoryReporter(new GfxD2DVramReporter()); UpdateRenderMode(); diff --git a/image/src/SurfaceCache.cpp b/image/src/SurfaceCache.cpp index 9ca996fe0e2..91ce1a5bdd3 100644 --- a/image/src/SurfaceCache.cpp +++ b/image/src/SurfaceCache.cpp @@ -197,17 +197,14 @@ private: * maintains high-level invariants and encapsulates the details of the surface * cache's implementation. */ -class SurfaceCacheImpl : public MemoryUniReporter +class SurfaceCacheImpl : public nsIMemoryReporter { public: NS_DECL_ISUPPORTS SurfaceCacheImpl(uint32_t aSurfaceCacheExpirationTimeMS, uint32_t aSurfaceCacheSize) - : MemoryUniReporter("imagelib-surface-cache", - KIND_OTHER, UNITS_BYTES, - "Memory used by the imagelib temporary surface cache.") - , mExpirationTracker(MOZ_THIS_IN_INITIALIZER_LIST(), + : mExpirationTracker(MOZ_THIS_IN_INITIALIZER_LIST(), aSurfaceCacheExpirationTimeMS) , mMemoryPressureObserver(new MemoryPressureObserver) , mMaxCost(aSurfaceCacheSize) @@ -362,9 +359,13 @@ public: return PL_DHASH_NEXT; } - int64_t Amount() MOZ_OVERRIDE + NS_IMETHOD + CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData) { - return SizeOfSurfacesEstimate(); + return MOZ_COLLECT_REPORT( + "imagelib-surface-cache", KIND_OTHER, UNITS_BYTES, + SizeOfSurfacesEstimate(), + "Memory used by the imagelib temporary surface cache."); } // XXX(seth): This is currently only an estimate and, since we don't know @@ -427,7 +428,7 @@ private: Cost mAvailableCost; }; -NS_IMPL_ISUPPORTS_INHERITED0(SurfaceCacheImpl, MemoryUniReporter) +NS_IMPL_ISUPPORTS1(SurfaceCacheImpl, nsIMemoryReporter) NS_IMPL_ISUPPORTS1(SurfaceCacheImpl::MemoryPressureObserver, nsIObserver) /////////////////////////////////////////////////////////////////////////////// diff --git a/image/src/imgLoader.cpp b/image/src/imgLoader.cpp index afb3de240d4..3bf3e7de20a 100644 --- a/image/src/imgLoader.cpp +++ b/image/src/imgLoader.cpp @@ -70,57 +70,57 @@ public: do { \ nsresult rv; \ rv = callback->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \ - _kind, nsIMemoryReporter::UNITS_BYTES, _amount, \ + _kind, UNITS_BYTES, _amount, \ NS_LITERAL_CSTRING(_desc), closure); \ NS_ENSURE_SUCCESS(rv, rv); \ } while (0) REPORT("explicit/images/chrome/used/raw", - nsIMemoryReporter::KIND_HEAP, chrome.mUsedRaw, + KIND_HEAP, chrome.mUsedRaw, "Memory used by in-use chrome images (compressed data)."); REPORT("explicit/images/chrome/used/uncompressed-heap", - nsIMemoryReporter::KIND_HEAP, chrome.mUsedUncompressedHeap, + KIND_HEAP, chrome.mUsedUncompressedHeap, "Memory used by in-use chrome images (uncompressed data)."); REPORT("explicit/images/chrome/used/uncompressed-nonheap", - nsIMemoryReporter::KIND_NONHEAP, chrome.mUsedUncompressedNonheap, + KIND_NONHEAP, chrome.mUsedUncompressedNonheap, "Memory used by in-use chrome images (uncompressed data)."); REPORT("explicit/images/chrome/unused/raw", - nsIMemoryReporter::KIND_HEAP, chrome.mUnusedRaw, + KIND_HEAP, chrome.mUnusedRaw, "Memory used by not in-use chrome images (compressed data)."); REPORT("explicit/images/chrome/unused/uncompressed-heap", - nsIMemoryReporter::KIND_HEAP, chrome.mUnusedUncompressedHeap, + KIND_HEAP, chrome.mUnusedUncompressedHeap, "Memory used by not in-use chrome images (uncompressed data)."); REPORT("explicit/images/chrome/unused/uncompressed-nonheap", - nsIMemoryReporter::KIND_NONHEAP, chrome.mUnusedUncompressedNonheap, + KIND_NONHEAP, chrome.mUnusedUncompressedNonheap, "Memory used by not in-use chrome images (uncompressed data)."); REPORT("explicit/images/content/used/raw", - nsIMemoryReporter::KIND_HEAP, content.mUsedRaw, + KIND_HEAP, content.mUsedRaw, "Memory used by in-use content images (compressed data)."); REPORT("explicit/images/content/used/uncompressed-heap", - nsIMemoryReporter::KIND_HEAP, content.mUsedUncompressedHeap, + KIND_HEAP, content.mUsedUncompressedHeap, "Memory used by in-use content images (uncompressed data)."); REPORT("explicit/images/content/used/uncompressed-nonheap", - nsIMemoryReporter::KIND_NONHEAP, content.mUsedUncompressedNonheap, + KIND_NONHEAP, content.mUsedUncompressedNonheap, "Memory used by in-use content images (uncompressed data)."); REPORT("explicit/images/content/unused/raw", - nsIMemoryReporter::KIND_HEAP, content.mUnusedRaw, + KIND_HEAP, content.mUnusedRaw, "Memory used by not in-use content images (compressed data)."); REPORT("explicit/images/content/unused/uncompressed-heap", - nsIMemoryReporter::KIND_HEAP, content.mUnusedUncompressedHeap, + KIND_HEAP, content.mUnusedUncompressedHeap, "Memory used by not in-use content images (uncompressed data)."); REPORT("explicit/images/content/unused/uncompressed-nonheap", - nsIMemoryReporter::KIND_NONHEAP, content.mUnusedUncompressedNonheap, + KIND_NONHEAP, content.mUnusedUncompressedNonheap, "Memory used by not in-use content images (uncompressed data)."); #undef REPORT diff --git a/ipc/glue/SharedMemory.cpp b/ipc/glue/SharedMemory.cpp index 046fdd21ec2..bf077fc646c 100644 --- a/ipc/glue/SharedMemory.cpp +++ b/ipc/glue/SharedMemory.cpp @@ -17,28 +17,32 @@ namespace ipc { static Atomic gShmemAllocated; static Atomic gShmemMapped; -class ShmemAllocatedReporter MOZ_FINAL : public MemoryUniReporter +class ShmemReporter MOZ_FINAL : public nsIMemoryReporter { public: - ShmemAllocatedReporter() - : MemoryUniReporter("shmem-allocated", KIND_OTHER, UNITS_BYTES, -"Memory shared with other processes that is accessible (but not necessarily " -"mapped).") - {} -private: - int64_t Amount() MOZ_OVERRIDE { return gShmemAllocated; } + NS_DECL_THREADSAFE_ISUPPORTS + + NS_IMETHOD + CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData) + { + nsresult rv; + rv = MOZ_COLLECT_REPORT( + "shmem-allocated", KIND_OTHER, UNITS_BYTES, gShmemAllocated, + "Memory shared with other processes that is accessible (but not " + "necessarily mapped)."); + NS_ENSURE_SUCCESS(rv, rv); + + rv = MOZ_COLLECT_REPORT( + "shmem-mapped", KIND_OTHER, UNITS_BYTES, gShmemMapped, + "Memory shared with other processes that is mapped into the address " + "space."); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; + } }; -class ShmemMappedReporter MOZ_FINAL : public MemoryUniReporter -{ -public: - ShmemMappedReporter() - : MemoryUniReporter("shmem-mapped", KIND_OTHER, UNITS_BYTES, -"Memory shared with other processes that is mapped into the address space.") - {} -private: - int64_t Amount() MOZ_OVERRIDE { return gShmemMapped; } -}; +NS_IMPL_ISUPPORTS1(ShmemReporter, nsIMemoryReporter) SharedMemory::SharedMemory() : mAllocSize(0) @@ -46,8 +50,7 @@ SharedMemory::SharedMemory() { static Atomic registered; if (registered.compareExchange(0, 1)) { - RegisterStrongMemoryReporter(new ShmemAllocatedReporter()); - RegisterStrongMemoryReporter(new ShmemMappedReporter()); + RegisterStrongMemoryReporter(new ShmemReporter()); } } diff --git a/js/src/jit-test/tests/asm.js/testFunctionPtr.js b/js/src/jit-test/tests/asm.js/testFunctionPtr.js index b181af119d7..9998356f044 100644 --- a/js/src/jit-test/tests/asm.js/testFunctionPtr.js +++ b/js/src/jit-test/tests/asm.js/testFunctionPtr.js @@ -12,7 +12,7 @@ assertAsmTypeFail(USE_ASM + "function f() {} function g(i) {i=i|0} var tbl=[f,g] assertAsmTypeFail(USE_ASM + "function f() {} function g() {return 0} var tbl=[f,g]; return f"); assertAsmTypeFail(USE_ASM + "function f(i) {i=i|0} function g(i) {i=+i} var tbl=[f,g]; return f"); assertAsmTypeFail(USE_ASM + "function f() {return 0} function g() {return 0.0} var tbl=[f,g]; return f"); -assertAsmTypeFail(USE_ASM + "var tbl=0; function g() {tbl[0&1]()} return g"); +assertAsmTypeFail(USE_ASM + "var tbl=0; function g() {tbl[0&1]()|0} return g"); assertEq(asmLink(asmCompile(USE_ASM + "function f() { return 42 } var tbl=[f]; return f"))(), 42); assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 0} function g() {return 1} var tbl=[f,g]; return f"))(), 0); @@ -26,6 +26,7 @@ assertAsmTypeFail(USE_ASM + "function f() {return 42} function g(i) { i=i|0; ret assertAsmTypeFail(USE_ASM + "function f(i) {i=i|0} function g(i) { i=i|0; return tbl[i&1]()|0 } var tbl=[f,f]; return g"); assertAsmTypeFail(USE_ASM + "function f(i) {i=i|0} function g(i) { i=i|0; return tbl[i&1](3.0)|0 } var tbl=[f,f]; return g"); assertAsmTypeFail(USE_ASM + "function f(d) {d=+d} function g(i) { i=i|0; return tbl[i&1](3)|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function g() {tbl[0&1]()|0} return g"); assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return tbl[i&1]()|0 } var tbl=[f,f]; return g"))(0), 42); assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return tbl[i&1]()|0 } const tbl=[f,f]; return g"))(0), 42); assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() {return 13} function h(i) { i=i|0; return tbl[i&1]()|0 } var tbl=[f,g]; return h"))(1), 13); diff --git a/js/src/jit/AsmJS.cpp b/js/src/jit/AsmJS.cpp index f2e304e60df..c078e465f7a 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -1209,8 +1209,9 @@ class MOZ_STACK_CLASS ModuleCompiler unsigned mask() const { return mask_; } unsigned globalDataOffset() const { return globalDataOffset_; } - void initElems(FuncPtrVector &&elems) { elems_ = Move(elems); JS_ASSERT(!elems_.empty()); } - unsigned numElems() const { JS_ASSERT(!elems_.empty()); return elems_.length(); } + bool initialized() const { return !elems_.empty(); } + void initElems(FuncPtrVector &&elems) { elems_ = Move(elems); JS_ASSERT(initialized()); } + unsigned numElems() const { JS_ASSERT(initialized()); return elems_.length(); } const Func &elem(unsigned i) const { return *elems_[i]; } }; @@ -4088,6 +4089,7 @@ CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltin case AsmJSMathBuiltin_log: arity = 1; doubleCallee = AsmJSImm_LogD; floatCallee = AsmJSImm_LogF; break; case AsmJSMathBuiltin_pow: arity = 2; doubleCallee = AsmJSImm_PowD; floatCallee = AsmJSImm_Invalid; break; case AsmJSMathBuiltin_atan2: arity = 2; doubleCallee = AsmJSImm_ATan2D; floatCallee = AsmJSImm_Invalid; break; + default: MOZ_ASSUME_UNREACHABLE("unexpected mathBuiltin"); } if (retType == RetType::Float && floatCallee == AsmJSImm_Invalid) @@ -5702,6 +5704,11 @@ CheckFuncPtrTables(ModuleCompiler &m) } } + for (unsigned i = 0; i < m.numFuncPtrTables(); i++) { + if (!m.funcPtrTable(i).initialized()) + return m.fail(nullptr, "expecting function-pointer table"); + } + return true; } diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index c4e4078584f..8eac009d628 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -1629,22 +1629,25 @@ JSMainRuntimeCompartmentsUserDistinguishedAmount() return JS::UserCompartmentCount(rt); } -class JSMainRuntimeTemporaryPeakReporter MOZ_FINAL : public MemoryUniReporter +class JSMainRuntimeTemporaryPeakReporter MOZ_FINAL : public nsIMemoryReporter { -public: - JSMainRuntimeTemporaryPeakReporter() - : MemoryUniReporter("js-main-runtime-temporary-peak", - KIND_OTHER, UNITS_BYTES, -"The peak size of the transient storage in the main JSRuntime (the current " -"size of which is reported as 'explicit/js-non-window/runtime/temporary').") - {} -private: - int64_t Amount() MOZ_OVERRIDE + public: + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) { - return JSMainRuntimeTemporaryPeakDistinguishedAmount(); + return MOZ_COLLECT_REPORT( + "js-main-runtime-temporary-peak", KIND_OTHER, UNITS_BYTES, + JSMainRuntimeTemporaryPeakDistinguishedAmount(), + "The peak size of the transient storage in the main JSRuntime " + "(the current size of which is reported as " + "'explicit/js-non-window/runtime/temporary')."); } }; +NS_IMPL_ISUPPORTS1(JSMainRuntimeTemporaryPeakReporter, nsIMemoryReporter) + // The REPORT* macros do an unconditional report. The ZCREPORT* macros are for // compartments and zones; they aggregate any entries smaller than // SUNDRIES_THRESHOLD into the "sundries/gc-heap" and "sundries/malloc-heap" diff --git a/layout/base/nsStyleSheetService.cpp b/layout/base/nsStyleSheetService.cpp index ce9368eb45b..3c90c78b5b1 100644 --- a/layout/base/nsStyleSheetService.cpp +++ b/layout/base/nsStyleSheetService.cpp @@ -27,9 +27,6 @@ using namespace mozilla; nsStyleSheetService *nsStyleSheetService::gInstance = nullptr; nsStyleSheetService::nsStyleSheetService() - : MemoryUniReporter("explicit/layout/style-sheet-service", - KIND_HEAP, UNITS_BYTES, -"Memory used for style sheets held by the style sheet service.") { PR_STATIC_ASSERT(0 == AGENT_SHEET && 1 == USER_SHEET && 2 == AUTHOR_SHEET); NS_ASSERTION(!gInstance, "Someone is using CreateInstance instead of GetService"); @@ -45,8 +42,8 @@ nsStyleSheetService::~nsStyleSheetService() nsLayoutStatics::Release(); } -NS_IMPL_ISUPPORTS_INHERITED1( - nsStyleSheetService, MemoryUniReporter, nsIStyleSheetService) +NS_IMPL_ISUPPORTS2( + nsStyleSheetService, nsIStyleSheetService, nsIMemoryReporter) void nsStyleSheetService::RegisterFromEnumerator(nsICategoryManager *aManager, @@ -282,13 +279,19 @@ static size_t SizeOfElementIncludingThis(nsIStyleSheet* aElement, MallocSizeOf aMallocSizeOf, void *aData) { - return aElement->SizeOfIncludingThis(aMallocSizeOf); + return aElement->SizeOfIncludingThis(aMallocSizeOf); } -int64_t -nsStyleSheetService::Amount() +MOZ_DEFINE_MALLOC_SIZE_OF(StyleSheetServiceMallocSizeOf) + +NS_IMETHODIMP +nsStyleSheetService::CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) { - return SizeOfIncludingThis(MallocSizeOf); + return MOZ_COLLECT_REPORT( + "explicit/layout/style-sheet-service", KIND_HEAP, UNITS_BYTES, + SizeOfIncludingThis(StyleSheetServiceMallocSizeOf), + "Memory used for style sheets held by the style sheet service."); } size_t diff --git a/layout/base/nsStyleSheetService.h b/layout/base/nsStyleSheetService.h index 5badadc9bb6..ddf3d4a4097 100644 --- a/layout/base/nsStyleSheetService.h +++ b/layout/base/nsStyleSheetService.h @@ -28,8 +28,8 @@ class nsIStyleSheet; "@mozilla.org/content/style-sheet-service;1" class nsStyleSheetService MOZ_FINAL - : public mozilla::MemoryUniReporter - , public nsIStyleSheetService + : public nsIStyleSheetService + , public nsIMemoryReporter { public: nsStyleSheetService() NS_HIDDEN; @@ -37,6 +37,7 @@ class nsStyleSheetService MOZ_FINAL NS_DECL_ISUPPORTS NS_DECL_NSISTYLESHEETSERVICE + NS_DECL_NSIMEMORYREPORTER NS_HIDDEN_(nsresult) Init(); @@ -49,8 +50,6 @@ class nsStyleSheetService MOZ_FINAL static nsStyleSheetService *GetInstance(); static nsStyleSheetService *gInstance; - int64_t Amount() MOZ_OVERRIDE; - private: NS_HIDDEN_(void) RegisterFromEnumerator(nsICategoryManager *aManager, diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index ad8106dafb6..ac705fdd0f2 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -433,6 +433,10 @@ Initialize() NS_WARNING("Could not get an observer service. We will leak on shutdown."); } +#ifdef DEBUG + nsStyleContext::AssertStyleStructMaxDifferenceValid(); +#endif + return NS_OK; } diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index 8454b8d33cb..e3d3c007bfb 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -400,7 +400,7 @@ load 570160.html load 570289-1.html load 571618-1.svg asserts(1) load 571975-1.html # bug 574889 -asserts(1) load 571995.xhtml # 761848 +load 571995.xhtml load 574958.xhtml asserts(0-4) load 578977.html # bug 757305 load 580504-1.xhtml diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 3aa10e882c1..87b38494e4d 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -95,7 +95,8 @@ Declaration::HasProperty(nsCSSProperty aProperty) const bool Declaration::AppendValueToString(nsCSSProperty aProperty, - nsAString& aResult) const + nsAString& aResult, + nsCSSValue::Serialization aSerialization) const { NS_ABORT_IF_FALSE(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands, @@ -108,7 +109,7 @@ Declaration::AppendValueToString(nsCSSProperty aProperty, return false; } - val->AppendToString(aProperty, aResult); + val->AppendToString(aProperty, aResult, aSerialization); return true; } @@ -117,7 +118,8 @@ Declaration::AppendValueToString(nsCSSProperty aProperty, static void AppendSidesShorthandToString(const nsCSSProperty aProperties[], const nsCSSValue* aValues[], - nsAString& aString) + nsAString& aString, + nsCSSValue::Serialization aSerialization) { const nsCSSValue& value1 = *aValues[0]; const nsCSSValue& value2 = *aValues[1]; @@ -125,19 +127,19 @@ AppendSidesShorthandToString(const nsCSSProperty aProperties[], const nsCSSValue& value4 = *aValues[3]; NS_ABORT_IF_FALSE(value1.GetUnit() != eCSSUnit_Null, "null value 1"); - value1.AppendToString(aProperties[0], aString); + value1.AppendToString(aProperties[0], aString, aSerialization); if (value1 != value2 || value1 != value3 || value1 != value4) { aString.Append(PRUnichar(' ')); NS_ABORT_IF_FALSE(value2.GetUnit() != eCSSUnit_Null, "null value 2"); - value2.AppendToString(aProperties[1], aString); + value2.AppendToString(aProperties[1], aString, aSerialization); if (value1 != value3 || value2 != value4) { aString.Append(PRUnichar(' ')); NS_ABORT_IF_FALSE(value3.GetUnit() != eCSSUnit_Null, "null value 3"); - value3.AppendToString(aProperties[2], aString); + value3.AppendToString(aProperties[2], aString, aSerialization); if (value2 != value4) { aString.Append(PRUnichar(' ')); NS_ABORT_IF_FALSE(value4.GetUnit() != eCSSUnit_Null, "null value 4"); - value4.AppendToString(aProperties[3], aString); + value4.AppendToString(aProperties[3], aString, aSerialization); } } } @@ -145,12 +147,25 @@ AppendSidesShorthandToString(const nsCSSProperty aProperties[], void Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const +{ + GetValue(aProperty, aValue, nsCSSValue::eNormalized); +} + +void +Declaration::GetAuthoredValue(nsCSSProperty aProperty, nsAString& aValue) const +{ + GetValue(aProperty, aValue, nsCSSValue::eAuthorSpecified); +} + +void +Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, + nsCSSValue::Serialization aSerialization) const { aValue.Truncate(0); // simple properties are easy. if (!nsCSSProps::IsShorthand(aProperty)) { - AppendValueToString(aProperty, aValue); + AppendValueToString(aProperty, aValue, aSerialization); return; } @@ -220,17 +235,20 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const } if (initialCount == totalCount) { // Simplify serialization below by serializing initial up-front. - nsCSSValue(eCSSUnit_Initial).AppendToString(eCSSProperty_UNKNOWN, aValue); + nsCSSValue(eCSSUnit_Initial).AppendToString(eCSSProperty_UNKNOWN, aValue, + nsCSSValue::eNormalized); return; } if (inheritCount == totalCount) { // Simplify serialization below by serializing inherit up-front. - nsCSSValue(eCSSUnit_Inherit).AppendToString(eCSSProperty_UNKNOWN, aValue); + nsCSSValue(eCSSUnit_Inherit).AppendToString(eCSSProperty_UNKNOWN, aValue, + nsCSSValue::eNormalized); return; } if (unsetCount == totalCount) { // Simplify serialization below by serializing unset up-front. - nsCSSValue(eCSSUnit_Unset).AppendToString(eCSSProperty_UNKNOWN, aValue); + nsCSSValue(eCSSUnit_Unset).AppendToString(eCSSProperty_UNKNOWN, aValue, + nsCSSValue::eNormalized); return; } if (initialCount != 0 || inheritCount != 0 || unsetCount != 0) { @@ -271,7 +289,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const data->ValueFor(subprops[2]), data->ValueFor(subprops[3]) }; - AppendSidesShorthandToString(subprops, vals, aValue); + AppendSidesShorthandToString(subprops, vals, aValue, aSerialization); break; } case eCSSProperty_border_radius: @@ -300,10 +318,10 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const } } - AppendSidesShorthandToString(subprops, xVals, aValue); + AppendSidesShorthandToString(subprops, xVals, aValue, aSerialization); if (needY) { aValue.AppendLiteral(" / "); - AppendSidesShorthandToString(subprops, yVals, aValue); + AppendSidesShorthandToString(subprops, yVals, aValue, aSerialization); } break; } @@ -312,7 +330,8 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const // 'border-image-source' (when it's none), it's probably not a // good idea since it's likely to be confusing. It would also // require adding the extra check that we serialize *something*. - AppendValueToString(eCSSProperty_border_image_source, aValue); + AppendValueToString(eCSSProperty_border_image_source, aValue, + aSerialization); bool sliceDefault = data->HasDefaultBorderImageSlice(); bool widthDefault = data->HasDefaultBorderImageWidth(); @@ -320,16 +339,19 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const if (!sliceDefault || !widthDefault || !outsetDefault) { aValue.Append(PRUnichar(' ')); - AppendValueToString(eCSSProperty_border_image_slice, aValue); + AppendValueToString(eCSSProperty_border_image_slice, aValue, + aSerialization); if (!widthDefault || !outsetDefault) { aValue.Append(NS_LITERAL_STRING(" /")); if (!widthDefault) { aValue.Append(PRUnichar(' ')); - AppendValueToString(eCSSProperty_border_image_width, aValue); + AppendValueToString(eCSSProperty_border_image_width, aValue, + aSerialization); } if (!outsetDefault) { aValue.Append(NS_LITERAL_STRING(" / ")); - AppendValueToString(eCSSProperty_border_image_outset, aValue); + AppendValueToString(eCSSProperty_border_image_outset, aValue, + aSerialization); } } } @@ -337,7 +359,8 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const bool repeatDefault = data->HasDefaultBorderImageRepeat(); if (!repeatDefault) { aValue.Append(PRUnichar(' ')); - AppendValueToString(eCSSProperty_border_image_repeat, aValue); + AppendValueToString(eCSSProperty_border_image_repeat, aValue, + aSerialization); } break; } @@ -407,13 +430,13 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const bool isMozUseTextColor = colorValue->GetUnit() == eCSSUnit_Enumerated && colorValue->GetIntValue() == NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR; - if (!AppendValueToString(subprops[0], aValue) || + if (!AppendValueToString(subprops[0], aValue, aSerialization) || !(aValue.Append(PRUnichar(' ')), - AppendValueToString(subprops[1], aValue)) || + AppendValueToString(subprops[1], aValue, aSerialization)) || // Don't output a third value when it's -moz-use-text-color. !(isMozUseTextColor || (aValue.Append(PRUnichar(' ')), - AppendValueToString(subprops[2], aValue)))) { + AppendValueToString(subprops[2], aValue, aSerialization)))) { aValue.Truncate(); } break; @@ -442,7 +465,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const nsCSSProps::SubpropertyEntryFor(aProperty); NS_ABORT_IF_FALSE(subprops[3] == eCSSProperty_UNKNOWN, "not box property with physical vs. logical cascading"); - AppendValueToString(subprops[0], aValue); + AppendValueToString(subprops[0], aValue, aSerialization); break; } case eCSSProperty_background: { @@ -475,27 +498,32 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const data->ValueFor(eCSSProperty_background_size)-> GetPairListValue(); for (;;) { - image->mValue.AppendToString(eCSSProperty_background_image, aValue); + image->mValue.AppendToString(eCSSProperty_background_image, aValue, + aSerialization); aValue.Append(PRUnichar(' ')); - repeat->mXValue.AppendToString(eCSSProperty_background_repeat, aValue); + repeat->mXValue.AppendToString(eCSSProperty_background_repeat, aValue, + aSerialization); if (repeat->mYValue.GetUnit() != eCSSUnit_Null) { - repeat->mYValue.AppendToString(eCSSProperty_background_repeat, aValue); + repeat->mYValue.AppendToString(eCSSProperty_background_repeat, aValue, + aSerialization); } aValue.Append(PRUnichar(' ')); attachment->mValue.AppendToString(eCSSProperty_background_attachment, - aValue); + aValue, aSerialization); aValue.Append(PRUnichar(' ')); position->mValue.AppendToString(eCSSProperty_background_position, - aValue); + aValue, aSerialization); if (size->mXValue.GetUnit() != eCSSUnit_Auto || size->mYValue.GetUnit() != eCSSUnit_Auto) { aValue.Append(PRUnichar(' ')); aValue.Append(PRUnichar('/')); aValue.Append(PRUnichar(' ')); - size->mXValue.AppendToString(eCSSProperty_background_size, aValue); + size->mXValue.AppendToString(eCSSProperty_background_size, aValue, + aSerialization); aValue.Append(PRUnichar(' ')); - size->mYValue.AppendToString(eCSSProperty_background_size, aValue); + size->mYValue.AppendToString(eCSSProperty_background_size, aValue, + aSerialization); } NS_ABORT_IF_FALSE(clip->mValue.GetUnit() == eCSSUnit_Enumerated && @@ -518,11 +546,13 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const NS_STYLE_BG_ORIGIN_CONTENT, "bg-clip and bg-origin style constants must agree"); aValue.Append(PRUnichar(' ')); - origin->mValue.AppendToString(eCSSProperty_background_origin, aValue); + origin->mValue.AppendToString(eCSSProperty_background_origin, aValue, + aSerialization); if (clip->mValue != origin->mValue) { aValue.Append(PRUnichar(' ')); - clip->mValue.AppendToString(eCSSProperty_background_clip, aValue); + clip->mValue.AppendToString(eCSSProperty_background_clip, aValue, + aSerialization); } } @@ -552,7 +582,8 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const } aValue.Append(PRUnichar(' ')); - AppendValueToString(eCSSProperty_background_color, aValue); + AppendValueToString(eCSSProperty_background_color, aValue, + aSerialization); break; } case eCSSProperty_font: { @@ -629,7 +660,8 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const // This can't be represented as a shorthand. return; } - systemFont->AppendToString(eCSSProperty__x_system_font, aValue); + systemFont->AppendToString(eCSSProperty__x_system_font, aValue, + aSerialization); } else { // properties reset by this shorthand property to their // initial values but not represented in its syntax @@ -654,35 +686,44 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const if (style->GetUnit() != eCSSUnit_Enumerated || style->GetIntValue() != NS_FONT_STYLE_NORMAL) { - style->AppendToString(eCSSProperty_font_style, aValue); + style->AppendToString(eCSSProperty_font_style, aValue, + aSerialization); aValue.Append(PRUnichar(' ')); } if (variant->GetUnit() != eCSSUnit_Enumerated || variant->GetIntValue() != NS_FONT_VARIANT_NORMAL) { - variant->AppendToString(eCSSProperty_font_variant, aValue); + variant->AppendToString(eCSSProperty_font_variant, aValue, + aSerialization); aValue.Append(PRUnichar(' ')); } if (weight->GetUnit() != eCSSUnit_Enumerated || weight->GetIntValue() != NS_FONT_WEIGHT_NORMAL) { - weight->AppendToString(eCSSProperty_font_weight, aValue); + weight->AppendToString(eCSSProperty_font_weight, aValue, + aSerialization); aValue.Append(PRUnichar(' ')); } - size->AppendToString(eCSSProperty_font_size, aValue); + size->AppendToString(eCSSProperty_font_size, aValue, aSerialization); if (lh->GetUnit() != eCSSUnit_Normal) { aValue.Append(PRUnichar('/')); - lh->AppendToString(eCSSProperty_line_height, aValue); + lh->AppendToString(eCSSProperty_line_height, aValue, aSerialization); } aValue.Append(PRUnichar(' ')); - family->AppendToString(eCSSProperty_font_family, aValue); + family->AppendToString(eCSSProperty_font_family, aValue, + aSerialization); } break; } case eCSSProperty_list_style: - if (AppendValueToString(eCSSProperty_list_style_type, aValue)) + if (AppendValueToString(eCSSProperty_list_style_type, aValue, + aSerialization)) { aValue.Append(PRUnichar(' ')); - if (AppendValueToString(eCSSProperty_list_style_position, aValue)) + } + if (AppendValueToString(eCSSProperty_list_style_position, aValue, + aSerialization)) { aValue.Append(PRUnichar(' ')); - AppendValueToString(eCSSProperty_list_style_image, aValue); + } + AppendValueToString(eCSSProperty_list_style_image, aValue, + aSerialization); break; case eCSSProperty_overflow: { const nsCSSValue &xValue = @@ -690,7 +731,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const const nsCSSValue &yValue = *data->ValueFor(eCSSProperty_overflow_y); if (xValue == yValue) - xValue.AppendToString(eCSSProperty_overflow_x, aValue); + xValue.AppendToString(eCSSProperty_overflow_x, aValue, aSerialization); break; } case eCSSProperty_text_decoration: { @@ -712,7 +753,8 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const return; } - AppendValueToString(eCSSProperty_text_decoration_line, aValue); + AppendValueToString(eCSSProperty_text_decoration_line, aValue, + aSerialization); break; } case eCSSProperty_transition: { @@ -747,14 +789,17 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const // If any of the other three lists has more than one element, // we can't use the shorthand. if (!dur->mNext && !tim->mNext && !del->mNext) { - transProp->AppendToString(eCSSProperty_transition_property, aValue); + transProp->AppendToString(eCSSProperty_transition_property, aValue, + aSerialization); aValue.Append(PRUnichar(' ')); - dur->mValue.AppendToString(eCSSProperty_transition_duration,aValue); + dur->mValue.AppendToString(eCSSProperty_transition_duration,aValue, + aSerialization); aValue.Append(PRUnichar(' ')); tim->mValue.AppendToString(eCSSProperty_transition_timing_function, - aValue); + aValue, aSerialization); aValue.Append(PRUnichar(' ')); - del->mValue.AppendToString(eCSSProperty_transition_delay, aValue); + del->mValue.AppendToString(eCSSProperty_transition_delay, aValue, + aSerialization); aValue.Append(PRUnichar(' ')); } else { aValue.Truncate(); @@ -767,16 +812,16 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const const nsCSSValueList* pro = transProp->GetListValue(); for (;;) { pro->mValue.AppendToString(eCSSProperty_transition_property, - aValue); + aValue, aSerialization); aValue.Append(PRUnichar(' ')); dur->mValue.AppendToString(eCSSProperty_transition_duration, - aValue); + aValue, aSerialization); aValue.Append(PRUnichar(' ')); tim->mValue.AppendToString(eCSSProperty_transition_timing_function, - aValue); + aValue, aSerialization); aValue.Append(PRUnichar(' ')); del->mValue.AppendToString(eCSSProperty_transition_delay, - aValue); + aValue, aSerialization); pro = pro->mNext; dur = dur->mNext; tim = tim->mNext; @@ -819,7 +864,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const "animation-name must be last"); bool done = false; for (uint32_t i = 0;;) { - lists[i]->mValue.AppendToString(subprops[i], aValue); + lists[i]->mValue.AppendToString(subprops[i], aValue, aSerialization); lists[i] = lists[i]->mNext; if (!lists[i]) { done = true; @@ -851,16 +896,16 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const const nsCSSValue &startValue = *data->ValueFor(eCSSProperty_marker_start); if (endValue == midValue && midValue == startValue) - AppendValueToString(eCSSProperty_marker_end, aValue); + AppendValueToString(eCSSProperty_marker_end, aValue, aSerialization); break; } case eCSSProperty__moz_columns: { // Two values, column-count and column-width, separated by a space. const nsCSSProperty* subprops = nsCSSProps::SubpropertyEntryFor(aProperty); - AppendValueToString(subprops[0], aValue); + AppendValueToString(subprops[0], aValue, aSerialization); aValue.Append(PRUnichar(' ')); - AppendValueToString(subprops[1], aValue); + AppendValueToString(subprops[1], aValue, aSerialization); break; } case eCSSProperty_flex: { @@ -868,11 +913,11 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const const nsCSSProperty* subprops = nsCSSProps::SubpropertyEntryFor(aProperty); - AppendValueToString(subprops[0], aValue); + AppendValueToString(subprops[0], aValue, aSerialization); aValue.Append(PRUnichar(' ')); - AppendValueToString(subprops[1], aValue); + AppendValueToString(subprops[1], aValue, aSerialization); aValue.Append(PRUnichar(' ')); - AppendValueToString(subprops[2], aValue); + AppendValueToString(subprops[2], aValue, aSerialization); break; } case eCSSProperty_flex_flow: { @@ -882,9 +927,9 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const NS_ABORT_IF_FALSE(subprops[2] == eCSSProperty_UNKNOWN, "must have exactly two subproperties"); - AppendValueToString(subprops[0], aValue); + AppendValueToString(subprops[0], aValue, aSerialization); aValue.Append(PRUnichar(' ')); - AppendValueToString(subprops[1], aValue); + AppendValueToString(subprops[1], aValue, aSerialization); break; } case eCSSProperty__moz_transform: { @@ -893,7 +938,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const nsCSSProps::SubpropertyEntryFor(aProperty); NS_ABORT_IF_FALSE(subprops[1] == eCSSProperty_UNKNOWN, "must have exactly one subproperty"); - AppendValueToString(subprops[0], aValue); + AppendValueToString(subprops[0], aValue, aSerialization); break; } case eCSSProperty_all: @@ -961,7 +1006,7 @@ Declaration::AppendPropertyAndValueToString(nsCSSProperty aProperty, AppendASCIItoUTF16(nsCSSProps::GetStringValue(aProperty), aResult); aResult.AppendLiteral(": "); if (aValue.IsEmpty()) - AppendValueToString(aProperty, aResult); + AppendValueToString(aProperty, aResult, nsCSSValue::eNormalized); else aResult.Append(aValue); if (GetValueIsImportant(aProperty)) { @@ -1096,7 +1141,8 @@ Declaration::ToString(nsAString& aString) const // Output the shorthand font declaration that we will // partially override later. But don't add it to // |shorthandsUsed|, since we will have to override it. - systemFont->AppendToString(eCSSProperty__x_system_font, value); + systemFont->AppendToString(eCSSProperty__x_system_font, value, + nsCSSValue::eNormalized); AppendPropertyAndValueToString(eCSSProperty_font, value, aString); value.Truncate(); didSystemFont = true; diff --git a/layout/style/Declaration.h b/layout/style/Declaration.h index 24aa6b41b3b..ec4548df671 100644 --- a/layout/style/Declaration.h +++ b/layout/style/Declaration.h @@ -63,6 +63,7 @@ public: bool HasProperty(nsCSSProperty aProperty) const; void GetValue(nsCSSProperty aProperty, nsAString& aValue) const; + void GetAuthoredValue(nsCSSProperty aProperty, nsAString& aValue) const; bool HasImportantData() const { return mImportantData || mImportantVariables; @@ -278,9 +279,14 @@ private: Declaration& operator=(const Declaration& aCopy) MOZ_DELETE; bool operator==(const Declaration& aCopy) const MOZ_DELETE; + void GetValue(nsCSSProperty aProperty, nsAString& aValue, + nsCSSValue::Serialization aValueSerialization) const; + static void AppendImportanceToString(bool aIsImportant, nsAString& aString); // return whether there was a value in |aValue| (i.e., it had a non-null unit) bool AppendValueToString(nsCSSProperty aProperty, nsAString& aResult) const; + bool AppendValueToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aValueSerialization) const; // Helper for ToString with strange semantics regarding aValue. void AppendPropertyAndValueToString(nsCSSProperty aProperty, nsAutoString& aValue, diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 4e1c7b8c6a7..c41eefbb376 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -738,14 +738,16 @@ protected: int32_t ParseChoice(nsCSSValue aValues[], const nsCSSProperty aPropIDs[], int32_t aNumIDs); bool ParseColor(nsCSSValue& aValue); - bool ParseColorComponent(uint8_t& aComponent, - int32_t& aType, char aStop); + bool ParseNumberColorComponent(uint8_t& aComponent, char aStop); + bool ParsePercentageColorComponent(float& aComponent, char aStop); // ParseHSLColor parses everything starting with the opening '(' // up through and including the aStop char. - bool ParseHSLColor(nscolor& aColor, char aStop); + bool ParseHSLColor(float& aHue, float& aSaturation, float& aLightness, + char aStop); // ParseColorOpacity will enforce that the color ends with a ')' // after the opacity bool ParseColorOpacity(uint8_t& aOpacity); + bool ParseColorOpacity(float& aOpacity); bool ParseEnum(nsCSSValue& aValue, const int32_t aKeywordTable[]); bool ParseVariant(nsCSSValue& aValue, int32_t aVariantMask, @@ -5271,12 +5273,6 @@ CSSParserImpl::ParseDeclarationBlock(uint32_t aFlags, nsCSSContextType aContext) return declaration; } -// The types to pass to ParseColorComponent. These correspond to the -// various datatypes that can go within rgb(). -#define COLOR_TYPE_UNKNOWN 0 -#define COLOR_TYPE_INTEGERS 1 -#define COLOR_TYPE_PERCENTAGES 2 - bool CSSParserImpl::ParseColor(nsCSSValue& aValue) { @@ -5292,7 +5288,12 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue) case eCSSToken_Hash: // #xxyyzz if (NS_HexToRGB(tk->mIdent, &rgba)) { - aValue.SetColorValue(rgba); + MOZ_ASSERT(tk->mIdent.Length() == 3 || tk->mIdent.Length() == 6, + "unexpected hex color length"); + nsCSSUnit unit = tk->mIdent.Length() == 3 ? + eCSSUnit_ShortHexColor : + eCSSUnit_HexColor; + aValue.SetIntegerColorValue(rgba, unit); return true; } break; @@ -5316,27 +5317,54 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue) case eCSSToken_Function: if (mToken.mIdent.LowerCaseEqualsLiteral("rgb")) { // rgb ( component , component , component ) - uint8_t r, g, b; - int32_t type = COLOR_TYPE_UNKNOWN; - if (ParseColorComponent(r, type, ',') && - ParseColorComponent(g, type, ',') && - ParseColorComponent(b, type, ')')) { - aValue.SetColorValue(NS_RGB(r,g,b)); - return true; + if (GetToken(true)) { + UngetToken(); + } + if (mToken.mType == eCSSToken_Number) { + uint8_t r, g, b; + if (ParseNumberColorComponent(r, ',') && + ParseNumberColorComponent(g, ',') && + ParseNumberColorComponent(b, ')')) { + aValue.SetIntegerColorValue(NS_RGB(r, g, b), eCSSUnit_RGBColor); + return true; + } + } else { + float r, g, b; + if (ParsePercentageColorComponent(r, ',') && + ParsePercentageColorComponent(g, ',') && + ParsePercentageColorComponent(b, ')')) { + aValue.SetFloatColorValue(r, g, b, 1.0f, + eCSSUnit_PercentageRGBColor); + return true; + } } SkipUntil(')'); return false; } else if (mToken.mIdent.LowerCaseEqualsLiteral("rgba")) { // rgba ( component , component , component , opacity ) - uint8_t r, g, b, a; - int32_t type = COLOR_TYPE_UNKNOWN; - if (ParseColorComponent(r, type, ',') && - ParseColorComponent(g, type, ',') && - ParseColorComponent(b, type, ',') && - ParseColorOpacity(a)) { - aValue.SetColorValue(NS_RGBA(r, g, b, a)); - return true; + if (GetToken(true)) { + UngetToken(); + } + if (mToken.mType == eCSSToken_Number) { + uint8_t r, g, b, a; + if (ParseNumberColorComponent(r, ',') && + ParseNumberColorComponent(g, ',') && + ParseNumberColorComponent(b, ',') && + ParseColorOpacity(a)) { + aValue.SetIntegerColorValue(NS_RGBA(r, g, b, a), + eCSSUnit_RGBAColor); + return true; + } + } else { + float r, g, b, a; + if (ParsePercentageColorComponent(r, ',') && + ParsePercentageColorComponent(g, ',') && + ParsePercentageColorComponent(b, ',') && + ParseColorOpacity(a)) { + aValue.SetFloatColorValue(r, g, b, a, eCSSUnit_PercentageRGBAColor); + return true; + } } SkipUntil(')'); return false; @@ -5344,8 +5372,9 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue) else if (mToken.mIdent.LowerCaseEqualsLiteral("hsl")) { // hsl ( hue , saturation , lightness ) // "hue" is a number, "saturation" and "lightness" are percentages. - if (ParseHSLColor(rgba, ')')) { - aValue.SetColorValue(rgba); + float h, s, l; + if (ParseHSLColor(h, s, l, ')')) { + aValue.SetFloatColorValue(h, s, l, 1.0f, eCSSUnit_HSLColor); return true; } SkipUntil(')'); @@ -5355,11 +5384,10 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue) // hsla ( hue , saturation , lightness , opacity ) // "hue" is a number, "saturation" and "lightness" are percentages, // "opacity" is a number. - uint8_t a; - if (ParseHSLColor(rgba, ',') && + float h, s, l, a; + if (ParseHSLColor(h, s, l, ',') && ParseColorOpacity(a)) { - aValue.SetColorValue(NS_RGBA(NS_GET_R(rgba), NS_GET_G(rgba), - NS_GET_B(rgba), a)); + aValue.SetFloatColorValue(h, s, l, a, eCSSUnit_HSLAColor); return true; } SkipUntil(')'); @@ -5414,7 +5442,7 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue) break; } if (NS_HexToRGB(str, &rgba)) { - aValue.SetColorValue(rgba); + aValue.SetIntegerColorValue(rgba, eCSSUnit_HexColor); return true; } } @@ -5425,66 +5453,25 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue) return false; } -// aType will be set if we have already parsed other color components -// in this color spec bool -CSSParserImpl::ParseColorComponent(uint8_t& aComponent, - int32_t& aType, - char aStop) +CSSParserImpl::ParseNumberColorComponent(uint8_t& aComponent, char aStop) { if (!GetToken(true)) { REPORT_UNEXPECTED_EOF(PEColorComponentEOF); return false; } - float value; - nsCSSToken* tk = &mToken; - switch (tk->mType) { - case eCSSToken_Number: - switch (aType) { - case COLOR_TYPE_UNKNOWN: - aType = COLOR_TYPE_INTEGERS; - break; - case COLOR_TYPE_INTEGERS: - break; - case COLOR_TYPE_PERCENTAGES: - REPORT_UNEXPECTED_TOKEN(PEExpectedPercent); - UngetToken(); - return false; - default: - NS_NOTREACHED("Someone forgot to add the new color component type in here"); - } - if (!mToken.mIntegerValid) { - REPORT_UNEXPECTED_TOKEN(PEExpectedInt); - UngetToken(); - return false; - } - value = tk->mNumber; - break; - case eCSSToken_Percentage: - switch (aType) { - case COLOR_TYPE_UNKNOWN: - aType = COLOR_TYPE_PERCENTAGES; - break; - case COLOR_TYPE_INTEGERS: - REPORT_UNEXPECTED_TOKEN(PEExpectedInt); - UngetToken(); - return false; - case COLOR_TYPE_PERCENTAGES: - break; - default: - NS_NOTREACHED("Someone forgot to add the new color component type in here"); - } - value = tk->mNumber * 255.0f; - break; - default: - REPORT_UNEXPECTED_TOKEN(PEColorBadRGBContents); + if (mToken.mType != eCSSToken_Number || !mToken.mIntegerValid) { + REPORT_UNEXPECTED_TOKEN(PEExpectedInt); UngetToken(); return false; } + + float value = mToken.mNumber; + if (value < 0.0f) value = 0.0f; + if (value > 255.0f) value = 255.0f; + if (ExpectSymbol(aStop, true)) { - if (value < 0.0f) value = 0.0f; - if (value > 255.0f) value = 255.0f; aComponent = NSToIntRound(value); return true; } @@ -5492,9 +5479,35 @@ CSSParserImpl::ParseColorComponent(uint8_t& aComponent, return false; } +bool +CSSParserImpl::ParsePercentageColorComponent(float& aComponent, char aStop) +{ + if (!GetToken(true)) { + REPORT_UNEXPECTED_EOF(PEColorComponentEOF); + return false; + } + + if (mToken.mType != eCSSToken_Percentage) { + REPORT_UNEXPECTED_TOKEN(PEExpectedPercent); + UngetToken(); + return false; + } + + float value = mToken.mNumber; + if (value < 0.0f) value = 0.0f; + if (value > 1.0f) value = 1.0f; + + if (ExpectSymbol(aStop, true)) { + aComponent = value; + return true; + } + REPORT_UNEXPECTED_TOKEN_CHAR(PEColorComponentBadTerm, aStop); + return false; +} + bool -CSSParserImpl::ParseHSLColor(nscolor& aColor, +CSSParserImpl::ParseHSLColor(float& aHue, float& aSaturation, float& aLightness, char aStop) { float h, s, l; @@ -5553,7 +5566,9 @@ CSSParserImpl::ParseHSLColor(nscolor& aColor, if (l > 1.0f) l = 1.0f; if (ExpectSymbol(aStop, true)) { - aColor = NS_HSL2RGB(h, s, l); + aHue = h; + aSaturation = s; + aLightness = l; return true; } @@ -5564,6 +5579,24 @@ CSSParserImpl::ParseHSLColor(nscolor& aColor, bool CSSParserImpl::ParseColorOpacity(uint8_t& aOpacity) +{ + float floatOpacity; + if (!ParseColorOpacity(floatOpacity)) { + return false; + } + + uint8_t value = nsStyleUtil::FloatToColorComponent(floatOpacity); + // Need to compare to something slightly larger + // than 0.5 due to floating point inaccuracies. + NS_ASSERTION(fabs(255.0f*mToken.mNumber - value) <= 0.51f, + "FloatToColorComponent did something weird"); + + aOpacity = value; + return true; +} + +bool +CSSParserImpl::ParseColorOpacity(float& aOpacity) { if (!GetToken(true)) { REPORT_UNEXPECTED_EOF(PEColorOpacityEOF); @@ -5576,25 +5609,18 @@ CSSParserImpl::ParseColorOpacity(uint8_t& aOpacity) return false; } + if (!ExpectSymbol(')', true)) { + REPORT_UNEXPECTED_TOKEN(PEExpectedCloseParen); + return false; + } + if (mToken.mNumber < 0.0f) { mToken.mNumber = 0.0f; } else if (mToken.mNumber > 1.0f) { mToken.mNumber = 1.0f; } - uint8_t value = nsStyleUtil::FloatToColorComponent(mToken.mNumber); - // Need to compare to something slightly larger - // than 0.5 due to floating point inaccuracies. - NS_ASSERTION(fabs(255.0f*mToken.mNumber - value) <= 0.51f, - "FloatToColorComponent did something weird"); - - if (!ExpectSymbol(')', true)) { - REPORT_UNEXPECTED_TOKEN(PEExpectedCloseParen); - return false; - } - - aOpacity = value; - + aOpacity = mToken.mNumber; return true; } @@ -8114,7 +8140,7 @@ CSSParserImpl::ParseBackground() // If we get to this point without seeing a color, provide a default. if (color.GetUnit() == eCSSUnit_Null) { - color.SetColorValue(NS_RGBA(0,0,0,0)); + color.SetIntegerColorValue(NS_RGBA(0,0,0,0), eCSSUnit_RGBAColor); } AppendValue(eCSSProperty_background_image, image); @@ -12069,8 +12095,8 @@ CSSParserImpl::ParseShadowItem(nsCSSValue& aValue, bool aIsBoxShadow) } else { // Must be a color (as string or color value) NS_ASSERTION(xOrColor.GetUnit() == eCSSUnit_Ident || - xOrColor.GetUnit() == eCSSUnit_Color || - xOrColor.GetUnit() == eCSSUnit_EnumColor, + xOrColor.GetUnit() == eCSSUnit_EnumColor || + xOrColor.IsNumericColorUnit(), "Must be a color value"); val->Item(IndexColor) = xOrColor; haveColor = true; diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 21a29a576fe..a187ca97b3a 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -20,7 +20,7 @@ #define VARIANT_KEYWORD 0x000001 // K #define VARIANT_LENGTH 0x000002 // L #define VARIANT_PERCENT 0x000004 // P -#define VARIANT_COLOR 0x000008 // C eCSSUnit_Color, eCSSUnit_Ident (e.g. "red") +#define VARIANT_COLOR 0x000008 // C eCSSUnit_*Color, eCSSUnit_Ident (e.g. "red") #define VARIANT_URL 0x000010 // U #define VARIANT_NUMBER 0x000020 // N #define VARIANT_INTEGER 0x000040 // I diff --git a/layout/style/nsCSSRules.cpp b/layout/style/nsCSSRules.cpp index c0a74f49662..2c7f9a8a852 100644 --- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -1512,15 +1512,18 @@ nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID, } case eCSSFontDesc_Style: - val.AppendToString(eCSSProperty_font_style, aResult); + val.AppendToString(eCSSProperty_font_style, aResult, + nsCSSValue::eNormalized); return NS_OK; case eCSSFontDesc_Weight: - val.AppendToString(eCSSProperty_font_weight, aResult); + val.AppendToString(eCSSProperty_font_weight, aResult, + nsCSSValue::eNormalized); return NS_OK; case eCSSFontDesc_Stretch: - val.AppendToString(eCSSProperty_font_stretch, aResult); + val.AppendToString(eCSSProperty_font_stretch, aResult, + nsCSSValue::eNormalized); return NS_OK; case eCSSFontDesc_FontFeatureSettings: @@ -1528,7 +1531,8 @@ nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID, return NS_OK; case eCSSFontDesc_FontLanguageOverride: - val.AppendToString(eCSSProperty_font_language_override, aResult); + val.AppendToString(eCSSProperty_font_language_override, aResult, + nsCSSValue::eNormalized); return NS_OK; case eCSSFontDesc_Src: @@ -1588,6 +1592,15 @@ nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString & propertyName, return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult); } +NS_IMETHODIMP +nsCSSFontFaceStyleDecl::GetAuthoredPropertyValue(const nsAString& propertyName, + nsAString& aResult) +{ + // We don't return any authored property values different from + // GetPropertyValue, currently. + return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult); +} + // nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName); already_AddRefed nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString & propertyName, diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp index f0e867ebd2b..06598ffc1ef 100644 --- a/layout/style/nsCSSStyleSheet.cpp +++ b/layout/style/nsCSSStyleSheet.cpp @@ -381,7 +381,8 @@ nsMediaQuery::AppendToString(nsAString& aString) const NS_ASSERTION(expr.mValue.IsLengthUnit(), "bad unit"); // Use 'width' as a property that takes length values // written in the normal way. - expr.mValue.AppendToString(eCSSProperty_width, aString); + expr.mValue.AppendToString(eCSSProperty_width, aString, + nsCSSValue::eNormalized); break; case nsMediaFeature::eInteger: case nsMediaFeature::eBoolInteger: @@ -389,7 +390,8 @@ nsMediaQuery::AppendToString(nsAString& aString) const "bad unit"); // Use 'z-index' as a property that takes integer values // written without anything extra. - expr.mValue.AppendToString(eCSSProperty_z_index, aString); + expr.mValue.AppendToString(eCSSProperty_z_index, aString, + nsCSSValue::eNormalized); break; case nsMediaFeature::eFloat: { @@ -397,7 +399,8 @@ nsMediaQuery::AppendToString(nsAString& aString) const "bad unit"); // Use 'line-height' as a property that takes float values // written in the normal way. - expr.mValue.AppendToString(eCSSProperty_line_height, aString); + expr.mValue.AppendToString(eCSSProperty_line_height, aString, + nsCSSValue::eNormalized); } break; case nsMediaFeature::eIntRatio: @@ -410,9 +413,11 @@ nsMediaQuery::AppendToString(nsAString& aString) const "bad unit"); NS_ASSERTION(array->Item(1).GetUnit() == eCSSUnit_Integer, "bad unit"); - array->Item(0).AppendToString(eCSSProperty_z_index, aString); + array->Item(0).AppendToString(eCSSProperty_z_index, aString, + nsCSSValue::eNormalized); aString.AppendLiteral("/"); - array->Item(1).AppendToString(eCSSProperty_z_index, aString); + array->Item(1).AppendToString(eCSSProperty_z_index, aString, + nsCSSValue::eNormalized); } break; case nsMediaFeature::eResolution: diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 00dd8c04c03..0a0f5284bf8 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -121,9 +121,13 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) else if (eCSSUnit_Integer <= mUnit && mUnit <= eCSSUnit_EnumColor) { mValue.mInt = aCopy.mValue.mInt; } - else if (eCSSUnit_Color == mUnit) { + else if (IsIntegerColorUnit()) { mValue.mColor = aCopy.mValue.mColor; } + else if (IsFloatColorUnit()) { + mValue.mFloatColor = aCopy.mValue.mFloatColor; + mValue.mFloatColor->AddRef(); + } else if (UnitHasArrayValue()) { mValue.mArray = aCopy.mValue.mArray; mValue.mArray->AddRef(); @@ -207,9 +211,12 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const else if ((eCSSUnit_Integer <= mUnit) && (mUnit <= eCSSUnit_EnumColor)) { return mValue.mInt == aOther.mValue.mInt; } - else if (eCSSUnit_Color == mUnit) { + else if (IsIntegerColorUnit()) { return mValue.mColor == aOther.mValue.mColor; } + else if (IsFloatColorUnit()) { + return *mValue.mFloatColor == *aOther.mValue.mFloatColor; + } else if (UnitHasArrayValue()) { return *mValue.mArray == *aOther.mValue.mArray; } @@ -305,6 +312,8 @@ void nsCSSValue::DoReset() { if (UnitHasStringValue()) { mValue.mString->Release(); + } else if (IsFloatColorUnit()) { + mValue.mFloatColor->Release(); } else if (UnitHasArrayValue()) { mValue.mArray->Release(); } else if (eCSSUnit_URL == mUnit) { @@ -375,12 +384,32 @@ void nsCSSValue::SetStringValue(const nsString& aValue, } void nsCSSValue::SetColorValue(nscolor aValue) +{ + SetIntegerColorValue(aValue, eCSSUnit_RGBAColor); +} + +void nsCSSValue::SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit) { Reset(); - mUnit = eCSSUnit_Color; + mUnit = aUnit; + NS_ABORT_IF_FALSE(IsIntegerColorUnit(), "bad unit"); mValue.mColor = aValue; } +void nsCSSValue::SetFloatColorValue(float aComponent1, + float aComponent2, + float aComponent3, + float aAlpha, + nsCSSUnit aUnit) +{ + Reset(); + mUnit = aUnit; + NS_ABORT_IF_FALSE(IsFloatColorUnit(), "bad unit"); + mValue.mFloatColor = + new nsCSSValueFloatColor(aComponent1, aComponent2, aComponent3, aAlpha); + mValue.mFloatColor->AddRef(); +} + void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit) { Reset(); @@ -633,6 +662,15 @@ void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const } } +nscolor nsCSSValue::GetColorValue() const +{ + NS_ABORT_IF_FALSE(IsNumericColorUnit(), "not a color value"); + if (IsFloatColorUnit()) { + return mValue.mFloatColor->GetColorValue(mUnit); + } + return mValue.mColor; +} + bool nsCSSValue::IsNonTransparentColor() const { // We have the value in the form it was specified in at this point, so we @@ -640,7 +678,8 @@ bool nsCSSValue::IsNonTransparentColor() const // rgba notation. nsDependentString buf; return - (mUnit == eCSSUnit_Color && NS_GET_A(GetColorValue()) > 0) || + (IsIntegerColorUnit() && NS_GET_A(GetColorValue()) > 0) || + (IsFloatColorUnit() && mValue.mFloatColor->IsNonTransparentColor()) || (mUnit == eCSSUnit_Ident && !nsGkAtoms::transparent->Equals(GetStringValue(buf))) || (mUnit == eCSSUnit_EnumColor); @@ -699,9 +738,11 @@ nsCSSValue::BufferFromString(const nsString& aValue) namespace { struct CSSValueSerializeCalcOps { - CSSValueSerializeCalcOps(nsCSSProperty aProperty, nsAString& aResult) + CSSValueSerializeCalcOps(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aSerialization) : mProperty(aProperty), - mResult(aResult) + mResult(aResult), + mValueSerialization(aSerialization) { } @@ -721,24 +762,26 @@ struct CSSValueSerializeCalcOps { { NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Percent || aValue.IsLengthUnit(), "unexpected unit"); - aValue.AppendToString(mProperty, mResult); + aValue.AppendToString(mProperty, mResult, mValueSerialization); } void AppendNumber(const input_type& aValue) { NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit"); - aValue.AppendToString(mProperty, mResult); + aValue.AppendToString(mProperty, mResult, mValueSerialization); } private: nsCSSProperty mProperty; nsAString &mResult; + nsCSSValue::Serialization mValueSerialization; }; } // anonymous namespace void -nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const +nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult, + Serialization aSerialization) const { // eCSSProperty_UNKNOWN gets used for some recursive calls below. NS_ABORT_IF_FALSE((0 <= aProperty && @@ -805,7 +848,7 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const i == array->Count() - 1) ? eCSSProperty_list_style_type : aProperty; if (array->Item(i).GetUnit() != eCSSUnit_Null) { - array->Item(i).AppendToString(prop, aResult); + array->Item(i).AppendToString(prop, aResult, aSerialization); mark = true; } } @@ -863,7 +906,8 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const /* Now, step through the function contents, writing each of them as we go. */ for (size_t index = 1; index < array->Count(); ++index) { - array->Item(index).AppendToString(aProperty, aResult); + array->Item(index).AppendToString(aProperty, aResult, + aSerialization); /* If we're not at the final element, append a comma. */ if (index + 1 != array->Count()) @@ -875,7 +919,7 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const } else if (IsCalcUnit()) { NS_ABORT_IF_FALSE(GetUnit() == eCSSUnit_Calc, "unexpected unit"); - CSSValueSerializeCalcOps ops(aProperty, aResult); + CSSValueSerializeCalcOps ops(aProperty, aResult, aSerialization); css::SerializeCalc(*this, ops); } else if (eCSSUnit_Integer == unit) { @@ -979,32 +1023,56 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const NS_ABORT_IF_FALSE(false, "bad color value"); } } - else if (eCSSUnit_Color == unit) { - nscolor color = GetColorValue(); - if (color == NS_RGBA(0, 0, 0, 0)) { - // Use the strictest match for 'transparent' so we do correct - // round-tripping of all other rgba() values. - aResult.AppendLiteral("transparent"); - } else { - uint8_t a = NS_GET_A(color); - if (a < 255) { - aResult.AppendLiteral("rgba("); + else if (IsNumericColorUnit(unit)) { + if (aSerialization == eNormalized || + unit == eCSSUnit_RGBColor || + unit == eCSSUnit_RGBAColor) { + nscolor color = GetColorValue(); + if (aSerialization == eNormalized && + color == NS_RGBA(0, 0, 0, 0)) { + // Use the strictest match for 'transparent' so we do correct + // round-tripping of all other rgba() values. + aResult.AppendLiteral("transparent"); } else { - aResult.AppendLiteral("rgb("); - } + uint8_t a = NS_GET_A(color); + bool showAlpha = + (aSerialization == eNormalized && a < 255) || + (aSerialization == eAuthorSpecified && + unit == eCSSUnit_RGBAColor); + if (showAlpha) { + aResult.AppendLiteral("rgba("); + } else { + aResult.AppendLiteral("rgb("); + } - NS_NAMED_LITERAL_STRING(comma, ", "); + NS_NAMED_LITERAL_STRING(comma, ", "); - aResult.AppendInt(NS_GET_R(color), 10); - aResult.Append(comma); - aResult.AppendInt(NS_GET_G(color), 10); - aResult.Append(comma); - aResult.AppendInt(NS_GET_B(color), 10); - if (a < 255) { + aResult.AppendInt(NS_GET_R(color), 10); aResult.Append(comma); - aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a)); + aResult.AppendInt(NS_GET_G(color), 10); + aResult.Append(comma); + aResult.AppendInt(NS_GET_B(color), 10); + if (showAlpha) { + aResult.Append(comma); + aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a)); + } + aResult.Append(PRUnichar(')')); } - aResult.Append(PRUnichar(')')); + } else if (eCSSUnit_HexColor == unit) { + nscolor color = GetColorValue(); + aResult.Append('#'); + aResult.AppendPrintf("%02x", NS_GET_R(color)); + aResult.AppendPrintf("%02x", NS_GET_G(color)); + aResult.AppendPrintf("%02x", NS_GET_B(color)); + } else if (eCSSUnit_ShortHexColor == unit) { + nscolor color = GetColorValue(); + aResult.Append('#'); + aResult.AppendInt(NS_GET_R(color) / 0x11, 16); + aResult.AppendInt(NS_GET_G(color) / 0x11, 16); + aResult.AppendInt(NS_GET_B(color) / 0x11, 16); + } else { + MOZ_ASSERT(IsFloatColorUnit()); + mValue.mFloatColor->AppendToString(unit, aResult); } } else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) { @@ -1073,10 +1141,12 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const } else { NS_ABORT_IF_FALSE(gradient->GetRadiusX().GetUnit() != eCSSUnit_None, "bad unit for radial gradient explicit size"); - gradient->GetRadiusX().AppendToString(aProperty, aResult); + gradient->GetRadiusX().AppendToString(aProperty, aResult, + aSerialization); if (gradient->GetRadiusY().GetUnit() != eCSSUnit_None) { aResult.AppendLiteral(" "); - gradient->GetRadiusY().AppendToString(aProperty, aResult); + gradient->GetRadiusY().AppendToString(aProperty, aResult, + aSerialization); } needSep = true; } @@ -1092,16 +1162,16 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) { aResult.AppendLiteral(" "); gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position, - aResult); + aResult, aSerialization); } if (!(gradient->mBgPos.mYValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) { aResult.AppendLiteral(" "); gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position, - aResult); + aResult, aSerialization); } needSep = true; } else if (gradient->mAngle.GetUnit() != eCSSUnit_None) { - gradient->mAngle.AppendToString(aProperty, aResult); + gradient->mAngle.AppendToString(aProperty, aResult, aSerialization); needSep = true; } } else if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None || @@ -1115,18 +1185,18 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const } if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) { gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position, - aResult); + aResult, aSerialization); aResult.AppendLiteral(" "); } if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) { gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position, - aResult); + aResult, aSerialization); aResult.AppendLiteral(" "); } if (gradient->mAngle.GetUnit() != eCSSUnit_None) { NS_ABORT_IF_FALSE(gradient->mIsLegacySyntax, "angle is allowed only for legacy syntax"); - gradient->mAngle.AppendToString(aProperty, aResult); + gradient->mAngle.AppendToString(aProperty, aResult, aSerialization); } needSep = true; } @@ -1167,10 +1237,12 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const } for (uint32_t i = 0 ;;) { - gradient->mStops[i].mColor.AppendToString(aProperty, aResult); + gradient->mStops[i].mColor.AppendToString(aProperty, aResult, + aSerialization); if (gradient->mStops[i].mLocation.GetUnit() != eCSSUnit_None) { aResult.AppendLiteral(" "); - gradient->mStops[i].mLocation.AppendToString(aProperty, aResult); + gradient->mStops[i].mLocation.AppendToString(aProperty, aResult, + aSerialization); } if (++i == gradient->mStops.Length()) { break; @@ -1208,23 +1280,23 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const nsStyleUtil::SerializeFunctionalAlternates(altValues, out); aResult.Append(out); } else { - GetPairValue().AppendToString(aProperty, aResult); + GetPairValue().AppendToString(aProperty, aResult, aSerialization); } } else if (eCSSUnit_Triplet == unit) { - GetTripletValue().AppendToString(aProperty, aResult); + GetTripletValue().AppendToString(aProperty, aResult, aSerialization); } else if (eCSSUnit_Rect == unit) { - GetRectValue().AppendToString(aProperty, aResult); + GetRectValue().AppendToString(aProperty, aResult, aSerialization); } else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) { - GetListValue()->AppendToString(aProperty, aResult); + GetListValue()->AppendToString(aProperty, aResult, aSerialization); } else if (eCSSUnit_SharedList == unit) { - GetSharedListValue()->AppendToString(aProperty, aResult); + GetSharedListValue()->AppendToString(aProperty, aResult, aSerialization); } else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) { switch (aProperty) { case eCSSProperty_font_feature_settings: nsStyleUtil::AppendFontFeatureSettings(*this, aResult); break; default: - GetPairListValue()->AppendToString(aProperty, aResult); + GetPairListValue()->AppendToString(aProperty, aResult, aSerialization); break; } } @@ -1267,8 +1339,15 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const case eCSSUnit_Calc_Divided: break; case eCSSUnit_Integer: break; case eCSSUnit_Enumerated: break; - case eCSSUnit_EnumColor: break; - case eCSSUnit_Color: break; + case eCSSUnit_EnumColor: break; + case eCSSUnit_RGBColor: break; + case eCSSUnit_RGBAColor: break; + case eCSSUnit_HexColor: break; + case eCSSUnit_ShortHexColor: break; + case eCSSUnit_PercentageRGBColor: break; + case eCSSUnit_PercentageRGBAColor: break; + case eCSSUnit_HSLColor: break; + case eCSSUnit_HSLAColor: break; case eCSSUnit_Percent: aResult.Append(PRUnichar('%')); break; case eCSSUnit_Number: break; case eCSSUnit_Gradient: break; @@ -1426,8 +1505,19 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const case eCSSUnit_EnumColor: break; - // Color: nothing extra to measure. - case eCSSUnit_Color: + // Integer Color: nothing extra to measure. + case eCSSUnit_RGBColor: + case eCSSUnit_RGBAColor: + case eCSSUnit_HexColor: + case eCSSUnit_ShortHexColor: + break; + + // Float Color + case eCSSUnit_PercentageRGBColor: + case eCSSUnit_PercentageRGBAColor: + case eCSSUnit_HSLColor: + case eCSSUnit_HSLAColor: + n += mValue.mFloatColor->SizeOfIncludingThis(aMallocSizeOf); break; // Float: nothing extra to measure. @@ -1497,11 +1587,12 @@ nsCSSValueList::CloneInto(nsCSSValueList* aList) const } void -nsCSSValueList::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const +nsCSSValueList::AppendToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aSerialization) const { const nsCSSValueList* val = this; for (;;) { - val->mValue.AppendToString(aProperty, aResult); + val->mValue.AppendToString(aProperty, aResult, aSerialization); val = val->mNext; if (!val) break; @@ -1561,10 +1652,11 @@ nsCSSValueSharedList::~nsCSSValueSharedList() } void -nsCSSValueSharedList::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const +nsCSSValueSharedList::AppendToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aSerialization) const { if (mHead) { - mHead->AppendToString(aProperty, aResult); + mHead->AppendToString(aProperty, aResult, aSerialization); } } @@ -1606,7 +1698,8 @@ nsCSSRect::~nsCSSRect() } void -nsCSSRect::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const +nsCSSRect::AppendToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aSerialization) const { NS_ABORT_IF_FALSE(mTop.GetUnit() != eCSSUnit_Null && mTop.GetUnit() != eCSSUnit_Inherit && @@ -1619,24 +1712,24 @@ nsCSSRect::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const eCSSProperty_border_image_outset == aProperty) { NS_NAMED_LITERAL_STRING(space, " "); - mTop.AppendToString(aProperty, aResult); + mTop.AppendToString(aProperty, aResult, aSerialization); aResult.Append(space); - mRight.AppendToString(aProperty, aResult); + mRight.AppendToString(aProperty, aResult, aSerialization); aResult.Append(space); - mBottom.AppendToString(aProperty, aResult); + mBottom.AppendToString(aProperty, aResult, aSerialization); aResult.Append(space); - mLeft.AppendToString(aProperty, aResult); + mLeft.AppendToString(aProperty, aResult, aSerialization); } else { NS_NAMED_LITERAL_STRING(comma, ", "); aResult.AppendLiteral("rect("); - mTop.AppendToString(aProperty, aResult); + mTop.AppendToString(aProperty, aResult, aSerialization); aResult.Append(comma); - mRight.AppendToString(aProperty, aResult); + mRight.AppendToString(aProperty, aResult, aSerialization); aResult.Append(comma); - mBottom.AppendToString(aProperty, aResult); + mBottom.AppendToString(aProperty, aResult, aSerialization); aResult.Append(comma); - mLeft.AppendToString(aProperty, aResult); + mLeft.AppendToString(aProperty, aResult, aSerialization); aResult.Append(PRUnichar(')')); } } @@ -1675,12 +1768,13 @@ static_assert(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 && void nsCSSValuePair::AppendToString(nsCSSProperty aProperty, - nsAString& aResult) const + nsAString& aResult, + nsCSSValue::Serialization aSerialization) const { - mXValue.AppendToString(aProperty, aResult); + mXValue.AppendToString(aProperty, aResult, aSerialization); if (mYValue.GetUnit() != eCSSUnit_Null) { aResult.Append(PRUnichar(' ')); - mYValue.AppendToString(aProperty, aResult); + mYValue.AppendToString(aProperty, aResult, aSerialization); } } @@ -1706,15 +1800,16 @@ nsCSSValuePair_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) co void nsCSSValueTriplet::AppendToString(nsCSSProperty aProperty, - nsAString& aResult) const + nsAString& aResult, + nsCSSValue::Serialization aSerialization) const { - mXValue.AppendToString(aProperty, aResult); + mXValue.AppendToString(aProperty, aResult, aSerialization); if (mYValue.GetUnit() != eCSSUnit_Null) { aResult.Append(PRUnichar(' ')); - mYValue.AppendToString(aProperty, aResult); + mYValue.AppendToString(aProperty, aResult, aSerialization); if (mZValue.GetUnit() != eCSSUnit_Null) { aResult.Append(PRUnichar(' ')); - mZValue.AppendToString(aProperty, aResult); + mZValue.AppendToString(aProperty, aResult, aSerialization); } } } @@ -1753,19 +1848,20 @@ nsCSSValuePairList::Clone() const void nsCSSValuePairList::AppendToString(nsCSSProperty aProperty, - nsAString& aResult) const + nsAString& aResult, + nsCSSValue::Serialization aSerialization) const { const nsCSSValuePairList* item = this; for (;;) { NS_ABORT_IF_FALSE(item->mXValue.GetUnit() != eCSSUnit_Null, "unexpected null unit"); - item->mXValue.AppendToString(aProperty, aResult); + item->mXValue.AppendToString(aProperty, aResult, aSerialization); if (item->mXValue.GetUnit() != eCSSUnit_Inherit && item->mXValue.GetUnit() != eCSSUnit_Initial && item->mXValue.GetUnit() != eCSSUnit_Unset && item->mYValue.GetUnit() != eCSSUnit_Null) { aResult.Append(PRUnichar(' ')); - item->mYValue.AppendToString(aProperty, aResult); + item->mYValue.AppendToString(aProperty, aResult, aSerialization); } item = item->mNext; if (!item) @@ -2052,6 +2148,93 @@ nsCSSValueTokenStream::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) return n; } +// --- nsCSSValueFloatColor ------------- + +bool +nsCSSValueFloatColor::operator==(nsCSSValueFloatColor& aOther) const +{ + return mComponent1 == aOther.mComponent1 && + mComponent2 == aOther.mComponent2 && + mComponent3 == aOther.mComponent3 && + mAlpha == aOther.mAlpha; +} + +nscolor +nsCSSValueFloatColor::GetColorValue(nsCSSUnit aUnit) const +{ + MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit"); + + if (aUnit == eCSSUnit_PercentageRGBColor || + aUnit == eCSSUnit_PercentageRGBAColor) { + return NS_RGBA(NSToIntRound(mComponent1 * 255.0f), + NSToIntRound(mComponent2 * 255.0f), + NSToIntRound(mComponent3 * 255.0f), + NSToIntRound(mAlpha * 255.0f)); + } + + // HSL color + MOZ_ASSERT(aUnit == eCSSUnit_HSLColor || + aUnit == eCSSUnit_HSLAColor); + nscolor hsl = NS_HSL2RGB(mComponent1, mComponent2, mComponent3); + return NS_RGBA(NS_GET_R(hsl), + NS_GET_G(hsl), + NS_GET_B(hsl), + NSToIntRound(mAlpha * 255.0f)); +} + +bool +nsCSSValueFloatColor::IsNonTransparentColor() const +{ + return mAlpha > 0.0f; +} + +void +nsCSSValueFloatColor::AppendToString(nsCSSUnit aUnit, nsAString& aResult) const +{ + MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit"); + + bool hasAlpha = aUnit == eCSSUnit_PercentageRGBAColor || + aUnit == eCSSUnit_HSLAColor; + bool isHSL = aUnit == eCSSUnit_HSLColor || + aUnit == eCSSUnit_HSLAColor; + + if (isHSL) { + aResult.AppendLiteral("hsl"); + } else { + aResult.AppendLiteral("rgb"); + } + if (hasAlpha) { + aResult.AppendLiteral("a("); + } else { + aResult.Append('('); + } + if (isHSL) { + aResult.AppendFloat(mComponent1 * 360.0f); + aResult.AppendLiteral(", "); + } else { + aResult.AppendFloat(mComponent1 * 100.0f); + aResult.AppendLiteral("%, "); + } + aResult.AppendFloat(mComponent2 * 100.0f); + aResult.AppendLiteral("%, "); + aResult.AppendFloat(mComponent3 * 100.0f); + if (hasAlpha) { + aResult.AppendLiteral("%, "); + aResult.AppendFloat(mAlpha); + aResult.Append(')'); + } else { + aResult.AppendLiteral("%)"); + } +} + +size_t +nsCSSValueFloatColor::SizeOfIncludingThis( + mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t n = aMallocSizeOf(this); + return n; +} + // --- nsCSSCornerSizes ----------------- nsCSSCornerSizes::nsCSSCornerSizes(void) @@ -2092,4 +2275,3 @@ nsCSSCornerSizes::corners[4] = { &nsCSSCornerSizes::mBottomRight, &nsCSSCornerSizes::mBottomLeft, }; - diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index 29c4b035e38..bb4d1bec80a 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -209,8 +209,15 @@ enum nsCSSUnit { eCSSUnit_Integer = 70, // (int) simple value eCSSUnit_Enumerated = 71, // (int) value has enumerated meaning - eCSSUnit_EnumColor = 80, // (int) enumerated color (kColorKTable) - eCSSUnit_Color = 81, // (nscolor) an RGBA value + eCSSUnit_EnumColor = 80, // (int) enumerated color (kColorKTable) + eCSSUnit_RGBColor = 81, // (nscolor) an opaque RGBA value specified as rgb() + eCSSUnit_RGBAColor = 82, // (nscolor) an RGBA value specified as rgba() + eCSSUnit_HexColor = 83, // (nscolor) an opaque RGBA value specified as #rrggbb + eCSSUnit_ShortHexColor = 84, // (nscolor) an opaque RGBA value specified as #rgb + eCSSUnit_PercentageRGBColor = 85, // (nsCSSValueFloatColor*) + eCSSUnit_PercentageRGBAColor = 86, // (nsCSSValueFloatColor*) + eCSSUnit_HSLColor = 87, // (nsCSSValueFloatColor*) + eCSSUnit_HSLAColor = 88, // (nsCSSValueFloatColor*) eCSSUnit_Percent = 90, // (float) 1.0 == 100%) value is percentage of something eCSSUnit_Number = 91, // (float) value is numeric (usually multiplier, different behavior that percent) @@ -267,6 +274,7 @@ struct nsCSSValuePairList; struct nsCSSValuePairList_heap; struct nsCSSValueTriplet; struct nsCSSValueTriplet_heap; +class nsCSSValueFloatColor; class nsCSSValue { public: @@ -303,11 +311,15 @@ public: return !(*this == aOther); } + // Enum for AppendToString's aValueSerialization argument. + enum Serialization { eNormalized, eAuthorSpecified }; + /** * Serialize |this| as a specified value for |aProperty| and append * it to |aResult|. */ - void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const; + void AppendToString(nsCSSProperty aProperty, nsAString& aResult, + Serialization aValueSerialization) const; nsCSSUnit GetUnit() const { return mUnit; } bool IsLengthUnit() const @@ -349,6 +361,35 @@ public: bool UnitHasArrayValue() const { return eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Calc_Divided; } + // Checks for the nsCSSValue being of a particular type of color unit: + // + // - IsIntegerColorUnit returns true for: + // eCSSUnit_RGBColor -- rgb(int,int,int) + // eCSSUnit_RGBAColor -- rgba(int,int,int,float) + // eCSSUnit_HexColor -- #rrggbb + // eCSSUnit_ShortHexColor -- #rgb + // + // - IsFLoatColorUnit returns true for: + // eCSSUnit_PercentageRGBColor -- rgb(%,%,%) + // eCSSUnit_PercentageRGBAColor -- rgba(%,%,%,float) + // eCSSUnit_HSLColor -- hsl(float,%,%) + // eCSSUnit_HSLAColor -- hsla(float,%,%,float) + // + // - IsNumericColorUnit returns true for any of the above units. + // + // Note that color keywords and system colors are represented by + // eCSSUnit_EnumColor and eCSSUnit_Ident. + bool IsIntegerColorUnit() const { return IsIntegerColorUnit(mUnit); } + bool IsFloatColorUnit() const { return IsFloatColorUnit(mUnit); } + bool IsNumericColorUnit() const { return IsNumericColorUnit(mUnit); } + static bool IsIntegerColorUnit(nsCSSUnit aUnit) + { return eCSSUnit_RGBColor <= aUnit && aUnit <= eCSSUnit_ShortHexColor; } + static bool IsFloatColorUnit(nsCSSUnit aUnit) + { return eCSSUnit_PercentageRGBColor <= aUnit && + aUnit <= eCSSUnit_HSLAColor; } + static bool IsNumericColorUnit(nsCSSUnit aUnit) + { return IsIntegerColorUnit(aUnit) || IsFloatColorUnit(aUnit); } + int32_t GetIntValue() const { NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Integer || @@ -402,12 +443,7 @@ public: return GetBufferValue(mValue.mString); } - nscolor GetColorValue() const - { - NS_ABORT_IF_FALSE((mUnit == eCSSUnit_Color), "not a color value"); - return mValue.mColor; - } - + nscolor GetColorValue() const; bool IsNonTransparentColor() const; Array* GetArrayValue() const @@ -503,6 +539,11 @@ public: void SetFloatValue(float aValue, nsCSSUnit aUnit); void SetStringValue(const nsString& aValue, nsCSSUnit aUnit); void SetColorValue(nscolor aValue); + void SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit); + void SetFloatColorValue(float aComponent1, + float aComponent2, + float aComponent3, + float aAlpha, nsCSSUnit aUnit); void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit); void SetURLValue(mozilla::css::URLValue* aURI); void SetImageValue(mozilla::css::ImageValue* aImage); @@ -573,6 +614,7 @@ protected: nsCSSValueSharedList* mSharedList; nsCSSValuePairList_heap* mPairList; nsCSSValuePairList* mPairListDependent; + nsCSSValueFloatColor* mFloatColor; } mValue; }; @@ -687,7 +729,8 @@ struct nsCSSValueList { nsCSSValueList* Clone() const; // makes a deep copy void CloneInto(nsCSSValueList* aList) const; // makes a deep copy into aList - void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const; + void AppendToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aValueSerialization) const; bool operator==(nsCSSValueList const& aOther) const; bool operator!=(const nsCSSValueList& aOther) const @@ -737,7 +780,8 @@ struct nsCSSValueSharedList { NS_INLINE_DECL_REFCOUNTING(nsCSSValueSharedList) - void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const; + void AppendToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aValueSerialization) const; bool operator==(nsCSSValueSharedList const& aOther) const; bool operator!=(const nsCSSValueSharedList& aOther) const @@ -777,7 +821,8 @@ struct nsCSSRect { nsCSSRect(const nsCSSRect& aCopy); ~nsCSSRect(); - void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const; + void AppendToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aValueSerialization) const; bool operator==(const nsCSSRect& aOther) const { return mTop == aOther.mTop && @@ -906,7 +951,8 @@ struct nsCSSValuePair { mYValue.GetUnit() != eCSSUnit_Null; } - void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const; + void AppendToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aValueSerialization) const; size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; @@ -991,7 +1037,8 @@ struct nsCSSValueTriplet { mZValue.GetUnit() != eCSSUnit_Null; } - void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const; + void AppendToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aValueSerialization) const; nsCSSValue mXValue; nsCSSValue mYValue; @@ -1048,7 +1095,8 @@ struct nsCSSValuePairList { ~nsCSSValuePairList(); nsCSSValuePairList* Clone() const; // makes a deep copy - void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const; + void AppendToString(nsCSSProperty aProperty, nsAString& aResult, + nsCSSValue::Serialization aValueSerialization) const; bool operator==(const nsCSSValuePairList& aOther) const; bool operator!=(const nsCSSValuePairList& aOther) const @@ -1285,6 +1333,46 @@ private: nsCSSValueTokenStream& operator=(const nsCSSValueTokenStream& aOther) MOZ_DELETE; }; +class nsCSSValueFloatColor { +public: + nsCSSValueFloatColor(float aComponent1, float aComponent2, float aComponent3, + float aAlpha) + : mComponent1(aComponent1) + , mComponent2(aComponent2) + , mComponent3(aComponent3) + , mAlpha(aAlpha) + { + MOZ_COUNT_CTOR(nsCSSValueFloatColor); + } + + ~nsCSSValueFloatColor() + { + MOZ_COUNT_DTOR(nsCSSValueFloatColor); + } + + bool operator==(nsCSSValueFloatColor& aOther) const; + + nscolor GetColorValue(nsCSSUnit aUnit) const; + bool IsNonTransparentColor() const; + + void AppendToString(nsCSSUnit aUnit, nsAString& aResult) const; + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + + NS_INLINE_DECL_REFCOUNTING(nsCSSValueFloatColor) + +private: + // FIXME: We should not be clamping specified RGB color components. + float mComponent1; // 0..1 for RGB, 0..360 for HSL + float mComponent2; // 0..1 + float mComponent3; // 0..1 + float mAlpha; // 0..1 + + nsCSSValueFloatColor(const nsCSSValueFloatColor& aOther) MOZ_DELETE; + nsCSSValueFloatColor& operator=(const nsCSSValueFloatColor& aOther) + MOZ_DELETE; +}; + struct nsCSSCornerSizes { nsCSSCornerSizes(void); nsCSSCornerSizes(const nsCSSCornerSizes& aCopy); diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 6e6f714bb91..ad768ab1f20 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -417,6 +417,15 @@ nsComputedDOMStyle::GetPropertyValue(const nsAString& aPropertyName, return NS_OK; } +NS_IMETHODIMP +nsComputedDOMStyle::GetAuthoredPropertyValue(const nsAString& aPropertyName, + nsAString& aReturn) +{ + // Authored style doesn't make sense to return from computed DOM style, + // so just return whatever GetPropertyValue() returns. + return GetPropertyValue(aPropertyName, aReturn); +} + /* static */ already_AddRefed nsComputedDOMStyle::GetStyleContextForElement(Element* aElement, diff --git a/layout/style/nsDOMCSSDeclaration.cpp b/layout/style/nsDOMCSSDeclaration.cpp index 10d233828db..b358b2d7537 100644 --- a/layout/style/nsDOMCSSDeclaration.cpp +++ b/layout/style/nsDOMCSSDeclaration.cpp @@ -184,6 +184,31 @@ nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName, return GetPropertyValue(propID, aReturn); } +NS_IMETHODIMP +nsDOMCSSDeclaration::GetAuthoredPropertyValue(const nsAString& aPropertyName, + nsAString& aReturn) +{ + const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName, + nsCSSProps::eEnabled); + if (propID == eCSSProperty_UNKNOWN) { + aReturn.Truncate(); + return NS_OK; + } + + if (propID == eCSSPropertyExtra_variable) { + GetCustomPropertyValue(aPropertyName, aReturn); + return NS_OK; + } + + css::Declaration* decl = GetCSSDeclaration(false); + if (!decl) { + return NS_ERROR_FAILURE; + } + + decl->GetAuthoredValue(propID, aReturn); + return NS_OK; +} + NS_IMETHODIMP nsDOMCSSDeclaration::GetPropertyPriority(const nsAString& aPropertyName, nsAString& aReturn) diff --git a/layout/style/nsICSSDeclaration.h b/layout/style/nsICSSDeclaration.h index 197cfce1a12..dcd5d1b3b7e 100644 --- a/layout/style/nsICSSDeclaration.h +++ b/layout/style/nsICSSDeclaration.h @@ -50,6 +50,9 @@ public: NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID, nsAString& aValue) = 0; + NS_IMETHOD GetAuthoredPropertyValue(const nsAString& aPropName, + nsAString& aValue) = 0; + /** * Method analogous to nsIDOMCSSStyleDeclaration::SetProperty. This * method does NOT allow setting a priority (the priority will @@ -125,6 +128,10 @@ public: mozilla::ErrorResult& rv) { rv = GetPropertyValue(aPropName, aValue); } + void GetAuthoredPropertyValue(const nsAString& aPropName, nsString& aValue, + mozilla::ErrorResult& rv) { + rv = GetAuthoredPropertyValue(aPropName, aValue); + } void GetPropertyPriority(const nsAString& aPropName, nsString& aPriority) { GetPropertyPriority(aPropName, static_cast(aPriority)); } @@ -145,10 +152,12 @@ public: NS_DEFINE_STATIC_IID_ACCESSOR(nsICSSDeclaration, NS_ICSSDECLARATION_IID) -#define NS_DECL_NSICSSDECLARATION \ - NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID, \ - nsAString& aValue); \ - NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID, \ +#define NS_DECL_NSICSSDECLARATION \ + NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID, \ + nsAString& aValue); \ + NS_IMETHOD GetAuthoredPropertyValue(const nsAString& aPropName, \ + nsAString& aValue); \ + NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID, \ const nsAString& aValue); #define NS_DECL_NSIDOMCSSSTYLEDECLARATION_HELPER \ diff --git a/layout/style/nsLayoutStylesheetCache.cpp b/layout/style/nsLayoutStylesheetCache.cpp index 3fd7879e912..226560658fc 100644 --- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -16,8 +16,8 @@ #include "nsIXULRuntime.h" #include "nsCSSStyleSheet.h" -NS_IMPL_ISUPPORTS_INHERITED1( - nsLayoutStylesheetCache, MemoryUniReporter, nsIObserver) +NS_IMPL_ISUPPORTS2( + nsLayoutStylesheetCache, nsIObserver, nsIMemoryReporter) nsresult nsLayoutStylesheetCache::Observe(nsISupports* aSubject, @@ -142,12 +142,19 @@ nsLayoutStylesheetCache::Shutdown() NS_IF_RELEASE(gStyleCache); } -int64_t -nsLayoutStylesheetCache::Amount() +MOZ_DEFINE_MALLOC_SIZE_OF(LayoutStylesheetCacheMallocSizeOf) + +NS_IMETHODIMP +nsLayoutStylesheetCache::CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData) { - return SizeOfIncludingThis(MallocSizeOf); + return MOZ_COLLECT_REPORT( + "explicit/layout/style-sheet-cache", KIND_HEAP, UNITS_BYTES, + SizeOfIncludingThis(LayoutStylesheetCacheMallocSizeOf), + "Memory used for some built-in style sheets."); } + size_t nsLayoutStylesheetCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { @@ -171,9 +178,6 @@ nsLayoutStylesheetCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf } nsLayoutStylesheetCache::nsLayoutStylesheetCache() - : MemoryUniReporter("explicit/layout/style-sheet-cache", - KIND_HEAP, UNITS_BYTES, - "Memory used for some built-in style sheets.") { nsCOMPtr obsSvc = mozilla::services::GetObserverService(); @@ -212,14 +216,14 @@ nsLayoutStylesheetCache::nsLayoutStylesheetCache() nsLayoutStylesheetCache::~nsLayoutStylesheetCache() { - UnregisterWeakMemoryReporter(this); + mozilla::UnregisterWeakMemoryReporter(this); gStyleCache = nullptr; } void nsLayoutStylesheetCache::InitMemoryReporter() { - RegisterWeakMemoryReporter(this); + mozilla::RegisterWeakMemoryReporter(this); } void diff --git a/layout/style/nsLayoutStylesheetCache.h b/layout/style/nsLayoutStylesheetCache.h index 5bf15e56ff9..83c22052724 100644 --- a/layout/style/nsLayoutStylesheetCache.h +++ b/layout/style/nsLayoutStylesheetCache.h @@ -24,11 +24,12 @@ class Loader; } class nsLayoutStylesheetCache MOZ_FINAL - : public mozilla::MemoryUniReporter - , public nsIObserver + : public nsIObserver + , public nsIMemoryReporter { NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER + NS_DECL_NSIMEMORYREPORTER static nsCSSStyleSheet* ScrollbarsSheet(); static nsCSSStyleSheet* FormsSheet(); @@ -40,7 +41,6 @@ class nsLayoutStylesheetCache MOZ_FINAL static void Shutdown(); - int64_t Amount() MOZ_OVERRIDE; size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; private: diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 348e5961b5b..91a9b758480 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -850,7 +850,7 @@ static bool SetColor(const nsCSSValue& aValue, const nscolor aParentColor, bool result = false; nsCSSUnit unit = aValue.GetUnit(); - if (eCSSUnit_Color == unit) { + if (aValue.IsNumericColorUnit()) { aResult = aValue.GetColorValue(); result = true; } diff --git a/layout/style/nsStyleAnimation.cpp b/layout/style/nsStyleAnimation.cpp index 2d6f2f0ac4c..a6e17862e81 100644 --- a/layout/style/nsStyleAnimation.cpp +++ b/layout/style/nsStyleAnimation.cpp @@ -752,7 +752,9 @@ nsStyleAnimation::ComputeDistance(nsCSSProperty aProperty, // (1) GetUnit() == eCSSUnit_Null // (2) GetUnit() == eCSSUnit_Enumerated && // GetIntValue() == NS_STYLE_BOX_SHADOW_INSET - NS_ABORT_IF_FALSE(color1.GetUnit() == color2.GetUnit() && + NS_ABORT_IF_FALSE(((color1.IsNumericColorUnit() && + color2.IsNumericColorUnit()) || + (color1.GetUnit() == color2.GetUnit())) && inset1 == inset2, "AddWeighted should have failed"); } @@ -2685,7 +2687,7 @@ nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty, return false; } - val.AppendToString(aProperty, aSpecifiedValue); + val.AppendToString(aProperty, aSpecifiedValue, nsCSSValue::eNormalized); return true; } diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 3e313777044..a63dd7d7a96 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -460,8 +460,11 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther, if (this##struct_) { \ const nsStyle##struct_* other##struct_ = aOther->Style##struct_(); \ nsChangeHint maxDifference = nsStyle##struct_::MaxDifference(); \ + nsChangeHint maxDifferenceNeverInherited = \ + nsStyle##struct_::MaxDifferenceNeverInherited(); \ if ((compare || \ - (maxDifference & aParentHintsNotHandledForDescendants)) && \ + (NS_SubtractHint(maxDifference, maxDifferenceNeverInherited) & \ + aParentHintsNotHandledForDescendants)) && \ !NS_IsHintSubset(maxDifference, hint) && \ this##struct_ != other##struct_) { \ NS_ASSERTION(NS_IsHintSubset( \ @@ -864,3 +867,15 @@ nsStyleContext::FreeAllocations(nsPresContext *aPresContext) shell->FreeMisc(alloc->mSize, alloc); } } + +#ifdef DEBUG +/* static */ void +nsStyleContext::AssertStyleStructMaxDifferenceValid() +{ +#define STYLE_STRUCT(name, checkdata_cb) \ + MOZ_ASSERT(NS_IsHintSubset(nsStyle##name::MaxDifferenceNeverInherited(), \ + nsStyle##name::MaxDifference())); +#include "nsStyleStructList.h" +#undef STYLE_STRUCT +} +#endif diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index d0b94ee61c5..f6141aba26f 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -340,6 +340,7 @@ public: #ifdef DEBUG void List(FILE* out, int32_t aIndent); + static void AssertStyleStructMaxDifferenceValid(); #endif protected: diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 42e0f2b4dd6..7e5e37636d5 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -79,6 +79,12 @@ public: static nsChangeHint MaxDifference() { return NS_STYLE_HINT_REFLOW; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } static nsChangeHint CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2); static nscoord ZoomText(nsPresContext* aPresContext, nscoord aSize); @@ -305,6 +311,11 @@ struct nsStyleColor { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_VISUAL; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics at all. + return nsChangeHint(0); + } void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW { return aContext->AllocateFromShell(sz); @@ -333,6 +344,11 @@ struct nsStyleBackground { static nsChangeHint MaxDifference() { return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics at all. + return nsChangeHint(0); + } struct Position; friend struct Position; @@ -561,6 +577,11 @@ struct nsStyleMargin { NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics, nsChangeHint_NeedDirtyReflow)); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and + // nsChangeHint_NeedReflow as inherited hints. + return nsChangeHint(0); + } nsStyleSides mMargin; // [reset] coord, percent, calc, auto @@ -596,6 +617,11 @@ struct nsStylePadding { return NS_SubtractHint(NS_STYLE_HINT_REFLOW, nsChangeHint_ClearDescendantIntrinsics); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference can return nsChangeHint_ClearAncestorIntrinsics as an + // inherited hint. + return nsChangeHint(0); + } nsStyleSides mPadding; // [reset] coord, percent, calc @@ -773,6 +799,12 @@ struct nsStyleBorder { return NS_CombineHint(NS_STYLE_HINT_REFLOW, nsChangeHint_BorderStyleNoneChange); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } void EnsureBorderColors() { if (!mBorderColors) { @@ -995,6 +1027,12 @@ struct nsStyleOutline { return NS_CombineHint(nsChangeHint_AllReflowHints, nsChangeHint_RepaintFrame); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } nsStyleCorners mOutlineRadius; // [reset] coord, percent, calc @@ -1080,6 +1118,12 @@ struct nsStyleList { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } imgRequestProxy* GetListStyleImage() const { return mListStyleImage; } void SetListStyleImage(imgRequestProxy* aReq) @@ -1119,6 +1163,11 @@ struct nsStylePosition { nsChangeHint(nsChangeHint_RecomputePosition | nsChangeHint_UpdateOverflow)); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and + // nsChangeHint_NeedReflow as inherited hints. + return nsChangeHint(0); + } nsStyleSides mOffset; // [reset] coord, percent, calc, auto nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto @@ -1284,6 +1333,12 @@ struct nsStyleTextReset { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_REFLOW; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } nsStyleCoord mVerticalAlign; // [reset] coord, percent, calc, enum (see nsStyleConsts.h) nsStyleTextOverflow mTextOverflow; // [reset] enum, string @@ -1313,6 +1368,12 @@ struct nsStyleText { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } uint8_t mTextAlign; // [inherited] see nsStyleConsts.h uint8_t mTextAlignLast; // [inherited] see nsStyleConsts.h @@ -1488,6 +1549,12 @@ struct nsStyleVisibility { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } nsStyleImageOrientation mImageOrientation; // [inherited] uint8_t mDirection; // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_* @@ -1695,6 +1762,11 @@ struct nsStyleDisplay { nsChangeHint_UpdateOverflow | nsChangeHint_AddOrRemoveTransform); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and + // nsChangeHint_NeedReflow as inherited hints. + return nsChangeHint(0); + } // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and // mBinding->mOriginPrincipal. @@ -1864,6 +1936,12 @@ struct nsStyleTable { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } uint8_t mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_* uint8_t mFrame; // [reset] see nsStyleConsts.h NS_STYLE_TABLE_FRAME_* @@ -1888,6 +1966,12 @@ struct nsStyleTableBorder { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } nscoord mBorderSpacingX;// [inherited] nscoord mBorderSpacingY;// [inherited] @@ -1978,6 +2062,12 @@ struct nsStyleQuotes { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } uint32_t QuotesCount(void) const { return mQuotesCount; } // [inherited] @@ -2045,6 +2135,12 @@ struct nsStyleContent { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } uint32_t ContentCount(void) const { return mContentCount; } // [reset] @@ -2149,6 +2245,12 @@ struct nsStyleUIReset { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } uint8_t mUserSelect; // [reset] (selection-style) uint8_t mForceBrokenImageIcon; // [reset] (0 if not forcing, otherwise forcing) @@ -2202,6 +2304,12 @@ struct nsStyleUserInterface { static nsChangeHint MaxDifference() { return nsChangeHint(nsChangeHint_UpdateCursor | NS_STYLE_HINT_FRAMECHANGE); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } uint8_t mUserInput; // [inherited] uint8_t mUserModify; // [inherited] (modify-content) @@ -2237,6 +2345,12 @@ struct nsStyleXUL { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } float mBoxFlex; // [reset] see nsStyleConsts.h uint32_t mBoxOrdinal; // [reset] see nsStyleConsts.h @@ -2264,6 +2378,12 @@ struct nsStyleColumn { static nsChangeHint MaxDifference() { return NS_STYLE_HINT_FRAMECHANGE; } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } /** * This is the maximum number of columns we can process. It's used in both @@ -2349,6 +2469,11 @@ struct nsStyleSVG { NS_CombineHint(nsChangeHint_NeedReflow, nsChangeHint_NeedDirtyReflow)), // XXX remove nsChangeHint_NeedDirtyReflow: bug 876085 nsChangeHint_RepaintFrame); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow as an inherited hint + // and never returns nsChangeHint_ClearAncestorIntrinsics at all. + return nsChangeHint_NeedReflow; + } nsStyleSVGPaint mFill; // [inherited] nsStyleSVGPaint mStroke; // [inherited] @@ -2477,6 +2602,12 @@ struct nsStyleSVGReset { return NS_CombineHint(nsChangeHint_UpdateEffects, NS_CombineHint(nsChangeHint_UpdateOverflow, NS_STYLE_HINT_REFLOW)); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics as inherited hints. + return NS_CombineHint(nsChangeHint_NeedReflow, + nsChangeHint_ClearAncestorIntrinsics); + } // The backend only supports one SVG reference right now. // Eventually, it will support multiple chained SVG reference filters and CSS @@ -2519,6 +2650,11 @@ struct nsStyleVariables { static nsChangeHint MaxDifference() { return nsChangeHint(0); } + static nsChangeHint MaxDifferenceNeverInherited() { + // CalcDifference never returns nsChangeHint_NeedReflow or + // nsChangeHint_ClearAncestorIntrinsics at all. + return nsChangeHint(0); + } mozilla::CSSVariableValues mVariables; }; diff --git a/layout/style/test/chrome/chrome.ini b/layout/style/test/chrome/chrome.ini index 1e1622b7ebb..d19b82afeed 100644 --- a/layout/style/test/chrome/chrome.ini +++ b/layout/style/test/chrome/chrome.ini @@ -6,6 +6,7 @@ support-files = hover_helper.html [test_additional_sheets.html] +[test_author_specified_style.html] [test_bug535806.xul] [test_hover.html] [test_moz_document_rules.html] diff --git a/layout/style/test/chrome/test_author_specified_style.html b/layout/style/test/chrome/test_author_specified_style.html new file mode 100644 index 00000000000..12e4fc55347 --- /dev/null +++ b/layout/style/test/chrome/test_author_specified_style.html @@ -0,0 +1,44 @@ + +Test for CSSStyleDeclaration.getAuthoredPropertyValue() + + + diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 020558edcee..50f9c29b31b 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -1050,14 +1050,6 @@ PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents, return strokeExtents; } -/*static*/ gfxRect -nsSVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents, - nsSVGGeometryFrame* aFrame, - const gfxMatrix& aMatrix) -{ - return ::PathExtentsToMaxStrokeExtents(aPathExtents, aFrame, 0.5, aMatrix); -} - /*static*/ gfxRect nsSVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents, nsTextFrame* aFrame, diff --git a/layout/svg/nsSVGUtils.h b/layout/svg/nsSVGUtils.h index 9a639fa2ade..b660cf4395a 100644 --- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -42,7 +42,6 @@ class nsStyleCoord; class nsSVGDisplayContainerFrame; class nsSVGElement; class nsSVGEnum; -class nsSVGGeometryFrame; class nsSVGLength2; class nsSVGOuterSVGFrame; class nsSVGPathGeometryFrame; @@ -507,9 +506,6 @@ public: * * This should die once bug 478152 is fixed. */ - static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents, - nsSVGGeometryFrame* aFrame, - const gfxMatrix& aMatrix); static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents, nsTextFrame* aFrame, const gfxMatrix& aMatrix); diff --git a/mobile/android/base/resources/layout/sync_setup_jpake_waiting.xml b/mobile/android/base/resources/layout/sync_setup_jpake_waiting.xml index 5444daff965..5e94574c96e 100644 --- a/mobile/android/base/resources/layout/sync_setup_jpake_waiting.xml +++ b/mobile/android/base/resources/layout/sync_setup_jpake_waiting.xml @@ -18,7 +18,7 @@ +