PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/javascripts/d3/detector.js

https://github.com/CBasis/CodeFlower
JavaScript | 438 lines | 383 code | 30 blank | 25 comment | 121 complexity | 7ff966a304c38277467dca380bb26a93 MD5 | raw file
  1. /**
  2. * Chrome AppSniffer
  3. *
  4. * Detect apps run on current page and send back to background page.
  5. * Some part of this script was refered from Wappalyzer Firefox Addon.
  6. *
  7. * @author Bao Nguyen <contact@nqbao.com>
  8. * @license GPLv3
  9. **/
  10. (function () {
  11. var _apps = {};
  12. var doc = document.documentElement;
  13. var a
  14. // 1: detect by meta tags, the first matching group will be version
  15. var metas = doc.getElementsByTagName("meta");
  16. var meta_tests = {
  17. 'generator': {
  18. 'Joomla': /joomla!?\s*([\d\.]+)?/i,
  19. 'vBulletin': /vBulletin\s*(.*)/i,
  20. 'WordPress': /WordPress\s*(.*)/i,
  21. 'XOOPS': /xoops/i,
  22. 'Plone': /plone/i,
  23. 'MediaWiki': /MediaWiki/i,
  24. 'CMSMadeSimple': /CMS Made Simple/i,
  25. 'SilverStripe': /SilverStripe/i,
  26. 'Movable Type': /Movable Type/i,
  27. 'Amiro.CMS': /Amiro/i,
  28. 'Koobi': /koobi/i,
  29. 'bbPress': /bbPress/i,
  30. 'DokuWiki': /dokuWiki/i,
  31. 'TYPO3': /TYPO3/i,
  32. 'PHP-Nuke': /PHP-Nuke/i,
  33. 'DotNetNuke': /DotNetNuke/i,
  34. 'Sitefinity': /Sitefinity\s+(.*)/i,
  35. 'WebGUI': /WebGUI/i,
  36. 'ez Publish': /eZ\s*Publish/i,
  37. 'BIGACE': /BIGACE/i,
  38. 'TypePad': /typepad\.com/i,
  39. 'Blogger': /blogger/i,
  40. 'PrestaShop': /PrestaShop/i,
  41. 'SharePoint': /SharePoint/,
  42. 'JaliosJCMS': /Jalios JCMS/i,
  43. 'ZenCart': /zen-cart/i,
  44. 'WPML': /WPML/i,
  45. 'PivotX': /PivotX/i,
  46. 'OpenACS': /OpenACS/i,
  47. 'AlphaCMS': /alphacms\s+(.*)/i,
  48. 'concrete5': /concrete5 -\s*(.*)$/,
  49. 'Webnode': /Webnode/,
  50. 'GetSimple': /GetSimple/,
  51. 'DataLifeEngine': /DataLife Engine/,
  52. 'ClanSphere': /ClanSphere/,
  53. },
  54. 'copyright': {
  55. 'phpBB': /phpBB/i
  56. },
  57. 'elggrelease': {
  58. 'Elgg': /.+/
  59. },
  60. 'powered-by': {
  61. 'Serendipity': /Serendipity/i,
  62. },
  63. 'author': {
  64. 'Avactis': /Avactis Team/i
  65. }
  66. };
  67. for (var idx in metas)
  68. {
  69. var m = metas[idx];
  70. var name = m.name ? m.name.toLowerCase() : "";
  71. if (!meta_tests[name]) continue;
  72. for (var t in meta_tests[name])
  73. {
  74. if (t in _apps) continue;
  75. var r = meta_tests[name][t].exec(m.content);
  76. if (r)
  77. {
  78. _apps[t] = r[1] ? r[1] : -1;
  79. }
  80. }
  81. }
  82. // 2: detect by script tags
  83. var scripts = doc.getElementsByTagName("script");
  84. var script_tests = {
  85. 'Google Analytics': /google-analytics.com\/(ga|urchin).js/i,
  86. 'Quantcast': /quantserve\.com\/quant\.js/i,
  87. 'Prototype': /prototype\.js/i,
  88. 'Joomla': /\/components\/com_/,
  89. 'Ubercart': /uc_cart/i,
  90. 'Closure': /\/goog\/base\.js/i,
  91. 'MODx': /\/min\/b=.*f=.*/,
  92. 'MooTools': /mootools/i,
  93. 'Dojo': /dojo(\.xd)?\.js/i,
  94. 'script.aculo.us': /scriptaculous\.js/i,
  95. 'Disqus': /disqus.com\/forums/i,
  96. 'GetSatisfaction': /getsatisfaction\.com\/feedback/i,
  97. 'Wibiya': /wibiya\.com\/Loaders\//i,
  98. 'reCaptcha': /(google\.com\/recaptcha|api\.recaptcha\.net\/)/i,
  99. 'Mollom': /mollom\/mollom\.js/i, // only work on Drupal now
  100. 'ZenPhoto': /zp-core\/js/i,
  101. 'Gallery2': /main\.php\?.*g2_.*/i,
  102. 'AdSense': /pagead\/show_ads\.js/,
  103. 'XenForo': /js\/xenforo\//i,
  104. 'Cappuccino': /Frameworks\/Objective-J\/Objective-J\.js/,
  105. 'Avactis': /\/avactis-themes\//i,
  106. 'Volusion': /a\/j\/javascripts\.js/,
  107. 'AddThis': /addthis\.com\/js/,
  108. 'BuySellAds': /buysellads.com\/.*bsa\.js/,
  109. 'Weebly': /weebly\.com\/weebly\//,
  110. 'Bootstrap': /bootstrap-.*\.js/,
  111. 'Jigsy': /javascripts\/asterion\.js/, // may change later
  112. 'Yola': /analytics\.yola\.net/, // may change later
  113. 'Alfresco': /(alfresco)+(-min)?(\/scripts\/menu)?\.js/ // both Alfresco Share and Explorer apps
  114. };
  115. for (var idx in scripts)
  116. {
  117. var s = scripts[idx];
  118. if (!s.src) continue;
  119. s = s.src;
  120. for (var t in script_tests)
  121. {
  122. if (t in _apps) continue;
  123. if (script_tests[t].test(s))
  124. {
  125. _apps[t] = -1;
  126. }
  127. }
  128. }
  129. // 3: detect by domains
  130. // 4: detect by regexp
  131. var text = document.documentElement.outerHTML;
  132. var text_tests = {
  133. 'SMF': /<script .+\s+var smf_/i,
  134. 'Magento': /var BLANK_URL = '[^>]+js\/blank\.html'/i,
  135. 'Tumblr': /<iframe src=("|')http:\/\/\S+\.tumblr\.com/i,
  136. 'WordPress': /<link rel=("|')stylesheet("|') [^>]+wp-content/i,
  137. 'Closure': /<script[^>]*>.*goog\.require/i,
  138. 'Liferay': /<script[^>]*>.*LifeRay\.currentURL/i,
  139. 'vBulletin': /vbmenu_control/i,
  140. 'MODx': /(<a[^>]+>Powered by MODx<\/a>|var el= \$\('modxhost'\);|<script type=("|')text\/javascript("|')>var MODX_MEDIA_PATH = "media";)/i,
  141. 'miniBB': /<a href=("|')[^>]+minibb.+\s*<!--End of copyright link/i,
  142. 'PHP-Fusion': /(href|src)=["']?infusions\//i, // @todo: recheck this pattern again
  143. 'OpenX': /(href|src)=["'].*delivery\/(afr|ajs|avw|ck)\.php[^"']*/,
  144. 'GetSatisfaction': /asset_host\s*\+\s*"javascripts\/feedback.*\.js/igm, // better recognization
  145. 'Fatwire': /\/Satellite\?|\/ContentServer\?/,
  146. 'Contao': /powered by (TYPOlight|Contao)/i,
  147. 'Moodle' : /<link[^>]*\/theme\/standard\/styles.php".*>|<link[^>]*\/theme\/styles.php\?theme=.*".*>/,
  148. '1c-bitrix' : /<link[^>]*\/bitrix\/.*?>/i,
  149. 'OpenCMS' : /<link[^>]*\.opencms\..*?>/i,
  150. 'HumansTxt': /<link[^>]*rel=['"]?author['"]?/i,
  151. 'GoogleFontApi': /ref=["']?http:\/\/fonts.googleapis.com\//i,
  152. 'Prostores' : /-legacycss\/Asset">/,
  153. 'osCommerce': /(product_info\.php\?products_id|_eof \/\/-->)/,
  154. 'OpenCart': /index.php\?route=product\/product/,
  155. 'Shibboleth': /<form action="\/idp\/Authn\/UserPassword" method="post">/
  156. };
  157. for (t in text_tests)
  158. {
  159. if (t in _apps) continue;
  160. if (text_tests[t].test(text))
  161. {
  162. _apps[t] = -1;
  163. }
  164. }
  165. // TODO: merge inline detector with version detector
  166. // 5: detect by inline javascript
  167. var js_tests = {
  168. 'Drupal': function() {
  169. return window.Drupal != null;
  170. },
  171. 'TomatoCMS': function() {
  172. return window.Tomato != null;
  173. },
  174. 'MojoMotor': function() {
  175. return window.Mojo != null;
  176. },
  177. 'ErainCart': function() {
  178. return window.fn_register_hooks != null;
  179. },
  180. 'SugarCRM': function() {
  181. return window.SUGAR != null;
  182. },
  183. 'YUI': function() {
  184. return window.YAHOO|window.YUI != null;
  185. },
  186. 'jQuery': function() {
  187. return window.jQuery != null;
  188. },
  189. 'jQuery UI': function() {
  190. return window.jQuery != null && window.jQuery.ui != null;
  191. },
  192. 'Typekit': function() {
  193. return window.Typekit != null;
  194. },
  195. 'Facebook': function() {
  196. return window.FB != null && window.FB.api != null;
  197. },
  198. 'ExtJS': function() {
  199. return window.Ext != null;
  200. },
  201. 'Modernizr': function() {
  202. return window.Modernizr != null;
  203. },
  204. 'Raphael': function() {
  205. return window.Raphael != null;
  206. },
  207. 'Cufon': function() {
  208. return window.Cufon != null;
  209. },
  210. 'sIFR': function() {
  211. return window.sIFR != null;
  212. },
  213. 'Xiti': function() {
  214. return window.xtsite != null && window.xtpage != null;
  215. },
  216. 'Piwik': function() {
  217. return window.Piwik != null;
  218. },
  219. 'IPB': function() {
  220. return window.IPBoard != null;
  221. },
  222. 'MyBB': function() {
  223. return window.MyBB != null;
  224. },
  225. 'Clicky': function() {
  226. return window.clicky != null;
  227. },
  228. 'Woopra': function() {
  229. return window.woopraTracker != null;
  230. },
  231. 'RightJS': function() {
  232. return window.RightJS != null;
  233. },
  234. 'OpenWebAnalytics': function() {
  235. return window.owa_baseUrl != null;
  236. },
  237. 'Prettify': function() {
  238. return window.prettyPrint != null;
  239. },
  240. 'SiteCatalyst': function() {
  241. return window.s_account != null;
  242. },
  243. 'Twitter': function() {
  244. return window.twttr != null;
  245. },
  246. 'Coremetrics': function() {
  247. return window.cmCreatePageviewTag != null;
  248. },
  249. 'Buzz': function() {
  250. return window.google_buzz__base_url != null;
  251. },
  252. 'Plus1': function() {
  253. return window.gapi && window.gapi.plusone;
  254. },
  255. 'Google Loader': function() {
  256. return window.google && window.google.load != null;
  257. },
  258. 'GoogleMapApi': function() {
  259. return window.google && window.google.maps != null;
  260. },
  261. 'Head JS': function() {
  262. return window.head && window.head.js != null;
  263. },
  264. 'SWFObject': function() {
  265. return window.swfobject != null;
  266. },
  267. 'Chitika': function() {
  268. return window.ch_client && window.ch_write_iframe;
  269. },
  270. 'Jimdo': function() {
  271. return window.jimdoData != null;
  272. },
  273. 'Webs': function() {
  274. return window.webs != null;
  275. },
  276. 'Backbone.js': function() {
  277. return window.Backbone && typeof(window.Backbone.sync) === 'function';
  278. },
  279. 'Underscore.js': function() {
  280. return window._ && typeof(window._.identity) === 'function'
  281. && window._.identity('abc') === 'abc';
  282. },
  283. 'Spine': function() {
  284. return window.Spine != null;
  285. }
  286. };
  287. for (t in js_tests)
  288. {
  289. if (t in _apps) continue;
  290. if (js_tests[t]())
  291. {
  292. _apps[t] = -1;
  293. }
  294. }
  295. // 6: detect some script version when available
  296. var js_versions = {
  297. 'Prototype': function() {
  298. if('Prototype' in window && Prototype.Version!=undefined)
  299. return window.Prototype.Version
  300. },
  301. 'script.aculo.us': function() {
  302. if('Scriptaculous' in window && Scriptaculous.Version!=undefined)
  303. return window.Scriptaculous.Version
  304. },
  305. 'jQuery': function() {
  306. if(typeof jQuery == 'function' && jQuery.prototype.jquery!=undefined )
  307. return jQuery.prototype.jquery
  308. },
  309. 'jQuery UI': function() {
  310. if(typeof jQuery == 'function' && jQuery.ui && jQuery.ui.version!=undefined )
  311. return jQuery.ui.version
  312. },
  313. 'Dojo': function() {
  314. if(typeof dojo == 'object' && dojo.version.toString()!=undefined)
  315. return dojo.version
  316. },
  317. 'YUI': function() {
  318. if(typeof YAHOO == 'object' && YAHOO.VERSION!=undefined )
  319. return YAHOO.VERSION
  320. if('YUI' in window && typeof YUI == 'function' && YUI().version!=undefined)
  321. return YUI().version
  322. },
  323. 'MooTools': function() {
  324. if(typeof MooTools == 'object' && MooTools.version!=undefined)
  325. return MooTools.version
  326. },
  327. 'ExtJS': function() {
  328. if(typeof Ext === 'object' && Ext.version!=undefined)
  329. return Ext.version
  330. },
  331. 'RightJS': function() {
  332. if('RightJS' in window && RightJS.version!=undefined)
  333. return RightJS.version
  334. },
  335. 'Modernizr': function() {
  336. if(window.Modernizr != null && Modernizr._version!=undefined)
  337. return Modernizr._version
  338. },
  339. 'Raphael': function() {
  340. if(window.Raphael != null && Raphael.version!=undefined)
  341. return Raphael.version
  342. },
  343. 'Backbone.js': function() {
  344. if (window.Backbone && window.Backbone.VERSION)
  345. return window.Backbone.VERSION;
  346. },
  347. 'Underscore.js': function() {
  348. if (window._ && window._.VERSION)
  349. return window._.VERSION;
  350. },
  351. 'Spine': function() {
  352. if(window.Spine && window.Spine.version)
  353. return window.Spine.version;
  354. }
  355. };
  356. for (a in _apps)
  357. {
  358. if (_apps[a]==-1 && js_versions[a])
  359. {
  360. var r = js_versions[a]()
  361. _apps[a] = r?r:-1
  362. }
  363. }
  364. // 7: detect by header
  365. // @todo
  366. // 8: detect based on built-in database
  367. // @todo
  368. // 9: detect based on defined css classes
  369. var cssClasses = {
  370. 'Bootstrap': ['hero-unit', '.carousel-control', '[class^="icon-"]:last-child']
  371. };
  372. for (t in cssClasses) {
  373. if (t in _apps) continue;
  374. var found = true;
  375. for(css in cssClasses[t]) {
  376. var act = false;
  377. var name = cssClasses[t][css];
  378. /* Iterate through all registered css classes and check for presence */
  379. for(cssFile in document.styleSheets) {
  380. for(cssRule in document.styleSheets[cssFile].cssRules) {
  381. var style = document.styleSheets[cssFile].cssRules[cssRule];
  382. if (typeof style === "undefined") continue;
  383. if (typeof style.selectorText === "undefined") continue;
  384. if (style.selectorText.indexOf(name) != -1) {
  385. act = true;
  386. break;
  387. }
  388. }
  389. if (act === true) break;
  390. }
  391. found = found & act;
  392. }
  393. if(found == true) {
  394. _apps[t] = -1;
  395. } else {
  396. break;
  397. }
  398. }
  399. // convert to array
  400. var jsonString = JSON.stringify(_apps);
  401. // send back to background page
  402. var meta = document.getElementById('chromesniffer_meta');
  403. meta.content = jsonString;
  404. //Notify Background Page
  405. var done = document.createEvent('Event');
  406. done.initEvent('ready', true, true);
  407. meta.dispatchEvent(done);
  408. })();