diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/devtools/front_end')
173 files changed, 3658 insertions, 3330 deletions
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png b/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png Binary files differindex fd0ab7ae41e..4dcaa26a841 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png +++ b/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png diff --git a/chromium/third_party/blink/renderer/devtools/front_end/OWNERS b/chromium/third_party/blink/renderer/devtools/front_end/OWNERS index 12637c58cc4..f31f5664378 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/OWNERS +++ b/chromium/third_party/blink/renderer/devtools/front_end/OWNERS @@ -1,5 +1,7 @@ alph@chromium.org caseq@chromium.org dgozman@chromium.org +einbinder@chromium.org +luoe@chromium.org lushnikov@chromium.org pfeldman@chromium.org diff --git a/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js b/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js index f48f9e4c6cf..5e6e5f1a0eb 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js @@ -971,7 +971,10 @@ Runtime.ExperimentsSupport = class { */ isEnabled(experimentName) { this._checkExperiment(experimentName); - + // Check for explicitly disabled experiments first - the code could call setEnable(false) on the experiment enabled + // by default and we should respect that. + if (Runtime._experimentsSetting()[experimentName] === false) + return false; if (this._enabledTransiently[experimentName]) return true; if (!this.supportEnabled()) diff --git a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js index 99c2b816302..3d3e6759cc2 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js @@ -74,7 +74,7 @@ Audits2.ProtocolService = class extends Common.Object { * @param {string} message */ _sendProtocolMessage(message) { - this._rawConnection.sendMessage(message); + this._rawConnection.sendRawMessage(message); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2StatusView.js b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2StatusView.js index 3198f953edd..52e44fb27fa 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2StatusView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2StatusView.js @@ -285,7 +285,7 @@ Audits2.StatusView.StatusPhases = [ { id: 'auditing', progressBarClass: 'auditing', - message: 'Almost there! Lighthouse is now generating your own special pretty report!', + message: 'Almost there! Lighthouse is now generating your report.', statusMessagePrefix: 'Evaluating', order: 30, } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BlackboxManager.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BlackboxManager.js index f8f4face142..0e6aab390f3 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BlackboxManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BlackboxManager.js @@ -13,17 +13,13 @@ Bindings.BlackboxManager = class { this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; SDK.targetManager.addModelListener( - SDK.DebuggerModel, SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this); - SDK.targetManager.addModelListener( - SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this); + SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, this._clearCacheIfNeeded.bind(this), this); Common.moduleSetting('skipStackFramesPattern').addChangeListener(this._patternChanged.bind(this)); Common.moduleSetting('skipContentScripts').addChangeListener(this._patternChanged.bind(this)); /** @type {!Set<function()>} */ this._listeners = new Set(); - /** @type {!Map<!SDK.DebuggerModel, !Map<string, !Array<!Protocol.Debugger.ScriptPosition>>>} */ - this._debuggerModelData = new Map(); /** @type {!Map<string, boolean>} */ this._isBlackboxedURLCache = new Map(); @@ -50,6 +46,9 @@ Bindings.BlackboxManager = class { */ modelAdded(debuggerModel) { this._setBlackboxPatterns(debuggerModel); + const sourceMapManager = debuggerModel.sourceMapManager(); + sourceMapManager.addEventListener(SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this); + sourceMapManager.addEventListener(SDK.SourceMapManager.Events.SourceMapDetached, this._sourceMapDetached, this); } /** @@ -57,8 +56,15 @@ Bindings.BlackboxManager = class { * @param {!SDK.DebuggerModel} debuggerModel */ modelRemoved(debuggerModel) { - this._debuggerModelData.delete(debuggerModel); - this._isBlackboxedURLCache.clear(); + this._clearCacheIfNeeded(); + const sourceMapManager = debuggerModel.sourceMapManager(); + sourceMapManager.removeEventListener(SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this); + sourceMapManager.removeEventListener(SDK.SourceMapManager.Events.SourceMapDetached, this._sourceMapDetached, this); + } + + _clearCacheIfNeeded() { + if (this._isBlackboxedURLCache.size > 1024) + this._isBlackboxedURLCache.clear(); } /** @@ -76,32 +82,6 @@ Bindings.BlackboxManager = class { } /** - * @param {!SDK.DebuggerModel.Location} location - * @return {boolean} - */ - isBlackboxedRawLocation(location) { - const script = location.script(); - if (!script) - return false; - const positions = this._scriptPositions(script); - if (!positions) - return this._isBlackboxedScript(script); - const index = positions.lowerBound(location, comparator); - return !!(index % 2); - - /** - * @param {!SDK.DebuggerModel.Location} a - * @param {!Protocol.Debugger.ScriptPosition} b - * @return {number} - */ - function comparator(a, b) { - if (a.lineNumber !== b.lineNumber) - return a.lineNumber - b.lineNumber; - return a.columnNumber - b.columnNumber; - } - } - - /** * @param {!Workspace.UISourceCode} uiSourceCode * @return {boolean} */ @@ -125,57 +105,76 @@ Bindings.BlackboxManager = class { if (isContentScript && Common.moduleSetting('skipContentScripts').get()) return true; const regex = Common.moduleSetting('skipStackFramesPattern').asRegExp(); - const isBlackboxed = regex && regex.test(url); + const isBlackboxed = (regex && regex.test(url)) || false; this._isBlackboxedURLCache.set(url, isBlackboxed); return isBlackboxed; } /** + * @param {!Common.Event} event + */ + _sourceMapAttached(event) { + const script = /** @type {!SDK.Script} */ (event.data.client); + const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap); + this._updateScriptRanges(script, sourceMap); + } + + /** + * @param {!Common.Event} event + */ + _sourceMapDetached(event) { + const script = /** @type {!SDK.Script} */ (event.data.client); + this._updateScriptRanges(script, null); + } + + /** * @param {!SDK.Script} script * @param {?SDK.SourceMap} sourceMap * @return {!Promise<undefined>} */ - sourceMapLoaded(script, sourceMap) { - if (!sourceMap) - return Promise.resolve(); - const previousScriptState = this._scriptPositions(script); - if (!previousScriptState) - return Promise.resolve(); - - const hasBlackboxedMappings = sourceMap.sourceURLs().some(url => this.isBlackboxedURL(url)); - const mappings = hasBlackboxedMappings ? sourceMap.mappings().slice() : []; - if (!mappings.length) { - if (previousScriptState.length > 0) - return this._setScriptState(script, []); - return Promise.resolve(); + async _updateScriptRanges(script, sourceMap) { + let hasBlackboxedMappings = false; + if (!Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript())) + hasBlackboxedMappings = sourceMap ? sourceMap.sourceURLs().some(url => this.isBlackboxedURL(url)) : false; + if (!hasBlackboxedMappings) { + if (script[Bindings.BlackboxManager._blackboxedRanges] && await script.setBlackboxedRanges([])) + delete script[Bindings.BlackboxManager._blackboxedRanges]; + this._debuggerWorkspaceBinding.updateLocations(script); + return; } - mappings.sort(mappingComparator); + const mappings = sourceMap.mappings(); + const newRanges = []; let currentBlackboxed = false; - let isBlackboxed = false; - const positions = []; - // If content in script file begin is not mapped and one or more ranges are blackboxed then blackbox it. if (mappings[0].lineNumber !== 0 || mappings[0].columnNumber !== 0) { - positions.push({lineNumber: 0, columnNumber: 0}); + newRanges.push({lineNumber: 0, columnNumber: 0}); currentBlackboxed = true; } for (const mapping of mappings) { if (mapping.sourceURL && currentBlackboxed !== this.isBlackboxedURL(mapping.sourceURL)) { - positions.push({lineNumber: mapping.lineNumber, columnNumber: mapping.columnNumber}); + newRanges.push({lineNumber: mapping.lineNumber, columnNumber: mapping.columnNumber}); currentBlackboxed = !currentBlackboxed; } - isBlackboxed = currentBlackboxed || isBlackboxed; } - return this._setScriptState(script, !isBlackboxed ? [] : positions); + + const oldRanges = script[Bindings.BlackboxManager._blackboxedRanges] || []; + if (!isEqual(oldRanges, newRanges) && await script.setBlackboxedRanges(newRanges)) + script[Bindings.BlackboxManager._blackboxedRanges] = newRanges; + this._debuggerWorkspaceBinding.updateLocations(script); + /** - * @param {!SDK.SourceMapEntry} a - * @param {!SDK.SourceMapEntry} b - * @return {number} + * @param {!Array<!{lineNumber: number, columnNumber: number}>} rangesA + * @param {!Array<!{lineNumber: number, columnNumber: number}>} rangesB + * @return {boolean} */ - function mappingComparator(a, b) { - if (a.lineNumber !== b.lineNumber) - return a.lineNumber - b.lineNumber; - return a.columnNumber - b.columnNumber; + function isEqual(rangesA, rangesB) { + if (rangesA.length !== rangesB.length) + return false; + for (let i = 0; i < rangesA.length; ++i) { + if (rangesA[i].lineNumber !== rangesB[i].lineNumber || rangesA[i].columnNumber !== rangesB[i].columnNumber) + return false; + } + return true; } } @@ -269,31 +268,22 @@ Bindings.BlackboxManager = class { Common.moduleSetting('skipStackFramesPattern').setAsArray(regexPatterns); } - _patternChanged() { + async _patternChanged() { this._isBlackboxedURLCache.clear(); /** @type {!Array<!Promise>} */ const promises = []; for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel)) { promises.push(this._setBlackboxPatterns(debuggerModel)); + const sourceMapManager = debuggerModel.sourceMapManager(); for (const script of debuggerModel.scripts()) - promises.push(this._addScript(script).then(loadSourceMap.bind(this, script))); - } - Promise.all(promises).then(() => { - const listeners = Array.from(this._listeners); - for (const listener of listeners) - listener(); - this._patternChangeFinishedForTests(); - }); - - /** - * @param {!SDK.Script} script - * @return {!Promise<undefined>} - * @this {Bindings.BlackboxManager} - */ - function loadSourceMap(script) { - return this.sourceMapLoaded(script, this._debuggerWorkspaceBinding.sourceMapForScript(script)); + promises.push(this._updateScriptRanges(script, sourceMapManager.sourceMapForClient(script))); } + await Promise.all(promises); + const listeners = Array.from(this._listeners); + for (const listener of listeners) + listener(); + this._patternChangeFinishedForTests(); } _patternChangeFinishedForTests() { @@ -301,105 +291,6 @@ Bindings.BlackboxManager = class { } /** - * @param {!Common.Event} event - */ - _globalObjectCleared(event) { - const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data); - this._debuggerModelData.delete(debuggerModel); - this._isBlackboxedURLCache.clear(); - } - - /** - * @param {!Common.Event} event - */ - _parsedScriptSource(event) { - const script = /** @type {!SDK.Script} */ (event.data); - this._addScript(script); - } - - /** - * @param {!SDK.Script} script - * @return {!Promise<undefined>} - */ - _addScript(script) { - if (!script.sourceURL && !script.sourceMapURL) - return Promise.resolve(); - const blackboxed = this._isBlackboxedScript(script); - return this._setScriptState(script, blackboxed ? [{lineNumber: 0, columnNumber: 0}] : []); - } - - /** - * @param {!SDK.Script} script - * @return {boolean} - */ - _isBlackboxedScript(script) { - return this.isBlackboxedURL(script.sourceURL, script.isContentScript()); - } - - /** - * @param {!SDK.Script} script - * @return {?Array<!Protocol.Debugger.ScriptPosition>} - */ - _scriptPositions(script) { - if (this._debuggerModelData.has(script.debuggerModel)) - return this._debuggerModelData.get(script.debuggerModel).get(script.scriptId) || null; - return null; - } - - /** - * @param {!SDK.Script} script - * @param {!Array<!Protocol.Debugger.ScriptPosition>} positions - */ - _setScriptPositions(script, positions) { - const debuggerModel = script.debuggerModel; - if (!this._debuggerModelData.has(debuggerModel)) - this._debuggerModelData.set(debuggerModel, new Map()); - this._debuggerModelData.get(debuggerModel).set(script.scriptId, positions); - } - - /** - * @param {!SDK.Script} script - * @param {!Array<!Protocol.Debugger.ScriptPosition>} positions - * @return {!Promise<undefined>} - */ - _setScriptState(script, positions) { - const previousScriptState = this._scriptPositions(script); - if (previousScriptState) { - let hasChanged = false; - hasChanged = previousScriptState.length !== positions.length; - for (let i = 0; !hasChanged && i < positions.length; ++i) { - hasChanged = positions[i].lineNumber !== previousScriptState[i].lineNumber || - positions[i].columnNumber !== previousScriptState[i].columnNumber; - } - if (!hasChanged) - return Promise.resolve(); - } else { - if (positions.length === 0) - return Promise.resolve().then(updateState.bind(this, false)); - } - - return script.setBlackboxedRanges(positions).then(updateState.bind(this)); - - /** - * @param {boolean} success - * @this {Bindings.BlackboxManager} - */ - function updateState(success) { - if (success) { - this._setScriptPositions(script, positions); - this._debuggerWorkspaceBinding.updateLocations(script); - const isBlackboxed = positions.length !== 0; - if (!isBlackboxed && script.sourceMapURL) - this._debuggerWorkspaceBinding.maybeLoadSourceMap(script); - } else { - const hasPositions = !!this._scriptPositions(script); - if (!hasPositions) - this._setScriptPositions(script, []); - } - } - } - - /** * @param {string} url * @return {string} */ @@ -430,5 +321,7 @@ Bindings.BlackboxManager = class { } }; +Bindings.BlackboxManager._blackboxedRanges = Symbol('blackboxedRanged'); + /** @type {!Bindings.BlackboxManager} */ Bindings.blackboxManager; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js index d57b5ff054d..2230513c879 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js @@ -43,14 +43,12 @@ Bindings.BreakpointManager = class extends Common.Object { this._targetManager = targetManager; this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; - /** @type {!Map<!Workspace.UISourceCode, !Map<number, !Map<number, !Array<!Bindings.BreakpointManager.Breakpoint>>>>} */ + /** @type {!Map<!Workspace.UISourceCode, !Map<string, !Bindings.BreakpointManager.BreakpointLocation>>} */ this._breakpointsForUISourceCode = new Map(); /** @type {!Map<string, !Bindings.BreakpointManager.Breakpoint>} */ this._breakpointByStorageId = new Map(); - this._workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved, this); this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this); - this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this); } /** @@ -99,23 +97,6 @@ Bindings.BreakpointManager = class extends Common.Object { } /** - * @param {!Common.Event} event - */ - _uiSourceCodeRemoved(event) { - const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); - this._removeUISourceCode(uiSourceCode); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - */ - _removeUISourceCode(uiSourceCode) { - const breakpoints = uiSourceCode[Bindings.BreakpointManager._breakpointsSymbol] || new Set(); - for (const breakpoint of breakpoints) - breakpoint._resetLocations(); - } - - /** * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber @@ -146,8 +127,8 @@ Bindings.BreakpointManager = class extends Common.Object { const itemId = Bindings.BreakpointManager._breakpointStorageId(uiSourceCode.url(), lineNumber, columnNumber); let breakpoint = this._breakpointByStorageId.get(itemId); if (breakpoint) { - breakpoint.setPrimaryUISourceCode(uiSourceCode); breakpoint._updateState(condition, enabled); + breakpoint.setPrimaryUISourceCode(uiSourceCode); breakpoint._updateBreakpoint(); return breakpoint; } @@ -158,27 +139,12 @@ Bindings.BreakpointManager = class extends Common.Object { } /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {number} lineNumber - * @return {!Array<!Bindings.BreakpointManager.Breakpoint>} - */ - findBreakpoints(uiSourceCode, lineNumber) { - const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); - const lineBreakpoints = breakpoints ? breakpoints.get(lineNumber) : null; - return lineBreakpoints ? lineBreakpoints.valuesArray()[0] : []; - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {number} lineNumber - * @param {number} columnNumber - * @return {?Bindings.BreakpointManager.Breakpoint} + * @param {!Workspace.UILocation} uiLocation + * @return {?Bindings.BreakpointManager.BreakpointLocation} */ - findBreakpoint(uiSourceCode, lineNumber, columnNumber) { - const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); - const lineBreakpoints = breakpoints ? breakpoints.get(lineNumber) : null; - const columnBreakpoints = lineBreakpoints ? lineBreakpoints.get(columnNumber) : null; - return columnBreakpoints ? columnBreakpoints[0] : null; + findBreakpoint(uiLocation) { + const breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode); + return breakpoints ? (breakpoints.get(uiLocation.id())) || null : null; } /** @@ -187,11 +153,24 @@ Bindings.BreakpointManager = class extends Common.Object { * @return {!Promise<!Array<!Workspace.UILocation>>} */ possibleBreakpoints(uiSourceCode, textRange) { - const startLocation = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation( + const startLocations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations( uiSourceCode, textRange.startLine, textRange.startColumn); - const endLocation = - Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, textRange.endLine, textRange.endColumn); - if (!startLocation || !endLocation || startLocation.debuggerModel !== endLocation.debuggerModel) + const endLocations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations( + uiSourceCode, textRange.endLine, textRange.endColumn); + const endLocationByModel = new Map(); + for (const location of endLocations) + endLocationByModel.set(location.debuggerModel, location); + let startLocation = null; + let endLocation = null; + for (const location of startLocations) { + const endLocationCandidate = endLocationByModel.get(location.debuggerModel); + if (endLocationCandidate) { + startLocation = location; + endLocation = endLocationCandidate; + break; + } + } + if (!startLocation || !endLocation) return Promise.resolve([]); return startLocation.debuggerModel @@ -223,101 +202,24 @@ Bindings.BreakpointManager = class extends Common.Object { /** * @param {!Workspace.UISourceCode} uiSourceCode - * @return {!Array.<!Bindings.BreakpointManager.Breakpoint>} - */ - breakpointsForUISourceCode(uiSourceCode) { - let result = []; - const uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); - const breakpoints = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.valuesArray() : []; - for (let i = 0; i < breakpoints.length; ++i) { - const lineBreakpoints = breakpoints[i]; - const columnBreakpointArrays = lineBreakpoints ? lineBreakpoints.valuesArray() : []; - result = result.concat.apply(result, columnBreakpointArrays); - } - return result; - } - - /** - * @return {!Array.<!Bindings.BreakpointManager.Breakpoint>} - */ - _allBreakpoints() { - let result = []; - const uiSourceCodes = this._breakpointsForUISourceCode.keysArray(); - for (let i = 0; i < uiSourceCodes.length; ++i) - result = result.concat(this.breakpointsForUISourceCode(uiSourceCodes[i])); - return result; - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} + * @return {!Array<!Bindings.BreakpointManager.BreakpointLocation>} */ breakpointLocationsForUISourceCode(uiSourceCode) { - const uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); - const lineNumbers = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.keysArray() : []; - const result = []; - for (let i = 0; i < lineNumbers.length; ++i) { - const lineBreakpoints = uiSourceCodeBreakpoints.get(lineNumbers[i]); - const columnNumbers = lineBreakpoints.keysArray(); - for (let j = 0; j < columnNumbers.length; ++j) { - const columnBreakpoints = lineBreakpoints.get(columnNumbers[j]); - const lineNumber = parseInt(lineNumbers[i], 10); - const columnNumber = parseInt(columnNumbers[j], 10); - for (let k = 0; k < columnBreakpoints.length; ++k) { - const breakpoint = columnBreakpoints[k]; - const uiLocation = uiSourceCode.uiLocation(lineNumber, columnNumber); - result.push({breakpoint: breakpoint, uiLocation: uiLocation}); - } - } - } - return result; + const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); + return breakpoints ? Array.from(breakpoints.values()) : []; } /** - * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} + * @return {!Array<!Bindings.BreakpointManager.BreakpointLocation>} */ allBreakpointLocations() { let result = []; - const uiSourceCodes = this._breakpointsForUISourceCode.keysArray(); - for (let i = 0; i < uiSourceCodes.length; ++i) - result = result.concat(this.breakpointLocationsForUISourceCode(uiSourceCodes[i])); + for (const breakpoints of this._breakpointsForUISourceCode.values()) + result = result.concat(Array.from(breakpoints.values())); return result; } /** - * @param {boolean} toggleState - */ - toggleAllBreakpoints(toggleState) { - const breakpoints = this._allBreakpoints(); - for (let i = 0; i < breakpoints.length; ++i) - breakpoints[i].setEnabled(toggleState); - } - - removeAllBreakpoints() { - const breakpoints = this._allBreakpoints(); - for (let i = 0; i < breakpoints.length; ++i) - breakpoints[i].remove(false /* keepInStorage */); - } - - /** - * @param {!Set<!Bindings.BreakpointManager.Breakpoint>} selectedBreakpoints - */ - removeOtherBreakpoints(selectedBreakpoints) { - const allBreakpoints = this._allBreakpoints(); - allBreakpoints.forEach(breakpoint => { - if (!selectedBreakpoints.has(breakpoint)) - breakpoint.remove(false /* keepInStorage */); - }); - } - - _projectRemoved(event) { - const project = /** @type {!Workspace.Project} */ (event.data); - const uiSourceCodes = project.uiSourceCodes(); - for (let i = 0; i < uiSourceCodes.length; ++i) - this._removeUISourceCode(uiSourceCodes[i]); - } - - /** * @param {!Bindings.BreakpointManager.Breakpoint} breakpoint * @param {boolean} removeFromStorage */ @@ -337,19 +239,9 @@ Bindings.BreakpointManager = class extends Common.Object { breakpoints = new Map(); this._breakpointsForUISourceCode.set(uiLocation.uiSourceCode, breakpoints); } - let lineBreakpoints = breakpoints.get(uiLocation.lineNumber); - if (!lineBreakpoints) { - lineBreakpoints = new Map(); - breakpoints.set(uiLocation.lineNumber, lineBreakpoints); - } - let columnBreakpoints = lineBreakpoints.get(uiLocation.columnNumber); - if (!columnBreakpoints) { - columnBreakpoints = []; - lineBreakpoints.set(uiLocation.columnNumber, columnBreakpoints); - } - columnBreakpoints.push(breakpoint); - this.dispatchEventToListeners( - Bindings.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation}); + const breakpointLocation = {breakpoint: breakpoint, uiLocation: uiLocation}; + breakpoints.set(uiLocation.id(), breakpointLocation); + this.dispatchEventToListeners(Bindings.BreakpointManager.Events.BreakpointAdded, breakpointLocation); } /** @@ -360,20 +252,12 @@ Bindings.BreakpointManager = class extends Common.Object { const breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode); if (!breakpoints) return; - - const lineBreakpoints = breakpoints.get(uiLocation.lineNumber); - if (!lineBreakpoints) - return; - const columnBreakpoints = lineBreakpoints.get(uiLocation.columnNumber); - if (!columnBreakpoints) + const breakpointLocation = breakpoints.get(uiLocation.id()) || null; + if (!breakpointLocation) return; - columnBreakpoints.remove(breakpoint); - if (!columnBreakpoints.length) - lineBreakpoints.remove(uiLocation.columnNumber); - if (!lineBreakpoints.size) - breakpoints.remove(uiLocation.lineNumber); - if (!breakpoints.size) - this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode); + breakpoints.delete(uiLocation.id()); + if (breakpoints.size === 0) + this._breakpointsForUISourceCode.delete(uiLocation.uiSourceCode); this.dispatchEventToListeners( Bindings.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation}); } @@ -385,6 +269,12 @@ Bindings.BreakpointManager.Events = { BreakpointRemoved: Symbol('breakpoint-removed') }; +/** @typedef {{ + * breakpoint: !Bindings.BreakpointManager.Breakpoint, + * uiLocation: !Workspace.UILocation + * }} + */ +Bindings.BreakpointManager.BreakpointLocation; /** * @unrestricted @@ -406,20 +296,19 @@ Bindings.BreakpointManager.Breakpoint = class { this._lineNumber = lineNumber; this._columnNumber = columnNumber; - this.setPrimaryUISourceCode(primaryUISourceCode); - - /** @type {!Map<string, number>} */ - this._numberOfDebuggerLocationForUILocation = new Map(); + /** @type {?Workspace.UILocation} */ + this._defaultUILocation = null; + /** @type {!Set<!Workspace.UILocation>} */ + this._uiLocations = new Set(); /** @type {string} */ this._condition; /** @type {boolean} */ this._enabled; /** @type {boolean} */ this._isRemoved; - /** @type {!Workspace.UILocation|undefined} */ this._fakePrimaryLocation; - this._currentState = null; /** @type {!Map.<!SDK.DebuggerModel, !Bindings.BreakpointManager.ModelBreakpoint>}*/ this._modelBreakpoints = new Map(); this._updateState(condition, enabled); + this.setPrimaryUISourceCode(primaryUISourceCode); this._breakpointManager._targetManager.observeModels(SDK.DebuggerModel, this); } @@ -454,15 +343,14 @@ Bindings.BreakpointManager.Breakpoint = class { * @param {?Workspace.UISourceCode} primaryUISourceCode */ setPrimaryUISourceCode(primaryUISourceCode) { - const symbol = Bindings.BreakpointManager._breakpointsSymbol; - if (this._primaryUISourceCode) - this._primaryUISourceCode[symbol].delete(this); - this._primaryUISourceCode = primaryUISourceCode; - if (!primaryUISourceCode) - return; - if (!this._primaryUISourceCode[symbol]) - this._primaryUISourceCode[symbol] = new Set(); - this._primaryUISourceCode[symbol].add(this); + if (this._uiLocations.size === 0 && this._defaultUILocation) + this._breakpointManager._uiLocationRemoved(this, this._defaultUILocation); + if (primaryUISourceCode) + this._defaultUILocation = primaryUISourceCode.uiLocation(this._lineNumber, this._columnNumber); + else + this._defaultUILocation = null; + if (this._uiLocations.size === 0 && this._defaultUILocation && !this._isRemoved) + this._breakpointManager._uiLocationAdded(this, this._defaultUILocation); } /** @@ -487,38 +375,25 @@ Bindings.BreakpointManager.Breakpoint = class { } /** - * @param {?Workspace.UILocation} oldUILocation - * @param {!Workspace.UILocation} newUILocation + * @param {!Workspace.UILocation} uiLocation */ - _replaceUILocation(oldUILocation, newUILocation) { + _uiLocationAdded(uiLocation) { if (this._isRemoved) return; - - this._removeUILocation(oldUILocation, true); - this._removeFakeBreakpointAtPrimaryLocation(); - - const current = (this._numberOfDebuggerLocationForUILocation.get(newUILocation.id()) || 0) + 1; - this._numberOfDebuggerLocationForUILocation.set(newUILocation.id(), current); - if (current === 1) - this._breakpointManager._uiLocationAdded(this, newUILocation); + if (this._uiLocations.size === 0 && this._defaultUILocation) + this._breakpointManager._uiLocationRemoved(this, this._defaultUILocation); + this._uiLocations.add(uiLocation); + this._breakpointManager._uiLocationAdded(this, uiLocation); } /** - * @param {?Workspace.UILocation} uiLocation - * @param {boolean=} muteCreationFakeBreakpoint + * @param {!Workspace.UILocation} uiLocation */ - _removeUILocation(uiLocation, muteCreationFakeBreakpoint) { - if (!uiLocation || !this._numberOfDebuggerLocationForUILocation.has(uiLocation.id())) - return; - const current = (this._numberOfDebuggerLocationForUILocation.get(uiLocation.id()) || 0) - 1; - this._numberOfDebuggerLocationForUILocation.set(uiLocation.id(), current); - if (current !== 0) - return; - - this._numberOfDebuggerLocationForUILocation.delete(uiLocation.id()); + _uiLocationRemoved(uiLocation) { + this._uiLocations.delete(uiLocation); this._breakpointManager._uiLocationRemoved(this, uiLocation); - if (!muteCreationFakeBreakpoint) - this._fakeBreakpointAtPrimaryLocation(); + if (this._uiLocations.size === 0 && this._defaultUILocation && !this._isRemoved) + this._breakpointManager._uiLocationAdded(this, this._defaultUILocation); } /** @@ -563,8 +438,6 @@ Bindings.BreakpointManager.Breakpoint = class { } _updateBreakpoint() { - this._removeFakeBreakpointAtPrimaryLocation(); - this._fakeBreakpointAtPrimaryLocation(); const modelBreakpoints = this._modelBreakpoints.valuesArray(); for (let i = 0; i < modelBreakpoints.length; ++i) modelBreakpoints[i]._scheduleUpdateInDebugger(); @@ -576,23 +449,15 @@ Bindings.BreakpointManager.Breakpoint = class { remove(keepInStorage) { this._isRemoved = true; const removeFromStorage = !keepInStorage; - this._removeFakeBreakpointAtPrimaryLocation(); const modelBreakpoints = this._modelBreakpoints.valuesArray(); for (let i = 0; i < modelBreakpoints.length; ++i) { modelBreakpoints[i]._scheduleUpdateInDebugger(); modelBreakpoints[i]._removeEventListeners(); } - this.setPrimaryUISourceCode(null); this._breakpointManager._removeBreakpoint(this, removeFromStorage); this._breakpointManager._targetManager.unobserveModels(SDK.DebuggerModel, this); - } - - /** - * @param {!SDK.DebuggerModel} debuggerModel - */ - _updateInDebuggerForModel(debuggerModel) { - this._modelBreakpoints.get(debuggerModel)._scheduleUpdateInDebugger(); + this.setPrimaryUISourceCode(null); } /** @@ -602,36 +467,14 @@ Bindings.BreakpointManager.Breakpoint = class { return Bindings.BreakpointManager._breakpointStorageId(this._url, this._lineNumber, this._columnNumber); } - _fakeBreakpointAtPrimaryLocation() { - if (this._isRemoved || this._numberOfDebuggerLocationForUILocation.size || this._fakePrimaryLocation) - return; - - if (!this._primaryUISourceCode) - return; - - this._fakePrimaryLocation = this._primaryUISourceCode.uiLocation(this._lineNumber, this._columnNumber); - if (this._fakePrimaryLocation) - this._breakpointManager._uiLocationAdded(this, this._fakePrimaryLocation); - } - - _removeFakeBreakpointAtPrimaryLocation() { - if (this._fakePrimaryLocation) { - this._breakpointManager._uiLocationRemoved(this, this._fakePrimaryLocation); - delete this._fakePrimaryLocation; - } - } - _resetLocations() { this.setPrimaryUISourceCode(null); - this._removeFakeBreakpointAtPrimaryLocation(); const modelBreakpoints = this._modelBreakpoints.valuesArray(); for (let i = 0; i < modelBreakpoints.length; ++i) modelBreakpoints[i]._resetLocations(); } }; -Bindings.BreakpointManager._breakpointsSymbol = Symbol('breakpoints'); - /** * @unrestricted */ @@ -648,7 +491,7 @@ Bindings.BreakpointManager.ModelBreakpoint = class { this._liveLocations = new Bindings.LiveLocationPool(); - /** @type {!Map<string, !Workspace.UILocation>} */ + /** @type {!Map<!Bindings.LiveLocation, !Workspace.UILocation>} */ this._uiLocations = new Map(); this._debuggerModel.addEventListener( SDK.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this); @@ -664,7 +507,7 @@ Bindings.BreakpointManager.ModelBreakpoint = class { _resetLocations() { for (const uiLocation of this._uiLocations.values()) - this._breakpoint._removeUILocation(uiLocation); + this._breakpoint._uiLocationRemoved(uiLocation); this._uiLocations.clear(); this._liveLocations.disposeAll(); @@ -692,7 +535,8 @@ Bindings.BreakpointManager.ModelBreakpoint = class { * @return {boolean} */ _scriptDiverged() { - const uiSourceCode = this._breakpoint._primaryUISourceCode; + const uiLocation = this._breakpoint._defaultUILocation; + const uiSourceCode = uiLocation ? uiLocation.uiSourceCode : null; if (!uiSourceCode) return false; const scriptFile = this._debuggerWorkspaceBinding.scriptFile(uiSourceCode, this._debuggerModel); @@ -710,15 +554,18 @@ Bindings.BreakpointManager.ModelBreakpoint = class { return; } - const uiSourceCode = this._breakpoint._primaryUISourceCode; + const uiLocation = this._breakpoint._defaultUILocation; + const uiSourceCode = uiLocation ? uiLocation.uiSourceCode : null; const lineNumber = this._breakpoint._lineNumber; const columnNumber = this._breakpoint._columnNumber; const condition = this._breakpoint.condition(); - let debuggerLocation = uiSourceCode && - Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber); - if (debuggerLocation && debuggerLocation.debuggerModel !== this._debuggerModel) - debuggerLocation = null; + let debuggerLocation = null; + if (uiSourceCode) { + const locations = + Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber); + debuggerLocation = locations.find(location => location.debuggerModel === this._debuggerModel); + } let newState; if (this._breakpoint._isRemoved || !this._breakpoint.enabled() || this._scriptDiverged()) { newState = null; @@ -731,10 +578,6 @@ Bindings.BreakpointManager.ModelBreakpoint = class { newState = new Bindings.BreakpointManager.Breakpoint.State( null, script.scriptId, script.hash, debuggerLocation.lineNumber, debuggerLocation.columnNumber, condition); } - } else if (this._breakpoint._currentState && this._breakpoint._currentState.url) { - const position = this._breakpoint._currentState; - newState = new Bindings.BreakpointManager.Breakpoint.State( - position.url, null, null, position.lineNumber, position.columnNumber, condition); } else if (uiSourceCode) { newState = new Bindings.BreakpointManager.Breakpoint.State( uiSourceCode.url(), null, null, lineNumber, columnNumber, condition); @@ -744,8 +587,6 @@ Bindings.BreakpointManager.ModelBreakpoint = class { return; } - this._breakpoint._currentState = newState; - if (this._debuggerId) { await this._refreshBreakpoint(); callback(); @@ -828,16 +669,26 @@ Bindings.BreakpointManager.ModelBreakpoint = class { } /** - * @param {!SDK.DebuggerModel.Location} location * @param {!Bindings.LiveLocation} liveLocation */ - _locationUpdated(location, liveLocation) { - const uiLocation = liveLocation.uiLocation(); - if (!uiLocation) - return; - const oldUILocation = this._uiLocations.get(location.id()) || null; - this._uiLocations.set(location.id(), uiLocation); - this._breakpoint._replaceUILocation(oldUILocation, uiLocation); + _locationUpdated(liveLocation) { + const oldUILocation = this._uiLocations.get(liveLocation); + if (oldUILocation) + this._breakpoint._uiLocationRemoved(oldUILocation); + let uiLocation = liveLocation.uiLocation(); + + if (uiLocation) { + const breakpointLocation = this._breakpoint._breakpointManager.findBreakpoint(uiLocation); + if (breakpointLocation && breakpointLocation.uiLocation !== breakpointLocation.breakpoint._defaultUILocation) + uiLocation = null; + } + + if (uiLocation) { + this._uiLocations.set(liveLocation, uiLocation); + this._breakpoint._uiLocationAdded(uiLocation); + } else { + this._uiLocations.delete(liveLocation); + } } /** @@ -848,15 +699,13 @@ Bindings.BreakpointManager.ModelBreakpoint = class { const uiLocation = this._debuggerWorkspaceBinding.rawLocationToUILocation(location); if (!uiLocation) return false; - const breakpoint = this._breakpoint._breakpointManager.findBreakpoint( - uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber); - if (breakpoint && breakpoint !== this._breakpoint) { + const breakpointLocation = this._breakpoint._breakpointManager.findBreakpoint(uiLocation); + if (breakpointLocation && breakpointLocation.breakpoint !== this._breakpoint) { // location clash this._breakpoint.remove(false /* keepInStorage */); return false; } - this._debuggerWorkspaceBinding.createLiveLocation( - location, this._locationUpdated.bind(this, location), this._liveLocations); + this._debuggerWorkspaceBinding.createLiveLocation(location, this._locationUpdated.bind(this), this._liveLocations); return true; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js index d484ae0daca..846be51b0a1 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js @@ -167,22 +167,22 @@ Bindings.CompilerScriptMapping = class { * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} + * @return {!Array<!SDK.DebuggerModel.Location>} */ - uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) { + uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) { const sourceMap = uiSourceCode[Bindings.CompilerScriptMapping._sourceMapSymbol]; if (!sourceMap) - return null; + return []; const scripts = this._sourceMapManager.clientsForSourceMap(sourceMap); - const script = scripts.length ? scripts[0] : null; - if (!script) - return null; + if (!scripts.length) + return []; const entry = sourceMap.sourceLineMapping(uiSourceCode.url(), lineNumber, columnNumber); if (!entry) - return null; - return this._debuggerModel.createRawLocation( - script, entry.lineNumber + script.lineOffset, - !entry.lineNumber ? entry.columnNumber + script.columnOffset : entry.columnNumber); + return []; + return scripts.map( + script => this._debuggerModel.createRawLocation( + script, entry.lineNumber + script.lineOffset, + !entry.lineNumber ? entry.columnNumber + script.columnOffset : entry.columnNumber)); } /** @@ -213,7 +213,6 @@ Bindings.CompilerScriptMapping = class { if (Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript())) return; - Bindings.blackboxManager.sourceMapLoaded(script, sourceMap); this._populateSourceMapSources(script, sourceMap); this._sourceMapAttachedForTest(sourceMap); @@ -245,16 +244,6 @@ Bindings.CompilerScriptMapping = class { } /** - * @param {!SDK.Script} script - */ - maybeLoadSourceMap(script) { - const sourceMap = this._sourceMapManager.sourceMapForClient(script); - if (!sourceMap) - return; - this._populateSourceMapSources(script, sourceMap); - } - - /** * @param {?SDK.SourceMap} sourceMap */ _sourceMapAttachedForTest(sourceMap) { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/DebuggerWorkspaceBinding.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/DebuggerWorkspaceBinding.js index 8b971eb46f3..b3bba8a2325 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/DebuggerWorkspaceBinding.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/DebuggerWorkspaceBinding.js @@ -131,21 +131,17 @@ Bindings.DebuggerWorkspaceBinding = class { * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} + * @return {!Array<!SDK.DebuggerModel.Location>} */ - uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) { - for (let i = 0; i < this._sourceMappings.length; ++i) { - const rawLocation = this._sourceMappings[i].uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber); - if (rawLocation) - return rawLocation; - } - - for (const modelData of this._debuggerModelToData.values()) { - const rawLocation = modelData._uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber); - if (rawLocation) - return rawLocation; - } - return null; + uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) { + let locations = []; + for (let i = 0; i < this._sourceMappings.length && !locations.length; ++i) + locations = this._sourceMappings[i].uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber); + if (locations.length) + return locations; + for (const modelData of this._debuggerModelToData.values()) + locations.push(...modelData._uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber)); + return locations; } /** @@ -153,10 +149,13 @@ Bindings.DebuggerWorkspaceBinding = class { * @return {!Workspace.UILocation} */ normalizeUILocation(uiLocation) { - const rawLocation = - this.uiLocationToRawLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber); - if (rawLocation) - return this.rawLocationToUILocation(rawLocation) || uiLocation; + const rawLocations = + this.uiLocationToRawLocations(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber); + for (const location of rawLocations) { + const uiLocationCandidate = this.rawLocationToUILocation(location); + if (uiLocationCandidate) + return uiLocationCandidate; + } return uiLocation; } @@ -182,16 +181,6 @@ Bindings.DebuggerWorkspaceBinding = class { } /** - * @param {!SDK.Script} script - */ - maybeLoadSourceMap(script) { - const modelData = this._debuggerModelToData.get(script.debuggerModel); - if (!modelData) - return; - modelData._compilerMapping.maybeLoadSourceMap(script); - } - - /** * @param {!Common.Event} event */ _globalObjectCleared(event) { @@ -319,16 +308,20 @@ Bindings.DebuggerWorkspaceBinding.ModelData = class { * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} + * @return {!Array<!SDK.DebuggerModel.Location>} */ - _uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) { - let rawLocation = null; - rawLocation = rawLocation || this._compilerMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber); - rawLocation = rawLocation || this._resourceMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber); - rawLocation = - rawLocation || Bindings.resourceMapping.uiLocationToJSLocation(uiSourceCode, lineNumber, columnNumber); - rawLocation = rawLocation || this._defaultMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber); - return rawLocation; + _uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) { + let locations = this._compilerMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber); + locations = locations.length ? + locations : + this._resourceMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber); + locations = locations.length ? + locations : + Bindings.resourceMapping.uiLocationToJSLocations(uiSourceCode, lineNumber, columnNumber); + locations = locations.length ? + locations : + this._defaultMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber); + return locations; } /** @@ -387,7 +380,8 @@ Bindings.DebuggerWorkspaceBinding.Location = class extends Bindings.LiveLocation * @return {boolean} */ isBlackboxed() { - return Bindings.blackboxManager.isBlackboxedRawLocation(this._rawLocation); + const uiLocation = this.uiLocation(); + return uiLocation ? Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode) : false; } }; @@ -466,9 +460,9 @@ Bindings.DebuggerSourceMapping.prototype = { * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} + * @return {!Array<!SDK.DebuggerModel.Location>} */ - uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {}, + uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {}, }; /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/DefaultScriptMapping.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/DefaultScriptMapping.js index dab1e802e9c..26fea9642b4 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/DefaultScriptMapping.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/DefaultScriptMapping.js @@ -47,10 +47,9 @@ Bindings.DefaultScriptMapping = class { debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this), debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this), debuggerModel.addEventListener( - SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this), - debuggerModel.addEventListener( SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, this._discardedScriptSource, this) ]; + this._scriptSymbol = Symbol('symbol'); } /** @@ -58,7 +57,8 @@ Bindings.DefaultScriptMapping = class { * @return {?SDK.Script} */ static scriptForUISourceCode(uiSourceCode) { - return uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol] || null; + const scripts = uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol]; + return scripts ? scripts.values().next().value : null; } /** @@ -83,17 +83,17 @@ Bindings.DefaultScriptMapping = class { * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} + * @return {!Array<!SDK.DebuggerModel.Location>} */ - uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) { - const script = uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol]; + uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) { + const script = uiSourceCode[this._scriptSymbol]; if (!script) - return null; + return []; if (script.isInlineScriptWithSourceURL()) { - return this._debuggerModel.createRawLocation( - script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset); + return [this._debuggerModel.createRawLocation( + script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset)]; } - return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber); + return [this._debuggerModel.createRawLocation(script, lineNumber, columnNumber)]; } /** @@ -105,7 +105,11 @@ Bindings.DefaultScriptMapping = class { const url = 'debugger:///VM' + script.scriptId + (name ? ' ' + name : ''); const uiSourceCode = this._project.createUISourceCode(url, Common.resourceTypes.Script); - uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol] = script; + uiSourceCode[this._scriptSymbol] = script; + if (!uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol]) + uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol] = new Set([script]); + else + uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol].add(script); script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol] = uiSourceCode; this._project.addUISourceCodeWithProvider(uiSourceCode, script, null, 'text/javascript'); this._debuggerWorkspaceBinding.updateLocations(script); @@ -120,7 +124,10 @@ Bindings.DefaultScriptMapping = class { if (!uiSourceCode) return; delete script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol]; - delete uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol]; + delete uiSourceCode[this._scriptSymbol]; + uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol].delete(script); + if (!uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol].size) + delete uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol]; this._project.removeUISourceCode(uiSourceCode.url()); } @@ -135,5 +142,5 @@ Bindings.DefaultScriptMapping = class { } }; -Bindings.DefaultScriptMapping._scriptSymbol = Symbol('symbol'); +Bindings.DefaultScriptMapping._scriptsSymbol = Symbol('symbol'); Bindings.DefaultScriptMapping._uiSourceCodeSymbol = Symbol('uiSourceCodeSymbol'); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/PresentationConsoleMessageHelper.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/PresentationConsoleMessageHelper.js index f639ae65f92..41c62e7f3a6 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/PresentationConsoleMessageHelper.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/PresentationConsoleMessageHelper.js @@ -94,9 +94,6 @@ Bindings.PresentationConsoleMessageHelper = class { // TODO(dgozman): setImmediate because we race with DebuggerWorkspaceBinding on ParsedScriptSource event delivery. debuggerModel.addEventListener( SDK.DebuggerModel.Events.ParsedScriptSource, event => setImmediate(this._parsedScriptSource.bind(this, event))); - debuggerModel.addEventListener( - SDK.DebuggerModel.Events.FailedToParseScriptSource, - event => setImmediate(this._parsedScriptSource.bind(this, event))); debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this); this._locationPool = new Bindings.LiveLocationPool(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceMapping.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceMapping.js index 2acdd1280c3..c26e2741cc7 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceMapping.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceMapping.js @@ -95,18 +95,19 @@ Bindings.ResourceMapping = class { * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} + * @return {!Array<!SDK.DebuggerModel.Location>} */ - uiLocationToJSLocation(uiSourceCode, lineNumber, columnNumber) { + uiLocationToJSLocations(uiSourceCode, lineNumber, columnNumber) { if (!uiSourceCode[Bindings.ResourceMapping._symbol]) - return null; + return []; const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode); if (!target) - return null; + return []; const debuggerModel = target.model(SDK.DebuggerModel); if (!debuggerModel) - return null; - return debuggerModel.createRawLocationByURL(uiSourceCode.url(), lineNumber, columnNumber); + return []; + const location = debuggerModel.createRawLocationByURL(uiSourceCode.url(), lineNumber, columnNumber); + return location ? [location] : []; } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js index f6eea9a66ba..92bcbcfd4f6 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js @@ -53,8 +53,6 @@ Bindings.ResourceScriptMapping = class { this._eventListeners = [ this._debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this), this._debuggerModel.addEventListener( - SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this), - this._debuggerModel.addEventListener( SDK.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this), runtimeModel.addEventListener( SDK.RuntimeModel.Events.ExecutionContextDestroyed, this._executionContextDestroyed, this), @@ -113,18 +111,18 @@ Bindings.ResourceScriptMapping = class { * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} + * @return {!Array<!SDK.DebuggerModel.Location>} */ - uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) { + uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) { const scriptFile = this._uiSourceCodeToScriptFile.get(uiSourceCode); if (!scriptFile) - return null; + return []; const script = scriptFile._script; if (script.isInlineScriptWithSourceURL()) { - return this._debuggerModel.createRawLocation( - script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset); + return [this._debuggerModel.createRawLocation( + script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset)]; } - return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber); + return [this._debuggerModel.createRawLocation(script, lineNumber, columnNumber)]; } /** @@ -308,7 +306,8 @@ Bindings.ResourceScriptFile = class extends Common.Object { if (!this._script) return; const debuggerModel = this._resourceScriptMapping._debuggerModel; - const breakpoints = Bindings.breakpointManager.breakpointsForUISourceCode(this._uiSourceCode); + const breakpoints = Bindings.breakpointManager.breakpointLocationsForUISourceCode(this._uiSourceCode) + .map(breakpointLocation => breakpointLocation.breakpoint); const source = this._uiSourceCode.workingCopy(); debuggerModel.setScriptSource(this._script.scriptId, source, scriptSourceWasSet.bind(this)); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/module.json b/chromium/third_party/blink/renderer/devtools/front_end/browser_components/module.json deleted file mode 100644 index bf178cbff78..00000000000 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/module.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dependencies": [ - "browser_sdk", - "components" - ], - "scripts": [ - "ImagePreview.js" - ], - "resources": [ - "imagePreview.css" - ] -} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js b/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js index aee39714f7f..a98df127fc4 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js @@ -15,7 +15,7 @@ BrowserConsole.BrowserConsole = class { */ appendApplicableItems(event, contextMenu, object) { const consoleMessage = /** @type {!SDK.ConsoleMessage} */ (object); - const request = BrowserSDK.NetworkLog.requestForConsoleMessage(consoleMessage); + const request = SDK.NetworkLog.requestForConsoleMessage(consoleMessage); if (request && SDK.NetworkManager.canReplayRequest(request)) { contextMenu.debugSection().appendItem( Common.UIString('Replay XHR'), SDK.NetworkManager.replayRequest.bind(null, request)); @@ -30,7 +30,7 @@ BrowserConsole.BrowserConsole = class { */ render(object, options) { const consoleMessage = /** @type {!SDK.ConsoleMessage} */ (object); - const request = BrowserSDK.NetworkLog.requestForConsoleMessage(consoleMessage); + const request = SDK.NetworkLog.requestForConsoleMessage(consoleMessage); let messageElement = null; if (request) { messageElement = createElement('span'); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/LogManager.js b/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/LogManager.js index 0681aa91f52..8fa6c8b0913 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/LogManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/LogManager.js @@ -41,7 +41,7 @@ BrowserSDK.LogManager = class { data.entry.timestamp, undefined, undefined, data.entry.workerId); if (data.entry.networkRequestId) - BrowserSDK.networkLog.associateConsoleMessageWithRequest(consoleMessage, data.entry.networkRequestId); + SDK.networkLog.associateConsoleMessageWithRequest(consoleMessage, data.entry.networkRequestId); SDK.consoleModel.addMessage(consoleMessage); } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/module.json b/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/module.json index 445eb49f7a4..1c276e0fa19 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/module.json @@ -22,9 +22,7 @@ } ], "scripts": [ - "LogManager.js", - "NetworkLog.js", - "HAREntry.js" + "LogManager.js" ], "dependencies": [ "sdk" diff --git a/chromium/third_party/blink/renderer/devtools/front_end/changes/ChangesSidebar.js b/chromium/third_party/blink/renderer/devtools/front_end/changes/ChangesSidebar.js index e5cb9bdaa6e..e1788dfd0ac 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/changes/ChangesSidebar.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/changes/ChangesSidebar.js @@ -103,7 +103,7 @@ Changes.ChangesSidebar.UISourceCodeTreeElement = class extends UI.TreeElement { this.listItemElement.classList.add('navigator-' + uiSourceCode.contentType().name() + '-tree-item'); let iconType = 'largeicon-navigator-file'; - if (this.uiSourceCode.contentType() === Common.resourceTypes.Snippet) + if (Snippets.isSnippetsUISourceCode(this.uiSourceCode)) iconType = 'largeicon-navigator-snippet'; const defaultIcon = UI.Icon.create(iconType, 'icon'); this.setLeadingIcons([defaultIcon]); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/changes/module.json b/chromium/third_party/blink/renderer/devtools/front_end/changes/module.json index 1875abc0e48..667b334a71e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/changes/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/changes/module.json @@ -24,6 +24,7 @@ "diff", "bindings", "persistence", + "snippets", "ui" ], "scripts": [ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/activeline.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/activeline.js index aa295d0d86c..c7b14ce07fb 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/activeline.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/activeline.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/closebrackets.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/closebrackets.js index 460f662f804..ce1a4ac6b15 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/closebrackets.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/closebrackets.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -129,16 +129,14 @@ else curType = "skip"; } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && - cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch && - (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) { + cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) { + if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass; curType = "addFour"; } else if (identical) { var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur) if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both"; else return CodeMirror.Pass; - } else if (opening && (cm.getLine(cur.line).length == cur.ch || - isClosingBracket(next, pairs) || - /\s/.test(next))) { + } else if (opening) { curType = "both"; } else { return CodeMirror.Pass; @@ -175,11 +173,6 @@ }); } - function isClosingBracket(ch, pairs) { - var pos = pairs.lastIndexOf(ch); - return pos > -1 && pos % 2 == 1; - } - function charsAround(cm, pos) { var str = cm.getRange(Pos(pos.line, pos.ch - 1), Pos(pos.line, pos.ch + 1)); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.css b/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.css index 3360cac9c42..fdbf48c3994 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.css @@ -118,7 +118,7 @@ .CodeMirror-linewidget { position: relative; z-index: 2; - overflow: auto; + padding: 0.1px; /* Force widget margins to stay inside of the container */ } .CodeMirror-widget {} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.js index 069c5796ca3..eaea2faa043 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.js @@ -1,7 +1,7 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE -// This is CodeMirror (http://codemirror.net), a code editor +// This is CodeMirror (https://codemirror.net), a code editor // implemented in JavaScript on top of the browser's DOM. // // You can find some technical background for some of the code below @@ -746,6 +746,16 @@ function collapsedSpanAtSide(line, start) { function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) } function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) } +function collapsedSpanAround(line, ch) { + var sps = sawCollapsedSpans && line.markedSpans, found; + if (sps) { for (var i = 0; i < sps.length; ++i) { + var sp = sps[i]; + if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker; } + } } + return found +} + // Test whether there exists a collapsed span that partially // overlaps (covers the start or end, but not both) of a new span. // Such overlap is not allowed. @@ -2780,12 +2790,11 @@ function coordsChar(cm, x, y) { var lineObj = getLine(doc, lineN); for (;;) { var found = coordsCharInner(cm, lineObj, lineN, x, y); - var merged = collapsedSpanAtEnd(lineObj); - var mergedPos = merged && merged.find(0, true); - if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) - { lineN = lineNo(lineObj = mergedPos.to.line); } - else - { return found } + var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0)); + if (!collapsed) { return found } + var rangeEnd = collapsed.find(1); + if (rangeEnd.line == lineN) { return rangeEnd } + lineObj = getLine(doc, lineN = rangeEnd.line); } } @@ -3545,6 +3554,7 @@ var NativeScrollbars = function(place, scroll, cm) { this.cm = cm; var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); + vert.tabIndex = horiz.tabIndex = -1; place(vert); place(horiz); on(vert, "scroll", function () { @@ -4796,7 +4806,7 @@ function addChangeToHistory(doc, change, selAfter, opId) { if ((hist.lastOp == opId || hist.lastOrigin == change.origin && change.origin && - ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || + ((change.origin.charAt(0) == "+" && hist.lastModTime > time - (doc.cm ? doc.cm.options.historyEventDelay : 500)) || change.origin.charAt(0) == "*")) && (cur = lastChangeEvent(hist, hist.lastOp == opId))) { // Merge this change into the last event @@ -5225,7 +5235,8 @@ function makeChangeInner(doc, change) { // Revert a change stored in a document's history. function makeChangeFromHistory(doc, type, allowSelectionOnly) { - if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) { return } + var suppress = doc.cm && doc.cm.state.suppressEdits; + if (suppress && !allowSelectionOnly) { return } var hist = doc.history, event, selAfter = doc.sel; var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; @@ -5250,8 +5261,10 @@ function makeChangeFromHistory(doc, type, allowSelectionOnly) { return } selAfter = event; - } - else { break } + } else if (suppress) { + source.push(event); + return + } else { break } } // Build up a reverse change object to add to the opposite history @@ -5694,7 +5707,7 @@ LineWidget.prototype.changed = function () { this.height = null; var diff = widgetHeight(this) - oldH; if (!diff) { return } - updateLineHeight(line, line.height + diff); + if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff); } if (cm) { runInOp(cm, function () { cm.curOp.forceUpdate = true; @@ -5727,7 +5740,7 @@ function addLineWidget(doc, handle, node, options) { } return true }); - signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)); + if (cm) { signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)); } return widget } @@ -6576,8 +6589,6 @@ function registerGlobalHandlers() { // Called when the window resizes function onResize(cm) { var d = cm.display; - if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) - { return } // Might be a text scaling operation, clear size caches. d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; d.scrollbarsClipped = false; @@ -6585,11 +6596,11 @@ function onResize(cm) { } var keyNames = { - 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 3: "Pause", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", - 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", + 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", 145: "ScrollLock", 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" @@ -6623,7 +6634,7 @@ keyMap.pcDefault = { "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", - fallthrough: "basic" + "fallthrough": "basic" }; // Very basic readline/emacs-style bindings, which are standard on Mac. keyMap.emacsy = { @@ -6641,7 +6652,7 @@ keyMap.macDefault = { "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", - fallthrough: ["basic", "emacsy"] + "fallthrough": ["basic", "emacsy"] }; keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; @@ -6736,6 +6747,9 @@ function keyName(event, noShift) { if (presto && event.keyCode == 34 && event["char"]) { return false } var name = keyNames[event.keyCode]; if (name == null || event.altGraphKey) { return false } + // Ctrl-ScrollLock has keyCode 3, same as Ctrl-Pause, + // so we'll use event.code when available (Chrome 48+, FF 38+, Safari 10.1+) + if (event.keyCode == 3 && event.code) { name = event.code; } return addModifierNames(name, event, noShift) } @@ -7318,8 +7332,8 @@ function leftButtonStartDrag(cm, event, pos, behavior) { var dragEnd = operation(cm, function (e) { if (webkit) { display.scroller.draggable = false; } cm.state.draggingText = false; - off(document, "mouseup", dragEnd); - off(document, "mousemove", mouseMove); + off(display.wrapper.ownerDocument, "mouseup", dragEnd); + off(display.wrapper.ownerDocument, "mousemove", mouseMove); off(display.scroller, "dragstart", dragStart); off(display.scroller, "drop", dragEnd); if (!moved) { @@ -7328,7 +7342,7 @@ function leftButtonStartDrag(cm, event, pos, behavior) { { extendSelection(cm.doc, pos, null, null, behavior.extend); } // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) if (webkit || ie && ie_version == 9) - { setTimeout(function () {document.body.focus(); display.input.focus();}, 20); } + { setTimeout(function () {display.wrapper.ownerDocument.body.focus(); display.input.focus();}, 20); } else { display.input.focus(); } } @@ -7343,8 +7357,8 @@ function leftButtonStartDrag(cm, event, pos, behavior) { dragEnd.copy = !behavior.moveOnDrag; // IE's approach to draggable if (display.scroller.dragDrop) { display.scroller.dragDrop(); } - on(document, "mouseup", dragEnd); - on(document, "mousemove", mouseMove); + on(display.wrapper.ownerDocument, "mouseup", dragEnd); + on(display.wrapper.ownerDocument, "mousemove", mouseMove); on(display.scroller, "dragstart", dragStart); on(display.scroller, "drop", dragEnd); @@ -7476,19 +7490,19 @@ function leftButtonSelect(cm, event, start, behavior) { counter = Infinity; e_preventDefault(e); display.input.focus(); - off(document, "mousemove", move); - off(document, "mouseup", up); + off(display.wrapper.ownerDocument, "mousemove", move); + off(display.wrapper.ownerDocument, "mouseup", up); doc.history.lastSelOrigin = null; } var move = operation(cm, function (e) { - if (!e_button(e)) { done(e); } + if (e.buttons === 0 || !e_button(e)) { done(e); } else { extend(e); } }); var up = operation(cm, done); cm.state.selectingText = up; - on(document, "mousemove", move); - on(document, "mouseup", up); + on(display.wrapper.ownerDocument, "mousemove", move); + on(display.wrapper.ownerDocument, "mouseup", up); } // Used when mouse-selecting to adjust the anchor to the proper side @@ -7618,6 +7632,7 @@ function defineOptions(CodeMirror) { clearCaches(cm); regChange(cm); }, true); + option("lineSeparator", null, function (cm, val) { cm.doc.lineSep = val; if (!val) { return } @@ -7719,6 +7734,7 @@ function defineOptions(CodeMirror) { option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; }); option("autofocus", null); option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true); + option("phrases", null); } function guttersChanged(cm) { @@ -7770,6 +7786,7 @@ function CodeMirror$1(place, options) { var doc = options.value; if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction); } + else if (options.mode) { doc.modeOption = options.mode; } this.doc = doc; var input = new CodeMirror$1.inputStyles[options.inputStyle](this); @@ -8024,7 +8041,7 @@ function applyTextInput(cm, inserted, deleted, sel, origin) { var paste = cm.state.pasteIncoming || origin == "paste"; var textLines = splitLinesAuto(inserted), multiPaste = null; - // When pasing N lines into N selections, insert one line per selection + // When pasting N lines into N selections, insert one line per selection if (paste && sel.ranges.length > 1) { if (lastCopied && lastCopied.text.join("\n") == inserted) { if (sel.ranges.length % lastCopied.text.length == 0) { @@ -8556,6 +8573,11 @@ var addEditorMethods = function(CodeMirror) { return old }), + phrase: function(phraseText) { + var phrases = this.options.phrases; + return phrases && Object.prototype.hasOwnProperty.call(phrases, phraseText) ? phrases[phraseText] : phraseText + }, + getInputField: function(){return this.display.input.getField()}, getWrapperElement: function(){return this.display.wrapper}, getScrollerElement: function(){return this.display.scroller}, @@ -8760,8 +8782,12 @@ ContentEditableInput.prototype.showSelection = function (info, takeFocus) { this.showMultipleSelections(info); }; +ContentEditableInput.prototype.getSelection = function () { + return this.cm.display.wrapper.ownerDocument.getSelection() +}; + ContentEditableInput.prototype.showPrimarySelection = function () { - var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary(); + var sel = this.getSelection(), cm = this.cm, prim = cm.doc.sel.primary(); var from = prim.from(), to = prim.to(); if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) { @@ -8828,13 +8854,13 @@ ContentEditableInput.prototype.showMultipleSelections = function (info) { }; ContentEditableInput.prototype.rememberSelection = function () { - var sel = window.getSelection(); + var sel = this.getSelection(); this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset; this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset; }; ContentEditableInput.prototype.selectionInEditor = function () { - var sel = window.getSelection(); + var sel = this.getSelection(); if (!sel.rangeCount) { return false } var node = sel.getRangeAt(0).commonAncestorContainer; return contains(this.div, node) @@ -8869,14 +8895,14 @@ ContentEditableInput.prototype.receivedFocus = function () { }; ContentEditableInput.prototype.selectionChanged = function () { - var sel = window.getSelection(); + var sel = this.getSelection(); return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset }; ContentEditableInput.prototype.pollSelection = function () { if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return } - var sel = window.getSelection(), cm = this.cm; + var sel = this.getSelection(), cm = this.cm; // On Android Chrome (version 56, at least), backspacing into an // uneditable block element will put the cursor in that element, // and then, because it's not editable, hide the virtual keyboard. @@ -9010,7 +9036,7 @@ ContentEditableInput.prototype.setUneditable = function (node) { }; ContentEditableInput.prototype.onKeyPress = function (e) { - if (e.charCode == 0) { return } + if (e.charCode == 0 || this.composing) { return } e.preventDefault(); if (!this.cm.isReadOnly()) { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); } @@ -9050,12 +9076,13 @@ function isInGutter(node) { function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos } function domTextBetween(cm, from, to, fromLine, toLine) { - var text = "", closing = false, lineSep = cm.doc.lineSeparator(); + var text = "", closing = false, lineSep = cm.doc.lineSeparator(), extraLinebreak = false; function recognizeMarker(id) { return function (marker) { return marker.id == id; } } function close() { if (closing) { text += lineSep; - closing = false; + if (extraLinebreak) { text += lineSep; } + closing = extraLinebreak = false; } } function addText(str) { @@ -9067,8 +9094,8 @@ function domTextBetween(cm, from, to, fromLine, toLine) { function walk(node) { if (node.nodeType == 1) { var cmText = node.getAttribute("cm-text"); - if (cmText != null) { - addText(cmText || node.textContent.replace(/\u200b/g, "")); + if (cmText) { + addText(cmText); return } var markerID = node.getAttribute("cm-marker"), range$$1; @@ -9079,19 +9106,24 @@ function domTextBetween(cm, from, to, fromLine, toLine) { return } if (node.getAttribute("contenteditable") == "false") { return } - var isBlock = /^(pre|div|p)$/i.test(node.nodeName); + var isBlock = /^(pre|div|p|li|table|br)$/i.test(node.nodeName); + if (!/^br$/i.test(node.nodeName) && node.textContent.length == 0) { return } + if (isBlock) { close(); } for (var i = 0; i < node.childNodes.length; i++) { walk(node.childNodes[i]); } + + if (/^(pre|p)$/i.test(node.nodeName)) { extraLinebreak = true; } if (isBlock) { closing = true; } } else if (node.nodeType == 3) { - addText(node.nodeValue); + addText(node.nodeValue.replace(/\u200b/g, "").replace(/\u00a0/g, " ")); } } for (;;) { walk(from); if (from == to) { break } from = from.nextSibling; + extraLinebreak = false; } return text } @@ -9192,13 +9224,10 @@ TextareaInput.prototype.init = function (display) { var this$1 = this; var input = this, cm = this.cm; + this.createField(display); + var te = this.textarea; - // Wraps and hides input textarea - var div = this.wrapper = hiddenTextarea(); - // The semihidden textarea that is focused when the editor is - // focused, and receives input. - var te = this.textarea = div.firstChild; - display.wrapper.insertBefore(div, display.wrapper.firstChild); + display.wrapper.insertBefore(this.wrapper, display.wrapper.firstChild); // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) if (ios) { te.style.width = "0px"; } @@ -9265,6 +9294,14 @@ TextareaInput.prototype.init = function (display) { }); }; +TextareaInput.prototype.createField = function (_display) { + // Wraps and hides input textarea + this.wrapper = hiddenTextarea(); + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + this.textarea = this.wrapper.firstChild; +}; + TextareaInput.prototype.prepareSelection = function () { // Redraw the selection and/or cursor var cm = this.cm, display = cm.display, doc = cm.doc; @@ -9658,7 +9695,7 @@ CodeMirror$1.fromTextArea = fromTextArea; addLegacyProps(CodeMirror$1); -CodeMirror$1.version = "5.31.1"; +CodeMirror$1.version = "5.39.3"; return CodeMirror$1; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/comment.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/comment.js index 84c67edf789..8394e85a4da 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/comment.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/comment.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/markselection.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/markselection.js index 1602acc3deb..adfaa62d1a6 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/markselection.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/markselection.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Because sometimes you need to mark the selected *text*. // diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/matchbrackets.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/matchbrackets.js index 4d7a230855a..c918c3f99f1 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/matchbrackets.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/matchbrackets.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -102,18 +102,23 @@ } } - var currentlyHighlighted = null; function doMatchBrackets(cm) { cm.operation(function() { - if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} - currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); + if (cm.state.matchBrackets.currentlyHighlighted) { + cm.state.matchBrackets.currentlyHighlighted(); + cm.state.matchBrackets.currentlyHighlighted = null; + } + cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); }); } CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { if (old && old != CodeMirror.Init) { cm.off("cursorActivity", doMatchBrackets); - if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} + if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) { + cm.state.matchBrackets.currentlyHighlighted(); + cm.state.matchBrackets.currentlyHighlighted = null; + } } if (val) { cm.state.matchBrackets = typeof val == "object" ? val : {}; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/multiplex.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/multiplex.js index 3d8b34c4520..738ea98a0de 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/multiplex.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/multiplex.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -50,7 +50,15 @@ CodeMirror.multiplexingMode = function(outer /*, others */) { if (found == stream.pos) { if (!other.parseDelimiters) stream.match(other.open); state.innerActive = other; - state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); + + // Get the outer indent, making sure to handle CodeMirror.Pass + var outerIndent = 0; + if (outer.indent) { + var possibleOuterIndent = outer.indent(state.outer, ""); + if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent; + } + + state.inner = CodeMirror.startState(other.mode, outerIndent); return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open"); } else if (found != -1 && found < cutOff) { cutOff = found; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/overlay.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/overlay.js index 4a9f99a072e..839d9e552ec 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm/overlay.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/overlay.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Utility function that allows modes to be combined. The mode given // as the base argument takes care of most of the normal mode diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_headless/headlesscodemirror.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_headless/headlesscodemirror.js index f7aec5b6d52..690a123ef99 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_headless/headlesscodemirror.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_headless/headlesscodemirror.js @@ -2,7 +2,7 @@ // from CodeMirror distribution (function(window) { // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE window.CodeMirror = {}; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clike.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clike.js index 02a85319ff0..42033bd0a0d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clike.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clike.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -216,15 +216,15 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { indent: function(state, textAfter) { if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass; var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); + var closing = firstChar == ctx.type; if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; if (parserConfig.dontIndentStatements) while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info)) ctx = ctx.prev if (hooks.indent) { - var hook = hooks.indent(state, ctx, textAfter); + var hook = hooks.indent(state, ctx, textAfter, indentUnit); if (typeof hook == "number") return hook } - var closing = firstChar == ctx.type; var switchBlock = ctx.prev && ctx.prev.info == "switch"; if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) { while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev @@ -374,7 +374,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { blockKeywords: words("case do else for if switch while struct"), defKeywords: words("struct"), typeFirstDefinitions: true, - atoms: words("null true false"), + atoms: words("NULL true false"), hooks: {"#": cppHook, "*": pointerHook}, modeProps: {fold: ["brace", "include"]} }); @@ -390,7 +390,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { blockKeywords: words("catch class do else finally for if struct switch try while"), defKeywords: words("class namespace struct enum union"), typeFirstDefinitions: true, - atoms: words("true false null"), + atoms: words("true false NULL"), dontIndentStatements: /^template$/, isIdentifierChar: /[\w\$_~\xa1-\uffff]/, hooks: { @@ -489,6 +489,27 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { return "string"; } + function tokenNestedComment(depth) { + return function (stream, state) { + var ch + while (ch = stream.next()) { + if (ch == "*" && stream.eat("/")) { + if (depth == 1) { + state.tokenize = null + break + } else { + state.tokenize = tokenNestedComment(depth - 1) + return state.tokenize(stream, state) + } + } else if (ch == "/" && stream.eat("*")) { + state.tokenize = tokenNestedComment(depth + 1) + return state.tokenize(stream, state) + } + } + return "comment" + } + } + def("text/x-scala", { name: "clike", keywords: words( @@ -544,6 +565,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { } else { return false } + }, + + "/": function(stream, state) { + if (!stream.eat("*")) return false + state.tokenize = tokenNestedComment(1) + return state.tokenize(stream, state) } }, modeProps: {closeBrackets: {triples: '"'}} @@ -570,34 +597,51 @@ CodeMirror.defineMode("clike", function(config, parserConfig) { name: "clike", keywords: words( /*keywords*/ - "package as typealias class interface this super val " + - "var fun for is in This throw return " + + "package as typealias class interface this super val operator " + + "var fun for is in This throw return annotation " + "break continue object if else while do try when !in !is as? " + /*soft keywords*/ "file import where by get set abstract enum open inner override private public internal " + "protected catch finally out final vararg reified dynamic companion constructor init " + "sealed field property receiver param sparam lateinit data inline noinline tailrec " + - "external annotation crossinline const operator infix suspend" + "external annotation crossinline const operator infix suspend actual expect setparam" ), types: words( /* package java.lang */ "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + - "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" + "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray " + + "ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy " + + "LazyThreadSafetyMode LongArray Nothing ShortArray Unit" ), intendSwitch: false, indentStatements: false, multiLineStrings: true, - number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, + number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, blockKeywords: words("catch class do else finally for if where try while enum"), defKeywords: words("class val var object interface fun"), atoms: words("true false null this"), hooks: { + "@": function(stream) { + stream.eatWhile(/[\w\$_]/); + return "meta"; + }, '"': function(stream, state) { state.tokenize = tokenKotlinString(stream.match('""')); return state.tokenize(stream, state); + }, + indent: function(state, ctx, textAfter, indentUnit) { + var firstChar = textAfter && textAfter.charAt(0); + if ((state.prevToken == "}" || state.prevToken == ")") && textAfter == "") + return state.indented; + if (state.prevToken == "operator" && textAfter != "}" || + state.prevToken == "variable" && firstChar == "." || + (state.prevToken == "}" || state.prevToken == ")") && firstChar == ".") + return indentUnit * 2 + ctx.indented; + if (ctx.align && ctx.type == "}") + return ctx.indented + (state.context.type == (textAfter || "").charAt(0) ? 0 : indentUnit); } }, modeProps: {closeBrackets: {triples: '"'}} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clojure.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clojure.js index ed6af2c83c1..2015edff148 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clojure.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clojure.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE /** * Author: Hans Engel diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/coffeescript.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/coffeescript.js index ae955db344a..a54e9d5ed0a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/coffeescript.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/coffeescript.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE /** * Link to the project's GitHub page: diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/jsx.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/jsx.js index 45c3024aba3..2c91beb955f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/jsx.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/jsx.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -26,7 +26,7 @@ } CodeMirror.defineMode("jsx", function(config, modeConfig) { - var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false}) + var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false, allowMissingTagName: true}) var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript") function flatXMLIndent(state) { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/livescript.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/livescript.js index 1e363f87699..595e067d16b 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/livescript.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/livescript.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE /** * Link to the project's GitHub page: diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/markdown.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/markdown.js index 61e0c4fc123..442ab6b95b9 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/markdown.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/markdown.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -90,7 +90,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/ , textRE = /^[^#!\[\]*_\\<>` "'(~:]+/ , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w+#-]*)[^\n`]*$/ - , linkDefRE = /^\s*\[[^\]]+?\]:\s*\S+(\s*\S*\s*)?$/ // naive link-definition + , linkDefRE = /^\s*\[[^\]]+?\]:.*$/ // naive link-definition , punctuation = /[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~\u2014]/ , expandedTab = " " // CommonMark specifies tab as 4 spaces @@ -126,8 +126,17 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { // Reset state.indentedCode state.indentedCode = false; if (state.f == htmlBlock) { - state.f = inlineNormal; - state.block = blockNormal; + var exit = htmlModeMissing + if (!exit) { + var inner = CodeMirror.innerMode(htmlMode, state.htmlState) + exit = inner.mode.name == "xml" && inner.state.tagStart === null && + (!inner.state.context && inner.state.tokenize.isInText) + } + if (exit) { + state.f = inlineNormal; + state.block = blockNormal; + state.htmlState = null; + } } // Reset state.trailingSpace state.trailingSpace = 0; @@ -497,6 +506,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { } if (ch === '[' && !state.image) { + if (state.linkText && stream.match(/^.*?\]/)) return getType(state) state.linkText = true; if (modeCfg.highlightFormatting) state.formatting = "link"; return getType(state); @@ -534,7 +544,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { return type + tokenTypes.linkEmail; } - if (modeCfg.xml && ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) { + if (modeCfg.xml && ch === '<' && stream.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i, false)) { var end = stream.string.indexOf(">", stream.pos); if (end != -1) { var atts = stream.string.substring(stream.start, end); @@ -619,7 +629,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { } if (ch === ' ') { - if (stream.match(/ +$/, false)) { + if (stream.match(/^ +$/, false)) { state.trailingSpace++; } else if (state.trailingSpace) { state.trailingSpaceNewLine = true; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/php.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/php.js index 589c9a66395..80e2f20bf18 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/php.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/php.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/python.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/python.js index c3187932073..623c03f7f0f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/python.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/python.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -41,7 +41,7 @@ CodeMirror.defineMode("python", function(conf, parserConf) { var ERRORCLASS = "error"; - var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/; + var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.\\]/; // (Backwards-compatiblity with old, cumbersome config system) var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters, parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@])/] @@ -62,7 +62,7 @@ var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/; myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]); myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]); - var stringPrefixes = new RegExp("^(([rbuf]|(br))?('{3}|\"{3}|['\"]))", "i"); + var stringPrefixes = new RegExp("^(([rbuf]|(br)|(fr))?('{3}|\"{3}|['\"]))", "i"); } else { var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/; myKeywords = myKeywords.concat(["exec", "print"]); @@ -76,9 +76,10 @@ // tokenizers function tokenBase(stream, state) { - if (stream.sol()) state.indent = stream.indentation() + var sol = stream.sol() && state.lastToken != "\\" + if (sol) state.indent = stream.indentation() // Handle scope changes - if (stream.sol() && top(state).type == "py") { + if (sol && top(state).type == "py") { var scopeOffset = top(state).offset; if (stream.eatSpace()) { var lineOffset = stream.indentation(); @@ -100,13 +101,8 @@ function tokenBaseInner(stream, state) { if (stream.eatSpace()) return null; - var ch = stream.peek(); - // Handle Comments - if (ch == "#") { - stream.skipToEnd(); - return "comment"; - } + if (stream.match(/^#.*/)) return "comment"; // Handle Number Literals if (stream.match(/^[0-9\.]/, false)) { @@ -146,8 +142,14 @@ // Handle Strings if (stream.match(stringPrefixes)) { - state.tokenize = tokenStringFactory(stream.current()); - return state.tokenize(stream, state); + var isFmtString = stream.current().toLowerCase().indexOf('f') !== -1; + if (!isFmtString) { + state.tokenize = tokenStringFactory(stream.current()); + return state.tokenize(stream, state); + } else { + state.tokenize = formatStringFactory(stream.current(), state.tokenize); + return state.tokenize(stream, state); + } } for (var i = 0; i < operators.length; i++) @@ -178,6 +180,77 @@ return ERRORCLASS; } + function formatStringFactory(delimiter, tokenOuter) { + while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0) + delimiter = delimiter.substr(1); + + var singleline = delimiter.length == 1; + var OUTCLASS = "string"; + + function tokenFString(stream, state) { + // inside f-str Expression + if (stream.match(delimiter)) { + // expression ends pre-maturally, but very common in editing + // Could show error to remind users to close brace here + state.tokenize = tokenString + return OUTCLASS; + } else if (stream.match('{')) { + // starting brace, if not eaten below + return "punctuation"; + } else if (stream.match('}')) { + // return to regular inside string state + state.tokenize = tokenString + return "punctuation"; + } else { + // use tokenBaseInner to parse the expression + return tokenBaseInner(stream, state); + } + } + + function tokenString(stream, state) { + while (!stream.eol()) { + stream.eatWhile(/[^'"\{\}\\]/); + if (stream.eat("\\")) { + stream.next(); + if (singleline && stream.eol()) + return OUTCLASS; + } else if (stream.match(delimiter)) { + state.tokenize = tokenOuter; + return OUTCLASS; + } else if (stream.match('{{')) { + // ignore {{ in f-str + return OUTCLASS; + } else if (stream.match('{', false)) { + // switch to nested mode + state.tokenize = tokenFString + if (stream.current()) { + return OUTCLASS; + } else { + // need to return something, so eat the starting { + stream.next(); + return "punctuation"; + } + } else if (stream.match('}}')) { + return OUTCLASS; + } else if (stream.match('}')) { + // single } in f-string is an error + return ERRORCLASS; + } else { + stream.eat(/['"]/); + } + } + if (singleline) { + if (parserConf.singleLineStringErrors) + return ERRORCLASS; + else + state.tokenize = tokenOuter; + } + return OUTCLASS; + } + tokenString.isString = true; + return tokenString; + } + function tokenStringFactory(delimiter) { while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0) delimiter = delimiter.substr(1); @@ -258,14 +331,16 @@ if (current == ":" && !state.lambda && top(state).type == "py") pushPyScope(state); - var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1; - if (delimiter_index != -1) - pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1)); + if (current.length == 1 && !/string|comment/.test(style)) { + var delimiter_index = "[({".indexOf(current); + if (delimiter_index != -1) + pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1)); - delimiter_index = "])}".indexOf(current); - if (delimiter_index != -1) { - if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent - else return ERRORCLASS; + delimiter_index = "])}".indexOf(current); + if (delimiter_index != -1) { + if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent + else return ERRORCLASS; + } } if (state.dedent > 0 && stream.eol() && top(state).type == "py") { if (state.scopes.length > 1) state.scopes.pop(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/shell.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/shell.js index 9b8b90b3056..0e667e6a54f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/shell.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/shell.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -31,7 +31,7 @@ CodeMirror.defineMode('shell', function() { // Commands define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' + 'curl cut diff echo find gawk gcc get git grep hg kill killall ln ls make ' + - 'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' + + 'mkdir openssl mv nc nl node npm ping ps restart rm rmdir sed service sh ' + 'shopt shred source sort sleep ssh start stop su sudo svn tee telnet top ' + 'touch vi vim wall wc wget who write yes zsh'); @@ -84,29 +84,38 @@ CodeMirror.defineMode('shell', function() { function tokenString(quote, style) { var close = quote == "(" ? ")" : quote == "{" ? "}" : quote return function(stream, state) { - var next, end = false, escaped = false; + var next, escaped = false; while ((next = stream.next()) != null) { if (next === close && !escaped) { - end = true; + state.tokens.shift(); break; - } - if (next === '$' && !escaped && quote !== "'") { + } else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) { escaped = true; stream.backUp(1); state.tokens.unshift(tokenDollar); break; - } - if (!escaped && next === quote && quote !== close) { + } else if (!escaped && quote !== close && next === quote) { state.tokens.unshift(tokenString(quote, style)) return tokenize(stream, state) + } else if (!escaped && /['"]/.test(next) && !/['"]/.test(quote)) { + state.tokens.unshift(tokenStringStart(next, "string")); + stream.backUp(1); + break; } escaped = !escaped && next === '\\'; } - if (end) state.tokens.shift(); return style; }; }; + function tokenStringStart(quote, style) { + return function(stream, state) { + state.tokens[0] = tokenString(quote, style) + stream.next() + return tokenize(stream, state) + } + } + var tokenDollar = function(stream, state) { if (state.tokens.length > 1) stream.eat('$'); var ch = stream.next() diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/stylus.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/stylus.js index b83be16f42b..dbe241d6132 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/stylus.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/stylus.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Stylus mode created by Dmitry Kiselyov http://git.io/AaRB @@ -76,7 +76,7 @@ if (ch == "#") { stream.next(); // Hex color - if (stream.match(/^[0-9a-f]{6}|[0-9a-f]{3}/i)) { + if (stream.match(/^[0-9a-f]{3}([0-9a-f]([0-9a-f]{2}){0,2})?\b/i)) { return ["atom", "atom"]; } // ID selector diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/css.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/css.js index 00e9b3df132..8b5722905de 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/css.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/css.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -77,9 +77,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) { return ret("qualifier", "qualifier"); } else if (/[:;{}\[\]\(\)]/.test(ch)) { return ret(null, ch); - } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) || - (ch == "d" && stream.match("omain(")) || - (ch == "r" && stream.match("egexp("))) { + } else if (((ch == "u" || ch == "U") && stream.match(/rl(-prefix)?\(/i)) || + ((ch == "d" || ch == "D") && stream.match("omain(", true, true)) || + ((ch == "r" || ch == "R") && stream.match("egexp(", true, true))) { stream.backUp(1); state.tokenize = tokenParenthesized; return ret("property", "word"); @@ -162,16 +162,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) { return pushContext(state, stream, "block"); } else if (type == "}" && state.context.prev) { return popContext(state); - } else if (supportsAtComponent && /@component/.test(type)) { + } else if (supportsAtComponent && /@component/i.test(type)) { return pushContext(state, stream, "atComponentBlock"); - } else if (/^@(-moz-)?document$/.test(type)) { + } else if (/^@(-moz-)?document$/i.test(type)) { return pushContext(state, stream, "documentTypes"); - } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) { + } else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) { return pushContext(state, stream, "atBlock"); - } else if (/^@(font-face|counter-style)/.test(type)) { + } else if (/^@(font-face|counter-style)/i.test(type)) { state.stateArg = type; return "restricted_atBlock_before"; - } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { + } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) { return "keyframes"; } else if (type && type.charAt(0) == "@") { return pushContext(state, stream, "at"); @@ -793,7 +793,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { }, "@": function(stream) { if (stream.eat("{")) return [null, "interpolation"]; - if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false; + if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false; stream.eatWhile(/[\w\\\-]/); if (stream.match(/^\s*:/, false)) return ["variable-2", "variable-definition"]; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlembedded.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlembedded.js index 464dc57f838..439e63a4276 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlembedded.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlembedded.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -14,7 +14,16 @@ "use strict"; CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { + var closeComment = parserConfig.closeComment || "--%>" return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), { + open: parserConfig.openComment || "<%--", + close: closeComment, + delimStyle: "comment", + mode: {token: function(stream) { + stream.skipTo(closeComment) || stream.skipToEnd() + return "comment" + }} + }, { open: parserConfig.open || parserConfig.scriptStartRegex || "<%", close: parserConfig.close || parserConfig.scriptEndRegex || "%>", mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec) diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlmixed.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlmixed.js index 33398ec5c0b..c9925384776 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlmixed.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlmixed.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/javascript.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/javascript.js index 139e53dfe4c..a31ffff8ef3 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/javascript.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/javascript.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -26,7 +26,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d"); var operator = kw("operator"), atom = {type: "atom", style: "atom"}; - var jsKeywords = { + return { "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C, "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"), @@ -38,33 +38,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { "yield": C, "export": kw("export"), "import": kw("import"), "extends": C, "await": C }; - - // Extend the 'normal' keywords with the TypeScript language extensions - if (isTS) { - var type = {type: "variable", style: "type"}; - var tsKeywords = { - // object-like things - "interface": kw("class"), - "implements": C, - "namespace": C, - - // scope modifiers - "public": kw("modifier"), - "private": kw("modifier"), - "protected": kw("modifier"), - "abstract": kw("modifier"), - "readonly": kw("modifier"), - - // types - "string": type, "number": type, "boolean": type, "any": type - }; - - for (var attr in tsKeywords) { - jsKeywords[attr] = tsKeywords[attr]; - } - } - - return jsKeywords; }(); var isOperatorChar = /[+\-*&%=<>!?|~^@]/; @@ -102,17 +75,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { return ret(ch); } else if (ch == "=" && stream.eat(">")) { return ret("=>", "operator"); - } else if (ch == "0" && stream.eat(/x/i)) { - stream.eatWhile(/[\da-f]/i); - return ret("number", "number"); - } else if (ch == "0" && stream.eat(/o/i)) { - stream.eatWhile(/[0-7]/i); - return ret("number", "number"); - } else if (ch == "0" && stream.eat(/b/i)) { - stream.eatWhile(/[01]/i); + } else if (ch == "0" && stream.match(/^(?:x[\da-f]+|o[0-7]+|b[01]+)n?/i)) { return ret("number", "number"); } else if (/\d/.test(ch)) { - stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); + stream.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/); return ret("number", "number"); } else if (ch == "/") { if (stream.eat("*")) { @@ -123,7 +89,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { return ret("comment", "comment"); } else if (expressionAllowed(stream, state, 1)) { readRegexp(stream); - stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); + stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/); return ret("regexp", "string-2"); } else { stream.eat("="); @@ -153,7 +119,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { var kw = keywords[word] return ret(kw.type, kw.style, word) } - if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\(\w]/, false)) + if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/, false)) return ret("async", "keyword", word) } return ret("variable", "variable", word) @@ -292,35 +258,68 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { pass.apply(null, arguments); return true; } + function inList(name, list) { + for (var v = list; v; v = v.next) if (v.name == name) return true + return false; + } function register(varname) { - function inList(list) { - for (var v = list; v; v = v.next) - if (v.name == varname) return true; - return false; - } var state = cx.state; cx.marked = "def"; if (state.context) { - if (inList(state.localVars)) return; - state.localVars = {name: varname, next: state.localVars}; + if (state.lexical.info == "var" && state.context && state.context.block) { + // FIXME function decls are also not block scoped + var newContext = registerVarScoped(varname, state.context) + if (newContext != null) { + state.context = newContext + return + } + } else if (!inList(varname, state.localVars)) { + state.localVars = new Var(varname, state.localVars) + return + } + } + // Fall through means this is global + if (parserConfig.globalVars && !inList(varname, state.globalVars)) + state.globalVars = new Var(varname, state.globalVars) + } + function registerVarScoped(varname, context) { + if (!context) { + return null + } else if (context.block) { + var inner = registerVarScoped(varname, context.prev) + if (!inner) return null + if (inner == context.prev) return context + return new Context(inner, context.vars, true) + } else if (inList(varname, context.vars)) { + return context } else { - if (inList(state.globalVars)) return; - if (parserConfig.globalVars) - state.globalVars = {name: varname, next: state.globalVars}; + return new Context(context.prev, new Var(varname, context.vars), false) } } + function isModifier(name) { + return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly" + } + // Combinators - var defaultVars = {name: "this", next: {name: "arguments"}}; + function Context(prev, vars, block) { this.prev = prev; this.vars = vars; this.block = block } + function Var(name, next) { this.name = name; this.next = next } + + var defaultVars = new Var("this", new Var("arguments", null)) function pushcontext() { - cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; - cx.state.localVars = defaultVars; + cx.state.context = new Context(cx.state.context, cx.state.localVars, false) + cx.state.localVars = defaultVars + } + function pushblockcontext() { + cx.state.context = new Context(cx.state.context, cx.state.localVars, true) + cx.state.localVars = null } function popcontext() { - cx.state.localVars = cx.state.context.vars; - cx.state.context = cx.state.context.prev; + cx.state.localVars = cx.state.context.vars + cx.state.context = cx.state.context.prev } + popcontext.lex = true function pushlex(type, info) { var result = function() { var state = cx.state, indent = state.indented; @@ -345,19 +344,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { function expect(wanted) { function exp(type) { if (type == wanted) return cont(); - else if (wanted == ";") return pass(); + else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass(); else return cont(exp); }; return exp; } function statement(type, value) { - if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); + if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex); if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex); if (type == "keyword b") return cont(pushlex("form"), statement, poplex); if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex); if (type == "debugger") return cont(expect(";")); - if (type == "{") return cont(pushlex("}"), block, poplex); + if (type == "{") return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext); if (type == ";") return cont(); if (type == "if") { if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) @@ -366,44 +365,51 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { } if (type == "function") return cont(functiondef); if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); + if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), className, poplex); } if (type == "variable") { - if (isTS && value == "type") { - cx.marked = "keyword" - return cont(typeexpr, expect("operator"), typeexpr, expect(";")); - } else if (isTS && value == "declare") { + if (isTS && value == "declare") { cx.marked = "keyword" return cont(statement) - } else if (isTS && (value == "module" || value == "enum") && cx.stream.match(/^\s*\w/, false)) { + } else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) { + cx.marked = "keyword" + if (value == "enum") return cont(enumdef); + else if (value == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";")); + else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex) + } else if (isTS && value == "namespace") { cx.marked = "keyword" - return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex) + return cont(pushlex("form"), expression, block, poplex) + } else if (isTS && value == "abstract") { + cx.marked = "keyword" + return cont(statement) } else { return cont(pushlex("stat"), maybelabel); } } - if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), - block, poplex, poplex); + if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext, + block, poplex, poplex, popcontext); if (type == "case") return cont(expression, expect(":")); if (type == "default") return cont(expect(":")); - if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), - statement, poplex, popcontext); - if (type == "class") return cont(pushlex("form"), className, poplex); + if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext); if (type == "export") return cont(pushlex("stat"), afterExport, poplex); if (type == "import") return cont(pushlex("stat"), afterImport, poplex); if (type == "async") return cont(statement) if (value == "@") return cont(expression, statement) return pass(pushlex("stat"), expression, expect(";"), poplex); } - function expression(type) { - return expressionInner(type, false); + function maybeCatchBinding(type) { + if (type == "(") return cont(funarg, expect(")")) } - function expressionNoComma(type) { - return expressionInner(type, true); + function expression(type, value) { + return expressionInner(type, value, false); + } + function expressionNoComma(type, value) { + return expressionInner(type, value, true); } function parenExpr(type) { if (type != "(") return pass() return cont(pushlex(")"), expression, expect(")"), poplex) } - function expressionInner(type, noComma) { + function expressionInner(type, value, noComma) { if (cx.state.fatArrowAt == cx.stream.start) { var body = noComma ? arrowBodyNoComma : arrowBody; if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext); @@ -413,7 +419,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); if (type == "function") return cont(functiondef, maybeop); - if (type == "class") return cont(pushlex("form"), classExpression, poplex); + if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); } if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression); if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); @@ -421,6 +427,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (type == "{") return contCommasep(objprop, "}", null, maybeop); if (type == "quasi") return pass(quasi, maybeop); if (type == "new") return cont(maybeTarget(noComma)); + if (type == "import") return cont(expression); return cont(); } function maybeexpression(type) { @@ -438,6 +445,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); if (type == "operator") { if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me); + if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false)) + return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me); if (value == "?") return cont(expression, expect(":"), expr); return cont(expr); } @@ -509,10 +518,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { return cont(afterprop); } else if (type == "jsonld-keyword") { return cont(afterprop); - } else if (type == "modifier") { + } else if (isTS && isModifier(value)) { + cx.marked = "keyword" return cont(objprop) } else if (type == "[") { - return cont(expression, expect("]"), afterprop); + return cont(expression, maybetype, expect("]"), afterprop); } else if (type == "spread") { return cont(expressionNoComma, afterprop); } else if (value == "*") { @@ -564,20 +574,32 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (value == "?") return cont(maybetype); } } + function mayberettype(type) { + if (isTS && type == ":") { + if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr) + else return cont(typeexpr) + } + } + function isKW(_, value) { + if (value == "is") { + cx.marked = "keyword" + return cont() + } + } function typeexpr(type, value) { + if (value == "keyof" || value == "typeof") { + cx.marked = "keyword" + return cont(value == "keyof" ? typeexpr : expressionNoComma) + } if (type == "variable" || value == "void") { - if (value == "keyof") { - cx.marked = "keyword" - return cont(typeexpr) - } else { - cx.marked = "type" - return cont(afterType) - } + cx.marked = "type" + return cont(afterType) } if (type == "string" || type == "number" || type == "atom") return cont(afterType); if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType) if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType) if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType) + if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr) } function maybeReturnType(type) { if (type == "=>") return cont(typeexpr) @@ -594,15 +616,16 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { return cont(expression, maybetype, expect("]"), typeprop) } } - function typearg(type) { - if (type == "variable") return cont(typearg) - else if (type == ":") return cont(typeexpr) + function typearg(type, value) { + if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg) + if (type == ":") return cont(typeexpr) + return pass(typeexpr) } function afterType(type, value) { if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) - if (value == "|" || type == ".") return cont(typeexpr) + if (value == "|" || type == "." || value == "&") return cont(typeexpr) if (type == "[") return cont(expect("]"), afterType) - if (value == "extends") return cont(typeexpr) + if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) } } function maybeTypeArgs(_, value) { if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) @@ -613,11 +636,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { function maybeTypeDefault(_, value) { if (value == "=") return cont(typeexpr) } - function vardef() { + function vardef(_, value) { + if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)} return pass(pattern, maybetype, maybeAssign, vardefCont); } function pattern(type, value) { - if (type == "modifier") return cont(pattern) + if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) } if (type == "variable") { register(value); return cont(); } if (type == "spread") return cont(pattern); if (type == "[") return contCommasep(pattern, "]"); @@ -642,7 +666,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { function maybeelse(type, value) { if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); } - function forspec(type) { + function forspec(type, value) { + if (value == "await") return cont(forspec); if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); } function forspec1(type) { @@ -666,12 +691,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { function functiondef(type, value) { if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} if (type == "variable") {register(value); return cont(functiondef);} - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext); + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext); if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef) } function funarg(type, value) { if (value == "@") cont(expression, funarg) - if (type == "spread" || type == "modifier") return cont(funarg); + if (type == "spread") return cont(funarg); + if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); } return pass(pattern, maybetype, maybeAssign); } function classExpression(type, value) { @@ -684,14 +710,16 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { } function classNameAfter(type, value) { if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter) - if (value == "extends" || value == "implements" || (isTS && type == ",")) + if (value == "extends" || value == "implements" || (isTS && type == ",")) { + if (value == "implements") cx.marked = "keyword"; return cont(isTS ? typeexpr : expression, classNameAfter); + } if (type == "{") return cont(pushlex("}"), classBody, poplex); } function classBody(type, value) { - if (type == "modifier" || type == "async" || + if (type == "async" || (type == "variable" && - (value == "static" || value == "get" || value == "set") && + (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) && cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) { cx.marked = "keyword"; return cont(classBody); @@ -701,7 +729,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { return cont(isTS ? classfield : functiondef, classBody); } if (type == "[") - return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody) + return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody) if (value == "*") { cx.marked = "keyword"; return cont(classBody); @@ -728,6 +756,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { } function afterImport(type) { if (type == "string") return cont(); + if (type == "(") return pass(expression); return pass(importSpec, maybeMoreImports, maybeFrom); } function importSpec(type, value) { @@ -749,6 +778,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { if (type == "]") return cont(); return pass(commasep(expressionNoComma, "]")); } + function enumdef() { + return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex) + } + function enummember() { + return pass(pattern, maybeAssign); + } function isContinuedStatement(state, textAfter) { return state.lastType == "operator" || state.lastType == "," || @@ -772,7 +807,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { cc: [], lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), localVars: parserConfig.localVars, - context: parserConfig.localVars && {vars: parserConfig.localVars}, + context: parserConfig.localVars && new Context(null, null, false), indented: basecolumn || 0 }; if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") @@ -813,7 +848,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { lexical = lexical.prev; var type = lexical.type, closing = firstChar == type; - if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); + if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0); else if (type == "form" && firstChar == "{") return lexical.indented; else if (type == "form") return lexical.indented + indentUnit; else if (type == "stat") diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/xml.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/xml.js index a36573949eb..b67bf850b1f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/xml.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/xml.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -52,6 +52,7 @@ var xmlConfig = { doNotIndent: {}, allowUnquoted: false, allowMissing: false, + allowMissingTagName: false, caseFold: false } @@ -162,8 +163,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { stream.next(); } return style; - }; + } } + function doctype(depth) { return function(stream, state) { var ch; @@ -226,6 +228,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { state.tagName = stream.current(); setStyle = "tag"; return attrState; + } else if (config.allowMissingTagName && type == "endTag") { + setStyle = "tag bracket"; + return attrState(type, stream, state); } else { setStyle = "error"; return tagNameState; @@ -244,6 +249,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { setStyle = "tag error"; return closeStateErr; } + } else if (config.allowMissingTagName && type == "endTag") { + setStyle = "tag bracket"; + return closeState(type, stream, state); } else { setStyle = "error"; return closeStateErr; @@ -391,4 +399,4 @@ CodeMirror.defineMIME("application/xml", "xml"); if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); -});
\ No newline at end of file +}); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js b/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js index 75d32a15fd3..ebc106c12ec 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js @@ -92,6 +92,14 @@ Common.ResourceType = class { } /** + * @param {string} ext + * @return {string|undefined} + */ + static mimeFromExtension(ext) { + return Common.ResourceType._mimeTypeByExtension.get(ext); + } + + /** * @return {string} */ name() { @@ -123,7 +131,7 @@ Common.ResourceType = class { * @return {boolean} */ isScript() { - return this._name === 'script' || this._name === 'sm-script' || this._name === 'snippet'; + return this._name === 'script' || this._name === 'sm-script'; } /** @@ -219,7 +227,6 @@ Common.resourceTypes = { Fetch: new Common.ResourceType('fetch', 'Fetch', Common.resourceCategories.XHR, true), EventSource: new Common.ResourceType('eventsource', 'EventSource', Common.resourceCategories.XHR, true), Script: new Common.ResourceType('script', 'Script', Common.resourceCategories.Script, true), - Snippet: new Common.ResourceType('snippet', 'Snippet', Common.resourceCategories.Script, true), Stylesheet: new Common.ResourceType('stylesheet', 'Stylesheet', Common.resourceCategories.Stylesheet, true), Image: new Common.ResourceType('image', 'Image', Common.resourceCategories.Image, false), Media: new Common.ResourceType('media', 'Media', Common.resourceCategories.Media, false), diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/ImagePreview.js b/chromium/third_party/blink/renderer/devtools/front_end/components/ImagePreview.js index 4abc3c31009..f278a498908 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/ImagePreview.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/components/ImagePreview.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -BrowserComponents.ImagePreview = class { +Components.ImagePreview = class { /** * @param {!SDK.Target} target * @param {string} originalImageURL @@ -41,7 +41,7 @@ BrowserComponents.ImagePreview = class { function buildContent() { const container = createElement('table'); - UI.appendStyle(container, 'browser_components/imagePreview.css'); + UI.appendStyle(container, 'components/imagePreview.css'); container.className = 'image-preview-container'; const naturalWidth = precomputedFeatures ? precomputedFeatures.naturalWidth : imageElement.naturalWidth; const naturalHeight = precomputedFeatures ? precomputedFeatures.naturalHeight : imageElement.naturalHeight; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js index 9dd411d5946..9ad19488ade 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js @@ -43,7 +43,6 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function( element.style.display = 'inline-block'; const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'components/jsUtils.css'); const contentElement = shadowRoot.createChild('table', 'stack-preview-container'); - const debuggerModel = target ? target.model(SDK.DebuggerModel) : null; let totalHiddenCallFramesCount = 0; /** @@ -59,15 +58,11 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function( const link = linkifier.maybeLinkifyConsoleCallFrame(target, stackFrame); if (link) { link.addEventListener('contextmenu', populateContextMenu.bind(null, link)); - if (debuggerModel) { - const location = debuggerModel.createRawLocationByScriptId( - stackFrame.scriptId, stackFrame.lineNumber, stackFrame.columnNumber); - if (location && Bindings.blackboxManager.isBlackboxedRawLocation(location)) { - row.classList.add('blackboxed'); - ++hiddenCallFrames; - } + const uiLocation = Components.Linkifier.uiLocation(link); + if (uiLocation && Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode)) { + row.classList.add('blackboxed'); + ++hiddenCallFrames; } - row.createChild('td').textContent = ' @ '; row.createChild('td').appendChild(link); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/imagePreview.css b/chromium/third_party/blink/renderer/devtools/front_end/components/imagePreview.css index 08020e5bdec..08020e5bdec 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/imagePreview.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/components/imagePreview.css diff --git a/chromium/third_party/blink/renderer/devtools/front_end/components/module.json b/chromium/third_party/blink/renderer/devtools/front_end/components/module.json index 8986fdfe000..b7b5ca9282e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/components/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/components/module.json @@ -7,11 +7,13 @@ "scripts": [ "JSPresentationUtils.js", "DockController.js", + "ImagePreview.js", "Linkifier.js", "Reload.js", "TargetDetachedDialog.js" ], "resources": [ + "imagePreview.css", "jsUtils.css" ] } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js index c806078b6ee..325fa85556f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js @@ -2,15 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -Console.ConsolePinPane = class extends UI.VBox { +Console.ConsolePinPane = class extends UI.ThrottledWidget { constructor() { - super(true); + super(true, 250); this.registerRequiredCSS('console/consolePinPane.css'); + this.registerRequiredCSS('object_ui/objectValue.css'); this.contentElement.classList.add('console-pins', 'monospace'); this.contentElement.addEventListener('contextmenu', this._contextMenuEventFired.bind(this), false); /** @type {!Set<!Console.ConsolePin>} */ this._pins = new Set(); + this._pinsSetting = Common.settings.createLocalSetting('consolePins', []); + for (const expression of this._pinsSetting.get()) + this.addPin(expression); + } + + _savePins() { + const toSave = Array.from(this._pins).map(pin => pin.expression()); + this._pinsSetting.set(toSave); } /** @@ -23,11 +32,12 @@ Console.ConsolePinPane = class extends UI.VBox { const targetPinElement = target.enclosingNodeOrSelfWithClass('console-pin'); if (targetPinElement) { const targetPin = targetPinElement[Console.ConsolePin._PinSymbol]; - contextMenu.editSection().appendItem(ls`Edit pin`, targetPin.focus.bind(targetPin)); - contextMenu.editSection().appendItem(ls`Remove pin`, this._removePin.bind(this, targetPin)); + contextMenu.editSection().appendItem(ls`Edit expression`, targetPin.focus.bind(targetPin)); + contextMenu.editSection().appendItem(ls`Remove expression`, this._removePin.bind(this, targetPin)); + targetPin.appendToContextMenu(contextMenu); } } - contextMenu.editSection().appendItem(ls`Remove all pins`, this._removeAllPins.bind(this)); + contextMenu.editSection().appendItem(ls`Remove all expressions`, this._removeAllPins.bind(this)); contextMenu.show(); } @@ -42,41 +52,66 @@ Console.ConsolePinPane = class extends UI.VBox { _removePin(pin) { pin.element().remove(); this._pins.delete(pin); + this._savePins(); } /** * @param {string} expression + * @param {boolean=} userGesture */ - addPin(expression) { - const pin = new Console.ConsolePin(expression, this._removePin.bind(this)); + addPin(expression, userGesture) { + const pin = new Console.ConsolePin(expression, this); this.contentElement.appendChild(pin.element()); this._pins.add(pin); - pin.focus(); + this._savePins(); + if (userGesture) + pin.focus(); + this.update(); + } + + /** + * @override + */ + doUpdate() { + if (!this._pins.size || !this.isShowing()) + return Promise.resolve(); + if (this.isShowing()) + this.update(); + const updatePromises = Array.from(this._pins, pin => pin.updatePreview()); + return Promise.all(updatePromises).then(this._updatedForTest.bind(this)); + } + + _updatedForTest() { } }; -Console.ConsolePin = class { +Console.ConsolePin = class extends Common.Object { /** * @param {string} expression - * @param {function(!Console.ConsolePin)} onRemove + * @param {!Console.ConsolePinPane} pinPane */ - constructor(expression, onRemove) { + constructor(expression, pinPane) { + super(); const deletePinIcon = UI.Icon.create('smallicon-cross', 'console-delete-pin'); - deletePinIcon.addEventListener('click', () => onRemove(this)); + deletePinIcon.addEventListener('click', () => pinPane._removePin(this)); const fragment = UI.Fragment.build` <div class='console-pin'> ${deletePinIcon} <div class='console-pin-name' $='name'></div> - <div class='console-pin-preview'>${ls`not available`}</div> + <div class='console-pin-preview' $='preview'>${ls`not available`}</div> </div>`; this._pinElement = fragment.element(); + this._pinPreview = fragment.$('preview'); const nameElement = fragment.$('name'); nameElement.title = expression; this._pinElement[Console.ConsolePin._PinSymbol] = this; + /** @type {?SDK.RemoteObject} */ + this._resultObject = null; /** @type {?UI.TextEditor} */ this._editor = null; + this._committedExpression = expression; this._editorPromise = self.runtime.extension(UI.TextEditorFactory).instance().then(factory => { this._editor = factory.createEditor({ @@ -86,18 +121,34 @@ Console.ConsolePin = class { autoHeight: true, placeholder: ls`Expression` }); + this._editor.configureAutocomplete(ObjectUI.JavaScriptAutocompleteConfig.createConfigForEditor(this._editor)); this._editor.widget().show(nameElement); this._editor.widget().element.classList.add('console-pin-editor'); this._editor.widget().element.tabIndex = -1; this._editor.setText(expression); this._editor.widget().element.addEventListener('keydown', event => { - if (event.key === 'Tab') + if (event.key === 'Tab' && !this._editor.text()) event.consume(); }, true); + this._editor.widget().element.addEventListener('focusout', event => { + const text = this._editor.text(); + const trimmedText = text.trim(); + if (text.length !== trimmedText.length) + this._editor.setText(trimmedText); + this._committedExpression = trimmedText; + pinPane._savePins(); + }); }); } /** + * @return {string} + */ + expression() { + return this._committedExpression; + } + + /** * @return {!Element} */ element() { @@ -109,6 +160,46 @@ Console.ConsolePin = class { this._editor.widget().focus(); this._editor.setSelection(TextUtils.TextRange.createFromLocation(Infinity, Infinity)); } + + /** + * @param {!UI.ContextMenu} contextMenu + */ + appendToContextMenu(contextMenu) { + if (this._resultObject) + contextMenu.appendApplicableItems(this._resultObject); + } + + /** + * @return {!Promise} + */ + async updatePreview() { + if (!this._editor) + return; + const text = this._editor.textWithCurrentSuggestion().trim(); + const isEditing = this._pinElement.hasFocus(); + const throwOnSideEffect = isEditing && text !== this._committedExpression; + const timeout = throwOnSideEffect ? 250 : undefined; + const {preview, result} = await ObjectUI.JavaScriptREPL.evaluateAndBuildPreview( + text, throwOnSideEffect, timeout, !isEditing /* allowErrors */); + this._resultObject = result ? (result.object || null) : null; + const previewText = preview.deepTextContent(); + if (!previewText || previewText !== this._pinPreview.deepTextContent()) { + this._pinPreview.removeChildren(); + if (result && SDK.RuntimeModel.isSideEffectFailure(result)) { + const sideEffectLabel = this._pinPreview.createChild('span', 'object-value-calculate-value-button'); + sideEffectLabel.textContent = `(...)`; + sideEffectLabel.title = ls`Evaluate, allowing side effects`; + } else if (previewText) { + this._pinPreview.appendChild(preview); + } else if (!isEditing) { + this._pinPreview.createTextChild(ls`not available`); + } + this._pinPreview.title = previewText; + } + + const isError = result && result.exceptionDetails && !SDK.RuntimeModel.isSideEffectFailure(result); + this._pinElement.classList.toggle('error-level', isError); + } }; Console.ConsolePin._PinSymbol = Symbol('pinSymbol'); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js index 96070e1e0e6..77f40a15994 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js @@ -5,6 +5,7 @@ Console.ConsolePrompt = class extends UI.Widget { constructor() { super(); + this.registerRequiredCSS('console/consolePrompt.css'); this._addCompletionsFromHistory = true; this._history = new Console.ConsoleHistoryManager(); @@ -23,10 +24,6 @@ Console.ConsolePrompt = class extends UI.Widget { this._eagerEvalSetting.addChangeListener(this._eagerSettingChanged.bind(this)); this._eagerPreviewElement.classList.toggle('hidden', !this._eagerEvalSetting.get()); - // TODO(luoe): split out prompt styles into ConsolePrompt.css. - const pinsEnabled = Runtime.experiments.isEnabled('pinnedExpressions'); - if (pinsEnabled) - this.element.style.marginRight = '20px'; this.element.tabIndex = 0; /** @type {?Promise} */ this._previewRequestForTest = null; @@ -34,6 +31,8 @@ Console.ConsolePrompt = class extends UI.Widget { /** @type {?UI.AutocompleteConfig} */ this._defaultAutocompleteConfig = null; + this._highlightingNode = false; + self.runtime.extension(UI.TextEditorFactory).instance().then(gotFactory.bind(this)); /** @@ -54,13 +53,6 @@ Console.ConsolePrompt = class extends UI.Widget { this._editor.widget().show(this.element); this._editor.addEventListener(UI.TextEditor.Events.TextChanged, this._onTextChanged, this); this._editor.addEventListener(UI.TextEditor.Events.SuggestionChanged, this._onTextChanged, this); - if (pinsEnabled) { - const pinButton = this.element.createChild('span', 'command-pin-button'); - pinButton.title = ls`Pin expression`; - pinButton.addEventListener('click', () => { - this.dispatchEventToListeners(Console.ConsolePrompt.Events.ExpressionPinned, this.text()); - }); - } if (this._isBelowPromptEnabled) this.element.appendChild(this._eagerPreviewElement); @@ -104,40 +96,28 @@ Console.ConsolePrompt = class extends UI.Widget { */ async _requestPreview() { const text = this._editor.textWithCurrentSuggestion().trim(); - const executionContext = UI.context.flavor(SDK.ExecutionContext); - if (!executionContext || !text || text.length > Console.ConsolePrompt._MaxLengthForEvaluation) { - this._innerPreviewElement.removeChildren(); - return; - } - - const options = { - expression: SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text), - includeCommandLineAPI: true, - generatePreview: true, - throwOnSideEffect: true, - timeout: 500 - }; - const result = await executionContext.evaluate(options, true /* userGesture */, false /* awaitPromise */); + const {preview, result} = + await ObjectUI.JavaScriptREPL.evaluateAndBuildPreview(text, true /* throwOnSideEffect */, 500); this._innerPreviewElement.removeChildren(); - if (result.error) - return; - - if (result.exceptionDetails) { - const exception = result.exceptionDetails.exception.description; - if (exception.startsWith('TypeError: ')) - this._innerPreviewElement.textContent = exception; - return; + if (preview.deepTextContent() !== this._editor.textWithCurrentSuggestion().trim()) + this._innerPreviewElement.appendChild(preview); + if (result && result.object && result.object.subtype === 'node') { + this._highlightingNode = true; + SDK.OverlayModel.highlightObjectAsDOMNode(result.object); + } else if (this._highlightingNode) { + this._highlightingNode = false; + SDK.OverlayModel.hideDOMNodeHighlight(); } + } - const {preview, type, subtype, description} = result.object; - if (preview && type === 'object' && subtype !== 'node') { - this._formatter.appendObjectPreview(this._innerPreviewElement, preview, false /* isEntry */); - } else { - const nonObjectPreview = this._formatter.renderPropertyPreview(type, subtype, description.trimEnd(400)); - this._innerPreviewElement.appendChild(nonObjectPreview); + /** + * @override + */ + willHide() { + if (this._highlightingNode) { + this._highlightingNode = false; + SDK.OverlayModel.hideDOMNodeHighlight(); } - if (this._innerPreviewElement.deepTextContent() === this._editor.textWithCurrentSuggestion().trim()) - this._innerPreviewElement.removeChildren(); } /** @@ -262,23 +242,15 @@ Console.ConsolePrompt = class extends UI.Widget { if (!str.length) return; - const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext); - if (!this._isCaretAtEndOfPrompt() || !currentExecutionContext) { - this._appendCommand(str, true); + if (!this._isCaretAtEndOfPrompt()) { + await this._appendCommand(str, true); return; } - const result = await currentExecutionContext.runtimeModel.compileScript(str, '', false, currentExecutionContext.id); - if (str !== this.text()) - return; - const exceptionDetails = result.exceptionDetails; - if (exceptionDetails && - (exceptionDetails.exception.description.startsWith('SyntaxError: Unexpected end of input') || - exceptionDetails.exception.description.startsWith('SyntaxError: Unterminated template literal'))) { + + if (await ObjectUI.JavaScriptAutocomplete.isExpressionComplete(str)) + await this._appendCommand(str, true); + else this._editor.newlineAndIndent(); - this._enterProcessedForTest(); - return; - } - await this._appendCommand(str, true); this._enterProcessedForTest(); } @@ -292,15 +264,10 @@ Console.ConsolePrompt = class extends UI.Widget { if (currentExecutionContext) { const executionContext = currentExecutionContext; const message = SDK.consoleModel.addCommandMessage(executionContext, text); - text = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text); - let preprocessed = false; - if (text.indexOf('await') !== -1) { - const preprocessedText = await Formatter.formatterWorkerPool().preprocessTopLevelAwaitExpressions(text); - preprocessed = !!preprocessedText; - text = preprocessedText || text; - } + const wrappedResult = await ObjectUI.JavaScriptREPL.preprocessExpression(text); SDK.consoleModel.evaluateCommandInConsole( - executionContext, message, text, useCommandLineAPI, /* awaitPromise */ preprocessed); + executionContext, message, wrappedResult.text, useCommandLineAPI, + /* awaitPromise */ wrappedResult.preprocessed); if (Console.ConsolePanel.instance().isShowing()) Host.userMetrics.actionTaken(Host.UserMetrics.Action.CommandEvaluatedInConsolePanel); } @@ -362,12 +329,6 @@ Console.ConsolePrompt = class extends UI.Widget { }; /** - * @const - * @type {number} - */ -Console.ConsolePrompt._MaxLengthForEvaluation = 2000; - -/** * @unrestricted */ Console.ConsoleHistoryManager = class { @@ -458,6 +419,5 @@ Console.ConsoleHistoryManager = class { }; Console.ConsolePrompt.Events = { - ExpressionPinned: Symbol('ExpressionPinned'), TextChanged: Symbol('TextChanged') }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js index d380af97275..598276af7ca 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js @@ -105,9 +105,13 @@ Console.ConsoleView = class extends UI.VBox { toolbar.appendSeparator(); toolbar.appendToolbarItem(this._consoleContextSelector.toolbarItem()); toolbar.appendSeparator(); + if (Runtime.experiments.isEnabled('pinnedExpressions')) { + toolbar.appendToolbarItem(UI.Toolbar.createActionButton( + /** @type {!UI.Action }*/ (UI.actionRegistry.action('console.create-pin')))); + } + toolbar.appendSeparator(); toolbar.appendToolbarItem(this._filter._textFilterUI); toolbar.appendToolbarItem(this._filter._levelMenuButton); - toolbar.appendToolbarItem(groupSimilarToggle); toolbar.appendToolbarItem(this._progressToolbarItem); rightToolbar.appendSeparator(); rightToolbar.appendToolbarItem(this._filterStatusText); @@ -136,6 +140,7 @@ Console.ConsoleView = class extends UI.VBox { settingsToolbarLeft.appendToolbarItem(this._hideNetworkMessagesCheckbox); settingsToolbarLeft.appendToolbarItem(this._preserveLogCheckbox); settingsToolbarLeft.appendToolbarItem(filterByExecutionContextCheckbox); + settingsToolbarLeft.appendToolbarItem(groupSimilarToggle); const settingsToolbarRight = new UI.Toolbar('', settingsPane.element); settingsToolbarRight.makeVertical(); @@ -157,6 +162,10 @@ Console.ConsoleView = class extends UI.VBox { this._pinPane = new Console.ConsolePinPane(); this._pinPane.element.classList.add('console-view-pinpane'); this._pinPane.show(this._contentsElement); + this._pinPane.element.addEventListener('keydown', event => { + if (event.key === 'Enter' && event.ctrlKey) + this._prompt.focus(); + }); } this._viewport = new Console.ConsoleViewport(this); @@ -198,7 +207,6 @@ Console.ConsoleView = class extends UI.VBox { this._prompt = new Console.ConsolePrompt(); this._prompt.show(this._promptElement); this._prompt.element.addEventListener('keydown', this._promptKeyDown.bind(this), true); - this._prompt.addEventListener(Console.ConsolePrompt.Events.ExpressionPinned, this._promptExpressionPinned, this); this._prompt.addEventListener(Console.ConsolePrompt.Events.TextChanged, this._promptTextChanged, this); this._consoleHistoryAutocompleteSetting.addChangeListener(this._consoleHistoryAutocompleteChanged, this); @@ -583,7 +591,7 @@ Console.ConsoleView = class extends UI.VBox { if (!this._currentGroup.messagesHidden()) { const originatingMessage = viewMessage.consoleMessage().originatingMessage(); if (lastMessage && originatingMessage && lastMessage.consoleMessage() === originatingMessage) - lastMessage.toMessageElement().classList.add('console-adjacent-user-command-result'); + viewMessage.toMessageElement().classList.add('console-adjacent-user-command-result'); this._visibleViewMessages.push(viewMessage); this._searchMessage(this._visibleViewMessages.length - 1); @@ -705,6 +713,8 @@ Console.ConsoleView = class extends UI.VBox { _tryToCollapseMessages(viewMessage, lastMessage) { const timestampsShown = this._timestampsSetting.get(); if (!timestampsShown && lastMessage && !viewMessage.consoleMessage().isGroupMessage() && + viewMessage.consoleMessage().type !== SDK.ConsoleMessage.MessageType.Command && + viewMessage.consoleMessage().type !== SDK.ConsoleMessage.MessageType.Result && viewMessage.consoleMessage().isEqual(lastMessage.consoleMessage())) { lastMessage.incrementRepeatCount(); if (viewMessage.isLastInSimilarGroup()) @@ -1155,14 +1165,6 @@ Console.ConsoleView = class extends UI.VBox { this._updateStickToBottomOnMouseUp(); } - /** - * @param {!Common.Event} event - */ - _promptExpressionPinned(event) { - const text = /** @type {string} */ (event.data); - this._pinPane.addPin(text); - } - _promptTextChanged() { this._viewport.setStickToBottom(this._isScrolledToBottom()); this._promptTextChangedForTest(); @@ -1505,6 +1507,11 @@ Console.ConsoleView.ActionDelegate = class { case 'console.clear.history': Console.ConsoleView.instance()._clearHistory(); return true; + case 'console.create-pin': + if (Runtime.experiments.isEnabled('pinnedExpressions')) { + Console.ConsoleView.instance()._pinPane.addPin('', true /* userGesture */); + return true; + } } return false; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js index fdc97909bcd..783c7ca88f2 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js @@ -93,7 +93,7 @@ Console.ConsoleViewMessage = class { */ willHide() { this._isVisible = false; - this._cachedHeight = this.contentElement().offsetHeight; + this._cachedHeight = this.element().offsetHeight; } /** @@ -125,9 +125,9 @@ Console.ConsoleViewMessage = class { */ _buildTableMessage() { const formattedMessage = createElementWithClass('span', 'source-code'); - const anchorElement = this._buildMessageAnchor(); - if (anchorElement) - formattedMessage.appendChild(anchorElement); + this._anchorElement = this._buildMessageAnchor(); + if (this._anchorElement) + formattedMessage.appendChild(this._anchorElement); const badgeElement = this._buildMessageBadge(); if (badgeElement) formattedMessage.appendChild(badgeElement); @@ -279,9 +279,9 @@ Console.ConsoleViewMessage = class { messageElement.classList.add('console-message-text'); const formattedMessage = createElementWithClass('span', 'source-code'); - const anchorElement = this._buildMessageAnchor(); - if (anchorElement) - formattedMessage.appendChild(anchorElement); + this._anchorElement = this._buildMessageAnchor(); + if (this._anchorElement) + formattedMessage.appendChild(this._anchorElement); const badgeElement = this._buildMessageBadge(); if (badgeElement) formattedMessage.appendChild(badgeElement); @@ -796,6 +796,8 @@ Console.ConsoleViewMessage = class { } function integerFormatter(obj) { + if (obj.type === 'bigint') + return obj.description; if (typeof obj.value !== 'number') return 'NaN'; return Math.floor(obj.value); @@ -921,8 +923,10 @@ Console.ConsoleViewMessage = class { */ matchesFilterRegex(regexObject) { regexObject.lastIndex = 0; - const text = this.contentElement().deepTextContent(); - return regexObject.test(text); + const contentElement = this.contentElement(); + const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : ''; + return (anchorText && regexObject.test(anchorText.trim())) || + regexObject.test(contentElement.deepTextContent().slice(anchorText.length)); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js index 023ecc6d35d..dad10ac84d1 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js @@ -51,6 +51,9 @@ Console.ConsoleViewport = class { this._topGapElement.textContent = '\uFEFF'; this._bottomGapElement.textContent = '\uFEFF'; + UI.ARIAUtils.markAsHidden(this._topGapElement); + UI.ARIAUtils.markAsHidden(this._bottomGapElement); + this._provider = provider; this.element.addEventListener('scroll', this._onScroll.bind(this), false); this.element.addEventListener('copy', this._onCopy.bind(this), false); @@ -166,13 +169,22 @@ Console.ConsoleViewport = class { } _rebuildCumulativeHeightsIfNeeded() { + let totalCachedHeight = 0; + let totalMeasuredHeight = 0; // Check whether current items in DOM have changed heights. Tolerate 1-pixel // error due to double-to-integer rounding errors. for (let i = 0; i < this._renderedItems.length; ++i) { const cachedItemHeight = this._cachedItemHeight(this._firstActiveIndex + i); - if (Math.abs(cachedItemHeight - this._renderedItems[i].element().offsetHeight) > 1) { + const measuredHeight = this._renderedItems[i].element().offsetHeight; + if (Math.abs(cachedItemHeight - measuredHeight) > 1) { + this._rebuildCumulativeHeights(); + return; + } + totalMeasuredHeight += measuredHeight; + totalCachedHeight += cachedItemHeight; + if (Math.abs(totalCachedHeight - totalMeasuredHeight) > 1) { this._rebuildCumulativeHeights(); - break; + return; } } } @@ -534,6 +546,9 @@ Console.ConsoleViewport = class { const lastVisibleIndex = this.lastVisibleIndex(); if (index > firstVisibleIndex && index < lastVisibleIndex) return; + // If the prompt is visible, then the last item must be fully on screen. + if (index === lastVisibleIndex && this._cumulativeHeights[index] <= this.element.scrollTop + this._visibleHeight()) + return; if (makeLast) this.forceScrollItemToBeLast(index); else if (index <= firstVisibleIndex) @@ -553,6 +568,8 @@ Console.ConsoleViewport = class { if (this.element.isScrolledToBottom()) this.setStickToBottom(true); this.refresh(); + // After refresh, the item is in DOM, but may not be visible (items above were larger than expected). + this.renderedElementAt(index).scrollIntoView(true /* alignTop */); } /** @@ -566,6 +583,8 @@ Console.ConsoleViewport = class { if (this.element.isScrolledToBottom()) this.setStickToBottom(true); this.refresh(); + // After refresh, the item is in DOM, but may not be visible (items above were larger than expected). + this.renderedElementAt(index).scrollIntoView(false /* alignTop */); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/consolePinPane.css b/chromium/third_party/blink/renderer/devtools/front_end/console/consolePinPane.css index c71d0e75ead..5fbf25d8378 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/consolePinPane.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/consolePinPane.css @@ -7,25 +7,43 @@ .console-pins { overflow-y: auto; background: var(--toolbar-bg-color); + --error-background-color: hsl(0, 100%, 97%); + --error-border-color: hsl(0, 100%, 92%); + --error-text-color: red; +} + +:host-context(.-theme-with-dark-background) .console-pins { + --error-background-color: hsl(0, 100%, 8%); + --error-border-color: rgb(92, 0, 0); + --error-text-color: hsl(0, 100%, 75%); } .console-pins:not(:empty) { border-bottom: 1px solid var(--divider-color); - padding: 5px 28px 0 24px; } .console-pin { - margin-bottom: 2px; position: relative; user-select: text; flex: none; - padding-bottom: 6px; + padding: 2px 0 6px 24px; } .console-pin:not(:last-child) { border-bottom: 1px solid #e4e4e4; } +.console-pin:not(:last-child).error-level:not(:focus-within) { + border-top: 1px solid var(--error-border-color); + border-bottom: 1px solid var(--error-border-color); + margin-top: -1px; +} + +.console-pin.error-level:not(:focus-within) { + background-color: var(--error-background-color); + color: var(--error-text-color); +} + .console-pin-name { margin-left: -4px; margin-bottom: 1px; @@ -38,13 +56,18 @@ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + min-height: 13px; +} + +:host-context(.-theme-with-dark-background) .console-delete-pin { + filter: brightness(2); } .console-delete-pin { position: absolute; - top: 6px; - left: -16px; - opacity: 0.5; + top: 8px; + left: 8px; + opacity: 0.7; cursor: pointer; } @@ -54,9 +77,10 @@ .console-pin-name:focus-within { background: #fff; - box-shadow: var(--focus-ring-active-shadow); + box-shadow: var(--focus-ring-active-shadow) inset; } +.console-pin:focus-within .console-pin-preview, .console-pin-name:not(:focus-within):not(:hover) { opacity: 0.6; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/consolePrompt.css b/chromium/third_party/blink/renderer/devtools/front_end/console/consolePrompt.css new file mode 100644 index 00000000000..203afb7685f --- /dev/null +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/consolePrompt.css @@ -0,0 +1,78 @@ +/* + * Copyright 2018 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. + */ + +#console-prompt .CodeMirror { + padding: 3px 0 1px 0; +} + +#console-prompt .CodeMirror-line { + padding-top: 0; +} + +#console-prompt .CodeMirror-lines { + padding-top: 0; +} + +#console-prompt .console-prompt-icon { + position: absolute; + left: -13px; + top: 5px; + -webkit-user-select: none; +} + +.console-eager-preview { + padding-bottom: 2px; + opacity: 0.6; + position: relative; + height: 15px; +} + +.console-eager-inner-preview { + text-overflow: ellipsis; + overflow: hidden; + margin-left: 4px; + height: 100%; +} + +.console-eager-inner-preview * { + white-space: nowrap; +} + +.console-eager-inner-preview:empty, +.console-eager-inner-preview:empty + .preview-result-icon { + opacity: 0; +} + +.preview-result-icon { + position: absolute; + left: -13px; + top: 1px; +} + +.command-pin-button::before { + content: '\1f4cc'; +} + +.command-pin-button { + cursor: pointer; + position: absolute; + top: 1px; + right: -40px; + opacity: 0; + width: 40px; +} + +#console-prompt:hover .command-pin-button { + opacity: 0.12; +} + +.-theme-with-dark-background #console-prompt:hover .command-pin-button { + opacity: 0.25; +} + +#console-prompt:hover .command-pin-button:hover { + opacity: 0.6; +} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css b/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css index ecc43036f56..17e99cb9519 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css @@ -30,6 +30,15 @@ .console-view { background-color: white; overflow: hidden; + --message-border-color: rgb(240, 240, 240); + --warning-border-color: hsl(50, 100%, 88%); + --error-border-color: hsl(0, 100%, 92%); +} + +.-theme-with-dark-background .console-view { + --message-border-color: rgb(58, 58, 58); + --warning-border-color: rgb(102, 85, 0); + --error-border-color: rgb(92, 0, 0); } .console-toolbar-container { @@ -67,7 +76,6 @@ #console-messages { flex: 1 1; - padding: 2px 0; overflow-y: auto; word-wrap: break-word; -webkit-user-select: text; @@ -81,32 +89,13 @@ min-height: 18px; /* Sync with ConsoleViewMessage.js */ } -#console-prompt .CodeMirror { - padding: 3px 0 1px 0; -} - -#console-prompt .CodeMirror-line { - padding-top: 0; -} - -#console-prompt .CodeMirror-lines { - padding-top: 0; -} - -#console-prompt .console-prompt-icon { - position: absolute; - left: -13px; - top: 5px; - -webkit-user-select: none; -} - .console-message, .console-user-command { clear: right; position: relative; padding: 3px 22px 1px 0; margin-left: 24px; - min-height: 18px; /* Sync with ConsoleViewMessage.js */ + min-height: 17px; /* Sync with ConsoleViewMessage.js */ flex: auto; display: flex; } @@ -199,23 +188,38 @@ .console-message-wrapper { display: flex; - border-bottom: 1px solid rgb(240, 240, 240); + border-top: 1px solid var(--message-border-color); + border-bottom: 1px solid transparent; +} + +.console-message-wrapper:first-of-type { + border-top-color: transparent; } -.console-message-wrapper.console-adjacent-user-command-result { - border-bottom: none; +.console-message-wrapper.console-adjacent-user-command-result:not(.console-error-level):not(.console-warning-level) { + border-top: none; } -.console-message-wrapper.console-error-level { - border-top: 1px solid hsl(0, 100%, 92%); - border-bottom: 1px solid hsl(0, 100%, 92%); - margin-top: -1px; +.console-message-wrapper.console-error-level, +.console-message-wrapper.console-error-level + .console-message-wrapper:not(.console-warning-level) { + border-top-color: var(--error-border-color); } -.console-message-wrapper.console-warning-level { - border-top: 1px solid hsl(50, 100%, 88%); - border-bottom: 1px solid hsl(50, 100%, 88%); - margin-top: -1px; +.console-message-wrapper.console-warning-level, +.console-message-wrapper.console-warning-level + .console-message-wrapper:not(.console-error-level) { + border-top-color: var(--warning-border-color); +} + +.console-message-wrapper:last-of-type { + border-bottom-color: var(--message-border-color); +} + +.console-message-wrapper.console-error-level:last-of-type { + border-bottom-color: var(--error-border-color); +} + +.console-message-wrapper.console-warning-level:last-of-type { + border-bottom-color: var(--warning-border-color); } .console-message-wrapper .nesting-level-marker { @@ -351,6 +355,10 @@ clear: both; } +.console-message .source-code { + line-height: 1.2; +} + .console-message-anchor { float: right; text-align: right; @@ -437,61 +445,7 @@ max-height: 100%; } -.console-eager-preview { - padding-bottom: 2px; - opacity: 0.6; - position: relative; - height: 15px; -} - -.console-eager-inner-preview { - text-overflow: ellipsis; - overflow: hidden; - margin-left: 4px; - height: 100%; -} - -.console-eager-inner-preview * { - white-space: nowrap; -} - -.console-eager-inner-preview:empty, -.console-eager-inner-preview:empty + .preview-result-icon { - opacity: 0; -} - -.preview-result-icon { - position: absolute; - left: -13px; - top: 1px; -} - .console-view-pinpane { flex: none; max-height: 200px; } - -.command-pin-button::before { - content: '\1f4cc'; -} - -.command-pin-button { - cursor: pointer; - position: absolute; - top: 1px; - right: -40px; - opacity: 0; - width: 40px; -} - -#console-prompt:hover .command-pin-button { - opacity: 0.12; -} - -.-theme-with-dark-background #console-prompt:hover .command-pin-button { - opacity: 0.25; -} - -#console-prompt:hover .command-pin-button:hover { - opacity: 0.6; -} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/module.json b/chromium/third_party/blink/renderer/devtools/front_end/console/module.json index 16fd2bdfbcc..a60af8b676d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/console/module.json @@ -60,6 +60,14 @@ "className": "Console.ConsoleView.ActionDelegate" }, { + "type": "action", + "category": "Console", + "actionId": "console.create-pin", + "iconClass": "largeicon-visibility", + "className": "Console.ConsoleView.ActionDelegate", + "title": "Create live expression" + }, + { "type": "setting", "category": "Console", "title": "Hide network messages", @@ -199,6 +207,7 @@ "resources": [ "consoleContextSelector.css", "consolePinPane.css", + "consolePrompt.css", "consoleSidebar.css", "consoleView.css" ] diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js index e72a511fa43..dc28c73c702 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js @@ -611,14 +611,12 @@ ConsoleTestRunner.dumpStackTraces = function() { }; /** - * Returns actual visible indices. Messages in the margin are treated as NOT visible. * @return {!{first: number, last: number, count: number}} */ ConsoleTestRunner.visibleIndices = function() { const consoleView = Console.ConsoleView.instance(); const viewport = consoleView._viewport; const viewportRect = viewport.element.getBoundingClientRect(); - const viewportPadding = parseFloat(window.getComputedStyle(viewport.element).paddingTop); let first = -1; let last = -1; let count = 0; @@ -628,8 +626,7 @@ ConsoleTestRunner.visibleIndices = function() { if (!item._element || !item._element.isConnected) continue; const itemRect = item._element.getBoundingClientRect(); - const isVisible = (itemRect.bottom > viewportRect.top + viewportPadding + 1) && - (itemRect.top <= viewportRect.bottom - viewportPadding - 1); + const isVisible = (itemRect.bottom > viewportRect.top + 1) && (itemRect.top <= viewportRect.bottom - 1); if (isVisible) { first = first === -1 ? i : first; last = i; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js b/chromium/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js index aec0f908e95..8aa45139ba7 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js @@ -138,8 +138,9 @@ Coverage.CoverageDecorationManager = class { const result = []; const contentType = uiSourceCode.contentType(); if (contentType.hasScripts()) { - let location = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, line, column); - if (location && location.script()) { + let locations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, line, column); + locations = locations.filter(location => !!location.script()); + for (let location of locations) { const script = location.script(); if (script.isInlineScript() && contentType.isDocument()) { if (comparePositions(script.lineOffset, script.columnOffset, location.lineNumber, location.columnNumber) > diff --git a/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json b/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json index e4441585647..02e578e0178 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json @@ -3,7 +3,6 @@ { "name": "emulation", "type": "autostart" }, { "name": "inspector_main", "type": "autostart" }, { "name": "mobile_throttling", "type": "autostart" }, - { "name": "browser_components", "type": "autostart" }, { "name": "accessibility", "type": "remote" }, { "name": "animation" }, diff --git a/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js b/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js index e4ddb5052d8..4489c397916 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js @@ -517,6 +517,13 @@ /** * @override + * @param {string} url + */ + close(url) { + } + + /** + * @override * @param {string} message */ sendMessageToBackend(message) { @@ -812,59 +819,6 @@ } /** - * Support for legacy front-ends (<M28). - * @return {boolean} - */ - canInspectWorkers() { - return true; - } - - /** - * Support for legacy front-ends (<M28). - * @return {boolean} - */ - canSaveAs() { - return true; - } - - /** - * Support for legacy front-ends (<M28). - * @return {boolean} - */ - canSave() { - return true; - } - - /** - * Support for legacy front-ends (<M28). - */ - loaded() { - } - - /** - * Support for legacy front-ends (<M28). - * @return {string} - */ - hiddenPanels() { - return ''; - } - - /** - * Support for legacy front-ends (<M28). - * @return {string} - */ - localizedStringsURL() { - return ''; - } - - /** - * Support for legacy front-ends (<M28). - * @param {string} url - */ - close(url) { - } - - /** * Support for legacy front-ends (<M44). * @param {number} actionCode */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js index 8979f943dba..7ae9081d399 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js @@ -483,7 +483,7 @@ Elements.ElementsPanel = class extends UI.Panel { const node = this.selectedDOMNode(); if (!node) return false; - const preview = await BrowserComponents.ImagePreview.build( + const preview = await Components.ImagePreview.build( node.domModel().target(), link[Elements.ElementsTreeElement.HrefSymbol], true); if (preview) popover.contentElement.appendChild(preview); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js index e5c1c4f8401..8cc0dcd20f7 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js @@ -529,7 +529,7 @@ Elements.ElementsTreeOutline = class extends UI.TreeOutline { const listItem = link.enclosingNodeOrSelfWithNodeName('li'); const node = /** @type {!Elements.ElementsTreeElement} */ (listItem.treeElement).node(); const precomputedFeatures = await this._loadDimensionsForNode(node); - const preview = await BrowserComponents.ImagePreview.build( + const preview = await Components.ImagePreview.build( node.domModel().target(), link[Elements.ElementsTreeElement.HrefSymbol], true, precomputedFeatures); if (preview) popover.contentElement.appendChild(preview); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js index b199ff8cf8d..55888d9ec65 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js @@ -1007,38 +1007,23 @@ Elements.StylePropertiesSection = class { const menuButton = new UI.ToolbarButton('', 'largeicon-menu'); menuButton.element.tabIndex = -1; sectionToolbar.appendToolbarItem(menuButton); - setItemsVisibility.call(this, items, false); - sectionToolbar.element.addEventListener('mouseenter', setItemsVisibility.bind(this, items, true)); - sectionToolbar.element.addEventListener('mouseleave', setItemsVisibility.bind(this, items, false)); + setItemsVisibility(items, false); + sectionToolbar.element.addEventListener('mouseenter', setItemsVisibility.bind(null, items, true)); + sectionToolbar.element.addEventListener('mouseleave', setItemsVisibility.bind(null, items, false)); UI.ARIAUtils.markAsHidden(sectionToolbar.element); /** * @param {!Array<!UI.ToolbarButton>} items * @param {boolean} value - * @this {Elements.StylePropertiesSection} */ function setItemsVisibility(items, value) { for (let i = 0; i < items.length; ++i) items[i].setVisible(value); menuButton.setVisible(!value); - if (this._isSASSStyle()) - newRuleButton.setVisible(false); } } /** - * @return {boolean} - */ - _isSASSStyle() { - const header = - this._style.styleSheetId ? this._style.cssModel().styleSheetHeaderForId(this._style.styleSheetId) : null; - if (!header) - return false; - const sourceMap = header.cssModel().sourceMapManager().sourceMapForClient(header); - return sourceMap ? sourceMap.editable() : false; - } - - /** * @return {!SDK.CSSStyleDeclaration} */ style() { @@ -1561,7 +1546,7 @@ Elements.StylePropertiesSection = class { return; } - if (!this.editable || this._isSASSStyle()) + if (!this.editable) return; const config = new UI.InplaceEditor.Config( @@ -1675,7 +1660,7 @@ Elements.StylePropertiesSection = class { } _startEditingAtFirstPosition() { - if (!this.editable || this._isSASSStyle()) + if (!this.editable) return; if (!this._style.parentRule) { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json b/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json index b655b00e9a2..6cffd5fed7f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json @@ -289,7 +289,7 @@ } ], "dependencies": [ - "browser_components", + "components", "extensions", "inline_editor", "color_picker", diff --git a/chromium/third_party/blink/renderer/devtools/front_end/event_listeners/EventListenersView.js b/chromium/third_party/blink/renderer/devtools/front_end/event_listeners/EventListenersView.js index f3fe2b55785..b1875f3dca1 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/event_listeners/EventListenersView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/event_listeners/EventListenersView.js @@ -22,6 +22,8 @@ EventListeners.EventListenersView = class extends UI.VBox { this._treeOutline.registerRequiredCSS('event_listeners/eventListenersView.css'); this._treeOutline.setComparator(EventListeners.EventListenersTreeElement.comparator); this._treeOutline.element.classList.add('monospace'); + this._treeOutline.setShowSelectionOnKeyboardFocus(true); + this._treeOutline.setFocusable(true); this.element.appendChild(this._treeOutline.element); this._emptyHolder = createElementWithClass('div', 'gray-info-message'); this._emptyHolder.textContent = Common.UIString('No event listeners'); @@ -182,12 +184,17 @@ EventListeners.EventListenersView = class extends UI.VBox { addEmptyHolderIfNeeded() { let allHidden = true; + let firstVisibleChild = null; for (const eventType of this._treeOutline.rootElement().children()) { eventType.hidden = !eventType.firstChild(); allHidden = allHidden && eventType.hidden; + if (!firstVisibleChild && !eventType.hidden) + firstVisibleChild = eventType; } if (allHidden && !this._emptyHolder.parentNode) this.element.appendChild(this._emptyHolder); + if (firstVisibleChild) + firstVisibleChild.select(true /* omitFocus */); } reset() { @@ -213,7 +220,6 @@ EventListeners.EventListenersTreeElement = class extends UI.TreeElement { constructor(type, linkifier, changeCallback) { super(type); this.toggleOnClick = true; - this.selectable = false; this._linkifier = linkifier; this._changeCallback = changeCallback; } @@ -255,7 +261,6 @@ EventListeners.ObjectEventListenerBar = class extends UI.TreeElement { super('', true); this._eventListener = eventListener; this.editable = false; - this.selectable = false; this._setTitle(object, linkifier); this._changeCallback = changeCallback; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js index d4a2f35999b..4a413d1b533 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js @@ -89,11 +89,13 @@ function defineCommonExtensionSymbols(apiPrivate) { * @param {!ExtensionDescriptor} extensionInfo * @param {string} inspectedTabId * @param {string} themeName + * @param {!Array<number>} keysToForward * @param {number} injectedScriptId * @param {function(!Object, !Object)} testHook * @suppressGlobalPropertiesCheck */ -function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook, injectedScriptId) { +function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, keysToForward, testHook, injectedScriptId) { + const keysToForwardSet = new Set(keysToForward); const chrome = window.chrome || {}; const devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, 'devtools'); if (devtools_descriptor) @@ -637,14 +639,26 @@ function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook let forwardTimer = null; function forwardKeyboardEvent(event) { + let modifiers = 0; + if (event.shiftKey) + modifiers |= 1; + if (event.ctrlKey) + modifiers |= 2; + if (event.altKey) + modifiers |= 4; + if (event.metaKey) + modifiers |= 8; + const num = (event.keyCode & 255) | (modifiers << 8); // We only care about global hotkeys, not about random text - if (!event.ctrlKey && !event.altKey && !event.metaKey && !/^F\d+$/.test(event.key) && event.key !== 'Escape') + if (!keysToForwardSet.has(num)) return; + event.preventDefault(); const requestPayload = { eventType: event.type, ctrlKey: event.ctrlKey, altKey: event.altKey, metaKey: event.metaKey, + shiftKey: event.shiftKey, keyIdentifier: event.keyIdentifier, key: event.key, code: event.code, @@ -664,7 +678,6 @@ function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook } document.addEventListener('keydown', forwardKeyboardEvent, false); - document.addEventListener('keypress', forwardKeyboardEvent, false); /** * @constructor @@ -795,11 +808,12 @@ function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook * @param {!ExtensionDescriptor} extensionInfo * @param {string} inspectedTabId * @param {string} themeName + * @param {!Array<number>} keysToForward * @param {function(!Object, !Object)|undefined} testHook * @return {string} */ -function buildExtensionAPIInjectedScript(extensionInfo, inspectedTabId, themeName, testHook) { - const argumentsJSON = [extensionInfo, inspectedTabId || null, themeName].map(_ => JSON.stringify(_)).join(','); +function buildExtensionAPIInjectedScript(extensionInfo, inspectedTabId, themeName, keysToForward, testHook) { + const argumentsJSON = [extensionInfo, inspectedTabId || null, themeName, keysToForward].map(_ => JSON.stringify(_)).join(','); if (!testHook) testHook = () => {}; return '(function(injectedScriptId){ ' + defineCommonExtensionSymbols.toString() + ';' + diff --git a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js index cb93140bfe1..f633923b7d0 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js @@ -378,7 +378,7 @@ Extensions.ExtensionServer = class extends Common.Object { return this._status.OK(); } - const request = BrowserSDK.networkLog.requestForURL(message.url); + const request = SDK.networkLog.requestForURL(message.url); if (request) { Common.Revealer.reveal(request); return this._status.OK(); @@ -434,8 +434,8 @@ Extensions.ExtensionServer = class extends Common.Object { } async _onGetHAR() { - const requests = BrowserSDK.networkLog.requests(); - const harLog = await BrowserSDK.HARLog.build(requests); + const requests = SDK.networkLog.requests(); + const harLog = await SDK.HARLog.build(requests); for (let i = 0; i < harLog.entries.length; ++i) harLog.entries[i]._requestId = this._requestId(requests[i]); return harLog; @@ -560,8 +560,6 @@ Extensions.ExtensionServer = class extends Common.Object { * @suppressGlobalPropertiesCheck */ function handleEventEntry(entry) { - if (!entry.ctrlKey && !entry.altKey && !entry.metaKey && !/^F\d+$/.test(entry.key) && entry.key !== 'Escape') - return; // Fool around closure compiler -- it has its own notion of both KeyboardEvent constructor // and initKeyboardEvent methods and overriding these in externs.js does not have effect. const event = new window.KeyboardEvent(entry.eventType, { @@ -640,7 +638,7 @@ Extensions.ExtensionServer = class extends Common.Object { async _notifyRequestFinished(event) { const request = /** @type {!SDK.NetworkRequest} */ (event.data); - const entry = await BrowserSDK.HAREntry.build(request); + const entry = await SDK.HARLog.Entry.build(request); this._postNotification(Extensions.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), entry); } @@ -703,6 +701,7 @@ Extensions.ExtensionServer = class extends Common.Object { // See ExtensionAPI.js for details. const injectedAPI = buildExtensionAPIInjectedScript( extensionInfo, this._inspectedTabId, UI.themeSupport.themeName(), + UI.shortcutRegistry.globalShortcutKeys(), Extensions.extensionServer['_extensionAPITestHook']); InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, injectedAPI); this._registeredExtensions[extensionOrigin] = {name: name}; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js b/chromium/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js index cb05d741488..064e04cf5db 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js @@ -152,8 +152,15 @@ FormatterWorker.evaluatableJavaScriptSubstring = function(content) { */ FormatterWorker.preprocessTopLevelAwaitExpressions = function(content) { let wrapped = '(async () => {' + content + '})()'; - const root = acorn.parse(wrapped, {ecmaVersion: 9}); - const body = root.body[0].expression.callee.body; + let root; + let body; + try { + root = acorn.parse(wrapped, {ecmaVersion: 9}); + body = root.body[0].expression.callee.body; + } catch (e) { + postMessage(''); + return; + } const changes = []; let containsAwait = false; let containsReturn = false; @@ -236,7 +243,11 @@ FormatterWorker.preprocessTopLevelAwaitExpressions = function(content) { * @param {string} content */ FormatterWorker.javaScriptIdentifiers = function(content) { - const root = acorn.parse(content, {ranges: false, ecmaVersion: 9}); + let root = null; + try { + root = acorn.parse(content, {ranges: false, ecmaVersion: 9}); + } catch (e) { + } /** @type {!Array<!ESTree.Node>} */ const identifiers = []; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js b/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js index 260f476eb67..ce1e59a8b71 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js @@ -15,7 +15,7 @@ HARImporter.Importer = class { log.entries.sort((a, b) => a.startedDateTime - b.startedDateTime); - /** @type {!Map<string, !BrowserSDK.PageLoad>} */ + /** @type {!Map<string, !SDK.NetworkLog.PageLoad>} */ const pageLoads = new Map(); /** @type {!Array<!SDK.NetworkRequest>} */ const requests = []; @@ -39,10 +39,10 @@ HARImporter.Importer = class { /** * @param {!HARImporter.HARPage} page * @param {!SDK.NetworkRequest} mainRequest - * @return {!BrowserSDK.PageLoad} + * @return {!SDK.NetworkLog.PageLoad} */ static _buildPageLoad(page, mainRequest) { - const pageLoad = new BrowserSDK.PageLoad(mainRequest); + const pageLoad = new SDK.NetworkLog.PageLoad(mainRequest); pageLoad.startTime = page.startedDateTime; pageLoad.contentLoadTime = page.pageTimings.onContentLoad * 1000; pageLoad.loadTime = page.pageTimings.onLoad * 1000; @@ -52,7 +52,7 @@ HARImporter.Importer = class { /** * @param {!SDK.NetworkRequest} request * @param {!HARImporter.HAREntry} entry - * @param {?BrowserSDK.PageLoad} pageLoad + * @param {?SDK.NetworkLog.PageLoad} pageLoad */ static _fillRequestFromHAREntry(request, entry, pageLoad) { // Request data. diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js index 9d2ce468d1d..ba2379884cf 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js @@ -42,7 +42,8 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() { node_fields: ['type', 'name', 'id', 'self_size', 'retained_size', 'dominator', 'edge_count'], node_types: [['hidden', 'object'], '', '', '', '', '', ''], edge_fields: ['type', 'name_or_index', 'to_node'], - edge_types: [['element', 'property', 'shortcut'], '', ''] + edge_types: [['element', 'property', 'shortcut'], '', ''], + location_fields: ['object_index', 'script_id', 'line', 'column'] }, node_count: 6, @@ -55,6 +56,9 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() { ], edges: [1, 6, 7, 1, 7, 14, 0, 1, 14, 1, 8, 21, 1, 9, 21, 1, 10, 28, 1, 11, 35], + + locations: [0, 1, 2, 3, 18, 2, 3, 4], + strings: ['', 'A', 'B', 'C', 'D', 'E', 'a', 'b', 'ac', 'bc', 'bd', 'ce'] }; }; @@ -76,7 +80,8 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() { node_fields: ['type', 'name', 'id', 'edge_count'], node_types: [['hidden', 'object', 'synthetic'], '', '', ''], edge_fields: ['type', 'name_or_index', 'to_node'], - edge_types: [['element', 'hidden', 'internal'], '', ''] + edge_types: [['element', 'hidden', 'internal'], '', ''], + location_fields: ['object_index', 'script_id', 'line', 'column'] }, node_count: 13, @@ -93,6 +98,8 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() { 24, 0, 2, 28, 1, 3, 32, 0, 1, 36, 0, 1, 40, 2, 12, 44, 2, 1, 48 ], + locations: [0, 2, 1, 1, 6, 2, 2, 2], + strings: ['', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'M', 'N', 'Window', 'native'] }); }; @@ -233,6 +240,7 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() { 'nodes': [], 'edges': [], + 'locations': [], 'strings': [] }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js index 02d0cf93560..aeb766a1ad3 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js @@ -411,3 +411,19 @@ HeapSnapshotModel.Samples = class { this.sizes = sizes; } }; + +/** + * @unrestricted + */ +HeapSnapshotModel.Location = class { + /** + * @param {number} scriptId + * @param {number} lineNumber + * @param {number} columnNumber + */ + constructor(scriptId, lineNumber, columnNumber) { + this.scriptId = scriptId; + this.lineNumber = lineNumber; + this.columnNumber = columnNumber; + } +};
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js index e710051a3cd..8c67f784b0e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js @@ -838,6 +838,8 @@ HeapSnapshotWorker.HeapSnapshot = class { this._samples = null; /** @type {!Array.<string>} */ this.strings = profile.strings; + /** @type {!Array.<number>} */ + this._locations = profile.locations; this._progress = progress; this._noDistance = -5; @@ -890,6 +892,14 @@ HeapSnapshotWorker.HeapSnapshot = class { this._edgeWeakType = this._edgeTypes.indexOf('weak'); this._edgeInvisibleType = this._edgeTypes.indexOf('invisible'); + const location_fields = meta.location_fields || []; + + this._locationIndexOffset = location_fields.indexOf('object_index'); + this._locationScriptIdOffset = location_fields.indexOf('script_id'); + this._locationLineOffset = location_fields.indexOf('line'); + this._locationColumnOffset = location_fields.indexOf('column'); + this._locationFieldCount = location_fields.length; + this.nodeCount = this.nodes.length / this._nodeFieldCount; this._edgeCount = this.containmentEdges.length / this._edgeFieldsCount; @@ -924,6 +934,8 @@ HeapSnapshotWorker.HeapSnapshot = class { this.calculateStatistics(); this._progress.updateStatus('Calculating samples\u2026'); this._buildSamples(); + this._progress.updateStatus('Building locations\u2026'); + this._buildLocationMap(); this._progress.updateStatus('Finished processing.'); if (this._profile.snapshot.trace_function_count) { @@ -1870,6 +1882,30 @@ HeapSnapshotWorker.HeapSnapshot = class { this._samples = new HeapSnapshotModel.Samples(timestamps, lastAssignedIds, sizeForRange); } + _buildLocationMap() { + /** @type {!Map<number, !HeapSnapshotModel.Location>} */ + const map = new Map(); + const locations = this._locations; + + for (let i = 0; i < locations.length; i += this._locationFieldCount) { + const nodeIndex = locations[i + this._locationIndexOffset]; + const scriptId = locations[i + this._locationScriptIdOffset]; + const line = locations[i + this._locationLineOffset]; + const col = locations[i + this._locationColumnOffset]; + map.set(nodeIndex, new HeapSnapshotModel.Location(scriptId, line, col)); + } + + this._locationMap = map; + } + + /** + * @param {number} nodeIndex + * @return {?HeapSnapshotModel.Location} + */ + getLocation(nodeIndex) { + return this._locationMap.get(nodeIndex) || null; + } + /** * @return {?HeapSnapshotModel.Samples} */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js index 6c0abf3aa04..6f49288eba4 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js @@ -107,7 +107,7 @@ HeapSnapshotWorker.HeapSnapshotLoader = class { _parseStringsArray() { this._progress.updateStatus('Parsing strings\u2026'); const closingBracketIndex = this._json.lastIndexOf(']'); - if (closingBracketIndex === -1) + if (closingBracketIndex === -1 || this._state !== 'accumulate-strings') throw new Error('Incomplete JSON'); this._json = this._json.slice(0, closingBracketIndex + 1); this._snapshot.strings = JSON.parse(this._json); @@ -198,7 +198,7 @@ HeapSnapshotWorker.HeapSnapshotLoader = class { this._state = 'find-samples'; this._progress.updateStatus('Loading samples\u2026'); } else { - this._state = 'find-strings'; + this._state = 'find-locations'; } break; } @@ -277,6 +277,39 @@ HeapSnapshotWorker.HeapSnapshotLoader = class { return; this._snapshot.samples = this._array; this._array = null; + this._state = 'find-locations'; + this._progress.updateStatus('Loading locations\u2026'); + break; + } + case 'find-locations': { + if (!this._snapshot.snapshot.meta.location_fields) { + // The property `locations` was added retroactively, so older + // snapshots might not contain it. In this case just expect `strings` + // as next property. + this._snapshot.locations = []; + this._array = null; + this._state = 'find-strings'; + break; + } + + const locationsToken = '"locations"'; + const locationsTokenIndex = this._json.indexOf(locationsToken); + if (locationsTokenIndex === -1) + return; + const bracketIndex = this._json.indexOf('[', locationsTokenIndex); + if (bracketIndex === -1) + return; + this._json = this._json.slice(bracketIndex + 1); + this._array = []; + this._arrayIndex = 0; + this._state = 'parse-locations'; + break; + } + case 'parse-locations': { + if (this._parseUintArray()) + return; + this._snapshot.locations = this._array; + this._array = null; this._state = 'find-strings'; this._progress.updateStatus('Loading strings\u2026'); break; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js b/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js index a149c0e8e78..fcb2c368557 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js @@ -13,6 +13,44 @@ const commandMenuShortcut = Host.isMac() ? 'Command + Shift + P' : 'Control + Sh /** @type {!Array<!Help.ReleaseNote>} */ Help.releaseNoteText = [ { + version: 12, + header: 'Highlights from the Chrome 70 update', + highlights: [ + { + title: 'Live Expressions in the Console', + subtitle: 'Pin expressions to the top of the Console to monitor their values in real-time.', + link: 'https://developers.google.com/web/updates/2018/08/devtools#watch', + }, + { + title: 'Highlight DOM nodes during Eager Evaluation', + subtitle: 'Type an expression that evaluates to a node to highlight that node in the viewport.', + link: 'https://developers.google.com/web/updates/2018/08/devtools#nodes', + }, + { + title: 'Autocomplete Conditional Breakpoints', + subtitle: 'Type expressions quickly and accurately.', + link: 'https://developers.google.com/web/updates/2018/08/devtools#autocomplete', + }, + { + title: 'Performance panel optimizations', + subtitle: 'Faster loading and processing of Performance recordings.', + link: 'https://developers.google.com/web/updates/2018/08/devtools#performance', + }, + { + title: 'More reliable debugging', + subtitle: 'Bug fixes for sourcemaps and blackboxing.', + link: 'https://developers.google.com/web/updates/2018/08/devtools#debugging', + }, + { + title: 'Debug Node.js apps with ndb', + subtitle: + 'Detect and attach to child processes, place breakpoints before modules are required, edit files within DevTools, and more.', + link: 'https://developers.google.com/web/updates/2018/08/devtools#ndb', + }, + ], + link: 'https://developers.google.com/web/updates/2018/08/devtools', + }, + { version: 11, header: 'Highlights from the Chrome 68 update', highlights: [ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js b/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js index b12d858aa15..2dd46365728 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js @@ -46,6 +46,10 @@ Host.InspectorFrontendHostStub = class { event.stopPropagation(); } document.addEventListener('keydown', stopEventPropagation, true); + /** + * @type {!Map<string, !Array<string>>} + */ + this._urlsBeingSaved = new Map(); } /** @@ -197,8 +201,13 @@ Host.InspectorFrontendHostStub = class { * @param {boolean} forceSaveAs */ save(url, content, forceSaveAs) { - Common.console.error('Saving files is not enabled in hosted mode. Please inspect using chrome://inspect'); - this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.CanceledSaveURL, url); + let buffer = this._urlsBeingSaved.get(url); + if (!buffer) { + buffer = []; + this._urlsBeingSaved.set(url, buffer); + } + buffer.push(content); + this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.SavedURL, {url, fileSystemPath: url}); } /** @@ -207,7 +216,24 @@ Host.InspectorFrontendHostStub = class { * @param {string} content */ append(url, content) { - Common.console.error('Saving files is not enabled in hosted mode. Please inspect using chrome://inspect'); + const buffer = this._urlsBeingSaved.get(url); + buffer.push(content); + this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.AppendedToURL, url); + } + + /** + * @override + * @param {string} url + */ + close(url) { + const buffer = this._urlsBeingSaved.get(url); + this._urlsBeingSaved.delete(url); + const fileName = url ? url.trimURL().removeURLFragment() : ''; + const link = createElement('a'); + link.download = fileName; + const blob = new Blob([buffer.join('')], {type: 'text/plain'}); + link.href = URL.createObjectURL(blob); + link.click(); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js b/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js index 6c0bc59cd53..93b1dc56a89 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js @@ -100,12 +100,6 @@ InspectorFrontendHostAPI.prototype = { */ addFileSystem(type) {}, - /** - * @param {string} url - * @param {string} content - */ - append(url, content) {}, - loadCompleted() {}, /** @@ -183,6 +177,17 @@ InspectorFrontendHostAPI.prototype = { save(url, content, forceSaveAs) {}, /** + * @param {string} url + * @param {string} content + */ + append(url, content) {}, + + /** + * @param {string} url + */ + close(url) {}, + + /** * @param {number} requestId * @param {string} fileSystemPath * @param {string} query diff --git a/chromium/third_party/blink/renderer/devtools/front_end/inline_editor/CSSShadowEditor.js b/chromium/third_party/blink/renderer/devtools/front_end/inline_editor/CSSShadowEditor.js index ddaa9f85a41..5bf765f6c9c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/inline_editor/CSSShadowEditor.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/inline_editor/CSSShadowEditor.js @@ -86,8 +86,8 @@ InlineEditor.CSSShadowEditor = class extends UI.VBox { */ setModel(model) { this._model = model; - this._typeField.hidden = !model.isBoxShadow(); - this._spreadField.hidden = !model.isBoxShadow(); + this._typeField.classList.toggle('hidden', !model.isBoxShadow()); + this._spreadField.classList.toggle('hidden', !model.isBoxShadow()); this._updateUI(); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/module.json b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/module.json index 24aa03bb647..99baa98c7f8 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/module.json @@ -14,7 +14,7 @@ "bindings": [ { "platform": "windows,linux", - "shortcut": "F5 Ctrl+R" + "shortcut": "Ctrl+R F5" }, { "platform": "mac", @@ -31,7 +31,7 @@ "bindings": [ { "platform": "windows,linux", - "shortcut": "Shift+F5 Ctrl+F5 Ctrl+Shift+F5 Shift+Ctrl+R" + "shortcut": "Shift+Ctrl+R Shift+F5 Ctrl+F5 Ctrl+Shift+F5" }, { "platform": "mac", diff --git a/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js b/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js index c275c351749..cbb0a62e42e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js @@ -131,6 +131,7 @@ Main.Main = class { Runtime.experiments.register('timelineShowAllEvents', 'Timeline: show all events', true); Runtime.experiments.register('timelineTracingJSProfile', 'Timeline: tracing based JS profiler', true); Runtime.experiments.register('timelineV8RuntimeCallStats', 'Timeline: V8 Runtime Call Stats on Timeline', true); + Runtime.experiments.register('timelineWebGL', 'Timeline: WebGL-based flamechart'); Runtime.experiments.cleanUpStaleExperiments(); @@ -143,10 +144,14 @@ Main.Main = class { Runtime.experiments.enableForTest('networkSearch'); if (testPath.indexOf('console/viewport-testing/') !== -1) Runtime.experiments.enableForTest('consoleBelowPrompt'); + if (testPath.indexOf('console/') !== -1) + Runtime.experiments.enableForTest('pinnedExpressions'); } - Runtime.experiments.setDefaultExperiments( - ['colorContrastRatio', 'stepIntoAsync', 'oopifInlineDOM', 'consoleBelowPrompt', 'timelineTracingJSProfile']); + Runtime.experiments.setDefaultExperiments([ + 'colorContrastRatio', 'stepIntoAsync', 'oopifInlineDOM', 'consoleBelowPrompt', 'timelineTracingJSProfile', + 'pinnedExpressions' + ]); } /** @@ -516,7 +521,8 @@ Main.Main.MainMenuItem = class { 'Placement of DevTools relative to the page. (%s to restore last position)', toggleDockSideShorcuts[0].name); dockItemElement.appendChild(titleElement); const dockItemToolbar = new UI.Toolbar('', dockItemElement); - dockItemToolbar.makeBlueOnHover(); + if (Host.isMac() && !UI.themeSupport.hasTheme()) + dockItemToolbar.makeBlueOnHover(); const undock = new UI.ToolbarToggle(Common.UIString('Undock into separate window'), 'largeicon-undock'); const bottom = new UI.ToolbarToggle(Common.UIString('Dock to bottom'), 'largeicon-dock-to-bottom'); const right = new UI.ToolbarToggle(Common.UIString('Dock to right'), 'largeicon-dock-to-right'); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/main/module.json b/chromium/third_party/blink/renderer/devtools/front_end/main/module.json index 3c439d87fdd..fc5bb81909a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/main/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/main/module.json @@ -40,7 +40,7 @@ "type": "action", "category": "Drawer", "actionId": "main.toggle-drawer", - "className": "UI.InspectorView.DrawerToggleActionDelegate", + "className": "UI.InspectorView.ActionDelegate", "order": 101, "title": "Toggle drawer", "bindings": [ @@ -51,6 +51,36 @@ }, { "type": "action", + "actionId": "main.next-tab", + "className": "UI.InspectorView.ActionDelegate", + "bindings": [ + { + "platform": "windows,linux", + "shortcut": "Ctrl+]" + }, + { + "platform": "mac", + "shortcut": "Meta+]" + } + ] + }, + { + "type": "action", + "actionId": "main.previous-tab", + "className": "UI.InspectorView.ActionDelegate", + "bindings": [ + { + "platform": "windows,linux", + "shortcut": "Ctrl+[" + }, + { + "platform": "mac", + "shortcut": "Meta+[" + } + ] + }, + { + "type": "action", "actionId": "main.debug-reload", "className": "Main.ReloadActionDelegate", "bindings": [ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/HARWriter.js b/chromium/third_party/blink/renderer/devtools/front_end/network/HARWriter.js index 52aa0b0b80c..b7f20e88d8a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/HARWriter.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/HARWriter.js @@ -54,7 +54,7 @@ Network.HARWriter = class { progress.setTitle(Common.UIString('Collecting content\u2026')); progress.setTotalWork(requests.length); - const harLog = await BrowserSDK.HARLog.build(requests); + const harLog = await SDK.HARLog.build(requests); const promises = []; for (let i = 0; i < requests.length; i++) { const promise = requests[i].contentData(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js index cbc6fb46691..5f3e50400aa 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js @@ -546,7 +546,7 @@ Network.NetworkRequestNode = class extends Network.NetworkNode { showingInitiatorChainChanged() { const showInitiatorChain = this.showingInitiatorChain(); - const initiatorGraph = BrowserSDK.networkLog.initiatorGraphForRequest(this._request); + const initiatorGraph = SDK.networkLog.initiatorGraphForRequest(this._request); for (const request of initiatorGraph.initiators) { if (request === this._request) continue; @@ -636,7 +636,7 @@ Network.NetworkRequestNode = class extends Network.NetworkNode { * @return {boolean} */ isNavigationRequest() { - const pageLoad = BrowserSDK.PageLoad.forRequest(this._request); + const pageLoad = SDK.NetworkLog.PageLoad.forRequest(this._request); return pageLoad ? pageLoad.mainRequest === this._request : false; } @@ -882,7 +882,7 @@ Network.NetworkRequestNode = class extends Network.NetworkNode { _renderInitiatorCell(cell) { this._initiatorCell = cell; const request = this._request; - const initiator = BrowserSDK.networkLog.initiatorInfoForRequest(request); + const initiator = SDK.networkLog.initiatorInfoForRequest(request); const timing = request.timing; if (timing && timing.pushStart) diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js index 19bc05754ef..f338f7375ac 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js @@ -146,9 +146,9 @@ Network.NetworkLogView = class extends UI.VBox { .addChangeListener(this._invalidateAllItems.bind(this, false), this); SDK.targetManager.observeModels(SDK.NetworkManager, this); - BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestAdded, this._onRequestUpdated, this); - BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestUpdated, this._onRequestUpdated, this); - BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.Reset, this._reset, this); + SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestAdded, this._onRequestUpdated, this); + SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestUpdated, this._onRequestUpdated, this); + SDK.networkLog.addEventListener(SDK.NetworkLog.Events.Reset, this._reset, this); this._updateGroupByFrame(); Common.moduleSetting('network.group-by-frame').addChangeListener(() => this._updateGroupByFrame()); @@ -466,7 +466,7 @@ Network.NetworkLogView = class extends UI.VBox { this._harLoadFailed(e); return; } - BrowserSDK.networkLog.importRequests(HARImporter.Importer.requestsFromHARLog(harRoot.log)); + SDK.networkLog.importRequests(HARImporter.Importer.requestsFromHARLog(harRoot.log)); } /** @@ -691,7 +691,7 @@ Network.NetworkLogView = class extends UI.VBox { let maxTime = -1; let nodeCount = 0; - for (const request of BrowserSDK.networkLog.requests()) { + for (const request of SDK.networkLog.requests()) { const node = request[Network.NetworkLogView._networkNodeSymbol]; if (!node) continue; @@ -797,7 +797,7 @@ Network.NetworkLogView = class extends UI.VBox { * @param {boolean=} deferUpdate */ _invalidateAllItems(deferUpdate) { - this._staleRequests = new Set(BrowserSDK.networkLog.requests()); + this._staleRequests = new Set(SDK.networkLog.requests()); if (deferUpdate) this.scheduleRefresh(); else @@ -1228,12 +1228,12 @@ Network.NetworkLogView = class extends UI.VBox { } _harRequests() { - const httpRequests = BrowserSDK.networkLog.requests().filter(Network.NetworkLogView.HTTPRequestsFilter); + const httpRequests = SDK.networkLog.requests().filter(Network.NetworkLogView.HTTPRequestsFilter); return httpRequests.filter(Network.NetworkLogView.FinishedRequestsFilter); } async _copyAll() { - const harArchive = {log: await BrowserSDK.HARLog.build(this._harRequests())}; + const harArchive = {log: await SDK.HARLog.build(this._harRequests())}; InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2)); } @@ -1250,7 +1250,7 @@ Network.NetworkLogView = class extends UI.VBox { * @param {string} platform */ async _copyAllCurlCommand(platform) { - const requests = BrowserSDK.networkLog.requests(); + const requests = SDK.networkLog.requests(); const commands = await Promise.all(requests.map(request => this._generateCurlCommand(request, platform))); if (platform === 'win') InspectorFrontendHost.copyText(commands.join(' &\r\n')); @@ -1268,7 +1268,7 @@ Network.NetworkLogView = class extends UI.VBox { } async _copyAllFetchCall() { - const requests = BrowserSDK.networkLog.requests(); + const requests = SDK.networkLog.requests(); const commands = await Promise.all(requests.map(request => this._generateFetchCall(request))); InspectorFrontendHost.copyText(commands.join(' ;\n')); } @@ -1282,7 +1282,7 @@ Network.NetworkLogView = class extends UI.VBox { } async _copyAllPowerShellCommand() { - const requests = BrowserSDK.networkLog.requests(); + const requests = SDK.networkLog.requests(); const commands = await Promise.all(requests.map(request => this._generatePowerShellCommand(request))); InspectorFrontendHost.copyText(commands.join(';\r\n')); } @@ -1544,8 +1544,7 @@ Network.NetworkLogView = class extends UI.VBox { const headers = {}; for (const headerArray of headerData) - headers[headerArray[0]] = headers[headerArray[1]]; - + headers[headerArray[0]] = headerArray[1]; const credentials = request.requestCookies || requestHeaders.some(({name}) => credentialHeaders[name.toLowerCase()]) ? 'include' : @@ -1561,7 +1560,7 @@ Network.NetworkLogView = class extends UI.VBox { const fetchOptions = { credentials, - headers, + headers: Object.keys(headers).length ? headers : void 0, referrer, referrerPolicy, body: requestBody, @@ -1631,23 +1630,19 @@ Network.NetworkLogView = class extends UI.VBox { * @return {string} */ function escapeCharacter(x) { - let code = x.charCodeAt(0); - if (code < 256) { - // Add leading zero when needed to not care about the next character. - return code < 16 ? '\\x0' + code.toString(16) : '\\x' + code.toString(16); - } - code = code.toString(16); - return '\\u' + ('0000' + code).substr(code.length, 4); + const code = x.charCodeAt(0); + // Add leading zero when needed to not care about the next character. + return code < 16 ? '\\u0' + code.toString(16) : '\\u' + code.toString(16); } - if (/[^\x20-\x7E]|\'/.test(str)) { + if (/[\u0000-\u001f\u007f-\u009f]|\'/.test(str)) { // Use ANSI-C quoting syntax. return '$\'' + str.replace(/\\/g, '\\\\') .replace(/\'/g, '\\\'') .replace(/\n/g, '\\n') .replace(/\r/g, '\\r') - .replace(/[^\x20-\x7E]/g, escapeCharacter) + + .replace(/[\u0000-\u001f\u007f-\u009f]/g, escapeCharacter) + '\''; } else { // Use single quote syntax. diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js index 1d2fc78d0f1..06013d284b8 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js @@ -137,9 +137,9 @@ Network.NetworkPanel = class extends UI.Panel { SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.WillReloadPage, this._willReloadPage, this); SDK.targetManager.addModelListener(SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._load, this); this._networkLogView.addEventListener(Network.NetworkLogView.Events.RequestSelected, this._onRequestSelected, this); - BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestAdded, this._onUpdateRequest, this); - BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestUpdated, this._onUpdateRequest, this); - BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.Reset, this._onNetworkLogReset, this); + SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestAdded, this._onUpdateRequest, this); + SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestUpdated, this._onUpdateRequest, this); + SDK.networkLog.addEventListener(SDK.NetworkLog.Events.Reset, this._onNetworkLogReset, this); } /** @@ -191,7 +191,7 @@ Network.NetworkPanel = class extends UI.Panel { } this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleRecordAction)); const clearButton = new UI.ToolbarButton(Common.UIString('Clear'), 'largeicon-clear'); - clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => BrowserSDK.networkLog.reset(), this); + clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => SDK.networkLog.reset(), this); this._panelToolbar.appendToolbarItem(clearButton); this._panelToolbar.appendSeparator(); const recordFilmStripButton = new UI.ToolbarSettingToggle( @@ -255,7 +255,7 @@ Network.NetworkPanel = class extends UI.Panel { _toggleRecording() { if (!this._preserveLogSetting.get() && !this._toggleRecordAction.toggled()) - BrowserSDK.networkLog.reset(); + SDK.networkLog.reset(); this._toggleRecord(!this._toggleRecordAction.toggled()); } @@ -269,7 +269,7 @@ Network.NetworkPanel = class extends UI.Panel { this._filmStripRecorder.stopRecording(this._filmStripAvailable.bind(this)); // TODO(einbinder) This should be moved to a setting/action that NetworkLog owns but NetworkPanel controls, but // always be present in the command menu. - BrowserSDK.networkLog.setIsRecording(toggled); + SDK.networkLog.setIsRecording(toggled); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkSearchScope.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkSearchScope.js index 8320051a51b..57afb465813 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkSearchScope.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkSearchScope.js @@ -24,8 +24,7 @@ Network.NetworkSearchScope = class { */ async performSearch(searchConfig, progress, searchResultCallback, searchFinishedCallback) { const promises = []; - const requests = - BrowserSDK.networkLog.requests().filter(request => searchConfig.filePathMatchesFileQuery(request.url())); + const requests = SDK.networkLog.requests().filter(request => searchConfig.filePathMatchesFileQuery(request.url())); progress.setTotalWork(requests.length); for (const request of requests) { const promise = this._searchRequest(searchConfig, request, progress); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/networkConfigView.css b/chromium/third_party/blink/renderer/devtools/front_end/network/networkConfigView.css index 5c9f81f3ea7..6c5ede0de91 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network/networkConfigView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/network/networkConfigView.css @@ -64,7 +64,6 @@ .network-config-ua input:not(.dt-radio-button) { display: block; width: calc(100% - 20px); - max-width: 250px; } .network-config-ua input[readonly] { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network_test_runner/NetworkTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/network_test_runner/NetworkTestRunner.js index 869853fea89..95f78d89e6a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/network_test_runner/NetworkTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/network_test_runner/NetworkTestRunner.js @@ -54,7 +54,7 @@ NetworkTestRunner.networkWaterfallColumn = function() { }; NetworkTestRunner.networkRequests = function() { - return Array.from(BrowserSDK.networkLog.requests()); + return Array.from(SDK.networkLog.requests()); }; NetworkTestRunner.dumpNetworkRequests = function() { @@ -71,7 +71,7 @@ NetworkTestRunner.dumpNetworkRequests = function() { }; NetworkTestRunner.dumpNetworkRequestsWithSignedExchangeInfo = function() { - for (const request of BrowserSDK.networkLog.requests()) { + for (const request of SDK.networkLog.requests()) { TestRunner.addResult(`* ${request.url()}`); TestRunner.addResult(` failed: ${!!request.failed}`); TestRunner.addResult(` statusCode: ${request.statusCode}`); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js index cddc8a81818..ddbfbc95e58 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js @@ -559,7 +559,7 @@ ObjectUI.JavaScriptAutocomplete = class { allProperties.add(property); if (property.startsWith(query)) - caseSensitivePrefix.push({text: property, priority: 4}); + caseSensitivePrefix.push({text: property, priority: property === query ? 5 : 4}); else if (lowerCaseProperty.startsWith(lowerCaseQuery)) caseInsensitivePrefix.push({text: property, priority: 3}); else if (property.indexOf(query) !== -1) @@ -596,6 +596,23 @@ ObjectUI.JavaScriptAutocomplete = class { return -1; return String.naturalOrderComparator(a, b); } + + /** + * @param {string} expression + * @return {!Promise<boolean>} + */ + static async isExpressionComplete(expression) { + const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext); + if (!currentExecutionContext) + return true; + const result = + await currentExecutionContext.runtimeModel.compileScript(expression, '', false, currentExecutionContext.id); + if (!result.exceptionDetails) + return true; + const description = result.exceptionDetails.exception.description; + return !description.startsWith('SyntaxError: Unexpected end of input') && + !description.startsWith('SyntaxError: Unterminated template literal'); + } }; /** @typedef {{title:(string|undefined), items:Array<string>}} */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptREPL.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptREPL.js new file mode 100644 index 00000000000..bdec0d7627d --- /dev/null +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptREPL.js @@ -0,0 +1,105 @@ +// Copyright 2018 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. + +ObjectUI.JavaScriptREPL = class { + /** + * @param {string} code + * @return {string} + */ + static wrapObjectLiteral(code) { + // Only parenthesize what appears to be an object literal. + if (!(/^\s*\{/.test(code) && /\}\s*$/.test(code))) + return code; + + const parse = (async () => 0).constructor; + try { + // Check if the code can be interpreted as an expression. + parse('return ' + code + ';'); + + // No syntax error! Does it work parenthesized? + const wrappedCode = '(' + code + ')'; + parse(wrappedCode); + + return wrappedCode; + } catch (e) { + return code; + } + } + + /** + * @param {string} text + * @return {!Promise<!{text: string, preprocessed: boolean}>} + */ + static async preprocessExpression(text) { + text = ObjectUI.JavaScriptREPL.wrapObjectLiteral(text); + let preprocessed = false; + if (text.indexOf('await') !== -1) { + const preprocessedText = await Formatter.formatterWorkerPool().preprocessTopLevelAwaitExpressions(text); + preprocessed = !!preprocessedText; + text = preprocessedText || text; + } + return {text, preprocessed}; + } + + /** + * @param {string} text + * @param {boolean} throwOnSideEffect + * @param {number=} timeout + * @param {boolean=} allowErrors + * @return {!Promise<!{preview: !DocumentFragment, result: ?SDK.RuntimeModel.EvaluationResult}>} + */ + static async evaluateAndBuildPreview(text, throwOnSideEffect, timeout, allowErrors) { + const executionContext = UI.context.flavor(SDK.ExecutionContext); + const isTextLong = text.length > ObjectUI.JavaScriptREPL._MaxLengthForEvaluation; + if (!text || !executionContext || (throwOnSideEffect && isTextLong)) + return {preview: createDocumentFragment(), result: null}; + + const wrappedResult = await ObjectUI.JavaScriptREPL.preprocessExpression(text); + const options = { + expression: wrappedResult.text, + generatePreview: true, + includeCommandLineAPI: true, + throwOnSideEffect: throwOnSideEffect, + timeout: timeout + }; + const result = await executionContext.evaluate( + options, false /* userGesture */, wrappedResult.preprocessed /* awaitPromise */); + const preview = ObjectUI.JavaScriptREPL._buildEvaluationPreview(result, allowErrors); + return {preview, result}; + } + + /** + * @param {!SDK.RuntimeModel.EvaluationResult} result + * @param {boolean=} allowErrors + * @return {!DocumentFragment} + */ + static _buildEvaluationPreview(result, allowErrors) { + const fragment = createDocumentFragment(); + if (result.error) + return fragment; + + if (result.exceptionDetails && result.exceptionDetails.exception && result.exceptionDetails.exception.description) { + const exception = result.exceptionDetails.exception.description; + if (exception.startsWith('TypeError: ') || allowErrors) + fragment.createChild('span').textContent = result.exceptionDetails.text + ' ' + exception; + return fragment; + } + + const formatter = new ObjectUI.RemoteObjectPreviewFormatter(); + const {preview, type, subtype, description} = result.object; + if (preview && type === 'object' && subtype !== 'node') { + formatter.appendObjectPreview(fragment, preview, false /* isEntry */); + } else { + const nonObjectPreview = formatter.renderPropertyPreview(type, subtype, description.trimEnd(400)); + fragment.appendChild(nonObjectPreview); + } + return fragment; + } +}; + +/** + * @const + * @type {number} + */ +ObjectUI.JavaScriptREPL._MaxLengthForEvaluation = 2000; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPopoverHelper.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPopoverHelper.js index 5fe611ed978..44b1ee92035 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPopoverHelper.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPopoverHelper.js @@ -71,7 +71,8 @@ ObjectUI.ObjectPopoverHelper = class { const titleElement = popoverContentElement.createChild('div', 'monospace object-popover-title'); titleElement.createChild('span').textContent = description; linkifier = new Components.Linkifier(); - const section = new ObjectUI.ObjectPropertiesSection(result, '', linkifier); + const section = new ObjectUI.ObjectPropertiesSection( + result, '', linkifier, undefined, undefined, undefined, true /* showOverflow */); section.element.classList.add('object-popover-tree'); section.titleLessMode(); popoverContentElement.appendChild(section.element); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js index 88a7f85ddff..076cf7645d0 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js @@ -35,13 +35,16 @@ ObjectUI.ObjectPropertiesSection = class extends UI.TreeOutlineInShadow { * @param {?string=} emptyPlaceholder * @param {boolean=} ignoreHasOwnProperty * @param {!Array.<!SDK.RemoteObjectProperty>=} extraProperties + * @param {boolean=} showOverflow */ - constructor(object, title, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties) { + constructor(object, title, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, showOverflow) { super(); this._object = object; this._editable = true; - this.hideOverflow(); - this.setFocusable(false); + if (!showOverflow) + this.hideOverflow(); + this.setFocusable(true); + this.setShowSelectionOnKeyboardFocus(true); this._objectTreeElement = new ObjectUI.ObjectPropertiesSection.RootElement( object, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties); this.appendChild(this._objectTreeElement); @@ -435,7 +438,7 @@ ObjectUI.ObjectPropertiesSection.RootElement = class extends UI.TreeElement { this._emptyPlaceholder = emptyPlaceholder; this.setExpandable(true); - this.selectable = false; + this.selectable = true; this.toggleOnClick = true; this.listItemElement.classList.add('object-properties-section-root-element'); this._linkifier = linkifier; @@ -490,7 +493,6 @@ ObjectUI.ObjectPropertyTreeElement = class extends UI.TreeElement { this.property = property; this.toggleOnClick = true; - this.selectable = false; /** @type {!Array.<!Object>} */ this._highlightChanges = []; this._linkifier = linkifier; @@ -792,7 +794,7 @@ ObjectUI.ObjectPropertyTreeElement = class extends UI.TreeElement { this.expandedValueElement = this._createExpandedValueElement(this.property.value); this.listItemElement.removeChildren(); - this._rowContainer = UI.html`<span>${this.nameElement}: ${this.valueElement}</span>`; + this._rowContainer = UI.html`<span class='name-and-value'>${this.nameElement}: ${this.valueElement}</span>`; this.listItemElement.appendChild(this._rowContainer); } @@ -864,6 +866,7 @@ ObjectUI.ObjectPropertyTreeElement = class extends UI.TreeElement { const proxyElement = this._prompt.attachAndStartEditing(this._editableDiv, this._editingCommitted.bind(this, originalContent)); + proxyElement.classList.add('property-prompt'); this.listItemElement.getComponentSelection().selectAllChildren(this._editableDiv); proxyElement.addEventListener('keydown', this._promptKeyDown.bind(this, originalContent), false); } @@ -918,7 +921,7 @@ ObjectUI.ObjectPropertyTreeElement = class extends UI.TreeElement { */ async _applyExpression(expression) { const property = SDK.RemoteObject.toCallArgument(this.property.symbol || this.property.name); - expression = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(expression.trim()); + expression = ObjectUI.JavaScriptREPL.wrapObjectLiteral(expression.trim()); if (this.property.synthetic) { let invalidate = false; @@ -1000,7 +1003,6 @@ ObjectUI.ArrayGroupingTreeElement = class extends UI.TreeElement { constructor(object, fromIndex, toIndex, propertyCount, linkifier) { super(String.sprintf('[%d \u2026 %d]', fromIndex, toIndex), true); this.toggleOnClick = true; - this.selectable = false; this._fromIndex = fromIndex; this._toIndex = toIndex; this._object = object; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js index 3a67026133a..37c61c7f280 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js @@ -32,7 +32,7 @@ ObjectUI.RemoteObjectPreviewFormatter = class { } /** - * @param {!Element} parentElement + * @param {!DocumentFragment|!Element} parentElement * @param {!Protocol.Runtime.ObjectPreview} preview * @param {boolean} isEntry */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json index 3cfab8316a3..d56753b9a10 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json @@ -19,6 +19,7 @@ "ObjectPopoverHelper.js", "ObjectPropertiesSection.js", "JavaScriptAutocomplete.js", + "JavaScriptREPL.js", "RemoteObjectPreviewFormatter.js" ], "resources": [ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/objectPropertiesSection.css b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/objectPropertiesSection.css index 6b4df5f92e9..1ef1a87609d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/objectPropertiesSection.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/objectPropertiesSection.css @@ -50,3 +50,18 @@ .object-properties-section .editable-div { overflow: hidden; } + +.name-and-value { + overflow: hidden; + text-overflow: ellipsis; + line-height: normal; +} + +.editing-sub-part .name-and-value { + overflow: visible; + display: inline-flex; +} + +.property-prompt { + margin-left: 4px; +} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js b/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js index 327fd7a722b..86f2a163a4a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js @@ -73,13 +73,18 @@ PerfUI.FlameChart = class extends UI.VBox { this._groupExpansionState = groupExpansionSetting && groupExpansionSetting.get() || {}; this._flameChartDelegate = flameChartDelegate; + this._useWebGL = Runtime.experiments.isEnabled('timelineWebGL'); this._chartViewport = new PerfUI.ChartViewport(this); this._chartViewport.show(this.contentElement); this._dataProvider = dataProvider; this._viewportElement = this._chartViewport.viewportElement; - this._canvas = /** @type {!HTMLCanvasElement} */ (this._viewportElement.createChild('canvas')); + if (this._useWebGL) { + this._canvasGL = /** @type {!HTMLCanvasElement} */ (this._viewportElement.createChild('canvas', 'fill')); + this._initWebGL(); + } + this._canvas = /** @type {!HTMLCanvasElement} */ (this._viewportElement.createChild('canvas', 'fill')); this._canvas.tabIndex = 0; this.setDefaultFocusedElement(this._canvas); @@ -204,6 +209,12 @@ PerfUI.FlameChart = class extends UI.VBox { this._canvas.height = height; this._canvas.style.width = `${width / ratio}px`; this._canvas.style.height = `${height / ratio}px`; + if (this._useWebGL) { + this._canvasGL.width = width; + this._canvasGL.height = height; + this._canvasGL.style.width = `${width / ratio}px`; + this._canvasGL.style.height = `${height / ratio}px`; + } } /** @@ -683,6 +694,8 @@ PerfUI.FlameChart = class extends UI.VBox { const ratio = window.devicePixelRatio; const top = this._chartViewport.scrollOffset(); context.scale(ratio, ratio); + context.fillStyle = 'rgba(0, 0, 0, 0)'; + context.fillRect(0, 0, width, height); context.translate(0, -top); const defaultFont = '11px ' + Host.fontFamily(); context.font = defaultFont; @@ -696,17 +709,9 @@ PerfUI.FlameChart = class extends UI.VBox { const markerIndices = []; const textPadding = this._textPadding; const minTextWidth = 2 * textPadding + UI.measureTextWidth(context, '\u2026'); + const minTextWidthDuration = this._chartViewport.pixelToTimeOffset(minTextWidth); const minVisibleBarLevel = Math.max(this._visibleLevelOffsets.upperBound(top) - 1, 0); - context.save(); - this._forEachGroup((offset, index, group, isFirst, groupHeight) => { - if (index === this._selectedGroup) { - context.fillStyle = this._selectedGroupBackroundColor; - context.fillRect(0, offset, width, groupHeight - group.style.padding); - } - }); - context.restore(); - /** @type {!Map<string, !Array<number>>} */ const colorBuckets = new Map(); for (let level = minVisibleBarLevel; level < this._dataProvider.maxStackDepth(); ++level) { @@ -724,10 +729,19 @@ PerfUI.FlameChart = class extends UI.VBox { let lastDrawOffset = Infinity; for (let entryIndexOnLevel = rightIndexOnLevel; entryIndexOnLevel >= 0; --entryIndexOnLevel) { const entryIndex = levelIndexes[entryIndexOnLevel]; + let duration = entryTotalTimes[entryIndex]; + if (isNaN(duration)) + markerIndices.push(entryIndex); + duration = duration || 0; + if (duration >= minTextWidthDuration || this._forceDecorationCache[entryIndex]) + titleIndices.push(entryIndex); + const entryStartTime = entryStartTimes[entryIndex]; - const entryOffsetRight = entryStartTime + (entryTotalTimes[entryIndex] || 0); + const entryOffsetRight = entryStartTime + duration; if (entryOffsetRight <= this._chartViewport.windowLeftTime()) break; + if (this._useWebGL) + continue; const barX = this._timeToPositionClipped(entryStartTime); // Check if the entry entirely fits into an already drawn pixel, we can just skip drawing it. @@ -735,7 +749,7 @@ PerfUI.FlameChart = class extends UI.VBox { continue; lastDrawOffset = barX; - const color = this._dataProvider.entryColor(entryIndex); + const color = this._entryColorsCache[entryIndex]; let bucket = colorBuckets.get(color); if (!bucket) { bucket = []; @@ -745,37 +759,47 @@ PerfUI.FlameChart = class extends UI.VBox { } } - const colors = colorBuckets.keysArray(); - // We don't use for-of here because it's slow. - for (let c = 0; c < colors.length; ++c) { - const color = colors[c]; - const indexes = colorBuckets.get(color); - context.beginPath(); - for (let i = 0; i < indexes.length; ++i) { - const entryIndex = indexes[i]; - const entryStartTime = entryStartTimes[entryIndex]; - const barX = this._timeToPositionClipped(entryStartTime); - const duration = entryTotalTimes[entryIndex]; - const barLevel = entryLevels[entryIndex]; - const barHeight = this._levelHeight(barLevel); - const barY = this._levelToOffset(barLevel); - if (isNaN(duration)) { - context.moveTo(barX + this._markerRadius, barY + barHeight / 2); - context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2); - markerIndices.push(entryIndex); - continue; + if (this._useWebGL) { + this._drawGL(); + } else { + context.save(); + this._forEachGroupInViewport((offset, index, group, isFirst, groupHeight) => { + if (index === this._selectedGroup) { + context.fillStyle = this._selectedGroupBackroundColor; + context.fillRect(0, offset, width, groupHeight - group.style.padding); } - const barRight = this._timeToPositionClipped(entryStartTime + duration); - const barWidth = Math.max(barRight - barX, 1); - if (color) - context.rect(barX, barY, barWidth - 0.4, barHeight - 1); - if (barWidth > minTextWidth || this._dataProvider.forceDecoration(entryIndex)) - titleIndices.push(entryIndex); + }); + context.restore(); + + const colors = colorBuckets.keysArray(); + // We don't use for-of here because it's slow. + for (let c = 0; c < colors.length; ++c) { + const color = colors[c]; + const indexes = colorBuckets.get(color); + context.beginPath(); + for (let i = 0; i < indexes.length; ++i) { + const entryIndex = indexes[i]; + const entryStartTime = entryStartTimes[entryIndex]; + const barX = this._timeToPositionClipped(entryStartTime); + const duration = entryTotalTimes[entryIndex]; + const barLevel = entryLevels[entryIndex]; + const barHeight = this._levelHeight(barLevel); + const barY = this._levelToOffset(barLevel); + if (isNaN(duration)) { + context.moveTo(barX + this._markerRadius, barY + barHeight / 2); + context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2); + continue; + } + const barRight = this._timeToPositionClipped(entryStartTime + duration); + const barWidth = Math.max(barRight - barX, 1); + if (color) + context.rect(barX, barY, barWidth - 0.4, barHeight - 1); + } + if (!color) + continue; + context.fillStyle = color; + context.fill(); } - if (!color) - continue; - context.fillStyle = color; - context.fill(); } context.beginPath(); @@ -834,6 +858,218 @@ PerfUI.FlameChart = class extends UI.VBox { this._updateMarkerHighlight(); } + _initWebGL() { + const gl = /** @type {?WebGLRenderingContext} */ (this._canvasGL.getContext('webgl')); + if (!gl) { + console.error('Failed to obtain WebGL context.'); + this._useWebGL = false; // Fallback to use canvas. + return; + } + + const vertexShaderSource = ` + attribute vec2 aVertexPosition; + attribute float aVertexColor; + + uniform vec2 uScalingFactor; + uniform vec2 uShiftVector; + + varying mediump vec2 vPalettePosition; + + void main() { + vec2 shiftedPosition = aVertexPosition - uShiftVector; + gl_Position = vec4(shiftedPosition * uScalingFactor + vec2(-1.0, 1.0), 0.0, 1.0); + vPalettePosition = vec2(aVertexColor, 0.5); + }`; + + const fragmentShaderSource = ` + varying mediump vec2 vPalettePosition; + uniform sampler2D uSampler; + + void main() { + gl_FragColor = texture2D(uSampler, vPalettePosition); + }`; + + /** + * @param {!WebGLRenderingContext} gl + * @param {number} type + * @param {string} source + * @return {?WebGLShader} + */ + function loadShader(gl, type, source) { + const shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) + return shader; + console.error('Shader compile error: ' + gl.getShaderInfoLog(shader)); + gl.deleteShader(shader); + return null; + } + + const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vertexShaderSource); + const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource); + + const shaderProgram = gl.createProgram(); + gl.attachShader(shaderProgram, vertexShader); + gl.attachShader(shaderProgram, fragmentShader); + gl.linkProgram(shaderProgram); + + if (gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { + this._shaderProgram = shaderProgram; + gl.useProgram(shaderProgram); + } else { + console.error('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram)); + this._shaderProgram = null; + } + + this._vertexBuffer = gl.createBuffer(); + this._colorBuffer = gl.createBuffer(); + + this._uScalingFactor = gl.getUniformLocation(shaderProgram, 'uScalingFactor'); + this._uShiftVector = gl.getUniformLocation(shaderProgram, 'uShiftVector'); + const uSampler = gl.getUniformLocation(shaderProgram, 'uSampler'); + gl.uniform1i(uSampler, 0); + this._aVertexPosition = gl.getAttribLocation(this._shaderProgram, 'aVertexPosition'); + this._aVertexColor = gl.getAttribLocation(this._shaderProgram, 'aVertexColor'); + gl.enableVertexAttribArray(this._aVertexPosition); + gl.enableVertexAttribArray(this._aVertexColor); + } + + _setupGLGeometry() { + const gl = /** @type {?WebGLRenderingContext} */ (this._canvasGL.getContext('webgl')); + if (!gl) + return; + + const timelineData = this._timelineData(); + if (!timelineData) + return; + + const entryTotalTimes = timelineData.entryTotalTimes; + const entryStartTimes = timelineData.entryStartTimes; + const entryLevels = timelineData.entryLevels; + + const verticesPerBar = 6; + const vertexArray = new Float32Array(entryTotalTimes.length * verticesPerBar * 2); + let colorArray = new Uint8Array(entryTotalTimes.length * verticesPerBar); + let vertex = 0; + /** @type {!Map<string, number>} */ + const parsedColorCache = new Map(); + /** @type {!Array<number>} */ + const colors = []; + + const collapsedOverviewLevels = new Array(this._visibleLevels.length); + const groups = this._rawTimelineData.groups || []; + this._forEachGroup((offset, index, group) => { + if (group.style.useFirstLineForOverview || !this._isGroupCollapsible(index) || group.expanded) + return; + let nextGroup = index + 1; + while (nextGroup < groups.length && groups[nextGroup].style.nestingLevel > group.style.nestingLevel) + ++nextGroup; + const endLevel = nextGroup < groups.length ? groups[nextGroup].startLevel : this._dataProvider.maxStackDepth(); + for (let i = group.startLevel; i < endLevel; ++i) + collapsedOverviewLevels[i] = offset; + }); + + for (let i = 0; i < entryTotalTimes.length; ++i) { + const level = entryLevels[i]; + const collapsedGroupOffset = collapsedOverviewLevels[level]; + if (!this._visibleLevels[level] && !collapsedGroupOffset) + continue; + const color = this._entryColorsCache[i]; + if (!color) + continue; + let colorIndex = parsedColorCache.get(color); + if (colorIndex === undefined) { + const rgba = Common.Color.parse(color).canonicalRGBA(); + rgba[3] = Math.round(rgba[3] * 255); + colorIndex = colors.length / 4; + colors.push(...rgba); + if (colorIndex === 256) + colorArray = new Uint16Array(colorArray); + parsedColorCache.set(color, colorIndex); + } + for (let j = 0; j < verticesPerBar; ++j) + colorArray[vertex + j] = colorIndex; + + const vpos = vertex * 2; + const x0 = entryStartTimes[i] - this._minimumBoundary; + const x1 = x0 + entryTotalTimes[i]; + const y0 = collapsedGroupOffset || this._levelToOffset(level); + const y1 = y0 + this._levelHeight(level) - 1; + vertexArray[vpos + 0] = x0; + vertexArray[vpos + 1] = y0; + vertexArray[vpos + 2] = x1; + vertexArray[vpos + 3] = y0; + vertexArray[vpos + 4] = x0; + vertexArray[vpos + 5] = y1; + vertexArray[vpos + 6] = x0; + vertexArray[vpos + 7] = y1; + vertexArray[vpos + 8] = x1; + vertexArray[vpos + 9] = y0; + vertexArray[vpos + 10] = x1; + vertexArray[vpos + 11] = y1; + + vertex += verticesPerBar; + } + this._vertexCount = vertex; + + const paletteTexture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, paletteTexture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.activeTexture(gl.TEXTURE0); + + const numColors = colors.length / 4; + const useShortForColors = numColors >= 256; + const width = !useShortForColors ? 256 : Math.min(1 << 16, gl.getParameter(gl.MAX_TEXTURE_SIZE)); + console.assert(numColors <= width, 'Too many colors'); + const height = 1; + const colorIndexType = useShortForColors ? gl.UNSIGNED_SHORT : gl.UNSIGNED_BYTE; + if (useShortForColors) { + const factor = (1 << 16) / width; + for (let i = 0; i < vertex; ++i) + colorArray[i] *= factor; + } + + const pixels = new Uint8Array(width * 4); + pixels.set(colors); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + + gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, vertexArray, gl.STATIC_DRAW); + gl.vertexAttribPointer(this._aVertexPosition, /* vertexComponents */ 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, colorArray, gl.STATIC_DRAW); + gl.vertexAttribPointer(this._aVertexColor, /* colorComponents */ 1, colorIndexType, true, 0, 0); + } + + _drawGL() { + const gl = /** @type {?WebGLRenderingContext} */ (this._canvasGL.getContext('webgl')); + if (!gl) + return; + const timelineData = this._timelineData(); + if (!timelineData) + return; + + if (!this._prevTimelineData || timelineData.entryTotalTimes !== this._prevTimelineData.entryTotalTimes) { + this._prevTimelineData = timelineData; + this._setupGLGeometry(); + } + + gl.viewport(0, 0, this._canvasGL.width, this._canvasGL.height); + + if (!this._vertexCount) + return; + + const viewportScale = [2.0 / this.boundarySpan(), -2.0 * window.devicePixelRatio / this._canvasGL.height]; + const viewportShift = [this.minimumBoundary() - this.zeroTime(), this._chartViewport.scrollOffset()]; + gl.uniform2fv(this._uScalingFactor, viewportScale); + gl.uniform2fv(this._uShiftVector, viewportShift); + + gl.drawArrays(gl.TRIANGLES, 0, this._vertexCount); + } + /** * @param {number} width * @param {number} height @@ -857,7 +1093,7 @@ PerfUI.FlameChart = class extends UI.VBox { context.font = defaultFont; context.fillStyle = UI.themeSupport.patchColorText('#fff', colorUsage.Background); - this._forEachGroup((offset, index, group) => { + this._forEachGroupInViewport((offset, index, group) => { const paddingHeight = group.style.padding; if (paddingHeight < 5) return; @@ -868,7 +1104,7 @@ PerfUI.FlameChart = class extends UI.VBox { context.strokeStyle = UI.themeSupport.patchColorText('#eee', colorUsage.Background); context.beginPath(); - this._forEachGroup((offset, index, group, isFirst) => { + this._forEachGroupInViewport((offset, index, group, isFirst) => { if (isFirst || group.style.padding < 4) return; hLine(offset - 2.5); @@ -876,7 +1112,7 @@ PerfUI.FlameChart = class extends UI.VBox { hLine(lastGroupOffset + 1.5); context.stroke(); - this._forEachGroup((offset, index, group) => { + this._forEachGroupInViewport((offset, index, group) => { if (group.style.useFirstLineForOverview) return; if (!this._isGroupCollapsible(index) || group.expanded) { @@ -886,6 +1122,8 @@ PerfUI.FlameChart = class extends UI.VBox { } return; } + if (this._useWebGL) + return; let nextGroup = index + 1; while (nextGroup < groups.length && groups[nextGroup].style.nestingLevel > group.style.nestingLevel) nextGroup++; @@ -894,7 +1132,7 @@ PerfUI.FlameChart = class extends UI.VBox { }); context.save(); - this._forEachGroup((offset, index, group) => { + this._forEachGroupInViewport((offset, index, group) => { context.font = group.style.font; if (this._isGroupCollapsible(index) && !group.expanded || group.style.shareHeaderLine) { const width = this._labelWidthForGroup(context, group) + 2; @@ -916,7 +1154,7 @@ PerfUI.FlameChart = class extends UI.VBox { context.fillStyle = UI.themeSupport.patchColorText('#6e6e6e', colorUsage.Foreground); context.beginPath(); - this._forEachGroup((offset, index, group) => { + this._forEachGroupInViewport((offset, index, group) => { if (this._isGroupCollapsible(index)) { drawExpansionArrow.call( this, this._expansionArrowIndent * (group.style.nestingLevel + 1), @@ -929,7 +1167,7 @@ PerfUI.FlameChart = class extends UI.VBox { context.beginPath(); context.stroke(); - this._forEachGroup((offset, index, group, isFirst, groupHeight) => { + this._forEachGroupInViewport((offset, index, group, isFirst, groupHeight) => { if (index === this._selectedGroup) { const lineWidth = 2; const bracketLength = 10; @@ -973,7 +1211,6 @@ PerfUI.FlameChart = class extends UI.VBox { * @param {function(number, number, !PerfUI.FlameChart.Group, boolean, number)} callback */ _forEachGroup(callback) { - const top = this._chartViewport.scrollOffset(); const groups = this._rawTimelineData.groups || []; if (!groups.length) return; @@ -983,8 +1220,6 @@ PerfUI.FlameChart = class extends UI.VBox { for (let i = 0; i < groups.length; ++i) { const groupTop = groupOffsets[i]; const group = groups[i]; - if (groupTop - group.style.padding > top + this._offsetHeight) - break; let firstGroup = true; while (groupStack.peekLast().nestingLevel >= group.style.nestingLevel) { groupStack.pop(); @@ -994,13 +1229,27 @@ PerfUI.FlameChart = class extends UI.VBox { const thisGroupVisible = parentGroupVisible && (!this._isGroupCollapsible(i) || group.expanded); groupStack.push({nestingLevel: group.style.nestingLevel, visible: thisGroupVisible}); const nextOffset = i === groups.length - 1 ? groupOffsets[i + 1] + group.style.padding : groupOffsets[i + 1]; - if (!parentGroupVisible || nextOffset < top) + if (!parentGroupVisible) continue; callback(groupTop, i, group, firstGroup, nextOffset - groupTop); } } /** + * @param {function(number, number, !PerfUI.FlameChart.Group, boolean, number)} callback + */ + _forEachGroupInViewport(callback) { + const top = this._chartViewport.scrollOffset(); + this._forEachGroup((groupTop, index, group, firstGroup, height) => { + if (groupTop - group.style.padding > top + this._offsetHeight) + return; + if (groupTop + height < top) + return; + callback(groupTop, index, group, firstGroup, height); + }); + } + + /** * @param {!CanvasRenderingContext2D} context * @param {!PerfUI.FlameChart.Group} group * @return {number} @@ -1041,7 +1290,7 @@ PerfUI.FlameChart = class extends UI.VBox { if (entryEndTime <= timeWindowLeft) break; lastDrawOffset = barX; - const color = this._dataProvider.entryColor(entryIndex); + const color = this._entryColorsCache[entryIndex]; const endBarX = this._timeToPositionClipped(entryEndTime); if (group.style.useDecoratorsForOverview && this._dataProvider.forceDecoration(entryIndex)) { const unclippedBarX = this._chartViewport.timeToPosition(entryStartTime); @@ -1197,6 +1446,8 @@ PerfUI.FlameChart = class extends UI.VBox { this._visibleLevels = null; this._groupOffsets = null; this._rawTimelineData = null; + this._forceDecorationCache = null; + this._entryColorsCache = null; this._rawTimelineDataLength = 0; this._selectedGroup = -1; this._flameChartDelegate.updateSelectedGroup(this, null); @@ -1205,6 +1456,12 @@ PerfUI.FlameChart = class extends UI.VBox { this._rawTimelineData = timelineData; this._rawTimelineDataLength = timelineData.entryStartTimes.length; + this._forceDecorationCache = new Int8Array(this._rawTimelineDataLength); + this._entryColorsCache = new Array(this._rawTimelineDataLength); + for (let i = 0; i < this._rawTimelineDataLength; ++i) { + this._forceDecorationCache[i] = this._dataProvider.forceDecoration(i) ? 1 : 0; + this._entryColorsCache[i] = this._dataProvider.entryColor(i); + } const entryCounters = new Uint32Array(this._dataProvider.maxStackDepth() + 1); for (let i = 0; i < timelineData.entryLevels.length; ++i) @@ -1293,6 +1550,8 @@ PerfUI.FlameChart = class extends UI.VBox { if (groupIndex >= 0) this._groupOffsets[groupIndex + 1] = currentOffset; this._visibleLevelOffsets[level] = currentOffset; + if (this._useWebGL) + this._setupGLGeometry(); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js index ab71f335d83..68feae279ac 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js @@ -114,8 +114,7 @@ Persistence.Automapping = class { _onUISourceCodeAdded(uiSourceCode) { const project = uiSourceCode.project(); if (project.type() === Workspace.projectTypes.FileSystem) { - // Never do bindings to filesystems that are typed to another client. - if (Persistence.FileSystemWorkspaceBinding.fileSystemType(project)) + if (!Persistence.FileSystemWorkspaceBinding.fileSystemSupportsAutomapping(project)) return; this._filesIndex.addPath(uiSourceCode.url()); this._fileSystemUISourceCodes.set(uiSourceCode.url(), uiSourceCode); @@ -179,6 +178,8 @@ Persistence.Automapping = class { async function validateStatus(status) { if (!status) return null; + if (networkSourceCode[Persistence.Automapping._processingPromise] !== createBindingPromise) + return null; if (status.network.contentType().isFromSourceMap() || !status.fileSystem.contentType().isTextType()) return status; @@ -297,7 +298,7 @@ Persistence.Automapping = class { * @return {!Promise<?Persistence.AutomappingStatus>} */ _createBinding(networkSourceCode) { - if (networkSourceCode.url().startsWith('file://')) { + if (networkSourceCode.url().startsWith('file://') || networkSourceCode.url().startsWith('snippet://')) { const fileSourceCode = this._fileSystemUISourceCodes.get(networkSourceCode.url()); const status = fileSourceCode ? new Persistence.AutomappingStatus(networkSourceCode, fileSourceCode, false) : null; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/FileSystemWorkspaceBinding.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/FileSystemWorkspaceBinding.js index ceb171c55b8..bbf6ce73481 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/FileSystemWorkspaceBinding.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/FileSystemWorkspaceBinding.js @@ -71,6 +71,16 @@ Persistence.FileSystemWorkspaceBinding = class { } /** + * @param {!Workspace.UISourceCode} uiSourceCode + * @return {string} + */ + static tooltipForUISourceCode(uiSourceCode) { + const fileSystem = + /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem}*/ (uiSourceCode.project())._fileSystem; + return fileSystem.tooltipForURL(uiSourceCode.url()); + } + + /** * @param {!Workspace.Project} project * @return {string} */ @@ -82,6 +92,16 @@ Persistence.FileSystemWorkspaceBinding = class { /** * @param {!Workspace.Project} project + * @return {boolean} + */ + static fileSystemSupportsAutomapping(project) { + const fileSystem = + /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem}*/ (project)._fileSystem; + return fileSystem.supportsAutomapping(); + } + + /** + * @param {!Workspace.Project} project * @param {string} relativePath * @return {string} */ @@ -91,23 +111,6 @@ Persistence.FileSystemWorkspaceBinding = class { } /** - * @param {string} extension - * @return {!Common.ResourceType} - */ - static _contentTypeForExtension(extension) { - if (Persistence.FileSystemWorkspaceBinding._styleSheetExtensions.has(extension)) - return Common.resourceTypes.Stylesheet; - if (Persistence.FileSystemWorkspaceBinding._documentExtensions.has(extension)) - return Common.resourceTypes.Document; - if (Persistence.FileSystemWorkspaceBinding._imageExtensions.has(extension)) - return Common.resourceTypes.Image; - if (Persistence.FileSystemWorkspaceBinding._scriptExtensions.has(extension)) - return Common.resourceTypes.Script; - return Persistence.FileSystemWorkspaceBinding._binaryExtensions.has(extension) ? Common.resourceTypes.Other : - Common.resourceTypes.Document; - } - - /** * @param {string} projectId * @return {string} */ @@ -134,12 +137,12 @@ Persistence.FileSystemWorkspaceBinding = class { * @param {!Common.Event} event */ _onFileSystemAdded(event) { - const fileSystem = /** @type {!Persistence.IsolatedFileSystem} */ (event.data); + const fileSystem = /** @type {!Persistence.PlatformFileSystem} */ (event.data); this._addFileSystem(fileSystem); } /** - * @param {!Persistence.IsolatedFileSystem} fileSystem + * @param {!Persistence.PlatformFileSystem} fileSystem */ _addFileSystem(fileSystem) { const boundFileSystem = new Persistence.FileSystemWorkspaceBinding.FileSystem(this, fileSystem, this._workspace); @@ -150,7 +153,7 @@ Persistence.FileSystemWorkspaceBinding = class { * @param {!Common.Event} event */ _onFileSystemRemoved(event) { - const fileSystem = /** @type {!Persistence.IsolatedFileSystem} */ (event.data); + const fileSystem = /** @type {!Persistence.PlatformFileSystem} */ (event.data); const boundFileSystem = this._boundFileSystems.get(fileSystem.path()); boundFileSystem.dispose(); this._boundFileSystems.remove(fileSystem.path()); @@ -192,17 +195,6 @@ Persistence.FileSystemWorkspaceBinding = class { } }; -Persistence.FileSystemWorkspaceBinding._styleSheetExtensions = new Set(['css', 'scss', 'sass', 'less']); -Persistence.FileSystemWorkspaceBinding._documentExtensions = new Set(['htm', 'html', 'asp', 'aspx', 'phtml', 'jsp']); -Persistence.FileSystemWorkspaceBinding._scriptExtensions = new Set([ - 'asp', 'aspx', 'c', 'cc', 'cljs', 'coffee', 'cpp', 'cs', 'dart', 'java', 'js', - 'jsp', 'jsx', 'h', 'm', 'mjs', 'mm', 'py', 'sh', 'ts', 'tsx', 'ls' -]); - -Persistence.FileSystemWorkspaceBinding._imageExtensions = Persistence.IsolatedFileSystem.ImageExtensions; - -Persistence.FileSystemWorkspaceBinding._binaryExtensions = Persistence.IsolatedFileSystem.BinaryExtensions; - /** * @implements {Workspace.Project} * @unrestricted @@ -210,7 +202,7 @@ Persistence.FileSystemWorkspaceBinding._binaryExtensions = Persistence.IsolatedF Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.ProjectStore { /** * @param {!Persistence.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding - * @param {!Persistence.IsolatedFileSystem} isolatedFileSystem + * @param {!Persistence.PlatformFileSystem} isolatedFileSystem * @param {!Workspace.Workspace} workspace */ constructor(fileSystemWorkspaceBinding, isolatedFileSystem, workspace) { @@ -246,7 +238,7 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj * @return {string} */ mimeType(uiSourceCode) { - return Common.ResourceType.mimeFromURL(uiSourceCode.url()) || 'text/plain'; + return this._fileSystem.mimeFromPath(uiSourceCode.url()); } /** @@ -383,9 +375,8 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj const parentPath = filePath.substring(0, slash); filePath = parentPath + '/' + newName; filePath = filePath.substr(1); - const extension = this._extensionForPath(newName); const newURL = this._fileSystemBaseURL + filePath; - const newContentType = Persistence.FileSystemWorkspaceBinding._contentTypeForExtension(extension); + const newContentType = this._fileSystem.contentType(newName); this.renameUISourceCode(uiSourceCode, newName); callback(true, newName, newURL, newContentType); } @@ -445,14 +436,6 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj this._fileSystem.indexContent(progress); } - /** - * @param {string} path - * @return {string} - */ - _extensionForPath(path) { - return Common.ParsedURL.extractExtension(path); - } - populate() { const chunkSize = 1000; const filePaths = this._fileSystem.initialFilePaths(); @@ -497,7 +480,7 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj * @return {boolean} */ canExcludeFolder(path) { - return !!path && Persistence.FileSystemWorkspaceBinding.fileSystemType(this) !== 'overrides'; + return this._fileSystem.canExcludeFolder(path); } /** @@ -552,9 +535,7 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj * @return {!Workspace.UISourceCode} */ _addFile(filePath) { - const extension = this._extensionForPath(filePath); - const contentType = Persistence.FileSystemWorkspaceBinding._contentTypeForExtension(extension); - + const contentType = this._fileSystem.contentType(filePath); const uiSourceCode = this.createUISourceCode(this._fileSystemBaseURL + filePath, contentType); this.addUISourceCode(uiSourceCode); return uiSourceCode; @@ -569,7 +550,7 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj return; const uiSourceCode = this.uiSourceCodeForURL(path); if (!uiSourceCode) { - const contentType = Persistence.FileSystemWorkspaceBinding._contentTypeForExtension(this._extensionForPath(path)); + const contentType = this._fileSystem.contentType(path); this.addUISourceCode(this.createUISourceCode(path, contentType)); return; } @@ -577,6 +558,14 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj uiSourceCode.checkContentUpdated(); } + /** + * @param {string} url + * @return {string} + */ + tooltipForURL(url) { + return this._fileSystem.tooltipForURL(url); + } + dispose() { this.removeProject(); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystem.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystem.js index 40ecbcf75d8..5756f749b99 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystem.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystem.js @@ -27,11 +27,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /** * @unrestricted */ -Persistence.IsolatedFileSystem = class { +Persistence.IsolatedFileSystem = class extends Persistence.PlatformFileSystem { /** * @param {!Persistence.IsolatedFileSystemManager} manager * @param {string} path @@ -40,11 +39,10 @@ Persistence.IsolatedFileSystem = class { * @param {string} type */ constructor(manager, path, embedderPath, domFileSystem, type) { + super(path, type); this._manager = manager; - this._path = path; this._embedderPath = embedderPath; this._domFileSystem = domFileSystem; - this._type = type; this._excludedFoldersSetting = Common.settings.createLocalSetting('workspaceExcludedFolders', {}); /** @type {!Set<string>} */ this._excludedFolders = new Set(this._excludedFoldersSetting.get()[path] || []); @@ -100,6 +98,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @param {string} path * @return {!Promise<?{modificationTime: !Date, size: number}>} */ @@ -127,6 +126,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @return {!Array<string>} */ initialFilePaths() { @@ -134,6 +134,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @return {!Array<string>} */ initialGitFolders() { @@ -141,13 +142,7 @@ Persistence.IsolatedFileSystem = class { } /** - * @return {string} - */ - path() { - return this._path; - } - - /** + * @override * @return {string} */ embedderPath() { @@ -155,13 +150,6 @@ Persistence.IsolatedFileSystem = class { } /** - * @return {string} - */ - type() { - return this._type; - } - - /** * @return {!Promise} */ _initializeFilePaths() { @@ -191,7 +179,7 @@ Persistence.IsolatedFileSystem = class { } if (this.isFileExcluded(entry.fullPath + '/')) { this._excludedEmbedderFolders.push( - Common.ParsedURL.urlToPlatformPath(this._path + entry.fullPath, Host.isWin())); + Common.ParsedURL.urlToPlatformPath(this.path() + entry.fullPath, Host.isWin())); continue; } ++pendingRequests; @@ -239,6 +227,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @param {string} path * @param {?string} name * @return {!Promise<?string>} @@ -268,7 +257,7 @@ Persistence.IsolatedFileSystem = class { } const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error); console.error( - errorMessage + ' when testing if file exists \'' + (this._path + '/' + path + '/' + nameCandidate) + + errorMessage + ' when testing if file exists \'' + (this.path() + '/' + path + '/' + nameCandidate) + '\''); resolve(null); }); @@ -277,6 +266,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @param {string} path * @return {!Promise<boolean>} */ @@ -306,12 +296,13 @@ Persistence.IsolatedFileSystem = class { */ function errorHandler(error) { const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error); - console.error(errorMessage + ' when deleting file \'' + (this._path + '/' + path) + '\''); + console.error(errorMessage + ' when deleting file \'' + (this.path() + '/' + path) + '\''); resolveCallback(false); } } /** + * @override * @param {string} path * @return {!Promise<?Blob>} */ @@ -331,13 +322,14 @@ Persistence.IsolatedFileSystem = class { } const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error); - console.error(errorMessage + ' when getting content for file \'' + (this._path + '/' + path) + '\''); + console.error(errorMessage + ' when getting content for file \'' + (this.path() + '/' + path) + '\''); resolve(null); } }); } /** + * @override * @param {string} path * @param {function(?string,boolean)} callback */ @@ -381,6 +373,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @param {string} path * @param {string} content * @param {boolean} isBase64 @@ -429,12 +422,13 @@ Persistence.IsolatedFileSystem = class { */ function errorHandler(error) { const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error); - console.error(errorMessage + ' when setting content for file \'' + (this._path + '/' + path) + '\''); + console.error(errorMessage + ' when setting content for file \'' + (this.path() + '/' + path) + '\''); callback(); } } /** + * @override * @param {string} path * @param {string} newName * @param {function(boolean, string=)} callback @@ -503,7 +497,7 @@ Persistence.IsolatedFileSystem = class { */ function errorHandler(error) { const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error); - console.error(errorMessage + ' when renaming file \'' + (this._path + '/' + path) + '\' to \'' + newName + '\''); + console.error(errorMessage + ' when renaming file \'' + (this.path() + '/' + path) + '\' to \'' + newName + '\''); callback(false); } } @@ -562,11 +556,12 @@ Persistence.IsolatedFileSystem = class { _saveExcludedFolders() { const settingValue = this._excludedFoldersSetting.get(); - settingValue[this._path] = this._excludedFolders.valuesArray(); + settingValue[this.path()] = this._excludedFolders.valuesArray(); this._excludedFoldersSetting.set(settingValue); } /** + * @override * @param {string} path */ addExcludedFolder(path) { @@ -576,6 +571,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @param {string} path */ removeExcludedFolder(path) { @@ -584,13 +580,17 @@ Persistence.IsolatedFileSystem = class { this._manager.dispatchEventToListeners(Persistence.IsolatedFileSystemManager.Events.ExcludedFolderRemoved, path); } + /** + * @override + */ fileSystemRemoved() { const settingValue = this._excludedFoldersSetting.get(); - delete settingValue[this._path]; + delete settingValue[this.path()]; this._excludedFoldersSetting.set(settingValue); } /** + * @override * @param {string} folderPath * @return {boolean} */ @@ -602,6 +602,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @return {!Set<string>} */ excludedFolders() { @@ -609,6 +610,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @param {string} query * @param {!Common.Progress} progress * @return {!Promise<!Array<string>>} @@ -629,6 +631,7 @@ Persistence.IsolatedFileSystem = class { } /** + * @override * @param {!Common.Progress} progress */ indexContent(progress) { @@ -636,8 +639,70 @@ Persistence.IsolatedFileSystem = class { const requestId = this._manager.registerProgress(progress); InspectorFrontendHost.indexPath(requestId, this._embedderPath, JSON.stringify(this._excludedEmbedderFolders)); } + + /** + * @override + * @param {string} path + * @return {string} + */ + mimeFromPath(path) { + return Common.ResourceType.mimeFromURL(path) || 'text/plain'; + } + + /** + * @override + * @param {string} path + * @return {boolean} + */ + canExcludeFolder(path) { + return !!path && this.type() !== 'overrides'; + } + + /** + * @override + * @param {string} path + * @return {!Common.ResourceType} + */ + contentType(path) { + const extension = Common.ParsedURL.extractExtension(path); + if (Persistence.IsolatedFileSystem._styleSheetExtensions.has(extension)) + return Common.resourceTypes.Stylesheet; + if (Persistence.IsolatedFileSystem._documentExtensions.has(extension)) + return Common.resourceTypes.Document; + if (Persistence.IsolatedFileSystem.ImageExtensions.has(extension)) + return Common.resourceTypes.Image; + if (Persistence.IsolatedFileSystem._scriptExtensions.has(extension)) + return Common.resourceTypes.Script; + return Persistence.IsolatedFileSystem.BinaryExtensions.has(extension) ? Common.resourceTypes.Other : + Common.resourceTypes.Document; + } + + /** + * @override + * @param {string} url + * @return {string} + */ + tooltipForURL(url) { + const path = Common.ParsedURL.urlToPlatformPath(url, Host.isWin()).trimMiddle(150); + return ls`Linked to ${path}`; + } + + /** + * @override + * @return {boolean} + */ + supportsAutomapping() { + return this.type() !== 'overrides'; + } }; +Persistence.IsolatedFileSystem._styleSheetExtensions = new Set(['css', 'scss', 'sass', 'less']); +Persistence.IsolatedFileSystem._documentExtensions = new Set(['htm', 'html', 'asp', 'aspx', 'phtml', 'jsp']); +Persistence.IsolatedFileSystem._scriptExtensions = new Set([ + 'asp', 'aspx', 'c', 'cc', 'cljs', 'coffee', 'cpp', 'cs', 'dart', 'java', 'js', + 'jsp', 'jsx', 'h', 'm', 'mjs', 'mm', 'py', 'sh', 'ts', 'tsx', 'ls' +]); + Persistence.IsolatedFileSystem.ImageExtensions = new Set(['jpeg', 'jpg', 'svg', 'gif', 'webp', 'png', 'ico', 'tiff', 'tif', 'bmp']); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js index 4cc6233dd8f..3ea1dc843db 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js @@ -35,7 +35,7 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object { constructor() { super(); - /** @type {!Map<string, !Persistence.IsolatedFileSystem>} */ + /** @type {!Map<string, !Persistence.PlatformFileSystem>} */ this._fileSystems = new Map(); /** @type {!Map<number, function(!Array.<string>)>} */ this._callbacks = new Map(); @@ -107,7 +107,7 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object { } /** - * @param {!Persistence.IsolatedFileSystem} fileSystem + * @param {!Persistence.PlatformFileSystem} fileSystem */ removeFileSystem(fileSystem) { InspectorFrontendHost.removeFileSystem(fileSystem.embedderPath()); @@ -133,7 +133,7 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object { return promise.then(storeFileSystem.bind(this)); /** - * @param {?Persistence.IsolatedFileSystem} fileSystem + * @param {?Persistence.PlatformFileSystem} fileSystem * @this {Persistence.IsolatedFileSystemManager} */ function storeFileSystem(fileSystem) { @@ -147,6 +147,15 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object { } /** + * @param {string} fileSystemURL + * @param {!Persistence.PlatformFileSystem} fileSystem + */ + addPlatformFileSystem(fileSystemURL, fileSystem) { + this._fileSystems.set(fileSystemURL, fileSystem); + this.dispatchEventToListeners(Persistence.IsolatedFileSystemManager.Events.FileSystemAdded, fileSystem); + } + + /** * @param {!Common.Event} event */ async _onFileSystemAdded(event) { @@ -224,7 +233,7 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object { /** * @param {string} fileSystemPath - * @return {?Persistence.IsolatedFileSystem} + * @return {?Persistence.PlatformFileSystem} */ fileSystem(fileSystemPath) { return this._fileSystems.get(fileSystemPath) || null; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js index 98a938efdb3..14accb96faf 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js @@ -275,7 +275,8 @@ Persistence.Persistence = class extends Common.Object { * @param {!Workspace.UISourceCode} to */ _moveBreakpoints(from, to) { - const breakpoints = this._breakpointManager.breakpointsForUISourceCode(from); + const breakpoints = this._breakpointManager.breakpointLocationsForUISourceCode(from).map( + breakpointLocation => breakpointLocation.breakpoint); for (const breakpoint of breakpoints) { breakpoint.remove(false /* keepInStorage */); this._breakpointManager.setBreakpoint( diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceUtils.js index 2db1e914195..ec923cf2a42 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceUtils.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceUtils.js @@ -11,10 +11,8 @@ Persistence.PersistenceUtils = class { const binding = Persistence.persistence.binding(uiSourceCode); if (!binding) return ''; - if (uiSourceCode === binding.network) { - const path = Common.ParsedURL.urlToPlatformPath(binding.fileSystem.url(), Host.isWin()).trimMiddle(150); - return ls`Linked to ${path}`; - } + if (uiSourceCode === binding.network) + return Persistence.FileSystemWorkspaceBinding.tooltipForUISourceCode(binding.fileSystem); if (binding.network.contentType().isFromSourceMap()) return Common.UIString('Linked to source map: %s', binding.network.url().trimMiddle(150)); return Common.UIString('Linked to %s', binding.network.url().trimMiddle(150)); @@ -27,6 +25,8 @@ Persistence.PersistenceUtils = class { static iconForUISourceCode(uiSourceCode) { const binding = Persistence.persistence.binding(uiSourceCode); if (binding) { + if (!binding.fileSystem.url().startsWith('file://')) + return null; const icon = UI.Icon.create('mediumicon-file-sync'); icon.title = Persistence.PersistenceUtils.tooltipForUISourceCode(binding.network); // TODO(allada) This will not work properly with dark theme. @@ -34,8 +34,10 @@ Persistence.PersistenceUtils = class { icon.style.filter = 'hue-rotate(160deg)'; return icon; } - if (uiSourceCode.project().type() !== Workspace.projectTypes.FileSystem) + if (uiSourceCode.project().type() !== Workspace.projectTypes.FileSystem || + !uiSourceCode.url().startsWith('file://')) return null; + const icon = UI.Icon.create('mediumicon-file'); icon.title = Persistence.PersistenceUtils.tooltipForUISourceCode(uiSourceCode); return icon; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/PlatformFileSystem.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PlatformFileSystem.js new file mode 100644 index 00000000000..e37a4e54bee --- /dev/null +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PlatformFileSystem.js @@ -0,0 +1,194 @@ +// Copyright 2018 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. + +Persistence.PlatformFileSystem = class { + /** + * @param {string} path + * @param {string} type + */ + constructor(path, type) { + this._path = path; + this._type = type; + } + + /** + * @param {string} path + * @return {!Promise<?{modificationTime: !Date, size: number}>} + */ + getMetadata(path) { + return Promise.resolve(/** @type ?{modificationTime: !Date, size: number} */ (null)); + } + + /** + * @return {!Array<string>} + */ + initialFilePaths() { + return []; + } + + /** + * @return {!Array<string>} + */ + initialGitFolders() { + return []; + } + + /** + * @return {string} + */ + path() { + return this._path; + } + + /** + * @return {string} + */ + embedderPath() { + throw new Error('Not implemented'); + } + + /** + * @return {string} + */ + type() { + // TODO(kozyatinskiy): remove type, overrides should implement this interface. + return this._type; + } + + /** + * @param {string} path + * @param {?string} name + * @return {!Promise<?string>} + */ + async createFile(path, name) { + return Promise.resolve(null); + } + + /** + * @param {string} path + * @return {!Promise<boolean>} + */ + deleteFile(path) { + return Promise.resolve(false); + } + + /** + * @param {string} path + * @return {!Promise<?Blob>} + */ + requestFileBlob(path) { + return Promise.resolve(/** @type {?Blob} */ (null)); + } + + /** + * @param {string} path + * @param {function(?string,boolean)} callback + */ + requestFileContent(path, callback) { + callback(null, false); + } + + /** + * @param {string} path + * @param {string} content + * @param {boolean} isBase64 + */ + setFileContent(path, content, isBase64) { + throw new Error('Not implemented'); + } + + /** + * @param {string} path + * @param {string} newName + * @param {function(boolean, string=)} callback + */ + renameFile(path, newName, callback) { + callback(false); + } + + /** + * @param {string} path + */ + addExcludedFolder(path) { + } + + /** + * @param {string} path + */ + removeExcludedFolder(path) { + } + + fileSystemRemoved() { + } + + /** + * @param {string} folderPath + * @return {boolean} + */ + isFileExcluded(folderPath) { + return false; + } + + /** + * @return {!Set<string>} + */ + excludedFolders() { + return new Set(); + } + + /** + * @param {string} query + * @param {!Common.Progress} progress + * @return {!Promise<!Array<string>>} + */ + searchInPath(query, progress) { + return Promise.resolve([]); + } + + /** + * @param {!Common.Progress} progress + */ + indexContent(progress) { + setImmediate(() => progress.done()); + } + + /** + * @param {string} path + * @return {string} + */ + mimeFromPath(path) { + throw new Error('Not implemented'); + } + + /** + * @param {string} path + * @return {boolean} + */ + canExcludeFolder(path) { + return false; + } + + /** + * @param {string} path + * @return {!Common.ResourceType} + */ + contentType(path) { + throw new Error('Not implemented'); + } + + /** + * @param {string} url + * @return {string} + */ + tooltipForURL(url) { + throw new Error('Not implemented'); + } + + /** + * @return {boolean} + */ + supportsAutomapping() { + throw new Error('Not implemented'); + } +}; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js index 7cb2637574d..59308118e36 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js @@ -15,21 +15,17 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox { Persistence.isolatedFileSystemManager.addEventListener( Persistence.IsolatedFileSystemManager.Events.FileSystemAdded, - event => this._fileSystemAdded(/** @type {!Persistence.IsolatedFileSystem} */ (event.data)), this); + event => this._fileSystemAdded(/** @type {!Persistence.PlatformFileSystem} */ (event.data)), this); Persistence.isolatedFileSystemManager.addEventListener( Persistence.IsolatedFileSystemManager.Events.FileSystemRemoved, - event => this._fileSystemRemoved(/** @type {!Persistence.IsolatedFileSystem} */ (event.data)), this); + event => this._fileSystemRemoved(/** @type {!Persistence.PlatformFileSystem} */ (event.data)), this); const folderExcludePatternInput = this._createFolderExcludePatternInput(); folderExcludePatternInput.classList.add('folder-exclude-pattern'); this.containerElement.appendChild(folderExcludePatternInput); const div = this.containerElement.createChild('div', 'settings-info-message'); - div.createTextChild(Common.UIString('Mappings are inferred automatically. Please ')); - div.appendChild(UI.XLink.create( - 'https://bugs.chromium.org/p/chromium/issues/entry?template=Defect%20report%20from%20user&components=Platform%3EDevTools%3EAuthoring&comment=DevTools%20failed%20to%20link%20network%20resource%20to%20filesystem.%0A%0APlatform%3A%20%3CLinux%2FWin%2FMac%3E%0AChrome%20version%3A%20%3Cyour%20chrome%20version%3E%0A%0AWhat%20are%20the%20details%20of%20your%20project%3F%0A-%20Source%20code%20(if%20any)%3A%20http%3A%2F%2Fgithub.com%2Fexample%2Fexample%0A-%20Build%20System%3A%20gulp%2Fgrunt%2Fwebpack%2Frollup%2F...%0A-%20HTTP%20server%3A%20node%20HTTP%2Fnginx%2Fapache...%0A%0AAssets%20failed%20to%20link%20(or%20incorrectly%20linked)%3A%0A1.%0A2.%0A3.%0A%0AIf%20possible%2C%20please%20attach%20a%20screenshot%20of%20network%20sources%20navigator%20which%20should%0Ashow%20which%20resources%20failed%20to%20map', - Common.UIString('report'))); - div.createTextChild(Common.UIString(' any bugs.')); + div.createTextChild(Common.UIString('Mappings are inferred automatically.')); this._fileSystemsListContainer = this.containerElement.createChild('div', ''); @@ -79,7 +75,7 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox { } /** - * @param {!Persistence.IsolatedFileSystem} fileSystem + * @param {!Persistence.PlatformFileSystem} fileSystem */ _addItem(fileSystem) { const networkPersistenceProject = Persistence.networkPersistenceManager.project(); @@ -98,7 +94,7 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox { } /** - * @param {!Persistence.IsolatedFileSystem} fileSystem + * @param {!Persistence.PlatformFileSystem} fileSystem * @return {!Element} */ _renderFileSystem(fileSystem) { @@ -124,7 +120,7 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox { } /** - * @param {!Persistence.IsolatedFileSystem} fileSystem + * @param {!Persistence.PlatformFileSystem} fileSystem */ _removeFileSystemClicked(fileSystem) { Persistence.isolatedFileSystemManager.removeFileSystem(fileSystem); @@ -135,14 +131,14 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox { } /** - * @param {!Persistence.IsolatedFileSystem} fileSystem + * @param {!Persistence.PlatformFileSystem} fileSystem */ _fileSystemAdded(fileSystem) { this._addItem(fileSystem); } /** - * @param {!Persistence.IsolatedFileSystem} fileSystem + * @param {!Persistence.PlatformFileSystem} fileSystem */ _fileSystemRemoved(fileSystem) { const mappingView = this._mappingViewByPath.get(fileSystem.path()); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/module.json b/chromium/third_party/blink/renderer/devtools/front_end/persistence/module.json index 254391aed64..9b3b1c9467c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/module.json @@ -44,6 +44,7 @@ } ], "scripts": [ + "PlatformFileSystem.js", "IsolatedFileSystem.js", "IsolatedFileSystemManager.js", "FileSystemWorkspaceBinding.js", diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js index 4662fcb6404..78d5314fa80 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js @@ -55,10 +55,30 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView { populateTextView(view) { const guides = '+!:|'; let text = `Sampling memory profile.\n\nDate/Time: ${new Date()}\n` + - `Report Version: 7\nNode weight: 1 KiB\n----\n\nCall graph:\n`; + `Report Version: 7\n` + + `App Version: ${/Chrom\S*/.exec(navigator.appVersion)[0] || 'Unknown'}\n` + + `Node Weight: 1 KiB\n` + + `Total Size: ${Math.round(this.profile.root.total / 1024)} KiB\n` + + `----\n\nCall graph:\n`; const sortedChildren = this.profile.root.children.sort((a, b) => b.total - a.total); + const modules = this.profile.modules.map( + m => Object.assign({address: BigInt(m.baseAddress), endAddress: BigInt(m.baseAddress) + BigInt(m.size)}, m)); + modules.sort((m1, m2) => m1.address > m2.address ? 1 : m1.address < m2.address ? -1 : 0); for (const child of sortedChildren) printTree(' ', child !== sortedChildren.peekLast(), child); + + text += '\nBinary Images:\n'; + for (const module of modules) { + const fileName = /[^/\\]*$/.exec(module.name)[0]; + const version = '1.0'; + const formattedUuid = module.uuid.includes('-') ? + module.uuid : + module.uuid.replace(/(.{8})(.{4})(.{4})(.{4})(.{12}).*/, '$1-$2-$3-$4-$5'); + text += `${('0x' + module.address.toString(16)).padStart(18)} - `; + text += `${('0x' + (module.endAddress - BigInt(1)).toString(16)).padStart(18)}`; + text += ` ${fileName} (${version}) <${formattedUuid}> ${module.name}\n`; + } + view.contentElement.createChild('pre', 'profile-text-view monospace').textContent = text; /** @@ -67,10 +87,27 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView { * @param {!SDK.ProfileNode} node */ function printTree(padding, drawGuide, node) { - const isAddress = node.functionName.startsWith('0x'); - const functionName = isAddress ? '???' : node.functionName; - const address = isAddress ? node.functionName : '???'; - text += `${padding}${Math.round(node.total / 1024)} ${functionName} [${address}]\n`; + const addressText = /0x[0-9a-f]*|[0-9]*/.exec(node.functionName)[0] || ''; + let module; + if (addressText) { + const address = BigInt(addressText); + const pos = modules.upperBound(address, (address, module) => address - module.address); + if (pos > 0 && address < modules[pos - 1].endAddress) + module = modules[pos - 1]; + } + const functionName = + (addressText ? node.functionName.substr(addressText.length + 1) : node.functionName) || '???'; + text += `${padding}${Math.round(node.total / 1024)} ${functionName} `; + if (module) { + const fileName = /[^/\\]*$/.exec(module.name); + if (fileName) + text += `(in ${fileName}) `; + const offset = BigInt(addressText) - module.address; + text += `load address ${module.baseAddress} + 0x${offset.toString(16)} `; + } + if (addressText) + text += `[${addressText}]`; + text += '\n'; const guideChar = drawGuide ? guides[padding.length / 2 % guides.length] : ' '; const nextPadding = padding + guideChar + ' '; const sortedChildren = node.children.sort((a, b) => b.total - a.total); @@ -351,8 +388,8 @@ Profiler.SamplingNativeHeapSnapshotBrowserType = class extends Profiler.Sampling * @param {!SDK.HeapProfilerModel} heapProfilerModel * @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>} */ - _takeNativeSnapshot(heapProfilerModel) { - return heapProfilerModel.takeNativeBrowserSnapshot(); + async _takeNativeSnapshot(heapProfilerModel) { + return await heapProfilerModel.takeNativeBrowserSnapshot(); } }; @@ -442,6 +479,7 @@ Profiler.SamplingHeapProfileModel = class extends SDK.ProfileTreeModel { constructor(profile) { super(); this.initialize(translateProfileTree(profile.head)); + this.modules = profile.modules || []; /** * @param {!Protocol.HeapProfiler.SamplingHeapProfileNode} root diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotGridNodes.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotGridNodes.js index a4b53344b8f..584e5791cbd 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotGridNodes.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotGridNodes.js @@ -584,11 +584,9 @@ Profiler.HeapSnapshotGenericObjectNode = class extends Profiler.HeapSnapshotGrid * @param {!Element} div */ async _appendSourceLocation(div) { - if (this._type !== 'closure') - return; const linkContainer = UI.html`<span class="heap-object-source-link" />`; div.appendChild(linkContainer); - const link = await this._dataGrid.dataDisplayDelegate().linkifyObject(String(this.snapshotNodeId)); + const link = await this._dataGrid.dataDisplayDelegate().linkifyObject(this.snapshotNodeIndex); if (link) linkContainer.appendChild(link); else diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotProxy.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotProxy.js index 98c2f67a071..d6757820067 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotProxy.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotProxy.js @@ -451,6 +451,14 @@ Profiler.HeapSnapshotProxy = class extends Profiler.HeapSnapshotProxyObject { } /** + * @param {number} nodeIndex + * @return {!Promise<?HeapSnapshotModel.Location>} + */ + getLocation(nodeIndex) { + return this._callMethodPromise('getLocation', nodeIndex); + } + + /** * @return {!Promise.<?HeapSnapshotModel.Samples>} */ getSamples() { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js index 57bf5fb754f..84fd1dc807c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js @@ -204,18 +204,22 @@ Profiler.HeapSnapshotView = class extends UI.SimpleView { /** * @override - * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId + * @param {number} nodeIndex * @return {!Promise<?Element>} */ - async linkifyObject(snapshotObjectId) { + async linkifyObject(nodeIndex) { const heapProfilerModel = this._profile.heapProfilerModel(); - const remoteObject = await heapProfilerModel.objectForSnapshotObjectId(String(snapshotObjectId), 'link'); - if (!remoteObject || remoteObject.type !== 'function') + // heapProfilerModel is null if snapshot was loaded from file + if (!heapProfilerModel) return null; - const functionDetails = await remoteObject.debuggerModel().functionDetailsPromise(remoteObject); - if (!functionDetails || !functionDetails.location) + const location = await this._profile.getLocation(nodeIndex); + if (!location) + return null; + const debuggerModel = heapProfilerModel.runtimeModel().debuggerModel(); + const rawLocation = debuggerModel.createRawLocationByScriptId( + String(location.scriptId), location.lineNumber, location.columnNumber); + if (!rawLocation) return null; - const rawLocation = functionDetails.location; const sourceURL = rawLocation.script() && rawLocation.script().sourceURL; return sourceURL && this._linkifier ? this._linkifier.linkifyRawLocation(rawLocation, sourceURL) : null; } @@ -1373,6 +1377,14 @@ Profiler.HeapProfileHeader = class extends Profiler.ProfileHeader { } /** + * @param {number} nodeIndex + * @return {!Promise<?HeapSnapshotModel.Location>} + */ + getLocation(nodeIndex) { + return this._snapshotProxy.getLocation(nodeIndex); + } + + /** * @override * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate * @return {!Profiler.ProfileSidebarTreeElement} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileDataGrid.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileDataGrid.js index 8ac82b605c9..646b521634c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileDataGrid.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileDataGrid.js @@ -35,6 +35,10 @@ Profiler.ProfileDataGridNode = class extends DataGrid.DataGridNode { constructor(profileNode, owningTree, hasChildren) { super(null, hasChildren); + this._searchMatchedSelfColumn = false; + this._searchMatchedTotalColumn = false; + this._searchMatchedFunctionColumn = false; + this.profileNode = profileNode; this.tree = owningTree; /** @type {!Map<string, !Profiler.ProfileDataGridNode>} */ @@ -476,9 +480,9 @@ Profiler.ProfileDataGridTree = class { * @return {boolean} */ function matchesQuery(profileDataGridNode) { - delete profileDataGridNode._searchMatchedSelfColumn; - delete profileDataGridNode._searchMatchedTotalColumn; - delete profileDataGridNode._searchMatchedFunctionColumn; + profileDataGridNode._searchMatchedSelfColumn = false; + profileDataGridNode._searchMatchedTotalColumn = false; + profileDataGridNode._searchMatchedFunctionColumn = false; if (percentUnits) { if (lessThan) { @@ -565,9 +569,9 @@ Profiler.ProfileDataGridTree = class { if (this._searchResults) { for (let i = 0; i < this._searchResults.length; ++i) { const profileNode = this._searchResults[i].profileNode; - delete profileNode._searchMatchedSelfColumn; - delete profileNode._searchMatchedTotalColumn; - delete profileNode._searchMatchedFunctionColumn; + profileNode._searchMatchedSelfColumn = false; + profileNode._searchMatchedTotalColumn = false; + profileNode._searchMatchedFunctionColumn = false; profileNode.refresh(); } } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileType.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileType.js index 2058baa102f..da6ce76f096 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileType.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileType.js @@ -247,8 +247,8 @@ Profiler.ProfileType.DataDisplayDelegate.prototype = { showObject(snapshotObjectId, perspectiveName) {}, /** - * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId + * @param {number} nodeIndex * @return {!Promise<?Element>} */ - async linkifyObject(snapshotObjectId) {} + async linkifyObject(nodeIndex) {} }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js index 25d33073763..d7d5ffe0aec 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js @@ -384,10 +384,10 @@ Profiler.ProfilesPanel = class extends UI.PanelWithSidebar { /** * @override - * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId + * @param {number} nodeIndex * @return {!Promise<?Element>} */ - async linkifyObject(snapshotObjectId) { + async linkifyObject(nodeIndex) { return null; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js b/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js index b73d299c689..d4d9a4a6125 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js @@ -180,24 +180,39 @@ Protocol.InspectorBackend.DevToolsStubErrorCode = -32015; Protocol.inspectorBackend = new Protocol.InspectorBackend(); /** - * @interface + * @unrestricted */ -Protocol.InspectorBackend.Connection = function() {}; +Protocol.InspectorBackend.Connection = class { + /** + * @param {string} domain + * @param {!Protocol.InspectorBackend.Connection.MessageObject} messageObject + */ + sendMessage(domain, messageObject) { + this.sendRawMessage(JSON.stringify(messageObject)); + } -Protocol.InspectorBackend.Connection.prototype = { /** * @param {string} message */ - sendMessage(message) {}, + sendRawMessage(message) {} /** * @return {!Promise} */ - disconnect() {}, + disconnect() {} }; /** * @typedef {!{ + * id: number, + * method: string, + * params: (!Object|undefined) + * }} + */ +Protocol.InspectorBackend.Connection.MessageObject; + +/** + * @typedef {!{ * onMessage: function((!Object|string)), * onDisconnect: function(string) * }} @@ -287,17 +302,16 @@ Protocol.TargetBase = class extends Common.Object { messageObject.params = params; const wrappedCallback = this._wrap(callback, domain, method); - const message = JSON.stringify(messageObject); if (Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages) - this._dumpProtocolMessage('frontend: ' + message, '[FE] ' + domain); + this._dumpProtocolMessage('frontend: ' + JSON.stringify(messageObject), '[FE] ' + domain); if (this.hasEventListeners(Protocol.TargetBase.Events.MessageSent)) { this.dispatchEventToListeners( Protocol.TargetBase.Events.MessageSent, {domain, method, params: JSON.parse(JSON.stringify(params)), id: messageId}); } - this._connection.sendMessage(message); + this._connection.sendMessage(domain, messageObject); ++this._pendingResponsesCount; this._callbacks[messageId] = wrappedCallback; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js b/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js index 15f5494ddb2..642804df148 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js @@ -341,8 +341,6 @@ Resources.ServiceWorkerCacheView.DataGridNode = class extends DataGrid.DataGridN this._path = Common.ParsedURL.extractPath(request.url()); if (!this._path) this._path = request.url(); - if (this._path.length > 1 && this._path.startsWith('/')) - this._path = this._path.substring(1); this._request = request; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js index 70eae3ceac3..aa75a6a6674 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js @@ -195,6 +195,11 @@ SDK.CSSMetadata = class { const entry = SDK.CSSMetadata._propertyDataMap[propertyName] || SDK.CSSMetadata._propertyDataMap[unprefixedName]; if (entry && entry.values) acceptedKeywords.pushAll(entry.values); + const commonKeywords = ['auto', 'none']; + for (const commonKeyword of commonKeywords) { + if (CSS.supports(propertyName, commonKeyword)) + acceptedKeywords.push(commonKeyword); + } if (this.isColorAwareProperty(propertyName)) { acceptedKeywords.push('currentColor'); for (const color in Common.Color.Nicknames) @@ -227,7 +232,7 @@ SDK.cssMetadata = function() { SDK.CSSMetadata._distanceProperties = new Set([ 'background-position', 'border-spacing', 'bottom', 'font-size', 'height', 'left', 'letter-spacing', 'max-height', 'max-width', 'min-height', 'min-width', 'right', 'text-indent', 'top', 'width', 'word-spacing', 'grid-row-gap', - 'grid-column-gap' + 'grid-column-gap', 'row-gap' ]); SDK.CSSMetadata._bezierAwareProperties = new Set([ @@ -291,18 +296,17 @@ SDK.CSSMetadata._colorAwareProperties = new Set([ ]); SDK.CSSMetadata._propertyDataMap = { - 'table-layout': {values: ['auto', 'fixed']}, + 'table-layout': {values: ['fixed']}, 'visibility': {values: ['hidden', 'visible', 'collapse']}, 'background-repeat': {values: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round']}, - 'content': {values: ['none', 'normal', 'close-quote', 'no-close-quote', 'no-open-quote', 'open-quote']}, - 'list-style-image': {values: ['none']}, - 'clear': {values: ['none', 'left', 'right', 'both']}, - 'overflow-x': {values: ['hidden', 'auto', 'visible', 'overlay', 'scroll']}, + 'content': {values: ['normal', 'close-quote', 'no-close-quote', 'no-open-quote', 'open-quote']}, + 'clear': {values: ['left', 'right', 'both']}, + 'overflow-x': {values: ['hidden', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']}, 'stroke-linejoin': {values: ['round', 'miter', 'bevel']}, 'baseline-shift': {values: ['baseline', 'sub', 'super']}, 'border-bottom-width': {values: ['medium', 'thick', 'thin']}, 'margin-top-collapse': {values: ['collapse', 'separate', 'discard']}, - 'max-height': {values: ['none', 'min-content', 'max-content', '-webkit-fill-available', 'fit-content']}, + 'max-height': {values: ['min-content', 'max-content', '-webkit-fill-available', 'fit-content']}, 'box-orient': { values: ['horizontal', 'vertical', 'inline-axis', 'block-axis'], }, @@ -313,22 +317,21 @@ SDK.CSSMetadata._propertyDataMap = { ] }, 'border-left-width': {values: ['medium', 'thick', 'thin']}, - 'box-shadow': {values: ['inset', 'none']}, + 'box-shadow': {values: ['inset']}, '-webkit-writing-mode': {values: ['horizontal-tb', 'vertical-rl', 'vertical-lr']}, 'writing-mode': {values: ['lr', 'rl', 'tb', 'lr-tb', 'rl-tb', 'tb-rl', 'horizontal-tb', 'vertical-rl', 'vertical-lr']}, 'border-collapse': {values: ['collapse', 'separate']}, - 'page-break-inside': {values: ['auto', 'avoid']}, + 'page-break-inside': {values: ['avoid']}, 'border-top-width': {values: ['medium', 'thick', 'thin']}, - 'outline-style': - {values: ['auto', 'none', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, + 'outline-style': {values: ['inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'hidden']}, 'cursor': { values: [ - 'none', 'copy', - 'auto', 'crosshair', 'default', + 'grab', + 'grabbing', 'pointer', 'move', 'vertical-text', @@ -365,19 +368,21 @@ SDK.CSSMetadata._propertyDataMap = { ] }, 'border-width': {values: ['medium', 'thick', 'thin']}, - 'border-style': - {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, - 'size': {values: ['auto', 'a3', 'a4', 'a5', 'b4', 'b5', 'landscape', 'ledger', 'legal', 'letter', 'portrait']}, - 'background-size': {values: ['auto', 'contain', 'cover']}, + 'border-style': {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, + 'size': {values: ['a3', 'a4', 'a5', 'b4', 'b5', 'landscape', 'ledger', 'legal', 'letter', 'portrait']}, + 'background-size': {values: ['contain', 'cover']}, 'direction': {values: ['ltr', 'rtl']}, 'enable-background': {values: ['accumulate', 'new']}, - 'float': {values: ['none', 'left', 'right']}, - 'overflow-y': {values: ['hidden', 'auto', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']}, + 'float': {values: ['left', 'right']}, + 'overflow-y': {values: ['hidden', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']}, 'margin-bottom-collapse': {values: ['collapse', 'separate', 'discard']}, 'box-reflect': {values: ['left', 'right', 'above', 'below']}, - 'overflow': {values: ['hidden', 'auto', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']}, - 'contain': {values: ['none', 'strict', 'content', 'size', 'layout', 'style', 'paint']}, - 'text-rendering': {values: ['auto', 'optimizeSpeed', 'optimizeLegibility', 'geometricPrecision']}, + 'overflow': {values: ['hidden', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']}, + 'overscroll-behavior': {values: ['contain']}, + 'overscroll-behavior-x': {values: ['contain']}, + 'overscroll-behavior-y': {values: ['contain']}, + 'contain': {values: ['strict', 'content', 'size', 'layout', 'style', 'paint']}, + 'text-rendering': {values: ['optimizeSpeed', 'optimizeLegibility', 'geometricPrecision']}, 'text-align': { values: [ '-webkit-auto', 'start', 'end', 'left', 'right', 'center', 'justify', '-webkit-left', '-webkit-right', @@ -385,25 +390,23 @@ SDK.CSSMetadata._propertyDataMap = { ] }, 'list-style-position': {values: ['outside', 'inside']}, - 'margin-bottom': {values: ['auto']}, - 'color-interpolation': {values: ['auto', 'sRGB', 'linearRGB']}, + 'color-interpolation': {values: ['sRGB', 'linearRGB']}, 'background-origin': {values: ['border-box', 'content-box', 'padding-box']}, 'word-wrap': {values: ['normal', 'break-word']}, 'font-weight': {values: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900']}, 'margin-before-collapse': {values: ['collapse', 'separate', 'discard']}, - 'text-transform': {values: ['none', 'capitalize', 'uppercase', 'lowercase']}, + 'text-transform': {values: ['capitalize', 'uppercase', 'lowercase']}, 'border-right-style': - {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, + {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, 'border-left-style': - {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, - '-webkit-text-emphasis': {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame', 'none']}, + {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, + '-webkit-text-emphasis': {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame']}, 'font-style': {values: ['italic', 'oblique', 'normal']}, - 'speak': {values: ['none', 'normal', 'spell-out', 'digits', 'literal-punctuation', 'no-punctuation']}, - 'color-rendering': {values: ['auto', 'optimizeSpeed', 'optimizeQuality']}, + 'speak': {values: ['normal', 'spell-out', 'digits', 'literal-punctuation', 'no-punctuation']}, + 'color-rendering': {values: ['optimizeSpeed', 'optimizeQuality']}, 'list-style-type': { values: [ - 'none', 'disc', 'circle', 'square', @@ -461,14 +464,11 @@ SDK.CSSMetadata._propertyDataMap = { 'katakana-iroha' ] }, - 'text-combine-upright': {values: ['none', 'all']}, - '-webkit-text-combine': {values: ['none', 'horizontal']}, + 'text-combine-upright': {values: ['all']}, + '-webkit-text-combine': {values: ['horizontal']}, 'text-orientation': {values: ['mixed', 'upright', 'sideways', 'sideways-right']}, 'outline': { - values: [ - 'none', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'auto', 'thick', - 'thin' - ] + values: ['inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'] }, 'font': { values: [ @@ -518,13 +518,12 @@ SDK.CSSMetadata._propertyDataMap = { }, 'dominant-baseline': { values: [ - 'middle', 'auto', 'central', 'text-before-edge', 'text-after-edge', 'ideographic', 'alphabetic', 'hanging', + 'middle', 'central', 'text-before-edge', 'text-after-edge', 'ideographic', 'alphabetic', 'hanging', 'mathematical', 'use-script', 'no-change', 'reset-size' ] }, 'display': { values: [ - 'none', 'inline', 'block', 'flow-root', @@ -550,55 +549,48 @@ SDK.CSSMetadata._propertyDataMap = { ] }, '-webkit-text-emphasis-position': {values: ['over', 'under']}, - 'image-rendering': {values: ['auto', 'pixelated', '-webkit-optimize-contrast']}, + 'image-rendering': {values: ['pixelated', '-webkit-optimize-contrast', 'optimizeSpeed', 'optimizeQuality']}, 'alignment-baseline': { values: [ - 'baseline', 'middle', 'auto', 'before-edge', 'after-edge', 'central', 'text-before-edge', 'text-after-edge', + 'baseline', 'middle', 'before-edge', 'after-edge', 'central', 'text-before-edge', 'text-after-edge', 'ideographic', 'alphabetic', 'hanging', 'mathematical' ] }, 'outline-width': {values: ['medium', 'thick', 'thin']}, 'box-align': {values: ['baseline', 'center', 'stretch', 'start', 'end']}, 'border-right-width': {values: ['medium', 'thick', 'thin']}, - 'border-top-style': - {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, + 'border-top-style': {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, 'line-height': {values: ['normal']}, 'text-overflow': {values: ['clip', 'ellipsis']}, 'overflow-wrap': {values: ['normal', 'break-word']}, 'box-direction': {values: ['normal', 'reverse']}, 'margin-after-collapse': {values: ['collapse', 'separate', 'discard']}, - 'page-break-before': {values: ['left', 'right', 'auto', 'always', 'avoid']}, - 'border-image': {values: ['repeat', 'stretch', 'none', 'space', 'round']}, - 'text-decoration': { - values: ['none', 'blink', 'line-through', 'overline', 'underline', 'wavy', 'double', 'solid', 'dashed', 'dotted'] - }, + 'page-break-before': {values: ['left', 'right', 'always', 'avoid']}, + 'border-image': {values: ['repeat', 'stretch', 'space', 'round']}, + 'text-decoration': + {values: ['blink', 'line-through', 'overline', 'underline', 'wavy', 'double', 'solid', 'dashed', 'dotted']}, 'position': {values: ['absolute', 'fixed', 'relative', 'static', 'sticky']}, 'font-family': {values: ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace', '-webkit-body', '-webkit-pictograph']}, - 'text-overflow-mode': {values: ['clip', 'ellipsis']}, 'border-bottom-style': - {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, + {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']}, 'unicode-bidi': {values: ['normal', 'bidi-override', 'embed', 'isolate', 'isolate-override', 'plaintext']}, 'clip-rule': {values: ['nonzero', 'evenodd']}, - 'margin-left': {values: ['auto']}, - 'margin-top': {values: ['auto']}, 'zoom': {values: ['normal']}, - 'max-width': {values: ['none', 'min-content', 'max-content', '-webkit-fill-available', 'fit-content']}, + 'max-width': {values: ['min-content', 'max-content', '-webkit-fill-available', 'fit-content']}, 'caption-side': {values: ['top', 'bottom']}, 'empty-cells': {values: ['hide', 'show']}, 'pointer-events': { values: [ - 'none', 'all', 'auto', 'visible', 'visiblepainted', 'visiblefill', 'visiblestroke', 'painted', 'fill', 'stroke', - 'bounding-box' + 'all', 'visible', 'visiblepainted', 'visiblefill', 'visiblestroke', 'painted', 'fill', 'stroke', 'bounding-box' ] }, 'letter-spacing': {values: ['normal']}, 'background-clip': {values: ['border-box', 'content-box', 'padding-box']}, - '-webkit-font-smoothing': {values: ['none', 'auto', 'antialiased', 'subpixel-antialiased']}, + '-webkit-font-smoothing': {values: ['antialiased', 'subpixel-antialiased']}, 'border': { values: [ - 'none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, 'font-size': { @@ -610,7 +602,6 @@ SDK.CSSMetadata._propertyDataMap = { values: [ 'small-caps', 'normal', - 'none', 'common-ligatures', 'no-common-ligatures', 'discretionary-ligatures', @@ -648,25 +639,19 @@ SDK.CSSMetadata._propertyDataMap = { ['baseline', 'middle', 'sub', 'super', 'text-top', 'text-bottom', 'top', 'bottom', '-webkit-baseline-middle'] }, 'white-space': {values: ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap']}, - 'page-break-after': {values: ['left', 'right', 'auto', 'always', 'avoid']}, - 'clip-path': {values: ['none']}, - 'margin': {values: ['auto']}, - 'margin-right': {values: ['auto']}, + 'page-break-after': {values: ['left', 'right', 'always', 'avoid']}, 'word-break': {values: ['normal', 'break-all', 'break-word', 'keep-all']}, 'word-spacing': {values: ['normal']}, - '-webkit-text-emphasis-style': - {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame', 'none']}, + '-webkit-text-emphasis-style': {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame']}, 'transform': { values: [ - 'scale', 'scaleX', 'scaleY', 'scale3d', 'rotate', 'rotateX', 'rotateY', - 'rotateZ', 'rotate3d', 'skew', 'skewX', 'skewY', 'translate', 'translateX', - 'translateY', 'translateZ', 'translate3d', 'matrix', 'matrix3d', 'perspective', 'none' + 'scale', 'scaleX', 'scaleY', 'scale3d', 'rotate', 'rotateX', 'rotateY', + 'rotateZ', 'rotate3d', 'skew', 'skewX', 'skewY', 'translate', 'translateX', + 'translateY', 'translateZ', 'translate3d', 'matrix', 'matrix3d', 'perspective' ] }, - 'image-resolution': {values: ['from-image', 'snap']}, 'box-sizing': {values: ['content-box', 'border-box']}, - 'clip': {values: ['auto']}, - 'resize': {values: ['none', 'both', 'horizontal', 'vertical', 'auto']}, + 'resize': {values: ['both', 'horizontal', 'vertical']}, 'align-content': { values: [ 'normal', 'baseline', 'space-between', 'space-around', 'space-evenly', 'stretch', 'unsafe', 'safe', 'center', @@ -694,36 +679,35 @@ SDK.CSSMetadata._propertyDataMap = { 'justify-items': { values: [ 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end', - 'flex-start', 'flex-end', 'left', 'right', 'legacy', 'auto' + 'flex-start', 'flex-end', 'left', 'right', 'legacy' ] }, 'place-items': { values: [ - 'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end', + 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end', 'left', 'right' ] }, 'align-self': { values: [ - 'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end', + 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end', 'left', 'right' ] }, 'justify-self': { values: [ - 'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end', + 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end', 'left', 'right' ] }, 'place-self': { values: [ - 'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end', + 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end', 'flex-start', 'flex-end', 'left', 'right' ] }, 'flex-direction': {values: ['row', 'row-reverse', 'column', 'column-reverse']}, 'flex-wrap': {values: ['nowrap', 'wrap', 'wrap-reverse']}, - 'perspective': {values: ['none']}, 'perspective-origin': {values: ['left', 'center', 'right', 'top', 'bottom']}, 'transform-origin': {values: ['left', 'center', 'right', 'top', 'bottom']}, 'transform-style': {values: ['flat', 'preserve-3d']}, @@ -741,30 +725,28 @@ SDK.CSSMetadata._propertyDataMap = { }, 'animation-direction': {values: ['normal', 'reverse', 'alternate', 'alternate-reverse']}, 'animation-play-state': {values: ['running', 'paused']}, - 'animation-fill-mode': {values: ['none', 'forwards', 'backwards', 'both']}, + 'animation-fill-mode': {values: ['forwards', 'backwards', 'both']}, '-webkit-backface-visibility': {values: ['visible', 'hidden']}, '-webkit-box-decoration-break': {values: ['slice', 'clone']}, '-webkit-column-break-after': - {values: ['auto', 'always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']}, + {values: ['always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']}, '-webkit-column-break-before': - {values: ['auto', 'always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']}, - '-webkit-column-break-inside': {values: ['auto', 'avoid', 'avoid-page', 'avoid-column']}, - '-webkit-column-span': {values: ['none', 'all']}, - '-webkit-column-count': {values: ['auto']}, + {values: ['always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']}, + '-webkit-column-break-inside': {values: ['avoid', 'avoid-page', 'avoid-column']}, + '-webkit-column-span': {values: ['all']}, '-webkit-column-gap': {values: ['normal']}, 'filter': { values: [ 'url', 'blur', 'brightness', 'contrast', 'drop-shadow', 'grayscale', 'hue-rotate', 'invert', 'opacity', - 'saturate', 'sepia', 'none' + 'saturate', 'sepia' ] }, - 'line-break': {values: ['auto', 'loose', 'normal', 'strict', 'after-white-space']}, - 'user-select': {values: ['none', 'text', 'all', 'auto']}, + 'line-break': {values: ['loose', 'normal', 'strict', 'after-white-space']}, + 'user-select': {values: ['text', 'all']}, '-webkit-user-modify': {values: ['read-only', 'read-write', 'read-write-plaintext-only']}, - 'text-align-last': {values: ['auto', 'start', 'end', 'left', 'right', 'center', 'justify']}, - '-webkit-text-decoration-line': {values: ['none', 'underline', 'overline', 'line-through', 'blink']}, + 'text-align-last': {values: ['start', 'end', 'left', 'right', 'center', 'justify']}, + '-webkit-text-decoration-line': {values: ['underline', 'overline', 'line-through', 'blink']}, '-webkit-text-decoration-style': {values: ['solid', 'double', 'dotted', 'dashed', 'wavy']}, - '-webkit-text-decoration-skip': {values: ['none', 'objects', 'spaces', 'ink', 'edges', 'box-decoration']}, 'mix-blend-mode': { values: [ 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', @@ -777,35 +759,26 @@ SDK.CSSMetadata._propertyDataMap = { 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity', 'unset' ] }, - 'caret-color': {values: ['auto']}, - 'grid-template-columns': {values: ['none', 'auto', 'min-content', 'max-content']}, - 'grid-template-rows': {values: ['none', 'auto', 'min-content', 'max-content']}, - 'grid-template-areas': {values: ['none']}, - 'grid-template': {values: ['none']}, - 'grid-auto-columns': {values: ['auto', 'min-content', 'max-content']}, - 'grid-auto-rows': {values: ['auto', 'min-content', 'max-content']}, + 'grid-template-columns': {values: ['min-content', 'max-content']}, + 'grid-template-rows': {values: ['min-content', 'max-content']}, + 'grid-auto-columns': {values: ['min-content', 'max-content']}, + 'grid-auto-rows': {values: ['min-content', 'max-content']}, 'grid-auto-flow': {values: ['row', 'column', 'dense']}, - 'grid': {values: ['none']}, - 'grid-row-start': {values: ['auto']}, - 'grid-column-start': {values: ['auto']}, - 'grid-row-end': {values: ['auto']}, - 'grid-column-end': {values: ['auto']}, - 'grid-row': {values: ['auto']}, - 'grid-column': {values: ['auto']}, - 'grid-area': {values: ['auto']}, + 'row-gap': {values: ['normal']}, 'animation-iteration-count': {values: ['infinite']}, 'font-feature-settings': {values: ['normal']}, - 'font-kerning': {values: ['none', 'normal', 'auto']}, - 'font-size-adjust': {values: ['none']}, + 'font-kerning': {values: ['normal']}, 'font-variant-caps': {values: ['small-caps', 'all-small-caps', 'petite-caps', 'all-petite-caps', 'unicase', 'titling-caps', 'normal']}, 'font-variant-east-asian': { - values: - ['jis78', 'jis83', 'jis90', 'jis04', 'simplified', 'traditional', 'full-width', 'proportional-width', 'ruby'] + values: [ + 'jis78', 'jis83', 'jis90', 'jis04', 'simplified', 'traditional', 'full-width', 'proportional-width', 'ruby', + 'normal' + ] }, 'font-variant-ligatures': { values: [ - 'none', 'common-ligatures', 'no-common-ligatures', 'discretionary-ligatures', 'no-discretionary-ligatures', + 'common-ligatures', 'no-common-ligatures', 'discretionary-ligatures', 'no-discretionary-ligatures', 'historical-ligatures', 'no-historical-ligatures', 'contextual', 'no-contextual', 'normal' ] }, @@ -816,17 +789,14 @@ SDK.CSSMetadata._propertyDataMap = { ] }, 'font-variation-settings': {values: ['normal']}, - '-webkit-locale': {values: ['auto']}, - 'backdrop-filter': {values: ['none']}, 'backface-visibility': {values: ['hidden', 'visible']}, 'background': { values: [ - 'none', 'repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'top', 'bottom', 'left', 'right', 'center', 'fixed', - 'local', 'scroll', 'space', 'round', 'border-box', 'content-box', 'padding-box' + 'repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'top', 'bottom', 'left', 'right', 'center', 'fixed', 'local', + 'scroll', 'space', 'round', 'border-box', 'content-box', 'padding-box' ] }, 'background-attachment': {values: ['fixed', 'local', 'scroll']}, - 'background-image': {values: ['none']}, 'background-position': {values: ['top', 'bottom', 'left', 'right', 'center']}, 'background-position-x': {values: ['left', 'right', 'center']}, 'background-position-y': {values: ['top', 'bottom', 'center']}, @@ -834,68 +804,50 @@ SDK.CSSMetadata._propertyDataMap = { 'background-repeat-y': {values: ['repeat', 'no-repeat']}, 'border-bottom': { values: [ - 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, 'border-image-repeat': {values: ['repeat', 'stretch', 'space', 'round']}, - 'border-image-source': {values: ['none']}, - 'border-image-width': {values: ['auto']}, 'border-left': { values: [ - 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, 'border-right': { values: [ - 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, 'border-top': { values: [ - 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, - 'bottom': {values: ['auto']}, - 'break-after': - {values: ['left', 'right', 'auto', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']}, + 'break-after': {values: ['left', 'right', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']}, 'break-before': - {values: ['left', 'right', 'auto', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']}, - 'break-inside': {values: ['auto', 'avoid', 'avoid-page', 'avoid-column']}, - 'buffered-rendering': {values: ['auto', 'static', 'dynamic']}, - 'color-interpolation-filters': {values: ['auto', 'srgb', 'linearrgb']}, - 'column-count': {values: ['auto']}, - 'column-fill': {values: ['auto', 'balance']}, + {values: ['left', 'right', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']}, + 'break-inside': {values: ['avoid', 'avoid-page', 'avoid-column']}, + 'buffered-rendering': {values: ['static', 'dynamic']}, + 'color-interpolation-filters': {values: ['srgb', 'linearrgb']}, + 'column-fill': {values: ['balance']}, 'column-gap': {values: ['normal']}, 'column-rule': { values: [ - 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, 'column-rule-style': - {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, + {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, 'column-rule-width': {values: ['medium', 'thick', 'thin']}, - 'column-span': {values: ['none', 'all']}, - 'column-width': {values: ['auto']}, - 'columns': {values: ['auto']}, - 'd': {values: ['none']}, - 'fill': {values: ['none']}, + 'column-span': {values: ['all']}, 'fill-rule': {values: ['nonzero', 'evenodd']}, - 'flex': {values: ['none', 'auto']}, - 'flex-basis': {values: ['auto']}, 'flex-flow': {values: ['nowrap', 'row', 'row-reverse', 'column', 'column-reverse', 'wrap', 'wrap-reverse']}, - 'height': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - 'hyphens': {values: ['none', 'manual']}, - 'inline-size': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - 'isolation': {values: ['auto', 'isolate']}, - 'left': {values: ['auto']}, + 'height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + 'hyphens': {values: ['manual']}, + 'inline-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + 'isolation': {values: ['isolate']}, 'list-style': { values: [ - 'none', 'outside', 'inside', 'disc', @@ -955,38 +907,24 @@ SDK.CSSMetadata._propertyDataMap = { 'katakana-iroha' ] }, - 'marker': {values: ['none']}, - 'marker-end': {values: ['none']}, - 'marker-mid': {values: ['none']}, - 'marker-start': {values: ['none']}, - 'mask': {values: ['none']}, - 'mask-source-type': {values: ['auto', 'alpha', 'luminance']}, + 'mask-source-type': {values: ['alpha', 'luminance']}, 'mask-type': {values: ['alpha', 'luminance']}, - 'max-block-size': {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - 'max-inline-size': {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - 'min-block-size': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - 'min-height': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - 'min-inline-size': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - 'min-width': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - 'object-fit': {values: ['none', 'contain', 'cover', 'fill', 'scale-down']}, + 'max-block-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + 'max-inline-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + 'min-block-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + 'min-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + 'min-inline-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + 'min-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + 'object-fit': {values: ['contain', 'cover', 'fill', 'scale-down']}, 'object-position': {values: ['top', 'bottom', 'left', 'right', 'center']}, - 'offset-anchor': {values: ['top', 'bottom', 'left', 'right', 'center', 'auto']}, - 'offset-path': {values: ['none']}, - 'offset-position': {values: ['top', 'bottom', 'left', 'right', 'center', 'auto']}, - 'offset-rotate': {values: ['auto', 'reverse']}, - 'overflow-anchor': {values: ['none', 'auto', 'visible']}, + 'offset-anchor': {values: ['top', 'bottom', 'left', 'right', 'center']}, + 'offset-position': {values: ['top', 'bottom', 'left', 'right', 'center']}, + 'offset-rotate': {values: ['reverse']}, + 'overflow-anchor': {values: ['visible']}, 'paint-order': {values: ['normal', 'fill', 'stroke', 'markers']}, - 'quotes': {values: ['none']}, - 'right': {values: ['auto']}, - 'rotate': {values: ['none']}, - 'rx': {values: ['auto']}, - 'ry': {values: ['auto']}, - 'scale': {values: ['none']}, - 'scroll-behavior': {values: ['auto', 'smooth']}, + 'scroll-behavior': {values: ['smooth']}, 'scroll-customization': { values: [ - 'none', - 'auto', 'pan-x', 'pan-y', 'pan-left', @@ -995,32 +933,24 @@ SDK.CSSMetadata._propertyDataMap = { 'pan-down', ] }, - 'shape-outside': {values: ['none', 'border-box', 'content-box', 'padding-box', 'margin-box']}, - 'shape-rendering': {values: ['auto', 'optimizespeed', 'geometricprecision', 'crispedges']}, - 'stroke': {values: ['none']}, - 'stroke-dasharray': {values: ['none']}, + 'scroll-snap-align': {values: ['start', 'end', 'center']}, + 'scroll-snap-stop': {values: ['normal', 'always']}, + 'scroll-snap-type': {values: ['x', 'y', 'block', 'inline', 'both', 'mandatory', 'proximity']}, + 'shape-outside': {values: ['border-box', 'content-box', 'padding-box', 'margin-box']}, + 'shape-rendering': {values: ['optimizespeed', 'geometricprecision', 'crispedges']}, 'stroke-linecap': {values: ['square', 'round', 'butt']}, 'text-anchor': {values: ['middle', 'start', 'end']}, - 'text-decoration-line': {values: ['none', 'blink', 'line-through', 'overline', 'underline']}, - 'text-decoration-skip': {values: ['objects', 'ink']}, + 'text-decoration-line': {values: ['blink', 'line-through', 'overline', 'underline']}, 'text-decoration-style': {values: ['dotted', 'dashed', 'solid', 'double', 'wavy']}, - 'text-justify': {values: ['none', 'inter-word', 'distribute', 'auto']}, - 'text-shadow': {values: ['none']}, - 'text-size-adjust': {values: ['none', 'auto']}, - 'text-underline-position': {values: ['auto', 'under']}, - 'top': {values: ['auto']}, - 'touch-action': { - values: [ - 'none', 'auto', 'pan-x', 'pan-y', 'pan-left', 'pan-right', 'pan-up', 'pan-down', 'manipulation', 'pinch-zoom' - ] - }, + 'text-justify': {values: ['inter-word', 'distribute']}, + 'text-underline-position': {values: ['under']}, + 'touch-action': + {values: ['pan-x', 'pan-y', 'pan-left', 'pan-right', 'pan-up', 'pan-down', 'manipulation', 'pinch-zoom']}, 'transform-box': {values: ['border-box', 'fill-box', 'view-box']}, - 'translate': {values: ['none']}, - 'vector-effect': {values: ['none', 'non-scaling-stroke']}, + 'vector-effect': {values: ['non-scaling-stroke']}, '-webkit-app-region': {values: ['drag', 'no-drag']}, '-webkit-appearance': { values: [ - 'none', 'checkbox', 'radio', 'push-button', @@ -1065,54 +995,42 @@ SDK.CSSMetadata._propertyDataMap = { }, '-webkit-border-after': { values: [ - 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, '-webkit-border-after-style': - {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, + {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, '-webkit-border-after-width': {values: ['medium', 'thick', 'thin']}, '-webkit-border-before': { values: [ - 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, '-webkit-border-before-style': - {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, + {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, '-webkit-border-before-width': {values: ['medium', 'thick', 'thin']}, '-webkit-border-end': { values: [ - 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, '-webkit-border-end-style': - {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, + {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, '-webkit-border-end-width': {values: ['medium', 'thick', 'thin']}, '-webkit-border-start': { values: [ - 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', - 'thin' + 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin' ] }, '-webkit-border-start-style': - {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, + {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']}, '-webkit-border-start-width': {values: ['medium', 'thick', 'thin']}, '-webkit-box-pack': {values: ['center', 'justify', 'start', 'end']}, - '-webkit-highlight': {values: ['none']}, - '-webkit-hyphenate-character': {values: ['auto']}, - '-webkit-logical-height': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - '-webkit-logical-width': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - '-webkit-margin-after': {values: ['auto']}, - '-webkit-margin-before': {values: ['auto']}, + '-webkit-logical-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + '-webkit-logical-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, '-webkit-margin-collapse': {values: ['collapse', 'separate', 'discard']}, - '-webkit-margin-end': {values: ['auto']}, - '-webkit-margin-start': {values: ['auto']}, - '-webkit-mask-box-image': {values: ['none', 'repeat', 'stretch', 'space', 'round']}, + '-webkit-mask-box-image': {values: ['repeat', 'stretch', 'space', 'round']}, '-webkit-mask-box-image-repeat': {values: ['repeat', 'stretch', 'space', 'round']}, - '-webkit-mask-box-image-source': {values: ['none']}, - '-webkit-mask-box-image-width': {values: ['auto']}, '-webkit-mask-clip': {values: ['text', 'border', 'border-box', 'content', 'content-box', 'padding', 'padding-box']}, '-webkit-mask-composite': { values: [ @@ -1120,35 +1038,29 @@ SDK.CSSMetadata._propertyDataMap = { 'destination-out', 'destination-atop', 'xor', 'plus-lighter' ] }, - '-webkit-mask-image': {values: ['none']}, '-webkit-mask-origin': {values: ['border', 'border-box', 'content', 'content-box', 'padding', 'padding-box']}, '-webkit-mask-position': {values: ['top', 'bottom', 'left', 'right', 'center']}, '-webkit-mask-position-x': {values: ['left', 'right', 'center']}, '-webkit-mask-position-y': {values: ['top', 'bottom', 'center']}, '-webkit-mask-repeat': {values: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round']}, - '-webkit-mask-size': {values: ['auto', 'contain', 'cover']}, - '-webkit-max-logical-height': - {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - '-webkit-max-logical-width': - {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - '-webkit-min-logical-height': - {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - '-webkit-min-logical-width': - {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + '-webkit-mask-size': {values: ['contain', 'cover']}, + '-webkit-max-logical-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + '-webkit-max-logical-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + '-webkit-min-logical-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, + '-webkit-min-logical-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, '-webkit-perspective-origin-x': {values: ['left', 'right', 'center']}, '-webkit-perspective-origin-y': {values: ['top', 'bottom', 'center']}, '-webkit-print-color-adjust': {values: ['economy', 'exact']}, '-webkit-rtl-ordering': {values: ['logical', 'visual']}, '-webkit-ruby-position': {values: ['after', 'before']}, - '-webkit-text-decorations-in-effect': {values: ['none', 'blink', 'line-through', 'overline', 'underline']}, - '-webkit-text-security': {values: ['none', 'disc', 'circle', 'square']}, + '-webkit-text-decorations-in-effect': {values: ['blink', 'line-through', 'overline', 'underline']}, + '-webkit-text-security': {values: ['disc', 'circle', 'square']}, '-webkit-text-stroke': {values: ['medium', 'thick', 'thin']}, '-webkit-text-stroke-width': {values: ['medium', 'thick', 'thin']}, '-webkit-transform-origin-x': {values: ['left', 'right', 'center']}, '-webkit-transform-origin-y': {values: ['top', 'bottom', 'center']}, - '-webkit-user-drag': {values: ['none', 'auto', 'element']}, - 'width': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, - 'z-index': {values: ['auto']} + '-webkit-user-drag': {values: ['element']}, + 'width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']}, }; // Weight of CSS properties based on their usage from https://www.chromestatus.com/metrics/css/popularity diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js index d8d152cf189..b27a970036a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js @@ -105,129 +105,18 @@ SDK.CSSModel = class extends SDK.SDKModel { * @param {boolean} majorChange * @return {!Promise<boolean>} */ - setStyleText(styleSheetId, range, text, majorChange) { - const original = this._innerSetStyleTexts.bind(this, [styleSheetId], [range], [text], majorChange); - const header = this.styleSheetHeaderForId(styleSheetId); - if (!header) - return original(); - - const sourceMap = this._sourceMapManager.sourceMapForClient(header); - if (!sourceMap) - return original(); - - const originalAndDetach = originalAndDetachIfSuccess.bind(this, header); - - if (!sourceMap.editable()) - return original(); - - return /** @type {!Promise<boolean>} */ ( - sourceMap.editCompiled([range], [text]).then(onEditingDone.bind(this)).catch(onError.bind(this, header))); - - /** - * @param {?SDK.SourceMap.EditResult} editResult - * @return {!Promise<boolean>} - * @this {SDK.CSSModel} - */ - function onEditingDone(editResult) { - if (!editResult) - return Promise.resolve(false); - - let edits = editResult.compiledEdits; - if (!edits.length) - return onCSSPatched.call(this, editResult, true); - - edits.sort(TextUtils.SourceEdit.comparator); - edits = edits.reverse(); - - const styleSheetIds = []; - const ranges = []; - const texts = []; - for (const 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 {!SDK.SourceMap.EditResult} editResult - * @param {boolean} success - * @return {!Promise<boolean>} - * @this {SDK.CSSModel} - */ - function onCSSPatched(editResult, success) { - if (!success) - return originalAndDetach(); - - this._sourceMapManager.applySourceMapEdit(editResult); - return Promise.resolve(true); - } - - /** - * @param {!SDK.CSSStyleSheetHeader} header - * @param {*} error - * @return {!Promise<boolean>} - * @this {SDK.CSSModel} - */ - function onError(header, error) { - Common.console.error(Common.UIString('LiveSASS failed: %s', sourceMap.compiledURL())); - console.error(error); - this._sourceMapManager.detachSourceMap(header); - return original(); - } - - /** - * @param {!SDK.CSSStyleSheetHeader} header - * @return {!Promise<boolean>} - * @this {SDK.CSSModel} - */ - function originalAndDetachIfSuccess(header) { - return this._innerSetStyleTexts([styleSheetId], [range], [text], majorChange).then(detachIfSuccess.bind(this)); - - /** - * @param {boolean} success - * @return {boolean} - * @this {SDK.CSSModel} - */ - function detachIfSuccess(success) { - if (success) - this._sourceMapManager.detachSourceMap(header); - return success; - } - } - } - - /** - * @param {!Array<!Protocol.CSS.StyleSheetId>} styleSheetIds - * @param {!Array<!TextUtils.TextRange>} ranges - * @param {!Array<string>} texts - * @param {boolean} majorChange - * @return {!Promise<boolean>} - */ - async _innerSetStyleTexts(styleSheetIds, ranges, texts, majorChange) { - console.assert( - styleSheetIds.length === ranges.length && ranges.length === texts.length, 'Array lengths must be equal'); - const edits = []; - const ensureContentPromises = []; - for (let i = 0; i < styleSheetIds.length; ++i) { - edits.push({styleSheetId: styleSheetIds[i], range: ranges[i].serializeToObject(), text: texts[i]}); - ensureContentPromises.push(this._ensureOriginalStyleSheetText(styleSheetIds[i])); - } - + async setStyleText(styleSheetId, range, text, majorChange) { try { - await Promise.all(ensureContentPromises); - const stylePayloads = await this._agent.setStyleTexts(edits); + await this._ensureOriginalStyleSheetText(styleSheetId); - if (!stylePayloads || stylePayloads.length !== ranges.length) + const stylePayloads = + await this._agent.setStyleTexts([{styleSheetId: styleSheetId, range: range.serializeToObject(), text: text}]); + if (!stylePayloads || stylePayloads.length !== 1) return false; this._domModel.markUndoableState(!majorChange); - for (let i = 0; i < ranges.length; ++i) { - const edit = new SDK.CSSModel.Edit(styleSheetIds[i], ranges[i], texts[i], stylePayloads[i]); - this._fireStyleSheetChanged(styleSheetIds[i], edit); - } + const edit = new SDK.CSSModel.Edit(styleSheetId, range, text, stylePayloads[0]); + this._fireStyleSheetChanged(styleSheetId, edit); return true; } catch (e) { return false; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js index 01811b8f4ff..112423b791f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js @@ -1,15 +1,16 @@ // Copyright (c) 2015 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. + /** - * @implements {Protocol.InspectorBackend.Connection} * @unrestricted */ -SDK.MainConnection = class { +SDK.MainConnection = class extends Protocol.InspectorBackend.Connection { /** * @param {!Protocol.InspectorBackend.Connection.Params} params */ constructor(params) { + super(); this._onMessage = params.onMessage; this._onDisconnect = params.onDisconnect; this._disconnected = false; @@ -25,7 +26,7 @@ SDK.MainConnection = class { * @override * @param {string} message */ - sendMessage(message) { + sendRawMessage(message) { if (!this._disconnected) InspectorFrontendHost.sendMessageToBackend(message); } @@ -77,16 +78,16 @@ SDK.MainConnection = class { }; /** - * @implements {Protocol.InspectorBackend.Connection} * @unrestricted */ -SDK.WebSocketConnection = class { +SDK.WebSocketConnection = class extends Protocol.InspectorBackend.Connection { /** * @param {string} url * @param {function()} onWebSocketDisconnect * @param {!Protocol.InspectorBackend.Connection.Params} params */ constructor(url, onWebSocketDisconnect, params) { + super(); this._socket = new WebSocket(url); this._socket.onerror = this._onError.bind(this); this._socket.onopen = this._onOpen.bind(this); @@ -137,7 +138,7 @@ SDK.WebSocketConnection = class { * @override * @param {string} message */ - sendMessage(message) { + sendRawMessage(message) { if (this._connected) this._socket.send(message); else @@ -160,14 +161,14 @@ SDK.WebSocketConnection = class { }; /** - * @implements {Protocol.InspectorBackend.Connection} * @unrestricted */ -SDK.StubConnection = class { +SDK.StubConnection = class extends Protocol.InspectorBackend.Connection { /** * @param {!Protocol.InspectorBackend.Connection.Params} params */ constructor(params) { + super(); this._onMessage = params.onMessage; this._onDisconnect = params.onDisconnect; } @@ -176,7 +177,7 @@ SDK.StubConnection = class { * @override * @param {string} message */ - sendMessage(message) { + sendRawMessage(message) { setTimeout(this._respondWithError.bind(this, message), 0); } @@ -205,16 +206,14 @@ SDK.StubConnection = class { } }; -/** - * @implements {Protocol.InspectorBackend.Connection} - */ -SDK.ChildConnection = class { +SDK.ChildConnection = class extends Protocol.InspectorBackend.Connection { /** * @param {!Protocol.TargetAgent} agent * @param {string} sessionId * @param {!Protocol.InspectorBackend.Connection.Params} params */ constructor(agent, sessionId, params) { + super(); this._agent = agent; this._sessionId = sessionId; this.onMessage = params.onMessage; @@ -225,7 +224,7 @@ SDK.ChildConnection = class { * @override * @param {string} message */ - sendMessage(message) { + sendRawMessage(message) { this._agent.sendMessageToTarget(message, this._sessionId); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js index 5bc6a1cf215..7bc0762f73c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js @@ -551,11 +551,13 @@ SDK.DebuggerModel = class extends SDK.SDKModel { * @param {boolean} hasSourceURLComment * @param {boolean} hasSyntaxError * @param {number} length + * @param {?Protocol.Runtime.StackTrace} originStackTrace * @return {!SDK.Script} */ _parsedScriptSource( scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, - executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURLComment, hasSyntaxError, length) { + executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURLComment, hasSyntaxError, length, + originStackTrace) { let isContentScript = false; if (executionContextAuxData && ('isDefault' in executionContextAuxData)) isContentScript = !executionContextAuxData['isDefault']; @@ -569,12 +571,10 @@ SDK.DebuggerModel = class extends SDK.SDKModel { } const script = new SDK.Script( this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, - this._internString(hash), isContentScript, isLiveEdit, sourceMapURL, hasSourceURLComment, length); + this._internString(hash), isContentScript, isLiveEdit, sourceMapURL, hasSourceURLComment, length, + originStackTrace); this._registerScript(script); - if (!hasSyntaxError) - this.dispatchEventToListeners(SDK.DebuggerModel.Events.ParsedScriptSource, script); - else - this.dispatchEventToListeners(SDK.DebuggerModel.Events.FailedToParseScriptSource, script); + this.dispatchEventToListeners(SDK.DebuggerModel.Events.ParsedScriptSource, script); const sourceMapId = SDK.DebuggerModel._sourceMapId(script.executionContextId, script.sourceURL, script.sourceMapURL); @@ -1017,13 +1017,14 @@ SDK.DebuggerDispatcher = class { * @param {boolean=} hasSourceURL * @param {boolean=} isModule * @param {number=} length + * @param {!Protocol.Runtime.StackTrace=} stackTrace */ scriptParsed( scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, - executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURL, isModule, length) { + executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURL, isModule, length, stackTrace) { this._debuggerModel._parsedScriptSource( scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, - executionContextAuxData, !!isLiveEdit, sourceMapURL, !!hasSourceURL, false, length || 0); + executionContextAuxData, !!isLiveEdit, sourceMapURL, !!hasSourceURL, false, length || 0, stackTrace || null); } /** @@ -1041,13 +1042,14 @@ SDK.DebuggerDispatcher = class { * @param {boolean=} hasSourceURL * @param {boolean=} isModule * @param {number=} length + * @param {!Protocol.Runtime.StackTrace=} stackTrace */ scriptFailedToParse( scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, - executionContextAuxData, sourceMapURL, hasSourceURL, isModule, length) { + executionContextAuxData, sourceMapURL, hasSourceURL, isModule, length, stackTrace) { this._debuggerModel._parsedScriptSource( scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, - executionContextAuxData, false, sourceMapURL, !!hasSourceURL, true, length || 0); + executionContextAuxData, false, sourceMapURL, !!hasSourceURL, true, length || 0, stackTrace || null); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/HAREntry.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js index cf907216d85..9ad29cb1de0 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/HAREntry.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js @@ -36,7 +36,87 @@ /** * @unrestricted */ -BrowserSDK.HAREntry = class { +SDK.HARLog = class { + /** + * @param {!SDK.NetworkRequest} request + * @param {number} monotonicTime + * @return {!Date} + */ + static pseudoWallTime(request, monotonicTime) { + return new Date(request.pseudoWallTime(monotonicTime) * 1000); + } + + /** + * @param {!Array.<!SDK.NetworkRequest>} requests + * @return {!Promise<!Object>} + */ + static async build(requests) { + const log = new SDK.HARLog(); + const entryPromises = []; + for (const request of requests) + entryPromises.push(SDK.HARLog.Entry.build(request)); + const entries = await Promise.all(entryPromises); + return {version: '1.2', creator: log._creator(), pages: log._buildPages(requests), entries: entries}; + } + + _creator() { + const webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent); + + return {name: 'WebInspector', version: webKitVersion ? webKitVersion[1] : 'n/a'}; + } + + /** + * @param {!Array.<!SDK.NetworkRequest>} requests + * @return {!Array.<!Object>} + */ + _buildPages(requests) { + const seenIdentifiers = {}; + const pages = []; + for (let i = 0; i < requests.length; ++i) { + const request = requests[i]; + const page = SDK.NetworkLog.PageLoad.forRequest(request); + if (!page || seenIdentifiers[page.id]) + continue; + seenIdentifiers[page.id] = true; + pages.push(this._convertPage(page, request)); + } + return pages; + } + + /** + * @param {!SDK.NetworkLog.PageLoad} page + * @param {!SDK.NetworkRequest} request + * @return {!Object} + */ + _convertPage(page, request) { + return { + startedDateTime: SDK.HARLog.pseudoWallTime(request, page.startTime).toJSON(), + id: 'page_' + page.id, + title: page.url, // We don't have actual page title here. URL is probably better than nothing. + pageTimings: { + onContentLoad: this._pageEventTime(page, page.contentLoadTime), + onLoad: this._pageEventTime(page, page.loadTime) + } + }; + } + + /** + * @param {!SDK.NetworkLog.PageLoad} page + * @param {number} time + * @return {number} + */ + _pageEventTime(page, time) { + const startTime = page.startTime; + if (time === -1 || startTime === -1) + return -1; + return SDK.HARLog.Entry._toMilliseconds(time - startTime); + } +}; + +/** + * @unrestricted + */ +SDK.HARLog.Entry = class { /** * @param {!SDK.NetworkRequest} request */ @@ -57,7 +137,7 @@ BrowserSDK.HAREntry = class { * @return {!Promise<!Object>} */ static async build(request) { - const harEntry = new BrowserSDK.HAREntry(request); + const harEntry = new SDK.HARLog.Entry(request); let ipAddress = harEntry._request.remoteAddress(); const portPositionInString = ipAddress.lastIndexOf(':'); if (portPositionInString !== -1) @@ -70,7 +150,7 @@ BrowserSDK.HAREntry = class { time += Math.max(t, 0); const entry = { - startedDateTime: BrowserSDK.HARLog.pseudoWallTime(harEntry._request, harEntry._request.issueTime()).toJSON(), + startedDateTime: SDK.HARLog.pseudoWallTime(harEntry._request, harEntry._request.issueTime()).toJSON(), time: time, request: await harEntry._buildRequest(), response: harEntry._buildResponse(), @@ -86,7 +166,7 @@ BrowserSDK.HAREntry = class { if (harEntry._request.connectionId !== '0') entry.connection = harEntry._request.connectionId; - const page = BrowserSDK.PageLoad.forRequest(harEntry._request); + const page = SDK.NetworkLog.PageLoad.forRequest(harEntry._request); if (page) entry.pageref = 'page_' + page.id; return entry; @@ -150,7 +230,7 @@ BrowserSDK.HAREntry = class { } /** - * @return {!BrowserSDK.HAREntry.Timing} + * @return {!SDK.HARLog.Entry.Timing} */ _buildTimings() { // Order of events: request_start = 0, [proxy], [dns], [connect [ssl]], [send], duration @@ -162,7 +242,7 @@ BrowserSDK.HAREntry = class { const queuedTime = (issueTime < startTime) ? startTime - issueTime : -1; result.blocked = queuedTime; - result._blocked_queueing = BrowserSDK.HAREntry._toMilliseconds(queuedTime); + result._blocked_queueing = SDK.HARLog.Entry._toMilliseconds(queuedTime); let highestTime = 0; if (timing) { @@ -207,11 +287,11 @@ BrowserSDK.HAREntry = class { const requestTime = timing ? timing.requestTime : startTime; const waitStart = highestTime; - const waitEnd = BrowserSDK.HAREntry._toMilliseconds(this._request.responseReceivedTime - requestTime); + const waitEnd = SDK.HARLog.Entry._toMilliseconds(this._request.responseReceivedTime - requestTime); result.wait = waitEnd - waitStart; const receiveStart = waitEnd; - const receiveEnd = BrowserSDK.HAREntry._toMilliseconds(this._request.endTime - issueTime); + const receiveEnd = SDK.HARLog.Entry._toMilliseconds(this._request.endTime - issueTime); result.receive = Math.max(receiveEnd - receiveStart, 0); return result; @@ -273,7 +353,7 @@ BrowserSDK.HAREntry = class { value: cookie.value(), path: cookie.path(), domain: cookie.domain(), - expires: cookie.expiresDate(BrowserSDK.HARLog.pseudoWallTime(this._request, this._request.startTime)), + expires: cookie.expiresDate(SDK.HARLog.pseudoWallTime(this._request, this._request.startTime)), httpOnly: cookie.httpOnly(), secure: cookie.secure() }; @@ -323,85 +403,4 @@ BrowserSDK.HAREntry = class { _blocked_queueing: number, _blocked_proxy: (number|undefined) }} */ -BrowserSDK.HAREntry.Timing; - - -/** - * @unrestricted - */ -BrowserSDK.HARLog = class { - /** - * @param {!SDK.NetworkRequest} request - * @param {number} monotonicTime - * @return {!Date} - */ - static pseudoWallTime(request, monotonicTime) { - return new Date(request.pseudoWallTime(monotonicTime) * 1000); - } - - /** - * @param {!Array.<!SDK.NetworkRequest>} requests - * @return {!Promise<!Object>} - */ - static async build(requests) { - const log = new BrowserSDK.HARLog(); - const entryPromises = []; - for (const request of requests) - entryPromises.push(BrowserSDK.HAREntry.build(request)); - const entries = await Promise.all(entryPromises); - return {version: '1.2', creator: log._creator(), pages: log._buildPages(requests), entries: entries}; - } - - _creator() { - const webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent); - - return {name: 'WebInspector', version: webKitVersion ? webKitVersion[1] : 'n/a'}; - } - - /** - * @param {!Array.<!SDK.NetworkRequest>} requests - * @return {!Array.<!Object>} - */ - _buildPages(requests) { - const seenIdentifiers = {}; - const pages = []; - for (let i = 0; i < requests.length; ++i) { - const request = requests[i]; - const page = BrowserSDK.PageLoad.forRequest(request); - if (!page || seenIdentifiers[page.id]) - continue; - seenIdentifiers[page.id] = true; - pages.push(this._convertPage(page, request)); - } - return pages; - } - - /** - * @param {!BrowserSDK.PageLoad} page - * @param {!SDK.NetworkRequest} request - * @return {!Object} - */ - _convertPage(page, request) { - return { - startedDateTime: BrowserSDK.HARLog.pseudoWallTime(request, page.startTime).toJSON(), - id: 'page_' + page.id, - title: page.url, // We don't have actual page title here. URL is probably better than nothing. - pageTimings: { - onContentLoad: this._pageEventTime(page, page.contentLoadTime), - onLoad: this._pageEventTime(page, page.loadTime) - } - }; - } - - /** - * @param {!BrowserSDK.PageLoad} page - * @param {number} time - * @return {number} - */ - _pageEventTime(page, time) { - const startTime = page.startTime; - if (time === -1 || startTime === -1) - return -1; - return BrowserSDK.HAREntry._toMilliseconds(time - startTime); - } -}; +SDK.HARLog.Entry.Timing;
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js index f1330463f27..7de66309643 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js @@ -55,7 +55,7 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel { } /** - * @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>} + * @return {!Promise<!SDK.HeapProfilerModel.NativeHeapProfile>} */ async stopNativeSampling() { const rawProfile = await this._memoryAgent.getSamplingProfile(); @@ -64,7 +64,7 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel { } /** - * @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>} + * @return {!Promise<!SDK.HeapProfilerModel.NativeHeapProfile>} */ async takeNativeSnapshot() { const rawProfile = await this._memoryAgent.getAllTimeSamplingProfile(); @@ -72,7 +72,7 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel { } /** - * @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>} + * @return {!Promise<!SDK.HeapProfilerModel.NativeHeapProfile>} */ async takeNativeBrowserSnapshot() { const rawProfile = await this._memoryAgent.getBrowserSamplingProfile(); @@ -81,10 +81,11 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel { /** * @param {!Protocol.Memory.SamplingProfile} rawProfile - * @return {!Protocol.HeapProfiler.SamplingHeapProfile} + * @return {!SDK.HeapProfilerModel.NativeHeapProfile} */ _convertNativeProfile(rawProfile) { - const head = {children: new Map(), selfSize: 0, callFrame: {functionName: '(root)', url: ''}}; + const head = /** @type {!Protocol.HeapProfiler.SamplingHeapProfileNode} */ + ({children: new Map(), selfSize: 0, callFrame: {functionName: '(root)', url: ''}}); for (const sample of rawProfile.samples) { const node = sample.stack.reverse().reduce((node, name) => { let child = node.children.get(name); @@ -108,7 +109,7 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel { } convertChildren(head); - return /** @type {!Protocol.HeapProfiler.SamplingHeapProfile} */ ({head}); + return new SDK.HeapProfilerModel.NativeHeapProfile(head, rawProfile.modules); } /** @@ -218,6 +219,20 @@ SDK.HeapProfilerModel.Events = { }; /** + * @extends {Protocol.HeapProfiler.SamplingHeapProfile} + */ +SDK.HeapProfilerModel.NativeHeapProfile = class { + /** + * @param {!Protocol.HeapProfiler.SamplingHeapProfileNode} head + * @param {!Array<!Protocol.Memory.Module>} modules + */ + constructor(head, modules) { + this.head = head; + this.modules = modules; + } +}; + +/** * @extends {Protocol.HeapProfilerDispatcher} * @unrestricted */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/NetworkLog.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkLog.js index 78447fddd68..bcb9bf82b25 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/NetworkLog.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkLog.js @@ -31,14 +31,14 @@ /** * @implements {SDK.SDKModelObserver<!SDK.NetworkManager>} */ -BrowserSDK.NetworkLog = class extends Common.Object { +SDK.NetworkLog = class extends Common.Object { constructor() { super(); /** @type {!Array<!SDK.NetworkRequest>} */ this._requests = []; /** @type {!Set<!SDK.NetworkRequest>} */ this._requestsSet = new Set(); - /** @type {!Map<!SDK.NetworkManager, !BrowserSDK.PageLoad>} */ + /** @type {!Map<!SDK.NetworkManager, !SDK.NetworkLog.PageLoad>} */ this._pageLoadForManager = new Map(); this._isRecording = true; SDK.targetManager.observeModels(SDK.NetworkManager, this); @@ -72,7 +72,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { SDK.ResourceTreeModel.Events.DOMContentLoaded, this._onDOMContentLoaded.bind(this, resourceTreeModel))); } - networkManager[BrowserSDK.NetworkLog._events] = eventListeners; + networkManager[SDK.NetworkLog._events] = eventListeners; } /** @@ -87,7 +87,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { * @param {!SDK.NetworkManager} networkManager */ _removeNetworkManagerListeners(networkManager) { - Common.EventTarget.removeEventListeners(networkManager[BrowserSDK.NetworkLog._events]); + Common.EventTarget.removeEventListeners(networkManager[SDK.NetworkLog._events]); } /** @@ -152,9 +152,9 @@ BrowserSDK.NetworkLog = class extends Common.Object { * @param {!SDK.NetworkRequest} request */ _initializeInitiatorSymbolIfNeeded(request) { - if (!request[BrowserSDK.NetworkLog._initiatorDataSymbol]) { - /** @type {!{info: ?BrowserSDK.NetworkLog._InitiatorInfo, chain: !Set<!SDK.NetworkRequest>, request: (?SDK.NetworkRequest|undefined)}} */ - request[BrowserSDK.NetworkLog._initiatorDataSymbol] = { + if (!request[SDK.NetworkLog._initiatorDataSymbol]) { + /** @type {!{info: ?SDK.NetworkLog._InitiatorInfo, chain: !Set<!SDK.NetworkRequest>, request: (?SDK.NetworkRequest|undefined)}} */ + request[SDK.NetworkLog._initiatorDataSymbol] = { info: null, chain: null, request: undefined, @@ -164,12 +164,12 @@ BrowserSDK.NetworkLog = class extends Common.Object { /** * @param {!SDK.NetworkRequest} request - * @return {!BrowserSDK.NetworkLog._InitiatorInfo} + * @return {!SDK.NetworkLog._InitiatorInfo} */ initiatorInfoForRequest(request) { this._initializeInitiatorSymbolIfNeeded(request); - if (request[BrowserSDK.NetworkLog._initiatorDataSymbol].info) - return request[BrowserSDK.NetworkLog._initiatorDataSymbol].info; + if (request[SDK.NetworkLog._initiatorDataSymbol].info) + return request[SDK.NetworkLog._initiatorDataSymbol].info; let type = SDK.NetworkRequest.InitiatorType.Other; let url = ''; @@ -215,7 +215,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { } } - request[BrowserSDK.NetworkLog._initiatorDataSymbol].info = { + request[SDK.NetworkLog._initiatorDataSymbol].info = { type: type, url: url, lineNumber: lineNumber, @@ -223,12 +223,12 @@ BrowserSDK.NetworkLog = class extends Common.Object { scriptId: scriptId, stack: initiatorStack }; - return request[BrowserSDK.NetworkLog._initiatorDataSymbol].info; + return request[SDK.NetworkLog._initiatorDataSymbol].info; } /** * @param {!SDK.NetworkRequest} request - * @return {!BrowserSDK.NetworkLog.InitiatorGraph} + * @return {!SDK.NetworkLog.InitiatorGraph} */ initiatorGraphForRequest(request) { /** @type {!Set<!SDK.NetworkRequest>} */ @@ -249,7 +249,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { _initiatorChain(request) { this._initializeInitiatorSymbolIfNeeded(request); let initiatorChainCache = - /** @type {?Set<!SDK.NetworkRequest>} */ (request[BrowserSDK.NetworkLog._initiatorDataSymbol].chain); + /** @type {?Set<!SDK.NetworkRequest>} */ (request[SDK.NetworkLog._initiatorDataSymbol].chain); if (initiatorChainCache) return initiatorChainCache; @@ -257,8 +257,8 @@ BrowserSDK.NetworkLog = class extends Common.Object { let checkRequest = request; do { - if (checkRequest[BrowserSDK.NetworkLog._initiatorDataSymbol].chain) { - initiatorChainCache.addAll(checkRequest[BrowserSDK.NetworkLog._initiatorDataSymbol].chain); + if (checkRequest[SDK.NetworkLog._initiatorDataSymbol].chain) { + initiatorChainCache.addAll(checkRequest[SDK.NetworkLog._initiatorDataSymbol].chain); break; } if (initiatorChainCache.has(checkRequest)) @@ -266,7 +266,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { initiatorChainCache.add(checkRequest); checkRequest = this._initiatorRequest(checkRequest); } while (checkRequest); - request[BrowserSDK.NetworkLog._initiatorDataSymbol].chain = initiatorChainCache; + request[SDK.NetworkLog._initiatorDataSymbol].chain = initiatorChainCache; return initiatorChainCache; } @@ -276,13 +276,13 @@ BrowserSDK.NetworkLog = class extends Common.Object { */ _initiatorRequest(request) { this._initializeInitiatorSymbolIfNeeded(request); - if (request[BrowserSDK.NetworkLog._initiatorDataSymbol].request !== undefined) - return request[BrowserSDK.NetworkLog._initiatorDataSymbol].request; + if (request[SDK.NetworkLog._initiatorDataSymbol].request !== undefined) + return request[SDK.NetworkLog._initiatorDataSymbol].request; const url = this.initiatorInfoForRequest(request).url; const networkManager = SDK.NetworkManager.forRequest(request); - request[BrowserSDK.NetworkLog._initiatorDataSymbol].request = + request[SDK.NetworkLog._initiatorDataSymbol].request = networkManager ? this._requestByManagerAndURL(networkManager, url) : null; - return request[BrowserSDK.NetworkLog._initiatorDataSymbol].request; + return request[SDK.NetworkLog._initiatorDataSymbol].request; } _willReloadPage() { @@ -303,7 +303,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { const oldRequestsSet = this._requestsSet; this._requests = []; this._requestsSet = new Set(); - this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.Reset); + this.dispatchEventToListeners(SDK.NetworkLog.Events.Reset); // Preserve requests from the new session. let currentPageLoad = null; @@ -312,7 +312,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { if (request.loaderId !== mainFrame.loaderId) continue; if (!currentPageLoad) { - currentPageLoad = new BrowserSDK.PageLoad(request); + currentPageLoad = new SDK.NetworkLog.PageLoad(request); let redirectSource = request.redirectSource(); while (redirectSource) { requestsToAdd.push(redirectSource); @@ -327,14 +327,14 @@ BrowserSDK.NetworkLog = class extends Common.Object { this._requests.push(request); this._requestsSet.add(request); currentPageLoad.bindRequest(request); - this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request); + this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestAdded, request); } if (Common.moduleSetting('network_log.preserve-log').get()) { for (const request of oldRequestsSet) { this._requests.push(request); this._requestsSet.add(request); - this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request); + this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestAdded, request); } } @@ -352,7 +352,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { for (const request of requests) { this._requests.push(request); this._requestsSet.add(request); - this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request); + this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestAdded, request); } } @@ -367,7 +367,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { const pageLoad = manager ? this._pageLoadForManager.get(manager) : null; if (pageLoad) pageLoad.bindRequest(request); - this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request); + this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestAdded, request); } /** @@ -377,7 +377,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { const request = /** @type {!SDK.NetworkRequest} */ (event.data); if (!this._requestsSet.has(request)) return; - this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestUpdated, request); + this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestUpdated, request); } /** @@ -385,7 +385,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { */ _onRequestRedirect(event) { const request = /** @type {!SDK.NetworkRequest} */ (event.data); - delete request[BrowserSDK.NetworkLog._initiatorDataSymbol]; + delete request[SDK.NetworkLog._initiatorDataSymbol]; } /** @@ -418,7 +418,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { this._pageLoadForManager.delete(manager); } - this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.Reset); + this.dispatchEventToListeners(SDK.NetworkLog.Events.Reset); } /** @@ -447,7 +447,7 @@ BrowserSDK.NetworkLog = class extends Common.Object { const request = this.requestByManagerAndId(networkManager, requestId); if (!request) return; - consoleMessage[BrowserSDK.NetworkLog._requestSymbol] = request; + consoleMessage[SDK.NetworkLog._requestSymbol] = request; const initiator = request.initiator(); if (initiator) { consoleMessage.stackTrace = initiator.stack || undefined; @@ -463,16 +463,16 @@ BrowserSDK.NetworkLog = class extends Common.Object { * @return {?SDK.NetworkRequest} */ static requestForConsoleMessage(consoleMessage) { - return consoleMessage[BrowserSDK.NetworkLog._requestSymbol] || null; + return consoleMessage[SDK.NetworkLog._requestSymbol] || null; } }; -BrowserSDK.PageLoad = class { +SDK.NetworkLog.PageLoad = class { /** * @param {!SDK.NetworkRequest} mainRequest */ constructor(mainRequest) { - this.id = ++BrowserSDK.PageLoad._lastIdentifier; + this.id = ++SDK.NetworkLog.PageLoad._lastIdentifier; this.url = mainRequest.url(); this.startTime = mainRequest.startTime; /** @type {number} */ @@ -491,53 +491,53 @@ BrowserSDK.PageLoad = class { if (!this.mainRequest.finished) await this.mainRequest.once(SDK.NetworkRequest.Events.FinishedLoading); const saveDataHeader = this.mainRequest.requestHeaderValue('Save-Data'); - if (!BrowserSDK.PageLoad._dataSaverMessageWasShown && saveDataHeader && saveDataHeader === 'on') { + if (!SDK.NetworkLog.PageLoad._dataSaverMessageWasShown && saveDataHeader && saveDataHeader === 'on') { const message = Common.UIString( 'Consider disabling %s while debugging. For more info see: %s', Common.UIString('Chrome Data Saver'), 'https://support.google.com/chrome/?p=datasaver'); manager.dispatchEventToListeners( SDK.NetworkManager.Events.MessageGenerated, {message: message, requestId: this.mainRequest.requestId(), warning: true}); - BrowserSDK.PageLoad._dataSaverMessageWasShown = true; + SDK.NetworkLog.PageLoad._dataSaverMessageWasShown = true; } } /** * @param {!SDK.NetworkRequest} request - * @return {?BrowserSDK.PageLoad} + * @return {?SDK.NetworkLog.PageLoad} */ static forRequest(request) { - return request[BrowserSDK.PageLoad._pageLoadForRequestSymbol] || null; + return request[SDK.NetworkLog.PageLoad._pageLoadForRequestSymbol] || null; } /** * @param {!SDK.NetworkRequest} request */ bindRequest(request) { - request[BrowserSDK.PageLoad._pageLoadForRequestSymbol] = this; + request[SDK.NetworkLog.PageLoad._pageLoadForRequestSymbol] = this; } }; -BrowserSDK.PageLoad._lastIdentifier = 0; -BrowserSDK.PageLoad._pageLoadForRequestSymbol = Symbol('PageLoadForRequest'); -BrowserSDK.NetworkLog._requestSymbol = Symbol('_request'); +SDK.NetworkLog.PageLoad._lastIdentifier = 0; +SDK.NetworkLog.PageLoad._pageLoadForRequestSymbol = Symbol('PageLoadForRequest'); +SDK.NetworkLog._requestSymbol = Symbol('_request'); -BrowserSDK.PageLoad._dataSaverMessageWasShown = false; +SDK.NetworkLog.PageLoad._dataSaverMessageWasShown = false; /** @typedef {!{initiators: !Set<!SDK.NetworkRequest>, initiated: !Set<!SDK.NetworkRequest>}} */ -BrowserSDK.NetworkLog.InitiatorGraph; +SDK.NetworkLog.InitiatorGraph; -BrowserSDK.NetworkLog.Events = { +SDK.NetworkLog.Events = { Reset: Symbol('Reset'), RequestAdded: Symbol('RequestAdded'), RequestUpdated: Symbol('RequestUpdated') }; /** @typedef {!{type: !SDK.NetworkRequest.InitiatorType, url: string, lineNumber: number, columnNumber: number, scriptId: ?string, stack: ?Protocol.Runtime.StackTrace}} */ -BrowserSDK.NetworkLog._InitiatorInfo; +SDK.NetworkLog._InitiatorInfo; -BrowserSDK.NetworkLog._initiatorDataSymbol = Symbol('InitiatorData'); -BrowserSDK.NetworkLog._events = Symbol('BrowserSDK.NetworkLog.events'); +SDK.NetworkLog._initiatorDataSymbol = Symbol('InitiatorData'); +SDK.NetworkLog._events = Symbol('SDK.NetworkLog.events'); -/** @type {!BrowserSDK.NetworkLog} */ -BrowserSDK.networkLog = new BrowserSDK.NetworkLog(); +/** @type {!SDK.NetworkLog} */ +SDK.networkLog = new SDK.NetworkLog(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js index 3356ea5e604..9821eebc461 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js @@ -54,27 +54,13 @@ SDK.RuntimeModel = class extends SDK.SDKModel { } /** - * @param {string} code - * @return {string} + * @param {!SDK.RuntimeModel.EvaluationResult} response */ - static wrapObjectLiteralExpressionIfNeeded(code) { - // Only parenthesize what appears to be an object literal. - if (!(/^\s*\{/.test(code) && /\}\s*$/.test(code))) - return code; - - const parse = (async () => 0).constructor; - try { - // Check if the code can be interpreted as an expression. - parse('return ' + code + ';'); - - // No syntax error! Does it work parenthesized? - const wrappedCode = '(' + code + ')'; - parse(wrappedCode); - - return wrappedCode; - } catch (e) { - return code; - } + static isSideEffectFailure(response) { + const exceptionDetails = !response[Protocol.Error] && response.exceptionDetails; + return !!( + exceptionDetails && exceptionDetails.exception && exceptionDetails.exception.description && + exceptionDetails.exception.description.startsWith('EvalError: Possible side-effect in debug-evaluate')); } /** @@ -493,12 +479,8 @@ SDK.RuntimeModel = class extends SDK.SDKModel { const response = await this._agent.invoke_evaluate( {expression: SDK.RuntimeModel._sideEffectTestExpression, contextId: testContext.id, throwOnSideEffect: true}); - const exceptionDetails = !response[Protocol.Error] && response.exceptionDetails; - const supports = - !!(exceptionDetails && exceptionDetails.exception && - exceptionDetails.exception.description.startsWith('EvalError: Possible side-effect in debug-evaluate')); - this._hasSideEffectSupport = supports; - return supports; + this._hasSideEffectSupport = SDK.RuntimeModel.isSideEffectFailure(response); + return this._hasSideEffectSupport; } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Script.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Script.js index 7a2a8228de7..14c5d7d2f08 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Script.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Script.js @@ -43,10 +43,11 @@ SDK.Script = class { * @param {string|undefined} sourceMapURL * @param {boolean} hasSourceURL * @param {number} length + * @param {?Protocol.Runtime.StackTrace} originStackTrace */ constructor( debuggerModel, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, - isContentScript, isLiveEdit, sourceMapURL, hasSourceURL, length) { + isContentScript, isLiveEdit, sourceMapURL, hasSourceURL, length, originStackTrace) { this.debuggerModel = debuggerModel; this.scriptId = scriptId; this.sourceURL = sourceURL; @@ -64,6 +65,7 @@ SDK.Script = class { this.contentLength = length; this._originalContentProvider = null; this._originalSource = null; + this.originStackTrace = originStackTrace; } /** @@ -141,7 +143,10 @@ SDK.Script = class { if (!this.scriptId) return ''; const source = await this.debuggerModel.target().debuggerAgent().getScriptSource(this.scriptId); - this._source = source ? SDK.Script._trimSourceURLComment(source) : ''; + if (source && this.hasSourceURL) + this._source = SDK.Script._trimSourceURLComment(source); + else + this._source = source || ''; if (this._originalSource === null) this._originalSource = this._source; return this._source; @@ -254,10 +259,7 @@ SDK.Script = class { async setBlackboxedRanges(positions) { const response = await this.debuggerModel.target().debuggerAgent().invoke_setBlackboxedRanges( {scriptId: this.scriptId, positions}); - const error = response[Protocol.Error]; - if (error) - console.error(error); - return !error; + return !response[Protocol.Error]; } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js index 20c4181754b..1a40f512f05 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js @@ -136,18 +136,6 @@ SDK.SourceMap.prototype = { * @return {?SDK.SourceMapEntry} */ findEntry(lineNumber, columnNumber) {}, - - /** - * @return {boolean} - */ - editable() {}, - - /** - * @param {!Array<!TextUtils.TextRange>} ranges - * @param {!Array<string>} texts - * @return {!Promise<?SDK.SourceMap.EditResult>} - */ - editCompiled(ranges, texts) {}, }; /** @@ -167,20 +155,6 @@ SDK.SourceMap.EditResult = class { }; /** - * @interface - */ -SDK.SourceMapFactory = function() {}; - -SDK.SourceMapFactory.prototype = { - /** - * @param {!SDK.Target} target - * @param {!SDK.SourceMap} sourceMap - * @return {!Promise<?SDK.SourceMap>} - */ - editableSourceMap(target, sourceMap) {}, -}; - -/** * @implements {SDK.SourceMap} * @unrestricted */ @@ -298,24 +272,6 @@ SDK.TextSourceMap = class { /** * @override - * @return {boolean} - */ - editable() { - return false; - } - - /** - * @override - * @param {!Array<!TextUtils.TextRange>} ranges - * @param {!Array<string>} texts - * @return {!Promise<?SDK.SourceMap.EditResult>} - */ - editCompiled(ranges, texts) { - return Promise.resolve(/** @type {?SDK.SourceMap.EditResult} */ (null)); - } - - /** - * @override * @param {number} lineNumber in compiled resource * @param {number} columnNumber in compiled resource * @return {?SDK.SourceMapEntry} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMapManager.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMapManager.js index 0298991f1c8..6024d21cd0e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMapManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMapManager.js @@ -141,31 +141,12 @@ SDK.SourceMapManager = class extends Common.Object { } if (!this._sourceMapURLToLoadingClients.has(sourceMapURL)) { SDK.TextSourceMap.load(sourceMapURL, sourceURL) - .then(onTextSourceMapLoaded.bind(this, sourceMapURL)) .then(onSourceMap.bind(this, sourceMapURL)); } this._sourceMapURLToLoadingClients.set(sourceMapURL, client); /** * @param {string} sourceMapURL - * @param {?SDK.TextSourceMap} sourceMap - * @return {!Promise<?SDK.SourceMap>} - * @this {SDK.SourceMapManager} - */ - function onTextSourceMapLoaded(sourceMapURL, sourceMap) { - if (!sourceMap) - return Promise.resolve(/** @type {?SDK.SourceMap} */ (null)); - const factoryExtension = this._factoryForSourceMap(sourceMap); - if (!factoryExtension) - return Promise.resolve(/** @type {?SDK.SourceMap} */ (sourceMap)); - return factoryExtension.instance() - .then(factory => factory.editableSourceMap(this._target, sourceMap)) - .then(map => map || sourceMap) - .catchException(/** @type {?SDK.SourceMap} */ (null)); - } - - /** - * @param {string} sourceMapURL * @param {?SDK.SourceMap} sourceMap * @this {SDK.SourceMapManager} */ @@ -199,22 +180,6 @@ SDK.SourceMapManager = class extends Common.Object { } /** - * @param {!SDK.SourceMap} sourceMap - * @return {?Runtime.Extension} - */ - _factoryForSourceMap(sourceMap) { - const sourceExtensions = new Set(); - for (const url of sourceMap.sourceURLs()) - sourceExtensions.add(Common.ParsedURL.extractExtension(url)); - for (const runtimeExtension of self.runtime.extensions(SDK.SourceMapFactory)) { - const supportedExtensions = new Set(runtimeExtension.descriptor()['extensions']); - if (supportedExtensions.containsAll(sourceExtensions)) - return runtimeExtension; - } - return null; - } - - /** * @param {!T} client */ detachSourceMap(client) { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json b/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json index 7edcfedf2c0..89048fb52ac 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json @@ -284,6 +284,7 @@ "DOMModel.js", "DebuggerModel.js", "EmulationModel.js", + "HARLog.js", "LayerTreeBase.js", "LogModel.js", "ServiceWorkerManager.js", @@ -301,6 +302,7 @@ "SourceMap.js", "SourceMapManager.js", "NetworkManager.js", + "NetworkLog.js", "NetworkRequest.js", "PaintProfiler.js", "HeapProfilerModel.js", diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js index a6bf418966d..d062f78d520 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js @@ -190,7 +190,7 @@ SDKTestRunner.PageMock = class { return true; } - _dispatch(id, methodName, params, message) { + _dispatch(id, methodName, params) { const handler = (this._isSupportedDomain(methodName) ? this._dispatchMap[methodName] : null); if (handler) @@ -230,9 +230,8 @@ MockPageConnection = class { setTimeout(() => this._onMessage.call(null, JSON.stringify(message)), 0); } - sendMessage(message) { - const json = JSON.parse(message); - this._page._dispatch(json.id, json.method, json.params, message); + sendMessage(domain, message) { + this._page._dispatch(message.id, message.method, message.params); } disconnect() { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetFileSystem.js b/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetFileSystem.js new file mode 100644 index 00000000000..2f3c1c4ce4c --- /dev/null +++ b/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetFileSystem.js @@ -0,0 +1,220 @@ +// Copyright 2018 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. + +Snippets.SnippetFileSystem = class extends Persistence.PlatformFileSystem { + constructor() { + super('snippet://', 'snippets'); + this._lastSnippetIdentifierSetting = Common.settings.createSetting('scriptSnippets_lastIdentifier', 0); + this._snippetsSetting = Common.settings.createSetting('scriptSnippets', []); + } + + /** + * @override + * @return {!Array<string>} + */ + initialFilePaths() { + const savedSnippets = this._snippetsSetting.get(); + return savedSnippets.map(snippet => escape(snippet.name)); + } + + /** + * @override + * @param {string} path + * @param {?string} name + * @return {!Promise<?string>} + */ + async createFile(path, name) { + const nextId = this._lastSnippetIdentifierSetting.get() + 1; + this._lastSnippetIdentifierSetting.set(nextId); + + const snippetName = `Script snippet #${nextId}`; + const snippets = this._snippetsSetting.get(); + snippets.push({name: snippetName, content: ''}); + this._snippetsSetting.set(snippets); + + return escape(snippetName); + } + + /** + * @override + * @param {string} path + * @return {!Promise<boolean>} + */ + async deleteFile(path) { + const name = unescape(path.substring(1)); + const allSnippets = this._snippetsSetting.get(); + const snippets = allSnippets.filter(snippet => snippet.name !== name); + if (allSnippets.length !== snippets.length) { + this._snippetsSetting.set(snippets); + return true; + } + return false; + } + + /** + * @override + * @param {string} path + * @param {function(?string,boolean)} callback + */ + requestFileContent(path, callback) { + const name = unescape(path.substring(1)); + const snippet = this._snippetsSetting.get().find(snippet => snippet.name === name); + callback(snippet ? snippet.content : null, /* encoded */ false); + } + + /** + * @override + * @param {string} path + * @param {string} content + * @param {boolean} isBase64 + */ + async setFileContent(path, content, isBase64) { + const name = unescape(path.substring(1)); + const snippets = this._snippetsSetting.get(); + const snippet = snippets.find(snippet => snippet.name === name); + if (snippet) { + snippet.content = content; + this._snippetsSetting.set(snippets); + return true; + } + return false; + } + + /** + * @override + * @param {string} path + * @param {string} newName + * @param {function(boolean, string=)} callback + */ + renameFile(path, newName, callback) { + const name = unescape(path.substring(1)); + const snippets = this._snippetsSetting.get(); + const snippet = snippets.find(snippet => snippet.name === name); + newName = newName.trim(); + if (!snippet || newName.length === 0 || snippets.find(snippet => snippet.name === newName)) { + callback(false); + return; + } + snippet.name = newName; + this._snippetsSetting.set(snippets); + callback(true, newName); + } + + /** + * @override + * @param {string} query + * @param {!Common.Progress} progress + * @return {!Promise<!Array<string>>} + */ + async searchInPath(query, progress) { + const re = new RegExp(query.escapeForRegExp(), 'i'); + const snippets = this._snippetsSetting.get().filter(snippet => snippet.content.match(re)); + return snippets.map(snippet => escape(snippet.name)); + } + + /** + * @override + * @param {string} path + * @return {string} + */ + mimeFromPath(path) { + return 'text/javascript'; + } + + /** + * @override + * @param {string} path + * @return {!Common.ResourceType} + */ + contentType(path) { + return Common.resourceTypes.Script; + } + + /** + * @override + * @param {string} url + * @return {string} + */ + tooltipForURL(url) { + return ls`Linked to ${unescape(url.substring(this.path().length))}`; + } + + /** + * @override + * @return {boolean} + */ + supportsAutomapping() { + return true; + } +}; + +/** + * @param {!Workspace.UISourceCode} uiSourceCode + */ +Snippets.evaluateScriptSnippet = async function(uiSourceCode) { + if (!uiSourceCode.url().startsWith('snippet://')) + return; + + const executionContext = UI.context.flavor(SDK.ExecutionContext); + if (!executionContext) + return; + + const runtimeModel = executionContext.runtimeModel; + + await uiSourceCode.requestContent(); + uiSourceCode.commitWorkingCopy(); + const expression = uiSourceCode.workingCopy(); + Common.console.show(); + + const url = uiSourceCode.url(); + let scriptId; + { + const result = await runtimeModel.compileScript(expression, url, true, executionContext.id); + if (!result.scriptId && !result.exceptionDetails) + return; + if (!result.scriptId) { + SDK.consoleModel.addMessage(SDK.ConsoleMessage.fromException( + runtimeModel, result.exceptionDetails, /* messageType */ undefined, /* timestamp */ undefined, url)); + return; + } + scriptId = result.scriptId; + } + const result = await runtimeModel.runScript( + scriptId, executionContext.id, 'console', /* silent */ false, /* includeCommandLineAPI */ true, + /* returnByValue */ false, /* generatePreview */ true); + if (!result.object && !result.exceptionDetails) + return; + if (result.object) { + const consoleMessage = new SDK.ConsoleMessage( + runtimeModel, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Info, '', + SDK.ConsoleMessage.MessageType.Result, url, undefined, undefined, [result.object], undefined, undefined, + executionContext.id, scriptId); + SDK.consoleModel.addMessage(consoleMessage); + } else { + SDK.consoleModel.addMessage( + SDK.ConsoleMessage.fromException(runtimeModel, result.exceptionDetails, undefined, undefined, url)); + } +}; + +/** + * @param {!Workspace.UISourceCode} uiSourceCode + * @return {boolean} + */ +Snippets.isSnippetsUISourceCode = function(uiSourceCode) { + return uiSourceCode.url().startsWith('snippet://'); +}; + +/** + * @param {!Workspace.Project} project + * @return {boolean} + */ +Snippets.isSnippetsProject = function(project) { + return project.type() === Workspace.projectTypes.FileSystem && + Persistence.FileSystemWorkspaceBinding.fileSystemType(project) === 'snippets'; +}; + +Persistence.isolatedFileSystemManager.addPlatformFileSystem('snippet://', new Snippets.SnippetFileSystem()); +Snippets.project = /** @type {!Workspace.Project} */ ( + Workspace.workspace.projectsForType(Workspace.projectTypes.FileSystem) + .find(project => Persistence.FileSystemWorkspaceBinding.fileSystemType(project) === 'snippets')); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetModel.js b/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetModel.js deleted file mode 100644 index 1420585297d..00000000000 --- a/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetModel.js +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/** - * @unrestricted - * @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>} - * @implements {Bindings.DebuggerSourceMapping} - */ -Snippets.ScriptSnippetModel = class extends Common.Object { - /** - * @param {!Workspace.Workspace} workspace - */ - constructor(workspace) { - super(); - this._workspace = workspace; - /** @type {!Object.<string, !Workspace.UISourceCode>} */ - this._uiSourceCodeForSnippetId = {}; - /** @type {!Map.<!Workspace.UISourceCode, string>} */ - this._snippetIdForUISourceCode = new Map(); - - /** @type {!Map.<!SDK.DebuggerModel, !Snippets.SnippetScriptMapping>} */ - this._mappingForDebuggerModel = new Map(); - this._snippetStorage = new Snippets.SnippetStorage('script', 'Script snippet #'); - this._lastSnippetEvaluationIndexSetting = Common.settings.createSetting('lastSnippetEvaluationIndex', 0); - this._project = new Snippets.SnippetsProject(workspace, this); - this._loadSnippets(); - SDK.targetManager.observeModels(SDK.DebuggerModel, this); - Bindings.debuggerWorkspaceBinding.addSourceMapping(this); - } - - /** - * @override - * @param {!SDK.DebuggerModel} debuggerModel - */ - modelAdded(debuggerModel) { - this._mappingForDebuggerModel.set(debuggerModel, new Snippets.SnippetScriptMapping(debuggerModel, this)); - } - - /** - * @override - * @param {!SDK.DebuggerModel} debuggerModel - */ - modelRemoved(debuggerModel) { - this._mappingForDebuggerModel.remove(debuggerModel); - } - - /** - * @override - * @param {!SDK.DebuggerModel.Location} rawLocation - * @return {?Workspace.UILocation} - */ - rawLocationToUILocation(rawLocation) { - const mapping = this._mappingForDebuggerModel.get(rawLocation.debuggerModel); - if (!mapping) - return null; - return mapping.rawLocationToUILocation(rawLocation); - } - - /** - * @override - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {number} lineNumber - * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} - */ - uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) { - for (const mapping of this._mappingForDebuggerModel.values()) { - const rawLocation = mapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber); - if (rawLocation) - return rawLocation; - } - return null; - } - - /** - * @param {!SDK.DebuggerModel} debuggerModel - * @return {!Snippets.SnippetScriptMapping|undefined} - */ - snippetScriptMapping(debuggerModel) { - return this._mappingForDebuggerModel.get(debuggerModel); - } - - /** - * @return {!Workspace.Project} - */ - project() { - return this._project; - } - - _loadSnippets() { - for (const snippet of this._snippetStorage.snippets()) - this._addScriptSnippet(snippet); - } - - /** - * @param {string} content - * @return {!Workspace.UISourceCode} - */ - createScriptSnippet(content) { - const snippet = this._snippetStorage.createSnippet(); - snippet.content = content; - return this._addScriptSnippet(snippet); - } - - /** - * @param {!Snippets.Snippet} snippet - * @return {!Workspace.UISourceCode} - */ - _addScriptSnippet(snippet) { - const uiSourceCode = this._project.addSnippet(snippet.name, new Snippets.SnippetContentProvider(snippet)); - uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this); - this._snippetIdForUISourceCode.set(uiSourceCode, snippet.id); - const breakpointLocations = this._removeBreakpoints(uiSourceCode); - this._restoreBreakpoints(uiSourceCode, breakpointLocations); - this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode; - return uiSourceCode; - } - - /** - * @param {!Common.Event} event - */ - _workingCopyChanged(event) { - const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); - this._scriptSnippetEdited(uiSourceCode); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - */ - deleteScriptSnippet(uiSourceCode) { - const snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || ''; - const snippet = this._snippetStorage.snippetForId(snippetId); - if (!snippet) - return; - this._snippetStorage.deleteSnippet(snippet); - this._removeBreakpoints(uiSourceCode); - this._releaseSnippetScript(uiSourceCode); - delete this._uiSourceCodeForSnippetId[snippet.id]; - this._snippetIdForUISourceCode.remove(uiSourceCode); - this._project.removeFile(snippet.name); - } - - /** - * @param {string} name - * @param {string} newName - * @param {function(boolean, string=)} callback - */ - renameScriptSnippet(name, newName, callback) { - newName = newName.trim(); - if (!newName || newName.indexOf('/') !== -1 || name === newName || this._snippetStorage.snippetForName(newName)) { - callback(false); - return; - } - const snippet = this._snippetStorage.snippetForName(name); - console.assert(snippet, 'Snippet \'' + name + '\' was not found.'); - const uiSourceCode = this._uiSourceCodeForSnippetId[snippet.id]; - console.assert(uiSourceCode, 'No uiSourceCode was found for snippet \'' + name + '\'.'); - - const breakpointLocations = this._removeBreakpoints(uiSourceCode); - snippet.name = newName; - this._restoreBreakpoints(uiSourceCode, breakpointLocations); - callback(true, newName); - } - - /** - * @param {string} name - * @param {string} newContent - */ - _setScriptSnippetContent(name, newContent) { - const snippet = this._snippetStorage.snippetForName(name); - snippet.content = newContent; - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - */ - _scriptSnippetEdited(uiSourceCode) { - const breakpointLocations = this._removeBreakpoints(uiSourceCode); - this._releaseSnippetScript(uiSourceCode); - this._restoreBreakpoints(uiSourceCode, breakpointLocations); - this._mappingForDebuggerModel.valuesArray().forEach(function(mapping) { - mapping._restoreBreakpoints(uiSourceCode, breakpointLocations); - }); - } - - /** - * @return {number} - */ - _nextEvaluationIndex() { - const evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1; - this._lastSnippetEvaluationIndexSetting.set(evaluationIndex); - return evaluationIndex; - } - - /** - * @param {!SDK.ExecutionContext} executionContext - * @param {!Workspace.UISourceCode} uiSourceCode - * @return {!Promise<undefined>} - */ - async evaluateScriptSnippet(executionContext, uiSourceCode) { - console.assert(uiSourceCode.project().type() === Workspace.projectTypes.Snippets); - let breakpointLocations = this._removeBreakpoints(uiSourceCode); - this._releaseSnippetScript(uiSourceCode); - this._restoreBreakpoints(uiSourceCode, breakpointLocations); - - const runtimeModel = executionContext.runtimeModel; - const debuggerModel = executionContext.debuggerModel; - const evaluationIndex = this._nextEvaluationIndex(); - const mapping = this._mappingForDebuggerModel.get(debuggerModel); - mapping._setEvaluationIndex(evaluationIndex, uiSourceCode); - const evaluationUrl = mapping._evaluationSourceURL(uiSourceCode); - await uiSourceCode.requestContent(); - const expression = uiSourceCode.workingCopy(); - Common.console.show(); - const result = await runtimeModel.compileScript(expression, '', true, executionContext.id); - if (!result || mapping.evaluationIndex(uiSourceCode) !== evaluationIndex) - return; - const script = /** @type {!SDK.Script} */ ( - debuggerModel.scriptForId(/** @type {string} */ (result.scriptId || result.exceptionDetails.scriptId))); - mapping._addScript(script, uiSourceCode); - if (!result.scriptId) { - this._printRunOrCompileScriptResultFailure( - runtimeModel, /** @type {!Protocol.Runtime.ExceptionDetails} */ (result.exceptionDetails), evaluationUrl); - return; - } - - breakpointLocations = this._removeBreakpoints(uiSourceCode); - this._restoreBreakpoints(uiSourceCode, breakpointLocations); - - this._runScript(script.scriptId, executionContext, evaluationUrl); - } - - /** - * @param {!Protocol.Runtime.ScriptId} scriptId - * @param {!SDK.ExecutionContext} executionContext - * @param {?string=} sourceURL - */ - async _runScript(scriptId, executionContext, sourceURL) { - const runtimeModel = executionContext.runtimeModel; - const result = await runtimeModel.runScript( - scriptId, executionContext.id, 'console', /* silent */ false, /* includeCommandLineAPI */ true, - /* returnByValue */ false, /* generatePreview */ true); - if (result.error) - return; - if (!result.exceptionDetails) - this._printRunScriptResult(runtimeModel, result.object || null, scriptId, sourceURL); - else - this._printRunOrCompileScriptResultFailure(runtimeModel, result.exceptionDetails, sourceURL); - } - - /** - * @param {!SDK.RuntimeModel} runtimeModel - * @param {?SDK.RemoteObject} result - * @param {!Protocol.Runtime.ScriptId} scriptId - * @param {?string=} sourceURL - */ - _printRunScriptResult(runtimeModel, result, scriptId, sourceURL) { - const consoleMessage = new SDK.ConsoleMessage( - runtimeModel, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Info, '', - SDK.ConsoleMessage.MessageType.Result, sourceURL, undefined, undefined, [result], undefined, undefined, - undefined, scriptId); - SDK.consoleModel.addMessage(consoleMessage); - } - - /** - * @param {!SDK.RuntimeModel} runtimeModel - * @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails - * @param {?string=} sourceURL - */ - _printRunOrCompileScriptResultFailure(runtimeModel, exceptionDetails, sourceURL) { - SDK.consoleModel.addMessage( - SDK.ConsoleMessage.fromException(runtimeModel, exceptionDetails, undefined, undefined, sourceURL || undefined)); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} - */ - _removeBreakpoints(uiSourceCode) { - const breakpointLocations = Bindings.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode); - for (let i = 0; i < breakpointLocations.length; ++i) - breakpointLocations[i].breakpoint.remove(false /* keepInStorage */); - return breakpointLocations; - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} breakpointLocations - */ - _restoreBreakpoints(uiSourceCode, breakpointLocations) { - for (let i = 0; i < breakpointLocations.length; ++i) { - const uiLocation = breakpointLocations[i].uiLocation; - const breakpoint = breakpointLocations[i].breakpoint; - Bindings.breakpointManager.setBreakpoint( - uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled()); - } - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - */ - _releaseSnippetScript(uiSourceCode) { - this._mappingForDebuggerModel.valuesArray().forEach(function(mapping) { - mapping._releaseSnippetScript(uiSourceCode); - }); - } - - /** - * @param {string} sourceURL - * @return {?string} - */ - _snippetIdForSourceURL(sourceURL) { - const snippetPrefix = Snippets.ScriptSnippetModel.snippetSourceURLPrefix; - if (!sourceURL.startsWith(snippetPrefix)) - return null; - const splitURL = sourceURL.substring(snippetPrefix.length).split('_'); - const snippetId = splitURL[0]; - return snippetId; - } -}; - -Snippets.ScriptSnippetModel.snippetSourceURLPrefix = 'snippets:///'; - -/** - * @unrestricted - */ -Snippets.SnippetScriptMapping = class { - /** - * @param {!SDK.DebuggerModel} debuggerModel - * @param {!Snippets.ScriptSnippetModel} scriptSnippetModel - */ - constructor(debuggerModel, scriptSnippetModel) { - this._debuggerModel = debuggerModel; - this._scriptSnippetModel = scriptSnippetModel; - /** @type {!Object.<string, !Workspace.UISourceCode>} */ - this._uiSourceCodeForScriptId = {}; - /** @type {!Map.<!Workspace.UISourceCode, !SDK.Script>} */ - this._scriptForUISourceCode = new Map(); - /** @type {!Map.<!Workspace.UISourceCode, number>} */ - this._evaluationIndexForUISourceCode = new Map(); - debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._reset, this); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - */ - _releaseSnippetScript(uiSourceCode) { - const script = this._scriptForUISourceCode.get(uiSourceCode); - if (!script) - return; - - delete this._uiSourceCodeForScriptId[script.scriptId]; - this._scriptForUISourceCode.remove(uiSourceCode); - this._evaluationIndexForUISourceCode.remove(uiSourceCode); - } - - /** - * @param {number} evaluationIndex - * @param {!Workspace.UISourceCode} uiSourceCode - */ - _setEvaluationIndex(evaluationIndex, uiSourceCode) { - this._evaluationIndexForUISourceCode.set(uiSourceCode, evaluationIndex); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @return {number|undefined} - */ - evaluationIndex(uiSourceCode) { - return this._evaluationIndexForUISourceCode.get(uiSourceCode); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @return {string} - */ - _evaluationSourceURL(uiSourceCode) { - const evaluationSuffix = '_' + this._evaluationIndexForUISourceCode.get(uiSourceCode); - const snippetId = this._scriptSnippetModel._snippetIdForUISourceCode.get(uiSourceCode); - return Snippets.ScriptSnippetModel.snippetSourceURLPrefix + snippetId + evaluationSuffix; - } - - _reset() { - this._uiSourceCodeForScriptId = {}; - this._scriptForUISourceCode.clear(); - this._evaluationIndexForUISourceCode.clear(); - } - - /** - * @param {!SDK.DebuggerModel.Location} rawLocation - * @return {?Workspace.UILocation} - */ - rawLocationToUILocation(rawLocation) { - const debuggerModelLocation = /** @type {!SDK.DebuggerModel.Location} */ (rawLocation); - const uiSourceCode = this._uiSourceCodeForScriptId[debuggerModelLocation.scriptId]; - if (!uiSourceCode) - return null; - - return uiSourceCode.uiLocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {number} lineNumber - * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} - */ - uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) { - const script = this._scriptForUISourceCode.get(uiSourceCode); - if (!script) - return null; - - return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber); - } - - /** - * @param {!SDK.Script} script - * @param {!Workspace.UISourceCode} uiSourceCode - */ - _addScript(script, uiSourceCode) { - console.assert(!this._scriptForUISourceCode.get(uiSourceCode)); - this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode; - this._scriptForUISourceCode.set(uiSourceCode, script); - Bindings.debuggerWorkspaceBinding.updateLocations(script); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} breakpointLocations - */ - _restoreBreakpoints(uiSourceCode, breakpointLocations) { - const script = this._scriptForUISourceCode.get(uiSourceCode); - if (!script) - return; - const rawLocation = - /** @type {!SDK.DebuggerModel.Location} */ (this._debuggerModel.createRawLocation(script, 0, 0)); - const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation); - if (uiLocation) - this._scriptSnippetModel._restoreBreakpoints(uiLocation.uiSourceCode, breakpointLocations); - } -}; - -/** - * @implements {Common.ContentProvider} - * @unrestricted - */ -Snippets.SnippetContentProvider = class { - /** - * @param {!Snippets.Snippet} snippet - */ - constructor(snippet) { - this._snippet = snippet; - } - - /** - * @override - * @return {string} - */ - contentURL() { - return ''; - } - - /** - * @override - * @return {!Common.ResourceType} - */ - contentType() { - return Common.resourceTypes.Snippet; - } - - /** - * @override - * @return {!Promise<boolean>} - */ - contentEncoded() { - return Promise.resolve(false); - } - - /** - * @override - * @return {!Promise<?string>} - */ - requestContent() { - return Promise.resolve(/** @type {?string} */ (this._snippet.content)); - } - - /** - * @override - * @param {string} query - * @param {boolean} caseSensitive - * @param {boolean} isRegex - * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>} - */ - async searchInContent(query, caseSensitive, isRegex) { - return Common.ContentProvider.performSearchInContent(this._snippet.content, query, caseSensitive, isRegex); - } -}; - -/** - * @unrestricted - */ -Snippets.SnippetsProject = class extends Bindings.ContentProviderBasedProject { - /** - * @param {!Workspace.Workspace} workspace - * @param {!Snippets.ScriptSnippetModel} model - */ - constructor(workspace, model) { - super(workspace, 'snippets:', Workspace.projectTypes.Snippets, '', false /* isServiceProject */); - this._model = model; - } - - /** - * @param {string} name - * @param {!Common.ContentProvider} contentProvider - * @return {!Workspace.UISourceCode} - */ - addSnippet(name, contentProvider) { - return this.addContentProvider(name, contentProvider, 'text/javascript'); - } - - /** - * @override - * @return {boolean} - */ - canSetFileContent() { - return true; - } - - /** - * @override - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {string} newContent - * @param {boolean} isBase64 - * @return {!Promise} - */ - async setFileContent(uiSourceCode, newContent, isBase64) { - this._model._setScriptSnippetContent(uiSourceCode.url(), newContent); - } - - /** - * @override - * @return {boolean} - */ - canRename() { - return true; - } - - /** - * @override - * @param {string} url - * @param {string} newName - * @param {function(boolean, string=)} callback - */ - performRename(url, newName, callback) { - this._model.renameScriptSnippet(url, newName, callback); - } - - /** - * @override - * @param {string} url - * @param {?string} name - * @param {string} content - * @param {boolean=} isBase64 - * @return {!Promise<?Workspace.UISourceCode>} - */ - createFile(url, name, content, isBase64) { - return /** @type {!Promise<?Workspace.UISourceCode>} */ (Promise.resolve(this._model.createScriptSnippet(content))); - } - - /** - * @override - * @param {!Workspace.UISourceCode} uiSourceCode - */ - deleteFile(uiSourceCode) { - this._model.deleteScriptSnippet(uiSourceCode); - } -}; - -/** - * @type {!Snippets.ScriptSnippetModel} - */ -Snippets.scriptSnippetModel = new Snippets.ScriptSnippetModel(Workspace.workspace); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetStorage.js b/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetStorage.js deleted file mode 100644 index 3f0bff09db1..00000000000 --- a/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetStorage.js +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @unrestricted - */ -Snippets.SnippetStorage = class extends Common.Object { - constructor(settingPrefix, namePrefix) { - super(); - /** @type {!Map<string,!Snippets.Snippet>} */ - this._snippets = new Map(); - - this._lastSnippetIdentifierSetting = Common.settings.createSetting(settingPrefix + 'Snippets_lastIdentifier', 0); - this._snippetsSetting = Common.settings.createSetting(settingPrefix + 'Snippets', []); - this._namePrefix = namePrefix; - - this._loadSettings(); - } - - get namePrefix() { - return this._namePrefix; - } - - _saveSettings() { - const savedSnippets = []; - for (const snippet of this._snippets.values()) - savedSnippets.push(snippet.serializeToObject()); - this._snippetsSetting.set(savedSnippets); - } - - /** - * @return {!Array<!Snippets.Snippet>} - */ - snippets() { - return this._snippets.valuesArray(); - } - - /** - * @param {string} id - * @return {?Snippets.Snippet} - */ - snippetForId(id) { - return this._snippets.get(id); - } - - /** - * @param {string} name - * @return {?Snippets.Snippet} - */ - snippetForName(name) { - for (const snippet of this._snippets.values()) { - if (snippet.name === name) - return snippet; - } - return null; - } - - _loadSettings() { - const savedSnippets = this._snippetsSetting.get(); - for (let i = 0; i < savedSnippets.length; ++i) - this._snippetAdded(Snippets.Snippet.fromObject(this, savedSnippets[i])); - } - - /** - * @param {!Snippets.Snippet} snippet - */ - deleteSnippet(snippet) { - this._snippets.delete(snippet.id); - this._saveSettings(); - } - - /** - * @return {!Snippets.Snippet} - */ - createSnippet() { - const nextId = this._lastSnippetIdentifierSetting.get() + 1; - const snippetId = String(nextId); - this._lastSnippetIdentifierSetting.set(nextId); - const snippet = new Snippets.Snippet(this, snippetId); - this._snippetAdded(snippet); - this._saveSettings(); - return snippet; - } - - /** - * @param {!Snippets.Snippet} snippet - */ - _snippetAdded(snippet) { - this._snippets.set(snippet.id, snippet); - } -}; - -/** - * @unrestricted - */ -Snippets.Snippet = class extends Common.Object { - /** - * @param {!Snippets.SnippetStorage} storage - * @param {string} id - * @param {string=} name - * @param {string=} content - */ - constructor(storage, id, name, content) { - super(); - this._storage = storage; - this._id = id; - this._name = name || storage.namePrefix + id; - this._content = content || ''; - } - - /** - * @param {!Snippets.SnippetStorage} storage - * @param {!Object} serializedSnippet - * @return {!Snippets.Snippet} - */ - static fromObject(storage, serializedSnippet) { - return new Snippets.Snippet(storage, serializedSnippet.id, serializedSnippet.name, serializedSnippet.content); - } - - /** - * @return {string} - */ - get id() { - return this._id; - } - - /** - * @return {string} - */ - get name() { - return this._name; - } - - /** - * @param {string} name - */ - set name(name) { - if (this._name === name) - return; - - this._name = name; - this._storage._saveSettings(); - } - - /** - * @return {string} - */ - get content() { - return this._content; - } - - /** - * @param {string} content - */ - set content(content) { - if (this._content === content) - return; - - this._content = content; - this._storage._saveSettings(); - } - - /** - * @return {!Object} - */ - serializeToObject() { - const serializedSnippet = {}; - serializedSnippet.id = this.id; - serializedSnippet.name = this.name; - serializedSnippet.content = this.content; - return serializedSnippet; - } -}; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetsQuickOpen.js b/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetsQuickOpen.js index ba86f8d37f0..c48bf1ab339 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetsQuickOpen.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetsQuickOpen.js @@ -16,9 +16,7 @@ Snippets.SnippetsQuickOpen = class extends QuickOpen.FilteredListWidget.Provider selectItem(itemIndex, promptValue) { if (itemIndex === null) return; - const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext); - if (currentExecutionContext) - Snippets.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, this._snippets[itemIndex]); + Snippets.evaluateScriptSnippet(this._snippets[itemIndex]); } /** @@ -34,7 +32,7 @@ Snippets.SnippetsQuickOpen = class extends QuickOpen.FilteredListWidget.Provider * @override */ attach() { - this._snippets = Snippets.scriptSnippetModel.project().uiSourceCodes(); + this._snippets = Snippets.project.uiSourceCodes(); } /** @@ -70,7 +68,7 @@ Snippets.SnippetsQuickOpen = class extends QuickOpen.FilteredListWidget.Provider * @param {!Element} subtitleElement */ renderItem(itemIndex, query, titleElement, subtitleElement) { - titleElement.textContent = this._snippets[itemIndex].name(); + titleElement.textContent = unescape(this._snippets[itemIndex].name()); titleElement.classList.add('monospace'); QuickOpen.FilteredListWidget.highlightRanges(titleElement, query, true); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/module.json b/chromium/third_party/blink/renderer/devtools/front_end/snippets/module.json index 79774a6b7fb..a5c80f51009 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/snippets/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/snippets/module.json @@ -7,10 +7,9 @@ "className": "Snippets.SnippetsQuickOpen" } ], - "dependencies": ["bindings", "quick_open"], + "dependencies": ["bindings", "quick_open", "persistence"], "scripts": [ - "SnippetStorage.js", - "ScriptSnippetModel.js", + "ScriptSnippetFileSystem.js", "SnippetsQuickOpen.js" ] } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/source_frame/JSONView.js b/chromium/third_party/blink/renderer/devtools/front_end/source_frame/JSONView.js index e49356679f9..7199d3ece3e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/source_frame/JSONView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/source_frame/JSONView.js @@ -166,7 +166,8 @@ SourceFrame.JSONView = class extends UI.VBox { const obj = SDK.RemoteObject.fromLocalObject(this._parsedJSON.data); const title = this._parsedJSON.prefix + obj.description + this._parsedJSON.suffix; - this._treeOutline = new ObjectUI.ObjectPropertiesSection(obj, title); + this._treeOutline = new ObjectUI.ObjectPropertiesSection( + obj, title, undefined, undefined, undefined, undefined, true /* showOverflow */); this._treeOutline.enableContextMenu(); this._treeOutline.setEditable(false); this._treeOutline.expand(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/CallStackSidebarPane.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/CallStackSidebarPane.js index 0f4a03f1e63..c0285a1c80b 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/CallStackSidebarPane.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/CallStackSidebarPane.js @@ -52,12 +52,14 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { this.contentElement.appendChild(this._showMoreMessageElement); this._showBlackboxed = false; - Bindings.blackboxManager.addChangeListener(this._update.bind(this)); this._locationPool = new Bindings.LiveLocationPool(); this._updateThrottler = new Common.Throttler(100); this._maxAsyncStackChainDepth = Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth; this._update(); + + this._updateItemThrottler = new Common.Throttler(100); + this._scheduledForUpdateItems = new Set(); } /** @@ -93,17 +95,12 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { let debuggerModel = details.debuggerModel; this._notPausedMessageElement.classList.add('hidden'); - const showBlackboxed = this._showBlackboxed || - details.callFrames.every(frame => Bindings.blackboxManager.isBlackboxedRawLocation(frame.location())); - - let hiddenCallFramesCount = 0; - let items = details.callFrames.map(frame => ({debuggerCallFrame: frame, debuggerModel: debuggerModel})); - if (!showBlackboxed) { - items = items.filter( - item => !Bindings.blackboxManager.isBlackboxedRawLocation( - /** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(item)))); - hiddenCallFramesCount += details.callFrames.length - items.length; - } + const items = details.callFrames.map(frame => { + const item = Sources.CallStackSidebarPane.Item.createForDebuggerCallFrame( + frame, this._locationPool, this._refreshItem.bind(this)); + item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol] = frame; + return item; + }); let asyncStackTrace = details.asyncStackTrace; if (!asyncStackTrace && details.asyncStackTraceId) { @@ -124,19 +121,8 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { title = UI.asyncStackTraceLabel(asyncStackTrace.description); } - let asyncItems = - asyncStackTrace.callFrames.map(frame => ({runtimeCallFrame: frame, debuggerModel: debuggerModel})); - if (!showBlackboxed) { - asyncItems = asyncItems.filter( - item => !Bindings.blackboxManager.isBlackboxedRawLocation( - /** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(item)))); - hiddenCallFramesCount += asyncStackTrace.callFrames.length - asyncItems.length; - } - - if (asyncItems.length) { - items.push({asyncStackHeader: title}); - items = items.concat(asyncItems); - } + items.push(...Sources.CallStackSidebarPane.Item.createItemsForAsyncStack( + title, debuggerModel, asyncStackTrace.callFrames, this._locationPool, this._refreshItem.bind(this))); --maxAsyncStackChainDepth; peviousStackTrace = asyncStackTrace.callFrames; @@ -150,24 +136,7 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { asyncStackTrace = null; } } - if (asyncStackTrace) - this._showMoreMessageElement.classList.remove('hidden'); - else - this._showMoreMessageElement.classList.add('hidden'); - - if (!hiddenCallFramesCount) { - this._blackboxedMessageElement.classList.add('hidden'); - } else { - if (hiddenCallFramesCount === 1) { - this._blackboxedMessageElement.firstChild.textContent = - Common.UIString('1 stack frame is hidden (blackboxed).'); - } else { - this._blackboxedMessageElement.firstChild.textContent = - Common.UIString('%d stack frames are hidden (blackboxed).', hiddenCallFramesCount); - } - this._blackboxedMessageElement.classList.remove('hidden'); - } - + this._showMoreMessageElement.classList.toggle('hidden', !asyncStackTrace); this._items.replaceAll(items); if (this._maxAsyncStackChainDepth === Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth) this._list.selectNextItem(true /* canWrap */, false /* center */); @@ -178,6 +147,43 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { } /** + * @param {!Sources.CallStackSidebarPane.Item} item + */ + _refreshItem(item) { + this._scheduledForUpdateItems.add(item); + this._updateItemThrottler.schedule(innerUpdate.bind(this)); + + /** + * @this {!Sources.CallStackSidebarPane} + * @return {!Promise<undefined>} + */ + function innerUpdate() { + const items = Array.from(this._scheduledForUpdateItems); + this._scheduledForUpdateItems.clear(); + + this._muteActivateItem = true; + if (!this._showBlackboxed && this._items.every(item => item.isBlackboxed)) { + this._showBlackboxed = true; + for (let i = 0; i < this._items.length; ++i) + this._list.refreshItemByIndex(i); + this._blackboxedMessageElement.classList.toggle('hidden', true); + } else { + const itemsSet = new Set(items); + let hasBlackboxed = false; + for (let i = 0; i < this._items.length; ++i) { + const item = this._items.at(i); + if (itemsSet.has(item)) + this._list.refreshItemByIndex(i); + hasBlackboxed = hasBlackboxed || item.isBlackboxed; + } + this._blackboxedMessageElement.classList.toggle('hidden', this._showBlackboxed || !hasBlackboxed); + } + delete this._muteActivateItem; + return Promise.resolve(); + } + } + + /** * @override * @param {!Sources.CallStackSidebarPane.Item} item * @return {!Element} @@ -185,31 +191,16 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { createElementForItem(item) { const element = createElementWithClass('div', 'call-frame-item'); const title = element.createChild('div', 'call-frame-item-title'); - title.createChild('div', 'call-frame-title-text').textContent = this._itemTitle(item); - if (item.asyncStackHeader) + title.createChild('div', 'call-frame-title-text').textContent = item.title; + if (item.isAsyncHeader) { element.classList.add('async-header'); - - const location = this._itemLocation(item); - if (location) { - if (Bindings.blackboxManager.isBlackboxedRawLocation(location)) - element.classList.add('blackboxed-call-frame'); - - /** - * @param {!Bindings.LiveLocation} liveLocation - */ - function updateLocation(liveLocation) { - const uiLocation = liveLocation.uiLocation(); - if (!uiLocation) - return; - const text = uiLocation.linkText(); - linkElement.textContent = text.trimMiddle(30); - linkElement.title = text; - } - + } else { const linkElement = element.createChild('div', 'call-frame-location'); - Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, updateLocation, this._locationPool); + linkElement.textContent = item.linkText.trimMiddle(30); + linkElement.title = item.linkText; + element.classList.toggle('blackboxed-call-frame', item.isBlackboxed); } - + element.classList.toggle('hidden', !this._showBlackboxed && item.isBlackboxed); element.appendChild(UI.Icon.create('smallicon-thick-right-arrow', 'selected-call-frame-icon')); return element; } @@ -230,7 +221,7 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { * @return {boolean} */ isItemSelectable(item) { - return !!item.debuggerCallFrame; + return !!item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol]; } /** @@ -250,45 +241,19 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { } /** - * @param {!Sources.CallStackSidebarPane.Item} item - * @return {string} - */ - _itemTitle(item) { - if (item.debuggerCallFrame) - return UI.beautifyFunctionName(item.debuggerCallFrame.functionName); - if (item.runtimeCallFrame) - return UI.beautifyFunctionName(item.runtimeCallFrame.functionName); - return item.asyncStackHeader || ''; - } - - /** - * @param {!Sources.CallStackSidebarPane.Item} item - * @return {?SDK.DebuggerModel.Location} - */ - _itemLocation(item) { - if (item.debuggerCallFrame) - return item.debuggerCallFrame.location(); - if (!item.debuggerModel) - return null; - if (item.runtimeCallFrame) { - const frame = item.runtimeCallFrame; - return new SDK.DebuggerModel.Location(item.debuggerModel, frame.scriptId, frame.lineNumber, frame.columnNumber); - } - return null; - } - - /** * @return {!Element} */ _createBlackboxedMessageElement() { const element = createElementWithClass('div', 'blackboxed-message'); element.createChild('span'); const showAllLink = element.createChild('span', 'link'); - showAllLink.textContent = Common.UIString('Show'); + showAllLink.textContent = Common.UIString('Show blackboxed frames'); showAllLink.addEventListener('click', () => { this._showBlackboxed = true; - this._update(); - }, false); + for (const item of this._items) + this._refreshItem(item); + this._blackboxedMessageElement.classList.toggle('hidden', true); + }); return element; } @@ -315,13 +280,12 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { if (!item) return; const contextMenu = new UI.ContextMenu(event); - if (item.debuggerCallFrame) - contextMenu.defaultSection().appendItem(Common.UIString('Restart frame'), () => item.debuggerCallFrame.restart()); + const debuggerCallFrame = item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol]; + if (debuggerCallFrame) + contextMenu.defaultSection().appendItem(Common.UIString('Restart frame'), () => debuggerCallFrame.restart()); contextMenu.defaultSection().appendItem(Common.UIString('Copy stack trace'), this._copyStackTrace.bind(this)); - const location = this._itemLocation(item); - const uiLocation = location ? Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location) : null; - if (uiLocation) - this.appendBlackboxURLContextMenuItems(contextMenu, uiLocation.uiSourceCode); + if (item.uiLocation) + this.appendBlackboxURLContextMenuItems(contextMenu, item.uiLocation.uiSourceCode); contextMenu.show(); } @@ -338,14 +302,15 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { * @param {!Sources.CallStackSidebarPane.Item} item */ _activateItem(item) { - const location = this._itemLocation(item); - if (!location) + const uiLocation = item.uiLocation; + if (this._muteActivateItem || !uiLocation) return; - if (item.debuggerCallFrame && UI.context.flavor(SDK.DebuggerModel.CallFrame) !== item.debuggerCallFrame) { - item.debuggerModel.setSelectedCallFrame(item.debuggerCallFrame); - UI.context.setFlavor(SDK.DebuggerModel.CallFrame, item.debuggerCallFrame); + const debuggerCallFrame = item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol]; + if (debuggerCallFrame && UI.context.flavor(SDK.DebuggerModel.CallFrame) !== debuggerCallFrame) { + debuggerCallFrame.debuggerModel.setSelectedCallFrame(debuggerCallFrame); + UI.context.setFlavor(SDK.DebuggerModel.CallFrame, debuggerCallFrame); } else { - Common.Revealer.reveal(Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location)); + Common.Revealer.reveal(uiLocation); } } @@ -401,30 +366,20 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { _copyStackTrace() { const text = []; for (const item of this._items) { - let itemText = this._itemTitle(item); - const location = this._itemLocation(item); - const uiLocation = location ? Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location) : null; - if (uiLocation) - itemText += ' (' + uiLocation.linkText(true /* skipTrim */) + ')'; + let itemText = item.title; + if (item.uiLocation) + itemText += ' (' + item.uiLocation.linkText(true /* skipTrim */) + ')'; text.push(itemText); } InspectorFrontendHost.copyText(text.join('\n')); } }; +Sources.CallStackSidebarPane._debuggerCallFrameSymbol = Symbol('debuggerCallFrame'); +Sources.CallStackSidebarPane._elementSymbol = Symbol('element'); Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth = 32; /** - * @typedef {{ - * debuggerCallFrame: (SDK.DebuggerModel.CallFrame|undefined), - * asyncStackHeader: (string|undefined), - * runtimeCallFrame: (Protocol.Runtime.CallFrame|undefined), - * debuggerModel: (!SDK.DebuggerModel|undefined) - * }} - */ -Sources.CallStackSidebarPane.Item; - -/** * @implements {UI.ActionDelegate} */ Sources.CallStackSidebarPane.ActionDelegate = class { @@ -447,3 +402,94 @@ Sources.CallStackSidebarPane.ActionDelegate = class { return false; } }; + +Sources.CallStackSidebarPane.Item = class { + /** + * @param {!SDK.DebuggerModel.CallFrame} frame + * @param {!Bindings.LiveLocationPool} locationPool + * @param {function(!Sources.CallStackSidebarPane.Item)} updateDelegate + * @return {!Sources.CallStackSidebarPane.Item} + */ + static createForDebuggerCallFrame(frame, locationPool, updateDelegate) { + const item = new Sources.CallStackSidebarPane.Item(UI.beautifyFunctionName(frame.functionName), updateDelegate); + Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation( + frame.location(), item._update.bind(item), locationPool); + return item; + } + + /** + * @param {string} title + * @param {?SDK.DebuggerModel} debuggerModel + * @param {!Array<!Protocol.Runtime.CallFrame>} frames + * @param {!Bindings.LiveLocationPool} locationPool + * @param {function(!Sources.CallStackSidebarPane.Item)} updateDelegate + * @return {!Array<!Sources.CallStackSidebarPane.Item>} + */ + static createItemsForAsyncStack(title, debuggerModel, frames, locationPool, updateDelegate) { + const whiteboxedItemsSymbol = Symbol('whiteboxedItems'); + const asyncHeaderItem = new Sources.CallStackSidebarPane.Item(title, updateDelegate); + asyncHeaderItem[whiteboxedItemsSymbol] = new Set(); + asyncHeaderItem.isAsyncHeader = true; + + const asyncFrameItems = frames.map(frame => { + const item = new Sources.CallStackSidebarPane.Item(UI.beautifyFunctionName(frame.functionName), update); + const rawLocation = debuggerModel ? + debuggerModel.createRawLocationByScriptId(frame.scriptId, frame.lineNumber, frame.columnNumber) : + null; + if (!rawLocation) { + item.linkText = (frame.url || '<unknown>') + ':' + (frame.lineNumber + 1); + item.updateDelegate(item); + } else { + Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation( + rawLocation, item._update.bind(item), locationPool); + } + return item; + }); + + updateDelegate(asyncHeaderItem); + return [asyncHeaderItem, ...asyncFrameItems]; + + /** + * @param {!Sources.CallStackSidebarPane.Item} item + */ + function update(item) { + updateDelegate(item); + let shouldUpdate = false; + const items = asyncHeaderItem[whiteboxedItemsSymbol]; + if (item.isBlackboxed) { + items.delete(item); + shouldUpdate = items.size === 0; + } else { + shouldUpdate = items.size === 0; + items.add(item); + } + asyncHeaderItem.isBlackboxed = asyncHeaderItem[whiteboxedItemsSymbol].size === 0; + if (shouldUpdate) + updateDelegate(asyncHeaderItem); + } + } + + /** + * @param {string} title + * @param {function(!Sources.CallStackSidebarPane.Item)} updateDelegate + */ + constructor(title, updateDelegate) { + this.isBlackboxed = false; + this.title = title; + this.linkText = ''; + this.uiLocation = null; + this.isAsyncHeader = false; + this.updateDelegate = updateDelegate; + } + + /** + * @param {!Bindings.LiveLocation} liveLocation + */ + _update(liveLocation) { + const uiLocation = liveLocation.uiLocation(); + this.isBlackboxed = uiLocation ? Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode) : false; + this.linkText = uiLocation ? uiLocation.linkText() : ''; + this.uiLocation = uiLocation; + this.updateDelegate(this); + } +}; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js index 4ad256df3d7..f70671d2d4e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js @@ -108,9 +108,7 @@ Sources.DebuggerPausedMessage = class { messageWrapper = buildWrapper(Common.UIString('Paused before potential out-of-memory crash')); } else if (details.callFrames.length) { const uiLocation = debuggerWorkspaceBinding.rawLocationToUILocation(details.callFrames[0].location()); - const breakpoint = uiLocation ? - breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber) : - null; + const breakpoint = uiLocation ? breakpointManager.findBreakpoint(uiLocation) : null; const defaultText = breakpoint ? Common.UIString('Paused on breakpoint') : Common.UIString('Debugger paused'); messageWrapper = buildWrapper(defaultText); } else { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js index 2e0970490ba..b719c593f7e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js @@ -40,10 +40,6 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin { this._uiSourceCode = uiSourceCode; this._transformer = transformer; - /** @type {?Element} */ - this._conditionEditorElement = null; - /** @type {?Element} */ - this._conditionElement = null; /** @type {?Workspace.UILocation} */ this._executionLocation = null; this._controlDown = false; @@ -120,7 +116,7 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin { this._updateScriptFiles(); - if (this._uiSourceCode.isDirty() && !this._supportsEnabledBreakpointsWhileEditing()) { + if (this._uiSourceCode.isDirty()) { this._muted = true; this._mutedFromStart = true; } else { @@ -334,7 +330,7 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin { } _workingCopyChanged() { - if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFileForDebuggerModel.size) + if (this._scriptFileForDebuggerModel.size) return; if (this._uiSourceCode.isDirty()) @@ -348,22 +344,15 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin { */ _workingCopyCommitted(event) { this._scriptsPanel.updateLastModificationTime(); - if (this._supportsEnabledBreakpointsWhileEditing()) - return; - if (!this._scriptFileForDebuggerModel.size) this._restoreBreakpointsAfterEditing(); } _didMergeToVM() { - if (this._supportsEnabledBreakpointsWhileEditing()) - return; this._restoreBreakpointsIfConsistentScripts(); } _didDivergeFromVM() { - if (this._supportsEnabledBreakpointsWhileEditing()) - return; this._muteBreakpointsWhileEditing(); } @@ -375,10 +364,6 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin { this._muted = true; } - _supportsEnabledBreakpointsWhileEditing() { - return this._uiSourceCode.project().type() === Workspace.projectTypes.Snippets; - } - _restoreBreakpointsIfConsistentScripts() { const scriptFiles = this._scriptFileForDebuggerModel.valuesArray(); for (let i = 0; i < scriptFiles.length; ++i) { @@ -476,6 +461,8 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin { const tokenBefore = this._textEditor.tokenAtTextPosition(editorLineNumber, startHighlight - 2); if (!tokenBefore || !tokenBefore.type) return null; + if (tokenBefore.type === 'js-meta') + break; startHighlight = tokenBefore.startColumn; } } @@ -646,52 +633,64 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin { * @param {?Bindings.BreakpointManager.Breakpoint} breakpoint * @param {?{lineNumber: number, columnNumber: number}} location */ - _editBreakpointCondition(editorLineNumber, breakpoint, location) { - this._conditionElement = this._createConditionElement(editorLineNumber); - this._textEditor.addDecoration(this._conditionElement, editorLineNumber); + async _editBreakpointCondition(editorLineNumber, breakpoint, location) { + const conditionElement = createElementWithClass('div', 'source-frame-breakpoint-condition'); + const labelElement = conditionElement.createChild('label', 'source-frame-breakpoint-message'); + labelElement.htmlFor = 'source-frame-breakpoint-condition'; + labelElement.createTextChild( + Common.UIString('The breakpoint on line %d will stop only if this expression is true:', editorLineNumber + 1)); + + + this._textEditor.addDecoration(conditionElement, editorLineNumber); + + /** @type {!UI.TextEditorFactory} */ + const factory = await self.runtime.extension(UI.TextEditorFactory).instance(); + const editor = + factory.createEditor({lineNumbers: false, lineWrapping: true, mimeType: 'javascript', autoHeight: true}); + editor.widget().show(conditionElement); + if (breakpoint) + editor.setText(breakpoint.condition()); + editor.setSelection(editor.fullRange()); + editor.configureAutocomplete(ObjectUI.JavaScriptAutocompleteConfig.createConfigForEditor(editor)); + editor.widget().element.addEventListener('keydown', async event => { + if (isEnterKey(event) && !event.shiftKey) { + event.consume(true); + const expression = editor.text(); + if (event.ctrlKey || await ObjectUI.JavaScriptAutocomplete.isExpressionComplete(expression)) + finishEditing.call(this, true); + else + editor.newlineAndIndent(); + } + if (isEscKey(event)) + finishEditing.call(this, false); + }, true); + editor.widget().focus(); + editor.widget().element.id = 'source-frame-breakpoint-condition'; + editor.widget().element.addEventListener('blur', event => { + if (event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(editor.widget().element)) + finishEditing.call(this, true); + }, true); + let finished = false; /** * @this {Sources.DebuggerPlugin} */ - function finishEditing(committed, element, newText) { - this._textEditor.removeDecoration(/** @type {!Element} */ (this._conditionElement), editorLineNumber); - this._conditionEditorElement = null; - this._conditionElement = null; + function finishEditing(committed) { + if (finished) + return; + finished = true; + editor.widget().detach(); + this._textEditor.removeDecoration(/** @type {!Element} */ (conditionElement), editorLineNumber); if (!committed) return; if (breakpoint) - breakpoint.setCondition(newText); + breakpoint.setCondition(editor.text().trim()); else if (location) - this._setBreakpoint(location.lineNumber, location.columnNumber, newText, true); + this._setBreakpoint(location.lineNumber, location.columnNumber, editor.text().trim(), true); else - this._createNewBreakpoint(editorLineNumber, newText, true); + this._createNewBreakpoint(editorLineNumber, editor.text().trim(), true); } - - const config = new UI.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false)); - UI.InplaceEditor.startEditing(/** @type {!Element} */ (this._conditionEditorElement), config); - this._conditionEditorElement.value = breakpoint ? breakpoint.condition() : ''; - this._conditionEditorElement.select(); - } - - /** - * @param {number} editorLineNumber - * @return {!Element} - */ - _createConditionElement(editorLineNumber) { - const conditionElement = createElementWithClass('div', 'source-frame-breakpoint-condition'); - - const labelElement = conditionElement.createChild('label', 'source-frame-breakpoint-message'); - labelElement.htmlFor = 'source-frame-breakpoint-condition'; - labelElement.createTextChild( - Common.UIString('The breakpoint on line %d will stop only if this expression is true:', editorLineNumber + 1)); - - const editorElement = UI.createInput('monospace', 'text'); - conditionElement.appendChild(editorElement); - editorElement.id = 'source-frame-breakpoint-condition'; - this._conditionEditorElement = editorElement; - - return conditionElement; } /** @@ -1265,8 +1264,6 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin { const uiLocation = /** @type {!Workspace.UILocation} */ (event.data.uiLocation); if (uiLocation.uiSourceCode !== this._uiSourceCode) return true; - if (this._supportsEnabledBreakpointsWhileEditing()) - return false; if (this._muted) return true; const scriptFiles = this._scriptFileForDebuggerModel.valuesArray(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js index 7d7f1e1b80c..281c34c35c8 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js @@ -25,7 +25,9 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget { * @return {!Promise<?>} */ doUpdate() { - const breakpointLocations = this._breakpointManager.allBreakpointLocations(); + const breakpointLocations = this._breakpointManager.allBreakpointLocations().filter( + breakpointLocation => + breakpointLocation.uiLocation.uiSourceCode.project().type() !== Workspace.projectTypes.Debugger); if (!breakpointLocations.length) { this._listElement = null; this.contentElement.removeChildren(); @@ -80,7 +82,7 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget { const hasEnabled = locations.some(location => location.breakpoint.enabled()); const hasDisabled = locations.some(location => !location.breakpoint.enabled()); promises.push(this._resetEntry(/** @type {!Element}*/ (entry), uiLocation, isSelected, hasEnabled, hasDisabled)); - + entry[Sources.JavaScriptBreakpointsSidebarPane._breakpointLocationsSymbol] = locations; if (isSelected) shouldShowView = true; entry = entry.nextSibling; @@ -94,8 +96,7 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget { UI.viewManager.showView('sources.jsBreakpoints'); this._listElement.classList.toggle( 'breakpoints-list-deactivated', !Common.moduleSetting('breakpointsActive').get()); - Promise.all(promises).then(() => this._didUpdateForTest()); - return Promise.resolve(); + return Promise.all(promises).then(() => this._didUpdateForTest()); } /** @@ -135,24 +136,20 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget { /** * @param {!Event} event - * @return {?Workspace.UILocation} + * @return {!Array<!Bindings.BreakpointManager.BreakpointLocation>} */ - _uiLocationFromEvent(event) { + _breakpointLocations(event) { const node = event.target.enclosingNodeOrSelfWithClass('breakpoint-entry'); if (!node) - return null; - return node[Sources.JavaScriptBreakpointsSidebarPane._locationSymbol] || null; + return []; + return node[Sources.JavaScriptBreakpointsSidebarPane._breakpointLocationsSymbol] || []; } /** * @param {!Event} event */ _breakpointCheckboxClicked(event) { - const uiLocation = this._uiLocationFromEvent(event); - if (!uiLocation) - return; - - const breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourceCode, uiLocation.lineNumber); + const breakpoints = this._breakpointLocations(event).map(breakpointLocation => breakpointLocation.breakpoint); const newState = event.target.checkboxElement.checked; for (const breakpoint of breakpoints) breakpoint.setEnabled(newState); @@ -163,7 +160,12 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget { * @param {!Event} event */ _revealLocation(event) { - const uiLocation = this._uiLocationFromEvent(event); + const uiLocations = this._breakpointLocations(event).map(breakpointLocation => breakpointLocation.uiLocation); + let uiLocation = null; + for (const uiLocationCandidate of uiLocations) { + if (!uiLocation || uiLocationCandidate.columnNumber < uiLocation.columnNumber) + uiLocation = uiLocationCandidate; + } if (uiLocation) Common.Revealer.reveal(uiLocation); } @@ -172,11 +174,7 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget { * @param {!Event} event */ _breakpointContextMenu(event) { - const uiLocation = this._uiLocationFromEvent(event); - if (!uiLocation) - return; - - const breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourceCode, uiLocation.lineNumber); + const breakpoints = this._breakpointLocations(event).map(breakpointLocation => breakpointLocation.breakpoint); const contextMenu = new UI.ContextMenu(event); const removeEntryTitle = breakpoints.length > 1 ? Common.UIString('Remove all breakpoints in line') : @@ -192,25 +190,44 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget { if (breakpoints.some(breakpoint => !breakpoint.enabled())) { const enableTitle = Common.UIString('Enable all breakpoints'); - contextMenu.defaultSection().appendItem( - enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, true)); + contextMenu.defaultSection().appendItem(enableTitle, this._toggleAllBreakpoints.bind(this, true)); } if (breakpoints.some(breakpoint => breakpoint.enabled())) { const disableTitle = Common.UIString('Disable all breakpoints'); - contextMenu.defaultSection().appendItem( - disableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, false)); + contextMenu.defaultSection().appendItem(disableTitle, this._toggleAllBreakpoints.bind(this, false)); } const removeAllTitle = Common.UIString('Remove all breakpoints'); - contextMenu.defaultSection().appendItem( - removeAllTitle, this._breakpointManager.removeAllBreakpoints.bind(this._breakpointManager)); + contextMenu.defaultSection().appendItem(removeAllTitle, this._removeAllBreakpoints.bind(this)); const removeOtherTitle = Common.UIString('Remove other breakpoints'); contextMenu.defaultSection().appendItem( - removeOtherTitle, - this._breakpointManager.removeOtherBreakpoints.bind(this._breakpointManager, new Set(breakpoints))); + removeOtherTitle, this._removeOtherBreakpoints.bind(this, new Set(breakpoints))); contextMenu.show(); } /** + * @param {boolean} toggleState + */ + _toggleAllBreakpoints(toggleState) { + for (const breakpointLocation of this._breakpointManager.allBreakpointLocations()) + breakpointLocation.breakpoint.setEnabled(toggleState); + } + + _removeAllBreakpoints() { + for (const breakpointLocation of this._breakpointManager.allBreakpointLocations()) + breakpointLocation.breakpoint.remove(false /* keepInStorage */); + } + + /** + * @param {!Set<!Bindings.BreakpointManager.Breakpoint>} selectedBreakpoints + */ + _removeOtherBreakpoints(selectedBreakpoints) { + for (const breakpointLocation of this._breakpointManager.allBreakpointLocations()) { + if (!selectedBreakpoints.has(breakpointLocation.breakpoint)) + breakpointLocation.breakpoint.remove(false /* keepInStorage */); + } + } + + /** * @override * @param {?Object} object */ @@ -225,3 +242,4 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget { Sources.JavaScriptBreakpointsSidebarPane._locationSymbol = Symbol('location'); Sources.JavaScriptBreakpointsSidebarPane._checkboxLabelSymbol = Symbol('checkbox-label'); Sources.JavaScriptBreakpointsSidebarPane._snippetElementSymbol = Symbol('snippet-element'); +Sources.JavaScriptBreakpointsSidebarPane._breakpointLocationsSymbol = Symbol('locations'); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptCompilerPlugin.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptCompilerPlugin.js index 575db346563..9e87115e507 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptCompilerPlugin.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptCompilerPlugin.js @@ -31,7 +31,7 @@ Sources.JavaScriptCompilerPlugin = class extends Sources.UISourceCodeFrame.Plugi static accepts(uiSourceCode) { if (uiSourceCode.extension() === 'js') return true; - if (uiSourceCode.project().type() === Workspace.projectTypes.Snippets) + if (Snippets.isSnippetsUISourceCode(uiSourceCode)) return true; for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel)) { if (Bindings.debuggerWorkspaceBinding.scriptFile(uiSourceCode, debuggerModel)) diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js index 959ac9629e3..668372bba1f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js @@ -345,7 +345,7 @@ Sources.NavigatorView = class extends UI.VBox { */ _projectAdded(project) { if (!this.acceptProject(project) || project.type() !== Workspace.projectTypes.FileSystem || - this._rootNode.child(project.id())) + Snippets.isSnippetsProject(project) || this._rootNode.child(project.id())) return; this._rootNode.appendChild(new Sources.NavigatorGroupTreeNode( this, project, project.id(), Sources.NavigatorView.Types.FileSystem, project.displayName())); @@ -418,7 +418,7 @@ Sources.NavigatorView = class extends UI.VBox { * @return {!Sources.NavigatorTreeNode} */ _folderNode(uiSourceCode, project, target, frame, projectOrigin, path, fromSourceMap) { - if (project.type() === Workspace.projectTypes.Snippets) + if (Snippets.isSnippetsUISourceCode(uiSourceCode)) return this._rootNode; if (target && !this._groupByFolder && !fromSourceMap) @@ -586,12 +586,6 @@ Sources.NavigatorView = class extends UI.VBox { /** * @param {!Workspace.UISourceCode} uiSourceCode */ - sourceDeleted(uiSourceCode) { - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - */ _removeUISourceCode(uiSourceCode) { const nodes = this._uiSourceCodeNodes.get(uiSourceCode); for (const node of nodes) @@ -997,7 +991,10 @@ Sources.NavigatorSourceTreeElement = class extends UI.TreeElement { const binding = Persistence.persistence.binding(this._uiSourceCode); if (binding) { const container = createElementWithClass('span', 'icon-stack'); - const icon = UI.Icon.create('largeicon-navigator-file-sync', 'icon'); + let iconType = 'largeicon-navigator-file-sync'; + if (Snippets.isSnippetsUISourceCode(binding.fileSystem)) + iconType = 'largeicon-navigator-snippet'; + const icon = UI.Icon.create(iconType, 'icon'); const badge = UI.Icon.create('badge-navigator-file-sync', 'icon-badge'); // TODO(allada) This does not play well with dark theme. Add an actual icon and use it. if (Persistence.networkPersistenceManager.project() === binding.fileSystem.project()) @@ -1008,7 +1005,7 @@ Sources.NavigatorSourceTreeElement = class extends UI.TreeElement { this.setLeadingIcons([container]); } else { let iconType = 'largeicon-navigator-file'; - if (this._uiSourceCode.contentType() === Common.resourceTypes.Snippet) + if (Snippets.isSnippetsUISourceCode(this._uiSourceCode)) iconType = 'largeicon-navigator-snippet'; const defaultIcon = UI.Icon.create(iconType, 'icon'); this.setLeadingIcons([defaultIcon]); @@ -1106,7 +1103,6 @@ Sources.NavigatorSourceTreeElement = class extends UI.TreeElement { * @return {boolean} */ ondelete() { - this._navigatorView.sourceDeleted(this.uiSourceCode); return true; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/ScriptOriginPlugin.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/ScriptOriginPlugin.js new file mode 100644 index 00000000000..238f2483737 --- /dev/null +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/ScriptOriginPlugin.js @@ -0,0 +1,53 @@ +// Copyright 2018 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. + +Sources.ScriptOriginPlugin = class extends Sources.UISourceCodeFrame.Plugin { + /** + * @param {!SourceFrame.SourcesTextEditor} textEditor + * @param {!Workspace.UISourceCode} uiSourceCode + */ + constructor(textEditor, uiSourceCode) { + super(); + this._textEditor = textEditor; + this._uiSourceCode = uiSourceCode; + } + + /** + * @override + * @param {!Workspace.UISourceCode} uiSourceCode + * @return {boolean} + */ + static accepts(uiSourceCode) { + return !!Sources.ScriptOriginPlugin._script(uiSourceCode); + } + + /** + * @override + * @return {!Array<!UI.ToolbarItem>} + */ + rightToolbarItems() { + const script = Sources.ScriptOriginPlugin._script(this._uiSourceCode); + if (!script || !script.originStackTrace) + return []; + const link = Sources.ScriptOriginPlugin._linkifier.linkifyStackTraceTopFrame( + script.debuggerModel.target(), script.originStackTrace); + return [new UI.ToolbarItem(link)]; + } + + /** + * @param {!Workspace.UISourceCode} uiSourceCode + * @return {?SDK.Script} + */ + static _script(uiSourceCode) { + const locations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, 0, 0); + for (const location of locations) { + const script = location.script(); + if (script.originStackTrace) + return script; + } + return null; + } +}; + +Sources.ScriptOriginPlugin._linkifier = new Components.Linkifier();
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SnippetsPlugin.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SnippetsPlugin.js index 019ab5545ec..c55334719f7 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SnippetsPlugin.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SnippetsPlugin.js @@ -19,7 +19,7 @@ Sources.SnippetsPlugin = class extends Sources.UISourceCodeFrame.Plugin { * @return {boolean} */ static accepts(uiSourceCode) { - return uiSourceCode.project().type() === Workspace.projectTypes.Snippets; + return Snippets.isSnippetsUISourceCode(uiSourceCode); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js index 527fe64ac75..86e202c3860 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js @@ -176,17 +176,18 @@ Sources.SourceFormatter.ScriptMapping = class { * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} columnNumber - * @return {?SDK.DebuggerModel.Location} + * @return {!Array<!SDK.DebuggerModel.Location>} */ - uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) { + uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) { const formatData = Sources.SourceFormatData._for(uiSourceCode); if (!formatData) - return null; + return []; const originalLocation = formatData.mapping.formattedToOriginal(lineNumber, columnNumber); const scripts = this._scriptsForUISourceCode(formatData.originalSourceCode); if (!scripts.length) - return null; - return scripts[0].debuggerModel.createRawLocation(scripts[0], originalLocation[0], originalLocation[1]); + return []; + return scripts.map( + script => script.debuggerModel.createRawLocation(script, originalLocation[0], originalLocation[1])); } /** @@ -223,9 +224,8 @@ Sources.SourceFormatter.ScriptMapping = class { } } if (uiSourceCode.contentType().isScript()) { - const rawLocation = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, 0, 0); - if (rawLocation) - return [rawLocation.script()]; + const rawLocations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, 0, 0); + return rawLocations.map(location => location.script()); } return []; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceMapNamesResolver.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceMapNamesResolver.js index 2990a5efb83..e72955c87dd 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceMapNamesResolver.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceMapNamesResolver.js @@ -228,22 +228,25 @@ Sources.SourceMapNamesResolver.resolveExpression = function( if (!uiSourceCode.contentType().isFromSourceMap()) return Promise.resolve(''); - return Sources.SourceMapNamesResolver._allVariablesInCallFrame(callFrame).then(findCompiledName); + return Sources.SourceMapNamesResolver._allVariablesInCallFrame(callFrame).then( + reverseMapping => findCompiledName(callFrame.debuggerModel, reverseMapping)); /** + * @param {!SDK.DebuggerModel} debuggerModel * @param {!Map<string, string>} reverseMapping * @return {!Promise<string>} */ - function findCompiledName(reverseMapping) { + function findCompiledName(debuggerModel, reverseMapping) { if (reverseMapping.has(originalText)) return Promise.resolve(reverseMapping.get(originalText) || ''); return Sources.SourceMapNamesResolver._resolveExpression( - uiSourceCode, lineNumber, startColumnNumber, endColumnNumber); + debuggerModel, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber); } }; /** + * @param {!SDK.DebuggerModel} debuggerModel * @param {!Workspace.UISourceCode} uiSourceCode * @param {number} lineNumber * @param {number} startColumnNumber @@ -251,9 +254,10 @@ Sources.SourceMapNamesResolver.resolveExpression = function( * @return {!Promise<string>} */ Sources.SourceMapNamesResolver._resolveExpression = function( - uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) { - const rawLocation = - Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, lineNumber, startColumnNumber); + debuggerModel, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) { + const rawLocations = + Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, lineNumber, startColumnNumber); + const rawLocation = rawLocations.find(location => location.debuggerModel === debuggerModel); if (!rawLocation) return Promise.resolve(''); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesNavigator.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesNavigator.js index 70db55da7d5..072c3238073 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesNavigator.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesNavigator.js @@ -96,7 +96,8 @@ Sources.FilesNavigatorView = class extends Sources.NavigatorView { */ acceptProject(project) { return project.type() === Workspace.projectTypes.FileSystem && - Persistence.FileSystemWorkspaceBinding.fileSystemType(project) !== 'overrides'; + Persistence.FileSystemWorkspaceBinding.fileSystemType(project) !== 'overrides' && + !Snippets.isSnippetsProject(project); } /** @@ -208,7 +209,7 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView { super(); const toolbar = new UI.Toolbar('navigator-toolbar'); const newButton = new UI.ToolbarButton('', 'largeicon-add', Common.UIString('New snippet')); - newButton.addEventListener(UI.ToolbarButton.Events.Click, this._handleCreateSnippet.bind(this)); + newButton.addEventListener(UI.ToolbarButton.Events.Click, () => this.create(Snippets.project, '')); toolbar.appendToolbarItem(newButton); this.contentElement.insertBefore(toolbar.element, this.contentElement.firstChild); } @@ -219,7 +220,7 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView { * @return {boolean} */ acceptProject(project) { - return project.type() === Workspace.projectTypes.Snippets; + return Snippets.isSnippetsProject(project); } /** @@ -228,7 +229,7 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView { */ handleContextMenu(event) { const contextMenu = new UI.ContextMenu(event); - contextMenu.headerSection().appendItem(Common.UIString('New'), this._handleCreateSnippet.bind(this)); + contextMenu.headerSection().appendItem(Common.UIString('New'), () => this.create(Snippets.project, '')); contextMenu.show(); } @@ -240,12 +241,10 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView { handleFileContextMenu(event, node) { const uiSourceCode = node.uiSourceCode(); const contextMenu = new UI.ContextMenu(event); - - contextMenu.headerSection().appendItem( - Common.UIString('Run'), this._handleEvaluateSnippet.bind(this, uiSourceCode)); - contextMenu.newSection().appendItem(Common.UIString('New'), this._handleCreateSnippet.bind(this)); - contextMenu.editSection().appendItem(Common.UIString('Rename'), this.rename.bind(this, node)); - contextMenu.editSection().appendItem(Common.UIString('Remove'), this._handleRemoveSnippet.bind(this, uiSourceCode)); + contextMenu.headerSection().appendItem(Common.UIString('Run'), () => Snippets.evaluateScriptSnippet(uiSourceCode)); + contextMenu.editSection().appendItem(Common.UIString('Rename\u2026'), () => this.rename(node, false)); + contextMenu.editSection().appendItem( + Common.UIString('Remove'), () => uiSourceCode.project().deleteFile(uiSourceCode)); contextMenu.saveSection().appendItem(Common.UIString('Save as...'), this._handleSaveAs.bind(this, uiSourceCode)); contextMenu.show(); } @@ -253,45 +252,12 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView { /** * @param {!Workspace.UISourceCode} uiSourceCode */ - _handleEvaluateSnippet(uiSourceCode) { - const executionContext = UI.context.flavor(SDK.ExecutionContext); - if (!executionContext) - return; - Snippets.scriptSnippetModel.evaluateScriptSnippet(executionContext, uiSourceCode); - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - */ async _handleSaveAs(uiSourceCode) { - if (uiSourceCode.project().type() !== Workspace.projectTypes.Snippets) - return; - uiSourceCode.commitWorkingCopy(); const content = await uiSourceCode.requestContent(); Workspace.fileManager.save(uiSourceCode.url(), content, true); Workspace.fileManager.close(uiSourceCode.url()); } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - */ - _handleRemoveSnippet(uiSourceCode) { - if (uiSourceCode.project().type() !== Workspace.projectTypes.Snippets) - return; - uiSourceCode.remove(); - } - - _handleCreateSnippet() { - this.create(Snippets.scriptSnippetModel.project(), ''); - } - - /** - * @override - */ - sourceDeleted(uiSourceCode) { - this._handleRemoveSnippet(uiSourceCode); - } }; /** @@ -307,8 +273,7 @@ Sources.SnippetsNavigatorView.CreatingActionDelegate = class { handleAction(context, actionId) { switch (actionId) { case 'sources.create-snippet': - const uiSourceCode = Snippets.scriptSnippetModel.createScriptSnippet(''); - Common.Revealer.reveal(uiSourceCode); + Snippets.project.createFile('', null, '').then(uiSourceCode => Common.Revealer.reveal(uiSourceCode)); return true; case 'sources.add-folder-to-workspace': Persistence.isolatedFileSystemManager.addFileSystem(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js index 8204f2279b0..bf86dd9075e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js @@ -81,9 +81,10 @@ Sources.SourcesPanel = class extends UI.Panel { if (UI.viewManager.hasViewsForLocation('run-view-sidebar')) { const navigatorSplitWidget = new UI.SplitWidget(false, true, 'sourcePanelNavigatorSidebarSplitViewState'); navigatorSplitWidget.setMainWidget(tabbedPane); - navigatorSplitWidget.setSidebarWidget( - UI.viewManager.createTabbedLocation(this._revealNavigatorSidebar.bind(this), 'run-view-sidebar') - .tabbedPane()); + const runViewTabbedPane = + UI.viewManager.createTabbedLocation(this._revealNavigatorSidebar.bind(this), 'run-view-sidebar').tabbedPane(); + navigatorSplitWidget.setSidebarWidget(runViewTabbedPane); + navigatorSplitWidget.installResizer(runViewTabbedPane.headerElement()); this.editorView.setSidebarWidget(navigatorSplitWidget); } else { this.editorView.setSidebarWidget(tabbedPane); @@ -529,23 +530,11 @@ Sources.SourcesPanel = class extends UI.Panel { Common.moduleSetting('pauseOnExceptionEnabled').set(!this._pauseOnExceptionButton.toggled()); } - /** - * @return {boolean} - */ _runSnippet() { const uiSourceCode = this._sourcesView.currentUISourceCode(); if (!uiSourceCode) - return false; - - const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext); - if (!currentExecutionContext) - return false; - - if (uiSourceCode.project().type() !== Workspace.projectTypes.Snippets) - return false; - - Snippets.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, uiSourceCode); - return true; + return; + Snippets.evaluateScriptSnippet(uiSourceCode); } /** @@ -672,9 +661,10 @@ Sources.SourcesPanel = class extends UI.Panel { if (!executionContext) return; // Always use 0 column. - const rawLocation = - Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, 0); - if (!rawLocation || rawLocation.debuggerModel !== executionContext.debuggerModel) + const rawLocations = + Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiLocation.uiSourceCode, uiLocation.lineNumber, 0); + const rawLocation = rawLocations.find(location => location.debuggerModel === executionContext.debuggerModel); + if (!rawLocation) return; if (!this._prepareToResume()) return; @@ -868,7 +858,7 @@ Sources.SourcesPanel = class extends UI.Panel { const executionContext = /** @type {!SDK.ExecutionContext} */ (currentExecutionContext); let text = /** @type {string} */ (callFunctionResult.object.value); const message = SDK.consoleModel.addCommandMessage(executionContext, text); - text = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text); + text = ObjectUI.JavaScriptREPL.wrapObjectLiteral(text); SDK.consoleModel.evaluateCommandInConsole( executionContext, message, text, /* useCommandLineAPI */ false, /* awaitPromise */ false); @@ -1202,7 +1192,7 @@ Sources.SourcesPanel.DebuggingActionDelegate = class { const executionContext = UI.context.flavor(SDK.ExecutionContext); if (executionContext) { const message = SDK.consoleModel.addCommandMessage(executionContext, text); - text = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text); + text = ObjectUI.JavaScriptREPL.wrapObjectLiteral(text); SDK.consoleModel.evaluateCommandInConsole( executionContext, message, text, /* useCommandLineAPI */ true, /* awaitPromise */ false); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/TabbedEditorContainer.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/TabbedEditorContainer.js index 3c3ba2976f6..caf96b1982f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/TabbedEditorContainer.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/TabbedEditorContainer.js @@ -379,11 +379,10 @@ Sources.TabbedEditorContainer = class extends Common.Object { if (!this._currentFile) return; - const currentProjectType = this._currentFile.project().type(); - const addedProjectType = uiSourceCode.project().type(); - const snippetsProjectType = Workspace.projectTypes.Snippets; - if (this._history.index(this._currentFile.url()) && currentProjectType === snippetsProjectType && - addedProjectType !== snippetsProjectType) + + const currentProjectIsSnippets = Snippets.isSnippetsUISourceCode(this._currentFile); + const addedProjectIsSnippets = Snippets.isSnippetsUISourceCode(uiSourceCode); + if (this._history.index(this._currentFile.url()) && currentProjectIsSnippets && !addedProjectIsSnippets) this._innerShowFile(uiSourceCode, false); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/UISourceCodeFrame.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/UISourceCodeFrame.js index 47de6207236..47cb6bc733e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/UISourceCodeFrame.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/UISourceCodeFrame.js @@ -323,6 +323,8 @@ Sources.UISourceCodeFrame = class extends SourceFrame.SourceFrame { this._plugins.push(new Sources.JavaScriptCompilerPlugin(this.textEditor, pluginUISourceCode)); if (Sources.SnippetsPlugin.accepts(pluginUISourceCode)) this._plugins.push(new Sources.SnippetsPlugin(this.textEditor, pluginUISourceCode)); + if (Sources.ScriptOriginPlugin.accepts(pluginUISourceCode)) + this._plugins.push(new Sources.ScriptOriginPlugin(this.textEditor, pluginUISourceCode)); if (!this.pretty && Runtime.experiments.isEnabled('sourceDiff') && Sources.GutterDiffPlugin.accepts(pluginUISourceCode)) this._plugins.push(new Sources.GutterDiffPlugin(this.textEditor, pluginUISourceCode)); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json b/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json index 2097f804d21..451a843622c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json @@ -863,7 +863,8 @@ "SourcesSearchScope.js", "SourcesPanel.js", "JavaScriptCompilerPlugin.js", - "SnippetsPlugin.js" + "SnippetsPlugin.js", + "ScriptOriginPlugin.js" ], "resources": [ "callStackSidebarPane.css", diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css b/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css index 6b27b3e74c9..42b8ab26914 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css @@ -85,6 +85,7 @@ width: 100%; box-shadow: none !important; outline: none !important; + background: white; } @-webkit-keyframes source-frame-value-update-highlight-animation { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js index b6a62667481..8ea7e66bfd3 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js @@ -299,7 +299,8 @@ SourcesTestRunner.captureStackTraceIntoString = function(callFrames, asyncStackT const location = locationFunction.call(frame); const script = location.script(); const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location); - const isFramework = Bindings.blackboxManager.isBlackboxedRawLocation(location); + const isFramework = + uiLocation ? Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode) : false; if (options.dropFrameworkCallFrames && isFramework) continue; @@ -446,6 +447,14 @@ SourcesTestRunner.waitForScriptSource = function(scriptName, callback) { SourcesTestRunner.waitForScriptSource.bind(SourcesTestRunner, scriptName, callback)); }; +SourcesTestRunner.objectForPopover = function(sourceFrame, lineNumber, columnNumber) { + const debuggerPlugin = SourcesTestRunner.debuggerPlugin(sourceFrame); + const {x, y} = debuggerPlugin._textEditor.cursorPositionToCoordinates(lineNumber, columnNumber); + const promise = TestRunner.addSnifferPromise(ObjectUI.ObjectPopoverHelper, 'buildObjectPopover'); + debuggerPlugin._getPopoverRequest({x, y}).show(new UI.GlassPane()); + return promise; +}; + SourcesTestRunner.setBreakpoint = function(sourceFrame, lineNumber, condition, enabled) { const debuggerPlugin = SourcesTestRunner.debuggerPlugin(sourceFrame); if (!debuggerPlugin._muted) @@ -454,7 +463,11 @@ SourcesTestRunner.setBreakpoint = function(sourceFrame, lineNumber, condition, e SourcesTestRunner.removeBreakpoint = function(sourceFrame, lineNumber) { const debuggerPlugin = SourcesTestRunner.debuggerPlugin(sourceFrame); - debuggerPlugin._breakpointManager.findBreakpoints(sourceFrame._uiSourceCode, lineNumber)[0].remove(); + const breakpointLocations = debuggerPlugin._breakpointManager.allBreakpointLocations(); + const breakpointLocation = breakpointLocations.find( + breakpointLocation => breakpointLocation.uiLocation.uiSourceCode === sourceFrame._uiSourceCode && + breakpointLocation.uiLocation.lineNumber === lineNumber); + breakpointLocation.breakpoint.remove(); }; SourcesTestRunner.createNewBreakpoint = function(sourceFrame, lineNumber, condition, enabled) { @@ -481,8 +494,8 @@ SourcesTestRunner.waitBreakpointSidebarPane = function(waitUntilResolved) { if (!waitUntilResolved) return; - for (const breakpoint of Bindings.breakpointManager._allBreakpoints()) { - if (breakpoint._fakePrimaryLocation && breakpoint.enabled()) + for (const {breakpoint} of Bindings.breakpointManager.allBreakpointLocations()) { + if (breakpoint._uiLocations.size === 0 && breakpoint.enabled()) return SourcesTestRunner.waitBreakpointSidebarPane(); } } @@ -693,8 +706,8 @@ SourcesTestRunner.waitDebuggerPluginBreakpoints = function(sourceFrame) { } function checkIfReady() { - for (const breakpoint of Bindings.breakpointManager._allBreakpoints()) { - if (breakpoint._fakePrimaryLocation && breakpoint.enabled()) + for (const {breakpoint} of Bindings.breakpointManager.allBreakpointLocations()) { + if (breakpoint._uiLocations.size === 0 && breakpoint.enabled()) return waitUpdate().then(checkIfReady); } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js index b2631c68434..034aa81a84d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js @@ -326,6 +326,7 @@ TestRunner.textContentWithoutStyles = function(node) { * @param {!SDK.Target} target */ TestRunner._setupTestHelpers = function(target) { + TestRunner.BrowserAgent = target.browserAgent(); TestRunner.CSSAgent = target.cssAgent(); TestRunner.DeviceOrientationAgent = target.deviceOrientationAgent(); TestRunner.DOMAgent = target.domAgent(); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js index 2b6ef3b892a..601007786a1 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js @@ -74,7 +74,7 @@ TextEditor.CodeMirrorTextEditor = class extends UI.VBox { 'Delete': 'delCharAfter', 'Backspace': 'delCharBefore', 'Tab': 'defaultTab', - 'Shift-Tab': 'indentLess', + 'Shift-Tab': 'indentLessOrPass', 'Enter': 'newlineAndIndent', 'Ctrl-Space': 'autocomplete', 'Esc': 'dismiss', @@ -1326,6 +1326,20 @@ CodeMirror.commands.selectCamelRight = TextEditor.CodeMirrorTextEditor.moveCamel /** * @param {!CodeMirror} codeMirror + * @return {!Object|undefined} + */ +CodeMirror.commands.indentLessOrPass = function(codeMirror) { + const selections = codeMirror.listSelections(); + if (selections.length === 1) { + const range = TextEditor.CodeMirrorUtils.toRange(selections[0].anchor, selections[0].head); + if (range.isEmpty() && !/^\s/.test(codeMirror.getLine(range.startLine))) + return CodeMirror.Pass; + } + codeMirror.execCommand('indentLess'); +}; + +/** + * @param {!CodeMirror} codeMirror */ CodeMirror.commands.gotoMatchingBracket = function(codeMirror) { const updatedSelections = []; @@ -1371,6 +1385,7 @@ CodeMirror.commands.redoAndReveal = function(codemirror) { }; /** + * @param {!CodeMirror} codemirror * @return {!Object|undefined} */ CodeMirror.commands.dismiss = function(codemirror) { @@ -1389,6 +1404,7 @@ CodeMirror.commands.dismiss = function(codemirror) { }; /** + * @param {!CodeMirror} codemirror * @return {!Object|undefined} */ CodeMirror.commands.goSmartPageUp = function(codemirror) { @@ -1398,6 +1414,7 @@ CodeMirror.commands.goSmartPageUp = function(codemirror) { }; /** + * @param {!CodeMirror} codemirror * @return {!Object|undefined} */ CodeMirror.commands.goSmartPageDown = function(codemirror) { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css index f30c3340dbe..6d42b866b0e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css @@ -245,22 +245,22 @@ opacity: 1; } -div.CodeMirror span.CodeMirror-matchingbracket { +div.CodeMirror:focus-within span.CodeMirror-matchingbracket { background-color: rgba(0, 0, 0, 0.07); border-bottom: 1px solid rgba(0, 0, 0, 0.5); } -div.CodeMirror span.CodeMirror-nonmatchingbracket { +div.CodeMirror:focus-within span.CodeMirror-nonmatchingbracket { background-color: rgba(255, 0, 0, 0.07); border-bottom: 1px solid rgba(255, 0, 0, 0.5); } -.-theme-with-dark-background div.CodeMirror span.CodeMirror-matchingbracket { +.-theme-with-dark-background div.CodeMirror:focus-within span.CodeMirror-matchingbracket { border-bottom: 1px solid rgb(217,217,217); background-color:initial; } -.-theme-with-dark-background div.CodeMirror span.CodeMirror-nonmatchingbracket { +.-theme-with-dark-background div.CodeMirror:focus-within span.CodeMirror-nonmatchingbracket { border-bottom: 1px solid rgb(255, 26, 26); background-color:initial; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js index 1cf667ee673..63d73d1426a 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js @@ -13,6 +13,7 @@ Timeline.TimelineController = class { * @param {!Timeline.TimelineController.Client} client */ constructor(target, client) { + this._target = target; this._tracingManager = target.model(SDK.TracingManager); this._performanceModel = new Timeline.PerformanceModel(); this._performanceModel.setMainTarget(target); @@ -34,7 +35,7 @@ Timeline.TimelineController = class { * @return {!SDK.Target} */ mainTarget() { - return this._tracingManager.target(); + return this._target; } /** @@ -93,9 +94,11 @@ Timeline.TimelineController = class { */ async stopRecording() { const tracingStoppedPromises = []; - tracingStoppedPromises.push(new Promise(resolve => this._tracingCompleteCallback = resolve)); + if (this._tracingManager) + tracingStoppedPromises.push(new Promise(resolve => this._tracingCompleteCallback = resolve)); tracingStoppedPromises.push(this._stopProfilingOnAllModels()); - this._tracingManager.stop(); + if (this._tracingManager) + this._tracingManager.stop(); tracingStoppedPromises.push(SDK.targetManager.resumeAllTargets()); this._client.loadingStarted(); @@ -171,14 +174,16 @@ Timeline.TimelineController = class { * @param {boolean=} enableJSSampling * @return {!Promise} */ - _startRecordingWithCategories(categories, enableJSSampling) { + async _startRecordingWithCategories(categories, enableJSSampling) { SDK.targetManager.suspendAllTargets(); - const profilingStartedPromise = enableJSSampling && !Runtime.experiments.isEnabled('timelineTracingJSProfile') ? - this._startProfilingOnAllModels() : - Promise.resolve(); + if (enableJSSampling && !Runtime.experiments.isEnabled('timelineTracingJSProfile')) + await this._startProfilingOnAllModels(); + if (!this._tracingManager) + return; + const samplingFrequencyHz = Common.moduleSetting('highResolutionCpuProfiling').get() ? 10000 : 1000; const options = 'sampling-frequency=' + samplingFrequencyHz; - return profilingStartedPromise.then(() => this._tracingManager.start(this, categories, options)); + return this._tracingManager.start(this, categories, options); } /** @@ -294,6 +299,16 @@ Timeline.TimelineController = class { const pid = mainMetaEvent.thread.process().id(); const mainCpuProfile = this._cpuProfiles.get(this._tracingManager.target().id()); this._injectCpuProfileEvent(pid, mainMetaEvent.thread.id(), mainCpuProfile); + } else { + // Or there was no tracing manager in the main target at all, in this case build the model full + // of cpu profiles. + let tid = 0; + for (const pair of this._cpuProfiles) { + const target = SDK.targetManager.targetById(pair[0]); + const name = target && target.name(); + this._tracingModel.addEvents(TimelineModel.TimelineJSProfileProcessor.buildTraceProfileFromCpuProfile( + pair[1], ++tid, /* injectPageEvent */ tid === 1, name)); + } } } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineLoader.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineLoader.js index fb7920ab0c6..65bf6f98d41 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineLoader.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineLoader.js @@ -221,7 +221,8 @@ Timeline.TimelineLoader = class { let traceEvents; try { const profile = JSON.parse(text); - traceEvents = TimelineModel.TimelineJSProfileProcessor.buildTraceProfileFromCpuProfile(profile); + traceEvents = TimelineModel.TimelineJSProfileProcessor.buildTraceProfileFromCpuProfile( + profile, /* tid */ 1, /* injectPageEvent */ true); } catch (e) { this._reportErrorAndCancelLoading(Common.UIString('Malformed CPU profile format')); return; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js index 628d07051ba..9e7c3642c72 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js @@ -179,10 +179,6 @@ Timeline.TimelineUIUtils = class { eventStyles[recordTypes.LatencyInfo] = new Timeline.TimelineRecordStyle(Common.UIString('Input Latency'), categories['scripting']); - eventStyles[recordTypes.GCIdleLazySweep] = - new Timeline.TimelineRecordStyle(Common.UIString('DOM GC'), categories['scripting']); - eventStyles[recordTypes.GCCompleteSweep] = - new Timeline.TimelineRecordStyle(Common.UIString('DOM GC'), categories['scripting']); eventStyles[recordTypes.GCCollectGarbage] = new Timeline.TimelineRecordStyle(Common.UIString('DOM GC'), categories['scripting']); @@ -604,18 +600,6 @@ Timeline.TimelineUIUtils = class { detailsText = eventData && eventData['name']; break; - case recordType.GCIdleLazySweep: - detailsText = Common.UIString('idle sweep'); - break; - - case recordType.GCCompleteSweep: - detailsText = Common.UIString('complete sweep'); - break; - - case recordType.GCCollectGarbage: - detailsText = Common.UIString('collect'); - break; - case recordType.AsyncTask: detailsText = eventData ? eventData['name'] : null; break; @@ -688,9 +672,6 @@ Timeline.TimelineUIUtils = class { case recordType.WebSocketSendHandshakeRequest: case recordType.WebSocketReceiveHandshakeResponse: case recordType.WebSocketDestroy: - case recordType.GCIdleLazySweep: - case recordType.GCCompleteSweep: - case recordType.GCCollectGarbage: detailsText = Timeline.TimelineUIUtils.buildDetailsTextForTraceEvent(event, target); break; case recordType.PaintImage: @@ -785,7 +766,7 @@ Timeline.TimelineUIUtils = class { let previewElement = null; const url = TimelineModel.TimelineData.forEvent(event).url; if (url) - previewElement = await BrowserComponents.ImagePreview.build(target, url, false); + previewElement = await Components.ImagePreview.build(target, url, false); else if (TimelineModel.TimelineData.forEvent(event).picture) previewElement = await Timeline.TimelineUIUtils.buildPicturePreviewContent(event, target); event[Timeline.TimelineUIUtils._previewElementSymbol] = previewElement; @@ -1076,36 +1057,38 @@ Timeline.TimelineUIUtils = class { static statsForTimeRange(events, startTime, endTime) { if (!events.length) return {'idle': endTime - startTime}; - const symbol = Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol; - Timeline.TimelineUIUtils._buildRangeStatsCacheIfNeeded(events); - - const before = findCachedStatsAfterTime(startTime); - const statsBefore = - subtractStats(before.stats, Timeline.TimelineUIUtils._slowStatsForTimeRange(events, startTime, before.time)); - - const after = findCachedStatsAfterTime(endTime); - const statsAfter = - subtractStats(after.stats, Timeline.TimelineUIUtils._slowStatsForTimeRange(events, endTime, after.time)); - const aggregatedStats = subtractStats(statsAfter, statsBefore); + buildRangeStatsCacheIfNeeded(events); + const aggregatedStats = subtractStats(aggregatedStatsAtTime(endTime), aggregatedStatsAtTime(startTime)); const aggregatedTotal = Object.values(aggregatedStats).reduce((a, b) => a + b, 0); aggregatedStats['idle'] = Math.max(0, endTime - startTime - aggregatedTotal); return aggregatedStats; /** - * @param {number} atTime - * @return {!{time: number, stats: !Object<string, number>}} + * @param {number} time + * @return {!Object} */ - function findCachedStatsAfterTime(atTime) { - let index = events.lowerBound(atTime, (time, event) => time - (event.endTime || event.startTime)); - while (index < events.length && !events[index][symbol]) - index++; - if (index === events.length) { - const lastEvent = events.peekLast(); - return {time: lastEvent.endTime || lastEvent.startTime, stats: events[symbol]}; + function aggregatedStatsAtTime(time) { + const stats = {}; + const cache = events[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol]; + for (const category in cache) { + const categoryCache = cache[category]; + const index = categoryCache.time.upperBound(time); + let value; + if (index === 0) { + value = 0; + } else if (index === categoryCache.time.length) { + value = categoryCache.value.peekLast(); + } else { + const t0 = categoryCache.time[index - 1]; + const t1 = categoryCache.time[index]; + const v0 = categoryCache.value[index - 1]; + const v1 = categoryCache.value[index]; + value = v0 + (v1 - v0) * (time - t0) / (t1 - t0); + } + stats[category] = value; } - const event = events[index]; - return {time: event.endTime || event.startTime, stats: event[symbol]}; + return stats; } /** @@ -1119,82 +1102,84 @@ Timeline.TimelineUIUtils = class { result[key] -= b[key]; return result; } - } - - /** - * @param {!Array<!SDK.TracingModel.Event>} events - * @param {number} startTime - * @param {number} endTime - */ - static _slowStatsForTimeRange(events, startTime, endTime) { - /** @type {!Object<string, number>} */ - const stats = {}; - const ownTimes = []; - - TimelineModel.TimelineModel.forEachEvent( - events, onStartEvent, onEndEvent, undefined, startTime, endTime, Timeline.TimelineUIUtils._filterForStats()); /** - * @param {!SDK.TracingModel.Event} e + * @param {!Array<!SDK.TracingModel.Event>} events */ - function onStartEvent(e) { - const duration = Math.min(e.endTime, endTime) - Math.max(e.startTime, startTime); - if (ownTimes.length) - ownTimes[ownTimes.length - 1] -= duration; - ownTimes.push(duration); - } + function buildRangeStatsCacheIfNeeded(events) { + if (events[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol]) + return; - /** - * @param {!SDK.TracingModel.Event} e - */ - function onEndEvent(e) { - const category = Timeline.TimelineUIUtils.eventStyle(e).category.name; - stats[category] = (stats[category] || 0) + ownTimes.pop(); - } - return stats; - } + // aggeregatedStats is a map by categories. For each category there's an array + // containing sorted time points which records accumulated value of the category. + const aggregatedStats = {}; + const categoryStack = []; + let lastTime = 0; + TimelineModel.TimelineModel.forEachEvent( + events, onStartEvent, onEndEvent, undefined, undefined, undefined, filterForStats()); + + /** + * @return {function(!SDK.TracingModel.Event):boolean} + */ + function filterForStats() { + const visibleEventsFilter = Timeline.TimelineUIUtils.visibleEventsFilter(); + return event => visibleEventsFilter.accept(event) || SDK.TracingModel.isTopLevelEvent(event); + } - /** - * @return {function(!SDK.TracingModel.Event):boolean} - */ - static _filterForStats() { - const visibleEventsFilter = Timeline.TimelineUIUtils.visibleEventsFilter(); - return event => visibleEventsFilter.accept(event) || SDK.TracingModel.isTopLevelEvent(event); - } + /** + * @param {string} category + * @param {number} time + */ + function updateCategory(category, time) { + let statsArrays = aggregatedStats[category]; + if (!statsArrays) { + statsArrays = {time: [], value: []}; + aggregatedStats[category] = statsArrays; + } + if (statsArrays.time.length && statsArrays.time.peekLast() === time) + return; + const lastValue = statsArrays.value.length ? statsArrays.value.peekLast() : 0; + statsArrays.value.push(lastValue + time - lastTime); + statsArrays.time.push(time); + } - /** - * @param {!Array<!SDK.TracingModel.Event>} events - */ - static _buildRangeStatsCacheIfNeeded(events) { - if (events[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol]) - return; + /** + * @param {?string} from + * @param {?string} to + * @param {number} time + */ + function categoryChange(from, to, time) { + if (from) + updateCategory(from, time); + lastTime = time; + if (to) + updateCategory(to, time); + } - const aggregatedStats = {}; - const ownTimes = []; - TimelineModel.TimelineModel.forEachEvent( - events, onStartEvent, onEndEvent, undefined, undefined, undefined, Timeline.TimelineUIUtils._filterForStats()); + /** + * @param {!SDK.TracingModel.Event} e + */ + function onStartEvent(e) { + const category = Timeline.TimelineUIUtils.eventStyle(e).category.name; + const parentCategory = categoryStack.length ? categoryStack.peekLast() : null; + if (category !== parentCategory) + categoryChange(parentCategory, category, e.startTime); + categoryStack.push(category); + } - /** - * @param {!SDK.TracingModel.Event} e - */ - function onStartEvent(e) { - if (ownTimes.length) - ownTimes[ownTimes.length - 1] -= e.duration; - ownTimes.push(e.duration); - } + /** + * @param {!SDK.TracingModel.Event} e + */ + function onEndEvent(e) { + const category = categoryStack.pop(); + const parentCategory = categoryStack.length ? categoryStack.peekLast() : null; + if (category !== parentCategory) + categoryChange(category, parentCategory, e.endTime); + } - /** - * @param {!SDK.TracingModel.Event} e - */ - function onEndEvent(e) { - const category = Timeline.TimelineUIUtils.eventStyle(e).category.name; - aggregatedStats[category] = (aggregatedStats[category] || 0) + ownTimes.pop(); - if (!ownTimes.length) - e[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol] = Object.assign({}, aggregatedStats); + const obj = /** @type {!Object} */ (events); + obj[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol] = aggregatedStats; } - - const obj = /** @type {!Object} */ (events); - obj[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol] = Object.assign({}, aggregatedStats); } /** @@ -1256,7 +1241,7 @@ Timeline.TimelineUIUtils = class { } if (!request.previewElement && request.url && target) - request.previewElement = await BrowserComponents.ImagePreview.build(target, request.url, false); + request.previewElement = await Components.ImagePreview.build(target, request.url, false); if (request.previewElement) contentHelper.appendElementRow(Common.UIString('Preview'), request.previewElement); return contentHelper.fragment; @@ -1496,7 +1481,7 @@ Timeline.TimelineUIUtils = class { if (!imageURL) return null; const container = createElement('div'); - UI.appendStyle(container, 'browser_components/imagePreview.css'); + UI.appendStyle(container, 'components/imagePreview.css'); container.classList.add('image-preview-container', 'vbox', 'link'); const img = container.createChild('img'); img.src = imageURL; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/module.json b/chromium/third_party/blink/renderer/devtools/front_end/timeline/module.json index 75f4094f494..f175531a90f 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/module.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/module.json @@ -218,7 +218,7 @@ } ], "dependencies": [ - "browser_components", + "components", "layer_viewer", "timeline_model", "perf_ui", diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineJSProfile.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineJSProfile.js index d544dd72ede..df66bb983d8 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineJSProfile.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineJSProfile.js @@ -227,13 +227,20 @@ TimelineModel.TimelineJSProfileProcessor = class { /** * @param {*} profile + * @param {number} tid + * @param {boolean} injectPageEvent + * @param {?string=} name * @return {!Array<!SDK.TracingManager.EventPayload>} */ - static buildTraceProfileFromCpuProfile(profile) { - if (!profile) - return []; + static buildTraceProfileFromCpuProfile(profile, tid, injectPageEvent, name) { const events = []; - appendEvent('TracingStartedInPage', {'sessionId': '1'}, 0, 0, 'M'); + if (injectPageEvent) + appendEvent('TracingStartedInPage', {data: {'sessionId': '1'}}, 0, 0, 'M'); + if (!name) + name = ls`Thread ${tid}`; + appendEvent(SDK.TracingModel.MetadataEvent.ThreadName, {name}, 0, 0, 'M', '__metadata'); + if (!profile) + return events; const idToNode = new Map(); const nodes = profile['nodes']; for (let i = 0; i < nodes.length; ++i) @@ -263,11 +270,11 @@ TimelineModel.TimelineJSProfileProcessor = class { } else { // A JS function. if (!functionEvent) - functionEvent = appendEvent('FunctionCall', {'sessionId': '1'}, currentTime); + functionEvent = appendEvent('FunctionCall', {data: {'sessionId': '1'}}, currentTime); } } closeEvents(); - appendEvent('CpuProfile', {'cpuProfile': profile}, profile.endTime, 0, 'I'); + appendEvent('CpuProfile', {data: {'cpuProfile': profile}}, profile.endTime, 0, 'I'); return events; function closeEvents() { @@ -281,23 +288,16 @@ TimelineModel.TimelineJSProfileProcessor = class { /** * @param {string} name - * @param {*} data + * @param {*} args * @param {number} ts * @param {number=} dur * @param {string=} ph * @param {string=} cat * @return {!SDK.TracingManager.EventPayload} */ - function appendEvent(name, data, ts, dur, ph, cat) { - const event = /** @type {!SDK.TracingManager.EventPayload} */ ({ - cat: cat || 'disabled-by-default-devtools.timeline', - name: name, - ph: ph || 'X', - pid: 1, - tid: 1, - ts: ts, - args: {data: data} - }); + function appendEvent(name, args, ts, dur, ph, cat) { + const event = /** @type {!SDK.TracingManager.EventPayload} */ ( + {cat: cat || 'disabled-by-default-devtools.timeline', name, ph: ph || 'X', pid: 1, tid, ts, args}); if (dur) event.dur = dur; events.push(event); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js index d5a6910fb15..332ace621d7 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js @@ -180,8 +180,9 @@ TimelineModel.TimelineModel = class { * @param {!SDK.TracingModel} tracingModel */ _processGenericTrace(tracingModel) { - const browserMainThread = - SDK.TracingModel.browserMainThread(tracingModel) || tracingModel.sortedProcesses()[0].sortedThreads()[0]; + let browserMainThread = SDK.TracingModel.browserMainThread(tracingModel); + if (!browserMainThread && tracingModel.sortedProcesses().length) + browserMainThread = tracingModel.sortedProcesses()[0].sortedThreads()[0]; for (const process of tracingModel.sortedProcesses()) { for (const thread of process.sortedThreads()) { this._processThreadEvents( @@ -200,6 +201,8 @@ TimelineModel.TimelineModel = class { const metaEvent = metadataEvents.page[i]; const process = metaEvent.thread.process(); const endTime = i + 1 < length ? metadataEvents.page[i + 1].startTime : Infinity; + if (startTime === endTime) + continue; this._legacyCurrentPage = metaEvent.args['data'] && metaEvent.args['data']['page']; for (const thread of process.sortedThreads()) { let workerUrl = null; @@ -1274,9 +1277,7 @@ TimelineModel.TimelineModel.RecordType = { InputLatencyMouseMove: 'InputLatency::MouseMove', InputLatencyMouseWheel: 'InputLatency::MouseWheel', ImplSideFling: 'InputHandlerProxy::HandleGestureFling::started', - GCIdleLazySweep: 'ThreadState::performIdleLazySweep', - GCCompleteSweep: 'ThreadState::completeSweep', - GCCollectGarbage: 'BlinkGCMarking', + GCCollectGarbage: 'BlinkGC.AtomicPhase', CryptoDoEncrypt: 'DoEncrypt', CryptoDoEncryptReply: 'DoEncryptReply', diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js index 7cf6d2f0333..376b50d328e 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js @@ -56,6 +56,20 @@ UI.ARIAUtils.markAsTextBox = function(element) { /** * @param {!Element} element */ +UI.ARIAUtils.markAsMenu = function(element) { + element.setAttribute('role', 'menu'); +}; + +/** + * @param {!Element} element + */ +UI.ARIAUtils.markAsMenuItem = function(element) { + element.setAttribute('role', 'menuitem'); +}; + +/** + * @param {!Element} element + */ UI.ARIAUtils.markAsHidden = function(element) { element.setAttribute('aria-hidden', 'true'); }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js index ac09596a632..2a4f6ed8a35 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js @@ -284,16 +284,6 @@ UI.InspectorView = class extends UI.VBox { } } } - - if (event.key === '[') { - this._tabbedPane.selectPrevTab(); - event.consume(true); - } - - if (event.key === ']') { - this._tabbedPane.selectNextTab(); - event.consume(true); - } } /** @@ -358,7 +348,7 @@ UI.inspectorView; * @implements {UI.ActionDelegate} * @unrestricted */ -UI.InspectorView.DrawerToggleActionDelegate = class { +UI.InspectorView.ActionDelegate = class { /** * @override * @param {!UI.Context} context @@ -366,10 +356,20 @@ UI.InspectorView.DrawerToggleActionDelegate = class { * @return {boolean} */ handleAction(context, actionId) { - if (UI.inspectorView.drawerVisible()) - UI.inspectorView._closeDrawer(); - else - UI.inspectorView._showDrawer(true); - return true; + switch (actionId) { + case 'main.toggle-drawer': + if (UI.inspectorView.drawerVisible()) + UI.inspectorView._closeDrawer(); + else + UI.inspectorView._showDrawer(true); + return true; + case 'main.next-tab': + UI.inspectorView._tabbedPane.selectNextTab(); + return true; + case 'main.previous-tab': + UI.inspectorView._tabbedPane.selectPrevTab(); + return true; + } + return false; } }; diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/ListControl.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/ListControl.js index 56f19464826..f30619c0739 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/ListControl.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/ListControl.js @@ -136,6 +136,14 @@ UI.ListControl = class { console.error('Item to refresh is not present'); return; } + this.refreshItemByIndex(index); + } + + /** + * @param {number} index + */ + refreshItemByIndex(index) { + const item = this._model.at(index); this._itemToElement.delete(item); this.invalidateRange(index, index + 1); if (this._selectedIndex !== -1) diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js index 6b72862fccf..0178835dbff 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js @@ -35,6 +35,20 @@ UI.ShortcutRegistry = class { } /** + * @return {!Array<number>} + */ + globalShortcutKeys() { + const keys = []; + for (const key of this._defaultKeyToActions.keysArray()) { + const actions = this._defaultKeyToActions.get(key).valuesArray(); + const applicableActions = this._actionRegistry.applicableActions(actions, new UI.Context()); + if (applicableActions.length) + keys.push(Number(key)); + } + return keys; + } + + /** * @param {string} actionId * @return {!Array.<!UI.KeyboardShortcut.Descriptor>} */ diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/SoftContextMenu.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/SoftContextMenu.js index 79304c3b102..aff0106c20b 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/SoftContextMenu.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/SoftContextMenu.js @@ -36,6 +36,8 @@ UI.SoftContextMenu = class { this._items = items; this._itemSelectedCallback = itemSelectedCallback; this._parentMenu = parentMenu; + /** @type {?Element} */ + this._highlightedMenuItemElement = null; } /** @@ -60,7 +62,8 @@ UI.SoftContextMenu = class { this._parentMenu ? UI.GlassPane.AnchorBehavior.PreferRight : UI.GlassPane.AnchorBehavior.PreferBottom); this._contextMenuElement = this._glassPane.contentElement.createChild('div', 'soft-context-menu'); - this._contextMenuElement.tabIndex = 0; + this._contextMenuElement.tabIndex = -1; + UI.ARIAUtils.markAsMenu(this._contextMenuElement); this._contextMenuElement.addEventListener('mouseup', e => e.consume(), false); this._contextMenuElement.addEventListener('keydown', this._menuKeyDown.bind(this), false); @@ -106,6 +109,8 @@ UI.SoftContextMenu = class { return this._createSubMenu(item); const menuItemElement = createElementWithClass('div', 'soft-context-menu-item'); + menuItemElement.tabIndex = -1; + UI.ARIAUtils.markAsMenuItem(menuItemElement); const checkMarkElement = UI.Icon.create('smallicon-checkmark', 'checkmark'); menuItemElement.appendChild(checkMarkElement); if (!item.checked) @@ -131,12 +136,22 @@ UI.SoftContextMenu = class { menuItemElement.addEventListener('mouseleave', this._menuItemMouseLeave.bind(this), false); menuItemElement._actionId = item.id; + + let accessibleName = item.label; + if (item.checked) + accessibleName += ', checked'; + if (item.shortcut) + accessibleName += ', ' + item.shortcut; + UI.ARIAUtils.setAccessibleName(menuItemElement, accessibleName); + return menuItemElement; } _createSubMenu(item) { const menuItemElement = createElementWithClass('div', 'soft-context-menu-item'); menuItemElement._subItems = item.subItems; + menuItemElement.tabIndex = -1; + UI.ARIAUtils.markAsMenuItem(menuItemElement); // Occupy the same space on the left in all items. const checkMarkElement = UI.Icon.create('smallicon-checkmark', 'soft-context-menu-item-checkmark'); @@ -146,8 +161,13 @@ UI.SoftContextMenu = class { menuItemElement.createTextChild(item.label); - const subMenuArrowElement = menuItemElement.createChild('span', 'soft-context-menu-item-submenu-arrow'); - subMenuArrowElement.textContent = '\u25B6'; // BLACK RIGHT-POINTING TRIANGLE + if (Host.isMac() && !UI.themeSupport.hasTheme()) { + const subMenuArrowElement = menuItemElement.createChild('span', 'soft-context-menu-item-submenu-arrow'); + subMenuArrowElement.textContent = '\u25B6'; // BLACK RIGHT-POINTING TRIANGLE + } else { + const subMenuArrowElement = UI.Icon.create('smallicon-triangle-right', 'soft-context-menu-item-submenu-arrow'); + menuItemElement.appendChild(subMenuArrowElement); + } menuItemElement.addEventListener('mousedown', this._menuItemMouseDown.bind(this), false); menuItemElement.addEventListener('mouseup', this._menuItemMouseUp.bind(this), false); @@ -254,9 +274,10 @@ UI.SoftContextMenu = class { } this._highlightedMenuItemElement = menuItemElement; if (this._highlightedMenuItemElement) { - this._highlightedMenuItemElement.classList.add('force-white-icons'); + if (UI.themeSupport.hasTheme() || Host.isMac()) + this._highlightedMenuItemElement.classList.add('force-white-icons'); this._highlightedMenuItemElement.classList.add('soft-context-menu-item-mouse-over'); - this._contextMenuElement.focus(); + this._highlightedMenuItemElement.focus(); if (scheduleSubMenu && this._highlightedMenuItemElement._subItems && !this._highlightedMenuItemElement._subMenuTimer) { this._highlightedMenuItemElement._subMenuTimer = @@ -268,7 +289,9 @@ UI.SoftContextMenu = class { _highlightPrevious() { let menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling : this._contextMenuElement.lastChild; - while (menuItemElement && (menuItemElement._isSeparator || menuItemElement._isCustom)) + while (menuItemElement && + (menuItemElement._isSeparator || menuItemElement._isCustom || + menuItemElement.classList.contains('soft-context-menu-disabled'))) menuItemElement = menuItemElement.previousSibling; if (menuItemElement) this._highlightMenuItem(menuItemElement, false); @@ -277,7 +300,9 @@ UI.SoftContextMenu = class { _highlightNext() { let menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling : this._contextMenuElement.firstChild; - while (menuItemElement && (menuItemElement._isSeparator || menuItemElement._isCustom)) + while (menuItemElement && + (menuItemElement._isSeparator || menuItemElement._isCustom || + menuItemElement.classList.contains('soft-context-menu-disabled'))) menuItemElement = menuItemElement.nextSibling; if (menuItemElement) this._highlightMenuItem(menuItemElement, false); diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/TabbedPane.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/TabbedPane.js index 44db82d8534..b1d9560bc79 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/TabbedPane.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/TabbedPane.js @@ -560,6 +560,8 @@ UI.TabbedPane = class extends UI.VBox { _createDropDownButton() { const dropDownContainer = createElementWithClass('div', 'tabbed-pane-header-tabs-drop-down-container'); const chevronIcon = UI.Icon.create('largeicon-chevron', 'chevron-icon'); + UI.ARIAUtils.markAsButton(dropDownContainer); + UI.ARIAUtils.setAccessibleName(dropDownContainer, ls`More tabs`); dropDownContainer.appendChild(chevronIcon); dropDownContainer.addEventListener('click', this._dropDownClicked.bind(this)); dropDownContainer.addEventListener('mousedown', event => { diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css b/chromium/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css index 2e7fa6ecce4..824db97feb5 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css @@ -137,9 +137,8 @@ iframe.widget { .highlighted-search-result { border-radius: 1px; - padding: 1px; - margin: -1px; background-color: rgba(255, 255, 0, 0.8); + outline: 1px solid rgba(255, 255, 0, 0.8); } .-theme-with-dark-background .highlighted-search-result, diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css b/chromium/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css index e159a13f0d3..ced1f40738d 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css @@ -5,19 +5,32 @@ */ .soft-context-menu { - border: 1px solid rgba(196, 196, 196, 0.9); - border-top: 1px solid rgba(196, 196, 196, 0.5); + overflow-y: auto; + min-width: 160px !important; /* NOTE: Keep padding in sync with padding adjustment in SoftContextMenu.js */ padding: 4px 0 4px 0; + border: 1px solid #b9b9b9; + background-color: #FFF; + box-shadow: var(--drop-shadow); + --context-menu-hover-bg: #ebebeb; + --context-menu-hover-color: #222; + --context-menu-seperator-color: var(--divider-color); +} + +:host:host-context(.platform-mac):host-context(html:not(.-theme-with-dark-background)) .soft-context-menu { + border: 1px solid rgba(196, 196, 196, 0.9); + border-top: 1px solid rgba(196, 196, 196, 0.5); border-radius: 4px; background-color: rgb(240, 240, 240); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25); - overflow-y: auto; - min-width: 160px !important; + --context-menu-hover-color: #FFF; + --context-menu-seperator-color: rgb(222, 222, 222); } :host-context(.-theme-with-dark-background) .soft-context-menu { - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25); + --context-menu-hover-bg: var(--selection-bg-color); + --context-menu-hover-color: var(--selection-fg-color); + border: none; } .soft-context-menu-item { @@ -45,33 +58,34 @@ .soft-context-menu-separator > .separator-line { margin: 0; height: 5px; - border-bottom: 1px solid rgb(222, 222, 222); + border-bottom: 1px solid var(--context-menu-seperator-color); pointer-events: none; } .soft-context-menu-item-mouse-over, .-theme-selection-color { - border-top: 1px solid var(--selection-bg-color); - border-bottom: 1px solid var(--selection-bg-color); - background-color: var(--selection-bg-color); - color: white; + border-top: 1px solid var(--context-menu-hover-bg); + border-bottom: 1px solid var(--context-menu-hover-bg); + background-color: var(--context-menu-hover-bg); + color: var(--context-menu-hover-color); } -:host-context(.platform-mac) .soft-context-menu-item-mouse-over, -theme-preserve { +:host:host-context(.platform-mac):host-context(html:not(.-theme-with-dark-background)) .soft-context-menu-item-mouse-over { border-top: 1px solid transparent; border-bottom: 1px solid transparent; background-image: linear-gradient(to right, hsl(214, 81%, 60%), hsl(214, 100%, 56%)); } -:host-context(.platform-mac) .separator-line { +:host:host-context(.platform-mac):host-context(html:not(.-theme-with-dark-background)) .separator-line { border-width: 2px; } .soft-context-menu-item-submenu-arrow { pointer-events: none; font-size: 11px; - flex: 1 1 auto; text-align: right; + align-self: center; + margin-left: auto; } .soft-context-menu-item-mouse-over .soft-context-menu-item-checkmark { @@ -103,6 +117,11 @@ margin: auto 5px auto 0px; } +:host-context(.-theme-with-dark-background) .checkmark { + filter: invert(80%); +} + .soft-context-menu-item-mouse-over .checkmark { opacity: 1; + filter: none; } diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css index 59abb4602d2..b83ae08c0b7 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css @@ -21,7 +21,7 @@ position: relative; } -.tree-outline li.hovered:not(.selected) .selection { +.tree-outline:not(.hide-selection-when-blurred) li.hovered:not(.selected) .selection { display: block; left: 3px; right: 3px; @@ -35,27 +35,27 @@ margin-left: -10000px; } -.tree-outline li.selected .selection { +.tree-outline:not(.hide-selection-when-blurred) li.selected .selection { display: block; background-color: var(--selection-inactive-bg-color); } -.tree-outline li.in-clipboard .highlight { +.tree-outline:not(.hide-selection-when-blurred) li.in-clipboard .highlight { outline: 1px dotted darkgrey; } -.tree-outline li.elements-drag-over .selection { +.tree-outline:not(.hide-selection-when-blurred) li.elements-drag-over .selection { display: block; margin-top: -2px; border-top: 2px solid; border-top-color: var(--selection-bg-color); } -ol.tree-outline li.selected:focus .selection { +ol.tree-outline:not(.hide-selection-when-blurred) li.selected:focus .selection { background-color: var(--selection-bg-color); } -ol.tree-outline li.parent.selected:focus::before { +ol.tree-outline:not(.hide-selection-when-blurred) li.parent.selected:focus::before { background-color: var(--selection-fg-color); } @@ -81,11 +81,11 @@ ol.tree-outline, min-height: 16px; } -ol.tree-outline li.selected:focus { +ol.tree-outline:not(.hide-selection-when-blurred) li.selected:focus { color: var(--selection-fg-color); } -ol.tree-outline li.selected:focus * { +ol.tree-outline:not(.hide-selection-when-blurred) li.selected:focus * { color: inherit; } @@ -107,11 +107,11 @@ ol.tree-outline li.selected:focus * { -webkit-user-select: none; -webkit-mask-image: url(Images/treeoutlineTriangles.png); -webkit-mask-size: 32px 24px; - content: "aa"; - color: transparent; + content: "\00a0\00a0"; text-shadow: none; margin-right: -2px; height: 12px; + width: 13px; } .tree-outline li:not(.parent)::before { @@ -157,3 +157,13 @@ ol.tree-outline li.selected:focus * { .tree-outline.tree-outline-dense ol { padding-left: 10px; } + +.tree-outline.hide-selection-when-blurred .selected:focus[data-keyboard-focus="true"] { + background: rgba(0, 0, 0, 0.08); + border-radius: 2px; +} + +.tree-outline-disclosure:not(.tree-outline-disclosure-hide-overflow) .tree-outline.hide-selection-when-blurred .selected:focus[data-keyboard-focus="true"] { + width: fit-content; + padding-right: 3px; +} diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js index 20a000dcab7..df4d0185bd8 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js @@ -43,6 +43,7 @@ UI.TreeOutline = class extends Common.Object { this.contentElement = this._rootElement._childrenListNode; this.contentElement.addEventListener('keydown', this._treeKeyDown.bind(this), true); + this._showSelectionOnKeyboardFocus = false; this._focusable = true; this.setFocusable(this._focusable); if (this._focusable) @@ -51,6 +52,14 @@ UI.TreeOutline = class extends Common.Object { UI.ARIAUtils.markAsTree(this.element); } + /** + * @param {boolean} show + */ + setShowSelectionOnKeyboardFocus(show) { + this.contentElement.classList.toggle('hide-selection-when-blurred', show); + this._showSelectionOnKeyboardFocus = show; + } + _createRootElement() { this._rootElement = new UI.TreeElement(); this._rootElement.treeOutline = this; @@ -793,7 +802,9 @@ UI.TreeElement = class { if (element.treeElement !== this || element.hasSelection()) return; - const toggleOnClick = this.toggleOnClick && !this.selectable; + console.assert(!!this.treeOutline); + const showSelectionOnKeyboardFocus = this.treeOutline ? this.treeOutline._showSelectionOnKeyboardFocus : false; + const toggleOnClick = this.toggleOnClick && (showSelectionOnKeyboardFocus || !this.selectable); const isInTriangle = this.isEventWithinDisclosureTriangle(event); if (!toggleOnClick && !isInTriangle) return; @@ -1068,11 +1079,13 @@ UI.TreeElement = class { } _onFocus() { - this._listItemNode.classList.add('force-white-icons'); + if (!this.treeOutline.contentElement.classList.contains('hide-selection-when-blurred')) + this._listItemNode.classList.add('force-white-icons'); } _onBlur() { - this._listItemNode.classList.remove('force-white-icons'); + if (!this.treeOutline.contentElement.classList.contains('hide-selection-when-blurred')) + this._listItemNode.classList.remove('force-white-icons'); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json b/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json index deadd1ff68c..bb5c7d438ff 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json +++ b/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json @@ -2,7 +2,6 @@ "modules" : [ { "name": "mobile_throttling", "type": "autostart" }, { "name": "worker_main", "type": "autostart" }, - { "name": "browser_components", "type": "autostart" }, { "name": "browser_console" }, { "name": "browser_debugger" }, diff --git a/chromium/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js b/chromium/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js index 16063e8311a..740a6ecdb4c 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js @@ -51,8 +51,9 @@ Workspace.FileManager = class extends Common.Object { */ save(url, content, forceSaveAs) { // Remove this url from the saved URLs while it is being saved. + const result = new Promise(resolve => this._saveCallbacks.set(url, resolve)); InspectorFrontendHost.save(url, content, forceSaveAs); - return new Promise(resolve => this._saveCallbacks.set(url, resolve)); + return result; } /** @@ -89,7 +90,7 @@ Workspace.FileManager = class extends Common.Object { * @param {string} url */ close(url) { - // Currently a no-op. + InspectorFrontendHost.close(url); } /** diff --git a/chromium/third_party/blink/renderer/devtools/front_end/workspace/Workspace.js b/chromium/third_party/blink/renderer/devtools/front_end/workspace/Workspace.js index 83e676e48a8..54a4c98e345 100644 --- a/chromium/third_party/blink/renderer/devtools/front_end/workspace/Workspace.js +++ b/chromium/third_party/blink/renderer/devtools/front_end/workspace/Workspace.js @@ -213,7 +213,6 @@ Workspace.projectTypes = { Debugger: 'debugger', Formatter: 'formatter', Network: 'network', - Snippets: 'snippets', FileSystem: 'filesystem', ContentScripts: 'contentscripts', Service: 'service' |