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 // This module implements WebView (<webview>) as a custom element that wraps a | 5 // This module implements WebView (<webview>) as a custom element that wraps a |
6 // BrowserPlugin object element. The object element is hidden within | 6 // BrowserPlugin object element. The object element is hidden within |
7 // the shadow DOM of the WebView element. | 7 // the shadow DOM of the WebView element. |
8 | 8 |
9 var DocumentNatives = requireNative('document_natives'); | 9 var DocumentNatives = requireNative('document_natives'); |
10 var GuestViewInternal = | 10 var GuestViewInternal = |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 | 122 |
123 // Validation helper function for executeScript() and insertCSS(). | 123 // Validation helper function for executeScript() and insertCSS(). |
124 WebView.prototype.validateExecuteCodeCall = function() { | 124 WebView.prototype.validateExecuteCodeCall = function() { |
125 if (!this.guestInstanceId) { | 125 if (!this.guestInstanceId) { |
126 throw new Error(WebViewConstants.ERROR_MSG_CANNOT_INJECT_SCRIPT); | 126 throw new Error(WebViewConstants.ERROR_MSG_CANNOT_INJECT_SCRIPT); |
127 } | 127 } |
128 }; | 128 }; |
129 | 129 |
130 WebView.prototype.setupAutoSizeProperties = function() { | 130 WebView.prototype.setupAutoSizeProperties = function() { |
131 $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) { | 131 $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) { |
132 this.attributes[attributeName].setValue( | |
133 this.webviewNode.getAttribute(attributeName)); | |
134 Object.defineProperty(this.webviewNode, attributeName, { | 132 Object.defineProperty(this.webviewNode, attributeName, { |
135 get: function() { | 133 get: function() { |
136 return this.attributes[attributeName].getValue(); | 134 return this.attributes[attributeName].getValue(); |
137 }.bind(this), | 135 }.bind(this), |
138 set: function(value) { | 136 set: function(value) { |
139 this.webviewNode.setAttribute(attributeName, value); | 137 this.attributes[attributeName].setValue(value); |
140 }.bind(this), | 138 }.bind(this), |
141 enumerable: true | 139 enumerable: true |
142 }); | 140 }); |
143 }.bind(this), this); | 141 }.bind(this), this); |
144 }; | 142 }; |
145 | 143 |
146 WebView.prototype.setupWebviewNodeProperties = function() { | 144 WebView.prototype.setupWebviewNodeProperties = function() { |
147 this.setupAutoSizeProperties(); | 145 this.setupAutoSizeProperties(); |
148 | 146 |
149 Object.defineProperty(this.webviewNode, | 147 Object.defineProperty(this.webviewNode, |
150 WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, { | 148 WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, { |
151 get: function() { | 149 get: function() { |
152 return this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY]. | 150 return this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY]. |
153 getValue(); | 151 getValue(); |
154 }.bind(this), | 152 }.bind(this), |
155 set: function(value) { | 153 set: function(value) { |
156 this.webviewNode.setAttribute( | 154 this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY]. |
157 WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, | 155 setValue(value); |
158 value); | |
159 }.bind(this), | 156 }.bind(this), |
160 enumerable: true | 157 enumerable: true |
161 }); | 158 }); |
162 | 159 |
163 // We cannot use {writable: true} property descriptor because we want a | 160 // We cannot use {writable: true} property descriptor because we want a |
164 // dynamic getter value. | 161 // dynamic getter value. |
165 Object.defineProperty(this.webviewNode, 'contentWindow', { | 162 Object.defineProperty(this.webviewNode, 'contentWindow', { |
166 get: function() { | 163 get: function() { |
167 if (this.contentWindow) { | 164 if (this.contentWindow) { |
168 return this.contentWindow; | 165 return this.contentWindow; |
169 } | 166 } |
170 window.console.error( | 167 window.console.error( |
171 WebViewConstants.ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE); | 168 WebViewConstants.ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE); |
172 }.bind(this), | 169 }.bind(this), |
173 // No setter. | 170 // No setter. |
174 enumerable: true | 171 enumerable: true |
175 }); | 172 }); |
176 | 173 |
177 Object.defineProperty(this.webviewNode, WebViewConstants.ATTRIBUTE_NAME, { | 174 Object.defineProperty(this.webviewNode, WebViewConstants.ATTRIBUTE_NAME, { |
178 get: function() { | 175 get: function() { |
179 return this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue(); | 176 return this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue(); |
180 }.bind(this), | 177 }.bind(this), |
181 set: function(value) { | 178 set: function(value) { |
182 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_NAME, value); | 179 this.attributes[WebViewConstants.ATTRIBUTE_NAME].setValue(value); |
183 }.bind(this), | 180 }.bind(this), |
184 enumerable: true | 181 enumerable: true |
185 }); | 182 }); |
186 | 183 |
187 Object.defineProperty(this.webviewNode, | 184 Object.defineProperty(this.webviewNode, |
188 WebViewConstants.ATTRIBUTE_PARTITION, { | 185 WebViewConstants.ATTRIBUTE_PARTITION, { |
189 get: function() { | 186 get: function() { |
190 return this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].getValue(); | 187 return this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].getValue(); |
191 }.bind(this), | 188 }.bind(this), |
192 set: function(value) { | 189 set: function(value) { |
193 var result = this.attributes[WebViewConstants.ATTRIBUTE_PARTITION]. | 190 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue(value); |
194 setValue(value); | |
195 if (result.error) { | |
196 throw result.error; | |
197 } | |
198 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_PARTITION, | |
199 value); | |
200 }.bind(this), | 191 }.bind(this), |
201 enumerable: true | 192 enumerable: true |
202 }); | 193 }); |
203 | 194 |
204 this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue( | |
205 this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_SRC)); | |
206 Object.defineProperty(this.webviewNode, WebViewConstants.ATTRIBUTE_SRC, { | 195 Object.defineProperty(this.webviewNode, WebViewConstants.ATTRIBUTE_SRC, { |
207 get: function() { | 196 get: function() { |
208 return this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue(); | 197 return this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue(); |
209 }.bind(this), | 198 }.bind(this), |
210 set: function(value) { | 199 set: function(value) { |
211 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, value); | 200 this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue(value); |
212 }.bind(this), | 201 }.bind(this), |
213 enumerable: true | 202 enumerable: true |
214 }); | 203 }); |
215 }; | 204 }; |
216 | 205 |
217 // The purpose of this mutation observer is to catch assignment to the src | 206 // The purpose of this mutation observer is to catch assignment to the src |
218 // attribute without any changes to its value. This is useful in the case | 207 // attribute without any changes to its value. This is useful in the case |
219 // where the webview guest has crashed and navigating to the same address | 208 // where the webview guest has crashed and navigating to the same address |
220 // spawns off a new process. | 209 // spawns off a new process. |
221 WebView.prototype.setupWebViewSrcAttributeMutationObserver = | 210 WebView.prototype.setupWebViewSrcAttributeMutationObserver = |
222 function() { | 211 function() { |
223 this.srcAndPartitionObserver = new MutationObserver(function(mutations) { | 212 this.srcAndPartitionObserver = new MutationObserver(function(mutations) { |
224 $Array.forEach(mutations, function(mutation) { | 213 $Array.forEach(mutations, function(mutation) { |
225 var oldValue = mutation.oldValue; | 214 var oldValue = mutation.oldValue; |
226 var newValue = this.webviewNode.getAttribute(mutation.attributeName); | 215 var newValue = this.attributes[mutation.attributeName].getValue(); |
227 if (oldValue != newValue) { | 216 if (oldValue != newValue) { |
228 return; | 217 return; |
229 } | 218 } |
230 this.handleWebviewAttributeMutation( | 219 this.handleWebviewAttributeMutation( |
231 mutation.attributeName, oldValue, newValue); | 220 mutation.attributeName, oldValue, newValue); |
232 }.bind(this)); | 221 }.bind(this)); |
233 }.bind(this)); | 222 }.bind(this)); |
234 var params = { | 223 var params = { |
235 attributes: true, | 224 attributes: true, |
236 attributeOldValue: true, | 225 attributeOldValue: true, |
237 attributeFilter: [WebViewConstants.ATTRIBUTE_SRC, | 226 attributeFilter: [WebViewConstants.ATTRIBUTE_SRC, |
238 WebViewConstants.ATTRIBUTE_PARTITION] | 227 WebViewConstants.ATTRIBUTE_PARTITION] |
239 }; | 228 }; |
240 this.srcAndPartitionObserver.observe(this.webviewNode, params); | 229 this.srcAndPartitionObserver.observe(this.webviewNode, params); |
241 }; | 230 }; |
242 | 231 |
243 // This observer monitors mutations to attributes of the <webview> and | 232 // This observer monitors mutations to attributes of the <webview> and |
244 // updates the BrowserPlugin properties accordingly. In turn, updating | 233 // updates the BrowserPlugin properties accordingly. In turn, updating |
245 // a BrowserPlugin property will update the corresponding BrowserPlugin | 234 // a BrowserPlugin property will update the corresponding BrowserPlugin |
246 // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more | 235 // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more |
247 // details. | 236 // details. |
248 WebView.prototype.handleWebviewAttributeMutation = | 237 WebView.prototype.handleWebviewAttributeMutation = |
249 function(name, oldValue, newValue) { | 238 function(attributeName, oldValue, newValue) { |
250 if (AUTO_SIZE_ATTRIBUTES.indexOf(name) > -1) { | 239 // Certain changes (such as internally-initiated changes) to attributes should |
251 this.attributes[name].setValue(newValue); | 240 // not be handled normally. |
241 if (this.attributes[attributeName] && | |
242 this.attributes[attributeName].ignoreNextMutation) { | |
243 this.attributes[attributeName].ignoreNextMutation = false; | |
244 return; | |
245 } | |
246 | |
247 if (AUTO_SIZE_ATTRIBUTES.indexOf(attributeName) > -1) { | |
252 if (!this.guestInstanceId) { | 248 if (!this.guestInstanceId) { |
253 return; | 249 return; |
254 } | 250 } |
255 // Convert autosize attribute to boolean. | |
256 var autosize = this.webviewNode.hasAttribute( | |
257 WebViewConstants.ATTRIBUTE_AUTOSIZE); | |
258 GuestViewInternal.setAutoSize(this.guestInstanceId, { | 251 GuestViewInternal.setAutoSize(this.guestInstanceId, { |
259 'enableAutoSize': autosize, | 252 'enableAutoSize': this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE]. |
253 getValue(), | |
260 'min': { | 254 'min': { |
261 'width': parseInt(this. | 255 'width': parseInt(this. |
262 attributes[WebViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0), | 256 attributes[WebViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0), |
263 'height': parseInt(this. | 257 'height': parseInt(this. |
264 attributes[WebViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || 0) | 258 attributes[WebViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || 0) |
265 }, | 259 }, |
266 'max': { | 260 'max': { |
267 'width': parseInt(this. | 261 'width': parseInt(this. |
268 attributes[WebViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || 0), | 262 attributes[WebViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || 0), |
269 'height': parseInt(this. | 263 'height': parseInt(this. |
270 attributes[WebViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || 0) | 264 attributes[WebViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || 0) |
271 } | 265 } |
272 }); | 266 }); |
273 return; | 267 return; |
274 } else if (name == WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY) { | 268 } else if (attributeName == WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY) { |
275 // We treat null attribute (attribute removed) and the empty string as | 269 // We treat null attribute (attribute removed) and the empty string as |
276 // one case. | 270 // one case. |
277 oldValue = oldValue || ''; | 271 oldValue = oldValue || ''; |
278 newValue = newValue || ''; | 272 newValue = newValue || ''; |
279 | 273 |
280 if (oldValue === newValue) { | 274 if (oldValue === newValue || !this.guestInstanceId) { |
281 return; | |
282 } | |
283 this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY]. | |
284 setValue(newValue != ''); | |
285 | |
286 if (!this.guestInstanceId) { | |
287 return; | 275 return; |
288 } | 276 } |
289 | 277 |
290 WebViewInternal.setAllowTransparency( | 278 WebViewInternal.setAllowTransparency( |
291 this.guestInstanceId, | 279 this.guestInstanceId, |
292 this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY]. | 280 this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY]. |
293 getValue()); | 281 getValue()); |
294 return; | 282 return; |
295 } else if (name == WebViewConstants.ATTRIBUTE_NAME) { | 283 } else if (attributeName == WebViewConstants.ATTRIBUTE_NAME) { |
296 // We treat null attribute (attribute removed) and the empty string as | 284 // We treat null attribute (attribute removed) and the empty string as |
297 // one case. | 285 // one case. |
298 oldValue = oldValue || ''; | 286 oldValue = oldValue || ''; |
299 newValue = newValue || ''; | 287 newValue = newValue || ''; |
300 | 288 |
301 if (oldValue === newValue) { | 289 if (oldValue === newValue) { |
302 return; | 290 return; |
303 } | 291 } |
304 this.attributes[WebViewConstants.ATTRIBUTE_NAME].setValue(newValue); | 292 |
305 if (!this.guestInstanceId) { | 293 if (!this.guestInstanceId) { |
306 return; | 294 return; |
307 } | 295 } |
308 WebViewInternal.setName(this.guestInstanceId, newValue); | 296 WebViewInternal.setName(this.guestInstanceId, newValue); |
309 return; | 297 return; |
310 } else if (name == WebViewConstants.ATTRIBUTE_SRC) { | 298 } else if (attributeName == WebViewConstants.ATTRIBUTE_SRC) { |
311 // We treat null attribute (attribute removed) and the empty string as | 299 // We treat null attribute (attribute removed) and the empty string as |
312 // one case. | 300 // one case. |
313 oldValue = oldValue || ''; | 301 oldValue = oldValue || ''; |
314 newValue = newValue || ''; | 302 newValue = newValue || ''; |
315 // Once we have navigated, we don't allow clearing the src attribute. | 303 // Once we have navigated, we don't allow clearing the src attribute. |
316 // Once <webview> enters a navigated state, it cannot be return back to a | 304 // Once <webview> enters a navigated state, it cannot return to a |
317 // placeholder state. | 305 // placeholder state. |
318 if (newValue == '' && oldValue != '') { | 306 if (newValue == '' && oldValue != '') { |
319 // src attribute changes normally initiate a navigation. We suppress | 307 // src attribute changes normally initiate a navigation. We suppress |
320 // the next src attribute handler call to avoid reloading the page | 308 // the next src attribute handler call to avoid reloading the page |
321 // on every guest-initiated navigation. | 309 // on every guest-initiated navigation. |
322 this.ignoreNextSrcAttributeChange = true; | 310 this.ignoreNextSrcAttributeChange = true; |
323 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, oldValue); | 311 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, oldValue); |
324 return; | 312 return; |
325 } | 313 } |
326 this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue(newValue); | 314 |
327 if (this.ignoreNextSrcAttributeChange) { | 315 if (this.ignoreNextSrcAttributeChange) { |
328 // Don't allow the src mutation observer to see this change. | 316 // Don't allow the src mutation observer to see this change. |
329 this.srcAndPartitionObserver.takeRecords(); | 317 this.srcAndPartitionObserver.takeRecords(); |
330 this.ignoreNextSrcAttributeChange = false; | 318 this.ignoreNextSrcAttributeChange = false; |
331 return; | 319 return; |
332 } | 320 } |
333 var result = {}; | 321 var result = {}; |
334 this.parseSrcAttribute(result); | 322 this.parseSrcAttribute(result); |
335 | 323 } else if (attributeName == WebViewConstants.ATTRIBUTE_PARTITION) { |
336 if (result.error) { | 324 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].handleMutation( |
337 throw result.error; | 325 oldValue, newValue); |
338 } | |
339 } else if (name == WebViewConstants.ATTRIBUTE_PARTITION) { | |
340 // Note that throwing error here won't synchronously propagate. | |
341 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue(newValue); | |
342 } | 326 } |
343 }; | 327 }; |
344 | 328 |
345 WebView.prototype.handleBrowserPluginAttributeMutation = | 329 WebView.prototype.handleBrowserPluginAttributeMutation = |
346 function(name, oldValue, newValue) { | 330 function(attributeName, oldValue, newValue) { |
347 if (name == WebViewConstants.ATTRIBUTE_INTERNALINSTANCEID && | 331 if (attributeName == WebViewConstants.ATTRIBUTE_INTERNALINSTANCEID && |
348 !oldValue && !!newValue) { | 332 !oldValue && !!newValue) { |
349 this.browserPluginNode.removeAttribute( | 333 this.browserPluginNode.removeAttribute( |
350 WebViewConstants.ATTRIBUTE_INTERNALINSTANCEID); | 334 WebViewConstants.ATTRIBUTE_INTERNALINSTANCEID); |
351 this.internalInstanceId = parseInt(newValue); | 335 this.internalInstanceId = parseInt(newValue); |
352 | 336 |
353 if (!!this.guestInstanceId && this.guestInstanceId != 0) { | 337 if (!!this.guestInstanceId && this.guestInstanceId != 0) { |
354 var isNewWindow = this.deferredAttachState ? | 338 var isNewWindow = this.deferredAttachState ? |
355 this.deferredAttachState.isNewWindow : false; | 339 this.deferredAttachState.isNewWindow : false; |
356 var params = this.buildAttachParams(isNewWindow); | 340 var params = this.buildAttachParams(isNewWindow); |
357 guestViewInternalNatives.AttachGuest( | 341 guestViewInternalNatives.AttachGuest( |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MINHEIGHT) && | 394 if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MINHEIGHT) && |
411 node[WebViewConstants.ATTRIBUTE_MINHEIGHT]) { | 395 node[WebViewConstants.ATTRIBUTE_MINHEIGHT]) { |
412 minHeight = node[WebViewConstants.ATTRIBUTE_MINHEIGHT]; | 396 minHeight = node[WebViewConstants.ATTRIBUTE_MINHEIGHT]; |
413 } else { | 397 } else { |
414 minHeight = height; | 398 minHeight = height; |
415 } | 399 } |
416 if (minHeight > maxHeight) { | 400 if (minHeight > maxHeight) { |
417 minHeight = maxHeight; | 401 minHeight = maxHeight; |
418 } | 402 } |
419 | 403 |
420 if (!this.webviewNode.hasAttribute(WebViewConstants.ATTRIBUTE_AUTOSIZE) || | 404 if (!this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue() || |
421 (newWidth >= minWidth && | 405 (newWidth >= minWidth && |
422 newWidth <= maxWidth && | 406 newWidth <= maxWidth && |
423 newHeight >= minHeight && | 407 newHeight >= minHeight && |
424 newHeight <= maxHeight)) { | 408 newHeight <= maxHeight)) { |
425 node.style.width = newWidth + 'px'; | 409 node.style.width = newWidth + 'px'; |
426 node.style.height = newHeight + 'px'; | 410 node.style.height = newHeight + 'px'; |
427 // Only fire the DOM event if the size of the <webview> has actually | 411 // Only fire the DOM event if the size of the <webview> has actually |
428 // changed. | 412 // changed. |
429 this.dispatchEvent(webViewEvent); | 413 this.dispatchEvent(webViewEvent); |
430 } | 414 } |
431 }; | 415 }; |
432 | 416 |
433 // Returns if <object> is in the render tree. | 417 // Returns if <object> is in the render tree. |
434 WebView.prototype.isPluginInRenderTree = function() { | 418 WebView.prototype.isPluginInRenderTree = function() { |
435 return !!this.internalInstanceId && this.internalInstanceId != 0; | 419 return !!this.internalInstanceId && this.internalInstanceId != 0; |
436 }; | 420 }; |
437 | 421 |
438 WebView.prototype.hasNavigated = function() { | 422 WebView.prototype.hasNavigated = function() { |
439 return !this.beforeFirstNavigation; | 423 return !this.beforeFirstNavigation; |
440 }; | 424 }; |
441 | 425 |
442 WebView.prototype.parseSrcAttribute = function(result) { | 426 WebView.prototype.parseSrcAttribute = function(result) { |
443 if (!this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId) { | 427 if (!this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId) { |
444 result.error = WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; | 428 result.error = WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; |
445 return; | 429 return; |
446 } | 430 } |
447 this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue( | |
448 this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_SRC)); | |
449 | 431 |
450 if (!this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()) { | 432 if (!this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()) { |
451 return; | 433 return; |
452 } | 434 } |
453 | 435 |
454 if (this.guestInstanceId == undefined) { | 436 if (this.guestInstanceId == undefined) { |
455 if (this.beforeFirstNavigation) { | 437 if (this.beforeFirstNavigation) { |
456 this.beforeFirstNavigation = false; | 438 this.beforeFirstNavigation = false; |
457 this.createGuest(); | 439 this.createGuest(); |
458 } | 440 } |
459 return; | 441 return; |
460 } | 442 } |
461 | 443 |
462 // Navigate to |this.src|. | 444 // Navigate to |this.src|. |
463 WebViewInternal.navigate( | 445 WebViewInternal.navigate( |
464 this.guestInstanceId, | 446 this.guestInstanceId, |
465 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()); | 447 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()); |
466 }; | 448 }; |
467 | 449 |
468 WebView.prototype.parseAttributes = function() { | 450 WebView.prototype.parseAttributes = function() { |
469 if (!this.elementAttached) { | 451 if (!this.elementAttached) { |
470 return; | 452 return; |
471 } | 453 } |
472 var attributeValue = this.webviewNode.getAttribute( | 454 var result = {}; |
Fady Samuel
2014/11/03 22:38:18
Is this necessary?
paulmeyer
2014/11/03 22:58:19
no
| |
473 WebViewConstants.ATTRIBUTE_PARTITION); | |
474 var result = this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue( | |
475 attributeValue); | |
476 this.parseSrcAttribute(result); | 455 this.parseSrcAttribute(result); |
477 }; | 456 }; |
478 | 457 |
479 WebView.prototype.createGuest = function() { | 458 WebView.prototype.createGuest = function() { |
480 if (this.pendingGuestCreation) { | 459 if (this.pendingGuestCreation) { |
481 return; | 460 return; |
482 } | 461 } |
483 var storagePartitionId = | |
484 this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_PARTITION) || | |
485 this.webviewNode[WebViewConstants.ATTRIBUTE_PARTITION]; | |
486 var params = { | 462 var params = { |
487 'storagePartitionId': storagePartitionId | 463 'storagePartitionId': this.attributes[ |
464 WebViewConstants.ATTRIBUTE_PARTITION].getValue() | |
488 }; | 465 }; |
489 GuestViewInternal.createGuest( | 466 GuestViewInternal.createGuest( |
490 'webview', | 467 'webview', |
491 params, | 468 params, |
492 function(guestInstanceId) { | 469 function(guestInstanceId) { |
493 this.pendingGuestCreation = false; | 470 this.pendingGuestCreation = false; |
494 if (!this.elementAttached) { | 471 if (!this.elementAttached) { |
495 GuestViewInternal.destroyGuest(guestInstanceId); | 472 GuestViewInternal.destroyGuest(guestInstanceId); |
496 return; | 473 return; |
497 } | 474 } |
498 this.attachWindow(guestInstanceId, false); | 475 this.attachWindow(guestInstanceId, false); |
499 }.bind(this) | 476 }.bind(this) |
500 ); | 477 ); |
501 this.pendingGuestCreation = true; | 478 this.pendingGuestCreation = true; |
502 }; | 479 }; |
503 | 480 |
504 WebView.prototype.onFrameNameChanged = function(name) { | 481 WebView.prototype.onFrameNameChanged = function(name) { |
505 this.attributes[WebViewConstants.ATTRIBUTE_NAME].setValue(name || ''); | 482 name = name || ''; |
506 if (this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue() === '') { | 483 if (name === '') { |
507 this.webviewNode.removeAttribute(WebViewConstants.ATTRIBUTE_NAME); | 484 this.webviewNode.removeAttribute(WebViewConstants.ATTRIBUTE_NAME); |
508 } else { | 485 } else { |
509 this.webviewNode.setAttribute( | 486 this.attributes[WebViewConstants.ATTRIBUTE_NAME].setValue(name); |
510 WebViewConstants.ATTRIBUTE_NAME, | |
511 this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue()); | |
512 } | 487 } |
513 }; | 488 }; |
514 | 489 |
515 WebView.prototype.dispatchEvent = function(webViewEvent) { | 490 WebView.prototype.dispatchEvent = function(webViewEvent) { |
516 return this.webviewNode.dispatchEvent(webViewEvent); | 491 return this.webviewNode.dispatchEvent(webViewEvent); |
517 }; | 492 }; |
518 | 493 |
519 // Adds an 'on<event>' property on the webview, which can be used to set/unset | 494 // Adds an 'on<event>' property on the webview, which can be used to set/unset |
520 // an event handler. | 495 // an event handler. |
521 WebView.prototype.setupEventProperty = function(eventName) { | 496 WebView.prototype.setupEventProperty = function(eventName) { |
(...skipping 14 matching lines...) Expand all Loading... | |
536 }; | 511 }; |
537 | 512 |
538 // Updates state upon loadcommit. | 513 // Updates state upon loadcommit. |
539 WebView.prototype.onLoadCommit = function( | 514 WebView.prototype.onLoadCommit = function( |
540 baseUrlForDataUrl, currentEntryIndex, entryCount, | 515 baseUrlForDataUrl, currentEntryIndex, entryCount, |
541 processId, url, isTopLevel) { | 516 processId, url, isTopLevel) { |
542 this.baseUrlForDataUrl = baseUrlForDataUrl; | 517 this.baseUrlForDataUrl = baseUrlForDataUrl; |
543 this.currentEntryIndex = currentEntryIndex; | 518 this.currentEntryIndex = currentEntryIndex; |
544 this.entryCount = entryCount; | 519 this.entryCount = entryCount; |
545 this.processId = processId; | 520 this.processId = processId; |
546 var oldValue = this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_SRC); | 521 var oldValue = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue(); |
547 var newValue = url; | 522 var newValue = url; |
548 if (isTopLevel && (oldValue != newValue)) { | 523 if (isTopLevel && (oldValue != newValue)) { |
549 // Touching the src attribute triggers a navigation. To avoid | 524 // Touching the src attribute triggers a navigation. To avoid |
550 // triggering a page reload on every guest-initiated navigation, | 525 // triggering a page reload on every guest-initiated navigation, |
551 // we use the flag ignoreNextSrcAttributeChange here. | 526 // we use the flag ignoreNextSrcAttributeChange here. |
552 this.ignoreNextSrcAttributeChange = true; | 527 this.ignoreNextSrcAttributeChange = true; |
553 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, newValue); | 528 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, newValue); |
554 } | 529 } |
555 }; | 530 }; |
556 | 531 |
557 WebView.prototype.onAttach = function(storagePartitionId) { | 532 WebView.prototype.onAttach = function(storagePartitionId) { |
558 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_PARTITION, | |
559 storagePartitionId); | |
560 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue( | 533 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue( |
561 storagePartitionId); | 534 storagePartitionId); |
562 }; | 535 }; |
563 | 536 |
564 WebView.prototype.buildAttachParams = function(isNewWindow) { | 537 WebView.prototype.buildAttachParams = function(isNewWindow) { |
565 var params = { | 538 var params = { |
566 'allowtransparency': this.attributes[ | 539 'allowtransparency': this.attributes[ |
567 WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].getValue() || false, | 540 WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].getValue(), |
568 'autosize': this.webviewNode.hasAttribute( | 541 'autosize': this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue(), |
569 WebViewConstants.ATTRIBUTE_AUTOSIZE), | |
570 'instanceId': this.viewInstanceId, | 542 'instanceId': this.viewInstanceId, |
571 'maxheight': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MAXHEIGHT]. | 543 'maxheight': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MAXHEIGHT]. |
572 getValue() || 0), | 544 getValue() || 0), |
573 'maxwidth': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MAXWIDTH]. | 545 'maxwidth': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MAXWIDTH]. |
574 getValue() || 0), | 546 getValue() || 0), |
575 'minheight': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MINHEIGHT]. | 547 'minheight': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MINHEIGHT]. |
576 getValue() || 0), | 548 getValue() || 0), |
577 'minwidth': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MINWIDTH]. | 549 'minwidth': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MINWIDTH]. |
578 getValue() || 0), | 550 getValue() || 0), |
579 'name': this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue(), | 551 'name': this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue(), |
580 // We don't need to navigate new window from here. | 552 // We don't need to navigate new window from here. |
581 'src': isNewWindow ? undefined : | 553 'src': isNewWindow ? undefined : |
582 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue(), | 554 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue(), |
583 // If we have a partition from the opener, that will also be already | 555 // If we have a partition from the opener, that will also be already |
584 // set via this.onAttach(). | 556 // set via this.onAttach(). |
585 'storagePartitionId': this.attributes[WebViewConstants.ATTRIBUTE_PARTITION]. | 557 'storagePartitionId': this.attributes[WebViewConstants.ATTRIBUTE_PARTITION]. |
586 getValue(), | 558 getValue(), |
587 'userAgentOverride': this.userAgentOverride | 559 'userAgentOverride': this.userAgentOverride |
588 }; | 560 }; |
589 return params; | 561 return params; |
590 }; | 562 }; |
591 | 563 |
592 WebView.prototype.attachWindow = function(guestInstanceId, | 564 WebView.prototype.attachWindow = function(guestInstanceId, |
593 isNewWindow) { | 565 isNewWindow) { |
594 this.guestInstanceId = guestInstanceId; | 566 this.guestInstanceId = guestInstanceId; |
595 var params = this.buildAttachParams(isNewWindow); | 567 var params = this.buildAttachParams(isNewWindow); |
596 | 568 |
597 if (!this.isPluginInRenderTree()) { | 569 if (!this.isPluginInRenderTree()) { |
598 this.deferredAttachState = {isNewWindow: isNewWindow}; | 570 this.deferredAttachState = {isNewWindow: isNewWindow}; |
599 return true; | 571 return true; |
600 } | 572 } |
601 | 573 |
602 this.deferredAttachState = null; | 574 this.deferredAttachState = null; |
603 return guestViewInternalNatives.AttachGuest( | 575 return guestViewInternalNatives.AttachGuest( |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
903 WebView.prototype.maybeGetChromeWebViewEvents = function() {}; | 875 WebView.prototype.maybeGetChromeWebViewEvents = function() {}; |
904 | 876 |
905 // Implemented when the experimental WebView API is available. | 877 // Implemented when the experimental WebView API is available. |
906 WebView.maybeGetExperimentalAPIs = function() {}; | 878 WebView.maybeGetExperimentalAPIs = function() {}; |
907 WebView.prototype.maybeGetExperimentalEvents = function() {}; | 879 WebView.prototype.maybeGetExperimentalEvents = function() {}; |
908 WebView.prototype.setupExperimentalContextMenus = function() {}; | 880 WebView.prototype.setupExperimentalContextMenus = function() {}; |
909 | 881 |
910 // Exports. | 882 // Exports. |
911 exports.WebView = WebView; | 883 exports.WebView = WebView; |
912 exports.WebViewInternal = WebViewInternal; | 884 exports.WebViewInternal = WebViewInternal; |
OLD | NEW |