Blame view

static/plugins/webshim-gh-pages/js-webshim/dev/shims/matchMedia.js 4.45 KB
831eac332   zhuzhenchao   add file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
  /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
  
  window.matchMedia || (window.matchMedia = function() {
      "use strict";
  
      // For browsers that support matchMedium api such as IE 9 and webkit
      var styleMedia = (window.styleMedia || window.media);
  
      // For those that don't support matchMedium
      if (!styleMedia) {
          var style       = document.createElement('style'),
              script      = document.getElementsByTagName('script')[0],
              info        = null;
  
          style.type  = 'text/css';
          style.id    = 'matchmediajs-test';
  
          script.parentNode.insertBefore(style, script);
  
          // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
          info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
  
          styleMedia = {
              matchMedium: function(media) {
                  var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
  
                  // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
                  if (style.styleSheet) {
                      style.styleSheet.cssText = text;
                  } else {
                      style.textContent = text;
                  }
  
                  // Test if media query is true or false
                  return info.width === '1px';
              }
          };
      }
  
      return function(media) {
          return {
              matches: styleMedia.matchMedium(media || 'all'),
              media: media || 'all'
          };
      };
  }());
  /*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */
  (function(){
      // Bail out for browsers that have addListener support
      if (window.matchMedia && window.matchMedia('all').addListener) {
          return false;
      }
  
      var localMatchMedia = window.matchMedia,
          hasMediaQueries = localMatchMedia('only all').matches,
          isListening     = false,
          timeoutID       = 0,    // setTimeout for debouncing 'handleChange'
          queries         = [],   // Contains each 'mql' and associated 'listeners' if 'addListener' is used
          handleChange    = function(evt) {
              // Debounce
              clearTimeout(timeoutID);
  
              timeoutID = setTimeout(function() {
                  for (var i = 0, il = queries.length; i < il; i++) {
                      var mql         = queries[i].mql,
                          listeners   = queries[i].listeners || [],
                          matches     = localMatchMedia(mql.media).matches;
  
                      // Update mql.matches value and call listeners
                      // Fire listeners only if transitioning to or from matched state
                      if (matches !== mql.matches) {
                          mql.matches = matches;
  
                          for (var j = 0, jl = listeners.length; j < jl; j++) {
                              listeners[j].call(window, mql);
                          }
                      }
                  }
              }, 30);
          };
  
      window.matchMedia = function(media) {
          var mql         = localMatchMedia(media),
              listeners   = [],
              index       = 0;
  
          mql.addListener = function(listener) {
              // Changes would not occur to css media type so return now (Affects IE <= 8)
              if (!hasMediaQueries) {
                  return;
              }
  
              // Set up 'resize' listener for browsers that support CSS3 media queries (Not for IE <= 8)
              // There should only ever be 1 resize listener running for performance
              if (!isListening) {
                  isListening = true;
                  window.addEventListener('resize', handleChange, true);
              }
  
              // Push object only if it has not been pushed already
              if (index === 0) {
                  index = queries.push({
                      mql         : mql,
                      listeners   : listeners
                  });
              }
  
              listeners.push(listener);
          };
  
          mql.removeListener = function(listener) {
              for (var i = 0, il = listeners.length; i < il; i++){
                  if (listeners[i] === listener){
                      listeners.splice(i, 1);
                  }
              }
          };
  
          return mql;
      };
  }());
  webshim.isReady('matchMedia', true);