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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/bindings/StylesSourceMapping.js

Issue 2893523002: DevTools: make StyleSourceMapping in charge of managing UISourceCodes (Closed)
Patch Set: update test Created 3 years, 7 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 unified diff | Download patch
OLDNEW
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
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;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698