Merge fx-team to central, a=merge

This commit is contained in:
Wes Kocher 2016-09-12 17:19:37 -07:00
Родитель c21b854efc 9f838998a8
Коммит bcc9ea6947
44 изменённых файлов: 2865 добавлений и 33971 удалений

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

@ -1220,8 +1220,8 @@ pref("social.shareDirectory", "https://activations.cdn.mozilla.net/sharePanel.ht
pref("security.mixed_content.block_active_content", true);
// Show degraded UI for http pages with password fields.
// Only for Nightly and Dev Edition for not, not for beta or release.
#ifndef RELEASE_BUILD
// Only for Nightly, Dev Edition and early beta, not for late beta or release.
#ifdef EARLY_BETA_OR_EARLIER
pref("security.insecure_password.ui.enabled", true);
#else
pref("security.insecure_password.ui.enabled", false);

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

@ -6852,7 +6852,7 @@ var gIdentityHandler = {
this._sharingState = tab._sharingState;
if (this._identityPopup.state == "open") {
this.updateSitePermissions();
this._handleHeightChange(() => this.updateSitePermissions());
}
},
@ -7364,6 +7364,20 @@ var gIdentityHandler = {
this.updatePermissionHint();
},
_handleHeightChange: function(aFunction, aWillShowReloadHint) {
let heightBefore = getComputedStyle(this._permissionList).height;
aFunction();
let heightAfter = getComputedStyle(this._permissionList).height;
// Showing the reload hint increases the height, we need to account for it.
if (aWillShowReloadHint) {
heightAfter = parseInt(heightAfter) +
parseInt(getComputedStyle(this._permissionList.nextSibling).height);
}
let heightChange = parseInt(heightAfter) - parseInt(heightBefore);
if (heightChange)
this._identityPopupMultiView.setHeightToFit(heightChange);
},
_createPermissionItem: function (aPermission) {
let container = document.createElement("hbox");
container.setAttribute("class", "identity-popup-permission-item");
@ -7393,7 +7407,8 @@ var gIdentityHandler = {
let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
button.setAttribute("tooltiptext", tooltiptext);
button.addEventListener("command", () => {
this._permissionList.removeChild(container);
this._handleHeightChange(() =>
this._permissionList.removeChild(container), !this._permissionJustRemoved);
if (aPermission.inUse &&
["camera", "microphone", "screen"].includes(aPermission.id)) {
let windowId = this._sharingState.windowId;

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

@ -37,7 +37,7 @@ add_task(function* testMainViewVisible() {
yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
let permissionsList = document.getElementById("identity-popup-permission-list");
let emptyLabel = permissionsList.nextSibling;
let emptyLabel = permissionsList.nextSibling.nextSibling;
yield openIdentityPopup();
@ -107,7 +107,7 @@ add_task(function* testCancelPermission() {
yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
let permissionsList = document.getElementById("identity-popup-permission-list");
let emptyLabel = permissionsList.nextSibling;
let emptyLabel = permissionsList.nextSibling.nextSibling;
SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.ALLOW);
SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.BLOCK);

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

@ -16,7 +16,7 @@
<panelmultiview id="identity-popup-multiView"
mainViewId="identity-popup-mainView">
<panelview id="identity-popup-mainView">
<panelview id="identity-popup-mainView" flex="1">
<!-- Security Section -->
<hbox id="identity-popup-security" class="identity-popup-section">
@ -91,8 +91,8 @@
class="identity-popup-headline"
value="&identity.permissions;"/>
<vbox id="identity-popup-permission-list"/>
<description id="identity-popup-permission-empty-hint">&identity.permissionsEmpty;</description>
<description id="identity-popup-permission-reload-hint">&identity.permissionsReloadHint;</description>
<description id="identity-popup-permission-empty-hint">&identity.permissionsEmpty;</description>
</vbox>
</hbox>
</panelview>

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

@ -338,7 +338,7 @@
break;
case "popuphidden":
this.removeAttribute("panelopen");
this._mainView.style.removeProperty("max-height");
this._mainView.style.removeProperty("height");
this.showMainView();
this._mainViewObserver.disconnect();
break;
@ -366,7 +366,7 @@
// Ignore the mutation that'll fire when we set the height of
// the main view.
this.ignoreMutations = true;
this._mainView.style.maxHeight =
this._mainView.style.height =
this.getBoundingClientRect().height + "px";
this.ignoreMutations = false;
]]></body>
@ -416,8 +416,11 @@
<!-- Call this when the height of one of your views (the main view or a
subview) changes and you want the heights of the multiview and panel
to be the same as the view's height. -->
to be the same as the view's height.
If the caller can give a hint of the expected height change with the
optional aExpectedChange parameter, it prevents flicker. -->
<method name="setHeightToFit">
<parameter name="aExpectedChange"/>
<body><![CDATA[
// Set the max-height to zero, wait until the height is actually
// updated, and then remove it. If it's not removed, weird things can
@ -425,7 +428,10 @@
// though they're visible.
let count = 5;
let height = getComputedStyle(this).height;
this.style.maxHeight = "0";
if (aExpectedChange)
this.style.maxHeight = (parseInt(height) + aExpectedChange) + "px";
else
this.style.maxHeight = "0";
let interval = setInterval(() => {
if (height != getComputedStyle(this).height || --count == 0) {
clearInterval(interval);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -65,6 +65,8 @@ DebuggerPanel.prototype = {
},
destroy: function() {
this.panelWin.Debugger.destroy();
this.emit("destroyed");
}
};

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

@ -46,7 +46,7 @@ var Debugger =
/***/ 0:
/***/ function(module, exports, __webpack_require__) {
var prettyFast = __webpack_require__(544);
var prettyFast = __webpack_require__(365);
self.onmessage = function (msg) {
var _prettyPrint = prettyPrint(msg.data);
@ -100,7 +100,7 @@ var Debugger =
/***/ },
/***/ 544:
/***/ 365:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
@ -122,8 +122,8 @@ var Debugger =
}(this, function () {
"use strict";
var acorn = this.acorn || __webpack_require__(545);
var sourceMap = this.sourceMap || __webpack_require__(546);
var acorn = this.acorn || __webpack_require__(366);
var sourceMap = this.sourceMap || __webpack_require__(367);
var SourceNode = sourceMap.SourceNode;
// If any of these tokens are seen before a "[" token, we know that "[" token
@ -982,7 +982,7 @@ var Debugger =
/***/ },
/***/ 545:
/***/ 366:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Acorn is a tiny, fast JavaScript parser written in JavaScript.
@ -3642,7 +3642,7 @@ var Debugger =
/***/ },
/***/ 546:
/***/ 367:
/***/ function(module, exports, __webpack_require__) {
/*
@ -3650,14 +3650,14 @@ var Debugger =
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = __webpack_require__(547).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(553).SourceMapConsumer;
exports.SourceNode = __webpack_require__(555).SourceNode;
exports.SourceMapGenerator = __webpack_require__(368).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(374).SourceMapConsumer;
exports.SourceNode = __webpack_require__(376).SourceNode;
/***/ },
/***/ 547:
/***/ 368:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3671,10 +3671,10 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var base64VLQ = __webpack_require__(548);
var util = __webpack_require__(550);
var ArraySet = __webpack_require__(551).ArraySet;
var MappingList = __webpack_require__(552).MappingList;
var base64VLQ = __webpack_require__(369);
var util = __webpack_require__(371);
var ArraySet = __webpack_require__(372).ArraySet;
var MappingList = __webpack_require__(373).MappingList;
/**
* An instance of the SourceMapGenerator represents a source map which is
@ -4064,7 +4064,7 @@ var Debugger =
/***/ },
/***/ 548:
/***/ 369:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4108,7 +4108,7 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var base64 = __webpack_require__(549);
var base64 = __webpack_require__(370);
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
@ -4213,7 +4213,7 @@ var Debugger =
/***/ },
/***/ 549:
/***/ 370:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4262,7 +4262,7 @@ var Debugger =
/***/ },
/***/ 550:
/***/ 371:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4588,7 +4588,7 @@ var Debugger =
/***/ },
/***/ 551:
/***/ 372:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4602,7 +4602,7 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var util = __webpack_require__(550);
var util = __webpack_require__(371);
/**
* A data structure which is a combination of an array and a set. Adding a new
@ -4692,7 +4692,7 @@ var Debugger =
/***/ },
/***/ 552:
/***/ 373:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4706,7 +4706,7 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var util = __webpack_require__(550);
var util = __webpack_require__(371);
/**
* Determine whether mappingB is after mappingA with respect to generated
@ -4785,7 +4785,7 @@ var Debugger =
/***/ },
/***/ 553:
/***/ 374:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4799,10 +4799,10 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var util = __webpack_require__(550);
var binarySearch = __webpack_require__(554);
var ArraySet = __webpack_require__(551).ArraySet;
var base64VLQ = __webpack_require__(548);
var util = __webpack_require__(371);
var binarySearch = __webpack_require__(375);
var ArraySet = __webpack_require__(372).ArraySet;
var base64VLQ = __webpack_require__(369);
/**
* A SourceMapConsumer instance represents a parsed source map which we can
@ -5367,7 +5367,7 @@ var Debugger =
/***/ },
/***/ 554:
/***/ 375:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -5454,7 +5454,7 @@ var Debugger =
/***/ },
/***/ 555:
/***/ 376:
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- Mode: js; js-indent-level: 2; -*- */
@ -5468,8 +5468,8 @@ var Debugger =
}
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
var SourceMapGenerator = __webpack_require__(547).SourceMapGenerator;
var util = __webpack_require__(550);
var SourceMapGenerator = __webpack_require__(368).SourceMapGenerator;
var util = __webpack_require__(371);
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).

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

