initial commit
[CPE_learningsite] / CPE / CPE.App / CPE.App.Web / Scripts / respond.js
1 /* NUGET: BEGIN LICENSE TEXT
2  *
3  * Microsoft grants you the right to use these script files for the sole
4  * purpose of either: (i) interacting through your browser with the Microsoft
5  * website or online service, subject to the applicable licensing or use
6  * terms; or (ii) using the files as included with a Microsoft product subject
7  * to that product's license terms. Microsoft reserves all other rights to the
8  * files not expressly granted by Microsoft, whether by implication, estoppel
9  * or otherwise. Insofar as a script file is dual licensed under GPL,
10  * Microsoft neither took the code under GPL nor distributes it thereunder but
11  * under the terms set out in this paragraph. All notices and licenses
12  * below are for informational purposes only.
13  *
14  * NUGET: END LICENSE TEXT */
15 /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
16 /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
17 window.matchMedia = window.matchMedia || (function(doc, undefined){
18   
19   var bool,
20       docElem  = doc.documentElement,
21       refNode  = docElem.firstElementChild || docElem.firstChild,
22       // fakeBody required for <FF4 when executed in <head>
23       fakeBody = doc.createElement('body'),
24       div      = doc.createElement('div');
25   
26   div.id = 'mq-test-1';
27   div.style.cssText = "position:absolute;top:-100em";
28   fakeBody.style.background = "none";
29   fakeBody.appendChild(div);
30   
31   return function(q){
32     
33     div.innerHTML = '&shy;<style media="'+q+'"> #mq-test-1 { width: 42px; }</style>';
34     
35     docElem.insertBefore(fakeBody, refNode);
36     bool = div.offsetWidth == 42;  
37     docElem.removeChild(fakeBody);
38     
39     return { matches: bool, media: q };
40   };
41   
42 })(document);
43
44
45
46
47 /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs  */
48 (function( win ){
49         //exposed namespace
50         win.respond             = {};
51         
52         //define update even in native-mq-supporting browsers, to avoid errors
53         respond.update  = function(){};
54         
55         //expose media query support flag for external use
56         respond.mediaQueriesSupported   = win.matchMedia && win.matchMedia( "only all" ).matches;
57         
58         //if media queries are supported, exit here
59         if( respond.mediaQueriesSupported ){ return; }
60         
61         //define vars
62         var doc                         = win.document,
63                 docElem                 = doc.documentElement,
64                 mediastyles             = [],
65                 rules                   = [],
66                 appendedEls     = [],
67                 parsedSheets    = {},
68                 resizeThrottle  = 30,
69                 head                    = doc.getElementsByTagName( "head" )[0] || docElem,
70                 base                    = doc.getElementsByTagName( "base" )[0],
71                 links                   = head.getElementsByTagName( "link" ),
72                 requestQueue    = [],
73                 
74                 //loop stylesheets, send text content to translate
75                 ripCSS                  = function(){
76                         var sheets      = links,
77                                 sl              = sheets.length,
78                                 i               = 0,
79                                 //vars for loop:
80                                 sheet, href, media, isCSS;
81
82                         for( ; i < sl; i++ ){
83                                 sheet   = sheets[ i ],
84                                 href    = sheet.href,
85                                 media   = sheet.media,
86                                 isCSS   = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
87
88                                 //only links plz and prevent re-parsing
89                                 if( !!href && isCSS && !parsedSheets[ href ] ){
90                                         // selectivizr exposes css through the rawCssText expando
91                                         if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
92                                                 translate( sheet.styleSheet.rawCssText, href, media );
93                                                 parsedSheets[ href ] = true;
94                                         } else {
95                                                 if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base)
96                                                         || href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){
97                                                         requestQueue.push( {
98                                                                 href: href,
99                                                                 media: media
100                                                         } );
101                                                 }
102                                         }
103                                 }
104                         }
105                         makeRequests();
106                 },
107                 
108                 //recurse through request queue, get css text
109                 makeRequests    = function(){
110                         if( requestQueue.length ){
111                                 var thisRequest = requestQueue.shift();
112                                 
113                                 ajax( thisRequest.href, function( styles ){
114                                         translate( styles, thisRequest.href, thisRequest.media );
115                                         parsedSheets[ thisRequest.href ] = true;
116                                         makeRequests();
117                                 } );
118                         }
119                 },
120                 
121                 //find media blocks in css text, convert to style blocks
122                 translate                       = function( styles, href, media ){
123                         var qs                  = styles.match(  /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ),
124                                 ql                      = qs && qs.length || 0,
125                                 //try to get CSS path
126                                 href            = href.substring( 0, href.lastIndexOf( "/" )),
127                                 repUrls         = function( css ){
128                                         return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" );
129                                 },
130                                 useMedia        = !ql && media,
131                                 //vars used in loop
132                                 i                       = 0,
133                                 j, fullq, thisq, eachq, eql;
134
135                         //if path exists, tack on trailing slash
136                         if( href.length ){ href += "/"; }       
137                                 
138                         //if no internal queries exist, but media attr does, use that   
139                         //note: this currently lacks support for situations where a media attr is specified on a link AND
140                                 //its associated stylesheet has internal CSS media queries.
141                                 //In those cases, the media attribute will currently be ignored.
142                         if( useMedia ){
143                                 ql = 1;
144                         }
145                         
146
147                         for( ; i < ql; i++ ){
148                                 j       = 0;
149                                 
150                                 //media attr
151                                 if( useMedia ){
152                                         fullq = media;
153                                         rules.push( repUrls( styles ) );
154                                 }
155                                 //parse for styles
156                                 else{
157                                         fullq   = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1;
158                                         rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
159                                 }
160                                 
161                                 eachq   = fullq.split( "," );
162                                 eql             = eachq.length;
163                                         
164                                 for( ; j < eql; j++ ){
165                                         thisq   = eachq[ j ];
166                                         mediastyles.push( { 
167                                                 media   : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all",
168                                                 rules   : rules.length - 1,
169                                                 hasquery: thisq.indexOf("(") > -1,
170                                                 minw    : thisq.match( /\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ), 
171                                                 maxw    : thisq.match( /\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" )
172                                         } );
173                                 }       
174                         }
175
176                         applyMedia();
177                 },
178                 
179                 lastCall,
180                 
181                 resizeDefer,
182                 
183                 // returns the value of 1em in pixels
184                 getEmValue              = function() {
185                         var ret,
186                                 div = doc.createElement('div'),
187                                 body = doc.body,
188                                 fakeUsed = false;
189                                                                         
190                         div.style.cssText = "position:absolute;font-size:1em;width:1em";
191                                         
192                         if( !body ){
193                                 body = fakeUsed = doc.createElement( "body" );
194                                 body.style.background = "none";
195                         }
196                                         
197                         body.appendChild( div );
198                                                                 
199                         docElem.insertBefore( body, docElem.firstChild );
200                                                                 
201                         ret = div.offsetWidth;
202                                                                 
203                         if( fakeUsed ){
204                                 docElem.removeChild( body );
205                         }
206                         else {
207                                 body.removeChild( div );
208                         }
209                         
210                         //also update eminpx before returning
211                         ret = eminpx = parseFloat(ret);
212                                                                 
213                         return ret;
214                 },
215                 
216                 //cached container for 1em value, populated the first time it's needed 
217                 eminpx,
218                 
219                 //enable/disable styles
220                 applyMedia                      = function( fromResize ){
221                         var name                = "clientWidth",
222                                 docElemProp     = docElem[ name ],
223                                 currWidth       = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
224                                 styleBlocks     = {},
225                                 lastLink        = links[ links.length-1 ],
226                                 now             = (new Date()).getTime();
227
228                         //throttle resize calls 
229                         if( fromResize && lastCall && now - lastCall < resizeThrottle ){
230                                 clearTimeout( resizeDefer );
231                                 resizeDefer = setTimeout( applyMedia, resizeThrottle );
232                                 return;
233                         }
234                         else {
235                                 lastCall        = now;
236                         }
237                                                                                 
238                         for( var i in mediastyles ){
239                                 var thisstyle = mediastyles[ i ],
240                                         min = thisstyle.minw,
241                                         max = thisstyle.maxw,
242                                         minnull = min === null,
243                                         maxnull = max === null,
244                                         em = "em";
245                                 
246                                 if( !!min ){
247                                         min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
248                                 }
249                                 if( !!max ){
250                                         max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
251                                 }
252                                 
253                                 // if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true
254                                 if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){
255                                                 if( !styleBlocks[ thisstyle.media ] ){
256                                                         styleBlocks[ thisstyle.media ] = [];
257                                                 }
258                                                 styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
259                                 }
260                         }
261                         
262                         //remove any existing respond style element(s)
263                         for( var i in appendedEls ){
264                                 if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){
265                                         head.removeChild( appendedEls[ i ] );
266                                 }
267                         }
268                         
269                         //inject active styles, grouped by media type
270                         for( var i in styleBlocks ){
271                                 var ss          = doc.createElement( "style" ),
272                                         css             = styleBlocks[ i ].join( "\n" );
273                                 
274                                 ss.type = "text/css";   
275                                 ss.media        = i;
276                                 
277                                 //originally, ss was appended to a documentFragment and sheets were appended in bulk.
278                                 //this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one!
279                                 head.insertBefore( ss, lastLink.nextSibling );
280                                 
281                                 if ( ss.styleSheet ){ 
282                                 ss.styleSheet.cssText = css;
283                         } 
284                         else {
285                                         ss.appendChild( doc.createTextNode( css ) );
286                         }
287                         
288                                 //push to appendedEls to track for later removal
289                                 appendedEls.push( ss );
290                         }
291                 },
292                 //tweaked Ajax functions from Quirksmode
293                 ajax = function( url, callback ) {
294                         var req = xmlHttp();
295                         if (!req){
296                                 return;
297                         }       
298                         req.open( "GET", url, true );
299                         req.onreadystatechange = function () {
300                                 if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){
301                                         return;
302                                 }
303                                 callback( req.responseText );
304                         }
305                         if ( req.readyState == 4 ){
306                                 return;
307                         }
308                         req.send( null );
309                 },
310                 //define ajax obj 
311                 xmlHttp = (function() {
312                         var xmlhttpmethod = false;      
313                         try {
314                                 xmlhttpmethod = new XMLHttpRequest();
315                         }
316                         catch( e ){
317                                 xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" );
318                         }
319                         return function(){
320                                 return xmlhttpmethod;
321                         };
322                 })();
323         
324         //translate CSS
325         ripCSS();
326         
327         //expose update for re-running respond later on
328         respond.update = ripCSS;
329         
330         //adjust on resize
331         function callMedia(){
332                 applyMedia( true );
333         }
334         if( win.addEventListener ){
335                 win.addEventListener( "resize", callMedia, false );
336         }
337         else if( win.attachEvent ){
338                 win.attachEvent( "onresize", callMedia );
339         }
340 })(this);