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 chrome = requireNative('chrome').GetChrome(); |
| 11 var forEach = require('utils').forEach; |
10 var watchForTag = require('tagWatcher').watchForTag; | 12 var watchForTag = require('tagWatcher').watchForTag; |
11 | 13 |
12 var chrome = requireNative('chrome').GetChrome(); | |
13 | |
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 // All exposed api methods for <webview>, these are forwarded to the browser | 17 // All exposed api methods for <webview>, these are forwarded to the browser |
18 // plugin. | 18 // plugin. |
19 var WEB_VIEW_API_METHODS = [ | 19 var WEB_VIEW_API_METHODS = [ |
20 'back', | 20 'back', |
21 'canGoBack', | 21 'canGoBack', |
22 'canGoForward', | 22 'canGoForward', |
23 'forward', | 23 'forward', |
(...skipping 23 matching lines...) Expand all Loading... |
47 */ | 47 */ |
48 function WebView(node) { | 48 function WebView(node) { |
49 this.node_ = node; | 49 this.node_ = node; |
50 var shadowRoot = node.webkitCreateShadowRoot(); | 50 var shadowRoot = node.webkitCreateShadowRoot(); |
51 | 51 |
52 this.objectNode_ = document.createElement('object'); | 52 this.objectNode_ = document.createElement('object'); |
53 this.objectNode_.type = 'application/browser-plugin'; | 53 this.objectNode_.type = 'application/browser-plugin'; |
54 // The <object> node fills in the <webview> container. | 54 // The <object> node fills in the <webview> container. |
55 this.objectNode_.style.width = '100%'; | 55 this.objectNode_.style.width = '100%'; |
56 this.objectNode_.style.height = '100%'; | 56 this.objectNode_.style.height = '100%'; |
57 WEB_VIEW_ATTRIBUTES.forEach(function(attributeName) { | 57 forEach(WEB_VIEW_ATTRIBUTES, function(i, attributeName) { |
58 // Only copy attributes that have been assigned values, rather than copying | 58 // Only copy attributes that have been assigned values, rather than copying |
59 // a series of undefined attributes to BrowserPlugin. | 59 // a series of undefined attributes to BrowserPlugin. |
60 if (this.node_.hasAttribute(attributeName)) { | 60 if (this.node_.hasAttribute(attributeName)) { |
61 this.objectNode_.setAttribute( | 61 this.objectNode_.setAttribute( |
62 attributeName, this.node_.getAttribute(attributeName)); | 62 attributeName, this.node_.getAttribute(attributeName)); |
63 } | 63 } |
64 }, this); | 64 }, this); |
65 | 65 |
66 shadowRoot.appendChild(this.objectNode_); | 66 shadowRoot.appendChild(this.objectNode_); |
67 | 67 |
68 // this.objectNode_[apiMethod] are not necessarily defined immediately after | 68 // this.objectNode_[apiMethod] are not necessarily defined immediately after |
69 // the shadow object is appended to the shadow root. | 69 // the shadow object is appended to the shadow root. |
70 var self = this; | 70 var self = this; |
71 WEB_VIEW_API_METHODS.forEach(function(apiMethod) { | 71 forEach(WEB_VIEW_API_METHODS, function(i, apiMethod) { |
72 node[apiMethod] = function(var_args) { | 72 node[apiMethod] = function(var_args) { |
73 return self.objectNode_[apiMethod].apply(self.objectNode_, arguments); | 73 return self.objectNode_[apiMethod].apply(self.objectNode_, arguments); |
74 }; | 74 }; |
75 }, this); | 75 }, this); |
76 | 76 |
77 // Map attribute modifications on the <webview> tag to property changes in | 77 // Map attribute modifications on the <webview> tag to property changes in |
78 // the underlying <object> node. | 78 // the underlying <object> node. |
79 var handleMutation = this.handleMutation_.bind(this); | 79 var handleMutation = function(i, mutation) { |
| 80 this.handleMutation_(mutation); |
| 81 }.bind(this); |
80 var observer = new WebKitMutationObserver(function(mutations) { | 82 var observer = new WebKitMutationObserver(function(mutations) { |
81 mutations.forEach(handleMutation); | 83 forEach(mutations, handleMutation); |
82 }); | 84 }); |
83 observer.observe( | 85 observer.observe( |
84 this.node_, | 86 this.node_, |
85 {attributes: true, attributeFilter: WEB_VIEW_ATTRIBUTES}); | 87 {attributes: true, attributeFilter: WEB_VIEW_ATTRIBUTES}); |
86 | 88 |
87 var handleObjectMutation = this.handleObjectMutation_.bind(this); | 89 var handleObjectMutation = function(i, mutation) { |
| 90 this.handleObjectMutation_(mutation); |
| 91 }.bind(this); |
88 var objectObserver = new WebKitMutationObserver(function(mutations) { | 92 var objectObserver = new WebKitMutationObserver(function(mutations) { |
89 mutations.forEach(handleObjectMutation); | 93 forEach(mutations, handleObjectMutation); |
90 }); | 94 }); |
91 objectObserver.observe( | 95 objectObserver.observe( |
92 this.objectNode_, | 96 this.objectNode_, |
93 {attributes: true, attributeFilter: WEB_VIEW_ATTRIBUTES}); | 97 {attributes: true, attributeFilter: WEB_VIEW_ATTRIBUTES}); |
94 | 98 |
95 var objectNode = this.objectNode_; | 99 var objectNode = this.objectNode_; |
96 // Expose getters and setters for the attributes. | 100 // Expose getters and setters for the attributes. |
97 WEB_VIEW_ATTRIBUTES.forEach(function(attributeName) { | 101 forEach(WEB_VIEW_ATTRIBUTES, function(i, attributeName) { |
98 Object.defineProperty(this.node_, attributeName, { | 102 Object.defineProperty(this.node_, attributeName, { |
99 get: function() { | 103 get: function() { |
100 return objectNode[attributeName]; | 104 return objectNode[attributeName]; |
101 }, | 105 }, |
102 set: function(value) { | 106 set: function(value) { |
103 objectNode[attributeName] = value; | 107 objectNode[attributeName] = value; |
104 }, | 108 }, |
105 enumerable: true | 109 enumerable: true |
106 }); | 110 }); |
107 }, this); | 111 }, this); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 }; | 172 }; |
169 | 173 |
170 /** | 174 /** |
171 * @private | 175 * @private |
172 */ | 176 */ |
173 WebView.prototype.setupEvent_ = function(eventname, attribs) { | 177 WebView.prototype.setupEvent_ = function(eventname, attribs) { |
174 var node = this.node_; | 178 var node = this.node_; |
175 this.objectNode_.addEventListener('-internal-' + eventname, function(e) { | 179 this.objectNode_.addEventListener('-internal-' + eventname, function(e) { |
176 var evt = new Event(eventname, { bubbles: true }); | 180 var evt = new Event(eventname, { bubbles: true }); |
177 var detail = e.detail ? JSON.parse(e.detail) : {}; | 181 var detail = e.detail ? JSON.parse(e.detail) : {}; |
178 attribs.forEach(function(attribName) { | 182 forEach(attribs, function(i, attribName) { |
179 evt[attribName] = detail[attribName]; | 183 evt[attribName] = detail[attribName]; |
180 }); | 184 }); |
181 node.dispatchEvent(evt); | 185 node.dispatchEvent(evt); |
182 }); | 186 }); |
183 }; | 187 }; |
184 | 188 |
185 /** | 189 /** |
186 * Implemented when experimental permission is available. | 190 * Implemented when experimental permission is available. |
187 * @private | 191 * @private |
188 */ | 192 */ |
189 WebView.prototype.maybeSetupPermissionEvent_ = function() {}; | 193 WebView.prototype.maybeSetupPermissionEvent_ = function() {}; |
190 | 194 |
191 /** | 195 /** |
192 * Implemented when experimental permission is available. | 196 * Implemented when experimental permission is available. |
193 * @private | 197 * @private |
194 */ | 198 */ |
195 WebView.prototype.maybeSetupExecuteScript_ = function() {}; | 199 WebView.prototype.maybeSetupExecuteScript_ = function() {}; |
196 | 200 |
197 exports.WebView = WebView; | 201 exports.WebView = WebView; |
OLD | NEW |