Home | History | Annotate | Download | only in components
      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  */
     35 WebInspector.HandlerRegistry = function(setting)
     36 {
     37     WebInspector.Object.call(this);
     38     this._handlers = {};
     39     this._setting = setting;
     40     this._activeHandler = this._setting.get();
     41 }
     42 
     43 WebInspector.HandlerRegistry.prototype = {
     44     get handlerNames()
     45     {
     46         return Object.getOwnPropertyNames(this._handlers);
     47     },
     48 
     49     get activeHandler()
     50     {
     51         return this._activeHandler;
     52     },
     53 
     54     set activeHandler(value)
     55     {
     56         this._activeHandler = value;
     57         this._setting.set(value);
     58     },
     59 
     60     /**
     61      * @param {!Object} data
     62      * @return {boolean}
     63      */
     64     dispatch: function(data)
     65     {
     66         return this.dispatchToHandler(this._activeHandler, data);
     67     },
     68 
     69     /**
     70      * @param {string} name
     71      * @param {!Object} data
     72      * @return {boolean}
     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 {string} url
     95      */
     96     _openInNewTab: function(url)
     97     {
     98         InspectorFrontendHost.openInNewTab(url);
     99     },
    100 
    101     /**
    102      * @param {!WebInspector.ContextMenu} contextMenu
    103      * @param {!Object} target
    104      */
    105     _appendContentProviderItems: function(contextMenu, target)
    106     {
    107         if (!(target instanceof WebInspector.UISourceCode || target instanceof WebInspector.Resource || target instanceof WebInspector.NetworkRequest))
    108             return;
    109         var contentProvider = /** @type {!WebInspector.ContentProvider} */ (target);
    110         if (!contentProvider.contentURL())
    111             return;
    112 
    113         contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), this._openInNewTab.bind(this, contentProvider.contentURL()));
    114         // Skip 0th handler, as it's 'Use default panel' one.
    115         for (var i = 1; i < this.handlerNames.length; ++i) {
    116             var handler = this.handlerNames[i];
    117             contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open using %s" : "Open Using %s", handler),
    118                 this.dispatchToHandler.bind(this, handler, { url: contentProvider.contentURL() }));
    119         }
    120         contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, contentProvider.contentURL()));
    121 
    122         if (!contentProvider.contentURL())
    123             return;
    124 
    125         var contentType = contentProvider.contentType();
    126         if (contentType !== WebInspector.resourceTypes.Document &&
    127             contentType !== WebInspector.resourceTypes.Stylesheet &&
    128             contentType !== WebInspector.resourceTypes.Script)
    129             return;
    130 
    131         /**
    132          * @param {boolean} forceSaveAs
    133          * @param {?string} content
    134          */
    135         function doSave(forceSaveAs, content)
    136         {
    137             var url = contentProvider.contentURL();
    138             WebInspector.fileManager.save(url, /** @type {string} */ (content), forceSaveAs);
    139             WebInspector.fileManager.close(url);
    140         }
    141 
    142         /**
    143          * @param {boolean} forceSaveAs
    144          */
    145         function save(forceSaveAs)
    146         {
    147             if (contentProvider instanceof WebInspector.UISourceCode) {
    148                 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (contentProvider);
    149                 uiSourceCode.saveToFileSystem(forceSaveAs);
    150                 return;
    151             }
    152             contentProvider.requestContent(doSave.bind(null, forceSaveAs));
    153         }
    154 
    155         contextMenu.appendSeparator();
    156         contextMenu.appendItem(WebInspector.UIString("Save"), save.bind(null, false));
    157         contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save as..." : "Save As..."), save.bind(null, true));
    158     },
    159 
    160     /**
    161      * @param {!WebInspector.ContextMenu} contextMenu
    162      * @param {!Object} target
    163      */
    164     _appendHrefItems: function(contextMenu, target)
    165     {
    166         if (!(target instanceof Node))
    167             return;
    168         var targetNode = /** @type {!Node} */ (target);
    169 
    170         var anchorElement = targetNode.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || targetNode.enclosingNodeOrSelfWithClass("webkit-html-external-link");
    171         if (!anchorElement)
    172             return;
    173 
    174         var resourceURL = anchorElement.href;
    175         if (!resourceURL)
    176             return;
    177 
    178         // Add resource-related actions.
    179         contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), this._openInNewTab.bind(this, resourceURL));
    180 
    181         function openInResourcesPanel(resourceURL)
    182         {
    183             var resource = WebInspector.resourceForURL(resourceURL);
    184             if (resource)
    185                 WebInspector.Revealer.reveal(resource);
    186             else
    187                 InspectorFrontendHost.openInNewTab(resourceURL);
    188         }
    189         if (WebInspector.resourceForURL(resourceURL))
    190             contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in Resources panel" : "Open Link in Resources Panel"), openInResourcesPanel.bind(null, resourceURL));
    191         contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, resourceURL));
    192     },
    193 
    194     __proto__: WebInspector.Object.prototype
    195 }
    196 
    197 
    198 WebInspector.HandlerRegistry.EventTypes = {
    199     HandlersUpdated: "HandlersUpdated"
    200 }
    201 
    202 /**
    203  * @constructor
    204  */
    205 WebInspector.HandlerSelector = function(handlerRegistry)
    206 {
    207     this._handlerRegistry = handlerRegistry;
    208     this.element = document.createElement("select");
    209     this.element.addEventListener("change", this._onChange.bind(this), false);
    210     this._update();
    211     this._handlerRegistry.addEventListener(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated, this._update.bind(this));
    212 }
    213 
    214 WebInspector.HandlerSelector.prototype =
    215 {
    216     _update: function()
    217     {
    218         this.element.removeChildren();
    219         var names = this._handlerRegistry.handlerNames;
    220         var activeHandler = this._handlerRegistry.activeHandler;
    221 
    222         for (var i = 0; i < names.length; ++i) {
    223             var option = document.createElement("option");
    224             option.textContent = names[i];
    225             option.selected = activeHandler === names[i];
    226             this.element.appendChild(option);
    227         }
    228         this.element.disabled = names.length <= 1;
    229     },
    230 
    231     _onChange: function(event)
    232     {
    233         var value = event.target.value;
    234         this._handlerRegistry.activeHandler = value;
    235     }
    236 }
    237 
    238 /**
    239  * @constructor
    240  * @implements {WebInspector.ContextMenu.Provider}
    241  */
    242 WebInspector.HandlerRegistry.ContextMenuProvider = function()
    243 {
    244 }
    245 
    246 WebInspector.HandlerRegistry.ContextMenuProvider.prototype = {
    247     /**
    248      * @param {!Event} event
    249      * @param {!WebInspector.ContextMenu} contextMenu
    250      * @param {!Object} target
    251      */
    252     appendApplicableItems: function(event, contextMenu, target)
    253     {
    254         WebInspector.openAnchorLocationRegistry._appendContentProviderItems(contextMenu, target);
    255         WebInspector.openAnchorLocationRegistry._appendHrefItems(contextMenu, target);
    256     }
    257 }
    258 
    259 /**
    260  * @constructor
    261  * @implements {WebInspector.Linkifier.LinkHandler}
    262  */
    263 WebInspector.HandlerRegistry.LinkHandler = function()
    264 {
    265 }
    266 
    267 WebInspector.HandlerRegistry.LinkHandler.prototype = {
    268     /**
    269      * @param {string} url
    270      * @param {number=} lineNumber
    271      * @return {boolean}
    272      */
    273     handleLink: function(url, lineNumber)
    274     {
    275         return WebInspector.openAnchorLocationRegistry.dispatch({ url: url, lineNumber: lineNumber});
    276     }
    277 }
    278 
    279 /**
    280  * @constructor
    281  * @extends {WebInspector.UISettingDelegate}
    282  */
    283 WebInspector.HandlerRegistry.OpenAnchorLocationSettingDelegate = function()
    284 {
    285     WebInspector.UISettingDelegate.call(this);
    286 }
    287 
    288 WebInspector.HandlerRegistry.OpenAnchorLocationSettingDelegate.prototype = {
    289     /**
    290      * @override
    291      * @return {?Element}
    292      */
    293     settingElement: function()
    294     {
    295         if (!WebInspector.openAnchorLocationRegistry.handlerNames.length)
    296             return null;
    297 
    298         var handlerSelector = new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry);
    299         return WebInspector.SettingsUI.createCustomSetting(WebInspector.UIString("Open links in"), handlerSelector.element);
    300     },
    301 
    302     __proto__: WebInspector.UISettingDelegate.prototype
    303 }
    304 
    305 /**
    306  * @type {!WebInspector.HandlerRegistry}
    307  */
    308 WebInspector.openAnchorLocationRegistry;
    309