зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to inbound. r=merge a=merge on a CLOSED TREE
This commit is contained in:
Коммит
28f65f2044
|
@ -1481,6 +1481,13 @@ AccessibleWrap::GetIAccessibleFor(const VARIANT& aVarChild, bool* aIsDefunct)
|
|||
// window and the child id points in the content documents. Thus we need to
|
||||
// make sure that it is never called on proxies.
|
||||
if (XRE_IsParentProcess() && !IsProxy() && !sIDGen.IsChromeID(varChild.lVal)) {
|
||||
if (!IsRoot()) {
|
||||
// Bug 1422201: accChild with a remote id is only valid on the root accessible.
|
||||
// Otherwise, we might return remote accessibles which aren't descendants
|
||||
// of this accessible. This would confuse clients which use accChild to
|
||||
// check whether something is a descendant of a document.
|
||||
return nullptr;
|
||||
}
|
||||
return GetRemoteIAccessibleFor(varChild);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,24 +78,24 @@ MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_A
|
|||
.PHONY: repackage
|
||||
tools repackage:: $(DIST)/bin/$(MOZ_APP_NAME) features
|
||||
rm -rf $(dist_dest)
|
||||
$(MKDIR) -p $(dist_dest)/Contents/MacOS
|
||||
$(MKDIR) -p $(dist_dest)/$(LPROJ)
|
||||
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents $(dist_dest) --exclude English.lproj
|
||||
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(dist_dest)/$(LPROJ)
|
||||
sed -e 's/%APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' -e 's/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/' -e 's|%MOZ_DEVELOPER_REPO_PATH%|$(topsrcdir)|' -e 's|%MOZ_DEVELOPER_OBJ_PATH%|$(topobjdir)|' $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
|
||||
sed -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(dist_dest)/$(LPROJ)/InfoPlist.strings
|
||||
rsync -a --exclude-from='$(srcdir)/macbuild/Contents/MacOS-files.in' $(DIST)/bin/ $(dist_dest)/Contents/Resources
|
||||
rsync -a --include-from='$(srcdir)/macbuild/Contents/MacOS-files.in' --exclude '*' $(DIST)/bin/ $(dist_dest)/Contents/MacOS
|
||||
$(RM) $(dist_dest)/Contents/MacOS/$(MOZ_APP_NAME)
|
||||
rsync -aL $(DIST)/bin/$(MOZ_APP_NAME) $(dist_dest)/Contents/MacOS
|
||||
cp -RL $(DIST)/branding/firefox.icns $(dist_dest)/Contents/Resources/firefox.icns
|
||||
cp -RL $(DIST)/branding/document.icns $(dist_dest)/Contents/Resources/document.icns
|
||||
$(MKDIR) -p $(dist_dest)/Contents/Library/LaunchServices
|
||||
$(MKDIR) -p '$(dist_dest)/Contents/MacOS'
|
||||
$(MKDIR) -p '$(dist_dest)/$(LPROJ)'
|
||||
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents '$(dist_dest)' --exclude English.lproj
|
||||
rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents/Resources/English.lproj/ '$(dist_dest)/$(LPROJ)'
|
||||
sed -e 's/%APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' -e 's/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/' -e 's|%MOZ_DEVELOPER_REPO_PATH%|$(topsrcdir)|' -e 's|%MOZ_DEVELOPER_OBJ_PATH%|$(topobjdir)|' $(srcdir)/macbuild/Contents/Info.plist.in > '$(dist_dest)/Contents/Info.plist'
|
||||
sed -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > '$(dist_dest)/$(LPROJ)/InfoPlist.strings'
|
||||
rsync -a --exclude-from='$(srcdir)/macbuild/Contents/MacOS-files.in' $(DIST)/bin/ '$(dist_dest)/Contents/Resources'
|
||||
rsync -a --include-from='$(srcdir)/macbuild/Contents/MacOS-files.in' --exclude '*' $(DIST)/bin/ '$(dist_dest)/Contents/MacOS'
|
||||
$(RM) '$(dist_dest)/Contents/MacOS/$(MOZ_APP_NAME)'
|
||||
rsync -aL $(DIST)/bin/$(MOZ_APP_NAME) '$(dist_dest)/Contents/MacOS'
|
||||
cp -RL $(DIST)/branding/firefox.icns '$(dist_dest)/Contents/Resources/firefox.icns'
|
||||
cp -RL $(DIST)/branding/document.icns '$(dist_dest)/Contents/Resources/document.icns'
|
||||
$(MKDIR) -p '$(dist_dest)/Contents/Library/LaunchServices'
|
||||
ifdef MOZ_UPDATER
|
||||
mv -f $(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater $(dist_dest)/Contents/Library/LaunchServices
|
||||
ln -s ../../../../Library/LaunchServices/org.mozilla.updater $(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater
|
||||
mv -f '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater' '$(dist_dest)/Contents/Library/LaunchServices'
|
||||
ln -s ../../../../Library/LaunchServices/org.mozilla.updater '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater'
|
||||
endif
|
||||
printf APPLMOZB > $(dist_dest)/Contents/PkgInfo
|
||||
printf APPLMOZB > '$(dist_dest)/Contents/PkgInfo'
|
||||
endif
|
||||
|
||||
.PHONY: features
|
||||
|
|
|
@ -582,6 +582,12 @@ pref("privacy.panicButton.enabled", true);
|
|||
// Time until temporary permissions expire, in ms
|
||||
pref("privacy.temporary_permission_expire_time_ms", 3600000);
|
||||
|
||||
// If Accept-Language should be spoofed by en-US
|
||||
// 0 - will prompt
|
||||
// 1 - don't spoof
|
||||
// 2 - spoof
|
||||
pref("privacy.spoof_english", 0);
|
||||
|
||||
pref("network.proxy.share_proxy_settings", false); // use the same proxy settings for all protocols
|
||||
|
||||
// simple gestures support
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
|
||||
<command id="cmd_print" oncommand="PrintUtils.printWindow(window.gBrowser.selectedBrowser.outerWindowID, window.gBrowser.selectedBrowser);"/>
|
||||
<command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
|
||||
<command id="cmd_close" oncommand="BrowserCloseTabOrWindow()"/>
|
||||
<command id="cmd_close" oncommand="BrowserCloseTabOrWindow(event);"/>
|
||||
<command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
|
||||
<command id="cmd_toggleMute" oncommand="gBrowser.selectedTab.toggleMuteAudio()"/>
|
||||
<command id="cmd_CustomizeToolbars" oncommand="gCustomizeMode.enter()"/>
|
||||
|
|
|
@ -34,6 +34,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
E10SUtils: "resource:///modules/E10SUtils.jsm",
|
||||
ExtensionsUI: "resource:///modules/ExtensionsUI.jsm",
|
||||
FormValidationHandler: "resource:///modules/FormValidationHandler.jsm",
|
||||
LanguagePrompt: "resource://gre/modules/LanguagePrompt.jsm",
|
||||
LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
|
||||
Log: "resource://gre/modules/Log.jsm",
|
||||
LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm",
|
||||
|
@ -1821,6 +1822,8 @@ var gBrowserInit = {
|
|||
|
||||
gAccessibilityServiceIndicator.uninit();
|
||||
|
||||
LanguagePrompt.uninit();
|
||||
|
||||
// Now either cancel delayedStartup, or clean up the services initialized from
|
||||
// it.
|
||||
if (this._boundDelayedStartup) {
|
||||
|
@ -2284,33 +2287,6 @@ function BrowserOpenTab(event) {
|
|||
openUILinkIn(BROWSER_NEW_TAB_URL, where, { relatedToCurrent });
|
||||
}
|
||||
|
||||
/* Called from the openLocation dialog. This allows that dialog to instruct
|
||||
its opener to open a new window and then step completely out of the way.
|
||||
Anything less byzantine is causing horrible crashes, rather believably,
|
||||
though oddly only on Linux. */
|
||||
function delayedOpenWindow(chrome, flags, href, postData) {
|
||||
// The other way to use setTimeout,
|
||||
// setTimeout(openDialog, 10, chrome, "_blank", flags, url),
|
||||
// doesn't work here. The extra "magic" extra argument setTimeout adds to
|
||||
// the callback function would confuse gBrowserInit.onLoad() by making
|
||||
// window.arguments[1] be an integer instead of null.
|
||||
setTimeout(function() { openDialog(chrome, "_blank", flags, href, null, null, postData); }, 10);
|
||||
}
|
||||
|
||||
/* Required because the tab needs time to set up its content viewers and get the load of
|
||||
the URI kicked off before becoming the active content area. */
|
||||
function delayedOpenTab(aUrl, aReferrer, aCharset, aPostData, aAllowThirdPartyFixup) {
|
||||
gBrowser.loadOneTab(aUrl, {
|
||||
referrerURI: aReferrer,
|
||||
charset: aCharset,
|
||||
postData: aPostData,
|
||||
inBackground: false,
|
||||
allowThirdPartyFixup: aAllowThirdPartyFixup,
|
||||
// Bug 1367168: only use systemPrincipal till we can remove that function
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
}
|
||||
|
||||
var gLastOpenDirectory = {
|
||||
_lastDir: null,
|
||||
get path() {
|
||||
|
@ -2372,13 +2348,24 @@ function BrowserOpenFileWindow() {
|
|||
}
|
||||
}
|
||||
|
||||
function BrowserCloseTabOrWindow() {
|
||||
// If we're not a browser window, just close the window
|
||||
function BrowserCloseTabOrWindow(event) {
|
||||
// If we're not a browser window, just close the window.
|
||||
if (window.location.href != getBrowserURL()) {
|
||||
closeWindow(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Keyboard shortcuts that would close a tab that is pinned select the first
|
||||
// unpinned tab instead.
|
||||
if (event &&
|
||||
(event.ctrlKey || event.metaKey || event.altKey) &&
|
||||
gBrowser.selectedTab.pinned) {
|
||||
if (gBrowser.visibleTabs.length > gBrowser._numPinnedTabs) {
|
||||
gBrowser.tabContainer.selectedIndex = gBrowser._numPinnedTabs;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If the current tab is the last one, this will close the window.
|
||||
gBrowser.removeCurrentTab({animate: true});
|
||||
}
|
||||
|
@ -2915,7 +2902,6 @@ var BrowserOnClick = {
|
|||
mm.addMessageListener("Browser:OpenCaptivePortalPage", this);
|
||||
mm.addMessageListener("Browser:SiteBlockedError", this);
|
||||
mm.addMessageListener("Browser:EnableOnlineMode", this);
|
||||
mm.addMessageListener("Browser:SendSSLErrorReport", this);
|
||||
mm.addMessageListener("Browser:SetSSLErrorReportAuto", this);
|
||||
mm.addMessageListener("Browser:ResetSSLPreferences", this);
|
||||
mm.addMessageListener("Browser:SSLErrorReportTelemetry", this);
|
||||
|
@ -2930,7 +2916,6 @@ var BrowserOnClick = {
|
|||
mm.removeMessageListener("Browser:CertExceptionError", this);
|
||||
mm.removeMessageListener("Browser:SiteBlockedError", this);
|
||||
mm.removeMessageListener("Browser:EnableOnlineMode", this);
|
||||
mm.removeMessageListener("Browser:SendSSLErrorReport", this);
|
||||
mm.removeMessageListener("Browser:SetSSLErrorReportAuto", this);
|
||||
mm.removeMessageListener("Browser:ResetSSLPreferences", this);
|
||||
mm.removeMessageListener("Browser:SSLErrorReportTelemetry", this);
|
||||
|
@ -2973,11 +2958,6 @@ var BrowserOnClick = {
|
|||
msg.target.reload();
|
||||
}
|
||||
break;
|
||||
case "Browser:SendSSLErrorReport":
|
||||
this.onSSLErrorReport(msg.target,
|
||||
msg.data.uri,
|
||||
msg.data.securityInfo);
|
||||
break;
|
||||
case "Browser:ResetSSLPreferences":
|
||||
let prefSSLImpact = PREF_SSL_IMPACT_ROOTS.reduce((prefs, root) => {
|
||||
return prefs.concat(Services.prefs.getChildList(root));
|
||||
|
@ -3006,23 +2986,6 @@ var BrowserOnClick = {
|
|||
}
|
||||
},
|
||||
|
||||
onSSLErrorReport(browser, uri, securityInfo) {
|
||||
if (!Services.prefs.getBoolPref("security.ssl.errorReporting.enabled")) {
|
||||
Cu.reportError("User requested certificate error report sending, but certificate error reporting is disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
|
||||
.getService(Ci.nsISerializationHelper);
|
||||
let transportSecurityInfo = serhelper.deserializeObject(securityInfo);
|
||||
transportSecurityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||
|
||||
let errorReporter = Cc["@mozilla.org/securityreporter;1"]
|
||||
.getService(Ci.nsISecurityReporter);
|
||||
errorReporter.reportTLSError(transportSecurityInfo,
|
||||
uri.host, uri.port);
|
||||
},
|
||||
|
||||
onCertError(browser, elementId, isTopFrame, location, securityInfoAsString) {
|
||||
let secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
|
||||
let securityInfo;
|
||||
|
@ -3526,15 +3489,6 @@ var PrintPreviewListener = {
|
|||
},
|
||||
};
|
||||
|
||||
function getMarkupDocumentViewer() {
|
||||
return gBrowser.markupDocumentViewer;
|
||||
}
|
||||
|
||||
// This function is obsolete. Newer code should use <tooltip page="true"/> instead.
|
||||
function FillInHTMLTooltip(tipElement) {
|
||||
document.getElementById("aHTMLTooltip").fillInPageTooltip(tipElement);
|
||||
}
|
||||
|
||||
var browserDragAndDrop = {
|
||||
canDropLink: aEvent => Services.droppedLinkHandler.canDropLink(aEvent, true),
|
||||
|
||||
|
@ -6318,20 +6272,6 @@ var gPageStyleMenu = {
|
|||
},
|
||||
};
|
||||
|
||||
/* Legacy global page-style functions */
|
||||
var stylesheetFillPopup = gPageStyleMenu.fillPopup.bind(gPageStyleMenu);
|
||||
function stylesheetSwitchAll(contentWindow, title) {
|
||||
// We ignore the contentWindow param. Add-ons don't appear to use
|
||||
// it, and it's difficult to support in e10s (where it will be a
|
||||
// CPOW).
|
||||
gPageStyleMenu.switchStyleSheet(title);
|
||||
}
|
||||
function setStyleDisabled(disabled) {
|
||||
if (disabled)
|
||||
gPageStyleMenu.disableStyle();
|
||||
}
|
||||
|
||||
|
||||
var LanguageDetectionListener = {
|
||||
init() {
|
||||
window.messageManager.addMessageListener("Translation:DocumentState", msg => {
|
||||
|
|
|
@ -442,14 +442,20 @@ var AboutNetAndCertErrorListener = {
|
|||
automatic: evt.detail
|
||||
});
|
||||
|
||||
// if we're enabling reports, send a report for this failure
|
||||
// If we're enabling reports, send a report for this failure.
|
||||
if (evt.detail) {
|
||||
let {host, port} = content.document.mozDocumentURIIfNotForErrorPages;
|
||||
sendAsyncMessage("Browser:SendSSLErrorReport", {
|
||||
uri: { host, port },
|
||||
securityInfo: getSerializedSecurityInfo(docShell),
|
||||
});
|
||||
let win = evt.originalTarget.ownerGlobal;
|
||||
let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
|
||||
let {securityInfo} = docShell.failedChannel;
|
||||
securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||
let {host, port} = win.document.mozDocumentURIIfNotForErrorPages;
|
||||
|
||||
let errorReporter = Cc["@mozilla.org/securityreporter;1"]
|
||||
.getService(Ci.nsISecurityReporter);
|
||||
errorReporter.reportTLSError(securityInfo, host, port);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -211,42 +211,6 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_setCloseKeyState">
|
||||
<parameter name="aEnabled"/>
|
||||
<body><![CDATA[
|
||||
let keyClose = document.getElementById("key_close");
|
||||
let closeKeyEnabled = keyClose.getAttribute("disabled") != "true";
|
||||
if (closeKeyEnabled == aEnabled)
|
||||
return;
|
||||
|
||||
if (aEnabled)
|
||||
keyClose.removeAttribute("disabled");
|
||||
else
|
||||
keyClose.setAttribute("disabled", "true");
|
||||
|
||||
// We also want to remove the keyboard shortcut from the file menu
|
||||
// when the shortcut is disabled, and bring it back when it's
|
||||
// renabled.
|
||||
//
|
||||
// Fixing bug 630826 could make that happen automatically.
|
||||
// Fixing bug 630830 could avoid the ugly hack below.
|
||||
|
||||
let closeMenuItem = document.getElementById("menu_close");
|
||||
let parentPopup = closeMenuItem.parentNode;
|
||||
let nextItem = closeMenuItem.nextSibling;
|
||||
let clonedItem = closeMenuItem.cloneNode(true);
|
||||
|
||||
parentPopup.removeChild(closeMenuItem);
|
||||
|
||||
if (aEnabled)
|
||||
clonedItem.setAttribute("key", "key_close");
|
||||
else
|
||||
clonedItem.removeAttribute("key");
|
||||
|
||||
parentPopup.insertBefore(clonedItem, nextItem);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="pinTab">
|
||||
<parameter name="aTab"/>
|
||||
<body><![CDATA[
|
||||
|
@ -264,9 +228,6 @@
|
|||
|
||||
this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: true });
|
||||
|
||||
if (aTab.selected)
|
||||
this._setCloseKeyState(false);
|
||||
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("TabPinned", true, false);
|
||||
aTab.dispatchEvent(event);
|
||||
|
@ -288,9 +249,6 @@
|
|||
|
||||
this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: false });
|
||||
|
||||
if (aTab.selected)
|
||||
this._setCloseKeyState(true);
|
||||
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("TabUnpinned", true, false);
|
||||
aTab.dispatchEvent(event);
|
||||
|
@ -1371,8 +1329,6 @@
|
|||
true, false);
|
||||
}
|
||||
|
||||
this._setCloseKeyState(!this.mCurrentTab.pinned);
|
||||
|
||||
// TabSelect events are suppressed during preview mode to avoid confusing extensions and other bits of code
|
||||
// that might rely upon the other changes suppressed.
|
||||
// Focus is suppressed in the event that the main browser window is minimized - focusing a tab would restore the window
|
||||
|
@ -4427,16 +4383,26 @@
|
|||
let {tabParent} = browser.frameLoader;
|
||||
if (state == this.STATE_LOADING) {
|
||||
this.assert(!this.minimizedOrFullyOccluded);
|
||||
browser.docShellIsActive = true;
|
||||
if (!tabParent) {
|
||||
|
||||
if (!this.tabbrowser.tabWarmingEnabled) {
|
||||
browser.docShellIsActive = true;
|
||||
}
|
||||
|
||||
if (tabParent) {
|
||||
browser.renderLayers = true;
|
||||
} else {
|
||||
this.onLayersReady(browser);
|
||||
}
|
||||
} else if (state == this.STATE_UNLOADING) {
|
||||
this.unwarmTab(tab);
|
||||
// Setting the docShell to be inactive will also cause it
|
||||
// to stop rendering layers.
|
||||
browser.docShellIsActive = false;
|
||||
if (!tabParent) {
|
||||
this.onLayersCleared(browser);
|
||||
}
|
||||
} else if (state == this.STATE_LOADED) {
|
||||
this.maybeActivateDocShell(tab);
|
||||
}
|
||||
|
||||
if (!tab.linkedBrowser.isRemoteBrowser) {
|
||||
|
@ -4461,11 +4427,6 @@
|
|||
init() {
|
||||
this.log("START");
|
||||
|
||||
// If we minimized the window before the switcher was activated,
|
||||
// we might have set the preserveLayers flag for the current
|
||||
// browser. Let's clear it.
|
||||
this.tabbrowser.mCurrentBrowser.preserveLayers(false);
|
||||
|
||||
window.addEventListener("MozAfterPaint", this);
|
||||
window.addEventListener("MozLayerTreeReady", this);
|
||||
window.addEventListener("MozLayerTreeCleared", this);
|
||||
|
@ -4475,16 +4436,30 @@
|
|||
window.addEventListener("SwapDocShells", this, true);
|
||||
window.addEventListener("EndSwapDocShells", this, true);
|
||||
|
||||
let tab = this.requestedTab;
|
||||
let browser = tab.linkedBrowser;
|
||||
let tabIsLoaded = !browser.isRemoteBrowser ||
|
||||
browser.frameLoader.tabParent.hasPresented;
|
||||
let initialTab = this.requestedTab;
|
||||
|
||||
if (!this.minimizedOrFullyOccluded) {
|
||||
this.log("Initial tab is loaded?: " + tabIsLoaded);
|
||||
this.setTabState(tab, tabIsLoaded ? this.STATE_LOADED
|
||||
: this.STATE_LOADING);
|
||||
for (let tab of this.tabbrowser.tabs) {
|
||||
if (tab == initialTab && this.minimizedOrFullyOccluded) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tab.linkedPanel) {
|
||||
let b = tab.linkedBrowser;
|
||||
let state;
|
||||
if (b.renderLayers && b.hasLayers) {
|
||||
state = this.STATE_LOADED;
|
||||
} else if (b.renderLayers && !b.hasLayers) {
|
||||
state = this.STATE_LOADING;
|
||||
} else if (!b.renderLayers && b.hasLayers) {
|
||||
state = this.STATE_UNLOADING;
|
||||
} else {
|
||||
state = this.STATE_UNLOADED;
|
||||
}
|
||||
|
||||
this.setTabState(tab, state);
|
||||
}
|
||||
}
|
||||
this.logState("Tab states initialized");
|
||||
},
|
||||
|
||||
destroy() {
|
||||
|
@ -4663,6 +4638,8 @@
|
|||
} else {
|
||||
this.tabbrowser._adjustFocusAfterTabSwitch(showTab);
|
||||
}
|
||||
|
||||
this.maybeActivateDocShell(this.requestedTab);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4701,6 +4678,29 @@
|
|||
this.setTabState(this.requestedTab, this.STATE_LOADING);
|
||||
},
|
||||
|
||||
maybeActivateDocShell(tab) {
|
||||
// If we've reached the point where the requested tab has entered
|
||||
// the loaded state, but the DocShell is still not yet active, we
|
||||
// should activate it.
|
||||
let browser = tab.linkedBrowser;
|
||||
let state = this.getTabState(tab);
|
||||
let canCheckDocShellState = !browser.mDestroyed &&
|
||||
(browser.docShell ||
|
||||
browser.frameLoader.tabParent);
|
||||
if (tab == this.requestedTab &&
|
||||
canCheckDocShellState &&
|
||||
state == this.STATE_LOADED &&
|
||||
!browser.docShellIsActive &&
|
||||
!this.minimizedOrFullyOccluded) {
|
||||
browser.docShellIsActive = true;
|
||||
this.logState("Set requested tab docshell to active and preserveLayers to false");
|
||||
// If we minimized the window before the switcher was activated,
|
||||
// we might have set the preserveLayers flag for the current
|
||||
// browser. Let's clear it.
|
||||
browser.preserveLayers(false);
|
||||
}
|
||||
},
|
||||
|
||||
// This function runs before every event. It fixes up the state
|
||||
// to account for closed tabs.
|
||||
preActions() {
|
||||
|
@ -4869,6 +4869,13 @@
|
|||
// Fires when the layers become available for a tab.
|
||||
onLayersReady(browser) {
|
||||
let tab = this.tabbrowser.getTabForBrowser(browser);
|
||||
if (!tab) {
|
||||
// We probably got a layer update from a tab that got before
|
||||
// the switcher was created, or for browser that's not being
|
||||
// tracked by the async tab switcher (like the preloaded about:newtab).
|
||||
return;
|
||||
}
|
||||
|
||||
this.logState(`onLayersReady(${tab._tPos}, ${browser.isRemoteBrowser})`);
|
||||
|
||||
this.assert(this.getTabState(tab) == this.STATE_LOADING ||
|
||||
|
@ -5014,7 +5021,12 @@
|
|||
|
||||
activateBrowserForPrintPreview(browser) {
|
||||
let tab = this.tabbrowser.getTabForBrowser(browser);
|
||||
this.setTabState(tab, this.STATE_LOADING);
|
||||
let state = this.getTabState(tab);
|
||||
if (state != this.STATE_LOADING &&
|
||||
state != this.STATE_LOADED) {
|
||||
this.setTabState(tab, this.STATE_LOADING);
|
||||
this.logState("Activated browser " + this.tinfo(tab) + " for print preview");
|
||||
}
|
||||
},
|
||||
|
||||
canWarmTab(tab) {
|
||||
|
|
|
@ -216,8 +216,6 @@ skip-if = toolkit != "cocoa" # Because of tests for supporting pasting from Serv
|
|||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_bug579872.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_bug580638.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_bug580956.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_bug581242.js]
|
||||
|
@ -382,8 +380,6 @@ support-files = test_offline_gzip.html gZipOfflineChild.cacheManifest gZipOfflin
|
|||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_page_style_menu_update.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_pinnedTabs.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_plainTextLinks.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_printpreview.js]
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
function testState(aPinned) {
|
||||
function elemAttr(id, attr) {
|
||||
return document.getElementById(id).getAttribute(attr);
|
||||
}
|
||||
|
||||
if (aPinned) {
|
||||
is(elemAttr("key_close", "disabled"), "true",
|
||||
"key_close should be disabled when a pinned-tab is selected");
|
||||
is(elemAttr("menu_close", "key"), "",
|
||||
"menu_close shouldn't have a key set when a pinned is selected");
|
||||
} else {
|
||||
is(elemAttr("key_close", "disabled"), "",
|
||||
"key_closed shouldn't have disabled state set when a non-pinned tab is selected");
|
||||
is(elemAttr("menu_close", "key"), "key_close",
|
||||
"menu_close should have key_close set as its key when a non-pinned tab is selected");
|
||||
}
|
||||
}
|
||||
|
||||
let lastSelectedTab = gBrowser.selectedTab;
|
||||
ok(!lastSelectedTab.pinned, "We should have started with a regular tab selected");
|
||||
|
||||
testState(false);
|
||||
|
||||
let pinnedTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
|
||||
gBrowser.pinTab(pinnedTab);
|
||||
|
||||
// Just pinning the tab shouldn't change the key state.
|
||||
testState(false);
|
||||
|
||||
// Test updating key state after selecting a tab.
|
||||
gBrowser.selectedTab = pinnedTab;
|
||||
testState(true);
|
||||
|
||||
gBrowser.selectedTab = lastSelectedTab;
|
||||
testState(false);
|
||||
|
||||
gBrowser.selectedTab = pinnedTab;
|
||||
testState(true);
|
||||
|
||||
// Test updating the key state after un/pinning the tab.
|
||||
gBrowser.unpinTab(pinnedTab);
|
||||
testState(false);
|
||||
|
||||
gBrowser.pinTab(pinnedTab);
|
||||
testState(true);
|
||||
|
||||
// Test updating the key state after removing the tab.
|
||||
gBrowser.removeTab(pinnedTab);
|
||||
testState(false);
|
||||
|
||||
finish();
|
||||
}
|
|
@ -20,6 +20,9 @@ var gExceptionPaths = [
|
|||
"resource://gre/defaults/pref/",
|
||||
"resource://shield-recipe-client/node_modules/jexl/lib/",
|
||||
|
||||
// These resources are referenced using relative paths from html files.
|
||||
"resource://payments/",
|
||||
|
||||
// https://github.com/mozilla/normandy/issues/577
|
||||
"resource://shield-recipe-client/test/",
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ skip-if = !e10s # Test only relevant for e10s.
|
|||
skip-if = !e10s # Pref and test only relevant for e10s.
|
||||
[browser_opened_file_tab_navigated_to_web.js]
|
||||
[browser_overflowScroll.js]
|
||||
[browser_pinnedTabs.js]
|
||||
[browser_pinnedTabs_closeByKeyboard.js]
|
||||
[browser_positional_attributes.js]
|
||||
[browser_preloadedBrowser_zoom.js]
|
||||
[browser_reload_deleted_file.js]
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/* 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/. */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
function testState(aPinned) {
|
||||
function elemAttr(id, attr) {
|
||||
return document.getElementById(id).getAttribute(attr);
|
||||
}
|
||||
|
||||
is(elemAttr("key_close", "disabled"), "",
|
||||
"key_closed should always be enabled");
|
||||
is(elemAttr("menu_close", "key"), "key_close",
|
||||
"menu_close should always have key_close set");
|
||||
}
|
||||
|
||||
let unpinnedTab = gBrowser.selectedTab;
|
||||
ok(!unpinnedTab.pinned, "We should have started with a regular tab selected");
|
||||
|
||||
testState(false);
|
||||
|
||||
let pinnedTab = gBrowser.addTab();
|
||||
gBrowser.pinTab(pinnedTab);
|
||||
|
||||
// Just pinning the tab shouldn't change the key state.
|
||||
testState(false);
|
||||
|
||||
// Test key state after selecting a tab.
|
||||
gBrowser.selectedTab = pinnedTab;
|
||||
testState(true);
|
||||
|
||||
gBrowser.selectedTab = unpinnedTab;
|
||||
testState(false);
|
||||
|
||||
gBrowser.selectedTab = pinnedTab;
|
||||
testState(true);
|
||||
|
||||
// Test the key state after un/pinning the tab.
|
||||
gBrowser.unpinTab(pinnedTab);
|
||||
testState(false);
|
||||
|
||||
gBrowser.pinTab(pinnedTab);
|
||||
testState(true);
|
||||
|
||||
// Test that accel+w in a pinned tab selects the next tab.
|
||||
let pinnedTab2 = gBrowser.addTab();
|
||||
gBrowser.pinTab(pinnedTab2);
|
||||
gBrowser.selectedTab = pinnedTab;
|
||||
|
||||
EventUtils.synthesizeKey("w", { accelKey: true });
|
||||
is(gBrowser.tabs.length, 3, "accel+w in a pinned tab didn't close it");
|
||||
is(gBrowser.selectedTab, unpinnedTab, "accel+w in a pinned tab selected the first unpinned tab");
|
||||
|
||||
// Test the key state after removing the tab.
|
||||
gBrowser.removeTab(pinnedTab);
|
||||
gBrowser.removeTab(pinnedTab2);
|
||||
testState(false);
|
||||
|
||||
finish();
|
||||
}
|
|
@ -3,7 +3,10 @@
|
|||
/* global gBrowser SessionStore */
|
||||
"use strict";
|
||||
|
||||
let lazyTabState = {entries: [{url: "http://example.com/", title: "Example Domain"}]};
|
||||
const {Utils} = Cu.import("resource://gre/modules/sessionstore/Utils.jsm", {});
|
||||
const triggeringPrincipal_base64 = Utils.SERIALIZED_SYSTEMPRINCIPAL;
|
||||
|
||||
let lazyTabState = {entries: [{url: "http://example.com/", triggeringPrincipal_base64, title: "Example Domain"}]};
|
||||
|
||||
add_task(async function test_discarded() {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
const {Utils} = Cu.import("resource://gre/modules/sessionstore/Utils.jsm", {});
|
||||
const triggeringPrincipal_base64 = Utils.SERIALIZED_SYSTEMPRINCIPAL;
|
||||
|
||||
const SESSION = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{entries: [{url: "about:blank"}]},
|
||||
{entries: [{url: "https://example.com/"}]},
|
||||
{entries: [{url: "about:blank", triggeringPrincipal_base64}]},
|
||||
{entries: [{url: "https://example.com/", triggeringPrincipal_base64}]},
|
||||
],
|
||||
}],
|
||||
};
|
||||
|
|
|
@ -41,6 +41,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
FormValidationHandler: "resource:///modules/FormValidationHandler.jsm",
|
||||
Integration: "resource://gre/modules/Integration.jsm",
|
||||
L10nRegistry: "resource://gre/modules/L10nRegistry.jsm",
|
||||
LanguagePrompt: "resource://gre/modules/LanguagePrompt.jsm",
|
||||
LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
|
||||
LoginHelper: "resource://gre/modules/LoginHelper.jsm",
|
||||
LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm",
|
||||
|
@ -1166,6 +1167,10 @@ BrowserGlue.prototype = {
|
|||
JawsScreenReaderVersionCheck.onWindowsRestored();
|
||||
});
|
||||
}
|
||||
|
||||
Services.tm.idleDispatchToMainThread(() => {
|
||||
LanguagePrompt.init();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "ExtensionSettingsStore",
|
|||
"resource://gre/modules/ExtensionSettingsStore.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
|
||||
"resource://gre/modules/AddonManager.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "formAutofillParent",
|
||||
"resource://formautofill/FormAutofillParent.jsm");
|
||||
|
||||
var gLastHash = "";
|
||||
|
||||
|
@ -174,17 +176,19 @@ function gotoPref(aCategory) {
|
|||
categories.clearSelection();
|
||||
}
|
||||
window.history.replaceState(category, document.title);
|
||||
search(category, "data-category", subcategory, "data-subcategory");
|
||||
search(category, "data-category");
|
||||
|
||||
let mainContent = document.querySelector(".main-content");
|
||||
mainContent.scrollTop = 0;
|
||||
|
||||
spotlight(subcategory);
|
||||
|
||||
Services.telemetry
|
||||
.getHistogramById("FX_PREFERENCES_CATEGORY_OPENED_V2")
|
||||
.add(telemetryBucketForCategory(friendlyName));
|
||||
}
|
||||
|
||||
function search(aQuery, aAttribute, aSubquery, aSubAttribute) {
|
||||
function search(aQuery, aAttribute) {
|
||||
let mainPrefPane = document.getElementById("mainPrefPane");
|
||||
let elements = mainPrefPane.children;
|
||||
for (let element of elements) {
|
||||
|
@ -196,14 +200,7 @@ function search(aQuery, aAttribute, aSubquery, aSubAttribute) {
|
|||
element.getAttribute("data-subpanel") == "true") {
|
||||
let attributeValue = element.getAttribute(aAttribute);
|
||||
if (attributeValue == aQuery) {
|
||||
if (!element.classList.contains("header") &&
|
||||
element.localName !== "preferences" &&
|
||||
aSubquery && aSubAttribute) {
|
||||
let subAttributeValue = element.getAttribute(aSubAttribute);
|
||||
element.hidden = subAttributeValue != aSubquery;
|
||||
} else {
|
||||
element.hidden = false;
|
||||
}
|
||||
element.hidden = false;
|
||||
} else {
|
||||
element.hidden = true;
|
||||
}
|
||||
|
@ -221,6 +218,106 @@ function search(aQuery, aAttribute, aSubquery, aSubAttribute) {
|
|||
}
|
||||
}
|
||||
|
||||
async function spotlight(subcategory) {
|
||||
let highlightedElements = document.querySelectorAll(".spotlight");
|
||||
if (highlightedElements.length) {
|
||||
for (let element of highlightedElements) {
|
||||
element.classList.remove("spotlight");
|
||||
}
|
||||
}
|
||||
if (subcategory) {
|
||||
if (!gSearchResultsPane.categoriesInitialized) {
|
||||
await waitForSystemAddonInjectionsFinished([{
|
||||
isGoingToInject: formAutofillParent.initialized,
|
||||
elementId: "formAutofillGroup",
|
||||
}]);
|
||||
}
|
||||
scrollAndHighlight(subcategory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for system addons finished their dom injections.
|
||||
* @param {Array} addons - The system addon information array.
|
||||
* For example, the element is looked like
|
||||
* { isGoingToInject: true, elementId: "formAutofillGroup" }.
|
||||
* The `isGoingToInject` means the system addon will be visible or not,
|
||||
* and the `elementId` means the id of the element will be injected into the dom
|
||||
* if the `isGoingToInject` is true.
|
||||
* @returns {Promise} Will resolve once all injections are finished.
|
||||
*/
|
||||
function waitForSystemAddonInjectionsFinished(addons) {
|
||||
return new Promise(resolve => {
|
||||
let elementIdSet = new Set();
|
||||
for (let addon of addons) {
|
||||
if (addon.isGoingToInject) {
|
||||
elementIdSet.add(addon.elementId);
|
||||
}
|
||||
}
|
||||
if (elementIdSet.size) {
|
||||
let observer = new MutationObserver(mutations => {
|
||||
for (let mutation of mutations) {
|
||||
for (let node of mutation.addedNodes) {
|
||||
elementIdSet.delete(node.id);
|
||||
if (elementIdSet.size === 0) {
|
||||
observer.disconnect();
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
let mainContent = document.querySelector(".main-content");
|
||||
observer.observe(mainContent, {childList: true, subtree: true});
|
||||
// Disconnect the mutation observer once there is any user input.
|
||||
mainContent.addEventListener("scroll", disconnectMutationObserver);
|
||||
window.addEventListener("mousedown", disconnectMutationObserver);
|
||||
window.addEventListener("keydown", disconnectMutationObserver);
|
||||
function disconnectMutationObserver() {
|
||||
mainContent.removeEventListener("scroll", disconnectMutationObserver);
|
||||
window.removeEventListener("mousedown", disconnectMutationObserver);
|
||||
window.removeEventListener("keydown", disconnectMutationObserver);
|
||||
observer.disconnect();
|
||||
}
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function scrollAndHighlight(subcategory) {
|
||||
let element = document.querySelector(`[data-subcategory="${subcategory}"]`);
|
||||
if (element) {
|
||||
let header = getClosestDisplayedHeader(element);
|
||||
scrollContentTo(header);
|
||||
element.classList.add("spotlight");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is no visible second level header it will return first level header,
|
||||
* otherwise return second level header.
|
||||
* @returns {Element} - The closest displayed header.
|
||||
*/
|
||||
function getClosestDisplayedHeader(element) {
|
||||
let header = element.closest("groupbox");
|
||||
let searchHeader = header.querySelector("caption.search-header");
|
||||
if (searchHeader && searchHeader.hidden &&
|
||||
header.previousSibling.classList.contains("subcategory")) {
|
||||
header = header.previousSibling;
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
function scrollContentTo(element) {
|
||||
const SEARCH_CONTAINER_HEIGHT = document.querySelector(".search-container").clientHeight;
|
||||
let mainContent = document.querySelector(".main-content");
|
||||
let top = element.getBoundingClientRect().top - SEARCH_CONTAINER_HEIGHT;
|
||||
mainContent.scroll({
|
||||
top,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
|
||||
function helpButtonCommand() {
|
||||
let pane = history.state;
|
||||
let categories = document.getElementById("categories");
|
||||
|
|
|
@ -707,20 +707,19 @@
|
|||
<hbox id="dataCollectionCategory"
|
||||
class="subcategory"
|
||||
hidden="true"
|
||||
data-category="panePrivacy"
|
||||
data-subcategory="reports">
|
||||
data-category="panePrivacy">
|
||||
<label class="header-name" flex="1">&dataCollection.label;</label>
|
||||
</hbox>
|
||||
|
||||
<!-- Firefox Data Collection and Use -->
|
||||
#ifdef MOZ_DATA_REPORTING
|
||||
<groupbox id="dataCollectionGroup" data-category="panePrivacy" data-subcategory="reports" hidden="true">
|
||||
<groupbox id="dataCollectionGroup" data-category="panePrivacy" hidden="true">
|
||||
<caption class="search-header" hidden="true"><label>&dataCollection.label;</label></caption>
|
||||
|
||||
<vbox>
|
||||
<description>
|
||||
<label class="tail-with-learn-more">&dataCollectionDesc.label;</label><label id="dataCollectionPrivacyNotice" class="learnMore text-link">&dataCollectionPrivacyNotice.label;</label>
|
||||
</description>
|
||||
<description>
|
||||
<label class="tail-with-learn-more">&dataCollectionDesc.label;</label><label id="dataCollectionPrivacyNotice" class="learnMore text-link">&dataCollectionPrivacyNotice.label;</label>
|
||||
</description>
|
||||
<vbox data-subcategory="reports">
|
||||
<description flex="1">
|
||||
<checkbox id="submitHealthReportBox" label="&enableHealthReport2.label;"
|
||||
class="tail-with-learn-more"
|
||||
|
@ -731,18 +730,19 @@
|
|||
#ifndef MOZ_TELEMETRY_REPORTING
|
||||
<description id="TelemetryDisabledDesc" class="indent tip-caption" control="telemetryGroup">&healthReportingDisabled.label;</description>
|
||||
#endif
|
||||
</vbox>
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
<hbox align="center">
|
||||
<checkbox id="automaticallySubmitCrashesBox"
|
||||
class="tail-with-learn-more"
|
||||
preference="browser.crashReports.unsubmittedCheck.autoSubmit"
|
||||
label="&alwaysSubmitCrashReports1.label;"
|
||||
accesskey="&alwaysSubmitCrashReports1.accesskey;"/>
|
||||
<label id="crashReporterLearnMore"
|
||||
class="learnMore text-link">&crashReporterLearnMore.label;</label>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<checkbox id="automaticallySubmitCrashesBox"
|
||||
class="tail-with-learn-more"
|
||||
preference="browser.crashReports.unsubmittedCheck.autoSubmit"
|
||||
label="&alwaysSubmitCrashReports1.label;"
|
||||
accesskey="&alwaysSubmitCrashReports1.accesskey;"/>
|
||||
<label id="crashReporterLearnMore"
|
||||
class="learnMore text-link">&crashReporterLearnMore.label;</label>
|
||||
</hbox>
|
||||
#endif
|
||||
</vbox>
|
||||
</groupbox>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ skip-if = e10s
|
|||
[browser_siteData.js]
|
||||
[browser_siteData2.js]
|
||||
[browser_siteData3.js]
|
||||
[browser_spotlight.js]
|
||||
[browser_site_login_exceptions.js]
|
||||
[browser_permissions_dialog.js]
|
||||
[browser_cookies_dialog.js]
|
||||
|
|
|
@ -56,7 +56,6 @@ const mockUpdateManager = {
|
|||
name: "Firefox Developer Edition 49.0a2",
|
||||
statusText: "The Update was successfully installed",
|
||||
buildID: "20160728004010",
|
||||
type: "minor",
|
||||
installDate: 1469763105156,
|
||||
detailsURL: "https://www.mozilla.org/firefox/aurora/"
|
||||
},
|
||||
|
@ -64,7 +63,6 @@ const mockUpdateManager = {
|
|||
name: "Firefox Developer Edition 43.0a2",
|
||||
statusText: "The Update was successfully installed",
|
||||
buildID: "20150929004011",
|
||||
type: "minor",
|
||||
installDate: 1443585886224,
|
||||
detailsURL: "https://www.mozilla.org/firefox/aurora/"
|
||||
},
|
||||
|
@ -72,7 +70,6 @@ const mockUpdateManager = {
|
|||
name: "Firefox Developer Edition 42.0a2",
|
||||
statusText: "The Update was successfully installed",
|
||||
buildID: "20150920004018",
|
||||
type: "major",
|
||||
installDate: 1442818147544,
|
||||
detailsURL: "https://www.mozilla.org/firefox/aurora/"
|
||||
}
|
||||
|
@ -146,7 +143,6 @@ add_task(async function() {
|
|||
updateData = mockUpdateManager.getUpdateAt(i);
|
||||
|
||||
is(update.name, updateData.name + " (" + updateData.buildID + ")", "Wrong update name");
|
||||
is(update.type, updateData.type == "major" ? "New Version" : "Security Update", "Wrong update type");
|
||||
is(update.installDate, formatInstallDate(updateData.installDate), "Wrong update installDate");
|
||||
is(update.detailsURL, updateData.detailsURL, "Wrong update detailsURL");
|
||||
is(update.status, updateData.statusText, "Wrong update status");
|
||||
|
|
|
@ -25,7 +25,8 @@ add_task(async function() {
|
|||
is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected by default");
|
||||
let doc = gBrowser.contentDocument;
|
||||
is(doc.location.hash, "#privacy", "The subcategory should be removed from the URI");
|
||||
ok(doc.querySelector("#locationBarGroup").hidden, "Location Bar prefs should be hidden when only Reports are requested");
|
||||
await TestUtils.waitForCondition(() => doc.querySelector(".spotlight"), "Wait for the reports section is spotlighted.");
|
||||
is(doc.querySelector(".spotlight").getAttribute("data-subcategory"), "reports", "The reports section is spotlighted.");
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
|
@ -43,7 +44,8 @@ add_task(async function() {
|
|||
let selectedPane = gBrowser.contentWindow.history.state;
|
||||
is(selectedPane, "panePrivacy", "Privacy pane should be selected");
|
||||
is(doc.location.hash, "#privacy", "The subcategory should be removed from the URI");
|
||||
ok(doc.querySelector("#locationBarGroup").hidden, "Location Bar prefs should be hidden when only Reports are requested");
|
||||
await TestUtils.waitForCondition(() => doc.querySelector(".spotlight"), "Wait for the reports section is spotlighted.");
|
||||
is(doc.querySelector(".spotlight").getAttribute("data-subcategory"), "reports", "The reports section is spotlighted.");
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/* eslint-disable mozilla/no-cpows-in-tests */
|
||||
|
||||
add_task(async function test_reports_section() {
|
||||
let prefs = await openPreferencesViaOpenPreferencesAPI("privacy-reports", {leaveOpen: true});
|
||||
is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected by default");
|
||||
let doc = gBrowser.contentDocument;
|
||||
is(doc.location.hash, "#privacy", "The subcategory should be removed from the URI");
|
||||
await TestUtils.waitForCondition(() => doc.querySelector(".spotlight"),
|
||||
"Wait for the reports section is spotlighted.");
|
||||
is(doc.querySelector(".spotlight").getAttribute("data-subcategory"), "reports",
|
||||
"The reports section is spotlighted.");
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
add_task(async function test_address_autofill_section() {
|
||||
let prefs = await openPreferencesViaOpenPreferencesAPI("privacy-address-autofill", {leaveOpen: true});
|
||||
is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected by default");
|
||||
let doc = gBrowser.contentDocument;
|
||||
is(doc.location.hash, "#privacy", "The subcategory should be removed from the URI");
|
||||
await TestUtils.waitForCondition(() => doc.querySelector(".spotlight"),
|
||||
"Wait for the ddress-autofill section is spotlighted.");
|
||||
is(doc.querySelector(".spotlight").getAttribute("data-subcategory"), "address-autofill",
|
||||
"The ddress-autofill section is spotlighted.");
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
add_task(async function test_credit_card_autofill_section() {
|
||||
let prefs = await openPreferencesViaOpenPreferencesAPI("privacy-credit-card-autofill", {leaveOpen: true});
|
||||
is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected by default");
|
||||
let doc = gBrowser.contentDocument;
|
||||
is(doc.location.hash, "#privacy", "The subcategory should be removed from the URI");
|
||||
await TestUtils.waitForCondition(() => doc.querySelector(".spotlight"),
|
||||
"Wait for the credit-card-autofill section is spotlighted.");
|
||||
is(doc.querySelector(".spotlight").getAttribute("data-subcategory"), "credit-card-autofill",
|
||||
"The credit-card-autofill section is spotlighted.");
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
|
@ -3,6 +3,8 @@
|
|||
* 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/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var gLanguagesDialog = {
|
||||
|
||||
_availableLanguagesList: [],
|
||||
|
@ -149,6 +151,10 @@ var gLanguagesDialog = {
|
|||
this._activeLanguages.selectedIndex = selectedIndex;
|
||||
}
|
||||
|
||||
// Update states of accept-language list and buttons according to
|
||||
// privacy.resistFingerprinting and privacy.spoof_english.
|
||||
this.readSpoofEnglish();
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
|
@ -157,8 +163,10 @@ var gLanguagesDialog = {
|
|||
},
|
||||
|
||||
onAvailableLanguageSelect() {
|
||||
var availableLanguages = this._availableLanguages;
|
||||
var addButton = document.getElementById("addButton");
|
||||
addButton.disabled = false;
|
||||
addButton.disabled = availableLanguages.disabled ||
|
||||
availableLanguages.selectedIndex < 0;
|
||||
|
||||
this._availableLanguages.removeAttribute("accesskey");
|
||||
},
|
||||
|
@ -291,6 +299,40 @@ var gLanguagesDialog = {
|
|||
downButton.disabled = true;
|
||||
removeButton.disabled = false;
|
||||
}
|
||||
},
|
||||
|
||||
readSpoofEnglish() {
|
||||
var checkbox = document.getElementById("spoofEnglish");
|
||||
var resistFingerprinting = Services.prefs.getBoolPref("privacy.resistFingerprinting");
|
||||
if (!resistFingerprinting) {
|
||||
checkbox.hidden = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
var spoofEnglish = document.getElementById("privacy.spoof_english").value;
|
||||
var activeLanguages = this._activeLanguages;
|
||||
var availableLanguages = this._availableLanguages;
|
||||
checkbox.hidden = false;
|
||||
switch (spoofEnglish) {
|
||||
case 1: // don't spoof intl.accept_lanauges
|
||||
activeLanguages.disabled = false;
|
||||
activeLanguages.selectItem(activeLanguages.firstChild);
|
||||
availableLanguages.disabled = false;
|
||||
this.onAvailableLanguageSelect();
|
||||
return false;
|
||||
case 2: // spoof intl.accept_lanauges
|
||||
activeLanguages.clearSelection();
|
||||
activeLanguages.disabled = true;
|
||||
availableLanguages.disabled = true;
|
||||
this.onAvailableLanguageSelect();
|
||||
return true;
|
||||
default: // will prompt for spoofing intl.accept_lanauges if resisting fingerprinting
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
writeSpoofEnglish() {
|
||||
return document.getElementById("spoofEnglish").checked ? 2 : 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
<preference id="pref.browser.language.disable_button.remove"
|
||||
name="pref.browser.language.disable_button.remove"
|
||||
type="bool"/>
|
||||
<preference id="privacy.spoof_english"
|
||||
name="privacy.spoof_english"
|
||||
type="int"/>
|
||||
</preferences>
|
||||
|
||||
<script type="application/javascript" src="chrome://browser/content/preferences/languages.js"/>
|
||||
|
@ -52,6 +55,11 @@
|
|||
</stringbundleset>
|
||||
|
||||
<description>&languages.customize2.description;</description>
|
||||
<checkbox id="spoofEnglish"
|
||||
label="&languages.customize.spoofEnglish;"
|
||||
preference="privacy.spoof_english"
|
||||
onsyncfrompreference="return gLanguagesDialog.readSpoofEnglish();"
|
||||
onsynctopreference="return gLanguagesDialog.writeSpoofEnglish();"/>
|
||||
<grid flex="1">
|
||||
<columns>
|
||||
<column flex="1"/>
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
const TEST_STATE = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com" }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: "http://example.com", triggeringPrincipal_base64 }] },
|
||||
]
|
||||
}]
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ const TEST_STATE = {
|
|||
const TEST_STATE_2 = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:robots" }]
|
||||
{ entries: [{ url: "about:robots", triggeringPrincipal_base64 }]
|
||||
},
|
||||
{ entries: [],
|
||||
userTypedValue: "http://example.com",
|
||||
|
|
|
@ -40,10 +40,10 @@ add_task(async function() {
|
|||
await promiseBrowserState({
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: REMOTE_URL }] },
|
||||
{ entries: [{ url: ABOUT_ROBOTS_URI }] },
|
||||
{ entries: [{ url: REMOTE_URL }] },
|
||||
{ entries: [{ url: NO_TITLE_URL }] },
|
||||
{ entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: ABOUT_ROBOTS_URI, triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] },
|
||||
{ entries: [{ url: NO_TITLE_URL, triggeringPrincipal_base64 }] },
|
||||
]
|
||||
}]
|
||||
});
|
||||
|
|
|
@ -45,8 +45,9 @@ add_UITour_task(async function test_openPrivacyReports() {
|
|||
let tab = await promiseTabOpened;
|
||||
await BrowserTestUtils.waitForEvent(gBrowser.selectedBrowser, "Initialized");
|
||||
let doc = gBrowser.selectedBrowser.contentDocument;
|
||||
let reports = doc.querySelector("groupbox[data-subcategory='reports']");
|
||||
is(doc.location.hash, "#privacy", "Should not display the reports subcategory in the location hash.");
|
||||
is(reports.hidden, false, "Should open to the reports subcategory in the privacy pane in the new Preferences.");
|
||||
await TestUtils.waitForCondition(() => doc.querySelector(".spotlight"),
|
||||
"Wait for the reports section is spotlighted.");
|
||||
is(doc.querySelector(".spotlight").getAttribute("data-subcategory"), "reports", "The reports section is spotlighted.");
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
|
|
@ -31,12 +31,37 @@ logger.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter()));
|
|||
logger.addAppender(new Log.DumpAppender(new Log.BasicFormatter()));
|
||||
logger.level = Preferences.get(PREF_LOG_LEVEL, Log.Level.Info);
|
||||
|
||||
this.TabCrashObserver = {
|
||||
init() {
|
||||
if (this.initialized)
|
||||
return;
|
||||
this.initialized = true;
|
||||
|
||||
Services.obs.addObserver(this, "ipc:content-shutdown");
|
||||
},
|
||||
|
||||
observe(aSubject, aTopic, aData) {
|
||||
if (aTopic == "ipc:content-shutdown") {
|
||||
aSubject.QueryInterface(Ci.nsIPropertyBag2);
|
||||
if (!aSubject.get("abnormal")) {
|
||||
return;
|
||||
}
|
||||
processDirectory("/tmp");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function install(aData, aReason) {}
|
||||
|
||||
function uninstall(aData, aReason) {}
|
||||
|
||||
function startup(aData, aReason) {
|
||||
logger.info("Starting up...");
|
||||
|
||||
// Install a handler to observe tab crashes, so we can report those right
|
||||
// after they happen instead of relying on the user to restart the browser.
|
||||
TabCrashObserver.init();
|
||||
|
||||
// We could use OS.Constants.Path.tmpDir here, but unfortunately there is
|
||||
// no way in C++ to get the same value *prior* to xpcom initialization.
|
||||
// Since ASan needs its options, including the "log_path" option already
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
mkdir tmp/
|
||||
git clone --no-checkout --depth 1 https://github.com/choller/firefox-asan-reporter tmp/
|
||||
(cd tmp && git reset --hard e1a5d7dc5a2706af72bac0f11eab34b3afdb48ba)
|
||||
(cd tmp && git reset --hard d508c6e3f5df752a9a7a2d6f1e4e7261ec2290e7)
|
||||
|
||||
# Copy only whitelisted files
|
||||
cp tmp/bootstrap.js tmp/install.rdf.in tmp/moz.build tmp/README.md tmp/LICENSE .
|
||||
|
|
|
@ -416,7 +416,7 @@ var FormAutofillContent = {
|
|||
}
|
||||
|
||||
let records = handler.createRecords();
|
||||
if (!Object.keys(records).length) {
|
||||
if (!Object.values(records).some(typeRecords => typeRecords.length)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -986,12 +986,27 @@ class FormAutofillHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the filled sections within submitted form and convert all the valid
|
||||
* field data into multiple records.
|
||||
*
|
||||
* @returns {Object} records
|
||||
* {Array.<Object>} records.address
|
||||
* {Array.<Object>} records.creditCard
|
||||
*/
|
||||
createRecords() {
|
||||
// TODO [Bug 1415073] `FormAutofillHandler.createRecords` should traverse
|
||||
// all sections and aggregate the records into one result.
|
||||
if (this.sections.length > 0) {
|
||||
return this.sections[0].createRecords();
|
||||
const records = {
|
||||
address: [],
|
||||
creditCard: [],
|
||||
};
|
||||
|
||||
for (const section of this.sections) {
|
||||
const secRecords = section.createRecords();
|
||||
for (const [type, record] of Object.entries(secRecords)) {
|
||||
records[type].push(record);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
log.debug("Create records:", records);
|
||||
return records;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
|
|||
|
||||
const PREF_HEURISTICS_ENABLED = "extensions.formautofill.heuristics.enabled";
|
||||
const PREF_SECTION_ENABLED = "extensions.formautofill.section.enabled";
|
||||
const DEFAULT_SECTION_NAME = "-moz-section-default";
|
||||
|
||||
/**
|
||||
* A scanner for traversing all elements in a form and retrieving the field
|
||||
|
@ -35,11 +36,13 @@ class FieldScanner {
|
|||
* @param {Array.DOMElement} elements
|
||||
* The elements from a form for each parser.
|
||||
*/
|
||||
constructor(elements) {
|
||||
constructor(elements, {allowDuplicates = false, sectionEnabled = true}) {
|
||||
this._elementsWeakRef = Cu.getWeakReference(elements);
|
||||
this.fieldDetails = [];
|
||||
this._parsingIndex = 0;
|
||||
this._sections = [];
|
||||
this._allowDuplicates = allowDuplicates;
|
||||
this._sectionEnabled = sectionEnabled;
|
||||
}
|
||||
|
||||
get _elements() {
|
||||
|
@ -112,22 +115,61 @@ class FieldScanner {
|
|||
});
|
||||
}
|
||||
|
||||
getSectionFieldDetails(allowDuplicates) {
|
||||
// TODO: [Bug 1416664] If there is only one section which is not defined by
|
||||
// `autocomplete` attribute, the sections should be classified by the
|
||||
// heuristics.
|
||||
return this._sections.map(section => {
|
||||
if (allowDuplicates) {
|
||||
return section.fieldDetails;
|
||||
_classifySections() {
|
||||
let fieldDetails = this._sections[0].fieldDetails;
|
||||
this._sections = [];
|
||||
let seenTypes = new Set();
|
||||
let previousType;
|
||||
let sectionCount = 0;
|
||||
|
||||
for (let fieldDetail of fieldDetails) {
|
||||
if (!fieldDetail.fieldName) {
|
||||
continue;
|
||||
}
|
||||
return this._trimFieldDetails(section.fieldDetails);
|
||||
});
|
||||
if (seenTypes.has(fieldDetail.fieldName) &&
|
||||
previousType != fieldDetail.fieldName) {
|
||||
seenTypes.clear();
|
||||
sectionCount++;
|
||||
}
|
||||
previousType = fieldDetail.fieldName;
|
||||
seenTypes.add(fieldDetail.fieldName);
|
||||
this._pushToSection(DEFAULT_SECTION_NAME + "-" + sectionCount, fieldDetail);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The result is an array contains the sections with its belonging field
|
||||
* details. If `this._sections` contains one section only with the default
|
||||
* section name (DEFAULT_SECTION_NAME), `this._classifySections` should be
|
||||
* able to identify all sections in the heuristic way.
|
||||
*
|
||||
* @returns {Array<Object>}
|
||||
* The array with the sections, and the belonging fieldDetails are in
|
||||
* each section.
|
||||
*/
|
||||
getSectionFieldDetails() {
|
||||
// When the section feature is disabled, `getSectionFieldDetails` should
|
||||
// provide a single section result.
|
||||
if (!this._sectionEnabled) {
|
||||
return [this._getFinalDetails(this.fieldDetails)];
|
||||
}
|
||||
if (this._sections.length == 0) {
|
||||
return [];
|
||||
}
|
||||
if (this._sections.length == 1 && this._sections[0].name == DEFAULT_SECTION_NAME) {
|
||||
this._classifySections();
|
||||
}
|
||||
|
||||
return this._sections.map(section =>
|
||||
this._getFinalDetails(section.fieldDetails)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will prepare an autocomplete info object with getInfo
|
||||
* function and push the detail to fieldDetails property. Any duplicated
|
||||
* detail will be marked as _duplicated = true for the parser.
|
||||
* function and push the detail to fieldDetails property.
|
||||
* Any field will be pushed into `this._sections` based on the section name
|
||||
* in `autocomplete` attribute.
|
||||
*
|
||||
* Any element without the related detail will be used for adding the detail
|
||||
* to the end of field details.
|
||||
|
@ -154,13 +196,6 @@ class FieldScanner {
|
|||
fieldInfo._reason = info._reason;
|
||||
}
|
||||
|
||||
// Store the association between the field metadata and the element.
|
||||
if (this.findSameField(info) != -1) {
|
||||
// A field with the same identifier already exists.
|
||||
log.debug("Not collecting a field matching another with the same info:", info);
|
||||
fieldInfo._duplicated = true;
|
||||
}
|
||||
|
||||
this.fieldDetails.push(fieldInfo);
|
||||
this._pushToSection(this._getSectionName(fieldInfo), fieldInfo);
|
||||
}
|
||||
|
@ -173,7 +208,7 @@ class FieldScanner {
|
|||
if (info.addressType) {
|
||||
names.push(info.addressType);
|
||||
}
|
||||
return names.length ? names.join(" ") : "-moz-section-default";
|
||||
return names.length ? names.join(" ") : DEFAULT_SECTION_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,22 +225,19 @@ class FieldScanner {
|
|||
throw new Error("Try to update the non-existing field detail.");
|
||||
}
|
||||
this.fieldDetails[index].fieldName = fieldName;
|
||||
|
||||
delete this.fieldDetails[index]._duplicated;
|
||||
let indexSame = this.findSameField(this.fieldDetails[index]);
|
||||
if (indexSame != index && indexSame != -1) {
|
||||
this.fieldDetails[index]._duplicated = true;
|
||||
}
|
||||
}
|
||||
|
||||
findSameField(info) {
|
||||
return this.fieldDetails.findIndex(f => f.section == info.section &&
|
||||
f.addressType == info.addressType &&
|
||||
f.fieldName == info.fieldName);
|
||||
_isSameField(field1, field2) {
|
||||
return field1.section == field2.section &&
|
||||
field1.addressType == field2.addressType &&
|
||||
field1.fieldName == field2.fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the field details without invalid field name and duplicated fields.
|
||||
* Provide the final field details without invalid field name, and the
|
||||
* duplicated fields will be removed as well. For the debugging purpose,
|
||||
* the final `fieldDetails` will include the duplicated fields if
|
||||
* `_allowDuplicates` is true.
|
||||
*
|
||||
* @param {Array<Object>} fieldDetails
|
||||
* The field details for trimming.
|
||||
|
@ -213,12 +245,20 @@ class FieldScanner {
|
|||
* The array with the field details without invalid field name and
|
||||
* duplicated fields.
|
||||
*/
|
||||
_trimFieldDetails(fieldDetails) {
|
||||
return fieldDetails.filter(f => f.fieldName && !f._duplicated);
|
||||
}
|
||||
_getFinalDetails(fieldDetails) {
|
||||
if (this._allowDuplicates) {
|
||||
return fieldDetails.filter(f => f.fieldName);
|
||||
}
|
||||
|
||||
getFieldDetails(allowDuplicates) {
|
||||
return allowDuplicates ? this.fieldDetails : this._trimFieldDetails(this.fieldDetails);
|
||||
let dedupedFieldDetails = [];
|
||||
for (let fieldDetail of fieldDetails) {
|
||||
if (fieldDetail.fieldName && !dedupedFieldDetails.find(f => this._isSameField(fieldDetail, f))) {
|
||||
dedupedFieldDetails.push(fieldDetail);
|
||||
} else {
|
||||
log.debug("Not collecting an invalid field or matching another with the same info:", fieldDetail);
|
||||
}
|
||||
}
|
||||
return dedupedFieldDetails;
|
||||
}
|
||||
|
||||
elementExisting(index) {
|
||||
|
@ -651,7 +691,8 @@ this.FormAutofillHeuristics = {
|
|||
return [];
|
||||
}
|
||||
|
||||
let fieldScanner = new FieldScanner(eligibleFields);
|
||||
let fieldScanner = new FieldScanner(eligibleFields,
|
||||
{allowDuplicates, sectionEnabled: this._sectionEnabled});
|
||||
while (!fieldScanner.parsingFinished) {
|
||||
let parsedPhoneFields = this._parsePhoneFields(fieldScanner);
|
||||
let parsedAddressFields = this._parseAddressFields(fieldScanner);
|
||||
|
@ -666,13 +707,7 @@ this.FormAutofillHeuristics = {
|
|||
|
||||
LabelUtils.clearLabelMap();
|
||||
|
||||
if (!this._sectionEnabled) {
|
||||
// When the section feature is disabled, `getFormInfo` should provide a
|
||||
// single section result.
|
||||
return [fieldScanner.getFieldDetails(allowDuplicates)];
|
||||
}
|
||||
|
||||
return fieldScanner.getSectionFieldDetails(allowDuplicates);
|
||||
return fieldScanner.getSectionFieldDetails();
|
||||
},
|
||||
|
||||
_regExpTableHashValue(...signBits) {
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["FormAutofillParent"];
|
||||
// We expose a singleton from this module. Some tests may import the
|
||||
// constructor via a backstage pass.
|
||||
this.EXPORTED_SYMBOLS = ["formAutofillParent"];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
|
@ -78,10 +80,30 @@ FormAutofillParent.prototype = {
|
|||
*/
|
||||
_active: null,
|
||||
|
||||
/**
|
||||
* The status of Form Autofill's initialization.
|
||||
*/
|
||||
_initialized: false,
|
||||
|
||||
/**
|
||||
* Exposes the status of Form Autofill's initialization. It can be used to
|
||||
* determine whether Form Autofill is available for current users.
|
||||
*
|
||||
* @returns {boolean} Whether FormAutofillParent is initialized.
|
||||
*/
|
||||
get initialized() {
|
||||
return this._initialized;
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes ProfileStorage and registers the message handler.
|
||||
*/
|
||||
async init() {
|
||||
if (this._initialized) {
|
||||
return;
|
||||
}
|
||||
this._initialized = true;
|
||||
|
||||
Services.obs.addObserver(this, "sync-pane-loaded");
|
||||
Services.ppmm.addMessageListener("FormAutofill:InitStorage", this);
|
||||
Services.ppmm.addMessageListener("FormAutofill:GetRecords", this);
|
||||
|
@ -361,6 +383,7 @@ FormAutofillParent.prototype = {
|
|||
},
|
||||
|
||||
_onAddressSubmit(address, target, timeStartedFillingMS) {
|
||||
let showDoorhanger = null;
|
||||
if (address.guid) {
|
||||
// Avoid updating the fields that users don't modify.
|
||||
let originalAddress = this.profileStorage.addresses.get(address.guid);
|
||||
|
@ -373,7 +396,8 @@ FormAutofillParent.prototype = {
|
|||
if (!this.profileStorage.addresses.mergeIfPossible(address.guid, address.record, true)) {
|
||||
this._recordFormFillingTime("address", "autofill-update", timeStartedFillingMS);
|
||||
|
||||
FormAutofillDoorhanger.show(target, "updateAddress").then((state) => {
|
||||
showDoorhanger = async () => {
|
||||
const state = await FormAutofillDoorhanger.show(target, "updateAddress");
|
||||
let changedGUIDs = this.profileStorage.addresses.mergeToStorage(address.record, true);
|
||||
switch (state) {
|
||||
case "create":
|
||||
|
@ -391,15 +415,15 @@ FormAutofillParent.prototype = {
|
|||
break;
|
||||
}
|
||||
changedGUIDs.forEach(guid => this.profileStorage.addresses.notifyUsed(guid));
|
||||
});
|
||||
};
|
||||
// Address should be updated
|
||||
Services.telemetry.scalarAdd("formautofill.addresses.fill_type_autofill_update", 1);
|
||||
return;
|
||||
} else {
|
||||
this._recordFormFillingTime("address", "autofill", timeStartedFillingMS);
|
||||
this.profileStorage.addresses.notifyUsed(address.guid);
|
||||
// Address is merged successfully
|
||||
Services.telemetry.scalarAdd("formautofill.addresses.fill_type_autofill", 1);
|
||||
}
|
||||
this._recordFormFillingTime("address", "autofill", timeStartedFillingMS);
|
||||
this.profileStorage.addresses.notifyUsed(address.guid);
|
||||
// Address is merged successfully
|
||||
Services.telemetry.scalarAdd("formautofill.addresses.fill_type_autofill", 1);
|
||||
} else {
|
||||
let changedGUIDs = this.profileStorage.addresses.mergeToStorage(address.record);
|
||||
if (!changedGUIDs.length) {
|
||||
|
@ -411,22 +435,24 @@ FormAutofillParent.prototype = {
|
|||
// Show first time use doorhanger
|
||||
if (FormAutofillUtils.isAutofillAddressesFirstTimeUse) {
|
||||
Services.prefs.setBoolPref(FormAutofillUtils.ADDRESSES_FIRST_TIME_USE_PREF, false);
|
||||
FormAutofillDoorhanger.show(target, "firstTimeUse").then((state) => {
|
||||
showDoorhanger = async () => {
|
||||
const state = await FormAutofillDoorhanger.show(target, "firstTimeUse");
|
||||
if (state !== "open-pref") {
|
||||
return;
|
||||
}
|
||||
|
||||
target.ownerGlobal.openPreferences("panePrivacy",
|
||||
{origin: "autofillDoorhanger"});
|
||||
});
|
||||
};
|
||||
} else {
|
||||
// We want to exclude the first time form filling.
|
||||
Services.telemetry.scalarAdd("formautofill.addresses.fill_type_manual", 1);
|
||||
}
|
||||
}
|
||||
return showDoorhanger;
|
||||
},
|
||||
|
||||
async _onCreditCardSubmit(creditCard, target, timeStartedFillingMS) {
|
||||
_onCreditCardSubmit(creditCard, target, timeStartedFillingMS) {
|
||||
// Updates the used status for shield/heartbeat to recognize users who have
|
||||
// used Credit Card Autofill.
|
||||
let setUsedStatus = status => {
|
||||
|
@ -463,7 +489,7 @@ FormAutofillParent.prototype = {
|
|||
// Add probe to record credit card autofill(without modification).
|
||||
Services.telemetry.scalarAdd("formautofill.creditCards.fill_type_autofill", 1);
|
||||
this._recordFormFillingTime("creditCard", "autofill", timeStartedFillingMS);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
// Add the probe to record credit card autofill with modification.
|
||||
Services.telemetry.scalarAdd("formautofill.creditCards.fill_type_autofill_modified", 1);
|
||||
|
@ -483,55 +509,79 @@ FormAutofillParent.prototype = {
|
|||
let dupGuid = this.profileStorage.creditCards.getDuplicateGuid(creditCard.record);
|
||||
if (dupGuid) {
|
||||
this.profileStorage.creditCards.notifyUsed(dupGuid);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Indicate that the user has seen the doorhanger.
|
||||
setUsedStatus(2);
|
||||
|
||||
let state = await FormAutofillDoorhanger.show(target, creditCard.guid ? "updateCreditCard" : "addCreditCard");
|
||||
if (state == "cancel") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == "disable") {
|
||||
Services.prefs.setBoolPref("extensions.formautofill.creditCards.enabled", false);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: "MasterPassword.ensureLoggedIn" can be removed after the storage
|
||||
// APIs are refactored to be async functions (bug 1399367).
|
||||
if (!await MasterPassword.ensureLoggedIn()) {
|
||||
log.warn("User canceled master password entry");
|
||||
return;
|
||||
}
|
||||
|
||||
let changedGUIDs = [];
|
||||
if (creditCard.guid) {
|
||||
if (state == "update") {
|
||||
this.profileStorage.creditCards.update(creditCard.guid, creditCard.record, true);
|
||||
changedGUIDs.push(creditCard.guid);
|
||||
} else if ("create") {
|
||||
changedGUIDs.push(this.profileStorage.creditCards.add(creditCard.record));
|
||||
return async () => {
|
||||
// Suppress the pending doorhanger from showing up if user disabled credit card in previous doorhanger.
|
||||
if (!FormAutofillUtils.isAutofillCreditCardsEnabled) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
changedGUIDs.push(...this.profileStorage.creditCards.mergeToStorage(creditCard.record));
|
||||
if (!changedGUIDs.length) {
|
||||
changedGUIDs.push(this.profileStorage.creditCards.add(creditCard.record));
|
||||
|
||||
const state = await FormAutofillDoorhanger.show(target, creditCard.guid ? "updateCreditCard" : "addCreditCard");
|
||||
if (state == "cancel") {
|
||||
return;
|
||||
}
|
||||
}
|
||||
changedGUIDs.forEach(guid => this.profileStorage.creditCards.notifyUsed(guid));
|
||||
|
||||
if (state == "disable") {
|
||||
Services.prefs.setBoolPref("extensions.formautofill.creditCards.enabled", false);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: "MasterPassword.ensureLoggedIn" can be removed after the storage
|
||||
// APIs are refactored to be async functions (bug 1399367).
|
||||
if (!await MasterPassword.ensureLoggedIn()) {
|
||||
log.warn("User canceled master password entry");
|
||||
return;
|
||||
}
|
||||
|
||||
let changedGUIDs = [];
|
||||
if (creditCard.guid) {
|
||||
if (state == "update") {
|
||||
this.profileStorage.creditCards.update(creditCard.guid, creditCard.record, true);
|
||||
changedGUIDs.push(creditCard.guid);
|
||||
} else if ("create") {
|
||||
changedGUIDs.push(this.profileStorage.creditCards.add(creditCard.record));
|
||||
}
|
||||
} else {
|
||||
changedGUIDs.push(...this.profileStorage.creditCards.mergeToStorage(creditCard.record));
|
||||
if (!changedGUIDs.length) {
|
||||
changedGUIDs.push(this.profileStorage.creditCards.add(creditCard.record));
|
||||
}
|
||||
}
|
||||
changedGUIDs.forEach(guid => this.profileStorage.creditCards.notifyUsed(guid));
|
||||
};
|
||||
},
|
||||
|
||||
_onFormSubmit(data, target) {
|
||||
async _onFormSubmit(data, target) {
|
||||
let {profile: {address, creditCard}, timeStartedFillingMS} = data;
|
||||
|
||||
if (address) {
|
||||
this._onAddressSubmit(address, target, timeStartedFillingMS);
|
||||
}
|
||||
if (creditCard) {
|
||||
this._onCreditCardSubmit(creditCard, target, timeStartedFillingMS);
|
||||
// Don't record filling time if any type of records has more than one section being
|
||||
// populated. We've been recording the filling time, so the other cases that aren't
|
||||
// recorded on the same basis should be out of the data samples. E.g. Filling time of
|
||||
// populating one profile is different from populating two sections, therefore, we
|
||||
// shouldn't record the later to regress the representation of existing statistics.
|
||||
if (address.length > 1 || creditCard.length > 1) {
|
||||
timeStartedFillingMS = null;
|
||||
}
|
||||
|
||||
// Transmit the telemetry immediately in the meantime form submitted, and handle these pending
|
||||
// doorhangers at a later.
|
||||
await Promise.all([
|
||||
address.map(addrRecord => this._onAddressSubmit(addrRecord, target, timeStartedFillingMS)),
|
||||
creditCard.map(ccRecord => this._onCreditCardSubmit(ccRecord, target, timeStartedFillingMS)),
|
||||
].map(pendingDoorhangers => {
|
||||
return pendingDoorhangers.filter(pendingDoorhanger => !!pendingDoorhanger &&
|
||||
typeof pendingDoorhanger == "function");
|
||||
}).map(pendingDoorhangers => new Promise(async resolve => {
|
||||
for (const showDoorhanger of pendingDoorhangers) {
|
||||
await showDoorhanger();
|
||||
}
|
||||
resolve();
|
||||
})));
|
||||
},
|
||||
/**
|
||||
* Set the probes for the filling time with specific filling type and form type.
|
||||
|
@ -552,3 +602,5 @@ FormAutofillParent.prototype = {
|
|||
histogram.add(`${formType}-${fillingType}`, Date.now() - startedFillingMS);
|
||||
},
|
||||
};
|
||||
|
||||
this.formAutofillParent = new FormAutofillParent();
|
||||
|
|
|
@ -87,6 +87,7 @@ FormAutofillPreferences.prototype = {
|
|||
addressAutofill.id = "addressAutofill";
|
||||
addressAutofillLearnMore.id = "addressAutofillLearnMore";
|
||||
|
||||
addressAutofill.setAttribute("data-subcategory", "address-autofill");
|
||||
addressAutofillLearnMore.setAttribute("value", this.bundle.GetStringFromName("learnMoreLabel"));
|
||||
addressAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("autofillAddressesCheckbox"));
|
||||
savedAddressesBtn.setAttribute("label", this.bundle.GetStringFromName("savedAddressesBtnLabel"));
|
||||
|
@ -130,6 +131,7 @@ FormAutofillPreferences.prototype = {
|
|||
creditCardAutofill.id = "creditCardAutofill";
|
||||
creditCardAutofillLearnMore.id = "creditCardAutofillLearnMore";
|
||||
|
||||
creditCardAutofill.setAttribute("data-subcategory", "credit-card-autofill");
|
||||
creditCardAutofillLearnMore.setAttribute("value", this.bundle.GetStringFromName("learnMoreLabel"));
|
||||
creditCardAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("autofillCreditCardsCheckbox"));
|
||||
savedCreditCardsBtn.setAttribute("label", this.bundle.GetStringFromName("savedCreditCardsBtnLabel"));
|
||||
|
|
|
@ -16,7 +16,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
|
||||
"resource://gre/modules/AddonManager.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FormAutofillParent",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "formAutofillParent",
|
||||
"resource://formautofill/FormAutofillParent.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FormAutofillUtils",
|
||||
"resource://formautofill/FormAutofillUtils.jsm");
|
||||
|
@ -110,8 +110,7 @@ function startup(data) {
|
|||
// Listen for the autocomplete popup message to lazily append our stylesheet related to the popup.
|
||||
Services.mm.addMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup);
|
||||
|
||||
let parent = new FormAutofillParent();
|
||||
parent.init().catch(Cu.reportError);
|
||||
formAutofillParent.init().catch(Cu.reportError);
|
||||
Services.ppmm.loadProcessScript("data:,new " + function() {
|
||||
Components.utils.import("resource://formautofill/FormAutofillContent.jsm");
|
||||
}, true);
|
||||
|
|
|
@ -2,10 +2,20 @@
|
|||
* 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/. */
|
||||
|
||||
html {
|
||||
/* Prevent unnecessary horizontal scroll bar from showing */
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
button {
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
|
|
@ -49,7 +49,7 @@ class ManageRecords {
|
|||
}
|
||||
|
||||
localizeDocument() {
|
||||
document.documentElement.style.width = FormAutofillUtils.stringBundle.GetStringFromName("manageDialogsWidth");
|
||||
document.documentElement.style.minWidth = FormAutofillUtils.stringBundle.GetStringFromName("manageDialogsWidth");
|
||||
FormAutofillUtils.localizeMarkup(AUTOFILL_BUNDLE_URI, document);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,11 @@ textarea {
|
|||
resize: none;
|
||||
}
|
||||
|
||||
button {
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
input,
|
||||
select {
|
||||
box-sizing: border-box;
|
||||
|
|
|
@ -11,32 +11,69 @@
|
|||
<label>Organization: <input id="organization" autocomplete="organization"></label><br/>
|
||||
|
||||
<br/>
|
||||
<label>Street Address: <input id="street-address" autocomplete="shipping street-address"></label><br/>
|
||||
<label>Address Level 2: <input id="address-level2" autocomplete="shipping address-level2"></label><br/>
|
||||
<label>Address Level 1: <input id="address-level1" autocomplete="shipping address-level1"></label><br/>
|
||||
<label>Postal Code: <input id="postal-code" autocomplete="shipping postal-code"></label><br/>
|
||||
<label>Country: <input id="country" autocomplete="shipping country"></label><br/>
|
||||
<label>Street Address: <input id="street-address-a" autocomplete="shipping street-address"></label><br/>
|
||||
<label>Address Level 2: <input id="address-level2-a" autocomplete="shipping address-level2"></label><br/>
|
||||
<label>Address Level 1: <input id="address-level1-a" autocomplete="shipping address-level1"></label><br/>
|
||||
<label>Postal Code: <input id="postal-code-a" autocomplete="shipping postal-code"></label><br/>
|
||||
<label>Country: <input id="country-a" autocomplete="shipping country"></label><br/>
|
||||
|
||||
<br/>
|
||||
<label>Street Address: <input id="street-address" autocomplete="billing street-address"></label><br/>
|
||||
<label>Address Level 2: <input id="address-level2" autocomplete="billing address-level2"></label><br/>
|
||||
<label>Address Level 1: <input id="address-level1" autocomplete="billing address-level1"></label><br/>
|
||||
<label>Postal Code: <input id="postal-code" autocomplete="billing postal-code"></label><br/>
|
||||
<label>Country: <input id="country" autocomplete="billing country"></label><br/>
|
||||
<label>Street Address: <input id="street-address-b" autocomplete="billing street-address"></label><br/>
|
||||
<label>Address Level 2: <input id="address-level2-b" autocomplete="billing address-level2"></label><br/>
|
||||
<label>Address Level 1: <input id="address-level1-b" autocomplete="billing address-level1"></label><br/>
|
||||
<label>Postal Code: <input id="postal-code-b" autocomplete="billing postal-code"></label><br/>
|
||||
<label>Country: <input id="country-b" autocomplete="billing country"></label><br/>
|
||||
|
||||
<br/>
|
||||
<label>Street Address: <input id="street-address" autocomplete="section-my street-address"></label><br/>
|
||||
<label>Address Level 2: <input id="address-level2" autocomplete="section-my address-level2"></label><br/>
|
||||
<label>Address Level 1: <input id="address-level1" autocomplete="section-my address-level1"></label><br/>
|
||||
<label>Postal Code: <input id="postal-code" autocomplete="section-my postal-code"></label><br/>
|
||||
<label>Country: <input id="country" autocomplete="section-my country"></label><br/>
|
||||
<label>Street Address: <input id="street-address-c" autocomplete="section-my street-address"></label><br/>
|
||||
<label>Address Level 2: <input id="address-level2-c" autocomplete="section-my address-level2"></label><br/>
|
||||
<label>Address Level 1: <input id="address-level1-c" autocomplete="section-my address-level1"></label><br/>
|
||||
<label>Postal Code: <input id="postal-code-c" autocomplete="section-my postal-code"></label><br/>
|
||||
<label>Country: <input id="country-c" autocomplete="section-my country"></label><br/>
|
||||
|
||||
<br/>
|
||||
<label>Telephone: <input id="tel" autocomplete="work tel"></label><br/>
|
||||
<label>Email: <input id="email" autocomplete="work email"></label><br/>
|
||||
<label>Telephone: <input id="tel-a" autocomplete="work tel"></label><br/>
|
||||
<label>Email: <input id="email-a" autocomplete="work email"></label><br/>
|
||||
<br/>
|
||||
<label>Telephone: <input id="tel" autocomplete="home tel"></label><br/>
|
||||
<label>Email: <input id="email" autocomplete="home email"></label><br/>
|
||||
<label>Telephone: <input id="tel-b" autocomplete="home tel"></label><br/>
|
||||
<label>Email: <input id="email-b" autocomplete="home email"></label><br/>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
<button type="reset">Reset</button>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<form>
|
||||
<label>Name: <input autocomplete="name"></label><br/>
|
||||
<label>Organization: <input autocomplete="organization"></label><br/>
|
||||
|
||||
<br/>
|
||||
<label>Street Address: <input autocomplete="street-address"></label><br/>
|
||||
<label>Address Level 2: <input autocomplete="address-level2"></label><br/>
|
||||
<label>Address Level 1: <input autocomplete="address-level1"></label><br/>
|
||||
<label>Postal Code: <input autocomplete="postal-code"></label><br/>
|
||||
<label>Country: <input autocomplete="country"></label><br/>
|
||||
|
||||
<br/>
|
||||
<label>Street Address: <input autocomplete="street-address"></label><br/>
|
||||
<label>Address Level 2: <input autocomplete="address-level2"></label><br/>
|
||||
<label>Address Level 1: <input autocomplete="address-level1"></label><br/>
|
||||
<label>Postal Code: <input autocomplete="postal-code"></label><br/>
|
||||
<label>Country: <input autocomplete="country"></label><br/>
|
||||
|
||||
<br/>
|
||||
<label>Street Address: <input autocomplete="street-address"></label><br/>
|
||||
<label>Address Level 2: <input autocomplete="address-level2"></label><br/>
|
||||
<label>Address Level 1: <input autocomplete="address-level1"></label><br/>
|
||||
<label>Postal Code: <input autocomplete="postal-code"></label><br/>
|
||||
<label>Country: <input autocomplete="country"></label><br/>
|
||||
|
||||
<br/>
|
||||
<label>Telephone: <input autocomplete="work tel"></label><br/>
|
||||
<label>Email: <input autocomplete="work email"></label><br/>
|
||||
<br/>
|
||||
<label>Telephone: <input autocomplete="home tel"></label><br/>
|
||||
<label>Email: <input autocomplete="home email"></label><br/>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
<button type="reset">Reset</button>
|
||||
|
|
|
@ -41,6 +41,37 @@ runHeuristicsTest([
|
|||
{"section": "section-my", "addressType": "", "contactType": "", "fieldName": "country"},
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "name"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "organization"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
|
||||
],
|
||||
[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
|
||||
],
|
||||
[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
|
||||
{"section": "", "addressType": "", "contactType": "work", "fieldName": "tel"},
|
||||
{"section": "", "addressType": "", "contactType": "work", "fieldName": "email"},
|
||||
],
|
||||
[
|
||||
{"section": "", "addressType": "", "contactType": "home", "fieldName": "tel"},
|
||||
{"section": "", "addressType": "", "contactType": "home", "fieldName": "email"},
|
||||
],
|
||||
],
|
||||
],
|
||||
},
|
||||
], "../../fixtures/");
|
||||
|
|
|
@ -6,7 +6,7 @@ runHeuristicsTest([
|
|||
{
|
||||
fixturePath: "Checkout_ShippingAddress.html",
|
||||
expectedResult: [
|
||||
[[]], // Search form
|
||||
[], // Search form
|
||||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
|
||||
|
@ -26,7 +26,7 @@ runHeuristicsTest([
|
|||
}, {
|
||||
fixturePath: "Checkout_Payment.html",
|
||||
expectedResult: [
|
||||
[[]], // Search form
|
||||
[], // Search form
|
||||
[[ // Sign up
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
]],
|
||||
|
|
|
@ -20,9 +20,10 @@ runHeuristicsTest([
|
|||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
|
||||
], [
|
||||
// The below "tel-extension" is correct and removed due to the
|
||||
// duplicated field above.
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
|
||||
]],
|
||||
[],
|
||||
],
|
||||
|
@ -47,6 +48,8 @@ runHeuristicsTest([
|
|||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
|
||||
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
|
||||
], [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
|
||||
]],
|
||||
[],
|
||||
],
|
||||
|
@ -54,7 +57,7 @@ runHeuristicsTest([
|
|||
fixturePath: "Checkout_Logon.html",
|
||||
expectedResult: [
|
||||
[],
|
||||
[[]],
|
||||
[],
|
||||
[],
|
||||
],
|
||||
},
|
||||
|
|
|
@ -50,7 +50,6 @@ runHeuristicsTest([
|
|||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
|
||||
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"}, // ac-off
|
||||
]],
|
||||
|
@ -58,7 +57,7 @@ runHeuristicsTest([
|
|||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
|
||||
]],
|
||||
[],
|
||||
[[]],
|
||||
[],
|
||||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "additional-name"}, // middle-name initial
|
||||
|
@ -96,7 +95,7 @@ runHeuristicsTest([
|
|||
}, {
|
||||
fixturePath: "SignIn.html",
|
||||
expectedResult: [
|
||||
[[]],
|
||||
[],
|
||||
[],
|
||||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
|
|
|
@ -16,10 +16,7 @@ runHeuristicsTest([
|
|||
{"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
|
||||
]],
|
||||
[
|
||||
/*
|
||||
*/
|
||||
],
|
||||
[],
|
||||
],
|
||||
}, {
|
||||
fixturePath: "Checkout_Payment.html",
|
||||
|
@ -56,7 +53,7 @@ runHeuristicsTest([
|
|||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
]],
|
||||
[[]],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
],
|
||||
|
|
|
@ -26,6 +26,9 @@ runHeuristicsTest([
|
|||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
|
||||
], [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
|
||||
|
|
|
@ -55,9 +55,9 @@ runHeuristicsTest([
|
|||
}, {
|
||||
fixturePath: "SignIn.html",
|
||||
expectedResult: [
|
||||
[[ // ac-off
|
||||
[ // ac-off
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
]],
|
||||
],
|
||||
],
|
||||
},
|
||||
], "../../../fixtures/third_party/OfficeDepot/");
|
||||
|
|
|
@ -13,11 +13,11 @@ runHeuristicsTest([
|
|||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"}, // select
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"},
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"},
|
||||
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
|
||||
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
|
||||
], [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
|
||||
]],
|
||||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
|
@ -33,11 +33,11 @@ runHeuristicsTest([
|
|||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"}, // select
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"}, // select
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, // select
|
||||
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"},
|
||||
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"},
|
||||
], [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off
|
||||
]],
|
||||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
|
@ -46,7 +46,7 @@ runHeuristicsTest([
|
|||
}, {
|
||||
fixturePath: "SignIn.html",
|
||||
expectedResult: [
|
||||
[[]],
|
||||
[],
|
||||
[[ // Sign in
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
]],
|
||||
|
|
|
@ -7,11 +7,11 @@ runHeuristicsTest([
|
|||
fixturePath: "ShippingAddress.html",
|
||||
expectedResult: [
|
||||
[],
|
||||
[[]], // search form, ac-off
|
||||
[[ // ac-off
|
||||
[], // search form, ac-off
|
||||
[ // ac-off
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
]],
|
||||
[[ // check-out, ac-off
|
||||
],
|
||||
[ // check-out, ac-off
|
||||
/*
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
|
||||
|
@ -24,7 +24,7 @@ runHeuristicsTest([
|
|||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
*/
|
||||
]],
|
||||
],
|
||||
[ // ac-off
|
||||
/*
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
|
@ -40,18 +40,18 @@ runHeuristicsTest([
|
|||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "new-password"},
|
||||
*/
|
||||
],
|
||||
[[ // ac-off
|
||||
[ // ac-off
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
]],
|
||||
[[ // ac-off
|
||||
],
|
||||
[ // ac-off
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
]],
|
||||
],
|
||||
],
|
||||
}, {
|
||||
fixturePath: "PaymentOptions.html",
|
||||
expectedResult: [
|
||||
[],
|
||||
[[]], // search
|
||||
[], // search
|
||||
[[ // credit card
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
|
||||
// FIXME: bug 1392958 - Cardholder name field should be detected as cc-name
|
||||
|
|
|
@ -6,7 +6,7 @@ runHeuristicsTest([
|
|||
{
|
||||
fixturePath: "Basic.html",
|
||||
expectedResult: [
|
||||
[[ // ac-off
|
||||
[ // ac-off
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
|
||||
|
@ -14,7 +14,7 @@ runHeuristicsTest([
|
|||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"},
|
||||
]],
|
||||
],
|
||||
],
|
||||
}, {
|
||||
fixturePath: "Basic_ac_on.html",
|
||||
|
|
|
@ -9,7 +9,7 @@ runHeuristicsTest([
|
|||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
|
||||
]],
|
||||
[[]],
|
||||
[],
|
||||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
|
||||
// {"section": "", "addressType": "", "contactType": "", "fieldName": "password"}, // ac-off
|
||||
|
@ -25,7 +25,7 @@ runHeuristicsTest([
|
|||
}, {
|
||||
fixturePath: "Payment.html",
|
||||
expectedResult: [
|
||||
[[]],
|
||||
[],
|
||||
[
|
||||
[
|
||||
{"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "given-name"},
|
||||
|
@ -50,7 +50,7 @@ runHeuristicsTest([
|
|||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"},
|
||||
]],
|
||||
[[]],
|
||||
[],
|
||||
[[
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"},
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://formautofill/FormAutofillParent.jsm");
|
||||
let {FormAutofillParent} = Cu.import("resource://formautofill/FormAutofillParent.jsm", {});
|
||||
Cu.import("resource://formautofill/ProfileStorage.jsm");
|
||||
|
||||
add_task(async function test_activeStatus_init() {
|
||||
|
|
|
@ -292,10 +292,22 @@ const TESTCASES = [
|
|||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"},
|
||||
],
|
||||
creditCardFieldDetails: [],
|
||||
}, {
|
||||
addressFieldDetails: [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
|
||||
// TODO Bug 1421181 - "tel-country-code" field should belong to the next
|
||||
// section. There should be a way to group the related fields during the
|
||||
// parsing stage.
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-country-code"},
|
||||
],
|
||||
creditCardFieldDetails: [],
|
||||
}, {
|
||||
addressFieldDetails: [
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"},
|
||||
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"},
|
||||
|
@ -461,13 +473,10 @@ for (let tc of TESTCASES) {
|
|||
Assert.equal(detail.elementWeakRef.get(), testCaseDetails[index].elementWeakRef.get(), "DOM reference");
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < testcase.sections.length; i++) {
|
||||
let section = testcase.sections[i];
|
||||
[
|
||||
section.addressFieldDetails,
|
||||
section.creditCardFieldDetails,
|
||||
].forEach(details => setElementWeakRef(details));
|
||||
}
|
||||
setElementWeakRef(testcase.sections.reduce((fieldDetails, section) => {
|
||||
fieldDetails.push(...section.addressFieldDetails, ...section.creditCardFieldDetails);
|
||||
return fieldDetails;
|
||||
}, []));
|
||||
setElementWeakRef(testcase.validFieldDetails);
|
||||
|
||||
let handler = new FormAutofillHandler(formLike);
|
||||
|
|
|
@ -26,16 +26,16 @@ const TESTCASES = [
|
|||
"cc-name": "*".repeat(201),
|
||||
},
|
||||
expectedRecord: {
|
||||
address: {
|
||||
address: [{
|
||||
"given-name": "John",
|
||||
"organization": "*".repeat(200),
|
||||
"address-level1": "",
|
||||
"country": "US",
|
||||
},
|
||||
creditCard: {
|
||||
}],
|
||||
creditCard: [{
|
||||
"cc-number": "1111222233334444",
|
||||
"cc-name": "",
|
||||
},
|
||||
}],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -50,7 +50,8 @@ const TESTCASES = [
|
|||
"organization": "Mozilla",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: undefined,
|
||||
address: [],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -66,11 +67,12 @@ const TESTCASES = [
|
|||
"country": "United States",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: {
|
||||
address: [{
|
||||
"given-name": "John",
|
||||
"organization": "Mozilla",
|
||||
"country": "United States",
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -86,11 +88,12 @@ const TESTCASES = [
|
|||
"country": "United States",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: {
|
||||
address: [{
|
||||
"given-name": "John",
|
||||
"organization": "Mozilla",
|
||||
"country": "US",
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -108,11 +111,12 @@ const TESTCASES = [
|
|||
"tel-national": "1234567890",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: {
|
||||
address: [{
|
||||
"given-name": "John",
|
||||
"organization": "Mozilla",
|
||||
"tel": "+11234567890",
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -130,12 +134,13 @@ const TESTCASES = [
|
|||
"tel": "1234",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: {
|
||||
address: [{
|
||||
"given-name": "John",
|
||||
"organization": "Mozilla",
|
||||
"country": "United States",
|
||||
"tel": "",
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -153,12 +158,13 @@ const TESTCASES = [
|
|||
"tel": "1234567890123456",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: {
|
||||
address: [{
|
||||
"given-name": "John",
|
||||
"organization": "Mozilla",
|
||||
"country": "United States",
|
||||
"tel": "",
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -176,12 +182,13 @@ const TESTCASES = [
|
|||
"tel": "12345###!!!",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: {
|
||||
address: [{
|
||||
"given-name": "John",
|
||||
"organization": "Mozilla",
|
||||
"country": "United States",
|
||||
"tel": "",
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -197,7 +204,8 @@ const TESTCASES = [
|
|||
"organization": "Mozilla",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: undefined,
|
||||
address: [],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -215,7 +223,8 @@ const TESTCASES = [
|
|||
"organization": "Mozilla",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: undefined,
|
||||
address: [],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -231,11 +240,12 @@ const TESTCASES = [
|
|||
"cc-exp": "2022-06",
|
||||
},
|
||||
expectedRecord: {
|
||||
creditCard: {
|
||||
address: [],
|
||||
creditCard: [{
|
||||
"cc-number": "4444000022220000",
|
||||
"cc-name": "Foo Bar",
|
||||
"cc-exp": "2022-06",
|
||||
},
|
||||
}],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -247,9 +257,10 @@ const TESTCASES = [
|
|||
"cc-number": "4444000022220000",
|
||||
},
|
||||
expectedRecord: {
|
||||
creditCard: {
|
||||
address: [],
|
||||
creditCard: [{
|
||||
"cc-number": "4444000022220000",
|
||||
},
|
||||
}],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -265,7 +276,8 @@ const TESTCASES = [
|
|||
"cc-exp": "2022-06",
|
||||
},
|
||||
expectedRecord: {
|
||||
creditCard: undefined,
|
||||
address: [],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -279,9 +291,80 @@ const TESTCASES = [
|
|||
"cc-exp": "2022-06",
|
||||
},
|
||||
expectedRecord: {
|
||||
creditCard: undefined,
|
||||
address: [],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "A form with multiple sections",
|
||||
document: `<form>
|
||||
<input id="given-name" autocomplete="given-name">
|
||||
<input id="organization" autocomplete="organization">
|
||||
<input id="country" autocomplete="country">
|
||||
|
||||
<input id="given-name-shipping" autocomplete="shipping given-name">
|
||||
<input id="family-name-shipping" autocomplete="shipping family-name">
|
||||
<input id="organization-shipping" autocomplete="shipping organization">
|
||||
<input id="country-shipping" autocomplete="shipping country">
|
||||
|
||||
<input id="given-name-billing" autocomplete="billing given-name">
|
||||
<input id="organization-billing" autocomplete="billing organization">
|
||||
<input id="country-billing" autocomplete="billing country">
|
||||
|
||||
<input id="cc-number-section-one" autocomplete="section-one cc-number">
|
||||
<input id="cc-name-section-one" autocomplete="section-one cc-name">
|
||||
|
||||
<input id="cc-number-section-two" autocomplete="section-two cc-number">
|
||||
<input id="cc-name-section-two" autocomplete="section-two cc-name">
|
||||
<input id="cc-exp-section-two" autocomplete="section-two cc-exp">
|
||||
</form>`,
|
||||
formValue: {
|
||||
"given-name": "Bar",
|
||||
"organization": "Foo",
|
||||
"country": "US",
|
||||
|
||||
"given-name-shipping": "John",
|
||||
"family-name-shipping": "Doe",
|
||||
"organization-shipping": "Mozilla",
|
||||
"country-shipping": "US",
|
||||
|
||||
"given-name-billing": "Foo",
|
||||
"organization-billing": "Bar",
|
||||
"country-billing": "US",
|
||||
|
||||
"cc-number-section-one": "4444000022220000",
|
||||
"cc-name-section-one": "John",
|
||||
|
||||
"cc-number-section-two": "4444000022221111",
|
||||
"cc-name-section-two": "Foo Bar",
|
||||
"cc-exp-section-two": "2026-26",
|
||||
},
|
||||
expectedRecord: {
|
||||
address: [{
|
||||
"given-name": "Bar",
|
||||
"organization": "Foo",
|
||||
"country": "US",
|
||||
}, {
|
||||
"given-name": "John",
|
||||
"family-name": "Doe",
|
||||
"organization": "Mozilla",
|
||||
"country": "US",
|
||||
}, {
|
||||
"given-name": "Foo",
|
||||
"organization": "Bar",
|
||||
"country": "US",
|
||||
}],
|
||||
creditCard: [{
|
||||
"cc-number": "4444000022220000",
|
||||
"cc-name": "John",
|
||||
}, {
|
||||
"cc-number": "4444000022221111",
|
||||
"cc-name": "Foo Bar",
|
||||
"cc-exp": "2026-26",
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
for (let testcase of TESTCASES) {
|
||||
|
@ -301,12 +384,9 @@ for (let testcase of TESTCASES) {
|
|||
|
||||
let record = handler.createRecords();
|
||||
|
||||
for (let type in testcase.expectedRecord) {
|
||||
if (!testcase.expectedRecord[type]) {
|
||||
do_check_eq(record[type], undefined);
|
||||
} else {
|
||||
Assert.deepEqual(record[type].record, testcase.expectedRecord[type]);
|
||||
}
|
||||
let expectedRecord = testcase.expectedRecord;
|
||||
for (let type in record) {
|
||||
Assert.deepEqual(record[type].map(secRecord => secRecord.record), expectedRecord[type]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://formautofill/FormAutofillParent.jsm");
|
||||
let {FormAutofillParent} = Cu.import("resource://formautofill/FormAutofillParent.jsm", {});
|
||||
Cu.import("resource://formautofill/MasterPassword.jsm");
|
||||
Cu.import("resource://formautofill/ProfileStorage.jsm");
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
|
@ -73,7 +73,8 @@ const TESTCASES = [
|
|||
"tel": "1-650-903-0800",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -88,7 +89,8 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
creditCard: {
|
||||
address: [],
|
||||
creditCard: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"cc-name": "John Doe",
|
||||
|
@ -97,7 +99,7 @@ const TESTCASES = [
|
|||
"cc-exp-year": 2000,
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -115,7 +117,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
|
@ -126,8 +128,8 @@ const TESTCASES = [
|
|||
"tel": "1-650-903-0800",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
creditCard: {
|
||||
}],
|
||||
creditCard: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"cc-name": "John Doe",
|
||||
|
@ -136,7 +138,7 @@ const TESTCASES = [
|
|||
"cc-exp-year": 2000,
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -150,7 +152,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
|
@ -161,7 +163,8 @@ const TESTCASES = [
|
|||
"tel": "1-650-903-0800",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -176,7 +179,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
|
@ -187,7 +190,8 @@ const TESTCASES = [
|
|||
"tel": "1-650-903-0800",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -201,7 +205,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"address-level1": "CA",
|
||||
|
@ -212,7 +216,8 @@ const TESTCASES = [
|
|||
"tel": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -226,7 +231,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"address-level1": "CA",
|
||||
|
@ -237,7 +242,8 @@ const TESTCASES = [
|
|||
"tel": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -251,7 +257,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"address-level1": "AR",
|
||||
|
@ -262,7 +268,8 @@ const TESTCASES = [
|
|||
"tel": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -276,7 +283,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"address-level1": "CA",
|
||||
|
@ -287,7 +294,8 @@ const TESTCASES = [
|
|||
"tel": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -301,7 +309,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"address-level1": "AZ",
|
||||
|
@ -312,7 +320,8 @@ const TESTCASES = [
|
|||
"tel": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -326,7 +335,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"address-level1": "Arizonac",
|
||||
|
@ -337,7 +346,8 @@ const TESTCASES = [
|
|||
"tel": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -352,7 +362,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
|
@ -363,7 +373,8 @@ const TESTCASES = [
|
|||
"email": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -378,7 +389,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
|
@ -389,7 +400,8 @@ const TESTCASES = [
|
|||
"email": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -404,7 +416,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
|
@ -415,7 +427,8 @@ const TESTCASES = [
|
|||
"email": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -430,7 +443,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
|
@ -441,7 +454,8 @@ const TESTCASES = [
|
|||
"email": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -456,7 +470,7 @@ const TESTCASES = [
|
|||
expectedResult: {
|
||||
formSubmission: true,
|
||||
records: {
|
||||
address: {
|
||||
address: [{
|
||||
guid: null,
|
||||
record: {
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
|
@ -467,7 +481,8 @@ const TESTCASES = [
|
|||
"email": "",
|
||||
},
|
||||
untouchedFields: [],
|
||||
},
|
||||
}],
|
||||
creditCard: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -478,8 +493,8 @@ add_task(async function handle_earlyformsubmit_event() {
|
|||
let fakeForm = MOCK_DOC.createElement("form");
|
||||
sinon.spy(FormAutofillContent, "_onFormSubmit");
|
||||
|
||||
do_check_eq(FormAutofillContent.notify(fakeForm), true);
|
||||
do_check_eq(FormAutofillContent._onFormSubmit.called, false);
|
||||
Assert.equal(FormAutofillContent.notify(fakeForm), true);
|
||||
Assert.equal(FormAutofillContent._onFormSubmit.called, false);
|
||||
FormAutofillContent._onFormSubmit.restore();
|
||||
});
|
||||
|
||||
|
@ -508,33 +523,33 @@ add_task(async function autofill_disabled() {
|
|||
Services.prefs.setBoolPref("extensions.formautofill.addresses.enabled", false);
|
||||
Services.prefs.setBoolPref("extensions.formautofill.creditCards.enabled", false);
|
||||
FormAutofillContent.notify(form);
|
||||
do_check_eq(FormAutofillContent._onFormSubmit.called, false);
|
||||
Assert.equal(FormAutofillContent._onFormSubmit.called, false);
|
||||
FormAutofillContent._onFormSubmit.reset();
|
||||
|
||||
// "_onFormSubmit" should be called as usual.
|
||||
Services.prefs.clearUserPref("extensions.formautofill.addresses.enabled");
|
||||
Services.prefs.clearUserPref("extensions.formautofill.creditCards.enabled");
|
||||
FormAutofillContent.notify(form);
|
||||
do_check_eq(FormAutofillContent._onFormSubmit.called, true);
|
||||
do_check_neq(FormAutofillContent._onFormSubmit.args[0][0].address, undefined);
|
||||
do_check_neq(FormAutofillContent._onFormSubmit.args[0][0].creditCard, undefined);
|
||||
Assert.equal(FormAutofillContent._onFormSubmit.called, true);
|
||||
Assert.notDeepEqual(FormAutofillContent._onFormSubmit.args[0][0].address, []);
|
||||
Assert.notDeepEqual(FormAutofillContent._onFormSubmit.args[0][0].creditCard, []);
|
||||
FormAutofillContent._onFormSubmit.reset();
|
||||
|
||||
// "address" should be empty if "addresses" pref is disabled.
|
||||
Services.prefs.setBoolPref("extensions.formautofill.addresses.enabled", false);
|
||||
FormAutofillContent.notify(form);
|
||||
do_check_eq(FormAutofillContent._onFormSubmit.called, true);
|
||||
do_check_eq(FormAutofillContent._onFormSubmit.args[0][0].address, undefined);
|
||||
do_check_neq(FormAutofillContent._onFormSubmit.args[0][0].creditCard, undefined);
|
||||
Assert.equal(FormAutofillContent._onFormSubmit.called, true);
|
||||
Assert.deepEqual(FormAutofillContent._onFormSubmit.args[0][0].address, []);
|
||||
Assert.notDeepEqual(FormAutofillContent._onFormSubmit.args[0][0].creditCard, []);
|
||||
FormAutofillContent._onFormSubmit.reset();
|
||||
Services.prefs.clearUserPref("extensions.formautofill.addresses.enabled");
|
||||
|
||||
// "creditCard" should be empty if "creditCards" pref is disabled.
|
||||
Services.prefs.setBoolPref("extensions.formautofill.creditCards.enabled", false);
|
||||
FormAutofillContent.notify(form);
|
||||
do_check_eq(FormAutofillContent._onFormSubmit.called, true);
|
||||
do_check_neq(FormAutofillContent._onFormSubmit.args[0][0].address, undefined);
|
||||
do_check_eq(FormAutofillContent._onFormSubmit.args[0][0].creditCard, undefined);
|
||||
Assert.deepEqual(FormAutofillContent._onFormSubmit.called, true);
|
||||
Assert.notDeepEqual(FormAutofillContent._onFormSubmit.args[0][0].address, []);
|
||||
Assert.deepEqual(FormAutofillContent._onFormSubmit.args[0][0].creditCard, []);
|
||||
FormAutofillContent._onFormSubmit.reset();
|
||||
Services.prefs.clearUserPref("extensions.formautofill.creditCards.enabled");
|
||||
|
||||
|
@ -566,7 +581,7 @@ TESTCASES.forEach(testcase => {
|
|||
FormAutofillContent.identifyAutofillFields(element);
|
||||
FormAutofillContent.notify(form);
|
||||
|
||||
do_check_eq(FormAutofillContent._onFormSubmit.called,
|
||||
Assert.equal(FormAutofillContent._onFormSubmit.called,
|
||||
testcase.expectedResult.formSubmission);
|
||||
if (FormAutofillContent._onFormSubmit.called) {
|
||||
Assert.deepEqual(FormAutofillContent._onFormSubmit.args[0][0],
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://formautofill/FormAutofillParent.jsm");
|
||||
let {FormAutofillParent} = Cu.import("resource://formautofill/FormAutofillParent.jsm", {});
|
||||
Cu.import("resource://formautofill/ProfileStorage.jsm");
|
||||
|
||||
add_task(async function test_profileSavedFieldNames_init() {
|
||||
|
|
|
@ -110,19 +110,19 @@ include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
|
|||
|
||||
ifeq (bundle, $(MOZ_FS_LAYOUT))
|
||||
BINPATH = $(_BINPATH)
|
||||
DEFINES += -DAPPNAME=$(_APPNAME)
|
||||
DEFINES += -DAPPNAME='$(_APPNAME)'
|
||||
else
|
||||
# Every other platform just winds up in dist/bin
|
||||
BINPATH = bin
|
||||
endif
|
||||
DEFINES += -DBINPATH=$(BINPATH)
|
||||
DEFINES += -DBINPATH='$(BINPATH)'
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
RESPATH = $(_APPNAME)/Contents/Resources
|
||||
else
|
||||
RESPATH = $(BINPATH)
|
||||
endif
|
||||
DEFINES += -DRESPATH=$(RESPATH)
|
||||
DEFINES += -DRESPATH="$(RESPATH)"
|
||||
|
||||
LPROJ_ROOT = $(firstword $(subst -, ,$(AB_CD)))
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
|
|
|
@ -171,10 +171,10 @@ endif
|
|||
ident:
|
||||
@printf 'fx_revision '
|
||||
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
|
||||
$(STAGEDIST)/application.ini App SourceStamp
|
||||
'$(STAGEDIST)'/application.ini App SourceStamp
|
||||
@printf 'buildid '
|
||||
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
|
||||
$(STAGEDIST)/application.ini App BuildID
|
||||
'$(STAGEDIST)'/application.ini App BuildID
|
||||
|
||||
# test target, depends on make package
|
||||
# try to repack x-test, with just toolkit/defines.inc being there
|
||||
|
|
|
@ -497,6 +497,9 @@ canvas.allow=Allow Data Access
|
|||
canvas.allow.accesskey=A
|
||||
canvas.remember=Always remember my decision
|
||||
|
||||
# Spoof Accept-Language prompt
|
||||
privacy.spoof_english=Changing your language setting to English will make you more difficult to identify and enhance your privacy. Do you want to request English language versions of web pages?
|
||||
|
||||
identity.identified.verifier=Verified by: %S
|
||||
identity.identified.verified_by_you=You have added a security exception for this site.
|
||||
identity.identified.state_and_country=%S, %S
|
||||
|
|
|
@ -15,4 +15,4 @@
|
|||
<!ENTITY languages.customize.selectLanguage.label "Select a language to add…">
|
||||
<!ENTITY languages.customize.addButton.label "Add">
|
||||
<!ENTITY languages.customize.addButton.accesskey "A">
|
||||
|
||||
<!ENTITY languages.customize.spoofEnglish "Request English versions of web pages for enhanced privacy">
|
||||
|
|
|
@ -5,32 +5,12 @@
|
|||
<!-- milon.morfix.co.il MozSearch plugin
|
||||
Compatible with Mozilla Firefox 2+
|
||||
Tomer Cohen, September 2006 - http://mozilla.org.il -->
|
||||
|
||||
|
||||
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>מילון מורפיקס</ShortName>
|
||||
<Description></Description>
|
||||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+g
|
||||
vaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gkdCRktdt52QwAAACR0
|
||||
RVh0Q29tbWVudABUb21lciBDb2hlbgp0b21lcmNAZ21haWwuY29tUau7swAAAxxJ
|
||||
REFUOMttk91rm2UYxq/7eZ/3fZO8SZqlcflct2at/YjokDJBPNAyHW4Hgw31wP9B
|
||||
kP0Bngw2QWHsxFOPdjJPhG1MEaqIddOWDbqxOmrStE3atGk+lrxJ3o/neTxYtlXx
|
||||
hpv74Oa64Oa+foQDpZQCAALAAPDhJADiQCsieqGh/4g5gCCAmO85cdFvhZVUJM0R
|
||||
O2AGGsTQJFAPgP/chA6IdQBxr7MzIde+m9Vqi+OsUxwl4ULo0dZecK4kXvvsYTqb
|
||||
faJpWuO5CQeAXrerBa1QzKuvnmD3L79n7P55grqVDKRrASAO6qfZcmV/69bY2utf
|
||||
BkLH37jfdBpNAJKqb09TMZM2kl9cyR+tfnNB37pzBv3GEQCaAgQ9O8sA4ChQ8fF+
|
||||
9IdL5vTNTlquCiUG2sUwo+ZGVTemvUzSXniX7NqbAPi+jcqDCisZnLXCpjIARAkI
|
||||
jZiOXyw1d5YIVWn6fQYACsCxSFUjuxYFoA181H4pmUsL1uc//n7k65/7RvoJABtA
|
||||
iGvInrS8XGptKjxWn2EcAJ6mQiogGgTpAkC372GjTIWVs+c/fliYmR11/thN4dFX
|
||||
efiuxYBgBH7o7NxpY/7UB8QBQHZcLJRT0zFnaqrbE/H1QWyCItnruUzW1Q2DfCsB
|
||||
MAOAKxXg+hKOyTX/cDKp+A1KKxUPQ7fzj47K1pzrdNHCYeTe+vSiETAPOY1iRt+7
|
||||
Ow7hWgAcV2Bvs2PVzEjcJkaSz9+4Tp7jUDqTIfb420uB7dtzuqoaJq721E/XFEkn
|
||||
Rp1yGsLVQahtNdVff4vJ4ju5XDcSjChemJkBAO5sL0eM+vejrL2SgvQPvUypYlBK
|
||||
Athp2Hhwd8u6xyfPrR8fHx+AoPgwksrr7Qv96UYPwm0PGWAApFQYeAL17bZa/W3T
|
||||
uree+GT59Pz79WQyKRhj4MMvuvKVk5srzfyi2N3dAxAeGvgKsEvt4HZZ5Ivs1Y/W
|
||||
z5z6sD5bKDicc3WQBVJSBsqVamxp8ddou93ShzsJYo5hjdj5Y2OdyYmJQSKREJqm
|
||||
qf+jkQAw3/eZEPIlrgTFGJOapiki+hfKAPAPFp9sbyN2GzAAAAAASUVORK5CYII=
|
||||
</Image>
|
||||
<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIACzAgAAJgAAACAgAAABACAAFQYAANkCAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAJ6SURBVDiNpZI7aN91FMU/9/H952URunQQE0qKhpYiFtFFRQe36iJa6upcRIoIulRXncW1gw5KKJWCIKhRFB9FEQpW0LZ2iAEflERo8s/ve+91+MXn6oWz3MfhcM6F/1kC8PD+k0ci67mqWgEoles15Vlb4IClPFJVc5VxVSIvrv2++t2/CB649cQxETknyGKSiAhmhqpcUtHbQPZXFZlBJb9l9nO70zzz2fbb6wC2NHfkNUHvKwJVxd1wV9zbATObUxNUBRkxr2LHROvBg/N3vPvj9uUtlWJBqL1jx5vTWqM1o02cNmkjWsPdEAP3dk9lexnOqC3NHl4X1ePmNu9u42JzmjuTyQzNG2b+l2MFVCVZHFqc3bhg16ffXjt4y9FNNz8+ynd84kzaDGJyUdReQvIbUb0LZLYqqSooZqrY9JHYNkQFVUVNcXPMdcPdTp796pUrAE8efmbTzV/tOiCqIEEVTyiAaJmIgMiYgjqm7fuzjy5c+zsv+RxJRHTMHhBhWf/7GFVFUSTFQ2v8Y173C8rowl4HthwgAkyTyqSyyEhSOmtrZ/pTd59eyl5PZ/ZTPTqZSY4eoFXvjPZGkCZkJpFB9KCKfuLQqeVhd7hgZSt96PQeI3kkVbWTwus+SinJSEICRFAGtGIQ5DEbbGU7bpKR9AgiAlKIzPN24+cvHCCrtiSCTlGAlRKhN7Eqw+kx7KlLCBhi93Lm8MLHrHUF2Gfty4IPK4XowXQYhmF3562hOL+zu7Peh6QPQQxJ7/2Dkunjn2yuXgUwgB+2L00X9c73cG7PzH2Qp9//5c03rmx+fWN5/uinEf3eHpER8aJ4PP/Rr6s//ZnEH4VnUn6KMJ1eAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAF3ElEQVRYhc2WW4idVxXHf2vtc6bJ1FwmVhqoSVD70DKpEPpgpRpDUaQ+iLZMaksf+tAYoUIQERQRCr4Z1IdQhYpGLC2paUuJFcT2YaSTlkBCq21iKcHamLb2emYaE2bmfHv9ffiuZ86M9k03Z/Nd+M76/9Zlr73hfzys+7B78627IH1ZaKewywwEIDCHokDHrprngaMczQB7PjKzVeHbXNqeIclsyYe8nq14V/3h28ffOXbhAwHcvOXmjRdjww8Fdxs+CSqVux+a4WZZxg9Stoci8R0z+yLoasNQhSqJULwH9pIpThTKDx1fePTkmgB72NOLqSvvc9LXQ3kV6UrcHTPHTAtYOt8znxYiFM13UglggFTGL8dwPuA3Qy8OnnjvsfNjtndv3rsb7EnBBCvEW2HD3DAMd8PMERrJXxkAIbUgklAEyAmGLwXsmxscnetquOArYGuK1zO5k1L9bCR3PKVmpua+811yLDmywOhf4/iRz07tvXEUQLpmZdi7wmMzeSWSGqiUKsBqNt91/mcu3NJVFvaLz6yf2d5qmS2Oek4Tcq9n8tY7r711Ui9VIKkBa+YIeGlPBO5+rU3Y9xoAxDNeZbMUXulx6qQhNcZT530TkZRwL4HSGhGUCdzu/NyWmU+XAOv0aFi8YeYtRLnk2vsqEmVUWvFaNKVxb807NupCrmYifSiLuwDSqxfPzG+/bOc5Qzd56k16lVer89mNQEpj4e2nPsn7pJRGUzi2RoyyT1RvFFMf3XT9kQRwbun0mR0bpl90/EsppfVN3n2ld3UNlDCYXcD5nSmOyXTajA+7+VRJ0hFXi1E3K7ApDYdP9hrI7C+QWDCzqdoDG0mDN6FNnhD8tdfr7dvyr8WTh84eWgK4Zdc9O3pL6UfJ015JzX+rsNSVVv9Izk1e609k77uZd0VHxKtrWVx2KfXZ/+DzB4/X4gCPPXffq/1l7RM65Z5K4BX1VDc0zJD8hgaAdZ24WZlMs9F3hpG8j9z+cH7jpmdZZTx49tD75nY4eV0TlceVTZqLMHS1j/y7EqFTQnVR1V4kT5jshdnZe4vVAKpxRgq8Xlkdm3UarNwqtvraNjrej92vsmN1Ryh11NYwYwC9/wKgzp2q5/+sDYBzveFVtdMuvRGTwmBpFECtkLrvyi3uA8nPTH9rC2Z3hnID0AVvlyII3mwBFivZUmt0S5UIgSKIHBSxevrv2PXtHcn0c5PtjIgGvuKvDSNRZ+hU0wcW18FEBrmw5nTTQrV7fYyF4WufPPApw2/Pw3yLiW05Su9VN52xCFYQZk+1jWgR1FNLHEIWRBhmAVGecrIHhdoI3Hbdgf0KO5gsbcixTI5MhIgIIgKFCJVT1bNkiFggp04nBEIZizorUXWvoD50mRmRS8MAM9fe8wUV8VPM1i9psRSLKFNWAYRqkCghJEyGFLOX3t/095EiVBPqlfmvjNUCIcG9noNvIl9f5KIBU6gCqY9k4/ayigL88CnuH/ZGAUoxCwMcLEbaklkJUOScv/qJf16Rs67D2oNpGe42At1I1NEpvdfjT8/rCYAGwBlKWCgEXhabwgiEVWvGzMgWZEUeZp/suyZFbgpTtB7X4Y6o3wXIyMqvKdv34bd5FMAuHxRcmkdUOe40zno7MCMXBaZ4u7gYA98YC45dKUVzKo6q4luAaKKhiIsB35i78PDLrePVmJ3/9bzLnil3KY1UcoTIVRiXY3kBsxNPDe5fyDmfVEDOmci5vVb9oilYQeRYCPLdc4OHn+imfaQIe/CTUD7npA59bVgoIIr41e//8csXAYbBj4fF8rsKI+cgRzTiOedSPIyIOK0obnt68MgRVozUfXhl6fRg27rpP2PcYPgVTUMuLzmTH/Dh8nf/tnhmCeCVC8+/8bHJ6bOIGyU2Nqug6iWhGEj5cM9j/5/mH3lupTis2OLqsefyma3FhN9lituBKbC/mPEzH7z1x1lmx/rw5zfd8XH1OBDErZI2h3hZ4nH1ODL3Tpvv/8vxb8af5VHCgdKPAAAAAElFTkSuQmCC</Image>
|
||||
<Url type="text/html" method="GET" template="http://milon.morfix.co.il/default.aspx" resultdomain="morfix.co.il">
|
||||
<Param name="q" value="{searchTerms}"/>
|
||||
</Url>
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
<ShortName>楽天市場</ShortName>
|
||||
<Description>楽天市場 商品検索</Description>
|
||||
<InputEncoding>EUC-JP</InputEncoding>
|
||||
<Image width="16" height="16">data:image/x-icon;base64,R0lGODlhEAAQALMOAOefn9psbMswMMMQEPjj4/PPz++/v+OPj99/f9+AgMcgIM9AQOuvr////wAAAL8AACH5BAEAAA4ALAAAAAAQABAAAARf0EnJ0FqIze2YemCoaBsQniEwMeIloOQHJk1NvKDSnTRQNIZThddYPAiNk4UYCDQIpwux1ghEEUTGc6BkhWiLA1DokD3Ag5/1odvlFlzFAkdymFAn1caDH3FWFhh1EhEAOw==</Image>
|
||||
<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAEAIACYAgAAJgAAACAgAAABACAARwUAAL4CAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAJfSURBVDiNdZFLSJRhFIaf8/9jOoFa3tLEBC/JCEU5yUgGahIS5TIqiCxTNIiKpCiiVWJBpV0Iw9vGnbMqokW6kYRJZCK6qRNmXhJprMzQ0XH8vxZOo47T2Z7zPuc95xWCytV4J3ug6WE5IoWiSFWiDIEhFJ3Z1TWt6VUXR1fPS0DoehE+cLT6NnBOBFMwGADFXNweW11eU0ediKgAwC9+KkJJSOE6jmordY5WiIjSAQ70vLorwgkApQyiMi1EZWSxMXkb4THxLEx9B8MAEb9t2f3D6fjd+ubTaxl83GBxtTS8R9ABDK+X3PttJBUfDGycGx/BUXUMz+TEigulZjLKr6TpJZP91xDyA42lJZJLSjEnJNF3qZJf75wkFR8iMiOLsWd2RNeXXYiEa5oxblJQEPjkqjJ8i7gd3SzNe9iybz/Rlp2Iae1vp5yOIpMoUglBEE0nMi2TiMStbN6Vy5/P/SjfIhK2YdWQpJiWc15PCIuKpsDeBcDizDQf62+imcKC4zA0UXwJcQE+zxyDT+5heL3Mfhtj+sPbQAorBhjWELpCAYyFeQYb6+l/dItNlh1Yzl/F8PnWzMTm2Dq17KqaZqXUfDBaNB3NZGKovQm3o5v0srMk5BeCUn73uDNPXegQAEflketTzt5aAKUU5oRE9Agzs2NfAdDDIzAnJePzzOGZnEBEiLHaTuY329vFL9KeW1NbgNOhzgmuWKutdm+z/QaAtuxYjMPOkTMxVttlpdTM/4QK3LE5eWX/xMD6/FytD+LdvT3Hf/b1FikhRcBAMRxrtb3cXlFjj8vLW7PgL85j5b2Pva1GAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFDklEQVRYha2Wa2xUVRSFv33ubadT2lLCQwSngwQRCYVCiwIqSIgPEHkkPDQQoyYYjBgjCBgfGFCDkT/8UjCRVE0UwYhUXlEiEiJRbCkgNEKgQikoD0npTDvtzL13+6N0+hqmM4SVTHLu3mevte6dk7O3kCK+n3BvrmluHI/HQ4KMVNGgQL6qeMBVhDNApYi3v7yitnw1eKnwSncbto0KDrIs7yVgviDBVEgVPWJUNjl+f+msgydDt2Rg3yTscCiwQpHXBXqlItzVCKeM8Pb0ipqtaRkoKx5cgBcrFZHJtyKcABsiTTmvzquqinZroKw4OAxPd4ow+DaJ34DuznSicx8/dqmhfdS0f9hVOPAuUW/X7RcHkKlRK3PzvknY7aNW66K8uDjjuolsF6Soa63gOTGchga8aHOXn8aigCCW1aW0E8/Q5mhe1tf/1O+Nh1oXZcWBN0RlbaI6L9pMr1ElFMx6uktOXZdwTTWXD/xM/akqLH82YkwClhv7QfG8yTOO1O6PG9hWMiBgu9YJRHITFTnhEIPmPkvR++tvSuxGGjnz+Qb++ngdYtnJTSiHKiprxq8GzwBYnrXkZuJA/C9IBsufzdDFSxmxYg1uUyTpXhHuLykOPgFgtgzvmwOyIGlFJzjhELU7vuX89m+4+NMOYvXX47nBCxfRb8IjuJHkJvD0RQDb588aL8rAdAxELv9LxfLFuLEYiJA/vJBxn3xF9oAAAIHZz3D5133JSUQn7Srq39cYZWI64gBiDHZOLhm5eWTm9aTuz0rObi6N53vecx9Wdg/US9YOJN+xMkYbRUama6CrIYtYuL7t2baSHsL4PkyhDRpMoSd1gHoeTjiE5zioemTm9SIwY34833ihBqexAdufnZzI8wpsID8tdSAzL5+7Fy5CHQfL72fg1Nn0Khwdz1/YUwZJP38rJM+WFPt2e/j69GXkWwnvLK4dLefinu1Y3b09oKKeAbmaroHEbMqV3w9QvnQRbiya2hlQrhmgOl0tz4nRWHuOWLht1lDg7JYvCFWfwvJlpUZkqDYoh9M10HjhPL/MmcKBBU/SdPkSACJC4cr3yBsyDLepKSUeceWoUfW6uTESQBUvFqPu+BGOrlkOqgBk9evPyFUfgWo3dwAAFxujkWMmt2dtJXAiXQ9iDBl5Pbn4Yxlnvvw0Hr/j4SkMeeFlnHDSURBV3Tmv6krYTN6PI8rGdA20ws7uQdX6D6g7fiQeG7ZkJb3HTsBpbEhYo6BGZCPcmIgcv79U0XNJ7CJW2yBjZfnja7Fs3KYIlateiwtaPh8l6zaS1a8/6jhd6AT9bvrhmoqW9Q38UFQwB0PC6dVzHHoEgvQe/QAAsXCISwf2tlw20kLhNkXoM/ZBehQMQlUxGZn898dBwjV/Y+w286pabxvGTKs4f6aDAYCy0YFPRWRRV8uCxmK4zS2nW4xJeNG4zU0d3tjK8iO2HT+kAB76/MzD50tbnzsMiHbI94qbGw0iPNaBWRWxbWw7J9EHahP0ZYGvU7CduCprZ1a2iUOnqXja6dPNrt8/R1V3JlW6BaiydkZlzZud4wnb4L5J2KH6wIcisuw2SNehZtlTlec2Jcom7cPbiwOPGo81iIy7JWllq2eZd2aVnz15sz3dDgLvgikZE5yp6HOCTgRJ2r5VqRV0jyfms5mHz/3WHX9ak8ju4oI7Y64UYXSEqAYVyRFQhGsK1YIes2zf0WmHTtd3z9aC/wGRJv+fU1BOjgAAAABJRU5ErkJggg==</Image>
|
||||
<Url type="text/html" method="GET" template="https://pt.afl.rakuten.co.jp/c/013ca98b.cd7c5f0c/" resultdomain="rakuten.co.jp">
|
||||
<Param name="sitem" value="{searchTerms}"/>
|
||||
<Param name="sv" value="2"/>
|
||||
<Param name="p" value="0"/>
|
||||
</Url>
|
||||
<SearchForm>http://www.rakuten.co.jp/</SearchForm>
|
||||
<SearchForm>https://www.rakuten.co.jp/</SearchForm>
|
||||
</SearchPlugin>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.ru/suggest-ff.cgi">
|
||||
<Param name="part" value="{searchTerms}"/>
|
||||
</Url>
|
||||
<Url type="text/html" method="GET" template="https://yandex.ru/yandsearch" resultdomain="yandex.ru">
|
||||
<Url type="text/html" method="GET" template="https://yandex.ru/search" resultdomain="yandex.ru">
|
||||
<MozParam name="clid" condition="purpose" purpose="searchbar" value="2186618"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="keyword" value="2186621"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="contextmenu" value="2186623"/>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.by/suggest-ff.cgi">
|
||||
<Param name="part" value="{searchTerms}"/>
|
||||
</Url>
|
||||
<Url type="text/html" method="GET" template="https://yandex.by/yandsearch" resultdomain="yandex.by">
|
||||
<Url type="text/html" method="GET" template="https://yandex.by/search" resultdomain="yandex.by">
|
||||
<MozParam name="clid" condition="purpose" purpose="searchbar" value="2186618"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="keyword" value="2186621"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="contextmenu" value="2186623"/>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.kz/suggest-ff.cgi">
|
||||
<Param name="part" value="{searchTerms}"/>
|
||||
</Url>
|
||||
<Url type="text/html" method="GET" template="https://yandex.kz/yandsearch" resultdomain="yandex.kz">
|
||||
<Url type="text/html" method="GET" template="https://yandex.kz/search" resultdomain="yandex.kz">
|
||||
<MozParam name="clid" condition="purpose" purpose="searchbar" value="2186618"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="keyword" value="2186621"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="contextmenu" value="2186623"/>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.ru/suggest-ff.cgi">
|
||||
<Param name="part" value="{searchTerms}"/>
|
||||
</Url>
|
||||
<Url type="text/html" method="GET" template="https://yandex.ru/yandsearch" resultdomain="yandex.ru">
|
||||
<Url type="text/html" method="GET" template="https://yandex.ru/search" resultdomain="yandex.ru">
|
||||
<MozParam name="clid" condition="purpose" purpose="searchbar" value="2186618"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="keyword" value="2186621"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="contextmenu" value="2186623"/>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.com.tr/suggest-ff.cgi">
|
||||
<Param name="part" value="{searchTerms}"/>
|
||||
</Url>
|
||||
<Url type="text/html" method="GET" template="https://yandex.com.tr/yandsearch" resultdomain="yandex.com.tr">
|
||||
<Url type="text/html" method="GET" template="https://yandex.com.tr/search" resultdomain="yandex.com.tr">
|
||||
<MozParam name="clid" condition="purpose" purpose="searchbar" value="2186618"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="keyword" value="2186621"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="contextmenu" value="2186623"/>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<Url type="application/x-suggestions+json" method="GET" template="https://suggest.yandex.ua/suggest-ff.cgi">
|
||||
<Param name="part" value="{searchTerms}"/>
|
||||
</Url>
|
||||
<Url type="text/html" method="GET" template="https://www.yandex.ua/yandsearch" resultdomain="yandex.ua">
|
||||
<Url type="text/html" method="GET" template="https://www.yandex.ua/search" resultdomain="yandex.ua">
|
||||
<MozParam name="clid" condition="purpose" purpose="searchbar" value="2186618"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="keyword" value="2186621"/>
|
||||
<MozParam name="clid" condition="purpose" purpose="contextmenu" value="2186623"/>
|
||||
|
|
|
@ -4,10 +4,7 @@
|
|||
|
||||
%include ../../../shared/incontentprefs/dialog.inc.css
|
||||
|
||||
label,
|
||||
textbox,
|
||||
description,
|
||||
.tab-text,
|
||||
menulist label {
|
||||
font-size: 1.11rem;
|
||||
:root > * {
|
||||
font-size: 1.05em;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,19 +4,8 @@
|
|||
|
||||
%include ../../../shared/incontentprefs/preferences.inc.css
|
||||
|
||||
html *,
|
||||
page *,
|
||||
window * {
|
||||
font-size: 1.11rem;
|
||||
}
|
||||
|
||||
caption label {
|
||||
font-size: 1.27rem;
|
||||
}
|
||||
|
||||
.tip-caption,
|
||||
.help-label {
|
||||
font-size: 1rem;
|
||||
:root > * {
|
||||
font-size: 1.11em;
|
||||
}
|
||||
|
||||
.treecol-sortdirection {
|
||||
|
@ -24,20 +13,9 @@ caption label {
|
|||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
.actionsMenu {
|
||||
font-family: "Clear Sans", sans-serif;
|
||||
font-size: 1.25rem;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.actionsMenu > .menulist-label-box > .menulist-icon {
|
||||
margin-top: 1px;
|
||||
margin-inline-start: 1px;
|
||||
margin-inline-end: 6px;
|
||||
}
|
||||
|
||||
.actionsMenu > .menulist-label-box > .menulist-label {
|
||||
margin-top: 2px !important;
|
||||
margin-inline-end: 8px;
|
||||
}
|
||||
|
||||
filefield + button {
|
||||
|
|
|
@ -9,12 +9,8 @@ prefwindow,
|
|||
font: message-box !important;
|
||||
}
|
||||
|
||||
label,
|
||||
textbox,
|
||||
description,
|
||||
.tab-text,
|
||||
menulist label {
|
||||
font-size: 1.36rem;
|
||||
:root > * {
|
||||
font-size: 1.18em;
|
||||
}
|
||||
|
||||
caption {
|
||||
|
|
|
@ -4,19 +4,8 @@
|
|||
|
||||
%include ../../../shared/incontentprefs/preferences.inc.css
|
||||
|
||||
html *,
|
||||
page *,
|
||||
window * {
|
||||
font-size: 1.36rem;
|
||||
}
|
||||
|
||||
caption label {
|
||||
font-size: 1.55rem;
|
||||
}
|
||||
|
||||
.tip-caption,
|
||||
.help-label {
|
||||
font-size: 1.18rem;
|
||||
:root > * {
|
||||
font-size: 1.36em;
|
||||
}
|
||||
|
||||
.actionsMenu > .menulist-label-box > .menulist-icon {
|
||||
|
|
|
@ -1,59 +1,62 @@
|
|||
<!-- 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/. -->
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 173.87 156.5">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 173.9 156.5">
|
||||
<style>
|
||||
.cls-1{fill:#eaeaee;}
|
||||
.cls-2{fill:#fff;}
|
||||
.cls-3{fill:url(#linear-gradient);}
|
||||
.cls-4{fill:#f9f9fa;}
|
||||
.cls-5{fill:url(#New_Gradient_Swatch_1);}
|
||||
.cls-6{fill:url(#New_Gradient_Swatch_1-2);}
|
||||
.cls-7{fill:url(#New_Gradient_Swatch_1-3);}
|
||||
.cls-8{fill:url(#New_Gradient_Swatch_1-4);}
|
||||
.cls-9{fill:url(#linear-gradient-2);}
|
||||
.cls-10{fill:url(#New_Gradient_Swatch_1-5);}
|
||||
.st0{opacity:0.1;fill:#0C0C0D;enable-background:new ;} .st1{fill:#FFFFFF;} .st2{fill:url(#SVGID_1_);} .st3{fill:#F9F9FA;} .st4{fill:url(#SVGID_2_);} .st5{fill:url(#SVGID_3_);} .st6{fill:url(#SVGID_4_);} .st7{fill:url(#SVGID_5_);} .st8{fill:url(#SVGID_6_);} .st9{fill:url(#SVGID_7_);}
|
||||
</style>
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient" x1="55.45" y1="55.54" x2="128.28" y2="128.38" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#ccfbff"/>
|
||||
<stop offset="1" stop-color="#c9e4ff"/>
|
||||
<path class="st0" d="M140.9 152h-69c-.6 0-1-.4-1-1s.4-1 1-1H141c.6 0 1 .4 1 1s-.5 1-1.1 1zm-9.3-5.1h-12c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h12c.3 0 .5.2.5.5s-.2.5-.5.5zm-15.7 9.6h-12c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h12c.3 0 .5.2.5.5s-.2.5-.5.5zm-20 0h-3c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h3c.3 0 .5.2.5.5s-.2.5-.5.5zm-7 0h-1c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h1c.3 0 .5.2.5.5s-.2.5-.5.5zm-10 0h-12c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h12c.3 0 .5.2.5.5s-.2.5-.5.5zm-20 0h-3c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h3c.3 0 .5.2.5.5s-.2.5-.5.5zm-7 0h-1c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h1c.3 0 .5.2.5.5s-.2.5-.5.5zm-10 0h-12c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h12c.3 0 .5.2.5.5s-.2.5-.5.5zm-20 0h-3c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h3c.3 0 .5.2.5.5s-.2.5-.5.5zm-7 0h-1c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h1c.3 0 .5.2.5.5s-.2.5-.5.5z"/>
|
||||
<path class="st1" d="M85 20.4h21.3s-6.7-14.9 7.5-16.8c12.6-1.7 17.6 11.3 17.6 11.3s1.5-7.5 9-6.1 12.9 13.3 12.9 13.3h18.6"/>
|
||||
<path class="st0" d="M172.2 18.6h-4c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h4c.3 0 .5.2.5.5s-.2.5-.5.5zm-13 0h-1c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h1c.3 0 .5.2.5.5s-.2.5-.5.5zm-5 0h-.8c-.1-.1-.2-.1-.2-.2-.1-.2-.5-1-1.2-2.1-.1-.2-.1-.5.2-.7.2-.1.5-.1.7.2.5.8.9 1.5 1.1 1.9h.2c.3 0 .5.2.5.5s-.2.4-.5.4zm-47.5-.6h-1.3c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h.6c-.1-.2-.2-.6-.3-.9-.1-.3.1-.6.3-.7.3-.1.6.1.7.3.3.9.6 1.5.6 1.5.1.3 0 .5-.3.7-.1.1-.2.1-.3.1zm-9.3 0h-12c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h12c.3 0 .5.2.5.5s-.3.5-.5.5zm7.8-5.5c-.3 0-.5-.2-.5-.4 0-.3-.1-.7-.1-1s.2-.5.5-.5.5.2.5.5 0 .6.1 1c.1.2-.1.4-.5.4.1.1.1.1 0 0zm26.2-1c-.2 0-.4-.1-.4-.3-.1-.2-.3-.5-.4-.9-.1-.2 0-.5.2-.7.2-.1.5 0 .7.2.2.3.3.6.5.9.1.2 0 .5-.2.7-.3.1-.3.1-.4.1zm16.1-1.3c-.1 0-.3 0-.4-.1-1.7-1.8-4-3.1-6.4-3.7-1.3-.3-2.6-.2-3.9.2-.3.1-.5-.1-.6-.3-.1-.3.1-.5.3-.6 1.4-.4 2.9-.5 4.4-.2 2.6.6 5.1 2 6.9 4 .2.2.2.5 0 .7-.1-.1-.2 0-.3 0zm-18.8-3c-.2 0-.3-.1-.4-.2-.6-.8-1.3-1.5-2-2.1-.2-.2-.1-.5.1-.7.2-.1.4-.1.6 0 .8.7 1.5 1.4 2.1 2.2.2.2.1.5-.1.7 0 .1-.2.1-.3.1zm-20.5-3.8c-.3 0-.5-.2-.5-.5 0-.2.1-.3.2-.4 1.8-1.3 4-2.2 6.2-2.4 1.9-.3 3.8-.2 5.7.2.3.1.5.3.4.6s-.3.5-.6.4c-1.7-.4-3.5-.4-5.3-.2-2.1.2-4.1.9-5.7 2.2-.2.1-.3.1-.4.1z"/>
|
||||
<path class="st1" d="M172.9 22.4H85c-.6 0-1-.4-1-1s.4-1 1-1h87.9c.6 0 1 .4 1 1s-.5 1-1 1zM.8 37.7h11.9s-3.7-8.3 4.2-9.4c7-1 9.8 6.3 9.8 6.3s.8-4.2 5-3.4 7.2 7.4 7.2 7.4h10.3"/>
|
||||
<path class="st0" d="M13 36.4H1.1c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h11.5c.2-.2.5-.2.7 0l.1.1v.1c.1.3 0 .5-.3.7 0 .1-.1.1-.1.1zm32.9-.2h-3c-.3 0-.5-.2-.5-.5s.2-.5.5-.5h3c.3 0 .5.2.5.5s-.2.5-.5.5zM27 33h-.1c-.3-.1-.4-.4-.3-.6.5-2 2.3-3.5 4.4-3.5.4 0 .7 0 1.1.1 1.9.5 3.6 1.5 4.9 3 .2.2.2.5 0 .7s-.5.2-.7 0c-1.1-1.3-2.6-2.3-4.3-2.7-.3-.1-.6-.1-.9-.1-1.7 0-3.1 1.2-3.4 2.8-.3.2-.5.3-.7.3zm-13.6-4.3c-.3 0-.5-.2-.5-.5 0-.1.1-.3.1-.4.8-.8 1.8-1.3 2.8-1.6.3-.1.6.1.6.4s-.1.6-.4.6c-.9.2-1.7.7-2.4 1.3.1.2 0 .2-.2.2zm7.5-1.3h-.1c-.3-.1-.6-.2-.9-.2-.3-.1-.5-.3-.4-.6.1-.3.3-.5.6-.4.3.1.7.2 1 .3.3 0 .5.3.4.6 0 .1-.3.3-.6.3z"/>
|
||||
<path class="st1" d="M49.9 39.7H1c-.6 0-1-.4-1-1s.4-1 1-1h48.8c.6 0 1 .4 1 1s-.4 1-.9 1zm85.5 37.5h-15.3V60.3c0-4.2-3.4-7.5-7.6-7.5H51.1c-4.2 0-7.5 3.4-7.5 7.5V101c0 1.3.4 2.6 1 3.7-.4.5-.8 1-1 1.6l-6.9 16.1c-.3.7-.5 1.5-.5 2.3v1.1c.1 3.4 2.8 6.1 6.2 6h60v3.2c0 4.1 3.3 7.4 7.4 7.4h25.6c4.1 0 7.4-3.3 7.4-7.4V84.7c.1-4.2-3.2-7.5-7.4-7.5z"/>
|
||||
<path class="st1" d="M50.8 56.5h61.4c2 0 3.6 1.6 3.6 3.5v40.7c0 2-1.6 3.6-3.6 3.6H50.8c-2 0-3.5-1.6-3.5-3.6V60.1c0-2 1.6-3.6 3.5-3.6z"/>
|
||||
<path class="st1" d="M52.7 62.5h57.7c1.2 0 2.1.9 2.1 2.1V99c0 1.2-.9 2.1-2.1 2.1H52.7c-1.2 0-2.1-.9-2.1-2.1V64.6c0-1.1 1-2.1 2.1-2.1z"/>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="55.4468" y1="665.5432" x2="128.2768" y2="738.3832" gradientTransform="translate(.02 -609.83)">
|
||||
<stop offset="0" stop-color="#CCFBFF"/>
|
||||
<stop offset="1" stop-color="#C9E4FF"/>
|
||||
</linearGradient>
|
||||
<path class="st2" d="M110.4 63.5c.6 0 1.1.5 1.1 1.1V99c0 .6-.5 1.1-1.1 1.1H52.7c-.6 0-1.1-.5-1.1-1.1V64.6c0-.6.5-1.1 1.1-1.1h57.7"/>
|
||||
<path class="st3" d="M115.7 107.6c-.4-.8-1.2-1.3-2.1-1.2H49c-.9 0-1.7.5-2.1 1.3L40 123.8c-.1.2-.1.5-.1.7v1.1c.1 1.2 1 2.1 2.2 2H121c1.2.1 2.2-.8 2.2-2v-1c0-.3-.1-.5-.2-.7l-7.3-16.3z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="-4.5021" y1="627.6644" x2="182.4979" y2="797.1644" gradientTransform="translate(.02 -609.83)">
|
||||
<stop offset="0" stop-color="#00C8D7"/>
|
||||
<stop offset="1" stop-color="#0A84FF"/>
|
||||
</linearGradient>
|
||||
<path class="st4" d="M124.9 122.9l-7.3-16.1c-.3-.8-.9-1.4-1.6-1.8 1.2-1.1 1.9-2.6 1.9-4.2V60.1c0-3.1-2.5-5.5-5.6-5.5H50.9c-3.1 0-5.5 2.5-5.5 5.5v40.7c0 1.5.6 3 1.7 4-.9.4-1.6 1.1-2 2L38.2 123c-.2.5-.3 1-.3 1.5v1.1c.1 2.3 1.9 4.1 4.2 4H121c2.3.1 4.2-1.7 4.2-4v-1c0-.6-.1-1.2-.3-1.7zm-1.7 2.6c-.1 1.2-1 2.1-2.2 2H42.1c-1.2.1-2.2-.8-2.2-2v-1.1c0-.2 0-.5.1-.7l6.9-16.1c.4-.8 1.2-1.3 2.1-1.3h64.7c.9 0 1.7.5 2.1 1.2l7.3 16.1c.1.2.2.5.2.7l-.1 1.2zm-75.9-24.7V60.1c0-2 1.6-3.5 3.5-3.5h61.4c2 0 3.6 1.6 3.6 3.5v40.7c0 2-1.6 3.6-3.5 3.6H50.9c-2 0-3.6-1.6-3.6-3.6z"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-51.3994" y1="590.94" x2="201.6006" y2="840.94" gradientTransform="translate(.02 -609.83)">
|
||||
<stop offset="0" stop-color="#00C8D7"/>
|
||||
<stop offset="1" stop-color="#0A84FF"/>
|
||||
</linearGradient>
|
||||
<path class="st5" d="M94.7 121.8H68.4c-.4 0-.8-.2-.8-.5.3-1.7.5-2.6.8-4.4 0-.2.3-.4.7-.4l25.3-.2c.4 0 .7.2.7.4.2 1.5.4 3 .4 4.5.1.4-.3.6-.8.6zM64 112.4h-3.9c-.3 0-.6.2-.7.4-.1.5-.2.7-.3 1.2s.4.7.9.7h3.8c.3 0 .6-.1.7-.3.1-.5.2-.7.3-1.2s-.3-.8-.8-.8zm9.9 0h-4.1c-.4 0-.7.2-.7.4-.1.5-.1.7-.2 1.2-.1.3.4.6.9.6h3.9c.3 0 .6-.1.7-.4.1-.5.2-.7.3-1.2.1-.4-.3-.7-.8-.6zm20.5 1.4c-.1-.5-.1-.7-.2-1.2 0-.2-.3-.4-.7-.4h-4.1c-.5 0-.9.3-.9.6l.3 1.2c0 .2.3.4.7.4h3.9c.6 0 1.1-.3 1-.6zm-9.9.1l-.2-1.2c0-.2-.4-.4-.8-.4h-3.7c-.4 0-.8.2-.8.4-.1.5-.2.7-.2 1.2-.1.3.3.6.8.6h4.1c.4-.1.8-.3.8-.6zm19.6-.2l-.2-1.2c0-.2-.3-.3-.6-.3h-3.9c-.5 0-1 .3-.9.7l.3 1.2c.1.2.3.3.7.3h3.8c.4-.1.9-.4.8-.7zm-39.1-5h-3.7c-.3 0-.5.1-.6.3-.1.4-.2.7-.3 1.1s.3.6.8.6h3.6c.3 0 .5-.1.7-.3.2-.4.2-.7.4-1.1s-.4-.6-.9-.6zm9.4 0h-3.9c-.4 0-.7.2-.7.4-.1.4-.2.7-.3 1.1s.3.6.8.6h3.8c.3 0 .6-.1.7-.4.1-.4.2-.7.3-1.1s-.3-.6-.7-.6zm19.6 1.4l-.2-1.1c0-.2-.3-.4-.7-.4h-3.9c-.5 0-.9.3-.8.6l.2 1.1c0 .2.3.4.7.4h3.8c.5-.1.9-.3.9-.6zm-9.5.1l-.2-1.1c0-.2-.3-.4-.7-.4H80c-.4 0-.7.2-.8.4-.1.4-.2.7-.3 1.1-.1.3.3.5.8.5h3.9c.5 0 .9-.3.9-.5zm18.7-.1l-.2-1.1c0-.2-.3-.3-.6-.3h-3.7c-.5 0-1 .3-.9.6l.3 1.1c.1.2.3.3.6.3h3.6c.5-.1.9-.4.9-.6zm-48.1 2.4h-3.8c-.3 0-.6.1-.7.4-.2.4-.3.8-.4 1.2-.1.3.4.7.9.7h3.7c.3 0 .6-.2.6-.4.1-.4.2-.8.4-1.2.2-.5-.2-.8-.7-.7zm1.3-3.7h-3.5c-.2 0-.5.1-.6.3-.1.4-.2.7-.4 1.1-.1.3.2.6.7.6h3.5c.3 0 .5-.1.7-.3.2-.4.3-.7.5-1.1s-.4-.7-.9-.6zm50.9 4.1c.1.4.3.8.3 1.1 0 .2.3.3.6.3h3.7c.5 0 1-.3.9-.6-.1-.4-.2-.8-.3-1.1-.1-.2-.4-.4-.7-.3h-3.7c-.5-.1-.9.2-.8.6zm-1.1-3.7c.1.4.2.7.4 1.1.1.2.4.3.6.3h3.4c.5 0 .8-.3.8-.6-.1-.4-.2-.7-.3-1.1 0-.2-.2-.3-.6-.3H107c-.4 0-.9.3-.8.6z"/>
|
||||
<g>
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-22.6206" y1="563.3309" x2="225.3794" y2="813.3309" gradientTransform="translate(0 -610)">
|
||||
<stop offset="0" stop-color="#00C8D7"/>
|
||||
<stop offset="1" stop-color="#0A84FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="New_Gradient_Swatch_1" x1="-4.48" y1="17.64" x2="182.52" y2="187.14" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#00c8d7"/>
|
||||
<stop offset="1" stop-color="#0a84ff"/>
|
||||
<circle class="st6" cx="82.6" cy="59.4" r="1.2"/>
|
||||
</g>
|
||||
<path class="st1" d="M109.6 80h25.6c2.5 0 4.4 2 4.4 4.4v50.3c0 2.5-2 4.4-4.4 4.4h-25.6c-2.5 0-4.4-2-4.4-4.4V84.4c-.1-2.4 1.9-4.4 4.4-4.4z"/>
|
||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="-19.2553" y1="590.7758" x2="221.2447" y2="809.2758" gradientTransform="translate(.02 -609.83)">
|
||||
<stop offset="0" stop-color="#00C8D7"/>
|
||||
<stop offset="1" stop-color="#0A84FF"/>
|
||||
</linearGradient>
|
||||
<path class="st7" d="M135.1 81c1.9 0 3.4 1.5 3.4 3.4v50.3c0 1.9-1.5 3.4-3.4 3.4h-25.6c-1.9 0-3.4-1.5-3.4-3.4V84.4c0-1.9 1.5-3.4 3.4-3.4h25.6m0-2h-25.6c-3 0-5.4 2.4-5.4 5.4v50.3c0 3 2.4 5.4 5.4 5.4h25.6c3 0 5.4-2.4 5.4-5.4V84.4c.1-3-2.4-5.4-5.4-5.4z"/>
|
||||
<g>
|
||||
<path class="st1" d="M111.1 84.8h22.4c.9 0 1.7.8 1.7 1.7v41.9c0 .9-.8 1.7-1.7 1.7h-22.4c-.9 0-1.7-.8-1.7-1.7V86.5c0-.9.8-1.7 1.7-1.7z"/>
|
||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="62.995" y1="657.995" x2="135.835" y2="730.835" gradientTransform="translate(.02 -609.83)">
|
||||
<stop offset="0" stop-color="#CCFBFF"/>
|
||||
<stop offset="1" stop-color="#C9E4FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="New_Gradient_Swatch_1-2" x1="-51.35" y1="-19.11" x2="201.65" y2="230.89" xlink:href="#New_Gradient_Swatch_1"/>
|
||||
<linearGradient id="New_Gradient_Swatch_1-3" x1="-22.65" y1="-46.64" x2="225.35" y2="203.36" xlink:href="#New_Gradient_Swatch_1"/>
|
||||
<linearGradient id="New_Gradient_Swatch_1-4" x1="-19.25" y1="-19.23" x2="221.25" y2="199.27" xlink:href="#New_Gradient_Swatch_1"/>
|
||||
<linearGradient id="linear-gradient-2" x1="63.01" y1="47.98" x2="135.85" y2="120.82" xlink:href="#linear-gradient"/>
|
||||
<linearGradient id="New_Gradient_Swatch_1-5" x1="-73.41" y1="91.75" x2="262.92" y2="91.75" xlink:href="#New_Gradient_Swatch_1"/>
|
||||
</defs>
|
||||
<path class="cls-1" d="M140.93,151.83H71.85a1,1,0,0,1,0-2h69.08a1,1,0,0,1,0,2Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-1" d="M131.6,146.72h-12a.5.5,0,0,1,0-1h12a.5.5,0,1,1,0,1Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-1" d="M115.89,156.33h-12a.5.5,0,1,1,0-1h12a.5.5,0,0,1,0,1Zm-20,0h-3a.5.5,0,0,1,0-1h3a.5.5,0,1,1,0,1Zm-7,0h-1a.5.5,0,0,1,0-1h1a.5.5,0,1,1,0,1Zm-10,0h-12a.5.5,0,0,1,0-1h12a.5.5,0,1,1,0,1Zm-20,0h-3a.5.5,0,1,1,0-1h3a.5.5,0,0,1,0,1Zm-7,0h-1a.5.5,0,1,1,0-1h1a.5.5,0,0,1,0,1Zm-10,0h-12a.5.5,0,1,1,0-1h12a.5.5,0,0,1,0,1Zm-20,0h-3a.5.5,0,1,1,0-1h3a.5.5,0,0,1,0,1Zm-7,0h-1a.5.5,0,1,1,0-1h1a.5.5,0,0,1,0,1Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-2" d="M85,20.23H106.3S99.63,5.33,113.8,3.4c12.63-1.72,17.62,11.27,17.62,11.27s1.5-7.49,9-6.05S153.3,21.94,153.3,21.94h18.57" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-1" d="M172.23,18.44h-4a.5.5,0,0,1,0-1h4a.5.5,0,0,1,0,1Zm-13,0h-1a.5.5,0,1,1,0-1h1a.5.5,0,1,1,0,1Zm-5,0h-.56a.5.5,0,0,1-.22-.05.54.54,0,0,1-.23-.23c-.11-.22-.53-1-1.2-2.08a.5.5,0,0,1,.85-.53c.53.84.9,1.52,1.1,1.89h.25a.5.5,0,1,1,0,1Zm-47.56-.61h-1.32a.5.5,0,1,1,0-1h.58c-.09-.25-.2-.56-.32-.92a.5.5,0,1,1,1-.31c.3.93.56,1.52.56,1.53a.5.5,0,0,1-.46.7Zm-9.32,0h-12a.5.5,0,1,1,0-1h12a.5.5,0,1,1,0,1Zm7.87-5.48a.5.5,0,0,1-.5-.44c0-.34-.07-.68-.09-1a.5.5,0,1,1,1-.06c0,.33,0,.65.09,1a.5.5,0,0,1-.44.56Zm26.15-1a.5.5,0,0,1-.45-.28c-.12-.25-.27-.54-.45-.87a.5.5,0,1,1,.88-.48c.19.34.34.65.47.91a.5.5,0,0,1-.45.72ZM147.48,10a.5.5,0,0,1-.35-.14,13.18,13.18,0,0,0-6.43-3.72,7.66,7.66,0,0,0-3.88.16.5.5,0,1,1-.32-.95,8.66,8.66,0,0,1,4.38-.19,14.15,14.15,0,0,1,6.93,4,.5.5,0,0,1-.35.86Zm-18.8-3a.5.5,0,0,1-.39-.19,19.12,19.12,0,0,0-2-2.13A.5.5,0,0,1,127,4a20.34,20.34,0,0,1,2.1,2.24.5.5,0,0,1-.39.81ZM108.19,3.27a.5.5,0,0,1-.31-.89A12.51,12.51,0,0,1,114.1,0a16.12,16.12,0,0,1,5.66.2.5.5,0,1,1-.22,1A15.06,15.06,0,0,0,114.23,1a11.54,11.54,0,0,0-5.73,2.18A.5.5,0,0,1,108.19,3.27Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-2" d="M172.85,22.23h0L85,22.21a1,1,0,1,1,0-2h0l87.87,0a1,1,0,1,1,0,2Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-2" d="M.76,37.55H12.62s-3.71-8.29,4.17-9.36c7-1,9.8,6.26,9.8,6.26s.83-4.16,5-3.37,7.16,7.41,7.16,7.41H49.08" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-1" d="M13,36.23H1.13a.5.5,0,0,1,0-1H12.59a.5.5,0,0,1,.8.18l0,.12a.5.5,0,0,1-.46.7Zm32.86-.15h-3a.5.5,0,1,1,0-1h3a.5.5,0,1,1,0,1ZM27,32.86l-.14,0a.5.5,0,0,1-.34-.62,4.66,4.66,0,0,1,4.4-3.55,6,6,0,0,1,1.11.11,9.37,9.37,0,0,1,4.88,3,.5.5,0,1,1-.73.69,8.42,8.42,0,0,0-4.34-2.73,5,5,0,0,0-.93-.09,3.63,3.63,0,0,0-3.44,2.84A.5.5,0,0,1,27,32.86ZM13.4,28.53a.5.5,0,0,1-.36-.85,6,6,0,0,1,2.82-1.57.5.5,0,1,1,.26,1,5,5,0,0,0-2.36,1.29A.5.5,0,0,1,13.4,28.53Zm7.52-1.35-.15,0a7.39,7.39,0,0,0-.91-.23.5.5,0,0,1,.19-1,8.41,8.41,0,0,1,1,.26.5.5,0,0,1-.15,1Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-2" d="M49.84,39.56H1a1,1,0,1,1,0-2H49.84a1,1,0,1,1,0,2Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-2" d="M135.34,77H120.06V60.18a7.56,7.56,0,0,0-7.55-7.55H51.08a7.56,7.56,0,0,0-7.55,7.55v40.74a7.55,7.55,0,0,0,1,3.67,5.88,5.88,0,0,0-1,1.6l-6.89,16.12a5.73,5.73,0,0,0-.46,2.26v1.05a6.1,6.1,0,0,0,6.22,6h60v3.19a7.45,7.45,0,0,0,7.45,7.45h25.55a7.46,7.46,0,0,0,7.45-7.45V84.49A7.46,7.46,0,0,0,135.34,77Z" transform="translate(0.02 0.17)"/>
|
||||
<rect class="cls-2" x="47.3" y="56.55" width="68.54" height="47.84" rx="3.55" ry="3.55"/>
|
||||
<rect class="cls-2" x="50.64" y="62.52" width="61.86" height="38.58" rx="2.09" ry="2.09"/>
|
||||
<path class="cls-3" d="M110.38,63.35a1.09,1.09,0,0,1,1.09,1.09V98.83a1.09,1.09,0,0,1-1.09,1.09H52.71a1.09,1.09,0,0,1-1.09-1.09V64.44a1.09,1.09,0,0,1,1.09-1.09h57.67" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-4" d="M115.72,107.47a2.23,2.23,0,0,0-2.06-1.23H49a2.22,2.22,0,0,0-2.07,1.27L40,123.63a1.76,1.76,0,0,0-.14.69v1.05a2.1,2.1,0,0,0,2.22,2H121a2.1,2.1,0,0,0,2.22-2v-1a1.77,1.77,0,0,0-.16-.73Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-5" d="M124.88,122.78l-7.34-16.14a4,4,0,0,0-1.64-1.79,5.54,5.54,0,0,0,1.91-4.18V59.93a5.56,5.56,0,0,0-5.55-5.55H50.83a5.56,5.56,0,0,0-5.55,5.55v40.74a5.53,5.53,0,0,0,1.74,4,4,4,0,0,0-2,2l-6.89,16.12a3.75,3.75,0,0,0-.3,1.48v1.05a4.1,4.1,0,0,0,4.22,4H121a4.1,4.1,0,0,0,4.22-4v-1A3.75,3.75,0,0,0,124.88,122.78Zm-1.66,2.59a2.1,2.1,0,0,1-2.22,2H42.09a2.1,2.1,0,0,1-2.22-2v-1.05a1.76,1.76,0,0,1,.14-.69L46.9,107.5A2.22,2.22,0,0,1,49,106.24h64.69a2.23,2.23,0,0,1,2.06,1.23l7.34,16.14a1.77,1.77,0,0,1,.16.73ZM47.27,100.66V59.93a3.55,3.55,0,0,1,3.55-3.55h61.43a3.55,3.55,0,0,1,3.55,3.55v40.74a3.55,3.55,0,0,1-3.55,3.55H50.83A3.55,3.55,0,0,1,47.27,100.66Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-6" d="M94.71,121.68H68.43c-.43,0-.81-.25-.79-.53.33-1.7.48-2.59.82-4.38,0-.24.3-.43.68-.43l25.34-.19c.38,0,.66.17.66.41a43.55,43.55,0,0,1,.44,4.53C95.55,121.4,95.14,121.68,94.71,121.68ZM64,112.2H60.07c-.34,0-.61.15-.66.36-.11.48-.17.72-.28,1.2s.39.66.91.66l3.82,0c.34,0,.61-.14.67-.35.13-.47.2-.71.34-1.19S64.53,112.2,64,112.2Zm9.85,0-4.07,0c-.38,0-.69.17-.73.4-.09.48-.13.71-.21,1.18-.05.31.37.61.87.6l3.95,0a.73.73,0,0,0,.74-.4c.12-.47.18-.7.31-1.18C74.76,112.46,74.35,112.16,73.83,112.16Zm20.57,1.46c-.06-.46-.1-.69-.16-1.16,0-.23-.33-.39-.71-.39l-4.07,0c-.52,0-.95.3-.88.61l.26,1.16c0,.23.35.39.73.39l3.95,0C94,114.22,94.45,113.93,94.4,113.63Zm-9.93.09-.2-1.17c0-.25-.38-.43-.79-.43l-3.68,0c-.41,0-.76.19-.81.44-.1.47-.15.71-.25,1.17-.06.3.32.57.8.56l4.09,0C84.13,114.28,84.52,114,84.47,113.72Zm19.61-.19-.23-1.15c0-.2-.3-.34-.64-.34H99.3c-.54,0-1,.33-.93.65l.3,1.15c.05.2.32.34.65.34l3.82,0C103.67,114.17,104.14,113.84,104.08,113.53Zm-39.11-5H61.26a.64.64,0,0,0-.64.33c-.13.44-.2.66-.32,1.09s.33.61.83.61h3.62a.66.66,0,0,0,.65-.33c.15-.44.23-.66.39-1.09S65.49,108.53,65,108.53Zm9.36,0H70.46c-.37,0-.67.16-.72.37-.11.44-.16.66-.26,1.1s.33.56.81.56h3.77a.72.72,0,0,0,.72-.37c.13-.44.2-.66.33-1.1S74.83,108.5,74.33,108.5Zm19.61,1.4-.16-1.1c0-.22-.31-.37-.68-.37H89.23c-.5,0-.91.28-.85.58l.24,1.09c0,.21.34.37.7.36h3.77C93.57,110.46,94,110.19,93.94,109.9Zm-9.49.06-.17-1.1c0-.23-.35-.4-.74-.4H80c-.39,0-.73.18-.79.41-.11.44-.17.66-.27,1.1-.07.28.29.53.76.53h3.92C84.12,110.5,84.5,110.25,84.45,110Zm18.67-.13-.22-1.1c0-.2-.28-.33-.61-.33h-3.7c-.52,0-1,.32-.88.62l.29,1.09c.05.19.3.32.63.32h3.62C102.74,110.44,103.19,110.13,103.13,109.83Zm-48.06,2.4H51.32a.71.71,0,0,0-.69.36,9.8,9.8,0,0,0-.39,1.21c-.09.33.37.67.88.67l3.7,0c.33,0,.58-.15.63-.36a7.82,7.82,0,0,1,.39-1.2C56,112.57,55.59,112.23,55.06,112.23Zm1.32-3.68h-3.5a.57.57,0,0,0-.59.32,10,10,0,0,1-.37,1.09c-.12.3.23.61.7.61h3.45a.72.72,0,0,0,.67-.33c.2-.44.29-.66.45-1.09S56.87,108.55,56.38,108.55Zm50.9,4.12a7.26,7.26,0,0,1,.34,1.14c0,.2.29.33.62.33l3.7,0c.51,0,1-.32.9-.63a9.34,9.34,0,0,0-.34-1.14.68.68,0,0,0-.67-.34h-3.74C107.57,112,107.17,112.36,107.28,112.67Zm-1.1-3.66a8.86,8.86,0,0,0,.36,1.09.66.66,0,0,0,.64.32h3.45c.47,0,.84-.3.75-.6a7.35,7.35,0,0,1-.27-1.1c0-.2-.25-.33-.56-.33H107C106.55,108.39,106.1,108.71,106.18,109Z" transform="translate(0.02 0.17)"/>
|
||||
<circle class="cls-7" cx="82.57" cy="59.42" r="1.15"/>
|
||||
<rect class="cls-2" x="105.11" y="79.96" width="34.45" height="59.17" rx="4.45" ry="4.45"/>
|
||||
<path class="cls-8" d="M135.09,80.79a3.45,3.45,0,0,1,3.45,3.45v50.28a3.45,3.45,0,0,1-3.45,3.45H109.53a3.45,3.45,0,0,1-3.45-3.45V84.24a3.45,3.45,0,0,1,3.45-3.45h25.55m0-2H109.53a5.45,5.45,0,0,0-5.45,5.45v50.28a5.45,5.45,0,0,0,5.45,5.45h25.55a5.45,5.45,0,0,0,5.45-5.45V84.24a5.45,5.45,0,0,0-5.45-5.45Z" transform="translate(0.02 0.17)"/>
|
||||
<rect class="cls-2" x="109.42" y="84.79" width="25.82" height="45.33" rx="1.72" ry="1.72"/>
|
||||
<path class="cls-9" d="M133.49,85.62a.72.72,0,0,1,.72.72v41.88a.72.72,0,0,1-.72.72H111.12a.72.72,0,0,1-.72-.72V86.34a.72.72,0,0,1,.72-.72h22.37" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-10" d="M82.85,97.67a2.47,2.47,0,0,1-1.55-.55L66.32,85a12.45,12.45,0,0,1-3.66-3.66,12.77,12.77,0,0,1,1.67-16,12.69,12.69,0,0,1,17.95,0,.67.67,0,0,0,.49.22.68.68,0,0,0,.48-.21A12.71,12.71,0,1,1,99.26,85L84.41,97.12A2.49,2.49,0,0,1,82.85,97.67Zm41,23.7,11-9a9.67,9.67,0,1,0-12.19-14.9.24.24,0,0,1-.17.08.25.25,0,0,1-.18-.09,9.66,9.66,0,0,0-13.66,0,9.72,9.72,0,0,0-1.27,12.15,9.46,9.46,0,0,0,2.78,2.78l11.09,9a2.09,2.09,0,0,0,2.63,0Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-2" d="M73.28,62.67a11.66,11.66,0,0,1,8.29,3.44l0,0a1.66,1.66,0,0,0,1.18.5,1.68,1.68,0,0,0,1.19-.5l0,0A11.71,11.71,0,1,1,98.7,84.16L83.78,96.34a1.48,1.48,0,0,1-.93.33,1.45,1.45,0,0,1-.92-.33l-15-12.16a11.41,11.41,0,0,1-3.41-3.4A11.82,11.82,0,0,1,65,66.08a11.65,11.65,0,0,1,8.25-3.41m0-2h0a13.6,13.6,0,0,0-9.66,4,13.77,13.77,0,0,0-1.8,17.22,13.4,13.4,0,0,0,3.91,3.92L80.67,97.9a3.47,3.47,0,0,0,4.35,0L99.89,85.77A13.71,13.71,0,1,0,82.77,64.49a13.62,13.62,0,0,0-9.49-3.82Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-4" d="M66.31,76h-.16a2,2,0,0,1-1.79-2.11,8.69,8.69,0,0,1,6.8-7.8A2,2,0,1,1,72,69.92a4.8,4.8,0,0,0-3.76,4.31A2,2,0,0,1,66.31,76Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-2" d="M115.4,95.66a8.64,8.64,0,0,1,6.14,2.55h0a1.23,1.23,0,0,0,.88.37,1.24,1.24,0,0,0,.88-.37h0a8.67,8.67,0,1,1,10.91,13.37l-11.05,9a1.1,1.1,0,0,1-.69.24,1.08,1.08,0,0,1-.68-.24l-11.13-9a8.45,8.45,0,0,1-2.53-2.52,8.76,8.76,0,0,1,1.14-10.89,8.63,8.63,0,0,1,6.11-2.52m0-2h0a10.59,10.59,0,0,0-7.52,3.11,10.72,10.72,0,0,0-1.4,13.4,10.44,10.44,0,0,0,3,3l11,8.94a3.09,3.09,0,0,0,3.87,0l11-9a10.67,10.67,0,1,0-13-16.88,10.59,10.59,0,0,0-7-2.64Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="cls-4" d="M110.24,105.54h-.12a1.46,1.46,0,0,1-1.33-1.56,6.43,6.43,0,0,1,5-5.78,1.45,1.45,0,1,1,.63,2.83,3.56,3.56,0,0,0-2.78,3.19A1.45,1.45,0,0,1,110.24,105.54Z" transform="translate(0.02 0.17)"/>
|
||||
<path class="st8" d="M133.5 85.8c.4 0 .7.3.7.7v41.9c0 .4-.3.7-.7.7h-22.4c-.4 0-.7-.3-.7-.7V86.5c0-.4.3-.7.7-.7h22.4"/>
|
||||
</g>
|
||||
<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="-73.41" y1="701.6741" x2="262.92" y2="701.6741" gradientTransform="translate(.02 -609.83)">
|
||||
<stop offset="0" stop-color="#00C8D7"/>
|
||||
<stop offset="1" stop-color="#0A84FF"/>
|
||||
</linearGradient>
|
||||
<path class="st9" d="M82.9 97.8c-.6 0-1.1-.2-1.6-.6l-15-12.1c-1.5-1-2.7-2.2-3.7-3.7-3.3-5.1-2.6-11.7 1.7-16 5-5 13-5 17.9 0 .1.1.3.2.5.2s.4-.1.5-.2c5.1-4.8 13.1-4.6 18 .5s4.6 13.1-.5 18c-.5.4-1 .9-1.5 1.2L84.4 97.3c-.4.3-1 .5-1.5.5zm41 23.7l11-9c4.4-3 5.6-9 2.7-13.4-3-4.4-9-5.6-13.4-2.7-.5.3-1 .7-1.4 1.2 0 0-.1.1-.2.1s-.1 0-.2-.1c-3.8-3.8-9.9-3.8-13.7 0-3.2 3.2-3.8 8.3-1.3 12.2.7 1.1 1.7 2.1 2.8 2.8l11.1 9c.7.6 1.8.6 2.6-.1z"/>
|
||||
<path class="st1" d="M73.3 62.8c3.1 0 6.1 1.2 8.3 3.4.3.3.7.5 1.2.5.4 0 .9-.2 1.2-.5 4.6-4.5 12-4.5 16.6.1 4.5 4.6 4.5 12-.1 16.6-.5.5-1.1 1-1.7 1.4l-15 12.2c-.3.2-.6.3-.9.3s-.7-.1-.9-.3L67 84.3c-1.4-.9-2.5-2-3.4-3.4-3-4.6-2.4-10.7 1.5-14.7 2.1-2.1 5.1-3.4 8.2-3.4m0-2c-3.6 0-7.1 1.4-9.7 4-4.6 4.6-5.3 11.8-1.8 17.2 1 1.6 2.3 2.9 3.9 3.9l15 12.1c1.3 1 3.1 1 4.3 0l14.9-12.1c6.3-4.2 8-12.7 3.8-19s-12.7-8-19-3.8c-.7.5-1.3 1-1.9 1.5-2.6-2.4-6-3.8-9.5-3.8z"/>
|
||||
<path class="st3" d="M66.3 76.2h-.2c-1.1-.1-1.9-1-1.8-2.1.3-3.8 3.1-7 6.8-7.8 1-.4 2.2 0 2.6 1s0 2.2-1 2.6c-.2.1-.5.2-.8.2-2.1.5-3.6 2.2-3.8 4.3 0 1-.8 1.7-1.8 1.8z"/>
|
||||
<path class="st1" d="M115.4 95.8c2.3 0 4.5.9 6.1 2.6.2.2.5.4.9.4.3 0 .6-.1.9-.4 3.4-3.4 8.9-3.4 12.3 0 3.4 3.4 3.4 8.9 0 12.3-.4.4-.8.8-1.3 1.1l-11.1 9c-.2.2-.4.2-.7.2-.2 0-.5-.1-.7-.2l-11.1-9c-1-.7-1.9-1.5-2.5-2.5-2.2-3.4-1.7-8 1.1-10.9 1.6-1.7 3.8-2.6 6.1-2.6m0-2c-2.8 0-5.5 1.1-7.5 3.1-3.6 3.6-4.1 9.2-1.4 13.4.8 1.2 1.8 2.2 3 3l11 8.9c1.1.9 2.7.9 3.9 0l11-9c4.9-3.3 6.1-10 2.8-14.8-3.3-4.9-10-6.1-14.8-2.8-.3.2-.7.5-1 .7-2-1.6-4.5-2.6-7-2.5z"/>
|
||||
<path class="st3" d="M110.3 105.7c-.9-.1-1.5-.8-1.4-1.6.2-2.8 2.2-5.2 5-5.8.8-.2 1.6.3 1.8 1.1.2.8-.3 1.6-1.1 1.8h-.1c-1.5.3-2.7 1.6-2.8 3.2-.1.7-.7 1.3-1.4 1.3z"/>
|
||||
</svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 11 KiB После Ширина: | Высота: | Размер: 11 KiB |
|
@ -50,7 +50,6 @@ caption {
|
|||
}
|
||||
|
||||
groupbox {
|
||||
font-size: 1em;
|
||||
margin-top: 0;
|
||||
margin-right: 4px;
|
||||
margin-left: 4px;
|
||||
|
@ -67,11 +66,6 @@ groupbox description {
|
|||
margin-left: 0;
|
||||
}
|
||||
|
||||
label.menu-text,
|
||||
textbox.tree-input {
|
||||
font-size: unset;
|
||||
}
|
||||
|
||||
menulist label {
|
||||
font-weight: unset;
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#mainPrefPane {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
font: message-box;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
prefpane > groupbox + groupbox {
|
||||
|
@ -57,11 +55,15 @@ html|option {
|
|||
|
||||
description,
|
||||
label {
|
||||
line-height: 30px;
|
||||
line-height: 1.8em;
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.tip-caption {
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
menulist > hbox > label,
|
||||
menuitem > label,
|
||||
button > hbox > label {
|
||||
|
@ -95,6 +97,24 @@ button > hbox > label {
|
|||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.spotlight {
|
||||
background-color: rgba(0,200,215,0.3);
|
||||
/* Show the border to spotlight the components in high-contrast mode. */
|
||||
border: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
[data-subcategory] {
|
||||
margin-left: -4px;
|
||||
margin-right: -4px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
[data-subcategory] > .groupbox-title {
|
||||
padding-inline-start: 4px;
|
||||
}
|
||||
|
||||
#searchInput {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
@ -211,12 +231,10 @@ button > hbox > label {
|
|||
}
|
||||
|
||||
#updateApp > .groupbox-body > label {
|
||||
margin: 0 0 4px 0;
|
||||
line-height: 30px;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
|
||||
#updateApp > .groupbox-body > description {
|
||||
line-height: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
@ -246,7 +264,7 @@ button > hbox > label {
|
|||
}
|
||||
|
||||
#filter {
|
||||
margin: 4px 0 8px 0;
|
||||
margin: 4px 0 8px;
|
||||
}
|
||||
|
||||
#handlersView {
|
||||
|
@ -290,7 +308,7 @@ button > hbox > label {
|
|||
/* Search Pane */
|
||||
|
||||
#engineList {
|
||||
margin: 2px 0 5px 0;
|
||||
margin: 2px 0 5px;
|
||||
}
|
||||
|
||||
#engineList > treechildren::-moz-tree-image(engineShown, checked),
|
||||
|
@ -319,7 +337,7 @@ button > hbox > label {
|
|||
}
|
||||
|
||||
#addEnginesBox {
|
||||
margin: 4px 0 0 0;
|
||||
margin: 4px 0 0;
|
||||
}
|
||||
|
||||
/* Privacy Pane */
|
||||
|
@ -412,7 +430,6 @@ button > hbox > label {
|
|||
background-color: #fbfbfb;
|
||||
background-clip: content-box;
|
||||
color: #424e5a;
|
||||
font-size: 14px;
|
||||
/* `transparent` will use the dialogText color in high-contrast themes and
|
||||
when page colors are disabled */
|
||||
border: 1px solid transparent;
|
||||
|
@ -438,7 +455,7 @@ button > hbox > label {
|
|||
}
|
||||
|
||||
.dialogTitle {
|
||||
font-size: unset;
|
||||
font-size: .9em;
|
||||
text-align: center;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
@ -683,7 +700,7 @@ button > hbox > label {
|
|||
|
||||
.help-label {
|
||||
margin: 0 4px;
|
||||
line-height: 22px;
|
||||
font-size: .9em;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
|
@ -725,9 +742,14 @@ button > hbox > label {
|
|||
.search-container {
|
||||
position: sticky;
|
||||
background-color: var(--in-content-page-background);
|
||||
width: 100%;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
/* The search-container should have the capability to cover all spotlight area. */
|
||||
width: calc(100% + 8px);
|
||||
margin-left: -4px;
|
||||
margin-right: -4px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
#searchInput {
|
||||
|
|
|
@ -231,6 +231,7 @@ body {
|
|||
|
||||
.deck .instructions {
|
||||
text-align: center;
|
||||
color: rgba(12, 12, 13, .5);
|
||||
padding: 0 11px;
|
||||
max-width: 15em;
|
||||
margin: 1em auto;
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
|
||||
%include ../../../shared/incontentprefs/dialog.inc.css
|
||||
|
||||
label,
|
||||
textbox,
|
||||
description,
|
||||
.tab-text,
|
||||
menulist label {
|
||||
font-size: 1.25rem;
|
||||
:root > * {
|
||||
font-size: 1.12em;
|
||||
}
|
||||
|
|
|
@ -4,19 +4,8 @@
|
|||
|
||||
%include ../../../shared/incontentprefs/preferences.inc.css
|
||||
|
||||
html *,
|
||||
page *,
|
||||
window * {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
caption label {
|
||||
font-size: 1.42rem;
|
||||
}
|
||||
|
||||
.tip-caption,
|
||||
.help-label {
|
||||
font-size: 1.08rem;
|
||||
:root > * {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
.actionsMenu > .menulist-label-box > .menulist-icon {
|
||||
|
|
|
@ -46,7 +46,6 @@ MACH_MODULES = [
|
|||
'python/mozbuild/mozbuild/backend/mach_commands.py',
|
||||
'python/mozbuild/mozbuild/compilation/codecomplete.py',
|
||||
'python/mozbuild/mozbuild/frontend/mach_commands.py',
|
||||
'services/common/tests/mach_commands.py',
|
||||
'taskcluster/mach_commands.py',
|
||||
'testing/awsy/mach_commands.py',
|
||||
'testing/firefox-ui/mach_commands.py',
|
||||
|
|
|
@ -219,15 +219,16 @@ button {
|
|||
align-items: center;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
background-image: url(chrome://devtools/skin/images/help.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 24px;
|
||||
padding-inline-start: 32px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.addons-tip-icon {
|
||||
margin-inline-end: 1ch;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-image: url(chrome://devtools/skin/images/help.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 24px;
|
||||
margin-inline-end: 8px;
|
||||
}
|
||||
|
||||
.error-page {
|
||||
|
|
|
@ -171,6 +171,7 @@ class AddonsPanel extends Component {
|
|||
sort: true
|
||||
}),
|
||||
dom.div({ className: "addons-tip"},
|
||||
dom.div({ className: "addons-tip-icon"}),
|
||||
dom.span({
|
||||
className: "addons-web-ext-tip",
|
||||
}, Strings.GetStringFromName("webExtTip")),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
This is the debugger.html project output.
|
||||
See https://github.com/devtools-html/debugger.html
|
||||
|
||||
Taken from upstream commit: d2e91e574acbe3d5b546508d028bd278eaabd286
|
||||
Taken from upstream commit: efa4ca367dadb1bb54525f9fe305dd38c0ec6323
|
||||
|
||||
Packages:
|
||||
- babel-plugin-transform-es2015-modules-commonjs @6.26.0
|
||||
|
|
|
@ -1758,6 +1758,11 @@ html .toggle-button-end.vertical svg {
|
|||
.source-footer .blackbox-summary {
|
||||
color: var(--theme-body-color);
|
||||
}
|
||||
|
||||
.source-footer .mapped-source {
|
||||
color: var(--theme-body-color);
|
||||
padding: 2.5px;
|
||||
}
|
||||
/* 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/>. */
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -27467,66 +27467,8 @@ module.exports = function(module) {
|
|||
|
||||
/***/ }),
|
||||
/* 794 */,
|
||||
/* 795 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var createToPairs = __webpack_require__(812),
|
||||
keys = __webpack_require__(205);
|
||||
|
||||
/**
|
||||
* Creates an array of own enumerable string keyed-value pairs for `object`
|
||||
* which can be consumed by `_.fromPairs`. If `object` is a map or set, its
|
||||
* entries are returned.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @since 4.0.0
|
||||
* @alias entries
|
||||
* @category Object
|
||||
* @param {Object} object The object to query.
|
||||
* @returns {Array} Returns the key-value pairs.
|
||||
* @example
|
||||
*
|
||||
* function Foo() {
|
||||
* this.a = 1;
|
||||
* this.b = 2;
|
||||
* }
|
||||
*
|
||||
* Foo.prototype.c = 3;
|
||||
*
|
||||
* _.toPairs(new Foo);
|
||||
* // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
|
||||
*/
|
||||
var toPairs = createToPairs(keys);
|
||||
|
||||
module.exports = toPairs;
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 796 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var arrayMap = __webpack_require__(110);
|
||||
|
||||
/**
|
||||
* The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
|
||||
* of key-value pairs for `object` corresponding to the property names of `props`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to query.
|
||||
* @param {Array} props The property names to get values for.
|
||||
* @returns {Object} Returns the key-value pairs.
|
||||
*/
|
||||
function baseToPairs(object, props) {
|
||||
return arrayMap(props, function(key) {
|
||||
return [key, object[key]];
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = baseToPairs;
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 795 */,
|
||||
/* 796 */,
|
||||
/* 797 */,
|
||||
/* 798 */,
|
||||
/* 799 */
|
||||
|
@ -27711,7 +27653,7 @@ module.exports = matchesStrictComparable;
|
|||
/* 812 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var baseToPairs = __webpack_require__(796),
|
||||
var baseToPairs = __webpack_require__(1757),
|
||||
getTag = __webpack_require__(198),
|
||||
mapToArray = __webpack_require__(203),
|
||||
setToPairs = __webpack_require__(813);
|
||||
|
@ -36616,7 +36558,7 @@ exports.getVariablesInLocalScope = getVariablesInLocalScope;
|
|||
exports.getVariablesInScope = getVariablesInScope;
|
||||
exports.isExpressionInScope = isExpressionInScope;
|
||||
|
||||
var _toPairs = __webpack_require__(795);
|
||||
var _toPairs = __webpack_require__(1756);
|
||||
|
||||
var _toPairs2 = _interopRequireDefault(_toPairs);
|
||||
|
||||
|
@ -41822,6 +41764,118 @@ function extendsComponent(classes) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/***/ }),
|
||||
/* 1704 */,
|
||||
/* 1705 */,
|
||||
/* 1706 */,
|
||||
/* 1707 */,
|
||||
/* 1708 */,
|
||||
/* 1709 */,
|
||||
/* 1710 */,
|
||||
/* 1711 */,
|
||||
/* 1712 */,
|
||||
/* 1713 */,
|
||||
/* 1714 */,
|
||||
/* 1715 */,
|
||||
/* 1716 */,
|
||||
/* 1717 */,
|
||||
/* 1718 */,
|
||||
/* 1719 */,
|
||||
/* 1720 */,
|
||||
/* 1721 */,
|
||||
/* 1722 */,
|
||||
/* 1723 */,
|
||||
/* 1724 */,
|
||||
/* 1725 */,
|
||||
/* 1726 */,
|
||||
/* 1727 */,
|
||||
/* 1728 */,
|
||||
/* 1729 */,
|
||||
/* 1730 */,
|
||||
/* 1731 */,
|
||||
/* 1732 */,
|
||||
/* 1733 */,
|
||||
/* 1734 */,
|
||||
/* 1735 */,
|
||||
/* 1736 */,
|
||||
/* 1737 */,
|
||||
/* 1738 */,
|
||||
/* 1739 */,
|
||||
/* 1740 */,
|
||||
/* 1741 */,
|
||||
/* 1742 */,
|
||||
/* 1743 */,
|
||||
/* 1744 */,
|
||||
/* 1745 */,
|
||||
/* 1746 */,
|
||||
/* 1747 */,
|
||||
/* 1748 */,
|
||||
/* 1749 */,
|
||||
/* 1750 */,
|
||||
/* 1751 */,
|
||||
/* 1752 */,
|
||||
/* 1753 */,
|
||||
/* 1754 */,
|
||||
/* 1755 */,
|
||||
/* 1756 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var createToPairs = __webpack_require__(812),
|
||||
keys = __webpack_require__(205);
|
||||
|
||||
/**
|
||||
* Creates an array of own enumerable string keyed-value pairs for `object`
|
||||
* which can be consumed by `_.fromPairs`. If `object` is a map or set, its
|
||||
* entries are returned.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @since 4.0.0
|
||||
* @alias entries
|
||||
* @category Object
|
||||
* @param {Object} object The object to query.
|
||||
* @returns {Array} Returns the key-value pairs.
|
||||
* @example
|
||||
*
|
||||
* function Foo() {
|
||||
* this.a = 1;
|
||||
* this.b = 2;
|
||||
* }
|
||||
*
|
||||
* Foo.prototype.c = 3;
|
||||
*
|
||||
* _.toPairs(new Foo);
|
||||
* // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
|
||||
*/
|
||||
var toPairs = createToPairs(keys);
|
||||
|
||||
module.exports = toPairs;
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 1757 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var arrayMap = __webpack_require__(110);
|
||||
|
||||
/**
|
||||
* The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
|
||||
* of key-value pairs for `object` corresponding to the property names of `props`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to query.
|
||||
* @param {Array} props The property names to get values for.
|
||||
* @returns {Object} Returns the key-value pairs.
|
||||
*/
|
||||
function baseToPairs(object, props) {
|
||||
return arrayMap(props, function(key) {
|
||||
return [key, object[key]];
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = baseToPairs;
|
||||
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
});
|
|
@ -43,7 +43,7 @@ add_task(async function() {
|
|||
assertPausedLocation(dbg);
|
||||
|
||||
// resume
|
||||
await clickResume(dbg)
|
||||
await clickResume(dbg);
|
||||
await waitForPaused(dbg);
|
||||
assertPausedLocation(dbg);
|
||||
|
||||
|
|
|
@ -47,5 +47,8 @@ add_task(async function() {
|
|||
await waitForLoadedSource(dbg, "long.js");
|
||||
|
||||
assertPausedLocation(dbg);
|
||||
ok(isVisibleInEditor(dbg, findElement(dbg, "breakpoint")), "Breakpoint is visible");
|
||||
ok(
|
||||
isVisibleInEditor(dbg, findElement(dbg, "breakpoint")),
|
||||
"Breakpoint is visible"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -47,7 +47,7 @@ async function editExpression(dbg, input) {
|
|||
info("updating the expression");
|
||||
dblClickElement(dbg, "expressionNode", 1);
|
||||
// Position cursor reliably at the end of the text.
|
||||
const evaluation = waitForDispatch(dbg, "EVALUATE_EXPRESSION")
|
||||
const evaluation = waitForDispatch(dbg, "EVALUATE_EXPRESSION");
|
||||
pressKey(dbg, "End");
|
||||
type(dbg, input);
|
||||
pressKey(dbg, "Enter");
|
||||
|
@ -59,7 +59,7 @@ async function editExpression(dbg, input) {
|
|||
* resume, and wait for the expression to finish being evaluated.
|
||||
*/
|
||||
async function addBadExpression(dbg, input) {
|
||||
const evaluation = waitForDispatch(dbg, "EVALUATE_EXPRESSION")
|
||||
const evaluation = waitForDispatch(dbg, "EVALUATE_EXPRESSION");
|
||||
|
||||
findElementWithSelector(dbg, expressionSelectors.input).focus();
|
||||
type(dbg, input);
|
||||
|
@ -70,7 +70,6 @@ async function addBadExpression(dbg, input) {
|
|||
ok(dbg.selectors.isEvaluatingExpression(dbg.getState()));
|
||||
await resume(dbg);
|
||||
await evaluation;
|
||||
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
|
|
|
@ -32,8 +32,8 @@ add_task(async function() {
|
|||
|
||||
// The pretty-print button should go away in the pretty-printed
|
||||
// source.
|
||||
ok(!findElement(dbg, "editorFooter"), "Footer is hidden");
|
||||
ok(!findElement(dbg, "prettyPrintButton"), "Pretty Print Button is hidden");
|
||||
|
||||
await selectSource(dbg, "math.min.js");
|
||||
ok(findElement(dbg, "editorFooter"), "Footer is hidden");
|
||||
ok(findElement(dbg, "prettyPrintButton"), "Pretty Print Button is visible");
|
||||
});
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
function assertBpInGutter(dbg, lineNumber) {
|
||||
const el = findElement(dbg, "breakpoint");
|
||||
const bpLineNumber = +el.querySelector(".CodeMirror-linenumber").innerText;
|
||||
is(bpLineNumber, lineNumber, "Breakpoint is on the correct line in the gutter");
|
||||
is(
|
||||
bpLineNumber,
|
||||
lineNumber,
|
||||
"Breakpoint is on the correct line in the gutter"
|
||||
);
|
||||
}
|
||||
|
||||
// Tests loading sourcemapped sources, setting breakpoints, and
|
||||
|
@ -38,4 +42,12 @@ add_task(async function() {
|
|||
|
||||
await waitForPaused(dbg);
|
||||
assertPausedLocation(dbg);
|
||||
|
||||
// Tests the existence of the sourcemap link in the original source.
|
||||
ok(findElement(dbg, "sourceMapLink"), "Sourcemap link in original source");
|
||||
await selectSource(dbg, "main.min.js");
|
||||
ok(
|
||||
!findElement(dbg, "sourceMapLink"),
|
||||
"No Sourcemap link exists in generated source"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -26,6 +26,7 @@ add_task(async function() {
|
|||
await waitForPaused(dbg);
|
||||
await waitForLoadedSource(dbg, "average.c");
|
||||
assertPausedLocation(dbg);
|
||||
toggleCallStack(dbg);
|
||||
|
||||
const frames = findAllElements(dbg, "frames");
|
||||
const firstFrameTitle = frames[0].querySelector(".title").textContent;
|
||||
|
|
|
@ -295,7 +295,9 @@ function assertDebugLine(dbg, line) {
|
|||
const url = source.get("url");
|
||||
ok(
|
||||
false,
|
||||
`Looks like the source ${url} is still loading. Try adding waitForLoadedSource in the test.`
|
||||
`Looks like the source ${
|
||||
url
|
||||
} is still loading. Try adding waitForLoadedSource in the test.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -305,8 +307,9 @@ function assertDebugLine(dbg, line) {
|
|||
"Line is highlighted as paused"
|
||||
);
|
||||
|
||||
const debugLine = findElementWithSelector(dbg, ".new-debug-line")
|
||||
|| findElementWithSelector(dbg, ".new-debug-line-error");
|
||||
const debugLine =
|
||||
findElementWithSelector(dbg, ".new-debug-line") ||
|
||||
findElementWithSelector(dbg, ".new-debug-line-error");
|
||||
|
||||
ok(isVisibleInEditor(dbg, debugLine), "debug line is visible");
|
||||
|
||||
|
@ -553,8 +556,11 @@ function waitForLoadedSources(dbg) {
|
|||
return waitForState(
|
||||
dbg,
|
||||
state => {
|
||||
const sources = dbg.selectors.getSources(state).valueSeq().toJS()
|
||||
return !sources.some(source => source.loadedState == "loading")
|
||||
const sources = dbg.selectors
|
||||
.getSources(state)
|
||||
.valueSeq()
|
||||
.toJS();
|
||||
return !sources.some(source => source.loadedState == "loading");
|
||||
},
|
||||
"loaded source"
|
||||
);
|
||||
|
@ -835,7 +841,6 @@ function type(dbg, string) {
|
|||
string.split("").forEach(char => EventUtils.synthesizeKey(char, {}, dbg.win));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Checks to see if the inner element is visible inside the editor.
|
||||
*
|
||||
|
@ -874,12 +879,14 @@ function isVisible(outerEl, innerEl) {
|
|||
const outerRect = outerEl.getBoundingClientRect();
|
||||
|
||||
const verticallyVisible =
|
||||
(innerRect.top >= outerRect.top || innerRect.bottom <= outerRect.bottom)
|
||||
|| (innerRect.top < outerRect.top && innerRect.bottom > outerRect.bottom);
|
||||
innerRect.top >= outerRect.top ||
|
||||
innerRect.bottom <= outerRect.bottom ||
|
||||
(innerRect.top < outerRect.top && innerRect.bottom > outerRect.bottom);
|
||||
|
||||
const horizontallyVisible =
|
||||
(innerRect.left >= outerRect.left || innerRect.right <= outerRect.right)
|
||||
|| (innerRect.left < outerRect.left && innerRect.right > outerRect.right);
|
||||
innerRect.left >= outerRect.left ||
|
||||
innerRect.right <= outerRect.right ||
|
||||
(innerRect.left < outerRect.left && innerRect.right > outerRect.right);
|
||||
|
||||
const visible = verticallyVisible && horizontallyVisible;
|
||||
return visible;
|
||||
|
@ -891,7 +898,9 @@ const selectors = {
|
|||
expressionNode: i =>
|
||||
`.expressions-list .expression-container:nth-child(${i}) .object-label`,
|
||||
expressionValue: i =>
|
||||
`.expressions-list .expression-container:nth-child(${i}) .object-delimiter + *`,
|
||||
`.expressions-list .expression-container:nth-child(${
|
||||
i
|
||||
}) .object-delimiter + *`,
|
||||
expressionClose: i =>
|
||||
`.expressions-list .expression-container:nth-child(${i}) .close`,
|
||||
expressionNodes: ".expressions-list .tree-node",
|
||||
|
@ -914,7 +923,8 @@ const selectors = {
|
|||
stepOut: ".stepOut.active",
|
||||
stepIn: ".stepIn.active",
|
||||
toggleBreakpoints: ".breakpoints-toggle",
|
||||
prettyPrintButton: ".prettyPrint",
|
||||
prettyPrintButton: ".source-footer .prettyPrint",
|
||||
sourceMapLink: ".source-footer .mapped-source",
|
||||
sourcesFooter: ".sources-panel .source-footer",
|
||||
editorFooter: ".editor-pane .source-footer",
|
||||
sourceNode: i => `.sources-list .tree-node:nth-child(${i})`,
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
define(function (require, exports, module) {
|
||||
const { Component } = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
|
||||
const { pre } = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
|
||||
/**
|
||||
* This object represents a live DOM text node in a <pre>.
|
||||
*/
|
||||
class LiveText extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
data: PropTypes.instanceOf(Text),
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.componentDidUpdate();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
let el = findDOMNode(this);
|
||||
if (el.firstChild === this.props.data) {
|
||||
return;
|
||||
}
|
||||
el.textContent = "";
|
||||
el.append(this.props.data);
|
||||
}
|
||||
|
||||
render() {
|
||||
return pre({className: "data"});
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
exports.LiveText = LiveText;
|
||||
});
|
|
@ -22,7 +22,7 @@ define(function (require, exports, module) {
|
|||
class MainTabbedArea extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
jsonText: PropTypes.string,
|
||||
jsonText: PropTypes.instanceOf(Text),
|
||||
tabActive: PropTypes.number,
|
||||
actions: PropTypes.object,
|
||||
headers: PropTypes.object,
|
||||
|
@ -42,8 +42,8 @@ define(function (require, exports, module) {
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
json: {},
|
||||
headers: {},
|
||||
json: props.json,
|
||||
expandedNodes: props.expandedNodes,
|
||||
jsonText: props.jsonText,
|
||||
tabActive: props.tabActive
|
||||
};
|
||||
|
@ -64,7 +64,7 @@ define(function (require, exports, module) {
|
|||
className: "json",
|
||||
title: JSONView.Locale.$STR("jsonViewer.tab.JSON")},
|
||||
JsonPanel({
|
||||
data: this.props.json,
|
||||
data: this.state.json,
|
||||
expandedNodes: this.props.expandedNodes,
|
||||
actions: this.props.actions,
|
||||
searchFilter: this.state.searchFilter
|
||||
|
@ -74,7 +74,8 @@ define(function (require, exports, module) {
|
|||
className: "rawdata",
|
||||
title: JSONView.Locale.$STR("jsonViewer.tab.RawData")},
|
||||
TextPanel({
|
||||
isValidJson: !(this.props.json instanceof Error),
|
||||
isValidJson: !(this.state.json instanceof Error) &&
|
||||
document.readyState != "loading",
|
||||
data: this.state.jsonText,
|
||||
actions: this.props.actions
|
||||
})
|
||||
|
|
|
@ -12,8 +12,8 @@ define(function (require, exports, module) {
|
|||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const { createFactories } = require("devtools/client/shared/react-utils");
|
||||
const { TextToolbar } = createFactories(require("./TextToolbar"));
|
||||
|
||||
const { div, pre } = dom;
|
||||
const { LiveText } = createFactories(require("./LiveText"));
|
||||
const { div } = dom;
|
||||
|
||||
/**
|
||||
* This template represents the 'Raw Data' panel displaying
|
||||
|
@ -24,7 +24,7 @@ define(function (require, exports, module) {
|
|||
return {
|
||||
isValidJson: PropTypes.bool,
|
||||
actions: PropTypes.object,
|
||||
data: PropTypes.string
|
||||
data: PropTypes.instanceOf(Text),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,7 @@ define(function (require, exports, module) {
|
|||
isValidJson: this.props.isValidJson
|
||||
}),
|
||||
div({className: "panelContent"},
|
||||
pre({className: "data"},
|
||||
this.props.data
|
||||
)
|
||||
LiveText({data: this.props.data})
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -14,6 +14,7 @@ DevToolsModules(
|
|||
'HeadersToolbar.js',
|
||||
'JsonPanel.js',
|
||||
'JsonToolbar.js',
|
||||
'LiveText.js',
|
||||
'MainTabbedArea.js',
|
||||
'SearchBox.js',
|
||||
'TextPanel.js',
|
||||
|
|
|
@ -168,6 +168,8 @@ function exportData(win, request) {
|
|||
|
||||
data.json = new win.Text();
|
||||
|
||||
data.readyState = "uninitialized";
|
||||
|
||||
let Locale = {
|
||||
$STR: key => {
|
||||
try {
|
||||
|
@ -241,17 +243,16 @@ function initialHTML(doc) {
|
|||
type: "text/css",
|
||||
href: baseURI + "css/main.css",
|
||||
}),
|
||||
element("script", {
|
||||
src: baseURI + "lib/require.js",
|
||||
"data-main": baseURI + "viewer-config.js",
|
||||
defer: true,
|
||||
})
|
||||
]),
|
||||
element("body", {}, [
|
||||
element("div", {"id": "content"}, [
|
||||
element("div", {"id": "json"})
|
||||
])
|
||||
])
|
||||
]),
|
||||
element("script", {
|
||||
src: baseURI + "lib/require.js",
|
||||
"data-main": baseURI + "viewer-config.js",
|
||||
}),
|
||||
]),
|
||||
]).outerHTML;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,41 +19,26 @@ define(function (require, exports, module) {
|
|||
|
||||
// Application state object.
|
||||
let input = {
|
||||
jsonText: JSONView.json.textContent,
|
||||
jsonText: JSONView.json,
|
||||
jsonPretty: null,
|
||||
headers: JSONView.headers,
|
||||
tabActive: 0,
|
||||
prettified: false
|
||||
};
|
||||
|
||||
try {
|
||||
input.json = JSON.parse(input.jsonText);
|
||||
} catch (err) {
|
||||
input.json = err;
|
||||
}
|
||||
|
||||
// Expand the document by default if its size isn't bigger than 100KB.
|
||||
if (!(input.json instanceof Error) && input.jsonText.length <= AUTO_EXPAND_MAX_SIZE) {
|
||||
input.expandedNodes = TreeViewClass.getExpandedNodes(
|
||||
input.json,
|
||||
{maxLevel: AUTO_EXPAND_MAX_LEVEL}
|
||||
);
|
||||
} else {
|
||||
input.expandedNodes = new Set();
|
||||
}
|
||||
|
||||
/**
|
||||
* Application actions/commands. This list implements all commands
|
||||
* available for the JSON viewer.
|
||||
*/
|
||||
input.actions = {
|
||||
onCopyJson: function () {
|
||||
copyString(input.prettified ? input.jsonPretty : input.jsonText);
|
||||
let text = input.prettified ? input.jsonPretty : input.jsonText;
|
||||
copyString(text.textContent);
|
||||
},
|
||||
|
||||
onSaveJson: function () {
|
||||
if (input.prettified && !prettyURL) {
|
||||
prettyURL = URL.createObjectURL(new window.Blob([input.jsonPretty]));
|
||||
prettyURL = URL.createObjectURL(new window.Blob([input.jsonPretty.textContent]));
|
||||
}
|
||||
dispatchEvent("save", input.prettified ? prettyURL : null);
|
||||
},
|
||||
|
@ -93,7 +78,7 @@ define(function (require, exports, module) {
|
|||
theApp.setState({jsonText: input.jsonText});
|
||||
} else {
|
||||
if (!input.jsonPretty) {
|
||||
input.jsonPretty = JSON.stringify(input.json, null, " ");
|
||||
input.jsonPretty = new Text(JSON.stringify(input.json, null, " "));
|
||||
}
|
||||
theApp.setState({jsonText: input.jsonPretty});
|
||||
}
|
||||
|
@ -139,11 +124,52 @@ define(function (require, exports, module) {
|
|||
* at the top of the window. This component also represents ReacJS root.
|
||||
*/
|
||||
let content = document.getElementById("content");
|
||||
let promise = (async function parseJSON() {
|
||||
if (document.readyState == "loading") {
|
||||
// If the JSON has not been loaded yet, render the Raw Data tab first.
|
||||
input.json = {};
|
||||
input.expandedNodes = new Set();
|
||||
input.tabActive = 1;
|
||||
return new Promise(resolve => {
|
||||
document.addEventListener("DOMContentLoaded", resolve, {once: true});
|
||||
}).then(parseJSON).then(() => {
|
||||
// Now update the state and switch to the JSON tab.
|
||||
theApp.setState({
|
||||
tabActive: 0,
|
||||
json: input.json,
|
||||
expandedNodes: input.expandedNodes,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// If the JSON has been loaded, parse it immediately before loading the app.
|
||||
let jsonString = input.jsonText.textContent;
|
||||
try {
|
||||
input.json = JSON.parse(jsonString);
|
||||
} catch (err) {
|
||||
input.json = err;
|
||||
}
|
||||
|
||||
// Expand the document by default if its size isn't bigger than 100KB.
|
||||
if (!(input.json instanceof Error) && jsonString.length <= AUTO_EXPAND_MAX_SIZE) {
|
||||
input.expandedNodes = TreeViewClass.getExpandedNodes(
|
||||
input.json,
|
||||
{maxLevel: AUTO_EXPAND_MAX_LEVEL}
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
})();
|
||||
|
||||
let theApp = render(MainTabbedArea(input), content);
|
||||
|
||||
// Send notification event to the window. Can be useful for
|
||||
// Send readyState change notification event to the window. Can be useful for
|
||||
// tests as well as extensions.
|
||||
let event = new CustomEvent("JSONViewInitialized", {});
|
||||
JSONView.initialized = true;
|
||||
window.dispatchEvent(event);
|
||||
JSONView.readyState = "interactive";
|
||||
window.dispatchEvent(new CustomEvent("AppReadyStateChange"));
|
||||
|
||||
promise.then(() => {
|
||||
// Another readyState change notification event.
|
||||
JSONView.readyState = "complete";
|
||||
window.dispatchEvent(new CustomEvent("AppReadyStateChange"));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -22,8 +22,11 @@ support-files =
|
|||
!/devtools/client/framework/test/head.js
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
|
||||
[browser_json_refresh.js]
|
||||
[browser_jsonview_bug_1380828.js]
|
||||
[browser_jsonview_ignore_charset.js]
|
||||
[browser_jsonview_chunked_json.js]
|
||||
support-files =
|
||||
chunked_json.sjs
|
||||
[browser_jsonview_content_type.js]
|
||||
[browser_jsonview_copy_headers.js]
|
||||
subsuite = clipboard
|
||||
|
@ -38,6 +41,7 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
|
|||
[browser_jsonview_empty_object.js]
|
||||
[browser_jsonview_encoding.js]
|
||||
[browser_jsonview_filter.js]
|
||||
[browser_jsonview_ignore_charset.js]
|
||||
[browser_jsonview_invalid_json.js]
|
||||
[browser_jsonview_manifest.js]
|
||||
[browser_jsonview_nojs.js]
|
||||
|
@ -47,8 +51,7 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
|
|||
[browser_jsonview_save_json.js]
|
||||
support-files =
|
||||
!/toolkit/content/tests/browser/common/mockTransfer.js
|
||||
[browser_jsonview_theme.js]
|
||||
[browser_jsonview_slash.js]
|
||||
[browser_jsonview_valid_json.js]
|
||||
[browser_json_refresh.js]
|
||||
[browser_jsonview_serviceworker.js]
|
||||
[browser_jsonview_slash.js]
|
||||
[browser_jsonview_theme.js]
|
||||
[browser_jsonview_valid_json.js]
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_JSON_URL = URL_ROOT + "chunked_json.sjs";
|
||||
|
||||
add_task(async function () {
|
||||
info("Test chunked JSON started");
|
||||
|
||||
await addJsonViewTab(TEST_JSON_URL, {
|
||||
appReadyState: "interactive",
|
||||
docReadyState: "loading",
|
||||
});
|
||||
|
||||
is(await getElementCount(".rawdata.is-active"), 1,
|
||||
"The Raw Data tab is selected.");
|
||||
|
||||
// Write some text and check that it is displayed.
|
||||
await write("[");
|
||||
await checkText();
|
||||
|
||||
// Repeat just in case.
|
||||
await write("1,");
|
||||
await checkText();
|
||||
|
||||
is(await getElementCount("button.prettyprint"), 0,
|
||||
"There is no pretty print button during load");
|
||||
|
||||
await selectJsonViewContentTab("json");
|
||||
is(await getElementText(".jsonPanelBox > .panelContent"), "", "There is no JSON tree");
|
||||
|
||||
await selectJsonViewContentTab("headers");
|
||||
ok(await getElementText(".headersPanelBox .netInfoHeadersTable"),
|
||||
"The headers table has been filled.");
|
||||
|
||||
// Write some text without being in Raw Data, then switch tab and check.
|
||||
await write("2");
|
||||
await selectJsonViewContentTab("rawdata");
|
||||
await checkText();
|
||||
|
||||
// Another text check.
|
||||
await write("]");
|
||||
await checkText();
|
||||
|
||||
// Close the connection.
|
||||
let appReady = waitForContentMessage("Test:JsonView:AppReadyStateChange");
|
||||
await server("close");
|
||||
await appReady;
|
||||
|
||||
is(await getElementCount(".json.is-active"), 1, "The JSON tab is selected.");
|
||||
|
||||
is(await getElementCount(".jsonPanelBox .treeTable .treeRow"), 2,
|
||||
"There is a tree with 2 rows.");
|
||||
|
||||
await selectJsonViewContentTab("rawdata");
|
||||
await checkText();
|
||||
|
||||
is(await getElementCount("button.prettyprint"), 1, "There is a pretty print button.");
|
||||
await clickJsonNode("button.prettyprint");
|
||||
await checkText(JSON.stringify(JSON.parse(data), null, 2));
|
||||
});
|
||||
|
||||
let data = " ";
|
||||
async function write(text) {
|
||||
data += text;
|
||||
let dataReceived = waitForContentMessage("Test:JsonView:NewDataReceived");
|
||||
await server("write", text);
|
||||
await dataReceived;
|
||||
}
|
||||
async function checkText(text = data) {
|
||||
is(await getElementText(".textPanelBox .data"), text, "Got the right text.");
|
||||
}
|
||||
|
||||
function server(action, value) {
|
||||
return new Promise(resolve => {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", TEST_JSON_URL + "?" + action + "=" + value);
|
||||
xhr.addEventListener("load", resolve, {once: true});
|
||||
xhr.send();
|
||||
});
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче