Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit a9e2771

Browse files
author
Narciso Jaramillo
committed
Merge pull request #3715 from adobe/nj-dk/issue-1697
Rebased/updated version of Dennis's live dev reason fix
2 parents 6475f7d + 51c532b commit a9e2771

File tree

6 files changed

+491
-14
lines changed

6 files changed

+491
-14
lines changed

src/LiveDevelopment/LiveDevelopment.js

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,23 @@
4242
* # STATUS
4343
*
4444
* Status updates are dispatched as `statusChange` jQuery events. The status
45-
* codes are:
45+
* is passed as the first parameter and the reason for the change as the second
46+
* parameter. Currently only the "Inactive" status supports the reason parameter.
47+
* The status codes are:
4648
*
4749
* -1: Error
4850
* 0: Inactive
4951
* 1: Connecting to the remote debugger
5052
* 2: Loading agents
5153
* 3: Active
5254
* 4: Out of sync
55+
*
56+
* The reason codes are:
57+
* - null (Unknown reason)
58+
* - "explicit_close" (LiveDevelopment.close() was called)
59+
* - "navigated_away" (The browser changed to a location outside of the project)
60+
* - "detached_target_closed" (The tab or window was closed)
61+
* - "detached_replaced_with_devtools" (The developer tools were opened in the browser)
5362
*/
5463
define(function LiveDevelopment(require, exports, module) {
5564
"use strict";
@@ -133,7 +142,8 @@ define(function LiveDevelopment(require, exports, module) {
133142
var _liveDocument; // the document open for live editing.
134143
var _relatedDocuments; // CSS and JS documents that are used by the live HTML document
135144
var _serverProvider; // current LiveDevServerProvider
136-
145+
var _closeReason; // reason why live preview was closed
146+
137147
function _isHtmlFileExt(ext) {
138148
return (FileUtils.isStaticHtmlFileExt(ext) ||
139149
(ProjectManager.getBaseUrl() && FileUtils.isServerHtmlFileExt(ext)));
@@ -451,8 +461,14 @@ define(function LiveDevelopment(require, exports, module) {
451461
* @param {integer} new status
452462
*/
453463
function _setStatus(status) {
464+
// Don't send a notification when the status didn't actually change
465+
if (status === exports.status) {
466+
return;
467+
}
468+
454469
exports.status = status;
455-
$(exports).triggerHandler("statusChange", status);
470+
var reason = status === STATUS_INACTIVE ? _closeReason : null;
471+
$(exports).triggerHandler("statusChange", [status, reason]);
456472
}
457473

458474
/** Triggered by Inspector.error */
@@ -504,13 +520,6 @@ define(function LiveDevelopment(require, exports, module) {
504520
});
505521
}
506522

507-
/** Triggered by Inspector.detached */
508-
function _onDetached(event, res) {
509-
// res.reason, e.g. "replaced_with_devtools", "target_closed", "canceled_by_user"
510-
// Sample list taken from https://chromiumcodereview.appspot.com/10947037/patch/12001/13004
511-
// However, the link refers to the Chrome Extension API, it may not apply 100% to the Inspector API
512-
}
513-
514523
// WebInspector Event: Page.frameNavigated
515524
function _onFrameNavigated(event, res) {
516525
// res = {frame}
@@ -539,6 +548,7 @@ define(function LiveDevelopment(require, exports, module) {
539548
if (!url.match(baseUrlRegExp)) {
540549
// No longer in site, so terminate live dev, but don't close browser window
541550
Inspector.disconnect();
551+
_closeReason = "navigated_away";
542552
_setStatus(STATUS_INACTIVE);
543553
_serverProvider = null;
544554
}
@@ -554,10 +564,22 @@ define(function LiveDevelopment(require, exports, module) {
554564
_setStatus(STATUS_INACTIVE);
555565
}
556566

567+
function _onDetached(event, res) {
568+
// If there already is a reason for closing the session, do not overwrite it
569+
if (!_closeReason) {
570+
// Get the explanation from res.reason, e.g. "replaced_with_devtools", "target_closed", "canceled_by_user"
571+
// Examples taken from https://chromiumcodereview.appspot.com/10947037/patch/12001/13004
572+
// However, the link refers to the Chrome Extension API, it may not apply 100% to the Inspector API
573+
// Prefix with "detached_" to create a quasi-namespace for Chrome's reasons
574+
_closeReason = "detached_" + res.reason;
575+
}
576+
}
577+
557578
function reconnect() {
558579
unloadAgents();
559-
var promises = loadAgents();
580+
560581
_setStatus(STATUS_LOADING_AGENTS);
582+
var promises = loadAgents();
561583
$.when.apply(undefined, promises).done(_onLoad).fail(_onError);
562584
}
563585

@@ -569,6 +591,8 @@ define(function LiveDevelopment(require, exports, module) {
569591
var browserStarted = false;
570592
var retryCount = 0;
571593

594+
_closeReason = null;
595+
572596
function showWrongDocError() {
573597
Dialogs.showModalDialog(
574598
Dialogs.DIALOG_ID_ERROR,
@@ -722,6 +746,8 @@ define(function LiveDevelopment(require, exports, module) {
722746
* @return {jQuery.Promise} Resolves once the connection is closed
723747
*/
724748
function close() {
749+
_closeReason = "explicit_close";
750+
725751
var deferred = $.Deferred();
726752

727753
/*
@@ -835,7 +861,6 @@ define(function LiveDevelopment(require, exports, module) {
835861
$.when.apply(undefined, promises).done(_onLoad).fail(_onError);
836862
}
837863

838-
$(Inspector.Inspector).on("detached.livedev", _onDetached);
839864
$(Inspector.Page).on("frameNavigated.livedev", _onFrameNavigated);
840865

841866
waitForInterstitialPageLoad()
@@ -960,6 +985,7 @@ define(function LiveDevelopment(require, exports, module) {
960985
$(Inspector).on("connect", _onConnect)
961986
.on("disconnect", _onDisconnect)
962987
.on("error", _onError);
988+
$(Inspector.Inspector).on("detached", _onDetached);
963989
$(DocumentManager).on("currentDocumentChange", _onDocumentChange)
964990
.on("documentSaved", _onDocumentSaved)
965991
.on("dirtyFlagChange", _onDirtyFlagChange);

src/LiveDevelopment/main.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ define(function main(require, exports, module) {
4848
Dialogs = require("widgets/Dialogs"),
4949
UrlParams = require("utils/UrlParams").UrlParams,
5050
Strings = require("strings"),
51-
ExtensionUtils = require("utils/ExtensionUtils");
51+
ExtensionUtils = require("utils/ExtensionUtils"),
52+
StringUtils = require("utils/StringUtils");
5253

5354
var prefs;
5455
var params = new UrlParams();
@@ -131,17 +132,48 @@ define(function main(require, exports, module) {
131132
}
132133
}
133134

135+
/** Called on status change */
136+
function _showStatusChangeReason(reason) {
137+
// Destroy the previous twipsy (options are not updated otherwise)
138+
_$btnGoLive.twipsy("hide").removeData("twipsy");
139+
140+
// If there was no reason or the action was an explicit request by the user, don't show a twipsy
141+
if (!reason || reason === "explicit_close") {
142+
return;
143+
}
144+
145+
// Translate the reason
146+
var translatedReason = Strings["LIVE_DEV_" + reason.toUpperCase()];
147+
if (!translatedReason) {
148+
translatedReason = StringUtils.format(Strings.LIVE_DEV_CLOSED_UNKNOWN_REASON, reason);
149+
}
150+
151+
// Configure the twipsy
152+
var options = {
153+
placement: "left",
154+
trigger: "manual",
155+
autoHideDelay: 5000,
156+
title: function () {
157+
return translatedReason;
158+
}
159+
};
160+
161+
// Show the twipsy with the explanation
162+
_$btnGoLive.twipsy(options).twipsy("show");
163+
}
164+
134165
/** Create the menu item "Go Live" */
135166
function _setupGoLiveButton() {
136167
_$btnGoLive = $("#toolbar-go-live");
137168
_$btnGoLive.click(function onGoLive() {
138169
_handleGoLiveCommand();
139170
});
140-
$(LiveDevelopment).on("statusChange", function statusChange(event, status) {
171+
$(LiveDevelopment).on("statusChange", function statusChange(event, status, reason) {
141172
// status starts at -1 (error), so add one when looking up name and style
142173
// See the comments at the top of LiveDevelopment.js for details on the
143174
// various status codes.
144175
_setLabel(_$btnGoLive, null, _statusStyle[status + 1], _statusTooltip[status + 1]);
176+
_showStatusChangeReason(reason);
145177
if (config.autoconnect) {
146178
window.sessionStorage.setItem("live.enabled", status === 3);
147179
}

src/brackets.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ define(function (require, exports, module) {
5353
// Load dependent non-module scripts
5454
require("widgets/bootstrap-dropdown");
5555
require("widgets/bootstrap-modal");
56+
require("widgets/bootstrap-twipsy-mod");
5657
require("thirdparty/path-utils/path-utils.min");
5758
require("thirdparty/smart-auto-complete/jquery.smart_autocomplete");
5859

src/nls/root/strings.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ define({
8787
"LIVE_DEV_STATUS_TIP_PROGRESS2" : "Live Preview: Initializing\u2026",
8888
"LIVE_DEV_STATUS_TIP_CONNECTED" : "Disconnect Live Preview",
8989
"LIVE_DEV_STATUS_TIP_OUT_OF_SYNC" : "Live Preview: Click to disconnect (Save file to update)",
90+
91+
"LIVE_DEV_DETACHED_REPLACED_WITH_DEVTOOLS" : "Live Preview was cancelled because the browser's developer tools were opened",
92+
"LIVE_DEV_DETACHED_TARGET_CLOSED" : "Live Preview was cancelled because the page was closed in the browser",
93+
"LIVE_DEV_NAVIGATED_AWAY" : "Live Preview was cancelled because the browser navigated to a page that is not part of the current project",
94+
"LIVE_DEV_CLOSED_UNKNOWN_REASON" : "Live Preview was cancelled for an unknown reason ({0})",
9095

9196
"SAVE_CLOSE_TITLE" : "Save Changes",
9297
"SAVE_CLOSE_MESSAGE" : "Do you want to save the changes you made in the document <span class='dialog-filename'>{0}</span>?",

src/styles/brackets_patterns_override.less

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,11 @@
572572
}
573573
}
574574

575+
/* Twipsy tooltips */
576+
.twipsy-inner {
577+
max-width: none;
578+
white-space: nowrap;
579+
}
575580

576581
/* Buttons */
577582

0 commit comments

Comments
 (0)