diff --git a/LiveDevelopment.js b/LiveDevelopment.js
index 37d7392..85ccb15 100644
--- a/LiveDevelopment.js
+++ b/LiveDevelopment.js
@@ -355,7 +355,7 @@ define(function (require, exports, module) {
$(liveDoc).on("updateDoc", function (event, url) {
var path = _server.urlToPath(url),
doc = getLiveDocForPath(path);
- doc.updateBrowser();
+ doc._updateBrowser();
});
}
}
diff --git a/documents/LiveCSSDocument.js b/documents/LiveCSSDocument.js
index f17d889..f3f28ae 100644
--- a/documents/LiveCSSDocument.js
+++ b/documents/LiveCSSDocument.js
@@ -94,16 +94,18 @@ 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);
+ })
+ .fail(function (err) {
+ deferred.reject(err);
+ });
+
+ return deferred.promise();
};
/**
@@ -119,13 +121,13 @@ define(function LiveCSSDocumentModule(require, exports, module) {
/**
* When the user edits the file, update the stylesheet in the browser and redraw highlights.
*/
- LiveCSSDocument.prototype.updateBrowser = function () {
+ LiveCSSDocument.prototype._updateBrowser = function () {
var i;
for (i = 0; i < this.roots.length; i++) {
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) + ", " +
@@ -177,7 +179,7 @@ define(function LiveCSSDocumentModule(require, exports, module) {
* @param {Object} change
*/
LiveCSSDocument.prototype.onChange = function (event, editor, change) {
- this.updateBrowser();
+ this._updateBrowser();
};
/**
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..986492e 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,40 @@
// 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 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, {
+ text: text
+ });
+ }
+ };
+
+ MessageBroker.on("CSS.getStyleSheetText", CSS.getStyleSheetText);
+
/**
* The remote handler for the protocol.
*/
diff --git a/unittests.js b/unittests.js
index ee8af77..0eb68b1 100644
--- a/unittests.js
+++ b/unittests.js
@@ -49,6 +49,10 @@ define(function (require, exports, module) {
var testFolder = FileUtils.getNativeModuleDirectoryPath(module) + "/unittest-files/",
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) {
@@ -222,5 +226,92 @@ 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);
+ });
+
+ waitsForLiveDevelopmentToOpen();
+
+ 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));
+ });
+ });
+
+ it("should push in memory css changes made before the session starts", function () {
+ var localText,
+ browserText;
+
+ runs(function () {
+ waitsForDone(SpecRunnerUtils.openProjectFiles(["simple1.css"]), "SpecRunnerUtils.openProjectFiles simple1.css", 1000);
+ });
+
+ runs(function () {
+ var curDoc = DocumentManager.getCurrentDocument();
+ localText = curDoc.getText();
+ localText += "\n .testClass { background-color:#090; }\n";
+ curDoc.setText(localText);
+
+ // Document should not be marked dirty
+ expect(LiveDevelopment.status).not.toBe(LiveDevelopment.STATUS_OUT_OF_SYNC);
+ });
+
+ runs(function () {
+ waitsForDone(SpecRunnerUtils.openProjectFiles(["simple1.html"]), "SpecRunnerUtils.openProjectFiles simple1.html", 1000);
+ });
+
+ waitsForLiveDevelopmentToOpen();
+
+
+ var liveDoc, doneSyncing = false;
+ runs(function () {
+ liveDoc = LiveDevelopment.getLiveDocForPath(testFolder + "simple1.css");
+ });
+
+ runs(function () {
+ liveDoc.getSourceFromBrowser().done(function (text) {
+ browserText = text;
+ }).always(function () {
+ doneSyncing = true;
+ });
+ });
+ waitsFor(function () { return doneSyncing; }, "Browser to sync changes", 10000);
+
+ runs(function () {
+ expect(fixSpaces(browserText)).toBe(fixSpaces(localText));
+ });
+ });
+ });
});
});