[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/webroot/rsrc/externals/javelin/core/ -> init.js (source)

   1  /**
   2   * Javelin core; installs Javelin and Stratcom event delegation.
   3   *
   4   * @provides javelin-magical-init
   5   *
   6   * @javelin-installs JX.__rawEventQueue
   7   * @javelin-installs JX.__simulate
   8   * @javelin-installs JX.__allowedEvents
   9   * @javelin-installs JX.enableDispatch
  10   * @javelin-installs JX.onload
  11   * @javelin-installs JX.flushHoldingQueue
  12   *
  13   * @javelin
  14   */
  15  (function() {
  16  
  17    if (window.JX) {
  18      return;
  19    }
  20  
  21    window.JX = {};
  22  
  23    // The holding queues hold calls to functions (JX.install() and JX.behavior())
  24    // before they load, so if you're async-loading them later in the document
  25    // the page will execute correctly regardless of the order resources arrive
  26    // in.
  27  
  28    var holding_queues = {};
  29  
  30    function makeHoldingQueue(name) {
  31      if (JX[name]) {
  32        return;
  33      }
  34      holding_queues[name] = [];
  35      JX[name] = function() { holding_queues[name].push(arguments); };
  36    }
  37  
  38    JX.flushHoldingQueue = function(name, fn) {
  39      for (var ii = 0; ii < holding_queues[name].length; ii++) {
  40        fn.apply(null, holding_queues[name][ii]);
  41      }
  42      holding_queues[name] = {};
  43    };
  44  
  45    makeHoldingQueue('install');
  46    makeHoldingQueue('behavior');
  47    makeHoldingQueue('install-init');
  48  
  49    window['__DEV__'] = window['__DEV__'] || 0;
  50  
  51    var loaded = false;
  52    var onload = [];
  53    var master_event_queue = [];
  54    var root = document.documentElement;
  55    var has_add_event_listener = !!root.addEventListener;
  56  
  57    JX.__rawEventQueue = function(what) {
  58      master_event_queue.push(what);
  59  
  60      // Evade static analysis - JX.Stratcom
  61      var Stratcom = JX['Stratcom'];
  62      if (Stratcom && Stratcom.ready) {
  63        //  Empty the queue now so that exceptions don't cause us to repeatedly
  64        //  try to handle events.
  65        var local_queue = master_event_queue;
  66        master_event_queue = [];
  67        for (var ii = 0; ii < local_queue.length; ++ii) {
  68          var evt = local_queue[ii];
  69  
  70          // Sometimes IE gives us events which throw when ".type" is accessed;
  71          // just ignore them since we can't meaningfully dispatch them. TODO:
  72          // figure out where these are coming from.
  73          try { var test = evt.type; } catch (x) { continue; }
  74  
  75          if (!loaded && evt.type == 'domready') {
  76            // NOTE: Firefox interprets "document.body.id = null" as the string
  77            // literal "null".
  78            document.body && (document.body.id = '');
  79            loaded = true;
  80            for (var jj = 0; jj < onload.length; jj++) {
  81              onload[jj]();
  82            }
  83          }
  84  
  85          Stratcom.dispatch(evt);
  86        }
  87      } else {
  88        var target = what.srcElement || what.target;
  89        if (target &&
  90            (what.type in {click: 1, submit: 1}) &&
  91            target.getAttribute &&
  92            target.getAttribute('data-mustcapture') === '1') {
  93          what.returnValue = false;
  94          what.preventDefault && what.preventDefault();
  95          document.body.id = 'event_capture';
  96  
  97          // For versions of IE that use attachEvent, the event object is somehow
  98          // stored globally by reference, and all the references we push to the
  99          // master_event_queue will always refer to the most recent event. We
 100          // work around this by popping the useless global event off the queue,
 101          // and pushing a clone of the event that was just fired using the IE's
 102          // proprietary createEventObject function.
 103          // see: http://msdn.microsoft.com/en-us/library/ms536390(v=vs.85).aspx
 104          if (!add_event_listener && document.createEventObject) {
 105            master_event_queue.pop();
 106            master_event_queue.push(document.createEventObject(what));
 107          }
 108  
 109          return false;
 110        }
 111      }
 112    };
 113  
 114    JX.enableDispatch = function(target, type) {
 115      if (__DEV__) {
 116        JX.__allowedEvents[type] = true;
 117      }
 118  
 119      if (target.addEventListener) {
 120        target.addEventListener(type, JX.__rawEventQueue, true);
 121      } else if (target.attachEvent) {
 122        target.attachEvent('on' + type, JX.__rawEventQueue);
 123      }
 124    };
 125  
 126    var document_events = [
 127      'click',
 128      'dblclick',
 129      'change',
 130      'submit',
 131      'keypress',
 132      'mousedown',
 133      'mouseover',
 134      'mouseout',
 135      'mouseup',
 136      'keyup',
 137      'keydown',
 138      'input',
 139      'drop',
 140      'dragenter',
 141      'dragleave',
 142      'dragover',
 143      'paste',
 144      'touchstart',
 145      'touchmove',
 146      'touchend',
 147      'touchcancel'
 148    ];
 149  
 150    //  Simulate focus and blur in old versions of IE using focusin and focusout
 151    //  TODO: Document the gigantic IE mess here with focus/blur.
 152    //  TODO: beforeactivate/beforedeactivate?
 153    //  http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
 154    if (!has_add_event_listener) {
 155      document_events.push('focusin', 'focusout');
 156    }
 157  
 158    //  Opera is multilol: it propagates focus / blur oddly
 159    if (window.opera) {
 160      document_events.push('focus', 'blur');
 161    }
 162  
 163    if (__DEV__) {
 164      JX.__allowedEvents = {};
 165      if ('onpagehide' in window) {
 166        JX.__allowedEvents.unload = true;
 167      }
 168    }
 169  
 170    var ii;
 171    for (ii = 0; ii < document_events.length; ++ii) {
 172      JX.enableDispatch(root, document_events[ii]);
 173    }
 174  
 175    //  In particular, we're interested in capturing window focus/blur here so
 176    //  long polls can abort when the window is not focused.
 177    var window_events = [
 178      ('onpagehide' in window) ? 'pagehide' : 'unload',
 179      'resize',
 180      'scroll',
 181      'focus',
 182      'blur',
 183      'popstate',
 184      'hashchange'
 185    ];
 186  
 187  
 188    for (ii = 0; ii < window_events.length; ++ii) {
 189      JX.enableDispatch(window, window_events[ii]);
 190    }
 191  
 192    JX.__simulate = function(node, event) {
 193      if (!has_add_event_listener) {
 194        var e = {target: node, type: event};
 195        JX.__rawEventQueue(e);
 196        if (e.returnValue === false) {
 197          return false;
 198        }
 199      }
 200    };
 201  
 202    if (has_add_event_listener) {
 203      document.addEventListener('DOMContentLoaded', function() {
 204        JX.__rawEventQueue({type: 'domready'});
 205      }, true);
 206    } else {
 207      var ready =
 208        "if (this.readyState == 'complete') {" +
 209          "JX.__rawEventQueue({type: 'domready'});" +
 210        "}";
 211  
 212      // NOTE: Don't write a 'src' attribute, because "javascript:void(0)" causes
 213      // a mixed content warning in IE8 if the page is served over SSL.
 214      document.write(
 215        '<script' +
 216        ' defer="defer"' +
 217        ' onreadystatechange="' + ready + '"' +
 218        '><\/sc' + 'ript' + '>');
 219    }
 220  
 221    JX.onload = function(func) {
 222      if (loaded) {
 223        func();
 224      } else {
 225        onload.push(func);
 226      }
 227    };
 228  
 229  })();


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1