Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / components / HandlerRegistry.js
blobcb3a6195b171136354c45c5858d7a628446172e2
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  */
31 /**
32  * @constructor
33  * @extends {WebInspector.Object}
34  */
35 WebInspector.HandlerRegistry = function(setting)
37     WebInspector.Object.call(this);
38     this._handlers = {};
39     this._setting = setting;
40     this._activeHandler = this._setting.get();
43 WebInspector.HandlerRegistry.prototype = {
44     get handlerNames()
45     {
46         return Object.getOwnPropertyNames(this._handlers);
47     },
49     get activeHandler()
50     {
51         return this._activeHandler;
52     },
54     set activeHandler(value)
55     {
56         this._activeHandler = value;
57         this._setting.set(value);
58     },
60     /**
61      * @param {!Object} data
62      * @return {boolean}
63      */
64     dispatch: function(data)
65     {
66         return this.dispatchToHandler(this._activeHandler, data);
67     },
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     },
81     registerHandler: function(name, handler)
82     {
83         this._handlers[name] = handler;
84         this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
85     },
87     unregisterHandler: function(name)
88     {
89         delete this._handlers[name];
90         this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
91     },
93     /**
94      * @param {string} url
95      */
96     _openInNewTab: function(url)
97     {
98         InspectorFrontendHost.openInNewTab(url);
99     },
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;
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.capitalize("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()));
122         if (!contentProvider.contentURL())
123             return;
125         var contentType = contentProvider.contentType();
126         if (contentType !== WebInspector.resourceTypes.Document &&
127             contentType !== WebInspector.resourceTypes.Stylesheet &&
128             contentType !== WebInspector.resourceTypes.Script)
129             return;
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         }
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.save(forceSaveAs);
150                 return;
151             }
152             contentProvider.requestContent(doSave.bind(null, forceSaveAs));
153         }
155         contextMenu.appendSeparator();
156         contextMenu.appendItem(WebInspector.UIString("Save"), save.bind(null, false));
158         if (contentProvider instanceof WebInspector.UISourceCode) {
159             var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (contentProvider);
160             if (uiSourceCode.project().type() !== WebInspector.projectTypes.FileSystem && uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
161                 contextMenu.appendItem(WebInspector.UIString.capitalize("Save ^as..."), save.bind(null, true));
162         }
163     },
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);
175         var anchorElement = targetNode.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || targetNode.enclosingNodeOrSelfWithClass("webkit-html-external-link");
176         if (!anchorElement)
177             return;
179         var uiLocation = WebInspector.Linkifier.uiLocationByAnchor(anchorElement);
180         var resourceURL = uiLocation ? uiLocation.uiSourceCode.contentURL() : anchorElement.href;
181         var uiSourceCode = uiLocation ? uiLocation.uiSourceCode : (resourceURL ? WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(resourceURL) : null);
182         function open()
183         {
184             WebInspector.Revealer.reveal(uiSourceCode);
185         }
186         if (uiSourceCode)
187             contextMenu.appendItem("Open", open);
189         if (!resourceURL)
190             return;
191         // Add resource-related actions.
192         contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), this._openInNewTab.bind(this, resourceURL));
194         /**
195          * @param {string} resourceURL
196          */
197         function openInResourcesPanel(resourceURL)
198         {
199             var resource = WebInspector.resourceForURL(resourceURL);
200             if (resource)
201                 WebInspector.Revealer.reveal(resource);
202             else
203                 InspectorFrontendHost.openInNewTab(resourceURL);
204         }
205         if (!targetNode.enclosingNodeOrSelfWithClassList(["resources", "panel"]) && WebInspector.resourceForURL(resourceURL))
206             contextMenu.appendItem(WebInspector.UIString.capitalize("Open ^link in Resources ^panel"), openInResourcesPanel.bind(null, resourceURL));
209         contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, resourceURL));
210     },
212     __proto__: WebInspector.Object.prototype
216 WebInspector.HandlerRegistry.EventTypes = {
217     HandlersUpdated: "HandlersUpdated"
221  * @constructor
222  */
223 WebInspector.HandlerSelector = function(handlerRegistry)
225     this._handlerRegistry = handlerRegistry;
226     this.element = createElementWithClass("select", "chrome-select");
227     this.element.addEventListener("change", this._onChange.bind(this), false);
228     this._update();
229     this._handlerRegistry.addEventListener(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated, this._update.bind(this));
232 WebInspector.HandlerSelector.prototype =
234     _update: function()
235     {
236         this.element.removeChildren();
237         var names = this._handlerRegistry.handlerNames;
238         var activeHandler = this._handlerRegistry.activeHandler;
240         for (var i = 0; i < names.length; ++i) {
241             var option = createElement("option");
242             option.textContent = names[i];
243             option.selected = activeHandler === names[i];
244             this.element.appendChild(option);
245         }
246         this.element.disabled = names.length <= 1;
247     },
249     _onChange: function(event)
250     {
251         var value = event.target.value;
252         this._handlerRegistry.activeHandler = value;
253     }
257  * @constructor
258  * @implements {WebInspector.ContextMenu.Provider}
259  */
260 WebInspector.HandlerRegistry.ContextMenuProvider = function()
264 WebInspector.HandlerRegistry.ContextMenuProvider.prototype = {
265     /**
266      * @override
267      * @param {!Event} event
268      * @param {!WebInspector.ContextMenu} contextMenu
269      * @param {!Object} target
270      */
271     appendApplicableItems: function(event, contextMenu, target)
272     {
273         WebInspector.openAnchorLocationRegistry._appendContentProviderItems(contextMenu, target);
274         WebInspector.openAnchorLocationRegistry._appendHrefItems(contextMenu, target);
275     }
279  * @constructor
280  * @implements {WebInspector.Linkifier.LinkHandler}
281  */
282 WebInspector.HandlerRegistry.LinkHandler = function()
286 WebInspector.HandlerRegistry.LinkHandler.prototype = {
287     /**
288      * @override
289      * @param {string} url
290      * @param {number=} lineNumber
291      * @return {boolean}
292      */
293     handleLink: function(url, lineNumber)
294     {
295         return WebInspector.openAnchorLocationRegistry.dispatch({ url: url, lineNumber: lineNumber});
296     }
300  * @constructor
301  * @implements {WebInspector.SettingUI}
302  */
303 WebInspector.HandlerRegistry.OpenAnchorLocationSettingUI = function()
307 WebInspector.HandlerRegistry.OpenAnchorLocationSettingUI.prototype = {
308     /**
309      * @override
310      * @return {?Element}
311      */
312     settingElement: function()
313     {
314         if (!WebInspector.openAnchorLocationRegistry.handlerNames.length)
315             return null;
317         var handlerSelector = new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry);
318         return WebInspector.SettingsUI.createCustomSetting(WebInspector.UIString("Link handling:"), handlerSelector.element);
319     }
323  * @type {!WebInspector.HandlerRegistry}
324  */
325 WebInspector.openAnchorLocationRegistry;