Merge mozilla-central to inbound. a=merge CLOSED TREE

This commit is contained in:
Tiberius Oros 2018-03-21 12:10:46 +02:00
Родитель f7522ae728 649398dfd9
Коммит e66ec58abf
242 изменённых файлов: 2526 добавлений и 1493 удалений

Просмотреть файл

@ -156,7 +156,7 @@ devtools/shared/webconsole/test/test_*.html
# Ignore devtools preferences files
devtools/client/preferences/**
devtools/shim/devtools-startup-prefs.js
devtools/startup/devtools-startup-prefs.js
# Ignore devtools third-party libs
devtools/shared/jsbeautify/*

Просмотреть файл

@ -15,7 +15,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
LoginManagerContextMenu: "resource://gre/modules/LoginManagerContextMenu.jsm",
WebNavigationFrames: "resource://gre/modules/WebNavigationFrames.jsm",
ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
DevToolsShim: "chrome://devtools-shim/content/DevToolsShim.jsm",
DevToolsShim: "chrome://devtools-startup/content/DevToolsShim.jsm",
NetUtil: "resource://gre/modules/NetUtil.jsm",
});

Просмотреть файл

@ -1,5 +1,5 @@
add_task(async function() {
let browserLoadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
let browserLoadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, "about:mozilla");
window.browserDOMWindow.openURI(makeURI("about:mozilla"), null,
Ci.nsIBrowserDOMWindow.OPEN_CURRENTWINDOW, null,
Services.scriptSecurityManager.getSystemPrincipal());

Просмотреть файл

@ -14,7 +14,7 @@
*/
ChromeUtils.defineModuleGetter(this, "DevToolsShim",
"chrome://devtools-shim/content/DevToolsShim.jsm");
"chrome://devtools-startup/content/DevToolsShim.jsm");
ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm");

Просмотреть файл

