diff options
11 files changed, 168 insertions, 780 deletions
diff --git a/third_party/WebKit/LayoutTests/inspector/sass/sass-test.js b/third_party/WebKit/LayoutTests/inspector/sass/sass-test.js index 96eb57f..3fd00a2 100644 --- a/third_party/WebKit/LayoutTests/inspector/sass/sass-test.js +++ b/third_party/WebKit/LayoutTests/inspector/sass/sass-test.js @@ -2,26 +2,18 @@ var initialize_SassTest = function() { InspectorTest.preloadModule("sass"); -var sassWorkspaceAdapter = null; -InspectorTest.sassWorkspaceAdapter = function() -{ - if (!sassWorkspaceAdapter) - sassWorkspaceAdapter = new WebInspector.SASSWorkspaceAdapter(InspectorTest.cssModel, WebInspector.workspace, WebInspector.networkMapping); - return sassWorkspaceAdapter; -} +var cssParserService = null; -var cssParser = null; - -InspectorTest.cssParser = function() +InspectorTest.cssParserService = function() { - if (!cssParser) - cssParser = new WebInspector.CSSParser(); - return cssParser; + if (!cssParserService) + cssParserService = new WebInspector.CSSParserService(); + return cssParserService; } InspectorTest.parseCSS = function(url, text) { - return WebInspector.SASSSupport.parseCSS(InspectorTest.cssParser(), url, text); + return WebInspector.SASSSupport.parseCSS(InspectorTest.cssParserService(), url, text); } InspectorTest.parseSCSS = function(url, text) @@ -31,37 +23,22 @@ InspectorTest.parseSCSS = function(url, text) function onTokenizer(tokenizer) { - return WebInspector.SASSSupport.parseSCSS(url, text, tokenizer); + return WebInspector.SASSSupport.parseSCSS(tokenizer, url, text); } } InspectorTest.loadASTMapping = function(header, callback) { - console.assert(header.cssModel() === InspectorTest.sassWorkspaceAdapter()._cssModel, "The header could not be processed by main target workspaceAdapter"); - var tokenizerFactory = null; - var sourceMap = null; var completeSourceMapURL = WebInspector.ParsedURL.completeURL(header.sourceURL, header.sourceMapURL); WebInspector.SourceMap.load(completeSourceMapURL, header.sourceURL, onSourceMapLoaded); - self.runtime.instancePromise(WebInspector.TokenizerFactory) - .then(tf => tokenizerFactory = tf) - .then(maybeStartLoading); - - function onSourceMapLoaded(sm) - { - sourceMap = sm; - maybeStartLoading(); - } - - function maybeStartLoading() + function onSourceMapLoaded(sourceMap) { - if (!sourceMap || !tokenizerFactory) - return; - var client = InspectorTest.sassWorkspaceAdapter().trackSources(sourceMap); - WebInspector.SASSLiveSourceMap._loadMapping(client, InspectorTest.cssParser(), tokenizerFactory, sourceMap) - .then(callback) - .then(() => client.dispose()) + var astService = new WebInspector.ASTService(); + WebInspector.SASSLiveSourceMap._createASTMapping(astService, header.cssModel(), sourceMap) + .then(mapping => callback(mapping)) + .then(() => astService.dispose()); } } diff --git a/third_party/WebKit/LayoutTests/inspector/sass/test-workspace-adapter-expected.txt b/third_party/WebKit/LayoutTests/inspector/sass/test-workspace-adapter-expected.txt deleted file mode 100644 index b230107..0000000 --- a/third_party/WebKit/LayoutTests/inspector/sass/test-workspace-adapter-expected.txt +++ /dev/null @@ -1,73 +0,0 @@ -Verify SourceMapTracker functionality. - - -Running: loadFileSystemResources - -Running: loadCSSResources - -Running: mutateCSS - -- TRACKER 1 -- SourceChanged event: all.css - -- TRACKER 1 -- SourceChanged event: all.css -== Outdated == -TRACKER 1: true -TRACKER 2: false - -- TRACKER 2 -- SourceChanged event: print.css -== Outdated == -TRACKER 1: true -TRACKER 2: true -== Contents == -content of print.css: <all.css update 1> -content of print.css: <print.css update 1> -== Outdated == -TRACKER 1: false -TRACKER 2: false - -Running: mutateSASS - -- TRACKER 1 -- SourceChanged event: file:///var/www/a.scss -== Outdated == -TRACKER 1: true -TRACKER 2: false - -- TRACKER 2 -- SourceChanged event: file:///var/www/b.scss -== Outdated == -TRACKER 1: true -TRACKER 2: true -== Contents == -content of file:///var/www/b.scss: <a.scss update 1> -content of file:///var/www/b.scss: <b.scss update 1> -== Outdated == -TRACKER 1: false -TRACKER 2: false - -Running: mutateSASSCommon - -- TRACKER 1 -- SourceChanged event: file:///var/www/common.scss - -- TRACKER 2 -- SourceChanged event: file:///var/www/common.scss -== Outdated == -TRACKER 1: true -TRACKER 2: true -== Contents == -content of file:///var/www/common.scss: <common.scss update 1> -content of file:///var/www/common.scss: <common.scss update 1> -== Outdated == -TRACKER 1: false -TRACKER 2: false - -Running: trackerSetCSS -tracker1.setCSSText result: true -tracker2.setCSSText result: true -== Contents == -content of print.css: <all.css TRACKER 1> -content of print.css: <print.css TRACKER 2> - -Running: trackerSetSASSCommon -tracker1.setSASSText result: true - -- TRACKER 2 -- SourceChanged event: file:///var/www/common.scss -== Outdated == -TRACKER 1: false -TRACKER 2: true - -Running: removeFirstTrackerStyleSheets - -- TRACKER 1 -- TrackingStopped - -Running: removeSecondTrackerStyleSheets - -- TRACKER 2 -- TrackingStopped - diff --git a/third_party/WebKit/LayoutTests/inspector/sass/test-workspace-adapter.html b/third_party/WebKit/LayoutTests/inspector/sass/test-workspace-adapter.html deleted file mode 100644 index 9243eed..0000000 --- a/third_party/WebKit/LayoutTests/inspector/sass/test-workspace-adapter.html +++ /dev/null @@ -1,189 +0,0 @@ -<html> -<head> - -<script src="../../http/tests/inspector/inspector-test.js"></script> -<script src="../../http/tests/inspector/debugger-test.js"></script> -<script src="../../http/tests/inspector/isolated-filesystem-test.js"></script> -<script src="./sass-test.js"></script> -<script> - -var styles = []; -function addStyleSheets() -{ - for (var i = 0; i < 2; ++i) { - var style = document.createElement("style"); - style.textContent = "<all.css content>\n/*# sourceURL=all.css */"; - document.head.appendChild(style); - styles.push(style); - } - - var style = document.createElement("style"); - style.textContent = "<print.css content>\n/*# sourceURL=print.css */"; - document.head.appendChild(style); - styles.push(style); -} - -function removeStyles(amount) -{ - for (var i = 0; i < amount; ++i) - styles.shift().remove(); -} - -function test() -{ - function createTracker(trackerName, cssURL, sassURLs) - { - var sources = sassURLs; - var fakeSourceMap = { - sources: () => sources, - compiledURL: () => cssURL - }; - var tracker = InspectorTest.sassWorkspaceAdapter().trackSources(fakeSourceMap); - tracker.__NAME = trackerName; - tracker.addEventListener(WebInspector.SourceMapTracker.Events.SourceChanged, onSourceChanged); - tracker.addEventListener(WebInspector.SourceMapTracker.Events.TrackingStopped, onTrackingStopped); - return tracker; - - function onSourceChanged(event) - { - InspectorTest.addResult(" -- " + event.target.__NAME + " -- SourceChanged event: " + event.data); - } - - function onTrackingStopped(event) - { - InspectorTest.addResult(" -- " + event.target.__NAME + " -- TrackingStopped"); - } - } - - var fileSystemPrefix = "file:///var/www"; - var css1 = "all.css"; - var css2 = "print.css"; - var sass1 = fileSystemPrefix + "/a.scss"; - var sass2 = fileSystemPrefix + "/b.scss"; - var sassCommon = fileSystemPrefix + "/common.scss"; - var tracker1 = createTracker("TRACKER 1", css1, [sass1, sassCommon]); - var tracker2 = createTracker("TRACKER 2", css2, [sass2, sassCommon]); - - InspectorTest.runTestSuite([ - function loadFileSystemResources(next) - { - var fs = new InspectorTest.TestFileSystem(fileSystemPrefix); - fs.addFileMapping(fileSystemPrefix, "/"); - fs.root.addFile("common.scss", "<common.scss content>"); - fs.root.addFile("a.scss", "<a.scss content>"); - fs.root.addFile("b.scss", "<b.scss content>"); - fs.reportCreated(next); - }, - - function loadCSSResources(next) - { - InspectorTest.evaluateInPage("addStyleSheets()", next); - }, - - function mutateCSS(next) - { - InspectorTest.updateCSSText(css1, "<all.css update 1>") - .then(checkOutdated) - .then(() => InspectorTest.updateCSSText(css2, "<print.css update 1>")) - .then(checkOutdated) - .then(() => requestContent([css1], [css2])) - .then(checkOutdated) - .then(next); - }, - - function mutateSASS(next) - { - InspectorTest.updateSASSText(sass1, "<a.scss update 1>"); - checkOutdated(); - InspectorTest.updateSASSText(sass2, "<b.scss update 1>"); - checkOutdated(); - requestContent([sass1], [sass2]) - .then(checkOutdated) - .then(next); - }, - - function mutateSASSCommon(next) - { - InspectorTest.updateSASSText(sassCommon, "<common.scss update 1>"); - checkOutdated(); - requestContent([sassCommon], [sassCommon]) - .then(checkOutdated) - .then(next); - }, - - function trackerSetCSS(next) - { - var result = tracker1.setCSSText("<all.css TRACKER 1>", []); - InspectorTest.addResult("tracker1.setCSSText result: " + result); - var result = tracker2.setCSSText("<print.css TRACKER 2>", []); - InspectorTest.addResult("tracker2.setCSSText result: " + result); - requestContent([css1], [css2]) - .then(next); - }, - - function trackerSetSASSCommon(next) - { - var result = tracker1.setSASSText(sassCommon, "<common.scss TRACKER 1>"); - InspectorTest.addResult("tracker1.setSASSText result: " + result); - awaitSourceChanges(tracker2, sassCommon) - .then(checkOutdated) - .then(next); - }, - - function removeFirstTrackerStyleSheets(next) - { - InspectorTest.evaluateInPage("removeStyles(2)", next); - }, - - function removeSecondTrackerStyleSheets(next) - { - InspectorTest.evaluateInPage("removeStyles(1)", next); - }, - ]); - - function awaitSourceChanges(tracker, url) - { - var callback; - var promise = new Promise(fulfill => callback = fulfill); - tracker.addEventListener(WebInspector.SourceMapTracker.Events.SourceChanged, onSourceChanged); - return promise; - - function onSourceChanged(event) - { - if (event.data !== url) - return; - tracker.removeEventListener(WebInspector.SourceMapTracker.Events.SourceChanged, onSourceChanged); - callback(); - } - } - - function checkOutdated() - { - InspectorTest.addResult("== Outdated =="); - InspectorTest.addResult(tracker1.__NAME + ": " + tracker1.isOutdated()); - InspectorTest.addResult(tracker2.__NAME + ": " + tracker2.isOutdated()); - } - - function requestContent(urls1, urls2) - { - InspectorTest.addResult("== Contents =="); - urls1 = urls1 || []; - urls2 = urls2 || []; - var onContent = (url, content) => InspectorTest.addResult("content of " + url + ": " + content); - var promises = []; - for (var url of urls1) - promises.push(tracker1.content(url).then(text => onContent(url, text))); - for (var url of urls2) - promises.push(tracker2.content(url).then(text => onContent(url, text))); - return Promise.all(promises); - } -} - -</script> - -</head> - -<body onload="runTest()"> -<p>Verify SourceMapTracker functionality.</p> -</body> -</html> diff --git a/third_party/WebKit/Source/devtools/devtools.gypi b/third_party/WebKit/Source/devtools/devtools.gypi index 7b940d2..9f902ef 100644 --- a/third_party/WebKit/Source/devtools/devtools.gypi +++ b/third_party/WebKit/Source/devtools/devtools.gypi @@ -118,8 +118,8 @@ 'front_end/host/UserMetrics.js', ], 'devtools_sass_js_files': [ + 'front_end/sass/ASTService.js', 'front_end/sass/SASSLiveSourceMap.js', - 'front_end/sass/SASSWorkspaceAdapter.js', 'front_end/sass/SASSSupport.js', ], 'devtools_screencast_js_files': [ diff --git a/third_party/WebKit/Source/devtools/front_end/sass/ASTService.js b/third_party/WebKit/Source/devtools/front_end/sass/ASTService.js new file mode 100644 index 0000000..4d6e2ba --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/sass/ASTService.js @@ -0,0 +1,45 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @constructor + */ +WebInspector.ASTService = function() +{ + this._cssParserService = new WebInspector.CSSParserService(); + this._sassInitPromise = self.runtime.instancePromise(WebInspector.TokenizerFactory); + this._terminated = false; +} + +WebInspector.ASTService.prototype = { + /** + * @param {string} url + * @param {string} text + * @return {!Promise<!WebInspector.SASSSupport.AST>} + */ + parseCSS: function(url, text) + { + console.assert(!this._terminated, "Illegal call parseCSS on terminated ASTService."); + return WebInspector.SASSSupport.parseCSS(this._cssParserService, url, text); + }, + + /** + * @param {string} url + * @param {string} text + * @return {!Promise<!WebInspector.SASSSupport.AST>} + */ + parseSCSS: function(url, text) + { + console.assert(!this._terminated, "Illegal call parseSCSS on terminated ASTService."); + return this._sassInitPromise.then(tokenizer => WebInspector.SASSSupport.parseSCSS(tokenizer, url, text)); + }, + + dispose: function() + { + if (this._terminated) + return; + this._terminated = true; + this._cssParserService.dispose(); + }, +} diff --git a/third_party/WebKit/Source/devtools/front_end/sass/SASSLiveSourceMap.js b/third_party/WebKit/Source/devtools/front_end/sass/SASSLiveSourceMap.js index 6c49db3..ba772cf 100644 --- a/third_party/WebKit/Source/devtools/front_end/sass/SASSLiveSourceMap.js +++ b/third_party/WebKit/Source/devtools/front_end/sass/SASSLiveSourceMap.js @@ -5,29 +5,35 @@ WebInspector.SASSLiveSourceMap = {} /** - * @param {!WebInspector.SourceMapTracker} tracker - * @param {!WebInspector.CSSParser} cssParser - * @param {!WebInspector.TokenizerFactory} tokenizer + * @param {!WebInspector.ASTService} astService + * @param {!WebInspector.CSSStyleModel} cssModel + * @param {!WebInspector.SourceMap} sourceMap * @return {!Promise<?WebInspector.SASSLiveSourceMap.CSSToSASSMapping>} */ -WebInspector.SASSLiveSourceMap._loadMapping = function(tracker, cssParser, tokenizer) +WebInspector.SASSLiveSourceMap._createASTMapping = function(astService, cssModel, sourceMap) { + var headerIds = cssModel.styleSheetIdsForURL(sourceMap.compiledURL()); + if (!headerIds || !headerIds.length) + return Promise.resolve(/** @type {?WebInspector.SASSLiveSourceMap.CSSToSASSMapping} */(null)); + var header = cssModel.styleSheetHeaderForId(headerIds[0]); + var sassModels = new Map(); var cssAST = null; var promises = []; - for (var url of tracker.sassURLs()) { - var sassPromise = tracker.content(url) - .then(text => WebInspector.SASSSupport.parseSCSS(url, text, tokenizer)) + for (var url of sourceMap.sources()) { + var contentProvider = sourceMap.sourceContentProvider(url, WebInspector.resourceTypes.SourceMapStyleSheet); + var sassPromise = contentProvider.requestContent() + .then(text => astService.parseSCSS(url, text || "")) .then(ast => sassModels.set(url, ast)); promises.push(sassPromise); } - var cssPromise = tracker.content(tracker.cssURL()) - .then(text => WebInspector.SASSSupport.parseCSS(cssParser, tracker.cssURL(), text)) + var cssPromise = header.requestContent() + .then(text => astService.parseCSS(sourceMap.compiledURL(), text || "")) .then(ast => cssAST = ast); promises.push(cssPromise); return Promise.all(promises) - .then(() => WebInspector.SASSLiveSourceMap.CSSToSASSMapping.fromSourceMap(tracker.sourceMap(), cssAST, sassModels)) + .then(() => WebInspector.SASSLiveSourceMap.CSSToSASSMapping.fromSourceMap(sourceMap, cssAST, sassModels)) .catchException(/** @type {?WebInspector.SASSLiveSourceMap.CSSToSASSMapping} */(null)); } diff --git a/third_party/WebKit/Source/devtools/front_end/sass/SASSSupport.js b/third_party/WebKit/Source/devtools/front_end/sass/SASSSupport.js index 0ed1943..7120d7f 100644 --- a/third_party/WebKit/Source/devtools/front_end/sass/SASSSupport.js +++ b/third_party/WebKit/Source/devtools/front_end/sass/SASSSupport.js @@ -5,14 +5,14 @@ WebInspector.SASSSupport = {} /** - * @param {!WebInspector.CSSParser} parser + * @param {!WebInspector.CSSParserService} cssParserService * @param {string} url * @param {string} text * @return {!Promise<!WebInspector.SASSSupport.AST>} */ -WebInspector.SASSSupport.parseCSS = function(parser, url, text) +WebInspector.SASSSupport.parseCSS = function(cssParserService, url, text) { - return parser.parsePromise(text) + return cssParserService.parseCSS(text) .then(onParsed); /** @@ -42,12 +42,12 @@ WebInspector.SASSSupport.parseCSS = function(parser, url, text) } /** + * @param {!WebInspector.TokenizerFactory} tokenizerFactory * @param {string} url * @param {string} text - * @param {!WebInspector.TokenizerFactory} tokenizerFactory * @return {!WebInspector.SASSSupport.AST} */ -WebInspector.SASSSupport.parseSCSS = function(url, text, tokenizerFactory) +WebInspector.SASSSupport.parseSCSS = function(tokenizerFactory, url, text) { var document = new WebInspector.SASSSupport.ASTDocument(url, text); var result = WebInspector.SASSSupport._innerParseSCSS(document, tokenizerFactory); diff --git a/third_party/WebKit/Source/devtools/front_end/sass/SASSWorkspaceAdapter.js b/third_party/WebKit/Source/devtools/front_end/sass/SASSWorkspaceAdapter.js deleted file mode 100644 index 5dc3292..0000000 --- a/third_party/WebKit/Source/devtools/front_end/sass/SASSWorkspaceAdapter.js +++ /dev/null @@ -1,461 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @constructor - * @param {!WebInspector.CSSStyleModel} cssModel - * @param {!WebInspector.Workspace} workspace - * @param {!WebInspector.NetworkMapping} networkMapping - */ -WebInspector.SASSWorkspaceAdapter = function(cssModel, workspace, networkMapping) -{ - this._workspace = workspace; - this._networkMapping = networkMapping; - this._cssModel = cssModel; - - /** @type {!Map<string, number>} */ - this._versions = new Map(); - /** @type {!Map<string, !Promise<boolean>>} */ - this._awaitingPromises = new Map(); - /** @type {!Map<string, function(boolean)>} */ - this._awaitingFulfills = new Map(); - - /** @type {!Multimap<string, !WebInspector.SourceMapTracker>} */ - this._urlToTrackers = new Multimap(); - /** @type {!Set<string>} */ - this._cssURLs = new Set(); - - this._eventListeners = [ - this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this), - this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this), - this._workspace.addEventListener(WebInspector.Workspace.Events.WorkingCopyChanged, this._uiSourceCodeChanged, this), - this._workspace.addEventListener(WebInspector.Workspace.Events.WorkingCopyCommitted, this._uiSourceCodeChanged, this), - this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this), - this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this), - this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetChanged, this) - ]; -} - -/** - * @constructor - * @param {string} url - * @param {number} version - * @param {string} text - */ -WebInspector.SASSWorkspaceAdapter.ContentResponse = function(url, version, text) -{ - this.url = url; - this.version = version; - this.text = text; -} - -WebInspector.SASSWorkspaceAdapter.prototype = { - /** - * @param {!WebInspector.SourceMap} sourceMap - * @return {!WebInspector.SourceMapTracker} - */ - trackSources: function(sourceMap) - { - var cssURL = sourceMap.compiledURL(); - this._cssURLs.add(cssURL); - - var allSources = new Set(sourceMap.sources().concat(cssURL)); - for (var sourceURL of allSources) { - if (this._versions.has(sourceURL)) - continue; - this._versions.set(sourceURL, 1); - var promise = new Promise(fulfill => this._awaitingFulfills.set(sourceURL, fulfill)); - this._awaitingPromises.set(sourceURL, promise); - var contentProvider = sourceURL === cssURL ? this._headersForURL(sourceURL).peekLast() : this._sassUISourceCode(sourceURL); - if (contentProvider) - this._contentProviderAdded(sourceURL); - } - - var tracker = new WebInspector.SourceMapTracker(this, sourceMap); - for (var sourceURL of tracker.allURLs()) - this._urlToTrackers.set(sourceURL, tracker); - return tracker; - }, - - /** - * @param {!WebInspector.SourceMapTracker} tracker - */ - _stopTrackSources: function(tracker) - { - for (var sourceURL of tracker.allURLs()) { - this._urlToTrackers.remove(sourceURL, tracker); - if (!this._urlToTrackers.has(sourceURL)) { - this._awaitingFulfills.get(sourceURL).call(null, false); - this._awaitingFulfills.delete(sourceURL); - this._awaitingPromises.delete(sourceURL); - this._versions.delete(sourceURL); - this._cssURLs.delete(sourceURL); - } - } - }, - - /** - * @param {string} url - * @return {?WebInspector.UISourceCode} - */ - _sassUISourceCode: function(url) - { - return this._networkMapping.uiSourceCodeForURLForAnyTarget(url); - }, - - /** - * @param {string} url - * @return {!Array<!WebInspector.CSSStyleSheetHeader>} - */ - _headersForURL: function(url) - { - return this._cssModel.styleSheetIdsForURL(url) - .map(styleSheetId => this._cssModel.styleSheetHeaderForId(styleSheetId)); - }, - - /** - * @param {string} url - */ - _contentProviderAdded: function(url) - { - this._awaitingFulfills.get(url).call(null, true); - }, - - /** - * @param {string} url - */ - _contentProviderRemoved: function(url) - { - var trackers = new Set(this._urlToTrackers.get(url)); - for (var tracker of trackers) - tracker.dispose(); - }, - - /** - * @param {string} url - * @return {boolean} - */ - _isSASSURL: function(url) - { - return this._versions.has(url) && !this._cssURLs.has(url); - }, - - /** - * @param {!WebInspector.Event} event - */ - _uiSourceCodeAdded: function(event) - { - var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.data); - var url = this._networkMapping.networkURL(uiSourceCode); - if (!this._isSASSURL(url)) - return; - this._contentProviderAdded(url); - }, - - /** - * @param {!WebInspector.Event} event - */ - _uiSourceCodeRemoved: function(event) - { - var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.data); - var url = this._networkMapping.networkURL(uiSourceCode); - if (!this._isSASSURL(url)) - return; - this._contentProviderRemoved(url); - }, - - /** - * @param {!WebInspector.Event} event - */ - _styleSheetAdded: function(event) - { - var styleSheetHeader = /** @type {!WebInspector.CSSStyleSheetHeader} */(event.data); - var url = styleSheetHeader.sourceURL; - if (!this._cssURLs.has(url)) - return; - this._contentProviderAdded(url); - }, - - /** - * @param {!WebInspector.Event} event - */ - _styleSheetRemoved: function(event) - { - var styleSheetHeader = /** @type {!WebInspector.CSSStyleSheetHeader} */(event.data); - var url = styleSheetHeader.sourceURL; - if (!this._cssURLs.has(url)) - return; - var headers = this._headersForURL(url); - if (headers.length) - return; - this._contentProviderRemoved(url); - }, - - /** - * @param {!WebInspector.Event} event - */ - _uiSourceCodeChanged: function(event) - { - var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.data.uiSourceCode); - var url = this._networkMapping.networkURL(uiSourceCode); - if (!this._isSASSURL(url)) - return; - this._newContentAvailable(url); - }, - - /** - * @param {!WebInspector.Event} event - */ - _styleSheetChanged: function(event) - { - var styleSheetId = /** @type {!CSSAgent.StyleSheetId} */(event.data.styleSheetId); - var styleSheetHeader = this._cssModel.styleSheetHeaderForId(styleSheetId); - var url = styleSheetHeader.sourceURL; - if (!this._cssURLs.has(url)) - return; - this._newContentAvailable(url); - }, - - /** - * @param {string} url - */ - _newContentAvailable: function(url) - { - console.assert(this._versions.has(url), "The '" + url + "' is not tracked.") - var newVersion = this._versions.get(url) + 1; - this._versions.set(url, newVersion); - for (var tracker of this._urlToTrackers.get(url)) - tracker._newContentAvailable(url, newVersion); - }, - - /** - * @param {string} url - * @return {number} - */ - _urlVersion: function(url) - { - var version = this._versions.get(url); - console.assert(version, "The '" + url + "' is not tracked.") - return version || 0; - }, - - /** - * @param {string} url - * @return {!Promise<?WebInspector.SASSWorkspaceAdapter.ContentResponse>} - */ - _getContent: function(url) - { - console.assert(this._awaitingPromises.has(url), "The '" + url + "' is not tracked.") - return this._awaitingPromises.get(url) - .then(onContentProviderResolved.bind(this)); - - /** - * @param {boolean} success - * @return {!Promise<?WebInspector.SASSWorkspaceAdapter.ContentResponse>} - * @this {WebInspector.SASSWorkspaceAdapter} - */ - function onContentProviderResolved(success) - { - if (!success) - return Promise.resolve(/** @type {?WebInspector.SASSWorkspaceAdapter.ContentResponse} */(null)); - var contentProvider = this._cssURLs.has(url) ? this._headersForURL(url).peekLast() : this._sassUISourceCode(url); - if (!contentProvider) - return Promise.resolve(/** @type {?WebInspector.SASSWorkspaceAdapter.ContentResponse} */(null)); - return contentProvider.requestContent() - .then(text => new WebInspector.SASSWorkspaceAdapter.ContentResponse(url, /** @type {number} */(this._versions.get(url)), text || "")); - } - }, - - /** - * @param {string} url - * @param {string} text - * @return {?WebInspector.SASSWorkspaceAdapter.ContentResponse} - */ - _setSASSText: function(url, text) - { - console.assert(this._isSASSURL(url), "The url '" + url + "' should be a tracked SASS url"); - var uiSourceCode = this._sassUISourceCode(url); - if (!uiSourceCode) - return null; - setImmediate(() => uiSourceCode.addRevision(text)); - var futureVersion = this._versions.get(url) + 1; - return new WebInspector.SASSWorkspaceAdapter.ContentResponse(url, futureVersion, text); - }, - - /** - * @param {string} url - * @param {string} text - * @param {!Array<!WebInspector.SourceEdit>} cssEdits - * @return {?WebInspector.SASSWorkspaceAdapter.ContentResponse} - */ - _setCSSText: function(url, text, cssEdits) - { - console.assert(this._cssURLs.has(url), "The url '" + url + "' should be a tracked CSS url"); - var headers = this._headersForURL(url); - if (!headers.length) - return null; - for (var i = 0; i < headers.length; ++i) - this._cssModel.setStyleSheetText(headers[i].id, text, true); - for (var i = cssEdits.length - 1; i >= 0; --i) { - var edit = cssEdits[i]; - var oldRange = edit.oldRange; - var newRange = edit.newRange(); - for (var j = 0; j < headers.length; ++j) { - this._cssModel.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.ExternalRangeEdit, { - styleSheetId: headers[j].id, - oldRange: oldRange, - newRange: newRange - }); - } - } - var futureVersion = this._versions.get(url) + headers.length; - return new WebInspector.SASSWorkspaceAdapter.ContentResponse(url, futureVersion, text); - } -} - -/** - * @constructor - * @extends {WebInspector.Object} - * @param {!WebInspector.SASSWorkspaceAdapter} adapter - * @param {!WebInspector.SourceMap} sourceMap - */ -WebInspector.SourceMapTracker = function(adapter, sourceMap) -{ - WebInspector.Object.call(this); - this._adapter = adapter; - this._sourceMap = sourceMap; - this._cssURL = sourceMap.compiledURL(); - this._sassURLs = sourceMap.sources().slice(); - this._allURLs = this._sassURLs.concat(this._cssURL); - this._terminated = false; - this._versions = new Map(); - for (var url of this._allURLs) - this._versions.set(url, adapter._urlVersion(url)); -} - -/** @enum {string} */ -WebInspector.SourceMapTracker.Events = { - SourceChanged: "SourceChanged", - TrackingStopped: "TrackingStopped" -} - -WebInspector.SourceMapTracker.prototype = { - /** - * @return {!WebInspector.SourceMap} - */ - sourceMap: function() - { - return this._sourceMap; - }, - - /** - * @return {!Array<string>} - */ - allURLs: function() - { - return this._allURLs; - }, - - /** - * @return {string} - */ - cssURL: function() - { - return this._cssURL; - }, - - /** - * @return {!Array<string>} - */ - sassURLs: function() - { - return this._sassURLs; - }, - - /** - * @return {boolean} - */ - isOutdated: function() - { - if (this._terminated) - return true; - for (var url of this._allURLs) { - if (this._adapter._urlVersion(url) > this._versions.get(url)) - return true; - } - return false; - }, - - /** - * @param {string} text - * @param {!Array<!WebInspector.SourceEdit>} edits - * @return {boolean} - */ - setCSSText: function(text, edits) - { - if (this._terminated || this.isOutdated()) - return false; - var result = this._adapter._setCSSText(this._cssURL, text, edits); - this._handleContentResponse(result); - return !!result; - }, - - /** - * @param {string} url - * @param {string} text - * @return {boolean} - */ - setSASSText: function(url, text) - { - if (this._terminated || this.isOutdated()) - return false; - var result = this._adapter._setSASSText(url, text); - this._handleContentResponse(result); - return !!result; - }, - - /** - * @param {?WebInspector.SASSWorkspaceAdapter.ContentResponse} contentResponse - * @return {?string} - */ - _handleContentResponse: function(contentResponse) - { - if (!contentResponse) - return null; - this._versions.set(contentResponse.url, contentResponse.version); - return contentResponse.text; - }, - - /** - * @param {string} url - * @return {!Promise<string>} - */ - content: function(url) - { - return this._adapter._getContent(url) - .then(this._handleContentResponse.bind(this)) - .then(text => text || ""); - }, - - dispose: function() - { - if (this._terminated) - return; - this._terminated = true; - this._adapter._stopTrackSources(this); - this.dispatchEventToListeners(WebInspector.SourceMapTracker.Events.TrackingStopped); - }, - - /** - * @param {string} url - * @param {number} newVersion - */ - _newContentAvailable: function(url, newVersion) - { - if (this._versions.get(url) < newVersion) - this.dispatchEventToListeners(WebInspector.SourceMapTracker.Events.SourceChanged, url); - }, - - __proto__: WebInspector.Object.prototype -} diff --git a/third_party/WebKit/Source/devtools/front_end/sass/module.json b/third_party/WebKit/Source/devtools/front_end/sass/module.json index d4704ba..59c052a 100644 --- a/third_party/WebKit/Source/devtools/front_end/sass/module.json +++ b/third_party/WebKit/Source/devtools/front_end/sass/module.json @@ -1,8 +1,8 @@ { - "dependencies": ["platform", "common", "diff", "sdk", "workspace", "bindings"], + "dependencies": ["platform", "common", "diff", "sdk"], "scripts": [ "SASSSupport.js", - "SASSWorkspaceAdapter.js", + "ASTService.js", "SASSLiveSourceMap.js" ] } diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CSSParser.js b/third_party/WebKit/Source/devtools/front_end/sdk/CSSParser.js index 6337682..0cafa6f 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/CSSParser.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/CSSParser.js @@ -66,6 +66,7 @@ WebInspector.CSSParser.prototype = { if (this._worker) { this._worker.terminate(); delete this._worker; + this._runFinishedCallback([]); } }, @@ -115,8 +116,18 @@ WebInspector.CSSParser.prototype = { _onFinishedParsing: function() { this._unlock(); - if (this._finishedCallback) - this._finishedCallback(this._rules); + this._runFinishedCallback(this._rules); + }, + + /** + * @param {!Array<!WebInspector.CSSRule>} rules + */ + _runFinishedCallback: function(rules) + { + var callback = this._finishedCallback; + delete this._finishedCallback; + if (callback) + callback.call(null, rules); }, __proto__: WebInspector.Object.prototype, @@ -165,3 +176,76 @@ WebInspector.CSSParser.Property = function() /** @type {(boolean|undefined)} */ this.disabled; } + +/** + * @constructor + */ +WebInspector.CSSParserService = function() +{ + this._cssParser = null; + this._cssRequests = []; + this._terminated = false; +} + +WebInspector.CSSParserService.prototype = { + /** + * @param {string} text + * @return {!Promise<!Array.<!WebInspector.CSSParser.Rule>>} + */ + parseCSS: function(text) + { + console.assert(!this._terminated, "Illegal call parseCSS on terminated CSSParserService."); + if (!this._cssParser) + this._cssParser = new WebInspector.CSSParser(); + var request = new WebInspector.CSSParserService.ParseRequest(text); + this._cssRequests.push(request); + this._maybeParseCSS(); + return request.parsedPromise; + }, + + _maybeParseCSS: function() + { + if (this._terminated || this._isParsingCSS || !this._cssRequests.length) + return; + this._isParsingCSS = true; + var request = this._cssRequests.shift(); + this._cssParser.parsePromise(request.text) + .catchException(/** @type {!Array.<!WebInspector.CSSParser.Rule>} */([])) + .then(onCSSParsed.bind(this)); + + /** + * @param {!Array.<!WebInspector.CSSParser.Rule>} rules + * @this {WebInspector.CSSParserService} + */ + function onCSSParsed(rules) + { + request.parsedCallback.call(null, rules); + this._isParsingCSS = false; + this._maybeParseCSS(); + } + }, + + dispose: function() + { + if (this._terminated) + return; + this._terminated = true; + if (this._cssParser) + this._cssParser.dispose(); + for (var request of this._cssRequests) + request.parsedCallback.call(null, /** @type {!Array.<!WebInspector.CSSParser.Rule>} */([])); + this._cssRequests = []; + }, +} + +/** + * @constructor + * @param {string} text + */ +WebInspector.CSSParserService.ParseRequest = function(text) +{ + this.text = text; + /** @type {function(!Array.<!WebInspector.CSSParser.Rule>)} */ + this.parsedCallback; + this.parsedPromise = new Promise(fulfill => this.parsedCallback = fulfill); +} diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleModel.js index ce5548d..cc46da3 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleModel.js @@ -70,8 +70,7 @@ WebInspector.CSSStyleModel.Events = { PseudoStateForced: "PseudoStateForced", StyleSheetAdded: "StyleSheetAdded", StyleSheetChanged: "StyleSheetChanged", - StyleSheetRemoved: "StyleSheetRemoved", - ExternalRangeEdit: "ExternalRangeEdit" + StyleSheetRemoved: "StyleSheetRemoved" } WebInspector.CSSStyleModel.MediaTypes = ["all", "braille", "embossed", "handheld", "print", "projection", "screen", "speech", "tty", "tv"]; |