Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Oana Pop Rus 2019-02-08 12:11:54 +02:00
Родитель bbcb8a93f2 03ebbdab95
Коммит 1f2fab8f20
3034 изменённых файлов: 36578 добавлений и 11455 удалений

Просмотреть файл

@ -1,9 +1,9 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Version 123
Version 124
Comparison: https://github.com/devtools-html/debugger.html/compare/release-122...release-123
Comparison: https://github.com/devtools-html/debugger.html/compare/release-123...release-124
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.2

Просмотреть файл

@ -1075,6 +1075,10 @@ html[dir="rtl"] .managed-tree .tree .node > div {
background: var(--theme-icon-color);
mask-size: 100%;
}
.img.arrow.arrow.expanded {
transform: rotate(0deg);
}
/* 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/>. */
@ -2331,10 +2335,6 @@ menuseparator {
color: inherit;
}
.sources-list .tree .img.arrow.expanded {
transform: rotate(0deg);
}
.theme-dark .source-list .tree .node.focused {
background-color: var(--theme-tab-toolbar-background);
}
@ -3761,8 +3761,8 @@ html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
* 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/>. */
.frames [role="list"] .frames-group .group,
.frames [role="list"] .frames-group .group .location {
.frames ul .frames-group .group,
.frames ul .frames-group .group .location {
font-weight: 500;
cursor: default;
/*
@ -3773,30 +3773,25 @@ html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
direction: ltr;
}
.frames [role="list"] .frames-group.expanded .group,
.frames [role="list"] .frames-group.expanded .group .location {
.frames ul .frames-group.expanded .group,
.frames ul .frames-group.expanded .group .location {
color: var(--theme-highlight-blue);
}
.frames [role="list"] .frames-group.expanded .react path {
.frames ul .frames-group.expanded .react path {
fill: var(--theme-highlight-blue);
}
.frames [role="list"] .frames-group .frames-list [role="listitem"] {
.frames ul .frames-group .frames-list li {
padding-left: 30px;
}
.frames [role="list"] .frames-group .frames-list {
.frames ul .frames-group .frames-list {
border-top: 1px solid var(--theme-splitter-color);
border-bottom: 1px solid var(--theme-splitter-color);
}
/* We don't want to display those as flex since only the name is displayed */
.frames [role="list"] .frames-group .frames-list [role="listitem"] {
display: block;
}
.frames [role="list"] .frames-group.expanded .badge {
.frames ul .frames-group.expanded .badge {
color: var(--theme-highlight-blue);
}
@ -3862,7 +3857,7 @@ html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
.frames [role="list"] {
list-style: none;
margin: 0;
margin-top: 4px;
padding: 0;
}
@ -3964,7 +3959,6 @@ html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
mask-size: 100%;
display: inline-block;
width: 12px;
margin-inline-start: 4px;
}
:root.theme-dark .annotation-logo:not(.angular) svg path {
@ -4624,6 +4618,13 @@ html .welcomebox .toggle-button-end.collapsed {
user-select: none;
}
.source-header .command-bar {
flex: initial;
flex-shrink: 0;
border-bottom: 0;
border-inline-start: 1px solid var(--theme-splitter-color);
}
.source-tabs {
max-width: calc(100% - 80px);
align-self: flex-start;
@ -4652,7 +4653,8 @@ html .welcomebox .toggle-button-end.collapsed {
width: 100%;
height: 2px;
background-color: var(--tab-line-color, transparent);
transition: transform 250ms var(--animation-curve), opacity 250ms var(--animation-curve);
transition: transform 250ms var(--animation-curve),
opacity 250ms var(--animation-curve);
opacity: 0;
transform: scaleX(0);
}

Просмотреть файл

@ -20759,8 +20759,6 @@ var _types = __webpack_require__(2268);
var t = _interopRequireWildcard(_types);
var _devtoolsSourceMap = __webpack_require__(3646);
var _getFunctionName = __webpack_require__(1621);
var _getFunctionName2 = _interopRequireDefault(_getFunctionName);
@ -20795,6 +20793,14 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
// Location information about the expression immediartely surrounding a
// given binding reference.
/* 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/>. */
function isGeneratedId(id) {
return !/\/originalSource/.test(id);
}
function parseSourceScopes(sourceId) {
const ast = (0, _ast.getAst)(sourceId);
if ((0, _isEmpty2.default)(ast)) {
@ -20802,9 +20808,7 @@ function parseSourceScopes(sourceId) {
}
return buildScopeList(ast, sourceId);
} /* 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/>. */
}
function buildScopeList(ast, sourceId) {
const { global, lexical } = createGlobalScope(ast, sourceId);
@ -20836,7 +20840,7 @@ function buildScopeList(ast, sourceId) {
// TODO: This should probably check for ".mjs" extension on the
// original file, and should also be skipped if the the generated
// code is an ES6 module rather than a script.
if ((0, _devtoolsSourceMap.isGeneratedId)(sourceId) || ast.program.sourceType === "script" && !looksLikeCommonJS(global)) {
if (isGeneratedId(sourceId) || ast.program.sourceType === "script" && !looksLikeCommonJS(global)) {
stripModuleScope(global);
}
@ -21479,344 +21483,6 @@ function stripModuleScope(rootScope) {
});
}
/***/ }),
/***/ 248:
/***/ (function(module, exports, __webpack_require__) {
(function(){
var crypt = __webpack_require__(249),
utf8 = __webpack_require__(250).utf8,
isBuffer = __webpack_require__(251),
bin = __webpack_require__(250).bin,
// The core
md5 = function (message, options) {
// Convert to byte array
if (message.constructor == String)
if (options && options.encoding === 'binary')
message = bin.stringToBytes(message);
else
message = utf8.stringToBytes(message);
else if (isBuffer(message))
message = Array.prototype.slice.call(message, 0);
else if (!Array.isArray(message))
message = message.toString();
// else, assume byte array already
var m = crypt.bytesToWords(message),
l = message.length * 8,
a = 1732584193,
b = -271733879,
c = -1732584194,
d = 271733878;
// Swap endian
for (var i = 0; i < m.length; i++) {
m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF |
((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00;
}
// Padding
m[l >>> 5] |= 0x80 << (l % 32);
m[(((l + 64) >>> 9) << 4) + 14] = l;
// Method shortcuts
var FF = md5._ff,
GG = md5._gg,
HH = md5._hh,
II = md5._ii;
for (var i = 0; i < m.length; i += 16) {
var aa = a,
bb = b,
cc = c,
dd = d;
a = FF(a, b, c, d, m[i+ 0], 7, -680876936);
d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
c = FF(c, d, a, b, m[i+ 2], 17, 606105819);
b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
a = FF(a, b, c, d, m[i+ 4], 7, -176418897);
d = FF(d, a, b, c, m[i+ 5], 12, 1200080426);
c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
a = FF(a, b, c, d, m[i+ 8], 7, 1770035416);
d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
c = FF(c, d, a, b, m[i+10], 17, -42063);
b = FF(b, c, d, a, m[i+11], 22, -1990404162);
a = FF(a, b, c, d, m[i+12], 7, 1804603682);
d = FF(d, a, b, c, m[i+13], 12, -40341101);
c = FF(c, d, a, b, m[i+14], 17, -1502002290);
b = FF(b, c, d, a, m[i+15], 22, 1236535329);
a = GG(a, b, c, d, m[i+ 1], 5, -165796510);
d = GG(d, a, b, c, m[i+ 6], 9, -1069501632);
c = GG(c, d, a, b, m[i+11], 14, 643717713);
b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
a = GG(a, b, c, d, m[i+ 5], 5, -701558691);
d = GG(d, a, b, c, m[i+10], 9, 38016083);
c = GG(c, d, a, b, m[i+15], 14, -660478335);
b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
a = GG(a, b, c, d, m[i+ 9], 5, 568446438);
d = GG(d, a, b, c, m[i+14], 9, -1019803690);
c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
b = GG(b, c, d, a, m[i+ 8], 20, 1163531501);
a = GG(a, b, c, d, m[i+13], 5, -1444681467);
d = GG(d, a, b, c, m[i+ 2], 9, -51403784);
c = GG(c, d, a, b, m[i+ 7], 14, 1735328473);
b = GG(b, c, d, a, m[i+12], 20, -1926607734);
a = HH(a, b, c, d, m[i+ 5], 4, -378558);
d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
c = HH(c, d, a, b, m[i+11], 16, 1839030562);
b = HH(b, c, d, a, m[i+14], 23, -35309556);
a = HH(a, b, c, d, m[i+ 1], 4, -1530992060);
d = HH(d, a, b, c, m[i+ 4], 11, 1272893353);
c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
b = HH(b, c, d, a, m[i+10], 23, -1094730640);
a = HH(a, b, c, d, m[i+13], 4, 681279174);
d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
b = HH(b, c, d, a, m[i+ 6], 23, 76029189);
a = HH(a, b, c, d, m[i+ 9], 4, -640364487);
d = HH(d, a, b, c, m[i+12], 11, -421815835);
c = HH(c, d, a, b, m[i+15], 16, 530742520);
b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
a = II(a, b, c, d, m[i+ 0], 6, -198630844);
d = II(d, a, b, c, m[i+ 7], 10, 1126891415);
c = II(c, d, a, b, m[i+14], 15, -1416354905);
b = II(b, c, d, a, m[i+ 5], 21, -57434055);
a = II(a, b, c, d, m[i+12], 6, 1700485571);
d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
c = II(c, d, a, b, m[i+10], 15, -1051523);
b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
a = II(a, b, c, d, m[i+ 8], 6, 1873313359);
d = II(d, a, b, c, m[i+15], 10, -30611744);
c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
b = II(b, c, d, a, m[i+13], 21, 1309151649);
a = II(a, b, c, d, m[i+ 4], 6, -145523070);
d = II(d, a, b, c, m[i+11], 10, -1120210379);
c = II(c, d, a, b, m[i+ 2], 15, 718787259);
b = II(b, c, d, a, m[i+ 9], 21, -343485551);
a = (a + aa) >>> 0;
b = (b + bb) >>> 0;
c = (c + cc) >>> 0;
d = (d + dd) >>> 0;
}
return crypt.endian([a, b, c, d]);
};
// Auxiliary functions
md5._ff = function (a, b, c, d, x, s, t) {
var n = a + (b & c | ~b & d) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
md5._gg = function (a, b, c, d, x, s, t) {
var n = a + (b & d | c & ~d) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
md5._hh = function (a, b, c, d, x, s, t) {
var n = a + (b ^ c ^ d) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
md5._ii = function (a, b, c, d, x, s, t) {
var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
return ((n << s) | (n >>> (32 - s))) + b;
};
// Package private blocksize
md5._blocksize = 16;
md5._digestsize = 16;
module.exports = function (message, options) {
if (message === undefined || message === null)
throw new Error('Illegal argument ' + message);
var digestbytes = crypt.wordsToBytes(md5(message, options));
return options && options.asBytes ? digestbytes :
options && options.asString ? bin.bytesToString(digestbytes) :
crypt.bytesToHex(digestbytes);
};
})();
/***/ }),
/***/ 249:
/***/ (function(module, exports) {
(function() {
var base64map
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
crypt = {
// Bit-wise rotation left
rotl: function(n, b) {
return (n << b) | (n >>> (32 - b));
},
// Bit-wise rotation right
rotr: function(n, b) {
return (n << (32 - b)) | (n >>> b);
},
// Swap big-endian to little-endian and vice versa
endian: function(n) {
// If number given, swap endian
if (n.constructor == Number) {
return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00;
}
// Else, assume array and swap all items
for (var i = 0; i < n.length; i++)
n[i] = crypt.endian(n[i]);
return n;
},
// Generate an array of any length of random bytes
randomBytes: function(n) {
for (var bytes = []; n > 0; n--)
bytes.push(Math.floor(Math.random() * 256));
return bytes;
},
// Convert a byte array to big-endian 32-bit words
bytesToWords: function(bytes) {
for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
words[b >>> 5] |= bytes[i] << (24 - b % 32);
return words;
},
// Convert big-endian 32-bit words to a byte array
wordsToBytes: function(words) {
for (var bytes = [], b = 0; b < words.length * 32; b += 8)
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
return bytes;
},
// Convert a byte array to a hex string
bytesToHex: function(bytes) {
for (var hex = [], i = 0; i < bytes.length; i++) {
hex.push((bytes[i] >>> 4).toString(16));
hex.push((bytes[i] & 0xF).toString(16));
}
return hex.join('');
},
// Convert a hex string to a byte array
hexToBytes: function(hex) {
for (var bytes = [], c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return bytes;
},
// Convert a byte array to a base-64 string
bytesToBase64: function(bytes) {
for (var base64 = [], i = 0; i < bytes.length; i += 3) {
var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
for (var j = 0; j < 4; j++)
if (i * 8 + j * 6 <= bytes.length * 8)
base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
else
base64.push('=');
}
return base64.join('');
},
// Convert a base-64 string to a byte array
base64ToBytes: function(base64) {
// Remove non-base-64 characters
base64 = base64.replace(/[^A-Z0-9+\/]/ig, '');
for (var bytes = [], i = 0, imod4 = 0; i < base64.length;
imod4 = ++i % 4) {
if (imod4 == 0) continue;
bytes.push(((base64map.indexOf(base64.charAt(i - 1))
& (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2))
| (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
}
return bytes;
}
};
module.exports = crypt;
})();
/***/ }),
/***/ 250:
/***/ (function(module, exports) {
var charenc = {
// UTF-8 encoding
utf8: {
// Convert a string to a byte array
stringToBytes: function(str) {
return charenc.bin.stringToBytes(unescape(encodeURIComponent(str)));
},
// Convert a byte array to a string
bytesToString: function(bytes) {
return decodeURIComponent(escape(charenc.bin.bytesToString(bytes)));
}
},
// Binary encoding
bin: {
// Convert a string to a byte array
stringToBytes: function(str) {
for (var bytes = [], i = 0; i < str.length; i++)
bytes.push(str.charCodeAt(i) & 0xFF);
return bytes;
},
// Convert a byte array to a string
bytesToString: function(bytes) {
for (var str = [], i = 0; i < bytes.length; i++)
str.push(String.fromCharCode(bytes[i]));
return str.join('');
}
}
};
module.exports = charenc;
/***/ }),
/***/ 251:
/***/ (function(module, exports) {
/*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
// The _isBuffer check is for Safari 5-7 support, because it's missing
// Object.prototype.constructor. Remove this eventually
module.exports = function (obj) {
return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
}
function isBuffer (obj) {
return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
}
// For Node v0.10 support. Remove this eventually.
function isSlowBuffer (obj) {
return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
}
/***/ }),
/***/ 262:
@ -23124,79 +22790,6 @@ function mapOriginalExpression(expression, ast, mappings) {
/***/ }),
/***/ 3646:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/>. */
const {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId
} = __webpack_require__(3652);
const {
workerUtils: { WorkerDispatcher }
} = __webpack_require__(3651);
const dispatcher = new WorkerDispatcher();
const setAssetRootURL = dispatcher.task("setAssetRootURL");
const getOriginalURLs = dispatcher.task("getOriginalURLs");
const hasOriginalURL = dispatcher.task("hasOriginalURL");
const getOriginalRanges = dispatcher.task("getOriginalRanges");
const getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
queue: true
});
const getGeneratedLocation = dispatcher.task("getGeneratedLocation", {
queue: true
});
const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", {
queue: true
});
const getOriginalLocation = dispatcher.task("getOriginalLocation");
const getFileGeneratedRange = dispatcher.task("getFileGeneratedRange");
const getLocationScopes = dispatcher.task("getLocationScopes");
const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
const applySourceMap = dispatcher.task("applySourceMap");
const clearSourceMaps = dispatcher.task("clearSourceMaps");
const hasMappedSource = dispatcher.task("hasMappedSource");
const getOriginalStackFrames = dispatcher.task("getOriginalStackFrames");
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId,
hasMappedSource,
getOriginalURLs,
hasOriginalURL,
getOriginalRanges,
getGeneratedRanges,
getGeneratedLocation,
getAllGeneratedLocations,
getOriginalLocation,
getFileGeneratedRange,
getLocationScopes,
getOriginalSourceText,
applySourceMap,
clearSourceMaps,
getOriginalStackFrames,
startSourceMapWorker(url, assetRoot) {
dispatcher.start(url);
setAssetRootURL(assetRoot);
},
stopSourceMapWorker: dispatcher.stop.bind(dispatcher)
};
/***/ }),
/***/ 3651:
/***/ (function(module, exports, __webpack_require__) {
@ -23214,94 +22807,6 @@ module.exports = {
/***/ }),
/***/ 3652:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* 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/>. */
const md5 = __webpack_require__(248);
function originalToGeneratedId(originalId) {
const match = originalId.match(/(.*)\/originalSource/);
return match ? match[1] : "";
}
function generatedToOriginalId(generatedId, url) {
return `${generatedId}/originalSource-${md5(url)}`;
}
function isOriginalId(id) {
return (/\/originalSource/.test(id)
);
}
function isGeneratedId(id) {
return !isOriginalId(id);
}
/**
* Trims the query part or reference identifier of a URL string, if necessary.
*/
function trimUrlQuery(url) {
const length = url.length;
const q1 = url.indexOf("?");
const q2 = url.indexOf("&");
const q3 = url.indexOf("#");
const q = Math.min(q1 != -1 ? q1 : length, q2 != -1 ? q2 : length, q3 != -1 ? q3 : length);
return url.slice(0, q);
}
// Map suffix to content type.
const contentMap = {
js: "text/javascript",
jsm: "text/javascript",
mjs: "text/javascript",
ts: "text/typescript",
tsx: "text/typescript-jsx",
jsx: "text/jsx",
vue: "text/vue",
coffee: "text/coffeescript",
elm: "text/elm",
cljc: "text/x-clojure",
cljs: "text/x-clojurescript"
};
/**
* Returns the content type for the specified URL. If no specific
* content type can be determined, "text/plain" is returned.
*
* @return String
* The content type.
*/
function getContentType(url) {
url = trimUrlQuery(url);
const dot = url.lastIndexOf(".");
if (dot >= 0) {
const name = url.substring(dot + 1);
if (name in contentMap) {
return contentMap[name];
}
}
return "text/plain";
}
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isOriginalId,
isGeneratedId,
getContentType,
contentMapForTesting: contentMap
};
/***/ }),
/***/ 3653:
/***/ (function(module, exports) {

Просмотреть файл

@ -26,7 +26,7 @@
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"eslint": "^5.0.0",
"eslint-plugin-mozilla": "1.0.4",
"eslint-plugin-mozilla": "1.1.1",
"fs-extra": "^7.0.0",
"lodash": "^4.17.2"
}

Просмотреть файл

@ -1,6 +1,6 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill #9B9B9B">
<path d="M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z"/>
<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<path d="M5 8c-.25 0-.35-.1-.65-.4l-3.1-3.35C.75 3.7 1.1 3 1.75 3h6.5c.65 0 1 .7.5 1.25L5.65 7.6c-.3.3-.4.4-.65.4z"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 474 B

После

Ширина:  |  Высота:  |  Размер: 400 B

Просмотреть файл

@ -58,8 +58,8 @@
background:url(/images/arrow.svg) no-repeat;
background-size:contain;
background-position:center center;
width: 9px;
height: 9px;
width: 10px;
height: 10px;
border:0;
padding:0;
margin-inline-start: 1px;

Просмотреть файл

@ -798,7 +798,7 @@ class Tree extends Component {
// it should be scrolled into view.
this._focus(item, { preventAutoScroll: true });
if (this.props.isExpanded(item)) {
this.props.onCollapse(item);
this.props.onCollapse(item, e.altKey);
} else {
this.props.onExpand(item, e.altKey);
}
@ -806,10 +806,7 @@ class Tree extends Component {
});
});
const style = Object.assign({}, this.props.style || {}, {
padding: 0,
margin: 0
});
const style = Object.assign({}, this.props.style || {});
return dom.div(
{

Просмотреть файл

@ -0,0 +1,48 @@
/* 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/. */
const { toolboxConfig } = require("devtools-launchpad/index");
const {isDevelopment} = require("devtools-config");
const path = require("path");
const projectPath = path.join(__dirname);
const webpackConfig = {
entry: {
"devtools-components": path.join(projectPath, "index.js"),
},
output: {
path: path.join(__dirname, "assets/build"),
filename: "[name].js",
publicPath: "/assets/build",
libraryTarget: "umd",
},
resolve: {
alias: {
"devtools/client/shared/vendor/react": "react",
"devtools/client/shared/vendor/react-dom": "react-dom",
"devtools/client/shared/vendor/react-dom-factories": "react-dom-factories",
"devtools/client/shared/vendor/react-prop-types": "prop-types",
"Services": path.join(__dirname,
"node_modules/devtools-modules/client/shared/shim/Services"),
}
}
};
const extra = {
disablePostCSS: true,
};
webpackConfig.plugins = [];
if (!isDevelopment()) {
extra.excludeMap = {
react: "devtools/client/shared/vendor/react",
"react-dom": "devtools/client/shared/vendor/react-dom",
"react-dom-factories": "devtools/client/shared/vendor/react-dom-factories",
"prop-types": "devtools/client/shared/vendor/react-prop-types",
lodash: "devtools/client/shared/vendor/lodash",
};
}
module.exports = toolboxConfig(webpackConfig, {}, extra);

Просмотреть файл

@ -63,17 +63,17 @@ and navigate to `http://localhost:8000` to access the dashboard.
Navigating to the above address will have landed you on an empty launchpad UI:
![Image of empty launchpad](./assets/images/empty-launchpad.png)
![Image of empty launchpad](./images/empty-launchpad.png)
Click on the _Launch Firefox_ button. This should launch Firefox with a dedicated profile, listening for connections on port 6080.
The UI should update automatically and show you at least one tab for the new Firefox instance. If it doesn't, reload the dashboard.
![Image of launchpad](./assets/images/launchpad-app.png)
![Image of launchpad](./images/launchpad-app.png)
Click on any of the tabs. This should open the demo app:
![Image of demo app](./assets/images/demo-app.png)
![Image of demo app](./images/demo-app.png)
Then you can type any expression in the input field. They will be evaluated against the target tab selected in the previous steps (so if there specific objects on window on this webpage, you can check how they are represented with reps etc, ...).

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 85 KiB

После

Ширина:  |  Высота:  |  Размер: 142 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 70 KiB

После

Ширина:  |  Высота:  |  Размер: 116 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 97 KiB

После

Ширина:  |  Высота:  |  Размер: 164 KiB

Просмотреть файл

@ -38,7 +38,7 @@
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-preset-react": "^6.24.1",
"devtools-config": "^0.0.16",
"devtools-launchpad": "^0.0.141",
"devtools-launchpad": "^0.0.145",
"devtools-license-check": "^0.7.0",
"devtools-modules": "~1.1.0",
"devtools-services": "^0.0.1",
@ -46,7 +46,7 @@
"enzyme-adapter-react-16": "^1.1.1",
"enzyme-to-json": "^3.3.1",
"eslint": "^5.0.0",
"eslint-plugin-mozilla": "1.0.4",
"eslint-plugin-mozilla": "1.1.1",
"fs-extra": "^7.0.0",
"immutable": "^3.8.2",
"postcss-url-mapper": "^1.2.0",

Просмотреть файл

@ -104,11 +104,19 @@ function releaseActors(state, client) {
}
}
function invokeGetter(node: Node, grip: object, getterName: string) {
function invokeGetter(
node: Node,
targetGrip: object,
receiverId: string | null,
getterName: string
) {
return async ({ dispatch, client, getState }: ThunkArg) => {
try {
const objectClient = client.createObjectClient(grip);
const result = await objectClient.getPropertyValue(getterName);
const objectClient = client.createObjectClient(targetGrip);
const result = await objectClient.getPropertyValue(
getterName,
receiverId
);
dispatch({
type: "GETTER_INVOKED",
data: {

Просмотреть файл

@ -37,7 +37,8 @@ const {
nodeIsLongString,
nodeHasFullText,
nodeHasGetter,
getNonPrototypeParentGripValue
getNonPrototypeParentGripValue,
getParentGripValue
} = Utils.node;
type Props = {
@ -167,11 +168,17 @@ class ObjectInspectorItem extends Component<Props> {
}
if (nodeHasGetter(item)) {
const parentGrip = getNonPrototypeParentGripValue(item);
if (parentGrip) {
const targetGrip = getParentGripValue(item);
const receiverGrip = getNonPrototypeParentGripValue(item);
if (targetGrip && receiverGrip) {
Object.assign(repProps, {
onInvokeGetterButtonClick: () =>
this.props.invokeGetter(item, parentGrip, item.name)
this.props.invokeGetter(
item,
targetGrip,
receiverGrip.actor,
item.name
)
});
}
}

Просмотреть файл

@ -9,12 +9,7 @@ exports[`ObjectInspector - classnames has the expected class 1`] = `
onKeyPress={[Function]}
onKeyUp={[Function]}
role="tree"
style={
Object {
"margin": 0,
"padding": 0,
}
}
style={Object {}}
tabIndex="0"
>
<div
@ -58,12 +53,7 @@ exports[`ObjectInspector - classnames has the inline class when inline prop is t
onKeyPress={[Function]}
onKeyUp={[Function]}
role="tree"
style={
Object {
"margin": 0,
"padding": 0,
}
}
style={Object {}}
tabIndex="0"
>
<div
@ -107,12 +97,7 @@ exports[`ObjectInspector - classnames has the nowrap class when disableWrap prop
onKeyPress={[Function]}
onKeyUp={[Function]}
role="tree"
style={
Object {
"margin": 0,
"padding": 0,
}
}
style={Object {}}
tabIndex="0"
>
<div

Просмотреть файл

@ -9,12 +9,7 @@ exports[`ObjectInspector - dimTopLevelWindow renders collapsed top-level window
onKeyPress={[Function]}
onKeyUp={[Function]}
role="tree"
style={
Object {
"margin": 0,
"padding": 0,
}
}
style={Object {}}
tabIndex="0"
>
<div
@ -68,12 +63,7 @@ exports[`ObjectInspector - dimTopLevelWindow renders sub-level window 1`] = `
onKeyPress={[Function]}
onKeyUp={[Function]}
role="tree"
style={
Object {
"margin": 0,
"padding": 0,
}
}
style={Object {}}
tabIndex="0"
>
<div
@ -154,12 +144,7 @@ exports[`ObjectInspector - dimTopLevelWindow renders window as expected when dim
onKeyPress={[Function]}
onKeyUp={[Function]}
role="tree"
style={
Object {
"margin": 0,
"padding": 0,
}
}
style={Object {}}
tabIndex="0"
>
<div
@ -213,12 +198,7 @@ exports[`ObjectInspector - dimTopLevelWindow renders window as expected when dim
onKeyPress={[Function]}
onKeyUp={[Function]}
role="tree"
style={
Object {
"margin": 0,
"padding": 0,
}
}
style={Object {}}
tabIndex="0"
>
<div

Просмотреть файл

@ -877,13 +877,26 @@ function getClosestNonBucketNode(item: Node): Node | null {
return getClosestNonBucketNode(parent);
}
function getNonPrototypeParentGripValue(item: Node | null): Node | null {
function getParentGripNode(item: Node | null): Node | null {
const parentNode = getParent(item);
if (!parentNode) {
return null;
}
const parentGripNode = getClosestGripNode(parentNode);
return getClosestGripNode(parentNode);
}
function getParentGripValue(item: Node | null): any {
const parentGripNode = getParentGripNode(item);
if (!parentGripNode) {
return null;
}
return getValue(parentGripNode);
}
function getNonPrototypeParentGripValue(item: Node | null): Node | null {
const parentGripNode = getParentGripNode(item);
if (!parentGripNode) {
return null;
}
@ -905,6 +918,7 @@ module.exports = {
getClosestGripNode,
getClosestNonBucketNode,
getParent,
getParentGripValue,
getNonPrototypeParentGripValue,
getNumericalPropertiesCount,
getValue,

Просмотреть файл

@ -57,7 +57,7 @@ function ErrorRep(props) {
const stacktrace = props.renderStacktrace
? props.renderStacktrace(parseStackString(preview.stack))
: getStacktraceElements(props, preview);
content.push("\n", stacktrace);
content.push(stacktrace);
}
return span(

Просмотреть файл

@ -14,4 +14,15 @@ stubs.set("SymbolWithoutIdentifier", {
actor: "server1.conn1.child1/symbol2"
});
stubs.set("SymbolWithLongString", {
type: "symbol",
actor: "server1.conn1.child1/symbol1",
name: {
type: "longString",
initial: "aa".repeat(10000),
length: 20000,
actor: "server1.conn1.child1/longString58"
}
});
module.exports = stubs;

Просмотреть файл

@ -8,8 +8,11 @@ const PropTypes = require("prop-types");
const { getGripType, wrapRender } = require("./rep-utils");
const dom = require("react-dom-factories");
const { rep: StringRep } = require("./string");
const { span } = dom;
const MAX_STRING_LENGTH = 50;
/**
* Renders a symbol.
*/
@ -21,12 +24,24 @@ function SymbolRep(props) {
const { className = "objectBox objectBox-symbol", object } = props;
const { name } = object;
let symbolText = name || "";
if (name && name.type && name.type === "longString") {
symbolText = StringRep({
object: symbolText,
shouldCrop: true,
cropLimit: MAX_STRING_LENGTH,
useQuotes: false
});
}
return span(
{
className,
"data-link-actor-id": object.actor
},
`Symbol(${name || ""})`
"Symbol(",
symbolText,
")"
);
}

Просмотреть файл

@ -6,8 +6,6 @@ exports[`Error - Eval error renders with expected text for an EvalError 1`] = `
data-link-actor-id="server1.conn1.child1/obj1022"
>
EvalError: "EvalError message"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -38,8 +36,6 @@ exports[`Error - Internal error renders with expected text for an InternalError
data-link-actor-id="server1.conn1.child1/obj1023"
>
InternalError: "InternalError message"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -70,8 +66,6 @@ exports[`Error - Multi line stack error renders with expected text for Error obj
data-link-actor-id="server1.conn1.child1/obj1021"
>
Error: "bar"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -134,8 +128,6 @@ exports[`Error - Range error renders with expected text for RangeError 1`] = `
data-link-actor-id="server1.conn1.child1/obj1024"
>
RangeError: "RangeError message"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -166,8 +158,6 @@ exports[`Error - Reference error renders with expected text for ReferenceError 1
data-link-actor-id="server1.conn1.child1/obj1025"
>
ReferenceError: "ReferenceError message"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -198,8 +188,6 @@ exports[`Error - Simple error renders with expected text for simple error 1`] =
data-link-actor-id="server1.conn1.child1/obj1020"
>
Error: "Error message"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -230,8 +218,6 @@ exports[`Error - Syntax error renders with expected text for SyntaxError 1`] = `
data-link-actor-id="server1.conn1.child1/obj1026"
>
SyntaxError: "SyntaxError message"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -262,8 +248,6 @@ exports[`Error - Type error renders with expected text for TypeError 1`] = `
data-link-actor-id="server1.conn1.child1/obj1027"
>
TypeError: "TypeError message"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -294,8 +278,6 @@ exports[`Error - URI error renders with expected text for URIError 1`] = `
data-link-actor-id="server1.conn1.child1/obj1028"
>
URIError: "URIError message"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -335,8 +317,6 @@ exports[`Error - base-loader.js renders as expected without mode 1`] = `
data-link-actor-id="server1.conn1.child1/obj1020"
>
Error: "Error message"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -415,8 +395,6 @@ exports[`Error - longString stacktrace - cut-off location renders as expected 1`
data-link-actor-id="server1.conn1.child1/obj33"
>
InternalError: "too much recursion"
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -543,8 +521,6 @@ exports[`Error - longString stacktrace renders as expected 1`] = `
data-link-actor-id="server1.conn2.child1/obj33"
>
Error: ""
<span
className="objectBox-stackTrace-grid"
key="stack"
@ -719,8 +695,6 @@ exports[`Error - renderStacktrace prop uses renderStacktrace prop when provided
data-link-actor-id="server1.conn1.child1/obj1021"
>
Error: "bar"
<li
className="frame"
>
@ -748,8 +722,6 @@ exports[`Error - renderStacktrace prop uses renderStacktrace with longString err
data-link-actor-id="server1.conn1.child1/obj33"
>
InternalError: "too much recursion"
<li
className="frame"
>

Просмотреть файл

@ -37,3 +37,20 @@ describe("test Symbol without identifier", () => {
expectActorAttribute(renderedComponent, stub.actor);
});
});
describe("test Symbol with long string", () => {
const stub = stubs.get("SymbolWithLongString");
it("renders the expected content", () => {
const renderedComponent = shallow(
Rep({
object: stub
})
);
expect(renderedComponent.text()).toEqual(
"Symbol(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…)"
);
expectActorAttribute(renderedComponent, stub.actor);
});
});

Просмотреть файл

@ -0,0 +1,35 @@
/* 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/. */
const { toolboxConfig } = require("devtools-launchpad/index");
const config = require("./config");
const ObjectRestSpreadPlugin = require("@sucrase/webpack-object-rest-spread-plugin");
const path = require("path");
const projectPath = path.join(__dirname, "src");
let webpackConfig = {
entry: {
reps: [path.join(projectPath, "launchpad/index.js")],
},
output: {
path: path.join(__dirname, "assets/build"),
filename: "[name].js",
publicPath: "/assets/build"
},
plugins: [new ObjectRestSpreadPlugin()],
resolve: {
alias: {
"devtools/client/shared/vendor/react": "react",
"devtools/client/shared/vendor/react-dom": "react-dom",
"devtools/client/shared/vendor/react-dom-factories": "react-dom-factories",
"devtools/client/shared/vendor/react-prop-types": "prop-types",
}
}
};
module.exports = toolboxConfig(webpackConfig, config);

Просмотреть файл

@ -5,60 +5,123 @@
// @flow
const {
workerUtils: { WorkerDispatcher }
} = require("devtools-utils");
import type { SourceLocation, Source, SourceId } from "debugger-html";
import type { SourceMapConsumer } from "source-map";
import type { locationOptions } from "./source-map";
export const dispatcher = new WorkerDispatcher();
const _getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
queue: true
});
const _getGeneratedLocation = dispatcher.task("getGeneratedLocation", { queue: true });
const _getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", { queue: true });
export const setAssetRootURL = async (assetRoot: string): Promise<void> =>
dispatcher.invoke("setAssetRootURL", assetRoot);
export const getOriginalURLs = async (
generatedSource: Source
): Promise<SourceMapConsumer> =>
dispatcher.invoke("getOriginalURLs", generatedSource);
export const hasOriginalURL = async (url: string): Promise<boolean> =>
dispatcher.invoke("hasOriginalURL", url);
export const getOriginalRanges = async (
sourceId: SourceId,
url: string
): Promise<
Array<{
line: number,
columnStart: number,
columnEnd: number
}>
> => dispatcher.invoke("getOriginalRanges", sourceId, url);
export const getGeneratedRanges = async (
location: SourceLocation,
originalSource: Source
): Promise<
Array<{
line: number,
columnStart: number,
columnEnd: number
}>
> =>
_getGeneratedRanges(location, originalSource);
export const getGeneratedLocation = async (
location: SourceLocation,
originalSource: Source
): Promise<SourceLocation> => _getGeneratedLocation(location,originalSource);
export const getAllGeneratedLocations = async (
location: SourceLocation,
originalSource: Source
): Promise<Array<SourceLocation>> => _getAllGeneratedLocations(
location,
originalSource
);
export const getOriginalLocation = async (
location: SourceLocation,
options: locationOptions = {}
): Promise<SourceLocation> =>
dispatcher.invoke("getOriginalLocation", location, options);
export const getFileGeneratedRange = async (
originalSource: Source
): Promise<?{ start: any, end: any }> =>
dispatcher.invoke("getFileGeneratedRange", originalSource);
export const getLocationScopes = dispatcher.task("getLocationScopes");
export const getOriginalSourceText = async (
originalSource: Source
): Promise<?{
text: string,
contentType: string
}> => dispatcher.invoke("getOriginalSourceText", originalSource);
export const applySourceMap = async (
generatedId: string,
url: string,
code: string,
mappings: Object
): Promise<void> =>
dispatcher.invoke("applySourceMap", generatedId, url, code, mappings);
export const clearSourceMaps = async (): Promise<void> =>
dispatcher.invoke("clearSourceMaps");
export const hasMappedSource = async (
location: SourceLocation
): Promise<boolean> => dispatcher.invoke("hasMappedSource", location);
export const getOriginalStackFrames = async (
generatedLocation: SourceLocation
): Promise<?Array<{
displayName: string,
location?: SourceLocation
}>> => dispatcher.invoke("getOriginalStackFrames", generatedLocation);
export {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId
} = require("./utils");
} from "./utils";
const {
workerUtils: { WorkerDispatcher }
} = require("devtools-utils");
const dispatcher = new WorkerDispatcher();
const setAssetRootURL = dispatcher.task("setAssetRootURL");
const getOriginalURLs = dispatcher.task("getOriginalURLs");
const getOriginalRanges = dispatcher.task("getOriginalRanges");
const getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
queue: true
});
const getGeneratedLocation = dispatcher.task("getGeneratedLocation", {
queue: true
});
const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", {
queue: true
});
const getOriginalLocation = dispatcher.task("getOriginalLocation");
const getFileGeneratedRange = dispatcher.task("getFileGeneratedRange");
const getLocationScopes = dispatcher.task("getLocationScopes");
const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
const applySourceMap = dispatcher.task("applySourceMap");
const clearSourceMaps = dispatcher.task("clearSourceMaps");
const hasMappedSource = dispatcher.task("hasMappedSource");
const getOriginalStackFrames = dispatcher.task("getOriginalStackFrames");
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId,
hasMappedSource,
getOriginalURLs,
getOriginalRanges,
getGeneratedRanges,
getGeneratedLocation,
getAllGeneratedLocations,
getOriginalLocation,
getFileGeneratedRange,
getLocationScopes,
getOriginalSourceText,
applySourceMap,
clearSourceMaps,
getOriginalStackFrames,
startSourceMapWorker(url: string, assetRoot: string) {
dispatcher.start(url);
setAssetRootURL(assetRoot);
},
stopSourceMapWorker: dispatcher.stop.bind(dispatcher)
export const startSourceMapWorker = (url: string, assetRoot: string) => {
dispatcher.start(url);
setAssetRootURL(assetRoot);
};
export const stopSourceMapWorker = dispatcher.stop.bind(dispatcher);
import * as self from "devtools-source-map";
export default self;

Просмотреть файл

@ -14,7 +14,11 @@ const { SourceMapConsumer, SourceMapGenerator } = require("source-map");
const { createConsumer } = require("./utils/createConsumer");
const assert = require("./utils/assert");
const { fetchSourceMap } = require("./utils/fetchSourceMap");
const {
fetchSourceMap,
hasOriginalURL,
clearOriginalURLs
} = require("./utils/fetchSourceMap");
const {
getSourceMap,
setSourceMap,
@ -31,7 +35,9 @@ const { clearWasmXScopes } = require("./utils/wasmXScopes");
import type { SourceLocation, Source, SourceId } from "debugger-html";
async function getOriginalURLs(generatedSource: Source) {
async function getOriginalURLs(
generatedSource: Source
): Promise<SourceMapConsumer> {
const map = await fetchSourceMap(generatedSource);
return map && map.sources;
}
@ -39,7 +45,16 @@ async function getOriginalURLs(generatedSource: Source) {
const COMPUTED_SPANS = new WeakSet();
const SOURCE_MAPPINGS = new WeakMap();
async function getOriginalRanges(sourceId: SourceId, url: string) {
async function getOriginalRanges(
sourceId: SourceId,
url: string
): Promise<
Array<{
line: number,
columnStart: number,
columnEnd: number
}>
> {
if (!isOriginalId(sourceId)) {
return [];
}
@ -231,7 +246,7 @@ async function getAllGeneratedLocations(
}));
}
type locationOptions = {
export type locationOptions = {
search?: "LEAST_UPPER_BOUND" | "GREATEST_LOWER_BOUND"
};
async function getOriginalLocation(
@ -285,7 +300,12 @@ async function getOriginalLocation(
};
}
async function getOriginalSourceText(originalSource: Source) {
async function getOriginalSourceText(
originalSource: Source
): Promise<?{
text: string,
contentType: string
}> {
assert(isOriginalId(originalSource.id), "Source is not an original source");
const generatedSourceId = originalToGeneratedId(originalSource.id);
@ -306,7 +326,9 @@ async function getOriginalSourceText(originalSource: Source) {
};
}
async function getFileGeneratedRange(originalSource: Source) {
async function getFileGeneratedRange(
originalSource: Source
): Promise<?{ start: any, end: any }> {
assert(isOriginalId(originalSource.id), "Source is not an original source");
const map = await getSourceMap(originalToGeneratedId(originalSource.id));
@ -360,10 +382,12 @@ function applySourceMap(
function clearSourceMaps() {
clearSourceMapsRequests();
clearWasmXScopes();
clearOriginalURLs();
}
module.exports = {
getOriginalURLs,
hasOriginalURL,
getOriginalRanges,
getGeneratedRanges,
getGeneratedLocation,

Просмотреть файл

@ -17,7 +17,7 @@ function convertDwarf(wasm, instance) {
);
const resultPtr = alloc_mem(12);
const enableXScopes = true;
convert_dwarf(
const success = convert_dwarf(
wasmPtr,
wasm.byteLength,
resultPtr,
@ -29,6 +29,9 @@ function convertDwarf(wasm, instance) {
const outputPtr = resultView.getUint32(0, true),
outputLen = resultView.getUint32(4, true);
free_mem(resultPtr);
if (!success) {
throw new Error("Unable to convert from DWARF sections");
}
if (!utf8Decoder) {
utf8Decoder = new TextDecoder("utf-8");
}

Просмотреть файл

@ -13,6 +13,17 @@ const { createConsumer } = require("./createConsumer");
import type { Source } from "debugger-html";
// URLs which have been seen in a completed source map request.
const originalURLs = new Set();
function clearOriginalURLs() {
originalURLs.clear();
}
function hasOriginalURL(url: string): boolean {
return originalURLs.has(url);
}
function _resolveSourceMapURL(source: Source) {
const { url = "", sourceMapURL = "" } = source;
@ -55,10 +66,14 @@ async function _resolveAndFetch(generatedSource: Source): SourceMapConsumer {
}
}
if (map && map.sources) {
map.sources.forEach(url => originalURLs.add(url));
}
return map;
}
function fetchSourceMap(generatedSource: Source) {
function fetchSourceMap(generatedSource: Source): SourceMapConsumer {
const existingRequest = getSourceMap(generatedSource.id);
// If it has already been requested, return the request. Make sure
@ -84,4 +99,4 @@ function fetchSourceMap(generatedSource: Source) {
return req;
}
module.exports = { fetchSourceMap };
module.exports = { fetchSourceMap, hasOriginalURL, clearOriginalURLs };

Просмотреть файл

@ -16,7 +16,7 @@ function generatedToOriginalId(generatedId: string, url: string) {
}
function isOriginalId(id: string) {
return !!id.match(/\/originalSource/);
return /\/originalSource/.test(id);
}
function isGeneratedId(id: string) {
@ -62,7 +62,7 @@ const contentMap = {
* @return String
* The content type.
*/
function getContentType(url: string) {
function getContentType(url: string): string {
url = trimUrlQuery(url);
const dot = url.lastIndexOf(".");
if (dot >= 0) {

Просмотреть файл

@ -13,14 +13,18 @@ const { generatedToOriginalId } = require("./index");
const xScopes = new Map();
type XScopeItem = any;
type XScopeItemsIndex = Map<string, XScopeItem>;
type XScopeItemsIndex = Map<string | number, XScopeItem>;
function indexLinkingNames(items: XScopeItem[]): XScopeItemsIndex {
const result = new Map();
let queue = [...items];
while (queue.length > 0) {
const item = queue.shift();
if ("linkage_name" in item) {
if ("uid" in item) {
result.set(item.uid, item);
} else if ("linkage_name" in item) {
// TODO the linkage_name string value is used for compatibility
// with old format. Remove in favour of the uid referencing.
result.set(item.linkage_name, item);
}
if ("children" in item) {
@ -30,6 +34,19 @@ function indexLinkingNames(items: XScopeItem[]): XScopeItemsIndex {
return result;
}
function getIndexedItem(
index: XScopeItemsIndex,
key: string | { uid: number }
): XScopeItem {
if (typeof key === "object" && key != null) {
return index.get(key.uid);
}
if (typeof key === "string") {
return index.get(key);
}
return null;
}
type XScopeData = {
code_section_offset: number,
debug_info: Array<XScopeItem>,
@ -112,7 +129,7 @@ function filterScopes(
break;
case "inlined_subroutine":
if (isInRange(item, pc)) {
const linkedItem = index.get(item.abstract_origin);
const linkedItem = getIndexedItem(index, item.abstract_origin);
const s: FoundScope = {
id: item.abstract_origin,
name: linkedItem ? linkedItem.name : void 0

Просмотреть файл

@ -5,6 +5,7 @@
const {
getOriginalURLs,
hasOriginalURL,
getOriginalRanges,
getGeneratedRanges,
getGeneratedLocation,
@ -29,6 +30,7 @@ const {
self.onmessage = workerHandler({
setAssetRootURL,
getOriginalURLs,
hasOriginalURL,
getOriginalRanges,
getGeneratedRanges,
getGeneratedLocation,

Двоичный файл не отображается.

Просмотреть файл

@ -4,9 +4,7 @@
// @flow
import { isOriginalId } from "devtools-source-map";
import {
locationMoved,
breakpointExists,
assertBreakpoint,
createBreakpoint,
@ -20,10 +18,13 @@ import {
getSource,
getSourceActors,
getSymbols,
getFirstVisibleBreakpointPosition
} from "../../selectors";
import { getGeneratedLocation } from "../../utils/source-maps";
import { getTextAtPosition } from "../../utils/source";
import { recordEvent } from "../../utils/telemetry";
import { features } from "../../utils/prefs";
import { setBreakpointPositions } from "./breakpointPositions";
import type {
BreakpointOptions,
@ -67,58 +68,40 @@ async function addBreakpointPromise(getState, client, sourceMaps, breakpoint) {
if (breakpointExists(state, location)) {
const newBreakpoint = { ...breakpoint, location, generatedLocation };
assertBreakpoint(newBreakpoint);
return { breakpoint: newBreakpoint };
return newBreakpoint;
}
const sourceActors = getSourceActors(state, generatedSource.id);
const newGeneratedLocation = { ...generatedLocation };
for (const sourceActor of sourceActors) {
const sourceActorLocation = makeSourceActorLocation(
sourceActor,
generatedLocation
);
const { actualLocation } = await client.setBreakpoint(
sourceActorLocation,
breakpoint.options,
isOriginalId(location.sourceId)
);
newGeneratedLocation.line = actualLocation.line;
newGeneratedLocation.column = actualLocation.column;
await client.setBreakpoint(sourceActorLocation, breakpoint.options);
}
const newLocation = await sourceMaps.getOriginalLocation(
newGeneratedLocation
);
const symbols = getSymbols(getState(), source);
const astLocation = await getASTLocation(source, symbols, newLocation);
const astLocation = await getASTLocation(source, symbols, location);
const originalText = getTextAtPosition(source, location);
const text = getTextAtPosition(generatedSource, newGeneratedLocation);
const text = getTextAtPosition(generatedSource, generatedLocation);
const newBreakpoint = {
id: makeBreakpointId(generatedLocation),
disabled: false,
loading: false,
options: breakpoint.options,
location: newLocation,
location,
astLocation,
generatedLocation: newGeneratedLocation,
generatedLocation,
text,
originalText
};
assertBreakpoint(newBreakpoint);
const previousLocation = locationMoved(location, newLocation)
? location
: null;
return {
breakpoint: newBreakpoint,
previousLocation
};
return newBreakpoint;
}
export function addHiddenBreakpoint(location: SourceLocation) {
@ -144,22 +127,26 @@ export function enableBreakpoint(breakpoint: Breakpoint) {
};
}
/**
* Add a new breakpoint
*
* @memberof actions/breakpoints
* @static
* @param {BreakpointOptions} options Any options for the new breakpoint.
*/
export function addBreakpoint(
location: SourceLocation,
options: BreakpointOptions = {}
) {
return ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
return async ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
recordEvent("add_breakpoint");
let breakpointPosition = location;
if (features.columnBreakpoints && location.column === undefined) {
await dispatch(setBreakpointPositions(location));
breakpointPosition = getFirstVisibleBreakpointPosition(
getState(),
location
);
}
const breakpoint = createBreakpoint(location, options);
if (!breakpointPosition) {
return;
}
const breakpoint = createBreakpoint(breakpointPosition, options);
return dispatch({
type: "ADD_BREAKPOINT",

Просмотреть файл

@ -0,0 +1,37 @@
/* 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/>. */
// @flow
import {
getSourceActors,
getBreakpointPositionsForLine
} from "../../selectors";
import { makeSourceActorLocation } from "../../utils/breakpoint";
import type { SourceLocation } from "../../types";
import type { ThunkArgs } from "../../actions/types";
export function setBreakpointPositions(location: SourceLocation) {
return async ({ getState, dispatch, client }: ThunkArgs) => {
if (
getBreakpointPositionsForLine(
getState(),
location.sourceId,
location.line
)
) {
return;
}
const sourceActors = getSourceActors(getState(), location.sourceId);
const sourceActor = sourceActors[0];
const sourceActorLocation = makeSourceActorLocation(sourceActor, location);
const positions = await client.getBreakpointPositions(sourceActorLocation);
return dispatch({ type: "ADD_BREAKPOINT_POSITIONS", positions, location });
};
}

Просмотреть файл

@ -9,6 +9,7 @@ DIRS += [
DebuggerModules(
'addBreakpoint.js',
'breakpointPositions.js',
'index.js',
'remapLocations.js',
'syncBreakpoint.js',

Просмотреть файл

@ -3,6 +3,8 @@
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
// @flow
import { setBreakpointPositions } from "./breakpointPositions";
import {
locationMoved,
createBreakpoint,
@ -16,6 +18,8 @@ import { getGeneratedLocation } from "../../utils/source-maps";
import { getTextAtPosition } from "../../utils/source";
import { originalToGeneratedId, isOriginalId } from "devtools-source-map";
import { getSource, getSourceActors } from "../../selectors";
import { features } from "../../utils/prefs";
import type { ThunkArgs, Action } from "../types";
import type {
@ -75,6 +79,7 @@ export async function syncBreakpointPromise(
getState: Function,
client: Object,
sourceMaps: Object,
dispatch: Function,
sourceId: SourceId,
pendingBreakpoint: PendingBreakpoint
): Promise<BreakpointSyncData | null> {
@ -121,10 +126,19 @@ export async function syncBreakpointPromise(
);
const sourceActors = getSourceActors(getState(), sourceId);
let possiblePosition = true;
if (features.columnBreakpoints && generatedLocation.column != undefined) {
const { positions } = await dispatch(
setBreakpointPositions(generatedLocation)
);
if (!positions.includes(generatedLocation.column)) {
possiblePosition = false;
}
}
/** ******* CASE 1: No server change ***********/
// early return if breakpoint is disabled or we are in the sameLocation
if (pendingBreakpoint.disabled || isSameLocation) {
if (possiblePosition && (pendingBreakpoint.disabled || isSameLocation)) {
// Make sure the breakpoint is installed on all source actors.
if (!pendingBreakpoint.disabled) {
for (const sourceActor of sourceActors) {
@ -166,42 +180,33 @@ export async function syncBreakpointPromise(
}
}
if (!possiblePosition || !scopedGeneratedLocation.line) {
return { previousLocation, breakpoint: null };
}
/** ******* Case 2: Add New Breakpoint ***********/
// If we are not disabled, set the breakpoint on the server and get
// that info so we can set it on our breakpoints.
if (!scopedGeneratedLocation.line) {
return { previousLocation, breakpoint: null };
}
const newGeneratedLocation = { ...scopedGeneratedLocation };
for (const sourceActor of sourceActors) {
const sourceActorLocation = makeSourceActorLocation(
sourceActor,
scopedGeneratedLocation
);
const { actualLocation } = await client.setBreakpoint(
await client.setBreakpoint(
sourceActorLocation,
pendingBreakpoint.options,
isOriginalId(sourceId)
);
newGeneratedLocation.line = actualLocation.line;
newGeneratedLocation.column = actualLocation.column;
}
// the breakpoint might have slid server side, so we want to get the location
// based on the server's return value
const newLocation = await sourceMaps.getOriginalLocation(
newGeneratedLocation
);
const originalText = getTextAtPosition(source, newLocation);
const text = getTextAtPosition(generatedSource, newGeneratedLocation);
const originalText = getTextAtPosition(source, scopedLocation);
const text = getTextAtPosition(generatedSource, scopedGeneratedLocation);
return createSyncData(
pendingBreakpoint,
newLocation,
newGeneratedLocation,
scopedLocation,
scopedGeneratedLocation,
previousLocation,
text,
originalText
@ -226,6 +231,7 @@ export function syncBreakpoint(
getState,
client,
sourceMaps,
dispatch,
sourceId,
pendingBreakpoint
);

Просмотреть файл

@ -1,40 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`breakpoints adding a breakpoint to an invalid location adds only one breakpoint with a corrected location 1`] = `
Object {
"astLocation": Object {
"index": 0,
"name": undefined,
"offset": Object {
"line": 7,
"sourceId": "a",
"sourceUrl": "http://localhost:8000/examples/a",
},
},
"disabled": false,
"generatedLocation": Object {
"column": undefined,
"line": 7,
"sourceId": "a",
"sourceUrl": "http://localhost:8000/examples/a",
},
"id": "a:5:",
"loading": false,
"location": Object {
"line": 7,
"sourceId": "a",
"sourceUrl": "http://localhost:8000/examples/a",
},
"options": Object {
"condition": null,
"hidden": false,
"logValue": null,
},
"originalText": "",
"text": "",
}
`;
exports[`breakpoints should add a breakpoint 1`] = `
Array [
Object {
@ -51,7 +16,6 @@ Array [
},
"disabled": false,
"generatedLocation": Object {
"column": undefined,
"line": 2,
"sourceId": "a",
"sourceUrl": "http://localhost:8000/examples/a",
@ -106,7 +70,6 @@ Object {
},
"disabled": false,
"generatedLocation": Object {
"column": undefined,
"line": 1,
"sourceId": "a.js",
"sourceUrl": "http://localhost:8000/examples/a.js",
@ -145,7 +108,6 @@ Array [
},
"disabled": true,
"generatedLocation": Object {
"column": undefined,
"line": 5,
"sourceId": "a",
"sourceUrl": "http://localhost:8000/examples/a",

Просмотреть файл

@ -179,7 +179,7 @@ Object {
"column": undefined,
"line": 3,
"sourceId": "magic.js",
"sourceUrl": "http://localhost:8000/magic.js",
"sourceUrl": "http://localhost:8000/examples/magic.js",
},
"options": Object {
"condition": null,

Просмотреть файл

@ -12,10 +12,7 @@ import {
getTelemetryEvents
} from "../../../utils/test-head";
import {
simulateCorrectThreadClient,
simpleMockThreadClient
} from "../../tests/helpers/threadClient.js";
import { simpleMockThreadClient } from "../../tests/helpers/threadClient.js";
describe("breakpoints", () => {
it("should add a breakpoint", async () => {
@ -68,7 +65,7 @@ describe("breakpoints", () => {
const csr = makeSource("a");
await dispatch(actions.newSource(csr));
await dispatch(actions.loadSourceText(csr.source));
const { breakpoint } = await dispatch(actions.addBreakpoint(loc1));
const breakpoint = await dispatch(actions.addBreakpoint(loc1));
await dispatch(actions.disableBreakpoint(breakpoint));
expect(selectors.getBreakpointCount(getState())).toEqual(1);
@ -98,31 +95,6 @@ describe("breakpoints", () => {
expect(selectors.getBreakpointCount(getState())).toEqual(1);
});
describe("adding a breakpoint to an invalid location", () => {
it("adds only one breakpoint with a corrected location", async () => {
const invalidLocation = {
sourceId: "a",
line: 5,
sourceUrl: "http://localhost:8000/examples/a"
};
const {
correctedThreadClient,
correctedLocation
} = simulateCorrectThreadClient(2, invalidLocation);
const { dispatch, getState } = createStore(correctedThreadClient);
const csr = makeSource("a");
await dispatch(actions.newSource(csr));
await dispatch(actions.loadSourceText(csr.source));
await dispatch(actions.addBreakpoint(invalidLocation));
const state = getState();
expect(selectors.getBreakpointCount(state)).toEqual(1);
const bp = selectors.getBreakpoint(state, correctedLocation);
expect(bp).toMatchSnapshot();
});
});
it("should remove a breakpoint", async () => {
const { dispatch, getState } = createStore(simpleMockThreadClient);
@ -181,7 +153,7 @@ describe("breakpoints", () => {
await dispatch(actions.newSource(bCSR));
await dispatch(actions.loadSourceText(bCSR.source));
const { breakpoint } = await dispatch(actions.addBreakpoint(loc1));
const breakpoint = await dispatch(actions.addBreakpoint(loc1));
await dispatch(actions.addBreakpoint(loc2));
await dispatch(actions.disableBreakpoint(breakpoint));
@ -202,7 +174,7 @@ describe("breakpoints", () => {
await dispatch(actions.newSource(aCSR));
await dispatch(actions.loadSourceText(aCSR.source));
const { breakpoint } = await dispatch(actions.addBreakpoint(loc));
const breakpoint = await dispatch(actions.addBreakpoint(loc));
await dispatch(actions.disableBreakpoint(breakpoint));
let bp = selectors.getBreakpoint(getState(), loc);
@ -338,7 +310,7 @@ describe("breakpoints", () => {
};
await dispatch(actions.newSource(makeSource("a")));
const { breakpoint } = await dispatch(actions.addBreakpoint(loc));
const breakpoint = await dispatch(actions.addBreakpoint(loc));
await dispatch(actions.disableBreakpoint(breakpoint));
const bp = selectors.getBreakpoint(getState(), loc);

Просмотреть файл

@ -135,6 +135,7 @@ describe("loading the debugger", () => {
getState,
threadClient,
sourceMaps,
dispatch,
reloadedSource.source.id,
pendingBreakpoint()
);
@ -165,6 +166,7 @@ describe("loading the debugger", () => {
getState,
threadClient,
sourceMaps,
dispatch,
reloadedSource.source.id,
pendingBreakpoint()
);
@ -209,6 +211,7 @@ describe("reloading debuggee", () => {
getState,
threadClient,
sourceMaps,
dispatch,
reloadedSource.source.id,
pendingBreakpoint({ location: loc1 })
);
@ -252,6 +255,7 @@ describe("reloading debuggee", () => {
getState,
threadClient,
sourceMaps,
dispatch,
reloadedSource.source.id,
pendingBreakpoint()
);
@ -279,7 +283,7 @@ describe("reloading debuggee", () => {
column: undefined
};
const { breakpoint } = await dispatch(actions.addBreakpoint(location));
const breakpoint = await dispatch(actions.addBreakpoint(location));
await dispatch(actions.disableBreakpoint(breakpoint));
(getGeneratedLocation: any).mockImplementationOnce(() =>

Просмотреть файл

@ -1,71 +0,0 @@
/* 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/>. */
import {
createStore,
selectors,
actions,
makeSource,
waitForState
} from "../../../utils/test-head";
import { generateBreakpoint } from "../../tests/helpers/breakpoints.js";
import { simpleMockThreadClient } from "../../tests/helpers/threadClient.js";
describe("toggleBreakpointsAtLine", () => {
it("removes all breakpoints on a given line", async () => {
const store = createStore(simpleMockThreadClient);
const { dispatch } = store;
const source = makeSource("foo.js");
await dispatch(actions.newSource(source));
await dispatch(actions.loadSourceText(source));
await Promise.all([
dispatch(
actions.addBreakpoint(generateBreakpoint("foo.js", 5, 1).location)
),
dispatch(
actions.addBreakpoint(generateBreakpoint("foo.js", 5, 2).location)
),
dispatch(
actions.addBreakpoint(generateBreakpoint("foo.js", 5, 3).location)
)
]);
await dispatch(actions.selectLocation({ sourceId: "foo.js" }));
await waitForState(store, state => selectors.hasSymbols(state, source));
await dispatch(actions.toggleBreakpointsAtLine(5));
await waitForState(
store,
state => selectors.getBreakpointCount(state) === 0
);
});
it("removes all breakpoints on an empty line", async () => {
const store = createStore(simpleMockThreadClient);
const { dispatch } = store;
const source = makeSource("foo.js");
await dispatch(actions.newSource(source));
await dispatch(actions.loadSourceText(makeSource("foo.js")));
await dispatch(actions.addBreakpoint({ sourceId: source.id, line: 3 }));
await dispatch(actions.selectLocation({ sourceId: "foo.js" }));
await waitForState(store, state =>
selectors.hasPausePoints(state, source.id)
);
await dispatch(actions.toggleBreakpointsAtLine(3));
await waitForState(
store,
state => selectors.getBreakpointCount(state) === 0
);
});
});

Просмотреть файл

@ -8,7 +8,8 @@ import {
isEvaluatingExpression,
getSelectedFrame,
getSources,
getLastCommand
getLastCommand,
wasStepping
} from "../../selectors";
import { mapFrames } from ".";
@ -81,7 +82,10 @@ export function paused(pauseInfo: Pause) {
await dispatch(selectLocation(selectedFrame.location));
}
dispatch(togglePaneCollapse("end", false));
if (!wasStepping(getState())) {
dispatch(togglePaneCollapse("end", false));
}
await dispatch(fetchScopes());
// Run after fetching scoping data so that it may make use of the sourcemap

Просмотреть файл

@ -23,7 +23,7 @@ export function resumed(packet: ResumedPacket) {
const wasPausedInEval = inDebuggerEval(why);
const wasStepping = isStepping(getState());
dispatch({ type: "RESUME", thread: packet.from });
dispatch({ type: "RESUME", thread: packet.from, wasStepping });
if (!wasStepping && !wasPausedInEval) {
await dispatch(evaluateExpressions());

Просмотреть файл

@ -28,43 +28,13 @@ Object {
}
`;
exports[`invalid breakpoint location a corrected corresponding pending breakpoint is added 1`] = `
Object {
"astLocation": Object {
"index": 0,
"name": undefined,
"offset": Object {
"column": 0,
"line": 7,
"sourceId": "foo.js",
"sourceUrl": "http://localhost:8000/examples/foo.js",
},
},
"disabled": false,
"generatedLocation": Object {
"column": 0,
"line": 7,
"sourceUrl": "http://localhost:8000/examples/foo.js",
},
"location": Object {
"column": 0,
"line": 7,
"sourceUrl": "http://localhost:8000/examples/foo.js",
},
"options": Object {
"condition": null,
"hidden": false,
"logValue": null,
},
}
`;
exports[`when adding breakpoints a corresponding pending breakpoint should be added 1`] = `
Object {
"astLocation": Object {
"index": 0,
"name": undefined,
"offset": Object {
"column": 0,
"line": 5,
"sourceId": "foo.js/originalSource",
"sourceUrl": "http://localhost:8000/examples/foo.js",
@ -77,7 +47,7 @@ Object {
"sourceUrl": "http://localhost:8000/examples/foo.js",
},
"location": Object {
"column": undefined,
"column": 0,
"line": 5,
"sourceUrl": "http://localhost:8000/examples/foo.js",
},
@ -95,6 +65,7 @@ Object {
"index": 0,
"name": undefined,
"offset": Object {
"column": 0,
"line": 5,
"sourceId": "foo/originalSource",
"sourceUrl": "http://localhost:8000/examples/foo",
@ -107,7 +78,7 @@ Object {
"sourceUrl": "http://localhost:8000/examples/foo",
},
"location": Object {
"column": undefined,
"column": 0,
"line": 5,
"sourceUrl": "http://localhost:8000/examples/foo",
},
@ -125,6 +96,7 @@ Object {
"index": 0,
"name": undefined,
"offset": Object {
"column": 0,
"line": 5,
"sourceId": "foo2/originalSource",
"sourceUrl": "http://localhost:8000/examples/foo2",
@ -137,7 +109,7 @@ Object {
"sourceUrl": "http://localhost:8000/examples/foo2",
},
"location": Object {
"column": undefined,
"column": 0,
"line": 5,
"sourceUrl": "http://localhost:8000/examples/foo2",
},

Просмотреть файл

@ -4,10 +4,7 @@
// @flow
import { makeBreakpointActorId } from "../../../utils/breakpoint";
import type {
SourceLocation,
SourceActor,
SourceActorLocation,
BreakpointOptions
@ -65,39 +62,6 @@ export const simpleMockThreadClient = {
})
};
// Breakpoint Sliding
function generateCorrectingThreadClient(offset = 0) {
return {
getBreakpointByLocation: (jest.fn(): any),
setBreakpoint: (location: SourceActorLocation, condition: string) => {
const actualLocation = { ...location, line: location.line + offset };
return Promise.resolve({
id: makeBreakpointActorId(location),
actualLocation,
condition
});
},
sourceContents: ({ source }: SourceActor) =>
Promise.resolve(createSource(source))
};
}
/* in some cases, a breakpoint may be added, but the source will respond
* with a different breakpoint location. This is due to the breakpoint being
* added between functions, or somewhere that doesnt make sense. This function
* simulates that behavior.
* */
export function simulateCorrectThreadClient(
offset: number,
location: SourceLocation
) {
const correctedThreadClient = generateCorrectingThreadClient(offset);
const offsetLine = { line: location.line + offset };
const correctedLocation = { ...location, ...offsetLine };
return { correctedThreadClient, correctedLocation };
}
// sources and tabs
export const sourceThreadClient = {
sourceContents: function({

Просмотреть файл

@ -10,10 +10,7 @@ import {
mockPendingBreakpoint
} from "./helpers/breakpoints.js";
import {
simulateCorrectThreadClient,
simpleMockThreadClient
} from "./helpers/threadClient.js";
import { simpleMockThreadClient } from "./helpers/threadClient.js";
import { asyncStore } from "../../utils/prefs";
@ -45,8 +42,7 @@ import {
selectors,
actions,
makeOriginalSource,
waitForState,
makeSource
waitForState
} from "../../utils/test-head";
import { makePendingLocationId } from "../../utils/breakpoint";
@ -350,31 +346,3 @@ describe("adding sources", () => {
expect(selectors.getBreakpointCount(getState())).toEqual(1);
});
});
describe("invalid breakpoint location", () => {
it("a corrected corresponding pending breakpoint is added", async () => {
// setup
const bp = generateBreakpoint("foo.js");
const {
correctedThreadClient,
correctedLocation
} = simulateCorrectThreadClient(2, bp.location);
const { dispatch, getState } = createStore(correctedThreadClient);
const correctedPendingId = makePendingLocationId(correctedLocation);
// test
const csr = makeSource("foo.js");
await dispatch(actions.newSource(csr));
await dispatch(actions.loadSourceText(csr.source));
// Fixup the breakpoint so that its location can be loaded.
bp.location.sourceId = "foo.js";
bp.generatedLocation = { ...bp.location };
await dispatch(actions.addBreakpoint(bp.location));
const pendingBps = selectors.getPendingBreakpoints(getState());
const pendingBp = pendingBps[correctedPendingId];
expect(pendingBp).toMatchSnapshot();
});
});

Просмотреть файл

@ -1,22 +0,0 @@
/* 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/>. */
import { actions, createStore } from "../../utils/test-head";
const threadClient = {
evaluate: jest.fn()
};
describe("toolbox", () => {
describe("evaluate in console", () => {
it("variable", () => {
const { dispatch } = createStore(threadClient);
dispatch(actions.evaluateInConsole("foo"));
expect(threadClient.evaluate).toBeCalledWith(
'console.log("foo"); console.log(foo)',
{ frameId: null, thread: "UnknownThread" }
);
});
});
});

Просмотреть файл

@ -4,15 +4,15 @@
// @flow
import type { Breakpoint, SourceLocation, XHRBreakpoint } from "../../types";
import type {
Breakpoint,
SourceLocation,
XHRBreakpoint,
BreakpointLinePositions
} from "../../types";
import type { PromiseAction } from "../utils/middleware/promise";
type AddBreakpointResult = {
previousLocation: SourceLocation,
breakpoint: Breakpoint
};
export type BreakpointAction =
| PromiseAction<
{|
@ -20,7 +20,7 @@ export type BreakpointAction =
+breakpoint: Breakpoint,
+condition?: string
|},
AddBreakpointResult
Breakpoint
>
| PromiseAction<{|
+type: "REMOVE_BREAKPOINT",
@ -74,7 +74,7 @@ export type BreakpointAction =
+type: "ENABLE_BREAKPOINT",
+breakpoint: Breakpoint
|},
AddBreakpointResult
Breakpoint
>
| {|
+type: "DISABLE_BREAKPOINT",
@ -91,4 +91,9 @@ export type BreakpointAction =
| {|
+type: "REMAP_BREAKPOINTS",
+breakpoints: Breakpoint[]
|}
| {|
type: "ADD_BREAKPOINT_POSITIONS",
positions: BreakpointLinePositions,
location: SourceLocation
|};

Просмотреть файл

@ -18,7 +18,8 @@ export type PauseAction =
| {|
+type: "RESUME",
+thread: string,
+value: void
+value: void,
+wasStepping: boolean
|}
| {|
+type: "PAUSED",

Просмотреть файл

@ -1,50 +0,0 @@
/* 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/>. */
// @flow
import {
type SymbolDeclaration,
type SymbolDeclarations
} from "../../workers/parser";
import type { Source } from "../../types";
function updateSymbolLocation(
site: SymbolDeclaration,
source: Source,
sourceMaps: any
) {
return sourceMaps
.getGeneratedLocation(
{ ...site.location.start, sourceId: source.id },
source
)
.then(loc => {
return {
...site,
generatedLocation: { line: loc.line, column: loc.column }
};
});
}
export async function updateSymbolLocations(
symbols: SymbolDeclarations,
source: Source,
sourceMaps: any
): Promise<SymbolDeclarations> {
if (!symbols || !symbols.callExpressions) {
return Promise.resolve(symbols);
}
const mappedCallExpressions = await Promise.all(
symbols.callExpressions.map(site =>
updateSymbolLocation(site, source, sourceMaps)
)
);
const newSymbols = { ...symbols, callExpressions: mappedCallExpressions };
return Promise.resolve(newSymbols);
}

Просмотреть файл

@ -32,7 +32,7 @@ import type { PausePointsMap } from "../../workers/parser";
import { makeBreakpointActorId } from "../../utils/breakpoint";
import { createSource, createBreakpointLocation, createWorker } from "./create";
import { createSource, createWorker } from "./create";
import { supportsWorkers, updateWorkerClients } from "./workers";
import { features } from "../../utils/prefs";
@ -189,9 +189,8 @@ function removeXHRBreakpoint(path: string, method: string) {
function setBreakpoint(
location: SourceActorLocation,
options: BreakpointOptions,
noSliding: boolean
): Promise<BreakpointResult> {
options: BreakpointOptions
) {
const sourceThreadClient = lookupThreadClient(location.sourceActor.thread);
const sourceClient = sourceThreadClient.source({
actor: location.sourceActor.actor
@ -202,17 +201,10 @@ function setBreakpoint(
line: location.line,
column: location.column,
options,
noSliding
})
.then(([{ actualLocation }, bpClient]) => {
actualLocation = createBreakpointLocation(location, actualLocation);
const id = makeBreakpointActorId(actualLocation);
.then(([, bpClient]) => {
const id = makeBreakpointActorId(location);
bpClients[id] = bpClient;
bpClient.location.line = actualLocation.line;
bpClient.location.column = actualLocation.column;
return { id, actualLocation };
});
}
@ -456,6 +448,23 @@ function getMainThread() {
return threadClient.actor;
}
async function getBreakpointPositions(
location: SourceActorLocation
): Promise<Array<Number>> {
const {
sourceActor: { thread, actor },
line
} = location;
const sourceThreadClient = lookupThreadClient(thread);
const sourceClient = sourceThreadClient.source({ actor });
const { positions } = await sourceClient.getBreakpointPositionsCompressed({
start: { line },
end: { line }
});
return positions ? positions[line] : [];
}
const clientCommands = {
autocomplete,
blackBox,
@ -476,6 +485,7 @@ const clientCommands = {
sourceContents,
getSourceForActor,
getBreakpointByLocation,
getBreakpointPositions,
setBreakpoint,
setXHRBreakpoint,
removeXHRBreakpoint,

Просмотреть файл

@ -5,7 +5,7 @@
// @flow
// This module converts Firefox specific types to the generic types
import type { Frame, Source, SourceActorLocation, ThreadId } from "../../types";
import type { Frame, Source, ThreadId } from "../../types";
import type {
PausedPacket,
FramesResponse,
@ -96,25 +96,6 @@ export function createPause(
};
}
// Firefox only returns `actualLocation` if it actually changed,
// but we want it always to exist. Format `actualLocation` if it
// exists, otherwise use `location`.
export function createBreakpointLocation(
location: SourceActorLocation,
actualLocation?: Object
): SourceActorLocation {
if (!actualLocation) {
return location;
}
return {
...location,
line: actualLocation.line,
column: actualLocation.column
};
}
export function createWorker(actor: string, url: string) {
return {
actor,

Просмотреть файл

@ -330,9 +330,12 @@ export type SourceClient = {
setBreakpoint: ({
line: number,
column: ?number,
condition: ?string,
noSliding: boolean
condition: ?string
}) => Promise<BreakpointResponse>,
getBreakpointPositionsCompressed: (range: {
start: { line: number },
end: { line: number }
}) => Promise<any>,
prettyPrint: number => Promise<*>,
disablePrettyPrint: () => Promise<*>,
blackBox: (range?: Range) => Promise<*>,
@ -398,7 +401,7 @@ export type BreakpointClient = {
line: number,
column: ?number
},
setOptions: (BreakpointOptions) => Promise<BreakpointClient>,
setOptions: BreakpointOptions => Promise<BreakpointClient>,
// request: any,
source: SourceClient,
options: BreakpointOptions

Просмотреть файл

@ -1,238 +0,0 @@
/* 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/>. */
import React, { Component } from "react";
import { connect } from "react-redux";
import { range, keyBy, isEqualWith, uniqBy, groupBy, flatten } from "lodash";
import CallSite from "./CallSite";
import {
getSelectedSource,
getSymbols,
getSelectedLocation,
getBreakpointsForSource
} from "../../selectors";
import { getTokenLocation } from "../../utils/editor";
import { isWasm } from "../../utils/wasm";
import actions from "../../actions";
function getCallSiteAtLocation(callSites, location) {
return callSites.find(callSite =>
isEqualWith(callSite.location, location, (cloc, loc) => {
return (
loc.line === cloc.start.line &&
(loc.column >= cloc.start.column && loc.column <= cloc.end.column)
);
})
);
}
class CallSites extends Component {
props: {
symbols: Array<Symbol>,
callSites: Array<Symbol>,
editor: Object,
breakpoints: Map,
addBreakpoint: Function,
removeBreakpoint: Function,
selectedSource: Object,
selectedLocation: Object
};
componentDidMount() {
const { editor } = this.props;
const codeMirrorWrapper = editor.codeMirror.getWrapperElement();
codeMirrorWrapper.addEventListener("click", e => this.onTokenClick(e));
}
componentWillUnmount() {
const { editor } = this.props;
const codeMirrorWrapper = editor.codeMirror.getWrapperElement();
codeMirrorWrapper.removeEventListener("click", e => this.onTokenClick(e));
}
onTokenClick(e) {
const { target } = e;
const { editor, selectedLocation } = this.props;
if (
!target.classList.contains("call-site") &&
!target.classList.contains("call-site-bp")
) {
return;
}
const { sourceId } = selectedLocation;
const { line, column } = getTokenLocation(editor.codeMirror, target);
this.toggleBreakpoint(line, isWasm(sourceId) ? undefined : column);
}
toggleBreakpoint(line, column = undefined) {
const {
selectedSource,
selectedLocation,
addBreakpoint,
removeBreakpoint,
callSites
} = this.props;
const callSite = getCallSiteAtLocation(callSites, { line, column });
if (!callSite) {
return;
}
const bp = callSite.breakpoint;
if ((bp && bp.loading) || !selectedLocation || !selectedSource) {
return;
}
const { sourceId } = selectedLocation;
if (bp) {
// NOTE: it's possible the breakpoint has slid to a column
column = column || bp.location.column;
removeBreakpoint({
sourceId: sourceId,
line: line,
column
});
} else {
addBreakpoint({
sourceId: sourceId,
sourceUrl: selectedSource.url,
line: line,
column: column
});
}
}
// Return the call sites that are on the same line as an
// existing line breakpoint
filterCallSitesByLineNumber() {
const { callSites, breakpoints } = this.props;
// Get unique lines from breakpoints so we can filter out unwated call sites
const uniqueBreakpointLines = new Set(
breakpoints.map(bp => bp.location.line)
);
// Get call sites based on activated breakpoint lines
const callSitesInRange = callSites.filter(({ location }) =>
uniqueBreakpointLines.has(location.start.line)
);
// Group call sites by line
const callSitesByLineObj = groupBy(callSitesInRange, "location.start.line");
// Per group, ensure all call sites are unique
return flatten(
Object.values(callSitesByLineObj).map(arr => {
const uniques = uniqBy(
arr,
site =>
`${site.generatedLocation.line}:${site.generatedLocation.column}`
);
// Only return call sites for a line when more than 1 is found
return uniques.length > 1 ? uniques : [];
})
);
}
render() {
const { editor, callSites, selectedSource, breakpoints } = this.props;
if (!callSites || breakpoints.length === 0) {
return null;
}
const callSitesFiltered = this.filterCallSitesByLineNumber();
let sites;
editor.codeMirror.operation(() => {
const childCallSites = callSitesFiltered.map((callSite, index) => {
const props = {
key: index,
callSite,
editor,
source: selectedSource,
breakpoint: callSite.breakpoint,
showCallSite: true
};
return <CallSite {...props} />;
});
sites = <div>{childCallSites}</div>;
});
return sites;
}
}
function getCallSites(symbols, breakpoints) {
if (!symbols || !symbols.callExpressions) {
return;
}
const callSites = symbols.callExpressions;
// NOTE: we create a breakpoint map keyed on location
// to speed up the lookups. Hopefully we'll fix the
// inconsistency with column offsets so that we can expect
// a breakpoint to be added at the beginning of a call expression.
const bpLocationMap = keyBy(breakpoints, ({ location }) =>
locationKey(location)
);
function locationKey({ line, column }) {
return `${line}/${column}`;
}
function findBreakpoint(callSite) {
const {
location: { start, end }
} = callSite;
const breakpointId = range(start.column - 1, end.column)
.map(column => locationKey({ line: start.line, column }))
.find(key => bpLocationMap[key]);
if (breakpointId) {
return bpLocationMap[breakpointId];
}
}
return callSites
.filter(({ location }) => location.start.line === location.end.line)
.map(callSite => ({ ...callSite, breakpoint: findBreakpoint(callSite) }));
}
const mapStateToProps = state => {
const selectedLocation = getSelectedLocation(state);
const selectedSource = getSelectedSource(state);
const sourceId = selectedLocation && selectedLocation.sourceId;
const symbols = getSymbols(state, selectedSource);
const breakpoints = getBreakpointsForSource(state, sourceId);
return {
selectedLocation,
selectedSource,
callSites: getCallSites(symbols, breakpoints),
breakpoints: breakpoints
};
};
const { addBreakpoint, removeBreakpoint } = actions;
const mapDispatchToProps = { addBreakpoint, removeBreakpoint };
export default connect(
mapStateToProps,
mapDispatchToProps
)(CallSites);

Просмотреть файл

@ -1,216 +0,0 @@
/* 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/>. */
import { Component } from "react";
import { showMenu } from "devtools-contextmenu";
import { connect } from "../../utils/connect";
import { lineAtHeight } from "../../utils/editor";
import { features } from "../../utils/prefs";
import {
getContextMenu,
getEmptyLines,
getSelectedLocation,
getSelectedSource,
getVisibleBreakpoints,
isPaused as getIsPaused
} from "../../selectors";
import actions from "../../actions";
type Props = {
setContextMenu: Function,
contextMenu: Object
};
export function gutterMenu({
breakpoint,
line,
column,
event,
isPaused,
toggleBreakpoint,
openConditionalPanel,
toggleDisabledBreakpoint,
isCbPanelOpen,
closeConditionalPanel,
continueToHere,
sourceId
}) {
event.stopPropagation();
event.preventDefault();
const gutterItems = {
addBreakpoint: {
id: "node-menu-add-breakpoint",
label: L10N.getStr("editor.addBreakpoint")
},
addLogPoint: {
id: "node-menu-add-log-point",
label: L10N.getStr("editor.addLogPoint")
},
addConditional: {
id: "node-menu-add-conditional-breakpoint",
label: L10N.getStr("editor.addConditionBreakpoint")
},
removeBreakpoint: {
id: "node-menu-remove-breakpoint",
label: L10N.getStr("editor.removeBreakpoint")
},
editLogPoint: {
id: "node-menu-edit-log-point",
label: L10N.getStr("editor.editLogPoint")
},
editConditional: {
id: "node-menu-edit-conditional-breakpoint",
label: L10N.getStr("editor.editConditionBreakpoint")
},
enableBreakpoint: {
id: "node-menu-enable-breakpoint",
label: L10N.getStr("editor.enableBreakpoint")
},
disableBreakpoint: {
id: "node-menu-disable-breakpoint",
label: L10N.getStr("editor.disableBreakpoint")
},
continueToHere: {
id: "node-menu-continue-to-here",
label: L10N.getStr("editor.continueToHere.label")
}
};
const toggleBreakpointItem = {
accesskey: L10N.getStr("shortcuts.toggleBreakpoint.accesskey"),
disabled: false,
click: () => {
toggleBreakpoint(line, column);
if (isCbPanelOpen) {
closeConditionalPanel();
}
},
accelerator: L10N.getStr("toggleBreakpoint.key"),
...(breakpoint ? gutterItems.removeBreakpoint : gutterItems.addBreakpoint)
};
const logPoint = {
accesskey: L10N.getStr("editor.addLogPoint.accesskey"),
disabled: false,
click: () =>
openConditionalPanel(
breakpoint ? breakpoint.location : { line, column, sourceId },
true
),
accelerator: L10N.getStr("toggleCondPanel.key"),
...(breakpoint && breakpoint.condition
? gutterItems.editLogPoint
: gutterItems.addLogPoint)
};
const conditionalBreakpoint = {
accesskey: L10N.getStr("editor.addConditionBreakpoint.accesskey"),
disabled: false,
// Leaving column undefined so pause points can be detected
click: () =>
openConditionalPanel(
breakpoint ? breakpoint.location : { line, column, sourceId }
),
accelerator: L10N.getStr("toggleCondPanel.key"),
...(breakpoint && breakpoint.condition
? gutterItems.editConditional
: gutterItems.addConditional)
};
let items = [toggleBreakpointItem, conditionalBreakpoint];
if (features.logPoints) {
items.push(logPoint)
}
if (breakpoint && breakpoint.condition) {
const remove = breakpoint.log ? conditionalBreakpoint : logPoint;
items = items.filter(item => item !== remove);
}
if (isPaused) {
const continueToHereItem = {
accesskey: L10N.getStr("editor.continueToHere.accesskey"),
disabled: false,
click: () => continueToHere(line, column),
...gutterItems.continueToHere
};
items.push(continueToHereItem);
}
if (breakpoint) {
const disableBreakpoint = {
accesskey: L10N.getStr("editor.disableBreakpoint.accesskey"),
disabled: false,
click: () => toggleDisabledBreakpoint(line, column),
...(breakpoint.disabled
? gutterItems.enableBreakpoint
: gutterItems.disableBreakpoint)
};
items.push(disableBreakpoint);
}
showMenu(event, items);
}
class GutterContextMenuComponent extends Component {
props: Props;
shouldComponentUpdate(nextProps) {
return nextProps.contextMenu.type === "Gutter";
}
componentWillUpdate(nextProps) {
// clear the context menu since it is open
this.props.setContextMenu("", null);
return this.showMenu(nextProps);
}
showMenu(nextProps) {
const { contextMenu, ...props } = nextProps;
const { event } = contextMenu;
const sourceId = props.selectedSource ? props.selectedSource.id : "";
const line = lineAtHeight(props.editor, sourceId, event);
const column = props.editor.codeMirror.coordsChar({
left: event.x,
top: event.y
}).ch;
const breakpoint = nextProps.breakpoints.find(
bp => bp.location.line === line && bp.location.column === column
);
// Allow getFirstVisiblePausePoint to find the best first breakpoint
// position by not providing an explicit column number
if (features.columnBreakpoints && !breakpoint && column === 0) {
column = undefined;
}
gutterMenu({ event, sourceId, line, column, breakpoint, ...props });
}
render() {
return null;
}
}
const mapStateToProps = state => {
const selectedSource = getSelectedSource(state);
return {
selectedLocation: getSelectedLocation(state),
selectedSource: selectedSource,
breakpoints: getVisibleBreakpoints(state),
isPaused: getIsPaused(state),
contextMenu: getContextMenu(state),
emptyLines: getEmptyLines(state, selectedSource.id)
};
};
export default connect(
mapStateToProps,
actions
)(GutterContextMenuComponent);

Просмотреть файл

@ -1,59 +0,0 @@
/* 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/>. */
// @flow
import { Component } from "react";
const markerEl = document.createElement("div");
function makeMarker() {
const marker = markerEl.cloneNode(true);
marker.className = "editor hit-marker";
return marker;
}
type Props = {
hitData: { [string]: any },
editor: any
};
class HitMarker extends Component<Props> {
addMarker() {
const hitData = this.props.hitData;
const line = hitData.line - 1;
this.props.editor.setGutterMarker(line, "hit-markers", makeMarker());
this.props.editor.addLineClass(line, "line", "hit-marker");
}
shouldComponentUpdate(nextProps: any) {
return (
this.props.editor !== nextProps.editor ||
this.props.hitData !== nextProps.hitData
);
}
componentDidMount() {
this.addMarker();
}
componentDidUpdate() {
this.addMarker();
}
componentWillUnmount() {
const hitData = this.props.hitData;
const line = hitData.line - 1;
this.props.editor.setGutterMarker(line, "hit-markers", null);
this.props.editor.removeLineClass(line, "line", "hit-marker");
}
render() {
return null;
}
}
export default HitMarker;

Просмотреть файл

@ -15,6 +15,13 @@
user-select: none;
}
.source-header .command-bar {
flex: initial;
flex-shrink: 0;
border-bottom: 0;
border-inline-start: 1px solid var(--theme-splitter-color);
}
.source-tabs {
max-width: calc(100% - 80px);
align-self: flex-start;
@ -43,7 +50,8 @@
width: 100%;
height: 2px;
background-color: var(--tab-line-color, transparent);
transition: transform 250ms var(--animation-curve), opacity 250ms var(--animation-curve);
transition: transform 250ms var(--animation-curve),
opacity 250ms var(--animation-curve);
opacity: 0;
transform: scaleX(0);
}

Просмотреть файл

@ -7,7 +7,11 @@
import React, { PureComponent } from "react";
import { connect } from "../../utils/connect";
import { getSelectedSource, getSourcesForTabs } from "../../selectors";
import {
getSelectedSource,
getSourcesForTabs,
getIsPaused
} from "../../selectors";
import { isVisible } from "../../utils/ui";
import { getHiddenTabs } from "../../utils/tabs";
@ -21,6 +25,7 @@ import Tab from "./Tab";
import { PaneToggleButton } from "../shared/Button";
import Dropdown from "../shared/Dropdown";
import AccessibleImage from "../shared/AccessibleImage";
import CommandBar from "../SecondaryPanes/CommandBar";
import type { Source } from "../../types";
@ -36,7 +41,8 @@ type Props = {
closeTab: typeof actions.closeTab,
togglePaneCollapse: typeof actions.togglePaneCollapse,
showSource: typeof actions.showSource,
selectSource: typeof actions.selectSource
selectSource: typeof actions.selectSource,
isPaused: boolean
};
type State = {
@ -170,6 +176,15 @@ class Tabs extends PureComponent<Props, State> {
return <Dropdown panel={Panel} icon={icon} />;
}
renderCommandBar() {
const { horizontal, endPanelCollapsed, isPaused } = this.props;
if (!endPanelCollapsed || !isPaused) {
return;
}
return <CommandBar horizontal={horizontal} />;
}
renderStartPanelToggleButton() {
return (
<PaneToggleButton
@ -203,6 +218,7 @@ class Tabs extends PureComponent<Props, State> {
{this.renderTabs()}
{this.renderDropdown()}
{this.renderEndPanelToggleButton()}
{this.renderCommandBar()}
</div>
);
}
@ -210,7 +226,8 @@ class Tabs extends PureComponent<Props, State> {
const mapStateToProps = state => ({
selectedSource: getSelectedSource(state),
tabSources: getSourcesForTabs(state)
tabSources: getSourcesForTabs(state),
isPaused: getIsPaused(state)
});
export default connect(

Просмотреть файл

@ -99,10 +99,6 @@
color: inherit;
}
.sources-list .tree .img.arrow.expanded {
transform: rotate(0deg);
}
.theme-dark .source-list .tree .node.focused {
background-color: var(--theme-tab-toolbar-background);
}

Просмотреть файл

@ -98,7 +98,6 @@ class SourcesTree extends Component<Props, State> {
componentWillReceiveProps(nextProps: Props) {
const {
thread,
projectRoot,
debuggeeUrl,
sources,

Просмотреть файл

@ -196,7 +196,7 @@ describe("SourcesTree", () => {
await component
.find(".sources-list")
.simulate("keydown", { keyCode: 13 });
// expect(props.selectSource).toHaveBeenCalledWith(item.contents.id);
expect(props.selectSource).toHaveBeenCalledWith(item.contents.id);
});
});
@ -370,7 +370,7 @@ function generateDefaults(overrides: Object) {
autoExpandAll: true,
selectSource: jest.fn(),
setExpandedState: jest.fn(),
sources: { FakeThread: defaultSources },
sources: defaultSources,
debuggeeUrl: "http://mdn.com",
clearProjectDirectoryRoot: jest.fn(),
setProjectDirectoryRoot: jest.fn(),

Просмотреть файл

@ -6,10 +6,32 @@ exports[`SourcesTree After changing expanded nodes Shows the tree with four.js,
key="pane"
>
<div
className="no-sources-message"
key="empty"
className="sources-list"
key="tree"
onKeyDown={[Function]}
>
This page has no sources
<ManagedTree
autoExpandAll={false}
autoExpandDepth={0}
expanded={
Array [
"four.js",
"five.js",
"six.js",
]
}
getChildren={[Function]}
getParent={[Function]}
getPath={[Function]}
getRoots={[Function]}
itemHeight={21}
key="full"
onCollapse={[Function]}
onExpand={[Function]}
onFocus={[Function]}
preventBlur={true}
renderItem={[Function]}
/>
</div>
</div>
`;
@ -20,10 +42,25 @@ exports[`SourcesTree Should show the tree with nothing expanded 1`] = `
key="pane"
>
<div
className="no-sources-message"
key="empty"
className="sources-list"
key="tree"
onKeyDown={[Function]}
>
This page has no sources
<ManagedTree
autoExpandAll={false}
autoExpandDepth={1}
getChildren={[Function]}
getParent={[Function]}
getPath={[Function]}
getRoots={[Function]}
itemHeight={21}
key="full"
onCollapse={[Function]}
onExpand={[Function]}
onFocus={[Function]}
preventBlur={true}
renderItem={[Function]}
/>
</div>
</div>
`;
@ -34,10 +71,32 @@ exports[`SourcesTree When loading initial source Shows the tree with one.js, two
key="pane"
>
<div
className="no-sources-message"
key="empty"
className="sources-list"
key="tree"
onKeyDown={[Function]}
>
This page has no sources
<ManagedTree
autoExpandAll={false}
autoExpandDepth={0}
expanded={
Array [
"one.js",
"two.js",
"three.js",
]
}
getChildren={[Function]}
getParent={[Function]}
getPath={[Function]}
getRoots={[Function]}
itemHeight={21}
key="full"
onCollapse={[Function]}
onExpand={[Function]}
onFocus={[Function]}
preventBlur={true}
renderItem={[Function]}
/>
</div>
</div>
`;
@ -48,8 +107,9 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
key="pane"
>
<div
className="no-sources-message"
key="empty"
className="sources-list"
key="tree"
onKeyDown={[Function]}
>
<ManagedTree
autoExpandAll={false}

Просмотреть файл

@ -4,7 +4,7 @@
.frames [role="list"] {
list-style: none;
margin: 0;
margin-top: 4px;
padding: 0;
}
@ -106,7 +106,6 @@
mask-size: 100%;
display: inline-block;
width: 12px;
margin-inline-start: 4px;
}
:root.theme-dark .annotation-logo:not(.angular) svg path {

Просмотреть файл

@ -2,8 +2,8 @@
* 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/>. */
.frames [role="list"] .frames-group .group,
.frames [role="list"] .frames-group .group .location {
.frames ul .frames-group .group,
.frames ul .frames-group .group .location {
font-weight: 500;
cursor: default;
/*
@ -14,30 +14,25 @@
direction: ltr;
}
.frames [role="list"] .frames-group.expanded .group,
.frames [role="list"] .frames-group.expanded .group .location {
.frames ul .frames-group.expanded .group,
.frames ul .frames-group.expanded .group .location {
color: var(--theme-highlight-blue);
}
.frames [role="list"] .frames-group.expanded .react path {
.frames ul .frames-group.expanded .react path {
fill: var(--theme-highlight-blue);
}
.frames [role="list"] .frames-group .frames-list [role="listitem"] {
.frames ul .frames-group .frames-list li {
padding-left: 30px;
}
.frames [role="list"] .frames-group .frames-list {
.frames ul .frames-group .frames-list {
border-top: 1px solid var(--theme-splitter-color);
border-bottom: 1px solid var(--theme-splitter-color);
}
/* We don't want to display those as flex since only the name is displayed */
.frames [role="list"] .frames-group .frames-list [role="listitem"] {
display: block;
}
.frames [role="list"] .frames-group.expanded .badge {
.frames ul .frames-group.expanded .badge {
color: var(--theme-highlight-blue);
}

Просмотреть файл

@ -70,7 +70,7 @@ describe("Frame", () => {
const props = frameProperties(frame, null);
const component = mount(<Frame {...props} />);
expect(component.text()).toBe("\trenderFoo foo-view.js:10\n");
expect(component.text()).toBe("    renderFoo foo-view.js:10");
});
it("full URL", () => {
@ -80,7 +80,7 @@ describe("Frame", () => {
const props = frameProperties(frame, null, { displayFullUrl: true });
const component = mount(<Frame {...props} />);
expect(component.text()).toBe(`renderFoo ${url}:10`);
expect(component.text()).toBe(`    renderFoo ${url}:10`);
});
it("getFrameTitle", () => {

Просмотреть файл

@ -65,6 +65,9 @@ exports[`Group displays a group 1`] = `
<Badge>
1
</Badge>
<br
className="clipboard-only"
/>
</div>
</div>
`;
@ -134,11 +137,16 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
<Badge>
3
</Badge>
<br
className="clipboard-only"
/>
</div>
<div
className="frames-list"
>
<FrameIndent />
<FrameIndent
key="frame-indent-0"
/>
<Frame
copyStackTrace={[MockFunction]}
disableContextMenu={false}
@ -233,7 +241,9 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
toggleBlackBox={[MockFunction]}
toggleFrameworkGrouping={[MockFunction]}
/>
<FrameIndent />
<FrameIndent
key="frame-indent-1"
/>
<Frame
copyStackTrace={[MockFunction]}
disableContextMenu={false}
@ -328,7 +338,9 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
toggleBlackBox={[MockFunction]}
toggleFrameworkGrouping={[MockFunction]}
/>
<FrameIndent />
<FrameIndent
key="frame-indent-2"
/>
<Frame
copyStackTrace={[MockFunction]}
disableContextMenu={false}
@ -492,6 +504,9 @@ exports[`Group renders group with anonymous functions 1`] = `
<Badge>
3
</Badge>
<br
className="clipboard-only"
/>
</div>
</div>
`;
@ -561,11 +576,16 @@ exports[`Group renders group with anonymous functions 2`] = `
<Badge>
3
</Badge>
<br
className="clipboard-only"
/>
</div>
<div
className="frames-list"
>
<FrameIndent />
<FrameIndent
key="frame-indent-0"
/>
<Frame
copyStackTrace={[MockFunction]}
disableContextMenu={false}
@ -659,7 +679,9 @@ exports[`Group renders group with anonymous functions 2`] = `
toggleBlackBox={[MockFunction]}
toggleFrameworkGrouping={[MockFunction]}
/>
<FrameIndent />
<FrameIndent
key="frame-indent-1"
/>
<Frame
copyStackTrace={[MockFunction]}
disableContextMenu={false}
@ -753,7 +775,9 @@ exports[`Group renders group with anonymous functions 2`] = `
toggleBlackBox={[MockFunction]}
toggleFrameworkGrouping={[MockFunction]}
/>
<FrameIndent />
<FrameIndent
key="frame-indent-2"
/>
<Frame
copyStackTrace={[MockFunction]}
disableContextMenu={false}

Просмотреть файл

@ -1,10 +0,0 @@
/* 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/>. */
import type { Frame } from "../../../types";
export type LocalFrame = Frame & {
library: string,
source: Source
};

Просмотреть файл

@ -1,110 +0,0 @@
/* 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/>. */
import React, { PureComponent } from "react";
import { connect } from "../../utils/connect";
import actions from "../../actions";
import { createObjectClient } from "../../client/firefox";
import { getSelectedFrame, getAllPopupObjectProperties } from "../../selectors";
import { objectInspector } from "devtools-reps";
import { isReactComponent } from "../../utils/preview";
import type { Frame } from "../../types";
const {
component: ObjectInspector,
utils: {
createNode,
getChildren,
loadProperties: { loadItemProperties }
}
} = objectInspector;
type Props = {
selectedFrame: Frame,
popupObjectProperties: Object,
setPopupObjectProperties: typeof actions.setPopupObjectProperties,
openElementInInspector: typeof actions.setPopupObjectProperties
};
class FrameworkComponent extends PureComponent<Props> {
async componentWillMount() {
const expression = "this;";
const { selectedFrame, setPopupObjectProperties } = this.props;
const value = selectedFrame.this;
const root = createNode({ name: expression, contents: { value } });
const properties = await loadItemProperties(root, createObjectClient);
if (properties) {
setPopupObjectProperties(value, properties);
}
}
renderReactComponent() {
const {
selectedFrame,
popupObjectProperties,
openElementInInspector
} = this.props;
const expression = "this;";
const value = selectedFrame.this;
const root = {
name: expression,
path: expression,
contents: { value }
};
const loadedRootProperties = popupObjectProperties[value.actor];
if (!loadedRootProperties) {
return null;
}
let roots = getChildren({
item: root,
loadedProperties: new Map([[root.path, loadedRootProperties]])
});
roots = roots.filter(r => ["state", "props"].includes(r.name));
return (
<div className="pane framework-component">
<ObjectInspector
roots={roots}
autoExpandAll={false}
autoExpandDepth={0}
disableWrap={true}
focusable={false}
dimTopLevelWindow={true}
createObjectClient={grip => createObjectClient(grip)}
onDOMNodeClick={grip => openElementInInspector(grip)}
onInspectIconClick={grip => openElementInInspector(grip)}
/>
</div>
);
}
render() {
const { selectedFrame } = this.props;
if (selectedFrame && isReactComponent(selectedFrame.this)) {
return this.renderReactComponent();
}
return null;
}
}
const mapStateToProps = state => ({
selectedFrame: getSelectedFrame(state),
popupObjectProperties: getAllPopupObjectProperties(state)
});
export default connect(
mapStateToProps,
{
setPopupObjectProperties: actions.setPopupObjectProperties,
openElementInInspector: actions.openElementInInspectorCommand
}
)(FrameworkComponent);

Просмотреть файл

@ -7,3 +7,7 @@
background: var(--theme-icon-color);
mask-size: 100%;
}
.img.arrow.arrow.expanded {
transform: rotate(0deg);
}

Просмотреть файл

@ -1,39 +0,0 @@
/* 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/>. */
import { shallow } from "enzyme";
import Svg from "../Svg";
describe("Svg", () => {
it("renders with props", () => {
const wrapper = shallow(
Svg({
name: "webpack",
className: "class",
onClick: () => {},
"aria-label": "label"
})
);
expect(wrapper).toMatchSnapshot();
});
it("render nothing if invalid svg name", () => {
const svg = Svg({ name: "reallyRandomNameHere" });
expect(svg).toBe(null);
});
it("calls onClick method on click", () => {
const onClick = jest.fn();
const wrapper = shallow(
Svg({
name: "webpack",
className: "class",
onClick,
"aria-label": "label"
})
);
wrapper.simulate("click");
expect(onClick).toBeCalledTimes(1);
});
});

Просмотреть файл

@ -1,15 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Svg renders with props 1`] = `
<i
aria-label="label"
className="webpack class"
dangerouslySetInnerHTML={
Object {
"__html": "<svg></svg>",
}
}
onClick={[Function]}
src={null}
/>
`;

Просмотреть файл

@ -232,30 +232,6 @@ export function getPausePoint(
}
}
export function getFirstPausePointLocation(
state: OuterState,
location: SourceLocation
): SourceLocation {
const { sourceId } = location;
const pausePoints = getPausePoints(state, location.sourceId);
if (!pausePoints) {
return location;
}
const pausesAtLine = pausePoints.filter(
point => point.location.line == location.line
);
if (pausesAtLine) {
const values: PausePoint[] = (Object.values(pausesAtLine): any);
const firstPausePoint = values.find(pausePoint => pausePoint.types.break);
if (firstPausePoint) {
return { ...firstPausePoint.location, sourceId };
}
}
return location;
}
export function hasPausePoints(state: OuterState, sourceId: string): boolean {
const pausePoints = getPausePoints(state, sourceId);
return !!pausePoints;

Просмотреть файл

@ -18,7 +18,10 @@ import type {
XHRBreakpoint,
Breakpoint,
BreakpointId,
SourceLocation
SourceLocation,
BreakpointPositions,
BreakpointLinePositions,
BreakpointSourcePositions
} from "../types";
import type { Action, DonePromiseAction } from "../actions/types";
@ -27,7 +30,9 @@ export type XHRBreakpointsList = $ReadOnlyArray<XHRBreakpoint>;
export type BreakpointsState = {
breakpoints: BreakpointsMap,
xhrBreakpoints: XHRBreakpointsList
breakpointPositions: BreakpointPositions,
xhrBreakpoints: XHRBreakpointsList,
breakpointsDisabled: boolean
};
export function initialBreakpointsState(
@ -36,6 +41,7 @@ export function initialBreakpointsState(
return {
breakpoints: {},
xhrBreakpoints: xhrBreakpoints,
breakpointPositions: {},
breakpointsDisabled: false
};
}
@ -104,6 +110,21 @@ function update(
case "DISABLE_XHR_BREAKPOINT": {
return updateXHRBreakpoint(state, action);
}
case "ADD_BREAKPOINT_POSITIONS": {
const {
location: { sourceId, line },
positions
} = action;
const sourcePositions = state.breakpointPositions[sourceId] || {};
return {
...state,
breakpointPositions: {
...state.breakpointPositions,
[sourceId]: { ...sourcePositions, [line]: positions }
}
};
}
}
return state;
@ -186,7 +207,7 @@ function addBreakpoint(state, action): BreakpointsState {
// when the action completes, we can commit the breakpoint
if (action.status === "done") {
const { value } = ((action: any): DonePromiseAction);
return syncBreakpoint(state, value);
return syncBreakpoint(state, { breakpoint: value, previousLocation: null });
}
// Remove the optimistic update
@ -331,4 +352,27 @@ export function getHiddenBreakpoint(state: OuterState): ?Breakpoint {
return breakpoints.find(bp => bp.options.hidden);
}
export function getBreakpointPositions(
state: OuterState
): ?BreakpointPositions {
return state.breakpoints.breakpointPositions;
}
export function getBreakpointPositionsForSource(
state: OuterState,
sourceId: string
): ?BreakpointSourcePositions {
const positions = getBreakpointPositions(state);
return positions && positions[sourceId];
}
export function getBreakpointPositionsForLine(
state: OuterState,
sourceId: string,
line: number
): ?BreakpointLinePositions {
const positions = getBreakpointPositionsForSource(state, sourceId);
return positions ? positions[line] : null;
}
export default update;

Просмотреть файл

@ -69,6 +69,7 @@ type ThreadPauseState = {
shouldPauseOnCaughtExceptions: boolean,
command: Command,
lastCommand: Command,
wasStepping: boolean,
previousLocation: ?MappedLocation,
skipPausing: boolean
};
@ -277,7 +278,10 @@ function update(
if (!action.thread && !state.currentThread) {
return state;
}
return updateThreadState(resumedPauseState);
return updateThreadState({
...resumedPauseState,
wasStepping: !!action.wasStepping
});
case "EVALUATE_EXPRESSION":
return updateThreadState({
@ -359,6 +363,10 @@ export function getLastCommand(state: OuterState, thread: string) {
return getThreadPauseState(state.pause, thread).lastCommand;
}
export function wasStepping(state: OuterState): boolean {
return getCurrentPauseState(state).wasStepping;
}
export function isStepping(state: OuterState) {
return ["stepIn", "stepOver", "stepOut"].includes(getPauseCommand(state));
}

Просмотреть файл

@ -69,15 +69,7 @@ function addBreakpoint(state, action) {
return state;
}
// when the action completes, we can commit the breakpoint
const {
breakpoint,
previousLocation
} = ((action: any): DonePromiseAction).value;
if (previousLocation) {
const previousLocationId = makePendingLocationId(previousLocation);
state = deleteBreakpoint(state, previousLocationId);
}
const breakpoint = ((action: any): DonePromiseAction).value;
const locationId = makePendingLocationId(breakpoint.location);
const pendingBreakpoint = createPendingBreakpoint(breakpoint);

Просмотреть файл

@ -30,7 +30,8 @@ export {
} from "./breakpointAtLocation";
export {
getVisibleBreakpoints,
getFirstVisibleBreakpoints
getFirstVisibleBreakpoints,
getFirstVisibleBreakpointPosition
} from "./visibleBreakpoints";
export { inComponent } from "./inComponent";
export { isSelectedFrameVisible } from "./isSelectedFrameVisible";

Просмотреть файл

@ -7,14 +7,24 @@
import { createSelector } from "reselect";
import { uniqBy } from "lodash";
import { getBreakpointsList } from "../reducers/breakpoints";
import {
getBreakpointsList,
getBreakpointPositionsForLine,
getBreakpointPositions
} from "../reducers/breakpoints";
import { getPausePoints } from "../reducers/ast";
import { getSelectedSource } from "../reducers/sources";
import { sortBreakpoints } from "../utils/breakpoint";
import { getSelectedLocation } from "../utils/source-maps";
import type { Breakpoint, Source } from "../types";
import type { Selector } from "../reducers/types";
import type {
Breakpoint,
Source,
SourceLocation,
BreakpointPositions
} from "../types";
import type { Selector, State } from "../reducers/types";
function isVisible(breakpoint: Breakpoint, selectedSource: Source) {
const location = getSelectedLocation(breakpoint, selectedSource);
@ -27,7 +37,12 @@ function isVisible(breakpoint: Breakpoint, selectedSource: Source) {
export const getVisibleBreakpoints: Selector<?(Breakpoint[])> = createSelector(
getSelectedSource,
getBreakpointsList,
(selectedSource: ?Source, breakpoints: Breakpoint[]) => {
getBreakpointPositions,
(
selectedSource: ?Source,
breakpoints: Breakpoint[],
positions: ?BreakpointPositions
) => {
if (selectedSource == null) {
return null;
}
@ -39,6 +54,33 @@ export const getVisibleBreakpoints: Selector<?(Breakpoint[])> = createSelector(
}
);
export function getFirstVisibleBreakpointPosition(
state: State,
location: SourceLocation
): ?SourceLocation {
const { sourceId, line } = location;
const pausePoints = getPausePoints(state, location.sourceId);
const positions = getBreakpointPositionsForLine(state, sourceId, line);
if (!pausePoints || !positions) {
return null;
}
const pausesAtLine = pausePoints.filter(
p => p.location.line == line && positions.includes(p.location.column)
);
if (pausesAtLine.length > 0) {
const firstPausePoint = pausesAtLine.find(
pausePoint => pausePoint.types.break
);
if (firstPausePoint) {
return { ...firstPausePoint.location, sourceId };
}
}
return location;
}
/*
* Finds the first breakpoint per line, which appear in the selected source.
*/

Просмотреть файл

@ -441,3 +441,8 @@ export type Cancellable = {
export type EventListenerBreakpoints = string[];
export type SourceDocuments = { [string]: Object };
export type BreakpointPosition = { line: number, string: number };
export type BreakpointLinePositions = Array<BreakpointPosition>;
export type BreakpointSourcePositions = { [number]: BreakpointLinePositions };
export type BreakpointPositions = { [string]: BreakpointSourcePositions };

Просмотреть файл

@ -22,6 +22,7 @@ import App from "../components/App";
import { asyncStore, prefs } from "./prefs";
import type { Panel } from "../client/firefox/types";
import typeof SourceMaps from "../../packages/devtools-source-map/src";
function renderPanel(component, store) {
const root = document.createElement("div");
@ -41,7 +42,7 @@ function renderPanel(component, store) {
export function bootstrapStore(
client: any,
sourceMaps: Object,
sourceMaps: SourceMaps,
panel: Panel,
initialState: Object
) {

Просмотреть файл

@ -1,12 +0,0 @@
/* 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/>. */
import { createSelector as reselectCreateSelector } from "reselect";
function createSelector(...args) {
// $FlowFixMe
return reselectCreateSelector(...args);
}
export { createSelector };

Просмотреть файл

@ -16,15 +16,12 @@ import type { Location as BabelLocation } from "@babel/types";
import type { Symbols } from "../reducers/ast";
import type { QuickOpenType } from "../reducers/quick-open";
import type { TabList } from "../reducers/tabs";
import type { SourcesMapByThread } from "../reducers/types";
import type { Source } from "../types";
import type {
SymbolDeclaration,
IdentifierDeclaration
} from "../workers/parser";
import { flatten } from "lodash";
export const MODIFIERS = {
"@": "functions",
"#": "variables",

Просмотреть файл

@ -13,7 +13,6 @@ import type {
Location as BabelLocation
} from "@babel/types";
import { isGeneratedId } from "devtools-source-map";
import getFunctionName from "../utils/getFunctionName";
import { getAst } from "../utils/ast";
@ -153,6 +152,10 @@ type ScopeCollectionVisitorState = {
declarationBindingIds: Set<Node>
};
function isGeneratedId(id: string) {
return !/\/originalSource/.test(id);
}
export function parseSourceScopes(sourceId: SourceId): ?Array<ParsedScope> {
const ast = getAst(sourceId);
if (isEmpty(ast)) {

Просмотреть файл

@ -35,15 +35,6 @@ function enableBreakpoints(dbg, count) {
return enabled;
}
function findBreakpoint(dbg, url, line) {
const {
selectors: { getBreakpoint },
getState
} = dbg;
const source = findSource(dbg, url);
return getBreakpoint(getState(), { sourceId: source.id, line });
}
// Test enabling and disabling a breakpoint using the check boxes
add_task(async function() {
const dbg = await initDebugger("doc-scripts.html", "simple2");

Просмотреть файл

@ -31,15 +31,6 @@ async function enableBreakpoint(dbg, index) {
await enabled;
}
function findBreakpoint(dbg, url, line) {
const {
selectors: { getBreakpoint },
getState
} = dbg;
const source = findSource(dbg, url);
return getBreakpoint(getState(), { sourceId: source.id, line });
}
add_task(async function() {
clearDebuggerPreferences();

Просмотреть файл

@ -30,7 +30,7 @@ add_task(async function() {
await selectSource(dbg, mainSrc);
// Test that breakpoint is not off by a line.
await addBreakpoint(dbg, mainSrc, 4);
await addBreakpoint(dbg, mainSrc, 4, 2);
is(getBreakpointCount(getState()), 1, "One breakpoint exists");
ok(
getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4, column: 2 }),

Просмотреть файл

@ -22,7 +22,7 @@ add_task(async function() {
await selectSource(dbg, sortedSrc);
// Test that breakpoint is not off by a line.
await addBreakpoint(dbg, sortedSrc, 9);
await addBreakpoint(dbg, sortedSrc, 9, 4);
is(getBreakpointCount(getState()), 1, "One breakpoint exists");
ok(
getBreakpoint(getState(), { sourceId: sortedSrc.id, line: 9, column: 4 }),

Просмотреть файл

@ -767,10 +767,13 @@ function findBreakpoint(dbg, url, line) {
if (
Services.prefs.getBoolPref("devtools.debugger.features.column-breakpoints")
) {
column = dbg.selectors.getFirstPausePointLocation(dbg.store.getState(), {
sourceId: source.id,
line
}).column;
({ column } = dbg.selectors.getFirstVisibleBreakpointPosition(
dbg.store.getState(),
{
sourceId: source.id,
line
}
));
}
return getBreakpoint(getState(), { sourceId: source.id, line, column });
}
@ -789,7 +792,7 @@ async function loadAndAddBreakpoint(dbg, filename, line, column) {
await selectSource(dbg, source);
// Test that breakpoint is not off by a line.
await addBreakpoint(dbg, source, line);
await addBreakpoint(dbg, source, line, column);
is(getBreakpointCount(getState()), 1, "One breakpoint exists");
if (!getBreakpoint(getState(), { sourceId: source.id, line, column })) {
@ -1103,7 +1106,7 @@ const selectors = {
scopeValue: i =>
`.scopes-list .tree-node:nth-child(${i}) .object-delimiter + *`,
frame: i => `.frames [role="list"] [role="listitem"]:nth-child(${i})`,
frames: '.frames [role="list"] [role="listitem"]',
frames: `.frames [role="list"] [role="listitem"]`,
gutter: i => `.CodeMirror-code *:nth-child(${i}) .CodeMirror-linenumber`,
// These work for bobth the breakpoint listing and gutter marker
gutterContextMenu: {

Просмотреть файл

@ -419,70 +419,97 @@ function isSlowBuffer (obj) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.stopSourceMapWorker = exports.startSourceMapWorker = exports.isOriginalId = exports.isGeneratedId = exports.generatedToOriginalId = exports.originalToGeneratedId = exports.getOriginalStackFrames = exports.hasMappedSource = exports.clearSourceMaps = exports.applySourceMap = exports.getOriginalSourceText = exports.getLocationScopes = exports.getFileGeneratedRange = exports.getOriginalLocation = exports.getAllGeneratedLocations = exports.getGeneratedLocation = exports.getGeneratedRanges = exports.getOriginalRanges = exports.hasOriginalURL = exports.getOriginalURLs = exports.setAssetRootURL = exports.dispatcher = undefined;
var _utils = __webpack_require__(3652);
Object.defineProperty(exports, "originalToGeneratedId", {
enumerable: true,
get: function () {
return _utils.originalToGeneratedId;
}
});
Object.defineProperty(exports, "generatedToOriginalId", {
enumerable: true,
get: function () {
return _utils.generatedToOriginalId;
}
});
Object.defineProperty(exports, "isGeneratedId", {
enumerable: true,
get: function () {
return _utils.isGeneratedId;
}
});
Object.defineProperty(exports, "isOriginalId", {
enumerable: true,
get: function () {
return _utils.isOriginalId;
}
});
var _devtoolsSourceMap = __webpack_require__(3646);
var self = _interopRequireWildcard(_devtoolsSourceMap);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
/* 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/>. */
const {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId
} = __webpack_require__(3652);
const {
workerUtils: { WorkerDispatcher }
} = __webpack_require__(3651);
const dispatcher = new WorkerDispatcher();
const dispatcher = exports.dispatcher = new WorkerDispatcher();
const setAssetRootURL = dispatcher.task("setAssetRootURL");
const getOriginalURLs = dispatcher.task("getOriginalURLs");
const hasOriginalURL = dispatcher.task("hasOriginalURL");
const getOriginalRanges = dispatcher.task("getOriginalRanges");
const getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
const _getGeneratedRanges = dispatcher.task("getGeneratedRanges", {
queue: true
});
const getGeneratedLocation = dispatcher.task("getGeneratedLocation", {
queue: true
});
const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", {
queue: true
});
const getOriginalLocation = dispatcher.task("getOriginalLocation");
const getFileGeneratedRange = dispatcher.task("getFileGeneratedRange");
const getLocationScopes = dispatcher.task("getLocationScopes");
const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
const applySourceMap = dispatcher.task("applySourceMap");
const clearSourceMaps = dispatcher.task("clearSourceMaps");
const hasMappedSource = dispatcher.task("hasMappedSource");
const getOriginalStackFrames = dispatcher.task("getOriginalStackFrames");
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId,
hasMappedSource,
getOriginalURLs,
hasOriginalURL,
getOriginalRanges,
getGeneratedRanges,
getGeneratedLocation,
getAllGeneratedLocations,
getOriginalLocation,
getFileGeneratedRange,
getLocationScopes,
getOriginalSourceText,
applySourceMap,
clearSourceMaps,
getOriginalStackFrames,
startSourceMapWorker(url, assetRoot) {
dispatcher.start(url);
setAssetRootURL(assetRoot);
},
stopSourceMapWorker: dispatcher.stop.bind(dispatcher)
const _getGeneratedLocation = dispatcher.task("getGeneratedLocation", { queue: true });
const _getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations", { queue: true });
const setAssetRootURL = exports.setAssetRootURL = async assetRoot => dispatcher.invoke("setAssetRootURL", assetRoot);
const getOriginalURLs = exports.getOriginalURLs = async generatedSource => dispatcher.invoke("getOriginalURLs", generatedSource);
const hasOriginalURL = exports.hasOriginalURL = async url => dispatcher.invoke("hasOriginalURL", url);
const getOriginalRanges = exports.getOriginalRanges = async (sourceId, url) => dispatcher.invoke("getOriginalRanges", sourceId, url);
const getGeneratedRanges = exports.getGeneratedRanges = async (location, originalSource) => _getGeneratedRanges(location, originalSource);
const getGeneratedLocation = exports.getGeneratedLocation = async (location, originalSource) => _getGeneratedLocation(location, originalSource);
const getAllGeneratedLocations = exports.getAllGeneratedLocations = async (location, originalSource) => _getAllGeneratedLocations(location, originalSource);
const getOriginalLocation = exports.getOriginalLocation = async (location, options = {}) => dispatcher.invoke("getOriginalLocation", location, options);
const getFileGeneratedRange = exports.getFileGeneratedRange = async originalSource => dispatcher.invoke("getFileGeneratedRange", originalSource);
const getLocationScopes = exports.getLocationScopes = dispatcher.task("getLocationScopes");
const getOriginalSourceText = exports.getOriginalSourceText = async originalSource => dispatcher.invoke("getOriginalSourceText", originalSource);
const applySourceMap = exports.applySourceMap = async (generatedId, url, code, mappings) => dispatcher.invoke("applySourceMap", generatedId, url, code, mappings);
const clearSourceMaps = exports.clearSourceMaps = async () => dispatcher.invoke("clearSourceMaps");
const hasMappedSource = exports.hasMappedSource = async location => dispatcher.invoke("hasMappedSource", location);
const getOriginalStackFrames = exports.getOriginalStackFrames = async generatedLocation => dispatcher.invoke("getOriginalStackFrames", generatedLocation);
const startSourceMapWorker = exports.startSourceMapWorker = (url, assetRoot) => {
dispatcher.start(url);
setAssetRootURL(assetRoot);
};
const stopSourceMapWorker = exports.stopSourceMapWorker = dispatcher.stop.bind(dispatcher);
exports.default = self;
/***/ }),

Просмотреть файл

@ -457,7 +457,7 @@ void ShadowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
if (!aVisitor.mEvent->mFlags.mComposed) {
nsCOMPtr<nsIContent> originalTarget =
do_QueryInterface(aVisitor.mEvent->mOriginalTarget);
if (originalTarget->GetContainingShadow() == this) {
if (originalTarget && originalTarget->GetContainingShadow() == this) {
// If we do stop propagation, we still want to propagate
// the event to chrome (nsPIDOMWindow::GetParentTarget()).
// The load event is special in that we don't ever propagate it

Просмотреть файл

@ -145,8 +145,10 @@ bool WebGLContext::InitWebGL2(FailureReason* const out_failReason) {
gl->GetUIntegerv(LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS,
&mGLMaxUniformBufferBindings);
mGLMinProgramTexelOffset = gl->GetIntAs<uint32_t>(LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET);
mGLMaxProgramTexelOffset = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET);
mGLMinProgramTexelOffset =
gl->GetIntAs<uint32_t>(LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET);
mGLMaxProgramTexelOffset =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET);
mIndexedUniformBufferBindings.resize(mGLMaxUniformBufferBindings);

Просмотреть файл

@ -428,25 +428,35 @@ bool WebGLContext::InitAndValidateGL(FailureReason* const out_failReason) {
////////////////
if (gl->IsGLES()) {
mGLMaxFragmentUniformVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS);
mGLMaxVertexUniformVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS);
mGLMaxFragmentUniformVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS);
mGLMaxVertexUniformVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS);
if (gl->Version() >= 300) {
mGLMaxVertexOutputVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS) / 4;
mGLMaxFragmentInputVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS) / 4;
mGLMaxVertexOutputVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS) / 4;
mGLMaxFragmentInputVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS) / 4;
} else {
mGLMaxFragmentInputVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VARYING_VECTORS);
mGLMaxFragmentInputVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VARYING_VECTORS);
mGLMaxVertexOutputVectors = mGLMaxFragmentInputVectors;
}
} else {
mGLMaxFragmentUniformVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS) / 4;
mGLMaxVertexUniformVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS) / 4;
mGLMaxFragmentUniformVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS) / 4;
mGLMaxVertexUniformVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS) / 4;
if (gl->Version() >= 320) {
mGLMaxVertexOutputVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS) / 4;
mGLMaxFragmentInputVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS) / 4;
mGLMaxVertexOutputVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS) / 4;
mGLMaxFragmentInputVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS) / 4;
} else {
// Same enum val as GL2's GL_MAX_VARYING_FLOATS.
mGLMaxFragmentInputVectors = gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VARYING_COMPONENTS) / 4;
mGLMaxFragmentInputVectors =
gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_VARYING_COMPONENTS) / 4;
mGLMaxVertexOutputVectors = mGLMaxFragmentInputVectors;
}
}

Просмотреть файл

@ -1819,7 +1819,7 @@ void RuntimeService::CrashIfHanging() {
}
// This string will be leaked.
MOZ_CRASH_UNSAFE_OOL(strdup(msg.BeginReading()));
MOZ_CRASH_UNSAFE(strdup(msg.BeginReading()));
}
// This spins the event loop until all workers are finished and their threads

Просмотреть файл

@ -14,7 +14,7 @@ namespace {
void AssertOnOwningThread(void* aThread) {
if (MOZ_UNLIKELY(aThread != GetCurrentVirtualThread())) {
MOZ_CRASH_UNSAFE_OOL("WorkerHolder on the wrong thread.");
MOZ_CRASH_UNSAFE("WorkerHolder on the wrong thread.");
}
}

Просмотреть файл

@ -193,7 +193,7 @@ void GLBlitTextureImageHelper::SetBlitFramebufferForDestTexture(
// your texture is not texture complete -- that is, you
// allocated a texture name, but didn't actually define its
// size via a call to TexImage2D.
MOZ_CRASH_UNSAFE_OOL(msg.get());
MOZ_CRASH_UNSAFE(msg.get());
}
}

Просмотреть файл

@ -1957,7 +1957,7 @@ gfxFont* gfxFontGroup::GetDefaultFont() {
mFamilyList.ToString(familiesString);
SprintfLiteral(msg, "unable to find a usable font (%.220s)",
familiesString.get());
MOZ_CRASH_UNSAFE_OOL(msg);
MOZ_CRASH_UNSAFE(msg);
}
return mDefaultFont.get();

Просмотреть файл

@ -102,11 +102,15 @@ VertexInfo write_vertex(RectWithSize instance_rect,
// Clamp to the two local clip rects.
vec2 clamped_local_pos = clamp_rect(local_pos, local_clip_rect);
// Compute the visible rect to snap against. This ensures segments along the
// edges are snapped consistently with other nearby primitives.
RectWithSize visible_rect = intersect_rects(local_clip_rect, snap_rect);
/// Compute the snapping offset.
vec2 snap_offset = compute_snap_offset(
clamped_local_pos,
transform.m,
snap_rect,
visible_rect,
task.common_data.device_pixel_scale
);

Просмотреть файл

@ -51,7 +51,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use storage;
use util::{ScaleOffset, MatrixHelpers, MaxRect, Recycler, TransformedRectKind};
use util::{pack_as_float, project_rect, raster_rect_to_device_pixels};
use util::{scale_factors, clamp_to_scale_factor, RectHelpers};
use util::{scale_factors, clamp_to_scale_factor};
use smallvec::SmallVec;
pub mod borders;
@ -3536,9 +3536,9 @@ fn compute_snap_offset_impl(
)
}
/// Retrieve the exact device space rectangle for a primitive, taking
/// into account the snapping that the shaders will apply if the transform
/// is axis-aligned.
/// Retrieve the exact unsnapped device space rectangle for a primitive.
/// If the transform is axis-aligned, compute the snapping offsets that
/// the shaders will apply.
fn get_unclipped_device_rect(
prim_spatial_node_index: SpatialNodeIndex,
root_spatial_node_index: SpatialNodeIndex,
@ -3583,11 +3583,7 @@ fn get_unclipped_device_rect(
bottom_right,
};
let p0 = unclipped_device_rect.origin + top_left;
let p1 = unclipped_device_rect.bottom_right() + bottom_right;
let unclipped = DeviceRect::from_floats(p0.x, p0.y, p1.x, p1.y);
Some((unclipped, snap_offsets))
Some((unclipped_device_rect, snap_offsets))
}
TransformedRectKind::Complex => {
Some((unclipped_device_rect, SnapOffsets::empty()))

Просмотреть файл

@ -14,7 +14,7 @@ platform(linux,mac) == border-suite-3.yaml border-suite-3.png
== border-double-simple-2.yaml border-double-simple-2-ref.yaml
fuzzy(64,24) == border-groove-simple.yaml border-groove-simple-ref.yaml
fuzzy(64,24) == border-ridge-simple.yaml border-ridge-simple-ref.yaml
platform(linux,mac) fuzzy(1,2) == degenerate-curve.yaml degenerate-curve.png
platform(linux,mac) fuzzy(1,3) == degenerate-curve.yaml degenerate-curve.png
platform(linux,mac) == border-image.yaml border-image-ref.png
== border-image-crash.yaml border-image-crash-ref.yaml
== border-image-fill.yaml border-image-fill-ref.png

Просмотреть файл

@ -34,4 +34,4 @@ fuzzy(1,5) platform(linux,mac) == box-shadow-huge-radius.yaml box-shadow-huge-ra
platform(linux,mac) == box-shadow-large-blur-radius-2.yaml box-shadow-large-blur-radius-2.png
platform(linux,mac) == box-shadow-large-blur-radius-3.yaml box-shadow-large-blur-radius-3.png
platform(linux,mac) == scale.yaml scale.png
platform(linux,mac) fuzzy(1,79) == scale.yaml scale.png

Просмотреть файл

@ -25,7 +25,7 @@ platform(linux,mac) == perspective-mask.yaml perspective-mask.png
rotate-clip.yaml rotate-clip-ref.yaml
clip-translate.yaml clip-translate-ref.yaml
platform(linux,mac) == perspective-clip.yaml perspective-clip.png
platform(linux,mac) == perspective-clip-1.yaml perspective-clip-1.png
platform(linux,mac) fuzzy(1,2) == perspective-clip-1.yaml perspective-clip-1.png
platform(linux,mac) fuzzy(1,2) == perspective-shadow.yaml perspective-shadow.png
== complex-preserve-3d.yaml blank.yaml
platform(linux,mac) fuzzy(9,348) == perspective-border-radius.yaml perspective-border-radius.png

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше