mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-20 17:20:54 +00:00
Bug 1039484 - Prevent closing WebIDE or switch to a new project if any file hasn't been saved. r=paul
This commit is contained in:
parent
c9bb9a8cf5
commit
fc1838f306
@ -155,7 +155,7 @@ var TextEditor = Class({
|
||||
if (!this.editor.isAppended()) {
|
||||
return true;
|
||||
}
|
||||
return this.editor.isClean();
|
||||
return this.editor.getText() === this._savedResourceContents;
|
||||
},
|
||||
|
||||
initialize: function(document, mode=Editor.modes.text) {
|
||||
@ -212,6 +212,7 @@ var TextEditor = Class({
|
||||
if (!this.editor) {
|
||||
return;
|
||||
}
|
||||
this._savedResourceContents = resourceContents;
|
||||
this.editor.setText(resourceContents);
|
||||
this.editor.clearHistory();
|
||||
this.editor.setClean();
|
||||
@ -229,8 +230,9 @@ var TextEditor = Class({
|
||||
* saved.
|
||||
*/
|
||||
save: function(resource) {
|
||||
return resource.save(this.editor.getText()).then(() => {
|
||||
this.editor.setClean();
|
||||
let newText = this.editor.getText();
|
||||
return resource.save(newText).then(() => {
|
||||
this._savedResourceContents = newText;
|
||||
this.emit("save", resource);
|
||||
});
|
||||
},
|
||||
|
@ -31,7 +31,12 @@ var DirtyPlugin = Class({
|
||||
},
|
||||
|
||||
onAnnotate: function(resource, editor, elt) {
|
||||
if (editor && editor.editor && !editor.editor.isClean()) {
|
||||
// Only run on a TextEditor
|
||||
if (!editor || !editor.editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!editor.isClean()) {
|
||||
elt.textContent = '*' + resource.displayName;
|
||||
return true;
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ const { ViewHelpers } = Cu.import("resource:///modules/devtools/ViewHelpers.jsm"
|
||||
const { DOMHelpers } = Cu.import("resource:///modules/devtools/DOMHelpers.jsm");
|
||||
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
const ITCHPAD_URL = "chrome://browser/content/devtools/projecteditor.xul";
|
||||
const { confirm } = require("projecteditor/helpers/prompts");
|
||||
const { getLocalizedString } = require("projecteditor/helpers/l10n");
|
||||
|
||||
// Enabled Plugins
|
||||
require("projecteditor/plugins/dirty/dirty");
|
||||
@ -728,7 +730,37 @@ var ProjectEditor = Class({
|
||||
|
||||
get menuEnabled() {
|
||||
return this._menuEnabled;
|
||||
},
|
||||
|
||||
/**
|
||||
* Are there any unsaved resources in the Project?
|
||||
*/
|
||||
get hasUnsavedResources() {
|
||||
return this.project.allResources().some(resource=> {
|
||||
let editor = this.editorFor(resource);
|
||||
return editor && !editor.isClean();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Check with the user about navigating away with unsaved changes.
|
||||
*
|
||||
* @returns Boolean
|
||||
* True if there are no unsaved changes
|
||||
* Otherwise, ask the user to confirm and return the outcome.
|
||||
*/
|
||||
confirmUnsaved: function() {
|
||||
|
||||
if (this.hasUnsavedResources) {
|
||||
return confirm(
|
||||
getLocalizedString("projecteditor.confirmUnsavedTitle"),
|
||||
getLocalizedString("projecteditor.confirmUnsavedLabel")
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
@ -7,6 +7,7 @@ support-files =
|
||||
|
||||
[browser_projecteditor_app_options.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_projecteditor_confirm_unsaved.js]
|
||||
[browser_projecteditor_contextmenu_01.js]
|
||||
[browser_projecteditor_contextmenu_02.js]
|
||||
[browser_projecteditor_delete_file.js]
|
||||
|
@ -0,0 +1,60 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
loadHelperScript("helper_edits.js");
|
||||
|
||||
// Test that a prompt shows up when requested if a file is unsaved.
|
||||
let test = asyncTest(function*() {
|
||||
let projecteditor = yield addProjectEditorTabForTempDirectory();
|
||||
ok(true, "ProjectEditor has loaded");
|
||||
|
||||
let resources = projecteditor.project.allResources();
|
||||
yield selectFile(projecteditor, resources[2]);
|
||||
let editor = projecteditor.currentEditor;
|
||||
let originalText = editor.editor.getText();
|
||||
|
||||
ok (!projecteditor.hasUnsavedResources, "There are no unsaved resources");
|
||||
ok (projecteditor.confirmUnsaved(), "When there are no unsaved changes, confirmUnsaved() is true");
|
||||
editor.editor.setText("bar");
|
||||
editor.editor.setText(originalText);
|
||||
ok (!projecteditor.hasUnsavedResources, "There are no unsaved resources");
|
||||
ok (projecteditor.confirmUnsaved(), "When an editor has changed but is still the original text, confirmUnsaved() is true");
|
||||
|
||||
editor.editor.setText("bar");
|
||||
|
||||
checkConfirmYes(projecteditor);
|
||||
checkConfirmNo(projecteditor);
|
||||
});
|
||||
|
||||
function checkConfirmYes(projecteditor, container) {
|
||||
function confirmYes(aSubject) {
|
||||
info("confirm dialog observed as expected, going to click OK");
|
||||
Services.obs.removeObserver(confirmYes, "common-dialog-loaded");
|
||||
Services.obs.removeObserver(confirmYes, "tabmodal-dialog-loaded");
|
||||
aSubject.Dialog.ui.button0.click();
|
||||
}
|
||||
|
||||
Services.obs.addObserver(confirmYes, "common-dialog-loaded", false);
|
||||
Services.obs.addObserver(confirmYes, "tabmodal-dialog-loaded", false);
|
||||
|
||||
ok (projecteditor.hasUnsavedResources, "There are unsaved resources");
|
||||
ok (projecteditor.confirmUnsaved(), "When there are unsaved changes, clicking OK makes confirmUnsaved() true");
|
||||
}
|
||||
|
||||
function checkConfirmNo(projecteditor, container) {
|
||||
function confirmNo(aSubject) {
|
||||
info("confirm dialog observed as expected, going to click cancel");
|
||||
Services.obs.removeObserver(confirmNo, "common-dialog-loaded");
|
||||
Services.obs.removeObserver(confirmNo, "tabmodal-dialog-loaded");
|
||||
aSubject.Dialog.ui.button1.click();
|
||||
}
|
||||
|
||||
Services.obs.addObserver(confirmNo, "common-dialog-loaded", false);
|
||||
Services.obs.addObserver(confirmNo, "tabmodal-dialog-loaded", false);
|
||||
|
||||
ok (projecteditor.hasUnsavedResources, "There are unsaved resources");
|
||||
ok (!projecteditor.confirmUnsaved(), "When there are unsaved changes, clicking cancel makes confirmUnsaved() false");
|
||||
}
|
@ -100,6 +100,13 @@ let UI = {
|
||||
window.removeEventListener("message", this.onMessage);
|
||||
},
|
||||
|
||||
canWindowClose: function() {
|
||||
if (this.projecteditor) {
|
||||
return this.projecteditor.confirmUnsaved();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
onfocus: function() {
|
||||
// Because we can't track the activity in the folder project,
|
||||
// we need to validate the project regularly. Let's assume that
|
||||
@ -665,7 +672,9 @@ let UI = {
|
||||
|
||||
let Cmds = {
|
||||
quit: function() {
|
||||
window.close();
|
||||
if (UI.canWindowClose()) {
|
||||
window.close();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,7 @@
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css"?>
|
||||
<?xml-stylesheet href="chrome://webide/skin/webide.css"?>
|
||||
|
||||
<window id="webide"
|
||||
<window id="webide" onclose="return UI.canWindowClose();"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
title="&windowTitle;"
|
||||
|
@ -11,6 +11,16 @@
|
||||
# A good criteria is the language in which you'd find the best
|
||||
# documentation on web development on the web.
|
||||
|
||||
# LOCALIZATION NOTE (projecteditor.confirmUnsavedTitle):
|
||||
# This string is displayed as as the title of the confirm prompt that checks
|
||||
# to make sure if the project editor can be closed without saving changes
|
||||
projecteditor.confirmUnsavedTitle=Unsaved Changes
|
||||
|
||||
# LOCALIZATION NOTE (projecteditor.confirmUnsavedLabel):
|
||||
# This string is displayed as the message of the confirm prompt that checks
|
||||
# to make sure if the project editor can be closed without saving changes
|
||||
projecteditor.confirmUnsavedLabel=You have unsaved changes that will be lost if you exit. Are you sure you want to continue?
|
||||
|
||||
# LOCALIZATION NOTE (projecteditor.deleteLabel):
|
||||
# This string is displayed as a context menu item for allowing the selected
|
||||
# file / folder to be deleted.
|
||||
|
Loading…
x
Reference in New Issue
Block a user