From d2a8a827454efe4e692fa17730e36649cb19a1dd Mon Sep 17 00:00:00 2001 From: Jason San Jose Date: Thu, 27 Feb 2014 14:52:34 -0800 Subject: [PATCH] account for styleSheetId changes after a CSSDocument reloads --- src/LiveDevelopment/Agents/CSSAgent.js | 23 ++++-- src/LiveDevelopment/Documents/CSSDocument.js | 87 +++++++++++--------- src/LiveDevelopment/Servers/BaseServer.js | 6 -- 3 files changed, 65 insertions(+), 51 deletions(-) diff --git a/src/LiveDevelopment/Agents/CSSAgent.js b/src/LiveDevelopment/Agents/CSSAgent.js index 0701cdbfd42..542872910c9 100644 --- a/src/LiveDevelopment/Agents/CSSAgent.js +++ b/src/LiveDevelopment/Agents/CSSAgent.js @@ -69,8 +69,10 @@ define(function CSSAgent(require, exports, module) { _styleSheetIdToUrl = {}; } - /** Get a style sheet for a url + /** + * Get a style sheet for a url * @param {string} url + * @return {CSS.CSSStyleSheetHeader} */ function styleForURL(url) { return _urlToStyle[_canonicalize(url)]; @@ -90,22 +92,26 @@ define(function CSSAgent(require, exports, module) { return urls; } - /** Reload a CSS style sheet from a document + /** + * Reload a CSS style sheet from a document * @param {Document} document + * @return {jQuery.Promise} */ function reloadCSSForDocument(doc) { var style = styleForURL(doc.url); console.assert(style, "Style Sheet for document not loaded: " + doc.url); - Inspector.CSS.setStyleSheetText(style.styleSheetId, doc.getText()); + return Inspector.CSS.setStyleSheetText(style.styleSheetId, doc.getText()); } - /** Empties a CSS style sheet given a document that has been deleted + /** + * Empties a CSS style sheet given a document that has been deleted * @param {Document} document + * @return {jQuery.Promise} */ function clearCSSForDocument(doc) { var style = styleForURL(doc.url); console.assert(style, "Style Sheet for document not loaded: " + doc.url); - Inspector.CSS.setStyleSheetText(style.styleSheetId, ""); + return Inspector.CSS.setStyleSheetText(style.styleSheetId, ""); } /** @@ -129,7 +135,7 @@ define(function CSSAgent(require, exports, module) { _urlToStyle[url] = res.header; _styleSheetIdToUrl[res.header.styleSheetId] = url; - $(exports).triggerHandler("styleSheetAdded", [url]); + $(exports).triggerHandler("styleSheetAdded", [url, res.header]); } /** @@ -142,7 +148,8 @@ define(function CSSAgent(require, exports, module) { return; } - var url = _styleSheetIdToUrl[res.styleSheetId]; + var url = _styleSheetIdToUrl[res.styleSheetId], + header = url && _urlToStyle[url]; if (url) { delete _urlToStyle[url]; @@ -150,7 +157,7 @@ define(function CSSAgent(require, exports, module) { delete _styleSheetIdToUrl[res.styleSheetId]; - $(exports).triggerHandler("styleSheetRemoved", [url]); + $(exports).triggerHandler("styleSheetRemoved", [url, header]); } /** diff --git a/src/LiveDevelopment/Documents/CSSDocument.js b/src/LiveDevelopment/Documents/CSSDocument.js index bd76cd67690..c037c4c33b3 100644 --- a/src/LiveDevelopment/Documents/CSSDocument.js +++ b/src/LiveDevelopment/Documents/CSSDocument.js @@ -48,7 +48,8 @@ define(function CSSDocumentModule(require, exports, module) { "use strict"; - var CSSAgent = require("LiveDevelopment/Agents/CSSAgent"), + var _ = require("thirdparty/lodash"), + CSSAgent = require("LiveDevelopment/Agents/CSSAgent"), CSSUtils = require("language/CSSUtils"), EditorManager = require("editor/EditorManager"), HighlightAgent = require("LiveDevelopment/Agents/HighlightAgent"), @@ -69,6 +70,9 @@ define(function CSSDocumentModule(require, exports, module) { this.doc.addRef(); this.onChange = this.onChange.bind(this); this.onDeleted = this.onDeleted.bind(this); + + this._updateBrowser = _.debounce(this._updateBrowser, 250); + $(this.doc).on("change.CSSDocument", this.onChange); $(this.doc).on("deleted.CSSDocument", this.onDeleted); @@ -81,34 +85,46 @@ define(function CSSDocumentModule(require, exports, module) { } }; - /** Get the browser version of the StyleSheet object */ - CSSDocument.prototype.getStyleSheetFromBrowser = function getStyleSheetFromBrowser() { - var deferred = new $.Deferred(); + CSSDocument.prototype._url = null; - // WebInspector Command: CSS.getStyleSheet - Inspector.CSS.getStyleSheet(this.styleSheet.styleSheetId, function callback(res) { - // res = {styleSheet} - if (res.styleSheet) { - deferred.resolve(res.styleSheet); - } else { - deferred.reject(); + Object.defineProperties(CSSDocument.prototype, { + "url": { + get: function () { return this._url; }, + set: function (url) { + _url = url; + + // Force initial update for dirty files + if (this.doc.isDirty) { + this._updateBrowser(); + } } - }); + } + }); - return deferred.promise(); + /** + * @private + * Get the CSSStyleSheetHeader for this document + */ + CSSDocument.prototype._getStyleSheetHeader = function () { + return CSSAgent.styleForURL(this.doc.url); }; - /** Get the browser version of the source */ - CSSDocument.prototype.getSourceFromBrowser = function getSourceFromBrowser() { - var deferred = new $.Deferred(); - - this.getStyleSheetFromBrowser().done(function onDone(styleSheet) { - deferred.resolve(styleSheet.text); - }).fail(function onFail() { - deferred.reject(); - }); + /** + * @deprecated + * CSSStyleSheetBody was removed in protocol 1.1. This method is unused in Brackets 36. + * Get the browser version of the StyleSheet object + * @return {jQuery.promise} + */ + CSSDocument.prototype.getStyleSheetFromBrowser = function getStyleSheetFromBrowser() { + return new $.Deferred().reject().promise(); + }; - return deferred.promise(); + /** + * Get the browser version of the source + * @return {jQuery.promise} Promise resolved with the text content of this CSS document + */ + CSSDocument.prototype.getSourceFromBrowser = function getSourceFromBrowser() { + return Inspector.CSS.getStyleSheetText(this._getStyleSheetHeader().styleSheetId); }; /** Close the document */ @@ -118,17 +134,16 @@ define(function CSSDocumentModule(require, exports, module) { this.doc.releaseRef(); this.detachFromEditor(); }; - + /** - * Force the browser to update if the file is dirty + * @private + * Update the style sheet text content and redraw highlights */ CSSDocument.prototype._updateBrowser = function () { - // get the style sheet - this.styleSheet = CSSAgent.styleForURL(this.doc.url); + var reloadPromise = CSSAgent.reloadCSSForDocument(this.doc); - // If the CSS document is dirty, push the changes into the browser now - if (this.doc.isDirty) { - CSSAgent.reloadCSSForDocument(this.doc); + if (Inspector.config.highlight) { + reloadPromise.done(HighlightAgent.redraw); } }; @@ -200,11 +215,7 @@ define(function CSSDocumentModule(require, exports, module) { /** Triggered whenever the Document is edited */ CSSDocument.prototype.onChange = function onChange(event, editor, change) { - // brute force: update the CSS - CSSAgent.reloadCSSForDocument(this.doc); - if (Inspector.config.highlight) { - HighlightAgent.redraw(); - } + this._updateBrowser(); }; /** Triggered if the Document's file is deleted */ @@ -241,11 +252,13 @@ define(function CSSDocumentModule(require, exports, module) { // WebInspector Command: CSS.getMatchedStylesForNode Inspector.CSS.getMatchedStylesForNode(node.nodeId, function onGetMatchesStyles(res) { // res = {matchedCSSRules, pseudoElements, inherited} - var codeMirror = this.editor._codeMirror; + var codeMirror = this.editor._codeMirror, + styleSheetId = this._getStyleSheetHeader().styleSheetId; + var i, rule, from, to; for (i in res.matchedCSSRules) { rule = res.matchedCSSRules[i]; - if (rule.ruleId && rule.ruleId.styleSheetId === this.styleSheet.styleSheetId) { + if (rule.ruleId && rule.ruleId.styleSheetId === styleSheetId) { from = codeMirror.posFromIndex(rule.selectorRange.start); to = codeMirror.posFromIndex(rule.style.range.end); this._highlight.push(codeMirror.markText(from, to, { className: "highlight" })); diff --git a/src/LiveDevelopment/Servers/BaseServer.js b/src/LiveDevelopment/Servers/BaseServer.js index 010a4f7eee6..fa8a713c93a 100644 --- a/src/LiveDevelopment/Servers/BaseServer.js +++ b/src/LiveDevelopment/Servers/BaseServer.js @@ -81,12 +81,6 @@ define(function (require, exports, module) { // for live development (the file for HTML files) // TODO: Issue #2033 Improve how default page is determined doc.root = { url: doc.url }; - - // TODO: Better workflow of liveDocument.doc.url assignment - // Force sync the browser after a URL is assigned - if (liveDocument._updateBrowser) { - liveDocument._updateBrowser(); - } }; /**