Subversion Repositories ALCASAR

Rev

Details | Last modification | View Log

Rev Author Line No. Line
3288 rexy 1
/* Bootstrap 4 for IE8 - v4.3.100          */
2
/* https://github.com/namiltd/bootstrap-ie */
3
 
4
/**
5
 * Modified code based on remPolyfill.js (c) Nicolas Bouvrette https://github.com/nbouvrette/remPolyfill
6
 *
7
 * Customizations:
8
 *
9
 * 1) Added new method `addCallBackWhenReady` to perform callbacks once the polyfill has been applied (especially useful for
10
 *    onload scrolling events.
11
 * 2) Added REM support.
12
 *
13
 **/
14
 
15
/**
16
 * For browsers that do not support REM units, fallback to pixels.
17
 */
18
window.remPolyfill = {
19
 
20
    /** @property Number|null - The body's font size.
21
     *  @private */
22
    bodyFontSize: null,
23
 
24
    /**
25
     * Get the body font size.
26
     *
27
     * @returns {Number} - The body font size in pixel (number only).
28
     */
29
    getBodyFontSize: function() {
30
        if (!this.bodyFontSize) {
31
            if (!document.body) {
32
                var bodyElement = document.createElement('body');
33
                document.documentElement.appendChild(bodyElement);
34
                this.bodyFontSize = parseFloat(this.getStyle(document.body, 'fontSize'));
35
                document.documentElement.removeChild(bodyElement);
36
                bodyElement = null;
37
            } else {
38
                this.bodyFontSize = parseFloat(this.getStyle(document.body, 'fontSize'));
39
            }
40
        }
41
        return this.bodyFontSize;
42
    },
43
 
44
    /**
45
     * Get the style of an element for a given property.
46
     *
47
     * @private
48
     *
49
     * @param {HTMLElement} element - The HTML element.
50
     * @param {string} property     - The property of the style to get.
51
     */
52
    getStyle: function(element, property) {
53
        if (typeof window.getComputedStyle !== 'undefined') {
54
            return window.getComputedStyle(element, null).getPropertyValue(property);
55
        } else {
56
            return element.currentStyle[property];
57
        }
58
    },
59
 
60
    /**
61
     * Implement this script on a given element.
62
     *
63
     * @private
64
     *
65
     * @param {string} cssText              - The CSS text of the link element.
66
     */
67
    replaceCSS: function (cssText) {
68
        if (cssText) {
69
            // Replace all properties containing REM units with their pixel equivalents.
70
            return cssText.replace(
71
                /([\d]+\.[\d]+|\.[\d]+|[\d]+)rem/g, function (fullMatch, groupMatch) {
72
                    return Math.round(parseFloat(groupMatch * remPolyfill.getBodyFontSize())) + 'px';}
73
            ).replace(
74
                /calc\s*\(\s*\(\s*([\d]+)\s*px\s*([\+-])\s*([\d]+)\s*px\s*\)\s*\*\s*(-?[\d]+)\s*\)/g, function (fullMatch, MatchArg1, MatchSign, MatchArg2, MatchArg3) {
75
                    return ((parseInt(MatchArg1)+(MatchSign=='-'?-1:1)*parseInt(MatchArg2))*parseInt(MatchArg3))+'px';}
76
            ).replace(
77
                /calc\s*\(\s*([\d]+)\s*px\s*([\+-])\s*([\d]+)\s*px\s*\)/g, function (fullMatch, MatchArg1, MatchSign, MatchArg2) {
78
                    return (parseInt(MatchArg1)+(MatchSign=='-'?-1:1)*parseInt(MatchArg2))+'px';}
79
            ).replace(
80
                /::/g, ':'
81
            ).replace(
82
                /:disabled/g, '._disabled'
83
            ).replace(
84
                /:invalid/g, '._invalid'
85
            ).replace(
86
                /:valid/g, '._valid'
87
            ).replace(
88
                /background-color\s*:\s*rgba\s*\(\s*([\d]+)\s*,\s*([\d]+)\s*,\s*([\d]+)\s*,\s*([\d\.]+)\s*\)/g, function (fullMatch, MatchR, MatchG, MatchB, MatchA) {
89
                    var ARGBhex = (4294967296+16777216*Math.round(parseFloat(MatchA)*255)+65536*parseInt(MatchR)+256*parseInt(MatchG)+parseInt(MatchB)).toString(16).substr(1);
90
                    return 'filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#'+ARGBhex+', endColorstr=#'+ARGBhex+')';}
91
            ).replace(
92
                /rgba\s*\(\s*([\d]+)\s*,\s*([\d]+)\s*,\s*([\d]+)\s*,\s*([\d\.]+)\s*\)/g, function (fullMatch, MatchR, MatchG, MatchB, MatchA) {
93
                    var MR = parseInt(MatchR), MG = parseInt(MatchG), MB = parseInt(MatchB), MA = parseFloat(MatchA);
94
                    if ((MR==255)&&(MG==255)&&(MB==255)) { //dark background
95
                        return 'rgb(' + Math.round(MA * 255) + ', ' + Math.round(MA * 255) + ', ' + Math.round(MA * 255) +')';
96
                    } else { //else
97
                        return 'rgb(' + Math.round((1-MA) * 255 + MA * MR) + ', ' + Math.round((1-MA) * 255 + MA * MG) + ', ' + Math.round((1-MA) * 255 + MA * MB) +')';
98
                    }
99
                 }
100
            ).replace(
101
                /opacity\s*:\s*([\d]+\.[\d]+|\.[\d]+|[\d]+)/g, function (fullMatch, groupMatch) {
102
                    return 'filter:alpha(opacity=' + Math.round(parseFloat(groupMatch * 100)) + ')';}
103
            );
104
        }
105
    },
106
 
107
    /**
108
     * Implement this script on a given element.
109
     *
110
     * @param {HTMLLinkElement} linkElement - The link element to polyfill.
111
     */
112
    implement: function (linkElement) {
113
        if (!linkElement.href) {
114
            return;
115
        }
116
 
117
        var request = null;
118
 
119
        if (window.XMLHttpRequest) {
120
            request = new XMLHttpRequest();
121
        } else if (window.ActiveXObject) {
122
            try {
123
                request = new ActiveXObject("Msxml2.XMLHTTP");
124
            } catch (exception) {
125
                try {
126
                    request = new ActiveXObject("Microsoft.XMLHTTP");
127
                } catch (exception) {
128
                    request = null;
129
                }
130
            }
131
        }
132
 
133
        if (!request) {
134
            return;
135
        }
136
 
137
        request.open('GET', linkElement.href, true);
138
        request.onreadystatechange = function() {
139
            if ( request.readyState === 4 ) {
140
                linkElement.styleSheet.cssText = remPolyfill.replaceCSS(request.responseText);
141
            }
142
        };
143
 
144
        request.send(null);
145
    }
146
};
147
 