@ -48,19 +48,19 @@ var Debugger =
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _require = __webpack_require__(556);
var _require = __webpack_require__(377);
var SourceMapConsumer = _require.SourceMapConsumer;
var SourceNode = _require.SourceNode;
var SourceMapGenerator = _require.SourceMapGenerator;
var _require2 = __webpack_require__(365);
var _require2 = __webpack_require__(216);
var makeOriginalSource = _require2.makeOriginalSource;
var getGeneratedSourceId = _require2.getGeneratedSourceId;
var toPairs = __webpack_require__(491);
var toPairs = __webpack_require__(312);
var sourceMapConsumers = new Map();
var sourceNodes = new Map();
@ -310,7 +310,7 @@ var Debugger =
/***/ },
/***/ 201:
/***/ 52:
/***/ function(module, exports) {
/**
@ -345,11 +345,11 @@ var Debugger =
/***/ },
/***/ 209:
/***/ 60:
/***/ function(module, exports, __webpack_require__) {
var baseIsNative = __webpack_require__(210),
getValue = __webpack_require__(218);
var baseIsNative = __webpack_require__(61),
getValue = __webpack_require__(69);
/**
* Gets the native function at `key` of `object`.
@ -369,14 +369,14 @@ var Debugger =
/***/ },
/***/ 210:
/***/ 61:
/***/ function(module, exports, __webpack_require__) {
var isFunction = __webpack_require__(211),
var isFunction = __webpack_require__(62),
isHostObject = __webpack_require__(6),
isMasked = __webpack_require__(213),
isObject = __webpack_require__(212),
toSource = __webpack_require__(217);
isMasked = __webpack_require__(64),
isObject = __webpack_require__(63),
toSource = __webpack_require__(68);
/**
* Used to match `RegExp`
@ -423,10 +423,10 @@ var Debugger =
/***/ },
/***/ 211:
/***/ 62:
/***/ function(module, exports, __webpack_require__) {
var isObject = __webpack_require__(212);
var isObject = __webpack_require__(63);
/** `Object#toString` result references. */
var funcTag = '[object Function]',
@ -473,7 +473,7 @@ var Debugger =
/***/ },
/***/ 212:
/***/ 63:
/***/ function(module, exports) {
/**
@ -511,10 +511,10 @@ var Debugger =
/***/ },
/***/ 213:
/***/ 64:
/***/ function(module, exports, __webpack_require__) {
var coreJsData = __webpack_require__(214);
var coreJsData = __webpack_require__(65);
/** Used to detect methods masquerading as native. */
var maskSrcKey = (function() {
@ -538,10 +538,10 @@ var Debugger =
/***/ },
/***/ 214:
/***/ 65:
/***/ function(module, exports, __webpack_require__) {
var root = __webpack_require__(215);
var root = __webpack_require__(66);
/** Used to detect overreaching core-js shims. */
var coreJsData = root['__core-js_shared__'];
@ -551,10 +551,10 @@ var Debugger =
/***/ },
/***/ 215:
/***/ 66:
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {var checkGlobal = __webpack_require__(216);
/* WEBPACK VAR INJECTION */(function(global) {var checkGlobal = __webpack_require__(67);
/** Detect free variable `global` from Node.js. */
var freeGlobal = checkGlobal(typeof global == 'object' && global);
@ -574,7 +574,7 @@ var Debugger =
/***/ },
/***/ 216:
/***/ 67:
/***/ function(module, exports) {
/**
@ -593,7 +593,7 @@ var Debugger =
/***/ },
/***/ 217:
/***/ 68:
/***/ function(module, exports) {
/** Used to resolve the decompiled source of functions. */
@ -623,7 +623,7 @@ var Debugger =
/***/ },
/***/ 218:
/***/ 69:
/***/ function(module, exports) {
/**
@ -643,11 +643,11 @@ var Debugger =
/***/ },
/***/ 231:
/***/ 82:
/***/ function(module, exports, __webpack_require__) {
var getNative = __webpack_require__(209),
root = __webpack_require__(215);
var getNative = __webpack_require__(60),
root = __webpack_require__(66);
/* Built-in method references that are verified to be native. */
var Map = getNative(root, 'Map');
@ -657,7 +657,7 @@ var Debugger =
/***/ },
/***/ 365:
/***/ 216:
/***/ function(module, exports) {
@ -687,11 +687,11 @@ var Debugger =
/***/ },
/***/ 491:
/***/ 312:
/***/ function(module, exports, __webpack_require__) {
var createToPairs = __webpack_require__(492),
keys = __webpack_require__(502);
var createToPairs = __webpack_require__(313),
keys = __webpack_require__(323);
/**
* Creates an array of own enumerable string keyed-value pairs for `object`
@ -724,13 +724,13 @@ var Debugger =
/***/ },
/***/ 492:
/***/ 313:
/***/ function(module, exports, __webpack_require__) {
var baseToPairs = __webpack_require__(493),
getTag = __webpack_require__(495),
mapToArray = __webpack_require__(500),
setToPairs = __webpack_require__(501);
var baseToPairs = __webpack_require__(314),
getTag = __webpack_require__(316),
mapToArray = __webpack_require__(321),
setToPairs = __webpack_require__(322);
/** `Object#toString` result references. */
var mapTag = '[object Map]',
@ -761,10 +761,10 @@ var Debugger =
/***/ },
/***/ 493:
/***/ 314:
/***/ function(module, exports, __webpack_require__) {
var arrayMap = __webpack_require__(494);
var arrayMap = __webpack_require__(315);
/**
* The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
@ -786,7 +786,7 @@ var Debugger =
/***/ },
/***/ 494:
/***/ 315:
/***/ function(module, exports) {
/**
@ -814,15 +814,15 @@ var Debugger =
/***/ },
/***/ 495:
/***/ 316:
/***/ function(module, exports, __webpack_require__) {
var DataView = __webpack_require__(496),
Map = __webpack_require__(231),
Promise = __webpack_require__(497),
Set = __webpack_require__(498),
WeakMap = __webpack_require__(499),
toSource = __webpack_require__(217);
var DataView = __webpack_require__(317),
Map = __webpack_require__(82),
Promise = __webpack_require__(318),
Set = __webpack_require__(319),
WeakMap = __webpack_require__(320),
toSource = __webpack_require__(68);
/** `Object#toString` result references. */
var mapTag = '[object Map]',
@ -891,11 +891,11 @@ var Debugger =
/***/ },
/***/ 496:
/***/ 317:
/***/ function(module, exports, __webpack_require__) {
var getNative = __webpack_require__(209),
root = __webpack_require__(215);
var getNative = __webpack_require__(60),
root = __webpack_require__(66);
/* Built-in method references that are verified to be native. */
var DataView = getNative(root, 'DataView');
@ -905,11 +905,11 @@ var Debugger =
/***/ },
/***/ 497:
/***/ 318:
/***/ function(module, exports, __webpack_require__) {
var getNative = __webpack_require__(209),
root = __webpack_require__(215);
var getNative = __webpack_require__(60),
root = __webpack_require__(66);
/* Built-in method references that are verified to be native. */
var Promise = getNative(root, 'Promise');
@ -919,11 +919,11 @@ var Debugger =
/***/ },
/***/ 498:
/***/ 319:
/***/ function(module, exports, __webpack_require__) {
var getNative = __webpack_require__(209),
root = __webpack_require__(215);
var getNative = __webpack_require__(60),
root = __webpack_require__(66);
/* Built-in method references that are verified to be native. */
var Set = getNative(root, 'Set');
@ -933,11 +933,11 @@ var Debugger =
/***/ },
/***/ 499:
/***/ 320:
/***/ function(module, exports, __webpack_require__) {
var getNative = __webpack_require__(209),
root = __webpack_require__(215);
var getNative = __webpack_require__(60),
root = __webpack_require__(66);
/* Built-in method references that are verified to be native. */
var WeakMap = getNative(root, 'WeakMap');
@ -947,7 +947,7 @@ var Debugger =
/***/ },
/***/ 500:
/***/ 321:
/***/ function(module, exports) {
/**
@ -972,7 +972,7 @@ var Debugger =
/***/ },
/***/ 501:
/***/ 322:
/***/ function(module, exports) {
/**
@ -997,15 +997,15 @@ var Debugger =
/***/ },
/***/ 502:
/***/ 323:
/***/ function(module, exports, __webpack_require__) {
var baseHas = __webpack_require__(503),
baseKeys = __webpack_require__(504),
indexKeys = __webpack_require__(505),
isArrayLike = __webpack_require__(509),
isIndex = __webpack_require__(514),
isPrototype = __webpack_require__(515);
var baseHas = __webpack_require__(324),
baseKeys = __webpack_require__(325),
indexKeys = __webpack_require__(326),
isArrayLike = __webpack_require__(330),
isIndex = __webpack_require__(335),
isPrototype = __webpack_require__(336);
/**
* Creates an array of the own enumerable property names of `object`.
@ -1060,7 +1060,7 @@ var Debugger =
/***/ },
/***/ 503:
/***/ 324:
/***/ function(module, exports, __webpack_require__) {
var getPrototype = __webpack_require__(5);
@ -1093,7 +1093,7 @@ var Debugger =
/***/ },
/***/ 504:
/***/ 325:
/***/ function(module, exports) {
/* Built-in method references for those with the same name as other `lodash` methods. */
@ -1116,14 +1116,14 @@ var Debugger =
/***/ },
/***/ 505:
/***/ 326:
/***/ function(module, exports, __webpack_require__) {
var baseTimes = __webpack_require__(506),
isArguments = __webpack_require__(507),
isArray = __webpack_require__(201),
isLength = __webpack_require__(512),
isString = __webpack_require__(513);
var baseTimes = __webpack_require__(327),
isArguments = __webpack_require__(328),
isArray = __webpack_require__(52),
isLength = __webpack_require__(333),
isString = __webpack_require__(334);
/**
* Creates an array of index keys for `object` values of arrays,
@ -1147,7 +1147,7 @@ var Debugger =
/***/ },
/***/ 506:
/***/ 327:
/***/ function(module, exports) {
/**
@ -1174,10 +1174,10 @@ var Debugger =
/***/ },
/***/ 507:
/***/ 328:
/***/ function(module, exports, __webpack_require__) {
var isArrayLikeObject = __webpack_require__(508);
var isArrayLikeObject = __webpack_require__(329);
/** `Object#toString` result references. */
var argsTag = '[object Arguments]';
@ -1227,10 +1227,10 @@ var Debugger =
/***/ },
/***/ 508:
/***/ 329:
/***/ function(module, exports, __webpack_require__) {
var isArrayLike = __webpack_require__(509),
var isArrayLike = __webpack_require__(330),
isObjectLike = __webpack_require__(7);
/**
@ -1267,12 +1267,12 @@ var Debugger =
/***/ },
/***/ 509:
/***/ 330:
/***/ function(module, exports, __webpack_require__) {
var getLength = __webpack_require__(510),
isFunction = __webpack_require__(211),
isLength = __webpack_require__(512);
var getLength = __webpack_require__(331),
isFunction = __webpack_require__(62),
isLength = __webpack_require__(333);
/**
* Checks if `value` is array-like. A value is considered array-like if it's
@ -1308,10 +1308,10 @@ var Debugger =
/***/ },
/***/ 510:
/***/ 331:
/***/ function(module, exports, __webpack_require__) {
var baseProperty = __webpack_require__(511);
var baseProperty = __webpack_require__(332);
/**
* Gets the "length" property value of `object`.
@ -1331,7 +1331,7 @@ var Debugger =
/***/ },
/***/ 511:
/***/ 332:
/***/ function(module, exports) {
/**
@ -1352,7 +1352,7 @@ var Debugger =
/***/ },
/***/ 512:
/***/ 333:
/***/ function(module, exports) {
/** Used as references for various `Number` constants. */
@ -1395,10 +1395,10 @@ var Debugger =
/***/ },
/***/ 513:
/***/ 334:
/***/ function(module, exports, __webpack_require__) {
var isArray = __webpack_require__(201),
var isArray = __webpack_require__(52),
isObjectLike = __webpack_require__(7);
/** `Object#toString` result references. */
@ -1442,7 +1442,7 @@ var Debugger =
/***/ },
/***/ 514:
/***/ 335:
/***/ function(module, exports) {
/** Used as references for various `Number` constants. */
@ -1471,7 +1471,7 @@ var Debugger =
/***/ },
/***/ 515:
/***/ 336:
/***/ function(module, exports) {
/** Used for built-in method references. */
@ -1496,7 +1496,7 @@ var Debugger =
/***/ },
/***/ 556:
/***/ 377:
/***/ function(module, exports, __webpack_require__) {
/*
@ -1504,14 +1504,14 @@ var Debugger =
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = __webpack_require__(557).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(563).SourceMapConsumer;
exports.SourceNode = __webpack_require__(566).SourceNode;
exports.SourceMapGenerator = __webpack_require__(378).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(384).SourceMapConsumer;
exports.SourceNode = __webpack_require__(387).SourceNode;
/***/ },
/***/ 557:
/***/ 378:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -1521,10 +1521,10 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var base64VLQ = __webpack_require__(558);
var util = __webpack_require__(560);
var ArraySet = __webpack_require__(561).ArraySet;
var MappingList = __webpack_require__(562).MappingList;
var base64VLQ = __webpack_require__(379);
var util = __webpack_require__(381);
var ArraySet = __webpack_require__(382).ArraySet;
var MappingList = __webpack_require__(383).MappingList;
/**
* An instance of the SourceMapGenerator represents a source map which is
@ -1922,7 +1922,7 @@ var Debugger =
/***/ },
/***/ 558:
/***/ 379:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -1962,7 +1962,7 @@ var Debugger =
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var base64 = __webpack_require__(559);
var base64 = __webpack_require__(380);
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
@ -2069,7 +2069,7 @@ var Debugger =
/***/ },
/***/ 559:
/***/ 380:
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -2143,7 +2143,7 @@ var Debugger =
/***/ },
/***/ 560:
/***/ 381:
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -2567,7 +2567,7 @@ var Debugger =
/***/ },
/***/ 561:
/***/ 382:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -2577,7 +2577,7 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(560);
var util = __webpack_require__(381);
var has = Object.prototype.hasOwnProperty;
/**
@ -2678,7 +2678,7 @@ var Debugger =
/***/ },
/***/ 562:
/***/ 383:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -2688,7 +2688,7 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(560);
var util = __webpack_require__(381);
/**
* Determine whether mappingB is after mappingA with respect to generated
@ -2764,7 +2764,7 @@ var Debugger =
/***/ },
/***/ 563:
/***/ 384:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -2774,11 +2774,11 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(560);
var binarySearch = __webpack_require__(564);
var ArraySet = __webpack_require__(561).ArraySet;
var base64VLQ = __webpack_require__(558);
var quickSort = __webpack_require__(565).quickSort;
var util = __webpack_require__(381);
var binarySearch = __webpack_require__(385);
var ArraySet = __webpack_require__(382).ArraySet;
var base64VLQ = __webpack_require__(379);
var quickSort = __webpack_require__(386).quickSort;
function SourceMapConsumer(aSourceMap) {
var sourceMap = aSourceMap;
@ -3853,7 +3853,7 @@ var Debugger =
/***/ },
/***/ 564:
/***/ 385:
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3971,7 +3971,7 @@ var Debugger =
/***/ },
/***/ 565:
/***/ 386:
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4092,7 +4092,7 @@ var Debugger =
/***/ },
/***/ 566:
/***/ 387:
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4102,8 +4102,8 @@ var Debugger =
* http://opensource.org/licenses/BSD-3-Clause
*/
var SourceMapGenerator = __webpack_require__(557).SourceMapGenerator;
var util = __webpack_require__(560);
var SourceMapGenerator = __webpack_require__(378).SourceMapGenerator;
var util = __webpack_require__(381);
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,64 @@
{
"globals": {
"add_task": false,
"Assert": false,
"BrowserTestUtils": false,
"content": false,
"ContentTask": false,
"ContentTaskUtils": false,
"EventUtils": false,
"executeSoon": false,
"expectUncaughtException": false,
"export_assertions": false,
"extractJarToTmp": false,
"finish": false,
"getJar": false,
"getRootDirectory": false,
"getTestFilePath": false,
"gBrowser": false,
"gTestPath": false,
"info": false,
"is": false,
"isnot": false,
"ok": false,
"registerCleanupFunction": false,
"requestLongerTimeout": false,
"SimpleTest": false,
"SpecialPowers": false,
"TestUtils": false,
"thisTestLeaksUncaughtRejectionsAndShouldBeFixed": false,
"todo": false,
"todo_is": false,
"todo_isnot": false,
"waitForClipboard": false,
"waitForExplicitFinish": false,
"waitForFocus": false,
// Globals introduced in debugger-specific head.js
"promise": false,
"BrowserToolboxProcess": false,
"OS": false,
"waitForNextDispatch": false,
"waitForDispatch": false,
"waitForThreadEvents": false,
"waitForState": false,
"waitForPaused": false,
"isPaused": false,
"assertPausedLocation": false,
"initDebugger": false,
"invokeInTab": false,
"findSource": false,
"findElement": false,
"selectSource": false,
"stepOver": false,
"stepIn": false,
"stepOut": false,
"resume": false,
"reload": false,
"addBreakpoint": false,
"toggleCallStack": false,
"isVisibleWithin": false,
"clickElement": false,
"togglePauseOnExceptions": false
}
}

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

