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

Side by Side Diff: extensions/renderer/resources/guest_view/web_view/web_view_attributes.js

Issue 1017863007: Refactored the attributes modules of extension_view and web_view into guest_view_attributes.js. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comment. Created 5 years, 9 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
« no previous file with comments | « extensions/renderer/resources/guest_view/web_view/web_view_action_requests.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 attributes of the <webview> tag. 5 // This module implements the attributes of the <webview> tag.
6 6
7 var GuestViewInternal = 7 var GuestViewAttributes = require('guestViewAttributes').GuestViewAttributes;
8 require('binding').Binding.create('guestViewInternal').generate();
9 var WebViewImpl = require('webView').WebViewImpl; 8 var WebViewImpl = require('webView').WebViewImpl;
10 var WebViewConstants = require('webViewConstants').WebViewConstants; 9 var WebViewConstants = require('webViewConstants').WebViewConstants;
11 var WebViewInternal = require('webViewInternal').WebViewInternal; 10 var WebViewInternal = require('webViewInternal').WebViewInternal;
12 11
13 // ----------------------------------------------------------------------------- 12 // -----------------------------------------------------------------------------
14 // Attribute objects. 13 // AllowScalingAttribute object.
15 14
16 // Default implementation of a WebView attribute. 15 // Attribute that specifies whether scaling is allowed in the webview.
17 function WebViewAttribute(name, webViewImpl) { 16 function AllowScalingAttribute(view) {
18 this.name = name; 17 GuestViewAttributes.BooleanAttribute.call(
19 this.webViewImpl = webViewImpl; 18 this, WebViewConstants.ATTRIBUTE_ALLOWSCALING, view);
20 this.ignoreMutation = false;
21
22 this.defineProperty();
23 } 19 }
24 20
25 // Retrieves and returns the attribute's value. 21 AllowScalingAttribute.prototype.__proto__ =
26 WebViewAttribute.prototype.getValue = function() { 22 GuestViewAttributes.BooleanAttribute.prototype;
27 return this.webViewImpl.element.getAttribute(this.name) || ''; 23
24 AllowScalingAttribute.prototype.handleMutation = function(oldValue, newValue) {
25 if (!this.view.guest.getId())
26 return;
27
28 WebViewInternal.setAllowScaling(this.view.guest.getId(), this.getValue());
28 }; 29 };
29 30
30 // Sets the attribute's value. 31 // -----------------------------------------------------------------------------
31 WebViewAttribute.prototype.setValue = function(value) { 32 // AllowTransparencyAttribute object.
32 this.webViewImpl.element.setAttribute(this.name, value || '');
33 };
34 33
35 // Changes the attribute's value without triggering its mutation handler. 34 // Attribute that specifies whether transparency is allowed in the webview.
36 WebViewAttribute.prototype.setValueIgnoreMutation = function(value) { 35 function AllowTransparencyAttribute(view) {
37 this.ignoreMutation = true; 36 GuestViewAttributes.BooleanAttribute.call(
38 this.setValue(value); 37 this, WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, view);
39 this.ignoreMutation = false;
40 } 38 }
41 39
42 // Defines this attribute as a property on the webview node. 40 AllowTransparencyAttribute.prototype.__proto__ =
43 WebViewAttribute.prototype.defineProperty = function() { 41 GuestViewAttributes.BooleanAttribute.prototype;
44 Object.defineProperty(this.webViewImpl.element, this.name, {
45 get: function() {
46 return this.getValue();
47 }.bind(this),
48 set: function(value) {
49 this.setValue(value);
50 }.bind(this),
51 enumerable: true
52 });
53 };
54
55 // Called when the attribute's value changes.
56 WebViewAttribute.prototype.maybeHandleMutation = function(oldValue, newValue) {
57 if (this.ignoreMutation) {
58 return;
59 }
60
61 this.handleMutation(oldValue, newValue);
62 };
63
64 // Called when a change that isn't ignored occurs to the attribute's value.
65 WebViewAttribute.prototype.handleMutation = function(oldValue, newValue) {};
66
67 // Called when the <webview> element is attached to the DOM tree.
68 WebViewAttribute.prototype.attach = function() {};
69
70 // Called when the <webview> element is detached from the DOM tree.
71 WebViewAttribute.prototype.detach = function() {};
72
73 // An attribute that is treated as a Boolean.
74 function BooleanAttribute(name, webViewImpl) {
75 WebViewAttribute.call(this, name, webViewImpl);
76 }
77
78 BooleanAttribute.prototype.__proto__ = WebViewAttribute.prototype;
79
80 BooleanAttribute.prototype.getValue = function() {
81 return this.webViewImpl.element.hasAttribute(this.name);
82 };
83
84 BooleanAttribute.prototype.setValue = function(value) {
85 if (!value) {
86 this.webViewImpl.element.removeAttribute(this.name);
87 } else {
88 this.webViewImpl.element.setAttribute(this.name, '');
89 }
90 };
91
92 // Attribute that specifies whether transparency is allowed in the webview.
93 function AllowTransparencyAttribute(webViewImpl) {
94 BooleanAttribute.call(
95 this, WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, webViewImpl);
96 }
97
98 AllowTransparencyAttribute.prototype.__proto__ = BooleanAttribute.prototype;
99 42
100 AllowTransparencyAttribute.prototype.handleMutation = function(oldValue, 43 AllowTransparencyAttribute.prototype.handleMutation = function(oldValue,
101 newValue) { 44 newValue) {
102 if (!this.webViewImpl.guest.getId()) { 45 if (!this.view.guest.getId())
103 return; 46 return;
104 }
105 47
106 WebViewInternal.setAllowTransparency(this.webViewImpl.guest.getId(), 48 WebViewInternal.setAllowTransparency(this.view.guest.getId(),
107 this.getValue()); 49 this.getValue());
108 }; 50 };
109 51
110 // Attribute that specifies whether transparency is allowed in the webview. 52 // -----------------------------------------------------------------------------
111 function AllowScalingAttribute(webViewImpl) { 53 // AutosizeDimensionAttribute object.
112 BooleanAttribute.call( 54
113 this, WebViewConstants.ATTRIBUTE_ALLOWSCALING, webViewImpl); 55 // Attribute used to define the demension limits of autosizing.
56 function AutosizeDimensionAttribute(name, view) {
57 GuestViewAttributes.IntegerAttribute.call(this, name, view);
114 } 58 }
115 59
116 AllowScalingAttribute.prototype.__proto__ = BooleanAttribute.prototype; 60 AutosizeDimensionAttribute.prototype.__proto__ =
117 61 GuestViewAttributes.IntegerAttribute.prototype;
118 AllowScalingAttribute.prototype.handleMutation = function(oldValue,
119 newValue) {
120 if (!this.webViewImpl.guest.getId()) {
121 return;
122 }
123
124 WebViewInternal.setAllowScaling(this.webViewImpl.guest.getId(),
125 this.getValue());
126 };
127
128 // Attribute used to define the demension limits of autosizing.
129 function AutosizeDimensionAttribute(name, webViewImpl) {
130 WebViewAttribute.call(this, name, webViewImpl);
131 }
132
133 AutosizeDimensionAttribute.prototype.__proto__ = WebViewAttribute.prototype;
134
135 AutosizeDimensionAttribute.prototype.getValue = function() {
136 return parseInt(this.webViewImpl.element.getAttribute(this.name)) || 0;
137 };
138 62
139 AutosizeDimensionAttribute.prototype.handleMutation = function( 63 AutosizeDimensionAttribute.prototype.handleMutation = function(
140 oldValue, newValue) { 64 oldValue, newValue) {
141 if (!this.webViewImpl.guest.getId()) { 65 if (!this.view.guest.getId())
142 return; 66 return;
143 } 67
144 this.webViewImpl.guest.setSize({ 68 this.view.guest.setSize({
145 'enableAutoSize': this.webViewImpl.attributes[ 69 'enableAutoSize': this.view.attributes[
146 WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue(), 70 WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue(),
147 'min': { 71 'min': {
148 'width': this.webViewImpl.attributes[ 72 'width': this.view.attributes[
149 WebViewConstants.ATTRIBUTE_MINWIDTH].getValue(), 73 WebViewConstants.ATTRIBUTE_MINWIDTH].getValue(),
150 'height': this.webViewImpl.attributes[ 74 'height': this.view.attributes[
151 WebViewConstants.ATTRIBUTE_MINHEIGHT].getValue() 75 WebViewConstants.ATTRIBUTE_MINHEIGHT].getValue()
152 }, 76 },
153 'max': { 77 'max': {
154 'width': this.webViewImpl.attributes[ 78 'width': this.view.attributes[
155 WebViewConstants.ATTRIBUTE_MAXWIDTH].getValue(), 79 WebViewConstants.ATTRIBUTE_MAXWIDTH].getValue(),
156 'height': this.webViewImpl.attributes[ 80 'height': this.view.attributes[
157 WebViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() 81 WebViewConstants.ATTRIBUTE_MAXHEIGHT].getValue()
158 } 82 }
159 }); 83 });
160 return; 84 return;
161 }; 85 };
162 86
87 // -----------------------------------------------------------------------------
88 // AutosizeAttribute object.
89
163 // Attribute that specifies whether the webview should be autosized. 90 // Attribute that specifies whether the webview should be autosized.
164 function AutosizeAttribute(webViewImpl) { 91 function AutosizeAttribute(view) {
165 BooleanAttribute.call(this, WebViewConstants.ATTRIBUTE_AUTOSIZE, webViewImpl); 92 GuestViewAttributes.BooleanAttribute.call(
93 this, WebViewConstants.ATTRIBUTE_AUTOSIZE, view);
166 } 94 }
167 95
168 AutosizeAttribute.prototype.__proto__ = BooleanAttribute.prototype; 96 AutosizeAttribute.prototype.__proto__ =
97 GuestViewAttributes.BooleanAttribute.prototype;
169 98
170 AutosizeAttribute.prototype.handleMutation = 99 AutosizeAttribute.prototype.handleMutation =
171 AutosizeDimensionAttribute.prototype.handleMutation; 100 AutosizeDimensionAttribute.prototype.handleMutation;
172 101
102 // -----------------------------------------------------------------------------
103 // NameAttribute object.
104
173 // Attribute that sets the guest content's window.name object. 105 // Attribute that sets the guest content's window.name object.
174 function NameAttribute(webViewImpl) { 106 function NameAttribute(view) {
175 WebViewAttribute.call(this, WebViewConstants.ATTRIBUTE_NAME, webViewImpl); 107 GuestViewAttributes.Attribute.call(
108 this, WebViewConstants.ATTRIBUTE_NAME, view);
176 } 109 }
177 110
178 NameAttribute.prototype.__proto__ = WebViewAttribute.prototype 111 NameAttribute.prototype.__proto__ = GuestViewAttributes.Attribute.prototype
179 112
180 NameAttribute.prototype.handleMutation = function(oldValue, newValue) { 113 NameAttribute.prototype.handleMutation = function(oldValue, newValue) {
181 oldValue = oldValue || ''; 114 oldValue = oldValue || '';
182 newValue = newValue || ''; 115 newValue = newValue || '';
183 if (oldValue === newValue || !this.webViewImpl.guest.getId()) { 116 if (oldValue === newValue || !this.view.guest.getId())
184 return; 117 return;
185 }
186 118
187 WebViewInternal.setName(this.webViewImpl.guest.getId(), newValue); 119 WebViewInternal.setName(this.view.guest.getId(), newValue);
188 }; 120 };
189 121
190 NameAttribute.prototype.setValue = function(value) { 122 NameAttribute.prototype.setValue = function(value) {
191 value = value || ''; 123 value = value || '';
192 if (value === '') { 124 if (value === '')
193 this.webViewImpl.element.removeAttribute(this.name); 125 this.view.element.removeAttribute(this.name);
194 } else { 126 else
195 this.webViewImpl.element.setAttribute(this.name, value); 127 this.view.element.setAttribute(this.name, value);
196 }
197 }; 128 };
198 129
130 // -----------------------------------------------------------------------------
131 // PartitionAttribute object.
132
199 // Attribute representing the state of the storage partition. 133 // Attribute representing the state of the storage partition.
200 function PartitionAttribute(webViewImpl) { 134 function PartitionAttribute(view) {
201 WebViewAttribute.call( 135 GuestViewAttributes.Attribute.call(
202 this, WebViewConstants.ATTRIBUTE_PARTITION, webViewImpl); 136 this, WebViewConstants.ATTRIBUTE_PARTITION, view);
203 this.validPartitionId = true; 137 this.validPartitionId = true;
204 } 138 }
205 139
206 PartitionAttribute.prototype.__proto__ = WebViewAttribute.prototype; 140 PartitionAttribute.prototype.__proto__ =
141 GuestViewAttributes.Attribute.prototype;
207 142
208 PartitionAttribute.prototype.handleMutation = function(oldValue, newValue) { 143 PartitionAttribute.prototype.handleMutation = function(oldValue, newValue) {
209 newValue = newValue || ''; 144 newValue = newValue || '';
210 145
211 // The partition cannot change if the webview has already navigated. 146 // The partition cannot change if the webview has already navigated.
212 if (!this.webViewImpl.attributes[ 147 if (!this.view.attributes[
213 WebViewConstants.ATTRIBUTE_SRC].beforeFirstNavigation) { 148 WebViewConstants.ATTRIBUTE_SRC].beforeFirstNavigation) {
214 window.console.error(WebViewConstants.ERROR_MSG_ALREADY_NAVIGATED); 149 window.console.error(WebViewConstants.ERROR_MSG_ALREADY_NAVIGATED);
215 this.setValueIgnoreMutation(oldValue); 150 this.setValueIgnoreMutation(oldValue);
216 return; 151 return;
217 } 152 }
218 if (newValue == 'persist:') { 153 if (newValue == 'persist:') {
219 this.validPartitionId = false; 154 this.validPartitionId = false;
220 window.console.error( 155 window.console.error(
221 WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE); 156 WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE);
222 } 157 }
223 }; 158 };
224 159
225 PartitionAttribute.prototype.detach = function() { 160 PartitionAttribute.prototype.detach = function() {
226 this.validPartitionId = true; 161 this.validPartitionId = true;
227 }; 162 };
228 163
164 // -----------------------------------------------------------------------------
165 // SrcAttribute object.
166
229 // Attribute that handles the location and navigation of the webview. 167 // Attribute that handles the location and navigation of the webview.
230 function SrcAttribute(webViewImpl) { 168 function SrcAttribute(view) {
231 WebViewAttribute.call(this, WebViewConstants.ATTRIBUTE_SRC, webViewImpl); 169 GuestViewAttributes.Attribute.call(
170 this, WebViewConstants.ATTRIBUTE_SRC, view);
232 this.setupMutationObserver(); 171 this.setupMutationObserver();
233 this.beforeFirstNavigation = true; 172 this.beforeFirstNavigation = true;
234 this.elementAttached = false;
235 } 173 }
236 174
237 SrcAttribute.prototype.__proto__ = WebViewAttribute.prototype; 175 SrcAttribute.prototype.__proto__ = GuestViewAttributes.Attribute.prototype;
238 176
239 SrcAttribute.prototype.setValueIgnoreMutation = function(value) { 177 SrcAttribute.prototype.setValueIgnoreMutation = function(value) {
240 WebViewAttribute.prototype.setValueIgnoreMutation.call(this, value); 178 GuestViewAttributes.Attribute.prototype.setValueIgnoreMutation.call(
179 this, value);
241 // takeRecords() is needed to clear queued up src mutations. Without it, it is 180 // takeRecords() is needed to clear queued up src mutations. Without it, it is
242 // possible for this change to get picked up asyncronously by src's mutation 181 // possible for this change to get picked up asyncronously by src's mutation
243 // observer |observer|, and then get handled even though we do not want to 182 // observer |observer|, and then get handled even though we do not want to
244 // handle this mutation. 183 // handle this mutation.
245 this.observer.takeRecords(); 184 this.observer.takeRecords();
246 } 185 }
247 186
248 SrcAttribute.prototype.handleMutation = function(oldValue, newValue) { 187 SrcAttribute.prototype.handleMutation = function(oldValue, newValue) {
249 // Once we have navigated, we don't allow clearing the src attribute. 188 // Once we have navigated, we don't allow clearing the src attribute.
250 // Once <webview> enters a navigated state, it cannot return to a 189 // Once <webview> enters a navigated state, it cannot return to a
251 // placeholder state. 190 // placeholder state.
252 if (!newValue && oldValue) { 191 if (!newValue && oldValue) {
253 // src attribute changes normally initiate a navigation. We suppress 192 // src attribute changes normally initiate a navigation. We suppress
254 // the next src attribute handler call to avoid reloading the page 193 // the next src attribute handler call to avoid reloading the page
255 // on every guest-initiated navigation. 194 // on every guest-initiated navigation.
256 this.setValueIgnoreMutation(oldValue); 195 this.setValueIgnoreMutation(oldValue);
257 return; 196 return;
258 } 197 }
259 this.parse(); 198 this.parse();
260 }; 199 };
261 200
262 SrcAttribute.prototype.attach = function() { 201 SrcAttribute.prototype.attach = function() {
263 this.elementAttached = true;
264 this.parse(); 202 this.parse();
265 }; 203 };
266 204
267 SrcAttribute.prototype.detach = function() { 205 SrcAttribute.prototype.detach = function() {
268 this.beforeFirstNavigation = true; 206 this.beforeFirstNavigation = true;
269 this.elementAttached = false;
270 }; 207 };
271 208
272 // The purpose of this mutation observer is to catch assignment to the src 209 // The purpose of this mutation observer is to catch assignment to the src
273 // attribute without any changes to its value. This is useful in the case 210 // attribute without any changes to its value. This is useful in the case
274 // where the webview guest has crashed and navigating to the same address 211 // where the webview guest has crashed and navigating to the same address
275 // spawns off a new process. 212 // spawns off a new process.
276 SrcAttribute.prototype.setupMutationObserver = 213 SrcAttribute.prototype.setupMutationObserver =
277 function() { 214 function() {
278 this.observer = new MutationObserver(function(mutations) { 215 this.observer = new MutationObserver(function(mutations) {
279 $Array.forEach(mutations, function(mutation) { 216 $Array.forEach(mutations, function(mutation) {
280 var oldValue = mutation.oldValue; 217 var oldValue = mutation.oldValue;
281 var newValue = this.getValue(); 218 var newValue = this.getValue();
282 if (oldValue != newValue) { 219 if (oldValue != newValue) {
283 return; 220 return;
284 } 221 }
285 this.handleMutation(oldValue, newValue); 222 this.handleMutation(oldValue, newValue);
286 }.bind(this)); 223 }.bind(this));
287 }.bind(this)); 224 }.bind(this));
288 var params = { 225 var params = {
289 attributes: true, 226 attributes: true,
290 attributeOldValue: true, 227 attributeOldValue: true,
291 attributeFilter: [this.name] 228 attributeFilter: [this.name]
292 }; 229 };
293 this.observer.observe(this.webViewImpl.element, params); 230 this.observer.observe(this.view.element, params);
294 }; 231 };
295 232
296 SrcAttribute.prototype.parse = function() { 233 SrcAttribute.prototype.parse = function() {
297 if (!this.elementAttached || 234 if (!this.view.elementAttached ||
298 !this.webViewImpl.attributes[ 235 !this.view.attributes[
299 WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId || 236 WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId ||
300 !this.getValue()) { 237 !this.getValue()) {
301 return; 238 return;
302 } 239 }
303 240
304 if (!this.webViewImpl.guest.getId()) { 241 if (!this.view.guest.getId()) {
305 if (this.beforeFirstNavigation) { 242 if (this.beforeFirstNavigation) {
306 this.beforeFirstNavigation = false; 243 this.beforeFirstNavigation = false;
307 this.webViewImpl.createGuest(); 244 this.view.createGuest();
308 } 245 }
309 return; 246 return;
310 } 247 }
311 248
312 // Navigate to |src|. 249 WebViewInternal.navigate(this.view.guest.getId(), this.getValue());
313 WebViewInternal.navigate(this.webViewImpl.guest.getId(), this.getValue());
314 }; 250 };
315 251
316 // ----------------------------------------------------------------------------- 252 // -----------------------------------------------------------------------------
317 253
318 // Sets up all of the webview attributes. 254 // Sets up all of the webview attributes.
319 WebViewImpl.prototype.setupWebViewAttributes = function() { 255 WebViewImpl.prototype.setupWebViewAttributes = function() {
320 this.attributes = {}; 256 this.attributes = {};
321 257
258 this.attributes[WebViewConstants.ATTRIBUTE_ALLOWSCALING] =
259 new AllowScalingAttribute(this);
322 this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] = 260 this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] =
323 new AllowTransparencyAttribute(this); 261 new AllowTransparencyAttribute(this);
324 this.attributes[WebViewConstants.ATTRIBUTE_ALLOWSCALING] =
325 new AllowScalingAttribute(this);
326 this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE] = 262 this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE] =
327 new AutosizeAttribute(this); 263 new AutosizeAttribute(this);
328 this.attributes[WebViewConstants.ATTRIBUTE_NAME] = 264 this.attributes[WebViewConstants.ATTRIBUTE_NAME] =
329 new NameAttribute(this); 265 new NameAttribute(this);
330 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION] = 266 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION] =
331 new PartitionAttribute(this); 267 new PartitionAttribute(this);
332 this.attributes[WebViewConstants.ATTRIBUTE_SRC] = 268 this.attributes[WebViewConstants.ATTRIBUTE_SRC] =
333 new SrcAttribute(this); 269 new SrcAttribute(this);
334 270
335 var autosizeAttributes = [WebViewConstants.ATTRIBUTE_MAXHEIGHT, 271 var autosizeAttributes = [WebViewConstants.ATTRIBUTE_MAXHEIGHT,
336 WebViewConstants.ATTRIBUTE_MAXWIDTH, 272 WebViewConstants.ATTRIBUTE_MAXWIDTH,
337 WebViewConstants.ATTRIBUTE_MINHEIGHT, 273 WebViewConstants.ATTRIBUTE_MINHEIGHT,
338 WebViewConstants.ATTRIBUTE_MINWIDTH]; 274 WebViewConstants.ATTRIBUTE_MINWIDTH];
339 for (var i = 0; autosizeAttributes[i]; ++i) { 275 for (var i = 0; autosizeAttributes[i]; ++i) {
340 this.attributes[autosizeAttributes[i]] = 276 this.attributes[autosizeAttributes[i]] =
341 new AutosizeDimensionAttribute(autosizeAttributes[i], this); 277 new AutosizeDimensionAttribute(autosizeAttributes[i], this);
342 } 278 }
343 }; 279 };
OLDNEW
« no previous file with comments | « extensions/renderer/resources/guest_view/web_view/web_view_action_requests.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698