From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- devtools/client/projecteditor/lib/helpers/event.js | 86 +++++++++++++++ .../projecteditor/lib/helpers/file-picker.js | 116 +++++++++++++++++++++ devtools/client/projecteditor/lib/helpers/l10n.js | 26 +++++ .../client/projecteditor/lib/helpers/moz.build | 12 +++ .../client/projecteditor/lib/helpers/prompts.js | 33 ++++++ .../client/projecteditor/lib/helpers/readdir.js | 89 ++++++++++++++++ 6 files changed, 362 insertions(+) create mode 100644 devtools/client/projecteditor/lib/helpers/event.js create mode 100644 devtools/client/projecteditor/lib/helpers/file-picker.js create mode 100644 devtools/client/projecteditor/lib/helpers/l10n.js create mode 100644 devtools/client/projecteditor/lib/helpers/moz.build create mode 100644 devtools/client/projecteditor/lib/helpers/prompts.js create mode 100644 devtools/client/projecteditor/lib/helpers/readdir.js (limited to 'devtools/client/projecteditor/lib/helpers') 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); + } +}; + + -- cgit v1.2.3