@ -1,5 +1,28 @@
[DEFAULT]
tags = devtools
subsuite = devtools
support-files =
head.js
!/devtools/client/commandline/test/helpers.js
!/devtools/client/framework/test/shared-head.js
examples/doc-scripts.html
examples/doc-script-switching-01.html
examples/doc-exceptions.html
examples/doc-iframes.html
examples/doc-debugger-statements.html
examples/code-exceptions.js
examples/code-simple1.js
examples/code-simple2.js
examples/code-long.js
examples/code-script-switching-02.js
examples/code-script-switching-01.js
[browser_dbg_stub.js]
[browser_dbg-editor-gutter.js]
[browser_dbg-editor-mode.js]
[browser_dbg-editor-select.js]
[browser_dbg-call-stack.js]
[browser_dbg-pause-exceptions.js]
[browser_dbg-chrome-create.js]
[browser_dbg-chrome-debugging.js]
[browser_dbg-iframes.js]
[browser_dbg-debugger-buttons.js]

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

@ -0,0 +1,33 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function findFrame(dbg, index) {
return findElement(dbg, "frame", index);
}
// checks to see if the frame is selected and the title is correct
function isFrameSelected(dbg, index, title) {
const $frame = findFrame(dbg, index);
const frame = dbg.selectors.getSelectedFrame(dbg.getState());
const elSelected = $frame.classList.contains("selected");
const titleSelected = frame.displayName == title;
return elSelected && titleSelected;
}
add_task(function* () {
const dbg = yield initDebugger(
"doc-script-switching-01.html",
"script-switching-01.js"
);
toggleCallStack(dbg);
invokeInTab("firstCall");
yield waitForPaused(dbg);
ok(isFrameSelected(dbg, 1, "secondCall"), "the first frame is selected");
findFrame(dbg, 2).click();
ok(isFrameSelected(dbg, 2, "firstCall"), "the second frame is selected");
});

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

