15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2009 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @fileoverview CFInstall.js provides a set of utilities for managing 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Chrome Frame detection and installation process. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @author slightlyoff@google.com (Alex Russell) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)(function(scope) { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bail if we'd be over-writing an existing CFInstall object 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (scope['CFInstall']) { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returns an item based on DOM ID. Optionally a document may be provided to 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * specify the scope to search in. If a node is passed, it's returned as-is. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string|Node} id The ID of the node to be located or a node 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Node} doc Optional A document to search for id. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {Node} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var byId = function(id, doc) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (typeof id == 'string') ? (doc || document).getElementById(id) : id; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ///////////////////////////////////////////////////////////////////////////// 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Plugin Detection 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ///////////////////////////////////////////////////////////////////////////// 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks to find out if ChromeFrame is available as a plugin 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {Boolean} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var isAvailable = function() { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For testing purposes. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (scope.CFInstall._force) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scope.CFInstall._forceValue; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Look for CF in the User Agent before trying more expensive checks 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var ua = navigator.userAgent.toLowerCase(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ua.indexOf("chromeframe") >= 0) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (typeof window['ActiveXObject'] != 'undefined') { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var obj = new ActiveXObject('ChromeTab.ChromeFrame'); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj.registerBhoIfNeeded(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch(e) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // squelch 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Creates a style sheet in the document containing the passed rules. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var injectStyleSheet = function(rules) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var ss = document.createElement('style'); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss.setAttribute('type', 'text/css'); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss.styleSheet) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss.styleSheet.cssText = rules; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss.appendChild(document.createTextNode(rules)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var h = document.getElementsByTagName('head')[0]; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var firstChild = h.firstChild; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h.insertBefore(ss, firstChild); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch (e) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // squelch 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** @type {boolean} */ 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var cfStyleTagInjected = false; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** @type {boolean} */ 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var cfHiddenInjected = false; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Injects style rules into the document to handle formatting of Chrome Frame 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * prompt. Multiple calls have no effect. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var injectCFStyleTag = function() { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cfStyleTagInjected) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once and only once 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var rules = '.chromeFrameInstallDefaultStyle {' + 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'width: 800px;' + 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'height: 600px;' + 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'position: absolute;' + 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'left: 50%;' + 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'top: 50%;' + 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'margin-left: -400px;' + 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'margin-top: -300px;' + 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '}' + 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '.chromeFrameOverlayContent {' + 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'position: absolute;' + 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'margin-left: -400px;' + 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'margin-top: -300px;' + 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'left: 50%;' + 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'top: 50%;' + 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'border: 1px solid #93B4D9;' + 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'background-color: white;' + 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'z-index: 2001;' + 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '}' + 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '.chromeFrameOverlayContent iframe {' + 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'width: 800px;' + 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'height: 600px;' + 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'border: none;' + 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '}' + 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '.chromeFrameOverlayCloseBar {' + 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'height: 1em;' + 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'text-align: right;' + 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'background-color: #CADEF4;' + 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '}' + 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '.chromeFrameOverlayUnderlay {' + 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'position: absolute;' + 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'width: 100%;' + 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'height: 100%;' + 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'background-color: white;' + 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'opacity: 0.5;' + 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '-moz-opacity: 0.5;' + 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '-webkit-opacity: 0.5;' + 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '-ms-filter: ' + 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";' + 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'filter: alpha(opacity=50);' + 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'z-index: 2000;' + 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '}'; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) injectStyleSheet(rules); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfStyleTagInjected = true; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Injects style rules to hide the overlay version of the GCF prompt. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Multiple calls have no effect. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var closeOverlay = function() { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IE has a limit to the # of <style> tags allowed, so we avoid 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tempting the fates. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cfHiddenInjected) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var rules = '.chromeFrameOverlayContent { display: none; }' + 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '.chromeFrameOverlayUnderlay { display: none; }'; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) injectStyleSheet(rules); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide the dialog for a year (or until cookies are deleted). 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var age = 365 * 24 * 60 * 60 * 1000; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.cookie = "disableGCFCheck=1;path=/;max-age="+age; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cfHiddenInjected = true; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Plucks properties from the passed arguments and sets them on the passed 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DOM node 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Node} node The node to set properties on 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} args A map of user-specified properties to set 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var setProperties = function(node, args) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var srcNode = byId(args['node']); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.id = args['id'] || (srcNode ? srcNode['id'] || getUid(srcNode) : ''); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(slightlyoff): Opera compat? need to test there 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var cssText = args['cssText'] || ''; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.style.cssText = ' ' + cssText; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var classText = args['className'] || ''; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.className = classText; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default if the browser doesn't so we don't show sad-tab 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var src = args['src'] || 'about:blank'; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node.src = src; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (srcNode) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srcNode.parentNode.replaceChild(node, srcNode); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Creates an iframe. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} args A bag of configuration properties, including values 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * like 'node', 'cssText', 'className', 'id', 'src', etc. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {Node} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var makeIframe = function(args) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var el = document.createElement('iframe'); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) el.setAttribute('frameborder', '0'); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) el.setAttribute('border', '0'); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setProperties(el, args); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return el; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adds an unadorned iframe into the page, taking arguments to customize it. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} args A map of user-specified properties to set 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var makeInlinePrompt = function(args) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.className = 'chromeFrameInstallDefaultStyle ' + 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (args.className || ''); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var ifr = makeIframe(args); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(slightlyoff): handle placement more elegantly! 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ifr.parentNode) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var firstChild = document.body.firstChild; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.body.insertBefore(ifr, firstChild); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adds a styled, closable iframe into the page with a background that 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * emulates a modal dialog. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} args A map of user-specified properties to set 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var makeOverlayPrompt = function(args) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (byId('chromeFrameOverlayContent')) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Was previously created. Bail. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var n = document.createElement('span'); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n.innerHTML = '<div class="chromeFrameOverlayUnderlay"></div>' + 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '<table class="chromeFrameOverlayContent"' + 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'id="chromeFrameOverlayContent"' + 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'cellpadding="0" cellspacing="0">' + 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '<tr class="chromeFrameOverlayCloseBar">' + 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '<td>' + 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(slightlyoff): i18n 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '<button id="chromeFrameCloseButton">close</button>' + 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '</td>' + 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '</tr>' + 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '<tr>' + 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '<td id="chromeFrameIframeHolder"></td>' + 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '</tr>' + 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '</table>'; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var b = document.body; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Insert underlay nodes into the document in the right order. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (n.firstChild) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b.insertBefore(n.lastChild, b.firstChild); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var ifr = makeIframe(args); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) byId('chromeFrameIframeHolder').appendChild(ifr); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) byId('chromeFrameCloseButton').onclick = closeOverlay; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var CFInstall = {}; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks to see if Chrome Frame is available, if not, prompts the user to 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * install. Once installation is begun, a background timer starts, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * checkinging for a successful install every 2 seconds. Upon detection of 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * successful installation, the current page is reloaded, or if a 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 'destination' parameter is passed, the page navigates there instead. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} args A bag of configuration properties. Respected 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * properties are: 'mode', 'url', 'destination', 'node', 'onmissing', 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 'preventPrompt', 'oninstall', 'preventInstallDetection', 'cssText', and 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 'className'. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @public 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFInstall.check = function(args) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args = args || {}; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We currently only support CF in IE 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(slightlyoff): Update this should we support other browsers! 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var ua = navigator.userAgent; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var ieRe = /MSIE (\S+); Windows NT/; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var bail = false; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ieRe.test(ua)) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We also only support Win2003/XPSP2 or better. See: 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://msdn.microsoft.com/en-us/library/ms537503%28VS.85%29.aspx 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parseFloat(ieRe.exec(ua)[1]) < 6 && 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'SV1' indicates SP2, only bail if not SP2 or Win2K3 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ua.indexOf('SV1') < 0) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bail = true; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not IE 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bail = true; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bail) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Inject the default styles 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) injectCFStyleTag(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (document.cookie.indexOf("disableGCFCheck=1") >=0) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're supposed to hide the overlay prompt, add the rules to do it. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closeOverlay(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When loaded in an alternate protocol (e.g., "file:"), still call out to 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the right location. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var currentProtocol = document.location.protocol; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var protocol = (currentProtocol == 'https:') ? 'https:' : 'http:'; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(slightlyoff): Update this URL when a mini-installer page is 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // available. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var installUrl = protocol + '//www.google.com/chromeframe'; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!isAvailable()) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args.onmissing) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.onmissing(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.src = args.url || installUrl; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var mode = args.mode || 'inline'; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var preventPrompt = args.preventPrompt || false; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!preventPrompt) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mode == 'inline') { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) makeInlinePrompt(args); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (mode == 'overlay') { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) makeOverlayPrompt(args); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window.open(args.src); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args.preventInstallDetection) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Begin polling for install success. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var installTimer = setInterval(function() { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // every 2 seconds, look to see if CF is available, if so, proceed on 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to our destination 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isAvailable()) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args.oninstall) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.oninstall(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clearInterval(installTimer); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(slightlyoff): add a way to prevent navigation or make it 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contingent on oninstall? 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window.location = args.destination || window.location; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2000); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFInstall._force = false; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFInstall._forceValue = false; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFInstall.isAvailable = isAvailable; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // expose CFInstall to the external scope. We've already checked to make 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sure we're not going to blow existing objects away. 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scope.CFInstall = CFInstall; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)})(this['ChromeFrameInstallScope'] || this); 358