Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1477)

Unified Diff: Source/devtools/front_end/sdk/CSSWorkspaceBinding.js

Issue 297923002: DevTools: Decouple CSS model from UI entities (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase atop new workspace bindings Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/devtools/front_end/sdk/CSSWorkspaceBinding.js
diff --git a/Source/devtools/front_end/sdk/CSSWorkspaceBinding.js b/Source/devtools/front_end/sdk/CSSWorkspaceBinding.js
index 75574889c97779049f35892d951c8d2dbe8d15b1..b88a6fdd1ec14936e4eb353ec4a104d5f974356e 100644
--- a/Source/devtools/front_end/sdk/CSSWorkspaceBinding.js
+++ b/Source/devtools/front_end/sdk/CSSWorkspaceBinding.js
@@ -4,20 +4,125 @@
/**
* @constructor
+ * @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.CSSWorkspaceBinding = function()
vsevik 2014/07/22 14:59:01 WebInspector.CSSStyleSheetMapping implementation a
apavlov 2014/07/22 16:19:53 Done.
{
+ /** @type {!Map.<!WebInspector.Target, !StringMap.<!WebInspector.CSSWorkspaceBinding.HeaderInfo>>} */
+ this._targetToHeaderDataMap = new Map();
+ WebInspector.targetManager.observeTargets(this);
+
+ WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameCreatedOrNavigated, this);
+ WebInspector.targetManager.addModelListener(WebInspector.CSSStyleModel, WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
}
WebInspector.CSSWorkspaceBinding.prototype = {
/**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ this._targetToHeaderDataMap.put(target, new StringMap());
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ this._targetToHeaderDataMap.remove(target);
+ },
+
+ /**
+ * @param {!WebInspector.CSSStyleSheetHeader} header
+ * @param {!WebInspector.SourceMapping} mapping
+ */
+ pushSourceMapping: function(header, mapping)
+ {
+ this._ensureInfoForHeader(header)._pushSourceMapping(mapping);
+ },
+
+ /**
+ * @param {!WebInspector.CSSStyleSheetHeader} header
+ * @return {?WebInspector.CSSWorkspaceBinding.HeaderInfo}
+ */
+ _headerInfo: function(header)
+ {
+ var map = this._targetToHeaderDataMap.get(header.target());
+ return map.get(header.id) || null;
+ },
+
+ /**
+ * @param {!WebInspector.CSSStyleSheetHeader} header
+ * @return {!WebInspector.CSSWorkspaceBinding.HeaderInfo}
+ */
+ _ensureInfoForHeader: function(header)
+ {
+ var headerDataMap = this._targetToHeaderDataMap.get(header.target());
+ var info = headerDataMap.get(header.id);
+ if (!info) {
+ info = new WebInspector.CSSWorkspaceBinding.HeaderInfo(header);
+ headerDataMap.put(header.id, info);
+ }
+ return info;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _mainFrameCreatedOrNavigated: function(event)
+ {
+ var target = /** @type {!WebInspector.ResourceTreeModel} */ (event.target).target();
+ this._targetToHeaderDataMap.put(target, new StringMap());
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _styleSheetRemoved: function(event)
+ {
+ var target = /** @type {!WebInspector.CSSStyleModel} */ (event.target).target();
+ var headerMap = this._targetToHeaderDataMap.get(target);
+ headerMap.remove(/** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data).id);
+ },
+
+ /**
+ * @param {!WebInspector.CSSStyleSheetHeader} header
+ */
+ updateLocations: function(header)
+ {
+ var info = this._headerInfo(header);
+ if (info)
+ info._updateLocations();
+ },
+
+ /**
* @param {!WebInspector.CSSLocation} rawLocation
* @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDelegate
- * @return {!WebInspector.CSSStyleModel.LiveLocation}
+ * @return {!WebInspector.CSSWorkspaceBinding.LiveLocation}
*/
createLiveLocation: function(rawLocation, updateDelegate)
{
- return /** @type {!WebInspector.CSSStyleModel.LiveLocation} */ (rawLocation.createLiveLocation(updateDelegate));
+ var header = rawLocation.styleSheetId ? rawLocation.target().cssModel.styleSheetHeaderForId(rawLocation.styleSheetId) : null;
+ return new WebInspector.CSSWorkspaceBinding.LiveLocation(rawLocation.target().cssModel, header, rawLocation, updateDelegate);
+ },
+
+ /**
+ * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location
+ */
+ _addLiveLocation: function(location)
+ {
+ this._ensureInfoForHeader(location._header)._addLocation(location);
+ },
+
+ /**
+ * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location
+ */
+ _removeLiveLocation: function(location)
+ {
+ var info = this._headerInfo(location._header);
+ if (info)
+ info._removeLocation(location);
},
/**
@@ -52,11 +157,182 @@ WebInspector.CSSWorkspaceBinding.prototype = {
*/
rawLocationToUILocation: function(rawLocation)
{
- return rawLocation ? rawLocation.target().cssModel.rawLocationToUILocation(rawLocation) : null;
+ if (!rawLocation)
+ return null;
+ var cssModel = rawLocation.target().cssModel;
+ var frameIdToSheetIds = cssModel.styleSheetIdsByFrameIdForURL(rawLocation.url);
+ if (!Object.values(frameIdToSheetIds).length)
+ return null;
+ var styleSheetIds = [];
+ for (var frameId in frameIdToSheetIds)
+ styleSheetIds = styleSheetIds.concat(frameIdToSheetIds[frameId]);
+ var uiLocation;
+ for (var i = 0; !uiLocation && i < styleSheetIds.length; ++i) {
+ var header = cssModel.styleSheetHeaderForId(styleSheetIds[i]);
+ if (!header)
+ continue;
+ var info = this._headerInfo(header);
+ if (info)
+ uiLocation = info._rawLocationToUILocation(rawLocation.lineNumber, rawLocation.columnNumber);
+ }
+ return uiLocation || null;
+ }
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.CSSStyleSheetHeader} header
+ */
+WebInspector.CSSWorkspaceBinding.HeaderInfo = function(header)
+{
+ this._header = header;
+
+ /** @type {!Array.<!WebInspector.SourceMapping>} */
+ this._sourceMappings = [];
+
+ /** @type {!Set.<!WebInspector.LiveLocation>} */
+ this._locations = new Set();
+}
+
+WebInspector.CSSWorkspaceBinding.HeaderInfo.prototype = {
+ /**
+ * @param {!WebInspector.LiveLocation} location
+ */
+ _addLocation: function(location)
+ {
+ this._locations.add(location);
+ location.update();
+ },
+
+ /**
+ * @param {!WebInspector.LiveLocation} location
+ */
+ _removeLocation: function(location)
+ {
+ this._locations.remove(location);
+ },
+
+ _updateLocations: function()
+ {
+ var items = this._locations.values();
+ for (var i = 0; i < items.length; ++i)
+ items[i].update();
+ },
+
+ /**
+ * @param {number} lineNumber
+ * @param {number=} columnNumber
+ * @return {?WebInspector.UILocation}
+ */
+ _rawLocationToUILocation: function(lineNumber, columnNumber)
+ {
+ var uiLocation = null;
+ var rawLocation = new WebInspector.CSSLocation(this._header.target(), this._header.id, this._header.resourceURL(), lineNumber, columnNumber);
+ for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i)
+ uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
+ return uiLocation;
+ },
+
+ /**
+ * @param {!WebInspector.SourceMapping} sourceMapping
+ */
+ _pushSourceMapping: function(sourceMapping)
+ {
+ this._sourceMappings.push(sourceMapping);
+ this._updateLocations();
}
}
/**
+ * @constructor
+ * @extends {WebInspector.LiveLocation}
+ * @param {!WebInspector.CSSStyleModel} cssModel
+ * @param {?WebInspector.CSSStyleSheetHeader} header
+ * @param {!WebInspector.CSSLocation} rawLocation
+ * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDelegate
+ */
+WebInspector.CSSWorkspaceBinding.LiveLocation = function(cssModel, header, rawLocation, updateDelegate)
+{
+ WebInspector.LiveLocation.call(this, rawLocation, updateDelegate);
+ this._cssModel = cssModel;
+ if (!header)
+ this._clearStyleSheet();
+ else
+ this._setStyleSheet(header);
+}
+
+WebInspector.CSSWorkspaceBinding.LiveLocation.prototype = {
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _styleSheetAdded: function(event)
+ {
+ console.assert(!this._header);
+ var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
+ if (header.sourceURL && header.sourceURL === this.rawLocation().url)
+ this._setStyleSheet(header);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _styleSheetRemoved: function(event)
+ {
+ console.assert(this._header);
+ var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
+ if (this._header !== header)
+ return;
+ WebInspector.cssWorkspaceBinding._removeLiveLocation(this);
+ this._clearStyleSheet();
+ },
+
+ /**
+ * @param {!WebInspector.CSSStyleSheetHeader} header
+ */
+ _setStyleSheet: function(header)
+ {
+ this._header = header;
+ WebInspector.cssWorkspaceBinding._addLiveLocation(this);
+ this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
+ this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
+ },
+
+ _clearStyleSheet: function()
+ {
+ delete this._header;
+ this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
+ this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
+ },
+
+ /**
+ * @return {?WebInspector.UILocation}
+ */
+ uiLocation: function()
+ {
+ var cssLocation = /** @type WebInspector.CSSLocation */ (this.rawLocation());
+ if (this._header) {
+ var headerInfo = WebInspector.cssWorkspaceBinding._headerInfo(this._header);
+ return headerInfo._rawLocationToUILocation(cssLocation.lineNumber, cssLocation.columnNumber);
+ }
+ var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(cssLocation.url);
+ if (!uiSourceCode)
+ return null;
+ return uiSourceCode.uiLocation(cssLocation.lineNumber, cssLocation.columnNumber);
+ },
+
+ dispose: function()
+ {
+ WebInspector.LiveLocation.prototype.dispose.call(this);
+ if (this._header)
+ WebInspector.cssWorkspaceBinding._removeLiveLocation(this);
+ this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
+ this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
+ },
+
+ __proto__: WebInspector.LiveLocation.prototype
+}
+
+/**
* @type {!WebInspector.CSSWorkspaceBinding}
*/
WebInspector.cssWorkspaceBinding;

Powered by Google App Engine
This is Rietveld 408576698