Index: third_party/WebKit/Source/devtools/front_end/bindings/StylesSourceMapping.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/StylesSourceMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/StylesSourceMapping.js |
index 49cb560acdc6cfcf0a820d99581a6e6968d0192a..8c647e5987013973bbe543c41fcde4b54a1849f7 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/bindings/StylesSourceMapping.js |
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/StylesSourceMapping.js |
@@ -34,27 +34,19 @@ |
Bindings.StylesSourceMapping = class { |
/** |
* @param {!SDK.CSSModel} cssModel |
- * @param {!Workspace.Workspace} workspace |
+ * @param {!Bindings.NetworkProject} networkProject |
*/ |
- constructor(cssModel, workspace) { |
+ constructor(cssModel, networkProject) { |
this._cssModel = cssModel; |
- this._workspace = workspace; |
+ this._networkProject = networkProject; |
- /** @type {!Map<string, !Map<string, !Map<string, !SDK.CSSStyleSheetHeader>>>} */ |
- this._urlToHeadersByFrameId = new Map(); |
/** @type {!Map.<!Workspace.UISourceCode, !Bindings.StyleFile>} */ |
this._styleFiles = new Map(); |
this._eventListeners = [ |
- this._workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved, this), |
- this._workspace.addEventListener( |
- Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this), |
- this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this), |
this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this), |
this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this), |
- this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetChanged, this._styleSheetChanged, this), |
- SDK.ResourceTreeModel.fromTarget(cssModel.target()) |
- .addEventListener(SDK.ResourceTreeModel.Events.MainFrameNavigated, this._unbindAllUISourceCodes, this) |
dgozman
2017/01/27 23:49:13
Why we don't need this anymore?
lushnikov
2017/01/30 14:19:15
We receive "styleSheetRemoved" events in this case
|
+ this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetChanged, this._styleSheetChanged, this) |
]; |
} |
@@ -63,13 +55,13 @@ Bindings.StylesSourceMapping = class { |
* @return {?Workspace.UILocation} |
*/ |
rawLocationToUILocation(rawLocation) { |
- var uiSourceCode = |
- Bindings.NetworkProject.uiSourceCodeForStyleURL(this._workspace, rawLocation.url, rawLocation.header()); |
+ var uiSourceCode = this._networkProject.getFile( |
+ rawLocation.url, SDK.ResourceTreeFrame.fromStyleSheet(rawLocation.header()), false); |
if (!uiSourceCode) |
return null; |
var lineNumber = rawLocation.lineNumber; |
var columnNumber = rawLocation.columnNumber; |
- var header = this._cssModel.styleSheetHeaderForId(rawLocation.styleSheetId); |
+ var header = rawLocation.header(); |
if (header && header.isInline && header.hasSourceURL) { |
lineNumber -= header.lineNumberInSource(0); |
columnNumber -= header.columnNumberInSource(lineNumber, 0); |
@@ -82,24 +74,22 @@ Bindings.StylesSourceMapping = class { |
*/ |
_styleSheetAdded(event) { |
var header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data); |
+ if (header.isInline && !header.hasSourceURL && header.origin !== 'inspector') |
+ return; |
+ |
var url = header.resourceURL(); |
if (!url) |
return; |
- var map = this._urlToHeadersByFrameId.get(url); |
- if (!map) { |
- map = /** @type {!Map.<string, !Map.<string, !SDK.CSSStyleSheetHeader>>} */ (new Map()); |
- this._urlToHeadersByFrameId.set(url, map); |
+ var uiSourceCode = this._networkProject.getFile(url, SDK.ResourceTreeFrame.fromStyleSheet(header), false); |
+ if (!uiSourceCode) { |
+ uiSourceCode = this._networkProject.createFileForStyleSheetHeader(header); |
+ this._styleFiles.set(uiSourceCode, new Bindings.StyleFile(this._cssModel, uiSourceCode)); |
} |
- var headersById = map.get(header.frameId); |
- if (!headersById) { |
- headersById = /** @type {!Map.<string, !SDK.CSSStyleSheetHeader>} */ (new Map()); |
- map.set(header.frameId, headersById); |
- } |
- headersById.set(header.id, header); |
- var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForStyleURL(this._workspace, url, header); |
- if (uiSourceCode) |
- this._bindUISourceCode(uiSourceCode, header); |
+ var styleFile = this._styleFiles.get(uiSourceCode); |
+ styleFile.addHeader(header); |
+ |
+ Bindings.cssWorkspaceBinding.updateLocations(header); |
} |
/** |
@@ -108,246 +98,184 @@ Bindings.StylesSourceMapping = class { |
_styleSheetRemoved(event) { |
var header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data); |
var url = header.resourceURL(); |
- if (!url) |
+ var frame = SDK.ResourceTreeFrame.fromStyleSheet(header); |
+ var uiSourceCode = this._networkProject.getFile(url, frame, false); |
+ if (!uiSourceCode) |
return; |
- |
- var map = this._urlToHeadersByFrameId.get(url); |
- console.assert(map); |
- var headersById = map.get(header.frameId); |
- console.assert(headersById); |
- headersById.delete(header.id); |
- |
- if (!headersById.size) { |
- map.delete(header.frameId); |
- if (!map.size) { |
- this._urlToHeadersByFrameId.delete(url); |
- var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForStyleURL(this._workspace, url, header); |
- if (uiSourceCode) |
- this._unbindUISourceCode(uiSourceCode); |
- } |
- } |
- } |
- |
- /** |
- * @param {!Workspace.UISourceCode} uiSourceCode |
- */ |
- _unbindUISourceCode(uiSourceCode) { |
var styleFile = this._styleFiles.get(uiSourceCode); |
- if (!styleFile) |
+ styleFile.removeHeader(header); |
+ if (styleFile.hasHeaders()) |
return; |
styleFile.dispose(); |
this._styleFiles.delete(uiSourceCode); |
+ this._networkProject.removeFile(uiSourceCode); |
} |
/** |
* @param {!Common.Event} event |
*/ |
- _unbindAllUISourceCodes(event) { |
- if (event.data.target() !== this._cssModel.target()) |
- return; |
- for (var styleFile of this._styleFiles.values()) |
+ _styleSheetChanged(event) { |
+ var styleSheetId = event.data.styleSheetId; |
+ var header = this._cssModel.styleSheetHeaderForId(styleSheetId); |
+ var uiSourceCode = |
dgozman
2017/01/27 23:49:12
Why do we have to consult with NetworkProject firs
lushnikov
2017/01/30 14:19:15
NetworkProject already has the knowledge of creati
|
+ this._networkProject.getFile(header.resourceURL(), SDK.ResourceTreeFrame.fromStyleSheet(header), false); |
+ var styleFile = uiSourceCode ? this._styleFiles.get(uiSourceCode) : null; |
+ if (styleFile) |
+ styleFile.styleSheetChanged(header); |
+ } |
+ |
+ dispose() { |
+ for (var uiSourceCode of this._styleFiles.keys()) { |
+ this._networkProject.removeFile(uiSourceCode); |
+ var styleFile = this._styleFiles.get(uiSourceCode); |
styleFile.dispose(); |
+ } |
this._styleFiles.clear(); |
- this._urlToHeadersByFrameId = new Map(); |
+ Common.EventTarget.removeEventListeners(this._eventListeners); |
} |
+}; |
+/** |
+ * @unrestricted |
+ */ |
+Bindings.StyleFile = class { |
/** |
- * @param {!Common.Event} event |
+ * @param {!SDK.CSSModel} cssModel |
+ * @param {!Workspace.UISourceCode} uiSourceCode |
*/ |
- _uiSourceCodeAddedToWorkspace(event) { |
- var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); |
- if (!this._urlToHeadersByFrameId.has(uiSourceCode.url())) |
- return; |
- this._bindUISourceCode( |
- uiSourceCode, this._urlToHeadersByFrameId.get(uiSourceCode.url()).valuesArray()[0].valuesArray()[0]); |
+ constructor(cssModel, uiSourceCode) { |
+ this._cssModel = cssModel; |
+ this._uiSourceCode = uiSourceCode; |
+ /** @type {!Set<!SDK.CSSStyleSheetHeader>} */ |
+ this._headers = new Set(); |
+ this._eventListeners = [ |
+ this._uiSourceCode.addEventListener( |
+ Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this), |
+ this._uiSourceCode.addEventListener( |
+ Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this) |
+ ]; |
+ this._commitThrottler = new Common.Throttler(Bindings.StyleFile.updateTimeout); |
+ this._terminated = false; |
} |
/** |
- * @param {!Workspace.UISourceCode} uiSourceCode |
* @param {!SDK.CSSStyleSheetHeader} header |
*/ |
- _bindUISourceCode(uiSourceCode, header) { |
- if (this._styleFiles.get(uiSourceCode) || (header.isInline && !header.hasSourceURL)) |
- return; |
- this._styleFiles.set(uiSourceCode, new Bindings.StyleFile(uiSourceCode, this)); |
- Bindings.cssWorkspaceBinding.updateLocations(header); |
+ addHeader(header) { |
+ this._headers.add(header); |
} |
/** |
- * @param {!Common.Event} event |
+ * @param {!SDK.CSSStyleSheetHeader} header |
*/ |
- _projectRemoved(event) { |
- var project = /** @type {!Workspace.Project} */ (event.data); |
- var uiSourceCodes = project.uiSourceCodes(); |
- for (var i = 0; i < uiSourceCodes.length; ++i) |
- this._unbindUISourceCode(uiSourceCodes[i]); |
+ removeHeader(header) { |
+ this._headers.delete(header); |
} |
/** |
- * @param {!Common.Event} event |
+ * @return {boolean} |
*/ |
- _uiSourceCodeRemoved(event) { |
- var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); |
- this._unbindUISourceCode(uiSourceCode); |
+ hasHeaders() { |
+ return !!this._headers.size; |
} |
/** |
- * @param {!Workspace.UISourceCode} uiSourceCode |
- * @param {string} content |
- * @param {boolean} majorChange |
- * @return {!Promise<?string>} |
+ * @param {!SDK.CSSStyleSheetHeader} header |
*/ |
- _setStyleContent(uiSourceCode, content, majorChange) { |
- var styleSheetIds = this._cssModel.styleSheetIdsForURL(uiSourceCode.url()); |
- if (!styleSheetIds.length) |
- return Promise.resolve(/** @type {?string} */ ('No stylesheet found: ' + uiSourceCode.url())); |
- |
- this._isSettingContent = true; |
- |
- /** |
- * @param {?string} error |
- * @this {Bindings.StylesSourceMapping} |
- * @return {?string} |
- */ |
- function callback(error) { |
- delete this._isSettingContent; |
- return error || null; |
- } |
- |
- var promises = []; |
- for (var i = 0; i < styleSheetIds.length; ++i) |
- promises.push(this._cssModel.setStyleSheetText(styleSheetIds[i], content, majorChange)); |
+ styleSheetChanged(header) { |
+ if (this._isSettingStyleSheetContents) |
+ return; |
- return Promise.all(promises).spread(callback.bind(this)); |
+ this._commitThrottler.schedule(this._syncStyleSheetChange.bind(this, header), false); |
} |
/** |
* @param {!Common.Event} event |
*/ |
- _styleSheetChanged(event) { |
- if (this._isSettingContent) |
+ _workingCopyCommitted(event) { |
+ if (this._isAddingRevision) |
return; |
- this._updateStyleSheetTextSoon(event.data.styleSheetId); |
+ this._isMajorChangePending = true; |
+ this._commitThrottler.schedule(this._syncUISourceCodeChange.bind(this), true); |
} |
/** |
- * @param {!Protocol.CSS.StyleSheetId} styleSheetId |
+ * @param {!Common.Event} event |
*/ |
- _updateStyleSheetTextSoon(styleSheetId) { |
- if (this._updateStyleSheetTextTimer) |
- clearTimeout(this._updateStyleSheetTextTimer); |
+ _workingCopyChanged(event) { |
+ if (this._isAddingRevision) |
+ return; |
- this._updateStyleSheetTextTimer = setTimeout( |
- this._updateStyleSheetText.bind(this, styleSheetId), Bindings.StylesSourceMapping.ChangeUpdateTimeoutMs); |
+ this._commitThrottler.schedule(this._syncUISourceCodeChange.bind(this), false); |
} |
/** |
- * @param {!Protocol.CSS.StyleSheetId} styleSheetId |
+ * @param {!SDK.CSSStyleSheetHeader} header |
+ * @return {!Promise} |
*/ |
- _updateStyleSheetText(styleSheetId) { |
- if (this._updateStyleSheetTextTimer) { |
- clearTimeout(this._updateStyleSheetTextTimer); |
- delete this._updateStyleSheetTextTimer; |
- } |
+ _syncStyleSheetChange(header) { |
+ if (this._terminated || !this._headers.has(header)) |
+ return Promise.resolve(); |
- var header = this._cssModel.styleSheetHeaderForId(styleSheetId); |
- if (!header) |
- return; |
- var styleSheetURL = header.resourceURL(); |
- if (!styleSheetURL) |
- return; |
- var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForStyleURL(this._workspace, styleSheetURL, header); |
- if (!uiSourceCode) |
- return; |
- header.requestContent().then(callback.bind(this, uiSourceCode)); |
+ return header.requestContent().then(onHeaderContent.bind(this)); |
/** |
- * @param {!Workspace.UISourceCode} uiSourceCode |
* @param {?string} content |
- * @this {Bindings.StylesSourceMapping} |
+ * @return {!Promise} |
+ * @this {Bindings.StyleFile} |
*/ |
- function callback(uiSourceCode, content) { |
- var styleFile = this._styleFiles.get(uiSourceCode); |
- if (styleFile) |
- styleFile.addRevision(content || ''); |
+ function onHeaderContent(content) { |
+ if (this._terminated || content === null) |
+ return Promise.resolve(); |
+ this._isAddingRevision = true; |
+ this._uiSourceCode.addRevision(content); |
+ delete this._isAddingRevision; |
+ return this._setStyleSheetContents(content, header, true); |
} |
} |
- dispose() { |
- Common.EventTarget.removeEventListeners(this._eventListeners); |
- } |
-}; |
- |
-Bindings.StylesSourceMapping.ChangeUpdateTimeoutMs = 200; |
- |
-/** |
- * @unrestricted |
- */ |
-Bindings.StyleFile = class { |
- /** |
- * @param {!Workspace.UISourceCode} uiSourceCode |
- * @param {!Bindings.StylesSourceMapping} mapping |
- */ |
- constructor(uiSourceCode, mapping) { |
- this._uiSourceCode = uiSourceCode; |
- this._mapping = mapping; |
- this._eventListeners = [ |
- this._uiSourceCode.addEventListener( |
- Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this), |
- this._uiSourceCode.addEventListener( |
- Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this) |
- ]; |
- this._commitThrottler = new Common.Throttler(Bindings.StyleFile.updateTimeout); |
- this._terminated = false; |
- } |
- |
/** |
- * @param {!Common.Event} event |
+ * @return {!Promise} |
*/ |
- _workingCopyCommitted(event) { |
- if (this._isAddingRevision) |
- return; |
- |
- this._isMajorChangePending = true; |
- this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), true); |
- } |
- |
- /** |
- * @param {!Common.Event} event |
- */ |
- _workingCopyChanged(event) { |
- if (this._isAddingRevision) |
- return; |
- |
- this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), false); |
- } |
- |
- _commitIncrementalEdit() { |
+ _syncUISourceCodeChange() { |
if (this._terminated) |
- return; |
- var promise = |
- this._mapping._setStyleContent(this._uiSourceCode, this._uiSourceCode.workingCopy(), this._isMajorChangePending) |
- .then(this._styleContentSet.bind(this)); |
+ return Promise.resolve(); |
+ var promise = this._setStyleSheetContents(this._uiSourceCode.workingCopy(), null, this._isMajorChangePending); |
this._isMajorChangePending = false; |
return promise; |
} |
/** |
- * @param {?string} error |
- */ |
- _styleContentSet(error) { |
- if (error) |
- console.error(error); |
- } |
- |
- /** |
* @param {string} content |
+ * @param {?SDK.CSSStyleSheetHeader} skipStyleSheet |
+ * @param {boolean} majorChange |
+ * @return {!Promise} |
*/ |
- addRevision(content) { |
- this._isAddingRevision = true; |
- this._uiSourceCode.addRevision(content); |
- delete this._isAddingRevision; |
+ _setStyleSheetContents(content, skipStyleSheet, majorChange) { |
+ this._isSettingStyleSheetContents = true; |
+ var promises = []; |
+ for (var header of this._headers) { |
+ if (header === skipStyleSheet) |
+ continue; |
+ promises.push(this._cssModel.setStyleSheetText(header.id, content, majorChange)); |
+ } |
+ |
+ return Promise.all(promises).then(onStyleSheetContentsUpdated.bind(this)); |
+ |
+ /** |
+ * @param {!Array<?Protocol.Error>} errors |
+ * @this {Bindings.StyleFile} |
+ */ |
+ function onStyleSheetContentsUpdated(errors) { |
+ delete this._isSettingStyleSheetContents; |
+ errors = errors.filter(error => !!error); |
+ for (var error of errors) { |
+ if (!error) |
dgozman
2017/01/27 23:49:13
Filtered them already.
|
+ continue; |
+ console.error(error); |
+ } |
+ } |
} |
dispose() { |