@ -0,0 +1,72 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that a chrome debugger can be created in a new process.
*/
const { BrowserToolboxProcess } = Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", {});
let gProcess = undefined;
function initChromeDebugger() {
info("Initializing a chrome debugger process.");
return new Promise(resolve => {
BrowserToolboxProcess.init(onClose, (event, _process) => {
info("Browser toolbox process started successfully.");
resolve(_process);
});
});
}
function onClose() {
ok(!gProcess._dbgProcess.isRunning,
"The remote debugger process isn't closed as it should be!");
is(gProcess._dbgProcess.exitValue, (Services.appinfo.OS == "WINNT" ? 0 : 256),
"The remote debugger process didn't die cleanly.");
info("process exit value: " + gProcess._dbgProcess.exitValue);
info("profile path: " + gProcess._dbgProfilePath);
finish();
}
registerCleanupFunction(function() {
Services.prefs.clearUserPref("devtools.debugger.remote-enabled");
gProcess = null;
});
add_task(function* () {
// Windows XP and 8.1 test slaves are terribly slow at this test.
requestLongerTimeout(5);
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
gProcess = yield initChromeDebugger();
ok(gProcess._dbgProcess,
"The remote debugger process wasn't created properly!");
ok(gProcess._dbgProcess.isRunning,
"The remote debugger process isn't running!");
is(typeof gProcess._dbgProcess.pid, "number",
"The remote debugger process doesn't have a pid (?!)");
info("process location: " + gProcess._dbgProcess.location);
info("process pid: " + gProcess._dbgProcess.pid);
info("process name: " + gProcess._dbgProcess.processName);
info("process sig: " + gProcess._dbgProcess.processSignature);
ok(gProcess._dbgProfilePath,
"The remote debugger profile wasn't created properly!");
is(
gProcess._dbgProfilePath,
OS.Path.join(OS.Constants.Path.profileDir, "chrome_debugger_profile"),
"The remote debugger profile isn't where we expect it!"
);
info("profile path: " + gProcess._dbgProfilePath);
gProcess.close();
});

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

