From 51bf2e34e38fabd1c66838b68af5f62201729798 Mon Sep 17 00:00:00 2001 From: Sebastian Salvucci Date: Fri, 3 Oct 2014 16:04:26 -0300 Subject: [PATCH 1/4] add getSourceFromBrowser impl for CSS docs to be used for developing CSS Editing unit tests. --- documents/LiveCSSDocument.js | 21 ++++++------- protocol/LiveDevProtocol.js | 20 ++++++++++++ protocol/remote/LiveDevProtocolRemote.js | 40 ++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/documents/LiveCSSDocument.js b/documents/LiveCSSDocument.js index f17d889..5d024b5 100644 --- a/documents/LiveCSSDocument.js +++ b/documents/LiveCSSDocument.js @@ -94,16 +94,15 @@ define(function LiveCSSDocumentModule(require, exports, module) { * @return {jQuery.promise} Promise resolved with the text content of this CSS document */ LiveCSSDocument.prototype.getSourceFromBrowser = function () { - // TODO: Only used for unit testing. Need to add protocol API to extract stylesheet from browser side. -// var deferred = new $.Deferred(), -// styleSheetId = this._getStyleSheetHeader().styleSheetId, -// inspectorPromise = Inspector.CSS.getStyleSheetText(styleSheetId); -// -// inspectorPromise.then(function (res) { -// deferred.resolve(res.text); -// }, deferred.reject); -// -// return deferred.promise(); + // Only used for unit testing. + var deferred = new $.Deferred(); + + this.protocol.getStyleSheetText(this.doc.url) + .then(function (res) { + deferred.resolve(res.text); + }, deferred.reject); + + return deferred.promise(); }; /** @@ -125,7 +124,7 @@ define(function LiveCSSDocumentModule(require, exports, module) { if (this.doc.url !== this.roots[i]) { // if it's not directly included through , // reload the original doc - $(this).triggerHandler("updateDoc", this.roots[i]); + //$(this).triggerHandler("updateDoc", this.roots[i]); } else { this.protocol.evaluate("_LD.reloadCSS(" + JSON.stringify(this.doc.url) + ", " + diff --git a/protocol/LiveDevProtocol.js b/protocol/LiveDevProtocol.js index 71f5a67..48defc4 100644 --- a/protocol/LiveDevProtocol.js +++ b/protocol/LiveDevProtocol.js @@ -292,6 +292,25 @@ define(function (require, exports, module) { ); } + /** + * Protocol method. Rretrieves the content of a given stylesheet + * @param {number|Array.} clients A client ID or array of client IDs that should navigate to the given URL. + * @param {string} url Absolute URL that identifies the stylesheet. + * @return {$.Promise} A promise that's resolved with the return value from the first client that responds + * to the method. + */ + function getStyleSheetText(url, clients) { + return _send( + { + method: "CSS.getStyleSheetText", + params: { + url: url + } + }, + clients + ); + } + /** * Closes the connection to the given client. Proxies to the transport. * @param {number} clientId @@ -315,6 +334,7 @@ define(function (require, exports, module) { exports.evaluate = evaluate; exports.reload = reload; exports.navigate = navigate; + exports.getStyleSheetText = getStyleSheetText; exports.close = close; exports.getConnectionIds = getConnectionIds; exports.closeAllConnections = closeAllConnections; diff --git a/protocol/remote/LiveDevProtocolRemote.js b/protocol/remote/LiveDevProtocolRemote.js index 7df32fe..f5e9b85 100644 --- a/protocol/remote/LiveDevProtocolRemote.js +++ b/protocol/remote/LiveDevProtocolRemote.js @@ -102,7 +102,7 @@ return; } response.id = orig.id; - this.send(JSON.stringify(response)); + this.send(response); }, /** @@ -143,7 +143,7 @@ console.log("Runtime.evaluate"); var result = eval(msg.params.expression); MessageBroker.respond(msg, { - result: JSON.stringify(result) // TODO: in original protocol this is an object handle + result: result // TODO: in original protocol this is an object handle }); } }; @@ -243,6 +243,42 @@ // exposing ProtocolManager global._Brackets_LiveDev_ProtocolManager = ProtocolManager; + /** + * CSS Domain. + */ + var CSS = { + /** + * retrieves the content of the stylesheet + * TODO: it now depends on reloadCSS implementation + */ + getStyleSheetText: function (msg) { + var i, + sheet, + text; + for (i = 0; i < document.styleSheets.length; i++) { + sheet = document.styleSheets[i]; + // if it was already 'reloaded' + if (sheet.ownerNode.id === msg.params.url) { + text = sheet.ownerNode.innerText; + } + // if it was not already 'reloaded' + if (!sheet.disabled && sheet.href === msg.params.url) { + var j, + rules = document.styleSheets[i].cssRules; + text = ""; + for (j = 0; j < rules.length; j++) { + text += rules[j].cssText + '\n'; + } + } + } + MessageBroker.respond(msg, { + text: text + }); + } + }; + + MessageBroker.on("CSS.getStyleSheetText", CSS.getStyleSheetText); + /** * The remote handler for the protocol. */ From 52e4643b430c347e0fee9661180aee20efc11998 Mon Sep 17 00:00:00 2001 From: Sebastian Salvucci Date: Fri, 3 Oct 2014 16:05:01 -0300 Subject: [PATCH 2/4] add basic unit test for CSS editing --- unittests.js | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/unittests.js b/unittests.js index 8704e4a..e693e58 100644 --- a/unittests.js +++ b/unittests.js @@ -50,6 +50,10 @@ define(function (require, exports, module) { tempDir = SpecRunnerUtils.getTempDirectory(), allSpacesRE = /\s+/gi; + function fixSpaces(str) { + return str.replace(allSpacesRE, " "); + } + beforeEach(function () { // Create a new window that will be shared by ALL tests in this spec. if (!testWindow) { @@ -75,6 +79,7 @@ define(function (require, exports, module) { }); afterEach(function () { + DocumentManager.closeAll(); testWindow.close(); testWindow = null; brackets = null; @@ -175,5 +180,48 @@ define(function (require, exports, module) { }); }); }); + + describe("CSS Editing", function () { + + it("should push changes through browser connection", function () { + var localText, + browserText, + liveDoc, + curDoc; + + runs(function () { + waitsForDone(SpecRunnerUtils.openProjectFiles(["simple1.html"]), "SpecRunnerUtils.openProjectFiles simple1.html", 1000); + }); + + openLiveDevelopmentAndWait(); + + runs(function () { + waitsForDone(SpecRunnerUtils.openProjectFiles(["simple1.css"]), "SpecRunnerUtils.openProjectFiles simple1.css", 1000); + }); + runs(function () { + curDoc = DocumentManager.getCurrentDocument(); + localText = curDoc.getText(); + localText += "\n .testClass { background-color:#090; }\n"; + curDoc.setText(localText); + }); + runs(function () { + liveDoc = LiveDevelopment.getLiveDocForPath(testFolder + "simple1.css"); + }); + var doneSyncing = false; + runs(function () { + liveDoc.getSourceFromBrowser().done(function (text) { + browserText = text; + }).always(function () { + doneSyncing = true; + }); + }); + waitsFor(function () { return doneSyncing; }, "Browser to sync changes", 5000); + + runs(function () { + console.log('local:' + localText + ' - browser:' + browserText); + expect(fixSpaces(browserText)).toBe(fixSpaces(localText)); + }); + }); + }); }); }); \ No newline at end of file From d6fae6e84edb1fd9c8b7a9b2e472465ecd26df17 Mon Sep 17 00:00:00 2001 From: Sebastian Salvucci Date: Fri, 10 Oct 2014 11:09:32 -0300 Subject: [PATCH 3/4] separate fail handler at getStyleSheetText --- documents/LiveCSSDocument.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/documents/LiveCSSDocument.js b/documents/LiveCSSDocument.js index 5d024b5..aede1af 100644 --- a/documents/LiveCSSDocument.js +++ b/documents/LiveCSSDocument.js @@ -100,7 +100,10 @@ define(function LiveCSSDocumentModule(require, exports, module) { this.protocol.getStyleSheetText(this.doc.url) .then(function (res) { deferred.resolve(res.text); - }, deferred.reject); + }) + .fail(function (err) { + deferred.reject(err); + }); return deferred.promise(); }; From 86b08978bbe93d80b151596f9046edfefd382a34 Mon Sep 17 00:00:00 2001 From: Sebastian Salvucci Date: Mon, 20 Oct 2014 16:31:07 -0300 Subject: [PATCH 4/4] change getStyleSheetText implementation just a couple of small changes. --- protocol/remote/LiveDevProtocolRemote.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/protocol/remote/LiveDevProtocolRemote.js b/protocol/remote/LiveDevProtocolRemote.js index f5e9b85..986492e 100644 --- a/protocol/remote/LiveDevProtocolRemote.js +++ b/protocol/remote/LiveDevProtocolRemote.js @@ -257,18 +257,16 @@ text; for (i = 0; i < document.styleSheets.length; i++) { sheet = document.styleSheets[i]; - // if it was already 'reloaded' - if (sheet.ownerNode.id === msg.params.url) { - text = sheet.ownerNode.innerText; - } - // if it was not already 'reloaded' - if (!sheet.disabled && sheet.href === msg.params.url) { + // if it was not 'reloaded' + if ((!sheet.disabled) && (sheet.href === msg.params.url)) { var j, rules = document.styleSheets[i].cssRules; text = ""; for (j = 0; j < rules.length; j++) { text += rules[j].cssText + '\n'; } + } else if (sheet.ownerNode.id === msg.params.url) { // if it was already 'reloaded' + text = sheet.ownerNode.innerText; } } MessageBroker.respond(msg, {