diff --git a/devtools/client/debugger/new/debugger.js b/devtools/client/debugger/new/debugger.js index f52a3e380ab6..c1213180cb13 100644 --- a/devtools/client/debugger/new/debugger.js +++ b/devtools/client/debugger/new/debugger.js @@ -116,7 +116,8 @@ if ((0, _devtoolsConfig.isFirefoxPanel)()) { var threadClient = _ref.threadClient, tabTarget = _ref.tabTarget, debuggerClient = _ref.debuggerClient, - sourceMaps = _ref.sourceMaps; + sourceMaps = _ref.sourceMaps, + toolboxActions = _ref.toolboxActions; return (0, _client.onConnect)({ tab: { clientType: "firefox" }, @@ -126,7 +127,8 @@ if ((0, _devtoolsConfig.isFirefoxPanel)()) { debuggerClient } }, { - sourceMaps + services: { sourceMaps }, + toolboxActions }); }, destroy: () => { @@ -19309,14 +19311,31 @@ function evaluateExpression(expression, frameId) { return; } + const input = wrapExpression(expression.input); return dispatch({ type: "EVALUATE_EXPRESSION", input: expression.input, - [_promise.PROMISE]: client.evaluate(expression.input, { frameId }) + [_promise.PROMISE]: client.evaluate(input, { frameId }) }); }; } +function sanitizeInput(input) { + return input.replace(/\\/g, "\\\\").replace(/"/g, "\\$&"); +} + +function wrapExpression(input) { + return `eval(\` + try { + ${sanitizeInput(input)} + } catch (e) { + e.name + ": " + e.message + } + \`)`.trim(); +} + + + /***/ }), /* 253 */ /***/ (function(module, exports, __webpack_require__) { @@ -19596,6 +19615,7 @@ var checkPendingBreakpoints = (() => { exports.newSource = newSource; exports.newSources = newSources; exports.selectSourceURL = selectSourceURL; +exports.openLink = openLink; exports.selectSource = selectSource; exports.jumpToMappedLocation = jumpToMappedLocation; exports.addTab = addTab; @@ -19738,6 +19758,12 @@ function loadSourceMap(generatedSource) { })(); } +function openLink(url) { + return async function({ openLink }) { + openLink(url); + }; +} + /** * Deterministically select a source that has a given URL. This will * work regardless of the connection status or if the source exists @@ -27885,7 +27911,8 @@ class Expressions extends _react.PureComponent { renderExpression(expression) { var _props3 = this.props, loadObjectProperties = _props3.loadObjectProperties, - loadedObjects = _props3.loadedObjects; + loadedObjects = _props3.loadedObjects, + openLink = _props3.openLink; var editing = this.state.editing; var input = expression.input, updating = expression.updating; @@ -27929,7 +27956,8 @@ class Expressions extends _react.PureComponent { loadObjectProperties: loadObjectProperties // TODO: See https://github.com/devtools-html/debugger.html/issues/3555. , getObjectEntries: actor => {}, - loadObjectEntries: grip => {} + loadObjectEntries: grip => {}, + openLink: openLink }), _react2.default.createElement( "div", @@ -28701,7 +28729,8 @@ class Scopes extends _react.PureComponent { var _props2 = this.props, pauseInfo = _props2.pauseInfo, loadObjectProperties = _props2.loadObjectProperties, - loadedObjects = _props2.loadedObjects; + loadedObjects = _props2.loadedObjects, + openLink = _props2.openLink; var scopes = this.state.scopes; @@ -28719,7 +28748,8 @@ class Scopes extends _react.PureComponent { dimTopLevelWindow: true // TODO: See https://github.com/devtools-html/debugger.html/issues/3555. , getObjectEntries: actor => {}, - loadObjectEntries: grip => {} + loadObjectEntries: grip => {}, + openLink: openLink }) ); } @@ -29230,7 +29260,8 @@ function getKey(action) { } function getKeyForOS(os, action) { - return KEYS[os][action]; + var osActions = KEYS[os] || KEYS.Linux; + return osActions[action]; } function formatKey(action) { @@ -30731,17 +30762,19 @@ class Popup extends _react.Component { } renderSimplePreview(value) { + var openLink = this.props.openLink; return _react2.default.createElement( "div", { className: "preview-popup" }, - Rep({ object: value, mode: MODE.LONG }) + Rep({ object: value, mode: MODE.LONG, openLink: openLink }) ); } renderObjectInspector(root) { var _props2 = this.props, loadObjectProperties = _props2.loadObjectProperties, - loadedObjects = _props2.loadedObjects; + loadedObjects = _props2.loadedObjects, + openLink = _props2.openLink; var getObjectProperties = id => loadedObjects[id]; @@ -30760,7 +30793,8 @@ class Popup extends _react.Component { loadObjectProperties: loadObjectProperties // TODO: See https://github.com/devtools-html/debugger.html/issues/3555. , getObjectEntries: actor => {}, - loadObjectEntries: grip => {} + loadObjectEntries: grip => {}, + openLink: openLink }); } @@ -32129,16 +32163,18 @@ Object.defineProperty(exports, "__esModule", { exports.onConnect = undefined; var onConnect = (() => { - var _ref = _asyncToGenerator(function* (connection, services) { + var _ref = _asyncToGenerator(function* (connection, options) { // NOTE: the landing page does not connect to a JS process if (!connection) { return; } + var services = options.services; + var toolboxActions = options.toolboxActions; var client = getClient(connection); var commands = client.clientCommands; - var _bootstrapStore = (0, _bootstrap.bootstrapStore)(commands, services), + var _bootstrapStore = (0, _bootstrap.bootstrapStore)(commands, options), store = _bootstrapStore.store, actions = _bootstrapStore.actions, selectors = _bootstrapStore.selectors; @@ -33217,12 +33253,14 @@ var _prefs = __webpack_require__(226); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function bootstrapStore(client, services) { +function bootstrapStore(client, options) { + var services = options.services; + var toolboxActions = options.toolboxActions; var createStore = (0, _createStore2.default)({ log: (0, _devtoolsConfig.getValue)("logging.actions"), timing: (0, _devtoolsConfig.getValue)("performance.actions"), makeThunkArgs: (args, state) => { - return Object.assign({}, args, { client }, services); + return Object.assign({}, args, { client }, services, toolboxActions); } }); diff --git a/devtools/client/debugger/new/panel.js b/devtools/client/debugger/new/panel.js index 2ae88ed4069f..5e369944c28c 100644 --- a/devtools/client/debugger/new/panel.js +++ b/devtools/client/debugger/new/panel.js @@ -30,8 +30,12 @@ DebuggerPanel.prototype = { threadClient: this.toolbox.threadClient, tabTarget: this.toolbox.target, debuggerClient: this.toolbox.target.client, - sourceMaps: this.toolbox.sourceMapService - }); + sourceMaps: this.toolbox.sourceMapService, + // Open a link in a new browser tab. + toolboxActions: { + openLink: this.openLink.bind(this) + } + }) this._actions = actions; this._store = store; @@ -54,6 +58,25 @@ DebuggerPanel.prototype = { return this._store.getState(); }, + openLink: function(url) { + const parentDoc = this.toolbox.doc; + if (!parentDoc) { + return; + } + + const win = parentDoc.querySelector("window"); + if (!win) { + return; + } + + const top = win.ownerDocument.defaultView.top; + if (!top || typeof top.openUILinkIn !== "function") { + return; + } + + top.openUILinkIn(url, "tab"); + }, + getFrames: function() { let frames = this._selectors.getFrames(this._getState()); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg-expressions.js b/devtools/client/debugger/new/test/mochitest/browser_dbg-expressions.js index 6a3d5252080b..1e6e4d207a5b 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg-expressions.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-expressions.js @@ -61,7 +61,7 @@ add_task(async function() { await addExpression(dbg, "f"); is(getLabel(dbg, 1), "f"); - is(getValue(dbg, 1), "(unavailable)"); + is(getValue(dbg, 1), `"ReferenceError: f is not defined"`); await editExpression(dbg, "oo"); is(getLabel(dbg, 1), "foo()");