Bug 1316413 - Update new debugger frontend r=me

This commit is contained in:
James Long 2016-11-10 23:47:23 -05:00
parent 573808d53f
commit 2b79998809
20 changed files with 20435 additions and 1581 deletions

File diff suppressed because it is too large Load Diff

View File

@ -46,8 +46,8 @@ var Debugger =
/***/ 0:
/***/ function(module, exports, __webpack_require__) {
var prettyFast = __webpack_require__(453);
var assert = __webpack_require__(245);
var prettyFast = __webpack_require__(460);
var assert = __webpack_require__(247);
function prettyPrint(_ref) {
var url = _ref.url;
@ -112,7 +112,7 @@ var Debugger =
/***/ },
/***/ 245:
/***/ 247:
/***/ function(module, exports) {
function assert(condition, message) {
@ -125,7 +125,7 @@ var Debugger =
/***/ },
/***/ 453:
/***/ 460:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
@ -147,8 +147,8 @@ var Debugger =
}(this, function () {
"use strict";
var acorn = this.acorn || __webpack_require__(454);
var sourceMap = this.sourceMap || __webpack_require__(455);
var acorn = this.acorn || __webpack_require__(461);
var sourceMap = this.sourceMap || __webpack_require__(462);
var SourceNode = sourceMap.SourceNode;
// If any of these tokens are seen before a "[" token, we know that "[" token
@ -1007,7 +1007,7 @@ var Debugger =
/***/ },
/***/ 454:
/***/ 461:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Acorn is a tiny, fast JavaScript parser written in JavaScript.
@ -3667,7 +3667,7 @@ var Debugger =
/***/ },
/***/ 455:
/***/ 462:
/***/ function(module, exports, __webpack_require__) {
/*
@ -3675,14 +3675,14 @@ var Debugger =
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = __webpack_require__(456).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(462).SourceMapConsumer;
exports.SourceNode = __webpack_require__(464).SourceNode;
exports.SourceMapGenerator = __webpack_require__(463).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(469).SourceMapConsumer;
exports.SourceNode = __webpack_require__(471).SourceNode;
/***/ },
/***/ 456:
/***/ 463:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3696,10 +3696,10 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var base64VLQ = __webpack_require__(457);
var util = __webpack_require__(459);
var ArraySet = __webpack_require__(460).ArraySet;
var MappingList = __webpack_require__(461).MappingList;
var base64VLQ = __webpack_require__(464);
var util = __webpack_require__(466);
var ArraySet = __webpack_require__(467).ArraySet;
var MappingList = __webpack_require__(468).MappingList;
/**
* An instance of the SourceMapGenerator represents a source map which is
@ -4089,7 +4089,7 @@ var Debugger =
/***/ },
/***/ 457:
/***/ 464:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4133,7 +4133,7 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var base64 = __webpack_require__(458);
var base64 = __webpack_require__(465);
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
@ -4238,7 +4238,7 @@ var Debugger =
/***/ },
/***/ 458:
/***/ 465:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4287,7 +4287,7 @@ var Debugger =
/***/ },
/***/ 459:
/***/ 466:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4613,7 +4613,7 @@ var Debugger =
/***/ },
/***/ 460:
/***/ 467:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4627,7 +4627,7 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var util = __webpack_require__(459);
var util = __webpack_require__(466);
/**
* A data structure which is a combination of an array and a set. Adding a new
@ -4717,7 +4717,7 @@ var Debugger =
/***/ },
/***/ 461:
/***/ 468:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4731,7 +4731,7 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var util = __webpack_require__(459);
var util = __webpack_require__(466);
/**
* Determine whether mappingB is after mappingA with respect to generated
@ -4810,7 +4810,7 @@ var Debugger =
/***/ },
/***/ 462:
/***/ 469:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4824,10 +4824,10 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var util = __webpack_require__(459);
var binarySearch = __webpack_require__(463);
var ArraySet = __webpack_require__(460).ArraySet;
var base64VLQ = __webpack_require__(457);
var util = __webpack_require__(466);
var binarySearch = __webpack_require__(470);
var ArraySet = __webpack_require__(467).ArraySet;
var base64VLQ = __webpack_require__(464);
/**
* A SourceMapConsumer instance represents a parsed source map which we can
@ -5392,7 +5392,7 @@ var Debugger =
/***/ },
/***/ 463:
/***/ 470:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -5479,7 +5479,7 @@ var Debugger =
/***/ },
/***/ 464:
/***/ 471:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -5493,8 +5493,8 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var SourceMapGenerator = __webpack_require__(456).SourceMapGenerator;
var util = __webpack_require__(459);
var SourceMapGenerator = __webpack_require__(463).SourceMapGenerator;
var util = __webpack_require__(466);
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).

View File

