author | Margareta Eliza Balazs <ebalazs@mozilla.com> |
Thu, 15 Feb 2018 22:43:18 +0200 | |
changeset 404039 | a7d2a49f46fbbe9e39650ea1e9acd457b01f8337 |
parent 403990 | 64db6b9c2139dbb7aec1850187516058e85e29cd (current diff) |
parent 404038 | 994a8d6eccbcdc6106794705bd77e3ac5f031be2 (diff) |
child 404040 | a9db2b954595da03b7ca54fd1b9d76d9953564b0 |
push id | 99924 |
push user | ebalazs@mozilla.com |
push date | Thu, 15 Feb 2018 20:43:51 +0000 |
treeherder | mozilla-inbound@a7d2a49f46fb [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 60.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/accessible/interfaces/gecko/Makefile.in +++ b/accessible/interfaces/gecko/Makefile.in @@ -7,17 +7,19 @@ GARBAGE += $(MIDL_GENERATED_FILES) done_ MIDL_GENERATED_FILES = \ dlldata.c \ IGeckoCustom.h \ IGeckoCustom_p.c \ IGeckoCustom_i.c \ IGeckoCustom.tlb \ $(NULL) -$(MIDL_GENERATED_FILES): done_gen +# Bug 1420119: We need the trailing semicolon here to generate a recipe for the +# midl targets to avoid timestamp caching issues. +$(MIDL_GENERATED_FILES): done_gen ; done_gen: IGeckoCustom.idl $(MIDL) $(MIDL_FLAGS) -I $(srcdir) -Oicf $(srcdir)/IGeckoCustom.idl touch $@ export:: done_gen midl_exports := \
--- a/accessible/interfaces/ia2/Makefile.in +++ b/accessible/interfaces/ia2/Makefile.in @@ -77,17 +77,19 @@ export:: midl include $(topsrcdir)/config/rules.mk # generate list of to-be-generated files that are missing # but ignore special file dlldata.c and .tlb files missing:=$(strip $(foreach onefile,$(strip $(patsubst %.tlb,,$(subst dlldata.c,,$(MIDL_GENERATED_FILES)))),$(if $(wildcard $(onefile)),,$(onefile)))) missing_base:=$(sort $(basename $(subst _p.c,,$(subst _i.c,,$(missing))))) -$(MIDL_GENERATED_FILES) : midl_done typelib_done +# Bug 1420119: We need the trailing semicolon here to generate a recipe for the +# midl targets to avoid timestamp caching issues. +$(MIDL_GENERATED_FILES) : midl_done typelib_done ; ifneq ("$(missing)","") midl_done : FORCE endif midl_done : $(addprefix $(IA2DIR)/,$(MIDL_INTERFACES) $(MIDL_ENUMS)) for idl in $(sort $(subst FORCE,,$?) $(addsuffix .idl,$(addprefix $(IA2DIR)/,$(missing_base)))); do \ $(MIDL) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -Oicf $$idl; \
--- a/accessible/interfaces/msaa/Makefile.in +++ b/accessible/interfaces/msaa/Makefile.in @@ -7,17 +7,19 @@ GARBAGE += $(MIDL_GENERATED_FILES) done_ MIDL_GENERATED_FILES = \ dlldata.c \ ISimpleDOM.h \ ISimpleDOM_i.c \ ISimpleDOM_p.c \ ISimpleDOM.tlb \ $(NULL) -$(MIDL_GENERATED_FILES): done_gen +# Bug 1420119: We need the trailing semicolon here to generate a recipe for the +# midl targets to avoid timestamp caching issues. +$(MIDL_GENERATED_FILES): done_gen ; done_gen: ISimpleDOM.idl \ ISimpleDOMNode.idl \ ISimpleDOMDocument.idl \ ISimpleDOMText.idl $(MIDL) $(MIDL_FLAGS) -I $(srcdir) -robust -Oicf $(srcdir)/ISimpleDOM.idl touch $@
--- a/accessible/ipc/win/handler/Makefile.in +++ b/accessible/ipc/win/handler/Makefile.in @@ -12,17 +12,19 @@ MIDL_GENERATED_FILES = \ HandlerData_c.c \ HandlerData_i.c \ HandlerData_p.c \ HandlerData.tlb \ $(NULL) export:: $(MIDL_GENERATED_FILES) -$(MIDL_GENERATED_FILES): midl_done +# Bug 1420119: We need the trailing semicolon here to generate a recipe for the +# midl targets to avoid timestamp caching issues. +$(MIDL_GENERATED_FILES): midl_done ; midl_done: HandlerData.acf HandlerData.idl $(MIDL) $(MIDL_FLAGS) $(DEFINES) -I $(topobjdir) -I $(DIST)/include -I $(IA2DIR) -I $(MSAADIR) -Oicf -acf $(srcdir)/HandlerData.acf $(srcdir)/HandlerData.idl touch $@ INSTALL_TARGETS += midl midl_FILES := HandlerData.h \ HandlerData_i.c \
--- a/accessible/ipc/win/typelib/Makefile.in +++ b/accessible/ipc/win/typelib/Makefile.in @@ -6,17 +6,19 @@ GARBAGE += $(MIDL_GENERATED_FILES) done_ MIDL_GENERATED_FILES = \ Accessible.h \ Accessible_i.c \ Accessible_p.c \ Accessible.tlb \ $(NULL) -$(MIDL_GENERATED_FILES): done_gen +# Bug 1420119: We need the trailing semicolon here to generate a recipe for the +# midl targets to avoid timestamp caching issues. +$(MIDL_GENERATED_FILES): done_gen ; done_gen: Accessible.idl $(MIDL) $(MIDL_FLAGS) -Oicf $(srcdir)/Accessible.idl touch $@ export:: done_gen midl_exports := \
--- a/browser/app/blocklist.xml +++ b/browser/app/blocklist.xml @@ -1,10 +1,10 @@ <?xml version='1.0' encoding='UTF-8'?> -<blocklist lastupdate="1518553957211" xmlns="http://www.mozilla.org/2006/addons-blocklist"> +<blocklist lastupdate="1518640450735" xmlns="http://www.mozilla.org/2006/addons-blocklist"> <emItems> <emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i1211" id="flvto@hotger.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> @@ -2190,16 +2190,20 @@ <emItem blockID="2104a522-bb2f-4b04-ad0d-b0c571644552" id="{ed352072-ddf0-4cb4-9cb6-d8aa3741c2de}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="646e2384-f894-41bf-b7fc-8879e0095109" id="/^(https|youtube)@vietbacsecurity\.com$/"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> + <emItem blockID="cc5848e8-23d5-4655-b45c-dc239839b74e" id="/^(\{01c9a4a4-06dd-426b-9500-2ea6fe841b88\}|{5e024309-042c-4b9d-a634-5d92cf9c7514\}|{f4262989-6de0-4604-918f-663b85fad605\}|{e341ed12-a703-47fe-b8dd-5948c38070e4\}|{cd89045b-2e06-46bb-9e34-48e8799e5ef2\}|{ac296b47-7c03-486f-a1d6-c48b24419749\}|{5da81d3d-5db1-432a-affc-4a2fe9a70749\}|{df09f268-3c92-49db-8c31-6a25a6643896\}|{81ac42f3-3d17-4cff-85af-8b7f89c8826b\}|{09c8fa16-4eec-4f78-b19d-9b24b1b57e1e\}|{71639610-9cc3-47e0-86ed-d5b99eaa41d5\}|{83d38ac3-121b-4f28-bf9c-1220bd3c643b\}|{7f8bc48d-1c7c-41a0-8534-54adc079338f\})$/"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> + </emItem> </emItems> <pluginItems> <pluginItem blockID="p1063"> <match exp="Java(\(TM\))? Plug-in 10\.(8[1-9]|90)(\.[0-9]+)?([^\d\._]|$)" name="name"/> <match exp="libnpjp2\.so" name="filename"/> <infoURL>https://java.com/</infoURL> <versionRange severity="0" vulnerabilitystatus="1"/> </pluginItem>
--- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -13,21 +13,25 @@ } :root:-moz-lwtheme { color: var(--lwt-text-color) !important; } :root:-moz-lwtheme { background-color: var(--lwt-accent-color) !important; - background-image: var(--lwt-header-image), var(--lwt-additional-images) !important; + background-image: var(--lwt-additional-images) !important; background-position: var(--lwt-background-alignment) !important; background-repeat: var(--lwt-background-tiling) !important; } +:root:-moz-lwtheme[lwtheme-image] { + background-image: var(--lwt-header-image), var(--lwt-additional-images) !important; +} + :root:-moz-lwtheme:-moz-window-inactive { background-color: var(--lwt-accent-color-inactive, var(--lwt-accent-color)) !important; } #main-window:not([chromehidden~="toolbar"]) { %ifdef XP_MACOSX min-width: 335px; %else
deleted file mode 100644 index e4e8dcaa3b3cd01a1287359902561166d7f942ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
--- a/browser/base/content/test/general/browser_compacttheme.js +++ b/browser/base/content/test/general/browser_compacttheme.js @@ -41,17 +41,16 @@ add_task(async function startTests() { LightweightThemeManager.currentTheme = null; ok(!CompactTheme.isStyleSheetEnabled, "There is no compact style sheet when no lw theme is applied."); }); function dummyLightweightTheme(id) { return { id, name: id, - headerURL: "resource:///chrome/browser/content/browser/defaultthemes/compact.header.png", iconURL: "resource:///chrome/browser/content/browser/defaultthemes/light.icon.svg", textcolor: "red", accentcolor: "blue" }; } add_task(async function testLightweightThemePreview() { info("Setting compact to current and previewing others");
--- a/browser/base/jar.mn +++ b/browser/base/jar.mn @@ -91,17 +91,16 @@ browser.jar: content/browser/defaultthemes/3.icon.png (content/defaultthemes/3.icon.png) content/browser/defaultthemes/3.preview.png (content/defaultthemes/3.preview.png) content/browser/defaultthemes/4.header.png (content/defaultthemes/4.header.png) content/browser/defaultthemes/4.icon.png (content/defaultthemes/4.icon.png) content/browser/defaultthemes/4.preview.png (content/defaultthemes/4.preview.png) content/browser/defaultthemes/5.header.png (content/defaultthemes/5.header.png) content/browser/defaultthemes/5.icon.jpg (content/defaultthemes/5.icon.jpg) content/browser/defaultthemes/5.preview.jpg (content/defaultthemes/5.preview.jpg) - content/browser/defaultthemes/compact.header.png (content/defaultthemes/compact.header.png) content/browser/defaultthemes/dark.icon.svg (content/defaultthemes/dark.icon.svg) content/browser/defaultthemes/light.icon.svg (content/defaultthemes/light.icon.svg) content/browser/newtab/newTab.xhtml (content/newtab/newTab.xhtml) * content/browser/newtab/newTab.js (content/newtab/newTab.js) content/browser/newtab/newTab.css (content/newtab/newTab.css) content/browser/newtab/alternativeDefaultSites.json (content/newtab/alternativeDefaultSites.json) * content/browser/pageinfo/pageInfo.xul (content/pageinfo/pageInfo.xul) content/browser/pageinfo/pageInfo.js (content/pageinfo/pageInfo.js)
--- a/browser/components/customizableui/content/toolbar.xml +++ b/browser/components/customizableui/content/toolbar.xml @@ -4,19 +4,16 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> <bindings id="browserToolbarBindings" xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl"> <binding id="toolbar"> - <resources> - <stylesheet src="chrome://global/skin/toolbar.css"/> - </resources> <implementation> <field name="overflowedDuringConstruction">null</field> <constructor><![CDATA[ let scope = {}; ChromeUtils.import("resource:///modules/CustomizableUI.jsm", scope); let CustomizableUI = scope.CustomizableUI; // Add an early overflow event listener that will mark if the
--- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -695,27 +695,25 @@ BrowserGlue.prototype = { SessionStore.init(); let vendorShortName = gBrandBundle.GetStringFromName("vendorShortName"); LightweightThemeManager.addBuiltInTheme({ id: "firefox-compact-light@mozilla.org", name: gBrowserBundle.GetStringFromName("lightTheme.name"), description: gBrowserBundle.GetStringFromName("lightTheme.description"), - headerURL: "resource:///chrome/browser/content/browser/defaultthemes/compact.header.png", iconURL: "resource:///chrome/browser/content/browser/defaultthemes/light.icon.svg", textcolor: "black", accentcolor: "white", author: vendorShortName, }); LightweightThemeManager.addBuiltInTheme({ id: "firefox-compact-dark@mozilla.org", name: gBrowserBundle.GetStringFromName("darkTheme.name"), description: gBrowserBundle.GetStringFromName("darkTheme.description"), - headerURL: "resource:///chrome/browser/content/browser/defaultthemes/compact.header.png", iconURL: "resource:///chrome/browser/content/browser/defaultthemes/dark.icon.svg", textcolor: "white", accentcolor: "black", author: vendorShortName, }); // Initialize the default l10n resource sources for L10nRegistry.
--- a/browser/components/preferences/clearSiteData.js +++ b/browser/components/preferences/clearSiteData.js @@ -51,28 +51,31 @@ var gClearSiteDataDialog = { onCheckboxCommand(event) { this._clearButton.disabled = !(this._clearSiteDataCheckbox.checked || this._clearCacheCheckbox.checked); }, onClear() { let allowed = true; + if (this._clearCacheCheckbox.checked && allowed) { + SiteDataManager.removeCache(); + // If we're not clearing site data, we need to tell the + // SiteDataManager to signal that it's updating. + if (!this._clearSiteDataCheckbox.checked) { + SiteDataManager.updateSites(); + } + } + if (this._clearSiteDataCheckbox.checked) { allowed = SiteDataManager.promptSiteDataRemoval(window); if (allowed) { SiteDataManager.removeSiteData(); } } - if (this._clearCacheCheckbox.checked && allowed) { - SiteDataManager.removeCache(); - // Update cache UI in about:preferences - window.opener.gPrivacyPane.updateActualCacheSize(); - } - if (allowed) { window.close(); } }, }; window.addEventListener("load", () => gClearSiteDataDialog.init());
--- a/browser/components/preferences/in-content/privacy.js +++ b/browser/components/preferences/in-content/privacy.js @@ -106,21 +106,16 @@ Preferences.addAll([ { id: "browser.safebrowsing.phishing.enabled", type: "bool" }, { id: "browser.safebrowsing.downloads.enabled", type: "bool" }, { id: "urlclassifier.malwareTable", type: "string" }, { id: "browser.safebrowsing.downloads.remote.block_potentially_unwanted", type: "bool" }, { id: "browser.safebrowsing.downloads.remote.block_uncommon", type: "bool" }, - - // Network tab - { id: "browser.cache.disk.capacity", type: "int" }, - - { id: "browser.cache.disk.smart_size.enabled", type: "bool", inverted: "true" }, ]); // Data Choices tab if (AppConstants.NIGHTLY_BUILD) { Preferences.add({ id: "browser.chrome.errorReporter.enabled", type: "bool" }); } if (AppConstants.MOZ_CRASHREPORTER) { Preferences.add({ id: "browser.crashReports.unsubmittedCheck.autoSubmit2", type: "bool" }); @@ -323,24 +318,20 @@ var gPrivacyPane = { setEventListener("showPasswords", "command", gPrivacyPane.showPasswords); setEventListener("addonExceptions", "command", gPrivacyPane.showAddonExceptions); setEventListener("viewCertificatesButton", "command", gPrivacyPane.showCertificates); setEventListener("viewSecurityDevicesButton", "command", gPrivacyPane.showSecurityDevices); - setEventListener("clearCacheButton", "command", - gPrivacyPane.clearCache); this._pane = document.getElementById("panePrivacy"); this._initMasterPasswordUI(); this._initSafeBrowsing(); - this.updateCacheSizeInputField(); - this.updateActualCacheSize(); setEventListener("notificationSettingsButton", "command", gPrivacyPane.showNotificationExceptions); setEventListener("locationSettingsButton", "command", gPrivacyPane.showLocationExceptions); setEventListener("cameraSettingsButton", "command", gPrivacyPane.showCameraExceptions); setEventListener("microphoneSettingsButton", "command", @@ -365,19 +356,16 @@ var gPrivacyPane = { checkbox.setAttribute("accesskey", bundlePrefs.getString("pauseNotifications.accesskey")); if (AlertsServiceDND.manualDoNotDisturb) { let notificationsDoNotDisturb = document.getElementById("notificationsDoNotDisturb"); notificationsDoNotDisturb.setAttribute("checked", true); } } - setEventListener("cacheSize", "change", - gPrivacyPane.updateCacheSizePref); - if (Services.prefs.getBoolPref("browser.storageManager.enabled")) { Services.obs.addObserver(this, "sitedatamanager:sites-updated"); Services.obs.addObserver(this, "sitedatamanager:updating-sites"); let unload = () => { window.removeEventListener("unload", unload); Services.obs.removeObserver(this, "sitedatamanager:sites-updated"); Services.obs.removeObserver(this, "sitedatamanager:updating-sites"); }; @@ -1413,121 +1401,41 @@ var gPrivacyPane = { /** * Displays a dialog from which the user can manage his security devices. */ showSecurityDevices() { gSubDialog.open("chrome://pippki/content/device_manager.xul"); }, - /** - * Clears the cache. - */ - clearCache() { - try { - Services.cache2.clear(); - } catch (ex) { } - this.updateActualCacheSize(); - }, - showSiteDataSettings() { gSubDialog.open("chrome://browser/content/preferences/siteDataSettings.xul"); }, toggleSiteData(shouldShow) { let clearButton = document.getElementById("clearSiteDataButton"); let settingsButton = document.getElementById("siteDataSettings"); clearButton.disabled = !shouldShow; settingsButton.disabled = !shouldShow; }, - updateTotalDataSizeLabel(usage) { - let prefStrBundle = document.getElementById("bundlePreferences"); + showSiteDataLoading() { let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize"); - if (usage < 0) { - totalSiteDataSizeLabel.textContent = prefStrBundle.getString("loadingSiteDataSize"); - } else { - let size = DownloadUtils.convertByteUnits(usage); - totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize", size); - } - }, - - // Retrieves the amount of space currently used by disk cache - updateActualCacheSize() { - var actualSizeLabel = document.getElementById("actualDiskCacheSize"); - var prefStrBundle = document.getElementById("bundlePreferences"); - - // Needs to root the observer since cache service keeps only a weak reference. - this.observer = { - onNetworkCacheDiskConsumption(consumption) { - var size = DownloadUtils.convertByteUnits(consumption); - // The XBL binding for the string bundle may have been destroyed if - // the page was closed before this callback was executed. - if (!prefStrBundle.getFormattedString) { - return; - } - actualSizeLabel.textContent = prefStrBundle.getFormattedString("actualDiskCacheSize", size); - }, - - QueryInterface: XPCOMUtils.generateQI([ - Components.interfaces.nsICacheStorageConsumptionObserver, - Components.interfaces.nsISupportsWeakReference - ]) - }; - - actualSizeLabel.textContent = prefStrBundle.getString("actualDiskCacheSizeCalculated"); - - try { - Services.cache2.asyncGetDiskConsumption(this.observer); - } catch (e) { } + let prefStrBundle = document.getElementById("bundlePreferences"); + totalSiteDataSizeLabel.textContent = prefStrBundle.getString("loadingSiteDataSize1"); }, - updateCacheSizeUI(smartSizeEnabled) { - document.getElementById("useCacheBefore").disabled = smartSizeEnabled; - document.getElementById("cacheSize").disabled = smartSizeEnabled; - document.getElementById("useCacheAfter").disabled = smartSizeEnabled; - }, - - readSmartSizeEnabled() { - // The smart_size.enabled preference element is inverted="true", so its - // value is the opposite of the actual pref value - var disabled = Preferences.get("browser.cache.disk.smart_size.enabled").value; - this.updateCacheSizeUI(!disabled); - }, - - /** - * Converts the cache size from units of KB to units of MB and stores it in - * the textbox element. - * - * Preferences: - * - * browser.cache.disk.capacity - * - the size of the browser cache in KB - * - Only used if browser.cache.disk.smart_size.enabled is disabled - */ - updateCacheSizeInputField() { - let cacheSizeElem = document.getElementById("cacheSize"); - let cachePref = Preferences.get("browser.cache.disk.capacity"); - cacheSizeElem.value = cachePref.value / 1024; - if (cachePref.locked) - cacheSizeElem.disabled = true; - }, - - /** - * Updates the cache size preference once user enters a new value. - * We intentionally do not set preference="browser.cache.disk.capacity" - * onto the textbox directly, as that would update the pref at each keypress - * not only after the final value is entered. - */ - updateCacheSizePref() { - let cacheSizeElem = document.getElementById("cacheSize"); - let cachePref = Preferences.get("browser.cache.disk.capacity"); - // Converts the cache size as specified in UI (in MB) to KB. - let intValue = parseInt(cacheSizeElem.value, 10); - cachePref.value = isNaN(intValue) ? 0 : intValue * 1024; + updateTotalDataSizeLabel(siteDataUsage) { + SiteDataManager.getCacheSize().then(function(cacheUsage) { + let prefStrBundle = document.getElementById("bundlePreferences"); + let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize"); + let totalUsage = siteDataUsage + cacheUsage; + let size = DownloadUtils.convertByteUnits(totalUsage); + totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize1", size); + }); }, clearSiteData() { gSubDialog.open("chrome://browser/content/preferences/clearSiteData.xul"); }, initDataCollection() { this._setupLearnMoreLink("toolkit.datacollection.infoURL", @@ -1588,17 +1496,17 @@ var gPrivacyPane = { Services.prefs.setBoolPref(PREF_UPLOAD_ENABLED, checkbox.checked); }, observe(aSubject, aTopic, aData) { switch (aTopic) { case "sitedatamanager:updating-sites": // While updating, we want to disable this section and display loading message until updated this.toggleSiteData(false); - this.updateTotalDataSizeLabel(-1); + this.showSiteDataLoading(); break; case "sitedatamanager:sites-updated": this.toggleSiteData(true); SiteDataManager.getTotalUsage() .then(this.updateTotalDataSizeLabel.bind(this)); break; }
--- a/browser/components/preferences/in-content/privacy.xul +++ b/browser/components/preferences/in-content/privacy.xul @@ -256,43 +256,16 @@ <checkbox id="openpageSuggestion" label="&locbar.openpage.label;" accesskey="&locbar.openpage.accesskey;" preference="browser.urlbar.suggest.openpage"/> <label class="text-link" id="openSearchEnginePreferences"> &suggestionSettings2.label; </label> </groupbox> -<!-- Cache --> -<groupbox id="cacheGroup" data-category="panePrivacy" hidden="true"> - <caption><label>&httpCache.label;</label></caption> - - <hbox align="center"> - <label id="actualDiskCacheSize" flex="1"/> - <button id="clearCacheButton" - class="accessory-button" - icon="clear" - label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"/> - </hbox> - <checkbox preference="browser.cache.disk.smart_size.enabled" - id="allowSmartSize" - onsyncfrompreference="return gPrivacyPane.readSmartSizeEnabled();" - label="&overrideSmartCacheSize.label;" - accesskey="&overrideSmartCacheSize.accesskey;"/> - <hbox align="center" class="indent"> - <label id="useCacheBefore" control="cacheSize" - accesskey="&limitCacheSizeBefore.accesskey;"> - &limitCacheSizeBefore.label; - </label> - <textbox id="cacheSize" type="number" size="4" max="1024" - aria-labelledby="useCacheBefore cacheSize useCacheAfter"/> - <label id="useCacheAfter" flex="1">&limitCacheSizeAfter.label;</label> - </hbox> -</groupbox> - <!-- Site Data --> <groupbox id="siteDataGroup" hidden="true" data-category="panePrivacy" data-hidden-from-search="true"> <caption><label>&siteData.label;</label></caption> <hbox align="baseline"> <vbox flex="1"> <description flex="1"> <label id="totalSiteDataSize" class="tail-with-learn-more"></label>
--- a/browser/components/preferences/in-content/tests/browser_bug795764_cachedisabled.js +++ b/browser/components/preferences/in-content/tests/browser_bug795764_cachedisabled.js @@ -11,20 +11,16 @@ function test() { // Otherwise, without any site then it would just return so we would end up in not testing SiteDataManager. let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin("https://www.foo.com"); Services.perms.addFromPrincipal(principal, "persistent-storage", Ci.nsIPermissionManager.ALLOW_ACTION); registerCleanupFunction(function() { Services.perms.removeFromPrincipal(principal, "persistent-storage"); }); SpecialPowers.pushPrefEnv({set: [ - ["browser.cache.offline.enable", false], - ["browser.cache.disk.enable", false], - ["browser.cache.memory.enable", false], - ["browser.storageManager.enabled", true], ["privacy.userContext.ui.enabled", true] ]}).then(() => open_preferences(runTest)); } function runTest(win) { is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded"); let tab = win.document;
--- a/browser/components/preferences/in-content/tests/browser_clearSiteData.js +++ b/browser/components/preferences/in-content/tests/browser_clearSiteData.js @@ -11,45 +11,16 @@ const { DownloadUtils } = ChromeUtils.im const TEST_QUOTA_USAGE_HOST = "example.com"; const TEST_QUOTA_USAGE_ORIGIN = "https://" + TEST_QUOTA_USAGE_HOST; const TEST_QUOTA_USAGE_URL = TEST_QUOTA_USAGE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/site_data_test.html"; const TEST_OFFLINE_HOST = "example.org"; const TEST_OFFLINE_ORIGIN = "https://" + TEST_OFFLINE_HOST; const TEST_OFFLINE_URL = TEST_OFFLINE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/offline/offline.html"; const TEST_SERVICE_WORKER_URL = TEST_OFFLINE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/service_worker_test.html"; -// XXX: The intermittent bug 1331851 -// The implementation of nsICacheStorageConsumptionObserver must be passed as weak referenced, -// so we must hold this observer here well. If we didn't, there would be a chance that -// in Linux debug test run the observer was released before the operation at gecko was completed -// (may be because of a relatively quicker GC cycle or a relatively slower operation). -// As a result of that, we would never get the cache usage we want so the test would fail from timeout. -const cacheUsageGetter = { - _promise: null, - _resolve: null, - get() { - if (!this._promise) { - this._promise = new Promise(resolve => { - this._resolve = resolve; - Services.cache2.asyncGetDiskConsumption(this); - }); - } - return this._promise; - }, - // nsICacheStorageConsumptionObserver implementations - onNetworkCacheDiskConsumption(usage) { - cacheUsageGetter._promise = null; - cacheUsageGetter._resolve(usage); - }, - QueryInterface: XPCOMUtils.generateQI([ - Components.interfaces.nsICacheStorageConsumptionObserver, - Components.interfaces.nsISupportsWeakReference - ]), -}; - async function testClearData(clearSiteData, clearCache) { let quotaURI = Services.io.newURI(TEST_QUOTA_USAGE_ORIGIN); SitePermissions.set(quotaURI, "persistent-storage", SitePermissions.ALLOW); // Open a test site which saves into appcache. await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_OFFLINE_URL); await BrowserTestUtils.removeTab(gBrowser.selectedTab); @@ -64,23 +35,28 @@ async function testClearData(clearSiteDa // Register some service workers. await loadServiceWorkerTestPage(TEST_SERVICE_WORKER_URL); await promiseServiceWorkerRegisteredFor(TEST_SERVICE_WORKER_URL); await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true }); // Test the initial states. - let cacheUsage = await cacheUsageGetter.get(); + let cacheUsage = await SiteDataManager.getCacheSize(); let quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN); let totalUsage = await SiteDataManager.getTotalUsage(); Assert.greater(cacheUsage, 0, "The cache usage should not be 0"); Assert.greater(quotaUsage, 0, "The quota usage should not be 0"); Assert.greater(totalUsage, 0, "The total usage should not be 0"); + let initialSizeLabelValue = await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() { + let sizeLabel = content.document.getElementById("totalSiteDataSize"); + return sizeLabel.textContent; + }); + let doc = gBrowser.selectedBrowser.contentDocument; let clearSiteDataButton = doc.getElementById("clearSiteDataButton"); let dialogOpened = promiseLoadSubDialog("chrome://browser/content/preferences/clearSiteData.xul"); clearSiteDataButton.doCommand(); let dialogWin = await dialogOpened; // Convert the usage numbers in the same way the UI does it to assert @@ -140,47 +116,48 @@ async function testClearData(clearSiteDa if (clearSiteData) { await acceptPromise; } await dialogClosed; if (clearCache) { TestUtils.waitForCondition(async function() { - let usage = await cacheUsageGetter.get(); + let usage = await SiteDataManager.getCacheSize(); return usage == 0; }, "The cache usage should be removed"); } else { - Assert.greater(await cacheUsageGetter.get(), 0, "The cache usage should not be 0"); + Assert.greater(await SiteDataManager.getCacheSize(), 0, "The cache usage should not be 0"); } if (clearSiteData) { await updatePromise; await cookiesClearedPromise; await promiseServiceWorkersCleared(); TestUtils.waitForCondition(async function() { let usage = await SiteDataManager.getTotalUsage(); return usage == 0; }, "The total usage should be removed"); - - // Check that the size label in about:preferences updates after we cleared data. - await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() { - let sizeLabel = content.document.getElementById("totalSiteDataSize"); - - await ContentTaskUtils.waitForCondition( - () => sizeLabel.textContent.includes("0"), "Site data size label should have updated."); - }); } else { quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN); totalUsage = await SiteDataManager.getTotalUsage(); Assert.greater(quotaUsage, 0, "The quota usage should not be 0"); Assert.greater(totalUsage, 0, "The total usage should not be 0"); } + if (clearCache || clearSiteData) { + // Check that the size label in about:preferences updates after we cleared data. + await ContentTask.spawn(gBrowser.selectedBrowser, {initialSizeLabelValue}, async function(opts) { + let sizeLabel = content.document.getElementById("totalSiteDataSize"); + await ContentTaskUtils.waitForCondition( + () => sizeLabel.textContent != opts.initialSizeLabelValue, "Site data size label should have updated."); + }); + } + let desiredPermissionState = clearSiteData ? SitePermissions.UNKNOWN : SitePermissions.ALLOW; let permission = SitePermissions.get(quotaURI, "persistent-storage"); is(permission.state, desiredPermissionState, "Should have the correct permission state."); await BrowserTestUtils.removeTab(gBrowser.selectedTab); await SiteDataManager.removeAll(); }
--- a/browser/components/preferences/in-content/tests/browser_extension_controlled.js +++ b/browser/components/preferences/in-content/tests/browser_extension_controlled.js @@ -439,16 +439,19 @@ add_task(async function testExtensionCon await ExtensionSettingsStore.initialize(); // Verify the setting isn't reported as controlled and the inputs are enabled. is(ExtensionSettingsStore.getSetting("prefs", "homepage_override"), null, "The homepage_override is not set"); await checkHomepageEnabled(); + // Disarm any pending writes before we modify the JSONFile directly. + await ExtensionSettingsStore._reloadFile(false); + // Write out a bad store file. let storeData = { prefs: { homepage_override: { initialValue: "", precedenceList: [{ id: "bad@mochi.test", installDate: 1508802672,
--- a/browser/components/preferences/in-content/tests/browser_siteData.js +++ b/browser/components/preferences/in-content/tests/browser_siteData.js @@ -67,49 +67,51 @@ add_task(async function() { }); // Test buttons are disabled and loading message shown while updating sites add_task(async function() { await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]}); let updatedPromise = promiseSiteDataManagerSitesUpdated(); await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true }); await updatedPromise; + let cacheSize = await SiteDataManager.getCacheSize(); let actual = null; let expected = null; let doc = gBrowser.selectedBrowser.contentDocument; let clearBtn = doc.getElementById("clearSiteDataButton"); let settingsButton = doc.getElementById("siteDataSettings"); let prefStrBundle = doc.getElementById("bundlePreferences"); let totalSiteDataSizeLabel = doc.getElementById("totalSiteDataSize"); is(clearBtn.disabled, false, "Should enable clear button after sites updated"); is(settingsButton.disabled, false, "Should enable settings button after sites updated"); await SiteDataManager.getTotalUsage() .then(usage => { actual = totalSiteDataSizeLabel.textContent; expected = prefStrBundle.getFormattedString( - "totalSiteDataSize", DownloadUtils.convertByteUnits(usage)); + "totalSiteDataSize1", DownloadUtils.convertByteUnits(usage + cacheSize)); is(actual, expected, "Should show the right total site data size"); }); Services.obs.notifyObservers(null, "sitedatamanager:updating-sites"); is(clearBtn.disabled, true, "Should disable clear button while updating sites"); is(settingsButton.disabled, true, "Should disable settings button while updating sites"); actual = totalSiteDataSizeLabel.textContent; - expected = prefStrBundle.getString("loadingSiteDataSize"); + expected = prefStrBundle.getString("loadingSiteDataSize1"); is(actual, expected, "Should show the loading message while updating"); Services.obs.notifyObservers(null, "sitedatamanager:sites-updated"); is(clearBtn.disabled, false, "Should enable clear button after sites updated"); is(settingsButton.disabled, false, "Should enable settings button after sites updated"); + cacheSize = await SiteDataManager.getCacheSize(); await SiteDataManager.getTotalUsage() .then(usage => { actual = totalSiteDataSizeLabel.textContent; expected = prefStrBundle.getFormattedString( - "totalSiteDataSize", DownloadUtils.convertByteUnits(usage)); + "totalSiteDataSize1", DownloadUtils.convertByteUnits(usage + cacheSize)); is(actual, expected, "Should show the right total site data size"); }); await BrowserTestUtils.removeTab(gBrowser.selectedTab); }); // Test clearing service wroker through the settings panel add_task(async function() {
--- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -738,17 +738,17 @@ you can use these alternative items. Oth <!ENTITY editBookmark.done.label "Done"> <!ENTITY editBookmark.removeBookmark.accessKey "R"> <!-- LOCALIZATION NOTE (identity.securityView.label) This is the header of the security subview in the Site Identity panel. --> <!ENTITY identity.securityView.label "Site Security"> <!ENTITY identity.connectionSecure "Secure Connection"> -<!ENTITY identity.connectionNotSecure "Connection is Not Secure"> +<!ENTITY identity.connectionNotSecure "Connection Is Not Secure"> <!ENTITY identity.connectionFile "This page is stored on your computer."> <!ENTITY identity.connectionVerified2 "You are securely connected to this site, owned by:"> <!ENTITY identity.connectionInternal "This is a secure &brandShortName; page."> <!ENTITY identity.extensionPage "This page is loaded from an extension."> <!ENTITY identity.insecureLoginForms2 "Logins entered on this page could be compromised."> <!-- Strings for connection state warnings. --> <!ENTITY identity.activeBlocked "&brandShortName; has blocked parts of this page that are not secure.">
--- a/browser/locales/en-US/chrome/browser/preferences/advanced.dtd +++ b/browser/locales/en-US/chrome/browser/preferences/advanced.dtd @@ -48,40 +48,24 @@ available. --> <!ENTITY networkTab.label "Network"> <!ENTITY networkProxy.label "Network Proxy"> <!ENTITY connectionSettingsLearnMore.label "Learn more"> <!ENTITY connectionSettings.label "Settings…"> <!ENTITY connectionSettings.accesskey "e"> -<!ENTITY httpCache.label "Cached Web Content"> - <!-- Site Data section manages sites using Storage API and is under Network --> <!ENTITY siteData.label "Site Data"> <!ENTITY clearSiteData.label "Clear All Data"> <!ENTITY clearSiteData.accesskey "l"> <!ENTITY siteDataSettings.label "Settings…"> <!ENTITY siteDataSettings.accesskey "i"> <!ENTITY siteDataLearnMoreLink.label "Learn more"> -<!-- LOCALIZATION NOTE: - The entities limitCacheSizeBefore.label and limitCacheSizeAfter.label appear on a single - line in preferences as follows: - - &limitCacheSizeBefore.label [textbox for cache size in MB] &limitCacheSizeAfter.label; ---> -<!ENTITY limitCacheSizeBefore.label "Limit cache to"> -<!ENTITY limitCacheSizeBefore.accesskey "L"> -<!ENTITY limitCacheSizeAfter.label "MB of space"> -<!ENTITY clearCacheNow.label "Clear Now"> -<!ENTITY clearCacheNow.accesskey "C"> -<!ENTITY overrideSmartCacheSize.label "Override automatic cache management"> -<!ENTITY overrideSmartCacheSize.accesskey "O"> - <!ENTITY updateTab.label "Update"> <!-- LOCALIZATION NOTE (updateApplication.label): Strings from aboutDialog.dtd are displayed in this section of the preferences. Please check for possible accesskey conflicts. --> <!ENTITY updateApplication.label "&brandShortName; Updates"> <!-- LOCALIZATION NOTE (updateApplication.version.*): updateApplication.version.pre
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties +++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties @@ -161,38 +161,22 @@ removeAllShownCookies.accesskey=A # you can use #1 in your localization as a placeholder for the number. # For example this is the English string with numbers: # removeSelectedCookied=Remove #1 Selected;Remove #1 Selected removeSelectedCookies.label=Remove Selected;Remove Selected removeSelectedCookies.accesskey=R defaultUserContextLabel=None -####Preferences::Advanced::Network -#LOCALIZATION NOTE: The next string is for the disk usage of the web content cache. -# e.g., "Your web content cache is currently using 200 MB" -# %1$S = size -# %2$S = unit (MB, KB, etc.) -actualDiskCacheSize=Your web content cache is currently using %1$S %2$S of disk space -actualDiskCacheSizeCalculated=Calculating web content cache size… - -####Preferences::Advanced::Network -#LOCALIZATION NOTE: The next string is for the disk usage of the application cache. -# e.g., "Your application cache is currently using 200 MB" -# %1$S = size -# %2$S = unit (MB, KB, etc.) -actualAppCacheSize=Your application cache is currently using %1$S %2$S of disk space - -####Preferences::Advanced::Network #LOCALIZATION NOTE: The next string is for the total usage of site data. # e.g., "The total usage is currently using 200 MB" # %1$S = size # %2$S = unit (MB, KB, etc.) -totalSiteDataSize=Your stored site data is currently using %1$S %2$S of disk space -loadingSiteDataSize=Calculating site data size… +totalSiteDataSize1=Your stored site data and cache are currently using %1$S %2$S of disk space +loadingSiteDataSize1=Calculating site data and cache size… persistent=Persistent siteUsage=%1$S %2$S acceptRemove=Remove # LOCALIZATION NOTE (siteDataSettings2.description): %S = brandShortName siteDataSettings2.description=The following websites store site data on your computer. %S keeps data from websites with persistent storage until you delete it, and deletes data from websites with non-persistent storage as space is needed. # LOCALIZATION NOTE (removeAllSiteData, removeAllSiteDataShown): # removeAllSiteData and removeAllSiteDataShown are both used on the same one button, # never displayed together and can share the same accesskey.
--- a/browser/themes/linux/browser.css +++ b/browser/themes/linux/browser.css @@ -465,18 +465,18 @@ notification[value="translation"] menuli color: -moz-menubartext; } #nav-bar { -moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#toolbar-drag"); } @media (-moz-menubar-drag) { - #toolbar-menubar:not([autohide="true"]):not(:-moz-lwtheme), - #TabsToolbar:not(:-moz-lwtheme) { + #toolbar-menubar:not([autohide="true"]), + #TabsToolbar { -moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#toolbar-drag"); } } .tabbrowser-tab:focus > .tab-stack > .tab-content { outline: 1px dotted; outline-offset: -6px; }
--- a/browser/themes/shared/compacttheme.inc.css +++ b/browser/themes/shared/compacttheme.inc.css @@ -2,18 +2,16 @@ % 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/. /* compacttheme.css is loaded in browser.xul after browser.css when it is preffed on. The bulk of the styling is here in the shared file, but there are overrides for each platform in their compacttheme.css files. */ :root:-moz-lwtheme { - text-shadow: none; - --toolbar-bgcolor: var(--chrome-secondary-background-color); --toolbar-gbimage: none; --toolbar-non-lwt-bgcolor: var(--toolbar-bgcolor); --toolbar-non-lwt-textcolor: var(--chrome-color); --toolbar-non-lwt-bgimage: none; --toolbarbutton-icon-fill-opacity: .7; } @@ -104,14 +102,8 @@ toolbar[brighttext] .toolbarbutton-1 { #urlbar-zoom-button:-moz-lwtheme-brighttext:hover { background-color: rgba(255,255,255,.2); } #urlbar-zoom-button:-moz-lwtheme-brighttext:hover:active { background-color: rgba(255,255,255,.3); } - -.tab-icon-sound[soundplaying], -.tab-icon-sound[muted] { - filter: none !important; /* removes drop-shadow filter */ -} -
--- a/browser/themes/shared/customizableui/customizeMode.inc.css +++ b/browser/themes/shared/customizableui/customizeMode.inc.css @@ -14,32 +14,32 @@ #customization-container { background-color: var(--toolbar-non-lwt-bgcolor); background-image: var(--toolbar-non-lwt-bgimage); color: var(--toolbar-non-lwt-textcolor); text-shadow: none; } -#customization-container:-moz-lwtheme { +:root[lwtheme-image] #customization-container { background-color: transparent; background-image: linear-gradient(var(--toolbar-bgcolor), var(--toolbar-non-lwt-bgcolor) 45px); } #customization-palette { padding: 5px 20px 20px; } #customization-header { font-weight: 500; font-size: 1.2em; margin: 20px 20px 15px; } -#customization-header:-moz-lwtheme { +:root[lwtheme-image] #customization-header { text-shadow: 0 0 1em var(--toolbar-non-lwt-bgcolor), 0 0 1em var(--toolbar-non-lwt-bgcolor), 0 0 .5em var(--toolbar-non-lwt-bgcolor); } #customization-panel-container { padding: 0 20px 25px; }
--- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -406,25 +406,25 @@ tabbrowser { .tab-icon-sound[muted] { list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio-muted.svg); } .tab-icon-sound[activemedia-blocked] { list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio-blocked.svg); } -.tab-icon-sound:-moz-lwtheme-darktext[soundplaying], -.tab-icon-sound:-moz-lwtheme-darktext[muted], -.tab-icon-sound:-moz-lwtheme-darktext[activemedia-blocked] { +:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-darktext[soundplaying], +:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-darktext[muted], +:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-darktext[activemedia-blocked] { filter: drop-shadow(1px 1px 1px white); } -.tab-icon-sound:-moz-lwtheme-brighttext[soundplaying], -.tab-icon-sound:-moz-lwtheme-brighttext[muted], -.tab-icon-sound:-moz-lwtheme-brighttext[activemedia-blocked] { +:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-brighttext[soundplaying], +:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-brighttext[muted], +:root[lwtheme-image] .tab-icon-sound:-moz-lwtheme-brighttext[activemedia-blocked] { filter: drop-shadow(1px 1px 1px black); } .tab-icon-sound[soundplaying]:not(:hover), .tab-icon-sound[muted]:not(:hover), .tab-icon-sound[activemedia-blocked]:not(:hover) { opacity: .8; } @@ -525,17 +525,17 @@ tabbrowser { } /* * LightweightThemeConsumer will set the current lightweight theme's header * image to the lwt-header-image variable, used in each of the following rulesets. */ /* Lightweight theme on tabs */ -#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background[selected=true]:-moz-lwtheme { +:root[lwtheme-image] #tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background[selected=true] { background-attachment: scroll, fixed; background-color: transparent; background-image: linear-gradient(var(--toolbar-bgcolor), var(--toolbar-bgcolor)), var(--lwt-header-image); background-position: 0 0, right top; background-repeat: repeat-x, no-repeat; background-size: auto 100%, auto auto; }
--- a/browser/themes/windows/browser-aero.css +++ b/browser/themes/windows/browser-aero.css @@ -101,29 +101,29 @@ :root[sizemode="maximized"] #titlebar-max { list-style-image: url(chrome://browser/skin/window-controls/restore.svg); } #titlebar-close { list-style-image: url(chrome://browser/skin/window-controls/close.svg); } - .titlebar-button:-moz-lwtheme { + :root[lwtheme-image] .titlebar-button { -moz-context-properties: unset; } - #titlebar-min:-moz-lwtheme { + :root[lwtheme-image] #titlebar-min { list-style-image: url(chrome://browser/skin/window-controls/minimize-themes.svg); } - #titlebar-max:-moz-lwtheme { + :root[lwtheme-image] #titlebar-max { list-style-image: url(chrome://browser/skin/window-controls/maximize-themes.svg); } - :root[sizemode="maximized"] #titlebar-max:-moz-lwtheme { + :root[lwtheme-image][sizemode="maximized"] #titlebar-max { list-style-image: url(chrome://browser/skin/window-controls/restore-themes.svg); } - #titlebar-close:-moz-lwtheme { + :root[lwtheme-image] #titlebar-close { list-style-image: url(chrome://browser/skin/window-controls/close-themes.svg); } /* the 12px image renders a 10px icon, and the 10px upscaled gets rounded to 12.5, which * rounds up to 13px, which makes the icon one pixel too big on 1.25dppx. Fix: */ @media (min-resolution: 1.20dppx) and (max-resolution: 1.45dppx) { .titlebar-button > .toolbarbutton-icon { width: 11.5px;
--- a/browser/themes/windows/compacttheme.css +++ b/browser/themes/windows/compacttheme.css @@ -26,20 +26,16 @@ background-color: rgb(185,209,234) !important; } #main-window:-moz-window-inactive { background-color: rgb(215,228,242) !important; } } } -#toolbar-menubar { - text-shadow: none !important; -} - @media (-moz-os-version: windows-win7) { @media (-moz-windows-default-theme) { /* Always show light toolbar elements on aero surface. */ #TabsToolbar { color: hsl(240,9%,98%); } /* Keep showing the correct color inside the tabs. */ @@ -60,21 +56,16 @@ } @media (-moz-windows-glass) { /* Set to full fill-opacity to improve visibility of toolbar buttons on aero glass. */ #TabsToolbar { --toolbarbutton-icon-fill-opacity: 1; } - /* Make the menubar text readable on aero glass (copied from browser-aero.css). */ - #toolbar-menubar { - text-shadow: 0 0 .5em white, 0 0 .5em white, 0 1px 0 rgba(255,255,255,.4); - } - #main-menubar:not(:-moz-window-inactive) { background-color: rgba(255,255,255,.5); color: black; border-radius: 4px; } } @media (-moz-os-version: windows-win7), @@ -150,28 +141,8 @@ * over the native border with our custom borders: */ #navigator-toolbox { /* These are !important to avoid specificity-wars with the selectors that add borders here. */ background-image: none !important; border-top: none !important; box-shadow: none !important; padding-top: 0 !important; } - -@media (-moz-os-version: windows-win10) { - .titlebar-button:-moz-lwtheme { - -moz-context-properties: stroke; - stroke: currentColor; - } - #titlebar-min:-moz-lwtheme { - list-style-image: url(chrome://browser/skin/window-controls/minimize.svg); - } - #titlebar-max:-moz-lwtheme { - list-style-image: url(chrome://browser/skin/window-controls/maximize.svg); - } - :root[sizemode="maximized"] #titlebar-max:-moz-lwtheme { - list-style-image: url(chrome://browser/skin/window-controls/restore.svg); - } - #titlebar-close:-moz-lwtheme { - list-style-image: url(chrome://browser/skin/window-controls/close.svg); - } -} -
--- a/devtools/client/inspector/animation/animation.js +++ b/devtools/client/inspector/animation/animation.js @@ -22,16 +22,17 @@ const { const { isAllAnimationEqual } = require("./utils/utils"); class AnimationInspector { constructor(inspector, win) { this.inspector = inspector; this.win = win; this.getAnimatedPropertyMap = this.getAnimatedPropertyMap.bind(this); + this.getComputedStyle = this.getComputedStyle.bind(this); this.getNodeFromActor = this.getNodeFromActor.bind(this); this.selectAnimation = this.selectAnimation.bind(this); this.setDetailVisibility = this.setDetailVisibility.bind(this); this.simulateAnimation = this.simulateAnimation.bind(this); this.toggleElementPicker = this.toggleElementPicker.bind(this); this.update = this.update.bind(this); this.onElementPickerStarted = this.onElementPickerStarted.bind(this); this.onElementPickerStopped = this.onElementPickerStopped.bind(this); @@ -52,16 +53,17 @@ class AnimationInspector { const { onHideBoxModelHighlighter, } = this.inspector.getPanel("boxmodel").getComponentProps(); const { emit: emitEventForTest, getAnimatedPropertyMap, + getComputedStyle, getNodeFromActor, selectAnimation, setDetailVisibility, simulateAnimation, toggleElementPicker, } = this; const target = this.inspector.target; @@ -72,16 +74,17 @@ class AnimationInspector { id: "newanimationinspector", key: "newanimationinspector", store: this.inspector.store }, App( { emitEventForTest, getAnimatedPropertyMap, + getComputedStyle, getNodeFromActor, onHideBoxModelHighlighter, onShowBoxModelHighlighterForNode, selectAnimation, setDetailVisibility, setSelectedNode, simulateAnimation, toggleElementPicker, @@ -152,16 +155,37 @@ class AnimationInspector { }); animatedPropertyMap.set(name, keyframes); } return animatedPropertyMap; } + /** + * Return the computed style of the specified property after setting the given styles + * to the simulated element. + * + * @param {String} property + * CSS property name (e.g. text-align). + * @param {Object} styles + * Map of CSS property name and value. + * @return {String} + * Computed style of property. + */ + getComputedStyle(property, styles) { + this.simulatedElement.style.cssText = ""; + + for (let propertyName in styles) { + this.simulatedElement.style.setProperty(propertyName, styles[propertyName]); + } + + return this.win.getComputedStyle(this.simulatedElement).getPropertyValue(property); + } + getNodeFromActor(actorID) { return this.inspector.walker.getNodeFromActor(actorID, ["node"]); } isPanelVisible() { return this.inspector && this.inspector.toolbox && this.inspector.sidebar && this.inspector.toolbox.currentToolId === "inspector" && this.inspector.sidebar.getCurrentTabID() === "newanimationinspector";
--- a/devtools/client/inspector/animation/components/AnimatedPropertyItem.js +++ b/devtools/client/inspector/animation/components/AnimatedPropertyItem.js @@ -1,28 +1,59 @@ /* 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 { PureComponent } = require("devtools/client/shared/vendor/react"); +const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const dom = require("devtools/client/shared/vendor/react-dom-factories"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); +const AnimatedPropertyName = createFactory(require("./AnimatedPropertyName")); +const KeyframesGraph = createFactory(require("./keyframes-graph/KeyframesGraph")); + class AnimatedPropertyItem extends PureComponent { static get propTypes() { return { + getComputedStyle: PropTypes.func.isRequired, property: PropTypes.string.isRequired, + simulateAnimation: PropTypes.func.isRequired, + state: PropTypes.object.isRequired, + type: PropTypes.string.isRequired, values: PropTypes.array.isRequired, }; } render() { + const { + getComputedStyle, + property, + simulateAnimation, + state, + type, + values, + } = this.props; + return dom.li( { className: "animated-property-item" - } + }, + AnimatedPropertyName( + { + property, + state, + } + ), + KeyframesGraph( + { + getComputedStyle, + property, + simulateAnimation, + type, + values, + } + ) ); } } module.exports = AnimatedPropertyItem;
--- a/devtools/client/inspector/animation/components/AnimatedPropertyList.js +++ b/devtools/client/inspector/animation/components/AnimatedPropertyList.js @@ -11,16 +11,18 @@ const PropTypes = require("devtools/clie const AnimatedPropertyItem = createFactory(require("./AnimatedPropertyItem")); class AnimatedPropertyList extends PureComponent { static get propTypes() { return { animation: PropTypes.object.isRequired, emitEventForTest: PropTypes.func.isRequired, getAnimatedPropertyMap: PropTypes.func.isRequired, + getComputedStyle: PropTypes.func.isRequired, + simulateAnimation: PropTypes.func.isRequired, }; } constructor(props) { super(props); this.state = { animatedPropertyMap: null @@ -30,43 +32,69 @@ class AnimatedPropertyList extends PureC componentDidMount() { this.updateKeyframesList(this.props.animation); } componentWillReceiveProps(nextProps) { this.updateKeyframesList(nextProps.animation); } + getPropertyState(property) { + const { animation } = this.props; + + for (const propState of animation.state.propertyState) { + if (propState.property === property) { + return propState; + } + } + + return null; + } + async updateKeyframesList(animation) { const { getAnimatedPropertyMap, emitEventForTest, } = this.props; const animatedPropertyMap = await getAnimatedPropertyMap(animation); + const animationTypes = await animation.getAnimationTypes(animatedPropertyMap.keys()); - this.setState({ animatedPropertyMap }); + this.setState({ animatedPropertyMap, animationTypes }); emitEventForTest("animation-keyframes-rendered"); } render() { - const { animatedPropertyMap } = this.state; + const { + getComputedStyle, + simulateAnimation, + } = this.props; + const { + animatedPropertyMap, + animationTypes, + } = this.state; if (!animatedPropertyMap) { return null; } return dom.ul( { className: "animated-property-list" }, [...animatedPropertyMap.entries()].map(([property, values]) => { + const state = this.getPropertyState(property); + const type = animationTypes[property]; return AnimatedPropertyItem( { + getComputedStyle, property, + simulateAnimation, + state, + type, values, } ); }) ); } }
--- a/devtools/client/inspector/animation/components/AnimatedPropertyListContainer.js +++ b/devtools/client/inspector/animation/components/AnimatedPropertyListContainer.js @@ -12,35 +12,41 @@ const AnimatedPropertyList = createFacto const AnimatedPropertyListHeader = createFactory(require("./AnimatedPropertyListHeader")); class AnimatedPropertyListContainer extends PureComponent { static get propTypes() { return { animation: PropTypes.object.isRequired, emitEventForTest: PropTypes.func.isRequired, getAnimatedPropertyMap: PropTypes.func.isRequired, + getComputedStyle: PropTypes.func.isRequired, + simulateAnimation: PropTypes.func.isRequired, }; } render() { const { animation, emitEventForTest, getAnimatedPropertyMap, + getComputedStyle, + simulateAnimation, } = this.props; return dom.div( { - className: "animated-property-list-container" + className: `animated-property-list-container ${ animation.state.type }` }, AnimatedPropertyListHeader(), AnimatedPropertyList( { animation, emitEventForTest, getAnimatedPropertyMap, + getComputedStyle, + simulateAnimation, } ) ); } } module.exports = AnimatedPropertyListContainer;
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/AnimatedPropertyName.js @@ -0,0 +1,40 @@ +/* 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 { PureComponent } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); + +class AnimatedPropertyName extends PureComponent { + static get propTypes() { + return { + property: PropTypes.string.isRequired, + state: PropTypes.oneOfType([null, PropTypes.object]).isRequired, + }; + } + + render() { + const { + property, + state, + } = this.props; + + return dom.div( + { + className: "animated-property-name" + + (state && state.runningOnCompositor ? " compositor" : "") + + (state && state.warning ? " warning" : ""), + title: state ? state.warning : "", + }, + dom.span( + {}, + property + ) + ); + } +} + +module.exports = AnimatedPropertyName;
--- a/devtools/client/inspector/animation/components/AnimationDetailContainer.js +++ b/devtools/client/inspector/animation/components/AnimationDetailContainer.js @@ -14,26 +14,30 @@ const AnimatedPropertyListContainer = createFactory(require("./AnimatedPropertyListContainer")); class AnimationDetailContainer extends PureComponent { static get propTypes() { return { animation: PropTypes.object.isRequired, emitEventForTest: PropTypes.func.isRequired, getAnimatedPropertyMap: PropTypes.func.isRequired, + getComputedStyle: PropTypes.func.isRequired, setDetailVisibility: PropTypes.func.isRequired, + simulateAnimation: PropTypes.func.isRequired, }; } render() { const { animation, emitEventForTest, getAnimatedPropertyMap, + getComputedStyle, setDetailVisibility, + simulateAnimation, } = this.props; return dom.div( { className: "animation-detail-container" }, animation ? AnimationDetailHeader( @@ -45,16 +49,18 @@ class AnimationDetailContainer extends P : null, animation ? AnimatedPropertyListContainer( { animation, emitEventForTest, getAnimatedPropertyMap, + getComputedStyle, + simulateAnimation, } ) : null ); } }
--- a/devtools/client/inspector/animation/components/App.js +++ b/devtools/client/inspector/animation/components/App.js @@ -16,16 +16,17 @@ const SplitBox = createFactory(require(" class App extends PureComponent { static get propTypes() { return { animations: PropTypes.arrayOf(PropTypes.object).isRequired, detailVisibility: PropTypes.bool.isRequired, emitEventForTest: PropTypes.func.isRequired, getAnimatedPropertyMap: PropTypes.func.isRequired, + getComputedStyle: PropTypes.func.isRequired, getNodeFromActor: PropTypes.func.isRequired, onHideBoxModelHighlighter: PropTypes.func.isRequired, onShowBoxModelHighlighterForNode: PropTypes.func.isRequired, selectAnimation: PropTypes.func.isRequired, setDetailVisibility: PropTypes.func.isRequired, setSelectedNode: PropTypes.func.isRequired, simulateAnimation: PropTypes.func.isRequired, toggleElementPicker: PropTypes.func.isRequired, @@ -37,16 +38,17 @@ class App extends PureComponent { } render() { const { animations, detailVisibility, emitEventForTest, getAnimatedPropertyMap, + getComputedStyle, getNodeFromActor, onHideBoxModelHighlighter, onShowBoxModelHighlighterForNode, selectAnimation, setDetailVisibility, setSelectedNode, simulateAnimation, toggleElementPicker, @@ -59,17 +61,19 @@ class App extends PureComponent { }, animations.length ? SplitBox({ className: "animation-container-splitter", endPanel: AnimationDetailContainer( { emitEventForTest, getAnimatedPropertyMap, + getComputedStyle, setDetailVisibility, + simulateAnimation, } ), endPanelControl: true, initialHeight: "50%", splitterSize: 1, startPanel: AnimationListContainer( { animations,
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/keyframes-graph/ColorPath.js @@ -0,0 +1,184 @@ +/* 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 dom = require("devtools/client/shared/vendor/react-dom-factories"); + +const {colorUtils} = require("devtools/shared/css/color.js"); + +const ComputedStylePath = require("./ComputedStylePath"); + +/* Count for linearGradient ID */ +let LINEAR_GRADIENT_ID_COUNT = 0; + +class ColorPath extends ComputedStylePath { + constructor(props) { + super(props); + + this.state = this.propToState(props); + } + + componentWillReceiveProps(nextProps) { + this.setState(this.propToState(nextProps)); + } + + getPropertyName() { + return "color"; + } + + getPropertyValue(keyframe) { + return keyframe.value; + } + + propToState({ values }) { + const maxObject = { distance: 0 }; + + for (let i = 0; i < values.length - 1; i++) { + const value1 = getRGBA(values[i].value); + for (let j = i + 1; j < values.length; j++) { + const value2 = getRGBA(values[j].value); + const distance = getRGBADistance(value1, value2); + + if (maxObject.distance >= distance) { + continue; + } + + maxObject.distance = distance; + maxObject.value1 = value1; + maxObject.value2 = value2; + } + } + + const maxDistance = maxObject.distance; + const baseValue = + maxObject.value1 < maxObject.value2 ? maxObject.value1 : maxObject.value2; + + return { baseValue, maxDistance }; + } + + toSegmentValue(computedStyle) { + const { baseValue, maxDistance } = this.state; + const value = getRGBA(computedStyle); + return getRGBADistance(baseValue, value) / maxDistance; + } + + /** + * Overide parent's method. + */ + renderEasingHint() { + const { + easingHintStrokeWidth, + graphHeight, + totalDuration, + values, + } = this.props; + + const hints = []; + + for (let i = 0; i < values.length - 1; i++) { + const startKeyframe = values[i]; + const endKeyframe = values[i + 1]; + const startTime = startKeyframe.offset * totalDuration; + const endTime = endKeyframe.offset * totalDuration; + + const g = dom.g( + { + className: "hint" + }, + dom.title({}, startKeyframe.easing), + dom.rect( + { + x: startTime, + y: -graphHeight, + height: graphHeight, + width: endTime - startTime, + style: { + "stroke-width": easingHintStrokeWidth, + }, + } + ) + ); + hints.push(g); + } + + return hints; + } + + /** + * Overide parent's method. + */ + renderPathSegments(segments) { + for (const segment of segments) { + segment.y = 1; + } + + const lastSegment = segments[segments.length - 1]; + const id = `color-property-${ LINEAR_GRADIENT_ID_COUNT++ }`; + const path = super.renderPathSegments(segments, { fill: `url(#${ id })` }); + const linearGradient = dom.linearGradient( + { id }, + segments.map(segment => { + return dom.stop( + { + "stopColor": segment.computedStyle, + "offset": segment.x / lastSegment.x, + } + ); + }) + ); + + return [path, linearGradient]; + } + + render() { + return dom.g( + { + className: "color-path", + }, + super.renderGraph() + ); + } +} + +/** + * Parse given RGBA string. + * + * @param {String} colorString + * e.g. rgb(0, 0, 0) or rgba(0, 0, 0, 0.5) and so on. + * @return {Object} + * RGBA {r: r, g: g, b: b, a: a}. + */ +function getRGBA(colorString) { + const color = new colorUtils.CssColor(colorString); + return color.getRGBATuple(); +} + +/** + * Return the distance from give two RGBA. + * + * @param {Object} rgba1 + * RGBA (format is same to getRGBA) + * @param {Object} rgba2 + * RGBA (format is same to getRGBA) + * @return {Number} + * The range is 0 - 1.0. + */ +function getRGBADistance(rgba1, rgba2) { + const startA = rgba1.a; + const startR = rgba1.r * startA; + const startG = rgba1.g * startA; + const startB = rgba1.b * startA; + const endA = rgba2.a; + const endR = rgba2.r * endA; + const endG = rgba2.g * endA; + const endB = rgba2.b * endA; + const diffA = startA - endA; + const diffR = startR - endR; + const diffG = startG - endG; + const diffB = startB - endB; + return Math.sqrt(diffA * diffA + diffR * diffR + diffG * diffG + diffB * diffB); +} + +module.exports = ColorPath;
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/keyframes-graph/ComputedStylePath.js @@ -0,0 +1,233 @@ +/* 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 { PureComponent } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); + +const { + createPathSegments, + DEFAULT_DURATION_RESOLUTION, + getPreferredProgressThresholdByKeyframes, + toPathString, +} = require("../../utils/graph-helper"); + +/* + * This class is an abstraction for computed style path of keyframes. + * Subclass of this should implement the following methods: + * + * getPropertyName() + * Returns property name which will be animated. + * @return {String} + * e.g. opacity + * + * getPropertyValue(keyframe) + * Returns value which uses as animated keyframe value from given parameter. + * @param {Object} keyframe + * @return {String||Number} + * e.g. 0 + * + * toSegmentValue(computedStyle) + * Convert computed style to segment value of graph. + * @param {String||Number} + * e.g. 0 + * @return {Number} + * e.g. 0 (should be 0 - 1.0) + */ +class ComputedStylePath extends PureComponent { + static get propTypes() { + return { + componentWidth: PropTypes.number.isRequired, + easingHintStrokeWidth: PropTypes.number.isRequired, + graphHeight: PropTypes.number.isRequired, + simulateAnimation: PropTypes.func.isRequired, + totalDuration: PropTypes.number.isRequired, + values: PropTypes.array.isRequired, + }; + } + + /** + * Return an array containing the path segments between the given start and + * end keyframe values. + * + * @param {Object} startValue + * Starting keyframe. + * @param {Object} startValue + * Ending keyframe. + * @return {Array} + * Array of path segment. + * [{x: {Number} time, y: {Number} segment value}, ...] + */ + getPathSegments(startValue, endValue) { + const { + componentWidth, + simulateAnimation, + totalDuration, + } = this.props; + + const propertyName = this.getPropertyName(); + const offsetDistance = endValue.offset - startValue.offset; + const duration = offsetDistance * totalDuration; + + const keyframes = [startValue, endValue].map((keyframe, index) => { + return { + offset: index, + easing: keyframe.easing, + [getJsPropertyName(propertyName)]: this.getPropertyValue(keyframe), + }; + }); + const effect = { + duration, + fill: "forwards", + }; + const simulatedAnimation = simulateAnimation(keyframes, effect, true); + const simulatedElement = simulatedAnimation.effect.target; + const win = simulatedElement.ownerGlobal; + const threshold = getPreferredProgressThresholdByKeyframes(keyframes); + + const getSegment = time => { + simulatedAnimation.currentTime = time; + const computedStyle = + win.getComputedStyle(simulatedElement).getPropertyValue(propertyName); + + return { + computedStyle, + x: time, + y: this.toSegmentValue(computedStyle), + }; + }; + + const segments = createPathSegments(0, duration, duration / componentWidth, threshold, + DEFAULT_DURATION_RESOLUTION, getSegment); + const offset = startValue.offset * totalDuration; + + for (const segment of segments) { + segment.x += offset; + } + + return segments; + } + + /** + * Render easing hint from given path segments. + * + * @param {Array} segments + * Path segments. + * @return {Element} + * Element which represents easing hint. + */ + renderEasingHint(segments) { + const { + easingHintStrokeWidth, + totalDuration, + values, + } = this.props; + + const hints = []; + + for (let i = 0, indexOfSegments = 0; i < values.length - 1; i++) { + const startKeyframe = values[i]; + const endKeyframe = values[i + 1]; + const endTime = endKeyframe.offset * totalDuration; + const hintSegments = []; + + for (; indexOfSegments < segments.length; indexOfSegments++) { + const segment = segments[indexOfSegments]; + hintSegments.push(segment); + + if (startKeyframe.offset === endKeyframe.offset) { + hintSegments.push(segments[++indexOfSegments]); + break; + } else if (segment.x === endTime) { + break; + } + } + + const g = dom.g( + { + className: "hint" + }, + dom.title({}, startKeyframe.easing), + dom.path( + { + d: `M${ hintSegments[0].x },${ hintSegments[0].y } ` + + toPathString(hintSegments), + style: { + "stroke-width": easingHintStrokeWidth, + } + } + ) + ); + + hints.push(g); + } + + return hints; + } + + /** + * Render graph. This method returns React dom. + * + * @return {Element} + */ + renderGraph() { + const { values } = this.props; + + const segments = []; + + for (let i = 0; i < values.length - 1; i++) { + const startValue = values[i]; + const endValue = values[i + 1]; + segments.push(...this.getPathSegments(startValue, endValue)); + } + + return [ + this.renderPathSegments(segments), + this.renderEasingHint(segments) + ]; + } + + /** + * Return react dom fron given path segments. + * + * @param {Array} segments + * @param {Object} style + * @return {Element} + */ + renderPathSegments(segments, style) { + const { graphHeight } = this.props; + + for (const segment of segments) { + segment.y *= graphHeight; + } + + let d = `M${ segments[0].x },0 `; + d += toPathString(segments); + d += `L${ segments[segments.length - 1].x },0 Z`; + + return dom.path({ d, style }); + } +} + +/** + * Convert given CSS property name to JavaScript CSS name. + * + * @param {String} cssPropertyName + * CSS property name (e.g. background-color). + * @return {String} + * JavaScript CSS property name (e.g. backgroundColor). + */ +function getJsPropertyName(cssPropertyName) { + if (cssPropertyName == "float") { + return "cssFloat"; + } + // https://drafts.csswg.org/cssom/#css-property-to-idl-attribute + return cssPropertyName.replace(/-([a-z])/gi, (str, group) => { + return group.toUpperCase(); + }); +} + +module.exports = ComputedStylePath;
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/keyframes-graph/DiscretePath.js @@ -0,0 +1,66 @@ +/* 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 dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); + +const ComputedStylePath = require("./ComputedStylePath"); + +class DiscretePath extends ComputedStylePath { + static get propTypes() { + return { + property: PropTypes.string.isRequired, + }; + } + + constructor(props) { + super(props); + + this.state = this.propToState(props); + } + + componentWillReceiveProps(nextProps) { + this.setState(this.propToState(nextProps)); + } + + getPropertyName() { + return this.props.property; + } + + getPropertyValue(keyframe) { + return keyframe.value; + } + + propToState({ property, getComputedStyle, values }) { + const discreteValues = []; + + for (const keyframe of values) { + const style = getComputedStyle(property, { [property]: keyframe.value }); + + if (!discreteValues.includes(style)) { + discreteValues.push(style); + } + } + + return { discreteValues }; + } + + toSegmentValue(computedStyle) { + const { discreteValues } = this.state; + return discreteValues.indexOf(computedStyle) / (discreteValues.length - 1); + } + + render() { + return dom.g( + { + className: "discrete-path", + }, + super.renderGraph() + ); + } +} + +module.exports = DiscretePath;
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/keyframes-graph/DistancePath.js @@ -0,0 +1,34 @@ +/* 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 dom = require("devtools/client/shared/vendor/react-dom-factories"); + +const ComputedStylePath = require("./ComputedStylePath"); + +class DistancePath extends ComputedStylePath { + getPropertyName() { + return "opacity"; + } + + getPropertyValue(keyframe) { + return keyframe.distance; + } + + toSegmentValue(computedStyle) { + return computedStyle; + } + + render() { + return dom.g( + { + className: "distance-path", + }, + super.renderGraph() + ); + } +} + +module.exports = DistancePath;
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/keyframes-graph/KeyframeMarkerItem.js @@ -0,0 +1,33 @@ +/* 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 { PureComponent } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); + +class KeyframeMarkerItem extends PureComponent { + static get propTypes() { + return { + keyframe: PropTypes.object.isRequired, + }; + } + + render() { + const { keyframe } = this.props; + + return dom.li( + { + className: "keyframe-marker-item", + title: keyframe.value, + style: { + left: `${ keyframe.offset * 100 }%`, + }, + } + ); + } +} + +module.exports = KeyframeMarkerItem;
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/keyframes-graph/KeyframeMarkerList.js @@ -0,0 +1,32 @@ +/* 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 { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); + +const KeyframeMarkerItem = createFactory(require("./KeyframeMarkerItem")); + +class KeyframeMarkerList extends PureComponent { + static get propTypes() { + return { + values: PropTypes.array.isRequired, + }; + } + + render() { + const { values } = this.props; + + return dom.ul( + { + className: "keyframe-marker-list" + }, + values.map(value => KeyframeMarkerItem({ keyframe: value })) + ); + } +} + +module.exports = KeyframeMarkerList;
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/keyframes-graph/KeyframesGraph.js @@ -0,0 +1,52 @@ +/* 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 { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); + +const KeyframeMarkerList = createFactory(require("./KeyframeMarkerList")); +const KeyframesGraphPath = createFactory(require("./KeyframesGraphPath")); + +class KeyframesGraph extends PureComponent { + static get propTypes() { + return { + getComputedStyle: PropTypes.func.isRequired, + property: PropTypes.string.isRequired, + simulateAnimation: PropTypes.func.isRequired, + type: PropTypes.string.isRequired, + values: PropTypes.array.isRequired, + }; + } + + render() { + const { + getComputedStyle, + property, + simulateAnimation, + type, + values, + } = this.props; + + return dom.div( + { + className: `keyframes-graph ${ property }` + }, + KeyframesGraphPath( + { + getComputedStyle, + property, + simulateAnimation, + type, + values, + } + ), + KeyframeMarkerList({ values }) + ); + } +} + +module.exports = KeyframesGraph;
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/keyframes-graph/KeyframesGraphPath.js @@ -0,0 +1,110 @@ +/* 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 { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); +const ReactDOM = require("devtools/client/shared/vendor/react-dom"); + +const ColorPath = createFactory(require("./ColorPath")); +const DiscretePath = createFactory(require("./DiscretePath")); +const DistancePath = createFactory(require("./DistancePath")); + +const { + DEFAULT_EASING_HINT_STROKE_WIDTH, + DEFAULT_GRAPH_HEIGHT, + DEFAULT_KEYFRAMES_GRAPH_DURATION, +} = require("../../utils/graph-helper"); + +class KeyframesGraphPath extends PureComponent { + static get propTypes() { + return { + getComputedStyle: PropTypes.func.isRequired, + property: PropTypes.string.isRequired, + simulateAnimation: PropTypes.func.isRequired, + type: PropTypes.string.isRequired, + values: PropTypes.array.isRequired, + }; + } + + constructor(props) { + super(props); + + this.state = { + componentHeight: 0, + componentWidth: 0, + }; + } + + componentDidMount() { + this.updateState(); + } + + getPathComponent(type) { + switch (type) { + case "color" : + return ColorPath; + case "discrete" : + return DiscretePath; + default : + return DistancePath; + } + } + + updateState() { + const thisEl = ReactDOM.findDOMNode(this); + this.setState({ + componentHeight: thisEl.parentNode.clientHeight, + componentWidth: thisEl.parentNode.clientWidth, + }); + } + + render() { + const { + getComputedStyle, + property, + simulateAnimation, + type, + values, + } = this.props; + const { + componentHeight, + componentWidth, + } = this.state; + + if (!componentWidth) { + return dom.svg(); + } + + const pathComponent = this.getPathComponent(type); + const strokeWidthInViewBox = + DEFAULT_EASING_HINT_STROKE_WIDTH / 2 / componentHeight * DEFAULT_GRAPH_HEIGHT; + + return dom.svg( + { + className: "keyframes-graph-path", + preserveAspectRatio: "none", + viewBox: `0 -${ DEFAULT_GRAPH_HEIGHT + strokeWidthInViewBox } ` + + `${ DEFAULT_KEYFRAMES_GRAPH_DURATION } ` + + `${ DEFAULT_GRAPH_HEIGHT + strokeWidthInViewBox * 2 }`, + }, + pathComponent( + { + componentWidth, + easingHintStrokeWidth: DEFAULT_EASING_HINT_STROKE_WIDTH, + getComputedStyle, + graphHeight: DEFAULT_GRAPH_HEIGHT, + property, + simulateAnimation, + totalDuration: DEFAULT_KEYFRAMES_GRAPH_DURATION, + values, + } + ) + ); + } +} + +module.exports = KeyframesGraphPath;
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/components/keyframes-graph/moz.build @@ -0,0 +1,14 @@ +# 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/. + +DevToolsModules( + 'ColorPath.js', + 'ComputedStylePath.js', + 'DiscretePath.js', + 'DistancePath.js', + 'KeyframeMarkerItem.js', + 'KeyframeMarkerList.js', + 'KeyframesGraph.js', + 'KeyframesGraphPath.js', +)
--- a/devtools/client/inspector/animation/components/moz.build +++ b/devtools/client/inspector/animation/components/moz.build @@ -1,21 +1,23 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. DIRS += [ - 'graph' + 'graph', + 'keyframes-graph' ] DevToolsModules( 'AnimatedPropertyItem.js', 'AnimatedPropertyList.js', 'AnimatedPropertyListContainer.js', 'AnimatedPropertyListHeader.js', + 'AnimatedPropertyName.js', 'AnimationDetailContainer.js', 'AnimationDetailHeader.js', 'AnimationItem.js', 'AnimationList.js', 'AnimationListContainer.js', 'AnimationListHeader.js', 'AnimationTarget.js', 'AnimationTimelineTickItem.js',
--- a/devtools/client/inspector/animation/test/browser.ini +++ b/devtools/client/inspector/animation/test/browser.ini @@ -1,30 +1,36 @@ [DEFAULT] tags = devtools subsuite = devtools support-files = + doc_multi_easings.html + doc_multi_keyframes.html doc_multi_timings.html doc_simple_animation.html head.js !/devtools/client/framework/test/shared-head.js !/devtools/client/inspector/test/head.js !/devtools/client/inspector/test/shared-head.js !/devtools/client/shared/test/test-actor-registry.js !/devtools/client/shared/test/test-actor.js [browser_animation_animated-property-list.js] +[browser_animation_animated-property-name.js] [browser_animation_animation-detail_close-button.js] [browser_animation_animation-detail_title.js] [browser_animation_animation-detail_visibility.js] [browser_animation_animation-list.js] [browser_animation_animation-target.js] [browser_animation_animation-timeline-tick.js] [browser_animation_empty_on_invalid_nodes.js] [browser_animation_inspector_exists.js] +[browser_animation_keyframes-graph_computed-value-path.js] +[browser_animation_keyframes-graph_computed-value-path_easing-hint.js] +[browser_animation_keyframes-graph_keyframe-marker.js] [browser_animation_summary-graph_animation-name.js] [browser_animation_summary-graph_compositor.js] [browser_animation_summary-graph_computed-timing-path.js] [browser_animation_summary-graph_delay-sign.js] [browser_animation_summary-graph_end-delay-sign.js] [browser_animation_summary-graph_effect-timing-path.js] [browser_animation_summary-graph_negative-delay-path.js] [browser_animation_summary-graph_negative-end-delay-path.js]
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/test/browser_animation_animated-property-name.js @@ -0,0 +1,79 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test the following animated property name component features: +// * name of property +// * display compositor sign when the property was running on compositor. +// * display warning when the property is runnable on compositor but was not. + +const TEST_DATA = [ + { + property: "opacity", + isOnCompositor: true, + }, + { + property: "transform", + isWarning: true, + }, + { + property: "width", + }, +]; + +add_task(async function () { + await addTab(URL_ROOT + "doc_simple_animation.html"); + const { inspector, panel } = await openAnimationInspector(); + + info("Checking animated property name component"); + await selectNodeAndWaitForAnimations(".compositor-notall", inspector); + + const animatedPropertyNameEls = panel.querySelectorAll(".animated-property-name"); + is(animatedPropertyNameEls.length, TEST_DATA.length, + `Number of animated property name elements should be ${ TEST_DATA.length }`); + + for (const [index, animatedPropertyNameEl] of animatedPropertyNameEls.entries()) { + const testData = TEST_DATA[index]; + + info(`Checking text content for ${ testData.property }`); + + const spanEl = animatedPropertyNameEl.querySelector("span"); + ok(spanEl, + `<span> element should be in animated-property-name of ${ testData.property }`); + is(spanEl.textContent, testData.property, + `textContent should be ${ testData.property }`); + + info(`Checking compositor sign for ${ testData.property }`); + + if (testData.isOnCompositor) { + ok(animatedPropertyNameEl.classList.contains("compositor"), + "animatedPropertyNameEl should has .compositor class"); + isnot(getComputedStyle(spanEl, "::before").width, "auto", + "width of ::before pseud should not be auto"); + } else { + ok(!animatedPropertyNameEl.classList.contains("compositor"), + "animatedPropertyNameEl should not have .compositor class"); + is(getComputedStyle(spanEl, "::before").width, "auto", + "width of ::before pseud should be auto"); + } + + info(`Checking warning for ${ testData.property }`); + + if (testData.isWarning) { + ok(animatedPropertyNameEl.classList.contains("warning"), + "animatedPropertyNameEl should has .warning class"); + is(getComputedStyle(spanEl).textDecorationStyle, "dotted", + "text-decoration-style of spanEl should be 'dotted'"); + is(getComputedStyle(spanEl).textDecorationLine, "underline", + "text-decoration-line of spanEl should be 'underline'"); + } else { + ok(!animatedPropertyNameEl.classList.contains("warning"), + "animatedPropertyNameEl should not have .warning class"); + is(getComputedStyle(spanEl).textDecorationStyle, "solid", + "text-decoration-style of spanEl should be 'solid'"); + is(getComputedStyle(spanEl).textDecorationLine, "none", + "text-decoration-line of spanEl should be 'none'"); + } + } +});
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/test/browser_animation_keyframes-graph_computed-value-path.js @@ -0,0 +1,461 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test for following ComputedValuePath component: +// * element existence +// * path segments +// * fill color by animation type +// * stop color if the animation type is color + +const TEST_DATA = [ + { + targetName: "multi-types", + properties: [ + { + name: "background-color", + computedValuePathClass: "color-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 0, y: 100 }, + { x: 1000, y: 100 }, + ], + expectedStopColors: [ + { offset: 0, color: "rgb(255, 0, 0)" }, + { offset: 1, color: "rgb(0, 255, 0)" }, + ] + }, + { + name: "background-repeat", + computedValuePathClass: "discrete-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 499.999, y: 0 }, + { x: 500, y: 100 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "font-size", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 500, y: 50 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "margin-left", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 500, y: 50 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "opacity", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 500, y: 50 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "text-align", + computedValuePathClass: "discrete-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 499.999, y: 0 }, + { x: 500, y: 100 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "transform", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 500, y: 50 }, + { x: 1000, y: 100 }, + ], + }, + ], + }, + { + targetName: "multi-types-reverse", + properties: [ + { + name: "background-color", + computedValuePathClass: "color-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 0, y: 100 }, + { x: 1000, y: 100 }, + ], + expectedStopColors: [ + { offset: 0, color: "rgb(0, 255, 0)" }, + { offset: 1, color: "rgb(255, 0, 0)" }, + ] + }, + { + name: "background-repeat", + computedValuePathClass: "discrete-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 499.999, y: 0 }, + { x: 500, y: 100 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "font-size", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 100 }, + { x: 500, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + { + name: "margin-left", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 100 }, + { x: 500, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + { + name: "opacity", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 100 }, + { x: 500, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + { + name: "text-align", + computedValuePathClass: "discrete-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 499.999, y: 0 }, + { x: 500, y: 100 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "transform", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 100 }, + { x: 500, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + ], + }, + { + targetName: "middle-keyframe", + properties: [ + { + name: "background-color", + computedValuePathClass: "color-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 0, y: 100 }, + { x: 500, y: 100 }, + { x: 1000, y: 100 }, + ], + expectedStopColors: [ + { offset: 0, color: "rgb(255, 0, 0)" }, + { offset: 0.5, color: "rgb(0, 0, 255)" }, + { offset: 1, color: "rgb(0, 255, 0)" }, + ] + }, + { + name: "background-repeat", + computedValuePathClass: "discrete-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 249.999, y: 0 }, + { x: 250, y: 100 }, + { x: 749.999, y: 100 }, + { x: 750, y: 0 }, + { x: 1000, y: 0 }, + ], + }, + { + name: "font-size", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 250, y: 50 }, + { x: 500, y: 100 }, + { x: 750, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + { + name: "margin-left", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 250, y: 50 }, + { x: 500, y: 100 }, + { x: 750, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + { + name: "opacity", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 250, y: 50 }, + { x: 500, y: 100 }, + { x: 750, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + { + name: "text-align", + computedValuePathClass: "discrete-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 249.999, y: 0 }, + { x: 250, y: 100 }, + { x: 749.999, y: 100 }, + { x: 750, y: 0 }, + { x: 1000, y: 0 }, + ], + }, + { + name: "transform", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 250, y: 50 }, + { x: 500, y: 100 }, + { x: 750, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + ], + }, + { + targetName: "steps-keyframe", + properties: [ + { + name: "background-color", + computedValuePathClass: "color-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 0, y: 100 }, + { x: 500, y: 100 }, + { x: 1000, y: 100 }, + ], + expectedStopColors: [ + { offset: 0, color: "rgb(255, 0, 0)" }, + { offset: 0.499, color: "rgb(255, 0, 0)" }, + { offset: 0.5, color: "rgb(128, 128, 0)" }, + { offset: 0.999, color: "rgb(128, 128, 0)" }, + { offset: 1, color: "rgb(0, 255, 0)" }, + ] + }, + { + name: "background-repeat", + computedValuePathClass: "discrete-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 499.999, y: 0 }, + { x: 500, y: 100 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "font-size", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 500, y: 0 }, + { x: 500, y: 50 }, + { x: 1000, y: 50 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "margin-left", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 499.999, y: 0 }, + { x: 500, y: 50 }, + { x: 999.999, y: 50 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "opacity", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 499.999, y: 0 }, + { x: 500, y: 50 }, + { x: 999.999, y: 50 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "text-align", + computedValuePathClass: "discrete-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 499.999, y: 0 }, + { x: 500, y: 100 }, + { x: 1000, y: 100 }, + ], + }, + { + name: "transform", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 500, y: 0 }, + { x: 500, y: 50 }, + { x: 1000, y: 50 }, + { x: 1000, y: 100 }, + ], + }, + ], + }, + { + targetName: "steps-effect", + properties: [ + { + name: "opacity", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 250, y: 25 }, + { x: 500, y: 50 }, + { x: 750, y: 75 }, + { x: 1000, y: 100 }, + ], + }, + ], + }, + { + targetName: "frames-keyframe", + properties: [ + { + name: "opacity", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 199, y: 0 }, + { x: 200, y: 25 }, + { x: 399, y: 25 }, + { x: 400, y: 50 }, + { x: 599, y: 50 }, + { x: 600, y: 75 }, + { x: 799, y: 75 }, + { x: 800, y: 100 }, + { x: 1000, y: 100 }, + ], + }, + ], + }, + { + targetName: "narrow-offsets", + properties: [ + { + name: "opacity", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 0 }, + { x: 100, y: 100 }, + { x: 110, y: 100 }, + { x: 114.9, y: 100 }, + { x: 115, y: 50 }, + { x: 129.9, y: 50 }, + { x: 130, y: 0 }, + { x: 1000, y: 100 }, + ], + }, + ], + }, + { + targetName: "duplicate-offsets", + properties: [ + { + name: "opacity", + computedValuePathClass: "distance-path", + expectedPathSegments: [ + { x: 0, y: 100 }, + { x: 250, y: 100 }, + { x: 499, y: 100 }, + { x: 500, y: 100 }, + { x: 500, y: 0 }, + { x: 750, y: 50 }, + { x: 1000, y: 100 }, + ], + }, + ], + }, +]; + +add_task(async function () { + await addTab(URL_ROOT + "doc_multi_keyframes.html"); + + const { inspector, panel } = await openAnimationInspector(); + + for (const { properties, targetName } of TEST_DATA) { + info(`Checking keyframes graph for ${ targetName }`); + await selectNodeAndWaitForAnimations(`#${ targetName }`, inspector); + + for (const property of properties) { + const { + name, + computedValuePathClass, + expectedPathSegments, + expectedStopColors, + } = property; + + const testTarget = `${ name } in ${ targetName }`; + info(`Checking keyframes graph for ${ testTarget }`); + info(`Checking keyframes graph path existence for ${ testTarget }`); + const keyframesGraphPathEl = panel.querySelector(`.${ name }`); + ok(keyframesGraphPathEl, + `The keyframes graph path element of ${ testTarget } should be existence`); + + info(`Checking computed value path existence for ${ testTarget }`); + const computedValuePathEl = + keyframesGraphPathEl.querySelector(`.${ computedValuePathClass }`); + ok(computedValuePathEl, + `The computed value path element of ${ testTarget } should be existence`); + + info(`Checking path segments for ${ testTarget }`); + const pathEl = computedValuePathEl.querySelector("path"); + ok(pathEl, `The <path> element of ${ testTarget } should be existence`); + assertPathSegments(pathEl, true, expectedPathSegments); + + if (!expectedStopColors) { + continue; + } + + info(`Checking linearGradient for ${ testTarget }`); + const linearGradientEl = computedValuePathEl.querySelector("linearGradient"); + ok(linearGradientEl, + `The <linearGradientEl> element of ${ testTarget } should be existence`); + + for (const expectedStopColor of expectedStopColors) { + const { offset, color } = expectedStopColor; + assertLinearGradient(linearGradientEl, offset, color); + } + } + } +});
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/test/browser_animation_keyframes-graph_computed-value-path_easing-hint.js @@ -0,0 +1,275 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test for following easing hint in ComputedValuePath. +// * element existence +// * path segments +// * hint text + +const TEST_DATA = [ + { + targetName: "no-easing", + properties: [ + { + name: "opacity", + expectedHints: [ + { + hint: "linear", + path: [ + { x: 0, y: 100 }, + { x: 500, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + ], + }, + ], + }, + { + targetName: "effect-easing", + properties: [ + { + name: "opacity", + expectedHints: [ + { + hint: "linear", + path: [ + { x: 0, y: 100 }, + { x: 500, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + ], + }, + ], + }, + { + targetName: "keyframe-easing", + properties: [ + { + name: "opacity", + expectedHints: [ + { + hint: "steps(2)", + path: [ + { x: 0, y: 100 }, + { x: 499, y: 100 }, + { x: 500, y: 50 }, + { x: 999, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + ], + }, + ], + }, + { + targetName: "both-easing", + properties: [ + { + name: "margin-left", + expectedHints: [ + { + hint: "steps(1)", + path: [ + { x: 0, y: 0 }, + { x: 999, y: 0 }, + { x: 1000, y: 100 }, + ], + }, + ], + }, + { + name: "opacity", + expectedHints: [ + { + hint: "steps(2)", + path: [ + { x: 0, y: 100 }, + { x: 499, y: 100 }, + { x: 500, y: 50 }, + { x: 999, y: 50 }, + { x: 1000, y: 0 }, + ], + }, + ], + }, + ], + }, + { + targetName: "narrow-keyframes", + properties: [ + { + name: "opacity", + expectedHints: [ + { + hint: "linear", + path: [ + { x: 0, y: 0 }, + { x: 100, y: 100 }, + ], + }, + { + hint: "steps(1)", + path: [ + { x: 129, y: 100 }, + { x: 130, y: 0 }, + ], + }, + { + hint: "linear", + path: [ + { x: 130, y: 0 }, + { x: 1000, y: 100 }, + ], + }, + ], + }, + ], + }, + { + targetName: "duplicate-keyframes", + properties: [ + { + name: "opacity", + expectedHints: [ + { + hint: "linear", + path: [ + { x: 0, y: 0 }, + { x: 500, y: 100 }, + ], + }, + { + hint: "", + path: [ + { x: 500, y: 100 }, + { x: 500, y: 0 }, + ], + }, + { + hint: "steps(1)", + path: [ + { x: 500, y: 0 }, + { x: 999, y: 0 }, + { x: 1000, y: 100 }, + ], + }, + ], + }, + ], + }, + { + targetName: "color-keyframes", + properties: [ + { + name: "color", + expectedHints: [ + { + hint: "ease-in", + rect: { + x: 0, + height: 100, + width: 400, + }, + }, + { + hint: "ease-out", + rect: { + x: 400, + height: 100, + width: 600, + }, + }, + ], + }, + ], + }, +]; + +add_task(async function () { + await addTab(URL_ROOT + "doc_multi_easings.html"); + + const { inspector, panel } = await openAnimationInspector(); + + for (const { properties, targetName } of TEST_DATA) { + info(`Checking keyframes graph for ${ targetName }`); + await selectNodeAndWaitForAnimations(`#${ targetName }`, inspector); + + for (const property of properties) { + const { + name, + expectedHints, + } = property; + + const testTarget = `${ name } in ${ targetName }`; + info(`Checking easing hint for ${ testTarget }`); + info(`Checking easing hint existence for ${ testTarget }`); + const hintEls = panel.querySelectorAll(`.${ name } .hint`); + is(hintEls.length, expectedHints.length, + `Count of easing hint elements of ${ testTarget } ` + + `should be ${ expectedHints.length }`); + + for (let i = 0; i < expectedHints.length; i++) { + const hintTarget = `hint[${ i }] of ${ testTarget }`; + + info(`Checking ${ hintTarget }`); + const hintEl = hintEls[i]; + const expectedHint = expectedHints[i]; + + info(`Checking <title> in ${ hintTarget }`); + const titleEl = hintEl.querySelector("title"); + ok(titleEl, + `<title> element in ${ hintTarget } should be existence`); + is(titleEl.textContent, expectedHint.hint, + `Content of <title> in ${ hintTarget } should be ${ expectedHint.hint }`); + + let interactionEl = null; + if (expectedHint.path) { + info(`Checking <path> in ${ hintTarget }`); + interactionEl = hintEl.querySelector("path"); + ok(interactionEl, `The <path> element in ${ hintTarget } should be existence`); + assertPathSegments(interactionEl, false, expectedHint.path); + } else { + info(`Checking <rect> in ${ hintTarget }`); + interactionEl = hintEl.querySelector("rect"); + ok(interactionEl, `The <rect> element in ${ hintTarget } should be existence`); + is(interactionEl.getAttribute("x"), expectedHint.rect.x, + `x of <rect> in ${ hintTarget } should be ${ expectedHint.rect.x }`); + is(interactionEl.getAttribute("width"), expectedHint.rect.width, + `width of <rect> in ${ hintTarget } should be ${ expectedHint.rect.width }`); + } + + info(`Checking interaction for ${ hintTarget }`); + interactionEl.scrollIntoView(false); + const win = hintEl.ownerGlobal; + // Mouse out once from pathEl. + EventUtils.synthesizeMouse(interactionEl, -1, -1, { type: "mouseout" }, win); + is(win.getComputedStyle(interactionEl).strokeOpacity, 0, + `stroke-opacity of hintEl for ${ hintTarget } should be 0` + + " while mouse is out from the element"); + // Mouse over the pathEl. + ok(isStrokeChangedByMouseOver(interactionEl, win), + `stroke-opacity of hintEl for ${ hintTarget } should be 1` + + " while mouse is over the element"); + } + } + } +}); + +function isStrokeChangedByMouseOver(pathEl, win) { + const boundingBox = pathEl.getBoundingClientRect(); + const x = boundingBox.width / 2; + + for (let y = 0; y < boundingBox.height; y++) { + EventUtils.synthesizeMouse(pathEl, x, y, { type: "mouseover" }, win); + + if (win.getComputedStyle(pathEl).strokeOpacity == 1) { + return true; + } + } + + return false; +}
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/test/browser_animation_keyframes-graph_keyframe-marker.js @@ -0,0 +1,176 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test for following keyframe marker. +// * element existence +// * title +// * and left style + +const TEST_DATA = [ + { + targetName: "multi-types", + properties: [ + { + name: "background-color", + expectedValues: [ + { + title: "rgb(255, 0, 0)", + left: "0%", + }, + { + title: "rgb(0, 255, 0)", + left: "100%", + } + ], + }, + { + name: "background-repeat", + expectedValues: [ + { + title: "space round", + left: "0%", + }, + { + title: "round space", + left: "100%", + } + ], + }, + { + name: "font-size", + expectedValues: [ + { + title: "10px", + left: "0%", + }, + { + title: "20px", + left: "100%", + } + ], + }, + { + name: "margin-left", + expectedValues: [ + { + title: "0px", + left: "0%", + }, + { + title: "100px", + left: "100%", + } + ], + }, + { + name: "opacity", + expectedValues: [ + { + title: "0", + left: "0%", + }, + { + title: "1", + left: "100%", + } + ], + }, + { + name: "text-align", + expectedValues: [ + { + title: "right", + left: "0%", + }, + { + title: "center", + left: "100%", + } + ], + }, + { + name: "transform", + expectedValues: [ + { + title: "translate(0px)", + left: "0%", + }, + { + title: "translate(100px)", + left: "100%", + } + ], + }, + ], + }, + { + targetName: "narrow-offsets", + properties: [ + { + name: "opacity", + expectedValues: [ + { + title: "0", + left: "0%", + }, + { + title: "1", + left: "10%", + }, + { + title: "0", + left: "13%", + }, + { + title: "1", + left: "100%", + }, + ], + }, + ], + } +]; + +add_task(async function () { + await addTab(URL_ROOT + "doc_multi_keyframes.html"); + + const { inspector, panel } = await openAnimationInspector(); + + for (const { properties, targetName } of TEST_DATA) { + info(`Checking keyframe marker for ${ targetName }`); + await selectNodeAndWaitForAnimations(`#${ targetName }`, inspector); + + for (const property of properties) { + const { + name, + expectedValues, + } = property; + + const testTarget = `${ name } in ${ targetName }`; + info(`Checking keyframe marker for ${ testTarget }`); + info(`Checking keyframe marker existence for ${ testTarget }`); + const markerEls = panel.querySelectorAll(`.${ name } .keyframe-marker-item`); + is(markerEls.length, expectedValues.length, + `Count of keyframe marker elements of ${ testTarget } ` + + `should be ${ expectedValues.length }`); + + for (let i = 0; i < expectedValues.length; i++) { + const hintTarget = `.keyframe-marker-item[${ i }] of ${ testTarget }`; + + info(`Checking ${ hintTarget }`); + const markerEl = markerEls[i]; + const expectedValue = expectedValues[i]; + + info(`Checking title in ${ hintTarget }`); + is(markerEl.getAttribute("title"), expectedValue.title, + `title in ${ hintTarget } should be ${ expectedValue.title }`); + + info(`Checking left style in ${ hintTarget }`); + is(markerEl.style.left, expectedValue.left, + `left in ${ hintTarget } should be ${ expectedValue.left }`); + } + } + } +});
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/test/doc_multi_easings.html @@ -0,0 +1,97 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> + <style> + div { + background-color: lime; + height: 50px; + } + </style> + </head> + <body> + <script> + "use strict"; + + function createAnimation(name, keyframes, effectEasing) { + const div = document.createElement("div"); + div.id = name; + document.body.appendChild(div); + + const effect = { + duration: 100000, + fill: "forwards" + }; + + if (effectEasing) { + effect.easing = effectEasing; + } + + div.animate(keyframes, effect); + } + + createAnimation( + "no-easing", + [ + { opacity: 1 }, + { opacity: 0 }, + ] + ); + + createAnimation( + "effect-easing", + [ + { opacity: 1 }, + { opacity: 0 }, + ], + "frames(5)" + ); + + createAnimation( + "keyframe-easing", + [ + { opacity: 1, easing: "steps(2)", }, + { opacity: 0 }, + ] + ); + + createAnimation( + "both-easing", + [ + { offset: 0, opacity: 1, easing: "steps(2)", }, + { offset: 0, marginLeft: "0px", easing: "steps(1)", }, + { marginLeft: "100px", opacity: 0 }, + ], + "steps(10)" + ); + + createAnimation( + "narrow-keyframes", + [ + { opacity: 0, }, + { offset: 0.1, opacity: 1, easing: "steps(1)", }, + { offset: 0.13, opacity: 0, }, + ] + ); + + createAnimation( + "duplicate-keyframes", + [ + { opacity: 0 }, + { offset: 0.5, opacity: 1, }, + { offset: 0.5, opacity: 0, easing: "steps(1)", }, + { opacity: 1, }, + ] + ); + + createAnimation( + "color-keyframes", + [ + { color: "red", easing: "ease-in", }, + { offset: 0.4, color: "blue", easing: "ease-out", }, + { color: "lime", }, + ] + ); + </script> + </body> +</html>
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/animation/test/doc_multi_keyframes.html @@ -0,0 +1,205 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> + <style> + div { + width: 50px; + height: 50px; + } + </style> + </head> + <body> + <script> + "use strict"; + + function createAnimation(name, keyframes, effectEasing) { + const div = document.createElement("div"); + div.id = name; + document.body.appendChild(div); + + const effect = { + duration: 100000, + fill: "forwards" + }; + + if (effectEasing) { + effect.easing = effectEasing; + } + + div.animate(keyframes, effect); + } + + createAnimation( + "multi-types", + [ + { + backgroundColor: "red", + backgroundRepeat: "space round", + fontSize: "10px", + marginLeft: "0px", + opacity: 0, + textAlign: "right", + transform: "translate(0px)" + }, + { + backgroundColor: "lime", + backgroundRepeat: "round space", + fontSize: "20px", + marginLeft: "100px", + opacity: 1, + textAlign: "center", + transform: "translate(100px)" + }, + ] + ); + + createAnimation( + "multi-types-reverse", + [ + { + backgroundColor: "lime", + backgroundRepeat: "space", + fontSize: "20px", + marginLeft: "100px", + opacity: 1, + textAlign: "center", + transform: "translate(100px)" + }, + { + backgroundColor: "red", + backgroundRepeat: "round", + fontSize: "10px", + marginLeft: "0px", + opacity: 0, + textAlign: "right", + transform: "translate(0px)" + }, + ] + ); + + createAnimation( + "middle-keyframe", + [ + { + backgroundColor: "red", + backgroundRepeat: "space", + fontSize: "10px", + marginLeft: "0px", + opacity: 0, + textAlign: "right", + transform: "translate(0px)" + }, + { + backgroundColor: "blue", + backgroundRepeat: "round", + fontSize: "20px", + marginLeft: "100px", + opacity: 1, + textAlign: "center", + transform: "translate(100px)" + }, + { + backgroundColor: "lime", + backgroundRepeat: "space", + fontSize: "10px", + marginLeft: "0px", + opacity: 0, + textAlign: "right", + transform: "translate(0px)" + }, + ] + ); + + createAnimation( + "steps-keyframe", + [ + { + backgroundColor: "red", + backgroundRepeat: "space", + fontSize: "10px", + marginLeft: "0px", + opacity: 0, + textAlign: "right", + transform: "translate(0px)", + easing: "steps(2)" + }, + { + backgroundColor: "lime", + backgroundRepeat: "round", + fontSize: "20px", + marginLeft: "100px", + opacity: 1, + textAlign: "center", + transform: "translate(100px)" + }, + ] + ); + + createAnimation( + "steps-effect", + [ + { + opacity: 0 + }, + { + opacity: 1 + }, + ], + "steps(2)" + ); + + createAnimation( + "frames-keyframe", + [ + { + easing: "frames(5)", + opacity: 0, + }, + { + opacity: 1 + }, + ] + ); + + createAnimation( + "narrow-offsets", + [ + { + opacity: 0, + }, + { + opacity: 1, + easing: "steps(2)", + offset: 0.1, + }, + { + opacity: 0, + offset: 0.13, + }, + ] + ); + + createAnimation( + "duplicate-offsets", + [ + { + opacity: 1, + }, + { + opacity: 1, + offset: 0.5, + }, + { + opacity: 0, + offset: 0.5, + }, + { + opacity: 1, + offset: 1, + }, + ] + ); + </script> + </body> +</html>
--- a/devtools/client/inspector/animation/test/head.js +++ b/devtools/client/inspector/animation/test/head.js @@ -204,16 +204,34 @@ const waitForAllAnimationTargets = async */ const waitForAllSummaryGraph = async function (animationInspector) { for (let i = 0; i < animationInspector.animations.length; i++) { await animationInspector.once("animation-summary-graph-rendered"); } }; /** + * Check the <stop> element in the given linearGradientEl for the correct offset + * and color attributes. + * + * @param {Element} linearGradientEl + <linearGradient> element which has <stop> element. + * @param {Number} offset + * float which represents the "offset" attribute of <stop>. + * @param {String} expectedColor + * e.g. rgb(0, 0, 255) + */ +function assertLinearGradient(linearGradientEl, offset, expectedColor) { + const stopEl = findStopElement(linearGradientEl, offset); + ok(stopEl, `stop element at offset ${ offset } should exist`); + is(stopEl.getAttribute("stop-color"), expectedColor, + `stop-color of stop element at offset ${ offset } should be ${ expectedColor }`); +} + +/** * SummaryGraph is constructed by <path> element. * This function checks the vertex of path segments. * * @param {Element} pathEl * <path> element. * @param {boolean} hasClosePath * Set true if the path shoud be closing. * @param {Object} expectedValues @@ -289,8 +307,28 @@ function findAnimationItemElementsByTarg if (className === targetClassName) { return animationTargetEl.closest(".animation-item"); } } return null; } + +/** + * Find the <stop> element which has the given offset in the given linearGradientEl. + * + * @param {Element} linearGradientEl + * <linearGradient> element which has <stop> element. + * @param {Number} offset + * Float which represents the "offset" attribute of <stop>. + * @return {Element} + * If can't find suitable element, returns null. + */ +function findStopElement(linearGradientEl, offset) { + for (const stopEl of linearGradientEl.querySelectorAll("stop")) { + if (offset <= parseFloat(stopEl.getAttribute("offset"))) { + return stopEl; + } + } + + return null; +}
--- a/devtools/client/inspector/animation/utils/graph-helper.js +++ b/devtools/client/inspector/animation/utils/graph-helper.js @@ -1,31 +1,35 @@ /* 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"; // BOUND_EXCLUDING_TIME should be less than 1ms and is used to exclude start -// and end bounds when dividing duration in createPathSegments. +// and end bounds when dividing duration in createPathSegments. const BOUND_EXCLUDING_TIME = 0.001; // We define default graph height since if the height of viewport in SVG is // too small (e.g. 1), vector-effect may not be able to calculate correctly. const DEFAULT_GRAPH_HEIGHT = 100; +// Default animation duration for keyframes graph. +const DEFAULT_KEYFRAMES_GRAPH_DURATION = 1000; // DEFAULT_MIN_PROGRESS_THRESHOLD shoud be between more than 0 to 1. const DEFAULT_MIN_PROGRESS_THRESHOLD = 0.1; // In the createPathSegments function, an animation duration is divided by -// DURATION_RESOLUTION in order to draw the way the animation progresses. +// DEFAULT_DURATION_RESOLUTION in order to draw the way the animation progresses. // But depending on the timing-function, we may be not able to make the graph // smoothly progress if this resolution is not high enough. // So, if the difference of animation progress between 2 divisions is more than // DEFAULT_MIN_PROGRESS_THRESHOLD * DEFAULT_GRAPH_HEIGHT, then createPathSegments -// re-divides by DURATION_RESOLUTION. -// DURATION_RESOLUTION shoud be integer and more than 2. -const DURATION_RESOLUTION = 4; +// re-divides by DEFAULT_DURATION_RESOLUTION. +// DEFAULT_DURATION_RESOLUTION shoud be integer and more than 2. +const DEFAULT_DURATION_RESOLUTION = 4; +// Stroke width for easing hint. +const DEFAULT_EASING_HINT_STROKE_WIDTH = 5; /** * The helper class for creating summary graph. */ class SummaryGraphHelper { /** * Constructor. * @@ -117,34 +121,34 @@ function createPathSegments(startTime, e let pathSegments = []; // Append the segment for the startTime position. const startTimeSegment = getSegment(startTime); pathSegments.push(startTimeSegment); let previousSegment = startTimeSegment; // Split the duration in equal intervals, and iterate over them. - // See the definition of DURATION_RESOLUTION for more information about this. + // See the definition of DEFAULT_DURATION_RESOLUTION for more information about this. const interval = (endTime - startTime) / resolution; for (let index = 1; index <= resolution; index++) { // Create a segment for this interval. const currentSegment = getSegment(startTime + index * interval); // If the distance between the Y coordinate (the animation's progress) of // the previous segment and the Y coordinate of the current segment is too // large, then recurse with a smaller duration to get more details // in the graph. if (Math.abs(currentSegment.y - previousSegment.y) > minProgressThreshold) { // Divide the current interval (excluding start and end bounds // by adding/subtracting BOUND_EXCLUDING_TIME). const nextStartTime = previousSegment.x + BOUND_EXCLUDING_TIME; const nextEndTime = currentSegment.x - BOUND_EXCLUDING_TIME; const segments = createPathSegments(nextStartTime, nextEndTime, minSegmentDuration, - minProgressThreshold, DURATION_RESOLUTION, getSegment); + minProgressThreshold, DEFAULT_DURATION_RESOLUTION, getSegment); pathSegments = pathSegments.concat(segments); } pathSegments.push(currentSegment); previousSegment = currentSegment; } return pathSegments; @@ -156,20 +160,20 @@ function createPathSegments(startTime, e * * @param {Array} keyframes * Array of keyframe. * @return {Number} * Preferred duration resolution. */ function getPreferredDurationResolution(keyframes) { if (!keyframes) { - return DURATION_RESOLUTION; + return DEFAULT_DURATION_RESOLUTION; } - let durationResolution = DURATION_RESOLUTION; + let durationResolution = DEFAULT_DURATION_RESOLUTION; let previousOffset = 0; for (let keyframe of keyframes) { if (previousOffset && previousOffset != keyframe.offset) { const interval = keyframe.offset - previousOffset; durationResolution = Math.max(durationResolution, Math.ceil(1 / interval)); } previousOffset = keyframe.offset; } @@ -194,16 +198,33 @@ function getPreferredProgressThreshold(s if ((stepsOrFrames = getStepsOrFramesCount(state.easing))) { threshold = Math.min(threshold, (1 / (stepsOrFrames + 1))); } if (!keyframes) { return threshold; } + threshold = Math.min(threshold, getPreferredProgressThresholdByKeyframes(keyframes)); + + return threshold; +} + +/** + * Return preferred progress threshold by keyframes. + * + * @param {Array} keyframes + * Array of keyframe. + * @return {float} + * Preferred threshold. + */ +function getPreferredProgressThresholdByKeyframes(keyframes) { + let threshold = DEFAULT_MIN_PROGRESS_THRESHOLD; + let stepsOrFrames; + for (let i = 0; i < keyframes.length - 1; i++) { const keyframe = keyframes[i]; if (!keyframe.easing) { continue; } if ((stepsOrFrames = getStepsOrFramesCount(keyframe.easing))) { @@ -234,11 +255,17 @@ function getStepsOrFramesCount(easing) { function toPathString(segments) { let pathString = ""; segments.forEach(segment => { pathString += `L${ segment.x },${ segment.y } `; }); return pathString; } -module.exports.DEFAULT_GRAPH_HEIGHT = DEFAULT_GRAPH_HEIGHT; +exports.createPathSegments = createPathSegments; +exports.DEFAULT_DURATION_RESOLUTION = DEFAULT_DURATION_RESOLUTION; +exports.DEFAULT_EASING_HINT_STROKE_WIDTH = DEFAULT_EASING_HINT_STROKE_WIDTH; +exports.DEFAULT_GRAPH_HEIGHT = DEFAULT_GRAPH_HEIGHT; +exports.DEFAULT_KEYFRAMES_GRAPH_DURATION = DEFAULT_KEYFRAMES_GRAPH_DURATION; +exports.getPreferredProgressThresholdByKeyframes = + getPreferredProgressThresholdByKeyframes; exports.SummaryGraphHelper = SummaryGraphHelper; exports.toPathString = toPathString;
--- a/devtools/client/netmonitor/src/components/RequestListColumnResponseHeader.js +++ b/devtools/client/netmonitor/src/components/RequestListColumnResponseHeader.js @@ -2,32 +2,46 @@ * 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 { Component } = require("devtools/client/shared/vendor/react"); const dom = require("devtools/client/shared/vendor/react-dom-factories"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); -const { getResponseHeader } = require("../utils/request-utils"); +const { + getResponseHeader, + fetchNetworkUpdatePacket +} = require("../utils/request-utils"); const { div } = dom; /** * Renders a response header column in the requests list. The actual * header to show is passed as a prop. */ class RequestListColumnResponseHeader extends Component { static get propTypes() { return { + connector: PropTypes.object.isRequired, item: PropTypes.object.isRequired, header: PropTypes.string.isRequired, }; } + componentDidMount() { + let { item, connector } = this.props; + fetchNetworkUpdatePacket(connector.requestData, item, ["responseHeaders"]); + } + + componentWillReceiveProps(nextProps) { + let { item, connector } = nextProps; + fetchNetworkUpdatePacket(connector.requestData, item, ["responseHeaders"]); + } + shouldComponentUpdate(nextProps) { const currHeader = getResponseHeader(this.props.item, this.props.header); const nextHeader = getResponseHeader(nextProps.item, nextProps.header); return currHeader !== nextHeader; } render() { let header = getResponseHeader(this.props.item, this.props.header);
--- a/devtools/client/netmonitor/src/components/RequestListContent.js +++ b/devtools/client/netmonitor/src/components/RequestListContent.js @@ -90,40 +90,33 @@ class RequestListContent extends Compone } componentDidMount() { // Install event handler for displaying a tooltip this.tooltip.startTogglingOnHover(this.refs.contentEl, this.onHover, { toggleDelay: REQUESTS_TOOLTIP_TOGGLE_DELAY, interactive: true }); - // Everytime the list is created or pruned, re-enable scroll to bottom feature. - this.shouldScrollToBottom = true; - // Install event handler to hide the tooltip on scroll this.refs.contentEl.addEventListener("scroll", this.onScroll, true); this.onResize(); } - componentDidUpdate(prevProps) { - if (!this.shouldScrollToBottom) { - return; - } + componentWillUpdate(nextProps) { // Check if the list is scrolled to bottom before the UI update. // The scroll is ever needed only if new rows are added to the list. - const hasNewRequests = this.props.displayedRequests.size - - prevProps.displayedRequests.size > 0; + const delta = nextProps.displayedRequests.size - this.props.displayedRequests.size; + this.shouldScrollBottom = delta > 0 && this.isScrolledToBottom(); + } + + componentDidUpdate(prevProps) { + let node = this.refs.contentEl; // Keep the list scrolled to bottom if a new row was added - if (hasNewRequests) { - // Set a boolean flag to help `scroll` listener to know that the next event - // is related to the scroll to bottom and can be ignored. - this.ignoreNextScroll = true; - + if (this.shouldScrollBottom && node.scrollTop !== MAX_SCROLL_HEIGHT) { // Using maximum scroll height rather than node.scrollHeight to avoid sync reflow. - let node = this.refs.contentEl; node.scrollTop = MAX_SCROLL_HEIGHT; } } componentWillUnmount() { this.refs.contentEl.removeEventListener("scroll", this.onScroll, true); // Uninstall the tooltip event handler @@ -195,24 +188,16 @@ class RequestListContent extends Compone return itemEl.querySelector(".requests-list-file"); } /** * Scroll listener for the requests menu view. */ onScroll() { this.tooltip.hide(); - - // Ignore scroll related to new requests being displayed - // To prevent slow reflows done in isScrolledToBottom. - if (this.ignoreNextScroll) { - this.ignoreNextScroll = false; - return; - } - this.shouldScrollToBottom = this.isScrolledToBottom(); } /** * Handler for keyboard events. For arrow up/down, page up/down, home/end, * move the selection up or down. */ onKeyDown(evt) { let delta; @@ -254,17 +239,17 @@ class RequestListContent extends Compone this.contextMenu.open(evt, selectedRequest, sortedRequests); } /** * If selection has just changed (by keyboard navigation), don't keep the list * scrolled to bottom, but allow scrolling up with the selection. */ onFocusedNodeChange() { - this.shouldScrollToBottom = false; + this.shouldScrollBottom = false; } render() { const { connector, columns, displayedRequests, firstRequestStartedMillis, @@ -280,19 +265,17 @@ class RequestListContent extends Compone return ( div({ className: "requests-list-wrapper" }, div({ className: "requests-list-table" }, div({ ref: "contentEl", className: "requests-list-contents", tabIndex: 0, onKeyDown: this.onKeyDown, - // scale is null until the waterfall is initialized - style: { "--timings-scale": scale ? scale : 0, - "--timings-rev-scale": (scale ? 1 / scale : 1) } + style: { "--timings-scale": scale, "--timings-rev-scale": 1 / scale } }, RequestListHeader(), displayedRequests.map((item, index) => RequestListItem({ firstRequestStartedMillis, fromCache: item.status === "304" || item.fromCache, connector, columns, item,
--- a/devtools/client/netmonitor/src/components/RequestListItem.js +++ b/devtools/client/netmonitor/src/components/RequestListItem.js @@ -258,17 +258,21 @@ class RequestListItem extends Component }), columns.latency && RequestListColumnTime({ connector, item, firstRequestStartedMillis, type: "latency", }), ...RESPONSE_HEADERS.filter(header => columns[header]).map( - header => RequestListColumnResponseHeader({ item, header }), + header => RequestListColumnResponseHeader({ + connector, + item, + header + }), ), columns.waterfall && RequestListColumnWaterfall({ connector, firstRequestStartedMillis, item, onWaterfallMouseDown, }), )
--- a/devtools/client/netmonitor/test/browser_net_autoscroll.js +++ b/devtools/client/netmonitor/test/browser_net_autoscroll.js @@ -36,21 +36,16 @@ add_task(function* () { // save for comparison later let scrollTop = requestsContainer.scrollTop; yield waitForNetworkEvents(monitor, 8); yield waitSomeTime(); is(requestsContainer.scrollTop, scrollTop, "Did not scroll."); // (3) Now set the scroll position back at the bottom and check that // additional requests *do* cause the container to scroll down. - // Wait for another request to be displayed in order to ensure that - // scrollTop is set just before next RequestListContent.componentWillUpdate fires. - // If scrollTop is set between componentWillUpdate and componentDidUpdate, - // the view won't be scrolled. - yield waitForNetworkEvents(monitor, 8); requestsContainer.scrollTop = requestsContainer.scrollHeight; ok(scrolledToBottom(requestsContainer), "Set scroll position to bottom."); yield waitForNetworkEvents(monitor, 8); yield waitForScroll(); ok(true, "Still scrolled to bottom."); // (4) Now select the first item in the list // and check that additional requests do not change the scroll position
--- a/devtools/client/netmonitor/test/browser_net_columns_showhide.js +++ b/devtools/client/netmonitor/test/browser_net_columns_showhide.js @@ -1,27 +1,37 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; /** * Test showing/hiding columns. */ - add_task(async function () { let { monitor, tab } = await initNetMonitor(SIMPLE_URL); info("Starting test... "); - let { document, store, parent } = monitor.panelWin; + let { document, store, parent, connector, windowRequire } = monitor.panelWin; + let { requestData } = connector; + let { + getSortedRequests, + } = windowRequire("devtools/client/netmonitor/src/selectors/index"); let wait = waitForNetworkEvents(monitor, 1); tab.linkedBrowser.loadURI(SIMPLE_URL); await wait; + let item = getSortedRequests(store.getState()).get(0); + ok(item.responseHeadersAvailable, "headers are available for lazily fetching"); + + if (item.responseHeadersAvailable && !item.responseHeaders) { + await requestData(item.id, "responseHeaders"); + } + let requestsContainer = document.querySelector(".requests-list-contents"); ok(requestsContainer, "Container element exists as expected."); let headers = document.querySelector(".requests-list-headers"); let columns = store.getState().ui.columns; for (let column in columns) { if (columns[column]) { await testVisibleColumnContextMenuItem(column, document, parent); @@ -48,66 +58,73 @@ add_task(async function () { async function testWhiteSpaceContextMenuItem(column, document, parent) { ok(!document.querySelector(`#requests-list-${column}-button`), `Column ${column} should be hidden`); info(`Right clicking on white-space in the header to get the context menu`); EventUtils.sendMouseEvent({ type: "contextmenu" }, document.querySelector(".devtools-toolbar.requests-list-headers")); + // Wait for next tick to do stuff async and force repaint. + await waitForTick(); await toggleAndCheckColumnVisibility(column, document, parent); } async function testVisibleColumnContextMenuItem(column, document, parent) { ok(document.querySelector(`#requests-list-${column}-button`), `Column ${column} should be visible`); info(`Clicking context-menu item for ${column}`); EventUtils.sendMouseEvent({ type: "contextmenu" }, document.querySelector("#requests-list-status-button") || document.querySelector("#requests-list-waterfall-button")); + await waitForTick(); + let menuItem = parent.document.querySelector(`#request-list-header-${column}-toggle`); is(menuItem.getAttribute("type"), "checkbox", `${column} menu item should have type="checkbox" attribute`); is(menuItem.getAttribute("checked"), "true", `checked state of ${column} menu item should be correct`); ok(!menuItem.disabled, `disabled state of ${column} menu item should be correct`); let onHeaderRemoved = waitForDOM(document, `#requests-list-${column}-button`, 0); menuItem.click(); await onHeaderRemoved; + await waitForTick(); ok(!document.querySelector(`#requests-list-${column}-button`), `Column ${column} should be hidden`); } async function testHiddenColumnContextMenuItem(column, document, parent) { ok(!document.querySelector(`#requests-list-${column}-button`), `Column ${column} should be hidden`); info(`Clicking context-menu item for ${column}`); EventUtils.sendMouseEvent({ type: "contextmenu" }, document.querySelector("#requests-list-status-button") || document.querySelector("#requests-list-waterfall-button")); + await waitForTick(); await toggleAndCheckColumnVisibility(column, document, parent); } async function toggleAndCheckColumnVisibility(column, document, parent) { let menuItem = parent.document.querySelector(`#request-list-header-${column}-toggle`); is(menuItem.getAttribute("type"), "checkbox", `${column} menu item should have type="checkbox" attribute`); ok(!menuItem.getAttribute("checked"), `checked state of ${column} menu item should be correct`); ok(!menuItem.disabled, `disabled state of ${column} menu item should be correct`); let onHeaderAdded = waitForDOM(document, `#requests-list-${column}-button`, 1); menuItem.click(); await onHeaderAdded; + await waitForTick(); ok(document.querySelector(`#requests-list-${column}-button`), `Column ${column} should be visible`); }
--- a/devtools/client/themes/animation.css +++ b/devtools/client/themes/animation.css @@ -2,23 +2,32 @@ * 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/. */ /* Animation-inspector specific theme variables */ :root { --animation-even-background-color: rgba(0, 0, 0, 0.05); --command-pick-image: url(chrome://devtools/skin/images/command-pick.svg); + --fast-track-image: url("images/animation-fast-track.svg"); + --fill-color-cssanimation: var(--theme-contrast-background); + --fill-color-csstransition: var(--theme-highlight-blue); + --fill-color-scriptanimation: var(--theme-graphs-green); --graph-right-offset: 10px; + --keyframe-marker-shadow-color: #c4c4c4; --sidebar-width: 200px; + --stroke-color-cssanimation: var(--theme-highlight-lightorange); + --stroke-color-csstransition: var(--theme-highlight-bluegrey); + --stroke-color-scriptanimation: var(--theme-highlight-green); --tick-line-style: 0.5px solid rgba(128, 136, 144, 0.5); } :root.theme-dark { --animation-even-background-color: rgba(255, 255, 255, 0.05); + --keyframe-marker-shadow-color: #818181; } :root.theme-firebug { --command-pick-image: url(chrome://devtools/skin/images/firebug/command-pick.svg); } /* Root element of animation inspector */ #animation-container { @@ -77,28 +86,28 @@ height: 30px; } .animation-item:nth-child(2n+1) { background-color: var(--animation-even-background-color); } .animation-item.cssanimation { - --computed-timing-graph-color: var(--theme-contrast-background); - --effect-timing-graph-color: var(--theme-highlight-lightorange); + --computed-timing-graph-color: var(--fill-color-cssanimation); + --effect-timing-graph-color: var(--stroke-color-cssanimation); } .animation-item.csstransition { - --computed-timing-graph-color: var(--theme-highlight-blue); - --effect-timing-graph-color: var(--theme-highlight-bluegrey); + --computed-timing-graph-color: var(--fill-color-csstransition); + --effect-timing-graph-color: var(--stroke-color-csstransition); } .animation-item.scriptanimation { - --computed-timing-graph-color: var(--theme-graphs-green); - --effect-timing-graph-color: var(--theme-highlight-green); + --computed-timing-graph-color: var(--fill-color-scriptanimation); + --effect-timing-graph-color: var(--stroke-color-scriptanimation); } .animation-item.selected { background-color: var(--theme-selection-background-hover); } /* Animation Target */ .animation-target { @@ -117,17 +126,17 @@ .animation-summary-graph { height: 100%; padding-top: 5px; position: relative; width: calc(100% - var(--sidebar-width) - var(--graph-right-offset)); } .animation-summary-graph.compositor::after { - background-image: url("images/animation-fast-track.svg"); + background-image: var(--fast-track-image); background-repeat: no-repeat; content: ""; display: block; fill: var(--theme-content-color3); height: 100%; position: absolute; right: 0; top: 5px; @@ -286,30 +295,163 @@ .keyframes-progress-tick-item.right { border-right: var(--tick-line-style); } /* Animated Property List */ .animated-property-list { flex: 1; list-style-type: none; - margin-top: 0; + margin: 0; overflow-y: auto; padding: 0; } /* Animated Property Item */ .animated-property-item { + display: flex; height: 30px; } .animated-property-item:nth-child(2n+1) { background-color: var(--animation-even-background-color); } +/* Animated Property Name */ +.animated-property-name { + align-items: center; + display: flex; + height: 100%; + justify-content: flex-end; + padding-right: 10px; + width: var(--sidebar-width); +} + +.animated-property-name.compositor span { + padding-left: 15px; + position: relative; +} + +.animated-property-list-container.cssanimation .animated-property-name.compositor { + --fast-track-color: var(--stroke-color-cssanimation); +} + +.animated-property-list-container.csstransition .animated-property-name.compositor { + --fast-track-color: var(--stroke-color-csstransition); +} + +.animated-property-list-container.scriptanimation .animated-property-name.compositor { + --fast-track-color: var(--stroke-color-scriptanimation); +} + +.animated-property-name.compositor span::before { + background-image: var(--fast-track-image); + background-repeat: no-repeat; + background-size: contain; + content: ""; + fill: var(--fast-track-color); + height: 100%; + position: absolute; + left: 0; + width: 15px; + -moz-context-properties: fill; +} + +.animated-property-name.warning span { + text-decoration: underline dotted; +} + +/* Keyframes Graph */ +.keyframes-graph { + height: 100%; + padding-top: 3px; + position: relative; + width: calc(100% - var(--sidebar-width) - var(--graph-right-offset)); +} + +.keyframes-graph-path { + height: 100%; + width: 100%; +} + +.keyframes-graph-path path { + fill: #00b0bd88; + stroke: #00b0bd; + vector-effect: non-scaling-stroke; + transform: scale(1, -1); +} + +.keyframes-graph.opacity .keyframes-graph-path path { + fill: #df00a988; + stroke: #df00a9; +} + +.keyframes-graph.transform .keyframes-graph-path path { + fill: #ea800088; + stroke: #ea8000; +} + +.keyframes-graph-path .color-path path { + stroke: none; +} + +.keyframes-graph .keyframes-graph-path .hint path { + fill: none; + stroke-linecap: round; + stroke-opacity: 0; +} + +.keyframes-graph-path .hint path:hover { + stroke-opacity: 1; +} + +.keyframes-graph-path .hint rect { + fill-opacity: 0.1; + stroke: #00b0bd; + stroke-opacity: 0; + vector-effect: non-scaling-stroke; +} + +.keyframes-graph-path .hint rect:hover { + stroke-opacity: 1; +} + +/* Keyframe Marker List */ +.keyframe-marker-list { + pointer-events: none; + position: absolute; + height: 100%; + list-style-type: none; + top: 0%; + width: 100%; +} + +.keyframe-marker-item { + box-shadow: 0 0 0 1px var(--keyframe-marker-shadow-color); + border-radius: 100%; + pointer-events: auto; + position: absolute; + top: 50%; + height: 10px; + transform: translate(-5px, -3px); + width: 10px; +} + +.animated-property-list-container.cssanimation .keyframe-marker-item { + background-color: var(--fill-color-cssanimation); +} + +.animated-property-list-container.csstransition .keyframe-marker-item { + background-color: var(--fill-color-csstransition); +} + +.animated-property-list-container.scriptanimation .keyframe-marker-item { + background-color: var(--fill-color-scriptanimation); +} + /* No Animation Panel */ .animation-error-message { overflow: auto; } .animation-error-message > p { white-space: pre; }
--- a/devtools/client/webconsole/new-console-output/components/message-types/PageError.js +++ b/devtools/client/webconsole/new-console-output/components/message-types/PageError.js @@ -24,27 +24,27 @@ PageError.defaultProps = { open: false, }; function PageError(props) { const { dispatch, message, open, + repeat, serviceContainer, timestampsVisible, } = props; const { id: messageId, indent, source, type, level, messageText, - repeat, stacktrace, frame, exceptionDocURL, timeStamp, notes, } = message; let messageBody;
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini @@ -6,17 +6,16 @@ support-files = code_bundle_invalidmap.js.map code_bundle_nosource.js code_bundle_nosource.js.map head.js sjs_slow-response-test-server.sjs source-mapped.css source-mapped.css.map source-mapped.scss - test_bug_1247459_violation.html test_bug_770099_violation.html test_bug_770099_violation.html^headers^ test_console_csp_ignore_reflected_xss_message.html test_console_csp_ignore_reflected_xss_message.html^headers^ test_hpkp-invalid-headers.sjs test_hsts-invalid-headers.sjs test-autocomplete-in-stackframe.html test-batching.html @@ -39,16 +38,17 @@ support-files = test-bug-782653-css-errors-2.css test-bug-782653-css-errors.html test-bug-837351-security-errors.html test-bug-859170-longstring-hang.html test-bug-952277-highlight-nodes-in-vview.html test-cd-iframe-child.html test-cd-iframe-parent.html test-console-api-iframe.html + test-csp-violation.html test-cspro.html test-cspro.html^headers^ test-iframe-child.html test-iframe-parent.html test-certificate-messages.html test-click-function-to-source.html test-click-function-to-source.js test-closure-optimized-out.html @@ -260,16 +260,17 @@ subsuite = clipboard skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts [browser_webconsole_context_menu_copy_object.js] subsuite = clipboard [browser_webconsole_context_menu_object_in_sidebar.js] [browser_webconsole_context_menu_open_url.js] [browser_webconsole_context_menu_store_as_global.js] [browser_webconsole_csp_ignore_reflected_xss_message.js] skip-if = (e10s && debug) || (e10s && os == 'win') # Bug 1221499 enabled these on windows +[browser_webconsole_csp_violation.js] [browser_webconsole_cspro.js] [browser_webconsole_document_focus.js] [browser_webconsole_duplicate_errors.js] [browser_webconsole_errors_after_page_reload.js] [browser_webconsole_eval_in_debugger_stackframe.js] [browser_webconsole_eval_in_debugger_stackframe2.js] [browser_webconsole_execution_scope.js] [browser_webconsole_external_script_errors.js] @@ -339,29 +340,23 @@ subsuite = clipboard [browser_webconsole_show_subresource_security_errors.js] [browser_webconsole_shows_reqs_in_netmonitor.js] [browser_webconsole_sourcemap_css.js] [browser_webconsole_sourcemap_error.js] [browser_webconsole_sourcemap_invalid.js] [browser_webconsole_sourcemap_nosource.js] [browser_webconsole_split.js] [browser_webconsole_split_escape_key.js] -skip-if = true # Bug 1405647 [browser_webconsole_split_focus.js] -skip-if = true # Bug 1405648 [browser_webconsole_split_persist.js] -skip-if = true # Bug 1405649 [browser_webconsole_stacktrace_location_debugger_link.js] [browser_webconsole_stacktrace_location_scratchpad_link.js] [browser_webconsole_strict_mode_errors.js] [browser_webconsole_string.js] [browser_webconsole_time_methods.js] skip-if = true # Bug 1404877 [browser_webconsole_timestamps.js] [browser_webconsole_trackingprotection_errors.js] tags = trackingprotection [browser_webconsole_view_source.js] -[browser_webconsole_violation.js] -skip-if = true # Bug 1405245 -# old console skip-if = e10s && (os == 'win') # Bug 1264955 [browser_webconsole_visibility_messages.js] [browser_webconsole_warn_about_replaced_api.js] [browser_webconsole_websocket.js]
rename from devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_violation.js rename to devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_csp_violation.js --- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_violation.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_csp_violation.js @@ -4,37 +4,24 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests that the Web Console CSP messages for two META policies // are correctly displayed. See Bug 1247459. "use strict"; const TEST_URI = "data:text/html;charset=utf8,Web Console CSP violation test"; -const TEST_VIOLATION = "https://example.com/browser/devtools/client/" + - "webconsole/test/test_bug_1247459_violation.html"; +const TEST_VIOLATION = "https://example.com/browser/devtools/client/webconsole/" + + "new-console-output/test/mochitest/test-csp-violation.html"; const CSP_VIOLATION_MSG = "Content Security Policy: The page\u2019s settings " + "blocked the loading of a resource at " + - "http://some.example.com/test.png (\u201cimg-src " + - "https://example.com\u201d)."; + "http://some.example.com/test.png (\u201cimg-src\u201d)."; -add_task(function* () { - let { browser } = yield loadTab(TEST_URI); - - let hud = yield openConsole(); - +add_task(async function () { + let hud = await openNewTabAndConsole(TEST_URI); hud.jsterm.clearOutput(); - let loaded = loadBrowser(browser); - BrowserTestUtils.loadURI(browser, TEST_VIOLATION); - yield loaded; + let onRepeatedMessage = waitForRepeatedMessage(hud, CSP_VIOLATION_MSG, 2); + await loadDocument(TEST_VIOLATION); + await onRepeatedMessage; - yield waitForMessages({ - webconsole: hud, - messages: [ - { - name: "CSP policy URI warning displayed successfully", - text: CSP_VIOLATION_MSG, - repeats: 2 - } - ] - }); + ok(true, "Received expected messages"); });
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split_escape_key.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split_escape_key.js @@ -1,158 +1,49 @@ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ - "use strict"; - - function test() { - info("Test various cases where the escape key should hide the split console."); +"use strict"; - let toolbox; - let hud; - let jsterm; - let hudMessages; - let variablesView; - - Task.spawn(runner).then(finish); +const TEST_URI = "data:text/html;charset=utf-8,<p>Web Console test for splitting"; - function* runner() { - let {tab} = yield loadTab("data:text/html;charset=utf-8,<p>Web Console " + - "test for splitting"); - let target = TargetFactory.forTab(tab); - toolbox = yield gDevTools.showToolbox(target, "inspector"); - - yield testCreateSplitConsoleAfterEscape(); - - yield showAutoCompletePopoup(); +add_task(async function () { + info("Test various cases where the escape key should hide the split console."); - yield testHideAutoCompletePopupAfterEscape(); - - yield executeJS(); - yield clickMessageAndShowVariablesView(); - jsterm.focus(); - - yield testHideVariablesViewAfterEscape(); - - yield clickMessageAndShowVariablesView(); - yield startPropertyEditor(); + let toolbox = await openNewTabAndToolbox(TEST_URI, "inspector"); - yield testCancelPropertyEditorAfterEscape(); - yield testHideVariablesViewAfterEscape(); - yield testHideSplitConsoleAfterEscape(); - } - - function testCreateSplitConsoleAfterEscape() { - let result = toolbox.once("webconsole-ready", () => { - hud = toolbox.getPanel("webconsole").hud; - jsterm = hud.jsterm; - ok(toolbox.splitConsole, "Split console is created."); - }); - - let contentWindow = toolbox.win; - contentWindow.focus(); - EventUtils.sendKey("ESCAPE", contentWindow); - - return result; - } + info("Send ESCAPE key and wait for the split console to be displayed"); - function testHideSplitConsoleAfterEscape() { - let result = toolbox.once("split-console", () => { - ok(!toolbox.splitConsole, "Split console is hidden."); - }); - EventUtils.sendKey("ESCAPE", toolbox.win); - - return result; - } + let onSplitConsoleReady = toolbox.once("webconsole-ready"); + toolbox.win.focus(); + EventUtils.sendKey("ESCAPE", toolbox.win); + await onSplitConsoleReady; - function testHideVariablesViewAfterEscape() { - let result = jsterm.once("sidebar-closed", () => { - ok(!hud.ui.jsterm.sidebar, - "Variables view is hidden."); - ok(toolbox.splitConsole, - "Split console is open after hiding the variables view."); - }); - EventUtils.sendKey("ESCAPE", toolbox.win); - - return result; - } + let hud = toolbox.getPanel("webconsole").hud; + let jsterm = hud.jsterm; + ok(toolbox.splitConsole, "Split console is created."); - function testHideAutoCompletePopupAfterEscape() { - let deferred = defer(); - let popup = jsterm.autocompletePopup; - - popup.once("popup-closed", () => { - ok(!popup.isOpen, - "Auto complete popup is hidden."); - ok(toolbox.splitConsole, - "Split console is open after hiding the autocomplete popup."); - - deferred.resolve(); - }); - - EventUtils.sendKey("ESCAPE", toolbox.win); - - return deferred.promise; - } + info("Wait for the autocomplete to show suggestions for `document.location.`"); + let popup = jsterm.autocompletePopup; + let onPopupShown = popup.once("popup-opened"); + jsterm.focus(); + jsterm.setInputValue("document.location."); + EventUtils.sendKey("TAB", hud.iframeWindow); + await onPopupShown; - function testCancelPropertyEditorAfterEscape() { - EventUtils.sendKey("ESCAPE", variablesView.window); - ok(hud.ui.jsterm.sidebar, - "Variables view is open after canceling property editor."); - ok(toolbox.splitConsole, - "Split console is open after editing."); - } - - function* executeJS() { - jsterm.execute("var foo = { bar: \"baz\" }; foo;"); - hudMessages = yield waitForMessages({ - webconsole: hud, - messages: [{ - text: "Object { bar: \"baz\" }", - category: CATEGORY_OUTPUT, - objects: true - }], - }); - } + info("Send ESCAPE key and check that it only hides the autocomplete suggestions"); - function clickMessageAndShowVariablesView() { - let result = jsterm.once("variablesview-fetched", (event, vview) => { - variablesView = vview; - }); - - let clickable = hudMessages[0].clickableElements[0]; - EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow); + let onPopupClosed = popup.once("popup-closed"); + EventUtils.sendKey("ESCAPE", toolbox.win); + await onPopupClosed; - return result; - } - - function* startPropertyEditor() { - let results = yield findVariableViewProperties(variablesView, [ - {name: "bar", value: "baz"} - ], {webconsole: hud}); - results[0].matchedProp.focus(); - EventUtils.synthesizeKey("VK_RETURN", variablesView.window); - } + ok(!popup.isOpen, "Auto complete popup is hidden."); + ok(toolbox.splitConsole, "Split console is open after hiding the autocomplete popup."); - function showAutoCompletePopoup() { - let onPopupShown = jsterm.autocompletePopup.once("popup-opened"); - - jsterm.focus(); - jsterm.setInputValue("document.location."); - EventUtils.sendKey("TAB", hud.iframeWindow); - - return onPopupShown; - } + info("Send ESCAPE key again and check that now closes the splitconsole"); + let onSplitConsoleEvent = toolbox.once("split-console"); + EventUtils.sendKey("ESCAPE", toolbox.win); + await onSplitConsoleEvent; - function finish() { - toolbox.destroy().then(() => { - toolbox = null; - hud = null; - jsterm = null; - hudMessages = null; - variablesView = null; - - finishTest(); - }); - } - } + ok(!toolbox.splitConsole, "Split console is hidden."); +});
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split_focus.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split_focus.js @@ -1,64 +1,44 @@ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ - "use strict"; - - function test() { - info("Test that the split console state is persisted"); +"use strict"; - let toolbox; - let TEST_URI = "data:text/html;charset=utf-8,<p>Web Console test for " + - "splitting</p>"; +const TEST_URI = "data:text/html;charset=utf-8,<p>Web Console test for splitting</p>"; - Task.spawn(runner).then(finish); +add_task(async function () { + info("Test that the split console input is focused and restores the focus properly."); - function* runner() { - info("Opening a tab while there is no user setting on split console pref"); - let {tab} = yield loadTab(TEST_URI); - let target = TargetFactory.forTab(tab); - toolbox = yield gDevTools.showToolbox(target, "inspector"); - - ok(!toolbox.splitConsole, "Split console is hidden by default"); + let toolbox = await openNewTabAndToolbox(TEST_URI, "inspector"); + ok(!toolbox.splitConsole, "Split console is hidden by default"); - info("Focusing the search box before opening the split console"); - let inspector = toolbox.getPanel("inspector"); - inspector.searchBox.focus(); + info("Focusing the search box before opening the split console"); + let inspector = toolbox.getPanel("inspector"); + inspector.searchBox.focus(); - let activeElement = getActiveElement(inspector.panelDoc); - is(activeElement, inspector.searchBox, "Search box is focused"); + let activeElement = getActiveElement(inspector.panelDoc); + is(activeElement, inspector.searchBox, "Search box is focused"); - yield toolbox.openSplitConsole(); - - ok(toolbox.splitConsole, "Split console is now visible"); + await toolbox.openSplitConsole(); - // Use the binding element since jsterm.inputNode is a XUL textarea element. - activeElement = getActiveElement(toolbox.doc); - activeElement = activeElement.ownerDocument.getBindingParent(activeElement); - let inputNode = toolbox.getPanel("webconsole").hud.jsterm.inputNode; - is(activeElement, inputNode, "Split console input is focused by default"); + ok(toolbox.splitConsole, "Split console is now visible"); + + activeElement = getActiveElement(toolbox.doc); + let inputNode = toolbox.getPanel("webconsole").hud.jsterm.inputNode; + is(activeElement, inputNode, "Split console input is focused by default"); + + await toolbox.closeSplitConsole(); - yield toolbox.closeSplitConsole(); + info("Making sure that the search box is refocused after closing the split console"); + activeElement = getActiveElement(inspector.panelDoc); + is(activeElement, inspector.searchBox, "Search box is focused"); +}); - info("Making sure that the search box is refocused after closing the " + - "split console"); - activeElement = getActiveElement(inspector.panelDoc); - is(activeElement, inspector.searchBox, "Search box is focused"); - - yield toolbox.destroy(); +function getActiveElement(doc) { + let activeElement = doc.activeElement; + while (activeElement && activeElement.contentDocument) { + activeElement = activeElement.contentDocument.activeElement; } - - function getActiveElement(doc) { - let activeElement = doc.activeElement; - while (activeElement && activeElement.contentDocument) { - activeElement = activeElement.contentDocument.activeElement; - } - return activeElement; - } - - function finish() { - toolbox = TEST_URI = null; - finishTest(); - } + return activeElement; }
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split_persist.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_split_persist.js @@ -1,117 +1,94 @@ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ - "use strict"; - - function test() { - info("Test that the split console state is persisted"); +"use strict"; - let toolbox; - let TEST_URI = "data:text/html;charset=utf-8,<p>Web Console test for " + - "splitting</p>"; +// Test that the split console state is persisted. - Task.spawn(runner).then(finish); +const TEST_URI = "data:text/html;charset=utf-8,<p>Web Console test for splitting</p>"; - function* runner() { - info("Opening a tab while there is no user setting on split console pref"); - let {tab} = yield loadTab(TEST_URI); - let target = TargetFactory.forTab(tab); - toolbox = yield gDevTools.showToolbox(target, "inspector"); +add_task(async function () { + info("Opening a tab while there is no user setting on split console pref"); + let toolbox = await openNewTabAndToolbox(TEST_URI, "inspector"); + ok(!toolbox.splitConsole, "Split console is hidden by default"); + ok(!isCommandButtonChecked(toolbox), "Split console button is unchecked by default."); - ok(!toolbox.splitConsole, "Split console is hidden by default."); - ok(!isCommandButtonChecked(), "Split console button is unchecked by " + - "default."); - yield toggleSplitConsoleWithEscape(); - ok(toolbox.splitConsole, "Split console is now visible."); - ok(isCommandButtonChecked(), "Split console button is now checked."); - ok(getVisiblePrefValue(), "Visibility pref is true"); + await toggleSplitConsoleWithEscape(toolbox); + ok(toolbox.splitConsole, "Split console is now visible."); + ok(isCommandButtonChecked(toolbox), "Split console button is now checked."); + ok(getVisiblePrefValue(), "Visibility pref is true"); + + is(getHeightPrefValue(), toolbox.webconsolePanel.height, + "Panel height matches the pref"); + toolbox.webconsolePanel.height = 200; - is(getHeightPrefValue(), toolbox.webconsolePanel.height, - "Panel height matches the pref"); - toolbox.webconsolePanel.height = 200; - - yield toolbox.destroy(); + await toolbox.destroy(); - info("Opening a tab while there is a true user setting on split console " + - "pref"); - ({tab} = yield loadTab(TEST_URI)); - target = TargetFactory.forTab(tab); - toolbox = yield gDevTools.showToolbox(target, "inspector"); + info("Opening a tab while there is a true user setting on split console pref"); + toolbox = await openNewTabAndToolbox(TEST_URI, "inspector"); + ok(toolbox.splitConsole, "Split console is visible by default."); + + ok(isCommandButtonChecked(toolbox), "Split console button is checked by default."); + is(getHeightPrefValue(), 200, "Height is set based on panel height after closing"); - ok(toolbox.splitConsole, "Split console is visible by default."); - ok(isCommandButtonChecked(), "Split console button is checked by default."); - is(getHeightPrefValue(), 200, "Height is set based on panel height after " + - "closing"); + let activeElement = getActiveElement(toolbox.doc); + let inputNode = toolbox.getPanel("webconsole").hud.jsterm.inputNode; + is(activeElement, inputNode, "Split console input is focused by default"); - // Use the binding element since jsterm.inputNode is a XUL textarea element. - let activeElement = getActiveElement(toolbox.doc); - activeElement = activeElement.ownerDocument.getBindingParent(activeElement); - let inputNode = toolbox.getPanel("webconsole").hud.jsterm.inputNode; - is(activeElement, inputNode, "Split console input is focused by default"); + toolbox.webconsolePanel.height = 1; + ok(toolbox.webconsolePanel.clientHeight > 1, + "The actual height of the console is bound with a min height"); - toolbox.webconsolePanel.height = 1; - ok(toolbox.webconsolePanel.clientHeight > 1, - "The actual height of the console is bound with a min height"); - - toolbox.webconsolePanel.height = 10000; - ok(toolbox.webconsolePanel.clientHeight < 10000, - "The actual height of the console is bound with a max height"); + toolbox.webconsolePanel.height = 10000; + ok(toolbox.webconsolePanel.clientHeight < 10000, + "The actual height of the console is bound with a max height"); - yield toggleSplitConsoleWithEscape(); - ok(!toolbox.splitConsole, "Split console is now hidden."); - ok(!isCommandButtonChecked(), "Split console button is now unchecked."); - ok(!getVisiblePrefValue(), "Visibility pref is false"); + await toggleSplitConsoleWithEscape(toolbox); + ok(!toolbox.splitConsole, "Split console is now hidden."); + ok(!isCommandButtonChecked(toolbox), "Split console button is now unchecked."); + ok(!getVisiblePrefValue(), "Visibility pref is false"); - yield toolbox.destroy(); + await toolbox.destroy(); - is(getHeightPrefValue(), 10000, - "Height is set based on panel height after closing"); + is(getHeightPrefValue(), 10000, "Height is set based on panel height after closing"); - info("Opening a tab while there is a false user setting on split " + - "console pref"); - ({tab} = yield loadTab(TEST_URI)); - target = TargetFactory.forTab(tab); - toolbox = yield gDevTools.showToolbox(target, "inspector"); + info("Opening a tab while there is a false user setting on split " + + "console pref"); + toolbox = await openNewTabAndToolbox(TEST_URI, "inspector"); - ok(!toolbox.splitConsole, "Split console is hidden by default."); - ok(!getVisiblePrefValue(), "Visibility pref is false"); + ok(!toolbox.splitConsole, "Split console is hidden by default."); + ok(!getVisiblePrefValue(), "Visibility pref is false"); - yield toolbox.destroy(); - } + await toolbox.destroy(); +}); - function getActiveElement(doc) { - let activeElement = doc.activeElement; - while (activeElement && activeElement.contentDocument) { - activeElement = activeElement.contentDocument.activeElement; - } - return activeElement; +function getActiveElement(doc) { + let activeElement = doc.activeElement; + while (activeElement && activeElement.contentDocument) { + activeElement = activeElement.contentDocument.activeElement; } + return activeElement; +} - function getVisiblePrefValue() { - return Services.prefs.getBoolPref("devtools.toolbox.splitconsoleEnabled"); - } - - function getHeightPrefValue() { - return Services.prefs.getIntPref("devtools.toolbox.splitconsoleHeight"); - } +function getVisiblePrefValue() { + return Services.prefs.getBoolPref("devtools.toolbox.splitconsoleEnabled"); +} - function isCommandButtonChecked() { - return toolbox.doc.querySelector("#command-button-splitconsole") - .classList.contains("checked"); - } +function getHeightPrefValue() { + return Services.prefs.getIntPref("devtools.toolbox.splitconsoleHeight"); +} - function toggleSplitConsoleWithEscape() { - let onceSplitConsole = toolbox.once("split-console"); - let contentWindow = toolbox.win; - contentWindow.focus(); - EventUtils.sendKey("ESCAPE", contentWindow); - return onceSplitConsole; - } +function isCommandButtonChecked(toolbox) { + return toolbox.doc.querySelector("#command-button-splitconsole") + .classList.contains("checked"); +} - function finish() { - toolbox = TEST_URI = null; - finishTest(); - } +function toggleSplitConsoleWithEscape(toolbox) { + let onceSplitConsole = toolbox.once("split-console"); + let toolboxWindow = toolbox.win; + toolboxWindow.focus(); + EventUtils.sendKey("ESCAPE", toolboxWindow); + return onceSplitConsole; }
--- a/devtools/client/webconsole/new-console-output/test/mochitest/head.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/head.js @@ -134,16 +134,41 @@ function waitForMessages({ hud, messages return; } } }); }); } /** + * Wait for a message with the provided text and showing the provided repeat count. + * + * @param {Object} hud : the webconsole + * @param {String} text : text included in .message-body + * @param {Number} repeat : expected repeat count in .message-repeats + */ +function waitForRepeatedMessage(hud, text, repeat) { + return waitFor(() => { + // Wait for a message matching the provided text. + let node = findMessage(hud, text); + if (!node) { + return false; + } + + // Check if there is a repeat node with the expected count. + let repeatNode = node.querySelector(".message-repeats"); + if (repeatNode && parseInt(repeatNode.textContent, 10) === repeat) { + return node; + } + + return false; + }); +} + +/** * Wait for a single message in the web console output, resolving once it is received. * * @param {Object} hud : the webconsole * @param {String} text : text included in .message-body */ async function waitForMessage(hud, text) { const messages = await waitForMessages({hud, messages: [{text}]}); return messages[0]; @@ -172,16 +197,17 @@ async function waitFor(condition, messag * Find a message in the output. * * @param object hud * The web console. * @param string text * A substring that can be found in the message. * @param selector [optional] * The selector to use in finding the message. + * @return {Node} the node corresponding the found message */ function findMessage(hud, text, selector = ".message") { const elements = findMessages(hud, text, selector); return elements.pop(); } /** * Find multiple messages in the output.
rename from devtools/client/webconsole/new-console-output/test/mochitest/test_bug_1247459_violation.html rename to devtools/client/webconsole/new-console-output/test/mochitest/test-csp-violation.html
--- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -1577,16 +1577,17 @@ nsDocument::nsDocument(const char* aCont , mNeedsReleaseAfterStackRefCntRelease(false) , mMaybeServiceWorkerControlled(false) #ifdef DEBUG , mWillReparent(false) #endif , mDOMLoadingSet(false) , mDOMInteractiveSet(false) , mDOMCompleteSet(false) + , mAutoFocusFired(false) { SetContentTypeInternal(nsDependentCString(aContentType)); MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p created", this)); // Start out mLastStyleSheetSet as null, per spec SetDOMStringToNull(mLastStyleSheetSet); @@ -9439,16 +9440,130 @@ nsDocument::GetTemplateContentsOwner() // |doc| is the template contents owner of template elements created // by |doc|. doc->mTemplateContentsOwner = doc; } return mTemplateContentsOwner; } +static already_AddRefed<nsPIDOMWindowOuter> +FindTopWindowForElement(Element* element) +{ + nsIDocument* document = element->OwnerDoc(); + if (!document) { + return nullptr; + } + + nsCOMPtr<nsPIDOMWindowOuter> window = document->GetWindow(); + if (!window) { + return nullptr; + } + + // Trying to find the top window (equivalent to window.top). + if (nsCOMPtr<nsPIDOMWindowOuter> top = window->GetTop()) { + window = top.forget(); + } + return window.forget(); +} + +/** + * nsAutoFocusEvent is used to dispatch a focus event for an + * nsGenericHTMLFormElement with the autofocus attribute enabled. + */ +class nsAutoFocusEvent : public Runnable +{ +public: + explicit nsAutoFocusEvent(already_AddRefed<Element>&& aElement, + already_AddRefed<nsPIDOMWindowOuter>&& aTopWindow) + : mozilla::Runnable("nsAutoFocusEvent") + , mElement(aElement) + , mTopWindow(aTopWindow) + { + } + + NS_IMETHOD Run() override + { + nsCOMPtr<nsPIDOMWindowOuter> currentTopWindow = + FindTopWindowForElement(mElement); + if (currentTopWindow != mTopWindow) { + // The element's top window changed from when the event was queued. + // Don't take away focus from an unrelated window. + return NS_OK; + } + + // Don't steal focus from the user. + if (mTopWindow->GetFocusedNode()) { + return NS_OK; + } + + mozilla::ErrorResult rv; + mElement->Focus(rv); + return rv.StealNSResult(); + } +private: + nsCOMPtr<Element> mElement; + nsCOMPtr<nsPIDOMWindowOuter> mTopWindow; +}; + +void +nsDocument::SetAutoFocusElement(Element* aAutoFocusElement) +{ + if (mAutoFocusFired) { + // Too late. + return; + } + + if (mAutoFocusElement) { + // The spec disallows multiple autofocus elements, so we consider only the + // first one to preserve the old behavior. + return; + } + + mAutoFocusElement = do_GetWeakReference(aAutoFocusElement); + TriggerAutoFocus(); +} + +void +nsDocument::TriggerAutoFocus() +{ + if (mAutoFocusFired) { + return; + } + + if (!mPresShell || !mPresShell->DidInitialize()) { + // Delay autofocus until frames are constructed so that we don't thrash + // style and layout calculations. + return; + } + + nsCOMPtr<Element> autoFocusElement = do_QueryReferent(mAutoFocusElement); + if (autoFocusElement && autoFocusElement->OwnerDoc() == this) { + mAutoFocusFired = true; + + nsCOMPtr<nsPIDOMWindowOuter> topWindow = + FindTopWindowForElement(autoFocusElement); + if (!topWindow) { + return; + } + + // NOTE: This may be removed in the future since the spec technically + // allows autofocus after load. + nsCOMPtr<nsIDocument> topDoc = topWindow->GetExtantDoc(); + if (topDoc && topDoc->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE) { + return; + } + + nsCOMPtr<nsIRunnable> event = + new nsAutoFocusEvent(autoFocusElement.forget(), topWindow.forget()); + nsresult rv = NS_DispatchToCurrentThread(event.forget()); + NS_ENSURE_SUCCESS_VOID(rv); + } +} + void nsDocument::SetScrollToRef(nsIURI *aDocumentURI) { if (!aDocumentURI) { return; } nsAutoCString ref;
--- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -799,16 +799,19 @@ public: virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet, RefPtr<mozilla::StyleSheet>* aSheet) override; virtual nsISupports* GetCurrentContentSink() override; // Only BlockOnload should call this! void AsyncBlockOnload(); + virtual void SetAutoFocusElement(Element* aAutoFocusElement) override; + virtual void TriggerAutoFocus() override; + virtual void SetScrollToRef(nsIURI *aDocumentURI) override; virtual void ScrollToRef() override; virtual void ResetScrolledToRefAlready() override; virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) override; virtual Element* LookupImageElement(const nsAString& aElementId) override; virtual void MozSetImageElement(const nsAString& aImageElementId, Element* aElement) override; @@ -1301,16 +1304,18 @@ private: // Set if we've found a URL for the current picture nsString mPreloadPictureFoundSource; RefPtr<mozilla::dom::DOMImplementation> mDOMImplementation; RefPtr<nsContentList> mImageMaps; + nsWeakPtr mAutoFocusElement; + nsCString mScrollToRef; uint8_t mScrolledToRefAlready : 1; uint8_t mChangeScrollPosWhenScrollingToRef : 1; // Tracking for plugins in the document. nsTHashtable< nsPtrHashKey<nsIObjectLoadingContent> > mPlugins; RefPtr<mozilla::dom::DocumentTimeline> mDocumentTimeline; @@ -1351,16 +1356,17 @@ public: bool mWillReparent; #endif private: void RecordNavigationTiming(ReadyState aReadyState); bool mDOMLoadingSet : 1; bool mDOMInteractiveSet : 1; bool mDOMCompleteSet : 1; + bool mAutoFocusFired : 1; }; class nsDocumentOnStack { public: explicit nsDocumentOnStack(nsDocument* aDoc) : mDoc(aDoc) { mDoc->IncreaseStackRefCnt();
--- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1598,17 +1598,17 @@ nsFocusManager::CheckIfFocusable(nsICont nsCOMPtr<nsIDocument> doc = aContent->GetComposedDoc(); // can't focus elements that are not in documents if (!doc) { LOGCONTENT("Cannot focus %s because content not in document", aContent) return nullptr; } // Make sure that our frames are up to date while ensuring the presshell is - // also initialized in case we come from an autofocus event. + // also initialized in case we come from a script calling focus() early. mEventHandlingNeedsFlush = false; doc->FlushPendingNotifications(FlushType::EnsurePresShellInitAndFrames); nsIPresShell *shell = doc->GetShell(); if (!shell) return nullptr; // the root content can always be focused,
--- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2632,16 +2632,19 @@ public: */ mozilla::EventStates GetDocumentState() const { return mDocumentState; } virtual nsISupports* GetCurrentContentSink() = 0; + virtual void SetAutoFocusElement(Element* aAutoFocusElement) = 0; + virtual void TriggerAutoFocus() = 0; + virtual void SetScrollToRef(nsIURI *aDocumentURI) = 0; virtual void ScrollToRef() = 0; virtual void ResetScrolledToRefAlready() = 0; virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) = 0; using mozilla::dom::DocumentOrShadowRoot::GetElementById; using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagName; using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagNameNS;
--- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -106,74 +106,16 @@ #include "mozilla/StyleSetHandleInlines.h" #include "ReferrerPolicy.h" #include "mozilla/dom/HTMLLabelElement.h" #include "mozilla/dom/HTMLInputElement.h" using namespace mozilla; using namespace mozilla::dom; -/** - * nsAutoFocusEvent is used to dispatch a focus event when a - * nsGenericHTMLFormElement is binded to the tree with the autofocus attribute - * enabled. - */ -class nsAutoFocusEvent : public Runnable -{ -public: - explicit nsAutoFocusEvent(nsGenericHTMLFormElement* aElement) - : mozilla::Runnable("nsAutoFocusEvent") - , mElement(aElement) - { - } - - NS_IMETHOD Run() override { - nsFocusManager* fm = nsFocusManager::GetFocusManager(); - if (!fm) { - return NS_ERROR_NULL_POINTER; - } - - nsIDocument* document = mElement->OwnerDoc(); - - nsPIDOMWindowOuter* window = document->GetWindow(); - if (!window) { - return NS_OK; - } - - // Trying to found the top window (equivalent to window.top). - if (nsCOMPtr<nsPIDOMWindowOuter> top = window->GetTop()) { - window = top; - } - - if (window->GetFocusedNode()) { - return NS_OK; - } - - nsCOMPtr<nsIDocument> topDoc = window->GetExtantDoc(); - if (topDoc && topDoc->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE) { - return NS_OK; - } - - // If something is focused in the same document, ignore autofocus. - if (!fm->GetFocusedContent() || - fm->GetFocusedContent()->OwnerDoc() != document) { - mozilla::ErrorResult rv; - mElement->Focus(rv); - return rv.StealNSResult(); - } - - return NS_OK; - } -private: - // NOTE: nsGenericHTMLFormElement is saved as a nsGenericHTMLElement - // because AddRef/Release are ambiguous with nsGenericHTMLFormElement - // and Focus() is declared (and defined) in nsGenericHTMLElement class. - RefPtr<nsGenericHTMLElement> mElement; -}; - NS_IMPL_ADDREF_INHERITED(nsGenericHTMLElement, nsGenericHTMLElementBase) NS_IMPL_RELEASE_INHERITED(nsGenericHTMLElement, nsGenericHTMLElementBase) NS_INTERFACE_MAP_BEGIN(nsGenericHTMLElement) NS_INTERFACE_MAP_ENTRY(nsIDOMElement) NS_INTERFACE_MAP_ENTRY(nsIDOMNode) NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElementBase) @@ -1877,20 +1819,18 @@ nsGenericHTMLFormElement::BindToTree(nsI aCompileEventHandlers); NS_ENSURE_SUCCESS(rv, rv); // An autofocus event has to be launched if the autofocus attribute is // specified and the element accept the autofocus attribute. In addition, // the document should not be already loaded and the "browser.autofocus" // preference should be 'true'. if (IsAutofocusable() && HasAttr(kNameSpaceID_None, nsGkAtoms::autofocus) && - nsContentUtils::AutoFocusEnabled()) { - nsCOMPtr<nsIRunnable> event = new nsAutoFocusEvent(this); - rv = NS_DispatchToCurrentThread(event); - NS_ENSURE_SUCCESS(rv, rv); + nsContentUtils::AutoFocusEnabled() && aDocument) { + aDocument->SetAutoFocusElement(this); } // If @form is set, the element *has* to be in a document, otherwise it // wouldn't be possible to find an element with the corresponding id. // If @form isn't set, the element *has* to have a parent, otherwise it // wouldn't be possible to find a form ancestor. // We should not call UpdateFormOwner if none of these conditions are // fulfilled.
--- a/dom/xbl/nsXBLWindowKeyHandler.cpp +++ b/dom/xbl/nsXBLWindowKeyHandler.cpp @@ -560,19 +560,22 @@ nsXBLWindowKeyHandler::HandleEventOnCapt void nsXBLWindowKeyHandler::HandleEventOnCaptureInSystemEventGroup( KeyboardEvent* aEvent) { WidgetKeyboardEvent* widgetEvent = aEvent->WidgetEventPtr()->AsKeyboardEvent(); // If the event won't be sent to remote process, this listener needs to do - // nothing. - if (widgetEvent->mFlags.mOnlySystemGroupDispatchInContent || - !widgetEvent->WillBeSentToRemoteProcess()) { + // nothing. Note that even if mOnlySystemGroupDispatchInContent is true, + // we need to send the event to remote process and check reply event + // before matching it with registered shortcut keys because event listeners + // in the system event group may want to handle the event before registered + // shortcut key handlers. + if (!widgetEvent->WillBeSentToRemoteProcess()) { return; } if (!HasHandlerForEvent(aEvent)) { return; } // If this event wasn't marked as IsCrossProcessForwardingStopped,
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -4509,24 +4509,24 @@ BinParse(JSContext* cx, unsigned argc, V if (args.length() < 1) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED, "parse", "0", "s"); return false; } if (!args[0].isObject()) { const char* typeName = InformalValueTypeName(args[0]); - JS_ReportErrorASCII(cx, "expected object (typed array) to parse, got %s", typeName); + JS_ReportErrorASCII(cx, "expected object (ArrayBuffer) to parse, got %s", typeName); return false; } RootedObject obj(cx, &args[0].toObject()); - if (!JS_IsTypedArrayObject(obj)) { + if (!JS_IsArrayBufferObject(obj)) { const char* typeName = InformalValueTypeName(args[0]); - JS_ReportErrorASCII(cx, "expected typed array to parse, got %s", typeName); + JS_ReportErrorASCII(cx, "expected ArrayBuffer to parse, got %s", typeName); return false; } uint32_t buf_length = 0; bool buf_isSharedMemory = false; uint8_t* buf_data = nullptr; GetArrayBufferViewLengthAndData(obj, &buf_length, &buf_isSharedMemory, &buf_data); MOZ_ASSERT(buf_data);
--- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -1812,16 +1812,18 @@ PresShell::Initialize(nscoord aWidth, ns // (Do this in a script runner, since our caller might have a script // blocker on the stack.) nsContentUtils::AddScriptRunner(new XBLConstructorRunner(mDocument)); // XBLConstructorRunner might destroy us. NS_ENSURE_STATE(!mHaveShutDown); } + mDocument->TriggerAutoFocus(); + NS_ASSERTION(rootFrame, "How did that happen?"); // Note: when the frame was created above it had the NS_FRAME_IS_DIRTY bit // set, but XBL processing could have caused a reflow which clears it. if (MOZ_LIKELY(rootFrame->GetStateBits() & NS_FRAME_IS_DIRTY)) { // Unset the DIRTY bits so that FrameNeedsReflow() will work right. rootFrame->RemoveStateBits(NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN);
new file mode 100644 --- /dev/null +++ b/layout/reftests/bugs/712130-1-ref.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<link rel="stylesheet" href="nothing"><!-- Empty stylesheet to delay PresShell init --> +<input type="text" autofocus="" onfocus="document.documentElement.removeAttribute('class')"> +<input type="text">
new file mode 100644 --- /dev/null +++ b/layout/reftests/bugs/712130-1.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<link rel="stylesheet" href="nothing"><!-- Empty stylesheet to delay PresShell init --> +<input type="text" autofocus="" onfocus="document.documentElement.removeAttribute('class')"> +<input type="text" autofocus="" onfocus="document.documentElement.removeAttribute('class')">
new file mode 100644 --- /dev/null +++ b/layout/reftests/bugs/712130-2-ref.html @@ -0,0 +1,3 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<input type="text" autofocus="" onfocus="document.documentElement.removeAttribute('class')">
new file mode 100644 --- /dev/null +++ b/layout/reftests/bugs/712130-2.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<link rel="stylesheet" href="nothing"><!-- Empty stylesheet to delay PresShell init --> +<input type="text" autofocus="" onfocus="document.documentElement.removeAttribute('class')">
--- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1702,16 +1702,18 @@ skip-if(azureSkiaGL) == 670442-1.html 67 != 691087-1.html 691087-1-ref.html == 691571-1.html 691571-1-ref.html fuzzy-if(skiaContent,1,200) == 696307-1.html 696307-1-ref.html fuzzy-if(skiaContent,1,550) == 696739-1.html 696739-1-ref.html needs-focus == 703186-1.html 703186-1-ref.html needs-focus == 703186-2.html 703186-2-ref.html needs-focus != 703186-1.html 703186-2.html == 711359-1.html 711359-1-ref.html +fuzzy-if(skiaContent,1,3) needs-focus == 712130-1.html 712130-1-ref.html +fuzzy-if(skiaContent,1,3) needs-focus == 712130-2.html 712130-2-ref.html == 712849-1.html 712849-1-ref.html == 713856-static.html 713856-ref.html == 713856-dynamic.html 713856-ref.html == 714519-1-as.html 714519-1-ref.html == 714519-1-q.html 714519-1-ref.html == 714519-2-as.html 714519-2-ref.html == 714519-2-q.html 714519-2-ref.html fuzzy-if(true,1,21) fuzzy-if(d2d,71,173) fuzzy-if(cocoaWidget,1,170) == 718521.html 718521-ref.html # bug 773482
--- a/memory/build/rb.h +++ b/memory/build/rb.h @@ -62,16 +62,17 @@ // that treat the first argument specially. // // *************************************************************************** #ifndef RB_H_ #define RB_H_ #include "mozilla/Alignment.h" +#include "mozilla/Assertions.h" #include "Utils.h" enum NodeColor { Black = 0, Red = 1, }; @@ -415,18 +416,18 @@ private: // instead swap it with its successor and delete the // successor. Record enough information to do the // swap later. rbp_r_xp is the aNode's parent. rbp_r_xp = rbp_r_p; rbp_r_cmp = Order::eGreater; // Note that deletion is incomplete. } } if (rbp_r_cmp == Order::eGreater) { - if (rbp_r_c->Right() && (!rbp_r_c->Right()->Left() || - rbp_r_c->Right()->Left()->IsBlack())) { + if (!rbp_r_c->Right() || !rbp_r_c->Right()->Left() || + rbp_r_c->Right()->Left()->IsBlack()) { rbp_r_t = rbp_r_c->Left(); if (rbp_r_t->IsRed()) { // Standard transform. rbp_r_t = MoveRedRight(rbp_r_c); } else { // Root-specific transform. rbp_r_c->SetColor(NodeColor::Red); rbp_r_u = rbp_r_t->Left();
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java @@ -2730,19 +2730,21 @@ public class BrowserApp extends GeckoApp keywordSearch = ""; } else { keyword = url.substring(0, index); keywordSearch = url.substring(index + 1); } final String keywordUrl = db.getUrlForKeyword(getContentResolver(), keyword); - // If there isn't a bookmark keyword, load the url. This may result in a query - // using the default search engine. - if (TextUtils.isEmpty(keywordUrl)) { + // If there isn't a bookmark keyword, or if there is no search query + // within the keywordURL, yet one is provided, load the url. + // This may result in a query using the default search engine. + if (TextUtils.isEmpty(keywordUrl) || + (!TextUtils.isEmpty(keywordSearch) && !StringUtils.queryExists(keywordUrl))) { Tabs.getInstance().loadUrl(url, Tabs.LOADURL_USER_ENTERED); Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.ACTIONBAR, "user"); return; } // Otherwise, construct a search query from the bookmark keyword. // Replace lower case bookmark keywords with URLencoded search query or // replace upper case bookmark keywords with un-encoded search query.
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java @@ -66,16 +66,28 @@ public class StringUtils { if (dot > -1 || colon > -1) { return false; } // Otherwise, text is ambiguous, and we keep its status unchanged return wasSearchQuery; } /** + * Check for the existence of %s and %S in a given URL + * + * @return True if %s or %S exists, False otherwise. + */ + public static boolean queryExists(final String inputURL) { + if (inputURL == null) { + return false; + } + return inputURL.contains("%s") || inputURL.contains("%S"); + } + + /** * Strip the ref from a URL, if present * * @return The base URL, without the ref. The original String is returned if it has no ref, * of if the input is malformed. */ public static String stripRef(final String inputURL) { if (inputURL == null) { return null; @@ -313,9 +325,9 @@ public class StringUtils { * @param textPaint the paint used to render the text * @return the width of the specified substring in screen pixels */ public static int getTextWidth(final String text, final int start, final int end, final Paint textPaint) { final Rect bounds = new Rect(); textPaint.getTextBounds(text, start, end, bounds); return bounds.width(); } -} \ No newline at end of file +}
--- a/mobile/android/geckoview/src/test/java/org/mozilla/gecko/util/TestStringUtils.java +++ b/mobile/android/geckoview/src/test/java/org/mozilla/gecko/util/TestStringUtils.java @@ -135,16 +135,35 @@ public class TestStringUtils { // test ambiguous String ambiguous = "~!@#$%^&*()_+`34567890-=qwertyuiop[]\\QWERTYUIOP{}|asdfghjkl;'ASDFGHJKL:\"ZXCVBNM<>?zxcvbnm,./"; ambiguous = ambiguous.replace(" ","").replace(".","").replace(":",""); assertTrue(StringUtils.isSearchQuery(ambiguous,true)); assertFalse(StringUtils.isSearchQuery(ambiguous,false)); } + + @Test + public void testQueryExists(){ + // test empty + assertFalse(StringUtils.queryExists("")); + + // test single + assertFalse(StringUtils.queryExists("mozilla.org")); + assertFalse(StringUtils.queryExists("https://www.google.com/")); + assertTrue(StringUtils.queryExists("https://www.google.com/search?q=%s")); + assertTrue(StringUtils.queryExists("https://www.google.com/search?q=%S")); + assertTrue(StringUtils.queryExists("%s")); + assertTrue(StringUtils.queryExists("%S")); + + //test double + assertTrue(StringUtils.queryExists("%s%S")); + assertTrue(StringUtils.queryExists("https://www.google.com/search?q=%s%S")); + } + @Test public void testPathStartIndex(){ // Tests without protocol assertTrue(StringUtils.pathStartIndex("mozilla.org") == -1); assertTrue(StringUtils.pathStartIndex("mozilla.org/en-US") == 11); // Tests with protocol assertTrue(StringUtils.pathStartIndex("https://mozilla.org") == -1);
--- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1258,21 +1258,17 @@ pref("extensions.spellcheck.inline.max-m // belong in comm-central/editor/ui/composer.js pref("editor.use_custom_colors", false); pref("editor.singleLine.pasteNewlines", 2); pref("editor.use_css", false); pref("editor.css.default_length_unit", "px"); pref("editor.resizing.preserve_ratio", true); pref("editor.positioning.offset", 0); -#ifdef EARLY_BETA_OR_EARLIER pref("editor.use_div_for_default_newlines", true); -#else -pref("editor.use_div_for_default_newlines", false); -#endif // Scripts & Windows prefs pref("dom.disable_beforeunload", false); pref("dom.disable_window_flip", false); pref("dom.disable_window_move_resize", false); pref("dom.disable_window_open_feature.titlebar", false); pref("dom.disable_window_open_feature.close", false);
--- a/security/manager/ssl/StaticHPKPins.h +++ b/security/manager/ssl/StaticHPKPins.h @@ -1157,9 +1157,9 @@ static const TransportSecurityPreload kP { "za.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, { "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, }; // Pinning Preload List Length = 484; static const int32_t kUnknownId = -1; -static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1527104327502000); +static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1527191478174000);
--- a/security/manager/ssl/nsSTSPreloadList.errors +++ b/security/manager/ssl/nsSTSPreloadList.errors @@ -1,10 +1,11 @@ 00220022.net: could not connect to host 007-preisvergleich.de: could not connect to host +00881919.com: could not connect to host 01100010011001010111001101110100.com: could not connect to host 0day.su: could not connect to host 0i0.nl: could not connect to host 0vi.org: could not connect to host 0x52.org: could not connect to host 10gb.io: could not connect to host 135vv.com: could not connect to host 13826145000.com: could not connect to host @@ -62,48 +63,52 @@ achterhoekseveiligheidsbeurs.nl: could n acpinformatique.fr: could not connect to host acrossgw.com: could not connect to host ad-disruptio.fr: could not connect to host adamcoffee.net: could not connect to host adamdixon.co.uk: could not connect to host adec-emsa.ae: could not connect to host adora-illustrations.fr: could not connect to host adult.properties: could not connect to host +adzie.xyz: could not connect to host aevpn.org: could not connect to host affily.io: could not connect to host afterstack.net: could not connect to host agoravm.tk: could not connect to host agowa.eu: could not connect to host agowa338.de: could not connect to host ahlz.sk: could not connect to host aiicy.org: could not connect to host aikenorganics.com: could not connect to host aim-consultants.com: could not connect to host ajetaci.cz: could not connect to host akiba-server.info: could not connect to host akita-stream.com: could not connect to host +akoch.net: could not connect to host akoww.de: could not connect to host akul.co.in: could not connect to host al-f.net: could not connect to host alasta.info: could not connect to host alauda-home.de: could not connect to host alcatraz.online: could not connect to host alexandernorth.ch: could not connect to host alexdaulby.com: could not connect to host alexei.su: could not connect to host alexey-shamara.ru: could not connect to host alexmol.tk: could not connect to host alexperry.io: could not connect to host alilialili.ga: could not connect to host alldm.ru: could not connect to host alloutatl.com: could not connect to host allscammers.exposed: could not connect to host +almatinki.com: could not connect to host alohapartyevents.co.uk: could not connect to host alphabrock.cn: could not connect to host altahrim.net: could not connect to host +amateurvoicetalent.com: could not connect to host amdouglas.uk: could not connect to host ameho.me: could not connect to host americandistribuidora.com: could not connect to host amilum.org: could not connect to host amua.fr: could not connect to host amunoz.org: could not connect to host analyzemyfriends.com: could not connect to host anastasia-shamara.ru: could not connect to host @@ -112,30 +117,30 @@ andreamcnett.com: could not connect to h andreas-kluge.eu: could not connect to host andreaskluge.eu: could not connect to host andrei-coman.com: could not connect to host andrewdaws.co: could not connect to host andrewdaws.info: could not connect to host andrewdaws.me: could not connect to host andrewdaws.tv: could not connect to host andrewrdaws.com: could not connect to host +andronika.net: could not connect to host angrydragonproductions.com: could not connect to host -animacurse.moe: could not connect to host anitube-nocookie.ch: could not connect to host annetaan.fi: could not connect to host -anon-next.de: could not connect to host anothermanfilm.co.uk: could not connect to host anshumanbiswas.com: could not connect to host antimatiere.space: could not connect to host antoinedeschenes.com: could not connect to host anyways.at: could not connect to host aojiao.org: could not connect to host apkoyunlar.club: could not connect to host appdrinks.com: could not connect to host apple.ax: could not connect to host +apps4all.sytes.net: could not connect to host area3.org: could not connect to host arent.kz: could not connect to host arenzanaphotography.com: could not connect to host argh.io: could not connect to host arknodejs.com: could not connect to host arksan.com.tr: could not connect to host armenians.online: could not connect to host arne-petersen.net: could not connect to host @@ -143,22 +148,24 @@ arresttracker.com: could not connect to arsenal.ru: could not connect to host artea.ga: could not connect to host articaexports.com: could not connect to host artisense.de: could not connect to host artisticedgegranite.net: could not connect to host artofeyes.nl: could not connect to host as200753.com: could not connect to host as200753.net: could not connect to host +asdyx.de: could not connect to host ashleyadum.com: could not connect to host askmagicconch.com: could not connect to host asphaltfruehling.de: could not connect to host asral7.com: could not connect to host assdecoeur.org: could not connect to host assindia.nl: could not connect to host +astaninki.com: could not connect to host asthon.cn: could not connect to host astrath.net: could not connect to host astrea-voetbal-groningen.nl: could not connect to host astrosnail.pt.eu.org: could not connect to host asuhe.xyz: could not connect to host async.be: could not connect to host at1.co: could not connect to host athi.pl: could not connect to host @@ -196,16 +203,17 @@ bandarifamily.com: could not connect to bannisbierblog.de: could not connect to host bardiharborow.com: could not connect to host bardiharborow.tk: could not connect to host barracuda.blog: could not connect to host barreaudenice.com: could not connect to host bashc.at: could not connect to host batfoundry.com: could not connect to host bbdos.ru: could not connect to host +bbwcs.co.uk: could not connect to host bbwteens.org: could not connect to host bcnet.com.hk: could not connect to host bdsmxxxpics.com: could not connect to host beamitapp.com: could not connect to host beasel.biz: could not connect to host beccajoshwedding.com: could not connect to host beersandco.ch: could not connect to host bellavistaoutdoor.com: could not connect to host @@ -271,23 +279,25 @@ bonobo.cz: could not connect to host bookreport.ga: could not connect to host borchers-media.de: could not connect to host borisbesemer.com: could not connect to host bouncing-bugs.co.uk: could not connect to host bqcp.net: could not connect to host brainlag.org: could not connect to host braintensive.com: could not connect to host brandontaylor-black.com: could not connect to host +bratteng.me: could not connect to host breathingblanket.com: could not connect to host brettabel.com: could not connect to host brfvh24.se: could not connect to host brideandgroomdirect.ie: could not connect to host brio-ukraine.store: could not connect to host brookframework.org: could not connect to host brrr.fr: could not connect to host +bruckner.li: could not connect to host bryanshearer.accountant: could not connect to host brynnan.nl: could not connect to host bsalyzer.com: could not connect to host bsktweetup.info: could not connect to host bslim-e-boutique.com: could not connect to host bsuess.de: could not connect to host btsow.com: could not connect to host buenotour.ru: could not connect to host @@ -316,17 +326,16 @@ calculatoaresecondhand.xyz: could not co callabs.net: could not connect to host calleveryday.com: could not connect to host callsigns.ca: could not connect to host calypso-tour.net: could not connect to host camda.online: could not connect to host campingcarlovers.com: could not connect to host cancelmyprofile.com: could not connect to host canifis.net: could not connect to host -caps.is: could not connect to host cardelmar.es: could not connect to host cardloan-manual.net: could not connect to host carey.bio: could not connect to host carloshmm.stream: could not connect to host carlovanwyk.com: could not connect to host carrierplatform.com: could not connect to host casinoreal.com: could not connect to host catsmagic.pp.ua: could not connect to host @@ -345,18 +354,16 @@ centos.pub: could not connect to host centrallead.net: could not connect to host cervejista.com: could not connect to host cgtx.us: could not connect to host challengeskins.com: could not connect to host championnat-romand-cuisiniers-amateurs.ch: could not connect to host channellife.asia: could not connect to host chaouby.com: could not connect to host charonsecurity.com: could not connect to host -chatzimanolis.com: could not connect to host -chatzimanolis.gr: could not connect to host cheesefusion.com: could not connect to host chez-janine.de: could not connect to host childrendeservebetter.org: could not connect to host china-line.org: could not connect to host chinternet.xyz: could not connect to host chiropracticwpb.com: could not connect to host chloe.re: could not connect to host chocolat-suisse.ch: could not connect to host @@ -375,17 +382,16 @@ class.com.au: could not connect to host clearchatsandbox.com: could not connect to host clearviewwealthprojector.com.au: could not connect to host clic-music.com: could not connect to host clintonbloodworth.com: could not connect to host closetemail.com: could not connect to host cloudbleed.info: could not connect to host cloudbolin.es: could not connect to host cloudimproved.com: could not connect to host -cloudimprovedtest.com: could not connect to host cloudwarez.xyz: could not connect to host clownish.co.il: could not connect to host clycat.ru: could not connect to host cmpr.es: could not connect to host cmrss.com: could not connect to host cms-weble.jp: could not connect to host cmweller.com: could not connect to host cnetw.xyz: could not connect to host @@ -407,16 +413,17 @@ coloppe.com: could not connect to host com.cc: could not connect to host combatshield.cz: could not connect to host complex-organization.com: could not connect to host complt.xyz: could not connect to host comprehensiveihc.com: could not connect to host conception.sk: could not connect to host conniesacademy.com: could not connect to host conrad.am: could not connect to host +console.ninja: could not connect to host construct-trust.com: could not connect to host constructive.men: could not connect to host conve.eu: could not connect to host coreapm.com: could not connect to host coreapm.org: could not connect to host corecdn.org: could not connect to host corinnanese.de: could not connect to host correct.horse: could not connect to host @@ -451,17 +458,16 @@ cypherpunk.ws: could not connect to host czlx.co: could not connect to host d-bood.site: could not connect to host d3x.pw: could not connect to host d8studio.net: could not connect to host daltonedwards.me: could not connect to host dam74.com.ar: could not connect to host daniel-stahl.net: could not connect to host danielthompson.info: could not connect to host -danpiel.net: could not connect to host darkdestiny.ch: could not connect to host darlo.co.uk: could not connect to host darrienworth.com: could not connect to host dashboard.yt: could not connect to host data-detox.com: could not connect to host databutlr.com: could not connect to host databutlr.net: could not connect to host datacool.tk: could not connect to host @@ -480,28 +486,29 @@ dc585.info: could not connect to host dcc.moe: could not connect to host dden.website: could not connect to host dden.xyz: could not connect to host de-servers.de: could not connect to host decoyrouting.com: could not connect to host dedietrich-asia.com: could not connect to host deepcreampie.com: could not connect to host deeps.cat: could not connect to host -deepspace.dedyn.io: could not connect to host deloittequant.com: could not connect to host derchris.me: could not connect to host derivativeshub.pro: could not connect to host dermacarecomplex.com: could not connect to host +design-fu.com: could not connect to host detecte-fuite.ch: could not connect to host detecte.ch: could not connect to host detectefuite.ch: could not connect to host devdesco.com: could not connect to host developersclub.website: could not connect to host deviltraxxx.de: could not connect to host devops.moe: could not connect to host +dgby.org: could not connect to host dhl-smart.ch: could not connect to host dhub.xyz: could not connect to host dhuy.net: could not connect to host dhxxls.com: could not connect to host diceduels.com: could not connect to host dicgaming.net: could not connect to host dick.red: could not connect to host didierlaumen.be: could not connect to host @@ -516,34 +523,33 @@ diguass.us: could not connect to host dijks.com: could not connect to host dingcc.com: could not connect to host directtwo.solutions: could not connect to host direwolfsoftware.ca: could not connect to host dirtycat.ru: could not connect to host disability.gov: could not connect to host disadattamentolavorativo.it: could not connect to host disco-crazy-world.de: could not connect to host +discoveringdocker.com: could not connect to host discoveryballoon.org: could not connect to host distinctivephotography.com.au: could not connect to host ditch.ch: could not connect to host dixmag.com: could not connect to host djul.net: could not connect to host dlouwrink.nl: could not connect to host dlyl888.com: could not connect to host dnfc.rocks: could not connect to host dobrisan.ro: could not connect to host doctafit.com: could not connect to host doesmycodehavebugs.today: could not connect to host dogcratereview.info: could not connect to host dojifish.space: could not connect to host dolphin-hosting.com: could not connect to host -domainstaff.com: could not connect to host domengrad.ru: could not connect to host domfee.com: could not connect to host -dominicself.co.uk: could not connect to host dongkexue.com: could not connect to host doop.im: could not connect to host doopdidoop.com: could not connect to host dopesoft.de: could not connect to host dostavkakurierom.ru: could not connect to host dougferris.id.au: could not connect to host doyoulyft.com: could not connect to host doze-cloud.tech: could not connect to host @@ -576,22 +582,24 @@ e-mak.eu: could not connect to host e-wishlist.net: could not connect to host earth-people.org: could not connect to host eatfitoutlet.com.br: could not connect to host eatry.io: could not connect to host ebonyriddle.com: could not connect to host eccux.com: could not connect to host ectora.com: could not connect to host edgecustomersportal.com: could not connect to host +edp-collaborative.com: could not connect to host eduif.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 115" data: no] eeb98.com: could not connect to host effectiveosgi.com: could not connect to host ehrlichesbier.de: could not connect to host ehuber.info: could not connect to host einsatzstiefel.info: could not connect to host +ejgconsultancy.co.uk: could not connect to host ekobudisantoso.net: could not connect to host elbetech.net: could not connect to host electricalcontrolpanels.co.uk: could not connect to host elektronring.com: could not connect to host elenorsmadness.org: could not connect to host elevateandprosper.com: could not connect to host elitesensual.com.br: could not connect to host elonbase.com: could not connect to host @@ -603,32 +611,35 @@ embracethedarkness.co.uk: could not conn emeraldcoastrideshare.com: could not connect to host emilyjohnson.ga: could not connect to host emrenovation.com: could not connect to host endohaus.us: could not connect to host endspamwith.us: could not connect to host enoou.com: could not connect to host enpalmademallorca.info: could not connect to host er-music.com: could not connect to host +erad.fr: could not connect to host erspro.net: could not connect to host erwinwensveen.nl: could not connect to host esoterik.link: could not connect to host +esseriumani.com: could not connect to host ethiobaba.com: could not connect to host euexia.fr: could not connect to host eung.ga: could not connect to host eurostrategy.vn.ua: could not connect to host evankurniawan.com: could not connect to host everyarti.st: could not connect to host eveshaiwu.com: could not connect to host +evileden.com: could not connect to host eworksmedia.com: could not connect to host exceed.global: could not connect to host exceptionalservices.us: could not connect to host exo.do: could not connect to host -extensiblewebsummit.org: could not connect to host exteriorservices.io: could not connect to host +extreme-players.com: could not connect to host eytosh.net: could not connect to host f1bigpicture.com: could not connect to host f8842.com: could not connect to host faber.org.ru: could not connect to host fabian-fingerle.de: could not connect to host fabian-kluge.de: could not connect to host fabienbaker.com: could not connect to host fabulouslyyouthfulskin.com: could not connect to host @@ -722,46 +733,47 @@ frusky.net: could not connect to host fsfi.is: could not connect to host fsradio.eu: could not connect to host ftgho.com: could not connect to host fuckcf.cf: could not connect to host fugle.de: could not connect to host fuitedeau.ch: could not connect to host fukuko.biz: could not connect to host fukuko.xyz: could not connect to host +fukuoka-cityliner.jp: could not connect to host fun9.cc: could not connect to host fun99.cc: could not connect to host funksteckdosen24.de: could not connect to host funoverip.net: could not connect to host funspins.com: could not connect to host futos.de: could not connect to host fuzoku-sodan.com: could not connect to host fyol.pw: could not connect to host g01.in.ua: could not connect to host g1jeu.com: could not connect to host gaasuper6.com: could not connect to host gabriele-kluge.de: could not connect to host gafachi.com: could not connect to host -gagniard.org: could not connect to host gala.kiev.ua: could not connect to host galgoafegao.com.br: could not connect to host galgoingles.com.br: could not connect to host gam3rs.de: could not connect to host game-gentle.com: could not connect to host gameswitchers.uk: could not connect to host gametium.com: could not connect to host gametium.es: could not connect to host gamhealth.net: could not connect to host gancedo.com.es: could not connect to host garage-door.pro: could not connect to host gasbarkenora.com: could not connect to host gasnews.net: could not connect to host gautham.it: could not connect to host gautham.pro: could not connect to host gaygeeks.de: could not connect to host +gaytorrent.ru: could not connect to host gc.net: could not connect to host gchoic.com: could not connect to host gdevpenze.ru: could not connect to host gdhzcgs.com: could not connect to host gdz-otvety.com: could not connect to host ge1.me: could not connect to host geek.ch: could not connect to host gehrke.nrw: could not connect to host @@ -786,31 +798,33 @@ getitpeople.com: could not connect to ho getwarden.net: could not connect to host getyourphix.tk: could not connect to host gevaulug.fr: could not connect to host gfoss.gr: could not connect to host gglks.com: could not connect to host ggss.cf: could not connect to host gh16.com.ar: could not connect to host gifzilla.net: could not connect to host +giliamor.com: could not connect to host gina-architektur.design: could not connect to host girlsforum.com: could not connect to host git.co: could not connect to host gix.net.pl: could not connect to host gladystudio.com: could not connect to host globalvisions-events.ch: could not connect to host glutenfreelife.co.nz: could not connect to host gmantra.org: could not connect to host gmanukyan.com: could not connect to host gnom.me: could not connect to host gnosticjade.net: could not connect to host godrealms.com: could not connect to host goiaspropaganda.com.br: could not connect to host goldfelt.com: could not connect to host gongjuhao.com: could not connect to host +goodyearsotn.co.uk: could not connect to host google.ax: could not connect to host goranrango.ch: could not connect to host gottfridsberg.org: could not connect to host gozadentro.com: could not connect to host gradsm-ci.net: could not connect to host granth.io: could not connect to host grassenberg.de: could not connect to host gratisonlinesex.com: could not connect to host @@ -818,28 +832,30 @@ greenitpark.net: could not connect to ho greggsfoundation.org.uk: could not connect to host gregmartyn.com: could not connect to host greuel.online: could not connect to host gritte.net: could not connect to host grossmisconduct.news: could not connect to host gugaltika-ipb.org: could not connect to host guinea-pig.co: could not connect to host guishem.com: could not connect to host +gunhunter.com: could not connect to host gurochan.ch: could not connect to host gus.moe: could not connect to host gutuia.blue: could not connect to host gvchannel.xyz: could not connect to host gzpblog.com: could not connect to host h3artbl33d.nl: could not connect to host habeo.si: could not connect to host hackbubble.me: could not connect to host hackingsafe.com: could not connect to host hackmeplz.com: could not connect to host haktec.de: could not connect to host hakugin.me: could not connect to host +halacs.hu: could not connect to host halcyonsbastion.com: could not connect to host half-logic.eu.org: could not connect to host halkyon.net: could not connect to host hamking.tk: could not connect to host hamu.blue: could not connect to host handinhandfoundation.org.uk: could not connect to host hapijs.cn: could not connect to host happytiger.eu: could not connect to host @@ -878,32 +894,34 @@ hetmeisjeachterpauw.nl: could not connec hexobind.com: could not connect to host hfu.io: could not connect to host hg881.com: could not connect to host hialatv.com: could not connect to host hill.selfip.net: could not connect to host hintermeier-rae.at: could not connect to host hirte-digital.de: could not connect to host hitchunion.org: could not connect to host +hiverlune.net: could not connect to host hjes.com.ve: could not connect to host hohm.in: could not connect to host holidayincotswolds.co.uk: could not connect to host homoglyph.net: could not connect to host hondenoppasfraneker.nl: could not connect to host honeycome.net: could not connect to host hoodoo.io: could not connect to host hoodoo.tech: could not connect to host hopglass.eu: could not connect to host hopglass.net: could not connect to host horvathd.eu: could not connect to host hosted-oswa.org: could not connect to host hotelmadhuwanvihar.com: could not connect to host hozinga.de: could not connect to host hr98.tk: could not connect to host hserver.top: could not connect to host +https4all.org: could not connect to host httptest.net: could not connect to host huangzenghao.cn: could not connect to host huangzenghao.com: could not connect to host hudingyuan.cn: could not connect to host huiser.nl: could not connect to host hukkatavara.com: could not connect to host hunger.im: could not connect to host huongquynh.com: could not connect to host @@ -942,16 +960,17 @@ imlinan.cn: could not connect to host imlinan.info: could not connect to host imlinan.net: could not connect to host imoner.ga: could not connect to host imperdintechnologies.com: could not connect to host increasetestosteronelevels.org: could not connect to host industreiler.com: could not connect to host industreiler.com.br: could not connect to host inexpensivecomputers.net: could not connect to host +infocity-tech.fr: could not connect to host informatik.zone: could not connect to host infoworm.org: could not connect to host injust.me: could not connect to host innovativeideaz.org: could not connect to host inondation.ch: could not connect to host inscript.pl: could not connect to host insouciant.org: could not connect to host inst.mobi: could not connect to host @@ -966,20 +985,23 @@ iodu.re: could not connect to host ip.or.at: could not connect to host iphonechina.net: could not connect to host iplog.info: could not connect to host ipnetworking.net: could not connect to host irinkeby.nu: could not connect to host isamiok.com: could not connect to host isisfighters.info: could not connect to host iskkk.com: could not connect to host +isoroc-nidzica.pl: could not connect to host isscouncil.com: could not connect to host +issuesofconcern.in: could not connect to host isthefieldcontrolsystemdown.com: could not connect to host isz.no: could not connect to host itad.top: could not connect to host +itnews-bg.com: could not connect to host itpro-mg.de: could not connect to host its-schindler.de: could not connect to host itsatrap.nl: could not connect to host ivanilla.org: could not connect to host ivanpolchenko.com: could not connect to host ivystech.com: could not connect to host ixio.cz: could not connect to host j0ng.xyz: could not connect to host @@ -1007,17 +1029,16 @@ jhburton.co.uk: could not connect to hos jiangzm.com: could not connect to host jiaqiang.vip: could not connect to host jmb.lc: could not connect to host jmk.hu: could not connect to host jobmedic.com: could not connect to host joecod.es: could not connect to host joetyson.io: could not connect to host johngo.tk: could not connect to host -johnkastler.net: could not connect to host johntomasowa.com: could not connect to host jonathansanchez.pro: could not connect to host jonfor.net: could not connect to host jonpads.com: could not connect to host jooto.com: could not connect to host josephsniderman.net: could not connect to host jpod.cc: could not connect to host js88.sg: could not connect to host @@ -1028,39 +1049,38 @@ juliaoantiguidades.com.br: could not con juliawebber.co.za: could not connect to host jumbopan.com: could not connect to host jumbopan.net: could not connect to host just-pools.co.za: could not connect to host justinharrison.ca: could not connect to host justzz.xyz: could not connect to host juventusmania1897.com: could not connect to host k33k00.com: could not connect to host -kabus.org: could not connect to host kaika-facilitymanagement.de: could not connect to host kaloix.de: could not connect to host kamalame.co: could not connect to host kamitech.ch: could not connect to host kandalife.com: could not connect to host kanganer.com: could not connect to host kangzaber.com: could not connect to host kapo.info: could not connect to host karamna.com: could not connect to host karuneshjohri.com: could not connect to host kat.al: could not connect to host -katzen.me: could not connect to host kawaiiku.com: could not connect to host kawaiiku.de: could not connect to host kaydan.io: could not connect to host kearney.io: could not connect to host kela.jp: could not connect to host kellyandantony.com: could not connect to host kelm.me: could not connect to host kermadec.com: could not connect to host keshausconsulting.com: could not connect to host kevinbowers.me: could not connect to host +kevinbusse.de: could not connect to host kevindekoninck.com: could not connect to host kevinfoley.cc: could not connect to host kevinfoley.org: could not connect to host keyihao.cn: could not connect to host keyserver.sexy: could not connect to host kgb.us: could not connect to host kidbacker.com: could not connect to host kieranweightman.me: could not connect to host @@ -1091,16 +1111,17 @@ kotorimusic.ga: could not connect to hos kozmik.co: could not connect to host krampus-fischamend.at: could not connect to host kriegskindernothilfe.de: could not connect to host ktube.yt: could not connect to host kubusadvocaten.nl: could not connect to host kuko-crews.org: could not connect to host kupiec.eu.org: could not connect to host kwikmed.eu: could not connect to host +kyberna.xyz: could not connect to host kyle.place: could not connect to host kylebaldw.in: could not connect to host kylling.io: could not connect to host kyujin-office.net: could not connect to host l18.io: could not connect to host laboutiquemarocaineduconvoyeur.com: could not connect to host laboutiquemarocaineduconvoyeur.ma: could not connect to host lacasa.fr: could not connect to host @@ -1141,16 +1162,17 @@ leveredge.net: could not connect to host lezdomsm.com: could not connect to host lfaz.org: could not connect to host lhalbert.xyz: could not connect to host lheinrich.org: could not connect to host lhsj28.com: could not connect to host lhsj68.com: could not connect to host lhsj78.com: could not connect to host liaozheqi.cn: could not connect to host +liautard.fr: could not connect to host libertas-tech.com: could not connect to host libscode.com: could not connect to host likenosis.com: could not connect to host linkages.org: could not connect to host linksanitizer.com: could not connect to host linksextremist.at: could not connect to host linley.de: could not connect to host linostassi.net: could not connect to host @@ -1210,28 +1232,30 @@ mamastore.eu: could not connect to host marcdorka.de: could not connect to host marcelmarnitz.com: could not connect to host marche-nordic-jorat.ch: could not connect to host mardelcupon.com: could not connect to host mare92.cz: could not connect to host mariusschulte.de: could not connect to host marketingdesignu.cz: could not connect to host marko-fenster24.de: could not connect to host +markrego.com: could not connect to host martins.im: could not connect to host marxist.party: could not connect to host mashandco.it: could not connect to host mastodon.expert: could not connect to host mastodon.my: could not connect to host matarrosabierzo.com: could not connect to host matcha-iga.jp: could not connect to host mathijskingma.nl: could not connect to host matthewtester.com: could not connect to host matthey.nl: could not connect to host mattli.us: could not connect to host mattwb65.com: could not connect to host +matze.co: could not connect to host maybeul.com: could not connect to host maynardnetworks.com: could not connect to host mazternet.ru: could not connect to host mazurlabs.tk: could not connect to host mb-is.info: could not connect to host mbdrogenbos-usedcars.be: could not connect to host mbsec.net: could not connect to host mbwemmel-usedcars.be: could not connect to host @@ -1262,27 +1286,31 @@ mentorithm.com: could not connect to hos menzaijia.com: could not connect to host mercanix.co.uk: could not connect to host mes10doigts.ovh: could not connect to host metrix-money-ptc.com: could not connect to host metrix.design: could not connect to host mexior.nl: could not connect to host meyeraviation.com: could not connect to host mhjuma.com: could not connect to host +michaelcullen.name: could not connect to host michaelkuchta.me: could not connect to host michaelsulzer.com: could not connect to host michaelsulzer.eu: could not connect to host mieterschutzkartei.de: could not connect to host mikeybot.com: could not connect to host min.kiwi: could not connect to host mingy.ddns.net: could not connect to host mingyueli.com: could not connect to host minitruckin.net: could not connect to host +misconfigured.io: could not connect to host mkfs.fr: could not connect to host mkplay.io: could not connect to host +mm13.at: could not connect to host +mmilog.hu: could not connect to host mmstick.tk: could not connect to host mneeb.de: could not connect to host mobile.eti.br: could not connect to host mobmp4.co: could not connect to host modded-minecraft-server-list.com: could not connect to host modernibytovytextil.cz: could not connect to host moderntld.net: could not connect to host moe-max.jp: could not connect to host @@ -1312,17 +1340,16 @@ mrafrohead.com: could not connect to hos mremallin.ca: could not connect to host mrizzio.com: could not connect to host mrjooz.com: could not connect to host mrliu.me: could not connect to host msgallery.tk: could not connect to host msz-fotografie.de: could not connect to host mtirc.co: could not connect to host mtn.cc: could not connect to host -muchohentai.com: could not connect to host muj-svet.cz: could not connect to host multivpn.fr: could not connect to host munduch.cz: could not connect to host murraycolin.org: could not connect to host murz.tv: could not connect to host muslimbanter.co.za: could not connect to host mxawei.cn: could not connect to host mxlife.org: could not connect to host @@ -1335,33 +1362,31 @@ mygreatjob.eu: could not connect to host mygreatjobs.de: could not connect to host mykeepsake.xyz: could not connect to host myndcommunication.com: could not connect to host mytravelblog.de: could not connect to host mzlog.win: could not connect to host n0099.cf: could not connect to host naano.org: could not connect to host naphex.rocks: could not connect to host -narodsovety.ru: could not connect to host nassi.me: could not connect to host nastysclaw.com: could not connect to host natur-udvar.hu: could not connect to host ncdesigns-studio.com: could not connect to host ndtblog.com: could not connect to host necesitodinero.org: could not connect to host neer.io: could not connect to host -nephy.jp: could not connect to host nerfroute.com: could not connect to host nestone.ru: could not connect to host net4visions.at: could not connect to host +netica.fr: could not connect to host netscaler.expert: could not connect to host nevadafiber.net: could not connect to host newcityinfo.info: could not connect to host newfacialbeautycream.com: could not connect to host -nex.sx: could not connect to host nexusbyte.de: could not connect to host nexuscorporation.in: could not connect to host nfluence.org: could not connect to host ngiemboon.net: could not connect to host nico.st: could not connect to host nienfun.com: could not connect to host nikksno.io: could not connect to host nikobradshaw.com: could not connect to host @@ -1389,41 +1414,40 @@ nowremindme.com: could not connect to ho nsbfalconacademy.org: could not connect to host nsdev.cn: could not connect to host nsmail.cn: could not connect to host nudel.ninja: could not connect to host nyanpasu.tv: could not connect to host obdolbacca.ru: could not connect to host oberam.de: could not connect to host oberhof.co: could not connect to host -odifi.com: could not connect to host off-the-clock.us: could not connect to host offgames.pro: could not connect to host office-ruru.com: could not connect to host ohyooo.com: could not connect to host oinky.ddns.net: could not connect to host +okmx.de: could not connect to host oldchaphome.nl: could not connect to host oldtimer-trifft-flugplatz.de: could not connect to host oliverspringer.eu: could not connect to host omnibot.tv: could not connect to host onewebdev.info: could not connect to host onsite4u.de: could not connect to host onstud.com: could not connect to host onwie.fr: could not connect to host ooeste.com: could not connect to host open-desk.org: could not connect to host opinion8td.com: could not connect to host optimist.bg: could not connect to host oscarmashauri.com: could not connect to host oscsdp.cz: could not connect to host +oskuro.net: could not connect to host osmanlitorunu.com: could not connect to host -osterkraenzchen.de: could not connect to host otinane.eu: could not connect to host ourchoice2016.com: could not connect to host -overthinkingit.com: could not connect to host owlscrap.ru: could not connect to host oxynux.xyz: could not connect to host pabloartea.ga: could not connect to host packetcrash.net: could not connect to host paichai.space: could not connect to host paio2-rec.com: could not connect to host paio2.com: could not connect to host panasca.is: could not connect to host @@ -1434,16 +1458,17 @@ panascais.eu: could not connect to host panascais.host: could not connect to host panascais.io: could not connect to host panascais.me: could not connect to host panascais.pw: could not connect to host panascais.site: could not connect to host panascais.tech: could not connect to host panascais.us: could not connect to host pandapsy.com: could not connect to host +paradisenazarene.com: could not connect to host pardnoy.com: could not connect to host pascalmathis.com: could not connect to host pascalmathis.me: could not connect to host pascalmathis.net: could not connect to host passrhce.com: could not connect to host passrhcsa.com: could not connect to host pastie.se: could not connect to host patrickbusch.net: could not connect to host @@ -1454,18 +1479,20 @@ paulshir.is: could not connect to host payload.tech: could not connect to host paymon.tj: could not connect to host paypod.org: could not connect to host pbytes.com: could not connect to host pcvirusclear.com: could not connect to host pear2pear.de: could not connect to host peerless.ae: could not connect to host peirong.me: could not connect to host +penfold.fr: could not connect to host pengisatelier.net: could not connect to host pepper.dog: could not connect to host +perrone.co: could not connect to host persjrp.ca: could not connect to host persoform.ch: could not connect to host petlife.od.ua: could not connect to host peuf.shop: could not connect to host peykezamin.ir: could not connect to host pgmsource.com: could not connect to host phdwuda.com: could not connect to host phelx.de: could not connect to host @@ -1481,16 +1508,17 @@ pianetaottica.info: could not connect to picallo.es: could not connect to host picone.com.au: could not connect to host picsandtours.com: could not connect to host pierrejeansuau.fr: could not connect to host pieterhordijk.com: could not connect to host pimspage.nl: could not connect to host pinebaylibrary.org: could not connect to host pinkhq.com: could not connect to host +pinoyonlinetv.com: could not connect to host pitot-rs.org: could not connect to host pixelgliders.de: could not connect to host plaasprodukte.com: could not connect to host planbox.info: could not connect to host playsharp.com: could not connect to host please-deny.me: could not connect to host plussizereviews.com: could not connect to host pmbremer.de: could not connect to host @@ -1521,16 +1549,17 @@ ppoozl.com: could not connect to host prettytunesapp.com: could not connect to host princessbackpack.de: could not connect to host printsos.com: could not connect to host prism-communication.com: could not connect to host privacymanatee.com: could not connect to host privcloud.org: could not connect to host privilegevisa.fr: could not connect to host proactive.run: could not connect to host +procinorte.net: could not connect to host profinetz.de: could not connect to host progressivecfo.co.nz: could not connect to host projectasterk.com: could not connect to host projectte.ch: could not connect to host projectx.top: could not connect to host projekt-umbriel.de: could not connect to host prokop.ovh: could not connect to host promhadan.com: could not connect to host @@ -1543,38 +1572,38 @@ prpsss.com: could not connect to host pruikshop.nl: could not connect to host prytkov.com: could not connect to host psncardplus.be: could not connect to host psncardplus.com: could not connect to host psncardplus.dk: could not connect to host psncardplus.nl: could not connect to host psncardplus.se: could not connect to host psychoco.net: could not connect to host -psylab.re: could not connect to host publimepa.it: could not connect to host pugilares.com.pl: could not connect to host puhe.se: could not connect to host -putney.io: could not connect to host pwdgen.net: could not connect to host pypa.io: could not connect to host pythia.nz: could not connect to host qbin.io: could not connect to host qforum.org: could not connect to host qikan.net: could not connect to host qirinus.com: could not connect to host qldformulaford.org: could not connect to host qnatek.org: could not connect to host qoqo.us: could not connect to host qqvips.com: could not connect to host qrlfinancial.com: could not connect to host qto.net: could not connect to host r-cut.fr: could not connect to host rackblue.com: could not connect to host +raidensnakesden.co.uk: could not connect to host +raidensnakesden.com: could not connect to host +raidensnakesden.net: could not connect to host rainbin.com: could not connect to host -ramatola.uk: could not connect to host ranos.org: could not connect to host ravengergaming.net: could not connect to host ravse.dk: could not connect to host raycarruthersphotography.co.uk: could not connect to host rb-china.net: could not connect to host rbxcatalog.com: could not connect to host rcoliveira.com: could not connect to host rdfz.tech: could not connect to host @@ -1583,16 +1612,19 @@ reaiaer.com: could not connect to host real-compare.com: could not connect to host realcli.com: could not connect to host reality0ne.com: could not connect to host realloc.me: could not connect to host realnewhomes.com: could not connect to host realraghavgupta.com: could not connect to host realwoo.com: could not connect to host reath.me: could not connect to host +reeson.at: could not connect to host +reeson.info: could not connect to host +reeson.org: could not connect to host reevu.net: could not connect to host reflecton.io: could not connect to host regendevices.eu: could not connect to host regio-salland.nl: could not connect to host reignsphere.net: could not connect to host reismil.ch: could not connect to host renemayrhofer.com: could not connect to host rentbrowser.com: could not connect to host @@ -1606,16 +1638,17 @@ reth.ch: could not connect to host retube.ga: could not connect to host reykjavik.guide: could not connect to host ribopierre.fr: could not connect to host riceglue.com: could not connect to host richardb.me: could not connect to host richeza.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 115" data: no] ris.fi: could not connect to host riversideauto.net: could not connect to host +riverweb.gr: could not connect to host robertocasares.no-ip.biz: could not connect to host robi-net.it: could not connect to host robomonkey.org: could not connect to host robust.ga: could not connect to host rodehutskors.net: could not connect to host rofrank.space: could not connect to host rolandszabo.com: could not connect to host romanticschemermovie.com: could not connect to host @@ -1624,61 +1657,62 @@ ronghexx.com: could not connect to host roolevoi.ru: could not connect to host rootbsd.at: could not connect to host rospa100.com: could not connect to host rotterdamjazz.info: could not connect to host royzez.com: could not connect to host rozalynne-dawn.ga: could not connect to host rpasafrica.com: could not connect to host rs-devdemo.host: could not connect to host +rsauget.fr: could not connect to host rsldb.com: could not connect to host rtc.fun: could not connect to host rubbix.net: could not connect to host rubendv.be: could not connect to host ruhr3.de: could not connect to host runcarina.com: could not connect to host rundumcolumn.xyz: could not connect to host runementors.com: could not connect to host -ruri.io: could not connect to host ruurdboomsma.nl: could not connect to host rzegroup.com: could not connect to host s0923.com: could not connect to host s3n.se: could not connect to host sabine-forschbach.de: could not connect to host sabineforschbach.de: could not connect to host safedevice.net: could not connect to host safejourney.education: could not connect to host saferedirectlink.com: could not connect to host sallysubs.com: could not connect to host salzamt.tk: could not connect to host samaritan.tech: could not connect to host samsonova.de: could not connect to host sanael.net: could not connect to host sanatrans.com: could not connect to host +santojuken.co.jp: could not connect to host sarahlicity.me.uk: could not connect to host sarindia.com: could not connect to host sarindia.de: could not connect to host sarndipity.com: could not connect to host sash.pw: could not connect to host savethedogfishfoundation.org: could not connect to host savingbytes.com: could not connect to host sbm.cloud: could not connect to host schaafenstrasse.koeln: could not connect to host schmidttulskie.de: could not connect to host schnapke.name: could not connect to host schwarzegar.de: could not connect to host -schwarzwaldcon.de: could not connect to host sciencemonster.co.uk: could not connect to host scintillating.stream: could not connect to host scitopia.me: could not connect to host scm-2017.org: could not connect to host scottainslie.me.uk: could not connect to host scripthost.org: could not connect to host scriptjunkie.us: could not connect to host sctm.at: could not connect to host +seankilgarriff.com: could not connect to host sebastian-lutsch.de: could not connect to host secitem.de: could not connect to host sectest.ml: could not connect to host secure-automotive-cloud.com: could not connect to host secure-automotive-cloud.org: could not connect to host secureindia.co: could not connect to host security.xn--q9jyb4c: could not connect to host securitymap.wiki: could not connect to host @@ -1691,16 +1725,17 @@ seleondar.ru: could not connect to host selfserverx.com: could not connect to host sellmoretires.com: could not connect to host seoscribe.net: could not connect to host serverlauget.no: could not connect to host servfefe.com: could not connect to host seryovpn.com: could not connect to host sesha.co.za: could not connect to host sessionslogning.dk: could not connect to host +sevsey.ru: could not connect to host shadiku.com: could not connect to host shadowplus.net: could not connect to host shadowrocket.net: could not connect to host shang-yu.cn: could not connect to host shanxiapark.com: could not connect to host shavingks.com: could not connect to host sheying.tm: could not connect to host shinko-osaka.jp: could not connect to host @@ -1710,51 +1745,54 @@ shredoptics.ch: could not connect to hos shurita.org: could not connect to host shuzicai.cn: could not connect to host shymeck.pw: could not connect to host siamega.com: could not connect to host siebens.net: could not connect to host signosquecombinam.com.br: could not connect to host sijmenschoon.nl: could not connect to host sikatehtaat.fi: could not connect to host +sikko.biz: could not connect to host siku.pro: could not connect to host silqueskineyeserum.com: could not connect to host silvistefi.com: could not connect to host sim4seed.org: could not connect to host simhaf.cf: could not connect to host simplerses.com: could not connect to host sims4hub.ga: could not connect to host sinfulforums.net: could not connect to host siqi.wang: could not connect to host +sistem-maklumat.com: could not connect to host sistersurprise.de: could not connect to host sitemaxiphilippe.ch: could not connect to host skarox.ru: could not connect to host sky-aroma.com: could not connect to host skylocker.net: could not connect to host skylocker.nl: could not connect to host skyvault.io: could not connect to host slaps.be: could not connect to host slytech.ch: could not connect to host -sm-supplements.gr: could not connect to host smallchat.nl: could not connect to host smartbiz.vn: could not connect to host smith.is: could not connect to host sml.lc: could not connect to host smuhelper.cn: could not connect to host sniderman.pro: could not connect to host sniderman.us: could not connect to host snowdy.eu: could not connect to host soboleva-pr.com.ua: could not connect to host +soc.net: could not connect to host socialworkout.com: could not connect to host socialworkout.net: could not connect to host socialworkout.org: could not connect to host socialworkout.tv: could not connect to host socketize.com: could not connect to host sogravatas.net.br: could not connect to host sojingle.net: could not connect to host +solariiknight.org: could not connect to host soldout-app.com: could not connect to host solymar.co: could not connect to host sonafe.info: could not connect to host sonja-kowa.de: could not connect to host soontm.de: could not connect to host sorenam.com: could not connect to host sortaweird.net: could not connect to host sowingseasons.com: could not connect to host @@ -1833,38 +1871,37 @@ tapestries.tk: could not connect to host tarek.link: could not connect to host tazemama.biz: could not connect to host tcpweb.net: could not connect to host tdelmas.eu: could not connect to host tdelmas.ovh: could not connect to host tdsb.cf: could not connect to host tdsbhack.tk: could not connect to host teacherph.net: could not connect to host -teamdaylo.xyz: could not connect to host tebieer.com: could not connect to host techask.it: could not connect to host techiehall.com: could not connect to host techpit.us: could not connect to host techshift.se: could not connect to host tektoria.de: could not connect to host telekollektiv.org: could not connect to host +tenberg.com: could not connect to host tenispopular.com: could not connect to host -teodio.cl: could not connect to host terra-x.net: could not connect to host terrax.net: could not connect to host testadron.com: could not connect to host testovaci.ml: could not connect to host tgod.co: could not connect to host thaigirls.xyz: could not connect to host the-digitale.com: could not connect to host the-finance-blog.com: could not connect to host the-gist.io: could not connect to host the-pcca.org: could not connect to host thebte.com: could not connect to host -thecozycastle.com: could not connect to host +thecuriouscat.net: could not connect to host thedailyupvote.com: could not connect to host thedarkartsandcrafts.com: could not connect to host theeducationchannel.info: could not connect to host theeducationdirectory.org: could not connect to host thefox.co: could not connect to host thefrk.xyz: could not connect to host thelostyankee.com: could not connect to host thenrdhrd.nl: could not connect to host @@ -1873,16 +1910,17 @@ theprincegame.com: could not connect to theprivacysolution.com: could not connect to host thequillmagazine.org: could not connect to host thermique.ch: could not connect to host thesehighsandlows.com: could not connect to host theserver201.tk: could not connect to host thetapirsmouth.com: could not connect to host thevoid.one: could not connect to host thinkcash.nl: could not connect to host +thismumdoesntknowbest.com: could not connect to host thompsonfamily.cloud: could not connect to host threatcentral.io: could not connect to host thxandbye.de: could not connect to host thynx.io: could not connect to host tianxicaipiao.com: could not connect to host tianxicaipiao.win: could not connect to host tianxicp.com: could not connect to host tibovanheule.site: could not connect to host @@ -1927,17 +1965,16 @@ tucidi.net: could not connect to host tupizm.com: could not connect to host turismo.cl: could not connect to host turkiet.guide: could not connect to host turn-sticks.com: could not connect to host tutiendaroja.com: could not connect to host tutiendarosa.com: could not connect to host tutoragency.org: could not connect to host tuvangoicuoc.com: could not connect to host -tuxflow.de: could not connect to host tuxhound.org: could not connect to host twinkieman.com: could not connect to host twiri.net: could not connect to host twittelzie.nl: could not connect to host twitter.ax: could not connect to host twotube.ie: could not connect to host tykoon.com: could not connect to host tylerharcourt.com: could not connect to host @@ -1953,16 +1990,17 @@ ulalau.com: could not connect to host ulti.gq: could not connect to host unefuite.ch: could not connect to host unhu.fr: could not connect to host uni2share.com: could not connect to host unicorn.li: could not connect to host uniformespousoalegre.com.br: could not connect to host uploadbro.com: could not connect to host upmchealthsecurity.us: could not connect to host +urbanwildlifealliance.org: could not connect to host urcentral.org: could not connect to host usafuelservice.com: could not connect to host uscp8.com: could not connect to host usportsgo.com: could not connect to host uwesander.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 115" data: no] uwimonacs.org.jm: could not connect to host uygindir.ml: could not connect to host vaaddress.co: could not connect to host @@ -1971,25 +2009,26 @@ vadik.me: could not connect to host valecnatechnika.cz: could not connect to host valenhub.com: could not connect to host valenhub.es: could not connect to host valis.sx: could not connect to host vamosfalardesaude.pt: could not connect to host vanderstraeten.dynv6.net: could not connect to host varela-electricite.fr: could not connect to host varta.io: could not connect to host +vasyharan.com: could not connect to host vayaport.com: could not connect to host vconcept.ch: could not connect to host vconcept.me: could not connect to host +vectro.me: could not connect to host velen.io: could not connect to host venicecomputerrepair.com: could not connect to host venicefloridawebsitedesign.com: could not connect to host venturavwparts.com: could not connect to host verdeandco.co.uk: could not connect to host -vernonfigureskatingclub.com: could not connect to host versfin.net: could not connect to host veryyounglesbians.com: could not connect to host vgatest.nl: could not connect to host vicenage.com: could not connect to host viciousviscosity.xyz: could not connect to host videorullen.se: could not connect to host vidiproject.com: could not connect to host vikasbabyworld.de: could not connect to host @@ -2072,17 +2111,16 @@ wilhelm-nathan.de: could not connect to willkommen-fuerstenberg.de: could not connect to host winnersports.co: could not connect to host winsufi.biz: could not connect to host wisak.eu: could not connect to host wishesbee.com: could not connect to host wissl.org: could not connect to host wizznab.tk: could not connect to host wk577.com: could not connect to host -wlog.it: could not connect to host wmawri.com: could not connect to host wolfemg.com: could not connect to host wollongongbaptist.hopto.org: could not connect to host wonderbooks.club: could not connect to host woomu.me: could not connect to host wordsofamaster.com: could not connect to host workemy.com: could not connect to host worldfree4.org: could not connect to host @@ -2115,21 +2153,19 @@ xn--yj8h0m.ws: could not connect to host xn--ykrp42k.com: could not connect to host xpwn.cz: could not connect to host xtom.io: could not connect to host xuntaosms.com: could not connect to host xwaretech.info: could not connect to host xyfun.net: could not connect to host y3451.com: could not connect to host yabrt.cn: could not connect to host -yagihiro.tech: could not connect to host yahoo.ax: could not connect to host yarchives.jp: could not connect to host yaucy.win: could not connect to host -ybresson.com: could not connect to host yd.io: could not connect to host yellowcar.website: could not connect to host yemalu.com: could not connect to host yemekbaz.az: could not connect to host yepbitcoin.com: could not connect to host yesfone.com.br: could not connect to host yggdar.ga: could not connect to host yhori.xyz: could not connect to host @@ -2151,17 +2187,16 @@ yum.beer: could not connect to host yurimoens.be: could not connect to host yux.fr: could not connect to host yveshield.com: could not connect to host z0rro.net: could not connect to host zachbolinger.com: could not connect to host zaoext.com: could not connect to host zbchen.com: could not connect to host zeitzer-turngala.de: could not connect to host -zemlova.cz: could not connect to host zenghx.tk: could not connect to host zero-x-baadf00d.com: could not connect to host zerosource.net: could not connect to host zertif.info: could not connect to host zeug.co: could not connect to host zhangfangzhou.com: could not connect to host zhangsir.net: could not connect to host zhaochen.xyz: could not connect to host @@ -2228,17 +2263,17 @@ 12vpnchina.com: could not connect to hos 1391kj.com: did not receive HSTS header 1396.cc: did not receive HSTS header 1536.cf: could not connect to host 163pwd.com: could not connect to host 16deza.com: did not receive HSTS header 16packets.com: could not connect to host 173vpn.cn: could not connect to host 173vpns.com: did not receive HSTS header -173vpnv.com: did not receive HSTS header +173vpnv.com: could not connect to host 188betwarriors.co.uk: could not connect to host 188trafalgar.ca: did not receive HSTS header 195gm.com: could not connect to host 1a-jva.de: could not connect to host 1atic.com: could not connect to host 1co-jp.net: did not receive HSTS header 1cover.com: could not connect to host 1k8b.com: could not connect to host @@ -2472,17 +2507,16 @@ aether.pw: could not connect to host aevpn.net: could not connect to host aeyoun.com: did not receive HSTS header af-fotografie.net: did not receive HSTS header afdkompakt.de: max-age too low: 86400 aficotroceni.ro: did not receive HSTS header afiru.net: could not connect to host afmchandler.com: did not receive HSTS header afp548.tk: could not connect to host -africantourer.com: did not receive HSTS header after.im: did not receive HSTS header afvallendoeje.nu: could not connect to host afyou.co.kr: could not connect to host agalaxyfarfaraway.co.uk: could not connect to host agatheetraphael.fr: could not connect to host agbremen.de: did not receive HSTS header agentseeker.ca: could not connect to host agevio.com: could not connect to host @@ -2730,20 +2764,20 @@ aquariumaccessories.shop: did not receiv aquilalab.com: could not connect to host arabdigitalexpression.org: did not receive HSTS header aradulconteaza.ro: could not connect to host aran.me.uk: could not connect to host arboineuropa.nl: did not receive HSTS header arboleda-hurtado.com: could not connect to host arbu.eu: max-age too low: 2419200 arcbit.io: did not receive HSTS header -archii.ca: did not receive HSTS header +archii.ca: could not connect to host architecte-interieur.be: did not receive HSTS header arcusnova.de: could not connect to host -ardao.me: did not receive HSTS header +ardao.me: could not connect to host ardorlabs.se: could not connect to host arewedubstepyet.com: did not receive HSTS header areyouever.me: did not receive HSTS header argennon.xyz: could not connect to host arguggi.co.uk: could not connect to host ariacreations.net: did not receive HSTS header arislight.com: could not connect to host arlatools.com: did not receive HSTS header @@ -2798,17 +2832,17 @@ ass.org.au: could not connect to host assekuranzjobs.de: could not connect to host asset-alive.com: did not receive HSTS header asset-alive.net: did not receive HSTS header assurancesmons.be: did not receive HSTS header astraalivankila.net: did not receive HSTS header astral.gq: did not receive HSTS header astrolpost.com: could not connect to host astromelody.com: did not receive HSTS header -asuhe.cc: did not receive HSTS header +asuhe.cc: could not connect to host atacadodesandalias.com.br: did not receive HSTS header atavio.at: could not connect to host atavio.ch: could not connect to host atavio.de: did not receive HSTS header atbeckett.com: did not receive HSTS header atelier-rk.com: did not receive HSTS header ateliersantgervasi.com: did not receive HSTS header atencionbimbo.com: max-age too low: 86400 @@ -2875,21 +2909,21 @@ avantmfg.com: did not receive HSTS heade avastantivirus.ro: did not receive HSTS header avec-ou-sans-ordonnance.fr: could not connect to host aveling-adventure.co.uk: did not receive HSTS header avepol.cz: did not receive HSTS header avepol.eu: did not receive HSTS header aviacao.pt: did not receive HSTS header avidcruiser.com: did not receive HSTS header aviodeals.com: could not connect to host -avmo.pw: did not receive HSTS header +avmo.pw: could not connect to host avqueen.cn: could not connect to host -avso.pw: did not receive HSTS header +avso.pw: could not connect to host avus-automobile.com: did not receive HSTS header -avxo.pw: did not receive HSTS header +avxo.pw: could not connect to host awanderlustadventure.com: did not receive HSTS header awg-mode.de: did not receive HSTS header aww.moe: did not receive HSTS header axado.com.br: did not receive HSTS header axelchv.fr: did not receive HSTS header axeny.com: did not receive HSTS header axolsoft.com: max-age too low: 10540800 ayahuascaadvisor.com: could not connect to host @@ -2949,17 +2983,17 @@ banbanchs.com: could not connect to host banchethai.com: could not connect to host bandb.xyz: could not connect to host bandrcrafts.com: did not receive HSTS header bangzafran.com: did not receive HSTS header bankmilhas.com.br: did not receive HSTS header banksaround.com: did not receive HSTS header banqingdiao.com: could not connect to host baobaobooks.net: did not receive HSTS header -baobeiglass.com: could not connect to host +baobeiglass.com: did not receive HSTS header barcel.com.mx: max-age too low: 86400 barely.sexy: did not receive HSTS header barrelhead.org: could not connect to host barrut.me: did not receive HSTS header barshout.co.uk: could not connect to host bartbania.com: did not receive HSTS header barunisystems.com: could not connect to host bashcode.ninja: could not connect to host @@ -2967,16 +3001,17 @@ basicsolutionsus.com: did not receive HS basilisk.io: could not connect to host basketsbymaurice.com: did not receive HSTS header baskettemple.com: did not receive HSTS header bassh.net: did not receive HSTS header baud.ninja: could not connect to host baudairenergyservices.com: did not receive HSTS header baum.ga: could not connect to host baumstark.ca: could not connect to host +bayinstruments.com: did not receive HSTS header baysse.eu: could not connect to host bazarstupava.sk: could not connect to host bazisszoftver.hu: did not receive HSTS header bb-shiokaze.jp: did not receive HSTS header bblovess.cn: could not connect to host bbrinck.eu: could not connect to host bbuio.com: max-age too low: 86400 bbwdom.xyz: could not connect to host @@ -2993,16 +3028,17 @@ bcnx.de: max-age too low: 0 bcsytv.com: could not connect to host bcweightlifting.ca: could not connect to host bddemir.com: could not connect to host bde-epitech.fr: could not connect to host be-real.life: did not receive HSTS header beach-inspector.com: did not receive HSTS header beachi.es: could not connect to host beaglewatch.com: could not connect to host +beanworks.ca: did not receive HSTS header bearden.io: did not receive HSTS header beardydave.com: did not receive HSTS header beastlog.tk: could not connect to host beastowner.com: did not receive HSTS header beavers.io: could not connect to host bebeefy.uk: could not connect to host bebesurdoue.com: could not connect to host bedabox.com: max-age too low: 0 @@ -3053,17 +3089,16 @@ bestcellular.com: did not receive HSTS h besthost.cz: did not receive HSTS header bestmodels.su: did not receive HSTS header bestof1001.de: could not connect to host bestorangeseo.com: could not connect to host betaclean.fr: did not receive HSTS header betafive.net: could not connect to host betakah.net: could not connect to host betcafearena.ro: did not receive HSTS header -bethanyduke.com: did not receive HSTS header bethditto.com: did not receive HSTS header betnet.fr: could not connect to host betplanning.it: did not receive HSTS header bets.de: did not receive HSTS header bets.gg: did not receive HSTS header betterlifemakers.com: max-age too low: 200 bettween.com: did not receive HSTS header betz.ro: did not receive HSTS header @@ -3124,16 +3159,17 @@ biophysik-ssl.de: did not receive HSTS h birgitandmerlin.com: did not receive HSTS header birkman.com: did not receive HSTS header bismarck.moe: did not receive HSTS header bisterfeldt.com: could not connect to host bitbit.org: did not receive HSTS header bitbr.net: did not receive HSTS header bitcantor.com: did not receive HSTS header bitchan.it: could not connect to host +bitcoinhk.org: did not receive HSTS header bitcoinprivacy.net: did not receive HSTS header bitcoinworld.me: did not receive HSTS header bitconcepts.co.uk: could not connect to host biteoftech.com: did not receive HSTS header bitf.ly: could not connect to host bitfactory.ws: could not connect to host bitfarm-archiv.com: did not receive HSTS header bitfarm-archiv.de: did not receive HSTS header @@ -3178,16 +3214,17 @@ blocksatz-medien.de: could not connect t blog-ritaline.com: could not connect to host blog.coffee: could not connect to host blog.cyveillance.com: did not receive HSTS header blog.torproject.org: max-age too low: 1000 bloglife-bb.com: did not receive HSTS header bloglikepro.com: could not connect to host blognone.com: did not receive HSTS header blogonblogspot.com: did not receive HSTS header +blok56.nl: did not receive HSTS header bloomnbud.com: did not receive HSTS header bloomzoomy.ru: max-age too low: 172800 blowjs.com: could not connect to host bls-fiduciaire.be: did not receive HSTS header bltc.co: could not connect to host blubbablasen.de: could not connect to host blucas.org: did not receive HSTS header blue17.co.uk: did not receive HSTS header @@ -3241,17 +3278,17 @@ borscheid-wenig.com: did not receive HST boschee.net: could not connect to host botox.bz: did not receive HSTS header botstack.host: did not receive HSTS header bounceboxspc.com: did not receive HSTS header bouncecoffee.com: did not receive HSTS header bouncelanduk.co.uk: did not receive HSTS header bouncycastleandparty.co.uk: did not receive HSTS header bourhis.info: did not receive HSTS header -bouwbedrijfpurmerend.nl: could not connect to host +bouwbedrijfpurmerend.nl: did not receive HSTS header bowlroll.net: max-age too low: 0 boxcryptor.com: did not receive HSTS header boxing-austria.eu: did not receive HSTS header boxlitepackaging.com: did not receive HSTS header boyan.in: could not connect to host boyfriendhusband.men: did not receive HSTS header bp-wahl.at: did not receive HSTS header bqtoolbox.com: could not connect to host @@ -3298,25 +3335,24 @@ brunohenc.from.hr: could not connect to brunoonline.co.uk: could not connect to host bryn.xyz: could not connect to host bs12v.ru: did not receive HSTS header bsdtips.com: could not connect to host bsklabels.com: did not receive HSTS header btc-e.com: did not receive HSTS header btcdlc.com: could not connect to host btcpot.ltd: did not receive HSTS header -btio.pw: did not receive HSTS header +btio.pw: could not connect to host btxiaobai.com: did not receive HSTS header buben.tech: did not receive HSTS header bubulazi.com: did not receive HSTS header bubulazy.com: did not receive HSTS header buch-cuber.de: max-age too low: 0 buchheld.at: did not receive HSTS header bucket.tk: could not connect to host -buderus-family.be: did not receive HSTS header budgetthostels.nl: did not receive HSTS header budskap.eu: did not receive HSTS header buenosairesestetica.com.ar: could not connect to host bugtrack.io: could not connect to host bugwie.com: did not receive HSTS header buhler.pro: did not receive HSTS header buildci.asia: could not connect to host buildify.co.za: could not connect to host @@ -3501,17 +3537,16 @@ ccretreatandfarm.com: did not receive HS cctech.ph: did not receive HSTS header cd0.us: could not connect to host cdnb.co: could not connect to host cdndepo.com: could not connect to host cdreporting.co.uk: did not receive HSTS header cdt.org: did not receive HSTS header ce-agentur.de: did not receive HSTS header cecilwalker.com.au: did not receive HSTS header -celebphotos.blog: did not receive HSTS header celeirorural.com.br: did not receive HSTS header celina-reads.de: did not receive HSTS header cellsites.nz: could not connect to host centennialrewards.com: did not receive HSTS header centralpoint.be: did not receive HSTS header centralpoint.nl: did not receive HSTS header centralvacsunlimited.net: did not receive HSTS header centralync.com: could not connect to host @@ -3800,17 +3835,16 @@ contactbig.com: did not receive HSTS hea contaimo.com: did not receive HSTS header container-lion.com: did not receive HSTS header containerstatistics.com: could not connect to host contarkos.xyz: could not connect to host content-design.de: did not receive HSTS header continuumgaming.com: could not connect to host contraspin.co.nz: did not receive HSTS header controlcenter.gigahost.dk: did not receive HSTS header -controleer-maar-een-ander.nl: did not receive HSTS header convert.zone: did not receive HSTS header cooink.net: could not connect to host coolaj86.com: did not receive HSTS header coolbutbroken.com: did not receive HSTS header coolchevy.org.ua: did not receive HSTS header coole-meister.de: could not connect to host cooxa.com: did not receive HSTS header copshop.com.br: could not connect to host @@ -3943,17 +3977,17 @@ cuongthach.com: did not receive HSTS hea curlyroots.com: did not receive HSTS header curroapp.com: could not connect to host curveweb.co.uk: did not receive HSTS header cusfit.com: did not receive HSTS header custe.rs: could not connect to host customadesign.com: did not receive HSTS header cutorrent.com: could not connect to host cuvva.insure: did not receive HSTS header -cvjm-memmingen.de: could not connect to host +cvjm-memmingen.de: did not receive HSTS header cvtparking.co.uk: did not receive HSTS header cwage.com: could not connect to host cyanogenmod.xxx: could not connect to host cyber-konzept.de: did not receive HSTS header cybercecurity.com: did not receive HSTS header cyberfrancais.ro: did not receive HSTS header cyberlab.kiev.ua: did not receive HSTS header cyberlab.team: did not receive HSTS header @@ -4100,27 +4134,26 @@ dekasan.ru: could not connect to host delayrefunds.co.uk: could not connect to host deliverance.co.uk: could not connect to host deltaconcepts.de: did not receive HSTS header delvj.org: could not connect to host demdis.org: could not connect to host demilitarized.ninja: could not connect to host demo-server.us: could not connect to host demo.swedbank.se: did not receive HSTS header -demomanca.com: could not connect to host +demomanca.com: did not receive HSTS header demotops.com: could not connect to host dempsters.ca: max-age too low: 86400 denh.am: did not receive HSTS header denisjean.fr: could not connect to host dentaldomain.org: did not receive HSTS header dentaldomain.ph: did not receive HSTS header denvercybersecurity.com: did not receive HSTS header denverprophit.us: did not receive HSTS header deped.blog: did not receive HSTS header -depedtayo.com: did not receive HSTS header depijl-mz.nl: did not receive HSTS header depixion.agency: could not connect to host depo.space: could not connect to host dequehablamos.es: could not connect to host derbyshiredotnet.co.uk: did not receive HSTS header derevtsov.com: did not receive HSTS header derpumpkinfuhrer.com: could not connect to host derrickemery.com: did not receive HSTS header @@ -4219,16 +4252,17 @@ diva-ey.com: could not connect to host diversity-spielzeug.de: did not receive HSTS header divvymonkey.com: did not receive HSTS header divvyradio.com: did not receive HSTS header dixiediner.com: did not receive HSTS header diyvideoeditor.com: did not receive HSTS header dizihocasi.com: could not connect to host dizorg.net: could not connect to host dj4et.de: could not connect to host +djangogolf.com: did not receive HSTS header djieno.com: did not receive HSTS header djxmmx.net: did not receive HSTS header djz4music.com: did not receive HSTS header dkniss.de: could not connect to host dlc.viasinc.com: could not connect to host dlemper.de: did not receive HSTS header dmcibulldog.com: did not receive HSTS header dmix.ca: could not connect to host @@ -4368,16 +4402,17 @@ dudesunderwear.com.br: could not connect duelysthub.com: could not connect to host dukec.me: did not receive HSTS header dullsir.com: did not receive HSTS header dune.io: did not receive HSTS header dunea.nl: did not receive HSTS header duole30.com: did not receive HSTS header duongpho.com: did not receive HSTS header duskopy.top: could not connect to host +dutchessuganda.com: did not receive HSTS header dutchrank.com: did not receive HSTS header duuu.ch: could not connect to host duyao.de: max-age too low: 86400 dv189.com: did not receive HSTS header dycem-ns.com: did not receive HSTS header dycontrol.de: could not connect to host dylanscott.com.au: did not receive HSTS header dymersion.com: did not receive HSTS header @@ -4473,24 +4508,26 @@ eengezinswoningverkopen.nl: could not co eenhoorn.ga: could not connect to host eesistumine2017.ee: could not connect to host efficienthealth.com: did not receive HSTS header effortlesshr.com: did not receive HSTS header eftcorp.biz: did not receive HSTS header egge.com: max-age too low: 0 egit.co: could not connect to host ego-world.org: could not connect to host +egupova.ru: did not receive HSTS header ehealthcounselor.com: could not connect to host ehipaadev.com: could not connect to host ehito.ovh: could not connect to host ehrenamt-skpfcw.de: could not connect to host eicfood.com: could not connect to host eidolonhost.com: did not receive HSTS header eifelindex.de: did not receive HSTS header eigo.work: could not connect to host +eimanavicius.lt: did not receive HSTS header einhorn.space: could not connect to host ekbanden.nl: could not connect to host eksik.com: did not receive HSTS header el-soul.com: did not receive HSTS header elaintehtaat.fi: could not connect to host elan-organics.com: did not receive HSTS header elanguest.pl: could not connect to host elanguest.ro: could not connect to host @@ -4672,16 +4709,17 @@ euph.eu: did not receive HSTS header eupho.me: could not connect to host eupresidency2018.com: did not receive HSTS header euren.se: could not connect to host eurocamping.se: could not connect to host euroshop24.net: could not connect to host eurospecautowerks.com: did not receive HSTS header evafojtova.cz: did not receive HSTS header evanhandgraaf.nl: did not receive HSTS header +evantage.org: did not receive HSTS header evdenevenakliyatankara.pw: could not connect to host evecalm.com: did not receive HSTS header events12.com: did not receive HSTS header eventsafrica.net: did not receive HSTS header everybooks.com: could not connect to host everydaytherich.com: max-age too low: 7776000 everygayporn.xyz: did not receive HSTS header everylab.org: could not connect to host @@ -4916,17 +4954,16 @@ flow.pe: could not connect to host flowersandclouds.com: could not connect to host floweslawncare.com: did not receive HSTS header flowlo.me: could not connect to host fluidojobs.com: could not connect to host flukethoughts.com: did not receive HSTS header flurrybridge.com: did not receive HSTS header flushstudios.com: did not receive HSTS header flyaces.com: could not connect to host -flyspace.ga: did not receive HSTS header fm83.nl: could not connect to host fm992.com: did not receive HSTS header fnvsecurity.com: could not connect to host fobc-usa.org: did not receive HSTS header foerster-kunststoff.de: did not receive HSTS header fojtova.cz: did not receive HSTS header fojtovi.cz: did not receive HSTS header fokan.ch: did not receive HSTS header @@ -4985,16 +5022,17 @@ franta.email: did not receive HSTS heade franzt.de: could not connect to host frasesdeamizade.pt: could not connect to host frasys.io: did not receive HSTS header fraudempire.com: could not connect to host freeasinlliure.org: did not receive HSTS header freeflow.tv: could not connect to host freekdevries.nl: did not receive HSTS header freelanced.co.za: could not connect to host +freelandinnovation.com: did not receive HSTS header freelo.cz: did not receive HSTS header freematthale.net: did not receive HSTS header freesoftwaredriver.com: could not connect to host freethought.org.au: could not connect to host freeutopia.org: did not receive HSTS header freqlabs.com: did not receive HSTS header freshfind.xyz: could not connect to host freshlymind.com: did not receive HSTS header @@ -5039,32 +5077,35 @@ funnyang.com: could not connect to host funrun.com: did not receive HSTS header funtastic-event-hire.co.uk: did not receive HSTS header fuorifuocogenova.it: did not receive HSTS header furiffic.com: did not receive HSTS header furnation.com: could not connect to host furry.be: did not receive HSTS header fusedrops.com: could not connect to host fusionmate.com: could not connect to host -futbol11.com: could not connect to host +futbol11.com: did not receive HSTS header +futbolvivo.tv: did not receive HSTS header futurefundapp.com: did not receive HSTS header futurestarsusa.org: did not receive HSTS header futuretechnologi.es: could not connect to host futureyouhealth.com: did not receive HSTS header +futuristarchitecture.com: did not receive HSTS header fuvpn.com: could not connect to host fws.gov: did not receive HSTS header fx-rk.com: did not receive HSTS header fyfywka.com: max-age too low: 86400 fyodorpi.com: did not receive HSTS header fysiohaenraets.nl: did not receive HSTS header fzn.io: did not receive HSTS header fzslm.me: could not connect to host g-i-s.vn: did not receive HSTS header g-marketing.ro: did not receive HSTS header g-rickroll-o.pw: could not connect to host +g-rom.net: did not receive HSTS header g2a.co: did not receive HSTS header g2g.com: did not receive HSTS header g5led.nl: could not connect to host g77.ca: could not connect to host gaanbaksho.com.au: did not receive HSTS header gabber.scot: could not connect to host gabi.com.es: could not connect to host gabi.soy: did not receive HSTS header @@ -5140,17 +5181,16 @@ genesischangelog.com: did not receive HS genshiken.org: could not connect to host genuu.com: could not connect to host genuxation.com: could not connect to host genyaa.com: could not connect to host genyhitch.com: did not receive HSTS header geoffdev.com: could not connect to host geoffreyrichard.com: did not receive HSTS header geopals.net: did not receive HSTS header -geoponika.gr: did not receive HSTS header george-brighton.co.uk: could not connect to host georgebrighton.co.uk: could not connect to host georgesonarthurs.com.au: did not receive HSTS header gereja.ga: could not connect to host gerencianet.com.br: did not receive HSTS header gereon.ch: could not connect to host gesiwista.net: could not connect to host gesunde-smoothies.de: did not receive HSTS header @@ -5373,27 +5413,29 @@ gts-schulsoftware.de: did not receive HS guarajubaimoveis.com.br: did not receive HSTS header guava.studio: did not receive HSTS header guentherhouse.com: did not receive HSTS header guenthernoack.de: could not connect to host guffrits.com: could not connect to host guge.gq: could not connect to host gugga.dk: could not connect to host guguke.net: did not receive HSTS header +guidetoiceland.is: did not receive HSTS header guilde-vindicta.fr: did not receive HSTS header guillaume-leduc.fr: did not receive HSTS header guillaumematheron.fr: did not receive HSTS header guineafruitcorp.com: could not connect to host gulch.in.ua: did not receive HSTS header gulenet.com: could not connect to host gulfcoast-sandbox.com: could not connect to host gunnarhafdal.com: did not receive HSTS header gunnaro.com: could not connect to host guntbert.net: could not connect to host guoqiang.info: did not receive HSTS header +guozeyu.com: did not receive HSTS header gurom.lv: could not connect to host gurusupe.com: could not connect to host guso.gq: could not connect to host guso.ml: could not connect to host guso.site: could not connect to host guso.tech: could not connect to host gussi.is: did not receive HSTS header gvpt.sk: did not receive HSTS header @@ -5776,16 +5818,17 @@ ierna.com: did not receive HSTS header ies-italia.it: did not receive HSTS header ies.id.lv: could not connect to host ievgenialehner.com: did not receive HSTS header ifad.org: did not receive HSTS header ifastuniversity.com: did not receive HSTS header ifleurs.com: could not connect to host ifx.ee: could not connect to host ifxor.com: did not receive HSTS header +igd.chat: did not receive HSTS header igforums.com: could not connect to host igi.codes: did not receive HSTS header igiftcards.nl: did not receive HSTS header ignatisd.gr: did not receive HSTS header igule.net: could not connect to host ihotel.io: did not receive HSTS header ihrlotto.de: could not connect to host ihrnationalrat.ch: could not connect to host @@ -5843,16 +5886,17 @@ imusic.dk: did not receive HSTS header inb4.us: could not connect to host inbox.li: did not receive HSTS header incendiary-arts.com: could not connect to host inche-ali.com: did not receive HSTS header inchomatic.com: did not receive HSTS header indiecert.net: could not connect to host indiemods.com: could not connect to host indien.guide: could not connect to host +indilens.com: did not receive HSTS header indochina.io: could not connect to host indoorskiassen.nl: did not receive HSTS header indredouglas.me: could not connect to host industrybazar.com: max-age too low: 2592000 ineed.com.mt: could not connect to host infcof.com: did not receive HSTS header infilock.com: could not connect to host infinitude.me.uk: could not connect to host @@ -5937,17 +5981,17 @@ invinsec.cloud: did not receive HSTS hea inviosolutions.com: max-age too low: 0 invite24.pro: could not connect to host invitethemhome.com: did not receive HSTS header iodice.org: did not receive HSTS header iolife.dk: could not connect to host ionas-law.ro: did not receive HSTS header iop.intuit.com: max-age too low: 86400 iora.fr: could not connect to host -iosmods.com: did not receive HSTS header +iosmods.com: could not connect to host iostips.ru: could not connect to host ip-life.net: did not receive HSTS header ip6.im: did not receive HSTS header ipbill.org.uk: could not connect to host iplife.cn: could not connect to host ipmimagazine.com: did not receive HSTS header iprice.co.id: did not receive HSTS header iprice.hk: did not receive HSTS header @@ -5975,16 +6019,17 @@ irland.guide: could not connect to host irmtrudjurke.de: did not receive HSTS header irstaxforumsonline.com: did not receive HSTS header irugs.ch: did not receive HSTS header irugs.co.uk: did not receive HSTS header irugs.com.sg: did not receive HSTS header irukandjilabs.com: could not connect to host irvinepa.org: max-age too low: 10540800 is-a-furry.org: did not receive HSTS header +isaackhor.com: did not receive HSTS header ischool.co.jp: did not receive HSTS header isdf.me: could not connect to host isef-eg.com: did not receive HSTS header iseulde.com: did not receive HSTS header ishadowsocks.ltd: could not connect to host ishangirdhar.com: could not connect to host ishillaryclintoninprisonyet.com: could not connect to host isitamor.pm: could not connect to host @@ -6079,16 +6124,17 @@ jan-daniels.de: did not receive HSTS hea jan27.org: did not receive HSTS header janario.me: could not connect to host janbrodda.de: max-age too low: 2592000 jangho.me: could not connect to host janking.de: could not connect to host janmachynka.cz: did not receive HSTS header jannyrijneveld.nl: did not receive HSTS header janus-engineering.de: did not receive HSTS header +jap-nope.de: did not receive HSTS header japaripark.com: could not connect to host japlex.com: could not connect to host jaqen.ch: could not connect to host jaredbates.net: did not receive HSTS header jarivisual.com: did not receive HSTS header jarnail.ca: did not receive HSTS header jaroslavtrsek.cz: did not receive HSTS header jarsater.com: could not connect to host @@ -6282,17 +6328,17 @@ kaanduman.com: did not receive HSTS head kaasbijwijn.nl: did not receive HSTS header kabinapp.com: could not connect to host kabuabc.com: could not connect to host kackscharf.de: could not connect to host kadioglumakina.com.tr: did not receive HSTS header kaela.design: could not connect to host kahopoon.net: could not connect to host kaika-hms.de: did not receive HSTS header -kainz.bayern: did not receive HSTS header +kainz.bayern: could not connect to host kaisers.de: did not receive HSTS header kaiyuewu.com: could not connect to host kaketalk.com: did not receive HSTS header kalami.nl: could not connect to host kaleidomarketing.com: did not receive HSTS header kambodja.guide: could not connect to host kamcvicit.sk: could not connect to host kamikano.com: could not connect to host @@ -6315,16 +6361,17 @@ kashdash.ca: could not connect to host katalogakci.cz: did not receive HSTS header katiaetdavid.fr: could not connect to host katoju.co.jp: could not connect to host katproxy.al: could not connect to host katproxy.online: could not connect to host katproxy.site: could not connect to host katproxy.tech: could not connect to host katproxy.top: did not receive HSTS header +katzen.me: did not receive HSTS header kaufkraftkiel.de: could not connect to host kauplusprofesional.com: did not receive HSTS header kausch.at: could not connect to host kavinvin.me: could not connect to host kcluster.io: could not connect to host kd-plus.pp.ua: could not connect to host kdata.it: did not receive HSTS header kdbx.online: could not connect to host @@ -6702,17 +6749,16 @@ lightning-ashe.com: did not receive HSTS lightnovelsekai.com: could not connect to host lightpaste.com: could not connect to host lightworkerandempathsupport.com: max-age too low: 300 lightworx.io: did not receive HSTS header lila.pink: did not receive HSTS header lilapmedia.com: did not receive HSTS header lillpopp.eu: max-age too low: 10 lilpwny.com: could not connect to host -lily-bearing.com: did not receive HSTS header lilycms.com: could not connect to host lim-light.com: did not receive HSTS header limalama.eu: max-age too low: 1 limeyeti.com: could not connect to host limiteddata.co.uk: did not receive HSTS header limodo-shop.de: did not receive HSTS header limpens.net: did not receive HSTS header limpido.it: could not connect to host @@ -6748,16 +6794,17 @@ listage.ovh: did not receive HSTS header litespeed.io: could not connect to host little.pw: did not receive HSTS header littlefreelibrary.org: did not receive HSTS header liujunyang.com: did not receive HSTS header livedemo.io: could not connect to host livej.am: could not connect to host liverewrite.com: could not connect to host liviababynet.com.br: could not connect to host +livinghealthywithchocolate.com: did not receive HSTS header livrariahugodesaovitor.com.br: did not receive HSTS header lixiang.one: could not connect to host lixingcong.com: could not connect to host lkp111138.me: could not connect to host llamasweet.tech: could not connect to host loacg.com: did not receive HSTS header loadingdeck.com: did not receive HSTS header loadso.me: could not connect to host @@ -7084,17 +7131,16 @@ mca2017.org: did not receive HSTS header mcard.vn: did not receive HSTS header mcb-bank.com: did not receive HSTS header mcc.re: could not connect to host mccarty.io: could not connect to host mcdonalds.ru: did not receive HSTS header mcga.media: could not connect to host mclab.su: max-age too low: 2592000 mclist.it: could not connect to host -mclyr.com: did not receive HSTS header mcmillansedationdentistry.com: did not receive HSTS header mcooperlaw.com: did not receive HSTS header mcuexchange.com: did not receive HSTS header mdfnet.se: did not receive HSTS header mdscomp.net: did not receive HSTS header meadowfenfarm.com: could not connect to host meat-education.com: could not connect to host mebio.us: could not connect to host @@ -7102,17 +7148,16 @@ mecenat-cassous.com: did not receive HST mechmk1.me: did not receive HSTS header medallia.io: could not connect to host media-access.online: did not receive HSTS header mediacru.sh: could not connect to host mediafinancelab.org: did not receive HSTS header mediamag.am: max-age too low: 0 mediawikicn.org: could not connect to host medienservice-fritz.de: did not receive HSTS header -medifab.online: did not receive HSTS header medirich.co: could not connect to host meditek-dv.ru: could not connect to host mediterenopmaandag.nl: did not receive HSTS header medm-test.com: could not connect to host medzinenews.com: did not receive HSTS header meedoennoordkop.nl: did not receive HSTS header meedoenzaanstad.nl: did not receive HSTS header meetfinch.com: could not connect to host @@ -7522,17 +7567,17 @@ n0psled.nl: could not connect to host n2x.in: could not connect to host n4l.pw: could not connect to host n8ch.net: could not connect to host nabru.co.uk: did not receive HSTS header nabu-bad-nauheim.de: did not receive HSTS header nabytko.cz: could not connect to host nacktetatsachen.at: did not receive HSTS header nadia.pt: could not connect to host -nagios.by: could not connect to host +nagios.by: did not receive HSTS header nagoya-kyuyo.com: could not connect to host naiharngym.com: did not receive HSTS header najedlo.sk: could not connect to host nakamastreamingcommunity.com: could not connect to host nakliyatsirketi.biz: could not connect to host nakuro.de: could not connect to host nalifornia.com: did not receive HSTS header nalinux.cz: did not receive HSTS header @@ -7752,17 +7797,17 @@ novacraft.me: did not receive HSTS heade novaopcaofestas.com.br: could not connect to host novatrucking.de: could not connect to host novavoidhowl.com: did not receive HSTS header novelabs.de: could not connect to host novelabs.eu: could not connect to host novelshouse.com: did not receive HSTS header novtest.ru: did not receive HSTS header novurania.com: did not receive HSTS header -nowak.ninja: did not receive HSTS header +nowak.ninja: could not connect to host noworrywp.com: could not connect to host nowprotein.com: did not receive HSTS header nozoe.jp: could not connect to host npol.de: could not connect to host nq7.pl: could not connect to host nrechn.de: could not connect to host nrizzio.me: could not connect to host nrnjn.xyz: did not receive HSTS header @@ -7775,16 +7820,17 @@ nu3.co.uk: could not connect to host nu3.com: did not receive HSTS header nu3.de: did not receive HSTS header nu3.dk: did not receive HSTS header nu3.fi: did not receive HSTS header nu3.fr: did not receive HSTS header nu3.no: did not receive HSTS header nu3.se: did not receive HSTS header nube.ninja: did not receive HSTS header +nuevaimagenpublicidad.es: did not receive HSTS header nufla.de: could not connect to host nuiguru.me: could not connect to host nukenet.se: could not connect to host nukute.com: did not receive HSTS header null-pointer.eu: did not receive HSTS header null-sec.ru: could not connect to host null.cat: did not receive HSTS header null.tips: could not connect to host @@ -8026,17 +8072,17 @@ pagerate.io: did not receive HSTS header pagetoimage.com: could not connect to host pahlawanpulsa.com: did not receive HSTS header paigeglass.com: did not receive HSTS header paino.cloud: could not connect to host paintingat.com: could not connect to host paisaone.com: did not receive HSTS header pajadam.me: did not receive HSTS header pajonzeck.de: could not connect to host -paket.io: did not receive HSTS header +paket.io: could not connect to host paku.me: could not connect to host palmer.im: could not connect to host pammbook.com: did not receive HSTS header pamplona.tv: could not connect to host pamsoft.pl: max-age too low: 0 pan.tips: could not connect to host panaceallc.net: could not connect to host panama-gbs.com: did not receive HSTS header @@ -8059,17 +8105,17 @@ paperwallets.io: did not receive HSTS he papierniak.net: could not connect to host papygeek.com: could not connect to host parabhairavayoga.com: max-age too low: 0 paradependentesquimicos.com.br: did not receive HSTS header paragon.edu: did not receive HSTS header parent5446.us: could not connect to host parentmail.co.uk: did not receive HSTS header parfum-baza.ru: did not receive HSTS header -paris-cyber.fr: did not receive HSTS header +paris-cyber.fr: could not connect to host parisvox.info: did not receive HSTS header parithy.net: could not connect to host parkingplus.co.il: could not connect to host parkrocker.com: max-age too low: 604800 parkwithark.com: could not connect to host parodybit.net: did not receive HSTS header parpaing-paillette.net: could not connect to host particonpsplus.it: could not connect to host @@ -8138,16 +8184,17 @@ peekops.com: could not connect to host peerherrmann.de: could not connect to host peissen.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 115" data: no] pekkapikkarainen.fi: did not receive HSTS header pekkarik.ru: could not connect to host peliculasaudiolatinoonline.com: could not connect to host peliseries24.com: did not receive HSTS header pemberton.at: did not receive HSTS header penablog.com: did not receive HSTS header +pencillab.cn: did not receive HSTS header pengui.uk: could not connect to host penguinclientsystem.com: did not receive HSTS header pennylane.me.uk: did not receive HSTS header pensanisso.com: max-age too low: 2592000 pentagram.me: max-age too low: 2592000 pentano.net: could not connect to host people-mozilla.org: could not connect to host peperiot.com: did not receive HSTS header @@ -8207,16 +8254,18 @@ phonenumberinfo.co.uk: could not connect phongmay24h.com: could not connect to host phood.be: did not receive HSTS header photoblogverona.com: could not connect to host photoboothpartyhire.co.uk: did not receive HSTS header phototag.org: did not receive HSTS header php-bach.org: could not connect to host phperformances.fr: did not receive HSTS header phrasing.me: could not connect to host +phuket-idc.com: did not receive HSTS header +phuket-idc.de: did not receive HSTS header physicaltherapist.com: did not receive HSTS header pi-eng.fr: did not receive HSTS header pianetaottica.net: could not connect to host pianetaottica.org: could not connect to host picardiascr.com: did not receive HSTS header pickersurvey.org: could not connect to host pickr.co: did not receive HSTS header picotronic.biz: could not connect to host @@ -8281,16 +8330,17 @@ pleasure.forsale: could not connect to h pleier-it.de: did not receive HSTS header pleier.it: did not receive HSTS header plfgr.eu.org: could not connect to host plhdb.org: did not receive HSTS header plirt.ru: could not connect to host plixer.com: did not receive HSTS header plogable.co: could not connect to host plombirator.kz: did not receive HSTS header +plongee-phuket.fr: did not receive HSTS header plothost.com: did not receive HSTS header ploup.net: could not connect to host ploxel.com: did not receive HSTS header pluff.nl: did not receive HSTS header plur.com.au: did not receive HSTS header plus-digital.net: did not receive HSTS header plus-u.com.au: did not receive HSTS header plut.org: could not connect to host @@ -8337,17 +8387,16 @@ popi.se: did not receive HSTS header popkins.ml: could not connect to host poris.web.id: could not connect to host pornstars.me: did not receive HSTS header portalm.tk: could not connect to host portalplatform.net: could not connect to host portaluniversalista.org: could not connect to host poshpak.com: max-age too low: 86400 postcodewise.co.uk: did not receive HSTS header -posterspy.com: did not receive HSTS header postscheduler.org: could not connect to host posylka.de: did not receive HSTS header potatoheads.net: could not connect to host potentialproject.com: did not receive HSTS header potsky.com: did not receive HSTS header pottshome.co.uk: did not receive HSTS header pourmesloisirs.com: did not receive HSTS header poussinooz.fr: could not connect to host @@ -8445,17 +8494,16 @@ proxybay.al: could not connect to host proxybay.club: could not connect to host proxybay.info: did not receive HSTS header proxybay.top: did not receive HSTS header proxydesk.net: could not connect to host proxyowl.pw: could not connect to host proxyportal.me: did not receive HSTS header proxyrox.com: could not connect to host proxyweb.us: did not receive HSTS header -prstatic.com: did not receive HSTS header prxio.date: could not connect to host prxio.site: could not connect to host pscleaningsolutions.co.uk: could not connect to host pshostpk.com: did not receive HSTS header psicologia.co.ve: could not connect to host psicologoforensebarcelona.com: did not receive HSTS header pstudio.me: did not receive HSTS header psw.academy: could not connect to host @@ -8590,27 +8638,26 @@ rate-esport.de: could not connect to hos rationem.nl: did not receive HSTS header ratuseks.com: could not connect to host ratuseks.net: could not connect to host ratuseks.us: could not connect to host rauchenwald.net: did not receive HSTS header raulfraile.net: could not connect to host ravage.fm: did not receive HSTS header raven.lipetsk.ru: could not connect to host -ravenger.net: did not receive HSTS header ravengergaming.ga: did not receive HSTS header ravkr.duckdns.org: max-age too low: 360000 raw-diets.com: did not receive HSTS header rawet.se: could not connect to host rawoil.com: could not connect to host rawstorieslondon.com: could not connect to host raydan.space: could not connect to host raydobe.me: could not connect to host raytron.org: could not connect to host -razeencheng.com: could not connect to host +razeencheng.com: did not receive HSTS header razlaw.name: did not receive HSTS header razzolini.com.br: could not connect to host rbhighinc.org: could not connect to host rbose.org: could not connect to host rbqcloud.com: could not connect to host rbti.me: could not connect to host rc-rp.com: did not receive HSTS header rc4.io: could not connect to host @@ -8662,16 +8709,17 @@ regenbogenwald.de: did not receive HSTS regenerescence.com: did not receive HSTS header reggae-cdmx.com: could not connect to host regionale.org: did not receive HSTS header registertovoteflorida.gov: did not receive HSTS header rehabthailand.nl: could not connect to host reic.me: could not connect to host reidascuecas.com.br: could not connect to host reikiqueen.uk: could not connect to host +reimann.me: did not receive HSTS header reisyukaku.org: did not receive HSTS header reithguard-it.de: did not receive HSTS header rejo.in: could not connect to host rejuvemedspa.com: did not receive HSTS header relayawards.com: could not connect to host reldoc.com.mx: did not receive HSTS header reliable-mail.de: could not connect to host relisten.nl: did not receive HSTS header @@ -8887,16 +8935,17 @@ sageth.com: max-age too low: 0 sah3.net: could not connect to host saharalondon.com: max-age too low: 0 saharmassachi.com: could not connect to host saigonstar.de: did not receive HSTS header sail-nyc.com: did not receive HSTS header saint-astier-triathlon.com: did not receive HSTS header saintjohnlutheran.church: did not receive HSTS header sairai.bid: could not connect to host +sajamstudija.info: did not receive HSTS header sakaki.anime.my: max-age too low: 5184000 sakaserver.com: did not receive HSTS header sakib.ninja: did not receive HSTS header sakurabuff.com: could not connect to host saleslift.pl: did not receive HSTS header salserocafe.com: did not receive HSTS header salserototal.com: could not connect to host saltedskies.com: could not connect to host @@ -8940,16 +8989,17 @@ satriyowibowo.my.id: could not connect t satsukii.moe: did not receive HSTS header saturne.tk: could not connect to host saturngames.co.uk: did not receive HSTS header saucyfox.net: did not receive HSTS header saudeeconforto.com.br: did not receive HSTS header saumon.xyz: could not connect to host saunasandstuff.ca: did not receive HSTS header saunasandstuff.com: did not receive HSTS header +savacloud.com: did not receive HSTS header save.gov: could not connect to host saveaward.gov: could not connect to host saveyour.biz: could not connect to host savingrecipe.com: did not receive HSTS header savisasolutions.co.za: did not receive HSTS header savvysuit.com: did not receive HSTS header sawamura-rental.com: did not receive HSTS header say-hanabi.com: could not connect to host @@ -9006,16 +9056,17 @@ screencaster.io: did not receive HSTS he screenresolution.space: could not connect to host screensaversplanet.com: did not receive HSTS header scribbleserver.com: could not connect to host scribe.systems: could not connect to host scrion.com: could not connect to host scriptenforcer.net: did not receive HSTS header scriptict.nl: could not connect to host scrollstory.com: did not receive HSTS header +scubadiving-phuket.com: did not receive HSTS header sdhmanagementgroup.com: could not connect to host sdia.ru: could not connect to host sdmoscow.ru: could not connect to host sdrobs.com: did not receive HSTS header sdsl-speedtest.de: could not connect to host se7ensins.com: did not receive HSTS header seans.cc: did not receive HSTS header searchgov.gov.il: did not receive HSTS header @@ -9061,17 +9112,16 @@ securiviera.ch: did not receive HSTS hea sedoexpert.nl: could not connect to host sedoexperts.nl: could not connect to host sedrubal.de: could not connect to host sedziapilkarski.pl: did not receive HSTS header seedboxers.net: could not connect to host seefunk.net: did not receive HSTS header seele.ca: could not connect to host sehenderson.com: did not receive HSTS header -seiko-dojo.com: could not connect to host seiler-bad.de: did not receive HSTS header seizoushokoyuubangou.com: did not receive HSTS header sektor.team: could not connect to host selecadm.name: could not connect to host selectary.com: could not connect to host selectcertifiedautos.com: did not receive HSTS header selectel.com: did not receive HSTS header selectruckscalltrackingreports.com: could not connect to host @@ -9181,17 +9231,17 @@ shiftplanning.com: did not receive HSTS shiinko.com: could not connect to host shikinobi.com: did not receive HSTS header shindorei.fr: could not connect to host shinebijoux.com.br: could not connect to host shinju.moe: could not connect to host shiona.xyz: could not connect to host shipinsight.com: did not receive HSTS header shipmile.com: did not receive HSTS header -shipping24h.com: could not connect to host +shipping24h.com: did not receive HSTS header shirosaki.org: could not connect to host shitfest.info: did not receive HSTS header shitposting.life: could not connect to host shm-forum.org.uk: could not connect to host shocksrv.com: did not receive HSTS header shooshosha.com: could not connect to host shopherbal.co.za: did not receive HSTS header shopods.com: did not receive HSTS header @@ -9406,16 +9456,17 @@ soply.com: did not receive HSTS header soporte.cc: could not connect to host sorensen-online.com: could not connect to host sosaka.ml: could not connect to host sosiolog.com: could not connect to host sotor.de: did not receive HSTS header soucorneteiro.com.br: could not connect to host soulfulglamour.uk: could not connect to host soundforsound.co.uk: did not receive HSTS header +souravsaha.com: did not receive HSTS header sourcelair.com: did not receive HSTS header sourcitec.com: did not receive HSTS header southcoastswords.com: did not receive HSTS header southernjamusa.com: did not receive HSTS header southgale.condos: could not connect to host southside-crew.club: could not connect to host southworcestershiregpservices.co.uk: could not connect to host souvik.me: did not receive HSTS header @@ -9461,17 +9512,16 @@ spineandscoliosis.com: did not receive H spirit-dev.net: max-age too low: 0 spiritfanfics.com: did not receive HSTS header spisoggrin.dk: did not receive HSTS header spitefultowel.com: did not receive HSTS header spititout.it: could not connect to host spittersberger.recipes: did not receive HSTS header spokonline.com: could not connect to host sponsortobias.com: could not connect to host -sport-socken.net: did not receive HSTS header sportchirp-internal.azurewebsites.net: did not receive HSTS header sporthit.ru: did not receive HSTS header sportifik.com: did not receive HSTS header sportingoods.com.br: could not connect to host sportscollection.com.br: could not connect to host sportwette.eu: did not receive HSTS header spot-events.com: could not connect to host spotifyripper.tk: could not connect to host @@ -9479,17 +9529,17 @@ spotlightsrule.ddns.net: could not conne spr.id.au: did not receive HSTS header spresso.me: did not receive HSTS header sprint.ml: did not receive HSTS header sprk.fitness: did not receive HSTS header sproutconnections.com: could not connect to host sprutech.de: could not connect to host spyroszarzonis.com: could not connect to host sqetsa.com: did not receive HSTS header -squaddraft.com: could not connect to host +squaddraft.com: did not receive HSTS header square.gs: could not connect to host squatldf.org: did not receive HSTS header srcc.fr: could not connect to host srevilak.net: did not receive HSTS header srmaximo.com: could not connect to host srna.sk: did not receive HSTS header srpdb.com: did not receive HSTS header srrr.ca: could not connect to host @@ -9594,22 +9644,24 @@ strivephysmed.com: did not receive HSTS stroeercrm.de: could not connect to host strongest-privacy.com: could not connect to host stuartbaxter.co: could not connect to host student-scientist.org: did not receive HSTS header studentrdh.com: did not receive HSTS header studentresearcher.org: did not receive HSTS header studentskydenik.cz: could not connect to host studenttravel.cz: did not receive HSTS header +studienservice.de: max-age too low: 7889238 studinf.xyz: could not connect to host studio-panic.com: did not receive HSTS header studiozelden.com: did not receive HSTS header studybay.com: did not receive HSTS header studydrive.net: did not receive HSTS header studyhub.cf: did not receive HSTS header +stuffie.org: did not receive HSTS header stugb.de: did not receive HSTS header sturbock.me: did not receive HSTS header sturdio.com.br: could not connect to host stylenda.com: could not connect to host stytt.com: did not receive HSTS header subbing.work: could not connect to host subdimension.org: did not receive HSTS header subeesu.com: could not connect to host @@ -9836,30 +9888,31 @@ tekshrek.com: did not receive HSTS heade tel-dithmarschen.de: did not receive HSTS header teleallarme.ch: could not connect to host telefisk.org: did not receive HSTS header telefonnummer.online: could not connect to host telefoonnummerinfo.nl: could not connect to host telescam.com: could not connect to host teletechnology.in: did not receive HSTS header teletra.ru: could not connect to host -tellingua.com: did not receive HSTS header +tellingua.com: could not connect to host temasa.net: did not receive HSTS header temehu.com: did not receive HSTS header tempcraft.net: could not connect to host tempo.co: did not receive HSTS header tempodecolheita.com.br: could not connect to host tendertool.nl: could not connect to host tendoryu-aikido.org: did not receive HSTS header tenerife-villas.com: did not receive HSTS header tengroup.com: max-age too low: 0 tenni.xyz: could not connect to host tensei-slime.com: did not receive HSTS header tensionup.com: could not connect to host tentins.com: could not connect to host +teodio.cl: did not receive HSTS header teoleonie.com: did not receive HSTS header teos.online: could not connect to host terra.by: did not receive HSTS header terrax.berlin: could not connect to host terrax.info: could not connect to host teru.com.br: could not connect to host test02.dk: did not receive HSTS header testandroid.xyz: could not connect to host @@ -10004,26 +10057,28 @@ thorncreek.net: did not receive HSTS hea thriveapproach.co.uk: did not receive HSTS header thrivewellnesshub.co.za: did not receive HSTS header throughthelookingglasslens.co.uk: could not connect to host thumbtack.com: did not receive HSTS header thundercampaign.com: could not connect to host ti.blog.br: could not connect to host tianxing.pro: did not receive HSTS header tianxingvpn.pro: could not connect to host +tibbitshall.ca: did not receive HSTS header ticketoplichting.nl: did not receive HSTS header tickopa.co.uk: could not connect to host tickreport.com: did not receive HSTS header ticktock.today: did not receive HSTS header tictactux.de: could not connect to host tidmore.us: could not connect to host tie-online.org: did not receive HSTS header tiendschuurstraat.nl: could not connect to host tiensnet.com: could not connect to host tierrarp.com: could not connect to host +tiffanytravels.com: did not receive HSTS header tightlineproductions.com: did not receive HSTS header tikutiku.pl: could not connect to host tildebot.com: could not connect to host tilient.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 115" data: no] tilikum.io: did not receive HSTS header tilkah.com.au: did not receive HSTS header tillcraft.com: could not connect to host timbeilby.com: could not connect to host @@ -10058,21 +10113,21 @@ titanleaf.com: could not connect to host titouan.co: did not receive HSTS header tittarpuls.se: could not connect to host titties.ml: could not connect to host tjc.wiki: could not connect to host tjeckien.guide: could not connect to host tkappertjedemetamorfose.nl: could not connect to host tkarstens.de: did not receive HSTS header tkonstantopoulos.tk: could not connect to host -tlach.cz: did not receive HSTS header tlcdn.net: could not connect to host tlo.hosting: could not connect to host tlo.link: could not connect to host tlo.network: could not connect to host +tloxygen.com: did not receive HSTS header tls.li: could not connect to host tlsbv.nl: did not receive HSTS header tlshost.net: could not connect to host tm-solutions.eu: could not connect to host tmaward.net: could not connect to host tmhlive.com: could not connect to host tmitchell.io: could not connect to host tmprod.com: did not receive HSTS header @@ -10102,31 +10157,32 @@ tokobungadipadangflorist.com: did not re tokoone.com: did not receive HSTS header tokotamz.net: could not connect to host tokotimbangandigitalmurah.web.id: did not receive HSTS header tokoyo.biz: could not connect to host tollmanz.com: did not receive HSTS header tolud.com: could not connect to host tom.run: did not receive HSTS header tomeara.net: could not connect to host -tomevans.io: did not receive HSTS header +tomevans.io: could not connect to host tomlankhorst.nl: did not receive HSTS header tomli.me: could not connect to host tommsy.com: did not receive HSTS header tommy-bordas.fr: did not receive HSTS header tommyads.com: could not connect to host tommyweber.de: did not receive HSTS header tomphill.co.uk: could not connect to host tongmu.me: did not receive HSTS header tonyfantjr.com: max-age too low: 0 toomanypillows.com: could not connect to host top-stage.net: could not connect to host topbargains.com.au: did not receive HSTS header topbestsellerproduct.com: did not receive HSTS header topdeskdev.net: could not connect to host +topdogsinflatables.co.uk: did not receive HSTS header topmarine.se: could not connect to host topnewstoday.org: could not connect to host topnovini.com: did not receive HSTS header toppik.com.br: could not connect to host topshelfguild.com: could not connect to host toptenthebest.com: did not receive HSTS header toptranslation.com: did not receive HSTS header topyx.com: did not receive HSTS header @@ -10214,17 +10270,17 @@ tripinsider.club: did not receive HSTS h trixies-wish.nz: could not connect to host trixy.com.br: could not connect to host troi.de: did not receive HSTS header trollme.me: could not connect to host trollscave.xyz: could not connect to host troo.ly: could not connect to host trouter.io: could not connect to host true.ink: did not receive HSTS header -truebred-labradors.com: did not receive HSTS header +truebred-labradors.com: could not connect to host trunkjunk.co: did not receive HSTS header trustedinnovators.com: did not receive HSTS header trusteecar.com: did not receive HSTS header trustmeimfancy.com: could not connect to host trybind.com: could not connect to host tryoneday.co: did not receive HSTS header ts2.se: could not connect to host ts3.consulting: could not connect to host @@ -10463,17 +10519,17 @@ vadodesign.nl: did not receive HSTS head valenscaelum.com: could not connect to host valethound.com: could not connect to host valhalla-agency.com: max-age too low: 0 valhallacostarica.com: could not connect to host valhallamovement.com: did not receive HSTS header valitron.se: did not receive HSTS header valkyrja.xyz: could not connect to host valleyridgepta.org: could not connect to host -vallis.net: did not receive HSTS header +vallis.net: could not connect to host valmagus.com: could not connect to host vamoaeturismo.com.br: could not connect to host vampirism.eu: could not connect to host vanacht.co.za: did not receive HSTS header vanajahosting.com: did not receive HSTS header vanderkley.it: could not connect to host vanestack.com: could not connect to host vanitas.xyz: could not connect to host @@ -10611,28 +10667,30 @@ voceinveste.com: did not receive HSTS he voicesuk.co.uk: did not receive HSTS header voidserv.net: could not connect to host volcrado.com: did not receive HSTS header voliere-info.nl: did not receive HSTS header volkden.com: could not connect to host voltotc.com: did not receive HSTS header vonavy-cukor.sk: could not connect to host vonavycukor.sk: could not connect to host +vonedelmann.de: did not receive HSTS header vonterra.us: did not receive HSTS header vooreenveiligthuis.nl: did not receive HSTS header voorjou.com: did not receive HSTS header vorangerie.com: could not connect to host vortexhobbies.com: did not receive HSTS header vowsy.club: did not receive HSTS header vox.vg: did not receive HSTS header vpip.net: could not connect to host vpl.me: did not receive HSTS header vpn-byen.dk: did not receive HSTS header vpn.pics: did not receive HSTS header vpnhot.com: could not connect to host +vpnzoom.com: did not receive HSTS header vps-szerver-berles.hu: could not connect to host vpsmojo.com: could not connect to host vratny.space: could not connect to host vriendenvoordeel.com: did not receive HSTS header vrijstaandhuis-in-alphen-aan-den-rijn-kopen.nl: could not connect to host vrijstaandhuis-in-brielle-kopen.nl: could not connect to host vrijstaandhuis-in-delfzijl-kopen.nl: could not connect to host vrijstaandhuis-in-friesland-kopen.nl: could not connect to host @@ -10859,16 +10917,17 @@ wodice.com: could not connect to host wohnungsbau-ludwigsburg.de: did not receive HSTS header woima.fi: max-age too low: 604800 wolfenland.net: did not receive HSTS header wolfesden.com: could not connect to host womf.org: did not receive HSTS header womosale.de: could not connect to host wonder.com.mx: max-age too low: 86400 wonderfall.xyz: could not connect to host +wondermags.com: did not receive HSTS header wondy.com: could not connect to host woodlandschurch.net: max-age too low: 43200 woodmafia.com.au: could not connect to host woodworkertip.com: did not receive HSTS header woording.com: could not connect to host wootton95.com: could not connect to host wooviet.com: could not connect to host work-and-jockel.de: did not receive HSTS header @@ -10922,17 +10981,17 @@ www-1117.com: could not connect to host www-39988.com: did not receive HSTS header www-507.net: could not connect to host www-746.com: could not connect to host www-771122.com: did not receive HSTS header www-8003.com: did not receive HSTS header www-88599.com: did not receive HSTS header www-9995.com: did not receive HSTS header www-djbet.com: did not receive HSTS header -www-jinshavip.com: could not connect to host +www-jinshavip.com: did not receive HSTS header www.cueup.com: could not connect to host www.cyveillance.com: did not receive HSTS header www.developer.mydigipass.com: could not connect to host www.elanex.biz: did not receive HSTS header www.gamesdepartment.co.uk: did not receive HSTS header www.gpo.gov: did not receive HSTS header www.greplin.com: could not connect to host www.jitsi.org: did not receive HSTS header @@ -11016,17 +11075,16 @@ xn--datenrettung-mnchen-jbc.com: did not xn--ekr87w7se89ay98ezcs.biz: did not receive HSTS header xn--gmq92k.nagoya: did not receive HSTS header xn--jp-6l5cs1yf3ivjsglphyv.net: could not connect to host xn--l8j9d2b.jp: did not receive HSTS header xn--lgb3a8bcpn.cf: could not connect to host xn--lgb3a8bcpn.ga: could not connect to host xn--lgb3a8bcpn.gq: could not connect to host xn--lgb3a8bcpn.ml: could not connect to host -xn--lnakuten-9za.com: did not receive HSTS header xn--ls8hi7a.tk: could not connect to host xn--milchaufschumer-test-lzb.de: could not connect to host xn--n8jubz39q0g0afpa985c.com: could not connect to host xn--neb-tma3u8u.xyz: could not connect to host xn--p8jskj.jp: did not receive HSTS header xn--pck4e3a2ex597b4ml.xyz: did not receive HSTS header xn--qckqc0nxbyc4cdb4527err7c.biz: did not receive HSTS header xn--u9jy16ncfao19mo8i.nagoya: did not receive HSTS header
--- a/security/manager/ssl/nsSTSPreloadList.inc +++ b/security/manager/ssl/nsSTSPreloadList.inc @@ -3,17 +3,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /*****************************************************************************/ /* This is an automatically generated file. If you're not */ /* nsSiteSecurityService.cpp, you shouldn't be #including it. */ /*****************************************************************************/ #include <stdint.h> -const PRTime gPreloadListExpirationTime = INT64_C(1529523515392000); +const PRTime gPreloadListExpirationTime = INT64_C(1529610665474000); %% 0-1.party, 1 0.me.uk, 1 0005pay.com, 1 00100010.net, 1 0010100.net, 1 00120012.net, 1 00130013.net, 1 @@ -127,17 +127,17 @@ 112hz.com, 1 113113113.net, 1 118118118.net, 1 11loc.de, 1 11scc.com, 1 11thstreetcoffee.com, 1 11urss.com, 1 1212873467.rsc.cdn77.org, 1 1218641649.rsc.cdn77.org, 1 -123comparer.fr, 1 +123comparer.fr, 0 123djdrop.com, 1 123midterm.com, 1 123pay.ir, 0 123plons.nl, 1 123termpapers.com, 1 123test.com, 1 123test.nl, 1 125m125.de, 1 @@ -1095,16 +1095,17 @@ aflowershop.ca, 1 afmt.fr, 1 afmtevents.com, 1 afonso.io, 1 afp548.com, 1 afri.cc, 1 africa.dating, 1 africanexponent.com, 1 africanimpact.com, 1 +africantourer.com, 1 africatravel.de, 1 afrikarl.de, 1 afrodigital.uk, 1 after.digital, 1 afterhate.fr, 1 afterstack.net, 1 afuh.de, 1 afva.net, 1 @@ -1628,17 +1629,17 @@ alza.de, 1 alza.hu, 1 alza.sk, 1 alzashop.com, 1 alzonaprinting.com, 1 am2s.fr, 1 am3.se, 1 ama.ne.jp, 1 amaderelectronics.com, 1 -amadilo.de, 1 +amadilo.de, 0 amadoraslindas.com, 1 amadvice.com, 1 amaforro.com, 1 amaforums.org, 1 amagdic.com, 1 amagical.net, 1 amalfi5stars.com, 1 amalficoastchauffeur.com, 1 @@ -3332,17 +3333,16 @@ bayer-stefan.com, 1 bayer-stefan.de, 1 bayer-stefan.eu, 1 bayerhazard.de, 1 bayerstefan.com, 1 bayerstefan.de, 1 bayerstefan.eu, 1 bayherbalist.com, 1 bayilelakiku.com, 1 -bayinstruments.com, 1 baymard.com, 1 bayrisch-fuer-anfaenger.de, 1 baywatch.io, 1 bayz.de, 1 bazaarcompass.com, 1 bazdell.com, 0 bazos.at, 1 bazos.cz, 1 @@ -3420,17 +3420,16 @@ be9966.com, 1 beachfutbolclub.com, 1 beacinsight.com, 1 beadare.com, 1 beagreenbean.co.uk, 1 bealpha.pl, 1 beamitapp.com, 1 beanjuice.me, 1 beans-one.com, 0 -beanworks.ca, 1 bearcosports.com.br, 1 bearded.sexy, 1 bearingworks.com, 1 beasel.biz, 1 beastowner.li, 1 beatfeld.de, 1 beatnikbreaks.com, 1 beatrizaebischer.ch, 1 @@ -3734,16 +3733,17 @@ bet909.com, 1 bet990.com, 1 bet9bet9.net, 1 betamint.org, 1 betaworx.de, 1 betaworx.eu, 1 betecnet.de, 1 betformular.com, 1 betgo9.cc, 1 +bethanyduke.com, 1 betkoo.com, 1 betobaccofree.gov, 1 betonmoney.com, 1 betpamm.com, 1 betseybuckheit.com, 1 betshoot.com, 1 betsonlinefree.com.au, 1 betsyshilling.com, 1 @@ -4051,17 +4051,16 @@ bitcoin.de, 1 bitcoin.im, 1 bitcoin.info, 1 bitcoin.org, 1 bitcoin.us, 1 bitcoinbitcoin.com, 1 bitcoinclashic.ninja, 1 bitcoincore.org, 1 bitcoinec.info, 1 -bitcoinhk.org, 1 bitcoinindia.com, 1 bitcoinjpn.com, 1 bitcoinkarlsruhe.de, 1 bitcoinrealestate.com.au, 1 bitcointhefts.com, 1 bitcoinwalletscript.tk, 1 bitcoinx.gr, 1 bitcoinx.ro, 1 @@ -4297,17 +4296,16 @@ blogexpert.ca, 1 blogging-life.com, 1 bloggingwithchildren.com, 1 bloggytalky.com, 1 bloginbeeld.nl, 1 blogom.at, 1 blogpentrusuflet.ro, 1 blogreen.org, 1 blogtroterzy.pl, 1 -blok56.nl, 1 blokuhaka.fr, 1 bloodsports.org, 1 bloodyexcellent.com, 1 bloom-avenue.com, 1 bltc.co.uk, 1 bltc.com, 1 bltc.net, 1 bltc.org, 1 @@ -5020,16 +5018,17 @@ buck.com, 1 buckmulligans.com, 1 buckypaper.com, 1 budaev-shop.ru, 1 buddhistische-weisheiten.org, 1 buddie5.com, 1 buddlycrafts.com, 1 buddyworks.net, 1 budeanu.com, 1 +buderus-family.be, 1 budger.nl, 1 budget.gov, 1 budgetalk.com, 1 budgetcastlehire.co.uk, 1 budgetenergievriendenvoordeel.nl, 1 budgetlob.gov, 1 budgetlovers.nl, 1 budgiesballoons.com, 1 @@ -5764,16 +5763,17 @@ cedriccassimo.ch, 1 cedriccassimo.com, 1 cee.io, 1 ceebee.com, 1 cefak.org.br, 1 cegfw.com, 1 ceilingpac.org, 1 cejhon.cz, 0 cekaja.com, 1 +celebphotos.blog, 1 celebrityscope.net, 1 celec.gob.ec, 0 celectro-pro.com, 1 celiendev.ch, 1 celigo.com, 1 celltek-server.de, 1 celti.ie.eu.org, 1 celti.name, 1 @@ -7059,16 +7059,17 @@ continuation.io, 1 contrabass.net, 1 contractormountain.com, 1 contratatupoliza.com, 1 contributor.google.com, 1 controlarlaansiedad.com, 1 controlautocom.com.br, 1 controlbooth.com, 1 controle.net, 1 +controleer-maar-een-ander.nl, 1 controltickets.com.br, 1 contxt-agentur.de, 1 conv2pdf.com, 1 conve.eu, 1 convergemagazine.com, 1 convergence.fi, 1 convergencela.com, 1 convergnce.com, 1 @@ -8307,17 +8308,17 @@ delivery.co.at, 1 dellipaoli.com, 1 delogo.nl, 1 deloittequant.com, 1 delorenzi.dk, 1 delphine.dance, 1 delta-data.ch, 1 delta-smart.ch, 1 delta.ru, 1 -delta23.de, 0 +delta23.de, 1 deltaacademy.org, 1 deltadata.ch, 1 deltaonlineguards.com, 1 deltasmart.ch, 1 deltava.org, 1 demandware.com, 1 demarche-expresse.com, 1 demarle.ch, 1 @@ -8368,16 +8369,17 @@ dentistglasgow.com, 1 dentrassi.de, 1 dentystabirmingham.co.uk, 1 denverphilharmonic.org, 1 deontology.com, 1 depaddestoeltjes.be, 1 deparis.me, 1 depechemode-live.com, 1 depedshs.com, 1 +depedtayo.com, 1 depedtayo.ph, 1 depicus.com, 1 depone.net, 1 depot-leipzig.de, 1 depotsquarekerrville.com, 1 depotter-usedcars.be, 1 deprecate.de, 1 deprobe.pro, 1 @@ -8882,17 +8884,16 @@ diycc.org, 1 diymediahome.org, 1 diyosun.com, 1 diz.in.ua, 1 dizzythewizard.co.uk, 1 dj-leszwolle.nl, 1 dj-x.info, 1 dj3dub.com, 1 djangobirthday.com, 1 -djangogolf.com, 1 djangoproject.com, 1 djangosnippets.org, 1 djbbouncycastles.co.uk, 1 djc.me, 1 djcursuszwolle.nl, 1 djdavid98.hu, 1 djipanov.com, 1 djlive.pl, 1 @@ -9483,17 +9484,16 @@ dusmomente.com, 1 dusnan.com, 1 dustplanet.de, 1 dustri.org, 1 dustycloth.com, 1 dustygroove.com, 1 dustyspokesbnb.ca, 1 dutch.desi, 1 dutch1.nl, 1 -dutchessuganda.com, 1 dutchrank.nl, 1 dutchwanderers.nl, 1 dutchweballiance.nl, 1 dutyfreeonboard.com, 1 dvbris.co.uk, 1 dvbris.com, 1 dvdland.com.au, 1 dvhosting.be, 1 @@ -9871,17 +9871,16 @@ egiftcards.be, 1 eglek.com, 1 ego4u.com, 1 ego4u.de, 1 egoroof.ru, 1 egov4.ch, 1 egretail.no, 0 egrp365.ru, 1 egumenita.ro, 1 -egupova.ru, 1 egw-ceramica.de, 1 egweb.tv, 1 ehaccp.it, 1 ehandel.com, 1 ehazi.hu, 1 ehertz.uk, 1 ehipaa.com, 1 ehlacademy.org, 1 @@ -9897,17 +9896,16 @@ eickhofcolumbaria.com, 1 eidolons.org, 1 eiga-movie.com, 1 eigenbubi.de, 1 eighty-aid.com, 1 eightyfour.ca, 1 eigpropertyauctions.co.uk, 1 eilhan.com, 1 eimacs.com, 1 -eimanavicius.lt, 1 einar.io, 1 einaros.is, 1 einfachbahn.de, 1 einfachmaldiefressehalten.de, 1 einheft.info, 1 einheizpreis.de, 1 einmonolog.de, 1 einrichtwerk.de, 1 @@ -10479,17 +10477,17 @@ errietta.me, 1 errlytics.com, 1 error418.nl, 1 ers35.com, 1 ersa-shop.com, 1 ershiwo.com, 1 ersinerce.com, 1 erspro.net, 1 erstehilfeprodukte.at, 1 -eru.im, 1 +eru.im, 0 erudicia.com, 1 erudicia.de, 1 erudicia.es, 1 erudicia.fr, 1 erudicia.it, 1 erudicia.nl, 1 erudicia.se, 1 erudicia.uk, 1 @@ -10844,17 +10842,16 @@ evades.io, 1 evailoil.ee, 1 evailoil.eu, 1 evalesc.com, 1 evamachkova.cz, 1 evamira.com, 1 evanfiddes.com, 1 evangelosm.com, 1 evankurniawan.com, 1 -evantage.org, 1 evantageglobal.com, 1 evapp.org, 1 evasion-energie.com, 1 evasioncreole.com, 1 evasovova.cz, 1 eve0s.com, 1 evegalaxy.net, 1 evelienzorgt.nl, 1 @@ -11822,16 +11819,17 @@ flygpost.com, 1 flyingdoggy.net, 1 flyinglocksmiths.com, 0 flyingpackets.net, 1 flyingrub.me, 1 flymns.fr, 1 flynn.io, 1 flyp.me, 1 flyserver.co.il, 1 +flyspace.ga, 1 flyspace.ml, 1 flyss.net, 1 flyssh.net, 1 flyt.online, 1 flytoadventures.com, 1 fm-cdn.de, 1 fm.ie, 1 fmapplication.com, 1 @@ -12157,17 +12155,16 @@ freejeremy.net, 1 freejidi.com, 1 freela.ch, 1 freelance.boutique, 1 freelance.guide, 1 freelance.nl, 1 freelancecollab.com, 1 freelancehunt.com, 1 freelanceshipping.com, 1 -freelandinnovation.com, 1 freelansir.com, 1 freelauri.com, 1 freelifer.jp, 1 freemanning.de, 1 freemans.com, 1 freemedforms.com, 1 freemyipod.org, 1 freend.me, 0 @@ -12418,26 +12415,24 @@ furrybot.me, 1 furryyiff.site, 1 furtivelook.com, 1 fusa-miyamoto.jp, 1 fuseos.net, 1 fushee.com, 1 fuskator.com, 1 fussball-xxl.de, 1 fussell.io, 1 -futbolvivo.tv, 1 futos.de, 1 futrou.com, 1 futurefire.de, 1 futurehack.io, 1 futurenda.com, 1 futureoceans.org, 1 futuresonline.com, 1 futurezone.at, 1 -futuristarchitecture.com, 1 futurope.com, 1 fuwafuwa.moe, 1 fuxwerk.de, 1 fuyu.moe, 1 fuzoku-sodan.com, 1 fuzoku.jp, 1 fuzzing-project.org, 1 fveevaete.com, 1 @@ -12470,17 +12465,16 @@ fysio123.nl, 1 fysiotherapieholtenbroek.nl, 1 fysiotherapierossum.nl, 1 fysiovdberg.nl, 1 fysuite.com, 1 fzbrweb.cz, 1 fzx750.ru, 1 g-m-w.eu, 1 g-o.pl, 1 -g-rom.net, 1 g01.in.ua, 1 g1.ie, 1 g10e.ch, 1 g1jeu.com, 1 g2-inc.com, 1 g2links.com, 1 g2pla.net, 1 g2soft.net, 1 @@ -12825,16 +12819,17 @@ geocompass.at, 1 geoffanderinmyers.com, 1 geoffmyers.com, 0 geofox.org, 1 geoip.fedoraproject.org, 1 geoip.stg.fedoraproject.org, 1 geojs.io, 1 geolad.com, 0 geometra.roma.it, 1 +geoponika.gr, 1 geoport.al, 1 george-orwell.com, 1 georgehalachev.com, 1 georgemaschke.com, 1 georgemaschke.net, 1 georgescarryout.com, 1 georgewbushlibrary.gov, 1 georgiaglassrepair.com, 1 @@ -13649,17 +13644,16 @@ guid2steamid.com, 1 guid2steamid.pw, 1 guide-peche-cantal.com, 1 guidechecking.com, 1 guidedselling.net, 1 guideline.gov, 1 guidelines.gov, 1 guideo.ch, 1 guides-peche64.com, 1 -guidetoiceland.is, 0 guildgearscore.cf, 0 guildofmusicsupervisors.co.uk, 1 guillaume-briand.fr, 1 guillaumecote.me, 1 guillaumeperrin.io, 1 guillemaud.me, 0 guiltypleasuresroleplaying.com, 1 guim.co.uk, 1 @@ -13676,17 +13670,16 @@ gumballs.com, 1 gume4you.com, 1 gumi.ca, 1 gummibande.noip.me, 1 gunhunter.com, 1 guniram.com, 1 gunwatch.co.uk, 1 guochang.xyz, 1 guoliang.me, 1 -guozeyu.com, 1 guphi.net, 0 gurkan.in, 1 gurmel.ru, 1 gurochan.ch, 1 guru-naradi.cz, 1 gurueffect.com, 1 gus.host, 1 gus.moe, 1 @@ -15236,17 +15229,16 @@ ifsclist.com, 1 ifsr.de, 1 iftrue.de, 1 ifxnet.com, 1 ifyou.live, 1 ig.com, 1 iga-semi.jp, 1 igamingforums.com, 1 igcc.jp, 1 -igd.chat, 1 igglabs.com, 1 iggprivate.com, 1 iggsoft.com, 1 iggsoftware.com, 1 igiftcards.de, 1 igimusic.com, 1 igk.nz, 1 igm-be.ch, 1 @@ -15492,17 +15484,16 @@ indianaantlersupply.com, 1 indianaffairs.gov, 0 indiawise.co.uk, 1 indicateurs-flash.fr, 1 indieethos.com, 1 indiegame.space, 1 indievelopment.nl, 1 indigoinflatables.com, 1 indigosakura.com, 1 -indilens.com, 1 inditip.com, 1 indogerman.de, 1 indogermanstartup.com, 1 indogermantrade.de, 1 indoorplantsexpert.com, 1 indostar303.com, 1 indovinabank.com.vn, 1 indusap.com, 1 @@ -15950,17 +15941,16 @@ irritant.net, 1 iruarts.ch, 1 iruca.co, 1 is-sw.net, 1 isaackabel.cf, 1 isaackabel.ga, 1 isaackabel.gq, 1 isaackabel.ml, 1 isaackabel.tk, 1 -isaackhor.com, 1 isaacman.tech, 1 isaacpartnership.co.uk, 1 isaacpartnership.com, 1 isaacphysics.org, 1 isaaczais.com, 1 isabelle-delpech.com, 1 isabellehogarth.co.uk, 1 isakssons.com, 1 @@ -16354,17 +16344,16 @@ jannisfink.de, 1 janoberst.com, 1 janokacer.sk, 1 janosh.com, 1 janschaumann.de, 1 janssen.fm, 1 janssenwigman.nl, 1 janverlaan.nl, 1 jaot.info, 1 -jap-nope.de, 1 japan4you.org, 1 japaneseemoticons.org, 1 japanesenames.biz, 1 japaniac.de, 0 japanphilosophy.com, 1 japanwatches.xyz, 1 jape.today, 1 jardin-exotique-rennes.fr, 1 @@ -17283,17 +17272,16 @@ kato-yane.com, 1 katrinjanke.de, 0 katscastles.co.uk, 1 kattelans.eu, 1 kattenfun.be, 1 kattenfun.nl, 1 katthewaffle.fr, 1 katyl.info, 0 katyusha.net, 1 -katzen.me, 1 katzspeech.com, 1 kau-boys.com, 1 kau-boys.de, 1 kaufberatung.community, 1 kauperwood.ovh, 1 kausta.me, 1 kavik.no, 1 kavovary-kava.cz, 1 @@ -18914,16 +18902,17 @@ likegeeks.com, 1 likehifi.de, 1 likemovies.de, 1 likenewhearing.com.au, 1 likenosis.com, 1 lilaccakeboutique.com, 1 liliang13.com, 1 lilismartinis.com, 1 lillepuu.com, 1 +lily-bearing.com, 1 lily-inn.com, 1 lilyfarmfreshskincare.com, 1 lilygreen.co.za, 1 lilysbouncycastles.com, 1 limawi.io, 1 limberg.me, 1 limbo.services, 1 limeburst.net, 1 @@ -19112,17 +19101,16 @@ livepath.ch, 1 liveperformersmeeting.net, 1 liveregistratie.nl, 1 livesearch-fukuoka.com, 1 livesure.com, 1 livi.co, 1 living-space.co.nz, 1 living24.de, 1 livingforreal.com, 1 -livinghealthywithchocolate.com, 1 livingworduk.org, 1 livnev.me, 1 livnev.xyz, 1 livolett.de, 1 livrariacoad.com.br, 1 livroseuniformes.com.br, 1 lixtick.com, 1 liyang.pro, 1 @@ -20352,16 +20340,17 @@ mcideas.tk, 1 mcjackk77.com, 1 mckenry.net, 1 mckernan.in, 1 mckinley.school, 1 mckinley1.com, 1 mckinleytk.com, 1 mcl.gg, 1 mclinflatables.co.uk, 1 +mclyr.com, 1 mcmillanskiclub.com.au, 1 mcneill.io, 1 mcnext.net, 1 mcpaoffice.com, 1 mcpart.land, 1 mcpro.games, 1 mcrn.jp, 1 mcsa-usa.org, 1 @@ -20450,16 +20439,17 @@ mediawiki.org, 1 mediawin.pl, 1 medic-world.com, 1 medicalcountermeasures.gov, 1 medicinesfast.com, 0 medicinia.com.br, 1 medicinskavranje.edu.rs, 1 medicocompetente.it, 1 medicoresponde.com.br, 1 +medifab.online, 1 medifi.com, 1 medinside.ch, 1 medinside.li, 1 medinsider.ch, 1 medinsider.li, 1 medireport.fr, 1 medium.com, 1 mediumraw.org, 1 @@ -21502,17 +21492,17 @@ mpi-sa.fr, 1 mpintaamalabanna.it, 1 mplanetphl.fr, 1 mplant.io, 1 mplicka.cz, 1 mplusm.eu, 1 mpn.poker, 1 mpnpokertour.com, 1 mpodraza.pl, 1 -mpreserver.com, 0 +mpreserver.com, 1 mprsco.eu, 1 mpserver12.org, 1 mpsgarage.com.au, 1 mpsoundcraft.com, 1 mpy.ovh, 1 mr-anderson.org, 1 mr-labo.jp, 1 mr-nachhilfe.de, 1 @@ -23053,17 +23043,16 @@ nubu.at, 1 nuclear-crimes.com, 1 nuclearcat.com, 1 nuclearcrimes.com, 1 nuclearcrimes1.com, 1 nucleuscore.org, 1 nudel.ninja, 1 nudestpics.com, 1 nuel.cl, 1 -nuevaimagenpublicidad.es, 1 null-life.com, 1 nullday.de, 1 nullpointer.io, 1 nullroute.com, 1 nulltime.net, 1 numarasorgulama.tel, 1 numatic.co.uk, 1 number.me, 1 @@ -24393,17 +24382,16 @@ pelican.ie, 1 pelletizermill.com, 1 pelletsprice.com, 1 pelopogrund.com, 1 pelopoplot.com, 1 pelotonimports.com, 1 pemagrid.org, 1 penaugustin.com, 1 pencepay.com, 1 -pencillab.cn, 1 pendriveapps.com, 1 penetrationstest.se, 1 penfold.fr, 1 pengi.me, 1 pengisatelier.net, 1 penguinprotocols.com, 1 pengumuman.id, 1 penispumpen.se, 1 @@ -24645,18 +24633,16 @@ phpkari.cz, 1 phpliteadmin.org, 1 phpmyadmin.net, 1 phpprime.com, 1 phpsecure.info, 1 phra.gs, 1 phrive.space, 1 phryanjr.com, 0 phryneas.de, 1 -phuket-idc.com, 1 -phuket-idc.de, 1 phunehehe.net, 1 phuong.faith, 1 phurl.de, 1 phurl.io, 1 phus.lu, 1 physicalism.com, 1 physicalist.com, 1 physiovesenaz.ch, 1 @@ -24953,17 +24939,16 @@ plexpy13.ddns.net, 1 plextv.de, 1 plexusmd.com, 1 plinc.co, 1 pliosoft.com, 1 plitu.de, 1 ploader.ru, 0 plochka.bg, 1 plomberierenga.com, 1 -plongee-phuket.fr, 1 ploofer.com, 1 plot.ly, 1 plotbubble.com, 1 plr4wp.com, 1 plsboop.me, 1 pluga.co, 1 plugboard.xyz, 1 plugcubed.net, 0 @@ -25215,16 +25200,17 @@ postbox.life, 1 postcardpayment.com, 1 postcode.nl, 1 postcodegarant.nl, 1 postdarwinian.com, 1 postdarwinism.com, 1 postdeck.de, 1 posteo.de, 0 posters.win, 1 +posterspy.com, 1 postfalls-naturopathic.com, 1 postfinance.ch, 1 postmatescode.com, 1 postn.eu, 1 postpot.co.kr, 1 posttigo.com, 1 potatiz.com, 1 potatofrom.space, 0 @@ -25645,16 +25631,17 @@ proxybay.one, 1 proxybay.tv, 1 proxydesk.eu, 1 proxyportal.net, 1 proxyportal.org, 1 proymaganadera.com, 1 prpferrara.it, 1 prplz.io, 1 prpsss.com, 1 +prstatic.com, 1 prt.in.th, 1 prtimes.com, 1 prtpe.com, 1 pruikshop.nl, 1 pruma.com.br, 1 prvikvadrat.hr, 1 prylarprylar.se, 1 pryspry.com, 1 @@ -26191,16 +26178,17 @@ rattenkot.io, 1 raucris.ro, 1 raulrivero.es, 1 raumzeitlabor.de, 0 rauros.net, 1 rautelow.de, 1 rautermods.net, 1 ravchat.com, 1 raven.dog, 1 +ravenger.net, 1 ravengergaming.net, 1 ravensbuch.de, 1 ravhaaglanden.org, 1 ravindran.me, 1 raviparekh.co.uk, 1 ravis.org, 1 ravse.dk, 1 rawsec.net, 1 @@ -26475,17 +26463,16 @@ rei.ki, 1 reichel-steinmetz.de, 1 reichelt-cloud.de, 1 reichl-online.net, 1 reidasbombas.com, 1 reignsphere.net, 1 reiki-coaching.nl, 0 reilly.io, 1 reimaginebelonging.de, 1 -reimann.me, 1 reimers.de, 1 reimu.ink, 0 rein.kr, 1 reinaertvandecruys.me, 1 reinaldudras.ee, 1 reinaldudrasfamily.ee, 1 reineberthe.ch, 1 reinencaressa.be, 1 @@ -27252,17 +27239,17 @@ runebet.com, 1 runementors.com, 0 runklesecurity.com, 1 runnergrapher.com, 1 runreport.fr, 1 runschrauger.com, 1 runvs.io, 1 ruobiyi.com, 1 ruobr.ru, 1 -ruri.io, 1 +ruri.io, 0 rus-trip.ru, 1 rusempire.ru, 1 rushball.net, 1 rushiiworks.com, 1 rushpoppershop.co.uk, 1 rushyo.com, 1 rusi-ns.ca, 1 ruskod.net, 1 @@ -27424,17 +27411,16 @@ saintaardvarkthecarpeted.com, 1 saintanthonyscorner.com, 1 sainth.de, 1 saintsrobotics.com, 1 saintw.com, 1 saipariwar.com, 1 saiputra.com, 1 saitrance.com, 1 saiyasu-search.com, 1 -sajamstudija.info, 1 sajdowski.de, 1 sakostacloud.de, 1 sakuraflores.com.br, 1 salaervergleich.com, 1 salde.net, 1 sale4ru.ru, 1 saleaks.org, 1 salearnership.co.za, 1 @@ -27640,17 +27626,16 @@ saumon-france.com, 1 saumon.io, 1 saumondefrance.fr, 1 saumonfrance.fr, 1 saunahats.eu, 1 saunas.fr, 1 saunatime.jp, 1 saurel.me, 1 sauvagebridge.nl, 1 -savacloud.com, 1 savageorgiev.com, 1 savannahtasteexperience.com, 1 save-me-aachen.de, 1 save-me-koeln.de, 1 savecashindia.com, 1 savecrypto.org, 1 savekorea.net, 1 savemoneyonenergy.com, 1 @@ -27910,17 +27895,16 @@ scruffymen.com, 0 scrumbleship.com, 1 scrumstack.co.uk, 1 scryfall.com, 1 scs-simulatoren.de, 1 scsd.si, 1 scswam.com, 1 sctm.at, 1 sctrainingllc.com, 1 -scubadiving-phuket.com, 1 scul.net, 1 sculpture.support, 1 scuolaguidalame.ch, 1 scw.com, 1 scw.nz, 1 scwilliams.co.uk, 1 scwilliams.uk, 1 sd.af, 1 @@ -28118,16 +28102,17 @@ segmetic.com, 1 segulink.com, 1 segurosbalboa.com.ec, 0 segurosocial.gov, 1 seguroviagem.srv.br, 1 sehnenweh.org, 1 seida.at, 1 seifried.org, 1 seikatu-navi.com, 1 +seiko-dojo.com, 1 seinfeldquote.com, 1 seirei.ne.jp, 1 seiryokuzai-ch.com, 1 seitai-taiyou.com, 1 seitenwaelzer.de, 1 sekisonn.com, 1 selbys.net.au, 1 selco-himejiminami.com, 1 @@ -29479,17 +29464,16 @@ soumya92.me, 1 soundabout.nl, 1 soundedj.com.br, 1 soundeo.com, 1 soundeo.net, 1 soundgasm.net, 1 soundhunter.xyz, 0 soundsecurity.io, 1 sour.is, 1 -souravsaha.com, 1 sourcebox.be, 1 sourcecode.love, 1 sourcely.net, 1 sourceway.de, 1 souris.ch, 1 sous-surveillance.net, 1 southafrican.dating, 1 southambouncycastle.co.uk, 1 @@ -29649,16 +29633,17 @@ spookbook.net, 1 spookquest.com, 1 spookyinternet.com, 1 spoopy.link, 1 sporcard.com, 1 spornkuller.de, 1 sport-in-sundern.de, 1 sport-potreby.cz, 1 sport-potreby.sk, 1 +sport-socken.net, 1 sporter.com, 1 sportflash.info, 1 sportnesia.com, 1 sportovnidum.cz, 1 sportparks.com, 1 sportparks.org, 1 sportressofblogitude.com, 1 sports.dating, 1 @@ -30191,17 +30176,16 @@ studentfinancecountdown.com, 1 studentforums.biz, 1 studentite.bg, 0 studentloans.gov, 1 studentrightsadvocate.org, 1 studenttenant.com, 1 studer.su, 1 studiemeter.nl, 1 studienportal.eu, 1 -studienservice.de, 1 studiereader.nl, 1 studio-architetto.com, 1 studio-fotografico.ru, 1 studiodentisticosanmarco.it, 1 studiodewit.nl, 1 studiodoprazer.com.br, 1 studiogavioli.com, 1 studiograou.com, 1 @@ -30220,17 +30204,16 @@ studium.cz, 1 studlan.no, 1 studport.rv.ua, 1 studyabroadstation.com, 1 studying-neet.com, 1 stuermer.me, 1 stuetzredli.ch, 1 stuff-fibre.co.nz, 1 stuffi.fr, 1 -stuffie.org, 1 stuka-art.de, 1 stulda.cz, 0 stumeta.de, 1 stumeta2018.de, 1 stumf.si, 1 stuntmen.xyz, 1 stupendous.net, 0 stupidstatetricks.com, 1 @@ -31071,17 +31054,16 @@ tenseapp.pl, 1 tenshoku-hanashi.com, 1 tent.io, 1 tenta.com, 1 tentabrowser.com, 1 tentations-voyages.com, 0 tenthousandcoffees.com, 1 tenyx.de, 1 tenzer.dk, 1 -teodio.cl, 1 teoskanta.fi, 1 tepid.org, 1 tepitus.de, 1 tequilazor.com, 1 terabyte.services, 1 teracloud.at, 1 teranacreative.com, 1 teranga.ch, 1 @@ -31622,17 +31604,16 @@ ti-planet.org, 1 tiacollection.com, 1 tiagonunes.pt, 1 tiaki.org, 1 tianeptine.com, 1 tianshili.me, 1 tianxicaipiao.com, 1 tianxicaipiao.win, 1 tianxicp.com, 1 -tibbitshall.ca, 1 tibipg.com, 1 tibovanheule.site, 1 ticfleet.com, 1 ticketluck.com, 1 ticketmates.com.au, 1 ticketpro.ca, 1 ticketslover.com, 1 ticketsmate.com, 1 @@ -31650,17 +31631,16 @@ tiendavertigo.com, 1 tiens-ib.cz, 1 tier-1-entrepreneur.com, 1 tierarztpraxis-bogenhausen.de, 1 tierarztpraxis-weinert.de, 1 tiernanx.com, 1 ties.com, 1 tiew.pl, 1 tifan.net, 1 -tiffanytravels.com, 1 tiffnix.com, 1 tigerchef.com, 1 tigerdile.com, 1 tiggeriffic.com, 1 tigit.co.nz, 1 tiglitub.com, 1 tiihosen.fi, 1 tijden.nu, 1 @@ -31782,21 +31762,21 @@ tkat.ch, 1 tkeycoin.com, 1 tkgpm.com, 1 tkjg.fi, 1 tkn.me, 1 tkn.tokyo, 1 tkts.cl, 1 tkusano.jp, 1 tkw01536.de, 1 +tlach.cz, 1 tlca.org, 1 tlcnet.info, 1 tlehseasyads.com, 1 tlo.xyz, 1 -tloxygen.com, 1 tls-proxy.de, 1 tls.builders, 1 tls.care, 1 tls1914.org, 1 tlsrobot.se, 1 tlthings.net, 1 tlys.de, 1 tm.id.au, 1 @@ -32031,17 +32011,16 @@ topaxi.codes, 1 topbilan.com, 1 topbounce.com, 1 topbouncycastles.co.uk, 1 topbrakes.com, 1 topclassfun.ie, 1 topdesk.net, 1 topdetoxcleanse.com, 1 topdevbox.net, 1 -topdogsinflatables.co.uk, 1 topeng-emas.com, 1 topesb.com, 1 topfivepercent.co.uk, 1 topicdesk.com, 1 topicit.net, 1 topirishcasinos.com, 1 topjobs.ch, 1 toplist.eu, 1 @@ -33710,17 +33689,16 @@ vollans.id.au, 1 voloevents.com, 1 volta.io, 1 voltimax.com, 1 volto.io, 1 volunteeringmatters.org.uk, 1 vomitb.in, 1 vonauw.com, 1 vonborstelboerner.de, 1 -vonedelmann.de, 0 vongerlach.at, 1 vonniehudson.com, 1 vonski.pl, 1 voodoochile.at, 1 vop.li, 1 vorderklier.de, 1 vorkbaard.nl, 1 vorlicek.de, 1 @@ -33751,17 +33729,16 @@ voyageforum.com, 1 voyagesaufildespages.be, 1 voyageschine.com, 1 voyagesdetective.fr, 1 vozami.com, 1 vpc-display.com, 1 vpn.black, 1 vpn.ht, 1 vpnservice.nl, 1 -vpnzoom.com, 1 vpsboard.com, 1 vpsdream.dk, 1 vrandopulo.ru, 1 vranjske.co.rs, 1 vreeman.com, 1 vriesdonkow.be, 1 vrijgezellen-feest.com, 1 vrijgezellenfeestzwolle.com, 1 @@ -34711,17 +34688,16 @@ women-only.net, 1 womenshairlossproject.com, 1 wonabo.com, 1 wonderbill.com, 1 wonderbooks.club, 1 wondergorilla.com, 1 wonderhost.info, 1 wonderhowto.com, 1 wonderlandmovies.de, 1 -wondermags.com, 1 wondershift.biz, 1 woodbury.io, 1 woodcoin.org, 1 woodev.us, 1 woodlandhillselectrical.com, 1 woodlandsmetro.church, 1 woodlandsvale.uk, 1 woodlandwindows.com, 1 @@ -35205,16 +35181,17 @@ xn--jbs-tna.de, 1 xn--jda.tk, 1 xn--jp8hx8f.ws, 1 xn--jywq5uqwqxhd2onsij.jp, 1 xn--kda.tk, 1 xn--knstler-n2a.tips, 0 xn--ktha-kamrater-pfba.se, 1 xn--lna-2000-9za.nu, 1 xn--lna-4000-9za.nu, 1 +xn--lnakuten-9za.com, 1 xn--love-un4c7e0d4a.com, 1 xn--lsaupp-iua.se, 1 xn--lsupp-mra.net, 1 xn--manuela-stsser-psb.de, 1 xn--maraa-rta.org, 1 xn--mentaltraining-fr-musiker-uwc.ch, 1 xn--mgbbh2a9fub.xn--ngbc5azd, 0 xn--mgbmmp7eub.com, 1
--- a/servo/components/style/gecko/rules.rs +++ b/servo/components/style/gecko/rules.rs @@ -16,17 +16,18 @@ use gecko_bindings::sugar::ns_css_value: use gecko_bindings::sugar::refptr::{RefPtr, UniqueRefPtr}; use nsstring::nsString; use properties::longhands::font_language_override; use shared_lock::{ToCssWithGuard, SharedRwLockReadGuard}; use std::fmt::{self, Write}; use std::str; use str::CssStringWriter; use values::computed::font::FamilyName; -use values::specified::font::{FontTag, FontVariationSettings, SpecifiedFontFeatureSettings}; +use values::generics::font::FontTag; +use values::specified::font::{FontVariationSettings, SpecifiedFontFeatureSettings}; /// A @font-face rule pub type FontFaceRule = RefPtr<nsCSSFontFaceRule>; impl ToNsCssValue for FamilyName { fn convert(self, nscssvalue: &mut nsCSSValue) { nscssvalue.set_string_from_atom(&self.name) }
--- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -1447,18 +1447,17 @@ impl Clone for ${style_struct.gecko_stru } } pub fn reset_${ident}(&mut self, other: &Self) { self.copy_${ident}_from(other) } pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { - use values::generics::font::{FontSettings, ${tag_type}}; - use values::specified::font::FontTag; + use values::generics::font::{FontSettings, FontTag, ${tag_type}}; FontSettings( self.gecko.mFont.${gecko_ffi_name}.iter().map(|gecko_font_setting| { ${tag_type} { tag: FontTag(gecko_font_setting.mTag), value: gecko_font_setting.mValue as ${value_type}, } }).collect::<Vec<_>>().into_boxed_slice() @@ -2385,17 +2384,17 @@ fn static_assert() { pub fn unzoom_fonts(&mut self, device: &Device) { self.gecko.mSize = device.unzoom_text(Au(self.gecko.mSize)).0; self.gecko.mScriptUnconstrainedSize = device.unzoom_text(Au(self.gecko.mScriptUnconstrainedSize)).0; self.gecko.mFont.size = device.unzoom_text(Au(self.gecko.mFont.size)).0; } pub fn set_font_size(&mut self, v: FontSize) { - use values::specified::font::KeywordSize; + use values::generics::font::KeywordSize; self.gecko.mSize = v.size().0; self.gecko.mScriptUnconstrainedSize = v.size().0; if let Some(info) = v.keyword_info { self.gecko.mFontSizeKeyword = match info.kw { KeywordSize::XXSmall => structs::NS_STYLE_FONT_SIZE_XXSMALL, KeywordSize::XSmall => structs::NS_STYLE_FONT_SIZE_XSMALL, KeywordSize::Small => structs::NS_STYLE_FONT_SIZE_SMALL, KeywordSize::Medium => structs::NS_STYLE_FONT_SIZE_MEDIUM, @@ -2597,18 +2596,17 @@ fn static_assert() { self.gecko.mFontSizeFactor = 1.; self.gecko.mFontSizeOffset = 0; self.gecko.mScriptUnconstrainedSize = parent.gecko.mScriptUnconstrainedSize; } self.fixup_font_min_size(device); } pub fn clone_font_size(&self) -> FontSize { - use values::computed::font::KeywordInfo; - use values::specified::font::KeywordSize; + use values::generics::font::{KeywordInfo, KeywordSize}; let size = Au(self.gecko.mSize).into(); let kw = match self.gecko.mFontSizeKeyword as u32 { structs::NS_STYLE_FONT_SIZE_XXSMALL => KeywordSize::XXSmall, structs::NS_STYLE_FONT_SIZE_XSMALL => KeywordSize::XSmall, structs::NS_STYLE_FONT_SIZE_SMALL => KeywordSize::Small, structs::NS_STYLE_FONT_SIZE_MEDIUM => KeywordSize::Medium, structs::NS_STYLE_FONT_SIZE_LARGE => KeywordSize::Large, structs::NS_STYLE_FONT_SIZE_XLARGE => KeywordSize::XLarge,
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs +++ b/servo/components/style/properties/helpers/animated_properties.mako.rs @@ -47,24 +47,22 @@ use values::computed::ToComputedValue; use values::computed::transform::{DirectionVector, Matrix, Matrix3D}; use values::computed::transform::TransformOperation as ComputedTransformOperation; use values::computed::transform::Transform as ComputedTransform; use values::computed::transform::Rotate as ComputedRotate; use values::computed::transform::Translate as ComputedTranslate; use values::computed::transform::Scale as ComputedScale; use values::generics::transform::{self, Rotate, Translate, Scale, Transform, TransformOperation}; use values::distance::{ComputeSquaredDistance, SquaredDistance}; -use values::generics::font::FontSettings as GenericFontSettings; +use values::generics::font::{FontSettings as GenericFontSettings, FontTag, VariationValue}; use values::computed::font::FontVariationSettings; -use values::generics::font::VariationValue; use values::generics::effects::Filter; use values::generics::position as generic_position; use values::generics::svg::{SVGLength, SvgLengthOrPercentageOrNumber, SVGPaint}; use values::generics::svg::{SVGPaintKind, SVGStrokeDashArray, SVGOpacity}; -use values::specified::font::FontTag; use void::{self, Void}; /// <https://drafts.csswg.org/css-transitions/#animtype-repeatable-list> pub trait RepeatableListAnimatable: Animate {} /// Returns true if this nsCSSPropertyID is one of the animatable properties. #[cfg(feature = "gecko")] pub fn nscsspropertyid_is_animatable(property: nsCSSPropertyID) -> bool {
--- a/servo/components/style/values/animated/effects.rs +++ b/servo/components/style/values/animated/effects.rs @@ -8,17 +8,17 @@ use properties::longhands::box_shadow::c use properties::longhands::filter::computed_value::T as ComputedFilterList; use properties::longhands::text_shadow::computed_value::T as ComputedTextShadowList; use std::cmp; #[cfg(not(feature = "gecko"))] use values::Impossible; use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; use values::animated::color::RGBA; use values::computed::{Angle, Number}; -use values::computed::length::{Length, NonNegativeLength}; +use values::computed::length::Length; use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::generics::effects::BoxShadow as GenericBoxShadow; use values::generics::effects::Filter as GenericFilter; use values::generics::effects::SimpleShadow as GenericSimpleShadow; /// An animated value for the `box-shadow` property. pub type BoxShadowList = ShadowList<BoxShadow>; @@ -28,33 +28,33 @@ pub type TextShadowList = ShadowList<Sim /// An animated value for shadow lists. /// /// <https://drafts.csswg.org/css-transitions/#animtype-shadow-list> #[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[derive(Clone, Debug, PartialEq)] pub struct ShadowList<Shadow>(Vec<Shadow>); /// An animated value for a single `box-shadow`. -pub type BoxShadow = GenericBoxShadow<Option<RGBA>, Length, NonNegativeLength, Length>; +pub type BoxShadow = GenericBoxShadow<Option<RGBA>, Length, Length, Length>; /// An animated value for the `filter` property. #[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[derive(Clone, Debug, PartialEq)] pub struct FilterList(pub Vec<Filter>); /// An animated value for a single `filter`. #[cfg(feature = "gecko")] -pub type Filter = GenericFilter<Angle, Number, NonNegativeLength, SimpleShadow>; +pub type Filter = GenericFilter<Angle, Number, Length, SimpleShadow>; /// An animated value for a single `filter`. #[cfg(not(feature = "gecko"))] -pub type Filter = GenericFilter<Angle, Number, NonNegativeLength, Impossible>; +pub type Filter = GenericFilter<Angle, Number, Length, Impossible>; /// An animated value for the `drop-shadow()` filter. -pub type SimpleShadow = GenericSimpleShadow<Option<RGBA>, Length, NonNegativeLength>; +pub type SimpleShadow = GenericSimpleShadow<Option<RGBA>, Length, Length>; impl ToAnimatedValue for ComputedBoxShadowList { type AnimatedValue = BoxShadowList; #[inline] fn to_animated_value(self) -> Self::AnimatedValue { ShadowList(self.0.to_animated_value()) }
--- a/servo/components/style/values/animated/mod.rs +++ b/servo/components/style/values/animated/mod.rs @@ -12,17 +12,16 @@ use app_units::Au; use euclid::{Point2D, Size2D}; use smallvec::SmallVec; use values::computed::Angle as ComputedAngle; use values::computed::BorderCornerRadius as ComputedBorderCornerRadius; #[cfg(feature = "servo")] use values::computed::ComputedUrl; use values::computed::MaxLength as ComputedMaxLength; use values::computed::MozLength as ComputedMozLength; -use values::computed::NonNegativeLength as ComputedNonNegativeLength; use values::specified::url::SpecifiedUrl; pub mod color; pub mod effects; /// Animate from one value to another. /// /// This trait is derivable with `#[derive(Animate)]`. The derived @@ -256,30 +255,16 @@ macro_rules! trivial_to_animated_value { trivial_to_animated_value!(Au); trivial_to_animated_value!(ComputedAngle); trivial_to_animated_value!(SpecifiedUrl); #[cfg(feature = "servo")] trivial_to_animated_value!(ComputedUrl); trivial_to_animated_value!(bool); trivial_to_animated_value!(f32); -impl ToAnimatedValue for ComputedNonNegativeLength { - type AnimatedValue = Self; - - #[inline] - fn to_animated_value(self) -> Self { - self - } - - #[inline] - fn from_animated_value(animated: Self::AnimatedValue) -> Self { - ComputedNonNegativeLength::new(animated.px().max(0.)) - } -} - impl ToAnimatedValue for ComputedBorderCornerRadius { type AnimatedValue = Self; #[inline] fn to_animated_value(self) -> Self { self } @@ -375,8 +360,21 @@ where #[inline] fn to_animated_zero(&self) -> Result<Self, ()> { match *self { Some(ref value) => Ok(Some(value.to_animated_zero()?)), None => Ok(None), } } } + +impl<T> ToAnimatedZero for Size2D<T> +where + T: ToAnimatedZero, +{ + #[inline] + fn to_animated_zero(&self) -> Result<Self, ()> { + Ok(Size2D::new( + self.width.to_animated_zero()?, + self.height.to_animated_zero()?, + )) + } +}
--- a/servo/components/style/values/computed/border.rs +++ b/servo/components/style/values/computed/border.rs @@ -64,24 +64,16 @@ impl BorderSpacing { impl BorderCornerRadius { /// Returns `0 0`. pub fn zero() -> Self { GenericBorderCornerRadius(Size::new(LengthOrPercentage::zero(), LengthOrPercentage::zero())) } } -impl ToAnimatedZero for BorderSpacing { - #[inline] - fn to_animated_zero(&self) -> Result<Self, ()> { - // FIXME(emilio): Why? - Err(()) - } -} - impl ToAnimatedZero for BorderCornerRadius { #[inline] fn to_animated_zero(&self) -> Result<Self, ()> { // FIXME(nox): Why? Err(()) } }
--- a/servo/components/style/values/computed/font.rs +++ b/servo/components/style/values/computed/font.rs @@ -18,17 +18,18 @@ use std::fmt::{self, Write}; #[cfg(feature = "gecko")] use std::hash::{Hash, Hasher}; #[cfg(feature = "servo")] use std::slice; use style_traits::{CssWriter, ParseError, ToCss}; use values::CSSFloat; use values::animated::{ToAnimatedValue, ToAnimatedZero}; use values::computed::{Context, NonNegativeLength, ToComputedValue, Integer, Number}; -use values::generics::font::{FontSettings, FeatureTagValue, VariationValue}; +use values::generics::font::{FontSettings, FeatureTagValue}; +use values::generics::font::{KeywordInfo as GenericKeywordInfo, VariationValue}; use values::specified::font as specified; use values::specified::length::{FontBaseSize, NoCalcLength}; pub use values::computed::Length as MozScriptMinSize; pub use values::specified::font::{XTextZoom, XLang, MozScriptSizeMultiplier, FontSynthesis}; /// As of CSS Fonts Module Level 3, only the following values are /// valid: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 @@ -44,60 +45,18 @@ pub struct FontWeight(pub u16); /// The computed value of font-size pub struct FontSize { /// The size. pub size: NonNegativeLength, /// If derived from a keyword, the keyword and additional transformations applied to it pub keyword_info: Option<KeywordInfo>, } -#[derive(Animate, ComputeSquaredDistance, MallocSizeOf, ToAnimatedValue, ToAnimatedZero)] -#[derive(Clone, Copy, Debug, PartialEq)] -/// Additional information for keyword-derived font sizes. -pub struct KeywordInfo { - /// The keyword used - pub kw: specified::KeywordSize, - /// A factor to be multiplied by the computed size of the keyword - pub factor: f32, - /// An additional Au offset to add to the kw*factor in the case of calcs - pub offset: NonNegativeLength, -} - -impl KeywordInfo { - /// Computes the final size for this font-size keyword, accounting for - /// text-zoom. - pub fn to_computed_value(&self, context: &Context) -> NonNegativeLength { - let base = context.maybe_zoom_text(self.kw.to_computed_value(context)); - base.scale_by(self.factor) + context.maybe_zoom_text(self.offset) - } - - /// Given a parent keyword info (self), apply an additional factor/offset to it - pub fn compose(self, factor: f32, offset: NonNegativeLength) -> Self { - KeywordInfo { - kw: self.kw, - factor: self.factor * factor, - offset: self.offset.scale_by(factor) + offset, - } - } - - /// KeywordInfo value for font-size: medium - pub fn medium() -> Self { - specified::KeywordSize::Medium.into() - } -} - -impl From<specified::KeywordSize> for KeywordInfo { - fn from(x: specified::KeywordSize) -> Self { - KeywordInfo { - kw: x, - factor: 1., - offset: Au(0).into(), - } - } -} +/// Additional information for computed keyword-derived font sizes. +pub type KeywordInfo = GenericKeywordInfo<NonNegativeLength>; impl FontWeight { /// Value for normal pub fn normal() -> Self { FontWeight(400) } /// Value for bold
--- a/servo/components/style/values/computed/length.rs +++ b/servo/components/style/values/computed/length.rs @@ -810,16 +810,30 @@ impl LengthOrNumber { } /// Either a computed `<length>` or the `normal` keyword. pub type LengthOrNormal = Either<Length, Normal>; /// A wrapper of Length, whose value must be >= 0. pub type NonNegativeLength = NonNegative<Length>; +impl ToAnimatedValue for NonNegativeLength { + type AnimatedValue = Length; + + #[inline] + fn to_animated_value(self) -> Self::AnimatedValue { + self.0 + } + + #[inline] + fn from_animated_value(animated: Self::AnimatedValue) -> Self { + NonNegativeLength::new(animated.px().max(0.)) + } +} + impl NonNegativeLength { /// Create a NonNegativeLength. #[inline] pub fn new(px: CSSFloat) -> Self { NonNegative(Length::new(px.max(0.))) } /// Return a zero value.
--- a/servo/components/style/values/generics/border.rs +++ b/servo/components/style/values/generics/border.rs @@ -38,17 +38,17 @@ impl<L> BorderCornerRadius<L> { /// Trivially create a `BorderCornerRadius`. pub fn new(w: L, h: L) -> Self { BorderCornerRadius(Size::new(w, h)) } } /// A generic value for the `border-spacing` property. #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf)] -#[derive(PartialEq, ToAnimatedValue, ToComputedValue, ToCss)] +#[derive(PartialEq, ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss)] pub struct BorderSpacing<L>(pub Size<L>); impl<L> BorderSpacing<L> { /// Trivially create a `BorderCornerRadius`. pub fn new(w: L, h: L) -> Self { BorderSpacing(Size::new(w, h)) } }
--- a/servo/components/style/values/generics/font.rs +++ b/servo/components/style/values/generics/font.rs @@ -1,21 +1,23 @@ /* 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/. */ //! Generic types for font stuff. +use app_units::Au; +use byteorder::{ReadBytesExt, BigEndian}; use cssparser::Parser; use num_traits::One; use parser::{Parse, ParserContext}; use std::fmt::{self, Write}; -use style_traits::{CssWriter, ParseError, ToCss}; +use std::io::Cursor; +use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; use values::distance::{ComputeSquaredDistance, SquaredDistance}; -use values::specified::font::FontTag; /// https://drafts.csswg.org/css-fonts-4/#feature-tag-value #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)] pub struct FeatureTagValue<Integer> { /// A four-character tag, packed into a u32 (one byte per character). pub tag: FontTag, /// The actual value. pub value: Integer, @@ -112,8 +114,149 @@ impl<T: ToCss> ToCss for FontSettings<T> } first = false; item.to_css(dest)?; } Ok(()) } } + +/// A font four-character tag, represented as a u32 for convenience. +/// +/// See: +/// https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def +/// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-feature-settings +/// +#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)] +pub struct FontTag(pub u32); + +impl ToCss for FontTag { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result + where + W: Write, + { + use byteorder::{BigEndian, ByteOrder}; + use std::str; + + let mut raw = [0u8; 4]; + BigEndian::write_u32(&mut raw, self.0); + str::from_utf8(&raw).unwrap_or_default().to_css(dest) + } +} + +impl Parse for FontTag { + fn parse<'i, 't>( + _context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + let location = input.current_source_location(); + let tag = input.expect_string()?; + + // allowed strings of length 4 containing chars: <U+20, U+7E> + if tag.len() != 4 || tag.as_bytes().iter().any(|c| *c < b' ' || *c > b'~') { + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + } + + let mut raw = Cursor::new(tag.as_bytes()); + Ok(FontTag(raw.read_u32::<BigEndian>().unwrap())) + } +} + +#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf)] +#[derive(PartialEq, ToAnimatedValue, ToAnimatedZero)] +/// Additional information for keyword-derived font sizes. +pub struct KeywordInfo<Length> { + /// The keyword used + pub kw: KeywordSize, + /// A factor to be multiplied by the computed size of the keyword + pub factor: f32, + /// An additional Au offset to add to the kw*factor in the case of calcs + pub offset: Length, +} + +impl<L> KeywordInfo<L> +where + Au: Into<L>, +{ + /// KeywordInfo value for font-size: medium + pub fn medium() -> Self { + KeywordSize::Medium.into() + } +} + +impl<L> From<KeywordSize> for KeywordInfo<L> +where + Au: Into<L>, +{ + fn from(x: KeywordSize) -> Self { + KeywordInfo { + kw: x, + factor: 1., + offset: Au(0).into(), + } + } +} + +/// CSS font keywords +#[derive(Animate, ComputeSquaredDistance, MallocSizeOf, ToAnimatedValue, ToAnimatedZero)] +#[derive(Clone, Copy, Debug, PartialEq)] +#[allow(missing_docs)] +pub enum KeywordSize { + XXSmall = 1, // This is to enable the NonZero optimization + // which simplifies the representation of Option<KeywordSize> + // in bindgen + XSmall, + Small, + Medium, + Large, + XLarge, + XXLarge, + // This is not a real font keyword and will not parse + // HTML font-size 7 corresponds to this value + XXXLarge, +} + +impl KeywordSize { + /// Convert to an HTML <font size> value + pub fn html_size(&self) -> u8 { + match *self { + KeywordSize::XXSmall => 0, + KeywordSize::XSmall => 1, + KeywordSize::Small => 2, + KeywordSize::Medium => 3, + KeywordSize::Large => 4, + KeywordSize::XLarge => 5, + KeywordSize::XXLarge => 6, + KeywordSize::XXXLarge => 7, + } + } +} + +impl Default for KeywordSize { + fn default() -> Self { + KeywordSize::Medium + } +} + +impl ToCss for KeywordSize { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result + where + W: Write, + { + dest.write_str(match *self { + KeywordSize::XXSmall => "xx-small", + KeywordSize::XSmall => "x-small", + KeywordSize::Small => "small", + KeywordSize::Medium => "medium", + KeywordSize::Large => "large", + KeywordSize::XLarge => "x-large", + KeywordSize::XXLarge => "xx-large", + KeywordSize::XXXLarge => { + debug_assert!( + false, + "We should never serialize specified values set via HTML presentation attributes" + ); + "-servo-xxx-large" + }, + }) + } +}
--- a/servo/components/style/values/generics/size.rs +++ b/servo/components/style/values/generics/size.rs @@ -9,17 +9,17 @@ use euclid::Size2D; use parser::ParserContext; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, ToCss}; use values::animated::ToAnimatedValue; /// A generic size, for `border-*-radius` longhand properties, or /// `border-spacing`. #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug)] -#[derive(MallocSizeOf, PartialEq, ToComputedValue)] +#[derive(MallocSizeOf, PartialEq, ToAnimatedZero, ToComputedValue)] pub struct Size<L>(pub Size2D<L>); impl<L> Size<L> { #[inline] /// Create a new `Size` for an area of given width and height. pub fn new(width: L, height: L) -> Size<L> { Size(Size2D::new(width, height)) }
--- a/servo/components/style/values/specified/font.rs +++ b/servo/components/style/values/specified/font.rs @@ -16,17 +16,18 @@ use parser::{Parse, ParserContext}; use properties::longhands::system_font::SystemFont; #[allow(unused_imports)] use std::ascii::AsciiExt; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; use values::CustomIdent; use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue}; use values::computed::font::{SingleFontFamily, FontFamilyList, FamilyName}; -use values::generics::font::{FontSettings, FeatureTagValue, VariationValue}; +use values::generics::font::{FontSettings, FontTag, FeatureTagValue}; +use values::generics::font::{KeywordInfo as GenericKeywordInfo, KeywordSize, VariationValue}; use values::specified::{AllowQuirks, Integer, LengthOrPercentage, NoCalcLength, Number}; use values::specified::length::{AU_PER_PT, AU_PER_PX, FontBaseSize}; const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8; const DEFAULT_SCRIPT_SIZE_MULTIPLIER: f64 = 0.71; #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] /// A specified font-weight value @@ -129,17 +130,17 @@ pub enum FontSize { /// will be 1 (with offset 0), but we cascade keywordness even /// after font-relative (percent and em) values /// have been applied, which is where the ratio /// comes in. The offset comes in if we cascaded a calc value, /// where the font-relative portion (em and percentage) will /// go into the ratio, and the remaining units all computed together /// will go into the offset. /// See bug 1355707. - Keyword(computed::KeywordInfo), + Keyword(KeywordInfo), /// font-size: smaller Smaller, /// font-size: larger Larger, /// Derived from a specified system font. System(SystemFont) } @@ -335,88 +336,50 @@ impl Parse for FontSizeAdjust { if input.try(|input| input.expect_ident_matching("none")).is_ok() { return Ok(FontSizeAdjust::None); } Ok(FontSizeAdjust::Number(Number::parse_non_negative(context, input)?)) } } -/// CSS font keywords -#[derive(Animate, ComputeSquaredDistance, MallocSizeOf, ToAnimatedValue, ToAnimatedZero)] -#[derive(Clone, Copy, Debug, PartialEq)] -#[allow(missing_docs)] -pub enum KeywordSize { - XXSmall = 1, // This is to enable the NonZero optimization - // which simplifies the representation of Option<KeywordSize> - // in bindgen - XSmall, - Small, - Medium, - Large, - XLarge, - XXLarge, - // This is not a real font keyword and will not parse - // HTML font-size 7 corresponds to this value - XXXLarge, +/// Additional information for specified keyword-derived font sizes. +pub type KeywordInfo = GenericKeywordInfo<NonNegativeLength>; + +impl KeywordInfo { + /// Computes the final size for this font-size keyword, accounting for + /// text-zoom. + pub fn to_computed_value(&self, context: &Context) -> NonNegativeLength { + let base = context.maybe_zoom_text(self.kw.to_computed_value(context)); + base.scale_by(self.factor) + context.maybe_zoom_text(self.offset) + } + + /// Given a parent keyword info (self), apply an additional factor/offset to it + pub fn compose(self, factor: f32, offset: NonNegativeLength) -> Self { + KeywordInfo { + kw: self.kw, + factor: self.factor * factor, + offset: self.offset.scale_by(factor) + offset, + } + } } impl KeywordSize { - /// Parse a keyword size + /// Parses a keyword size. pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { try_match_ident_ignore_ascii_case! { input, "xx-small" => Ok(KeywordSize::XXSmall), "x-small" => Ok(KeywordSize::XSmall), "small" => Ok(KeywordSize::Small), "medium" => Ok(KeywordSize::Medium), "large" => Ok(KeywordSize::Large), "x-large" => Ok(KeywordSize::XLarge), "xx-large" => Ok(KeywordSize::XXLarge), } } - - /// Convert to an HTML <font size> value - pub fn html_size(&self) -> u8 { - match *self { - KeywordSize::XXSmall => 0, - KeywordSize::XSmall => 1, - KeywordSize::Small => 2, - KeywordSize::Medium => 3, - KeywordSize::Large => 4, - KeywordSize::XLarge => 5, - KeywordSize::XXLarge => 6, - KeywordSize::XXXLarge => 7, - } - } -} - -impl Default for KeywordSize { - fn default() -> Self { - KeywordSize::Medium - } -} - -impl ToCss for KeywordSize { - fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result - where - W: Write, - { - dest.write_str(match *self { - KeywordSize::XXSmall => "xx-small", - KeywordSize::XSmall => "x-small", - KeywordSize::Small => "small", - KeywordSize::Medium => "medium", - KeywordSize::Large => "large", - KeywordSize::XLarge => "x-large", - KeywordSize::XXLarge => "xx-large", - KeywordSize::XXXLarge => unreachable!("We should never serialize \ - specified values set via - HTML presentation attributes"), - }) - } } /// This is the ratio applied for font-size: larger /// and smaller by both Firefox and Chrome const LARGER_FONT_SIZE_RATIO: f32 = 1.2; /// The default font size. pub const FONT_MEDIUM_PX: i32 = 16; @@ -667,17 +630,17 @@ impl FontSize { } else { None } } #[inline] /// Get initial value for specified font size. pub fn medium() -> Self { - FontSize::Keyword(computed::KeywordInfo::medium()) + FontSize::Keyword(KeywordInfo::medium()) } /// Parses a font-size, with quirks. pub fn parse_quirky<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks ) -> Result<FontSize, ParseError<'i>> { @@ -1940,60 +1903,16 @@ impl Parse for FontLanguageOverride { return Ok(FontLanguageOverride::Normal) } let string = input.expect_string()?; Ok(FontLanguageOverride::Override(string.as_ref().to_owned().into_boxed_str())) } } -/// A font four-character tag, represented as a u32 for convenience. -/// -/// See: -/// https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def -/// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-feature-settings -/// -#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)] -pub struct FontTag(pub u32); - -impl Parse for FontTag { - fn parse<'i, 't>( - _context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - use byteorder::{ReadBytesExt, BigEndian}; - use std::io::Cursor; - - let location = input.current_source_location(); - let tag = input.expect_string()?; - - // allowed strings of length 4 containing chars: <U+20, U+7E> - if tag.len() != 4 || tag.as_bytes().iter().any(|c| *c < b' ' || *c > b'~') { - return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } - - let mut raw = Cursor::new(tag.as_bytes()); - Ok(FontTag(raw.read_u32::<BigEndian>().unwrap())) - } -} - -impl ToCss for FontTag { - fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result - where - W: Write, - { - use byteorder::{BigEndian, ByteOrder}; - use std::str; - - let mut raw = [0u8; 4]; - BigEndian::write_u32(&mut raw, self.0); - str::from_utf8(&raw).unwrap_or_default().to_css(dest) - } -} - /// This property provides low-level control over OpenType or TrueType font /// variations. pub type FontVariationSettings = FontSettings<VariationValue<Number>>; fn parse_one_feature_value<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<Integer, ParseError<'i>> {
--- a/testing/marionette/client/marionette_driver/geckoinstance.py +++ b/testing/marionette/client/marionette_driver/geckoinstance.py @@ -197,27 +197,27 @@ class GeckoInstance(object): else: profile_args = self.profile_args profile_path = profile # If a path to a profile is given then clone it if isinstance(profile_path, basestring): profile_args["path_from"] = profile_path profile_args["path_to"] = tempfile.mkdtemp( - suffix=".{}".format(profile_name or os.path.basename(profile_path)), + suffix=u".{}".format(profile_name or os.path.basename(profile_path)), dir=self.workspace) # The target must not exist yet os.rmdir(profile_args["path_to"]) profile = Profile.clone(**profile_args) # Otherwise create a new profile else: profile_args["profile"] = tempfile.mkdtemp( - suffix=".{}".format(profile_name or "mozrunner"), + suffix=u".{}".format(profile_name or "mozrunner"), dir=self.workspace) profile = Profile(**profile_args) profile.create_new = True if isinstance(self.profile, Profile): self.profile.cleanup() self._profile = profile
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py @@ -2,21 +2,16 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. from __future__ import absolute_import, print_function from marionette_driver.errors import SessionNotCreatedException from marionette_harness import MarionetteTestCase -# Unlike python 3, python 2 doesn't have a proper implementation of realpath or -# samefile for Windows. However this function, which does exactly what we want, -# was added to python 2 to fix an issue with tcl installations and symlinks. -from FixTk import convert_path - class TestCapabilities(MarionetteTestCase): def setUp(self): super(TestCapabilities, self).setUp() self.caps = self.marionette.session_capabilities with self.marionette.using_context("chrome"): self.appinfo = self.marionette.execute_script(""" @@ -57,19 +52,19 @@ class TestCapabilities(MarionetteTestCas self.assertEqual(self.caps["moz:processID"], self.appinfo["processID"]) self.assertEqual(self.marionette.process_id, self.appinfo["processID"]) self.assertIn("moz:profile", self.caps) if self.marionette.instance is not None: if self.caps["browserName"] == "fennec": current_profile = self.marionette.instance.runner.device.app_ctx.remote_profile else: - current_profile = convert_path(self.marionette.instance.runner.profile.profile) - self.assertEqual(convert_path(str(self.caps["moz:profile"])), current_profile) - self.assertEqual(convert_path(str(self.marionette.profile)), current_profile) + current_profile = self.marionette.profile_path + # Bug 1438461 - mozprofile uses lower-case letters even on case-sensitive filesystems + self.assertEqual(self.caps["moz:profile"].lower(), current_profile.lower()) self.assertIn("moz:accessibilityChecks", self.caps) self.assertFalse(self.caps["moz:accessibilityChecks"]) self.assertIn("moz:useNonSpecCompliantPointerOrigin", self.caps) self.assertFalse(self.caps["moz:useNonSpecCompliantPointerOrigin"]) self.assertIn("moz:webdriverClick", self.caps)
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_profile_management.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_profile_management.py @@ -1,8 +1,10 @@ +# coding=UTF-8 + # 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/. from __future__ import absolute_import import os import shutil @@ -167,16 +169,34 @@ class TestSwitchProfileWithoutWorkspace( def test_new_named_profile(self): self.marionette.instance.switch_profile("foobar") self.marionette.start_session() self.assertNotEqual(self.profile_path, self.orig_profile_path) self.assertIn("foobar", self.profile_path) self.assertFalse(os.path.exists(self.orig_profile_path)) + def test_new_named_profile_unicode(self): + """Test using unicode string with 1-4 bytes encoding works.""" + self.marionette.instance.switch_profile(u"$¢€🍪") + self.marionette.start_session() + + self.assertNotEqual(self.profile_path, self.orig_profile_path) + self.assertIn(u"$¢€🍪", self.profile_path) + self.assertFalse(os.path.exists(self.orig_profile_path)) + + def test_new_named_profile_unicode_escape_characters(self): + """Test using escaped unicode string with 1-4 bytes encoding works.""" + self.marionette.instance.switch_profile(u"\u0024\u00A2\u20AC\u1F36A") + self.marionette.start_session() + + self.assertNotEqual(self.profile_path, self.orig_profile_path) + self.assertIn(u"\u0024\u00A2\u20AC\u1F36A", self.profile_path) + self.assertFalse(os.path.exists(self.orig_profile_path)) + def test_clone_existing_profile(self): self.marionette.instance.switch_profile(clone_from=self.external_profile) self.marionette.start_session() self.assertIn(os.path.basename(self.external_profile.profile), self.profile_path) self.assertTrue(os.path.exists(self.external_profile.profile)) def test_replace_with_current_profile(self):
--- a/toolkit/components/extensions/ExtensionSettingsStore.jsm +++ b/toolkit/components/extensions/ExtensionSettingsStore.jsm @@ -83,20 +83,22 @@ function initialize() { dataPostProcessor, }); _initializePromise = _store.load(); } return _initializePromise; } // Test-only method to force reloading of the JSON file. -async function reloadFile(finalize) { - if (finalize) { - await _store.finalize(); +async function reloadFile(saveChanges) { + if (!saveChanges) { + // Disarm the saver so that the current changes are dropped. + _store._saver.disarm(); } + await _store.finalize(); _initializePromise = null; return initialize(); } // Checks that the store is ready and that the requested type exists. function ensureType(type) { if (!_store.dataReady) { throw new Error( @@ -504,17 +506,18 @@ this.ExtensionSettingsStore = { }, /** * Test-only method to force reloading of the JSON file. * * Note that this method simply clears the local variable that stores the * file, so the next time the file is accessed it will be reloaded. * - * @param {boolean} finalize - * When false, skip finalizing the store (writing current state to file). + * @param {boolean} saveChanges + * When false, discard any changes that have been made since the last + * time the store was saved. * @returns {Promise} * A promise that resolves once the settings store has been cleared. */ - _reloadFile(finalize = true) { - return reloadFile(finalize); + _reloadFile(saveChanges = true) { + return reloadFile(saveChanges); }, };