Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(279)

Side by Side Diff: chrome/renderer/resources/extensions/web_view.js

Issue 11233065: Rename <browser> shim to <webview> (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged with ToT. No longer exposed to Extensions Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <browser> 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 BROWSER_TAG_ATTRIBUTES = ['src', 'width', 'height']; 10 var WEB_VIEW_ATTRIBUTES = ['src', 'width', 'height'];
11 11
12 var BROWSER_TAG_READONLY_ATTRIBUTES = ['contentWindow']; 12 var WEB_VIEW_READONLY_ATTRIBUTES = ['contentWindow'];
13 13
14 // All exposed api methods for <browser>, these are forwarded to the browser 14 // All exposed api methods for <webview>, these are forwarded to the browser
15 // plugin. 15 // plugin.
16 var BROWSER_TAG_API_METHODS = [ 16 var WEB_VIEW_API_METHODS = [
17 'addEventListener', 17 'addEventListener',
18 'back', 18 'back',
19 'canGoBack', 19 'canGoBack',
20 'canGoForward', 20 'canGoForward',
21 'forward', 21 'forward',
22 'getProcessId', 22 'getProcessId',
23 'go', 23 'go',
24 'reload', 24 'reload',
25 'removeEventListener', 25 'removeEventListener',
26 'stop', 26 'stop',
27 'terminate' 27 'terminate'
28 ]; 28 ];
29 29
30 window.addEventListener('DOMContentLoaded', function() { 30 window.addEventListener('DOMContentLoaded', function() {
31 // Handle <browser> tags already in the document. 31 // Handle <webview> tags already in the document.
32 var browserNodes = document.body.querySelectorAll('browser'); 32 var webViewNodes = document.body.querySelectorAll('webview');
33 for (var i = 0, browserNode; browserNode = browserNodes[i]; i++) { 33 for (var i = 0, webViewNode; webViewNode = webViewNodes[i]; i++) {
34 new BrowserTag(browserNode); 34 new WebView(webViewNode);
35 } 35 }
36 36
37 // Handle <browser> tags added later. 37 // Handle <webview> tags added later.
38 var documentObserver = new WebKitMutationObserver(function(mutations) { 38 var documentObserver = new WebKitMutationObserver(function(mutations) {
39 mutations.forEach(function(mutation) { 39 mutations.forEach(function(mutation) {
40 for (var i = 0, addedNode; addedNode = mutation.addedNodes[i]; i++) { 40 for (var i = 0, addedNode; addedNode = mutation.addedNodes[i]; i++) {
41 if (addedNode.tagName == 'BROWSER') { 41 if (addedNode.tagName == 'WEBVIEW') {
42 new BrowserTag(addedNode); 42 new WebView(addedNode);
43 } 43 }
44 } 44 }
45 }); 45 });
46 }); 46 });
47 documentObserver.observe(document, {subtree: true, childList: true}); 47 documentObserver.observe(document, {subtree: true, childList: true});
48 }); 48 });
49 49
50 /** 50 /**
51 * @constructor 51 * @constructor
52 */ 52 */
53 function BrowserTag(node) { 53 function WebView(node) {
54 this.node_ = node; 54 this.node_ = node;
55 var shadowRoot = new WebKitShadowRoot(node); 55 var shadowRoot = new WebKitShadowRoot(node);
56 56
57 this.objectNode_ = document.createElement('object'); 57 this.objectNode_ = document.createElement('object');
58 this.objectNode_.type = 'application/browser-plugin'; 58 this.objectNode_.type = 'application/browser-plugin';
59 BROWSER_TAG_ATTRIBUTES.forEach(this.copyAttribute_, this); 59 WEB_VIEW_ATTRIBUTES.forEach(this.copyAttribute_, this);
60 60
61 shadowRoot.appendChild(this.objectNode_); 61 shadowRoot.appendChild(this.objectNode_);
62 62
63 // this.objectNode_[apiMethod] are defined after the shadow object is appended 63 // this.objectNode_[apiMethod] are defined after the shadow object is appended
64 // to the shadow root. 64 // to the shadow root.
65 BROWSER_TAG_API_METHODS.forEach(function(apiMethod) { 65 WEB_VIEW_API_METHODS.forEach(function(apiMethod) {
66 node[apiMethod] = this.objectNode_[apiMethod].bind(this.objectNode_); 66 node[apiMethod] = this.objectNode_[apiMethod].bind(this.objectNode_);
67 }, this); 67 }, this);
68 68
69 // Map attribute modifications on the <browser> tag to changes on the 69 // Map attribute modifications on the <webview> tag to changes on the
70 // underlying <object> node. 70 // underlying <object> node.
71 var handleMutation = this.handleMutation_.bind(this); 71 var handleMutation = this.handleMutation_.bind(this);
72 var observer = new WebKitMutationObserver(function(mutations) { 72 var observer = new WebKitMutationObserver(function(mutations) {
73 mutations.forEach(handleMutation); 73 mutations.forEach(handleMutation);
74 }); 74 });
75 observer.observe( 75 observer.observe(
76 this.node_, 76 this.node_,
77 {attributes: true, attributeFilter: BROWSER_TAG_ATTRIBUTES}); 77 {attributes: true, attributeFilter: WEB_VIEW_ATTRIBUTES});
78 78
79 var objectNode = this.objectNode_; 79 var objectNode = this.objectNode_;
80 // Expose getters and setters for the attributes. 80 // Expose getters and setters for the attributes.
81 BROWSER_TAG_ATTRIBUTES.forEach(function(attributeName) { 81 WEB_VIEW_ATTRIBUTES.forEach(function(attributeName) {
82 Object.defineProperty(this.node_, attributeName, { 82 Object.defineProperty(this.node_, attributeName, {
83 get: function() { 83 get: function() {
84 if (attributeName == 'src') { 84 if (attributeName == 'src') {
85 // Always read src attribute from the plugin <object> since: a) It can 85 // Always read src attribute from the plugin <object> since: a) It can
86 // have different value when empty src is set. b) BrowserPlugin 86 // have different value when empty src is set. b) BrowserPlugin
87 // updates its src attribute on guest-initiated navigations. 87 // updates its src attribute on guest-initiated navigations.
88 return objectNode.src; 88 return objectNode.src;
89 } 89 }
90 var value = node.getAttribute(attributeName); 90 var value = node.getAttribute(attributeName);
91 var numericValue = parseInt(value, 10); 91 var numericValue = parseInt(value, 10);
92 return isNaN(numericValue) ? value : numericValue; 92 return isNaN(numericValue) ? value : numericValue;
93 }, 93 },
94 set: function(value) { 94 set: function(value) {
95 node.setAttribute(attributeName, value); 95 node.setAttribute(attributeName, value);
96 }, 96 },
97 enumerable: true 97 enumerable: true
98 }); 98 });
99 }, this); 99 }, this);
100 100
101 // We cannot use {writable: true} property descriptor because we want dynamic 101 // We cannot use {writable: true} property descriptor because we want dynamic
102 // getter value. 102 // getter value.
103 BROWSER_TAG_READONLY_ATTRIBUTES.forEach(function(attributeName) { 103 WEB_VIEW_READONLY_ATTRIBUTES.forEach(function(attributeName) {
104 Object.defineProperty(this.node_, attributeName, { 104 Object.defineProperty(this.node_, attributeName, {
105 get: function() { 105 get: function() {
106 // Read these attributes from the plugin <object>. 106 // Read these attributes from the plugin <object>.
107 return objectNode[attributeName]; 107 return objectNode[attributeName];
108 }, 108 },
109 // No setter. 109 // No setter.
110 enumerable: true 110 enumerable: true
111 }) 111 })
112 }, this); 112 }, this);
113 }; 113 };
114 114
115 /** 115 /**
116 * @private 116 * @private
117 */ 117 */
118 BrowserTag.prototype.handleMutation_ = function(mutation) { 118 WebView.prototype.handleMutation_ = function(mutation) {
119 switch (mutation.attributeName) { 119 switch (mutation.attributeName) {
120 case 'src': 120 case 'src':
121 // We need to set .src directly on the shadow element so that 121 // We need to set .src directly on the shadow element so that
122 // BrowserPluginBindings catches this as src attribute mutation. The 122 // BrowserPluginBindings catches this as src attribute mutation. The
123 // bindings would catch 'SetAttribute' method call with src as argument 123 // bindings would catch 'SetAttribute' method call with src as argument
124 // otherwise. 124 // otherwise.
125 this.objectNode_.src = this.node_.getAttribute('src'); 125 this.objectNode_.src = this.node_.getAttribute('src');
126 break; 126 break;
127 default: 127 default:
128 this.copyAttribute_(mutation.attributeName); 128 this.copyAttribute_(mutation.attributeName);
129 break; 129 break;
130 } 130 }
131 }; 131 };
132 132
133 /** 133 /**
134 * @private 134 * @private
135 */ 135 */
136 BrowserTag.prototype.copyAttribute_ = function(attributeName) { 136 WebView.prototype.copyAttribute_ = function(attributeName) {
137 this.objectNode_.setAttribute( 137 this.objectNode_.setAttribute(
138 attributeName, this.node_.getAttribute(attributeName)); 138 attributeName, this.node_.getAttribute(attributeName));
139 }; 139 };
OLDNEW
« no previous file with comments | « chrome/renderer/resources/extensions/platform_app.css ('k') | chrome/renderer/resources/extensions/web_view_old.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698