Advertisement
Guest User

Untitled

a guest
Sep 26th, 2015
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //! ng-stats version 2.5.1 built with ♥ by Kent C. Dodds <kent@doddsfamily.us> (http://kent.doddsfamily.us), Viper Bailey <jinxidoru@gmail.com> (http://jinxidoru.blogspot.com), Daniel Lamb <dlamb.open.source@gmail.com> (http://daniellmb.com) (ó ì_í)=óò=(ì_í ò)
  2.  
  3. (function webpackUniversalModuleDefinition(root, factory) {
  4.     if(typeof exports === 'object' && typeof module === 'object')
  5.         module.exports = factory(require("angular"));
  6.     else if(typeof define === 'function' && define.amd)
  7.         define(["angular"], factory);
  8.     else if(typeof exports === 'object')
  9.         exports["showAngularStats"] = factory(require("angular"));
  10.     else
  11.         root["showAngularStats"] = factory(root["angular"]);
  12. })(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {
  13. return /******/ (function(modules) { // webpackBootstrap
  14. /******/    // The module cache
  15. /******/    var installedModules = {};
  16.  
  17. /******/    // The require function
  18. /******/    function __webpack_require__(moduleId) {
  19.  
  20. /******/        // Check if module is in cache
  21. /******/        if(installedModules[moduleId])
  22. /******/            return installedModules[moduleId].exports;
  23.  
  24. /******/        // Create a new module (and put it into the cache)
  25. /******/        var module = installedModules[moduleId] = {
  26. /******/            exports: {},
  27. /******/            id: moduleId,
  28. /******/            loaded: false
  29. /******/        };
  30.  
  31. /******/        // Execute the module function
  32. /******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  33.  
  34. /******/        // Flag the module as loaded
  35. /******/        module.loaded = true;
  36.  
  37. /******/        // Return the exports of the module
  38. /******/        return module.exports;
  39. /******/    }
  40.  
  41.  
  42. /******/    // expose the modules object (__webpack_modules__)
  43. /******/    __webpack_require__.m = modules;
  44.  
  45. /******/    // expose the module cache
  46. /******/    __webpack_require__.c = installedModules;
  47.  
  48. /******/    // __webpack_public_path__
  49. /******/    __webpack_require__.p = "";
  50.  
  51. /******/    // Load entry module and return exports
  52. /******/    return __webpack_require__(0);
  53. /******/ })
  54. /************************************************************************/
  55. /******/ ([
  56. /* 0 */
  57. /***/ function(module, exports, __webpack_require__) {
  58.  
  59.     /* eslint no-console:0 */
  60.     'use strict';
  61.  
  62.     Object.defineProperty(exports, '__esModule', {
  63.       value: true
  64.     });
  65.  
  66.     function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  67.  
  68.     var _angular = __webpack_require__(1);
  69.  
  70.     var _angular2 = _interopRequireDefault(_angular);
  71.  
  72.     var angular = _angular2['default'];
  73.  
  74.     /* istanbul ignore next */
  75.     if (!angular.version) {
  76.       // we're doing this because some versions
  77.       // of angular don't expose itself correctly
  78.       angular = window.angular;
  79.     }
  80.  
  81.     exports['default'] = showAngularStats;
  82.  
  83.     var autoloadKey = 'showAngularStats_autoload';
  84.     var current = null;
  85.     // define the timer function to use based upon whether or not 'performance is available'
  86.     var timerNow = window.self.performance && window.self.performance.now ? function () {
  87.       return window.self.performance.now();
  88.     } : function () {
  89.       return Date.now();
  90.     };
  91.  
  92.     var lastWatchCountRun = timerNow();
  93.     var watchCountTimeout = null;
  94.     var lastWatchCount = getWatcherCount() || 0;
  95.     var lastDigestLength = 0;
  96.     var scopeSelectors = '.ng-scope, .ng-isolate-scope';
  97.     var $rootScope;
  98.  
  99.     var digestIsHijacked = false;
  100.  
  101.     var listeners = {
  102.       watchCount: {},
  103.       digestLength: {}
  104.     };
  105.  
  106.     // Hijack $digest to time it and update data on every digest.
  107.     function hijackDigest() {
  108.       if (digestIsHijacked) {
  109.         return;
  110.       }
  111.       digestIsHijacked = true;
  112.       var scopePrototype = Object.getPrototypeOf(getRootScope());
  113.       var oldDigest = scopePrototype.$digest;
  114.       scopePrototype.$digest = function $digest() {
  115.         var start = timerNow();
  116.         oldDigest.apply(this, arguments);
  117.         var diff = timerNow() - start;
  118.         updateData(getWatcherCount(), diff);
  119.       };
  120.     }
  121.  
  122.     // used to prevent localstorage error in chrome packaged apps
  123.     function isChromeApp() {
  124.       return typeof chrome !== 'undefined' && typeof chrome.storage !== 'undefined' && typeof chrome.storage.local !== 'undefined';
  125.     }
  126.  
  127.     // check for autoload
  128.     var autoloadOptions = sessionStorage[autoloadKey] || !isChromeApp() && localStorage[autoloadKey];
  129.     if (autoloadOptions) {
  130.       autoload(JSON.parse(autoloadOptions));
  131.     }
  132.  
  133.     function autoload(options) {
  134.       if (window.self.angular && getRootScope()) {
  135.         showAngularStats(options);
  136.       } else {
  137.         // wait for angular to load...
  138.         window.self.setTimeout(function () {
  139.           autoload(options);
  140.         }, 200);
  141.       }
  142.     }
  143.  
  144.     function initOptions(opts) {
  145.  
  146.       // Remove autoload if they did not specifically request it
  147.       if (opts === false || !opts.autoload) {
  148.         sessionStorage.removeItem(autoloadKey);
  149.         localStorage.removeItem(autoloadKey);
  150.         // do nothing if the argument is false
  151.         if (opts === false) {
  152.           return;
  153.         }
  154.       }
  155.  
  156.       opts.position = opts.position || 'top-left';
  157.       opts = angular.extend({
  158.         htmlId: null,
  159.         rootScope: undefined,
  160.         digestTimeThreshold: 16,
  161.         watchCountThreshold: 2000,
  162.         autoload: false,
  163.         trackDigest: false,
  164.         trackWatches: false,
  165.         logDigest: false,
  166.         logWatches: false,
  167.         styles: {
  168.           position: 'fixed',
  169.           background: 'black',
  170.           borderBottom: '1px solid #666',
  171.           borderRight: '1px solid #666',
  172.           color: '#666',
  173.           fontFamily: 'Courier',
  174.           width: 130,
  175.           zIndex: 9999,
  176.           textAlign: 'right',
  177.           top: opts.position.indexOf('top') === -1 ? null : 0,
  178.           bottom: opts.position.indexOf('bottom') === -1 ? null : 0,
  179.           right: opts.position.indexOf('right') === -1 ? null : 0,
  180.           left: opts.position.indexOf('left') === -1 ? null : 0
  181.         }
  182.       }, opts || {});
  183.  
  184.       // for ionic support
  185.       if (opts.rootScope) {
  186.         $rootScope = opts.rootScope;
  187.       }
  188.  
  189.       return opts;
  190.     }
  191.  
  192.     function showAngularStats(opts) {
  193.       /* eslint max-statements:[2, 45] */
  194.       /* eslint complexity:[2, 18] */
  195.       /* eslint consistent-return:0 */
  196.       // TODO ^^ fix these things...
  197.       opts = opts !== undefined ? opts : {};
  198.       var returnData = {
  199.         listeners: listeners
  200.       };
  201.       // delete the previous one
  202.       if (current) {
  203.         current.$el && current.$el.remove();
  204.         current.active = false;
  205.         current = null;
  206.       }
  207.  
  208.       // Implemented in separate function due to webpack's statement count limit
  209.       opts = initOptions(opts);
  210.  
  211.       hijackDigest();
  212.  
  213.       // setup the state
  214.       var state = current = { active: true };
  215.  
  216.       // auto-load on startup
  217.       if (opts.autoload) {
  218.         if (opts.autoload === 'localStorage') {
  219.           localStorage.setItem(autoloadKey, JSON.stringify(opts));
  220.         } else if (opts.autoload === 'sessionStorage' || typeof opts.autoload === 'boolean') {
  221.           sessionStorage.setItem(autoloadKey, JSON.stringify(opts));
  222.         } else {
  223.           throw new Error('Invalid value for autoload: ' + opts.autoload + ' can only be "localStorage" "sessionStorage" or boolean.');
  224.         }
  225.       }
  226.  
  227.       // general variables
  228.       var bodyEl = angular.element(document.body);
  229.       var noDigestSteps = 0;
  230.  
  231.       // add the DOM element
  232.       var htmlId = opts.htmlId ? ' id="' + opts.htmlId + '"' : '';
  233.       state.$el = angular.element('<div' + htmlId + '><canvas></canvas><div><span></span> | <span></span></div></div>').css(opts.styles);
  234.       bodyEl.append(state.$el);
  235.       var $watchCount = state.$el.find('span');
  236.       var $digestTime = $watchCount.next();
  237.  
  238.       // initialize the canvas
  239.       var graphSz = { width: 130, height: 40 };
  240.       var cvs = state.$el.find('canvas').attr(graphSz)[0];
  241.  
  242.       // add listeners
  243.       listeners.digestLength.ngStatsAddToCanvas = function (digestLength) {
  244.         addDataToCanvas(null, digestLength);
  245.       };
  246.  
  247.       listeners.watchCount.ngStatsAddToCanvas = function (watchCount) {
  248.         addDataToCanvas(watchCount);
  249.       };
  250.  
  251.       track('digest', listeners.digestLength);
  252.       track('watches', listeners.watchCount, true);
  253.  
  254.       log('digest', listeners.digestLength);
  255.       log('watches', listeners.watchCount, true);
  256.  
  257.       function track(thingToTrack, listenerCollection, diffOnly) {
  258.         var capThingToTrack = thingToTrack.charAt(0).toUpperCase() + thingToTrack.slice(1);
  259.         if (opts['track' + capThingToTrack]) {
  260.           returnData[thingToTrack] = [];
  261.           listenerCollection['track + capThingToTrack'] = function (tracked) {
  262.             if (!diffOnly || returnData[thingToTrack][returnData.length - 1] !== tracked) {
  263.               returnData[thingToTrack][returnData.length - 1] = tracked;
  264.               returnData[thingToTrack].push(tracked);
  265.             }
  266.           };
  267.         }
  268.       }
  269.  
  270.       function log(thingToLog, listenerCollection, diffOnly) {
  271.         var capThingToLog = thingToLog.charAt(0).toUpperCase() + thingToLog.slice(1);
  272.         if (opts['log' + capThingToLog]) {
  273.           var last;
  274.           listenerCollection['log' + capThingToLog] = function (tracked) {
  275.             if (!diffOnly || last !== tracked) {
  276.               last = tracked;
  277.               var color = colorLog(thingToLog, tracked);
  278.               if (color) {
  279.                 console.log('%c' + thingToLog + ':', color, tracked);
  280.               } else {
  281.                 console.log(thingToLog + ':', tracked);
  282.               }
  283.             }
  284.           };
  285.         }
  286.       }
  287.  
  288.       function getColor(metric, threshold) {
  289.         if (metric > threshold) {
  290.           return 'red';
  291.         } else if (metric > 0.7 * threshold) {
  292.           return 'orange';
  293.         }
  294.         return 'green';
  295.       }
  296.  
  297.       function colorLog(thingToLog, tracked) {
  298.         var color;
  299.         if (thingToLog === 'digest') {
  300.           color = 'color:' + getColor(tracked, opts.digestTimeThreshold);
  301.         } else if (thingToLog === 'watches') {
  302.           color = 'color:' + getColor(tracked, opts.watchCountThreshold);
  303.         }
  304.         return color;
  305.       }
  306.  
  307.       function addDataToCanvas(watchCount, digestLength) {
  308.         var averageDigest = digestLength || lastDigestLength;
  309.         var digestColor = getColor(averageDigest, opts.digestTimeThreshold);
  310.         lastWatchCount = nullOrUndef(watchCount) ? lastWatchCount : watchCount;
  311.         var watchColor = getColor(lastWatchCount, opts.watchCountThreshold);
  312.         lastDigestLength = nullOrUndef(digestLength) ? lastDigestLength : digestLength;
  313.         $watchCount.text(lastWatchCount).css({ color: watchColor });
  314.         $digestTime.text(lastDigestLength.toFixed(2)).css({ color: digestColor });
  315.  
  316.         if (!digestLength) {
  317.           return;
  318.         }
  319.  
  320.         // color the sliver if this is the first step
  321.         var ctx = cvs.getContext('2d');
  322.         if (noDigestSteps > 0) {
  323.           noDigestSteps = 0;
  324.           ctx.fillStyle = '#333';
  325.           ctx.fillRect(graphSz.width - 1, 0, 1, graphSz.height);
  326.         }
  327.  
  328.         // mark the point on the graph
  329.         ctx.fillStyle = digestColor;
  330.         ctx.fillRect(graphSz.width - 1, Math.max(0, graphSz.height - averageDigest), 2, 2);
  331.       }
  332.  
  333.       // Shift the canvas to the left.
  334.       function shiftLeft() {
  335.         if (state.active) {
  336.           window.self.setTimeout(shiftLeft, 250);
  337.           var ctx = cvs.getContext('2d');
  338.           var imageData = ctx.getImageData(1, 0, graphSz.width - 1, graphSz.height);
  339.           ctx.putImageData(imageData, 0, 0);
  340.           ctx.fillStyle = noDigestSteps++ > 2 ? 'black' : '#333';
  341.           ctx.fillRect(graphSz.width - 1, 0, 1, graphSz.height);
  342.         }
  343.       }
  344.  
  345.       // start everything
  346.       shiftLeft();
  347.       if (!$rootScope.$$phase) {
  348.         $rootScope.$digest();
  349.       }
  350.  
  351.       return returnData;
  352.     }
  353.  
  354.     angular.module('angularStats', []).directive('angularStats', function () {
  355.       var index = 1;
  356.       return {
  357.         scope: {
  358.           digestLength: '@',
  359.           watchCount: '@',
  360.           watchCountRoot: '@',
  361.           onDigestLengthUpdate: '&?',
  362.           onWatchCountUpdate: '&?'
  363.         },
  364.         link: function link(scope, el, attrs) {
  365.           hijackDigest();
  366.           var directiveIndex = index++;
  367.  
  368.           setupDigestLengthElement();
  369.           setupWatchCountElement();
  370.           addWatchCountListener();
  371.           addDigestLengthListener();
  372.           scope.$on('$destroy', destroyListeners);
  373.  
  374.           function setupDigestLengthElement() {
  375.             if (attrs.hasOwnProperty('digestLength')) {
  376.               var digestEl = el;
  377.               if (attrs.digestLength) {
  378.                 digestEl = angular.element(el[0].querySelector(attrs.digestLength));
  379.               }
  380.               listeners.digestLength['ngStatsDirective' + directiveIndex] = function (length) {
  381.                 window.dirDigestNode = digestEl[0];
  382.                 digestEl.text((length || 0).toFixed(2));
  383.               };
  384.             }
  385.           }
  386.  
  387.           function setupWatchCountElement() {
  388.             if (attrs.hasOwnProperty('watchCount')) {
  389.               var watchCountRoot;
  390.               var watchCountEl = el;
  391.               if (scope.watchCount) {
  392.                 watchCountEl = angular.element(el[0].querySelector(attrs.watchCount));
  393.               }
  394.  
  395.               if (scope.watchCountRoot) {
  396.                 if (scope.watchCountRoot === 'this') {
  397.                   watchCountRoot = el;
  398.                 } else {
  399.                   // In the case this directive is being compiled and it's not in the dom,
  400.                   // we're going to do the find from the root of what we have...
  401.                   var rootParent;
  402.                   if (attrs.hasOwnProperty('watchCountOfChild')) {
  403.                     rootParent = el[0];
  404.                   } else {
  405.                     rootParent = findRootOfElement(el);
  406.                   }
  407.                   watchCountRoot = angular.element(rootParent.querySelector(scope.watchCountRoot));
  408.                   if (!watchCountRoot.length) {
  409.                     throw new Error('no element at selector: ' + scope.watchCountRoot);
  410.                   }
  411.                 }
  412.               }
  413.  
  414.               listeners.watchCount['ngStatsDirective' + directiveIndex] = function (count) {
  415.                 var watchCount = count;
  416.                 if (watchCountRoot) {
  417.                   watchCount = getWatcherCountForElement(watchCountRoot);
  418.                 }
  419.                 watchCountEl.text(watchCount);
  420.               };
  421.             }
  422.           }
  423.  
  424.           function addWatchCountListener() {
  425.             if (attrs.hasOwnProperty('onWatchCountUpdate')) {
  426.               listeners.watchCount['ngStatsDirectiveUpdate' + directiveIndex] = function (count) {
  427.                 scope.onWatchCountUpdate({ watchCount: count });
  428.               };
  429.             }
  430.           }
  431.  
  432.           function addDigestLengthListener() {
  433.             if (attrs.hasOwnProperty('onDigestLengthUpdate')) {
  434.               listeners.digestLength['ngStatsDirectiveUpdate' + directiveIndex] = function (length) {
  435.                 scope.onDigestLengthUpdate({ digestLength: length });
  436.               };
  437.             }
  438.           }
  439.  
  440.           function destroyListeners() {
  441.             delete listeners.digestLength['ngStatsDirectiveUpdate' + directiveIndex];
  442.             delete listeners.watchCount['ngStatsDirectiveUpdate' + directiveIndex];
  443.             delete listeners.digestLength['ngStatsDirective' + directiveIndex];
  444.             delete listeners.watchCount['ngStatsDirective' + directiveIndex];
  445.           }
  446.         }
  447.       };
  448.  
  449.       function findRootOfElement(el) {
  450.         var parent = el[0];
  451.         while (parent.parentElement) {
  452.           parent = parent.parentElement;
  453.         }
  454.         return parent;
  455.       }
  456.     });
  457.  
  458.     // UTILITY FUNCTIONS
  459.  
  460.     function getRootScope() {
  461.       if ($rootScope) {
  462.         return $rootScope;
  463.       }
  464.       var scopeEl = document.querySelector(scopeSelectors);
  465.       if (!scopeEl) {
  466.         return null;
  467.       }
  468.       $rootScope = angular.element(scopeEl).scope().$root;
  469.       return $rootScope;
  470.     }
  471.  
  472.     // Uses timeouts to ensure that this is only run every 300ms (it's a perf bottleneck)
  473.     function getWatcherCount() {
  474.       window.self.clearTimeout(watchCountTimeout);
  475.       var now = timerNow();
  476.       if (now - lastWatchCountRun > 300) {
  477.         lastWatchCountRun = now;
  478.         lastWatchCount = getWatcherCountForScope();
  479.       } else {
  480.         watchCountTimeout = window.self.setTimeout(function () {
  481.           updateData(getWatcherCount());
  482.         }, 350);
  483.       }
  484.       return lastWatchCount;
  485.     }
  486.  
  487.     function getWatcherCountForElement(element) {
  488.       var startingScope = getClosestChildScope(element);
  489.       return getWatcherCountForScope(startingScope);
  490.     }
  491.  
  492.     function getClosestChildScope(element) {
  493.       element = angular.element(element);
  494.       var scope = element.scope();
  495.       if (!scope) {
  496.         element = angular.element(element.querySelector(scopeSelectors));
  497.         scope = element.scope();
  498.       }
  499.       return scope;
  500.     }
  501.  
  502.     function getWatchersFromScope(scope) {
  503.       return scope && scope.$$watchers ? scope.$$watchers : [];
  504.     }
  505.  
  506.     // iterate through listeners to call them with the watchCount and digestLength
  507.     function updateData(watchCount, digestLength) {
  508.       // update the listeners
  509.       if (!nullOrUndef(watchCount)) {
  510.         angular.forEach(listeners.watchCount, function (listener) {
  511.           listener(watchCount);
  512.         });
  513.       }
  514.       if (!nullOrUndef(digestLength)) {
  515.         angular.forEach(listeners.digestLength, function (listener) {
  516.           listener(digestLength);
  517.         });
  518.       }
  519.     }
  520.  
  521.     function nullOrUndef(item) {
  522.       return item === null || item === undefined;
  523.     }
  524.  
  525.     function getWatcherCountForScope(scope) {
  526.       var count = 0;
  527.       iterateScopes(scope, function (childScope) {
  528.         count += getWatchersFromScope(childScope).length;
  529.       });
  530.       return count;
  531.     }
  532.  
  533.     function iterateScopes(currentScope, fn) {
  534.       if (typeof currentScope === 'function') {
  535.         fn = currentScope;
  536.         currentScope = null;
  537.       }
  538.       currentScope = currentScope || getRootScope();
  539.       currentScope = _makeScopeReference(currentScope);
  540.       if (!currentScope) {
  541.         return;
  542.       }
  543.       var ret = fn(currentScope);
  544.       if (ret === false) {
  545.         return ret;
  546.       }
  547.       return iterateChildren(currentScope, fn);
  548.     }
  549.  
  550.     function iterateSiblings(start, fn) {
  551.       var ret;
  552.       /* eslint no-extra-boolean-cast:0 */
  553.       while (!!(start = start.$$nextSibling)) {
  554.         ret = fn(start);
  555.         if (ret === false) {
  556.           break;
  557.         }
  558.  
  559.         ret = iterateChildren(start, fn);
  560.         if (ret === false) {
  561.           break;
  562.         }
  563.       }
  564.       return ret;
  565.     }
  566.  
  567.     function iterateChildren(start, fn) {
  568.       var ret;
  569.       while (!!(start = start.$$childHead)) {
  570.         ret = fn(start);
  571.         if (ret === false) {
  572.           break;
  573.         }
  574.  
  575.         ret = iterateSiblings(start, fn);
  576.         if (ret === false) {
  577.           break;
  578.         }
  579.       }
  580.       return ret;
  581.     }
  582.  
  583.     function getScopeById(id) {
  584.       var myScope = null;
  585.       iterateScopes(function (scope) {
  586.         if (scope.$id === id) {
  587.           myScope = scope;
  588.           return false;
  589.         }
  590.       });
  591.       return myScope;
  592.     }
  593.  
  594.     function _makeScopeReference(scope) {
  595.       if (_isScopeId(scope)) {
  596.         scope = getScopeById(scope);
  597.       }
  598.       return scope;
  599.     }
  600.  
  601.     function _isScopeId(scope) {
  602.       return typeof scope === 'string' || typeof scope === 'number';
  603.     }
  604.     module.exports = exports['default'];
  605.  
  606. /***/ },
  607. /* 1 */
  608. /***/ function(module, exports) {
  609.  
  610.     module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
  611.  
  612. /***/ }
  613. /******/ ])
  614. });
  615. ;
  616. window.showAngularStats();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement