1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvar DocumentNatives = requireNative('document_natives'); 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvar GuestViewInternal = 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch require('binding').Binding.create('guestViewInternal').generate(); 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvar IdGenerator = requireNative('id_generator'); 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)var guestViewInternalNatives = requireNative('guest_view_internal'); 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfunction AppViewInternal(appviewNode) { 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch privates(appviewNode).internal = this; 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.appviewNode = appviewNode; 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.browserPluginNode = this.createBrowserPluginNode(); 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var shadowRoot = this.appviewNode.createShadowRoot(); 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch shadowRoot.appendChild(this.browserPluginNode); 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.viewInstanceId = IdGenerator.GetNextId(); 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 21116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAppViewInternal.prototype.getErrorNode = function() { 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!this.errorNode) { 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.errorNode = document.createElement('div'); 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.errorNode.innerText = 'Unable to connect to app.'; 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.errorNode.style.position = 'absolute'; 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.errorNode.style.left = '0px'; 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.errorNode.style.top = '0px'; 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.errorNode.style.width = '100%'; 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.errorNode.style.height = '100%'; 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.appviewNode.shadowRoot.appendChild(this.errorNode); 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return this.errorNode; 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 35116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAppViewInternal.prototype.createBrowserPluginNode = function() { 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // We create BrowserPlugin as a custom element in order to observe changes 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // to attributes synchronously. 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var browserPluginNode = new AppViewInternal.BrowserPlugin(); 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch privates(browserPluginNode).internal = this; 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return browserPluginNode; 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)AppViewInternal.prototype.connect = function(app, data, callback) { 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) var createParams = { 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 'appId': app, 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'data': data || {} 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var self = this; 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GuestViewInternal.createGuest( 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'appview', 516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) createParams, 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) function(guestInstanceId) { 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!guestInstanceId) { 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.browserPluginNode.style.visibility = 'hidden'; 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var errorMsg = 'Unable to connect to app "' + app + '".'; 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch window.console.warn(errorMsg); 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.getErrorNode().innerText = errorMsg; 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (callback) { 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback(false); 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.attachWindow(guestInstanceId); 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (callback) { 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback(true); 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }.bind(this) 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ); 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)AppViewInternal.prototype.attachWindow = function(guestInstanceId) { 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.guestInstanceId = guestInstanceId; 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var params = { 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'instanceId': this.viewInstanceId, 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.browserPluginNode.style.visibility = 'visible'; 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return guestViewInternalNatives.AttachGuest( 7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) parseInt(this.browserPluginNode.getAttribute('internalinstanceid')), 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) guestInstanceId, 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) params); 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfunction registerBrowserPluginElement() { 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var proto = Object.create(HTMLObjectElement.prototype); 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch proto.createdCallback = function() { 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.setAttribute('type', 'application/browser-plugin'); 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.style.width = '100%'; 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this.style.height = '100%'; 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch proto.attachedCallback = function() { 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Load the plugin immediately. 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var unused = this.nonExistentAttribute; 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AppViewInternal.BrowserPlugin = 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DocumentNatives.RegisterElement('appplugin', {extends: 'object', 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch prototype: proto}); 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete proto.createdCallback; 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete proto.attachedCallback; 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete proto.detachedCallback; 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete proto.attributeChangedCallback; 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfunction registerAppViewElement() { 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var proto = Object.create(HTMLElement.prototype); 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch proto.createdCallback = function() { 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new AppViewInternal(this); 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch proto.connect = function() { 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch var internal = privates(this).internal; 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch $Function.apply(internal.connect, internal, arguments); 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch window.AppView = 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DocumentNatives.RegisterElement('appview', {prototype: proto}); 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Delete the callbacks so developers cannot call them and produce unexpected 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // behavior. 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete proto.createdCallback; 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete proto.attachedCallback; 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete proto.detachedCallback; 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete proto.attributeChangedCallback; 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvar useCapture = true; 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdochwindow.addEventListener('readystatechange', function listener(event) { 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (document.readyState == 'loading') 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch registerBrowserPluginElement(); 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch registerAppViewElement(); 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch window.removeEventListener(event.type, listener, useCapture); 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}, useCapture); 138