summaryrefslogtreecommitdiffstats
path: root/devtools/client/projecteditor/lib/helpers
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /devtools/client/projecteditor/lib/helpers
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'devtools/client/projecteditor/lib/helpers')
-rw-r--r--devtools/client/projecteditor/lib/helpers/event.js86
-rw-r--r--devtools/client/projecteditor/lib/helpers/file-picker.js116
-rw-r--r--devtools/client/projecteditor/lib/helpers/l10n.js26
-rw-r--r--devtools/client/projecteditor/lib/helpers/moz.build12
-rw-r--r--devtools/client/projecteditor/lib/helpers/prompts.js33
-rw-r--r--devtools/client/projecteditor/lib/helpers/readdir.js89
6 files changed, 362 insertions, 0 deletions
diff --git a/devtools/client/projecteditor/lib/helpers/event.js b/devtools/client/projecteditor/lib/helpers/event.js
new file mode 100644
index 000000000..74b4adb04
--- /dev/null
+++ b/devtools/client/projecteditor/lib/helpers/event.js
@@ -0,0 +1,86 @@
+/* -*- 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);
+};
+
diff --git a/devtools/client/projecteditor/lib/helpers/file-picker.js b/devtools/client/projecteditor/lib/helpers/file-picker.js
new file mode 100644
index 000000000..1dab0f001
--- /dev/null
+++ b/devtools/client/projecteditor/lib/helpers/file-picker.js
@@ -0,0 +1,116 @@
+/* -*- 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;
diff --git a/devtools/client/projecteditor/lib/helpers/l10n.js b/devtools/client/projecteditor/lib/helpers/l10n.js
new file mode 100644
index 000000000..b2b315ff8
--- /dev/null
+++ b/devtools/client/projecteditor/lib/helpers/l10n.js
@@ -0,0 +1,26 @@
+/* -*- 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;
diff --git a/devtools/client/projecteditor/lib/helpers/moz.build b/devtools/client/projecteditor/lib/helpers/moz.build
new file mode 100644
index 000000000..c2e14fce6
--- /dev/null
+++ b/devtools/client/projecteditor/lib/helpers/moz.build
@@ -0,0 +1,12 @@
+# -*- 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',
+)
diff --git a/devtools/client/projecteditor/lib/helpers/prompts.js b/devtools/client/projecteditor/lib/helpers/prompts.js
new file mode 100644
index 000000000..0df6af304
--- /dev/null
+++ b/devtools/client/projecteditor/lib/helpers/prompts.js
@@ -0,0 +1,33 @@
+/* -*- 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;
+
diff --git a/devtools/client/projecteditor/lib/helpers/readdir.js b/devtools/client/projecteditor/lib/helpers/readdir.js
new file mode 100644
index 000000000..054730faf
--- /dev/null
+++ b/devtools/client/projecteditor/lib/helpers/readdir.js
@@ -0,0 +1,89 @@
+/* -*- 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);
+ }
+};
+
+