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 this._appendContentProviderItems(contextMenu, target); 100 this._appendHrefItems(contextMenu, target); 101 }, 102 103 /** 104 * @param {!WebInspector.ContextMenu} contextMenu 105 * @param {!Object} target 106 */ 107 _appendContentProviderItems: function(contextMenu, target) 108 { 109 if (!(target instanceof WebInspector.UISourceCode || target instanceof WebInspector.Resource || target instanceof WebInspector.NetworkRequest)) 110 return; 111 var contentProvider = /** @type {!WebInspector.ContentProvider} */ (target); 112 if (!contentProvider.contentURL()) 113 return; 114 115 contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, contentProvider.contentURL(), false)); 116 // Skip 0th handler, as it's 'Use default panel' one. 117 for (var i = 1; i < this.handlerNames.length; ++i) { 118 var handler = this.handlerNames[i]; 119 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open using %s" : "Open Using %s", handler), 120 this.dispatchToHandler.bind(this, handler, { url: contentProvider.contentURL() })); 121 } 122 contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, contentProvider.contentURL())); 123 124 if (!contentProvider.contentURL()) 125 return; 126 127 var contentType = contentProvider.contentType(); 128 if (contentType !== WebInspector.resourceTypes.Document && 129 contentType !== WebInspector.resourceTypes.Stylesheet && 130 contentType !== WebInspector.resourceTypes.Script) 131 return; 132 133 /** 134 * @param {boolean} forceSaveAs 135 * @param {?string} content 136 */ 137 function doSave(forceSaveAs, content) 138 { 139 var url = contentProvider.contentURL(); 140 WebInspector.fileManager.save(url, content, forceSaveAs); 141 WebInspector.fileManager.close(url); 142 } 143 144 /** 145 * @param {boolean} forceSaveAs 146 * @this {WebInspector.HandlerRegistry} 147 */ 148 function save(forceSaveAs) 149 { 150 if (contentProvider instanceof WebInspector.UISourceCode) { 151 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (contentProvider); 152 uiSourceCode.saveToFileSystem(forceSaveAs); 153 return; 154 } 155 contentProvider.requestContent(doSave.bind(this, forceSaveAs)); 156 } 157 158 contextMenu.appendSeparator(); 159 contextMenu.appendItem(WebInspector.UIString("Save"), save.bind(this, false)); 160 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save as..." : "Save As..."), save.bind(this, true)); 161 }, 162 163 /** 164 * @param {!WebInspector.ContextMenu} contextMenu 165 * @param {!Object} target 166 */ 167 _appendHrefItems: function(contextMenu, target) 168 { 169 if (!(target instanceof Node)) 170 return; 171 var targetNode = /** @type {!Node} */ (target); 172 173 var anchorElement = targetNode.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || targetNode.enclosingNodeOrSelfWithClass("webkit-html-external-link"); 174 if (!anchorElement) 175 return; 176 177 var resourceURL = anchorElement.href; 178 if (!resourceURL) 179 return; 180 181 // Add resource-related actions. 182 contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, resourceURL, false)); 183 if (WebInspector.resourceForURL(resourceURL)) 184 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in Resources panel" : "Open Link in Resources Panel"), WebInspector.openResource.bind(null, resourceURL, true)); 185 contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, resourceURL)); 186 }, 187 188 __proto__: WebInspector.Object.prototype 189 } 190 191 192 WebInspector.HandlerRegistry.EventTypes = { 193 HandlersUpdated: "HandlersUpdated" 194 } 195 196 /** 197 * @constructor 198 */ 199 WebInspector.HandlerSelector = function(handlerRegistry) 200 { 201 this._handlerRegistry = handlerRegistry; 202 this.element = document.createElement("select"); 203 this.element.addEventListener("change", this._onChange.bind(this), false); 204 this._update(); 205 this._handlerRegistry.addEventListener(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated, this._update.bind(this)); 206 } 207 208 WebInspector.HandlerSelector.prototype = 209 { 210 _update: function() 211 { 212 this.element.removeChildren(); 213 var names = this._handlerRegistry.handlerNames; 214 var activeHandler = this._handlerRegistry.activeHandler; 215 216 for (var i = 0; i < names.length; ++i) { 217 var option = document.createElement("option"); 218 option.textContent = names[i]; 219 option.selected = activeHandler === names[i]; 220 this.element.appendChild(option); 221 } 222 this.element.disabled = names.length <= 1; 223 }, 224 225 _onChange: function(event) 226 { 227 var value = event.target.value; 228 this._handlerRegistry.activeHandler = value; 229 } 230 } 231 232 233 /** 234 * @type {!WebInspector.HandlerRegistry} 235 */ 236 WebInspector.openAnchorLocationRegistry; 237