Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 * @implements {Bindings.CSSWorkspaceBinding.SourceMapping} | 32 * @implements {Bindings.CSSWorkspaceBinding.SourceMapping} |
| 33 * @unrestricted | 33 * @unrestricted |
| 34 */ | 34 */ |
| 35 Bindings.StylesSourceMapping = class { | 35 Bindings.StylesSourceMapping = class { |
| 36 /** | 36 /** |
| 37 * @param {!SDK.CSSModel} cssModel | 37 * @param {!SDK.CSSModel} cssModel |
| 38 * @param {!Workspace.Workspace} workspace | 38 * @param {!Workspace.Workspace} workspace |
| 39 */ | 39 */ |
| 40 constructor(cssModel, workspace) { | 40 constructor(cssModel, workspace) { |
| 41 this._cssModel = cssModel; | 41 this._cssModel = cssModel; |
| 42 this._workspace = workspace; | 42 var target = this._cssModel.target(); |
| 43 this._project = new Bindings.ContentProviderBasedProject( | |
| 44 workspace, 'css:' + target.id(), Workspace.projectTypes.Network, '', fal se /* isServiceProject */); | |
| 45 Bindings.NetworkProject.setTargetForProject(this._project, target); | |
| 43 | 46 |
| 44 /** @type {!Map<string, !Map<string, !Map<string, !SDK.CSSStyleSheetHeader>> >} */ | 47 /** @type {!Map.<string, !Bindings.StyleFile>} */ |
| 45 this._urlToHeadersByFrameId = new Map(); | |
| 46 /** @type {!Map.<!Workspace.UISourceCode, !Bindings.StyleFile>} */ | |
| 47 this._styleFiles = new Map(); | 48 this._styleFiles = new Map(); |
| 48 | |
| 49 this._eventListeners = [ | 49 this._eventListeners = [ |
| 50 this._workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved , this._projectRemoved, this), | |
| 51 this._workspace.addEventListener( | |
| 52 Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedT oWorkspace, this), | |
| 53 this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRe moved, this._uiSourceCodeRemoved, this), | |
| 54 this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, this. _styleSheetAdded, this), | 50 this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, this. _styleSheetAdded, this), |
| 55 this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, thi s._styleSheetRemoved, this), | 51 this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, thi s._styleSheetRemoved, this), |
| 56 this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetChanged, thi s._styleSheetChanged, this), | |
| 57 cssModel.target() | |
| 58 .model(SDK.ResourceTreeModel) | |
| 59 .addEventListener(SDK.ResourceTreeModel.Events.MainFrameNavigated, thi s._unbindAllUISourceCodes, this) | |
|
dgozman
2017/05/17 16:46:20
Why don't we need this anymore?
lushnikov
2017/05/20 01:24:18
1. CSSModel handles MainFrameNavigation by itself
| |
| 60 ]; | 52 ]; |
| 61 } | 53 } |
| 62 | 54 |
| 63 /** | 55 /** |
| 64 * @override | 56 * @override |
| 65 * @param {!SDK.CSSLocation} rawLocation | 57 * @param {!SDK.CSSLocation} rawLocation |
| 66 * @return {?Workspace.UILocation} | 58 * @return {?Workspace.UILocation} |
| 67 */ | 59 */ |
| 68 rawLocationToUILocation(rawLocation) { | 60 rawLocationToUILocation(rawLocation) { |
| 69 var header = rawLocation.header(); | 61 var header = rawLocation.header(); |
| 70 if (!header) | 62 if (!header || !this._acceptsHeader(header)) |
| 71 return null; | 63 return null; |
| 72 var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForStyleURL(this._wor kspace, rawLocation.url, header); | 64 var styleFile = this._styleFiles.get(header.resourceURL()); |
| 73 if (!uiSourceCode) | 65 if (!styleFile) |
| 74 return null; | 66 return null; |
| 75 var lineNumber = rawLocation.lineNumber; | 67 var lineNumber = rawLocation.lineNumber; |
| 76 var columnNumber = rawLocation.columnNumber; | 68 var columnNumber = rawLocation.columnNumber; |
| 77 if (header.isInline && header.hasSourceURL) { | 69 if (header.isInline && header.hasSourceURL) { |
| 78 lineNumber -= header.lineNumberInSource(0); | 70 lineNumber -= header.lineNumberInSource(0); |
| 79 columnNumber -= header.columnNumberInSource(lineNumber, 0); | 71 columnNumber -= header.columnNumberInSource(lineNumber, 0); |
| 80 } | 72 } |
| 81 return uiSourceCode.uiLocation(lineNumber, columnNumber); | 73 return styleFile.uiSourceCode().uiLocation(lineNumber, columnNumber); |
| 82 } | 74 } |
| 83 | 75 |
| 84 /** | 76 /** |
| 85 * @override | 77 * @override |
| 86 * @param {!Workspace.UILocation} uiLocation | 78 * @param {!Workspace.UILocation} uiLocation |
| 87 * @return {!Array<!SDK.CSSLocation>} | 79 * @return {!Array<!SDK.CSSLocation>} |
| 88 */ | 80 */ |
| 89 uiLocationToRawLocations(uiLocation) { | 81 uiLocationToRawLocations(uiLocation) { |
| 90 // TODO(caseq,lushnikov): return multiple raw locations. | 82 var styleFile = uiLocation.uiSourceCode[Bindings.StyleFile._symbol]; |
| 91 var header = Bindings.NetworkProject.styleHeaderForUISourceCode(uiLocation.u iSourceCode); | 83 if (!styleFile) |
| 92 if (!header) | |
| 93 return []; | 84 return []; |
| 94 var lineNumber = uiLocation.lineNumber; | 85 var headers = styleFile.headers(); |
| 95 var columnNumber = uiLocation.columnNumber; | 86 var rawLocations = []; |
| 96 if (header.isInline && header.hasSourceURL) { | 87 for (var header of headers) { |
| 97 columnNumber = header.columnNumberInSource(lineNumber, columnNumber); | 88 var lineNumber = uiLocation.lineNumber; |
| 98 lineNumber = header.lineNumberInSource(lineNumber); | 89 var columnNumber = uiLocation.columnNumber; |
| 90 if (header.isInline && header.hasSourceURL) { | |
| 91 columnNumber = header.columnNumberInSource(lineNumber, columnNumber); | |
| 92 lineNumber = header.lineNumberInSource(lineNumber); | |
| 93 } | |
| 94 rawLocations.push(new SDK.CSSLocation(header, lineNumber, columnNumber)); | |
| 99 } | 95 } |
| 100 return [new SDK.CSSLocation(header, lineNumber, columnNumber)]; | 96 return rawLocations; |
| 101 } | 97 } |
| 102 | 98 |
| 103 /** | 99 /** |
| 100 * @param {!SDK.CSSStyleSheetHeader} header | |
| 101 */ | |
| 102 _acceptsHeader(header) { | |
| 103 if (header.isInline && !header.hasSourceURL && header.origin !== 'inspector' ) | |
| 104 return false; | |
| 105 if (!header.resourceURL()) | |
| 106 return false; | |
| 107 return true; | |
| 108 } | |
| 109 | |
| 110 /** | |
| 104 * @param {!Common.Event} event | 111 * @param {!Common.Event} event |
| 105 */ | 112 */ |
| 106 _styleSheetAdded(event) { | 113 _styleSheetAdded(event) { |
| 107 var header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data); | 114 var header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data); |
| 108 var url = header.resourceURL(); | 115 if (!this._acceptsHeader(header)) |
| 109 if (!url) | |
| 110 return; | 116 return; |
| 111 | 117 |
| 112 var map = this._urlToHeadersByFrameId.get(url); | 118 var url = header.resourceURL(); |
| 113 if (!map) { | 119 var styleFile = this._styleFiles.get(url); |
| 114 map = /** @type {!Map.<string, !Map.<string, !SDK.CSSStyleSheetHeader>>} * / (new Map()); | 120 if (!styleFile) { |
| 115 this._urlToHeadersByFrameId.set(url, map); | 121 styleFile = new Bindings.StyleFile(this._cssModel, this._project, header); |
| 122 this._styleFiles.set(url, styleFile); | |
| 123 } else { | |
| 124 styleFile.addHeader(header); | |
| 116 } | 125 } |
| 117 var headersById = map.get(header.frameId); | |
| 118 if (!headersById) { | |
| 119 headersById = /** @type {!Map.<string, !SDK.CSSStyleSheetHeader>} */ (new Map()); | |
| 120 map.set(header.frameId, headersById); | |
| 121 } | |
| 122 headersById.set(header.id, header); | |
| 123 var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForStyleURL(this._wor kspace, url, header); | |
| 124 if (uiSourceCode) | |
| 125 this._bindUISourceCode(uiSourceCode, header); | |
| 126 } | 126 } |
| 127 | 127 |
| 128 /** | 128 /** |
| 129 * @param {!Common.Event} event | 129 * @param {!Common.Event} event |
| 130 */ | 130 */ |
| 131 _styleSheetRemoved(event) { | 131 _styleSheetRemoved(event) { |
| 132 var header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data); | 132 var header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data); |
| 133 if (!this._acceptsHeader(header)) | |
| 134 return; | |
| 133 var url = header.resourceURL(); | 135 var url = header.resourceURL(); |
| 134 if (!url) | 136 var styleFile = this._styleFiles.get(url); |
| 135 return; | 137 if (styleFile.headers().size === 1) { |
| 136 | 138 styleFile.dispose(); |
| 137 var map = this._urlToHeadersByFrameId.get(url); | 139 this._styleFiles.delete(url); |
| 138 console.assert(map); | 140 } else { |
| 139 var headersById = map.get(header.frameId); | 141 styleFile.removeHeader(header); |
| 140 console.assert(headersById); | |
| 141 headersById.delete(header.id); | |
| 142 | |
| 143 if (!headersById.size) { | |
| 144 map.delete(header.frameId); | |
| 145 if (!map.size) { | |
| 146 this._urlToHeadersByFrameId.delete(url); | |
| 147 var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForStyleURL(this. _workspace, url, header); | |
| 148 if (uiSourceCode) | |
| 149 this._unbindUISourceCode(uiSourceCode); | |
| 150 } | |
| 151 } | 142 } |
| 152 } | 143 } |
| 153 | 144 |
| 154 /** | 145 dispose() { |
| 155 * @param {!Workspace.UISourceCode} uiSourceCode | |
| 156 */ | |
| 157 _unbindUISourceCode(uiSourceCode) { | |
| 158 var styleFile = this._styleFiles.get(uiSourceCode); | |
| 159 if (!styleFile) | |
| 160 return; | |
| 161 styleFile.dispose(); | |
| 162 this._styleFiles.delete(uiSourceCode); | |
| 163 } | |
| 164 | |
| 165 /** | |
| 166 * @param {!Common.Event} event | |
| 167 */ | |
| 168 _unbindAllUISourceCodes(event) { | |
| 169 for (var styleFile of this._styleFiles.values()) | 146 for (var styleFile of this._styleFiles.values()) |
| 170 styleFile.dispose(); | 147 styleFile.dispose(); |
| 171 this._styleFiles.clear(); | 148 this._styleFiles.clear(); |
| 172 this._urlToHeadersByFrameId = new Map(); | |
| 173 } | |
| 174 | |
| 175 /** | |
| 176 * @param {!Common.Event} event | |
| 177 */ | |
| 178 _uiSourceCodeAddedToWorkspace(event) { | |
| 179 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); | |
| 180 if (!this._urlToHeadersByFrameId.has(uiSourceCode.url())) | |
| 181 return; | |
| 182 this._bindUISourceCode( | |
| 183 uiSourceCode, this._urlToHeadersByFrameId.get(uiSourceCode.url()).values Array()[0].valuesArray()[0]); | |
| 184 } | |
| 185 | |
| 186 /** | |
| 187 * @param {!Workspace.UISourceCode} uiSourceCode | |
| 188 * @param {!SDK.CSSStyleSheetHeader} header | |
| 189 */ | |
| 190 _bindUISourceCode(uiSourceCode, header) { | |
| 191 if (this._styleFiles.get(uiSourceCode) || (header.isInline && !header.hasSou rceURL)) | |
| 192 return; | |
| 193 this._styleFiles.set(uiSourceCode, new Bindings.StyleFile(uiSourceCode, this )); | |
| 194 Bindings.cssWorkspaceBinding.updateLocations(header); | |
| 195 } | |
| 196 | |
| 197 /** | |
| 198 * @param {!Common.Event} event | |
| 199 */ | |
| 200 _projectRemoved(event) { | |
| 201 var project = /** @type {!Workspace.Project} */ (event.data); | |
| 202 var uiSourceCodes = project.uiSourceCodes(); | |
| 203 for (var i = 0; i < uiSourceCodes.length; ++i) | |
| 204 this._unbindUISourceCode(uiSourceCodes[i]); | |
| 205 } | |
| 206 | |
| 207 /** | |
| 208 * @param {!Common.Event} event | |
| 209 */ | |
| 210 _uiSourceCodeRemoved(event) { | |
| 211 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); | |
| 212 this._unbindUISourceCode(uiSourceCode); | |
| 213 } | |
| 214 | |
| 215 /** | |
| 216 * @param {!Workspace.UISourceCode} uiSourceCode | |
| 217 * @param {string} content | |
| 218 * @param {boolean} majorChange | |
| 219 * @return {!Promise<?string>} | |
| 220 */ | |
| 221 _setStyleContent(uiSourceCode, content, majorChange) { | |
| 222 var styleSheetIds = this._cssModel.styleSheetIdsForURL(uiSourceCode.url()); | |
| 223 if (!styleSheetIds.length) | |
| 224 return Promise.resolve(/** @type {?string} */ ('No stylesheet found: ' + u iSourceCode.url())); | |
| 225 | |
| 226 this._isSettingContent = true; | |
| 227 | |
| 228 /** | |
| 229 * @param {?string} error | |
| 230 * @this {Bindings.StylesSourceMapping} | |
| 231 * @return {?string} | |
| 232 */ | |
| 233 function callback(error) { | |
| 234 delete this._isSettingContent; | |
| 235 return error || null; | |
| 236 } | |
| 237 | |
| 238 var promises = []; | |
| 239 for (var i = 0; i < styleSheetIds.length; ++i) | |
| 240 promises.push(this._cssModel.setStyleSheetText(styleSheetIds[i], content, majorChange)); | |
| 241 | |
| 242 return Promise.all(promises).spread(callback.bind(this)); | |
| 243 } | |
| 244 | |
| 245 /** | |
| 246 * @param {!Common.Event} event | |
| 247 */ | |
| 248 _styleSheetChanged(event) { | |
|
dgozman
2017/05/17 16:46:20
I feel like moving all these method could be postp
lushnikov
2017/05/20 01:24:18
This is possible, though I feel it's harder to val
| |
| 249 if (this._isSettingContent) | |
| 250 return; | |
| 251 | |
| 252 this._updateStyleSheetTextSoon(event.data.styleSheetId); | |
| 253 } | |
| 254 | |
| 255 /** | |
| 256 * @param {!Protocol.CSS.StyleSheetId} styleSheetId | |
| 257 */ | |
| 258 _updateStyleSheetTextSoon(styleSheetId) { | |
| 259 if (this._updateStyleSheetTextTimer) | |
| 260 clearTimeout(this._updateStyleSheetTextTimer); | |
| 261 | |
| 262 this._updateStyleSheetTextTimer = setTimeout( | |
| 263 this._updateStyleSheetText.bind(this, styleSheetId), Bindings.StylesSour ceMapping.ChangeUpdateTimeoutMs); | |
| 264 } | |
| 265 | |
| 266 /** | |
| 267 * @param {!Protocol.CSS.StyleSheetId} styleSheetId | |
| 268 */ | |
| 269 _updateStyleSheetText(styleSheetId) { | |
| 270 if (this._updateStyleSheetTextTimer) { | |
| 271 clearTimeout(this._updateStyleSheetTextTimer); | |
| 272 delete this._updateStyleSheetTextTimer; | |
| 273 } | |
| 274 | |
| 275 var header = this._cssModel.styleSheetHeaderForId(styleSheetId); | |
| 276 if (!header) | |
| 277 return; | |
| 278 var styleSheetURL = header.resourceURL(); | |
| 279 if (!styleSheetURL) | |
| 280 return; | |
| 281 var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForStyleURL(this._wor kspace, styleSheetURL, header); | |
| 282 if (!uiSourceCode) | |
| 283 return; | |
| 284 header.requestContent().then(callback.bind(this, uiSourceCode)); | |
| 285 | |
| 286 /** | |
| 287 * @param {!Workspace.UISourceCode} uiSourceCode | |
| 288 * @param {?string} content | |
| 289 * @this {Bindings.StylesSourceMapping} | |
| 290 */ | |
| 291 function callback(uiSourceCode, content) { | |
| 292 var styleFile = this._styleFiles.get(uiSourceCode); | |
| 293 if (typeof content === 'string' && styleFile) | |
| 294 styleFile.addRevision(content); | |
| 295 this._styleFileSyncedForTest(); | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 _styleFileSyncedForTest() { | |
| 300 } | |
| 301 | |
| 302 dispose() { | |
| 303 Common.EventTarget.removeEventListeners(this._eventListeners); | 149 Common.EventTarget.removeEventListeners(this._eventListeners); |
| 304 } | 150 } |
| 305 }; | 151 }; |
| 306 | 152 |
| 307 Bindings.StylesSourceMapping.ChangeUpdateTimeoutMs = 200; | |
| 308 | |
| 309 /** | 153 /** |
| 310 * @unrestricted | 154 * @unrestricted |
| 311 */ | 155 */ |
| 312 Bindings.StyleFile = class { | 156 Bindings.StyleFile = class { |
| 313 /** | 157 /** |
| 314 * @param {!Workspace.UISourceCode} uiSourceCode | 158 * @param {!SDK.CSSModel} cssModel |
| 315 * @param {!Bindings.StylesSourceMapping} mapping | 159 * @param {!Bindings.ContentProviderBasedProject} project |
| 160 * @param {!SDK.CSSStyleSheetHeader} header | |
| 316 */ | 161 */ |
| 317 constructor(uiSourceCode, mapping) { | 162 constructor(cssModel, project, header) { |
| 318 this._uiSourceCode = uiSourceCode; | 163 this._cssModel = cssModel; |
| 319 this._mapping = mapping; | 164 this._project = project; |
| 165 /** @type {!Set<!SDK.CSSStyleSheetHeader>} */ | |
| 166 this._headers = new Set([header]); | |
| 167 | |
| 168 var target = cssModel.target(); | |
| 169 | |
| 170 var url = header.resourceURL(); | |
| 171 var originalContentProvider = header.originalContentProvider(); | |
| 172 var metadata = Bindings.metadataForURL(target, header.frameId, url); | |
| 173 | |
| 174 this._uiSourceCode = this._project.createUISourceCode(url, originalContentPr ovider.contentType()); | |
| 175 this._uiSourceCode[Bindings.StyleFile._symbol] = this; | |
| 176 Bindings.NetworkProject.setInitialFrameAttribution(this._uiSourceCode, heade r.frameId); | |
| 177 Bindings.NetworkProject.forceCanonicalMimeType(this._uiSourceCode); | |
| 178 this._project.addUISourceCodeWithProvider(this._uiSourceCode, originalConten tProvider, metadata); | |
| 179 | |
| 180 this._styleSheetChangedBound = this._styleSheetChanged.bind(this); | |
| 181 | |
| 182 this._cssModel.subscribeToStyleSheetChanged(header.id, this._styleSheetChang edBound); | |
| 320 this._eventListeners = [ | 183 this._eventListeners = [ |
| 321 this._uiSourceCode.addEventListener( | 184 this._uiSourceCode.addEventListener( |
| 322 Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyCha nged, this), | 185 Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyCha nged, this), |
| 323 this._uiSourceCode.addEventListener( | 186 this._uiSourceCode.addEventListener( |
| 324 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyC ommitted, this) | 187 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyC ommitted, this) |
| 325 ]; | 188 ]; |
| 326 this._commitThrottler = new Common.Throttler(Bindings.StyleFile.updateTimeou t); | 189 this._throttler = new Common.Throttler(Bindings.StyleFile.updateTimeout); |
| 327 this._terminated = false; | 190 this._terminated = false; |
| 328 } | 191 } |
| 329 | 192 |
| 330 /** | 193 /** |
| 194 * @param {!SDK.CSSStyleSheetHeader} header | |
| 195 */ | |
| 196 addHeader(header) { | |
| 197 this._headers.add(header); | |
| 198 this._cssModel.subscribeToStyleSheetChanged(header.id, this._styleSheetChang edBound); | |
| 199 Bindings.NetworkProject.addFrameAttribution(this._uiSourceCode, header.frame Id); | |
| 200 } | |
| 201 | |
| 202 /** | |
| 203 * @param {!SDK.CSSStyleSheetHeader} header | |
| 204 */ | |
| 205 removeHeader(header) { | |
| 206 this._headers.delete(header); | |
| 207 this._cssModel.unsubscribeFromStyleSheetChanged(header.id, this._styleSheetC hangedBound); | |
| 208 Bindings.NetworkProject.removeFrameAttribution(this._uiSourceCode, header.fr ameId); | |
| 209 } | |
| 210 | |
| 211 /** | |
| 212 * @return {!Set<!SDK.CSSStyleSheetHeader>} | |
| 213 */ | |
| 214 headers() { | |
|
dgozman
2017/05/17 16:46:20
I find these "API" methods between tightly coupled
lushnikov
2017/05/20 01:24:18
Agreed and inlined both headers() and uiSourceCode
| |
| 215 return this._headers; | |
| 216 } | |
| 217 | |
| 218 /** | |
| 219 * @return {!Workspace.UISourceCode} | |
| 220 */ | |
| 221 uiSourceCode() { | |
| 222 return this._uiSourceCode; | |
| 223 } | |
| 224 | |
| 225 /** | |
| 226 * @param {!SDK.CSSStyleSheetHeader} header | |
| 227 */ | |
| 228 _styleSheetChanged(header) { | |
| 229 if (this._isUpdatingHeaders) | |
| 230 return; | |
| 231 var mirrorContentBound = this._mirrorContent.bind(this, header, true /* majo rChange */); | |
| 232 this._throttler.schedule(mirrorContentBound, false /* asSoonAsPossible */); | |
| 233 } | |
| 234 | |
| 235 /** | |
| 331 * @param {!Common.Event} event | 236 * @param {!Common.Event} event |
| 332 */ | 237 */ |
| 333 _workingCopyCommitted(event) { | 238 _workingCopyCommitted(event) { |
| 334 if (this._isAddingRevision) | 239 if (this._isAddingRevision) |
| 335 return; | 240 return; |
| 336 | 241 var mirrorContentBound = this._mirrorContent.bind(this, this._uiSourceCode, true /* majorChange */); |
| 337 this._isMajorChangePending = true; | 242 this._throttler.schedule(mirrorContentBound, true /* asSoonAsPossible */); |
| 338 this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), true) ; | |
| 339 } | 243 } |
| 340 | 244 |
| 341 /** | 245 /** |
| 342 * @param {!Common.Event} event | 246 * @param {!Common.Event} event |
| 343 */ | 247 */ |
| 344 _workingCopyChanged(event) { | 248 _workingCopyChanged(event) { |
| 345 if (this._isAddingRevision) | 249 if (this._isAddingRevision) |
| 346 return; | 250 return; |
| 347 | 251 var mirrorContentBound = this._mirrorContent.bind(this, this._uiSourceCode, false /* majorChange */); |
| 348 this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), false ); | 252 this._throttler.schedule(mirrorContentBound, false /* asSoonAsPossible */); |
| 349 } | |
| 350 | |
| 351 _commitIncrementalEdit() { | |
| 352 if (this._terminated) | |
| 353 return; | |
| 354 var promise = | |
| 355 this._mapping._setStyleContent(this._uiSourceCode, this._uiSourceCode.wo rkingCopy(), this._isMajorChangePending) | |
| 356 .then(this._styleContentSet.bind(this)); | |
| 357 this._isMajorChangePending = false; | |
| 358 return promise; | |
| 359 } | 253 } |
| 360 | 254 |
| 361 /** | 255 /** |
| 362 * @param {?string} error | 256 * @param {!Common.ContentProvider} fromProvider |
| 257 * @param {boolean} majorChange | |
| 258 * @return {!Promise} | |
| 363 */ | 259 */ |
| 364 _styleContentSet(error) { | 260 async _mirrorContent(fromProvider, majorChange) { |
| 365 if (error) | 261 var newContent = null; |
| 366 console.error(error); | 262 if (fromProvider === this._uiSourceCode) |
| 263 newContent = this._uiSourceCode.workingCopy(); | |
| 264 else | |
| 265 newContent = await fromProvider.requestContent(); | |
|
dgozman
2017/05/17 16:46:20
Per recent discussions, you have to add comment be
lushnikov
2017/05/20 01:24:18
Added the ASYNC comment.
The previous version of
| |
| 266 | |
| 267 if (newContent === null || this._terminated) { | |
| 268 this._styleFileSyncedForTest(); | |
| 269 return; | |
| 270 } | |
| 271 | |
| 272 if (fromProvider !== this._uiSourceCode) { | |
| 273 this._isAddingRevision = true; | |
| 274 this._uiSourceCode.addRevision(newContent); | |
| 275 this._isAddingRevision = false; | |
| 276 } | |
| 277 | |
| 278 this._isUpdatingHeaders = true; | |
| 279 var promises = []; | |
| 280 for (var header of this._headers) { | |
| 281 if (header === fromProvider) | |
| 282 continue; | |
| 283 promises.push(this._cssModel.setStyleSheetText(header.id, newContent, majo rChange)); | |
| 284 } | |
| 285 var errors = await Promise.all(promises); | |
|
dgozman
2017/05/17 16:46:20
Same here.
lushnikov
2017/05/20 01:24:18
Done.
| |
| 286 this._isUpdatingHeaders = false; | |
| 287 errors.filter(error => !!error).forEach(console.error); | |
| 288 this._styleFileSyncedForTest(); | |
| 367 } | 289 } |
| 368 | 290 |
| 369 /** | 291 _styleFileSyncedForTest() { |
| 370 * @param {string} content | |
| 371 */ | |
| 372 addRevision(content) { | |
| 373 this._isAddingRevision = true; | |
| 374 this._uiSourceCode.addRevision(content); | |
| 375 delete this._isAddingRevision; | |
| 376 } | 292 } |
| 377 | 293 |
| 378 dispose() { | 294 dispose() { |
| 379 if (this._terminated) | 295 if (this._terminated) |
| 380 return; | 296 return; |
| 381 this._terminated = true; | 297 this._terminated = true; |
| 298 for (var header of this._headers) | |
| 299 this._cssModel.unsubscribeFromStyleSheetChanged(header.id, this._styleShee tChangedBound); | |
| 300 this._project.removeFile(this._uiSourceCode.url()); | |
| 382 Common.EventTarget.removeEventListeners(this._eventListeners); | 301 Common.EventTarget.removeEventListeners(this._eventListeners); |
| 383 } | 302 } |
| 384 }; | 303 }; |
| 385 | 304 |
| 305 Bindings.StyleFile._symbol = Symbol('Bindings.StyleFile._symbol'); | |
| 306 | |
| 386 Bindings.StyleFile.updateTimeout = 200; | 307 Bindings.StyleFile.updateTimeout = 200; |
| OLD | NEW |