OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 // This module implements the shared functionality for different guestview | 5 // This module implements the shared functionality for different guestview |
6 // containers, such as web_view, app_view, etc. | 6 // containers, such as web_view, app_view, etc. |
7 | 7 |
8 var DocumentNatives = requireNative('document_natives'); | 8 var DocumentNatives = requireNative('document_natives'); |
9 var GuestView = require('guestView').GuestView; | 9 var GuestView = require('guestView').GuestView; |
10 var GuestViewInternalNatives = requireNative('guest_view_internal'); | 10 var GuestViewInternalNatives = requireNative('guest_view_internal'); |
11 var IdGenerator = requireNative('id_generator'); | 11 var IdGenerator = requireNative('id_generator'); |
12 | 12 |
13 function GuestViewContainer(element, viewType) { | 13 function GuestViewContainer(element, viewType) { |
14 privates(element).internal = this; | 14 privates(element).internal = this; |
15 this.attributes = {}; | 15 this.attributes = {}; |
16 this.element = element; | 16 this.element = element; |
17 this.elementAttached = false; | 17 this.elementAttached = false; |
18 this.viewInstanceId = IdGenerator.GetNextId(); | 18 this.viewInstanceId = IdGenerator.GetNextId(); |
19 this.viewType = viewType; | 19 this.viewType = viewType; |
20 | 20 |
21 this.setupGuestProperty(); | 21 this.setupGuestProperty(); |
22 this.guest = new GuestView(viewType); | 22 this.guest = new GuestView(viewType); |
23 this.setupAttributes(); | 23 this.setupAttributes(); |
24 | 24 |
25 privates(this).browserPluginElement = this.createBrowserPluginElement(); | 25 privates(this).browserPluginElement = this.createBrowserPluginElement(); |
26 this.guest.setBrowserPluginElement(privates(this).browserPluginElement); | |
Fady Samuel
2015/05/26 16:42:15
Why is this necessary? Also, guests can change the
| |
26 this.setupFocusPropagation(); | 27 this.setupFocusPropagation(); |
27 var shadowRoot = this.element.createShadowRoot(); | 28 var shadowRoot = this.element.createShadowRoot(); |
28 shadowRoot.appendChild(privates(this).browserPluginElement); | 29 shadowRoot.appendChild(privates(this).browserPluginElement); |
29 } | 30 } |
30 | 31 |
31 // Forward public API methods from |proto| to their internal implementations. | 32 // Forward public API methods from |proto| to their internal implementations. |
32 GuestViewContainer.forwardApiMethods = function(proto, apiMethods) { | 33 GuestViewContainer.forwardApiMethods = function(proto, apiMethods) { |
33 var createProtoHandler = function(m) { | 34 var createProtoHandler = function(m) { |
34 return function(var_args) { | 35 return function(var_args) { |
35 var internal = privates(this).internal; | 36 var internal = privates(this).internal; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 | 85 |
85 GuestViewContainer.prototype.createBrowserPluginElement = function() { | 86 GuestViewContainer.prototype.createBrowserPluginElement = function() { |
86 // We create BrowserPlugin as a custom element in order to observe changes | 87 // We create BrowserPlugin as a custom element in order to observe changes |
87 // to attributes synchronously. | 88 // to attributes synchronously. |
88 var browserPluginElement = | 89 var browserPluginElement = |
89 new GuestViewContainer[this.viewType + 'BrowserPlugin'](); | 90 new GuestViewContainer[this.viewType + 'BrowserPlugin'](); |
90 privates(browserPluginElement).internal = this; | 91 privates(browserPluginElement).internal = this; |
91 return browserPluginElement; | 92 return browserPluginElement; |
92 }; | 93 }; |
93 | 94 |
95 GuestViewContainer.prototype.getBrowserPluginElement = function() { | |
96 return privates(this).browserPluginElement; | |
97 }; | |
98 | |
94 GuestViewContainer.prototype.setupFocusPropagation = function() { | 99 GuestViewContainer.prototype.setupFocusPropagation = function() { |
95 if (!this.element.hasAttribute('tabIndex')) { | 100 if (!this.element.hasAttribute('tabIndex')) { |
96 // GuestViewContainer needs a tabIndex in order to be focusable. | 101 // GuestViewContainer needs a tabIndex in order to be focusable. |
97 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute | 102 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute |
98 // to allow GuestViewContainer to be focusable. | 103 // to allow GuestViewContainer to be focusable. |
99 // See http://crbug.com/231664. | 104 // See http://crbug.com/231664. |
100 this.element.setAttribute('tabIndex', -1); | 105 this.element.setAttribute('tabIndex', -1); |
101 } | 106 } |
102 this.element.addEventListener('focus', function(e) { | 107 this.element.addEventListener('focus', function(e) { |
103 // Focus the BrowserPlugin when the GuestViewContainer takes focus. | 108 // Focus the BrowserPlugin when the GuestViewContainer takes focus. |
104 privates(this).browserPluginElement.focus(); | 109 privates(this).browserPluginElement.focus(); |
105 }.bind(this)); | 110 }.bind(this)); |
106 this.element.addEventListener('blur', function(e) { | 111 this.element.addEventListener('blur', function(e) { |
107 // Blur the BrowserPlugin when the GuestViewContainer loses focus. | 112 // Blur the BrowserPlugin when the GuestViewContainer loses focus. |
108 privates(this).browserPluginElement.blur(); | 113 privates(this).browserPluginElement.blur(); |
109 }.bind(this)); | 114 }.bind(this)); |
110 }; | 115 }; |
111 | 116 |
112 GuestViewContainer.prototype.attachWindow = function() { | 117 GuestViewContainer.prototype.attachWindow = function() { |
113 if (!this.internalInstanceId) { | 118 if (!this.internalInstanceId) { |
114 return true; | 119 return true; |
115 } | 120 } |
116 | 121 |
117 this.guest.attach(this.internalInstanceId, | 122 this.guest.attach(this.internalInstanceId, |
118 this.viewInstanceId, | 123 this.viewInstanceId, |
119 this.buildParams()); | 124 this.buildParams()); |
120 return true; | 125 return true; |
121 }; | 126 }; |
122 | 127 |
128 GuestViewContainer.prototype.onInternalInstanceID = function( | |
129 internalInstanceId) { | |
130 window.console.log('onInternalInstanceID: ' + internalInstanceId); | |
131 this.internalInstanceId = internalInstanceId; | |
132 | |
133 // Track when the element resizes using the element resize callback. | |
134 GuestViewInternalNatives.RegisterElementResizeCallback( | |
135 this.internalInstanceId, this.onElementResize.bind(this)); | |
136 | |
137 window.console.log('this.guest.getId() = ' + | |
138 this.guest.getId()); | |
139 if (!this.guest.getId()) { | |
140 return; | |
141 } | |
142 this.guest.attach(this.internalInstanceId, | |
143 this.viewInstanceId, | |
144 this.buildParams()); | |
145 }; | |
146 | |
123 GuestViewContainer.prototype.handleBrowserPluginAttributeMutation = | 147 GuestViewContainer.prototype.handleBrowserPluginAttributeMutation = |
124 function(name, oldValue, newValue) { | 148 function(name, oldValue, newValue) { |
125 if (name == 'internalinstanceid' && !oldValue && !!newValue) { | 149 if (name == 'internalinstanceid' && !oldValue && !!newValue) { |
126 privates(this).browserPluginElement.removeAttribute('internalinstanceid'); | 150 privates(this).browserPluginElement.removeAttribute('internalinstanceid'); |
127 this.internalInstanceId = parseInt(newValue); | 151 this.onInternalInstanceID(parseInt(newValue)); |
128 | |
129 // Track when the element resizes using the element resize callback. | |
130 GuestViewInternalNatives.RegisterElementResizeCallback( | |
131 this.internalInstanceId, this.onElementResize.bind(this)); | |
132 | |
133 if (!this.guest.getId()) { | |
134 return; | |
135 } | |
136 this.guest.attach(this.internalInstanceId, | |
137 this.viewInstanceId, | |
138 this.buildParams()); | |
139 } | 152 } |
140 }; | 153 }; |
141 | 154 |
142 GuestViewContainer.prototype.onElementResize = function(oldWidth, oldHeight, | 155 GuestViewContainer.prototype.onElementResize = function(oldWidth, oldHeight, |
143 newWidth, newHeight) { | 156 newWidth, newHeight) { |
144 // Dispatch the 'resize' event. | 157 // Dispatch the 'resize' event. |
145 var resizeEvent = new Event('resize', { bubbles: true }); | 158 var resizeEvent = new Event('resize', { bubbles: true }); |
146 resizeEvent.oldWidth = oldWidth; | 159 resizeEvent.oldWidth = oldWidth; |
147 resizeEvent.oldHeight = oldHeight; | 160 resizeEvent.oldHeight = oldHeight; |
148 resizeEvent.newWidth = newWidth; | 161 resizeEvent.newWidth = newWidth; |
(...skipping 27 matching lines...) Expand all Loading... | |
176 } | 189 } |
177 | 190 |
178 // Implemented by the specific view type, if needed. | 191 // Implemented by the specific view type, if needed. |
179 GuestViewContainer.prototype.buildContainerParams = function() { return {}; }; | 192 GuestViewContainer.prototype.buildContainerParams = function() { return {}; }; |
180 GuestViewContainer.prototype.onElementAttached = function() {}; | 193 GuestViewContainer.prototype.onElementAttached = function() {}; |
181 GuestViewContainer.prototype.onElementDetached = function() {}; | 194 GuestViewContainer.prototype.onElementDetached = function() {}; |
182 GuestViewContainer.prototype.setupAttributes = function() {}; | 195 GuestViewContainer.prototype.setupAttributes = function() {}; |
183 | 196 |
184 // Registers the browser plugin <object> custom element. |viewType| is the | 197 // Registers the browser plugin <object> custom element. |viewType| is the |
185 // name of the specific guestview container (e.g. 'webview'). | 198 // name of the specific guestview container (e.g. 'webview'). |
186 function registerBrowserPluginElement(viewType) { | 199 function registerBrowserPluginElement(viewType) { |
Fady Samuel
2015/05/26 16:42:15
Is this at all necessary in sitePerProcess?
lazyboy
2015/05/29 00:02:24
This function would register the custom element in
| |
187 var proto = $Object.create(HTMLElement.prototype); | 200 var isSitePerProcess = GuestViewInternalNatives.IsSitePerProcess(); |
201 var proto = $Object.create(isSitePerProcess ? HTMLIFrameElement.prototype | |
202 : HTMLElement.prototype); | |
203 | |
204 window.console.log('isSitePerProcess: ' + isSitePerProcess); | |
188 | 205 |
189 proto.createdCallback = function() { | 206 proto.createdCallback = function() { |
190 this.setAttribute('type', 'application/browser-plugin'); | 207 if (!isSitePerProcess) { |
191 this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId()); | 208 this.setAttribute('type', 'application/browser-plugin'); |
209 this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId()); | |
210 } | |
192 this.style.width = '100%'; | 211 this.style.width = '100%'; |
193 this.style.height = '100%'; | 212 this.style.height = '100%'; |
194 }; | 213 }; |
195 | 214 |
196 proto.attachedCallback = function() { | 215 proto.attachedCallback = function() { |
197 // Load the plugin immediately. | 216 // Load the plugin immediately. |
198 var unused = this.nonExistentAttribute; | 217 var unused = this.nonExistentAttribute; |
199 }; | 218 }; |
200 | 219 |
201 proto.attributeChangedCallback = function(name, oldValue, newValue) { | 220 if (!isSitePerProcess) { |
202 var internal = privates(this).internal; | 221 proto.attributeChangedCallback = function(name, oldValue, newValue) { |
203 if (!internal) { | 222 var internal = privates(this).internal; |
204 return; | 223 if (!internal) { |
205 } | 224 return; |
206 internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue); | 225 } |
207 }; | 226 internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue); |
227 }; | |
228 } | |
208 | 229 |
230 var options = {prototype: proto}; | |
231 options.extends = isSitePerProcess ? 'iframe' : 'object'; | |
209 GuestViewContainer[viewType + 'BrowserPlugin'] = | 232 GuestViewContainer[viewType + 'BrowserPlugin'] = |
210 DocumentNatives.RegisterElement(viewType + 'browserplugin', | 233 DocumentNatives.RegisterElement(viewType + 'browserplugin', options); |
211 {extends: 'object', prototype: proto}); | |
212 | 234 |
213 delete proto.createdCallback; | 235 delete proto.createdCallback; |
214 delete proto.attachedCallback; | 236 delete proto.attachedCallback; |
215 delete proto.detachedCallback; | 237 delete proto.detachedCallback; |
216 delete proto.attributeChangedCallback; | 238 delete proto.attributeChangedCallback; |
217 }; | 239 }; |
218 | 240 |
219 // Registers the guestview container as a custom element. | 241 // Registers the guestview container as a custom element. |
220 // |guestViewContainerType| is the type of guestview container | 242 // |guestViewContainerType| is the type of guestview container |
221 // (e.g.WebViewImpl). | 243 // (e.g.WebViewImpl). |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 // Delete the callbacks so developers cannot call them and produce unexpected | 292 // Delete the callbacks so developers cannot call them and produce unexpected |
271 // behavior. | 293 // behavior. |
272 delete proto.createdCallback; | 294 delete proto.createdCallback; |
273 delete proto.attachedCallback; | 295 delete proto.attachedCallback; |
274 delete proto.detachedCallback; | 296 delete proto.detachedCallback; |
275 delete proto.attributeChangedCallback; | 297 delete proto.attributeChangedCallback; |
276 } | 298 } |
277 | 299 |
278 // Exports. | 300 // Exports. |
279 exports.GuestViewContainer = GuestViewContainer; | 301 exports.GuestViewContainer = GuestViewContainer; |
OLD | NEW |