const Cu = Components.utils; const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {}); const require = devtools.require; const promise = require("projecteditor/helpers/promise"); const ProjectEditor = require("projecteditor/projecteditor"); const SAMPLE_PATH = buildTempDirectoryStructure(); const SAMPLE_NAME = "DevTools Content Application Name"; const SAMPLE_PROJECT_URL = "data:text/html;charset=utf-8,

Project Overview

"; const SAMPLE_ICON = "chrome://global/skin/devtools/tool-debugger.svg"; /** * Create a workspace for working on projecteditor, available at * chrome://global/content/devtools/projecteditor-loader.xul. * This emulates the integration points that the app manager uses. */ let appManagerEditor; // Log a message to the project overview URL to make development easier function log(msg) { if (!appManagerEditor) { return; } let doc = appManagerEditor.iframe.contentDocument; let el = doc.createElement("p"); el.textContent = msg; doc.body.appendChild(el); } document.addEventListener("DOMContentLoaded", function onDOMReady(e) { document.removeEventListener("DOMContentLoaded", onDOMReady, false); let iframe = document.getElementById("projecteditor-iframe"); window.projecteditor = ProjectEditor.ProjectEditor(iframe); projecteditor.on("onEditorCreated", (editor, a) => { log("editor created: " + editor); if (editor.label === "app-manager") { appManagerEditor = editor; appManagerEditor.on("load", function foo() { appManagerEditor.off("load", foo); log("Working on: " + SAMPLE_PATH); }) } }); projecteditor.on("onEditorDestroyed", (editor) => { log("editor destroyed: " + editor); }); projecteditor.on("onEditorSave", (editor, resource) => { log("editor saved: " + editor, resource.path); }); projecteditor.on("onTreeSelected", (resource) => { log("tree selected: " + resource.path); }); projecteditor.on("onEditorLoad", (editor) => { log("editor loaded: " + editor); }); projecteditor.on("onEditorActivated", (editor) => { log("editor focused: " + editor); }); projecteditor.on("onEditorDeactivated", (editor) => { log("editor blur: " + editor); }); projecteditor.on("onEditorChange", (editor) => { log("editor changed: " + editor); }); projecteditor.on("onCommand", (cmd) => { log("Command: " + cmd); }); projecteditor.loaded.then(() => { projecteditor.setProjectToAppPath(SAMPLE_PATH, { name: SAMPLE_NAME, iconUrl: SAMPLE_ICON, projectOverviewURL: SAMPLE_PROJECT_URL, validationStatus: "valid" }).then(() => { let allResources = projecteditor.project.allResources(); console.log("All resources have been loaded", allResources, allResources.map(r=>r.basename).join("|")); }); }); }, false); /** * 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() { // First create (and remove) the temp dir to discard any changes let TEMP_DIR = FileUtils.getDir("TmpD", ["ProjectEditor"], true); TEMP_DIR.remove(true); // Now rebuild our fake project. TEMP_DIR = FileUtils.getDir("TmpD", ["ProjectEditor"], true); FileUtils.getDir("TmpD", ["ProjectEditor", "css"], true); FileUtils.getDir("TmpD", ["ProjectEditor", "data"], true); FileUtils.getDir("TmpD", ["ProjectEditor", "img", "icons"], true); FileUtils.getDir("TmpD", ["ProjectEditor", "js"], true); let htmlFile = FileUtils.getFile("TmpD", ["ProjectEditor", "index.html"]); htmlFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); writeToFile(htmlFile, [ '', '', ' ', ' ', ' ProjectEditor Temp File', ' ', ' ', ' ', '

ProjectEditor Temp File

', ' ', ''].join("\n") ); let readmeFile = FileUtils.getFile("TmpD", ["ProjectEditor", "README.md"]); readmeFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); writeToFile(readmeFile, [ '## Readme' ].join("\n") ); let licenseFile = FileUtils.getFile("TmpD", ["ProjectEditor", "LICENSE"]); licenseFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); writeToFile(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", ["ProjectEditor", "css", "styles.css"]); cssFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); writeToFile(cssFile, [ 'body {', ' background: red;', '}' ].join("\n") ); FileUtils.getFile("TmpD", ["ProjectEditor", "js", "script.js"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); FileUtils.getFile("TmpD", ["ProjectEditor", "img", "fake.png"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); FileUtils.getFile("TmpD", ["ProjectEditor", "img", "icons", "16x16.png"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); FileUtils.getFile("TmpD", ["ProjectEditor", "img", "icons", "32x32.png"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); FileUtils.getFile("TmpD", ["ProjectEditor", "img", "icons", "128x128.png"]).createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); FileUtils.getFile("TmpD", ["ProjectEditor", "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) { 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! console.log("ERROR WRITING TEMP FILE", status); } }); }