diff --git a/BUILD.gn b/BUILD.gn
index 7b22252a1a..e0294a700f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -41,7 +41,6 @@ devtools_modules_js_files =
gypi_values.devtools_layers_js_files +
gypi_values.devtools_network_js_files +
gypi_values.devtools_profiler_js_files +
- gypi_values.devtools_promises_js_files +
gypi_values.devtools_resources_js_files +
gypi_values.devtools_sass_js_files +
gypi_values.devtools_security_js_files +
@@ -150,7 +149,6 @@ action("generate_devtools_grd") {
resources_out_dir + "layers_module.js",
resources_out_dir + "network_module.js",
resources_out_dir + "profiler_module.js",
- resources_out_dir + "promises_module.js",
resources_out_dir + "resources_module.js",
resources_out_dir + "sass_module.js",
resources_out_dir + "security_module.js",
@@ -282,7 +280,6 @@ action("build_applications") {
resources_out_dir + "layers_module.js",
resources_out_dir + "network_module.js",
resources_out_dir + "profiler_module.js",
- resources_out_dir + "promises_module.js",
resources_out_dir + "resources_module.js",
resources_out_dir + "sass_module.js",
resources_out_dir + "security_module.js",
diff --git a/devtools.gyp b/devtools.gyp
index ab14a9aa8f..bfb3128eee 100644
--- a/devtools.gyp
+++ b/devtools.gyp
@@ -115,7 +115,6 @@
'<(PRODUCT_DIR)/resources/inspector/layers_module.js',
'<(PRODUCT_DIR)/resources/inspector/network_module.js',
'<(PRODUCT_DIR)/resources/inspector/profiler_module.js',
- '<(PRODUCT_DIR)/resources/inspector/promises_module.js',
'<(PRODUCT_DIR)/resources/inspector/resources_module.js',
'<(PRODUCT_DIR)/resources/inspector/sass_module.js',
'<(PRODUCT_DIR)/resources/inspector/security_module.js',
@@ -283,7 +282,6 @@
'<(_output_path)/layers_module.js',
'<(_output_path)/network_module.js',
'<(_output_path)/profiler_module.js',
- '<(_output_path)/promises_module.js',
'<(_output_path)/resources_module.js',
'<(_output_path)/sass_module.js',
'<(_output_path)/security_module.js',
diff --git a/devtools.gypi b/devtools.gypi
index 27a3c6cb7c..04ddd729ee 100644
--- a/devtools.gypi
+++ b/devtools.gypi
@@ -105,6 +105,7 @@
'front_end/components/ObjectPopoverHelper.js',
'front_end/components/ObjectPropertiesSection.js',
'front_end/components/RemoteObjectPreviewFormatter.js',
+ 'front_end/components/RequestAppBannerActionDelegate.js',
'front_end/components/ShortcutsScreen.js',
'front_end/components/EventListenersUtils.js',
'front_end/components/EventListenersView.js',
@@ -337,7 +338,6 @@
'front_end/network/module.json',
'front_end/platform/module.json',
'front_end/profiler/module.json',
- 'front_end/promises/module.json',
'front_end/resources/module.json',
'front_end/sass/module.json',
'front_end/security/module.json',
@@ -497,10 +497,6 @@
'front_end/extensions/ExtensionView.js',
'<@(devtools_extension_api_files)',
],
- 'devtools_promises_js_files': [
- 'front_end/promises/promisePane.css',
- 'front_end/promises/PromisePane.js',
- ],
'devtools_heap_snapshot_worker_js_files': [
'front_end/common/TextUtils.js',
'front_end/common/UIString.js',
@@ -775,7 +771,6 @@
'<@(devtools_layers_js_files)',
'<@(devtools_network_js_files)',
'<@(devtools_profiler_js_files)',
- '<@(devtools_promises_js_files)',
'<@(devtools_resources_js_files)',
'<@(devtools_sass_js_files)',
'<@(devtools_security_js_files)',
@@ -823,7 +818,6 @@
'front_end/Images/localStorage.png',
'front_end/Images/navigationControls.png',
'front_end/Images/navigationControls_2x.png',
- 'front_end/Images/notifications.svg',
'front_end/Images/paneAddButtons.png',
'front_end/Images/paneFilterButtons.png',
'front_end/Images/paneRefreshButtons.png',
@@ -867,7 +861,6 @@
'front_end/Images/toolbarItemSelected.png',
'front_end/Images/touchCursor.png',
'front_end/Images/touchCursor_2x.png',
- 'front_end/Images/updateServiceWorker.svg',
],
'devtools_extension_api_files': [
'front_end/extensions/ExtensionAPI.js',
diff --git a/front_end/Images/notifications.svg b/front_end/Images/notifications.svg
deleted file mode 100644
index ec2adeddc5..0000000000
--- a/front_end/Images/notifications.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/front_end/Images/src/optimize_png.hashes b/front_end/Images/src/optimize_png.hashes
index 25464fd48b..36fe3b8b14 100644
--- a/front_end/Images/src/optimize_png.hashes
+++ b/front_end/Images/src/optimize_png.hashes
@@ -3,5 +3,5 @@
"breakpoint.svg": "69cd92d807259c022791112809b97799",
"settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485",
"breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
- "toolbarButtonGlyphs.svg": "fcf3159499e07a580dc9bd827d4f627f"
+ "toolbarButtonGlyphs.svg": "304b6a326639d26c4710d57205413323"
}
\ No newline at end of file
diff --git a/front_end/Images/src/svg2png.hashes b/front_end/Images/src/svg2png.hashes
index 25464fd48b..36fe3b8b14 100644
--- a/front_end/Images/src/svg2png.hashes
+++ b/front_end/Images/src/svg2png.hashes
@@ -3,5 +3,5 @@
"breakpoint.svg": "69cd92d807259c022791112809b97799",
"settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485",
"breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
- "toolbarButtonGlyphs.svg": "fcf3159499e07a580dc9bd827d4f627f"
+ "toolbarButtonGlyphs.svg": "304b6a326639d26c4710d57205413323"
}
\ No newline at end of file
diff --git a/front_end/Images/src/toolbarButtonGlyphs.svg b/front_end/Images/src/toolbarButtonGlyphs.svg
index 779809e51e..fd43823dc8 100644
--- a/front_end/Images/src/toolbarButtonGlyphs.svg
+++ b/front_end/Images/src/toolbarButtonGlyphs.svg
@@ -21,13 +21,13 @@
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
\ No newline at end of file
+ sketch:type="MSShapeGroup" />
\ No newline at end of file
diff --git a/front_end/Images/toolbarButtonGlyphs.png b/front_end/Images/toolbarButtonGlyphs.png
index c19a2bf2ae..fad9b5ec30 100644
Binary files a/front_end/Images/toolbarButtonGlyphs.png and b/front_end/Images/toolbarButtonGlyphs.png differ
diff --git a/front_end/Images/toolbarButtonGlyphs_2x.png b/front_end/Images/toolbarButtonGlyphs_2x.png
index 0a8df07151..939de055b2 100644
Binary files a/front_end/Images/toolbarButtonGlyphs_2x.png and b/front_end/Images/toolbarButtonGlyphs_2x.png differ
diff --git a/front_end/Images/updateServiceWorker.svg b/front_end/Images/updateServiceWorker.svg
deleted file mode 100644
index 2362003f11..0000000000
--- a/front_end/Images/updateServiceWorker.svg
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
diff --git a/front_end/Tests.js b/front_end/Tests.js
index 81e0557550..af9d033d9a 100644
--- a/front_end/Tests.js
+++ b/front_end/Tests.js
@@ -978,7 +978,7 @@ TestSuite.prototype.evaluateInConsole_ = function(code, callback)
function innerEvaluate()
{
WebInspector.context.removeFlavorChangeListener(WebInspector.ExecutionContext, showConsoleAndEvaluate, this);
- var consoleView = WebInspector.ConsolePanel._view();
+ var consoleView = WebInspector.ConsoleView.instance();
consoleView._prompt.setText(code);
consoleView._promptElement.dispatchEvent(TestSuite.createKeyEvent("Enter"));
diff --git a/front_end/animation/AnimationModel.js b/front_end/animation/AnimationModel.js
index cbcb11098b..9831cb8873 100644
--- a/front_end/animation/AnimationModel.js
+++ b/front_end/animation/AnimationModel.js
@@ -771,7 +771,12 @@ WebInspector.AnimationModel.AnimationGroup.prototype = {
return !error ? currentTime : 0;
}
- return this.target().animationAgent().getCurrentTime(this._animations[0].id(), callback).catchException(0);
+ var longestAnim = null;
+ for (var anim of this._animations) {
+ if (!longestAnim || anim.endTime() > longestAnim.endTime())
+ longestAnim = anim;
+ }
+ return this.target().animationAgent().getCurrentTime(longestAnim.id(), callback).catchException(0);
},
/**
diff --git a/front_end/bindings/BlackboxManager.js b/front_end/bindings/BlackboxManager.js
index 9e16e76f24..16e11e30c9 100644
--- a/front_end/bindings/BlackboxManager.js
+++ b/front_end/bindings/BlackboxManager.js
@@ -117,6 +117,7 @@ WebInspector.BlackboxManager.prototype = {
if (!mappings.length) {
if (previousScriptState.length > 0)
return this._setScriptState(script, []);
+ return Promise.resolve();
}
var currentBlackboxed = false;
diff --git a/front_end/bindings/BreakpointManager.js b/front_end/bindings/BreakpointManager.js
index 53446c5b79..867152495d 100644
--- a/front_end/bindings/BreakpointManager.js
+++ b/front_end/bindings/BreakpointManager.js
@@ -739,8 +739,7 @@ WebInspector.BreakpointManager.TargetBreakpoint = function(debuggerModel, breakp
this._networkMapping = networkMapping;
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
- /** @type {!Array.} */
- this._liveLocations = [];
+ this._liveLocations = new WebInspector.LiveLocationPool();
/** @type {!Object.} */
this._uiLocations = {};
@@ -763,10 +762,7 @@ WebInspector.BreakpointManager.TargetBreakpoint.prototype = {
this._breakpoint._removeUILocation(uiLocations[i]);
this._uiLocations = {};
-
- for (var i = 0; i < this._liveLocations.length; ++i)
- this._liveLocations[i].dispose();
- this._liveLocations = [];
+ this._liveLocations.disposeAll();
},
_scheduleUpdateInDebugger: function()
@@ -944,7 +940,7 @@ WebInspector.BreakpointManager.TargetBreakpoint.prototype = {
this._breakpoint.remove();
return false;
}
- this._liveLocations.push(this._debuggerWorkspaceBinding.createLiveLocation(location, this._locationUpdated.bind(this, location)));
+ this._debuggerWorkspaceBinding.createLiveLocation(location, this._locationUpdated.bind(this, location), this._liveLocations);
return true;
},
diff --git a/front_end/bindings/CSSWorkspaceBinding.js b/front_end/bindings/CSSWorkspaceBinding.js
index 044b691ba2..41bb76a811 100644
--- a/front_end/bindings/CSSWorkspaceBinding.js
+++ b/front_end/bindings/CSSWorkspaceBinding.js
@@ -101,12 +101,13 @@ WebInspector.CSSWorkspaceBinding.prototype = {
/**
* @param {!WebInspector.CSSLocation} rawLocation
* @param {function(!WebInspector.LiveLocation)} updateDelegate
+ * @param {!WebInspector.LiveLocationPool} locationPool
* @return {!WebInspector.CSSWorkspaceBinding.LiveLocation}
*/
- createLiveLocation: function(rawLocation, updateDelegate)
+ createLiveLocation: function(rawLocation, updateDelegate, locationPool)
{
var header = rawLocation.styleSheetId ? rawLocation.cssModel().styleSheetHeaderForId(rawLocation.styleSheetId) : null;
- return new WebInspector.CSSWorkspaceBinding.LiveLocation(rawLocation.cssModel(), header, rawLocation, this, updateDelegate);
+ return new WebInspector.CSSWorkspaceBinding.LiveLocation(rawLocation.cssModel(), header, rawLocation, this, updateDelegate, locationPool);
},
/**
@@ -313,16 +314,17 @@ WebInspector.CSSWorkspaceBinding.HeaderInfo.prototype = {
/**
* @constructor
- * @extends {WebInspector.LiveLocation}
+ * @extends {WebInspector.LiveLocationWithPool}
* @param {!WebInspector.CSSModel} cssModel
* @param {?WebInspector.CSSStyleSheetHeader} header
* @param {!WebInspector.CSSLocation} rawLocation
* @param {!WebInspector.CSSWorkspaceBinding} binding
* @param {function(!WebInspector.LiveLocation)} updateDelegate
+ * @param {!WebInspector.LiveLocationPool} locationPool
*/
-WebInspector.CSSWorkspaceBinding.LiveLocation = function(cssModel, header, rawLocation, binding, updateDelegate)
+WebInspector.CSSWorkspaceBinding.LiveLocation = function(cssModel, header, rawLocation, binding, updateDelegate, locationPool)
{
- WebInspector.LiveLocation.call(this, updateDelegate);
+ WebInspector.LiveLocationWithPool.call(this, updateDelegate, locationPool);
this._cssModel = cssModel;
this._rawLocation = rawLocation;
this._binding = binding;
@@ -392,9 +394,12 @@ WebInspector.CSSWorkspaceBinding.LiveLocation.prototype = {
return uiSourceCode.uiLocation(cssLocation.lineNumber, cssLocation.columnNumber);
},
+ /**
+ * @override
+ */
dispose: function()
{
- WebInspector.LiveLocation.prototype.dispose.call(this);
+ WebInspector.LiveLocationWithPool.prototype.dispose.call(this);
if (this._header)
this._binding._removeLiveLocation(this);
this._cssModel.removeEventListener(WebInspector.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
@@ -410,7 +415,7 @@ WebInspector.CSSWorkspaceBinding.LiveLocation.prototype = {
return false;
},
- __proto__: WebInspector.LiveLocation.prototype
+ __proto__: WebInspector.LiveLocationWithPool.prototype
}
/**
diff --git a/front_end/bindings/DebuggerWorkspaceBinding.js b/front_end/bindings/DebuggerWorkspaceBinding.js
index 313b8a4d5f..ab89ed06a2 100644
--- a/front_end/bindings/DebuggerWorkspaceBinding.js
+++ b/front_end/bindings/DebuggerWorkspaceBinding.js
@@ -122,13 +122,14 @@ WebInspector.DebuggerWorkspaceBinding.prototype = {
/**
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @param {function(!WebInspector.LiveLocation)} updateDelegate
+ * @param {!WebInspector.LiveLocationPool} locationPool
* @return {!WebInspector.DebuggerWorkspaceBinding.Location}
*/
- createLiveLocation: function(rawLocation, updateDelegate)
+ createLiveLocation: function(rawLocation, updateDelegate, locationPool)
{
var info = this._infoForScript(rawLocation.target(), rawLocation.scriptId);
console.assert(info);
- var location = new WebInspector.DebuggerWorkspaceBinding.Location(info._script, rawLocation, this, updateDelegate);
+ var location = new WebInspector.DebuggerWorkspaceBinding.Location(info._script, rawLocation, this, updateDelegate, locationPool);
info._addLocation(location);
return location;
},
@@ -136,12 +137,13 @@ WebInspector.DebuggerWorkspaceBinding.prototype = {
/**
* @param {!Array} rawLocations
* @param {function(!WebInspector.LiveLocation)} updateDelegate
+ * @param {!WebInspector.LiveLocationPool} locationPool
* @return {!WebInspector.LiveLocation}
*/
- createStackTraceTopFrameLiveLocation: function(rawLocations, updateDelegate)
+ createStackTraceTopFrameLiveLocation: function(rawLocations, updateDelegate, locationPool)
{
console.assert(rawLocations.length);
- var location = new WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation(rawLocations, this, updateDelegate);
+ var location = new WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation(rawLocations, this, updateDelegate, locationPool);
location.update();
return location;
},
@@ -149,13 +151,14 @@ WebInspector.DebuggerWorkspaceBinding.prototype = {
/**
* @param {!WebInspector.DebuggerModel.Location} location
* @param {function(!WebInspector.LiveLocation)} updateDelegate
+ * @param {!WebInspector.LiveLocationPool} locationPool
* @return {!WebInspector.DebuggerWorkspaceBinding.Location}
*/
- createCallFrameLiveLocation: function(location, updateDelegate)
+ createCallFrameLiveLocation: function(location, updateDelegate, locationPool)
{
var target = location.target();
this._ensureInfoForScript(location.script());
- var liveLocation = this.createLiveLocation(location, updateDelegate);
+ var liveLocation = this.createLiveLocation(location, updateDelegate, locationPool);
this._registerCallFrameLiveLocation(target, liveLocation);
return liveLocation;
},
@@ -281,7 +284,7 @@ WebInspector.DebuggerWorkspaceBinding.prototype = {
_reset: function(target)
{
var targetData = this._targetToData.get(target);
- targetData.callFrameLocations.valuesArray().forEach(function(location) { location.dispose(); });
+ targetData.callFrameLocations.valuesArray().forEach((location) => this._removeLiveLocation(location));
targetData.callFrameLocations.clear();
},
@@ -468,7 +471,7 @@ WebInspector.DebuggerWorkspaceBinding.ScriptInfo = function(script)
/** @type {!Array.} */
this._sourceMappings = [];
- /** @type {!Set.} */
+ /** @type {!Set} */
this._locations = new Set();
}
@@ -532,15 +535,16 @@ WebInspector.DebuggerWorkspaceBinding.ScriptInfo.prototype = {
/**
* @constructor
- * @extends {WebInspector.LiveLocation}
+ * @extends {WebInspector.LiveLocationWithPool}
* @param {!WebInspector.Script} script
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @param {!WebInspector.DebuggerWorkspaceBinding} binding
* @param {function(!WebInspector.LiveLocation)} updateDelegate
+ * @param {!WebInspector.LiveLocationPool} locationPool
*/
-WebInspector.DebuggerWorkspaceBinding.Location = function(script, rawLocation, binding, updateDelegate)
+WebInspector.DebuggerWorkspaceBinding.Location = function(script, rawLocation, binding, updateDelegate, locationPool)
{
- WebInspector.LiveLocation.call(this, updateDelegate);
+ WebInspector.LiveLocationWithPool.call(this, updateDelegate, locationPool);
this._script = script;
this._rawLocation = rawLocation;
this._binding = binding;
@@ -562,7 +566,7 @@ WebInspector.DebuggerWorkspaceBinding.Location.prototype = {
*/
dispose: function()
{
- WebInspector.LiveLocation.prototype.dispose.call(this);
+ WebInspector.LiveLocationWithPool.prototype.dispose.call(this);
this._binding._removeLiveLocation(this);
},
@@ -575,25 +579,26 @@ WebInspector.DebuggerWorkspaceBinding.Location.prototype = {
return WebInspector.blackboxManager.isBlackboxedRawLocation(this._rawLocation);
},
- __proto__: WebInspector.LiveLocation.prototype
+ __proto__: WebInspector.LiveLocationWithPool.prototype
}
/**
* @constructor
- * @extends {WebInspector.LiveLocation}
+ * @extends {WebInspector.LiveLocationWithPool}
* @param {!Array} rawLocations
* @param {!WebInspector.DebuggerWorkspaceBinding} binding
* @param {function(!WebInspector.LiveLocation)} updateDelegate
+ * @param {!WebInspector.LiveLocationPool} locationPool
*/
-WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation = function(rawLocations, binding, updateDelegate)
+WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation = function(rawLocations, binding, updateDelegate, locationPool)
{
- WebInspector.LiveLocation.call(this, updateDelegate);
+ WebInspector.LiveLocationWithPool.call(this, updateDelegate, locationPool);
this._updateScheduled = true;
- /** @type {!Array} */
- this._locations = [];
+ /** @type {!Set} */
+ this._locations = new Set();
for (var location of rawLocations)
- this._locations.push(binding.createLiveLocation(location, this._scheduleUpdate.bind(this)));
+ this._locations.add(binding.createCallFrameLiveLocation(location, this._scheduleUpdate.bind(this), locationPool));
this._updateLocation();
}
@@ -604,25 +609,26 @@ WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation.prototype = {
*/
uiLocation: function()
{
- return this._currentLocation().uiLocation();
+ return this._current.uiLocation();
},
/**
* @override
+ * @return {boolean}
*/
- dispose: function()
+ isBlackboxed: function()
{
- for (var location of this._locations)
- location.dispose();
+ return this._current.isBlackboxed();
},
/**
* @override
- * @return {boolean}
*/
- isBlackboxed: function()
+ dispose: function()
{
- return this._currentLocation().isBlackboxed();
+ WebInspector.LiveLocationWithPool.prototype.dispose.call(this);
+ for (var location of this._locations)
+ location.dispose();
},
_scheduleUpdate: function()
@@ -633,24 +639,20 @@ WebInspector.DebuggerWorkspaceBinding.StackTraceTopFrameLocation.prototype = {
}
},
- /**
- * @return {!WebInspector.DebuggerWorkspaceBinding.Location}
- */
- _currentLocation: function()
- {
- return this._locations[this._current < this._locations.length ? this._current : 0];
- },
-
_updateLocation: function()
{
this._updateScheduled = false;
- this._current = 0;
- while (this._current < this._locations.length && this._locations[this._current].isBlackboxed())
- ++this._current;
+ this._current = this._locations.values().next().value;
+ for (var current of this._locations) {
+ if (!current.isBlackboxed()) {
+ this._current = current;
+ break;
+ }
+ }
this.update();
},
- __proto__: WebInspector.LiveLocation.prototype
+ __proto__: WebInspector.LiveLocationWithPool.prototype
}
/**
diff --git a/front_end/bindings/LiveLocation.js b/front_end/bindings/LiveLocation.js
index 50bd67c120..12625e1b31 100644
--- a/front_end/bindings/LiveLocation.js
+++ b/front_end/bindings/LiveLocation.js
@@ -2,22 +2,49 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+/** @interface */
+WebInspector.LiveLocation = function() {}
+
+WebInspector.LiveLocation.prototype = {
+ update: function() {},
+
+ /**
+ * @return {?WebInspector.UILocation}
+ */
+ uiLocation: function() {},
+
+ dispose: function() {},
+
+ /**
+ * @return {boolean}
+ */
+ isBlackboxed: function() {}
+}
+
/**
* @constructor
+ * @implements {WebInspector.LiveLocation}
* @param {function(!WebInspector.LiveLocation)} updateDelegate
+ * @param {!WebInspector.LiveLocationPool} locationPool
*/
-WebInspector.LiveLocation = function(updateDelegate)
+WebInspector.LiveLocationWithPool = function(updateDelegate, locationPool)
{
this._updateDelegate = updateDelegate;
+ this._locationPool = locationPool;
+ this._locationPool._add(this);
}
-WebInspector.LiveLocation.prototype = {
+WebInspector.LiveLocationWithPool.prototype = {
+ /**
+ * @override
+ */
update: function()
{
this._updateDelegate(this);
},
/**
+ * @override
* @return {?WebInspector.UILocation}
*/
uiLocation: function()
@@ -25,12 +52,17 @@ WebInspector.LiveLocation.prototype = {
throw "Not implemented";
},
+ /**
+ * @override
+ */
dispose: function()
{
- // Overridden by subclasses.
+ this._locationPool._delete(this);
+ this._updateDelegate = null;
},
/**
+ * @override
* @return {boolean}
*/
isBlackboxed: function()
@@ -38,3 +70,35 @@ WebInspector.LiveLocation.prototype = {
throw "Not implemented";
}
}
+
+/**
+ * @constructor
+ */
+WebInspector.LiveLocationPool = function()
+{
+ this._locations = new Set();
+}
+
+WebInspector.LiveLocationPool.prototype = {
+ /**
+ * @param {!WebInspector.LiveLocation} location
+ */
+ _add: function(location)
+ {
+ this._locations.add(location);
+ },
+
+ /**
+ * @param {!WebInspector.LiveLocation} location
+ */
+ _delete: function(location)
+ {
+ this._locations.delete(location);
+ },
+
+ disposeAll: function()
+ {
+ for (var location of this._locations)
+ location.dispose();
+ }
+}
diff --git a/front_end/bindings/PresentationConsoleMessageHelper.js b/front_end/bindings/PresentationConsoleMessageHelper.js
index 7d54c7041d..77f57d9566 100644
--- a/front_end/bindings/PresentationConsoleMessageHelper.js
+++ b/front_end/bindings/PresentationConsoleMessageHelper.js
@@ -48,6 +48,8 @@ WebInspector.PresentationConsoleMessageHelper = function(workspace)
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+
+ this._locationPool = new WebInspector.LiveLocationPool();
}
WebInspector.PresentationConsoleMessageHelper.prototype = {
@@ -101,7 +103,7 @@ WebInspector.PresentationConsoleMessageHelper.prototype = {
*/
_addConsoleMessageToScript: function(message, rawLocation)
{
- this._presentationConsoleMessages.push(new WebInspector.PresentationConsoleMessage(message, rawLocation));
+ this._presentationConsoleMessages.push(new WebInspector.PresentationConsoleMessage(message, rawLocation, this._locationPool));
},
/**
@@ -151,6 +153,7 @@ WebInspector.PresentationConsoleMessageHelper.prototype = {
for (var i = 0; i < this._presentationConsoleMessages.length; ++i)
this._presentationConsoleMessages[i].dispose();
this._presentationConsoleMessages = [];
+ this._locationPool.disposeAll();
},
_debuggerReset: function()
@@ -163,12 +166,13 @@ WebInspector.PresentationConsoleMessageHelper.prototype = {
* @constructor
* @param {!WebInspector.ConsoleMessage} message
* @param {!WebInspector.DebuggerModel.Location} rawLocation
+ * @param {!WebInspector.LiveLocationPool} locationPool
*/
-WebInspector.PresentationConsoleMessage = function(message, rawLocation)
+WebInspector.PresentationConsoleMessage = function(message, rawLocation, locationPool)
{
this._text = message.messageText;
this._level = message.level === WebInspector.ConsoleMessage.MessageLevel.Error ? WebInspector.UISourceCode.Message.Level.Error : WebInspector.UISourceCode.Message.Level.Warning;
- this._liveLocation = WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this._updateLocation.bind(this));
+ WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this._updateLocation.bind(this), locationPool);
}
WebInspector.PresentationConsoleMessage.prototype = {
@@ -187,7 +191,6 @@ WebInspector.PresentationConsoleMessage.prototype = {
dispose: function()
{
- this._liveLocation.dispose();
if (this._uiMessage)
this._uiMessage.remove();
}
diff --git a/front_end/bindings/SASSSourceMapping.js b/front_end/bindings/SASSSourceMapping.js
index 6041cebdea..4bb7c5f137 100644
--- a/front_end/bindings/SASSSourceMapping.js
+++ b/front_end/bindings/SASSSourceMapping.js
@@ -42,6 +42,7 @@ WebInspector.SASSSourceMapping = function(cssModel, networkMapping, networkProje
this._networkMapping = networkMapping;
this._cssModel.addEventListener(WebInspector.CSSModel.Events.SourceMapAttached, this._sourceMapAttached, this);
this._cssModel.addEventListener(WebInspector.CSSModel.Events.SourceMapDetached, this._sourceMapDetached, this);
+ this._cssModel.addEventListener(WebInspector.CSSModel.Events.SourceMapChanged, this._sourceMapChanged, this);
}
WebInspector.SASSSourceMapping.prototype = {
@@ -70,6 +71,32 @@ WebInspector.SASSSourceMapping.prototype = {
WebInspector.cssWorkspaceBinding.updateLocations(header);
},
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _sourceMapChanged: function(event)
+ {
+ var sourceMap = /** @type {!WebInspector.SourceMap} */(event.data.sourceMap);
+ var newSources = /** @type {!Map} */(event.data.newSources);
+ var headers = this._cssModel.headersForSourceMap(sourceMap);
+ var handledUISourceCodes = new Set();
+ for (var header of headers) {
+ WebInspector.cssWorkspaceBinding.updateLocations(header);
+ for (var sourceURL of newSources.keys()) {
+ var uiSourceCode = this._networkMapping.uiSourceCodeForStyleURL(sourceURL, header);
+ if (!uiSourceCode) {
+ console.error("Failed to update source for " + sourceURL);
+ continue;
+ }
+ if (handledUISourceCodes.has(uiSourceCode))
+ continue;
+ handledUISourceCodes.add(uiSourceCode);
+ var sassText = /** @type {string} */(newSources.get(sourceURL));
+ uiSourceCode.addRevision(sassText);
+ }
+ }
+ },
+
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
diff --git a/front_end/common/ResourceType.js b/front_end/common/ResourceType.js
index 4cdb4dd318..6e343109eb 100644
--- a/front_end/common/ResourceType.js
+++ b/front_end/common/ResourceType.js
@@ -190,7 +190,7 @@ WebInspector.resourceTypes = {
Other: new WebInspector.ResourceType("other", "Other", WebInspector.resourceCategories.Other, false),
SourceMapScript: new WebInspector.ResourceType("sm-script", "Script", WebInspector.resourceCategories.Script, false),
SourceMapStyleSheet: new WebInspector.ResourceType("sm-stylesheet", "Stylesheet", WebInspector.resourceCategories.Stylesheet, false),
- Manifest: new WebInspector.ResourceType("manifest", "Manifest", WebInspector.resourceCategories.Manifest, false),
+ Manifest: new WebInspector.ResourceType("manifest", "Manifest", WebInspector.resourceCategories.Manifest, true),
}
/**
diff --git a/front_end/common/Text.js b/front_end/common/Text.js
index 4e02e37d91..3e62f17a72 100644
--- a/front_end/common/Text.js
+++ b/front_end/common/Text.js
@@ -95,3 +95,52 @@ WebInspector.Text.prototype = {
return this._value.substr(sourceRange.offset, sourceRange.length);
},
}
+
+/**
+ * @constructor
+ * @param {!Array} lineEndings
+ */
+WebInspector.TextCursor = function(lineEndings)
+{
+ this._lineEndings = lineEndings;
+ this._offset = 0;
+ this._lineNumber = 0;
+ this._columnNumber = 0;
+}
+
+WebInspector.TextCursor.prototype = {
+ /**
+ * @param {number} offset
+ */
+ advance: function(offset)
+ {
+ this._offset = offset;
+ while (this._lineNumber < this._lineEndings.length && this._lineEndings[this._lineNumber] < this._offset)
+ ++this._lineNumber;
+ this._columnNumber = this._lineNumber ? this._offset - this._lineEndings[this._lineNumber - 1] - 1 : this._offset;
+ },
+
+ /**
+ * @return {number}
+ */
+ offset: function()
+ {
+ return this._offset;
+ },
+
+ /**
+ * @return {number}
+ */
+ lineNumber: function()
+ {
+ return this._lineNumber;
+ },
+
+ /**
+ * @return {number}
+ */
+ columnNumber: function()
+ {
+ return this._columnNumber;
+ }
+}
diff --git a/front_end/common/TextRange.js b/front_end/common/TextRange.js
index 661674001f..e478d29bc3 100644
--- a/front_end/common/TextRange.js
+++ b/front_end/common/TextRange.js
@@ -196,15 +196,6 @@ WebInspector.TextRange.prototype = {
this.startColumn === other.startColumn && this.endColumn === other.endColumn;
},
- /**
- * @param {number} lineOffset
- * @return {!WebInspector.TextRange}
- */
- shift: function(lineOffset)
- {
- return new WebInspector.TextRange(this.startLine + lineOffset, this.startColumn, this.endLine + lineOffset, this.endColumn);
- },
-
/**
* @param {number} line
* @param {number} column
@@ -355,3 +346,12 @@ WebInspector.SourceEdit.prototype = {
},
}
+/**
+ * @param {!WebInspector.SourceEdit} edit1
+ * @param {!WebInspector.SourceEdit} edit2
+ * @return {number}
+ */
+WebInspector.SourceEdit.comparator = function(edit1, edit2)
+{
+ return WebInspector.TextRange.comparator(edit1.oldRange, edit2.oldRange);
+}
diff --git a/front_end/components/Linkifier.js b/front_end/components/Linkifier.js
index 6e70d88d6d..fe34672a41 100644
--- a/front_end/components/Linkifier.js
+++ b/front_end/components/Linkifier.js
@@ -52,8 +52,10 @@ WebInspector.LinkifierFormatter.prototype = {
WebInspector.Linkifier = function(formatter)
{
this._formatter = formatter || new WebInspector.Linkifier.DefaultFormatter(WebInspector.Linkifier.MaxLengthForDisplayedURLs);
- /** @type {!Map.>}*/
- this._liveLocationsByTarget = new Map();
+ /** @type {!Map>} */
+ this._anchorsByTarget = new Map();
+ /** @type {!Map} */
+ this._locationPoolByTarget = new Map();
WebInspector.targetManager.observeTargets(this);
}
@@ -115,6 +117,7 @@ WebInspector.Linkifier.linkifyUsingRevealer = function(revealable, text, fallbac
WebInspector.Linkifier._uiLocationSymbol = Symbol("uiLocation");
WebInspector.Linkifier._fallbackAnchorSymbol = Symbol("fallbackAnchor");
+WebInspector.Linkifier._liveLocationSymbol = Symbol("liveLocation");
WebInspector.Linkifier.prototype = {
/**
@@ -123,7 +126,8 @@ WebInspector.Linkifier.prototype = {
*/
targetAdded: function(target)
{
- this._liveLocationsByTarget.set(target, new Map());
+ this._anchorsByTarget.set(target, []);
+ this._locationPoolByTarget.set(target, new WebInspector.LiveLocationPool());
},
/**
@@ -132,12 +136,11 @@ WebInspector.Linkifier.prototype = {
*/
targetRemoved: function(target)
{
- var liveLocations = this._liveLocationsByTarget.remove(target);
- var anchors = liveLocations.keysArray();
- for (var i = 0; i < anchors.length; ++i) {
- var anchor = anchors[i];
- var location = liveLocations.get(anchor);
- delete anchor[WebInspector.Linkifier._uiLocationSymbol];
+ var locationPool = /** @type {!WebInspector.LiveLocationPool} */(this._locationPoolByTarget.remove(target));
+ locationPool.disposeAll();
+ var anchors = this._anchorsByTarget.remove(target);
+ for (var anchor of anchors) {
+ delete anchor[WebInspector.Linkifier._liveLocationSymbol];
var fallbackAnchor = anchor[WebInspector.Linkifier._fallbackAnchorSymbol];
if (fallbackAnchor) {
anchor.href = fallbackAnchor.href;
@@ -147,7 +150,6 @@ WebInspector.Linkifier.prototype = {
anchor.textContent = fallbackAnchor.textContent;
delete anchor[WebInspector.Linkifier._fallbackAnchorSymbol];
}
- location.dispose();
}
},
@@ -175,8 +177,10 @@ WebInspector.Linkifier.prototype = {
return fallbackAnchor;
var anchor = this._createAnchor(classes);
- var liveLocation = WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor));
- this._liveLocationsByTarget.get(rawLocation.target()).set(anchor, liveLocation);
+ var liveLocation = WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor), /** @type {!WebInspector.LiveLocationPool} */(this._locationPoolByTarget.get(rawLocation.target())));
+ var anchors = /** @type {!Array} */(this._anchorsByTarget.get(rawLocation.target()));
+ anchors.push(anchor);
+ anchor[WebInspector.Linkifier._liveLocationSymbol] = liveLocation;
anchor[WebInspector.Linkifier._fallbackAnchorSymbol] = fallbackAnchor;
return anchor;
},
@@ -224,8 +228,10 @@ WebInspector.Linkifier.prototype = {
return fallbackAnchor;
var anchor = this._createAnchor(classes);
- var liveLocation = WebInspector.debuggerWorkspaceBinding.createStackTraceTopFrameLiveLocation(rawLocations, this._updateAnchor.bind(this, anchor));
- this._liveLocationsByTarget.get(target).set(anchor, liveLocation);
+ var liveLocation = WebInspector.debuggerWorkspaceBinding.createStackTraceTopFrameLiveLocation(rawLocations, this._updateAnchor.bind(this, anchor), /** @type {!WebInspector.LiveLocationPool} */(this._locationPoolByTarget.get(target)));
+ var anchors = /** @type {!Array} */(this._anchorsByTarget.get(target));
+ anchors.push(anchor);
+ anchor[WebInspector.Linkifier._liveLocationSymbol] = liveLocation;
anchor[WebInspector.Linkifier._fallbackAnchorSymbol] = fallbackAnchor;
return anchor;
},
@@ -238,8 +244,10 @@ WebInspector.Linkifier.prototype = {
linkifyCSSLocation: function(rawLocation, classes)
{
var anchor = this._createAnchor(classes);
- var liveLocation = WebInspector.cssWorkspaceBinding.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor));
- this._liveLocationsByTarget.get(rawLocation.target()).set(anchor, liveLocation);
+ var liveLocation = WebInspector.cssWorkspaceBinding.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor), /** @type {!WebInspector.LiveLocationPool} */(this._locationPoolByTarget.get(rawLocation.target())));
+ var anchors = /** @type {!Array} */(this._anchorsByTarget.get(rawLocation.target()));
+ anchors.push(anchor);
+ anchor[WebInspector.Linkifier._liveLocationSymbol] = liveLocation;
return anchor;
},
@@ -251,12 +259,10 @@ WebInspector.Linkifier.prototype = {
{
delete anchor[WebInspector.Linkifier._uiLocationSymbol];
delete anchor[WebInspector.Linkifier._fallbackAnchorSymbol];
- var liveLocations = this._liveLocationsByTarget.get(target);
- if (!liveLocations)
- return;
- var location = liveLocations.remove(anchor);
- if (location)
- location.dispose();
+ var liveLocation = anchor[WebInspector.Linkifier._liveLocationSymbol];
+ if (liveLocation)
+ liveLocation.dispose();
+ delete anchor[WebInspector.Linkifier._liveLocationSymbol];
},
/**
@@ -289,9 +295,7 @@ WebInspector.Linkifier.prototype = {
reset: function()
{
- var targets = this._liveLocationsByTarget.keysArray();
- for (var i = 0; i < targets.length; ++i) {
- var target = targets[i];
+ for (var target of this._anchorsByTarget.keysArray()) {
this.targetRemoved(target);
this.targetAdded(target);
}
@@ -299,9 +303,9 @@ WebInspector.Linkifier.prototype = {
dispose: function()
{
- this.reset();
+ for (var target of this._anchorsByTarget.keysArray())
+ this.targetRemoved(target);
WebInspector.targetManager.unobserveTargets(this);
- this._liveLocationsByTarget.clear();
},
/**
diff --git a/front_end/components/NetworkConditionsSelector.js b/front_end/components/NetworkConditionsSelector.js
index 4c2db2df48..bf851ab09e 100644
--- a/front_end/components/NetworkConditionsSelector.js
+++ b/front_end/components/NetworkConditionsSelector.js
@@ -39,7 +39,7 @@ WebInspector.NetworkConditionsSelector._throughputText = function(throughput)
/** @type {!Array.} */
WebInspector.NetworkConditionsSelector._presets = [
- {title: "Offline", download: 0 * 1024 / 8, upload: 0 * 1024 / 8, latency: 0},
+ WebInspector.NetworkManager.OfflineConditions,
{title: "GPRS", download: 50 * 1024 / 8, upload: 20 * 1024 / 8, latency: 500},
{title: "Regular 2G", download: 250 * 1024 / 8, upload: 50 * 1024 / 8, latency: 300},
{title: "Good 2G", download: 450 * 1024 / 8, upload: 150 * 1024 / 8, latency: 150},
@@ -434,3 +434,32 @@ WebInspector.NetworkConditionsSettingsTab.prototype = {
__proto__: WebInspector.VBox.prototype
}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.NetworkConditionsActionDelegate = function()
+{
+}
+
+WebInspector.NetworkConditionsActionDelegate.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.Context} context
+ * @param {string} actionId
+ * @return {boolean}
+ */
+ handleAction: function(context, actionId)
+ {
+ if (actionId === "components.network-online") {
+ WebInspector.multitargetNetworkManager.setNetworkConditions(WebInspector.NetworkManager.NoThrottlingConditions);
+ return true;
+ }
+ if (actionId === "components.network-offline") {
+ WebInspector.multitargetNetworkManager.setNetworkConditions(WebInspector.NetworkManager.OfflineConditions);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/front_end/components/RequestAppBannerActionDelegate.js b/front_end/components/RequestAppBannerActionDelegate.js
new file mode 100644
index 0000000000..21f09f6ecd
--- /dev/null
+++ b/front_end/components/RequestAppBannerActionDelegate.js
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.RequestAppBannerActionDelegate = function()
+{
+}
+
+WebInspector.RequestAppBannerActionDelegate.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.Context} context
+ * @param {string} actionId
+ * @return {boolean}
+ */
+ handleAction: function(context, actionId)
+ {
+ var target = WebInspector.targetManager.mainTarget();
+ if (target && target.isPage()) {
+ target.pageAgent().requestAppBanner();
+ WebInspector.console.show();
+ }
+ return true;
+ }
+}
diff --git a/front_end/components/module.json b/front_end/components/module.json
index b1fb6ddf9c..bb36a96929 100644
--- a/front_end/components/module.json
+++ b/front_end/components/module.json
@@ -21,6 +21,22 @@
"settingType": "array",
"defaultValue": []
},
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "components.network-offline",
+ "category": "Network",
+ "title": "Go offline",
+ "className": "WebInspector.NetworkConditionsActionDelegate",
+ "tags": "device"
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "components.network-online",
+ "category": "Network",
+ "title": "Go online",
+ "className": "WebInspector.NetworkConditionsActionDelegate",
+ "tags": "device"
+ },
{
"type": "settings-view",
"name": "network-conditions",
@@ -30,6 +46,13 @@
"settings": [
"customNetworkConditions"
]
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "category": "Mobile",
+ "actionId": "components.request-app-banner",
+ "className": "WebInspector.RequestAppBannerActionDelegate",
+ "title": "Trigger add to homescreen"
}
],
"dependencies": [
@@ -52,6 +75,7 @@
"ObjectPopoverHelper.js",
"ObjectPropertiesSection.js",
"RemoteObjectPreviewFormatter.js",
+ "RequestAppBannerActionDelegate.js",
"ShortcutsScreen.js",
"EventListenersUtils.js",
"EventListenersView.js",
diff --git a/front_end/console/ConsolePanel.js b/front_end/console/ConsolePanel.js
index fae8e4491c..47a5027db5 100644
--- a/front_end/console/ConsolePanel.js
+++ b/front_end/console/ConsolePanel.js
@@ -33,18 +33,7 @@
WebInspector.ConsolePanel = function()
{
WebInspector.Panel.call(this, "console");
- this._view = WebInspector.ConsolePanel._view();
-}
-
-/**
- * @return {!WebInspector.ConsoleView}
- */
-WebInspector.ConsolePanel._view = function()
-{
- if (!WebInspector.ConsolePanel._consoleView)
- WebInspector.ConsolePanel._consoleView = new WebInspector.ConsoleView();
-
- return WebInspector.ConsolePanel._consoleView;
+ this._view = WebInspector.ConsoleView.instance();
}
WebInspector.ConsolePanel.prototype = {
@@ -86,7 +75,7 @@ WebInspector.ConsolePanel.prototype = {
*/
searchableView: function()
{
- return WebInspector.ConsolePanel._view().searchableView();
+ return WebInspector.ConsoleView.instance().searchableView();
},
__proto__: WebInspector.Panel.prototype
@@ -103,7 +92,7 @@ WebInspector.ConsolePanel.WrapperView = function()
WebInspector.ConsolePanel.WrapperView._instance = this;
- this._view = WebInspector.ConsolePanel._view();
+ this._view = WebInspector.ConsoleView.instance();
}
WebInspector.ConsolePanel.WrapperView.prototype = {
@@ -158,7 +147,7 @@ WebInspector.ConsolePanel.ConsoleRevealer.prototype = {
*/
reveal: function(object)
{
- var consoleView = WebInspector.ConsolePanel._view();
+ var consoleView = WebInspector.ConsoleView.instance();
if (consoleView.isShowing()) {
consoleView.focus();
return Promise.resolve();
diff --git a/front_end/console/ConsoleView.js b/front_end/console/ConsoleView.js
index da86d912bc..851347821a 100644
--- a/front_end/console/ConsoleView.js
+++ b/front_end/console/ConsoleView.js
@@ -164,6 +164,12 @@ WebInspector.ConsoleView.prototype = {
return this._searchableView;
},
+ _clearHistory: function()
+ {
+ this._consoleHistorySetting.set([]);
+ this._prompt.setHistoryData([]);
+ },
+
/**
* @param {!WebInspector.Event} event
*/
@@ -578,6 +584,7 @@ WebInspector.ConsoleView.prototype = {
contextMenu.appendSeparator();
contextMenu.appendAction("console.clear");
+ contextMenu.appendAction("console.clear.history");
contextMenu.appendItem(WebInspector.UIString("Save as..."), this._saveConsole.bind(this));
var request = consoleMessage ? consoleMessage.request : null;
@@ -1274,6 +1281,16 @@ WebInspector.ConsoleGroup.prototype = {
},
}
+/**
+ * @return {!WebInspector.ConsoleView}
+ */
+WebInspector.ConsoleView.instance = function()
+{
+ if (!WebInspector.ConsoleView._instance)
+ WebInspector.ConsoleView._instance = new WebInspector.ConsoleView();
+ return WebInspector.ConsoleView._instance;
+}
+
/**
* @constructor
* @implements {WebInspector.ActionDelegate}
@@ -1298,6 +1315,9 @@ WebInspector.ConsoleView.ActionDelegate.prototype = {
case "console.clear":
WebInspector.ConsoleModel.clearConsole();
return true;
+ case "console.clear.history":
+ WebInspector.ConsoleView.instance()._clearHistory();
+ return true;
}
return false;
}
diff --git a/front_end/console/module.json b/front_end/console/module.json
index 181d9e0804..2cdde5847b 100644
--- a/front_end/console/module.json
+++ b/front_end/console/module.json
@@ -48,6 +48,13 @@
}
]
},
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "category": "Console",
+ "actionId": "console.clear.history",
+ "title": "Clear console history",
+ "className": "WebInspector.ConsoleView.ActionDelegate"
+ },
{
"type": "setting",
"category": "Console",
diff --git a/front_end/devtools.js b/front_end/devtools.js
index 84325f7a37..8733c4a949 100644
--- a/front_end/devtools.js
+++ b/front_end/devtools.js
@@ -1001,6 +1001,11 @@ function installBackwardsCompatibility()
var styleElement = window.document.createElement("style");
styleElement.type = "text/css";
styleElement.textContent = "html /deep/ * { min-width: 0; min-height: 0; }";
+
+ // Support for quirky border-image behavior ( WebInspector.actionRegistry.action("elements.edit-as-html").execute());
+ },
+
__proto__: TreeElement.prototype
}
diff --git a/front_end/elements/StylesSidebarPane.js b/front_end/elements/StylesSidebarPane.js
index 299c2fa4cd..fa507a75a5 100644
--- a/front_end/elements/StylesSidebarPane.js
+++ b/front_end/elements/StylesSidebarPane.js
@@ -218,10 +218,11 @@ WebInspector.StylesSidebarPane.prototype = {
if (!node)
return;
+ var fullRefresh = Runtime.experiments.isEnabled("liveSASS");
for (var section of this.allSections()) {
if (section.isBlank)
continue;
- section.update(section === editedSection);
+ section.update(fullRefresh || section === editedSection);
}
if (this._filterRegex)
@@ -2391,7 +2392,10 @@ WebInspector.StylePropertyTreeElement.prototype = {
if (!isEditingName && this._parentPane._mouseDownTreeElementIsName)
moveDirection = "backward";
}
- this.editingCommitted((context.isEditingName ? this.name : this.value) || event.target.textContent, context, moveDirection);
+ var text = event.target.textContent;
+ if (!context.isEditingName)
+ text = this.value || text;
+ this.editingCommitted(text, context, moveDirection);
}
this._originalPropertyText = this.property.propertyText;
diff --git a/front_end/emulation/DeviceModeView.js b/front_end/emulation/DeviceModeView.js
index d4c2a4969a..4980cc9c7a 100644
--- a/front_end/emulation/DeviceModeView.js
+++ b/front_end/emulation/DeviceModeView.js
@@ -16,10 +16,9 @@ WebInspector.DeviceModeView = function()
this._model = new WebInspector.DeviceModeModel(this._updateUI.bind(this));
this._mediaInspector = new WebInspector.MediaQueryInspector(() => this._model.appliedDeviceSize().width, this._model.setWidth.bind(this._model));
- // TODO(dgozman): remove CountUpdated event.
- this._showMediaInspectorSetting = WebInspector.settings.createSetting("showMediaQueryInspector", false);
+ this._showMediaInspectorSetting = WebInspector.settings.moduleSetting("showMediaQueryInspector");
this._showMediaInspectorSetting.addChangeListener(this._updateUI, this);
- this._showRulersSetting = WebInspector.settings.createSetting("emulation.showRulers", false);
+ this._showRulersSetting = WebInspector.settings.moduleSetting("emulation.showRulers");
this._showRulersSetting.addChangeListener(this._updateUI, this);
this._topRuler = new WebInspector.DeviceModeView.Ruler(true, this._model.setWidthAndScaleToFit.bind(this._model));
@@ -352,6 +351,52 @@ WebInspector.DeviceModeView.prototype = {
this._model.emulate(WebInspector.DeviceModeModel.Type.None, null, null);
},
+ captureScreenshot: function()
+ {
+ var mainTarget = WebInspector.targetManager.mainTarget();
+ if (!mainTarget)
+ return;
+ mainTarget.pageAgent().captureScreenshot(screenshotCaptured.bind(this));
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {string} content
+ * @this {WebInspector.DeviceModeView}
+ */
+ function screenshotCaptured(error, content)
+ {
+ if (error)
+ return;
+
+ // Create a canvas to splice the images together.
+ var canvas = createElement("canvas");
+ var ctx = canvas.getContext("2d");
+ var screenRect = this._model.screenRect();
+ canvas.width = screenRect.width;
+ canvas.height = screenRect.height;
+ // Add any available screen images.
+ if (this._model.screenImage()) {
+ var screenImage = new Image();
+ screenImage.crossOrigin = "Anonymous";
+ screenImage.srcset = this._model.screenImage();
+ ctx.drawImage(screenImage, 0, 0, screenRect.width, screenRect.height);
+ }
+ var pageImage = new Image();
+ pageImage.src = "data:image/png;base64," + content;
+ var visiblePageRect = this._model.visiblePageRect();
+ ctx.drawImage(pageImage, visiblePageRect.left, visiblePageRect.top, visiblePageRect.width, visiblePageRect.height);
+ var mainFrame = mainTarget.resourceTreeModel.mainFrame;
+ var fileName = mainFrame ? mainFrame.url.trimURL().removeURLFragment() : "";
+ if (this._model.type() === WebInspector.DeviceModeModel.Type.Device)
+ fileName += WebInspector.UIString("(%s)", this._model.device().title);
+ // Trigger download.
+ var link = createElement("a");
+ link.download = fileName + ".png";
+ link.href = canvas.toDataURL("image/png");
+ link.click();
+ }
+ },
+
__proto__: WebInspector.VBox.prototype
}
diff --git a/front_end/emulation/DeviceModeWrapper.js b/front_end/emulation/DeviceModeWrapper.js
index 51515ccc47..f1cfe7f1c7 100644
--- a/front_end/emulation/DeviceModeWrapper.js
+++ b/front_end/emulation/DeviceModeWrapper.js
@@ -29,6 +29,17 @@ WebInspector.DeviceModeWrapper.prototype = {
this._showDeviceModeSetting.set(!this._showDeviceModeSetting.get());
},
+ /**
+ * @return {boolean}
+ */
+ _captureScreenshot: function()
+ {
+ if (!this._deviceModeView)
+ return false;
+ this._deviceModeView.captureScreenshot();
+ return true;
+ },
+
/**
* @param {boolean} force
*/
@@ -80,12 +91,8 @@ WebInspector.DeviceModeWrapper.ActionDelegate.prototype = {
WebInspector.DeviceModeView._wrapperInstance._toggleDeviceMode();
return true;
}
- if (actionId === "emulation.request-app-banner") {
- var target = WebInspector.targetManager.mainTarget();
- if (target && target.isPage())
- target.pageAgent().requestAppBanner();
- return true;
- }
+ if (actionId === "emulation.capture-screenshot")
+ return WebInspector.DeviceModeView._wrapperInstance._captureScreenshot();
}
return false;
}
diff --git a/front_end/emulation/module.json b/front_end/emulation/module.json
index 988c5234c0..0375d4f9a4 100644
--- a/front_end/emulation/module.json
+++ b/front_end/emulation/module.json
@@ -25,6 +25,18 @@
}
]
},
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "emulation.capture-screenshot",
+ "className": "WebInspector.DeviceModeWrapper.ActionDelegate",
+ "title": "Capture screenshot"
+ },
+ {
+ "type": "context-menu-item",
+ "location": "deviceModeMenu/tools",
+ "order": 12,
+ "actionId": "emulation.capture-screenshot"
+ },
{
"type": "@WebInspector.ToolbarItem.Provider",
"actionId": "emulation.toggle-device-mode",
@@ -32,6 +44,30 @@
"location": "main-toolbar-left",
"order": 1
},
+ {
+ "type": "setting",
+ "category": "Mobile",
+ "settingName": "showMediaQueryInspector",
+ "settingType": "boolean",
+ "defaultValue": false,
+ "options": [
+ {"value": true, "title": "Show media queries"},
+ {"value": false, "title": "Hide media queries"}
+ ],
+ "tags": "device"
+ },
+ {
+ "type": "setting",
+ "category": "Mobile",
+ "settingName": "emulation.showRulers",
+ "settingType": "boolean",
+ "defaultValue": false,
+ "options": [
+ {"value": true, "title": "Show rulers"},
+ {"value": false, "title": "Hide rulers"}
+ ],
+ "tags": "device"
+ },
{
"type": "settings-view",
"name": "devices",
@@ -64,18 +100,11 @@
"className": "WebInspector.SensorsView",
"tags": "geolocation, accelerometer, device orientation"
},
- {
- "type": "@WebInspector.ActionDelegate",
- "actionId": "emulation.request-app-banner",
- "className": "WebInspector.DeviceModeWrapper.ActionDelegate",
- "title": "Request app banner\u2026"
- },
{
"type": "context-menu-item",
"location": "deviceModeMenu/tools",
- "experiment": "appBanner",
"order": 10,
- "actionId": "emulation.request-app-banner"
+ "actionId": "components.request-app-banner"
}
],
"dependencies": [
diff --git a/front_end/formatter_worker/CSSFormatter.js b/front_end/formatter_worker/CSSFormatter.js
index 5743e0deb5..3476327b90 100644
--- a/front_end/formatter_worker/CSSFormatter.js
+++ b/front_end/formatter_worker/CSSFormatter.js
@@ -59,14 +59,11 @@ WebInspector.CSSFormatter.prototype = {
* @param {string} token
* @param {?string} type
* @param {number} startPosition
- * @param {number} endPosition
*/
- _tokenCallback: function(token, type, startPosition, endPosition)
+ _tokenCallback: function(token, type, startPosition)
{
startPosition += this._fromOffset;
- endPosition += this._fromOffset;
var startLine = this._lineEndings.lowerBound(startPosition);
- var endLine = this._lineEndings.lowerBound(endPosition);
if (startLine !== this._lastLine)
this._state.eatWhitespace = true;
if (/^property/.test(type) && !this._state.inPropertyValue)
@@ -94,7 +91,7 @@ WebInspector.CSSFormatter.prototype = {
this._state.afterClosingBrace = true;
this._state.inPropertyValue = false;
} else if (token === ":" && !this._state.inPropertyValue && this._state.seenProperty) {
- this._builder.addToken(token, startPosition, startLine, endLine);
+ this._builder.addToken(token, startPosition);
this._builder.addSoftSpace();
this._state.eatWhitespace = true;
this._state.inPropertyValue = true;
@@ -102,13 +99,13 @@ WebInspector.CSSFormatter.prototype = {
return;
} else if (token === "{") {
this._builder.addSoftSpace();
- this._builder.addToken(token, startPosition, startLine, endLine);
+ this._builder.addToken(token, startPosition);
this._builder.addNewLine();
this._builder.increaseNestingLevel();
return;
}
- this._builder.addToken(token, startPosition, startLine, endLine);
+ this._builder.addToken(token, startPosition);
if (type === "comment" && !this._state.inPropertyValue && !this._state.seenProperty)
this._builder.addNewLine();
diff --git a/front_end/formatter_worker/FormattedContentBuilder.js b/front_end/formatter_worker/FormattedContentBuilder.js
index 4a5428be4f..3d1d266e87 100644
--- a/front_end/formatter_worker/FormattedContentBuilder.js
+++ b/front_end/formatter_worker/FormattedContentBuilder.js
@@ -17,7 +17,6 @@ WebInspector.FormattedContentBuilder = function(indentString)
/** @type {!{original: !Array., formatted: !Array.}} */
this._mapping = { original: [0], formatted: [0] };
- this._lineNumber = 0;
this._nestingLevel = 0;
this._indentString = indentString;
/** @type {!Map} */
@@ -31,15 +30,10 @@ WebInspector.FormattedContentBuilder = function(indentString)
WebInspector.FormattedContentBuilder.prototype = {
/**
* @param {string} token
- * @param {number} startPosition
- * @param {number} startLine
- * @param {number} endLine
+ * @param {number} offset
*/
- addToken: function(token, startPosition, startLine, endLine)
+ addToken: function(token, offset)
{
- if (this._lineNumber < startLine)
- this._newLines = Math.max(this._newLines, startLine - this._lineNumber);
-
var last = this._formattedContent.peekLast();
if (last && /\w/.test(last[last.length - 1]) && /\w/.test(token))
this.addSoftSpace();
@@ -47,9 +41,8 @@ WebInspector.FormattedContentBuilder.prototype = {
this._appendFormatting();
// Insert token.
- this._addMappingIfNeeded(startPosition);
+ this._addMappingIfNeeded(offset);
this._addText(token);
- this._lineNumber = endLine;
},
addSoftSpace: function()
diff --git a/front_end/formatter_worker/FormatterWorker.js b/front_end/formatter_worker/FormatterWorker.js
index 4d22f1b252..37014ddcfc 100644
--- a/front_end/formatter_worker/FormatterWorker.js
+++ b/front_end/formatter_worker/FormatterWorker.js
@@ -72,11 +72,112 @@ self.onmessage = function(event) {
case "javaScriptOutline":
WebInspector.javaScriptOutline(params.content);
break;
+ case "javaScriptIdentifiers":
+ WebInspector.javaScriptIdentifiers(params.content);
+ break;
+ case "evaluatableJavaScriptSubstring":
+ WebInspector.evaluatableJavaScriptSubstring(params.content);
+ break;
default:
console.error("Unsupport method name: " + method);
}
};
+/**
+ * @param {string} content
+ */
+WebInspector.evaluatableJavaScriptSubstring = function(content)
+{
+ var tokenizer = acorn.tokenizer(content, {ecmaVersion: 6});
+ var result = "";
+ try {
+ var token = tokenizer.getToken();
+ while (token.type !== acorn.tokTypes.eof && WebInspector.AcornTokenizer.punctuator(token))
+ token = tokenizer.getToken();
+
+ var startIndex = token.start;
+ var endIndex = token.end;
+ var openBracketsCounter = 0;
+ while (token.type !== acorn.tokTypes.eof) {
+ var isIdentifier = WebInspector.AcornTokenizer.identifier(token);
+ var isThis = WebInspector.AcornTokenizer.keyword(token, "this");
+ var isString = token.type === acorn.tokTypes.string;
+ if (!isThis && !isIdentifier && !isString)
+ break;
+
+ endIndex = token.end;
+ token = tokenizer.getToken();
+ while (WebInspector.AcornTokenizer.punctuator(token, ".[]")) {
+ if (WebInspector.AcornTokenizer.punctuator(token, "["))
+ openBracketsCounter++;
+
+ if (WebInspector.AcornTokenizer.punctuator(token, "]")) {
+ endIndex = openBracketsCounter > 0 ? token.end : endIndex;
+ openBracketsCounter--;
+ }
+
+ token = tokenizer.getToken();
+ }
+ }
+ result = content.substring(startIndex, endIndex);
+ } catch (e) {
+ console.error(e);
+ }
+ postMessage(result);
+}
+
+/**
+ * @param {string} content
+ */
+WebInspector.javaScriptIdentifiers = function(content)
+{
+ var root = acorn.parse(content, {});
+ /** @type {!Array} */
+ var identifiers = [];
+ var functionDeclarationCounter = 0;
+ var walker = new WebInspector.ESTreeWalker(beforeVisit, afterVisit);
+
+ /**
+ * @param {!ESTree.Node} node
+ * @return {boolean}
+ */
+ function isFunction(node)
+ {
+ return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
+ }
+
+ /**
+ * @param {!ESTree.Node} node
+ */
+ function beforeVisit(node)
+ {
+ if (isFunction(node))
+ functionDeclarationCounter++;
+
+ if (functionDeclarationCounter > 1)
+ return;
+
+ if (isFunction(node) && node.params)
+ identifiers.pushAll(node.params);
+
+ if (node.type === "VariableDeclarator")
+ identifiers.push(/** @type {!ESTree.Node} */(node.id));
+ }
+
+ /**
+ * @param {!ESTree.Node} node
+ */
+ function afterVisit(node)
+ {
+ if (isFunction(node))
+ functionDeclarationCounter--;
+ }
+
+ walker.walk(root);
+ var reduced = identifiers.map(id => ({name: id.name, offset: id.start}));
+ postMessage(reduced);
+}
+
/**
* @param {string} mimeType
* @param {string} text
diff --git a/front_end/formatter_worker/HTMLFormatter.js b/front_end/formatter_worker/HTMLFormatter.js
index ab7f46a5c2..9514125d63 100644
--- a/front_end/formatter_worker/HTMLFormatter.js
+++ b/front_end/formatter_worker/HTMLFormatter.js
@@ -49,9 +49,7 @@ WebInspector.HTMLFormatter.prototype = {
tokenStart += fromOffset;
tokenEnd += fromOffset;
lastOffset = tokenEnd;
- var startLine = lineEndings.lowerBound(tokenStart);
- var endLine = lineEndings.lowerBound(tokenEnd);
- this._builder.addToken(tokenValue, tokenStart, startLine, endLine);
+ this._builder.addToken(tokenValue, tokenStart);
if (!type)
return;
diff --git a/front_end/formatter_worker/IdentityFormatter.js b/front_end/formatter_worker/IdentityFormatter.js
index bafb5f2b1b..e428b7066a 100644
--- a/front_end/formatter_worker/IdentityFormatter.js
+++ b/front_end/formatter_worker/IdentityFormatter.js
@@ -21,9 +21,7 @@ WebInspector.IdentityFormatter.prototype = {
format: function(text, lineEndings, fromOffset, toOffset)
{
var content = text.substring(fromOffset, toOffset);
- var startLine = lineEndings.lowerBound(fromOffset);
- var endLine = lineEndings.lowerBound(toOffset);
- this._builder.addToken(content, fromOffset, startLine, endLine);
+ this._builder.addToken(content, fromOffset);
}
}
diff --git a/front_end/formatter_worker/JavaScriptFormatter.js b/front_end/formatter_worker/JavaScriptFormatter.js
index 7a8c611aa5..6a61ddce29 100644
--- a/front_end/formatter_worker/JavaScriptFormatter.js
+++ b/front_end/formatter_worker/JavaScriptFormatter.js
@@ -46,7 +46,6 @@ WebInspector.JavaScriptFormatter.prototype = {
*/
format: function(text, lineEndings, fromOffset, toOffset)
{
- this._lineOffset = lineEndings.lowerBound(fromOffset);
this._fromOffset = fromOffset;
this._toOffset = toOffset;
this._content = text.substring(this._fromOffset, this._toOffset);
@@ -74,7 +73,7 @@ WebInspector.JavaScriptFormatter.prototype = {
else if (format[i] === "<")
this._builder.decreaseNestingLevel();
else if (format[i] === "t")
- this._builder.addToken(this._content.substring(token.start, token.end), this._fromOffset + token.start, this._lineOffset + this._tokenizer.tokenLineStart(), this._lineOffset + this._tokenizer.tokenLineEnd());
+ this._builder.addToken(this._content.substring(token.start, token.end), this._fromOffset + token.start);
}
},
@@ -132,7 +131,7 @@ WebInspector.JavaScriptFormatter.prototype = {
if (AT.lineComment(token))
return "tn";
if (AT.blockComment(token))
- return "t";
+ return "tn";
if (node.type === "ContinueStatement" || node.type === "BreakStatement") {
return node.label && AT.keyword(token) ? "ts" : "t";
} else if (node.type === "Identifier") {
diff --git a/front_end/inspector.json b/front_end/inspector.json
index 657336c6ce..f3a0a2b1dc 100644
--- a/front_end/inspector.json
+++ b/front_end/inspector.json
@@ -26,7 +26,6 @@
{ "name": "cm_modes", "type": "remote" },
{ "name": "settings" },
{ "name": "layers" },
- { "name": "promises" },
{ "name": "snippets" },
{ "name": "diff" },
{ "name": "sass" },
diff --git a/front_end/main/Main.js b/front_end/main/Main.js
index b67f01d7f5..8302a039aa 100644
--- a/front_end/main/Main.js
+++ b/front_end/main/Main.js
@@ -103,7 +103,6 @@ WebInspector.Main.prototype = {
{
Runtime.experiments.register("accessibilityInspection", "Accessibility Inspection");
Runtime.experiments.register("applyCustomStylesheet", "Allow custom UI themes");
- Runtime.experiments.register("appBanner", "App banner support", true);
Runtime.experiments.register("blackboxJSFramesOnTimeline", "Blackbox JavaScript frames on Timeline", true);
Runtime.experiments.register("colorContrastRatio", "Contrast ratio line in color picker", true);
Runtime.experiments.register("cpuThrottling", "CPU throttling", true);
@@ -112,11 +111,11 @@ WebInspector.Main.prototype = {
Runtime.experiments.register("layersPanel", "Layers panel");
Runtime.experiments.register("layoutEditor", "Layout editor", true);
Runtime.experiments.register("inspectTooltip", "Dark inspect element tooltip");
+ Runtime.experiments.register("liveSASS", "Live SASS", true);
Runtime.experiments.register("multipleTimelineViews", "Multiple main views on Timeline", true);
Runtime.experiments.register("networkRequestHeadersFilterInDetailsView", "Network request headers filter in details view", true);
Runtime.experiments.register("networkRequestsOnTimeline", "Network requests on Timeline", true);
Runtime.experiments.register("privateScriptInspection", "Private script inspection");
- Runtime.experiments.register("promiseTracker", "Promise inspector");
Runtime.experiments.register("reducedIndentation", "Reduced indentation in Elements DOM tree");
Runtime.experiments.register("requestBlocking", "Request blocking", true);
Runtime.experiments.register("resolveVariableNames", "Resolve variable names", true);
@@ -134,8 +133,6 @@ WebInspector.Main.prototype = {
if (InspectorFrontendHost.isUnderTest()) {
var testPath = JSON.parse(prefs["testPath"] || "\"\"");
// Enable experiments for testing.
- if (testPath.indexOf("debugger/promise") !== -1)
- Runtime.experiments.enableForTest("promiseTracker");
if (testPath.indexOf("layers/") !== -1)
Runtime.experiments.enableForTest("layersPanel");
if (testPath.indexOf("timeline/") !== -1 || testPath.indexOf("layers/") !== -1)
diff --git a/front_end/main/module.json b/front_end/main/module.json
index dfccf28766..0a441fdd47 100644
--- a/front_end/main/module.json
+++ b/front_end/main/module.json
@@ -59,10 +59,8 @@
},
{
"type": "@WebInspector.ActionDelegate",
- "category": "Navigation",
"actionId": "main.debug-reload",
"className": "WebInspector.Main.ReloadActionDelegate",
- "title": "Clear cache & hard reload page",
"bindings": [
{
"shortcut": "Alt+R"
diff --git a/front_end/network/NetworkLogView.js b/front_end/network/NetworkLogView.js
index fe06f36582..4b7c2d7978 100644
--- a/front_end/network/NetworkLogView.js
+++ b/front_end/network/NetworkLogView.js
@@ -252,7 +252,7 @@ WebInspector.NetworkLogView.prototype = {
_addFilters: function()
{
- this._textFilterUI = new WebInspector.TextFilterUI();
+ this._textFilterUI = new WebInspector.TextFilterUI(true);
this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged, this);
this._filterBar.addFilter(this._textFilterUI);
@@ -966,11 +966,16 @@ WebInspector.NetworkLogView.prototype = {
var node = this._nodesByRequestId.get(requestId);
if (!node)
continue;
- if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
- rootNode.removeChild(node);
- node[WebInspector.NetworkLogView._isFilteredOutSymbol] = !this._applyFilter(node);
- if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
- nodesToInsert.push(node);
+ var isFilteredOut = !this._applyFilter(node);
+ if (node[WebInspector.NetworkLogView._isFilteredOutSymbol] !== isFilteredOut) {
+ if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
+ rootNode.removeChild(node);
+
+ node[WebInspector.NetworkLogView._isFilteredOutSymbol] = isFilteredOut;
+
+ if (!node[WebInspector.NetworkLogView._isFilteredOutSymbol])
+ nodesToInsert.push(node);
+ }
var request = node.request();
this._timeCalculator.updateBoundaries(request);
this._durationCalculator.updateBoundaries(request);
@@ -1570,7 +1575,7 @@ WebInspector.NetworkLogView.prototype = {
*/
supportsRegexSearch: function()
{
- return false;
+ return true;
},
/**
@@ -1634,8 +1639,14 @@ WebInspector.NetworkLogView.prototype = {
*/
_parseFilterQuery: function(query)
{
- var parsedQuery = this._suggestionBuilder.parseQuery(query);
- this._filters = parsedQuery.text.map(this._createTextFilter);
+ var parsedQuery;
+ if (this._textFilterUI.isRegexChecked() && query !== "")
+ parsedQuery = {text: [query], filters: []};
+ else
+ parsedQuery = this._suggestionBuilder.parseQuery(query);
+
+ this._filters = parsedQuery.text.map(this._createTextFilter, this);
+
var n = parsedQuery.filters.length;
for (var i = 0; i < n; ++i) {
var filter = parsedQuery.filters[i];
@@ -1651,11 +1662,12 @@ WebInspector.NetworkLogView.prototype = {
_createTextFilter: function(text)
{
var negative = false;
- if (text[0] === "-" && text.length > 1) {
+ if (!this._textFilterUI.isRegexChecked() && text[0] === "-" && text.length > 1) {
negative = true;
text = text.substring(1);
}
- var regexp = new RegExp(text.escapeForRegExp(), "i");
+ var regexp = this._textFilterUI.regex();
+
var filter = WebInspector.NetworkLogView._requestNameOrPathFilter.bind(null, regexp);
if (negative)
filter = WebInspector.NetworkLogView._negativeFilter.bind(null, filter);
@@ -1935,12 +1947,14 @@ WebInspector.NetworkLogView._negativeFilter = function(filter, request)
}
/**
- * @param {!RegExp} regex
+ * @param {?RegExp} regex
* @param {!WebInspector.NetworkRequest} request
* @return {boolean}
*/
WebInspector.NetworkLogView._requestNameOrPathFilter = function(regex, request)
{
+ if (!regex)
+ return false;
return regex.test(request.name()) || regex.test(request.path());
}
diff --git a/front_end/platform/utilities.js b/front_end/platform/utilities.js
index a4a133262a..6025a3629d 100644
--- a/front_end/platform/utilities.js
+++ b/front_end/platform/utilities.js
@@ -1239,6 +1239,20 @@ Set.prototype.addAll = function(iterable)
this.add(e);
}
+/**
+ * @param {!Iterable|!Array} iterable
+ * @return {boolean}
+ * @template T
+ */
+Set.prototype.containsAll = function(iterable)
+{
+ for (var e of iterable) {
+ if (!this.has(e))
+ return false;
+ }
+ return true;
+}
+
/**
* @return {T}
* @template T
@@ -1312,6 +1326,19 @@ Multimap.prototype = {
return this._map.has(key);
},
+ /**
+ * @param {K} key
+ * @param {V} value
+ * @return {boolean}
+ */
+ hasValue: function(key, value)
+ {
+ var set = this._map.get(key);
+ if (!set)
+ return false;
+ return set.has(value);
+ },
+
/**
* @return {number}
*/
diff --git a/front_end/profiler/CPUProfileBottomUpDataGrid.js b/front_end/profiler/CPUProfileBottomUpDataGrid.js
index 8f3f02db8f..591d4acbb6 100644
--- a/front_end/profiler/CPUProfileBottomUpDataGrid.js
+++ b/front_end/profiler/CPUProfileBottomUpDataGrid.js
@@ -172,9 +172,6 @@ WebInspector.BottomUpProfileDataGridNode._sharedPopulate = function(container)
}
}
- for (var i = 0; i < container.children.length; ++i)
- container.children[i].buildData();
-
delete container._remainingNodeInfos;
}
@@ -325,10 +322,6 @@ WebInspector.BottomUpProfileDataGridTree.prototype = {
return this._searchResults.length;
},
- buildData: function()
- {
- },
-
/**
* @override
*/
diff --git a/front_end/profiler/CPUProfileDataGrid.js b/front_end/profiler/CPUProfileDataGrid.js
index a8430b46a2..863127a0e2 100644
--- a/front_end/profiler/CPUProfileDataGrid.js
+++ b/front_end/profiler/CPUProfileDataGrid.js
@@ -52,100 +52,62 @@ WebInspector.ProfileDataGridNode = function(profileNode, owningTree, hasChildren
WebInspector.ProfileDataGridNode.prototype = {
/**
* @override
- * @param {string} columnIdentifier
+ * @param {string} columnId
* @return {!Element}
*/
- createCell: function(columnIdentifier)
+ createCell: function(columnId)
{
- var cell = this._createValueCell(columnIdentifier) || WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
-
- if (columnIdentifier === "self" && this._searchMatchedSelfColumn)
- cell.classList.add("highlight");
- else if (columnIdentifier === "total" && this._searchMatchedTotalColumn)
- cell.classList.add("highlight");
-
- if (columnIdentifier !== "function")
+ /**
+ * @param {number} value
+ * @param {number} percent
+ * @return {!Element}
+ */
+ function createValueCell(value, percent)
+ {
+ var cell = createElementWithClass("td", "numeric-column");
+ var div = cell.createChild("div", "profile-multiple-values");
+ div.createChild("span").textContent = WebInspector.UIString("%.1f\u2009ms", value);
+ div.createChild("span", "percent-column").textContent = percent >= 0 ? WebInspector.UIString("%.2f\u2009%%", percent) : "";
return cell;
+ }
- if (this._deoptReason)
- cell.classList.add("not-optimized");
-
- if (this._searchMatchedFunctionColumn)
- cell.classList.add("highlight");
-
- if (this.profileNode.scriptId !== "0") {
+ var cell;
+ var isIdleNode = this.profileNode === this.tree.profileView.profile.idleNode;
+ switch (columnId) {
+ case "self":
+ cell = createValueCell(this.selfTime, isIdleNode ? -1 : this.selfPercent);
+ cell.classList.toggle("highlight", this._searchMatchedSelfColumn);
+ break;
+
+ case "total":
+ cell = createValueCell(this.totalTime, isIdleNode ? -1 : this.totalPercent);
+ cell.classList.toggle("highlight", this._searchMatchedTotalColumn);
+ break;
+
+ case "function":
+ cell = this.createTD(columnId);
+ cell.classList.toggle("highlight", this._searchMatchedFunctionColumn);
+ if (this._deoptReason) {
+ cell.classList.add("not-optimized");
+ cell.createChild("span", "profile-warn-marker").title = WebInspector.UIString("Not optimized: %s", this._deoptReason);
+ }
+ cell.createTextChild(this.functionName);
+ if (this.profileNode.scriptId === "0")
+ break;
var target = this.tree.profileView.target();
var callFrame = /** @type {!RuntimeAgent.CallFrame} */ (this.profileNode);
var urlElement = this.tree.profileView._linkifier.linkifyConsoleCallFrame(target, callFrame, "profile-node-file");
urlElement.style.maxWidth = "75%";
- cell.insertBefore(urlElement, cell.firstChild);
- }
-
- return cell;
- },
-
- /**
- * @param {string} columnIdentifier
- * @return {?Element}
- */
- _createValueCell: function(columnIdentifier)
- {
- if (columnIdentifier !== "self" && columnIdentifier !== "total")
- return null;
+ cell.appendChild(urlElement);
+ break;
- var cell = createElement("td");
- cell.className = "numeric-column";
- var div = createElement("div");
- var valueSpan = createElement("span");
- valueSpan.textContent = this.data[columnIdentifier];
- div.appendChild(valueSpan);
- var percentColumn = columnIdentifier + "-percent";
- if (percentColumn in this.data) {
- var percentSpan = createElement("span");
- percentSpan.className = "percent-column";
- percentSpan.textContent = this.data[percentColumn];
- div.appendChild(percentSpan);
- div.classList.add("profile-multiple-values");
+ default:
+ cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnId);
+ break;
}
- cell.appendChild(div);
return cell;
},
- buildData: function()
- {
- function formatMilliseconds(time)
- {
- return WebInspector.UIString("%.1f\u2009ms", time);
- }
- function formatPercent(value)
- {
- return WebInspector.UIString("%.2f\u2009%%", value);
- }
-
- var functionName;
- if (this._deoptReason) {
- var content = createDocumentFragment();
- var marker = content.createChild("span", "profile-warn-marker");
- marker.title = WebInspector.UIString("Not optimized: %s", this._deoptReason);
- content.createTextChild(this.functionName);
- functionName = content;
- } else {
- functionName = this.functionName;
- }
-
- this.data = {
- "function": functionName,
- "self-percent": formatPercent(this.selfPercent),
- "self": formatMilliseconds(this.selfTime),
- "total-percent": formatPercent(this.totalPercent),
- "total": formatMilliseconds(this.totalTime),
- };
- if (this.profileNode === this.tree.profileView.profile.idleNode) {
- this.data['self-percent'] = undefined;
- this.data['total-percent'] = undefined
- }
- },
-
select: function(supressSelectedEvent)
{
WebInspector.DataGridNode.prototype.select.call(this, supressSelectedEvent);
diff --git a/front_end/profiler/CPUProfileTopDownDataGrid.js b/front_end/profiler/CPUProfileTopDownDataGrid.js
index 48445c8843..f28e58b314 100644
--- a/front_end/profiler/CPUProfileTopDownDataGrid.js
+++ b/front_end/profiler/CPUProfileTopDownDataGrid.js
@@ -36,7 +36,6 @@ WebInspector.TopDownProfileDataGridNode = function(profileNode, owningTree)
WebInspector.ProfileDataGridNode.call(this, profileNode, owningTree, hasChildren);
this._remainingChildren = profileNode.children;
- this.buildData();
}
WebInspector.TopDownProfileDataGridNode.prototype = {
diff --git a/front_end/promises/PromisePane.js b/front_end/promises/PromisePane.js
deleted file mode 100644
index 24381fe2a6..0000000000
--- a/front_end/promises/PromisePane.js
+++ /dev/null
@@ -1,791 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @constructor
- * @extends {WebInspector.VBox}
- * @implements {WebInspector.TargetManager.Observer}
- */
-WebInspector.PromisePane = function()
-{
- WebInspector.VBox.call(this);
- this.registerRequiredCSS("promises/promisePane.css");
- this.element.classList.add("promises");
-
- var toolbar = new WebInspector.Toolbar("", this.element);
- this._recordButton = new WebInspector.ToolbarToggle("", "record-toolbar-item");
- this._recordButton.addEventListener("click", this._recordButtonClicked.bind(this));
- toolbar.appendToolbarItem(this._recordButton);
-
- var clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Clear"), "clear-toolbar-item");
- clearButton.addEventListener("click", this._clearButtonClicked.bind(this));
- toolbar.appendToolbarItem(clearButton);
- toolbar.appendSeparator();
-
- this._promiseStatusFiltersSetting = WebInspector.settings.createSetting("promiseStatusFilters", {});
- this._hideCollectedPromisesSetting = WebInspector.settings.createSetting("hideCollectedPromises", false);
-
- this._createFilterBar();
- toolbar.appendToolbarItem(this._filterBar.filterButton());
-
- var garbageCollectButton = new WebInspector.ToolbarButton(WebInspector.UIString("Collect garbage"), "garbage-collect-toolbar-item");
- garbageCollectButton.addEventListener("click", this._garbageCollectButtonClicked, this);
- toolbar.appendToolbarItem(garbageCollectButton);
-
- toolbar.appendSeparator();
- var asyncCheckbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString("Async"), WebInspector.UIString("Capture async stack traces"), WebInspector.moduleSetting("enableAsyncStackTraces"));
- toolbar.appendToolbarItem(asyncCheckbox);
-
- this._filterBar.show(this.element);
-
- this._hiddenByFilterCount = 0;
- this._filterStatusMessageElement = this.element.createChild("div", "promises-filter-status hidden");
- this._filterStatusTextElement = this._filterStatusMessageElement.createChild("span");
- this._filterStatusMessageElement.createTextChild(" ");
- var resetFiltersLink = this._filterStatusMessageElement.createChild("span", "link");
- resetFiltersLink.textContent = WebInspector.UIString("Show all promises.");
- resetFiltersLink.addEventListener("click", this._resetFilters.bind(this), true);
-
- // FIXME: Make "status" column width fixed to ~16px.
- var columns = [
- { id: "status", weight: 1 },
- { id: "function", title: WebInspector.UIString("Function"), disclosure: true, weight: 10 },
- { id: "created", title: WebInspector.UIString("Created"), weight: 10 },
- { id: "settled", title: WebInspector.UIString("Settled"), weight: 10 },
- { id: "tts", title: WebInspector.UIString("Time to settle"), weight: 10 }
- ];
- this._dataGrid = new WebInspector.ViewportDataGrid(columns, undefined, undefined, undefined, this._onContextMenu.bind(this));
- this._dataGrid.setStickToBottom(true);
- this._dataGrid.asWidget().show(this.element);
-
- this._linkifier = new WebInspector.Linkifier();
-
- /** @type {!Map.>} */
- this._promiseDetailsByDebuggerModel = new Map();
- /** @type {!Map.} */
- this._promiseIdToNode = new Map();
-
- this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
- this._popoverHelper.setTimeout(250, 250);
-
- this.element.addEventListener("click", this._hidePopover.bind(this), true);
-
- WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.PromiseUpdated, this._onPromiseUpdated, this);
- WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
- WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targetChanged, this);
-
- WebInspector.targetManager.observeTargets(this);
-}
-
-WebInspector.PromisePane._maxPromiseCount = 10000;
-
-
-/**
- * @constructor
- * @param {!DebuggerAgent.PromiseDetails} details
- */
-WebInspector.PromiseDetails = function(details)
-{
- this.id = details.id;
- this.isGarbageCollected = false;
- this.update(details);
-}
-
-WebInspector.PromiseDetails.prototype = {
- /**
- * @param {!DebuggerAgent.PromiseDetails} details
- */
- update: function(details)
- {
- if (this.id !== details.id)
- throw new Error("Invalid id, expected " + this.id + " was " + details.id);
- if (details.status)
- this.status = details.status;
- if (details.parentId)
- this.parentId = details.parentId;
- if (details.creationTime)
- this.creationTime = details.creationTime;
- if (details.settlementTime)
- this.settlementTime = details.settlementTime;
- if (details.creationStack) {
- this.creationStack = details.creationStack;
- if (this.creationStack.callFrames.length)
- this.callFrame = this.creationStack.callFrames[0];
- }
- if (details.asyncCreationStack)
- this.asyncCreationStack = details.asyncCreationStack;
- if (details.settlementStack)
- this.settlementStack = details.settlementStack;
- if (details.asyncSettlementStack)
- this.asyncSettlementStack = details.asyncSettlementStack;
- }
-}
-
-
-WebInspector.PromisePane.prototype = {
- _createFilterBar: function()
- {
- this._filterBar = new WebInspector.FilterBar("promisePane");
-
- this._textFilterUI = new WebInspector.TextFilterUI(true);
- this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._onFilterChanged, this);
- this._filterBar.addFilter(this._textFilterUI);
-
- var statuses = [
- { name: "pending", label: WebInspector.UIString("Pending") },
- { name: "resolved", label: WebInspector.UIString("Fulfilled") },
- { name: "rejected", label: WebInspector.UIString("Rejected") }
- ];
- this._statusFilterUI = new WebInspector.NamedBitSetFilterUI(statuses, this._promiseStatusFiltersSetting);
- this._statusFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._onFilterChanged, this);
- this._filterBar.addFilter(this._statusFilterUI);
-
- var hideCollectedCheckbox = new WebInspector.CheckboxFilterUI("hide-collected-promises", WebInspector.UIString("Hide collected promises"), true, this._hideCollectedPromisesSetting);
- hideCollectedCheckbox.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._onFilterChanged, this);
- this._filterBar.addFilter(hideCollectedCheckbox);
- },
-
- /**
- * @param {!WebInspector.PromiseDetails} details
- * @param {!WebInspector.DataGridNode} node
- * @return {boolean}
- */
- _shouldBeVisible: function(details, node)
- {
- if (!this._statusFilterUI.accept(details.status))
- return false;
-
- if (this._hideCollectedPromisesSetting.get() && details.isGarbageCollected)
- return false;
-
- var regex = this._textFilterUI.regex();
- if (!regex)
- return true;
-
- var text = node.dataTextForSearch();
- regex.lastIndex = 0;
- return regex.test(text);
- },
-
- _onFilterChanged: function()
- {
- if (this._filterChangedTimeout)
- clearTimeout(this._filterChangedTimeout);
- this._filterChangedTimeout = setTimeout(onTimerFired.bind(this), 100);
-
- /**
- * @this {WebInspector.PromisePane}
- */
- function onTimerFired()
- {
- delete this._filterChangedTimeout;
- this._refresh();
- }
- },
-
- /**
- * @override
- * @return {!Array.}
- */
- elementsToRestoreScrollPositionsFor: function()
- {
- return [this._dataGrid.scrollContainer];
- },
-
- /**
- * @override
- * @param {!WebInspector.Target} target
- */
- targetAdded: function(target)
- {
- var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
- if (debuggerModel && this._enabled)
- this._enablePromiseTracker(debuggerModel);
- },
-
- /**
- * @override
- * @param {!WebInspector.Target} target
- */
- targetRemoved: function(target)
- {
- var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
- if (!debuggerModel)
- return;
- this._promiseDetailsByDebuggerModel.delete(debuggerModel);
- if (this._debuggerModel === debuggerModel) {
- this._clear();
- delete this._debuggerModel;
- }
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _targetChanged: function(event)
- {
- if (!this._enabled)
- return;
- var target = /** @type {!WebInspector.Target} */ (event.data);
- var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
- if (!debuggerModel || this._debuggerModel === debuggerModel)
- return;
- this._debuggerModel = debuggerModel;
- this._refresh();
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _mainFrameNavigated: function(event)
- {
- var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
- var target = frame.target();
- var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
- if (!debuggerModel)
- return;
- this._promiseDetailsByDebuggerModel.delete(debuggerModel);
- if (this._debuggerModel === debuggerModel)
- this._clear();
- },
-
- /** @override */
- wasShown: function()
- {
- // Auto enable upon the very first show.
- if (typeof this._enabled === "undefined") {
- var target = WebInspector.context.flavor(WebInspector.Target);
- this._debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
- this._updateRecordingState(true);
- }
- if (this._refreshIsNeeded)
- this._refresh();
- },
-
- /**
- * @param {!WebInspector.DebuggerModel} debuggerModel
- */
- _enablePromiseTracker: function(debuggerModel)
- {
- debuggerModel.enablePromiseTracker(true);
- },
-
- /**
- * @param {!WebInspector.DebuggerModel} debuggerModel
- */
- _disablePromiseTracker: function(debuggerModel)
- {
- debuggerModel.disablePromiseTracker();
- },
-
- /** @override */
- willHide: function()
- {
- this._hidePopover();
- },
-
- _hidePopover: function()
- {
- this._popoverHelper.hidePopover();
- },
-
- _recordButtonClicked: function()
- {
- this._updateRecordingState(!this._recordButton.toggled());
- },
-
- /**
- * @param {boolean} enabled
- */
- _updateRecordingState: function(enabled)
- {
- this._enabled = enabled;
- this._recordButton.setToggled(this._enabled);
- this._recordButton.setTitle(this._enabled ? WebInspector.UIString("Stop Recording Promises Log") : WebInspector.UIString("Record Promises Log"));
- WebInspector.DebuggerModel.instances().forEach(this._enabled ? this._enablePromiseTracker : this._disablePromiseTracker, this);
- },
-
- _clearButtonClicked: function()
- {
- this._clear();
- if (this._debuggerModel)
- this._promiseDetailsByDebuggerModel.delete(this._debuggerModel);
- },
-
- _resetFilters: function()
- {
- this._hideCollectedPromisesSetting.set(false);
- this._promiseStatusFiltersSetting.set({});
- this._textFilterUI.setValue("");
- },
-
- _updateFilterStatus: function()
- {
- this._filterStatusTextElement.textContent = WebInspector.UIString(this._hiddenByFilterCount === 1 ? "%d promise is hidden by filters." : "%d promises are hidden by filters.", this._hiddenByFilterCount);
- this._filterStatusMessageElement.classList.toggle("hidden", !this._hiddenByFilterCount);
- },
-
- _garbageCollectButtonClicked: function()
- {
- var targets = WebInspector.targetManager.targets();
- for (var i = 0; i < targets.length; ++i)
- targets[i].heapProfilerAgent().collectGarbage();
- },
-
- /**
- * @param {!WebInspector.DebuggerModel} debuggerModel
- * @return {boolean}
- */
- _truncateLogIfNeeded: function(debuggerModel)
- {
- var promiseIdToDetails = this._promiseDetailsByDebuggerModel.get(debuggerModel);
- if (!promiseIdToDetails || promiseIdToDetails.size <= WebInspector.PromisePane._maxPromiseCount)
- return false;
-
- var elementsToTruncate = WebInspector.PromisePane._maxPromiseCount / 10;
- var sortedDetails = promiseIdToDetails.valuesArray().sort(compare);
- for (var i = 0; i < elementsToTruncate; ++i)
- promiseIdToDetails.delete(sortedDetails[i].id);
- return true;
-
- /**
- * @param {!WebInspector.PromiseDetails} x
- * @param {!WebInspector.PromiseDetails} y
- * @return {number}
- */
- function compare(x, y)
- {
- var t1 = x.creationTime || 0;
- var t2 = y.creationTime || 0;
- return t1 - t2 || x.id - y.id;
- }
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onPromiseUpdated: function(event)
- {
- var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
- var eventType = /** @type {string} */ (event.data.eventType);
- var protocolDetails = /** @type {!DebuggerAgent.PromiseDetails} */ (event.data.promise);
-
- var promiseIdToDetails = this._promiseDetailsByDebuggerModel.get(debuggerModel);
- if (!promiseIdToDetails) {
- promiseIdToDetails = new Map();
- this._promiseDetailsByDebuggerModel.set(debuggerModel, promiseIdToDetails);
- }
-
- var details = promiseIdToDetails.get(protocolDetails.id);
- if (!details && eventType === "gc")
- return;
-
- var truncated = this._truncateLogIfNeeded(debuggerModel);
- if (details)
- details.update(protocolDetails)
- else
- details = new WebInspector.PromiseDetails(protocolDetails);
- promiseIdToDetails.set(details.id, details);
-
- if (eventType === "gc")
- details.isGarbageCollected = true;
-
- if (debuggerModel === this._debuggerModel) {
- if (!this.isShowing()) {
- this._refreshIsNeeded = true;
- return;
- }
- if (truncated || this._refreshIsNeeded) {
- this._refresh();
- return;
- }
-
- var node = /** @type {!WebInspector.DataGridNode} */ (this._promiseIdToNode.get(details.id));
- var wasVisible = !node || !node._isPromiseHidden;
-
- // Check for the fast path on GC events.
- if (eventType === "gc" && node && node.parent && !this._hideCollectedPromisesSetting.get())
- node.update(details);
- else
- this._attachDataGridNode(details);
-
- var isVisible = this._shouldBeVisible(details, /** @type {!WebInspector.DataGridNode} */(this._promiseIdToNode.get(details.id)));
- if (wasVisible !== isVisible) {
- this._hiddenByFilterCount += wasVisible ? 1 : -1;
- this._updateFilterStatus();
- }
- }
- },
-
- /**
- * @param {!WebInspector.PromiseDetails} details
- */
- _attachDataGridNode: function(details)
- {
- var node = this._createDataGridNode(details);
- var parentNode = this._findVisibleParentNodeDetails(details);
- if (parentNode !== node.parent)
- parentNode.appendChild(node);
- if (this._shouldBeVisible(details, node))
- parentNode.expanded = true;
- else
- node.remove();
- },
-
- /**
- * @param {!WebInspector.PromiseDetails} details
- * @return {!WebInspector.DataGridNode}
- */
- _findVisibleParentNodeDetails: function(details)
- {
- var promiseIdToDetails = /** @type {!Map.} */ (this._promiseDetailsByDebuggerModel.get(this._debuggerModel));
- var currentDetails = details;
- while (currentDetails) {
- var parentId = currentDetails.parentId;
- if (typeof parentId !== "number")
- break;
- currentDetails = promiseIdToDetails.get(parentId);
- if (!currentDetails)
- break;
- var node = this._promiseIdToNode.get(currentDetails.id);
- if (node && this._shouldBeVisible(currentDetails, node))
- return node;
- }
- return this._dataGrid.rootNode();
- },
-
- /**
- * @param {!WebInspector.PromiseDetails} details
- * @return {!WebInspector.DataGridNode}
- */
- _createDataGridNode: function(details)
- {
- var node = this._promiseIdToNode.get(details.id);
- if (!node) {
- node = new WebInspector.PromiseDataGridNode(details, this._debuggerModel, this._linkifier, this._dataGrid);
- this._promiseIdToNode.set(details.id, node);
- } else {
- node.update(details);
- }
- return node;
- },
-
- _refresh: function()
- {
- delete this._refreshIsNeeded;
- this._clear();
- if (!this._debuggerModel)
- return;
- if (!this._promiseDetailsByDebuggerModel.has(this._debuggerModel))
- return;
-
- var rootNode = this._dataGrid.rootNode();
- var promiseIdToDetails = /** @type {!Map.} */ (this._promiseDetailsByDebuggerModel.get(this._debuggerModel));
-
- var nodesToInsert = { __proto__: null };
- // The for..of loop iterates in insertion order.
- for (var pair of promiseIdToDetails) {
- var id = /** @type {number} */ (pair[0]);
- var details = /** @type {!WebInspector.PromiseDetails} */ (pair[1]);
- var node = this._createDataGridNode(details);
- node._isPromiseHidden = !this._shouldBeVisible(details, node);
- if (node._isPromiseHidden) {
- ++this._hiddenByFilterCount;
- continue;
- }
- nodesToInsert[id] = { details: details, node: node };
- }
-
- for (var id in nodesToInsert) {
- var node = nodesToInsert[id].node;
- var details = nodesToInsert[id].details;
- this._findVisibleParentNodeDetails(details).appendChild(node);
- }
-
- for (var id in nodesToInsert) {
- var node = nodesToInsert[id].node;
- var details = nodesToInsert[id].details;
- node.expanded = true;
- }
-
- this._updateFilterStatus();
- },
-
- _clear: function()
- {
- this._hiddenByFilterCount = 0;
- this._updateFilterStatus();
- this._promiseIdToNode.clear();
- this._hidePopover();
- this._dataGrid.rootNode().removeChildren();
- this._linkifier.reset();
- },
-
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {!WebInspector.DataGridNode} node
- */
- _onContextMenu: function(contextMenu, node)
- {
- var debuggerModel = this._debuggerModel;
- if (!debuggerModel)
- return;
-
- var promiseId = node.promiseId();
- if (this._promiseDetailsByDebuggerModel.has(debuggerModel)) {
- var details = this._promiseDetailsByDebuggerModel.get(debuggerModel).get(promiseId);
- if (details.isGarbageCollected)
- return;
- }
-
- contextMenu.appendItem(WebInspector.UIString.capitalize("Show in ^console"), showPromiseInConsole);
- contextMenu.show();
-
- function showPromiseInConsole()
- {
- debuggerModel.getPromiseById(promiseId, "console", didGetPromiseById);
- }
-
- /**
- * @param {?RuntimeAgent.RemoteObject} promise
- */
- function didGetPromiseById(promise)
- {
- if (!promise)
- return;
- var object = debuggerModel.target().runtimeModel.createRemoteObject(promise);
- object.callFunction(dumpIntoConsole);
- object.release();
- /**
- * @suppressReceiverCheck
- * @this {Object}
- */
- function dumpIntoConsole()
- {
- console.log(this);
- }
- WebInspector.console.show();
- }
- },
-
- /**
- * @param {!Element} element
- * @param {!Event} event
- * @return {!Element|!AnchorBox|undefined}
- */
- _getPopoverAnchor: function(element, event)
- {
- if (!this._debuggerModel || !this._promiseDetailsByDebuggerModel.has(this._debuggerModel))
- return undefined;
- var node = this._dataGrid.dataGridNodeFromNode(element);
- if (!node)
- return undefined;
- var details = this._promiseDetailsByDebuggerModel.get(this._debuggerModel).get(node.promiseId());
- if (!details)
- return undefined;
- var anchor = element.enclosingNodeOrSelfWithClass("created-column");
- if (anchor)
- return details.creationStack ? anchor : undefined;
- anchor = element.enclosingNodeOrSelfWithClass("settled-column");
- return (anchor && details.settlementStack) ? anchor : undefined;
- },
-
- /**
- * @param {!Element} anchor
- * @param {!WebInspector.Popover} popover
- */
- _showPopover: function(anchor, popover)
- {
- var node = this._dataGrid.dataGridNodeFromNode(anchor);
- var details = this._promiseDetailsByDebuggerModel.get(this._debuggerModel).get(node.promiseId());
-
- var stackTrace;
- if (anchor.classList.contains("created-column"))
- stackTrace = details.creationStack;
- else
- stackTrace = details.settlementStack;
-
- var content = WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(this._debuggerModel.target(), this._linkifier, stackTrace);
- popover.setCanShrink(true);
- popover.showForAnchor(content, anchor);
- },
-
- __proto__: WebInspector.VBox.prototype
-}
-
-/**
- * @constructor
- * @extends {WebInspector.ViewportDataGridNode}
- * @param {!WebInspector.PromiseDetails} details
- * @param {!WebInspector.DebuggerModel} debuggerModel
- * @param {!WebInspector.Linkifier} linkifier
- * @param {!WebInspector.ViewportDataGrid} dataGrid
- */
-WebInspector.PromiseDataGridNode = function(details, debuggerModel, linkifier, dataGrid)
-{
- WebInspector.ViewportDataGridNode.call(this, {});
- this._details = details;
- this._debuggerModel = debuggerModel;
- this._linkifier = linkifier;
- /** @type {!Array.} */
- this._linkifiedAnchors = [];
- this.dataGrid = dataGrid;
-}
-
-WebInspector.PromiseDataGridNode.prototype = {
- _disposeAnchors: function()
- {
- for (var i = 0; i < this._linkifiedAnchors.length; ++i)
- this._linkifier.disposeAnchor(this._debuggerModel.target(), this._linkifiedAnchors[i]);
- this._linkifiedAnchors = [];
- },
-
- /**
- * @param {!WebInspector.PromiseDetails} details
- */
- update: function(details)
- {
- this._disposeAnchors();
- this._details = details;
- this.refresh();
- },
-
- /**
- * @override
- */
- wasDetached: function()
- {
- this._disposeAnchors();
- },
-
- /**
- * @override
- * @return {number}
- */
- nodeSelfHeight: function()
- {
- return 24;
- },
-
- /**
- * @return {number}
- */
- promiseId: function()
- {
- return this._details.id;
- },
-
- /**
- * @override
- */
- createCells: function()
- {
- this._element.classList.toggle("promise-gc", !!this._details.isGarbageCollected);
- WebInspector.ViewportDataGridNode.prototype.createCells.call(this);
- },
-
- /**
- * @param {!Element} cell
- * @param {?RuntimeAgent.CallFrame=} callFrame
- */
- _appendCallFrameAnchor: function(cell, callFrame)
- {
- if (!callFrame)
- return;
- var anchor = this._linkifier.linkifyConsoleCallFrame(this._debuggerModel.target(), callFrame);
- this._linkifiedAnchors.push(anchor);
- cell.appendChild(anchor);
- },
-
- /**
- * @override
- * @param {string} columnIdentifier
- * @return {!Element}
- */
- createCell: function(columnIdentifier)
- {
- var cell = this.createTD(columnIdentifier);
- var details = this._details;
-
- switch (columnIdentifier) {
- case "status":
- var title = "";
- switch (details.status) {
- case "pending":
- title = WebInspector.UIString("Pending");
- break;
- case "resolved":
- title = WebInspector.UIString("Fulfilled");
- break;
- case "rejected":
- title = WebInspector.UIString("Rejected");
- break;
- }
- if (details.isGarbageCollected)
- title += " " + WebInspector.UIString("(garbage collected)");
- cell.createChild("div", "status " + details.status).title = title;
- break;
-
- case "function":
- cell.createTextChild(WebInspector.beautifyFunctionName(details.callFrame ? details.callFrame.functionName : ""));
- break;
-
- case "created":
- this._appendCallFrameAnchor(cell, details.callFrame);
- break;
-
- case "settled":
- this._appendCallFrameAnchor(cell, details.settlementStack && details.settlementStack.callFrames.length ? details.settlementStack.callFrames[0] : null);
- break;
-
- case "tts":
- cell.createTextChild(this._ttsCellText());
- break;
- }
-
- return cell;
- },
-
- /**
- * @return {string}
- */
- _ttsCellText: function()
- {
- var details = this._details;
- if (details.creationTime && details.settlementTime && details.settlementTime >= details.creationTime)
- return Number.millisToString(details.settlementTime - details.creationTime);
- return "";
- },
-
- /**
- * @param {?RuntimeAgent.CallFrame=} callFrame
- * @return {string}
- */
- _callFrameAnchorTextForSearch: function(callFrame)
- {
- if (!callFrame)
- return "";
- var script = callFrame.scriptId && this._debuggerModel ? this._debuggerModel.scriptForId(callFrame.scriptId) : null;
- var sourceURL = script ? script.sourceURL : callFrame.url;
- var lineNumber = callFrame.lineNumber || 0;
- return WebInspector.displayNameForURL(sourceURL) + ":" + lineNumber;
- },
-
- /**
- * @return {string}
- */
- dataTextForSearch: function()
- {
- var details = this._details;
- var texts = [
- WebInspector.beautifyFunctionName(details.callFrame ? details.callFrame.functionName : ""),
- this._callFrameAnchorTextForSearch(details.callFrame),
- this._callFrameAnchorTextForSearch(details.settlementStack && details.settlementStack.callFrames.length ? details.settlementStack.callFrames[0] : null),
- this._ttsCellText().replace(/\u2009/g, " ") // \u2009 is a thin space.
- ];
- return texts.join(" ");
- },
-
- __proto__: WebInspector.ViewportDataGridNode.prototype
-}
diff --git a/front_end/promises/module.json b/front_end/promises/module.json
deleted file mode 100644
index 520e4f6a64..0000000000
--- a/front_end/promises/module.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "extensions": [
- {
- "type": "drawer-view",
- "name": "promises",
- "title": "Promises",
- "order": 30,
- "persistence": "permanent",
- "className": "WebInspector.PromisePane"
- }
- ],
- "dependencies": ["components", "ui_lazy"],
- "experiment": "promiseTracker",
- "scripts": [
- "PromisePane.js"
- ],
- "resources": [
- "promisePane.css"
- ]
-}
diff --git a/front_end/promises/promisePane.css b/front_end/promises/promisePane.css
deleted file mode 100644
index 55a61a6998..0000000000
--- a/front_end/promises/promisePane.css
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.promises .data-grid {
- border: none;
- flex: 1 1;
-}
-
-.promises > .toolbar {
- border-bottom: 1px solid #dadada;
-}
-
-.promises .promise-gc {
- opacity: 0.6;
-}
-
-.promises .data-grid th:hover {
- background-color: inherit !important;
-}
-
-.promises .data-grid .odd {
- background-color: #eee;
-}
-
-.promises .data-grid .header-container {
- height: 30px;
-}
-
-.promises .data-grid .data-container {
- top: 29px;
-}
-
-.promises .data-grid table.data {
- background: transparent;
-}
-
-.promises .data-grid th {
- background-color: white;
-}
-
-.promises .data-grid td {
- line-height: 17px;
- height: 24px;
- vertical-align: middle;
-}
-
-.promises .data-grid th,
-.promises .data-grid td {
- border-bottom: 1px solid rgb(205, 205, 205);
- border-left: 1px solid rgb(205, 205, 205);
-}
-
-.promises .status {
- -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);
- -webkit-mask-size: 352px 168px;
- -webkit-mask-position: -294px -26px;
- background-color: #bbb;
- height: 20px;
- width: 20px;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.5) {
-.promises .status {
- -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);
-}
-} /* media */
-
-.promises .status.rejected {
- background-color: rgb(216, 0, 0);
-}
-
-.promises .status.resolved {
- background-color: #696;
-}
-
-.promises-filters-header {
- flex: 0 0 23px;
- overflow: hidden;
-}
-
-.promises-filter-status {
- flex: 0 0 23px;
- padding-left: 18px;
- color: rgb(128, 128, 128);
- font-style: italic;
-}
-.promises-filter-status .link:hover {
- color: rgb(15%, 15%, 15%);
-}
-.promises-filter-status .link {
- color: rgb(33%, 33%, 33%);
-}
diff --git a/front_end/resources/ServiceWorkersView.js b/front_end/resources/ServiceWorkersView.js
index 23c0f89f20..2aafa6f038 100644
--- a/front_end/resources/ServiceWorkersView.js
+++ b/front_end/resources/ServiceWorkersView.js
@@ -15,10 +15,10 @@ WebInspector.ServiceWorkersView = function()
/** @type {!Set.} */
this._securityOriginHosts = new Set();
- /** @type {!Map.} */
- this._originHostToOriginElementMap = new Map();
- /** @type {!Map.} */
- this._registrationIdToOriginElementMap = new Map();
+ /** @type {!Map.} */
+ this._originHostToOriginWidgetMap = new Map();
+ /** @type {!Map.} */
+ this._registrationIdToOriginWidgetMap = new Map();
var settingsDiv = createElementWithClass("div", "service-workers-settings");
var debugOnStartCheckboxLabel = createCheckboxLabel(WebInspector.UIString("Open DevTools window and pause JavaScript execution on Service Worker startup for debugging."));
@@ -28,7 +28,7 @@ WebInspector.ServiceWorkersView = function()
settingsDiv.appendChild(debugOnStartCheckboxLabel);
this.contentElement.appendChild(settingsDiv);
- this._root = this.contentElement.createChild("ol");
+ this._root = this.contentElement.createChild("div");
this._root.classList.add("service-workers-root");
WebInspector.targetManager.observeTargets(this);
@@ -48,7 +48,6 @@ WebInspector.ServiceWorkersView.prototype = {
this._debugOnStartCheckbox.disabled = false;
this._debugOnStartCheckbox.checked = this._manager.debugOnStart();
-
for (var registration of this._manager.registrations().values())
this._updateRegistration(registration);
@@ -91,15 +90,15 @@ WebInspector.ServiceWorkersView.prototype = {
if (!parsedURL)
return;
var originHost = parsedURL.host;
- var originElement = this._originHostToOriginElementMap.get(originHost);
- if (!originElement) {
- originElement = new WebInspector.ServiceWorkerOriginElement(this._manager, originHost);
+ var originWidget = this._originHostToOriginWidgetMap.get(originHost);
+ if (!originWidget) {
+ originWidget = new WebInspector.ServiceWorkerOriginWidget(this._manager, originHost);
if (this._securityOriginHosts.has(originHost))
- this._appendOriginNode(originElement);
- this._originHostToOriginElementMap.set(originHost, originElement);
+ originWidget.show(this._root);
+ this._originHostToOriginWidgetMap.set(originHost, originWidget);
}
- this._registrationIdToOriginElementMap.set(registration.id, originElement);
- originElement._updateRegistration(registration);
+ this._registrationIdToOriginWidgetMap.set(registration.id, originWidget);
+ originWidget._updateRegistration(registration);
},
/**
@@ -109,16 +108,16 @@ WebInspector.ServiceWorkersView.prototype = {
{
var registration = /** @type {!WebInspector.ServiceWorkerRegistration} */ (event.data);
var registrationId = registration.id;
- var originElement = this._registrationIdToOriginElementMap.get(registrationId);
- if (!originElement)
+ var originWidget = this._registrationIdToOriginWidgetMap.get(registrationId);
+ if (!originWidget)
return;
- this._registrationIdToOriginElementMap.delete(registrationId);
- originElement._deleteRegistration(registrationId);
- if (originElement._hasRegistration())
+ this._registrationIdToOriginWidgetMap.delete(registrationId);
+ originWidget._deleteRegistration(registrationId);
+ if (originWidget._hasRegistration())
return;
- if (this._securityOriginHosts.has(originElement._originHost))
- this._removeOriginNode(originElement);
- this._originHostToOriginElementMap.delete(originElement._originHost);
+ if (this._securityOriginHosts.has(originWidget._originHost))
+ originWidget.detach();
+ this._originHostToOriginWidgetMap.delete(originWidget._originHost);
},
/**
@@ -150,10 +149,10 @@ WebInspector.ServiceWorkersView.prototype = {
if (this._securityOriginHosts.has(originHost))
return;
this._securityOriginHosts.add(originHost);
- var originElement = this._originHostToOriginElementMap.get(originHost);
- if (!originElement)
+ var originWidget = this._originHostToOriginWidgetMap.get(originHost);
+ if (!originWidget)
return;
- this._appendOriginNode(originElement);
+ originWidget.show(this._root);
},
/**
@@ -169,26 +168,10 @@ WebInspector.ServiceWorkersView.prototype = {
if (!this._securityOriginHosts.has(originHost))
return;
this._securityOriginHosts.delete(originHost);
- var originElement = this._originHostToOriginElementMap.get(originHost);
- if (!originElement)
+ var originWidget = this._originHostToOriginWidgetMap.get(originHost);
+ if (!originWidget)
return;
- this._removeOriginNode(originElement);
- },
-
- /**
- * @param {!WebInspector.ServiceWorkerOriginElement} originElement
- */
- _appendOriginNode: function(originElement)
- {
- this._root.appendChild(originElement._element);
- },
-
- /**
- * @param {!WebInspector.ServiceWorkerOriginElement} originElement
- */
- _removeOriginNode: function(originElement)
- {
- this._root.removeChild(originElement._element);
+ originWidget.detach();
},
_debugOnStartCheckboxChanged: function()
@@ -204,28 +187,28 @@ WebInspector.ServiceWorkersView.prototype = {
/**
* @constructor
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.ServiceWorkerManager} manager
* @param {string} originHost
*/
-WebInspector.ServiceWorkerOriginElement = function(manager, originHost)
+WebInspector.ServiceWorkerOriginWidget = function(manager, originHost)
{
+ WebInspector.VBox.call(this);
this._manager = manager;
- /** @type {!Map.} */
- this._registrationElements = new Map();
+ /** @type {!Map.} */
+ this._registrationWidgets = new Map();
this._originHost = originHost;
- this._element = createElementWithClass("div", "service-workers-origin");
- this._listItemNode = this._element.createChild("li", "service-workers-origin-title");
- this._listItemNode.createChild("div").setTextAndTitle(originHost);
- this._childrenListNode = this._element.createChild("ol");
+ this.element.classList.add("service-workers-origin");
+ this._titleElement = this.element.createChild("span", "service-workers-origin-title");
}
-WebInspector.ServiceWorkerOriginElement.prototype = {
+WebInspector.ServiceWorkerOriginWidget.prototype = {
/**
* @return {boolean}
*/
_hasRegistration: function()
{
- return this._registrationElements.size != 0;
+ return this._registrationWidgets.size != 0;
},
/**
@@ -233,14 +216,16 @@ WebInspector.ServiceWorkerOriginElement.prototype = {
*/
_updateRegistration: function(registration)
{
- var swRegistrationElement = this._registrationElements.get(registration.id);
- if (swRegistrationElement) {
- swRegistrationElement._updateRegistration(registration);
+ this._titleElement.setTextAndTitle(WebInspector.UIString(registration.isDeleted ? "%s%s - deleted" : "%s%s", this._originHost, registration.scopeURL.asParsedURL().path));
+
+ var registrationWidget = this._registrationWidgets.get(registration.id);
+ if (registrationWidget) {
+ registrationWidget._updateRegistration(registration);
return;
}
- swRegistrationElement = new WebInspector.SWRegistrationElement(this._manager, this, registration);
- this._registrationElements.set(registration.id, swRegistrationElement);
- this._childrenListNode.appendChild(swRegistrationElement._element);
+ registrationWidget = new WebInspector.SWRegistrationWidget(this._manager, this, registration);
+ this._registrationWidgets.set(registration.id, registrationWidget);
+ registrationWidget.show(this.element);
},
/**
@@ -248,187 +233,125 @@ WebInspector.ServiceWorkerOriginElement.prototype = {
*/
_deleteRegistration: function(registrationId)
{
- var swRegistrationElement = this._registrationElements.get(registrationId);
- if (!swRegistrationElement)
+ var registrationWidget = this._registrationWidgets.get(registrationId);
+ if (!registrationWidget)
return;
- this._registrationElements.delete(registrationId);
- this._childrenListNode.removeChild(swRegistrationElement._element);
+ this._registrationWidgets.delete(registrationId);
+ registrationWidget.detach();
},
- /**
- * @return {boolean}
- */
- _visible: function()
- {
- return !!this._element.parentElement;
- },
+ __proto__: WebInspector.VBox.prototype
}
/**
* @constructor
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.ServiceWorkerManager} manager
- * @param {!WebInspector.ServiceWorkerOriginElement} originElement
+ * @param {!WebInspector.ServiceWorkerOriginWidget} originWidget
* @param {!WebInspector.ServiceWorkerRegistration} registration
*/
-WebInspector.SWRegistrationElement = function(manager, originElement, registration)
+WebInspector.SWRegistrationWidget = function(manager, originWidget, registration)
{
+ WebInspector.VBox.call(this);
this._manager = manager;
- this._originElement = originElement;
+ this._originWidget = originWidget;
this._registration = registration;
- this._element = createElementWithClass("div", "service-workers-registration");
- var headerNode = this._element.createChild("div", "service-workers-registration-header");
- this._titleNode = headerNode.createChild("div", "service-workers-registration-title");
- var buttonsNode = headerNode.createChild("div", "service-workers-registration-buttons");
- this._updateButton = buttonsNode.createChild("button", "service-workers-button service-workers-update-button");
- this._updateButton.addEventListener("click", this._updateButtonClicked.bind(this), false);
- this._updateButton.title = WebInspector.UIString("Update");
- this._updateButton.disabled = true
- this._pushButton = buttonsNode.createChild("button", "service-workers-button service-workers-push-button");
- this._pushButton.addEventListener("click", this._pushButtonClicked.bind(this), false);
- this._pushButton.title = WebInspector.UIString("Emulate push event");
- this._pushButton.disabled = true
- this._deleteButton = buttonsNode.createChild("button", "service-workers-button service-workers-delete-button");
- this._deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);
- this._deleteButton.title = WebInspector.UIString("Delete");
- this._childrenListNode = this._element.createChild("div", "service-workers-registration-content");
+ this.element.classList.add("service-workers-registration");
+
+ var toolbar = new WebInspector.Toolbar("", this.element);
+ this._updateButton = new WebInspector.ToolbarButton(WebInspector.UIString("Update"), "refresh-toolbar-item", WebInspector.UIString("Update"));
+ this._updateButton.addEventListener("click", this._updateButtonClicked.bind(this));
+ toolbar.appendToolbarItem(this._updateButton);
+
+ toolbar.appendSeparator();
+ this._pushButton = new WebInspector.ToolbarButton(WebInspector.UIString("Emulate push event"), "notification-toolbar-item", WebInspector.UIString("Push"));
+ this._pushButton.addEventListener("click", this._pushButtonClicked.bind(this));
+ toolbar.appendToolbarItem(this._pushButton);
+ toolbar.appendSpacer();
+ this._deleteButton = new WebInspector.ToolbarButton(WebInspector.UIString("Delete"), "garbage-collect-toolbar-item", WebInspector.UIString("Delete"));
+ this._deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this));
+ toolbar.appendToolbarItem(this._deleteButton);
+
+ this._tabbedPane = new WebInspector.TabbedPane();
+ this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
+ var modes = WebInspector.ServiceWorkerVersion.Modes;
+ this._tabbedPane.appendTab(modes.Installing, WebInspector.UIString("Installing"), new WebInspector.VBox());
+ this._tabbedPane.appendTab(modes.Waiting, WebInspector.UIString("Waiting"), new WebInspector.VBox());
+ this._tabbedPane.appendTab(modes.Active, WebInspector.UIString("Active"), new WebInspector.VBox());
+ this._tabbedPane.appendTab(modes.Redundant, WebInspector.UIString("Redundant"), new WebInspector.VBox());
+ this._tabbedPane.show(this.element);
+
+ /** @type {!Map} */
+ this._versionWidgets = new Map();
- /**
- * @type {!Object.>}
- */
- this._categorizedVersions = {};
- for (var mode in WebInspector.ServiceWorkerVersion.Modes)
- this._categorizedVersions[WebInspector.ServiceWorkerVersion.Modes[mode]] = [];
-
- this._selectedMode = WebInspector.ServiceWorkerVersion.Modes.Active;
+ this._updateRegistration(registration);
+}
+WebInspector.SWRegistrationWidget.prototype = {
/**
- * @type {!Array.}
+ * @param {!WebInspector.Event} event
*/
- this._versionElements = [];
-
- this._updateRegistration(registration);
-}
+ _tabSelected: function(event)
+ {
+ if (event.data["isUserGesture"])
+ this._lastManuallySelectedTab = event.data["tabId"];
+ },
-WebInspector.SWRegistrationElement.prototype = {
/**
* @param {!WebInspector.ServiceWorkerRegistration} registration
*/
_updateRegistration: function(registration)
{
this._registration = registration;
- this._titleNode.setTextAndTitle(WebInspector.UIString(registration.isDeleted ? "Scope: %s - deleted" : "Scope: %s", registration.scopeURL.asParsedURL().path));
- this._updateButton.disabled = !!registration.isDeleted;
- this._deleteButton.disabled = !!registration.isDeleted;
-
- var lastFocusedVersionId = undefined;
- if (this._categorizedVersions[this._selectedMode].length)
- lastFocusedVersionId = this._categorizedVersions[this._selectedMode][0].id;
- for (var mode in WebInspector.ServiceWorkerVersion.Modes)
- this._categorizedVersions[WebInspector.ServiceWorkerVersion.Modes[mode]] = [];
+ this._updateButton.setEnabled(!registration.isDeleted);
+ this._deleteButton.setEnabled(!registration.isDeleted);
+
+ /** @type {!Map} */
+ var versionWidgets = new Map();
+
+ var modesWithVersions = new Set();
+ var firstMode;
for (var version of registration.versions.valuesArray()) {
if (version.isStoppedAndRedundant() && !version.errorMessages.length)
continue;
var mode = version.mode();
- this._categorizedVersions[mode].push(version);
- if (version.id === lastFocusedVersionId)
- this._selectedMode = mode;
+ if (!firstMode)
+ firstMode = mode;
+ modesWithVersions.add(mode);
+ var view = this._tabbedPane.tabView(mode);
+ var versionWidget = this._versionWidgets.get(version.id);
+ if (versionWidget)
+ versionWidget._updateVersion(version);
+ else
+ versionWidget = new WebInspector.SWVersionWidget(this._manager, this._registration.scopeURL, version);
+ versionWidget.show(view.element);
+ versionWidgets.set(version.id, versionWidget);
}
- if (!this._categorizedVersions[this._selectedMode].length) {
- for (var mode of [WebInspector.ServiceWorkerVersion.Modes.Active,
- WebInspector.ServiceWorkerVersion.Modes.Waiting,
- WebInspector.ServiceWorkerVersion.Modes.Installing,
- WebInspector.ServiceWorkerVersion.Modes.Redundant]) {
- if (this._categorizedVersions[mode].length) {
- this._selectedMode = mode;
- break;
- }
- }
+ for (var id of this._versionWidgets.keys()) {
+ if (!versionWidgets.has(id))
+ this._versionWidgets.get(id).detach();
}
- this._pushButton.disabled = !this._categorizedVersions[WebInspector.ServiceWorkerVersion.Modes.Active].length || !!this._registration.isDeleted;
+ this._versionWidgets = versionWidgets;
- this._updateVersionList();
- },
+ for (var id of this._tabbedPane.tabIds())
+ this._tabbedPane.setTabEnabled(id, modesWithVersions.has(id));
- _updateVersionList: function()
- {
- var fragment = createDocumentFragment();
- var modeTabList = createElementWithClass("div", "service-workers-versions-mode-tab-list");
- modeTabList.appendChild(this._createVersionModeTab(WebInspector.ServiceWorkerVersion.Modes.Installing));
- modeTabList.appendChild(this._createVersionModeTab(WebInspector.ServiceWorkerVersion.Modes.Waiting));
- modeTabList.appendChild(this._createVersionModeTab(WebInspector.ServiceWorkerVersion.Modes.Active));
- modeTabList.appendChild(this._createVersionModeTab(WebInspector.ServiceWorkerVersion.Modes.Redundant));
- fragment.appendChild(modeTabList);
- fragment.appendChild(this._createSelectedModeVersionsPanel(this._selectedMode));
- this._childrenListNode.removeChildren();
- this._childrenListNode.appendChild(fragment);
- },
-
- /**
- * @param {string} mode
- * @return {!Element}
- */
- _createVersionModeTab: function(mode)
- {
- var versions = this._categorizedVersions[mode];
- var modeTitle = WebInspector.UIString(mode);
- var selected = this._selectedMode == mode;
- var modeTab = createElementWithClass("div", "service-workers-versions-mode-tab");
- for (var version of versions) {
- var icon = modeTab.createChild("div", "service-workers-versions-mode-tab-icon service-workers-color-" + (version.id % 10));
- icon.title = WebInspector.UIString("ID: %s", version.id);
- }
- var modeTabText = modeTab.createChild("div", "service-workers-versions-mode-tab-text");
- modeTabText.setTextAndTitle(WebInspector.UIString(modeTitle));
- if (selected) {
- modeTab.classList.add("service-workers-versions-mode-tab-selected");
- modeTabText.classList.add("service-workers-versions-mode-tab-text-selected");
- }
- if (versions.length) {
- modeTab.addEventListener("click", this._modeTabClicked.bind(this, mode), false);
- } else {
- modeTab.classList.add("service-workers-versions-mode-tab-disabled");
- modeTabText.classList.add("service-workers-versions-mode-tab-text-disabled");
- }
- return modeTab;
- },
+ this._pushButton.setEnabled(modesWithVersions.has(WebInspector.ServiceWorkerVersion.Modes.Active) && !this._registration.isDeleted);
- /**
- * @param {string} mode
- * @return {!Element}
- */
- _createSelectedModeVersionsPanel: function(mode)
- {
- var versions = this._categorizedVersions[mode];
- var panelContainer = createElementWithClass("div", "service-workers-versions-panel-container");
- var index = 0;
- var versionElement;
- for (var i = 0; i < versions.length; ++i) {
- if (i < this._versionElements.length) {
- versionElement = this._versionElements[i];
- versionElement._updateVersion(versions[i]);
- } else {
- versionElement = new WebInspector.SWVersionElement(this._manager, this._registration.scopeURL, versions[i]);
- this._versionElements.push(versionElement);
- }
- panelContainer.appendChild(versionElement._element);
+ if (modesWithVersions.has(this._lastManuallySelectedTab)) {
+ this._tabbedPane.selectTab(this._lastManuallySelectedTab);
+ return;
}
- this._versionElements.splice(versions.length);
- return panelContainer;
- },
-
- /**
- * @param {string} mode
- */
- _modeTabClicked: function(mode)
- {
- if (this._selectedMode == mode)
+ if (modesWithVersions.has(WebInspector.ServiceWorkerVersion.Modes.Active)) {
+ this._tabbedPane.selectTab(WebInspector.ServiceWorkerVersion.Modes.Active);
return;
- this._selectedMode = mode;
- this._updateVersionList();
+ }
+ if (firstMode)
+ this._tabbedPane.selectTab(firstMode);
},
/**
- * @param {!Event} event
+ * @param {!WebInspector.Event} event
*/
_deleteButtonClicked: function(event)
{
@@ -436,7 +359,7 @@ WebInspector.SWRegistrationElement.prototype = {
},
/**
- * @param {!Event} event
+ * @param {!WebInspector.Event} event
*/
_updateButtonClicked: function(event)
{
@@ -444,7 +367,7 @@ WebInspector.SWRegistrationElement.prototype = {
},
/**
- * @param {!Event} event
+ * @param {!WebInspector.Event} event
*/
_pushButtonClicked: function(event)
{
@@ -452,27 +375,23 @@ WebInspector.SWRegistrationElement.prototype = {
this._manager.deliverPushMessage(this._registration.id, data);
},
- /**
- * @return {boolean}
- */
- _visible: function()
- {
- return this._originElement._visible();
- },
+ __proto__: WebInspector.VBox.prototype
}
/**
* @constructor
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.ServiceWorkerManager} manager
* @param {string} scopeURL
* @param {!WebInspector.ServiceWorkerVersion} version
*/
-WebInspector.SWVersionElement = function(manager, scopeURL, version)
+WebInspector.SWVersionWidget = function(manager, scopeURL, version)
{
+ WebInspector.VBox.call(this);
this._manager = manager;
this._scopeURL = scopeURL;
this._version = version;
- this._element = createElementWithClass("div", "service-workers-version");
+ this.element.classList.add("service-workers-version", "flex-none");
/**
* @type {!Object.}
@@ -482,7 +401,7 @@ WebInspector.SWVersionElement = function(manager, scopeURL, version)
this._updateVersion(version);
}
-WebInspector.SWVersionElement.prototype = {
+WebInspector.SWVersionWidget.prototype = {
_createElements: function()
{
var panel = createElementWithClass("div", "service-workers-versions-panel");
@@ -500,7 +419,7 @@ WebInspector.SWVersionElement.prototype = {
this._clientsTitle = rightPanel.createChild("div", "service-workers-versions-table-clients-title");
this._clientsTitle.createTextChild(WebInspector.UIString("Controlled clients"));
this._clientsPanel = rightPanel.createChild("div", "service-workers-versions-table-clients-content");
- this._element.appendChild(panel);
+ this.element.appendChild(panel);
},
/**
@@ -516,13 +435,15 @@ WebInspector.SWVersionElement.prototype = {
var runningStatusLeftCell = runningStatusCell.createChild("div", "service-workers-versions-table-running-status-left-cell");
var runningStatusRightCell = runningStatusCell.createChild("div", "service-workers-versions-table-running-status-right-cell");
if (version.isRunning() || version.isStarting()) {
- var stopButton = runningStatusLeftCell.createChild("button", "service-workers-button service-workers-stop-button");
- stopButton.addEventListener("click", this._stopButtonClicked.bind(this, version.id), false);
- stopButton.title = WebInspector.UIString("Stop");
+ var toolbar = new WebInspector.Toolbar("", runningStatusLeftCell);
+ var stopButton = new WebInspector.ToolbarButton(WebInspector.UIString("Stop"), "stop-toolbar-item");
+ stopButton.addEventListener("click", this._stopButtonClicked.bind(this, version.id));
+ toolbar.appendToolbarItem(stopButton);
} else if (version.isStartable()) {
- var startButton = runningStatusLeftCell.createChild("button", "service-workers-button service-workers-start-button");
- startButton.addEventListener("click", this._startButtonClicked.bind(this), false);
- startButton.title = WebInspector.UIString("Start");
+ var toolbar = new WebInspector.Toolbar("", runningStatusLeftCell);
+ var startButton = new WebInspector.ToolbarButton(WebInspector.UIString("Start"), "play-toolbar-item");
+ startButton.addEventListener("click", this._startButtonClicked.bind(this));
+ toolbar.appendToolbarItem(startButton);
}
runningStatusRightCell.setTextAndTitle(version.runningStatus);
if (version.isRunning() || version.isStarting()) {
@@ -627,7 +548,7 @@ WebInspector.SWVersionElement.prototype = {
},
/**
- * @param {!Event} event
+ * @param {!WebInspector.Event} event
*/
_startButtonClicked: function(event)
{
@@ -636,7 +557,7 @@ WebInspector.SWVersionElement.prototype = {
/**
* @param {string} versionId
- * @param {!Event} event
+ * @param {!WebInspector.Event} event
*/
_stopButtonClicked: function(versionId, event)
{
@@ -651,4 +572,6 @@ WebInspector.SWVersionElement.prototype = {
{
this._manager.inspectWorker(versionId);
},
+
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/front_end/resources/module.json b/front_end/resources/module.json
index 29dc86bf50..dc773577fc 100644
--- a/front_end/resources/module.json
+++ b/front_end/resources/module.json
@@ -11,6 +11,12 @@
"type": "@WebInspector.Revealer",
"contextTypes": ["WebInspector.Resource"],
"className": "WebInspector.ResourcesPanel.ResourceRevealer"
+ },
+ {
+ "type": "setting",
+ "settingName": "serviceWorkerUpdateOnReload",
+ "settingType": "boolean",
+ "defaultValue": "false"
}
],
"dependencies": ["source_frame", "ui_lazy", "components_lazy"],
diff --git a/front_end/resources/serviceWorkersView.css b/front_end/resources/serviceWorkersView.css
index c7fa7e58b0..a308604b05 100644
--- a/front_end/resources/serviceWorkersView.css
+++ b/front_end/resources/serviceWorkersView.css
@@ -4,27 +4,25 @@
* found in the LICENSE file.
*/
-.service-workers-view {
- overflow: auto;
-}
-
.service-workers-settings {
border-bottom: 1px solid #e1e1e1;
min-height: 26px;
overflow: hidden;
padding: 5px;
white-space: nowrap;
+ flex: none;
}
.service-workers-root {
margin: 0;
padding: 5px;
-webkit-user-select: text;
+ display: flex;
}
.service-workers-root ol {
list-style-type: none;
- padding-left: 12px;
+ padding-left: 0;
}
.service-workers-origin {
@@ -32,23 +30,23 @@
}
.service-workers-origin-title {
- font-size: 20px;
+ font-size: 17px;
+ flex: none;
}
.service-workers-registration {
- border-right: 1px solid #e1e1e1;
margin-top: 5px;
margin-bottom: 10px;
padding: 0;
+ flex: auto;
}
-.service-workers-registration-header {
- border-left: 1px solid #e1e1e1;
- border-top: 1px solid #e1e1e1;
- display: flex;
- flex-wrap: wrap;
- overflow: hidden;
- position: relative;
+.service-workers-registration .tabbed-pane > .widget {
+ overflow: auto;
+}
+
+.service-workers-registration .toolbar {
+ flex: none;
}
.service-workers-registration-title {
@@ -57,62 +55,10 @@
padding: 4px;
}
-.service-workers-registration-buttons {
- flex: 1 1 0;
- padding: 1px;
-}
-
-.service-workers-registration-content {
- border: 0;
- padding: 0;
-}
-
-.service-workers-versions-mode-tab-list {
- display: flex;
-}
-
-.service-workers-versions-mode-tab {
- border-bottom: 1px solid #e1e1e1;
- border-left: 1px solid #e1e1e1;
- border-top: 1px solid #e1e1e1;
- display: flex;
- flex: 1 1 0;
- flex-wrap: wrap;
- overflow: hidden;
- padding: 3px;
-}
-
-.service-workers-versions-mode-tab-disabled {
- background-color: #eee;
-}
-
-.service-workers-versions-mode-tab-selected {
- border-bottom: 0;
-}
-
-.service-workers-versions-mode-tab-icon {
- height: 16px;
- margin: 1px;
- -webkit-mask-image: url(Images/serviceWorker.svg);
- -webkit-mask-size: 16px 16px;
- width: 16px;
-}
-
-.service-workers-versions-mode-tab-text {
- margin: 2px;
-}
-
-.service-workers-versions-mode-tab-text-disabled {
- color: #888;
-}
-
-.service-workers-versions-mode-tab-text-selected {
- font-weight: bold;
-}
-
.service-workers-versions-panel {
border-bottom: 1px solid #e1e1e1;
border-left: 1px solid #e1e1e1;
+ border-right: 1px solid #e1e1e1;
display: flex;
}
@@ -151,8 +97,12 @@
}
.service-workers-versions-table-messages-content {
- overflow: auto;
padding: 3px 3px 3px 10px;
+ line-height: 22px;
+ max-height: 150px;
+ border-left: 1px solid #eee;
+ overflow: auto;
+ margin-right: 10px;
}
.service-workers-versions-table-clients-title {
@@ -179,63 +129,6 @@
text-decoration: underline;
}
-.service-workers-button {
- -webkit-mask-image: url(Images/toolbarButtonGlyphs.png);
- -webkit-mask-size: 352px 168px;
- background-color: rgba(0, 0, 0, 0.75);
- height: 24px;
- opacity: 0.8;
- width: 32px;
- border: 0;
- padding: 0;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.5) {
-.service-workers-button {
- -webkit-mask-image: url(Images/toolbarButtonGlyphs_2x.png);
-}
-} /* media */
-
-.service-workers-button:hover {
- opacity: 1;
-}
-
-.service-workers-button:active {
- opacity: 0.8;
-}
-
-.service-workers-button:disabled {
- opacity: 0.5;
-}
-
-.service-workers-start-button {
- -webkit-mask-position: -64px -48px;
-}
-
-.service-workers-stop-button {
- -webkit-mask-position: -96px -48px;
-}
-
-.service-workers-delete-button {
- float: right;
- -webkit-mask-position: -128px -24px;
- position: relative;
-}
-
-.service-workers-update-button {
- -webkit-mask-image: url(Images/updateServiceWorker.svg);
- -webkit-mask-position: 7px 3px;
- -webkit-mask-repeat: no-repeat;
- -webkit-mask-size: 18px 18px;
-}
-
-.service-workers-push-button {
- -webkit-mask-image: url(Images/notifications.svg);
- -webkit-mask-position: 7px 3px;
- -webkit-mask-repeat: no-repeat;
- -webkit-mask-size: 18px 18px;
-}
-
.service-workers-versions-option-panel {
border-bottom: 1px solid #e1e1e1;
border-left: 1px solid #e1e1e1;
@@ -246,12 +139,13 @@
display: flex;
}
-.service-workers-error-message {
- font-weight: bold;
+.service-workers-error > label {
+ flex: none;
}
.service-workers-info {
display: flex;
+ align-items: center;
}
.service-worker-client-focus {
@@ -260,43 +154,3 @@
padding-left: 4px;
text-decoration: underline;
}
-
-.service-workers-color-0 {
- background-color: #003366;
-}
-
-.service-workers-color-1 {
- background-color: #663300;
-}
-
-.service-workers-color-2 {
- background-color: #660066;
-}
-
-.service-workers-color-3 {
- background-color: #003300;
-}
-
-.service-workers-color-4 {
- background-color: #993333;
-}
-
-.service-workers-color-5 {
- background-color: #000066;
-}
-
-.service-workers-color-6 {
- background-color: #006666;
-}
-
-.service-workers-color-7 {
- background-color: #996600;
-}
-
-.service-workers-color-8 {
- background-color: #9900CC;
-}
-
-.service-workers-color-9 {
- background-color: #336600;
-}
diff --git a/front_end/sass/SASSProcessor.js b/front_end/sass/SASSProcessor.js
index a747f0c431..62f1dae4c0 100644
--- a/front_end/sass/SASSProcessor.js
+++ b/front_end/sass/SASSProcessor.js
@@ -120,6 +120,8 @@ WebInspector.SASSProcessor.processCSSEdits = function(astService, map, ranges, n
*/
function onCSSParsed(newCSSAST)
{
+ if (newCSSAST.rules.length !== map.compiledModel().rules.length)
+ return Promise.resolve(/** @type {?WebInspector.SourceMap.EditResult} */(null));
//TODO(lushnikov): only diff changed styles.
var cssDiff = WebInspector.SASSSupport.diffModels(map.compiledModel(), newCSSAST);
var edits = WebInspector.SASSProcessor._editsFromCSSDiff(cssDiff, map);
diff --git a/front_end/sass/SASSSupport.js b/front_end/sass/SASSSupport.js
index 92dad21eda..78e67d29d2 100644
--- a/front_end/sass/SASSSupport.js
+++ b/front_end/sass/SASSSupport.js
@@ -80,7 +80,6 @@ WebInspector.SASSSupport.SCSSParserStates = {
*/
WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory)
{
- var lines = document.text.value().split("\n");
var properties = [];
var variables = [];
var mixins = [];
@@ -92,45 +91,50 @@ WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory)
var mixinName, mixinValue;
var UndefTokenType = {};
+ var cursor = new WebInspector.TextCursor(document.text.lineEndings());
+
/**
* @param {string} tokenValue
* @param {?string} tokenTypes
- * @param {number} column
- * @param {number} newColumn
+ * @param {number} startPosition
+ * @param {number} endPosition
*/
- function processToken(tokenValue, tokenTypes, column, newColumn)
+ function processToken(tokenValue, tokenTypes, startPosition, endPosition)
{
+ cursor.advance(startPosition);
+ var startLine = cursor.lineNumber();
+ var startColumn = cursor.columnNumber();
+ cursor.advance(endPosition);
+ var endLine = cursor.lineNumber();
+ var endColumn = cursor.columnNumber();
+
var tokenType = tokenTypes ? tokenTypes.split(" ").keySet() : UndefTokenType;
switch (state) {
case States.Initial:
if (tokenType["css-variable-2"]) {
- variableName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(lineNumber, column, lineNumber, newColumn));
+ variableName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn));
state = States.VariableName;
} else if (tokenType["css-property"] || tokenType["css-meta"]) {
- propertyName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(lineNumber, column, lineNumber, newColumn));
+ propertyName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn));
state = States.PropertyName;
} else if (tokenType["css-def"] && tokenValue === "@include") {
- mixinName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(lineNumber, column, lineNumber, newColumn));
+ mixinName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn));
state = States.MixinName;
} else if (tokenType["css-comment"]) {
// Support only a one-line comments.
- if (tokenValue.substring(0, 2) !== "/*" || tokenValue.substring(tokenValue.length - 2) !== "*/")
+ if (startLine !== endLine || tokenValue.substring(0, 2) !== "/*" || tokenValue.substring(tokenValue.length - 2) !== "*/")
break;
var uncommentedText = tokenValue.substring(2, tokenValue.length - 2);
- var fakeRuleText = "a{\n" + uncommentedText + "}";
+ var fakeRuleText = "a{" + uncommentedText + "}";
var fakeDocument = new WebInspector.SASSSupport.ASTDocument("", new WebInspector.Text(fakeRuleText));
var result = WebInspector.SASSSupport._innerParseSCSS(fakeDocument, tokenizerFactory);
if (result.properties.length === 1 && result.variables.length === 0 && result.mixins.length === 0) {
var disabledProperty = result.properties[0];
- // We should offset property to current coordinates.
- var offset = column + 2;
- var nameRange = new WebInspector.TextRange(lineNumber, disabledProperty.name.range.startColumn + offset,
- lineNumber, disabledProperty.name.range.endColumn + offset);
- var valueRange = new WebInspector.TextRange(lineNumber, disabledProperty.value.range.startColumn + offset,
- lineNumber, disabledProperty.value.range.endColumn + offset);
+ var nameRange = rebaseInsideOneLineComment(disabledProperty.name.range, startLine, startColumn);
+ var valueRange = rebaseInsideOneLineComment(disabledProperty.value.range, startLine, startColumn);
var name = new WebInspector.SASSSupport.TextNode(document, disabledProperty.name.text, nameRange);
var value = new WebInspector.SASSSupport.TextNode(document, disabledProperty.value.text, valueRange);
- var range = new WebInspector.TextRange(lineNumber, column, lineNumber, newColumn);
+ var range = new WebInspector.TextRange(startLine, startColumn, startLine, endColumn);
var property = new WebInspector.SASSSupport.Property(document, name, value, range, true);
properties.push(property);
}
@@ -145,18 +149,18 @@ WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory)
state = States.Initial;
} else if (tokenValue === ":" && tokenType === UndefTokenType) {
state = States.VariableValue;
- variableValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(lineNumber, newColumn));
+ variableValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(startLine, endColumn));
} else if (tokenType !== UndefTokenType) {
state = States.Initial;
}
break;
case States.VariableValue:
if (tokenValue === ";" && tokenType === UndefTokenType) {
- variableValue.range.endLine = lineNumber;
- variableValue.range.endColumn = column;
+ variableValue.range.endLine = startLine;
+ variableValue.range.endColumn = startColumn;
var variable = new WebInspector.SASSSupport.Property(document, variableName, variableValue, variableName.range.clone(), false);
- variable.range.endLine = lineNumber;
- variable.range.endColumn = newColumn;
+ variable.range.endLine = startLine;
+ variable.range.endColumn = endColumn;
variables.push(variable);
state = States.Initial;
} else {
@@ -164,22 +168,26 @@ WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory)
}
break;
case States.PropertyName:
- if (tokenValue === ":" && tokenType === UndefTokenType) {
+ if (tokenValue === "{" && tokenType === UndefTokenType) {
+ state = States.Initial;
+ } else if (tokenValue === ":" && tokenType === UndefTokenType) {
state = States.PropertyValue;
- propertyName.range.endLine = lineNumber;
- propertyName.range.endColumn = column;
- propertyValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(lineNumber, newColumn));
+ propertyName.range.endLine = startLine;
+ propertyName.range.endColumn = startColumn;
+ propertyValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(startLine, endColumn));
} else if (tokenType["css-property"]) {
propertyName.text += tokenValue;
}
break;
case States.PropertyValue:
- if ((tokenValue === "}" || tokenValue === ";") && tokenType === UndefTokenType) {
- propertyValue.range.endLine = lineNumber;
- propertyValue.range.endColumn = column;
+ if (tokenValue === "{" && tokenType === UndefTokenType) {
+ state = States.Initial;
+ } else if ((tokenValue === "}" || tokenValue === ";") && tokenType === UndefTokenType) {
+ propertyValue.range.endLine = startLine;
+ propertyValue.range.endColumn = startColumn;
var property = new WebInspector.SASSSupport.Property(document, propertyName, propertyValue, propertyName.range.clone(), false);
- property.range.endLine = lineNumber;
- property.range.endColumn = newColumn;
+ property.range.endLine = startLine;
+ property.range.endColumn = endColumn;
properties.push(property);
state = States.Initial;
} else {
@@ -189,9 +197,9 @@ WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory)
case States.MixinName:
if (tokenValue === "(" && tokenType === UndefTokenType) {
state = States.MixinValue;
- mixinName.range.endLine = lineNumber;
- mixinName.range.endColumn = column;
- mixinValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(lineNumber, newColumn));
+ mixinName.range.endLine = startLine;
+ mixinName.range.endColumn = startColumn;
+ mixinValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(startLine, endColumn));
} else if (tokenValue === ";" && tokenType === UndefTokenType) {
state = States.Initial;
mixinValue = null;
@@ -201,11 +209,11 @@ WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory)
break;
case States.MixinValue:
if (tokenValue === ")" && tokenType === UndefTokenType) {
- mixinValue.range.endLine = lineNumber;
- mixinValue.range.endColumn = column;
+ mixinValue.range.endLine = startLine;
+ mixinValue.range.endColumn = startColumn;
var mixin = new WebInspector.SASSSupport.Property(document, mixinName, /** @type {!WebInspector.SASSSupport.TextNode} */(mixinValue), mixinName.range.clone(), false);
- mixin.range.endLine = lineNumber;
- mixin.range.endColumn = newColumn;
+ mixin.range.endLine = startLine;
+ mixin.range.endColumn = endColumn;
mixins.push(mixin);
state = States.Initial;
} else {
@@ -221,17 +229,24 @@ WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory)
}
}
var tokenizer = tokenizerFactory.createTokenizer("text/x-scss");
- var lineNumber;
- for (lineNumber = 0; lineNumber < lines.length; ++lineNumber) {
- var line = lines[lineNumber];
- tokenizer(line, processToken);
- processToken("\n", null, line.length, line.length + 1);
- }
+ tokenizer(document.text.value(), processToken);
+
return {
variables: variables,
properties: properties,
mixins: mixins
};
+
+ /**
+ * @param {!WebInspector.TextRange} range
+ * @param {number} startLine
+ * @param {number} startColumn
+ * @return {!WebInspector.TextRange}
+ */
+ function rebaseInsideOneLineComment(range, startLine, startColumn)
+ {
+ return new WebInspector.TextRange(range.startLine + startLine, range.startColumn + startColumn, range.endLine + startLine, range.endColumn + startColumn);
+ }
}
/**
diff --git a/front_end/sass/module.json b/front_end/sass/module.json
index dc9deb47ad..b4983d27b6 100644
--- a/front_end/sass/module.json
+++ b/front_end/sass/module.json
@@ -6,5 +6,15 @@
"SASSProcessor.js",
"ASTSourceMap.js",
"SASSSourceMapFactory.js"
+ ],
+ "extensions": [
+ {
+ "type": "@WebInspector.SourceMapFactory",
+ "className": "WebInspector.SASSSourceMapFactory",
+ "experiment": "liveSASS",
+ "extensions": [
+ "scss"
+ ]
+ }
]
}
diff --git a/front_end/screencast/ScreencastApp.js b/front_end/screencast/ScreencastApp.js
index b3f22741a3..8eb98047f4 100644
--- a/front_end/screencast/ScreencastApp.js
+++ b/front_end/screencast/ScreencastApp.js
@@ -90,12 +90,6 @@ WebInspector.ScreencastApp.prototype = {
this._rootSplitWidget.showBoth();
else
this._rootSplitWidget.hideMain();
- },
-
- _requestAppBanner: function()
- {
- if (this._target && this._target.pageAgent())
- this._target.pageAgent().requestAppBanner();
}
};
@@ -132,33 +126,6 @@ WebInspector.ScreencastApp.ToolbarButtonProvider.prototype = {
}
}
-
-/**
- * @constructor
- * @implements {WebInspector.ActionDelegate}
- */
-WebInspector.ScreencastApp.ActionDelegate = function()
-{
-};
-
-WebInspector.ScreencastApp.ActionDelegate.prototype = {
- /**
- * @override
- * @param {!WebInspector.Context} context
- * @param {string} actionId
- * @return {boolean}
- */
- handleAction: function(context, actionId)
- {
- if (actionId === "screencast.request-app-banner") {
- WebInspector.ScreencastApp._instance()._requestAppBanner()
- return true;
- }
- return false;
- }
-};
-
-
/**
* @constructor
* @implements {WebInspector.AppProvider}
diff --git a/front_end/screencast/module.json b/front_end/screencast/module.json
index 0f9edda280..64f46d99e7 100644
--- a/front_end/screencast/module.json
+++ b/front_end/screencast/module.json
@@ -11,19 +11,12 @@
"order": 1,
"location": "main-toolbar-left"
},
- {
- "type": "@WebInspector.ActionDelegate",
- "actionId": "screencast.request-app-banner",
- "className": "WebInspector.ScreencastApp.ActionDelegate",
- "title": "Request app banner\u2026"
- },
{
"type": "context-menu-item",
"condition": "remoteFrontend",
"location": "mainMenu/tools",
- "experiment": "appBanner",
"order": 10,
- "actionId": "screencast.request-app-banner"
+ "actionId": "components.request-app-banner"
}
],
"dependencies": [
diff --git a/front_end/sdk/CSSModel.js b/front_end/sdk/CSSModel.js
index f1860be784..1cd81314e0 100644
--- a/front_end/sdk/CSSModel.js
+++ b/front_end/sdk/CSSModel.js
@@ -47,8 +47,9 @@ WebInspector.CSSModel = function(target)
/** @type {!Map.>>} */
this._styleSheetIdsForURL = new Map();
- /** @type {!Map} */
- this._sourceMapLoadingPromises = new Map();
+ /** @type {!Multimap} */
+ this._sourceMapLoadingStyleSheetsIds = new Multimap();
+
/** @type {!Map} */
this._sourceMapByURL = new Map();
/** @type {!Multimap} */
@@ -65,7 +66,8 @@ WebInspector.CSSModel.Events = {
StyleSheetChanged: "StyleSheetChanged",
StyleSheetRemoved: "StyleSheetRemoved",
SourceMapAttached: "SourceMapAttached",
- SourceMapDetached: "SourceMapDetached"
+ SourceMapDetached: "SourceMapDetached",
+ SourceMapChanged: "SourceMapChanged"
}
WebInspector.CSSModel.MediaTypes = ["all", "braille", "embossed", "handheld", "print", "projection", "screen", "speech", "tty", "tv"];
@@ -99,7 +101,7 @@ WebInspector.CSSModel.prototype = {
if (enabled)
this._attachSourceMap(header);
else
- this._detachSourceMap(header.sourceMapURL, header);
+ this._detachSourceMap(header);
}
},
@@ -112,6 +114,17 @@ WebInspector.CSSModel.prototype = {
return this._sourceMapByURL.get(header.sourceMapURL) || null;
},
+ _sourceMapLoadedForTest: function() { },
+
+ /**
+ * @param {!WebInspector.SourceMap} sourceMap
+ * @return {!Array}
+ */
+ headersForSourceMap: function(sourceMap)
+ {
+ return this._sourceMapURLToHeaders.get(sourceMap.url()).valuesArray();
+ },
+
/**
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
@@ -120,45 +133,104 @@ WebInspector.CSSModel.prototype = {
var sourceMapURL = header.sourceMapURL;
if (!sourceMapURL || !WebInspector.moduleSetting("cssSourceMapsEnabled").get())
return;
- this._sourceMapURLToHeaders.set(sourceMapURL, header);
if (this._sourceMapByURL.has(sourceMapURL)) {
- this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapAttached, header);
+ attach.call(this, sourceMapURL, header);
return;
}
- if (this._sourceMapLoadingPromises.has(sourceMapURL))
- return;
- var loadingPromise = WebInspector.TextSourceMap.load(sourceMapURL, header.sourceURL)
- .then(onSourceMapLoaded.bind(this, sourceMapURL));
- this._sourceMapLoadingPromises.set(sourceMapURL, loadingPromise);
+ if (!this._sourceMapLoadingStyleSheetsIds.has(sourceMapURL)) {
+ WebInspector.TextSourceMap.load(sourceMapURL, header.sourceURL)
+ .then(onTextSourceMapLoaded.bind(this, sourceMapURL))
+ .then(onSourceMap.bind(this, sourceMapURL));
+ }
+ this._sourceMapLoadingStyleSheetsIds.set(sourceMapURL, header.id);
/**
* @param {string} sourceMapURL
* @param {?WebInspector.TextSourceMap} sourceMap
+ * @return {!Promise}
* @this {WebInspector.CSSModel}
*/
- function onSourceMapLoaded(sourceMapURL, sourceMap)
+ function onTextSourceMapLoaded(sourceMapURL, sourceMap)
{
- this._sourceMapLoadingPromises.delete(sourceMapURL);
- var headers = this._sourceMapURLToHeaders.get(sourceMapURL);
- if (!headers || !sourceMap)
+ if (!sourceMap)
+ return Promise.resolve(/** @type {?WebInspector.SourceMap} */(null));
+ var factoryExtension = this._factoryForSourceMap(sourceMap);
+ if (!factoryExtension)
+ return Promise.resolve(/** @type {?WebInspector.SourceMap} */(sourceMap));
+
+ return factoryExtension.instancePromise()
+ .then(factory => factory.editableSourceMap(this.target(), sourceMap))
+ .then(map => map || sourceMap)
+ .catchException(/** @type {?WebInspector.SourceMap} */(null));
+ }
+
+ /**
+ * @param {string} sourceMapURL
+ * @param {?WebInspector.SourceMap} sourceMap
+ * @this {WebInspector.CSSModel}
+ */
+ function onSourceMap(sourceMapURL, sourceMap)
+ {
+ this._sourceMapLoadedForTest();
+ var styleSheetIds = this._sourceMapLoadingStyleSheetsIds.get(sourceMapURL);
+ this._sourceMapLoadingStyleSheetsIds.removeAll(sourceMapURL);
+ if (!sourceMap)
return;
+ var headers = new Set();
+ for (var styleSheetId of styleSheetIds) {
+ var header = this.styleSheetHeaderForId(styleSheetId);
+ if (header)
+ headers.add(header);
+ }
+ if (!headers.size)
+ return;
+ if (sourceMap.editable())
+ WebInspector.console.log(WebInspector.UIString("LiveSASS started: %s", sourceMapURL));
this._sourceMapByURL.set(sourceMapURL, sourceMap);
for (var header of headers)
- this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapAttached, header);
+ attach.call(this, sourceMapURL, header);
}
+
+ /**
+ * @param {string} sourceMapURL
+ * @param {!WebInspector.CSSStyleSheetHeader} header
+ * @this {WebInspector.CSSModel}
+ */
+ function attach(sourceMapURL, header)
+ {
+ this._sourceMapURLToHeaders.set(sourceMapURL, header);
+ this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapAttached, header);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.SourceMap} sourceMap
+ * @return {?Runtime.Extension}
+ */
+ _factoryForSourceMap: function(sourceMap)
+ {
+ var sourceExtensions = new Set(sourceMap.sourceURLs().map(url => WebInspector.TextUtils.extension(url)));
+ for (var runtimeExtension of self.runtime.extensions(WebInspector.SourceMapFactory)) {
+ var supportedExtensions = new Set(runtimeExtension.descriptor()["extensions"]);
+ if (supportedExtensions.containsAll(sourceExtensions))
+ return runtimeExtension;
+ }
+ return null;
},
/**
- * @param {?string} sourceMapURL
* @param {!WebInspector.CSSStyleSheetHeader} header
*/
- _detachSourceMap: function(sourceMapURL, header)
+ _detachSourceMap: function(header)
{
- if (!sourceMapURL)
+ if (!header.sourceMapURL || !this._sourceMapURLToHeaders.hasValue(header.sourceMapURL, header))
return;
- this._sourceMapURLToHeaders.remove(sourceMapURL, header);
- if (!this._sourceMapURLToHeaders.has(sourceMapURL))
- this._sourceMapByURL.delete(sourceMapURL);
+ this._sourceMapURLToHeaders.remove(header.sourceMapURL, header);
+ if (!this._sourceMapURLToHeaders.has(header.sourceMapURL))
+ var sourceMap = this._sourceMapByURL.get(header.sourceMapURL);
+ if (sourceMap.editable())
+ WebInspector.console.log(WebInspector.UIString("LiveSASS stopped: %s", header.sourceMapURL));
+ this._sourceMapByURL.delete(header.sourceMapURL);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapDetached, header);
},
@@ -170,6 +242,119 @@ WebInspector.CSSModel.prototype = {
return /** @type {!WebInspector.DOMModel} */(this._domModel);
},
+ /**
+ * @param {!CSSAgent.StyleSheetId} styleSheetId
+ * @param {!WebInspector.TextRange} range
+ * @param {string} text
+ * @param {boolean} majorChange
+ * @return {!Promise}
+ */
+ setStyleText: function(styleSheetId, range, text, majorChange)
+ {
+ var original = this._innerSetStyleTexts.bind(this, [styleSheetId], [range], [text], majorChange);
+ var header = this.styleSheetHeaderForId(styleSheetId);
+ if (!header)
+ return original();
+
+ var sourceMap = this.sourceMapForHeader(header);
+ if (!sourceMap)
+ return original();
+
+ var originalAndDetach = originalAndDetachIfSuccess.bind(this, header);
+
+ if (!sourceMap.editable())
+ return originalAndDetach();
+
+ return /** @type {!Promise} */(sourceMap.editCompiled([range], [text])
+ .then(onEditingDone.bind(this))
+ .catch(onError.bind(this, header)));
+
+ /**
+ * @param {?WebInspector.SourceMap.EditResult} editResult
+ * @return {!Promise}
+ * @this {WebInspector.CSSModel}
+ */
+ function onEditingDone(editResult)
+ {
+ if (!editResult)
+ return originalAndDetach();
+
+ var edits = editResult.compiledEdits;
+ if (!edits.length)
+ return onCSSPatched.call(this, editResult, true);
+
+ edits.sort(WebInspector.SourceEdit.comparator);
+ edits = edits.reverse();
+
+ var styleSheetIds = [];
+ var ranges = [];
+ var texts = [];
+ for (var edit of edits) {
+ styleSheetIds.push(header.id);
+ ranges.push(edit.oldRange);
+ texts.push(edit.newText);
+ }
+ return this._innerSetStyleTexts(styleSheetIds, ranges, texts, majorChange)
+ .then(onCSSPatched.bind(this, editResult));
+ }
+
+ /**
+ * @param {!WebInspector.SourceMap.EditResult} editResult
+ * @param {boolean} success
+ * @return {!Promise}
+ * @this {WebInspector.CSSModel}
+ */
+ function onCSSPatched(editResult, success)
+ {
+ if (!success)
+ return originalAndDetach();
+
+ this._sourceMapByURL.set(header.sourceMapURL, editResult.map);
+ this.dispatchEventToListeners(WebInspector.CSSModel.Events.SourceMapChanged, {
+ sourceMap: editResult.map,
+ newSources: editResult.newSources
+ });
+ return Promise.resolve(true);
+ }
+
+ /**
+ * @param {!WebInspector.CSSStyleSheetHeader} header
+ * @param {*} error
+ * @return {!Promise}
+ * @this {WebInspector.CSSModel}
+ */
+ function onError(header, error)
+ {
+ WebInspector.console.error(WebInspector.UIString("LiveSASS failed: %s", sourceMap.compiledURL()));
+ console.error(error);
+ this._detachSourceMap(header);
+ return original();
+ }
+
+ /**
+ * @param {!WebInspector.CSSStyleSheetHeader} header
+ * @return {!Promise}
+ * @this {WebInspector.CSSModel}
+ */
+ function originalAndDetachIfSuccess(header)
+ {
+ return this._innerSetStyleTexts([styleSheetId], [range], [text], majorChange)
+ .then(detachIfSuccess.bind(this));
+
+ /**
+ * @param {boolean} success
+ * @return {boolean}
+ * @this {WebInspector.CSSModel}
+ */
+ function detachIfSuccess(success)
+ {
+ if (success)
+ this._detachSourceMap(header);
+ return success;
+ }
+ }
+ },
+
/**
* @param {!Array} styleSheetIds
* @param {!Array} ranges
@@ -177,7 +362,7 @@ WebInspector.CSSModel.prototype = {
* @param {boolean} majorChange
* @return {!Promise}
*/
- setStyleTexts: function(styleSheetIds, ranges, texts, majorChange)
+ _innerSetStyleTexts: function(styleSheetIds, ranges, texts, majorChange)
{
/**
* @param {?Protocol.Error} error
@@ -233,7 +418,7 @@ WebInspector.CSSModel.prototype = {
return false;
this._domModel.markUndoableState();
var edit = new WebInspector.CSSModel.Edit(styleSheetId, range, text, selectorPayload);
- this._fireStyleSheetChanged(styleSheetId, edit);
+ this._fireStyleSheetChangedAndDetach(styleSheetId, edit);
return true;
}
@@ -262,7 +447,7 @@ WebInspector.CSSModel.prototype = {
return false;
this._domModel.markUndoableState();
var edit = new WebInspector.CSSModel.Edit(styleSheetId, range, text, payload);
- this._fireStyleSheetChanged(styleSheetId, edit);
+ this._fireStyleSheetChangedAndDetach(styleSheetId, edit);
return true;
}
@@ -494,7 +679,7 @@ WebInspector.CSSModel.prototype = {
return false;
this._domModel.markUndoableState();
var edit = new WebInspector.CSSModel.Edit(media.parentStyleSheetId, media.range, newMediaText, mediaPayload);
- this._fireStyleSheetChanged(media.parentStyleSheetId, edit);
+ this._fireStyleSheetChangedAndDetach(media.parentStyleSheetId, edit);
return true;
}
@@ -528,7 +713,7 @@ WebInspector.CSSModel.prototype = {
return null;
this._domModel.markUndoableState();
var edit = new WebInspector.CSSModel.Edit(styleSheetId, ruleLocation, ruleText, rulePayload);
- this._fireStyleSheetChanged(styleSheetId, edit);
+ this._fireStyleSheetChangedAndDetach(styleSheetId, edit);
return new WebInspector.CSSStyleRule(this, rulePayload);
}
},
@@ -593,10 +778,19 @@ WebInspector.CSSModel.prototype = {
*/
_fireStyleSheetChanged: function(styleSheetId, edit)
{
+ this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, edit: edit });
+ },
+
+ /**
+ * @param {!CSSAgent.StyleSheetId} styleSheetId
+ * @param {!WebInspector.CSSModel.Edit=} edit
+ */
+ _fireStyleSheetChangedAndDetach: function(styleSheetId, edit)
+ {
+ this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, edit: edit });
var header = this.styleSheetHeaderForId(styleSheetId);
if (header)
- this._detachSourceMap(header.sourceMapURL, header);
- this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, edit: edit });
+ this._detachSourceMap(header);
},
/**
@@ -640,7 +834,7 @@ WebInspector.CSSModel.prototype = {
if (!Object.keys(frameIdToStyleSheetIds).length)
this._styleSheetIdsForURL.remove(url);
}
- this._detachSourceMap(header.sourceMapURL, header);
+ this._detachSourceMap(header);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetRemoved, header);
},
@@ -668,7 +862,7 @@ WebInspector.CSSModel.prototype = {
*/
setStyleSheetText: function(styleSheetId, newText, majorChange)
{
- var header = this._styleSheetIdToHeader.get(styleSheetId);
+ var header = /** @type {!WebInspector.CSSStyleSheetHeader} */(this._styleSheetIdToHeader.get(styleSheetId));
console.assert(header);
newText = WebInspector.CSSModel.trimSourceURL(newText);
if (header.hasSourceURL)
@@ -683,12 +877,9 @@ WebInspector.CSSModel.prototype = {
*/
function callback(error, sourceMapURL)
{
- var oldSourceMapURL = header.sourceMapURL;
+ this._detachSourceMap(header);
header.setSourceMapURL(sourceMapURL);
- if (oldSourceMapURL !== header.sourceMapURL) {
- this._detachSourceMap(oldSourceMapURL, header);
- this._attachSourceMap(header);
- }
+ this._attachSourceMap(header);
if (error)
return error;
if (majorChange)
@@ -734,12 +925,12 @@ WebInspector.CSSModel.prototype = {
this._styleSheetIdsForURL.clear();
this._styleSheetIdToHeader.clear();
for (var i = 0; i < headers.length; ++i) {
- this._detachSourceMap(headers[i].sourceMapURL, headers[i]);
+ this._detachSourceMap(headers[i]);
this.dispatchEventToListeners(WebInspector.CSSModel.Events.StyleSheetRemoved, headers[i]);
}
this._sourceMapByURL.clear();
this._sourceMapURLToHeaders.clear();
- this._sourceMapLoadingPromises.clear();
+ this._sourceMapLoadingStyleSheetsIds.clear();
},
/**
@@ -868,7 +1059,7 @@ WebInspector.CSSDispatcher.prototype = {
*/
styleSheetChanged: function(styleSheetId)
{
- this._cssModel._fireStyleSheetChanged(styleSheetId);
+ this._cssModel._fireStyleSheetChangedAndDetach(styleSheetId);
},
/**
diff --git a/front_end/sdk/CSSStyleDeclaration.js b/front_end/sdk/CSSStyleDeclaration.js
index c92a61a4b4..f2d3cc72d1 100644
--- a/front_end/sdk/CSSStyleDeclaration.js
+++ b/front_end/sdk/CSSStyleDeclaration.js
@@ -286,7 +286,7 @@ WebInspector.CSSStyleDeclaration.prototype = {
*/
setText: function(text, majorChange)
{
- return this._cssModel.setStyleTexts([this.styleSheetId], [this.range], [text], majorChange)
+ return this._cssModel.setStyleText(this.styleSheetId, this.range, text, majorChange)
},
/**
diff --git a/front_end/sdk/DebuggerModel.js b/front_end/sdk/DebuggerModel.js
index 3c65ab385b..491729eacb 100644
--- a/front_end/sdk/DebuggerModel.js
+++ b/front_end/sdk/DebuggerModel.js
@@ -89,8 +89,7 @@ WebInspector.DebuggerModel.Events = {
FailedToParseScriptSource: "FailedToParseScriptSource",
GlobalObjectCleared: "GlobalObjectCleared",
CallFrameSelected: "CallFrameSelected",
- ConsoleCommandEvaluatedInSelectedCallFrame: "ConsoleCommandEvaluatedInSelectedCallFrame",
- PromiseUpdated: "PromiseUpdated",
+ ConsoleCommandEvaluatedInSelectedCallFrame: "ConsoleCommandEvaluatedInSelectedCallFrame"
}
/** @enum {string} */
@@ -351,43 +350,6 @@ WebInspector.DebuggerModel.prototype = {
}
},
- /**
- * @param {boolean} captureStacks
- */
- enablePromiseTracker: function(captureStacks)
- {
- this._agent.enablePromiseTracker(captureStacks);
- },
-
- disablePromiseTracker: function()
- {
- this._agent.disablePromiseTracker();
- },
-
- /**
- * @param {number} promiseId
- * @param {string=} objectGroup
- * @param {function(?RuntimeAgent.RemoteObject)=} callback
- */
- getPromiseById: function(promiseId, objectGroup, callback)
- {
- this._agent.getPromiseById(promiseId, objectGroup, innerCallback);
-
- /**
- * @param {?Protocol.Error} error
- * @param {?RuntimeAgent.RemoteObject} promise
- */
- function innerCallback(error, promise)
- {
- if (error) {
- console.error(error);
- callback(null);
- return;
- }
- callback(promise);
- }
- },
-
flushAsyncOperationEvents: function()
{
this._agent.flushAsyncOperationEvents();
@@ -426,15 +388,6 @@ WebInspector.DebuggerModel.prototype = {
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.GlobalObjectCleared);
},
- /**
- * @param {string} eventType
- * @param {!DebuggerAgent.PromiseDetails} promise
- */
- _promiseUpdated: function(eventType, promise)
- {
- this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.PromiseUpdated, { eventType: eventType, promise: promise });
- },
-
/**
* @param {!DebuggerAgent.AsyncOperation} operation
*/
@@ -1023,16 +976,6 @@ WebInspector.DebuggerDispatcher.prototype = {
this._debuggerModel._breakpointResolved(breakpointId, location);
},
- /**
- * @override
- * @param {string} eventType
- * @param {!DebuggerAgent.PromiseDetails} promise
- */
- promiseUpdated: function(eventType, promise)
- {
- this._debuggerModel._promiseUpdated(eventType, promise);
- },
-
/**
* @override
* @param {!DebuggerAgent.AsyncOperation} operation
diff --git a/front_end/sdk/HAREntry.js b/front_end/sdk/HAREntry.js
index ce3591f89d..ec7d526f14 100644
--- a/front_end/sdk/HAREntry.js
+++ b/front_end/sdk/HAREntry.js
@@ -49,13 +49,19 @@ WebInspector.HAREntry.prototype = {
*/
build: function()
{
+ var ipAddress = this._request.remoteAddress();
+ var portPositionInString = ipAddress.lastIndexOf(":");
+ if (portPositionInString !== -1)
+ ipAddress = ipAddress.substr(0, portPositionInString);
+
var entry = {
startedDateTime: WebInspector.HARLog.pseudoWallTime(this._request, this._request.startTime),
time: this._request.timing ? WebInspector.HAREntry._toMilliseconds(this._request.duration) : 0,
request: this._buildRequest(),
response: this._buildResponse(),
cache: { }, // Not supported yet.
- timings: this._buildTimings()
+ timings: this._buildTimings(),
+ serverIPAddress: ipAddress
};
if (this._request.connectionId !== "0")
diff --git a/front_end/sdk/NetworkManager.js b/front_end/sdk/NetworkManager.js
index 45986d2318..55b3b748b8 100644
--- a/front_end/sdk/NetworkManager.js
+++ b/front_end/sdk/NetworkManager.js
@@ -80,6 +80,8 @@ WebInspector.NetworkManager._MIMETypes = {
WebInspector.NetworkManager.Conditions;
/** @type {!WebInspector.NetworkManager.Conditions} */
WebInspector.NetworkManager.NoThrottlingConditions = {title: WebInspector.UIString("No throttling"), download: -1, upload: -1, latency: 0};
+/** @type {!WebInspector.NetworkManager.Conditions} */
+WebInspector.NetworkManager.OfflineConditions = {title: WebInspector.UIString("Offline"), download: 0, upload: 0, latency: 0};
WebInspector.NetworkManager.prototype = {
/**
diff --git a/front_end/source_frame/SourceFrame.js b/front_end/source_frame/SourceFrame.js
index f59378c3b8..8b4417bceb 100644
--- a/front_end/source_frame/SourceFrame.js
+++ b/front_end/source_frame/SourceFrame.js
@@ -29,8 +29,9 @@
*/
/**
- * @extends {WebInspector.VBoxWithToolbarItems}
* @constructor
+ * @extends {WebInspector.VBoxWithToolbarItems}
+ * @implements {WebInspector.Searchable}
* @implements {WebInspector.Replaceable}
* @param {!WebInspector.ContentProvider} contentProvider
*/
@@ -54,6 +55,11 @@ WebInspector.SourceFrame = function(contentProvider)
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
this._sourcePosition = new WebInspector.ToolbarText();
+
+ /**
+ * @type {?WebInspector.SearchableView}
+ */
+ this._searchableView = null;
}
WebInspector.SourceFrame.Events = {
@@ -230,8 +236,8 @@ WebInspector.SourceFrame.prototype = {
*/
onTextChanged: function(oldRange, newRange)
{
- if (this._searchResultsChangedCallback)
- this._searchResultsChangedCallback();
+ if (this._searchConfig && this._searchableView)
+ this.performSearch(this._searchConfig, false, false);
},
/**
@@ -299,13 +305,20 @@ WebInspector.SourceFrame.prototype = {
onTextEditorContentLoaded: function() {},
+ /**
+ * @param {?WebInspector.SearchableView} view
+ */
+ setSearchableView: function(view)
+ {
+ this._searchableView = view;
+ },
+
/**
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
* @param {boolean} jumpBackwards
- * @param {function(!WebInspector.Widget, number)} searchFinishedCallback
*/
- _doFindSearchMatches: function(searchConfig, shouldJump, jumpBackwards, searchFinishedCallback)
+ _doFindSearchMatches: function(searchConfig, shouldJump, jumpBackwards)
{
this._currentSearchResultIndex = -1;
this._searchResults = [];
@@ -313,7 +326,10 @@ WebInspector.SourceFrame.prototype = {
var regex = searchConfig.toSearchRegex();
this._searchRegex = regex;
this._searchResults = this._collectRegexMatches(regex);
- searchFinishedCallback(this, this._searchResults.length);
+
+ if (this._searchableView)
+ this._searchableView.updateSearchMatchesCount(this._searchResults.length);
+
if (!this._searchResults.length)
this._textEditor.cancelSearchResultsHighlight();
else if (shouldJump && jumpBackwards)
@@ -325,23 +341,22 @@ WebInspector.SourceFrame.prototype = {
},
/**
+ * @override
* @param {!WebInspector.SearchableView.SearchConfig} searchConfig
* @param {boolean} shouldJump
- * @param {boolean} jumpBackwards
- * @param {function(!WebInspector.Widget, number)} searchFinishedCallback
- * @param {function(number)} currentMatchChangedCallback
- * @param {function()} searchResultsChangedCallback
+ * @param {boolean=} jumpBackwards
*/
- performSearch: function(searchConfig, shouldJump, jumpBackwards, searchFinishedCallback, currentMatchChangedCallback, searchResultsChangedCallback)
+ performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
+ if (this._searchableView)
+ this._searchableView.updateSearchMatchesCount(0);
+
this._resetSearch();
- this._currentSearchMatchChangedCallback = currentMatchChangedCallback;
- this._searchResultsChangedCallback = searchResultsChangedCallback;
- var searchFunction = this._doFindSearchMatches.bind(this, searchConfig, shouldJump, jumpBackwards, searchFinishedCallback);
+ this._searchConfig = searchConfig;
if (this.loaded)
- searchFunction.call(this);
+ this._doFindSearchMatches(searchConfig, shouldJump, !!jumpBackwards)
else
- this._delayedFindSearchMatches = searchFunction;
+ this._delayedFindSearchMatches = this._doFindSearchMatches.bind(this, searchConfig, shouldJump, !!jumpBackwards);
this._ensureContentLoaded();
},
@@ -356,21 +371,23 @@ WebInspector.SourceFrame.prototype = {
if (!this._searchResults.length)
return;
this._currentSearchResultIndex = -1;
- if (this._currentSearchMatchChangedCallback)
- this._currentSearchMatchChangedCallback(this._currentSearchResultIndex);
+ if (this._searchableView)
+ this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
this._textEditor.highlightSearchResults(this._searchRegex, null);
},
_resetSearch: function()
{
+ delete this._searchConfig;
delete this._delayedFindSearchMatches;
- delete this._currentSearchMatchChangedCallback;
- delete this._searchResultsChangedCallback;
this._currentSearchResultIndex = -1;
this._searchResults = [];
delete this._searchRegex;
},
+ /**
+ * @override
+ */
searchCanceled: function()
{
var range = this._currentSearchResultIndex !== -1 ? this._searchResults[this._currentSearchResultIndex] : null;
@@ -408,6 +425,9 @@ WebInspector.SourceFrame.prototype = {
return this._searchResults.lowerBound(this._textEditor.selection().collapseToEnd(), WebInspector.TextRange.comparator);
},
+ /**
+ * @override
+ */
jumpToNextSearchResult: function()
{
var currentIndex = this._searchResultIndexForCurrentSelection();
@@ -415,12 +435,33 @@ WebInspector.SourceFrame.prototype = {
this.jumpToSearchResult(nextIndex);
},
+ /**
+ * @override
+ */
jumpToPreviousSearchResult: function()
{
var currentIndex = this._searchResultIndexForCurrentSelection();
this.jumpToSearchResult(currentIndex - 1);
},
+ /**
+ * @override
+ * @return {boolean}
+ */
+ supportsCaseSensitiveSearch: function ()
+ {
+ return true;
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ supportsRegexSearch: function()
+ {
+ return true;
+ },
+
get currentSearchResultIndex()
{
return this._currentSearchResultIndex;
@@ -431,8 +472,8 @@ WebInspector.SourceFrame.prototype = {
if (!this.loaded || !this._searchResults.length)
return;
this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
- if (this._currentSearchMatchChangedCallback)
- this._currentSearchMatchChangedCallback(this._currentSearchResultIndex);
+ if (this._searchableView)
+ this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
this._textEditor.highlightSearchResults(this._searchRegex, this._searchResults[this._currentSearchResultIndex]);
},
diff --git a/front_end/source_frame/TextEditorAutocompleteController.js b/front_end/source_frame/TextEditorAutocompleteController.js
index fc755380a3..3c96b052fb 100644
--- a/front_end/source_frame/TextEditorAutocompleteController.js
+++ b/front_end/source_frame/TextEditorAutocompleteController.js
@@ -138,7 +138,7 @@ WebInspector.TextEditorAutocompleteController.prototype = {
this._prefixRange = prefixRange;
if (!oldPrefixRange || prefixRange.startLine !== oldPrefixRange.startLine || prefixRange.startColumn !== oldPrefixRange.startColumn)
this._updateAnchorBox();
- this._suggestBox.updateSuggestions(this._anchorBox, wordsWithPrefix, 0, true, this._textEditor.copyRange(prefixRange));
+ this._suggestBox.updateSuggestions(this._anchorBox, wordsWithPrefix.map(item => ({title: item})), 0, true, this._textEditor.copyRange(prefixRange));
if (!this._suggestBox.visible())
this.finishAutocomplete();
this._onSuggestionsShownForTest(wordsWithPrefix);
diff --git a/front_end/sources/CallStackSidebarPane.js b/front_end/sources/CallStackSidebarPane.js
index 6f0605b1c7..d2232a31fa 100644
--- a/front_end/sources/CallStackSidebarPane.js
+++ b/front_end/sources/CallStackSidebarPane.js
@@ -37,6 +37,9 @@ WebInspector.CallStackSidebarPane = function()
this._linkifier = new WebInspector.Linkifier();
WebInspector.moduleSetting("enableAsyncStackTraces").addChangeListener(this._asyncStackTracesStateChanged, this);
WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._blackboxingStateChanged, this);
+ /** @type {!Array} */
+ this.callFrames = [];
+ this._locationPool = new WebInspector.LiveLocationPool();
}
/** @enum {string} */
@@ -55,6 +58,7 @@ WebInspector.CallStackSidebarPane.prototype = {
this.callFrameList.clear();
this._linkifier.reset();
this.element.removeChildren();
+ this._locationPool.disposeAll();
if (!details) {
var infoElement = this.element.createChild("div", "callstack-info");
@@ -68,7 +72,6 @@ WebInspector.CallStackSidebarPane.prototype = {
delete this._statusMessageElement;
delete this._hiddenCallFramesMessageElement;
- /** @type {!Array.} */
this.callFrames = [];
this._hiddenCallFrames = 0;
@@ -110,7 +113,7 @@ WebInspector.CallStackSidebarPane.prototype = {
var callFrameItems = [];
for (var i = 0, n = callFrames.length; i < n; ++i) {
var callFrame = callFrames[i];
- var callFrameItem = new WebInspector.CallStackSidebarPane.CallFrame(callFrame.functionName, callFrame.location(), this._linkifier, callFrame);
+ var callFrameItem = new WebInspector.CallStackSidebarPane.CallFrame(callFrame.functionName, callFrame.location(), this._linkifier, callFrame, this._locationPool);
callFrameItem.element.addEventListener("click", this._callFrameSelected.bind(this, callFrameItem), false);
callFrameItems.push(callFrameItem);
}
@@ -131,7 +134,7 @@ WebInspector.CallStackSidebarPane.prototype = {
var lineNumber = callFrame.lineNumber ? callFrame.lineNumber - 1 : 0;
var columnNumber = callFrame.columnNumber ? callFrame.columnNumber - 1 : 0;
var location = new WebInspector.DebuggerModel.Location(this._debuggerModel, callFrame.scriptId, lineNumber, columnNumber);
- var callFrameItem = new WebInspector.CallStackSidebarPane.CallFrame(callFrame.functionName, location, this._linkifier, null, asyncCallFrameItem);
+ var callFrameItem = new WebInspector.CallStackSidebarPane.CallFrame(callFrame.functionName, location, this._linkifier, null, this._locationPool, asyncCallFrameItem);
callFrameItem.element.addEventListener("click", this._asyncCallFrameClicked.bind(this, callFrameItem), false);
callFrameItems.push(callFrameItem);
}
@@ -438,9 +441,10 @@ WebInspector.CallStackSidebarPane.prototype = {
* @param {!WebInspector.DebuggerModel.Location} location
* @param {!WebInspector.Linkifier} linkifier
* @param {?WebInspector.DebuggerModel.CallFrame} debuggerCallFrame
+ * @param {!WebInspector.LiveLocationPool} locationPool
* @param {!WebInspector.UIList.Item=} asyncCallFrame
*/
-WebInspector.CallStackSidebarPane.CallFrame = function(functionName, location, linkifier, debuggerCallFrame, asyncCallFrame)
+WebInspector.CallStackSidebarPane.CallFrame = function(functionName, location, linkifier, debuggerCallFrame, locationPool, asyncCallFrame)
{
WebInspector.UIList.Item.call(this, WebInspector.beautifyFunctionName(functionName), "");
this._location = location;
@@ -451,7 +455,8 @@ WebInspector.CallStackSidebarPane.CallFrame = function(functionName, location, l
var locationElement = linkifier.linkifyRawLocation(location, location.script().sourceURL);
this.subtitleElement.appendChild(locationElement);
} else {
- WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, this._update.bind(this));
+ this._liveLocationPool = new WebInspector.LiveLocationPool();
+ WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, this._update.bind(this), locationPool);
}
}
diff --git a/front_end/sources/SourceMapNamesResolver.js b/front_end/sources/SourceMapNamesResolver.js
index 68da339dc6..99802d14e4 100644
--- a/front_end/sources/SourceMapNamesResolver.js
+++ b/front_end/sources/SourceMapNamesResolver.js
@@ -38,12 +38,12 @@ WebInspector.SourceMapNamesResolver._resolveScope = function(scope)
/**
* @param {?string} content
- * @return {!Map}
+ * @return {!Promise>}
*/
function onContent(content)
{
if (!content)
- return new Map();
+ return Promise.resolve(new Map());
var startLocation = scope.startLocation();
var endLocation = scope.endLocation();
@@ -53,56 +53,26 @@ WebInspector.SourceMapNamesResolver._resolveScope = function(scope)
var scopeText = text.extract(textRange);
var scopeStart = text.toSourceRange(textRange).offset;
var prefix = "function fui";
- var root = acorn.parse(prefix + scopeText, {});
- /** @type {!Array} */
- var identifiers = [];
- var functionDeclarationCounter = 0;
- var walker = new WebInspector.ESTreeWalker(beforeVisit, afterVisit);
-
- /**
- * @param {!ESTree.Node} node
- * @return {boolean}
- */
- function isFunction(node)
- {
- return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
- }
-
- /**
- * @param {!ESTree.Node} node
- */
- function beforeVisit(node)
- {
- if (isFunction(node))
- functionDeclarationCounter++;
-
- if (functionDeclarationCounter > 1)
- return;
-
- if (isFunction(node) && node.params)
- identifiers.pushAll(node.params);
-
- if (node.type === "VariableDeclarator")
- identifiers.push(/** @type {!ESTree.Node} */(node.id));
- }
-
- /**
- * @param {!ESTree.Node} node
- */
- function afterVisit(node)
- {
- if (isFunction(node))
- functionDeclarationCounter--;
- }
- walker.walk(root);
+ return WebInspector.SourceMapNamesResolverWorker._instance().javaScriptIdentifiers(prefix + scopeText)
+ .then(onIdentifiers.bind(null, text, scopeStart, prefix));
+ }
+ /**
+ * @param {!WebInspector.Text} text
+ * @param {number} scopeStart
+ * @param {string} prefix
+ * @param {!Array} identifiers
+ * @return {!Map}
+ */
+ function onIdentifiers(text, scopeStart, prefix, identifiers)
+ {
var namesMapping = new Map();
- var lineEndings = content.computeLineEndings();
+ var lineEndings = text.lineEndings();
for (var i = 0; i < identifiers.length; ++i) {
var id = identifiers[i];
- var start = scopeStart + id.start - prefix.length;
+ var start = scopeStart + id.offset - prefix.length;
var lineNumber = lineEndings.lowerBound(start);
var columnNumber = start - (lineNumber === 0 ? 0 : (lineEndings[lineNumber - 1] + 1));
@@ -113,10 +83,13 @@ WebInspector.SourceMapNamesResolver._resolveScope = function(scope)
scope[WebInspector.SourceMapNamesResolver._cachedMapSymbol] = namesMapping;
delete scope[WebInspector.SourceMapNamesResolver._cachedPromiseSymbol];
+ WebInspector.SourceMapNamesResolver._scopeResolvedForTest();
return namesMapping;
}
}
+WebInspector.SourceMapNamesResolver._scopeResolvedForTest = function() { }
+
/**
* @param {!WebInspector.DebuggerModel.CallFrame} callFrame
* @return {!Promise.>}
@@ -206,53 +179,19 @@ WebInspector.SourceMapNamesResolver._resolveExpression = function(callFrame, uiS
/**
* @param {?string} content
- * @return {string}
+ * @return {!Promise}
*/
function onContent(content)
{
if (!content)
- return "";
+ return Promise.resolve("");
var text = new WebInspector.Text(content);
var textRange = sourceMap.reverseMapTextRange(uiSourceCode.url(), new WebInspector.TextRange(lineNumber, startColumnNumber, lineNumber, endColumnNumber));
var originalText = text.extract(textRange);
if (!originalText)
- return "";
-
- var tokenizer = acorn.tokenizer(originalText, {ecmaVersion: 6});
- try {
- var token = tokenizer.getToken();
- while (token.type !== acorn.tokTypes.eof && WebInspector.AcornTokenizer.punctuator(token))
- token = tokenizer.getToken();
-
- var startIndex = token.start;
- var endIndex = token.end;
- var openBracketsCounter = 0;
- while (token.type !== acorn.tokTypes.eof) {
- var isIdentifier = WebInspector.AcornTokenizer.identifier(token);
- var isThis = WebInspector.AcornTokenizer.keyword(token, "this");
- var isString = token.type === acorn.tokTypes.string;
- if (!isThis && !isIdentifier && !isString)
- break;
-
- endIndex = token.end;
- token = tokenizer.getToken();
- while (WebInspector.AcornTokenizer.punctuator(token, ".[]")) {
- if (WebInspector.AcornTokenizer.punctuator(token, "["))
- openBracketsCounter++;
-
- if (WebInspector.AcornTokenizer.punctuator(token, "]")) {
- endIndex = openBracketsCounter > 0 ? token.end : endIndex;
- openBracketsCounter--;
- }
-
- token = tokenizer.getToken();
- }
- }
- return originalText.substring(startIndex, endIndex);
- } catch (e) {
- return "";
- }
+ return Promise.resolve("");
+ return WebInspector.SourceMapNamesResolverWorker._instance().evaluatableJavaScriptSubstring(originalText);
}
}
@@ -519,3 +458,99 @@ WebInspector.SourceMapNamesResolver.RemoteObject.prototype = {
__proto__: WebInspector.RemoteObject.prototype
}
+
+/**
+ * @constructor
+ */
+WebInspector.SourceMapNamesResolverWorker = function()
+{
+ this._worker = new WorkerRuntime.Worker("formatter_worker");
+ this._worker.onmessage = this._onMessage.bind(this);
+ this._methodNames = [];
+ this._contents = [];
+ this._callbacks = [];
+}
+
+WebInspector.SourceMapNamesResolverWorker.prototype = {
+ /**
+ * @param {string} text
+ * @return {!Promise}
+ */
+ evaluatableJavaScriptSubstring: function(text)
+ {
+ var callback;
+ var promise = new Promise(fulfill => callback = fulfill);
+ this._methodNames.push("evaluatableJavaScriptSubstring");
+ this._contents.push(text);
+ this._callbacks.push(this._evaluatableJavaScriptSubstringCallback.bind(this, callback));
+ this._maybeRunTask();
+ return promise;
+ },
+
+ /**
+ * @param {function(string)} callback
+ * @param {!MessageEvent} event
+ */
+ _evaluatableJavaScriptSubstringCallback: function(callback, event)
+ {
+ callback.call(null, /** @type {string} */(event.data));
+ },
+
+ /**
+ * @param {string} text
+ * @return {!Promise>}
+ */
+ javaScriptIdentifiers: function(text)
+ {
+ var callback;
+ var promise = new Promise(fulfill => callback = fulfill);
+ this._methodNames.push("javaScriptIdentifiers");
+ this._contents.push(text);
+ this._callbacks.push(this._javaScriptIdentifiersCallback.bind(this, callback));
+ this._maybeRunTask();
+ return promise;
+ },
+
+ /**
+ * @param {function(!Array)} callback
+ * @param {!MessageEvent} event
+ */
+ _javaScriptIdentifiersCallback: function(callback, event)
+ {
+ callback.call(null, /** @type {!Array} */(event.data));
+ },
+
+ /**
+ * @param {!MessageEvent} event
+ */
+ _onMessage: function(event)
+ {
+ var callback = this._callbacks[0];
+ this._methodNames.shift();
+ this._contents.shift();
+ this._callbacks.shift();
+ callback.call(null, event);
+ this._runningTask = false;
+ this._maybeRunTask();
+ },
+
+ _maybeRunTask: function()
+ {
+ if (this._runningTask || !this._methodNames.length)
+ return;
+ this._runningTask = true;
+ var methodName = this._methodNames[0];
+ var content = this._contents[0];
+ this._worker.postMessage({ method: methodName, params: { content: content } });
+ }
+}
+
+/**
+ * @return {!WebInspector.SourceMapNamesResolverWorker}
+ */
+WebInspector.SourceMapNamesResolverWorker._instance = function()
+{
+ if (!WebInspector.SourceMapNamesResolverWorker._instanceObject)
+ WebInspector.SourceMapNamesResolverWorker._instanceObject = new WebInspector.SourceMapNamesResolverWorker();
+ return WebInspector.SourceMapNamesResolverWorker._instanceObject;
+}
\ No newline at end of file
diff --git a/front_end/sources/SourcesPanel.js b/front_end/sources/SourcesPanel.js
index ff6ae63c74..b24be6139e 100644
--- a/front_end/sources/SourcesPanel.js
+++ b/front_end/sources/SourcesPanel.js
@@ -103,6 +103,9 @@ WebInspector.SourcesPanel = function(workspaceForTest)
this._updateDebuggerButtons();
this._pauseOnExceptionEnabledChanged();
WebInspector.moduleSetting("pauseOnExceptionEnabled").addChangeListener(this._pauseOnExceptionEnabledChanged, this);
+
+ this._liveLocationPool = new WebInspector.LiveLocationPool();
+
this._setTarget(WebInspector.context.flavor(WebInspector.Target));
WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._onCurrentTargetChanged, this);
@@ -291,7 +294,7 @@ WebInspector.SourcesPanel.prototype = {
}
} else {
if (details.callFrames.length)
- WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(details.callFrames[0].location(), didGetUILocation.bind(this));
+ WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(details.callFrames[0].location(), didGetUILocation.bind(this), this._liveLocationPool);
else
console.warn("ScriptsPanel paused, but callFrames.length is zero."); // TODO remove this once we understand this case better
}
@@ -436,7 +439,7 @@ WebInspector.SourcesPanel.prototype = {
this.sidebarPanes.scopechain.update(callFrame);
this.sidebarPanes.watchExpressions.refreshExpressions();
this.sidebarPanes.callstack.setSelectedCallFrame(callFrame);
- WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(callFrame.location(), this._executionLineChanged.bind(this));
+ WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(callFrame.location(), this._executionLineChanged.bind(this), this._liveLocationPool);
},
/**
@@ -507,6 +510,7 @@ WebInspector.SourcesPanel.prototype = {
if (this._switchToPausedTargetTimeout)
clearTimeout(this._switchToPausedTargetTimeout);
+ this._liveLocationPool.disposeAll();
},
/**
diff --git a/front_end/sources/SourcesView.js b/front_end/sources/SourcesView.js
index 337ba81e46..e96704fe77 100644
--- a/front_end/sources/SourcesView.js
+++ b/front_end/sources/SourcesView.js
@@ -316,9 +316,18 @@ WebInspector.SourcesView.prototype = {
if (this._currentUISourceCode === uiSourceCode)
return sourceView;
+ var currentFrame = this.currentSourceFrame();
+ if (currentFrame)
+ currentFrame.setSearchableView(null);
+
this._currentUISourceCode = uiSourceCode;
this._editorContainer.showFile(uiSourceCode);
this._updateScriptViewToolbarItems();
+
+ currentFrame = this.currentSourceFrame();
+ if (currentFrame)
+ currentFrame.setSearchableView(this._searchableView);
+
return sourceView;
},
@@ -497,8 +506,6 @@ WebInspector.SourcesView.prototype = {
*/
performSearch: function(searchConfig, shouldJump, jumpBackwards)
{
- this._searchableView.updateSearchMatchesCount(0);
-
var sourceFrame = this.currentSourceFrame();
if (!sourceFrame)
return;
@@ -506,37 +513,7 @@ WebInspector.SourcesView.prototype = {
this._searchView = sourceFrame;
this._searchConfig = searchConfig;
- /**
- * @param {!WebInspector.Widget} view
- * @param {number} searchMatches
- * @this {WebInspector.SourcesView}
- */
- function finishedCallback(view, searchMatches)
- {
- if (!searchMatches)
- return;
-
- this._searchableView.updateSearchMatchesCount(searchMatches);
- }
-
- /**
- * @param {number} currentMatchIndex
- * @this {WebInspector.SourcesView}
- */
- function currentMatchChanged(currentMatchIndex)
- {
- this._searchableView.updateCurrentMatchIndex(currentMatchIndex);
- }
-
- /**
- * @this {WebInspector.SourcesView}
- */
- function searchResultsChanged()
- {
- this.performSearch(this._searchConfig, false, false);
- }
-
- this._searchView.performSearch(this._searchConfig, shouldJump, !!jumpBackwards, finishedCallback.bind(this), currentMatchChanged.bind(this), searchResultsChanged.bind(this));
+ this._searchView.performSearch(this._searchConfig, shouldJump, jumpBackwards);
},
/**
diff --git a/front_end/sources/module.json b/front_end/sources/module.json
index 8903b9bde2..fd07496e71 100644
--- a/front_end/sources/module.json
+++ b/front_end/sources/module.json
@@ -343,7 +343,6 @@
}
],
"dependencies": [
- "es_tree",
"components",
"source_frame",
"snippets",
diff --git a/front_end/timeline/TimelineFlameChart.js b/front_end/timeline/TimelineFlameChart.js
index aa805541f9..e9e4e1b2b7 100644
--- a/front_end/timeline/TimelineFlameChart.js
+++ b/front_end/timeline/TimelineFlameChart.js
@@ -291,7 +291,7 @@ WebInspector.TimelineFlameChartDataProvider = function(model, frameModel, irMode
color: WebInspector.themeSupport.patchColor("#222", WebInspector.ThemeSupport.ColorUsage.Foreground),
font: this._font,
backgroundColor: WebInspector.themeSupport.patchColor("white", WebInspector.ThemeSupport.ColorUsage.Background),
- nestingLevel: 0,
+ nestingLevel: 0
};
this._headerLevel2 = {
@@ -388,17 +388,16 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
this._appendInteractionRecords();
var threads = this._model.virtualThreads();
+ this._appendThreadTimelineData(WebInspector.UIString("Main"), this._model.mainThreadEvents(), this._model.mainThreadAsyncEvents(), true);
var compositorThreads = threads.filter(thread => thread.name.startsWith("CompositorTileWorker"));
var otherThreads = threads.filter(thread => !thread.name.startsWith("CompositorTileWorker"));
if (compositorThreads.length) {
- this._appendHeader(WebInspector.UIString("Rasterizer Threads"), this._headerLevel1);
+ this._appendHeader(WebInspector.UIString("Raster"), this._headerLevel1);
for (var i = 0; i < compositorThreads.length; ++i)
this._appendSyncEvents(compositorThreads[i].events, WebInspector.UIString("Rasterizer Thread %d", i), this._headerLevel2);
}
this._appendGPUEvents();
- this._appendThreadTimelineData(WebInspector.UIString("Main Thread"), this._model.mainThreadEvents(), this._model.mainThreadAsyncEvents(), true);
-
otherThreads.forEach(thread => this._appendThreadTimelineData(thread.name, thread.events, thread.asyncEventsByGroup));
/**
@@ -654,7 +653,7 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
if (type === WebInspector.TimelineFlameChartEntryType.Frame)
return "white";
if (type === WebInspector.TimelineFlameChartEntryType.InteractionRecord)
- return WebInspector.TimelineUIUtils.interactionPhaseColor(/** @type {!WebInspector.TimelineIRModel.Phases} */ (this._entryData[entryIndex]));
+ return "transparent";
return "";
},
@@ -681,10 +680,8 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
barWidth -= 2 * hPadding;
barY += vPadding;
barHeight -= 2 * vPadding + 1;
- context.fillStyle = frame.idle ? "white" : "#eee";
+ context.fillStyle = frame.idle ? "white" : (frame.hasWarnings() ? "#fad1d1" : "#d7f0d1");
context.fillRect(barX, barY, barWidth, barHeight);
- if (frame.hasWarnings())
- paintWarningDecoration(barX, barWidth);
var frameDurationText = Number.preciseMillisToString(frame.duration, 1);
var textWidth = context.measureText(frameDurationText).width;
if (barWidth >= textWidth) {
@@ -694,6 +691,15 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
return true;
}
+ if (type === WebInspector.TimelineFlameChartEntryType.InteractionRecord) {
+ var color = WebInspector.TimelineUIUtils.interactionPhaseColor(/** @type {!WebInspector.TimelineIRModel.Phases} */ (this._entryData[entryIndex]));
+ context.fillStyle = color;
+ context.fillRect(barX, barY, barWidth - 1, 2);
+ context.fillRect(barX, barY - 3, 2, 3);
+ context.fillRect(barX + barWidth - 3, barY - 3, 2, 3);
+ return false;
+ }
+
if (type === WebInspector.TimelineFlameChartEntryType.Event) {
var event = /** @type {!WebInspector.TracingModel.Event} */ (this._entryData[entryIndex]);
if (event && event.warning)
diff --git a/front_end/timeline/TimelineModel.js b/front_end/timeline/TimelineModel.js
index 243d057d79..70686f5f9b 100644
--- a/front_end/timeline/TimelineModel.js
+++ b/front_end/timeline/TimelineModel.js
@@ -117,6 +117,7 @@ WebInspector.TimelineModel.RecordType = {
V8Sample: "V8Sample",
JitCodeAdded: "JitCodeAdded",
JitCodeMoved: "JitCodeMoved",
+ ParseScriptOnBackground: "v8.parseOnBackground",
UpdateCounters: "UpdateCounters",
diff --git a/front_end/timeline/TimelinePanel.js b/front_end/timeline/TimelinePanel.js
index a048529b60..fcd5f5b543 100644
--- a/front_end/timeline/TimelinePanel.js
+++ b/front_end/timeline/TimelinePanel.js
@@ -119,6 +119,7 @@ WebInspector.TimelinePanel = function()
this._detailsSplitWidget.hideSidebar();
WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged, this);
this._showRecordingHelpMessage();
+ this._locationPool = new WebInspector.LiveLocationPool();
}
/**
@@ -1280,7 +1281,7 @@ WebInspector.TimelinePanel.prototype = {
var time = lineInfo[1];
var rawLocation = debuggerModel.createRawLocationByURL(url, line, 0);
if (rawLocation)
- new WebInspector.TimelineUIUtils.LineLevelProfilePresentation(rawLocation, time);
+ new WebInspector.TimelineUIUtils.LineLevelProfilePresentation(rawLocation, time, this._locationPool);
else if (uiSourceCode)
uiSourceCode.addLineDecoration(line, WebInspector.TimelineUIUtils.PerformanceLineDecorator.type, time);
}
@@ -1289,6 +1290,7 @@ WebInspector.TimelinePanel.prototype = {
_resetLineLevelCPUProfile: function()
{
+ this._locationPool.disposeAll();
WebInspector.workspace.uiSourceCodes().forEach(uiSourceCode => uiSourceCode.removeAllLineDecorations(WebInspector.TimelineUIUtils.PerformanceLineDecorator.type));
},
diff --git a/front_end/timeline/TimelineUIUtils.js b/front_end/timeline/TimelineUIUtils.js
index 9e77d90fc3..b0cfb04149 100644
--- a/front_end/timeline/TimelineUIUtils.js
+++ b/front_end/timeline/TimelineUIUtils.js
@@ -90,6 +90,7 @@ WebInspector.TimelineUIUtils._initEventStyles = function()
eventStyles[recordTypes.XHRLoad] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("XHR Load"), categories["scripting"]);
eventStyles[recordTypes.CompileScript] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Compile Script"), categories["scripting"]);
eventStyles[recordTypes.EvaluateScript] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Evaluate Script"), categories["scripting"]);
+ eventStyles[recordTypes.ParseScriptOnBackground] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse Script"), categories["scripting"]);
eventStyles[recordTypes.MarkLoad] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Load event"), categories["scripting"], true);
eventStyles[recordTypes.MarkDOMContent] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOMContentLoaded event"), categories["scripting"], true);
eventStyles[recordTypes.MarkFirstPaint] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("First paint"), categories["painting"], true);
@@ -391,13 +392,14 @@ WebInspector.TimelineUIUtils.buildDetailsTextForTraceEvent = function(event, tar
case recordType.EvaluateScript:
var url = eventData["url"];
if (url)
- detailsText = detailsText = WebInspector.displayNameForURL(url) + ":" + eventData["lineNumber"];
+ detailsText = WebInspector.displayNameForURL(url) + ":" + eventData["lineNumber"];
break;
+ case recordType.ParseScriptOnBackground:
case recordType.XHRReadyStateChange:
case recordType.XHRLoad:
var url = eventData["url"];
if (url)
- detailsText = detailsText = WebInspector.displayNameForURL(url);
+ detailsText = WebInspector.displayNameForURL(url);
break;
case recordType.WebSocketCreate:
@@ -540,6 +542,11 @@ WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent = function(event, tar
if (url)
details = linkifyLocation("", url, eventData["lineNumber"], 0);
break;
+ case recordType.ParseScriptOnBackground:
+ var url = eventData["url"];
+ if (url)
+ details = linkifyLocation("", url, 0, 0);
+ break;
default:
if (event.hasCategory(WebInspector.TimelineModel.Category.Console))
detailsText = null;
@@ -2114,11 +2121,12 @@ WebInspector.TimelineUIUtils.eventWarning = function(event, warningType)
* @constructor
* @param {!WebInspector.DebuggerModel.Location} rawLocation
* @param {number} time
+ * @param {!WebInspector.LiveLocationPool} locationPool
*/
-WebInspector.TimelineUIUtils.LineLevelProfilePresentation = function(rawLocation, time)
+WebInspector.TimelineUIUtils.LineLevelProfilePresentation = function(rawLocation, time, locationPool)
{
this._time = time;
- WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this.updateLocation.bind(this));
+ WebInspector.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this.updateLocation.bind(this), locationPool);
}
WebInspector.TimelineUIUtils.LineLevelProfilePresentation.prototype = {
diff --git a/front_end/ui/FilterBar.js b/front_end/ui/FilterBar.js
index 281deb6fa9..3ff751863e 100644
--- a/front_end/ui/FilterBar.js
+++ b/front_end/ui/FilterBar.js
@@ -264,6 +264,14 @@ WebInspector.TextFilterUI.prototype = {
return this._filterElement;
},
+ /**
+ * @return {boolean}
+ */
+ isRegexChecked: function()
+ {
+ return this._supportRegex ? this._regexCheckBox.checked : false;
+ },
+
/**
* @return {string}
*/
@@ -341,6 +349,11 @@ WebInspector.TextFilterUI.prototype = {
{
if (!this._suggestionBuilder)
return;
+ if (this.isRegexChecked()) {
+ if (this._suggestBox.visible())
+ this._suggestBox.hide();
+ return;
+ }
var suggestions = this._suggestionBuilder.buildSuggestions(this._filterInputElement);
if (suggestions && suggestions.length) {
if (this._suppressSuggestion)
@@ -348,7 +361,7 @@ WebInspector.TextFilterUI.prototype = {
else
this._suggestionBuilder.applySuggestion(this._filterInputElement, suggestions[0], true);
var anchorBox = this._filterInputElement.boxInWindow().relativeTo(new AnchorBox(-3, 0));
- this._suggestBox.updateSuggestions(anchorBox, suggestions, 0, true, "");
+ this._suggestBox.updateSuggestions(anchorBox, suggestions.map(item => ({title: item})), 0, true, "");
} else {
this._suggestBox.hide();
}
@@ -369,7 +382,7 @@ WebInspector.TextFilterUI.prototype = {
this._regex = null;
this._filterInputElement.classList.remove("filter-text-invalid");
if (filterQuery) {
- if (this._supportRegex && this._regexCheckBox.checked) {
+ if (this.isRegexChecked()) {
try {
this._regex = new RegExp(filterQuery, "i");
} catch (e) {
diff --git a/front_end/ui/SuggestBox.js b/front_end/ui/SuggestBox.js
index f1cb273a04..188772dbbc 100644
--- a/front_end/ui/SuggestBox.js
+++ b/front_end/ui/SuggestBox.js
@@ -71,6 +71,11 @@ WebInspector.SuggestBox = function(suggestBoxDelegate, maxItemsHeight)
this._asyncDetailsPromises = new Map();
}
+/**
+ * @typedef Array.<{title: string, className: (string|undefined)}>
+ */
+WebInspector.SuggestBox.Suggestions;
+
WebInspector.SuggestBox.prototype = {
/**
* @return {boolean}
@@ -240,11 +245,12 @@ WebInspector.SuggestBox.prototype = {
/**
* @param {string} prefix
* @param {string} text
+ * @param {string|undefined} className
* @param {number} index
*/
- _createItemElement: function(prefix, text, index)
+ _createItemElement: function(prefix, text, className, index)
{
- var element = createElementWithClass("div", "suggest-box-content-item source-code");
+ var element = createElementWithClass("div", "suggest-box-content-item source-code " + (className || ""));
element.tabIndex = -1;
if (prefix && prefix.length && !text.indexOf(prefix)) {
element.createChild("span", "prefix").textContent = prefix;
@@ -259,7 +265,7 @@ WebInspector.SuggestBox.prototype = {
},
/**
- * @param {!Array.} items
+ * @param {!WebInspector.SuggestBox.Suggestions} items
* @param {string} userEnteredText
* @param {function(number): !Promise<{detail:string, description:string}>=} asyncDetails
*/
@@ -273,7 +279,7 @@ WebInspector.SuggestBox.prototype = {
for (var i = 0; i < items.length; ++i) {
var item = items[i];
- var currentItemElement = this._createItemElement(userEnteredText, item, i);
+ var currentItemElement = this._createItemElement(userEnteredText, item.title, item.className, i);
this._element.appendChild(currentItemElement);
}
},
@@ -338,7 +344,7 @@ WebInspector.SuggestBox.prototype = {
},
/**
- * @param {!Array.} completions
+ * @param {!WebInspector.SuggestBox.Suggestions} completions
* @param {boolean} canShowForSingleItem
* @param {string} userEnteredText
*/
@@ -351,7 +357,7 @@ WebInspector.SuggestBox.prototype = {
return true;
// Do not show a single suggestion if it is the same as user-entered prefix, even if allowed to show single-item suggest boxes.
- return canShowForSingleItem && completions[0] !== userEnteredText;
+ return canShowForSingleItem && completions[0].title !== userEnteredText;
},
_ensureRowCountPerViewport: function()
@@ -366,7 +372,7 @@ WebInspector.SuggestBox.prototype = {
/**
* @param {!AnchorBox} anchorBox
- * @param {!Array.} completions
+ * @param {!WebInspector.SuggestBox.Suggestions} completions
* @param {number} selectedIndex
* @param {boolean} canShowForSingleItem
* @param {string} userEnteredText
diff --git a/front_end/ui/TabbedPane.js b/front_end/ui/TabbedPane.js
index 1a342f310d..75b60c75e1 100644
--- a/front_end/ui/TabbedPane.js
+++ b/front_end/ui/TabbedPane.js
@@ -83,20 +83,29 @@ WebInspector.TabbedPane.prototype = {
return this._currentTab ? this._currentTab.view : null;
},
+ /**
+ * @return {!Array.}
+ */
+ tabIds: function()
+ {
+ return this._tabs.map(tab => tab._id);
+ },
+
/**
* @return {!Array.}
*/
tabViews: function()
{
- /**
- * @param {!WebInspector.TabbedPaneTab} tab
- * @return {!WebInspector.Widget}
- */
- function tabToView(tab)
- {
- return tab.view;
- }
- return this._tabs.map(tabToView);
+ return this._tabs.map(tab => tab.view);
+ },
+
+ /**
+ * @param {string} tabId
+ * @return {?WebInspector.Widget}
+ */
+ tabView: function(tabId)
+ {
+ return this._tabsById[tabId] ? this._tabsById[tabId].view : null;
},
/**
@@ -361,6 +370,16 @@ WebInspector.TabbedPane.prototype = {
this._updateTabElements();
},
+ /**
+ * @param {string} id
+ * @param {boolean} enabled
+ */
+ setTabEnabled: function(id, enabled)
+ {
+ var tab = this._tabsById[id];
+ tab.tabElement.classList.toggle("disabled", !enabled);
+ },
+
/**
* @param {string} id
* @param {string} className
diff --git a/front_end/ui/TextPrompt.js b/front_end/ui/TextPrompt.js
index 84e2a53008..79952d3939 100644
--- a/front_end/ui/TextPrompt.js
+++ b/front_end/ui/TextPrompt.js
@@ -471,7 +471,7 @@ WebInspector.TextPrompt.prototype = {
/**
* @param {string} prefix
- * @return {!Array.}
+ * @return {!WebInspector.SuggestBox.Suggestions}
*/
additionalCompletions: function(prefix)
{
@@ -489,18 +489,20 @@ WebInspector.TextPrompt.prototype = {
_completionsReady: function(selection, originalWordPrefixRange, reverse, force, completions, selectedIndex)
{
var prefix = originalWordPrefixRange.toString();
- if (prefix || force) {
- if (prefix)
- completions = completions.concat(this.additionalCompletions(prefix));
- else
- completions = this.additionalCompletions(prefix).concat(completions);
- }
// Filter out dupes.
var store = new Set();
completions = completions.filter(item => !store.has(item) && !!store.add(item));
+ var annotatedCompletions = completions.map(item => ({title: item}));
+
+ if (prefix || force) {
+ if (prefix)
+ annotatedCompletions = annotatedCompletions.concat(this.additionalCompletions(prefix));
+ else
+ annotatedCompletions = this.additionalCompletions(prefix).concat(annotatedCompletions);
+ }
- if (!this._waitingForCompletions || !completions.length) {
+ if (!this._waitingForCompletions || !annotatedCompletions.length) {
this.hideSuggestBox();
return;
}
@@ -522,7 +524,7 @@ WebInspector.TextPrompt.prototype = {
this._userEnteredText = fullWordRange.toString();
if (this._suggestBox)
- this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), completions, selectedIndex, !this.isCaretAtEndOfPrompt(), this._userEnteredText);
+ this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), annotatedCompletions, selectedIndex, !this.isCaretAtEndOfPrompt(), this._userEnteredText);
if (selectedIndex === -1)
return;
@@ -531,7 +533,7 @@ WebInspector.TextPrompt.prototype = {
this._commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
if (this.isCaretAtEndOfPrompt()) {
- var completionText = completions[selectedIndex];
+ var completionText = annotatedCompletions[selectedIndex].title;
var prefixText = this._userEnteredRange.toString();
var suffixText = completionText.substring(wordPrefixLength);
this._userEnteredRange.deleteContents();
@@ -827,7 +829,7 @@ WebInspector.TextPromptWithHistory.prototype = {
/**
* @override
* @param {string} prefix
- * @return {!Array.}
+ * @return {!WebInspector.SuggestBox.Suggestions}
*/
additionalCompletions: function(prefix)
{
@@ -835,11 +837,15 @@ WebInspector.TextPromptWithHistory.prototype = {
return [];
var result = [];
var text = this.text();
+ var set = new Set();
for (var i = this._data.length - 1; i >= 0 && result.length < 50; --i) {
var item = this._data[i];
if (!item.startsWith(text))
continue;
- result.push(item.substring(text.length - prefix.length));
+ if (set.has(item))
+ continue;
+ set.add(item);
+ result.push({title: item.substring(text.length - prefix.length), className: "additional"});
}
return result;
},
diff --git a/front_end/ui/Toolbar.js b/front_end/ui/Toolbar.js
index 70c374e8dc..c57e0cf7b4 100644
--- a/front_end/ui/Toolbar.js
+++ b/front_end/ui/Toolbar.js
@@ -101,6 +101,11 @@ WebInspector.Toolbar.prototype = {
this.appendToolbarItem(new WebInspector.ToolbarSeparator());
},
+ appendSpacer: function()
+ {
+ this.appendToolbarItem(new WebInspector.ToolbarSeparator(true));
+ },
+
/**
* @param {string} text
*/
@@ -719,10 +724,11 @@ WebInspector.ToolbarSettingToggle.prototype = {
/**
* @constructor
* @extends {WebInspector.ToolbarItem}
+ * @param {boolean=} spacer
*/
-WebInspector.ToolbarSeparator = function()
+WebInspector.ToolbarSeparator = function(spacer)
{
- WebInspector.ToolbarItem.call(this, createElementWithClass("div", "toolbar-divider"));
+ WebInspector.ToolbarItem.call(this, createElementWithClass("div", spacer ? "toolbar-spacer" : "toolbar-divider"));
}
WebInspector.ToolbarSeparator.prototype = {
diff --git a/front_end/ui/suggestBox.css b/front_end/ui/suggestBox.css
index 4752503cb6..e33ff52c40 100644
--- a/front_end/ui/suggestBox.css
+++ b/front_end/ui/suggestBox.css
@@ -91,6 +91,30 @@
white-space: nowrap;
}
+.suggest-box .suggest-box-content-item.additional {
+ background-color: #f9f9f9;
+}
+
+.suggest-box .suggest-box-content-item.additional::before {
+ display: inline-block;
+ content: "";
+ -webkit-user-select: none;
+ background-image: url(Images/toolbarButtonGlyphs.png);
+ background-size: 352px 168px;
+ width: 10px;
+ height: 10px;
+ position: relative;
+ top: 2px;
+ margin-right: 4px;
+ background-position: -192px -96px;
+}
+
+@media (-webkit-min-device-pixel-ratio: 1.5) {
+.suggest-box .suggest-box-content-item.additional::before {
+ background-image: url(Images/toolbarButtonGlyphs_2x.png);
+}
+} /* media */
+
.suggest-box .suggest-box-content-item .prefix {
font-weight: bold;
}
diff --git a/front_end/ui/tabbedPane.css b/front_end/ui/tabbedPane.css
index f2f5b88c3e..2223c6d0d0 100644
--- a/front_end/ui/tabbedPane.css
+++ b/front_end/ui/tabbedPane.css
@@ -260,6 +260,11 @@
visibility: visible;
}
+.tabbed-pane-header-tab.disabled {
+ opacity: 0.5;
+ pointer-events: none;
+}
+
.tabbed-pane-header.tabbed-pane-no-header-background {
background-color: transparent;
}
diff --git a/front_end/ui/toolbar.css b/front_end/ui/toolbar.css
index 45d3c61b75..6b93471648 100644
--- a/front_end/ui/toolbar.css
+++ b/front_end/ui/toolbar.css
@@ -227,6 +227,10 @@ input.toolbar-item.hover {
height: 16px;
}
+.toolbar-spacer {
+ flex: auto;
+}
+
/* Long click */
.long-click-glyph {
@@ -336,6 +340,10 @@ input.toolbar-item.hover {
transform: scaleX(-1);
}
+.stop-toolbar-item.toolbar-glyph {
+ -webkit-mask-position: -96px -48px;
+}
+
.pause-on-exceptions-toolbar-item.toolbar-glyph {
-webkit-mask-position: -256px 0;
}
@@ -356,6 +364,10 @@ input.toolbar-item.hover {
-webkit-mask-position: 0 -24px;
}
+.notification-toolbar-item.toolbar-glyph {
+ -webkit-mask-position: -32px -120px;
+}
+
.format-toolbar-item.toolbar-glyph {
-webkit-mask-position: -256px -24px;
}
diff --git a/front_end/ui_lazy/FlameChart.js b/front_end/ui_lazy/FlameChart.js
index da1c28a86d..5cdacf611e 100644
--- a/front_end/ui_lazy/FlameChart.js
+++ b/front_end/ui_lazy/FlameChart.js
@@ -1354,26 +1354,12 @@ WebInspector.FlameChart.prototype = {
if (groups.length && lastGroupOffset < top + height)
context.fillRect(0, lastGroupOffset + 2, width, top + height - lastGroupOffset)
- context.strokeStyle = WebInspector.themeSupport.patchColor("#ddd", colorUsage.Background);
- context.beginPath();
- forEachGroup((offset, index, group, isFirst) => {
- if (isFirst)
- return;
- if (group.style.padding > 1)
- hLine(offset - 1.5);
- if (group.style.padding > 2)
- hLine(offset - group.style.padding + 1.5);
- });
- hLine(lastGroupOffset + 1.5);
- context.stroke();
-
context.strokeStyle = WebInspector.themeSupport.patchColor("#bbb", colorUsage.Background);
context.beginPath();
forEachGroup((offset, index, group, isFirst) => {
if (isFirst || group.style.padding < 4)
return;
- hLine(offset - group.style.padding + 0.5);
- hLine(offset - 0.5);
+ hLine(offset - 2.5);
});
hLine(lastGroupOffset + 0.5);
context.stroke();
@@ -1422,10 +1408,6 @@ WebInspector.FlameChart.prototype = {
context.strokeStyle = WebInspector.themeSupport.patchColor("#ddd", colorUsage.Background);
context.beginPath();
- forEachGroup((offset, index, group) => {
- if (group.expanded)
- hLine(offset + barHeight - 0.5);
- });
context.stroke();
context.restore();
diff --git a/protocol.json b/protocol.json
index 9462985bd0..3b20f37a90 100644
--- a/protocol.json
+++ b/protocol.json
@@ -455,9 +455,6 @@
},
{
"name": "requestAppBanner",
- "returns": [
- { "name": "result", "type": "boolean" }
- ],
"hidden": true,
"handlers": ["browser"]
}
@@ -3454,21 +3451,6 @@
"description": "Error data for setScriptSource command. Contains uncompilable script source error.",
"hidden": true
},
- {
- "id": "PromiseDetails",
- "type": "object",
- "description": "Information about the promise. All fields but id are optional and if present they reflect the new state of the property on the promise with given id.",
- "properties": [
- { "name": "id", "type": "integer", "description": "Unique id of the promise." },
- { "name": "status", "type": "string", "optional": true, "enum": ["pending", "resolved", "rejected"], "description": "Status of the promise." },
- { "name": "parentId", "type": "integer", "optional": true, "description": "Id of the parent promise." },
- { "name": "creationTime", "type": "number", "optional": true, "description": "Creation time of the promise." },
- { "name": "settlementTime", "type": "number", "optional": true, "description": "Settlement time of the promise." },
- { "name": "creationStack", "$ref": "Runtime.StackTrace", "optional": true, "description": "JavaScript stack trace on promise creation." },
- { "name": "settlementStack", "$ref": "Runtime.StackTrace", "optional": true, "description": "JavaScript stack trace on promise settlement." }
- ],
- "hidden": true
- },
{
"id": "AsyncOperation",
"type": "object",
@@ -3724,31 +3706,6 @@
"hidden": true,
"description": "Enables or disables async call stacks tracking."
},
- {
- "name": "enablePromiseTracker",
- "parameters": [
- { "name": "captureStacks", "type": "boolean", "optional": true, "description": "Whether to capture stack traces for promise creation and settlement events (default: false)." }
- ],
- "hidden": true,
- "description": "Enables promise tracking, information about Promise
s created or updated will now be stored on the backend."
- },
- {
- "name": "disablePromiseTracker",
- "hidden": true,
- "description": "Disables promise tracking."
- },
- {
- "name": "getPromiseById",
- "parameters": [
- { "name": "promiseId", "type": "integer" },
- { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." }
- ],
- "returns": [
- { "name": "promise", "$ref": "Runtime.RemoteObject", "description": "Object wrapper for Promise
with specified ID, if any." }
- ],
- "hidden": true,
- "description": "Returns Promise
with specified ID."
- },
{
"name": "flushAsyncOperationEvents",
"hidden": true,
@@ -3843,15 +3800,6 @@
"name": "resumed",
"description": "Fired when the virtual machine resumed execution."
},
- {
- "name": "promiseUpdated",
- "parameters": [
- { "name": "eventType", "type": "string", "enum": ["new", "update", "gc"], "description": "Type of the event." },
- { "name": "promise", "$ref": "PromiseDetails", "description": "Information about the updated Promise
." }
- ],
- "description": "Fired when a Promise
is created, updated or garbage collected.",
- "hidden": true
- },
{
"name": "asyncOperationStarted",
"parameters": [
diff --git a/scripts/compile_frontend.py b/scripts/compile_frontend.py
index fa792f08ac..b95dee3f18 100755
--- a/scripts/compile_frontend.py
+++ b/scripts/compile_frontend.py
@@ -78,6 +78,8 @@ def to_platform_path_exact(filepath):
protocol_externs_file = path.join(devtools_frontend_path, 'protocol_externs.js')
injected_script_source_name = path.join(v8_inspector_path, 'InjectedScriptSource.js')
injected_script_externs_file = path.join(v8_inspector_path, 'injected_script_externs.js')
+debugger_script_source_name = path.join(v8_inspector_path, 'DebuggerScript.js')
+debugger_script_externs_file = path.join(v8_inspector_path, 'debugger_script_externs.js')
jsmodule_name_prefix = 'jsmodule_'
runtime_module_name = '_runtime'
@@ -403,6 +405,16 @@ def replace_function(matchobj):
injectedScriptCompileProc = popen(command)
+print 'Compiling DebuggerScript.js...'
+
+command = spawned_compiler_command + [
+ '--externs', to_platform_path_exact(debugger_script_externs_file),
+ '--module', jsmodule_name_prefix + 'debugger_script' + ':1',
+ '--js', to_platform_path(debugger_script_source_name)
+]
+
+debuggerScriptCompileProc = popen(command)
+
print 'Compiling devtools.js...'
command = spawned_compiler_command + [
@@ -492,6 +504,10 @@ def skip_dependents(module_name):
print 'InjectedScriptSource.js compilation output:%s' % os.linesep, injectedScriptCompileOut
errors_found |= hasErrors(injectedScriptCompileOut)
+(debuggerScriptCompilerOut, _) = debuggerScriptCompileProc.communicate()
+print 'DebuggerScript.js compilation output:%s' % os.linesep, debuggerScriptCompilerOut
+errors_found |= hasErrors(debuggerScriptCompilerOut)
+
(devtoolsJSCompileOut, _) = devtoolsJSCompileProc.communicate()
print 'devtools.js compilation output:%s' % os.linesep, devtoolsJSCompileOut
errors_found |= hasErrors(devtoolsJSCompileOut)