Merge mozilla-central to inbound. a=merge CLOSED TREE
|
@ -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");
|