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 = |
11 require('binding').Binding.create('guestViewInternal').generate(); | 11 require('binding').Binding.create('guestViewInternal').generate(); |
12 var IdGenerator = requireNative('id_generator'); | 12 var IdGenerator = requireNative('id_generator'); |
13 // TODO(lazyboy): Rename this to WebViewInternal and call WebViewInternal | 13 // TODO(lazyboy): Rename this to WebViewInternal and call WebViewInternal |
14 // something else. | 14 // something else. |
15 var WebView = require('webViewInternal').WebView; | 15 var WebView = require('webViewInternal').WebView; |
16 var WebViewEvents = require('webViewEvents').WebViewEvents; | 16 var WebViewEvents = require('webViewEvents').WebViewEvents; |
17 | 17 |
18 var WEB_VIEW_ATTRIBUTE_AUTOSIZE = 'autosize'; | |
19 var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight'; | 18 var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight'; |
20 var WEB_VIEW_ATTRIBUTE_MAXWIDTH = 'maxwidth'; | 19 var WEB_VIEW_ATTRIBUTE_MAXWIDTH = 'maxwidth'; |
21 var WEB_VIEW_ATTRIBUTE_MINHEIGHT = 'minheight'; | 20 var WEB_VIEW_ATTRIBUTE_MINHEIGHT = 'minheight'; |
22 var WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth'; | 21 var WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth'; |
23 var AUTO_SIZE_ATTRIBUTES = [ | |
24 WEB_VIEW_ATTRIBUTE_AUTOSIZE, | |
25 WEB_VIEW_ATTRIBUTE_MAXHEIGHT, | |
26 WEB_VIEW_ATTRIBUTE_MAXWIDTH, | |
27 WEB_VIEW_ATTRIBUTE_MINHEIGHT, | |
28 WEB_VIEW_ATTRIBUTE_MINWIDTH | |
29 ]; | |
30 | |
31 var WEB_VIEW_ATTRIBUTE_PARTITION = 'partition'; | 22 var WEB_VIEW_ATTRIBUTE_PARTITION = 'partition'; |
32 | 23 |
33 var PLUGIN_METHOD_ATTACH = '-internal-attach'; | 24 var PLUGIN_METHOD_ATTACH = '-internal-attach'; |
34 | 25 |
35 var ERROR_MSG_ALREADY_NAVIGATED = | 26 var ERROR_MSG_ALREADY_NAVIGATED = |
36 'The object has already navigated, so its partition cannot be changed.'; | 27 'The object has already navigated, so its partition cannot be changed.'; |
37 var ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.'; | 28 var ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.'; |
38 | 29 |
39 /** @type {Array.<string>} */ | 30 /** @type {Array.<string>} */ |
40 var WEB_VIEW_ATTRIBUTES = [ | 31 var WEB_VIEW_ATTRIBUTES = [ |
41 'allowtransparency', | 32 'allowtransparency', |
| 33 'autosize', |
| 34 WEB_VIEW_ATTRIBUTE_MINHEIGHT, |
| 35 WEB_VIEW_ATTRIBUTE_MINWIDTH, |
| 36 WEB_VIEW_ATTRIBUTE_MAXHEIGHT, |
| 37 WEB_VIEW_ATTRIBUTE_MAXWIDTH |
42 ]; | 38 ]; |
43 | 39 |
44 /** @class representing state of storage partition. */ | 40 /** @class representing state of storage partition. */ |
45 function Partition() { | 41 function Partition() { |
46 this.validPartitionId = true; | 42 this.validPartitionId = true; |
47 this.persistStorage = false; | 43 this.persistStorage = false; |
48 this.storagePartitionId = ''; | 44 this.storagePartitionId = ''; |
49 }; | 45 }; |
50 | 46 |
51 Partition.prototype.toAttribute = function() { | 47 Partition.prototype.toAttribute = function() { |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 /** | 308 /** |
313 * @private | 309 * @private |
314 */ | 310 */ |
315 WebViewInternal.prototype.insertCSS = function(var_args) { | 311 WebViewInternal.prototype.insertCSS = function(var_args) { |
316 this.validateExecuteCodeCall(); | 312 this.validateExecuteCodeCall(); |
317 var args = $Array.concat([this.instanceId, this.src], | 313 var args = $Array.concat([this.instanceId, this.src], |
318 $Array.slice(arguments)); | 314 $Array.slice(arguments)); |
319 $Function.apply(WebView.insertCSS, null, args); | 315 $Function.apply(WebView.insertCSS, null, args); |
320 }; | 316 }; |
321 | 317 |
322 WebViewInternal.prototype.setupAutoSizeProperties = function() { | |
323 var self = this; | |
324 $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) { | |
325 this[attributeName] = this.webviewNode.getAttribute(attributeName); | |
326 Object.defineProperty(this.webviewNode, attributeName, { | |
327 get: function() { | |
328 return self[attributeName]; | |
329 }, | |
330 set: function(value) { | |
331 self.webviewNode.setAttribute(attributeName, value); | |
332 }, | |
333 enumerable: true | |
334 }); | |
335 }, this); | |
336 }; | |
337 | |
338 /** | 318 /** |
339 * @private | 319 * @private |
340 */ | 320 */ |
341 WebViewInternal.prototype.setupWebviewNodeProperties = function() { | 321 WebViewInternal.prototype.setupWebviewNodeProperties = function() { |
342 var ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE = '<webview>: ' + | 322 var ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE = '<webview>: ' + |
343 'contentWindow is not available at this time. It will become available ' + | 323 'contentWindow is not available at this time. It will become available ' + |
344 'when the page has finished loading.'; | 324 'when the page has finished loading.'; |
345 | 325 |
346 this.setupAutoSizeProperties(); | |
347 var self = this; | 326 var self = this; |
348 var browserPluginNode = this.browserPluginNode; | 327 var browserPluginNode = this.browserPluginNode; |
349 // Expose getters and setters for the attributes. | 328 // Expose getters and setters for the attributes. |
350 $Array.forEach(WEB_VIEW_ATTRIBUTES, function(attributeName) { | 329 $Array.forEach(WEB_VIEW_ATTRIBUTES, function(attributeName) { |
351 Object.defineProperty(this.webviewNode, attributeName, { | 330 Object.defineProperty(this.webviewNode, attributeName, { |
352 get: function() { | 331 get: function() { |
353 if (browserPluginNode.hasOwnProperty(attributeName)) { | 332 if (browserPluginNode.hasOwnProperty(attributeName)) { |
354 return browserPluginNode[attributeName]; | 333 return browserPluginNode[attributeName]; |
355 } else { | 334 } else { |
356 return browserPluginNode.getAttribute(attributeName); | 335 return browserPluginNode.getAttribute(attributeName); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 /** | 439 /** |
461 * @private | 440 * @private |
462 */ | 441 */ |
463 WebViewInternal.prototype.handleWebviewAttributeMutation = | 442 WebViewInternal.prototype.handleWebviewAttributeMutation = |
464 function(name, oldValue, newValue) { | 443 function(name, oldValue, newValue) { |
465 // This observer monitors mutations to attributes of the <webview> and | 444 // This observer monitors mutations to attributes of the <webview> and |
466 // updates the BrowserPlugin properties accordingly. In turn, updating | 445 // updates the BrowserPlugin properties accordingly. In turn, updating |
467 // a BrowserPlugin property will update the corresponding BrowserPlugin | 446 // a BrowserPlugin property will update the corresponding BrowserPlugin |
468 // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more | 447 // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more |
469 // details. | 448 // details. |
470 if (AUTO_SIZE_ATTRIBUTES.indexOf(name) > -1) { | 449 if (name == 'name') { |
471 this[name] = newValue; | |
472 if (!this.instanceId) { | |
473 return; | |
474 } | |
475 // Convert autosize attribute to boolean. | |
476 var autosize = this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE); | |
477 GuestViewInternal.setAutoSize(this.instanceId, { | |
478 'enableAutoSize': autosize, | |
479 'min': { | |
480 'width': parseInt(this.minwidth || 0), | |
481 'height': parseInt(this.minheight || 0) | |
482 }, | |
483 'max': { | |
484 'width': parseInt(this.maxwidth || 0), | |
485 'height': parseInt(this.maxheight || 0) | |
486 } | |
487 }); | |
488 return; | |
489 } else if (name == 'name') { | |
490 // We treat null attribute (attribute removed) and the empty string as | 450 // We treat null attribute (attribute removed) and the empty string as |
491 // one case. | 451 // one case. |
492 oldValue = oldValue || ''; | 452 oldValue = oldValue || ''; |
493 newValue = newValue || ''; | 453 newValue = newValue || ''; |
494 | 454 |
495 if (oldValue === newValue) { | 455 if (oldValue === newValue) { |
496 return; | 456 return; |
497 } | 457 } |
498 this.name = newValue; | 458 this.name = newValue; |
499 if (!this.instanceId) { | 459 if (!this.instanceId) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 if (newValue != this.webviewNode.getAttribute(name)) { | 544 if (newValue != this.webviewNode.getAttribute(name)) { |
585 this.webviewNode.setAttribute(name, newValue); | 545 this.webviewNode.setAttribute(name, newValue); |
586 } | 546 } |
587 } else { | 547 } else { |
588 // If an attribute is removed from the BrowserPlugin, then remove it | 548 // If an attribute is removed from the BrowserPlugin, then remove it |
589 // from the <webview> as well. | 549 // from the <webview> as well. |
590 this.webviewNode.removeAttribute(name); | 550 this.webviewNode.removeAttribute(name); |
591 } | 551 } |
592 }; | 552 }; |
593 | 553 |
594 WebViewInternal.prototype.onSizeChanged = function(webViewEvent) { | 554 WebViewInternal.prototype.onSizeChanged = function(newWidth, newHeight) { |
595 var newWidth = webViewEvent.newWidth; | |
596 var newHeight = webViewEvent.newHeight; | |
597 | |
598 var node = this.webviewNode; | 555 var node = this.webviewNode; |
599 | 556 |
600 var width = node.offsetWidth; | 557 var width = node.offsetWidth; |
601 var height = node.offsetHeight; | 558 var height = node.offsetHeight; |
602 | 559 |
603 // Check the current bounds to make sure we do not resize <webview> | 560 // Check the current bounds to make sure we do not resize <webview> |
604 // outside of current constraints. | 561 // outside of current constraints. |
605 var maxWidth; | 562 var maxWidth; |
606 if (node.hasAttribute(WEB_VIEW_ATTRIBUTE_MAXWIDTH) && | 563 if (node.hasAttribute(WEB_VIEW_ATTRIBUTE_MAXWIDTH) && |
607 node[WEB_VIEW_ATTRIBUTE_MAXWIDTH]) { | 564 node[WEB_VIEW_ATTRIBUTE_MAXWIDTH]) { |
(...skipping 24 matching lines...) Expand all Loading... |
632 if (node.hasAttribute(WEB_VIEW_ATTRIBUTE_MINHEIGHT) && | 589 if (node.hasAttribute(WEB_VIEW_ATTRIBUTE_MINHEIGHT) && |
633 node[WEB_VIEW_ATTRIBUTE_MINHEIGHT]) { | 590 node[WEB_VIEW_ATTRIBUTE_MINHEIGHT]) { |
634 minHeight = node[WEB_VIEW_ATTRIBUTE_MINHEIGHT]; | 591 minHeight = node[WEB_VIEW_ATTRIBUTE_MINHEIGHT]; |
635 } else { | 592 } else { |
636 minHeight = height; | 593 minHeight = height; |
637 } | 594 } |
638 if (minHeight > maxHeight) { | 595 if (minHeight > maxHeight) { |
639 minHeight = maxHeight; | 596 minHeight = maxHeight; |
640 } | 597 } |
641 | 598 |
642 if (!this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE) || | 599 if (newWidth >= minWidth && |
643 (newWidth >= minWidth && | 600 newWidth <= maxWidth && |
644 newWidth <= maxWidth && | 601 newHeight >= minHeight && |
645 newHeight >= minHeight && | 602 newHeight <= maxHeight) { |
646 newHeight <= maxHeight)) { | |
647 node.style.width = newWidth + 'px'; | 603 node.style.width = newWidth + 'px'; |
648 node.style.height = newHeight + 'px'; | 604 node.style.height = newHeight + 'px'; |
649 // Only fire the DOM event if the size of the <webview> has actually | |
650 // changed. | |
651 this.dispatchEvent(webViewEvent); | |
652 } | 605 } |
653 }; | 606 }; |
654 | 607 |
655 // Returns true if Browser Plugin bindings is available. | 608 // Returns true if Browser Plugin bindings is available. |
656 // Bindings are unavailable if <object> is not in the render tree. | 609 // Bindings are unavailable if <object> is not in the render tree. |
657 WebViewInternal.prototype.hasBindings = function() { | 610 WebViewInternal.prototype.hasBindings = function() { |
658 return 'function' == typeof this.browserPluginNode[PLUGIN_METHOD_ATTACH]; | 611 return 'function' == typeof this.browserPluginNode[PLUGIN_METHOD_ATTACH]; |
659 }; | 612 }; |
660 | 613 |
661 WebViewInternal.prototype.hasNavigated = function() { | 614 WebViewInternal.prototype.hasNavigated = function() { |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 | 781 |
829 WebViewInternal.prototype.getZoom = function(callback) { | 782 WebViewInternal.prototype.getZoom = function(callback) { |
830 if (!this.instanceId) { | 783 if (!this.instanceId) { |
831 return; | 784 return; |
832 } | 785 } |
833 WebView.getZoom(this.instanceId, callback); | 786 WebView.getZoom(this.instanceId, callback); |
834 }; | 787 }; |
835 | 788 |
836 WebViewInternal.prototype.buildAttachParams = function(isNewWindow) { | 789 WebViewInternal.prototype.buildAttachParams = function(isNewWindow) { |
837 var params = { | 790 var params = { |
838 'autosize': this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE), | 791 'api': 'webview', |
839 'instanceId': this.viewInstanceId, | 792 'instanceId': this.viewInstanceId, |
840 'maxheight': parseInt(this.maxheight || 0), | |
841 'maxwidth': parseInt(this.maxwidth || 0), | |
842 'minheight': parseInt(this.minheight || 0), | |
843 'minwidth': parseInt(this.minwidth || 0), | |
844 'name': this.name, | 793 'name': this.name, |
845 // We don't need to navigate new window from here. | 794 // We don't need to navigate new window from here. |
846 'src': isNewWindow ? undefined : this.src, | 795 'src': isNewWindow ? undefined : this.src, |
847 // If we have a partition from the opener, that will also be already | 796 // If we have a partition from the opener, that will also be already |
848 // set via this.onAttach(). | 797 // set via this.onAttach(). |
849 'storagePartitionId': this.partition.toAttribute(), | 798 'storagePartitionId': this.partition.toAttribute(), |
850 'userAgentOverride': this.userAgentOverride | 799 'userAgentOverride': this.userAgentOverride |
851 }; | 800 }; |
852 return params; | 801 return params; |
853 }; | 802 }; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1023 }; | 972 }; |
1024 | 973 |
1025 /** | 974 /** |
1026 * Implemented when the experimental API is available. | 975 * Implemented when the experimental API is available. |
1027 * @private | 976 * @private |
1028 */ | 977 */ |
1029 WebViewInternal.prototype.setupExperimentalContextMenus = function() {}; | 978 WebViewInternal.prototype.setupExperimentalContextMenus = function() {}; |
1030 | 979 |
1031 exports.WebView = WebView; | 980 exports.WebView = WebView; |
1032 exports.WebViewInternal = WebViewInternal; | 981 exports.WebViewInternal = WebViewInternal; |
OLD | NEW |