define(function(require, exports, module) { var gcli = require('gcli/index'); var l10n = require('gcli/l10n'); /** * 'intro' command */ var introCmdSpec = { name: 'intro', description: l10n.lookup('introDesc'), manual: l10n.lookup('introManual'), returnType: 'html', exec: function echo(args, context) { return context.createView({ html: require('text!gcli/ui/intro.html') }); } }; /** * Registration and de-registration. */ exports.startup = function() { gcli.addCommand(introCmdSpec); }; exports.shutdown = function() { gcli.removeCommand(introCmdSpec); }; });
NodeType.prototype.parse = function(arg) { if (arg.text === '') { return new Conversion(undefined, arg, Status.INCOMPLETE); } var nodes; try { nodes = doc.querySelectorAll(arg.text); } catch (ex) { return new Conversion(undefined, arg, Status.ERROR, l10n.lookup('nodeParseSyntax')); } if (nodes.length === 0) { return new Conversion(undefined, arg, Status.INCOMPLETE, l10n.lookup('nodeParseNone')); } if (nodes.length === 1) { var node = nodes.item(0); node.__gcliQuery = arg.text; host.flashNodes(node, true); return new Conversion(node, arg, Status.VALID, ''); } host.flashNodes(nodes, false); return new Conversion(undefined, arg, Status.ERROR, l10n.lookupFormat('nodeParseMultiple', [ nodes.length ])); };
getTypeDescription: function(param) { var input = ''; if (param.defaultValue === undefined) { input = l10n.lookup('helpManRequired'); } else if (param.defaultValue === null) { input = l10n.lookup('helpManOptional'); } else { input = param.defaultValue; } return '(' + param.type.name + ', ' + input + ')'; }
exec: function(args, context) { var listener = debuggerServer.createListener(); if (!listener) { throw new Error(l10n.lookup("listenDisabledOutput")); } listener.portOrPath = args.port; listener.open(); if (debuggerServer.initialized) { return l10n.lookupFormat("listenInitOutput", [ "" + args.port ]); } return l10n.lookup("listenNoInitOutput"); },
function showFolder(path) { let NSLocalFile = CC("@mozilla.org/file/local;1", "nsIFile", "initWithPath"); try { let file = new NSLocalFile(path); if (file.exists()) { file.reveal(); return l10n.lookupFormat("folderOpenDirResult", [path]); } return l10n.lookup("folderInvalidPath"); } catch (e) { return l10n.lookup("folderInvalidPath"); } }
/** * Adds add/delete buttons to a normal field allowing there to be many values * given for a parameter. */ function ArrayField(type, options) { this.document = options.document; this.type = type; this.options = options; this.requ = options.requisition; this._onAdd = this._onAdd.bind(this); this.members = []; // <div class=gcliArrayParent save="${element}"> this.element = dom.createElement(this.document, 'div'); this.element.className = 'gcliArrayParent'; // <button class=gcliArrayMbrAdd onclick="${_onAdd}" save="${addButton}">Add this.addButton = dom.createElement(this.document, 'button'); this.addButton.className = 'gcliArrayMbrAdd'; this.addButton.addEventListener('click', this._onAdd, false); this.addButton.innerHTML = l10n.lookup('fieldArrayAdd'); this.element.appendChild(this.addButton); // <div class=gcliArrayMbrs save="${mbrElement}"> this.container = dom.createElement(this.document, 'div'); this.container.className = 'gcliArrayMbrs'; this.element.appendChild(this.container); this.onInputChange = this.onInputChange.bind(this); this.fieldChanged = createEvent('ArrayField.fieldChanged'); }
exec: function(result, context) { let propertyName = result.property; let document = context.document; let root = document.createElement("div"); if (result.error) { // The css property specified doesn't exist. root.appendChild(document.createTextNode( l10n.lookupFormat("mdnCssPropertyNotFound", [ propertyName ]) + " (" + result.error + ")")); } else { let title = document.createElement("h2"); title.textContent = propertyName; root.appendChild(title); let link = document.createElement("p"); link.classList.add("gcli-mdn-url"); link.textContent = l10n.lookup("mdnCssVisitPage"); root.appendChild(link); link.addEventListener("click", () => { let gBrowser = context.environment.chromeWindow.gBrowser; gBrowser.selectedTab = gBrowser.addTab(result.url); }); let summary = document.createElement("p"); summary.textContent = result.data.summary; root.appendChild(summary); } return root; }
exec: function Restart(args, context) { let canceled = Cc["@mozilla.org/supports-PRBool;1"] .createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(canceled, "quit-application-requested", "restart"); if (canceled.data) { return l10n.lookup("restartBrowserRequestCancelled"); } // disable loading content from cache. if (args.nocache) { Services.appinfo.invalidateCachesOnRestart(); } const appStartup = Cc["@mozilla.org/toolkit/app-startup;1"] .getService(Ci.nsIAppStartup); if (args.safemode) { // restart in safemode appStartup.restartInSafeMode(Ci.nsIAppStartup.eAttemptQuit); } else { // restart normally appStartup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); } return l10n.lookupFormat("restartBrowserRestarting", [ BRAND_SHORT_NAME ]); }
exec: function(cookies, context) { if (cookies.length == 0) { let host = new URL(context.environment.target.url).host; host = sanitizeHost(host); let msg = l10n.lookupFormat("cookieListOutNoneHost", [ host ]); return context.createView({ html: "<span>" + msg + "</span>" }); } for (let cookie of cookies) { cookie.expires = translateExpires(cookie.expires); let noAttrs = !cookie.secure && !cookie.httpOnly && !cookie.sameDomain; cookie.attrs = (cookie.secure ? "secure" : " ") + (cookie.httpOnly ? "httpOnly" : " ") + (cookie.sameDomain ? "sameDomain" : " ") + (noAttrs ? l10n.lookup("cookieListOutNone") : " "); } return context.createView({ html: "<ul class='gcli-cookielist-list'>" + " <li foreach='cookie in ${cookies}'>" + " <div>${cookie.name}=${cookie.value}</div>" + " <table class='gcli-cookielist-detail'>" + " <tr>" + " <td>" + l10n.lookup("cookieListOutHost") + "</td>" + " <td>${cookie.host}</td>" + " </tr>" + " <tr>" + " <td>" + l10n.lookup("cookieListOutPath") + "</td>" + " <td>${cookie.path}</td>" + " </tr>" + " <tr>" + " <td>" + l10n.lookup("cookieListOutExpires") + "</td>" + " <td>${cookie.expires}</td>" + " </tr>" + " <tr>" + " <td>" + l10n.lookup("cookieListOutAttributes") + "</td>" + " <td>${cookie.attrs}</td>" + " </tr>" + " <tr><td colspan='2'>" + " <span class='gcli-out-shortcut' onclick='${onclick}'" + " data-command='cookie set ${cookie.name} '" + " >" + l10n.lookup("cookieListOutEdit") + "</span>" + " <span class='gcli-out-shortcut'" + " onclick='${onclick}' ondblclick='${ondblclick}'" + " data-command='cookie remove ${cookie.name}'" + " >" + l10n.lookup("cookieListOutRemove") + "</span>" + " </td></tr>" + " </table>" + " </li>" + "</ul>", data: { options: { allowEval: true }, cookies: cookies, onclick: context.update, ondblclick: context.updateExec } }); }
/** * The cookie 'expires' value needs converting into something more readable. * * And the unit of expires is sec, the unit that in argument of Date() needs * millisecond. */ function translateExpires(expires) { if (expires == 0) { return l10n.lookup("cookieListOutSession"); } let expires_msec = expires * 1000; return (new Date(expires_msec)).toLocaleString(); }
/** * Save the image data to the clipboard. This returns a promise, so it can * be treated exactly like imgur / file processing, but it's really sync * for now. */ function saveToClipboard(context, reply) { try { const channel = NetUtil.newChannel({ uri: reply.data, loadUsingSystemPrincipal: true, contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE }); const input = channel.open2(); const loadContext = context.environment.chromeWindow .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsILoadContext); const imgTools = Cc["@mozilla.org/image/tools;1"] .getService(Ci.imgITools); const container = {}; imgTools.decodeImageData(input, channel.contentType, container); const wrapped = Cc["@mozilla.org/supports-interface-pointer;1"] .createInstance(Ci.nsISupportsInterfacePointer); wrapped.data = container.value; const trans = Cc["@mozilla.org/widget/transferable;1"] .createInstance(Ci.nsITransferable); trans.init(loadContext); trans.addDataFlavor(channel.contentType); trans.setTransferData(channel.contentType, wrapped, -1); const clip = Cc["@mozilla.org/widget/clipboard;1"] .getService(Ci.nsIClipboard); clip.setData(trans, null, Ci.nsIClipboard.kGlobalClipboard); reply.destinations.push(l10n.lookup("screenshotCopied")); } catch (ex) { console.error(ex); reply.destinations.push(l10n.lookup("screenshotErrorCopying")); } return Promise.resolve(); }
define(function(require, exports, module) { var settings = require('gcli/settings'); var l10n = require('gcli/l10n'); var view = require('gcli/ui/view'); var Output = require('gcli/cli').Output; /** * Record if the user has clicked on 'Got It!' */ var hideIntroSettingSpec = { name: 'hideIntro', type: 'boolean', description: l10n.lookup('hideIntroDesc'), defaultValue: false }; var hideIntro; /** * Register (and unregister) the hide-intro setting */ exports.startup = function() { hideIntro = settings.addSetting(hideIntroSettingSpec); }; exports.shutdown = function() { settings.removeSetting(hideIntroSettingSpec); hideIntro = undefined; }; /** * Called when the UI is ready to add a welcome message to the output */ exports.maybeShowIntro = function(commandOutputManager) { if (hideIntro.value) { return; } var output = new Output(); commandOutputManager.onOutput({ output: output }); var viewData = view.createView({ html: require('text!gcli/ui/intro.html'), data: { showHideButton: true, onGotIt: function(ev) { hideIntro.value = true; output.onClose(); } } }); output.complete(viewData); }; });
exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { return l10n.lookup("debuggerStopped"); } let controller = dbg._controller; let thread = controller.activeThread; if (thread.paused) { thread.stepOut(); } }
xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { reply.href = xhr.response.data.link; reply.destinations.push(l10n.lookupFormat("screenshotImgurUploaded", [ reply.href ])); } else { reply.destinations.push(l10n.lookup("screenshotImgurError")); } resolve(); } };
NodeListType.prototype.parse = function(arg) { if (arg.text === '') { return new Conversion(undefined, arg, Status.INCOMPLETE); } var nodes; try { nodes = doc.querySelectorAll(arg.text); } catch (ex) { return new Conversion(undefined, arg, Status.ERROR, l10n.lookup('nodeParseSyntax')); } if (nodes.length === 0 && !this.allowEmpty) { return new Conversion(undefined, arg, Status.INCOMPLETE, l10n.lookup('nodeParseNone')); } host.flashNodes(nodes, false); return new Conversion(nodes, arg, Status.VALID, ''); };
exec: function(args, context) { let numDebuggers = debuggers.length; if (numDebuggers == 0) { return l10n.lookup("calllogStopNoLogging"); } for (let dbg of debuggers) { dbg.onEnterFrame = undefined; } debuggers = []; return l10n.lookupFormat("calllogStopReply", [ numDebuggers ]); }
exec: function(entries, context) { return context.createView({ html: "" + "<ul class='gcli-appcache-list'>" + " <li foreach='entry in ${entries}'>" + " <table class='gcli-appcache-detail'>" + " <tr>" + " <td>" + l10n.lookup("appCacheListKey") + "</td>" + " <td>${entry.key}</td>" + " </tr>" + " <tr>" + " <td>" + l10n.lookup("appCacheListFetchCount") + "</td>" + " <td>${entry.fetchCount}</td>" + " </tr>" + " <tr>" + " <td>" + l10n.lookup("appCacheListLastFetched") + "</td>" + " <td>${entry.lastFetched}</td>" + " </tr>" + " <tr>" + " <td>" + l10n.lookup("appCacheListLastModified") + "</td>" + " <td>${entry.lastModified}</td>" + " </tr>" + " <tr>" + " <td>" + l10n.lookup("appCacheListExpirationTime") + "</td>" + " <td>${entry.expirationTime}</td>" + " </tr>" + " <tr>" + " <td>" + l10n.lookup("appCacheListDataSize") + "</td>" + " <td>${entry.dataSize}</td>" + " </tr>" + " <tr>" + " <td>" + l10n.lookup("appCacheListDeviceID") + "</td>" + " <td>${entry.deviceID} <span class='gcli-out-shortcut' " + "onclick='${onclick}' ondblclick='${ondblclick}' " + "data-command='appcache viewentry ${entry.key}'" + ">" + l10n.lookup("appCacheListViewEntry") + "</span>" + " </td>" + " </tr>" + " </table>" + " </li>" + "</ul>", data: { entries: entries, onclick: context.update, ondblclick: context.updateExec } }); }
exec: function (args, context) { let listener = debuggerServer.createListener(); if (!listener) { throw new Error(l10n.lookup("listenDisabledOutput")); } let webSocket = false; if (args.protocol === "websocket") { webSocket = true; } else if (args.protocol === "mozilla-rdp") { webSocket = false; } listener.portOrPath = args.port; listener.webSocket = webSocket; listener.open(); if (debuggerServer.initialized) { return l10n.lookupFormat("listenInitOutput", [ "" + args.port ]); } return l10n.lookup("listenNoInitOutput"); },
NodeType.prototype.parse = function(arg) { if (arg.text === '') { return new Conversion(null, arg, Status.INCOMPLETE, l10n.lookup('nodeParseNone')); } var nodes; try { nodes = doc.querySelectorAll(arg.text); } catch (ex) { return new Conversion(null, arg, Status.ERROR, l10n.lookup('nodeParseSyntax')); } if (nodes.length === 0) { return new Conversion(null, arg, Status.INCOMPLETE, l10n.lookup('nodeParseNone')); } if (nodes.length === 1) { var node = nodes.item(0); node.__gcliQuery = arg.text; host.flashNode(node, 'green'); return new Conversion(node, arg, Status.VALID, ''); } Array.prototype.forEach.call(nodes, function(n) { host.flashNode(n, 'red'); }); return new Conversion(null, arg, Status.ERROR, l10n.lookupFormat('nodeParseMultiple', [ nodes.length ])); };
/** * Implement the localization algorithm for any documentation objects (i.e. * description and manual) in a command. * @param data The data assigned to a description or manual property * @param onUndefined If data == null, should we return the data untouched or * lookup a 'we don't know' key in it's place. */ function lookup(data, onUndefined) { if (data == null) { if (onUndefined) { return l10n.lookup(onUndefined); } return data; } if (typeof data === 'string') { return data; } if (typeof data === 'object') { if (data.key) { return l10n.lookup(data.key); } var locales = l10n.getPreferredLocales(); var translated; locales.some(function(locale) { translated = data[locale]; return translated != null; }); if (translated != null) { return translated; } console.error('Can\'t find locale in descriptions: ' + 'locales=' + JSON.stringify(locales) + ', ' + 'description=' + JSON.stringify(data)); return '(No description)'; } return l10n.lookup(onUndefined); }
/** * Create a block of data suitable to be passed to the help_list.html template */ function getListTemplateData(args, context) { var matchingCommands = canon.getCommands().filter(function(command) { if (command.hidden) { return false; } if (args.search && command.name.indexOf(args.search) !== 0) { // Filtered out because they don't match the search return false; } if (!args.search && command.name.indexOf(' ') != -1) { // We don't show sub commands with plain 'help' return false; } return true; }); matchingCommands.sort(function(c1, c2) { return c1.name.localeCompare(c2.name); }); var heading; if (matchingCommands.length === 0) { heading = l10n.lookupFormat('helpListNone', [ args.search ]); } else if (args.search == null) { heading = l10n.lookup('helpListAll'); } else { heading = l10n.lookupFormat('helpListPrefix', [ args.search ]); } return { l10n: l10n.propertyLookup, includeIntro: args.search == null, matchingCommands: matchingCommands, heading: heading, onclick: function(ev) { util.updateCommand(ev.currentTarget, context); }, ondblclick: function(ev) { util.executeCommand(ev.currentTarget, context); }, }; }
exec: function(args, context) { let contentWindow = context.environment.window; let dbg = new Debugger(contentWindow); dbg.onEnterFrame = function(frame) { // BUG 773652 - Make the output from the GCLI calllog command nicer contentWindow.console.log("Method call: " + this.callDescription(frame)); }.bind(this); debuggers.push(dbg); let gBrowser = context.environment.chromeDocument.defaultView.gBrowser; let target = TargetFactory.forTab(gBrowser.selectedTab); gDevTools.showToolbox(target, "webconsole"); return l10n.lookup("calllogStartReply"); },
exec: function(breakpoints, context) { let dbg = getPanel(context, "jsdebugger"); if (dbg && breakpoints.length) { return context.createView({ html: breakListHtml, data: { breakpoints: breakpoints, onclick: context.update, ondblclick: context.updateExec } }); } else { return context.createView({ html: "<p>${message}</p>", data: { message: l10n.lookup("breaklistNone") } }); } }
exec: function(args, context) { let numDebuggers = chromeDebuggers.length; if (numDebuggers == 0) { return l10n.lookup("calllogChromeStopNoLogging"); } for (let dbg of chromeDebuggers) { dbg.onEnterFrame = undefined; dbg.enabled = false; } for (let sandbox of sandboxes) { Cu.nukeSandbox(sandbox); } chromeDebuggers = []; sandboxes = []; return l10n.lookupFormat("calllogChromeStopReply", [ numDebuggers ]); }
var predictions = matches.map(function(match) { var description; var incomplete = true; if (this._isSafeProperty(scope, match.prop)) { description = '(property getter)'; } else { try { var value = scope[match.prop]; if (typeof value === 'function') { description = '(function)'; } else if (typeof value === 'boolean' || typeof value === 'number') { description = '= ' + value; incomplete = false; } else if (typeof value === 'string') { if (value.length > 40) { value = value.substring(0, 37) + '…'; } description = '= \'' + value + '\''; incomplete = false; } else { description = '(' + typeof value + ')'; } } catch (ex) { description = '(' + l10n.lookup('jstypeParseError') + ')'; } } return { name: prefix + match.prop, value: { name: prefix + match.prop, description: description }, description: description, incomplete: incomplete }; }, this);
exec: function(args, context) { let opts = { indent_size: args.indentSize, indent_char: args.indentChar, preserve_newlines: !args.doNotPreserveNewlines, max_preserve_newlines: args.preserveMaxNewlines == -1 ? undefined : args.preserveMaxNewlines, jslint_happy: args.jslintHappy, brace_style: args.braceStyle, space_before_conditional: !args.noSpaceBeforeConditional, unescape_strings: args.unescapeStrings }; let xhr = new XMLHttpRequest(); try { xhr.open("GET", args.url, true); } catch(e) { return l10n.lookup("jsbInvalidURL"); } let deferred = context.defer(); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200 || xhr.status == 0) { let browserDoc = context.environment.chromeDocument; let browserWindow = browserDoc.defaultView; let gBrowser = browserWindow.gBrowser; let result = beautify.js(xhr.responseText, opts); browserWindow.Scratchpad.ScratchpadManager.openScratchpad({text: result}); deferred.resolve(); } else { deferred.reject("Unable to load page to beautify: " + args.url + " " + xhr.status + " " + xhr.statusText); } }; } xhr.send(null); return deferred.promise; }
ArrayField.prototype._onAdd = function(ev, subConversion) { // <div class=gcliArrayMbr save="${element}"> var element = dom.createElement(this.document, 'div'); element.className = 'gcliArrayMbr'; this.container.appendChild(element); // ${field.element} var field = getField(this.type.subtype, this.options); field.fieldChanged.add(function() { var conversion = this.getConversion(); this.fieldChanged({ conversion: conversion }); this.setMessage(conversion.message); }, this); if (subConversion) { field.setConversion(subConversion); } element.appendChild(field.element); // <div class=gcliArrayMbrDel onclick="${_onDel}"> var delButton = dom.createElement(this.document, 'button'); delButton.className = 'gcliArrayMbrDel'; delButton.addEventListener('click', this._onDel, false); delButton.innerHTML = l10n.lookup('fieldArrayDel'); element.appendChild(delButton); var member = { element: element, field: field, parent: this }; member.onDelete = function() { this.parent.container.removeChild(this.element); this.parent.members = this.parent.members.filter(function(test) { return test !== this; }); this.parent.onInputChange(); }.bind(member); delButton.addEventListener('click', member.onDelete, false); this.members.push(member); };
exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { return l10n.lookup("debuggerClosed"); } let sources = getAllSources(dbg); let doc = context.environment.chromeDocument; let div = createXHTMLElement(doc, "div"); let ol = createXHTMLElement(doc, "ol"); sources.forEach(source => { let li = createXHTMLElement(doc, "li"); li.textContent = source.name; ol.appendChild(li); }); div.appendChild(ol); return div; }
exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { return l10n.lookup("debuggerStopped"); } let deferred = context.defer(); let item = dbg._view.Sources.getItemForAttachment(a => { return a.source && a.source.actor === args.file; }) let position = { actor: item.value, line: args.line }; dbg.addBreakpoint(position).then(() => { deferred.resolve(l10n.lookup("breakaddAdded")); }, aError => { deferred.resolve(l10n.lookupFormat("breakaddFailed", [aError])); }); return deferred.promise; }
exec: function(args, context) { if (args.chrome && args.selector) { // Node screenshot with chrome option does not work as intended // Refer https://bugzilla.mozilla.org/show_bug.cgi?id=659268#c7 // throwing for now. throw new Error(l10n.lookup("screenshotSelectorChromeConflict")); } let capture; if (!args.chrome) { // Re-execute the command on the server const command = context.typed.replace(/^screenshot/, "screenshot_server"); capture = context.updateExec(command).then(output => { return output.error ? Promise.reject(output.data) : output.data; }); } else { capture = captureScreenshot(args, context.environment.chromeDocument); } return capture.then(saveScreenshot.bind(null, args, context)); },