@ -9,6 +9,9 @@ var gSearchResultsPane = {
listSearchTooltips: new Set(),
listSearchMenuitemIndicators: new Set(),
searchInput: null,
// A map of DOM Elements to a string of keywords used in search
// XXX: We should invalidate this cache on `intl:app-locales-changed`
searchKeywords: new WeakMap(),
inited: false,
init() {
@ -221,7 +224,8 @@ var gSearchResultsPane = {
}
let srHeader = document.getElementById("header-searchResults");
let noResultsEl = document.getElementById("no-results-message");
srHeader.hidden = !this.query;
if (this.query) {
// Showing the Search Results Tag
gotoPref("paneSearchResults");
@ -229,75 +233,66 @@ var gSearchResultsPane = {
let resultsFound = false;
// Building the range for highlighted areas
let rootPreferencesChildren = document
.querySelectorAll("#mainPrefPane > *:not([data-hidden-from-search])");
// Show all second level headers in search result
for (let element of document.querySelectorAll("caption.search-header")) {
element.hidden = false;
}
let rootPreferencesChildren = [...document
.querySelectorAll("#mainPrefPane > *:not([data-hidden-from-search])")];
if (subQuery) {
// Since the previous query is a subset of the current query,
// there is no need to check elements that is hidden already.
rootPreferencesChildren =
Array.prototype.filter.call(rootPreferencesChildren, el => !el.hidden);
rootPreferencesChildren = rootPreferencesChildren.filter(el => !el.hidden);
}
// Mark all the children to check be visible to bind JS, Access Keys, etc,
// but don't really show them by setting their visibility to hidden in CSS.
for (let i = 0; i < rootPreferencesChildren.length; i++) {
rootPreferencesChildren[i].hidden = false;
rootPreferencesChildren[i].classList.add("visually-hidden");
for (let child of rootPreferencesChildren) {
child.classList.add("visually-hidden");
child.hidden = false;
}
let ts = performance.now();
let FRAME_THRESHOLD = 1000 / 60;
// Showing or Hiding specific section depending on if words in query are found
for (let i = 0; i < rootPreferencesChildren.length; i++) {
for (let child of rootPreferencesChildren) {
if (performance.now() - ts > FRAME_THRESHOLD) {
// Creating tooltips for all the instances found
for (let anchorNode of this.listSearchTooltips) {
this.createSearchTooltip(anchorNode, this.query);
}
// It hides Search Results header so turning it on
srHeader.hidden = false;
srHeader.classList.remove("visually-hidden");
ts = await new Promise(resolve => window.requestAnimationFrame(resolve));
if (query !== this.query) {
return;
}
}
rootPreferencesChildren[i].classList.remove("visually-hidden");
if (!rootPreferencesChildren[i].classList.contains("header") &&
!rootPreferencesChildren[i].classList.contains("subcategory") &&
!rootPreferencesChildren[i].classList.contains("no-results-message") &&
this.searchWithinNode(rootPreferencesChildren[i], this.query)) {
rootPreferencesChildren[i].hidden = false;
if (!child.classList.contains("header") &&
!child.classList.contains("subcategory") &&
await this.searchWithinNode(child, this.query)) {
child.hidden = false;
child.classList.remove("visually-hidden");
// Show the preceding search-header if one exists.
let groupbox = child.closest("groupbox");
let groupHeader = groupbox && groupbox.querySelector(".search-header");
if (groupHeader) {
groupHeader.hidden = false;
}
resultsFound = true;
} else {
rootPreferencesChildren[i].hidden = true;
child.hidden = true;
}
}
// It hides Search Results header so turning it on
srHeader.hidden = false;
srHeader.classList.remove("visually-hidden");
if (!resultsFound) {
let noResultsEl = document.querySelector(".no-results-message");
noResultsEl.setAttribute("query", this.query);
// XXX: This is potentially racy in case where Fluent retranslates the
// message and ereases the query within.
// The feature is not yet supported, but we should fix for it before
// we enable it. See bug 1446389 for details.
let msgQueryElem = document.getElementById("sorry-message-query");
msgQueryElem.textContent = this.query;
noResultsEl.hidden = false;
} else {
noResultsEl.hidden = !!resultsFound;
noResultsEl.setAttribute("query", this.query);
// XXX: This is potentially racy in case where Fluent retranslates the
// message and ereases the query within.
// The feature is not yet supported, but we should fix for it before
// we enable it. See bug 1446389 for details.
let msgQueryElem = document.getElementById("sorry-message-query");
msgQueryElem.textContent = this.query;
if (resultsFound) {
// Creating tooltips for all the instances found
for (let anchorNode of this.listSearchTooltips) {
this.createSearchTooltip(anchorNode, this.query);
@ -311,7 +306,8 @@ var gSearchResultsPane = {
}
}
} else {
document.getElementById("sorry-message").textContent = "";
noResultsEl.hidden = true;
document.getElementById("sorry-message-query").textContent = "";
// Going back to General when cleared
gotoPref("paneGeneral");
@ -334,7 +330,7 @@ var gSearchResultsPane = {
* @returns boolean
* Returns true when found in at least one childNode, false otherwise
*/
searchWithinNode(nodeObject, searchPhrase) {
async searchWithinNode(nodeObject, searchPhrase) {
let matchesFound = false;
if (nodeObject.childElementCount == 0 ||
nodeObject.tagName == "label" ||
@ -373,8 +369,20 @@ var gSearchResultsPane = {
let valueResult = nodeObject.tagName !== "menuitem" ?
this.queryMatchesContent(nodeObject.getAttribute("value"), searchPhrase) : false;
// Searching some elements, such as xul:button, buttons to open subdialogs.
let keywordsResult = this.queryMatchesContent(nodeObject.getAttribute("searchkeywords"), searchPhrase);
// Searching some elements, such as xul:button, buttons to open subdialogs
// using l10n ids.
let keywordsResult =
nodeObject.hasAttribute("search-l10n-ids") &&
await this.matchesSearchL10nIDs(nodeObject, searchPhrase);
if (!keywordsResult) {
// Searching some elements, such as xul:button, buttons to open subdialogs
// using searchkeywords attribute.
keywordsResult =
!keywordsResult &&
nodeObject.hasAttribute("searchkeywords") &&
this.queryMatchesContent(nodeObject.getAttribute("searchkeywords"), searchPhrase);
}
// Creating tooltips for buttons
if (keywordsResult && (nodeObject.tagName === "button" || nodeObject.tagName == "menulist")) {
@ -405,12 +413,12 @@ var gSearchResultsPane = {
if (nodeObject.tagName == "deck" && nodeObject.id != "historyPane") {
let index = nodeObject.selectedIndex;
if (index != -1) {
let result = this.searchChildNodeIfVisible(nodeObject, index, searchPhrase);
let result = await this.searchChildNodeIfVisible(nodeObject, index, searchPhrase);
matchesFound = matchesFound || result;
}
} else {
for (let i = 0; i < nodeObject.childNodes.length; i++) {
let result = this.searchChildNodeIfVisible(nodeObject, i, searchPhrase);
let result = await this.searchChildNodeIfVisible(nodeObject, i, searchPhrase);
matchesFound = matchesFound || result;
}
}
@ -428,10 +436,10 @@ var gSearchResultsPane = {
* @returns boolean
* Returns true when found the specific childNode, false otherwise
*/
searchChildNodeIfVisible(nodeObject, index, searchPhrase) {
async searchChildNodeIfVisible(nodeObject, index, searchPhrase) {
let result = false;
if (!nodeObject.childNodes[index].hidden && nodeObject.getAttribute("data-hidden-from-search") !== "true") {
result = this.searchWithinNode(nodeObject.childNodes[index], searchPhrase);
result = await this.searchWithinNode(nodeObject.childNodes[index], searchPhrase);
// Creating tooltips for menulist element
if (result && nodeObject.tagName === "menulist") {
this.listSearchTooltips.add(nodeObject);
@ -440,6 +448,56 @@ var gSearchResultsPane = {
return result;
},
/**
* Search for a phrase in l10n messages associated with the element.
*
* @param Node nodeObject
* The parent DOM Element
* @param String searchPhrase
* @returns boolean
* true when the text content contains the query string else false
*/
async matchesSearchL10nIDs(nodeObject, searchPhrase) {
if (!this.searchKeywords.has(nodeObject)) {
// The `search-l10n-ids` attribute is a comma-separated list of
// l10n ids. It may also uses a dot notation to specify an attribute
// of the message to be used.
//
// Example: "containers-add-button.label, user-context-personal"
//
// The result is an array of arrays of l10n ids and optionally attribute names.
//
// Example: [["containers-add-button", "label"], ["user-context-personal"]]
const refs = nodeObject.getAttribute("search-l10n-ids")
.split(",")
.map(s => s.trim().split(".")).filter(s => s[0].length > 0);
const messages = await document.l10n.formatMessages(refs.map(ref => [ref[0]]));
// Map the localized messages taking value or a selected attribute and
// building a string of concatenated translated strings out of it.
let keywords = messages.map((msg, i) => {
if (msg === null) {
console.warn(`Missing search l10n id "${refs[i][0]}"`);
return null;
}
if (refs[i][1]) {
let attr = msg.attrs.find(a => a.name === refs[i][1]);
if (attr) {
return attr.value;
}
return null;
}
return msg.value;
}).filter(keyword => keyword !== null).join(" ");
this.searchKeywords.set(nodeObject, keywords);
return this.queryMatchesContent(keywords, searchPhrase);
}
return this.queryMatchesContent(this.searchKeywords.get(nodeObject), searchPhrase);
},
/**
* Inserting a div structure infront of the DOM element matched textContent.
* Then calculation the offsets to position the tooltip in the correct place.

Просмотреть файл

@ -5,11 +5,15 @@
<hbox id="header-searchResults"
class="subcategory"
hidden="true"
data-hidden-from-search="true"
data-category="paneSearchResults">
<label class="header-name" flex="1" data-l10n-id="search-results-header" />
</hbox>
<groupbox class="no-results-message" data-category="paneSearchResults" hidden="true">
<groupbox id="no-results-message"
data-hidden-from-search="true"
data-category="paneSearchResults"
hidden="true">
<vbox class="no-results-container">
<label id="sorry-message" data-l10n-id="search-results-sorry-message">
<html:span id="sorry-message-query"/>

Просмотреть файл

@ -8,7 +8,7 @@ requestLongerTimeout(6);
/**
* Tests to see if search bar is being shown when pref is turned on
*/
add_task(async function() {
add_task(async function show_search_bar_when_pref_is_enabled() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", { leaveOpen: true });
let searchInput = gBrowser.contentDocument.getElementById("searchInput");
is_element_visible(searchInput, "Search box should be shown");
@ -20,7 +20,7 @@ add_task(async function() {
* After it runs a search, it tests if the "Search Results" panel is the only selected category.
* The search is then cleared, it then tests if the "General" panel is the only selected category.
*/
add_task(async function() {
add_task(async function show_search_results_pane_only_then_revert_to_general() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", { leaveOpen: true });
// Performs search
@ -66,7 +66,7 @@ add_task(async function() {
/**
* Test for "password" case. When we search "password", it should show the "passwordGroup"
*/
add_task(async function() {
add_task(async function search_for_password_show_passwordGroup() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", { leaveOpen: true });
// Performs search
@ -138,10 +138,11 @@ add_task(async function() {
/**
* Test for if nothing is found
*/
add_task(async function() {
add_task(async function search_with_nothing_found() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", { leaveOpen: true });
let noResultsEl = gBrowser.contentDocument.querySelector(".no-results-message");
let noResultsEl = gBrowser.contentDocument.querySelector("#no-results-message");
let sorryMsgQueryEl = gBrowser.contentDocument.getElementById("sorry-message-query");
is_element_hidden(noResultsEl, "Should not be in search results yet");
@ -158,6 +159,7 @@ add_task(async function() {
await searchCompletedPromise;
is_element_visible(noResultsEl, "Should be in search results");
is(sorryMsgQueryEl.textContent, query, "sorry-message-query should contain the query");
// Takes search off
searchCompletedPromise = BrowserTestUtils.waitForEvent(
@ -169,6 +171,7 @@ add_task(async function() {
await searchCompletedPromise;
is_element_hidden(noResultsEl, "Should not be in search results");
is(sorryMsgQueryEl.textContent.length, 0, "sorry-message-query should be empty");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
@ -176,7 +179,7 @@ add_task(async function() {
/**
* Test for if we go back to general tab after search case
*/
add_task(async function() {
add_task(async function exiting_search_reverts_to_general_pane() {
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
let generalPane = gBrowser.contentDocument.getElementById("generalCategory");
@ -213,7 +216,7 @@ add_task(async function() {
* Test for "Site Data" case, verifying elements with data-hidden-from-search = true
* are hidden in search result.
*/
add_task(async function() {
add_task(async function verify_hidden_from_search_elements_dont_show_up() {
await SpecialPowers.pushPrefEnv({ "set": [["browser.storageManager.enabled", false]] });
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
let generalPane = gBrowser.contentDocument.getElementById("generalCategory");
@ -255,7 +258,7 @@ add_task(async function() {
/**
* Test for if we go to another tab after searching
*/
add_task(async function() {
add_task(async function changing_tabs_after_searching() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", { leaveOpen: true });
let searchInput = gBrowser.contentDocument.getElementById("searchInput");

Просмотреть файл

@ -60,8 +60,69 @@ add_task(async function() {
EventUtils.sendString(query);
await searchCompletedPromise;
let noResultsEl = gBrowser.contentDocument.querySelector(".no-results-message");
let noResultsEl = gBrowser.contentDocument.querySelector("#no-results-message");
is_element_visible(noResultsEl, "Should be reporting no results");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
/**
* Test that we search using `search-l10n-ids`.
*
* The test uses element `browserContainersSettings` and
* l10n id `language-and-appearance-header` and expects the element
* to be matched on the first word from the l10n id value ("Language" in en-US).
*/
add_task(async function() {
let l10nId = "language-and-appearance-header";
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
// First, lets make sure that the element is not matched without
// `search-l10n-ids`.
{
let searchInput = gBrowser.contentDocument.getElementById("searchInput");
let bcsElem = gBrowser.contentDocument.getElementById("browserContainersSettings");
is(searchInput, gBrowser.contentDocument.activeElement.closest("#searchInput"),
"Search input should be focused when visiting preferences");
ok(!bcsElem.getAttribute("search-l10n-ids").includes(l10nId),
"browserContainersSettings element should not contain the l10n id here.");
let query = "Language";
let searchCompletedPromise = BrowserTestUtils.waitForEvent(
gBrowser.contentWindow, "PreferencesSearchCompleted", evt => evt.detail == query);
EventUtils.sendString(query);
await searchCompletedPromise;
is_element_hidden(bcsElem, "browserContainersSettings should not be in search results");
}
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
// Now, let's add the l10n id to the element and perform the same search again.
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
{
let searchInput = gBrowser.contentDocument.getElementById("searchInput");
is(searchInput, gBrowser.contentDocument.activeElement.closest("#searchInput"),
"Search input should be focused when visiting preferences");
let bcsElem = gBrowser.contentDocument.getElementById("browserContainersSettings");
bcsElem.setAttribute("search-l10n-ids", l10nId);
let query = "Language";
let searchCompletedPromise = BrowserTestUtils.waitForEvent(
gBrowser.contentWindow, "PreferencesSearchCompleted", evt => evt.detail == query);
EventUtils.sendString(query);
await searchCompletedPromise;
is_element_visible(bcsElem, "browserContainersSettings should be in search results");
}
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

Просмотреть файл

@ -165,7 +165,7 @@ XPCOMUtils.defineLazyServiceGetters(this, {
XPCOMUtils.defineLazyModuleGetters(this, {
AppConstants: "resource://gre/modules/AppConstants.jsm",
AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
DevToolsShim: "chrome://devtools-shim/content/DevToolsShim.jsm",
DevToolsShim: "chrome://devtools-startup/content/DevToolsShim.jsm",
GlobalState: "resource:///modules/sessionstore/GlobalState.jsm",
PrivacyFilter: "resource:///modules/sessionstore/PrivacyFilter.jsm",
PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",

Просмотреть файл

@ -613,9 +613,9 @@
@RESPATH@/browser/chrome/webide.manifest
@RESPATH@/browser/@PREF_DIR@/webide-prefs.js
; [DevTools Shim Files]
@RESPATH@/browser/chrome/devtools-shim@JAREXT@
@RESPATH@/browser/chrome/devtools-shim.manifest
; [DevTools Startup Files]
@RESPATH@/browser/chrome/devtools-startup@JAREXT@
@RESPATH@/browser/chrome/devtools-startup.manifest
@RESPATH@/browser/@PREF_DIR@/devtools-startup-prefs.js
; DevTools

Просмотреть файл

@ -83,7 +83,7 @@ ifneq '$(or $(MOZ_DEV_EDITION),$(NIGHTLY_BUILD))' ''
@$(MAKE) -C ../extensions/webcompat-reporter/locales AB_CD=$* XPI_NAME=locale-$*
endif
@$(MAKE) -C ../../devtools/client/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -C ../../devtools/shim/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -C ../../devtools/startup/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -B searchplugins AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR)
@$(MAKE) multilocale.txt-$* AB_CD=$* XPI_NAME=locale-$*
@ -104,7 +104,7 @@ ifndef RELEASE_OR_BETA
@$(MAKE) -C ../extensions/presentation/locale chrome AB_CD=$*
endif
@$(MAKE) -C ../../devtools/client/locales chrome AB_CD=$*
@$(MAKE) -C ../../devtools/shim/locales chrome AB_CD=$*
@$(MAKE) -C ../../devtools/startup/locales chrome AB_CD=$*
@$(MAKE) chrome AB_CD=$*
@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales chrome AB_CD=$*
ifdef NIGHTLY_BUILD

Просмотреть файл

@ -6,7 +6,7 @@ def test(mod, path, entity = None):
import re
# ignore anything but Firefox
if mod not in ("netwerk", "dom", "toolkit", "security/manager",
"devtools/client", "devtools/shared", "devtools/shim",
"devtools/client", "devtools/shared", "devtools/startup",
"browser",
"browser/extensions/formautofill",
"browser/extensions/onboarding",

Просмотреть файл

@ -11,7 +11,7 @@ dirs = browser
other-licenses/branding/firefox
browser/branding/official
devtools/client
devtools/shim
devtools/startup
browser/extensions/formautofill
browser/extensions/onboarding
browser/extensions/webcompat-reporter

Просмотреть файл

@ -145,8 +145,8 @@ locales = [
path = "devtools/client/locales/l10n.toml"
[[paths]]
reference = "devtools/shim/locales/en-US/**"
l10n = "{l}devtools/shim/**"
reference = "devtools/startup/locales/en-US/**"
l10n = "{l}devtools/startup/**"
# Filters
# The filters below are evaluated one after the other, in the given order.

Просмотреть файл

@ -839,7 +839,7 @@ button > hbox > label {
}
.visually-hidden {
visibility: hidden;
visibility: collapse;
}
menulist {

Просмотреть файл

@ -34,7 +34,7 @@ loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scrat
const {MultiLocalizationHelper} = require("devtools/shared/l10n");
const L10N = new MultiLocalizationHelper(
"devtools/client/locales/startup.properties",
"devtools/shim/locales/key-shortcuts.properties"
"devtools/startup/locales/key-shortcuts.properties"
);
var Tools = {};

Просмотреть файл

@ -7,7 +7,7 @@
const {Cu} = require("chrome");
const Services = require("Services");
const {DevToolsShim} = require("chrome://devtools-shim/content/DevToolsShim.jsm");
const {DevToolsShim} = require("chrome://devtools-startup/content/DevToolsShim.jsm");
// Load gDevToolsBrowser toolbox lazily as they need gDevTools to be fully initialized
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
@ -53,9 +53,8 @@ function DevTools() {
// related events.
this.registerDefaults();
// Register this new DevTools instance to Firefox. DevToolsShim is part of Firefox,
// integrating with all Firefox codebase and making the glue between code from
// mozilla-central and DevTools add-on on github
// Register this DevTools instance on the DevToolsShim, which is used by non-devtools
// code to interact with DevTools.
DevToolsShim.register(this);
}
@ -655,8 +654,7 @@ DevTools.prototype = {
},
/**
* Either the DevTools Loader has been destroyed by the add-on contribution
* workflow, or firefox is shutting down.
* Either the DevTools Loader has been destroyed or firefox is shutting down.
* @param {boolean} shuttingDown
* True if firefox is currently shutting down. We may prevent doing
@ -664,8 +662,7 @@ DevTools.prototype = {
* cleaned up in order to be able to load devtools again.
*/
destroy({ shuttingDown }) {
// Do not cleanup everything during firefox shutdown, but only when
// devtools are reloaded via the add-on contribution workflow.
// Do not cleanup everything during firefox shutdown.
if (!shuttingDown) {
for (let [, toolbox] of this._toolboxes) {
toolbox.destroy();
@ -685,7 +682,7 @@ DevTools.prototype = {
// manager state on shutdown.
if (!shuttingDown) {
// Notify the DevToolsShim that DevTools are no longer available, particularly if
// the destroy was caused by disabling/removing the DevTools add-on.
// the destroy was caused by disabling/removing DevTools.
DevToolsShim.unregister();
}

Просмотреть файл

@ -407,7 +407,7 @@ TabTarget.prototype = {
DebuggerServer.init();
// When connecting to a local tab, we only need the root actor.
// Then we are going to call DebuggerServer.connectToChild and talk
// Then we are going to call DebuggerServer.connectToFrame and talk
// directly with actors living in the child process.
// We also need browser actors for actor registry which enabled addons
// to register custom actors.

Просмотреть файл

@ -50,8 +50,8 @@ class RequestListContent extends Component {
connector: PropTypes.object.isRequired,
columns: PropTypes.object.isRequired,
networkDetailsOpen: PropTypes.bool.isRequired,
networkDetailsWidth: PropTypes.number.isRequired,
networkDetailsHeight: PropTypes.number.isRequired,
networkDetailsWidth: PropTypes.number,
networkDetailsHeight: PropTypes.number,
cloneSelectedRequest: PropTypes.func.isRequired,
displayedRequests: PropTypes.array.isRequired,
firstRequestStartedMillis: PropTypes.number.isRequired,

Просмотреть файл

@ -92,7 +92,7 @@ let webpackConfig = {
// Locales need to be explicitly mapped to the en-US subfolder
"devtools/client/locales": path.join(__dirname, "../../client/locales/en-US"),
"devtools/shared/locales": path.join(__dirname, "../../shared/locales/en-US"),
"devtools/shim/locales": path.join(__dirname, "../../shared/locales/en-US"),
"devtools/startup/locales": path.join(__dirname, "../../shared/locales/en-US"),
"toolkit/locales": path.join(__dirname, "../../../toolkit/locales/en-US"),
// Unless a path explicitly needs to be rewritten or shimmed, all devtools paths can

Просмотреть файл

@ -448,7 +448,7 @@ MessageManagerTunnel.prototype = {
OUTER_TO_INNER_FRAME_SCRIPTS: [
// DevTools server for OOP frames
"resource://devtools/server/child.js"
"resource://devtools/server/startup/frame.js"
],
get outer() {

Просмотреть файл

@ -10,7 +10,6 @@ support-files = head.js
[browser_scratchpad_eval_func.js]
[browser_scratchpad_goto_line_ui.js]
[browser_scratchpad_reload_and_run.js]
uses-unsafe-cpows = true
[browser_scratchpad_display_non_error_exceptions.js]
[browser_scratchpad_modeline.js]
[browser_scratchpad_chrome_context_pref.js]
@ -27,7 +26,6 @@ disabled=bug 807234 becoming basically permanent
[browser_scratchpad_revert_to_saved.js]
[browser_scratchpad_run_error_goto_line.js]
[browser_scratchpad_contexts.js]
uses-unsafe-cpows = true
[browser_scratchpad_execute_print.js]
[browser_scratchpad_files.js]
[browser_scratchpad_initialization.js]
@ -43,7 +41,6 @@ support-files = NS_ERROR_ILLEGAL_INPUT.txt
[browser_scratchpad_pprint_error_goto_line.js]
[browser_scratchpad_restore.js]
[browser_scratchpad_tab_switch.js]
uses-unsafe-cpows = true
[browser_scratchpad_ui.js]
[browser_scratchpad_close_toolbox.js]
[browser_scratchpad_remember_view_options.js]

Просмотреть файл

@ -48,10 +48,10 @@ function runTests() {
});
ok(!pageResult, "no content.foobarBug636725");
},
then: function() {
is(gBrowser.contentWindowAsCPOW.wrappedJSObject.foobarBug636725, "aloha",
then: () => ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
is(content.wrappedJSObject.foobarBug636725, "aloha",
"content.foobarBug636725 has been set");
}
}),
}, {
method: "run",
prepare: function() {

Просмотреть файл

@ -10,22 +10,20 @@ var EDITOR_TEXT = [
"window.dispatchEvent(evt);"
].join("\n");
function test()
{
requestLongerTimeout(2);
waitForExplicitFinish();
add_task(async function test() {
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, true);
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(function () {
openScratchpad(runTests);
});
let url = "data:text/html,Scratchpad test for bug 740948";
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, url);
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
gBrowser.loadURI("data:text/html,Scratchpad test for bug 740948");
}
await new Promise((resolve) => openScratchpad(resolve));
await runTests();
function runTests()
{
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
});
async function runTests() {
let sp = gScratchpadWindow.Scratchpad;
ok(sp, "Scratchpad object exists in new window");
@ -52,20 +50,25 @@ function runTests()
sp.setText(EDITOR_TEXT);
let browser = gBrowser.selectedBrowser;
let deferred = defer();
browser.contentWindowAsCPOW.addEventListener("DOMWindowCreated", function () {
browser.contentWindowAsCPOW.addEventListener("foo", function () {
is(browser.contentWindow.document.body.innerHTML, "Modified text",
"After reloading, HTML is different.");
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
deferred.resolve();
}, {capture: true, once: true});
}, {capture: true, once: true});
ok(browser.contentWindowAsCPOW.document.body.innerHTML !== "Modified text",
await ContentTask.spawn(browser, null, function() {
ok(content.document.body.innerHTML !== "Modified text",
"Before reloading, HTML is intact.");
sp.reloadAndRun().then(deferred.promise).then(finish);
});
let reloaded = BrowserTestUtils.browserLoaded(browser);
sp.reloadAndRun();
await reloaded;
await ContentTask.spawn(browser, null, async function() {
// If `evt` is not defined, the scratchpad code has not run yet,
// so we need to await the "foo" event.
if (!content.wrappedJSObject.evt) {
await new Promise((resolve) => {
content.addEventListener("foo", resolve, {once: true});
});
}
is(content.document.body.innerHTML, "Modified text",
"After reloading, HTML is different.");
});
}

Просмотреть файл

@ -24,8 +24,7 @@ function test()
gBrowser.loadURI("data:text/html,test context switch in Scratchpad tab 1");
}
function runTests()
{
async function runTests() {
sp = gScratchpadWindow.Scratchpad;
let contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
@ -52,36 +51,39 @@ function runTests()
sp.setText("window.foosbug653108 = 'aloha';");
ok(!gBrowser.contentWindowAsCPOW.wrappedJSObject.foosbug653108,
"no content.foosbug653108");
sp.run().then(function () {
is(gBrowser.contentWindowAsCPOW.wrappedJSObject.foosbug653108, "aloha",
"content.foosbug653108 has been set");
gBrowser.tabContainer.addEventListener("TabSelect", runTests2, true);
gBrowser.selectedTab = tab1;
await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
ok(!content.wrappedJSObject.foosbug653108, "no content.foosbug653108");
});
await sp.run();
await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
is(content.wrappedJSObject.foosbug653108, "aloha",
"content.foosbug653108 has been set");
});
gBrowser.tabContainer.addEventListener("TabSelect", runTests2, true);
gBrowser.selectedTab = tab1;
}
function runTests2() {
async function runTests2() {
gBrowser.tabContainer.removeEventListener("TabSelect", runTests2, true);
ok(!window.foosbug653108, "no window.foosbug653108");
sp.setText("window.foosbug653108");
sp.run().then(function ([, , result]) {
isnot(result, "aloha", "window.foosbug653108 is not aloha");
let [, , result] = await sp.run();
isnot(result, "aloha", "window.foosbug653108 is not aloha");
sp.setText("window.foosbug653108 = 'ahoyhoy';");
sp.run().then(function () {
is(gBrowser.contentWindowAsCPOW.wrappedJSObject.foosbug653108, "ahoyhoy",
"content.foosbug653108 has been set 2");
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(runTests3);
gBrowser.loadURI("data:text/html,test context switch in Scratchpad location 2");
});
sp.setText("window.foosbug653108 = 'ahoyhoy';");
await sp.run();
await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
is(content.wrappedJSObject.foosbug653108, "ahoyhoy",
"content.foosbug653108 has been set 2");
});
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(runTests3);
gBrowser.loadURI("data:text/html,test context switch in Scratchpad location 2");
}
function runTests3() {

Просмотреть файл

@ -41,11 +41,8 @@ support-files =
[browser_editor_addons.js]
[browser_codemirror.js]
[browser_css_autocompletion.js]
uses-unsafe-cpows = true
[browser_css_getInfo.js]
uses-unsafe-cpows = true
[browser_css_statemachine.js]
uses-unsafe-cpows = true
[browser_detectindent.js]
[browser_vimemacs.js]
skip-if = os == 'linux'&&debug # bug 981707

Просмотреть файл

@ -70,57 +70,62 @@ const TEST_URI = "data:text/html;charset=UTF-8," + encodeURIComponent(
" </html>"
].join("\n"));
let doc = null;
let browser;
let index = 0;
let completer = null;
let progress;
let progressDiv;
let inspector;
function test() {
waitForExplicitFinish();
addTab(TEST_URI).then(function() {
doc = gBrowser.contentDocumentAsCPOW;
runTests();
});
}
add_task(async function test() {
let tab = await addTab(TEST_URI);
browser = tab.linkedBrowser;
await runTests();
browser = null;
gBrowser.removeCurrentTab();
});
function runTests() {
progress = doc.getElementById("progress");
progressDiv = doc.querySelector("#progress > div");
async function runTests() {
let target = TargetFactory.forTab(gBrowser.selectedTab);
target.makeRemote().then(() => {
inspector = InspectorFront(target.client, target.form);
inspector.getWalker().then(walker => {
completer = new CSSCompleter({walker: walker,
cssProperties: getClientCssProperties()});
checkStateAndMoveOn();
});
});
await target.makeRemote();
inspector = InspectorFront(target.client, target.form);
let walker = await inspector.getWalker();
completer = new CSSCompleter({walker: walker,
cssProperties: getClientCssProperties()});
await checkStateAndMoveOn();
await completer.walker.release();
inspector.destroy();
inspector = null;
completer = null;
}
function checkStateAndMoveOn() {
async function checkStateAndMoveOn() {
if (index == tests.length) {
finishUp();
return;
}
let [lineCh, expectedSuggestions] = tests[index];
let [line, ch] = lineCh;
progress.dataset.progress = ++index;
progressDiv.style.width = 100 * index / tests.length + "%";
++index;
await ContentTask.spawn(browser, [index, tests.length], function([idx, len]) {
let progress = content.document.getElementById("progress");
let progressDiv = content.document.querySelector("#progress > div");
progress.dataset.progress = idx;
progressDiv.style.width = 100 * idx / len + "%";
});
completer.complete(limit(source, lineCh), {line, ch})
.then(actualSuggestions => checkState(expectedSuggestions, actualSuggestions))
.then(checkStateAndMoveOn);
let actualSuggestions = await completer.complete(limit(source, lineCh), {line, ch});
await checkState(expectedSuggestions, actualSuggestions);
await checkStateAndMoveOn();
}
function checkState(expected, actual) {
async function checkState(expected, actual) {
if (expected.length != actual.length) {
ok(false, "Number of suggestions did not match up for state " + index +
". Expected: " + expected.length + ", Actual: " + actual.length);
progress.classList.add("failed");
await ContentTask.spawn(browser, null, function() {
let progress = content.document.getElementById("progress");
progress.classList.add("failed");
});
return;
}
@ -133,15 +138,3 @@ function checkState(expected, actual) {
}
ok(true, "Test " + index + " passed. ");
}
function finishUp() {
completer.walker.release().then(() => {
inspector.destroy();
inspector = null;
completer = null;
gBrowser.removeCurrentTab();
finish();
});
progress = null;
progressDiv = null;
}

Просмотреть файл

@ -123,18 +123,10 @@ const TEST_URI = "data:text/html;charset=UTF-8," + encodeURIComponent(
" </html>"
].join("\n"));
let doc = null;
function test() {
waitForExplicitFinish();
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
doc = gBrowser.contentDocumentAsCPOW;
runTests();
});
gBrowser.loadURI(TEST_URI);
}
add_task(async function test() {
let tab = await addTab(TEST_URI);
let browser = tab.linkedBrowser;
function runTests() {
let completer = new CSSCompleter({
cssProperties: getClientCssProperties()
});
@ -158,13 +150,16 @@ function runTests() {
return false;
};
let progress = doc.getElementById("progress");
let progressDiv = doc.querySelector("#progress > div");
let i = 0;
for (let expected of tests) {
++i;
let caret = expected.splice(0, 1)[0];
progress.dataset.progress = ++i;
progressDiv.style.width = 100 * i / tests.length + "%";
await ContentTask.spawn(browser, [i, tests.length], function([idx, len]) {
let progress = content.document.getElementById("progress");
let progressDiv = content.document.querySelector("#progress > div");
progress.dataset.progress = idx;
progressDiv.style.width = 100 * idx / len + "%";
});
let actual = completer.getInfoAt(source, caret);
if (checkState(expected, actual)) {
ok(true, "Test " + i + " passed. ");
@ -173,9 +168,11 @@ function runTests() {
"but found [" + actual.state + ", " +
(actual.selector || actual.selectors) + ", " +
actual.propertyName + ", " + actual.value + "].");
progress.classList.add("failed");
await ContentTask.spawn(browser, null, function() {
let progress = content.document.getElementById("progress");
progress.classList.add("failed");
});
}
}
gBrowser.removeCurrentTab();
finish();
}
});

Просмотреть файл

@ -54,17 +54,10 @@ const TEST_URI = "data:text/html;charset=UTF-8," + encodeURIComponent(
" </html>"
].join("\n"));
var doc = null;
function test() {
waitForExplicitFinish();
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TEST_URI);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
doc = gBrowser.contentDocumentAsCPOW;
runTests();
});
}
add_task(async function test() {
let tab = await addTab(TEST_URI);
let browser = tab.linkedBrowser;
function runTests() {
let completer = new CSSCompleter({
cssProperties: getClientCssProperties()
});
@ -88,12 +81,15 @@ function runTests() {
return false;
};
let progress = doc.getElementById("progress");
let progressDiv = doc.querySelector("#progress > div");
let i = 0;
for (let testcase of tests) {
progress.dataset.progress = ++i;
progressDiv.style.width = 100 * i / tests.length + "%";
++i;
await ContentTask.spawn(browser, [i, tests.length], function([idx, len]) {
let progress = content.document.getElementById("progress");
let progressDiv = content.document.querySelector("#progress > div");
progress.dataset.progress = idx;
progressDiv.style.width = 100 * idx / len + "%";
});
completer.resolveState(limit(source, testcase[0]),
{line: testcase[0][0], ch: testcase[0][1]});
if (checkState(testcase[1])) {
@ -103,9 +99,11 @@ function runTests() {
"but found [" + completer.state + ", " + completer.selectorState +
", " + completer.completing + ", " +
(completer.propertyName || completer.selector) + "].");
progress.classList.add("failed");
await ContentTask.spawn(browser, null, function() {
let progress = content.document.getElementById("progress");
progress.classList.add("failed");
});
}
}
gBrowser.removeCurrentTab();
finish();
}
});

Просмотреть файл

@ -106,7 +106,7 @@ webpackConfig.resolve = {
"toolkit/locales": path.join(__dirname, "../../../toolkit/locales/en-US"),
"devtools/client/locales": path.join(__dirname, "../../client/locales/en-US"),
"devtools/shared/locales": path.join(__dirname, "../../shared/locales/en-US"),
"devtools/shim/locales": path.join(__dirname, "../../shared/locales/en-US"),
"devtools/startup/locales": path.join(__dirname, "../../shared/locales/en-US"),
// Unless a path explicitly needs to be rewritten or shimmed, all devtools paths can
// be mapped to ../../

Просмотреть файл

@ -72,12 +72,12 @@ To create a new preference, it should be assigned a default value. Default prefe
defined in preferences files such as:
- devtools/client/preferences/devtools.js
- devtools/client/preferences/debugger.js
- devtools/shim/devtools-startup-prefs.js
- devtools/startup/devtools-startup-prefs.js
Most new preferences should go in devtools/client/preferences/devtools.js. Debugger
specific preferences should go in devtools/client/preferences/debugger.js. Finally if a
preference needs to be available very early during the Firefox startup sequence, it should
go in devtools/shim/devtools-startup-prefs.js.
go in devtools/startup/devtools-startup-prefs.js.
### Projects using Launchpad

Просмотреть файл

@ -4,7 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
if CONFIG['MOZ_DEVTOOLS'] and CONFIG['MOZ_DEVTOOLS'] not in ('all', 'server', 'addon'):
if CONFIG['MOZ_DEVTOOLS'] and CONFIG['MOZ_DEVTOOLS'] not in ('all', 'server'):
error('Unsupported MOZ_DEVTOOLS value: %s' % (CONFIG['MOZ_DEVTOOLS']))
if CONFIG['MOZ_DEVTOOLS'] == 'all':
@ -12,21 +12,14 @@ if CONFIG['MOZ_DEVTOOLS'] == 'all':
'client',
]
# `addon` is a special build mode to strip everything except binary components
# and shim modules that are going to stay in Firefox once DevTools ship as an
# add-on.
# `platform` contains all native components
DIRS += [
'shim',
'server',
'shared',
'startup',
'platform',
]
if CONFIG['MOZ_DEVTOOLS'] != 'addon':
DIRS += [
'server',
'shared',
]
# /browser uses DIST_SUBDIR. We opt-in to this treatment when building
# DevTools for the browser to keep the root omni.ja slim for use by external XUL
# apps. Mulet also uses this since it includes /browser.

Просмотреть файл

@ -9,7 +9,7 @@ const defer = require("devtools/shared/defer");
const protocol = require("devtools/shared/protocol");
const {CallWatcherActor} = require("devtools/server/actors/call-watcher");
const {CallWatcherFront} = require("devtools/shared/fronts/call-watcher");
const {WebGLPrimitiveCounter} = require("devtools/server/primitive");
const {WebGLPrimitiveCounter} = require("devtools/server/actors/canvas/primitive");
const {
frameSnapshotSpec,
canvasSpec,

Просмотреть файл

@ -0,0 +1,9 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'primitive.js',
)

Просмотреть файл

@ -13,7 +13,7 @@ const InspectorUtils = require("InspectorUtils");
const lazyContainer = {};
loader.lazyRequireGetter(lazyContainer, "CssLogic",
"devtools/server/css-logic", true);
"devtools/server/actors/inspector/css-logic", true);
exports.getComputedStyle = (node) =>
lazyContainer.CssLogic.getComputedStyle(node);

Просмотреть файл

@ -5,7 +5,9 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'css-logic.js',
'document-walker.js',
'event-parsers.js',
'inspector.js',
'node.js',
'utils.js',

Просмотреть файл

@ -25,8 +25,8 @@ loader.lazyRequireGetter(this, "isAnonymous", "devtools/shared/layout/utils", tr
loader.lazyRequireGetter(this, "InspectorActorUtils", "devtools/server/actors/inspector/utils");
loader.lazyRequireGetter(this, "LongStringActor", "devtools/server/actors/string", true);
loader.lazyRequireGetter(this, "getFontPreviewData", "devtools/server/actors/styles", true);
loader.lazyRequireGetter(this, "CssLogic", "devtools/server/css-logic", true);
loader.lazyRequireGetter(this, "EventParsers", "devtools/server/event-parsers", true);
loader.lazyRequireGetter(this, "CssLogic", "devtools/server/actors/inspector/css-logic", true);
loader.lazyRequireGetter(this, "EventParsers", "devtools/server/actors/inspector/event-parsers", true);
const EventEmitter = require("devtools/shared/event-emitter");

Просмотреть файл

@ -12,7 +12,7 @@ const { getStringifiableFragments } =
require("devtools/server/actors/utils/css-grid-utils");
loader.lazyRequireGetter(this, "nodeConstants", "devtools/shared/dom-node-constants");
loader.lazyRequireGetter(this, "CssLogic", "devtools/server/css-logic", true);
loader.lazyRequireGetter(this, "CssLogic", "devtools/server/actors/inspector/css-logic", true);
/**
* Set of actors the expose the CSS layout information to the devtools protocol clients.

Просмотреть файл

@ -5,11 +5,13 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS += [
'canvas',
'emulation',
'highlighters',
'inspector',
'utils',
'webconsole',
'worker',
]
DevToolsModules(

Просмотреть файл

@ -524,7 +524,7 @@ RootActor.prototype = {
this._parameters.processList.onListChanged = null;
},
onGetProcess: function(request) {
async onGetProcess(request) {
if (!DebuggerServer.allowChromeProcess) {
return { error: "forbidden",
message: "You are not allowed to debug chrome." };
@ -559,10 +559,9 @@ RootActor.prototype = {
let onDestroy = () => {
this._processActors.delete(id);
};
return DebuggerServer.connectToContent(this.conn, mm, onDestroy).then(formResult => {
this._processActors.set(id, formResult);
return { form: formResult };
});
form = await DebuggerServer.connectToContentProcess(this.conn, mm, onDestroy);
this._processActors.set(id, form);
return { form };
},
/* This is not in the spec, but it's used by tests. */

Просмотреть файл

@ -14,7 +14,7 @@ const InspectorUtils = require("InspectorUtils");
const {pageStyleSpec, styleRuleSpec, ELEMENT_STYLE} = require("devtools/shared/specs/styles");
loader.lazyRequireGetter(this, "CssLogic", "devtools/server/css-logic", true);
loader.lazyRequireGetter(this, "CssLogic", "devtools/server/actors/inspector/css-logic", true);
loader.lazyRequireGetter(this, "SharedCssLogic", "devtools/shared/inspector/css-logic");
loader.lazyRequireGetter(this, "getDefinedGeometryProperties",
"devtools/server/actors/highlighters/geometry-editor", true);

Просмотреть файл

@ -721,7 +721,7 @@ BrowserTabActor.prototype = {
}
this.exit();
};
let connect = DebuggerServer.connectToChild(this._conn, this._browser, onDestroy);
let connect = DebuggerServer.connectToFrame(this._conn, this._browser, onDestroy);
let form = await connect;
this._form = form;

Просмотреть файл

@ -161,7 +161,7 @@ ProxyChildActor.prototype = {
this._browser = await ExtensionParent.DebugUtils.getExtensionProcessBrowser(this);
this._form = await DebuggerServer.connectToChild(this._conn, this._browser, onDestroy,
this._form = await DebuggerServer.connectToFrame(this._conn, this._browser, onDestroy,
{addonId: this.addonId});
this._childActorID = this._form.actor;

Просмотреть файл

@ -47,7 +47,7 @@ const FALLBACK_DOC_MESSAGE = "Your addon does not have any document opened yet."
* The connection to the client.
* @param {nsIMessageSender} chromeGlobal.
* The chromeGlobal where this actor has been injected by the
* DebuggerServer.connectToChild method.
* DebuggerServer.connectToFrame method.
* @param {string} prefix
* the custom RDP prefix to use.
* @param {string} addonId

Просмотреть файл

@ -242,7 +242,7 @@ let ServiceWorkerActor = protocol.ActorClassWithSpec(serviceWorkerSpec, {
},
});
// Lazily load the service-worker-child.js process script only once.
// Lazily load the service-worker-process.js process script only once.
let _serviceWorkerProcessScriptLoaded = false;
let ServiceWorkerRegistrationActor =
@ -351,7 +351,7 @@ protocol.ActorClassWithSpec(serviceWorkerRegistrationSpec, {
start() {
if (!_serviceWorkerProcessScriptLoaded) {
Services.ppmm.loadProcessScript(
"resource://devtools/server/service-worker-child.js", true);
"resource://devtools/server/actors/worker/service-worker-process.js", true);
_serviceWorkerProcessScriptLoaded = true;
}

Просмотреть файл

@ -0,0 +1,9 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'service-worker-process.js',
)

Просмотреть файл

@ -6,6 +6,11 @@
"use strict";
/*
* Process script used to control service workers via a DevTools actor.
* Loaded into content processes by the service worker actors.
*/
let swm = Cc["@mozilla.org/serviceworkers/manager;1"]
.getService(Ci.nsIServiceWorkerManager);

Просмотреть файл

@ -52,8 +52,8 @@ if (isWorker) {
Services.prefs.getBoolPref(VERBOSE_PREF);
}
const CONTENT_PROCESS_DBG_SERVER_SCRIPT =
"resource://devtools/server/content-process-debugger-server.js";
const CONTENT_PROCESS_SERVER_STARTUP_SCRIPT =
"resource://devtools/server/startup/content-process.js";
function loadSubScript(url) {
try {
@ -127,14 +127,14 @@ function ModuleAPI() {
};
}
/** *
/**
* Public API
*/
var DebuggerServer = {
_listeners: [],
_initialized: false,
// Flag to check if the content process debugger server script was already loaded.
_contentProcessScriptLoaded: false,
// Flag to check if the content process server startup script was already loaded.
_contentProcessServerStartupScriptLoaded: false,
// Map of global actor names to actor constructors provided by extensions.
globalActorFactories: {},
// Map of tab actor names to actor constructors provided by extensions.
@ -699,7 +699,11 @@ var DebuggerServer = {
return this._onConnection(transport, prefix, true);
},
connectToContent(connection, mm, onDestroy) {
/**
* Start a DevTools server in a content process (representing the entire process, not
* just a single frame) and add it as a child server for an active connection.
*/
connectToContentProcess(connection, mm, onDestroy) {
return new Promise(resolve => {
let prefix = connection.allocID("content-process");
let actor, childTransport;
@ -719,21 +723,21 @@ var DebuggerServer = {
connection.setForwarding(prefix, childTransport);
dumpn("establishing forwarding for process with prefix " + prefix);
dumpn(`Start forwarding for process with prefix ${prefix}`);
actor = msg.json.actor;
resolve(actor);
});
// Load the content process debugger server script only once.
if (!this._contentProcessScriptLoaded) {
// Load the content process server startup script only once.
if (!this._contentProcessServerStartupScriptLoaded) {
// Load the process script that will receive the debug:init-content-server message
Services.ppmm.loadProcessScript(CONTENT_PROCESS_DBG_SERVER_SCRIPT, true);
this._contentProcessScriptLoaded = true;
Services.ppmm.loadProcessScript(CONTENT_PROCESS_SERVER_STARTUP_SCRIPT, true);
this._contentProcessServerStartupScriptLoaded = true;
}
// Send a message to the content process debugger server script to forward it the
// Send a message to the content process server startup script to forward it the
// prefix.
mm.sendAsyncMessage("debug:init-content-server", {
prefix: prefix
@ -775,11 +779,15 @@ var DebuggerServer = {
});
},
/**
* Start a DevTools server in a worker and add it as a child server for an active
* connection.
*/
connectToWorker(connection, dbg, id, options) {
return new Promise((resolve, reject) => {
// Step 1: Ensure the worker debugger is initialized.
if (!dbg.isInitialized) {
dbg.initialize("resource://devtools/server/worker.js");
dbg.initialize("resource://devtools/server/startup/worker.js");
// Create a listener for rpc requests from the worker debugger. Only do
// this once, when the worker debugger is first initialized, rather than
@ -973,12 +981,13 @@ var DebuggerServer = {
_childMessageManagers: new Set(),
/**
* Connect to a child process.
* Start a DevTools server in a remote frame's process and add it as a child server for
* an active connection.
*
* @param object connection
* The debugger server connection to use.
* @param nsIDOMElement frame
* The browser element that holds the child process.
* The frame element with remote content to connect to.
* @param function [onDestroy]
* Optional function to invoke when the child process closes
* or the connection shuts down. (Need to forget about the
@ -987,12 +996,12 @@ var DebuggerServer = {
* A promise object that is resolved once the connection is
* established.
*/
connectToChild(connection, frame, onDestroy, {addonId} = {}) {
connectToFrame(connection, frame, onDestroy, {addonId} = {}) {
return new Promise(resolve => {
// Get messageManager from XUL browser (which might be a specialized tunnel for RDM)
// or else fallback to asking the frameLoader itself.
let mm = frame.messageManager || frame.frameLoader.messageManager;
mm.loadFrameScript("resource://devtools/server/child.js", false);
mm.loadFrameScript("resource://devtools/server/startup/frame.js", false);
let trackMessageManager = () => {
frame.addEventListener("DevTools:BrowserSwap", onBrowserSwap);
@ -1021,7 +1030,7 @@ var DebuggerServer = {
// between e10s parent and child processes
let parentModules = [];
let onSetupInParent = function(msg) {
// We may have multiple connectToChild instance running for the same tab
// We may have multiple connectToFrame instance running for the same tab
// and need to filter the messages.
if (msg.json.prefix != connPrefix) {
return false;
@ -1067,7 +1076,7 @@ var DebuggerServer = {
connection.setForwarding(prefix, childTransport);
dumpn("establishing forwarding for app with prefix " + prefix);
dumpn(`Start forwarding for frame with prefix ${prefix}`);
actor = msg.json.actor;
resolve(actor);
@ -1129,14 +1138,14 @@ var DebuggerServer = {
// Nothing to do
}
} else {
// Otherwise, the app has been closed before the actor
// Otherwise, the frame has been closed before the actor
// had a chance to be created, so we are not able to create
// the actor.
resolve(null);
}
if (actor) {
// The ContentActor within the child process doesn't necessary
// have time to uninitialize itself when the app is closed/killed.
// have time to uninitialize itself when the frame is closed/killed.
// So ensure telling the client that the related actor is detached.
connection.send({ from: actor.actor, type: "tabDetached" });
actor = null;
@ -1345,12 +1354,12 @@ var DebuggerServer = {
},
/**
* Called when DevTools are unloaded to remove the contend process server script for the
* list of scripts loaded for each new content process. Will also remove message
* Called when DevTools are unloaded to remove the contend process server startup script
* for the list of scripts loaded for each new content process. Will also remove message
* listeners from already loaded scripts.
*/
removeContentServerScript() {
Services.ppmm.removeDelayedProcessScript(CONTENT_PROCESS_DBG_SERVER_SCRIPT);
Services.ppmm.removeDelayedProcessScript(CONTENT_PROCESS_SERVER_STARTUP_SCRIPT);
try {
Services.ppmm.broadcastAsyncMessage("debug:close-content-server");
} catch (e) {

Просмотреть файл

@ -9,6 +9,8 @@ include('../templates.mozbuild')
DIRS += [
'actors',
'performance',
'socket',
'startup',
]
BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
@ -16,16 +18,7 @@ MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
DevToolsModules(
'child.js',
'content-process-debugger-server.js',
'content-server.jsm',
'css-logic.js',
'event-parsers.js',
'main.js',
'primitive.js',
'service-worker-child.js',
'websocket-server.js',
'worker.js'
)
with Files('**'):

Просмотреть файл

@ -0,0 +1,11 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
DevToolsModules(
'websocket-server.js',
)

Просмотреть файл

@ -0,0 +1,6 @@
"use strict";
module.exports = {
// Extend from the common devtools mochitest eslintrc config.
"extends": "../../../.eslintrc.xpcshell.js"
};

Просмотреть файл

@ -0,0 +1,3 @@
[DEFAULT]
tags = devtools
[test_websocket-server.html]

Просмотреть файл

@ -14,7 +14,7 @@
window.onload = function() {
const CC = Components.Constructor;
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
const WebSocketServer = require("devtools/server/websocket-server");
const WebSocketServer = require("devtools/server/socket/websocket-server");
const ServerSocket = CC("@mozilla.org/network/server-socket;1",
"nsIServerSocket", "init");

Просмотреть файл

@ -6,12 +6,20 @@
"use strict";
/*
* Process script that listens for requests to start a `DebuggerServer` for an entire
* content process. Loaded into content processes by the main process during
* `DebuggerServer.connectToContentProcess`.
*
* The actual server startup itself is in a JSM so that code can be cached.
*/
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
function onInit(message) {
// Only reply if we are in a real content process
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
let {init} = ChromeUtils.import("resource://devtools/server/content-server.jsm", {});
let {init} = ChromeUtils.import("resource://devtools/server/startup/content-process.jsm", {});
init(message);
}
}

Просмотреть файл

@ -4,6 +4,14 @@
"use strict";
/*
* Module that listens for requests to start a `DebuggerServer` for an entire content
* process. Loaded into content processes by the main process during
* `DebuggerServer.connectToContentProcess` via the process script `content-process.js`.
*
* The actual server startup itself is in this JSM so that code can be cached.
*/
/* exported init */
this.EXPORTED_SYMBOLS = ["init"];

Просмотреть файл

@ -6,6 +6,12 @@
/* global addEventListener, addMessageListener, removeMessageListener, sendAsyncMessage */
/*
* Frame script that listens for requests to start a `DebuggerServer` for a frame in a
* content process. Loaded into content process frames by the main process during
* `DebuggerServer.connectToFrame`.
*/
try {
var chromeGlobal = this;
@ -128,5 +134,5 @@ try {
});
})();
} catch (e) {
dump(`Exception in app child process: ${e}\n`);
dump(`Exception in DevTools frame startup: ${e}\n`);
}

Просмотреть файл

@ -0,0 +1,12 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'content-process.js',
'content-process.jsm',
'frame.js',
'worker.js',
)

Просмотреть файл

@ -7,6 +7,12 @@
/* eslint-env mozilla/chrome-worker */
/* global worker, loadSubScript, global */
/*
* Worker debugger script that listens for requests to start a `DebuggerServer` for a
* worker in a process. Loaded into a specific worker during
* `DebuggerServer.connectToWorker` which is called from the same process as the worker.
*/
// This function is used to do remote procedure calls from the worker to the
// main thread. It is exposed as a built-in global to every module by the
// worker loader. To make sure the worker loader can access it, it needs to be

Просмотреть файл

@ -31,7 +31,7 @@ support-files =
webextension-helpers.js
[test_animation_actor-lifetime.html]
[test_connection-manager.html]
[test_connectToChild.html]
[test_connectToFrame.html]
[test_css-logic.html]
[test_css-logic-media-queries.html]
[test_css-logic-specificity.html]
@ -108,4 +108,3 @@ support-files =
skip-if = !e10s # test is designed to work on e10s only
[test_webextension-addon-debugging-reload.html]
skip-if = !e10s # test is designed to work on e10s only
[test_websocket-server.html]

Просмотреть файл

@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<html>
<!--
Bug 966991 - Test DebuggerServer.connectToChild
Bug 966991 - Test DebuggerServer.connectToFrame
-->
<head>
<meta charset="utf-8">
@ -78,7 +78,7 @@ function runTests() {
let transport = DebuggerServer.connectPipe();
let conn = transport._serverConnection;
let client = new DebuggerClient(transport);
DebuggerServer.connectToChild(conn, iframe).then(actor => {
DebuggerServer.connectToFrame(conn, iframe).then(actor => {
ok(actor.testActor, "Got the test actor");
// Ensure sending at least one request to our actor,
@ -107,7 +107,7 @@ function runTests() {
let transport = DebuggerServer.connectPipe();
let conn = transport._serverConnection;
let client = new DebuggerClient(transport);
DebuggerServer.connectToChild(conn, iframe).then(actor => {
DebuggerServer.connectToFrame(conn, iframe).then(actor => {
ok(actor.testActor, "Got a test actor for the second connection");
isnot(actor.testActor, firstActor,
"We get different actor instances between two connections");

Просмотреть файл

@ -30,7 +30,7 @@ Test that css-logic handles media-queries correctly
window.onload = function() {
const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
const Services = require("Services");
const {CssLogic} = require("devtools/server/css-logic");
const {CssLogic} = require("devtools/server/actors/inspector/css-logic");
SimpleTest.waitForExplicitFinish();

Просмотреть файл

@ -14,7 +14,7 @@ Test that css-logic calculates CSS specificity properly
window.onload = function() {
const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
const {CssLogic, CssSelector} = require("devtools/server/css-logic");
const {CssLogic, CssSelector} = require("devtools/server/actors/inspector/css-logic");
const InspectorUtils = SpecialPowers.InspectorUtils;
const TEST_DATA = [

Просмотреть файл

@ -13,7 +13,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=
<script type="application/javascript">
"use strict";
const {CssLogic} = require("devtools/server/css-logic");
const {CssLogic} = require("devtools/server/actors/inspector/css-logic");
window.onload = function() {
SimpleTest.waitForExplicitFinish();

Просмотреть файл

@ -80,7 +80,7 @@ function runTests() {
Services.obs.addObserver(onParent, "test:setupParent");
// Instanciate e10s machinery and call setupInChild
DebuggerServer.connectToChild(conn, iframe).then(actor => {
DebuggerServer.connectToFrame(conn, iframe).then(actor => {
DebuggerServer.setupInChild({
module: "chrome://mochitests/content/chrome/devtools/server/tests/mochitest/setup-in-child.js",
setupChild: "setupChild",

Просмотреть файл

@ -47,7 +47,7 @@ BuiltinProvider.prototype = {
// used in the source tree.
"devtools/client/locales": "chrome://devtools/locale",
"devtools/shared/locales": "chrome://devtools-shared/locale",
"devtools/shim/locales": "chrome://devtools-shim/locale",
"devtools/startup/locales": "chrome://devtools-startup/locale",
"toolkit/locales": "chrome://global/locale",
};
// When creating a Loader invisible to the Debugger, we have to ensure

Просмотреть файл

@ -31,7 +31,7 @@ exports.createDevToolsIndexedDB = function(indexedDB) {
* Only the standard version of indexedDB.open is supported.
*/
open(name, version) {
let options = { storage: "persistent" };
let options = {};
if (typeof version === "number") {
options.version = version;
}
@ -41,7 +41,7 @@ exports.createDevToolsIndexedDB = function(indexedDB) {
* Only the standard version of indexedDB.deleteDatabase is supported.
*/
deleteDatabase(name) {
return indexedDB.deleteForPrincipal(principal, name, { storage: "persistent" });
return indexedDB.deleteForPrincipal(principal, name);
},
cmp: indexedDB.cmp.bind(indexedDB),
});

Просмотреть файл

@ -30,7 +30,7 @@ const reqShared = require.context("raw!devtools/shared/locales/",
true, /^.*\.properties$/);
const reqClient = require.context("raw!devtools/client/locales/",
true, /^.*\.properties$/);
const reqShim = require.context("raw!devtools/shim/locales/",
const reqStartup = require.context("raw!devtools/startup/locales/",
true, /^.*\.properties$/);
const reqGlobal = require.context("raw!toolkit/locales/",
true, /^.*\.properties$/);
@ -74,8 +74,8 @@ function getProperties(url) {
reqFn = reqGlobal;
} else if (/^devtools\/shared/.test(url)) {
reqFn = reqShared;
} else if (/^devtools\/shim/.test(url)) {
reqFn = reqShim;
} else if (/^devtools\/startup/.test(url)) {
reqFn = reqStartup;
} else {
reqFn = reqClient;
}

Просмотреть файл

@ -17,7 +17,7 @@ var defer = require("devtools/shared/defer");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var { dumpn, dumpv } = DevToolsUtils;
loader.lazyRequireGetter(this, "WebSocketServer",
"devtools/server/websocket-server");
"devtools/server/socket/websocket-server");
loader.lazyRequireGetter(this, "DebuggerTransport",
"devtools/shared/transport/transport", true);
loader.lazyRequireGetter(this, "WebSocketDebuggerTransport",

Просмотреть файл

@ -1,21 +0,0 @@
// This file was copied from the .eslintrc.xpcshell.js
// This new xpcshell test folder should stay in mozilla-central while devtools move to a
// GitHub repository, hence the duplication.
module.exports = {
"extends": [
"plugin:mozilla/xpcshell-test"
],
"rules": {
// Allow non-camelcase so that run_test doesn't produce a warning.
"camelcase": "off",
// Allow using undefined variables so that tests can refer to functions
// and variables defined in head.js files, without having to maintain a
// list of globals in each .eslintrc file.
// Note that bug 1168340 will eventually help auto-registering globals
// from head.js files.
"no-undef": "off",
"block-scoped-var": "off",
// Tests can always import anything.
"mozilla/reject-some-requires": "off",
}
};

Просмотреть файл

@ -28,34 +28,17 @@ function removeItem(array, callback) {
}
/**
* The DevToolsShim is a part of the DevTools go faster project, which moves the Firefox
* DevTools outside of mozilla-central to an add-on. It aims to bridge the gap for
* existing mozilla-central code that still needs to interact with DevTools (such as
* web-extensions).
*
* DevToolsShim is a singleton that provides a set of helpers to interact with DevTools,
* that work whether the DevTools addon is installed or not. It can be used to start
* listening to events. As soon as a DevTools addon is installed the DevToolsShim will
* forward all the requests received until then to the real DevTools instance.
* that work whether Devtools are enabled or not.
*
* DevToolsShim.isInstalled() can also be used to know if DevTools are currently
* installed.
* It can be used to start listening to devtools events before DevTools are ready. As soon
* as DevTools are enabled, the DevToolsShim will forward all the requests received until
* then to the real DevTools instance.
*/
this.DevToolsShim = {
_gDevTools: null,
listeners: [],
/**
* Check if DevTools are currently installed (but not necessarily initialized).
*
* @return {Boolean} true if DevTools are installed.
*/
isInstalled: function() {
return Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler)
.hasSubstitution("devtools");
},
/**
* Returns true if DevTools are enabled for the current profile. If devtools are not
* enabled, initializing DevTools will open the onboarding page. Some entry points
@ -185,7 +168,7 @@ this.DevToolsShim = {
* needed if the element is nested in frames and not directly in the root
* document.
* @return {Promise} a promise that resolves when the node is selected in the inspector
* markup view or that resolves immediately if DevTools are not installed.
* markup view or that resolves immediately if DevTools are not enabled.
*/
inspectNode: function(tab, selectors) {
if (!this.isEnabled()) {

Просмотреть файл

@ -14,7 +14,7 @@ const { nsIAboutModule } = Ci;
function AboutDevtools() {}
AboutDevtools.prototype = {
uri: Services.io.newURI("chrome://devtools-shim/content/aboutdevtools/aboutdevtools.xhtml"),
uri: Services.io.newURI("chrome://devtools-startup/content/aboutdevtools/aboutdevtools.xhtml"),
classDescription: "about:devtools",
classID: Components.ID("3a16d383-92bd-4c24-ac10-0e2bd66883ab"),
contractID: "@mozilla.org/network/protocol/about;1?what=devtools",

Просмотреть файл

@ -28,10 +28,10 @@ const GA_PARAMETERS = [
["utm_medium", "onboarding"],
];
const ABOUTDEVTOOLS_STRINGS = "chrome://devtools-shim/locale/aboutdevtools.properties";
const ABOUTDEVTOOLS_STRINGS = "chrome://devtools-startup/locale/aboutdevtools.properties";
const aboutDevtoolsBundle = Services.strings.createBundle(ABOUTDEVTOOLS_STRINGS);
const KEY_SHORTCUTS_STRINGS = "chrome://devtools-shim/locale/key-shortcuts.properties";
const KEY_SHORTCUTS_STRINGS = "chrome://devtools-startup/locale/key-shortcuts.properties";
const keyShortcutsBundle = Services.strings.createBundle(KEY_SHORTCUTS_STRINGS);
// URL constructor doesn't support about: scheme,
@ -86,47 +86,47 @@ function updatePage() {
*/
const features = [
{
icon: "chrome://devtools-shim/content/aboutdevtools/images/feature-inspector.svg",
icon: "chrome://devtools-startup/content/aboutdevtools/images/feature-inspector.svg",
title: "features.inspector.title",
desc: "features.inspector.desc",
link: "https://developer.mozilla.org/docs/Tools/Page_Inspector",
}, {
icon: "chrome://devtools-shim/content/aboutdevtools/images/feature-console.svg",
icon: "chrome://devtools-startup/content/aboutdevtools/images/feature-console.svg",
title: "features.console.title",
desc: "features.console.desc",
link: "https://developer.mozilla.org/docs/Tools/Web_Console",
}, {
icon: "chrome://devtools-shim/content/aboutdevtools/images/feature-debugger.svg",
icon: "chrome://devtools-startup/content/aboutdevtools/images/feature-debugger.svg",
title: "features.debugger.title",
desc: "features.debugger.desc",
link: "https://developer.mozilla.org/docs/Tools/Debugger",
}, {
icon: "chrome://devtools-shim/content/aboutdevtools/images/feature-network.svg",
icon: "chrome://devtools-startup/content/aboutdevtools/images/feature-network.svg",
title: "features.network.title",
desc: "features.network.desc",
link: "https://developer.mozilla.org/docs/Tools/Network_Monitor",
}, {
icon: "chrome://devtools-shim/content/aboutdevtools/images/feature-storage.svg",
icon: "chrome://devtools-startup/content/aboutdevtools/images/feature-storage.svg",
title: "features.storage.title",
desc: "features.storage.desc",
link: "https://developer.mozilla.org/docs/Tools/Storage_Inspector",
}, {
icon: "chrome://devtools-shim/content/aboutdevtools/images/feature-responsive.svg",
icon: "chrome://devtools-startup/content/aboutdevtools/images/feature-responsive.svg",
title: "features.responsive.title",
desc: "features.responsive.desc",
link: "https://developer.mozilla.org/docs/Tools/Responsive_Design_Mode",
}, {
icon: "chrome://devtools-shim/content/aboutdevtools/images/feature-visualediting.svg",
icon: "chrome://devtools-startup/content/aboutdevtools/images/feature-visualediting.svg",
title: "features.visualediting.title",
desc: "features.visualediting.desc",
link: "https://developer.mozilla.org/docs/Tools/Style_Editor",
}, {
icon: "chrome://devtools-shim/content/aboutdevtools/images/feature-performance.svg",
icon: "chrome://devtools-startup/content/aboutdevtools/images/feature-performance.svg",
title: "features.performance.title",
desc: "features.performance.desc",
link: "https://developer.mozilla.org/docs/Tools/Performance",
}, {
icon: "chrome://devtools-shim/content/aboutdevtools/images/feature-memory.svg",
icon: "chrome://devtools-startup/content/aboutdevtools/images/feature-memory.svg",
title: "features.memory.title",
desc: "features.memory.desc",
link: "https://developer.mozilla.org/docs/Tools/Memory",

Просмотреть файл

@ -5,7 +5,7 @@
<!DOCTYPE html [
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> %htmlDTD;
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd"> %globalDTD;
<!ENTITY % aboutdevtoolsDTD SYSTEM "chrome://devtools-shim/locale/aboutdevtools.dtd"> %aboutdevtoolsDTD;
<!ENTITY % aboutdevtoolsDTD SYSTEM "chrome://devtools-startup/locale/aboutdevtools.dtd"> %aboutdevtoolsDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml" dir="&locale.dir;">
@ -13,10 +13,10 @@
<title>&aboutDevtools.headTitle;</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>a
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css" type="text/css"/>
<link rel="stylesheet" href="chrome://devtools-shim/content/aboutdevtools/aboutdevtools.css" type="text/css"/>
<link rel="stylesheet" href="chrome://devtools-shim/content/aboutdevtools/subscribe.css" type="text/css"/>
<script type="application/javascript" src="chrome://devtools-shim/content/aboutdevtools/aboutdevtools.js"></script>
<script type="application/javascript" src="chrome://devtools-shim/content/aboutdevtools/subscribe.js"></script>
<link rel="stylesheet" href="chrome://devtools-startup/content/aboutdevtools/aboutdevtools.css" type="text/css"/>
<link rel="stylesheet" href="chrome://devtools-startup/content/aboutdevtools/subscribe.css" type="text/css"/>
<script type="application/javascript" src="chrome://devtools-startup/content/aboutdevtools/aboutdevtools.js"></script>
<script type="application/javascript" src="chrome://devtools-startup/content/aboutdevtools/subscribe.js"></script>
</head>
<body>
<div id="install-page" class="wrapper" hidden="true">
@ -89,7 +89,7 @@
<footer>
<img class="dev-edition-logo"
src="chrome://devtools-shim/content/aboutdevtools/images/dev-edition-logo.svg"
src="chrome://devtools-startup/content/aboutdevtools/images/dev-edition-logo.svg"
alt="Firefox Developer Edition logo"/>
<div class="footer-message">
<h1 class="footer-message-title">&aboutDevtools.footer.title;</h1>

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 76 KiB

После

Ширина:  |  Высота:  |  Размер: 76 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 631 B

После

Ширина:  |  Высота:  |  Размер: 631 B

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 3.6 KiB

После

Ширина:  |  Высота:  |  Размер: 3.6 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 3.4 KiB

После

Ширина:  |  Высота:  |  Размер: 3.4 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 3.8 KiB

После

Ширина:  |  Высота:  |  Размер: 3.8 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 3.6 KiB

После

Ширина:  |  Высота:  |  Размер: 3.6 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 2.5 KiB

После

Ширина:  |  Высота:  |  Размер: 2.5 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 5.0 KiB

После

Ширина:  |  Высота:  |  Размер: 5.0 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 5.0 KiB

После

Ширина:  |  Высота:  |  Размер: 5.0 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 3.0 KiB

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 2.8 KiB

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 25 KiB

После

Ширина:  |  Высота:  |  Размер: 25 KiB

Просмотреть файл

@ -15,7 +15,7 @@ window.addEventListener("load", function() {
// Timeout for the subscribe XHR.
const REQUEST_TIMEOUT = 5000;
const ABOUTDEVTOOLS_STRINGS = "chrome://devtools-shim/locale/aboutdevtools.properties";
const ABOUTDEVTOOLS_STRINGS = "chrome://devtools-startup/locale/aboutdevtools.properties";
const aboutDevtoolsBundle = Services.strings.createBundle(ABOUTDEVTOOLS_STRINGS);
let emailInput = document.getElementById("email");

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше