StylesSourceMapping.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. export default class StylesSourceMapping{constructor(cssModel,workspace){this._cssModel=cssModel;const target=this._cssModel.target();this._project=new Bindings.ContentProviderBasedProject(workspace,'css:'+target.id(),Workspace.projectTypes.Network,'',false);Bindings.NetworkProject.setTargetForProject(this._project,target);this._styleFiles=new Map();this._eventListeners=[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),];}
  2. rawLocationToUILocation(rawLocation){const header=rawLocation.header();if(!header||!this._acceptsHeader(header)){return null;}
  3. const styleFile=this._styleFiles.get(header.resourceURL());if(!styleFile){return null;}
  4. let lineNumber=rawLocation.lineNumber;let columnNumber=rawLocation.columnNumber;if(header.isInline&&header.hasSourceURL){lineNumber-=header.lineNumberInSource(0);columnNumber-=header.columnNumberInSource(lineNumber,0);}
  5. return styleFile._uiSourceCode.uiLocation(lineNumber,columnNumber);}
  6. uiLocationToRawLocations(uiLocation){const styleFile=uiLocation.uiSourceCode[StyleFile._symbol];if(!styleFile){return[];}
  7. const rawLocations=[];for(const header of styleFile._headers){let lineNumber=uiLocation.lineNumber;let columnNumber=uiLocation.columnNumber;if(header.isInline&&header.hasSourceURL){columnNumber=header.columnNumberInSource(lineNumber,columnNumber);lineNumber=header.lineNumberInSource(lineNumber);}
  8. rawLocations.push(new SDK.CSSLocation(header,lineNumber,columnNumber));}
  9. return rawLocations;}
  10. _acceptsHeader(header){if(header.isInline&&!header.hasSourceURL&&header.origin!=='inspector'){return false;}
  11. if(!header.resourceURL()){return false;}
  12. return true;}
  13. _styleSheetAdded(event){const header=(event.data);if(!this._acceptsHeader(header)){return;}
  14. const url=header.resourceURL();let styleFile=this._styleFiles.get(url);if(!styleFile){styleFile=new StyleFile(this._cssModel,this._project,header);this._styleFiles.set(url,styleFile);}else{styleFile.addHeader(header);}}
  15. _styleSheetRemoved(event){const header=(event.data);if(!this._acceptsHeader(header)){return;}
  16. const url=header.resourceURL();const styleFile=this._styleFiles.get(url);if(styleFile._headers.size===1){styleFile.dispose();this._styleFiles.delete(url);}else{styleFile.removeHeader(header);}}
  17. _styleSheetChanged(event){const header=this._cssModel.styleSheetHeaderForId(event.data.styleSheetId);if(!header||!this._acceptsHeader(header)){return;}
  18. const styleFile=this._styleFiles.get(header.resourceURL());styleFile._styleSheetChanged(header);}
  19. dispose(){for(const styleFile of this._styleFiles.values()){styleFile.dispose();}
  20. this._styleFiles.clear();Common.EventTarget.removeEventListeners(this._eventListeners);this._project.removeProject();}}
  21. export class StyleFile{constructor(cssModel,project,header){this._cssModel=cssModel;this._project=project;this._headers=new Set([header]);const target=cssModel.target();const url=header.resourceURL();const metadata=Bindings.metadataForURL(target,header.frameId,url);this._uiSourceCode=this._project.createUISourceCode(url,header.contentType());this._uiSourceCode[StyleFile._symbol]=this;Bindings.NetworkProject.setInitialFrameAttribution(this._uiSourceCode,header.frameId);this._project.addUISourceCodeWithProvider(this._uiSourceCode,this,metadata,'text/css');this._eventListeners=[this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged,this._workingCopyChanged,this),this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted,this._workingCopyCommitted,this)];this._throttler=new Common.Throttler(StyleFile.updateTimeout);this._terminated=false;}
  22. addHeader(header){this._headers.add(header);Bindings.NetworkProject.addFrameAttribution(this._uiSourceCode,header.frameId);}
  23. removeHeader(header){this._headers.delete(header);Bindings.NetworkProject.removeFrameAttribution(this._uiSourceCode,header.frameId);}
  24. _styleSheetChanged(header){console.assert(this._headers.has(header));if(this._isUpdatingHeaders||!this._headers.has(header)){return;}
  25. const mirrorContentBound=this._mirrorContent.bind(this,header,true);this._throttler.schedule(mirrorContentBound,false);}
  26. _workingCopyCommitted(event){if(this._isAddingRevision){return;}
  27. const mirrorContentBound=this._mirrorContent.bind(this,this._uiSourceCode,true);this._throttler.schedule(mirrorContentBound,true);}
  28. _workingCopyChanged(event){if(this._isAddingRevision){return;}
  29. const mirrorContentBound=this._mirrorContent.bind(this,this._uiSourceCode,false);this._throttler.schedule(mirrorContentBound,false);}
  30. async _mirrorContent(fromProvider,majorChange){if(this._terminated){this._styleFileSyncedForTest();return;}
  31. let newContent=null;if(fromProvider===this._uiSourceCode){newContent=this._uiSourceCode.workingCopy();}else{const deferredContent=await fromProvider.requestContent();newContent=deferredContent.content;}
  32. if(newContent===null||this._terminated){this._styleFileSyncedForTest();return;}
  33. if(fromProvider!==this._uiSourceCode){this._isAddingRevision=true;this._uiSourceCode.addRevision(newContent);this._isAddingRevision=false;}
  34. this._isUpdatingHeaders=true;const promises=[];for(const header of this._headers){if(header===fromProvider){continue;}
  35. promises.push(this._cssModel.setStyleSheetText(header.id,newContent,majorChange));}
  36. await Promise.all(promises);this._isUpdatingHeaders=false;this._styleFileSyncedForTest();}
  37. _styleFileSyncedForTest(){}
  38. dispose(){if(this._terminated){return;}
  39. this._terminated=true;this._project.removeFile(this._uiSourceCode.url());Common.EventTarget.removeEventListeners(this._eventListeners);}
  40. contentURL(){return this._headers.firstValue().originalContentProvider().contentURL();}
  41. contentType(){return this._headers.firstValue().originalContentProvider().contentType();}
  42. contentEncoded(){return this._headers.firstValue().originalContentProvider().contentEncoded();}
  43. requestContent(){return this._headers.firstValue().originalContentProvider().requestContent();}
  44. searchInContent(query,caseSensitive,isRegex){return this._headers.firstValue().originalContentProvider().searchInContent(query,caseSensitive,isRegex);}}
  45. StyleFile._symbol=Symbol('Bindings.StyleFile._symbol');StyleFile.updateTimeout=200;self.Bindings=self.Bindings||{};Bindings=Bindings||{};Bindings.StylesSourceMapping=StylesSourceMapping;Bindings.StyleFile=StyleFile;