detect-global.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // https://github.com/kangax/detect-global
  2. // tweaked to run without a UI.
  3. (function () {
  4. function getPropertyDescriptors(object) {
  5. var props = { };
  6. for (var prop in object) {
  7. // nerfing for firefox who goes crazy over some objects like sessionStorage
  8. try {
  9. props[prop] = {
  10. type: typeof object[prop],
  11. value: object[prop]
  12. };
  13. } catch(e){
  14. props[prop] = {};
  15. }
  16. }
  17. return props;
  18. }
  19. function getCleanWindow() {
  20. var elIframe = document.createElement('iframe');
  21. elIframe.style.display = 'none';
  22. var ref = document.getElementsByTagName('script')[0];
  23. ref.parentNode.insertBefore(elIframe, ref);
  24. elIframe.src = 'about:blank';
  25. return elIframe.contentWindow;
  26. }
  27. function appendControl(el, name) {
  28. var elCheckbox = document.createElement('input');
  29. elCheckbox.type = 'checkbox';
  30. elCheckbox.checked = true;
  31. elCheckbox.id = '__' + name;
  32. var elLabel = document.createElement('label');
  33. elLabel.htmlFor = '__' + name;
  34. elLabel.innerHTML = 'Exclude ' + name + ' properties?';
  35. elLabel.style.marginLeft = '0.5em';
  36. var elWrapper = document.createElement('p');
  37. elWrapper.style.marginBottom = '0.5em';
  38. elWrapper.appendChild(elCheckbox);
  39. elWrapper.appendChild(elLabel);
  40. el.appendChild(elWrapper);
  41. }
  42. function appendAnalyze(el) {
  43. var elAnalyze = document.createElement('button');
  44. elAnalyze.id = '__analyze';
  45. elAnalyze.innerHTML = 'Analyze';
  46. elAnalyze.style.marginTop = '1em';
  47. el.appendChild(elAnalyze);
  48. }
  49. function appendCancel(el) {
  50. var elCancel = document.createElement('a');
  51. elCancel.href = '#';
  52. elCancel.innerHTML = 'Cancel';
  53. elCancel.style.cssText = 'color:#eee;margin-left:0.5em;';
  54. elCancel.onclick = function() {
  55. el.parentNode.removeChild(el);
  56. return false;
  57. };
  58. el.appendChild(elCancel);
  59. }
  60. function initConfigPopup() {
  61. var el = document.createElement('div');
  62. el.style.cssText = 'position:fixed; left:10px; top:10px; width:300px; background:rgba(50,50,50,0.9);' +
  63. '-moz-border-radius:10px; padding:1em; color: #eee; text-align: left;' +
  64. 'font-family: "Helvetica Neue", Verdana, Arial, sans serif; z-index: 99999;';
  65. for (var prop in propSets) {
  66. appendControl(el, prop);
  67. }
  68. appendAnalyze(el);
  69. appendCancel(el);
  70. var ref = document.getElementsByTagName('script')[0];
  71. ref.parentNode.insertBefore(el, ref);
  72. }
  73. function getPropsCount(object) {
  74. var count = 0;
  75. for (var prop in object) {
  76. count++;
  77. }
  78. return count;
  79. }
  80. function shouldDeleteProperty(propToCheck) {
  81. for (var prop in propSets) {
  82. var elCheckbox = document.getElementById('__' + prop);
  83. var isPropInSet = propSets[prop].indexOf(propToCheck) > -1;
  84. if (isPropInSet && (elCheckbox ? elCheckbox.checked : true) ) {
  85. return true;
  86. }
  87. }
  88. }
  89. function analyze() {
  90. var global = (function(){ return this; })(),
  91. globalProps = getPropertyDescriptors(global),
  92. cleanWindow = getCleanWindow();
  93. for (var prop in cleanWindow) {
  94. if (globalProps[prop]) {
  95. delete globalProps[prop];
  96. }
  97. }
  98. for (var prop in globalProps) {
  99. if (shouldDeleteProperty(prop)) {
  100. delete globalProps[prop];
  101. }
  102. }
  103. window.__globalsCount = getPropsCount(globalProps);
  104. window.__globals = globalProps;
  105. window.console && console.log('Total number of global properties: ' + __globalsCount);
  106. window.console && console.dir(__globals);
  107. }
  108. var propSets = {
  109. 'Prototype': '$$ $A $F $H $R $break $continue $w Abstract Ajax Class Enumerable Element Field Form ' +
  110. 'Hash Insertion ObjectRange PeriodicalExecuter Position Prototype Selector Template Toggle Try'.split(' '),
  111. 'Scriptaculous': 'Autocompleter Builder Control Draggable Draggables Droppables Effect Sortable SortableObserver Sound Scriptaculous'.split(' '),
  112. 'Firebug': 'loadFirebugConsole console _getFirebugConsoleElement _FirebugConsole _FirebugCommandLine _firebug'.split(' '),
  113. 'Mozilla': 'Components XPCNativeWrapper XPCSafeJSObjectWrapper getInterface netscape GetWeakReference GeckoActiveXObject'.split(' '),
  114. 'GoogleAnalytics': 'gaJsHost gaGlobal _gat _gaq pageTracker'.split(' '),
  115. 'lazyGlobals': 'onhashchange'.split(' ')
  116. };
  117. // initConfigPopup(); // disable because we're going UI-less.
  118. var analyzeElem = document.getElementById('__analyze');
  119. analyzeElem && (analyzeElem.onclick = analyze);
  120. analyze(); // and assign total added globals to window.__globalsCount
  121. })();