Permalink
Browse files

Add non-minified javascript files used in docs/ (#939)

  • Loading branch information...
1 parent 5705fcf commit 5d1fdc7941f010d0f80740e0284414163c03e301 @bigon bigon committed May 30, 2012
Showing with 2,209 additions and 13 deletions.
  1. +289 −13 docs/public/js/libs/dd_belatedpng.js
  2. +892 −0 docs/public/js/libs/modernizr-1.6.js
  3. +1,028 −0 docs/public/js/profiling/yahoo-profiling.js
View
302 docs/public/js/libs/dd_belatedpng.js 100755 → 100644
@@ -1,13 +1,289 @@
-/**
-* DD_belatedPNG: Adds IE6 support: PNG images for CSS background-image and HTML <IMG/>.
-* Author: Drew Diller
-* Email: drew.diller@gmail.com
-* URL: http://www.dillerdesign.com/experiment/DD_belatedPNG/
-* Version: 0.0.8a
-* Licensed under the MIT License: http://dillerdesign.com/experiment/DD_belatedPNG/#license
-*
-* Example usage:
-* DD_belatedPNG.fix('.png_bg'); // argument is a CSS selector
-* DD_belatedPNG.fixPng( someNode ); // argument is an HTMLDomElement
-**/
-var DD_belatedPNG={ns:"DD_belatedPNG",imgSize:{},delay:10,nodesFixed:0,createVmlNameSpace:function(){if(document.namespaces&&!document.namespaces[this.ns]){document.namespaces.add(this.ns,"urn:schemas-microsoft-com:vml")}},createVmlStyleSheet:function(){var b,a;b=document.createElement("style");b.setAttribute("media","screen");document.documentElement.firstChild.insertBefore(b,document.documentElement.firstChild.firstChild);if(b.styleSheet){b=b.styleSheet;b.addRule(this.ns+"\\:*","{behavior:url(#default#VML)}");b.addRule(this.ns+"\\:shape","position:absolute;");b.addRule("img."+this.ns+"_sizeFinder","behavior:none; border:none; position:absolute; z-index:-1; top:-10000px; visibility:hidden;");this.screenStyleSheet=b;a=document.createElement("style");a.setAttribute("media","print");document.documentElement.firstChild.insertBefore(a,document.documentElement.firstChild.firstChild);a=a.styleSheet;a.addRule(this.ns+"\\:*","{display: none !important;}");a.addRule("img."+this.ns+"_sizeFinder","{display: none !important;}")}},readPropertyChange:function(){var b,c,a;b=event.srcElement;if(!b.vmlInitiated){return}if(event.propertyName.search("background")!=-1||event.propertyName.search("border")!=-1){DD_belatedPNG.applyVML(b)}if(event.propertyName=="style.display"){c=(b.currentStyle.display=="none")?"none":"block";for(a in b.vml){if(b.vml.hasOwnProperty(a)){b.vml[a].shape.style.display=c}}}if(event.propertyName.search("filter")!=-1){DD_belatedPNG.vmlOpacity(b)}},vmlOpacity:function(b){if(b.currentStyle.filter.search("lpha")!=-1){var a=b.currentStyle.filter;a=parseInt(a.substring(a.lastIndexOf("=")+1,a.lastIndexOf(")")),10)/100;b.vml.color.shape.style.filter=b.currentStyle.filter;b.vml.image.fill.opacity=a}},handlePseudoHover:function(a){setTimeout(function(){DD_belatedPNG.applyVML(a)},1)},fix:function(a){if(this.screenStyleSheet){var c,b;c=a.split(",");for(b=0;b<c.length;b++){this.screenStyleSheet.addRule(c[b],"behavior:expression(DD_belatedPNG.fixPng(this))")}}},applyVML:function(a){a.runtimeStyle.cssText="";this.vmlFill(a);this.vmlOffsets(a);this.vmlOpacity(a);if(a.isImg){this.copyImageBorders(a)}},attachHandlers:function(i){var d,c,g,e,b,f;d=this;c={resize:"vmlOffsets",move:"vmlOffsets"};if(i.nodeName=="A"){e={mouseleave:"handlePseudoHover",mouseenter:"handlePseudoHover",focus:"handlePseudoHover",blur:"handlePseudoHover"};for(b in e){if(e.hasOwnProperty(b)){c[b]=e[b]}}}for(f in c){if(c.hasOwnProperty(f)){g=function(){d[c[f]](i)};i.attachEvent("on"+f,g)}}i.attachEvent("onpropertychange",this.readPropertyChange)},giveLayout:function(a){a.style.zoom=1;if(a.currentStyle.position=="static"){a.style.position="relative"}},copyImageBorders:function(b){var c,a;c={borderStyle:true,borderWidth:true,borderColor:true};for(a in c){if(c.hasOwnProperty(a)){b.vml.color.shape.style[a]=b.currentStyle[a]}}},vmlFill:function(e){if(!e.currentStyle){return}else{var d,f,g,b,a,c;d=e.currentStyle}for(b in e.vml){if(e.vml.hasOwnProperty(b)){e.vml[b].shape.style.zIndex=d.zIndex}}e.runtimeStyle.backgroundColor="";e.runtimeStyle.backgroundImage="";f=true;if(d.backgroundImage!="none"||e.isImg){if(!e.isImg){e.vmlBg=d.backgroundImage;e.vmlBg=e.vmlBg.substr(5,e.vmlBg.lastIndexOf('")')-5)}else{e.vmlBg=e.src}g=this;if(!g.imgSize[e.vmlBg]){a=document.createElement("img");g.imgSize[e.vmlBg]=a;a.className=g.ns+"_sizeFinder";a.runtimeStyle.cssText="behavior:none; position:absolute; left:-10000px; top:-10000px; border:none; margin:0; padding:0;";c=function(){this.width=this.offsetWidth;this.height=this.offsetHeight;g.vmlOffsets(e)};a.attachEvent("onload",c);a.src=e.vmlBg;a.removeAttribute("width");a.removeAttribute("height");document.body.insertBefore(a,document.body.firstChild)}e.vml.image.fill.src=e.vmlBg;f=false}e.vml.image.fill.on=!f;e.vml.image.fill.color="none";e.vml.color.shape.style.backgroundColor=d.backgroundColor;e.runtimeStyle.backgroundImage="none";e.runtimeStyle.backgroundColor="transparent"},vmlOffsets:function(d){var h,n,a,e,g,m,f,l,j,i,k;h=d.currentStyle;n={W:d.clientWidth+1,H:d.clientHeight+1,w:this.imgSize[d.vmlBg].width,h:this.imgSize[d.vmlBg].height,L:d.offsetLeft,T:d.offsetTop,bLW:d.clientLeft,bTW:d.clientTop};a=(n.L+n.bLW==1)?1:0;e=function(b,p,q,c,s,u){b.coordsize=c+","+s;b.coordorigin=u+","+u;b.path="m0,0l"+c+",0l"+c+","+s+"l0,"+s+" xe";b.style.width=c+"px";b.style.height=s+"px";b.style.left=p+"px";b.style.top=q+"px"};e(d.vml.color.shape,(n.L+(d.isImg?0:n.bLW)),(n.T+(d.isImg?0:n.bTW)),(n.W-1),(n.H-1),0);e(d.vml.image.shape,(n.L+n.bLW),(n.T+n.bTW),(n.W),(n.H),1);g={X:0,Y:0};if(d.isImg){g.X=parseInt(h.paddingLeft,10)+1;g.Y=parseInt(h.paddingTop,10)+1}else{for(j in g){if(g.hasOwnProperty(j)){this.figurePercentage(g,n,j,h["backgroundPosition"+j])}}}d.vml.image.fill.position=(g.X/n.W)+","+(g.Y/n.H);m=h.backgroundRepeat;f={T:1,R:n.W+a,B:n.H,L:1+a};l={X:{b1:"L",b2:"R",d:"W"},Y:{b1:"T",b2:"B",d:"H"}};if(m!="repeat"||d.isImg){i={T:(g.Y),R:(g.X+n.w),B:(g.Y+n.h),L:(g.X)};if(m.search("repeat-")!=-1){k=m.split("repeat-")[1].toUpperCase();i[l[k].b1]=1;i[l[k].b2]=n[l[k].d]}if(i.B>n.H){i.B=n.H}d.vml.image.shape.style.clip="rect("+i.T+"px "+(i.R+a)+"px "+i.B+"px "+(i.L+a)+"px)"}else{d.vml.image.shape.style.clip="rect("+f.T+"px "+f.R+"px "+f.B+"px "+f.L+"px)"}},figurePercentage:function(d,c,f,a){var b,e;e=true;b=(f=="X");switch(a){case"left":case"top":d[f]=0;break;case"center":d[f]=0.5;break;case"right":case"bottom":d[f]=1;break;default:if(a.search("%")!=-1){d[f]=parseInt(a,10)/100}else{e=false}}d[f]=Math.ceil(e?((c[b?"W":"H"]*d[f])-(c[b?"w":"h"]*d[f])):parseInt(a,10));if(d[f]%2===0){d[f]++}return d[f]},fixPng:function(c){c.style.behavior="none";var g,b,f,a,d;if(c.nodeName=="BODY"||c.nodeName=="TD"||c.nodeName=="TR"){return}c.isImg=false;if(c.nodeName=="IMG"){if(c.src.toLowerCase().search(/\.png$/)!=-1){c.isImg=true;c.style.visibility="hidden"}else{return}}else{if(c.currentStyle.backgroundImage.toLowerCase().search(".png")==-1){return}}g=DD_belatedPNG;c.vml={color:{},image:{}};b={shape:{},fill:{}};for(a in c.vml){if(c.vml.hasOwnProperty(a)){for(d in b){if(b.hasOwnProperty(d)){f=g.ns+":"+d;c.vml[a][d]=document.createElement(f)}}c.vml[a].shape.stroked=false;c.vml[a].shape.appendChild(c.vml[a].fill);c.parentNode.insertBefore(c.vml[a].shape,c)}}c.vml.image.shape.fillcolor="none";c.vml.image.fill.type="tile";c.vml.color.fill.on=false;g.attachHandlers(c);g.giveLayout(c);g.giveLayout(c.offsetParent);c.vmlInitiated=true;g.applyVML(c)}};try{document.execCommand("BackgroundImageCache",false,true)}catch(r){}DD_belatedPNG.createVmlNameSpace();DD_belatedPNG.createVmlStyleSheet();
+/**
+* DD_belatedPNG: Adds IE6 support: PNG images for CSS background-image and HTML <IMG/>.
+* Author: Drew Diller
+* Email: drew.diller@gmail.com
+* URL: http://www.dillerdesign.com/experiment/DD_belatedPNG/
+* Version: 0.0.8a
+* Licensed under the MIT License: http://dillerdesign.com/experiment/DD_belatedPNG/#license
+*
+* Example usage:
+* DD_belatedPNG.fix('.png_bg'); // argument is a CSS selector
+* DD_belatedPNG.fixPng( someNode ); // argument is an HTMLDomElement
+**/
+
+/*
+PLEASE READ:
+Absolutely everything in this script is SILLY. I know this. IE's rendering of certain pixels doesn't make sense, so neither does this code!
+*/
+
+var DD_belatedPNG = {
+ ns: 'DD_belatedPNG',
+ imgSize: {},
+ delay: 10,
+ nodesFixed: 0,
+ createVmlNameSpace: function () { /* enable VML */
+ if (document.namespaces && !document.namespaces[this.ns]) {
+ document.namespaces.add(this.ns, 'urn:schemas-microsoft-com:vml');
+ }
+ },
+ createVmlStyleSheet: function () { /* style VML, enable behaviors */
+ /*
+ Just in case lots of other developers have added
+ lots of other stylesheets using document.createStyleSheet
+ and hit the 31-limit mark, let's not use that method!
+ further reading: http://msdn.microsoft.com/en-us/library/ms531194(VS.85).aspx
+ */
+ var screenStyleSheet, printStyleSheet;
+ screenStyleSheet = document.createElement('style');
+ screenStyleSheet.setAttribute('media', 'screen');
+ document.documentElement.firstChild.insertBefore(screenStyleSheet, document.documentElement.firstChild.firstChild);
+ if (screenStyleSheet.styleSheet) {
+ screenStyleSheet = screenStyleSheet.styleSheet;
+ screenStyleSheet.addRule(this.ns + '\\:*', '{behavior:url(#default#VML)}');
+ screenStyleSheet.addRule(this.ns + '\\:shape', 'position:absolute;');
+ screenStyleSheet.addRule('img.' + this.ns + '_sizeFinder', 'behavior:none; border:none; position:absolute; z-index:-1; top:-10000px; visibility:hidden;'); /* large negative top value for avoiding vertical scrollbars for large images, suggested by James O'Brien, http://www.thanatopsic.org/hendrik/ */
+ this.screenStyleSheet = screenStyleSheet;
+
+ /* Add a print-media stylesheet, for preventing VML artifacts from showing up in print (including preview). */
+ /* Thanks to Rémi Prévost for automating this! */
+ printStyleSheet = document.createElement('style');
+ printStyleSheet.setAttribute('media', 'print');
+ document.documentElement.firstChild.insertBefore(printStyleSheet, document.documentElement.firstChild.firstChild);
+ printStyleSheet = printStyleSheet.styleSheet;
+ printStyleSheet.addRule(this.ns + '\\:*', '{display: none !important;}');
+ printStyleSheet.addRule('img.' + this.ns + '_sizeFinder', '{display: none !important;}');
+ }
+ },
+ readPropertyChange: function () {
+ var el, display, v;
+ el = event.srcElement;
+ if (!el.vmlInitiated) {
+ return;
+ }
+ if (event.propertyName.search('background') != -1 || event.propertyName.search('border') != -1) {
+ DD_belatedPNG.applyVML(el);
+ }
+ if (event.propertyName == 'style.display') {
+ display = (el.currentStyle.display == 'none') ? 'none' : 'block';
+ for (v in el.vml) {
+ if (el.vml.hasOwnProperty(v)) {
+ el.vml[v].shape.style.display = display;
+ }
+ }
+ }
+ if (event.propertyName.search('filter') != -1) {
+ DD_belatedPNG.vmlOpacity(el);
+ }
+ },
+ vmlOpacity: function (el) {
+ if (el.currentStyle.filter.search('lpha') != -1) {
+ var trans = el.currentStyle.filter;
+ trans = parseInt(trans.substring(trans.lastIndexOf('=')+1, trans.lastIndexOf(')')), 10)/100;
+ el.vml.color.shape.style.filter = el.currentStyle.filter; /* complete guesswork */
+ el.vml.image.fill.opacity = trans; /* complete guesswork */
+ }
+ },
+ handlePseudoHover: function (el) {
+ setTimeout(function () { /* wouldn't work as intended without setTimeout */
+ DD_belatedPNG.applyVML(el);
+ }, 1);
+ },
+ /**
+ * This is the method to use in a document.
+ * @param {String} selector - REQUIRED - a CSS selector, such as '#doc .container'
+ **/
+ fix: function (selector) {
+ if (this.screenStyleSheet) {
+ var selectors, i;
+ selectors = selector.split(','); /* multiple selectors supported, no need for multiple calls to this anymore */
+ for (i=0; i<selectors.length; i++) {
+ this.screenStyleSheet.addRule(selectors[i], 'behavior:expression(DD_belatedPNG.fixPng(this))'); /* seems to execute the function without adding it to the stylesheet - interesting... */
+ }
+ }
+ },
+ applyVML: function (el) {
+ el.runtimeStyle.cssText = '';
+ this.vmlFill(el);
+ this.vmlOffsets(el);
+ this.vmlOpacity(el);
+ if (el.isImg) {
+ this.copyImageBorders(el);
+ }
+ },
+ attachHandlers: function (el) {
+ var self, handlers, handler, moreForAs, a, h;
+ self = this;
+ handlers = {resize: 'vmlOffsets', move: 'vmlOffsets'};
+ if (el.nodeName == 'A') {
+ moreForAs = {mouseleave: 'handlePseudoHover', mouseenter: 'handlePseudoHover', focus: 'handlePseudoHover', blur: 'handlePseudoHover'};
+ for (a in moreForAs) {
+ if (moreForAs.hasOwnProperty(a)) {
+ handlers[a] = moreForAs[a];
+ }
+ }
+ }
+ for (h in handlers) {
+ if (handlers.hasOwnProperty(h)) {
+ handler = function () {
+ self[handlers[h]](el);
+ };
+ el.attachEvent('on' + h, handler);
+ }
+ }
+ el.attachEvent('onpropertychange', this.readPropertyChange);
+ },
+ giveLayout: function (el) {
+ el.style.zoom = 1;
+ if (el.currentStyle.position == 'static') {
+ el.style.position = 'relative';
+ }
+ },
+ copyImageBorders: function (el) {
+ var styles, s;
+ styles = {'borderStyle':true, 'borderWidth':true, 'borderColor':true};
+ for (s in styles) {
+ if (styles.hasOwnProperty(s)) {
+ el.vml.color.shape.style[s] = el.currentStyle[s];
+ }
+ }
+ },
+ vmlFill: function (el) {
+ if (!el.currentStyle) {
+ return;
+ } else {
+ var elStyle, noImg, lib, v, img, imgLoaded;
+ elStyle = el.currentStyle;
+ }
+ for (v in el.vml) {
+ if (el.vml.hasOwnProperty(v)) {
+ el.vml[v].shape.style.zIndex = elStyle.zIndex;
+ }
+ }
+ el.runtimeStyle.backgroundColor = '';
+ el.runtimeStyle.backgroundImage = '';
+ noImg = true;
+ if (elStyle.backgroundImage != 'none' || el.isImg) {
+ if (!el.isImg) {
+ el.vmlBg = elStyle.backgroundImage;
+ el.vmlBg = el.vmlBg.substr(5, el.vmlBg.lastIndexOf('")')-5);
+ }
+ else {
+ el.vmlBg = el.src;
+ }
+ lib = this;
+ if (!lib.imgSize[el.vmlBg]) { /* determine size of loaded image */
+ img = document.createElement('img');
+ lib.imgSize[el.vmlBg] = img;
+ img.className = lib.ns + '_sizeFinder';
+ img.runtimeStyle.cssText = 'behavior:none; position:absolute; left:-10000px; top:-10000px; border:none; margin:0; padding:0;'; /* make sure to set behavior to none to prevent accidental matching of the helper elements! */
+ imgLoaded = function () {
+ this.width = this.offsetWidth; /* weird cache-busting requirement! */
+ this.height = this.offsetHeight;
+ lib.vmlOffsets(el);
+ };
+ img.attachEvent('onload', imgLoaded);
+ img.src = el.vmlBg;
+ img.removeAttribute('width');
+ img.removeAttribute('height');
+ document.body.insertBefore(img, document.body.firstChild);
+ }
+ el.vml.image.fill.src = el.vmlBg;
+ noImg = false;
+ }
+ el.vml.image.fill.on = !noImg;
+ el.vml.image.fill.color = 'none';
+ el.vml.color.shape.style.backgroundColor = elStyle.backgroundColor;
+ el.runtimeStyle.backgroundImage = 'none';
+ el.runtimeStyle.backgroundColor = 'transparent';
+ },
+ /* IE can't figure out what do when the offsetLeft and the clientLeft add up to 1, and the VML ends up getting fuzzy... so we have to push/enlarge things by 1 pixel and then clip off the excess */
+ vmlOffsets: function (el) {
+ var thisStyle, size, fudge, makeVisible, bg, bgR, dC, altC, b, c, v;
+ thisStyle = el.currentStyle;
+ size = {'W':el.clientWidth+1, 'H':el.clientHeight+1, 'w':this.imgSize[el.vmlBg].width, 'h':this.imgSize[el.vmlBg].height, 'L':el.offsetLeft, 'T':el.offsetTop, 'bLW':el.clientLeft, 'bTW':el.clientTop};
+ fudge = (size.L + size.bLW == 1) ? 1 : 0;
+ /* vml shape, left, top, width, height, origin */
+ makeVisible = function (vml, l, t, w, h, o) {
+ vml.coordsize = w+','+h;
+ vml.coordorigin = o+','+o;
+ vml.path = 'm0,0l'+w+',0l'+w+','+h+'l0,'+h+' xe';
+ vml.style.width = w + 'px';
+ vml.style.height = h + 'px';
+ vml.style.left = l + 'px';
+ vml.style.top = t + 'px';
+ };
+ makeVisible(el.vml.color.shape, (size.L + (el.isImg ? 0 : size.bLW)), (size.T + (el.isImg ? 0 : size.bTW)), (size.W-1), (size.H-1), 0);
+ makeVisible(el.vml.image.shape, (size.L + size.bLW), (size.T + size.bTW), (size.W), (size.H), 1 );
+ bg = {'X':0, 'Y':0};
+ if (el.isImg) {
+ bg.X = parseInt(thisStyle.paddingLeft, 10) + 1;
+ bg.Y = parseInt(thisStyle.paddingTop, 10) + 1;
+ }
+ else {
+ for (b in bg) {
+ if (bg.hasOwnProperty(b)) {
+ this.figurePercentage(bg, size, b, thisStyle['backgroundPosition'+b]);
+ }
+ }
+ }
+ el.vml.image.fill.position = (bg.X/size.W) + ',' + (bg.Y/size.H);
+ bgR = thisStyle.backgroundRepeat;
+ dC = {'T':1, 'R':size.W+fudge, 'B':size.H, 'L':1+fudge}; /* these are defaults for repeat of any kind */
+ altC = { 'X': {'b1': 'L', 'b2': 'R', 'd': 'W'}, 'Y': {'b1': 'T', 'b2': 'B', 'd': 'H'} };
+ if (bgR != 'repeat' || el.isImg) {
+ c = {'T':(bg.Y), 'R':(bg.X+size.w), 'B':(bg.Y+size.h), 'L':(bg.X)}; /* these are defaults for no-repeat - clips down to the image location */
+ if (bgR.search('repeat-') != -1) { /* now let's revert to dC for repeat-x or repeat-y */
+ v = bgR.split('repeat-')[1].toUpperCase();
+ c[altC[v].b1] = 1;
+ c[altC[v].b2] = size[altC[v].d];
+ }
+ if (c.B > size.H) {
+ c.B = size.H;
+ }
+ el.vml.image.shape.style.clip = 'rect('+c.T+'px '+(c.R+fudge)+'px '+c.B+'px '+(c.L+fudge)+'px)';
+ }
+ else {
+ el.vml.image.shape.style.clip = 'rect('+dC.T+'px '+dC.R+'px '+dC.B+'px '+dC.L+'px)';
+ }
+ },
+ figurePercentage: function (bg, size, axis, position) {
+ var horizontal, fraction;
+ fraction = true;
+ horizontal = (axis == 'X');
+ switch(position) {
+ case 'left':
+ case 'top':
+ bg[axis] = 0;
+ break;
+ case 'center':
+ bg[axis] = 0.5;
+ break;
+ case 'right':
+ case 'bottom':
+ bg[axis] = 1;
+ break;
+ default:
+ if (position.search('%') != -1) {
+ bg[axis] = parseInt(position, 10) / 100;
+ }
+ else {
+ fraction = false;
+ }
+ }
+ bg[axis] = Math.ceil( fraction ? ( (size[horizontal?'W': 'H'] * bg[axis]) - (size[horizontal?'w': 'h'] * bg[axis]) ) : parseInt(position, 10) );
+ if (bg[axis] % 2 === 0) {
+ bg[axis]++;
+ }
+ return bg[axis];
+ },
+ fixPng: function (el) {
+ el.style.behavior = 'none';
+ var lib, els, nodeStr, v, e;
+ if (el.nodeName == 'BODY' || el.nodeName == 'TD' || el.nodeName == 'TR') { /* elements not supported yet */
+ return;
+ }
+ el.isImg = false;
+ if (el.nodeName == 'IMG') {
+ if(el.src.toLowerCase().search(/\.png$/) != -1) {
+ el.isImg = true;
+ el.style.visibility = 'hidden';
View
892 docs/public/js/libs/modernizr-1.6.js
@@ -0,0 +1,892 @@
+/*!
+ * Modernizr v1.6
+ * http://www.modernizr.com
+ *
+ * Developed by:
+ * - Faruk Ates http://farukat.es/
+ * - Paul Irish http://paulirish.com/
+ *
+ * Copyright (c) 2009-2010
+ * Dual-licensed under the BSD or MIT licenses.
+ * http://www.modernizr.com/license/
+ */
+
+
+/*
+ * Modernizr is a script that detects native CSS3 and HTML5 features
+ * available in the current UA and provides an object containing all
+ * features with a true/false value, depending on whether the UA has
+ * native support for it or not.
+ *
+ * Modernizr will also add classes to the <html> element of the page,
+ * one for each feature it detects. If the UA supports it, a class
+ * like "cssgradients" will be added. If not, the class name will be
+ * "no-cssgradients". This allows for simple if-conditionals in your
+ * CSS, giving you fine control over the look & feel of your website.
+ *
+ * @author Faruk Ates
+ * @author Paul Irish
+ * @copyright (c) 2009-2010 Faruk Ates.
+ * @contributor Ben Alman
+ */
+
+window.Modernizr = (function(window,doc,undefined){
+
+ var version = '1.6',
+
+ ret = {},
+
+ /**
+ * !! DEPRECATED !!
+ *
+ * enableHTML5 is a private property for advanced use only. If enabled,
+ * it will make Modernizr.init() run through a brief while() loop in
+ * which it will create all HTML5 elements in the DOM to allow for
+ * styling them in Internet Explorer, which does not recognize any
+ * non-HTML4 elements unless created in the DOM this way.
+ *
+ * enableHTML5 is ON by default.
+ *
+ * The enableHTML5 toggle option is DEPRECATED as per 1.6, and will be
+ * replaced in 2.0 in lieu of the modular, configurable nature of 2.0.
+ */
+ enableHTML5 = true,
+
+
+ docElement = doc.documentElement,
+
+ /**
+ * Create our "modernizr" element that we do most feature tests on.
+ */
+ mod = 'modernizr',
+ m = doc.createElement( mod ),
+ m_style = m.style,
+
+ /**
+ * Create the input element for various Web Forms feature tests.
+ */
+ f = doc.createElement( 'input' ),
+
+ smile = ':)',
+
+ tostring = Object.prototype.toString,
+
+ // List of property values to set for css tests. See ticket #21
+ prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '),
+
+ // Following spec is to expose vendor-specific style properties as:
+ // elem.style.WebkitBorderRadius
+ // and the following would be incorrect:
+ // elem.style.webkitBorderRadius
+
+ // Webkit ghosts their properties in lowercase but Opera & Moz do not.
+ // Microsoft foregoes prefixes entirely <= IE8, but appears to
+ // use a lowercase `ms` instead of the correct `Ms` in IE9
+
+ // More here: http://github.com/Modernizr/Modernizr/issues/issue/21
+ domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
+
+ ns = {'svg': 'http://www.w3.org/2000/svg'},
+
+ tests = {},
+ inputs = {},
+ attrs = {},
+
+ classes = [],
+
+ featurename, // used in testing loop
+
+
+
+ // todo: consider using http://javascript.nwbox.com/CSSSupport/css-support.js instead
+ testMediaQuery = function(mq){
+
+ var st = document.createElement('style'),
+ div = doc.createElement('div'),
+ ret;
+
+ st.textContent = mq + '{#modernizr{height:3px}}';
+ (doc.head || doc.getElementsByTagName('head')[0]).appendChild(st);
+ div.id = 'modernizr';
+ docElement.appendChild(div);
+
+ ret = div.offsetHeight === 3;
+
+ st.parentNode.removeChild(st);
+ div.parentNode.removeChild(div);
+
+ return !!ret;
+
+ },
+
+
+ /**
+ * isEventSupported determines if a given element supports the given event
+ * function from http://yura.thinkweb2.com/isEventSupported/
+ */
+ isEventSupported = (function(){
+
+ var TAGNAMES = {
+ 'select':'input','change':'input',
+ 'submit':'form','reset':'form',
+ 'error':'img','load':'img','abort':'img'
+ };
+
+ function isEventSupported(eventName, element) {
+
+ element = element || document.createElement(TAGNAMES[eventName] || 'div');
+ eventName = 'on' + eventName;
+
+ // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
+ var isSupported = (eventName in element);
+
+ if (!isSupported) {
+ // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
+ if (!element.setAttribute) {
+ element = document.createElement('div');
+ }
+ if (element.setAttribute && element.removeAttribute) {
+ element.setAttribute(eventName, '');
+ isSupported = typeof element[eventName] == 'function';
+
+ // If property was created, "remove it" (by setting value to `undefined`)
+ if (typeof element[eventName] != 'undefined') {
+ element[eventName] = undefined;
+ }
+ element.removeAttribute(eventName);
+ }
+ }
+
+ element = null;
+ return isSupported;
+ }
+ return isEventSupported;
+ })();
+
+
+ // hasOwnProperty shim by kangax needed for Safari 2.0 support
+ var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
+ if (typeof _hasOwnProperty !== 'undefined' && typeof _hasOwnProperty.call !== 'undefined') {
+ hasOwnProperty = function (object, property) {
+ return _hasOwnProperty.call(object, property);
+ };
+ }
+ else {
+ hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
+ return ((property in object) && typeof object.constructor.prototype[property] === 'undefined');
+ };
+ }
+
+ /**
+ * set_css applies given styles to the Modernizr DOM node.
+ */
+ function set_css( str ) {
+ m_style.cssText = str;
+ }
+
+ /**
+ * set_css_all extrapolates all vendor-specific css strings.
+ */
+ function set_css_all( str1, str2 ) {
+ return set_css(prefixes.join(str1 + ';') + ( str2 || '' ));
+ }
+
+ /**
+ * contains returns a boolean for if substr is found within str.
+ */
+ function contains( str, substr ) {
+ return (''+str).indexOf( substr ) !== -1;
+ }
+
+ /**
+ * test_props is a generic CSS / DOM property test; if a browser supports
+ * a certain property, it won't return undefined for it.
+ * A supported CSS property returns empty string when its not yet set.
+ */
+ function test_props( props, callback ) {
+ for ( var i in props ) {
+ if ( m_style[ props[i] ] !== undefined && ( !callback || callback( props[i], m ) ) ) {
+ return true;
+ }
+ }
+ }
+
+ /**
+ * test_props_all tests a list of DOM properties we want to check against.
+ * We specify literally ALL possible (known and/or likely) properties on
+ * the element including the non-vendor prefixed one, for forward-
+ * compatibility.
+ */
+ function test_props_all( prop, callback ) {
+
+ var uc_prop = prop.charAt(0).toUpperCase() + prop.substr(1),
+ props = (prop + ' ' + domPrefixes.join(uc_prop + ' ') + uc_prop).split(' ');
+
+ return !!test_props( props, callback );
+ }
+
+
+ /**
+ * Tests
+ */
+
+ tests['flexbox'] = function() {
+ /**
+ * set_prefixed_value_css sets the property of a specified element
+ * adding vendor prefixes to the VALUE of the property.
+ * @param {Element} element
+ * @param {string} property The property name. This will not be prefixed.
+ * @param {string} value The value of the property. This WILL be prefixed.
+ * @param {string=} extra Additional CSS to append unmodified to the end of
+ * the CSS string.
+ */
+ function set_prefixed_value_css(element, property, value, extra) {
+ property += ':';
+ element.style.cssText = (property + prefixes.join(value + ';' + property)).slice(0, -property.length) + (extra || '');
+ }
+
+ /**
+ * set_prefixed_property_css sets the property of a specified element
+ * adding vendor prefixes to the NAME of the property.
+ * @param {Element} element
+ * @param {string} property The property name. This WILL be prefixed.
+ * @param {string} value The value of the property. This will not be prefixed.
+ * @param {string=} extra Additional CSS to append unmodified to the end of
+ * the CSS string.
+ */
+ function set_prefixed_property_css(element, property, value, extra) {
+ element.style.cssText = prefixes.join(property + ':' + value + ';') + (extra || '');
+ }
+
+ var c = doc.createElement('div'),
+ elem = doc.createElement('div');
+
+ set_prefixed_value_css(c, 'display', 'box', 'width:42px;padding:0;');
+ set_prefixed_property_css(elem, 'box-flex', '1', 'width:10px;');
+
+ c.appendChild(elem);
+ docElement.appendChild(c);
+
+ var ret = elem.offsetWidth === 42;
+
+ c.removeChild(elem);
+ docElement.removeChild(c);
+
+ return ret;
+ };
+
+ // On the S60 and BB Storm, getContext exists, but always returns undefined
+ // http://github.com/Modernizr/Modernizr/issues/issue/97/
+
+ tests['canvas'] = function() {
+ var elem = doc.createElement( 'canvas' );
+ return !!(elem.getContext && elem.getContext('2d'));
+ };
+
+ tests['canvastext'] = function() {
+ return !!(ret['canvas'] && typeof doc.createElement( 'canvas' ).getContext('2d').fillText == 'function');
+ };
+
+
+ tests['webgl'] = function(){
+
+ var elem = doc.createElement( 'canvas' );
+
+ try {
+ if (elem.getContext('webgl')){ return true; }
+ } catch(e){ }
+
+ try {
+ if (elem.getContext('experimental-webgl')){ return true; }
+ } catch(e){ }
+
+ return false;
+ };
+
+ /*
+ * The Modernizr.touch test only indicates if the browser supports
+ * touch events, which does not necessarily reflect a touchscreen
+ * device, as evidenced by tablets running Windows 7 or, alas,
+ * the Palm Pre / WebOS (touch) phones.
+ *
+ * Additionally, Chrome (desktop) used to lie about its support on this,
+ * but that has since been rectified: http://crbug.com/36415
+ *
+ * We also test for Firefox 4 Multitouch Support.
+ *
+ * For more info, see: http://modernizr.github.com/Modernizr/touch.html
+ */
+
+ tests['touch'] = function() {
+
+ return ('ontouchstart' in window) || testMediaQuery('@media ('+prefixes.join('touch-enabled),(')+'modernizr)');
+
+ };
+
+
+ /**
+ * geolocation tests for the new Geolocation API specification.
+ * This test is a standards compliant-only test; for more complete
+ * testing, including a Google Gears fallback, please see:
+ * http://code.google.com/p/geo-location-javascript/
+ * or view a fallback solution using google's geo API:
+ * http://gist.github.com/366184
+ */
+ tests['geolocation'] = function() {
+ return !!navigator.geolocation;
+ };
+
+ // Per 1.6:
+ // This used to be Modernizr.crosswindowmessaging but the longer
+ // name has been deprecated in favor of a shorter and property-matching one.
+ // The old API is still available in 1.6, but as of 2.0 will throw a warning,
+ // and in the first release thereafter disappear entirely.
+ tests['postmessage'] = function() {
+ return !!window.postMessage;
+ };
+
+ // Web SQL database detection is tricky:
+
+ // In chrome incognito mode, openDatabase is truthy, but using it will
+ // throw an exception: http://crbug.com/42380
+ // We can create a dummy database, but there is no way to delete it afterwards.
+
+ // Meanwhile, Safari users can get prompted on any database creation.
+ // If they do, any page with Modernizr will give them a prompt:
+ // http://github.com/Modernizr/Modernizr/issues/closed#issue/113
+
+ // We have chosen to allow the Chrome incognito false positive, so that Modernizr
+ // doesn't litter the web with these test databases. As a developer, you'll have
+ // to account for this gotcha yourself.
+ tests['websqldatabase'] = function() {
+ var result = !!window.openDatabase;
+ /*
+ if (result){
+ try {
+ result = !!openDatabase( mod + "testdb", "1.0", mod + "testdb", 2e4);
+ } catch(e) {
+ }
+ }
+ */
+ return result;
+ };
+
+ // Vendors have inconsistent prefixing with the experimental Indexed DB:
+ // - Firefox is shipping indexedDB in FF4 as moz_indexedDB
+ // - Webkit's implementation is accessible through webkitIndexedDB
+ // We test both styles.
+ tests['indexedDB'] = function(){
+ for (var i = -1, len = domPrefixes.length; ++i < len; ){
+ var prefix = domPrefixes[i].toLowerCase();
+ if (window[prefix + '_indexedDB'] || window[prefix + 'IndexedDB']){
+ return true;
+ }
+ }
+ return false;
+ };
+
+ // documentMode logic from YUI to filter out IE8 Compat Mode
+ // which false positives.
+ tests['hashchange'] = function() {
+ return isEventSupported('hashchange', window) && ( document.documentMode === undefined || document.documentMode > 7 );
+ };
+
+ // Per 1.6:
+ // This used to be Modernizr.historymanagement but the longer
+ // name has been deprecated in favor of a shorter and property-matching one.
+ // The old API is still available in 1.6, but as of 2.0 will throw a warning,
+ // and in the first release thereafter disappear entirely.
+ tests['history'] = function() {
+ return !!(window.history && history.pushState);
+ };
+
+ tests['draganddrop'] = function() {
+ return isEventSupported('drag') &&
+ isEventSupported('dragstart') &&
+ isEventSupported('dragenter') &&
+ isEventSupported('dragover') &&
+ isEventSupported('dragleave') &&
+ isEventSupported('dragend') &&
+ isEventSupported('drop');
+ };
+
+ tests['websockets'] = function(){
+ return ('WebSocket' in window);
+ };
+
+
+ // http://css-tricks.com/rgba-browser-support/
+ tests['rgba'] = function() {
+ // Set an rgba() color and check the returned value
+
+ set_css( 'background-color:rgba(150,255,150,.5)' );
+
+ return contains( m_style.backgroundColor, 'rgba' );
+ };
+
+ tests['hsla'] = function() {
+ // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
+ // except IE9 who retains it as hsla
+
+ set_css('background-color:hsla(120,40%,100%,.5)' );
+
+ return contains( m_style.backgroundColor, 'rgba' ) || contains( m_style.backgroundColor, 'hsla' );
+ };
+
+ tests['multiplebgs'] = function() {
+ // Setting multiple images AND a color on the background shorthand property
+ // and then querying the style.background property value for the number of
+ // occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
+
+ set_css( 'background:url(//:),url(//:),red url(//:)' );
+
+ // If the UA supports multiple backgrounds, there should be three occurrences
+ // of the string "url(" in the return value for elem_style.background
+
+ return new RegExp("(url\\s*\\(.*?){3}").test(m_style.background);
+ };
+
+
+ // In testing support for a given CSS property, it's legit to test:
+ // elem.style[styleName] !== undefined
+ // If the property is supported it will return an empty string,
+ // if unsupported it will return undefined.
+ // We'll take advantage of this quick test and skip setting a style
+ // on our modernizr element, but instead just testing undefined vs
+ // empty string.
+ // The legacy set_css_all calls will remain in the source
+ // (however, commented) for clarity, yet functionally they are
+ // no longer needed.
+
+
+ tests['backgroundsize'] = function() {
+ return test_props_all( 'backgroundSize' );
+ };
+
+ tests['borderimage'] = function() {
+ // set_css_all( 'border-image:url(m.png) 1 1 stretch' );
+ return test_props_all( 'borderImage' );
+ };
+
+
+ // Super comprehensive table about all the unique implementations of
+ // border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance
+
+ tests['borderradius'] = function() {
+ // set_css_all( 'border-radius:10px' );
+ return test_props_all( 'borderRadius', '', function( prop ) {
+ return contains( prop, 'orderRadius' );
+ });
+ };
+
+
+ tests['boxshadow'] = function() {
+ // set_css_all( 'box-shadow:#000 1px 1px 3px' );
+ return test_props_all( 'boxShadow' );
+ };
+
+ // Note: FF3.0 will false positive on this test
+ tests['textshadow'] = function(){
+ return doc.createElement('div').style.textShadow === '';
+ };
+
+
+ tests['opacity'] = function() {
+ // Browsers that actually have CSS Opacity implemented have done so
+ // according to spec, which means their return values are within the
+ // range of [0.0,1.0] - including the leading zero.
+
+ set_css_all( 'opacity:.5' );
+
+ return contains( m_style.opacity, '0.5' );
+ };
+
+
+ tests['cssanimations'] = function() {
+ // set_css_all( 'animation:"animate" 2s ease 2', 'position:relative' );
+ return test_props_all( 'animationName' );
+ };
+
+
+ tests['csscolumns'] = function() {
+ // set_css_all( 'column-count:3' );
+ return test_props_all( 'columnCount' );
+ };
+
+
+ tests['cssgradients'] = function() {
+ /**
+ * For CSS Gradients syntax, please see:
+ * http://webkit.org/blog/175/introducing-css-gradients/
+ * https://developer.mozilla.org/en/CSS/-moz-linear-gradient
+ * https://developer.mozilla.org/en/CSS/-moz-radial-gradient
+ * http://dev.w3.org/csswg/css3-images/#gradients-
+ */
+
+ var str1 = 'background-image:',
+ str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
+ str3 = 'linear-gradient(left top,#9f9, white);';
+
+ set_css(
+ (str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0,-str1.length)
+ );
+
+ return contains( m_style.backgroundImage, 'gradient' );
+ };
+
+
+ tests['cssreflections'] = function() {
+ // set_css_all( 'box-reflect:right 1px' );
+ return test_props_all( 'boxReflect' );
+ };
+
+
+ tests['csstransforms'] = function() {
+ // set_css_all( 'transform:rotate(3deg)' );
+ return !!test_props([ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ]);
+ };
+
+
+ tests['csstransforms3d'] = function() {
+ // set_css_all( 'perspective:500' );
+
+ var ret = !!test_props([ 'perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective' ]);
+
+ // Webkit’s 3D transforms are passed off to the browser's own graphics renderer.
+ // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome (yet?).
+ // As a result, Webkit typically recognizes the syntax but will sometimes throw a false
+ // positive, thus we must do a more thorough check:
+ if (ret){
+
+ // Webkit allows this media query to succeed only if the feature is enabled.
+ // "@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }"
+ ret = testMediaQuery('@media ('+prefixes.join('transform-3d),(')+'modernizr)');
+ }
+ return ret;
+ };
+
+
+ tests['csstransitions'] = function() {
+ // set_css_all( 'transition:all .5s linear' );
+ return test_props_all( 'transitionProperty' );
+ };
+
+
+ // @font-face detection routine by Diego Perini
+ // http://javascript.nwbox.com/CSSSupport/
+ tests['fontface'] = function(){
+
+ var
+ sheet,
+ head = doc.head || doc.getElementsByTagName('head')[0] || docElement,
+ style = doc.createElement("style"),
+ impl = doc.implementation || { hasFeature: function() { return false; } };
+
+ style.type = 'text/css';
+ head.insertBefore(style, head.firstChild);
+ sheet = style.sheet || style.styleSheet;
+
+ // removing it crashes IE browsers
+ //head.removeChild(style);
+
+ var supportAtRule = impl.hasFeature('CSS2', '') ?
+ function(rule) {
+ if (!(sheet && rule)) return false;
+ var result = false;
+ try {
+ sheet.insertRule(rule, 0);
+ result = !(/unknown/i).test(sheet.cssRules[0].cssText);
+ sheet.deleteRule(sheet.cssRules.length - 1);
+ } catch(e) { }
+ return result;
+ } :
+ function(rule) {
+ if (!(sheet && rule)) return false;
+ sheet.cssText = rule;
+
+ return sheet.cssText.length !== 0 && !(/unknown/i).test(sheet.cssText) &&
+ sheet.cssText
+ .replace(/\r+|\n+/g, '')
+ .indexOf(rule.split(' ')[0]) === 0;
+ };
+
+
+ // DEPRECATED - allow for a callback
+ ret._fontfaceready = function(fn){
+ fn(ret.fontface);
+ };
+
+ return supportAtRule('@font-face { font-family: "font"; src: "font.ttf"; }');
+
+ };
+
+
+ // These tests evaluate support of the video/audio elements, as well as
+ // testing what types of content they support.
+ //
+ // We're using the Boolean constructor here, so that we can extend the value
+ // e.g. Modernizr.video // true
+ // Modernizr.video.ogg // 'probably'
+ //
+ // Codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
+ // thx to NielsLeenheer and zcorpan
+
+ // Note: in FF 3.5.1 and 3.5.0, "no" was a return value instead of empty string.
+ // Modernizr does not normalize for that.
+
+ tests['video'] = function() {
+ var elem = doc.createElement('video'),
+ bool = !!elem.canPlayType;
+
+ if (bool){
+ bool = new Boolean(bool);
+ bool.ogg = elem.canPlayType('video/ogg; codecs="theora"');
+
+ // Workaround required for IE9, which doesn't report video support without audio codec specified.
+ // bug 599718 @ msft connect
+ var h264 = 'video/mp4; codecs="avc1.42E01E';
+ bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
+
+ bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
+ }
+ return bool;
+ };
+
+ tests['audio'] = function() {
+ var elem = doc.createElement('audio'),
+ bool = !!elem.canPlayType;
+
+ if (bool){
+ bool = new Boolean(bool);
+ bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"');
+ bool.mp3 = elem.canPlayType('audio/mpeg;');
+
+ // Mimetypes accepted:
+ // https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
+ // http://bit.ly/iphoneoscodecs
+ bool.wav = elem.canPlayType('audio/wav; codecs="1"');
+ bool.m4a = elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;');
+ }
+ return bool;
+ };
+
+
+ // Both localStorage and sessionStorage are
+ // tested via the `in` operator because otherwise Firefox will
+ // throw an error: https://bugzilla.mozilla.org/show_bug.cgi?id=365772
+ // if cookies are disabled
+
+ // They require try/catch because of possible firefox configuration:
+ // http://github.com/Modernizr/Modernizr/issues#issue/92
+
+ // FWIW miller device resolves to [object Storage] in all supporting browsers
+ // except for IE who does [object Object]
+
+ // IE8 Compat mode supports these features completely:
+ // http://www.quirksmode.org/dom/html5.html
+
+ tests['localstorage'] = function() {
+ try {
+ return ('localStorage' in window) && window.localStorage !== null;
+ } catch(e) {
+ return false;
+ }
+ };
+
+ tests['sessionstorage'] = function() {
+ try {
+ return ('sessionStorage' in window) && window.sessionStorage !== null;
+ } catch(e){
+ return false;
+ }
+ };
+
+
+ tests['webWorkers'] = function () {
+ return !!window.Worker;
+ };
+
+
+ tests['applicationcache'] = function() {
+ return !!window.applicationCache;
+ };
+
+
+ // Thanks to Erik Dahlstrom
+ tests['svg'] = function(){
+ return !!doc.createElementNS && !!doc.createElementNS(ns.svg, "svg").createSVGRect;
+ };
+
+ tests['inlinesvg'] = function() {
+ var div = document.createElement('div');
+ div.innerHTML = '<svg/>';
+ return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
+ };
+
+ // Thanks to F1lt3r and lucideer
+ // http://github.com/Modernizr/Modernizr/issues#issue/35
+ tests['smil'] = function(){
+ return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS(ns.svg,'animate')));
+ };
+
+ tests['svgclippaths'] = function(){
+ // Possibly returns a false positive in Safari 3.2?
+ return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS(ns.svg,'clipPath')));
+ };
+
+
+ // input features and input types go directly onto the ret object, bypassing the tests loop.
+ // Hold this guy to execute in a moment.
+ function webforms(){
+
+ // Run through HTML5's new input attributes to see if the UA understands any.
+ // We're using f which is the <input> element created early on
+ // Mike Taylr has created a comprehensive resource for testing these attributes
+ // when applied to all input types:
+ // http://miketaylr.com/code/input-type-attr.html
+ // spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
+ ret['input'] = (function(props) {
+ for (var i = 0,len=props.length;i<len;i++) {
+ attrs[ props[i] ] = !!(props[i] in f);
+ }
+ return attrs;
+ })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
+
+ // Run through HTML5's new input types to see if the UA understands any.
+ // This is put behind the tests runloop because it doesn't return a
+ // true/false like all the other tests; instead, it returns an object
+ // containing each input type with its corresponding true/false value
+
+ // Big thanks to @miketaylr for the html5 forms expertise. http://miketaylr.com/
+ ret['inputtypes'] = (function(props) {
+ for (var i = 0, bool, len=props.length ; i < len ; i++) {
+
+ f.setAttribute('type', props[i]);
+ bool = f.type !== 'text';
+
+ // Chrome likes to falsely purport support, so we feed it a textual value;
+ // if that doesnt succeed then we know there's a custom UI
+ if (bool){
+
+ f.value = smile;
+
+ if (/^range$/.test(f.type) && f.style.WebkitAppearance !== undefined){
+
+ docElement.appendChild(f);
+ var defaultView = doc.defaultView;
+
+ // Safari 2-4 allows the smiley as a value, despite making a slider
+ bool = defaultView.getComputedStyle &&
+ defaultView.getComputedStyle(f, null).WebkitAppearance !== 'textfield' &&
+
+ // Mobile android web browser has false positive, so must
+ // check the height to see if the widget is actually there.
+ (f.offsetHeight !== 0);
+
+ docElement.removeChild(f);
+
+ } else if (/^(search|tel)$/.test(f.type)){
+ // Spec doesnt define any special parsing or detectable UI
+ // behaviors so we pass these through as true
+
+ // Interestingly, opera fails the earlier test, so it doesn't
+ // even make it here.
+
+ } else if (/^(url|email)$/.test(f.type)) {
+
+ // Real url and email support comes with prebaked validation.
+ bool = f.checkValidity && f.checkValidity() === false;
+
+ } else {
+ // If the upgraded input compontent rejects the :) text, we got a winner
+ bool = f.value != smile;
+ }
+ }
+
+ inputs[ props[i] ] = !!bool;
+ }
+ return inputs;
+ })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
+
+ }
+
+
+
+ // End of test definitions
+
+
+
+ // Run through all tests and detect their support in the current UA.
+ // todo: hypothetically we could be doing an array of tests and use a basic loop here.
+ for ( var feature in tests ) {
+ if ( hasOwnProperty( tests, feature ) ) {
+ // run the test, throw the return value into the Modernizr,
+ // then based on that boolean, define an appropriate className
+ // and push it into an array of classes we'll join later.
+ featurename = feature.toLowerCase();
+ ret[ featurename ] = tests[ feature ]();
+
+ classes.push( ( ret[ featurename ] ? '' : 'no-' ) + featurename );
+ }
+ }
+
+ // input tests need to run.
+ if (!ret.input) webforms();
+
+
+
+ // Per 1.6: deprecated API is still accesible for now:
+ ret.crosswindowmessaging = ret.postmessage;
+ ret.historymanagement = ret.history;
+
+
+
+ /**
+ * Addtest allows the user to define their own feature tests
+ * the result will be added onto the Modernizr object,
+ * as well as an appropriate className set on the html element
+ *
+ * @param feature - String naming the feature
+ * @param test - Function returning true if feature is supported, false if not
+ */
+ ret.addTest = function (feature, test) {
+ feature = feature.toLowerCase();
+
+ if (ret[ feature ]) {
+ return; // quit if you're trying to overwrite an existing test
+ }
+ test = !!(test());
+ docElement.className += ' ' + (test ? '' : 'no-') + feature;
+ ret[ feature ] = test;
+ return ret; // allow chaining.
+ };
+
+ /**
+ * Reset m.style.cssText to nothing to reduce memory footprint.
+ */
+ set_css( '' );
+ m = f = null;
+
+ // Enable HTML 5 elements for styling in IE.
+ // fyi: jscript version does not reflect trident version
+ // therefore ie9 in ie7 mode will still have a jScript v.9
+ if ( enableHTML5 && window.attachEvent && (function(){ var elem = doc.createElement("div");
+ elem.innerHTML = "<elem></elem>";
+ return elem.childNodes.length !== 1; })()) {
+ // iepp v1.6 by @jon_neal : code.google.com/p/ie-print-protector
+ (function(f,l){var j="abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",n=j.split("|"),k=n.length,g=new RegExp("<(/*)("+j+")","gi"),h=new RegExp("\\b("+j+")\\b(?!.*[;}])","gi"),m=l.createDocumentFragment(),d=l.documentElement,i=d.firstChild,b=l.createElement("style"),e=l.createElement("body");b.media="all";function c(p){var o=-1;while(++o<k){p.createElement(n[o])}}c(l);c(m);function a(t,s){var r=t.length,q=-1,o,p=[];while(++q<r){o=t[q];s=o.media||s;p.push(a(o.imports,s));p.push(o.cssText)}return p.join("")}f.attachEvent("onbeforeprint",function(){var r=-1;while(++r<k){var o=l.getElementsByTagName(n[r]),q=o.length,p=-1;while(++p<q){if(o[p].className.indexOf("iepp_")<0){o[p].className+=" iepp_"+n[r]}}}i.insertBefore(b,i.firstChild);b.styleSheet.cssText=a(l.styleSheets,"all").replace(h,".iepp_$1");m.appendChild(l.body);d.appendChild(e);e.innerHTML=m.firstChild.innerHTML.replace(g,"<$1bdo")});f.attachEvent("onafterprint",function(){e.innerHTML="";d.removeChild(e);i.removeChild(b);d.appendChild(m.firstChild)})})(this,document);
+ }
+
+ // Assign private properties to the return object with prefix
+ ret._enableHTML5 = enableHTML5;
+ ret._version = version;
+
+ // Remove "no-js" class from <html> element, if it exists:
+ docElement.className=docElement.className.replace(/\bno-js\b/,'') + ' js';
+
+ // Add the new classes to the <html> element.
+ docElement.className += ' ' + classes.join( ' ' );
+
+ return ret;
+
+})(this,this.document);
View
1,028 docs/public/js/profiling/yahoo-profiling.js
@@ -0,0 +1,1028 @@
+/*
+Copyright (c) 2009, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.7.0
+*/
+/**
+ * The YAHOO object is the single global object used by YUI Library. It
+ * contains utility function for setting up namespaces, inheritance, and
+ * logging. YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces
+ * created automatically for and used by the library.
+ * @module yahoo
+ * @title YAHOO Global
+ */
+
+/**
+ * YAHOO_config is not included as part of the library. Instead it is an
+ * object that can be defined by the implementer immediately before
+ * including the YUI library. The properties included in this object
+ * will be used to configure global properties needed as soon as the
+ * library begins to load.
+ * @class YAHOO_config
+ * @static
+ */
+
+/**
+ * A reference to a function that will be executed every time a YAHOO module
+ * is loaded. As parameter, this function will receive the version
+ * information for the module. See <a href="YAHOO.env.html#getVersion">
+ * YAHOO.env.getVersion</a> for the description of the version data structure.
+ * @property listener
+ * @type Function
+ * @static
+ * @default undefined
+ */
+
+/**
+ * Set to true if the library will be dynamically loaded after window.onload.
+ * Defaults to false
+ * @property injecting
+ * @type boolean
+ * @static
+ * @default undefined
+ */
+
+/**
+ * Instructs the yuiloader component to dynamically load yui components and
+ * their dependencies. See the yuiloader documentation for more information
+ * about dynamic loading
+ * @property load
+ * @static
+ * @default undefined
+ * @see yuiloader
+ */
+
+/**
+ * Forces the use of the supplied locale where applicable in the library
+ * @property locale
+ * @type string
+ * @static
+ * @default undefined
+ */
+
+if (typeof YAHOO == "undefined" || !YAHOO) {
+ /**
+ * The YAHOO global namespace object. If YAHOO is already defined, the
+ * existing YAHOO object will not be overwritten so that defined
+ * namespaces are preserved.
+ * @class YAHOO
+ * @static
+ */
+ var YAHOO = {};
+}
+
+/**
+ * Returns the namespace specified and creates it if it doesn't exist
+ * <pre>
+ * YAHOO.namespace("property.package");
+ * YAHOO.namespace("YAHOO.property.package");
+ * </pre>
+ * Either of the above would create YAHOO.property, then
+ * YAHOO.property.package
+ *
+ * Be careful when naming packages. Reserved words may work in some browsers
+ * and not others. For instance, the following will fail in Safari:
+ * <pre>
+ * YAHOO.namespace("really.long.nested.namespace");
+ * </pre>
+ * This fails because "long" is a future reserved word in ECMAScript
+ *
+ * For implementation code that uses YUI, do not create your components
+ * in the namespaces created by the library. defined by YUI -- create
+ * your own (YAHOO.util, YAHOO.widget, YAHOO.lang, YAHOO.env)
+ *
+ * @method namespace
+ * @static
+ * @param {String*} arguments 1-n namespaces to create
+ * @return {Object} A reference to the last namespace object created
+ */
+YAHOO.namespace = function() {
+ var a=arguments, o=null, i, j, d;
+ for (i=0; i<a.length; i=i+1) {
+ d=(""+a[i]).split(".");
+ o=YAHOO;
+
+ // YAHOO is implied, so it is ignored if it is included
+ for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {
+ o[d[j]]=o[d[j]] || {};
+ o=o[d[j]];
+ }
+ }
+
+ return o;
+};
+
+/**
+ * Uses YAHOO.widget.Logger to output a log message, if the widget is
+ * available.
+ *
+ * @method log
+ * @static
+ * @param {String} msg The message to log.
+ * @param {String} cat The log category for the message. Default
+ * categories are "info", "warn", "error", time".
+ * Custom categories can be used as well. (opt)
+ * @param {String} src The source of the the message (opt)
+ * @return {Boolean} True if the log operation was successful.
+ */
+YAHOO.log = function(msg, cat, src) {
+ var l=YAHOO.widget.Logger;
+ if(l && l.log) {
+ return l.log(msg, cat, src);
+ } else {
+ return false;
+ }
+};
+
+/**
+ * Registers a module with the YAHOO object
+ * @method register
+ * @static
+ * @param {String} name the name of the module (event, slider, etc)
+ * @param {Function} mainClass a reference to class in the module. This
+ * class will be tagged with the version info
+ * so that it will be possible to identify the
+ * version that is in use when multiple versions
+ * have loaded
+ * @param {Object} data metadata object for the module. Currently it
+ * is expected to contain a "version" property
+ * and a "build" property at minimum.
+ */
+YAHOO.register = function(name, mainClass, data) {
+ var mods = YAHOO.env.modules, m, v, b, ls, i;
+
+ if (!mods[name]) {
+ mods[name] = {
+ versions:[],
+ builds:[]
+ };
+ }
+
+ m = mods[name];
+ v = data.version;
+ b = data.build;
+ ls = YAHOO.env.listeners;
+
+ m.name = name;
+ m.version = v;
+ m.build = b;
+ m.versions.push(v);
+ m.builds.push(b);
+ m.mainClass = mainClass;
+
+ // fire the module load listeners
+ for (i=0;i<ls.length;i=i+1) {
+ ls[i](m);
+ }
+ // label the main class
+ if (mainClass) {
+ mainClass.VERSION = v;
+ mainClass.BUILD = b;
+ } else {
+ YAHOO.log("mainClass is undefined for module " + name, "warn");
+ }
+};
+
+/**
+ * YAHOO.env is used to keep track of what is known about the YUI library and
+ * the browsing environment
+ * @class YAHOO.env
+ * @static
+ */
+YAHOO.env = YAHOO.env || {
+
+ /**
+ * Keeps the version info for all YUI modules that have reported themselves
+ * @property modules
+ * @type Object[]
+ */
+ modules: [],
+
+ /**
+ * List of functions that should be executed every time a YUI module
+ * reports itself.
+ * @property listeners
+ * @type Function[]
+ */
+ listeners: []
+};
+
+/**
+ * Returns the version data for the specified module:
+ * <dl>
+ * <dt>name:</dt> <dd>The name of the module</dd>
+ * <dt>version:</dt> <dd>The version in use</dd>
+ * <dt>build:</dt> <dd>The build number in use</dd>
+ * <dt>versions:</dt> <dd>All versions that were registered</dd>
+ * <dt>builds:</dt> <dd>All builds that were registered.</dd>
+ * <dt>mainClass:</dt> <dd>An object that was was stamped with the
+ * current version and build. If
+ * mainClass.VERSION != version or mainClass.BUILD != build,
+ * multiple versions of pieces of the library have been
+ * loaded, potentially causing issues.</dd>
+ * </dl>
+ *
+ * @method getVersion
+ * @static
+ * @param {String} name the name of the module (event, slider, etc)
+ * @return {Object} The version info
+ */
+YAHOO.env.getVersion = function(name) {
+ return YAHOO.env.modules[name] || null;
+};
+
+/**
+ * Do not fork for a browser if it can be avoided. Use feature detection when
+ * you can. Use the user agent as a last resort. YAHOO.env.ua stores a version
+ * number for the browser engine, 0 otherwise. This value may or may not map
+ * to the version number of the browser using the engine. The value is
+ * presented as a float so that it can easily be used for boolean evaluation
+ * as well as for looking for a particular range of versions. Because of this,
+ * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9
+ * reports 1.8).
+ * @class YAHOO.env.ua
+ * @static
+ */
+YAHOO.env.ua = function() {
+ var o={
+
+ /**
+ * Internet Explorer version number or 0. Example: 6
+ * @property ie
+ * @type float
+ */
+ ie:0,
+
+ /**
+ * Opera version number or 0. Example: 9.2
+ * @property opera
+ * @type float
+ */
+ opera:0,
+
+ /**
+ * Gecko engine revision number. Will evaluate to 1 if Gecko
+ * is detected but the revision could not be found. Other browsers
+ * will be 0. Example: 1.8
+ * <pre>
+ * Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7
+ * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8
+ * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8
+ * Firefox 3 alpha: 1.9a4 <-- Reports 1.9
+ * </pre>
+ * @property gecko
+ * @type float
+ */
+ gecko:0,
+
+ /**
+ * AppleWebKit version. KHTML browsers that are not WebKit browsers
+ * will evaluate to 1, other browsers 0. Example: 418.9.1
+ * <pre>
+ * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
+ * latest available for Mac OSX 10.3.
+ * Safari 2.0.2: 416 <-- hasOwnProperty introduced
+ * Safari 2.0.4: 418 <-- preventDefault fixed
+ * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
+ * different versions of webkit
+ * Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been
+ * updated, but not updated
+ * to the latest patch.
+ * Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native SVG
+ * and many major issues fixed).
+ * 3.x yahoo.com, flickr:422 <-- Safari 3.x hacks the user agent
+ * string when hitting yahoo.com and
+ * flickr.com.
+ * Safari 3.0.4 (523.12):523.12 <-- First Tiger release - automatic update
+ * from 2.x via the 10.4.11 OS patch
+ * Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event.
+ * yahoo.com user agent hack removed.
+ *
+ * </pre>
+ * http://developer.apple.com/internet/safari/uamatrix.html
+ * @property webkit
+ * @type float
+ */
+ webkit: 0,
+
+ /**
+ * The mobile property will be set to a string containing any relevant
+ * user agent information when a modern mobile browser is detected.
+ * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
+ * devices with the WebKit-based browser, and Opera Mini.
+ * @property mobile
+ * @type string
+ */
+ mobile: null,
+
+ /**
+ * Adobe AIR version number or 0. Only populated if webkit is detected.
+ * Example: 1.0
+ * @property air
+ * @type float
+ */
+ air: 0,
+
+ /**
+ * Google Caja version number or 0.
+ * @property caja
+ * @type float
+ */
+ caja: 0
+
+ },
+
+ ua = navigator.userAgent,
+
+ m;
+
+ // Modern KHTML browsers should qualify as Safari X-Grade
+ if ((/KHTML/).test(ua)) {
+ o.webkit=1;
+ }
+ // Modern WebKit browsers are at least X-Grade
+ m=ua.match(/AppleWebKit\/([^\s]*)/);
+ if (m&&m[1]) {
+ o.webkit=parseFloat(m[1]);
+
+ // Mobile browser check
+ if (/ Mobile\//.test(ua)) {
+ o.mobile = "Apple"; // iPhone or iPod Touch
+ } else {
+ m=ua.match(/NokiaN[^\/]*/);
+ if (m) {
+ o.mobile = m[0]; // Nokia N-series, ex: NokiaN95
+ }
+ }
+
+ m=ua.match(/AdobeAIR\/([^\s]*)/);
+ if (m) {
+ o.air = m[0]; // Adobe AIR 1.0 or better
+ }
+
+ }
+
+ if (!o.webkit) { // not webkit
+ // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
+ m=ua.match(/Opera[\s\/]([^\s]*)/);
+ if (m&&m[1]) {
+ o.opera=parseFloat(m[1]);
+ m=ua.match(/Opera Mini[^;]*/);
+ if (m) {
+ o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
+ }
+ } else { // not opera or webkit
+ m=ua.match(/MSIE\s([^;]*)/);
+ if (m&&m[1]) {
+ o.ie=parseFloat(m[1]);
+ } else { // not opera, webkit, or ie
+ m=ua.match(/Gecko\/([^\s]*)/);
+ if (m) {
+ o.gecko=1; // Gecko detected, look for revision
+ m=ua.match(/rv:([^\s\)]*)/);
+ if (m&&m[1]) {
+ o.gecko=parseFloat(m[1]);
+ }
+ }
+ }
+ }
+ }
+
+ m=ua.match(/Caja\/([^\s]*)/);
+ if (m&&m[1]) {
+ o.caja=parseFloat(m[1]);
+ }
+
+ return o;
+}();
+
+/*
+ * Initializes the global by creating the default namespaces and applying
+ * any new configuration information that is detected. This is the setup
+ * for env.
+ * @method init
+ * @static
+ * @private
+ */
+(function() {
+ YAHOO.namespace("util", "widget", "example");
+ /*global YAHOO_config*/
+ if ("undefined" !== typeof YAHOO_config) {
+ var l=YAHOO_config.listener,ls=YAHOO.env.listeners,unique=true,i;
+ if (l) {
+ // if YAHOO is loaded multiple times we need to check to see if
+ // this is a new config object. If it is, add the new component
+ // load listener to the stack
+ for (i=0;i<ls.length;i=i+1) {
+ if (ls[i]==l) {
+ unique=false;
+ break;
+ }
+ }
+ if (unique) {
+ ls.push(l);
+ }
+ }
+ }
+})();
+/**
+ * Provides the language utilites and extensions used by the library
+ * @class YAHOO.lang
+ */
+YAHOO.lang = YAHOO.lang || {};
+
+(function() {
+
+
+var L = YAHOO.lang,
+
+ ARRAY_TOSTRING = '[object Array]',
+ FUNCTION_TOSTRING = '[object Function]',
+ OP = Object.prototype,
+
+ // ADD = ["toString", "valueOf", "hasOwnProperty"],
+ ADD = ["toString", "valueOf"],
+
+ OB = {
+
+ /**
+ * Determines wheather or not the provided object is an array.
+ * @method isArray
+ * @param {any} o The object being testing
+ * @return {boolean} the result
+ */
+ isArray: function(o) {
+ return OP.toString.apply(o) === ARRAY_TOSTRING;
+ },
+
+ /**
+ * Determines whether or not the provided object is a boolean
+ * @method isBoolean
+ * @param {any} o The object being testing
+ * @return {boolean} the result
+ */
+ isBoolean: function(o) {
+ return typeof o === 'boolean';
+ },
+
+ /**
+ * Determines whether or not the provided object is a function.
+ * Note: Internet Explorer thinks certain functions are objects:
+ *
+ * var obj = document.createElement("object");
+ * YAHOO.lang.isFunction(obj.getAttribute) // reports false in IE
+ *
+ * var input = document.createElement("input"); // append to body
+ * YAHOO.lang.isFunction(input.focus) // reports false in IE
+ *
+ * You will have to implement additional tests if these functions
+ * matter to you.
+ *
+ * @method isFunction
+ * @param {any} o The object being testing
+ * @return {boolean} the result
+ */
+ isFunction: function(o) {
+ return OP.toString.apply(o) === FUNCTION_TOSTRING;
+ },
+
+ /**
+ * Determines whether or not the provided object is null
+ * @method isNull
+ * @param {any} o The object being testing
+ * @return {boolean} the result
+ */
+ isNull: function(o) {
+ return o === null;
+ },
+
+ /**
+ * Determines whether or not the provided object is a legal number
+ * @method isNumber
+ * @param {any} o The object being testing
+ * @return {boolean} the result
+ */
+ isNumber: function(o) {
+ return typeof o === 'number' && isFinite(o);
+ },
+
+ /**
+ * Determines whether or not the provided object is of type object
+ * or function
+ * @method isObject
+ * @param {any} o The object being testing
+ * @return {boolean} the result
+ */
+ isObject: function(o) {
+return (o && (typeof o === 'object' || L.isFunction(o))) || false;
+ },
+
+ /**
+ * Determines whether or not the provided object is a string
+ * @method isString
+ * @param {any} o The object being testing
+ * @return {boolean} the result
+ */
+ isString: function(o) {
+ return typeof o === 'string';
+ },
+
+ /**
+ * Determines whether or not the provided object is undefined
+ * @method isUndefined
+ * @param {any} o The object being testing
+ * @return {boolean} the result
+ */
+ isUndefined: function(o) {
+ return typeof o === 'undefined';
+ },
+
+
+ /**
+ * IE will not enumerate native functions in a derived object even if the
+ * function was overridden. This is a workaround for specific functions
+ * we care about on the Object prototype.
+ * @property _IEEnumFix
+ * @param {Function} r the object to receive the augmentation
+ * @param {Function} s the object that supplies the properties to augment
+ * @static
+ * @private
+ */
+ _IEEnumFix: (YAHOO.env.ua.ie) ? function(r, s) {
+ var i, fname, f;
+ for (i=0;i<ADD.length;i=i+1) {
+
+ fname = ADD[i];
+ f = s[fname];
+
+ if (L.isFunction(f) && f!=OP[fname]) {
+ r[fname]=f;
+ }
+ }
+ } : function(){},
+
+ /**
+ * Utility to set up the prototype, constructor and superclass properties to
+ * support an inheritance strategy that can chain constructors and methods.
+ * Static members will not be inherited.
+ *
+ * @method extend
+ * @static
+ * @param {Function} subc the object to modify
+ * @param {Function} superc the object to inherit
+ * @param {Object} overrides additional properties/methods to add to the
+ * subclass prototype. These will override the
+ * matching items obtained from the superclass
+ * if present.
+ */
+ extend: function(subc, superc, overrides) {
+ if (!superc||!subc) {
+ throw new Error("extend failed, please check that " +
+ "all dependencies are included.");
+ }
+ var F = function() {}, i;
+ F.prototype=superc.prototype;
+ subc.prototype=new F();
+ subc.prototype.constructor=subc;
+ subc.superclass=superc.prototype;
+ if (superc.prototype.constructor == OP.constructor) {
+ superc.prototype.constructor=superc;
+ }
+
+ if (overrides) {
+ for (i in overrides) {
+ if (L.hasOwnProperty(overrides, i)) {
+ subc.prototype[i]=overrides[i];
+ }
+ }
+
+ L._IEEnumFix(subc.prototype, overrides);
+ }
+ },
+
+ /**
+ * Applies all properties in the supplier to the receiver if the
+ * receiver does not have these properties yet. Optionally, one or
+ * more methods/properties can be specified (as additional
+ * parameters). This option will overwrite the property if receiver
+ * has it already. If true is passed as the third parameter, all
+ * properties will be applied and _will_ overwrite properties in
+ * the receiver.
+ *
+ * @method augmentObject
+ * @static
+ * @since 2.3.0
+ * @param {Function} r the object to receive the augmentation
+ * @param {Function} s the object that supplies the properties to augment
+ * @param {String*|boolean} arguments zero or more properties methods
+ * to augment the receiver with. If none specified, everything
+ * in the supplier will be used unless it would
+ * overwrite an existing property in the receiver. If true
+ * is specified as the third parameter, all properties will
+ * be applied and will overwrite an existing property in
+ * the receiver
+ */
+ augmentObject: function(r, s) {
+ if (!s||!r) {
+ throw new Error("Absorb failed, verify dependencies.");
+ }
+ var a=arguments, i, p, overrideList=a[2];
+ if (overrideList && overrideList!==true) { // only absorb the specified properties
+ for (i=2; i<a.length; i=i+1) {
+ r[a[i]] = s[a[i]];
+ }
+ } else { // take everything, overwriting only if the third parameter is true
+ for (p in s) {
+ if (overrideList || !(p in r)) {
+ r[p] = s[p];
+ }
+ }
+
+ L._IEEnumFix(r, s);
+ }
+ },
+
+ /**
+ * Same as YAHOO.lang.augmentObject, except it only applies prototype properties
+ * @see YAHOO.lang.augmentObject
+ * @method augmentProto
+ * @static
+ * @param {Function} r the object to receive the augmentation
+ * @param {Function} s the object that supplies the properties to augment
+ * @param {String*|boolean} arguments zero or more properties methods
+ * to augment the receiver with. If none specified, everything
+ * in the supplier will be used unless it would overwrite an existing
+ * property in the receiver. if true is specified as the third
+ * parameter, all properties will be applied and will overwrite an
+ * existing property in the receiver
+ */
+ augmentProto: function(r, s) {
+ if (!s||!r) {
+ throw new Error("Augment failed, verify dependencies.");
+ }
+ //var a=[].concat(arguments);
+ var a=[r.prototype,s.prototype], i;
+ for (i=2;i<arguments.length;i=i+1) {
+ a.push(arguments[i]);
+ }
+ L.augmentObject.apply(this, a);
+ },
+
+
+ /**
+ * Returns a simple string representation of the object or array.
+ * Other types of objects will be returned unprocessed. Arrays
+ * are expected to be indexed. Use object notation for
+ * associative arrays.
+ * @method dump
+ * @since 2.3.0
+ * @param o {Object} The object to dump
+ * @param d {int} How deep to recurse child objects, default 3
+ * @return {String} the dump result
+ */
+ dump: function(o, d) {
+ var i,len,s=[],OBJ="{...}",FUN="f(){...}",
+ COMMA=', ', ARROW=' => ';
+
+ // Cast non-objects to string
+ // Skip dates because the std toString is what we want
+ // Skip HTMLElement-like objects because trying to dump
+ // an element will cause an unhandled exception in FF 2.x
+ if (!L.isObject(o)) {
+ return o + "";
+ } else if (o instanceof Date || ("nodeType" in o && "tagName" in o)) {
+ return o;
+ } else if (L.isFunction(o)) {
+ return FUN;
+ }
+
+ // dig into child objects the depth specifed. Default 3
+ d = (L.isNumber(d)) ? d : 3;
+
+ // arrays [1, 2, 3]
+ if (L.isArray(o)) {
+ s.push("[");
+ for (i=0,len=o.length;i<len;i=i+1) {
+ if (L.isObject(o[i])) {
+ s.push((d > 0) ? L.dump(o[i], d-1) : OBJ);
+ } else {
+ s.push(o[i]);
+ }
+ s.push(COMMA);
+ }
+ if (s.length > 1) {
+ s.pop();
+ }
+ s.push("]");
+ // objects {k1 => v1, k2 => v2}
+ } else {
+ s.push("{");
+ for (i in o) {
+ if (L.hasOwnProperty(o, i)) {
+ s.push(i + ARROW);
+ if (L.isObject(o[i])) {
+ s.push((d > 0) ? L.dump(o[i], d-1) : OBJ);
+ } else {
+ s.push(o[i]);
+ }
+ s.push(COMMA);
+ }
+ }
+ if (s.length > 1) {
+ s.pop();
+ }
+ s.push("}");
+ }
+
+ return s.join("");
+ },
+
+ /**
+ * Does variable substitution on a string. It scans through the string
+ * looking for expressions enclosed in { } braces. If an expression
+ * is found, it is used a key on the object. If there is a space in
+ * the key, the first word is used for the key and the rest is provided
+ * to an optional function to be used to programatically determine the
+ * value (the extra information might be used for this decision). If
+ * the value for the key in the object, or what is returned from the
+ * function has a string value, number value, or object value, it is
+ * substituted for the bracket expression and it repeats. If this
+ * value is an object, it uses the Object's toString() if this has
+ * been overridden, otherwise it does a shallow dump of the key/value
+ * pairs.
+ * @method substitute
+ * @since 2.3.0
+ * @param s {String} The string that will be modified.
+ * @param o {Object} An object containing the replacement values
+ * @param f {Function} An optional function that can be used to
+ * process each match. It receives the key,
+ * value, and any extra metadata included with
+ * the key inside of the braces.
+ * @return {String} the substituted string
+ */
+ substitute: function (s, o, f) {
+ var i, j, k, key, v, meta, saved=[], token,
+ DUMP='dump', SPACE=' ', LBRACE='{', RBRACE='}',
+ dump;
+
+
+ for (;;) {
+ i = s.lastIndexOf(LBRACE);
+ if (i < 0) {
+ break;
+ }
+ j = s.indexOf(RBRACE, i);
+ if (i + 1 >= j) {
+ break;
+ }
+
+ //Extract key and meta info
+ token = s.substring(i + 1, j);
+ key = token;
+ meta = null;
+ k = key.indexOf(SPACE);
+ if (k > -1) {
+ meta = key.substring(k + 1);
+ key = key.substring(0, k);
+ }
+
+ // lookup the value
+ v = o[key];
+
+ // if a substitution function was provided, execute it
+ if (f) {
+ v = f(key, v, meta);
+ }
+
+ if (L.isObject(v)) {
+ if (L.isArray(v)) {
+ v = L.dump(v, parseInt(meta, 10));
+ } else {
+ meta = meta || "";
+
+ // look for the keyword 'dump', if found force obj dump
+ dump = meta.indexOf(DUMP);
+ if (dump > -1) {
+ meta = meta.substring(4);
+ }
+
+ // use the toString if it is not the Object toString
+ // and the 'dump' meta info was not found
+ if (v.toString===OP.toString || dump>-1) {
+ v = L.dump(v, parseInt(meta, 10));
+ } else {
+ v = v.toString();
+ }
+ }
+ } else if (!L.isString(v) && !L.isNumber(v)) {
+ // This {block} has no replace string. Save it for later.
+ v = "~-" + saved.length + "-~";
+ saved[saved.length] = token;
+
+ // break;
+ }
+
+ s = s.substring(0, i) + v + s.substring(j + 1);
+
+
+ }
+
+ // restore saved {block}s
+ for (i=saved.length-1; i>=0; i=i-1) {
+ s = s.replace(new RegExp("~-" + i + "-~"), "{" + saved[i] + "}", "g");
+ }
+
+ return s;
+ },
+
+
+ /**
+ * Returns a string without any leading or trailing whitespace. If
+ * the input is not a string, the input will be returned untouched.
+ * @method trim
+ * @since 2.3.0
+ * @param s {string} the string to trim
+ * @return {string} the trimmed string
+ */
+ trim: function(s){
+ try {
+ return s.replace(/^\s+|\s+$/g, "");
+ } catch(e) {
+ return s;
+ }
+ },
+
+ /**
+ * Returns a new object containing all of the properties of
+ * all the supplied objects. The properties from later objects
+ * will overwrite those in earlier objects.
+ * @method merge
+ * @since 2.3.0
+ * @param arguments {Object*} the objects to merge
+ * @return the new merged object
+ */
+ merge: function() {
+ var o={}, a=arguments, l=a.length, i;
+ for (i=0; i<l; i=i+1) {
+ L.augmentObject(o, a[i], true);
+ }
+ return o;
+ },
+
+ /**
+ * Executes the supplied function in the context of the supplied
+ * object 'when' milliseconds later. Executes the function a
+ * single time unless periodic is set to true.
+ * @method later
+ * @since 2.4.0
+ * @param when {int} the number of milliseconds to wait until the fn
+ * is executed
+ * @param o the context object
+ * @param fn {Function|String} the function to execute or the name of
+ * the method in the 'o' object to execute
+ * @param data [Array] data that is provided to the function. This accepts
+ * either a single item or an array. If an array is provided, the
+ * function is executed with one parameter for each array item. If
+ * you need to pass a single array parameter, it needs to be wrapped in
+ * an array [myarray]
+ * @param periodic {boolean} if true, executes continuously at supplied
+ * interval until canceled
+ * @return a timer object. Call the cancel() method on this object to
+ * stop the timer.
+ */
+ later: function(when, o, fn, data, periodic) {
+ when = when || 0;
+ o = o || {};
+ var m=fn, d=data, f, r;
+
+ if (L.isString(fn)) {
+ m = o[fn];
+ }
+
+ if (!m) {
+ throw new TypeError("method undefined");
+ }
+
+ if (!L.isArray(d)) {
+ d = [data];
+ }
+
+ f = function() {
+ m.apply(o, d);
+ };
+
+ r = (periodic) ? setInterval(f, when) : setTimeout(f, when);
+
+ return {
+ interval: periodic,
+ cancel: function() {
+ if (this.interval) {
+ clearInterval(r);
+ } else {
+ clearTimeout(r);
+ }
+ }
+ };
+ },
+
+ /**
+ * A convenience method for detecting a legitimate non-null value.
+ * Returns false for null/undefined/NaN, true for other values,
+ * including 0/false/''
+ * @method isValue
+ * @since 2.3.0
+ * @param o {any} the item to test
+ * @return {boolean} true if it is not null/undefined/NaN || false
+ */
+ isValue: function(o) {
+ // return (o || o === false || o === 0 || o === ''); // Infinity fails
+return (L.isObject(o) || L.isString(o) || L.isNumber(o) || L.isBoolean(o));
+ }
+
+};
+
+/**
+ * Determines whether or not the property was added
+ * to the object instance. Returns false if the property is not present
+ * in the object, or was inherited from the prototype.
+ * This abstraction is provided to enable hasOwnProperty for Safari 1.3.x.
+ * There is a discrepancy between YAHOO.lang.hasOwnProperty and
+ * Object.prototype.hasOwnProperty when the property is a primitive added to
+ * both the instance AND prototype with the same value:
+ * <pre>
+ * var A = function() {};
+ * A.prototype.foo = 'foo';
+ * var a = new A();
+ * a.foo = 'foo';
+ * alert(a.hasOwnProperty('foo')); // true
+ * alert(YAHOO.lang.hasOwnProperty(a, 'foo')); // false when using fallback
+ * </pre>
+ * @method hasOwnProperty
+ * @param {any} o The object being testing
+ * @param prop {string} the name of the property to test
+ * @return {boolean} the result
+ */
+L.hasOwnProperty = (OP.hasOwnProperty) ?
+ function(o, prop) {
+ return o && o.hasOwnProperty(prop);
+ } : function(o, prop) {
+ return !L.isUndefined(o[prop]) &&
+ o.constructor.prototype[prop] !== o[prop];
+ };
+
+// new lang wins
+OB.augmentObject(L, OB, true);
+
+/*
+ * An alias for <a href="YAHOO.lang.html">YAHOO.lang</a>
+ * @class YAHOO.util.Lang
+ */
+YAHOO.util.Lang = L;
+
+/**
+ * Same as YAHOO.lang.augmentObject, except it only applies prototype
+ * properties. This is an alias for augmentProto.
+ * @see YAHOO.lang.augmentObject
+ * @method augment
+ * @static
+ * @param {Function} r the object to receive the augmentation
+ * @param {Function} s the object that supplies the properties to augment
+ * @param {String*|boolean} arguments zero or more properties methods to
+ * augment the receiver with. If none specified, everything
+ * in the supplier will be used unless it would
+ * overwrite an existing property in the receiver. if true
+ * is specified as the third parameter, all properties will
+ * be applied and will overwrite an existing property in
+ * the receiver
+ */
+L.augment = L.augmentProto;
+
+/**
+ * An alias for <a href="YAHOO.lang.html#augment">YAHOO.lang.augment</a>
+ * @for YAHOO
+ * @method augment
+ * @static
+ * @param {Function} r the object to receive the augmentation
+ * @param {Function} s the object that supplies the properties to augment
+ * @param {String*} arguments zero or more properties methods to
+ * augment the receiver with. If none specified, everything
+ * in the supplier will be used unless it would
+ * overwrite an existing property in the receiver
+ */
+YAHOO.augment = L.augmentProto;
+
+/**
+ * An alias for <a href="YAHOO.lang.html#extend">YAHOO.lang.extend</a>
+ * @method extend
+ * @static
+ * @param {Function} subc the object to modify
+ * @param {Function} superc the object to inherit
+ * @param {Object} overrides additional properties/methods to add to the
+ * subclass prototype. These will override the
+ * matching items obtained from the superclass if present.
+ */
+YAHOO.extend = L.extend;
+
+})();
+YAHOO.register("yahoo", YAHOO, {version: "2.7.0", build: "1796"});

0 comments on commit 5d1fdc7

Please sign in to comment.