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

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

Issue 715583007: Various webview cleanup. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 } 43 }
44 44
45 WebViewImpl.prototype.createBrowserPluginNode = function() { 45 WebViewImpl.prototype.createBrowserPluginNode = function() {
46 // We create BrowserPlugin as a custom element in order to observe changes 46 // We create BrowserPlugin as a custom element in order to observe changes
47 // to attributes synchronously. 47 // to attributes synchronously.
48 var browserPluginNode = new WebViewImpl.BrowserPlugin(); 48 var browserPluginNode = new WebViewImpl.BrowserPlugin();
49 privates(browserPluginNode).internal = this; 49 privates(browserPluginNode).internal = this;
50 return browserPluginNode; 50 return browserPluginNode;
51 }; 51 };
52 52
53 WebViewImpl.prototype.getGuestInstanceId = function() {
54 return this.guestInstanceId;
55 };
56
57 // Resets some state upon reattaching <webview> element to the DOM. 53 // Resets some state upon reattaching <webview> element to the DOM.
58 WebViewImpl.prototype.reset = function() { 54 WebViewImpl.prototype.reset = function() {
59 // If guestInstanceId is defined then the <webview> has navigated and has 55 // If guestInstanceId is defined then the <webview> has navigated and has
60 // already picked up a partition ID. Thus, we need to reset the initialization 56 // already picked up a partition ID. Thus, we need to reset the initialization
61 // state. However, it may be the case that beforeFirstNavigation is false BUT 57 // state. However, it may be the case that beforeFirstNavigation is false BUT
62 // guestInstanceId has yet to be initialized. This means that we have not 58 // guestInstanceId has yet to be initialized. This means that we have not
63 // heard back from createGuest yet. We will not reset the flag in this case so 59 // heard back from createGuest yet. We will not reset the flag in this case so
64 // that we don't end up allocating a second guest. 60 // that we don't end up allocating a second guest.
65 if (this.guestInstanceId) { 61 if (this.guestInstanceId) {
66 GuestViewInternal.destroyGuest(this.guestInstanceId); 62 GuestViewInternal.destroyGuest(this.guestInstanceId);
(...skipping 29 matching lines...) Expand all
96 this.webviewNode.addEventListener('focus', function(e) { 92 this.webviewNode.addEventListener('focus', function(e) {
97 // Focus the BrowserPlugin when the <webview> takes focus. 93 // Focus the BrowserPlugin when the <webview> takes focus.
98 this.browserPluginNode.focus(); 94 this.browserPluginNode.focus();
99 }.bind(this)); 95 }.bind(this));
100 this.webviewNode.addEventListener('blur', function(e) { 96 this.webviewNode.addEventListener('blur', function(e) {
101 // Blur the BrowserPlugin when the <webview> loses focus. 97 // Blur the BrowserPlugin when the <webview> loses focus.
102 this.browserPluginNode.blur(); 98 this.browserPluginNode.blur();
103 }.bind(this)); 99 }.bind(this));
104 }; 100 };
105 101
106 // Validation helper function for executeScript() and insertCSS().
107 WebViewImpl.prototype.validateExecuteCodeCall = function() {
108 if (!this.guestInstanceId) {
109 throw new Error(WebViewConstants.ERROR_MSG_CANNOT_INJECT_SCRIPT);
110 }
111 };
112
113 WebViewImpl.prototype.setupWebviewNodeProperties = function() { 102 WebViewImpl.prototype.setupWebviewNodeProperties = function() {
114 // We cannot use {writable: true} property descriptor because we want a 103 // We cannot use {writable: true} property descriptor because we want a
115 // dynamic getter value. 104 // dynamic getter value.
116 Object.defineProperty(this.webviewNode, 'contentWindow', { 105 Object.defineProperty(this.webviewNode, 'contentWindow', {
117 get: function() { 106 get: function() {
118 if (this.contentWindow) { 107 if (this.contentWindow) {
119 return this.contentWindow; 108 return this.contentWindow;
120 } 109 }
121 window.console.error( 110 window.console.error(
122 WebViewConstants.ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE); 111 WebViewConstants.ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 var newWidth = webViewEvent.newWidth; 157 var newWidth = webViewEvent.newWidth;
169 var newHeight = webViewEvent.newHeight; 158 var newHeight = webViewEvent.newHeight;
170 159
171 var node = this.webviewNode; 160 var node = this.webviewNode;
172 161
173 var width = node.offsetWidth; 162 var width = node.offsetWidth;
174 var height = node.offsetHeight; 163 var height = node.offsetHeight;
175 164
176 // Check the current bounds to make sure we do not resize <webview> 165 // Check the current bounds to make sure we do not resize <webview>
177 // outside of current constraints. 166 // outside of current constraints.
178 var maxWidth; 167 var maxWidth = this.attributes[
179 if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MAXWIDTH) && 168 WebViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || width;
180 node[WebViewConstants.ATTRIBUTE_MAXWIDTH]) { 169 var minWidth = this.attributes[
181 maxWidth = node[WebViewConstants.ATTRIBUTE_MAXWIDTH]; 170 WebViewConstants.ATTRIBUTE_MINWIDTH].getValue() || width;
182 } else { 171 var maxHeight = this.attributes[
183 maxWidth = width; 172 WebViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || height;
184 } 173 var minHeight = this.attributes[
174 WebViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || height;
185 175
186 var minWidth; 176 minWidth = Math.min(minWidth, maxWidth);
187 if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MINWIDTH) && 177 minHeight = Math.min(minHeight, maxHeight);
188 node[WebViewConstants.ATTRIBUTE_MINWIDTH]) {
189 minWidth = node[WebViewConstants.ATTRIBUTE_MINWIDTH];
190 } else {
191 minWidth = width;
192 }
193 if (minWidth > maxWidth) {
194 minWidth = maxWidth;
195 }
196
197 var maxHeight;
198 if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MAXHEIGHT) &&
199 node[WebViewConstants.ATTRIBUTE_MAXHEIGHT]) {
200 maxHeight = node[WebViewConstants.ATTRIBUTE_MAXHEIGHT];
201 } else {
202 maxHeight = height;
203 }
204
205 var minHeight;
206 if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MINHEIGHT) &&
207 node[WebViewConstants.ATTRIBUTE_MINHEIGHT]) {
208 minHeight = node[WebViewConstants.ATTRIBUTE_MINHEIGHT];
209 } else {
210 minHeight = height;
211 }
212 if (minHeight > maxHeight) {
213 minHeight = maxHeight;
214 }
215 178
216 if (!this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue() || 179 if (!this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue() ||
217 (newWidth >= minWidth && 180 (newWidth >= minWidth &&
218 newWidth <= maxWidth && 181 newWidth <= maxWidth &&
219 newHeight >= minHeight && 182 newHeight >= minHeight &&
220 newHeight <= maxHeight)) { 183 newHeight <= maxHeight)) {
221 node.style.width = newWidth + 'px'; 184 node.style.width = newWidth + 'px';
222 node.style.height = newHeight + 'px'; 185 node.style.height = newHeight + 'px';
223 // Only fire the DOM event if the size of the <webview> has actually 186 // Only fire the DOM event if the size of the <webview> has actually
224 // changed. 187 // changed.
225 this.dispatchEvent(webViewEvent); 188 this.dispatchEvent(webViewEvent);
226 } 189 }
227 }; 190 };
228 191
229 // Returns if <object> is in the render tree.
230 WebViewImpl.prototype.isPluginInRenderTree = function() {
231 return !!this.internalInstanceId && this.internalInstanceId != 0;
232 };
233
234 WebViewImpl.prototype.hasNavigated = function() {
235 return !this.beforeFirstNavigation;
236 };
237
238 WebViewImpl.prototype.parseSrcAttribute = function() { 192 WebViewImpl.prototype.parseSrcAttribute = function() {
239 if (!this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId || 193 if (!this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId ||
240 !this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()) { 194 !this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()) {
241 return; 195 return;
242 } 196 }
243 197
244 if (this.guestInstanceId == undefined) { 198 if (this.guestInstanceId == undefined) {
245 if (this.beforeFirstNavigation) { 199 if (this.beforeFirstNavigation) {
246 this.beforeFirstNavigation = false; 200 this.beforeFirstNavigation = false;
247 this.createGuest(); 201 this.createGuest();
248 } 202 }
249 return; 203 return;
250 } 204 }
251 205
252 // Navigate to |this.src|. 206 // Navigate to |this.src|.
253 WebViewInternal.navigate( 207 WebViewInternal.navigate(
254 this.guestInstanceId, 208 this.guestInstanceId,
255 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()); 209 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue());
256 }; 210 };
257 211
258 WebViewImpl.prototype.parseAttributes = function() {
259 if (!this.elementAttached) {
260 return;
261 }
262 this.parseSrcAttribute();
263 };
264
265 WebViewImpl.prototype.createGuest = function() { 212 WebViewImpl.prototype.createGuest = function() {
266 if (this.pendingGuestCreation) { 213 if (this.pendingGuestCreation) {
267 return; 214 return;
268 } 215 }
269 var params = { 216 var params = {
270 'storagePartitionId': this.attributes[ 217 'storagePartitionId': this.attributes[
271 WebViewConstants.ATTRIBUTE_PARTITION].getValue() 218 WebViewConstants.ATTRIBUTE_PARTITION].getValue()
272 }; 219 };
273 GuestViewInternal.createGuest( 220 GuestViewInternal.createGuest(
274 'webview', 221 'webview',
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 for (var i in this.attributes) { 296 for (var i in this.attributes) {
350 params[i] = this.attributes[i].getValue(); 297 params[i] = this.attributes[i].getValue();
351 } 298 }
352 return params; 299 return params;
353 }; 300 };
354 301
355 WebViewImpl.prototype.attachWindow = function(guestInstanceId) { 302 WebViewImpl.prototype.attachWindow = function(guestInstanceId) {
356 this.guestInstanceId = guestInstanceId; 303 this.guestInstanceId = guestInstanceId;
357 var params = this.buildAttachParams(); 304 var params = this.buildAttachParams();
358 305
359 if (!this.isPluginInRenderTree()) { 306 if (!this.internalInstanceId) {
360 return true; 307 return true;
361 } 308 }
362 309
363 return guestViewInternalNatives.AttachGuest( 310 return guestViewInternalNatives.AttachGuest(
364 this.internalInstanceId, 311 this.internalInstanceId,
365 this.guestInstanceId, 312 this.guestInstanceId,
366 params, function(w) { 313 params, function(w) {
367 this.contentWindow = w; 314 this.contentWindow = w;
368 }.bind(this) 315 }.bind(this)
369 ); 316 );
(...skipping 21 matching lines...) Expand all
391 338
392 // Clears browsing data for the WebView partition. 339 // Clears browsing data for the WebView partition.
393 WebViewImpl.prototype.clearData = function() { 340 WebViewImpl.prototype.clearData = function() {
394 if (!this.guestInstanceId) { 341 if (!this.guestInstanceId) {
395 return; 342 return;
396 } 343 }
397 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments)); 344 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments));
398 $Function.apply(WebViewInternal.clearData, null, args); 345 $Function.apply(WebViewInternal.clearData, null, args);
399 }; 346 };
400 347
401 // Injects JavaScript code into the guest page. 348 // Shared implementation of executeScript() and insertCSS().
402 WebViewImpl.prototype.executeScript = function(var_args) { 349 WebViewImpl.prototype.executeCode = function(func, args) {
403 this.validateExecuteCodeCall(); 350 if (!this.guestInstanceId) {
351 window.console.error(WebViewConstants.ERROR_MSG_CANNOT_INJECT_SCRIPT);
352 return;
353 }
354
404 var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue(); 355 var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
405 if (this.baseUrlForDataUrl != '') { 356 if (this.baseUrlForDataUrl != '') {
406 webviewSrc = this.baseUrlForDataUrl; 357 webviewSrc = this.baseUrlForDataUrl;
407 } 358 }
408 var args = $Array.concat([this.guestInstanceId, webviewSrc], 359
409 $Array.slice(arguments)); 360 args = $Array.concat([this.guestInstanceId, webviewSrc],
410 $Function.apply(WebViewInternal.executeScript, null, args); 361 $Array.slice(args));
362 $Function.apply(func, null, args);
363 }
364
365 // Injects JavaScript code into the guest page.
366 WebViewImpl.prototype.executeScript = function(var_args) {
367 this.executeCode(WebViewInternal.executeScript, $Array.slice(arguments));
411 }; 368 };
412 369
413 // Initiates a find-in-page request. 370 // Initiates a find-in-page request.
414 WebViewImpl.prototype.find = function(search_text, options, callback) { 371 WebViewImpl.prototype.find = function(search_text, options, callback) {
415 if (!this.guestInstanceId) { 372 if (!this.guestInstanceId) {
416 return; 373 return;
417 } 374 }
418 WebViewInternal.find(this.guestInstanceId, search_text, options, callback); 375 WebViewInternal.find(this.guestInstanceId, search_text, options, callback);
419 }; 376 };
420 377
(...skipping 25 matching lines...) Expand all
446 // navigation. 403 // navigation.
447 WebViewImpl.prototype.go = function(relativeIndex, callback) { 404 WebViewImpl.prototype.go = function(relativeIndex, callback) {
448 if (!this.guestInstanceId) { 405 if (!this.guestInstanceId) {
449 return; 406 return;
450 } 407 }
451 WebViewInternal.go(this.guestInstanceId, relativeIndex, callback); 408 WebViewInternal.go(this.guestInstanceId, relativeIndex, callback);
452 }; 409 };
453 410
454 // Injects CSS into the guest page. 411 // Injects CSS into the guest page.
455 WebViewImpl.prototype.insertCSS = function(var_args) { 412 WebViewImpl.prototype.insertCSS = function(var_args) {
456 this.validateExecuteCodeCall(); 413 this.executeCode(WebViewInternal.insertCSS, $Array.slice(arguments));
457 var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
458 if (this.baseUrlForDataUrl != '') {
459 webviewSrc = this.baseUrlForDataUrl;
460 }
461 var args = $Array.concat([this.guestInstanceId, webviewSrc],
462 $Array.slice(arguments));
463 $Function.apply(WebViewInternal.insertCSS, null, args);
464 }; 414 };
465 415
466 // Indicates whether or not the webview's user agent string has been overridden. 416 // Indicates whether or not the webview's user agent string has been overridden.
467 WebViewImpl.prototype.isUserAgentOverridden = function() { 417 WebViewImpl.prototype.isUserAgentOverridden = function() {
468 return !!this.userAgentOverride && 418 return !!this.userAgentOverride &&
469 this.userAgentOverride != navigator.userAgent; 419 this.userAgentOverride != navigator.userAgent;
470 }; 420 };
471 421
472 // Prints the contents of the webview. 422 // Prints the contents of the webview.
473 WebViewImpl.prototype.print = function() { 423 WebViewImpl.prototype.print = function() {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 internal.reset(); 537 internal.reset();
588 }; 538 };
589 539
590 proto.attachedCallback = function() { 540 proto.attachedCallback = function() {
591 var internal = privates(this).internal; 541 var internal = privates(this).internal;
592 if (!internal) { 542 if (!internal) {
593 return; 543 return;
594 } 544 }
595 if (!internal.elementAttached) { 545 if (!internal.elementAttached) {
596 internal.elementAttached = true; 546 internal.elementAttached = true;
597 internal.parseAttributes(); 547 internal.parseSrcAttribute();
598 } 548 }
599 }; 549 };
600 550
601 // Public-facing API methods. 551 // Public-facing API methods.
602 var methods = [ 552 var methods = [
603 'back', 553 'back',
604 'canGoBack', 554 'canGoBack',
605 'canGoForward', 555 'canGoForward',
606 'clearData', 556 'clearData',
607 'executeScript', 557 'executeScript',
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 registerBrowserPluginElement(); 607 registerBrowserPluginElement();
658 registerWebViewElement(); 608 registerWebViewElement();
659 window.removeEventListener(event.type, listener, useCapture); 609 window.removeEventListener(event.type, listener, useCapture);
660 }, useCapture); 610 }, useCapture);
661 611
662 // Implemented when the ChromeWebView API is available. 612 // Implemented when the ChromeWebView API is available.
663 WebViewImpl.prototype.maybeGetChromeWebViewEvents = function() {}; 613 WebViewImpl.prototype.maybeGetChromeWebViewEvents = function() {};
664 614
665 // Implemented when the experimental WebView API is available. 615 // Implemented when the experimental WebView API is available.
666 WebViewImpl.maybeGetExperimentalAPIs = function() {}; 616 WebViewImpl.maybeGetExperimentalAPIs = function() {};
667 WebViewImpl.prototype.maybeGetExperimentalEvents = function() {};
668 WebViewImpl.prototype.setupExperimentalContextMenus = function() {}; 617 WebViewImpl.prototype.setupExperimentalContextMenus = function() {};
669 618
670 // Exports. 619 // Exports.
671 exports.WebViewImpl = WebViewImpl; 620 exports.WebViewImpl = WebViewImpl;
672 exports.WebViewInternal = WebViewInternal; 621 exports.WebViewInternal = WebViewInternal;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698