From 53598108bcecd3138b18cdf3888194a66bc7f625 Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Tue, 23 Apr 2013 14:28:15 +0200 Subject: [PATCH] Simple querySelectorAll command-770156 Simple querySelectorAll (`qsa`) command added to gcli. The command takes a string parameter which will be run as a css selector. Matching nodes will be displayed. Nodes can then be clicked. When clicked, a unique CSS selector will be calculated for the given node and `qsa` will be run again with that selector. The command simply uses document.querySelectorAll in its exec method. The view is done via a converter. Signed-off-by: Patrick Brosset --- lib/demo/index.js | 1 + lib/gcli/commands/qsa.css | 23 ++++++++ lib/gcli/commands/qsa.html | 13 +++++ lib/gcli/commands/qsa.js | 105 +++++++++++++++++++++++++++++++++++++ lib/gcli/nls/strings.js | 20 ++++++- 5 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 lib/gcli/commands/qsa.css create mode 100644 lib/gcli/commands/qsa.html create mode 100644 lib/gcli/commands/qsa.js diff --git a/lib/demo/index.js b/lib/demo/index.js index f5d39d92..e08fdc26 100644 --- a/lib/demo/index.js +++ b/lib/demo/index.js @@ -26,6 +26,7 @@ require('gcli/commands/help').startup(); require('gcli/commands/intro').startup(); require('gcli/commands/pref').startup(); require('gcli/commands/pref_list').startup(); +require('gcli/commands/qsa').startup(); require('demo/commands/basic').startup(); require('demo/commands/bugs').startup(); diff --git a/lib/gcli/commands/qsa.css b/lib/gcli/commands/qsa.css new file mode 100644 index 00000000..26905d7a --- /dev/null +++ b/lib/gcli/commands/qsa.css @@ -0,0 +1,23 @@ +.qsa-node-list, .qsa-node-attr-list, .qsa-node-attr-list .qsa-node-attr { + margin: 0; + padding: 0; + display: inline; +} +.qsa-node-list { + color: #999; +} +.qsa-node-list .qsa-node { + display: inline-block; + background: #F2F2F2; + border: 1px solid #D6D6D6; + border-radius: .2em; + margin: .2em; + padding: .5em; + cursor: pointer; +} +.qsa-node-attr-name { + color: #7ED3E8; +} +.qsa-node-attr-value { + color: #F20505; +} diff --git a/lib/gcli/commands/qsa.html b/lib/gcli/commands/qsa.html new file mode 100644 index 00000000..0e14082a --- /dev/null +++ b/lib/gcli/commands/qsa.html @@ -0,0 +1,13 @@ +
+

${l10n.lookupFormat('qsaResultIntroText', [nodes.length, selector])}${l10n.lookup('qsaResultsTooMany')}

+
    +
  1. + <${node.tagName.toLowerCase()} +
      +
    • + ${attr.name}="${attr.value}" +
    • +
    /> +
  2. +
+
diff --git a/lib/gcli/commands/qsa.js b/lib/gcli/commands/qsa.js new file mode 100644 index 00000000..ee8eb351 --- /dev/null +++ b/lib/gcli/commands/qsa.js @@ -0,0 +1,105 @@ +define(function(require, exports, module) { + +'use strict'; + +var util = require('util/util'); +var l10n = require('util/l10n'); +var gcli = require('gcli/index'); + +var qsaViewHtml = require('text!gcli/commands/qsa.html'); +var qsaViewCss = require('text!gcli/commands/qsa.css'); + +/** + * Transform a nodeList into an array. + * Useful for forEach'ing for example. + * @param nodeList The nodeList as returned by querySelectorAll + * @return The transformed array + */ +function nodesToArray(nodeList) { + return Array.prototype.slice.call(nodeList); +} + +/** + * QuerySelectorAll (qsa) command spec + */ +var qsaCmdSpec = { + name: 'qsa', + description: l10n.lookup('qsaDesc'), + manual: l10n.lookup('qsaManual'), + params: [{ + name: 'query', + type: 'string', + defaultValue: '*', + description: l10n.lookup('qsaQueryDesc'), + }], + returnType: 'qsaCmdOutput', + exec: function(args, context) { + var out = { + nodes: [], + selector: args.query + }; + + // An invalid selector may lead to a SyntaxError exception e.g. '3' or '' + try { + out.nodes = nodesToArray(context.document.querySelectorAll(args.query)); + } catch(e) {} + + // Converting the nodes and attributes to plain objects to allow JSONing + out.nodes.forEach(function(node, index, nodeList) { + var attributes = nodesToArray(node.attributes); + attributes.forEach(function(attr, index, attrList) { + attrList[index] = { + name: attr.name, + value: attr.value + }; + }); + + nodeList[index] = { + tagName: node.tagName, + attributes: attributes, + selector: util.findCssSelector(node) + }; + }); + + return out; + } +}; + +/** + * QuerySelectorAll (qsa) command output converter + * qsaCmdOutput -> View + */ +var qsaConverterSpec = { + from: 'qsaCmdOutput', + to: 'view', + exec: function(qsaCmdOutput, context) { + return context.createView({ + html: qsaViewHtml, + css: qsaViewCss, + options: {allowEval: true, stack: 'qsa.html'}, + data: { + onclick: function(ev) { + context.exec({ + command: 'qsa', + args: {query: ev.currentTarget.dataset.selector} + }); + }, + selector: qsaCmdOutput.selector, + nodes: qsaCmdOutput.nodes, + maxDisplayedNodes: 100, + l10n: l10n + } + }); + } +}; + +exports.startup = function() { + gcli.addCommand(qsaCmdSpec); + gcli.addConverter(qsaConverterSpec); +}; +exports.shutdown = function() { + gcli.removeCommand(qsaCmdSpec); + gcli.removeConverter(qsaConverterSpec); +}; + +}); diff --git a/lib/gcli/nls/strings.js b/lib/gcli/nls/strings.js index e0a48dd0..e0368019 100644 --- a/lib/gcli/nls/strings.js +++ b/lib/gcli/nls/strings.js @@ -433,7 +433,25 @@ var i18n = { // Short description of the 'allowSetDesc' setting. Displayed when the user // asks for help on the settings. - allowSetDesc: 'Has the user enabled the \'pref set\' command?' + allowSetDesc: 'Has the user enabled the \'pref set\' command?', + + // A very short description of the 'qsa' command. + qsaDesc: 'Execute querySelectorAll given a selector and show matches', + + // A fuller description of the 'qsa' command. + qsaManual: 'Execute querySelectorAll on the current document and show the number of matched elements as well as the elements themselves (provided the selector returns less than 100 nodes)', + + // A very short description of the 'query' parameter to the 'qsa' command. + qsaQueryDesc: 'The CSS selector to use, or several selectors seperated by commas', + + // The intro text to the 'qsa' command shows after the command has been run and gives the number of nodes matched + qsaResultIntroText: '%1$S node(s) found for selector %2$S', + + // The too many results message of the 'qsa' command shows when there are more than X nodes matched by the query, to request the user to refine it + qsaResultsTooMany: ', please refine your selector to display the resulting nodes.', + + // The tooltip text is displayed on hovering over a matched node, to inform the user of the action executed on click + qsaNodeTooltip: 'Click to run qsa with selector %S' } }; exports.root = i18n.root;