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

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

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

Powered by Google App Engine
This is Rietveld 408576698