--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -4,18 +4,16 @@
devtools.jar:
% content devtools %content/
content/shared/vendor/d3.js (shared/vendor/d3.js)
content/shared/vendor/dagre-d3.js (shared/vendor/dagre-d3.js)
content/shared/widgets/widgets.css (shared/widgets/widgets.css)
content/netmonitor/src/assets/styles/netmonitor.css (netmonitor/src/assets/styles/netmonitor.css)
content/shared/widgets/VariablesView.xul (shared/widgets/VariablesView.xul)
- content/projecteditor/chrome/content/projecteditor.xul (projecteditor/chrome/content/projecteditor.xul)
- content/projecteditor/lib/helpers/readdir.js (projecteditor/lib/helpers/readdir.js)
content/netmonitor/index.html (netmonitor/index.html)
content/webconsole/webconsole.xul (webconsole/webconsole.xul)
content/scratchpad/scratchpad.xul (scratchpad/scratchpad.xul)
content/scratchpad/scratchpad.js (scratchpad/scratchpad.js)
content/shared/splitview.css (shared/splitview.css)
content/shared/theme-switching.js (shared/theme-switching.js)
content/shared/frame-script-utils.js (shared/frame-script-utils.js)
content/styleeditor/styleeditor.xul (styleeditor/styleeditor.xul)
@@ -248,17 +246,16 @@ devtools.jar:
skin/images/sort-descending-arrow.svg (themes/images/sort-descending-arrow.svg)
skin/images/cubic-bezier-swatch.png (themes/images/cubic-bezier-swatch.png)
skin/images/cubic-bezier-swatch@2x.png (themes/images/cubic-bezier-swatch@2x.png)
skin/fonts.css (themes/fonts.css)
skin/computed.css (themes/computed.css)
skin/layout.css (themes/layout.css)
skin/images/arrow-e.png (themes/images/arrow-e.png)
skin/images/arrow-e@2x.png (themes/images/arrow-e@2x.png)
- skin/projecteditor/projecteditor.css (themes/projecteditor/projecteditor.css)
skin/images/search-clear-failed.svg (themes/images/search-clear-failed.svg)
skin/images/search-clear-light.svg (themes/images/search-clear-light.svg)
skin/images/search-clear-dark.svg (themes/images/search-clear-dark.svg)
skin/tooltip/arrow-horizontal-dark.png (themes/tooltip/arrow-horizontal-dark.png)
skin/tooltip/arrow-horizontal-dark@2x.png (themes/tooltip/arrow-horizontal-dark@2x.png)
skin/tooltip/arrow-vertical-dark.png (themes/tooltip/arrow-vertical-dark.png)
skin/tooltip/arrow-vertical-dark@2x.png (themes/tooltip/arrow-vertical-dark@2x.png)
skin/tooltip/arrow-horizontal-light.png (themes/tooltip/arrow-horizontal-light.png)
deleted file mode 100644
--- a/devtools/client/locales/en-US/projecteditor.properties
+++ /dev/null
@@ -1,88 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# LOCALIZATION NOTE These strings are used inside the ProjectEditor component
-# which is used for editing files in a directory and is used inside the
-# App Manager.
-# The correct localization of this file might be to keep it in
-# English, or another language commonly spoken among web developers.
-# You want to make that choice consistent across the developer tools.
-# 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 can be closed/switched without saving changes
-projecteditor.confirmUnsavedTitle=Unsaved Changes
-
-# LOCALIZATION NOTE (projecteditor.confirmUnsavedLabel2):
-# This string is displayed as the message of the confirm prompt that checks
-# to make sure if the project can be closed/switched without saving changes
-projecteditor.confirmUnsavedLabel2=You have unsaved changes that will be lost. 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.
-projecteditor.deleteLabel=Delete
-
-# LOCALIZATION NOTE (projecteditor.deletePromptTitle):
-# This string is displayed as as the title of the confirm prompt that checks
-# to make sure if a file or folder should be removed.
-projecteditor.deletePromptTitle=Delete
-
-# LOCALIZATION NOTE (projecteditor.deleteFolderPromptMessage):
-# This string is displayed as as the message of the confirm prompt that checks
-# to make sure if a folder should be removed.
-projecteditor.deleteFolderPromptMessage=Are you sure you want to delete this folder?
-
-# LOCALIZATION NOTE (projecteditor.deleteFilePromptMessage):
-# This string is displayed as as the message of the confirm prompt that checks
-# to make sure if a file should be removed.
-projecteditor.deleteFilePromptMessage=Are you sure you want to delete this file?
-
-# LOCALIZATION NOTE (projecteditor.newLabel):
-# This string is displayed as a menu item for adding a new file to
-# the directory.
-projecteditor.newLabel=New…
-
-# LOCALIZATION NOTE (projecteditor.renameLabel):
-# This string is displayed as a menu item for renaming a file in
-# the directory.
-projecteditor.renameLabel=Rename
-
-# LOCALIZATION NOTE (projecteditor.saveLabel):
-# This string is displayed as a menu item for saving the current file.
-projecteditor.saveLabel=Save
-
-# LOCALIZATION NOTE (projecteditor.saveAsLabel):
-# This string is displayed as a menu item for saving the current file
-# with a new name.
-projecteditor.saveAsLabel=Save As…
-
-# LOCALIZATION NOTE (projecteditor.selectFileLabel):
-# This string is displayed as the title on the file picker when saving a file.
-projecteditor.selectFileLabel=Select a File
-
-# LOCALIZATION NOTE (projecteditor.openFolderLabel):
-# This string is displayed as the title on the file picker when opening a folder.
-projecteditor.openFolderLabel=Select a Folder
-
-# LOCALIZATION NOTE (projecteditor.openFileLabel):
-# This string is displayed as the title on the file picker when opening a file.
-projecteditor.openFileLabel=Open a File
-
-# LOCALIZATION NOTE (projecteditor.find.commandkey): This is the key to use in
-# conjunction with accel (Command on Mac or Ctrl on other platforms) to search
-# text in the files.
-projecteditor.find.commandkey=F
-
-# LOCALIZATION NOTE (projecteditor.save.commandkey): This is the key to use in
-# conjunction with accel (Command on Mac or Ctrl on other platforms) to
-# save the file. It is used with accel+shift to "save as".
-projecteditor.save.commandkey=S
-
-# LOCALIZATION NOTE (projecteditor.new.commandkey): This is the key to use in
-# conjunction with accel (Command on Mac or Ctrl on other platforms) to
-# create a new file.
-projecteditor.new.commandkey=N
--- a/devtools/client/moz.build
+++ b/devtools/client/moz.build
@@ -16,17 +16,16 @@ DIRS += [
'framework',
'inspector',
'jsonview',
'locales',
'memory',
'netmonitor',
'performance',
'preferences',
- 'projecteditor',
'responsive.html',
'responsivedesign',
'scratchpad',
'shadereditor',
'shared',
'shims',
'sourceeditor',
'storage',
@@ -48,10 +47,10 @@ EXTRA_COMPONENTS += [
JAR_MANIFESTS += ['jar.mn']
DevToolsModules(
'definitions.js',
'menus.js',
)
-with Files('**'):
- BUG_COMPONENT = ('Firefox', 'Developer Tools')
+with Files('**'):
+ BUG_COMPONENT = ('Firefox', 'Developer Tools')
deleted file mode 100644
--- a/devtools/client/projecteditor/chrome/content/projecteditor.xul
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<?xml-stylesheet href="chrome://devtools/skin/light-theme.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/projecteditor/projecteditor.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/content/debugger/debugger.css" type="text/css"?>
-<?xml-stylesheet href="resource://devtools/client/themes/common.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/markup.css" type="text/css"?>
-
-<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
-
-<!DOCTYPE window [
-<!ENTITY % scratchpadDTD SYSTEM "chrome://devtools/locale/scratchpad.dtd" >
- %scratchpadDTD;
-<!ENTITY % editMenuStrings SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
-%editMenuStrings;
-<!ENTITY % sourceEditorStrings SYSTEM "chrome://devtools/locale/sourceeditor.dtd">
-%sourceEditorStrings;
-]>
-
-<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" class="theme-body theme-light">
-
- <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
-
- <commandset id="projecteditor-commandset" />
- <commandset id="editMenuCommands"/>
- <keyset id="projecteditor-keyset" />
- <keyset id="editMenuKeys"/>
-
- <!-- Eventually we want to let plugins declare their own menu items.
- Wait unti app manager lands to deal with this integration point.
- -->
- <menubar id="projecteditor-menubar">
- <menu id="file-menu" label="&fileMenu.label;" accesskey="&fileMenu.accesskey;">
- <menupopup id="file-menu-popup" />
- </menu>
-
- <menu id="edit-menu" label="&editMenu.label;"
- accesskey="&editMenu.accesskey;">
- <menupopup id="edit-menu-popup">
- <menuitem id="menu_undo"/>
- <menuitem id="menu_redo"/>
- <menuseparator/>
- <menuitem id="menu_cut"/>
- <menuitem id="menu_copy"/>
- <menuitem id="menu_paste"/>
- </menupopup>
- </menu>
- </menubar>
-
- <popupset>
- <menupopup id="context-menu-popup">
- </menupopup>
- <menupopup id="texteditor-context-popup">
- <menuitem id="cMenu_cut"/>
- <menuitem id="cMenu_copy"/>
- <menuitem id="cMenu_paste"/>
- <menuitem id="cMenu_delete"/>
- <menuseparator/>
- <menuitem id="cMenu_selectAll"/>
- </menupopup>
- </popupset>
-
- <deck id="main-deck" flex="1">
- <vbox flex="1" id="source-deckitem">
- <hbox id="sources-body" flex="1">
- <vbox width="250" id="sources">
- <vbox flex="1">
- </vbox>
- <toolbar id="project-toolbar" class="devtools-toolbar" hidden="true"></toolbar>
- </vbox>
- <splitter id="source-editor-splitter" class="devtools-side-splitter"/>
- <vbox id="shells" flex="4">
- <toolbar id="projecteditor-toolbar" class="devtools-toolbar">
- <hbox id="plugin-toolbar-left"/>
- <spacer flex="1"/>
- <hbox id="plugin-toolbar-right"/>
- </toolbar>
- <box id="shells-deck-container" flex="4"></box>
- <toolbar id="projecteditor-toolbar-bottom" class="devtools-toolbar">
- </toolbar>
- </vbox>
- </hbox>
- </vbox>
- </deck>
-</page>
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/editors.js
+++ /dev/null
@@ -1,303 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const { EventTarget } = require("sdk/event/target");
-const { emit } = require("sdk/event/core");
-const promise = require("promise");
-const Editor = require("devtools/client/sourceeditor/editor");
-const HTML_NS = "http://www.w3.org/1999/xhtml";
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-/**
- * ItchEditor is extended to implement an editor, which is the main view
- * that shows up when a file is selected. This object should not be used
- * directly - use TextEditor for a basic code editor.
- */
-var ItchEditor = Class({
- extends: EventTarget,
-
- /**
- * A boolean specifying if the toolbar above the editor should be hidden.
- */
- hidesToolbar: false,
-
- /**
- * A boolean specifying whether the editor can be edited / saved.
- * For instance, a 'save' doesn't make sense on an image.
- */
- isEditable: false,
-
- toString: function () {
- return this.label || "";
- },
-
- emit: function (name, ...args) {
- emit(this, name, ...args);
- },
-
- /* Does the editor not have any unsaved changes? */
- isClean: function () {
- return true;
- },
-
- /**
- * Initialize the editor with a single host. This should be called
- * by objects extending this object with:
- * ItchEditor.prototype.initialize.apply(this, arguments)
- */
- initialize: function (host) {
- this.host = host;
- this.doc = host.document;
- this.label = "";
- this.elt = this.doc.createElement("vbox");
- this.elt.setAttribute("flex", "1");
- this.elt.editor = this;
- this.toolbar = this.doc.querySelector("#projecteditor-toolbar");
- this.projectEditorKeyset = host.projectEditorKeyset;
- this.projectEditorCommandset = host.projectEditorCommandset;
- },
-
- /**
- * Sets the visibility of the element that shows up above the editor
- * based on the this.hidesToolbar property.
- */
- setToolbarVisibility: function () {
- if (this.hidesToolbar) {
- this.toolbar.setAttribute("hidden", "true");
- } else {
- this.toolbar.removeAttribute("hidden");
- }
- },
-
-
- /**
- * Load a single resource into the editor.
- *
- * @param Resource resource
- * The single file / item that is being dealt with (see stores/base)
- * @returns Promise
- * A promise that is resolved once the editor has loaded the contents
- * of the resource.
- */
- load: function (resource) {
- return promise.resolve();
- },
-
- /**
- * Clean up the editor. This can have different meanings
- * depending on the type of editor.
- */
- destroy: function () {
-
- },
-
- /**
- * Give focus to the editor. This can have different meanings
- * depending on the type of editor.
- *
- * @returns Promise
- * A promise that is resolved once the editor has been focused.
- */
- focus: function () {
- return promise.resolve();
- }
-});
-exports.ItchEditor = ItchEditor;
-
-/**
- * The main implementation of the ItchEditor class. The TextEditor is used
- * when editing any sort of plain text file, and can be created with different
- * modes for syntax highlighting depending on the language.
- */
-var TextEditor = Class({
- extends: ItchEditor,
-
- isEditable: true,
-
- /**
- * Extra keyboard shortcuts to use with the editor. Shortcuts defined
- * within projecteditor should be triggered when they happen in the editor, and
- * they would usually be swallowed without registering them.
- * See "devtools/sourceeditor/editor" for more information.
- */
- get extraKeys() {
- let extraKeys = {};
-
- // Copy all of the registered keys into extraKeys object, to notify CodeMirror
- // that it should be ignoring these keys
- [...this.projectEditorKeyset.querySelectorAll("key")].forEach((key) => {
- let keyUpper = key.getAttribute("key").toUpperCase();
- let toolModifiers = key.getAttribute("modifiers");
- let modifiers = {
- alt: toolModifiers.includes("alt"),
- shift: toolModifiers.includes("shift")
- };
-
- // On the key press, we will dispatch the event within projecteditor.
- extraKeys[Editor.accel(keyUpper, modifiers)] = () => {
- let doc = this.projectEditorCommandset.ownerDocument;
- let event = doc.createEvent("Event");
- event.initEvent("command", true, true);
- let command = this.projectEditorCommandset.querySelector("#" + key.getAttribute("command"));
- command.dispatchEvent(event);
- };
- });
-
- return extraKeys;
- },
-
- isClean: function () {
- if (!this.editor.isAppended()) {
- return true;
- }
- return this.editor.getText() === this._savedResourceContents;
- },
-
- initialize: function (document, mode = Editor.modes.text) {
- ItchEditor.prototype.initialize.apply(this, arguments);
- this.label = mode.name;
- this.editor = new Editor({
- mode: mode,
- lineNumbers: true,
- extraKeys: this.extraKeys,
- themeSwitching: false,
- autocomplete: true,
- contextMenu: this.host.textEditorContextMenuPopup
- });
-
- // Trigger a few editor specific events on `this`.
- this.editor.on("change", (...args) => {
- this.emit("change", ...args);
- });
- this.editor.on("cursorActivity", (...args) => {
- this.emit("cursorActivity", ...args);
- });
- this.editor.on("focus", (...args) => {
- this.emit("focus", ...args);
- });
- this.editor.on("saveRequested", (...args) => {
- this.emit("saveRequested", ...args);
- });
-
- this.appended = this.editor.appendTo(this.elt);
- },
-
- /**
- * Clean up the editor. This can have different meanings
- * depending on the type of editor.
- */
- destroy: function () {
- this.editor.destroy();
- this.editor = null;
- },
-
- /**
- * Load a single resource into the text editor.
- *
- * @param Resource resource
- * The single file / item that is being dealt with (see stores/base)
- * @returns Promise
- * A promise that is resolved once the text editor has loaded the
- * contents of the resource.
- */
- load: function (resource) {
- // Wait for the editor.appendTo and resource.load before proceeding.
- // They can run in parallel.
- return promise.all([
- resource.load(),
- this.appended
- ]).then(([resourceContents])=> {
- if (!this.editor) {
- return;
- }
- this._savedResourceContents = resourceContents;
- this.editor.setText(resourceContents);
- this.editor.clearHistory();
- this.editor.setClean();
- this.emit("load");
- }, console.error);
- },
-
- /**
- * Save the resource based on the current state of the editor
- *
- * @param Resource resource
- * The single file / item to be saved
- * @returns Promise
- * A promise that is resolved once the resource has been
- * saved.
- */
- save: function (resource) {
- let newText = this.editor.getText();
- return resource.save(newText).then(() => {
- this._savedResourceContents = newText;
- this.emit("save", resource);
- });
- },
-
- /**
- * Give focus to the code editor.
- *
- * @returns Promise
- * A promise that is resolved once the editor has been focused.
- */
- focus: function () {
- return this.appended.then(() => {
- if (this.editor) {
- this.editor.focus();
- }
- });
- }
-});
-
-/**
- * Wrapper for TextEditor using JavaScript syntax highlighting.
- */
-function JSEditor(host) {
- return TextEditor(host, Editor.modes.js);
-}
-
-/**
- * Wrapper for TextEditor using CSS syntax highlighting.
- */
-function CSSEditor(host) {
- return TextEditor(host, Editor.modes.css);
-}
-
-/**
- * Wrapper for TextEditor using HTML syntax highlighting.
- */
-function HTMLEditor(host) {
- return TextEditor(host, Editor.modes.html);
-}
-
-/**
- * Get the type of editor that can handle a particular resource.
- * @param Resource resource
- * The single file that is going to be opened.
- * @returns Type:Editor
- * The type of editor that can handle this resource. The
- * return value is a constructor function.
- */
-function EditorTypeForResource(resource) {
- const categoryMap = {
- "txt": TextEditor,
- "html": HTMLEditor,
- "xml": HTMLEditor,
- "css": CSSEditor,
- "js": JSEditor,
- "json": JSEditor
- };
- return categoryMap[resource.contentCategory] || TextEditor;
-}
-
-exports.TextEditor = TextEditor;
-exports.JSEditor = JSEditor;
-exports.CSSEditor = CSSEditor;
-exports.HTMLEditor = HTMLEditor;
-exports.EditorTypeForResource = EditorTypeForResource;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/helpers/event.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * This file wraps EventEmitter objects to provide functions to forget
- * all events bound on a certain object.
- */
-
-const { Class } = require("sdk/core/heritage");
-
-/**
- * The Scope object is used to keep track of listeners.
- * This object is not exported.
- */
-var Scope = Class({
- on: function (target, event, handler) {
- this.listeners = this.listeners || [];
- this.listeners.push({
- target: target,
- event: event,
- handler: handler
- });
- target.on(event, handler);
- },
-
- off: function (t, e, h) {
- if (!this.listeners) return;
- this.listeners = this.listeners.filter(({ target, event, handler }) => {
- return !(target === t && event === e && handler === h);
- });
- target.off(event, handler);
- },
-
- clear: function (clearTarget) {
- if (!this.listeners) return;
- this.listeners = this.listeners.filter(({ target, event, handler }) => {
- if (target === clearTarget) {
- target.off(event, handler);
- return false;
- }
- return true;
- });
- },
-
- destroy: function () {
- if (!this.listeners) return;
- this.listeners.forEach(({ target, event, handler }) => {
- target.off(event, handler);
- });
- this.listeners = undefined;
- }
-});
-
-var scopes = new WeakMap();
-function scope(owner) {
- if (!scopes.has(owner)) {
- let scope = new Scope(owner);
- scopes.set(owner, scope);
- return scope;
- }
- return scopes.get(owner);
-}
-exports.scope = scope;
-
-exports.on = function on(owner, target, event, handler) {
- if (!target) return;
- scope(owner).on(target, event, handler);
-};
-
-exports.off = function off(owner, target, event, handler) {
- if (!target) return;
- scope(owner).off(target, event, handler);
-};
-
-exports.forget = function forget(owner, target) {
- scope(owner).clear(target);
-};
-
-exports.done = function done(owner) {
- scope(owner).destroy();
- scopes.delete(owner);
-};
-
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/helpers/file-picker.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * This file contains helper functions for showing OS-specific
- * file and folder pickers.
- */
-
-const { Cu, Cc, Ci } = require("chrome");
-const { FileUtils } = Cu.import("resource://gre/modules/FileUtils.jsm", {});
-const promise = require("promise");
-const { merge } = require("sdk/util/object");
-const { getLocalizedString } = require("devtools/client/projecteditor/lib/helpers/l10n");
-
-/**
- * Show a file / folder picker.
- * https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker
- *
- * @param object options
- * Additional options for setting the source. Supported options:
- * - directory: string, The path to default opening
- * - defaultName: string, The filename including extension that
- * should be suggested to the user as a default
- * - window: DOMWindow, The filename including extension that
- * should be suggested to the user as a default
- * - title: string, The filename including extension that
- * should be suggested to the user as a default
- * - mode: int, The type of picker to open.
- *
- * @return promise
- * A promise that is resolved with the full path
- * after the file has been picked.
- */
-function showPicker(options) {
- let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
- if (options.directory) {
- try {
- fp.displayDirectory = FileUtils.File(options.directory);
- } catch (ex) {
- console.warn(ex);
- }
- }
-
- if (options.defaultName) {
- fp.defaultString = options.defaultName;
- }
-
- fp.init(options.window, options.title, options.mode);
- let deferred = promise.defer();
- fp.open({
- done: function (res) {
- if (res === Ci.nsIFilePicker.returnOK || res === Ci.nsIFilePicker.returnReplace) {
- deferred.resolve(fp.file.path);
- } else {
- deferred.reject();
- }
- }
- });
- return deferred.promise;
-}
-exports.showPicker = showPicker;
-
-/**
- * Show a save dialog
- * https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker
- *
- * @param object options
- * Additional options as specified in showPicker
- *
- * @return promise
- * A promise that is resolved when the save dialog has closed
- */
-function showSave(options) {
- return showPicker(merge({
- title: getLocalizedString("projecteditor.selectFileLabel"),
- mode: Ci.nsIFilePicker.modeSave
- }, options));
-}
-exports.showSave = showSave;
-
-/**
- * Show a file open dialog
- *
- * @param object options
- * Additional options as specified in showPicker
- *
- * @return promise
- * A promise that is resolved when the file has been opened
- */
-function showOpen(options) {
- return showPicker(merge({
- title: getLocalizedString("projecteditor.openFileLabel"),
- mode: Ci.nsIFilePicker.modeOpen
- }, options));
-}
-exports.showOpen = showOpen;
-
-/**
- * Show a folder open dialog
- *
- * @param object options
- * Additional options as specified in showPicker
- *
- * @return promise
- * A promise that is resolved when the folder has been opened
- */
-function showOpenFolder(options) {
- return showPicker(merge({
- title: getLocalizedString("projecteditor.openFolderLabel"),
- mode: Ci.nsIFilePicker.modeGetFolder
- }, options));
-}
-exports.showOpenFolder = showOpenFolder;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/helpers/l10n.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-/**
- * This file contains helper functions for internationalizing projecteditor strings
- */
-
-const { LocalizationHelper } = require("devtools/shared/l10n");
-const ITCHPAD_STRINGS_URI = "devtools/client/locales/projecteditor.properties";
-const L10N = new LocalizationHelper(ITCHPAD_STRINGS_URI);
-
-function getLocalizedString(name) {
- try {
- return L10N.getStr(name);
- } catch (ex) {
- console.log("Error reading '" + name + "'");
- throw new Error("l10n error with " + name);
- }
-}
-
-exports.getLocalizedString = getLocalizedString;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/helpers/moz.build
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'event.js',
- 'file-picker.js',
- 'l10n.js',
- 'prompts.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/helpers/prompts.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * This file contains helper functions for showing user prompts.
- * See https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService
- */
-
-const { Cu, Cc, Ci } = require("chrome");
-const { getLocalizedString } = require("devtools/client/projecteditor/lib/helpers/l10n");
-const prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Ci.nsIPromptService);
-
-/**
- * Show a prompt.
- *
- * @param string title
- * The title to the dialog
- * @param string message
- * The message to display
- *
- * @return bool
- * Whether the user has confirmed the action
- */
-function confirm(title, message) {
- var result = prompts.confirm(null, title || "Title of this Dialog", message || "Are you sure?");
- return result;
-}
-exports.confirm = confirm;
-
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/helpers/readdir.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-importScripts("resource://gre/modules/osfile.jsm");
-
-/**
- * This file is meant to be loaded in a worker using:
- * new ChromeWorker("chrome://devtools/content/projecteditor/lib/helpers/readdir.js");
- *
- * Read a local directory inside of a web woker
- *
- * @param {string} path
- * window to inspect
- * @param {RegExp|string} ignore
- * A pattern to ignore certain files. This is
- * called with file.name.match(ignore).
- * @param {Number} maxDepth
- * How many directories to recurse before stopping.
- * Directories with depth > maxDepth will be ignored.
- */
-function readDir(path, ignore, maxDepth = Infinity) {
- let ret = {};
-
- let set = new Set();
-
- let info = OS.File.stat(path);
- set.add({
- path: path,
- name: info.name,
- isDir: info.isDir,
- isSymLink: info.isSymLink,
- depth: 0
- });
-
- for (let info of set) {
- let children = [];
-
- if (info.isDir && !info.isSymLink) {
- if (info.depth > maxDepth) {
- continue;
- }
-
- let iterator = new OS.File.DirectoryIterator(info.path);
- try {
- for (let child in iterator) {
- if (ignore && child.name.match(ignore)) {
- continue;
- }
-
- children.push(child.path);
- set.add({
- path: child.path,
- name: child.name,
- isDir: child.isDir,
- isSymLink: child.isSymLink,
- depth: info.depth + 1
- });
- }
- } finally {
- iterator.close();
- }
- }
-
- ret[info.path] = {
- name: info.name,
- isDir: info.isDir,
- isSymLink: info.isSymLink,
- depth: info.depth,
- children: children,
- };
- }
-
- return ret;
-}
-
-onmessage = function (event) {
- try {
- let {path, ignore, depth} = event.data;
- let message = readDir(path, ignore, depth);
- postMessage(message);
- } catch (ex) {
- console.log(ex);
- }
-};
-
-
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/moz.build
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += [
- 'helpers',
- 'plugins',
- 'stores',
-]
-
-DevToolsModules(
- 'editors.js',
- 'project.js',
- 'projecteditor.js',
- 'shells.js',
- 'tree.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/app-manager/app-project-editor.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const promise = require("promise");
-const { ItchEditor } = require("devtools/client/projecteditor/lib/editors");
-
-var AppProjectEditor = Class({
- extends: ItchEditor,
-
- hidesToolbar: true,
-
- initialize: function (host) {
- ItchEditor.prototype.initialize.apply(this, arguments);
- this.appended = promise.resolve();
- this.host = host;
- this.label = "app-manager";
- },
-
- destroy: function () {
- this.elt.remove();
- this.elt = null;
- },
-
- load: function (resource) {
- let {appManagerOpts} = this.host.project;
-
- // Only load the frame the first time it is selected
- if (!this.iframe || this.iframe.getAttribute("src") !== appManagerOpts.projectOverviewURL) {
-
- this.elt.textContent = "";
- let iframe = this.iframe = this.elt.ownerDocument.createElement("iframe");
- let iframeLoaded = this.iframeLoaded = promise.defer();
-
- iframe.addEventListener("load", function () {
- iframeLoaded.resolve();
- }, {once: true});
-
- iframe.setAttribute("flex", "1");
- iframe.setAttribute("src", appManagerOpts.projectOverviewURL);
- this.elt.appendChild(iframe);
-
- }
-
- promise.all([this.iframeLoaded.promise, this.appended]).then(() => {
- this.emit("load");
- });
- }
-});
-
-exports.AppProjectEditor = AppProjectEditor;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/app-manager/moz.build
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'app-project-editor.js',
- 'plugin.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/app-manager/plugin.js
+++ /dev/null
@@ -1,77 +0,0 @@
-const { Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const { EventTarget } = require("sdk/event/target");
-const { emit } = require("sdk/event/core");
-const promise = require("promise");
-var { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core");
-const { AppProjectEditor } = require("./app-project-editor");
-const OPTION_URL = "chrome://devtools/skin/images/tool-options.svg";
-const Services = require("Services");
-const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties");
-
-var AppManagerRenderer = Class({
- extends: Plugin,
-
- isAppManagerProject: function () {
- return !!this.host.project.appManagerOpts;
- },
- editorForResource: function (resource) {
- if (!resource.parent && this.isAppManagerProject()) {
- return AppProjectEditor;
- }
- },
- getUI: function (parent) {
- let doc = parent.ownerDocument;
- if (parent.childElementCount == 0) {
- let image = doc.createElement("image");
- let optionImage = doc.createElement("image");
- let flexElement = doc.createElement("div");
- let nameLabel = doc.createElement("span");
- let statusElement = doc.createElement("div");
-
- image.className = "project-image";
- optionImage.className = "project-options";
- optionImage.setAttribute("src", OPTION_URL);
- nameLabel.className = "project-name-label";
- statusElement.className = "project-status";
- flexElement.className = "project-flex";
-
- parent.appendChild(image);
- parent.appendChild(nameLabel);
- parent.appendChild(flexElement);
- parent.appendChild(statusElement);
- parent.appendChild(optionImage);
- }
-
- return {
- image: parent.querySelector(".project-image"),
- nameLabel: parent.querySelector(".project-name-label"),
- statusElement: parent.querySelector(".project-status")
- };
- },
- onAnnotate: function (resource, editor, elt) {
- if (resource.parent || !this.isAppManagerProject()) {
- return;
- }
-
- let {appManagerOpts} = this.host.project;
- let doc = elt.ownerDocument;
-
- let {image, nameLabel, statusElement} = this.getUI(elt);
- let name = appManagerOpts.name || resource.basename;
- let url = appManagerOpts.iconUrl || "icon-sample.png";
- let status = appManagerOpts.validationStatus || "unknown";
- let tooltip = Strings.formatStringFromName("status_tooltip",
- [Strings.GetStringFromName("status_" + status)], 1);
-
- nameLabel.textContent = name;
- image.setAttribute("src", url);
- statusElement.setAttribute("status", status);
- statusElement.setAttribute("tooltiptext", tooltip);
-
- return true;
- }
-});
-
-exports.AppManagerRenderer = AppManagerRenderer;
-registerPlugin(AppManagerRenderer);
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/core.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This is the core plugin API.
-
-const { Class } = require("sdk/core/heritage");
-
-var Plugin = Class({
- initialize: function (host) {
- this.host = host;
- this.init(host);
- },
-
- destroy: function (host) { },
-
- init: function (host) {},
-
- showForCategories: function (elt, categories) {
- this._showFor = this._showFor || [];
- let set = new Set(categories);
- this._showFor.push({
- elt: elt,
- categories: new Set(categories)
- });
- if (this.host.currentEditor) {
- this.onEditorActivated(this.host.currentEditor);
- } else {
- elt.classList.add("plugin-hidden");
- }
- },
-
- priv: function (item) {
- if (!this._privData) {
- this._privData = new WeakMap();
- }
- if (!this._privData.has(item)) {
- this._privData.set(item, {});
- }
- return this._privData.get(item);
- },
- onTreeSelected: function (resource) {},
-
-
- // Editor state lifetime...
- onEditorCreated: function (editor) {},
- onEditorDestroyed: function (editor) {},
-
- onEditorActivated: function (editor) {
- if (this._showFor) {
- let category = editor.category;
- for (let item of this._showFor) {
- if (item.categories.has(category)) {
- item.elt.classList.remove("plugin-hidden");
- } else {
- item.elt.classList.add("plugin-hidden");
- }
- }
- }
- },
- onEditorDeactivated: function (editor) {
- if (this._showFor) {
- for (let item of this._showFor) {
- item.elt.classList.add("plugin-hidden");
- }
- }
- },
-
- onEditorLoad: function (editor) {},
- onEditorSave: function (editor) {},
- onEditorChange: function (editor) {},
- onEditorCursorActivity: function (editor) {},
-});
-exports.Plugin = Plugin;
-
-function registerPlugin(constr) {
- exports.registeredPlugins.push(constr);
-}
-exports.registerPlugin = registerPlugin;
-
-exports.registeredPlugins = [];
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/delete/delete.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Class } = require("sdk/core/heritage");
-const { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core");
-const { confirm } = require("devtools/client/projecteditor/lib/helpers/prompts");
-const { getLocalizedString } = require("devtools/client/projecteditor/lib/helpers/l10n");
-
-var DeletePlugin = Class({
- extends: Plugin,
- shouldConfirm: true,
-
- init: function (host) {
- this.host.addCommand(this, {
- id: "cmd-delete"
- });
- this.contextMenuItem = this.host.createMenuItem({
- parent: this.host.contextMenuPopup,
- label: getLocalizedString("projecteditor.deleteLabel"),
- command: "cmd-delete"
- });
- },
-
- confirmDelete: function (resource) {
- let deletePromptMessage = resource.isDir ?
- getLocalizedString("projecteditor.deleteFolderPromptMessage") :
- getLocalizedString("projecteditor.deleteFilePromptMessage");
- return !this.shouldConfirm || confirm(
- getLocalizedString("projecteditor.deletePromptTitle"),
- deletePromptMessage
- );
- },
-
- onContextMenuOpen: function (resource) {
- // Do not allow deletion of the top level items in the tree. In the
- // case of the Web IDE in particular this can leave the UI in a weird
- // state. If we'd like to add ability to delete the project folder from
- // the tree in the future, then the UI could be cleaned up by listening
- // to the ProjectTree's "resource-removed" event.
- if (!resource.parent) {
- this.contextMenuItem.setAttribute("hidden", "true");
- } else {
- this.contextMenuItem.removeAttribute("hidden");
- }
- },
-
- onCommand: function (cmd) {
- if (cmd === "cmd-delete") {
- let tree = this.host.projectTree;
- let resource = tree.getSelectedResource();
-
- if (!this.confirmDelete(resource)) {
- return;
- }
-
- resource.delete().then(() => {
- this.host.project.refresh();
- });
- }
- }
-});
-
-exports.DeletePlugin = DeletePlugin;
-registerPlugin(DeletePlugin);
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/delete/moz.build
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'delete.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/dirty/dirty.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Class } = require("sdk/core/heritage");
-const { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core");
-const { emit } = require("sdk/event/core");
-
-var DirtyPlugin = Class({
- extends: Plugin,
-
- onEditorSave: function (editor) { this.onEditorChange(editor); },
- onEditorLoad: function (editor) { this.onEditorChange(editor); },
-
- onEditorChange: function (editor) {
- // Only run on a TextEditor
- if (!editor || !editor.editor) {
- return;
- }
-
- // Dont' force a refresh unless the dirty state has changed...
- let priv = this.priv(editor);
- let clean = editor.isClean();
- if (priv.isClean !== clean) {
- let resource = editor.shell.resource;
- emit(resource, "label-change", resource);
- priv.isClean = clean;
- }
- },
-
- onAnnotate: function (resource, editor, elt) {
- // Only run on a TextEditor
- if (!editor || !editor.editor) {
- return;
- }
-
- if (!editor.isClean()) {
- elt.textContent = "*" + resource.displayName;
- return true;
- }
- }
-});
-exports.DirtyPlugin = DirtyPlugin;
-
-registerPlugin(DirtyPlugin);
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/dirty/moz.build
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'dirty.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/image-view/image-editor.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const promise = require("promise");
-const { ItchEditor } = require("devtools/client/projecteditor/lib/editors");
-
-var ImageEditor = Class({
- extends: ItchEditor,
-
- initialize: function () {
- ItchEditor.prototype.initialize.apply(this, arguments);
- this.label = "image";
- this.appended = promise.resolve();
- },
-
- load: function (resource) {
- this.elt.innerHTML = "";
- let image = this.image = this.doc.createElement("image");
- image.className = "editor-image";
- image.setAttribute("src", resource.uri);
-
- let box1 = this.doc.createElement("box");
- box1.appendChild(image);
-
- let box2 = this.doc.createElement("box");
- box2.setAttribute("flex", 1);
-
- this.elt.appendChild(box1);
- this.elt.appendChild(box2);
-
- this.appended.then(() => {
- this.emit("load");
- });
- },
-
- destroy: function () {
- if (this.image) {
- this.image.remove();
- this.image = null;
- }
- }
-
-});
-
-exports.ImageEditor = ImageEditor;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/image-view/moz.build
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'image-editor.js',
- 'plugin.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/image-view/plugin.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const promise = require("promise");
-const { ImageEditor } = require("./image-editor");
-const { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core");
-
-var ImageEditorPlugin = Class({
- extends: Plugin,
-
- editorForResource: function (node) {
- if (node.contentCategory === "image") {
- return ImageEditor;
- }
- },
-
- init: function (host) {
-
- }
-});
-
-exports.ImageEditorPlugin = ImageEditorPlugin;
-registerPlugin(ImageEditorPlugin);
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/logging/logging.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var { Class } = require("sdk/core/heritage");
-var { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core");
-
-var LoggingPlugin = Class({
- extends: Plugin,
-
- // Editor state lifetime...
- onEditorCreated: function (editor) { console.log("editor created: " + editor); },
- onEditorDestroyed: function (editor) { console.log("editor destroyed: " + editor);},
-
- onEditorSave: function (editor) { console.log("editor saved: " + editor); },
- onEditorLoad: function (editor) { console.log("editor loaded: " + editor); },
-
- onEditorActivated: function (editor) { console.log("editor activated: " + editor);},
- onEditorDeactivated: function (editor) { console.log("editor deactivated: " + editor);},
-
- onEditorChange: function (editor) { console.log("editor changed: " + editor);},
-
- onCommand: function (cmd) { console.log("Command: " + cmd); }
-});
-exports.LoggingPlugin = LoggingPlugin;
-
-registerPlugin(LoggingPlugin);
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/logging/moz.build
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'logging.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/moz.build
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += [
- 'app-manager',
- 'delete',
- 'dirty',
- 'image-view',
- 'logging',
- 'new',
- 'rename',
- 'save',
- 'status-bar',
-]
-
-DevToolsModules(
- 'core.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/new/moz.build
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'new.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/new/new.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Class } = require("sdk/core/heritage");
-const { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core");
-const { getLocalizedString } = require("devtools/client/projecteditor/lib/helpers/l10n");
-
-// Handles the new command.
-var NewFile = Class({
- extends: Plugin,
-
- init: function () {
- this.command = this.host.addCommand(this, {
- id: "cmd-new",
- key: getLocalizedString("projecteditor.new.commandkey"),
- modifiers: "accel"
- });
- this.host.createMenuItem({
- parent: this.host.fileMenuPopup,
- label: getLocalizedString("projecteditor.newLabel"),
- command: "cmd-new",
- key: "key_cmd-new"
- });
- this.host.createMenuItem({
- parent: this.host.contextMenuPopup,
- label: getLocalizedString("projecteditor.newLabel"),
- command: "cmd-new"
- });
- },
-
- onCommand: function (cmd) {
- if (cmd === "cmd-new") {
- let tree = this.host.projectTree;
- let resource = tree.getSelectedResource();
- parent = resource.isDir ? resource : resource.parent;
- sibling = resource.isDir ? null : resource;
-
- if (!("createChild" in parent)) {
- return;
- }
-
- let extension = sibling ? sibling.contentCategory : parent.store.defaultCategory;
- let template = "untitled{1}." + extension;
- let name = this.suggestName(parent, template);
-
- tree.promptNew(name, parent, sibling).then(name => {
-
- // XXX: sanitize bad file names.
-
- // If the name is already taken, just add/increment a number.
- if (parent.hasChild(name)) {
- let matches = name.match(/([^\d.]*)(\d*)([^.]*)(.*)/);
- template = matches[1] + "{1}" + matches[3] + matches[4];
- name = this.suggestName(parent, template, parseInt(matches[2]) || 2);
- }
-
- return parent.createChild(name);
- }).then(resource => {
- tree.selectResource(resource);
- this.host.currentEditor.focus();
- }).then(null, console.error);
- }
- },
-
- suggestName: function (parent, template, start = 1) {
- let i = start;
- let name;
- do {
- name = template.replace("\{1\}", i === 1 ? "" : i);
- i++;
- } while (parent.hasChild(name));
-
- return name;
- }
-});
-exports.NewFile = NewFile;
-registerPlugin(NewFile);
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/rename/moz.build
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'rename.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/rename/rename.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Class } = require("sdk/core/heritage");
-const { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core");
-const { getLocalizedString } = require("devtools/client/projecteditor/lib/helpers/l10n");
-
-var RenamePlugin = Class({
- extends: Plugin,
-
- init: function (host) {
- this.host.addCommand(this, {
- id: "cmd-rename"
- });
- this.contextMenuItem = this.host.createMenuItem({
- parent: this.host.contextMenuPopup,
- label: getLocalizedString("projecteditor.renameLabel"),
- command: "cmd-rename"
- });
- },
-
- onContextMenuOpen: function (resource) {
- if (resource.isRoot) {
- this.contextMenuItem.setAttribute("hidden", "true");
- } else {
- this.contextMenuItem.removeAttribute("hidden");
- }
- },
-
- onCommand: function (cmd) {
- if (cmd === "cmd-rename") {
- let tree = this.host.projectTree;
- let resource = tree.getSelectedResource();
- let parent = resource.parent;
- let oldName = resource.basename;
-
- tree.promptEdit(oldName, resource).then(name => {
- if (name === oldName) {
- return resource;
- }
- if (parent.hasChild(name)) {
- let matches = name.match(/([^\d.]*)(\d*)([^.]*)(.*)/);
- let template = matches[1] + "{1}" + matches[3] + matches[4];
- name = this.suggestName(resource, template, parseInt(matches[2]) || 2);
- }
- return parent.rename(oldName, name);
- }).then(resource => {
- this.host.project.refresh();
- tree.selectResource(resource);
- if (!resource.isDir) {
- this.host.currentEditor.focus();
- }
- }).then(null, console.error);
- }
- },
-
- suggestName: function (resource, template, start = 1) {
- let i = start;
- let name;
- let parent = resource.parent;
- do {
- name = template.replace("\{1\}", i === 1 ? "" : i);
- i++;
- } while (parent.hasChild(name));
-
- return name;
- }
-});
-
-exports.RenamePlugin = RenamePlugin;
-registerPlugin(RenamePlugin);
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/save/moz.build
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'save.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/save/save.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Class } = require("sdk/core/heritage");
-const { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core");
-const picker = require("devtools/client/projecteditor/lib/helpers/file-picker");
-const { getLocalizedString } = require("devtools/client/projecteditor/lib/helpers/l10n");
-
-// Handles the save command.
-var SavePlugin = Class({
- extends: Plugin,
-
- init: function (host) {
-
- this.host.addCommand(this, {
- id: "cmd-save",
- key: getLocalizedString("projecteditor.save.commandkey"),
- modifiers: "accel"
- });
- this.host.addCommand(this, {
- id: "cmd-saveas",
- key: getLocalizedString("projecteditor.save.commandkey"),
- modifiers: "accel shift"
- });
- this.host.createMenuItem({
- parent: this.host.fileMenuPopup,
- label: getLocalizedString("projecteditor.saveLabel"),
- command: "cmd-save",
- key: "key_cmd-save"
- });
- this.host.createMenuItem({
- parent: this.host.fileMenuPopup,
- label: getLocalizedString("projecteditor.saveAsLabel"),
- command: "cmd-saveas",
- key: "key_cmd-saveas"
- });
- },
-
- isCommandEnabled: function (cmd) {
- let currentEditor = this.host.currentEditor;
- return currentEditor.isEditable;
- },
-
- onCommand: function (cmd) {
- if (cmd === "cmd-save") {
- this.onEditorSaveRequested();
- } else if (cmd === "cmd-saveas") {
- this.saveAs();
- }
- },
-
- saveAs: function () {
- let editor = this.host.currentEditor;
- let project = this.host.resourceFor(editor);
-
- let resource;
- picker.showSave({
- window: this.host.window,
- directory: project && project.parent ? project.parent.path : null,
- defaultName: project ? project.basename : null,
- }).then(path => {
- return this.createResource(path);
- }).then(res => {
- resource = res;
- return this.saveResource(editor, resource);
- }).then(() => {
- this.host.openResource(resource);
- }).then(null, console.error);
- },
-
- onEditorSaveRequested: function () {
- let editor = this.host.currentEditor;
- let resource = this.host.resourceFor(editor);
- if (!resource) {
- return this.saveAs();
- }
-
- return this.saveResource(editor, resource);
- },
-
- createResource: function (path) {
- return this.host.project.resourceFor(path, { create: true });
- },
-
- saveResource: function (editor, resource) {
- return editor.save(resource);
- }
-});
-exports.SavePlugin = SavePlugin;
-registerPlugin(SavePlugin);
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/status-bar/moz.build
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'plugin.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/plugins/status-bar/plugin.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const promise = require("promise");
-const { registerPlugin, Plugin } = require("devtools/client/projecteditor/lib/plugins/core");
-
-/**
- * Print information about the currently opened file
- * and the state of the current editor
- */
-var StatusBarPlugin = Class({
- extends: Plugin,
-
- init: function () {
- this.box = this.host.createElement("hbox", {
- parent: "#projecteditor-toolbar-bottom"
- });
-
- this.activeMode = this.host.createElement("label", {
- parent: this.box,
- class: "projecteditor-basic-display"
- });
-
- this.cursorPosition = this.host.createElement("label", {
- parent: this.box,
- class: "projecteditor-basic-display"
- });
-
- this.fileLabel = this.host.createElement("label", {
- parent: "#plugin-toolbar-left",
- class: "projecteditor-file-label"
- });
- },
-
- destroy: function () {
- },
-
- /**
- * Print information about the current state of the editor
- *
- * @param Editor editor
- */
- render: function (editor, resource) {
- if (!resource || resource.isDir) {
- this.fileLabel.textContent = "";
- this.cursorPosition.value = "";
- return;
- }
-
- this.fileLabel.textContent = resource.basename;
- this.activeMode.value = editor.toString();
- if (editor.editor) {
- let cursorStart = editor.editor.getCursor("start");
- let cursorEnd = editor.editor.getCursor("end");
- if (cursorStart.line === cursorEnd.line && cursorStart.ch === cursorEnd.ch) {
- this.cursorPosition.value = cursorStart.line + " " + cursorStart.ch;
- } else {
- this.cursorPosition.value = cursorStart.line + " " + cursorStart.ch + " | " +
- cursorEnd.line + " " + cursorEnd.ch;
- }
- } else {
- this.cursorPosition.value = "";
- }
- },
-
-
- /**
- * Print the current file name
- *
- * @param Resource resource
- */
- onTreeSelected: function (resource) {
- if (!resource || resource.isDir) {
- this.fileLabel.textContent = "";
- return;
- }
- this.fileLabel.textContent = resource.basename;
- },
-
- onEditorDeactivated: function (editor) {
- this.fileLabel.textContent = "";
- this.cursorPosition.value = "";
- },
-
- onEditorChange: function (editor, resource) {
- this.render(editor, resource);
- },
-
- onEditorCursorActivity: function (editor, resource) {
- this.render(editor, resource);
- },
-
- onEditorActivated: function (editor, resource) {
- this.render(editor, resource);
- },
-
-});
-
-exports.StatusBarPlugin = StatusBarPlugin;
-registerPlugin(StatusBarPlugin);
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/project.js
+++ /dev/null
@@ -1,246 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const { EventTarget } = require("sdk/event/target");
-const { emit } = require("sdk/event/core");
-const { scope, on, forget } = require("devtools/client/projecteditor/lib/helpers/event");
-const prefs = require("sdk/preferences/service");
-const { LocalStore } = require("devtools/client/projecteditor/lib/stores/local");
-const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
-const { Task } = require("devtools/shared/task");
-const promise = require("promise");
-const { TextEncoder, TextDecoder } = require("sdk/io/buffer");
-const url = require("sdk/url");
-
-const gDecoder = new TextDecoder();
-const gEncoder = new TextEncoder();
-
-/**
- * A Project keeps track of the opened folders using LocalStore
- * objects. Resources are generally requested from the project,
- * even though the Store is actually keeping track of them.
- *
- *
- * This object emits the following events:
- * - "refresh-complete": After all stores have been refreshed from disk.
- * - "store-added": When a store has been added to the project.
- * - "store-removed": When a store has been removed from the project.
- * - "resource-added": When a resource has been added to one of the stores.
- * - "resource-removed": When a resource has been removed from one of the stores.
- */
-var Project = Class({
- extends: EventTarget,
-
- /**
- * Intialize the Project.
- *
- * @param Object options
- * Options to be passed into Project.load function
- */
- initialize: function (options) {
- this.localStores = new Map();
-
- this.load(options);
- },
-
- destroy: function () {
- // We are removing the store because the project never gets persisted.
- // There may need to be separate destroy functionality that doesn't remove
- // from project if this is saved to DB.
- this.removeAllStores();
- },
-
- toString: function () {
- return "[Project] " + this.name;
- },
-
- /**
- * Load a project given metadata about it.
- *
- * @param Object options
- * Information about the project, containing:
- * id: An ID (currently unused, but could be used for saving)
- * name: The display name of the project
- * directories: An array of path strings to load
- */
- load: function (options) {
- this.id = options.id;
- this.name = options.name || "Untitled";
-
- let paths = new Set(options.directories.map(name => OS.Path.normalize(name)));
-
- for (let [path, store] of this.localStores) {
- if (!paths.has(path)) {
- this.removePath(path);
- }
- }
-
- for (let path of paths) {
- this.addPath(path);
- }
- },
-
- /**
- * Refresh all project stores from disk
- *
- * @returns Promise
- * A promise that resolves when everything has been refreshed.
- */
- refresh: function () {
- return Task.spawn(function* () {
- for (let [path, store] of this.localStores) {
- yield store.refresh();
- }
- emit(this, "refresh-complete");
- }.bind(this));
- },
-
-
- /**
- * Fetch a resource from the backing storage system for the store.
- *
- * @param string path
- * The path to fetch
- * @param Object options
- * "create": bool indicating whether to create a file if it does not exist.
- * @returns Promise
- * A promise that resolves with the Resource.
- */
- resourceFor: function (path, options) {
- let store = this.storeContaining(path);
- return store.resourceFor(path, options);
- },
-
- /**
- * Get every resource used inside of the project.
- *
- * @returns Array<Resource>
- * A list of all Resources in all Stores.
- */
- allResources: function () {
- let resources = [];
- for (let store of this.allStores()) {
- resources = resources.concat(store.allResources());
- }
- return resources;
- },
-
- /**
- * Get every Path used inside of the project.
- *
- * @returns generator-iterator<Store>
- * A list of all Stores
- */
- allStores: function* () {
- for (let [path, store] of this.localStores) {
- yield store;
- }
- },
-
- /**
- * Get every file path used inside of the project.
- *
- * @returns Array<string>
- * A list of all file paths
- */
- allPaths: function () {
- return [...this.localStores.keys()];
- },
-
- /**
- * Get the store that contains a path.
- *
- * @returns Store
- * The store, if any. Will return null if no store
- * contains the given path.
- */
- storeContaining: function (path) {
- let containingStore = null;
- for (let store of this.allStores()) {
- if (store.contains(path)) {
- // With nested projects, the final containing store will be returned.
- containingStore = store;
- }
- }
- return containingStore;
- },
-
- /**
- * Add a store at the current path. If a store already exists
- * for this path, then return it.
- *
- * @param string path
- * @returns LocalStore
- */
- addPath: function (path) {
- if (!this.localStores.has(path)) {
- this.addLocalStore(new LocalStore(path));
- }
- return this.localStores.get(path);
- },
-
- /**
- * Remove a store for a given path.
- *
- * @param string path
- */
- removePath: function (path) {
- this.removeLocalStore(this.localStores.get(path));
- },
-
-
- /**
- * Add the given Store to the project.
- * Fires a 'store-added' event on the project.
- *
- * @param Store store
- */
- addLocalStore: function (store) {
- store.canPair = true;
- this.localStores.set(store.path, store);
-
- // Originally StoreCollection.addStore
- on(this, store, "resource-added", (resource) => {
- emit(this, "resource-added", resource);
- });
- on(this, store, "resource-removed", (resource) => {
- emit(this, "resource-removed", resource);
- });
-
- emit(this, "store-added", store);
- },
-
-
- /**
- * Remove all of the Stores belonging to the project.
- */
- removeAllStores: function () {
- for (let store of this.allStores()) {
- this.removeLocalStore(store);
- }
- },
-
- /**
- * Remove the given Store from the project.
- * Fires a 'store-removed' event on the project.
- *
- * @param Store store
- */
- removeLocalStore: function (store) {
- // XXX: tree selection should be reset if active element is affected by
- // the store being removed
- if (store) {
- this.localStores.delete(store.path);
- forget(this, store);
- emit(this, "store-removed", store);
- store.destroy();
- }
- }
-});
-
-exports.Project = Project;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/projecteditor.js
+++ /dev/null
@@ -1,816 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { Cc, Ci, Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const { Project } = require("devtools/client/projecteditor/lib/project");
-const { ProjectTreeView } = require("devtools/client/projecteditor/lib/tree");
-const { ShellDeck } = require("devtools/client/projecteditor/lib/shells");
-const { Resource } = require("devtools/client/projecteditor/lib/stores/resource");
-const { registeredPlugins } = require("devtools/client/projecteditor/lib/plugins/core");
-const { EventTarget } = require("sdk/event/target");
-const { on, forget } = require("devtools/client/projecteditor/lib/helpers/event");
-const { emit } = require("sdk/event/core");
-const { merge } = require("sdk/util/object");
-const promise = require("promise");
-const { ViewHelpers } = require("devtools/client/shared/widgets/view-helpers");
-const { DOMHelpers } = require("resource://devtools/client/shared/DOMHelpers.jsm");
-const Services = require("Services");
-const { Task } = require("devtools/shared/task");
-const ITCHPAD_URL = "chrome://devtools/content/projecteditor/chrome/content/projecteditor.xul";
-const { confirm } = require("devtools/client/projecteditor/lib/helpers/prompts");
-const { getLocalizedString } = require("devtools/client/projecteditor/lib/helpers/l10n");
-
-// Enabled Plugins
-require("devtools/client/projecteditor/lib/plugins/dirty/dirty");
-require("devtools/client/projecteditor/lib/plugins/delete/delete");
-require("devtools/client/projecteditor/lib/plugins/new/new");
-require("devtools/client/projecteditor/lib/plugins/rename/rename");
-require("devtools/client/projecteditor/lib/plugins/save/save");
-require("devtools/client/projecteditor/lib/plugins/image-view/plugin");
-require("devtools/client/projecteditor/lib/plugins/app-manager/plugin");
-require("devtools/client/projecteditor/lib/plugins/status-bar/plugin");
-
-// Uncomment to enable logging.
-// require("devtools/client/projecteditor/lib/plugins/logging/logging");
-
-/**
- * This is the main class tying together an instance of the ProjectEditor.
- * The frontend is contained inside of this.iframe, which loads projecteditor.xul.
- *
- * Usage:
- * let projecteditor = new ProjectEditor(frame);
- * projecteditor.loaded.then((projecteditor) => {
- * // Ready to use.
- * });
- *
- * Responsible for maintaining:
- * - The list of Plugins for this instance.
- * - The ShellDeck, which includes all Shells for opened Resources
- * -- Shells take in a Resource, and construct the appropriate Editor
- * - The Project, which includes all Stores for this instance
- * -- Stores manage all Resources starting from a root directory
- * --- Resources are a representation of a file on disk
- * - The ProjectTreeView that builds the UI for interacting with the
- * project.
- *
- * This object emits the following events:
- * - "onEditorDestroyed": When editor is destroyed
- * - "onEditorSave": When editor is saved
- * - "onEditorLoad": When editor is loaded
- * - "onEditorActivated": When editor is activated
- * - "onEditorChange": When editor is changed
- * - "onEditorCursorActivity": When there is cursor activity in a text editor
- * - "onCommand": When a command happens
- * - "onEditorDestroyed": When editor is destroyed
- * - "onContextMenuOpen": When the context menu is opened on the project tree
- *
- * The events can be bound like so:
- * projecteditor.on("onEditorCreated", (editor) => { });
- */
-var ProjectEditor = Class({
- extends: EventTarget,
-
- /**
- * Initialize ProjectEditor, and load into an iframe if specified.
- *
- * @param Iframe iframe
- * The iframe to inject the DOM into. If this is not
- * specified, then this.load(frame) will need to be called
- * before accessing ProjectEditor.
- * @param Object options
- * - menubar: a <menubar> element to inject menus into
- * - menuindex: Integer child index to insert menus
- */
- initialize: function (iframe, options = {}) {
- this._onTreeSelected = this._onTreeSelected.bind(this);
- this._onTreeResourceRemoved = this._onTreeResourceRemoved.bind(this);
- this._onEditorCreated = this._onEditorCreated.bind(this);
- this._onEditorActivated = this._onEditorActivated.bind(this);
- this._onEditorDeactivated = this._onEditorDeactivated.bind(this);
- this._updateMenuItems = this._updateMenuItems.bind(this);
- this._updateContextMenuItems = this._updateContextMenuItems.bind(this);
- this.destroy = this.destroy.bind(this);
- this.menubar = options.menubar || null;
- this.menuindex = options.menuindex || null;
- this._menuEnabled = true;
- this._destroyed = false;
- this._loaded = false;
- this._pluginCommands = new Map();
- if (iframe) {
- this.load(iframe);
- }
- },
-
- /**
- * Load the instance inside of a specified iframe.
- * This can be called more than once, and it will return the promise
- * from the first call.
- *
- * @param Iframe iframe
- * The iframe to inject the projecteditor DOM into
- * @returns Promise
- * A promise that is resolved once the iframe has been
- * loaded.
- */
- load: function (iframe) {
- if (this.loaded) {
- return this.loaded;
- }
-
- let deferred = promise.defer();
- this.loaded = deferred.promise;
- this.iframe = iframe;
-
- let domReady = () => {
- if (this._destroyed) {
- deferred.reject("Error: ProjectEditor has been destroyed before loading");
- return;
- }
- this._onLoad();
- this._loaded = true;
- deferred.resolve(this);
- };
-
- let domHelper = new DOMHelpers(this.iframe.contentWindow);
- domHelper.onceDOMReady(domReady);
-
- this.iframe.setAttribute("src", ITCHPAD_URL);
-
- return this.loaded;
- },
-
- /**
- * Build the projecteditor DOM inside of this.iframe.
- */
- _onLoad: function () {
- this.document = this.iframe.contentDocument;
- this.window = this.iframe.contentWindow;
-
- this._initCommands();
- this._buildMenubar();
- this._buildSidebar();
-
- this.window.addEventListener("unload", this.destroy);
-
- // Editor management
- this.shells = new ShellDeck(this, this.document);
- this.shells.on("editor-created", this._onEditorCreated);
- this.shells.on("editor-activated", this._onEditorActivated);
- this.shells.on("editor-deactivated", this._onEditorDeactivated);
-
- let shellContainer = this.document.querySelector("#shells-deck-container");
- shellContainer.appendChild(this.shells.elt);
-
- // We are not allowing preset projects for now - rebuild a fresh one
- // each time.
- this.setProject(new Project({
- id: "",
- name: "",
- directories: [],
- openFiles: []
- }));
-
- this._initPlugins();
- },
-
- _buildMenubar: function () {
-
- this.contextMenuPopup = this.document.getElementById("context-menu-popup");
- this.contextMenuPopup.addEventListener("popupshowing", this._updateContextMenuItems);
-
- this.textEditorContextMenuPopup = this.document.getElementById("texteditor-context-popup");
- this.textEditorContextMenuPopup.addEventListener("popupshowing", this._updateMenuItems);
-
- this.editMenu = this.document.getElementById("edit-menu");
- this.fileMenu = this.document.getElementById("file-menu");
-
- this.editMenuPopup = this.document.getElementById("edit-menu-popup");
- this.fileMenuPopup = this.document.getElementById("file-menu-popup");
- this.editMenu.addEventListener("popupshowing", this._updateMenuItems);
- this.fileMenu.addEventListener("popupshowing", this._updateMenuItems);
-
- if (this.menubar) {
- let body = this.menubar.ownerDocument.body ||
- this.menubar.ownerDocument.querySelector("window");
- body.appendChild(this.projectEditorCommandset);
- body.appendChild(this.projectEditorKeyset);
- body.appendChild(this.editorCommandset);
- body.appendChild(this.editorKeyset);
- body.appendChild(this.contextMenuPopup);
- body.appendChild(this.textEditorContextMenuPopup);
-
- let index = this.menuindex || 0;
- this.menubar.insertBefore(this.editMenu, this.menubar.children[index]);
- this.menubar.insertBefore(this.fileMenu, this.menubar.children[index]);
- } else {
- this.document.getElementById("projecteditor-menubar").style.display = "block";
- }
-
- // Insert a controller to allow enabling and disabling of menu items.
- this._commandWindow = this.editorCommandset.ownerDocument.defaultView;
- this._commandController = getCommandController(this);
- this._commandWindow.controllers.insertControllerAt(0, this._commandController);
- },
-
- /**
- * Create the project tree sidebar that lists files.
- */
- _buildSidebar: function () {
- this.projectTree = new ProjectTreeView(this.document, {
- resourceVisible: this.resourceVisible.bind(this),
- resourceFormatter: this.resourceFormatter.bind(this),
- contextMenuPopup: this.contextMenuPopup
- });
- on(this, this.projectTree, "selection", this._onTreeSelected);
- on(this, this.projectTree, "resource-removed", this._onTreeResourceRemoved);
-
- let sourcesBox = this.document.querySelector("#sources > vbox");
- sourcesBox.appendChild(this.projectTree.elt);
- },
-
- /**
- * Set up listeners for commands to dispatch to all of the plugins
- */
- _initCommands: function () {
-
- this.projectEditorCommandset = this.document.getElementById("projecteditor-commandset");
- this.projectEditorKeyset = this.document.getElementById("projecteditor-keyset");
-
- this.editorCommandset = this.document.getElementById("editMenuCommands");
- this.editorKeyset = this.document.getElementById("editMenuKeys");
-
- this.projectEditorCommandset.addEventListener("command", (evt) => {
- evt.stopPropagation();
- evt.preventDefault();
- this.pluginDispatch("onCommand", evt.target.id, evt.target);
- });
- },
-
- /**
- * Initialize each plugin in registeredPlugins
- */
- _initPlugins: function () {
- this._plugins = [];
-
- for (let plugin of registeredPlugins) {
- try {
- this._plugins.push(plugin(this));
- } catch (ex) {
- console.exception(ex);
- }
- }
-
- this.pluginDispatch("lateInit");
- },
-
- /**
- * Enable / disable necessary menu items using globalOverlay.js.
- */
- _updateMenuItems: function () {
- let window = this.editMenu.ownerDocument.defaultView;
- let commands = ["cmd_undo", "cmd_redo", "cmd_delete", "cmd_cut", "cmd_copy", "cmd_paste"];
- commands.forEach(window.goUpdateCommand);
-
- for (let c of this._pluginCommands.keys()) {
- window.goUpdateCommand(c);
- }
- },
-
- /**
- * Enable / disable necessary context menu items by passing an event
- * onto plugins.
- */
- _updateContextMenuItems: function () {
- let resource = this.projectTree.getSelectedResource();
- this.pluginDispatch("onContextMenuOpen", resource);
- },
-
- /**
- * Destroy all objects on the iframe unload event.
- */
- destroy: function () {
- this._destroyed = true;
-
-
- // If been destroyed before the iframe finished loading, then
- // the properties below will not exist.
- if (!this._loaded) {
- this.iframe.setAttribute("src", "about:blank");
- return;
- }
-
- // Reset the src for the iframe so if it reused for a new ProjectEditor
- // instance, the load will fire properly.
- this.window.removeEventListener("unload", this.destroy);
- this.iframe.setAttribute("src", "about:blank");
-
- this._plugins.forEach(plugin => { plugin.destroy(); });
-
- forget(this, this.projectTree);
- this.projectTree.destroy();
- this.projectTree = null;
-
- this.shells.destroy();
-
- this.projectEditorCommandset.remove();
- this.projectEditorKeyset.remove();
- this.editorCommandset.remove();
- this.editorKeyset.remove();
- this.contextMenuPopup.remove();
- this.textEditorContextMenuPopup.remove();
- this.editMenu.remove();
- this.fileMenu.remove();
-
- this._commandWindow.controllers.removeController(this._commandController);
- this._commandController = null;
-
- forget(this, this.project);
- this.project.destroy();
- this.project = null;
- },
-
- /**
- * Set the current project viewed by the projecteditor.
- *
- * @param Project project
- * The project to set.
- */
- setProject: function (project) {
- if (this.project) {
- forget(this, this.project);
- }
- this.project = project;
- this.projectTree.setProject(project);
-
- // Whenever a store gets removed, clean up any editors that
- // exist for resources within it.
- on(this, project, "store-removed", (store) => {
- store.allResources().forEach((resource) => {
- this.shells.removeResource(resource);
- });
- });
- },
-
- /**
- * Set the current project viewed by the projecteditor to a single path,
- * used by the app manager.
- *
- * @param string path
- * The file path to set
- * @param Object opts
- * Custom options used by the project.
- * - name: display name for project
- * - iconUrl: path to icon for project
- * - validationStatus: one of 'unknown|error|warning|valid'
- * - projectOverviewURL: path to load for iframe when project
- * is selected in the tree.
- * @param Promise
- * Promise that is resolved once the project is ready to be used.
- */
- setProjectToAppPath: function (path, opts = {}) {
- this.project.appManagerOpts = opts;
-
- let existingPaths = this.project.allPaths();
- if (existingPaths.length !== 1 || existingPaths[0] !== path) {
- // Only fully reset if this is a new path.
- this.project.removeAllStores();
- this.project.addPath(path);
- } else {
- // Otherwise, just ask for the root to be redrawn
- let rootResource = this.project.localStores.get(path).root;
- emit(rootResource, "label-change", rootResource);
- }
-
- return this.project.refresh();
- },
-
- /**
- * Open a resource in a particular shell.
- *
- * @param Resource resource
- * The file to be opened.
- */
- openResource: function (resource) {
- let shell = this.shells.open(resource);
- this.projectTree.selectResource(resource);
- shell.editor.focus();
- },
-
- /**
- * When a node is selected in the tree, open its associated editor.
- *
- * @param Resource resource
- * The file that has been selected
- */
- _onTreeSelected: function (resource) {
- // Don't attempt to open a directory that is not the root element.
- if (resource.isDir && resource.parent) {
- return;
- }
- this.pluginDispatch("onTreeSelected", resource);
- this.openResource(resource);
- },
-
- /**
- * When a node is removed, destroy it and its associated editor.
- *
- * @param Resource resource
- * The resource being removed
- */
- _onTreeResourceRemoved: function (resource) {
- this.shells.removeResource(resource);
- },
-
- /**
- * Create an xul element with options
- *
- * @param string type
- * The tag name of the element to create.
- * @param Object options
- * "command": DOMNode or string ID of a command element.
- * "parent": DOMNode or selector of parent to append child to.
- * anything other keys are set as an attribute as the element.
- * @returns DOMElement
- * The element that has been created.
- */
- createElement: function (type, options) {
- let elt = this.document.createElement(type);
-
- let parent;
-
- for (let opt in options) {
- if (opt === "command") {
- let command = typeof (options.command) === "string" ? options.command : options.command.id;
- elt.setAttribute("command", command);
- } else if (opt === "parent") {
- continue;
- } else {
- elt.setAttribute(opt, options[opt]);
- }
- }
-
- if (options.parent) {
- let parent = options.parent;
- if (typeof (parent) === "string") {
- parent = this.document.querySelector(parent);
- }
- parent.appendChild(elt);
- }
-
- return elt;
- },
-
- /**
- * Create a "menuitem" xul element with options
- *
- * @param Object options
- * See createElement for available options.
- * @returns DOMElement
- * The menuitem that has been created.
- */
- createMenuItem: function (options) {
- return this.createElement("menuitem", options);
- },
-
- /**
- * Add a command to the projecteditor document.
- * This method is meant to be used with plugins.
- *
- * @param Object definition
- * key: a key/keycode string. Example: "f".
- * id: Unique ID. Example: "find".
- * modifiers: Key modifiers. Example: "accel".
- * @returns DOMElement
- * The command element that has been created.
- */
- addCommand: function (plugin, definition) {
- this._pluginCommands.set(definition.id, plugin);
- let document = this.projectEditorKeyset.ownerDocument;
- let command = document.createElement("command");
- command.setAttribute("id", definition.id);
- if (definition.key) {
- let key = document.createElement("key");
- key.id = "key_" + definition.id;
-
- let keyName = definition.key;
- if (keyName.startsWith("VK_")) {
- key.setAttribute("keycode", keyName);
- } else {
- key.setAttribute("key", keyName);
- }
- key.setAttribute("modifiers", definition.modifiers);
- key.setAttribute("command", definition.id);
- this.projectEditorKeyset.appendChild(key);
- }
- command.setAttribute("oncommand", "void(0);"); // needed. See bug 371900
- this.projectEditorCommandset.appendChild(command);
- return command;
- },
-
- /**
- * Get the instance of a plugin registered with a certain type.
- *
- * @param Type pluginType
- * The type, such as SavePlugin
- * @returns Plugin
- * The plugin instance matching the specified type.
- */
- getPlugin: function (pluginType) {
- for (let plugin of this.plugins) {
- if (plugin.constructor === pluginType) {
- return plugin;
- }
- }
- return null;
- },
-
- /**
- * Get all plugin instances active for the current project
- *
- * @returns [Plugin]
- */
- get plugins() {
- if (!this._plugins) {
- console.log("plugins requested before _plugins was set");
- return [];
- }
- // Could filter further based on the type of project selected,
- // but no need right now.
- return this._plugins;
- },
-
- /**
- * Dispatch an onEditorCreated event, and listen for other events specific
- * to this editor instance.
- *
- * @param Editor editor
- * The new editor instance.
- */
- _onEditorCreated: function (editor) {
- this.pluginDispatch("onEditorCreated", editor);
- this._editorListenAndDispatch(editor, "change", "onEditorChange");
- this._editorListenAndDispatch(editor, "cursorActivity", "onEditorCursorActivity");
- this._editorListenAndDispatch(editor, "load", "onEditorLoad");
- this._editorListenAndDispatch(editor, "saveRequested", "onEditorSaveRequested");
- this._editorListenAndDispatch(editor, "save", "onEditorSave");
-
- editor.on("focus", () => {
- this.projectTree.selectResource(this.resourceFor(editor));
- });
- },
-
- /**
- * Dispatch an onEditorActivated event and finish setting up once the
- * editor is ready to use.
- *
- * @param Editor editor
- * The editor instance, which is now appended in the document.
- * @param Resource resource
- * The resource used by the editor
- */
- _onEditorActivated: function (editor, resource) {
- editor.setToolbarVisibility();
- this.pluginDispatch("onEditorActivated", editor, resource);
- },
-
- /**
- * Dispatch an onEditorDactivated event once an editor loses focus
- *
- * @param Editor editor
- * The editor instance, which is no longer active.
- * @param Resource resource
- * The resource used by the editor
- */
- _onEditorDeactivated: function (editor, resource) {
- this.pluginDispatch("onEditorDeactivated", editor, resource);
- },
-
- /**
- * Call a method on all plugins that implement the method.
- * Also emits the same handler name on `this`.
- *
- * @param string handler
- * Which function name to call on plugins.
- * @param ...args args
- * All remaining parameters are passed into the handler.
- */
- pluginDispatch: function (handler, ...args) {
- emit(this, handler, ...args);
- this.plugins.forEach(plugin => {
- try {
- if (handler in plugin) plugin[handler](...args);
- } catch (ex) {
- console.error(ex);
- }
- });
- },
-
- /**
- * Listen to an event on the editor object and dispatch it
- * to all plugins that implement the associated method
- *
- * @param Editor editor
- * Which editor to listen to
- * @param string event
- * Which editor event to listen for
- * @param string handler
- * Which plugin method to call
- */
- _editorListenAndDispatch: function (editor, event, handler) {
- editor.on(event, (...args) => {
- this.pluginDispatch(handler, editor, this.resourceFor(editor), ...args);
- });
- },
-
- /**
- * Find a shell for a resource.
- *
- * @param Resource resource
- * The file to be opened.
- * @returns Shell
- */
- shellFor: function (resource) {
- return this.shells.shellFor(resource);
- },
-
- /**
- * Returns the Editor for a given resource.
- *
- * @param Resource resource
- * The file to check.
- * @returns Editor
- * Instance of the editor for this file.
- */
- editorFor: function (resource) {
- let shell = this.shellFor(resource);
- return shell ? shell.editor : shell;
- },
-
- /**
- * Returns a resource for the given editor
- *
- * @param Editor editor
- * The editor to check
- * @returns Resource
- * The resource associated with this editor
- */
- resourceFor: function (editor) {
- if (editor && editor.shell && editor.shell.resource) {
- return editor.shell.resource;
- }
- return null;
- },
-
- /**
- * Decide whether a given resource should be hidden in the tree.
- *
- * @param Resource resource
- * The resource in the tree
- * @returns Boolean
- * True if the node should be visible, false if hidden.
- */
- resourceVisible: function (resource) {
- return true;
- },
-
- /**
- * Format the given node for display in the resource tree view.
- *
- * @param Resource resource
- * The file to be opened.
- * @param DOMNode elt
- * The element in the tree to render into.
- */
- resourceFormatter: function (resource, elt) {
- let editor = this.editorFor(resource);
- let renderedByPlugin = false;
-
- // Allow plugins to override default templating of resource in tree.
- this.plugins.forEach(plugin => {
- if (!plugin.onAnnotate) {
- return;
- }
- if (plugin.onAnnotate(resource, editor, elt)) {
- renderedByPlugin = true;
- }
- });
-
- // If no plugin wants to handle it, just use a string from the resource.
- if (!renderedByPlugin) {
- elt.textContent = resource.displayName;
- }
- },
-
- get sourcesVisible() {
- return this.sourceToggle.classList.contains("pane-collapsed");
- },
-
- get currentShell() {
- return this.shells.currentShell;
- },
-
- get currentEditor() {
- return this.shells.currentEditor;
- },
-
- /**
- * Whether or not menu items should be able to be enabled.
- * Note that even if this is true, certain menu items will not be
- * enabled until the correct state is achieved (for instance, the
- * 'copy' menu item is only enabled when there is a selection).
- * But if this is false, then nothing will be enabled.
- */
- set menuEnabled(val) {
- this._menuEnabled = val;
- if (this._loaded) {
- this._updateMenuItems();
- }
- },
-
- 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.confirmUnsavedLabel2")
- );
- }
-
- return true;
- },
-
- /**
- * Save all the changes in source files.
- *
- * @returns Boolean
- * True if there were resources to save.
- */
- saveAllFiles: Task.async(function* () {
- if (this.hasUnsavedResources) {
- for (let resource of this.project.allResources()) {
- let editor = this.editorFor(resource);
- if (editor && !editor.isClean()) {
- yield editor.save(resource);
- }
- }
-
- return true;
- }
-
- return false;
- })
-
-});
-
-
-/**
- * Returns a controller object that can be used for
- * editor-specific commands such as find, jump to line,
- * copy/paste, etc.
- */
-function getCommandController(host) {
- return {
- supportsCommand: function (cmd) {
- return host._pluginCommands.get(cmd);
- },
-
- isCommandEnabled: function (cmd) {
- if (!host.menuEnabled) {
- return false;
- }
- let plugin = host._pluginCommands.get(cmd);
- if (plugin && plugin.isCommandEnabled) {
- return plugin.isCommandEnabled(cmd);
- }
- return true;
- },
- doCommand: function (cmd) {
- }
- };
-}
-
-exports.ProjectEditor = ProjectEditor;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/shells.js
+++ /dev/null
@@ -1,243 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const { EventTarget } = require("sdk/event/target");
-const { emit } = require("sdk/event/core");
-const { EditorTypeForResource } = require("devtools/client/projecteditor/lib/editors");
-const NetworkHelper = require("devtools/shared/webconsole/network-helper");
-const promise = require("promise");
-
-/**
- * The Shell is the object that manages the editor for a single resource.
- * It is in charge of selecting the proper Editor (text/image/plugin-defined)
- * and instantiating / appending the editor.
- * This object is not exported, it is just used internally by the ShellDeck.
- *
- * This object has a promise `editorAppended`, that will resolve once the editor
- * is ready to be used.
- */
-var Shell = Class({
- extends: EventTarget,
-
- /**
- * @param ProjectEditor host
- * @param Resource resource
- */
- initialize: function (host, resource) {
- this.host = host;
- this.doc = host.document;
- this.resource = resource;
- this.elt = this.doc.createElement("vbox");
- this.elt.classList.add("view-project-detail");
- this.elt.shell = this;
-
- let constructor = this._editorTypeForResource();
-
- this.editor = constructor(this.host);
- this.editor.shell = this;
- this.editorAppended = this.editor.appended;
-
- this.editor.on("load", () => {
- this.editorDeferred.resolve();
- });
- this.elt.appendChild(this.editor.elt);
- },
-
- /**
- * Start loading the resource. The 'load' event happens as
- * a result of this function, so any listeners to 'editorAppended'
- * need to be added before calling this.
- */
- load: function () {
- this.editorDeferred = promise.defer();
- this.editorLoaded = this.editorDeferred.promise;
- this.editor.load(this.resource);
- },
-
- /**
- * Destroy the shell and its associated editor
- */
- destroy: function () {
- this.editor.destroy();
- this.resource.destroy();
- },
-
- /**
- * Make sure the correct editor is selected for the resource.
- * @returns Type:Editor
- */
- _editorTypeForResource: function () {
- let resource = this.resource;
- let constructor = EditorTypeForResource(resource);
-
- if (this.host.plugins) {
- this.host.plugins.forEach(plugin => {
- if (plugin.editorForResource) {
- let pluginEditor = plugin.editorForResource(resource);
- if (pluginEditor) {
- constructor = pluginEditor;
- }
- }
- });
- }
-
- return constructor;
- }
-});
-
-/**
- * The ShellDeck is in charge of managing the list of active Shells for
- * the current ProjectEditor instance (aka host).
- *
- * This object emits the following events:
- * - "editor-created": When an editor is initially created
- * - "editor-activated": When an editor is ready to use
- * - "editor-deactivated": When an editor is ready to use
- */
-var ShellDeck = Class({
- extends: EventTarget,
-
- /**
- * @param ProjectEditor host
- * @param Document document
- */
- initialize: function (host, document) {
- this.doc = document;
- this.host = host;
- this.deck = this.doc.createElement("deck");
- this.deck.setAttribute("flex", "1");
- this.elt = this.deck;
-
- this.shells = new Map();
-
- this._activeShell = null;
- },
-
- /**
- * Open a resource in a Shell. Will create the Shell
- * if it doesn't exist yet.
- *
- * @param Resource resource
- * The file to be opened
- * @returns Shell
- */
- open: function (defaultResource) {
- let shell = this.shellFor(defaultResource);
- if (!shell) {
- shell = this._createShell(defaultResource);
- this.shells.set(defaultResource, shell);
- }
- this.selectShell(shell);
- return shell;
- },
-
- /**
- * Create a new Shell for a resource. Called by `open`.
- *
- * @returns Shell
- */
- _createShell: function (defaultResource) {
- let shell = Shell(this.host, defaultResource);
-
- shell.editorAppended.then(() => {
- this.shells.set(shell.resource, shell);
- emit(this, "editor-created", shell.editor);
- if (this.currentShell === shell) {
- this.selectShell(shell);
- }
-
- });
-
- shell.load();
- this.deck.appendChild(shell.elt);
- return shell;
- },
-
- /**
- * Remove the shell for a given resource.
- *
- * @param Resource resource
- */
- removeResource: function (resource) {
- let shell = this.shellFor(resource);
- if (shell) {
- this.shells.delete(resource);
- shell.destroy();
- }
- },
-
- destroy: function () {
- for (let [resource, shell] of this.shells.entries()) {
- this.shells.delete(resource);
- shell.destroy();
- }
- },
-
- /**
- * Select a given shell and open its editor.
- * Will fire editor-deactivated on the old selected Shell (if any),
- * and editor-activated on the new one once it is ready
- *
- * @param Shell shell
- */
- selectShell: function (shell) {
- // Don't fire another activate if this is already the active shell
- if (this._activeShell != shell) {
- if (this._activeShell) {
- emit(this, "editor-deactivated", this._activeShell.editor, this._activeShell.resource);
- }
- this.deck.selectedPanel = shell.elt;
- this._activeShell = shell;
-
- // Only reload the shell if the editor doesn't have local changes.
- if (shell.editor.isClean()) {
- shell.load();
- }
- shell.editorLoaded.then(() => {
- // Handle case where another shell has been requested before this
- // one is finished loading.
- if (this._activeShell === shell) {
- emit(this, "editor-activated", shell.editor, shell.resource);
- }
- });
- }
- },
-
- /**
- * Find a Shell for a Resource.
- *
- * @param Resource resource
- * @returns Shell
- */
- shellFor: function (resource) {
- return this.shells.get(resource);
- },
-
- /**
- * The currently active Shell. Note: the editor may not yet be available
- * on the current shell. Best to wait for the 'editor-activated' event
- * instead.
- *
- * @returns Shell
- */
- get currentShell() {
- return this._activeShell;
- },
-
- /**
- * The currently active Editor, or null if it is not ready.
- *
- * @returns Editor
- */
- get currentEditor() {
- let shell = this.currentShell;
- return shell ? shell.editor : null;
- },
-
-});
-exports.ShellDeck = ShellDeck;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/stores/base.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cc, Ci, Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const { EventTarget } = require("sdk/event/target");
-const { emit } = require("sdk/event/core");
-const promise = require("promise");
-
-/**
- * A Store object maintains a collection of Resource objects stored in a tree.
- *
- * The Store class should not be instantiated directly. Instead, you should
- * use a class extending it - right now this is only a LocalStore.
- *
- * Events:
- * This object emits the 'resource-added' and 'resource-removed' events.
- */
-var Store = Class({
- extends: EventTarget,
-
- /**
- * Should be called during initialize() of a subclass.
- */
- initStore: function () {
- this.resources = new Map();
- },
-
- refresh: function () {
- return promise.resolve();
- },
-
- /**
- * Return a sorted Array of all Resources in the Store
- */
- allResources: function () {
- var resources = [];
- function addResource(resource) {
- resources.push(resource);
- resource.childrenSorted.forEach(addResource);
- }
- addResource(this.root);
- return resources;
- },
-
- notifyAdd: function (resource) {
- emit(this, "resource-added", resource);
- },
-
- notifyRemove: function (resource) {
- emit(this, "resource-removed", resource);
- }
-});
-
-exports.Store = Store;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/stores/local.js
+++ /dev/null
@@ -1,215 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cc, Ci, Cu, ChromeWorker } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const { OS } = require("resource://gre/modules/osfile.jsm");
-const { emit } = require("sdk/event/core");
-const { Store } = require("devtools/client/projecteditor/lib/stores/base");
-const { Task } = require("devtools/shared/task");
-const promise = require("promise");
-const Services = require("Services");
-const { on, forget } = require("devtools/client/projecteditor/lib/helpers/event");
-const { FileResource } = require("devtools/client/projecteditor/lib/stores/resource");
-
-const CHECK_LINKED_DIRECTORY_DELAY = 5000;
-const SHOULD_LIVE_REFRESH = true;
-// XXX: Ignores should be customizable
-const IGNORE_REGEX = /(^\.)|(\~$)|(^node_modules$)/;
-
-/**
- * A LocalStore object maintains a collection of Resource objects
- * from the file system.
- *
- * This object emits the following events:
- * - "resource-added": When a resource is added
- * - "resource-removed": When a resource is removed
- */
-var LocalStore = Class({
- extends: Store,
-
- defaultCategory: "js",
-
- initialize: function(path) {
- this.initStore();
- this.path = OS.Path.normalize(path);
- this.rootPath = this.path;
- this.displayName = this.path;
- this.root = this._forPath(this.path);
- this.notifyAdd(this.root);
- this.refreshLoop = this.refreshLoop.bind(this);
- this.refreshLoop();
- },
-
- destroy: function() {
- clearTimeout(this._refreshTimeout);
-
- if (this._refreshDeferred) {
- this._refreshDeferred.reject("destroy");
- }
- if (this.worker) {
- this.worker.terminate();
- }
-
- this._refreshTimeout = null;
- this._refreshDeferred = null;
- this.worker = null;
-
- if (this.root) {
- forget(this, this.root);
- this.root.destroy();
- }
- },
-
- toString: function() { return "[LocalStore:" + this.path + "]" },
-
- /**
- * Return a FileResource object for the given path. If a FileInfo
- * is provided the resource will use it, otherwise the FileResource
- * might not have full information until the next refresh.
- *
- * The following parameters are passed into the FileResource constructor
- * See resource.js for information about them
- *
- * @param String path
- * @param FileInfo info
- * @returns Resource
- */
- _forPath: function(path, info=null) {
- if (this.resources.has(path)) {
- return this.resources.get(path);
- }
-
- let resource = FileResource(this, path, info);
- this.resources.set(path, resource);
- return resource;
- },
-
- /**
- * Return a promise that resolves to a fully-functional FileResource
- * within this project. This will hit the disk for stat info.
- * options:
- *
- * create: If true, a resource will be created even if the underlying
- * file doesn't exist.
- */
- resourceFor: function(path, options) {
- path = OS.Path.normalize(path);
-
- if (this.resources.has(path)) {
- return promise.resolve(this.resources.get(path));
- }
-
- if (!this.contains(path)) {
- return promise.reject(new Error(path + " does not belong to " + this.path));
- }
-
- return Task.spawn(function*() {
- let parent = yield this.resourceFor(OS.Path.dirname(path));
-
- let info;
- try {
- info = yield OS.File.stat(path);
- } catch (ex if ex instanceof OS.File.Error && ex.becauseNoSuchFile) {
- if (!options.create) {
- throw ex;
- }
- }
-
- let resource = this._forPath(path, info);
- parent.addChild(resource);
- return resource;
- }.bind(this));
- },
-
- refreshLoop: function() {
- // XXX: Once Bug 958280 adds a watch function, will not need to forever loop here.
- this.refresh().then(() => {
- if (SHOULD_LIVE_REFRESH) {
- this._refreshTimeout = setTimeout(this.refreshLoop,
- CHECK_LINKED_DIRECTORY_DELAY);
- }
- });
- },
-
- _refreshTimeout: null,
- _refreshDeferred: null,
-
- /**
- * Refresh the directory structure.
- */
- refresh: function(path=this.rootPath) {
- if (this._refreshDeferred) {
- return this._refreshDeferred.promise;
- }
- this._refreshDeferred = promise.defer();
-
- let worker = this.worker = new ChromeWorker("chrome://devtools/content/projecteditor/lib/helpers/readdir.js");
- let start = Date.now();
-
- worker.onmessage = evt => {
- // console.log("Directory read finished in " + ( Date.now() - start ) +"ms", evt);
- for (path in evt.data) {
- let info = evt.data[path];
- info.path = path;
-
- let resource = this._forPath(path, info);
- resource.info = info;
- if (info.isDir) {
- let newChildren = new Set();
- for (let childPath of info.children) {
- childInfo = evt.data[childPath];
- newChildren.add(this._forPath(childPath, childInfo));
- }
- resource.setChildren(newChildren);
- }
- resource.info.children = null;
- }
-
- worker = null;
- this._refreshDeferred.resolve();
- this._refreshDeferred = null;
- };
- worker.onerror = ex => {
- console.error(ex);
- worker = null;
- this._refreshDeferred.reject(ex);
- this._refreshDeferred = null;
- }
- worker.postMessage({ path: this.rootPath, ignore: IGNORE_REGEX });
- return this._refreshDeferred.promise;
- },
-
- /**
- * Returns true if the given path would be a child of the store's
- * root directory.
- */
- contains: function(path) {
- path = OS.Path.normalize(path);
- let thisPath = OS.Path.split(this.rootPath);
- let thatPath = OS.Path.split(path)
-
- if (!(thisPath.absolute && thatPath.absolute)) {
- throw new Error("Contains only works with absolute paths.");
- }
-
- if (thisPath.winDrive && (thisPath.winDrive != thatPath.winDrive)) {
- return false;
- }
-
- if (thatPath.components.length <= thisPath.components.length) {
- return false;
- }
-
- for (let i = 0; i < thisPath.components.length; i++) {
- if (thisPath.components[i] != thatPath.components[i]) {
- return false;
- }
- }
- return true;
- }
-});
-exports.LocalStore = LocalStore;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/stores/moz.build
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DevToolsModules(
- 'base.js',
- 'local.js',
- 'resource.js',
-)
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/stores/resource.js
+++ /dev/null
@@ -1,398 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { Cc, Ci, Cu } = require("chrome");
-const { TextEncoder, TextDecoder } = require("sdk/io/buffer");
-const { Class } = require("sdk/core/heritage");
-const { EventTarget } = require("sdk/event/target");
-const { emit } = require("sdk/event/core");
-const URL = require("sdk/url");
-const promise = require("promise");
-const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
-const { FileUtils } = Cu.import("resource://gre/modules/FileUtils.jsm", {});
-const mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
-const { Task } = require("devtools/shared/task");
-
-const gDecoder = new TextDecoder();
-const gEncoder = new TextEncoder();
-
-/**
- * A Resource is a single file-like object that can be respresented
- * as a file for ProjectEditor.
- *
- * The Resource class is not exported, and should not be instantiated
- * Instead, you should use the FileResource class that extends it.
- *
- * This object emits the following events:
- * - "children-changed": When a child has been added or removed.
- * See setChildren.
- * - "deleted": When the resource has been deleted.
- */
-var Resource = Class({
- extends: EventTarget,
-
- refresh: function () { return promise.resolve(this); },
- destroy: function () { },
- delete: function () { },
-
- setURI: function (uri) {
- if (typeof (uri) === "string") {
- uri = URL.URL(uri);
- }
- this.uri = uri;
- },
-
- /**
- * Is there more than 1 child Resource?
- */
- get hasChildren() { return this.children && this.children.size > 0; },
-
- /**
- * Is this Resource the root (top level for the store)?
- */
- get isRoot() {
- return !this.parent;
- },
-
- /**
- * Sorted array of children for display
- */
- get childrenSorted() {
- if (!this.hasChildren) {
- return [];
- }
-
- return [...this.children].sort((a, b)=> {
- // Put directories above files.
- if (a.isDir !== b.isDir) {
- return b.isDir;
- }
- return a.basename.toLowerCase() > b.basename.toLowerCase();
- });
- },
-
- /**
- * Set the children set of this Resource, and notify of any
- * additions / removals that happened in the change.
- */
- setChildren: function (newChildren) {
- let oldChildren = this.children || new Set();
- let change = false;
-
- for (let child of oldChildren) {
- if (!newChildren.has(child)) {
- change = true;
- child.parent = null;
- this.store.notifyRemove(child);
- }
- }
-
- for (let child of newChildren) {
- if (!oldChildren.has(child)) {
- change = true;
- child.parent = this;
- this.store.notifyAdd(child);
- }
- }
-
- this.children = newChildren;
- if (change) {
- emit(this, "children-changed", this);
- }
- },
-
- /**
- * Add a resource to children set and notify of the change.
- *
- * @param Resource resource
- */
- addChild: function (resource) {
- this.children = this.children || new Set();
-
- resource.parent = this;
- this.children.add(resource);
- this.store.notifyAdd(resource);
- emit(this, "children-changed", this);
- return resource;
- },
-
- /**
- * Checks if current object has child with specific name.
- *
- * @param string name
- */
- hasChild: function (name) {
- for (let child of this.children) {
- if (child.basename === name) {
- return true;
- }
- }
- return false;
- },
-
- /**
- * Remove a resource to children set and notify of the change.
- *
- * @param Resource resource
- */
- removeChild: function (resource) {
- resource.parent = null;
- this.children.remove(resource);
- this.store.notifyRemove(resource);
- emit(this, "children-changed", this);
- return resource;
- },
-
- /**
- * Return a set with children, children of children, etc -
- * gathered recursively.
- *
- * @returns Set<Resource>
- */
- allDescendants: function () {
- let set = new Set();
-
- function addChildren(item) {
- if (!item.children) {
- return;
- }
-
- for (let child of item.children) {
- set.add(child);
- }
- }
-
- addChildren(this);
- for (let item of set) {
- addChildren(item);
- }
-
- return set;
- },
-});
-
-/**
- * A FileResource is an implementation of Resource for a File System
- * backing. This is exported, and should be used instead of Resource.
- */
-var FileResource = Class({
- extends: Resource,
-
- /**
- * @param Store store
- * @param String path
- * @param FileInfo info
- * https://developer.mozilla.org/en-US/docs/JavaScript_OS.File/OS.File.Info
- */
- initialize: function (store, path, info) {
- this.store = store;
- this.path = path;
-
- this.setURI(URL.URL(URL.fromFilename(path)));
- this._lastReadModification = undefined;
-
- this.info = info;
- this.parent = null;
- },
-
- toString: function () {
- return "[FileResource:" + this.path + "]";
- },
-
- destroy: function () {
- if (this._refreshDeferred) {
- this._refreshDeferred.reject();
- }
- this._refreshDeferred = null;
- },
-
- /**
- * Fetch and cache information about this particular file.
- * https://developer.mozilla.org/en-US/docs/JavaScript_OS.File/OS.File_for_the_main_thread#OS.File.stat
- *
- * @returns Promise
- * Resolves once the File.stat has finished.
- */
- refresh: function () {
- if (this._refreshDeferred) {
- return this._refreshDeferred.promise;
- }
- this._refreshDeferred = promise.defer();
- OS.File.stat(this.path).then(info => {
- this.info = info;
- if (this._refreshDeferred) {
- this._refreshDeferred.resolve(this);
- this._refreshDeferred = null;
- }
- });
- return this._refreshDeferred.promise;
- },
-
- /**
- * Return the trailing name component of this Resource
- */
- get basename() {
- return this.path.replace(/\/+$/, "").replace(/\\/g, "/").replace(/.*\//, "");
- },
-
- /**
- * A string to be used when displaying this Resource in views
- */
- get displayName() {
- return this.basename + (this.isDir ? "/" : "");
- },
-
- /**
- * Is this FileResource a directory? Rather than checking children
- * here, we use this.info. So this could return a false negative
- * if there was no info passed in on constructor and the first
- * refresh hasn't yet finished.
- */
- get isDir() {
- if (!this.info) { return false; }
- return this.info.isDir && !this.info.isSymLink;
- },
-
- /**
- * Read the file as a string asynchronously.
- *
- * @returns Promise
- * Resolves with the text of the file.
- */
- load: function () {
- return OS.File.read(this.path).then(bytes => {
- return gDecoder.decode(bytes);
- });
- },
-
- /**
- * Delete the file from the filesystem
- *
- * @returns Promise
- * Resolves when the file is deleted
- */
- delete: function () {
- emit(this, "deleted", this);
- if (this.isDir) {
- return OS.File.removeDir(this.path);
- } else {
- return OS.File.remove(this.path);
- }
- },
-
- /**
- * Add a text file as a child of this FileResource.
- * This instance must be a directory.
- *
- * @param string name
- * The filename (path will be generated based on this.path).
- * string initial
- * The content to write to the new file.
- * @returns Promise
- * Resolves with the new FileResource once it has
- * been written to disk.
- * Rejected if this is not a directory.
- */
- createChild: function (name, initial = "") {
- if (!this.isDir) {
- return promise.reject(new Error("Cannot add child to a regular file"));
- }
-
- let newPath = OS.Path.join(this.path, name);
-
- let buffer = initial ? gEncoder.encode(initial) : "";
- return OS.File.writeAtomic(newPath, buffer, {
- noOverwrite: true
- }).then(() => {
- return this.store.refresh();
- }).then(() => {
- let resource = this.store.resources.get(newPath);
- if (!resource) {
- throw new Error("Error creating " + newPath);
- }
- return resource;
- });
- },
-
- /**
- * Rename the file from the filesystem
- *
- * @returns Promise
- * Resolves with the renamed FileResource.
- */
- rename: function (oldName, newName) {
- let oldPath = OS.Path.join(this.path, oldName);
- let newPath = OS.Path.join(this.path, newName);
-
- return OS.File.move(oldPath, newPath).then(() => {
- return this.store.refresh();
- }).then(() => {
- let resource = this.store.resources.get(newPath);
- if (!resource) {
- throw new Error("Error creating " + newPath);
- }
- return resource;
- });
- },
-
- /**
- * Write a string to this file.
- *
- * @param string content
- * @returns Promise
- * Resolves once it has been written to disk.
- * Rejected if there is an error
- */
- save: Task.async(function* (content) {
- // XXX: writeAtomic was losing permissions after saving on OSX
- // return OS.File.writeAtomic(this.path, buffer, { tmpPath: this.path + ".tmp" });
- let buffer = gEncoder.encode(content);
- let path = this.path;
- let file = yield OS.File.open(path, {truncate: true});
- yield file.write(buffer);
- yield file.close();
- }),
-
- /**
- * Attempts to get the content type from the file.
- */
- get contentType() {
- if (this._contentType) {
- return this._contentType;
- }
- if (this.isDir) {
- return "x-directory/normal";
- }
- try {
- this._contentType = mimeService.getTypeFromFile(new FileUtils.File(this.path));
- } catch (ex) {
- if (ex.name !== "NS_ERROR_NOT_AVAILABLE" &&
- ex.name !== "NS_ERROR_FAILURE") {
- console.error(ex, this.path);
- }
- this._contentType = null;
- }
- return this._contentType;
- },
-
- /**
- * A string used when determining the type of Editor to open for this.
- * See editors.js -> EditorTypeForResource.
- */
- get contentCategory() {
- const NetworkHelper = require("devtools/shared/webconsole/network-helper");
- let category = NetworkHelper.mimeCategoryMap[this.contentType];
- // Special treatment for manifest.webapp.
- if (!category && this.basename === "manifest.webapp") {
- return "json";
- }
- return category || "txt";
- }
-});
-
-exports.FileResource = FileResource;
deleted file mode 100644
--- a/devtools/client/projecteditor/lib/tree.js
+++ /dev/null
@@ -1,593 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { Cu } = require("chrome");
-const { Class } = require("sdk/core/heritage");
-const { emit } = require("sdk/event/core");
-const { EventTarget } = require("sdk/event/target");
-const { merge } = require("sdk/util/object");
-const promise = require("promise");
-const { InplaceEditor } = require("devtools/client/shared/inplace-editor");
-const { on, forget } = require("devtools/client/projecteditor/lib/helpers/event");
-const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
-
-const HTML_NS = "http://www.w3.org/1999/xhtml";
-
-/**
- * ResourceContainer is used as the view of a single Resource in
- * the tree. It is not exported.
- */
-var ResourceContainer = Class({
- /**
- * @param ProjectTreeView tree
- * @param Resource resource
- */
- initialize: function (tree, resource) {
- this.tree = tree;
- this.resource = resource;
- this.elt = null;
- this.expander = null;
- this.children = null;
-
- let doc = tree.doc;
-
- this.elt = doc.createElementNS(HTML_NS, "li");
- this.elt.classList.add("child");
-
- this.line = doc.createElementNS(HTML_NS, "div");
- this.line.classList.add("child");
- this.line.classList.add("entry");
- this.line.setAttribute("theme", "dark");
- this.line.setAttribute("tabindex", "0");
-
- this.elt.appendChild(this.line);
-
- this.highlighter = doc.createElementNS(HTML_NS, "span");
- this.highlighter.classList.add("highlighter");
- this.line.appendChild(this.highlighter);
-
- this.expander = doc.createElementNS(HTML_NS, "span");
- this.expander.className = "arrow expander";
- this.expander.setAttribute("open", "");
- this.line.appendChild(this.expander);
-
- this.label = doc.createElementNS(HTML_NS, "span");
- this.label.className = "file-label";
- this.line.appendChild(this.label);
-
- this.line.addEventListener("contextmenu", (ev) => {
- this.select();
- this.openContextMenu(ev);
- });
-
- this.children = doc.createElementNS(HTML_NS, "ul");
- this.children.classList.add("children");
-
- this.elt.appendChild(this.children);
-
- this.line.addEventListener("click", (evt) => {
- this.select();
- this.toggleExpansion();
- evt.stopPropagation();
- });
- this.expander.addEventListener("click", (evt) => {
- this.toggleExpansion();
- this.select();
- evt.stopPropagation();
- }, true);
-
- if (!this.resource.isRoot) {
- this.expanded = false;
- }
- this.update();
- },
-
- toggleExpansion: function () {
- if (!this.resource.isRoot) {
- this.expanded = !this.expanded;
- } else {
- this.expanded = true;
- }
- },
-
- destroy: function () {
- this.elt.remove();
- this.expander.remove();
- this.highlighter.remove();
- this.children.remove();
- this.label.remove();
- this.elt = this.expander = this.highlighter = this.children = this.label = null;
- },
-
- /**
- * Open the context menu when right clicking on the view.
- * XXX: We could pass this to plugins to allow themselves
- * to be register/remove items from the context menu if needed.
- *
- * @param Event e
- */
- openContextMenu: function (ev) {
- ev.preventDefault();
- let popup = this.tree.options.contextMenuPopup;
- popup.openPopupAtScreen(ev.screenX, ev.screenY, true);
- },
-
- /**
- * Update the view based on the current state of the Resource.
- */
- update: function () {
- let visible = this.tree.options.resourceVisible ?
- this.tree.options.resourceVisible(this.resource) :
- true;
-
- this.elt.hidden = !visible;
-
- this.tree.options.resourceFormatter(this.resource, this.label);
-
- this.expander.style.visibility = this.resource.hasChildren ? "visible" : "hidden";
-
- },
-
- /**
- * Select this view in the ProjectTreeView.
- */
- select: function () {
- this.tree.selectContainer(this);
- },
-
- /**
- * @returns Boolean
- * Is this view currently selected
- */
- get selected() {
- return this.line.classList.contains("selected");
- },
-
- /**
- * Set the selected state in the UI.
- */
- set selected(v) {
- if (v) {
- this.line.classList.add("selected");
- } else {
- this.line.classList.remove("selected");
- }
- },
-
- /**
- * @returns Boolean
- * Are any children visible.
- */
- get expanded() {
- return !this.elt.classList.contains("tree-collapsed");
- },
-
- /**
- * Set the visiblity state of children.
- */
- set expanded(v) {
- if (v) {
- this.elt.classList.remove("tree-collapsed");
- this.expander.setAttribute("open", "");
- } else {
- this.expander.removeAttribute("open");
- this.elt.classList.add("tree-collapsed");
- }
- }
-});
-
-/**
- * TreeView is a view managing a list of children.
- * It is not to be instantiated directly - only extended.
- * Use ProjectTreeView instead.
- */
-var TreeView = Class({
- extends: EventTarget,
-
- /**
- * @param Document document
- * @param Object options
- * - contextMenuPopup: a <menupopup> element
- * - resourceFormatter: a function(Resource, DOMNode)
- * that renders the resource into the view
- * - resourceVisible: a function(Resource) -> Boolean
- * that determines if the resource should show up.
- */
- initialize: function (doc, options) {
- this.doc = doc;
- this.options = merge({
- resourceFormatter: function (resource, elt) {
- elt.textContent = resource.toString();
- }
- }, options);
- this.models = new Set();
- this.roots = new Set();
- this._containers = new Map();
- this.elt = this.doc.createElementNS(HTML_NS, "div");
- this.elt.tree = this;
- this.elt.className = "sources-tree";
- this.elt.setAttribute("with-arrows", "true");
- this.elt.setAttribute("theme", "dark");
- this.elt.setAttribute("flex", "1");
-
- this.children = this.doc.createElementNS(HTML_NS, "ul");
- this.elt.appendChild(this.children);
-
- this.resourceChildrenChanged = this.resourceChildrenChanged.bind(this);
- this.removeResource = this.removeResource.bind(this);
- this.updateResource = this.updateResource.bind(this);
- },
-
- destroy: function () {
- this._destroyed = true;
- this.elt.remove();
- },
-
- /**
- * Helper function to create DOM elements for promptNew and promptEdit
- */
- createInputContainer: function () {
- let inputholder = this.doc.createElementNS(HTML_NS, "div");
- inputholder.className = "child entry";
-
- let expander = this.doc.createElementNS(HTML_NS, "span");
- expander.className = "arrow expander";
- expander.setAttribute("invisible", "");
- inputholder.appendChild(expander);
-
- let placeholder = this.doc.createElementNS(HTML_NS, "div");
- placeholder.className = "child";
- inputholder.appendChild(placeholder);
-
- return {inputholder, placeholder};
- },
-
- /**
- * Prompt the user to create a new file in the tree.
- *
- * @param string initial
- * The suggested starting file name
- * @param Resource parent
- * @param Resource sibling
- * Which resource to put this next to. If not set,
- * it will be put in front of all other children.
- *
- * @returns Promise
- * Resolves once the prompt has been successful,
- * Rejected if it is cancelled
- */
- promptNew: function (initial, parent, sibling = null) {
- let deferred = promise.defer();
-
- let parentContainer = this._containers.get(parent);
- let item = this.doc.createElement("li");
- item.className = "child";
-
- let {inputholder, placeholder} = this.createInputContainer();
- item.appendChild(inputholder);
-
- let children = parentContainer.children;
- sibling = sibling ? this._containers.get(sibling).elt : null;
- parentContainer.children.insertBefore(item, sibling ? sibling.nextSibling : children.firstChild);
-
- new InplaceEditor({
- element: placeholder,
- initial: initial,
- preserveTextStyles: true,
- start: editor => {
- editor.input.select();
- },
- done: function (val, commit) {
- if (commit) {
- deferred.resolve(val);
- } else {
- deferred.reject(val);
- }
- parentContainer.line.focus();
- },
- destroy: () => {
- item.remove();
- },
- });
-
- return deferred.promise;
- },
-
- /**
- * Prompt the user to rename file in the tree.
- *
- * @param string initial
- * The suggested starting file name
- * @param resource
- *
- * @returns Promise
- * Resolves once the prompt has been successful,
- * Rejected if it is cancelled
- */
- promptEdit: function (initial, resource) {
- let deferred = promise.defer();
- let item = this._containers.get(resource).elt;
- let originalText = item.childNodes[0];
-
- let {inputholder, placeholder} = this.createInputContainer();
- item.insertBefore(inputholder, originalText);
-
- item.removeChild(originalText);
-
- new InplaceEditor({
- element: placeholder,
- initial: initial,
- preserveTextStyles: true,
- start: editor => {
- editor.input.select();
- },
- done: function (val, commit) {
- if (val === initial) {
- item.insertBefore(originalText, inputholder);
- }
-
- item.removeChild(inputholder);
-
- if (commit) {
- deferred.resolve(val);
- } else {
- deferred.reject(val);
- }
- },
- });
-
- return deferred.promise;
- },
-
- /**
- * Add a new Store into the TreeView
- *
- * @param Store model
- */
- addModel: function (model) {
- if (this.models.has(model)) {
- // Requesting to add a model that already exists
- return;
- }
- this.models.add(model);
- let placeholder = this.doc.createElementNS(HTML_NS, "li");
- placeholder.style.display = "none";
- this.children.appendChild(placeholder);
- this.roots.add(model.root);
- model.root.refresh().then(root => {
- if (this._destroyed || !this.models.has(model)) {
- // model may have been removed during the initial refresh.
- // In this case, do not import the resource or add to DOM, just leave it be.
- return;
- }
- let container = this.importResource(root);
- container.line.classList.add("entry-group-title");
- container.line.setAttribute("theme", "dark");
- this.selectContainer(container);
-
- this.children.insertBefore(container.elt, placeholder);
- this.children.removeChild(placeholder);
- });
- },
-
- /**
- * Remove a Store from the TreeView
- *
- * @param Store model
- */
- removeModel: function (model) {
- this.models.delete(model);
- this.removeResource(model.root);
- },
-
-
- /**
- * Get the ResourceContainer. Used for testing the view.
- *
- * @param Resource resource
- * @returns ResourceContainer
- */
- getViewContainer: function (resource) {
- return this._containers.get(resource);
- },
-
- /**
- * Select a ResourceContainer in the tree.
- *
- * @param ResourceContainer container
- */
- selectContainer: function (container) {
- if (this.selectedContainer === container) {
- return;
- }
- if (this.selectedContainer) {
- this.selectedContainer.selected = false;
- }
- this.selectedContainer = container;
- container.selected = true;
- emit(this, "selection", container.resource);
- },
-
- /**
- * Select a Resource in the tree.
- *
- * @param Resource resource
- */
- selectResource: function (resource) {
- this.selectContainer(this._containers.get(resource));
- },
-
- /**
- * Get the currently selected Resource
- *
- * @param Resource resource
- */
- getSelectedResource: function () {
- return this.selectedContainer.resource;
- },
-
- /**
- * Insert a Resource into the view.
- * Makes a new ResourceContainer if needed
- *
- * @param Resource resource
- */
- importResource: function (resource) {
- if (!resource) {
- return null;
- }
-
- if (this._containers.has(resource)) {
- return this._containers.get(resource);
- }
- var container = ResourceContainer(this, resource);
- this._containers.set(resource, container);
- this._updateChildren(container);
-
- on(this, resource, "children-changed", this.resourceChildrenChanged);
- on(this, resource, "label-change", this.updateResource);
- on(this, resource, "deleted", this.removeResource);
-
- return container;
- },
-
- /**
- * Remove a Resource (including children) from the view.
- *
- * @param Resource resource
- */
- removeResource: function (resource) {
- let toRemove = resource.allDescendants();
- toRemove.add(resource);
- for (let remove of toRemove) {
- this._removeResource(remove);
- }
- },
-
- /**
- * Remove an individual Resource (but not children) from the view.
- *
- * @param Resource resource
- */
- _removeResource: function (resource) {
- forget(this, resource);
- if (this._containers.get(resource)) {
- this._containers.get(resource).destroy();
- this._containers.delete(resource);
- }
- emit(this, "resource-removed", resource);
- },
-
- /**
- * Listener for when a resource has new children.
- * This can happen as files are being loaded in from FileSystem, for example.
- *
- * @param Resource resource
- */
- resourceChildrenChanged: function (resource) {
- this.updateResource(resource);
- this._updateChildren(this._containers.get(resource));
- },
-
- /**
- * Listener for when a label in the view has been updated.
- * For example, the 'dirty' plugin marks changed files with an '*'
- * next to the filename, and notifies with this event.
- *
- * @param Resource resource
- */
- updateResource: function (resource) {
- let container = this._containers.get(resource);
- container.update();
- },
-
- /**
- * Build necessary ResourceContainers for a Resource and its
- * children, then append them into the view.
- *
- * @param ResourceContainer container
- */
- _updateChildren: function (container) {
- let resource = container.resource;
- let fragment = this.doc.createDocumentFragment();
- if (resource.children) {
- for (let child of resource.childrenSorted) {
- let childContainer = this.importResource(child);
- fragment.appendChild(childContainer.elt);
- }
- }
-
- while (container.children.firstChild) {
- container.children.firstChild.remove();
- }
-
- container.children.appendChild(fragment);
- },
-});
-
-/**
- * ProjectTreeView is the implementation of TreeView
- * that is exported. This is the class that is to be used
- * directly.
- */
-var ProjectTreeView = Class({
- extends: TreeView,
-
- /**
- * See TreeView.initialize
- *
- * @param Document document
- * @param Object options
- */
- initialize: function (document, options) {
- TreeView.prototype.initialize.apply(this, arguments);
- },
-
- destroy: function () {
- this.forgetProject();
- TreeView.prototype.destroy.apply(this, arguments);
- },
-
- /**
- * Remove current project and empty the tree
- */
- forgetProject: function () {
- if (this.project) {
- forget(this, this.project);
- for (let store of this.project.allStores()) {
- this.removeModel(store);
- }
- }
- },
-
- /**
- * Show a project in the tree
- *
- * @param Project project
- * The project to render into a tree
- */
- setProject: function (project) {
- this.forgetProject();
- this.project = project;
- if (this.project) {
- on(this, project, "store-added", this.addModel.bind(this));
- on(this, project, "store-removed", this.removeModel.bind(this));
- on(this, project, "project-saved", this.refresh.bind(this));
- this.refresh();
- }
- },
-
- /**
- * Refresh the tree with all of the current project stores
- */
- refresh: function () {
- for (let store of this.project.allStores()) {
- this.addModel(store);
- }
- }
-});
-
-exports.ProjectTreeView = ProjectTreeView;
deleted file mode 100644
--- a/devtools/client/projecteditor/moz.build
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['lib']
-
-BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
deleted file mode 100644
--- a/devtools/client/projecteditor/test/.eslintrc.js
+++ /dev/null
@@ -1,6 +0,0 @@
-"use strict";
-
-module.exports = {
- // Extend from the shared list of defined globals for mochitests.
- "extends": "../../../.eslintrc.mochitests.js"
-};
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser.ini
+++ /dev/null
@@ -1,32 +0,0 @@
-[DEFAULT]
-tags = devtools
-subsuite = devtools
-support-files =
- head.js
- helper_homepage.html
- helper_edits.js
- projecteditor-test.xul
-
-[browser_projecteditor_app_options.js]
-[browser_projecteditor_confirm_unsaved.js]
-[browser_projecteditor_contextmenu_01.js]
-skip-if = asan # Bug 1083140
-[browser_projecteditor_contextmenu_02.js]
-skip-if = true # Bug 1173950
-[browser_projecteditor_delete_file.js]
-skip-if = e10s # Frequent failures in e10s - Bug 1020027
-[browser_projecteditor_rename_file_01.js]
-[browser_projecteditor_rename_file_02.js]
-[browser_projecteditor_editing_01.js]
-[browser_projecteditor_editors_image.js]
-[browser_projecteditor_external_change.js]
-[browser_projecteditor_immediate_destroy.js]
-[browser_projecteditor_init.js]
-[browser_projecteditor_menubar_01.js]
-[browser_projecteditor_menubar_02.js]
-skip-if = true # Bug 1173950
-[browser_projecteditor_new_file.js]
-[browser_projecteditor_saveall.js]
-[browser_projecteditor_stores.js]
-[browser_projecteditor_tree_selection_01.js]
-[browser_projecteditor_tree_selection_02.js]
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_app_options.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/* 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";
-
-// Test that options can be changed without resetting the whole
-// editor.
-add_task(function* () {
-
- let TEMP_PATH = buildTempDirectoryStructure();
- let projecteditor = yield addProjectEditorTab();
-
- let resourceBeenAdded = promise.defer();
- projecteditor.project.once("resource-added", () => {
- info("A resource has been added");
- resourceBeenAdded.resolve();
- });
-
- info("About to set project to: " + TEMP_PATH);
- yield projecteditor.setProjectToAppPath(TEMP_PATH, {
- name: "Test",
- iconUrl: "chrome://devtools/skin/images/tool-options.svg",
- projectOverviewURL: SAMPLE_WEBAPP_URL
- });
-
- info("Making sure a resource has been added before continuing");
- yield resourceBeenAdded.promise;
-
- info("From now on, if a resource is added it should fail");
- projecteditor.project.on("resource-added", failIfResourceAdded);
-
- info("Getting ahold and validating the project header DOM");
- let header = projecteditor.document.querySelector(".entry-group-title");
- let image = header.querySelector(".project-image");
- let nameLabel = header.querySelector(".project-name-label");
- let statusElement = header.querySelector(".project-status");
- is(statusElement.getAttribute("status"), "unknown", "The status starts out as unknown.");
- is(nameLabel.textContent, "Test", "The name label has been set correctly");
- is(image.getAttribute("src"), "chrome://devtools/skin/images/tool-options.svg", "The icon has been set correctly");
-
- info("About to set project with new options.");
- yield projecteditor.setProjectToAppPath(TEMP_PATH, {
- name: "Test2",
- iconUrl: "chrome://devtools/skin/images/tool-inspector.svg",
- projectOverviewURL: SAMPLE_WEBAPP_URL,
- validationStatus: "error"
- });
-
- info("Getting ahold of and validating the project header DOM");
- is(statusElement.getAttribute("status"), "error", "The status has been set correctly.");
- is(nameLabel.textContent, "Test2", "The name label has been set correctly");
- is(image.getAttribute("src"), "chrome://devtools/skin/images/tool-inspector.svg", "The icon has been set correctly");
-
- info("About to set project with new options.");
- yield projecteditor.setProjectToAppPath(TEMP_PATH, {
- name: "Test3",
- iconUrl: "chrome://devtools/skin/images/tool-webconsole.svg",
- projectOverviewURL: SAMPLE_WEBAPP_URL,
- validationStatus: "warning"
- });
-
- info("Getting ahold of and validating the project header DOM");
- is(statusElement.getAttribute("status"), "warning", "The status has been set correctly.");
- is(nameLabel.textContent, "Test3", "The name label has been set correctly");
- is(image.getAttribute("src"), "chrome://devtools/skin/images/tool-webconsole.svg", "The icon has been set correctly");
-
- info("About to set project with new options.");
- yield projecteditor.setProjectToAppPath(TEMP_PATH, {
- name: "Test4",
- iconUrl: "chrome://devtools/skin/images/tool-debugger.svg",
- projectOverviewURL: SAMPLE_WEBAPP_URL,
- validationStatus: "valid"
- });
-
- info("Getting ahold of and validating the project header DOM");
- is(statusElement.getAttribute("status"), "valid", "The status has been set correctly.");
- is(nameLabel.textContent, "Test4", "The name label has been set correctly");
- is(image.getAttribute("src"), "chrome://devtools/skin/images/tool-debugger.svg", "The icon has been set correctly");
-
- info("Test finished, cleaning up");
- projecteditor.project.off("resource-added", failIfResourceAdded);
-});
-
-function failIfResourceAdded() {
- ok(false, "A resource has been added, but it shouldn't have been");
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_confirm_unsaved.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* 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.
-add_task(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");
- Services.obs.addObserver(confirmYes, "tabmodal-dialog-loaded");
-
- 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");
- Services.obs.addObserver(confirmNo, "tabmodal-dialog-loaded");
-
- ok(projecteditor.hasUnsavedResources, "There are unsaved resources");
- ok(!projecteditor.confirmUnsaved(), "When there are unsaved changes, clicking cancel makes confirmUnsaved() false");
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_contextmenu_01.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 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";
-
-// Test that context menus append to the correct document.
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory({
- menubar: false
- });
- ok(projecteditor, "ProjectEditor has loaded");
-
- let contextMenuPopup = projecteditor.document.querySelector("#context-menu-popup");
- let textEditorContextMenuPopup = projecteditor.document.querySelector("#texteditor-context-popup");
- ok(contextMenuPopup, "The menu has loaded in the projecteditor document");
- ok(textEditorContextMenuPopup, "The menu has loaded in the projecteditor document");
-
- let projecteditor2 = yield addProjectEditorTabForTempDirectory();
- contextMenuPopup = projecteditor2.document.getElementById("context-menu-popup");
- textEditorContextMenuPopup = projecteditor2.document.getElementById("texteditor-context-popup");
- ok(!contextMenuPopup, "The menu has NOT loaded in the projecteditor document");
- ok(!textEditorContextMenuPopup, "The menu has NOT loaded in the projecteditor document");
- ok(content.document.querySelector("#context-menu-popup"), "The menu has loaded in the specified element");
- ok(content.document.querySelector("#texteditor-context-popup"), "The menu has loaded in the specified element");
-});
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_contextmenu_02.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 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 context menu enabled / disabled state in editor
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- ok(projecteditor, "ProjectEditor has loaded");
-
- let {textEditorContextMenuPopup} = projecteditor;
-
- // Update menu items for a clean slate, so previous tests cannot
- // affect paste, and possibly other side effects
- projecteditor._updateMenuItems();
-
- let cmdDelete = textEditorContextMenuPopup.querySelector("[command=cmd_delete]");
- let cmdSelectAll = textEditorContextMenuPopup.querySelector("[command=cmd_selectAll]");
- let cmdCut = textEditorContextMenuPopup.querySelector("[command=cmd_cut]");
- let cmdCopy = textEditorContextMenuPopup.querySelector("[command=cmd_copy]");
- let cmdPaste = textEditorContextMenuPopup.querySelector("[command=cmd_paste]");
-
- info("Opening resource");
- let resource = projecteditor.project.allResources()[2];
- yield selectFile(projecteditor, resource);
- let editor = projecteditor.currentEditor;
- editor.editor.focus();
-
- info("Opening context menu on resource");
- yield openContextMenuForEditor(editor, textEditorContextMenuPopup);
-
- is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
- is(cmdSelectAll.getAttribute("disabled"), "", "cmdSelectAll is enabled");
- is(cmdCut.getAttribute("disabled"), "true", "cmdCut is disabled");
- is(cmdCopy.getAttribute("disabled"), "true", "cmdCopy is disabled");
- is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
-
- info("Setting a selection and repening context menu on resource");
- yield closeContextMenuForEditor(editor, textEditorContextMenuPopup);
- editor.editor.setSelection({line: 0, ch: 0}, {line: 0, ch: 2});
- yield openContextMenuForEditor(editor, textEditorContextMenuPopup);
-
- is(cmdDelete.getAttribute("disabled"), "", "cmdDelete is enabled");
- is(cmdSelectAll.getAttribute("disabled"), "", "cmdSelectAll is enabled");
- is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
- is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
- is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
-});
-
-function* openContextMenuForEditor(editor, contextMenu) {
- let editorDoc = editor.editor.container.contentDocument;
- let shown = onPopupShow(contextMenu);
- EventUtils.synthesizeMouse(editorDoc.body, 2, 2,
- {type: "contextmenu", button: 2}, editorDoc.defaultView);
- yield shown;
-}
-function* closeContextMenuForEditor(editor, contextMenu) {
- let editorDoc = editor.editor.container.contentDocument;
- let hidden = onPopupHidden(contextMenu);
- contextMenu.hidePopup();
- yield hidden;
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_delete_file.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/* 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";
-
-// Test tree selection functionality
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- ok(true, "ProjectEditor has loaded");
-
- let root = [...projecteditor.project.allStores()][0].root;
- is(root.path, TEMP_PATH, "The root store is set to the correct temp path.");
- for (let child of root.children) {
- yield deleteWithContextMenu(projecteditor, projecteditor.projectTree.getViewContainer(child));
- }
-
- yield testDeleteOnRoot(projecteditor, projecteditor.projectTree.getViewContainer(root));
-});
-
-
-function openContextMenuOn(node) {
- EventUtils.synthesizeMouseAtCenter(
- node,
- {button: 2, type: "contextmenu"},
- node.ownerDocument.defaultView
- );
-}
-
-function* testDeleteOnRoot(projecteditor, container) {
- let popup = projecteditor.contextMenuPopup;
- let oncePopupShown = onPopupShow(popup);
- openContextMenuOn(container.label);
- yield oncePopupShown;
-
- let deleteCommand = popup.querySelector("[command=cmd-delete]");
- ok(deleteCommand, "Delete command exists in popup");
- is(deleteCommand.getAttribute("hidden"), "true", "Delete command is hidden");
-}
-
-function deleteWithContextMenu(projecteditor, container) {
- let defer = promise.defer();
-
- let popup = projecteditor.contextMenuPopup;
- let resource = container.resource;
- info("Going to attempt deletion for: " + resource.path);
-
- onPopupShow(popup).then(function () {
- let deleteCommand = popup.querySelector("[command=cmd-delete]");
- ok(deleteCommand, "Delete command exists in popup");
- is(deleteCommand.getAttribute("hidden"), "", "Delete command is visible");
- is(deleteCommand.getAttribute("disabled"), "", "Delete command is enabled");
-
- function onConfirmShown(aSubject) {
- info("confirm dialog observed as expected");
- Services.obs.removeObserver(onConfirmShown, "common-dialog-loaded");
- Services.obs.removeObserver(onConfirmShown, "tabmodal-dialog-loaded");
-
- projecteditor.project.on("refresh-complete", function refreshComplete() {
- projecteditor.project.off("refresh-complete", refreshComplete);
- OS.File.stat(resource.path).then(() => {
- ok(false, "The file was not deleted");
- defer.resolve();
- }, (ex) => {
- ok(ex instanceof OS.File.Error && ex.becauseNoSuchFile, "OS.File.stat promise was rejected because the file is gone");
- defer.resolve();
- });
- });
-
- // Click the 'OK' button
- aSubject.Dialog.ui.button0.click();
- }
-
- Services.obs.addObserver(onConfirmShown, "common-dialog-loaded");
- Services.obs.addObserver(onConfirmShown, "tabmodal-dialog-loaded");
-
- deleteCommand.click();
- popup.hidePopup();
- });
-
- openContextMenuOn(container.label);
-
- return defer.promise;
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_editing_01.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* 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";
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy");
-
-loadHelperScript("helper_edits.js");
-
-// Test ProjectEditor basic functionality
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- let TEMP_PATH = projecteditor.project.allPaths()[0];
-
- is(getTempFile("").path, TEMP_PATH, "Temp path is set correctly.");
-
- ok(projecteditor.currentEditor, "There is an editor for projecteditor");
- let resources = projecteditor.project.allResources();
-
- for (let data of helperEditData) {
- info("Processing " + data.path);
- let resource = resources.filter(r=>r.basename === data.basename)[0];
- yield selectFile(projecteditor, resource);
- yield testEditFile(projecteditor, getTempFile(data.path).path, data.newContent);
- }
-});
-
-function* testEditFile(projecteditor, filePath, newData) {
- info("Testing file editing for: " + filePath);
-
- let initialData = yield getFileData(filePath);
- let editor = projecteditor.currentEditor;
- let resource = projecteditor.resourceFor(editor);
- let viewContainer = projecteditor.projectTree.getViewContainer(resource);
- let originalTreeLabel = viewContainer.label.textContent;
-
- is(resource.path, filePath, "Resource path is set correctly");
- is(editor.editor.getText(), initialData, "Editor is loaded with correct file contents");
-
- info("Setting text in the editor and doing checks before saving");
-
- editor.editor.undo();
- editor.editor.undo();
- is(editor.editor.getText(), initialData, "Editor is still loaded with correct contents after undo");
-
- editor.editor.setText(newData);
- is(editor.editor.getText(), newData, "Editor has been filled with new data");
- is(viewContainer.label.textContent, "*" + originalTreeLabel, "Label is marked as changed");
-
- info("Saving the editor and checking to make sure the file gets saved on disk");
-
- editor.save(resource);
-
- let savedResource = yield onceEditorSave(projecteditor);
-
- is(viewContainer.label.textContent, originalTreeLabel, "Label is unmarked as changed");
- is(savedResource.path, filePath, "The saved resouce path matches the original file path");
- is(savedResource, resource, "The saved resource is the same as the original resource");
-
- let savedData = yield getFileData(filePath);
- is(savedData, newData, "Data has been correctly saved to disk");
-
- info("Finished checking saving for " + filePath);
-
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_editors_image.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* 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";
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy");
-
-loadHelperScript("helper_edits.js");
-
-// Test ProjectEditor image editor functionality
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- let TEMP_PATH = projecteditor.project.allPaths()[0];
-
- is(getTempFile("").path, TEMP_PATH, "Temp path is set correctly.");
-
- ok(projecteditor.currentEditor, "There is an editor for projecteditor");
- let resources = projecteditor.project.allResources();
-
- let helperImageData = [
- {
- basename: "16x16.png",
- path: "img/icons/16x16.png"
- },
- {
- basename: "32x32.png",
- path: "img/icons/32x32.png"
- },
- {
- basename: "128x128.png",
- path: "img/icons/128x128.png"
- },
- ];
-
- for (let data of helperImageData) {
- info("Processing " + data.path);
- let resource = resources.filter(r=>r.basename === data.basename)[0];
- yield selectFile(projecteditor, resource);
- yield testEditor(projecteditor, getTempFile(data.path).path);
- }
-});
-
-function* testEditor(projecteditor, filePath) {
- info("Testing file editing for: " + filePath);
-
- let editor = projecteditor.currentEditor;
- let resource = projecteditor.resourceFor(editor);
-
- is(resource.path, filePath, "Resource path is set correctly");
-
- let images = editor.elt.querySelectorAll("image");
- is(images.length, 1, "There is one image inside the editor");
- is(images[0], editor.image, "The image property is set correctly with the DOM");
- is(editor.image.getAttribute("src"), resource.uri, "The image has the resource URL");
-
- info("Selecting another resource, then reselecting this one");
- projecteditor.projectTree.selectResource(resource.store.root);
- yield onceEditorActivated(projecteditor);
- projecteditor.projectTree.selectResource(resource);
- yield onceEditorActivated(projecteditor);
-
- editor = projecteditor.currentEditor;
- images = editor.elt.querySelectorAll("image");
- ok(images.length, 1, "There is one image inside the editor");
- is(images[0], editor.image, "The image property is set correctly with the DOM");
- is(editor.image.getAttribute("src"), resource.uri, "The image has the resource URL");
-
- info("Finished checking saving for " + filePath);
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_external_change.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/* 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 ProjectEditor reaction to external changes (made outside of the)
-// editor.
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- let TEMP_PATH = projecteditor.project.allPaths()[0];
-
- is(getTempFile("").path, TEMP_PATH, "Temp path is set correctly.");
-
- ok(projecteditor.currentEditor, "There is an editor for projecteditor");
- let resources = projecteditor.project.allResources();
-
- for (let data of helperEditData) {
- info("Processing " + data.path);
- let resource = resources.filter(r=>r.basename === data.basename)[0];
- yield selectFile(projecteditor, resource);
- yield testChangeFileExternally(projecteditor, getTempFile(data.path).path, data.newContent);
- yield testChangeUnsavedFileExternally(projecteditor, getTempFile(data.path).path, data.newContent + "[changed]");
- }
-});
-
-function* testChangeUnsavedFileExternally(projecteditor, filePath, newData) {
- info("Testing file external changes for: " + filePath);
-
- let editor = projecteditor.currentEditor;
- let resource = projecteditor.resourceFor(editor);
- let initialData = yield getFileData(filePath);
-
- is(resource.path, filePath, "Resource path is set correctly");
- is(editor.editor.getText(), initialData, "Editor is loaded with correct file contents");
-
- info("Editing but not saving file in project editor");
- ok(editor.isClean(), "Editor is clean");
- editor.editor.setText("foobar");
- ok(!editor.isClean(), "Editor is dirty");
-
- info("Editor has been selected, writing to file externally");
- yield writeToFile(resource.path, newData);
-
- info("Selecting another resource, then reselecting this one");
- projecteditor.projectTree.selectResource(resource.store.root);
- yield onceEditorActivated(projecteditor);
- projecteditor.projectTree.selectResource(resource);
- yield onceEditorActivated(projecteditor);
-
- editor = projecteditor.currentEditor;
- info("Checking to make sure the editor is now populated correctly");
- is(editor.editor.getText(), "foobar", "Editor has not been updated with new file contents");
-
- info("Finished checking saving for " + filePath);
-}
-
-function* testChangeFileExternally(projecteditor, filePath, newData) {
- info("Testing file external changes for: " + filePath);
-
- let editor = projecteditor.currentEditor;
- let resource = projecteditor.resourceFor(editor);
- let initialData = yield getFileData(filePath);
-
- is(resource.path, filePath, "Resource path is set correctly");
- is(editor.editor.getText(), initialData, "Editor is loaded with correct file contents");
-
- info("Editor has been selected, writing to file externally");
- yield writeToFile(resource.path, newData);
-
- info("Selecting another resource, then reselecting this one");
- projecteditor.projectTree.selectResource(resource.store.root);
- yield onceEditorActivated(projecteditor);
- projecteditor.projectTree.selectResource(resource);
- yield onceEditorActivated(projecteditor);
-
- editor = projecteditor.currentEditor;
- info("Checking to make sure the editor is now populated correctly");
- is(editor.editor.getText(), newData, "Editor has been updated with correct file contents");
-
- info("Finished checking saving for " + filePath);
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_immediate_destroy.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* 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";
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy");
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: this.window is null");
-
-// Test that projecteditor can be destroyed in various states of loading
-// without causing any leaks or exceptions.
-
-add_task(function* () {
-
- info("Testing tab closure when projecteditor is in various states");
- let loaderUrl = "chrome://mochitests/content/browser/devtools/client/projecteditor/test/projecteditor-test.xul";
-
- yield addTab(loaderUrl).then(() => {
- let iframe = content.document.getElementById("projecteditor-iframe");
- ok(iframe, "Tab has placeholder iframe for projecteditor");
-
- info("Closing the tab without doing anything");
- gBrowser.removeCurrentTab();
- });
-
- yield addTab(loaderUrl).then(() => {
- let iframe = content.document.getElementById("projecteditor-iframe");
- ok(iframe, "Tab has placeholder iframe for projecteditor");
-
- let projecteditor = ProjectEditor.ProjectEditor();
- ok(projecteditor, "ProjectEditor has been initialized");
-
- info("Closing the tab before attempting to load");
- gBrowser.removeCurrentTab();
- });
-
- yield addTab(loaderUrl).then(() => {
- let iframe = content.document.getElementById("projecteditor-iframe");
- ok(iframe, "Tab has placeholder iframe for projecteditor");
-
- let projecteditor = ProjectEditor.ProjectEditor();
- ok(projecteditor, "ProjectEditor has been initialized");
-
- projecteditor.load(iframe);
-
- info("Closing the tab after a load is requested, but before load is finished");
- gBrowser.removeCurrentTab();
- });
-
- yield addTab(loaderUrl).then(() => {
- let iframe = content.document.getElementById("projecteditor-iframe");
- ok(iframe, "Tab has placeholder iframe for projecteditor");
-
- let projecteditor = ProjectEditor.ProjectEditor();
- ok(projecteditor, "ProjectEditor has been initialized");
-
- return projecteditor.load(iframe).then(() => {
- info("Closing the tab after a load has been requested and finished");
- gBrowser.removeCurrentTab();
- });
- });
-
- yield addTab(loaderUrl).then(() => {
- let iframe = content.document.getElementById("projecteditor-iframe");
- ok(iframe, "Tab has placeholder iframe for projecteditor");
-
- let projecteditor = ProjectEditor.ProjectEditor(iframe);
- ok(projecteditor, "ProjectEditor has been initialized");
-
- let loadedDone = promise.defer();
- projecteditor.loaded.then(() => {
- ok(false, "Loaded has finished after destroy() has been called");
- loadedDone.resolve();
- }, () => {
- ok(true, "Loaded has been rejected after destroy() has been called");
- loadedDone.resolve();
- });
-
- projecteditor.destroy();
-
- return loadedDone.promise.then(() => {
- gBrowser.removeCurrentTab();
- });
- });
-
- finish();
-});
-
-
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_init.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* 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";
-
-// Test that projecteditor can be initialized.
-
-function test() {
- info("Initializing projecteditor");
- addProjectEditorTab().then((projecteditor) => {
- ok(projecteditor, "Load callback has been called");
- ok(projecteditor.shells, "ProjectEditor has shells");
- ok(projecteditor.project, "ProjectEditor has a project");
- finish();
- });
-}
-
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_menubar_01.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* 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";
-
-// Test that menu bar appends to the correct document.
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory({
- menubar: false
- });
- ok(projecteditor, "ProjectEditor has loaded");
-
- let fileMenu = projecteditor.document.getElementById("file-menu");
- let editMenu = projecteditor.document.getElementById("edit-menu");
- ok(fileMenu, "The menu has loaded in the projecteditor document");
- ok(editMenu, "The menu has loaded in the projecteditor document");
-
- let projecteditor2 = yield addProjectEditorTabForTempDirectory();
- let menubar = projecteditor2.menubar;
- fileMenu = projecteditor2.document.getElementById("file-menu");
- editMenu = projecteditor2.document.getElementById("edit-menu");
- ok(!fileMenu, "The menu has NOT loaded in the projecteditor document");
- ok(!editMenu, "The menu has NOT loaded in the projecteditor document");
- ok(content.document.querySelector("#file-menu"), "The menu has loaded in the specified element");
- ok(content.document.querySelector("#edit-menu"), "The menu has loaded in the specified element");
-});
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_menubar_02.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/* 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 menu bar enabled / disabled state.
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- let menubar = projecteditor.menubar;
-
- // Update menu items for a clean slate, so previous tests cannot
- // affect paste, and possibly other side effects
- projecteditor._updateMenuItems();
-
- // let projecteditor = yield addProjectEditorTabForTempDirectory();
- ok(projecteditor, "ProjectEditor has loaded");
-
- let fileMenu = menubar.querySelector("#file-menu");
- let editMenu = menubar.querySelector("#edit-menu");
- ok(fileMenu, "The menu has loaded in the projecteditor document");
- ok(editMenu, "The menu has loaded in the projecteditor document");
-
- let cmdNew = fileMenu.querySelector("[command=cmd-new]");
- let cmdSave = fileMenu.querySelector("[command=cmd-save]");
- let cmdSaveas = fileMenu.querySelector("[command=cmd-saveas]");
-
- let cmdUndo = editMenu.querySelector("[command=cmd_undo]");
- let cmdRedo = editMenu.querySelector("[command=cmd_redo]");
- let cmdCut = editMenu.querySelector("[command=cmd_cut]");
- let cmdCopy = editMenu.querySelector("[command=cmd_copy]");
- let cmdPaste = editMenu.querySelector("[command=cmd_paste]");
-
- info("Checking initial state of menus");
- yield openAndCloseMenu(fileMenu);
- yield openAndCloseMenu(editMenu);
-
- is(cmdNew.getAttribute("disabled"), "", "File menu item is enabled");
- is(cmdSave.getAttribute("disabled"), "true", "File menu item is disabled");
- is(cmdSaveas.getAttribute("disabled"), "true", "File menu item is disabled");
-
- is(cmdUndo.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdRedo.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdCut.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdCopy.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdPaste.getAttribute("disabled"), "true", "Edit menu item is disabled");
-
- projecteditor.menuEnabled = false;
-
- info("Checking with menuEnabled = false");
- yield openAndCloseMenu(fileMenu);
- yield openAndCloseMenu(editMenu);
-
- is(cmdNew.getAttribute("disabled"), "true", "File menu item is disabled");
- is(cmdSave.getAttribute("disabled"), "true", "File menu item is disabled");
- is(cmdSaveas.getAttribute("disabled"), "true", "File menu item is disabled");
-
- is(cmdUndo.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdRedo.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdCut.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdCopy.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdPaste.getAttribute("disabled"), "true", "Edit menu item is disabled");
-
- info("Checking with menuEnabled=true");
- projecteditor.menuEnabled = true;
-
- yield openAndCloseMenu(fileMenu);
- yield openAndCloseMenu(editMenu);
-
- is(cmdNew.getAttribute("disabled"), "", "File menu item is enabled");
- is(cmdSave.getAttribute("disabled"), "true", "File menu item is disabled");
- is(cmdSaveas.getAttribute("disabled"), "true", "File menu item is disabled");
-
- is(cmdUndo.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdRedo.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdCut.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdCopy.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdPaste.getAttribute("disabled"), "true", "Edit menu item is disabled");
-
- info("Checking with resource selected");
- let resource = projecteditor.project.allResources()[2];
- yield selectFile(projecteditor, resource);
- let editor = projecteditor.currentEditor;
-
- let onChange = promise.defer();
-
- projecteditor.on("onEditorChange", () => {
- info("onEditorChange has been detected");
- onChange.resolve();
- });
- editor.editor.focus();
- EventUtils.synthesizeKey("f", { }, projecteditor.window);
-
- yield onChange;
- yield openAndCloseMenu(fileMenu);
- yield openAndCloseMenu(editMenu);
-
- is(cmdNew.getAttribute("disabled"), "", "File menu item is enabled");
- is(cmdSave.getAttribute("disabled"), "", "File menu item is enabled");
- is(cmdSaveas.getAttribute("disabled"), "", "File menu item is enabled");
-
- // Use editor.canUndo() to see if this is failing - the menu disabled property
- // should be in sync with this because of isCommandEnabled in editor.js.
- info('cmdUndo.getAttribute("disabled") is: "' + cmdUndo.getAttribute("disabled") + '"');
- ok(editor.editor.canUndo(), "Edit menu item is enabled");
-
- is(cmdRedo.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdCut.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdCopy.getAttribute("disabled"), "true", "Edit menu item is disabled");
- is(cmdPaste.getAttribute("disabled"), "", "Edit menu item is enabled");
-});
-
-function* openAndCloseMenu(menu) {
- let shown = onPopupShow(menu);
- EventUtils.synthesizeMouseAtCenter(menu, {}, menu.ownerDocument.defaultView);
- yield shown;
- let hidden = onPopupHidden(menu);
- EventUtils.synthesizeMouseAtCenter(menu, {}, menu.ownerDocument.defaultView);
- yield hidden;
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_new_file.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/* 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";
-
-// Test tree selection functionality
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- ok(projecteditor, "ProjectEditor has loaded");
-
-});
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_rename_file_01.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* 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";
-
-// Test file rename functionality
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- ok(true, "ProjectEditor has loaded");
-
- let root = [...projecteditor.project.allStores()][0].root;
- is(root.path, TEMP_PATH, "The root store is set to the correct temp path.");
- for (let child of root.children) {
- yield renameWithContextMenu(projecteditor,
- projecteditor.projectTree.getViewContainer(child), ".renamed");
- }
-});
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_rename_file_02.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* 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";
-
-// Test file rename functionality with non ascii characters
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- ok(true, "ProjectEditor has loaded");
-
- let root = [...projecteditor.project.allStores()][0].root;
- is(root.path, TEMP_PATH, "The root store is set to the correct temp path.");
-
- let childrenList = [];
- for (let child of root.children) {
- yield renameWithContextMenu(projecteditor,
- projecteditor.projectTree.getViewContainer(child), ".ren\u0061\u0308med");
- childrenList.push(child.basename + ".ren\u0061\u0308med");
- }
- for (let child of root.children) {
- is(childrenList.indexOf(child.basename) == -1, false,
- "Failed to update tree with non-ascii character");
- }
-});
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_saveall.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 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";
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy");
-
-loadHelperScript("helper_edits.js");
-
-// Test ProjectEditor basic functionality
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- let TEMP_PATH = projecteditor.project.allPaths()[0];
-
- is(getTempFile("").path, TEMP_PATH, "Temp path is set correctly.");
-
- ok(projecteditor.currentEditor, "There is an editor for projecteditor");
- let resources = projecteditor.project.allResources();
-
- for (let data of helperEditData) {
- info("Processing " + data.path);
- let resource = resources.filter(r=>r.basename === data.basename)[0];
- yield selectFile(projecteditor, resource);
- yield editFile(projecteditor, getTempFile(data.path).path, data.newContent);
- }
-
- info("Saving all resources");
- ok(projecteditor.hasUnsavedResources, "hasUnsavedResources");
- yield projecteditor.saveAllFiles();
- ok(!projecteditor.hasUnsavedResources, "!hasUnsavedResources");
- for (let data of helperEditData) {
- let filePath = getTempFile(data.path).path;
- info("Asserting that data at " + filePath + " has been saved");
- let resource = resources.filter(r=>r.basename === data.basename)[0];
- yield selectFile(projecteditor, resource);
- let editor = projecteditor.currentEditor;
- let savedData = yield getFileData(filePath);
- is(savedData, data.newContent, "Data has been correctly saved to disk");
- }
-});
-
-function* editFile(projecteditor, filePath, newData) {
- info("Testing file editing for: " + filePath);
-
- let initialData = yield getFileData(filePath);
- let editor = projecteditor.currentEditor;
- let resource = projecteditor.resourceFor(editor);
- let viewContainer = projecteditor.projectTree.getViewContainer(resource);
- let originalTreeLabel = viewContainer.label.textContent;
-
- is(resource.path, filePath, "Resource path is set correctly");
- is(editor.editor.getText(), initialData, "Editor is loaded with correct file contents");
-
- info("Setting text in the editor");
-
- editor.editor.setText(newData);
- is(editor.editor.getText(), newData, "Editor has been filled with new data");
- is(viewContainer.label.textContent, "*" + originalTreeLabel, "Label is marked as changed");
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_stores.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* 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";
-
-// Test ProjectEditor basic functionality
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- let TEMP_PATH = projecteditor.project.allPaths()[0];
- is(getTempFile("").path, TEMP_PATH, "Temp path is set correctly.");
-
- is(projecteditor.project.allPaths().length, 1, "1 path is set");
- projecteditor.project.removeAllStores();
- is(projecteditor.project.allPaths().length, 0, "No paths are remaining");
-});
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_tree_selection_01.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* 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";
-
-// Test tree selection functionality
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- let TEMP_PATH = projecteditor.project.allPaths()[0];
-
- is(getTempFile("").path, TEMP_PATH, "Temp path is set correctly.");
-
- ok(projecteditor.currentEditor, "There is an editor for projecteditor");
- let resources = projecteditor.project.allResources();
-
- is(
- resources.map(r=>r.basename).join("|"),
- TEMP_FOLDER_NAME + "|css|styles.css|data|img|icons|128x128.png|16x16.png|32x32.png|vector.svg|fake.png|js|script.js|index.html|LICENSE|README.md",
- "Resources came through in proper order"
- );
-
- for (let i = 0; i < resources.length; i++) {
- yield selectFileFirstLoad(projecteditor, resources[i]);
- }
- for (let i = 0; i < resources.length; i++) {
- yield selectFileSubsequentLoad(projecteditor, resources[i]);
- }
- for (let i = 0; i < resources.length; i++) {
- yield selectFileSubsequentLoad(projecteditor, resources[i]);
- }
-});
-
-function* selectFileFirstLoad(projecteditor, resource) {
- ok(resource && resource.path, "A valid resource has been passed in for selection " + (resource && resource.path));
- projecteditor.projectTree.selectResource(resource);
- let container = projecteditor.projectTree.getViewContainer(resource);
-
- if (resource.isRoot) {
- ok(container.expanded, "The root directory is expanded by default.");
- container.line.click();
- ok(container.expanded, "Clicking on the line does not toggles expansion.");
- return;
- }
- if (resource.isDir) {
- ok(!container.expanded, "A directory is not expanded by default.");
- container.line.click();
- ok(container.expanded, "Clicking on the line toggles expansion.");
- container.line.click();
- ok(!container.expanded, "Clicking on the line toggles expansion.");
- return;
- }
-
- let [editorCreated, editorLoaded, editorActivated] = yield promise.all([
- onceEditorCreated(projecteditor),
- onceEditorLoad(projecteditor),
- onceEditorActivated(projecteditor)
- ]);
-
- is(editorCreated, projecteditor.currentEditor, "Editor has been created for " + resource.path);
- is(editorActivated, projecteditor.currentEditor, "Editor has been activated for " + resource.path);
- is(editorLoaded, projecteditor.currentEditor, "Editor has been loaded for " + resource.path);
-}
-
-function* selectFileSubsequentLoad(projecteditor, resource) {
- ok(resource && resource.path, "A valid resource has been passed in for selection " + (resource && resource.path));
- projecteditor.projectTree.selectResource(resource);
-
- if (resource.isDir) {
- return;
- }
-
- // Make sure text editors are focused immediately when selected.
- let focusPromise = promise.resolve();
- if (projecteditor.currentEditor.editor) {
- focusPromise = onEditorFocus(projecteditor.currentEditor);
- }
-
- // Only activated should fire the next time
- // (may add load() if we begin checking for changes from disk)
- let [editorActivated] = yield promise.all([
- onceEditorActivated(projecteditor)
- ]);
-
- is(editorActivated, projecteditor.currentEditor, "Editor has been activated for " + resource.path);
-
- yield focusPromise;
-}
-
-function onEditorFocus(editor) {
- let def = promise.defer();
- editor.on("focus", function focus() {
- editor.off("focus", focus);
- def.resolve();
- });
- return def.promise;
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/browser_projecteditor_tree_selection_02.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 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";
-
-//
-// Whitelisting this test.
-// As part of bug 1077403, the leaking uncaught rejection should be fixed.
-//
-thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy");
-
-// Test that files get reselected in the tree when their editor
-// is focused. https://bugzilla.mozilla.org/show_bug.cgi?id=1011116.
-
-add_task(function* () {
- let projecteditor = yield addProjectEditorTabForTempDirectory();
- let TEMP_PATH = projecteditor.project.allPaths()[0];
-
- is(getTempFile("").path, TEMP_PATH, "Temp path is set correctly.");
-
- ok(projecteditor.currentEditor, "There is an editor for projecteditor");
- let resources = projecteditor.project.allResources();
-
- is(
- resources.map(r=>r.basename).join("|"),
- TEMP_FOLDER_NAME + "|css|styles.css|data|img|icons|128x128.png|16x16.png|32x32.png|vector.svg|fake.png|js|script.js|index.html|LICENSE|README.md",
- "Resources came through in proper order"
- );
-
- for (let i = 0; i < resources.length; i++) {
- yield selectAndRefocusFile(projecteditor, resources[i]);
- }
-});
-
-function* selectAndRefocusFile(projecteditor, resource) {
- ok(resource && resource.path, "A valid resource has been passed in for selection " + (resource && resource.path));
- projecteditor.projectTree.selectResource(resource);
-
- if (resource.isDir) {
- return;
- }
-
- let [editorCreated, editorLoaded, editorActivated] = yield promise.all([
- onceEditorCreated(projecteditor),
- onceEditorLoad(projecteditor),
- onceEditorActivated(projecteditor)
- ]);
-
- if (projecteditor.currentEditor.editor) {
- // This is a text editor. Go ahead and select a directory then refocus
- // the editor to make sure it is reselected in tree.
- let treeContainer = projecteditor.projectTree.getViewContainer(getDirectoryInStore(resource));
- treeContainer.line.click();
- EventUtils.synthesizeMouseAtCenter(treeContainer.elt, {}, treeContainer.elt.ownerDocument.defaultView);
- let waitForTreeSelect = onTreeSelection(projecteditor);
- projecteditor.currentEditor.focus();
- yield waitForTreeSelect;
-
- is(projecteditor.projectTree.getSelectedResource(), resource, "The resource gets reselected in the tree");
- }
-}
-
-// Return a directory to select in the tree.
-function getDirectoryInStore(resource) {
- return resource.store.root.childrenSorted.filter(r=>r.isDir)[0];
-}
-
-function onTreeSelection(projecteditor) {
- let def = promise.defer();
- projecteditor.projectTree.on("selection", function selection() {
- projecteditor.projectTree.off("focus", selection);
- def.resolve();
- });
- return def.promise;
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/head.js
+++ /dev/null
@@ -1,389 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var Cu = Components.utils;
-const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
-const {TargetFactory} = require("devtools/client/framework/target");
-const {console} = Cu.import("resource://gre/modules/Console.jsm", {});
-const promise = require("promise");
-const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
-const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
-const ProjectEditor = require("devtools/client/projecteditor/lib/projecteditor");
-const DevToolsUtils = require("devtools/shared/DevToolsUtils");
-const flags = require("devtools/shared/flags");
-
-const TEST_URL_ROOT = "http://mochi.test:8888/browser/devtools/client/projecteditor/test/";
-const SAMPLE_WEBAPP_URL = TEST_URL_ROOT + "/helper_homepage.html";
-var TEMP_PATH;
-var TEMP_FOLDER_NAME = "ProjectEditor" + (new Date().getTime());
-
-// All test are asynchronous
-waitForExplicitFinish();
-
-// Uncomment this pref to dump all devtools emitted events to the console.
-// Services.prefs.setBoolPref("devtools.dump.emit", true);
-
-// Set the testing flag and reset it when the test ends
-flags.testing = true;
-registerCleanupFunction(() => flags.testing = false);
-
-// Clear preferences that may be set during the course of tests.
-registerCleanupFunction(() => {
- // Services.prefs.clearUserPref("devtools.dump.emit");
- TEMP_PATH = null;
- TEMP_FOLDER_NAME = null;
-});
-
-// Auto close the toolbox and close the test tabs when the test ends
-registerCleanupFunction(() => {
- try {
- let target = TargetFactory.forTab(gBrowser.selectedTab);
- gDevTools.closeToolbox(target);
- } catch (ex) {
- dump(ex);
- }
- while (gBrowser.tabs.length > 1) {
- gBrowser.removeCurrentTab();
- }
-});
-
-/**
- * Add a new test tab in the browser and load the given url.
- * @param {String} url The url to be loaded in the new tab
- * @return a promise that resolves to the tab object when the url is loaded
- */
-function addTab(url) {
- info("Adding a new tab with URL: '" + url + "'");
- let def = promise.defer();
-
- let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, url);
- BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(function () {
- info("URL '" + url + "' loading complete");
- waitForFocus(() => {
- def.resolve(tab);
- }, content);
- });
-
- return def.promise;
-}
-
-/**
- * Some tests may need to import one or more of the test helper scripts.
- * A test helper script is simply a js file that contains common test code that
- * is either not common-enough to be in head.js, or that is located in a separate
- * directory.
- * The script will be loaded synchronously and in the test's scope.
- * @param {String} filePath The file path, relative to the current directory.
- * Examples:
- * - "helper_attributes_test_runner.js"
- * - "../../../commandline/test/helpers.js"
- */
-function loadHelperScript(filePath) {
- let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
- Services.scriptloader.loadSubScript(testDir + "/" + filePath, this);
-}
-
-function addProjectEditorTabForTempDirectory(opts = {}) {
- try {
- TEMP_PATH = buildTempDirectoryStructure();
- } catch (e) {
- // Bug 1037292 - The test servers sometimes are unable to
- // write to the temporary directory due to locked files
- // or access denied errors. Try again if this failed.
- info("Project Editor temp directory creation failed. Trying again.");
- TEMP_PATH = buildTempDirectoryStructure();
- }
- let customOpts = {
- name: "Test",
- iconUrl: "chrome://devtools/skin/images/tool-options.svg",
- projectOverviewURL: SAMPLE_WEBAPP_URL
- };
-
- info("Adding a project editor tab for editing at: " + TEMP_PATH);
- return addProjectEditorTab(opts).then((projecteditor) => {
- return projecteditor.setProjectToAppPath(TEMP_PATH, customOpts).then(() => {
- return projecteditor;
- });
- });
-}
-
-function addProjectEditorTab(opts = {}) {
- return addTab("chrome://mochitests/content/browser/devtools/client/projecteditor/test/projecteditor-test.xul").then(() => {
- let iframe = content.document.getElementById("projecteditor-iframe");
- if (opts.menubar !== false) {
- opts.menubar = content.document.querySelector("menubar");
- }
- let projecteditor = ProjectEditor.ProjectEditor(iframe, opts);
-
-
- ok(iframe, "Tab has placeholder iframe for projecteditor");
- ok(projecteditor, "ProjectEditor has been initialized");
-
- return projecteditor.loaded.then((projecteditor) => {
- return projecteditor;
- });
- });
-}
-
-/**
- * Build a temporary directory as a workspace for this loader
- * https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O
- */
-function buildTempDirectoryStructure() {
-
- let dirName = TEMP_FOLDER_NAME;
- info("Building a temporary directory at " + dirName);
-
- // First create (and remove) the temp dir to discard any changes
- let TEMP_DIR = FileUtils.getDir("TmpD", [dirName], true);
- TEMP_DIR.remove(true);
-
- // Now rebuild our fake project.
- TEMP_DIR = FileUtils.getDir("TmpD", [dirName], true);
-
- FileUtils.getDir("TmpD", [dirName, "css"], true);
- FileUtils.getDir("TmpD", [dirName, "data"], true);
- FileUtils.getDir("TmpD", [dirName, "img", "icons"], true);
- FileUtils.getDir("TmpD", [dirName, "js"], true);
-
- let htmlFile = FileUtils.getFile("TmpD", [dirName, "index.html"]);
- htmlFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- writeToFileSync(htmlFile, [
- "<!DOCTYPE html>",
- '<html lang="en">',
- " <head>",
- ' <meta charset="utf-8" />',
- " <title>ProjectEditor Temp File</title>",
- ' <link rel="stylesheet" href="style.css" />',
- " </head>",
- ' <body id="home">',
- " <p>ProjectEditor Temp File</p>",
- " </body>",
- "</html>"].join("\n")
- );
-
- let readmeFile = FileUtils.getFile("TmpD", [dirName, "README.md"]);
- readmeFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- writeToFileSync(readmeFile, [
- "## Readme"
- ].join("\n")
- );
-
- let licenseFile = FileUtils.getFile("TmpD", [dirName, "LICENSE"]);
- licenseFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- writeToFileSync(licenseFile, [
- "/* This Source Code Form is subject to the terms of the Mozilla Public",
- " * License, v. 2.0. If a copy of the MPL was not distributed with this",
- " * file, You can obtain one at http://mozilla.org/MPL/2.0/. */"
- ].join("\n")
- );
-
- let cssFile = FileUtils.getFile("TmpD", [dirName, "css", "styles.css"]);
- cssFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- writeToFileSync(cssFile, [
- "body {",
- " background: red;",
- "}"
- ].join("\n")
- );
-
- FileUtils.getFile("TmpD", [dirName, "js", "script.js"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
-
- FileUtils.getFile("TmpD", [dirName, "img", "fake.png"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- FileUtils.getFile("TmpD", [dirName, "img", "icons", "16x16.png"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- FileUtils.getFile("TmpD", [dirName, "img", "icons", "32x32.png"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- FileUtils.getFile("TmpD", [dirName, "img", "icons", "128x128.png"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
- FileUtils.getFile("TmpD", [dirName, "img", "icons", "vector.svg"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
-
- return TEMP_DIR.path;
-}
-
-// https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O#Writing_to_a_file
-function writeToFile(file, data) {
- if (typeof file === "string") {
- file = new FileUtils.File(file);
- }
- info("Writing to file: " + file.path + " (exists? " + file.exists() + ")");
- let defer = promise.defer();
- var ostream = FileUtils.openSafeFileOutputStream(file);
-
- var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
- createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
- converter.charset = "UTF-8";
- var istream = converter.convertToInputStream(data);
-
- // The last argument (the callback) is optional.
- NetUtil.asyncCopy(istream, ostream, function (status) {
- if (!Components.isSuccessCode(status)) {
- // Handle error!
- info("ERROR WRITING TEMP FILE", status);
- }
- defer.resolve();
- });
- return defer.promise;
-}
-
-// This is used when setting up the test.
-// You should typically use the async version of this, writeToFile.
-// https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O#More
-function writeToFileSync(file, data) {
- // file is nsIFile, data is a string
- var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
- createInstance(Components.interfaces.nsIFileOutputStream);
-
- // use 0x02 | 0x10 to open file for appending.
- foStream.init(file, 0x02 | 0x08 | 0x20, 0o666, 0);
- // write, create, truncate
- // In a c file operation, we have no need to set file mode with or operation,
- // directly using "r" or "w" usually.
-
- // if you are sure there will never ever be any non-ascii text in data you can
- // also call foStream.write(data, data.length) directly
- var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].
- createInstance(Components.interfaces.nsIConverterOutputStream);
- converter.init(foStream, "UTF-8", 0, 0);
- converter.writeString(data);
- converter.close(); // this closes foStream
-}
-
-function getTempFile(path) {
- let parts = [TEMP_FOLDER_NAME];
- parts = parts.concat(path.split("/"));
- return FileUtils.getFile("TmpD", parts);
-}
-
-// https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O#Writing_to_a_file
-function* getFileData(file) {
- if (typeof file === "string") {
- file = new FileUtils.File(file);
- }
- let def = promise.defer();
-
- NetUtil.asyncFetch({
- uri: NetUtil.newURI(file),
- loadUsingSystemPrincipal: true
- }, function (inputStream, status) {
- if (!Components.isSuccessCode(status)) {
- info("ERROR READING TEMP FILE", status);
- }
-
- // Detect if an empty file is loaded
- try {
- inputStream.available();
- } catch (e) {
- def.resolve("");
- return;
- }
-
- var data = NetUtil.readInputStreamToString(inputStream, inputStream.available());
- def.resolve(data);
- });
-
- return def.promise;
-}
-
-/**
- * Rename the resource of the provided container using the context menu.
- *
- * @param {ProjectEditor} projecteditor the current project editor instance
- * @param {Shell} container for the resource to rename
- * @param {String} newName the name to use for renaming the resource
- * @return {Promise} a promise that resolves when the resource has been renamed
- */
-var renameWithContextMenu = Task.async(function* (projecteditor,
- container, newName) {
- let popup = projecteditor.contextMenuPopup;
- let resource = container.resource;
- info("Going to attempt renaming for: " + resource.path);
-
- let waitForPopupShow = onPopupShow(popup);
- openContextMenu(container.label);
- yield waitForPopupShow;
-
- let renameCommand = popup.querySelector("[command=cmd-rename]");
- ok(renameCommand, "Rename command exists in popup");
- is(renameCommand.getAttribute("hidden"), "", "Rename command is visible");
- is(renameCommand.getAttribute("disabled"), "", "Rename command is enabled");
-
- renameCommand.click();
- popup.hidePopup();
- let input = container.elt.childNodes[0].childNodes[1];
- input.value = resource.basename + newName;
-
- let waitForProjectRefresh = onceProjectRefreshed(projecteditor);
- EventUtils.synthesizeKey("VK_RETURN", {}, projecteditor.window);
- yield waitForProjectRefresh;
-
- try {
- yield OS.File.stat(resource.path + newName);
- ok(true, "File is renamed");
- } catch (e) {
- ok(false, "Failed to rename file");
- }
-});
-
-function onceEditorCreated(projecteditor) {
- let def = promise.defer();
- projecteditor.once("onEditorCreated", (editor) => {
- def.resolve(editor);
- });
- return def.promise;
-}
-
-function onceEditorLoad(projecteditor) {
- let def = promise.defer();
- projecteditor.once("onEditorLoad", (editor) => {
- def.resolve(editor);
- });
- return def.promise;
-}
-
-function onceEditorActivated(projecteditor) {
- let def = promise.defer();
- projecteditor.once("onEditorActivated", (editor) => {
- def.resolve(editor);
- });
- return def.promise;
-}
-
-function onceEditorSave(projecteditor) {
- let def = promise.defer();
- projecteditor.once("onEditorSave", (editor, resource) => {
- def.resolve(resource);
- });
- return def.promise;
-}
-
-function onceProjectRefreshed(projecteditor) {
- return new Promise(resolve => {
- projecteditor.project.on("refresh-complete", function refreshComplete() {
- projecteditor.project.off("refresh-complete", refreshComplete);
- resolve();
- });
- });
-}
-
-function onPopupShow(menu) {
- let defer = promise.defer();
- menu.addEventListener("popupshown", function () {
- defer.resolve();
- }, {once: true});
- return defer.promise;
-}
-
-function onPopupHidden(menu) {
- let defer = promise.defer();
- menu.addEventListener("popuphidden", function () {
- defer.resolve();
- }, {once: true});
- return defer.promise;
-}
-
-function openContextMenu(node) {
- EventUtils.synthesizeMouseAtCenter(
- node,
- {button: 2, type: "contextmenu"},
- node.ownerDocument.defaultView
- );
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/helper_edits.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* 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";
-
-var helperEditData = [
- {
- basename: "styles.css",
- path: "css/styles.css",
- newContent: "body,html { color: orange; }"
- },
- {
- basename: "index.html",
- path: "index.html",
- newContent: "<h1>Changed Content Again</h1>"
- },
- {
- basename: "LICENSE",
- path: "LICENSE",
- newContent: "My new license"
- },
- {
- basename: "README.md",
- path: "README.md",
- newContent: "My awesome readme"
- },
- {
- basename: "script.js",
- path: "js/script.js",
- newContent: "alert('hi')"
- },
- {
- basename: "vector.svg",
- path: "img/icons/vector.svg",
- newContent: "<svg></svg>"
- },
-];
-
-function* selectFile(projecteditor, resource) {
- ok(resource && resource.path, "A valid resource has been passed in for selection " + (resource && resource.path));
- projecteditor.projectTree.selectResource(resource);
-
- if (resource.isDir) {
- return;
- }
-
- let [editorActivated] = yield promise.all([
- onceEditorActivated(projecteditor)
- ]);
-
- is(editorActivated, projecteditor.currentEditor, "Editor has been activated for " + resource.path);
-}
deleted file mode 100644
--- a/devtools/client/projecteditor/test/helper_homepage.html
+++ /dev/null
@@ -1,1 +0,0 @@
-<h1>ProjectEditor tests</h1>
\ No newline at end of file
deleted file mode 100644
--- a/devtools/client/projecteditor/test/projecteditor-test.xul
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
-<?xml-stylesheet href="chrome://global/skin/global.css"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:html="http://www.w3.org/1999/xhtml">
-
- <script type="application/javascript" src="chrome://global/content/globalOverlay.js"></script>
-
- <commandset id="mainCommandSet">
- <commandset id="editMenuCommands"/>
- </commandset>
- <menubar></menubar>
- <iframe id='projecteditor-iframe' flex="1"></iframe>
-</window>
deleted file mode 100644
--- a/devtools/client/themes/projecteditor/projecteditor.css
+++ /dev/null
@@ -1,184 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-.view-project-detail {
- overflow: auto;
-}
-
-.plugin-hidden {
- display: none;
-}
-
-.arrow {
- -moz-appearance: treetwisty;
- width: 20px;
- height: 20px;
-}
-
-.arrow[open] {
- -moz-appearance: treetwistyopen;
-}
-
-.arrow[invisible] {
- visibility: hidden;
-}
-
-#projecteditor-menubar {
- display: none;
-}
-
-#projecteditor-toolbar,
-#projecteditor-toolbar-bottom {
- display: none; /* For now don't show the status bars */
- min-height: 22px;
- height: 22px;
- background: rgb(237, 237, 237);
-}
-
-#sources {
- overflow: auto;
-}
-
-.sources-tree {
- overflow:auto;
- overflow-x: hidden;
- -moz-user-focus: normal;
-
- /* Allows this to expand inside of parent xul element, while
- still supporting child flexbox elements, including ellipses. */
- -moz-box-flex: 1;
- display: block;
-}
-
-.sources-tree input {
- margin: -1px;
- border: 1px solid gray;
-}
-
-#main-deck .sources-tree {
- background: rgb(225, 225, 225);
- min-width: 100px;
-}
-
-.entry {
- color: #18191A;
- display: flex;
- align-items: center;
-}
-
-.entry .file-label {
- display: flex;
- flex: 1;
- align-items: center;
-}
-
-.entry {
- border: none;
- box-shadow: none;
- white-space: nowrap;
- cursor: pointer;
-}
-
-.entry:hover:not(.entry-group-title):not(.selected) {
- background: rgba(0, 0, 0, .05);
-}
-
-.entry.selected {
- background: rgba(56, 117, 215, 1);
- color: #F5F7FA;
- outline: none;
-}
-
-.entry-group-title {
- background: rgba(56, 117, 215, 0.8);
- color: #F5F7FA;
- font-weight: bold;
- font-size: 1.05em;
- line-height: 35px;
- padding: 0 10px;
-}
-
-.sources-tree .entry-group-title .expander {
- display: none;
-}
-
-.entry .expander {
- width: 16px;
- padding: 0;
-}
-
-.tree-collapsed .children {
- display: none;
-}
-
-/* Plugins */
-
-#projecteditor-toolbar textbox {
- margin: 0;
-}
-
-.projecteditor-basic-display {
- padding: 0 3px;
-}
-
-/* App Manager */
-.project-name-label {
- font-weight: bold;
- padding-left: 10px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.project-flex {
- flex: 1;
-}
-
-.project-image {
- max-height: 25px;
- margin-left: -10px;
-}
-
-.project-image,
-.project-status,
-.project-options {
- flex-shrink: 0;
-}
-
-.project-status {
- width: 10px;
- height: 10px;
- border-radius: 50%;
- border: solid 1px rgba(255, 255, 255, .5);
- margin-right: 10px;
- visibility: hidden;
-}
-
-.project-status[status=valid] {
- background: #70bf53;
- visibility: visible;
-}
-
-.project-status[status=warning] {
- background: #d99b28;
- visibility: visible;
-}
-
-.project-status[status=error] {
- background: #ed2655;
- visibility: visible;
-}
-
-/* Status Bar */
-.projecteditor-file-label {
- font-weight: bold;
- padding-left: 29px;
- padding-right: 10px;
- flex: 1;
-}
-
-/* Image View */
-.editor-image {
- padding: 10px;
-}