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

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

Issue 299753011: Move allocate instance id to chrome/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more comments addressed Created 6 years, 6 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 EventBindings = require('event_bindings'); 10 var EventBindings = require('event_bindings');
11 var GuestView = require('binding').Binding.create('guestview').generate();
11 var IdGenerator = requireNative('id_generator'); 12 var IdGenerator = requireNative('id_generator');
12 var MessagingNatives = requireNative('messaging_natives'); 13 var MessagingNatives = requireNative('messaging_natives');
13 var WebRequestEvent = require('webRequestInternal').WebRequestEvent; 14 var WebRequestEvent = require('webRequestInternal').WebRequestEvent;
14 var WebRequestSchema = 15 var WebRequestSchema =
15 requireNative('schema_registry').GetSchema('webRequest'); 16 requireNative('schema_registry').GetSchema('webRequest');
16 var DeclarativeWebRequestSchema = 17 var DeclarativeWebRequestSchema =
17 requireNative('schema_registry').GetSchema('declarativeWebRequest'); 18 requireNative('schema_registry').GetSchema('declarativeWebRequest');
18 var WebView = require('webview').WebView; 19 var WebView = require('webview').WebView;
19 20
20 var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight'; 21 var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight';
21 var WEB_VIEW_ATTRIBUTE_MAXWIDTH = 'maxwidth'; 22 var WEB_VIEW_ATTRIBUTE_MAXWIDTH = 'maxwidth';
22 var WEB_VIEW_ATTRIBUTE_MINHEIGHT = 'minheight'; 23 var WEB_VIEW_ATTRIBUTE_MINHEIGHT = 'minheight';
23 var WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth'; 24 var WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth';
25 var WEB_VIEW_ATTRIBUTE_PARTITION = 'partition';
26
27 var ERROR_MSG_ALREADY_NAVIGATED =
28 'The object has already navigated, so its partition cannot be changed.';
29 var ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.';
24 30
25 /** @type {Array.<string>} */ 31 /** @type {Array.<string>} */
26 var WEB_VIEW_ATTRIBUTES = [ 32 var WEB_VIEW_ATTRIBUTES = [
27 'allowtransparency', 33 'allowtransparency',
28 'autosize', 34 'autosize',
29 'partition',
30 WEB_VIEW_ATTRIBUTE_MINHEIGHT, 35 WEB_VIEW_ATTRIBUTE_MINHEIGHT,
31 WEB_VIEW_ATTRIBUTE_MINWIDTH, 36 WEB_VIEW_ATTRIBUTE_MINWIDTH,
32 WEB_VIEW_ATTRIBUTE_MAXHEIGHT, 37 WEB_VIEW_ATTRIBUTE_MAXHEIGHT,
33 WEB_VIEW_ATTRIBUTE_MAXWIDTH 38 WEB_VIEW_ATTRIBUTE_MAXWIDTH
34 ]; 39 ];
35 40
41 /** @class representing state of storage partition. */
42 function Partition() {
43 this.validPartitionId = true;
44 this.persist_storage_ = false;
45 this.storage_partition_id = '';
46 };
47
48 Partition.prototype.toAttribute = function() {
49 if (!this.validPartitionId) {
50 return '';
51 }
52 return (this.persist_storage_ ? 'persist:' : '') + this.storage_partition_id;
53 };
54
55 Partition.prototype.fromAttribute = function(value, hasNavigated) {
56 var result = {};
57 if (hasNavigated) {
58 result.error = ERROR_MSG_ALREADY_NAVIGATED;
59 return result;
60 }
61 if (!value) {
62 value = '';
63 }
64
65 var LEN = 'persist:'.length;
66 if (value.substr(0, LEN) == 'persist:') {
67 value = value.substr(LEN);
68 if (!value) {
69 this.validPartitionId = false;
70 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE;
71 return result;
72 }
73 this.persist_storage_ = true;
74 } else {
75 this.persist_storage_ = false;
76 }
77
78 this.storage_partition_id = value;
79 return result;
80 };
81
36 var CreateEvent = function(name) { 82 var CreateEvent = function(name) {
37 var eventOpts = {supportsListeners: true, supportsFilters: true}; 83 var eventOpts = {supportsListeners: true, supportsFilters: true};
38 return new EventBindings.Event(name, undefined, eventOpts); 84 return new EventBindings.Event(name, undefined, eventOpts);
39 }; 85 };
40 86
41 // WEB_VIEW_EVENTS is a map of stable <webview> DOM event names to their 87 // WEB_VIEW_EVENTS is a map of stable <webview> DOM event names to their
42 // associated extension event descriptor objects. 88 // associated extension event descriptor objects.
43 // An event listener will be attached to the extension event |evt| specified in 89 // An event listener will be attached to the extension event |evt| specified in
44 // the descriptor. 90 // the descriptor.
45 // |fields| specifies the public-facing fields in the DOM event that are 91 // |fields| specifies the public-facing fields in the DOM event that are
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 // Implemented when the experimental API is available. 215 // Implemented when the experimental API is available.
170 WebViewInternal.maybeRegisterExperimentalAPIs = function(proto) {} 216 WebViewInternal.maybeRegisterExperimentalAPIs = function(proto) {}
171 217
172 /** 218 /**
173 * @constructor 219 * @constructor
174 */ 220 */
175 function WebViewInternal(webviewNode) { 221 function WebViewInternal(webviewNode) {
176 privates(webviewNode).internal = this; 222 privates(webviewNode).internal = this;
177 this.webviewNode = webviewNode; 223 this.webviewNode = webviewNode;
178 this.attached = false; 224 this.attached = false;
225
226 this.beforeFirstNavigation = true;
227 this.validPartitionId = true;
228
179 this.browserPluginNode = this.createBrowserPluginNode(); 229 this.browserPluginNode = this.createBrowserPluginNode();
180 var shadowRoot = this.webviewNode.createShadowRoot(); 230 var shadowRoot = this.webviewNode.createShadowRoot();
181 shadowRoot.appendChild(this.browserPluginNode); 231 shadowRoot.appendChild(this.browserPluginNode);
182 232
183 this.setupWebviewNodeAttributes(); 233 this.setupWebviewNodeAttributes();
184 this.setupFocusPropagation(); 234 this.setupFocusPropagation();
185 this.setupWebviewNodeProperties(); 235 this.setupWebviewNodeProperties();
236
237 this.viewInstanceId = IdGenerator.GetNextId();
238
239 //this.allocateInstanceId();
Fady Samuel 2014/06/04 04:54:18 Remove this?
240 this.partition = new Partition();
241 this.parseAttributes();
242
186 this.setupWebviewNodeEvents(); 243 this.setupWebviewNodeEvents();
187 } 244 }
188 245
189 /** 246 /**
190 * @private 247 * @private
191 */ 248 */
192 WebViewInternal.prototype.createBrowserPluginNode = function() { 249 WebViewInternal.prototype.createBrowserPluginNode = function() {
193 // We create BrowserPlugin as a custom element in order to observe changes 250 // We create BrowserPlugin as a custom element in order to observe changes
194 // to attributes synchronously. 251 // to attributes synchronously.
195 var browserPluginNode = new WebViewInternal.BrowserPlugin(); 252 var browserPluginNode = new WebViewInternal.BrowserPlugin();
196 privates(browserPluginNode).internal = this; 253 privates(browserPluginNode).internal = this;
197 254
198 var ALL_ATTRIBUTES = WEB_VIEW_ATTRIBUTES.concat(['src']); 255 $Array.forEach(WEB_VIEW_ATTRIBUTES, function(attributeName) {
199 $Array.forEach(ALL_ATTRIBUTES, function(attributeName) {
200 // Only copy attributes that have been assigned values, rather than copying 256 // Only copy attributes that have been assigned values, rather than copying
201 // a series of undefined attributes to BrowserPlugin. 257 // a series of undefined attributes to BrowserPlugin.
202 if (this.webviewNode.hasAttribute(attributeName)) { 258 if (this.webviewNode.hasAttribute(attributeName)) {
203 browserPluginNode.setAttribute( 259 browserPluginNode.setAttribute(
204 attributeName, this.webviewNode.getAttribute(attributeName)); 260 attributeName, this.webviewNode.getAttribute(attributeName));
205 } else if (this.webviewNode[attributeName]){ 261 } else if (this.webviewNode[attributeName]){
206 // Reading property using has/getAttribute does not work on 262 // Reading property using has/getAttribute does not work on
207 // document.DOMContentLoaded event (but works on 263 // document.DOMContentLoaded event (but works on
208 // window.DOMContentLoaded event). 264 // window.DOMContentLoaded event).
209 // So copy from property if copying from attribute fails. 265 // So copy from property if copying from attribute fails.
210 browserPluginNode.setAttribute( 266 browserPluginNode.setAttribute(
211 attributeName, this.webviewNode[attributeName]); 267 attributeName, this.webviewNode[attributeName]);
212 } 268 }
213 }, this); 269 }, this);
214 270
215 return browserPluginNode; 271 return browserPluginNode;
216 }; 272 };
217 273
218 /** 274 /**
219 * @private 275 * @private
276 * Resets some state upon re-attaching <webview> element to the DOM.
277 */
278 WebViewInternal.prototype.resetUponReattachment = function() {
279 this.instanceId = undefined;
280 this.beforeFirstNavigation = true;
281 this.validPartitionId = true;
282 this.partition.validPartitionId = true;
283 };
284
285 /**
286 * @private
220 */ 287 */
221 WebViewInternal.prototype.setupFocusPropagation = function() { 288 WebViewInternal.prototype.setupFocusPropagation = function() {
222 if (!this.webviewNode.hasAttribute('tabIndex')) { 289 if (!this.webviewNode.hasAttribute('tabIndex')) {
223 // <webview> needs a tabIndex in order to be focusable. 290 // <webview> needs a tabIndex in order to be focusable.
224 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute 291 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute
225 // to allow <webview> to be focusable. 292 // to allow <webview> to be focusable.
226 // See http://crbug.com/231664. 293 // See http://crbug.com/231664.
227 this.webviewNode.setAttribute('tabIndex', -1); 294 this.webviewNode.setAttribute('tabIndex', -1);
228 } 295 }
229 var self = this; 296 var self = this;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 Object.defineProperty(this.webviewNode, 'name', { 459 Object.defineProperty(this.webviewNode, 'name', {
393 get: function() { 460 get: function() {
394 return self.name; 461 return self.name;
395 }, 462 },
396 set: function(value) { 463 set: function(value) {
397 self.webviewNode.setAttribute('name', value); 464 self.webviewNode.setAttribute('name', value);
398 }, 465 },
399 enumerable: true 466 enumerable: true
400 }); 467 });
401 468
469 Object.defineProperty(this.webviewNode, 'partition', {
470 get: function() {
471 return self.partition.toAttribute();
472 },
473 set: function(value) {
474 var result = self.partition.fromAttribute(value, self.hasNavigated());
475 if (result.error) {
476 throw result.error;
477 }
478 self.webviewNode.setAttribute('partition', value);
479 },
480 enumerable: true
481 });
482
402 // We cannot use {writable: true} property descriptor because we want a 483 // We cannot use {writable: true} property descriptor because we want a
403 // dynamic getter value. 484 // dynamic getter value.
404 Object.defineProperty(this.webviewNode, 'contentWindow', { 485 Object.defineProperty(this.webviewNode, 'contentWindow', {
405 get: function() { 486 get: function() {
406 if (browserPluginNode.contentWindow) 487 if (browserPluginNode.contentWindow)
407 return browserPluginNode.contentWindow; 488 return browserPluginNode.contentWindow;
408 window.console.error(ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE); 489 window.console.error(ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE);
409 }, 490 },
410 // No setter. 491 // No setter.
411 enumerable: true 492 enumerable: true
(...skipping 10 matching lines...) Expand all
422 /** 503 /**
423 * @private 504 * @private
424 */ 505 */
425 WebViewInternal.prototype.setupWebViewSrcAttributeMutationObserver = 506 WebViewInternal.prototype.setupWebViewSrcAttributeMutationObserver =
426 function() { 507 function() {
427 // The purpose of this mutation observer is to catch assignment to the src 508 // The purpose of this mutation observer is to catch assignment to the src
428 // attribute without any changes to its value. This is useful in the case 509 // attribute without any changes to its value. This is useful in the case
429 // where the webview guest has crashed and navigating to the same address 510 // where the webview guest has crashed and navigating to the same address
430 // spawns off a new process. 511 // spawns off a new process.
431 var self = this; 512 var self = this;
432 this.srcObserver = new MutationObserver(function(mutations) { 513 this.srcAndPartitionObserver = new MutationObserver(function(mutations) {
433 $Array.forEach(mutations, function(mutation) { 514 $Array.forEach(mutations, function(mutation) {
434 var oldValue = mutation.oldValue; 515 var oldValue = mutation.oldValue;
435 var newValue = self.webviewNode.getAttribute(mutation.attributeName); 516 var newValue = self.webviewNode.getAttribute(mutation.attributeName);
436 if (oldValue != newValue) { 517 if (oldValue != newValue) {
437 return; 518 return;
438 } 519 }
439 self.handleWebviewAttributeMutation( 520 self.handleWebviewAttributeMutation(
440 mutation.attributeName, oldValue, newValue); 521 mutation.attributeName, oldValue, newValue);
441 }); 522 });
442 }); 523 });
443 var params = { 524 var params = {
444 attributes: true, 525 attributes: true,
445 attributeOldValue: true, 526 attributeOldValue: true,
446 attributeFilter: ['src'] 527 attributeFilter: ['src', 'partition']
447 }; 528 };
448 this.srcObserver.observe(this.webviewNode, params); 529 this.srcAndPartitionObserver.observe(this.webviewNode, params);
449 }; 530 };
450 531
451 /** 532 /**
452 * @private 533 * @private
453 */ 534 */
454 WebViewInternal.prototype.handleWebviewAttributeMutation = 535 WebViewInternal.prototype.handleWebviewAttributeMutation =
455 function(name, oldValue, newValue) { 536 function(name, oldValue, newValue) {
456 // This observer monitors mutations to attributes of the <webview> and 537 // This observer monitors mutations to attributes of the <webview> and
457 // updates the BrowserPlugin properties accordingly. In turn, updating 538 // updates the BrowserPlugin properties accordingly. In turn, updating
458 // a BrowserPlugin property will update the corresponding BrowserPlugin 539 // a BrowserPlugin property will update the corresponding BrowserPlugin
(...skipping 26 matching lines...) Expand all
485 // src attribute changes normally initiate a navigation. We suppress 566 // src attribute changes normally initiate a navigation. We suppress
486 // the next src attribute handler call to avoid reloading the page 567 // the next src attribute handler call to avoid reloading the page
487 // on every guest-initiated navigation. 568 // on every guest-initiated navigation.
488 this.ignoreNextSrcAttributeChange = true; 569 this.ignoreNextSrcAttributeChange = true;
489 this.webviewNode.setAttribute('src', oldValue); 570 this.webviewNode.setAttribute('src', oldValue);
490 return; 571 return;
491 } 572 }
492 this.src = newValue; 573 this.src = newValue;
493 if (this.ignoreNextSrcAttributeChange) { 574 if (this.ignoreNextSrcAttributeChange) {
494 // Don't allow the src mutation observer to see this change. 575 // Don't allow the src mutation observer to see this change.
495 this.srcObserver.takeRecords(); 576 this.srcAndPartitionObserver.takeRecords();
496 this.ignoreNextSrcAttributeChange = false; 577 this.ignoreNextSrcAttributeChange = false;
497 return; 578 return;
498 } 579 }
580 var result = {};
581 this.parseSrcAttribute(result);
582
583 if (result.error) {
584 throw result.error;
585 }
586 } else if (name == 'partition') {
587 // Note that throwing error here won't synchronously propagate.
588 this.partition.fromAttribute(newValue, this.hasNavigated());
499 } 589 }
590
591 // No <webview> -> <object> mutation propagation for these attributes.
592 if (name == 'src' || name == 'partition') {
593 return;
594 }
595
500 if (this.browserPluginNode.hasOwnProperty(name)) { 596 if (this.browserPluginNode.hasOwnProperty(name)) {
501 this.browserPluginNode[name] = newValue; 597 this.browserPluginNode[name] = newValue;
502 } else { 598 } else {
503 this.browserPluginNode.setAttribute(name, newValue); 599 this.browserPluginNode.setAttribute(name, newValue);
504 } 600 }
505 }; 601 };
506 602
507 /** 603 /**
508 * @private 604 * @private
509 */ 605 */
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 if (webViewEvent.newWidth >= minWidth && 686 if (webViewEvent.newWidth >= minWidth &&
591 webViewEvent.newWidth <= maxWidth && 687 webViewEvent.newWidth <= maxWidth &&
592 webViewEvent.newHeight >= minHeight && 688 webViewEvent.newHeight >= minHeight &&
593 webViewEvent.newHeight <= maxHeight) { 689 webViewEvent.newHeight <= maxHeight) {
594 node.style.width = webViewEvent.newWidth + 'px'; 690 node.style.width = webViewEvent.newWidth + 'px';
595 node.style.height = webViewEvent.newHeight + 'px'; 691 node.style.height = webViewEvent.newHeight + 'px';
596 } 692 }
597 node.dispatchEvent(webViewEvent); 693 node.dispatchEvent(webViewEvent);
598 }; 694 };
599 695
696 WebViewInternal.prototype.hasNavigated = function() {
697 return !this.beforeFirstNavigation;
698 };
699
700 /** @return {boolean} */
701 WebViewInternal.prototype.parseSrcAttribute = function(result) {
702 if (!this.partition.validPartitionId) {
703 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE;
704 return false;
705 }
706 this.src = this.webviewNode.getAttribute('src');
707
708 if (!this.src) {
709 return true;
710 }
711
712 if (!this.hasGuestInstanceID()) {
713 if (this.beforeFirstNavigation) {
714 this.beforeFirstNavigation = false;
715 this.allocateInstanceId();
716 }
717 return true;
718 }
719
720 // Navigate to this.src.
721 WebView.navigate(this.instanceId, this.src);
722 return true;
723 };
724
725 /** @return {boolean} */
726 WebViewInternal.prototype.parseAttributes = function() {
727 var hasNavigated = this.hasNavigated();
728 var attributeValue = this.webviewNode.getAttribute('partition');
729 var result = this.partition.fromAttribute(attributeValue, hasNavigated);
730 return this.parseSrcAttribute(result);
731 };
732
733 WebViewInternal.prototype.hasGuestInstanceID = function() {
734 return this.instanceId != undefined;
735 };
736
737 WebViewInternal.prototype.allocateInstanceId = function() {
738 // Parse .src and .partition.
739 var self = this;
740 GuestView.allocateInstanceId(
741 function(instanceId) {
742 self.instanceId = instanceId;
743 // TODO(lazyboy): Make sure this.autoNavigate_ stuff correctly updated
744 // |self.src| at this point.
745 self.attachWindowAndSetUpEvents(self.instanceId, self.src);
746 });
747 };
748
600 /** 749 /**
601 * @private 750 * @private
602 */ 751 */
603 WebViewInternal.prototype.setupWebviewNodeEvents = function() { 752 WebViewInternal.prototype.setupWebviewNodeEvents = function() {
604 var self = this;
605 this.viewInstanceId = IdGenerator.GetNextId();
606 var onInstanceIdAllocated = function(e) {
607 var detail = e.detail ? JSON.parse(e.detail) : {};
608 self.attachWindowAndSetUpEvents(detail.windowId);
609 };
610 this.browserPluginNode.addEventListener('-internal-instanceid-allocated',
611 onInstanceIdAllocated);
612 this.setupWebRequestEvents(); 753 this.setupWebRequestEvents();
613 this.setupExperimentalContextMenus_(); 754 this.setupExperimentalContextMenus_();
614 755
615 this.on = {}; 756 this.on = {};
616 var events = self.getEvents(); 757 var events = this.getEvents();
617 for (var eventName in events) { 758 for (var eventName in events) {
618 this.setupEventProperty(eventName); 759 this.setupEventProperty(eventName);
619 } 760 }
620 }; 761 };
621 762
622 /** 763 /**
623 * @private 764 * @private
624 */ 765 */
625 WebViewInternal.prototype.setupNameAttribute = function() { 766 WebViewInternal.prototype.setupNameAttribute = function() {
626 var self = this; 767 var self = this;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 validateCall(); 979 validateCall();
839 if (!webview || !webview.tagName || webview.tagName != 'WEBVIEW') 980 if (!webview || !webview.tagName || webview.tagName != 'WEBVIEW')
840 throw new Error(ERROR_MSG_WEBVIEW_EXPECTED); 981 throw new Error(ERROR_MSG_WEBVIEW_EXPECTED);
841 // Attach happens asynchronously to give the tagWatcher an opportunity 982 // Attach happens asynchronously to give the tagWatcher an opportunity
842 // to pick up the new webview before attach operates on it, if it hasn't 983 // to pick up the new webview before attach operates on it, if it hasn't
843 // been attached to the DOM already. 984 // been attached to the DOM already.
844 // Note: Any subsequent errors cannot be exceptions because they happen 985 // Note: Any subsequent errors cannot be exceptions because they happen
845 // asynchronously. 986 // asynchronously.
846 setTimeout(function() { 987 setTimeout(function() {
847 var webViewInternal = privates(webview).internal; 988 var webViewInternal = privates(webview).internal;
989 if (event.storagePartitionId) {
990 webViewInternal.webviewNode.setAttribute('partition',
991 event.storagePartitionId);
992 var partition = new Partition();
993 partition.fromAttribute(event.storagePartitionId,
994 webViewInternal.hasNavigated());
995 webViewInternal.partition = partition;
996 }
997
848 var attached = 998 var attached =
849 webViewInternal.attachWindowAndSetUpEvents(event.windowId); 999 webViewInternal.attachWindowAndSetUpEvents(
1000 event.windowId, undefined, event.storagePartitionId);
850 1001
851 if (!attached) { 1002 if (!attached) {
852 window.console.error(ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH); 1003 window.console.error(ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH);
853 } 1004 }
854 // If the object being passed into attach is not a valid <webview> 1005 // If the object being passed into attach is not a valid <webview>
855 // then we will fail and it will be treated as if the new window 1006 // then we will fail and it will be treated as if the new window
856 // was rejected. The permission API plumbing is used here to clean 1007 // was rejected. The permission API plumbing is used here to clean
857 // up the state created for the new window if attaching fails. 1008 // up the state created for the new window if attaching fails.
858 WebView.setPermission( 1009 WebView.setPermission(
859 self.instanceId, requestId, attached ? 'allow' : 'deny'); 1010 self.instanceId, requestId, attached ? 'allow' : 'deny');
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 this.userAgentOverride = userAgentOverride; 1244 this.userAgentOverride = userAgentOverride;
1094 if (!this.instanceId) { 1245 if (!this.instanceId) {
1095 // If we are not attached yet, then we will pick up the user agent on 1246 // If we are not attached yet, then we will pick up the user agent on
1096 // attachment. 1247 // attachment.
1097 return; 1248 return;
1098 } 1249 }
1099 WebView.overrideUserAgent(this.instanceId, userAgentOverride); 1250 WebView.overrideUserAgent(this.instanceId, userAgentOverride);
1100 }; 1251 };
1101 1252
1102 /** @private */ 1253 /** @private */
1103 WebViewInternal.prototype.attachWindowAndSetUpEvents = function(instanceId) { 1254 WebViewInternal.prototype.attachWindowAndSetUpEvents = function(
1255 instanceId, opt_src, opt_partitionId) {
1104 this.instanceId = instanceId; 1256 this.instanceId = instanceId;
1257 // If we have a partition from the opener, use that instead.
1258 var storagePartitionId =
1259 opt_partitionId ||
1260 this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) ||
1261 this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION];
1105 var params = { 1262 var params = {
1106 'api': 'webview', 1263 'api': 'webview',
1107 'instanceId': this.viewInstanceId, 1264 'instanceId': this.viewInstanceId,
1108 'name': this.name 1265 'name': this.name,
1266 'src': opt_src,
1267 'storagePartitionId': storagePartitionId,
1268 'userAgentOverride': this.userAgentOverride
1109 }; 1269 };
1110 if (this.userAgentOverride) {
1111 params['userAgentOverride'] = this.userAgentOverride;
1112 }
1113 this.setupNameAttribute(); 1270 this.setupNameAttribute();
1114 var events = this.getEvents(); 1271 var events = this.getEvents();
1115 for (var eventName in events) { 1272 for (var eventName in events) {
1116 this.setupEvent(eventName, events[eventName]); 1273 this.setupEvent(eventName, events[eventName]);
1117 } 1274 }
1118 1275
1119 return this.browserPluginNode['-internal-attach'](this.instanceId, params); 1276 return this.browserPluginNode['-internal-attach'](this.instanceId, params);
1120 }; 1277 };
1121 1278
1122 // Registers browser plugin <object> custom element. 1279 // Registers browser plugin <object> custom element.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 } 1311 }
1155 1312
1156 // Registers <webview> custom element. 1313 // Registers <webview> custom element.
1157 function registerWebViewElement() { 1314 function registerWebViewElement() {
1158 var proto = Object.create(HTMLElement.prototype); 1315 var proto = Object.create(HTMLElement.prototype);
1159 1316
1160 proto.createdCallback = function() { 1317 proto.createdCallback = function() {
1161 new WebViewInternal(this); 1318 new WebViewInternal(this);
1162 }; 1319 };
1163 1320
1321 proto.customElementDetached = false;
1322
1164 proto.attributeChangedCallback = function(name, oldValue, newValue) { 1323 proto.attributeChangedCallback = function(name, oldValue, newValue) {
1165 var internal = privates(this).internal; 1324 var internal = privates(this).internal;
1166 if (!internal) { 1325 if (!internal) {
1167 return; 1326 return;
1168 } 1327 }
1169 internal.handleWebviewAttributeMutation(name, oldValue, newValue); 1328 internal.handleWebviewAttributeMutation(name, oldValue, newValue);
1170 }; 1329 };
1171 1330
1331 proto.detachedCallback = function() {
1332 this.customElementDetached = true;
1333 };
1334
1335 proto.attachedCallback = function() {
1336 if (this.customElementDetached) {
1337 var webViewInternal = privates(this).internal;
1338 webViewInternal.resetUponReattachment();
1339 webViewInternal.allocateInstanceId();
1340 }
1341 this.customElementDetached = false;
1342 };
1343
1172 proto.back = function() { 1344 proto.back = function() {
1173 this.go(-1); 1345 this.go(-1);
1174 }; 1346 };
1175 1347
1176 proto.forward = function() { 1348 proto.forward = function() {
1177 this.go(1); 1349 this.go(1);
1178 }; 1350 };
1179 1351
1180 proto.canGoBack = function() { 1352 proto.canGoBack = function() {
1181 return privates(this).internal.canGoBack(); 1353 return privates(this).internal.canGoBack();
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 1457
1286 /** 1458 /**
1287 * Implemented when the experimental API is available. 1459 * Implemented when the experimental API is available.
1288 * @private 1460 * @private
1289 */ 1461 */
1290 WebViewInternal.prototype.setupExperimentalContextMenus_ = function() {}; 1462 WebViewInternal.prototype.setupExperimentalContextMenus_ = function() {};
1291 1463
1292 exports.WebView = WebView; 1464 exports.WebView = WebView;
1293 exports.WebViewInternal = WebViewInternal; 1465 exports.WebViewInternal = WebViewInternal;
1294 exports.CreateEvent = CreateEvent; 1466 exports.CreateEvent = CreateEvent;
OLDNEW
« no previous file with comments | « chrome/common/extensions/api/webview.json ('k') | chrome/test/data/extensions/platform_apps/web_view/shim/main.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698