browser/devtools/styleeditor/StyleEditorUtil.jsm

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 /* vim:set ts=2 sw=2 sts=2 et: */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 "use strict";
     8 this.EXPORTED_SYMBOLS = [
     9   "_",
    10   "assert",
    11   "log",
    12   "text",
    13   "wire",
    14   "showFilePicker"
    15 ];
    17 const Cc = Components.classes;
    18 const Ci = Components.interfaces;
    19 const Cu = Components.utils;
    21 Cu.import("resource://gre/modules/Services.jsm");
    23 const PROPERTIES_URL = "chrome://browser/locale/devtools/styleeditor.properties";
    25 const console = Services.console;
    26 const gStringBundle = Services.strings.createBundle(PROPERTIES_URL);
    29 /**
    30  * Returns a localized string with the given key name from the string bundle.
    31  *
    32  * @param aName
    33  * @param ...rest
    34  *        Optional arguments to format in the string.
    35  * @return string
    36  */
    37 this._ = function _(aName)
    38 {
    40   if (arguments.length == 1) {
    41     return gStringBundle.GetStringFromName(aName);
    42   }
    43   let rest = Array.prototype.slice.call(arguments, 1);
    44   return gStringBundle.formatStringFromName(aName, rest, rest.length);
    45 }
    47 /**
    48  * Assert an expression is true or throw if false.
    49  *
    50  * @param aExpression
    51  * @param aMessage
    52  *        Optional message.
    53  * @return aExpression
    54  */
    55 this.assert = function assert(aExpression, aMessage)
    56 {
    57   if (!!!(aExpression)) {
    58     let msg = aMessage ? "ASSERTION FAILURE:" + aMessage : "ASSERTION FAILURE";
    59     log(msg);
    60     throw new Error(msg);
    61   }
    62   return aExpression;
    63 }
    65 /**
    66  * Retrieve or set the text content of an element.
    67  *
    68  * @param DOMElement aRoot
    69  *        The element to use for querySelector.
    70  * @param string aSelector
    71  *        Selector string for the element to get/set the text content.
    72  * @param string aText
    73  *        Optional text to set.
    74  * @return string
    75  *         Text content of matching element or null if there were no element
    76  *         matching aSelector.
    77  */
    78 this.text = function text(aRoot, aSelector, aText)
    79 {
    80   let element = aRoot.querySelector(aSelector);
    81   if (!element) {
    82     return null;
    83   }
    85   if (aText === undefined) {
    86     return element.textContent;
    87   }
    88   element.textContent = aText;
    89   return aText;
    90 }
    92 /**
    93  * Iterates _own_ properties of an object.
    94  *
    95  * @param aObject
    96  *        The object to iterate.
    97  * @param function aCallback(aKey, aValue)
    98  */
    99 function forEach(aObject, aCallback)
   100 {
   101   for (let key in aObject) {
   102     if (aObject.hasOwnProperty(key)) {
   103       aCallback(key, aObject[key]);
   104     }
   105   }
   106 }
   108 /**
   109  * Log a message to the console.
   110  *
   111  * @param ...rest
   112  *        One or multiple arguments to log.
   113  *        If multiple arguments are given, they will be joined by " " in the log.
   114  */
   115 this.log = function log()
   116 {
   117   console.logStringMessage(Array.prototype.slice.call(arguments).join(" "));
   118 }
   120 /**
   121  * Wire up element(s) matching selector with attributes, event listeners, etc.
   122  *
   123  * @param DOMElement aRoot
   124  *        The element to use for querySelectorAll.
   125  *        Can be null if aSelector is a DOMElement.
   126  * @param string|DOMElement aSelectorOrElement
   127  *        Selector string or DOMElement for the element(s) to wire up.
   128  * @param object aDescriptor
   129  *        An object describing how to wire matching selector, supported properties
   130  *        are "events" and "attributes" taking objects themselves.
   131  *        Each key of properties above represents the name of the event or
   132  *        attribute, with the value being a function used as an event handler or
   133  *        string to use as attribute value.
   134  *        If aDescriptor is a function, the argument is equivalent to :
   135  *        {events: {'click': aDescriptor}}
   136  */
   137 this.wire = function wire(aRoot, aSelectorOrElement, aDescriptor)
   138 {
   139   let matches;
   140   if (typeof(aSelectorOrElement) == "string") { // selector
   141     matches = aRoot.querySelectorAll(aSelectorOrElement);
   142     if (!matches.length) {
   143       return;
   144     }
   145   } else {
   146     matches = [aSelectorOrElement]; // element
   147   }
   149   if (typeof(aDescriptor) == "function") {
   150     aDescriptor = {events: {click: aDescriptor}};
   151   }
   153   for (let i = 0; i < matches.length; i++) {
   154     let element = matches[i];
   155     forEach(aDescriptor.events, function (aName, aHandler) {
   156       element.addEventListener(aName, aHandler, false);
   157     });
   158     forEach(aDescriptor.attributes, element.setAttribute);
   159   }
   160 }
   162 /**
   163  * Show file picker and return the file user selected.
   164  *
   165  * @param mixed file
   166  *        Optional nsIFile or string representing the filename to auto-select.
   167  * @param boolean toSave
   168  *        If true, the user is selecting a filename to save.
   169  * @param nsIWindow parentWindow
   170  *        Optional parent window. If null the parent window of the file picker
   171  *        will be the window of the attached input element.
   172  * @param callback
   173  *        The callback method, which will be called passing in the selected
   174  *        file or null if the user did not pick one.
   175  * @param AString suggestedFilename
   176  *        The suggested filename when toSave is true.
   177  */
   178 this.showFilePicker = function showFilePicker(path, toSave, parentWindow,
   179                                               callback, suggestedFilename)
   180 {
   181   if (typeof(path) == "string") {
   182     try {
   183       if (Services.io.extractScheme(path) == "file") {
   184         let uri = Services.io.newURI(path, null, null);
   185         let file = uri.QueryInterface(Ci.nsIFileURL).file;
   186         callback(file);
   187         return;
   188       }
   189     } catch (ex) {
   190       callback(null);
   191       return;
   192     }
   193     try {
   194       let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
   195       file.initWithPath(path);
   196       callback(file);
   197       return;
   198     } catch (ex) {
   199       callback(null);
   200       return;
   201     }
   202   }
   203   if (path) { // "path" is an nsIFile
   204     callback(path);
   205     return;
   206   }
   208   let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
   209   let mode = toSave ? fp.modeSave : fp.modeOpen;
   210   let key = toSave ? "saveStyleSheet" : "importStyleSheet";
   211   let fpCallback = function(result) {
   212     if (result == Ci.nsIFilePicker.returnCancel) {
   213       callback(null);
   214     } else {
   215       callback(fp.file);
   216     }
   217   };
   219   if (toSave && suggestedFilename) {
   220     fp.defaultString = suggestedFilename;
   221   }
   223   fp.init(parentWindow, _(key + ".title"), mode);
   224   fp.appendFilters(_(key + ".filter"), "*.css");
   225   fp.appendFilters(fp.filterAll);
   226   fp.open(fpCallback);
   227   return;
   228 }

mercurial