| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Shim that simulates a <webview> tag via Mutation Observers. | 5 // Shim that simulates a <webview> tag via Mutation Observers. |
| 6 // | 6 // |
| 7 // The actual tag is implemented via the browser plugin. The internals of this | 7 // The actual tag is implemented via the browser plugin. The internals of this |
| 8 // are hidden via Shadow DOM. | 8 // are hidden via Shadow DOM. |
| 9 | 9 |
| 10 var watchForTag = require('tagWatcher').watchForTag; | 10 var watchForTag = require('tagWatcher').watchForTag; |
| 11 var eventBindings = require('event_bindings'); | 11 var eventBindings = require('event_bindings'); |
| 12 | 12 |
| 13 /** @type {Array.<string>} */ | 13 /** @type {Array.<string>} */ |
| 14 var WEB_VIEW_ATTRIBUTES = ['name', 'src', 'partition', 'autosize', 'minheight', | 14 var WEB_VIEW_ATTRIBUTES = ['name', 'src', 'partition', 'autosize', 'minheight', |
| 15 'minwidth', 'maxheight', 'maxwidth']; | 15 'minwidth', 'maxheight', 'maxwidth']; |
| 16 | 16 |
| 17 | 17 |
| 18 // All exposed api methods for <webview>, these are forwarded to the browser | 18 // All exposed api methods for <webview>, these are forwarded to the browser |
| 19 // plugin. | 19 // plugin. |
| 20 var WEB_VIEW_API_METHODS = [ | 20 var WEB_VIEW_API_METHODS = [ |
| 21 'back', | |
| 22 'canGoBack', | |
| 23 'canGoForward', | |
| 24 'forward', | |
| 25 'getProcessId', | 21 'getProcessId', |
| 26 'go', | |
| 27 'reload', | 22 'reload', |
| 28 'stop', | 23 'stop', |
| 29 'terminate' | 24 'terminate' |
| 30 ]; | 25 ]; |
| 31 | 26 |
| 32 var WEB_VIEW_EVENTS = { | 27 var WEB_VIEW_EVENTS = { |
| 33 'close': [], | 28 'close': [], |
| 34 'consolemessage': ['level', 'message', 'line', 'sourceId'], | 29 'consolemessage': ['level', 'message', 'line', 'sourceId'], |
| 35 'contentload' : [], | 30 'contentload' : [], |
| 36 'exit' : ['processId', 'reason'], | 31 'exit' : ['processId', 'reason'], |
| (...skipping 24 matching lines...) Expand all Loading... |
| 61 window.addEventListener('readystatechange', function(e) { | 56 window.addEventListener('readystatechange', function(e) { |
| 62 if (document.readyState != 'loading') { | 57 if (document.readyState != 'loading') { |
| 63 return; | 58 return; |
| 64 } | 59 } |
| 65 | 60 |
| 66 document.addEventListener('DOMContentLoaded', function(e) { | 61 document.addEventListener('DOMContentLoaded', function(e) { |
| 67 watchForTag('WEBVIEW', function(addedNode) { new WebView(addedNode); }); | 62 watchForTag('WEBVIEW', function(addedNode) { new WebView(addedNode); }); |
| 68 }); | 63 }); |
| 69 }, true /* useCapture */); | 64 }, true /* useCapture */); |
| 70 | 65 |
| 66 |
| 67 /** @type {number} */ |
| 68 WebView.prototype.entryCount_; |
| 69 |
| 70 /** @type {number} */ |
| 71 WebView.prototype.currentEntryIndex_; |
| 72 |
| 71 /** | 73 /** |
| 72 * @constructor | 74 * @constructor |
| 73 */ | 75 */ |
| 74 function WebView(webviewNode) { | 76 function WebView(webviewNode) { |
| 75 this.webviewNode_ = webviewNode; | 77 this.webviewNode_ = webviewNode; |
| 76 this.browserPluginNode_ = this.createBrowserPluginNode_(); | 78 this.browserPluginNode_ = this.createBrowserPluginNode_(); |
| 77 var shadowRoot = this.webviewNode_.webkitCreateShadowRoot(); | 79 var shadowRoot = this.webviewNode_.webkitCreateShadowRoot(); |
| 78 shadowRoot.appendChild(this.browserPluginNode_); | 80 shadowRoot.appendChild(this.browserPluginNode_); |
| 79 | 81 |
| 80 this.setupFocusPropagation_(); | 82 this.setupFocusPropagation_(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 self.browserPluginNode_.blur(); | 139 self.browserPluginNode_.blur(); |
| 138 }); | 140 }); |
| 139 }; | 141 }; |
| 140 | 142 |
| 141 /** | 143 /** |
| 142 * @private | 144 * @private |
| 143 */ | 145 */ |
| 144 WebView.prototype.setupWebviewNodeMethods_ = function() { | 146 WebView.prototype.setupWebviewNodeMethods_ = function() { |
| 145 // this.browserPluginNode_[apiMethod] are not necessarily defined immediately | 147 // this.browserPluginNode_[apiMethod] are not necessarily defined immediately |
| 146 // after the shadow object is appended to the shadow root. | 148 // after the shadow object is appended to the shadow root. |
| 149 var webviewNode = this.webviewNode_; |
| 150 var browserPluginNode = this.browserPluginNode_; |
| 147 var self = this; | 151 var self = this; |
| 152 |
| 153 webviewNode['canGoBack'] = function() { |
| 154 return self.entryCount_ > 1 && self.currentEntryIndex_ > 0; |
| 155 }; |
| 156 |
| 157 webviewNode['canGoForward'] = function() { |
| 158 return self.currentEntryIndex_ >=0 && |
| 159 self.currentEntryIndex_ < (self.entryCount_ - 1); |
| 160 }; |
| 161 |
| 162 webviewNode['back'] = function() { |
| 163 webviewNode.go(-1); |
| 164 }; |
| 165 |
| 166 webviewNode['forward'] = function() { |
| 167 webviewNode.go(1); |
| 168 }; |
| 169 |
| 170 webviewNode['go'] = function(relativeIndex) { |
| 171 var instanceId = browserPluginNode.getGuestInstanceId(); |
| 172 if (!instanceId) |
| 173 return; |
| 174 chrome.webview.go(instanceId, relativeIndex); |
| 175 }; |
| 176 |
| 148 $Array.forEach(WEB_VIEW_API_METHODS, function(apiMethod) { | 177 $Array.forEach(WEB_VIEW_API_METHODS, function(apiMethod) { |
| 149 self.webviewNode_[apiMethod] = function(var_args) { | 178 webviewNode[apiMethod] = function(var_args) { |
| 150 return $Function.apply(self.browserPluginNode_[apiMethod], | 179 return browserPluginNode[apiMethod].apply(browserPluginNode, arguments); |
| 151 self.browserPluginNode_, arguments); | |
| 152 }; | 180 }; |
| 153 }, this); | 181 }, this); |
| 154 this.setupExecuteCodeAPI_(); | 182 this.setupExecuteCodeAPI_(); |
| 155 }; | 183 }; |
| 156 | 184 |
| 157 /** | 185 /** |
| 158 * @private | 186 * @private |
| 159 */ | 187 */ |
| 160 WebView.prototype.setupWebviewNodeProperties_ = function() { | 188 WebView.prototype.setupWebviewNodeProperties_ = function() { |
| 161 var ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE = '<webview>: ' + | 189 var ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE = '<webview>: ' + |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 if (newValue != oldValue) { | 295 if (newValue != oldValue) { |
| 268 this.webviewNode_.setAttribute(mutation.attributeName, newValue); | 296 this.webviewNode_.setAttribute(mutation.attributeName, newValue); |
| 269 } | 297 } |
| 270 } | 298 } |
| 271 }; | 299 }; |
| 272 | 300 |
| 273 /** | 301 /** |
| 274 * @private | 302 * @private |
| 275 */ | 303 */ |
| 276 WebView.prototype.setupWebviewNodeEvents_ = function() { | 304 WebView.prototype.setupWebviewNodeEvents_ = function() { |
| 305 var self = this; |
| 277 var webviewNode = this.webviewNode_; | 306 var webviewNode = this.webviewNode_; |
| 278 // TODO(fsamuel): Generalize this further as we add more events. | 307 // TODO(fsamuel): Generalize this further as we add more events. |
| 279 var onAttached = function(e) { | 308 var onAttached = function(e) { |
| 280 var detail = e.detail ? JSON.parse(e.detail) : {}; | 309 var detail = e.detail ? JSON.parse(e.detail) : {}; |
| 281 loadCommitEvent.addListener(function(event) { | 310 loadCommitEvent.addListener(function(event) { |
| 282 var webviewEvent = new Event('loadcommit', {bubbles: true}); | 311 var webviewEvent = new Event('loadcommit', {bubbles: true}); |
| 283 var attribs = WEB_VIEW_EVENTS['loadcommit']; | 312 var attribs = WEB_VIEW_EVENTS['loadcommit']; |
| 284 $Array.forEach(attribs, function(attribName) { | 313 $Array.forEach(attribs, function(attribName) { |
| 285 webviewEvent[attribName] = event[attribName]; | 314 webviewEvent[attribName] = event[attribName]; |
| 286 }); | 315 }); |
| 316 self.currentEntryIndex_ = event.currentEntryIndex; |
| 317 self.entryCount_ = event.entryCount; |
| 287 webviewNode.dispatchEvent(webviewEvent); | 318 webviewNode.dispatchEvent(webviewEvent); |
| 288 }, {instanceId: detail.windowId}); | 319 }, {instanceId: detail.windowId}); |
| 289 }; | 320 }; |
| 290 this.browserPluginNode_.addEventListener('-internal-attached', onAttached); | 321 this.browserPluginNode_.addEventListener('-internal-attached', onAttached); |
| 291 | 322 |
| 292 for (var eventName in WEB_VIEW_EVENTS) { | 323 for (var eventName in WEB_VIEW_EVENTS) { |
| 293 this.setupEvent_(eventName, WEB_VIEW_EVENTS[eventName]); | 324 this.setupEvent_(eventName, WEB_VIEW_EVENTS[eventName]); |
| 294 } | 325 } |
| 295 this.setupNewWindowEvent_(); | 326 this.setupNewWindowEvent_(); |
| 296 this.setupPermissionEvent_(); | 327 this.setupPermissionEvent_(); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 return []; | 540 return []; |
| 510 }; | 541 }; |
| 511 | 542 |
| 512 /** | 543 /** |
| 513 * Implemented when the experimental API is available. | 544 * Implemented when the experimental API is available. |
| 514 * @private | 545 * @private |
| 515 */ | 546 */ |
| 516 WebView.prototype.maybeSetupExperimentalAPI_ = function() {}; | 547 WebView.prototype.maybeSetupExperimentalAPI_ = function() {}; |
| 517 | 548 |
| 518 exports.WebView = WebView; | 549 exports.WebView = WebView; |
| OLD | NEW |