148
var linkElements = document.querySelectorAll('link[rel=stylesheet]');
149
for (var linkElementId in linkElements) {
150
    if (Object.prototype.hasOwnProperty.call(linkElements, linkElementId)) {
151
        remPolyfill.implement(linkElements[linkElementId]);
152
    }
153
}
154
 
155
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
156
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
157
(function (w) {
158
    "use strict";
159
    w.matchMedia = w.matchMedia || function (doc, undefined) {
160
            var bool, docElem = doc.documentElement, refNode = docElem.firstElementChild || docElem.firstChild,
161
                fakeBody = doc.createElement("body"), div = doc.createElement("div");
162
            div.id = "mq-test-1";
163
            div.style.cssText = "position:absolute;top:-100em";
164
            fakeBody.style.background = "none";
165
            fakeBody.appendChild(div);
166
            return function (q) {
167
                div.innerHTML = '&shy;<style media="' + q + '"> #mq-test-1 { width: 42px; }</style>';
168
                docElem.insertBefore(fakeBody, refNode);
169
                bool = div.offsetWidth === 42;
170
                docElem.removeChild(fakeBody);
171
                return {
172
                    matches: bool,
173
                    media: q
174
                };
175
            };
176
        }(w.document);
177
})(this);
178
 
179
/* Respond.js: min/max-width media query polyfill. (c) Scott Jehl. MIT Lic. j.mp/respondjs  */
180
 