@ -164,7 +164,7 @@ var Debugger =
return {
text,
contentType: isJavaScript(originalSource.url) ? "text/javascript" : "text/plain"
contentType: isJavaScript(originalSource.url || "") ? "text/javascript" : "text/plain"
};
});
@ -175,27 +175,36 @@ var Debugger =
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
var networkRequest = __webpack_require__(205);
var URL = __webpack_require__(289);
var path = __webpack_require__(276);
/**
* Source Map Worker
* @module utils/source-map-worker
*/
var _require = __webpack_require__(465);
var networkRequest = __webpack_require__(207);
var SourceMapConsumer = _require.SourceMapConsumer;
var SourceMapGenerator = _require.SourceMapGenerator;
var _require = __webpack_require__(293);
var _require2 = __webpack_require__(275);
var parse = _require.parse;
var isJavaScript = _require2.isJavaScript;
var path = __webpack_require__(278);
var assert = __webpack_require__(245);
var _require2 = __webpack_require__(472);
var _require3 = __webpack_require__(263);
var SourceMapConsumer = _require2.SourceMapConsumer;
var SourceMapGenerator = _require2.SourceMapGenerator;
var originalToGeneratedId = _require3.originalToGeneratedId;
var generatedToOriginalId = _require3.generatedToOriginalId;
var isGeneratedId = _require3.isGeneratedId;
var isOriginalId = _require3.isOriginalId;
var _require3 = __webpack_require__(277);
var isJavaScript = _require3.isJavaScript;
var assert = __webpack_require__(247);
var _require4 = __webpack_require__(265);
var originalToGeneratedId = _require4.originalToGeneratedId;
var generatedToOriginalId = _require4.generatedToOriginalId;
var isGeneratedId = _require4.isGeneratedId;
var isOriginalId = _require4.isOriginalId;
var sourceMapRequests = new Map();
@ -210,24 +219,36 @@ var Debugger =
}
function _resolveSourceMapURL(source) {
if (path.isURL(source.sourceMapURL) || !source.url) {
var _source$url = source.url;
var url = _source$url === undefined ? "" : _source$url;
var _source$sourceMapURL = source.sourceMapURL;
var sourceMapURL = _source$sourceMapURL === undefined ? "" : _source$sourceMapURL;
if (path.isURL(sourceMapURL) || url == "") {
// If it's already a full URL or the source doesn't have a URL,
// don't resolve anything.
return source.sourceMapURL;
} else if (path.isAbsolute(source.sourceMapURL)) {
return sourceMapURL;
} else if (path.isAbsolute(sourceMapURL)) {
// If it's an absolute path, it should be resolved relative to the
// host of the source.
var urlObj = URL.parse(source.url);
var base = urlObj.protocol + "//" + urlObj.host;
return base + source.sourceMapURL;
var _parse = parse(url);
var _parse$protocol = _parse.protocol;
var protocol = _parse$protocol === undefined ? "" : _parse$protocol;
var _parse$host = _parse.host;
var host = _parse$host === undefined ? "" : _parse$host;
return `${ protocol }//${ host }${ sourceMapURL }`;
}
// Otherwise, it's a relative path and should be resolved relative
// to the source.
return path.dirname(source.url) + "/" + source.sourceMapURL;
return path.dirname(url) + "/" + sourceMapURL;
}
/**
* Sets the source map's sourceRoot to be relative to the source map url.
* @memberof utils/source-map-worker
* @static
*/
function _setSourceMapRoot(sourceMap, absSourceMapURL, source) {
// No need to do this fiddling if we won't be fetching any sources over the
@ -326,7 +347,7 @@ var Debugger =
/***/ },
/***/ 205:
/***/ 207:
/***/ function(module, exports) {
function networkRequest(url, opts) {
@ -361,7 +382,7 @@ var Debugger =
/***/ },
/***/ 242:
/***/ 244:
/***/ function(module, exports, __webpack_require__) {
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
@ -374,8 +395,17 @@ var Debugger =
* 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/. */
var co = __webpack_require__(243);
/**
* Utils for utils, by utils
* @module utils/utils
*/
var co = __webpack_require__(245);
/**
* @memberof utils/utils
* @static
*/
function asPaused(client, func) {
if (client.state != "paused") {
return co(function* () {
@ -398,10 +428,18 @@ var Debugger =
return func();
}
/**
* @memberof utils/utils
* @static
*/
function handleError(err) {
console.log("ERROR: ", err);
}
/**
* @memberof utils/utils
* @static
*/
function promisify(context, method) {
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
@ -419,6 +457,10 @@ var Debugger =
});
}
/**
* @memberof utils/utils
* @static
*/
function truncateStr(str, size) {
if (str.length > size) {
return str.slice(0, size) + "...";
@ -426,6 +468,10 @@ var Debugger =
return str;
}
/**
* @memberof utils/utils
* @static
*/
function endTruncateStr(str, size) {
if (str.length > size) {
return "..." + str.slice(str.length - size);
@ -434,6 +480,10 @@ var Debugger =
}
var msgId = 1;
/**
* @memberof utils/utils
* @static
*/
function workerTask(worker, method) {
return function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
@ -473,6 +523,8 @@ var Debugger =
* @param Array b
* @returns Array
* The combined array, in the form [a1, b1, a2, b2, ...]
* @memberof utils/utils
* @static
*/
function zip(a, b) {
if (!b) {
@ -493,13 +545,18 @@ var Debugger =
* pairs of the object. `{ foo: 1, bar: 2}` would become
* `[[foo, 1], [bar 2]]` (order not guaranteed);
*
* @param object obj
* @returns array
* @memberof utils/utils
* @static
*/
function entries(obj) {
return Object.keys(obj).map(k => [k, obj[k]]);
}
/**
* @memberof utils/utils
* @static
*/
function mapObject(obj, iteratee) {
return toObject(entries(obj).map((_ref2) => {
var _ref3 = _slicedToArray(_ref2, 2);
@ -514,6 +571,8 @@ var Debugger =
/**
* Takes an array of 2-element arrays as key/values pairs and
* constructs an object using them.
* @memberof utils/utils
* @static
*/
function toObject(arr) {
var obj = {};
@ -531,6 +590,8 @@ var Debugger =
*
* @param ...function funcs
* @returns function
* @memberof utils/utils
* @static
*/
function compose() {
for (var _len3 = arguments.length, funcs = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
@ -548,10 +609,18 @@ var Debugger =
};
}
/**
* @memberof utils/utils
* @static
*/
function updateObj(obj, fields) {
return Object.assign({}, obj, fields);
}
/**
* @memberof utils/utils
* @static
*/
function throttle(func, ms) {
var timeout = void 0,
_this = void 0;
@ -588,7 +657,7 @@ var Debugger =
/***/ },
/***/ 243:
/***/ 245:
/***/ function(module, exports) {
@ -832,7 +901,7 @@ var Debugger =
/***/ },
/***/ 245:
/***/ 247:
/***/ function(module, exports) {
function assert(condition, message) {
@ -845,14 +914,14 @@ var Debugger =
/***/ },
/***/ 263:
/***/ 265:
/***/ function(module, exports, __webpack_require__) {
var md5 = __webpack_require__(264);
var md5 = __webpack_require__(266);
function originalToGeneratedId(originalId) {
var match = originalId.match(/(.*)\/originalSource/);
return match ? match[1] : null;
return match ? match[1] : "";
}
function generatedToOriginalId(generatedId, url) {
@ -860,7 +929,7 @@ var Debugger =
}
function isOriginalId(id) {
return id.match(/\/originalSource/);
return !!id.match(/\/originalSource/);
}
function isGeneratedId(id) {
@ -873,14 +942,14 @@ var Debugger =
/***/ },
/***/ 264:
/***/ 266:
/***/ function(module, exports, __webpack_require__) {
(function(){
var crypt = __webpack_require__(265),
utf8 = __webpack_require__(266).utf8,
isBuffer = __webpack_require__(267),
bin = __webpack_require__(266).bin,
var crypt = __webpack_require__(267),
utf8 = __webpack_require__(268).utf8,
isBuffer = __webpack_require__(269),
bin = __webpack_require__(268).bin,
// The core
md5 = function (message, options) {
@ -1040,7 +1109,7 @@ var Debugger =
/***/ },
/***/ 265:
/***/ 267:
/***/ function(module, exports) {
(function() {
@ -1143,7 +1212,7 @@ var Debugger =
/***/ },
/***/ 266:
/***/ 268:
/***/ function(module, exports) {
var charenc = {
@ -1183,7 +1252,7 @@ var Debugger =
/***/ },
/***/ 267:
/***/ 269:
/***/ function(module, exports) {
/*!
@ -1211,20 +1280,30 @@ var Debugger =
/***/ },
/***/ 275:
/***/ 277:
/***/ function(module, exports, __webpack_require__) {
var _require = __webpack_require__(242);
/**
* Utils for working with Source URLs
* @module utils/source
*/
var _require = __webpack_require__(244);
var endTruncateStr = _require.endTruncateStr;
var _require2 = __webpack_require__(276);
var _require2 = __webpack_require__(278);
var basename = _require2.basename;
/**
* Trims the query part or reference identifier of a url string, if necessary.
*
* @memberof utils/source
* @static
*/
function trimUrlQuery(url) {
var length = url.length;
@ -1242,6 +1321,9 @@ var Debugger =
*
* @return boolean
* True if the source is likely javascript.
*
* @memberof utils/source
* @static
*/
function isJavaScript(url) {
var contentType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
@ -1249,6 +1331,10 @@ var Debugger =
return url && /\.(jsm|js)?$/.test(trimUrlQuery(url)) || contentType.includes("javascript");
}
/**
* @memberof utils/source
* @static
*/
function isPretty(source) {
return source.url ? /formatted$/.test(source.url) : false;
}
@ -1256,6 +1342,9 @@ var Debugger =
/**
* Show a source url's filename.
* If the source does not have a url, use the source id.
*
* @memberof utils/source
* @static
*/
function getFilename(source) {
var url = source.url;
@ -1266,7 +1355,7 @@ var Debugger =
return `SOURCE${ sourceId }`;
}
var name = basename(source.url);
var name = basename(source.url || "") || "(index)";
return endTruncateStr(name, 50);
}
@ -1278,7 +1367,7 @@ var Debugger =
/***/ },
/***/ 276:
/***/ 278:
/***/ function(module, exports) {
function basename(path) {
@ -1298,13 +1387,17 @@ var Debugger =
return str[0] === "/";
}
function join(base, dir) {
return base + "/" + dir;
}
module.exports = {
basename, dirname, isURL, isAbsolute
basename, dirname, isURL, isAbsolute, join
};
/***/ },
/***/ 289:
/***/ 293:
/***/ function(module, exports, __webpack_require__) {
// Copyright Joyent, Inc. and other Node contributors.
@ -1328,7 +1421,7 @@ var Debugger =
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var punycode = __webpack_require__(290);
var punycode = __webpack_require__(294);
exports.parse = urlParse;
exports.resolve = urlResolve;
@ -1400,7 +1493,7 @@ var Debugger =
'gopher:': true,
'file:': true
},
querystring = __webpack_require__(291);
querystring = __webpack_require__(295);
function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url && isObject(url) && url instanceof Url) return url;
@ -2018,7 +2111,7 @@ var Debugger =
/***/ },
/***/ 290:
/***/ 294:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/punycode v1.3.2 by @mathias */
@ -2554,18 +2647,18 @@ var Debugger =
/***/ },
/***/ 291:
/***/ 295:
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.decode = exports.parse = __webpack_require__(292);
exports.encode = exports.stringify = __webpack_require__(293);
exports.decode = exports.parse = __webpack_require__(296);
exports.encode = exports.stringify = __webpack_require__(297);
/***/ },
/***/ 292:
/***/ 296:
/***/ function(module, exports) {
// Copyright Joyent, Inc. and other Node contributors.
@ -2652,7 +2745,7 @@ var Debugger =
/***/ },
/***/ 293:
/***/ 297:
/***/ function(module, exports) {
// Copyright Joyent, Inc. and other Node contributors.
@ -2723,7 +2816,7 @@ var Debugger =
/***/ },
/***/ 465:
/***/ 472:
/***/ function(module, exports, __webpack_require__) {
/*
@ -2731,14 +2824,14 @@ var Debugger =
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = __webpack_require__(466).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(472).SourceMapConsumer;
exports.SourceNode = __webpack_require__(475).SourceNode;
exports.SourceMapGenerator = __webpack_require__(473).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(479).SourceMapConsumer;
exports.SourceNode = __webpack_require__(482).SourceNode;
/***/ },
/***/ 466:
/***/ 473:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -2748,10 +2841,10 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var base64VLQ = __webpack_require__(467);
var util = __webpack_require__(469);
var ArraySet = __webpack_require__(470).ArraySet;
var MappingList = __webpack_require__(471).MappingList;
var base64VLQ = __webpack_require__(474);
var util = __webpack_require__(476);
var ArraySet = __webpack_require__(477).ArraySet;
var MappingList = __webpack_require__(478).MappingList;
/**
* An instance of the SourceMapGenerator represents a source map which is
@ -3149,7 +3242,7 @@ var Debugger =
/***/ },
/***/ 467:
/***/ 474:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3189,7 +3282,7 @@ var Debugger =
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var base64 = __webpack_require__(468);
var base64 = __webpack_require__(475);
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
@ -3296,7 +3389,7 @@ var Debugger =
/***/ },
/***/ 468:
/***/ 475:
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3370,7 +3463,7 @@ var Debugger =
/***/ },
/***/ 469:
/***/ 476:
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3794,7 +3887,7 @@ var Debugger =
/***/ },
/***/ 470:
/***/ 477:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3804,7 +3897,7 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(469);
var util = __webpack_require__(476);
var has = Object.prototype.hasOwnProperty;
/**
@ -3905,7 +3998,7 @@ var Debugger =
/***/ },
/***/ 471:
/***/ 478:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3915,7 +4008,7 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(469);
var util = __webpack_require__(476);
/**
* Determine whether mappingB is after mappingA with respect to generated
@ -3991,7 +4084,7 @@ var Debugger =
/***/ },
/***/ 472:
/***/ 479:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4001,11 +4094,11 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(469);
var binarySearch = __webpack_require__(473);
var ArraySet = __webpack_require__(470).ArraySet;
var base64VLQ = __webpack_require__(467);
var quickSort = __webpack_require__(474).quickSort;
var util = __webpack_require__(476);
var binarySearch = __webpack_require__(480);
var ArraySet = __webpack_require__(477).ArraySet;
var base64VLQ = __webpack_require__(474);
var quickSort = __webpack_require__(481).quickSort;
function SourceMapConsumer(aSourceMap) {
var sourceMap = aSourceMap;
@ -5080,7 +5173,7 @@ var Debugger =
/***/ },
/***/ 473:
/***/ 480:
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -5198,7 +5291,7 @@ var Debugger =
/***/ },
/***/ 474:
/***/ 481:
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -5319,7 +5412,7 @@ var Debugger =
/***/ },
/***/ 475:
/***/ 482:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -5329,8 +5422,8 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var SourceMapGenerator = __webpack_require__(466).SourceMapGenerator;
var util = __webpack_require__(469);
var SourceMapGenerator = __webpack_require__(473).SourceMapGenerator;
var util = __webpack_require__(476);
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).

View File

@ -50,14 +50,14 @@ body {
.landing-page .sidebar {
display: flex;
background-color: var(--theme-content-color1);
background-color: var(--theme-tab-toolbar-background);
width: 200px;
height: 100%;
flex-direction: column;
}
.landing-page .sidebar h1 {
color: white;
color: var(--theme-body-color);
font-size: 24px;
margin: 0;
line-height: 30px;
@ -77,16 +77,21 @@ body {
}
.landing-page .sidebar li.selected {
background: #1f2327;
background: var(--theme-search-overlays-semitransparent);
transition: all 0.25s ease;
}
.landing-page .sidebar li:hover {
background: #1f2327;
background: var(--theme-selection-background);
cursor: pointer;
}
.landing-page .sidebar li a {
color: var(--theme-comment-alt);
color: var(--theme-body-color);
}
.landing-page .sidebar li:hover a {
color: var(--theme-selection-color);
}
.landing-page .panel {
@ -100,9 +105,8 @@ body {
.landing-page .panel .title {
margin: 20px 40px;
width: calc(100% - 80px);
padding: 0 20px;
font-size: 16px;
border-bottom: 1px solid #cccccc;
border-bottom: 1px solid var(--theme-splitter-color);
height: 54px;
}
@ -177,6 +181,12 @@ body {
:root.theme-light,
:root .theme-light {
--theme-search-overlays-semitransparent: rgba(221, 225, 228, 0.66);
--theme-faded-tab-color: #7e7e7e;
}
:root.theme-dark,
:root .theme-dark {
--theme-faded-tab-color: #6e7d8c;
}
* {
@ -256,6 +266,49 @@ body {
font-weight: lighter;
z-index: 100;
}
menupopup {
position: fixed;
z-index: 10000;
background: white;
border: 1px solid #cccccc;
padding: 5px 0;
background: #f2f2f2;
border-radius: 5px;
color: #585858;
box-shadow: 0 0 4px 0 rgba(190, 190, 190, 0.8);
min-width: 130px;
}
menuitem {
display: block;
padding: 0 20px;
line-height: 20px;
font-weight: 500;
font-size: 13px;
}
menuitem:hover {
background: #3780fb;
color: white;
cursor: pointer;
}
menuseparator {
border-bottom: 1px solid #cacdd3;
width: 100%;
height: 5px;
display: block;
margin-bottom: 5px;
}
#contextmenu-mask.show {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
}
/* vim:set ts=2 sw=2 sts=2 et: */
/* 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
@ -546,6 +599,14 @@ body {
flex: 1;
}
.searchinput-container {
display: flex;
}
.searchinput-container .close-btn-big {
border-bottom: 1px solid var(--theme-splitter-color);
}
.autocomplete {
width: 100%;
}
@ -555,6 +616,10 @@ body {
user-select: none;
}
.autocomplete .results-summary {
margin: 10px;
}
.autocomplete ul {
list-style: none;
width: 100%;
@ -582,11 +647,13 @@ body {
.autocomplete li .title {
line-height: 1.5em;
word-break: break-all;
}
.autocomplete li .subtitle {
line-height: 1.5em;
color: grey;
word-break: break-all;
}
.autocomplete input {
@ -613,20 +680,6 @@ body {
left: 10px;
}
.autocomplete .close-btn {
position: absolute;
top: 12px;
right: 10px;
}
.autocomplete .close-btn .close svg {
width: 12px;
}
.autocomplete .close-btn .close path {
fill: var(--theme-splitter-color);
}
.autocomplete.focused .magnifying-glass path,
.autocomplete.focused .magnifying-glass ellipse {
stroke: var(--theme-highlight-blue);
@ -661,6 +714,7 @@ body {
}
.close-btn .close {
cursor: pointer;
width: 12px;
height: 12px;
padding: 2px;
@ -682,6 +736,41 @@ body {
.close-btn .close:hover path {
fill: white;
}
.close-btn-big {
padding: 13px;
width: 40px;
height: 40px;
}
.close-btn-big path {
fill: var(--theme-body-color);
}
.close-btn-big .close {
cursor: pointer;
display: inline-block;
padding: 2px;
text-align: center;
transition: all 0.25s easeinout;
line-height: 100%;
width: 16px;
height: 16px;
}
.close-btn-big .close svg {
width: 9px;
height: 9px;
}
.close-btn-big .close:hover {
background: var(--theme-selection-background);
border-radius: 2px;
}
.close-btn-big .close:hover path {
fill: white;
}
.tree {
-webkit-user-select: none;
-moz-user-select: none;
@ -936,13 +1025,14 @@ html[dir="rtl"] .command-bar > span {
display: flex;
}
.search-bar svg {
width: 16px;
}
.search-bar i {
display: block;
padding: 13px 0 0 13px;
width: 40px;
}
.search-bar i svg {
width: 16px;
}
.search-bar input {
@ -952,14 +1042,17 @@ html[dir="rtl"] .command-bar > span {
background-color: var(--theme-body-background);
color: var(--theme-comment);
width: calc(100% - 38px);
padding-left: 10px;
display: flex;
padding-right: 100px;
flex: 1;
}
.search-bar .magnifying-glass {
background-color: var(--theme-body-background);
width: 40px;
}
.search-bar .magnifying-glass path,
.search-bar .magnifying-glass ellipse {
stroke: var(--theme-splitter-color);
}
.search-bar input::placeholder {
@ -1200,9 +1293,16 @@ html[dir="rtl"] .editor-mount {
.expression-container {
border: 1px;
padding: 2px;
padding: 5px 2px 5px 5px;
margin: 1px;
width: 100%;
color: var(--theme-body-color) !important;
background-color: var(--theme-tab-toolbar-background);
}
.expression-container:hover {
background-color: var(--theme-selection-background);
color: var(--theme-body-background) !important;
}
.expression-output-container .close-btn {
@ -1215,7 +1315,6 @@ html[dir="rtl"] .editor-mount {
}
.expression-input {
color: var(--theme-content-color1);
cursor: pointer;
max-width: 50%;
}
@ -1225,6 +1324,10 @@ html[dir="rtl"] .editor-mount {
color: var(--theme-content-color2);
max-width: 50% !important;
}
.expression-error {
color: var(--theme-highlight-red);
}
.arrow svg {
fill: var(--theme-splitter-color);
margin-top: 3px;
@ -1286,6 +1389,12 @@ html .arrow.expanded svg {
overflow: hidden;
}
/* Style the focused call frame like so:
.frames ul li:focus {
border: 3px solid red;
}
*/
.frames ul li * {
-moz-user-select: none;
user-select: none;
@ -1311,7 +1420,7 @@ html .arrow.expanded svg {
.frames ul li.selected,
.frames ul li.selected .location {
background-color: var(--theme-selection-background);
color: var(--theme-body-background);
color: white;
}
.show-more {
@ -1323,7 +1432,7 @@ html .arrow.expanded svg {
}
.show-more:hover {
background-color: var(--theme-selection-color);
background-color: var(--theme-search-overlays-semitransparent);
}
.accordion {
background-color: var(--theme-body-background);
@ -1347,7 +1456,7 @@ html .arrow.expanded svg {
}
.accordion ._header:hover {
background-color: var(--theme-selection-color);
background-color: var(--theme-search-overlays-semitransparent);
}
.accordion ._header:hover svg {
@ -1441,6 +1550,8 @@ html[dir="rtl"] .command-bar .stepOut {
font-style: italic;
text-align: center;
padding: 0.5em;
-moz-user-select: none;
user-select: none;
}
.toggleBreakpoints.breakpoints-disabled path {
@ -1558,15 +1669,6 @@ html[dir="rtl"] .source-tab .close-btn {
.source-tab:hover .close {
display: block;
}
.source-header .subsettings {
position: absolute;
right: 12px;
top: 5px;
width: 12px;
height: 12px;
color: var(--theme-body-color);
}
.dropdown {
background: var(--theme-body-background);
border: 1px solid var(--theme-splitter-color);
@ -1579,6 +1681,15 @@ html[dir="rtl"] .source-tab .close-btn {
z-index: 1000;
}
.dropdown-button {
position: absolute;
right: 12px;
top: 5px;
font-size: 16px;
color: var(--theme-body-color);
cursor: pointer;
}
.dropdown li {
transition: all 0.25s ease;
padding: 2px 10px 10px 5px;

View File

@ -42,6 +42,7 @@
"waitForDispatch": false,
"waitForThreadEvents": false,
"waitForState": false,
"waitForElement": false,
"waitForPaused": false,
"waitForSources": false,
"isPaused": false,
@ -52,6 +53,7 @@
"invokeInTab": false,
"findSource": false,
"findElement": false,
"findElementWithSelector": false,
"findAllElements": false,
"openNewTabAndToolbox": false,
"selectSource": false,
@ -67,8 +69,12 @@
"toggleScopes": false,
"isVisibleWithin": false,
"clickElement": false,
"rightClickElement": false,
"selectMenuItem": false,
"togglePauseOnExceptions": false,
"type": false,
"pressKey": false,
"EXAMPLE_URL": false
"EXAMPLE_URL": false,
"waitUntil": false
}
}

View File

@ -12,19 +12,23 @@ support-files =
examples/doc-script-switching.html
examples/doc-exceptions.html
examples/doc-iframes.html
examples/doc-frames.html
examples/doc-debugger-statements.html
examples/doc-minified.html
examples/doc-sourcemaps.html
examples/doc-sourcemap-bogus.html
examples/doc-sources.html
examples/bogus-map.js
examples/entry.js
examples/exceptions.js
examples/math.min.js
examples/opts.js
examples/long.js
examples/math.min.js
examples/nested/nested-source.js
examples/opts.js
examples/output.js
examples/simple1.js
examples/simple2.js
examples/frames.js
examples/script-switching-02.js
examples/script-switching-01.js
examples/times2.js
@ -32,6 +36,7 @@ support-files =
[browser_dbg-breaking.js]
[browser_dbg-breaking-from-console.js]
[browser_dbg-breakpoints.js]
[browser_dbg-breakpoints-cond.js]
[browser_dbg-call-stack.js]
[browser_dbg-scopes.js]
[browser_dbg-chrome-create.js]
@ -48,5 +53,8 @@ support-files =
[browser_dbg-navigation.js]
[browser_dbg-pretty-print.js]
[browser_dbg-pretty-print-paused.js]
[browser_dbg-searching.js]
skip-if = true
[browser_dbg-sourcemaps.js]
[browser_dbg-sourcemaps-bogus.js]
[browser_dbg-sources.js]

View File

@ -0,0 +1,50 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function findBreakpoint(dbg, url, line) {
const { selectors: { getBreakpoint }, getState } = dbg;
const source = findSource(dbg, url);
return getBreakpoint(getState(), { sourceId: source.id, line });
}
function setConditionalBreakpoint(dbg, index, condition) {
return Task.spawn(function* () {
rightClickElement(dbg, "gutter", index);
selectMenuItem(dbg, 2);
yield waitForElement(dbg, ".conditional-breakpoint-panel input");
findElementWithSelector(dbg, ".conditional-breakpoint-panel input").focus();
type(dbg, condition);
pressKey(dbg, "Enter");
});
}
add_task(function* () {
const dbg = yield initDebugger("doc-scripts.html");
yield selectSource(dbg, "simple2");
// Adding a conditional Breakpoint
yield setConditionalBreakpoint(dbg, 5, "1");
yield waitForDispatch(dbg, "ADD_BREAKPOINT");
let bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, "1", "breakpoint is created with the condition");
// Editing a conditional Breakpoint
yield setConditionalBreakpoint(dbg, 5, "2");
yield waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION");
bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, "12", "breakpoint is created with the condition");
// Removing a conditional breakpoint
clickElement(dbg, "gutter", 5);
yield waitForDispatch(dbg, "REMOVE_BREAKPOINT");
bp = findBreakpoint(dbg, "simple2", 5);
is(bp, null, "breakpoint was removed");
// Adding a condition to a breakpoint
clickElement(dbg, "gutter", 5);
yield waitForDispatch(dbg, "ADD_BREAKPOINT");
yield setConditionalBreakpoint(dbg, 5, "1");
bp = findBreakpoint(dbg, "simple2", 5);
is(bp.condition, "1", "breakpoint is created with the condition");
});

View File

@ -68,11 +68,21 @@ add_task(function* () {
yield enableBreakpoint(dbg, 2);
bp2 = findBreakpoint(dbg, "simple2", 5);
is(bp2.disabled, false, "second breakpoint is enabled");
});
// toggle all
add_task(function* () {
const dbg = yield initDebugger("doc-scripts.html");
// Create two breakpoints
yield selectSource(dbg, "simple2");
yield addBreakpoint(dbg, "simple2", 3);
yield addBreakpoint(dbg, "simple2", 5);
// Disable all of the breakpoints
yield toggleBreakpoints(dbg);
bp1 = findBreakpoint(dbg, "simple2", 3);
bp2 = findBreakpoint(dbg, "simple2", 5);
let bp1 = findBreakpoint(dbg, "simple2", 3);
let bp2 = findBreakpoint(dbg, "simple2", 5);
is(bp1.disabled, true, "first breakpoint is disabled");
is(bp2.disabled, true, "second breakpoint is disabled");

View File

@ -1,12 +1,9 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function findFrame(dbg, index) {
return findElement(dbg, "frame", index);
}
// checks to see if the frame is selected and the title is correct
function isFrameSelected(dbg, index, title) {
const $frame = findFrame(dbg, index);
const $frame = findElement(dbg, "frame", index);
const frame = dbg.selectors.getSelectedFrame(dbg.getState());
const elSelected = $frame.classList.contains("selected");
@ -15,16 +12,51 @@ function isFrameSelected(dbg, index, title) {
return elSelected && titleSelected;
}
function toggleButton(dbg) {
const callStackBody = findElement(dbg, "callStackBody");
return callStackBody.querySelector(".show-more");
}
add_task(function* () {
const dbg = yield initDebugger("doc-script-switching.html");
toggleCallStack(dbg);
const notPaused = findElement(dbg, "callStackBody").innerText;
is(notPaused, "Not Paused", "Not paused message is shown");
invokeInTab("firstCall");
yield waitForPaused(dbg);
ok(isFrameSelected(dbg, 1, "secondCall"), "the first frame is selected");
findFrame(dbg, 2).click();
clickElement(dbg, "frame", 2);
ok(isFrameSelected(dbg, 2, "firstCall"), "the second frame is selected");
let button = toggleButton(dbg);
ok(!button, "toggle button shouldn't be there");
});
add_task(function* () {
const dbg = yield initDebugger("doc-frames.html");
toggleCallStack(dbg);
invokeInTab("startRecursion");
yield waitForPaused(dbg);
ok(isFrameSelected(dbg, 1, "recurseA"), "the first frame is selected");
// check to make sure that the toggle button isn't there
let button = toggleButton(dbg);
let frames = findAllElements(dbg, "frames");
is(button.innerText, "Expand Rows", "toggle button should be expand");
is(frames.length, 7, "There should be at most seven frames");
button.click();
button = toggleButton(dbg);
frames = findAllElements(dbg, "frames");
is(button.innerText, "Collapse Rows", "toggle button should be collapse");
is(frames.length, 22, "All of the frames should be shown");
});

View File

@ -0,0 +1,28 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Testing source search
add_task(function* () {
const dbg = yield initDebugger("doc-script-switching.html");
pressKey(dbg, "sourceSearch");
yield waitForElement(dbg, "input");
findElementWithSelector(dbg, "input").focus();
type(dbg, "sw");
pressKey(dbg, "Enter");
yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT");
let source = dbg.selectors.getSelectedSource(dbg.getState());
ok(source.get("url").match(/switching-01/), "first source is selected");
// 2. arrow keys and check to see if source is selected
pressKey(dbg, "sourceSearch");
findElementWithSelector(dbg, "input").focus();
type(dbg, "sw");
pressKey(dbg, "Down");
pressKey(dbg, "Enter");
yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT");
source = dbg.selectors.getSelectedSource(dbg.getState());
ok(source.get("url").match(/switching-02/), "second source is selected");
});

View File

@ -0,0 +1,58 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that the source tree works.
function* waitForSourceCount(dbg, i) {
// We are forced to wait until the DOM nodes appear because the
// source tree batches its rendering.
yield waitUntil(() => {
return findAllElements(dbg, "sourceNodes").length === i;
});
}
add_task(function* () {
const dbg = yield initDebugger("doc-sources.html");
const { selectors: { getSelectedSource }, getState } = dbg;
// Expand nodes and make sure more sources appear.
is(findAllElements(dbg, "sourceNodes").length, 2);
clickElement(dbg, "sourceArrow", 2);
is(findAllElements(dbg, "sourceNodes").length, 7);
clickElement(dbg, "sourceArrow", 3);
is(findAllElements(dbg, "sourceNodes").length, 8);
// Select a source.
ok(!findElementWithSelector(dbg, ".sources-list .focused"),
"Source is not focused");
const selected = waitForDispatch(dbg, "SELECT_SOURCE");
clickElement(dbg, "sourceNode", 4);
yield selected;
ok(findElementWithSelector(dbg, ".sources-list .focused"),
"Source is focused");
ok(getSelectedSource(getState()).get("url").includes("nested-source.js"),
"The right source is selected");
// Make sure new sources appear in the list.
ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
const script = content.document.createElement("script");
script.src = "math.min.js";
content.document.body.appendChild(script);
});
yield waitForSourceCount(dbg, 9);
is(findElement(dbg, "sourceNode", 7).querySelector("span").innerText,
"math.min.js",
"The dynamic script exists");
// Make sure named eval sources appear in the list.
ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
content.eval("window.evaledFunc = function() {} //# sourceURL=evaled.js");
});
yield waitForSourceCount(dbg, 11);
is(findElement(dbg, "sourceNode", 2).querySelector("span").innerText,
"evaled.js",
"The eval script exists");
});

View File

@ -0,0 +1,17 @@
<html>
<head>
<title>Frames</title>
</head>
<body>
<script>
debugger;
// This inline script allows this HTML page to show up as a
// source. It also needs to introduce a new global variable so
// it's not immediately garbage collected.
function inline_script() { var x = 5; }
</script>
<script type="text/javascript" src="frames.js"></script>
</body>
</html>

View File

@ -0,0 +1,23 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Debugger test page</title>
</head>
<body>
<script src="simple1.js"></script>
<script src="simple2.js"></script>
<script src="long.js"></script>
<script>
// This inline script allows this HTML page to show up as a
// source. It also needs to introduce a new global variable so
// it's not immediately garbage collected.
function inline_script() { var x = 5; }
</script>
<script src="nested/nested-source.js"></script>
<script src="nested/deeper/deeper-source.js"></script>
</body>
</html>

View File

@ -0,0 +1,24 @@
function recurseA(i) {
if (i == 20) {
debugger;
return;
}
// down into the rabbit hole we go
return (i % 2) ? recurseA(++i) : recurseB(++i);
}
function recurseB(i) {
if (i == 20) {
debugger;
return;
}
// down into the rabbit hole we go
return (i % 2) ? recurseA(++i) : recurseB(++i);
}
window.startRecursion = function() {
return recurseA(0);
}

View File

@ -0,0 +1,3 @@
function computeSomething() {
return 1;
}

View File

@ -180,6 +180,10 @@ function waitForSources(dbg, ...sources) {
}));
}
function waitForElement(dbg, selector) {
return waitUntil(() => findElementWithSelector(dbg, selector))
}
/**
* Assert that the debugger is paused at the correct location.
*
@ -523,7 +527,13 @@ function invokeInTab(fnc) {
}
const isLinux = Services.appinfo.OS === "Linux";
const cmdOrCtrl = isLinux ? { ctrlKey: true } : { metaKey: true };
const keyMappings = {
sourceSearch: { code: "p", modifiers: cmdOrCtrl},
fileSearch: { code: "f", modifiers: cmdOrCtrl},
"Enter": { code: "VK_RETURN" },
"Up": { code: "VK_UP" },
"Down": { code: "VK_DOWN" },
pauseKey: { code: "VK_F8" },
resumeKey: { code: "VK_F8" },
stepOverKey: { code: "VK_F10" },
@ -542,6 +552,7 @@ const keyMappings = {
*/
function pressKey(dbg, keyName) {
let keyEvent = keyMappings[keyName];
const { code, modifiers } = keyEvent;
return EventUtils.synthesizeKey(
code,
@ -550,6 +561,12 @@ function pressKey(dbg, keyName) {
);
}
function type(dbg, string) {
string.split("").forEach(char => {
EventUtils.synthesizeKey(char, {}, dbg.win);
});
}
function isVisibleWithin(outerEl, innerEl) {
const innerRect = innerEl.getBoundingClientRect();
const outerRect = outerEl.getBoundingClientRect();
@ -559,11 +576,14 @@ function isVisibleWithin(outerEl, innerEl) {
const selectors = {
callStackHeader: ".call-stack-pane ._header",
callStackBody: ".call-stack-pane .pane",
scopesHeader: ".scopes-pane ._header",
breakpointItem: i => `.breakpoints-list .breakpoint:nth-child(${i})`,
scopeNode: i => `.scopes-list .tree-node:nth-child(${i}) .object-label`,
frame: index => `.frames ul li:nth-child(${index})`,
frame: i => `.frames ul li:nth-child(${i})`,
frames: ".frames ul li",
gutter: i => `.CodeMirror-code *:nth-child(${i}) .CodeMirror-linenumber`,
menuitem: i => `menupopup menuitem:nth-child(${i})`,
pauseOnExceptions: ".pause-exceptions",
breakpoint: ".CodeMirror-code > .new-breakpoint",
highlightLine: ".CodeMirror-code > .highlight-line",
@ -574,7 +594,10 @@ const selectors = {
stepIn: ".stepIn.active",
toggleBreakpoints: ".toggleBreakpoints",
prettyPrintButton: ".prettyPrint",
sourceFooter: ".source-footer"
sourceFooter: ".source-footer",
sourceNode: i => `.sources-list .tree-node:nth-child(${i})`,
sourceNodes: ".sources-list .tree-node",
sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`,
};
function getSelector(elementName, ...args) {
@ -592,6 +615,10 @@ function getSelector(elementName, ...args) {
function findElement(dbg, elementName, ...args) {
const selector = getSelector(elementName, ...args);
return findElementWithSelector(dbg, selector);
}
function findElementWithSelector(dbg, selector) {
return dbg.win.document.querySelector(selector);
}
@ -612,14 +639,34 @@ function findAllElements(dbg, elementName, ...args) {
*/
function clickElement(dbg, elementName, ...args) {
const selector = getSelector(elementName, ...args);
const doc = dbg.win.document;
return EventUtils.synthesizeMouseAtCenter(
doc.querySelector(selector),
findElementWithSelector(dbg, selector),
{},
dbg.win
);
}
function rightClickElement(dbg, elementName, ...args) {
const selector = getSelector(elementName, ...args);
const doc = dbg.win.document;
return EventUtils.synthesizeMouseAtCenter(
doc.querySelector(selector),
{type: "contextmenu"},
dbg.win
);
}
function selectMenuItem(dbg, index) {
// the context menu is in the toolbox window
const doc = dbg.toolbox.win.document;
// there are several context menus, we want the one with the menu-api
const popup = doc.querySelector("menupopup[menu-api=\"true\"]");
const item = popup.querySelector(`menuitem:nth-child(${index})`);
return EventUtils.synthesizeMouseAtCenter(item, {}, dbg.toolbox.win );
}
/**
* Toggles the debugger call stack accordian.
*

View File

@ -0,0 +1,20 @@
function originalToGeneratedId(originalId) {
const match = originalId.match(/(.*)\/originalSource/);
return match ? match[1] : "";
}
function generatedToOriginalId(generatedId, url) {
return generatedId + "/originalSource-" + url.replace(/ \//, '-');
}
function isOriginalId(id) {
return !!id.match(/\/originalSource/);
}
function isGeneratedId(id) {
return !isOriginalId(id);
}
module.exports = {
originalToGeneratedId, generatedToOriginalId, isOriginalId, isGeneratedId
};

View File

@ -0,0 +1,220 @@
const { fetch, assert } = require("devtools/shared/DevToolsUtils");
const { joinURI } = require("devtools/shared/path");
const path = require("sdk/fs/path");
const { SourceMapConsumer, SourceMapGenerator } = require("source-map");
const { isJavaScript } = require("./source");
const {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId
} = require("./source-map-util");
let sourceMapRequests = new Map();
let sourceMapsEnabled = false;
function clearSourceMaps() {
sourceMapRequests.clear();
}
function enableSourceMaps() {
sourceMapsEnabled = true;
}
function _resolveSourceMapURL(source) {
const { url = "", sourceMapURL = "" } = source;
if (path.isURL(sourceMapURL) || url == "") {
// If it's already a full URL or the source doesn't have a URL,
// don't resolve anything.
return sourceMapURL;
} else if (path.isAbsolute(sourceMapURL)) {
// If it's an absolute path, it should be resolved relative to the
// host of the source.
const { protocol = "", host = "" } = parse(url);
return `${protocol}//${host}${sourceMapURL}`;
}
// Otherwise, it's a relative path and should be resolved relative
// to the source.
return dirname(url) + "/" + sourceMapURL;
}
/**
* Sets the source map's sourceRoot to be relative to the source map url.
* @memberof utils/source-map-worker
* @static
*/
function _setSourceMapRoot(sourceMap, absSourceMapURL, source) {
// No need to do this fiddling if we won't be fetching any sources over the
// wire.
if (sourceMap.hasContentsOfAllSources()) {
return;
}
const base = dirname(
(absSourceMapURL.indexOf("data:") === 0 && source.url) ?
source.url :
absSourceMapURL
);
if (sourceMap.sourceRoot) {
sourceMap.sourceRoot = joinURI(base, sourceMap.sourceRoot);
} else {
sourceMap.sourceRoot = base;
}
return sourceMap;
}
function _getSourceMap(generatedSourceId)
: ?Promise<SourceMapConsumer> {
return sourceMapRequests.get(generatedSourceId);
}
async function _resolveAndFetch(generatedSource) : SourceMapConsumer {
// Fetch the sourcemap over the network and create it.
const sourceMapURL = _resolveSourceMapURL(generatedSource);
const fetched = await fetch(
sourceMapURL, { loadFromCache: false }
);
// Create the source map and fix it up.
const map = new SourceMapConsumer(fetched.content);
_setSourceMapRoot(map, sourceMapURL, generatedSource);
return map;
}
function _fetchSourceMap(generatedSource) {
const existingRequest = sourceMapRequests.get(generatedSource.id);
if (existingRequest) {
// If it has already been requested, return the request. Make sure
// to do this even if sourcemapping is turned off, because
// pretty-printing uses sourcemaps.
//
// An important behavior here is that if it's in the middle of
// requesting it, all subsequent calls will block on the initial
// request.
return existingRequest;
} else if (!generatedSource.sourceMapURL || !sourceMapsEnabled) {
return Promise.resolve(null);
}
// Fire off the request, set it in the cache, and return it.
// Suppress any errors and just return null (ignores bogus
// sourcemaps).
const req = _resolveAndFetch(generatedSource).catch(() => null);
sourceMapRequests.set(generatedSource.id, req);
return req;
}
async function getOriginalURLs(generatedSource) {
const map = await _fetchSourceMap(generatedSource);
return map && map.sources;
}
async function getGeneratedLocation(location: Location, originalSource: Source)
: Promise<Location> {
if (!isOriginalId(location.sourceId)) {
return location;
}
const generatedSourceId = originalToGeneratedId(location.sourceId);
const map = await _getSourceMap(generatedSourceId);
if (!map) {
return location;
}
const { line, column } = map.generatedPositionFor({
source: originalSource.url,
line: location.line,
column: location.column == null ? 0 : location.column
});
return {
sourceId: generatedSourceId,
line: line,
// Treat 0 as no column so that line breakpoints work correctly.
column: column === 0 ? undefined : column
};
}
async function getOriginalLocation(location) {
if (!isGeneratedId(location.sourceId)) {
return location;
}
const map = await _getSourceMap(location.sourceId);
if (!map) {
return location;
}
const { source: url, line, column } = map.originalPositionFor({
line: location.line,
column: location.column == null ? Infinity : location.column
});
if (url == null) {
// No url means the location didn't map.
return location;
}
return {
sourceId: generatedToOriginalId(location.sourceId, url),
line,
column
};
}
async function getOriginalSourceText(originalSource) {
assert(isOriginalId(originalSource.id),
"Source is not an original source");
const generatedSourceId = originalToGeneratedId(originalSource.id);
const map = await _getSourceMap(generatedSourceId);
if (!map) {
return null;
}
let text = map.sourceContentFor(originalSource.url);
if (!text) {
text = (await fetch(
originalSource.url, { loadFromCache: false }
)).content;
}
return {
text,
contentType: isJavaScript(originalSource.url || "") ?
"text/javascript" :
"text/plain"
};
}
function applySourceMap(generatedId, url, code, mappings) {
const generator = new SourceMapGenerator({ file: url });
mappings.forEach(mapping => generator.addMapping(mapping));
generator.setSourceContent(url, code);
const map = SourceMapConsumer(generator.toJSON());
sourceMapRequests.set(generatedId, Promise.resolve(map));
}
const publicInterface = {
getOriginalURLs,
getGeneratedLocation,
getOriginalLocation,
getOriginalSourceText,
enableSourceMaps,
applySourceMap,
clearSourceMaps
};
self.onmessage = function(msg) {
const { id, method, args } = msg.data;
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }),
err => self.postMessage({ id, error: err }));
} else {
self.postMessage({ id, response });
}
};

View File

@ -0,0 +1,84 @@
// @flow
const {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId
} = require("./source-map-util");
function workerTask(worker, method) {
return function(...args: any) {
return new Promise((resolve, reject) => {
const id = msgId++;
worker.postMessage({ id, method, args });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
worker.addEventListener("message", listener);
});
};
}
let sourceMapWorker;
function restartWorker() {
if (sourceMapWorker) {
sourceMapWorker.terminate();
}
sourceMapWorker = new Worker(
"resource://devtools/client/framework/source-map-worker.js"
);
if (Services.prefs.getBoolPref("devtools.debugger.client-source-maps-enabled")) {
sourceMapWorker.postMessage({ id: 0, method: "enableSourceMaps" });
}
}
restartWorker();
function destroyWorker() {
if (sourceMapWorker) {
sourceMapWorker.terminate();
sourceMapWorker = null;
}
}
function shouldSourceMap() {
return Services.prefs.getBoolPref("devtools.debugger.client-source-maps-enabled");
}
const getOriginalURLs = workerTask(sourceMapWorker, "getOriginalURLs");
const getGeneratedLocation = workerTask(sourceMapWorker,
"getGeneratedLocation");
const getOriginalLocation = workerTask(sourceMapWorker,
"getOriginalLocation");
const getOriginalSourceText = workerTask(sourceMapWorker,
"getOriginalSourceText");
const applySourceMap = workerTask(sourceMapWorker, "applySourceMap");
const clearSourceMaps = workerTask(sourceMapWorker, "clearSourceMaps");
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId,
getOriginalURLs,
getGeneratedLocation,
getOriginalLocation,
getOriginalSourceText,
applySourceMap,
clearSourceMaps,
destroyWorker,
shouldSourceMap
};

View File

@ -187,6 +187,38 @@ editor.searchResults=%d of %d results
# for when no results found.
editor.noResults=no results
# LOCALIZATION NOTE(editor.addBreakpoint): Editor gutter context menu item
# for adding a breakpoint on a line.
editor.addBreakpoint=Add Breakpoint
# LOCALIZATION NOTE(editor.removeBreakpoint): Editor gutter context menu item
# for removing a breakpoint on a line.
editor.removeBreakpoint=Remove Breakpoint
# LOCALIZATION NOTE(editor.editBreakpoint): Editor gutter context menu item
# for setting a breakpoint condition on a line.
editor.editBreakpoint=Edit Breakpoint
# LOCALIZATION NOTE(editor.addConditionalBreakpoint): Editor gutter context
# menu item for adding a breakpoint condition on a line.
editor.addConditionalBreakpoint=Add Conditional Breakpoint
# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item
# for closing the selected tab below the mouse.
sourceTabs.closeTab=Close tab
# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item
# for closing the other tabs.
sourceTabs.closeOtherTabs=Close others
# LOCALIZATION NOTE (sourceTabs.closeTabsToRight): Editor source tab context menu item
# for closing the tabs to the right of the selected tab.
sourceTabs.closeTabsToRight=Close tabs to the right
# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item
# for closing all tabs.
sourceTabs.closeAllTabs=Close all tabs
# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.
scopes.header=Scopes