Merge mozilla central to inbound
@ -767,8 +767,7 @@ var gHistorySwipeAnimation = {
|
||||
* @return the newly created element.
|
||||
*/
|
||||
_createElement: function HSA__createElement(aID, aTagName) {
|
||||
let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
let element = document.createElementNS(XULNS, aTagName);
|
||||
let element = document.createXULElement(aTagName);
|
||||
element.id = aID;
|
||||
return element;
|
||||
},
|
||||
|
@ -653,8 +653,7 @@ var gPluginHandler = {
|
||||
iconURL, priority, buttons);
|
||||
|
||||
// Add the "learn more" link.
|
||||
let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
let link = notification.ownerDocument.createElementNS(XULNS, "label");
|
||||
let link = notification.ownerDocument.createXULElement("label");
|
||||
link.className = "text-link";
|
||||
link.setAttribute("value", gNavigatorBundle.getString("crashedpluginsMessage.learnMore"));
|
||||
let crashurl = formatURL("app.support.baseURL", true);
|
||||
|
@ -66,14 +66,6 @@ searchbar {
|
||||
min-width: 25px;
|
||||
}
|
||||
|
||||
.browserStack > browser {
|
||||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-browser");
|
||||
}
|
||||
|
||||
.browserStack > browser[remote="true"] {
|
||||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-remote-browser");
|
||||
}
|
||||
|
||||
toolbar[customizable="true"] {
|
||||
-moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#toolbar");
|
||||
}
|
||||
|
@ -8073,8 +8073,7 @@ TabModalPromptBox.prototype = {
|
||||
},
|
||||
|
||||
appendPrompt(args, onCloseCallback) {
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
let newPrompt = document.createElementNS(XUL_NS, "tabmodalprompt");
|
||||
let newPrompt = document.createXULElement("tabmodalprompt");
|
||||
let browser = this.browser;
|
||||
browser.parentNode.insertBefore(newPrompt, browser.nextElementSibling);
|
||||
browser.setAttribute("tabmodalPromptShowing", true);
|
||||
@ -8096,9 +8095,9 @@ TabModalPromptBox.prototype = {
|
||||
hostForAllowFocusCheckbox = principalToAllowFocusFor.URI.host;
|
||||
} catch (ex) { /* Ignore exceptions for host-less URIs */ }
|
||||
if (hostForAllowFocusCheckbox) {
|
||||
let allowFocusRow = document.createElementNS(XUL_NS, "row");
|
||||
allowFocusCheckbox = document.createElementNS(XUL_NS, "checkbox");
|
||||
let spacer = document.createElementNS(XUL_NS, "spacer");
|
||||
let allowFocusRow = document.createXULElement("row");
|
||||
allowFocusCheckbox = document.createXULElement("checkbox");
|
||||
let spacer = document.createXULElement("spacer");
|
||||
allowFocusRow.appendChild(spacer);
|
||||
let label = gTabBrowserBundle.formatStringFromName("tabs.allowTabFocusByPromptForSite",
|
||||
[hostForAllowFocusCheckbox], 1);
|
||||
|
@ -831,6 +831,7 @@ nsContextMenu.prototype = {
|
||||
let referrer = gContextMenuContentData.referrer;
|
||||
openLinkIn(gContextMenuContentData.docLocation, "tab",
|
||||
{ charset: gContextMenuContentData.charSet,
|
||||
triggeringPrincipal: this.browser.contentPrincipal,
|
||||
referrerURI: referrer ? makeURI(referrer) : null });
|
||||
},
|
||||
|
||||
|
@ -258,7 +258,7 @@ window._gBrowser = {
|
||||
}
|
||||
let stack = this.selectedBrowser.parentNode;
|
||||
// Create an anchor for the popup
|
||||
let popupAnchor = document.createElementNS(this._XUL_NS, "hbox");
|
||||
let popupAnchor = document.createXULElement("hbox");
|
||||
popupAnchor.className = "popup-anchor";
|
||||
popupAnchor.hidden = true;
|
||||
stack.appendChild(popupAnchor);
|
||||
@ -293,6 +293,7 @@ window._gBrowser = {
|
||||
|
||||
browser.permanentKey = {};
|
||||
browser.droppedLinkHandler = handleDroppedLink;
|
||||
browser.loadURI = _loadURI.bind(null, browser);
|
||||
|
||||
let autoScrollPopup = browser._createAutoScrollPopup();
|
||||
autoScrollPopup.id = "autoscroller";
|
||||
@ -513,7 +514,7 @@ window._gBrowser = {
|
||||
* @return the created findbar, or null if the window or tab is closed/closing.
|
||||
*/
|
||||
async _createFindBar(aTab) {
|
||||
let findBar = document.createElementNS(this._XUL_NS, "findbar");
|
||||
let findBar = document.createXULElement("findbar");
|
||||
let browser = this.getBrowserForTab(aTab);
|
||||
let browserContainer = this.getBrowserContainer(browser);
|
||||
browserContainer.appendChild(findBar);
|
||||
@ -1799,7 +1800,7 @@ window._gBrowser = {
|
||||
uriIsAboutBlank,
|
||||
userContextId,
|
||||
} = {}) {
|
||||
let b = document.createElementNS(this._XUL_NS, "browser");
|
||||
let b = document.createXULElement("browser");
|
||||
b.permanentKey = {};
|
||||
|
||||
for (let attribute in this._defaultBrowserAttributes) {
|
||||
@ -1874,25 +1875,25 @@ window._gBrowser = {
|
||||
}
|
||||
|
||||
// Create the browserStack container
|
||||
let stack = document.createElementNS(this._XUL_NS, "stack");
|
||||
let stack = document.createXULElement("stack");
|
||||
stack.className = "browserStack";
|
||||
stack.appendChild(b);
|
||||
stack.setAttribute("flex", "1");
|
||||
|
||||
// Create the browserContainer
|
||||
let browserContainer = document.createElementNS(this._XUL_NS, "vbox");
|
||||
let browserContainer = document.createXULElement("vbox");
|
||||
browserContainer.className = "browserContainer";
|
||||
browserContainer.appendChild(stack);
|
||||
browserContainer.setAttribute("flex", "10000");
|
||||
|
||||
// Create the sidebar container
|
||||
let browserSidebarContainer = document.createElementNS(this._XUL_NS, "hbox");
|
||||
let browserSidebarContainer = document.createXULElement("hbox");
|
||||
browserSidebarContainer.className = "browserSidebarContainer";
|
||||
browserSidebarContainer.appendChild(browserContainer);
|
||||
browserSidebarContainer.setAttribute("flex", "10000");
|
||||
|
||||
// Add the Message and the Browser to the box
|
||||
let notificationbox = document.createElementNS(this._XUL_NS, "notificationbox");
|
||||
let notificationbox = document.createXULElement("notificationbox");
|
||||
notificationbox.setAttribute("flex", "1");
|
||||
notificationbox.setAttribute("notificationside", "top");
|
||||
notificationbox.appendChild(browserSidebarContainer);
|
||||
@ -2040,6 +2041,7 @@ window._gBrowser = {
|
||||
this._tabFilters.set(aTab, filter);
|
||||
|
||||
browser.droppedLinkHandler = handleDroppedLink;
|
||||
browser.loadURI = _loadURI.bind(null, browser);
|
||||
|
||||
// Most of the time, we start our browser's docShells out as inactive,
|
||||
// and then maintain activeness in the tab switcher. Preloaded about:newtab's
|
||||
@ -2233,7 +2235,7 @@ window._gBrowser = {
|
||||
let openerTab = ((openerBrowser && this.getTabForBrowser(openerBrowser)) ||
|
||||
(relatedToCurrent && this.selectedTab));
|
||||
|
||||
var t = document.createElementNS(this._XUL_NS, "tab");
|
||||
var t = document.createXULElement("tab");
|
||||
|
||||
t.openerTab = openerTab;
|
||||
|
||||
@ -3724,6 +3726,7 @@ window._gBrowser = {
|
||||
}
|
||||
|
||||
aTab.setAttribute("multiselected", "true");
|
||||
aTab.setAttribute("aria-selected", "true");
|
||||
this._multiSelectedTabsSet.add(aTab);
|
||||
this._startMultiSelectChange();
|
||||
if (this._multiSelectChangeRemovals.has(aTab)) {
|
||||
@ -3763,6 +3766,7 @@ window._gBrowser = {
|
||||
return;
|
||||
}
|
||||
aTab.removeAttribute("multiselected");
|
||||
aTab.removeAttribute("aria-selected");
|
||||
this._multiSelectedTabsSet.delete(aTab);
|
||||
this._startMultiSelectChange();
|
||||
if (this._multiSelectChangeAdditions.has(aTab)) {
|
||||
|
@ -128,6 +128,11 @@
|
||||
|
||||
this._tabMinWidth = this._tabMinWidthPref;
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "_multiselectEnabledPref",
|
||||
"browser.tabs.multiselect", null,
|
||||
(pref, prevValue, newValue) => this._multiselectEnabled = newValue);
|
||||
this._multiselectEnabled = this._multiselectEnabledPref;
|
||||
|
||||
this._setPositionalAttributes();
|
||||
|
||||
CustomizableUI.addListener(this);
|
||||
@ -172,6 +177,17 @@
|
||||
</setter>
|
||||
</property>
|
||||
|
||||
<property name="_multiselectEnabled">
|
||||
<setter>
|
||||
// Unlike boolean HTML attributes, the value of boolean ARIA attributes actually matters.
|
||||
this.setAttribute("aria-multiselectable", !!val);
|
||||
return val;
|
||||
</setter>
|
||||
<getter>
|
||||
return this.getAttribute("aria-multiselectable") == "true";
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<method name="observe">
|
||||
<parameter name="aSubject"/>
|
||||
<parameter name="aTopic"/>
|
||||
@ -2069,7 +2085,7 @@
|
||||
} else {
|
||||
// When browser.tabs.multiselect config is set to false,
|
||||
// then we ignore the state of multi-selection keys (Ctrl/Cmd).
|
||||
const tabSelectionToggled = Services.prefs.getBoolPref("browser.tabs.multiselect") &&
|
||||
const tabSelectionToggled = tabContainer._multiselectEnabled &&
|
||||
(event.getModifierState("Accel") || event.shiftKey);
|
||||
|
||||
if (this.mOverCloseButton || this._overPlayingIcon || tabSelectionToggled) {
|
||||
@ -2092,7 +2108,8 @@
|
||||
</handler>
|
||||
|
||||
<handler event="click" button="0"><![CDATA[
|
||||
if (Services.prefs.getBoolPref("browser.tabs.multiselect")) {
|
||||
let tabContainer = this.parentNode;
|
||||
if (tabContainer._multiselectEnabled) {
|
||||
let shiftKey = event.shiftKey;
|
||||
let accelKey = event.getModifierState("Accel");
|
||||
if (shiftKey) {
|
||||
@ -2188,41 +2205,4 @@
|
||||
</handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
|
||||
<binding id="tabbrowser-browser"
|
||||
extends="chrome://global/content/bindings/browser.xml#browser">
|
||||
<implementation>
|
||||
<field name="tabModalPromptBox">null</field>
|
||||
|
||||
<!-- throws exception for unknown schemes -->
|
||||
<method name="loadURI">
|
||||
<parameter name="aURI"/>
|
||||
<parameter name="aParams"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
_loadURI(this, aURI, aParams);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="tabbrowser-remote-browser"
|
||||
extends="chrome://global/content/bindings/remote-browser.xml#remote-browser">
|
||||
<implementation>
|
||||
<field name="tabModalPromptBox">null</field>
|
||||
|
||||
<!-- throws exception for unknown schemes -->
|
||||
<method name="loadURI">
|
||||
<parameter name="aURI"/>
|
||||
<parameter name="aParams"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
_loadURI(this, aURI, aParams);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
||||
|
@ -7,6 +7,9 @@ support-files =
|
||||
[browser_contextmenu_touch.js]
|
||||
skip-if = !(os == 'win' && os_version == '10.0')
|
||||
[browser_contextmenu_linkopen.js]
|
||||
[browser_contextmenu_iframe.js]
|
||||
support-files =
|
||||
test_contextmenu_iframe.html
|
||||
[browser_utilityOverlay.js]
|
||||
skip-if = os == "linux" || os == "mac" #Bug 1444631
|
||||
[browser_utilityOverlayPrincipal.js]
|
||||
|
@ -0,0 +1,47 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_LINK = "https://example.com/";
|
||||
const RESOURCE_LINK = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "test_contextmenu_iframe.html";
|
||||
|
||||
/* This test checks that a context menu can open up
|
||||
* a frame into it's own tab. */
|
||||
|
||||
add_task(async function test_open_iframe() {
|
||||
let testTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, RESOURCE_LINK);
|
||||
const selector = "#iframe";
|
||||
const openPromise = BrowserTestUtils.waitForNewTab(gBrowser, TEST_LINK, false);
|
||||
const contextMenu = document.getElementById("contentAreaContextMenu");
|
||||
is(contextMenu.state, "closed", "checking if popup is closed");
|
||||
let awaitPopupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(selector, {
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
centered: true,
|
||||
},
|
||||
gBrowser.selectedBrowser);
|
||||
await awaitPopupShown;
|
||||
info("Popup Shown");
|
||||
const awaitPopupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
|
||||
|
||||
// Open frame submenu
|
||||
const menuPopup = contextMenu.querySelector("#frame").menupopup;
|
||||
const menuPopupPromise = BrowserTestUtils.waitForEvent(menuPopup, "popupshown");
|
||||
menuPopup.openPopup();
|
||||
await menuPopupPromise;
|
||||
|
||||
let domItem = contextMenu.querySelector("#context-openframeintab");
|
||||
info("Going to click item " + domItem.id);
|
||||
ok(BrowserTestUtils.is_visible(domItem), "DOM context menu item tab should be visible");
|
||||
ok(!domItem.disabled, "DOM context menu item tab shouldn't be disabled");
|
||||
domItem.click();
|
||||
|
||||
let openedTab = await openPromise;
|
||||
contextMenu.hidePopup();
|
||||
await awaitPopupHidden;
|
||||
await BrowserTestUtils.removeTab(openedTab);
|
||||
|
||||
BrowserTestUtils.removeTab(testTab);
|
||||
});
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Subtest for browser context menu iframes</title>
|
||||
</head>
|
||||
<body>
|
||||
Browser context menu iframe subtest.
|
||||
|
||||
<iframe src="https://example.com/" id="iframe"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -12,6 +12,8 @@ add_task(async function() {
|
||||
});
|
||||
|
||||
function testSelectedTabs(tabs) {
|
||||
is(gBrowser.tabContainer.getAttribute("aria-multiselectable"), "true",
|
||||
"tabbrowser should be marked as aria-multiselectable");
|
||||
gBrowser.selectedTabs = tabs;
|
||||
let {selectedTab, selectedTabs, _multiSelectedTabsSet} = gBrowser;
|
||||
is(selectedTab, tabs[0], "The selected tab should be the expected one");
|
||||
@ -20,12 +22,15 @@ add_task(async function() {
|
||||
ok(!_multiSelectedTabsSet.has(selectedTab), "Selected tab shouldn't be in _multiSelectedTabsSet");
|
||||
is(selectedTabs.length, 1, "selectedTabs should contain a single tab");
|
||||
is(selectedTabs[0], selectedTab, "selectedTabs should contain the selected tab");
|
||||
ok(!selectedTab.hasAttribute("aria-selected"),
|
||||
"Selected tab shouldn't be marked as aria-selected when only one tab is selected");
|
||||
} else {
|
||||
ok(selectedTabs.length, tabs.length, "Check number of selected tabs");
|
||||
for (let tab of tabs) {
|
||||
ok(tab.multiselected, "Tab should be multi-selected");
|
||||
ok(_multiSelectedTabsSet.has(tab), "Tab should be in _multiSelectedTabsSet");
|
||||
ok(selectedTabs.includes(tab), "Tab should be in selectedTabs");
|
||||
is(tab.getAttribute("aria-selected"), "true", "Selected tab should be marked as aria-selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2642,9 +2642,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
child.style.display;
|
||||
child.style.display = "none";
|
||||
}
|
||||
let XUL_NS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
let iframe = document.createElementNS(XUL_NS, "iframe");
|
||||
let iframe = document.createXULElement("iframe");
|
||||
iframe.setAttribute("type", "content");
|
||||
iframe.setAttribute("flex", "1");
|
||||
iframe.style.transition = "height 100ms";
|
||||
|
@ -25,10 +25,10 @@ function getBrowser(sidebar) {
|
||||
return Promise.resolve(browser);
|
||||
}
|
||||
|
||||
let stack = document.createElementNS(XUL_NS, "stack");
|
||||
let stack = document.createXULElement("stack");
|
||||
stack.setAttribute("flex", "1");
|
||||
|
||||
browser = document.createElementNS(XUL_NS, "browser");
|
||||
browser = document.createXULElement("browser");
|
||||
browser.setAttribute("id", "webext-panels-browser");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute("flex", "1");
|
||||
|
@ -28,8 +28,6 @@ XPCOMUtils.defineLazyGetter(this, "gWidgetsBundle", function() {
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gELS",
|
||||
"@mozilla.org/eventlistenerservice;1", "nsIEventListenerService");
|
||||
|
||||
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
const kSpecialWidgetPfx = "customizableui-special-";
|
||||
|
||||
const kPrefCustomizationState = "browser.uiCustomization.state";
|
||||
@ -1364,7 +1362,7 @@ var CustomizableUIInternal = {
|
||||
|
||||
createSpecialWidget(aId, aDocument) {
|
||||
let nodeName = "toolbar" + aId.match(/spring|spacer|separator/)[0];
|
||||
let node = aDocument.createElementNS(kNSXUL, nodeName);
|
||||
let node = aDocument.createXULElement(nodeName);
|
||||
node.className = "chromeclass-toolbar-additional";
|
||||
node.id = this.ensureSpecialWidgetId(aId);
|
||||
return node;
|
||||
@ -1459,7 +1457,7 @@ var CustomizableUIInternal = {
|
||||
if (aWidget.onBeforeCreated) {
|
||||
aWidget.onBeforeCreated(aDocument);
|
||||
}
|
||||
node = aDocument.createElementNS(kNSXUL, "toolbarbutton");
|
||||
node = aDocument.createXULElement("toolbarbutton");
|
||||
|
||||
node.setAttribute("id", aWidget.id);
|
||||
node.setAttribute("widget-id", aWidget.id);
|
||||
@ -3906,9 +3904,9 @@ var CustomizableUI = {
|
||||
if (!fragment.lastElementChild || fragment.lastElementChild.localName == "menuseparator") {
|
||||
continue;
|
||||
}
|
||||
subviewItem = doc.createElementNS(kNSXUL, "menuseparator");
|
||||
subviewItem = doc.createXULElement("menuseparator");
|
||||
} else if (menuChild.localName == "menuitem") {
|
||||
subviewItem = doc.createElementNS(kNSXUL, "toolbarbutton");
|
||||
subviewItem = doc.createXULElement("toolbarbutton");
|
||||
CustomizableUI.addShortcut(menuChild, subviewItem);
|
||||
|
||||
let item = menuChild;
|
||||
|
@ -26,7 +26,6 @@ XPCOMUtils.defineLazyGetter(this, "CharsetBundle", function() {
|
||||
return Services.strings.createBundle(kCharsetBundle);
|
||||
});
|
||||
|
||||
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "log", () => {
|
||||
@ -196,10 +195,10 @@ const CustomizableWidgets = [
|
||||
onCreated(aNode) {
|
||||
// Add an observer so the button is checked while the sidebar is open
|
||||
let doc = aNode.ownerDocument;
|
||||
let obChecked = doc.createElementNS(kNSXUL, "observes");
|
||||
let obChecked = doc.createXULElement("observes");
|
||||
obChecked.setAttribute("element", "sidebar-box");
|
||||
obChecked.setAttribute("attribute", "checked");
|
||||
let obPosition = doc.createElementNS(kNSXUL, "observes");
|
||||
let obPosition = doc.createXULElement("observes");
|
||||
obPosition.setAttribute("element", "sidebar-box");
|
||||
obPosition.setAttribute("attribute", "positionend");
|
||||
|
||||
@ -244,7 +243,7 @@ const CustomizableWidgets = [
|
||||
"class": "toolbarbutton-1 toolbarbutton-combined",
|
||||
}];
|
||||
|
||||
let node = aDocument.createElementNS(kNSXUL, "toolbaritem");
|
||||
let node = aDocument.createXULElement("toolbaritem");
|
||||
node.setAttribute("id", "zoom-controls");
|
||||
node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
|
||||
node.setAttribute("title", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
|
||||
@ -255,8 +254,8 @@ const CustomizableWidgets = [
|
||||
|
||||
buttons.forEach(function(aButton, aIndex) {
|
||||
if (aIndex != 0)
|
||||
node.appendChild(aDocument.createElementNS(kNSXUL, "separator"));
|
||||
let btnNode = aDocument.createElementNS(kNSXUL, "toolbarbutton");
|
||||
node.appendChild(aDocument.createXULElement("separator"));
|
||||
let btnNode = aDocument.createXULElement("toolbarbutton");
|
||||
setAttributes(btnNode, aButton);
|
||||
node.appendChild(btnNode);
|
||||
});
|
||||
@ -290,7 +289,7 @@ const CustomizableWidgets = [
|
||||
"class": "toolbarbutton-1 toolbarbutton-combined",
|
||||
}];
|
||||
|
||||
let node = aDocument.createElementNS(kNSXUL, "toolbaritem");
|
||||
let node = aDocument.createXULElement("toolbaritem");
|
||||
node.setAttribute("id", "edit-controls");
|
||||
node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
|
||||
node.setAttribute("title", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
|
||||
@ -301,8 +300,8 @@ const CustomizableWidgets = [
|
||||
|
||||
buttons.forEach(function(aButton, aIndex) {
|
||||
if (aIndex != 0)
|
||||
node.appendChild(aDocument.createElementNS(kNSXUL, "separator"));
|
||||
let btnNode = aDocument.createElementNS(kNSXUL, "toolbarbutton");
|
||||
node.appendChild(aDocument.createXULElement("separator"));
|
||||
let btnNode = aDocument.createXULElement("toolbarbutton");
|
||||
setAttributes(btnNode, aButton);
|
||||
node.appendChild(btnNode);
|
||||
});
|
||||
@ -386,7 +385,7 @@ const CustomizableWidgets = [
|
||||
let list = this.charsetInfo[aSection];
|
||||
|
||||
for (let item of list) {
|
||||
let elem = aDocument.createElementNS(kNSXUL, "toolbarbutton");
|
||||
let elem = aDocument.createXULElement("toolbarbutton");
|
||||
elem.setAttribute("label", item.label);
|
||||
elem.setAttribute("type", "checkbox");
|
||||
elem.section = aSection;
|
||||
@ -644,7 +643,7 @@ if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
|
||||
for (let client of clients) {
|
||||
// add a menu separator for all clients other than the first.
|
||||
if (fragment.lastElementChild) {
|
||||
let separator = doc.createElementNS(kNSXUL, "menuseparator");
|
||||
let separator = doc.createXULElement("menuseparator");
|
||||
fragment.appendChild(separator);
|
||||
}
|
||||
if (paginationInfo && paginationInfo.clientId == client.id) {
|
||||
@ -678,7 +677,7 @@ if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
|
||||
}
|
||||
let message = this._tabsList.getAttribute(messageAttr);
|
||||
let doc = this._tabsList.ownerDocument;
|
||||
let messageLabel = doc.createElementNS(kNSXUL, "label");
|
||||
let messageLabel = doc.createXULElement("label");
|
||||
messageLabel.textContent = message;
|
||||
appendTo.appendChild(messageLabel);
|
||||
return messageLabel;
|
||||
@ -686,7 +685,7 @@ if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
|
||||
_appendClient(client, attachFragment, maxTabs = this.TABS_PER_PAGE) {
|
||||
let doc = attachFragment.ownerDocument;
|
||||
// Create the element for the remote client.
|
||||
let clientItem = doc.createElementNS(kNSXUL, "label");
|
||||
let clientItem = doc.createXULElement("label");
|
||||
clientItem.setAttribute("itemtype", "client");
|
||||
let window = doc.defaultView;
|
||||
clientItem.setAttribute("tooltiptext",
|
||||
@ -726,7 +725,7 @@ if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
|
||||
}
|
||||
},
|
||||
_createTabElement(doc, tabInfo) {
|
||||
let item = doc.createElementNS(kNSXUL, "toolbarbutton");
|
||||
let item = doc.createXULElement("toolbarbutton");
|
||||
let tooltipText = (tabInfo.title ? tabInfo.title + "\n" : "") + tabInfo.url;
|
||||
item.setAttribute("itemtype", "tab");
|
||||
item.setAttribute("class", "subviewbutton");
|
||||
@ -758,7 +757,7 @@ if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
|
||||
labelAttr = "showMoreLabel";
|
||||
tooltipAttr = "showMoreTooltipText";
|
||||
}
|
||||
let showAllItem = doc.createElementNS(kNSXUL, "toolbarbutton");
|
||||
let showAllItem = doc.createXULElement("toolbarbutton");
|
||||
showAllItem.setAttribute("itemtype", "showmorebutton");
|
||||
showAllItem.setAttribute("class", "subviewbutton");
|
||||
let label = this._tabsList.getAttribute(labelAttr);
|
||||
|
@ -623,7 +623,6 @@ const PanelUI = {
|
||||
let helpMenu = document.getElementById("menu_HelpPopup");
|
||||
let items = this.getElementsByTagName("vbox")[0];
|
||||
let attrs = ["oncommand", "onclick", "label", "key", "disabled"];
|
||||
let NSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
// Remove all buttons from the view
|
||||
while (items.firstChild) {
|
||||
@ -636,7 +635,7 @@ const PanelUI = {
|
||||
for (let node of menuItems) {
|
||||
if (node.hidden)
|
||||
continue;
|
||||
let button = document.createElementNS(NSXUL, "toolbarbutton");
|
||||
let button = document.createXULElement("toolbarbutton");
|
||||
// Copy specific attributes from a menuitem of the Help menu
|
||||
for (let attrName of attrs) {
|
||||
if (!node.hasAttribute(attrName))
|
||||
|
@ -33,8 +33,6 @@ const {
|
||||
|
||||
const POPUP_LOAD_TIMEOUT_MS = 200;
|
||||
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
function promisePopupShown(popup) {
|
||||
return new Promise(resolve => {
|
||||
if (popup.state == "open") {
|
||||
@ -239,10 +237,10 @@ class BasePopup {
|
||||
createBrowser(viewNode, popupURL = null) {
|
||||
let document = viewNode.ownerDocument;
|
||||
|
||||
let stack = document.createElementNS(XUL_NS, "stack");
|
||||
let stack = document.createXULElement("stack");
|
||||
stack.setAttribute("class", "webextension-popup-stack");
|
||||
|
||||
let browser = document.createElementNS(XUL_NS, "browser");
|
||||
let browser = document.createXULElement("browser");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute("disableglobalhistory", "true");
|
||||
browser.setAttribute("transparent", "true");
|
||||
|
@ -31,8 +31,6 @@ const POPUP_PRELOAD_TIMEOUT_MS = 200;
|
||||
const POPUP_OPEN_MS_HISTOGRAM = "WEBEXT_BROWSERACTION_POPUP_OPEN_MS";
|
||||
const POPUP_RESULT_HISTOGRAM = "WEBEXT_BROWSERACTION_POPUP_PRELOAD_RESULT_COUNT";
|
||||
|
||||
var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
// WeakMap[Extension -> BrowserAction]
|
||||
const browserActionMap = new WeakMap();
|
||||
|
||||
@ -143,7 +141,7 @@ this.browserAction = class extends ExtensionAPI {
|
||||
localized: false,
|
||||
|
||||
onBeforeCreated: document => {
|
||||
let view = document.createElementNS(XUL_NS, "panelview");
|
||||
let view = document.createXULElement("panelview");
|
||||
view.id = this.viewId;
|
||||
view.setAttribute("flex", "1");
|
||||
view.setAttribute("extension", true);
|
||||
|
@ -12,8 +12,6 @@ var {
|
||||
ExtensionError,
|
||||
} = ExtensionUtils;
|
||||
|
||||
var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
const EXECUTE_PAGE_ACTION = "_execute_page_action";
|
||||
const EXECUTE_BROWSER_ACTION = "_execute_browser_action";
|
||||
const EXECUTE_SIDEBAR_ACTION = "_execute_sidebar_action";
|
||||
@ -154,7 +152,7 @@ this.commands = class extends ExtensionAPI {
|
||||
*/
|
||||
registerKeysToDocument(window, commands) {
|
||||
let doc = window.document;
|
||||
let keyset = doc.createElementNS(XUL_NS, "keyset");
|
||||
let keyset = doc.createXULElement("keyset");
|
||||
keyset.id = `ext-keyset-id-${this.id}`;
|
||||
if (this.keysetsMap.has(window)) {
|
||||
this.keysetsMap.get(window).remove();
|
||||
@ -232,7 +230,7 @@ this.commands = class extends ExtensionAPI {
|
||||
* @returns {Document} The newly created Key element.
|
||||
*/
|
||||
buildKeyFromShortcut(doc, name, shortcut) {
|
||||
let keyElement = doc.createElementNS(XUL_NS, "key");
|
||||
let keyElement = doc.createXULElement("key");
|
||||
|
||||
let parts = shortcut.split("+");
|
||||
|
||||
|
@ -16,8 +16,6 @@ var {
|
||||
promiseEvent,
|
||||
} = ExtensionUtils;
|
||||
|
||||
var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
/**
|
||||
* Represents an addon devtools panel in the main process.
|
||||
*
|
||||
@ -218,13 +216,13 @@ class ParentDevToolsPanel {
|
||||
// extension sidebar pages).
|
||||
let stack = document.getElementById("webext-panels-stack");
|
||||
if (!stack) {
|
||||
stack = document.createElementNS(XUL_NS, "stack");
|
||||
stack = document.createXULElement("stack");
|
||||
stack.setAttribute("flex", "1");
|
||||
stack.setAttribute("id", "webext-panels-stack");
|
||||
document.documentElement.appendChild(stack);
|
||||
}
|
||||
|
||||
const browser = document.createElementNS(XUL_NS, "browser");
|
||||
const browser = document.createXULElement("browser");
|
||||
browser.setAttribute("id", "webext-panels-browser");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute("disableglobalhistory", "true");
|
||||
|
@ -12,8 +12,6 @@ var {
|
||||
IconDetails,
|
||||
} = ExtensionParent;
|
||||
|
||||
var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
// WeakMap[Extension -> SidebarAction]
|
||||
let sidebarActionMap = new WeakMap();
|
||||
|
||||
@ -149,7 +147,7 @@ this.sidebarAction = class extends ExtensionAPI {
|
||||
|
||||
// Use of the broadcaster allows browser-sidebar.js to properly manage the
|
||||
// checkmarks in the menus.
|
||||
let broadcaster = document.createElementNS(XUL_NS, "broadcaster");
|
||||
let broadcaster = document.createXULElement("broadcaster");
|
||||
broadcaster.setAttribute("id", this.id);
|
||||
broadcaster.setAttribute("autoCheck", "false");
|
||||
broadcaster.setAttribute("type", "checkbox");
|
||||
@ -172,14 +170,14 @@ this.sidebarAction = class extends ExtensionAPI {
|
||||
header.addEventListener("SidebarShown", this.updateHeader);
|
||||
|
||||
// Insert a menuitem for View->Show Sidebars.
|
||||
let menuitem = document.createElementNS(XUL_NS, "menuitem");
|
||||
let menuitem = document.createXULElement("menuitem");
|
||||
menuitem.setAttribute("id", this.menuId);
|
||||
menuitem.setAttribute("observes", this.id);
|
||||
menuitem.setAttribute("class", "menuitem-iconic webextension-menuitem");
|
||||
this.setMenuIcon(menuitem, details);
|
||||
|
||||
// Insert a toolbarbutton for the sidebar dropdown selector.
|
||||
let toolbarbutton = document.createElementNS(XUL_NS, "toolbarbutton");
|
||||
let toolbarbutton = document.createXULElement("toolbarbutton");
|
||||
toolbarbutton.setAttribute("id", this.buttonId);
|
||||
toolbarbutton.setAttribute("observes", this.id);
|
||||
toolbarbutton.setAttribute("class", "subviewbutton subviewbutton-iconic webextension-menuitem");
|
||||
|
@ -127,7 +127,7 @@ this.AboutPreferences = class AboutPreferences {
|
||||
renderPreferences({document, Preferences, gHomePane}, strings, prefStructure) {
|
||||
// Helper to create a new element and append it
|
||||
const createAppend = (tag, parent) => parent.appendChild(
|
||||
document.createElementNS(XUL_NS, tag));
|
||||
document.createXULElement(tag));
|
||||
|
||||
// Helper to get strings and format with values if necessary
|
||||
const formatString = id => {
|
||||
|
@ -530,14 +530,12 @@
|
||||
<method name="initContextMenu">
|
||||
<parameter name="aMenu"/>
|
||||
<body><![CDATA[
|
||||
const kXULNS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
let stringBundle = document.getBindingParent(this)._stringBundle;
|
||||
|
||||
let pasteAndSearch, suggestMenuItem;
|
||||
let element, label, akey;
|
||||
|
||||
element = document.createElementNS(kXULNS, "menuseparator");
|
||||
element = document.createXULElement("menuseparator");
|
||||
aMenu.appendChild(element);
|
||||
|
||||
let insertLocation = aMenu.firstElementChild;
|
||||
@ -545,7 +543,7 @@
|
||||
insertLocation.getAttribute("cmd") != "cmd_paste")
|
||||
insertLocation = insertLocation.nextElementSibling;
|
||||
if (insertLocation) {
|
||||
element = document.createElementNS(kXULNS, "menuitem");
|
||||
element = document.createXULElement("menuitem");
|
||||
label = stringBundle.getString("cmd_pasteAndSearch");
|
||||
element.setAttribute("label", label);
|
||||
element.setAttribute("anonid", "paste-and-search");
|
||||
@ -554,7 +552,7 @@
|
||||
pasteAndSearch = element;
|
||||
}
|
||||
|
||||
element = document.createElementNS(kXULNS, "menuitem");
|
||||
element = document.createXULElement("menuitem");
|
||||
label = stringBundle.getString("cmd_clearHistory");
|
||||
akey = stringBundle.getString("cmd_clearHistory_accesskey");
|
||||
element.setAttribute("label", label);
|
||||
@ -562,7 +560,7 @@
|
||||
element.setAttribute("cmd", "cmd_clearhistory");
|
||||
aMenu.appendChild(element);
|
||||
|
||||
element = document.createElementNS(kXULNS, "menuitem");
|
||||
element = document.createXULElement("menuitem");
|
||||
label = stringBundle.getString("cmd_showSuggestions");
|
||||
akey = stringBundle.getString("cmd_showSuggestions_accesskey");
|
||||
element.setAttribute("anonid", "toggle-suggest-item");
|
||||
@ -1508,13 +1506,10 @@
|
||||
this.settingsButton.id = origin + "-anon-search-settings";
|
||||
this.settingsButtonCompact.id = origin + "-anon-search-settings-compact";
|
||||
|
||||
const kXULNS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
let dummyItems = enginesPerRow - (oneOffCount % enginesPerRow || enginesPerRow);
|
||||
for (let i = 0; i < engines.length; ++i) {
|
||||
let engine = engines[i];
|
||||
let button = document.createElementNS(kXULNS, "button");
|
||||
let button = document.createXULElement("button");
|
||||
button.id = this._buttonIDForEngine(engine);
|
||||
let uri = "chrome://browser/skin/search-engine-placeholder.png";
|
||||
if (engine.iconURI) {
|
||||
@ -1540,7 +1535,7 @@
|
||||
|
||||
let hasDummyItems = !!dummyItems;
|
||||
while (dummyItems) {
|
||||
let button = document.createElementNS(kXULNS, "button");
|
||||
let button = document.createXULElement("button");
|
||||
button.setAttribute("class", "searchbar-engine-one-off-item dummy last-row");
|
||||
button.setAttribute("width", buttonWidth);
|
||||
|
||||
@ -1589,15 +1584,12 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const kXULNS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
let engines = gBrowser.selectedBrowser.engines;
|
||||
let tooManyEngines = engines.length > this._addEngineMenuThreshold;
|
||||
|
||||
if (tooManyEngines) {
|
||||
// Make the top-level menu button.
|
||||
let button = document.createElementNS(kXULNS, "toolbarbutton");
|
||||
let button = document.createXULElement("toolbarbutton");
|
||||
list.appendChild(button);
|
||||
button.classList.add("addengine-item", "badged-button");
|
||||
button.setAttribute("anonid", "addengine-menu-button");
|
||||
@ -1616,7 +1608,7 @@
|
||||
}
|
||||
|
||||
// Now make the button's child menupopup.
|
||||
list = document.createElementNS(kXULNS, "menupopup");
|
||||
list = document.createXULElement("menupopup");
|
||||
button.appendChild(list);
|
||||
list.setAttribute("anonid", "addengine-menu");
|
||||
list.setAttribute("position", "topright topleft");
|
||||
@ -1643,7 +1635,7 @@
|
||||
// handling for free inside menupopups.
|
||||
let eltType = tooManyEngines ? "menuitem" : "toolbarbutton";
|
||||
for (let engine of engines) {
|
||||
let button = document.createElementNS(kXULNS, eltType);
|
||||
let button = document.createXULElement(eltType);
|
||||
button.classList.add("addengine-item");
|
||||
if (!tooManyEngines) {
|
||||
button.classList.add("badged-button");
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
var EXPORTED_SYMBOLS = ["RecentlyClosedTabsAndWindowsMenuUtils"];
|
||||
|
||||
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "PluralForm",
|
||||
@ -138,7 +136,7 @@ function setImage(aItem, aElement) {
|
||||
*/
|
||||
function createEntry(aTagName, aIsWindowsFragment, aIndex, aClosedTab,
|
||||
aDocument, aMenuLabel, aFragment) {
|
||||
let element = aDocument.createElementNS(kNSXUL, aTagName);
|
||||
let element = aDocument.createXULElement(aTagName);
|
||||
|
||||
element.setAttribute("label", aMenuLabel);
|
||||
if (aClosedTab.image) {
|
||||
@ -196,7 +194,7 @@ function createEntry(aTagName, aIsWindowsFragment, aIndex, aClosedTab,
|
||||
function createRestoreAllEntry(aDocument, aFragment, aPrefixRestoreAll,
|
||||
aIsWindowsFragment, aRestoreAllLabel,
|
||||
aEntryCount, aTagName) {
|
||||
let restoreAllElements = aDocument.createElementNS(kNSXUL, aTagName);
|
||||
let restoreAllElements = aDocument.createXULElement(aTagName);
|
||||
restoreAllElements.classList.add("restoreallitem");
|
||||
restoreAllElements.setAttribute("label", navigatorBundle.GetStringFromName(aRestoreAllLabel));
|
||||
restoreAllElements.setAttribute("oncommand",
|
||||
@ -205,7 +203,7 @@ function createRestoreAllEntry(aDocument, aFragment, aPrefixRestoreAll,
|
||||
if (aPrefixRestoreAll) {
|
||||
aFragment.insertBefore(restoreAllElements, aFragment.firstChild);
|
||||
} else {
|
||||
aFragment.appendChild(aDocument.createElementNS(kNSXUL, "menuseparator"));
|
||||
aFragment.appendChild(aDocument.createXULElement("menuseparator"));
|
||||
aFragment.appendChild(restoreAllElements);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ var EXPORTED_SYMBOLS = ["FormAutofillPreferences"];
|
||||
const BUNDLE_URI = "chrome://formautofill/locale/formautofill.properties";
|
||||
const MANAGE_ADDRESSES_URL = "chrome://formautofill/content/manageAddresses.xhtml";
|
||||
const MANAGE_CREDITCARDS_URL = "chrome://formautofill/content/manageCreditCards.xhtml";
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://formautofill/FormAutofill.jsm");
|
||||
@ -68,17 +67,17 @@ FormAutofillPreferences.prototype = {
|
||||
*/
|
||||
createPreferenceGroup(document) {
|
||||
let learnMoreURL = Services.urlFormatter.formatURLPref("app.support.baseURL") + "autofill-card-address";
|
||||
let formAutofillGroup = document.createElementNS(XUL_NS, "vbox");
|
||||
let addressAutofill = document.createElementNS(XUL_NS, "hbox");
|
||||
let addressAutofillCheckboxGroup = document.createElementNS(XUL_NS, "hbox");
|
||||
let addressAutofillCheckbox = document.createElementNS(XUL_NS, "checkbox");
|
||||
let addressAutofillCheckboxLabel = document.createElementNS(XUL_NS, "label");
|
||||
let addressAutofillCheckboxLabelSpacer = document.createElementNS(XUL_NS, "spacer");
|
||||
let addressAutofillLearnMore = document.createElementNS(XUL_NS, "label");
|
||||
let savedAddressesBtn = document.createElementNS(XUL_NS, "button");
|
||||
let formAutofillGroup = document.createXULElement("vbox");
|
||||
let addressAutofill = document.createXULElement("hbox");
|
||||
let addressAutofillCheckboxGroup = document.createXULElement("hbox");
|
||||
let addressAutofillCheckbox = document.createXULElement("checkbox");
|
||||
let addressAutofillCheckboxLabel = document.createXULElement("label");
|
||||
let addressAutofillCheckboxLabelSpacer = document.createXULElement("spacer");
|
||||
let addressAutofillLearnMore = document.createXULElement("label");
|
||||
let savedAddressesBtn = document.createXULElement("button");
|
||||
// Wrappers are used to properly compute the search tooltip positions
|
||||
let savedAddressesBtnWrapper = document.createElementNS(XUL_NS, "hbox");
|
||||
let savedCreditCardsBtnWrapper = document.createElementNS(XUL_NS, "hbox");
|
||||
let savedAddressesBtnWrapper = document.createXULElement("hbox");
|
||||
let savedCreditCardsBtnWrapper = document.createXULElement("hbox");
|
||||
|
||||
savedAddressesBtn.className = "accessory-button";
|
||||
addressAutofillCheckboxLabelSpacer.className = "tail-with-learn-more";
|
||||
@ -129,13 +128,13 @@ FormAutofillPreferences.prototype = {
|
||||
};
|
||||
|
||||
if (FormAutofill.isAutofillCreditCardsAvailable) {
|
||||
let creditCardAutofill = document.createElementNS(XUL_NS, "hbox");
|
||||
let creditCardAutofillCheckboxGroup = document.createElementNS(XUL_NS, "hbox");
|
||||
let creditCardAutofillCheckbox = document.createElementNS(XUL_NS, "checkbox");
|
||||
let creditCardAutofillCheckboxLabel = document.createElementNS(XUL_NS, "label");
|
||||
let creditCardAutofillCheckboxLabelSpacer = document.createElementNS(XUL_NS, "spacer");
|
||||
let creditCardAutofillLearnMore = document.createElementNS(XUL_NS, "label");
|
||||
let savedCreditCardsBtn = document.createElementNS(XUL_NS, "button");
|
||||
let creditCardAutofill = document.createXULElement("hbox");
|
||||
let creditCardAutofillCheckboxGroup = document.createXULElement("hbox");
|
||||
let creditCardAutofillCheckbox = document.createXULElement("checkbox");
|
||||
let creditCardAutofillCheckboxLabel = document.createXULElement("label");
|
||||
let creditCardAutofillCheckboxLabelSpacer = document.createXULElement("spacer");
|
||||
let creditCardAutofillLearnMore = document.createXULElement("label");
|
||||
let savedCreditCardsBtn = document.createXULElement("button");
|
||||
savedCreditCardsBtn.className = "accessory-button";
|
||||
creditCardAutofillCheckboxLabelSpacer.className = "tail-with-learn-more";
|
||||
creditCardAutofillLearnMore.className = "learnMore text-link";
|
||||
|
@ -8,7 +8,6 @@ ChromeUtils.defineModuleGetter(this, "PanelMultiView",
|
||||
"resource:///modules/PanelMultiView.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = ["TabsPanel"];
|
||||
const NSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
function setAttributes(element, attrs) {
|
||||
for (let [name, value] of Object.entries(attrs)) {
|
||||
@ -216,7 +215,7 @@ class TabsPanel extends TabsListBase {
|
||||
|
||||
_createRow(tab) {
|
||||
let {doc} = this;
|
||||
let row = doc.createElementNS(NSXUL, "toolbaritem");
|
||||
let row = doc.createXULElement("toolbaritem");
|
||||
row.setAttribute("class", "all-tabs-item");
|
||||
if (this.className) {
|
||||
row.classList.add(this.className);
|
||||
@ -225,7 +224,7 @@ class TabsPanel extends TabsListBase {
|
||||
row.addEventListener("command", this);
|
||||
this.tabToElement.set(tab, row);
|
||||
|
||||
let button = doc.createElementNS(NSXUL, "toolbarbutton");
|
||||
let button = doc.createXULElement("toolbarbutton");
|
||||
button.setAttribute("class", "all-tabs-button subviewbutton subviewbutton-iconic");
|
||||
button.setAttribute("flex", "1");
|
||||
button.setAttribute("crop", "right");
|
||||
@ -233,7 +232,7 @@ class TabsPanel extends TabsListBase {
|
||||
|
||||
row.appendChild(button);
|
||||
|
||||
let secondaryButton = doc.createElementNS(NSXUL, "toolbarbutton");
|
||||
let secondaryButton = doc.createXULElement("toolbarbutton");
|
||||
secondaryButton.setAttribute(
|
||||
"class", "all-tabs-secondary-button subviewbutton subviewbutton-iconic");
|
||||
secondaryButton.setAttribute("closemenu", "none");
|
||||
|
@ -30,10 +30,6 @@
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.sidebar-placesTreechildren::-moz-tree-row {
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
:root[uidensity=touch] #search-box,
|
||||
:root[uidensity=touch] .sidebar-placesTreechildren::-moz-tree-row {
|
||||
min-height: 32px;
|
||||
@ -56,8 +52,3 @@
|
||||
/* Trees */
|
||||
|
||||
%include ../../shared/places/tree-icons.inc.css
|
||||
|
||||
treechildren:-moz-tree-image(container,selected),
|
||||
treechildren:-moz-tree-image(selected,focus) {
|
||||
fill: HighlightText;
|
||||
}
|
||||
|
@ -50,26 +50,3 @@ html {
|
||||
.textbox-search-clear:not([disabled]) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item-twisty-container {
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
min-width: 9px; /* The image's width is 9 pixels */
|
||||
height: 9px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.item.client .item-twisty-container {
|
||||
background-image: url("chrome://global/skin/tree/twisty-expanded.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.item.client.closed .item-twisty-container {
|
||||
background-image: url("chrome://global/skin/tree/twisty-collapsed.svg");
|
||||
}
|
||||
|
||||
.item.client.closed .item-twisty-container:dir(rtl) {
|
||||
background-image: url("chrome://global/skin/tree/twisty-collapsed-rtl.svg");
|
||||
}
|
||||
|
@ -5,14 +5,10 @@
|
||||
/* Places Organizer Sidebars */
|
||||
|
||||
#placesList > treechildren::-moz-tree-row {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
padding-bottom: 1px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
#placesList > treechildren::-moz-tree-cell-text {
|
||||
font-size: 12px;
|
||||
margin-inline-end: 6px;
|
||||
}
|
||||
|
||||
@ -47,27 +43,6 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#placesList > treechildren::-moz-tree-twisty {
|
||||
-moz-appearance: none;
|
||||
padding: 0 2px;
|
||||
list-style-image: url("chrome://global/skin/tree/arrow-collapsed.svg");
|
||||
-moz-context-properties: fill, fill-opacity;
|
||||
fill: currentColor;
|
||||
fill-opacity: 0.6;
|
||||
}
|
||||
|
||||
#placesList > treechildren::-moz-tree-twisty(selected) {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
#placesList > treechildren::-moz-tree-twisty(open) {
|
||||
list-style-image: url("chrome://global/skin/tree/arrow-expanded.svg");
|
||||
}
|
||||
|
||||
#placesList > treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(closed) {
|
||||
list-style-image: url("chrome://global/skin/tree/arrow-collapsed-rtl.svg");
|
||||
}
|
||||
|
||||
@media (-moz-mac-yosemite-theme) {
|
||||
#placesList > treechildren::-moz-tree-twisty(selected),
|
||||
#placesList > treechildren::-moz-tree-cell-text(selected) {
|
||||
|
@ -50,7 +50,6 @@
|
||||
.sidebar-placesTreechildren::-moz-tree-twisty(selected),
|
||||
.sidebar-placesTreechildren::-moz-tree-cell-text(selected) {
|
||||
color: #fff;
|
||||
fill-opacity: 1;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@ -60,39 +59,16 @@
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.sidebar-placesTreechildren::-moz-tree-twisty {
|
||||
-moz-appearance: none;
|
||||
padding: 0 2px;
|
||||
list-style-image: url("chrome://global/skin/tree/arrow-collapsed.svg");
|
||||
-moz-context-properties: fill, fill-opacity;
|
||||
fill: currentColor;
|
||||
fill-opacity: 0.6;
|
||||
}
|
||||
|
||||
.sidebar-placesTreechildren::-moz-tree-twisty(selected) {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.sidebar-placesTreechildren::-moz-tree-twisty(open) {
|
||||
list-style-image: url("chrome://global/skin/tree/arrow-expanded.svg");
|
||||
}
|
||||
|
||||
.sidebar-placesTreechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(closed) {
|
||||
list-style-image: url("chrome://global/skin/tree/arrow-collapsed-rtl.svg");
|
||||
}
|
||||
|
||||
@media (-moz-mac-yosemite-theme) {
|
||||
.sidebar-placesTreechildren::-moz-tree-twisty(selected),
|
||||
.sidebar-placesTreechildren::-moz-tree-cell-text(selected) {
|
||||
color: -moz-dialogtext;
|
||||
fill-opacity: 0.6;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sidebar-placesTreechildren::-moz-tree-twisty(selected, focus),
|
||||
.sidebar-placesTreechildren::-moz-tree-cell-text(selected, focus) {
|
||||
color: #fff;
|
||||
fill-opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +86,3 @@
|
||||
/* Trees */
|
||||
|
||||
%include ../../shared/places/tree-icons.inc.css
|
||||
|
||||
treechildren:-moz-tree-image(selected,focus) {
|
||||
fill: HighlightText;
|
||||
}
|
||||
|
@ -37,34 +37,6 @@
|
||||
-moz-font-smoothing-background-color: -moz-mac-active-source-list-selection;
|
||||
}
|
||||
|
||||
.item.client .item-twisty-container {
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
background-image: url("chrome://global/skin/tree/arrow-expanded.svg");
|
||||
-moz-context-properties: fill, fill-opacity;
|
||||
fill: currentColor;
|
||||
fill-opacity: 1;
|
||||
}
|
||||
|
||||
.item.client.closed .item-twisty-container {
|
||||
background-image: url("chrome://global/skin/tree/arrow-collapsed.svg");
|
||||
}
|
||||
|
||||
.item.client.closed .item-twisty-container:dir(rtl) {
|
||||
background-image: url("chrome://global/skin/tree/arrow-collapsed-rtl.svg");
|
||||
}
|
||||
|
||||
.item.client.selected:focus .item-twisty-container {
|
||||
fill-opacity: 1;
|
||||
}
|
||||
|
||||
@media (-moz-mac-yosemite-theme: 0) {
|
||||
.item.client.selected .item-twisty-container {
|
||||
fill-opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (-moz-mac-yosemite-theme) {
|
||||
.item.selected > .item-title-container {
|
||||
color: -moz-dialogtext;
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
treechildren:-moz-tree-image {
|
||||
-moz-context-properties: fill, fill-opacity;
|
||||
fill: -moz-FieldText;
|
||||
fill-opacity: 0.7;
|
||||
}
|
||||
|
||||
|
@ -80,6 +80,23 @@ body {
|
||||
color: HighlightText;
|
||||
}
|
||||
|
||||
.item.client .item-twisty-container {
|
||||
min-width: 8px;
|
||||
height: 8px;
|
||||
background-image: url("chrome://global/skin/icons/twisty-expanded.svg");
|
||||
-moz-context-properties: fill, fill-opacity;
|
||||
fill: currentColor;
|
||||
fill-opacity: 1;
|
||||
}
|
||||
|
||||
.item.client.closed .item-twisty-container {
|
||||
background-image: url("chrome://global/skin/icons/twisty-collapsed.svg");
|
||||
}
|
||||
|
||||
.item.client.closed .item-twisty-container:dir(rtl) {
|
||||
background-image: url("chrome://global/skin/icons/twisty-collapsed-rtl.svg");
|
||||
}
|
||||
|
||||
.client .item.tab > .item-title-container {
|
||||
padding-inline-start: 35px;
|
||||
}
|
||||
@ -90,11 +107,7 @@ body {
|
||||
|
||||
.item.client[clientType] > .item-title-container > .item-icon-container {
|
||||
-moz-context-properties: fill;
|
||||
fill: #4d4d4d;
|
||||
}
|
||||
|
||||
.item.client[clientType].selected:focus > .item-title-container > .item-icon-container {
|
||||
fill: white;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.item.client[clientType=phone] > .item-title-container > .item-icon-container {
|
||||
@ -133,6 +146,7 @@ body {
|
||||
flex-flow: row;
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
|
@ -75,35 +75,3 @@
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.item-twisty-container {
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
min-width: 9px; /* The image's width is 9 pixels */
|
||||
height: 9px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.item.client .item-twisty-container {
|
||||
background-image: url("chrome://global/skin/tree/twisty-expanded.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: #636363;
|
||||
}
|
||||
|
||||
.item.client.closed .item-twisty-container {
|
||||
background-image: url("chrome://global/skin/tree/twisty-collapsed.svg");
|
||||
fill: #b6b6b6;
|
||||
}
|
||||
|
||||
.item.client.closed .item-twisty-container:dir(rtl) {
|
||||
background-image: url("chrome://global/skin/tree/twisty-collapsed-rtl.svg");
|
||||
}
|
||||
|
||||
.item.client .item-twisty-container:hover {
|
||||
fill: #4ed0f9;
|
||||
}
|
||||
|
||||
.item.client.selected .item-twisty-container:not(:hover) {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const { getCurrentZoom } = require("devtools/shared/layout/utils");
|
||||
|
||||
@ -84,7 +83,7 @@ Menu.prototype.popup = function(screenX, screenY, toolbox) {
|
||||
|
||||
let popupset = doc.querySelector("popupset");
|
||||
if (!popupset) {
|
||||
popupset = doc.createElementNS(XUL_NS, "popupset");
|
||||
popupset = doc.createXULElement("popupset");
|
||||
doc.documentElement.appendChild(popupset);
|
||||
}
|
||||
// See bug 1285229, on Windows, opening the same popup multiple times in a
|
||||
@ -96,7 +95,7 @@ Menu.prototype.popup = function(screenX, screenY, toolbox) {
|
||||
popup.hidePopup();
|
||||
}
|
||||
|
||||
popup = doc.createElementNS(XUL_NS, "menupopup");
|
||||
popup = doc.createXULElement("menupopup");
|
||||
popup.setAttribute("menu-api", "true");
|
||||
popup.setAttribute("consumeoutsideclicks", "true");
|
||||
|
||||
@ -131,18 +130,18 @@ Menu.prototype._createMenuItems = function(parent) {
|
||||
}
|
||||
|
||||
if (item.submenu) {
|
||||
const menupopup = doc.createElementNS(XUL_NS, "menupopup");
|
||||
const menupopup = doc.createXULElement("menupopup");
|
||||
item.submenu._createMenuItems(menupopup);
|
||||
|
||||
const menu = doc.createElementNS(XUL_NS, "menu");
|
||||
const menu = doc.createXULElement("menu");
|
||||
menu.appendChild(menupopup);
|
||||
applyItemAttributesToNode(item, menu);
|
||||
parent.appendChild(menu);
|
||||
} else if (item.type === "separator") {
|
||||
const menusep = doc.createElementNS(XUL_NS, "menuseparator");
|
||||
const menusep = doc.createXULElement("menuseparator");
|
||||
parent.appendChild(menusep);
|
||||
} else {
|
||||
const menuitem = doc.createElementNS(XUL_NS, "menuitem");
|
||||
const menuitem = doc.createXULElement("menuitem");
|
||||
applyItemAttributesToNode(item, menuitem);
|
||||
|
||||
menuitem.addEventListener("command", () => {
|
||||
|
@ -11,8 +11,6 @@ var Telemetry = require("devtools/client/shared/telemetry");
|
||||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
|
||||
|
||||
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
/**
|
||||
* ToolSidebar provides methods to register tabs in the sidebar.
|
||||
* It's assumed that the sidebar contains a xul:tabbox.
|
||||
@ -118,7 +116,7 @@ ToolSidebar.prototype = {
|
||||
const tabs = this._tabbox.tabs;
|
||||
|
||||
// Create a container and insert it first in the tabbox
|
||||
const allTabsContainer = this._panelDoc.createElementNS(XULNS, "stack");
|
||||
const allTabsContainer = this._panelDoc.createXULElement("stack");
|
||||
this._tabbox.insertBefore(allTabsContainer, tabs);
|
||||
|
||||
// Move the tabs inside and make them flex
|
||||
@ -126,7 +124,7 @@ ToolSidebar.prototype = {
|
||||
tabs.setAttribute("flex", "1");
|
||||
|
||||
// Create the dropdown menu next to the tabs
|
||||
this._allTabsBtn = this._panelDoc.createElementNS(XULNS, "toolbarbutton");
|
||||
this._allTabsBtn = this._panelDoc.createXULElement("toolbarbutton");
|
||||
this._allTabsBtn.setAttribute("class", "devtools-sidebar-alltabs");
|
||||
this._allTabsBtn.setAttribute("end", "0");
|
||||
this._allTabsBtn.setAttribute("top", "0");
|
||||
@ -137,7 +135,7 @@ ToolSidebar.prototype = {
|
||||
this._allTabsBtn.setAttribute("hidden", "true");
|
||||
allTabsContainer.appendChild(this._allTabsBtn);
|
||||
|
||||
const menuPopup = this._panelDoc.createElementNS(XULNS, "menupopup");
|
||||
const menuPopup = this._panelDoc.createXULElement("menupopup");
|
||||
this._allTabsBtn.appendChild(menuPopup);
|
||||
|
||||
// Listening to tabs overflow event to toggle the alltabs button
|
||||
@ -189,7 +187,7 @@ ToolSidebar.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
const item = this._panelDoc.createElementNS(XULNS, "menuitem");
|
||||
const item = this._panelDoc.createXULElement("menuitem");
|
||||
const idPrefix = "sidebar-alltabs-item-";
|
||||
item.setAttribute("id", idPrefix + id);
|
||||
item.setAttribute("label", tab.getAttribute("label"));
|
||||
@ -230,14 +228,14 @@ ToolSidebar.prototype = {
|
||||
* tabbox, pass the ID of an existing tab to insert it before that tab instead.
|
||||
*/
|
||||
addTab: function(id, url, options = {}) {
|
||||
const iframe = this._panelDoc.createElementNS(XULNS, "iframe");
|
||||
const iframe = this._panelDoc.createXULElement("iframe");
|
||||
iframe.className = "iframe-" + id;
|
||||
iframe.setAttribute("flex", "1");
|
||||
iframe.setAttribute("src", url);
|
||||
iframe.tooltip = "aHTMLTooltip";
|
||||
|
||||
// Creating the tab and adding it to the tabbox
|
||||
const tab = this._panelDoc.createElementNS(XULNS, "tab");
|
||||
const tab = this._panelDoc.createXULElement("tab");
|
||||
|
||||
tab.setAttribute("id", this.TAB_ID_PREFIX + id);
|
||||
tab.setAttribute("crop", "end");
|
||||
@ -272,7 +270,7 @@ ToolSidebar.prototype = {
|
||||
|
||||
iframe.addEventListener("load", onIFrameLoaded, true);
|
||||
|
||||
const tabpanel = this._panelDoc.createElementNS(XULNS, "tabpanel");
|
||||
const tabpanel = this._panelDoc.createXULElement("tabpanel");
|
||||
tabpanel.setAttribute("id", this.TABPANEL_ID_PREFIX + id);
|
||||
tabpanel.appendChild(iframe);
|
||||
|
||||
@ -283,7 +281,7 @@ ToolSidebar.prototype = {
|
||||
this._tabbox.tabpanels.appendChild(tabpanel);
|
||||
}
|
||||
|
||||
this._tooltip = this._panelDoc.createElementNS(XULNS, "tooltip");
|
||||
this._tooltip = this._panelDoc.createXULElement("tooltip");
|
||||
this._tooltip.id = "aHTMLTooltip";
|
||||
tabpanel.appendChild(this._tooltip);
|
||||
this._tooltip.page = true;
|
||||
|
@ -10,12 +10,13 @@ const {
|
||||
TOGGLE_REQUEST_FILTER_TYPE,
|
||||
ENABLE_REQUEST_FILTER_TYPE_ONLY,
|
||||
SET_REQUEST_FILTER_TEXT,
|
||||
SELECT_DETAILS_PANEL_TAB,
|
||||
} = require("../constants");
|
||||
|
||||
/**
|
||||
* Event telemetry middleware is responsible for logging
|
||||
* specific filter events to telemetry. This telemetry
|
||||
* helps to track Net panel filtering usage.
|
||||
* various events to telemetry. This helps to track Network
|
||||
* panel usage.
|
||||
*/
|
||||
function eventTelemetryMiddleware(connector, telemetry) {
|
||||
return store => next => action => {
|
||||
@ -27,6 +28,7 @@ function eventTelemetryMiddleware(connector, telemetry) {
|
||||
}
|
||||
|
||||
const state = store.getState();
|
||||
const sessionId = toolbox.sessionId;
|
||||
|
||||
const filterChangeActions = [
|
||||
TOGGLE_REQUEST_FILTER_TYPE,
|
||||
@ -34,13 +36,25 @@ function eventTelemetryMiddleware(connector, telemetry) {
|
||||
SET_REQUEST_FILTER_TEXT,
|
||||
];
|
||||
|
||||
// Record telemetry event when filter changes.
|
||||
if (filterChangeActions.includes(action.type)) {
|
||||
filterChange({
|
||||
action,
|
||||
state,
|
||||
oldState,
|
||||
telemetry,
|
||||
sessionId: toolbox.sessionId,
|
||||
sessionId,
|
||||
});
|
||||
}
|
||||
|
||||
// Record telemetry event when side panel is selected.
|
||||
if (action.type == SELECT_DETAILS_PANEL_TAB) {
|
||||
sidePanelChange({
|
||||
action,
|
||||
state,
|
||||
oldState,
|
||||
telemetry,
|
||||
sessionId,
|
||||
});
|
||||
}
|
||||
|
||||
@ -48,6 +62,10 @@ function eventTelemetryMiddleware(connector, telemetry) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function is executed when filter related action is fired.
|
||||
* It's responsible for recording "filters_changed" telemetry event.
|
||||
*/
|
||||
function filterChange({action, state, oldState, telemetry, sessionId}) {
|
||||
const oldFilterState = oldState.filters;
|
||||
const filterState = state.filters;
|
||||
@ -79,7 +97,20 @@ function filterChange({action, state, oldState, telemetry, sessionId}) {
|
||||
"trigger": trigger,
|
||||
"active": activeFilters.join(","),
|
||||
"inactive": inactiveFilters.join(","),
|
||||
"session_id": sessionId
|
||||
"session_id": sessionId,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function is executed when side panel is selected.
|
||||
* It's responsible for recording "sidepanel_tool_changed"
|
||||
* telemetry event.
|
||||
*/
|
||||
function sidePanelChange({action, state, oldState, telemetry, sessionId}) {
|
||||
telemetry.recordEvent("devtools.main", "sidepanel_changed", "netmonitor", null, {
|
||||
"oldpanel": oldState.ui.detailsPanelSelectedTab,
|
||||
"newpanel": state.ui.detailsPanelSelectedTab,
|
||||
"session_id": sessionId,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -186,6 +186,7 @@ skip-if = true # Bug 1373558
|
||||
[browser_net_status-codes.js]
|
||||
[browser_net_streaming-response.js]
|
||||
[browser_net_telemetry_filters_changed.js]
|
||||
[browser_net_telemetry_sidepanel_changed.js]
|
||||
[browser_net_throttle.js]
|
||||
[browser_net_timeline_ticks.js]
|
||||
skip-if = true # TODO: fix the test
|
||||
|
@ -42,6 +42,8 @@ add_task(async function() {
|
||||
trigger: "html",
|
||||
active: "html",
|
||||
inactive: "all,css,js,xhr,fonts,images,media,ws,other",
|
||||
}, {
|
||||
method: "filters_changed"
|
||||
});
|
||||
|
||||
info("Click on the 'CSS' filter");
|
||||
@ -52,6 +54,8 @@ add_task(async function() {
|
||||
trigger: "css",
|
||||
active: "html,css",
|
||||
inactive: "all,js,xhr,fonts,images,media,ws,other",
|
||||
}, {
|
||||
method: "filters_changed"
|
||||
});
|
||||
|
||||
info("Filter the output using the text filter input");
|
||||
@ -64,6 +68,8 @@ add_task(async function() {
|
||||
trigger: "text",
|
||||
active: "html,css",
|
||||
inactive: "all,js,xhr,fonts,images,media,ws,other",
|
||||
}, {
|
||||
method: "filters_changed"
|
||||
});
|
||||
|
||||
return teardown(monitor);
|
||||
@ -80,30 +86,3 @@ function setFreetextFilter(monitor, value) {
|
||||
EventUtils.synthesizeKey(ch, {}, monitor.panelWin);
|
||||
}
|
||||
}
|
||||
|
||||
function checkTelemetryEvent(expectedEvent) {
|
||||
const events = getFiltersChangedEventsExtra();
|
||||
is(events.length, 1, "There was only 1 event logged");
|
||||
const [event] = events;
|
||||
ok(event.session_id > 0, "There is a valid session_id in the logged event");
|
||||
const f = e => JSON.stringify(e, null, 2);
|
||||
is(f(event), f({
|
||||
...expectedEvent,
|
||||
"session_id": event.session_id
|
||||
}), "The event has the expected data");
|
||||
}
|
||||
|
||||
function getFiltersChangedEventsExtra() {
|
||||
// Retrieve and clear telemetry events.
|
||||
const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
|
||||
|
||||
const filtersChangedEvents = snapshot.parent.filter(event =>
|
||||
event[1] === "devtools.main" &&
|
||||
event[2] === "filters_changed" &&
|
||||
event[3] === "netmonitor"
|
||||
);
|
||||
|
||||
// Since we already know we have the correct event, we only return the `extra` field
|
||||
// that was passed to it (which is event[5] here).
|
||||
return filtersChangedEvents.map(event => event[5]);
|
||||
}
|
||||
|
@ -0,0 +1,55 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
|
||||
|
||||
/**
|
||||
* Test the sidepanel_changed telemetry event.
|
||||
*/
|
||||
add_task(async function() {
|
||||
const { tab, monitor } = await initNetMonitor(SIMPLE_URL);
|
||||
info("Starting test... ");
|
||||
|
||||
const { document, store, windowRequire } = monitor.panelWin;
|
||||
const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
|
||||
store.dispatch(Actions.batchEnable(false));
|
||||
|
||||
// Remove all telemetry events (you can check about:telemetry).
|
||||
Services.telemetry.clearEvents();
|
||||
|
||||
// Ensure no events have been logged
|
||||
const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
|
||||
ok(!snapshot.parent, "No events have been logged for the main process");
|
||||
|
||||
// Reload to have one request in the list.
|
||||
const waitForEvents = waitForNetworkEvents(monitor, 1);
|
||||
tab.linkedBrowser.loadURI(SIMPLE_URL);
|
||||
await waitForEvents;
|
||||
|
||||
// Click on a request and wait till the default "Headers" side panel is opened.
|
||||
info("Click on a request");
|
||||
const waitForHeaders = waitUntil(() => document.querySelector(".headers-overview"));
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[0]);
|
||||
await waitForHeaders;
|
||||
await waitForRequestData(store, ["requestHeaders", "responseHeaders"]);
|
||||
|
||||
// Click on the Cookies panel and wait till it's opened.
|
||||
info("Click on the Cookies panel");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#cookies-tab"));
|
||||
await waitForRequestData(store, ["requestCookies", "responseCookies"]);
|
||||
|
||||
checkTelemetryEvent({
|
||||
oldpanel: "headers",
|
||||
newpanel: "cookies",
|
||||
}, {
|
||||
method: "sidepanel_changed"
|
||||
});
|
||||
|
||||
return teardown(monitor);
|
||||
});
|
@ -799,3 +799,42 @@ function waitForRequestData(store, fields, id) {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Telemetry
|
||||
|
||||
/**
|
||||
* Helper for verifying telemetry event.
|
||||
*
|
||||
* @param Object expectedEvent object representing expected event data.
|
||||
* @param Object query fields specifying category, method and object
|
||||
* of the target telemetry event.
|
||||
*/
|
||||
function checkTelemetryEvent(expectedEvent, query) {
|
||||
const events = queryTelemetryEvents(query);
|
||||
is(events.length, 1, "There was only 1 event logged");
|
||||
|
||||
const [event] = events;
|
||||
ok(event.session_id > 0, "There is a valid session_id in the logged event");
|
||||
|
||||
const f = e => JSON.stringify(e, null, 2);
|
||||
is(f(event), f({
|
||||
...expectedEvent,
|
||||
"session_id": event.session_id
|
||||
}), "The event has the expected data");
|
||||
}
|
||||
|
||||
function queryTelemetryEvents(query) {
|
||||
const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
|
||||
const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
|
||||
const category = query.category || "devtools.main";
|
||||
const object = query.object || "netmonitor";
|
||||
|
||||
const filtersChangedEvents = snapshot.parent.filter(event =>
|
||||
event[1] === category &&
|
||||
event[2] === query.method &&
|
||||
event[3] === object
|
||||
);
|
||||
|
||||
// Return the `extra` field (which is event[5]e).
|
||||
return filtersChangedEvents.map(event => event[5]);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ loader.lazyRequireGetter(this, "naturalSortCaseInsensitive",
|
||||
"devtools/client/shared/natural-sort", true);
|
||||
const {KeyCodes} = require("devtools/client/shared/keycodes");
|
||||
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
const AFTER_SCROLL_DELAY = 100;
|
||||
|
||||
@ -77,7 +76,7 @@ function TableWidget(node, options = {}) {
|
||||
this.removableColumns = removableColumns !== false;
|
||||
this.cellContextMenuId = cellContextMenuId;
|
||||
|
||||
this.tbody = this.document.createElementNS(XUL_NS, "hbox");
|
||||
this.tbody = this.document.createXULElement("hbox");
|
||||
this.tbody.className = "table-widget-body theme-body";
|
||||
this.tbody.setAttribute("flex", "1");
|
||||
this.tbody.setAttribute("tabindex", "0");
|
||||
@ -85,7 +84,7 @@ function TableWidget(node, options = {}) {
|
||||
this.afterScroll = this.afterScroll.bind(this);
|
||||
this.tbody.addEventListener("scroll", this.onScroll.bind(this));
|
||||
|
||||
this.placeholder = this.document.createElementNS(XUL_NS, "label");
|
||||
this.placeholder = this.document.createXULElement("label");
|
||||
this.placeholder.className = "plain table-widget-empty-text";
|
||||
this.placeholder.setAttribute("flex", "1");
|
||||
this._parent.appendChild(this.placeholder);
|
||||
@ -644,11 +643,11 @@ TableWidget.prototype = {
|
||||
setupHeadersContextMenu: function() {
|
||||
let popupset = this.document.getElementsByTagName("popupset")[0];
|
||||
if (!popupset) {
|
||||
popupset = this.document.createElementNS(XUL_NS, "popupset");
|
||||
popupset = this.document.createXULElement("popupset");
|
||||
this.document.documentElement.appendChild(popupset);
|
||||
}
|
||||
|
||||
this.menupopup = this.document.createElementNS(XUL_NS, "menupopup");
|
||||
this.menupopup = this.document.createXULElement("menupopup");
|
||||
this.menupopup.id = "table-widget-column-select";
|
||||
this.menupopup.addEventListener("command", this.onPopupCommand);
|
||||
popupset.appendChild(this.menupopup);
|
||||
@ -678,7 +677,7 @@ TableWidget.prototype = {
|
||||
continue;
|
||||
}
|
||||
|
||||
const menuitem = this.document.createElementNS(XUL_NS, "menuitem");
|
||||
const menuitem = this.document.createXULElement("menuitem");
|
||||
menuitem.setAttribute("label", column.header.getAttribute("value"));
|
||||
menuitem.setAttribute("data-id", column.id);
|
||||
menuitem.setAttribute("type", "checkbox");
|
||||
@ -1045,13 +1044,13 @@ function Column(table, id, header) {
|
||||
|
||||
// This wrapping element is required solely so that position:sticky works on
|
||||
// the headers of the columns.
|
||||
this.wrapper = this.document.createElementNS(XUL_NS, "vbox");
|
||||
this.wrapper = this.document.createXULElement("vbox");
|
||||
this.wrapper.className = "table-widget-wrapper";
|
||||
this.wrapper.setAttribute("flex", "1");
|
||||
this.wrapper.setAttribute("tabindex", "0");
|
||||
this.tbody.appendChild(this.wrapper);
|
||||
|
||||
this.splitter = this.document.createElementNS(XUL_NS, "splitter");
|
||||
this.splitter = this.document.createXULElement("splitter");
|
||||
this.splitter.className = "devtools-side-splitter";
|
||||
this.tbody.appendChild(this.splitter);
|
||||
|
||||
@ -1060,7 +1059,7 @@ function Column(table, id, header) {
|
||||
this.column.className = "table-widget-column";
|
||||
this.wrapper.appendChild(this.column);
|
||||
|
||||
this.header = this.document.createElementNS(XUL_NS, "label");
|
||||
this.header = this.document.createXULElement("label");
|
||||
this.header.className = "devtools-toolbar table-widget-column-header";
|
||||
this.header.setAttribute("value", header);
|
||||
this.column.appendChild(this.header);
|
||||
@ -1565,7 +1564,7 @@ function Cell(column, item, nextCell) {
|
||||
const document = column.document;
|
||||
|
||||
this.wrapTextInElements = column.wrapTextInElements;
|
||||
this.label = document.createElementNS(XUL_NS, "label");
|
||||
this.label = document.createXULElement("label");
|
||||
this.label.setAttribute("crop", "end");
|
||||
this.label.className = "plain table-widget-cell";
|
||||
|
||||
@ -1737,7 +1736,7 @@ EditableFieldsEngine.prototype = {
|
||||
get textbox() {
|
||||
if (!this._textbox) {
|
||||
const doc = this.root.ownerDocument;
|
||||
this._textbox = doc.createElementNS(XUL_NS, "textbox");
|
||||
this._textbox = doc.createXULElement("textbox");
|
||||
this._textbox.id = this.INPUT_ID;
|
||||
|
||||
this._textbox.setAttribute("flex", "1");
|
||||
|
@ -878,7 +878,7 @@ HTMLTooltip.prototype = {
|
||||
},
|
||||
|
||||
_createXulPanelWrapper: function() {
|
||||
const panel = this.doc.createElementNS(XUL_NS, "panel");
|
||||
const panel = this.doc.createXULElement("panel");
|
||||
|
||||
// XUL panel is only a way to display DOM elements outside of the document viewport,
|
||||
// so disable all features that impact the behavior.
|
||||
|
@ -1180,9 +1180,10 @@ WebConsoleActor.prototype =
|
||||
matches = result.matches || [];
|
||||
matchProp = result.matchProp;
|
||||
|
||||
// We consider '$' as alphanumerc because it is used in the names of some
|
||||
// helper functions.
|
||||
const lastNonAlphaIsDot = /[.][a-zA-Z0-9$]*$/.test(reqText);
|
||||
// We consider '$' as alphanumeric because it is used in the names of some
|
||||
// helper functions; we also consider whitespace as alphanum since it should not
|
||||
// be seen as break in the evaled string.
|
||||
const lastNonAlphaIsDot = /[.][a-zA-Z0-9$\s]*$/.test(reqText);
|
||||
if (!lastNonAlphaIsDot) {
|
||||
matches = matches.concat(this._getWebConsoleCommandsCache().filter(n =>
|
||||
// filter out `screenshot` command as it is inaccessible without
|
||||
|
@ -51,7 +51,7 @@ function hasArrayIndex(str) {
|
||||
*
|
||||
* {
|
||||
* state: STATE_NORMAL|STATE_QUOTE|STATE_DQUOTE,
|
||||
* startPos: index of where the last statement begins
|
||||
* lastStatement: the last statement in the string
|
||||
* }
|
||||
*/
|
||||
function findCompletionBeginning(str) {
|
||||
@ -60,8 +60,11 @@ function findCompletionBeginning(str) {
|
||||
let state = STATE_NORMAL;
|
||||
let start = 0;
|
||||
let c;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
c = str[i];
|
||||
|
||||
// Use an array in order to handle character with a length > 2 (e.g. 😎).
|
||||
const characters = Array.from(str);
|
||||
for (let i = 0; i < characters.length; i++) {
|
||||
c = characters[i];
|
||||
|
||||
switch (state) {
|
||||
// Normal JS state.
|
||||
@ -73,7 +76,33 @@ function findCompletionBeginning(str) {
|
||||
} else if (c == ";") {
|
||||
start = i + 1;
|
||||
} else if (c == " ") {
|
||||
start = i + 1;
|
||||
const before = characters.slice(0, i);
|
||||
const after = characters.slice(i + 1);
|
||||
const trimmedBefore = Array.from(before.join("").trimRight());
|
||||
const trimmedAfter = Array.from(after.join("").trimLeft());
|
||||
|
||||
const nextNonSpaceChar = trimmedAfter[0];
|
||||
const nextNonSpaceCharIndex = after.indexOf(nextNonSpaceChar);
|
||||
const previousNonSpaceChar = trimmedBefore[trimmedBefore.length - 1];
|
||||
|
||||
// If the previous meaningful char was a dot and there is no meaningful char
|
||||
// after, we can break out of the loop.
|
||||
if (previousNonSpaceChar === "." && !nextNonSpaceChar) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextNonSpaceChar) {
|
||||
// If the previous char wasn't a dot, and the next one isn't a dot either,
|
||||
// update the start pos.
|
||||
if (previousNonSpaceChar !== "." && nextNonSpaceChar !== ".") {
|
||||
start = i + nextNonSpaceCharIndex;
|
||||
}
|
||||
// Let's jump to handle the next non-space char.
|
||||
i = i + nextNonSpaceCharIndex;
|
||||
} else {
|
||||
// There's only spaces after that, so we can break out of the loop.
|
||||
break;
|
||||
}
|
||||
} else if (OPEN_BODY.includes(c)) {
|
||||
bodyStack.push({
|
||||
token: c,
|
||||
@ -125,7 +154,7 @@ function findCompletionBeginning(str) {
|
||||
|
||||
return {
|
||||
state: state,
|
||||
startPos: start
|
||||
lastStatement: characters.slice(start).join("")
|
||||
};
|
||||
}
|
||||
|
||||
@ -165,20 +194,20 @@ function JSPropertyProvider(dbgObject, anEnvironment, inputValue, cursor) {
|
||||
|
||||
// Analyse the inputValue and find the beginning of the last part that
|
||||
// should be completed.
|
||||
const beginning = findCompletionBeginning(inputValue);
|
||||
const {err, state, lastStatement} = findCompletionBeginning(inputValue);
|
||||
|
||||
// There was an error analysing the string.
|
||||
if (beginning.err) {
|
||||
if (err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If the current state is not STATE_NORMAL, then we are inside of an string
|
||||
// which means that no completion is possible.
|
||||
if (beginning.state != STATE_NORMAL) {
|
||||
if (state != STATE_NORMAL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const completionPart = inputValue.substring(beginning.startPos);
|
||||
const completionPart = lastStatement;
|
||||
const lastDot = completionPart.lastIndexOf(".");
|
||||
|
||||
// Don't complete on just an empty string.
|
||||
@ -201,7 +230,7 @@ function JSPropertyProvider(dbgObject, anEnvironment, inputValue, cursor) {
|
||||
// If there were parse errors this won't exist.
|
||||
if (lastBody) {
|
||||
const expression = lastBody.expression;
|
||||
const matchProp = completionPart.slice(lastDot + 1);
|
||||
const matchProp = completionPart.slice(lastDot + 1).trimLeft();
|
||||
if (expression.type === "ArrayExpression") {
|
||||
return getMatchedProps(Array.prototype, matchProp);
|
||||
} else if (expression.type === "Literal" &&
|
||||
|
@ -12,214 +12,236 @@
|
||||
<p>Test for JavaScript terminal autocomplete functionality</p>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
const {
|
||||
MAX_AUTOCOMPLETE_ATTEMPTS,
|
||||
MAX_AUTOCOMPLETIONS
|
||||
} = require("devtools/shared/webconsole/js-property-provider");
|
||||
|
||||
let gState;
|
||||
let {MAX_AUTOCOMPLETE_ATTEMPTS,MAX_AUTOCOMPLETIONS} = require("devtools/shared/webconsole/js-property-provider");
|
||||
addEventListener("load", startTest);
|
||||
|
||||
function evaluateJS(input, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
gState.client.evaluateJSAsync(input, resolve, options);
|
||||
});
|
||||
}
|
||||
async function startTest() {
|
||||
// First run the tests with a tab as a target.
|
||||
let state = await new Promise(resolve => attachConsoleToTab(["PageError"], resolve));
|
||||
await performTests({state, isWorker: false});
|
||||
|
||||
function autocompletePromise(str, cursor = str.length, frameActor) {
|
||||
return gState.client.autocomplete(str, cursor, frameActor);
|
||||
}
|
||||
// Then run the tests with a worker as a target.
|
||||
state = await new Promise(resolve => attachConsoleToWorker(["PageError"], resolve));
|
||||
await performTests({state, isWorker: true});
|
||||
|
||||
// This test runs all of its assertions twice - once with
|
||||
// the tab as a target and once with a worker
|
||||
let runningInTab = true;
|
||||
function startTest({worker}) {
|
||||
if (worker) {
|
||||
attachConsoleToWorker(["PageError"], onAttach.bind(null, true));
|
||||
} else {
|
||||
attachConsoleToTab(["PageError"], onAttach.bind(null, false));
|
||||
}
|
||||
};
|
||||
|
||||
let onAttach = async function (isWorker, aState, response) {
|
||||
gState = aState;
|
||||
|
||||
let longStrLength = DebuggerServer.LONG_STRING_LENGTH;
|
||||
|
||||
// Set up the global variables needed to test autocompletion
|
||||
// in the target.
|
||||
let script = `
|
||||
// This is for workers so autocomplete acts the same
|
||||
if (!this.window) {
|
||||
window = this;
|
||||
}
|
||||
|
||||
window.foobarObject = Object.create(null);
|
||||
window.foobarObject.foo = 1;
|
||||
window.foobarObject.foobar = 2;
|
||||
window.foobarObject.foobaz = 3;
|
||||
window.foobarObject.omg = 4;
|
||||
window.foobarObject.omgfoo = 5;
|
||||
window.foobarObject.strfoo = "foobarz";
|
||||
window.foobarObject.omgstr = "foobarz" +
|
||||
(new Array(${longStrLength})).join("abb");
|
||||
window.largeObject1 = Object.create(null);
|
||||
for (let i = 0; i < ${MAX_AUTOCOMPLETE_ATTEMPTS + 1}; i++) {
|
||||
window.largeObject1['a' + i] = i;
|
||||
}
|
||||
|
||||
window.largeObject2 = Object.create(null);
|
||||
for (let i = 0; i < ${MAX_AUTOCOMPLETIONS * 2}; i++) {
|
||||
window.largeObject2['a' + i] = i;
|
||||
}
|
||||
|
||||
window.proxy1 = new Proxy({foo: 1}, {
|
||||
getPrototypeOf() { throw new Error() }
|
||||
});
|
||||
window.proxy2 = new Proxy(Object.create(Object.create(null, {foo:{}})), {
|
||||
ownKeys() { throw new Error() }
|
||||
});
|
||||
`;
|
||||
|
||||
await evaluateJS(script);
|
||||
|
||||
let tests = [doAutocomplete1, doAutocomplete2, doAutocomplete3,
|
||||
doAutocomplete4, doAutocompleteLarge1,
|
||||
doAutocompleteLarge2, doAutocompleteProxyThrowsPrototype,
|
||||
doAutocompleteProxyThrowsOwnKeys];
|
||||
if (!isWorker) {
|
||||
// `Cu` is not defined in workers, then we can't test `Cu.Sandbox`
|
||||
tests.push(doAutocompleteSandbox);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
runTests(tests, testEnd);
|
||||
};
|
||||
async function performTests({state, isWorker}) {
|
||||
// Set up the global variables needed to test autocompletion in the target.
|
||||
const script = `
|
||||
// This is for workers so autocomplete acts the same
|
||||
if (!this.window) {
|
||||
window = this;
|
||||
}
|
||||
|
||||
async function doAutocomplete1() {
|
||||
info("test autocomplete for 'window.foo'");
|
||||
let response = await autocompletePromise("window.foo");
|
||||
let matches = response.matches;
|
||||
window.foobarObject = Object.create(null);
|
||||
window.foobarObject.foo = 1;
|
||||
window.foobarObject.foobar = 2;
|
||||
window.foobarObject.foobaz = 3;
|
||||
window.foobarObject.omg = 4;
|
||||
window.foobarObject.omgfoo = 5;
|
||||
window.foobarObject.strfoo = "foobarz";
|
||||
window.foobarObject.omgstr = "foobarz" +
|
||||
(new Array(${DebuggerServer.LONG_STRING_LENGTH})).join("abb");
|
||||
window.largeObject1 = Object.create(null);
|
||||
for (let i = 0; i < ${MAX_AUTOCOMPLETE_ATTEMPTS + 1}; i++) {
|
||||
window.largeObject1['a' + i] = i;
|
||||
}
|
||||
|
||||
is(response.matchProp, "foo", "matchProp");
|
||||
is(matches.length, 1, "matches.length");
|
||||
is(matches[0], "foobarObject", "matches[0]");
|
||||
window.largeObject2 = Object.create(null);
|
||||
for (let i = 0; i < ${MAX_AUTOCOMPLETIONS * 2}; i++) {
|
||||
window.largeObject2['a' + i] = i;
|
||||
}
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
async function doAutocomplete2() {
|
||||
info("test autocomplete for 'window.foobarObject.'");
|
||||
let response = await autocompletePromise("window.foobarObject.");
|
||||
let matches = response.matches;
|
||||
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(matches.length, 7, "matches.length");
|
||||
checkObject(matches,
|
||||
["foo", "foobar", "foobaz", "omg", "omgfoo", "omgstr", "strfoo"]);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
async function doAutocomplete3() {
|
||||
// Check that completion suggestions are offered inside the string.
|
||||
info("test autocomplete for 'dump(window.foobarObject.)'");
|
||||
let response = await autocompletePromise("dump(window.foobarObject.)", 25);
|
||||
let matches = response.matches;
|
||||
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(matches.length, 7, "matches.length");
|
||||
checkObject(matches,
|
||||
["foo", "foobar", "foobaz", "omg", "omgfoo", "omgstr", "strfoo"]);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
async function doAutocomplete4() {
|
||||
// Check that completion requests can have no suggestions.
|
||||
info("test autocomplete for 'dump(window.foobarObject.)'");
|
||||
let response = await autocompletePromise("dump(window.foobarObject.)");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(response.matches.length, 0, "matches.length");
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
async function doAutocompleteLarge1() {
|
||||
// Check that completion requests with too large objects will
|
||||
// have no suggestions.
|
||||
info("test autocomplete for 'window.largeObject1.'");
|
||||
let response = await autocompletePromise("window.largeObject1.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
info (response.matches.join("|"));
|
||||
is(response.matches.length, 0, "Bailed out with too many properties");
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
async function doAutocompleteLarge2() {
|
||||
// Check that completion requests with pretty large objects will
|
||||
// have MAX_AUTOCOMPLETIONS suggestions
|
||||
info("test autocomplete for 'window.largeObject2.'");
|
||||
let response = await autocompletePromise("window.largeObject2.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(response.matches.length, MAX_AUTOCOMPLETIONS, "matches.length is MAX_AUTOCOMPLETIONS");
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
async function doAutocompleteProxyThrowsPrototype() {
|
||||
// Check that completion provides own properties even if [[GetPrototypeOf]] throws.
|
||||
info("test autocomplete for 'window.proxy1.'");
|
||||
let response = await autocompletePromise("window.proxy1.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(response.matches.length, 1, "matches.length");
|
||||
checkObject(response.matches, ["foo"]);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
async function doAutocompleteProxyThrowsOwnKeys() {
|
||||
// Check that completion provides inherited properties even if [[OwnPropertyKeys]] throws.
|
||||
info("test autocomplete for 'window.proxy2.'");
|
||||
let response = await autocompletePromise("window.proxy2.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(response.matches.length, 1, "matches.length");
|
||||
checkObject(response.matches, ["foo"]);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
async function doAutocompleteSandbox() {
|
||||
// Check that completion provides inherited properties even if [[OwnPropertyKeys]] throws.
|
||||
info("test autocomplete for 'Cu.Sandbox.'");
|
||||
let response = await autocompletePromise("Cu.Sandbox.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
let keys = Object.getOwnPropertyNames(Object.prototype).sort();
|
||||
is(response.matches.length, keys.length, "matches.length");
|
||||
checkObject(response.matches, keys);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function testEnd()
|
||||
{
|
||||
// If this is the first run, reload the page and do it again
|
||||
// in a worker. Otherwise, end the test.
|
||||
closeDebugger(gState, function() {
|
||||
gState = null;
|
||||
if (runningInTab) {
|
||||
runningInTab = false;
|
||||
startTest({
|
||||
worker: true
|
||||
window.proxy1 = new Proxy({foo: 1}, {
|
||||
getPrototypeOf() { throw new Error() }
|
||||
});
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
window.proxy2 = new Proxy(Object.create(Object.create(null, {foo:{}})), {
|
||||
ownKeys() { throw new Error() }
|
||||
});
|
||||
window.emojiObject = Object.create(null);
|
||||
window.emojiObject["😎"] = "😎";
|
||||
`;
|
||||
await state.client.evaluateJSAsync(script);
|
||||
|
||||
addEventListener("load", () => {
|
||||
startTest({
|
||||
worker: false
|
||||
});
|
||||
});
|
||||
const tests = [
|
||||
doAutocomplete1,
|
||||
doAutocomplete2,
|
||||
doAutocomplete3,
|
||||
doAutocomplete4,
|
||||
doAutocompleteLarge1,
|
||||
doAutocompleteLarge2,
|
||||
doAutocompleteProxyThrowsPrototype,
|
||||
doAutocompleteProxyThrowsOwnKeys,
|
||||
doAutocompleteDotSurroundedBySpaces,
|
||||
doAutocompleteAfterOr,
|
||||
];
|
||||
|
||||
if (!isWorker) {
|
||||
// `Cu` is not defined in workers, then we can't test `Cu.Sandbox`
|
||||
tests.push(doAutocompleteSandbox);
|
||||
// Array literal completion isn't handled in Workers yet.
|
||||
tests.push(doAutocompleteArray);
|
||||
}
|
||||
|
||||
for (const test of tests) {
|
||||
await test(state.client);
|
||||
}
|
||||
|
||||
await closeDebugger(state);
|
||||
}
|
||||
|
||||
async function doAutocomplete1(client) {
|
||||
info("test autocomplete for 'window.foo'");
|
||||
let response = await client.autocomplete("window.foo");
|
||||
let matches = response.matches;
|
||||
|
||||
is(response.matchProp, "foo", "matchProp");
|
||||
is(matches.length, 1, "matches.length");
|
||||
is(matches[0], "foobarObject", "matches[0]");
|
||||
}
|
||||
|
||||
async function doAutocomplete2(client) {
|
||||
info("test autocomplete for 'window.foobarObject.'");
|
||||
let response = await client.autocomplete("window.foobarObject.");
|
||||
let matches = response.matches;
|
||||
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(matches.length, 7, "matches.length");
|
||||
checkObject(matches,
|
||||
["foo", "foobar", "foobaz", "omg", "omgfoo", "omgstr", "strfoo"]);
|
||||
}
|
||||
|
||||
async function doAutocomplete3(client) {
|
||||
// Check that completion suggestions are offered inside the string.
|
||||
info("test autocomplete for 'dump(window.foobarObject.)'");
|
||||
let response = await client.autocomplete("dump(window.foobarObject.)", 25);
|
||||
let matches = response.matches;
|
||||
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(matches.length, 7, "matches.length");
|
||||
checkObject(matches,
|
||||
["foo", "foobar", "foobaz", "omg", "omgfoo", "omgstr", "strfoo"]);
|
||||
}
|
||||
|
||||
async function doAutocomplete4(client) {
|
||||
// Check that completion requests can have no suggestions.
|
||||
info("test autocomplete for 'dump(window.foobarObject.)'");
|
||||
let response = await client.autocomplete("dump(window.foobarObject.)");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(response.matches.length, 0, "matches.length");
|
||||
}
|
||||
|
||||
async function doAutocompleteLarge1(client) {
|
||||
// Check that completion requests with too large objects will
|
||||
// have no suggestions.
|
||||
info("test autocomplete for 'window.largeObject1.'");
|
||||
let response = await client.autocomplete("window.largeObject1.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
info (response.matches.join("|"));
|
||||
is(response.matches.length, 0, "Bailed out with too many properties");
|
||||
}
|
||||
|
||||
async function doAutocompleteLarge2(client) {
|
||||
// Check that completion requests with pretty large objects will
|
||||
// have MAX_AUTOCOMPLETIONS suggestions
|
||||
info("test autocomplete for 'window.largeObject2.'");
|
||||
let response = await client.autocomplete("window.largeObject2.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(response.matches.length, MAX_AUTOCOMPLETIONS, "matches.length is MAX_AUTOCOMPLETIONS");
|
||||
}
|
||||
|
||||
async function doAutocompleteProxyThrowsPrototype(client) {
|
||||
// Check that completion provides own properties even if [[GetPrototypeOf]] throws.
|
||||
info("test autocomplete for 'window.proxy1.'");
|
||||
let response = await client.autocomplete("window.proxy1.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(response.matches.length, 1, "matches.length");
|
||||
checkObject(response.matches, ["foo"]);
|
||||
}
|
||||
|
||||
async function doAutocompleteProxyThrowsOwnKeys(client) {
|
||||
// Check that completion provides inherited properties even if [[OwnPropertyKeys]] throws.
|
||||
info("test autocomplete for 'window.proxy2.'");
|
||||
let response = await client.autocomplete("window.proxy2.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
is(response.matches.length, 1, "matches.length");
|
||||
checkObject(response.matches, ["foo"]);
|
||||
}
|
||||
|
||||
async function doAutocompleteSandbox(client) {
|
||||
// Check that completion provides inherited properties even if [[OwnPropertyKeys]] throws.
|
||||
info("test autocomplete for 'Cu.Sandbox.'");
|
||||
let response = await client.autocomplete("Cu.Sandbox.");
|
||||
ok(!response.matchProp, "matchProp");
|
||||
let keys = Object.getOwnPropertyNames(Object.prototype).sort();
|
||||
is(response.matches.length, keys.length, "matches.length");
|
||||
checkObject(response.matches, keys);
|
||||
}
|
||||
|
||||
async function doAutocompleteArray(client) {
|
||||
info("test autocomplete for [1,2,3]");
|
||||
let response = await client.autocomplete("[1,2,3].");
|
||||
let {matches} = response;
|
||||
|
||||
ok(matches.length > 0, "There are completion results for the array");
|
||||
ok(matches.includes("length") && matches.includes("filter"),
|
||||
"Array autocomplete contains expected results");
|
||||
|
||||
info("test autocomplete for '[] . '");
|
||||
matches = (await client.autocomplete("[] . ")).matches;
|
||||
ok(matches.length > 1);
|
||||
ok(matches.includes("length") && matches.includes("filter"),
|
||||
"Array autocomplete contains expected results");
|
||||
ok(!matches.includes("copy"), "Array autocomplete does not contain helpers");
|
||||
}
|
||||
|
||||
async function doAutocompleteDotSurroundedBySpaces(client) {
|
||||
info("test autocomplete for 'window.foobarObject\n .'");
|
||||
let {matches} = await client.autocomplete("window.foobarObject\n .");
|
||||
is(matches.length, 7);
|
||||
checkObject(matches,
|
||||
["foo", "foobar", "foobaz", "omg", "omgfoo", "omgstr", "strfoo"]);
|
||||
|
||||
info("test autocomplete for 'window.foobarObject\n .o'");
|
||||
matches = (await client.autocomplete("window.foobarObject\n .o")).matches;
|
||||
is(matches.length, 3);
|
||||
checkObject(matches, ["omg", "omgfoo", "omgstr"]);
|
||||
|
||||
info("test autocomplete for 'window.foobarObject\n .\n s'");
|
||||
matches = (await client.autocomplete("window.foobarObject\n .\n s")).matches;
|
||||
is(matches.length, 1);
|
||||
checkObject(matches, ["strfoo"]);
|
||||
|
||||
info("test autocomplete for 'window.foobarObject\n . '");
|
||||
matches = (await client.autocomplete("window.foobarObject\n . ")).matches;
|
||||
is(matches.length, 7);
|
||||
checkObject(matches,
|
||||
["foo", "foobar", "foobaz", "omg", "omgfoo", "omgstr", "strfoo"]);
|
||||
|
||||
matches =
|
||||
(await client.autocomplete("window.foobarObject. foo ; window.foo")).matches;
|
||||
is(matches.length, 1);
|
||||
checkObject(matches, ["foobarObject"]);
|
||||
|
||||
matches =
|
||||
(await client.autocomplete("window.emojiObject . ")).matches;
|
||||
is(matches.length, 1);
|
||||
checkObject(matches, ["😎"]);
|
||||
}
|
||||
|
||||
async function doAutocompleteAfterOr(client) {
|
||||
info("test autocomplete for 'true || foo'");
|
||||
const {matches} = await client.autocomplete("true || foobar");
|
||||
is(matches.length, 1, "autocomplete returns expected results");
|
||||
is(matches.join("-"), "foobarObject");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2362,13 +2362,20 @@ nsRange::CloneParentsBetween(nsINode *aAncestor,
|
||||
if (aAncestor == aNode)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsINode> firstParent, lastParent;
|
||||
nsCOMPtr<nsINode> parent = aNode->GetParentNode();
|
||||
AutoTArray<nsCOMPtr<nsINode>, 16> parentStack;
|
||||
|
||||
nsCOMPtr<nsINode> parent = aNode->GetParentNode();
|
||||
while(parent && parent != aAncestor)
|
||||
{
|
||||
parentStack.AppendElement(parent);
|
||||
parent = parent->GetParentNode();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> firstParent;
|
||||
nsCOMPtr<nsINode> lastParent;
|
||||
for (int32_t i = parentStack.Length() - 1; i >= 0; i--) {
|
||||
ErrorResult rv;
|
||||
nsCOMPtr<nsINode> clone = parent->CloneNode(false, rv);
|
||||
nsCOMPtr<nsINode> clone = parentStack[i]->CloneNode(false, rv);
|
||||
|
||||
if (rv.Failed()) {
|
||||
return rv.StealNSResult();
|
||||
@ -2377,23 +2384,20 @@ nsRange::CloneParentsBetween(nsINode *aAncestor,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (! firstParent) {
|
||||
firstParent = lastParent = clone;
|
||||
} else {
|
||||
clone->AppendChild(*lastParent, rv);
|
||||
if (rv.Failed()) return rv.StealNSResult();
|
||||
|
||||
if (!lastParent) {
|
||||
lastParent = clone;
|
||||
} else {
|
||||
firstParent->AppendChild(*clone, rv);
|
||||
if (rv.Failed()) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
}
|
||||
|
||||
parent = parent->GetParentNode();
|
||||
firstParent = clone;
|
||||
}
|
||||
|
||||
*aClosestAncestor = firstParent;
|
||||
NS_IF_ADDREF(*aClosestAncestor);
|
||||
|
||||
*aFarthestAncestor = lastParent;
|
||||
NS_IF_ADDREF(*aFarthestAncestor);
|
||||
firstParent.forget(aClosestAncestor);
|
||||
lastParent.forget(aFarthestAncestor);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -848,6 +848,7 @@ ParserBase::ParserBase(JSContext* cx, LifoAlloc& alloc,
|
||||
#endif
|
||||
isUnexpectedEOF_(false),
|
||||
awaitHandling_(AwaitIsName),
|
||||
inParametersOfAsyncFunction_(false),
|
||||
parseGoal_(uint8_t(parseGoal))
|
||||
{
|
||||
cx->frontendCollectionPool().addActiveCompilation();
|
||||
@ -932,6 +933,29 @@ GeneralParser<ParseHandler, CharT>::setAwaitHandling(AwaitHandling awaitHandling
|
||||
asFinalParser()->setAwaitHandling(awaitHandling);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
void
|
||||
Parser<SyntaxParseHandler, CharT>::setInParametersOfAsyncFunction(bool inParameters)
|
||||
{
|
||||
this->inParametersOfAsyncFunction_ = inParameters;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
void
|
||||
Parser<FullParseHandler, CharT>::setInParametersOfAsyncFunction(bool inParameters)
|
||||
{
|
||||
this->inParametersOfAsyncFunction_ = inParameters;
|
||||
if (SyntaxParser* syntaxParser = getSyntaxParser())
|
||||
syntaxParser->setInParametersOfAsyncFunction(inParameters);
|
||||
}
|
||||
|
||||
template <class ParseHandler, typename CharT>
|
||||
inline void
|
||||
GeneralParser<ParseHandler, CharT>::setInParametersOfAsyncFunction(bool inParameters)
|
||||
{
|
||||
asFinalParser()->setInParametersOfAsyncFunction(inParameters);
|
||||
}
|
||||
|
||||
ObjectBox*
|
||||
ParserBase::newObjectBox(JSObject* obj)
|
||||
{
|
||||
@ -3822,6 +3846,7 @@ GeneralParser<ParseHandler, CharT>::functionFormalParametersAndBody(InHandling i
|
||||
? AwaitIsKeyword
|
||||
: AwaitIsName;
|
||||
AutoAwaitIsKeyword<ParseHandler, CharT> awaitIsKeyword(this, awaitHandling);
|
||||
AutoInParametersOfAsyncFunction<ParseHandler, CharT> inParameters(this, funbox->isAsync());
|
||||
if (!functionArguments(yieldHandling, kind, *pn))
|
||||
return false;
|
||||
}
|
||||
@ -3883,6 +3908,7 @@ GeneralParser<ParseHandler, CharT>::functionFormalParametersAndBody(InHandling i
|
||||
Node body;
|
||||
{
|
||||
AutoAwaitIsKeyword<ParseHandler, CharT> awaitIsKeyword(this, bodyAwaitHandling);
|
||||
AutoInParametersOfAsyncFunction<ParseHandler, CharT> inParameters(this, false);
|
||||
body = functionBody(inHandling, bodyYieldHandling, kind, bodyType);
|
||||
if (!body)
|
||||
return false;
|
||||
@ -8586,6 +8612,10 @@ GeneralParser<ParseHandler, CharT>::unaryExpr(YieldHandling yieldHandling,
|
||||
|
||||
case TokenKind::Await: {
|
||||
if (pc->isAsync()) {
|
||||
if (inParametersOfAsyncFunction()) {
|
||||
error(JSMSG_AWAIT_IN_DEFAULT);
|
||||
return null();
|
||||
}
|
||||
Node kid = unaryExpr(yieldHandling, tripledotHandling, possibleError, invoked);
|
||||
if (!kid)
|
||||
return null();
|
||||
|
@ -249,6 +249,9 @@ enum AwaitHandling : uint8_t { AwaitIsName, AwaitIsKeyword, AwaitIsModuleKeyword
|
||||
template <class ParseHandler, typename CharT>
|
||||
class AutoAwaitIsKeyword;
|
||||
|
||||
template <class ParseHandler, typename CharT>
|
||||
class AutoInParametersOfAsyncFunction;
|
||||
|
||||
class MOZ_STACK_CLASS ParserBase
|
||||
: public StrictModeGetter,
|
||||
private JS::AutoGCRooter
|
||||
@ -297,6 +300,8 @@ class MOZ_STACK_CLASS ParserBase
|
||||
|
||||
/* AwaitHandling */ uint8_t awaitHandling_:2;
|
||||
|
||||
bool inParametersOfAsyncFunction_:1;
|
||||
|
||||
/* ParseGoal */ uint8_t parseGoal_:1;
|
||||
|
||||
public:
|
||||
@ -304,11 +309,16 @@ class MOZ_STACK_CLASS ParserBase
|
||||
return awaitHandling_ != AwaitIsName;
|
||||
}
|
||||
|
||||
bool inParametersOfAsyncFunction() const {
|
||||
return inParametersOfAsyncFunction_;
|
||||
}
|
||||
|
||||
ParseGoal parseGoal() const {
|
||||
return ParseGoal(parseGoal_);
|
||||
}
|
||||
|
||||
template<class, typename> friend class AutoAwaitIsKeyword;
|
||||
template<class, typename> friend class AutoInParametersOfAsyncFunction;
|
||||
|
||||
ParserBase(JSContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
|
||||
bool foldConstants, UsedNameTracker& usedNames,
|
||||
@ -690,6 +700,7 @@ class MOZ_STACK_CLASS GeneralParser
|
||||
|
||||
using Base::alloc;
|
||||
using Base::awaitIsKeyword;
|
||||
using Base::inParametersOfAsyncFunction;
|
||||
using Base::parseGoal;
|
||||
#if DEBUG
|
||||
using Base::checkOptionsCalled;
|
||||
@ -896,6 +907,7 @@ class MOZ_STACK_CLASS GeneralParser
|
||||
ParseGoal parseGoal);
|
||||
|
||||
inline void setAwaitHandling(AwaitHandling awaitHandling);
|
||||
inline void setInParametersOfAsyncFunction(bool inParameters);
|
||||
|
||||
/*
|
||||
* Parse a top-level JS script.
|
||||
@ -1355,6 +1367,7 @@ class MOZ_STACK_CLASS Parser<SyntaxParseHandler, CharT> final
|
||||
// Functions present in both Parser<ParseHandler, CharT> specializations.
|
||||
|
||||
inline void setAwaitHandling(AwaitHandling awaitHandling);
|
||||
inline void setInParametersOfAsyncFunction(bool inParameters);
|
||||
|
||||
Node newRegExp();
|
||||
|
||||
@ -1473,6 +1486,9 @@ class MOZ_STACK_CLASS Parser<FullParseHandler, CharT> final
|
||||
friend class AutoAwaitIsKeyword<SyntaxParseHandler, CharT>;
|
||||
inline void setAwaitHandling(AwaitHandling awaitHandling);
|
||||
|
||||
friend class AutoInParametersOfAsyncFunction<SyntaxParseHandler, CharT>;
|
||||
inline void setInParametersOfAsyncFunction(bool inParameters);
|
||||
|
||||
Node newRegExp();
|
||||
|
||||
// Parse a module.
|
||||
@ -1612,6 +1628,27 @@ class MOZ_STACK_CLASS AutoAwaitIsKeyword
|
||||
}
|
||||
};
|
||||
|
||||
template <class ParseHandler, typename CharT>
|
||||
class MOZ_STACK_CLASS AutoInParametersOfAsyncFunction
|
||||
{
|
||||
using GeneralParser = frontend::GeneralParser<ParseHandler, CharT>;
|
||||
|
||||
private:
|
||||
GeneralParser* parser_;
|
||||
bool oldInParametersOfAsyncFunction_;
|
||||
|
||||
public:
|
||||
AutoInParametersOfAsyncFunction(GeneralParser* parser, bool inParameters) {
|
||||
parser_ = parser;
|
||||
oldInParametersOfAsyncFunction_ = parser_->inParametersOfAsyncFunction_;
|
||||
parser_->setInParametersOfAsyncFunction(inParameters);
|
||||
}
|
||||
|
||||
~AutoInParametersOfAsyncFunction() {
|
||||
parser_->setInParametersOfAsyncFunction(oldInParametersOfAsyncFunction_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Scope>
|
||||
extern typename Scope::Data*
|
||||
NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, uint32_t numBindings);
|
||||
|
@ -0,0 +1,67 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
* Contributor:
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 1478910;
|
||||
var summary = 'JSMSG_AWAIT_IN_DEFAULT error for incomplete await expr in async function/generator parameter';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus(summary);
|
||||
|
||||
let testAwaitInDefaultExprOfAsyncFunc = (code) => {
|
||||
assertThrowsInstanceOf(() => eval(code), SyntaxError, "await can't be used in default expression");
|
||||
};
|
||||
|
||||
let testNoException = (code) => {
|
||||
assertEq(completesNormally(code), true);
|
||||
};
|
||||
|
||||
// https://www.ecma-international.org/ecma-262/9.0/
|
||||
|
||||
// Async Generator Function Definitions : AsyncGeneratorDeclaration & AsyncGeneratorExpression
|
||||
// async function* f() {}
|
||||
// f = async function*() {}
|
||||
testAwaitInDefaultExprOfAsyncFunc("async function* f(a = await) {}");
|
||||
testAwaitInDefaultExprOfAsyncFunc("let f = async function*(a = await) {}");
|
||||
|
||||
testAwaitInDefaultExprOfAsyncFunc("function f(a = async function*(a = await) {}) {}");
|
||||
testAwaitInDefaultExprOfAsyncFunc("function f() { a = async function*(a = await) {}; }");
|
||||
|
||||
testAwaitInDefaultExprOfAsyncFunc("async function* f() { a = async function*(a = await) {}; }");
|
||||
testNoException("async function* f() { let a = function(a = await) {}; }");
|
||||
|
||||
testNoException("async function* f(a = async function*() { await 1; }) {}");
|
||||
|
||||
// Async Function Definitions : AsyncFunctionDeclaration & AsyncFunctionExpression
|
||||
// async function f() {}
|
||||
// f = async function() {}
|
||||
testAwaitInDefaultExprOfAsyncFunc("async function f(a = await) {}");
|
||||
testAwaitInDefaultExprOfAsyncFunc("let f = async function(a = await) {}");
|
||||
|
||||
testAwaitInDefaultExprOfAsyncFunc("function f(a = async function(a = await) {}) {}");
|
||||
testAwaitInDefaultExprOfAsyncFunc("function f() { a = async function(a = await) {}; }");
|
||||
|
||||
testAwaitInDefaultExprOfAsyncFunc("async function f() { a = async function(a = await) {}; }");
|
||||
testNoException("async function f() { let a = function(a = await) {}; }");
|
||||
|
||||
testNoException("async function f(a = async function() { await 1; }) {}");
|
||||
|
||||
// Async Arrow Function Definitions : AsyncArrowFunction
|
||||
// async () => {}
|
||||
testAwaitInDefaultExprOfAsyncFunc("async (a = await) => {}");
|
||||
|
||||
testNoException("async (a = async () => { await 1; }) => {}");
|
||||
|
||||
reportCompare(true, true, summary);
|
||||
}
|
@ -1685,7 +1685,7 @@ fuzzy-if(skiaContent,0-1,0-65536) == 654950-1.html 654950-1-ref.html # Quartz al
|
||||
!= 656875.html about:blank
|
||||
== 658952.html 658952-ref.html
|
||||
fuzzy-if(skiaContent,0-10,0-919) fuzzy-if(webrender&&cocoaWidget,54-54,831-831) == 660682-1.html 660682-1-ref.html
|
||||
pref(layout.css.xul-tree-pseudos.content.enabled,true) fuzzy-if(d2d,0-1,0-256) skip-if(Android) fuzzy-if(skiaContent,0-1,0-68000) fuzzy-if(webrender&&cocoaWidget,2-2,256-256) == 664127-1.xul 664127-1-ref.xul # Android: Intermittent failures - bug 1019131
|
||||
pref(layout.css.xul-tree-pseudos.content.enabled,true) fuzzy-if(d2d,0-1,0-256) skip-if(Android) fuzzy-if(skiaContent,0-1,0-68000) == 664127-1.xul 664127-1-ref.xul # Android: Intermittent failures - bug 1019131
|
||||
== 665597-1.html 665597-1-ref.html
|
||||
== 665597-2.html 665597-2-ref.html
|
||||
== 667079-1.html 667079-1-ref.html
|
||||
|
@ -7,7 +7,7 @@ random-if(Android) == menulist-shrinkwrap-2.xul menulist-shrinkwrap-2-ref.xul
|
||||
== textbox-overflow-1.xul textbox-overflow-1-ref.xul # for bug 749658
|
||||
# accesskeys are not normally displayed on Mac, so skip this test
|
||||
skip-if(cocoaWidget) == accesskey.xul accesskey-ref.xul
|
||||
pref(layout.css.xul-tree-pseudos.content.enabled,true) fails-if(cocoaWidget) fuzzy-if(xulRuntime.widgetToolkit=="gtk3",0-1,0-11) == tree-row-outline-1.xul tree-row-outline-1-ref.xul # win8: bug 1254832
|
||||
pref(layout.css.xul-tree-pseudos.content.enabled,true) fuzzy-if(xulRuntime.widgetToolkit=="gtk3",0-1,0-11) == tree-row-outline-1.xul tree-row-outline-1-ref.xul # win8: bug 1254832
|
||||
skip-if(!cocoaWidget) fails-if(webrender&&cocoaWidget) == mac-tab-toolbar.xul mac-tab-toolbar-ref.xul
|
||||
pref(layout.css.xul-tree-pseudos.content.enabled,true) != tree-row-outline-1.xul tree-row-outline-1-notref.xul
|
||||
== text-crop.xul text-crop-ref.xul
|
||||
|
@ -16,5 +16,52 @@
|
||||
// bug 1338260, directv.com
|
||||
"directv.com": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
// bug 1385206, rakuten.co.jp
|
||||
"rakuten.co.jp": "Firefox.+$#"
|
||||
"rakuten.co.jp": "Firefox.+$#",
|
||||
// bug 1483233, ebay.com, m.ebay.com, and localized versions
|
||||
"ebay.at": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.at": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.be": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.be": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.ca": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.ca": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.ch": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.ch": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.cn": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.cn": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.co.th": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.co.th": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.co.uk": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.co.uk": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.com": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.com": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.com.au": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.com.au": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.com.hk": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.com.hk": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.com.my": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.com.my": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.com.sg": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.com.sg": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.com.tw": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.com.tw": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.de": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.de": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.es": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.es": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.fr": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.fr": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.ie": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.ie": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.in": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.in": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.it": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.it": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.nl": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.nl": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.ph": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.ph": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.pl": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.pl": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"ebay.vn": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
|
||||
"m.ebay.vn": "Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36"
|
||||
}
|
||||
|
@ -418,7 +418,7 @@ public class GeckoMediaControlAgent {
|
||||
|
||||
if (!AppConstants.Versions.preO) {
|
||||
notificationBuilder.setChannelId(NotificationHelper.getInstance(mContext)
|
||||
.getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
|
||||
.getNotificationChannel(NotificationHelper.Channel.MEDIA).getId());
|
||||
}
|
||||
|
||||
return notificationBuilder.build();
|
||||
|
@ -97,7 +97,11 @@ public final class NotificationHelper implements BundleEventListener {
|
||||
/**
|
||||
* Mozilla Location Services notification channel.
|
||||
*/
|
||||
DOWNLOAD
|
||||
DOWNLOAD,
|
||||
/**
|
||||
* Media notification channel
|
||||
*/
|
||||
MEDIA
|
||||
}
|
||||
|
||||
private final Map<Channel, String> mDefinedNotificationChannels = new HashMap<Channel, String>() {{
|
||||
@ -109,6 +113,10 @@ public final class NotificationHelper implements BundleEventListener {
|
||||
|
||||
final String DOWNLOAD_NOTIFICATION_TAG = "download-notification-channel";
|
||||
put(Channel.DOWNLOAD, DOWNLOAD_NOTIFICATION_TAG);
|
||||
|
||||
|
||||
final String MEDIA_CHANNEL_TAG = "media-notification-channel";
|
||||
put(Channel.MEDIA, MEDIA_CHANNEL_TAG);
|
||||
}};
|
||||
|
||||
// Holds a list of notifications that should be cleared if the Fennec Activity is shut down.
|
||||
@ -176,6 +184,12 @@ public final class NotificationHelper implements BundleEventListener {
|
||||
}
|
||||
break;
|
||||
|
||||
case MEDIA: {
|
||||
channel = new NotificationChannel(mDefinedNotificationChannels.get(definedChannel),
|
||||
mContext.getString(R.string.media_notification_channel), NotificationManager.IMPORTANCE_LOW);
|
||||
}
|
||||
break;
|
||||
|
||||
case DEFAULT:
|
||||
|
||||
default: {
|
||||
|
@ -897,4 +897,5 @@ Picture-in-picture mini window -->
|
||||
<!-- Notification channels names -->
|
||||
<!ENTITY default_notification_channel "&brandShortName;">
|
||||
<!ENTITY mls_notification_channel "&vendorShortName; Location Service">
|
||||
<!ENTITY download_notification_channel "Downloads">
|
||||
<!ENTITY download_notification_channel "Downloads">
|
||||
<!ENTITY media_notification_channel "Media playback">
|
@ -650,5 +650,6 @@
|
||||
|
||||
<string name="default_notification_channel">&default_notification_channel;</string>
|
||||
<string name="mls_notification_channel">&mls_notification_channel;</string>
|
||||
<string name="media_notification_channel">&media_notification_channel;</string>
|
||||
<string name="download_notification_channel">&download_notification_channel;</string>
|
||||
</resources>
|
||||
|
@ -10,7 +10,10 @@ export AR="$topsrcdir/clang/bin/llvm-ar"
|
||||
export NM="$topsrcdir/clang/bin/llvm-nm"
|
||||
export RANLIB="$topsrcdir/clang/bin/llvm-ranlib"
|
||||
|
||||
ac_add_options --enable-lto
|
||||
# Enable LTO if the NDK is available.
|
||||
if [ -z "$NO_NDK" ]; then
|
||||
ac_add_options --enable-lto
|
||||
fi
|
||||
|
||||
export MOZILLA_OFFICIAL=1
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
@ -20,6 +20,9 @@ export AR="$topsrcdir/clang/bin/llvm-ar"
|
||||
export NM="$topsrcdir/clang/bin/llvm-nm"
|
||||
export RANLIB="$topsrcdir/clang/bin/llvm-ranlib"
|
||||
|
||||
ac_add_options --enable-lto
|
||||
# Enable LTO if the NDK is available.
|
||||
if [ -z "$NO_NDK" ]; then
|
||||
ac_add_options --enable-lto
|
||||
fi
|
||||
|
||||
. "$topsrcdir/mobile/android/config/mozconfigs/common.override"
|
||||
|
@ -18,6 +18,9 @@ export AR="$topsrcdir/clang/bin/llvm-ar"
|
||||
export NM="$topsrcdir/clang/bin/llvm-nm"
|
||||
export RANLIB="$topsrcdir/clang/bin/llvm-ranlib"
|
||||
|
||||
ac_add_options --enable-lto
|
||||
# Enable LTO if the NDK is available.
|
||||
if [ -z "$NO_NDK" ]; then
|
||||
ac_add_options --enable-lto
|
||||
fi
|
||||
|
||||
. "$topsrcdir/mobile/android/config/mozconfigs/common.override"
|
||||
|
@ -42,30 +42,32 @@ const CACHE_LINE: usize = 64;
|
||||
|
||||
const CACHE_LINE_MASK: usize = CACHE_LINE - 1;
|
||||
|
||||
/// Returns true if the string is both longer than a cache line
|
||||
/// and the first cache line is ASCII.
|
||||
#[inline(always)]
|
||||
fn starts_with_ascii(buffer: &[u8]) -> bool {
|
||||
fn long_string_starts_with_ascii(buffer: &[u8]) -> bool {
|
||||
// We examine data only up to the end of the cache line
|
||||
// to make this check minimally disruptive.
|
||||
let bound = if buffer.len() <= CACHE_LINE {
|
||||
buffer.len()
|
||||
} else {
|
||||
CACHE_LINE - ((buffer.as_ptr() as usize) & CACHE_LINE_MASK)
|
||||
};
|
||||
if buffer.len() <= CACHE_LINE {
|
||||
return false;
|
||||
}
|
||||
let bound = CACHE_LINE - ((buffer.as_ptr() as usize) & CACHE_LINE_MASK);
|
||||
is_ascii(&buffer[..bound])
|
||||
}
|
||||
|
||||
/// Returns true if the string is both longer than two cache lines
|
||||
/// and the first two cache lines are Basic Latin.
|
||||
#[inline(always)]
|
||||
fn starts_with_basic_latin(buffer: &[u16]) -> bool {
|
||||
fn long_string_stars_with_basic_latin(buffer: &[u16]) -> bool {
|
||||
// We look at two cache lines with code unit size of two. There is need
|
||||
// to look at more than one cache line in the UTF-16 case, because looking
|
||||
// at just one cache line wouldn't catch non-ASCII Latin with high enough
|
||||
// probability with Latin-script languages that have relatively infrequent
|
||||
// non-ASCII characters.
|
||||
let bound = if buffer.len() <= CACHE_LINE {
|
||||
buffer.len()
|
||||
} else {
|
||||
(CACHE_LINE * 2 - ((buffer.as_ptr() as usize) & CACHE_LINE_MASK)) / 2
|
||||
};
|
||||
if buffer.len() <= CACHE_LINE {
|
||||
return false;
|
||||
}
|
||||
let bound = (CACHE_LINE * 2 - ((buffer.as_ptr() as usize) & CACHE_LINE_MASK)) / 2;
|
||||
is_basic_latin(&buffer[..bound])
|
||||
}
|
||||
|
||||
@ -118,7 +120,8 @@ macro_rules! shrinking_conversion {
|
||||
self.bulk_write(old_len.checked_add(needed).ok_or(())?, old_len, false)?
|
||||
};
|
||||
let written = $convert(other, &mut handle.as_mut_slice()[old_len..]);
|
||||
Ok(handle.finish(old_len + written, true))
|
||||
let new_len = old_len + written;
|
||||
Ok(handle.finish(new_len, new_len > CACHE_LINE))
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -313,9 +316,22 @@ impl nsACString {
|
||||
other: &[u16],
|
||||
old_len: usize,
|
||||
) -> Result<BulkWriteOk, ()> {
|
||||
// We first size the buffer for ASCII if the first cache line is ASCII. If that turns out not to
|
||||
// be enough, we size for the worst case given the length of the remaining input at that point.
|
||||
let (filled, num_ascii, mut handle) = if starts_with_basic_latin(other) {
|
||||
// We first size the buffer for ASCII if the first two cache lines are ASCII. If that turns out
|
||||
// not to be enough, we size for the worst case given the length of the remaining input at that
|
||||
// point. BUT if the worst case fits inside the inline capacity of an autostring, we skip
|
||||
// the ASCII stuff.
|
||||
let worst_case_needed = if let Some(inline_capacity) = self.inline_capacity() {
|
||||
let worst_case = times_three_plus_one(other.len()).ok_or(())?;
|
||||
if worst_case <= inline_capacity {
|
||||
Some(worst_case)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let (filled, num_ascii, mut handle) = if worst_case_needed.is_none() &&
|
||||
long_string_stars_with_basic_latin(other) {
|
||||
let new_len_with_ascii = old_len.checked_add(other.len()).ok_or(())?;
|
||||
let mut handle = unsafe { self.bulk_write(new_len_with_ascii, old_len, false)? };
|
||||
let num_ascii = copy_basic_latin_to_ascii(other, &mut handle.as_mut_slice()[old_len..]);
|
||||
@ -332,7 +348,11 @@ impl nsACString {
|
||||
(filled, num_ascii, handle)
|
||||
} else {
|
||||
// Started with non-ASCII. Compute worst case
|
||||
let needed = times_three_plus_one(other.len()).ok_or(())?;
|
||||
let needed = if let Some(n) = worst_case_needed {
|
||||
n
|
||||
} else {
|
||||
times_three_plus_one(other.len()).ok_or(())?
|
||||
};
|
||||
let new_len = old_len.checked_add(needed).ok_or(())?;
|
||||
let mut handle = unsafe { self.bulk_write(new_len, old_len, false)? };
|
||||
(old_len, 0, handle)
|
||||
@ -568,31 +588,47 @@ impl nsACString {
|
||||
(&mut handle.as_mut_slice()[old_len..filled]).copy_from_slice(&other[..num_ascii]);
|
||||
}
|
||||
(filled, num_ascii, handle)
|
||||
} else if starts_with_ascii(other) {
|
||||
// Wrapper didn't check for ASCII, so let's see if `other` starts with ASCII
|
||||
// `other` starts with ASCII, so let's first size the buffer
|
||||
// with optimism that it's ASCII-only.
|
||||
let new_len_with_ascii = old_len.checked_add(other.len()).ok_or(())?;
|
||||
let mut handle = unsafe { self.bulk_write(new_len_with_ascii, old_len, false)? };
|
||||
let num_ascii = copy_ascii_to_ascii(other, &mut handle.as_mut_slice()[old_len..]);
|
||||
let left = other.len() - num_ascii;
|
||||
let filled = old_len + num_ascii;
|
||||
if left == 0 {
|
||||
// `other` was all ASCII
|
||||
return Ok(handle.finish(filled, true));
|
||||
}
|
||||
let needed = left.checked_mul(2).ok_or(())?;
|
||||
let new_len = filled.checked_add(needed).ok_or(())?;
|
||||
unsafe {
|
||||
handle.restart_bulk_write(new_len, filled, false)?;
|
||||
}
|
||||
(filled, num_ascii, handle)
|
||||
} else {
|
||||
// Started with non-ASCII. Assume worst case.
|
||||
let needed = other.len().checked_mul(2).ok_or(())?;
|
||||
let new_len = old_len.checked_add(needed).ok_or(())?;
|
||||
let mut handle = unsafe { self.bulk_write(new_len, old_len, false)? };
|
||||
(old_len, 0, handle)
|
||||
let worst_case_needed = if let Some(inline_capacity) = self.inline_capacity() {
|
||||
let worst_case = other.len().checked_mul(2).ok_or(())?;
|
||||
if worst_case <= inline_capacity {
|
||||
Some(worst_case)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if worst_case_needed.is_none() && long_string_starts_with_ascii(other) {
|
||||
// Wrapper didn't check for ASCII, so let's see if `other` starts with ASCII
|
||||
// `other` starts with ASCII, so let's first size the buffer
|
||||
// with optimism that it's ASCII-only.
|
||||
let new_len_with_ascii = old_len.checked_add(other.len()).ok_or(())?;
|
||||
let mut handle = unsafe { self.bulk_write(new_len_with_ascii, old_len, false)? };
|
||||
let num_ascii = copy_ascii_to_ascii(other, &mut handle.as_mut_slice()[old_len..]);
|
||||
let left = other.len() - num_ascii;
|
||||
let filled = old_len + num_ascii;
|
||||
if left == 0 {
|
||||
// `other` was all ASCII
|
||||
return Ok(handle.finish(filled, true));
|
||||
}
|
||||
let needed = left.checked_mul(2).ok_or(())?;
|
||||
let new_len = filled.checked_add(needed).ok_or(())?;
|
||||
unsafe {
|
||||
handle.restart_bulk_write(new_len, filled, false)?;
|
||||
}
|
||||
(filled, num_ascii, handle)
|
||||
} else {
|
||||
// Started with non-ASCII. Assume worst case.
|
||||
let needed = if let Some(n) = worst_case_needed {
|
||||
n
|
||||
} else {
|
||||
other.len().checked_mul(2).ok_or(())?
|
||||
};
|
||||
let new_len = old_len.checked_add(needed).ok_or(())?;
|
||||
let mut handle = unsafe { self.bulk_write(new_len, old_len, false)? };
|
||||
(old_len, 0, handle)
|
||||
}
|
||||
};
|
||||
let written =
|
||||
convert_latin1_to_utf8(&other[num_ascii..], &mut handle.as_mut_slice()[filled..]);
|
||||
|
@ -144,6 +144,11 @@ pub use self::conversions::nsstring_fallible_append_utf8_impl;
|
||||
/// this type!
|
||||
pub struct BulkWriteOk;
|
||||
|
||||
/// Semi-arbitrary threshold below which we don't care about shrinking
|
||||
/// buffers to size. Currently matches `CACHE_LINE` in the `conversions`
|
||||
/// module.
|
||||
const SHRINKING_THRESHOLD: usize = 64;
|
||||
|
||||
///////////////////////////////////
|
||||
// Internal Implementation Flags //
|
||||
///////////////////////////////////
|
||||
@ -336,6 +341,7 @@ macro_rules! define_string_types {
|
||||
StringAdapter = $StringAdapter: ident;
|
||||
|
||||
StringRepr = $StringRepr: ident;
|
||||
AutoStringRepr = $AutoStringRepr: ident;
|
||||
|
||||
BulkWriteHandle = $BulkWriteHandle: ident;
|
||||
|
||||
@ -395,6 +401,13 @@ macro_rules! define_string_types {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct $AutoStringRepr {
|
||||
super_repr: $StringRepr,
|
||||
inline_capacity: u32,
|
||||
}
|
||||
|
||||
pub struct $BulkWriteHandle<'a> {
|
||||
string: &'a mut $AString,
|
||||
capacity: usize,
|
||||
@ -430,7 +443,7 @@ macro_rules! define_string_types {
|
||||
mem::forget(self); // Don't run the failure path in drop()
|
||||
return BulkWriteOk{};
|
||||
}
|
||||
if allow_shrinking {
|
||||
if allow_shrinking && length > SHRINKING_THRESHOLD {
|
||||
unsafe {
|
||||
let _ = self.restart_bulk_write(length, length, true);
|
||||
}
|
||||
@ -622,7 +635,7 @@ macro_rules! define_string_types {
|
||||
let rounded = $start_bulk_write(self,
|
||||
capacity32,
|
||||
units_to_preserve as u32,
|
||||
allow_shrinking);
|
||||
allow_shrinking && capacity > SHRINKING_THRESHOLD);
|
||||
if rounded == u32::max_value() {
|
||||
return Err(())
|
||||
}
|
||||
@ -633,6 +646,27 @@ macro_rules! define_string_types {
|
||||
fn as_repr(&mut self) -> ptr::NonNull<$StringRepr> {
|
||||
unsafe { ptr::NonNull::new_unchecked(self as *mut _ as *mut $StringRepr)}
|
||||
}
|
||||
|
||||
/// If this is an autostring, returns the capacity (excluding the zero
|
||||
/// terminator) of the inline buffer within `Some()`. Otherwise returns
|
||||
/// `None`.
|
||||
pub fn inline_capacity(&self) -> Option<usize> {
|
||||
if unsafe {
|
||||
// All $AString values point to a struct prefix which is
|
||||
// identical to $StringRepr, this we can transmute `self`
|
||||
// into $StringRepr to get the reference to the underlying
|
||||
// data.
|
||||
let this: &$StringRepr = mem::transmute(self);
|
||||
this.classflags.contains(ClassFlags::INLINE)
|
||||
} {
|
||||
unsafe {
|
||||
let this: &$AutoStringRepr = mem::transmute(self);
|
||||
Some(this.inline_capacity as usize)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for $AString {
|
||||
@ -1016,6 +1050,7 @@ define_string_types! {
|
||||
StringAdapter = nsCStringAdapter;
|
||||
|
||||
StringRepr = nsCStringRepr;
|
||||
AutoStringRepr = nsAutoCStringRepr;
|
||||
|
||||
BulkWriteHandle = nsACStringBulkWriteHandle;
|
||||
|
||||
@ -1146,6 +1181,7 @@ define_string_types! {
|
||||
StringAdapter = nsStringAdapter;
|
||||
|
||||
StringRepr = nsStringRepr;
|
||||
AutoStringRepr = nsAutoStringRepr;
|
||||
|
||||
BulkWriteHandle = nsAStringBulkWriteHandle;
|
||||
|
||||
@ -1259,6 +1295,7 @@ pub mod test_helpers {
|
||||
//! It is public to ensure that these testing functions are avaliable to
|
||||
//! gtest code.
|
||||
|
||||
use super::{nsACString, nsAString};
|
||||
use super::{nsCStr, nsCString, nsCStringRepr};
|
||||
use super::{nsStr, nsString, nsStringRepr};
|
||||
use super::{ClassFlags, DataFlags};
|
||||
@ -1400,4 +1437,16 @@ pub mod test_helpers {
|
||||
*f_class_null_terminated = ClassFlags::NULL_TERMINATED.bits();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(non_snake_case)]
|
||||
pub extern fn Rust_InlineCapacityFromRust(cstring: *const nsACString,
|
||||
string: *const nsAString,
|
||||
cstring_capacity: *mut usize,
|
||||
string_capacity: *mut usize) {
|
||||
unsafe {
|
||||
*cstring_capacity = (*cstring).inline_capacity().unwrap();
|
||||
*string_capacity = (*string).inline_capacity().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,3 +221,32 @@ raptor-unity-webgl-chrome:
|
||||
fetches:
|
||||
fetch:
|
||||
- unity-webgl
|
||||
|
||||
raptor-assorted-dom-firefox:
|
||||
description: "Raptor Assorted-Dom on Firefox"
|
||||
try-name: raptor-assorted-dom-firefox
|
||||
treeherder-symbol: Rap(dom)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 3
|
||||
max-run-time: 1500
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-assorted-dom
|
||||
fetches:
|
||||
fetch:
|
||||
- assorted-dom
|
||||
|
||||
raptor-assorted-dom-chrome:
|
||||
description: "Raptor Assorted-Dom on Chrome"
|
||||
try-name: raptor-assorted-dom-chrome
|
||||
treeherder-symbol: Rap-C(dom)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 3
|
||||
max-run-time: 1500
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-assorted-dom
|
||||
- --app=chrome
|
||||
fetches:
|
||||
fetch:
|
||||
- assorted-dom
|
||||
|
@ -90,6 +90,7 @@ raptor-firefox:
|
||||
- raptor-webaudio-firefox
|
||||
- raptor-gdocs-firefox
|
||||
- raptor-sunspider-firefox
|
||||
- raptor-assorted-dom-firefox
|
||||
|
||||
raptor-chrome:
|
||||
- raptor-tp6-chrome
|
||||
@ -100,6 +101,7 @@ raptor-chrome:
|
||||
- raptor-webaudio-chrome
|
||||
- raptor-gdocs-chrome
|
||||
- raptor-sunspider-chrome
|
||||
- raptor-assorted-dom-chrome
|
||||
|
||||
# Fetch tasks are only supported on Linux for now,
|
||||
# so these need to be separate sets.
|
||||
|
@ -11,18 +11,18 @@ from __future__ import absolute_import, print_function, unicode_literals
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
import socket
|
||||
import subprocess
|
||||
|
||||
import mozfile
|
||||
from mach.decorators import CommandProvider, Command
|
||||
from mozboot.util import get_state_dir
|
||||
from mozbuild.base import MozbuildObject, MachCommandBase
|
||||
from mozpack.copier import FileCopier
|
||||
from mozpack.manifests import InstallManifest
|
||||
|
||||
HERE = os.path.dirname(os.path.realpath(__file__))
|
||||
BENCHMARK_REPOSITORY = 'https://github.com/mozilla/perf-automation'
|
||||
BENCHMARK_REVISION = '6beb3d3e22abce8cf8e2e89bc45acd4152258f12'
|
||||
BENCHMARK_REVISION = '4befd28725c687b91ce749420eab29352ecbcab4'
|
||||
|
||||
|
||||
class RaptorRunner(MozbuildObject):
|
||||
@ -74,24 +74,30 @@ class RaptorRunner(MozbuildObject):
|
||||
|
||||
subprocess.check_call(['git', 'checkout', BENCHMARK_REVISION], cwd=external_repo_path)
|
||||
|
||||
# Link benchmarks to the objdir
|
||||
# Link or copy benchmarks to the objdir
|
||||
benchmark_paths = (
|
||||
os.path.join(external_repo_path, 'benchmarks'),
|
||||
os.path.join(self.topsrcdir, 'third_party', 'webkit', 'PerformanceTests'),
|
||||
)
|
||||
manifest = InstallManifest()
|
||||
|
||||
benchmark_dest = os.path.join(self.topobjdir, 'testing', 'raptor', 'benchmarks')
|
||||
if not os.path.isdir(benchmark_dest):
|
||||
os.makedirs(benchmark_dest)
|
||||
|
||||
for benchmark_path in benchmark_paths:
|
||||
for path in os.listdir(benchmark_path):
|
||||
abspath = os.path.join(benchmark_path, path)
|
||||
if not os.path.isdir(abspath) or path.startswith('.'):
|
||||
for name in os.listdir(benchmark_path):
|
||||
path = os.path.join(benchmark_path, name)
|
||||
dest = os.path.join(benchmark_dest, name)
|
||||
if not os.path.isdir(path) or name.startswith('.'):
|
||||
continue
|
||||
|
||||
manifest.add_link(abspath, path)
|
||||
|
||||
copier = FileCopier()
|
||||
manifest.populate_registry(copier)
|
||||
copier.copy(os.path.join(self.topobjdir, 'testing', 'raptor', 'benchmarks'))
|
||||
if hasattr(os, 'symlink'):
|
||||
if not os.path.exists(dest):
|
||||
os.symlink(path, dest)
|
||||
else:
|
||||
# Clobber the benchmark in case a recent update removed any files.
|
||||
mozfile.remove(dest)
|
||||
shutil.copytree(path, dest)
|
||||
|
||||
def make_config(self):
|
||||
default_actions = ['populate-webroot', 'install-chrome', 'create-virtualenv', 'run-tests']
|
||||
|
@ -97,6 +97,8 @@ class Output(object):
|
||||
subtests, vals = self.parseWebaudioOutput(test)
|
||||
elif 'unity-webgl' in test.measurements:
|
||||
subtests, vals = self.parseUnityWebGLOutput(test)
|
||||
elif 'assorted-dom' in test.measurements:
|
||||
subtests, vals = self.parseAssortedDomOutput(test)
|
||||
suite['subtests'] = subtests
|
||||
|
||||
else:
|
||||
@ -342,6 +344,47 @@ class Output(object):
|
||||
|
||||
return subtests, vals
|
||||
|
||||
def parseAssortedDomOutput(self, test):
|
||||
# each benchmark 'index' becomes a subtest; each pagecycle / iteration
|
||||
# of the test has multiple values
|
||||
|
||||
# this is the format we receive the results in from the benchmark
|
||||
# i.e. this is ONE pagecycle of assorted-dom ('test' is a valid subtest name btw):
|
||||
|
||||
# {u'worker-getname-performance-getter': 5.9, u'window-getname-performance-getter': 6.1,
|
||||
# u'window-getprop-performance-getter': 6.1, u'worker-getprop-performance-getter': 6.1,
|
||||
# u'test': 5.8, u'total': 30}
|
||||
|
||||
# the 'total' is provided for us from the benchmark; the overall score will be the mean of
|
||||
# the totals from all pagecycles; but keep all the subtest values for the logs/json
|
||||
|
||||
_subtests = {}
|
||||
data = test.measurements['assorted-dom']
|
||||
for pagecycle in data:
|
||||
for _sub, _value in pagecycle[0].iteritems():
|
||||
# build a list of subtests and append all related replicates
|
||||
if _sub not in _subtests.keys():
|
||||
# subtest not added yet, first pagecycle, so add new one
|
||||
_subtests[_sub] = {'unit': test.unit,
|
||||
'alertThreshold': float(test.alert_threshold),
|
||||
'lowerIsBetter': test.lower_is_better,
|
||||
'name': _sub,
|
||||
'replicates': []}
|
||||
_subtests[_sub]['replicates'].extend([_value])
|
||||
|
||||
vals = []
|
||||
subtests = []
|
||||
names = _subtests.keys()
|
||||
names.sort(reverse=True)
|
||||
for name in names:
|
||||
_subtests[name]['value'] = round(filter.median(_subtests[name]['replicates']), 2)
|
||||
subtests.append(_subtests[name])
|
||||
# only use the 'total's to compute the overall result
|
||||
if name == 'total':
|
||||
vals.append([_subtests[name]['value'], name])
|
||||
|
||||
return subtests, vals
|
||||
|
||||
def output(self):
|
||||
"""output to file and perfherder data json """
|
||||
if self.summarized_results == {}:
|
||||
@ -477,6 +520,11 @@ class Output(object):
|
||||
results = [i for i, j in val_list]
|
||||
return sum(results)
|
||||
|
||||
@classmethod
|
||||
def assorted_dom_score(cls, val_list):
|
||||
results = [i for i, j in val_list]
|
||||
return round(filter.geometric_mean(results), 2)
|
||||
|
||||
def construct_summary(self, vals, testname):
|
||||
if testname.startswith('raptor-v8_7'):
|
||||
return self.v8_Metric(vals)
|
||||
@ -494,6 +542,8 @@ class Output(object):
|
||||
return self.unity_webgl_score(vals)
|
||||
elif testname.startswith('raptor-webaudio'):
|
||||
return self.webaudio_score(vals)
|
||||
elif testname.startswith('raptor-assorted-dom'):
|
||||
return self.assorted_dom_score(vals)
|
||||
elif len(vals) > 1:
|
||||
return round(filter.geometric_mean([i for i, j in vals]), 2)
|
||||
else:
|
||||
|
@ -8,3 +8,4 @@
|
||||
[include:tests/raptor-unity-webgl.ini]
|
||||
[include:tests/raptor-webaudio.ini]
|
||||
[include:tests/raptor-gdocs.ini]
|
||||
[include:tests/raptor-assorted-dom.ini]
|
||||
|
14
testing/raptor/raptor/tests/raptor-assorted-dom.ini
Normal file
@ -0,0 +1,14 @@
|
||||
[DEFAULT]
|
||||
type = benchmark
|
||||
test_url = http://localhost:<port>/assorted-dom/assorted/driver.html?raptor
|
||||
page_cycles = 10
|
||||
page_timeout = 60000
|
||||
unit = ms
|
||||
lower_is_better = true
|
||||
alert_threshold = 2.0
|
||||
|
||||
[raptor-assorted-dom-firefox]
|
||||
apps = firefox
|
||||
|
||||
[raptor-assorted-dom-chrome]
|
||||
apps = chrome
|
@ -25,7 +25,8 @@
|
||||
"*://*/MotionMark/*",
|
||||
"*://*/SunSpider/*",
|
||||
"*://*/webaudio/*",
|
||||
"*://*/unity-webgl/index.html*"],
|
||||
"*://*/unity-webgl/index.html*",
|
||||
"*://*/assorted-dom/assorted/results.html*"],
|
||||
"js": ["benchmark-relay.js"]
|
||||
}
|
||||
],
|
||||
|
@ -338365,6 +338365,12 @@
|
||||
{}
|
||||
]
|
||||
],
|
||||
"custom-elements/range-and-constructors.html": [
|
||||
[
|
||||
"/custom-elements/range-and-constructors.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"custom-elements/reaction-timing.html": [
|
||||
[
|
||||
"/custom-elements/reaction-timing.html",
|
||||
@ -578532,6 +578538,10 @@
|
||||
"60d88cffb517c0062db338e5ba89e98f7748c280",
|
||||
"testharness"
|
||||
],
|
||||
"custom-elements/range-and-constructors.html": [
|
||||
"d17c3b71480aa9dd2a75ccbc2cccfd362060eb3c",
|
||||
"testharness"
|
||||
],
|
||||
"custom-elements/reaction-timing.html": [
|
||||
"9e5bafbedfec42d28eb94c95ed84396941bc61ac",
|
||||
"testharness"
|
||||
|
@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Custom elements: Range APIs should invoke constructor in tree order</title>
|
||||
<meta name="author" title="Edgar Chen" href="mailto:echen@mozilla.com">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-element">
|
||||
<link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element">
|
||||
<line rel="help" href="https://dom.spec.whatwg.org/#concept-range-extract">
|
||||
<line rel="help" href="https://dom.spec.whatwg.org/#concept-range-clone">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
|
||||
<c-e data-index="root">
|
||||
<c-e data-index="root-0">
|
||||
<c-e data-index="root-0-0">
|
||||
<c-e data-index="root-0-0-0"></c-e>
|
||||
<span id="start"></span>
|
||||
</c-e>
|
||||
</c-e>
|
||||
<c-e data-index="root-1"></c-e>
|
||||
<span id="end"></span>
|
||||
</c-e>
|
||||
|
||||
<script>
|
||||
|
||||
var logs = [];
|
||||
class CE extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
logs.push(this.dataset.index);
|
||||
}
|
||||
}
|
||||
customElements.define('c-e', CE);
|
||||
|
||||
function getRange() {
|
||||
const range = new Range();
|
||||
range.setStart(document.getElementById('start'), 0);
|
||||
range.setEnd(document.getElementById('end'), 0);
|
||||
return range;
|
||||
}
|
||||
|
||||
test(function () {
|
||||
// Clear log for testing.
|
||||
logs = [];
|
||||
getRange().cloneContents();
|
||||
assert_array_equals(logs, ['root-0', 'root-0-0', 'root-1']);
|
||||
}, 'Range.cloneContents should invoke constructor in tree order');
|
||||
|
||||
test(function () {
|
||||
// Clear log for testing.
|
||||
logs = [];
|
||||
getRange().extractContents();
|
||||
assert_array_equals(logs, ['root-0', 'root-0-0']);
|
||||
}, 'Range.extractContents should invoke constructor in tree order');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -207,7 +207,7 @@ var listener = {
|
||||
},
|
||||
|
||||
onWindowLoaded() {
|
||||
let browser = this.win.document.createElementNS(XUL_NS, "browser");
|
||||
let browser = this.win.document.createXULElement("browser");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute("disableglobalhistory", "true");
|
||||
|
||||
|
@ -543,10 +543,7 @@ var PrintUtils = {
|
||||
|
||||
// show the toolbar after we go into print preview mode so
|
||||
// that we can initialize the toolbar with total num pages
|
||||
const XUL_NS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
printPreviewTB = document.createElementNS(XUL_NS, "toolbar",
|
||||
printPreviewTB = document.createXULElement("toolbar",
|
||||
{ is: "printpreview-toolbar" });
|
||||
printPreviewTB.setAttribute("fullscreentoolbar", true);
|
||||
printPreviewTB.id = "print-preview-toolbar";
|
||||
|
@ -23,7 +23,9 @@ activity_stream:
|
||||
"PREVIEW_REQUEST",
|
||||
"SAVE_TO_POCKET",
|
||||
"SEARCH",
|
||||
"SEARCH_EDIT_ADD",
|
||||
"SEARCH_EDIT_CLOSE",
|
||||
"SEARCH_EDIT_DELETE",
|
||||
"SKIPPED_SIGNIN",
|
||||
"SUBMIT_EMAIL",
|
||||
"DISCLAIMER_ACKED",
|
||||
@ -526,8 +528,8 @@ devtools.main:
|
||||
extra_keys:
|
||||
session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
|
||||
sidepanel_changed:
|
||||
objects: ["inspector"]
|
||||
bug_numbers: [1463083]
|
||||
objects: ["inspector", "netmonitor"]
|
||||
bug_numbers: [1463083, 1463169]
|
||||
notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
|
||||
record_in_processes: ["main"]
|
||||
description: User has switched sidepanel tabs.
|
||||
|
@ -106,7 +106,8 @@ Preferences
|
||||
|
||||
``toolkit.telemetry.log.level``
|
||||
|
||||
This sets the Telemetry logging verbosity per ``Log.jsm``, with ``Trace`` or ``0`` being the most verbose and the default being ``Warn``.
|
||||
This sets the Telemetry logging verbosity per ``Log.jsm``. The available levels, in descending order of verbosity, are ``Trace``, ``Debug``, ``Config``, ``Info``, ``Warn``, ``Error`` and ``Fatal`` with the default being ``Warn``.
|
||||
|
||||
By default logging goes only the console service.
|
||||
|
||||
``toolkit.telemetry.log.dump``
|
||||
|
@ -12,8 +12,6 @@ const FRAME_SCRIPT_URL = "chrome://global/content/backgroundPageThumbsContent.js
|
||||
|
||||
const TELEMETRY_HISTOGRAM_ID_PREFIX = "FX_THUMBNAILS_BG_";
|
||||
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
const ABOUT_NEWTAB_SEGREGATION_PREF = "privacy.usercontext.about_newtab_segregation.enabled";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
||||
@ -256,7 +254,7 @@ const BackgroundPageThumbs = {
|
||||
this._destroyBrowser();
|
||||
this._renewThumbBrowser = false;
|
||||
|
||||
let browser = this._parentWin.document.createElementNS(XUL_NS, "browser");
|
||||
let browser = this._parentWin.document.createXULElement("browser");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute("remote", "true");
|
||||
browser.setAttribute("disableglobalhistory", "true");
|
||||
|
@ -979,7 +979,7 @@
|
||||
|
||||
} else {
|
||||
// need to create a new item
|
||||
item = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "richlistitem");
|
||||
item = document.createXULElement("richlistitem");
|
||||
}
|
||||
|
||||
item.setAttribute("dir", this.style.direction);
|
||||
|
@ -1113,8 +1113,7 @@
|
||||
<method name="_createAutoScrollPopup">
|
||||
<body>
|
||||
<![CDATA[
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var popup = document.createElementNS(XUL_NS, "panel");
|
||||
var popup = document.createXULElement("panel");
|
||||
popup.className = "autoscroller";
|
||||
// We set this attribute on the element so that mousemove
|
||||
// events can be handled by browser-content.js.
|
||||
|
@ -64,16 +64,13 @@
|
||||
<parameter name="aLabel"/>
|
||||
<parameter name="aValue"/>
|
||||
<body>
|
||||
const XUL_NS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
var menupopup = this.menupopup;
|
||||
if (!menupopup) {
|
||||
menupopup = this.ownerDocument.createElementNS(XUL_NS, "menupopup");
|
||||
menupopup = this.ownerDocument.createXULElement("menupopup");
|
||||
this.appendChild(menupopup);
|
||||
}
|
||||
|
||||
var menuitem = this.ownerDocument.createElementNS(XUL_NS, "menuitem");
|
||||
var menuitem = this.ownerDocument.createXULElement("menuitem");
|
||||
menuitem.setAttribute("label", aLabel);
|
||||
menuitem.setAttribute("value", aValue);
|
||||
|
||||
|
@ -318,10 +318,9 @@
|
||||
<parameter name="description"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var popup = this.menupopup ||
|
||||
this.appendChild(document.createElementNS(XULNS, "menupopup"));
|
||||
var item = document.createElementNS(XULNS, "menuitem");
|
||||
this.appendChild(document.createXULElement("menupopup"));
|
||||
var item = document.createXULElement("menuitem");
|
||||
item.setAttribute("label", label);
|
||||
item.setAttribute("value", value);
|
||||
if (description)
|
||||
|
@ -112,8 +112,7 @@
|
||||
insertPos = notifications[n];
|
||||
}
|
||||
|
||||
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var newitem = document.createElementNS(XULNS, "notification");
|
||||
var newitem = document.createXULElement("notification");
|
||||
// Can't use instanceof in case this was created from a different document:
|
||||
let labelIsDocFragment = aLabel && typeof aLabel == "object" && aLabel.nodeType &&
|
||||
aLabel.nodeType == aLabel.DOCUMENT_FRAGMENT_NODE;
|
||||
@ -133,7 +132,7 @@
|
||||
|
||||
for (var b = 0; b < aButtons.length; b++) {
|
||||
var button = aButtons[b];
|
||||
var buttonElem = document.createElementNS(XULNS, "button");
|
||||
var buttonElem = document.createXULElement("button");
|
||||
buttonElem.setAttribute("label", button.label);
|
||||
if (typeof button.accessKey == "string")
|
||||
buttonElem.setAttribute("accesskey", button.accessKey);
|
||||
|
@ -306,8 +306,7 @@
|
||||
<parameter name="value"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var radio = document.createElementNS(XULNS, "radio");
|
||||
var radio = document.createXULElement("radio");
|
||||
radio.setAttribute("label", label);
|
||||
radio.setAttribute("value", value);
|
||||
this.appendChild(radio);
|
||||
|
@ -117,14 +117,11 @@
|
||||
<parameter name="aLabel"/>
|
||||
<parameter name="aValue"/>
|
||||
<body>
|
||||
const XULNS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
var item =
|
||||
this.ownerDocument.createElementNS(XULNS, "richlistitem");
|
||||
this.ownerDocument.createXULElement("richlistitem");
|
||||
item.setAttribute("value", aValue);
|
||||
|
||||
var label = this.ownerDocument.createElementNS(XULNS, "label");
|
||||
var label = this.ownerDocument.createXULElement("label");
|
||||
label.setAttribute("value", aLabel);
|
||||
label.setAttribute("flex", "1");
|
||||
label.setAttribute("crop", "end");
|
||||
|
@ -506,8 +506,7 @@
|
||||
<parameter name="value"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var tab = document.createElementNS(XULNS, "tab");
|
||||
var tab = document.createXULElement("tab");
|
||||
tab.setAttribute("label", label);
|
||||
tab.setAttribute("value", value);
|
||||
this.appendChild(tab);
|
||||
|
@ -787,8 +787,6 @@ PopupNotifications.prototype = {
|
||||
_refreshPanel: function PopupNotifications_refreshPanel(notificationsToShow) {
|
||||
this._clearPanel();
|
||||
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
notificationsToShow.forEach(function(n) {
|
||||
let doc = this.window.document;
|
||||
|
||||
@ -802,7 +800,7 @@ PopupNotifications.prototype = {
|
||||
if (popupnotification)
|
||||
gNotificationParents.set(popupnotification, popupnotification.parentNode);
|
||||
else
|
||||
popupnotification = doc.createElementNS(XUL_NS, "popupnotification");
|
||||
popupnotification = doc.createXULElement("popupnotification");
|
||||
|
||||
// Create the notification description element.
|
||||
let desc = this._formatDescriptionMessage(n);
|
||||
@ -884,7 +882,7 @@ PopupNotifications.prototype = {
|
||||
|
||||
for (let i = 1; i < n.secondaryActions.length; i++) {
|
||||
let action = n.secondaryActions[i];
|
||||
let item = doc.createElementNS(XUL_NS, "menuitem");
|
||||
let item = doc.createXULElement("menuitem");
|
||||
item.setAttribute("label", action.label);
|
||||
item.setAttribute("accesskey", action.accessKey);
|
||||
item.notification = n;
|
||||
|
@ -3,8 +3,6 @@
|
||||
* 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/. */
|
||||
|
||||
const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
var gUpdateHistory = {
|
||||
_view: null,
|
||||
|
||||
@ -35,7 +33,7 @@ var gUpdateHistory = {
|
||||
if (!update.statusText)
|
||||
continue;
|
||||
|
||||
var element = document.createElementNS(NS_XUL, "richlistitem");
|
||||
var element = document.createXULElement("richlistitem");
|
||||
element.className = "update";
|
||||
this._view.appendChild(element);
|
||||
element.name = bundle.getFormattedString("updateFullName",
|
||||
|
@ -72,12 +72,12 @@ button.plain {
|
||||
button[type="disclosure"] {
|
||||
margin: 0;
|
||||
-moz-appearance: none;
|
||||
list-style-image: url("chrome://global/skin/tree/twisty-collapsed.svg");
|
||||
list-style-image: url("chrome://global/skin/icons/twisty-collapsed.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
button[type="disclosure"][open="true"] {
|
||||
list-style-image: url("chrome://global/skin/tree/twisty-expanded.svg");
|
||||
list-style-image: url("chrome://global/skin/icons/twisty-expanded.svg");
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ toolkit.jar:
|
||||
skin/classic/global/toolbar.css
|
||||
skin/classic/global/toolbarbutton.css
|
||||
skin/classic/global/tooltip.css
|
||||
skin/classic/global/tree.css
|
||||
* skin/classic/global/tree.css
|
||||
* skin/classic/global/alerts/alert.css (alerts/alert.css)
|
||||
|
||||
skin/classic/global/icons/Authentication.png (icons/Authentication.png)
|
||||
@ -42,6 +42,3 @@ toolkit.jar:
|
||||
|
||||
* skin/classic/global/in-content/common.css (in-content/common.css)
|
||||
* skin/classic/global/in-content/info-pages.css (in-content/info-pages.css)
|
||||
skin/classic/global/tree/twisty-collapsed.svg (tree/twisty-collapsed.svg)
|
||||
skin/classic/global/tree/twisty-collapsed-rtl.svg (tree/twisty-collapsed-rtl.svg)
|
||||
skin/classic/global/tree/twisty-expanded.svg (tree/twisty-expanded.svg)
|
||||
|
@ -2,215 +2,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* ===== tree.css ===================================================
|
||||
== Styles used by the XUL outline element.
|
||||
======================================================================= */
|
||||
|
||||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
|
||||
/* ::::: tree ::::: */
|
||||
|
||||
tree {
|
||||
margin: 0 4px;
|
||||
background-color: -moz-Field;
|
||||
color: -moz-FieldText;
|
||||
-moz-appearance: listbox;
|
||||
}
|
||||
|
||||
/* ::::: tree focusring ::::: */
|
||||
|
||||
.focusring > .tree-stack > .tree-rows > .tree-bodybox {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.focusring:focus > .tree-stack > .tree-rows > .tree-bodybox {
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: tree rows ::::: */
|
||||
|
||||
treechildren::-moz-tree-row {
|
||||
border: 1px solid transparent;
|
||||
min-height: 18px;
|
||||
height: 1.3em;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(multicol, odd) {
|
||||
background-color: -moz-oddtreerow;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(selected) {
|
||||
background-color: -moz-cellhighlight;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(selected, focus) {
|
||||
background-color: Highlight;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(current, focus) {
|
||||
border: 1px dotted Highlight;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(selected, current, focus) {
|
||||
border: 1px dotted #F3D982;
|
||||
}
|
||||
|
||||
/* ::::: tree cells ::::: */
|
||||
|
||||
treechildren::-moz-tree-cell {
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(selected) {
|
||||
color: -moz-cellhighlighttext;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(selected, focus) {
|
||||
color: HighlightText;
|
||||
}
|
||||
|
||||
/* ::::: lines connecting cells ::::: */
|
||||
|
||||
treechildren::-moz-tree-line {
|
||||
border: 1px dotted ThreeDShadow;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-line(selected, focus) {
|
||||
border: 1px dotted HighlightText;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: tree separator ::::: */
|
||||
|
||||
treechildren::-moz-tree-separator {
|
||||
border-top: 1px solid ThreeDShadow;
|
||||
border-bottom: 1px solid ThreeDHighlight;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: drop feedback ::::: */
|
||||
|
||||
treechildren::-moz-tree-cell-text(primary, dropOn) {
|
||||
background-color: Highlight;
|
||||
color: HighlightText;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-drop-feedback {
|
||||
background-color: Highlight;
|
||||
width: 50px;
|
||||
height: 2px;
|
||||
margin-inline-start: 5px;
|
||||
}
|
||||
|
||||
/* ::::: tree columns ::::: */
|
||||
|
||||
treecol,
|
||||
treecolpicker {
|
||||
-moz-appearance: treeheadercell;
|
||||
-moz-box-align: center;
|
||||
-moz-box-pack: center;
|
||||
color: -moz-DialogText;
|
||||
}
|
||||
|
||||
treecol:hover,
|
||||
treecolpicker:hover {
|
||||
color: -moz-buttonhovertext;
|
||||
}
|
||||
|
||||
.treecol-image {
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
.treecol-text {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
treecol[hideheader="true"] {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
/* ::::: column drag and drop styles ::::: */
|
||||
|
||||
treecol[dragging="true"] {
|
||||
color: Graytext;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-column(insertbefore) {
|
||||
border-inline-start: 1px solid ThreeDShadow;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-column(insertafter) {
|
||||
border-inline-end: 1px solid ThreeDShadow;
|
||||
}
|
||||
%include ../../shared/tree.inc.css
|
||||
|
||||
/* ::::: sort direction indicator ::::: */
|
||||
|
||||
.treecol-sortdirection {
|
||||
-moz-appearance: treeheadersortarrow;
|
||||
}
|
||||
|
||||
/* ::::: column picker ::::: */
|
||||
|
||||
.tree-columnpicker-icon {
|
||||
list-style-image: url("chrome://global/skin/tree/columnpicker.gif");
|
||||
}
|
||||
|
||||
/* ::::: twisty ::::: */
|
||||
|
||||
treechildren::-moz-tree-twisty {
|
||||
padding-inline-end: 4px;
|
||||
padding-top: 1px;
|
||||
width: 9px; /* The image's width is 9 pixels */
|
||||
list-style-image: url("chrome://global/skin/tree/twisty-collapsed.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(closed) {
|
||||
list-style-image: url("chrome://global/skin/tree/twisty-collapsed-rtl.svg");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-twisty(open) {
|
||||
list-style-image: url("chrome://global/skin/tree/twisty-expanded.svg");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-twisty(selected) {
|
||||
fill: -moz-cellhighlighttext;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-indentation {
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
/* ::::: editable tree ::::: */
|
||||
|
||||
treechildren::-moz-tree-row(selected, editing) {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(selected, editing) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell(active, selected, focus, editing) {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(active, selected, editing) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.tree-input {
|
||||
-moz-appearance: none;
|
||||
border: 1px solid Highlight;
|
||||
margin: 0;
|
||||
margin-inline-start: -4px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
@ -1,6 +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/. -->
|
||||
<svg width="9" height="9" xmlns="http://www.w3.org/2000/svg" stroke="context-fill" stroke-width="1.6" fill="none">
|
||||
<path d="m 8.5,2.5 -4,4 -4,-4"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 369 B |
@ -72,7 +72,4 @@ toolkit.jar:
|
||||
skin/classic/global/icons/sslWarning.png (icons/sslWarning.png)
|
||||
* skin/classic/global/in-content/common.css (in-content/common.css)
|
||||
* skin/classic/global/in-content/info-pages.css (in-content/info-pages.css)
|
||||
skin/classic/global/tree/arrow-collapsed.svg (tree/arrow-collapsed.svg)
|
||||
skin/classic/global/tree/arrow-collapsed-rtl.svg (tree/arrow-collapsed-rtl.svg)
|
||||
skin/classic/global/tree/arrow-expanded.svg (tree/arrow-expanded.svg)
|
||||
skin/classic/global/tree/columnpicker.gif (tree/columnpicker.gif)
|
||||
|
@ -2,15 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
%include shared.inc
|
||||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
|
||||
tree {
|
||||
margin: 0px 4px;
|
||||
color: -moz-DialogText;
|
||||
background-color: #FFFFFF;
|
||||
-moz-appearance: listbox;
|
||||
}
|
||||
%include ../../shared/tree.inc.css
|
||||
|
||||
/* ::::: tree focusring ::::: */
|
||||
|
||||
@ -22,165 +14,10 @@ tree {
|
||||
border: 1px solid -moz-mac-focusring;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: tree rows ::::: */
|
||||
|
||||
treechildren::-moz-tree-row {
|
||||
border-top: 1px solid transparent;
|
||||
height: 18px;
|
||||
background-color: -moz-field;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(multicol, odd) {
|
||||
background-color: -moz-oddtreerow;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(selected) {
|
||||
background-color: -moz-mac-secondaryhighlight;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(selected, focus) {
|
||||
background-color: Highlight;
|
||||
color: HighlightText;
|
||||
}
|
||||
|
||||
/* ::::: tree cells ::::: */
|
||||
|
||||
treechildren::-moz-tree-cell {
|
||||
padding: 0px 2px 0px 2px;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(selected) {
|
||||
color: -moz-DialogText;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(selected, focus) {
|
||||
color: HighlightText;
|
||||
}
|
||||
|
||||
/* ::::: lines connecting cells ::::: */
|
||||
|
||||
treechildren::-moz-tree-line {
|
||||
/* XXX there should be no border on Mac, but trees currently
|
||||
paint the line black by default, so I'll just leave this
|
||||
for now. */
|
||||
visibility: hidden;
|
||||
border: 1px dotted grey;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: tree separator ::::: */
|
||||
|
||||
treechildren::-moz-tree-separator {
|
||||
border-top: 1px dashed #C7C7C7;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: drop feedback ::::: */
|
||||
|
||||
treechildren::-moz-tree-cell(primary, dropOn) {
|
||||
background-color: #A1A1A1 !important;
|
||||
color: #FFF !important;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(primary, dropOn) {
|
||||
color: #FFF !important;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-drop-feedback {
|
||||
background-color: #A1A1A1;
|
||||
width: 50px;
|
||||
height: 2px;
|
||||
margin-inline-start: 5px;
|
||||
}
|
||||
|
||||
/* ::::: tree columns ::::: */
|
||||
|
||||
treecol,
|
||||
treecolpicker {
|
||||
-moz-appearance: treeheadercell;
|
||||
-moz-box-align: center;
|
||||
-moz-box-pack: center;
|
||||
color: -moz-DialogText;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.treecol-image {
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
.treecol-text {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
treecol[hideheader="true"] {
|
||||
-moz-appearance: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
max-height: 0;
|
||||
}
|
||||
|
||||
/* ::::: column drag and drop styles ::::: */
|
||||
|
||||
treecol[dragging="true"] {
|
||||
color: GrayText;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-column(insertbefore) {
|
||||
border-inline-start: 1px solid ThreeDShadow;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-column(insertafter) {
|
||||
border-inline-end: 1px solid ThreeDShadow;
|
||||
}
|
||||
|
||||
/* ::::: column picker ::::: */
|
||||
|
||||
.tree-columnpicker-icon {
|
||||
list-style-image: url("chrome://global/skin/tree/columnpicker.gif");
|
||||
}
|
||||
|
||||
/* ::::: twisty ::::: */
|
||||
|
||||
treechildren::-moz-tree-twisty {
|
||||
-moz-appearance: treetwisty;
|
||||
padding-inline-end: 2px;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-twisty(open) {
|
||||
-moz-appearance: treetwistyopen;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-twisty(Name, separator) {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-indentation {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
/* ::::: editable tree ::::: */
|
||||
|
||||
.tree-input {
|
||||
-moz-appearance: none;
|
||||
border-width: 0;
|
||||
box-shadow: var(--focus-ring-box-shadow);
|
||||
margin: 0;
|
||||
margin-inline-start: -2px;
|
||||
padding: 2px 1px 1px;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell(active, selected, focus, editing) {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(active, selected, editing) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
@ -1,6 +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/. -->
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" fill="context-fill" fill-opacity="context-fill-opacity">
|
||||
<polygon points="4,8.5 12,4 12,13" />
|
||||
</svg>
|
Before Width: | Height: | Size: 381 B |
@ -1,6 +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/. -->
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" fill="context-fill" fill-opacity="context-fill-opacity">
|
||||
<polygon points="4,4 12,8.5 4,13" />
|
||||
</svg>
|
Before Width: | Height: | Size: 380 B |
@ -1,6 +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/. -->
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" fill="context-fill" fill-opacity="context-fill-opacity">
|
||||
<polygon points="3,5 12,5 7.5,13" />
|
||||
</svg>
|
Before Width: | Height: | Size: 380 B |
@ -1,6 +1,6 @@
|
||||
<!-- 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 width="9" height="9" xmlns="http://www.w3.org/2000/svg" stroke="context-fill" stroke-width="1.6" fill="none">
|
||||
<path d="m 6.5,0.5 -4,4 4,4"/>
|
||||
</svg>
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg" >
|
||||
<path d="M1 4l4 4 1-1-3-3 3-3-1-1-4 4z" fill="context-fill"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 363 B |
@ -1,6 +1,6 @@
|
||||
<!-- 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 width="9" height="9" xmlns="http://www.w3.org/2000/svg" stroke="context-fill" stroke-width="1.6" fill="none">
|
||||
<path d="m 2.5,0.5 4,4 -4,4"/>
|
||||
</svg>
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7,4L3,8L2,7l3-3L2,1l1-1L7,4z" fill="context-fill"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 362 B |
@ -1,6 +1,6 @@
|
||||
<!-- 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 width="9" height="9" xmlns="http://www.w3.org/2000/svg" stroke="context-fill" stroke-width="1.6" fill="none">
|
||||
<path d="m 2.5,0.5 4,4 -4,4"/>
|
||||
</svg>
|
||||
<svg width="8" height="8" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 7L0 3l1-1 3 3 3-3 1 1-4 4z" fill="context-fill"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 344 B |
@ -40,6 +40,9 @@ toolkit.jar:
|
||||
skin/classic/global/icons/resizer.svg (../../shared/icons/resizer.svg)
|
||||
skin/classic/global/icons/spinner-arrow-down.svg (../../shared/icons/spinner-arrow-down.svg)
|
||||
skin/classic/global/icons/spinner-arrow-up.svg (../../shared/icons/spinner-arrow-up.svg)
|
||||
skin/classic/global/icons/twisty-collapsed.svg (../../shared/icons/twisty-collapsed.svg)
|
||||
skin/classic/global/icons/twisty-collapsed-rtl.svg (../../shared/icons/twisty-collapsed-rtl.svg)
|
||||
skin/classic/global/icons/twisty-expanded.svg (../../shared/icons/twisty-expanded.svg)
|
||||
skin/classic/global/icons/arrow-dropdown-12.svg (../../shared/icons/arrow-dropdown-12.svg)
|
||||
skin/classic/global/icons/arrow-dropdown-16.svg (../../shared/icons/arrow-dropdown-16.svg)
|
||||
skin/classic/global/icons/warning.svg (../../shared/icons/warning.svg)
|
||||
|
208
toolkit/themes/shared/tree.inc.css
Normal file
@ -0,0 +1,208 @@
|
||||
/* 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/. */
|
||||
|
||||
/* ===== tree.css ===================================================
|
||||
== Styles used by the XUL tree element.
|
||||
======================================================================= */
|
||||
|
||||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
|
||||
/* ::::: tree ::::: */
|
||||
|
||||
tree {
|
||||
margin: 0 4px;
|
||||
background-color: -moz-Field;
|
||||
color: -moz-FieldText;
|
||||
-moz-appearance: listbox;
|
||||
}
|
||||
|
||||
/* ::::: tree focusring ::::: */
|
||||
|
||||
.focusring > .tree-stack > .tree-rows > .tree-bodybox {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.focusring:focus > .tree-stack > .tree-rows > .tree-bodybox {
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: tree rows ::::: */
|
||||
|
||||
treechildren::-moz-tree-row {
|
||||
border: 1px solid transparent;
|
||||
min-height: 24px;
|
||||
height: 1.3em;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(multicol, odd) {
|
||||
background-color: -moz-oddtreerow;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(selected) {
|
||||
background-color: -moz-cellhighlight;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-row(selected, focus) {
|
||||
background-color: Highlight;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: tree cells ::::: */
|
||||
|
||||
treechildren::-moz-tree-cell {
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(selected),
|
||||
treechildren::-moz-tree-twisty(selected),
|
||||
treechildren::-moz-tree-cell-text(selected) {
|
||||
color: -moz-cellhighlighttext;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(selected, focus),
|
||||
treechildren::-moz-tree-twisty(selected, focus),
|
||||
treechildren::-moz-tree-cell-text(selected, focus) {
|
||||
color: HighlightText;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: lines connecting cells ::::: */
|
||||
|
||||
treechildren::-moz-tree-line {
|
||||
border: 1px dotted ThreeDShadow;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-line(selected, focus) {
|
||||
border: 1px dotted HighlightText;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: tree separator ::::: */
|
||||
|
||||
treechildren::-moz-tree-separator {
|
||||
border-top: 1px solid ThreeDShadow;
|
||||
border-bottom: 1px solid ThreeDHighlight;
|
||||
}
|
||||
|
||||
|
||||
/* ::::: drop feedback ::::: */
|
||||
|
||||
treechildren::-moz-tree-cell-text(primary, dropOn) {
|
||||
background-color: Highlight;
|
||||
color: HighlightText;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-drop-feedback {
|
||||
background-color: Highlight;
|
||||
width: 50px;
|
||||
height: 2px;
|
||||
margin-inline-start: 5px;
|
||||
}
|
||||
|
||||
/* ::::: tree columns ::::: */
|
||||
|
||||
treecol,
|
||||
treecolpicker {
|
||||
-moz-appearance: treeheadercell;
|
||||
-moz-box-align: center;
|
||||
-moz-box-pack: center;
|
||||
color: -moz-DialogText;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.treecol-image {
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
.treecol-text {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
treecol[hideheader="true"] {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
/* ::::: column drag and drop styles ::::: */
|
||||
|
||||
treecol[dragging="true"] {
|
||||
color: Graytext;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-column(insertbefore) {
|
||||
border-inline-start: 1px solid ThreeDShadow;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-column(insertafter) {
|
||||
border-inline-end: 1px solid ThreeDShadow;
|
||||
}
|
||||
|
||||
/* ::::: column picker ::::: */
|
||||
|
||||
.tree-columnpicker-icon {
|
||||
list-style-image: url("chrome://global/skin/tree/columnpicker.gif");
|
||||
}
|
||||
|
||||
/* ::::: tree icons ::::: */
|
||||
|
||||
treechildren::-moz-tree-image {
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* ::::: twisty ::::: */
|
||||
|
||||
treechildren::-moz-tree-twisty {
|
||||
padding-inline-end: 4px;
|
||||
padding-inline-start: 4px;
|
||||
padding-top: 1px;
|
||||
width: 8px; /* The image's width is 8 pixels */
|
||||
list-style-image: url("chrome://global/skin/icons/twisty-collapsed.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(closed) {
|
||||
list-style-image: url("chrome://global/skin/icons/twisty-collapsed-rtl.svg");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-twisty(open) {
|
||||
list-style-image: url("chrome://global/skin/icons/twisty-expanded.svg");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-indentation {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
/* ::::: editable tree ::::: */
|
||||
|
||||
treechildren::-moz-tree-row(selected, editing) {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(selected, editing) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell(active, selected, focus, editing) {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-cell-text(active, selected, editing) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.tree-input {
|
||||
-moz-appearance: none;
|
||||
border: 1px solid Highlight;
|
||||
margin: 0;
|
||||
margin-inline-start: -4px;
|
||||
padding: 1px;
|
||||
}
|