@ -0,0 +1,88 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that chrome debugging works.
*/
var gClient, gThreadClient;
var gNewGlobal = promise.defer();
var gNewChromeSource = promise.defer();
var { DevToolsLoader } = Cu.import("resource://devtools/shared/Loader.jsm", {});
var customLoader = new DevToolsLoader();
customLoader.invisibleToDebugger = true;
var { DebuggerServer } = customLoader.require("devtools/server/main");
var { DebuggerClient } = require("devtools/shared/client/main");
function initDebuggerClient() {
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
DebuggerServer.allowChromeProcess = true;
let transport = DebuggerServer.connectPipe();
return new DebuggerClient(transport);
}
function attachThread(client, actor) {
return new Promise(resolve => {
client.attachTab(actor, (response, tabClient) => {
tabClient.attachThread(null, (r, threadClient) => {
resolve(threadClient);
});
});
});
}
function onNewGlobal() {
ok(true, "Received a new chrome global.");
gClient.removeListener("newGlobal", onNewGlobal);
gNewGlobal.resolve();
}
function onNewSource(event, packet) {
if (packet.source.url.startsWith("chrome:")) {
ok(true, "Received a new chrome source: " + packet.source.url);
gThreadClient.removeListener("newSource", onNewSource);
gNewChromeSource.resolve();
}
}
function resumeAndCloseConnection() {
return new Promise(resolve => {
gThreadClient.resume(() => resolve(gClient.close()));
});
}
registerCleanupFunction(function() {
gClient = null;
gThreadClient = null;
gNewGlobal = null;
gNewChromeSource = null;
customLoader = null;
DebuggerServer = null;
});
add_task(function* () {
gClient = initDebuggerClient();
const [type] = yield gClient.connect();
is(type, "browser", "Root actor should identify itself as a browser.");
const response = yield gClient.getProcess();
let actor = response.form.actor;
gThreadClient = yield attachThread(gClient, actor);
gBrowser.selectedTab = gBrowser.addTab("about:mozilla");
// listen for a new source and global
gThreadClient.addListener("newSource", onNewSource);
gClient.addListener("newGlobal", onNewGlobal);
yield promise.all([ gNewGlobal.promise, gNewChromeSource.promise ]);
yield resumeAndCloseConnection();
});

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

@ -0,0 +1,57 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function clickStepOver(dbg) {
clickElement(dbg, "stepOver");
return waitForPaused(dbg);
}
function clickStepIn(dbg) {
clickElement(dbg, "stepIn");
return waitForPaused(dbg);
}
function clickStepOut(dbg) {
clickElement(dbg, "stepOut");
return waitForPaused(dbg);
}
/**
* Test debugger buttons
* 1. resume
* 2. stepOver
* 3. stepIn
* 4. stepOver to the end of a function
* 5. stepUp at the end of a function
*/
add_task(function* () {
const dbg = yield initDebugger(
"doc-debugger-statements.html",
"debugger-statements.html"
);
yield reload(dbg);
yield waitForPaused(dbg);
assertPausedLocation(dbg, "debugger-statements.html", 8);
// resume
clickElement(dbg, "resume");
yield waitForPaused(dbg);
assertPausedLocation(dbg, "debugger-statements.html", 12);
// step over
yield clickStepOver(dbg);
assertPausedLocation(dbg, "debugger-statements.html", 13);
// step into
yield clickStepIn(dbg);
assertPausedLocation(dbg, "debugger-statements.html", 18);
// step over
yield clickStepOver(dbg);
assertPausedLocation(dbg, "debugger-statements.html", 20);
// step out
yield clickStepOut(dbg);
assertPausedLocation(dbg, "debugger-statements.html", 20);
});

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

@ -0,0 +1,64 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests the breakpoint gutter and making sure breakpoint icons exist
// correctly
// Utilities for interacting with the editor
function clickGutter(dbg, line) {
clickElement(dbg, "gutter", line);
}
function getLineEl(dbg, line) {
const lines = dbg.win.document.querySelectorAll(".CodeMirror-code > div");
return lines[line - 1];
}
function assertEditorBreakpoint(dbg, line, shouldExist) {
const exists = !!getLineEl(dbg, line).querySelector(".new-breakpoint");
ok(exists === shouldExist,
"Breakpoint " + (shouldExist ? "exists" : "does not exist") +
" on line " + line);
}
add_task(function* () {
const dbg = yield initDebugger("doc-scripts.html", "simple1.js");
const { selectors: { getBreakpoints, getBreakpoint }, getState } = dbg;
const source = findSource(dbg, "simple1.js");
yield selectSource(dbg, source.url);
// Make sure that clicking the gutter creates a breakpoint icon.
clickGutter(dbg, 4);
yield waitForDispatch(dbg, "ADD_BREAKPOINT");
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
assertEditorBreakpoint(dbg, 4, true);
// Make sure clicking at the same place removes the icon.
clickGutter(dbg, 4);
yield waitForDispatch(dbg, "REMOVE_BREAKPOINT");
is(getBreakpoints(getState()).size, 0, "No breakpoints exist");
assertEditorBreakpoint(dbg, 4, false);
// Test that a breakpoint icon slides down to the correct line.
clickGutter(dbg, 2);
yield waitForDispatch(dbg, "ADD_BREAKPOINT");
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
ok(getBreakpoint(getState(), { sourceId: source.id, line: 4 }),
"Breakpoint has correct line");
assertEditorBreakpoint(dbg, 2, false);
assertEditorBreakpoint(dbg, 4, true);
// Do the same sliding and make sure it works if there's already a
// breakpoint.
clickGutter(dbg, 2);
yield waitForDispatch(dbg, "ADD_BREAKPOINT");
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
assertEditorBreakpoint(dbg, 2, false);
assertEditorBreakpoint(dbg, 4, true);
clickGutter(dbg, 4);
yield waitForDispatch(dbg, "REMOVE_BREAKPOINT");
is(getBreakpoints(getState()).size, 0, "No breakpoints exist");
assertEditorBreakpoint(dbg, 4, false);
});

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

@ -0,0 +1,17 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that the editor sets the correct mode for different file
// types
add_task(function* () {
const dbg = yield initDebugger(
"doc-scripts.html",
"simple1.js", "doc-scripts.html"
);
yield selectSource(dbg, "simple1.js");
is(dbg.win.cm.getOption("mode").name, "javascript", "Mode is correct");
yield selectSource(dbg, "doc-scripts.html");
is(dbg.win.cm.getOption("mode").name, "htmlmixed", "Mode is correct");
});

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

@ -0,0 +1,52 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that the editor highlights the correct location when the
// debugger pauses
// checks to see if the first breakpoint is visible
function isBreakpointVisible(dbg) {
const bpLine = findElement(dbg, "breakpoint");
const cm = findElement(dbg, "codeMirror");
ok(isVisibleWithin(cm, bpLine), "CodeMirror is scrolled to line");
}
add_task(function* () {
const dbg = yield initDebugger(
"doc-scripts.html",
"simple1.js", "simple2.js", "long.js"
);
const { selectors: { getSelectedSource }, getState } = dbg;
const simple1 = findSource(dbg, "simple1.js");
const simple2 = findSource(dbg, "simple2.js");
// Set the initial breakpoint.
yield addBreakpoint(dbg, simple1.id, 4);
ok(!getSelectedSource(getState()), "No selected source");
// Call the function that we set a breakpoint in.
invokeInTab("main");
yield waitForPaused(dbg);
assertPausedLocation(dbg, simple1, 4);
// Step through to another file and make sure it's paused in the
// right place.
yield stepIn(dbg);
assertPausedLocation(dbg, simple2, 2);
// Step back out to the initial file.
yield stepOut(dbg);
yield stepOut(dbg);
assertPausedLocation(dbg, simple1, 5);
yield resume(dbg);
// Make sure that we can set a breakpoint on a line out of the
// viewport, and that pausing there scrolls the editor to it.
const longSrc = findSource(dbg, "long.js");
yield addBreakpoint(dbg, longSrc.id, 66);
invokeInTab("testModel");
yield waitForPaused(dbg);
assertPausedLocation(dbg, longSrc, 66);
isBreakpointVisible(dbg);
});

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

