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

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: 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;
187 if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MINWIDTH) &&
188 node[WebViewConstants.ATTRIBUTE_MINWIDTH]) {
189 minWidth = node[WebViewConstants.ATTRIBUTE_MINWIDTH];
190 } else {
191 minWidth = width;
192 }
193 if (minWidth > maxWidth) { 176 if (minWidth > maxWidth) {
194 minWidth = maxWidth; 177 minWidth = maxWidth;
195 } 178 }
Fady Samuel 2014/11/11 00:04:21 minWidth = Math.min(minWidth, maxWidth); https://
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) { 179 if (minHeight > maxHeight) {
213 minHeight = maxHeight; 180 minHeight = maxHeight;
214 } 181 }
Fady Samuel 2014/11/11 00:04:21 minHeight = Math.min(minHeight, maxHeight);
215 182
216 if (!this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue() || 183 if (!this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue() ||
217 (newWidth >= minWidth && 184 (newWidth >= minWidth &&
218 newWidth <= maxWidth && 185 newWidth <= maxWidth &&
219 newHeight >= minHeight && 186 newHeight >= minHeight &&
220 newHeight <= maxHeight)) { 187 newHeight <= maxHeight)) {
221 node.style.width = newWidth + 'px'; 188 node.style.width = newWidth + 'px';
222 node.style.height = newHeight + 'px'; 189 node.style.height = newHeight + 'px';
223 // Only fire the DOM event if the size of the <webview> has actually 190 // Only fire the DOM event if the size of the <webview> has actually
224 // changed. 191 // changed.
225 this.dispatchEvent(webViewEvent); 192 this.dispatchEvent(webViewEvent);
226 } 193 }
227 }; 194 };
228 195
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() { 196 WebViewImpl.prototype.parseSrcAttribute = function() {
239 if (!this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId || 197 if (!this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId ||
240 !this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()) { 198 !this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()) {
241 return; 199 return;
242 } 200 }
243 201
244 if (this.guestInstanceId == undefined) { 202 if (this.guestInstanceId == undefined) {
245 if (this.beforeFirstNavigation) { 203 if (this.beforeFirstNavigation) {
246 this.beforeFirstNavigation = false; 204 this.beforeFirstNavigation = false;
247 this.createGuest(); 205 this.createGuest();
248 } 206 }
249 return; 207 return;
250 } 208 }
251 209
252 // Navigate to |this.src|. 210 // Navigate to |this.src|.
253 WebViewInternal.navigate( 211 WebViewInternal.navigate(
254 this.guestInstanceId, 212 this.guestInstanceId,
255 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()); 213 this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue());
256 }; 214 };
257 215
258 WebViewImpl.prototype.parseAttributes = function() {
259 if (!this.elementAttached) {
260 return;
261 }
262 this.parseSrcAttribute();
263 };
264
265 WebViewImpl.prototype.createGuest = function() { 216 WebViewImpl.prototype.createGuest = function() {
266 if (this.pendingGuestCreation) { 217 if (this.pendingGuestCreation) {
267 return; 218 return;
268 } 219 }
269 var params = { 220 var params = {
270 'storagePartitionId': this.attributes[ 221 'storagePartitionId': this.attributes[
271 WebViewConstants.ATTRIBUTE_PARTITION].getValue() 222 WebViewConstants.ATTRIBUTE_PARTITION].getValue()
272 }; 223 };
273 GuestViewInternal.createGuest( 224 GuestViewInternal.createGuest(
274 'webview', 225 'webview',
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 for (var i in this.attributes) { 300 for (var i in this.attributes) {
350 params[i] = this.attributes[i].getValue(); 301 params[i] = this.attributes[i].getValue();
351 } 302 }
352 return params; 303 return params;
353 }; 304 };
354 305
355 WebViewImpl.prototype.attachWindow = function(guestInstanceId) { 306 WebViewImpl.prototype.attachWindow = function(guestInstanceId) {
356 this.guestInstanceId = guestInstanceId; 307 this.guestInstanceId = guestInstanceId;
357 var params = this.buildAttachParams(); 308 var params = this.buildAttachParams();
358 309
359 if (!this.isPluginInRenderTree()) { 310 if (!this.internalInstanceId) {
360 return true; 311 return true;
361 } 312 }
362 313
363 return guestViewInternalNatives.AttachGuest( 314 return guestViewInternalNatives.AttachGuest(
364 this.internalInstanceId, 315 this.internalInstanceId,
365 this.guestInstanceId, 316 this.guestInstanceId,
366 params, function(w) { 317 params, function(w) {
367 this.contentWindow = w; 318 this.contentWindow = w;
368 }.bind(this) 319 }.bind(this)
369 ); 320 );
(...skipping 21 matching lines...) Expand all
391 342
392 // Clears browsing data for the WebView partition. 343 // Clears browsing data for the WebView partition.
393 WebViewImpl.prototype.clearData = function() { 344 WebViewImpl.prototype.clearData = function() {
394 if (!this.guestInstanceId) { 345 if (!this.guestInstanceId) {
395 return; 346 return;
396 } 347 }
397 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments)); 348 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments));
398 $Function.apply(WebViewInternal.clearData, null, args); 349 $Function.apply(WebViewInternal.clearData, null, args);
399 }; 350 };
400 351
401 // Injects JavaScript code into the guest page. 352 // Shared implementation of executeScript() and insertCSS().
402 WebViewImpl.prototype.executeScript = function(var_args) { 353 WebViewImpl.prototype.executeCode = function(func, args) {
403 this.validateExecuteCodeCall(); 354 if (!this.guestInstanceId) {
355 window.console.error(WebViewConstants.ERROR_MSG_CANNOT_INJECT_SCRIPT);
356 return;
357 }
358
404 var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue(); 359 var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
405 if (this.baseUrlForDataUrl != '') { 360 if (this.baseUrlForDataUrl != '') {
406 webviewSrc = this.baseUrlForDataUrl; 361 webviewSrc = this.baseUrlForDataUrl;
407 } 362 }
408 var args = $Array.concat([this.guestInstanceId, webviewSrc], 363
409 $Array.slice(arguments)); 364 args = $Array.concat([this.guestInstanceId, webviewSrc],
410 $Function.apply(WebViewInternal.executeScript, null, args); 365 $Array.slice(args));
366 $Function.apply(func, null, args);
367 }
368
369 // Injects JavaScript code into the guest page.
370 WebViewImpl.prototype.executeScript = function(var_args) {
371 this.executeCode(WebViewInternal.executeScript, $Array.slice(arguments));
411 }; 372 };
412 373
413 // Initiates a find-in-page request. 374 // Initiates a find-in-page request.
414 WebViewImpl.prototype.find = function(search_text, options, callback) { 375 WebViewImpl.prototype.find = function(search_text, options, callback) {
415 if (!this.guestInstanceId) { 376 if (!this.guestInstanceId) {
416 return; 377 return;
417 } 378 }
418 WebViewInternal.find(this.guestInstanceId, search_text, options, callback); 379 WebViewInternal.find(this.guestInstanceId, search_text, options, callback);
419 }; 380 };
420 381
(...skipping 25 matching lines...) Expand all
446 // navigation. 407 // navigation.
447 WebViewImpl.prototype.go = function(relativeIndex, callback) { 408 WebViewImpl.prototype.go = function(relativeIndex, callback) {
448 if (!this.guestInstanceId) { 409 if (!this.guestInstanceId) {
449 return; 410 return;
450 } 411 }
451 WebViewInternal.go(this.guestInstanceId, relativeIndex, callback); 412 WebViewInternal.go(this.guestInstanceId, relativeIndex, callback);
452 }; 413 };
453 414
454 // Injects CSS into the guest page. 415 // Injects CSS into the guest page.
455 WebViewImpl.prototype.insertCSS = function(var_args) { 416 WebViewImpl.prototype.insertCSS = function(var_args) {
456 this.validateExecuteCodeCall(); 417 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 }; 418 };
465 419
466 // Indicates whether or not the webview's user agent string has been overridden. 420 // Indicates whether or not the webview's user agent string has been overridden.
467 WebViewImpl.prototype.isUserAgentOverridden = function() { 421 WebViewImpl.prototype.isUserAgentOverridden = function() {
468 return !!this.userAgentOverride && 422 return !!this.userAgentOverride &&
469 this.userAgentOverride != navigator.userAgent; 423 this.userAgentOverride != navigator.userAgent;
470 }; 424 };
471 425
472 // Prints the contents of the webview. 426 // Prints the contents of the webview.
473 WebViewImpl.prototype.print = function() { 427 WebViewImpl.prototype.print = function() {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 internal.reset(); 541 internal.reset();
588 }; 542 };
589 543
590 proto.attachedCallback = function() { 544 proto.attachedCallback = function() {
591 var internal = privates(this).internal; 545 var internal = privates(this).internal;
592 if (!internal) { 546 if (!internal) {
593 return; 547 return;
594 } 548 }
595 if (!internal.elementAttached) { 549 if (!internal.elementAttached) {
596 internal.elementAttached = true; 550 internal.elementAttached = true;
597 internal.parseAttributes(); 551 internal.parseSrcAttribute();
598 } 552 }
599 }; 553 };
600 554
601 // Public-facing API methods. 555 // Public-facing API methods.
602 var methods = [ 556 var methods = [
603 'back', 557 'back',
604 'canGoBack', 558 'canGoBack',
605 'canGoForward', 559 'canGoForward',
606 'clearData', 560 'clearData',
607 'executeScript', 561 'executeScript',
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 registerBrowserPluginElement(); 611 registerBrowserPluginElement();
658 registerWebViewElement(); 612 registerWebViewElement();
659 window.removeEventListener(event.type, listener, useCapture); 613 window.removeEventListener(event.type, listener, useCapture);
660 }, useCapture); 614 }, useCapture);
661 615
662 // Implemented when the ChromeWebView API is available. 616 // Implemented when the ChromeWebView API is available.
663 WebViewImpl.prototype.maybeGetChromeWebViewEvents = function() {}; 617 WebViewImpl.prototype.maybeGetChromeWebViewEvents = function() {};
664 618
665 // Implemented when the experimental WebView API is available. 619 // Implemented when the experimental WebView API is available.
666 WebViewImpl.maybeGetExperimentalAPIs = function() {}; 620 WebViewImpl.maybeGetExperimentalAPIs = function() {};
667 WebViewImpl.prototype.maybeGetExperimentalEvents = function() {};
668 WebViewImpl.prototype.setupExperimentalContextMenus = function() {};
669 621
670 // Exports. 622 // Exports.
671 exports.WebViewImpl = WebViewImpl; 623 exports.WebViewImpl = WebViewImpl;
672 exports.WebViewInternal = WebViewInternal; 624 exports.WebViewInternal = WebViewInternal;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698