Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / extensions / renderer / resources / guest_view / web_view / web_view.js
blobfd0e45c81b01e04239d6704d51194cc3d1cfff2d
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
3 // found in the LICENSE file.
5 // This module implements WebView (<webview>) as a custom element that wraps a
6 // BrowserPlugin object element. The object element is hidden within
7 // the shadow DOM of the WebView element.
9 var DocumentNatives = requireNative('document_natives');
10 var GuestView = require('guestView').GuestView;
11 var GuestViewContainer = require('guestViewContainer').GuestViewContainer;
12 var GuestViewInternalNatives = requireNative('guest_view_internal');
13 var WebViewConstants = require('webViewConstants').WebViewConstants;
14 var WebViewEvents = require('webViewEvents').WebViewEvents;
15 var WebViewInternal = require('webViewInternal').WebViewInternal;
17 // Represents the internal state of <webview>.
18 function WebViewImpl(webviewElement) {
19   GuestViewContainer.call(this, webviewElement, 'webview');
20   this.cachedZoom = 1;
21   this.setupElementProperties();
22   new WebViewEvents(this, this.viewInstanceId);
25 WebViewImpl.prototype.__proto__ = GuestViewContainer.prototype;
27 WebViewImpl.VIEW_TYPE = 'WebView';
29 // Add extra functionality to |this.element|.
30 WebViewImpl.setupElement = function(proto) {
31   // Public-facing API methods.
32   var apiMethods = WebViewImpl.getApiMethods();
34   // Create default implementations for undefined API methods.
35   var createDefaultApiMethod = function(m) {
36     return function(var_args) {
37       if (!this.guest.getId()) {
38         return false;
39       }
40       var args = $Array.concat([this.guest.getId()], $Array.slice(arguments));
41       $Function.apply(WebViewInternal[m], null, args);
42       return true;
43     };
44   };
45   for (var i = 0; i != apiMethods.length; ++i) {
46     if (WebViewImpl.prototype[apiMethods[i]] == undefined) {
47       WebViewImpl.prototype[apiMethods[i]] =
48           createDefaultApiMethod(apiMethods[i]);
49     }
50   }
52   // Forward proto.foo* method calls to WebViewImpl.foo*.
53   GuestViewContainer.forwardApiMethods(proto, apiMethods);
56 // Initiates navigation once the <webview> element is attached to the DOM.
57 WebViewImpl.prototype.onElementAttached = function() {
58   // Mark all attributes as dirty on attachment.
59   for (var i in this.attributes) {
60     this.attributes[i].dirty = true;
61   }
62   for (var i in this.attributes) {
63     this.attributes[i].attach();
64   }
67 // Resets some state upon detaching <webview> element from the DOM.
68 WebViewImpl.prototype.onElementDetached = function() {
69   this.guest.destroy();
70   for (var i in this.attributes) {
71     this.attributes[i].dirty = false;
72   }
73   for (var i in this.attributes) {
74     this.attributes[i].detach();
75   }
78 // Sets the <webview>.request property.
79 WebViewImpl.prototype.setRequestPropertyOnWebViewElement = function(request) {
80   Object.defineProperty(
81       this.element,
82       'request',
83       {
84         value: request,
85         enumerable: true
86       }
87   );
90 WebViewImpl.prototype.setupElementProperties = function() {
91   // We cannot use {writable: true} property descriptor because we want a
92   // dynamic getter value.
93   Object.defineProperty(this.element, 'contentWindow', {
94     get: function() {
95       return this.guest.getContentWindow();
96     }.bind(this),
97     // No setter.
98     enumerable: true
99   });
102 WebViewImpl.prototype.onSizeChanged = function(webViewEvent) {
103   var newWidth = webViewEvent.newWidth;
104   var newHeight = webViewEvent.newHeight;
106   var element = this.element;
108   var width = element.offsetWidth;
109   var height = element.offsetHeight;
111   // Check the current bounds to make sure we do not resize <webview>
112   // outside of current constraints.
113   var maxWidth = this.attributes[
114     WebViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || width;
115   var minWidth = this.attributes[
116     WebViewConstants.ATTRIBUTE_MINWIDTH].getValue() || width;
117   var maxHeight = this.attributes[
118     WebViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || height;
119   var minHeight = this.attributes[
120     WebViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || height;
122   minWidth = Math.min(minWidth, maxWidth);
123   minHeight = Math.min(minHeight, maxHeight);
125   if (!this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue() ||
126       (newWidth >= minWidth &&
127       newWidth <= maxWidth &&
128       newHeight >= minHeight &&
129       newHeight <= maxHeight)) {
130     element.style.width = newWidth + 'px';
131     element.style.height = newHeight + 'px';
132     // Only fire the DOM event if the size of the <webview> has actually
133     // changed.
134     this.dispatchEvent(webViewEvent);
135   }
138 WebViewImpl.prototype.createGuest = function() {
139   this.guest.create(this.buildParams(), function() {
140     this.attachWindow();
141   }.bind(this));
144 WebViewImpl.prototype.onFrameNameChanged = function(name) {
145   this.attributes[WebViewConstants.ATTRIBUTE_NAME].setValueIgnoreMutation(name);
148 // Updates state upon loadcommit.
149 WebViewImpl.prototype.onLoadCommit = function(
150     baseUrlForDataUrl, currentEntryIndex, entryCount,
151     processId, url, isTopLevel) {
152   this.baseUrlForDataUrl = baseUrlForDataUrl;
153   this.currentEntryIndex = currentEntryIndex;
154   this.entryCount = entryCount;
155   this.processId = processId;
156   if (isTopLevel) {
157     // Touching the src attribute triggers a navigation. To avoid
158     // triggering a page reload on every guest-initiated navigation,
159     // we do not handle this mutation.
160     this.attributes[
161         WebViewConstants.ATTRIBUTE_SRC].setValueIgnoreMutation(url);
162   }
165 WebViewImpl.prototype.onAttach = function(storagePartitionId) {
166   this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValueIgnoreMutation(
167       storagePartitionId);
170 WebViewImpl.prototype.buildContainerParams = function() {
171   var params = { 'initialZoomFactor': this.cachedZoomFactor,
172                  'userAgentOverride': this.userAgentOverride };
173   for (var i in this.attributes) {
174     var value = this.attributes[i].getValueIfDirty();
175     if (value)
176       params[i] = value;
177   }
178   return params;
181 WebViewImpl.prototype.attachWindow = function(opt_guestInstanceId) {
182   // If |opt_guestInstanceId| was provided, then a different existing guest is
183   // being attached to this webview, and the current one will get destroyed.
184   if (opt_guestInstanceId) {
185     if (this.guest.getId() == opt_guestInstanceId) {
186       return true;
187     }
188     this.guest.destroy();
189     this.guest = new GuestView('webview', opt_guestInstanceId);
190   }
192   return GuestViewContainer.prototype.attachWindow.call(this);
195 // Shared implementation of executeScript() and insertCSS().
196 WebViewImpl.prototype.executeCode = function(func, args) {
197   if (!this.guest.getId()) {
198     window.console.error(WebViewConstants.ERROR_MSG_CANNOT_INJECT_SCRIPT);
199     return false;
200   }
202   var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
203   if (this.baseUrlForDataUrl) {
204     webviewSrc = this.baseUrlForDataUrl;
205   }
207   args = $Array.concat([this.guest.getId(), webviewSrc],
208                        $Array.slice(args));
209   $Function.apply(func, null, args);
210   return true;
213 // Requests the <webview> element wihtin the embedder to enter fullscreen.
214 WebViewImpl.prototype.makeElementFullscreen = function() {
215   GuestViewInternalNatives.RunWithGesture(function() {
216     this.element.webkitRequestFullScreen();
217   }.bind(this));
220 // Implemented when the ChromeWebView API is available.
221 WebViewImpl.prototype.maybeSetupContextMenus = function() {};
223 GuestViewContainer.registerElement(WebViewImpl);
225 // Exports.
226 exports.WebViewImpl = WebViewImpl;