From 426bfa371df2242f51f6e4773a936372b568b008 Mon Sep 17 00:00:00 2001 From: Jason San Jose Date: Tue, 9 Apr 2013 16:04:40 -0700 Subject: [PATCH 1/4] Fix #3372. Check for valid server. Small refactoring to live dev startup to create live document before agents load. --- src/LiveDevelopment/Documents/HTMLDocument.js | 37 ++++++-- src/LiveDevelopment/LiveDevelopment.js | 89 ++++++++++--------- 2 files changed, 79 insertions(+), 47 deletions(-) diff --git a/src/LiveDevelopment/Documents/HTMLDocument.js b/src/LiveDevelopment/Documents/HTMLDocument.js index ae412d6ac07..64928a53317 100644 --- a/src/LiveDevelopment/Documents/HTMLDocument.js +++ b/src/LiveDevelopment/Documents/HTMLDocument.js @@ -61,17 +61,15 @@ define(function HTMLDocumentModule(require, exports, module) { return; } this.editor = editor; - HTMLInstrumentation._markText(this.editor); - this.onCursorActivity = this.onCursorActivity.bind(this); - $(this.editor).on("cursorActivity", this.onCursorActivity); - this.onCursorActivity(); + this.onCursorActivity = this.onCursorActivity.bind(this); this.onDocumentSaved = this.onDocumentSaved.bind(this); + + $(this.editor).on("cursorActivity", this.onCursorActivity); $(DocumentManager).on("documentSaved", this.onDocumentSaved); // Experimental code if (LiveDevelopment.config.experimental) { - // Used by highlight agent to highlight editor text as selected in browser this.onHighlight = this.onHighlight.bind(this); $(HighlightAgent).on("highlight", this.onHighlight); @@ -80,6 +78,34 @@ define(function HTMLDocumentModule(require, exports, module) { $(this.editor).on("change", this.onChange); } }; + + /** + * Enable instrumented HTML + * @param enabled {boolean} + */ + HTMLDocument.prototype.setInstrumentationEnabled = function setInstrumentationEnabled(enabled) { + if (enabled && !this._instrumentationEnabled) { + HTMLInstrumentation.scanDocument(this.doc); + HTMLInstrumentation._markText(this.editor); + } + + this._instrumentationEnabled = enabled; + }; + + HTMLDocument.prototype._instrumentationEnabled = false; + + /** + * Returns a JSON object with HTTP response overrides + * @returns {{body: string}} + */ + HTMLDocument.prototype.getResponseData = function getResponseData(enabled) { + var body = (this._instrumentationEnabled) ? + HTMLInstrumentation.generateInstrumentedHTML(this.doc) : this.doc.getText(); + + return { + body: body + }; + }; /** Close the document */ HTMLDocument.prototype.close = function close() { @@ -92,7 +118,6 @@ define(function HTMLDocumentModule(require, exports, module) { // Experimental code if (LiveDevelopment.config.experimental) { - $(HighlightAgent).off("highlight", this.onHighlight); this.onHighlight(); diff --git a/src/LiveDevelopment/LiveDevelopment.js b/src/LiveDevelopment/LiveDevelopment.js index c89b63cebda..6c42ec85c1d 100644 --- a/src/LiveDevelopment/LiveDevelopment.js +++ b/src/LiveDevelopment/LiveDevelopment.js @@ -296,6 +296,12 @@ define(function LiveDevelopment(require, exports, module) { _liveDocument.close(); _liveDocument = undefined; } + + if (_serverProvider) { + // Remove any "request" listeners that were added previously + $(_serverProvider).off(".livedev"); + } + if (_relatedDocuments) { _relatedDocuments.forEach(function (liveDoc) { liveDoc.close(); @@ -315,13 +321,42 @@ define(function LiveDevelopment(require, exports, module) { } } - /** Open a live document + /** + * @private + * Open a live document * @param {Document} source document to open - * @return {jQuery.Promise} A promise that is resolved once the live - * document is open, and is never explicitly rejected. */ function _openDocument(doc, editor) { + _closeDocument(); + _liveDocument = _createDocument(doc, editor); + // Enable instrumentation + if (_liveDocument.setInstrumentationEnabled) { + var enableInstrumentation = false; + + if (_serverProvider && _serverProvider.setRequestFilterPaths) { + enableInstrumentation = true; + + _serverProvider.setRequestFilterPaths( + ["/" + encodeURI(ProjectManager.makeProjectRelativeIfPossible(doc.file.fullPath))] + ); + + // Send custom HTTP response for the current live document + $(_serverProvider).on("request.livedev", function (event, request) { + var response = _liveDocument.getResponseData ? _liveDocument.getResponseData() : null; + request.send(response); + }); + } + + _liveDocument.setInstrumentationEnabled(enableInstrumentation); + } + } + + /** + * @private + * Populate array of related documents reported by the browser agent(s) + */ + function _getRelatedDocuments() { function createLiveStylesheet(url) { var stylesheetDeferred = $.Deferred(); @@ -348,9 +383,6 @@ define(function LiveDevelopment(require, exports, module) { return stylesheetDeferred.promise(); } - _closeDocument(); - _liveDocument = _createDocument(doc, editor); - // Gather related CSS documents. // FUTURE: Gather related JS documents as well. _relatedDocuments = []; @@ -453,13 +485,12 @@ define(function LiveDevelopment(require, exports, module) { return; } - var editor = EditorManager.getCurrentFullEditor(), - status = STATUS_ACTIVE; + var status = STATUS_ACTIVE; // Note: the following promise is never explicitly rejected, so there - // is no failure handler. If _openDocument is changed so that rejection + // is no failure handler. If _getRelatedDocuments is changed so that rejection // is possible, failure should be managed accordingly. - _openDocument(doc, editor) + _getRelatedDocuments() .done(function () { if (doc.isDirty && _classForDocument(doc) !== CSSDocument) { status = STATUS_OUT_OF_SYNC; @@ -572,23 +603,7 @@ define(function LiveDevelopment(require, exports, module) { function doLaunchAfterServerReady() { _setStatus(STATUS_CONNECTING); - if (_serverProvider) { - // Install a request filter for the current document. In the future, - // we need to install filters for *all* files that need to be instrumented. - HTMLInstrumentation.scanDocument(doc); - _serverProvider.setRequestFilterPaths( - ["/" + ProjectManager.makeProjectRelativeIfPossible(doc.file.fullPath)] - ); - - // Remove any "request" listeners that were added previously - $(_serverProvider).off(".livedev"); - - $(_serverProvider).on("request.livedev", function (event, request) { - var html = HTMLInstrumentation.generateInstrumentedHTML(doc); - - request.send({ body: html }); - }); - } + _openDocument(doc, EditorManager.getCurrentFullEditor()); Inspector.connectToURL(launcherUrl).done(result.resolve).fail(function onConnectFail(err) { if (err === "CANCEL") { @@ -669,7 +684,6 @@ define(function LiveDevelopment(require, exports, module) { if (!doc || !doc.root) { showWrongDocError(); - } else { _serverProvider = LiveDevServerManager.getProvider(doc.file.fullPath); @@ -841,9 +855,9 @@ define(function LiveDevelopment(require, exports, module) { if (Inspector.connected()) { hideHighlight(); if (agents.network && agents.network.wasURLRequested(doc.url)) { - _closeDocument(); - var editor = EditorManager.getCurrentFullEditor(); - promise = _openDocument(doc, editor); + _openDocument(doc, EditorManager.getCurrentFullEditor()); + + promise = _getRelatedDocuments(); } else { if (exports.config.experimental || _isHtmlFileExt(doc.extension)) { promise = close().done(open); @@ -895,15 +909,10 @@ define(function LiveDevelopment(require, exports, module) { /** * Determines whether we can serve local file. - * - * @param {String} localPath - * A local path to file being served. - * - * @return {Boolean} - * true for yes, otherwise false. + * @param {String} localPath A local path to file being served. + * @return {Boolean} true for yes, otherwise false. */ UserServerProvider.prototype.canServe = function (localPath) { - var baseUrl = ProjectManager.getBaseUrl(); if (!baseUrl) { return false; @@ -918,9 +927,7 @@ define(function LiveDevelopment(require, exports, module) { /** * Returns a base url for current project. - * - * @return {String} - * Base url for current project. + * @return {String} Base url for current project. */ UserServerProvider.prototype.getBaseUrl = function () { return ProjectManager.getBaseUrl(); From a4006f243e856d80741a23c84f123d676f0b5cca Mon Sep 17 00:00:00 2001 From: Jason San Jose Date: Tue, 9 Apr 2013 16:17:33 -0700 Subject: [PATCH 2/4] update live dev highlighting unit tests --- test/spec/LiveDevelopment-test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/spec/LiveDevelopment-test.js b/test/spec/LiveDevelopment-test.js index b6167911f7f..31118c02c44 100644 --- a/test/spec/LiveDevelopment-test.js +++ b/test/spec/LiveDevelopment-test.js @@ -725,6 +725,7 @@ define(function (require, exports, module) { instrumentedHtml = HTMLInstrumentationModule.generateInstrumentedHTML(testDocument); createIdToTagMap(instrumentedHtml); testHTMLDoc = new HTMLDocumentModule(testDocument, testEditor); + testHTMLDoc.setInstrumentationEnabled(true); }); }); From 90e749f3ffbf3be3b33d86f7ec895d812eafe354 Mon Sep 17 00:00:00 2001 From: Jason San Jose Date: Tue, 9 Apr 2013 18:44:07 -0700 Subject: [PATCH 3/4] code review comments --- src/LiveDevelopment/Documents/HTMLDocument.js | 3 +-- src/LiveDevelopment/LiveDevelopment.js | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LiveDevelopment/Documents/HTMLDocument.js b/src/LiveDevelopment/Documents/HTMLDocument.js index 64928a53317..f10b53e5fa1 100644 --- a/src/LiveDevelopment/Documents/HTMLDocument.js +++ b/src/LiveDevelopment/Documents/HTMLDocument.js @@ -61,6 +61,7 @@ define(function HTMLDocumentModule(require, exports, module) { return; } this.editor = editor; + this._instrumentationEnabled = false; this.onCursorActivity = this.onCursorActivity.bind(this); this.onDocumentSaved = this.onDocumentSaved.bind(this); @@ -92,8 +93,6 @@ define(function HTMLDocumentModule(require, exports, module) { this._instrumentationEnabled = enabled; }; - HTMLDocument.prototype._instrumentationEnabled = false; - /** * Returns a JSON object with HTTP response overrides * @returns {{body: string}} diff --git a/src/LiveDevelopment/LiveDevelopment.js b/src/LiveDevelopment/LiveDevelopment.js index 6c42ec85c1d..6dd20ea7a28 100644 --- a/src/LiveDevelopment/LiveDevelopment.js +++ b/src/LiveDevelopment/LiveDevelopment.js @@ -343,6 +343,7 @@ define(function LiveDevelopment(require, exports, module) { // Send custom HTTP response for the current live document $(_serverProvider).on("request.livedev", function (event, request) { + // response can be null in which case the StaticServerDomain reverts to simple file serving. var response = _liveDocument.getResponseData ? _liveDocument.getResponseData() : null; request.send(response); }); From 8bb9626e6d4d54d9f092d7ab463821efd0d2ab77 Mon Sep 17 00:00:00 2001 From: Jason San Jose Date: Tue, 9 Apr 2013 19:19:33 -0700 Subject: [PATCH 4/4] fix #3394. clear out old request filters. --- .../default/StaticServer/node/StaticServerDomain.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/extensions/default/StaticServer/node/StaticServerDomain.js b/src/extensions/default/StaticServer/node/StaticServerDomain.js index 1a1584699c9..ff8f3f32af9 100644 --- a/src/extensions/default/StaticServer/node/StaticServerDomain.js +++ b/src/extensions/default/StaticServer/node/StaticServerDomain.js @@ -21,8 +21,7 @@ * */ -/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, -maxerr: 50, node: true */ +/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, node: true */ /*global */ (function () { @@ -292,7 +291,10 @@ maxerr: 50, node: true */ function _cmdSetRequestFilterPaths(root, paths) { var rootPath = normalizeRootPath(root), pathKey = getPathKey(root), - rewritePaths = _rewritePaths[pathKey]; + rewritePaths = {}; + + // reset list of filtered paths for each call to setRequestFilterPaths + _rewritePaths[pathKey] = rewritePaths; paths.forEach(function (path) { rewritePaths[path] = pathJoin(root, path);