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_attributes.js
blobce538fdc3df3c2ff51c44d006036eae868eed295
1 // Copyright 2014 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 the attributes of the <webview> tag.
7 var GuestViewAttributes = require('guestViewAttributes').GuestViewAttributes;
8 var WebViewConstants = require('webViewConstants').WebViewConstants;
9 var WebViewImpl = require('webView').WebViewImpl;
10 var WebViewInternal = require('webViewInternal').WebViewInternal;
12 // -----------------------------------------------------------------------------
13 // AllowScalingAttribute object.
15 // Attribute that specifies whether scaling is allowed in the webview.
16 function AllowScalingAttribute(view) {
17   GuestViewAttributes.BooleanAttribute.call(
18       this, WebViewConstants.ATTRIBUTE_ALLOWSCALING, view);
21 AllowScalingAttribute.prototype.__proto__ =
22     GuestViewAttributes.BooleanAttribute.prototype;
24 AllowScalingAttribute.prototype.handleMutation = function(oldValue, newValue) {
25   if (!this.view.guest.getId())
26   return;
28   WebViewInternal.setAllowScaling(this.view.guest.getId(), this.getValue());
31 // -----------------------------------------------------------------------------
32 // AllowTransparencyAttribute object.
34 // Attribute that specifies whether transparency is allowed in the webview.
35 function AllowTransparencyAttribute(view) {
36   GuestViewAttributes.BooleanAttribute.call(
37       this, WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, view);
40 AllowTransparencyAttribute.prototype.__proto__ =
41     GuestViewAttributes.BooleanAttribute.prototype;
43 AllowTransparencyAttribute.prototype.handleMutation = function(oldValue,
44                                                                newValue) {
45   if (!this.view.guest.getId())
46     return;
48   WebViewInternal.setAllowTransparency(this.view.guest.getId(),
49                                        this.getValue());
52 // -----------------------------------------------------------------------------
53 // AutosizeDimensionAttribute object.
55 // Attribute used to define the demension limits of autosizing.
56 function AutosizeDimensionAttribute(name, view) {
57   GuestViewAttributes.IntegerAttribute.call(this, name, view);
60 AutosizeDimensionAttribute.prototype.__proto__ =
61     GuestViewAttributes.IntegerAttribute.prototype;
63 AutosizeDimensionAttribute.prototype.handleMutation = function(
64     oldValue, newValue) {
65   if (!this.view.guest.getId())
66     return;
68   this.view.guest.setSize({
69     'enableAutoSize': this.view.attributes[
70       WebViewConstants.ATTRIBUTE_AUTOSIZE].getValue(),
71     'min': {
72       'width': this.view.attributes[
73           WebViewConstants.ATTRIBUTE_MINWIDTH].getValue(),
74       'height': this.view.attributes[
75           WebViewConstants.ATTRIBUTE_MINHEIGHT].getValue()
76     },
77     'max': {
78       'width': this.view.attributes[
79           WebViewConstants.ATTRIBUTE_MAXWIDTH].getValue(),
80       'height': this.view.attributes[
81           WebViewConstants.ATTRIBUTE_MAXHEIGHT].getValue()
82     }
83   });
84   return;
87 // -----------------------------------------------------------------------------
88 // AutosizeAttribute object.
90 // Attribute that specifies whether the webview should be autosized.
91 function AutosizeAttribute(view) {
92   GuestViewAttributes.BooleanAttribute.call(
93       this, WebViewConstants.ATTRIBUTE_AUTOSIZE, view);
96 AutosizeAttribute.prototype.__proto__ =
97     GuestViewAttributes.BooleanAttribute.prototype;
99 AutosizeAttribute.prototype.handleMutation =
100     AutosizeDimensionAttribute.prototype.handleMutation;
102 // -----------------------------------------------------------------------------
103 // NameAttribute object.
105 // Attribute that sets the guest content's window.name object.
106 function NameAttribute(view) {
107   GuestViewAttributes.Attribute.call(
108       this, WebViewConstants.ATTRIBUTE_NAME, view);
111 NameAttribute.prototype.__proto__ = GuestViewAttributes.Attribute.prototype
113 NameAttribute.prototype.handleMutation = function(oldValue, newValue) {
114   oldValue = oldValue || '';
115   newValue = newValue || '';
116   if (oldValue === newValue || !this.view.guest.getId())
117     return;
119   WebViewInternal.setName(this.view.guest.getId(), newValue);
122 NameAttribute.prototype.setValue = function(value) {
123   value = value || '';
124   if (value === '')
125     this.view.element.removeAttribute(this.name);
126   else
127     this.view.element.setAttribute(this.name, value);
130 // -----------------------------------------------------------------------------
131 // PartitionAttribute object.
133 // Attribute representing the state of the storage partition.
134 function PartitionAttribute(view) {
135   GuestViewAttributes.Attribute.call(
136       this, WebViewConstants.ATTRIBUTE_PARTITION, view);
137   this.validPartitionId = true;
140 PartitionAttribute.prototype.__proto__ =
141     GuestViewAttributes.Attribute.prototype;
143 PartitionAttribute.prototype.handleMutation = function(oldValue, newValue) {
144   newValue = newValue || '';
146   // The partition cannot change if the webview has already navigated.
147   if (!this.view.attributes[
148           WebViewConstants.ATTRIBUTE_SRC].beforeFirstNavigation) {
149     window.console.error(WebViewConstants.ERROR_MSG_ALREADY_NAVIGATED);
150     this.setValueIgnoreMutation(oldValue);
151     return;
152   }
153   if (newValue == 'persist:') {
154     this.validPartitionId = false;
155     window.console.error(
156         WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE);
157   }
160 PartitionAttribute.prototype.detach = function() {
161   this.validPartitionId = true;
164 // -----------------------------------------------------------------------------
165 // SrcAttribute object.
167 // Attribute that handles the location and navigation of the webview.
168 function SrcAttribute(view) {
169   GuestViewAttributes.Attribute.call(
170       this, WebViewConstants.ATTRIBUTE_SRC, view);
171   this.setupMutationObserver();
172   this.beforeFirstNavigation = true;
175 SrcAttribute.prototype.__proto__ = GuestViewAttributes.Attribute.prototype;
177 SrcAttribute.prototype.setValueIgnoreMutation = function(value) {
178   GuestViewAttributes.Attribute.prototype.setValueIgnoreMutation.call(
179       this, value);
180   // takeRecords() is needed to clear queued up src mutations. Without it, it is
181   // possible for this change to get picked up asyncronously by src's mutation
182   // observer |observer|, and then get handled even though we do not want to
183   // handle this mutation.
184   this.observer.takeRecords();
187 SrcAttribute.prototype.handleMutation = function(oldValue, newValue) {
188   // Once we have navigated, we don't allow clearing the src attribute.
189   // Once <webview> enters a navigated state, it cannot return to a
190   // placeholder state.
191   if (!newValue && oldValue) {
192     // src attribute changes normally initiate a navigation. We suppress
193     // the next src attribute handler call to avoid reloading the page
194     // on every guest-initiated navigation.
195     this.setValueIgnoreMutation(oldValue);
196     return;
197   }
198   this.parse();
201 SrcAttribute.prototype.attach = function() {
202   this.parse();
205 SrcAttribute.prototype.detach = function() {
206   this.beforeFirstNavigation = true;
209 // The purpose of this mutation observer is to catch assignment to the src
210 // attribute without any changes to its value. This is useful in the case
211 // where the webview guest has crashed and navigating to the same address
212 // spawns off a new process.
213 SrcAttribute.prototype.setupMutationObserver =
214     function() {
215   this.observer = new MutationObserver(function(mutations) {
216     $Array.forEach(mutations, function(mutation) {
217       var oldValue = mutation.oldValue;
218       var newValue = this.getValue();
219       if (oldValue != newValue) {
220         return;
221       }
222       this.handleMutation(oldValue, newValue);
223     }.bind(this));
224   }.bind(this));
225   var params = {
226     attributes: true,
227     attributeOldValue: true,
228     attributeFilter: [this.name]
229   };
230   this.observer.observe(this.view.element, params);
233 SrcAttribute.prototype.parse = function() {
234   if (!this.view.elementAttached ||
235       !this.view.attributes[
236           WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId ||
237       !this.getValue()) {
238     return;
239   }
241   if (!this.view.guest.getId()) {
242     if (this.beforeFirstNavigation) {
243       this.beforeFirstNavigation = false;
244       this.view.createGuest();
245     }
246     return;
247   }
249   WebViewInternal.navigate(this.view.guest.getId(), this.getValue());
252 // -----------------------------------------------------------------------------
254 // Sets up all of the webview attributes.
255 WebViewImpl.prototype.setupAttributes = function() {
256   this.attributes[WebViewConstants.ATTRIBUTE_ALLOWSCALING] =
257       new AllowScalingAttribute(this);
258   this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] =
259       new AllowTransparencyAttribute(this);
260   this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE] =
261       new AutosizeAttribute(this);
262   this.attributes[WebViewConstants.ATTRIBUTE_NAME] =
263       new NameAttribute(this);
264   this.attributes[WebViewConstants.ATTRIBUTE_PARTITION] =
265       new PartitionAttribute(this);
266   this.attributes[WebViewConstants.ATTRIBUTE_SRC] =
267       new SrcAttribute(this);
269   var autosizeAttributes = [WebViewConstants.ATTRIBUTE_MAXHEIGHT,
270                             WebViewConstants.ATTRIBUTE_MAXWIDTH,
271                             WebViewConstants.ATTRIBUTE_MINHEIGHT,
272                             WebViewConstants.ATTRIBUTE_MINWIDTH];
273   for (var i = 0; autosizeAttributes[i]; ++i) {
274     this.attributes[autosizeAttributes[i]] =
275         new AutosizeDimensionAttribute(autosizeAttributes[i], this);
276   }