Home | History | Annotate | Download | only in front_end
      1 /*
      2  * Copyright (C) 2011 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 /**
     32  * @constructor
     33  * @extends {WebInspector.Object}
     34  * @implements {WebInspector.ContextMenu.Provider}
     35  */
     36 WebInspector.HandlerRegistry = function(setting)
     37 {
     38     WebInspector.Object.call(this);
     39     this._handlers = {};
     40     this._setting = setting;
     41     this._activeHandler = this._setting.get();
     42     WebInspector.ContextMenu.registerProvider(this);
     43 }
     44 
     45 WebInspector.HandlerRegistry.prototype = {
     46     get handlerNames()
     47     {
     48         return Object.getOwnPropertyNames(this._handlers);
     49     },
     50 
     51     get activeHandler()
     52     {
     53         return this._activeHandler;
     54     },
     55 
     56     set activeHandler(value)
     57     {
     58         this._activeHandler = value;
     59         this._setting.set(value);
     60     },
     61 
     62     /**
     63      * @param {Object} data
     64      */
     65     dispatch: function(data)
     66     {
     67         return this.dispatchToHandler(this._activeHandler, data);
     68     },
     69 
     70     /**
     71      * @param {string} name
     72      * @param {Object} data
     73      */
     74     dispatchToHandler: function(name, data)
     75     {
     76         var handler = this._handlers[name];
     77         var result = handler && handler(data);
     78         return !!result;
     79     },
     80 
     81     registerHandler: function(name, handler)
     82     {
     83         this._handlers[name] = handler;
     84         this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
     85     },
     86 
     87     unregisterHandler: function(name)
     88     {
     89         delete this._handlers[name];
     90         this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
     91     },
     92 
     93     /**
     94      * @param {WebInspector.ContextMenu} contextMenu
     95      * @param {Object} target
     96      */
     97     appendApplicableItems: function(event, contextMenu, target)
     98     {
     99         if (event.hasBeenHandledByHandlerRegistry)
    100             return;
    101         event.hasBeenHandledByHandlerRegistry = true;
    102         this._appendContentProviderItems(contextMenu, target);
    103         this._appendHrefItems(contextMenu, target);
    104     },
    105 
    106     /**
    107      * @param {WebInspector.ContextMenu} contextMenu
    108      * @param {Object} target
    109      */
    110     _appendContentProviderItems: function(contextMenu, target)
    111     {
    112         if (!(target instanceof WebInspector.UISourceCode || target instanceof WebInspector.Resource || target instanceof WebInspector.NetworkRequest))
    113             return;
    114         var contentProvider = /** @type {WebInspector.ContentProvider} */ (target);
    115         if (!contentProvider.contentURL())
    116             return;
    117 
    118         contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, contentProvider.contentURL(), false));
    119         // Skip 0th handler, as it's 'Use default panel' one.
    120         for (var i = 1; i < this.handlerNames.length; ++i) {
    121             var handler = this.handlerNames[i];
    122             contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open using %s" : "Open Using %s", handler),
    123                 this.dispatchToHandler.bind(this, handler, { url: contentProvider.contentURL() }));
    124         }
    125         contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, contentProvider.contentURL()));
    126 
    127         if (!contentProvider.contentURL())
    128             return;
    129 
    130         var contentType = contentProvider.contentType();
    131         if (contentType !== WebInspector.resourceTypes.Document &&
    132             contentType !== WebInspector.resourceTypes.Stylesheet &&
    133             contentType !== WebInspector.resourceTypes.Script)
    134             return;
    135 
    136         /**
    137          * @param {boolean} forceSaveAs
    138          * @param {?string} content
    139          */
    140         function doSave(forceSaveAs, content)
    141         {
    142             var url = contentProvider.contentURL();
    143             WebInspector.fileManager.save(url, content, forceSaveAs);
    144             WebInspector.fileManager.close(url);
    145         }
    146 
    147         /**
    148          * @param {boolean} forceSaveAs
    149          */
    150         function save(forceSaveAs)
    151         {
    152             if (contentProvider instanceof WebInspector.UISourceCode) {
    153                 var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (contentProvider);
    154                 uiSourceCode.saveToFileSystem(forceSaveAs);
    155                 return;
    156             }
    157             contentProvider.requestContent(doSave.bind(this, forceSaveAs));
    158         }
    159 
    160         contextMenu.appendSeparator();
    161         contextMenu.appendItem(WebInspector.UIString("Save"), save.bind(this, false));
    162         contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save as..." : "Save As..."), save.bind(this, true));
    163     },
    164 
    165     /**
    166      * @param {WebInspector.ContextMenu} contextMenu
    167      * @param {Object} target
    168      */
    169     _appendHrefItems: function(contextMenu, target)
    170     {
    171         if (!(target instanceof Node))
    172             return;
    173         var targetNode = /** @type {Node} */ (target);
    174 
    175         var anchorElement = targetNode.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || targetNode.enclosingNodeOrSelfWithClass("webkit-html-external-link");
    176         if (!anchorElement)
    177             return;
    178 
    179         var resourceURL = anchorElement.href;
    180         if (!resourceURL)
    181             return;
    182 
    183         // Add resource-related actions.
    184         contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, resourceURL, false));
    185         if (WebInspector.resourceForURL(resourceURL))
    186             contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in Resources panel" : "Open Link in Resources Panel"), WebInspector.openResource.bind(null, resourceURL, true));
    187         contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, resourceURL));
    188     },
    189 
    190     __proto__: WebInspector.Object.prototype
    191 }
    192 
    193 
    194 WebInspector.HandlerRegistry.EventTypes = {
    195     HandlersUpdated: "HandlersUpdated"
    196 }
    197 
    198 /**
    199  * @constructor
    200  */
    201 WebInspector.HandlerSelector = function(handlerRegistry)
    202 {
    203     this._handlerRegistry = handlerRegistry;
    204     this.element = document.createElement("select");
    205     this.element.addEventListener("change", this._onChange.bind(this), false);
    206     this._update();
    207     this._handlerRegistry.addEventListener(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated, this._update.bind(this));
    208 }
    209 
    210 WebInspector.HandlerSelector.prototype =
    211 {
    212     _update: function()
    213     {
    214         this.element.removeChildren();
    215         var names = this._handlerRegistry.handlerNames;
    216         var activeHandler = this._handlerRegistry.activeHandler;
    217 
    218         for (var i = 0; i < names.length; ++i) {
    219             var option = document.createElement("option");
    220             option.textContent = names[i];
    221             option.selected = activeHandler === names[i];
    222             this.element.appendChild(option);
    223         }
    224         this.element.disabled = names.length <= 1;
    225     },
    226 
    227     _onChange: function(event)
    228     {
    229         var value = event.target.value;
    230         this._handlerRegistry.activeHandler = value;
    231     }
    232 }
    233 
    234 
    235 /**
    236  * @type {WebInspector.HandlerRegistry}
    237  */
    238 WebInspector.openAnchorLocationRegistry = null;
    239