@ -0,0 +1,26 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test debugging a page with iframes
* 1. pause in the main thread
* 2. pause in the iframe
*/
add_task(function* () {
const dbg = yield initDebugger("doc-iframes.html", "iframes.html");
// test pausing in the main thread
yield reload(dbg);
yield waitForPaused(dbg);
assertPausedLocation(dbg, "iframes.html", 8);
// test pausing in the iframe
yield resume(dbg);
yield waitForPaused(dbg);
assertPausedLocation(dbg, "debugger-statements.html", 8);
// test pausing in the iframe
yield resume(dbg);
yield waitForPaused(dbg);
assertPausedLocation(dbg, "debugger-statements.html", 12);
});

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

@ -0,0 +1,46 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function uncaughtException() {
return invokeInTab("uncaughtException").catch(() => {});
}
function caughtException() {
return invokeInTab("caughtException");
}
/*
Tests Pausing on exception
1. skip an uncaught exception
2. pause on an uncaught exception
3. pause on a caught error
4. skip a caught error
*/
add_task(function* () {
const dbg = yield initDebugger("doc-exceptions.html", "exceptions.js");
// test skipping an uncaught exception
yield togglePauseOnExceptions(dbg, false, false);
yield uncaughtException();
ok(!isPaused(dbg));
// Test pausing on an uncaught exception
yield togglePauseOnExceptions(dbg, true, false);
uncaughtException();
yield waitForPaused(dbg);
assertPausedLocation(dbg, "exceptions.js", 2);
yield resume(dbg);
// Test pausing on a caught Error
caughtException();
yield waitForPaused(dbg);
assertPausedLocation(dbg, "exceptions.js", 15);
yield resume(dbg);
// Test skipping a caught error
yield togglePauseOnExceptions(dbg, true, true);
caughtException();
yield waitForPaused(dbg);
assertPausedLocation(dbg, "exceptions.js", 17);
yield resume(dbg);
});

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

@ -1,7 +0,0 @@
add_task(function*() {
ok(true,
"This is a stub so that we can run the new debugger tests " +
"by copying them in here. This will go away once we land " +
"the initial suite of new tests");
});

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

@ -0,0 +1,7 @@
### Test Examples
##### Pages
* **doc_script-switching-01** - includes two scripts that reference each other. The second function has a debugger.
* **doc-scripts** - includes three sources, a long source and two sources that reference each other.
* **doc-iframes** - includes an iframe with the debugger statements source.
* **debugger-statements** - inline script with functions for testing stepping.

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

@ -0,0 +1,19 @@
function uncaughtException() {
throw "unreachable"
}
function caughtError() {
try {
throw new Error("error");
} catch (e) {
debugger;
}
}
function caughtException() {
try {
throw "reachable";
} catch (e) {
debugger;
}
}

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

@ -0,0 +1,76 @@
var app = {};
// Generic "model" object. You can use whatever
// framework you want. For this application it
// may not even be worth separating this logic
// out, but we do this to demonstrate one way to
// separate out parts of your application.
app.TodoModel = function (key) {
this.key = key;
this.todos = [];
this.onChanges = [];
};
app.TodoModel.prototype.addTodo = function (title) {
this.todos = this.todos.concat([{
id: Utils.uuid(),
title: title,
completed: false
}]);
};
app.TodoModel.prototype.inform = function() {
// Something changed, but we do nothing
return null;
};
app.TodoModel.prototype.toggleAll = function (checked) {
// Note: it's usually better to use immutable data structures since they're
// easier to reason about and React works very well with them. That's why
// we use map() and filter() everywhere instead of mutating the array or
// todo items themselves.
this.todos = this.todos.map(function (todo) {
return Object.assign({}, todo, {completed: checked});
});
this.inform();
};
app.TodoModel.prototype.toggle = function (todoToToggle) {
this.todos = this.todos.map(function (todo) {
return todo !== todoToToggle ?
todo :
Object.assign({}, todo, {completed: !todo.completed});
});
this.inform();
};
app.TodoModel.prototype.destroy = function (todo) {
this.todos = this.todos.filter(function (candidate) {
return candidate !== todo;
});
this.inform();
};
app.TodoModel.prototype.save = function (todoToSave, text) {
this.todos = this.todos.map(function (todo) {
return todo !== todoToSave ? todo : Object.assign({}, todo, {title: text});
});
this.inform();
};
app.TodoModel.prototype.clearCompleted = function () {
this.todos = this.todos.filter(function (todo) {
return !todo.completed;
});
this.inform();
};
function testModel() {
const model = new app.TodoModel();
model.clearCompleted();
}

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

@ -0,0 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function firstCall() {
secondCall();
}

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

@ -0,0 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function secondCall() {
// This comment is useful: ☺
debugger;
function foo() {}
if (x) {
foo();
}
}
var x = true;

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

@ -0,0 +1,7 @@
function main() {
// A comment so we can test that breakpoint sliding works across
// multiple lines
const func = foo(1, 2);
const result = func();
return result;
}

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

@ -0,0 +1,6 @@
function foo(x, y) {
function bar() {
return x + y;
}
return bar;
}

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

@ -0,0 +1,27 @@
<html>
<head>
<title>Debugger Statements</title>
</head>
<body>
<script>
debugger;
test();
function test() {
debugger;
stepIntoMe();
}
function stepIntoMe() {
// step in
stepOverMe();
// step out
}
function stepOverMe() {
}
</script>
</body>
</html>

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

@ -0,0 +1,7 @@
<html>
<head>
<title>Debugger test page</title>
<script type="text/javascript" src="code-exceptions.js"></script>
</head>
<body></body>
</html>

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

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

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

@ -0,0 +1,18 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Debugger test page</title>
</head>
<body>
<button onclick="firstCall()">Click me!</button>
<script type="text/javascript" src="code-script-switching-01.js"></script>
<script type="text/javascript" src="code-script-switching-02.js"></script>
</body>
</html>

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

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

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

