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

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

Issue 663483004: Webview attributes overhaul. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 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
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 =
11 require('binding').Binding.create('guestViewInternal').generate(); 11 require('binding').Binding.create('guestViewInternal').generate();
12 var guestViewInternalNatives = requireNative('guest_view_internal'); 12 var guestViewInternalNatives = requireNative('guest_view_internal');
13 var IdGenerator = requireNative('id_generator'); 13 var IdGenerator = requireNative('id_generator');
14 var WebViewConstants = require('webViewConstants').WebViewConstants; 14 var WebViewConstants = require('webViewConstants').WebViewConstants;
15 var WebViewEvents = require('webViewEvents').WebViewEvents; 15 var WebViewEvents = require('webViewEvents').WebViewEvents;
16 var WebViewInternal = require('webViewInternal').WebViewInternal; 16 var WebViewInternal = require('webViewInternal').WebViewInternal;
17 17
18 // Attributes.
19 var BROWSER_PLUGIN_ATTRIBUTE_INTERNALINSTANCEID = 'internalinstanceid'
Fady Samuel 2014/10/22 21:48:26 Move to WebViewConstants?
paulmeyer 2014/10/23 21:39:56 Done.
18 var AUTO_SIZE_ATTRIBUTES = [ 20 var AUTO_SIZE_ATTRIBUTES = [
19 WebViewConstants.ATTRIBUTE_AUTOSIZE, 21 WebViewConstants.ATTRIBUTE_AUTOSIZE,
20 WebViewConstants.ATTRIBUTE_MAXHEIGHT, 22 WebViewConstants.ATTRIBUTE_MAXHEIGHT,
21 WebViewConstants.ATTRIBUTE_MAXWIDTH, 23 WebViewConstants.ATTRIBUTE_MAXWIDTH,
22 WebViewConstants.ATTRIBUTE_MINHEIGHT, 24 WebViewConstants.ATTRIBUTE_MINHEIGHT,
23 WebViewConstants.ATTRIBUTE_MINWIDTH 25 WebViewConstants.ATTRIBUTE_MINWIDTH
24 ]; 26 ];
25 27
26 // Represents the state of the storage partition.
27 function Partition() {
28 this.validPartitionId = true;
29 this.persistStorage = false;
30 this.storagePartitionId = '';
31 }
32
33 Partition.prototype.toAttribute = function() {
34 if (!this.validPartitionId) {
35 return '';
36 }
37 return (this.persistStorage ? 'persist:' : '') + this.storagePartitionId;
38 };
39
40 Partition.prototype.fromAttribute = function(value, hasNavigated) {
41 var result = {};
42 if (hasNavigated) {
43 result.error = WebViewConstants.ERROR_MSG_ALREADY_NAVIGATED;
44 return result;
45 }
46 if (!value) {
47 value = '';
48 }
49
50 var LEN = 'persist:'.length;
51 if (value.substr(0, LEN) == 'persist:') {
52 value = value.substr(LEN);
53 if (!value) {
54 this.validPartitionId = false;
55 result.error = WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE;
56 return result;
57 }
58 this.persistStorage = true;
59 } else {
60 this.persistStorage = false;
61 }
62
63 this.storagePartitionId = value;
64 return result;
65 };
66
67 // Represents the internal state of the WebView node. 28 // Represents the internal state of the WebView node.
68 function WebView(webviewNode) { 29 function WebView(webviewNode) {
69 privates(webviewNode).internal = this; 30 privates(webviewNode).internal = this;
70 this.webviewNode = webviewNode; 31 this.webviewNode = webviewNode;
71 this.attached = false; 32 this.attached = false;
72 this.pendingGuestCreation = false; 33 this.pendingGuestCreation = false;
73 this.elementAttached = false; 34 this.elementAttached = false;
74 35
75 this.beforeFirstNavigation = true; 36 this.beforeFirstNavigation = true;
76 this.contentWindow = null; 37 this.contentWindow = null;
77 this.validPartitionId = true; 38 this.validPartitionId = true;
78 // Used to save some state upon deferred attachment. 39 // Used to save some state upon deferred attachment.
79 // If <object> bindings is not available, we defer attachment. 40 // If <object> bindings is not available, we defer attachment.
80 // This state contains whether or not the attachment request was for 41 // This state contains whether or not the attachment request was for
81 // newwindow. 42 // newwindow.
82 this.deferredAttachState = null; 43 this.deferredAttachState = null;
83 44
84 // on* Event handlers. 45 // on* Event handlers.
85 this.on = {}; 46 this.on = {};
86 47
87 this.browserPluginNode = this.createBrowserPluginNode(); 48 this.browserPluginNode = this.createBrowserPluginNode();
88 var shadowRoot = this.webviewNode.createShadowRoot(); 49 var shadowRoot = this.webviewNode.createShadowRoot();
89 this.partition = new Partition(); 50 this.setupWebViewAttributes();
90
91 this.setupWebViewSrcAttributeMutationObserver(); 51 this.setupWebViewSrcAttributeMutationObserver();
92 this.setupFocusPropagation(); 52 this.setupFocusPropagation();
93 this.setupWebviewNodeProperties(); 53 this.setupWebviewNodeProperties();
94 54
95 this.viewInstanceId = IdGenerator.GetNextId(); 55 this.viewInstanceId = IdGenerator.GetNextId();
96 56
97 new WebViewEvents(this, this.viewInstanceId); 57 new WebViewEvents(this, this.viewInstanceId);
98 58
99 shadowRoot.appendChild(this.browserPluginNode); 59 shadowRoot.appendChild(this.browserPluginNode);
100 } 60 }
(...skipping 16 matching lines...) Expand all
117 // already picked up a partition ID. Thus, we need to reset the initialization 77 // already picked up a partition ID. Thus, we need to reset the initialization
118 // state. However, it may be the case that beforeFirstNavigation is false BUT 78 // state. However, it may be the case that beforeFirstNavigation is false BUT
119 // guestInstanceId has yet to be initialized. This means that we have not 79 // guestInstanceId has yet to be initialized. This means that we have not
120 // heard back from createGuest yet. We will not reset the flag in this case so 80 // heard back from createGuest yet. We will not reset the flag in this case so
121 // that we don't end up allocating a second guest. 81 // that we don't end up allocating a second guest.
122 if (this.guestInstanceId) { 82 if (this.guestInstanceId) {
123 GuestViewInternal.destroyGuest(this.guestInstanceId); 83 GuestViewInternal.destroyGuest(this.guestInstanceId);
124 this.guestInstanceId = undefined; 84 this.guestInstanceId = undefined;
125 this.beforeFirstNavigation = true; 85 this.beforeFirstNavigation = true;
126 this.validPartitionId = true; 86 this.validPartitionId = true;
127 this.partition.validPartitionId = true; 87 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId =
88 true;
128 this.contentWindow = null; 89 this.contentWindow = null;
129 } 90 }
130 this.internalInstanceId = 0; 91 this.internalInstanceId = 0;
131 }; 92 };
132 93
133 // Sets the <webview>.request property. 94 // Sets the <webview>.request property.
134 WebView.prototype.setRequestPropertyOnWebViewNode = function(request) { 95 WebView.prototype.setRequestPropertyOnWebViewNode = function(request) {
135 Object.defineProperty( 96 Object.defineProperty(
136 this.webviewNode, 97 this.webviewNode,
137 'request', 98 'request',
(...skipping 24 matching lines...) Expand all
162 123
163 // Validation helper function for executeScript() and insertCSS(). 124 // Validation helper function for executeScript() and insertCSS().
164 WebView.prototype.validateExecuteCodeCall = function() { 125 WebView.prototype.validateExecuteCodeCall = function() {
165 if (!this.guestInstanceId) { 126 if (!this.guestInstanceId) {
166 throw new Error(WebViewConstants.ERROR_MSG_CANNOT_INJECT_SCRIPT); 127 throw new Error(WebViewConstants.ERROR_MSG_CANNOT_INJECT_SCRIPT);
167 } 128 }
168 }; 129 };
169 130
170 WebView.prototype.setupAutoSizeProperties = function() { 131 WebView.prototype.setupAutoSizeProperties = function() {
171 $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) { 132 $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) {
172 this[attributeName] = this.webviewNode.getAttribute(attributeName); 133 this.attributes[attributeName].setValue(
134 this.webviewNode.getAttribute(attributeName));
173 Object.defineProperty(this.webviewNode, attributeName, { 135 Object.defineProperty(this.webviewNode, attributeName, {
174 get: function() { 136 get: function() {
175 return this[attributeName]; 137 return this.attributes[attributeName];
176 }.bind(this), 138 }.bind(this),
177 set: function(value) { 139 set: function(value) {
178 this.webviewNode.setAttribute(attributeName, value); 140 this.webviewNode.setAttribute(attributeName, value);
179 }.bind(this), 141 }.bind(this),
180 enumerable: true 142 enumerable: true
181 }); 143 });
182 }.bind(this), this); 144 }.bind(this), this);
183 }; 145 };
184 146
185 WebView.prototype.setupWebviewNodeProperties = function() { 147 WebView.prototype.setupWebviewNodeProperties = function() {
(...skipping 19 matching lines...) Expand all
205 if (this.contentWindow) { 167 if (this.contentWindow) {
206 return this.contentWindow; 168 return this.contentWindow;
207 } 169 }
208 window.console.error( 170 window.console.error(
209 WebViewConstants.ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE); 171 WebViewConstants.ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE);
210 }.bind(this), 172 }.bind(this),
211 // No setter. 173 // No setter.
212 enumerable: true 174 enumerable: true
213 }); 175 });
214 176
215 Object.defineProperty(this.webviewNode, 'name', { 177 Object.defineProperty(this.webviewNode, WebViewConstants.ATTRIBUTE_NAME, {
216 get: function() { 178 get: function() {
217 return this.name; 179 return this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue();
218 }.bind(this), 180 }.bind(this),
219 set: function(value) { 181 set: function(value) {
220 this.webviewNode.setAttribute('name', value); 182 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_NAME, value);
221 }.bind(this), 183 }.bind(this),
222 enumerable: true 184 enumerable: true
223 }); 185 });
224 186
225 Object.defineProperty(this.webviewNode, 'partition', { 187 Object.defineProperty(this.webviewNode,
188 WebViewConstants.ATTRIBUTE_PARTITION, {
226 get: function() { 189 get: function() {
227 return this.partition.toAttribute(); 190 return this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].getValue();
228 }.bind(this), 191 }.bind(this),
229 set: function(value) { 192 set: function(value) {
230 var result = this.partition.fromAttribute(value, this.hasNavigated()); 193 var result = this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].
194 setValue(value);
231 if (result.error) { 195 if (result.error) {
232 throw result.error; 196 throw result.error;
233 } 197 }
234 this.webviewNode.setAttribute('partition', value); 198 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_PARTITION,
199 value);
235 }.bind(this), 200 }.bind(this),
236 enumerable: true 201 enumerable: true
237 }); 202 });
238 203
239 this.src = this.webviewNode.getAttribute('src'); 204 this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue(
240 Object.defineProperty(this.webviewNode, 'src', { 205 this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_SRC));
206 Object.defineProperty(this.webviewNode, WebViewConstants.ATTRIBUTE_SRC, {
241 get: function() { 207 get: function() {
242 return this.src; 208 return this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
243 }.bind(this), 209 }.bind(this),
244 set: function(value) { 210 set: function(value) {
245 this.webviewNode.setAttribute('src', value); 211 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, value);
246 }.bind(this), 212 }.bind(this),
247 // No setter.
248 enumerable: true 213 enumerable: true
249 }); 214 });
250 }; 215 };
251 216
252 // The purpose of this mutation observer is to catch assignment to the src 217 // The purpose of this mutation observer is to catch assignment to the src
253 // attribute without any changes to its value. This is useful in the case 218 // attribute without any changes to its value. This is useful in the case
254 // where the webview guest has crashed and navigating to the same address 219 // where the webview guest has crashed and navigating to the same address
255 // spawns off a new process. 220 // spawns off a new process.
256 WebView.prototype.setupWebViewSrcAttributeMutationObserver = 221 WebView.prototype.setupWebViewSrcAttributeMutationObserver =
257 function() { 222 function() {
258 this.srcAndPartitionObserver = new MutationObserver(function(mutations) { 223 this.srcAndPartitionObserver = new MutationObserver(function(mutations) {
259 $Array.forEach(mutations, function(mutation) { 224 $Array.forEach(mutations, function(mutation) {
260 var oldValue = mutation.oldValue; 225 var oldValue = mutation.oldValue;
261 var newValue = this.webviewNode.getAttribute(mutation.attributeName); 226 var newValue = this.webviewNode.getAttribute(mutation.attributeName);
262 if (oldValue != newValue) { 227 if (oldValue != newValue) {
263 return; 228 return;
264 } 229 }
265 this.handleWebviewAttributeMutation( 230 this.handleWebviewAttributeMutation(
266 mutation.attributeName, oldValue, newValue); 231 mutation.attributeName, oldValue, newValue);
267 }.bind(this)); 232 }.bind(this));
268 }.bind(this)); 233 }.bind(this));
269 var params = { 234 var params = {
270 attributes: true, 235 attributes: true,
271 attributeOldValue: true, 236 attributeOldValue: true,
272 attributeFilter: ['src', 'partition'] 237 attributeFilter: [WebViewConstants.ATTRIBUTE_SRC,
238 WebViewConstants.ATTRIBUTE_PARTITION]
273 }; 239 };
274 this.srcAndPartitionObserver.observe(this.webviewNode, params); 240 this.srcAndPartitionObserver.observe(this.webviewNode, params);
275 }; 241 };
276 242
277 // This observer monitors mutations to attributes of the <webview> and 243 // This observer monitors mutations to attributes of the <webview> and
278 // updates the BrowserPlugin properties accordingly. In turn, updating 244 // updates the BrowserPlugin properties accordingly. In turn, updating
279 // a BrowserPlugin property will update the corresponding BrowserPlugin 245 // a BrowserPlugin property will update the corresponding BrowserPlugin
280 // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more 246 // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more
281 // details. 247 // details.
282 WebView.prototype.handleWebviewAttributeMutation = 248 WebView.prototype.handleWebviewAttributeMutation =
283 function(name, oldValue, newValue) { 249 function(name, oldValue, newValue) {
284 if (AUTO_SIZE_ATTRIBUTES.indexOf(name) > -1) { 250 if (AUTO_SIZE_ATTRIBUTES.indexOf(name) > -1) {
285 this[name] = newValue; 251 this.attributes[name] = newValue;
286 if (!this.guestInstanceId) { 252 if (!this.guestInstanceId) {
287 return; 253 return;
288 } 254 }
289 // Convert autosize attribute to boolean. 255 // Convert autosize attribute to boolean.
256 // TODO(paulmeyer) is this right?
Fady Samuel 2014/10/22 21:48:26 Yes, we're not looking specifically for any value
paulmeyer 2014/10/23 21:39:56 Acknowledged.
290 var autosize = this.webviewNode.hasAttribute( 257 var autosize = this.webviewNode.hasAttribute(
291 WebViewConstants.ATTRIBUTE_AUTOSIZE); 258 WebViewConstants.ATTRIBUTE_AUTOSIZE);
292 GuestViewInternal.setAutoSize(this.guestInstanceId, { 259 GuestViewInternal.setAutoSize(this.guestInstanceId, {
293 'enableAutoSize': autosize, 260 'enableAutoSize': autosize,
294 'min': { 261 'min': {
295 'width': parseInt(this.minwidth || 0), 262 'width': parseInt(this.
296 'height': parseInt(this.minheight || 0) 263 attributes[WebViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0),
264 'height': parseInt(this.
265 attributes[WebViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || 0)
297 }, 266 },
298 'max': { 267 'max': {
299 'width': parseInt(this.maxwidth || 0), 268 'width': parseInt(this.
300 'height': parseInt(this.maxheight || 0) 269 attributes[WebViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || 0),
270 'height': parseInt(this.
271 attributes[WebViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || 0)
301 } 272 }
302 }); 273 });
303 return; 274 return;
304 } else if (name == WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY) { 275 } else if (name == WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY) {
305 // We treat null attribute (attribute removed) and the empty string as 276 // We treat null attribute (attribute removed) and the empty string as
306 // one case. 277 // one case.
307 oldValue = oldValue || ''; 278 oldValue = oldValue || '';
308 newValue = newValue || ''; 279 newValue = newValue || '';
309 280
310 if (oldValue === newValue) { 281 if (oldValue === newValue) {
311 return; 282 return;
312 } 283 }
313 this.allowtransparency = newValue != ''; 284 this.allowtransparency = newValue != '';
314 285
315 if (!this.guestInstanceId) { 286 if (!this.guestInstanceId) {
316 return; 287 return;
317 } 288 }
318 289
319 WebViewInternal.setAllowTransparency(this.guestInstanceId, 290 WebViewInternal.setAllowTransparency(this.guestInstanceId,
320 this.allowtransparency); 291 this.allowtransparency);
321 return; 292 return;
322 } else if (name == 'name') { 293 } else if (name == WebViewConstants.ATTRIBUTE_NAME) {
323 // We treat null attribute (attribute removed) and the empty string as 294 // We treat null attribute (attribute removed) and the empty string as
324 // one case. 295 // one case.
325 oldValue = oldValue || ''; 296 oldValue = oldValue || '';
326 newValue = newValue || ''; 297 newValue = newValue || '';
327 298
328 if (oldValue === newValue) { 299 if (oldValue === newValue) {
329 return; 300 return;
330 } 301 }
331 this.name = newValue; 302 this.attributes[WebViewConstants.ATTRIBUTE_NAME].setValue(newValue);
332 if (!this.guestInstanceId) { 303 if (!this.guestInstanceId) {
333 return; 304 return;
334 } 305 }
335 WebViewInternal.setName(this.guestInstanceId, newValue); 306 WebViewInternal.setName(this.guestInstanceId, newValue);
336 return; 307 return;
337 } else if (name == 'src') { 308 } else if (name == WebViewConstants.ATTRIBUTE_SRC) {
338 // We treat null attribute (attribute removed) and the empty string as 309 // We treat null attribute (attribute removed) and the empty string as
339 // one case. 310 // one case.
340 oldValue = oldValue || ''; 311 oldValue = oldValue || '';
341 newValue = newValue || ''; 312 newValue = newValue || '';
342 // Once we have navigated, we don't allow clearing the src attribute. 313 // Once we have navigated, we don't allow clearing the src attribute.
343 // Once <webview> enters a navigated state, it cannot be return back to a 314 // Once <webview> enters a navigated state, it cannot be return back to a
344 // placeholder state. 315 // placeholder state.
345 if (newValue == '' && oldValue != '') { 316 if (newValue == '' && oldValue != '') {
346 // src attribute changes normally initiate a navigation. We suppress 317 // src attribute changes normally initiate a navigation. We suppress
347 // the next src attribute handler call to avoid reloading the page 318 // the next src attribute handler call to avoid reloading the page
348 // on every guest-initiated navigation. 319 // on every guest-initiated navigation.
349 this.ignoreNextSrcAttributeChange = true; 320 this.ignoreNextSrcAttributeChange = true;
350 this.webviewNode.setAttribute('src', oldValue); 321 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, oldValue);
351 return; 322 return;
352 } 323 }
353 this.src = newValue; 324 this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue(newValue);
354 if (this.ignoreNextSrcAttributeChange) { 325 if (this.ignoreNextSrcAttributeChange) {
355 // Don't allow the src mutation observer to see this change. 326 // Don't allow the src mutation observer to see this change.
356 this.srcAndPartitionObserver.takeRecords(); 327 this.srcAndPartitionObserver.takeRecords();
357 this.ignoreNextSrcAttributeChange = false; 328 this.ignoreNextSrcAttributeChange = false;
358 return; 329 return;
359 } 330 }
360 var result = {}; 331 var result = {};
361 this.parseSrcAttribute(result); 332 this.parseSrcAttribute(result);
362 333
363 if (result.error) { 334 if (result.error) {
364 throw result.error; 335 throw result.error;
365 } 336 }
366 } else if (name == 'partition') { 337 } else if (name == WebViewConstants.ATTRIBUTE_PARTITION) {
367 // Note that throwing error here won't synchronously propagate. 338 // Note that throwing error here won't synchronously propagate.
368 this.partition.fromAttribute(newValue, this.hasNavigated()); 339 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue(newValue);
369 } 340 }
370 }; 341 };
371 342
372 WebView.prototype.handleBrowserPluginAttributeMutation = 343 WebView.prototype.handleBrowserPluginAttributeMutation =
373 function(name, oldValue, newValue) { 344 function(name, oldValue, newValue) {
374 if (name == 'internalinstanceid' && !oldValue && !!newValue) { 345 if (name == BROWSER_PLUGIN_ATTRIBUTE_INTERNALINSTANCEID &&
375 this.browserPluginNode.removeAttribute('internalinstanceid'); 346 !oldValue && !!newValue) {
347 this.browserPluginNode.removeAttribute(
348 BROWSER_PLUGIN_ATTRIBUTE_INTERNALINSTANCEID);
376 this.internalInstanceId = parseInt(newValue); 349 this.internalInstanceId = parseInt(newValue);
377 350
378 if (!!this.guestInstanceId && this.guestInstanceId != 0) { 351 if (!!this.guestInstanceId && this.guestInstanceId != 0) {
379 var isNewWindow = this.deferredAttachState ? 352 var isNewWindow = this.deferredAttachState ?
380 this.deferredAttachState.isNewWindow : false; 353 this.deferredAttachState.isNewWindow : false;
381 var params = this.buildAttachParams(isNewWindow); 354 var params = this.buildAttachParams(isNewWindow);
382 guestViewInternalNatives.AttachGuest( 355 guestViewInternalNatives.AttachGuest(
383 this.internalInstanceId, 356 this.internalInstanceId,
384 this.guestInstanceId, 357 this.guestInstanceId,
385 params, 358 params,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 // Returns if <object> is in the render tree. 431 // Returns if <object> is in the render tree.
459 WebView.prototype.isPluginInRenderTree = function() { 432 WebView.prototype.isPluginInRenderTree = function() {
460 return !!this.internalInstanceId && this.internalInstanceId != 0; 433 return !!this.internalInstanceId && this.internalInstanceId != 0;
461 }; 434 };
462 435
463 WebView.prototype.hasNavigated = function() { 436 WebView.prototype.hasNavigated = function() {
464 return !this.beforeFirstNavigation; 437 return !this.beforeFirstNavigation;
465 }; 438 };
466 439
467 WebView.prototype.parseSrcAttribute = function(result) { 440 WebView.prototype.parseSrcAttribute = function(result) {
468 if (!this.partition.validPartitionId) { 441 if (!this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId) {
469 result.error = WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; 442 result.error = WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE;
470 return; 443 return;
471 } 444 }
472 this.src = this.webviewNode.getAttribute('src'); 445 this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue(
446 this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_SRC));
473 447
474 if (!this.src) { 448 if (!this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()) {
475 return; 449 return;
476 } 450 }
477 451
478 if (this.guestInstanceId == undefined) { 452 if (this.guestInstanceId == undefined) {
479 if (this.beforeFirstNavigation) { 453 if (this.beforeFirstNavigation) {
480 this.beforeFirstNavigation = false; 454 this.beforeFirstNavigation = false;
481 this.createGuest(); 455 this.createGuest();
482 } 456 }
483 return; 457 return;
484 } 458 }
485 459
486 // Navigate to |this.src|. 460 // Navigate to |this.src|.
487 WebViewInternal.navigate(this.guestInstanceId, this.src); 461 WebViewInternal.navigate(
462 this.guestInstanceId,
463 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue());
488 }; 464 };
489 465
490 WebView.prototype.parseAttributes = function() { 466 WebView.prototype.parseAttributes = function() {
491 if (!this.elementAttached) { 467 if (!this.elementAttached) {
492 return; 468 return;
493 } 469 }
494 var hasNavigated = this.hasNavigated(); 470 var attributeValue = this.webviewNode.getAttribute(
495 var attributeValue = this.webviewNode.getAttribute('partition'); 471 WebViewConstants.ATTRIBUTE_PARTITION);
496 var result = this.partition.fromAttribute(attributeValue, hasNavigated); 472 var result = this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue(
473 attributeValue);
497 this.parseSrcAttribute(result); 474 this.parseSrcAttribute(result);
498 }; 475 };
499 476
500 WebView.prototype.createGuest = function() { 477 WebView.prototype.createGuest = function() {
501 if (this.pendingGuestCreation) { 478 if (this.pendingGuestCreation) {
502 return; 479 return;
503 } 480 }
481 // TODO(paulmeyer) this looks wacky.
Fady Samuel 2014/10/22 21:48:26 Please ask Istiaque about this. I'm not sure why t
paulmeyer 2014/10/23 21:39:55 This will get cleaned up when I unify the storage/
504 var storagePartitionId = 482 var storagePartitionId =
505 this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_PARTITION) || 483 this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_PARTITION) ||
506 this.webviewNode[WebViewConstants.ATTRIBUTE_PARTITION]; 484 this.webviewNode[WebViewConstants.ATTRIBUTE_PARTITION];
507 var params = { 485 var params = {
508 'storagePartitionId': storagePartitionId 486 'storagePartitionId': storagePartitionId
509 }; 487 };
510 GuestViewInternal.createGuest( 488 GuestViewInternal.createGuest(
511 'webview', 489 'webview',
512 params, 490 params,
513 function(guestInstanceId) { 491 function(guestInstanceId) {
514 this.pendingGuestCreation = false; 492 this.pendingGuestCreation = false;
515 if (!this.elementAttached) { 493 if (!this.elementAttached) {
516 GuestViewInternal.destroyGuest(guestInstanceId); 494 GuestViewInternal.destroyGuest(guestInstanceId);
517 return; 495 return;
518 } 496 }
519 this.attachWindow(guestInstanceId, false); 497 this.attachWindow(guestInstanceId, false);
520 }.bind(this) 498 }.bind(this)
521 ); 499 );
522 this.pendingGuestCreation = true; 500 this.pendingGuestCreation = true;
523 }; 501 };
524 502
525 WebView.prototype.onFrameNameChanged = function(name) { 503 WebView.prototype.onFrameNameChanged = function(name) {
526 this.name = name || ''; 504 this.attributes[WebViewConstants.ATTRIBUTE_NAME].setValue(name || '');
527 if (this.name === '') { 505 if (this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue() === '') {
528 this.webviewNode.removeAttribute('name'); 506 this.webviewNode.removeAttribute(WebViewConstants.ATTRIBUTE_NAME);
529 } else { 507 } else {
530 this.webviewNode.setAttribute('name', this.name); 508 this.webviewNode.setAttribute(
509 WebViewConstants.ATTRIBUTE_NAME,
510 this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue());
531 } 511 }
532 }; 512 };
533 513
534 WebView.prototype.dispatchEvent = function(webViewEvent) { 514 WebView.prototype.dispatchEvent = function(webViewEvent) {
535 return this.webviewNode.dispatchEvent(webViewEvent); 515 return this.webviewNode.dispatchEvent(webViewEvent);
536 }; 516 };
537 517
538 // Adds an 'on<event>' property on the webview, which can be used to set/unset 518 // Adds an 'on<event>' property on the webview, which can be used to set/unset
539 // an event handler. 519 // an event handler.
540 WebView.prototype.setupEventProperty = function(eventName) { 520 WebView.prototype.setupEventProperty = function(eventName) {
(...skipping 14 matching lines...) Expand all
555 }; 535 };
556 536
557 // Updates state upon loadcommit. 537 // Updates state upon loadcommit.
558 WebView.prototype.onLoadCommit = function( 538 WebView.prototype.onLoadCommit = function(
559 baseUrlForDataUrl, currentEntryIndex, entryCount, 539 baseUrlForDataUrl, currentEntryIndex, entryCount,
560 processId, url, isTopLevel) { 540 processId, url, isTopLevel) {
561 this.baseUrlForDataUrl = baseUrlForDataUrl; 541 this.baseUrlForDataUrl = baseUrlForDataUrl;
562 this.currentEntryIndex = currentEntryIndex; 542 this.currentEntryIndex = currentEntryIndex;
563 this.entryCount = entryCount; 543 this.entryCount = entryCount;
564 this.processId = processId; 544 this.processId = processId;
565 var oldValue = this.webviewNode.getAttribute('src'); 545 var oldValue = this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_SRC);
566 var newValue = url; 546 var newValue = url;
567 if (isTopLevel && (oldValue != newValue)) { 547 if (isTopLevel && (oldValue != newValue)) {
568 // Touching the src attribute triggers a navigation. To avoid 548 // Touching the src attribute triggers a navigation. To avoid
569 // triggering a page reload on every guest-initiated navigation, 549 // triggering a page reload on every guest-initiated navigation,
570 // we use the flag ignoreNextSrcAttributeChange here. 550 // we use the flag ignoreNextSrcAttributeChange here.
571 this.ignoreNextSrcAttributeChange = true; 551 this.ignoreNextSrcAttributeChange = true;
572 this.webviewNode.setAttribute('src', newValue); 552 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, newValue);
573 } 553 }
574 }; 554 };
575 555
576 WebView.prototype.onAttach = function(storagePartitionId) { 556 WebView.prototype.onAttach = function(storagePartitionId) {
577 this.webviewNode.setAttribute('partition', storagePartitionId); 557 this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_PARTITION,
578 this.partition.fromAttribute(storagePartitionId, this.hasNavigated()); 558 storagePartitionId);
559 this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue(
560 storagePartitionId);
579 }; 561 };
580 562
581 WebView.prototype.buildAttachParams = function(isNewWindow) { 563 WebView.prototype.buildAttachParams = function(isNewWindow) {
582 var params = { 564 var params = {
583 'allowtransparency': this.allowtransparency || false, 565 'allowtransparency': this.allowtransparency || false,
584 'autosize': this.webviewNode.hasAttribute( 566 'autosize': this.webviewNode.hasAttribute(
585 WebViewConstants.ATTRIBUTE_AUTOSIZE), 567 WebViewConstants.ATTRIBUTE_AUTOSIZE),
586 'instanceId': this.viewInstanceId, 568 'instanceId': this.viewInstanceId,
587 'maxheight': parseInt(this.maxheight || 0), 569 'maxheight': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MAXHEIGHT].
Fady Samuel 2014/10/22 21:48:26 I feel like the key names should probably also mat
paulmeyer 2014/10/23 21:39:56 I agree, and hopefully there will be a nice concis
588 'maxwidth': parseInt(this.maxwidth || 0), 570 getValue() || 0),
589 'minheight': parseInt(this.minheight || 0), 571 'maxwidth': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MAXWIDTH].
590 'minwidth': parseInt(this.minwidth || 0), 572 getValue() || 0),
591 'name': this.name, 573 'minheight': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MINHEIGHT].
574 getValue() || 0),
575 'minwidth': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MINWIDTH].
576 getValue() || 0),
577 'name': this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue(),
592 // We don't need to navigate new window from here. 578 // We don't need to navigate new window from here.
593 'src': isNewWindow ? undefined : this.src, 579 'src': isNewWindow ? undefined :
580 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue(),
594 // If we have a partition from the opener, that will also be already 581 // If we have a partition from the opener, that will also be already
595 // set via this.onAttach(). 582 // set via this.onAttach().
596 'storagePartitionId': this.partition.toAttribute(), 583 'storagePartitionId': this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].
584 getValue(),
597 'userAgentOverride': this.userAgentOverride 585 'userAgentOverride': this.userAgentOverride
598 }; 586 };
599 return params; 587 return params;
600 }; 588 };
601 589
602 WebView.prototype.attachWindow = function(guestInstanceId, 590 WebView.prototype.attachWindow = function(guestInstanceId,
603 isNewWindow) { 591 isNewWindow) {
604 this.guestInstanceId = guestInstanceId; 592 this.guestInstanceId = guestInstanceId;
605 var params = this.buildAttachParams(isNewWindow); 593 var params = this.buildAttachParams(isNewWindow);
606 594
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 if (!this.guestInstanceId) { 632 if (!this.guestInstanceId) {
645 return; 633 return;
646 } 634 }
647 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments)); 635 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments));
648 $Function.apply(WebViewInternal.clearData, null, args); 636 $Function.apply(WebViewInternal.clearData, null, args);
649 }; 637 };
650 638
651 // Injects JavaScript code into the guest page. 639 // Injects JavaScript code into the guest page.
652 WebView.prototype.executeScript = function(var_args) { 640 WebView.prototype.executeScript = function(var_args) {
653 this.validateExecuteCodeCall(); 641 this.validateExecuteCodeCall();
654 var webviewSrc = this.src; 642 var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
655 if (this.baseUrlForDataUrl != '') { 643 if (this.baseUrlForDataUrl != '') {
656 webviewSrc = this.baseUrlForDataUrl; 644 webviewSrc = this.baseUrlForDataUrl;
657 } 645 }
658 var args = $Array.concat([this.guestInstanceId, webviewSrc], 646 var args = $Array.concat([this.guestInstanceId, webviewSrc],
659 $Array.slice(arguments)); 647 $Array.slice(arguments));
660 $Function.apply(WebViewInternal.executeScript, null, args); 648 $Function.apply(WebViewInternal.executeScript, null, args);
661 }; 649 };
662 650
663 // Initiates a find-in-page request. 651 // Initiates a find-in-page request.
664 WebView.prototype.find = function(search_text, options, callback) { 652 WebView.prototype.find = function(search_text, options, callback) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 WebView.prototype.go = function(relativeIndex, callback) { 685 WebView.prototype.go = function(relativeIndex, callback) {
698 if (!this.guestInstanceId) { 686 if (!this.guestInstanceId) {
699 return; 687 return;
700 } 688 }
701 WebViewInternal.go(this.guestInstanceId, relativeIndex, callback); 689 WebViewInternal.go(this.guestInstanceId, relativeIndex, callback);
702 }; 690 };
703 691
704 // Injects CSS into the guest page. 692 // Injects CSS into the guest page.
705 WebView.prototype.insertCSS = function(var_args) { 693 WebView.prototype.insertCSS = function(var_args) {
706 this.validateExecuteCodeCall(); 694 this.validateExecuteCodeCall();
707 var webviewSrc = this.src; 695 var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
708 if (this.baseUrlForDataUrl != '') { 696 if (this.baseUrlForDataUrl != '') {
709 webviewSrc = this.baseUrlForDataUrl; 697 webviewSrc = this.baseUrlForDataUrl;
710 } 698 }
711 var args = $Array.concat([this.guestInstanceId, webviewSrc], 699 var args = $Array.concat([this.guestInstanceId, webviewSrc],
712 $Array.slice(arguments)); 700 $Array.slice(arguments));
713 $Function.apply(WebViewInternal.insertCSS, null, args); 701 $Function.apply(WebViewInternal.insertCSS, null, args);
714 }; 702 };
715 703
716 // Indicates whether or not the webview's user agent string has been overridden. 704 // Indicates whether or not the webview's user agent string has been overridden.
717 WebView.prototype.isUserAgentOverridden = function() { 705 WebView.prototype.isUserAgentOverridden = function() {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 WebView.prototype.maybeGetChromeWebViewEvents = function() {}; 901 WebView.prototype.maybeGetChromeWebViewEvents = function() {};
914 902
915 // Implemented when the experimental WebView API is available. 903 // Implemented when the experimental WebView API is available.
916 WebView.maybeGetExperimentalAPIs = function() {}; 904 WebView.maybeGetExperimentalAPIs = function() {};
917 WebView.prototype.maybeGetExperimentalEvents = function() {}; 905 WebView.prototype.maybeGetExperimentalEvents = function() {};
918 WebView.prototype.setupExperimentalContextMenus = function() {}; 906 WebView.prototype.setupExperimentalContextMenus = function() {};
919 907
920 // Exports. 908 // Exports.
921 exports.WebView = WebView; 909 exports.WebView = WebView;
922 exports.WebViewInternal = WebViewInternal; 910 exports.WebViewInternal = WebViewInternal;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698