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