Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @constructor | 6 * @constructor |
| 7 * @implements {WebInspector.TargetManager.Observer} | |
| 7 */ | 8 */ |
| 8 WebInspector.CSSWorkspaceBinding = function() | 9 WebInspector.CSSWorkspaceBinding = function() |
|
vsevik
2014/07/22 14:59:01
WebInspector.CSSStyleSheetMapping implementation a
apavlov
2014/07/22 16:19:53
Done.
| |
| 9 { | 10 { |
| 11 /** @type {!Map.<!WebInspector.Target, !StringMap.<!WebInspector.CSSWorkspac eBinding.HeaderInfo>>} */ | |
| 12 this._targetToHeaderDataMap = new Map(); | |
| 13 WebInspector.targetManager.observeTargets(this); | |
| 14 | |
| 15 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameCre atedOrNavigated, this); | |
| 16 WebInspector.targetManager.addModelListener(WebInspector.CSSStyleModel, WebI nspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this); | |
| 10 } | 17 } |
| 11 | 18 |
| 12 WebInspector.CSSWorkspaceBinding.prototype = { | 19 WebInspector.CSSWorkspaceBinding.prototype = { |
| 13 /** | 20 /** |
| 21 * @param {!WebInspector.Target} target | |
| 22 */ | |
| 23 targetAdded: function(target) | |
| 24 { | |
| 25 this._targetToHeaderDataMap.put(target, new StringMap()); | |
| 26 }, | |
| 27 | |
| 28 /** | |
| 29 * @param {!WebInspector.Target} target | |
| 30 */ | |
| 31 targetRemoved: function(target) | |
| 32 { | |
| 33 this._targetToHeaderDataMap.remove(target); | |
| 34 }, | |
| 35 | |
| 36 /** | |
| 37 * @param {!WebInspector.CSSStyleSheetHeader} header | |
| 38 * @param {!WebInspector.SourceMapping} mapping | |
| 39 */ | |
| 40 pushSourceMapping: function(header, mapping) | |
| 41 { | |
| 42 this._ensureInfoForHeader(header)._pushSourceMapping(mapping); | |
| 43 }, | |
| 44 | |
| 45 /** | |
| 46 * @param {!WebInspector.CSSStyleSheetHeader} header | |
| 47 * @return {?WebInspector.CSSWorkspaceBinding.HeaderInfo} | |
| 48 */ | |
| 49 _headerInfo: function(header) | |
| 50 { | |
| 51 var map = this._targetToHeaderDataMap.get(header.target()); | |
| 52 return map.get(header.id) || null; | |
| 53 }, | |
| 54 | |
| 55 /** | |
| 56 * @param {!WebInspector.CSSStyleSheetHeader} header | |
| 57 * @return {!WebInspector.CSSWorkspaceBinding.HeaderInfo} | |
| 58 */ | |
| 59 _ensureInfoForHeader: function(header) | |
| 60 { | |
| 61 var headerDataMap = this._targetToHeaderDataMap.get(header.target()); | |
| 62 var info = headerDataMap.get(header.id); | |
| 63 if (!info) { | |
| 64 info = new WebInspector.CSSWorkspaceBinding.HeaderInfo(header); | |
| 65 headerDataMap.put(header.id, info); | |
| 66 } | |
| 67 return info; | |
| 68 }, | |
| 69 | |
| 70 /** | |
| 71 * @param {!WebInspector.Event} event | |
| 72 */ | |
| 73 _mainFrameCreatedOrNavigated: function(event) | |
| 74 { | |
| 75 var target = /** @type {!WebInspector.ResourceTreeModel} */ (event.targe t).target(); | |
| 76 this._targetToHeaderDataMap.put(target, new StringMap()); | |
| 77 }, | |
| 78 | |
| 79 /** | |
| 80 * @param {!WebInspector.Event} event | |
| 81 */ | |
| 82 _styleSheetRemoved: function(event) | |
| 83 { | |
| 84 var target = /** @type {!WebInspector.CSSStyleModel} */ (event.target).t arget(); | |
| 85 var headerMap = this._targetToHeaderDataMap.get(target); | |
| 86 headerMap.remove(/** @type {!WebInspector.CSSStyleSheetHeader} */ (event .data).id); | |
| 87 }, | |
| 88 | |
| 89 /** | |
| 90 * @param {!WebInspector.CSSStyleSheetHeader} header | |
| 91 */ | |
| 92 updateLocations: function(header) | |
| 93 { | |
| 94 var info = this._headerInfo(header); | |
| 95 if (info) | |
| 96 info._updateLocations(); | |
| 97 }, | |
| 98 | |
| 99 /** | |
| 14 * @param {!WebInspector.CSSLocation} rawLocation | 100 * @param {!WebInspector.CSSLocation} rawLocation |
| 15 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDel egate | 101 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDel egate |
| 16 * @return {!WebInspector.CSSStyleModel.LiveLocation} | 102 * @return {!WebInspector.CSSWorkspaceBinding.LiveLocation} |
| 17 */ | 103 */ |
| 18 createLiveLocation: function(rawLocation, updateDelegate) | 104 createLiveLocation: function(rawLocation, updateDelegate) |
| 19 { | 105 { |
| 20 return /** @type {!WebInspector.CSSStyleModel.LiveLocation} */ (rawLocat ion.createLiveLocation(updateDelegate)); | 106 var header = rawLocation.styleSheetId ? rawLocation.target().cssModel.st yleSheetHeaderForId(rawLocation.styleSheetId) : null; |
| 107 return new WebInspector.CSSWorkspaceBinding.LiveLocation(rawLocation.tar get().cssModel, header, rawLocation, updateDelegate); | |
| 21 }, | 108 }, |
| 22 | 109 |
| 23 /** | 110 /** |
| 111 * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location | |
| 112 */ | |
| 113 _addLiveLocation: function(location) | |
| 114 { | |
| 115 this._ensureInfoForHeader(location._header)._addLocation(location); | |
| 116 }, | |
| 117 | |
| 118 /** | |
| 119 * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location | |
| 120 */ | |
| 121 _removeLiveLocation: function(location) | |
| 122 { | |
| 123 var info = this._headerInfo(location._header); | |
| 124 if (info) | |
| 125 info._removeLocation(location); | |
| 126 }, | |
| 127 | |
| 128 /** | |
| 24 * @param {!WebInspector.CSSProperty} cssProperty | 129 * @param {!WebInspector.CSSProperty} cssProperty |
| 25 * @param {boolean} forName | 130 * @param {boolean} forName |
| 26 * @return {?WebInspector.UILocation} | 131 * @return {?WebInspector.UILocation} |
| 27 */ | 132 */ |
| 28 propertyUILocation: function(cssProperty, forName) | 133 propertyUILocation: function(cssProperty, forName) |
| 29 { | 134 { |
| 30 var style = cssProperty.ownerStyle; | 135 var style = cssProperty.ownerStyle; |
| 31 if (!style || !style.parentRule || !style.styleSheetId) | 136 if (!style || !style.parentRule || !style.styleSheetId) |
| 32 return null; | 137 return null; |
| 33 | 138 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 45 var rawLocation = new WebInspector.CSSLocation(style.target(), style.sty leSheetId, url, line, column); | 150 var rawLocation = new WebInspector.CSSLocation(style.target(), style.sty leSheetId, url, line, column); |
| 46 return this.rawLocationToUILocation(rawLocation); | 151 return this.rawLocationToUILocation(rawLocation); |
| 47 }, | 152 }, |
| 48 | 153 |
| 49 /** | 154 /** |
| 50 * @param {?WebInspector.CSSLocation} rawLocation | 155 * @param {?WebInspector.CSSLocation} rawLocation |
| 51 * @return {?WebInspector.UILocation} | 156 * @return {?WebInspector.UILocation} |
| 52 */ | 157 */ |
| 53 rawLocationToUILocation: function(rawLocation) | 158 rawLocationToUILocation: function(rawLocation) |
| 54 { | 159 { |
| 55 return rawLocation ? rawLocation.target().cssModel.rawLocationToUILocati on(rawLocation) : null; | 160 if (!rawLocation) |
| 161 return null; | |
| 162 var cssModel = rawLocation.target().cssModel; | |
| 163 var frameIdToSheetIds = cssModel.styleSheetIdsByFrameIdForURL(rawLocatio n.url); | |
| 164 if (!Object.values(frameIdToSheetIds).length) | |
| 165 return null; | |
| 166 var styleSheetIds = []; | |
| 167 for (var frameId in frameIdToSheetIds) | |
| 168 styleSheetIds = styleSheetIds.concat(frameIdToSheetIds[frameId]); | |
| 169 var uiLocation; | |
| 170 for (var i = 0; !uiLocation && i < styleSheetIds.length; ++i) { | |
| 171 var header = cssModel.styleSheetHeaderForId(styleSheetIds[i]); | |
| 172 if (!header) | |
| 173 continue; | |
| 174 var info = this._headerInfo(header); | |
| 175 if (info) | |
| 176 uiLocation = info._rawLocationToUILocation(rawLocation.lineNumbe r, rawLocation.columnNumber); | |
| 177 } | |
| 178 return uiLocation || null; | |
| 56 } | 179 } |
| 57 } | 180 } |
| 58 | 181 |
| 59 /** | 182 /** |
| 183 * @constructor | |
| 184 * @param {!WebInspector.CSSStyleSheetHeader} header | |
| 185 */ | |
| 186 WebInspector.CSSWorkspaceBinding.HeaderInfo = function(header) | |
| 187 { | |
| 188 this._header = header; | |
| 189 | |
| 190 /** @type {!Array.<!WebInspector.SourceMapping>} */ | |
| 191 this._sourceMappings = []; | |
| 192 | |
| 193 /** @type {!Set.<!WebInspector.LiveLocation>} */ | |
| 194 this._locations = new Set(); | |
| 195 } | |
| 196 | |
| 197 WebInspector.CSSWorkspaceBinding.HeaderInfo.prototype = { | |
| 198 /** | |
| 199 * @param {!WebInspector.LiveLocation} location | |
| 200 */ | |
| 201 _addLocation: function(location) | |
| 202 { | |
| 203 this._locations.add(location); | |
| 204 location.update(); | |
| 205 }, | |
| 206 | |
| 207 /** | |
| 208 * @param {!WebInspector.LiveLocation} location | |
| 209 */ | |
| 210 _removeLocation: function(location) | |
| 211 { | |
| 212 this._locations.remove(location); | |
| 213 }, | |
| 214 | |
| 215 _updateLocations: function() | |
| 216 { | |
| 217 var items = this._locations.values(); | |
| 218 for (var i = 0; i < items.length; ++i) | |
| 219 items[i].update(); | |
| 220 }, | |
| 221 | |
| 222 /** | |
| 223 * @param {number} lineNumber | |
| 224 * @param {number=} columnNumber | |
| 225 * @return {?WebInspector.UILocation} | |
| 226 */ | |
| 227 _rawLocationToUILocation: function(lineNumber, columnNumber) | |
| 228 { | |
| 229 var uiLocation = null; | |
| 230 var rawLocation = new WebInspector.CSSLocation(this._header.target(), th is._header.id, this._header.resourceURL(), lineNumber, columnNumber); | |
| 231 for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i ) | |
| 232 uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLoca tion); | |
| 233 return uiLocation; | |
| 234 }, | |
| 235 | |
| 236 /** | |
| 237 * @param {!WebInspector.SourceMapping} sourceMapping | |
| 238 */ | |
| 239 _pushSourceMapping: function(sourceMapping) | |
| 240 { | |
| 241 this._sourceMappings.push(sourceMapping); | |
| 242 this._updateLocations(); | |
| 243 } | |
| 244 } | |
| 245 | |
| 246 /** | |
| 247 * @constructor | |
| 248 * @extends {WebInspector.LiveLocation} | |
| 249 * @param {!WebInspector.CSSStyleModel} cssModel | |
| 250 * @param {?WebInspector.CSSStyleSheetHeader} header | |
| 251 * @param {!WebInspector.CSSLocation} rawLocation | |
| 252 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDelegat e | |
| 253 */ | |
| 254 WebInspector.CSSWorkspaceBinding.LiveLocation = function(cssModel, header, rawLo cation, updateDelegate) | |
| 255 { | |
| 256 WebInspector.LiveLocation.call(this, rawLocation, updateDelegate); | |
| 257 this._cssModel = cssModel; | |
| 258 if (!header) | |
| 259 this._clearStyleSheet(); | |
| 260 else | |
| 261 this._setStyleSheet(header); | |
| 262 } | |
| 263 | |
| 264 WebInspector.CSSWorkspaceBinding.LiveLocation.prototype = { | |
| 265 /** | |
| 266 * @param {!WebInspector.Event} event | |
| 267 */ | |
| 268 _styleSheetAdded: function(event) | |
| 269 { | |
| 270 console.assert(!this._header); | |
| 271 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a); | |
| 272 if (header.sourceURL && header.sourceURL === this.rawLocation().url) | |
| 273 this._setStyleSheet(header); | |
| 274 }, | |
| 275 | |
| 276 /** | |
| 277 * @param {!WebInspector.Event} event | |
| 278 */ | |
| 279 _styleSheetRemoved: function(event) | |
| 280 { | |
| 281 console.assert(this._header); | |
| 282 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a); | |
| 283 if (this._header !== header) | |
| 284 return; | |
| 285 WebInspector.cssWorkspaceBinding._removeLiveLocation(this); | |
| 286 this._clearStyleSheet(); | |
| 287 }, | |
| 288 | |
| 289 /** | |
| 290 * @param {!WebInspector.CSSStyleSheetHeader} header | |
| 291 */ | |
| 292 _setStyleSheet: function(header) | |
| 293 { | |
| 294 this._header = header; | |
| 295 WebInspector.cssWorkspaceBinding._addLiveLocation(this); | |
| 296 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetAdded, this._styleSheetAdded, this); | |
| 297 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleS heetRemoved, this._styleSheetRemoved, this); | |
| 298 }, | |
| 299 | |
| 300 _clearStyleSheet: function() | |
| 301 { | |
| 302 delete this._header; | |
| 303 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetRemoved, this._styleSheetRemoved, this); | |
| 304 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleS heetAdded, this._styleSheetAdded, this); | |
| 305 }, | |
| 306 | |
| 307 /** | |
| 308 * @return {?WebInspector.UILocation} | |
| 309 */ | |
| 310 uiLocation: function() | |
| 311 { | |
| 312 var cssLocation = /** @type WebInspector.CSSLocation */ (this.rawLocatio n()); | |
| 313 if (this._header) { | |
| 314 var headerInfo = WebInspector.cssWorkspaceBinding._headerInfo(this._ header); | |
| 315 return headerInfo._rawLocationToUILocation(cssLocation.lineNumber, c ssLocation.columnNumber); | |
| 316 } | |
| 317 var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(cssLocation .url); | |
| 318 if (!uiSourceCode) | |
| 319 return null; | |
| 320 return uiSourceCode.uiLocation(cssLocation.lineNumber, cssLocation.colum nNumber); | |
| 321 }, | |
| 322 | |
| 323 dispose: function() | |
| 324 { | |
| 325 WebInspector.LiveLocation.prototype.dispose.call(this); | |
| 326 if (this._header) | |
| 327 WebInspector.cssWorkspaceBinding._removeLiveLocation(this); | |
| 328 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetAdded, this._styleSheetAdded, this); | |
| 329 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetRemoved, this._styleSheetRemoved, this); | |
| 330 }, | |
| 331 | |
| 332 __proto__: WebInspector.LiveLocation.prototype | |
| 333 } | |
| 334 | |
| 335 /** | |
| 60 * @type {!WebInspector.CSSWorkspaceBinding} | 336 * @type {!WebInspector.CSSWorkspaceBinding} |
| 61 */ | 337 */ |
| 62 WebInspector.cssWorkspaceBinding; | 338 WebInspector.cssWorkspaceBinding; |
| OLD | NEW |