toolkit/devtools/gcli/commands/pagemod.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 const { Cc, Ci, Cu } = require("chrome");
     8 const gcli = require("gcli/index");
    10 exports.items = [
    11   {
    12     name: "pagemod",
    13     description: gcli.lookup("pagemodDesc"),
    14   },
    15   {
    16     name: "pagemod replace",
    17     description: gcli.lookup("pagemodReplaceDesc"),
    18     params: [
    19       {
    20         name: "search",
    21         type: "string",
    22         description: gcli.lookup("pagemodReplaceSearchDesc"),
    23       },
    24       {
    25         name: "replace",
    26         type: "string",
    27         description: gcli.lookup("pagemodReplaceReplaceDesc"),
    28       },
    29       {
    30         name: "ignoreCase",
    31         type: "boolean",
    32         description: gcli.lookup("pagemodReplaceIgnoreCaseDesc"),
    33       },
    34       {
    35         name: "selector",
    36         type: "string",
    37         description: gcli.lookup("pagemodReplaceSelectorDesc"),
    38         defaultValue: "*:not(script):not(style):not(embed):not(object):not(frame):not(iframe):not(frameset)",
    39       },
    40       {
    41         name: "root",
    42         type: "node",
    43         description: gcli.lookup("pagemodReplaceRootDesc"),
    44         defaultValue: null,
    45       },
    46       {
    47         name: "attrOnly",
    48         type: "boolean",
    49         description: gcli.lookup("pagemodReplaceAttrOnlyDesc"),
    50       },
    51       {
    52         name: "contentOnly",
    53         type: "boolean",
    54         description: gcli.lookup("pagemodReplaceContentOnlyDesc"),
    55       },
    56       {
    57         name: "attributes",
    58         type: "string",
    59         description: gcli.lookup("pagemodReplaceAttributesDesc"),
    60         defaultValue: null,
    61       },
    62     ],
    63     // Make a given string safe to use in a regular expression.
    64     escapeRegex: function(aString) {
    65       return aString.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
    66     },
    67     exec: function(args, context) {
    68       let searchTextNodes = !args.attrOnly;
    69       let searchAttributes = !args.contentOnly;
    70       let regexOptions = args.ignoreCase ? "ig" : "g";
    71       let search = new RegExp(this.escapeRegex(args.search), regexOptions);
    72       let attributeRegex = null;
    73       if (args.attributes) {
    74         attributeRegex = new RegExp(args.attributes, regexOptions);
    75       }
    77       let root = args.root || context.environment.document;
    78       let elements = root.querySelectorAll(args.selector);
    79       elements = Array.prototype.slice.call(elements);
    81       let replacedTextNodes = 0;
    82       let replacedAttributes = 0;
    84       function replaceAttribute() {
    85         replacedAttributes++;
    86         return args.replace;
    87       }
    88       function replaceTextNode() {
    89         replacedTextNodes++;
    90         return args.replace;
    91       }
    93       for (let i = 0; i < elements.length; i++) {
    94         let element = elements[i];
    95         if (searchTextNodes) {
    96           for (let y = 0; y < element.childNodes.length; y++) {
    97             let node = element.childNodes[y];
    98             if (node.nodeType == node.TEXT_NODE) {
    99               node.textContent = node.textContent.replace(search, replaceTextNode);
   100             }
   101           }
   102         }
   104         if (searchAttributes) {
   105           if (!element.attributes) {
   106             continue;
   107           }
   108           for (let y = 0; y < element.attributes.length; y++) {
   109             let attr = element.attributes[y];
   110             if (!attributeRegex || attributeRegex.test(attr.name)) {
   111               attr.value = attr.value.replace(search, replaceAttribute);
   112             }
   113           }
   114         }
   115       }
   117       return gcli.lookupFormat("pagemodReplaceResult",
   118                               [elements.length, replacedTextNodes,
   119                                 replacedAttributes]);
   120     }
   121   },
   122   {
   123     name: "pagemod remove",
   124     description: gcli.lookup("pagemodRemoveDesc"),
   125   },
   126   {
   127     name: "pagemod remove element",
   128     description: gcli.lookup("pagemodRemoveElementDesc"),
   129     params: [
   130       {
   131         name: "search",
   132         type: "string",
   133         description: gcli.lookup("pagemodRemoveElementSearchDesc"),
   134       },
   135       {
   136         name: "root",
   137         type: "node",
   138         description: gcli.lookup("pagemodRemoveElementRootDesc"),
   139         defaultValue: null,
   140       },
   141       {
   142         name: "stripOnly",
   143         type: "boolean",
   144         description: gcli.lookup("pagemodRemoveElementStripOnlyDesc"),
   145       },
   146       {
   147         name: "ifEmptyOnly",
   148         type: "boolean",
   149         description: gcli.lookup("pagemodRemoveElementIfEmptyOnlyDesc"),
   150       },
   151     ],
   152     exec: function(args, context) {
   153       let root = args.root || context.environment.document;
   154       let elements = Array.prototype.slice.call(root.querySelectorAll(args.search));
   156       let removed = 0;
   157       for (let i = 0; i < elements.length; i++) {
   158         let element = elements[i];
   159         let parentNode = element.parentNode;
   160         if (!parentNode || !element.removeChild) {
   161           continue;
   162         }
   163         if (args.stripOnly) {
   164           while (element.hasChildNodes()) {
   165             parentNode.insertBefore(element.childNodes[0], element);
   166           }
   167         }
   168         if (!args.ifEmptyOnly || !element.hasChildNodes()) {
   169           element.parentNode.removeChild(element);
   170           removed++;
   171         }
   172       }
   174       return gcli.lookupFormat("pagemodRemoveElementResultMatchedAndRemovedElements",
   175                               [elements.length, removed]);
   176     }
   177   },
   178   {
   179     name: "pagemod remove attribute",
   180     description: gcli.lookup("pagemodRemoveAttributeDesc"),
   181     params: [
   182       {
   183         name: "searchAttributes",
   184         type: "string",
   185         description: gcli.lookup("pagemodRemoveAttributeSearchAttributesDesc"),
   186       },
   187       {
   188         name: "searchElements",
   189         type: "string",
   190         description: gcli.lookup("pagemodRemoveAttributeSearchElementsDesc"),
   191       },
   192       {
   193         name: "root",
   194         type: "node",
   195         description: gcli.lookup("pagemodRemoveAttributeRootDesc"),
   196         defaultValue: null,
   197       },
   198       {
   199         name: "ignoreCase",
   200         type: "boolean",
   201         description: gcli.lookup("pagemodRemoveAttributeIgnoreCaseDesc"),
   202       },
   203     ],
   204     exec: function(args, context) {
   205       let root = args.root || context.environment.document;
   206       let regexOptions = args.ignoreCase ? "ig" : "g";
   207       let attributeRegex = new RegExp(args.searchAttributes, regexOptions);
   208       let elements = root.querySelectorAll(args.searchElements);
   209       elements = Array.prototype.slice.call(elements);
   211       let removed = 0;
   212       for (let i = 0; i < elements.length; i++) {
   213         let element = elements[i];
   214         if (!element.attributes) {
   215           continue;
   216         }
   218         var attrs = Array.prototype.slice.call(element.attributes);
   219         for (let y = 0; y < attrs.length; y++) {
   220           let attr = attrs[y];
   221           if (attributeRegex.test(attr.name)) {
   222             element.removeAttribute(attr.name);
   223             removed++;
   224           }
   225         }
   226       }
   228       return gcli.lookupFormat("pagemodRemoveAttributeResult",
   229                               [elements.length, removed]);
   230     }
   231   },
   232   // This command allows the user to export the page to HTML after DOM changes
   233   {
   234     name: "export",
   235     description: gcli.lookup("exportDesc"),
   236   },
   237   {
   238     name: "export html",
   239     description: gcli.lookup("exportHtmlDesc"),
   240     params: [
   241       {
   242         name: "destination",
   243         type: {
   244           name: "selection",
   245           data: [ "window", "stdout", "clipboard" ]
   246         },
   247         defaultValue: "window"
   248       }
   249     ],
   250     exec: function(args, context) {
   251       let html = context.environment.document.documentElement.outerHTML;
   252       if (args.destination === "stdout") {
   253         return html;
   254       }
   256       if (args.desination === "clipboard") {
   257         let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"]
   258                           .getService(Ci.nsIClipboardHelper);
   259         clipboard.copyString(url);
   260         return '';
   261       }
   263       let url = "data:text/plain;charset=utf8," + encodeURIComponent(html);
   264       context.environment.window.open(url);
   265       return '';
   266     }
   267   }
   268 ];

mercurial