mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Merge m-c to graphics
MozReview-Commit-ID: 5zsIClrx1FB
This commit is contained in:
commit
2e1380aecf
10
.cron.yml
10
.cron.yml
@ -21,6 +21,16 @@ jobs:
|
||||
mozilla-aurora: [{hour: 7, minute: 45}] # Buildbot uses minute 40
|
||||
# No default
|
||||
|
||||
- name: nightly-desktop-osx
|
||||
job:
|
||||
type: decision-task
|
||||
treeherder-symbol: Nd-OSX
|
||||
triggered-by: nightly
|
||||
target-tasks-method: nightly_macosx
|
||||
run-on-projects:
|
||||
- date
|
||||
when: [] # never (hook only)
|
||||
|
||||
- name: nightly-android
|
||||
job:
|
||||
type: decision-task
|
||||
|
@ -4,6 +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/. */
|
||||
|
||||
#include "mozilla-config.h"
|
||||
#include "AccessibleHandler.h"
|
||||
|
||||
import "ocidl.idl";
|
||||
|
@ -20,7 +20,7 @@ export:: $(MIDL_GENERATED_FILES)
|
||||
$(MIDL_GENERATED_FILES): midl_done
|
||||
|
||||
midl_done: HandlerData.acf HandlerData.idl
|
||||
$(MIDL) $(MIDL_FLAGS) $(DEFINES) -I $(IA2DIR) -I $(MSAADIR) -Oicf -acf $(srcdir)/HandlerData.acf $(srcdir)/HandlerData.idl
|
||||
$(MIDL) $(MIDL_FLAGS) $(DEFINES) -I $(topobjdir) -I $(DIST)/include -I $(IA2DIR) -I $(MSAADIR) -Oicf -acf $(srcdir)/HandlerData.acf $(srcdir)/HandlerData.idl
|
||||
touch $@
|
||||
|
||||
INSTALL_TARGETS += midl
|
||||
|
@ -1613,6 +1613,9 @@ pref("browser.formautofill.experimental", false);
|
||||
pref("browser.formautofill.enabled", false);
|
||||
pref("browser.formautofill.loglevel", "Warn");
|
||||
|
||||
// Whether or not to restore a session with lazy-browser tabs.
|
||||
pref("browser.sessionstore.restore_tabs_lazily", true);
|
||||
|
||||
// Enable safebrowsing v4 tables (suffixed by "-proto") update.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("urlclassifier.malwareTable", "goog-malware-shavar,goog-unwanted-shavar,goog-malware-proto,goog-unwanted-proto,test-malware-simple,test-unwanted-simple");
|
||||
|
@ -636,7 +636,8 @@ var FullScreen = {
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarIconColor.inferFromText();
|
||||
ToolbarIconColor.inferFromText("fullscreen", aEnterFS);
|
||||
|
||||
|
||||
// For Lion fullscreen, all fullscreen controls are hidden, don't
|
||||
// bother to touch them. If we don't stop here, the following code
|
||||
|
@ -247,7 +247,8 @@ var TabsInTitlebar = {
|
||||
menubar.style.paddingBottom = "";
|
||||
}
|
||||
|
||||
ToolbarIconColor.inferFromText();
|
||||
ToolbarIconColor.inferFromText("tabsintitlebar", TabsInTitlebar.enabled);
|
||||
|
||||
if (CustomizationHandler.isCustomizing()) {
|
||||
gCustomizeMode.updateLWTStyling();
|
||||
}
|
||||
|
@ -5408,8 +5408,6 @@ function setToolbarVisibility(toolbar, isVisible, persist = true) {
|
||||
|
||||
PlacesToolbarHelper.init();
|
||||
BookmarkingUI.onToolbarVisibilityChange();
|
||||
if (isVisible)
|
||||
ToolbarIconColor.inferFromText();
|
||||
}
|
||||
|
||||
var TabletModeUpdater = {
|
||||
@ -7686,7 +7684,7 @@ var gIdentityHandler = {
|
||||
let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
|
||||
button.setAttribute("tooltiptext", tooltiptext);
|
||||
button.addEventListener("command", () => {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
// Only resize the window if the reload hint was previously hidden.
|
||||
this._handleHeightChange(() => this._permissionList.removeChild(container),
|
||||
this._permissionReloadHint.hasAttribute("hidden"));
|
||||
@ -8219,8 +8217,8 @@ var MousePosTracker = {
|
||||
|
||||
handleEvent(event) {
|
||||
var fullZoom = this._windowUtils.fullZoom;
|
||||
this._x = event.clientX / fullZoom;
|
||||
this._y = event.clientY / fullZoom;
|
||||
this._x = event.screenX / fullZoom - window.mozInnerScreenX;
|
||||
this._y = event.screenY / fullZoom - window.mozInnerScreenY;
|
||||
|
||||
this._listeners.forEach(function(listener) {
|
||||
try {
|
||||
@ -8253,18 +8251,25 @@ var MousePosTracker = {
|
||||
};
|
||||
|
||||
var ToolbarIconColor = {
|
||||
_windowState: {
|
||||
"active": false,
|
||||
"fullscreen": false,
|
||||
"tabsintitlebar": false
|
||||
},
|
||||
init() {
|
||||
this._initialized = true;
|
||||
|
||||
window.addEventListener("activate", this);
|
||||
window.addEventListener("deactivate", this);
|
||||
window.addEventListener("toolbarvisibilitychange", this);
|
||||
Services.obs.addObserver(this, "lightweight-theme-styling-update");
|
||||
|
||||
// If the window isn't active now, we assume that it has never been active
|
||||
// before and will soon become active such that inferFromText will be
|
||||
// called from the initial activate event.
|
||||
if (Services.focus.activeWindow == window)
|
||||
this.inferFromText();
|
||||
if (Services.focus.activeWindow == window) {
|
||||
this.inferFromText("activate");
|
||||
}
|
||||
},
|
||||
|
||||
uninit() {
|
||||
@ -8272,14 +8277,18 @@ var ToolbarIconColor = {
|
||||
|
||||
window.removeEventListener("activate", this);
|
||||
window.removeEventListener("deactivate", this);
|
||||
window.removeEventListener("toolbarvisibilitychange", this);
|
||||
Services.obs.removeObserver(this, "lightweight-theme-styling-update");
|
||||
},
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "activate":
|
||||
case "activate": // falls through
|
||||
case "deactivate":
|
||||
this.inferFromText();
|
||||
this.inferFromText(event.type);
|
||||
break;
|
||||
case "toolbarvisibilitychange":
|
||||
this.inferFromText(event.type, event.visible);
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -8289,32 +8298,66 @@ var ToolbarIconColor = {
|
||||
case "lightweight-theme-styling-update":
|
||||
// inferFromText needs to run after LightweightThemeConsumer.jsm's
|
||||
// lightweight-theme-styling-update observer.
|
||||
setTimeout(() => { this.inferFromText(); }, 0);
|
||||
setTimeout(() => {
|
||||
this.inferFromText(aTopic);
|
||||
}, 0);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
inferFromText() {
|
||||
// a cache of luminance values for each toolbar
|
||||
// to avoid unnecessary calls to getComputedStyle
|
||||
_toolbarLuminanceCache: new Map(),
|
||||
|
||||
inferFromText(reason, reasonValue) {
|
||||
if (!this._initialized)
|
||||
return;
|
||||
|
||||
function parseRGB(aColorString) {
|
||||
let rgb = aColorString.match(/^rgba?\((\d+), (\d+), (\d+)/);
|
||||
rgb.shift();
|
||||
return rgb.map(x => parseInt(x));
|
||||
}
|
||||
|
||||
switch (reason) {
|
||||
case "activate": // falls through
|
||||
case "deactivate":
|
||||
this._windowState.active = (reason === "activate");
|
||||
break;
|
||||
case "fullscreen":
|
||||
this._windowState.fullscreen = reasonValue;
|
||||
break;
|
||||
case "lightweight-theme-styling-update":
|
||||
// theme change, we'll need to recalculate all color values
|
||||
this._toolbarLuminanceCache.clear();
|
||||
break;
|
||||
case "toolbarvisibilitychange":
|
||||
// toolbar changes dont require reset of the cached color values
|
||||
break;
|
||||
case "tabsintitlebar":
|
||||
this._windowState.tabsintitlebar = reasonValue;
|
||||
break;
|
||||
}
|
||||
|
||||
let toolbarSelector = "#navigator-toolbox > toolbar:not([collapsed=true]):not(#addon-bar)";
|
||||
if (AppConstants.platform == "macosx")
|
||||
toolbarSelector += ":not([type=menubar])";
|
||||
|
||||
// The getComputedStyle calls and setting the brighttext are separated in
|
||||
// two loops to avoid flushing layout and making it dirty repeatedly.
|
||||
|
||||
let luminances = new Map;
|
||||
let cachedLuminances = this._toolbarLuminanceCache;
|
||||
let luminances = new Map();
|
||||
for (let toolbar of document.querySelectorAll(toolbarSelector)) {
|
||||
let [r, g, b] = parseRGB(getComputedStyle(toolbar).color);
|
||||
let luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b;
|
||||
// toolbars *should* all have ids, but guard anyway to avoid blowing up
|
||||
let cacheKey = toolbar.id && toolbar.id + JSON.stringify(this._windowState);
|
||||
// lookup cached luminance value for this toolbar in this window state
|
||||
let luminance = cacheKey && cachedLuminances.get(cacheKey);
|
||||
if (isNaN(luminance)) {
|
||||
let [r, g, b] = parseRGB(getComputedStyle(toolbar).color);
|
||||
luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b;
|
||||
if (cacheKey) {
|
||||
cachedLuminances.set(cacheKey, luminance);
|
||||
}
|
||||
}
|
||||
luminances.set(toolbar, luminance);
|
||||
}
|
||||
|
||||
|
@ -2034,7 +2034,8 @@
|
||||
"addProgressListener", "removeProgressListener", "audioPlaybackStarted",
|
||||
"audioPlaybackStopped", "adjustPriority", "pauseMedia", "stopMedia",
|
||||
"blockMedia", "resumeMedia", "mute", "unmute", "blockedPopups", "lastURI",
|
||||
"purgeSessionHistory", "stopScroll", "startScroll"
|
||||
"purgeSessionHistory", "stopScroll", "startScroll",
|
||||
"userTypedValue", "userTypedClear"
|
||||
]</field>
|
||||
|
||||
<method name="_createLazyBrowser">
|
||||
@ -2052,11 +2053,51 @@
|
||||
switch (name) {
|
||||
case "permitUnload":
|
||||
getter = () => {
|
||||
return function() {
|
||||
return () => {
|
||||
return { permitUnload: true, timedOut: false };
|
||||
};
|
||||
};
|
||||
break;
|
||||
case "reload":
|
||||
case "reloadWithFlags":
|
||||
getter = () => {
|
||||
return (params) => {
|
||||
// Wait for load handler to be instantiated before
|
||||
// initializing the reload.
|
||||
aTab.addEventListener("SSTabRestoring", () => {
|
||||
browser[name](params);
|
||||
}, { once: true });
|
||||
gBrowser._insertBrowser(aTab);
|
||||
};
|
||||
};
|
||||
break;
|
||||
case "isRemoteBrowser":
|
||||
getter = () => {
|
||||
return browser.getAttribute("remote") == "true";
|
||||
};
|
||||
break;
|
||||
case "audioMuted":
|
||||
getter = () => {
|
||||
return false;
|
||||
};
|
||||
break;
|
||||
case "currentURI":
|
||||
getter = () => {
|
||||
let url = SessionStore.getLazyTabValue(aTab, "url");
|
||||
return Services.io.newURI(url);
|
||||
};
|
||||
break;
|
||||
case "contentTitle":
|
||||
getter = () => {
|
||||
return SessionStore.getLazyTabValue(aTab, "title");
|
||||
};
|
||||
break;
|
||||
case "userTypedValue":
|
||||
case "userTypedClear":
|
||||
getter = () => {
|
||||
return SessionStore.getLazyTabValue(aTab, name);
|
||||
};
|
||||
break;
|
||||
default:
|
||||
getter = () => {
|
||||
this._insertBrowser(aTab);
|
||||
@ -2084,9 +2125,8 @@
|
||||
<![CDATA[
|
||||
"use strict";
|
||||
|
||||
// If browser is already inserted, or aTab doesn't have a
|
||||
// browser, don't do anything.
|
||||
if (aTab.linkedPanel || !aTab.linkedBrowser) {
|
||||
// If browser is already inserted don't do anything.
|
||||
if (aTab.linkedPanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4876,7 +4916,8 @@
|
||||
tab.linkedBrowser &&
|
||||
tab.linkedBrowser.isRemoteBrowser) {
|
||||
label += " - e10s";
|
||||
if (Services.appinfo.maxWebProcessCount > 1) {
|
||||
if (tab.linkedBrowser.frameLoader &&
|
||||
Services.appinfo.maxWebProcessCount > 1) {
|
||||
label += " (" + tab.linkedBrowser.frameLoader.tabParent.osPid + ")";
|
||||
}
|
||||
}
|
||||
@ -7245,6 +7286,11 @@
|
||||
<parameter name="aMuteReason"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
// Do not attempt to toggle mute state if browser is lazy.
|
||||
if (!this.linkedPanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tabContainer = this.parentNode;
|
||||
let browser = this.linkedBrowser;
|
||||
let modifiedAttrs = [];
|
||||
|
@ -254,8 +254,6 @@ var whitelist = new Set([
|
||||
{file: "resource://gre/modules/addons/AddonLogging.jsm"},
|
||||
// Bug 1351637
|
||||
{file: "resource://gre/modules/sdk/bootstrap.js"},
|
||||
// Bug 1351657
|
||||
{file: "resource://gre/res/langGroups.properties", platforms: ["macosx"]},
|
||||
|
||||
].filter(item =>
|
||||
("isFromDevTools" in item) == isDevtools &&
|
||||
|
7
browser/base/content/test/windows/.eslintrc.js
Normal file
7
browser/base/content/test/windows/.eslintrc.js
Normal file
@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"plugin:mozilla/browser-test"
|
||||
]
|
||||
};
|
2
browser/base/content/test/windows/browser.ini
Normal file
2
browser/base/content/test/windows/browser.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[DEFAULT]
|
||||
[browser_toolbariconcolor_restyles.js]
|
@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Ensure redundant style flushes are not triggered when switching between windows
|
||||
*/
|
||||
add_task(function* test_toolbar_element_restyles_on_activation() {
|
||||
let restyles = {
|
||||
win1: {},
|
||||
win2: {}
|
||||
};
|
||||
|
||||
// create a window and snapshot the elementsStyled
|
||||
let win1 = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
yield new Promise(resolve => waitForFocus(resolve, win1));
|
||||
|
||||
// create a 2nd window and snapshot the elementsStyled
|
||||
let win2 = yield BrowserTestUtils.openNewBrowserWindow();
|
||||
yield new Promise(resolve => waitForFocus(resolve, win2));
|
||||
|
||||
let utils1 = SpecialPowers.getDOMWindowUtils(win1);
|
||||
restyles.win1.initial = utils1.elementsRestyled;
|
||||
|
||||
let utils2 = SpecialPowers.getDOMWindowUtils(win2);
|
||||
restyles.win2.initial = utils2.elementsRestyled;
|
||||
|
||||
// switch back to 1st window, and snapshot elementsStyled
|
||||
win1.focus();
|
||||
restyles.win1.activate = utils1.elementsRestyled;
|
||||
restyles.win2.deactivate = utils2.elementsRestyled;
|
||||
|
||||
// switch back to 2nd window, and snapshot elementsStyled
|
||||
win2.focus();
|
||||
restyles.win2.activate = utils2.elementsRestyled;
|
||||
restyles.win1.deactivate = utils1.elementsRestyled;
|
||||
|
||||
is(restyles.win1.activate - restyles.win1.deactivate, 0,
|
||||
"No elements restyled when re-activating/deactivating a window");
|
||||
is(restyles.win2.activate - restyles.win2.deactivate, 0,
|
||||
"No elements restyled when re-activating/deactivating a window");
|
||||
|
||||
yield BrowserTestUtils.closeWindow(win1);
|
||||
yield BrowserTestUtils.closeWindow(win2);
|
||||
});
|
@ -35,6 +35,7 @@ BROWSER_CHROME_MANIFESTS += [
|
||||
'content/test/urlbar/browser.ini',
|
||||
'content/test/webextensions/browser.ini',
|
||||
'content/test/webrtc/browser.ini',
|
||||
'content/test/windows/browser.ini',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_UPDATER']:
|
||||
|
@ -1492,7 +1492,8 @@ var CustomizableUIInternal = {
|
||||
let anchor = aNode;
|
||||
if (area != CustomizableUI.AREA_PANEL) {
|
||||
let wrapper = this.wrapWidget(aWidget.id).forWindow(ownerWindow);
|
||||
if (wrapper && wrapper.anchor) {
|
||||
|
||||
if (wrapper && !wrapper.overflowed && wrapper.anchor) {
|
||||
this.hidePanelForNode(aNode);
|
||||
anchor = wrapper.anchor;
|
||||
}
|
||||
@ -4118,7 +4119,9 @@ OverflowableToolbar.prototype = {
|
||||
return new Promise(resolve => {
|
||||
let doc = this._panel.ownerDocument;
|
||||
this._panel.hidden = false;
|
||||
let contextMenu = doc.getElementById(this._panel.getAttribute("context"));
|
||||
let mainViewId = this._panel.querySelector("panelmultiview").getAttribute("mainViewId");
|
||||
let mainView = doc.getElementById(mainViewId);
|
||||
let contextMenu = doc.getElementById(mainView.getAttribute("context"));
|
||||
gELS.addSystemEventListener(contextMenu, "command", this, true);
|
||||
let anchor = doc.getAnonymousElementByAttribute(this._chevron, "class", "toolbarbutton-icon");
|
||||
this._panel.openPopup(anchor || this._chevron);
|
||||
|
@ -377,13 +377,17 @@
|
||||
role="group"
|
||||
type="arrow"
|
||||
noautofocus="true"
|
||||
context="toolbar-context-menu"
|
||||
position="bottomcenter topright"
|
||||
hidden="true">
|
||||
<vbox id="widget-overflow-scroller">
|
||||
<vbox id="widget-overflow-list" class="widget-overflow-list"
|
||||
overflowfortoolbar="nav-bar"/>
|
||||
</vbox>
|
||||
<panelmultiview mainViewId="widget-overflow-mainView">
|
||||
<panelview id="widget-overflow-mainView"
|
||||
context="toolbar-context-menu">
|
||||
<vbox id="widget-overflow-scroller">
|
||||
<vbox id="widget-overflow-list" class="widget-overflow-list"
|
||||
overflowfortoolbar="nav-bar"/>
|
||||
</vbox>
|
||||
</panelview>
|
||||
</panelmultiview>
|
||||
</panel>
|
||||
|
||||
<panel id="customization-tipPanel"
|
||||
|
@ -431,8 +431,9 @@ const PanelUI = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aPlacementArea == CustomizableUI.AREA_PANEL) {
|
||||
this.multiView.showSubView(aViewId, aAnchor);
|
||||
let container = aAnchor.closest("panelmultiview");
|
||||
if (container) {
|
||||
container.showSubView(aViewId, aAnchor);
|
||||
} else if (!aAnchor.open) {
|
||||
aAnchor.open = true;
|
||||
|
||||
|
@ -178,6 +178,14 @@
|
||||
<body><![CDATA[
|
||||
Task.spawn(function*() {
|
||||
let viewNode = this.querySelector("#" + aViewId);
|
||||
if (!viewNode) {
|
||||
viewNode = document.getElementById(aViewId);
|
||||
if (viewNode) {
|
||||
this._subViews.appendChild(viewNode);
|
||||
} else {
|
||||
throw new Error(`Subview ${aViewId} doesn't exist!`);
|
||||
}
|
||||
}
|
||||
viewNode.setAttribute("current", true);
|
||||
// Emit the ViewShowing event so that the widget definition has a chance
|
||||
// to lazily populate the subview with things.
|
||||
|
@ -149,6 +149,7 @@ skip-if = os == "mac"
|
||||
[browser_bootstrapped_custom_toolbar.js]
|
||||
[browser_customizemode_contextmenu_menubuttonstate.js]
|
||||
[browser_exit_background_customize_mode.js]
|
||||
[browser_overflow_use_subviews.js]
|
||||
[browser_panel_toggle.js]
|
||||
[browser_panelUINotifications.js]
|
||||
[browser_switch_to_customize_mode.js]
|
||||
|
@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
|
||||
const kOverflowPanel = document.getElementById("widget-overflow");
|
||||
|
||||
var gOriginalWidth;
|
||||
registerCleanupFunction(function*() {
|
||||
kOverflowPanel.removeAttribute("animate");
|
||||
window.resizeTo(gOriginalWidth, window.outerHeight);
|
||||
CustomizableUI.reset();
|
||||
});
|
||||
|
||||
/**
|
||||
* This checks that subview-compatible items show up as subviews rather than
|
||||
* re-anchored panels. If we ever remove the character encoding widget, please
|
||||
* replace this test with another subview - don't remove it.
|
||||
*/
|
||||
add_task(async function check_character_encoding_subview_in_overflow() {
|
||||
kOverflowPanel.setAttribute("animate", "false");
|
||||
gOriginalWidth = window.outerWidth;
|
||||
|
||||
CustomizableUI.addWidgetToArea("developer-button", CustomizableUI.AREA_NAVBAR);
|
||||
|
||||
let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
|
||||
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
|
||||
window.resizeTo(400, window.outerHeight);
|
||||
|
||||
await waitForCondition(() => navbar.hasAttribute("overflowing"));
|
||||
|
||||
let chevron = document.getElementById("nav-bar-overflow-button");
|
||||
let shownPanelPromise = promisePanelElementShown(window, kOverflowPanel);
|
||||
chevron.click();
|
||||
await shownPanelPromise;
|
||||
|
||||
let developerView = document.getElementById("PanelUI-developer");
|
||||
let button = document.getElementById("developer-button");
|
||||
let subviewShownPromise = subviewShown(developerView);
|
||||
button.click();
|
||||
await subviewShownPromise;
|
||||
is(developerView.closest("panel"), kOverflowPanel, "Should be inside the panel");
|
||||
kOverflowPanel.hidePopup();
|
||||
await Promise.resolve(); // wait for popup to hide fully.
|
||||
|
||||
CustomizableUI.reset();
|
||||
});
|
||||
|
||||
/**
|
||||
* This checks that non-subview-compatible items still work correctly.
|
||||
* Ideally we should make the downloads panel and bookmarks/library item
|
||||
* proper subview items, then this test can go away, and potentially we can
|
||||
* simplify some of the subview anchoring code.
|
||||
*/
|
||||
add_task(async function check_downloads_panel_in_overflow() {
|
||||
let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
|
||||
ok(navbar.hasAttribute("overflowing"), "Should still be overflowing");
|
||||
let chevron = document.getElementById("nav-bar-overflow-button");
|
||||
let shownPanelPromise = promisePanelElementShown(window, kOverflowPanel);
|
||||
chevron.click();
|
||||
await shownPanelPromise;
|
||||
|
||||
let button = document.getElementById("downloads-button");
|
||||
button.click();
|
||||
await waitForCondition(() => {
|
||||
let panel = document.getElementById("downloadsPanel");
|
||||
return panel && panel.state != "closed";
|
||||
});
|
||||
let downloadsPanel = document.getElementById("downloadsPanel");
|
||||
isnot(downloadsPanel.state, "closed", "Should be attempting to show the downloads panel.");
|
||||
downloadsPanel.hidePopup();
|
||||
});
|
@ -1859,7 +1859,7 @@ BrowserGlue.prototype = {
|
||||
|
||||
Services.prefs.clearUserPref("browser.tabs.animate");
|
||||
Services.prefs.clearUserPref("browser.fullscreen.animate");
|
||||
Services.prefs.clearUserPref("browser.tabs.animate");
|
||||
Services.prefs.clearUserPref("alerts.disableSlidingEffect");
|
||||
}
|
||||
|
||||
// Update the migration version.
|
||||
|
@ -334,6 +334,10 @@ this.SessionStore = {
|
||||
SessionStoreInternal.deleteTabValue(aTab, aKey);
|
||||
},
|
||||
|
||||
getLazyTabValue(aTab, aKey) {
|
||||
return SessionStoreInternal.getLazyTabValue(aTab, aKey);
|
||||
},
|
||||
|
||||
getGlobalValue: function ss_getGlobalValue(aKey) {
|
||||
return SessionStoreInternal.getGlobalValue(aKey);
|
||||
},
|
||||
@ -1871,6 +1875,15 @@ var SessionStoreInternal = {
|
||||
if (browser.frameLoader) {
|
||||
this._lastKnownFrameLoader.set(browser.permanentKey, browser.frameLoader);
|
||||
}
|
||||
|
||||
// Only restore if browser has been lazy.
|
||||
if (aTab.__SS_lazyData && !browser.__SS_restoreState && TabStateCache.get(browser)) {
|
||||
let tabState = TabState.clone(aTab);
|
||||
this.restoreTab(aTab, tabState);
|
||||
}
|
||||
|
||||
// The browser has been inserted now, so lazy data is no longer relevant.
|
||||
delete aTab.__SS_lazyData;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2545,6 +2558,19 @@ var SessionStoreInternal = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves data specific to lazy-browser tabs. If tab is not lazy,
|
||||
* will return undefined.
|
||||
*
|
||||
* @param aTab (xul:tab)
|
||||
* The tabbrowser-tab the data is for.
|
||||
* @param aKey (string)
|
||||
* The key which maps to the desired data.
|
||||
*/
|
||||
getLazyTabValue(aTab, aKey) {
|
||||
return (aTab.__SS_lazyData || {})[aKey];
|
||||
},
|
||||
|
||||
getGlobalValue: function ssi_getGlobalValue(aKey) {
|
||||
return this._globalState.get(aKey);
|
||||
},
|
||||
@ -3272,6 +3298,9 @@ var SessionStoreInternal = {
|
||||
|
||||
let numVisibleTabs = 0;
|
||||
|
||||
let createLazyBrowser = this._prefBranch.getBoolPref("sessionstore.restore_tabs_lazily") &&
|
||||
this._prefBranch.getBoolPref("sessionstore.restore_on_demand");
|
||||
|
||||
for (var t = 0; t < newTabCount; t++) {
|
||||
// When trying to restore into existing tab, we also take the userContextId
|
||||
// into account if present.
|
||||
@ -3280,7 +3309,8 @@ var SessionStoreInternal = {
|
||||
(tabbrowser.tabs[t].getAttribute("usercontextid") == (userContextId || ""));
|
||||
let tab = reuseExisting ? this._maybeUpdateBrowserRemoteness(tabbrowser.tabs[t])
|
||||
: tabbrowser.addTab("about:blank",
|
||||
{ skipAnimation: true,
|
||||
{ createLazyBrowser,
|
||||
skipAnimation: true,
|
||||
userContextId,
|
||||
skipBackgroundNotify: true });
|
||||
|
||||
@ -3595,9 +3625,7 @@ var SessionStoreInternal = {
|
||||
tabbrowser.selectedBrowser == browser ||
|
||||
loadArguments;
|
||||
|
||||
if (!willRestoreImmediately && !forceOnDemand) {
|
||||
TabRestoreQueue.add(tab);
|
||||
}
|
||||
let isBrowserInserted = browser.isConnected;
|
||||
|
||||
// Increase the busy state counter before modifying the tab.
|
||||
this._setWindowStateBusy(window);
|
||||
@ -3665,14 +3693,6 @@ var SessionStoreInternal = {
|
||||
// Save the index in case we updated it above.
|
||||
tabData.index = activeIndex + 1;
|
||||
|
||||
// Start a new epoch to discard all frame script messages relating to a
|
||||
// previous epoch. All async messages that are still on their way to chrome
|
||||
// will be ignored and don't override any tab data set when restoring.
|
||||
let epoch = this.startNextEpoch(browser);
|
||||
|
||||
// keep the data around to prevent dataloss in case
|
||||
// a tab gets closed before it's been properly restored
|
||||
browser.__SS_restoreState = TAB_STATE_NEEDS_RESTORE;
|
||||
browser.setAttribute("pending", "true");
|
||||
tab.setAttribute("pending", "true");
|
||||
|
||||
@ -3700,26 +3720,57 @@ var SessionStoreInternal = {
|
||||
userTypedClear: tabData.userTypedClear || 0
|
||||
});
|
||||
|
||||
this._sendRestoreHistory(browser, {tabData, epoch, loadArguments});
|
||||
|
||||
// Update tab label and icon to show something
|
||||
// while we wait for the messages to be processed.
|
||||
this.updateTabLabelAndIcon(tab, tabData);
|
||||
|
||||
// Restore tab attributes.
|
||||
if ("attributes" in tabData) {
|
||||
TabAttributes.set(tab, tabData.attributes);
|
||||
}
|
||||
|
||||
// This could cause us to ignore MAX_CONCURRENT_TAB_RESTORES a bit, but
|
||||
// it ensures each window will have its selected tab loaded.
|
||||
if (willRestoreImmediately) {
|
||||
this.restoreTabContent(tab, loadArguments, reloadInFreshProcess,
|
||||
restoreContentReason);
|
||||
} else if (!forceOnDemand) {
|
||||
this.restoreNextTab();
|
||||
if (isBrowserInserted) {
|
||||
// Start a new epoch to discard all frame script messages relating to a
|
||||
// previous epoch. All async messages that are still on their way to chrome
|
||||
// will be ignored and don't override any tab data set when restoring.
|
||||
let epoch = this.startNextEpoch(browser);
|
||||
|
||||
// Ensure that the tab will get properly restored in the event the tab
|
||||
// crashes while restoring. But don't set this on lazy browsers as
|
||||
// restoreTab will get called again when the browser is instantiated.
|
||||
browser.__SS_restoreState = TAB_STATE_NEEDS_RESTORE;
|
||||
|
||||
this._sendRestoreHistory(browser, {tabData, epoch, loadArguments});
|
||||
|
||||
// This could cause us to ignore MAX_CONCURRENT_TAB_RESTORES a bit, but
|
||||
// it ensures each window will have its selected tab loaded.
|
||||
if (willRestoreImmediately) {
|
||||
this.restoreTabContent(tab, loadArguments, reloadInFreshProcess,
|
||||
restoreContentReason);
|
||||
} else if (!forceOnDemand) {
|
||||
TabRestoreQueue.add(tab);
|
||||
this.restoreNextTab();
|
||||
}
|
||||
} else {
|
||||
// __SS_lazyData holds data for lazy-browser tabs to proxy for
|
||||
// data unobtainable from the unbound browser. This only applies to lazy
|
||||
// browsers and will be removed once the browser is inserted in the document.
|
||||
// This must preceed `updateTabLabelAndIcon` call for required data to be present.
|
||||
let url = "about:blank";
|
||||
let title = "";
|
||||
|
||||
if (activeIndex in tabData.entries) {
|
||||
url = tabData.entries[activeIndex].url;
|
||||
title = tabData.entries[activeIndex].title || url;
|
||||
}
|
||||
tab.__SS_lazyData = {
|
||||
url,
|
||||
title,
|
||||
userTypedValue: tabData.userTypedValue || "",
|
||||
userTypedClear: tabData.userTypedClear || 0
|
||||
};
|
||||
}
|
||||
|
||||
// Update tab label and icon to show something
|
||||
// while we wait for the messages to be processed.
|
||||
this.updateTabLabelAndIcon(tab, tabData);
|
||||
|
||||
// Decrease the busy state counter after we're done.
|
||||
this._setWindowStateReady(window);
|
||||
},
|
||||
|
@ -32,11 +32,27 @@ function test() {
|
||||
"We still know that no load is ongoing");
|
||||
is(gURLBar.value, "example.com",
|
||||
"Address bar's value correctly restored");
|
||||
// Change tabs to make sure address bar value gets updated
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.getItemAtIndex(0);
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
|
||||
// Change tabs to make sure address bar value gets updated. If tab is
|
||||
// lazy, wait for SSTabRestored to ensure address bar has time to update.
|
||||
let tabToSelect = gBrowser.tabContainer.getItemAtIndex(0);
|
||||
if (tabToSelect.linkedBrowser.isConnected) {
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
} else {
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored",
|
||||
function SSTabRestored(event) {
|
||||
if (event.target == tabToSelect) {
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", SSTabRestored, true);
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
}
|
||||
}, true);
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -60,15 +76,34 @@ function test() {
|
||||
"No history entries still sets currentURI to about:blank");
|
||||
is(browser.userTypedValue, "example.org",
|
||||
"userTypedValue was correctly restored");
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"We still know that no load is ongoing");
|
||||
// didStartLoadSinceLastUserTyping does not exist on lazy tabs.
|
||||
if (browser.didStartLoadSinceLastUserTyping) {
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"We still know that no load is ongoing");
|
||||
}
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly restored");
|
||||
// Change tabs to make sure address bar value gets updated
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.getItemAtIndex(1);
|
||||
is(gURLBar.value, "example.org",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
|
||||
// Change tabs to make sure address bar value gets updated. If tab is
|
||||
// lazy, wait for SSTabRestored to ensure address bar has time to update.
|
||||
let tabToSelect = gBrowser.tabContainer.getItemAtIndex(1);
|
||||
if (tabToSelect.linkedBrowser.isConnected) {
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
is(gURLBar.value, "example.org",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
} else {
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored",
|
||||
function SSTabRestored(event) {
|
||||
if (event.target == tabToSelect) {
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", SSTabRestored, true);
|
||||
is(gURLBar.value, "example.org",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
}
|
||||
}, true);
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,9 @@
|
||||
var stateBackup = ss.getBrowserState();
|
||||
|
||||
function cleanup() {
|
||||
// Reset the pref
|
||||
try {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
} catch (e) {}
|
||||
// Reset the prefs
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_tabs_lazily");
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
}
|
||||
@ -20,6 +19,8 @@ function test() {
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
// Don't restore tabs lazily.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_tabs_lazily", false);
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org/#1", triggeringPrincipal_base64 }] },
|
||||
|
@ -9,6 +9,8 @@ add_task(function* () {
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
// Don't restore tabs lazily.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_tabs_lazily", false);
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org#1", triggeringPrincipal_base64 }], extData: { "uniq": r() } },
|
||||
@ -92,5 +94,7 @@ add_task(function* () {
|
||||
yield progressCallback();
|
||||
|
||||
// Cleanup.
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_tabs_lazily");
|
||||
yield promiseBrowserState(stateBackup);
|
||||
});
|
||||
|
@ -97,22 +97,26 @@ function test_setTabState() {
|
||||
ss.setTabValue(tab, "baz", "qux");
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(tab, "baz"), "qux");
|
||||
is(tab.linkedBrowser.currentURI.spec, "http://example.org/");
|
||||
function onSSTabRestoring(aEvent) {
|
||||
if (aEvent.target == tab) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(tab, "baz"), "qux");
|
||||
is(tab.linkedBrowser.currentURI.spec, "http://example.org/");
|
||||
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored);
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestoring", onSSTabRestoring);
|
||||
|
||||
runNextTest();
|
||||
runNextTest();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.addEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestoring", onSSTabRestoring);
|
||||
// Browser must be inserted in order to restore.
|
||||
gBrowser._insertBrowser(tab);
|
||||
ss.setTabState(tab, newTabState);
|
||||
}
|
||||
|
||||
@ -137,23 +141,26 @@ function test_duplicateTab() {
|
||||
ss.setTabValue(newTab, "baz", "qux");
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(newTab, "baz"), "qux");
|
||||
is(newTab.linkedBrowser.currentURI.spec, "about:rights");
|
||||
function onSSTabRestoring(aEvent) {
|
||||
if (aEvent.target == newTab) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(newTab, "baz"), "qux");
|
||||
is(newTab.linkedBrowser.currentURI.spec, "about:rights");
|
||||
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored);
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestoring", onSSTabRestoring);
|
||||
|
||||
runNextTest();
|
||||
runNextTest();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.addEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestoring", onSSTabRestoring);
|
||||
|
||||
gBrowser._insertBrowser(tab);
|
||||
newTab = ss.duplicateTab(window, tab);
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,6 @@ add_task(function* test_scroll_background_tabs() {
|
||||
|
||||
// The second tab should be the one we loaded URL at still
|
||||
tab = newWin.gBrowser.tabs[1];
|
||||
yield promiseTabRestoring(tab);
|
||||
|
||||
ok(tab.hasAttribute("pending"), "Tab should be pending");
|
||||
browser = tab.linkedBrowser;
|
||||
|
@ -47,7 +47,6 @@ add_task(function* test_scroll_background_about_reader_tabs() {
|
||||
|
||||
// The second tab should be the one we loaded URL at still
|
||||
tab = newWin.gBrowser.tabs[1];
|
||||
yield promiseTabRestoring(tab);
|
||||
|
||||
ok(tab.hasAttribute("pending"), "Tab should be pending");
|
||||
browser = tab.linkedBrowser;
|
||||
|
@ -94,18 +94,24 @@ function waitForBrowserState(aState, aSetStateCallback) {
|
||||
let windowObserving = false;
|
||||
let restoreHiddenTabs = Services.prefs.getBoolPref(
|
||||
"browser.sessionstore.restore_hidden_tabs");
|
||||
let restoreTabsLazily = Services.prefs.getBoolPref(
|
||||
"browser.sessionstore.restore_tabs_lazily");
|
||||
|
||||
aState.windows.forEach(function(winState) {
|
||||
winState.tabs.forEach(function(tabState) {
|
||||
if (restoreHiddenTabs || !tabState.hidden)
|
||||
if (!restoreTabsLazily && (restoreHiddenTabs || !tabState.hidden))
|
||||
expectedTabsRestored++;
|
||||
});
|
||||
});
|
||||
|
||||
// There must be only hidden tabs and restoreHiddenTabs = false. We still
|
||||
// If there are only hidden tabs and restoreHiddenTabs = false, we still
|
||||
// expect one of them to be restored because it gets shown automatically.
|
||||
if (!expectedTabsRestored)
|
||||
// Otherwise if lazy tab restore there will only be one tab restored per window.
|
||||
if (!expectedTabsRestored) {
|
||||
expectedTabsRestored = 1;
|
||||
} else if (restoreTabsLazily) {
|
||||
expectedTabsRestored = aState.windows.length;
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
if (++tabsRestored == expectedTabsRestored) {
|
||||
@ -376,11 +382,11 @@ var gProgressListener = {
|
||||
for (let win of BrowserWindowIterator()) {
|
||||
for (let i = 0; i < win.gBrowser.tabs.length; i++) {
|
||||
let browser = win.gBrowser.tabs[i].linkedBrowser;
|
||||
if (!browser.__SS_restoreState)
|
||||
if (browser.isConnected && !browser.__SS_restoreState)
|
||||
wasRestored++;
|
||||
else if (browser.__SS_restoreState == TAB_STATE_RESTORING)
|
||||
isRestoring++;
|
||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE || !browser.isConnected)
|
||||
needsRestore++;
|
||||
}
|
||||
}
|
||||
|
3
browser/extensions/e10srollout/bootstrap.js
vendored
3
browser/extensions/e10srollout/bootstrap.js
vendored
@ -127,6 +127,7 @@ function defineCohort() {
|
||||
setCohort("optedOut");
|
||||
} else if (userOptedIn.e10s) {
|
||||
setCohort("optedIn");
|
||||
inMultiExperiment = true;
|
||||
} else if (temporaryDisqualification != "") {
|
||||
// Users who are disqualified by the backend (from multiprocessBlockPolicy)
|
||||
// can be put into either the test or control groups, because e10s will
|
||||
@ -185,7 +186,7 @@ function defineCohort() {
|
||||
let multiUserSample = getUserSample(true);
|
||||
for (let sampleName of Object.getOwnPropertyNames(BUCKETS)) {
|
||||
if (multiUserSample < BUCKETS[sampleName]) {
|
||||
setCohort(`${cohortPrefix}multiBucket${sampleName}`);
|
||||
setCohort(`multiBucket${sampleName}`);
|
||||
Preferences.set(PREF_E10S_PROCESSCOUNT + ".web", sampleName);
|
||||
break;
|
||||
}
|
||||
|
@ -10,7 +10,8 @@
|
||||
- loaded as a stacked subdialog. -->
|
||||
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css" />
|
||||
<link rel="stylesheet" href="chrome://browser/skin/preferences/in-content/dialog.css" />
|
||||
<link rel="stylesheet" href="chrome://formautofill/content/editProfile.css" />
|
||||
<link rel="stylesheet" href="chrome://formautofill-shared/skin/editProfile.css" />
|
||||
<link rel="stylesheet" href="chrome://formautofill/skin/editProfile.css" />
|
||||
<script src="chrome://formautofill/content/editProfile.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -0,0 +1,5 @@
|
||||
/* 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/. */
|
||||
|
||||
/* Linux specific rules */
|
5
browser/extensions/formautofill/skin/osx/editProfile.css
Normal file
5
browser/extensions/formautofill/skin/osx/editProfile.css
Normal file
@ -0,0 +1,5 @@
|
||||
/* 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/. */
|
||||
|
||||
/* OSX specific rules */
|
12
browser/extensions/formautofill/skin/windows/editProfile.css
Normal file
12
browser/extensions/formautofill/skin/windows/editProfile.css
Normal file
@ -0,0 +1,12 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* The save button should be on the left and cancel on the right for Windows */
|
||||
#save {
|
||||
order: 0;
|
||||
}
|
||||
|
||||
#cancel {
|
||||
order: 1;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 1.8.229
|
||||
Current extension version is: 1.8.243
|
||||
|
@ -90,7 +90,7 @@ var PdfjsChromeUtils = {
|
||||
this._mmg.addMessageListener("PDFJS:Parent:removeEventListener", this);
|
||||
this._mmg.addMessageListener("PDFJS:Parent:updateControlState", this);
|
||||
|
||||
// observer to handle shutdown
|
||||
// Observer to handle shutdown.
|
||||
Services.obs.addObserver(this, "quit-application");
|
||||
}
|
||||
},
|
||||
|
@ -45,6 +45,7 @@ var PdfjsContentUtils = {
|
||||
this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].
|
||||
getService(Ci.nsISyncMessageSender);
|
||||
this._mm.addMessageListener("PDFJS:Child:refreshSettings", this);
|
||||
|
||||
Services.obs.addObserver(this, "quit-application");
|
||||
}
|
||||
},
|
||||
|
@ -961,12 +961,12 @@ var createBlob = function createBlob(data, contentType) {
|
||||
if (typeof Blob !== 'undefined') {
|
||||
return new Blob([data], { type: contentType });
|
||||
}
|
||||
warn('The "Blob" constructor is not supported.');
|
||||
throw new Error('The "Blob" constructor is not supported.');
|
||||
};
|
||||
var createObjectURL = function createObjectURLClosure() {
|
||||
var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
return function createObjectURL(data, contentType, forceDataSchema) {
|
||||
if (!forceDataSchema && typeof URL !== 'undefined' && URL.createObjectURL) {
|
||||
return function createObjectURL(data, contentType, forceDataSchema = false) {
|
||||
if (!forceDataSchema) {
|
||||
var blob = createBlob(data, contentType);
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
@ -3391,8 +3391,8 @@ var _UnsupportedManager = function UnsupportedManagerClosure() {
|
||||
}();
|
||||
var version, build;
|
||||
{
|
||||
exports.version = version = '1.8.229';
|
||||
exports.build = build = '5ad3611c';
|
||||
exports.version = version = '1.8.243';
|
||||
exports.build = build = '96cb599e';
|
||||
}
|
||||
exports.getDocument = getDocument;
|
||||
exports.PDFDataRangeTransport = PDFDataRangeTransport;
|
||||
@ -4394,8 +4394,8 @@ if (!_util.globalScope.PDFJS) {
|
||||
}
|
||||
var PDFJS = _util.globalScope.PDFJS;
|
||||
{
|
||||
PDFJS.version = '1.8.229';
|
||||
PDFJS.build = '5ad3611c';
|
||||
PDFJS.version = '1.8.243';
|
||||
PDFJS.build = '96cb599e';
|
||||
}
|
||||
PDFJS.pdfBug = false;
|
||||
if (PDFJS.verbosity !== undefined) {
|
||||
@ -6709,8 +6709,8 @@ exports.TilingPattern = TilingPattern;
|
||||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '1.8.229';
|
||||
var pdfjsBuild = '5ad3611c';
|
||||
var pdfjsVersion = '1.8.243';
|
||||
var pdfjsBuild = '96cb599e';
|
||||
var pdfjsSharedUtil = __w_pdfjs_require__(0);
|
||||
var pdfjsDisplayGlobal = __w_pdfjs_require__(8);
|
||||
var pdfjsDisplayAPI = __w_pdfjs_require__(3);
|
||||
|
@ -961,12 +961,12 @@ var createBlob = function createBlob(data, contentType) {
|
||||
if (typeof Blob !== 'undefined') {
|
||||
return new Blob([data], { type: contentType });
|
||||
}
|
||||
warn('The "Blob" constructor is not supported.');
|
||||
throw new Error('The "Blob" constructor is not supported.');
|
||||
};
|
||||
var createObjectURL = function createObjectURLClosure() {
|
||||
var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
return function createObjectURL(data, contentType, forceDataSchema) {
|
||||
if (!forceDataSchema && typeof URL !== 'undefined' && URL.createObjectURL) {
|
||||
return function createObjectURL(data, contentType, forceDataSchema = false) {
|
||||
if (!forceDataSchema) {
|
||||
var blob = createBlob(data, contentType);
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
@ -36565,8 +36565,8 @@ exports.Type1Parser = Type1Parser;
|
||||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '1.8.229';
|
||||
var pdfjsBuild = '5ad3611c';
|
||||
var pdfjsVersion = '1.8.243';
|
||||
var pdfjsBuild = '96cb599e';
|
||||
var pdfjsCoreWorker = __w_pdfjs_require__(17);
|
||||
;
|
||||
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||
|
@ -315,9 +315,18 @@ function getVisibleElements(scrollEl, views, sortByVisibility) {
|
||||
function noContextMenuHandler(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
function getPDFFileNameFromURL(url, defaultFilename) {
|
||||
if (typeof defaultFilename === 'undefined') {
|
||||
defaultFilename = 'document.pdf';
|
||||
function isDataSchema(url) {
|
||||
var i = 0,
|
||||
ii = url.length;
|
||||
while (i < ii && url[i].trim() === '') {
|
||||
i++;
|
||||
}
|
||||
return url.substr(i, 5).toLowerCase() === 'data:';
|
||||
}
|
||||
function getPDFFileNameFromURL(url, defaultFilename = 'document.pdf') {
|
||||
if (isDataSchema(url)) {
|
||||
console.warn('getPDFFileNameFromURL: ' + 'ignoring "data:" URL for performance reasons.');
|
||||
return defaultFilename;
|
||||
}
|
||||
var reURI = /^(?:(?:[^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
|
||||
var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
|
||||
@ -3869,11 +3878,14 @@ var PDFAttachmentViewer = function PDFAttachmentViewerClosure() {
|
||||
});
|
||||
this._renderedCapability.resolve();
|
||||
},
|
||||
_bindPdfLink: function PDFAttachmentViewer_bindPdfLink(button, content, filename) {
|
||||
_bindPdfLink(button, content, filename) {
|
||||
if (_pdfjs.PDFJS.disableCreateObjectURL) {
|
||||
throw new Error('bindPdfLink: ' + 'Unsupported "PDFJS.disableCreateObjectURL" value.');
|
||||
}
|
||||
var blobUrl;
|
||||
button.onclick = function () {
|
||||
if (!blobUrl) {
|
||||
blobUrl = (0, _pdfjs.createObjectURL)(content, 'application/pdf', _pdfjs.PDFJS.disableCreateObjectURL);
|
||||
blobUrl = (0, _pdfjs.createObjectURL)(content, 'application/pdf');
|
||||
}
|
||||
var viewerUrl;
|
||||
viewerUrl = blobUrl + '?' + encodeURIComponent(filename);
|
||||
@ -3911,7 +3923,7 @@ var PDFAttachmentViewer = function PDFAttachmentViewerClosure() {
|
||||
div.className = 'attachmentsItem';
|
||||
var button = document.createElement('button');
|
||||
button.textContent = filename;
|
||||
if (/\.pdf$/i.test(filename)) {
|
||||
if (/\.pdf$/i.test(filename) && !_pdfjs.PDFJS.disableCreateObjectURL) {
|
||||
this._bindPdfLink(button, item.content, filename);
|
||||
} else {
|
||||
this._bindLink(button, item.content, filename);
|
||||
@ -7630,7 +7642,7 @@ var pdfjsWebApp;
|
||||
pdfjsWebApp = __webpack_require__(4);
|
||||
}
|
||||
{
|
||||
window.FirefoxCom = __webpack_require__(10).FirefoxCom;
|
||||
__webpack_require__(10);
|
||||
__webpack_require__(9);
|
||||
}
|
||||
;
|
||||
|
@ -696,10 +696,6 @@
|
||||
@RESPATH@/res/fonts/*
|
||||
@RESPATH@/res/dtd/*
|
||||
@RESPATH@/res/html/*
|
||||
#if defined(XP_MACOSX)
|
||||
; For SafariProfileMigrator.js.
|
||||
@RESPATH@/res/langGroups.properties
|
||||
#endif
|
||||
@RESPATH@/res/language.properties
|
||||
@RESPATH@/res/entityTables/*
|
||||
#ifdef XP_MACOSX
|
||||
|
@ -98,8 +98,7 @@ let customizationListener = {
|
||||
};
|
||||
customizationListener.onWidgetAdded =
|
||||
customizationListener.onWidgetRemoved =
|
||||
customizationListener.onWidgetMoved =
|
||||
customizationListener.onWidgetInstanceRemoved = function(aWidgetId) {
|
||||
customizationListener.onWidgetMoved = function(aWidgetId) {
|
||||
if (aWidgetId == "zoom-controls") {
|
||||
for (let window of CustomizableUI.windows) {
|
||||
updateZoomUI(window.gBrowser.selectedBrowser);
|
||||
|
@ -92,12 +92,22 @@ var BrowserHelper = {
|
||||
},
|
||||
|
||||
increasePriority: function NP_BH_increasePriority(aBrowser) {
|
||||
// Ignore if browser is lazy. Once the browser is instantiated, this will
|
||||
// get taken care of by TabBrowserInserted and TabSelect handlers.
|
||||
if (!aBrowser.isConnected) {
|
||||
return;
|
||||
}
|
||||
aBrowser.adjustPriority(PRIORITY_DELTA);
|
||||
_priorityBackup.set(aBrowser.permanentKey,
|
||||
_priorityBackup.get(aBrowser.permanentKey) + PRIORITY_DELTA);
|
||||
},
|
||||
|
||||
decreasePriority: function NP_BH_decreasePriority(aBrowser) {
|
||||
// Ignore if browser is lazy. Once the browser is instantiated, this will
|
||||
// get taken care of by TabBrowserInserted and TabSelect handlers.
|
||||
if (!aBrowser.isConnected) {
|
||||
return;
|
||||
}
|
||||
aBrowser.adjustPriority(PRIORITY_DELTA * -1);
|
||||
_priorityBackup.set(aBrowser.permanentKey,
|
||||
_priorityBackup.get(aBrowser.permanentKey) - PRIORITY_DELTA);
|
||||
|
@ -34,6 +34,7 @@ run-if = crashreporter
|
||||
[browser_UsageTelemetry.js]
|
||||
[browser_UsageTelemetry_private_and_restore.js]
|
||||
[browser_UsageTelemetry_urlbar.js]
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1356758
|
||||
support-files =
|
||||
usageTelemetrySearchSuggestions.sjs
|
||||
usageTelemetrySearchSuggestions.xml
|
||||
|
@ -553,7 +553,7 @@ menuitem.bookmark-item {
|
||||
|
||||
/* Menu panel buttons */
|
||||
|
||||
%include ../shared/toolbarbuttons.inc.css
|
||||
%include ../shared/toolbarbutton-icons.inc.css
|
||||
%include ../shared/menupanel.inc.css
|
||||
|
||||
#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-icon,
|
||||
|
@ -726,7 +726,7 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-ic
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
%include ../shared/toolbarbuttons.inc.css
|
||||
%include ../shared/toolbarbutton-icons.inc.css
|
||||
%include ../shared/menupanel.inc.css
|
||||
|
||||
@media not all and (min-resolution: 1.1dppx) {
|
||||
|
@ -578,7 +578,7 @@ menuitem.bookmark-item {
|
||||
|
||||
/* ::::: primary toolbar buttons ::::: */
|
||||
|
||||
%include ../shared/toolbarbuttons.inc.css
|
||||
%include ../shared/toolbarbutton-icons.inc.css
|
||||
|
||||
#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-icon,
|
||||
#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-menu-dropmarker,
|
||||
|
@ -7,7 +7,7 @@ console.assert(false, "Failing mozscreenshots assertion");
|
||||
|
||||
console.group("Grouped Message");
|
||||
console.log("group message 1");
|
||||
console.groupEnd("Grouped Message");
|
||||
console.groupEnd();
|
||||
|
||||
console.count("counter");
|
||||
console.count("counter");
|
||||
|
@ -504,6 +504,13 @@ set_config('HAVE_64BIT_BUILD', have_64_bit)
|
||||
set_define('HAVE_64BIT_BUILD', have_64_bit)
|
||||
add_old_configure_assignment('HAVE_64BIT_BUILD', have_64_bit)
|
||||
|
||||
@depends(host)
|
||||
def host_os_kernel_major_version(host):
|
||||
versions = host.raw_os.split('.')
|
||||
version = ''.join(x for x in versions[0] if x.isdigit())
|
||||
return version
|
||||
|
||||
set_config('HOST_MAJOR_VERSION', host_os_kernel_major_version)
|
||||
|
||||
# Autoconf needs these set
|
||||
@depends(host)
|
||||
|
@ -61,6 +61,9 @@ check_and_add_gcc_warning('-Wc++14-compat', cxx_compiler)
|
||||
check_and_add_gcc_warning('-Wc++14-compat-pedantic', cxx_compiler)
|
||||
check_and_add_gcc_warning('-Wc++1z-compat', cxx_compiler)
|
||||
|
||||
# catches possible misuse of the comma operator
|
||||
check_and_add_gcc_warning('-Wcomma', cxx_compiler)
|
||||
|
||||
# catches unintentional switch case fallthroughs
|
||||
check_and_add_gcc_warning('-Wimplicit-fallthrough', cxx_compiler)
|
||||
|
||||
|
4
config/external/nspr/pr/moz.build
vendored
4
config/external/nspr/pr/moz.build
vendored
@ -40,6 +40,10 @@ elif CONFIG['OS_TARGET'] in ('FreeBSD', 'OpenBSD', 'NetBSD'):
|
||||
SOURCES += ['/nsprpub/pr/src/md/unix/%s.c' % CONFIG['OS_TARGET'].lower()]
|
||||
elif CONFIG['OS_TARGET'] == 'Darwin':
|
||||
OS_LIBS += ['-framework CoreServices']
|
||||
if CONFIG['HOST_MAJOR_VERSION'] == '15':
|
||||
DEFINES.update(
|
||||
HAS_CONNECTX=True,
|
||||
)
|
||||
DEFINES.update(
|
||||
DARWIN=True,
|
||||
HAVE_BSD_FLOCK=True,
|
||||
|
@ -26,7 +26,7 @@ module.exports = createClass({
|
||||
displayName: "multiE10SWarning",
|
||||
|
||||
onUpdatePreferenceClick() {
|
||||
let message = Strings.GetStringFromName("multiProcessWarningConfirmUpdate");
|
||||
let message = Strings.GetStringFromName("multiProcessWarningConfirmUpdate2");
|
||||
if (window.confirm(message)) {
|
||||
// Disable multi until at least the next experiment.
|
||||
Services.prefs.setIntPref(MULTI_OPT_OUT_PREF,
|
||||
@ -48,14 +48,14 @@ module.exports = createClass({
|
||||
),
|
||||
dom.div(
|
||||
{},
|
||||
Strings.GetStringFromName("multiProcessWarningMessage")
|
||||
Strings.GetStringFromName("multiProcessWarningMessage2")
|
||||
),
|
||||
dom.button(
|
||||
{
|
||||
className: "update-button",
|
||||
onClick: this.onUpdatePreferenceClick,
|
||||
},
|
||||
Strings.GetStringFromName("multiProcessWarningUpdateLink")
|
||||
Strings.GetStringFromName("multiProcessWarningUpdateLink2")
|
||||
)
|
||||
);
|
||||
},
|
||||
|
@ -31,6 +31,7 @@ const Strings = Services.strings.createBundle(
|
||||
const WorkerIcon = "chrome://devtools/skin/images/debugging-workers.svg";
|
||||
const MORE_INFO_URL = "https://developer.mozilla.org/en-US/docs/Tools/about%3Adebugging";
|
||||
const PROCESS_COUNT_PREF = "dom.ipc.processCount";
|
||||
const MULTI_OPTOUT_PREF = "dom.ipc.multiOptOut";
|
||||
|
||||
module.exports = createClass({
|
||||
displayName: "WorkersPanel",
|
||||
@ -58,7 +59,20 @@ module.exports = createClass({
|
||||
client.addListener("processListChanged", this.updateWorkers);
|
||||
client.addListener("registration-changed", this.updateWorkers);
|
||||
|
||||
// Some notes about these observers:
|
||||
// - nsIPrefBranch.addObserver observes prefixes. In reality, watching
|
||||
// PROCESS_COUNT_PREF watches two separate prefs:
|
||||
// dom.ipc.processCount *and* dom.ipc.processCount.web. Because these
|
||||
// are the two ways that we control the number of content processes,
|
||||
// that works perfectly fine.
|
||||
// - The user might opt in or out of multi by setting the multi opt out
|
||||
// pref. That affects whether we need to show our warning, so we need to
|
||||
// update our state when that pref changes.
|
||||
// - In all cases, we don't have to manually check which pref changed to
|
||||
// what. The platform code in nsIXULRuntime.maxWebProcessCount does all
|
||||
// of that for us.
|
||||
Services.prefs.addObserver(PROCESS_COUNT_PREF, this.updateMultiE10S);
|
||||
Services.prefs.addObserver(MULTI_OPTOUT_PREF, this.updateMultiE10S);
|
||||
|
||||
this.updateMultiE10S();
|
||||
this.updateWorkers();
|
||||
@ -72,11 +86,12 @@ module.exports = createClass({
|
||||
client.removeListener("registration-changed", this.updateWorkers);
|
||||
|
||||
Services.prefs.removeObserver(PROCESS_COUNT_PREF, this.updateMultiE10S);
|
||||
Services.prefs.removeObserver(MULTI_OPTOUT_PREF, this.updateMultiE10S);
|
||||
},
|
||||
|
||||
updateMultiE10S() {
|
||||
// We watch the pref but set the state based on
|
||||
// nsIXULRuntime::maxWebProcessCount.
|
||||
// nsIXULRuntime.maxWebProcessCount.
|
||||
let processCount = Services.appinfo.maxWebProcessCount;
|
||||
this.setState({ processCount });
|
||||
},
|
||||
|
@ -79,7 +79,6 @@ function loadTelemetryAndRecordLogs() {
|
||||
info("Mock the Telemetry log function to record logged information");
|
||||
|
||||
let Telemetry = require("devtools/client/shared/telemetry");
|
||||
|
||||
Telemetry.prototype.telemetryInfo = {};
|
||||
Telemetry.prototype._oldlog = Telemetry.prototype.log;
|
||||
Telemetry.prototype.log = function (histogramId, value) {
|
||||
@ -94,6 +93,8 @@ function loadTelemetryAndRecordLogs() {
|
||||
this.telemetryInfo[histogramId].push(value);
|
||||
}
|
||||
};
|
||||
Telemetry.prototype._oldlogScalar = Telemetry.prototype.logScalar;
|
||||
Telemetry.prototype.logScalar = Telemetry.prototype.log;
|
||||
Telemetry.prototype._oldlogKeyed = Telemetry.prototype.logKeyed;
|
||||
Telemetry.prototype.logKeyed = function (histogramId, key, value) {
|
||||
this.log(`${histogramId}|${key}`, value);
|
||||
@ -110,8 +111,10 @@ function loadTelemetryAndRecordLogs() {
|
||||
function stopRecordingTelemetryLogs(Telemetry) {
|
||||
info("Stopping Telemetry");
|
||||
Telemetry.prototype.log = Telemetry.prototype._oldlog;
|
||||
Telemetry.prototype.logScalar = Telemetry.prototype._oldlogScalar;
|
||||
Telemetry.prototype.logKeyed = Telemetry.prototype._oldlogKeyed;
|
||||
delete Telemetry.prototype._oldlog;
|
||||
delete Telemetry.prototype._oldlogScalar;
|
||||
delete Telemetry.prototype._oldlogKeyed;
|
||||
delete Telemetry.prototype.telemetryInfo;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
this._preferredSourceURL = null;
|
||||
this._unnamedSourceIndex = 0;
|
||||
this.emptyText = L10N.getStr("noSourcesText");
|
||||
this._blackBoxCheckboxTooltip = L10N.getStr("blackBoxCheckboxTooltip");
|
||||
this._blackBoxCheckboxTooltip = L10N.getStr("blackboxCheckboxTooltip2");
|
||||
|
||||
this._commandset = document.getElementById("debuggerCommands");
|
||||
this._popupset = document.getElementById("debuggerPopupset");
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -7,6 +7,6 @@ DevToolsModules(
|
||||
'debugger.css',
|
||||
'debugger.js',
|
||||
'panel.js',
|
||||
'parser-worker.js',
|
||||
'pretty-print-worker.js',
|
||||
'source-map-worker.js'
|
||||
)
|
||||
|
@ -4,7 +4,7 @@
|
||||
"use strict";
|
||||
|
||||
const { Task } = require("devtools/shared/task");
|
||||
var {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
var { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
|
||||
const DBG_STRINGS_URI = "devtools/client/locales/debugger.properties";
|
||||
var L10N = new LocalizationHelper(DBG_STRINGS_URI);
|
||||
@ -16,38 +16,46 @@ function DebuggerPanel(iframeWindow, toolbox) {
|
||||
}
|
||||
|
||||
DebuggerPanel.prototype = {
|
||||
open: Task.async(function* () {
|
||||
open: async function() {
|
||||
if (!this.toolbox.target.isRemote) {
|
||||
yield this.toolbox.target.makeRemote();
|
||||
await this.toolbox.target.makeRemote();
|
||||
}
|
||||
|
||||
yield this.panelWin.Debugger.bootstrap({
|
||||
const {
|
||||
actions,
|
||||
store,
|
||||
selectors,
|
||||
client
|
||||
} = await this.panelWin.Debugger.bootstrap({
|
||||
threadClient: this.toolbox.threadClient,
|
||||
tabTarget: this.toolbox.target
|
||||
tabTarget: this.toolbox.target,
|
||||
debuggerClient: this.toolbox.target._client,
|
||||
sourceMaps: this.toolbox.sourceMapService
|
||||
});
|
||||
|
||||
this._actions = actions;
|
||||
this._store = store;
|
||||
this._selectors = selectors;
|
||||
this._client = client;
|
||||
this.isReady = true;
|
||||
return this;
|
||||
}),
|
||||
|
||||
_store: function () {
|
||||
return this.panelWin.Debugger.store;
|
||||
},
|
||||
|
||||
_getState: function () {
|
||||
return this._store().getState();
|
||||
getVarsForTests() {
|
||||
return {
|
||||
store: this._store,
|
||||
selectors: this._selectors,
|
||||
actions: this._actions,
|
||||
client: this._client
|
||||
};
|
||||
},
|
||||
|
||||
_actions: function () {
|
||||
return this.panelWin.Debugger.actions;
|
||||
_getState: function() {
|
||||
return this._store.getState();
|
||||
},
|
||||
|
||||
_selectors: function () {
|
||||
return this.panelWin.Debugger.selectors;
|
||||
},
|
||||
|
||||
getFrames: function () {
|
||||
let frames = this._selectors().getFrames(this._getState());
|
||||
getFrames: function() {
|
||||
let frames = this._selectors.getFrames(this._getState());
|
||||
|
||||
// Frames is null when the debugger is not paused.
|
||||
if (!frames) {
|
||||
@ -58,7 +66,7 @@ DebuggerPanel.prototype = {
|
||||
}
|
||||
|
||||
frames = frames.toJS();
|
||||
const selectedFrame = this._selectors().getSelectedFrame(this._getState());
|
||||
const selectedFrame = this._selectors.getSelectedFrame(this._getState());
|
||||
const selected = frames.findIndex(frame => frame.id == selectedFrame.id);
|
||||
|
||||
frames.forEach(frame => {
|
||||
@ -68,7 +76,15 @@ DebuggerPanel.prototype = {
|
||||
return { frames, selected };
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
selectSource(sourceURL, sourceLine) {
|
||||
this._actions.selectSourceURL(sourceURL, { line: sourceLine });
|
||||
},
|
||||
|
||||
getSource(sourceURL) {
|
||||
return this._selectors.getSourceByURL(this._getState(), sourceURL);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.panelWin.Debugger.destroy();
|
||||
this.emit("destroyed");
|
||||
}
|
||||
|
29381
devtools/client/debugger/new/parser-worker.js
Normal file
29381
devtools/client/debugger/new/parser-worker.js
Normal file
File diff suppressed because one or more lines are too long
@ -55,7 +55,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
/***/ 0:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
module.exports = __webpack_require__(801);
|
||||
module.exports = __webpack_require__(964);
|
||||
|
||||
|
||||
/***/ },
|
||||
@ -75,76 +75,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
|
||||
/***/ },
|
||||
|
||||
/***/ 801:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var prettyFast = __webpack_require__(802);
|
||||
var assert = __webpack_require__(223);
|
||||
|
||||
function prettyPrint(_ref) {
|
||||
var url = _ref.url,
|
||||
indent = _ref.indent,
|
||||
source = _ref.source;
|
||||
|
||||
try {
|
||||
var prettified = prettyFast(source, {
|
||||
url: url,
|
||||
indent: " ".repeat(indent)
|
||||
});
|
||||
|
||||
return {
|
||||
code: prettified.code,
|
||||
mappings: prettified.map._mappings
|
||||
};
|
||||
} catch (e) {
|
||||
throw new Error(`${e.message}\n${e.stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
function invertMappings(mappings) {
|
||||
return mappings._array.map(m => {
|
||||
var mapping = {
|
||||
generated: {
|
||||
line: m.originalLine,
|
||||
column: m.originalColumn
|
||||
}
|
||||
};
|
||||
if (m.source) {
|
||||
mapping.source = m.source;
|
||||
mapping.original = {
|
||||
line: m.generatedLine,
|
||||
column: m.generatedColumn
|
||||
};
|
||||
mapping.name = m.name;
|
||||
}
|
||||
return mapping;
|
||||
});
|
||||
}
|
||||
|
||||
self.onmessage = function (msg) {
|
||||
var _msg$data = msg.data,
|
||||
id = _msg$data.id,
|
||||
args = _msg$data.args;
|
||||
|
||||
assert(msg.data.method === "prettyPrint", "Method must be `prettyPrint`");
|
||||
|
||||
try {
|
||||
var _prettyPrint = prettyPrint(args[0]),
|
||||
code = _prettyPrint.code,
|
||||
mappings = _prettyPrint.mappings;
|
||||
|
||||
self.postMessage({ id, response: {
|
||||
code, mappings: invertMappings(mappings)
|
||||
} });
|
||||
} catch (e) {
|
||||
self.postMessage({ id, error: e });
|
||||
}
|
||||
};
|
||||
|
||||
/***/ },
|
||||
|
||||
/***/ 802:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
@ -5918,6 +5848,80 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||||
|
||||
|
||||
/***/ },
|
||||
|
||||
/***/ 964:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var prettyFast = __webpack_require__(802);
|
||||
var assert = __webpack_require__(223);
|
||||
|
||||
function prettyPrint(_ref) {
|
||||
var url = _ref.url,
|
||||
indent = _ref.indent,
|
||||
source = _ref.source;
|
||||
|
||||
try {
|
||||
var prettified = prettyFast(source, {
|
||||
url: url,
|
||||
indent: " ".repeat(indent)
|
||||
});
|
||||
|
||||
return {
|
||||
code: prettified.code,
|
||||
mappings: prettified.map._mappings
|
||||
};
|
||||
} catch (e) {
|
||||
throw new Error(`${e.message}\n${e.stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
function invertMappings(mappings) {
|
||||
return mappings._array.map(m => {
|
||||
var mapping = {
|
||||
generated: {
|
||||
line: m.originalLine,
|
||||
column: m.originalColumn
|
||||
}
|
||||
};
|
||||
if (m.source) {
|
||||
mapping.source = m.source;
|
||||
mapping.original = {
|
||||
line: m.generatedLine,
|
||||
column: m.generatedColumn
|
||||
};
|
||||
mapping.name = m.name;
|
||||
}
|
||||
return mapping;
|
||||
});
|
||||
}
|
||||
|
||||
self.onmessage = function (msg) {
|
||||
var _msg$data = msg.data,
|
||||
id = _msg$data.id,
|
||||
args = _msg$data.args;
|
||||
|
||||
assert(msg.data.method === "prettyPrint", "Method must be `prettyPrint`");
|
||||
|
||||
try {
|
||||
var _prettyPrint = prettyPrint(args[0]),
|
||||
code = _prettyPrint.code,
|
||||
mappings = _prettyPrint.mappings;
|
||||
|
||||
self.postMessage({
|
||||
id,
|
||||
response: {
|
||||
code,
|
||||
mappings: invertMappings(mappings)
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
self.postMessage({ id, error: e });
|
||||
}
|
||||
};
|
||||
|
||||
/***/ }
|
||||
|
||||
/******/ })
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,6 +42,7 @@ support-files =
|
||||
[browser_dbg-breakpoints.js]
|
||||
[browser_dbg-breakpoints-cond.js]
|
||||
[browser_dbg-call-stack.js]
|
||||
[browser_dbg-expressions.js]
|
||||
[browser_dbg-scopes.js]
|
||||
[browser_dbg-chrome-create.js]
|
||||
[browser_dbg-chrome-debugging.js]
|
||||
|
@ -54,6 +54,6 @@ add_task(function* () {
|
||||
|
||||
button = toggleButton(dbg);
|
||||
frames = findAllElements(dbg, "frames");
|
||||
is(button.innerText, "Collapse Rows", "toggle button should be collapse");
|
||||
is(button.innerText, "Collapse Rows", "toggle button should be collapsed");
|
||||
is(frames.length, 22, "All of the frames should be shown");
|
||||
});
|
||||
|
@ -18,7 +18,9 @@ add_task(function* () {
|
||||
// Wait for the source text to load and make sure we're in the right
|
||||
// place.
|
||||
yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT");
|
||||
assertHighlightLocation(dbg, "long.js", 66);
|
||||
|
||||
// TODO: revisit highlighting lines when the debugger opens
|
||||
//assertHighlightLocation(dbg, "long.js", 66);
|
||||
|
||||
// Jump to line 16 and make sure the editor scrolled.
|
||||
yield selectSource(dbg, "long.js", 16);
|
||||
|
@ -50,5 +50,5 @@ add_task(function* () {
|
||||
invokeInTab("testModel");
|
||||
yield waitForPaused(dbg);
|
||||
assertPausedLocation(dbg, longSrc, 66);
|
||||
// ok(isElementVisible(dbg, "breakpoint"), "Breakpoint is visible");
|
||||
ok(isElementVisible(dbg, "breakpoint"), "Breakpoint is visible");
|
||||
});
|
||||
|
@ -1,12 +1,56 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const {
|
||||
setupTestRunner,
|
||||
expressions
|
||||
} = require("devtools/client/debugger/new/integration-tests");
|
||||
/**
|
||||
* tests the watch expressions component
|
||||
* 1. add watch expressions
|
||||
* 2. edit watch expressions
|
||||
* 3. delete watch expressions
|
||||
*/
|
||||
|
||||
const expressionSelectors = {
|
||||
input: "input.input-expression"
|
||||
};
|
||||
|
||||
function getLabel(dbg, index) {
|
||||
return findElement(dbg, "expressionNode", index).innerText;
|
||||
}
|
||||
|
||||
function getValue(dbg, index) {
|
||||
return findElement(dbg, "expressionValue", index).innerText;
|
||||
}
|
||||
|
||||
async function addExpression(dbg, input) {
|
||||
info("Adding an expression");
|
||||
findElementWithSelector(dbg, expressionSelectors.input).focus();
|
||||
type(dbg, input);
|
||||
pressKey(dbg, "Enter");
|
||||
|
||||
await waitForDispatch(dbg, "EVALUATE_EXPRESSION");
|
||||
}
|
||||
|
||||
async function editExpression(dbg, input) {
|
||||
info("updating the expression");
|
||||
dblClickElement(dbg, "expressionNode", 1);
|
||||
type(dbg, input);
|
||||
pressKey(dbg, "Enter");
|
||||
await waitForDispatch(dbg, "EVALUATE_EXPRESSION");
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
setupTestRunner(this);
|
||||
yield expressions(this);
|
||||
const dbg = yield initDebugger("doc-script-switching.html");
|
||||
|
||||
invokeInTab("firstCall");
|
||||
yield waitForPaused(dbg);
|
||||
|
||||
yield addExpression(dbg, "f");
|
||||
is(getLabel(dbg, 1), "f");
|
||||
is(getValue(dbg, 1), "ReferenceError");
|
||||
|
||||
yield editExpression(dbg, "oo");
|
||||
is(getLabel(dbg, 1), "foo()");
|
||||
is(getValue(dbg, 1), "");
|
||||
|
||||
yield deleteExpression(dbg, "foo");
|
||||
is(findAllElements(dbg, "expressionNodes").length, 0);
|
||||
});
|
||||
|
@ -20,7 +20,6 @@ add_task(function* () {
|
||||
const dbg = yield initDebugger("doc-exceptions.html");
|
||||
|
||||
// test skipping an uncaught exception
|
||||
yield togglePauseOnExceptions(dbg, false, false);
|
||||
yield uncaughtException();
|
||||
ok(!isPaused(dbg));
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
// Tests basic pretty-printing functionality.
|
||||
|
||||
add_task(function* () {
|
||||
add_task(function*() {
|
||||
const dbg = yield initDebugger("doc-minified.html");
|
||||
|
||||
yield selectSource(dbg, "math.min.js");
|
||||
|
@ -19,4 +19,13 @@ add_task(function* () {
|
||||
|
||||
is(getLabel(dbg, 1), "secondCall");
|
||||
is(getLabel(dbg, 2), "<this>");
|
||||
is(getLabel(dbg, 4), "foo()");
|
||||
|
||||
toggleNode(dbg, 4);
|
||||
yield waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES");
|
||||
is(getLabel(dbg, 5), "prototype");
|
||||
|
||||
yield stepOver(dbg);
|
||||
is(getLabel(dbg, 4), "foo()");
|
||||
is(getLabel(dbg, 5), "prototype");
|
||||
});
|
||||
|
@ -4,7 +4,10 @@
|
||||
// Test that an error while loading a sourcemap does not break
|
||||
// debugging.
|
||||
|
||||
add_task(function* () {
|
||||
add_task(function*() {
|
||||
// NOTE: the CORS call makes the test run times inconsistent
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const dbg = yield initDebugger("doc-sourcemap-bogus.html");
|
||||
const { selectors: { getSources }, getState } = dbg;
|
||||
|
||||
|
@ -4,7 +4,10 @@
|
||||
// Tests loading sourcemapped sources, setting breakpoints, and
|
||||
// stepping in them.
|
||||
|
||||
add_task(function* () {
|
||||
add_task(function*() {
|
||||
// NOTE: the CORS call makes the test run times inconsistent
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const dbg = yield initDebugger("doc-sourcemaps.html");
|
||||
const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg;
|
||||
|
||||
@ -13,21 +16,27 @@ add_task(function* () {
|
||||
const entrySrc = findSource(dbg, "entry.js");
|
||||
|
||||
yield selectSource(dbg, entrySrc);
|
||||
ok(dbg.win.cm.getValue().includes("window.keepMeAlive"),
|
||||
"Original source text loaded correctly");
|
||||
ok(
|
||||
dbg.win.cm.getValue().includes("window.keepMeAlive"),
|
||||
"Original source text loaded correctly"
|
||||
);
|
||||
|
||||
// Test that breakpoint sliding is not attempted. The breakpoint
|
||||
// should not move anywhere.
|
||||
yield addBreakpoint(dbg, entrySrc, 13);
|
||||
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
|
||||
ok(getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }),
|
||||
"Breakpoint has correct line");
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
|
||||
// Test breaking on a breakpoint
|
||||
yield addBreakpoint(dbg, "entry.js", 15);
|
||||
is(getBreakpoints(getState()).size, 2, "Two breakpoints exist");
|
||||
ok(getBreakpoint(getState(), { sourceId: entrySrc.id, line: 15 }),
|
||||
"Breakpoint has correct line");
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: entrySrc.id, line: 15 }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
|
||||
invokeInTab("keepMeAlive");
|
||||
yield waitForPaused(dbg);
|
||||
|
@ -6,7 +6,10 @@
|
||||
|
||||
// This source map does not have source contents, so it's fetched separately
|
||||
|
||||
add_task(function* () {
|
||||
add_task(function*() {
|
||||
// NOTE: the CORS call makes the test run times inconsistent
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const dbg = yield initDebugger("doc-sourcemaps2.html");
|
||||
const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg;
|
||||
|
||||
@ -20,8 +23,10 @@ add_task(function* () {
|
||||
// Test that breakpoint is not off by a line.
|
||||
yield addBreakpoint(dbg, mainSrc, 4);
|
||||
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
|
||||
ok(getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4 }),
|
||||
"Breakpoint has correct line");
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4 }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
|
||||
invokeInTab("logMessage");
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
<body>
|
||||
<script>
|
||||
debugger;
|
||||
|
||||
// This inline script allows this HTML page to show up as a
|
||||
// source. It also needs to introduce a new global variable so
|
||||
// it's not immediately garbage collected.
|
||||
|
@ -33,13 +33,14 @@
|
||||
*/
|
||||
|
||||
// shared-head.js handles imports, constants, and utility functions
|
||||
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this);
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
|
||||
this
|
||||
);
|
||||
var { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/new/test/mochitest/examples/";
|
||||
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true);
|
||||
Services.prefs.clearUserPref("devtools.debugger.tabs")
|
||||
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location")
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
@ -76,9 +77,9 @@ function _afterDispatchDone(store, type) {
|
||||
type: "@@service/waitUntil",
|
||||
predicate: action => {
|
||||
if (action.type === type) {
|
||||
return action.status ?
|
||||
(action.status === "done" || action.status === "error") :
|
||||
true;
|
||||
return action.status
|
||||
? action.status === "done" || action.status === "error"
|
||||
: true;
|
||||
}
|
||||
},
|
||||
run: (dispatch, getState, action) => {
|
||||
@ -102,7 +103,7 @@ function _afterDispatchDone(store, type) {
|
||||
function waitForDispatch(dbg, type, eventRepeat = 1) {
|
||||
let count = 0;
|
||||
|
||||
return Task.spawn(function* () {
|
||||
return Task.spawn(function*() {
|
||||
info("Waiting for " + type + " to dispatch " + eventRepeat + " time(s)");
|
||||
while (count < eventRepeat) {
|
||||
yield _afterDispatchDone(dbg.store, type);
|
||||
@ -170,21 +171,23 @@ function waitForSources(dbg, ...sources) {
|
||||
|
||||
info("Waiting on sources: " + sources.join(", "));
|
||||
const { selectors: { getSources }, store } = dbg;
|
||||
return Promise.all(sources.map(url => {
|
||||
function sourceExists(state) {
|
||||
return getSources(state).some(s => {
|
||||
return s.get("url").includes(url);
|
||||
});
|
||||
}
|
||||
return Promise.all(
|
||||
sources.map(url => {
|
||||
function sourceExists(state) {
|
||||
return getSources(state).some(s => {
|
||||
return s.get("url").includes(url);
|
||||
});
|
||||
}
|
||||
|
||||
if (!sourceExists(store.getState())) {
|
||||
return waitForState(dbg, sourceExists);
|
||||
}
|
||||
}));
|
||||
if (!sourceExists(store.getState())) {
|
||||
return waitForState(dbg, sourceExists);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function waitForElement(dbg, selector) {
|
||||
return waitUntil(() => findElementWithSelector(dbg, selector))
|
||||
return waitUntil(() => findElementWithSelector(dbg, selector));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,8 +212,10 @@ function assertPausedLocation(dbg, source, line) {
|
||||
is(location.get("line"), line);
|
||||
|
||||
// Check the debug line
|
||||
ok(dbg.win.cm.lineInfo(line - 1).wrapClass.includes("debug-line"),
|
||||
"Line is highlighted as paused");
|
||||
ok(
|
||||
dbg.win.cm.lineInfo(line - 1).wrapClass.includes("debug-line"),
|
||||
"Line is highlighted as paused"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -232,10 +237,14 @@ function assertHighlightLocation(dbg, source, line) {
|
||||
// Check the highlight line
|
||||
const lineEl = findElement(dbg, "highlightLine");
|
||||
ok(lineEl, "Line is highlighted");
|
||||
// ok(isVisibleWithin(findElement(dbg, "codeMirror"), lineEl),
|
||||
// "Highlighted line is visible");
|
||||
ok(dbg.win.cm.lineInfo(line - 1).wrapClass.includes("highlight-line"),
|
||||
"Line is highlighted");
|
||||
ok(
|
||||
isVisibleWithin(findElement(dbg, "codeMirror"), lineEl),
|
||||
"Highlighted line is visible"
|
||||
);
|
||||
ok(
|
||||
dbg.win.cm.lineInfo(line - 1).wrapClass.includes("highlight-line"),
|
||||
"Line is highlighted"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,12 +267,11 @@ function isPaused(dbg) {
|
||||
* @static
|
||||
*/
|
||||
function waitForPaused(dbg) {
|
||||
return Task.spawn(function* () {
|
||||
return Task.spawn(function*() {
|
||||
// We want to make sure that we get both a real paused event and
|
||||
// that the state is fully populated. The client may do some more
|
||||
// work (call other client methods) before populating the state.
|
||||
yield waitForThreadEvents(dbg, "paused"),
|
||||
yield waitForState(dbg, state => {
|
||||
yield waitForThreadEvents(dbg, "paused"), yield waitForState(dbg, state => {
|
||||
const pause = dbg.selectors.getPause(state);
|
||||
// Make sure we have the paused state.
|
||||
if (!pause) {
|
||||
@ -279,15 +287,16 @@ function waitForPaused(dbg) {
|
||||
}
|
||||
|
||||
function createDebuggerContext(toolbox) {
|
||||
const win = toolbox.getPanel("jsdebugger").panelWin;
|
||||
const store = win.Debugger.store;
|
||||
const panel = toolbox.getPanel("jsdebugger");
|
||||
const win = panel.panelWin;
|
||||
const { store, client, selectors, actions } = panel.getVarsForTests();
|
||||
|
||||
return {
|
||||
actions: win.Debugger.actions,
|
||||
selectors: win.Debugger.selectors,
|
||||
actions: actions,
|
||||
selectors: selectors,
|
||||
getState: store.getState,
|
||||
store: store,
|
||||
client: win.Debugger.client,
|
||||
client: client,
|
||||
toolbox: toolbox,
|
||||
win: win
|
||||
};
|
||||
@ -303,9 +312,13 @@ function createDebuggerContext(toolbox) {
|
||||
* @static
|
||||
*/
|
||||
function initDebugger(url, ...sources) {
|
||||
return Task.spawn(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.tabs")
|
||||
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location")
|
||||
return Task.spawn(function*() {
|
||||
Services.prefs.clearUserPref("devtools.debugger.pause-on-exceptions");
|
||||
Services.prefs.clearUserPref("devtools.debugger.ignore-caught-exceptions");
|
||||
Services.prefs.clearUserPref("devtools.debugger.tabs");
|
||||
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location");
|
||||
Services.prefs.clearUserPref("devtools.debugger.pending-breakpoints");
|
||||
Services.prefs.clearUserPref("devtools.debugger.expressions");
|
||||
const toolbox = yield openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger");
|
||||
return createDebuggerContext(toolbox);
|
||||
});
|
||||
@ -429,6 +442,11 @@ function resume(dbg) {
|
||||
return waitForThreadEvents(dbg, "resumed");
|
||||
}
|
||||
|
||||
function deleteExpression(dbg, input) {
|
||||
info("Resuming");
|
||||
return dbg.actions.deleteExpression({ input });
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the debuggee.
|
||||
*
|
||||
@ -500,8 +518,11 @@ function removeBreakpoint(dbg, sourceId, line, col) {
|
||||
* @return {Promise}
|
||||
* @static
|
||||
*/
|
||||
function togglePauseOnExceptions(dbg,
|
||||
pauseOnExceptions, ignoreCaughtExceptions) {
|
||||
function togglePauseOnExceptions(
|
||||
dbg,
|
||||
pauseOnExceptions,
|
||||
ignoreCaughtExceptions
|
||||
) {
|
||||
const command = dbg.actions.pauseOnExceptions(
|
||||
pauseOnExceptions,
|
||||
ignoreCaughtExceptions
|
||||
@ -526,7 +547,7 @@ function togglePauseOnExceptions(dbg,
|
||||
*/
|
||||
function invokeInTab(fnc) {
|
||||
info(`Invoking function ${fnc} in tab`);
|
||||
return ContentTask.spawn(gBrowser.selectedBrowser, fnc, function* (fnc) {
|
||||
return ContentTask.spawn(gBrowser.selectedBrowser, fnc, function*(fnc) {
|
||||
content.wrappedJSObject[fnc](); // eslint-disable-line mozilla/no-cpows-in-tests, max-len
|
||||
});
|
||||
}
|
||||
@ -534,18 +555,21 @@ function invokeInTab(fnc) {
|
||||
const isLinux = Services.appinfo.OS === "Linux";
|
||||
const cmdOrCtrl = isLinux ? { ctrlKey: true } : { metaKey: true };
|
||||
const keyMappings = {
|
||||
sourceSearch: { code: "p", modifiers: cmdOrCtrl},
|
||||
fileSearch: { code: "f", modifiers: cmdOrCtrl},
|
||||
"Enter": { code: "VK_RETURN" },
|
||||
"Up": { code: "VK_UP" },
|
||||
"Down": { code: "VK_DOWN" },
|
||||
"Tab": { code: "VK_TAB" },
|
||||
"Escape": { code: "VK_ESCAPE" },
|
||||
sourceSearch: { code: "p", modifiers: cmdOrCtrl },
|
||||
fileSearch: { code: "f", modifiers: cmdOrCtrl },
|
||||
Enter: { code: "VK_RETURN" },
|
||||
Up: { code: "VK_UP" },
|
||||
Down: { code: "VK_DOWN" },
|
||||
Tab: { code: "VK_TAB" },
|
||||
Escape: { code: "VK_ESCAPE" },
|
||||
pauseKey: { code: "VK_F8" },
|
||||
resumeKey: { code: "VK_F8" },
|
||||
stepOverKey: { code: "VK_F10" },
|
||||
stepInKey: { code: "VK_F11", modifiers: { ctrlKey: isLinux }},
|
||||
stepOutKey: { code: "VK_F11", modifiers: { ctrlKey: isLinux, shiftKey: true }}
|
||||
stepInKey: { code: "VK_F11", modifiers: { ctrlKey: isLinux } },
|
||||
stepOutKey: {
|
||||
code: "VK_F11",
|
||||
modifiers: { ctrlKey: isLinux, shiftKey: true }
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -561,11 +585,7 @@ function pressKey(dbg, keyName) {
|
||||
let keyEvent = keyMappings[keyName];
|
||||
|
||||
const { code, modifiers } = keyEvent;
|
||||
return EventUtils.synthesizeKey(
|
||||
code,
|
||||
modifiers || {},
|
||||
dbg.win
|
||||
);
|
||||
return EventUtils.synthesizeKey(code, modifiers || {}, dbg.win);
|
||||
}
|
||||
|
||||
function type(dbg, string) {
|
||||
@ -577,14 +597,19 @@ function type(dbg, string) {
|
||||
function isVisibleWithin(outerEl, innerEl) {
|
||||
const innerRect = innerEl.getBoundingClientRect();
|
||||
const outerRect = outerEl.getBoundingClientRect();
|
||||
|
||||
return innerRect.top > outerRect.top &&
|
||||
innerRect.bottom < outerRect.bottom;
|
||||
return innerRect.top > outerRect.top && innerRect.bottom < outerRect.bottom;
|
||||
}
|
||||
|
||||
const selectors = {
|
||||
callStackHeader: ".call-stack-pane ._header",
|
||||
callStackBody: ".call-stack-pane .pane",
|
||||
expressionNode: i =>
|
||||
`.expressions-list .tree-node:nth-child(${i}) .object-label`,
|
||||
expressionValue: i =>
|
||||
`.expressions-list .tree-node:nth-child(${i}) .object-value`,
|
||||
expressionClose: i =>
|
||||
`.expressions-list .expression-container:nth-child(${i}) .close`,
|
||||
expressionNodes: ".expressions-list .tree-node",
|
||||
scopesHeader: ".scopes-pane ._header",
|
||||
breakpointItem: i => `.breakpoints-list .breakpoint:nth-child(${i})`,
|
||||
scopeNode: i => `.scopes-list .tree-node:nth-child(${i}) .object-label`,
|
||||
@ -605,7 +630,7 @@ const selectors = {
|
||||
sourceFooter: ".source-footer",
|
||||
sourceNode: i => `.sources-list .tree-node:nth-child(${i})`,
|
||||
sourceNodes: ".sources-list .tree-node",
|
||||
sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`,
|
||||
sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`
|
||||
};
|
||||
|
||||
function getSelector(elementName, ...args) {
|
||||
@ -647,6 +672,9 @@ function findAllElements(dbg, elementName, ...args) {
|
||||
*/
|
||||
function clickElement(dbg, elementName, ...args) {
|
||||
const selector = getSelector(elementName, ...args);
|
||||
const el = findElement(dbg, elementName, ...args);
|
||||
el.scrollIntoView();
|
||||
|
||||
return EventUtils.synthesizeMouseAtCenter(
|
||||
findElementWithSelector(dbg, selector),
|
||||
{},
|
||||
@ -654,12 +682,22 @@ function clickElement(dbg, elementName, ...args) {
|
||||
);
|
||||
}
|
||||
|
||||
function dblClickElement(dbg, elementName, ...args) {
|
||||
const selector = getSelector(elementName, ...args);
|
||||
|
||||
return EventUtils.synthesizeMouseAtCenter(
|
||||
findElementWithSelector(dbg, selector),
|
||||
{ clickCount: 2 },
|
||||
dbg.win
|
||||
);
|
||||
}
|
||||
|
||||
function rightClickElement(dbg, elementName, ...args) {
|
||||
const selector = getSelector(elementName, ...args);
|
||||
const doc = dbg.win.document;
|
||||
return EventUtils.synthesizeMouseAtCenter(
|
||||
doc.querySelector(selector),
|
||||
{type: "contextmenu"},
|
||||
{ type: "contextmenu" },
|
||||
dbg.win
|
||||
);
|
||||
}
|
||||
@ -669,10 +707,10 @@ function selectMenuItem(dbg, index) {
|
||||
const doc = dbg.toolbox.win.document;
|
||||
|
||||
// there are several context menus, we want the one with the menu-api
|
||||
const popup = doc.querySelector("menupopup[menu-api=\"true\"]");
|
||||
const popup = doc.querySelector('menupopup[menu-api="true"]');
|
||||
|
||||
const item = popup.querySelector(`menuitem:nth-child(${index})`);
|
||||
return EventUtils.synthesizeMouseAtCenter(item, {}, dbg.toolbox.win );
|
||||
return EventUtils.synthesizeMouseAtCenter(item, {}, dbg.toolbox.win);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -584,6 +584,8 @@ function loadTelemetryAndRecordLogs() {
|
||||
this.telemetryInfo[histogramId].push(value);
|
||||
}
|
||||
};
|
||||
Telemetry.prototype._oldlogScalar = Telemetry.prototype.logScalar;
|
||||
Telemetry.prototype.logScalar = Telemetry.prototype.log;
|
||||
Telemetry.prototype._oldlogKeyed = Telemetry.prototype.logKeyed;
|
||||
Telemetry.prototype.logKeyed = function (histogramId, key, value) {
|
||||
this.log(`${histogramId}|${key}`, value);
|
||||
@ -600,8 +602,10 @@ function loadTelemetryAndRecordLogs() {
|
||||
function stopRecordingTelemetryLogs(Telemetry) {
|
||||
info("Stopping Telemetry");
|
||||
Telemetry.prototype.log = Telemetry.prototype._oldlog;
|
||||
Telemetry.prototype.logScalar = Telemetry.prototype._oldlogScalar;
|
||||
Telemetry.prototype.logKeyed = Telemetry.prototype._oldlogKeyed;
|
||||
delete Telemetry.prototype._oldlog;
|
||||
delete Telemetry.prototype._oldlogScalar;
|
||||
delete Telemetry.prototype._oldlogKeyed;
|
||||
delete Telemetry.prototype.telemetryInfo;
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
// Test that the various copy items in the context menu works correctly.
|
||||
|
||||
const TEST_URL = URL_ROOT + "doc_inspector_menu.html";
|
||||
const SELECTOR_UNIQUE = "devtools.copy.unique.css.selector.opened";
|
||||
const SELECTOR_FULL = "devtools.copy.full.css.selector.opened";
|
||||
const COPY_ITEMS_TEST_DATA = [
|
||||
{
|
||||
desc: "copy inner html",
|
||||
@ -26,7 +28,7 @@ const COPY_ITEMS_TEST_DATA = [
|
||||
text: "body > div:nth-child(1) > p:nth-child(2)",
|
||||
},
|
||||
{
|
||||
desc: "copy css path",
|
||||
desc: "copy CSS path",
|
||||
id: "node-menu-copycsspath",
|
||||
selector: "[data-id=\"copy\"]",
|
||||
text: "html body div p",
|
||||
@ -41,7 +43,9 @@ const COPY_ITEMS_TEST_DATA = [
|
||||
];
|
||||
|
||||
add_task(function* () {
|
||||
let Telemetry = loadTelemetryAndRecordLogs();
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
|
||||
for (let {desc, id, selector, text} of COPY_ITEMS_TEST_DATA) {
|
||||
info("Testing " + desc);
|
||||
yield selectNode(selector, inspector);
|
||||
@ -52,4 +56,32 @@ add_task(function* () {
|
||||
|
||||
yield waitForClipboardPromise(() => item.click(), text);
|
||||
}
|
||||
|
||||
checkTelemetryResults(Telemetry);
|
||||
stopRecordingTelemetryLogs(Telemetry);
|
||||
});
|
||||
|
||||
function checkTelemetryResults(Telemetry) {
|
||||
let data = Telemetry.prototype.telemetryInfo;
|
||||
let results = new Map();
|
||||
|
||||
for (let key in data) {
|
||||
if (key.toLowerCase() === key) {
|
||||
let pings = data[key].length;
|
||||
|
||||
results.set(key, pings);
|
||||
}
|
||||
}
|
||||
|
||||
is(results.size, 2, "The correct number of scalars were logged");
|
||||
|
||||
let pings = checkPings(SELECTOR_UNIQUE, results);
|
||||
is(pings, 1, `${SELECTOR_UNIQUE} has just 1 ping`);
|
||||
|
||||
pings = checkPings(SELECTOR_FULL, results);
|
||||
is(pings, 1, `${SELECTOR_FULL} has just 1 ping`);
|
||||
}
|
||||
|
||||
function checkPings(scalarId, results) {
|
||||
return results.get(scalarId);
|
||||
}
|
||||
|
@ -128,14 +128,14 @@ multiProcessWarningTitle = Service Worker debugging is not compatible with multi
|
||||
# LOCALIZATION NOTE (multiProcessWarningMessage):
|
||||
# This string is displayed in the warning section for multi-e10s in
|
||||
# about:debugging#workers
|
||||
multiProcessWarningMessage = The preference “dom.ipc.processCount” can be set to 1 to force a single content process.
|
||||
multiProcessWarningMessage2 = The preference “dom.ipc.multiOptOut” can be modified to force a single content process for the current version.
|
||||
|
||||
# LOCALIZATION NOTE (multiProcessWarningLink):
|
||||
# This string is the text content of a link in the warning section for multi-e10s in
|
||||
# about:debugging#workers. The link updates the pref and restarts the browser.
|
||||
multiProcessWarningUpdateLink = Set dom.ipc.processCount to 1
|
||||
multiProcessWarningUpdateLink2 = Opt out of multiple content processes
|
||||
|
||||
# LOCALIZATION NOTE (multiProcessWarningConfirmUpdate):
|
||||
# This string is displayed as a confirmation message when the user clicks on
|
||||
# the multiProcessWarningUpdateLink in about:debugging#workers
|
||||
multiProcessWarningConfirmUpdate = Set “dom.ipc.processCount” to 1 and restart the browser?
|
||||
multiProcessWarningConfirmUpdate2 = Opt out of multiple processes?
|
||||
|
@ -115,15 +115,19 @@ timeEvents=Time
|
||||
touchEvents=Touch
|
||||
otherEvents=Other
|
||||
|
||||
# LOCALIZATION NOTE (blackBoxCheckboxTooltip): The tooltip text to display when
|
||||
# the user hovers over the checkbox used to toggle black boxing its associated
|
||||
# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when
|
||||
# the user hovers over the checkbox used to toggle blackboxing its associated
|
||||
# source.
|
||||
blackBoxCheckboxTooltip=Toggle black boxing
|
||||
blackboxCheckboxTooltip2=Toggle blackboxing
|
||||
|
||||
# LOCALIZATION NOTE (sources.search.key): Key shortcut to open the search for
|
||||
# searching all the source files the debugger has seen.
|
||||
sources.search.key=P
|
||||
|
||||
# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger
|
||||
# does not have any sources.
|
||||
sources.noSourcesAvailable=This page has no sources
|
||||
|
||||
# LOCALIZATION NOTE (sources.searchAlt.key): Alternate key shortcut to open
|
||||
# the search for searching all the source files the debugger has seen.
|
||||
sources.searchAlt.key=O
|
||||
@ -235,10 +239,17 @@ callStack.expand=Expand Rows
|
||||
# for the summarizing the selected search result. e.g. 5 of 10 results.
|
||||
editor.searchResults=%d of %d results
|
||||
|
||||
# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.
|
||||
editor.singleResult=1 result
|
||||
|
||||
# LOCALIZATION NOTE (editor.noResults): Editor Search bar message
|
||||
# for when no results found.
|
||||
editor.noResults=no results
|
||||
|
||||
# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for
|
||||
# toggling search type buttons(function search, variable search)
|
||||
editor.searchTypeToggleTitle=Search for:
|
||||
|
||||
# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item
|
||||
# for adding a breakpoint on a line.
|
||||
editor.addBreakpoint=Add Breakpoint
|
||||
@ -341,6 +352,22 @@ sourceTabs.prettyPrint=Pretty Print Source
|
||||
# the editor context menu.
|
||||
sourceTabs.prettyPrint.accesskey=p
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated
|
||||
# with the blackbox button
|
||||
sourceFooter.blackbox=Blackbox Source
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated
|
||||
# with the blackbox button
|
||||
sourceFooter.unblackbox=Unblackbox Source
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.blackbox.accesskey): Access key to blackbox
|
||||
# an associated source
|
||||
sourceFooter.blackbox.accesskey=b
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated
|
||||
# with a blackboxed source
|
||||
sourceFooter.blackboxed=Blackboxed Source
|
||||
|
||||
# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed
|
||||
# for close tab button in source tabs.
|
||||
sourceTabs.closeTabButtonTooltip=Close tab
|
||||
@ -393,10 +420,6 @@ sourceSearch.search=Search Sources…
|
||||
# message when the query did not match any of the sources.
|
||||
sourceSearch.noResults=No files matching %S found
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.debugBtnTooltip): Tooltip text associated
|
||||
# with the pretty-print button
|
||||
sourceFooter.debugBtnTooltip=Prettify Source
|
||||
|
||||
# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip
|
||||
# when the debugger will not pause on exceptions.
|
||||
ignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions
|
||||
@ -508,8 +531,30 @@ watchExpressionsSeparatorLabel2=\u0020→
|
||||
# in the functions search panel as a separator between function's inferred name
|
||||
# and its real name (if available).
|
||||
functionSearchSeparatorLabel=←
|
||||
functionSearch.search.placeholder=Search Functions…
|
||||
functionSearch.search.key=O
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder
|
||||
# text displayed when the user searches for functions in a file
|
||||
symbolSearch.search.functionsPlaceholder=Search functions…
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder
|
||||
# text displayed when the user searches for variables in a file
|
||||
symbolSearch.search.variablesPlaceholder=Search variables…
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.search.key): The shortcut (cmd+shift+o) for
|
||||
# searching for a function or variable
|
||||
symbolSearch.search.key=O
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option
|
||||
# when searching text in a file
|
||||
symbolSearch.searchModifier.regex=Regex
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option
|
||||
# when searching text in a file
|
||||
symbolSearch.searchModifier.caseSensitive=Case sensitive
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option
|
||||
# when searching text in a file
|
||||
symbolSearch.searchModifier.wholeWord=Whole word
|
||||
|
||||
# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears
|
||||
# as a description in the notification panel popup, when multiple debuggers are
|
||||
@ -577,3 +622,7 @@ whyPaused.debugCommand=Paused on debugged function
|
||||
# in a info block explaining how the debugger is currently paused on an event
|
||||
# listener breakpoint set
|
||||
whyPaused.other=Debugger paused
|
||||
|
||||
# LOCALIZATION NOTE (ctrl): The text that is used for documenting
|
||||
# keyboard shortcuts that use the control key
|
||||
ctrl=Ctrl
|
||||
|
@ -11,7 +11,6 @@
|
||||
# A good criteria is the language in which you'd find the best
|
||||
# documentation on web development on the web.
|
||||
|
||||
|
||||
# LOCALIZATION NOTE (responsiveUI.rotate2): tooltip of the rotate button.
|
||||
responsiveUI.rotate2=Rotate
|
||||
|
||||
@ -67,3 +66,13 @@ responsiveUI.notificationReload=Reload
|
||||
responsiveUI.notificationReload_accesskey=R
|
||||
responsiveUI.dontShowReloadNotification=Never show again
|
||||
responsiveUI.dontShowReloadNotification_accesskey=N
|
||||
|
||||
# LOCALIZATION NOTE (responsiveUI.newVersionUserDisabled): notification that appears
|
||||
# when old RDM is displayed because the user has disabled new RDM.
|
||||
responsiveUI.newVersionUserDisabled=A new version of Responsive Design Mode is available, but it appears to be disabled. Please enable it and provide feedback, as this version will be removed.
|
||||
# LOCALIZATION NOTE (responsiveUI.newVersionE10sDisabled): notification that appears
|
||||
# when old RDM is displayed because e10s is disabled.
|
||||
responsiveUI.newVersionE10sDisabled=A new version of Responsive Design Mode is available, but it requires multi-process mode, which is currently disabled. Please enable it and provide feedback, as this version will be removed.
|
||||
# LOCALIZATION NOTE (responsiveUI.newVersionEnableAndRestart): button text in notification
|
||||
# to enable new RDM itself or e10s as a prerequisite for new RDM.
|
||||
responsiveUI.newVersionEnableAndRestart=Enable and Restart
|
@ -1,7 +1,5 @@
|
||||
# -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
# 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/.
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
#ifdef RELEASE_OR_BETA
|
||||
pref("devtools.debugger.new-debugger-frontend", false);
|
||||
@ -17,7 +15,7 @@ pref("devtools.debugger.chrome-debugging-websocket", false);
|
||||
pref("devtools.debugger.remote-host", "localhost");
|
||||
pref("devtools.debugger.remote-timeout", 20000);
|
||||
pref("devtools.debugger.pause-on-exceptions", false);
|
||||
pref("devtools.debugger.ignore-caught-exceptions", true);
|
||||
pref("devtools.debugger.ignore-caught-exceptions", false);
|
||||
pref("devtools.debugger.source-maps-enabled", true);
|
||||
pref("devtools.debugger.client-source-maps-enabled", true);
|
||||
pref("devtools.debugger.pretty-print-enabled", true);
|
||||
@ -38,4 +36,5 @@ pref("devtools.debugger.start-panel-collapsed", false);
|
||||
pref("devtools.debugger.end-panel-collapsed", false);
|
||||
pref("devtools.debugger.tabs", "[]");
|
||||
pref("devtools.debugger.pending-selected-location", "{}");
|
||||
|
||||
pref("devtools.debugger.pending-breakpoints", "[]");
|
||||
pref("devtools.debugger.expressions", "[]");
|
||||
|
@ -14,6 +14,8 @@ const EventEmitter = require("devtools/shared/event-emitter");
|
||||
|
||||
loader.lazyImporter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
loader.lazyImporter(this, "BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm");
|
||||
loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
|
||||
loader.lazyRequireGetter(this, "showDoorhanger",
|
||||
"devtools/client/shared/doorhanger", true);
|
||||
@ -27,9 +29,12 @@ loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerServer",
|
||||
"devtools/server/main", true);
|
||||
loader.lazyRequireGetter(this, "system", "devtools/shared/system");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ResponsiveUIManager"];
|
||||
|
||||
const NEW_RDM_ENABLED = "devtools.responsive.html.enabled";
|
||||
|
||||
const MIN_WIDTH = 50;
|
||||
const MIN_HEIGHT = 50;
|
||||
|
||||
@ -136,7 +141,7 @@ EventEmitter.decorate(Manager);
|
||||
// the new HTML RDM UI to function), delegate the ResponsiveUIManager API over to that
|
||||
// tool instead. Performing this delegation here allows us to contain the pref check to a
|
||||
// single place.
|
||||
if (Services.prefs.getBoolPref("devtools.responsive.html.enabled") &&
|
||||
if (Services.prefs.getBoolPref(NEW_RDM_ENABLED) &&
|
||||
Services.appinfo.browserTabsRemoteAutostart) {
|
||||
let { ResponsiveUIManager } =
|
||||
require("devtools/client/responsive.html/manager");
|
||||
@ -266,6 +271,8 @@ ResponsiveUI.prototype = {
|
||||
anchor: this.chromeDoc.querySelector("#content")
|
||||
});
|
||||
|
||||
this.showNewUINotification();
|
||||
|
||||
// Notify that responsive mode is on.
|
||||
this._telemetry.toolOpened("responsive");
|
||||
ResponsiveUIManager.emit("on", { tab: this.tab });
|
||||
@ -399,12 +406,14 @@ ResponsiveUI.prototype = {
|
||||
|
||||
this._telemetry.toolClosed("responsive");
|
||||
|
||||
if (this.tab.linkedBrowser.messageManager) {
|
||||
if (this.tab.linkedBrowser && this.tab.linkedBrowser.messageManager) {
|
||||
let stopped = this.waitForMessage("ResponsiveMode:Stop:Done");
|
||||
this.tab.linkedBrowser.messageManager.sendAsyncMessage("ResponsiveMode:Stop");
|
||||
yield stopped;
|
||||
}
|
||||
|
||||
this.hideNewUINotification();
|
||||
|
||||
this.inited = null;
|
||||
ResponsiveUIManager.emit("off", { tab: this.tab });
|
||||
}),
|
||||
@ -683,6 +692,69 @@ ResponsiveUI.prototype = {
|
||||
this.container.appendChild(bottomToolbar);
|
||||
},
|
||||
|
||||
showNewUINotification() {
|
||||
let nbox = this.mainWindow.gBrowser.getNotificationBox(this.browser);
|
||||
|
||||
// One reason we might be using old RDM is that the user explcitly disabled new RDM.
|
||||
// We should encourage them to use the new one, since the old one will be removed.
|
||||
if (Services.prefs.prefHasUserValue(NEW_RDM_ENABLED) &&
|
||||
!Services.prefs.getBoolPref(NEW_RDM_ENABLED)) {
|
||||
let buttons = [{
|
||||
label: this.strings.GetStringFromName("responsiveUI.newVersionEnableAndRestart"),
|
||||
callback: () => {
|
||||
Services.prefs.setBoolPref(NEW_RDM_ENABLED, true);
|
||||
BrowserUtils.restartApplication();
|
||||
},
|
||||
}];
|
||||
nbox.appendNotification(
|
||||
this.strings.GetStringFromName("responsiveUI.newVersionUserDisabled"),
|
||||
"responsive-ui-new-version-user-disabled",
|
||||
null,
|
||||
nbox.PRIORITY_INFO_LOW,
|
||||
buttons
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only show a notification about the new RDM UI on channels where there is an e10s
|
||||
// switch in the preferences UI (Dev. Ed, Nightly). On other channels, it is less
|
||||
// clear how a user would proceed here, so don't show a message.
|
||||
if (!system.constants.E10S_TESTING_ONLY) {
|
||||
return;
|
||||
}
|
||||
|
||||
let buttons = [{
|
||||
label: this.strings.GetStringFromName("responsiveUI.newVersionEnableAndRestart"),
|
||||
callback: () => {
|
||||
Services.prefs.setBoolPref("browser.tabs.remote.autostart", true);
|
||||
Services.prefs.setBoolPref("browser.tabs.remote.autostart.2", true);
|
||||
BrowserUtils.restartApplication();
|
||||
},
|
||||
}];
|
||||
nbox.appendNotification(
|
||||
this.strings.GetStringFromName("responsiveUI.newVersionE10sDisabled"),
|
||||
"responsive-ui-new-version-e10s-disabled",
|
||||
null,
|
||||
nbox.PRIORITY_INFO_LOW,
|
||||
buttons
|
||||
);
|
||||
},
|
||||
|
||||
hideNewUINotification() {
|
||||
if (!this.mainWindow.gBrowser || !this.mainWindow.gBrowser.getNotificationBox) {
|
||||
return;
|
||||
}
|
||||
let nbox = this.mainWindow.gBrowser.getNotificationBox(this.browser);
|
||||
let n = nbox.getNotificationWithValue("responsive-ui-new-version-user-disabled");
|
||||
if (n) {
|
||||
n.close();
|
||||
}
|
||||
n = nbox.getNotificationWithValue("responsive-ui-new-version-e10s-disabled");
|
||||
if (n) {
|
||||
n.close();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate and apply any user input on the editable menulist
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -69,7 +69,3 @@ function testRepRenderModes(modeTests, testName, componentUnderTest, gripStub,
|
||||
is(rendered.textContent, expectedOutput, message);
|
||||
});
|
||||
}
|
||||
|
||||
function getStubAttachedActorIds(gripStubs) {
|
||||
return gripStubs.map(gripStub => gripStub.actor);
|
||||
}
|
||||
|
@ -20,8 +20,12 @@ Test ArrayRep rep
|
||||
/* import-globals-from head.js */
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS, MODE } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, ArrayRep } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
MODE,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { ArrayRep } = REPS;
|
||||
|
||||
let componentUnderTest = ArrayRep;
|
||||
const maxLength = {
|
||||
@ -52,9 +56,7 @@ window.onload = Task.async(function* () {
|
||||
function testBasic() {
|
||||
// Test that correct rep is chosen
|
||||
const stub = [];
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: stub });
|
||||
is(renderedRep.type, ArrayRep.rep,
|
||||
`Rep correctly selects ${ArrayRep.rep.displayName}`);
|
||||
is(getRep(stub), ArrayRep.rep, "Rep correctly selects Array Rep");
|
||||
|
||||
|
||||
// Test rendering
|
||||
|
@ -17,8 +17,11 @@ Test Attribute rep
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, Attribute } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Attribute } = REPS;
|
||||
|
||||
try {
|
||||
testBasic();
|
||||
@ -31,8 +34,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testBasic() {
|
||||
// Test that correct rep is chosen
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: getStub() });
|
||||
is(renderedRep.type, Attribute.rep, `Rep correctly selects ${Attribute.rep.displayName}`);
|
||||
is(getRep(getStub()), Attribute.rep, "Rep correctly selects Attribute Rep");
|
||||
|
||||
// Test rendering
|
||||
const renderedComponent = renderComponent(Attribute.rep, { object: getStub() });
|
||||
|
@ -20,8 +20,12 @@ Test comment-node rep
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
const { REPS, MODE } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, CommentNode } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
MODE,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { CommentNode } = REPS;
|
||||
|
||||
let gripStub = {
|
||||
"type": "object",
|
||||
@ -40,9 +44,7 @@ window.onload = Task.async(function* () {
|
||||
};
|
||||
|
||||
// Test that correct rep is chosen.
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, CommentNode.rep,
|
||||
`Rep correctly selects ${CommentNode.rep.displayName}`);
|
||||
is(getRep(gripStub), CommentNode.rep, "Rep correctly selects CommentNode Rep");
|
||||
|
||||
// Test rendering.
|
||||
const renderedComponent = renderComponent(CommentNode.rep, { object: gripStub });
|
||||
|
@ -17,8 +17,11 @@ Test DateTime rep
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, DateTime } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { DateTime } = REPS;
|
||||
|
||||
try {
|
||||
testValid();
|
||||
@ -45,12 +48,11 @@ window.onload = Task.async(function* () {
|
||||
};
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, DateTime.rep, `Rep correctly selects ${DateTime.rep.displayName}`);
|
||||
is(getRep(gripStub), DateTime.rep, "Rep correctly selects DateTime Rep");
|
||||
|
||||
// Test rendering
|
||||
const renderedComponent = renderComponent(DateTime.rep, { object: gripStub });
|
||||
is(renderedComponent.textContent, "2016-03-30T21:17:24.859Z", "DateTime rep has expected text content for valid date");
|
||||
is(renderedComponent.textContent, "Date 2016-03-30T21:17:24.859Z", "DateTime rep has expected text content for valid date");
|
||||
}
|
||||
|
||||
function testInvalid() {
|
||||
|
@ -17,8 +17,11 @@ Test Document rep
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, Document } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Document } = REPS;
|
||||
|
||||
try {
|
||||
testBasic();
|
||||
@ -31,12 +34,11 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testBasic() {
|
||||
// Test that correct rep is chosen
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: getStub() });
|
||||
is(renderedRep.type, Document.rep, `Rep correctly selects ${Document.rep.displayName}`);
|
||||
is(getRep(getStub()), Document.rep, "Rep correctly selects Document Rep");
|
||||
|
||||
// Test rendering
|
||||
const renderedComponent = renderComponent(Document.rep, { object: getStub() });
|
||||
is(renderedComponent.textContent, "https://www.mozilla.org/en-US/firefox/new/",
|
||||
is(renderedComponent.textContent, "HTMLDocument https://www.mozilla.org/en-US/firefox/new/",
|
||||
"Document rep has expected text content");
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,10 @@ window.onload = Task.async(function* () {
|
||||
const {
|
||||
REPS,
|
||||
MODE,
|
||||
getRep,
|
||||
getSelectableInInspectorGrips,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, ElementNode } = REPS;
|
||||
let { ElementNode } = REPS;
|
||||
|
||||
try {
|
||||
yield testBodyNode();
|
||||
@ -48,9 +49,8 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testBodyNode() {
|
||||
const stub = getGripStub("testBodyNode");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: stub });
|
||||
is(renderedRep.type, ElementNode.rep,
|
||||
`Rep correctly selects ${ElementNode.rep.displayName} for body node`);
|
||||
is(getRep(stub), ElementNode.rep,
|
||||
"Rep correctly selects ElementNode Rep for body node");
|
||||
|
||||
const renderedComponent = renderComponent(ElementNode.rep, { object: stub });
|
||||
is(renderedComponent.textContent, `<body id="body-id" class="body-class">`,
|
||||
@ -64,9 +64,8 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testDocumentElement() {
|
||||
const stub = getGripStub("testDocumentElement");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: stub });
|
||||
is(renderedRep.type, ElementNode.rep,
|
||||
`Rep correctly selects ${ElementNode.rep.displayName} for document element node`);
|
||||
is(getRep(stub), ElementNode.rep,
|
||||
"Rep correctly selects ElementNode Rep for document element node");
|
||||
|
||||
const renderedComponent = renderComponent(ElementNode.rep, { object: stub });
|
||||
is(renderedComponent.textContent, `<html dir="ltr" lang="en-US">`,
|
||||
@ -80,9 +79,8 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testNode() {
|
||||
const stub = getGripStub("testNode");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: stub });
|
||||
is(renderedRep.type, ElementNode.rep,
|
||||
`Rep correctly selects ${ElementNode.rep.displayName} for element node`);
|
||||
is(getRep(stub), ElementNode.rep,
|
||||
"Rep correctly selects ElementNode Rep for element node");
|
||||
|
||||
const renderedComponent = renderComponent(ElementNode.rep, { object: stub });
|
||||
is(renderedComponent.textContent,
|
||||
@ -99,9 +97,8 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testNodeWithLeadingAndTrailingSpacesClassName() {
|
||||
const stub = getGripStub("testNodeWithLeadingAndTrailingSpacesClassName");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: stub });
|
||||
is(renderedRep.type, ElementNode.rep,
|
||||
`Rep correctly selects ${ElementNode.rep.displayName} for element node`);
|
||||
is(getRep(stub), ElementNode.rep,
|
||||
"Rep correctly selects ElementNode Rep for element node");
|
||||
|
||||
const renderedComponent = renderComponent(ElementNode.rep, { object: stub });
|
||||
is(renderedComponent.textContent,
|
||||
@ -119,8 +116,7 @@ window.onload = Task.async(function* () {
|
||||
function testNodeWithoutAttributes() {
|
||||
const stub = getGripStub("testNodeWithoutAttributes");
|
||||
|
||||
const renderedComponent = renderComponent(ElementNode.rep, { object: stub });
|
||||
is(renderedComponent.textContent, "<p>",
|
||||
is(getRep(stub), ElementNode.rep,
|
||||
"Element node rep has expected text content for element node without attributes");
|
||||
|
||||
const tinyRenderedComponent = renderComponent(
|
||||
@ -147,8 +143,7 @@ window.onload = Task.async(function* () {
|
||||
function testSvgNode() {
|
||||
const stub = getGripStub("testSvgNode");
|
||||
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: stub });
|
||||
is(renderedRep.type, ElementNode.rep,
|
||||
is(getRep(stub), ElementNode.rep,
|
||||
`Rep correctly selects ${ElementNode.rep.displayName} for SVG element node`);
|
||||
|
||||
const renderedComponent = renderComponent(ElementNode.rep, { object: stub });
|
||||
@ -165,8 +160,7 @@ window.onload = Task.async(function* () {
|
||||
function testSvgNodeInXHTML() {
|
||||
const stub = getGripStub("testSvgNodeInXHTML");
|
||||
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: stub });
|
||||
is(renderedRep.type, ElementNode.rep,
|
||||
is(getRep(stub), ElementNode.rep,
|
||||
`Rep correctly selects ${ElementNode.rep.displayName} for XHTML SVG element node`);
|
||||
|
||||
const renderedComponent = renderComponent(ElementNode.rep, { object: stub });
|
||||
@ -182,12 +176,9 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testOnMouseOver() {
|
||||
const stub = getGripStub("testNode");
|
||||
debugger;
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
is(grips.length, 1, "the stub has one node grip");
|
||||
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let mouseOverValue;
|
||||
let onDOMNodeMouseOver = (object) => {
|
||||
mouseOverValue = object;
|
||||
@ -195,7 +186,6 @@ window.onload = Task.async(function* () {
|
||||
const renderedComponent = renderComponent(ElementNode.rep, {
|
||||
object: stub,
|
||||
onDOMNodeMouseOver,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
TestUtils.Simulate.mouseOver(renderedComponent);
|
||||
@ -209,8 +199,6 @@ window.onload = Task.async(function* () {
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
is(grips.length, 1, "the stub has one node grip");
|
||||
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let called = false;
|
||||
let onDOMNodeMouseOut = (object) => {
|
||||
called = true;
|
||||
@ -218,7 +206,6 @@ window.onload = Task.async(function* () {
|
||||
const renderedComponent = renderComponent(ElementNode.rep, {
|
||||
object: stub,
|
||||
onDOMNodeMouseOut,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
TestUtils.Simulate.mouseOut(renderedComponent);
|
||||
@ -231,8 +218,6 @@ window.onload = Task.async(function* () {
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
is(grips.length, 1, "the stub has one node grip");
|
||||
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let inspectIconClickedValue = null;
|
||||
let inspectIconClickedEvent = null;
|
||||
|
||||
@ -242,28 +227,18 @@ window.onload = Task.async(function* () {
|
||||
};
|
||||
|
||||
const renderedComponentWithoutInspectIcon = renderComponent(ElementNode.rep, {
|
||||
object: stub,
|
||||
object: getGripStub("testDisconnectedNode"),
|
||||
onInspectIconClick,
|
||||
attachedActorIds: ["someOtherId"]
|
||||
});
|
||||
is(renderedComponentWithoutInspectIcon.querySelector(".open-inspector"), null,
|
||||
"There isn't an inspect icon when actor is not in attachedActorIds");
|
||||
"There isn't an inspect icon when the node is not in the DOM tree");
|
||||
|
||||
let renderedComponent = renderComponent(ElementNode.rep, {
|
||||
const renderedComponent = renderComponent(ElementNode.rep, {
|
||||
object: stub,
|
||||
onInspectIconClick,
|
||||
});
|
||||
let inspectIconNode = renderedComponent.querySelector(".open-inspector");
|
||||
ok(inspectIconNode !== null,
|
||||
"There is an inspect icon when attachedActorIds is not specified");
|
||||
|
||||
renderedComponent = renderComponent(ElementNode.rep, {
|
||||
object: stub,
|
||||
onInspectIconClick,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
inspectIconNode = renderedComponent.querySelector(".open-inspector");
|
||||
const inspectIconNode = renderedComponent.querySelector(".open-inspector");
|
||||
ok(inspectIconNode !== null, "There is an inspect icon as expected");
|
||||
TestUtils.Simulate.click(inspectIconNode);
|
||||
|
||||
@ -345,6 +320,32 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "input",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "newtab-customize-button",
|
||||
"dir": "ltr",
|
||||
"title": "Customize your New Tab page",
|
||||
"class": "bar baz",
|
||||
"value": "foo",
|
||||
"type": "button"
|
||||
},
|
||||
"attributesLength": 6
|
||||
}
|
||||
};
|
||||
case "testDisconnectedNode":
|
||||
return {
|
||||
"type": "object",
|
||||
"actor": "server1.conn2.child1/obj116",
|
||||
"class": "HTMLInputElement",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "input",
|
||||
"isConnected": false,
|
||||
"attributes": {
|
||||
"id": "newtab-customize-button",
|
||||
"dir": "ltr",
|
||||
|
@ -19,8 +19,12 @@ Test Error rep
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS, MODE } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, ErrorRep } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
MODE,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { ErrorRep } = REPS;
|
||||
|
||||
try {
|
||||
// Test errors with different properties
|
||||
@ -47,9 +51,7 @@ window.onload = Task.async(function* () {
|
||||
function testSimpleError() {
|
||||
// Test object = `new Error("Error message")`
|
||||
const stub = getGripStub("testSimpleError");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for Error object`);
|
||||
is(getRep(stub), ErrorRep.rep, "Rep correctly selects Error Rep for Error object");
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
@ -77,9 +79,8 @@ window.onload = Task.async(function* () {
|
||||
* errorFoo();`
|
||||
*/
|
||||
const stub = getGripStub("testMultilineStackError");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for Error object`);
|
||||
is(getRep(stub), ErrorRep.rep,
|
||||
`Rep correctly selects Error Rep for Error object`);
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
@ -99,9 +100,8 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testErrorWithoutStacktrace() {
|
||||
const stub = getGripStub("testErrorWithoutStacktrace");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for Error object`);
|
||||
is(getRep(stub), ErrorRep.rep,
|
||||
`Rep correctly selects Error Rep for Error object`);
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
@ -118,9 +118,8 @@ window.onload = Task.async(function* () {
|
||||
function testEvalError() {
|
||||
// Test object = `new EvalError("EvalError message")`
|
||||
const stub = getGripStub("testEvalError");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for EvalError object`);
|
||||
is(getRep(stub), ErrorRep.rep,
|
||||
`Rep correctly selects Error Rep for EvalError object`);
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
@ -139,9 +138,8 @@ window.onload = Task.async(function* () {
|
||||
function testInternalError() {
|
||||
// Test object = `new InternalError("InternalError message")`
|
||||
const stub = getGripStub("testInternalError");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for InternalError object`);
|
||||
is(getRep(stub), ErrorRep.rep,
|
||||
`Rep correctly selects Error Rep for InternalError object`);
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
@ -160,9 +158,8 @@ window.onload = Task.async(function* () {
|
||||
function testRangeError() {
|
||||
// Test object = `new RangeError("RangeError message")`
|
||||
const stub = getGripStub("testRangeError");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for RangeError object`);
|
||||
is(getRep(stub), ErrorRep.rep,
|
||||
`Rep correctly selects Error Rep for RangeError object`);
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
@ -181,9 +178,8 @@ window.onload = Task.async(function* () {
|
||||
function testReferenceError() {
|
||||
// Test object = `new ReferenceError("ReferenceError message"`
|
||||
const stub = getGripStub("testReferenceError");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for ReferenceError object`);
|
||||
is(getRep(stub), ErrorRep.rep,
|
||||
`Rep correctly selects Error Rep for ReferenceError object`);
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
@ -202,9 +198,8 @@ window.onload = Task.async(function* () {
|
||||
function testSyntaxError() {
|
||||
// Test object = `new SyntaxError("SyntaxError message"`
|
||||
const stub = getGripStub("testSyntaxError");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for SyntaxError object`);
|
||||
is(getRep(stub), ErrorRep.rep,
|
||||
`Rep correctly selects Error Rep for SyntaxError object`);
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
@ -223,9 +218,8 @@ window.onload = Task.async(function* () {
|
||||
function testTypeError() {
|
||||
// Test object = `new TypeError("TypeError message"`
|
||||
const stub = getGripStub("testTypeError");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for TypeError`);
|
||||
is(getRep(stub), ErrorRep.rep,
|
||||
`Rep correctly selects Error Rep for TypeError`);
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
@ -244,9 +238,8 @@ window.onload = Task.async(function* () {
|
||||
function testURIError() {
|
||||
// Test object = `new URIError("URIError message")`
|
||||
const stub = getGripStub("testURIError");
|
||||
const renderedRep = shallowRenderComponent(Rep, {object: stub});
|
||||
is(renderedRep.type, ErrorRep.rep,
|
||||
`Rep correctly selects ${ErrorRep.rep.displayName} for URIError object`);
|
||||
is(getRep(stub), ErrorRep.rep,
|
||||
`Rep correctly selects Error Rep for URIError object`);
|
||||
|
||||
const renderedComponent = renderComponent(ErrorRep.rep, {object: stub});
|
||||
is(renderedComponent.textContent,
|
||||
|
@ -20,14 +20,14 @@ window.onload = Task.async(function* () {
|
||||
const {
|
||||
REPS,
|
||||
MODE,
|
||||
getRep,
|
||||
getSelectableInInspectorGrips,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, Event } = REPS;
|
||||
let { Event } = REPS;
|
||||
|
||||
try {
|
||||
// Test that correct rep is chosen
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: getGripStub("testEvent") });
|
||||
is(renderedRep.type, Event.rep, `Rep correctly selects ${Event.rep.displayName}`);
|
||||
is(getRep(getGripStub("testEvent")), Event.rep, "Rep correctly selects Event Rep");
|
||||
|
||||
yield testEvent();
|
||||
yield testMouseEvent();
|
||||
@ -129,8 +129,6 @@ window.onload = Task.async(function* () {
|
||||
|
||||
is(grips.length, 1, "the stub has one node grip");
|
||||
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let mouseOverValue;
|
||||
let onDOMNodeMouseOver = (object) => {
|
||||
mouseOverValue = object;
|
||||
@ -138,7 +136,6 @@ window.onload = Task.async(function* () {
|
||||
const renderedComponent = renderComponent(Event.rep, {
|
||||
object: stub,
|
||||
onDOMNodeMouseOver,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
const node = renderedComponent.querySelector(".objectBox-node");
|
||||
@ -153,8 +150,6 @@ window.onload = Task.async(function* () {
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
is(grips.length, 1, "the stub has one node grip");
|
||||
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let called = false;
|
||||
let onDOMNodeMouseOut = (object) => {
|
||||
called = true;
|
||||
@ -162,7 +157,6 @@ window.onload = Task.async(function* () {
|
||||
const renderedComponent = renderComponent(Event.rep, {
|
||||
object: stub,
|
||||
onDOMNodeMouseOut,
|
||||
attachedActorIds
|
||||
});
|
||||
|
||||
const node = renderedComponent.querySelector(".objectBox-node");
|
||||
@ -176,34 +170,19 @@ window.onload = Task.async(function* () {
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
is(grips.length, 1, "the stub has one node grip");
|
||||
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let inspectIconClickedValue = null;
|
||||
let onInspectIconClick = (object) => {
|
||||
inspectIconClickedValue = object;
|
||||
};
|
||||
|
||||
let renderedComponentWithoutInspectIcon = renderComponent(Event.rep, {
|
||||
object: stub,
|
||||
onInspectIconClick,
|
||||
attachedActorIds: ["someOtherId"]
|
||||
});
|
||||
is(renderedComponentWithoutInspectIcon.querySelector(".open-inspector"), null,
|
||||
"There isn't an inspect icon when the actor is not in attachedActorIds");
|
||||
|
||||
is(renderedComponentWithoutInspectIcon.querySelector(".open-inspector"), null,
|
||||
"There isn't an inspect icon when attachedActorIds does not have keys " +
|
||||
"matching grip event's target item");
|
||||
|
||||
const renderedComponent = renderComponent(Event.rep, {
|
||||
object: stub,
|
||||
onInspectIconClick,
|
||||
attachedActorIds
|
||||
});
|
||||
|
||||
const icon = renderedComponent.querySelector(".open-inspector");
|
||||
ok(icon !== null, "There is an icon as expected when passing a matching " +
|
||||
"attachedActorIds item");
|
||||
ok(icon !== null,
|
||||
"There is an inspect icon when the node is connected to the DOM tree");
|
||||
|
||||
TestUtils.Simulate.click(icon);
|
||||
|
||||
@ -344,6 +323,7 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "div",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "test"
|
||||
},
|
||||
|
@ -18,8 +18,11 @@ Test fallback for rep rendering when a rep fails to render.
|
||||
<script type="application/javascript">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, ArrayRep, RegExp } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { ArrayRep, RegExp } = REPS;
|
||||
|
||||
// Force the RegExp rep to crash by creating RegExp grip that throws when accessing
|
||||
// the displayString property
|
||||
@ -37,8 +40,7 @@ window.onload = Task.async(function* () {
|
||||
};
|
||||
|
||||
// Test that correct rep is chosen.
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, RegExp.rep, `Rep correctly selects ${RegExp.rep.displayName}`);
|
||||
is(getRep(gripStub), RegExp.rep, "Rep correctly selects RegExp Rep");
|
||||
|
||||
// Test fallback message is displayed when rendering bad rep directly.
|
||||
let renderedComponent = renderComponent(RegExp.rep, { object: gripStub });
|
||||
|
@ -17,16 +17,19 @@ Test Func rep
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS, MODE } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, Func } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
MODE,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Func } = REPS;
|
||||
|
||||
const componentUnderTest = Func;
|
||||
|
||||
try {
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub("testNamed");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Func.rep, `Rep correctly selects ${Func.rep.displayName}`);
|
||||
is(getRep(gripStub), Func.rep, "Rep correctly selects Func Rep");
|
||||
|
||||
yield testNamed();
|
||||
yield testVarNamed();
|
||||
|
@ -20,9 +20,10 @@ window.onload = Task.async(function* () {
|
||||
const {
|
||||
REPS,
|
||||
MODE,
|
||||
getRep,
|
||||
getSelectableInInspectorGrips,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, GripArray } = REPS;
|
||||
let { GripArray } = REPS;
|
||||
|
||||
let componentUnderTest = GripArray;
|
||||
const maxLength = {
|
||||
@ -60,8 +61,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub("testBasic");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, GripArray.rep, `Rep correctly selects ${GripArray.rep.displayName}`);
|
||||
is(getRep(gripStub), GripArray.rep, "Rep correctly selects GripArray Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `Array []`;
|
||||
@ -328,8 +328,6 @@ window.onload = Task.async(function* () {
|
||||
|
||||
is(grips.length, 3, "the stub has three node grips");
|
||||
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let mouseOverValue;
|
||||
let onDOMNodeMouseOver = (object) => {
|
||||
mouseOverValue = object;
|
||||
@ -337,7 +335,6 @@ window.onload = Task.async(function* () {
|
||||
const renderedComponent = renderComponent(GripArray.rep, {
|
||||
object: stub,
|
||||
onDOMNodeMouseOver,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
const nodes = renderedComponent.querySelectorAll(".objectBox-node");
|
||||
@ -357,8 +354,6 @@ window.onload = Task.async(function* () {
|
||||
|
||||
is(grips.length, 3, "the stub has three node grips");
|
||||
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let called = 0;
|
||||
let onDOMNodeMouseOut = (object) => {
|
||||
called++;
|
||||
@ -366,7 +361,6 @@ window.onload = Task.async(function* () {
|
||||
const renderedComponent = renderComponent(GripArray.rep, {
|
||||
object: stub,
|
||||
onDOMNodeMouseOut,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
const nodes = renderedComponent.querySelectorAll(".objectBox-node");
|
||||
@ -377,35 +371,30 @@ window.onload = Task.async(function* () {
|
||||
}
|
||||
|
||||
function testOnDomNodeInspectIconClick() {
|
||||
const stub = getGripStub("testNodeList");
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
|
||||
is(grips.length, 3, "the stub has three node grips");
|
||||
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let inspectIconClickedValue = null;
|
||||
let onInspectIconClick = (object) => {
|
||||
inspectIconClickedValue = object;
|
||||
};
|
||||
|
||||
let renderedComponentWithoutInspectIcon = renderComponent(GripArray.rep, {
|
||||
object: stub,
|
||||
object: getGripStub("testDisconnectedNodeList"),
|
||||
onInspectIconClick,
|
||||
attachedActorIds: ["someOtherId"],
|
||||
});
|
||||
is(renderedComponentWithoutInspectIcon.querySelector(".open-inspector"), null,
|
||||
"There isn't an inspect icon when the actor is not in attachedActorIds");
|
||||
"There isn't an inspect icon when the nodes are not connected to the DOM tree");
|
||||
|
||||
const stub = getGripStub("testNodeList");
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
|
||||
is(grips.length, 3, "the stub has three node grips");
|
||||
const renderedComponent = renderComponent(GripArray.rep, {
|
||||
object: stub,
|
||||
onInspectIconClick,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
const icons = renderedComponent.querySelectorAll(".open-inspector");
|
||||
is(icons.length, grips.length,
|
||||
"There is an icon for each grip array item with a matching attachedNodeFront");
|
||||
"There is an icon for each node connected to the DOM tree");
|
||||
|
||||
icons.forEach((icon, index) => {
|
||||
TestUtils.Simulate.click(icon);
|
||||
@ -678,6 +667,7 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-1",
|
||||
"class": "btn btn-log",
|
||||
@ -698,6 +688,7 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-2",
|
||||
"class": "btn btn-err",
|
||||
@ -718,6 +709,87 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-3",
|
||||
"class": "btn btn-count",
|
||||
"type": "button"
|
||||
},
|
||||
"attributesLength": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
case "testDisconnectedNodeList":
|
||||
return {
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj51",
|
||||
"class": "NodeList",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 3,
|
||||
"preview": {
|
||||
"kind": "ArrayLike",
|
||||
"length": 3,
|
||||
"items": [
|
||||
{
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj52",
|
||||
"class": "HTMLButtonElement",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": false,
|
||||
"attributes": {
|
||||
"id": "btn-1",
|
||||
"class": "btn btn-log",
|
||||
"type": "button"
|
||||
},
|
||||
"attributesLength": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj53",
|
||||
"class": "HTMLButtonElement",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": false,
|
||||
"attributes": {
|
||||
"id": "btn-2",
|
||||
"class": "btn btn-err",
|
||||
"type": "button"
|
||||
},
|
||||
"attributesLength": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj54",
|
||||
"class": "HTMLButtonElement",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": false,
|
||||
"attributes": {
|
||||
"id": "btn-3",
|
||||
"class": "btn btn-count",
|
||||
|
@ -22,9 +22,10 @@ window.onload = Task.async(function* () {
|
||||
const {
|
||||
REPS,
|
||||
MODE,
|
||||
getRep,
|
||||
getSelectableInInspectorGrips,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, GripMap } = REPS;
|
||||
let { GripMap } = REPS;
|
||||
|
||||
const componentUnderTest = GripMap;
|
||||
|
||||
@ -55,8 +56,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub("testEmptyMap");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, GripMap.rep, `Rep correctly selects ${GripMap.rep.displayName}`);
|
||||
is(getRep(gripStub), GripMap.rep, "Rep correctly selects GripMap Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `Map { }`;
|
||||
@ -118,8 +118,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub("testWeakMap");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, GripMap.rep, `Rep correctly selects ${GripMap.rep.displayName}`);
|
||||
is(getRep(gripStub), GripMap.rep, "Rep correctly selects GripMap Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `WeakMap { Object: "value-a" }`;
|
||||
@ -254,11 +253,9 @@ window.onload = Task.async(function* () {
|
||||
|
||||
const valuesGrips = getSelectableInInspectorGrips(nodeValuedStub);
|
||||
is(valuesGrips.length, 3, "the stub has three node grips");
|
||||
const valuesattachedActorIds = getStubAttachedActorIds(valuesGrips);
|
||||
|
||||
const keysGrips = getSelectableInInspectorGrips(nodeKeyedStub);
|
||||
is(keysGrips.length, 3, "the stub has three node grips");
|
||||
const keysAttachedActorIds = getStubAttachedActorIds(keysGrips);
|
||||
|
||||
let mouseOverValue;
|
||||
let onDOMNodeMouseOver = (object) => {
|
||||
@ -269,7 +266,6 @@ window.onload = Task.async(function* () {
|
||||
const nodeValuedRenderedComponent = renderComponent(GripMap.rep, {
|
||||
object: nodeValuedStub,
|
||||
onDOMNodeMouseOver,
|
||||
attachedActorIds: valuesattachedActorIds,
|
||||
});
|
||||
|
||||
let nodes = nodeValuedRenderedComponent.querySelectorAll(".objectBox-node");
|
||||
@ -284,7 +280,6 @@ window.onload = Task.async(function* () {
|
||||
const nodeKeyedRenderedComponent = renderComponent(GripMap.rep, {
|
||||
object: nodeKeyedStub,
|
||||
onDOMNodeMouseOver,
|
||||
attachedActorIds: keysAttachedActorIds,
|
||||
});
|
||||
|
||||
nodes = nodeKeyedRenderedComponent.querySelectorAll(".objectBox-node");
|
||||
@ -302,11 +297,9 @@ window.onload = Task.async(function* () {
|
||||
|
||||
const valuesGrips = getSelectableInInspectorGrips(nodeValuedStub);
|
||||
is(valuesGrips.length, 3, "the stub has three node grips");
|
||||
const valuesattachedActorIds = getStubAttachedActorIds(valuesGrips);
|
||||
|
||||
const keysGrips = getSelectableInInspectorGrips(nodeKeyedStub);
|
||||
is(keysGrips.length, 3, "the stub has three node grips");
|
||||
const keysAttachedActorIds = getStubAttachedActorIds(keysGrips);
|
||||
|
||||
let called = 0;
|
||||
let onDOMNodeMouseOut = (object) => {
|
||||
@ -317,7 +310,6 @@ window.onload = Task.async(function* () {
|
||||
const nodeValuedRenderedComponent = renderComponent(GripMap.rep, {
|
||||
object: nodeValuedStub,
|
||||
onDOMNodeMouseOut,
|
||||
attachedActorIds: valuesattachedActorIds,
|
||||
});
|
||||
|
||||
let nodes = nodeValuedRenderedComponent.querySelectorAll(".objectBox-node");
|
||||
@ -330,7 +322,6 @@ window.onload = Task.async(function* () {
|
||||
const nodeKeyedRenderedComponent = renderComponent(GripMap.rep, {
|
||||
object: nodeKeyedStub,
|
||||
onDOMNodeMouseOut,
|
||||
attachedActorIds: keysAttachedActorIds,
|
||||
});
|
||||
|
||||
nodes = nodeKeyedRenderedComponent.querySelectorAll(".objectBox-node");
|
||||
@ -348,11 +339,9 @@ window.onload = Task.async(function* () {
|
||||
|
||||
const valuesGrips = getSelectableInInspectorGrips(nodeValuedStub);
|
||||
is(valuesGrips.length, 3, "the stub has three node grips");
|
||||
const valuesattachedActorIds = getStubAttachedActorIds(valuesGrips);
|
||||
|
||||
const keysGrips = getSelectableInInspectorGrips(nodeKeyedStub);
|
||||
is(keysGrips.length, 3, "the stub has three node grips");
|
||||
const keysAttachedActorIds = getStubAttachedActorIds(keysGrips);
|
||||
|
||||
let inspectIconClickedValue = null;
|
||||
let onInspectIconClick = (object) => {
|
||||
@ -360,23 +349,21 @@ window.onload = Task.async(function* () {
|
||||
};
|
||||
|
||||
const renderedComponentWithoutInspectIcon = renderComponent(GripMap.rep, {
|
||||
object: nodeValuedStub,
|
||||
object: getGripStub("testDisconnectedNodeValuedMap"),
|
||||
onInspectIconClick,
|
||||
attachedActorIds: [],
|
||||
});
|
||||
is(renderedComponentWithoutInspectIcon.querySelector(".open-inspector"), null,
|
||||
"There isn't an inspect icon when the actor is not in attachedActorIds");
|
||||
"There isn't an inspect icon when nodes are not connected to the DOM tree");
|
||||
|
||||
info("Testing onInspectIconClick on node valued Map");
|
||||
const nodeValuedRenderedComponent = renderComponent(GripMap.rep, {
|
||||
object: nodeValuedStub,
|
||||
onInspectIconClick,
|
||||
attachedActorIds: valuesattachedActorIds,
|
||||
});
|
||||
|
||||
let icons = nodeValuedRenderedComponent.querySelectorAll(".open-inspector");
|
||||
is(icons.length, valuesGrips.length,
|
||||
"There is an icon for each map value with a matching attachedNodeFront");
|
||||
"There is an icon for each node connected to the DOM tree");
|
||||
|
||||
icons.forEach((icon, index) => {
|
||||
TestUtils.Simulate.click(icon);
|
||||
@ -388,12 +375,11 @@ window.onload = Task.async(function* () {
|
||||
const nodeKeyedRenderedComponent = renderComponent(GripMap.rep, {
|
||||
object: nodeKeyedStub,
|
||||
onInspectIconClick,
|
||||
attachedActorIds: keysAttachedActorIds,
|
||||
});
|
||||
|
||||
icons = nodeKeyedRenderedComponent.querySelectorAll(".open-inspector");
|
||||
is(icons.length, keysGrips.length,
|
||||
"There is an icon for each map key with a matching attachedNodeFront");
|
||||
"There is an icon for each node connected to the DOM tree");
|
||||
|
||||
icons.forEach((icon, index) => {
|
||||
TestUtils.Simulate.click(icon);
|
||||
@ -607,6 +593,92 @@ window.onload = Task.async(function* () {
|
||||
}
|
||||
};
|
||||
|
||||
case "testDisconnectedNodeValuedMap":
|
||||
return {
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj213",
|
||||
"class": "Map",
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "MapLike",
|
||||
"size": 3,
|
||||
"entries": [
|
||||
[
|
||||
"item-0",
|
||||
{
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj214",
|
||||
"class": "HTMLButtonElement",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": false,
|
||||
"attributes": {
|
||||
"id": "btn-1",
|
||||
"class": "btn btn-log",
|
||||
"type": "button"
|
||||
},
|
||||
"attributesLength": 3
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
"item-1",
|
||||
{
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj215",
|
||||
"class": "HTMLButtonElement",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": false,
|
||||
"attributes": {
|
||||
"id": "btn-2",
|
||||
"class": "btn btn-err",
|
||||
"type": "button"
|
||||
},
|
||||
"attributesLength": 3
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
"item-2",
|
||||
{
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj216",
|
||||
"class": "HTMLButtonElement",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": false,
|
||||
"attributes": {
|
||||
"id": "btn-3",
|
||||
"class": "btn btn-count",
|
||||
"type": "button"
|
||||
},
|
||||
"attributesLength": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
case "testNodeValuedMap":
|
||||
return {
|
||||
"type": "object",
|
||||
@ -631,6 +703,7 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-1",
|
||||
"class": "btn btn-log",
|
||||
@ -654,6 +727,7 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-2",
|
||||
"class": "btn btn-err",
|
||||
@ -677,6 +751,7 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-3",
|
||||
"class": "btn btn-count",
|
||||
@ -713,6 +788,7 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-1",
|
||||
"class": "btn btn-log",
|
||||
@ -736,6 +812,7 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-3",
|
||||
"class": "btn btn-count",
|
||||
@ -759,6 +836,7 @@ window.onload = Task.async(function* () {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-2",
|
||||
"class": "btn btn-err",
|
||||
|
@ -20,9 +20,10 @@ window.onload = Task.async(function* () {
|
||||
const {
|
||||
REPS,
|
||||
MODE,
|
||||
getRep,
|
||||
getSelectableInInspectorGrips,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, Grip } = REPS;
|
||||
let { Grip } = REPS;
|
||||
|
||||
const componentUnderTest = Grip;
|
||||
|
||||
@ -66,8 +67,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub("testBasic");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
is(getRep(gripStub), Grip.rep, "Rep correctly selects Grip Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `Object { }`;
|
||||
@ -100,8 +100,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub(testName);
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
is(getRep(gripStub), Grip.rep, "Rep correctly selects Grip Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `Boolean { true }`;
|
||||
@ -134,8 +133,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub(testName);
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
is(getRep(gripStub), Grip.rep, "Rep correctly selects Grip Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `Number { 42 }`;
|
||||
@ -168,8 +166,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub(testName);
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
is(getRep(gripStub), Grip.rep, "Rep correctly selects Grip Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `String { "foo" }`;
|
||||
@ -202,8 +199,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub(testName);
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
is(getRep(gripStub), Grip.rep, "Rep correctly selects Grip Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `Proxy { <target>: Object, <handler>: [3] }`;
|
||||
@ -236,8 +232,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub(testName);
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
is(getRep(gripStub), Grip.rep, "Rep correctly selects Grip Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `ArrayBuffer { byteLength: 10 }`;
|
||||
@ -270,8 +265,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub(testName);
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
is(getRep(gripStub), Grip.rep, "Rep correctly selects Grip Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `SharedArrayBuffer { byteLength: 5 }`;
|
||||
@ -304,8 +298,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub(testName);
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
is(getRep(gripStub), Grip.rep, "Rep correctly selects Grip Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput =
|
||||
@ -412,8 +405,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
// Test that correct rep is chosen
|
||||
const gripStub = getGripStub("testNonEnumerableProps");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
|
||||
is(renderedRep.type, Grip.rep, `Rep correctly selects ${Grip.rep.displayName}`);
|
||||
is(getRep(gripStub), Grip.rep, "Rep correctly selects Grip Rep");
|
||||
|
||||
// Test rendering
|
||||
const defaultOutput = `Object { }`;
|
||||
@ -537,7 +529,6 @@ window.onload = Task.async(function* () {
|
||||
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
is(grips.length, 2, "the stub has two node grips");
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let mouseOverValue;
|
||||
let called = 0;
|
||||
@ -549,7 +540,6 @@ window.onload = Task.async(function* () {
|
||||
const renderedComponent = renderComponent(Grip.rep, {
|
||||
object: stub,
|
||||
onDOMNodeMouseOver,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
const nodes = renderedComponent.querySelectorAll(".objectBox-node");
|
||||
@ -568,7 +558,6 @@ window.onload = Task.async(function* () {
|
||||
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
is(grips.length, 2, "the stub has two node grips");
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let called = 0;
|
||||
let onDOMNodeMouseOut = (object) => {
|
||||
@ -578,7 +567,6 @@ window.onload = Task.async(function* () {
|
||||
const renderedComponent = renderComponent(Grip.rep, {
|
||||
object: stub,
|
||||
onDOMNodeMouseOut,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
const nodes = renderedComponent.querySelectorAll(".objectBox-node");
|
||||
@ -593,7 +581,6 @@ window.onload = Task.async(function* () {
|
||||
|
||||
const grips = getSelectableInInspectorGrips(stub);
|
||||
is(grips.length, 2, "the stub has two node grips");
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let inspectIconClickedValue = null;
|
||||
let onInspectIconClick = (object) => {
|
||||
@ -601,26 +588,20 @@ window.onload = Task.async(function* () {
|
||||
};
|
||||
|
||||
let renderedComponentWithoutInspectIcon = renderComponent(Grip.rep, {
|
||||
object: stub,
|
||||
object: getGripStub("testObjectWithDisconnectedNodes"),
|
||||
onInspectIconClick,
|
||||
attachedActorIds: ["someOtherId"],
|
||||
});
|
||||
is(renderedComponentWithoutInspectIcon.querySelector(".open-inspector"), null,
|
||||
"There isn't an inspect icon when the actor is not in attachedActorIds");
|
||||
|
||||
is(renderedComponentWithoutInspectIcon.querySelector(".open-inspector"), null,
|
||||
"There isn't an inspect icon when attachedActorIds does not have keys " +
|
||||
"matching grip properties");
|
||||
"There isn't an inspect icon when the node is not connected to the DOM tree");
|
||||
|
||||
const renderedComponent = renderComponent(Grip.rep, {
|
||||
object: stub,
|
||||
onInspectIconClick,
|
||||
attachedActorIds,
|
||||
});
|
||||
|
||||
const icons = renderedComponent.querySelectorAll(".open-inspector");
|
||||
is(icons.length, 2,
|
||||
"There is an icon for each grip property matching an attachedNodeFront");
|
||||
"There is an icon for each node connected to the DOM tree");
|
||||
|
||||
icons.forEach((icon, index) => {
|
||||
TestUtils.Simulate.click(icon);
|
||||
@ -1169,6 +1150,72 @@ window.onload = Task.async(function* () {
|
||||
}
|
||||
};
|
||||
case "testObjectWithNodes":
|
||||
return {
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj214",
|
||||
"class": "Object",
|
||||
"ownPropertyLength": 2,
|
||||
"preview": {
|
||||
"kind": "Object",
|
||||
"ownProperties": {
|
||||
"foo": {
|
||||
"configurable": true,
|
||||
"enumerable": true,
|
||||
"writable": true,
|
||||
"value": {
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj215",
|
||||
"class": "HTMLButtonElement",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-1",
|
||||
"class": "btn btn-log",
|
||||
"type": "button"
|
||||
},
|
||||
"attributesLength": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
"bar": {
|
||||
"configurable": true,
|
||||
"enumerable": true,
|
||||
"writable": true,
|
||||
"value": {
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj216",
|
||||
"class": "HTMLButtonElement",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"kind": "DOMNode",
|
||||
"nodeType": 1,
|
||||
"nodeName": "button",
|
||||
"isConnected": true,
|
||||
"attributes": {
|
||||
"id": "btn-2",
|
||||
"class": "btn btn-err",
|
||||
"type": "button"
|
||||
},
|
||||
"attributesLength": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ownPropertiesLength": 2,
|
||||
"safeGetterValues": {}
|
||||
}
|
||||
};
|
||||
case "testObjectWithDisconnectedNodes":
|
||||
return {
|
||||
"type": "object",
|
||||
"actor": "server1.conn1.child1/obj214",
|
||||
|
@ -19,8 +19,11 @@ Test Infinity rep
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, InfinityRep } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { InfinityRep } = REPS;
|
||||
|
||||
try {
|
||||
yield testInfinity();
|
||||
@ -33,9 +36,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testInfinity() {
|
||||
const stub = getGripStub("testInfinity");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: stub });
|
||||
is(renderedRep.type, InfinityRep.rep,
|
||||
`Rep correctly selects ${InfinityRep.rep.displayName} for Infinity value`);
|
||||
is(getRep(stub), InfinityRep.rep, "Rep correctly selects Infinity Rep");
|
||||
|
||||
const renderedComponent = renderComponent(InfinityRep.rep, { object: stub });
|
||||
is(renderedComponent.textContent, "Infinity",
|
||||
@ -44,9 +45,7 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testNegativeInfinity() {
|
||||
const stub = getGripStub("testNegativeInfinity");
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: stub });
|
||||
is(renderedRep.type, InfinityRep.rep,
|
||||
`Rep correctly selects ${InfinityRep.rep.displayName} for negative Infinity value`);
|
||||
is(getRep(stub), InfinityRep.rep, "Rep correctly selects Infinity Rep");
|
||||
|
||||
const renderedComponent = renderComponent(InfinityRep.rep, { object: stub });
|
||||
is(renderedComponent.textContent, "-Infinity",
|
||||
|
@ -17,14 +17,16 @@ Test LongString rep
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, LongStringRep } = REPS;
|
||||
const {
|
||||
REPS,
|
||||
getRep,
|
||||
} = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { LongStringRep } = REPS;
|
||||
|
||||
try {
|
||||
// Test that correct rep is chosen
|
||||
const renderedRep = shallowRenderComponent(Rep, { object: getGripStub("testMultiline") });
|
||||
is(renderedRep.type, LongStringRep.rep,
|
||||
`Rep correctly selects ${LongStringRep.rep.displayName}`);
|
||||
is(getRep(getGripStub("testMultiline")), LongStringRep.rep,
|
||||
"Rep correctly selects LongString Rep");
|
||||
|
||||
// Test rendering
|
||||
yield testMultiline();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user