зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-central to mozilla-inbound. r=merge a=merge
This commit is contained in:
Коммит
92986dd48f
|
@ -18,7 +18,6 @@ extensions/universalchardet/**
|
|||
gfx/**
|
||||
image/**
|
||||
intl/**
|
||||
ipc/**
|
||||
layout/**
|
||||
media/**
|
||||
memory/**
|
||||
|
|
|
@ -18,11 +18,6 @@ Cu.import("resource://services-sync/util.js");
|
|||
|
||||
const ACTION_URL_PARAM = "action";
|
||||
|
||||
const OBSERVER_TOPICS = [
|
||||
fxAccountsCommon.ONVERIFIED_NOTIFICATION,
|
||||
fxAccountsCommon.ONLOGOUT_NOTIFICATION,
|
||||
];
|
||||
|
||||
function log(msg) {
|
||||
// dump("FXA: " + msg + "\n");
|
||||
}
|
||||
|
@ -300,24 +295,15 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
function initObservers() {
|
||||
function observe(subject, topic, data) {
|
||||
log("about:accounts observed " + topic);
|
||||
if (topic == fxAccountsCommon.ONLOGOUT_NOTIFICATION) {
|
||||
// All about:account windows get changed to action=signin on logout.
|
||||
window.location = "about:accounts?action=signin";
|
||||
return;
|
||||
}
|
||||
|
||||
// must be onverified - we want to open preferences.
|
||||
openPrefs();
|
||||
window.location = "about:accounts?action=signin";
|
||||
}
|
||||
|
||||
for (let topic of OBSERVER_TOPICS) {
|
||||
Services.obs.addObserver(observe, topic);
|
||||
}
|
||||
Services.obs.addObserver(observe, fxAccountsCommon.ONLOGOUT_NOTIFICATION);
|
||||
|
||||
window.addEventListener("unload", function(event) {
|
||||
log("about:accounts unloading")
|
||||
for (let topic of OBSERVER_TOPICS) {
|
||||
Services.obs.removeObserver(observe, topic);
|
||||
}
|
||||
log("about:accounts unloading");
|
||||
Services.obs.removeObserver(observe,
|
||||
fxAccountsCommon.ONLOGOUT_NOTIFICATION);
|
||||
});
|
||||
}
|
||||
initObservers();
|
||||
|
|
|
@ -20,7 +20,7 @@ loader.lazyGetter(this, "WorkersPanel",
|
|||
() => createFactory(require("./workers/panel")));
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(this, "Telemetry",
|
||||
"devtools/client/shared/telemetry");
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ const PanelHeader = createFactory(require("../panel-header"));
|
|||
const TargetList = createFactory(require("../target-list"));
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
|
|
|
@ -16,7 +16,7 @@ loader.lazyImporter(this, "BrowserToolboxProcess",
|
|||
"resource://devtools/client/framework/ToolboxProcess.jsm");
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
|
|
|
@ -15,7 +15,7 @@ const TargetList = createFactory(require("../target-list"));
|
|||
const TabTarget = createFactory(require("./target"));
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
|
|
|
@ -9,7 +9,7 @@ const { createClass, DOM: dom, PropTypes } =
|
|||
const Services = require("Services");
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
|
|
|
@ -17,7 +17,7 @@ loader.lazyImporter(this, "PrivateBrowsingUtils",
|
|||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
|
||||
const Strings = Services.strings.createBundle("chrome://devtools/locale/aboutdebugging.properties");
|
||||
const MULTI_OPT_OUT_PREF = "dom.ipc.multiOptOut";
|
||||
|
|
|
@ -23,7 +23,7 @@ loader.lazyImporter(this, "PrivateBrowsingUtils",
|
|||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
|
|
|
@ -12,7 +12,7 @@ const { debugWorker } = require("../../modules/worker");
|
|||
const Services = require("Services");
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
|
|
|
@ -12,7 +12,7 @@ const { debugWorker } = require("../../modules/worker");
|
|||
const Services = require("Services");
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
|
|
|
@ -13,7 +13,7 @@ const { BrowserLoader } = Components.utils.import(
|
|||
"resource://devtools/client/shared/browser-loader.js", {});
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerServer",
|
||||
"devtools/server/main", true);
|
||||
loader.lazyRequireGetter(this, "Telemetry",
|
||||
|
|
|
@ -11,7 +11,7 @@ var Services = require("Services");
|
|||
var promise = require("promise");
|
||||
const defer = require("devtools/shared/defer");
|
||||
var { gDevTools } = require("devtools/client/framework/devtools");
|
||||
var { DebuggerClient } = require("devtools/shared/client/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var { CallWatcherFront } = require("devtools/shared/fronts/call-watcher");
|
||||
var { CanvasFront } = require("devtools/shared/fronts/canvas");
|
||||
|
|
|
@ -15,7 +15,7 @@ var { DevToolsLoader } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
|||
var customLoader = new DevToolsLoader();
|
||||
customLoader.invisibleToDebugger = true;
|
||||
var { DebuggerServer } = customLoader.require("devtools/server/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
function initDebuggerClient() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
|
|
|
@ -16,7 +16,8 @@ Services.prefs.setBoolPref("devtools.debugger.log", false);
|
|||
|
||||
var { BrowserToolboxProcess } = Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", {});
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var { DebuggerClient, ObjectClient } = require("devtools/shared/client/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
var ObjectClient = require("devtools/shared/client/object-client");
|
||||
var { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
var EventEmitter = require("devtools/shared/old-event-emitter");
|
||||
var { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"use strict";
|
||||
|
||||
const { Cu } = require("chrome");
|
||||
const { ObjectClient } = require("devtools/shared/client/main");
|
||||
const ObjectClient = require("devtools/shared/client/object-client");
|
||||
|
||||
const defer = require("devtools/shared/defer");
|
||||
const EventEmitter = require("devtools/shared/old-event-emitter");
|
||||
|
|
|
@ -12,7 +12,7 @@ var Services = require("Services");
|
|||
var {gDevTools} = require("devtools/client/framework/devtools");
|
||||
var {TargetFactory} = require("devtools/client/framework/target");
|
||||
var {Toolbox} = require("devtools/client/framework/toolbox");
|
||||
var {DebuggerClient} = require("devtools/shared/client/main");
|
||||
var {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
var {Task} = require("devtools/shared/task");
|
||||
var {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
var L10N = new LocalizationHelper("devtools/client/locales/connection-screen.properties");
|
||||
|
|
|
@ -21,7 +21,7 @@ const {gDevTools} = require("./devtools");
|
|||
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
|
||||
loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(this, "BrowserMenus", "devtools/client/framework/browser-menus");
|
||||
loader.lazyRequireGetter(this, "appendStyleSheet", "devtools/client/shared/stylesheet-utils", true);
|
||||
loader.lazyRequireGetter(this, "DeveloperToolbar", "devtools/client/shared/developer-toolbar", true);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
const { TargetFactory } = require("devtools/client/framework/target");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
const { Task } = require("devtools/shared/task");
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,7 @@ const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
|
|||
|
||||
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerClient",
|
||||
"devtools/shared/client/main", true);
|
||||
"devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(this, "gDevTools",
|
||||
"devtools/client/framework/devtools", true);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"use strict";
|
||||
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
// Bug 1277805: Too slow for debug runs
|
||||
requestLongerTimeout(2);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"use strict";
|
||||
|
||||
const { on, off } = require("devtools/shared/event-emitter");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
function test() {
|
||||
gDevTools.on("toolbox-created", onToolboxCreated);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
const TAB_URL_1 = "data:text/html;charset=utf-8,foo";
|
||||
const TAB_URL_2 = "data:text/html;charset=utf-8,bar";
|
||||
|
|
|
@ -26,7 +26,7 @@ function toggleAllTools(state) {
|
|||
function getChromeActors(callback)
|
||||
{
|
||||
let { DebuggerServer } = require("devtools/server/main");
|
||||
let { DebuggerClient } = require("devtools/shared/client/main");
|
||||
let { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
|
|
|
@ -21,7 +21,7 @@ if (url.search.length > 1) {
|
|||
const { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
const { TargetFactory } = require("devtools/client/framework/target");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
const { Task } = require("devtools/shared/task");
|
||||
|
||||
// `host` is the frame element loading the toolbox.
|
||||
|
|
|
@ -16,7 +16,7 @@ var { gDevTools } = require("devtools/client/framework/devtools");
|
|||
var { TargetFactory } = require("devtools/client/framework/target");
|
||||
var { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
var Services = require("Services");
|
||||
var { DebuggerClient } = require("devtools/shared/client/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
var { PrefsHelper } = require("devtools/client/shared/prefs");
|
||||
var { Task } = require("devtools/shared/task");
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ devtools.jar:
|
|||
skin/toolbox.css (themes/toolbox.css)
|
||||
skin/tooltips.css (themes/tooltips.css)
|
||||
skin/images/add.svg (themes/images/add.svg)
|
||||
skin/images/breadcrumbs-divider.svg (themes/images/breadcrumbs-divider.svg)
|
||||
skin/images/filters.svg (themes/images/filters.svg)
|
||||
skin/images/filter-swatch.svg (themes/images/filter-swatch.svg)
|
||||
skin/images/grid.svg (themes/images/grid.svg)
|
||||
|
@ -273,7 +274,6 @@ devtools.jar:
|
|||
skin/images/firebug/play.svg (themes/images/firebug/play.svg)
|
||||
skin/images/firebug/rewind.svg (themes/images/firebug/rewind.svg)
|
||||
skin/images/firebug/disable.svg (themes/images/firebug/disable.svg)
|
||||
skin/images/firebug/breadcrumbs-divider.svg (themes/images/firebug/breadcrumbs-divider.svg)
|
||||
skin/images/firebug/breakpoint.svg (themes/images/firebug/breakpoint.svg)
|
||||
skin/images/firebug/tool-options.svg (themes/images/firebug/tool-options.svg)
|
||||
skin/images/firebug/debugger-step-in.svg (themes/images/firebug/debugger-step-in.svg)
|
||||
|
|
|
@ -10,6 +10,7 @@ const {
|
|||
PropTypes,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const { L10N } = require("../utils/l10n");
|
||||
const { sortObjectKeys } = require("../utils/sort-utils");
|
||||
|
||||
// Component
|
||||
const PropertiesView = createFactory(require("./properties-view"));
|
||||
|
@ -50,11 +51,11 @@ function CookiesPanel({
|
|||
let object = {};
|
||||
|
||||
if (responseCookies.length) {
|
||||
object[RESPONSE_COOKIES] = getProperties(responseCookies);
|
||||
object[RESPONSE_COOKIES] = sortObjectKeys(getProperties(responseCookies));
|
||||
}
|
||||
|
||||
if (requestCookies.length) {
|
||||
object[REQUEST_COOKIES] = getProperties(requestCookies);
|
||||
object[REQUEST_COOKIES] = sortObjectKeys(getProperties(requestCookies));
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -20,6 +20,7 @@ const {
|
|||
getHTTPStatusCodeURL,
|
||||
} = require("../utils/mdn-utils");
|
||||
const { writeHeaderText } = require("../utils/request-utils");
|
||||
const { sortObjectKeys } = require("../utils/sort-utils");
|
||||
|
||||
// Components
|
||||
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
|
||||
|
@ -74,7 +75,7 @@ const HeadersPanel = createClass({
|
|||
, {})
|
||||
};
|
||||
|
||||
propertiesResult[headerKey] = this.sortByKey(propertiesResult[headerKey]);
|
||||
propertiesResult[headerKey] = sortObjectKeys(propertiesResult[headerKey]);
|
||||
return propertiesResult;
|
||||
}
|
||||
|
||||
|
@ -128,16 +129,6 @@ const HeadersPanel = createClass({
|
|||
);
|
||||
},
|
||||
|
||||
sortByKey: function (object) {
|
||||
let result = {};
|
||||
Object.keys(object).sort(function (left, right) {
|
||||
return left.toLowerCase().localeCompare(right.toLowerCase());
|
||||
}).forEach(function (key) {
|
||||
result[key] = object[key];
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
render() {
|
||||
const {
|
||||
openLink,
|
||||
|
|
|
@ -11,6 +11,7 @@ const {
|
|||
} = require("devtools/client/shared/vendor/react");
|
||||
const { L10N } = require("../utils/l10n");
|
||||
const { getUrlQuery, parseQueryString, parseFormData } = require("../utils/request-utils");
|
||||
const { sortObjectKeys } = require("../utils/sort-utils");
|
||||
|
||||
// Components
|
||||
const PropertiesView = createFactory(require("./properties-view"));
|
||||
|
@ -76,7 +77,7 @@ function ParamsPanel({
|
|||
}
|
||||
|
||||
if (json) {
|
||||
object[JSON_SCOPE_NAME] = json;
|
||||
object[JSON_SCOPE_NAME] = sortObjectKeys(json);
|
||||
} else {
|
||||
object[PARAMS_POST_PAYLOAD] = {
|
||||
EDITOR_CONFIG: {
|
||||
|
@ -118,7 +119,7 @@ ParamsPanel.propTypes = {
|
|||
* @returns {Object} Rep compatible object
|
||||
*/
|
||||
function getProperties(arr) {
|
||||
return arr.reduce((map, obj) => {
|
||||
return sortObjectKeys(arr.reduce((map, obj) => {
|
||||
let value = map[obj.name];
|
||||
if (value) {
|
||||
if (typeof value !== "object") {
|
||||
|
@ -129,7 +130,7 @@ function getProperties(arr) {
|
|||
map[obj.name] = obj.value;
|
||||
}
|
||||
return map;
|
||||
}, {});
|
||||
}, {}));
|
||||
}
|
||||
|
||||
module.exports = ParamsPanel;
|
||||
|
|
|
@ -15,4 +15,5 @@ DevToolsModules(
|
|||
'prefs.js',
|
||||
'request-utils.js',
|
||||
'sort-predicates.js',
|
||||
'sort-utils.js'
|
||||
)
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Sorts object by keys in alphabetical order
|
||||
* If object has nested children, it sorts the child-elements also by keys
|
||||
* @param {object} which should be sorted by keys in alphabetical order
|
||||
*/
|
||||
function sortObjectKeys(object) {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
return Object.keys(object).sort(function (left, right) {
|
||||
return left.toLowerCase().localeCompare(right.toLowerCase());
|
||||
}).reduce((acc, key) => {
|
||||
if (typeof object[key] === "object") {
|
||||
acc[key] = sortObjectKeys(object[key]);
|
||||
} else {
|
||||
acc[key] = object[key];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sortObjectKeys
|
||||
};
|
|
@ -44,6 +44,7 @@ support-files =
|
|||
sjs_hsts-test-server.sjs
|
||||
sjs_json-test-server.sjs
|
||||
sjs_simple-test-server.sjs
|
||||
sjs_simple-unsorted-cookies-test-server.sjs
|
||||
sjs_sorting-test-server.sjs
|
||||
sjs_status-codes-test-server.sjs
|
||||
sjs_truncate-test-server.sjs
|
||||
|
@ -99,6 +100,7 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
|
|||
[browser_net_copy_headers.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_net_cookies_sorted.js]
|
||||
[browser_net_copy_as_curl.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
|
@ -133,6 +135,7 @@ skip-if = (os == 'linux' && debug && bits == 32) # Bug 1303439
|
|||
[browser_net_open_request_in_tab.js]
|
||||
[browser_net_pane-collapse.js]
|
||||
[browser_net_pane-toggle.js]
|
||||
[browser_net_params_sorted.js]
|
||||
[browser_net_persistent_logs.js]
|
||||
[browser_net_post-data-01.js]
|
||||
[browser_net_post-data-02.js]
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Tests if Request-Cookies and Response-Cookies are sorted in Cookies tab.
|
||||
*/
|
||||
add_task(function* () {
|
||||
let { tab, monitor } = yield initNetMonitor(SIMPLE_UNSORTED_COOKIES_SJS);
|
||||
info("Starting test... ");
|
||||
|
||||
let { document, store, windowRequire } = monitor.panelWin;
|
||||
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
|
||||
|
||||
store.dispatch(Actions.batchEnable(false));
|
||||
|
||||
tab.linkedBrowser.reload();
|
||||
|
||||
let wait = waitForNetworkEvents(monitor, 1);
|
||||
yield wait;
|
||||
|
||||
wait = waitForDOM(document, ".headers-overview");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[0]);
|
||||
yield wait;
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[0]);
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#cookies-tab"));
|
||||
|
||||
info("Check if Request-Cookies and Response-Cookies are sorted");
|
||||
let expectedLabelValues = ["Response cookies", "bob", "httpOnly", "value",
|
||||
"foo", "httpOnly", "value", "tom", "httpOnly", "value",
|
||||
"Request cookies", "bob", "foo", "tom"];
|
||||
let labelCells = document.querySelectorAll(".treeLabelCell");
|
||||
labelCells.forEach(function (val, index) {
|
||||
is(val.innerText, expectedLabelValues[index],
|
||||
"Actual label value " + val.innerText + " not equal to expected label value "
|
||||
+ expectedLabelValues[index]);
|
||||
});
|
||||
yield teardown(monitor);
|
||||
});
|
|
@ -0,0 +1,42 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Tests whether keys in Params panel are sorted.
|
||||
*/
|
||||
|
||||
add_task(function* () {
|
||||
let { tab, monitor } = yield initNetMonitor(POST_DATA_URL);
|
||||
info("Starting test... ");
|
||||
|
||||
let { document, store, windowRequire } = monitor.panelWin;
|
||||
let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
|
||||
|
||||
store.dispatch(Actions.batchEnable(false));
|
||||
|
||||
let wait = waitForNetworkEvents(monitor, 0, 2);
|
||||
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.performRequests();
|
||||
});
|
||||
yield wait;
|
||||
|
||||
wait = waitForDOM(document, ".headers-overview");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[0]);
|
||||
yield wait;
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
document.querySelector("#params-tab"));
|
||||
|
||||
let actualKeys = document.querySelectorAll(".treeLabel");
|
||||
let expectedKeys = ["Query string", "baz", "foo", "type",
|
||||
"Form data", "baz", "foo"];
|
||||
|
||||
for (let i = 0; i < actualKeys.length; i++) {
|
||||
is(actualKeys[i].innerText, expectedKeys[i],
|
||||
"Actual value " + actualKeys[i].innerText + " is equal to the " +
|
||||
"expected value " + expectedKeys[i]);
|
||||
}
|
||||
});
|
|
@ -112,20 +112,20 @@ add_task(function* () {
|
|||
let values = tabpanel
|
||||
.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
|
||||
|
||||
is(labels[0].textContent, "foo", "The first query param name was incorrect.");
|
||||
is(values[0].textContent, "bar", "The first query param value was incorrect.");
|
||||
is(labels[1].textContent, "baz", "The second query param name was incorrect.");
|
||||
is(values[1].textContent, "42", "The second query param value was incorrect.");
|
||||
is(labels[0].textContent, "baz", "The first query param name was incorrect.");
|
||||
is(values[0].textContent, "42", "The first query param value was incorrect.");
|
||||
is(labels[1].textContent, "foo", "The second query param name was incorrect.");
|
||||
is(values[1].textContent, "bar", "The second query param value was incorrect.");
|
||||
is(labels[2].textContent, "type", "The third query param name was incorrect.");
|
||||
is(values[2].textContent, type, "The third query param value was incorrect.");
|
||||
|
||||
if (type == "urlencoded") {
|
||||
checkVisibility("params");
|
||||
is(labels.length, 5, "There should be 5 param values displayed in this tabpanel.");
|
||||
is(labels[3].textContent, "foo", "The first post param name was incorrect.");
|
||||
is(values[3].textContent, "bar", "The first post param value was incorrect.");
|
||||
is(labels[4].textContent, "baz", "The second post param name was incorrect.");
|
||||
is(values[4].textContent, "123", "The second post param value was incorrect.");
|
||||
is(labels[3].textContent, "baz", "The first post param name was incorrect.");
|
||||
is(values[3].textContent, "123", "The first post param value was incorrect.");
|
||||
is(labels[4].textContent, "foo", "The second post param name was incorrect.");
|
||||
is(values[4].textContent, "bar", "The second post param value was incorrect.");
|
||||
} else {
|
||||
checkVisibility("params editor");
|
||||
|
||||
|
|
|
@ -54,10 +54,10 @@ add_task(function* () {
|
|||
let values = tabpanel
|
||||
.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
|
||||
|
||||
is(labels[0].textContent, "foo", "The first query param name was incorrect.");
|
||||
is(values[0].textContent, "bar", "The first query param value was incorrect.");
|
||||
is(labels[1].textContent, "baz", "The second query param name was incorrect.");
|
||||
is(values[1].textContent, "123", "The second query param value was incorrect.");
|
||||
is(labels[0].textContent, "baz", "The first query param name was incorrect.");
|
||||
is(values[0].textContent, "123", "The first query param value was incorrect.");
|
||||
is(labels[1].textContent, "foo", "The second query param name was incorrect.");
|
||||
is(values[1].textContent, "bar", "The second query param value was incorrect.");
|
||||
|
||||
return teardown(monitor);
|
||||
});
|
||||
|
|
|
@ -79,10 +79,10 @@ add_task(function* () {
|
|||
values = tabpanel
|
||||
.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
|
||||
|
||||
is(labels[0].textContent, "foo", "The first payload param name was incorrect.");
|
||||
is(values[0].textContent, "bar", "The first payload param value was incorrect.");
|
||||
is(labels[1].textContent, "baz", "The second payload param name was incorrect.");
|
||||
is(values[1].textContent, "123", "The second payload param value was incorrect.");
|
||||
is(labels[0].textContent, "baz", "The first payload param name was incorrect.");
|
||||
is(values[0].textContent, "123", "The first payload param value was incorrect.");
|
||||
is(labels[1].textContent, "foo", "The second payload param name was incorrect.");
|
||||
is(values[1].textContent, "bar", "The second payload param value was incorrect.");
|
||||
|
||||
return teardown(monitor);
|
||||
});
|
||||
|
|
|
@ -62,6 +62,7 @@ const SEND_BEACON_URL = EXAMPLE_URL + "html_send-beacon.html";
|
|||
const CORS_URL = EXAMPLE_URL + "html_cors-test-page.html";
|
||||
|
||||
const SIMPLE_SJS = EXAMPLE_URL + "sjs_simple-test-server.sjs";
|
||||
const SIMPLE_UNSORTED_COOKIES_SJS = EXAMPLE_URL + "sjs_simple-unsorted-cookies-test-server.sjs";
|
||||
const CONTENT_TYPE_SJS = EXAMPLE_URL + "sjs_content-type-test-server.sjs";
|
||||
const HTTPS_CONTENT_TYPE_SJS = HTTPS_EXAMPLE_URL + "sjs_content-type-test-server.sjs";
|
||||
const STATUS_CODES_SJS = EXAMPLE_URL + "sjs_status-codes-test-server.sjs";
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function handleRequest(request, response) {
|
||||
response.setStatusLine(request.httpVersion, 200, "Och Aye");
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Expires", "0");
|
||||
|
||||
response.setHeader("Set-Cookie", "tom=cool; Max-Age=10; HttpOnly", true);
|
||||
response.setHeader("Set-Cookie", "bob=true; Max-Age=10; HttpOnly", true);
|
||||
response.setHeader("Set-Cookie", "foo=bar; Max-Age=10; HttpOnly", true);
|
||||
|
||||
response.setHeader("Content-Type", "text/plain; charset=utf-8", false);
|
||||
response.setHeader("Foo-Bar", "baz", false);
|
||||
response.write("Hello world!");
|
||||
}
|
|
@ -11,7 +11,7 @@ const EventEmitter = require("devtools/shared/old-event-emitter");
|
|||
|
||||
const TOOL_URL = "chrome://devtools/content/responsive.html/index.xhtml";
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
|
||||
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
|
||||
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
|
||||
|
|
|
@ -83,9 +83,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "VariablesViewController",
|
|||
|
||||
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "EnvironmentClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(this, "EnvironmentClient", "devtools/shared/client/environment-client");
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/object-client");
|
||||
loader.lazyRequireGetter(this, "HUDService", "devtools/client/webconsole/hudservice", true);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "REMOTE_TIMEOUT", () =>
|
||||
|
|
|
@ -11,7 +11,7 @@ var Services = require("Services");
|
|||
var promise = require("promise");
|
||||
const defer = require("devtools/shared/defer");
|
||||
var { gDevTools } = require("devtools/client/framework/devtools");
|
||||
var { DebuggerClient } = require("devtools/shared/client/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var { WebGLFront } = require("devtools/shared/fronts/webgl");
|
||||
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
|
|
|
@ -15,7 +15,7 @@ var promise = require("promise");
|
|||
var defer = require("devtools/shared/defer");
|
||||
var Services = require("Services");
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
var flags = require("devtools/shared/flags");
|
||||
var { Task } = require("devtools/shared/task");
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
// create a front for the given `tab`
|
||||
exports.getTestActorWithoutToolbox = Task.async(function* (tab) {
|
||||
let { DebuggerServer } = require("devtools/server/main");
|
||||
let { DebuggerClient } = require("devtools/shared/client/main");
|
||||
let { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
// We need to spawn a client instance,
|
||||
// but for that we have to first ensure a server is running
|
||||
|
|
|
@ -87,15 +87,10 @@
|
|||
|
||||
.breadcrumbs-widget-item {
|
||||
background-color: transparent;
|
||||
-moz-appearance: none;
|
||||
min-height: 24px;
|
||||
min-width: 65px;
|
||||
margin: 0;
|
||||
padding: 0 8px 0 20px;
|
||||
border: none;
|
||||
outline: none;
|
||||
color: hsl(210,30%,85%);
|
||||
position: relative;
|
||||
margin-inline-start: 10px;
|
||||
margin-inline-end: 1px;
|
||||
padding: 0 0 2px 0;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item > .button-box {
|
||||
|
@ -108,32 +103,10 @@
|
|||
border-width: 0;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
offset-inline-start: 0;
|
||||
width: 12px;
|
||||
height: 22px;
|
||||
background-repeat: no-repeat;
|
||||
/* Given the 1/2 aspect ratio of the separator pseudo-element and the 45deg angle of
|
||||
the arrow shape, we need the arrow edges to be at this position from the start of
|
||||
the gradient line. */
|
||||
--position: 66.5%;
|
||||
/* The color of the thin line in the arrow-shaped separator between 2 unselected
|
||||
crumbs. There is no theme variable for this, this used to be an image. */
|
||||
--line-color: #ACACAC;
|
||||
--background-color: var(--theme-body-background);
|
||||
}
|
||||
|
||||
#debugger-toolbar .breadcrumbs-widget-item::before {
|
||||
--background-color: var(--theme-toolbar-background);
|
||||
}
|
||||
|
||||
.theme-dark .breadcrumbs-widget-item::before {
|
||||
--line-color: #6E6E6E;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item:first-child::before {
|
||||
/* The first crumb does not need any separator before itself */
|
||||
content: unset;
|
||||
|
@ -143,68 +116,6 @@
|
|||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item:not([checked])::before {
|
||||
background-color: var(--background-color);
|
||||
background-image:
|
||||
linear-gradient(45deg,
|
||||
var(--background-color) 30%,
|
||||
transparent),
|
||||
linear-gradient(-45deg,
|
||||
transparent,
|
||||
var(--background-color) 70%,
|
||||
var(--background-color)),
|
||||
linear-gradient(45deg,
|
||||
transparent var(--position),
|
||||
var(--line-color) var(--position),
|
||||
var(--line-color) calc(var(--position) + 1px),
|
||||
transparent 0),
|
||||
linear-gradient(-45deg,
|
||||
transparent calc(100% - var(--position)),
|
||||
var(--line-color) calc(100% - var(--position)),
|
||||
var(--line-color) calc(calc(100% - var(--position)) + 1px),
|
||||
transparent 0);
|
||||
background-size:
|
||||
100% 50%,
|
||||
100% 50%,
|
||||
100%,
|
||||
100%;
|
||||
background-position:
|
||||
left bottom,
|
||||
left top,
|
||||
left top,
|
||||
left top;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item[checked] + .breadcrumbs-widget-item::before {
|
||||
background-color: var(--theme-selection-background);
|
||||
background-image:
|
||||
linear-gradient(45deg,
|
||||
transparent var(--position),
|
||||
var(--background-color) 0),
|
||||
linear-gradient(-45deg,
|
||||
var(--background-color) calc(100% - var(--position)),
|
||||
transparent 0);
|
||||
background-size: unset;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item[checked]::before {
|
||||
background-image:
|
||||
linear-gradient(45deg,
|
||||
transparent var(--position),
|
||||
var(--theme-selection-background) 0),
|
||||
linear-gradient(-45deg,
|
||||
var(--theme-selection-background) calc(100% - var(--position)),
|
||||
var(--background-color) 0);
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item[checked] {
|
||||
background-color: var(--theme-selection-background);
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item:first-child {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
/* RTL support: move the images that were on the left to the right,
|
||||
* and move images that were on the right to the left.
|
||||
*/
|
||||
|
@ -217,11 +128,23 @@
|
|||
background-position: center right;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-id,
|
||||
.breadcrumbs-widget-item:not(:first-child)::before {
|
||||
content: url(chrome://devtools/skin/images/breadcrumbs-divider.svg);
|
||||
background: none;
|
||||
position: relative;
|
||||
left: -3px;
|
||||
margin: 0 4px 0 -1px;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-id {
|
||||
color: var(--theme-highlight-purple);
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-tag,
|
||||
.breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-pseudo-classes,
|
||||
.breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-classes {
|
||||
color: var(--theme-selection-color);
|
||||
color: var(--theme-highlight-blue);
|
||||
}
|
||||
|
||||
.theme-dark .breadcrumbs-widget-item {
|
||||
|
@ -244,34 +167,16 @@
|
|||
color: var(--theme-highlight-lightorange);
|
||||
}
|
||||
|
||||
.theme-dark .breadcrumbs-widget-item:not([checked]):hover label {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.theme-light .breadcrumbs-widget-item:not([checked]):hover label {
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* Firebug theme support for breadcrumbs widget. */
|
||||
|
||||
.theme-firebug .breadcrumbs-widget-item {
|
||||
margin-inline-start: 10px;
|
||||
margin-inline-end: 1px;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
color: #141414;
|
||||
border-radius: 2px;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
font-size: var(--theme-toolbar-font-size);
|
||||
}
|
||||
|
||||
.theme-firebug .breadcrumbs-widget-item:hover {
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
background: transparent linear-gradient(
|
||||
rgba(255, 255, 255, 0.4),
|
||||
rgba(255, 255, 255, 0.2)) no-repeat;
|
||||
box-shadow: 1px 1px 1px rgba(255, 255, 255, 0.6) inset,
|
||||
0 0 1px rgba(255, 255, 255, 0.6) inset,
|
||||
0 0 2px rgba(0, 0, 0, 0.05);
|
||||
|
@ -287,13 +192,8 @@
|
|||
}
|
||||
|
||||
.theme-firebug .breadcrumbs-widget-item:not(:first-child)::before {
|
||||
content: url(chrome://devtools/skin/images/firebug/breadcrumbs-divider.svg);
|
||||
background: none;
|
||||
position: relative;
|
||||
left: -3px;
|
||||
margin: 0 0 0 -5px;
|
||||
padding: 0;
|
||||
width: 5px;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/* Breadcrumbs Separators (reset selection styles) */
|
||||
|
|
До Ширина: | Высота: | Размер: 1.1 KiB После Ширина: | Высота: | Размер: 1.1 KiB |
|
@ -13,7 +13,7 @@ loader.lazyImporter(this, "escapeHTML", "resource://devtools/client/shared/widge
|
|||
|
||||
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
|
||||
loader.lazyRequireGetter(this, "TableWidget", "devtools/client/shared/widgets/TableWidget", true);
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/object-client");
|
||||
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ loader.lazyRequireGetter(this, "WebConsoleFrame", "devtools/client/webconsole/we
|
|||
loader.lazyRequireGetter(this, "NewWebConsoleFrame", "devtools/client/webconsole/new-webconsole", true);
|
||||
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(this, "showDoorhanger", "devtools/client/shared/doorhanger", true);
|
||||
loader.lazyRequireGetter(this, "viewSource", "devtools/client/shared/view-source");
|
||||
const l10n = require("devtools/client/webconsole/webconsole-l10n");
|
||||
|
|
|
@ -21,8 +21,8 @@ loader.lazyRequireGetter(this, "AutocompletePopup", "devtools/client/shared/auto
|
|||
loader.lazyRequireGetter(this, "ToolSidebar", "devtools/client/framework/sidebar", true);
|
||||
loader.lazyRequireGetter(this, "Messages", "devtools/client/webconsole/console-output", true);
|
||||
loader.lazyRequireGetter(this, "asyncStorage", "devtools/shared/async-storage");
|
||||
loader.lazyRequireGetter(this, "EnvironmentClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "EnvironmentClient", "devtools/shared/client/environment-client");
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/object-client");
|
||||
loader.lazyImporter(this, "VariablesView", "resource://devtools/client/shared/widgets/VariablesView.jsm");
|
||||
loader.lazyImporter(this, "VariablesViewController", "resource://devtools/client/shared/widgets/VariablesViewController.jsm");
|
||||
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
|
||||
|
|
|
@ -9,7 +9,7 @@ const {
|
|||
DOM: dom,
|
||||
PropTypes
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const { ObjectClient } = require("devtools/shared/client/main");
|
||||
const ObjectClient = require("devtools/shared/client/object-client");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const { MODE } = require("devtools/client/shared/components/reps/reps");
|
||||
|
|
|
@ -17,7 +17,7 @@ const {
|
|||
createFactory,
|
||||
PropTypes,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const { ObjectClient } = require("devtools/shared/client/main");
|
||||
const ObjectClient = require("devtools/shared/client/object-client");
|
||||
const {
|
||||
MESSAGE_TYPE,
|
||||
JSTERM_COMMANDS,
|
||||
|
|
|
@ -34,7 +34,7 @@ requireHacker.global_hook("default", path => {
|
|||
case "Services":
|
||||
case "Services.default":
|
||||
return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/Services")`;
|
||||
case "devtools/shared/client/main":
|
||||
case "devtools/shared/client/object-client":
|
||||
return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/ObjectClient")`;
|
||||
case "devtools/client/netmonitor/src/components/tabbox-panel":
|
||||
return "{}";
|
||||
|
|
|
@ -17,7 +17,7 @@ const TEST_XHR_ERROR_URI = `http://example.com/404.html?${Date.now()}`;
|
|||
const TEST_IMAGE = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-image.png";
|
||||
|
||||
const {ObjectClient} = require("devtools/shared/client/main");
|
||||
const ObjectClient = require("devtools/shared/client/object-client");
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
|
|
@ -26,8 +26,8 @@ loader.lazyServiceGetter(this, "clipboardHelper",
|
|||
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/old-event-emitter");
|
||||
loader.lazyRequireGetter(this, "ConsoleOutput", "devtools/client/webconsole/console-output", true);
|
||||
loader.lazyRequireGetter(this, "Messages", "devtools/client/webconsole/console-output", true);
|
||||
loader.lazyRequireGetter(this, "EnvironmentClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/main", true);
|
||||
loader.lazyRequireGetter(this, "EnvironmentClient", "devtools/shared/client/environment-client");
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/object-client");
|
||||
loader.lazyRequireGetter(this, "system", "devtools/shared/system");
|
||||
loader.lazyRequireGetter(this, "JSTerm", "devtools/client/webconsole/jsterm", true);
|
||||
loader.lazyRequireGetter(this, "gSequenceId", "devtools/client/webconsole/jsterm", true);
|
||||
|
|
|
@ -89,7 +89,7 @@ webpackConfig.resolve = {
|
|||
|
||||
"devtools/shared/fronts/timeline": path.join(__dirname, "../../client/shared/webpack/shims/fronts-timeline-shim"),
|
||||
"devtools/shared/old-event-emitter": "devtools-modules/src/utils/event-emitter",
|
||||
"devtools/shared/client/main": path.join(__dirname, "new-console-output/test/fixtures/ObjectClient"),
|
||||
"devtools/shared/client/object-client": path.join(__dirname, "new-console-output/test/fixtures/ObjectClient"),
|
||||
"devtools/shared/platform/clipboard": path.join(__dirname, "../../client/shared/webpack/shims/platform-clipboard-stub"),
|
||||
"devtools/shared/platform/stack": path.join(__dirname, "../../client/shared/webpack/shims/platform-stack-stub"),
|
||||
|
||||
|
|
|
@ -613,7 +613,11 @@
|
|||
}
|
||||
|
||||
:-moz-native-anonymous .shapes-markers {
|
||||
fill: var(--highlighter-marker-color);
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
:-moz-native-anonymous .shapes-markers-outline {
|
||||
fill: var(--highlighter-guide-color);
|
||||
}
|
||||
|
||||
:-moz-native-anonymous .shapes-marker-hover {
|
||||
|
|
|
@ -17,7 +17,7 @@ const {
|
|||
} = require("devtools/server/actors/utils/shapes-geometry-utils");
|
||||
const EventEmitter = require("devtools/shared/old-event-emitter");
|
||||
|
||||
const BASE_MARKER_SIZE = 10;
|
||||
const BASE_MARKER_SIZE = 5;
|
||||
// the width of the area around highlighter lines that can be clicked, in px
|
||||
const LINE_CLICK_WIDTH = 5;
|
||||
const DOM_EVENTS = ["mousedown", "mousemove", "mouseup", "dblclick"];
|
||||
|
@ -116,6 +116,16 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
});
|
||||
|
||||
// Append a path to display the markers for the shape.
|
||||
createSVGNode(this.win, {
|
||||
nodeType: "path",
|
||||
parent: mainSvg,
|
||||
attributes: {
|
||||
"id": "markers-outline",
|
||||
"class": "markers-outline",
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
|
||||
createSVGNode(this.win, {
|
||||
nodeType: "path",
|
||||
parent: mainSvg,
|
||||
|
@ -193,24 +203,11 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
} else if (this.shapeType === "inset") {
|
||||
this._handleInsetClick(pageX, pageY);
|
||||
}
|
||||
// Currently, changes to shape-outside do not become visible unless a reflow
|
||||
// is forced (bug 1359834). This is a hack to force a reflow so changes made
|
||||
// using the highlighter can be seen: we change the width of the element
|
||||
// slightly on mousedown on a point, and restore the original width on mouseup.
|
||||
if (this.property === "shape-outside" && this[_dragging]) {
|
||||
let { width } = this.zoomAdjustedDimensions;
|
||||
let origWidth = getDefinedShapeProperties(this.currentNode, "width");
|
||||
this.currentNode.style.setProperty("width", `${width + 1}px`);
|
||||
this[_dragging].origWidth = origWidth;
|
||||
}
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
break;
|
||||
case "mouseup":
|
||||
if (this[_dragging]) {
|
||||
if (this.property === "shape-outside") {
|
||||
this.currentNode.style.setProperty("width", this[_dragging].origWidth);
|
||||
}
|
||||
this[_dragging] = null;
|
||||
}
|
||||
break;
|
||||
|
@ -675,7 +672,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
let { width, height } = this.zoomAdjustedDimensions;
|
||||
let zoom = getCurrentZoom(this.win);
|
||||
let path = points.map(([x, y]) => {
|
||||
return getCirclePath(x, y, width, height, zoom);
|
||||
return getCirclePath(BASE_MARKER_SIZE, x, y, width, height, zoom);
|
||||
}).join(" ");
|
||||
|
||||
let markerHover = this.getElement("marker-hover");
|
||||
|
@ -1274,6 +1271,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
this.getElement("polygon").setAttribute("hidden", true);
|
||||
this.getElement("rect").setAttribute("hidden", true);
|
||||
this.getElement("markers").setAttribute("d", "");
|
||||
this.getElement("markers-outline").setAttribute("d", "");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1402,10 +1400,14 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
|
|||
*/
|
||||
_drawMarkers(coords, width, height, zoom) {
|
||||
let markers = coords.map(([x, y]) => {
|
||||
return getCirclePath(x, y, width, height, zoom);
|
||||
return getCirclePath(BASE_MARKER_SIZE, x, y, width, height, zoom);
|
||||
}).join(" ");
|
||||
let outline = coords.map(([x, y]) => {
|
||||
return getCirclePath(BASE_MARKER_SIZE + 2, x, y, width, height, zoom);
|
||||
}).join(" ");
|
||||
|
||||
this.getElement("markers").setAttribute("d", markers);
|
||||
this.getElement("markers-outline").setAttribute("d", outline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1531,6 +1533,7 @@ exports.shapeModeToCssPropertyName = shapeModeToCssPropertyName;
|
|||
|
||||
/**
|
||||
* Get the SVG path definition for a circle with given attributes.
|
||||
* @param {Number} size the radius of the circle in pixels
|
||||
* @param {Number} cx the x coordinate of the centre of the circle
|
||||
* @param {Number} cy the y coordinate of the centre of the circle
|
||||
* @param {Number} width the width of the element the circle is being drawn for
|
||||
|
@ -1538,14 +1541,14 @@ exports.shapeModeToCssPropertyName = shapeModeToCssPropertyName;
|
|||
* @param {Number} zoom the zoom level of the window the circle is drawn in
|
||||
* @returns {String} the definition of the circle in SVG path description format.
|
||||
*/
|
||||
const getCirclePath = (cx, cy, width, height, zoom) => {
|
||||
const getCirclePath = (size, cx, cy, width, height, zoom) => {
|
||||
// We use a viewBox of 100x100 for shape-container so it's easy to position things
|
||||
// based on their percentage, but this makes it more difficult to create circles.
|
||||
// Therefor, 100px is the base size of shape-container. In order to make the markers'
|
||||
// size scale properly, we must adjust the radius based on zoom and the width/height of
|
||||
// the element being highlighted, then calculate a radius for both x/y axes based
|
||||
// on the aspect ratio of the element.
|
||||
let radius = BASE_MARKER_SIZE * (100 / Math.max(width, height)) / zoom;
|
||||
let radius = size * (100 / Math.max(width, height)) / zoom;
|
||||
let ratio = width / height;
|
||||
let rx = (ratio > 1) ? radius : radius / ratio;
|
||||
let ry = (ratio > 1) ? radius * ratio : radius;
|
||||
|
|
|
@ -12,7 +12,7 @@ var Cu = Components.utils;
|
|||
|
||||
const {console} = Cu.import("resource://gre/modules/Console.jsm", {});
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {DebuggerClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
const {defer} = require("promise");
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
var Cu = Components.utils;
|
||||
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {DebuggerClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
const { Task } = require("devtools/shared/task");
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ const Cu = Components.utils;
|
|||
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const Services = require("Services");
|
||||
const { Task } = require("devtools/shared/task");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
|
||||
const { MemoryFront } = require("devtools/shared/fronts/memory");
|
||||
|
|
|
@ -18,7 +18,7 @@ let Cu = Components.utils;
|
|||
let Ci = Components.interfaces;
|
||||
|
||||
let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
let { DebuggerClient } = require("devtools/shared/client/main");
|
||||
let { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
let { DebuggerServer } = require("devtools/server/main");
|
||||
|
||||
window.onload = function () {
|
||||
|
|
|
@ -19,7 +19,7 @@ window.onload = function () {
|
|||
const Ci = Components.interfaces;
|
||||
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {DebuggerClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
const Services = require("Services");
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ window.onload = function () {
|
|||
|
||||
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const Services = require("Services");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
|
||||
// Always log packets when running tests.
|
||||
|
|
|
@ -18,7 +18,7 @@ window.onload = function () {
|
|||
const Cu = Components.utils;
|
||||
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {DebuggerClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
const Services = require("Services");
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ window.onload = function () {
|
|||
const Cu = Components.utils;
|
||||
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {DebuggerClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
const Services = require("Services");
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ window.onload = function () {
|
|||
let Cu = Components.utils;
|
||||
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {DebuggerClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
const Services = require("Services");
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ Bug 1060093 - Test DebuggerServer.getProcess
|
|||
let Cu = Components.utils;
|
||||
|
||||
let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
let {DebuggerClient} = require("devtools/shared/client/main");
|
||||
let {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
let {DebuggerServer} = require("devtools/server/main");
|
||||
let Services = require("Services");
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ function runTests() {
|
|||
let Ci = Components.interfaces;
|
||||
|
||||
let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
let {DebuggerClient} = require("devtools/shared/client/main");
|
||||
let {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
let {DebuggerServer} = require("devtools/server/main");
|
||||
let Services = require("Services");
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ let Cc = Components.classes;
|
|||
let Ci = Components.interfaces;
|
||||
|
||||
let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
let {DebuggerClient} = require("devtools/shared/client/main");
|
||||
let {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
let {DebuggerServer} = require("devtools/server/main");
|
||||
let Services = require("Services");
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
var Cu = Components.utils;
|
||||
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {DebuggerClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
|
||||
const Services = require("Services");
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
const Cu = Components.utils;
|
||||
const {require, loader} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {DebuggerClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
const {TargetFactory} = require("devtools/client/framework/target");
|
||||
|
||||
|
|
|
@ -40,7 +40,8 @@ Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
|
|||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DebuggerServer: WorkerDebuggerServer } = worker.require("devtools/server/main");
|
||||
const { DebuggerClient, ObjectClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
const ObjectClient = require("devtools/shared/client/object-client");
|
||||
const { MemoryFront } = require("devtools/shared/fronts/memory");
|
||||
|
||||
const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {});
|
||||
|
|
|
@ -106,25 +106,25 @@ function test_shape_mode_to_css_property_name() {
|
|||
|
||||
function test_get_circle_path() {
|
||||
const tests = [{
|
||||
desc: "getCirclePath with no resizing, no zoom, 1:1 ratio",
|
||||
cx: 0, cy: 0, width: 100, height: 100, zoom: 1,
|
||||
expected: "M-10,0a10,10 0 1,0 20,0a10,10 0 1,0 -20,0"
|
||||
}, {
|
||||
desc: "getCirclePath with resizing, no zoom, 1:1 ratio",
|
||||
cx: 0, cy: 0, width: 200, height: 200, zoom: 1,
|
||||
desc: "getCirclePath with size 5, no resizing, no zoom, 1:1 ratio",
|
||||
size: 5, cx: 0, cy: 0, width: 100, height: 100, zoom: 1,
|
||||
expected: "M-5,0a5,5 0 1,0 10,0a5,5 0 1,0 -10,0"
|
||||
}, {
|
||||
desc: "getCirclePath with resizing, zoom, 1:1 ratio",
|
||||
cx: 0, cy: 0, width: 200, height: 200, zoom: 2,
|
||||
expected: "M-2.5,0a2.5,2.5 0 1,0 5,0a2.5,2.5 0 1,0 -5,0"
|
||||
desc: "getCirclePath with size 7, resizing, no zoom, 1:1 ratio",
|
||||
size: 7, cx: 0, cy: 0, width: 200, height: 200, zoom: 1,
|
||||
expected: "M-3.5,0a3.5,3.5 0 1,0 7,0a3.5,3.5 0 1,0 -7,0"
|
||||
}, {
|
||||
desc: "getCirclePath with resizing, zoom, non-square ratio",
|
||||
cx: 0, cy: 0, width: 100, height: 200, zoom: 2,
|
||||
expected: "M-5,0a5,2.5 0 1,0 10,0a5,2.5 0 1,0 -10,0"
|
||||
desc: "getCirclePath with size 5, resizing, zoom, 1:1 ratio",
|
||||
size: 5, cx: 0, cy: 0, width: 200, height: 200, zoom: 2,
|
||||
expected: "M-1.25,0a1.25,1.25 0 1,0 2.5,0a1.25,1.25 0 1,0 -2.5,0"
|
||||
}, {
|
||||
desc: "getCirclePath with size 5, resizing, zoom, non-square ratio",
|
||||
size: 5, cx: 0, cy: 0, width: 100, height: 200, zoom: 2,
|
||||
expected: "M-2.5,0a2.5,1.25 0 1,0 5,0a2.5,1.25 0 1,0 -5,0"
|
||||
}];
|
||||
|
||||
for (let { desc, cx, cy, width, height, zoom, expected } of tests) {
|
||||
equal(getCirclePath(cx, cy, width, height, zoom), expected, desc);
|
||||
for (let { desc, size, cx, cy, width, height, zoom, expected } of tests) {
|
||||
equal(getCirclePath(size, cx, cy, width, height, zoom), expected, desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {DebuggerClient} = require("./debugger-client");
|
||||
|
||||
function AddonClient(client, actor) {
|
||||
this._client = client;
|
||||
this._actor = actor;
|
||||
this.request = this._client.request;
|
||||
this.events = [];
|
||||
}
|
||||
|
||||
AddonClient.prototype = {
|
||||
get actor() {
|
||||
return this._actor;
|
||||
},
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
|
||||
/**
|
||||
* Detach the client from the addon actor.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
detach: DebuggerClient.requester({
|
||||
type: "detach"
|
||||
}, {
|
||||
after: function (response) {
|
||||
if (this._client.activeAddon === this) {
|
||||
this._client.activeAddon = null;
|
||||
}
|
||||
this._client.unregisterClient(this);
|
||||
return response;
|
||||
},
|
||||
})
|
||||
};
|
||||
|
||||
module.exports = AddonClient;
|
|
@ -0,0 +1,43 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {arg, DebuggerClient} = require("./debugger-client");
|
||||
|
||||
/**
|
||||
* A ArrayBufferClient provides a way to access ArrayBuffer from the
|
||||
* debugger server.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The debugger client parent.
|
||||
* @param grip Object
|
||||
* A pause-lifetime ArrayBuffer grip returned by the protocol.
|
||||
*/
|
||||
function ArrayBufferClient(client, grip) {
|
||||
this._grip = grip;
|
||||
this._client = client;
|
||||
this.request = this._client.request;
|
||||
}
|
||||
ArrayBufferClient.prototype = {
|
||||
get actor() {
|
||||
return this._grip.actor;
|
||||
},
|
||||
get length() {
|
||||
return this._grip.length;
|
||||
},
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
|
||||
valid: true,
|
||||
|
||||
slice: DebuggerClient.requester({
|
||||
type: "slice",
|
||||
start: arg(0),
|
||||
count: arg(1)
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = ArrayBufferClient;
|
|
@ -0,0 +1,134 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { Cu } = require("chrome");
|
||||
const promise = Cu.import("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise;
|
||||
|
||||
const eventSource = require("./event-source");
|
||||
const {DebuggerClient} = require("./debugger-client");
|
||||
|
||||
/**
|
||||
* Breakpoint clients are used to remove breakpoints that are no longer used.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The debugger client parent.
|
||||
* @param sourceClient SourceClient
|
||||
* The source where this breakpoint exists
|
||||
* @param actor string
|
||||
* The actor ID for this breakpoint.
|
||||
* @param location object
|
||||
* The location of the breakpoint. This is an object with two properties:
|
||||
* url and line.
|
||||
* @param condition string
|
||||
* The conditional expression of the breakpoint
|
||||
*/
|
||||
function BreakpointClient(client, sourceClient, actor, location, condition) {
|
||||
this._client = client;
|
||||
this._actor = actor;
|
||||
this.location = location;
|
||||
this.location.actor = sourceClient.actor;
|
||||
this.location.url = sourceClient.url;
|
||||
this.source = sourceClient;
|
||||
this.request = this._client.request;
|
||||
|
||||
// The condition property should only exist if it's a truthy value
|
||||
if (condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
}
|
||||
|
||||
BreakpointClient.prototype = {
|
||||
|
||||
_actor: null,
|
||||
get actor() {
|
||||
return this._actor;
|
||||
},
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the breakpoint from the server.
|
||||
*/
|
||||
remove: DebuggerClient.requester({
|
||||
type: "delete"
|
||||
}),
|
||||
|
||||
/**
|
||||
* Determines if this breakpoint has a condition
|
||||
*/
|
||||
hasCondition: function () {
|
||||
let root = this._client.mainRoot;
|
||||
// XXX bug 990137: We will remove support for client-side handling of
|
||||
// conditional breakpoints
|
||||
if (root.traits.conditionalBreakpoints) {
|
||||
return "condition" in this;
|
||||
}
|
||||
return "conditionalExpression" in this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the condition of this breakpoint. Currently we have to
|
||||
* support locally emulated conditional breakpoints until the
|
||||
* debugger servers are updated (see bug 990137). We used a
|
||||
* different property when moving it server-side to ensure that we
|
||||
* are testing the right code.
|
||||
*/
|
||||
getCondition: function () {
|
||||
let root = this._client.mainRoot;
|
||||
if (root.traits.conditionalBreakpoints) {
|
||||
return this.condition;
|
||||
}
|
||||
return this.conditionalExpression;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the condition of this breakpoint
|
||||
*/
|
||||
setCondition: function (gThreadClient, condition) {
|
||||
let root = this._client.mainRoot;
|
||||
let deferred = promise.defer();
|
||||
|
||||
if (root.traits.conditionalBreakpoints) {
|
||||
let info = {
|
||||
line: this.location.line,
|
||||
column: this.location.column,
|
||||
condition: condition
|
||||
};
|
||||
|
||||
// Remove the current breakpoint and add a new one with the
|
||||
// condition.
|
||||
this.remove(response => {
|
||||
if (response && response.error) {
|
||||
deferred.reject(response);
|
||||
return;
|
||||
}
|
||||
|
||||
this.source.setBreakpoint(info, (resp, newBreakpoint) => {
|
||||
if (resp && resp.error) {
|
||||
deferred.reject(resp);
|
||||
} else {
|
||||
deferred.resolve(newBreakpoint);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// The property shouldn't even exist if the condition is blank
|
||||
if (condition === "") {
|
||||
delete this.conditionalExpression;
|
||||
} else {
|
||||
this.conditionalExpression = condition;
|
||||
}
|
||||
deferred.resolve(this);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
};
|
||||
|
||||
eventSource(BreakpointClient.prototype);
|
||||
|
||||
module.exports = BreakpointClient;
|
|
@ -9,7 +9,7 @@
|
|||
const {Cc, Ci, Cr} = require("chrome");
|
||||
const EventEmitter = require("devtools/shared/old-event-emitter");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
const Services = require("Services");
|
||||
const { Task } = require("devtools/shared/task");
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Set of protocol messages that affect thread state, and the
|
||||
* state the actor is in after each message.
|
||||
*/
|
||||
const ThreadStateTypes = {
|
||||
"paused": "paused",
|
||||
"resumed": "attached",
|
||||
"detached": "detached",
|
||||
"running": "attached"
|
||||
};
|
||||
|
||||
/**
|
||||
* Set of protocol messages that are sent by the server without a prior request
|
||||
* by the client.
|
||||
*/
|
||||
const UnsolicitedNotifications = {
|
||||
"consoleAPICall": "consoleAPICall",
|
||||
"eventNotification": "eventNotification",
|
||||
"fileActivity": "fileActivity",
|
||||
"lastPrivateContextExited": "lastPrivateContextExited",
|
||||
"logMessage": "logMessage",
|
||||
"networkEvent": "networkEvent",
|
||||
"networkEventUpdate": "networkEventUpdate",
|
||||
"newGlobal": "newGlobal",
|
||||
"newScript": "newScript",
|
||||
"tabDetached": "tabDetached",
|
||||
"tabListChanged": "tabListChanged",
|
||||
"reflowActivity": "reflowActivity",
|
||||
"addonListChanged": "addonListChanged",
|
||||
"workerListChanged": "workerListChanged",
|
||||
"serviceWorkerRegistrationListChanged": "serviceWorkerRegistrationList",
|
||||
"tabNavigated": "tabNavigated",
|
||||
"frameUpdate": "frameUpdate",
|
||||
"pageError": "pageError",
|
||||
"documentLoad": "documentLoad",
|
||||
"enteredFrame": "enteredFrame",
|
||||
"exitedFrame": "exitedFrame",
|
||||
"appOpen": "appOpen",
|
||||
"appClose": "appClose",
|
||||
"appInstall": "appInstall",
|
||||
"appUninstall": "appUninstall",
|
||||
"evaluationResult": "evaluationResult",
|
||||
"newSource": "newSource",
|
||||
"updatedSource": "updatedSource",
|
||||
"inspectObject": "inspectObject"
|
||||
};
|
||||
|
||||
/**
|
||||
* Set of pause types that are sent by the server and not as an immediate
|
||||
* response to a client request.
|
||||
*/
|
||||
const UnsolicitedPauses = {
|
||||
"resumeLimit": "resumeLimit",
|
||||
"debuggerStatement": "debuggerStatement",
|
||||
"breakpoint": "breakpoint",
|
||||
"DOMEvent": "DOMEvent",
|
||||
"watchpoint": "watchpoint",
|
||||
"exception": "exception"
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
ThreadStateTypes,
|
||||
UnsolicitedNotifications,
|
||||
UnsolicitedPauses,
|
||||
};
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,54 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {arg, DebuggerClient} = require("./debugger-client");
|
||||
const eventSource = require("./event-source");
|
||||
|
||||
/**
|
||||
* Environment clients are used to manipulate the lexical environment actors.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The debugger client parent.
|
||||
* @param form Object
|
||||
* The form sent across the remote debugging protocol.
|
||||
*/
|
||||
function EnvironmentClient(client, form) {
|
||||
this._client = client;
|
||||
this._form = form;
|
||||
this.request = this._client.request;
|
||||
}
|
||||
exports.EnvironmentClient = EnvironmentClient;
|
||||
|
||||
EnvironmentClient.prototype = {
|
||||
|
||||
get actor() {
|
||||
return this._form.actor;
|
||||
},
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches the bindings introduced by this lexical environment.
|
||||
*/
|
||||
getBindings: DebuggerClient.requester({
|
||||
type: "bindings"
|
||||
}),
|
||||
|
||||
/**
|
||||
* Changes the value of the identifier whose name is name (a string) to that
|
||||
* represented by value (a grip).
|
||||
*/
|
||||
assign: DebuggerClient.requester({
|
||||
type: "assign",
|
||||
name: arg(0),
|
||||
value: arg(1)
|
||||
})
|
||||
};
|
||||
|
||||
eventSource(EnvironmentClient.prototype);
|
||||
|
||||
module.exports = EnvironmentClient;
|
|
@ -0,0 +1,126 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
|
||||
/**
|
||||
* TODO: Get rid of this API in favor of EventTarget (bug 1042642)
|
||||
*
|
||||
* Add simple event notification to a prototype object. Any object that has
|
||||
* some use for event notifications or the observer pattern in general can be
|
||||
* augmented with the necessary facilities by passing its prototype to this
|
||||
* function.
|
||||
*
|
||||
* @param proto object
|
||||
* The prototype object that will be modified.
|
||||
*/
|
||||
function eventSource(proto) {
|
||||
/**
|
||||
* Add a listener to the event source for a given event.
|
||||
*
|
||||
* @param name string
|
||||
* The event to listen for.
|
||||
* @param listener function
|
||||
* Called when the event is fired. If the same listener
|
||||
* is added more than once, it will be called once per
|
||||
* addListener call.
|
||||
*/
|
||||
proto.addListener = function (name, listener) {
|
||||
if (typeof listener != "function") {
|
||||
throw TypeError("Listeners must be functions.");
|
||||
}
|
||||
|
||||
if (!this._listeners) {
|
||||
this._listeners = {};
|
||||
}
|
||||
|
||||
this._getListeners(name).push(listener);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a listener to the event source for a given event. The
|
||||
* listener will be removed after it is called for the first time.
|
||||
*
|
||||
* @param name string
|
||||
* The event to listen for.
|
||||
* @param listener function
|
||||
* Called when the event is fired.
|
||||
*/
|
||||
proto.addOneTimeListener = function (name, listener) {
|
||||
let l = (...args) => {
|
||||
this.removeListener(name, l);
|
||||
listener.apply(null, args);
|
||||
};
|
||||
this.addListener(name, l);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a listener from the event source previously added with
|
||||
* addListener().
|
||||
*
|
||||
* @param name string
|
||||
* The event name used during addListener to add the listener.
|
||||
* @param listener function
|
||||
* The callback to remove. If addListener was called multiple
|
||||
* times, all instances will be removed.
|
||||
*/
|
||||
proto.removeListener = function (name, listener) {
|
||||
if (!this._listeners || (listener && !this._listeners[name])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!listener) {
|
||||
this._listeners[name] = [];
|
||||
} else {
|
||||
this._listeners[name] =
|
||||
this._listeners[name].filter(l => l != listener);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the listeners for the specified event name. If none are defined it
|
||||
* initializes an empty list and returns that.
|
||||
*
|
||||
* @param name string
|
||||
* The event name.
|
||||
*/
|
||||
proto._getListeners = function (name) {
|
||||
if (name in this._listeners) {
|
||||
return this._listeners[name];
|
||||
}
|
||||
this._listeners[name] = [];
|
||||
return this._listeners[name];
|
||||
};
|
||||
|
||||
/**
|
||||
* Notify listeners of an event.
|
||||
*
|
||||
* @param name string
|
||||
* The event to fire.
|
||||
* @param arguments
|
||||
* All arguments will be passed along to the listeners,
|
||||
* including the name argument.
|
||||
*/
|
||||
proto.emit = function () {
|
||||
if (!this._listeners) {
|
||||
return;
|
||||
}
|
||||
|
||||
let name = arguments[0];
|
||||
let listeners = this._getListeners(name).slice(0);
|
||||
|
||||
for (let listener of listeners) {
|
||||
try {
|
||||
listener.apply(null, arguments);
|
||||
} catch (e) {
|
||||
// Prevent a bad listener from interfering with the others.
|
||||
DevToolsUtils.reportException("notify event '" + name + "'", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = eventSource;
|
|
@ -0,0 +1,56 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {arg, DebuggerClient} = require("./debugger-client");
|
||||
/**
|
||||
* A LongStringClient provides a way to access "very long" strings from the
|
||||
* debugger server.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The debugger client parent.
|
||||
* @param grip Object
|
||||
* A pause-lifetime long string grip returned by the protocol.
|
||||
*/
|
||||
function LongStringClient(client, grip) {
|
||||
this._grip = grip;
|
||||
this._client = client;
|
||||
this.request = this._client.request;
|
||||
}
|
||||
|
||||
LongStringClient.prototype = {
|
||||
get actor() {
|
||||
return this._grip.actor;
|
||||
},
|
||||
get length() {
|
||||
return this._grip.length;
|
||||
},
|
||||
get initial() {
|
||||
return this._grip.initial;
|
||||
},
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
|
||||
valid: true,
|
||||
|
||||
/**
|
||||
* Get the substring of this LongString from start to end.
|
||||
*
|
||||
* @param start Number
|
||||
* The starting index.
|
||||
* @param end Number
|
||||
* The ending index.
|
||||
* @param callback Function
|
||||
* The function called when we receive the substring.
|
||||
*/
|
||||
substring: DebuggerClient.requester({
|
||||
type: "substring",
|
||||
start: arg(0),
|
||||
end: arg(1)
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = LongStringClient;
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -5,6 +5,22 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'addon-client.js',
|
||||
'array-buffer-client.js',
|
||||
'breakpoint-client.js',
|
||||
'connection-manager.js',
|
||||
'main.js',
|
||||
'constants.js',
|
||||
'debugger-client.js',
|
||||
'environment-client.js',
|
||||
'event-source.js',
|
||||
'long-string-client.js',
|
||||
'object-client.js',
|
||||
'property-iterator-client.js',
|
||||
'root-client.js',
|
||||
'source-client.js',
|
||||
'symbol-iterator-client.js',
|
||||
'tab-client.js',
|
||||
'thread-client.js',
|
||||
'trace-client.js',
|
||||
'worker-client.js',
|
||||
)
|
|
@ -0,0 +1,278 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {arg, DebuggerClient} = require("./debugger-client");
|
||||
loader.lazyRequireGetter(this, "PropertyIteratorClient", "devtools/shared/client/property-iterator-client");
|
||||
loader.lazyRequireGetter(this, "SymbolIteratorClient", "devtools/shared/client/symbol-iterator-client");
|
||||
|
||||
/**
|
||||
* Grip clients are used to retrieve information about the relevant object.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The debugger client parent.
|
||||
* @param grip object
|
||||
* A pause-lifetime object grip returned by the protocol.
|
||||
*/
|
||||
function ObjectClient(client, grip) {
|
||||
this._grip = grip;
|
||||
this._client = client;
|
||||
this.request = this._client.request;
|
||||
}
|
||||
|
||||
ObjectClient.prototype = {
|
||||
get actor() {
|
||||
return this._grip.actor;
|
||||
},
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
|
||||
valid: true,
|
||||
|
||||
get isFrozen() {
|
||||
return this._grip.frozen;
|
||||
},
|
||||
get isSealed() {
|
||||
return this._grip.sealed;
|
||||
},
|
||||
get isExtensible() {
|
||||
return this._grip.extensible;
|
||||
},
|
||||
|
||||
getDefinitionSite: DebuggerClient.requester({
|
||||
type: "definitionSite"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (this._grip.class != "Function") {
|
||||
throw new Error("getDefinitionSite is only valid for function grips.");
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the names of a function's formal parameters.
|
||||
*
|
||||
* @param onResponse function
|
||||
* Called with an object of the form:
|
||||
* { parameterNames:[<parameterName>, ...] }
|
||||
* where each <parameterName> is the name of a parameter.
|
||||
*/
|
||||
getParameterNames: DebuggerClient.requester({
|
||||
type: "parameterNames"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (this._grip.class !== "Function") {
|
||||
throw new Error("getParameterNames is only valid for function grips.");
|
||||
}
|
||||
return packet;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the names of the properties defined on the object and not its
|
||||
* prototype.
|
||||
*
|
||||
* @param onResponse function Called with the request's response.
|
||||
*/
|
||||
getOwnPropertyNames: DebuggerClient.requester({
|
||||
type: "ownPropertyNames"
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the prototype and own properties of the object.
|
||||
*
|
||||
* @param onResponse function Called with the request's response.
|
||||
*/
|
||||
getPrototypeAndProperties: DebuggerClient.requester({
|
||||
type: "prototypeAndProperties"
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request a PropertyIteratorClient instance to ease listing
|
||||
* properties for this object.
|
||||
*
|
||||
* @param options Object
|
||||
* A dictionary object with various boolean attributes:
|
||||
* - ignoreIndexedProperties Boolean
|
||||
* If true, filters out Array items.
|
||||
* e.g. properties names between `0` and `object.length`.
|
||||
* - ignoreNonIndexedProperties Boolean
|
||||
* If true, filters out items that aren't array items
|
||||
* e.g. properties names that are not a number between `0`
|
||||
* and `object.length`.
|
||||
* - sort Boolean
|
||||
* If true, the iterator will sort the properties by name
|
||||
* before dispatching them.
|
||||
* @param onResponse function Called with the client instance.
|
||||
*/
|
||||
enumProperties: DebuggerClient.requester({
|
||||
type: "enumProperties",
|
||||
options: arg(0)
|
||||
}, {
|
||||
after: function (response) {
|
||||
if (response.iterator) {
|
||||
return { iterator: new PropertyIteratorClient(this._client, response.iterator) };
|
||||
}
|
||||
return response;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request a PropertyIteratorClient instance to enumerate entries in a
|
||||
* Map/Set-like object.
|
||||
*
|
||||
* @param onResponse function Called with the request's response.
|
||||
*/
|
||||
enumEntries: DebuggerClient.requester({
|
||||
type: "enumEntries"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (!["Map", "WeakMap", "Set", "WeakSet"].includes(this._grip.class)) {
|
||||
throw new Error("enumEntries is only valid for Map/Set-like grips.");
|
||||
}
|
||||
return packet;
|
||||
},
|
||||
after: function (response) {
|
||||
if (response.iterator) {
|
||||
return {
|
||||
iterator: new PropertyIteratorClient(this._client, response.iterator)
|
||||
};
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request a SymbolIteratorClient instance to enumerate symbols in an object.
|
||||
*
|
||||
* @param onResponse function Called with the request's response.
|
||||
*/
|
||||
enumSymbols: DebuggerClient.requester({
|
||||
type: "enumSymbols"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (this._grip.type !== "object") {
|
||||
throw new Error("enumSymbols is only valid for objects grips.");
|
||||
}
|
||||
return packet;
|
||||
},
|
||||
after: function (response) {
|
||||
if (response.iterator) {
|
||||
return {
|
||||
iterator: new SymbolIteratorClient(this._client, response.iterator)
|
||||
};
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the property descriptor of the object's specified property.
|
||||
*
|
||||
* @param name string The name of the requested property.
|
||||
* @param onResponse function Called with the request's response.
|
||||
*/
|
||||
getProperty: DebuggerClient.requester({
|
||||
type: "property",
|
||||
name: arg(0)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the prototype of the object.
|
||||
*
|
||||
* @param onResponse function Called with the request's response.
|
||||
*/
|
||||
getPrototype: DebuggerClient.requester({
|
||||
type: "prototype"
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the display string of the object.
|
||||
*
|
||||
* @param onResponse function Called with the request's response.
|
||||
*/
|
||||
getDisplayString: DebuggerClient.requester({
|
||||
type: "displayString"
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the scope of the object.
|
||||
*
|
||||
* @param onResponse function Called with the request's response.
|
||||
*/
|
||||
getScope: DebuggerClient.requester({
|
||||
type: "scope"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (this._grip.class !== "Function") {
|
||||
throw new Error("scope is only valid for function grips.");
|
||||
}
|
||||
return packet;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the promises directly depending on the current promise.
|
||||
*/
|
||||
getDependentPromises: DebuggerClient.requester({
|
||||
type: "dependentPromises"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (this._grip.class !== "Promise") {
|
||||
throw new Error("getDependentPromises is only valid for promise " +
|
||||
"grips.");
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the stack to the promise's allocation point.
|
||||
*/
|
||||
getPromiseAllocationStack: DebuggerClient.requester({
|
||||
type: "allocationStack"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (this._grip.class !== "Promise") {
|
||||
throw new Error("getAllocationStack is only valid for promise grips.");
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the stack to the promise's fulfillment point.
|
||||
*/
|
||||
getPromiseFulfillmentStack: DebuggerClient.requester({
|
||||
type: "fulfillmentStack"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (this._grip.class !== "Promise") {
|
||||
throw new Error("getPromiseFulfillmentStack is only valid for " +
|
||||
"promise grips.");
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the stack to the promise's rejection point.
|
||||
*/
|
||||
getPromiseRejectionStack: DebuggerClient.requester({
|
||||
type: "rejectionStack"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (this._grip.class !== "Promise") {
|
||||
throw new Error("getPromiseRejectionStack is only valid for " +
|
||||
"promise grips.");
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
module.exports = ObjectClient;
|
|
@ -0,0 +1,81 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {arg, DebuggerClient} = require("./debugger-client");
|
||||
|
||||
/**
|
||||
* A PropertyIteratorClient provides a way to access to property names and
|
||||
* values of an object efficiently, slice by slice.
|
||||
* Note that the properties can be sorted in the backend,
|
||||
* this is controled while creating the PropertyIteratorClient
|
||||
* from ObjectClient.enumProperties.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The debugger client parent.
|
||||
* @param grip Object
|
||||
* A PropertyIteratorActor grip returned by the protocol via
|
||||
* TabActor.enumProperties request.
|
||||
*/
|
||||
function PropertyIteratorClient(client, grip) {
|
||||
this._grip = grip;
|
||||
this._client = client;
|
||||
this.request = this._client.request;
|
||||
}
|
||||
|
||||
PropertyIteratorClient.prototype = {
|
||||
get actor() {
|
||||
return this._grip.actor;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the total number of properties available in the iterator.
|
||||
*/
|
||||
get count() {
|
||||
return this._grip.count;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get one or more property names that correspond to the positions in the
|
||||
* indexes parameter.
|
||||
*
|
||||
* @param indexes Array
|
||||
* An array of property indexes.
|
||||
* @param callback Function
|
||||
* The function called when we receive the property names.
|
||||
*/
|
||||
names: DebuggerClient.requester({
|
||||
type: "names",
|
||||
indexes: arg(0)
|
||||
}, {}),
|
||||
|
||||
/**
|
||||
* Get a set of following property value(s).
|
||||
*
|
||||
* @param start Number
|
||||
* The index of the first property to fetch.
|
||||
* @param count Number
|
||||
* The number of properties to fetch.
|
||||
* @param callback Function
|
||||
* The function called when we receive the property values.
|
||||
*/
|
||||
slice: DebuggerClient.requester({
|
||||
type: "slice",
|
||||
start: arg(0),
|
||||
count: arg(1)
|
||||
}, {}),
|
||||
|
||||
/**
|
||||
* Get all the property values.
|
||||
*
|
||||
* @param callback Function
|
||||
* The function called when we receive the property values.
|
||||
*/
|
||||
all: DebuggerClient.requester({
|
||||
type: "all"
|
||||
}, {}),
|
||||
};
|
||||
|
||||
module.exports = PropertyIteratorClient;
|
|
@ -0,0 +1,179 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { Ci } = require("chrome");
|
||||
const {DebuggerClient} = require("./debugger-client");
|
||||
|
||||
/**
|
||||
* A RootClient object represents a root actor on the server. Each
|
||||
* DebuggerClient keeps a RootClient instance representing the root actor
|
||||
* for the initial connection; DebuggerClient's 'listTabs' and
|
||||
* 'listChildProcesses' methods forward to that root actor.
|
||||
*
|
||||
* @param client object
|
||||
* The client connection to which this actor belongs.
|
||||
* @param greeting string
|
||||
* The greeting packet from the root actor we're to represent.
|
||||
*
|
||||
* Properties of a RootClient instance:
|
||||
*
|
||||
* @property actor string
|
||||
* The name of this child's root actor.
|
||||
* @property applicationType string
|
||||
* The application type, as given in the root actor's greeting packet.
|
||||
* @property traits object
|
||||
* The traits object, as given in the root actor's greeting packet.
|
||||
*/
|
||||
function RootClient(client, greeting) {
|
||||
this._client = client;
|
||||
this.actor = greeting.from;
|
||||
this.applicationType = greeting.applicationType;
|
||||
this.traits = greeting.traits;
|
||||
}
|
||||
exports.RootClient = RootClient;
|
||||
|
||||
RootClient.prototype = {
|
||||
constructor: RootClient,
|
||||
|
||||
/**
|
||||
* Gets the "root" form, which lists all the global actors that affect the entire
|
||||
* browser. This can replace usages of `listTabs` that only wanted the global actors
|
||||
* and didn't actually care about tabs.
|
||||
*/
|
||||
getRoot: DebuggerClient.requester({ type: "getRoot" }),
|
||||
|
||||
/**
|
||||
* List the open tabs.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
listTabs: DebuggerClient.requester({ type: "listTabs" }),
|
||||
|
||||
/**
|
||||
* List the installed addons.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
listAddons: DebuggerClient.requester({ type: "listAddons" }),
|
||||
|
||||
/**
|
||||
* List the registered workers.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
listWorkers: DebuggerClient.requester({ type: "listWorkers" }),
|
||||
|
||||
/**
|
||||
* List the registered service workers.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
listServiceWorkerRegistrations: DebuggerClient.requester({
|
||||
type: "listServiceWorkerRegistrations"
|
||||
}),
|
||||
|
||||
/**
|
||||
* List the running processes.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
listProcesses: DebuggerClient.requester({ type: "listProcesses" }),
|
||||
|
||||
/**
|
||||
* Fetch the TabActor for the currently selected tab, or for a specific
|
||||
* tab given as first parameter.
|
||||
*
|
||||
* @param [optional] object filter
|
||||
* A dictionary object with following optional attributes:
|
||||
* - outerWindowID: used to match tabs in parent process
|
||||
* - tabId: used to match tabs in child processes
|
||||
* - tab: a reference to xul:tab element
|
||||
* If nothing is specified, returns the actor for the currently
|
||||
* selected tab.
|
||||
*/
|
||||
getTab: function (filter) {
|
||||
let packet = {
|
||||
to: this.actor,
|
||||
type: "getTab"
|
||||
};
|
||||
|
||||
if (filter) {
|
||||
if (typeof (filter.outerWindowID) == "number") {
|
||||
packet.outerWindowID = filter.outerWindowID;
|
||||
} else if (typeof (filter.tabId) == "number") {
|
||||
packet.tabId = filter.tabId;
|
||||
} else if ("tab" in filter) {
|
||||
let browser = filter.tab.linkedBrowser;
|
||||
if (browser.frameLoader.tabParent) {
|
||||
// Tabs in child process
|
||||
packet.tabId = browser.frameLoader.tabParent.tabId;
|
||||
} else if (browser.outerWindowID) {
|
||||
// <xul:browser> tabs in parent process
|
||||
packet.outerWindowID = browser.outerWindowID;
|
||||
} else {
|
||||
// <iframe mozbrowser> tabs in parent process
|
||||
let windowUtils = browser.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
packet.outerWindowID = windowUtils.outerWindowID;
|
||||
}
|
||||
} else {
|
||||
// Throw if a filter object have been passed but without
|
||||
// any clearly idenfified filter.
|
||||
throw new Error("Unsupported argument given to getTab request");
|
||||
}
|
||||
}
|
||||
|
||||
return this.request(packet);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the WindowActor for a specific window, like a browser window in
|
||||
* Firefox, but it can be used to reach any window in the process.
|
||||
*
|
||||
* @param number outerWindowID
|
||||
* The outerWindowID of the top level window you are looking for.
|
||||
*/
|
||||
getWindow: function ({ outerWindowID }) {
|
||||
if (!outerWindowID) {
|
||||
throw new Error("Must specify outerWindowID");
|
||||
}
|
||||
|
||||
let packet = {
|
||||
to: this.actor,
|
||||
type: "getWindow",
|
||||
outerWindowID,
|
||||
};
|
||||
|
||||
return this.request(packet);
|
||||
},
|
||||
|
||||
/**
|
||||
* Description of protocol's actors and methods.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
protocolDescription: DebuggerClient.requester({ type: "protocolDescription" }),
|
||||
|
||||
/*
|
||||
* Methods constructed by DebuggerClient.requester require these forwards
|
||||
* on their 'this'.
|
||||
*/
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
get request() {
|
||||
return this._client.request;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = RootClient;
|
|
@ -0,0 +1,282 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {DebuggerClient} = require("./debugger-client");
|
||||
loader.lazyRequireGetter(this, "BreakpointClient", "devtools/shared/client/breakpoint-client");
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* A SourceClient provides a way to access the source text of a script.
|
||||
*
|
||||
* @param client ThreadClient
|
||||
* The thread client parent.
|
||||
* @param form Object
|
||||
* The form sent across the remote debugging protocol.
|
||||
*/
|
||||
function SourceClient(client, form) {
|
||||
this._form = form;
|
||||
this._isBlackBoxed = form.isBlackBoxed;
|
||||
this._isPrettyPrinted = form.isPrettyPrinted;
|
||||
this._activeThread = client;
|
||||
this._client = client.client;
|
||||
}
|
||||
|
||||
SourceClient.prototype = {
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
get isBlackBoxed() {
|
||||
return this._isBlackBoxed;
|
||||
},
|
||||
get isPrettyPrinted() {
|
||||
return this._isPrettyPrinted;
|
||||
},
|
||||
get actor() {
|
||||
return this._form.actor;
|
||||
},
|
||||
get request() {
|
||||
return this._client.request;
|
||||
},
|
||||
get url() {
|
||||
return this._form.url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Black box this SourceClient's source.
|
||||
*
|
||||
* @param callback Function
|
||||
* The callback function called when we receive the response from the server.
|
||||
*/
|
||||
blackBox: DebuggerClient.requester({
|
||||
type: "blackbox"
|
||||
}, {
|
||||
after: function (response) {
|
||||
if (!response.error) {
|
||||
this._isBlackBoxed = true;
|
||||
if (this._activeThread) {
|
||||
this._activeThread.emit("blackboxchange", this);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Un-black box this SourceClient's source.
|
||||
*
|
||||
* @param callback Function
|
||||
* The callback function called when we receive the response from the server.
|
||||
*/
|
||||
unblackBox: DebuggerClient.requester({
|
||||
type: "unblackbox"
|
||||
}, {
|
||||
after: function (response) {
|
||||
if (!response.error) {
|
||||
this._isBlackBoxed = false;
|
||||
if (this._activeThread) {
|
||||
this._activeThread.emit("blackboxchange", this);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Get Executable Lines from a source
|
||||
*
|
||||
* @param callback Function
|
||||
* The callback function called when we receive the response from the server.
|
||||
*/
|
||||
getExecutableLines: function (cb = noop) {
|
||||
let packet = {
|
||||
to: this._form.actor,
|
||||
type: "getExecutableLines"
|
||||
};
|
||||
|
||||
return this._client.request(packet).then(res => {
|
||||
cb(res.lines);
|
||||
return res.lines;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a long string grip for this SourceClient's source.
|
||||
*/
|
||||
source: function (callback = noop) {
|
||||
let packet = {
|
||||
to: this._form.actor,
|
||||
type: "source"
|
||||
};
|
||||
return this._client.request(packet).then(response => {
|
||||
return this._onSourceResponse(response, callback);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Pretty print this source's text.
|
||||
*/
|
||||
prettyPrint: function (indent, callback = noop) {
|
||||
const packet = {
|
||||
to: this._form.actor,
|
||||
type: "prettyPrint",
|
||||
indent
|
||||
};
|
||||
return this._client.request(packet).then(response => {
|
||||
if (!response.error) {
|
||||
this._isPrettyPrinted = true;
|
||||
this._activeThread._clearFrames();
|
||||
this._activeThread.emit("prettyprintchange", this);
|
||||
}
|
||||
return this._onSourceResponse(response, callback);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop pretty printing this source's text.
|
||||
*/
|
||||
disablePrettyPrint: function (callback = noop) {
|
||||
const packet = {
|
||||
to: this._form.actor,
|
||||
type: "disablePrettyPrint"
|
||||
};
|
||||
return this._client.request(packet).then(response => {
|
||||
if (!response.error) {
|
||||
this._isPrettyPrinted = false;
|
||||
this._activeThread._clearFrames();
|
||||
this._activeThread.emit("prettyprintchange", this);
|
||||
}
|
||||
return this._onSourceResponse(response, callback);
|
||||
});
|
||||
},
|
||||
|
||||
_onSourceResponse: function (response, callback) {
|
||||
if (response.error) {
|
||||
callback(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
if (typeof response.source === "string") {
|
||||
callback(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
let { contentType, source } = response;
|
||||
if (source.type === "arrayBuffer") {
|
||||
let arrayBuffer = this._activeThread.threadArrayBuffer(source);
|
||||
return arrayBuffer.slice(0, arrayBuffer.length).then(function (resp) {
|
||||
if (resp.error) {
|
||||
callback(resp);
|
||||
return resp;
|
||||
}
|
||||
// Keeping str as a string, ArrayBuffer/Uint8Array will not survive
|
||||
// setIn/mergeIn operations.
|
||||
const str = atob(resp.encoded);
|
||||
let newResponse = {
|
||||
source: {
|
||||
binary: str,
|
||||
toString: () => "[wasm]",
|
||||
},
|
||||
contentType,
|
||||
};
|
||||
callback(newResponse);
|
||||
return newResponse;
|
||||
});
|
||||
}
|
||||
|
||||
let longString = this._activeThread.threadLongString(source);
|
||||
return longString.substring(0, longString.length).then(function (resp) {
|
||||
if (resp.error) {
|
||||
callback(resp);
|
||||
return resp;
|
||||
}
|
||||
|
||||
let newResponse = {
|
||||
source: resp.substring,
|
||||
contentType: contentType
|
||||
};
|
||||
callback(newResponse);
|
||||
return newResponse;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Request to set a breakpoint in the specified location.
|
||||
*
|
||||
* @param object location
|
||||
* The location and condition of the breakpoint in
|
||||
* the form of { line[, column, condition] }.
|
||||
* @param function onResponse
|
||||
* Called with the thread's response.
|
||||
*/
|
||||
setBreakpoint: function ({ line, column, condition, noSliding }, onResponse = noop) {
|
||||
// A helper function that sets the breakpoint.
|
||||
let doSetBreakpoint = callback => {
|
||||
let root = this._client.mainRoot;
|
||||
let location = {
|
||||
line,
|
||||
column,
|
||||
};
|
||||
|
||||
let packet = {
|
||||
to: this.actor,
|
||||
type: "setBreakpoint",
|
||||
location,
|
||||
condition,
|
||||
noSliding,
|
||||
};
|
||||
|
||||
// Backwards compatibility: send the breakpoint request to the
|
||||
// thread if the server doesn't support Debugger.Source actors.
|
||||
if (!root.traits.debuggerSourceActors) {
|
||||
packet.to = this._activeThread.actor;
|
||||
packet.location.url = this.url;
|
||||
}
|
||||
|
||||
return this._client.request(packet).then(response => {
|
||||
// Ignoring errors, since the user may be setting a breakpoint in a
|
||||
// dead script that will reappear on a page reload.
|
||||
let bpClient;
|
||||
if (response.actor) {
|
||||
bpClient = new BreakpointClient(
|
||||
this._client,
|
||||
this,
|
||||
response.actor,
|
||||
location,
|
||||
root.traits.conditionalBreakpoints ? condition : undefined
|
||||
);
|
||||
}
|
||||
onResponse(response, bpClient);
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
return [response, bpClient];
|
||||
});
|
||||
};
|
||||
|
||||
// If the debuggee is paused, just set the breakpoint.
|
||||
if (this._activeThread.paused) {
|
||||
return doSetBreakpoint();
|
||||
}
|
||||
// Otherwise, force a pause in order to set the breakpoint.
|
||||
return this._activeThread.interrupt().then(response => {
|
||||
if (response.error) {
|
||||
// Can't set the breakpoint if pausing failed.
|
||||
onResponse(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
const { type, why } = response;
|
||||
const cleanUp = type == "paused" && why.type == "interrupted"
|
||||
? () => this._activeThread.resume()
|
||||
: noop;
|
||||
|
||||
return doSetBreakpoint(cleanUp);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = SourceClient;
|
|
@ -0,0 +1,64 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {arg, DebuggerClient} = require("./debugger-client");
|
||||
|
||||
/**
|
||||
* A SymbolIteratorClient provides a way to access to symbols
|
||||
* of an object efficiently, slice by slice.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The debugger client parent.
|
||||
* @param grip Object
|
||||
* A SymbolIteratorActor grip returned by the protocol via
|
||||
* TabActor.enumSymbols request.
|
||||
*/
|
||||
function SymbolIteratorClient(client, grip) {
|
||||
this._grip = grip;
|
||||
this._client = client;
|
||||
this.request = this._client.request;
|
||||
}
|
||||
|
||||
SymbolIteratorClient.prototype = {
|
||||
get actor() {
|
||||
return this._grip.actor;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the total number of symbols available in the iterator.
|
||||
*/
|
||||
get count() {
|
||||
return this._grip.count;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a set of following symbols.
|
||||
*
|
||||
* @param start Number
|
||||
* The index of the first symbol to fetch.
|
||||
* @param count Number
|
||||
* The number of symbols to fetch.
|
||||
* @param callback Function
|
||||
* The function called when we receive the symbols.
|
||||
*/
|
||||
slice: DebuggerClient.requester({
|
||||
type: "slice",
|
||||
start: arg(0),
|
||||
count: arg(1)
|
||||
}, {}),
|
||||
|
||||
/**
|
||||
* Get all the symbols.
|
||||
*
|
||||
* @param callback Function
|
||||
* The function called when we receive the symbols.
|
||||
*/
|
||||
all: DebuggerClient.requester({
|
||||
type: "all"
|
||||
}, {}),
|
||||
};
|
||||
|
||||
module.exports = SymbolIteratorClient;
|
|
@ -0,0 +1,156 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { Cu } = require("chrome");
|
||||
const promise = Cu.import("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise;
|
||||
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const eventSource = require("./event-source");
|
||||
const {arg, DebuggerClient} = require("./debugger-client");
|
||||
loader.lazyRequireGetter(this, "ThreadClient", "devtools/shared/client/thread-client");
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* Creates a tab client for the remote debugging protocol server. This client
|
||||
* is a front to the tab actor created in the server side, hiding the protocol
|
||||
* details in a traditional JavaScript API.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The debugger client parent.
|
||||
* @param form object
|
||||
* The protocol form for this tab.
|
||||
*/
|
||||
function TabClient(client, form) {
|
||||
this.client = client;
|
||||
this._actor = form.from;
|
||||
this._threadActor = form.threadActor;
|
||||
this.javascriptEnabled = form.javascriptEnabled;
|
||||
this.cacheDisabled = form.cacheDisabled;
|
||||
this.thread = null;
|
||||
this.request = this.client.request;
|
||||
this.traits = form.traits || {};
|
||||
this.events = ["workerListChanged"];
|
||||
}
|
||||
|
||||
TabClient.prototype = {
|
||||
get actor() {
|
||||
return this._actor;
|
||||
},
|
||||
get _transport() {
|
||||
return this.client._transport;
|
||||
},
|
||||
|
||||
/**
|
||||
* Attach to a thread actor.
|
||||
*
|
||||
* @param object options
|
||||
* Configuration options.
|
||||
* - useSourceMaps: whether to use source maps or not.
|
||||
* @param function onResponse
|
||||
* Called with the response packet and a ThreadClient
|
||||
* (which will be undefined on error).
|
||||
*/
|
||||
attachThread: function (options = {}, onResponse = noop) {
|
||||
if (this.thread) {
|
||||
DevToolsUtils.executeSoon(() => onResponse({}, this.thread));
|
||||
return promise.resolve([{}, this.thread]);
|
||||
}
|
||||
|
||||
let packet = {
|
||||
to: this._threadActor,
|
||||
type: "attach",
|
||||
options,
|
||||
};
|
||||
return this.request(packet).then(response => {
|
||||
if (!response.error) {
|
||||
this.thread = new ThreadClient(this, this._threadActor);
|
||||
this.client.registerClient(this.thread);
|
||||
}
|
||||
onResponse(response, this.thread);
|
||||
return [response, this.thread];
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Detach the client from the tab actor.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
detach: DebuggerClient.requester({
|
||||
type: "detach"
|
||||
}, {
|
||||
before: function (packet) {
|
||||
if (this.thread) {
|
||||
this.thread.detach();
|
||||
}
|
||||
return packet;
|
||||
},
|
||||
after: function (response) {
|
||||
this.client.unregisterClient(this);
|
||||
return response;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Bring the window to the front.
|
||||
*/
|
||||
focus: DebuggerClient.requester({
|
||||
type: "focus"
|
||||
}, {}),
|
||||
|
||||
/**
|
||||
* Reload the page in this tab.
|
||||
*
|
||||
* @param [optional] object options
|
||||
* An object with a `force` property indicating whether or not
|
||||
* this reload should skip the cache
|
||||
*/
|
||||
reload: function (options = { force: false }) {
|
||||
return this._reload(options);
|
||||
},
|
||||
_reload: DebuggerClient.requester({
|
||||
type: "reload",
|
||||
options: arg(0)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Navigate to another URL.
|
||||
*
|
||||
* @param string url
|
||||
* The URL to navigate to.
|
||||
*/
|
||||
navigateTo: DebuggerClient.requester({
|
||||
type: "navigateTo",
|
||||
url: arg(0)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Reconfigure the tab actor.
|
||||
*
|
||||
* @param object options
|
||||
* A dictionary object of the new options to use in the tab actor.
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
reconfigure: DebuggerClient.requester({
|
||||
type: "reconfigure",
|
||||
options: arg(0)
|
||||
}),
|
||||
|
||||
listWorkers: DebuggerClient.requester({
|
||||
type: "listWorkers"
|
||||
}),
|
||||
|
||||
attachWorker: function (workerActor, onResponse) {
|
||||
return this.client.attachWorker(workerActor, onResponse);
|
||||
},
|
||||
};
|
||||
|
||||
eventSource(TabClient.prototype);
|
||||
|
||||
module.exports = TabClient;
|
|
@ -0,0 +1,663 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { Cu } = require("chrome");
|
||||
const promise = Cu.import("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise;
|
||||
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const {arg, DebuggerClient} = require("./debugger-client");
|
||||
const eventSource = require("./event-source");
|
||||
const {ThreadStateTypes} = require("./constants");
|
||||
|
||||
loader.lazyRequireGetter(this, "ArrayBufferClient", "devtools/shared/client/array-buffer-client");
|
||||
loader.lazyRequireGetter(this, "EnvironmentClient", "devtools/shared/client/environment-client");
|
||||
loader.lazyRequireGetter(this, "LongStringClient", "devtools/shared/client/long-string-client");
|
||||
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/object-client");
|
||||
loader.lazyRequireGetter(this, "SourceClient", "devtools/shared/client/source-client");
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* Creates a thread client for the remote debugging protocol server. This client
|
||||
* is a front to the thread actor created in the server side, hiding the
|
||||
* protocol details in a traditional JavaScript API.
|
||||
*
|
||||
* @param client DebuggerClient|TabClient
|
||||
* The parent of the thread (tab for tab-scoped debuggers, DebuggerClient
|
||||
* for chrome debuggers).
|
||||
* @param actor string
|
||||
* The actor ID for this thread.
|
||||
*/
|
||||
function ThreadClient(client, actor) {
|
||||
this._parent = client;
|
||||
this.client = client instanceof DebuggerClient ? client : client.client;
|
||||
this._actor = actor;
|
||||
this._frameCache = [];
|
||||
this._scriptCache = {};
|
||||
this._pauseGrips = {};
|
||||
this._threadGrips = {};
|
||||
this.request = this.client.request;
|
||||
}
|
||||
|
||||
ThreadClient.prototype = {
|
||||
_state: "paused",
|
||||
get state() {
|
||||
return this._state;
|
||||
},
|
||||
get paused() {
|
||||
return this._state === "paused";
|
||||
},
|
||||
|
||||
_pauseOnExceptions: false,
|
||||
_ignoreCaughtExceptions: false,
|
||||
_pauseOnDOMEvents: null,
|
||||
|
||||
_actor: null,
|
||||
get actor() {
|
||||
return this._actor;
|
||||
},
|
||||
|
||||
get _transport() {
|
||||
return this.client._transport;
|
||||
},
|
||||
|
||||
_assertPaused: function (command) {
|
||||
if (!this.paused) {
|
||||
throw Error(command + " command sent while not paused. Currently " + this._state);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Resume a paused thread. If the optional limit parameter is present, then
|
||||
* the thread will also pause when that limit is reached.
|
||||
*
|
||||
* @param [optional] object limit
|
||||
* An object with a type property set to the appropriate limit (next,
|
||||
* step, or finish) per the remote debugging protocol specification.
|
||||
* Use null to specify no limit.
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
_doResume: DebuggerClient.requester({
|
||||
type: "resume",
|
||||
resumeLimit: arg(0)
|
||||
}, {
|
||||
before: function (packet) {
|
||||
this._assertPaused("resume");
|
||||
|
||||
// Put the client in a tentative "resuming" state so we can prevent
|
||||
// further requests that should only be sent in the paused state.
|
||||
this._previousState = this._state;
|
||||
this._state = "resuming";
|
||||
|
||||
if (this._pauseOnExceptions) {
|
||||
packet.pauseOnExceptions = this._pauseOnExceptions;
|
||||
}
|
||||
if (this._ignoreCaughtExceptions) {
|
||||
packet.ignoreCaughtExceptions = this._ignoreCaughtExceptions;
|
||||
}
|
||||
if (this._pauseOnDOMEvents) {
|
||||
packet.pauseOnDOMEvents = this._pauseOnDOMEvents;
|
||||
}
|
||||
return packet;
|
||||
},
|
||||
after: function (response) {
|
||||
if (response.error && this._state == "resuming") {
|
||||
// There was an error resuming, update the state to the new one
|
||||
// reported by the server, if given (only on wrongState), otherwise
|
||||
// reset back to the previous state.
|
||||
if (response.state) {
|
||||
this._state = ThreadStateTypes[response.state];
|
||||
} else {
|
||||
this._state = this._previousState;
|
||||
}
|
||||
}
|
||||
delete this._previousState;
|
||||
return response;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Reconfigure the thread actor.
|
||||
*
|
||||
* @param object options
|
||||
* A dictionary object of the new options to use in the thread actor.
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
reconfigure: DebuggerClient.requester({
|
||||
type: "reconfigure",
|
||||
options: arg(0)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Resume a paused thread.
|
||||
*/
|
||||
resume: function (onResponse) {
|
||||
return this._doResume(null, onResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Resume then pause without stepping.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
resumeThenPause: function (onResponse) {
|
||||
return this._doResume({ type: "break" }, onResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Step over a function call.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
stepOver: function (onResponse) {
|
||||
return this._doResume({ type: "next" }, onResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Step into a function call.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
stepIn: function (onResponse) {
|
||||
return this._doResume({ type: "step" }, onResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Step out of a function call.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
stepOut: function (onResponse) {
|
||||
return this._doResume({ type: "finish" }, onResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Immediately interrupt a running thread.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
interrupt: function (onResponse) {
|
||||
return this._doInterrupt(null, onResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Pause execution right before the next JavaScript bytecode is executed.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
breakOnNext: function (onResponse) {
|
||||
return this._doInterrupt("onNext", onResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Interrupt a running thread.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
_doInterrupt: DebuggerClient.requester({
|
||||
type: "interrupt",
|
||||
when: arg(0)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Enable or disable pausing when an exception is thrown.
|
||||
*
|
||||
* @param boolean pauseOnExceptions
|
||||
* Enables pausing if true, disables otherwise.
|
||||
* @param boolean ignoreCaughtExceptions
|
||||
* Whether to ignore caught exceptions
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
pauseOnExceptions: function (pauseOnExceptions,
|
||||
ignoreCaughtExceptions,
|
||||
onResponse = noop) {
|
||||
this._pauseOnExceptions = pauseOnExceptions;
|
||||
this._ignoreCaughtExceptions = ignoreCaughtExceptions;
|
||||
|
||||
// Otherwise send the flag using a standard resume request.
|
||||
if (!this.paused) {
|
||||
return this.interrupt(response => {
|
||||
if (response.error) {
|
||||
// Can't continue if pausing failed.
|
||||
onResponse(response);
|
||||
return response;
|
||||
}
|
||||
return this.resume(onResponse);
|
||||
});
|
||||
}
|
||||
|
||||
onResponse();
|
||||
return promise.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable pausing when the specified DOM events are triggered. Disabling
|
||||
* pausing on an event can be realized by calling this method with the updated
|
||||
* array of events that doesn't contain it.
|
||||
*
|
||||
* @param array|string events
|
||||
* An array of strings, representing the DOM event types to pause on,
|
||||
* or "*" to pause on all DOM events. Pass an empty array to
|
||||
* completely disable pausing on DOM events.
|
||||
* @param function onResponse
|
||||
* Called with the response packet in a future turn of the event loop.
|
||||
*/
|
||||
pauseOnDOMEvents: function (events, onResponse = noop) {
|
||||
this._pauseOnDOMEvents = events;
|
||||
// If the debuggee is paused, the value of the array will be communicated in
|
||||
// the next resumption. Otherwise we have to force a pause in order to send
|
||||
// the array.
|
||||
if (this.paused) {
|
||||
DevToolsUtils.executeSoon(() => onResponse({}));
|
||||
return {};
|
||||
}
|
||||
return this.interrupt(response => {
|
||||
// Can't continue if pausing failed.
|
||||
if (response.error) {
|
||||
onResponse(response);
|
||||
return response;
|
||||
}
|
||||
return this.resume(onResponse);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Send a clientEvaluate packet to the debuggee. Response
|
||||
* will be a resume packet.
|
||||
*
|
||||
* @param string frame
|
||||
* The actor ID of the frame where the evaluation should take place.
|
||||
* @param string expression
|
||||
* The expression that will be evaluated in the scope of the frame
|
||||
* above.
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
eval: DebuggerClient.requester({
|
||||
type: "clientEvaluate",
|
||||
frame: arg(0),
|
||||
expression: arg(1)
|
||||
}, {
|
||||
before: function (packet) {
|
||||
this._assertPaused("eval");
|
||||
// Put the client in a tentative "resuming" state so we can prevent
|
||||
// further requests that should only be sent in the paused state.
|
||||
this._state = "resuming";
|
||||
return packet;
|
||||
},
|
||||
after: function (response) {
|
||||
if (response.error) {
|
||||
// There was an error resuming, back to paused state.
|
||||
this._state = "paused";
|
||||
}
|
||||
return response;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Detach from the thread actor.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
detach: DebuggerClient.requester({
|
||||
type: "detach"
|
||||
}, {
|
||||
after: function (response) {
|
||||
this.client.unregisterClient(this);
|
||||
this._parent.thread = null;
|
||||
return response;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Release multiple thread-lifetime object actors. If any pause-lifetime
|
||||
* actors are included in the request, a |notReleasable| error will return,
|
||||
* but all the thread-lifetime ones will have been released.
|
||||
*
|
||||
* @param array actors
|
||||
* An array with actor IDs to release.
|
||||
*/
|
||||
releaseMany: DebuggerClient.requester({
|
||||
type: "releaseMany",
|
||||
actors: arg(0),
|
||||
}),
|
||||
|
||||
/**
|
||||
* Promote multiple pause-lifetime object actors to thread-lifetime ones.
|
||||
*
|
||||
* @param array actors
|
||||
* An array with actor IDs to promote.
|
||||
*/
|
||||
threadGrips: DebuggerClient.requester({
|
||||
type: "threadGrips",
|
||||
actors: arg(0)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Return the event listeners defined on the page.
|
||||
*
|
||||
* @param onResponse Function
|
||||
* Called with the thread's response.
|
||||
*/
|
||||
eventListeners: DebuggerClient.requester({
|
||||
type: "eventListeners"
|
||||
}),
|
||||
|
||||
/**
|
||||
* Request the loaded sources for the current thread.
|
||||
*
|
||||
* @param onResponse Function
|
||||
* Called with the thread's response.
|
||||
*/
|
||||
getSources: DebuggerClient.requester({
|
||||
type: "sources"
|
||||
}),
|
||||
|
||||
/**
|
||||
* Clear the thread's source script cache. A scriptscleared event
|
||||
* will be sent.
|
||||
*/
|
||||
_clearScripts: function () {
|
||||
if (Object.keys(this._scriptCache).length > 0) {
|
||||
this._scriptCache = {};
|
||||
this.emit("scriptscleared");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Request frames from the callstack for the current thread.
|
||||
*
|
||||
* @param start integer
|
||||
* The number of the youngest stack frame to return (the youngest
|
||||
* frame is 0).
|
||||
* @param count integer
|
||||
* The maximum number of frames to return, or null to return all
|
||||
* frames.
|
||||
* @param onResponse function
|
||||
* Called with the thread's response.
|
||||
*/
|
||||
getFrames: DebuggerClient.requester({
|
||||
type: "frames",
|
||||
start: arg(0),
|
||||
count: arg(1)
|
||||
}),
|
||||
|
||||
/**
|
||||
* An array of cached frames. Clients can observe the framesadded and
|
||||
* framescleared event to keep up to date on changes to this cache,
|
||||
* and can fill it using the fillFrames method.
|
||||
*/
|
||||
get cachedFrames() {
|
||||
return this._frameCache;
|
||||
},
|
||||
|
||||
/**
|
||||
* true if there are more stack frames available on the server.
|
||||
*/
|
||||
get moreFrames() {
|
||||
return this.paused && (!this._frameCache || this._frameCache.length == 0
|
||||
|| !this._frameCache[this._frameCache.length - 1].oldest);
|
||||
},
|
||||
|
||||
/**
|
||||
* Request the frame environment.
|
||||
*
|
||||
* @param frameId string
|
||||
*/
|
||||
getEnvironment: function (frameId) {
|
||||
return this.request({ to: frameId, type: "getEnvironment" });
|
||||
},
|
||||
|
||||
/**
|
||||
* Ensure that at least total stack frames have been loaded in the
|
||||
* ThreadClient's stack frame cache. A framesadded event will be
|
||||
* sent when the stack frame cache is updated.
|
||||
*
|
||||
* @param total number
|
||||
* The minimum number of stack frames to be included.
|
||||
* @param callback function
|
||||
* Optional callback function called when frames have been loaded
|
||||
* @returns true if a framesadded notification should be expected.
|
||||
*/
|
||||
fillFrames: function (total, callback = noop) {
|
||||
this._assertPaused("fillFrames");
|
||||
if (this._frameCache.length >= total) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let numFrames = this._frameCache.length;
|
||||
|
||||
this.getFrames(numFrames, total - numFrames, (response) => {
|
||||
if (response.error) {
|
||||
callback(response);
|
||||
return;
|
||||
}
|
||||
|
||||
let threadGrips = DevToolsUtils.values(this._threadGrips);
|
||||
|
||||
for (let i in response.frames) {
|
||||
let frame = response.frames[i];
|
||||
if (!frame.where.source) {
|
||||
// Older servers use urls instead, so we need to resolve
|
||||
// them to source actors
|
||||
for (let grip of threadGrips) {
|
||||
if (grip instanceof SourceClient && grip.url === frame.url) {
|
||||
frame.where.source = grip._form;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._frameCache[frame.depth] = frame;
|
||||
}
|
||||
|
||||
// If we got as many frames as we asked for, there might be more
|
||||
// frames available.
|
||||
this.emit("framesadded");
|
||||
|
||||
callback(response);
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear the thread's stack frame cache. A framescleared event
|
||||
* will be sent.
|
||||
*/
|
||||
_clearFrames: function () {
|
||||
if (this._frameCache.length > 0) {
|
||||
this._frameCache = [];
|
||||
this.emit("framescleared");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return a ObjectClient object for the given object grip.
|
||||
*
|
||||
* @param grip object
|
||||
* A pause-lifetime object grip returned by the protocol.
|
||||
*/
|
||||
pauseGrip: function (grip) {
|
||||
if (grip.actor in this._pauseGrips) {
|
||||
return this._pauseGrips[grip.actor];
|
||||
}
|
||||
|
||||
let client = new ObjectClient(this.client, grip);
|
||||
this._pauseGrips[grip.actor] = client;
|
||||
return client;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get or create a long string client, checking the grip client cache if it
|
||||
* already exists.
|
||||
*
|
||||
* @param grip Object
|
||||
* The long string grip returned by the protocol.
|
||||
* @param gripCacheName String
|
||||
* The property name of the grip client cache to check for existing
|
||||
* clients in.
|
||||
*/
|
||||
_longString: function (grip, gripCacheName) {
|
||||
if (grip.actor in this[gripCacheName]) {
|
||||
return this[gripCacheName][grip.actor];
|
||||
}
|
||||
|
||||
let client = new LongStringClient(this.client, grip);
|
||||
this[gripCacheName][grip.actor] = client;
|
||||
return client;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return an instance of LongStringClient for the given long string grip that
|
||||
* is scoped to the current pause.
|
||||
*
|
||||
* @param grip Object
|
||||
* The long string grip returned by the protocol.
|
||||
*/
|
||||
pauseLongString: function (grip) {
|
||||
return this._longString(grip, "_pauseGrips");
|
||||
},
|
||||
|
||||
/**
|
||||
* Return an instance of LongStringClient for the given long string grip that
|
||||
* is scoped to the thread lifetime.
|
||||
*
|
||||
* @param grip Object
|
||||
* The long string grip returned by the protocol.
|
||||
*/
|
||||
threadLongString: function (grip) {
|
||||
return this._longString(grip, "_threadGrips");
|
||||
},
|
||||
|
||||
/**
|
||||
* Get or create an ArrayBuffer client, checking the grip client cache if it
|
||||
* already exists.
|
||||
*
|
||||
* @param grip Object
|
||||
* The ArrayBuffer grip returned by the protocol.
|
||||
* @param gripCacheName String
|
||||
* The property name of the grip client cache to check for existing
|
||||
* clients in.
|
||||
*/
|
||||
_arrayBuffer: function (grip, gripCacheName) {
|
||||
if (grip.actor in this[gripCacheName]) {
|
||||
return this[gripCacheName][grip.actor];
|
||||
}
|
||||
|
||||
let client = new ArrayBufferClient(this.client, grip);
|
||||
this[gripCacheName][grip.actor] = client;
|
||||
return client;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return an instance of ArrayBufferClient for the given ArrayBuffer grip that
|
||||
* is scoped to the thread lifetime.
|
||||
*
|
||||
* @param grip Object
|
||||
* The ArrayBuffer grip returned by the protocol.
|
||||
*/
|
||||
threadArrayBuffer: function (grip) {
|
||||
return this._arrayBuffer(grip, "_threadGrips");
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear and invalidate all the grip clients from the given cache.
|
||||
*
|
||||
* @param gripCacheName
|
||||
* The property name of the grip cache we want to clear.
|
||||
*/
|
||||
_clearObjectClients: function (gripCacheName) {
|
||||
for (let id in this[gripCacheName]) {
|
||||
this[gripCacheName][id].valid = false;
|
||||
}
|
||||
this[gripCacheName] = {};
|
||||
},
|
||||
|
||||
/**
|
||||
* Invalidate pause-lifetime grip clients and clear the list of current grip
|
||||
* clients.
|
||||
*/
|
||||
_clearPauseGrips: function () {
|
||||
this._clearObjectClients("_pauseGrips");
|
||||
},
|
||||
|
||||
/**
|
||||
* Invalidate thread-lifetime grip clients and clear the list of current grip
|
||||
* clients.
|
||||
*/
|
||||
_clearThreadGrips: function () {
|
||||
this._clearObjectClients("_threadGrips");
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle thread state change by doing necessary cleanup and notifying all
|
||||
* registered listeners.
|
||||
*/
|
||||
_onThreadState: function (packet) {
|
||||
this._state = ThreadStateTypes[packet.type];
|
||||
// The debugger UI may not be initialized yet so we want to keep
|
||||
// the packet around so it knows what to pause state to display
|
||||
// when it's initialized
|
||||
this._lastPausePacket = packet.type === "resumed" ? null : packet;
|
||||
this._clearFrames();
|
||||
this._clearPauseGrips();
|
||||
packet.type === ThreadStateTypes.detached && this._clearThreadGrips();
|
||||
this.client._eventsEnabled && this.emit(packet.type, packet);
|
||||
},
|
||||
|
||||
getLastPausePacket: function () {
|
||||
return this._lastPausePacket;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return an EnvironmentClient instance for the given environment actor form.
|
||||
*/
|
||||
environment: function (form) {
|
||||
return new EnvironmentClient(this.client, form);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return an instance of SourceClient for the given source actor form.
|
||||
*/
|
||||
source: function (form) {
|
||||
if (form.actor in this._threadGrips) {
|
||||
return this._threadGrips[form.actor];
|
||||
}
|
||||
|
||||
this._threadGrips[form.actor] = new SourceClient(this, form);
|
||||
return this._threadGrips[form.actor];
|
||||
},
|
||||
|
||||
/**
|
||||
* Request the prototype and own properties of mutlipleObjects.
|
||||
*
|
||||
* @param onResponse function
|
||||
* Called with the request's response.
|
||||
* @param actors [string]
|
||||
* List of actor ID of the queried objects.
|
||||
*/
|
||||
getPrototypesAndProperties: DebuggerClient.requester({
|
||||
type: "prototypesAndProperties",
|
||||
actors: arg(0)
|
||||
}),
|
||||
|
||||
events: ["newSource"]
|
||||
};
|
||||
|
||||
eventSource(ThreadClient.prototype);
|
||||
|
||||
module.exports = ThreadClient;
|
|
@ -0,0 +1,112 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {arg, DebuggerClient} = require("./debugger-client");
|
||||
|
||||
/**
|
||||
* Creates a tracing profiler client for the remote debugging protocol
|
||||
* server. This client is a front to the trace actor created on the
|
||||
* server side, hiding the protocol details in a traditional
|
||||
* JavaScript API.
|
||||
*
|
||||
* @param client DebuggerClient
|
||||
* The debugger client parent.
|
||||
* @param actor string
|
||||
* The actor ID for this thread.
|
||||
*/
|
||||
function TraceClient(client, actor) {
|
||||
this._client = client;
|
||||
this._actor = actor;
|
||||
this._activeTraces = new Set();
|
||||
this._waitingPackets = new Map();
|
||||
this._expectedPacket = 0;
|
||||
this.request = this._client.request;
|
||||
this.events = [];
|
||||
}
|
||||
|
||||
TraceClient.prototype = {
|
||||
get actor() {
|
||||
return this._actor;
|
||||
},
|
||||
get tracing() {
|
||||
return this._activeTraces.size > 0;
|
||||
},
|
||||
|
||||
get _transport() {
|
||||
return this._client._transport;
|
||||
},
|
||||
|
||||
/**
|
||||
* Detach from the trace actor.
|
||||
*/
|
||||
detach: DebuggerClient.requester({
|
||||
type: "detach"
|
||||
}, {
|
||||
after: function (response) {
|
||||
this._client.unregisterClient(this);
|
||||
return response;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Start a new trace.
|
||||
*
|
||||
* @param trace [string]
|
||||
* An array of trace types to be recorded by the new trace.
|
||||
*
|
||||
* @param name string
|
||||
* The name of the new trace.
|
||||
*
|
||||
* @param onResponse function
|
||||
* Called with the request's response.
|
||||
*/
|
||||
startTrace: DebuggerClient.requester({
|
||||
type: "startTrace",
|
||||
name: arg(1),
|
||||
trace: arg(0)
|
||||
}, {
|
||||
after: function (response) {
|
||||
if (response.error) {
|
||||
return response;
|
||||
}
|
||||
|
||||
if (!this.tracing) {
|
||||
this._waitingPackets.clear();
|
||||
this._expectedPacket = 0;
|
||||
}
|
||||
this._activeTraces.add(response.name);
|
||||
|
||||
return response;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* End a trace. If a name is provided, stop the named
|
||||
* trace. Otherwise, stop the most recently started trace.
|
||||
*
|
||||
* @param name string
|
||||
* The name of the trace to stop.
|
||||
*
|
||||
* @param onResponse function
|
||||
* Called with the request's response.
|
||||
*/
|
||||
stopTrace: DebuggerClient.requester({
|
||||
type: "stopTrace",
|
||||
name: arg(0)
|
||||
}, {
|
||||
after: function (response) {
|
||||
if (response.error) {
|
||||
return response;
|
||||
}
|
||||
|
||||
this._activeTraces.delete(response.name);
|
||||
|
||||
return response;
|
||||
},
|
||||
})
|
||||
};
|
||||
|
||||
module.exports = TraceClient;
|
|
@ -0,0 +1,120 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {DebuggerClient} = require("./debugger-client");
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const eventSource = require("./event-source");
|
||||
loader.lazyRequireGetter(this, "ThreadClient", "devtools/shared/client/thread-client");
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
function WorkerClient(client, form) {
|
||||
this.client = client;
|
||||
this._actor = form.from;
|
||||
this._isClosed = false;
|
||||
this._url = form.url;
|
||||
|
||||
this._onClose = this._onClose.bind(this);
|
||||
|
||||
this.addListener("close", this._onClose);
|
||||
|
||||
this.traits = {};
|
||||
}
|
||||
|
||||
WorkerClient.prototype = {
|
||||
get _transport() {
|
||||
return this.client._transport;
|
||||
},
|
||||
|
||||
get request() {
|
||||
return this.client.request;
|
||||
},
|
||||
|
||||
get actor() {
|
||||
return this._actor;
|
||||
},
|
||||
|
||||
get url() {
|
||||
return this._url;
|
||||
},
|
||||
|
||||
get isClosed() {
|
||||
return this._isClosed;
|
||||
},
|
||||
|
||||
detach: DebuggerClient.requester({ type: "detach" }, {
|
||||
after: function (response) {
|
||||
if (this.thread) {
|
||||
this.client.unregisterClient(this.thread);
|
||||
}
|
||||
this.client.unregisterClient(this);
|
||||
return response;
|
||||
},
|
||||
}),
|
||||
|
||||
attachThread: function (options = {}, onResponse = noop) {
|
||||
if (this.thread) {
|
||||
let response = [{
|
||||
type: "connected",
|
||||
threadActor: this.thread._actor,
|
||||
consoleActor: this.consoleActor,
|
||||
}, this.thread];
|
||||
DevToolsUtils.executeSoon(() => onResponse(response));
|
||||
return response;
|
||||
}
|
||||
|
||||
// The connect call on server doesn't attach the thread as of version 44.
|
||||
return this.request({
|
||||
to: this._actor,
|
||||
type: "connect",
|
||||
options,
|
||||
}).then(connectResponse => {
|
||||
if (connectResponse.error) {
|
||||
onResponse(connectResponse, null);
|
||||
return [connectResponse, null];
|
||||
}
|
||||
|
||||
return this.request({
|
||||
to: connectResponse.threadActor,
|
||||
type: "attach",
|
||||
options,
|
||||
}).then(attachResponse => {
|
||||
if (attachResponse.error) {
|
||||
onResponse(attachResponse, null);
|
||||
}
|
||||
|
||||
this.thread = new ThreadClient(this, connectResponse.threadActor);
|
||||
this.consoleActor = connectResponse.consoleActor;
|
||||
this.client.registerClient(this.thread);
|
||||
|
||||
onResponse(connectResponse, this.thread);
|
||||
return [connectResponse, this.thread];
|
||||
});
|
||||
}, error => {
|
||||
onResponse(error, null);
|
||||
});
|
||||
},
|
||||
|
||||
_onClose: function () {
|
||||
this.removeListener("close", this._onClose);
|
||||
|
||||
if (this.thread) {
|
||||
this.client.unregisterClient(this.thread);
|
||||
}
|
||||
this.client.unregisterClient(this);
|
||||
this._isClosed = true;
|
||||
},
|
||||
|
||||
reconfigure: function () {
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
events: ["close"]
|
||||
};
|
||||
|
||||
eventSource(WorkerClient.prototype);
|
||||
|
||||
module.exports = WorkerClient;
|
|
@ -14,7 +14,7 @@
|
|||
window.onload = function () {
|
||||
const {require} = Components.utils.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const Services = require("Services");
|
||||
const {DebuggerClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
|
||||
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
|
||||
|
|
|
@ -12,7 +12,7 @@ const defer = require("devtools/shared/defer");
|
|||
const Services = require("Services");
|
||||
const xpcInspector = require("xpcInspector");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
// We do not want to log packets by default, because in some tests,
|
||||
// we can be sending large amounts of data. The test harness has
|
||||
|
|
|
@ -32,7 +32,7 @@ const Services = require("Services");
|
|||
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
|
||||
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/main");
|
||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
// Convert an nsIScriptError 'flags' value into an appropriate string.
|
||||
function scriptErrorFlagsToKind(flags) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const EventEmitter = require("devtools/shared/old-event-emitter");
|
||||
const {LongStringClient} = require("devtools/shared/client/main");
|
||||
const LongStringClient = require("devtools/shared/client/long-string-client");
|
||||
|
||||
/**
|
||||
* A WebConsoleClient is used as a front end for the WebConsoleActor that is
|
||||
|
|
|
@ -16,7 +16,8 @@ const {console} = Cu.import("resource://gre/modules/Console.jsm", {});
|
|||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {Task} = require("devtools/shared/task");
|
||||
const {DebuggerServer} = require("devtools/server/main");
|
||||
const {DebuggerClient, ObjectClient} = require("devtools/shared/client/main");
|
||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||
const ObjectClient = require("devtools/shared/client/object-client");
|
||||
const Services = require("Services");
|
||||
|
||||
function initCommon() {
|
||||
|
|
|
@ -634,6 +634,7 @@ ConvertKeyframeSequence(JSContext* aCx,
|
|||
{
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
nsCSSParser parser(aDocument->CSSLoader());
|
||||
ErrorResult parseEasingResult;
|
||||
|
||||
for (;;) {
|
||||
bool done;
|
||||
|
@ -671,13 +672,6 @@ ConvertKeyframeSequence(JSContext* aCx,
|
|||
keyframe->mComposite.emplace(keyframeDict.mComposite.Value());
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
keyframe->mTimingFunction =
|
||||
TimingParams::ParseEasing(keyframeDict.mEasing, aDocument, rv);
|
||||
if (rv.MaybeSetPendingException(aCx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Look for additional property-values pairs on the object.
|
||||
nsTArray<PropertyValuesPair> propertyValuePairs;
|
||||
if (value.isObject()) {
|
||||
|
@ -690,6 +684,18 @@ ConvertKeyframeSequence(JSContext* aCx,
|
|||
}
|
||||
}
|
||||
|
||||
if (!parseEasingResult.Failed()) {
|
||||
keyframe->mTimingFunction =
|
||||
TimingParams::ParseEasing(keyframeDict.mEasing,
|
||||
aDocument,
|
||||
parseEasingResult);
|
||||
// Even if the above fails, we still need to continue reading off all the
|
||||
// properties since checking the validity of easing should be treated as
|
||||
// a separate step that happens *after* all the other processing in this
|
||||
// loop since (since it is never likely to be handled by WebIDL unlike the
|
||||
// rest of this loop).
|
||||
}
|
||||
|
||||
for (PropertyValuesPair& pair : propertyValuePairs) {
|
||||
MOZ_ASSERT(pair.mValues.Length() == 1);
|
||||
|
||||
|
@ -716,6 +722,11 @@ ConvertKeyframeSequence(JSContext* aCx,
|
|||
}
|
||||
}
|
||||
|
||||
// Throw any errors we encountered while parsing 'easing' properties.
|
||||
if (parseEasingResult.MaybeSetPendingException(aCx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1386,12 +1397,6 @@ GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
|
|||
composite.emplace(keyframeDict.mComposite.Value());
|
||||
}
|
||||
|
||||
Maybe<ComputedTimingFunction> easing =
|
||||
TimingParams::ParseEasing(keyframeDict.mEasing, aDocument, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all the property--value-list pairs off the object.
|
||||
JS::Rooted<JSObject*> object(aCx, &aValue.toObject());
|
||||
nsTArray<PropertyValuesPair> propertyValuesPairs;
|
||||
|
@ -1402,6 +1407,15 @@ GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
|
|||
return;
|
||||
}
|
||||
|
||||
// Parse the easing property. We need to do this after reading off the
|
||||
// property values since this is conceptually a separate step that happens
|
||||
// after the WebIDL-like processing.
|
||||
Maybe<ComputedTimingFunction> easing =
|
||||
TimingParams::ParseEasing(keyframeDict.mEasing, aDocument, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a set of keyframes for each property.
|
||||
nsCSSParser parser(aDocument->CSSLoader());
|
||||
nsClassHashtable<nsFloatHashKey, Keyframe> processedKeyframes;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче