Created
August 10, 2011 19:32
-
-
Save SlexAxton/1137907 to your computer and use it in GitHub Desktop.
Chrome Frame install script with 'user=true' as a config value option (no admin needed)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
(function(d){if(!d.CFInstall){var e=function(a){return typeof a=="string"?document.getElementById(a):a},f=function(){if(d.a.b)return d.a.c;if(navigator.userAgent.toLowerCase().indexOf("chromeframe")>=0)return!0;if(typeof window.ActiveXObject!="undefined")try{var a=new ActiveXObject("ChromeTab.ChromeFrame");if(a)return a.k(),!0}catch(b){}return!1},g=function(a){try{var b=document.createElement("style");b.setAttribute("type","text/css");b.styleSheet?b.styleSheet.cssText=a:b.appendChild(document.createTextNode(a)); | |
var c=document.getElementsByTagName("head")[0];c.insertBefore(b,c.firstChild)}catch(d){}},h=!1,i=!1,j=function(){if(!i)g(".chromeFrameOverlayContent { display: none; }.chromeFrameOverlayUnderlay { display: none; }"),document.cookie="disableGCFCheck=1;path=/;max-age=31536000000",i=!0},k=function(a){var b=document.createElement("iframe");b.setAttribute("frameborder","0");b.setAttribute("border","0");var c=e(a.node);b.id=a.id||(c?c.id||getUid(c):"");b.style.cssText=" "+(a.cssText||"");b.className=a.className|| | |
"";b.src=a.src||"about:blank";c&&c.parentNode.replaceChild(b,c);return b},m=function(a){a.className="chromeFrameInstallDefaultStyle "+(a.className||"");a=k(a);a.parentNode||document.body.insertBefore(a,document.body.firstChild)},n=function(a){if(!e("chromeFrameOverlayContent")){var b=document.createElement("span");b.innerHTML='<div class="chromeFrameOverlayUnderlay"></div><table class="chromeFrameOverlayContent"id="chromeFrameOverlayContent"cellpadding="0" cellspacing="0"><tr class="chromeFrameOverlayCloseBar"><td><button id="chromeFrameCloseButton">close</button></td></tr><tr><td id="chromeFrameIframeHolder"></td></tr></table>'; | |
for(var c=document.body;b.firstChild;)c.insertBefore(b.lastChild,c.firstChild);a=k(a);e("chromeFrameIframeHolder").appendChild(a);e("chromeFrameCloseButton").onclick=j}},l={f:function(a){var a=a||{},b=navigator.userAgent,c=/MSIE (\S+); Windows NT/,d=!1;c.test(b)?parseFloat(c.exec(b)[1])<6&&b.indexOf("SV1")<0&&(d=!0):d=!0;if(!d&&(h||(g('.chromeFrameInstallDefaultStyle {width: 800px;height: 600px;position: absolute;left: 50%;top: 50%;margin-left: -400px;margin-top: -300px;}.chromeFrameOverlayContent {position: absolute;margin-left: -400px;margin-top: -300px;left: 50%;top: 50%;border: 1px solid #93B4D9;background-color: white;z-index: 2001;}.chromeFrameOverlayContent iframe {width: 800px;height: 600px;border: none;}.chromeFrameOverlayCloseBar {height: 1em;text-align: right;background-color: #CADEF4;}.chromeFrameOverlayUnderlay {position: absolute;width: 100%;height: 100%;background-color: white;opacity: 0.5;-moz-opacity: 0.5;-webkit-opacity: 0.5;-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";filter: alpha(opacity=50);z-index: 2000;}'), | |
h=!0),document.cookie.indexOf("disableGCFCheck=1")>=0&&j(),b=(document.location.protocol=="https:"?"https:":"http:")+"//www.google.com/chromeframe"+(a.l?"?user=true":""),!f()&&(a.e&&a.e(),a.src=a.url||b,b=a.mode||"inline",a.j||(b=="inline"?m(a):b=="overlay"?n(a):window.open(a.src)),!a.i)))var e=setInterval(function(){if(f())a.d&&a.d(),clearInterval(e),window.location=a.g||window.location},2E3)},b:!1,c:!1};l.h=f;d.a=l}})(this.ChromeFrameInstallScope||this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
/** | |
* @fileoverview CFInstall.js provides a set of utilities for managing | |
* the Chrome Frame detection and installation process. | |
* @author [email protected] (Alex Russell) | |
*/ | |
(function(scope) { | |
// bail if we'd be over-writing an existing CFInstall object | |
if (scope['CFInstall']) { | |
return; | |
} | |
/** | |
* returns an item based on DOM ID. Optionally a document may be provided to | |
* specify the scope to search in. If a node is passed, it's returned as-is. | |
* @param {string|Node} id The ID of the node to be located or a node | |
* @param {Node} doc Optional A document to search for id. | |
* @return {Node} | |
*/ | |
var byId = function(id, doc) { | |
return (typeof id == 'string') ? (doc || document).getElementById(id) : id; | |
}; | |
///////////////////////////////////////////////////////////////////////////// | |
// Plugin Detection | |
///////////////////////////////////////////////////////////////////////////// | |
/** | |
* Checks to find out if ChromeFrame is available as a plugin | |
* @return {Boolean} | |
*/ | |
var isAvailable = function() { | |
// For testing purposes. | |
if (scope.CFInstall._force) { | |
return scope.CFInstall._forceValue; | |
} | |
// Look for CF in the User Agent before trying more expensive checks | |
var ua = navigator.userAgent.toLowerCase(); | |
if (ua.indexOf("chromeframe") >= 0) { | |
return true; | |
} | |
if (typeof window['ActiveXObject'] != 'undefined') { | |
try { | |
var obj = new ActiveXObject('ChromeTab.ChromeFrame'); | |
if (obj) { | |
obj.registerBhoIfNeeded(); | |
return true; | |
} | |
} catch(e) { | |
// squelch | |
} | |
} | |
return false; | |
}; | |
/** | |
* Creates a style sheet in the document containing the passed rules. | |
*/ | |
var injectStyleSheet = function(rules) { | |
try { | |
var ss = document.createElement('style'); | |
ss.setAttribute('type', 'text/css'); | |
if (ss.styleSheet) { | |
ss.styleSheet.cssText = rules; | |
} else { | |
ss.appendChild(document.createTextNode(rules)); | |
} | |
var h = document.getElementsByTagName('head')[0]; | |
var firstChild = h.firstChild; | |
h.insertBefore(ss, firstChild); | |
} catch (e) { | |
// squelch | |
} | |
}; | |
/** @type {boolean} */ | |
var cfStyleTagInjected = false; | |
/** @type {boolean} */ | |
var cfHiddenInjected = false; | |
/** | |
* Injects style rules into the document to handle formatting of Chrome Frame | |
* prompt. Multiple calls have no effect. | |
*/ | |
var injectCFStyleTag = function() { | |
if (cfStyleTagInjected) { | |
// Once and only once | |
return; | |
} | |
var rules = '.chromeFrameInstallDefaultStyle {' + | |
'width: 800px;' + | |
'height: 600px;' + | |
'position: absolute;' + | |
'left: 50%;' + | |
'top: 50%;' + | |
'margin-left: -400px;' + | |
'margin-top: -300px;' + | |
'}' + | |
'.chromeFrameOverlayContent {' + | |
'position: absolute;' + | |
'margin-left: -400px;' + | |
'margin-top: -300px;' + | |
'left: 50%;' + | |
'top: 50%;' + | |
'border: 1px solid #93B4D9;' + | |
'background-color: white;' + | |
'z-index: 2001;' + | |
'}' + | |
'.chromeFrameOverlayContent iframe {' + | |
'width: 800px;' + | |
'height: 600px;' + | |
'border: none;' + | |
'}' + | |
'.chromeFrameOverlayCloseBar {' + | |
'height: 1em;' + | |
'text-align: right;' + | |
'background-color: #CADEF4;' + | |
'}' + | |
'.chromeFrameOverlayUnderlay {' + | |
'position: absolute;' + | |
'width: 100%;' + | |
'height: 100%;' + | |
'background-color: white;' + | |
'opacity: 0.5;' + | |
'-moz-opacity: 0.5;' + | |
'-webkit-opacity: 0.5;' + | |
'-ms-filter: ' + | |
'"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";' + | |
'filter: alpha(opacity=50);' + | |
'z-index: 2000;' + | |
'}'; | |
injectStyleSheet(rules); | |
cfStyleTagInjected = true; | |
}; | |
/** | |
* Injects style rules to hide the overlay version of the GCF prompt. | |
* Multiple calls have no effect. | |
*/ | |
var closeOverlay = function() { | |
// IE has a limit to the # of <style> tags allowed, so we avoid | |
// tempting the fates. | |
if (cfHiddenInjected) { | |
return; | |
} | |
var rules = '.chromeFrameOverlayContent { display: none; }' + | |
'.chromeFrameOverlayUnderlay { display: none; }'; | |
injectStyleSheet(rules); | |
// Hide the dialog for a year (or until cookies are deleted). | |
var age = 365 * 24 * 60 * 60 * 1000; | |
document.cookie = "disableGCFCheck=1;path=/;max-age="+age; | |
cfHiddenInjected = true; | |
}; | |
/** | |
* Plucks properties from the passed arguments and sets them on the passed | |
* DOM node | |
* @param {Node} node The node to set properties on | |
* @param {Object} args A map of user-specified properties to set | |
*/ | |
var setProperties = function(node, args) { | |
var srcNode = byId(args['node']); | |
node.id = args['id'] || (srcNode ? srcNode['id'] || getUid(srcNode) : ''); | |
// TODO(slightlyoff): Opera compat? need to test there | |
var cssText = args['cssText'] || ''; | |
node.style.cssText = ' ' + cssText; | |
var classText = args['className'] || ''; | |
node.className = classText; | |
// default if the browser doesn't so we don't show sad-tab | |
var src = args['src'] || 'about:blank'; | |
node.src = src; | |
if (srcNode) { | |
srcNode.parentNode.replaceChild(node, srcNode); | |
} | |
}; | |
/** | |
* Creates an iframe. | |
* @param {Object} args A bag of configuration properties, including values | |
* like 'node', 'cssText', 'className', 'id', 'src', etc. | |
* @return {Node} | |
*/ | |
var makeIframe = function(args) { | |
var el = document.createElement('iframe'); | |
el.setAttribute('frameborder', '0'); | |
el.setAttribute('border', '0'); | |
setProperties(el, args); | |
return el; | |
}; | |
/** | |
* Adds an unadorned iframe into the page, taking arguments to customize it. | |
* @param {Object} args A map of user-specified properties to set | |
*/ | |
var makeInlinePrompt = function(args) { | |
args.className = 'chromeFrameInstallDefaultStyle ' + | |
(args.className || ''); | |
var ifr = makeIframe(args); | |
// TODO(slightlyoff): handle placement more elegantly! | |
if (!ifr.parentNode) { | |
var firstChild = document.body.firstChild; | |
document.body.insertBefore(ifr, firstChild); | |
} | |
}; | |
/** | |
* Adds a styled, closable iframe into the page with a background that | |
* emulates a modal dialog. | |
* @param {Object} args A map of user-specified properties to set | |
*/ | |
var makeOverlayPrompt = function(args) { | |
if (byId('chromeFrameOverlayContent')) { | |
return; // Was previously created. Bail. | |
} | |
var n = document.createElement('span'); | |
n.innerHTML = '<div class="chromeFrameOverlayUnderlay"></div>' + | |
'<table class="chromeFrameOverlayContent"' + | |
'id="chromeFrameOverlayContent"' + | |
'cellpadding="0" cellspacing="0">' + | |
'<tr class="chromeFrameOverlayCloseBar">' + | |
'<td>' + | |
// TODO(slightlyoff): i18n | |
'<button id="chromeFrameCloseButton">close</button>' + | |
'</td>' + | |
'</tr>' + | |
'<tr>' + | |
'<td id="chromeFrameIframeHolder"></td>' + | |
'</tr>' + | |
'</table>'; | |
var b = document.body; | |
// Insert underlay nodes into the document in the right order. | |
while (n.firstChild) { | |
b.insertBefore(n.lastChild, b.firstChild); | |
} | |
var ifr = makeIframe(args); | |
byId('chromeFrameIframeHolder').appendChild(ifr); | |
byId('chromeFrameCloseButton').onclick = closeOverlay; | |
}; | |
var CFInstall = {}; | |
/** | |
* Checks to see if Chrome Frame is available, if not, prompts the user to | |
* install. Once installation is begun, a background timer starts, | |
* checkinging for a successful install every 2 seconds. Upon detection of | |
* successful installation, the current page is reloaded, or if a | |
* 'destination' parameter is passed, the page navigates there instead. | |
* @param {Object} args A bag of configuration properties. Respected | |
* properties are: 'mode', 'url', 'destination', 'node', 'onmissing', | |
* 'preventPrompt', 'oninstall', 'preventInstallDetection', 'cssText', and | |
* 'className'. | |
* @public | |
*/ | |
CFInstall.check = function(args) { | |
args = args || {}; | |
// We currently only support CF in IE | |
// TODO(slightlyoff): Update this should we support other browsers! | |
var ua = navigator.userAgent; | |
var ieRe = /MSIE (\S+); Windows NT/; | |
var bail = false; | |
if (ieRe.test(ua)) { | |
// We also only support Win2003/XPSP2 or better. See: | |
// http://msdn.microsoft.com/en-us/library/ms537503%28VS.85%29.aspx | |
if (parseFloat(ieRe.exec(ua)[1]) < 6 && | |
// 'SV1' indicates SP2, only bail if not SP2 or Win2K3 | |
ua.indexOf('SV1') < 0) { | |
bail = true; | |
} | |
} else { | |
// Not IE | |
bail = true; | |
} | |
if (bail) { | |
return; | |
} | |
// Inject the default styles | |
injectCFStyleTag(); | |
if (document.cookie.indexOf("disableGCFCheck=1") >=0) { | |
// If we're supposed to hide the overlay prompt, add the rules to do it. | |
closeOverlay(); | |
} | |
// When loaded in an alternate protocol (e.g., "file:"), still call out to | |
// the right location. | |
var currentProtocol = document.location.protocol; | |
var protocol = (currentProtocol == 'https:') ? 'https:' : 'http:'; | |
// TODO(slightlyoff): Update this URL when a mini-installer page is | |
// available. | |
var installUrl = protocol + '//www.google.com/chromeframe' + (args.user ? '?user=true': ''); | |
if (!isAvailable()) { | |
if (args.onmissing) { | |
args.onmissing(); | |
} | |
args.src = args.url || installUrl; | |
var mode = args.mode || 'inline'; | |
var preventPrompt = args.preventPrompt || false; | |
if (!preventPrompt) { | |
if (mode == 'inline') { | |
makeInlinePrompt(args); | |
} else if (mode == 'overlay') { | |
makeOverlayPrompt(args); | |
} else { | |
window.open(args.src); | |
} | |
} | |
if (args.preventInstallDetection) { | |
return; | |
} | |
// Begin polling for install success. | |
var installTimer = setInterval(function() { | |
// every 2 seconds, look to see if CF is available, if so, proceed on | |
// to our destination | |
if (isAvailable()) { | |
if (args.oninstall) { | |
args.oninstall(); | |
} | |
clearInterval(installTimer); | |
// TODO(slightlyoff): add a way to prevent navigation or make it | |
// contingent on oninstall? | |
window.location = args.destination || window.location; | |
} | |
}, 2000); | |
} | |
}; | |
CFInstall._force = false; | |
CFInstall._forceValue = false; | |
CFInstall.isAvailable = isAvailable; | |
// expose CFInstall to the external scope. We've already checked to make | |
// sure we're not going to blow existing objects away. | |
scope.CFInstall = CFInstall; | |
})(this['ChromeFrameInstallScope'] || this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--[if lt IE 7 ]> | |
<script defer src="//x.com/cfinstall.1.0.3mod-min.js"></script> | |
<script defer>window.attachEvent('onload',function(){CFInstall.check({mode:'overlay', user:true})})</script> | |
<![endif]--> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment