@@ -518,6 +518,7 @@ <h3>Dependencies</h3>
518518 < li > < a href ="../../modules/widgets/Dialogs.html "> Dialogs</ a > </ li >
519519 < li > < a href ="../../modules/document/DocumentManager.html "> DocumentManager</ a > </ li >
520520 < li > < a href ="../../modules/editor/EditorManager.html "> EditorManager</ a > </ li >
521+ < li > < a href ="../../modules/utils/EventDispatcher.html "> EventDispatcher</ a > </ li >
521522 < li > < a href ="../../modules/filesystem/FileSystem.html "> FileSystem</ a > </ li >
522523 < li > < a href ="../../modules/filesystem/FileSystemError.html "> FileSystemError</ a > </ li >
523524 < li > < a href ="../../modules/file/FileUtils.html "> FileUtils</ a > </ li >
@@ -549,7 +550,25 @@ <h3>Variables
549550 < input class ="toggle-public " type ="checkbox "> Show Private Members
550551</ label > </ h3 >
551552
552- < div class ="member ">
553+ < div class ="member public ">
554+
555+ < span class ="pull-right scope ">
556+
557+ Public API
558+ </ span >
559+ < h4 >
560+ APP_QUIT_CANCELLED
561+ < a class ="anchor " href ="#-APP_QUIT_CANCELLED " id ="-APP_QUIT_CANCELLED "> < span class ="icon-link "> </ span > </ a >
562+ </ h4 >
563+
564+
565+ < div class ="description "> < p > Event triggered when File Save is cancelled, when prompted to save dirty files</ p >
566+ </ div >
567+
568+ < dl >
569+ </ dl > < dl >
570+ < dl > < button class ="btn btn-small show-code "> Show code</ button >
571+ < pre class ="code language-javascript "> < code class ="language-javascript "> var APP_QUIT_CANCELLED = "appQuitCancelled";</ code > </ pre > </ div > < div class ="member ">
553572
554573< span class ="pull-right scope ">
555574
571590
572591 PreferencesManager.definePreference("defaultExtension", "string", "", {
573592 excludeFromHints: true
574- });</ code > </ pre > </ div > < div class ="member ">
593+ });
594+ EventDispatcher.makeEventDispatcher(exports);</ code > </ pre > </ div > < div class ="member ">
575595
576596< span class ="pull-right scope ">
577597
@@ -903,7 +923,47 @@ <h4>
903923< dl >
904924</ dl > < dl >
905925< dl > < button class ="btn btn-small show-code "> Show code</ button >
906- < pre class ="code language-javascript "> < code class ="language-javascript "> var handleReloadWithoutExts = _.partial(handleReload, true);</ code > </ pre > </ div >
926+ < pre class ="code language-javascript "> < code class ="language-javascript "> var handleReloadWithoutExts = _.partial(handleReload, true);</ code > </ pre > </ div > < div class ="member ">
927+
928+ < span class ="pull-right scope ">
929+
930+
931+ </ span >
932+ < h4 >
933+ isTestWindow
934+ < a class ="anchor " href ="#-isTestWindow " id ="-isTestWindow "> < span class ="icon-link "> </ span > </ a >
935+ </ h4 >
936+
937+
938+ < div class ="description "> < p > Attach a beforeunload handler to notify user about unsaved changes and URL redirection in CEF.
939+ Prevents data loss in scenario reported under #13708
940+ Make sure we don't attach this handler if the current window is actually a test window</ p >
941+ </ div >
942+
943+ < dl >
944+ </ dl > < dl >
945+ < dl > < button class ="btn btn-small show-code "> Show code</ button >
946+ < pre class ="code language-javascript "> < code class ="language-javascript ">
947+ var isTestWindow = (new window.URLSearchParams(window.location.search || "")).get("testEnvironment");
948+ if (!isTestWindow) {
949+ window.onbeforeunload = function(e) {
950+ var openDocs = DocumentManager.getAllOpenDocuments();
951+
952+ // Detect any unsaved changes
953+ openDocs = openDocs.filter(function(doc) {
954+ return doc && doc.isDirty;
955+ });
956+
957+ // Ensure we are not in normal app-quit or reload workflow
958+ if (!_isReloading && !_windowGoingAway) {
959+ if (openDocs.length > 0) {
960+ return Strings.WINDOW_UNLOAD_WARNING_WITH_UNSAVED_CHANGES;
961+ } else {
962+ return Strings.WINDOW_UNLOAD_WARNING;
963+ }
964+ }
965+ };
966+ }</ code > </ pre > </ div >
907967</ section >
908968
909969< section id ="functions ">
@@ -1004,6 +1064,7 @@ <h4>
10041064 )
10051065 .done(function (id) {
10061066 if (id === Dialogs.DIALOG_BTN_CANCEL) {
1067+ dispatchAppQuitCancelledEvent();
10071068 result.reject();
10081069 } else if (id === Dialogs.DIALOG_BTN_OK) {
10091070 // Save all unsaved files, then if that succeeds, close all
@@ -1510,6 +1571,7 @@ <h4>
15101571 if (selectedPath) {
15111572 _doSaveAfterSaveDialog(selectedPath);
15121573 } else {
1574+ dispatchAppQuitCancelledEvent();
15131575 result.reject(USER_CANCELED);
15141576 }
15151577 } else {
@@ -1914,7 +1976,9 @@ <h4>
19141976< pre class ="code language-javascript "> < code class ="language-javascript "> function _updateTitle() {
19151977 var currentDoc = DocumentManager.getCurrentDocument(),
19161978 windowTitle = brackets.config.app_title,
1917- currentlyViewedPath = MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE);
1979+ currentlyViewedFile = MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE),
1980+ currentlyViewedPath = currentlyViewedFile && currentlyViewedFile.fullPath,
1981+ readOnlyString = (currentlyViewedFile && currentlyViewedFile.readOnly) ? "[Read Only] - " : "";
19181982
19191983 if (!brackets.nativeMenus) {
19201984 if (currentlyViewedPath) {
@@ -1954,7 +2018,7 @@ <h4>
19542018 var projectName = projectRoot.name;
19552019 // Construct shell/browser window title, e.g. "• index.html (myProject) — Brackets"
19562020 if (currentlyViewedPath) {
1957- windowTitle = StringUtils.format(WINDOW_TITLE_STRING_DOC, _currentTitlePath, projectName, brackets.config.app_title);
2021+ windowTitle = StringUtils.format(WINDOW_TITLE_STRING_DOC, readOnlyString + _currentTitlePath, projectName, brackets.config.app_title);
19582022 // Display dirty dot when there are unsaved changes
19592023 if (currentDoc && currentDoc.isDirty) {
19602024 windowTitle = "• " + windowTitle;
@@ -2066,6 +2130,28 @@ <h4>
20662130< span class ="pull-right scope ">
20672131
20682132
2133+ </ span >
2134+ < h4 >
2135+ dispatchAppQuitCancelledEvent
2136+ < a class ="anchor " href ="#-dispatchAppQuitCancelledEvent " id ="-dispatchAppQuitCancelledEvent "> < span class ="icon-link "> </ span > </ a >
2137+ </ h4 >
2138+
2139+
2140+ < div class ="description "> < p > Dispatches the app quit cancelled event</ p >
2141+ </ div >
2142+
2143+ < dl >
2144+ </ dl > < dl >
2145+ </ dl > < dl >
2146+ </ dl > < dl >
2147+ < dl > < button class ="btn btn-small show-code "> Show code</ button >
2148+ < pre class ="code language-javascript "> < code class ="language-javascript "> function dispatchAppQuitCancelledEvent() {
2149+ exports.trigger(exports.APP_QUIT_CANCELLED);
2150+ }</ code > </ pre > </ div > < div class ="member ">
2151+
2152+ < span class ="pull-right scope ">
2153+
2154+
20692155</ span >
20702156 < h4 >
20712157 doSave
@@ -2570,6 +2656,7 @@ <h4>
25702656 )
25712657 .done(function (id) {
25722658 if (id === Dialogs.DIALOG_BTN_CANCEL) {
2659+ dispatchAppQuitCancelledEvent();
25732660 result.reject();
25742661 } else if (id === Dialogs.DIALOG_BTN_OK) {
25752662 // "Save" case: wait until we confirm save has succeeded before closing
0 commit comments