Merge autoland to m-c. a=merge
Merge autoland to m-c. a=merge
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1695,16 +1695,21 @@ pref("browser.crashReports.unsubmittedCh
#ifdef NIGHTLY_BUILD
pref("extensions.formautofill.available", "on");
#elif MOZ_UPDATE_CHANNEL == release
pref("extensions.formautofill.available", "staged-rollout");
#else
pref("extensions.formautofill.available", "detect");
#endif
pref("extensions.formautofill.addresses.enabled", true);
+#ifdef NIGHTLY_BUILD
+pref("extensions.formautofill.creditCards.available", true);
+#else
+pref("extensions.formautofill.creditCards.available", false);
+#endif
pref("extensions.formautofill.creditCards.enabled", true);
pref("extensions.formautofill.firstTimeUse", true);
pref("extensions.formautofill.heuristics.enabled", true);
pref("extensions.formautofill.loglevel", "Warn");
// Whether or not to restore a session with lazy-browser tabs.
pref("browser.sessionstore.restore_tabs_lazily", true);
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -541,16 +541,29 @@ toolbar:not(#TabsToolbar) > #personal-bo
width: 1px;
min-width: 1px;
}
#urlbar {
-moz-binding: url(chrome://browser/content/urlbarBindings.xml#urlbar);
}
+/* Display URLs left-to-right but right aligned in RTL mode. */
+html|input.urlbar-input:-moz-locale-dir(rtl) {
+ direction: ltr !important;
+ text-align: right !important;
+}
+
+/* Make sure that the location bar's alignment in RTL mode changes according
+ to the input box direction if the user switches the text direction using
+ cmd_switchTextDirection (which applies a dir attribute to the <input>). */
+html|input.urlbar-input[dir=ltr]:-moz-locale-dir(rtl) {
+ text-align: left !important;
+}
+
/*
* Display visual cue that browser is under remote control by Marionette.
* This is to help users visually distinguish a user agent session that
* is under remote control from those used for normal browsing sessions.
*
* Attribute is controlled by browser.js:/gRemoteControl.
*/
#main-window[remotecontrol] #urlbar {
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -32,17 +32,17 @@ file, You can obtain one at http://mozil
<children includes="image|deck|stack|box">
<xul:image class="autocomplete-icon" allowevents="true"/>
</children>
<xul:hbox anonid="textbox-input-box"
class="textbox-input-box urlbar-input-box"
flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
<children/>
<html:input anonid="input"
- class="autocomplete-textbox urlbar-input textbox-input uri-element-right-align"
+ class="autocomplete-textbox urlbar-input textbox-input"
allowevents="true"
inputmode="url"
xbl:inherits="tooltiptext=inputtooltiptext,value,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,focused,textoverflow"/>
</xul:hbox>
<xul:image anonid="urlbar-go-button"
class="urlbar-go-button urlbar-icon"
onclick="gURLBar.handleCommand(event);"
tooltiptext="&goEndCap.tooltip;"
--- a/browser/components/customizableui/SearchWidgetTracker.jsm
+++ b/browser/components/customizableui/SearchWidgetTracker.jsm
@@ -31,20 +31,25 @@ const SearchWidgetTracker = {
this.onWidgetReset = this.onWidgetUndoMove = node => {
if (node.id == WIDGET_ID) {
this.syncPreferenceWithWidget();
}
};
CustomizableUI.addListener(this);
Services.prefs.addObserver(PREF_NAME,
() => this.syncWidgetWithPreference());
+ },
+ onAreaNodeRegistered(aArea) {
// The placement of the widget always takes priority, and the preference
- // should always match the actual placement when the browser starts up.
- this.syncPreferenceWithWidget();
+ // should always match the actual placement when the browser starts up - i.e.
+ // once the navigation bar has been registered.
+ if (aArea == CustomizableUI.AREA_NAVBAR) {
+ this.syncPreferenceWithWidget();
+ }
},
onCustomizeEnd() {
// onWidgetUndoMove does not fire when the search container is moved back to
// the customization palette as a result of an undo, so we sync again here.
this.syncPreferenceWithWidget();
},
--- a/browser/components/extensions/ext-c-devtools-panels.js
+++ b/browser/components/extensions/ext-c-devtools-panels.js
@@ -217,16 +217,25 @@ class ChildDevToolsInspectorSidebar exte
setObject(jsonObject, rootTitle) {
return context.cloneScope.Promise.resolve().then(() => {
return context.childManager.callParentAsyncFunction(
"devtools.panels.elements.Sidebar.setObject",
[id, jsonObject, rootTitle]
);
});
},
+
+ setExpression(evalExpression, rootTitle) {
+ return context.cloneScope.Promise.resolve().then(() => {
+ return context.childManager.callParentAsyncFunction(
+ "devtools.panels.elements.Sidebar.setExpression",
+ [id, evalExpression, rootTitle]
+ );
+ });
+ },
};
}
}
this.devtools_panels = class extends ExtensionAPI {
getAPI(context) {
const themeChangeObserver = ExtensionChildDevToolsUtils.getThemeChangeObserver();
--- a/browser/components/extensions/ext-devtools-inspectedWindow.js
+++ b/browser/components/extensions/ext-devtools-inspectedWindow.js
@@ -1,81 +1,58 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
-/* global getDevToolsTargetForContext */
+// The ext-* files are imported into the same scopes.
+/* import-globals-from ext-devtools.js */
+/* import-globals-from ext-browser.js */
XPCOMUtils.defineLazyModuleGetter(this, "DevToolsShim",
"chrome://devtools-shim/content/DevToolsShim.jsm");
var {
SpreadArgs,
} = ExtensionCommon;
this.devtools_inspectedWindow = class extends ExtensionAPI {
getAPI(context) {
- // Lazily retrieve and store an inspectedWindow actor front per child context.
+ // Lazily retrieved inspectedWindow actor front per child context.
let waitForInspectedWindowFront;
- async function getInspectedWindowFront() {
- // If there is not yet a front instance, then a lazily cloned target for the context is
- // retrieved using the DevtoolsParentContextsManager helper (which is an asynchronous operation,
- // because the first time that the target has been cloned, it is not ready to be used to create
- // the front instance until it is connected to the remote debugger successfully).
- const clonedTarget = await getDevToolsTargetForContext(context);
- return DevToolsShim.createWebExtensionInspectedWindowFront(clonedTarget);
- }
-
- function getToolboxOptions() {
- const options = {};
- const toolbox = context.devToolsToolbox;
- const selectedNode = toolbox.selection;
-
- if (selectedNode && selectedNode.nodeFront) {
- // If there is a selected node in the inspector, we hand over
- // its actor id to the eval request in order to provide the "$0" binding.
- options.toolboxSelectedNodeActorID = selectedNode.nodeFront.actorID;
- }
-
- // Provide the console actor ID to implement the "inspect" binding.
- options.toolboxConsoleActorID = toolbox.target.form.consoleActor;
-
- return options;
- }
// TODO(rpl): retrive a more detailed callerInfo object, like the filename and
// lineNumber of the actual extension called, in the child process.
const callerInfo = {
addonId: context.extension.id,
url: context.extension.baseURI.spec,
};
return {
devtools: {
inspectedWindow: {
async eval(expression, options) {
if (!waitForInspectedWindowFront) {
- waitForInspectedWindowFront = getInspectedWindowFront();
+ waitForInspectedWindowFront = getInspectedWindowFront(context);
}
const front = await waitForInspectedWindowFront;
- const evalOptions = Object.assign({}, options, getToolboxOptions());
+ const evalOptions = Object.assign({}, options, getToolboxEvalOptions(context));
const evalResult = await front.eval(callerInfo, expression, evalOptions);
// TODO(rpl): check for additional undocumented behaviors on chrome
// (e.g. if we should also print error to the console or set lastError?).
return new SpreadArgs([evalResult.value, evalResult.exceptionInfo]);
},
async reload(options) {
const {ignoreCache, userAgent, injectedScript} = options || {};
if (!waitForInspectedWindowFront) {
- waitForInspectedWindowFront = getInspectedWindowFront();
+ waitForInspectedWindowFront = getInspectedWindowFront(context);
}
const front = await waitForInspectedWindowFront;
front.reload(callerInfo, {ignoreCache, userAgent, injectedScript});
},
},
},
};
--- a/browser/components/extensions/ext-devtools-panels.js
+++ b/browser/components/extensions/ext-devtools-panels.js
@@ -439,16 +439,27 @@ class ParentDevToolsInspectorSidebar {
}
}
}
const sidebarsById = new Map();
this.devtools_panels = class extends ExtensionAPI {
getAPI(context) {
+ // Lazily retrieved inspectedWindow actor front per child context
+ // (used by Sidebar.setExpression).
+ let waitForInspectedWindowFront;
+
+ // TODO(rpl): retrive a more detailed callerInfo object, like the filename and
+ // lineNumber of the actual extension called, in the child process.
+ const callerInfo = {
+ addonId: context.extension.id,
+ url: context.extension.baseURI.spec,
+ };
+
// An incremental "per context" id used in the generated devtools panel id.
let nextPanelId = 0;
const toolboxSelectionObserver = new DevToolsSelectionObserver(context);
function newBasePanelId() {
return `${context.extension.id}-${context.contextId}-${nextPanelId++}`;
}
@@ -487,16 +498,37 @@ this.devtools_panels = class extends Ext
// The following methods are used internally to allow the sidebar API
// piece that is running in the child process to asks the parent process
// to execute the sidebar methods.
Sidebar: {
setObject(sidebarId, jsonObject, rootTitle) {
const sidebar = sidebarsById.get(sidebarId);
return sidebar.setObject(jsonObject, rootTitle);
},
+ async setExpression(sidebarId, evalExpression, rootTitle) {
+ const sidebar = sidebarsById.get(sidebarId);
+
+ if (!waitForInspectedWindowFront) {
+ waitForInspectedWindowFront = getInspectedWindowFront(context);
+ }
+
+ const front = await waitForInspectedWindowFront;
+ const evalOptions = Object.assign({}, getToolboxEvalOptions(context));
+ const evalResult = await front.eval(callerInfo, evalExpression, evalOptions);
+
+ let jsonObject;
+
+ if (evalResult.exceptionInfo) {
+ jsonObject = evalResult.exceptionInfo;
+ } else {
+ jsonObject = evalResult.value;
+ }
+
+ return sidebar.setObject(jsonObject, rootTitle);
+ },
},
},
create(title, icon, url) {
// Get a fallback icon from the manifest data.
if (icon === "" && context.extension.manifest.icons) {
const iconInfo = IconDetails.getPreferredIcon(context.extension.manifest.icons,
context.extension, 128);
icon = iconInfo ? iconInfo.icon : "";
--- a/browser/components/extensions/ext-devtools.js
+++ b/browser/components/extensions/ext-devtools.js
@@ -1,14 +1,14 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
-/* exported getDevToolsTargetForContext */
-/* global getTargetTabIdForToolbox, getDevToolsTargetForContext */
+/* exported getDevToolsTargetForContext, getInspectedWindowFront, getToolboxEvalOptions */
+/* global getTargetTabIdForToolbox, getDevToolsTargetForContext, getInspectedWindowFront, getToolboxEvalOptions */
// The ext-* files are imported into the same scopes.
/* import-globals-from ext-browser.js */
/**
* This module provides helpers used by the other specialized `ext-devtools-*.js` modules
* and the implementation of the `devtools_page`.
*/
@@ -80,16 +80,46 @@ global.getTargetTabIdForToolbox = (toolb
}
let parentWindow = target.tab.linkedBrowser.ownerGlobal;
let tab = parentWindow.gBrowser.getTabForBrowser(target.tab.linkedBrowser);
return tabTracker.getId(tab);
};
+// Create an InspectedWindowFront instance for a given context (used in devtoools.inspectedWindow.eval
+// and in sidebar.setExpression API methods).
+global.getInspectedWindowFront = async function(context) {
+ // If there is not yet a front instance, then a lazily cloned target for the context is
+ // retrieved using the DevtoolsParentContextsManager helper (which is an asynchronous operation,
+ // because the first time that the target has been cloned, it is not ready to be used to create
+ // the front instance until it is connected to the remote debugger successfully).
+ const clonedTarget = await getDevToolsTargetForContext(context);
+ return DevToolsShim.createWebExtensionInspectedWindowFront(clonedTarget);
+};
+
+// Get the WebExtensionInspectedWindowActor eval options (needed to provide the $0 and inspect
+// binding provided to the evaluated js code).
+global.getToolboxEvalOptions = function(context) {
+ const options = {};
+ const toolbox = context.devToolsToolbox;
+ const selectedNode = toolbox.selection;
+
+ if (selectedNode && selectedNode.nodeFront) {
+ // If there is a selected node in the inspector, we hand over
+ // its actor id to the eval request in order to provide the "$0" binding.
+ options.toolboxSelectedNodeActorID = selectedNode.nodeFront.actorID;
+ }
+
+ // Provide the console actor ID to implement the "inspect" binding.
+ options.toolboxConsoleActorID = toolbox.target.form.consoleActor;
+
+ return options;
+};
+
/**
* The DevToolsPage represents the "devtools_page" related to a particular
* Toolbox and WebExtension.
*
* The devtools_page contexts are invisible WebExtensions contexts, similar to the
* background page, associated to a single developer toolbox (e.g. If an add-on
* registers a devtools_page and the user opens 3 developer toolbox in 3 webpages,
* 3 devtools_page contexts will be created for that add-on).
--- a/browser/components/extensions/schemas/devtools_panels.json
+++ b/browser/components/extensions/schemas/devtools_panels.json
@@ -175,17 +175,16 @@
"name": "height",
"type": "string",
"description": "A CSS-like size specification, such as <code>'100px'</code> or <code>'12ex'</code>."
}
]
},
{
"name": "setExpression",
- "unsupported": true,
"async": "callback",
"type": "function",
"description": "Sets an expression that is evaluated within the inspected page. The result is displayed in the sidebar pane.",
"parameters": [
{
"name": "expression",
"type": "string",
"description": "An expression to be evaluated in context of the inspected page. JavaScript objects and DOM nodes are displayed in an expandable tree similar to the console/watch."
--- a/browser/components/extensions/test/browser/browser_ext_devtools_inspectedWindow_eval_bindings.js
+++ b/browser/components/extensions/test/browser/browser_ext_devtools_inspectedWindow_eval_bindings.js
@@ -133,16 +133,44 @@ add_task(async function test_devtools_in
resolve(m.node);
jsterm.hud.off("new-messages", onThisMessage);
return;
}
});
});
let objectInspectors = [...messageNode.querySelectorAll(".tree")];
is(objectInspectors.length, 1, "There is the expected number of object inspectors");
+
+ // We need to wait for the object to be expanded so we don't call the server on a closed connection.
+ const [oi] = objectInspectors;
+ let nodes = oi.querySelectorAll(".node");
+
+ ok(nodes.length >= 1, "The object preview is rendered as expected");
+
+ // The tree can still be collapsed since the properties are fetched asynchronously.
+ if (nodes.length === 1) {
+ info("Waiting for the object properties to be displayed");
+ // If this is the case, we wait for the properties to be fetched and displayed.
+ await new Promise(resolve => {
+ const observer = new MutationObserver(mutations => {
+ resolve();
+ observer.disconnect();
+ });
+ observer.observe(oi, {childList: true});
+ });
+
+ // Retrieve the new nodes.
+ nodes = oi.querySelectorAll(".node");
+ }
+
+ // We should have 3 nodes :
+ // ▼ Object { testkey: "testvalue" }
+ // | testkey: "testvalue"
+ // | ▶︎ __proto__: Object { … }
+ is(nodes.length, 3, "The object preview has the expected number of nodes");
} else {
const options = await new Promise(resolve => {
jsterm.once("variablesview-open", (evt, view, options) => resolve(options));
});
const objectType = options.objectActor.type;
const objectPreviewProperties = options.objectActor.preview.ownProperties;
is(objectType, "object", "The inspected object has the expected type");
--- a/browser/components/extensions/test/browser/browser_ext_devtools_panels_elements_sidebar.js
+++ b/browser/components/extensions/test/browser/browser_ext_devtools_panels_elements_sidebar.js
@@ -1,41 +1,52 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools",
"resource://devtools/client/framework/gDevTools.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "devtools",
"resource://devtools/shared/Loader.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ContentTaskUtils",
+ "resource://testing-common/ContentTaskUtils.jsm");
function isActiveSidebarTabTitle(inspector, expectedTabTitle, message) {
const actualTabTitle = inspector.panelDoc.querySelector(".tabs-menu-item.is-active").innerText;
is(actualTabTitle, expectedTabTitle, message);
}
add_task(async function test_devtools_panels_elements_sidebar() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");
async function devtools_page() {
const sidebar1 = await browser.devtools.panels.elements.createSidebarPane("Test Sidebar 1");
const sidebar2 = await browser.devtools.panels.elements.createSidebarPane("Test Sidebar 2");
+ const sidebar3 = await browser.devtools.panels.elements.createSidebarPane("Test Sidebar 3");
const onShownListener = (event, sidebarInstance) => {
browser.test.sendMessage(`devtools_sidebar_${event}`, sidebarInstance);
};
sidebar1.onShown.addListener(() => onShownListener("shown", "sidebar1"));
sidebar2.onShown.addListener(() => onShownListener("shown", "sidebar2"));
+ sidebar3.onShown.addListener(() => onShownListener("shown", "sidebar3"));
+
sidebar1.onHidden.addListener(() => onShownListener("hidden", "sidebar1"));
sidebar2.onHidden.addListener(() => onShownListener("hidden", "sidebar2"));
+ sidebar3.onHidden.addListener(() => onShownListener("hidden", "sidebar3"));
sidebar1.setObject({propertyName: "propertyValue"}, "Optional Root Object Title");
sidebar2.setObject({anotherPropertyName: 123});
+ // Refresh the sidebar content on every inspector selection.
+ browser.devtools.panels.elements.onSelectionChanged.addListener(() => {
+ sidebar3.setExpression("$0 && $0.tagName", "Selected Element tagName");
+ });
+
browser.test.sendMessage("devtools_page_loaded");
}
let extension = ExtensionTestUtils.loadExtension({
manifest: {
devtools_page: "devtools_page.html",
},
files: {
@@ -110,25 +121,59 @@ add_task(async function test_devtools_pa
ok(sidebarPanel2, "Got a rendered sidebar panel for the second registered extension sidebar");
is(sidebarPanel2.querySelectorAll("table.treeTable").length, 1,
"The second sidebar panel contains a rendered TreeView component");
is(sidebarPanel2.querySelectorAll("table.treeTable .numberCell").length, 1,
"The TreeView component contains the expected a cell of type number.");
+ inspector.sidebar.show(sidebarIds[2]);
+
+ const shownSidebarInstance3 = await extension.awaitMessage("devtools_sidebar_shown");
+ const hiddenSidebarInstance2 = await extension.awaitMessage("devtools_sidebar_hidden");
+
+ is(shownSidebarInstance3, "sidebar3", "Got the shown event on the third extension sidebar");
+ is(hiddenSidebarInstance2, "sidebar2", "Got the hidden event on the second extension sidebar");
+
+ isActiveSidebarTabTitle(inspector, "Test Sidebar 3",
+ "Got the expected title on the active sidebar tab");
+
+ const sidebarPanel3 = inspector.sidebar.getTabPanel(sidebarIds[2]);
+
+ ok(sidebarPanel3, "Got a rendered sidebar panel for the third registered extension sidebar");
+
+ info("Waiting for the third panel to be rendered");
+ await ContentTaskUtils.waitForCondition(() => {
+ return sidebarPanel3.querySelectorAll("table.treeTable").length > 0;
+ });
+
+ is(sidebarPanel3.querySelectorAll("table.treeTable").length, 1,
+ "The third sidebar panel contains a rendered TreeView component");
+
+ const treeViewStringValues = sidebarPanel3.querySelectorAll("table.treeTable .stringCell");
+
+ is(treeViewStringValues.length, 1,
+ "The TreeView component contains the expected content of type string.");
+
+ is(treeViewStringValues[0].innerText, "\"BODY\"",
+ "Got the expected content in the sidebar.setExpression rendered TreeView");
+
await extension.unload();
is(Array.from(toolbox._inspectorExtensionSidebars.keys()).length, 0,
"All the registered sidebars have been unregistered on extension unload");
is(inspector.sidebar.getTabPanel(sidebarIds[0]), undefined,
"The first registered sidebar has been removed");
is(inspector.sidebar.getTabPanel(sidebarIds[1]), undefined,
"The second registered sidebar has been removed");
+ is(inspector.sidebar.getTabPanel(sidebarIds[2]), undefined,
+ "The third registered sidebar has been removed");
+
await gDevTools.closeToolbox(target);
await target.destroy();
await BrowserTestUtils.removeTab(tab);
});
--- a/browser/extensions/formautofill/FormAutofillParent.jsm
+++ b/browser/extensions/formautofill/FormAutofillParent.jsm
@@ -83,27 +83,31 @@ FormAutofillParent.prototype = {
/**
* Initializes ProfileStorage and registers the message handler.
*/
async init() {
Services.obs.addObserver(this, "sync-pane-loaded");
Services.ppmm.addMessageListener("FormAutofill:InitStorage", this);
Services.ppmm.addMessageListener("FormAutofill:GetRecords", this);
Services.ppmm.addMessageListener("FormAutofill:SaveAddress", this);
- Services.ppmm.addMessageListener("FormAutofill:SaveCreditCard", this);
Services.ppmm.addMessageListener("FormAutofill:RemoveAddresses", this);
- Services.ppmm.addMessageListener("FormAutofill:RemoveCreditCards", this);
Services.ppmm.addMessageListener("FormAutofill:OpenPreferences", this);
- Services.ppmm.addMessageListener("FormAutofill:GetDecryptedString", this);
Services.mm.addMessageListener("FormAutofill:OnFormSubmit", this);
// Observing the pref and storage changes
Services.prefs.addObserver(ENABLED_AUTOFILL_ADDRESSES_PREF, this);
- Services.prefs.addObserver(ENABLED_AUTOFILL_CREDITCARDS_PREF, this);
Services.obs.addObserver(this, "formautofill-storage-changed");
+
+ // Only listen to credit card related messages if it is available
+ if (FormAutofillUtils.isAutofillCreditCardsAvailable) {
+ Services.ppmm.addMessageListener("FormAutofill:SaveCreditCard", this);
+ Services.ppmm.addMessageListener("FormAutofill:RemoveCreditCards", this);
+ Services.ppmm.addMessageListener("FormAutofill:GetDecryptedString", this);
+ Services.prefs.addObserver(ENABLED_AUTOFILL_CREDITCARDS_PREF, this);
+ }
},
observe(subject, topic, data) {
log.debug("observe:", topic, "with data:", data);
switch (topic) {
case "sync-pane-loaded": {
let formAutofillPreferences = new FormAutofillPreferences();
let document = subject.document;
@@ -243,22 +247,26 @@ FormAutofillParent.prototype = {
* @private
*/
_uninit() {
this.profileStorage._saveImmediately();
Services.ppmm.removeMessageListener("FormAutofill:InitStorage", this);
Services.ppmm.removeMessageListener("FormAutofill:GetRecords", this);
Services.ppmm.removeMessageListener("FormAutofill:SaveAddress", this);
- Services.ppmm.removeMessageListener("FormAutofill:SaveCreditCard", this);
Services.ppmm.removeMessageListener("FormAutofill:RemoveAddresses", this);
- Services.ppmm.removeMessageListener("FormAutofill:RemoveCreditCards", this);
Services.obs.removeObserver(this, "sync-pane-loaded");
Services.prefs.removeObserver(ENABLED_AUTOFILL_ADDRESSES_PREF, this);
- Services.prefs.removeObserver(ENABLED_AUTOFILL_CREDITCARDS_PREF, this);
+
+ if (FormAutofillUtils.isAutofillCreditCardsAvailable) {
+ Services.ppmm.removeMessageListener("FormAutofill:SaveCreditCard", this);
+ Services.ppmm.removeMessageListener("FormAutofill:RemoveCreditCards", this);
+ Services.ppmm.removeMessageListener("FormAutofill:GetDecryptedString", this);
+ Services.prefs.removeObserver(ENABLED_AUTOFILL_CREDITCARDS_PREF, this);
+ }
},
/**
* Get the records from profile store and return results back to content
* process. It will decrypt the credit card number and append
* "cc-number-decrypted" to each record if MasterPassword isn't set.
*
* @private
--- a/browser/extensions/formautofill/FormAutofillPreferences.jsm
+++ b/browser/extensions/formautofill/FormAutofillPreferences.jsm
@@ -17,17 +17,24 @@ const BUNDLE_URI = "chrome://formautofil
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";
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
-const {ENABLED_AUTOFILL_ADDRESSES_PREF, ENABLED_AUTOFILL_CREDITCARDS_PREF} = FormAutofillUtils;
+const {
+ ENABLED_AUTOFILL_ADDRESSES_PREF,
+ ENABLED_AUTOFILL_CREDITCARDS_PREF,
+ MANAGE_ADDRESSES_KEYWORDS,
+ EDIT_ADDRESS_KEYWORDS,
+ MANAGE_CREDITCARDS_KEYWORDS,
+ EDIT_CREDITCARD_KEYWORDS,
+} = FormAutofillUtils;
// Add credit card enabled flag in telemetry environment for recording the number of
// users who disable/enable the credit card autofill feature.
this.log = null;
FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
function FormAutofillPreferences() {
this.bundle = Services.strings.createBundle(BUNDLE_URI);
@@ -56,79 +63,103 @@ FormAutofillPreferences.prototype = {
},
/**
* Create Form Autofill preference group
*
* @param {XULDocument} document
*/
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, "description");
let addressAutofillCheckbox = document.createElementNS(XUL_NS, "checkbox");
let addressAutofillLearnMore = document.createElementNS(XUL_NS, "label");
let savedAddressesBtn = document.createElementNS(XUL_NS, "button");
- let creditCardAutofill = document.createElementNS(XUL_NS, "hbox");
- let creditCardAutofillCheckboxGroup = document.createElementNS(XUL_NS, "description");
- let creditCardAutofillCheckbox = document.createElementNS(XUL_NS, "checkbox");
- let creditCardAutofillLearnMore = document.createElementNS(XUL_NS, "label");
- let savedCreditCardsBtn = document.createElementNS(XUL_NS, "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");
savedAddressesBtn.className = "accessory-button";
- savedCreditCardsBtn.className = "accessory-button";
addressAutofillLearnMore.className = "learnMore text-link";
- creditCardAutofillLearnMore.className = "learnMore text-link";
+
+ formAutofillGroup.id = "formAutofillGroup";
+ addressAutofill.id = "addressAutofill";
+ addressAutofillLearnMore.id = "addressAutofillLearnMore";
+
+ addressAutofillLearnMore.setAttribute("value", this.bundle.GetStringFromName("learnMore"));
+ addressAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("enableAddressAutofill"));
+ savedAddressesBtn.setAttribute("label", this.bundle.GetStringFromName("savedAddresses"));
+
+ addressAutofillLearnMore.setAttribute("href", learnMoreURL);
+
+ // Add preferences search support
+ savedAddressesBtn.setAttribute("searchkeywords", MANAGE_ADDRESSES_KEYWORDS.concat(EDIT_ADDRESS_KEYWORDS)
+ .map(key => this.bundle.GetStringFromName(key)).join("\n"));
+
+ // Manually set the checked state
+ if (FormAutofillUtils.isAutofillAddressesEnabled) {
+ addressAutofillCheckbox.setAttribute("checked", true);
+ }
+
+ addressAutofillCheckboxGroup.flex = 1;
+
+ formAutofillGroup.appendChild(addressAutofill);
+ addressAutofill.appendChild(addressAutofillCheckboxGroup);
+ addressAutofillCheckboxGroup.appendChild(addressAutofillCheckbox);
+ addressAutofillCheckboxGroup.appendChild(addressAutofillLearnMore);
+ addressAutofill.appendChild(savedAddressesBtnWrapper);
+ savedAddressesBtnWrapper.appendChild(savedAddressesBtn);
this.refs = {
formAutofillGroup,
addressAutofillCheckbox,
savedAddressesBtn,
- creditCardAutofillCheckbox,
- savedCreditCardsBtn,
};
- formAutofillGroup.id = "formAutofillGroup";
- addressAutofill.id = "addressAutofill";
- addressAutofillLearnMore.id = "addressAutofillLearnMore";
- creditCardAutofill.id = "creditCardAutofill";
- creditCardAutofillLearnMore.id = "creditCardAutofillLearnMore";
+ if (FormAutofillUtils.isAutofillCreditCardsAvailable) {
+ let creditCardAutofill = document.createElementNS(XUL_NS, "hbox");
+ let creditCardAutofillCheckboxGroup = document.createElementNS(XUL_NS, "description");
+ let creditCardAutofillCheckbox = document.createElementNS(XUL_NS, "checkbox");
+ let creditCardAutofillLearnMore = document.createElementNS(XUL_NS, "label");
+ let savedCreditCardsBtn = document.createElementNS(XUL_NS, "button");
+ savedCreditCardsBtn.className = "accessory-button";
+ creditCardAutofillLearnMore.className = "learnMore text-link";
- addressAutofillLearnMore.setAttribute("value", this.bundle.GetStringFromName("learnMore"));
- addressAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("enableAddressAutofill"));
- savedAddressesBtn.setAttribute("label", this.bundle.GetStringFromName("savedAddresses"));
- creditCardAutofillLearnMore.setAttribute("value", this.bundle.GetStringFromName("learnMore"));
- creditCardAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("enableCreditCardAutofill"));
- savedCreditCardsBtn.setAttribute("label", this.bundle.GetStringFromName("savedCreditCards"));
+ creditCardAutofill.id = "creditCardAutofill";
+ creditCardAutofillLearnMore.id = "creditCardAutofillLearnMore";
- let learnMoreURL = Services.urlFormatter.formatURLPref("app.support.baseURL") + "autofill-card-address";
- addressAutofillLearnMore.setAttribute("href", learnMoreURL);
- creditCardAutofillLearnMore.setAttribute("href", learnMoreURL);
+ creditCardAutofillLearnMore.setAttribute("value", this.bundle.GetStringFromName("learnMore"));
+ creditCardAutofillCheckbox.setAttribute("label", this.bundle.GetStringFromName("enableCreditCardAutofill"));
+ savedCreditCardsBtn.setAttribute("label", this.bundle.GetStringFromName("savedCreditCards"));
+
+ creditCardAutofillLearnMore.setAttribute("href", learnMoreURL);
- // Manually set the checked state
- if (FormAutofillUtils.isAutofillAddressesEnabled) {
- addressAutofillCheckbox.setAttribute("checked", true);
- }
- if (FormAutofillUtils.isAutofillCreditCardsEnabled) {
- creditCardAutofillCheckbox.setAttribute("checked", true);
- }
+ // Add preferences search support
+ savedCreditCardsBtn.setAttribute("searchkeywords", MANAGE_CREDITCARDS_KEYWORDS.concat(EDIT_CREDITCARD_KEYWORDS)
+ .map(key => this.bundle.GetStringFromName(key)).join("\n"));
- addressAutofillCheckboxGroup.flex = 1;
- creditCardAutofillCheckboxGroup.flex = 1;
+ // Manually set the checked state
+ if (FormAutofillUtils.isAutofillCreditCardsEnabled) {
+ creditCardAutofillCheckbox.setAttribute("checked", true);
+ }
+
+ creditCardAutofillCheckboxGroup.flex = 1;
- formAutofillGroup.appendChild(addressAutofill);
- addressAutofill.appendChild(addressAutofillCheckboxGroup);
- addressAutofillCheckboxGroup.appendChild(addressAutofillCheckbox);
- addressAutofillCheckboxGroup.appendChild(addressAutofillLearnMore);
- addressAutofill.appendChild(savedAddressesBtn);
- formAutofillGroup.appendChild(creditCardAutofill);
- creditCardAutofill.appendChild(creditCardAutofillCheckboxGroup);
- creditCardAutofillCheckboxGroup.appendChild(creditCardAutofillCheckbox);
- creditCardAutofillCheckboxGroup.appendChild(creditCardAutofillLearnMore);
- creditCardAutofill.appendChild(savedCreditCardsBtn);
+ formAutofillGroup.appendChild(creditCardAutofill);
+ creditCardAutofill.appendChild(creditCardAutofillCheckboxGroup);
+ creditCardAutofillCheckboxGroup.appendChild(creditCardAutofillCheckbox);
+ creditCardAutofillCheckboxGroup.appendChild(creditCardAutofillLearnMore);
+ creditCardAutofill.appendChild(savedCreditCardsBtnWrapper);
+ savedCreditCardsBtnWrapper.appendChild(savedCreditCardsBtn);
+
+ this.refs.creditCardAutofillCheckbox = creditCardAutofillCheckbox;
+ this.refs.savedCreditCardsBtn = savedCreditCardsBtn;
+ }
},
/**
* Handle events
*
* @param {DOMEvent} event
*/
handleEvent(event) {
--- a/browser/extensions/formautofill/FormAutofillUtils.jsm
+++ b/browser/extensions/formautofill/FormAutofillUtils.jsm
@@ -14,29 +14,42 @@ const ADDRESS_REFERENCES = "chrome://for
// bug 1370193.
const ALTERNATIVE_COUNTRY_NAMES = {
"US": ["US", "United States of America", "United States", "America", "U.S.", "USA", "U.S.A.", "U.S.A"],
};
const ADDRESSES_COLLECTION_NAME = "addresses";
const CREDITCARDS_COLLECTION_NAME = "creditCards";
const ENABLED_AUTOFILL_ADDRESSES_PREF = "extensions.formautofill.addresses.enabled";
+const AUTOFILL_CREDITCARDS_AVAILABLE_PREF = "extensions.formautofill.creditCards.available";
const ENABLED_AUTOFILL_CREDITCARDS_PREF = "extensions.formautofill.creditCards.enabled";
+const MANAGE_ADDRESSES_KEYWORDS = ["manageAddressesTitle", "addNewAddressTitle"];
+const EDIT_ADDRESS_KEYWORDS = [
+ "givenName", "additionalName", "familyName", "organization", "streetAddress",
+ "state", "province", "city", "country", "zip", "postalCode", "email", "tel",
+];
+const MANAGE_CREDITCARDS_KEYWORDS = ["manageCreditCardsTitle", "addNewCreditCardTitle", "showCreditCards"];
+const EDIT_CREDITCARD_KEYWORDS = ["cardNumber", "nameOnCard", "cardExpires"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
this.FormAutofillUtils = {
get AUTOFILL_FIELDS_THRESHOLD() { return 3; },
get isAutofillEnabled() { return this.isAutofillAddressesEnabled || this.isAutofillCreditCardsEnabled; },
+ get isAutofillCreditCardsEnabled() { return this.isAutofillCreditCardsAvailable && this._isAutofillCreditCardsEnabled; },
ADDRESSES_COLLECTION_NAME,
CREDITCARDS_COLLECTION_NAME,
ENABLED_AUTOFILL_ADDRESSES_PREF,
ENABLED_AUTOFILL_CREDITCARDS_PREF,
+ MANAGE_ADDRESSES_KEYWORDS,
+ EDIT_ADDRESS_KEYWORDS,
+ MANAGE_CREDITCARDS_KEYWORDS,
+ EDIT_CREDITCARD_KEYWORDS,
_fieldNameInfo: {
"name": "name",
"given-name": "name",
"additional-name": "name",
"family-name": "name",
"organization": "organization",
"street-address": "address",
@@ -521,9 +534,11 @@ this.FormAutofillUtils.defineLazyLogGett
XPCOMUtils.defineLazyGetter(FormAutofillUtils, "stringBundle", function() {
return Services.strings.createBundle("chrome://formautofill/locale/formautofill.properties");
});
XPCOMUtils.defineLazyPreferenceGetter(this.FormAutofillUtils,
"isAutofillAddressesEnabled", ENABLED_AUTOFILL_ADDRESSES_PREF);
XPCOMUtils.defineLazyPreferenceGetter(this.FormAutofillUtils,
- "isAutofillCreditCardsEnabled", ENABLED_AUTOFILL_CREDITCARDS_PREF);
+ "isAutofillCreditCardsAvailable", AUTOFILL_CREDITCARDS_AVAILABLE_PREF);
+XPCOMUtils.defineLazyPreferenceGetter(this.FormAutofillUtils,
+ "_isAutofillCreditCardsEnabled", ENABLED_AUTOFILL_CREDITCARDS_PREF);
--- a/browser/extensions/formautofill/content/manageAddresses.xhtml
+++ b/browser/extensions/formautofill/content/manageAddresses.xhtml
@@ -12,17 +12,20 @@
</head>
<body>
<fieldset>
<legend data-localization="addressesListHeader"/>
<select id="addresses" size="9" multiple="multiple"/>
</fieldset>
<div id="controls-container">
<button id="remove" disabled="disabled" data-localization="remove"/>
- <button id="add" data-localization="add"/>
+ <!-- Wrapper is used to properly compute the search tooltip position -->
+ <div>
+ <button id="add" data-localization="add"/>
+ </div>
<button id="edit" disabled="disabled" data-localization="edit"/>
</div>
<script type="application/javascript">
"use strict";
/* global ManageAddresses */
new ManageAddresses({
records: document.getElementById("addresses"),
controlsContainer: document.getElementById("controls-container"),
--- a/browser/extensions/formautofill/content/manageCreditCards.xhtml
+++ b/browser/extensions/formautofill/content/manageCreditCards.xhtml
@@ -13,17 +13,20 @@
<body>
<fieldset>
<legend data-localization="creditCardsListHeader"/>
<select id="credit-cards" size="9" multiple="multiple"/>
</fieldset>
<div id="controls-container">
<button id="remove" disabled="disabled" data-localization="remove"/>
<button id="show-hide-credit-cards" data-localization="showCreditCards"/>
- <button id="add" data-localization="add"/>
+ <!-- Wrapper is used to properly compute the search tooltip position -->
+ <div>
+ <button id="add" data-localization="add"/>
+ </div>
<button id="edit" disabled="disabled" data-localization="edit"/>
</div>
<script type="application/javascript">
"use strict";
/* global ManageCreditCards */
new ManageCreditCards({
records: document.getElementById("credit-cards"),
controlsContainer: document.getElementById("controls-container"),
--- a/browser/extensions/formautofill/content/manageDialog.js
+++ b/browser/extensions/formautofill/content/manageDialog.js
@@ -266,16 +266,19 @@ class ManageRecords {
this._elements.controlsContainer.removeEventListener("click", this);
Services.obs.removeObserver(this, "formautofill-storage-changed");
}
}
class ManageAddresses extends ManageRecords {
constructor(elements) {
super("addresses", elements);
+ elements.add.setAttribute("searchkeywords", FormAutofillUtils.EDIT_ADDRESS_KEYWORDS
+ .map(key => FormAutofillUtils.stringBundle.GetStringFromName(key))
+ .join("\n"));
}
/**
* Open the edit address dialog to create/edit an address.
*
* @param {object} address [optional]
*/
openEditDialog(address) {
@@ -322,16 +325,19 @@ class ManageAddresses extends ManageReco
}
return parts.join(", ");
}
}
class ManageCreditCards extends ManageRecords {
constructor(elements) {
super("creditCards", elements);
+ elements.add.setAttribute("searchkeywords", FormAutofillUtils.EDIT_CREDITCARD_KEYWORDS
+ .map(key => FormAutofillUtils.stringBundle.GetStringFromName(key))
+ .join("\n"));
this._hasMasterPassword = MasterPassword.isEnabled;
this._isDecrypted = false;
if (this._hasMasterPassword) {
elements.showHideCreditCards.setAttribute("hidden", true);
}
}
/**
--- a/browser/extensions/formautofill/test/browser/browser_privacyPreferences.js
+++ b/browser/extensions/formautofill/test/browser/browser_privacyPreferences.js
@@ -78,8 +78,22 @@ add_task(async function test_autofillDis
"Form Autofill group should be visible");
is(content.document.querySelector(selectors.addressAutofillCheckbox).checked, false,
"Checkbox should be unchecked when Autofill Addresses is disabled");
is(content.document.querySelector(selectors.creditCardAutofillCheckbox).checked, false,
"Checkbox should be unchecked when Autofill Credit Cards is disabled");
});
});
});
+
+add_task(async function test_creditCardNotAvailable() {
+ SpecialPowers.pushPrefEnv({set: [[AUTOFILL_CREDITCARDS_AVAILABLE_PREF, false]]});
+ let finalPrefPaneLoaded = TestUtils.topicObserved("sync-pane-loaded", () => true);
+ await BrowserTestUtils.withNewTab({gBrowser, url: PAGE_PRIVACY}, async function(browser) {
+ await finalPrefPaneLoaded;
+ await ContentTask.spawn(browser, SELECTORS, (selectors) => {
+ is(content.document.querySelector(selectors.group).hidden, false,
+ "Form Autofill group should be visible");
+ ok(!content.document.querySelector(selectors.creditCardAutofillCheckbox),
+ "Autofill credit cards checkbox should not exist");
+ });
+ });
+});
--- a/browser/extensions/formautofill/test/browser/head.js
+++ b/browser/extensions/formautofill/test/browser/head.js
@@ -1,28 +1,30 @@
/* exported MANAGE_ADDRESSES_DIALOG_URL, MANAGE_CREDIT_CARDS_DIALOG_URL, EDIT_ADDRESS_DIALOG_URL, EDIT_CREDIT_CARD_DIALOG_URL,
BASE_URL, TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3, TEST_ADDRESS_4, TEST_ADDRESS_5,
TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_3, FORM_URL, CREDITCARD_FORM_URL,
- FTU_PREF, ENABLED_AUTOFILL_ADDRESSES_PREF, ENABLED_AUTOFILL_CREDITCARDS_PREF, SYNC_USERNAME_PREF, SYNC_ADDRESSES_PREF,
+ FTU_PREF, ENABLED_AUTOFILL_ADDRESSES_PREF, AUTOFILL_CREDITCARDS_AVAILABLE_PREF, ENABLED_AUTOFILL_CREDITCARDS_PREF,
+ SYNC_USERNAME_PREF, SYNC_ADDRESSES_PREF,
sleep, expectPopupOpen, openPopupOn, expectPopupClose, closePopup, clickDoorhangerButton,
getAddresses, saveAddress, removeAddresses, saveCreditCard,
getDisplayedPopupItems, getDoorhangerCheckbox, waitForMasterPasswordDialog */
"use strict";
const MANAGE_ADDRESSES_DIALOG_URL = "chrome://formautofill/content/manageAddresses.xhtml";
const MANAGE_CREDIT_CARDS_DIALOG_URL = "chrome://formautofill/content/manageCreditCards.xhtml";
const EDIT_ADDRESS_DIALOG_URL = "chrome://formautofill/content/editAddress.xhtml";
const EDIT_CREDIT_CARD_DIALOG_URL = "chrome://formautofill/content/editCreditCard.xhtml";
const BASE_URL = "http://mochi.test:8888/browser/browser/extensions/formautofill/test/browser/";
const FORM_URL = "http://mochi.test:8888/browser/browser/extensions/formautofill/test/browser/autocomplete_basic.html";
const CREDITCARD_FORM_URL =
"http://mochi.test:8888/browser/browser/extensions/formautofill/test/browser/autocomplete_creditcard_basic.html";
const FTU_PREF = "extensions.formautofill.firstTimeUse";
const ENABLED_AUTOFILL_ADDRESSES_PREF = "extensions.formautofill.addresses.enabled";
+const AUTOFILL_CREDITCARDS_AVAILABLE_PREF = "extensions.formautofill.creditCards.available";
const ENABLED_AUTOFILL_CREDITCARDS_PREF = "extensions.formautofill.creditCards.enabled";
const SYNC_USERNAME_PREF = "services.sync.username";
const SYNC_ADDRESSES_PREF = "services.sync.engine.addresses";
const TEST_ADDRESS_1 = {
"given-name": "John",
"additional-name": "R.",
"family-name": "Smith",
--- a/browser/extensions/onboarding/content/onboarding.css
+++ b/browser/extensions/onboarding/content/onboarding.css
@@ -20,17 +20,17 @@
}
#onboarding-overlay.onboarding-opened {
display: block;
}
#onboarding-overlay-button {
padding: 10px 0 0 0;
- position: absolute;
+ position: fixed;
cursor: pointer;
top: 4px;
offset-inline-start: 12px;
border: none;
/* Set to none so no grey contrast background in the high-contrast mode */
background: none;
/* make sure the icon stay above the activity-stream searchbar */
/* We want this always under #onboarding-overlay */
@@ -90,17 +90,17 @@
box-shadow: -2px 0 5px 0 rgba(74, 74, 79, 0.25);
}
#onboarding-overlay-button:dir(rtl)::after {
box-shadow: 2px 0 5px 0 rgba(74, 74, 79, 0.25);
}
#onboarding-overlay-button-watermark-icon,
-#onboarding-overlay-button.onboarding-watermark:not(:hover)::after,
+#onboarding-overlay-button.onboarding-watermark::after,
#onboarding-overlay-button.onboarding-watermark:not(:hover) > #onboarding-overlay-button-icon {
display: none;
}
#onboarding-overlay-button.onboarding-watermark:not(:hover) > #onboarding-overlay-button-watermark-icon {
display: block;
}
--- a/browser/extensions/onboarding/content/onboarding.js
+++ b/browser/extensions/onboarding/content/onboarding.js
@@ -231,17 +231,17 @@ var onboardingTourset = {
button: bundle.GetStringFromName("onboarding.button.learnMore"),
};
},
getPage(win) {
let div = win.document.createElement("div");
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-library.title"></h1>
- <p data-l10n-id="onboarding.tour-library.description"></p>
+ <p data-l10n-id="onboarding.tour-library.description2"></p>
</section>
<section class="onboarding-tour-content">
<img src="resource://onboarding/img/figure_library.svg" role="presentation"/>
</section>
<aside class="onboarding-tour-button-container">
<button id="onboarding-tour-library-button" class="onboarding-tour-action-button" data-l10n-id="onboarding.tour-library.button2"></button>
</aside>
`;
--- a/browser/extensions/onboarding/locales/en-US/onboarding.properties
+++ b/browser/extensions/onboarding/locales/en-US/onboarding.properties
@@ -89,18 +89,18 @@ onboarding.tour-sync.form.title=Create a
onboarding.tour-sync.form.description=to continue to Firefox Sync
onboarding.tour-sync.button=Next
onboarding.tour-sync.email-input.placeholder=Email
onboarding.notification.onboarding-tour-sync.title=Pick up where you left off.
onboarding.notification.onboarding-tour-sync.message=Still sending yourself links to save or read on your phone? Do it the easy way: get Sync and have the things you save here show up on all of your devices.
onboarding.tour-library=Library
onboarding.tour-library.title=Keep it together.
-# LOCALIZATION NOTE (onboarding.tour-library.description): This string will be used in the library tour description. %1$S is brandShortName
-onboarding.tour-library.description=Check out the new %1$S library in the redesigned toolbar. The library puts the things you’ve seen and saved to %1$S - your browsing history, bookmarks, Pocket lists, and synced tabs - in one convenient place.
+# LOCALIZATION NOTE (onboarding.tour-library.description2): This string will be used in the library tour description. %1$S is brandShortName
+onboarding.tour-library.description2=Check out the new %1$S library in the redesigned toolbar. The library puts the things you’ve seen and saved to %1$S — your browsing history, bookmarks, Pocket list, and synced tabs — in one convenient place.
onboarding.tour-library.button2=Show Library Menu
onboarding.notification.onboarding-tour-library.title=Keep it together.
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-library.message): This string will be used in the notification message for the library tour. %S is brandShortName
onboarding.notification.onboarding-tour-library.message=The new %S library puts the great things you’ve discovered on the web in one convenient place.
onboarding.tour-singlesearch=Address Bar
onboarding.tour-singlesearch.title=Find it faster.
# LOCALIZATION NOTE(onboarding.tour-singlesearch.description): %S is brandShortName
--- a/browser/modules/E10SUtils.jsm
+++ b/browser/modules/E10SUtils.jsm
@@ -6,18 +6,16 @@
this.EXPORTED_SYMBOLS = ["E10SUtils"];
const {interfaces: Ci, utils: Cu, classes: Cc} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyPreferenceGetter(this, "useRemoteWebExtensions",
- "extensions.webextensions.remote", false);
XPCOMUtils.defineLazyPreferenceGetter(this, "useSeparateFileUriProcess",
"browser.tabs.remote.separateFileUriProcess", false);
XPCOMUtils.defineLazyPreferenceGetter(this, "allowLinkedWebInFileUriProcess",
"browser.tabs.remote.allowLinkedWebInFileUriProcess", false);
XPCOMUtils.defineLazyModuleGetter(this, "Utils",
"resource://gre/modules/sessionstore/Utils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "console",
"resource://gre/modules/Console.jsm");
@@ -180,17 +178,17 @@ this.E10SUtils = {
if (chromeReg.canLoadURLRemotely(aURI) &&
aPreferredRemoteType != NOT_REMOTE) {
return DEFAULT_REMOTE_TYPE;
}
return NOT_REMOTE;
case "moz-extension":
- return useRemoteWebExtensions ? EXTENSION_REMOTE_TYPE : NOT_REMOTE;
+ return WebExtensionPolicy.useRemoteWebExtensions ? EXTENSION_REMOTE_TYPE : NOT_REMOTE;
default:
// For any other nested URIs, we use the innerURI to determine the
// remote type. In theory we should use the innermost URI, but some URIs
// have fake inner URIs (e.g. about URIs with inner moz-safe-about) and
// if such URIs are wrapped in other nested schemes like view-source:,
// we don't want to "skip" past "about:" by going straight to the
// innermost URI. Any URIs like this will need to be handled in the
--- a/browser/modules/test/browser/browser_PageActions.js
+++ b/browser/modules/test/browser/browser_PageActions.js
@@ -21,17 +21,17 @@ add_task(async function init() {
});
});
// Tests a simple non-built-in action without an iframe or subview. Also
// thoroughly checks most of the action's properties, methods, and DOM nodes, so
// it's not necessary to do that in general in other test tasks.
add_task(async function simple() {
- let iconURL = "chrome://browser/skin/email-link.svg";
+ let iconURL = "chrome://browser/skin/mail.svg";
let id = "test-simple";
let nodeAttributes = {
"test-attr": "test attr value",
};
let title = "Test simple";
let tooltip = "Test simple tooltip";
let onCommandCallCount = 0;
@@ -289,17 +289,17 @@ add_task(async function withSubview() {
if (node.localName == "panel") {
node.hidePopup();
break;
}
}
};
let action = PageActions.addAction(new PageActions.Action({
- iconURL: "chrome://browser/skin/email-link.svg",
+ iconURL: "chrome://browser/skin/mail.svg",
id,
shownInUrlbar: true,
subview,
title: "Test subview",
onCommand(event, buttonNode) {
onActionCommandCallCount++;
},
onPlacedInPanel(buttonNode) {
@@ -432,17 +432,17 @@ add_task(async function withIframe() {
let onPlacedInPanelCallCount = 0;
let onPlacedInUrlbarCallCount = 0;
let onIframeShownCount = 0;
let panelButtonID = BrowserPageActions._panelButtonNodeIDForActionID(id);
let urlbarButtonID = BrowserPageActions._urlbarButtonNodeIDForActionID(id);
let action = PageActions.addAction(new PageActions.Action({
- iconURL: "chrome://browser/skin/email-link.svg",
+ iconURL: "chrome://browser/skin/mail.svg",
id,
shownInUrlbar: true,
title: "Test iframe",
wantsIframe: true,
onCommand(event, buttonNode) {
onCommandCallCount++;
},
onIframeShown(iframeNode, panelNode) {
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -17,16 +17,17 @@
--toolbar-non-lwt-bgcolor: -moz-dialog;
--toolbar-non-lwt-textcolor: -moz-dialogtext;
--toolbar-non-lwt-bgimage: linear-gradient(rgba(255,255,255,.15), rgba(255,255,255,.15));
--toolbar-bgcolor: var(--toolbar-non-lwt-bgcolor);
--toolbar-bgimage: var(--toolbar-non-lwt-bgimage);
--toolbarbutton-border-radius: 4px;
--toolbarbutton-vertical-text-padding: calc(var(--toolbarbutton-inner-padding) - 1px);
+ --toolbarbutton-icon-fill-opacity: .85;
--panel-separator-color: ThreeDShadow;
--arrowpanel-dimmed: hsla(0,0%,80%,.3);
--arrowpanel-dimmed-further: hsla(0,0%,80%,.45);
--arrowpanel-dimmed-even-further: hsla(0,0%,80%,.8);
--urlbar-separator-color: ThreeDShadow;
@@ -52,16 +53,17 @@
-moz-appearance: none;
background-color: transparent;
border-top: none;
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
background-color: var(--toolbar-bgcolor);
background-image: var(--toolbar-bgimage);
+ color: var(--toolbar-color, inherit);
-moz-appearance: none;
border-style: none;
}
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
border-top: 1px solid var(--tabs-border) !important;
background-clip: padding-box;
/* Position the toolbar above the bottom of background tabs */
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -18,16 +18,17 @@
--toolbar-non-lwt-bgcolor: #f9f9fa;
--toolbar-non-lwt-textcolor: #0c0c0d;
--toolbar-non-lwt-bgimage: none;
--toolbar-bgcolor: var(--toolbar-non-lwt-bgcolor);
--toolbar-bgimage: var(--toolbar-non-lwt-bgimage);
--toolbarbutton-vertical-text-padding: calc(var(--toolbarbutton-inner-padding) + 1px);
--toolbarbutton-border-radius: 4px;
+ --toolbarbutton-icon-fill-opacity: .7;
--panel-separator-color: hsla(210,4%,10%,.14);
--arrowpanel-dimmed: hsla(210,4%,10%,.07);
--arrowpanel-dimmed-further: hsla(210,4%,10%,.12);
--arrowpanel-dimmed-even-further: hsla(210,4%,10%,.17);
--urlbar-separator-color: hsla(0,0%,16%,.2);
@@ -120,16 +121,17 @@
#main-window[chromehidden~="toolbar"][chromehidden~="location"][chromehidden~="directories"] {
border-top: 1px solid rgba(0,0,0,0.65);
}
#navigator-toolbox > toolbar:not(#TabsToolbar) {
-moz-appearance: none;
background: var(--toolbar-bgcolor);
+ color: var(--toolbar-color, inherit);
}
/* Draw the bottom border of the tabs toolbar when it's not using
-moz-appearance: toolbar. */
#main-window:-moz-any([sizemode="fullscreen"],[customize-entered]) #TabsToolbar:not([collapsed="true"]) + #nav-bar,
#main-window:not([tabsintitlebar]) #TabsToolbar:not([collapsed="true"]) + #nav-bar,
#TabsToolbar:not([collapsed="true"]) + #nav-bar:-moz-lwtheme {
border-top: 1px solid var(--tabs-border);
--- a/browser/themes/shared/compacttheme.inc.css
+++ b/browser/themes/shared/compacttheme.inc.css
@@ -8,16 +8,18 @@
:root:-moz-lwtheme {
--toolbar-bgcolor: var(--chrome-secondary-background-color);
--toolbar-gbimage: none;
--toolbar-non-lwt-bgcolor: var(--toolbar-bgcolor);
--toolbar-non-lwt-textcolor: var(--chrome-color);
--toolbar-non-lwt-bgimage: none;
+ --toolbarbutton-icon-fill-opacity: .7;
+
--tab-line-color: highlight;
}
:root:-moz-lwtheme-brighttext {
/* Chrome */
--chrome-background-color: hsl(240, 5%, 5%);
--chrome-color: rgb(249, 249, 250);
--chrome-secondary-background-color: hsl(240, 1%, 20%);
@@ -48,17 +50,17 @@
--chrome-nav-bar-controls-border-color: #ccc;
--chrome-selection-color: #f5f7fa;
--chrome-selection-background-color: #4c9ed9;
}
.toolbarbutton-animatable-box[brighttext],
toolbar[brighttext] .toolbarbutton-animatable-box,
toolbar[brighttext] .toolbarbutton-1 {
- fill: rgba(249, 249, 250, .7);
+ fill: rgb(249, 249, 250);
}
#urlbar ::-moz-selection,
#navigator-toolbox .searchbar-textbox ::-moz-selection,
.browserContainer > findbar ::-moz-selection {
background-color: var(--chrome-selection-background-color);
color: var(--chrome-selection-color);
}
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -87,24 +87,24 @@
/* These values are adjusted for the padding and height of the panel. */
from { margin-top: -.5em; } to { margin-top: calc(64px - .5em); }
}
@keyframes whimsyRotate {
to { transform: perspective(5000px) rotateY(360deg); }
}
-#PanelUI-button {
+:root:not([uidensity=compact]) #PanelUI-button {
margin-inline-start: 3px;
border-inline-start: 1px solid;
border-image: linear-gradient(transparent 4px, rgba(0,0,0,.1) 4px, rgba(0,0,0,.1) calc(100% - 4px), transparent calc(100% - 4px));
border-image-slice: 1;
}
-#nav-bar[brighttext] > #PanelUI-button {
+:root:not([uidensity=compact]) #nav-bar[brighttext] > #PanelUI-button {
border-image-source: linear-gradient(transparent 4px, rgba(100%,100%,100%,.2) 4px, rgba(100%,100%,100%,.2) calc(100% - 4px), transparent calc(100% - 4px));
}
#PanelUI-menu-button[badge-status] > .toolbarbutton-badge-stack > .toolbarbutton-badge {
display: -moz-box;
height: 10px;
width: 10px;
background-size: contain;
--- a/browser/themes/shared/downloads/download-icons.svg
+++ b/browser/themes/shared/downloads/download-icons.svg
@@ -8,17 +8,17 @@
display: none;
}
</style>
<defs>
<path id="arrow-icon" d="M7.293 12.725a1 1 0 0 0 1.414 0l5-5a1 1 0 0 0-1.414-1.413L9 9.605V1.019a1 1 0 0 0-2 0v8.586L3.707 6.312a1 1 0 0 0-1.414 1.413l5 5z"/>
<path id="short-bar-icon" d="m 13,14 a 1,1 0 1 1 0,2 h -10 a 1,1 0 1 1 0,-2 z"/>
<path id="long-bar-icon" d="m 14,14 a 1,1 0 1 1 0,2 h -12 a 1,1 0 1 1 0,-2"/>
</defs>
- <use id="arrow" fill="context-fill" href="#arrow-icon"/>
- <g id="arrow-with-bar" fill="context-fill">
+ <use id="arrow" fill="context-fill" fill-opacity="context-fill-opacity" href="#arrow-icon"/>
+ <g id="arrow-with-bar" fill="context-fill" fill-opacity="context-fill-opacity">
<use href="#arrow-icon"/>
<use href="#short-bar-icon"/>
</g>
- <use id="default-bar" fill="context-fill" href="#short-bar-icon"/>
+ <use id="default-bar" fill="context-fill" fill-opacity="context-fill-opacity" href="#short-bar-icon"/>
<use id="progress-bar-bg" fill="context-fill" fill-opacity="0.2" href="#long-bar-icon"/>
- <use id="progress-bar-fg" fill="context-fill" href="#long-bar-icon"/>
+ <use id="progress-bar-fg" fill="context-fill" fill-opacity="context-fill-opacity" href="#long-bar-icon"/>
</svg>
--- a/browser/themes/shared/downloads/indicator.inc.css
+++ b/browser/themes/shared/downloads/indicator.inc.css
@@ -8,30 +8,31 @@
min-width: 16px;
min-height: 16px;
}
#downloads-indicator-progress-outer {
width: 16px;
height: 16px;
background-size: 16px;
- -moz-context-properties: fill;
background: url("chrome://browser/skin/downloads/download-icons.svg#default-bar") center no-repeat;
}
#downloads-button[attention="success"] > #downloads-indicator-anchor > #downloads-indicator-icon,
#downloads-button[attention="success"] > #downloads-indicator-anchor > #downloads-indicator-progress-outer {
+ -moz-context-properties: fill, fill-opacity;
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
#downloads-button[progress] > #downloads-indicator-anchor > #downloads-indicator-progress-outer {
background: url("chrome://browser/skin/downloads/download-icons.svg#progress-bar-bg") center no-repeat;
}
#downloads-indicator-icon {
- -moz-context-properties: fill;
+ -moz-context-properties: fill, fill-opacity;
background-image: url("chrome://browser/skin/downloads/download-icons.svg#arrow");
width: 16px;
height: 16px;
}
#downloads-indicator-progress-inner {
background: url("chrome://browser/skin/downloads/download-icons.svg#progress-bar-fg") left no-repeat;
margin-right: 16px;
--- a/browser/themes/shared/icons/arrow-left.svg
+++ b/browser/themes/shared/icons/arrow-left.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16">
- <path fill="context-fill" d="M6.414 8l4.293-4.293a1 1 0 0 0-1.414-1.414l-5 5a1 1 0 0 0 0 1.414l5 5a1 1 0 0 0 1.414-1.414z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M6.414 8l4.293-4.293a1 1 0 0 0-1.414-1.414l-5 5a1 1 0 0 0 0 1.414l5 5a1 1 0 0 0 1.414-1.414z"/>
</svg>
--- a/browser/themes/shared/icons/back-12.svg
+++ b/browser/themes/shared/icons/back-12.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
- <path fill="context-fill" d="M 4.748 6 L 7.966 2.781 C 8.367 2.365 8.169 1.672 7.609 1.532 C 7.358 1.47 7.092 1.54 6.906 1.72 L 3.158 5.47 C 2.865 5.762 2.865 6.237 3.158 6.53 L 6.906 10.279 C 7.321 10.68 8.015 10.481 8.155 9.921 C 8.217 9.67 8.146 9.405 7.966 9.219 Z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M 4.748 6 L 7.966 2.781 C 8.367 2.365 8.169 1.672 7.609 1.532 C 7.358 1.47 7.092 1.54 6.906 1.72 L 3.158 5.47 C 2.865 5.762 2.865 6.237 3.158 6.53 L 6.906 10.279 C 7.321 10.68 8.015 10.481 8.155 9.921 C 8.217 9.67 8.146 9.405 7.966 9.219 Z"/>
</svg>
--- a/browser/themes/shared/icons/back.svg
+++ b/browser/themes/shared/icons/back.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill-opacity="context-fill-opacity" fill="context-fill" d="M15,7H3.414L7.707,2.707A1,1,0,0,0,6.293,1.293l-6,6a1,1,0,0,0,0,1.414l6,6a1,1,0,0,0,1.414-1.414L3.414,9H15a1,1,0,0,0,0-2Z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M15,7H3.414L7.707,2.707A1,1,0,0,0,6.293,1.293l-6,6a1,1,0,0,0,0,1.414l6,6a1,1,0,0,0,1.414-1.414L3.414,9H15a1,1,0,0,0,0-2Z"/>
</svg>
--- a/browser/themes/shared/icons/bookmark-animation.svg
+++ b/browser/themes/shared/icons/bookmark-animation.svg
@@ -12,17 +12,17 @@
</mask>
</defs>
<path fill="none" stroke="context-fill" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.584" d="M16.457 9.307l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.624 -2.66 2.897 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31"/>
<g mask="url(#a)">
<path fill="#FFF" d="M16.456 9.271l1.716 3.376 0.725 1.427 1.577 0.269 3.666 0.626 -2.67 2.907 -1.033 1.125 0.23 1.512 0.589 3.838 -3.333 -1.768 -1.5 -0.796 -1.496 0.803 -3.238 1.737 0.586 -3.813 0.234 -1.52 -1.047 -1.128 -2.686 -2.892 3.732 -0.627 1.619 -0.273 0.716 -1.477 1.612 -3.324"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.59" d="M16.456 9.271l1.716 3.376 0.725 1.427 1.577 0.269 3.666 0.626 -2.67 2.907 -1.033 1.125 0.23 1.512 0.589 3.838 -3.333 -1.768 -1.5 -0.796 -1.496 0.803 -3.238 1.737 0.586 -3.813 0.234 -1.52 -1.047 -1.128 -2.686 -2.892 3.732 -0.627 1.619 -0.273 0.716 -1.477 1.612 -3.324"/>
</g>
<g mask="url(#b)" opacity=".08">
- <path fill="context-fill" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
<path fill="none" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
</g>
</svg>
<svg x="33">
<defs>
<mask id="d" mask-type="alpha">
<path fill="context-stroke" d="M0 0h320v240h-320z" transform="matrix(.04 0 0 .04 9.957 11.594)"/>
</mask>
@@ -126,25 +126,25 @@
<g mask="url(#m)">
<path fill="#FFF" d="M16.457 9.299l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.625 -2.66 2.896 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.584" d="M16.457 9.299l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.625 -2.66 2.896 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31"/>
</g>
<g mask="url(#n)">
<path fill="context-stroke" d="M16.502 10.108l2.247 4.553 5.025 0.73 -3.636 3.545 0.858 5.004 -4.494 -2.363 -4.494 2.363 0.858 -5.004 -3.636 -3.545 5.025 -0.73 2.247 -4.553z"/>
<path fill="none" d="M16.502 10.108l2.247 4.553 5.025 0.73 -3.636 3.545 0.858 5.004 -4.494 -2.363 -4.494 2.363 0.858 -5.004 -3.636 -3.545 5.025 -0.73 2.247 -4.553z"/>
</g>
- <path fill="context-fill" d="M4.273 14.274l-0.235 -0.115"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M4.273 14.274l-0.235 -0.115"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-0.235 -0.115"/>
- <path fill="context-fill" d="M28.738 14.306l0.234 -0.115"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M28.738 14.306l0.234 -0.115"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306l0.234 -0.115"/>
- <path fill="context-fill" d="M24.168 28.806l0.168 0.2"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M24.168 28.806l0.168 0.2"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l0.168 0.2"/>
- <path fill="context-fill" d="M8.816 28.826l-0.168 0.2"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8.816 28.826l-0.168 0.2"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-0.168 0.2"/>
- <path fill="context-fill" d="M16.559 4.97v-0.26"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 4.97v-0.26"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-0.26"/>
</svg>
<svg x="231">
<defs>
<mask id="p" mask-type="alpha">
<path fill="context-stroke" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.623 -12.404)"/>
</mask>
<mask id="o" mask-type="alpha">
@@ -154,25 +154,25 @@
<g mask="url(#o)">
<path fill="#FFF" d="M16.448 9.017l1.774 3.492 0.75 1.475 1.63 0.278 3.792 0.648 -2.76 3.007 -1.07 1.163 0.24 1.563 0.608 3.97 -3.447 -1.83 -1.552 -0.822 -1.546 0.83 -3.35 1.797 0.607 -3.943 0.241 -1.572 -1.082 -1.167 -2.777 -2.99 3.859 -0.65 1.674 -0.281 0.74 -1.528 1.667 -3.437"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.644" d="M16.448 9.017l1.774 3.492 0.75 1.475 1.63 0.278 3.792 0.648 -2.76 3.007 -1.07 1.163 0.24 1.563 0.608 3.97 -3.447 -1.83 -1.552 -0.822 -1.546 0.83 -3.35 1.797 0.607 -3.943 0.241 -1.572 -1.082 -1.167 -2.777 -2.99 3.859 -0.65 1.674 -0.281 0.74 -1.528 1.667 -3.437"/>
</g>
<g mask="url(#p)">
<path fill="context-stroke" d="M16.495 9.857l2.332 4.727 5.217 0.758 -3.775 3.68 0.891 5.194 -4.665 -2.453 -4.666 2.453 0.891 -5.195 -3.774 -3.68 5.216 -0.757 2.333 -4.727z"/>
<path fill="none" d="M16.495 9.857l2.332 4.727 5.217 0.758 -3.775 3.68 0.891 5.194 -4.665 -2.453 -4.666 2.453 0.891 -5.195 -3.774 -3.68 5.216 -0.757 2.333 -4.727z"/>
</g>
- <path fill="context-fill" d="M4.273 14.274l-0.772 -0.377"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M4.273 14.274l-0.772 -0.377"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-0.772 -0.377"/>
- <path fill="context-fill" d="M28.738 14.306s0.33 -0.16 0.772 -0.377"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M28.738 14.306s0.33 -0.16 0.772 -0.377"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306s0.33 -0.16 0.772 -0.377"/>
- <path fill="context-fill" d="M24.168 28.806l0.552 0.658"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M24.168 28.806l0.552 0.658"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l0.552 0.658"/>
- <path fill="context-fill" d="M8.816 28.826l-0.552 0.657"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8.816 28.826l-0.552 0.657"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-0.552 0.657"/>
- <path fill="context-fill" d="M16.559 4.97v-0.859"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 4.97v-0.859"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-0.859"/>
</svg>
<svg x="264">
<defs>
<mask id="r" mask-type="alpha">
<path fill="context-stroke" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.623 -12.404)"/>
</mask>
<mask id="q" mask-type="alpha">
@@ -182,25 +182,25 @@
<g mask="url(#q)">
<path fill="#FFF" d="M16.437 8.692l1.85 3.64 0.781 1.538 1.7 0.29 3.953 0.675 -2.878 3.133 -1.115 1.213 0.25 1.63 0.633 4.137 -3.593 -1.906 -1.617 -0.858 -1.612 0.866 -3.491 1.873 0.632 -4.11 0.252 -1.639 -1.129 -1.216 -2.895 -3.118 4.023 -0.676 1.745 -0.294 0.772 -1.593 1.737 -3.583"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.714" d="M16.437 8.692l1.85 3.64 0.781 1.538 1.7 0.29 3.953 0.675 -2.878 3.133 -1.115 1.213 0.25 1.63 0.633 4.137 -3.593 -1.906 -1.617 -0.858 -1.612 0.866 -3.491 1.873 0.632 -4.11 0.252 -1.639 -1.129 -1.216 -2.895 -3.118 4.023 -0.676 1.745 -0.294 0.772 -1.593 1.737 -3.583"/>
</g>
<g mask="url(#r)">
<path fill="context-stroke" d="M16.486 9.568l2.432 4.927 5.437 0.79 -3.935 3.835 0.93 5.415 -4.864 -2.557 -4.863 2.557 0.929 -5.415 -3.935 -3.835 5.437 -0.79 2.432 -4.927z"/>
<path fill="none" d="M16.486 9.568l2.432 4.927 5.437 0.79 -3.935 3.835 0.93 5.415 -4.864 -2.557 -4.863 2.557 0.929 -5.415 -3.935 -3.835 5.437 -0.79 2.432 -4.927z"/>
</g>
- <path fill="context-fill" d="M4.273 14.274l-1.48 -0.722"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M4.273 14.274l-1.48 -0.722"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-1.48 -0.722"/>
- <path fill="context-fill" d="M28.738 14.306l1.48 -0.722"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M28.738 14.306l1.48 -0.722"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306l1.48 -0.722"/>
- <path fill="context-fill" d="M24.168 28.806l1.058 1.26"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M24.168 28.806l1.058 1.26"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l1.058 1.26"/>
- <path fill="context-fill" d="M8.816 28.826l-1.059 1.26"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8.816 28.826l-1.059 1.26"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-1.059 1.26"/>
- <path fill="context-fill" d="M16.559 4.97v-1.646"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 4.97v-1.646"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-1.646"/>
</svg>
<svg x="297">
<defs>
<mask id="t" mask-type="alpha">
<path fill="context-stroke" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.623 -12.404)"/>
</mask>
<mask id="s" mask-type="alpha">
@@ -210,25 +210,25 @@
<g mask="url(#s)">
<path fill="#FFF" d="M16.426 8.351l1.928 3.795 0.815 1.603 1.772 0.302 4.121 0.705 -3 3.267 -1.162 1.264 0.26 1.7 0.66 4.313 -3.746 -1.987 -1.686 -0.895 -1.68 0.903 -3.64 1.952 0.659 -4.285 0.262 -1.708 -1.176 -1.268 -3.018 -3.251 4.194 -0.705 1.819 -0.306 0.805 -1.66 1.811 -3.736"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.787" d="M16.426 8.351l1.928 3.795 0.815 1.603 1.772 0.302 4.121 0.705 -3 3.267 -1.162 1.264 0.26 1.7 0.66 4.313 -3.746 -1.987 -1.686 -0.895 -1.68 0.903 -3.64 1.952 0.659 -4.285 0.262 -1.708 -1.176 -1.268 -3.018 -3.251 4.194 -0.705 1.819 -0.306 0.805 -1.66 1.811 -3.736"/>
</g>
<g mask="url(#t)">
<path fill="context-stroke" d="M16.477 9.264l2.535 5.137 5.669 0.824 -4.102 3.998 0.968 5.646 -5.07 -2.666 -5.07 2.666 0.968 -5.646 -4.102 -3.998 5.669 -0.824 2.535 -5.137z"/>
<path fill="none" d="M16.477 9.264l2.535 5.137 5.669 0.824 -4.102 3.998 0.968 5.646 -5.07 -2.666 -5.07 2.666 0.968 -5.646 -4.102 -3.998 5.669 -0.824 2.535 -5.137z"/>
</g>
- <path fill="context-fill" d="M4.273 14.274l-2.281 -1.113"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M4.273 14.274l-2.281 -1.113"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-2.281 -1.113"/>
- <path fill="context-fill" d="M28.738 14.306l2.28 -1.112"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M28.738 14.306l2.28 -1.112"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306l2.28 -1.112"/>
- <path fill="context-fill" d="M24.168 28.806l1.631 1.944"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M24.168 28.806l1.631 1.944"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l1.631 1.944"/>
- <path fill="context-fill" d="M8.816 28.826l-1.631 1.943"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8.816 28.826l-1.631 1.943"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-1.631 1.943"/>
- <path fill="context-fill" d="M16.559 4.97v-2.537"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 4.97v-2.537"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-2.537"/>
</svg>
<svg x="330">
<defs>
<mask id="v" mask-type="alpha">
<g clip-path="url(#f10_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
<path fill="context-stroke" d="M0 0h320v240h-320z"/>
</g>
@@ -242,25 +242,25 @@
<g mask="url(#u)">
<path fill="#FFF" d="M16.415 8.021l2.005 3.945 0.847 1.667 1.842 0.314 4.284 0.732 -3.119 3.397 -1.208 1.314 0.27 1.766 0.687 4.484 -3.894 -2.065 -1.753 -0.93 -1.747 0.938 -3.784 2.03 0.685 -4.455 0.273 -1.776 -1.223 -1.318 -3.138 -3.38 4.36 -0.732 1.891 -0.318 0.837 -1.727 1.883 -3.883"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.858" d="M16.415 8.021l2.005 3.945 0.847 1.667 1.842 0.314 4.284 0.732 -3.119 3.397 -1.208 1.314 0.27 1.766 0.687 4.484 -3.894 -2.065 -1.753 -0.93 -1.747 0.938 -3.784 2.03 0.685 -4.455 0.273 -1.776 -1.223 -1.318 -3.138 -3.38 4.36 -0.732 1.891 -0.318 0.837 -1.727 1.883 -3.883"/>
</g>
<g mask="url(#v)">
<path fill="context-stroke" d="M16.468 8.97l2.636 5.34 5.893 0.857 -4.265 4.156 1.007 5.87 -5.27 -2.771 -5.272 2.77 1.007 -5.869 -4.265 -4.156 5.894 -0.857 2.635 -5.34z"/>
<path fill="none" d="M16.468 8.97l2.636 5.34 5.893 0.857 -4.265 4.156 1.007 5.87 -5.27 -2.771 -5.272 2.77 1.007 -5.869 -4.265 -4.156 5.894 -0.857 2.635 -5.34z"/>
</g>
- <path fill="context-fill" d="M4.273 14.274l-3.056 -1.49"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M4.273 14.274l-3.056 -1.49"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-3.056 -1.49"/>
- <path fill="context-fill" d="M28.738 14.306l3.056 -1.49"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M28.738 14.306l3.056 -1.49"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306l3.056 -1.49"/>
- <path fill="context-fill" d="M24.168 28.806l2.186 2.605"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M24.168 28.806l2.186 2.605"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l2.186 2.605"/>
- <path fill="context-fill" d="M8.816 28.826l-2.186 2.604"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8.816 28.826l-2.186 2.604"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-2.186 2.604"/>
- <path fill="context-fill" d="M16.559 4.97v-3.4"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 4.97v-3.4"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-3.4"/>
</svg>
<svg x="363">
<defs>
<mask id="x" mask-type="alpha">
<g clip-path="url(#f11_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
<path fill="context-stroke" d="M0 0h320v240h-320z"/>
</g>
@@ -274,25 +274,25 @@
<g mask="url(#w)">
<path fill="#FFF" d="M16.406 7.738l2.07 4.074 0.875 1.721 1.902 0.324 4.424 0.756 -3.221 3.508 -1.248 1.357 0.28 1.824 0.709 4.63 -4.022 -2.133 -1.81 -0.96 -1.804 0.97 -3.907 2.095 0.707 -4.6 0.282 -1.834 -1.263 -1.361 -3.24 -3.49 4.502 -0.757 1.953 -0.328 0.864 -1.783 1.945 -4.01"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.918" d="M16.406 7.738l2.07 4.074 0.875 1.721 1.902 0.324 4.424 0.756 -3.221 3.508 -1.248 1.357 0.28 1.824 0.709 4.63 -4.022 -2.133 -1.81 -0.96 -1.804 0.97 -3.907 2.095 0.707 -4.6 0.282 -1.834 -1.263 -1.361 -3.24 -3.49 4.502 -0.757 1.953 -0.328 0.864 -1.783 1.945 -4.01"/>
</g>
<g mask="url(#x)">
<path fill="context-stroke" d="M16.46 8.718l2.722 5.515 6.086 0.884 -4.404 4.292 1.04 6.061 -5.443 -2.861 -5.444 2.861 1.04 -6.06 -4.404 -4.293 6.086 -0.884 2.722 -5.515z"/>
<path fill="none" d="M16.46 8.718l2.722 5.515 6.086 0.884 -4.404 4.292 1.04 6.061 -5.443 -2.861 -5.444 2.861 1.04 -6.06 -4.404 -4.293 6.086 -0.884 2.722 -5.515z"/>
</g>
- <path fill="context-fill" d="M4.145 14.211l-2.928 -1.428"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M4.145 14.211l-2.928 -1.428"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M4.145 14.211l-2.928 -1.428"/>
- <path fill="context-fill" d="M28.866 14.243l2.928 -1.428"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M28.866 14.243l2.928 -1.428"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M28.866 14.243l2.928 -1.428"/>
- <path fill="context-fill" d="M24.26 28.915l2.094 2.496"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M24.26 28.915l2.094 2.496"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M24.26 28.915l2.094 2.496"/>
- <path fill="context-fill" d="M8.724 28.935l-2.094 2.495"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8.724 28.935l-2.094 2.495"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M8.724 28.935l-2.094 2.495"/>
- <path fill="context-fill" d="M16.559 4.828v-3.258"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 4.828v-3.258"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.828v-3.258"/>
</svg>
<svg x="396">
<defs>
<mask id="z" mask-type="alpha">
<g clip-path="url(#f12_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
<path fill="context-stroke" d="M0 0h320v240h-320z"/>
</g>
@@ -306,25 +306,25 @@
<g mask="url(#y)">
<path fill="#FFF" d="M16.401 7.59l2.104 4.141 0.89 1.75 1.933 0.33 4.497 0.768 -3.274 3.565 -1.269 1.38 0.284 1.854 0.721 4.707 -4.087 -2.169 -1.84 -0.975 -1.834 0.984 -3.972 2.131 0.72 -4.676 0.286 -1.864 -1.284 -1.384 -3.293 -3.547 4.576 -0.77 1.985 -0.333 0.878 -1.812 1.977 -4.077"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.95" d="M16.401 7.59l2.104 4.141 0.89 1.75 1.933 0.33 4.497 0.768 -3.274 3.565 -1.269 1.38 0.284 1.854 0.721 4.707 -4.087 -2.169 -1.84 -0.975 -1.834 0.984 -3.972 2.131 0.72 -4.676 0.286 -1.864 -1.284 -1.384 -3.293 -3.547 4.576 -0.77 1.985 -0.333 0.878 -1.812 1.977 -4.077"/>
</g>
<g mask="url(#z)">
<path fill="context-stroke" d="M16.457 8.587l2.766 5.605 6.186 0.899 -4.476 4.363 1.056 6.16 -5.532 -2.908 -5.533 2.909 1.057 -6.161 -4.476 -4.363 6.185 -0.899 2.767 -5.605z"/>
<path fill="none" d="M16.457 8.587l2.766 5.605 6.186 0.899 -4.476 4.363 1.056 6.16 -5.532 -2.908 -5.533 2.909 1.057 -6.161 -4.476 -4.363 6.185 -0.899 2.767 -5.605z"/>
</g>
- <path fill="context-fill" d="M3.835 14.06l-2.618 -1.277"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M3.835 14.06l-2.618 -1.277"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M3.835 14.06l-2.618 -1.277"/>
- <path fill="context-fill" d="M29.176 14.092l2.618 -1.277"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M29.176 14.092l2.618 -1.277"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M29.176 14.092l2.618 -1.277"/>
- <path fill="context-fill" d="M24.481 29.18l1.873 2.23"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M24.481 29.18l1.873 2.23"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M24.481 29.18l1.873 2.23"/>
- <path fill="context-fill" d="M8.502 29.199l-1.872 2.231"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8.502 29.199l-1.872 2.231"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M8.502 29.199l-1.872 2.231"/>
- <path fill="context-fill" d="M16.559 4.483v-2.913"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 4.483v-2.913"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.483v-2.913"/>
</svg>
<svg x="429">
<defs>
<mask id="B" mask-type="alpha">
<g clip-path="url(#f13_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
<path fill="context-stroke" d="M0 0h320v240h-320z"/>
</g>
@@ -338,25 +338,25 @@
<g mask="url(#A)">
<path fill="#FFF" d="M16.406 7.738l2.07 4.074 0.875 1.721 1.902 0.324 4.424 0.756 -3.221 3.508 -1.248 1.357 0.28 1.824 0.709 4.63 -4.022 -2.133 -1.81 -0.96 -1.804 0.97 -3.907 2.096 0.707 -4.6 0.282 -1.835 -1.263 -1.361 -3.24 -3.49 4.502 -0.757 1.953 -0.328 0.864 -1.783 1.945 -4.01"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.918" d="M16.406 7.738l2.07 4.074 0.875 1.721 1.902 0.324 4.424 0.756 -3.221 3.508 -1.248 1.357 0.28 1.824 0.709 4.63 -4.022 -2.133 -1.81 -0.96 -1.804 0.97 -3.907 2.096 0.707 -4.6 0.282 -1.835 -1.263 -1.361 -3.24 -3.49 4.502 -0.757 1.953 -0.328 0.864 -1.783 1.945 -4.01"/>
</g>
<g mask="url(#B)">
<path fill="context-stroke" d="M16.46 8.718l2.722 5.515 6.086 0.884 -4.404 4.292 1.04 6.061 -5.444 -2.861 -5.443 2.861 1.04 -6.06 -4.404 -4.293 6.086 -0.884 2.721 -5.515z"/>
<path fill="none" d="M16.46 8.718l2.722 5.515 6.086 0.884 -4.404 4.292 1.04 6.061 -5.444 -2.861 -5.443 2.861 1.04 -6.06 -4.404 -4.293 6.086 -0.884 2.721 -5.515z"/>
</g>
- <path fill="context-fill" d="M3.408 13.852l-2.191 -1.069"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M3.408 13.852l-2.191 -1.069"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M3.408 13.852l-2.191 -1.069"/>
- <path fill="context-fill" d="M29.602 13.884l2.192 -1.069"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M29.602 13.884l2.192 -1.069"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M29.602 13.884l2.192 -1.069"/>
- <path fill="context-fill" d="M24.786 29.543l1.568 1.868"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M24.786 29.543l1.568 1.868"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M24.786 29.543l1.568 1.868"/>
- <path fill="context-fill" d="M8.197 29.563l-1.567 1.867"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8.197 29.563l-1.567 1.867"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M8.197 29.563l-1.567 1.867"/>
- <path fill="context-fill" d="M16.559 4.008v-2.438"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 4.008v-2.438"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.008v-2.438"/>
</svg>
<svg x="462">
<defs>
<mask id="D" mask-type="alpha">
<g clip-path="url(#f14_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
<path fill="context-stroke" d="M0 0h320v240h-320z"/>
</g>
@@ -370,25 +370,25 @@
<g mask="url(#C)">
<path fill="#FFF" d="M16.413 7.97l2.017 3.968 0.852 1.677 1.853 0.316 4.31 0.736 -3.138 3.417 -1.216 1.322 0.272 1.777 0.691 4.51 -3.917 -2.078 -1.763 -0.935 -1.758 0.944 -3.805 2.042 0.688 -4.482 0.275 -1.786 -1.23 -1.326 -3.156 -3.4 4.386 -0.736 1.902 -0.32 0.841 -1.737 1.895 -3.906"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.869" d="M16.413 7.97l2.017 3.968 0.852 1.677 1.853 0.316 4.31 0.736 -3.138 3.417 -1.216 1.322 0.272 1.777 0.691 4.51 -3.917 -2.078 -1.763 -0.935 -1.758 0.944 -3.805 2.042 0.688 -4.482 0.275 -1.786 -1.23 -1.326 -3.156 -3.4 4.386 -0.736 1.902 -0.32 0.841 -1.737 1.895 -3.906"/>
</g>
<g mask="url(#D)">
<path fill="context-stroke" d="M16.467 8.925l2.65 5.371 5.928 0.862 -4.289 4.18 1.013 5.905 -5.302 -2.788 -5.302 2.788 1.012 -5.904 -4.289 -4.181 5.928 -0.862 2.65 -5.371z"/>
<path fill="none" d="M16.467 8.925l2.65 5.371 5.928 0.862 -4.289 4.18 1.013 5.905 -5.302 -2.788 -5.302 2.788 1.012 -5.904 -4.289 -4.181 5.928 -0.862 2.65 -5.371z"/>
</g>
- <path fill="context-fill" d="M2.901 13.605l-1.684 -0.822"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M2.901 13.605l-1.684 -0.822"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M2.901 13.605l-1.684 -0.822"/>
- <path fill="context-fill" d="M30.109 13.637l1.685 -0.822"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M30.109 13.637l1.685 -0.822"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M30.109 13.637l1.685 -0.822"/>
- <path fill="context-fill" d="M25.149 29.975l1.205 1.436"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M25.149 29.975l1.205 1.436"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M25.149 29.975l1.205 1.436"/>
- <path fill="context-fill" d="M7.835 29.994l-1.205 1.436"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M7.835 29.994l-1.205 1.436"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M7.835 29.994l-1.205 1.436"/>
- <path fill="context-fill" d="M16.559 3.445v-1.875"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 3.445v-1.875"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 3.445v-1.875"/>
</svg>
<svg x="495">
<defs>
<mask id="F" mask-type="alpha">
<g clip-path="url(#f15_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
<path fill="context-stroke" d="M0 0h320v240h-320z"/>
</g>
@@ -402,25 +402,25 @@
<g mask="url(#E)">
<path fill="#FFF" d="M16.422 8.223l1.958 3.853 0.827 1.628 1.8 0.307 4.184 0.715 -3.047 3.317 -1.18 1.284 0.264 1.725 0.671 4.38 -3.804 -2.018 -1.712 -0.908 -1.706 0.917 -3.696 1.982 0.67 -4.35 0.266 -1.736 -1.195 -1.287 -3.064 -3.3 4.258 -0.716 1.848 -0.311 0.817 -1.686 1.839 -3.793"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.814" d="M16.422 8.223l1.958 3.853 0.827 1.628 1.8 0.307 4.184 0.715 -3.047 3.317 -1.18 1.284 0.264 1.725 0.671 4.38 -3.804 -2.018 -1.712 -0.908 -1.706 0.917 -3.696 1.982 0.67 -4.35 0.266 -1.736 -1.195 -1.287 -3.064 -3.3 4.258 -0.716 1.848 -0.311 0.817 -1.686 1.839 -3.793"/>
</g>
<g mask="url(#F)">
<path fill="context-stroke" d="M16.473 9.15l2.575 5.216 5.755 0.836 -4.165 4.06 0.984 5.733 -5.149 -2.707 -5.148 2.707 0.984 -5.733 -4.165 -4.06 5.755 -0.836 2.574 -5.216z"/>
<path fill="none" d="M16.473 9.15l2.575 5.216 5.755 0.836 -4.165 4.06 0.984 5.733 -5.149 -2.707 -5.148 2.707 0.984 -5.733 -4.165 -4.06 5.755 -0.836 2.574 -5.216z"/>
</g>
- <path fill="context-fill" d="M2.342 13.332l-1.125 -0.549"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M2.342 13.332l-1.125 -0.549"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M2.342 13.332l-1.125 -0.549"/>
- <path fill="context-fill" d="M30.668 13.364l1.126 -0.549"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M30.668 13.364l1.126 -0.549"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M30.668 13.364l1.126 -0.549"/>
- <path fill="context-fill" d="M25.549 30.451l0.805 0.96"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M25.549 30.451l0.805 0.96"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M25.549 30.451l0.805 0.96"/>
- <path fill="context-fill" d="M7.435 30.47l-0.805 0.96"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M7.435 30.47l-0.805 0.96"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M7.435 30.47l-0.805 0.96"/>
- <path fill="context-fill" d="M16.559 2.822v-1.252"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 2.822v-1.252"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 2.822v-1.252"/>
</svg>
<svg x="528">
<defs>
<mask id="H" mask-type="alpha">
<g clip-path="url(#f16_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
<path fill="context-stroke" d="M0 0h320v240h-320z"/>
</g>
@@ -434,25 +434,25 @@
<g mask="url(#G)">
<path fill="#FFF" d="M16.43 8.48l1.899 3.736 0.802 1.579 1.745 0.297 4.057 0.693 -2.954 3.217 -1.144 1.245 0.255 1.673 0.651 4.247 -3.688 -1.957 -1.66 -0.88 -1.655 0.888 -3.583 1.923 0.649 -4.22 0.258 -1.681 -1.158 -1.249 -2.972 -3.2 4.13 -0.694 1.79 -0.301 0.793 -1.636 1.783 -3.677"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.759" d="M16.43 8.48l1.899 3.736 0.802 1.579 1.745 0.297 4.057 0.693 -2.954 3.217 -1.144 1.245 0.255 1.673 0.651 4.247 -3.688 -1.957 -1.66 -0.88 -1.655 0.888 -3.583 1.923 0.649 -4.22 0.258 -1.681 -1.158 -1.249 -2.972 -3.2 4.13 -0.694 1.79 -0.301 0.793 -1.636 1.783 -3.677"/>
</g>
<g mask="url(#H)">
<path fill="context-stroke" d="M16.48 9.38l2.496 5.056 5.581 0.811 -4.038 3.937 0.953 5.559 -4.992 -2.625 -4.992 2.625 0.954 -5.559 -4.039 -3.937 5.581 -0.81 2.496 -5.058z"/>
<path fill="none" d="M16.48 9.38l2.496 5.056 5.581 0.811 -4.038 3.937 0.953 5.559 -4.992 -2.625 -4.992 2.625 0.954 -5.559 -4.039 -3.937 5.581 -0.81 2.496 -5.058z"/>
</g>
- <path fill="context-fill" d="M1.758 13.047l-0.541 -0.264"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M1.758 13.047l-0.541 -0.264"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M1.758 13.047l-0.541 -0.264"/>
- <path fill="context-fill" d="M31.253 13.08l0.54 -0.265"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M31.253 13.08l0.54 -0.265"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M31.253 13.08l0.54 -0.265"/>
- <path fill="context-fill" d="M25.967 30.95l0.387 0.46"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M25.967 30.95l0.387 0.46"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M25.967 30.95l0.387 0.46"/>
- <path fill="context-fill" d="M7.017 30.97l-0.387 0.46"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M7.017 30.97l-0.387 0.46"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M7.017 30.97l-0.387 0.46"/>
- <path fill="context-fill" d="M16.559 2.172v-0.602"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.559 2.172v-0.602"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-width="1.6" d="M16.559 2.172v-0.602"/>
</svg>
<svg x="561">
<defs>
<mask id="J" mask-type="alpha">
<g clip-path="url(#f17_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
<path fill="context-stroke" d="M0 0h320v240h-320z"/>
</g>
@@ -530,13 +530,13 @@
</mask>
</defs>
<path fill="none" stroke="context-fill" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.584" d="M16.457 9.307l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.624 -2.66 2.897 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31" display="block"/>
<g mask="url(#O)">
<path fill="#FFF" d="M16.456 9.271l1.716 3.376 0.725 1.427 1.577 0.269 3.666 0.626 -2.67 2.907 -1.033 1.125 0.23 1.512 0.589 3.838 -3.333 -1.768 -1.5 -0.796 -1.496 0.803 -3.238 1.737 0.586 -3.813 0.234 -1.52 -1.047 -1.128 -2.686 -2.892 3.732 -0.627 1.619 -0.273 0.716 -1.477 1.612 -3.324"/>
<path fill="none" stroke="context-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.59" d="M16.456 9.271l1.716 3.376 0.725 1.427 1.577 0.269 3.666 0.626 -2.67 2.907 -1.033 1.125 0.23 1.512 0.589 3.838 -3.333 -1.768 -1.5 -0.796 -1.496 0.803 -3.238 1.737 0.586 -3.813 0.234 -1.52 -1.047 -1.128 -2.686 -2.892 3.732 -0.627 1.619 -0.273 0.716 -1.477 1.612 -3.324"/>
</g>
<g mask="url(#P)" opacity=".08">
- <path fill="context-fill" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
<path fill="none" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
</g>
</svg>
</svg>
--- a/browser/themes/shared/icons/bookmark-hollow.svg
+++ b/browser/themes/shared/icons/bookmark-hollow.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill-opacity="context-fill-opacity" fill="context-fill" d="M3.8 15.922a1.1 1.1 0 0 1-1.09-1.253l.609-4.36L.393 7.163a1.1 1.1 0 0 1 .616-1.833l4.08-.73L7.016.734a1.1 1.1 0 0 1 1.969 0L10.911 4.6 15 5.331a1.1 1.1 0 0 1 .611 1.833L12.68 10.31l.609 4.359a1.1 1.1 0 0 1-1.6 1.127L8 13.873 4.308 15.8a1.093 1.093 0 0 1-.508.122zm-.415-1.9zm9.228 0zM2.981 7.01l2.451 2.635-.5 3.572L8 11.618l3.067 1.6-.5-3.572 2.452-2.636-3.45-.616L8 3.244l-1.569 3.15zm11.659.29zm-13.278 0zm12.78-1.5zm-12.286 0z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M3.8 15.922a1.1 1.1 0 0 1-1.09-1.253l.609-4.36L.393 7.163a1.1 1.1 0 0 1 .616-1.833l4.08-.73L7.016.734a1.1 1.1 0 0 1 1.969 0L10.911 4.6 15 5.331a1.1 1.1 0 0 1 .611 1.833L12.68 10.31l.609 4.359a1.1 1.1 0 0 1-1.6 1.127L8 13.873 4.308 15.8a1.093 1.093 0 0 1-.508.122zm-.415-1.9zm9.228 0zM2.981 7.01l2.451 2.635-.5 3.572L8 11.618l3.067 1.6-.5-3.572 2.452-2.636-3.45-.616L8 3.244l-1.569 3.15zm11.659.29zm-13.278 0zm12.78-1.5zm-12.286 0z"/>
</svg>
--- a/browser/themes/shared/icons/bookmark-star-on-tray.svg
+++ b/browser/themes/shared/icons/bookmark-star-on-tray.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M14 16H2a1 1 0 0 1-1-1v-2a1 1 0 0 1 2 0v1h10v-1a1 1 0 0 1 2 0v2a1 1 0 0 1-1 1zM13.961 4.282a.9.9 0 0 0-.723-.609l-3.063-.445L8.805.456a.934.934 0 0 0-1.605 0L5.83 3.228l-3.063.445A.893.893 0 0 0 2.27 5.2l2.217 2.156-.523 3.044a.894.894 0 0 0 1.3.942L8 9.907l2.74 1.439a.888.888 0 0 0 .416.1.9.9 0 0 0 .526-.172.893.893 0 0 0 .355-.874l-.522-3.047 2.22-2.153a.893.893 0 0 0 .226-.918zm-4.367 2.45l.376 2.189L8 7.888 6.035 8.921l.376-2.189-1.592-1.55 2.2-.319L8 2.872l.983 1.991 2.2.319z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M14 16H2a1 1 0 0 1-1-1v-2a1 1 0 0 1 2 0v1h10v-1a1 1 0 0 1 2 0v2a1 1 0 0 1-1 1zM13.961 4.282a.9.9 0 0 0-.723-.609l-3.063-.445L8.805.456a.934.934 0 0 0-1.605 0L5.83 3.228l-3.063.445A.893.893 0 0 0 2.27 5.2l2.217 2.156-.523 3.044a.894.894 0 0 0 1.3.942L8 9.907l2.74 1.439a.888.888 0 0 0 .416.1.9.9 0 0 0 .526-.172.893.893 0 0 0 .355-.874l-.522-3.047 2.22-2.153a.893.893 0 0 0 .226-.918zm-4.367 2.45l.376 2.189L8 7.888 6.035 8.921l.376-2.189-1.592-1.55 2.2-.319L8 2.872l.983 1.991 2.2.319z"/>
</svg>
\ No newline at end of file
--- a/browser/themes/shared/icons/bookmark.svg
+++ b/browser/themes/shared/icons/bookmark.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill-opacity="context-fill-opacity" fill="context-fill" d="M15.845 6.064A1.1 1.1 0 0 0 15 5.331L10.911 4.6 8.985.735a1.1 1.1 0 0 0-1.969 0L5.089 4.6l-4.081.729a1.1 1.1 0 0 0-.615 1.834L3.32 10.31l-.609 4.36a1.1 1.1 0 0 0 1.6 1.127L8 13.873l3.69 1.927a1.1 1.1 0 0 0 1.6-1.127l-.61-4.363 2.926-3.146a1.1 1.1 0 0 0 .239-1.1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M15.845 6.064A1.1 1.1 0 0 0 15 5.331L10.911 4.6 8.985.735a1.1 1.1 0 0 0-1.969 0L5.089 4.6l-4.081.729a1.1 1.1 0 0 0-.615 1.834L3.32 10.31l-.609 4.36a1.1 1.1 0 0 0 1.6 1.127L8 13.873l3.69 1.927a1.1 1.1 0 0 0 1.6-1.127l-.61-4.363 2.926-3.146a1.1 1.1 0 0 0 .239-1.1z"/>
</svg>
--- a/browser/themes/shared/icons/characterEncoding.svg
+++ b/browser/themes/shared/icons/characterEncoding.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M13 15H3a2.006 2.006 0 0 1-2-2V3a2.006 2.006 0 0 1 2-2h10a2.006 2.006 0 0 1 2 2v10a2.006 2.006 0 0 1-2 2zm0-10a2.946 2.946 0 0 0-3-3H6a2.946 2.946 0 0 0-3 3v4a2.946 2.946 0 0 0 3 3h4c1.7 0 3-.3 3-2zm-3 3.2a2.769 2.769 0 0 0 .9-.1c.3-.1.5-.2.8-.3v.8a6.89 6.89 0 0 0-.8.3 2.22 2.22 0 0 1-.9.1 2.149 2.149 0 0 1-2.1-1.2 3.819 3.819 0 0 1-.9.9 2.663 2.663 0 0 1-1.2.3 1.728 1.728 0 0 1-1.3-.5A1.248 1.248 0 0 1 4 7.3 1.486 1.486 0 0 1 4.6 6a3.312 3.312 0 0 1 1.9-.5h.9v-.4a1.327 1.327 0 0 0-.3-1c-.1-.3-.4-.4-.8-.4a3.429 3.429 0 0 0-1.6.4l-.2-.6a3.919 3.919 0 0 1 .9-.4c.3 0 .6-.1 1-.1a3.6 3.6 0 0 1 1.1.2 1.7 1.7 0 0 1 .6.8 1.575 1.575 0 0 1 .7-.7 1.689 1.689 0 0 1 1-.3 1.865 1.865 0 0 1 1.6.7 2.883 2.883 0 0 1 .6 1.9v.6H8.4c0 1.4.6 2 1.6 2zM7.5 6.1h-.8a2.42 2.42 0 0 0-1.4.3.975.975 0 0 0-.4.9.779.779 0 0 0 .3.7.844.844 0 0 0 .7.2 1.594 1.594 0 0 0 1.2-.4 1.7 1.7 0 0 0 .4-1.3zm3.6-.6a2.269 2.269 0 0 0-.3-1.3.975.975 0 0 0-.9-.4 1.284 1.284 0 0 0-1 .4 2.226 2.226 0 0 0-.5 1.3z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M13 15H3a2.006 2.006 0 0 1-2-2V3a2.006 2.006 0 0 1 2-2h10a2.006 2.006 0 0 1 2 2v10a2.006 2.006 0 0 1-2 2zm0-10a2.946 2.946 0 0 0-3-3H6a2.946 2.946 0 0 0-3 3v4a2.946 2.946 0 0 0 3 3h4c1.7 0 3-.3 3-2zm-3 3.2a2.769 2.769 0 0 0 .9-.1c.3-.1.5-.2.8-.3v.8a6.89 6.89 0 0 0-.8.3 2.22 2.22 0 0 1-.9.1 2.149 2.149 0 0 1-2.1-1.2 3.819 3.819 0 0 1-.9.9 2.663 2.663 0 0 1-1.2.3 1.728 1.728 0 0 1-1.3-.5A1.248 1.248 0 0 1 4 7.3 1.486 1.486 0 0 1 4.6 6a3.312 3.312 0 0 1 1.9-.5h.9v-.4a1.327 1.327 0 0 0-.3-1c-.1-.3-.4-.4-.8-.4a3.429 3.429 0 0 0-1.6.4l-.2-.6a3.919 3.919 0 0 1 .9-.4c.3 0 .6-.1 1-.1a3.6 3.6 0 0 1 1.1.2 1.7 1.7 0 0 1 .6.8 1.575 1.575 0 0 1 .7-.7 1.689 1.689 0 0 1 1-.3 1.865 1.865 0 0 1 1.6.7 2.883 2.883 0 0 1 .6 1.9v.6H8.4c0 1.4.6 2 1.6 2zM7.5 6.1h-.8a2.42 2.42 0 0 0-1.4.3.975.975 0 0 0-.4.9.779.779 0 0 0 .3.7.844.844 0 0 0 .7.2 1.594 1.594 0 0 0 1.2-.4 1.7 1.7 0 0 0 .4-1.3zm3.6-.6a2.269 2.269 0 0 0-.3-1.3.975.975 0 0 0-.9-.4 1.284 1.284 0 0 0-1 .4 2.226 2.226 0 0 0-.5 1.3z"/>
</svg>
--- a/browser/themes/shared/icons/check.svg
+++ b/browser/themes/shared/icons/check.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M6 14a1 1 0 0 1-.707-.293l-3-3a1 1 0 0 1 1.414-1.414l2.157 2.157 6.316-9.023a1 1 0 0 1 1.639 1.146l-7 10a1 1 0 0 1-.732.427A.863.863 0 0 1 6 14z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M6 14a1 1 0 0 1-.707-.293l-3-3a1 1 0 0 1 1.414-1.414l2.157 2.157 6.316-9.023a1 1 0 0 1 1.639 1.146l-7 10a1 1 0 0 1-.732.427A.863.863 0 0 1 6 14z"/>
</svg>
--- a/browser/themes/shared/icons/chevron-animation.svg
+++ b/browser/themes/shared/icons/chevron-animation.svg
@@ -1,12 +1,12 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="1278" height="36" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="1278" height="36" fill="context-fill" fill-opacity="context-fill-opacity">
<svg>
<path d="M9.707 17.293l-5 -5a1 1 0 1 0 -1.414 1.414l4.293 4.293 -4.293 4.293a1 1 0 0 0 -0.025 1.414 1 1 0 0 0 1.414 0.025l0.025 -0.025 5 -5a1 1 0 0 0 0 -1.414zm6 0l-5 -5a1 1 0 1 0 -1.414 1.414l4.293 4.293 -4.293 4.293a1 1 0 0 0 -0.025 1.414 1 1 0 0 0 1.414 0.025l0.025 -0.025 5 -5a1 1 0 0 0 0 -1.414z"/>
</svg>
<svg x="18">
<path d="M9.714 17.3l-4.948 -5.051a1 1 0 1 0 -1.429 1.4l4.25 4.336 -4.338 4.249a1 1 0 0 0 -0.04 1.413 1 1 0 0 0 1.414 0.04l0.025 -0.025 5.052 -4.948a1 1 0 0 0 0.014 -1.414zm6 0.063l-4.948 -5.052a1 1 0 1 0 -1.429 1.4l4.249 4.337 -4.338 4.248a1 1 0 0 0 -0.04 1.413 1 1 0 0 0 1.415 0.04l0.025 -0.025 5.051 -4.948a1 1 0 0 0 0.015 -1.413z"/>
</svg>
<svg x="36">
<path d="M9.735 17.322l-4.796 -5.196a1 1 0 1 0 -1.47 1.356l4.118 4.461 -4.461 4.118a1 1 0 0 0 -0.082 1.412 1 1 0 0 0 1.412 0.081c0.01 -0.007 0.017 -0.016 0.026 -0.024l5.196 -4.795a1 1 0 0 0 0.057 -1.413zm5.995 0.24l-4.796 -5.196a1 1 0 1 0 -1.47 1.356l4.118 4.462 -4.461 4.117a1 1 0 0 0 -0.082 1.412 1 1 0 0 0 1.412 0.082l0.026 -0.024 5.196 -4.796a1 1 0 0 0 0.057 -1.413z"/>
--- a/browser/themes/shared/icons/chevron.svg
+++ b/browser/themes/shared/icons/chevron.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M8.707,7.293l-5-5A1,1,0,0,0,2.293,3.707L6.586,8,2.293,12.293a1,1,0,1,0,1.414,1.414l5-5A1,1,0,0,0,8.707,7.293Zm6,0-5-5A1,1,0,0,0,8.293,3.707L12.586,8,8.293,12.293a1,1,0,1,0,1.414,1.414l5-5A1,1,0,0,0,14.707,7.293Z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8.707,7.293l-5-5A1,1,0,0,0,2.293,3.707L6.586,8,2.293,12.293a1,1,0,1,0,1.414,1.414l5-5A1,1,0,0,0,8.707,7.293Zm6,0-5-5A1,1,0,0,0,8.293,3.707L12.586,8,8.293,12.293a1,1,0,1,0,1.414,1.414l5-5A1,1,0,0,0,14.707,7.293Z"/>
</svg>
--- a/browser/themes/shared/icons/containers.svg
+++ b/browser/themes/shared/icons/containers.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M12 4H4v4h8zm-2 2.75a.25.25 0 0 1-.25.25h-3.5A.25.25 0 0 1 6 6.75v-.5A.25.25 0 0 1 6.25 6h3.5a.25.25 0 0 1 .25.25zM12 9H4v4h8zm-2 2.75a.25.25 0 0 1-.25.25h-3.5a.25.25 0 0 1-.25-.25v-.5a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25zm3.854-9.9L13 1H3l-.854.853A.5.5 0 0 0 2 2.207V14a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2.207a.5.5 0 0 0-.146-.354zM13 14H3V3h10z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M12 4H4v4h8zm-2 2.75a.25.25 0 0 1-.25.25h-3.5A.25.25 0 0 1 6 6.75v-.5A.25.25 0 0 1 6.25 6h3.5a.25.25 0 0 1 .25.25zM12 9H4v4h8zm-2 2.75a.25.25 0 0 1-.25.25h-3.5a.25.25 0 0 1-.25-.25v-.5a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25zm3.854-9.9L13 1H3l-.854.853A.5.5 0 0 0 2 2.207V14a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2.207a.5.5 0 0 0-.146-.354zM13 14H3V3h10z"/>
</svg>
--- a/browser/themes/shared/icons/customize.svg
+++ b/browser/themes/shared/icons/customize.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M4 10a1.994 1.994 0 0 0-1.911 1.44c0 .01-.014.015-.017.025-.362 1.135-.705 2.11-1.759 2.573l-.023.012-.024.012A.5.5 0 0 0 0 14.5a.5.5 0 0 0 .5.5 6.974 6.974 0 0 0 4.825-1.5c.006-.006.007-.013.013-.019A1.993 1.993 0 0 0 4 10zM15.693.307a.984.984 0 0 0-1.338-.046l-8.031 7a.982.982 0 0 0-.049 1.433l1.032 1.031a.983.983 0 0 0 .693.287h.033a.982.982 0 0 0 .706-.335l7-8.031a.982.982 0 0 0-.046-1.339z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M4 10a1.994 1.994 0 0 0-1.911 1.44c0 .01-.014.015-.017.025-.362 1.135-.705 2.11-1.759 2.573l-.023.012-.024.012A.5.5 0 0 0 0 14.5a.5.5 0 0 0 .5.5 6.974 6.974 0 0 0 4.825-1.5c.006-.006.007-.013.013-.019A1.993 1.993 0 0 0 4 10zM15.693.307a.984.984 0 0 0-1.338-.046l-8.031 7a.982.982 0 0 0-.049 1.433l1.032 1.031a.983.983 0 0 0 .693.287h.033a.982.982 0 0 0 .706-.335l7-8.031a.982.982 0 0 0-.046-1.339z"/>
</svg>
--- a/browser/themes/shared/icons/developer.svg
+++ b/browser/themes/shared/icons/developer.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M14.555 3.2l-2.434 2.436a1.243 1.243 0 1 1-1.757-1.757L12.8 1.445A3.956 3.956 0 0 0 11 1a3.976 3.976 0 0 0-3.434 6.02l-6.273 6.273a1 1 0 1 0 1.414 1.414L8.98 8.434A3.96 3.96 0 0 0 11 9a4 4 0 0 0 4-4 3.956 3.956 0 0 0-.445-1.8z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M14.555 3.2l-2.434 2.436a1.243 1.243 0 1 1-1.757-1.757L12.8 1.445A3.956 3.956 0 0 0 11 1a3.976 3.976 0 0 0-3.434 6.02l-6.273 6.273a1 1 0 1 0 1.414 1.414L8.98 8.434A3.96 3.96 0 0 0 11 9a4 4 0 0 0 4-4 3.956 3.956 0 0 0-.445-1.8z"/>
</svg>
--- a/browser/themes/shared/icons/device-desktop.svg
+++ b/browser/themes/shared/icons/device-desktop.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill-opacity="context-fill-opacity" fill="context-fill" d="M15.5 12H15V3a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v9H.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h15a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zM10 13H6v-1h4zm3-2H3V4h10z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M15.5 12H15V3a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v9H.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h15a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zM10 13H6v-1h4zm3-2H3V4h10z"/>
</svg>
--- a/browser/themes/shared/icons/device-mobile.svg
+++ b/browser/themes/shared/icons/device-mobile.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill-opacity="context-fill-opacity" fill="context-fill" d="M12 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zM9 15H7v-1h2zm3-2.5a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 .5.5z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M12 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zM9 15H7v-1h2zm3-2.5a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 .5.5z"/>
</svg>
--- a/browser/themes/shared/icons/device-tablet.svg
+++ b/browser/themes/shared/icons/device-tablet.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill-opacity="context-fill-opacity" fill="context-fill" d="M14 1H2C.895 1 0 1.895 0 3v10c0 1.105.895 2 2 2h12c1.105 0 2-.895 2-2V3c0-1.105-.895-2-2-2zm-1 11.5c0 .276-.224.5-.5.5h-10c-.276 0-.5-.224-.5-.5v-9c0-.276.224-.5.5-.5h10c.276 0 .5.224.5.5v9zM15 9h-1V7h1v2z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M14 1H2C.895 1 0 1.895 0 3v10c0 1.105.895 2 2 2h12c1.105 0 2-.895 2-2V3c0-1.105-.895-2-2-2zm-1 11.5c0 .276-.224.5-.5.5h-10c-.276 0-.5-.224-.5-.5v-9c0-.276.224-.5.5-.5h10c.276 0 .5.224.5.5v9zM15 9h-1V7h1v2z"/>
</svg>
--- a/browser/themes/shared/icons/edit-copy.svg
+++ b/browser/themes/shared/icons/edit-copy.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M14.707 8.293l-3-3A1 1 0 0 0 11 5h-1V4a1 1 0 0 0-.293-.707l-3-3A1 1 0 0 0 6 0H3a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3v3a2 2 0 0 0 2 2h5a2 2 0 0 0 2-2V9a1 1 0 0 0-.293-.707zM12.586 9H11V7.414zm-5-5H6V2.414zM6 7v2H3V2h2v2.5a.5.5 0 0 0 .5.5H8a2 2 0 0 0-2 2zm2 7V7h2v2.5a.5.5 0 0 0 .5.5H13v4z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M14.707 8.293l-3-3A1 1 0 0 0 11 5h-1V4a1 1 0 0 0-.293-.707l-3-3A1 1 0 0 0 6 0H3a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3v3a2 2 0 0 0 2 2h5a2 2 0 0 0 2-2V9a1 1 0 0 0-.293-.707zM12.586 9H11V7.414zm-5-5H6V2.414zM6 7v2H3V2h2v2.5a.5.5 0 0 0 .5.5H8a2 2 0 0 0-2 2zm2 7V7h2v2.5a.5.5 0 0 0 .5.5H13v4z"/>
</svg>
--- a/browser/themes/shared/icons/edit-cut.svg
+++ b/browser/themes/shared/icons/edit-cut.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M11.5 10a2.481 2.481 0 0 0-.379.038L3.977 1.214a2.5 2.5 0 0 0-.371 3.515l2.789 3.444-1.51 1.866A2.486 2.486 0 0 0 4.5 10a2.522 2.522 0 1 0 2.329 1.609L8 10.159 9.172 11.6A2.5 2.5 0 1 0 11.5 10zm-7 3.75a1.25 1.25 0 1 1 1.25-1.25 1.251 1.251 0 0 1-1.25 1.25zm7 0a1.25 1.25 0 1 1 1.25-1.25 1.251 1.251 0 0 1-1.25 1.25zm.9-9.021a2.5 2.5 0 0 0-.371-3.515L8.5 5.569l1.608 1.986z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M11.5 10a2.481 2.481 0 0 0-.379.038L3.977 1.214a2.5 2.5 0 0 0-.371 3.515l2.789 3.444-1.51 1.866A2.486 2.486 0 0 0 4.5 10a2.522 2.522 0 1 0 2.329 1.609L8 10.159 9.172 11.6A2.5 2.5 0 1 0 11.5 10zm-7 3.75a1.25 1.25 0 1 1 1.25-1.25 1.251 1.251 0 0 1-1.25 1.25zm7 0a1.25 1.25 0 1 1 1.25-1.25 1.251 1.251 0 0 1-1.25 1.25zm.9-9.021a2.5 2.5 0 0 0-.371-3.515L8.5 5.569l1.608 1.986z"/>
</svg>
--- a/browser/themes/shared/icons/edit-paste.svg
+++ b/browser/themes/shared/icons/edit-paste.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M11 2H9.95a2.5 2.5 0 0 0-4.9 0H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 7a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5h7zm0-5H4V3h1.05a1 1 0 0 0 .98-.8 1.5 1.5 0 0 1 2.939 0 1 1 0 0 0 .98.8H11zM7.5 2a.5.5 0 1 0 .5.5.5.5 0 0 0-.5-.5zm-2 5h4a.5.5 0 0 0 0-1h-4a.5.5 0 0 0 0 1zm0 2h2a.5.5 0 0 0 0-1h-2a.5.5 0 0 0 0 1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M11 2H9.95a2.5 2.5 0 0 0-4.9 0H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 7a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5h7zm0-5H4V3h1.05a1 1 0 0 0 .98-.8 1.5 1.5 0 0 1 2.939 0 1 1 0 0 0 .98.8H11zM7.5 2a.5.5 0 1 0 .5.5.5.5 0 0 0-.5-.5zm-2 5h4a.5.5 0 0 0 0-1h-4a.5.5 0 0 0 0 1zm0 2h2a.5.5 0 0 0 0-1h-2a.5.5 0 0 0 0 1z"/>
</svg>
deleted file mode 100644
--- a/browser/themes/shared/icons/email-link.svg
+++ /dev/null
@@ -1,7 +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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill-opacity="context-fill-opacity" fill="context-fill">
- <path d="M13 2H3a3.013 3.013 0 0 0-3 3v6a3.013 3.013 0 0 0 3 3h10a3.013 3.013 0 0 0 3-3V5a3.013 3.013 0 0 0-3-3zm1 9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1z"/>
- <path d="M8 9a.5.5 0 0 1-.294-.1l-5.5-4a.5.5 0 1 1 .588-.8L8 7.882 13.207 4.1a.5.5 0 0 1 .588.809l-5.5 4A.5.5 0 0 1 8 9z"/>
-</svg>
--- a/browser/themes/shared/icons/feed.svg
+++ b/browser/themes/shared/icons/feed.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M3.5 10A2.5 2.5 0 1 0 6 12.5 2.5 2.5 0 0 0 3.5 10zM2 1a1 1 0 0 0 0 2 10.883 10.883 0 0 1 11 11 1 1 0 0 0 2 0A12.862 12.862 0 0 0 2 1zm0 4a1 1 0 0 0 0 2 6.926 6.926 0 0 1 7 7 1 1 0 0 0 2 0 8.9 8.9 0 0 0-9-9z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M3.5 10A2.5 2.5 0 1 0 6 12.5 2.5 2.5 0 0 0 3.5 10zM2 1a1 1 0 0 0 0 2 10.883 10.883 0 0 1 11 11 1 1 0 0 0 2 0A12.862 12.862 0 0 0 2 1zm0 4a1 1 0 0 0 0 2 6.926 6.926 0 0 1 7 7 1 1 0 0 0 2 0 8.9 8.9 0 0 0-9-9z"/>
</svg>
--- a/browser/themes/shared/icons/find.svg
+++ b/browser/themes/shared/icons/find.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M15.707 14.293l-4.822-4.822a6.019 6.019 0 1 0-1.414 1.414l4.822 4.822a1 1 0 0 0 1.414-1.414zM6 10a4 4 0 1 1 4-4 4 4 0 0 1-4 4z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M15.707 14.293l-4.822-4.822a6.019 6.019 0 1 0-1.414 1.414l4.822 4.822a1 1 0 0 0 1.414-1.414zM6 10a4 4 0 1 1 4-4 4 4 0 0 1-4 4z"/>
</svg>
--- a/browser/themes/shared/icons/folder.svg
+++ b/browser/themes/shared/icons/folder.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M14 3H8.151L6.584 1.538A2 2 0 0 0 5.219 1H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zM5.219 3l1.072 1H2V3zM14 13H2V5h6v-.014c.05 0 .1.014.151.014H14z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M14 3H8.151L6.584 1.538A2 2 0 0 0 5.219 1H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zM5.219 3l1.072 1H2V3zM14 13H2V5h6v-.014c.05 0 .1.014.151.014H14z"/>
</svg>
--- a/browser/themes/shared/icons/forget.svg
+++ b/browser/themes/shared/icons/forget.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M6.854 10.854l2-2A.5.5 0 0 0 9 8.5v-4a.5.5 0 0 0-1 0v3.793l-1.854 1.853a.5.5 0 1 0 .707.707zM8 0a8.011 8.011 0 0 0-7 4.184V1.5a.5.5 0 0 0-1 0v5a.5.5 0 0 0 .5.5h5a.5.5 0 0 0 0-1H2.344a.938.938 0 0 0 .056-.085 6 6 0 1 1 0 4.184 1 1 0 0 0-1.873.7A7.991 7.991 0 1 0 8 0z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M6.854 10.854l2-2A.5.5 0 0 0 9 8.5v-4a.5.5 0 0 0-1 0v3.793l-1.854 1.853a.5.5 0 1 0 .707.707zM8 0a8.011 8.011 0 0 0-7 4.184V1.5a.5.5 0 0 0-1 0v5a.5.5 0 0 0 .5.5h5a.5.5 0 0 0 0-1H2.344a.938.938 0 0 0 .056-.085 6 6 0 1 1 0 4.184 1 1 0 0 0-1.873.7A7.991 7.991 0 1 0 8 0z"/>
</svg>
--- a/browser/themes/shared/icons/forward.svg
+++ b/browser/themes/shared/icons/forward.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M15.707,7.293l-6-6A1,1,0,0,0,8.293,2.707L12.586,7H1A1,1,0,0,0,1,9H12.586L8.293,13.293a1,1,0,1,0,1.414,1.414l6-6A1,1,0,0,0,15.707,7.293Z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M15.707,7.293l-6-6A1,1,0,0,0,8.293,2.707L12.586,7H1A1,1,0,0,0,1,9H12.586L8.293,13.293a1,1,0,1,0,1.414,1.414l6-6A1,1,0,0,0,15.707,7.293Z"/>
</svg>
--- a/browser/themes/shared/icons/fullscreen-exit.svg
+++ b/browser/themes/shared/icons/fullscreen-exit.svg
@@ -1,7 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M7,8H2a1,1,0,0,0,0,2H4.586L1.293,13.293a1,1,0,1,0,1.414,1.414L6,11.414V14a1,1,0,0,0,2,0V9A1,1,0,0,0,7,8Z"/>
<path d="M14,6H11.414l3.293-3.293a1,1,0,0,0-1.414-1.414L10,4.586V2A1,1,0,0,0,8,2V7A1,1,0,0,0,9,8h5a1,1,0,0,0,0-2Z"/>
</svg>
--- a/browser/themes/shared/icons/fullscreen.svg
+++ b/browser/themes/shared/icons/fullscreen.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M7.707 8.293a1 1 0 0 0-1.414 0L3 11.586V9a1 1 0 0 0-2 0v5a1 1 0 0 0 1 1h5a1 1 0 1 0 0-2H4.414l3.293-3.293a1 1 0 0 0 0-1.414zM14 1H9a1 1 0 0 0 0 2h2.586L8.293 6.293a1 1 0 1 0 1.414 1.414L13 4.414V7a1 1 0 0 0 2 0V2a1 1 0 0 0-1-1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M7.707 8.293a1 1 0 0 0-1.414 0L3 11.586V9a1 1 0 0 0-2 0v5a1 1 0 0 0 1 1h5a1 1 0 1 0 0-2H4.414l3.293-3.293a1 1 0 0 0 0-1.414zM14 1H9a1 1 0 0 0 0 2h2.586L8.293 6.293a1 1 0 1 0 1.414 1.414L13 4.414V7a1 1 0 0 0 2 0V2a1 1 0 0 0-1-1z"/>
</svg>
--- a/browser/themes/shared/icons/history.svg
+++ b/browser/themes/shared/icons/history.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M8 0a8 8 0 1 0 8 8 8.009 8.009 0 0 0-8-8zm0 14a6 6 0 1 1 6-6 6.007 6.007 0 0 1-6 6zm3.5-6H8V4.5a.5.5 0 0 0-1 0v4a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 0-1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8 0a8 8 0 1 0 8 8 8.009 8.009 0 0 0-8-8zm0 14a6 6 0 1 1 6-6 6.007 6.007 0 0 1-6 6zm3.5-6H8V4.5a.5.5 0 0 0-1 0v4a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 0-1z"/>
</svg>
--- a/browser/themes/shared/icons/home.svg
+++ b/browser/themes/shared/icons/home.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M15.707,7.293l-7-7a1,1,0,0,0-1.414,0l-7,7A1,1,0,0,0,1.707,8.707L2,8.414V14a2,2,0,0,0,2,2h8a2,2,0,0,0,2-2V8.414l.293.293a1,1,0,0,0,1.414-1.414ZM8,11.5a.5.5,0,1,1,.5.5A.5.5,0,0,1,8,11.5ZM12,13a1,1,0,0,1-1,1H10V9A1,1,0,0,0,9,8H7A1,1,0,0,0,6,9v5H5a1,1,0,0,1-1-1V6.414l4-4,4,4Z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M15.707,7.293l-7-7a1,1,0,0,0-1.414,0l-7,7A1,1,0,0,0,1.707,8.707L2,8.414V14a2,2,0,0,0,2,2h8a2,2,0,0,0,2-2V8.414l.293.293a1,1,0,0,0,1.414-1.414ZM8,11.5a.5.5,0,1,1,.5.5A.5.5,0,0,1,8,11.5ZM12,13a1,1,0,0,1-1,1H10V9A1,1,0,0,0,9,8H7A1,1,0,0,0,6,9v5H5a1,1,0,0,1-1-1V6.414l4-4,4,4Z"/>
</svg>
--- a/browser/themes/shared/icons/library-bookmark-animation.svg
+++ b/browser/themes/shared/icons/library-bookmark-animation.svg
@@ -1,12 +1,12 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="1078" height="54" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="1078" height="54" fill="context-fill" fill-opacity="context-fill-opacity">
<svg>
<path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
</svg>
<svg x="22">
<defs>
<mask id="a" mask-type="alpha">
<path fill="context-stroke" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
<path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
--- a/browser/themes/shared/icons/library.svg
+++ b/browser/themes/shared/icons/library.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M5 3a1 1 0 0 0-1 1v10a1 1 0 0 0 2 0V4a1 1 0 0 0-1-1zm3-1a1 1 0 0 0-1 1v11a1 1 0 0 0 2 0V3a1 1 0 0 0-1-1zm7.939 11.658l-4-11a1 1 0 1 0-1.879.684l4 11a1 1 0 1 0 1.879-.684zM2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 2 0V2a1 1 0 0 0-1-1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M5 3a1 1 0 0 0-1 1v10a1 1 0 0 0 2 0V4a1 1 0 0 0-1-1zm3-1a1 1 0 0 0-1 1v11a1 1 0 0 0 2 0V3a1 1 0 0 0-1-1zm7.939 11.658l-4-11a1 1 0 1 0-1.879.684l4 11a1 1 0 1 0 1.879-.684zM2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 2 0V2a1 1 0 0 0-1-1z"/>
</svg>
--- a/browser/themes/shared/icons/link.svg
+++ b/browser/themes/shared/icons/link.svg
@@ -1,8 +1,8 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <rect fill-opacity="context-fill-opacity" fill="context-fill" x="7" y="3.286" width="2" height="9.429" rx="1" ry="1" transform="rotate(-45 8 8)"/>
- <path fill-opacity="context-fill-opacity" fill="context-fill" d="M2.354 4.522L4.485 2.39a.5.5 0 0 1 .711 0l3.19 3.19.014-.015a2 2 0 0 0 0-2.821L6.272.616a2 2 0 0 0-2.821 0L.616 3.451a2 2 0 0 0 0 2.821L2.744 8.4a1.993 1.993 0 0 0 2.8.02l-3.19-3.186a.5.5 0 0 1 0-.712z"/>
- <path fill-opacity="context-fill-opacity" fill="context-fill" d="M15.416 9.759L13.287 7.63a2 2 0 0 0-2.821 0l-.015.015 3.189 3.189a.5.5 0 0 1 0 .711l-2.132 2.132a.5.5 0 0 1-.711 0L7.61 10.49a1.993 1.993 0 0 0 .02 2.8l2.128 2.128a2 2 0 0 0 2.821 0l2.835-2.835a2 2 0 0 0 .002-2.824z"/>
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
+ <rect x="7" y="3.286" width="2" height="9.429" rx="1" ry="1" transform="rotate(-45 8 8)"/>
+ <path d="M2.354 4.522L4.485 2.39a.5.5 0 0 1 .711 0l3.19 3.19.014-.015a2 2 0 0 0 0-2.821L6.272.616a2 2 0 0 0-2.821 0L.616 3.451a2 2 0 0 0 0 2.821L2.744 8.4a1.993 1.993 0 0 0 2.8.02l-3.19-3.186a.5.5 0 0 1 0-.712z"/>
+ <path d="M15.416 9.759L13.287 7.63a2 2 0 0 0-2.821 0l-.015.015 3.189 3.189a.5.5 0 0 1 0 .711l-2.132 2.132a.5.5 0 0 1-.711 0L7.61 10.49a1.993 1.993 0 0 0 .02 2.8l2.128 2.128a2 2 0 0 0 2.821 0l2.835-2.835a2 2 0 0 0 .002-2.824z"/>
</svg>
--- a/browser/themes/shared/icons/mail.svg
+++ b/browser/themes/shared/icons/mail.svg
@@ -1,7 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M13 2H3a3.013 3.013 0 0 0-3 3v6a3.013 3.013 0 0 0 3 3h10a3.013 3.013 0 0 0 3-3V5a3.013 3.013 0 0 0-3-3zm1 9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1z"/>
<path d="M8 9a.5.5 0 0 1-.294-.1l-5.5-4a.5.5 0 1 1 .588-.8L8 7.882 13.207 4.1a.5.5 0 0 1 .588.809l-5.5 4A.5.5 0 0 1 8 9z"/>
</svg>
--- a/browser/themes/shared/icons/menu.svg
+++ b/browser/themes/shared/icons/menu.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M3,4H13a1,1,0,0,0,0-2H3A1,1,0,0,0,3,4ZM13,7H3A1,1,0,0,0,3,9H13a1,1,0,0,0,0-2Zm0,5H3a1,1,0,0,0,0,2H13a1,1,0,0,0,0-2Z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M3,4H13a1,1,0,0,0,0-2H3A1,1,0,0,0,3,4ZM13,7H3A1,1,0,0,0,3,9H13a1,1,0,0,0,0-2Zm0,5H3a1,1,0,0,0,0,2H13a1,1,0,0,0,0-2Z"/>
</svg>
--- a/browser/themes/shared/icons/new-tab.svg
+++ b/browser/themes/shared/icons/new-tab.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M11 11V9a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v6H1a1 1 0 0 0 0 2h7v-1a1 1 0 0 1 1-1zm4.5 1H13V9.5a.5.5 0 0 0-1 0V12H9.5a.5.5 0 0 0 0 1H12v2.5a.5.5 0 0 0 1 0V13h2.5a.5.5 0 0 0 0-1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M11 11V9a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v6H1a1 1 0 0 0 0 2h7v-1a1 1 0 0 1 1-1zm4.5 1H13V9.5a.5.5 0 0 0-1 0V12H9.5a.5.5 0 0 0 0 1H12v2.5a.5.5 0 0 0 1 0V13h2.5a.5.5 0 0 0 0-1z"/>
</svg>
--- a/browser/themes/shared/icons/new-window.svg
+++ b/browser/themes/shared/icons/new-window.svg
@@ -1,7 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M15.5 12H13V9.5a.5.5 0 0 0-1 0V12H9.5a.5.5 0 0 0 0 1H12v2.5a.5.5 0 0 0 1 0V13h2.5a.5.5 0 0 0 0-1z"/>
<path d="M16 4a3 3 0 0 0-3-3H3a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h4.03v-.006a.994.994 0 0 0 0-1.987V13H3a1 1 0 0 1-1-1V6h12v1.952h.01c0 .017-.01.031-.01.048a1 1 0 0 0 2 0c0-.017-.009-.031-.01-.048H16zM2 5V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1z"/>
</svg>
--- a/browser/themes/shared/icons/open.svg
+++ b/browser/themes/shared/icons/open.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M14.859 3.2a1.335 1.335 0 0 1-1.217.8H13v1h1v8H2V5h8V4h-.642a1.365 1.365 0 0 1-1.325-1.11L6.584 1.538A2 2 0 0 0 5.219 1H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V5a2 2 0 0 0-1.141-1.8zM2 3h3.219l1.072 1H2zm7.854-.146L11 1.707V8.5a.5.5 0 0 0 1 0V1.707l1.146 1.146a.5.5 0 1 0 .707-.707l-2-2a.5.5 0 0 0-.707 0l-2 2a.5.5 0 0 0 .707.707z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M14.859 3.2a1.335 1.335 0 0 1-1.217.8H13v1h1v8H2V5h8V4h-.642a1.365 1.365 0 0 1-1.325-1.11L6.584 1.538A2 2 0 0 0 5.219 1H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V5a2 2 0 0 0-1.141-1.8zM2 3h3.219l1.072 1H2zm7.854-.146L11 1.707V8.5a.5.5 0 0 0 1 0V1.707l1.146 1.146a.5.5 0 1 0 .707-.707l-2-2a.5.5 0 0 0-.707 0l-2 2a.5.5 0 0 0 .707.707z"/>
</svg>
--- a/browser/themes/shared/icons/page-action.svg
+++ b/browser/themes/shared/icons/page-action.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill-opacity="context-fill-opacity" fill="context-fill" d="M2 6a2 2 0 1 0 2 2 2 2 0 0 0-2-2zm6 0a2 2 0 1 0 2 2 2 2 0 0 0-2-2zm6 0a2 2 0 1 0 2 2 2 2 0 0 0-2-2z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M2 6a2 2 0 1 0 2 2 2 2 0 0 0-2-2zm6 0a2 2 0 1 0 2 2 2 2 0 0 0-2-2zm6 0a2 2 0 1 0 2 2 2 2 0 0 0-2-2z"/>
</svg>
--- a/browser/themes/shared/icons/print.svg
+++ b/browser/themes/shared/icons/print.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M14 5h-1V1a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v4H2a2 2 0 0 0-2 2v5h3v3a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-3h3V7a2 2 0 0 0-2-2zM2.5 8a.5.5 0 1 1 .5-.5.5.5 0 0 1-.5.5zm9.5 7H4v-5h8zm0-10H4V1h8zm-6.5 7h4a.5.5 0 0 0 0-1h-4a.5.5 0 1 0 0 1zm0 2h5a.5.5 0 0 0 0-1h-5a.5.5 0 1 0 0 1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M14 5h-1V1a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v4H2a2 2 0 0 0-2 2v5h3v3a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-3h3V7a2 2 0 0 0-2-2zM2.5 8a.5.5 0 1 1 .5-.5.5.5 0 0 1-.5.5zm9.5 7H4v-5h8zm0-10H4V1h8zm-6.5 7h4a.5.5 0 0 0 0-1h-4a.5.5 0 1 0 0 1zm0 2h5a.5.5 0 0 0 0-1h-5a.5.5 0 1 0 0 1z"/>
</svg>
--- a/browser/themes/shared/icons/privateBrowsing.svg
+++ b/browser/themes/shared/icons/privateBrowsing.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M12.408 11.992c-1.663 0-2.813-2-4.408-2s-2.844 2-4.408 2C1.54 11.992.025 10.048 0 6.719c-.015-2.068.6-2.727 3.265-2.727S6.709 5.082 8 5.082s2.071-1.091 4.735-1.091 3.28.66 3.265 2.727c-.025 3.33-1.54 5.274-3.592 5.274zM4.572 6.537c-1.619.07-2.286 1.035-2.286 1.273s1.073.909 2.122.909 2.286-.384 2.286-.727a1.9 1.9 0 0 0-2.122-1.455zm6.857 0a1.9 1.9 0 0 0-2.123 1.455c0 .343 1.236.727 2.286.727s2.122-.671 2.122-.909-.667-1.203-2.286-1.273z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M12.408 11.992c-1.663 0-2.813-2-4.408-2s-2.844 2-4.408 2C1.54 11.992.025 10.048 0 6.719c-.015-2.068.6-2.727 3.265-2.727S6.709 5.082 8 5.082s2.071-1.091 4.735-1.091 3.28.66 3.265 2.727c-.025 3.33-1.54 5.274-3.592 5.274zM4.572 6.537c-1.619.07-2.286 1.035-2.286 1.273s1.073.909 2.122.909 2.286-.384 2.286-.727a1.9 1.9 0 0 0-2.122-1.455zm6.857 0a1.9 1.9 0 0 0-2.123 1.455c0 .343 1.236.727 2.286.727s2.122-.671 2.122-.909-.667-1.203-2.286-1.273z"/>
</svg>
--- a/browser/themes/shared/icons/quit.svg
+++ b/browser/themes/shared/icons/quit.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M8 6a1 1 0 0 0 1-1V1a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1zm3.5-4.032a1 1 0 0 0-1 1.732A4.946 4.946 0 0 1 13 8 5 5 0 0 1 3 8a4.946 4.946 0 0 1 2.5-4.3 1 1 0 0 0-1-1.732 7 7 0 1 0 7.006 0z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M8 6a1 1 0 0 0 1-1V1a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1zm3.5-4.032a1 1 0 0 0-1 1.732A4.946 4.946 0 0 1 13 8 5 5 0 0 1 3 8a4.946 4.946 0 0 1 2.5-4.3 1 1 0 0 0-1-1.732 7 7 0 1 0 7.006 0z"/>
</svg>
--- a/browser/themes/shared/icons/reload-to-stop.svg
+++ b/browser/themes/shared/icons/reload-to-stop.svg
@@ -1,12 +1,12 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="468" height="20" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="468" height="20" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M10.414 10l5.293-5.293a1 1 0 0 0-1.414-1.414L9 8.586 3.707 3.293a1 1 0 0 0-1.414 1.414L7.586 10l-5.293 5.293a1 1 0 1 0 1.414 1.414L9 11.414l5.293 5.293a1 1 0 0 0 1.414-1.414z"/>
<svg x="18">
<path d="M10.414 10l5.293-5.293a1 1 0 0 0-1.414-1.414L9 8.586 3.707 3.293a1 1 0 0 0-1.414 1.414L7.586 10l-5.293 5.293a1 1 0 1 0 1.414 1.414L9 11.414l5.293 5.293a1 1 0 0 0 1.414-1.414z"/>
</svg>
<svg x="36">
<path d="M10.414 10l5.293-5.293a1 1 0 0 0-1.414-1.414L9 8.586 3.707 3.293a1 1 0 0 0-1.414 1.414L7.586 10l-5.293 5.293a1 1 0 1 0 1.414 1.414L9 11.414l5.293 5.293a1 1 0 0 0 1.414-1.414z"/>
</svg>
<svg x="54">
--- a/browser/themes/shared/icons/reload.svg
+++ b/browser/themes/shared/icons/reload.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M15,1a1,1,0,0,0-1,1V4.418A6.995,6.995,0,1,0,8,15a6.954,6.954,0,0,0,4.95-2.05,1,1,0,0,0-1.414-1.414A5.019,5.019,0,1,1,12.549,6H10a1,1,0,0,0,0,2h5a1,1,0,0,0,1-1V2A1,1,0,0,0,15,1Z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M15,1a1,1,0,0,0-1,1V4.418A6.995,6.995,0,1,0,8,15a6.954,6.954,0,0,0,4.95-2.05,1,1,0,0,0-1.414-1.414A5.019,5.019,0,1,1,12.549,6H10a1,1,0,0,0,0,2h5a1,1,0,0,0,1-1V2A1,1,0,0,0,15,1Z"/>
</svg>
--- a/browser/themes/shared/icons/restore-session.svg
+++ b/browser/themes/shared/icons/restore-session.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M13 0H3a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h4l-.3.4a1 1 0 1 0 1.6 1.2l1.5-2a1 1 0 0 0 0-1.2l-1.5-2a1 1 0 0 0-1.6 1.2l.3.4H3a1 1 0 0 1-1-1V5h12v6a1 1 0 0 1-1 1 1 1 0 0 0 0 2 3 3 0 0 0 3-3V3a3 3 0 0 0-3-3zM2 4V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1z"/>
</svg>
--- a/browser/themes/shared/icons/save.svg
+++ b/browser/themes/shared/icons/save.svg
@@ -1,7 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M14 3h-2v2h2v8H2V5h7V3h-.849L6.584 1.538A2 2 0 0 0 5.219 1H2a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zM2 3h3.219l1.072 1H2z"/>
<path d="M8.146 6.146a.5.5 0 0 0 0 .707l2 2a.5.5 0 0 0 .707 0l2-2a.5.5 0 1 0-.707-.707L11 7.293V.5a.5.5 0 0 0-1 0v6.793L8.854 6.146a.5.5 0 0 0-.708 0z"/>
</svg>
--- a/browser/themes/shared/icons/settings.svg
+++ b/browser/themes/shared/icons/settings.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M15 7h-2.1a4.967 4.967 0 0 0-.732-1.753l1.49-1.49a1 1 0 0 0-1.414-1.414l-1.49 1.49A4.968 4.968 0 0 0 9 3.1V1a1 1 0 0 0-2 0v2.1a4.968 4.968 0 0 0-1.753.732l-1.49-1.49a1 1 0 0 0-1.414 1.415l1.49 1.49A4.967 4.967 0 0 0 3.1 7H1a1 1 0 0 0 0 2h2.1a4.968 4.968 0 0 0 .737 1.763c-.014.013-.032.017-.045.03l-1.45 1.45a1 1 0 1 0 1.414 1.414l1.45-1.45c.013-.013.018-.031.03-.045A4.968 4.968 0 0 0 7 12.9V15a1 1 0 0 0 2 0v-2.1a4.968 4.968 0 0 0 1.753-.732l1.49 1.49a1 1 0 0 0 1.414-1.414l-1.49-1.49A4.967 4.967 0 0 0 12.9 9H15a1 1 0 0 0 0-2zM5 8a3 3 0 1 1 3 3 3 3 0 0 1-3-3z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M15 7h-2.1a4.967 4.967 0 0 0-.732-1.753l1.49-1.49a1 1 0 0 0-1.414-1.414l-1.49 1.49A4.968 4.968 0 0 0 9 3.1V1a1 1 0 0 0-2 0v2.1a4.968 4.968 0 0 0-1.753.732l-1.49-1.49a1 1 0 0 0-1.414 1.415l1.49 1.49A4.967 4.967 0 0 0 3.1 7H1a1 1 0 0 0 0 2h2.1a4.968 4.968 0 0 0 .737 1.763c-.014.013-.032.017-.045.03l-1.45 1.45a1 1 0 1 0 1.414 1.414l1.45-1.45c.013-.013.018-.031.03-.045A4.968 4.968 0 0 0 7 12.9V15a1 1 0 0 0 2 0v-2.1a4.968 4.968 0 0 0 1.753-.732l1.49 1.49a1 1 0 0 0 1.414-1.414l-1.49-1.49A4.967 4.967 0 0 0 12.9 9H15a1 1 0 0 0 0-2zM5 8a3 3 0 1 1 3 3 3 3 0 0 1-3-3z"/>
</svg>
--- a/browser/themes/shared/icons/sidebars-right.svg
+++ b/browser/themes/shared/icons/sidebars-right.svg
@@ -1,7 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M13 1H3a3.007 3.007 0 0 0-3 3v8a3.009 3.009 0 0 0 3 3h10a3.005 3.005 0 0 0 3-3V4a3.012 3.012 0 0 0-3-3zM2 12V4a1 1 0 0 1 1-1h5v10H3a1 1 0 0 1-1-1zm12 0a1 1 0 0 1-1 1H9V3h4a1 1 0 0 1 1 1z"/>
<path d="M12.5 5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 0 1zm0 2h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 0 1zm-1 2h-1a.5.5 0 0 1 0-1h1a.5.5 0 0 1 0 1z"/>
</svg>
--- a/browser/themes/shared/icons/sidebars.svg
+++ b/browser/themes/shared/icons/sidebars.svg
@@ -1,7 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M3 1h10c1.655.004 2.996 1.345 3 3v8c-.005 1.655-1.345 2.995-3 3H3c-1.656-.003-2.997-1.344-3-3V4c.007-1.654 1.346-2.993 3-3zm11 11V4c0-.552-.448-1-1-1H8v10h5c.552 0 1-.448 1-1zM2 12c0 .552.448 1 1 1h4V3H3c-.552 0-1 .448-1 1v8z"/>
<path d="M3.5 5h2c.276 0 .5-.224.5-.5S5.776 4 5.5 4h-2c-.276 0-.5.224-.5.5s.224.5.5.5zm0 2h2c.276 0 .5-.224.5-.5S5.776 6 5.5 6h-2c-.276 0-.5.224-.5.5s.224.5.5.5zm1 2h1c.276 0 .5-.224.5-.5S5.776 8 5.5 8h-1c-.276 0-.5.224-.5.5s.224.5.5.5z"/>
</svg>
--- a/browser/themes/shared/icons/stop-to-reload.svg
+++ b/browser/themes/shared/icons/stop-to-reload.svg
@@ -1,12 +1,12 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="468" height="20" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="468" height="20" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M13.55 8H11a1 1 0 0 0 0 2h5a1 1 0 0 0 1-1V4a1 1 0 0 0-2 0v2.418"/>
<path d="M15 6.418C13.02 3.1 8.724 2.018 5.408 4c-3.317 1.98-4.4 6.275-2.42 9.592A6.997 6.997 0 0 0 9 17a6.954 6.954 0 0 0 4.95-2.05 1 1 0 1 0-1.414-1.414A5.02 5.02 0 1 1 13.55 8"/>
<svg x="18">
<path d="M13.735 8.606l-1.72-.78a.74.74 0 0 0-.61 1.35l3.37 1.53a.74.74 0 0 0 .98-.37l1.532-3.372a.74.74 0 0 0-1.35-.612l-.74 1.63"/>
<path d="M15.91 8.954c-.58-3.82-4.146-6.446-7.965-5.867-3.82.58-6.447 4.144-5.868 7.964a6.997 6.997 0 0 0 4.275 5.43 6.954 6.954 0 0 0 5.357-.025 1 1 0 1 0-.775-1.844 5.02 5.02 0 1 1 3.032-4.74"/>
</svg>
<svg x="36">
<path d="M14.088 9.318l-.89-.845a.482.482 0 0 0-.663.7l1.747 1.656a.482.482 0 0 0 .68-.02l1.657-1.746a.482.482 0 0 0-.7-.662l-.8.844"/>
--- a/browser/themes/shared/icons/stop.svg
+++ b/browser/themes/shared/icons/stop.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M9.414 8l5.293-5.293a1 1 0 0 0-1.414-1.414L8 6.586 2.707 1.293a1 1 0 0 0-1.414 1.414L6.586 8l-5.293 5.293a1 1 0 1 0 1.414 1.414L8 9.414l5.293 5.293a1 1 0 0 0 1.414-1.414z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M9.414 8l5.293-5.293a1 1 0 0 0-1.414-1.414L8 6.586 2.707 1.293a1 1 0 0 0-1.414 1.414L6.586 8l-5.293 5.293a1 1 0 1 0 1.414 1.414L8 9.414l5.293 5.293a1 1 0 0 0 1.414-1.414z"/>
</svg>
--- a/browser/themes/shared/icons/sync.svg
+++ b/browser/themes/shared/icons/sync.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M14 1a1 1 0 0 0-1 1v1.146A6.948 6.948 0 0 0 1.227 6.307a1 1 0 1 0 1.94.484A4.983 4.983 0 0 1 8 3a4.919 4.919 0 0 1 3.967 2H10a1 1 0 0 0 0 2h4a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zm.046 7.481a1 1 0 0 0-1.213.728A4.983 4.983 0 0 1 8 13a4.919 4.919 0 0 1-3.967-2H6a1 1 0 0 0 0-2H2a1 1 0 0 0-1 1v4a1 1 0 0 0 2 0v-1.146a6.948 6.948 0 0 0 11.773-3.161 1 1 0 0 0-.727-1.212z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M14 1a1 1 0 0 0-1 1v1.146A6.948 6.948 0 0 0 1.227 6.307a1 1 0 1 0 1.94.484A4.983 4.983 0 0 1 8 3a4.919 4.919 0 0 1 3.967 2H10a1 1 0 0 0 0 2h4a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zm.046 7.481a1 1 0 0 0-1.213.728A4.983 4.983 0 0 1 8 13a4.919 4.919 0 0 1-3.967-2H6a1 1 0 0 0 0-2H2a1 1 0 0 0-1 1v4a1 1 0 0 0 2 0v-1.146a6.948 6.948 0 0 0 11.773-3.161 1 1 0 0 0-.727-1.212z"/>
</svg>
--- a/browser/themes/shared/icons/synced-tabs.svg
+++ b/browser/themes/shared/icons/synced-tabs.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M15 11h-1V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v6H1a1 1 0 0 0 0 2h14a1 1 0 1 0 0-2z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M15 11h-1V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v6H1a1 1 0 0 0 0 2h14a1 1 0 1 0 0-2z"/>
</svg>
--- a/browser/themes/shared/icons/toolbar.svg
+++ b/browser/themes/shared/icons/toolbar.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M13 1H3a3.007 3.007 0 0 0-3 3v8a3.009 3.009 0 0 0 3 3h10a3.005 3.005 0 0 0 3-3V4a3.012 3.012 0 0 0-3-3zM3 3h10a1 1 0 0 1 1 1v1H2V4a1 1 0 0 1 1-1zm11 3v1H2V6zm-1 7H3a1 1 0 0 1-1-1V8h12v4a1 1 0 0 1-1 1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M13 1H3a3.007 3.007 0 0 0-3 3v8a3.009 3.009 0 0 0 3 3h10a3.005 3.005 0 0 0 3-3V4a3.012 3.012 0 0 0-3-3zM3 3h10a1 1 0 0 1 1 1v1H2V4a1 1 0 0 1 1-1zm11 3v1H2V6zm-1 7H3a1 1 0 0 1-1-1V8h12v4a1 1 0 0 1-1 1z"/>
</svg>
--- a/browser/themes/shared/icons/webIDE.svg
+++ b/browser/themes/shared/icons/webIDE.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M9.884 13.209l-2.121-2.122 6.176-6.148L16.06 7.06zM11.46 5c.02.1.019.217.037.32l-.875.9A10.929 10.929 0 0 0 10.456 5H8v2h1.856L8.88 8H8v.9L7 9.925V8H4.322a12.382 12.382 0 0 0 .222 2h2.383l-.977 1H4.808a7.92 7.92 0 0 0 .342.887l-.837 2.379A7.486 7.486 0 1 1 13.6 3.164L11.809 5zm-6.832 7.966A8.619 8.619 0 0 1 3.79 11H2.362a6.111 6.111 0 0 0 2.266 1.966zM1.813 10H3.54a12.64 12.64 0 0 1-.23-2H1.332a6.184 6.184 0 0 0 .481 2zm0-5a6.184 6.184 0 0 0-.481 2H3.31a12.64 12.64 0 0 1 .23-2zm.549-1H3.79a8.619 8.619 0 0 1 .838-1.966A6.111 6.111 0 0 0 2.362 4zM7 1.332a6.216 6.216 0 0 0-.669.13A5.269 5.269 0 0 0 4.808 4H7zM7 5H4.544a12.382 12.382 0 0 0-.222 2H7zm1.669-3.538A6.209 6.209 0 0 0 8 1.332V4h2.192a5.268 5.268 0 0 0-1.523-2.538zm1.7.573A8.619 8.619 0 0 1 11.21 4h1.428a6.111 6.111 0 0 0-2.266-1.966zM9.034 14.148L5 16l1.863-4.024zm1.8.039l3.239-3.14a7.483 7.483 0 0 1-3.241 3.14z" fill-rule="evenodd"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M9.884 13.209l-2.121-2.122 6.176-6.148L16.06 7.06zM11.46 5c.02.1.019.217.037.32l-.875.9A10.929 10.929 0 0 0 10.456 5H8v2h1.856L8.88 8H8v.9L7 9.925V8H4.322a12.382 12.382 0 0 0 .222 2h2.383l-.977 1H4.808a7.92 7.92 0 0 0 .342.887l-.837 2.379A7.486 7.486 0 1 1 13.6 3.164L11.809 5zm-6.832 7.966A8.619 8.619 0 0 1 3.79 11H2.362a6.111 6.111 0 0 0 2.266 1.966zM1.813 10H3.54a12.64 12.64 0 0 1-.23-2H1.332a6.184 6.184 0 0 0 .481 2zm0-5a6.184 6.184 0 0 0-.481 2H3.31a12.64 12.64 0 0 1 .23-2zm.549-1H3.79a8.619 8.619 0 0 1 .838-1.966A6.111 6.111 0 0 0 2.362 4zM7 1.332a6.216 6.216 0 0 0-.669.13A5.269 5.269 0 0 0 4.808 4H7zM7 5H4.544a12.382 12.382 0 0 0-.222 2H7zm1.669-3.538A6.209 6.209 0 0 0 8 1.332V4h2.192a5.268 5.268 0 0 0-1.523-2.538zm1.7.573A8.619 8.619 0 0 1 11.21 4h1.428a6.111 6.111 0 0 0-2.266-1.966zM9.034 14.148L5 16l1.863-4.024zm1.8.039l3.239-3.14a7.483 7.483 0 0 1-3.241 3.14z" fill-rule="evenodd"/>
</svg>
--- a/browser/themes/shared/icons/window.svg
+++ b/browser/themes/shared/icons/window.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
- <path fill="context-fill" d="M13 1H3a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h11a2 2 0 0 0 2-2V4a3 3 0 0 0-3-3zm1 11a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6h12zm0-7H2V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1z"/>
+ <path fill="context-fill" fill-opacity="context-fill-opacity" d="M13 1H3a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h11a2 2 0 0 0 2-2V4a3 3 0 0 0-3-3zm1 11a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6h12zm0-7H2V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1z"/>
</svg>
--- a/browser/themes/shared/icons/zoom-in.svg
+++ b/browser/themes/shared/icons/zoom-in.svg
@@ -1,7 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M14 7H9V2a1 1 0 0 0-2 0v5H2a1 1 0 0 0 0 2h5v5a1 1 0 0 0 2 0V9h5a1 1 0 0 0 0-2z"/>
</svg>
--- a/browser/themes/shared/icons/zoom-out.svg
+++ b/browser/themes/shared/icons/zoom-out.svg
@@ -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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="context-fill">
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity">
<rect x="2" y="7" width="12" height="2" rx="1"/>
</svg>
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -130,17 +130,16 @@
skin/classic/browser/customize.svg (../shared/icons/customize.svg)
skin/classic/browser/developer.svg (../shared/icons/developer.svg)
skin/classic/browser/device-mobile.svg (../shared/icons/device-mobile.svg)
skin/classic/browser/device-tablet.svg (../shared/icons/device-tablet.svg)
skin/classic/browser/device-desktop.svg (../shared/icons/device-desktop.svg)
skin/classic/browser/edit-copy.svg (../shared/icons/edit-copy.svg)
skin/classic/browser/edit-cut.svg (../shared/icons/edit-cut.svg)
skin/classic/browser/edit-paste.svg (../shared/icons/edit-paste.svg)
- skin/classic/browser/email-link.svg (../shared/icons/email-link.svg)
skin/classic/browser/feed.svg (../shared/icons/feed.svg)
skin/classic/browser/find.svg (../shared/icons/find.svg)
skin/classic/browser/folder.svg (../shared/icons/folder.svg)
skin/classic/browser/forget.svg (../shared/icons/forget.svg)
skin/classic/browser/forward.svg (../shared/icons/forward.svg)
skin/classic/browser/fullscreen.svg (../shared/icons/fullscreen.svg)
skin/classic/browser/fullscreen-exit.svg (../shared/icons/fullscreen-exit.svg)
skin/classic/browser/history.svg (../shared/icons/history.svg)
--- a/browser/themes/shared/tabbrowser/newtab.svg
+++ b/browser/themes/shared/tabbrowser/newtab.svg
@@ -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="16" height="16" xmlns="http://www.w3.org/2000/svg" fill="context-fill">
+<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" fill="context-fill" fill-opacity="context-fill-opacity">
<path d="M14 7H9V2a1 1 0 0 0-2 0v5H2a1 1 0 1 0 0 2h5v5a1 1 0 0 0 2 0V9h5a1 1 0 0 0 0-2z"/>
</svg>
--- a/browser/themes/shared/tabs.inc.css
+++ b/browser/themes/shared/tabs.inc.css
@@ -391,16 +391,20 @@
transition: opacity 150ms ease;
}
.tabbrowser-tab:not([visuallyselected=true]),
.tabbrowser-tab:-moz-lwtheme {
color: inherit;
}
+.tabbrowser-tab[visuallyselected=true]:-moz-lwtheme {
+ color: var(--toolbar-color, inherit);
+}
+
.tab-line {
height: 2px;
}
/* Selected tab */
.tab-background {
border: 1px none transparent;
@@ -545,18 +549,19 @@
display: -moz-box;
}
/* Tab bar scroll arrows */
.tabbrowser-arrowscrollbox > .scrollbutton-up,
.tabbrowser-arrowscrollbox > .scrollbutton-down {
list-style-image: url(chrome://browser/skin/arrow-left.svg);
- -moz-context-properties: fill;
+ -moz-context-properties: fill, fill-opacity;
fill: currentColor;
+ fill-opacity: .8;
}
.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl),
.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(ltr) {
transform: scaleX(-1);
}
/* New tab button */
--- a/browser/themes/shared/toolbarbutton-icons.inc.css
+++ b/browser/themes/shared/toolbarbutton-icons.inc.css
@@ -1,26 +1,26 @@
:root {
--toolbarbutton-icon-fill-attention: #0a84ff;
}
+:root:-moz-lwtheme {
+ --toolbarbutton-icon-fill-opacity: 1;
+}
+
toolbar[brighttext] {
--toolbarbutton-icon-fill-attention: #45a1ff;
}
.toolbarbutton-animatable-box,
.toolbarbutton-1 {
- -moz-context-properties: fill;
- fill: #4c4c4c;
-}
-
-.toolbarbutton-animatable-box[brighttext],
-toolbar[brighttext] .toolbarbutton-animatable-box,
-toolbar[brighttext] .toolbarbutton-1 {
- fill: #fff;
+ color: inherit;
+ -moz-context-properties: fill, fill-opacity;
+ fill: currentColor;
+ fill-opacity: var(--toolbarbutton-icon-fill-opacity);
}
#back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
#forward-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
#reload-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
#nav-bar-overflow-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
#PlacesChevron:-moz-locale-dir(rtl) > .toolbarbutton-icon,
#panic-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
@@ -305,45 +305,51 @@ toolbar[brighttext] .toolbarbutton-1 {
}
@keyframes overflow-animation {
from {
transform: translateX(0);
}
50% {
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
to {
transform: translateX(-1260px);
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
}
@keyframes overflow-animation-rtl {
from {
transform: scaleX(-1) translateX(0);
}
50% {
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
to {
transform: scaleX(-1) translateX(-1260px);
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
}
/* The animation is supposed to show the blue fill color for 520ms, then the
fade to the toolbarbutton-fill color for the remaining 210ms. Thus with an
animation-duration of 730ms, 71% is the point where we start the fade out. */
@keyframes overflow-fade {
from {
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
71% {
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
to {
fill: inherit;
}
}
#nav-bar-overflow-button > .toolbarbutton-animatable-box {
position: absolute;
@@ -420,43 +426,48 @@ toolbar[brighttext] .toolbarbutton-1 {
transform: translateX(0);
fill: inherit;
}
25% {
fill: inherit;
}
50% {
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
to {
transform: translateX(-1056px);
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
}
@keyframes library-bookmark-animation-rtl {
from {
transform: translateX(1056px);
fill: inherit;
}
25% {
fill: inherit;
}
50% {
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
to {
transform: translateX(0);
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
}
@keyframes library-bookmark-fade {
from {
fill: var(--toolbarbutton-icon-fill-attention);
+ fill-opacity: 1;
}
to {
fill: inherit;
}
}
#library-button[animate] > .toolbarbutton-icon {
fill: transparent;
@@ -489,17 +500,17 @@ toolbar[brighttext] .toolbarbutton-1 {
}
.toolbarbutton-animatable-box[animate="bookmark"] > .toolbarbutton-animatable-image {
background-image: url("chrome://browser/skin/library-bookmark-animation.svg");
width: 1078px;
animation-name: library-bookmark-animation;
animation-duration: 800ms;
animation-timing-function: steps(48);
- -moz-context-properties: fill, stroke;
+ -moz-context-properties: fill, fill-opacity, stroke;
stroke: var(--toolbarbutton-icon-fill-attention);
}
.toolbarbutton-animatable-box[animate="bookmark"]:-moz-locale-dir(rtl) > .toolbarbutton-animatable-image {
animation-name: library-bookmark-animation-rtl;
}
.toolbarbutton-animatable-box[animate="bookmark"][fade] > .toolbarbutton-animatable-image {
--- a/browser/themes/shared/urlbar-searchbar.inc.css
+++ b/browser/themes/shared/urlbar-searchbar.inc.css
@@ -84,17 +84,17 @@
#pageAction-panel-copyURL,
#pageAction-urlbar-copyURL {
list-style-image: url("chrome://browser/skin/link.svg");
}
#pageAction-panel-emailLink,
#pageAction-urlbar-emailLink {
- list-style-image: url("chrome://browser/skin/email-link.svg");
+ list-style-image: url("chrome://browser/skin/mail.svg");
}
#pageAction-panel-sendToDevice,
#pageAction-urlbar-sendToDevice {
list-style-image: url("chrome://browser/skin/device-mobile.svg");
}
.pageAction-sendToDevice-device[clientType=mobile] {
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -17,16 +17,17 @@
--toolbar-non-lwt-bgcolor: -moz-dialog;
--toolbar-non-lwt-textcolor: -moz-dialogtext;
--toolbar-non-lwt-bgimage: linear-gradient(rgba(255,255,255,.15), rgba(255,255,255,.15));
--toolbar-bgcolor: var(--toolbar-non-lwt-bgcolor);
--toolbar-bgimage: var(--toolbar-non-lwt-bgimage);
--toolbarbutton-vertical-text-padding: calc(var(--toolbarbutton-inner-padding) - 1px);
--toolbarbutton-border-radius: 2px;
+ --toolbarbutton-icon-fill-opacity: 1;
--panel-separator-color: ThreeDLightShadow;
--arrowpanel-dimmed: hsla(0,0%,80%,.3);
--arrowpanel-dimmed-further: hsla(0,0%,80%,.45);
--arrowpanel-dimmed-even-further: hsla(0,0%,80%,.8);
--urlbar-separator-color: ThreeDLightShadow;
@@ -36,16 +37,18 @@
@media (-moz-windows-default-theme) {
:root {
--tabs-border: rgba(0,0,0,.3);
--toolbar-non-lwt-bgcolor: #f9f9fa;
--toolbar-non-lwt-textcolor: #0c0c0d;
--toolbar-non-lwt-bgimage: none;
+ --toolbarbutton-icon-fill-opacity: .7;
+
--panel-separator-color: hsla(210,4%,10%,.14);
--toolbox-border-bottom-color: #e1e1e2;
}
}
:root:-moz-lwtheme {
--tabs-border: rgba(0,0,0,.3);
@@ -79,16 +82,17 @@
#navigator-toolbox > toolbar {
-moz-appearance: none;
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
background-color: var(--toolbar-bgcolor);
background-image: var(--toolbar-bgimage);
background-clip: padding-box;
+ color: var(--toolbar-color, inherit);
}
#toolbar-menubar,
#TabsToolbar {
color: var(--titlebar-text-color);
}
@media (-moz-windows-compositor: 0),
--- a/devtools/client/netmonitor/src/assets/styles/netmonitor.css
+++ b/devtools/client/netmonitor/src/assets/styles/netmonitor.css
@@ -780,16 +780,21 @@ body,
.panel-container,
.properties-view {
display: flex;
flex-direction: column;
overflow-x: hidden;
overflow-y: auto;
}
+.panel-container .tree-container .objectBox {
+ white-space: normal;
+ word-wrap: break-word;
+}
+
.properties-view {
flex-grow: 1;
}
.properties-view .searchbox-section {
flex: 0 1 auto;
}
--- a/devtools/client/netmonitor/src/components/properties-view.js
+++ b/devtools/client/netmonitor/src/components/properties-view.js
@@ -45,25 +45,27 @@ const PropertiesView = createClass({
propTypes: {
object: PropTypes.object,
enableInput: PropTypes.bool,
expandableStrings: PropTypes.bool,
filterPlaceHolder: PropTypes.string,
sectionNames: PropTypes.array,
openLink: PropTypes.func,
+ cropLimit: PropTypes.number
},
getDefaultProps() {
return {
enableInput: true,
enableFilter: true,
expandableStrings: false,
filterPlaceHolder: "",
sectionNames: [],
+ cropLimit: 1024
};
},
getInitialState() {
return {
filterText: "",
};
},
@@ -116,20 +118,20 @@ const PropertiesView = createClass({
// Put 2 here to not dup this method
if (member.level === 0 && member.type === "object" ||
(typeof member.value === "object" && member.value && member.value.value)) {
return null;
}
return Rep(Object.assign(props, {
// FIXME: A workaround for the issue in StringRep
- // Force StringRep to crop the text everytime
+ // Force StringRep to crop the text every time
member: Object.assign({}, member, { open: false }),
mode: MODE.TINY,
- cropLimit: 60,
+ cropLimit: this.props.cropLimit,
}));
},
shouldRenderSearchBox(object) {
return this.props.enableFilter && object && Object.keys(object)
.filter((section) => !object[section][EDITOR_CONFIG_ID]).length > 0;
},
--- a/devtools/client/shared/components/reps/reps.css
+++ b/devtools/client/shared/components/reps/reps.css
@@ -1,24 +1,25 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* 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/. */
.theme-dark,
.theme-light {
--number-color: var(--theme-highlight-green);
- --string-color: var(--theme-highlight-orange);
+ --string-color: var(--theme-highlight-red);
--null-color: var(--theme-comment);
- --object-color: var(--theme-body-color);
+ --object-color: var(--theme-highlight-blue);
--caption-color: var(--theme-highlight-blue);
- --location-color: var(--theme-content-color1);
+ --location-color: var(--theme-comment);
--source-link-color: var(--theme-highlight-blue);
- --node-color: var(--theme-highlight-bluegrey);
- --reference-color: var(--theme-highlight-purple);
+ --node-color: var(--theme-highlight-purple);
+ --reference-color: var(--theme-highlight-blue);
+ --comment-node-color: var(--theme-comment);
}
.theme-firebug {
--number-color: #000088;
--string-color: #FF0000;
--null-color: #787878;
--object-color: DarkGreen;
--caption-color: #444444;
@@ -68,26 +69,26 @@
}
.objectBox-function,
.objectBox-stackTrace,
.objectBox-profile {
color: var(--object-color);
}
-.objectBox-Location {
- font-style: italic;
+.objectBox-Location,
+.location {
color: var(--location-color);
}
.objectBox-null,
.objectBox-undefined,
.objectBox-hint,
+.objectBox-nan,
.logRowHint {
- font-style: italic;
color: var(--null-color);
}
.objectBox-sourceLink {
position: absolute;
right: 4px;
top: 2px;
padding-left: 8px;
@@ -104,62 +105,77 @@
padding: 0 2px;
}
/******************************************************************************/
.objectBox-event,
.objectBox-eventLog,
.objectBox-regexp,
-.objectBox-object,
-.objectBox-Date {
- font-weight: bold;
+.objectBox-object {
color: var(--object-color);
white-space: pre-wrap;
}
+.objectBox .Date {
+ color: var(--string-color);
+ white-space: pre-wrap;
+}
+
/******************************************************************************/
-.objectBox-object .nodeName,
-.objectBox-NamedNodeMap .nodeName,
-.objectBox-NamedNodeMap .objectEqual,
-.objectBox-Attr .attrEqual,
-.objectBox-Attr .attrTitle {
+.objectBox.theme-comment {
+ color: var(--comment-node-color);
+}
+
+.tag-name {
+ color: var(--object-color);
+}
+
+.attrName {
+ color: var(--string-color);
+}
+
+.attrEqual,
+.objectEqual {
+ color: var(--comment-node-color);
+}
+
+.attrValue,
+.attrValue.objectBox-string {
color: var(--node-color);
}
-.objectBox-object .nodeName {
- font-weight: normal;
+.angleBracket {
+ color: var(--theme-body-color);
}
/******************************************************************************/
.objectLeftBrace,
.objectRightBrace,
.arrayLeftBracket,
.arrayRightBracket {
- color: var(--theme-highlight-blue);
+ color: var(--object-color);
}
/******************************************************************************/
/* Cycle reference*/
.objectBox-Reference {
font-weight: bold;
color: var(--reference-color);
}
-[class*="objectBox-"] > .objectTitle {
- color: var(--theme-highlight-blue);
- font-style: italic;
+[class*="objectBox"] > .objectTitle {
+ color: var(--object-color);
}
.caption {
- font-weight: bold;
- color: var(--caption-color);
+ color: var(--caption-color);
}
/******************************************************************************/
/* Themes */
.theme-dark .objectBox-null,
.theme-dark .objectBox-undefined,
.theme-light .objectBox-null,
@@ -177,40 +193,50 @@
.theme-light .caption {
font-weight: normal;
}
/******************************************************************************/
/* Open DOMNode in inspector button */
.open-inspector svg {
- fill: rgb(215, 215, 215);
+ fill: var(--comment-node-color);
height: 16px;
width: 16px;
margin-left: .25em;
cursor: pointer;
vertical-align: middle;
}
.objectBox-node:hover .open-inspector svg,
.objectBox-textNode:hover .open-inspector svg,
.open-inspector svg:hover {
- fill: rgb(65, 175, 230);
+ fill: var(--theme-highlight-blue);
}
/******************************************************************************/
/* "more…" ellipsis */
.more-ellipsis {
- color: var(--theme-comment);
+ color: var(--comment-node-color);
}
/* 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 {
+ --arrow-width: 10px;
+ --arrow-single-margin: 5px;
+ --arrow-total-width: calc(var(--arrow-width) + var(--arrow-single-margin));
+ --arrow-fill-color: var(--theme-splitter-color, #9B9B9B);
+ --tree-indent-width: 1em;
+ --tree-indent-border-color: #A2D1FF;
+ --tree-indent-border-width: 1px;
+ --tree-node-hover-background-color: #F0F9FE;
+ --tree-node-focus-color: white;
+ --tree-node-focus-background-color: var(--theme-selection-background, #0a84ff);
overflow: auto;
}
.tree.inline {
display: inline-block;
}
.tree.nowrap {
@@ -224,49 +250,62 @@
-o-user-select: none;
user-select: none;
}
.tree button {
display: block;
}
-.tree .node {
- padding: 0 0.25em;
- position: relative;
+.tree .tree-node {
cursor: pointer;
}
-.tree .node.focused {
- color: white;
- background-color: var(--theme-selection-background);
+.tree .tree-node:not(.focused):hover {
+ background-color: var(--tree-node-hover-background-color);
+}
+
+.tree .tree-node.focused {
+ color: var(--tree-node-focus-color);
+ background-color: var(--tree-node-focus-background-color);
+ --arrow-fill-color: currentColor;
}
.arrow svg {
- fill: var(--theme-splitter-color);
+ fill: var(--arrow-fill-color);
transition: transform 0.125s ease;
- width: 10px;
- margin-inline-end: 5px;
+ width: var(--arrow-width);
+ margin-inline-end: var(--arrow-single-margin);
transform: rotate(-90deg);
}
html[dir="rtl"] .arrow svg,
.arrow svg:dir(rtl),
.arrow svg:-moz-locale-dir(rtl) {
transform: rotate(90deg);
}
.arrow.expanded.expanded svg {
transform: rotate(0deg);
}
+/* 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/. */
-.object-label, .object-label * {
+.tree.object-inspector .object-label,
+.tree.object-inspector .object-label * {
color: var(--theme-highlight-blue);
}
-.tree .node .unavailable {
- color: var(--theme-content-color3);
+.tree.object-inspector .node .unavailable {
+ color: var(--theme-comment);
}
-.lessen {
- opacity: 0.6;
+.tree.object-inspector .lessen,
+.tree.object-inspector .lessen *,
+.tree.object-inspector .lessen .object-label,
+.tree.object-inspector .lessen .object-label * {
+ color: var(--theme-comment);
}
+.object-inspector .object-delimiter {
+ color: var(--theme-comment);
+}
--- a/devtools/client/shared/components/reps/reps.js
+++ b/devtools/client/shared/components/reps/reps.js
@@ -1,18 +1,18 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory(require("devtools/client/shared/vendor/react"));
+ module.exports = factory(require("devtools/client/shared/vendor/react"), require("devtools/client/shared/vendor/lodash"));
else if(typeof define === 'function' && define.amd)
- define(["devtools/client/shared/vendor/react"], factory);
+ define(["devtools/client/shared/vendor/react", "devtools/client/shared/vendor/lodash"], factory);
else {
- var a = typeof exports === 'object' ? factory(require("devtools/client/shared/vendor/react")) : factory(root["devtools/client/shared/vendor/react"]);
+ var a = typeof exports === 'object' ? factory(require("devtools/client/shared/vendor/react"), require("devtools/client/shared/vendor/lodash")) : factory(root["devtools/client/shared/vendor/react"], root["devtools/client/shared/vendor/lodash"]);
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
-})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
+})(this, function(__WEBPACK_EXTERNAL_MODULE_0__, __WEBPACK_EXTERNAL_MODULE_49__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
@@ -65,29 +65,32 @@ return /******/ (function(modules) { //
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/assets/build";
/******/
/******/ // Load entry module and return exports
-/******/ return __webpack_require__(__webpack_require__.s = 26);
+/******/ return __webpack_require__(__webpack_require__.s = 15);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_0__;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const validProtocols = /^(http|https|ftp|data|javascript|resource|chrome):/i;
const tokenSplitRegex = /(\s|\'|\"|\\)+/;
@@ -486,17 +489,20 @@ module.exports = {
maybeEscapePropertyName,
getGripPreviewItems,
getGripType,
tokenSplitRegex
};
/***/ }),
/* 2 */
-/***/ (function(module, exports) {
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
/* 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/. */
module.exports = {
MODE: {
TINY: Symbol("TINY"),
@@ -504,55 +510,58 @@ module.exports = {
LONG: Symbol("LONG")
}
};
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
-__webpack_require__(27);
+__webpack_require__(16);
// Load all existing rep templates
-const Undefined = __webpack_require__(28);
-const Null = __webpack_require__(29);
-const StringRep = __webpack_require__(16);
-const LongStringRep = __webpack_require__(30);
-const Number = __webpack_require__(31);
-const ArrayRep = __webpack_require__(17);
-const Obj = __webpack_require__(32);
-const SymbolRep = __webpack_require__(33);
-const InfinityRep = __webpack_require__(34);
-const NaNRep = __webpack_require__(35);
-const Accessor = __webpack_require__(36);
+const Undefined = __webpack_require__(17);
+const Null = __webpack_require__(18);
+const StringRep = __webpack_require__(5);
+const LongStringRep = __webpack_require__(19);
+const Number = __webpack_require__(20);
+const ArrayRep = __webpack_require__(7);
+const Obj = __webpack_require__(21);
+const SymbolRep = __webpack_require__(22);
+const InfinityRep = __webpack_require__(23);
+const NaNRep = __webpack_require__(24);
+const Accessor = __webpack_require__(25);
// DOM types (grips)
-const Attribute = __webpack_require__(37);
-const DateTime = __webpack_require__(38);
-const Document = __webpack_require__(39);
-const Event = __webpack_require__(40);
-const Func = __webpack_require__(41);
-const PromiseRep = __webpack_require__(42);
-const RegExp = __webpack_require__(43);
-const StyleSheet = __webpack_require__(44);
-const CommentNode = __webpack_require__(45);
-const ElementNode = __webpack_require__(46);
-const TextNode = __webpack_require__(50);
-const ErrorRep = __webpack_require__(51);
-const Window = __webpack_require__(52);
-const ObjectWithText = __webpack_require__(53);
-const ObjectWithURL = __webpack_require__(54);
-const GripArray = __webpack_require__(19);
-const GripMap = __webpack_require__(55);
-const GripMapEntry = __webpack_require__(20);
-const Grip = __webpack_require__(9);
+const Attribute = __webpack_require__(26);
+const DateTime = __webpack_require__(27);
+const Document = __webpack_require__(28);
+const Event = __webpack_require__(29);
+const Func = __webpack_require__(30);
+const PromiseRep = __webpack_require__(31);
+const RegExp = __webpack_require__(32);
+const StyleSheet = __webpack_require__(33);
+const CommentNode = __webpack_require__(34);
+const ElementNode = __webpack_require__(35);
+const TextNode = __webpack_require__(37);
+const ErrorRep = __webpack_require__(38);
+const Window = __webpack_require__(39);
+const ObjectWithText = __webpack_require__(40);
+const ObjectWithURL = __webpack_require__(41);
+const GripArray = __webpack_require__(11);
+const GripMap = __webpack_require__(12);
+const GripMapEntry = __webpack_require__(13);
+const Grip = __webpack_require__(6);
// List of all registered template.
// XXX there should be a way for extensions to register a new
// or modify an existing rep.
let reps = [RegExp, StyleSheet, Event, DateTime, CommentNode, ElementNode, TextNode, Attribute, LongStringRep, Func, PromiseRep, ArrayRep, Document, Window, ObjectWithText, ObjectWithURL, ErrorRep, GripArray, GripMap, GripMapEntry, Grip, Undefined, Null, StringRep, Number, SymbolRep, InfinityRep, NaNRep, Accessor];
/**
* Generic rep that is using for rendering native JS types or an object.
@@ -640,16 +649,19 @@ module.exports = {
// Exporting for tests
getRep
};
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
maybeEscapePropertyName,
@@ -683,17 +695,17 @@ PropRep.propTypes = {
/**
* Function that given a name, a delimiter and an object returns an array
* of React elements representing an object property (e.g. `name: value`)
*
* @param {Object} props
* @return {Array} Array of React elements.
*/
function PropRep(props) {
- const Grip = __webpack_require__(9);
+ const Grip = __webpack_require__(6);
const { Rep } = __webpack_require__(3);
let {
name,
mode,
equal,
suppressQuotes
} = props;
@@ -720,112 +732,139 @@ function PropRep(props) {
}, equal), Rep(Object.assign({}, props))];
}
// Exports from this module
module.exports = wrapRender(PropRep);
/***/ }),
/* 5 */
-/***/ (function(module, exports) {
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* 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/. */
+
+// Dependencies
+const React = __webpack_require__(0);
+
+const {
+ containsURL,
+ isURL,
+ escapeString,
+ getGripType,
+ rawCropString,
+ sanitizeString,
+ wrapRender,
+ tokenSplitRegex
+} = __webpack_require__(1);
+
+// Shortcuts
+const { a, span } = React.DOM;
/**
- * Checks if `value` is classified as an `Array` object.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an array, else `false`.
- * @example
- *
- * _.isArray([1, 2, 3]);
- * // => true
- *
- * _.isArray(document.body.children);
- * // => false
- *
- * _.isArray('abc');
- * // => false
- *
- * _.isArray(_.noop);
- * // => false
+ * Renders a string. String value is enclosed within quotes.
*/
-var isArray = Array.isArray;
-
-module.exports = isArray;
-
+StringRep.propTypes = {
+ useQuotes: React.PropTypes.bool,
+ escapeWhitespace: React.PropTypes.bool,
+ style: React.PropTypes.object,
+ object: React.PropTypes.string.isRequired,
+ member: React.PropTypes.any,
+ cropLimit: React.PropTypes.number,
+ openLink: React.PropTypes.func,
+ className: React.PropTypes.string
+};
+
+function StringRep(props) {
+ let {
+ className,
+ cropLimit,
+ object: text,
+ member,
+ style,
+ useQuotes = true,
+ escapeWhitespace = true,
+ openLink
+ } = props;
+
+ const classNames = ["objectBox", "objectBox-string"];
+ if (className) {
+ classNames.push(className);
+ }
+ let config = { className: classNames.join(" ") };
+ if (style) {
+ config.style = style;
+ }
+
+ if (useQuotes) {
+ text = escapeString(text, escapeWhitespace);
+ } else {
+ text = sanitizeString(text);
+ }
+
+ if ((!member || !member.open) && cropLimit) {
+ text = rawCropString(text, cropLimit);
+ }
+
+ if (!containsURL(text)) {
+ return span(config, text);
+ }
+
+ const items = [];
+
+ // As we walk through the tokens of the source string, we make sure to preserve
+ // the original whitespace that separated the tokens.
+ let tokens = text.split(tokenSplitRegex);
+ let textIndex = 0;
+ let tokenStart;
+ tokens.forEach((token, i) => {
+ tokenStart = text.indexOf(token, textIndex);
+ if (isURL(token)) {
+ items.push(text.slice(textIndex, tokenStart));
+ textIndex = tokenStart + token.length;
+
+ items.push(a({
+ className: "url",
+ title: token,
+ href: token,
+ draggable: false,
+ onClick: openLink ? e => {
+ e.preventDefault();
+ openLink(token);
+ } : null
+ }, token));
+ }
+ });
+
+ // Clean up any non-URL text at the end of the source string.
+ items.push(text.slice(textIndex, text.length));
+ return span(config, ...items);
+}
+
+function supportsObject(object, noGrip = false) {
+ return getGripType(object, noGrip) == "string";
+}
+
+// Exports from this module
+
+module.exports = {
+ rep: wrapRender(StringRep),
+ supportsObject
+};
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
-var getNative = __webpack_require__(23);
-
-/* Built-in method references that are verified to be native. */
-var nativeCreate = getNative(Object, 'create');
-
-module.exports = nativeCreate;
-
-
-/***/ }),
-/* 7 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var eq = __webpack_require__(88);
-
-/**
- * Gets the index at which the `key` is found in `array` of key-value pairs.
- *
- * @private
- * @param {Array} array The array to inspect.
- * @param {*} key The key to search for.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
-function assocIndexOf(array, key) {
- var length = array.length;
- while (length--) {
- if (eq(array[length][0], key)) {
- return length;
- }
- }
- return -1;
-}
-
-module.exports = assocIndexOf;
-
-
-/***/ }),
-/* 8 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var isKeyable = __webpack_require__(94);
-
-/**
- * Gets the data for `map`.
- *
- * @private
- * @param {Object} map The map to query.
- * @param {string} key The reference key.
- * @returns {*} Returns the map data.
- */
-function getMapData(map, key) {
- var data = map.__data__;
- return isKeyable(key)
- ? data[typeof key == 'string' ? 'string' : 'hash']
- : data.map;
-}
-
-module.exports = getMapData;
-
-
-/***/ }),
-/* 9 */
-/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Dependencies
@@ -1127,296 +1166,21 @@ let Grip = {
supportsObject,
maxLengthMap
};
// Exports from this module
module.exports = Grip;
/***/ }),
-/* 10 */
-/***/ (function(module, exports, __webpack_require__) {
-
-/* 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/. */
-
-const React = __webpack_require__(0);
-const InlineSVG = __webpack_require__(47);
-
-const svg = {
- "arrow": __webpack_require__(48),
- "open-inspector": __webpack_require__(49)
-};
-
-Svg.propTypes = {
- className: React.PropTypes.string
-};
-
-function Svg(name, props) {
- if (!svg[name]) {
- throw new Error("Unknown SVG: " + name);
- }
- let className = name;
- if (props && props.className) {
- className = `${name} ${props.className}`;
- }
- if (name === "subSettings") {
- className = "";
- }
- props = Object.assign({}, props, { className, src: svg[name] });
- return React.createElement(InlineSVG, props);
-}
-
-module.exports = Svg;
-
-/***/ }),
-/* 11 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var baseGetTag = __webpack_require__(12),
- isObjectLike = __webpack_require__(15);
-
-/** `Object#toString` result references. */
-var symbolTag = '[object Symbol]';
-
-/**
- * Checks if `value` is classified as a `Symbol` primitive or object.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
- * @example
- *
- * _.isSymbol(Symbol.iterator);
- * // => true
- *
- * _.isSymbol('abc');
- * // => false
- */
-function isSymbol(value) {
- return typeof value == 'symbol' ||
- (isObjectLike(value) && baseGetTag(value) == symbolTag);
-}
-
-module.exports = isSymbol;
-
-
-/***/ }),
-/* 12 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var Symbol = __webpack_require__(13),
- getRawTag = __webpack_require__(66),
- objectToString = __webpack_require__(67);
-
-/** `Object#toString` result references. */
-var nullTag = '[object Null]',
- undefinedTag = '[object Undefined]';
-
-/** Built-in value references. */
-var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
-
-/**
- * The base implementation of `getTag` without fallbacks for buggy environments.
- *
- * @private
- * @param {*} value The value to query.
- * @returns {string} Returns the `toStringTag`.
- */
-function baseGetTag(value) {
- if (value == null) {
- return value === undefined ? undefinedTag : nullTag;
- }
- return (symToStringTag && symToStringTag in Object(value))
- ? getRawTag(value)
- : objectToString(value);
-}
-
-module.exports = baseGetTag;
-
-
-/***/ }),
-/* 13 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var root = __webpack_require__(14);
-
-/** Built-in value references. */
-var Symbol = root.Symbol;
-
-module.exports = Symbol;
-
-
-/***/ }),
-/* 14 */
+/* 7 */
/***/ (function(module, exports, __webpack_require__) {
-var freeGlobal = __webpack_require__(64);
-
-/** Detect free variable `self`. */
-var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
-
-/** Used as a reference to the global object. */
-var root = freeGlobal || freeSelf || Function('return this')();
-
-module.exports = root;
-
-
-/***/ }),
-/* 15 */
-/***/ (function(module, exports) {
-
-/**
- * Checks if `value` is object-like. A value is object-like if it's not `null`
- * and has a `typeof` result of "object".
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
- * @example
- *
- * _.isObjectLike({});
- * // => true
- *
- * _.isObjectLike([1, 2, 3]);
- * // => true
- *
- * _.isObjectLike(_.noop);
- * // => false
- *
- * _.isObjectLike(null);
- * // => false
- */
-function isObjectLike(value) {
- return value != null && typeof value == 'object';
-}
-
-module.exports = isObjectLike;
-
-
-/***/ }),
-/* 16 */
-/***/ (function(module, exports, __webpack_require__) {
-
-/* 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/. */
-
-// Dependencies
-const React = __webpack_require__(0);
-
-const {
- containsURL,
- isURL,
- escapeString,
- getGripType,
- rawCropString,
- sanitizeString,
- wrapRender,
- tokenSplitRegex
-} = __webpack_require__(1);
-
-// Shortcuts
-const { a, span } = React.DOM;
-
-/**
- * Renders a string. String value is enclosed within quotes.
- */
-StringRep.propTypes = {
- useQuotes: React.PropTypes.bool,
- escapeWhitespace: React.PropTypes.bool,
- style: React.PropTypes.object,
- object: React.PropTypes.string.isRequired,
- member: React.PropTypes.any,
- cropLimit: React.PropTypes.number,
- openLink: React.PropTypes.func
-};
-
-function StringRep(props) {
- let {
- cropLimit,
- object: text,
- member,
- style,
- useQuotes = true,
- escapeWhitespace = true,
- openLink
- } = props;
-
- let config = { className: "objectBox objectBox-string" };
- if (style) {
- config.style = style;
- }
-
- if (useQuotes) {
- text = escapeString(text, escapeWhitespace);
- } else {
- text = sanitizeString(text);
- }
-
- if ((!member || !member.open) && cropLimit) {
- text = rawCropString(text, cropLimit);
- }
-
- if (!containsURL(text)) {
- return span(config, text);
- }
-
- const items = [];
-
- // As we walk through the tokens of the source string, we make sure to preserve
- // the original whitespace that separated the tokens.
- let tokens = text.split(tokenSplitRegex);
- let textIndex = 0;
- let tokenStart;
- tokens.forEach((token, i) => {
- tokenStart = text.indexOf(token, textIndex);
- if (isURL(token)) {
- items.push(text.slice(textIndex, tokenStart));
- textIndex = tokenStart + token.length;
-
- items.push(a({
- className: "url",
- title: token,
- href: token,
- draggable: false,
- onClick: openLink ? e => {
- e.preventDefault();
- openLink(token);
- } : null
- }, token));
- }
- });
-
- // Clean up any non-URL text at the end of the source string.
- items.push(text.slice(textIndex, text.length));
- return span(config, ...items);
-}
-
-function supportsObject(object, noGrip = false) {
- return getGripType(object, noGrip) == "string";
-}
-
-// Exports from this module
-
-module.exports = {
- rep: wrapRender(StringRep),
- supportsObject
-};
-
-/***/ }),
-/* 17 */
-/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
@@ -1528,34 +1292,42 @@ function ItemRep(props) {
mode
} = props;
return DOM.span({}, Rep(Object.assign({}, props, {
object: object,
mode: mode
})), delim);
}
+function getLength(object) {
+ return object.length;
+}
+
function supportsObject(object) {
return Array.isArray(object) || Object.prototype.toString.call(object) === "[object Arguments]";
}
const maxLengthMap = new Map();
maxLengthMap.set(MODE.SHORT, 3);
maxLengthMap.set(MODE.LONG, 10);
// Exports from this module
module.exports = {
rep: wrapRender(ArrayRep),
supportsObject,
- maxLengthMap
+ maxLengthMap,
+ getLength
};
/***/ }),
-/* 18 */
-/***/ (function(module, exports) {
+/* 8 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
/* 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/. */
module.exports = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
@@ -1575,19 +1347,214 @@ module.exports = {
DOCUMENT_POSITION_PRECEDING: 0x02,
DOCUMENT_POSITION_FOLLOWING: 0x04,
DOCUMENT_POSITION_CONTAINS: 0x08,
DOCUMENT_POSITION_CONTAINED_BY: 0x10,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 0x20
};
/***/ }),
-/* 19 */
+/* 9 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/* 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/. */
+
+const React = __webpack_require__(0);
+const InlineSVG = __webpack_require__(10);
+
+const svg = {
+ "open-inspector": __webpack_require__(36)
+};
+
+Svg.propTypes = {
+ className: React.PropTypes.string
+};
+
+function Svg(name, props) {
+ if (!svg[name]) {
+ throw new Error("Unknown SVG: " + name);
+ }
+ let className = name;
+ if (props && props.className) {
+ className = `${name} ${props.className}`;
+ }
+ if (name === "subSettings") {
+ className = "";
+ }
+ props = Object.assign({}, props, { className, src: svg[name] });
+ return React.createElement(InlineSVG, props);
+}
+
+module.exports = Svg;
+
+/***/ }),
+/* 10 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
+Object.defineProperty(exports, '__esModule', {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var _react = __webpack_require__(0);
+
+var _react2 = _interopRequireDefault(_react);
+
+var DOMParser = typeof window !== 'undefined' && window.DOMParser;
+var process = process || {};
+process.env = process.env || {};
+var parserAvailable = typeof DOMParser !== 'undefined' && DOMParser.prototype != null && DOMParser.prototype.parseFromString != null;
+
+function isParsable(src) {
+ // kinda naive but meh, ain't gonna use full-blown parser for this
+ return parserAvailable && typeof src === 'string' && src.trim().substr(0, 4) === '<svg';
+}
+
+// parse SVG string using `DOMParser`
+function parseFromSVGString(src) {
+ var parser = new DOMParser();
+ return parser.parseFromString(src, "image/svg+xml");
+}
+
+// Transform DOM prop/attr names applicable to `<svg>` element but react-limited
+function switchSVGAttrToReactProp(propName) {
+ switch (propName) {
+ case 'class':
+ return 'className';
+ default:
+ return propName;
+ }
+}
+
+var InlineSVG = (function (_React$Component) {
+ _inherits(InlineSVG, _React$Component);
+
+ _createClass(InlineSVG, null, [{
+ key: 'defaultProps',
+ value: {
+ element: 'i',
+ raw: false,
+ src: ''
+ },
+ enumerable: true
+ }, {
+ key: 'propTypes',
+ value: {
+ src: _react2['default'].PropTypes.string.isRequired,
+ element: _react2['default'].PropTypes.string,
+ raw: _react2['default'].PropTypes.bool
+ },
+ enumerable: true
+ }]);
+
+ function InlineSVG(props) {
+ _classCallCheck(this, InlineSVG);
+
+ _get(Object.getPrototypeOf(InlineSVG.prototype), 'constructor', this).call(this, props);
+ this._extractSVGProps = this._extractSVGProps.bind(this);
+ }
+
+ // Serialize `Attr` objects in `NamedNodeMap`
+
+ _createClass(InlineSVG, [{
+ key: '_serializeAttrs',
+ value: function _serializeAttrs(map) {
+ var ret = {};
+ var prop = undefined;
+ for (var i = 0; i < map.length; i++) {
+ prop = switchSVGAttrToReactProp(map[i].name);
+ ret[prop] = map[i].value;
+ }
+ return ret;
+ }
+
+ // get <svg /> element props
+ }, {
+ key: '_extractSVGProps',
+ value: function _extractSVGProps(src) {
+ var map = parseFromSVGString(src).documentElement.attributes;
+ return map.length > 0 ? this._serializeAttrs(map) : null;
+ }
+
+ // get content inside <svg> element.
+ }, {
+ key: '_stripSVG',
+ value: function _stripSVG(src) {
+ return parseFromSVGString(src).documentElement.innerHTML;
+ }
+ }, {
+ key: 'componentWillReceiveProps',
+ value: function componentWillReceiveProps(_ref) {
+ var children = _ref.children;
+
+ if ("production" !== process.env.NODE_ENV && children != null) {
+ console.info('<InlineSVG />: `children` prop will be ignored.');
+ }
+ }
+ }, {
+ key: 'render',
+ value: function render() {
+ var Element = undefined,
+ __html = undefined,
+ svgProps = undefined;
+ var _props = this.props;
+ var element = _props.element;
+ var raw = _props.raw;
+ var src = _props.src;
+
+ var otherProps = _objectWithoutProperties(_props, ['element', 'raw', 'src']);
+
+ if (raw === true && isParsable(src)) {
+ Element = 'svg';
+ svgProps = this._extractSVGProps(src);
+ __html = this._stripSVG(src);
+ }
+ __html = __html || src;
+ Element = Element || element;
+ svgProps = svgProps || {};
+
+ return _react2['default'].createElement(Element, _extends({}, svgProps, otherProps, { src: null, children: null,
+ dangerouslySetInnerHTML: { __html: __html } }));
+ }
+ }]);
+
+ return InlineSVG;
+})(_react2['default'].Component);
+
+exports['default'] = InlineSVG;
+module.exports = exports['default'];
+
+/***/ }),
+/* 11 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
getGripType,
@@ -1775,23 +1742,234 @@ function supportsObject(grip, noGrip = f
const maxLengthMap = new Map();
maxLengthMap.set(MODE.SHORT, 3);
maxLengthMap.set(MODE.LONG, 10);
// Exports from this module
module.exports = {
rep: wrapRender(GripArray),
supportsObject,
- maxLengthMap
+ maxLengthMap,
+ getLength
};
/***/ }),
-/* 20 */
+/* 12 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
+/* 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/. */
+
+// Dependencies
+const React = __webpack_require__(0);
+const {
+ isGrip,
+ wrapRender
+} = __webpack_require__(1);
+const PropRep = __webpack_require__(4);
+const { MODE } = __webpack_require__(2);
+// Shortcuts
+const { span } = React.DOM;
+
+/**
+ * Renders an map. A map is represented by a list of its
+ * entries enclosed in curly brackets.
+ */
+GripMap.propTypes = {
+ object: React.PropTypes.object,
+ // @TODO Change this to Object.values once it's supported in Node's version of V8
+ mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])),
+ isInterestingEntry: React.PropTypes.func,
+ onDOMNodeMouseOver: React.PropTypes.func,
+ onDOMNodeMouseOut: React.PropTypes.func,
+ onInspectIconClick: React.PropTypes.func,
+ title: React.PropTypes.string
+};
+
+function GripMap(props) {
+ let {
+ mode,
+ object
+ } = props;
+
+ const config = {
+ "data-link-actor-id": object.actor,
+ className: "objectBox objectBox-object"
+ };
+
+ if (mode === MODE.TINY) {
+ return span(config, getTitle(props, object));
+ }
+
+ let propsArray = safeEntriesIterator(props, object, maxLengthMap.get(mode));
+
+ return span(config, getTitle(props, object), span({
+ className: "objectLeftBrace"
+ }, " { "), ...propsArray, span({
+ className: "objectRightBrace"
+ }, " }"));
+}
+
+function getTitle(props, object) {
+ let title = props.title || (object && object.class ? object.class : "Map");
+ return span({
+ className: "objectTitle"
+ }, title);
+}
+
+function safeEntriesIterator(props, object, max) {
+ max = typeof max === "undefined" ? 3 : max;
+ try {
+ return entriesIterator(props, object, max);
+ } catch (err) {
+ console.error(err);
+ }
+ return [];
+}
+
+function entriesIterator(props, object, max) {
+ // Entry filter. Show only interesting entries to the user.
+ let isInterestingEntry = props.isInterestingEntry || ((type, value) => {
+ return type == "boolean" || type == "number" || type == "string" && value.length != 0;
+ });
+
+ let mapEntries = object.preview && object.preview.entries ? object.preview.entries : [];
+
+ let indexes = getEntriesIndexes(mapEntries, max, isInterestingEntry);
+ if (indexes.length < max && indexes.length < mapEntries.length) {
+ // There are not enough entries yet, so we add uninteresting entries.
+ indexes = indexes.concat(getEntriesIndexes(mapEntries, max - indexes.length, (t, value, name) => {
+ return !isInterestingEntry(t, value, name);
+ }));
+ }
+
+ let entries = getEntries(props, mapEntries, indexes);
+ if (entries.length < getLength(object)) {
+ // There are some undisplayed entries. Then display "…".
+ entries.push(span({
+ key: "more",
+ className: "more-ellipsis",
+ title: "more…"
+ }, "…"));
+ }
+
+ return unfoldEntries(entries);
+}
+
+function unfoldEntries(items) {
+ return items.reduce((res, item, index) => {
+ if (Array.isArray(item)) {
+ res = res.concat(item);
+ } else {
+ res.push(item);
+ }
+
+ // Interleave commas between elements
+ if (index !== items.length - 1) {
+ res.push(", ");
+ }
+ return res;
+ }, []);
+}
+
+/**
+ * Get entries ordered by index.
+ *
+ * @param {Object} props Component props.
+ * @param {Array} entries Entries array.
+ * @param {Array} indexes Indexes of entries.
+ * @return {Array} Array of PropRep.
+ */
+function getEntries(props, entries, indexes) {
+ let {
+ onDOMNodeMouseOver,
+ onDOMNodeMouseOut,
+ onInspectIconClick
+ } = props;
+
+ // Make indexes ordered by ascending.
+ indexes.sort(function (a, b) {
+ return a - b;
+ });
+
+ return indexes.map((index, i) => {
+ let [key, entryValue] = entries[index];
+ let value = entryValue.value !== undefined ? entryValue.value : entryValue;
+
+ return PropRep({
+ name: key,
+ equal: " \u2192 ",
+ object: value,
+ mode: MODE.TINY,
+ onDOMNodeMouseOver,
+ onDOMNodeMouseOut,
+ onInspectIconClick
+ });
+ });
+}
+
+/**
+ * Get the indexes of entries in the map.
+ *
+ * @param {Array} entries Entries array.
+ * @param {Number} max The maximum length of indexes array.
+ * @param {Function} filter Filter the entry you want.
+ * @return {Array} Indexes of filtered entries in the map.
+ */
+function getEntriesIndexes(entries, max, filter) {
+ return entries.reduce((indexes, [key, entry], i) => {
+ if (indexes.length < max) {
+ let value = entry && entry.value !== undefined ? entry.value : entry;
+ // Type is specified in grip's "class" field and for primitive
+ // values use typeof.
+ let type = (value && value.class ? value.class : typeof value).toLowerCase();
+
+ if (filter(type, value, key)) {
+ indexes.push(i);
+ }
+ }
+
+ return indexes;
+ }, []);
+}
+
+function getLength(grip) {
+ return grip.preview.size || 0;
+}
+
+function supportsObject(grip, noGrip = false) {
+ if (noGrip === true || !isGrip(grip)) {
+ return false;
+ }
+ return grip.preview && grip.preview.kind == "MapLike";
+}
+
+const maxLengthMap = new Map();
+maxLengthMap.set(MODE.SHORT, 3);
+maxLengthMap.set(MODE.LONG, 10);
+
+// Exports from this module
+module.exports = {
+ rep: wrapRender(GripMap),
+ supportsObject,
+ maxLengthMap,
+ getLength
+};
+
+/***/ }),
+/* 13 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
// Shortcuts
const { span } = React.DOM;
@@ -1853,41 +2031,48 @@ function createGripMapEntry(key, value)
// Exports from this module
module.exports = {
rep: wrapRender(GripMapEntry),
createGripMapEntry,
supportsObject
};
/***/ }),
-/* 21 */
+/* 14 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
-const get = __webpack_require__(61);
-const has = __webpack_require__(101);
+const { get, has } = __webpack_require__(49);
const { maybeEscapePropertyName } = __webpack_require__(1);
-const ArrayRep = __webpack_require__(17);
-const GripArrayRep = __webpack_require__(19);
-const GripMapEntryRep = __webpack_require__(20);
+const ArrayRep = __webpack_require__(7);
+const GripArrayRep = __webpack_require__(11);
+const GripMap = __webpack_require__(12);
+const GripMapEntryRep = __webpack_require__(13);
+
+const MAX_NUMERICAL_PROPERTIES = 100;
const NODE_TYPES = {
BUCKET: Symbol("[n…n]"),
DEFAULT_PROPERTIES: Symbol("[default properties]"),
ENTRIES: Symbol("<entries>"),
GET: Symbol("<get>"),
GRIP: Symbol("GRIP"),
MAP_ENTRY_KEY: Symbol("<key>"),
MAP_ENTRY_VALUE: Symbol("<value>"),
PROMISE_REASON: Symbol("<reason>"),
PROMISE_STATE: Symbol("<state>"),
PROMISE_VALUE: Symbol("<value>"),
+ PROXY_HANDLER: Symbol("<handler>"),
+ PROXY_TARGET: Symbol("<target>"),
SET: Symbol("<set>"),
PROTOTYPE: Symbol("__proto__")
};
let WINDOW_PROPERTIES = {};
if (typeof window === "object") {
WINDOW_PROPERTIES = Object.getOwnPropertyNames(window);
@@ -1923,17 +2108,17 @@ function nodeIsEntries(item) {
return getType(item) === NODE_TYPES.ENTRIES;
}
function nodeIsMapEntry(item) {
return GripMapEntryRep.supportsObject(getValue(item));
}
function nodeHasChildren(item) {
- return Array.isArray(item.contents) || nodeIsBucket(item);
+ return Array.isArray(item.contents);
}
function nodeIsObject(item) {
const value = getValue(item);
return value && value.type === "object";
}
function nodeIsArrayLike(item) {
@@ -1956,17 +2141,17 @@ function nodeIsMissingArguments(item) {
return !nodeHasChildren(item) && value && value.missingArguments;
}
function nodeHasProperties(item) {
return !nodeHasChildren(item) && nodeIsObject(item);
}
function nodeIsPrimitive(item) {
- return !nodeHasChildren(item) && !nodeHasProperties(item) && !nodeIsEntries(item) && !nodeIsMapEntry(item) && !nodeHasAccessors(item);
+ return !nodeHasChildren(item) && !nodeHasProperties(item) && !nodeIsEntries(item) && !nodeIsMapEntry(item) && !nodeHasAccessors(item) && !nodeIsBucket(item);
}
function nodeIsDefaultProperties(item) {
return getType(item) === NODE_TYPES.DEFAULT_PROPERTIES;
}
function isDefaultWindowProperty(name) {
return WINDOW_PROPERTIES.includes(name);
@@ -1976,16 +2161,25 @@ function nodeIsPromise(item) {
const value = getValue(item);
if (!value) {
return false;
}
return value.class == "Promise";
}
+function nodeIsProxy(item) {
+ const value = getValue(item);
+ if (!value) {
+ return false;
+ }
+
+ return value.class == "Proxy";
+}
+
function nodeIsPrototype(item) {
return getType(item) === NODE_TYPES.PROTOTYPE;
}
function nodeIsWindow(item) {
const value = getValue(item);
if (!value) {
return false;
@@ -2001,18 +2195,20 @@ function nodeIsGetter(item) {
function nodeIsSetter(item) {
return getType(item) === NODE_TYPES.SET;
}
function nodeHasAccessors(item) {
return !!getNodeGetter(item) || !!getNodeSetter(item);
}
-function nodeSupportsBucketing(item) {
- return nodeIsArrayLike(item) || nodeIsEntries(item);
+function nodeSupportsNumericalBucketing(item) {
+ // We exclude elements with entries since it's the <entries> node
+ // itself that can have buckets.
+ return nodeIsArrayLike(item) && !nodeHasEntries(item) || nodeIsEntries(item) || nodeIsBucket(item);
}
function nodeHasEntries(item) {
const value = getValue(item);
if (!value) {
return false;
}
@@ -2030,16 +2226,20 @@ function nodeHasAllEntriesInPreview(item
items,
length,
size
} = preview;
return entries ? entries.length === size : items.length === length;
}
+function nodeNeedsNumericalBuckets(item) {
+ return nodeSupportsNumericalBucketing(item) && getNumericalPropertiesCount(item) > MAX_NUMERICAL_PROPERTIES;
+}
+
function makeNodesForPromiseProperties(item) {
const { promiseState: { reason, value, state } } = getValue(item);
const properties = [];
if (state) {
properties.push(createNode(item, "<state>", `${item.path}/${SAFE_PATH_PREFIX}state`, { value: state }, NODE_TYPES.PROMISE_STATE));
}
@@ -2050,24 +2250,33 @@ function makeNodesForPromiseProperties(i
if (value) {
properties.push(createNode(item, "<value>", `${item.path}/${SAFE_PATH_PREFIX}value`, { value: value }, NODE_TYPES.PROMISE_VALUE));
}
return properties;
}
+function makeNodesForProxyProperties(item) {
+ const {
+ proxyHandler,
+ proxyTarget
+ } = getValue(item);
+
+ return [createNode(item, "<target>", `${item.path}/${SAFE_PATH_PREFIX}target`, { value: proxyTarget }, NODE_TYPES.PROXY_TARGET), createNode(item, "<handler>", `${item.path}/${SAFE_PATH_PREFIX}handler`, { value: proxyHandler }, NODE_TYPES.PROXY_HANDLER)];
+}
+
function makeNodesForEntries(item) {
const { path } = item;
- const { preview } = getValue(item);
const nodeName = "<entries>";
const entriesPath = `${path}/${SAFE_PATH_PREFIX}entries`;
if (nodeHasAllEntriesInPreview(item)) {
let entriesNodes = [];
+ const { preview } = getValue(item);
if (preview.entries) {
entriesNodes = preview.entries.map(([key, value], index) => {
return createNode(item, index, `${entriesPath}/${index}`, {
value: GripMapEntryRep.createGripMapEntry(key, value)
});
});
} else if (preview.items) {
entriesNodes = preview.items.map((value, index) => {
@@ -2124,50 +2333,38 @@ function sortProperties(properties) {
if (isNaN(aInt) || isNaN(bInt)) {
return a > b ? 1 : -1;
}
return aInt - bInt;
});
}
-function makeNumericalBuckets(propertiesNames, parent, ownProperties, startIndex = 0) {
+function makeNumericalBuckets(parent) {
const parentPath = parent.path;
- const numProperties = propertiesNames.length;
+ const numProperties = getNumericalPropertiesCount(parent);
// We want to have at most a hundred slices.
const bucketSize = 10 ** Math.max(2, Math.ceil(Math.log10(numProperties)) - 2);
const numBuckets = Math.ceil(numProperties / bucketSize);
let buckets = [];
for (let i = 1; i <= numBuckets; i++) {
const minKey = (i - 1) * bucketSize;
const maxKey = Math.min(i * bucketSize - 1, numProperties - 1);
-
- if (maxKey === minKey) {
- const name = propertiesNames[maxKey];
- buckets.push(createNode(parent, name, `${parentPath}/${name}`, ownProperties[name]));
- } else {
- const minIndex = startIndex + minKey;
- const maxIndex = startIndex + maxKey;
- const bucketKey = `${SAFE_PATH_PREFIX}bucket_${minIndex}-${maxIndex}`;
- const bucketName = `[${minIndex}…${maxIndex}]`;
-
- const bucketRoot = createNode(parent, bucketName, `${parentPath}/${bucketKey}`, [], NODE_TYPES.BUCKET);
-
- const bucketProperties = propertiesNames.slice(minKey, maxKey + 1);
- let bucketNodes;
- if (bucketProperties.length <= 100) {
- bucketNodes = bucketProperties.map(name => createNode(bucketRoot, name, `${parentPath}/${bucketKey}/${name}`, ownProperties[name]));
- } else {
- bucketNodes = makeNumericalBuckets(bucketProperties, bucketRoot, ownProperties, minIndex);
- }
- setNodeChildren(bucketRoot, bucketNodes);
- buckets.push(bucketRoot);
- }
+ const startIndex = nodeIsBucket(parent) ? parent.meta.startIndex : 0;
+ const minIndex = startIndex + minKey;
+ const maxIndex = startIndex + maxKey;
+ const bucketKey = `${SAFE_PATH_PREFIX}bucket_${minIndex}-${maxIndex}`;
+ const bucketName = `[${minIndex}…${maxIndex}]`;
+
+ buckets.push(createNode(parent, bucketName, `${parentPath}/${bucketKey}`, null, NODE_TYPES.BUCKET, {
+ startIndex: minIndex,
+ endIndex: maxIndex
+ }));
}
return buckets;
}
function makeDefaultPropsBucket(propertiesNames, parent, ownProperties) {
const parentPath = parent.path;
const userPropertiesNames = [];
@@ -2206,305 +2403,331 @@ function makeNodesForProperties(objProps
} = objProps;
const parentPath = parent.path;
const parentValue = getValue(parent);
let allProperties = Object.assign({}, ownProperties, safeGetterValues);
// Ignore properties that are neither non-concrete nor getters/setters.
- const propertiesNames = sortProperties(Object.keys(allProperties)).filter(name => allProperties[name].hasOwnProperty("value") || allProperties[name].hasOwnProperty("getterValue") || allProperties[name].hasOwnProperty("get") || allProperties[name].hasOwnProperty("set"));
-
- const numProperties = propertiesNames.length;
+ const propertiesNames = sortProperties(Object.keys(allProperties)).filter(name => {
+ if (!allProperties[name]) {
+ return false;
+ }
+
+ const properties = Object.getOwnPropertyNames(allProperties[name]);
+ return properties.some(property => ["value", "getterValue", "get", "set"].includes(property));
+ });
let nodes = [];
- if (nodeSupportsBucketing(parent) && numProperties > 100) {
- nodes = makeNumericalBuckets(propertiesNames, parent, allProperties);
- } else if (parentValue && parentValue.class == "Window") {
+ if (parentValue && parentValue.class == "Window") {
nodes = makeDefaultPropsBucket(propertiesNames, parent, allProperties);
} else {
nodes = makeNodesForOwnProps(propertiesNames, parent, allProperties);
}
if (Array.isArray(ownSymbols)) {
ownSymbols.forEach((ownSymbol, index) => {
- nodes.push(createNode(parent, ownSymbol.name, `${parentPath}/${SAFE_PATH_PREFIX}symbol-${index}`, ownSymbol.descriptor));
+ nodes.push(createNode(parent, ownSymbol.name, `${parentPath}/${SAFE_PATH_PREFIX}symbol-${index}`, ownSymbol.descriptor || null));
}, this);
}
if (nodeIsPromise(parent)) {
nodes.push(...makeNodesForPromiseProperties(parent));
}
if (nodeHasEntries(parent)) {
nodes.push(makeNodesForEntries(parent));
}
// Add the prototype if it exists and is not null
if (prototype && prototype.type !== "null") {
- nodes.push(createNode(parent, "__proto__", `${parentPath}/__proto__`, { value: prototype }, NODE_TYPES.PROTOTYPE));
+ nodes.push(makeNodeForPrototype(objProps, parent));
}
return nodes;
}
-function createNode(parent, name, path, contents, type = NODE_TYPES.GRIP) {
+function makeNodeForPrototype(objProps, parent) {
+ const {
+ prototype
+ } = objProps || {};
+
+ // Add the prototype if it exists and is not null
+ if (prototype && prototype.type !== "null") {
+ return createNode(parent, "__proto__", `${parent.path}/__proto__`, { value: prototype }, NODE_TYPES.PROTOTYPE);
+ }
+
+ return null;
+}
+
+function createNode(parent, name, path, contents, type = NODE_TYPES.GRIP, meta) {
if (contents === undefined) {
return null;
}
// The path is important to uniquely identify the item in the entire
// tree. This helps debugging & optimizes React's rendering of large
// lists. The path will be separated by property name,
// i.e. `{ foo: { bar: { baz: 5 }}}` will have a path of `foo/bar/baz`
// for the inner object.
return {
parent,
name,
path,
contents,
- type
+ type,
+ meta
};
}
function setNodeChildren(node, children) {
node.contents = children;
return node;
}
function getChildren(options) {
const {
- actors = {},
- getObjectEntries,
- getObjectProperties,
+ cachedNodes,
+ loadedProperties = new Map(),
item
} = options;
- // Nodes can either have children already, or be an object with
- // properties that we need to go and fetch.
- if (nodeHasAccessors(item)) {
- return makeNodesForAccessors(item);
- }
-
- if (nodeIsMapEntry(item)) {
- return makeNodesForMapEntry(item);
+
+ const key = item.path;
+ if (cachedNodes && cachedNodes.has(key)) {
+ return cachedNodes.get(key);
}
- if (nodeHasChildren(item)) {
- return item.contents;
- }
-
- if (!nodeHasProperties(item) && !nodeIsEntries(item)) {
- return [];
- }
+ const loadedProps = loadedProperties.get(key);
+ const {
+ ownProperties,
+ ownSymbols,
+ safeGetterValues,
+ prototype
+ } = loadedProps || {};
+ const hasLoadedProps = ownProperties || ownSymbols || safeGetterValues || prototype;
// Because we are dynamically creating the tree as the user
// expands it (not precalculated tree structure), we cache child
// arrays. This not only helps performance, but is necessary
// because the expanded state depends on instances of nodes
// being the same across renders. If we didn't do this, each
// node would be a new instance every render.
- const key = item.path;
- if (actors && actors[key]) {
- return actors[key];
+ // If the node needs properties, we only add children to
+ // the cache if the properties are loaded.
+ const addToCache = children => {
+ if (cachedNodes) {
+ cachedNodes.set(item.path, children);
+ }
+ return children;
+ };
+
+ // Nodes can either have children already, or be an object with
+ // properties that we need to go and fetch.
+ if (nodeHasChildren(item)) {
+ return addToCache(item.contents);
}
- if (nodeIsBucket(item)) {
- return item.contents.children;
+ if (nodeHasAccessors(item)) {
+ return addToCache(makeNodesForAccessors(item));
+ }
+
+ if (nodeIsMapEntry(item)) {
+ return addToCache(makeNodesForMapEntry(item));
}
- let loadedProps;
- if (nodeIsEntries(item)) {
- // If `item` is an <entries> node, we need to get the entries
- // matching the parent node actor.
- const parent = getParent(item);
- loadedProps = getObjectEntries(get(getValue(parent), "actor", undefined));
- } else {
- loadedProps = getObjectProperties(get(getValue(item), "actor", undefined));
+ if (nodeIsProxy(item)) {
+ const nodes = makeNodesForProxyProperties(item);
+ const protoNode = makeNodeForPrototype(loadedProps, item);
+ if (protoNode) {
+ return addToCache(nodes.concat(protoNode));
+ }
+ return nodes;
}
- const {
- ownProperties,
- ownSymbols,
- safeGetterValues,
- prototype
- } = loadedProps || {};
-
- if (!ownProperties && !ownSymbols && !safeGetterValues && !prototype) {
+ if (nodeNeedsNumericalBuckets(item)) {
+ const bucketNodes = makeNumericalBuckets(item);
+ // Even if we have numerical buckets, we might have loaded non indexed properties,
+ // like length for example.
+ if (hasLoadedProps) {
+ return addToCache(bucketNodes.concat(makeNodesForProperties(loadedProps, item)));
+ }
+
+ // We don't cache the result here so we can have the prototype, properties and symbols
+ // when they are loaded.
+ return bucketNodes;
+ }
+
+ if (!nodeIsEntries(item) && !nodeIsBucket(item) && !nodeHasProperties(item)) {
return [];
}
- let children = makeNodesForProperties(loadedProps, item);
- actors[key] = children;
- return children;
+ if (!hasLoadedProps) {
+ return [];
+ }
+
+ return addToCache(makeNodesForProperties(loadedProps, item));
}
function getParent(item) {
return item.parent;
}
+function getNumericalPropertiesCount(item) {
+ if (nodeIsBucket(item)) {
+ return item.meta.endIndex - item.meta.startIndex + 1;
+ }
+
+ const value = getValue(getClosestGripNode(item));
+ if (!value) {
+ return 0;
+ }
+
+ if (GripArrayRep.supportsObject(value)) {
+ return GripArrayRep.getLength(value);
+ }
+
+ if (GripMap.supportsObject(value)) {
+ return GripMap.getLength(value);
+ }
+
+ // TODO: We can also have numerical properties on Objects, but at the
+ // moment we don't have a way to distinguish them from non-indexed properties,
+ // as they are all computed in a ownPropertiesLength property.
+
+ return 0;
+}
+
+function getClosestGripNode(item) {
+ const type = getType(item);
+ if (type !== NODE_TYPES.BUCKET && type !== NODE_TYPES.DEFAULT_PROPERTIES && type !== NODE_TYPES.ENTRIES) {
+ return item;
+ }
+
+ const parent = getParent(item);
+ if (!parent) {
+ return null;
+ }
+
+ return getClosestGripNode(parent);
+}
+
+function getClosestNonBucketNode(item) {
+ const type = getType(item);
+
+ if (type !== NODE_TYPES.BUCKET) {
+ return item;
+ }
+
+ const parent = getParent(item);
+ if (!parent) {
+ return null;
+ }
+
+ return getClosestNonBucketNode(parent);
+}
+
+function shouldLoadItemIndexedProperties(item, loadedProperties = new Map()) {
+ const gripItem = getClosestGripNode(item);
+ const value = getValue(gripItem);
+
+ return value && nodeHasProperties(gripItem) && !loadedProperties.has(item.path) && !nodeIsProxy(item) && !nodeNeedsNumericalBuckets(item) && !nodeIsEntries(getClosestNonBucketNode(item))
+ // The data is loaded when expanding the window node.
+ && !nodeIsDefaultProperties(item);
+}
+
+function shouldLoadItemNonIndexedProperties(item, loadedProperties = new Map()) {
+ const gripItem = getClosestGripNode(item);
+ const value = getValue(gripItem);
+
+ return value && nodeHasProperties(gripItem) && !loadedProperties.has(item.path) && !nodeIsProxy(item) && !nodeIsEntries(getClosestNonBucketNode(item)) && !nodeIsBucket(item)
+ // The data is loaded when expanding the window node.
+ && !nodeIsDefaultProperties(item);
+}
+
+function shouldLoadItemEntries(item, loadedProperties = new Map()) {
+ const gripItem = getClosestGripNode(item);
+ const value = getValue(gripItem);
+
+ return value && nodeIsEntries(getClosestNonBucketNode(item)) && !nodeHasAllEntriesInPreview(gripItem) && !loadedProperties.has(item.path) && !nodeNeedsNumericalBuckets(item);
+}
+
+function shouldLoadItemPrototype(item, loadedProperties = new Map()) {
+ const value = getValue(item);
+
+ return value && !loadedProperties.has(item.path) && !nodeIsBucket(item) && !nodeIsMapEntry(item) && !nodeIsEntries(item) && !nodeIsDefaultProperties(item) && !nodeHasAccessors(item) && !nodeIsPrimitive(item);
+}
+
+function shouldLoadItemSymbols(item, loadedProperties = new Map()) {
+ const value = getValue(item);
+
+ return value && !loadedProperties.has(item.path) && !nodeIsBucket(item) && !nodeIsMapEntry(item) && !nodeIsEntries(item) && !nodeIsDefaultProperties(item) && !nodeHasAccessors(item) && !nodeIsPrimitive(item) && !nodeIsProxy(item);
+}
+
module.exports = {
createNode,
getChildren,
+ getClosestGripNode,
+ getClosestNonBucketNode,
getParent,
+ getNumericalPropertiesCount,
getValue,
makeNodesForEntries,
makeNodesForPromiseProperties,
makeNodesForProperties,
+ makeNumericalBuckets,
nodeHasAccessors,
nodeHasAllEntriesInPreview,
nodeHasChildren,
nodeHasEntries,
nodeHasProperties,
+ nodeIsBucket,
nodeIsDefaultProperties,
nodeIsEntries,
nodeIsFunction,
nodeIsGetter,
nodeIsMapEntry,
nodeIsMissingArguments,
nodeIsObject,
nodeIsOptimizedOut,
nodeIsPrimitive,
nodeIsPromise,
nodeIsPrototype,
+ nodeIsProxy,
nodeIsSetter,
nodeIsWindow,
- nodeSupportsBucketing,
+ nodeNeedsNumericalBuckets,
+ nodeSupportsNumericalBucketing,
setNodeChildren,
+ shouldLoadItemEntries,
+ shouldLoadItemIndexedProperties,
+ shouldLoadItemNonIndexedProperties,
+ shouldLoadItemPrototype,
+ shouldLoadItemSymbols,
sortProperties,
NODE_TYPES,
// Export for testing purpose.
SAFE_PATH_PREFIX
};
/***/ }),
-/* 22 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var isArray = __webpack_require__(5),
- isKey = __webpack_require__(63),
- stringToPath = __webpack_require__(68),
- toString = __webpack_require__(98);
-
-/**
- * Casts `value` to a path array if it's not one.
- *
- * @private
- * @param {*} value The value to inspect.
- * @param {Object} [object] The object to query keys on.
- * @returns {Array} Returns the cast property path array.
- */
-function castPath(value, object) {
- if (isArray(value)) {
- return value;
- }
- return isKey(value, object) ? [value] : stringToPath(toString(value));
-}
-
-module.exports = castPath;
-
-
-/***/ }),
-/* 23 */
+/* 15 */
/***/ (function(module, exports, __webpack_require__) {
-var baseIsNative = __webpack_require__(75),
- getValue = __webpack_require__(80);
-
-/**
- * Gets the native function at `key` of `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {string} key The key of the method to get.
- * @returns {*} Returns the function if it's native, else `undefined`.
- */
-function getNative(object, key) {
- var value = getValue(object, key);
- return baseIsNative(value) ? value : undefined;
-}
-
-module.exports = getNative;
-
-
-/***/ }),
-/* 24 */
-/***/ (function(module, exports) {
-
-/**
- * Checks if `value` is the
- * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
- * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an object, else `false`.
- * @example
- *
- * _.isObject({});
- * // => true
- *
- * _.isObject([1, 2, 3]);
- * // => true
- *
- * _.isObject(_.noop);
- * // => true
- *
- * _.isObject(null);
- * // => false
- */
-function isObject(value) {
- var type = typeof value;
- return value != null && (type == 'object' || type == 'function');
-}
-
-module.exports = isObject;
-
-
-/***/ }),
-/* 25 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var isSymbol = __webpack_require__(11);
-
-/** Used as references for various `Number` constants. */
-var INFINITY = 1 / 0;
-
-/**
- * Converts `value` to a string key if it's not a string or symbol.
- *
- * @private
- * @param {*} value The value to inspect.
- * @returns {string|symbol} Returns the key.
- */
-function toKey(value) {
- if (typeof value == 'string' || isSymbol(value)) {
- return value;
- }
- var result = (value + '');
- return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
-}
-
-module.exports = toKey;
-
-
-/***/ }),
-/* 26 */
-/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
/* 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/. */
const { MODE } = __webpack_require__(2);
const { REPS, getRep } = __webpack_require__(3);
-const ObjectInspector = __webpack_require__(56);
-const ObjectInspectorUtils = __webpack_require__(21);
+const ObjectInspector = __webpack_require__(42);
+const ObjectInspectorUtils = __webpack_require__(14);
const {
parseURLEncodedText,
parseURLParams,
maybeEscapePropertyName,
getGripPreviewItems
} = __webpack_require__(1);
@@ -2516,25 +2739,28 @@ module.exports = {
parseURLEncodedText,
parseURLParams,
getGripPreviewItems,
ObjectInspector,
ObjectInspectorUtils
};
/***/ }),
-/* 27 */
+/* 16 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
-/* 28 */
+/* 17 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
@@ -2549,33 +2775,36 @@ const { span } = React.DOM;
* Renders undefined value
*/
const Undefined = function () {
return span({ className: "objectBox objectBox-undefined" }, "undefined");
};
function supportsObject(object, noGrip = false) {
if (noGrip === true) {
- return false;
+ return object === undefined;
}
return object && object.type && object.type == "undefined" || getGripType(object, noGrip) == "undefined";
}
// Exports from this module
module.exports = {
rep: wrapRender(Undefined),
supportsObject
};
/***/ }),
-/* 29 */
+/* 18 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const { wrapRender } = __webpack_require__(1);
@@ -2587,17 +2816,17 @@ const { span } = React.DOM;
* Renders null value
*/
function Null(props) {
return span({ className: "objectBox objectBox-null" }, "null");
}
function supportsObject(object, noGrip = false) {
if (noGrip === true) {
- return false;
+ return object === null;
}
if (object && object.type && object.type == "null") {
return true;
}
return object == null;
}
@@ -2605,19 +2834,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(Null),
supportsObject
};
/***/ }),
-/* 30 */
+/* 19 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
escapeString,
@@ -2678,19 +2910,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(LongStringRep),
supportsObject
};
/***/ }),
-/* 31 */
+/* 20 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
@@ -2727,19 +2962,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(Number),
supportsObject
};
/***/ }),
-/* 32 */
+/* 21 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
wrapRender
@@ -2925,19 +3163,22 @@ function supportsObject(object) {
// Exports from this module
module.exports = {
rep: wrapRender(ObjectRep),
supportsObject
};
/***/ }),
-/* 33 */
+/* 22 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
@@ -2971,19 +3212,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(SymbolRep),
supportsObject
};
/***/ }),
-/* 34 */
+/* 23 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
@@ -3016,19 +3260,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(InfinityRep),
supportsObject
};
/***/ }),
-/* 35 */
+/* 24 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
@@ -3052,19 +3299,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(NaNRep),
supportsObject
};
/***/ }),
-/* 36 */
+/* 25 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
wrapRender
@@ -3120,33 +3370,36 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(Accessor),
supportsObject
};
/***/ }),
-/* 37 */
+/* 26 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
const {
getGripType,
isGrip,
wrapRender
} = __webpack_require__(1);
-const { rep: StringRep } = __webpack_require__(16);
+const { rep: StringRep } = __webpack_require__(5);
// Shortcuts
const { span } = React.DOM;
/**
* Renders DOM attribute
*/
Attribute.propTypes = {
@@ -3156,18 +3409,18 @@ Attribute.propTypes = {
function Attribute(props) {
let {
object
} = props;
let value = object.preview.value;
return span({
"data-link-actor-id": object.actor,
- className: "objectLink-Attr"
- }, span({ className: "attrTitle" }, getTitle(object)), span({ className: "attrEqual" }, "="), StringRep({ object: value }));
+ className: "objectBox-Attr"
+ }, span({ className: "attrName" }, getTitle(object)), span({ className: "attrEqual" }, "="), StringRep({ className: "attrValue", object: value }));
}
function getTitle(grip) {
return grip.preview.nodeName;
}
// Registration
function supportsObject(grip, noGrip = false) {
@@ -3179,19 +3432,22 @@ function supportsObject(grip, noGrip = f
}
module.exports = {
rep: wrapRender(Attribute),
supportsObject
};
/***/ }),
-/* 38 */
+/* 27 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
@@ -3243,19 +3499,22 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(DateTime),
supportsObject
};
/***/ }),
-/* 39 */
+/* 28 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
@@ -3276,18 +3535,18 @@ Document.propTypes = {
object: React.PropTypes.object.isRequired
};
function Document(props) {
let grip = props.object;
return span({
"data-link-actor-id": grip.actor,
- className: "objectBox objectBox-object"
- }, getTitle(grip), span({ className: "objectPropValue" }, getLocation(grip)));
+ className: "objectBox objectBox-document"
+ }, getTitle(grip), span({ className: "location" }, getLocation(grip)));
}
function getLocation(grip) {
let location = grip.preview.location;
return location ? getURLDisplayString(location) : "";
}
function getTitle(grip) {
@@ -3307,34 +3566,37 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(Document),
supportsObject
};
/***/ }),
-/* 40 */
+/* 29 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
const {
isGrip,
wrapRender
} = __webpack_require__(1);
const { MODE } = __webpack_require__(2);
-const { rep } = __webpack_require__(9);
+const { rep } = __webpack_require__(6);
/**
* Renders DOM event objects.
*/
Event.propTypes = {
object: React.PropTypes.object.isRequired,
// @TODO Change this to Object.values once it's supported in Node's version of V8
mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])),
@@ -3411,33 +3673,37 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(Event),
supportsObject
};
/***/ }),
-/* 41 */
+/* 30 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
const {
getGripType,
isGrip,
cropString,
wrapRender
} = __webpack_require__(1);
+const { MODE } = __webpack_require__(2);
// Shortcuts
const { span } = React.DOM;
/**
* This component represents a template for Function objects.
*/
FunctionRep.propTypes = {
@@ -3449,32 +3715,32 @@ function FunctionRep(props) {
let grip = props.object;
return span({
"data-link-actor-id": grip.actor,
className: "objectBox objectBox-function",
// Set dir="ltr" to prevent function parentheses from
// appearing in the wrong direction
dir: "ltr"
- }, getTitle(props, grip), getFunctionName(grip, props), "(", ...renderParams(props), ")");
-}
-
-function getTitle(props, grip) {
+ }, getTitle(grip, props), getFunctionName(grip, props), "(", ...renderParams(props), ")");
+}
+
+function getTitle(grip, props) {
const {
- simplified
+ mode
} = props;
- if (simplified === true && !grip.isGenerator && !grip.isAsync) {
+ if (mode === MODE.TINY && !grip.isGenerator && !grip.isAsync) {
return null;
}
- let title = simplified === true ? "" : "function ";
+ let title = mode === MODE.TINY ? "" : "function ";
if (grip.isGenerator) {
- title = simplified === true ? "* " : "function* ";
+ title = mode === MODE.TINY ? "* " : "function* ";
}
if (grip.isAsync) {
title = "async" + " " + title;
}
return span({
className: "objectTitle"
@@ -3513,19 +3779,22 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(FunctionRep),
supportsObject
};
/***/ }),
-/* 42 */
+/* 31 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Dependencies
const {
@@ -3619,19 +3888,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(PromiseRep),
supportsObject
};
/***/ }),
-/* 43 */
+/* 32 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
@@ -3672,19 +3944,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(RegExp),
supportsObject
};
/***/ }),
-/* 44 */
+/* 33 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
@@ -3737,33 +4012,36 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(StyleSheet),
supportsObject
};
/***/ }),
-/* 45 */
+/* 34 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// Dependencies
const React = __webpack_require__(0);
const {
isGrip,
cropString,
cropMultipleLines,
wrapRender
} = __webpack_require__(1);
const { MODE } = __webpack_require__(2);
-const nodeConstants = __webpack_require__(18);
+const nodeConstants = __webpack_require__(8);
// Shortcuts
const { span } = React.DOM;
/**
* Renders DOM comment node.
*/
CommentNode.propTypes = {
@@ -3801,34 +4079,38 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(CommentNode),
supportsObject
};
/***/ }),
-/* 46 */
+/* 35 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Utils
const {
isGrip,
wrapRender
} = __webpack_require__(1);
+const { rep: StringRep } = __webpack_require__(5);
const { MODE } = __webpack_require__(2);
-const nodeConstants = __webpack_require__(18);
-const Svg = __webpack_require__(10);
+const nodeConstants = __webpack_require__(8);
+const Svg = __webpack_require__(9);
// Shortcuts
const { span } = React.DOM;
/**
* Renders DOM element node.
*/
ElementNode.propTypes = {
@@ -3882,46 +4164,46 @@ function ElementNode(props) {
}
return span(baseConfig, ...elements, inspectIcon);
}
function getElements(grip, mode) {
let { attributes, nodeName } = grip.preview;
const nodeNameElement = span({
- className: "tag-name theme-fg-color3"
+ className: "tag-name"
}, nodeName);
if (mode === MODE.TINY) {
let elements = [nodeNameElement];
if (attributes.id) {
- elements.push(span({ className: "attr-name theme-fg-color2" }, `#${attributes.id}`));
+ elements.push(span({ className: "attrName" }, `#${attributes.id}`));
}
if (attributes.class) {
- elements.push(span({ className: "attr-name theme-fg-color2" }, attributes.class.replace(/(^\s+)|(\s+$)/g, "").split(" ").map(cls => `.${cls}`).join("")));
+ elements.push(span({ className: "attrName" }, attributes.class.trim().split(/\s+/).map(cls => `.${cls}`).join("")));
}
return elements;
}
let attributeKeys = Object.keys(attributes);
if (attributeKeys.includes("class")) {
attributeKeys.splice(attributeKeys.indexOf("class"), 1);
attributeKeys.unshift("class");
}
if (attributeKeys.includes("id")) {
attributeKeys.splice(attributeKeys.indexOf("id"), 1);
attributeKeys.unshift("id");
}
const attributeElements = attributeKeys.reduce((arr, name, i, keys) => {
let value = attributes[name];
- let attribute = span({}, span({ className: "attr-name theme-fg-color2" }, `${name}`), `="`, span({ className: "attr-value theme-fg-color6" }, `${value}`), `"`);
+ let attribute = span({}, span({ className: "attrName" }, name), span({ className: "attrEqual" }, "="), StringRep({ className: "attrValue", object: value }));
return arr.concat([" ", attribute]);
}, []);
- return ["<", nodeNameElement, ...attributeElements, ">"];
+ return [span({ className: "angleBracket" }, "<"), nodeNameElement, ...attributeElements, span({ className: "angleBracket" }, ">")];
}
// Registration
function supportsObject(object, noGrip = false) {
if (noGrip === true || !isGrip(object)) {
return false;
}
return object.preview && object.preview.nodeType === nodeConstants.ELEMENT_NODE;
@@ -3929,199 +4211,43 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(ElementNode),
supportsObject
};
/***/ }),
-/* 47 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, '__esModule', {
- value: true
-});
-
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
-function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var _react = __webpack_require__(0);
-
-var _react2 = _interopRequireDefault(_react);
-
-var DOMParser = typeof window !== 'undefined' && window.DOMParser;
-var process = process || {};
-process.env = process.env || {};
-var parserAvailable = typeof DOMParser !== 'undefined' && DOMParser.prototype != null && DOMParser.prototype.parseFromString != null;
-
-function isParsable(src) {
- // kinda naive but meh, ain't gonna use full-blown parser for this
- return parserAvailable && typeof src === 'string' && src.trim().substr(0, 4) === '<svg';
-}
-
-// parse SVG string using `DOMParser`
-function parseFromSVGString(src) {
- var parser = new DOMParser();
- return parser.parseFromString(src, "image/svg+xml");
-}
-
-// Transform DOM prop/attr names applicable to `<svg>` element but react-limited
-function switchSVGAttrToReactProp(propName) {
- switch (propName) {
- case 'class':
- return 'className';
- default:
- return propName;
- }
-}
-
-var InlineSVG = (function (_React$Component) {
- _inherits(InlineSVG, _React$Component);
-
- _createClass(InlineSVG, null, [{
- key: 'defaultProps',
- value: {
- element: 'i',
- raw: false,
- src: ''
- },
- enumerable: true
- }, {
- key: 'propTypes',
- value: {
- src: _react2['default'].PropTypes.string.isRequired,
- element: _react2['default'].PropTypes.string,
- raw: _react2['default'].PropTypes.bool
- },
- enumerable: true
- }]);
-
- function InlineSVG(props) {
- _classCallCheck(this, InlineSVG);
-
- _get(Object.getPrototypeOf(InlineSVG.prototype), 'constructor', this).call(this, props);
- this._extractSVGProps = this._extractSVGProps.bind(this);
- }
-
- // Serialize `Attr` objects in `NamedNodeMap`
-
- _createClass(InlineSVG, [{
- key: '_serializeAttrs',
- value: function _serializeAttrs(map) {
- var ret = {};
- var prop = undefined;
- for (var i = 0; i < map.length; i++) {
- prop = switchSVGAttrToReactProp(map[i].name);
- ret[prop] = map[i].value;
- }
- return ret;
- }
-
- // get <svg /> element props
- }, {
- key: '_extractSVGProps',
- value: function _extractSVGProps(src) {
- var map = parseFromSVGString(src).documentElement.attributes;
- return map.length > 0 ? this._serializeAttrs(map) : null;
- }
-
- // get content inside <svg> element.
- }, {
- key: '_stripSVG',
- value: function _stripSVG(src) {
- return parseFromSVGString(src).documentElement.innerHTML;
- }
- }, {
- key: 'componentWillReceiveProps',
- value: function componentWillReceiveProps(_ref) {
- var children = _ref.children;
-
- if ("production" !== process.env.NODE_ENV && children != null) {
- console.info('<InlineSVG />: `children` prop will be ignored.');
- }
- }
- }, {
- key: 'render',
- value: function render() {
- var Element = undefined,
- __html = undefined,
- svgProps = undefined;
- var _props = this.props;
- var element = _props.element;
- var raw = _props.raw;
- var src = _props.src;
-
- var otherProps = _objectWithoutProperties(_props, ['element', 'raw', 'src']);
-
- if (raw === true && isParsable(src)) {
- Element = 'svg';
- svgProps = this._extractSVGProps(src);
- __html = this._stripSVG(src);
- }
- __html = __html || src;
- Element = Element || element;
- svgProps = svgProps || {};
-
- return _react2['default'].createElement(Element, _extends({}, svgProps, otherProps, { src: null, children: null,
- dangerouslySetInnerHTML: { __html: __html } }));
- }
- }]);
-
- return InlineSVG;
-})(_react2['default'].Component);
-
-exports['default'] = InlineSVG;
-module.exports = exports['default'];
-
-/***/ }),
-/* 48 */
-/***/ (function(module, exports) {
-
-module.exports = "<!-- 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 viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z\"></path></svg>"
-
-/***/ }),
-/* 49 */
+/* 36 */
/***/ (function(module, exports) {
module.exports = "<!-- 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 viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8,3L12,3L12,7L14,7L14,8L12,8L12,12L8,12L8,14L7,14L7,12L3,12L3,8L1,8L1,7L3,7L3,3L7,3L7,1L8,1L8,3ZM10,10L10,5L5,5L5,10L10,10Z\"></path></svg>"
/***/ }),
-/* 50 */
+/* 37 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
const {
isGrip,
cropString,
wrapRender
} = __webpack_require__(1);
const { MODE } = __webpack_require__(2);
-const Svg = __webpack_require__(10);
+const Svg = __webpack_require__(9);
// Shortcuts
const DOM = React.DOM;
/**
* Renders DOM #text node.
*/
TextNode.propTypes = {
@@ -4200,19 +4326,22 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(TextNode),
supportsObject
};
/***/ }),
-/* 51 */
+/* 38 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Utils
const {
@@ -4266,19 +4395,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(ErrorRep),
supportsObject
};
/***/ }),
-/* 52 */
+/* 39 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
@@ -4313,22 +4445,22 @@ function WindowRep(props) {
"data-link-actor-id": object.actor,
className: "objectBox objectBox-Window"
};
if (mode === MODE.TINY) {
return span(config, getTitle(object));
}
- return span(config, getTitle(object), " ", span({ className: "objectPropValue" }, getLocation(object)));
+ return span(config, getTitle(object), " ", span({ className: "location" }, getLocation(object)));
}
function getTitle(object) {
let title = object.displayClass || object.class || "Window";
- return span({ className: "objectBoxTitle" }, title);
+ return span({ className: "objectTitle" }, title);
}
function getLocation(object) {
return getURLDisplayString(object.preview.url);
}
// Registration
function supportsObject(object, noGrip = false) {
@@ -4341,19 +4473,22 @@ function supportsObject(object, noGrip =
// Exports from this module
module.exports = {
rep: wrapRender(WindowRep),
supportsObject
};
/***/ }),
-/* 53 */
+/* 40 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
@@ -4399,19 +4534,22 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(ObjectWithText),
supportsObject
};
/***/ }),
-/* 54 */
+/* 41 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
/* 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/. */
// ReactJS
const React = __webpack_require__(0);
// Reps
@@ -4462,263 +4600,87 @@ function supportsObject(grip, noGrip = f
// Exports from this module
module.exports = {
rep: wrapRender(ObjectWithURL),
supportsObject
};
/***/ }),
-/* 55 */
+/* 42 */
/***/ (function(module, exports, __webpack_require__) {
-/* 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/. */
-
-// Dependencies
-const React = __webpack_require__(0);
-const {
- isGrip,
- wrapRender
-} = __webpack_require__(1);
-const PropRep = __webpack_require__(4);
-const { MODE } = __webpack_require__(2);
-// Shortcuts
-const { span } = React.DOM;
-
-/**
- * Renders an map. A map is represented by a list of its
- * entries enclosed in curly brackets.
- */
-GripMap.propTypes = {
- object: React.PropTypes.object,
- // @TODO Change this to Object.values once it's supported in Node's version of V8
- mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])),
- isInterestingEntry: React.PropTypes.func,
- onDOMNodeMouseOver: React.PropTypes.func,
- onDOMNodeMouseOut: React.PropTypes.func,
- onInspectIconClick: React.PropTypes.func,
- title: React.PropTypes.string
-};
-
-function GripMap(props) {
- let {
- mode,
- object
- } = props;
-
- const config = {
- "data-link-actor-id": object.actor,
- className: "objectBox objectBox-object"
- };
-
- if (mode === MODE.TINY) {
- return span(config, getTitle(props, object));
- }
-
- let propsArray = safeEntriesIterator(props, object, maxLengthMap.get(mode));
-
- return span(config, getTitle(props, object), span({
- className: "objectLeftBrace"
- }, " { "), ...propsArray, span({
- className: "objectRightBrace"
- }, " }"));
-}
-
-function getTitle(props, object) {
- let title = props.title || (object && object.class ? object.class : "Map");
- return span({
- className: "objectTitle"
- }, title);
-}
-
-function safeEntriesIterator(props, object, max) {
- max = typeof max === "undefined" ? 3 : max;
- try {
- return entriesIterator(props, object, max);
- } catch (err) {
- console.error(err);
- }
- return [];
-}
-
-function entriesIterator(props, object, max) {
- // Entry filter. Show only interesting entries to the user.
- let isInterestingEntry = props.isInterestingEntry || ((type, value) => {
- return type == "boolean" || type == "number" || type == "string" && value.length != 0;
- });
-
- let mapEntries = object.preview && object.preview.entries ? object.preview.entries : [];
-
- let indexes = getEntriesIndexes(mapEntries, max, isInterestingEntry);
- if (indexes.length < max && indexes.length < mapEntries.length) {
- // There are not enough entries yet, so we add uninteresting entries.
- indexes = indexes.concat(getEntriesIndexes(mapEntries, max - indexes.length, (t, value, name) => {
- return !isInterestingEntry(t, value, name);
- }));
- }
-
- let entries = getEntries(props, mapEntries, indexes);
- if (entries.length < object.preview.size) {
- // There are some undisplayed entries. Then display "…".
- entries.push(span({
- key: "more",
- className: "more-ellipsis",
- title: "more…"
- }, "…"));
- }
-
- return unfoldEntries(entries);
-}
-
-function unfoldEntries(items) {
- return items.reduce((res, item, index) => {
- if (Array.isArray(item)) {
- res = res.concat(item);
- } else {
- res.push(item);
- }
-
- // Interleave commas between elements
- if (index !== items.length - 1) {
- res.push(", ");
- }
- return res;
- }, []);
-}
-
-/**
- * Get entries ordered by index.
- *
- * @param {Object} props Component props.
- * @param {Array} entries Entries array.
- * @param {Array} indexes Indexes of entries.
- * @return {Array} Array of PropRep.
- */
-function getEntries(props, entries, indexes) {
- let {
- onDOMNodeMouseOver,
- onDOMNodeMouseOut,
- onInspectIconClick
- } = props;
-
- // Make indexes ordered by ascending.
- indexes.sort(function (a, b) {
- return a - b;
- });
-
- return indexes.map((index, i) => {
- let [key, entryValue] = entries[index];
- let value = entryValue.value !== undefined ? entryValue.value : entryValue;
-
- return PropRep({
- name: key,
- equal: " \u2192 ",
- object: value,
- mode: MODE.TINY,
- onDOMNodeMouseOver,
- onDOMNodeMouseOut,
- onInspectIconClick
- });
- });
-}
-
-/**
- * Get the indexes of entries in the map.
- *
- * @param {Array} entries Entries array.
- * @param {Number} max The maximum length of indexes array.
- * @param {Function} filter Filter the entry you want.
- * @return {Array} Indexes of filtered entries in the map.
- */
-function getEntriesIndexes(entries, max, filter) {
- return entries.reduce((indexes, [key, entry], i) => {
- if (indexes.length < max) {
- let value = entry && entry.value !== undefined ? entry.value : entry;
- // Type is specified in grip's "class" field and for primitive
- // values use typeof.
- let type = (value && value.class ? value.class : typeof value).toLowerCase();
-
- if (filter(type, value, key)) {
- indexes.push(i);
- }
- }
-
- return indexes;
- }, []);
-}
-
-function supportsObject(grip, noGrip = false) {
- if (noGrip === true || !isGrip(grip)) {
- return false;
- }
- return grip.preview && grip.preview.kind == "MapLike";
-}
-
-const maxLengthMap = new Map();
-maxLengthMap.set(MODE.SHORT, 3);
-maxLengthMap.set(MODE.LONG, 10);
-
-// Exports from this module
-module.exports = {
- rep: wrapRender(GripMap),
- supportsObject,
- maxLengthMap
-};
-
-/***/ }),
-/* 56 */
-/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
+var _devtoolsComponents = __webpack_require__(43);
+
+var _devtoolsComponents2 = _interopRequireDefault(_devtoolsComponents);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
/* 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/. */
const {
Component,
createFactory,
DOM: dom,
PropTypes
} = __webpack_require__(0);
-const Tree = createFactory(__webpack_require__(57).Tree);
-__webpack_require__(59);
-
-const classnames = __webpack_require__(60);
-const Svg = __webpack_require__(10);
+const Tree = createFactory(_devtoolsComponents2.default.Tree);
+__webpack_require__(47);
+
+const classnames = __webpack_require__(48);
+
const {
REPS: {
Rep,
Grip
}
} = __webpack_require__(3);
const {
MODE
} = __webpack_require__(2);
const {
getChildren,
+ getClosestGripNode,
getParent,
getValue,
nodeHasAccessors,
- nodeHasAllEntriesInPreview,
nodeHasProperties,
nodeIsDefaultProperties,
- nodeIsEntries,
+ nodeIsFunction,
nodeIsGetter,
nodeIsMapEntry,
- nodeIsFunction,
nodeIsMissingArguments,
nodeIsOptimizedOut,
nodeIsPrimitive,
nodeIsPrototype,
nodeIsSetter,
- nodeIsWindow
-} = __webpack_require__(21);
+ nodeIsWindow,
+ shouldLoadItemEntries,
+ shouldLoadItemIndexedProperties,
+ shouldLoadItemNonIndexedProperties,
+ shouldLoadItemPrototype,
+ shouldLoadItemSymbols
+} = __webpack_require__(14);
+
+const {
+ enumEntries,
+ enumIndexedProperties,
+ enumNonIndexedProperties,
+ getPrototype,
+ enumSymbols
+} = __webpack_require__(50);
// This implements a component that renders an interactive inspector
// for looking at JavaScript objects. It expects descriptions of
// objects from the protocol, and will dynamically fetch child
// properties as objects are expanded.
//
// If you want to inspect a single object, pass the name and the
// protocol descriptor of it:
@@ -4738,90 +4700,194 @@ const {
// });
// There are 3 types of nodes: a simple node with a children array, an
// object that has properties that should be children when they are
// fetched, and a primitive value that should be displayed with no
// children.
class ObjectInspector extends Component {
- constructor() {
+ constructor(props) {
super();
-
- this.actors = {};
+ this.cachedNodes = new Map();
+
this.state = {
- expandedKeys: new Set(),
- focusedItem: null
+ actors: new Set(),
+ expandedPaths: new Set(),
+ focusedItem: null,
+ loadedProperties: props.loadedProperties || new Map(),
+ loading: new Map()
};
const self = this;
self.getChildren = this.getChildren.bind(this);
self.renderTreeItem = this.renderTreeItem.bind(this);
self.setExpanded = this.setExpanded.bind(this);
self.focusItem = this.focusItem.bind(this);
self.getRoots = this.getRoots.bind(this);
}
+ shouldComponentUpdate(nextProps, nextState) {
+ const {
+ expandedPaths,
+ loadedProperties
+ } = this.state;
+
+ return expandedPaths.size !== nextState.expandedPaths.size || loadedProperties.size !== nextState.loadedProperties.size || [...expandedPaths].some(key => !nextState.expandedPaths.has(key));
+ }
+
+ componentWillUnmount() {
+ const { releaseActor } = this.props;
+ if (typeof releaseActor !== "function") {
+ return;
+ }
+
+ const { actors } = this.state;
+ for (let actor of actors) {
+ releaseActor(actor);
+ }
+ }
+
getChildren(item) {
const {
- getObjectEntries,
- getObjectProperties
- } = this.props;
- const { actors } = this;
+ loadedProperties
+ } = this.state;
+ const { cachedNodes } = this;
return getChildren({
- getObjectEntries,
- getObjectProperties,
- actors,
+ loadedProperties,
+ cachedNodes,
item
});
}
getRoots() {
return this.props.roots;
}
getKey(item) {
return item.path;
}
+ /**
+ * This function is responsible for expanding/collapsing a given node,
+ * which also means that it will check if we need to fetch properties,
+ * entries, prototype and symbols for the said node. If we do, it will call
+ * the appropriate ObjectClient functions, and change the state of the component
+ * with the results it gets from those functions.
+ */
setExpanded(item, expand) {
- const { expandedKeys } = this.state;
- const key = this.getKey(item);
-
- if (expand === true) {
- expandedKeys.add(key);
- } else {
- expandedKeys.delete(key);
- }
-
- this.setState({ expandedKeys });
-
- if (expand === true) {
+ var _this = this;
+
+ return _asyncToGenerator(function* () {
+ if (nodeIsPrimitive(item)) {
+ return;
+ }
+
const {
- getObjectProperties,
- getObjectEntries,
- loadObjectProperties,
- loadObjectEntries
- } = this.props;
-
- const value = getValue(item);
- const parent = getParent(item);
- const parentValue = getValue(parent);
- const parentActor = parentValue ? parentValue.actor : null;
-
- if (nodeHasProperties(item) && value && !getObjectProperties(value.actor)) {
- loadObjectProperties(value);
+ loadedProperties
+ } = _this.state;
+
+ const key = _this.getKey(item);
+
+ _this.setState(function (prevState, props) {
+ const newPaths = new Set(prevState.expandedPaths);
+ if (expand === true) {
+ newPaths.add(key);
+ } else {
+ newPaths.delete(key);
+ }
+ return {
+ expandedPaths: newPaths
+ };
+ });
+
+ if (expand === true) {
+ const gripItem = getClosestGripNode(item);
+ const value = getValue(gripItem);
+
+ const path = item.path;
+ const [start, end] = item.meta ? [item.meta.startIndex, item.meta.endIndex] : [];
+
+ let promises = [];
+ let objectClient;
+ const getObjectClient = function () {
+ if (objectClient) {
+ return objectClient;
+ }
+ return _this.props.createObjectClient(value);
+ };
+
+ if (shouldLoadItemIndexedProperties(item, loadedProperties)) {
+ promises.push(enumIndexedProperties(getObjectClient(), start, end));
+ }
+
+ if (shouldLoadItemNonIndexedProperties(item, loadedProperties)) {
+ promises.push(enumNonIndexedProperties(getObjectClient(), start, end));
+ }
+
+ if (shouldLoadItemEntries(item, loadedProperties)) {
+ promises.push(enumEntries(getObjectClient(), start, end));
+ }
+
+ if (shouldLoadItemPrototype(item, loadedProperties)) {
+ promises.push(getPrototype(getObjectClient()));
+ }
+
+ if (shouldLoadItemSymbols(item, loadedProperties)) {
+ promises.push(enumSymbols(getObjectClient(), start, end));
+ }
+
+ if (promises.length > 0) {
+ // Set the loading state with the pending promises.
+ _this.setState(function (prevState, props) {
+ const nextLoading = new Map(prevState.loading);
+ nextLoading.set(path, promises);
+ return {
+ loading: nextLoading
+ };
+ });
+
+ const responses = yield Promise.all(promises);
+
+ // Let's loop through the responses to build a single response object.
+ const response = responses.reduce(function (accumulator, res) {
+ Object.entries(res).forEach(function ([k, v]) {
+ if (accumulator.hasOwnProperty(k)) {
+ if (Array.isArray(accumulator[k])) {
+ accumulator[k].push(...v);
+ } else if (typeof accumulator[k] === "object") {
+ accumulator[k] = Object.assign({}, accumulator[k], v);
+ }
+ } else {
+ accumulator[k] = v;
+ }
+ });
+ return accumulator;
+ }, {});
+
+ _this.setState(function (prevState, props) {
+ const nextLoading = new Map(prevState.loading);
+ nextLoading.delete(path);
+
+ const isRoot = _this.props.roots.some(function (root) {
+ const rootValue = getValue(root);
+ return rootValue && rootValue.actor === value.actor;
+ });
+
+ return {
+ actors: isRoot ? prevState.actors : new Set(prevState.actors).add(value.actor),
+ loadedProperties: new Map(prevState.loadedProperties).set(path, response),
+ loading: nextLoading
+ };
+ });
+ }
}
-
- if (nodeIsEntries(item) && !nodeHasAllEntriesInPreview(parent) && parentActor && !getObjectEntries(parentActor)) {
- loadObjectEntries(parentValue);
- }
- }
+ })();
}
focusItem(item) {
if (!this.props.disabledFocus && this.state.focusedItem !== item) {
this.setState({
focusedItem: item
});
@@ -4839,79 +4905,73 @@ class ObjectInspector extends Component
const isPrimitive = nodeIsPrimitive(item);
const unavailable = isPrimitive && itemValue && itemValue.hasOwnProperty && itemValue.hasOwnProperty("unavailable");
if (nodeIsOptimizedOut(item)) {
objectValue = dom.span({ className: "unavailable" }, "(optimized away)");
} else if (nodeIsMissingArguments(item) || unavailable) {
objectValue = dom.span({ className: "unavailable" }, "(unavailable)");
- } else if (nodeIsFunction(item) && !nodeIsGetter(item) && !nodeIsSetter(item)) {
+ } else if (nodeIsFunction(item) && !nodeIsGetter(item) && !nodeIsSetter(item) && (this.props.mode === MODE.TINY || !this.props.mode)) {
objectValue = undefined;
label = this.renderGrip(item, Object.assign({}, this.props, {
- simplified: depth !== 0,
functionName: label
}));
} else if (nodeHasProperties(item) || nodeHasAccessors(item) || nodeIsMapEntry(item) || isPrimitive) {
let repsProp = Object.assign({}, this.props);
if (depth > 0) {
repsProp.mode = this.props.mode === MODE.LONG ? MODE.SHORT : MODE.TINY;
}
+ if (expanded) {
+ repsProp.mode = MODE.TINY;
+ }
objectValue = this.renderGrip(item, repsProp);
}
const hasLabel = label !== null && typeof label !== "undefined";
const hasValue = typeof objectValue !== "undefined";
- const SINGLE_INDENT_WIDTH = 15;
- const indentWidth = (depth + (isPrimitive ? 1 : 0)) * SINGLE_INDENT_WIDTH;
-
const {
onDoubleClick,
onLabelClick,
dimTopLevelWindow
} = this.props;
return dom.div({
className: classnames("node object-node", {
focused,
lessen: !expanded && (nodeIsDefaultProperties(item) || nodeIsPrototype(item) || dimTopLevelWindow === true && nodeIsWindow(item) && depth === 0)
}),
- style: {
- marginLeft: indentWidth
+ onClick: e => {
+ e.stopPropagation();
+ if (isPrimitive === false) {
+ this.setExpanded(item, !expanded);
+ }
},
- onClick: isPrimitive === false ? e => {
- e.stopPropagation();
- this.setExpanded(item, !expanded);
- } : null,
onDoubleClick: onDoubleClick ? e => {
e.stopPropagation();
onDoubleClick(item, {
depth,
focused,
expanded
});
} : null
- }, isPrimitive === false ? Svg("arrow", {
- className: classnames({
- expanded: expanded
- })
- }) : null, hasLabel ? dom.span({
+ }, arrow, hasLabel ? dom.span({
className: "object-label",
onClick: onLabelClick ? event => {
event.stopPropagation();
onLabelClick(item, {
depth,
focused,
expanded,
setExpanded: this.setExpanded
});
} : null
- }, label) : null, hasLabel && hasValue ? dom.span({ className: "object-delimiter" }, " : ") : null, hasValue ? objectValue : null);
+ }, label) : null, hasLabel && hasValue ? dom.span({ className: "object-delimiter" }, ": ") : null, hasValue ? objectValue : null);
}
renderGrip(item, props) {
const object = getValue(item);
return Rep(Object.assign({}, props, {
object,
mode: props.mode || MODE.TINY,
defaultRep: Grip
@@ -4924,40 +4984,42 @@ class ObjectInspector extends Component
autoExpandAll = true,
disabledFocus,
inline,
itemHeight = 20,
disableWrap = false
} = this.props;
const {
- expandedKeys,
+ expandedPaths,
focusedItem
} = this.state;
let roots = this.getRoots();
if (roots.length === 1) {
const root = roots[0];
const name = root && root.name;
if (nodeIsPrimitive(root) && (name === null || typeof name === "undefined")) {
return this.renderGrip(root, this.props);
}
}
return Tree({
className: classnames({
inline,
- nowrap: disableWrap
+ nowrap: disableWrap,
+ "object-inspector": true
}),
autoExpandAll,
autoExpandDepth,
disabledFocus,
itemHeight,
- isExpanded: item => expandedKeys.has(this.getKey(item)),
+ isExpanded: item => expandedPaths.has(this.getKey(item)),
+ isExpandable: item => nodeIsPrimitive(item) === false,
focused: focusedItem,
getRoots: this.getRoots,
getParent,
getChildren: this.getChildren,
getKey: this.getKey,
onExpand: item => this.setExpanded(item, true),
@@ -4973,143 +5035,193 @@ ObjectInspector.displayName = "ObjectIns
ObjectInspector.propTypes = {
autoExpandAll: PropTypes.bool,
autoExpandDepth: PropTypes.number,
disabledFocus: PropTypes.bool,
disableWrap: PropTypes.bool,
inline: PropTypes.bool,
roots: PropTypes.array,
- getObjectProperties: PropTypes.func.isRequired,
- loadObjectProperties: PropTypes.func.isRequired,
itemHeight: PropTypes.number,
mode: PropTypes.oneOf(Object.values(MODE)),
+ createObjectClient: PropTypes.func.isRequired,
onFocus: PropTypes.func,
onDoubleClick: PropTypes.func,
onLabelClick: PropTypes.func
};
module.exports = ObjectInspector;
/***/ }),
-/* 57 */
+/* 43 */
/***/ (function(module, exports, __webpack_require__) {
-/* 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/. */
-
-const Tree = __webpack_require__(58);
-
-module.exports = {
- Tree
-};
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _tree = __webpack_require__(44);
+
+var _tree2 = _interopRequireDefault(_tree);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ Tree: _tree2.default
+}; /* 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/. */
/***/ }),
-/* 58 */
+/* 44 */
/***/ (function(module, exports, __webpack_require__) {
-/* 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/. */
-
-const { DOM: dom, createClass, createFactory, PropTypes } = __webpack_require__(0);
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _react = __webpack_require__(0);
+
+var _react2 = _interopRequireDefault(_react);
+
+var _svgInlineReact = __webpack_require__(10);
+
+var _svgInlineReact2 = _interopRequireDefault(_svgInlineReact);
+
+var _arrow = __webpack_require__(45);
+
+var _arrow2 = _interopRequireDefault(_arrow);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+const { DOM: dom, createClass, createFactory, createElement, PropTypes } = _react2.default; /* 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/. */
+
+__webpack_require__(46);
const AUTO_EXPAND_DEPTH = 0; // depth
/**
* An arrow that displays whether its node is expanded (▼) or collapsed
* (▶). When its node has no children, it is hidden.
*/
const ArrowExpander = createFactory(createClass({
displayName: "ArrowExpander",
+ propTypes: {
+ expanded: PropTypes.bool
+ },
+
shouldComponentUpdate(nextProps, nextState) {
- return this.props.item !== nextProps.item || this.props.visible !== nextProps.visible || this.props.expanded !== nextProps.expanded;
+ return this.props.expanded !== nextProps.expanded;
},
render() {
- const attrs = {
- className: "arrow theme-twisty",
- onClick: this.props.expanded ? () => this.props.onCollapse(this.props.item) : e => this.props.onExpand(this.props.item, e.altKey)
- };
-
- if (this.props.expanded) {
- attrs.className += " open";
+ const {
+ expanded
+ } = this.props;
+
+ const classNames = ["arrow"];
+ if (expanded) {
+ classNames.push("expanded");
}
-
- if (!this.props.visible) {
- attrs.style = Object.assign({}, this.props.style || {}, {
- visibility: "hidden"
- });
- }
-
- return dom.div(attrs, this.props.children);
+ return createElement(_svgInlineReact2.default, {
+ className: classNames.join(" "),
+ src: _arrow2.default
+ });
}
}));
const TreeNode = createFactory(createClass({
displayName: "TreeNode",
- componentDidMount() {
- if (this.props.focused) {
- this.refs.button.focus();
- }
- },
-
- componentDidUpdate() {
- if (this.props.focused) {
- this.refs.button.focus();
- }
+ propTypes: {
+ index: PropTypes.number.isRequired,
+ depth: PropTypes.number.isRequired,
+ focused: PropTypes.bool.isRequired,
+ expanded: PropTypes.bool.isRequired,
+ item: PropTypes.any.isRequired,
+ isExpandable: PropTypes.bool.isRequired,
+ onClick: PropTypes.func,
+ renderItem: PropTypes.func.isRequired
},
shouldComponentUpdate(nextProps) {
return this.props.item !== nextProps.item || this.props.focused !== nextProps.focused || this.props.expanded !== nextProps.expanded;
},
render() {
- const arrow = ArrowExpander({
- item: this.props.item,
- expanded: this.props.expanded,
- visible: this.props.hasChildren,
- onExpand: this.props.onExpand,
- onCollapse: this.props.onCollapse
- });
-
- let isOddRow = this.props.index % 2;
+ const {
+ depth,
+ item,
+ focused,
+ expanded,
+ renderItem,
+ isExpandable
+ } = this.props;
+
+ const arrow = isExpandable ? ArrowExpander({
+ item,
+ expanded
+ }) : null;
+
+ const treeIndentWidthVar = "var(--tree-indent-width)";
+ const treeBorderColorVar = "var(--tree-indent-border-color, black)";
+ const treeBorderWidthVar = "var(--tree-indent-border-width, 1px)";
+
+ const paddingInlineStart = `calc(
+ (${treeIndentWidthVar} * ${depth})
+ ${isExpandable ? "" : "+ var(--arrow-total-width)"}
+ )`;
+
+ // This is the computed border that will mimic a border on tree nodes.
+ // This allow us to have as many "borders" as we need without adding
+ // specific elements for that purpose only.
+ // it's a gradient with "hard stops" which will give us as much plain
+ // lines as we need given the depth of the node.
+ // The gradient uses CSS custom properties so everything is customizable
+ // by consumers if needed.
+ const backgroundBorder = depth === 0 ? null : "linear-gradient(90deg, " + Array.from({ length: depth }).map((_, i) => {
+ const indentWidth = `(${i} * ${treeIndentWidthVar})`;
+ const alignIndent = `(var(--arrow-width) / 2)`;
+ const start = `calc(${indentWidth} + ${alignIndent})`;
+ const end = `calc(${indentWidth} + ${alignIndent} + ${treeBorderWidthVar})`;
+
+ return `transparent ${start},
+ ${treeBorderColorVar} ${start},
+ ${treeBorderColorVar} ${end},
+ transparent ${end}`;
+ }).join(",") + ")";
+
+ let ariaExpanded;
+ if (this.props.isExpandable) {
+ ariaExpanded = false;
+ }
+ if (this.props.expanded) {
+ ariaExpanded = true;
+ }
+
return dom.div({
- className: `tree-node div ${isOddRow ? "tree-node-odd" : ""}`,
- onFocus: this.props.onFocus,
- onClick: this.props.onFocus,
- onBlur: this.props.onBlur,
+ className: "tree-node" + (focused ? " focused" : ""),
style: {
- padding: 0,
- margin: 0
- }
- }, this.props.renderItem(this.props.item, this.props.depth, this.props.focused, arrow, this.props.expanded),
-
- // XXX: OSX won't focus/blur regular elements even if you set tabindex
- // unless there is an input/button child.
- dom.button(this._buttonAttrs));
- },
-
- _buttonAttrs: {
- ref: "button",
- style: {
- opacity: 0,
- width: "0 !important",
- height: "0 !important",
- padding: "0 !important",
- outline: "none",
- MozAppearance: "none",
- // XXX: Despite resetting all of the above properties (and margin), the
- // button still ends up with ~79px width, so we set a large negative
- // margin to completely hide it.
- MozMarginStart: "-1000px !important"
- }
+ paddingInlineStart,
+ backgroundImage: backgroundBorder
+ },
+ onClick: this.props.onClick,
+ role: "treeitem",
+ "aria-level": depth,
+ "aria-expanded": ariaExpanded
+ }, renderItem(item, depth, focused, arrow, expanded));
}
}));
/**
* Create a function that calls the given function `fn` only once per animation
* frame.
*
* @param {Function} fn
@@ -5127,62 +5239,233 @@ function oncePerAnimationFrame(fn) {
animationId = requestAnimationFrame(() => {
fn.call(this, ...argsToPass);
animationId = null;
argsToPass = null;
});
};
}
-const NUMBER_OF_OFFSCREEN_ITEMS = 1;
-
/**
* A generic tree component. See propTypes for the public API.
*
- * @see `devtools/client/memory/components/test/mochitest/head.js` for usage
- * @see `devtools/client/memory/components/heap.js` for usage
+ * This tree component doesn't make any assumptions about the structure of your
+ * tree data. Whether children are computed on demand, or stored in an array in
+ * the parent's `_children` property, it doesn't matter. We only require the
+ * implementation of `getChildren`, `getRoots`, `getParent`, and `isExpanded`
+ * functions.
+ *
+ * This tree component is well tested and reliable. See the tests in ./tests
+ * and its usage in the performance and memory panels in mozilla-central.
+ *
+ * This tree component doesn't make any assumptions about how to render items in
+ * the tree. You provide a `renderItem` function, and this component will ensure
+ * that only those items whose parents are expanded and which are visible in the
+ * viewport are rendered. The `renderItem` function could render the items as a
+ * "traditional" tree or as rows in a table or anything else. It doesn't
+ * restrict you to only one certain kind of tree.
+ *
+ * The tree comes with basic styling for the indent, the arrow, as well as hovered
+ * and focused styles.
+ * All of this can be customize on the customer end, by overriding the following
+ * CSS custom properties :
+ * --arrow-width: the width of the arrow.
+ * --arrow-single-margin: the end margin between the arrow and the item that follows.
+ * --arrow-fill-color: the fill-color of the arrow.
+ * --tree-indent-width: the width of a 1-level-deep item.
+ * --tree-indent-border-color: the color of the indent border.
+ * --tree-indent-border-width: the width of the indent border.
+ * --tree-node-hover-background-color: the background color of a hovered node.
+ * --tree-node-focus-color: the color of a focused node.
+ * --tree-node-focus-background-color: the background color of a focused node.
+ *
+ *
+ * ### Example Usage
+ *
+ * Suppose we have some tree data where each item has this form:
+ *
+ * {
+ * id: Number,
+ * label: String,
+ * parent: Item or null,
+ * children: Array of child items,
+ * expanded: bool,
+ * }
+ *
+ * Here is how we could render that data with this component:
+ *
+ * const MyTree = createClass({
+ * displayName: "MyTree",
+ *
+ * propTypes: {
+ * // The root item of the tree, with the form described above.
+ * root: PropTypes.object.isRequired
+ * },
+ *
+ * render() {
+ * return Tree({
+ * itemHeight: 20, // px
+ *
+ * getRoots: () => [this.props.root],
+ *
+ * getParent: item => item.parent,
+ * getChildren: item => item.children,
+ * getKey: item => item.id,
+ * isExpanded: item => item.expanded,
+ *
+ * renderItem: (item, depth, isFocused, arrow, isExpanded) => {
+ * let className = "my-tree-item";
+ * if (isFocused) {
+ * className += " focused";
+ * }
+ * return dom.div({
+ * className,
+ * },
+ * arrow,
+ * // And here is the label for this item.
+ * dom.span({ className: "my-tree-item-label" }, item.label)
+ * );
+ * },
+ *
+ * onExpand: item => dispatchExpandActionToRedux(item),
+ * onCollapse: item => dispatchCollapseActionToRedux(item),
+ * });
+ * }
+ * });
*/
-const Tree = module.exports = createClass({
+const Tree = createClass({
displayName: "Tree",
propTypes: {
// Required props
// A function to get an item's parent, or null if it is a root.
+ //
+ // Type: getParent(item: Item) -> Maybe<Item>
+ //
+ // Example:
+ //
+ // // The parent of this item is stored in its `parent` property.
+ // getParent: item => item.parent
getParent: PropTypes.func.isRequired,
+
// A function to get an item's children.
+ //
+ // Type: getChildren(item: Item) -> [Item]
+ //
+ // Example:
+ //
+ // // This item's children are stored in its `children` property.
+ // getChildren: item => item.children
getChildren: PropTypes.func.isRequired,
- // A function which takes an item and ArrowExpander and returns a
- // component.
+
+ // A function which takes an item and ArrowExpander component instance and
+ // returns a component, or text, or anything else that React considers
+ // renderable.
+ //
+ // Type: renderItem(item: Item,
+ // depth: Number,
+ // isFocused: Boolean,
+ // arrow: ReactComponent,
+ // isExpanded: Boolean) -> ReactRenderable
+ //
+ // Example:
+ //
+ // renderItem: (item, depth, isFocused, arrow, isExpanded) => {
+ // let className = "my-tree-item";
+ // if (isFocused) {
+ // className += " focused";
+ // }
+ // return dom.div(
+ // {
+ // className,
+ // style: { marginLeft: depth * 10 + "px" }
+ // },
+ // arrow,
+ // dom.span({ className: "my-tree-item-label" }, item.label)
+ // );
+ // },
renderItem: PropTypes.func.isRequired,
+
// A function which returns the roots of the tree (forest).
+ //
+ // Type: getRoots() -> [Item]
+ //
+ // Example:
+ //
+ // // In this case, we only have one top level, root item. You could
+ // // return multiple items if you have many top level items in your
+ // // tree.
+ // getRoots: () => [this.props.rootOfMyTree]
getRoots: PropTypes.func.isRequired,
- // A function to get a unique key for the given item.
+
+ // A function to get a unique key for the given item. This helps speed up
+ // React's rendering a *TON*.
+ //
+ // Type: getKey(item: Item) -> String
+ //
+ // Example:
+ //
+ // getKey: item => `my-tree-item-${item.uniqueId}`
getKey: PropTypes.func.isRequired,
+
// A function to get whether an item is expanded or not. If an item is not
// expanded, then it must be collapsed.
+ //
+ // Type: isExpanded(item: Item) -> Boolean
+ //
+ // Example:
+ //
+ // isExpanded: item => item.expanded,
isExpanded: PropTypes.func.isRequired,
+
// The height of an item in the tree including margin and padding, in
// pixels.
itemHeight: PropTypes.number.isRequired,
// Optional props
// The currently focused item, if any such item exists.
focused: PropTypes.any,
+
// Handle when a new item is focused.
onFocus: PropTypes.func,
+
// The depth to which we should automatically expand new items.
autoExpandDepth: PropTypes.number,
// Should auto expand all new items or just the new items under the first
// root item.
autoExpandAll: PropTypes.bool,
- // Optional event handlers for when items are expanded or collapsed.
+
+ // Note: the two properties below are mutually exclusive. Only one of the
+ // label properties is necessary.
+ // ID of an element whose textual content serves as an accessible label for
+ // a tree.
+ labelledby: PropTypes.string,
+ // Accessibility label for a tree widget.
+ label: PropTypes.string,
+
+ // Optional event handlers for when items are expanded or collapsed. Useful
+ // for dispatching redux events and updating application state, maybe lazily
+ // loading subtrees from a worker, etc.
+ //
+ // Type:
+ // onExpand(item: Item)
+ // onCollapse(item: Item)
+ //
+ // Example:
+ //
+ // onExpand: item => dispatchExpandActionToRedux(item)
onExpand: PropTypes.func,
- onCollapse: PropTypes.func
+ onCollapse: PropTypes.func,
+ isExpandable: PropTypes.func,
+ // Additional classes to add to the root element.
+ className: PropTypes.string,
+ // style object to be applied to the root element.
+ style: PropTypes.object
},
getDefaultProps() {
return {
autoExpandDepth: AUTO_EXPAND_DEPTH,
autoExpandAll: true
};
},
@@ -5192,99 +5475,63 @@ const Tree = module.exports = createClas
scroll: 0,
height: window.innerHeight,
seen: new Set()
};
},
componentDidMount() {
window.addEventListener("resize", this._updateHeight);
- this._autoExpand(this.props);
+ this._autoExpand();
+ this._updateHeight();
+ },
+
+ componentWillReceiveProps(nextProps) {
+ this._autoExpand();
this._updateHeight();
},
componentWillUnmount() {
window.removeEventListener("resize", this._updateHeight);
},
- componentWillReceiveProps(nextProps) {
- this._autoExpand(nextProps);
- this._updateHeight();
- },
-
- _autoExpand(props) {
- if (!props.autoExpandDepth) {
+ _autoExpand() {
+ if (!this.props.autoExpandDepth) {
return;
}
// Automatically expand the first autoExpandDepth levels for new items. Do
// not use the usual DFS infrastructure because we don't want to ignore
// collapsed nodes.
const autoExpand = (item, currentDepth) => {
- if (currentDepth >= props.autoExpandDepth || this.state.seen.has(item)) {
+ if (currentDepth >= this.props.autoExpandDepth || this.state.seen.has(item)) {
return;
}
- props.onExpand(item);
+ this.props.onExpand(item);
this.state.seen.add(item);
- const children = props.getChildren(item);
+ const children = this.props.getChildren(item);
const length = children.length;
for (let i = 0; i < length; i++) {
autoExpand(children[i], currentDepth + 1);
}
};
- const roots = props.getRoots();
+ const roots = this.props.getRoots();
const length = roots.length;
- if (props.autoExpandAll) {
+ if (this.props.autoExpandAll) {
for (let i = 0; i < length; i++) {
autoExpand(roots[i], 0);
}
} else if (length != 0) {
autoExpand(roots[0], 0);
}
},
- render() {
- const traversal = this._dfsFromRoots();
-
- const renderItem = i => {
- let { item, depth } = traversal[i];
- return TreeNode({
- key: this.props.getKey(item, i),
- index: i,
- item: item,
- depth: depth,
- renderItem: this.props.renderItem,
- focused: this.props.focused === item,
- expanded: this.props.isExpanded(item),
- hasChildren: !!this.props.getChildren(item).length,
- onExpand: this._onExpand,
- onCollapse: this._onCollapse,
- onFocus: () => this._focus(i, item)
- });
- };
-
- const style = Object.assign({}, this.props.style || {}, {
- padding: 0,
- margin: 0
- });
-
- return dom.div({
- className: `tree ${this.props.className ? this.props.className : ""}`,
- ref: "tree",
- onKeyDown: this._onKeyDown,
- onKeyPress: this._preventArrowKeyScrolling,
- onKeyUp: this._preventArrowKeyScrolling,
- onScroll: this._onScroll,
- style
- }, traversal.map((v, i) => renderItem(i)));
- },
-
_preventArrowKeyScrolling(e) {
switch (e.key) {
case "ArrowUp":
case "ArrowDown":
case "ArrowLeft":
case "ArrowRight":
e.preventDefault();
e.stopPropagation();
@@ -5454,28 +5701,29 @@ const Tree = module.exports = createClas
this._focusPrevNode();
return;
case "ArrowDown":
this._focusNextNode();
return;
case "ArrowLeft":
- if (this.props.isExpanded(this.props.focused) && this.props.getChildren(this.props.focused).length) {
+ if (this.props.isExpanded(this.props.focused) && this._nodeIsExpandable(this.props.focused)) {
this._onCollapse(this.props.focused);
} else {
this._focusParentNode();
}
return;
case "ArrowRight":
if (!this.props.isExpanded(this.props.focused)) {
this._onExpand(this.props.focused);
+ } else {
+ this._focusNextNode();
}
- return;
}
},
/**
* Sets the previous node relative to the currently focused item, to focused.
*/
_focusPrevNode: oncePerAnimationFrame(function () {
// Start a depth first search and keep going until we reach the currently
@@ -5543,27 +5791,114 @@ const Tree = module.exports = createClas
let parentIndex = 0;
for (; parentIndex < length; parentIndex++) {
if (traversal[parentIndex].item === parent) {
break;
}
}
this._focus(parentIndex, parent);
- })
+ }),
+
+ _nodeIsExpandable: function (item) {
+ return this.props.isExpandable ? this.props.isExpandable(item) : !!this.props.getChildren(item).length;
+ },
+
+ render() {
+ const traversal = this._dfsFromRoots();
+ const {
+ focused
+ } = this.props;
+
+ const nodes = traversal.map((v, i) => {
+ const { item, depth } = traversal[i];
+ return TreeNode({
+ key: this.props.getKey(item, i),
+ index: i,
+ item,
+ depth,
+ renderItem: this.props.renderItem,
+ focused: focused === item,
+ expanded: this.props.isExpanded(item),
+ isExpandable: this._nodeIsExpandable(item),
+ onExpand: this._onExpand,
+ onCollapse: this._onCollapse,
+ onClick: e => {
+ this._focus(i, item);
+ if (this.props.isExpanded(item)) {
+ this.props.onCollapse(item);
+ } else {
+ this.props.onExpand(item, e.altKey);
+ }
+ }
+ });
+ });
+
+ const style = Object.assign({}, this.props.style || {}, {
+ padding: 0,
+ margin: 0
+ });
+
+ return dom.div({
+ className: `tree ${this.props.className ? this.props.className : ""}`,
+ ref: "tree",
+ role: "tree",
+ tabIndex: "0",
+ onKeyDown: this._onKeyDown,
+ onKeyPress: this._preventArrowKeyScrolling,
+ onKeyUp: this._preventArrowKeyScrolling,
+ onScroll: this._onScroll,
+ onFocus: ({ nativeEvent }) => {
+ if (focused || !nativeEvent || !this.refs.tree) {
+ return;
+ }
+
+ let { explicitOriginalTarget } = nativeEvent;
+ // Only set default focus to the first tree node if the focus came
+ // from outside the tree (e.g. by tabbing to the tree from other
+ // external elements).
+ if (explicitOriginalTarget !== this.refs.tree && !this.refs.tree.contains(explicitOriginalTarget)) {
+ this._focus(0, traversal[0].item);
+ }
+ },
+ onBlur: this._onBlur,
+ onClick: () => {
+ // Focus should always remain on the tree container itself.
+ this.refs.tree.focus();
+ },
+ "aria-label": this.props.label,
+ "aria-labelledby": this.props.labelledby,
+ "aria-activedescendant": focused && this.props.getKey(focused),
+ style
+ }, nodes);
+ }
});
+exports.default = Tree;
+
/***/ }),
-/* 59 */
+/* 45 */
+/***/ (function(module, exports) {
+
+module.exports = "<!-- 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 viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z\"></path></svg>"
+
+/***/ }),
+/* 46 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
-/* 60 */
+/* 47 */
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+/* 48 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
Copyright (c) 2016 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/* global define */
@@ -5608,1503 +5943,94 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBP
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else {
window.classNames = classNames;
}
}());
/***/ }),
-/* 61 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var baseGet = __webpack_require__(62);
-
-/**
- * Gets the value at `path` of `object`. If the resolved value is
- * `undefined`, the `defaultValue` is returned in its place.
- *
- * @static
- * @memberOf _
- * @since 3.7.0
- * @category Object
- * @param {Object} object The object to query.
- * @param {Array|string} path The path of the property to get.
- * @param {*} [defaultValue] The value returned for `undefined` resolved values.
- * @returns {*} Returns the resolved value.
- * @example
- *
- * var object = { 'a': [{ 'b': { 'c': 3 } }] };
- *
- * _.get(object, 'a[0].b.c');
- * // => 3
- *
- * _.get(object, ['a', '0', 'b', 'c']);
- * // => 3
- *
- * _.get(object, 'a.b.c', 'default');
- * // => 'default'
- */
-function get(object, path, defaultValue) {
- var result = object == null ? undefined : baseGet(object, path);
- return result === undefined ? defaultValue : result;
-}
-
-module.exports = get;
-
-
-/***/ }),
-/* 62 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var castPath = __webpack_require__(22),
- toKey = __webpack_require__(25);
-
-/**
- * The base implementation of `_.get` without support for default values.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array|string} path The path of the property to get.
- * @returns {*} Returns the resolved value.
- */
-function baseGet(object, path) {
- path = castPath(path, object);
-
- var index = 0,
- length = path.length;
-
- while (object != null && index < length) {
- object = object[toKey(path[index++])];
- }
- return (index && index == length) ? object : undefined;
-}
-
-module.exports = baseGet;
-
-
-/***/ }),
-/* 63 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var isArray = __webpack_require__(5),
- isSymbol = __webpack_require__(11);
-
-/** Used to match property names within property paths. */
-var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
- reIsPlainProp = /^\w*$/;
-
-/**
- * Checks if `value` is a property name and not a property path.
- *
- * @private
- * @param {*} value The value to check.
- * @param {Object} [object] The object to query keys on.
- * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
- */
-function isKey(value, object) {
- if (isArray(value)) {
- return false;
- }
- var type = typeof value;
- if (type == 'number' || type == 'symbol' || type == 'boolean' ||
- value == null || isSymbol(value)) {
- return true;
- }
- return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
- (object != null && value in Object(object));
-}
-
-module.exports = isKey;
-
-
-/***/ }),
-/* 64 */
-/***/ (function(module, exports, __webpack_require__) {
-
-/* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */
-var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
-
-module.exports = freeGlobal;
-
-/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(65)))
-
-/***/ }),
-/* 65 */
-/***/ (function(module, exports) {
-
-var g;
-
-// This works in non-strict mode
-g = (function() {
- return this;
-})();
-
-try {
- // This works if eval is allowed (see CSP)
- g = g || Function("return this")() || (1,eval)("this");
-} catch(e) {
- // This works if the window reference is available
- if(typeof window === "object")
- g = window;
-}
-
-// g can still be undefined, but nothing to do about it...
-// We return undefined, instead of nothing here, so it's
-// easier to handle this case. if(!global) { ...}
-
-module.exports = g;
-
-
-/***/ }),
-/* 66 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var Symbol = __webpack_require__(13);
-
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/**
- * Used to resolve the
- * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
- * of values.
- */
-var nativeObjectToString = objectProto.toString;
-
-/** Built-in value references. */
-var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
-
-/**
- * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
- *
- * @private
- * @param {*} value The value to query.
- * @returns {string} Returns the raw `toStringTag`.
- */
-function getRawTag(value) {
- var isOwn = hasOwnProperty.call(value, symToStringTag),
- tag = value[symToStringTag];
-
- try {
- value[symToStringTag] = undefined;
- var unmasked = true;
- } catch (e) {}
-
- var result = nativeObjectToString.call(value);
- if (unmasked) {
- if (isOwn) {
- value[symToStringTag] = tag;
- } else {
- delete value[symToStringTag];
- }
- }
- return result;
-}
-
-module.exports = getRawTag;
-
-
-/***/ }),
-/* 67 */
+/* 49 */
/***/ (function(module, exports) {
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
-
-/**
- * Used to resolve the
- * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
- * of values.
- */
-var nativeObjectToString = objectProto.toString;
-
-/**
- * Converts `value` to a string using `Object.prototype.toString`.
- *
- * @private
- * @param {*} value The value to convert.
- * @returns {string} Returns the converted string.
- */
-function objectToString(value) {
- return nativeObjectToString.call(value);
-}
-
-module.exports = objectToString;
-
-
-/***/ }),
-/* 68 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var memoizeCapped = __webpack_require__(69);
-
-/** Used to match property names within property paths. */
-var reLeadingDot = /^\./,
- rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
-
-/** Used to match backslashes in property paths. */
-var reEscapeChar = /\\(\\)?/g;
-
-/**
- * Converts `string` to a property path array.
- *
- * @private
- * @param {string} string The string to convert.
- * @returns {Array} Returns the property path array.
- */
-var stringToPath = memoizeCapped(function(string) {
- var result = [];
- if (reLeadingDot.test(string)) {
- result.push('');
- }
- string.replace(rePropName, function(match, number, quote, string) {
- result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
- });
- return result;
-});
-
-module.exports = stringToPath;
-
-
-/***/ }),
-/* 69 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var memoize = __webpack_require__(70);
-
-/** Used as the maximum memoize cache size. */
-var MAX_MEMOIZE_SIZE = 500;
-
-/**
- * A specialized version of `_.memoize` which clears the memoized function's
- * cache when it exceeds `MAX_MEMOIZE_SIZE`.
- *
- * @private
- * @param {Function} func The function to have its output memoized.
- * @returns {Function} Returns the new memoized function.
- */
-function memoizeCapped(func) {
- var result = memoize(func, function(key) {
- if (cache.size === MAX_MEMOIZE_SIZE) {
- cache.clear();
- }
- return key;
- });
-
- var cache = result.cache;
- return result;
-}
-
-module.exports = memoizeCapped;
-
-
-/***/ }),
-/* 70 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var MapCache = __webpack_require__(71);
-
-/** Error message constants. */
-var FUNC_ERROR_TEXT = 'Expected a function';
-
-/**
- * Creates a function that memoizes the result of `func`. If `resolver` is
- * provided, it determines the cache key for storing the result based on the
- * arguments provided to the memoized function. By default, the first argument
- * provided to the memoized function is used as the map cache key. The `func`
- * is invoked with the `this` binding of the memoized function.
- *
- * **Note:** The cache is exposed as the `cache` property on the memoized
- * function. Its creation may be customized by replacing the `_.memoize.Cache`
- * constructor with one whose instances implement the
- * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
- * method interface of `clear`, `delete`, `get`, `has`, and `set`.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Function
- * @param {Function} func The function to have its output memoized.
- * @param {Function} [resolver] The function to resolve the cache key.
- * @returns {Function} Returns the new memoized function.
- * @example
- *
- * var object = { 'a': 1, 'b': 2 };
- * var other = { 'c': 3, 'd': 4 };
- *
- * var values = _.memoize(_.values);
- * values(object);
- * // => [1, 2]
- *
- * values(other);
- * // => [3, 4]
- *
- * object.a = 2;
- * values(object);
- * // => [1, 2]
- *
- * // Modify the result cache.
- * values.cache.set(object, ['a', 'b']);
- * values(object);
- * // => ['a', 'b']
- *
- * // Replace `_.memoize.Cache`.
- * _.memoize.Cache = WeakMap;
- */
-function memoize(func, resolver) {
- if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
- throw new TypeError(FUNC_ERROR_TEXT);
- }
- var memoized = function() {
- var args = arguments,
- key = resolver ? resolver.apply(this, args) : args[0],
- cache = memoized.cache;
-
- if (cache.has(key)) {
- return cache.get(key);
- }
- var result = func.apply(this, args);
- memoized.cache = cache.set(key, result) || cache;
- return result;
- };
- memoized.cache = new (memoize.Cache || MapCache);
- return memoized;
-}
-
-// Expose `MapCache`.
-memoize.Cache = MapCache;
-
-module.exports = memoize;
-
-
-/***/ }),
-/* 71 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var mapCacheClear = __webpack_require__(72),
- mapCacheDelete = __webpack_require__(93),
- mapCacheGet = __webpack_require__(95),
- mapCacheHas = __webpack_require__(96),
- mapCacheSet = __webpack_require__(97);
-
-/**
- * Creates a map cache object to store key-value pairs.
- *
- * @private
- * @constructor
- * @param {Array} [entries] The key-value pairs to cache.
- */
-function MapCache(entries) {
- var index = -1,
- length = entries == null ? 0 : entries.length;
-
- this.clear();
- while (++index < length) {
- var entry = entries[index];
- this.set(entry[0], entry[1]);
- }
-}
-
-// Add methods to `MapCache`.
-MapCache.prototype.clear = mapCacheClear;
-MapCache.prototype['delete'] = mapCacheDelete;
-MapCache.prototype.get = mapCacheGet;
-MapCache.prototype.has = mapCacheHas;
-MapCache.prototype.set = mapCacheSet;
-
-module.exports = MapCache;
-
-
-/***/ }),
-/* 72 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var Hash = __webpack_require__(73),
- ListCache = __webpack_require__(85),
- Map = __webpack_require__(92);
-
-/**
- * Removes all key-value entries from the map.
- *
- * @private
- * @name clear
- * @memberOf MapCache
- */
-function mapCacheClear() {
- this.size = 0;
- this.__data__ = {
- 'hash': new Hash,
- 'map': new (Map || ListCache),
- 'string': new Hash
- };
-}
-
-module.exports = mapCacheClear;
-
-
-/***/ }),
-/* 73 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var hashClear = __webpack_require__(74),
- hashDelete = __webpack_require__(81),
- hashGet = __webpack_require__(82),
- hashHas = __webpack_require__(83),
- hashSet = __webpack_require__(84);
-
-/**
- * Creates a hash object.
- *
- * @private
- * @constructor
- * @param {Array} [entries] The key-value pairs to cache.
- */
-function Hash(entries) {
- var index = -1,
- length = entries == null ? 0 : entries.length;
-
- this.clear();
- while (++index < length) {
- var entry = entries[index];
- this.set(entry[0], entry[1]);
- }
-}
-
-// Add methods to `Hash`.
-Hash.prototype.clear = hashClear;
-Hash.prototype['delete'] = hashDelete;
-Hash.prototype.get = hashGet;
-Hash.prototype.has = hashHas;
-Hash.prototype.set = hashSet;
-
-module.exports = Hash;
-
-
-/***/ }),
-/* 74 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var nativeCreate = __webpack_require__(6);
-
-/**
- * Removes all key-value entries from the hash.
- *
- * @private
- * @name clear
- * @memberOf Hash
- */
-function hashClear() {
- this.__data__ = nativeCreate ? nativeCreate(null) : {};
- this.size = 0;
-}
-
-module.exports = hashClear;
-
-
-/***/ }),
-/* 75 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var isFunction = __webpack_require__(76),
- isMasked = __webpack_require__(77),
- isObject = __webpack_require__(24),
- toSource = __webpack_require__(79);
-
-/**
- * Used to match `RegExp`
- * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
- */
-var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
-
-/** Used to detect host constructors (Safari). */
-var reIsHostCtor = /^\[object .+?Constructor\]$/;
-
-/** Used for built-in method references. */
-var funcProto = Function.prototype,
- objectProto = Object.prototype;
-
-/** Used to resolve the decompiled source of functions. */
-var funcToString = funcProto.toString;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/** Used to detect if a method is native. */
-var reIsNative = RegExp('^' +
- funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
- .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
-);
-
-/**
- * The base implementation of `_.isNative` without bad shim checks.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a native function,
- * else `false`.
- */
-function baseIsNative(value) {
- if (!isObject(value) || isMasked(value)) {
- return false;
- }
- var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
- return pattern.test(toSource(value));
-}
-
-module.exports = baseIsNative;
-
-
-/***/ }),
-/* 76 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var baseGetTag = __webpack_require__(12),
- isObject = __webpack_require__(24);
-
-/** `Object#toString` result references. */
-var asyncTag = '[object AsyncFunction]',
- funcTag = '[object Function]',
- genTag = '[object GeneratorFunction]',
- proxyTag = '[object Proxy]';
-
-/**
- * Checks if `value` is classified as a `Function` object.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a function, else `false`.
- * @example
- *
- * _.isFunction(_);
- * // => true
- *
- * _.isFunction(/abc/);
- * // => false
- */
-function isFunction(value) {
- if (!isObject(value)) {
- return false;
- }
- // The use of `Object#toString` avoids issues with the `typeof` operator
- // in Safari 9 which returns 'object' for typed arrays and other constructors.
- var tag = baseGetTag(value);
- return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
-}
-
-module.exports = isFunction;
-
-
-/***/ }),
-/* 77 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var coreJsData = __webpack_require__(78);
-
-/** Used to detect methods masquerading as native. */
-var maskSrcKey = (function() {
- var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
- return uid ? ('Symbol(src)_1.' + uid) : '';
-}());
-
-/**
- * Checks if `func` has its source masked.
- *
- * @private
- * @param {Function} func The function to check.
- * @returns {boolean} Returns `true` if `func` is masked, else `false`.
- */
-function isMasked(func) {
- return !!maskSrcKey && (maskSrcKey in func);
-}
-
-module.exports = isMasked;
-
-
-/***/ }),
-/* 78 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var root = __webpack_require__(14);
-
-/** Used to detect overreaching core-js shims. */
-var coreJsData = root['__core-js_shared__'];
-
-module.exports = coreJsData;
-
-
-/***/ }),
-/* 79 */
-/***/ (function(module, exports) {
-
-/** Used for built-in method references. */
-var funcProto = Function.prototype;
-
-/** Used to resolve the decompiled source of functions. */
-var funcToString = funcProto.toString;
-
-/**
- * Converts `func` to its source code.
- *
- * @private
- * @param {Function} func The function to convert.
- * @returns {string} Returns the source code.
- */
-function toSource(func) {
- if (func != null) {
- try {
- return funcToString.call(func);
- } catch (e) {}
- try {
- return (func + '');
- } catch (e) {}
- }
- return '';
-}
-
-module.exports = toSource;
-
-
-/***/ }),
-/* 80 */
-/***/ (function(module, exports) {
-
-/**
- * Gets the value at `key` of `object`.
- *
- * @private
- * @param {Object} [object] The object to query.
- * @param {string} key The key of the property to get.
- * @returns {*} Returns the property value.
- */
-function getValue(object, key) {
- return object == null ? undefined : object[key];
-}
-
-module.exports = getValue;
-
-
-/***/ }),
-/* 81 */
-/***/ (function(module, exports) {
-
-/**
- * Removes `key` and its value from the hash.
- *
- * @private
- * @name delete
- * @memberOf Hash
- * @param {Object} hash The hash to modify.
- * @param {string} key The key of the value to remove.
- * @returns {boolean} Returns `true` if the entry was removed, else `false`.
- */
-function hashDelete(key) {
- var result = this.has(key) && delete this.__data__[key];
- this.size -= result ? 1 : 0;
- return result;
-}
-
-module.exports = hashDelete;
-
-
-/***/ }),
-/* 82 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var nativeCreate = __webpack_require__(6);
-
-/** Used to stand-in for `undefined` hash values. */
-var HASH_UNDEFINED = '__lodash_hash_undefined__';
-
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/**
- * Gets the hash value for `key`.
- *
- * @private
- * @name get
- * @memberOf Hash
- * @param {string} key The key of the value to get.
- * @returns {*} Returns the entry value.
- */
-function hashGet(key) {
- var data = this.__data__;
- if (nativeCreate) {
- var result = data[key];
- return result === HASH_UNDEFINED ? undefined : result;
- }
- return hasOwnProperty.call(data, key) ? data[key] : undefined;
-}
-
-module.exports = hashGet;
-
+module.exports = __WEBPACK_EXTERNAL_MODULE_49__;
/***/ }),
-/* 83 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var nativeCreate = __webpack_require__(6);
-
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/**
- * Checks if a hash value for `key` exists.
- *
- * @private
- * @name has
- * @memberOf Hash
- * @param {string} key The key of the entry to check.
- * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
- */
-function hashHas(key) {
- var data = this.__data__;
- return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
-}
-
-module.exports = hashHas;
-
-
-/***/ }),
-/* 84 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var nativeCreate = __webpack_require__(6);
-
-/** Used to stand-in for `undefined` hash values. */
-var HASH_UNDEFINED = '__lodash_hash_undefined__';
-
-/**
- * Sets the hash `key` to `value`.
- *
- * @private
- * @name set
- * @memberOf Hash
- * @param {string} key The key of the value to set.
- * @param {*} value The value to set.
- * @returns {Object} Returns the hash instance.
- */
-function hashSet(key, value) {
- var data = this.__data__;
- this.size += this.has(key) ? 0 : 1;
- data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
- return this;
-}
-
-module.exports = hashSet;
-
-
-/***/ }),
-/* 85 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var listCacheClear = __webpack_require__(86),
- listCacheDelete = __webpack_require__(87),
- listCacheGet = __webpack_require__(89),
- listCacheHas = __webpack_require__(90),
- listCacheSet = __webpack_require__(91);
-
-/**
- * Creates an list cache object.
- *
- * @private
- * @constructor
- * @param {Array} [entries] The key-value pairs to cache.
- */
-function ListCache(entries) {
- var index = -1,
- length = entries == null ? 0 : entries.length;
-
- this.clear();
- while (++index < length) {
- var entry = entries[index];
- this.set(entry[0], entry[1]);
- }
-}
-
-// Add methods to `ListCache`.
-ListCache.prototype.clear = listCacheClear;
-ListCache.prototype['delete'] = listCacheDelete;
-ListCache.prototype.get = listCacheGet;
-ListCache.prototype.has = listCacheHas;
-ListCache.prototype.set = listCacheSet;
-
-module.exports = ListCache;
-
-
-/***/ }),
-/* 86 */
-/***/ (function(module, exports) {
-
-/**
- * Removes all key-value entries from the list cache.
- *
- * @private
- * @name clear
- * @memberOf ListCache
- */
-function listCacheClear() {
- this.__data__ = [];
- this.size = 0;
-}
-
-module.exports = listCacheClear;
-
-
-/***/ }),
-/* 87 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var assocIndexOf = __webpack_require__(7);
-
-/** Used for built-in method references. */
-var arrayProto = Array.prototype;
-
-/** Built-in value references. */
-var splice = arrayProto.splice;
-
-/**
- * Removes `key` and its value from the list cache.
- *
- * @private
- * @name delete
- * @memberOf ListCache
- * @param {string} key The key of the value to remove.
- * @returns {boolean} Returns `true` if the entry was removed, else `false`.
- */
-function listCacheDelete(key) {
- var data = this.__data__,
- index = assocIndexOf(data, key);
-
- if (index < 0) {
- return false;
- }
- var lastIndex = data.length - 1;
- if (index == lastIndex) {
- data.pop();
- } else {
- splice.call(data, index, 1);
- }
- --this.size;
- return true;
-}
-
-module.exports = listCacheDelete;
-
-
-/***/ }),
-/* 88 */
-/***/ (function(module, exports) {
-
-/**
- * Performs a
- * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
- * comparison between two values to determine if they are equivalent.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to compare.
- * @param {*} other The other value to compare.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- * @example
- *
- * var object = { 'a': 1 };
- * var other = { 'a': 1 };
- *
- * _.eq(object, object);
- * // => true
- *
- * _.eq(object, other);
- * // => false
- *
- * _.eq('a', 'a');
- * // => true
- *
- * _.eq('a', Object('a'));
- * // => false
- *
- * _.eq(NaN, NaN);
- * // => true
- */
-function eq(value, other) {
- return value === other || (value !== value && other !== other);
-}
-
-module.exports = eq;
-
-
-/***/ }),
-/* 89 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var assocIndexOf = __webpack_require__(7);
-
-/**
- * Gets the list cache value for `key`.
- *
- * @private
- * @name get
- * @memberOf ListCache
- * @param {string} key The key of the value to get.
- * @returns {*} Returns the entry value.
- */
-function listCacheGet(key) {
- var data = this.__data__,
- index = assocIndexOf(data, key);
-
- return index < 0 ? undefined : data[index][1];
-}
-
-module.exports = listCacheGet;
-
-
-/***/ }),
-/* 90 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var assocIndexOf = __webpack_require__(7);
-
-/**
- * Checks if a list cache value for `key` exists.
- *
- * @private
- * @name has
- * @memberOf ListCache
- * @param {string} key The key of the entry to check.
- * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
- */
-function listCacheHas(key) {
- return assocIndexOf(this.__data__, key) > -1;
-}
-
-module.exports = listCacheHas;
-
-
-/***/ }),
-/* 91 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var assocIndexOf = __webpack_require__(7);
-
-/**
- * Sets the list cache `key` to `value`.
- *
- * @private
- * @name set
- * @memberOf ListCache
- * @param {string} key The key of the value to set.
- * @param {*} value The value to set.
- * @returns {Object} Returns the list cache instance.
- */
-function listCacheSet(key, value) {
- var data = this.__data__,
- index = assocIndexOf(data, key);
-
- if (index < 0) {
- ++this.size;
- data.push([key, value]);
- } else {
- data[index][1] = value;
- }
- return this;
-}
-
-module.exports = listCacheSet;
-
-
-/***/ }),
-/* 92 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var getNative = __webpack_require__(23),
- root = __webpack_require__(14);
-
-/* Built-in method references that are verified to be native. */
-var Map = getNative(root, 'Map');
-
-module.exports = Map;
-
-
-/***/ }),
-/* 93 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var getMapData = __webpack_require__(8);
-
-/**
- * Removes `key` and its value from the map.
- *
- * @private
- * @name delete
- * @memberOf MapCache
- * @param {string} key The key of the value to remove.
- * @returns {boolean} Returns `true` if the entry was removed, else `false`.
- */
-function mapCacheDelete(key) {
- var result = getMapData(this, key)['delete'](key);
- this.size -= result ? 1 : 0;
- return result;
-}
-
-module.exports = mapCacheDelete;
-
-
-/***/ }),
-/* 94 */
-/***/ (function(module, exports) {
-
-/**
- * Checks if `value` is suitable for use as unique object key.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
- */
-function isKeyable(value) {
- var type = typeof value;
- return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
- ? (value !== '__proto__')
- : (value === null);
-}
-
-module.exports = isKeyable;
-
-
-/***/ }),
-/* 95 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var getMapData = __webpack_require__(8);
-
-/**
- * Gets the map value for `key`.
- *
- * @private
- * @name get
- * @memberOf MapCache
- * @param {string} key The key of the value to get.
- * @returns {*} Returns the entry value.
- */
-function mapCacheGet(key) {
- return getMapData(this, key).get(key);
-}
-
-module.exports = mapCacheGet;
-
-
-/***/ }),
-/* 96 */
+/* 50 */
/***/ (function(module, exports, __webpack_require__) {
-var getMapData = __webpack_require__(8);
-
-/**
- * Checks if a map value for `key` exists.
- *
- * @private
- * @name has
- * @memberOf MapCache
- * @param {string} key The key of the entry to check.
- * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
- */
-function mapCacheHas(key) {
- return getMapData(this, key).has(key);
-}
-
-module.exports = mapCacheHas;
-
-
-/***/ }),
-/* 97 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var getMapData = __webpack_require__(8);
-
-/**
- * Sets the map `key` to `value`.
- *
- * @private
- * @name set
- * @memberOf MapCache
- * @param {string} key The key of the value to set.
- * @param {*} value The value to set.
- * @returns {Object} Returns the map cache instance.
- */
-function mapCacheSet(key, value) {
- var data = getMapData(this, key),
- size = data.size;
-
- data.set(key, value);
- this.size += data.size == size ? 0 : 1;
- return this;
-}
-
-module.exports = mapCacheSet;
-
-
-/***/ }),
-/* 98 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var baseToString = __webpack_require__(99);
-
-/**
- * Converts `value` to a string. An empty string is returned for `null`
- * and `undefined` values. The sign of `-0` is preserved.
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to convert.
- * @returns {string} Returns the converted string.
- * @example
- *
- * _.toString(null);
- * // => ''
- *
- * _.toString(-0);
- * // => '-0'
- *
- * _.toString([1, 2, 3]);
- * // => '1,2,3'
- */
-function toString(value) {
- return value == null ? '' : baseToString(value);
-}
-
-module.exports = toString;
-
-
-/***/ }),
-/* 99 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var Symbol = __webpack_require__(13),
- arrayMap = __webpack_require__(100),
- isArray = __webpack_require__(5),
- isSymbol = __webpack_require__(11);
-
-/** Used as references for various `Number` constants. */
-var INFINITY = 1 / 0;
-
-/** Used to convert symbols to primitives and strings. */
-var symbolProto = Symbol ? Symbol.prototype : undefined,
- symbolToString = symbolProto ? symbolProto.toString : undefined;
-
-/**
- * The base implementation of `_.toString` which doesn't convert nullish
- * values to empty strings.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {string} Returns the string.
- */
-function baseToString(value) {
- // Exit early for strings to avoid a performance hit in some environments.
- if (typeof value == 'string') {
- return value;
- }
- if (isArray(value)) {
- // Recursively convert values (susceptible to call stack limits).
- return arrayMap(value, baseToString) + '';
- }
- if (isSymbol(value)) {
- return symbolToString ? symbolToString.call(value) : '';
- }
- var result = (value + '');
- return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
-}
-
-module.exports = baseToString;
-
-
-/***/ }),
-/* 100 */
-/***/ (function(module, exports) {
-
-/**
- * A specialized version of `_.map` for arrays without support for iteratee
- * shorthands.
- *
- * @private
- * @param {Array} [array] The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns the new mapped array.
- */
-function arrayMap(array, iteratee) {
- var index = -1,
- length = array == null ? 0 : array.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = iteratee(array[index], index, array);
- }
- return result;
-}
-
-module.exports = arrayMap;
-
-
-/***/ }),
-/* 101 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var baseHas = __webpack_require__(102),
- hasPath = __webpack_require__(103);
-
-/**
- * Checks if `path` is a direct property of `object`.
- *
- * @static
- * @since 0.1.0
- * @memberOf _
- * @category Object
- * @param {Object} object The object to query.
- * @param {Array|string} path The path to check.
- * @returns {boolean} Returns `true` if `path` exists, else `false`.
- * @example
- *
- * var object = { 'a': { 'b': 2 } };
- * var other = _.create({ 'a': _.create({ 'b': 2 }) });
- *
- * _.has(object, 'a');
- * // => true
- *
- * _.has(object, 'a.b');
- * // => true
- *
- * _.has(object, ['a', 'b']);
- * // => true
- *
- * _.has(other, 'a');
- * // => false
- */
-function has(object, path) {
- return object != null && hasPath(object, path, baseHas);
-}
-
-module.exports = has;
-
-
-/***/ }),
-/* 102 */
-/***/ (function(module, exports) {
-
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/**
- * The base implementation of `_.has` without support for deep paths.
- *
- * @private
- * @param {Object} [object] The object to query.
- * @param {Array|string} key The key to check.
- * @returns {boolean} Returns `true` if `key` exists, else `false`.
- */
-function baseHas(object, key) {
- return object != null && hasOwnProperty.call(object, key);
-}
-
-module.exports = baseHas;
-
-
-/***/ }),
-/* 103 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var castPath = __webpack_require__(22),
- isArguments = __webpack_require__(104),
- isArray = __webpack_require__(5),
- isIndex = __webpack_require__(106),
- isLength = __webpack_require__(107),
- toKey = __webpack_require__(25);
-
-/**
- * Checks if `path` exists on `object`.
- *
- * @private
- * @param {Object} object The object to query.
- * @param {Array|string} path The path to check.
- * @param {Function} hasFunc The function to check properties.
- * @returns {boolean} Returns `true` if `path` exists, else `false`.
- */
-function hasPath(object, path, hasFunc) {
- path = castPath(path, object);
-
- var index = -1,
- length = path.length,
- result = false;
-
- while (++index < length) {
- var key = toKey(path[index]);
- if (!(result = object != null && hasFunc(object, key))) {
- break;
- }
- object = object[key];
- }
- if (result || ++index != length) {
- return result;
- }
- length = object == null ? 0 : object.length;
- return !!length && isLength(length) && isIndex(key, length) &&
- (isArray(object) || isArguments(object));
-}
-
-module.exports = hasPath;
-
-
-/***/ }),
-/* 104 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var baseIsArguments = __webpack_require__(105),
- isObjectLike = __webpack_require__(15);
-
-/** Used for built-in method references. */
-var objectProto = Object.prototype;
-
-/** Used to check objects for own properties. */
-var hasOwnProperty = objectProto.hasOwnProperty;
-
-/** Built-in value references. */
-var propertyIsEnumerable = objectProto.propertyIsEnumerable;
-
-/**
- * Checks if `value` is likely an `arguments` object.
- *
- * @static
- * @memberOf _
- * @since 0.1.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an `arguments` object,
- * else `false`.
- * @example
- *
- * _.isArguments(function() { return arguments; }());
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
-var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
- return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
- !propertyIsEnumerable.call(value, 'callee');
+"use strict";
+
+
+let enumIndexedProperties = (() => {
+ var _ref = _asyncToGenerator(function* (objectClient, start, end) {
+ const { iterator } = yield objectClient.enumProperties({ ignoreNonIndexedProperties: true });
+ const response = yield iteratorSlice(iterator, start, end);
+ return response;
+ });
+
+ return function enumIndexedProperties(_x, _x2, _x3) {
+ return _ref.apply(this, arguments);
+ };
+})(); /* 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/. */
+
+let enumNonIndexedProperties = (() => {
+ var _ref2 = _asyncToGenerator(function* (objectClient, start, end) {
+ const { iterator } = yield objectClient.enumProperties({ ignoreIndexedProperties: true });
+
+ const response = yield iteratorSlice(iterator, start, end);
+ return response;
+ });
+
+ return function enumNonIndexedProperties(_x4, _x5, _x6) {
+ return _ref2.apply(this, arguments);
+ };
+})();
+
+let enumEntries = (() => {
+ var _ref3 = _asyncToGenerator(function* (objectClient, start, end) {
+ const { iterator } = yield objectClient.enumEntries();
+ const response = yield iteratorSlice(iterator, start, end);
+ return response;
+ });
+
+ return function enumEntries(_x7, _x8, _x9) {
+ return _ref3.apply(this, arguments);
+ };
+})();
+
+let enumSymbols = (() => {
+ var _ref4 = _asyncToGenerator(function* (objectClient, start, end) {
+ const { iterator } = yield objectClient.enumSymbols();
+ const response = yield iteratorSlice(iterator, start, end);
+ return response;
+ });
+
+ return function enumSymbols(_x10, _x11, _x12) {
+ return _ref4.apply(this, arguments);
+ };
+})();
+
+function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
+
+function getPrototype(objectClient) {
+ return objectClient.getPrototype();
+}
+
+function iteratorSlice(iterator, start, end) {
+ start = start || 0;
+ const count = end ? end - start + 1 : iterator.count;
+ return iterator.slice(start, count);
+}
+
+module.exports = {
+ enumEntries,
+ enumIndexedProperties,
+ enumNonIndexedProperties,
+ enumSymbols,
+ getPrototype
};
-module.exports = isArguments;
-
-
-/***/ }),
-/* 105 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var baseGetTag = __webpack_require__(12),
- isObjectLike = __webpack_require__(15);
-
-/** `Object#toString` result references. */
-var argsTag = '[object Arguments]';
-
-/**
- * The base implementation of `_.isArguments`.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is an `arguments` object,
- */
-function baseIsArguments(value) {
- return isObjectLike(value) && baseGetTag(value) == argsTag;
-}
-
-module.exports = baseIsArguments;
-
-
-/***/ }),
-/* 106 */
-/***/ (function(module, exports) {
-
-/** Used as references for various `Number` constants. */
-var MAX_SAFE_INTEGER = 9007199254740991;
-
-/** Used to detect unsigned integer values. */
-var reIsUint = /^(?:0|[1-9]\d*)$/;
-
-/**
- * Checks if `value` is a valid array-like index.
- *
- * @private
- * @param {*} value The value to check.
- * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
- * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
- */
-function isIndex(value, length) {
- length = length == null ? MAX_SAFE_INTEGER : length;
- return !!length &&
- (typeof value == 'number' || reIsUint.test(value)) &&
- (value > -1 && value % 1 == 0 && value < length);
-}
-
-module.exports = isIndex;
-
-
-/***/ }),
-/* 107 */
-/***/ (function(module, exports) {
-
-/** Used as references for various `Number` constants. */
-var MAX_SAFE_INTEGER = 9007199254740991;
-
-/**
- * Checks if `value` is a valid array-like length.
- *
- * **Note:** This method is loosely based on
- * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
- *
- * @static
- * @memberOf _
- * @since 4.0.0
- * @category Lang
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
- * @example
- *
- * _.isLength(3);
- * // => true
- *
- * _.isLength(Number.MIN_VALUE);
- * // => false
- *
- * _.isLength(Infinity);
- * // => false
- *
- * _.isLength('3');
- * // => false
- */
-function isLength(value) {
- return typeof value == 'number' &&
- value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
-}
-
-module.exports = isLength;
-
-
/***/ })
/******/ ]);
});
\ No newline at end of file
--- a/devtools/client/webconsole/new-console-output/actions/messages.js
+++ b/devtools/client/webconsole/new-console-output/actions/messages.js
@@ -16,18 +16,16 @@ const {
MESSAGE_ADD,
NETWORK_MESSAGE_UPDATE,
NETWORK_UPDATE_REQUEST,
MESSAGES_CLEAR,
MESSAGE_OPEN,
MESSAGE_CLOSE,
MESSAGE_TYPE,
MESSAGE_TABLE_RECEIVE,
- MESSAGE_OBJECT_PROPERTIES_RECEIVE,
- MESSAGE_OBJECT_ENTRIES_RECEIVE,
} = require("../constants");
const defaultIdGenerator = new IdGenerator();
function messageAdd(packet, idGenerator = null) {
if (idGenerator == null) {
idGenerator = defaultIdGenerator;
}
@@ -112,89 +110,19 @@ function networkMessageUpdate(packet, id
function networkUpdateRequest(id, data) {
return {
type: NETWORK_UPDATE_REQUEST,
id,
data,
};
}
-/**
- * This action is used to load the properties of a grip passed as an argument,
- * for a given message. The action then dispatch the messageObjectPropertiesReceive
- * action with the loaded properties.
- * This action is mainly called by the ObjectInspector component when the user expands
- * an object.
- *
- * @param {string} id - The message id the grip is in.
- * @param {ObjectClient} client - The ObjectClient built for the grip.
- * @param {object} grip - The grip to load properties from.
- * @returns {async function} - A function that retrieves the properties
- * and dispatch the messageObjectPropertiesReceive action.
- */
-function messageObjectPropertiesLoad(id, client, grip) {
- return async (dispatch) => {
- const response = await client.getPrototypeAndProperties();
- dispatch(messageObjectPropertiesReceive(id, grip.actor, response));
- };
-}
-
-function messageObjectEntriesLoad(id, client, grip) {
- return (dispatch) => {
- client.enumEntries(enumResponse => {
- const {iterator} = enumResponse;
- iterator.slice(0, iterator.count, sliceResponse => {
- dispatch(messageObjectEntriesReceive(id, grip.actor, sliceResponse));
- });
- });
- };
-}
-
-/**
- * This action is dispatched when properties of a grip are loaded.
- *
- * @param {string} id - The message id the grip is in.
- * @param {string} actor - The actor id of the grip the properties were loaded from.
- * @param {object} properties - A RDP packet that contains the properties of the grip.
- * @returns {object}
- */
-function messageObjectPropertiesReceive(id, actor, properties) {
- return {
- type: MESSAGE_OBJECT_PROPERTIES_RECEIVE,
- id,
- actor,
- properties
- };
-}
-
-/**
- * This action is dispatched when entries of a grip are loaded.
- *
- * @param {string} id - The message id the grip is in.
- * @param {string} actor - The actor id of the grip the properties were loaded from.
- * @param {object} entries - A RDP packet that contains the entries of the grip.
- * @returns {object}
- */
-function messageObjectEntriesReceive(id, actor, entries) {
- return {
- type: MESSAGE_OBJECT_ENTRIES_RECEIVE,
- id,
- actor,
- entries
- };
-}
-
module.exports = {
messageAdd,
messagesClear,
messageOpen,
messageClose,
messageTableDataGet,
networkMessageUpdate,
networkUpdateRequest,
- messageObjectPropertiesLoad,
- messageObjectEntriesLoad,
// for test purpose only.
messageTableDataReceive,
- messageObjectPropertiesReceive,
- messageObjectEntriesReceive,
};
-
--- a/devtools/client/webconsole/new-console-output/components/console-output.js
+++ b/devtools/client/webconsole/new-console-output/components/console-output.js
@@ -10,18 +10,16 @@ const {
PropTypes
} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const {
getAllMessagesById,
getAllMessagesUiById,
getAllMessagesTableDataById,
- getAllMessagesObjectPropertiesById,
- getAllMessagesObjectEntriesById,
getAllNetworkMessagesUpdateById,
getVisibleMessages,
getAllRepeatById,
} = require("devtools/client/webconsole/new-console-output/selectors/messages");
const MessageContainer = createFactory(require("devtools/client/webconsole/new-console-output/components/message-container").MessageContainer);
const {
MESSAGE_TYPE,
} = require("devtools/client/webconsole/new-console-output/constants");
@@ -36,18 +34,16 @@ const ConsoleOutput = createClass({
serviceContainer: PropTypes.shape({
attachRefToHud: PropTypes.func.isRequired,
openContextMenu: PropTypes.func.isRequired,
sourceMapService: PropTypes.object,
}),
dispatch: PropTypes.func.isRequired,
timestampsVisible: PropTypes.bool,
messagesTableData: PropTypes.object.isRequired,
- messagesObjectProperties: PropTypes.object.isRequired,
- messagesObjectEntries: PropTypes.object.isRequired,
messagesRepeat: PropTypes.object.isRequired,
networkMessagesUpdate: PropTypes.object.isRequired,
visibleMessages: PropTypes.array.isRequired,
networkMessageActiveTabId: PropTypes.string.isRequired,
},
componentDidMount() {
// Do the scrolling in the nextTick since this could hit console startup performances.
@@ -94,18 +90,16 @@ const ConsoleOutput = createClass({
render() {
let {
dispatch,
visibleMessages,
messages,
messagesUi,
messagesTableData,
- messagesObjectProperties,
- messagesObjectEntries,
messagesRepeat,
networkMessagesUpdate,
networkMessageActiveTabId,
serviceContainer,
timestampsVisible,
} = this.props;
let messageNodes = visibleMessages.map((messageId) => MessageContainer({
@@ -115,18 +109,16 @@ const ConsoleOutput = createClass({
serviceContainer,
open: messagesUi.includes(messageId),
tableData: messagesTableData.get(messageId),
timestampsVisible,
repeat: messagesRepeat[messageId],
networkMessageUpdate: networkMessagesUpdate[messageId],
networkMessageActiveTabId,
getMessage: () => messages.get(messageId),
- loadedObjectProperties: messagesObjectProperties.get(messageId),
- loadedObjectEntries: messagesObjectEntries.get(messageId),
}));
return (
dom.div({
className: "webconsole-output",
onContextMenu: this.onContextMenu,
ref: node => {
this.outputNode = node;
@@ -149,18 +141,16 @@ function isScrolledToBottom(outputNode,
}
function mapStateToProps(state, props) {
return {
messages: getAllMessagesById(state),
visibleMessages: getVisibleMessages(state),
messagesUi: getAllMessagesUiById(state),
messagesTableData: getAllMessagesTableDataById(state),
- messagesObjectProperties: getAllMessagesObjectPropertiesById(state),
- messagesObjectEntries: getAllMessagesObjectEntriesById(state),
messagesRepeat: getAllRepeatById(state),
networkMessagesUpdate: getAllNetworkMessagesUpdateById(state),
timestampsVisible: state.ui.timestampsVisible,
networkMessageActiveTabId: state.ui.networkMessageActiveTabId,
};
}
module.exports = connect(mapStateToProps)(ConsoleOutput);
--- a/devtools/client/webconsole/new-console-output/components/console-table.js
+++ b/devtools/client/webconsole/new-console-output/components/console-table.js
@@ -21,30 +21,30 @@ const TABLE_COLUMN_MAX_ITEMS = 10;
const ConsoleTable = createClass({
displayName: "ConsoleTable",
propTypes: {
dispatch: PropTypes.func.isRequired,
parameters: PropTypes.array.isRequired,
serviceContainer: PropTypes.shape({
- hudProxyClient: PropTypes.object.isRequired,
+ hudProxy: PropTypes.object.isRequired,
}),
id: PropTypes.string.isRequired,
tableData: PropTypes.object,
},
componentWillMount: function () {
const {id, dispatch, serviceContainer, parameters} = this.props;
if (!Array.isArray(parameters) || parameters.length === 0) {
return;
}
- const client = new ObjectClient(serviceContainer.hudProxyClient, parameters[0]);
+ const client = new ObjectClient(serviceContainer.hudProxy.client, parameters[0]);
let dataType = getParametersDataType(parameters);
// Get all the object properties.
dispatch(actions.messageTableDataGet(id, client, dataType));
},
getHeaders: function (columns) {
let headerItems = [];
--- a/devtools/client/webconsole/new-console-output/components/grip-message-body.js
+++ b/devtools/client/webconsole/new-console-output/components/grip-message-body.js
@@ -18,59 +18,52 @@ const {
PropTypes,
} = require("devtools/client/shared/vendor/react");
const { ObjectClient } = require("devtools/shared/client/main");
const {
MESSAGE_TYPE,
JSTERM_COMMANDS,
} = require("../constants");
-const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
const reps = require("devtools/client/shared/components/reps/reps");
const { REPS, MODE } = reps;
const ObjectInspector = createFactory(reps.ObjectInspector);
const { Grip } = REPS;
GripMessageBody.displayName = "GripMessageBody";
GripMessageBody.propTypes = {
grip: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.object,
]).isRequired,
serviceContainer: PropTypes.shape({
createElement: PropTypes.func.isRequired,
- hudProxyClient: PropTypes.object.isRequired,
+ hudProxy: PropTypes.object.isRequired,
}),
userProvidedStyle: PropTypes.string,
useQuotes: PropTypes.bool,
escapeWhitespace: PropTypes.bool,
- loadedObjectProperties: PropTypes.object,
- loadedObjectEntries: PropTypes.object,
type: PropTypes.string,
helperType: PropTypes.string,
};
GripMessageBody.defaultProps = {
mode: MODE.LONG,
};
function GripMessageBody(props) {
const {
- dispatch,
- messageId,
grip,
userProvidedStyle,
serviceContainer,
useQuotes,
escapeWhitespace,
mode = MODE.LONG,
- loadedObjectProperties,
- loadedObjectEntries,
} = props;
let styleObject;
if (userProvidedStyle && userProvidedStyle !== "") {
styleObject = cleanupStyle(userProvidedStyle, serviceContainer.createElement);
}
let onDOMNodeMouseOver;
@@ -98,25 +91,23 @@ function GripMessageBody(props) {
// Let's remove the property below when problem are fixed in OI.
disabledFocus: true,
roots: [{
path: (grip && grip.actor) || JSON.stringify(grip),
contents: {
value: grip
}
}],
- getObjectProperties: actor => loadedObjectProperties && loadedObjectProperties[actor],
- loadObjectProperties: object => {
- const client = new ObjectClient(serviceContainer.hudProxyClient, object);
- dispatch(actions.messageObjectPropertiesLoad(messageId, client, object));
- },
- getObjectEntries: actor => loadedObjectEntries && loadedObjectEntries[actor],
- loadObjectEntries: object => {
- const client = new ObjectClient(serviceContainer.hudProxyClient, object);
- dispatch(actions.messageObjectEntriesLoad(messageId, client, object));
+ createObjectClient: object =>
+ new ObjectClient(serviceContainer.hudProxy.client, object),
+ releaseActor: actor => {
+ if (!actor || !serviceContainer.hudProxy.releaseActor) {
+ return;
+ }
+ serviceContainer.hudProxy.releaseActor(actor);
},
openLink: serviceContainer.openLink,
};
if (typeof grip === "string" || (grip && grip.type === "longString")) {
Object.assign(objectInspectorProps, {
useQuotes,
escapeWhitespace,
--- a/devtools/client/webconsole/new-console-output/components/message-container.js
+++ b/devtools/client/webconsole/new-console-output/components/message-container.js
@@ -33,46 +33,38 @@ const MessageContainer = createClass({
messageId: PropTypes.string.isRequired,
open: PropTypes.bool.isRequired,
serviceContainer: PropTypes.object.isRequired,
tableData: PropTypes.object,
timestampsVisible: PropTypes.bool.isRequired,
repeat: PropTypes.number,
networkMessageUpdate: PropTypes.object,
getMessage: PropTypes.func.isRequired,
- loadedObjectProperties: PropTypes.object,
- loadedObjectEntries: PropTypes.object,
},
getDefaultProps: function () {
return {
open: false,
};
},
shouldComponentUpdate(nextProps, nextState) {
const repeatChanged = this.props.repeat !== nextProps.repeat;
const openChanged = this.props.open !== nextProps.open;
const tableDataChanged = this.props.tableData !== nextProps.tableData;
const timestampVisibleChanged =
this.props.timestampsVisible !== nextProps.timestampsVisible;
const networkMessageUpdateChanged =
this.props.networkMessageUpdate !== nextProps.networkMessageUpdate;
- const loadedObjectPropertiesChanged =
- this.props.loadedObjectProperties !== nextProps.loadedObjectProperties;
- const loadedObjectEntriesChanged =
- this.props.loadedObjectEntries !== nextProps.loadedObjectEntries;
return repeatChanged
|| openChanged
|| tableDataChanged
|| timestampVisibleChanged
- || networkMessageUpdateChanged
- || loadedObjectPropertiesChanged
- || loadedObjectEntriesChanged;
+ || networkMessageUpdateChanged;
},
render() {
const message = this.props.getMessage();
let MessageComponent = getMessageComponent(message);
return MessageComponent(Object.assign({message}, this.props));
}
--- a/devtools/client/webconsole/new-console-output/components/message-types/console-api-call.js
+++ b/devtools/client/webconsole/new-console-output/components/message-types/console-api-call.js
@@ -21,35 +21,31 @@ const Message = createFactory(require("d
ConsoleApiCall.displayName = "ConsoleApiCall";
ConsoleApiCall.propTypes = {
dispatch: PropTypes.func.isRequired,
message: PropTypes.object.isRequired,
open: PropTypes.bool,
serviceContainer: PropTypes.object.isRequired,
timestampsVisible: PropTypes.bool.isRequired,
- loadedObjectProperties: PropTypes.object,
- loadedObjectEntries: PropTypes.object,
};
ConsoleApiCall.defaultProps = {
open: false,
};
function ConsoleApiCall(props) {
const {
dispatch,
message,
open,
tableData,
serviceContainer,
timestampsVisible,
repeat,
- loadedObjectProperties,
- loadedObjectEntries,
} = props;
const {
id: messageId,
indent,
source,
type,
level,
stacktrace,
@@ -58,18 +54,16 @@ function ConsoleApiCall(props) {
parameters,
messageText,
userProvidedStyles,
} = message;
let messageBody;
const messageBodyConfig = {
dispatch,
- loadedObjectProperties,
- loadedObjectEntries,
messageId,
parameters,
userProvidedStyles,
serviceContainer,
type,
};
if (type === "trace") {
--- a/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js
+++ b/devtools/client/webconsole/new-console-output/components/message-types/evaluation-result.js
@@ -16,28 +16,24 @@ const GripMessageBody = require("devtool
EvaluationResult.displayName = "EvaluationResult";
EvaluationResult.propTypes = {
dispatch: PropTypes.func.isRequired,
message: PropTypes.object.isRequired,
timestampsVisible: PropTypes.bool.isRequired,
serviceContainer: PropTypes.object,
- loadedObjectProperties: PropTypes.object,
- loadedObjectEntries: PropTypes.object,
};
function EvaluationResult(props) {
const {
dispatch,
message,
serviceContainer,
timestampsVisible,
- loadedObjectProperties,
- loadedObjectEntries,
} = props;
const {
source,
type,
helperType,
level,
id: messageId,
@@ -62,18 +58,16 @@ function EvaluationResult(props) {
} else {
messageBody = GripMessageBody({
dispatch,
messageId,
grip: parameters,
serviceContainer,
useQuotes: true,
escapeWhitespace: false,
- loadedObjectProperties,
- loadedObjectEntries,
type,
helperType,
});
}
const topLevelClasses = ["cm-s-mozilla"];
return Message({
--- a/devtools/client/webconsole/new-console-output/constants.js
+++ b/devtools/client/webconsole/new-console-output/constants.js
@@ -9,18 +9,16 @@ const actionTypes = {
BATCH_ACTIONS: "BATCH_ACTIONS",
MESSAGE_ADD: "MESSAGE_ADD",
MESSAGES_CLEAR: "MESSAGES_CLEAR",
MESSAGE_OPEN: "MESSAGE_OPEN",
MESSAGE_CLOSE: "MESSAGE_CLOSE",
NETWORK_MESSAGE_UPDATE: "NETWORK_MESSAGE_UPDATE",
NETWORK_UPDATE_REQUEST: "NETWORK_UPDATE_REQUEST",
MESSAGE_TABLE_RECEIVE: "MESSAGE_TABLE_RECEIVE",
- MESSAGE_OBJECT_PROPERTIES_RECEIVE: "MESSAGE_OBJECT_PROPERTIES_RECEIVE",
- MESSAGE_OBJECT_ENTRIES_RECEIVE: "MESSAGE_OBJECT_ENTRIES_RECEIVE",
REMOVED_ACTORS_CLEAR: "REMOVED_ACTORS_CLEAR",
TIMESTAMPS_TOGGLE: "TIMESTAMPS_TOGGLE",
FILTER_TOGGLE: "FILTER_TOGGLE",
FILTER_TEXT_SET: "FILTER_TEXT_SET",
FILTERS_CLEAR: "FILTERS_CLEAR",
DEFAULT_FILTERS_RESET: "DEFAULT_FILTERS_RESET",
FILTER_BAR_TOGGLE: "FILTER_BAR_TOGGLE",
SELECT_NETWORK_MESSAGE_TAB: "SELECT_NETWORK_MESSAGE_TAB",
--- a/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
+++ b/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
@@ -74,17 +74,17 @@ NewConsoleOutputWrapper.prototype = {
const serviceContainer = {
attachRefToHud,
emitNewMessage: (node, messageId) => {
this.jsterm.hud.emit("new-messages", new Set([{
node,
messageId,
}]));
},
- hudProxyClient: this.jsterm.hud.proxy.client,
+ hudProxy: this.jsterm.hud.proxy,
openLink: url => {
this.jsterm.hud.owner.openLink(url);
},
createElement: nodename => {
return this.document.createElementNS("http://www.w3.org/1999/xhtml", nodename);
},
};
--- a/devtools/client/webconsole/new-console-output/reducers/messages.js
+++ b/devtools/client/webconsole/new-console-output/reducers/messages.js
@@ -33,26 +33,16 @@ const MessageState = Immutable.Record({
visibleMessages: [],
// Object for the filtered messages.
filteredMessagesCount: getDefaultFiltersCounter(),
// List of the message ids which are opened.
messagesUiById: Immutable.List(),
// Map of the form {messageId : tableData}, which represent the data passed
// as an argument in console.table calls.
messagesTableDataById: Immutable.Map(),
- // Map of the form {messageId : {[actor]: properties}}, where `properties` is
- // a RDP packet containing the properties of the ${actor} grip.
- // This map is consumed by the ObjectInspector so we only load properties once,
- // when needed (when an ObjectInspector node is expanded), and then caches them.
- messagesObjectPropertiesById: Immutable.Map(),
- // Map of the form {messageId : {[actor]: entries}}, where `entries` is
- // a RDP packet containing the entries of the ${actor} grip.
- // This map is consumed by the ObjectInspector so we only load entries once,
- // when needed (when an ObjectInspector node is expanded), and then caches them.
- messagesObjectEntriesById: Immutable.Map(),
// Map of the form {groupMessageId : groupArray},
// where groupArray is the list of of all the parent groups' ids of the groupMessageId.
groupsById: Immutable.Map(),
// Message id of the current group (no corresponding console.groupEnd yet).
currentGroup: null,
// Array of removed actors (i.e. actors logged in removed messages) we keep track of
// in order to properly release them.
// This array is not supposed to be consumed by any UI component.
@@ -64,18 +54,16 @@ const MessageState = Immutable.Record({
networkMessagesUpdateById: {},
});
function messages(state = new MessageState(), action, filtersState, prefsState) {
const {
messagesById,
messagesUiById,
messagesTableDataById,
- messagesObjectPropertiesById,
- messagesObjectEntriesById,
networkMessagesUpdateById,
groupsById,
currentGroup,
repeatById,
visibleMessages,
filteredMessagesCount,
} = state;
@@ -237,37 +225,16 @@ function messages(state = new MessageSta
);
}
});
case constants.MESSAGE_TABLE_RECEIVE:
const {id, data} = action;
return state.set("messagesTableDataById", messagesTableDataById.set(id, data));
- case constants.MESSAGE_OBJECT_PROPERTIES_RECEIVE:
- return state.set(
- "messagesObjectPropertiesById",
- messagesObjectPropertiesById.set(
- action.id,
- Object.assign({
- [action.actor]: action.properties
- }, messagesObjectPropertiesById.get(action.id))
- )
- );
- case constants.MESSAGE_OBJECT_ENTRIES_RECEIVE:
- return state.set(
- "messagesObjectEntriesById",
- messagesObjectEntriesById.set(
- action.id,
- Object.assign({
- [action.actor]: action.entries
- }, messagesObjectEntriesById.get(action.id))
- )
- );
-
case constants.NETWORK_MESSAGE_UPDATE:
return state.set(
"networkMessagesUpdateById",
Object.assign({}, networkMessagesUpdateById, {
[action.message.id]: action.message
})
);
@@ -452,40 +419,30 @@ function limitTopLevelMessageCount(state
}
if (mapHasRemovedIdKey(record.messagesTableDataById)) {
record.set("messagesTableDataById",
record.messagesTableDataById.withMutations(cleanUpCollection));
}
if (mapHasRemovedIdKey(record.groupsById)) {
record.set("groupsById", record.groupsById.withMutations(cleanUpCollection));
}
- if (mapHasRemovedIdKey(record.messagesObjectPropertiesById)) {
- record.set("messagesObjectPropertiesById",
- record.messagesObjectPropertiesById.withMutations(cleanUpCollection));
- }
- if (mapHasRemovedIdKey(record.messagesObjectEntriesById)) {
- record.set("messagesObjectEntriesById",
- record.messagesObjectEntriesById.withMutations(cleanUpCollection));
- }
if (objectHasRemovedIdKey(record.repeatById)) {
record.set("repeatById", cleanUpObject(record.repeatById));
}
if (objectHasRemovedIdKey(record.networkMessagesUpdateById)) {
record.set("networkMessagesUpdateById",
cleanUpObject(record.networkMessagesUpdateById));
}
return record;
}
/**
* Get an array of all the actors logged in a specific message.
- * This could be directly the actors representing the arguments of a console.log call
- * as well as all the properties that where expanded using the object inspector.
*
* @param {Message} message: The message to get actors from.
* @param {Record} state: The redux state.
* @return {Array} An array containing all the actors logged in a message.
*/
function getAllActorsInMessage(message, state) {
// Messages without argument cannot be associated with backend actors.
if (!message || !Array.isArray(message.parameters) || message.parameters.length === 0) {
@@ -494,26 +451,16 @@ function getAllActorsInMessage(message,
const actors = [...message.parameters.reduce((res, parameter) => {
if (parameter.actor) {
res.push(parameter.actor);
}
return res;
}, [])];
- const loadedProperties = state.messagesObjectPropertiesById.get(message.id);
- if (loadedProperties) {
- actors.push(...Object.keys(loadedProperties));
- }
-
- const loadedEntries = state.messagesObjectEntriesById.get(message.id);
- if (loadedEntries) {
- actors.push(...Object.keys(loadedEntries));
- }
-
return actors;
}
/**
* Returns total count of top level messages (those which are not
* within a group).
*/
function getToplevelMessageCount(record) {
--- a/devtools/client/webconsole/new-console-output/selectors/messages.js
+++ b/devtools/client/webconsole/new-console-output/selectors/messages.js
@@ -16,24 +16,16 @@ function getMessage(state, id) {
function getAllMessagesUiById(state) {
return state.messages.messagesUiById;
}
function getAllMessagesTableDataById(state) {
return state.messages.messagesTableDataById;
}
-function getAllMessagesObjectPropertiesById(state) {
- return state.messages.messagesObjectPropertiesById;
-}
-
-function getAllMessagesObjectEntriesById(state) {
- return state.messages.messagesObjectEntriesById;
-}
-
function getAllGroupsById(state) {
return state.messages.groupsById;
}
function getCurrentGroup(state) {
return state.messages.currentGroup;
}
@@ -59,11 +51,9 @@ module.exports = {
getAllMessagesUiById,
getAllMessagesTableDataById,
getAllGroupsById,
getCurrentGroup,
getVisibleMessages,
getFilteredMessagesCount,
getAllRepeatById,
getAllNetworkMessagesUpdateById,
- getAllMessagesObjectPropertiesById,
- getAllMessagesObjectEntriesById,
};
--- a/devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer.js
+++ b/devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer.js
@@ -1,17 +1,20 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
module.exports = {
attachRefToHud: () => {},
emitNewMessage: () => {},
- hudProxyClient: {},
+ hudProxy: {
+ client: {},
+ releaseActor: actor => console.log("Release actor", actor),
+ },
onViewSourceInDebugger: () => {},
onViewSourceInStyleEditor: () => {},
onViewSourceInScratchpad: () => {},
openNetworkPanel: () => {},
sourceMapService: {
subscribe: () => {},
originalPositionFor: () => {
return new Promise(resolve => {
--- a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js
+++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js
@@ -13,16 +13,17 @@
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
this);
Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", true);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.webconsole.new-frontend-enabled");
});
+const { PREFS } = require("devtools/client/webconsole/new-console-output/constants");
const { prepareMessage } = require("devtools/client/webconsole/new-console-output/utils/messages");
const { stubPackets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js");
const {
consoleApi,
cssMessage,
evaluationResult,
networkEvent,
@@ -283,16 +284,19 @@ module.exports = {
stubPackets,
};
`;
}
function* generateConsoleApiStubs() {
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html";
+ // Hiding log messages so we don't get unwanted client/server communication.
+ Services.prefs.setBoolPref(PREFS.FILTER.LOG, false);
+
let stubs = {
preparedMessages: [],
packets: [],
};
let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole");
const hud = toolbox.getCurrentPanel().hud;
let {ui} = hud;
@@ -325,16 +329,18 @@ function* generateConsoleApiStubs() {
content.wrappedJSObject.triggerPacket();
script.remove();
}
);
yield received;
}
+ Services.prefs.clearUserPref(PREFS.FILTER.LOG);
+
yield closeTabAndToolbox();
return formatFile(stubs, "ConsoleMessage");
}
function* generateCssMessageStubs() {
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-css-message.html";
let stubs = {
--- a/devtools/client/webconsole/new-console-output/test/store/messages.test.js
+++ b/devtools/client/webconsole/new-console-output/test/store/messages.test.js
@@ -6,18 +6,16 @@ const {
getAllGroupsById,
getAllMessagesById,
getAllMessagesTableDataById,
getAllMessagesUiById,
getAllNetworkMessagesUpdateById,
getAllRepeatById,
getCurrentGroup,
getVisibleMessages,
- getAllMessagesObjectPropertiesById,
- getAllMessagesObjectEntriesById,
} = require("devtools/client/webconsole/new-console-output/selectors/messages");
const {
clonePacket,
getMessageAt,
setupActions,
setupStore,
} = require("devtools/client/webconsole/new-console-output/test/helpers");
const { stubPackets, stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
@@ -754,216 +752,9 @@ describe("Message reducer:", () => {
expect(table.get(id2)).toBe(tableData2);
// This addition will remove the second table message.
dispatch(actions.messageAdd(stubPackets.get("console.log('foobar', 'test')")));
expect(getAllMessagesTableDataById(getState()).size).toBe(0);
});
});
-
- describe("messagesObjectPropertiesById", () => {
- it(`adds messagesObjectPropertiesById data in response to
- MESSAGE_OBJECT_PROPERTIES_RECEIVE action`, () => {
- const { dispatch, getState } = setupStore([]);
-
- // Add 2 log messages with loaded object properties.
- dispatch(actions.messageAdd(