181
(function (w) {
182
    "use strict";
183
    //exposed namespace
184
    var respond = {};
185
    w.respond = respond;
186
    //define update even in native-mq-supporting browsers, to avoid errors
187
    respond.update = function () {
188
    };
189
    //define ajax obj
190
    var requestQueue = [],
191
        xmlHttp = function () {
192
            var xmlhttpmethod = false;
193
            try {
194
                xmlhttpmethod = new w.XMLHttpRequest();
195
            } catch (e) {
196
                xmlhttpmethod = new w.ActiveXObject("Microsoft.XMLHTTP");
197
            }
198
            return function () {
199
                return xmlhttpmethod;
200
            };
201
        }(),
202
        //tweaked Ajax functions from Quirksmode
203
        ajax = function (url, callback) {
204
            var req = xmlHttp();
205
            if (!req) {
206
                return;
207
            }
208
            try {
209
                req.open("GET", url, true);
210
                req.onreadystatechange = function () {
211
                    if (req.readyState !== 4 || req.status !== 200 && req.status !== 304) {
212
                        return;
213
                    }
214
                    callback( remPolyfill.replaceCSS(req.responseText) );
215
                };
216
                if (req.readyState === 4) {
217
                    return;
218
                }
219
                req.send(null);
220
            }
221
            catch ( e ) {
222
            }
223
        }, isUnsupportedMediaQuery = function (query) {
224
            return query.replace(respond.regex.minmaxwh, '').match(respond.regex.other);
225
        };
226
    //expose for testing
227
    respond.ajax = ajax;
228
    respond.queue = requestQueue;
229
    respond.unsupportedmq = isUnsupportedMediaQuery;
230
    respond.regex = {
231
        media: /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,
232
        keyframes: /@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,
233
        comments: /\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,
234
        urls: /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,
235
        findStyles: /@media *([^\{]+)\{([\S\s]+?)$/,
236
        only: /(only\s+)?([a-zA-Z]+)\s?/,
237
        minw: /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,
238
        maxw: /\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,
239
        minmaxwh: /\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,
240
        other: /\([^\)]*\)/g
241
    };
242
    //expose media query support flag for external use
243
    respond.mediaQueriesSupported = w.matchMedia && w.matchMedia("only all") !== null && w.matchMedia("only all").matches;
244
    //if media queries are supported, exit here
245
    if (respond.mediaQueriesSupported) {
246
        return;
247
    }
248
    respond.callbackQueue = [];
249
    respond.addCallBackWhenReady = function (callback) {
250
        respond.callbackQueue.push(callback);
251
    };
252
    respond.callback = function () {
253
        if (respond.callbackQueue.length) {
254
            for (var callback in respond.callbackQueue) {
255
                respond.callbackQueue[callback]();
256
            }
257
        }
258
    };
259
 
260
    //define vars
261
    var doc = w.document,
262
        docElem = doc.documentElement,
263
        mediastyles = [],
264
        rules = [],
265
        appendedEls = [],
266
        parsedSheets = {},
267
        resizeThrottle = 30,
268
        head = doc.getElementsByTagName("head")[0] || docElem,
269
        base = doc.getElementsByTagName("base")[0],
270
        links = head.getElementsByTagName("link"),
271
 
272
        lastCall,
273
        resizeDefer,
274
 
275
        //cached container for 1em value, populated the first time it's needed
276
        eminpx,
277
 
278
        // returns the value of 1em in pixels
279
        getEmValue = function () {
280
            var ret,
281
                div = doc.createElement('div'),
282
                body = doc.body,
283
                originalHTMLFontSize = docElem.style.fontSize,
284
                originalBodyFontSize = body && body.style.fontSize,
285
                fakeUsed = false;
286
 
287
            div.style.cssText = "position:absolute;font-size:1em;width:1em";
288
            if (!body) {
289
                body = fakeUsed = doc.createElement("body");
290
                body.style.background = "none";
291
            }
292
            // 1em in a media query is the value of the default font size of the browser
293
            // reset docElem and body to ensure the correct value is returned
294
            docElem.style.fontSize = "100%";
295
            body.style.fontSize = "100%";
296
            body.appendChild(div);
297
            if (fakeUsed) {
298
                docElem.insertBefore(body, docElem.firstChild);
299
            }
300
            ret = div.offsetWidth;
301
            if (fakeUsed) {
302
                docElem.removeChild(body);
303
            } else {
304
                body.removeChild(div);
305
            }
306
            // restore the original values
307
            docElem.style.fontSize = originalHTMLFontSize;
308
            if (originalBodyFontSize) {
309
                body.style.fontSize = originalBodyFontSize;
310
            }
311
            //also update eminpx before returning
312
            ret = eminpx = parseFloat(ret);
313
            return ret;
314
        },
315
 
316
        //enable/disable styles
317
        applyMedia = function (fromResize) {
318
            var name = "clientWidth",
319
                docElemProp = docElem[name],
320
                currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[name] || docElemProp,
321
                styleBlocks = {},
322
                lastLink = links[links.length - 1],
323
                now = new Date().getTime();
324
 
325
            //throttle resize calls
326
 
327
            if (fromResize && lastCall && now - lastCall < resizeThrottle) {
328
                w.clearTimeout(resizeDefer);
329
                resizeDefer = w.setTimeout(applyMedia, resizeThrottle);
330
                return;
331
            } else {
332
                lastCall = now;
333
            }
334
            for (var i in mediastyles) {
335
                if (mediastyles.hasOwnProperty(i)) {
336
                    var thisstyle = mediastyles[i],
337
                        min = thisstyle.minw,
338
                        max = thisstyle.maxw,
339
                        minnull = min === null,
340
                        maxnull = max === null,
341
                        em = "em";
342
                    if (!!min) {
343
                        min = parseFloat(min) * (min.indexOf(em) > -1 ? ( eminpx || getEmValue() ) : 1);
344
                    }
345
                    if (!!max) {
346
                        max = parseFloat(max) * (max.indexOf(em) > -1 ? ( eminpx || getEmValue() ) : 1);
347
                    }
348
                    // 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
349
                    if (!thisstyle.hasquery || (!minnull || !maxnull) && (minnull || currWidth >= min) && (maxnull || currWidth <= max)) {
350
                        if (!styleBlocks[thisstyle.media]) {
351
                            styleBlocks[thisstyle.media] = [];
352
                        }
353
                        styleBlocks[thisstyle.media].push(rules[thisstyle.rules]);
354
                    }
355
                }
356
            }
357
            //remove any existing respond style element(s)
358
            for (var j in appendedEls) {
359
                if (appendedEls.hasOwnProperty(j)) {
360
                    if (appendedEls[j] && appendedEls[j].parentNode === head) {
361
                        head.removeChild(appendedEls[j]);
362
                    }
363
                }
364
            }
365
            appendedEls.length = 0;
366
            //inject active styles, grouped by media type
367
            for (var k in styleBlocks) {
368
                if (styleBlocks.hasOwnProperty(k)) {
369
                    var ss = doc.createElement("style"),
370
                        css = styleBlocks[k].join("\n");
371
                    ss.type = "text/css";
372
                    ss.media = k;
373
                    //originally, ss was appended to a documentFragment and sheets were appended in bulk.
374
                    //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!
375
                    head.insertBefore(ss, lastLink.nextSibling);
376
                    if (ss.styleSheet) {
377
                        ss.styleSheet.cssText = css;
378
                    } else {
379
                        ss.appendChild(doc.createTextNode(css));
380
                    }
381
                    //push to appendedEls to track for later removal
382
                    appendedEls.push(ss);
383
                }
384
            }
385
        },
386
        //find media blocks in css text, convert to style blocks
387
        translate = function (styles, href, media) {
388
            var qs = styles.replace(respond.regex.comments, "")
389
                    .replace(respond.regex.keyframes, "")
390
                    .match(respond.regex.media),
391
                ql = qs && qs.length || 0;
392
            //try to get CSS path
393
            href = href.substring(0, href.lastIndexOf("/"));
394
            var repUrls = function (css) {
395
                return css.replace(respond.regex.urls, "$1" + href + "$2$3");
396
            }, useMedia = !ql && media;
397
            //if path exists, tack on trailing slash
398
            if (href.length) {
399
                href += "/";
400
            }
401
            //if no internal queries exist, but media attr does, use that
402
            //note: this currently lacks support for situations where a media attr is specified on a link AND
403
            //its associated stylesheet has internal CSS media queries.
404
            //In those cases, the media attribute will currently be ignored.
405
            if (useMedia) {
406
                ql = 1;
407
            }
408
            for (var i = 0; i < ql; i++) {
409
                var fullq, thisq, eachq, eql;
410
                //media attr
411
                if (useMedia) {
412
                    fullq = media;
413
                    rules.push(repUrls(styles));
414
                    //parse for styles
415
                } else {
416
                    fullq = qs[i].match(respond.regex.findStyles) && RegExp.$1;
417
                    rules.push(RegExp.$2 && repUrls(RegExp.$2));
418
                }
419
                eachq = fullq.split(",");
420
                eql = eachq.length;
421
                for (var j = 0; j < eql; j++) {
422
                    thisq = eachq[j];
423
                    if (isUnsupportedMediaQuery(thisq)) {
424
                        continue;
425
                    }
426
                    mediastyles.push({
427
                        media: thisq.split("(")[0].match(respond.regex.only) && RegExp.$2 || "all",
428
                        rules: rules.length - 1,
429
                        hasquery: thisq.indexOf("(") > -1,
430
                        minw: thisq.match(respond.regex.minw) && parseFloat(RegExp.$1) + (RegExp.$2 || ""),
431
                        maxw: thisq.match(respond.regex.maxw) && parseFloat(RegExp.$1) + (RegExp.$2 || "")
432
                    });
433
                }
434
            }
435
            applyMedia();
436
        },
437
 
438
        //recurse through request queue, get css text
439
        makeRequests = function () {
440
            if (requestQueue.length) {
441
                var thisRequest = requestQueue.shift();
442
                ajax(thisRequest.href, function (styles) {
443
                    translate(styles, thisRequest.href, thisRequest.media);
444
                    parsedSheets[thisRequest.href] = true;
445
                    // by wrapping recursive function call in setTimeout
446
                    // we prevent "Stack overflow" error in IE7
447
                    w.setTimeout(function () {
448
                        makeRequests();
449
                    }, 0);
450
                });
451
            } else {
452
                respond.callback();
453
            }
454
        },
455
 
456
        //loop stylesheets, send text content to translate
457
        ripCSS = function () {
458
            for (var i = 0; i < links.length; i++) {
459
                var sheet = links[i],
460
                    href = sheet.href,
461
                    media = sheet.media,
462
                    isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
463
                //only links plz and prevent re-parsing
464
                if (!!href && isCSS && !parsedSheets[href]) {
465
                    // selectivizr exposes css through the rawCssText expando
466
                    if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
467
                        translate(sheet.styleSheet.rawCssText, href, media);
468
                        parsedSheets[href] = true;
469
                    } else {
470
                        if (!/^([a-zA-Z:]*\/\/)/.test(href) && !base ||
471
                            href.replace(RegExp.$1, "").split("/")[0] === w.location.host) {
472
                            // IE7 doesn't handle urls that start with '//' for ajax request
473
                            // manually add in the protocol
474
                            if (href.substring(0, 2) === "//") {
475
                                href = w.location.protocol + href;
476
                            }
477
                            requestQueue.push({
478
                                href: href,
479
                                media: media
480
                            });
481
                        }
482
                    }
483
                }
484
            }
485
            makeRequests();
486
        };
487
    //translate CSS
488
    ripCSS();
489
 
490
    //expose update for re-running respond later on
491
    respond.update = ripCSS;
492
 
493
    //expose getEmValue
494
    respond.getEmValue = getEmValue;
495
 
496
    //adjust on resize
497
    function callMedia() {
498
        applyMedia(true);
499
    }
500
 
501
    if (w.addEventListener) {
502
        w.addEventListener("resize", callMedia, false);
503
    }
504
    else if (w.attachEvent) {
505
        w.attachEvent("onresize", callMedia);
506
    }
507
})(this);