@ -0,0 +1,316 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// shared-head.js handles imports, constants, and utility functions
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this);
var { Toolbox } = require("devtools/client/framework/toolbox");
const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/new/test/mochitest/examples/";
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
delete window.resumeTest;
})
// Wait until an action of `type` is dispatched. This is different
// then `_afterDispatchDone` because it doesn't wait for async actions
// to be done/errored. Use this if you want to listen for the "start"
// action of an async operation (somewhat rare).
function waitForNextDispatch(store, type) {
return new Promise(resolve => {
store.dispatch({
// Normally we would use `services.WAIT_UNTIL`, but use the
// internal name here so tests aren't forced to always pass it
// in
type: "@@service/waitUntil",
predicate: action => action.type === type,
run: (dispatch, getState, action) => {
resolve(action);
}
});
});
}
// Wait until an action of `type` is dispatched. If it's part of an
// async operation, wait until the `status` field is "done" or "error"
function _afterDispatchDone(store, type) {
return new Promise(resolve => {
store.dispatch({
// Normally we would use `services.WAIT_UNTIL`, but use the
// internal name here so tests aren't forced to always pass it
// in
type: "@@service/waitUntil",
predicate: action => {
if (action.type === type) {
return action.status ?
(action.status === "done" || action.status === "error") :
true;
}
},
run: (dispatch, getState, action) => {
resolve(action);
}
});
});
}
function waitForDispatch(dbg, type, eventRepeat = 1) {
let count = 0;
return Task.spawn(function* () {
info("Waiting for " + type + " to dispatch " + eventRepeat + " time(s)");
while (count < eventRepeat) {
yield _afterDispatchDone(dbg.store, type);
count++;
info(type + " dispatched " + count + " time(s)");
}
});
}
function waitForThreadEvents(dbg, eventName) {
info("Waiting for thread event '" + eventName + "' to fire.");
const thread = dbg.toolbox.threadClient;
return new Promise(function(resolve, reject) {
thread.addListener(eventName, function onEvent(eventName, ...args) {
info("Thread event '" + eventName + "' fired.");
thread.removeListener(eventName, onEvent);
resolve.apply(resolve, args);
});
});
}
function waitForState(dbg, predicate) {
return new Promise(resolve => {
const unsubscribe = dbg.store.subscribe(() => {
if (predicate(dbg.store.getState())) {
unsubscribe();
resolve();
}
});
});
}
function waitForMs(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
function assertPausedLocation(dbg, source, line) {
const { selectors: { getSelectedSource, getPause }, getState } = dbg;
// support passing in a partial url and fetching the source
if (typeof source == "string") {
source = findSource(dbg, source);
}
// check the selected source
is(getSelectedSource(getState()).get("url"), source.url);
// check the pause location
const location = getPause(getState()).getIn(["frame", "location"]);
is(location.get("sourceId"), source.id);
is(location.get("line"), line);
// check the debug line
ok(dbg.win.cm.lineInfo(line - 1).wrapClass.includes("debug-line"),
"Line is highlighted");
}
function isPaused(dbg) {
const { selectors: { getPause }, getState } = dbg;
return !!getPause(getState());
}
const waitForPaused = Task.async(function* (dbg) {
// We want to make sure that we get both a real paused event and
// that the state is fully populated. The client may do some more
// work (call other client methods) before populating the state.
return Promise.all([
yield waitForThreadEvents(dbg, "paused"),
yield waitForState(dbg, state => {
const pause = dbg.selectors.getPause(state);
// Make sure we have the paused state.
if(!pause) {
return false;
}
// Make sure the source text is completely loaded for the
// source we are paused in.
const sourceId = pause.getIn(["frame", "location", "sourceId"]);
const sourceText = dbg.selectors.getSourceText(dbg.getState(), sourceId);
return sourceText && !sourceText.get("loading");
})
]);
});
const initDebugger = Task.async(function* (url, ...sources) {
const toolbox = yield openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger");
const win = toolbox.getPanel("jsdebugger").panelWin;
const store = win.Debugger.store;
const { getSources } = win.Debugger.selectors;
const dbg = {
actions: win.Debugger.actions,
selectors: win.Debugger.selectors,
getState: store.getState,
store: store,
client: win.Debugger.client,
toolbox: toolbox,
win: win
};
if(sources.length) {
// TODO: Extract this out to a utility function
info("Waiting on sources: " + sources.join(", "));
yield Promise.all(sources.map(url => {
function sourceExists(state) {
return getSources(state).some(s => s.get("url").includes(url));
}
if(!sourceExists(store.getState())) {
return waitForState(dbg, sourceExists);
}
}));
}
return dbg;
});
window.resumeTest = undefined;
function pauseTest() {
info("Test paused. Invoke resumeTest to continue.");
return new Promise(resolve => resumeTest = resolve);
}
// Actions
function findSource(dbg, url) {
const sources = dbg.selectors.getSources(dbg.getState());
const source = sources.find(s => s.get("url").includes(url));
if(!source) {
throw new Error("Unable to find source: " + url);
}
return source.toJS();
}
function selectSource(dbg, url) {
info("Selecting source: " + url);
const source = findSource(dbg, url);
dbg.actions.selectSource(source.id);
return waitForDispatch(dbg, "LOAD_SOURCE_TEXT");
}
function stepOver(dbg) {
info("Stepping over");
dbg.actions.stepOver();
return waitForPaused(dbg);
}
function stepIn(dbg) {
info("Stepping in");
dbg.actions.stepIn();
return waitForPaused(dbg);
}
function stepOut(dbg) {
info("Stepping out");
dbg.actions.stepOut();
return waitForPaused(dbg);
}
function resume(dbg) {
info("Resuming");
dbg.actions.resume();
return waitForThreadEvents(dbg, "resumed");
}
function reload(dbg) {
return dbg.client.reload();
}
function addBreakpoint(dbg, sourceId, line, col) {
return dbg.actions.addBreakpoint({ sourceId, line, col });
}
function togglePauseOnExceptions(dbg,
pauseOnExceptions, ignoreCaughtExceptions) {
const command = dbg.actions.pauseOnExceptions(
pauseOnExceptions,
ignoreCaughtExceptions
);
if (!isPaused(dbg)) {
return waitForThreadEvents(dbg, "resumed");
}
return command;
}
// Helpers
// invoke a global function in the debugged tab
function invokeInTab(fnc) {
return ContentTask.spawn(gBrowser.selectedBrowser, fnc, function* (fnc) {
content.wrappedJSObject[fnc](); // eslint-disable-line mozilla/no-cpows-in-tests, max-len
});
}
function isVisibleWithin(outerEl, innerEl) {
const innerRect = innerEl.getBoundingClientRect();
const outerRect = outerEl.getBoundingClientRect();
return innerRect.top > outerRect.top &&
innerRect.bottom < outerRect.bottom;
}
const selectors = {
callStackHeader: ".call-stack-pane ._header",
frame: index => `.frames ul li:nth-child(${index})`,
gutter: i => `.CodeMirror-code *:nth-child(${i}) .CodeMirror-linenumber`,
pauseOnExceptions: ".pause-exceptions",
breakpoint: ".CodeMirror-code > .new-breakpoint",
codeMirror: ".CodeMirror",
resume: ".resume.active",
stepOver: ".stepOver.active",
stepOut: ".stepOut.active",
stepIn: ".stepIn.active"
}
function getSelector(elementName, ...args) {
let selector = selectors[elementName];
if (!selector) {
throw new Error(`The selector ${elementName} is not defined`);
}
if (typeof selector == "function") {
selector = selector(...args)
}
return selector;
}
function findElement(dbg, elementName, ...args) {
const selector = getSelector(elementName, ...args);
return dbg.win.document.querySelector(selector);
}
// click an element in the debugger
function clickElement(dbg, elementName, ...args) {
const selector = getSelector(elementName, ...args);
const doc = dbg.win.document;
return EventUtils.synthesizeMouseAtCenter(
doc.querySelector(selector),
{},
dbg.win
);
}
function toggleCallStack(dbg) {
return findElement(dbg, "callStackHeader").click()
}

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

@ -13,15 +13,23 @@ module.exports = createClass({
render() {
let {
onRecordButtonClick,
isRecording
isRecording,
isLocked
} = this.props;
let classList = ["devtools-button", "record-button"];
if (isRecording) {
classList.push("checked");
}
return button(
{
className: "devtools-toolbarbutton record-button",
className: classList.join(" "),
onClick: onRecordButtonClick,
"data-standalone": "true",
"data-text-only": "true",
disabled: isLocked
},
isRecording ? L10N.getStr("recordings.stop") : L10N.getStr("recordings.start")
);

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

@ -10,24 +10,6 @@ const {div, button} = DOM;
module.exports = createClass({
displayName: "Recording Controls",
/**
* Manually handle the "checked" and "locked" attributes, as the DOM element won't
* change by just by changing the checked attribute through React.
*/
componentDidUpdate() {
if (this.props.isRecording) {
this._recordButton.setAttribute("checked", true);
} else {
this._recordButton.removeAttribute("checked");
}
if (this.props.isLocked) {
this._recordButton.setAttribute("locked", true);
} else {
this._recordButton.removeAttribute("locked");
}
},
render() {
let {
onClearButtonClick,
@ -37,6 +19,12 @@ module.exports = createClass({
isLocked
} = this.props;
let recordButtonClassList = ["devtools-button", "record-button"];
if (isRecording) {
recordButtonClassList.push("checked");
}
return (
div({ className: "devtools-toolbar" },
div({ className: "toolbar-group" },
@ -48,14 +36,10 @@ module.exports = createClass({
}),
button({
id: "main-record-button",
className: "devtools-button record-button",
className: recordButtonClassList.join(" "),
disabled: isLocked,
title: L10N.getStr("recordings.start.tooltip"),
onClick: onRecordButtonClick,
checked: isRecording,
ref: (el) => {
this._recordButton = el;
},
locked: isLocked
onClick: onRecordButtonClick
}),
button({
id: "import-button",

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

@ -16,13 +16,11 @@ add_task(function* () {
win: window
});
let { $, EVENTS, PerformanceController, PerformanceView } = panel.panelWin;
let { $, $$, EVENTS, PerformanceController, PerformanceView } = panel.panelWin;
let recordButton = $("#main-record-button");
ok(!recordButton.hasAttribute("checked"),
"The record button should not be checked yet.");
ok(!recordButton.hasAttribute("locked"),
"The record button should not be locked yet.");
checkRecordButtonsStates(false, false);
let uiStartClick = once(PerformanceView, EVENTS.UI_START_RECORDING);
let recordingStarted = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
@ -37,17 +35,11 @@ add_task(function* () {
click(recordButton);
yield uiStartClick;
ok(recordButton.hasAttribute("checked"),
"The record button should now be checked.");
ok(recordButton.hasAttribute("locked"),
"The record button should be locked.");
checkRecordButtonsStates(true, true);
yield recordingStarted;
ok(recordButton.hasAttribute("checked"),
"The record button should still be checked.");
ok(!recordButton.hasAttribute("locked"),
"The record button should not be locked.");
checkRecordButtonsStates(true, false);
yield backendStartReady;
yield uiStateRecording;
@ -66,13 +58,19 @@ add_task(function* () {
yield uiStopClick;
yield recordingStopped;
ok(!recordButton.hasAttribute("checked"),
"The record button should not be checked.");
ok(!recordButton.hasAttribute("locked"),
"The record button should not be locked.");
checkRecordButtonsStates(false, false);
yield backendStopReady;
yield uiStateRecorded;
yield teardownToolboxAndRemoveTab(panel);
function checkRecordButtonsStates(checked, locked) {
for (let button of $$(".record-button")) {
is(button.classList.contains("checked"), checked,
"The record button checked state should be " + checked);
is(button.disabled, locked,
"The record button locked state should be " + locked);
}
}
});

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

@ -32,9 +32,9 @@ add_task(function* () {
RecordingsView.selectedIndex = 0;
yield selected;
ok($("#main-record-button").hasAttribute("checked"),
ok($("#main-record-button").classList.contains("checked"),
"Button is still checked after selecting another item.");
ok(!$("#main-record-button").hasAttribute("locked"),
ok(!$("#main-record-button").hasAttribute("disabled"),
"Button is not locked after selecting another item.");
yield stopRecording(panel);

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

@ -367,6 +367,7 @@ checkbox:-moz-focusring {
}
.devtools-button:hover:empty::before,
.devtools-button.checked:empty::before,
.devtools-button[checked]:empty::before,
.devtools-button[open]:empty::before,
.devtools-toolbarbutton:not([label]):hover > image,
@ -378,6 +379,7 @@ checkbox:-moz-focusring {
.devtools-button:disabled,
.devtools-button[disabled],
.devtools-toolbarbutton[disabled] {
pointer-events: none;
opacity: 0.5 !important;
}
@ -397,29 +399,31 @@ checkbox:-moz-focusring {
/* Text-only buttons */
.theme-light .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]),
.theme-light .devtools-toolbarbutton[data-text-only] {
.theme-light .devtools-toolbarbutton[data-text-only],
.theme-light .devtools-button:not(:empty) {
background-color: var(--toolbar-tab-hover);
}
.theme-dark .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]),
.theme-dark .devtools-toolbarbutton[data-text-only] {
.theme-dark .devtools-toolbarbutton[data-text-only],
.theme-dark .devtools-button:not(:empty) {
background-color: rgba(0, 0, 0, .2); /* Splitter */
}
/* Text-only button states */
.theme-dark .devtools-button:not(:empty):not([disabled]):hover,
.theme-dark .devtools-button:not(:empty):not(:disabled):hover,
.theme-dark .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled],[text-as-image]))[label]:hover {
background: rgba(0, 0, 0, .3); /* Splitters */
}
.theme-light .devtools-button:not(:empty):not([disabled]):hover,
.theme-light .devtools-button:not(:empty):not(:disabled):hover,
.theme-light .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled],[text-as-image]))[label]:hover {
background: rgba(170, 170, 170, .3); /* Splitters */
}
.theme-dark .devtools-button:not(:empty):not([disabled]):hover:active,
.theme-dark .devtools-button:not(:empty):not(:disabled):hover:active,
.theme-dark .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled],[text-as-image]))[label]:hover:active {
background: rgba(0, 0, 0, .4); /* Splitters */
}
.theme-light .devtools-button:not(:empty):not([disabled]):hover:active,
.theme-light .devtools-button:not(:empty):not(:disabled):hover:active,
.theme-light .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled],[text-as-image]))[label]:hover:active {
background: var(--toolbar-tab-hover-active);
}

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

@ -116,17 +116,12 @@
padding: 5px !important;
}
.notice-container .record-button[checked],
.notice-container .record-button[checked] {
.notice-container .record-button.checked,
.notice-container .record-button.checked {
color: var(--theme-selection-color) !important;
background: var(--theme-selection-background) !important;
}
.record-button[locked] {
pointer-events: none;
opacity: 0.5;
}
/* Sidebar & recording items */
#recordings-pane {

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

@ -238,8 +238,7 @@ Finder.prototype = {
},
highlight: Task.async(function* (aHighlight, aWord, aLinksOnly) {
let found = yield this.highlighter.highlight(aHighlight, aWord, null, aLinksOnly);
this.highlighter.notifyFinished({ highlight: aHighlight, found });
yield this.highlighter.highlight(aHighlight, aWord, null, aLinksOnly);
}),
getInitialSelection: function() {

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

@ -224,6 +224,8 @@ FinderHighlighter.prototype = {
this._found = true;
}
this.notifyFinished({ highlight, found: this._found });
return this._found;
}),

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

@ -3,12 +3,15 @@
Cu.import("resource://testing-common/BrowserTestUtils.jsm", this);
Cu.import("resource://testing-common/ContentTask.jsm", this);
Cu.import("resource://gre/modules/Promise.jsm", this);
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/Task.jsm", this);
Cu.import("resource://gre/modules/Timer.jsm", this);
Cu.import("resource://gre/modules/AppConstants.jsm");
const kHighlightAllPref = "findbar.highlightAll";
const kPrefModalHighlight = "findbar.modalHighlight";
const kFixtureBaseURL = "https://example.com/browser/toolkit/modules/tests/browser/";
const kIteratorTimeout = Services.prefs.getIntPref("findbar.iteratorTimeout");
function promiseOpenFindbar(findbar) {
findbar.onFindCommand()
@ -155,8 +158,8 @@ add_task(function* testModalResults() {
}],
["o", {
rectCount: 492,
insertCalls: [1, 4],
removeCalls: [1, 3]
insertCalls: [1, 5],
removeCalls: [1, 4]
}]
]);
let url = kFixtureBaseURL + "file_FinderSample.html";
@ -167,6 +170,7 @@ add_task(function* testModalResults() {
yield promiseOpenFindbar(findbar);
Assert.ok(!findbar.hidden, "Findbar should be open now.");
yield new Promise(resolve => setTimeout(resolve, kIteratorTimeout));
let promise = promiseTestHighlighterOutput(browser, word, expectedResult);
yield promiseEnterStringIntoFindField(findbar, word);
yield promise;
@ -311,3 +315,28 @@ add_task(function* testHighlightAllToggle() {
yield promise;
});
});
add_task(function* testXMLDocument() {
let url = "data:text/xml;charset=utf-8," + encodeURIComponent(`<?xml version="1.0"?>
<result>
<Title>Example</Title>
<Error>Error</Error>
</result>`);
yield BrowserTestUtils.withNewTab(url, function* (browser) {
let findbar = gBrowser.getFindBar();
yield promiseOpenFindbar(findbar);
let word = "Example";
let expectedResult = {
rectCount: 0,
insertCalls: [1, 4],
removeCalls: [1, 2]
};
let promise = promiseTestHighlighterOutput(browser, word, expectedResult);
yield promiseEnterStringIntoFindField(findbar, word);
yield promise;
findbar.close(true);
});
});