import _ from 'underscore';
import {log, debugMode} from '../base';
/**
 * Browser feature detection.
 *
 * @since 0.9
 */
export const browser = (function(){
  var tests = {},
      results = {};

  let ready;
  let readyPromise = new Promise(function(resolve) {
    ready = resolve;
  });


  return {
    off: {},
    on: {},
    unset: {},

    /**
     * Add a feature test.
     *
     * @param name [String] Name of the feature. Can contain whitespace.
     * @param test [Function] A function that either returns `true` or
     *   `false` or a promise that resolves to `true` or `false`.
     * @memberof pageflow.browser
     */
    feature: function(name, test) {
      var s = name.replace(/ /g, '_');

      this.off[s] = function() {
        window.localStorage['override ' + name] = 'off';
        log('Feature off: ' + name, {force: true});
      };

      this.on[s] = function() {
        window.localStorage['override ' + name] = 'on';
        log('Feature on: ' + name, {force: true});
      };

      this.unset[s] = function() {
        window.localStorage.removeItem('override ' + name);
        log('Feature unset: ' + name, {force: true});
      };

      tests[name] = test;
    },

    /**
     * Check whether the browser has a specific feature. This method
     * may only be called after the `#ready` promise is resolved.
     *
     * @param name [String] Name of the feature.
     * @return [Boolean]
     * @memberof pageflow.browser
     */
    has: function(name) {
      if (this.ready().state() != 'resolved') {
        throw 'Feature detection has not finished yet.';
      }

      if (results[name] === undefined) {
        throw 'Unknown feature "' + name +'".';
      }

      return results[name];
    },

    /**
     * A promise that is resolved once feature detection has finished.
     *
     * @return Promise
     * @memberof pageflow.browser
     */
    ready: function() {
      return readyPromise;
    },

    /** @api private */
    detectFeatures: function() {
      var promises = {};

      var asyncHas = function(name) {
        var runTest = function() {
          var value, underscoredName = name.replace(/ /g, '_');

          if (debugMode() && location.href.indexOf('&has=' + underscoredName) >= 0) {
            value = location.href.indexOf('&has=' + underscoredName + '_on') >= 0;
            log('FEATURE OVERRIDDEN ' + name + ': ' + value, {force: true});
            return value;
          }
          else if ((debugMode() || window.PAGEFLOW_ALLOW_FEATURE_OVERRIDES) &&
                   window.localStorage &&
                   typeof window.localStorage['override ' + name] !== 'undefined') {
            value = (window.localStorage['override ' + name] === 'on');
            log('FEATURE OVERRIDDEN ' + name + ': ' + value, {force: true});
            return value;
          }
          else {
            return tests[name](asyncHas);
          }
        };

        promises[name] = promises[name] || Promise.all([runTest(name)]);
        return promises[name];
      };

      asyncHas.not = function(name) {
        return asyncHas(name).pipe(function(result) {
          return !result;
        });
      };

      asyncHas.all = function(/* arguments */) {
        return Promise.resolve().apply(null, arguments).pipe(function(/* arguments */) {
          return _.all(arguments);
        });
      };

      Promise.resolve().apply(null, _.map(_.keys(tests), function(name) {
        return asyncHas(name).then(function(result) {
          var cssClassName = name.replace(/ /g, '_');

          // TODO: Replace $
          $('body').toggleClass('has_' + cssClassName, !!result);
          $('body').toggleClass('has_no_' + cssClassName, !result);

          results[name] = !!result;
        });
      })).then(ready());

      return this.ready();
    }
  };
}());

@@ -192,22 +192,76 @@
 = %7B%7D
-;%0A%0A  let ready
+,%0A      featureDetectionComplete = false;%0A%0A  let readyPromiseResolve
 ;%0A  
@@ -307,16 +307,24 @@
 (resolve
+, reject
 ) %7B%0A    
@@ -328,16 +328,30 @@
    ready
+PromiseResolve
  = resol
@@ -361,17 +361,16 @@
 %0A  %7D);%0A%0A
-%0A
   return
@@ -1583,42 +1583,33 @@
 if (
-this.ready().state() != 'resolved'
+!featureDetectionComplete
 ) %7B%0A
@@ -3070,16 +3070,43 @@
 (name)%5D)
+.then((a) =%3E %7Breturn a%5B0%5D%7D)
 ;%0A      
@@ -3208,20 +3208,20 @@
 s(name).
-pipe
+then
 (functio
@@ -3352,38 +3352,20 @@
 Promise.
-resolve().apply(null, 
+all(
 argument
@@ -3371,12 +3371,12 @@
 ts).
-pipe
+then
 (fun
@@ -3377,39 +3377,31 @@
 en(function(
-/* arguments */
+results
 ) %7B%0A        
@@ -3415,23 +3415,21 @@
 n _.all(
-argumen
+resul
 ts);%0A   
@@ -3465,30 +3465,12 @@
 ise.
-resolve().apply(null, 
+all(
 _.ma
@@ -3626,58 +3626,38 @@
     
-// TODO: Replace $%0A          $('body')
+document.body.classList
 .toggle
-Class
 ('ha
@@ -3685,17 +3685,16 @@
 !result)
-;
 %0A       
@@ -3700,29 +3700,38 @@
     
-$('body')
+document.body.classList
 .toggle
-Class
 ('ha
@@ -3761,17 +3761,16 @@
 !result)
-;
 %0A%0A      
@@ -3826,23 +3826,103 @@
 )).then(
-ready()
+() =%3E %7B%0A        featureDetectionComplete = true;%0A        readyPromiseResolve();%0A      %7D
 );%0A%0A    

Refactor browser.js to vanilla JS