UNPKG

js-library-detector

Version:
1,655 lines (1,557 loc) 61.9 kB
function _createTimeoutHelper() { let timeout; const timeoutPromise = new Promise((_, reject) => { timeout = setTimeout(() => reject(new Error('Timed out')), 5000); }); return {timeoutPromise, clearTimeout: () => clearTimeout(timeout)}; } var UNKNOWN_VERSION = null; var d41d8cd98f00b204e9800998ecf8427e_LibraryDetectorTests = { 'GWT': { id: 'gwt', icon: 'gwt', url: 'http://www.gwtproject.org/', test: function(win) { // pretty complicated, many possible tell tales var doc = win.document, hasHistFrame = doc.getElementById('__gwt_historyFrame'), hasGwtUid = doc.gwt_uid, hasBodyListener = doc.body.__listener, hasBodyEventBits = doc.body.__eventBits, hasModules = win.__gwt_activeModules, hasJsonP = win.__gwt_jsonp__, hasRootWinApp = win.__gwt_scriptsLoaded || win.__gwt_stylesLoaded || win.__gwt_activeModules; // use the many possible indicators if(hasHistFrame || hasGwtUid || hasBodyListener || hasBodyEventBits || hasModules || hasJsonP || hasRootWinApp) { // carefully look at frames, but only if certain is GWT frame var frames = doc.getElementsByTagName('iframe'), gwtVersion = UNKNOWN_VERSION; for(var n=0; n<frames.length; n++) { // catch security access errors try { var hasNegativeTabIndex = frames[n].tabIndex < 0; // on for GWT if(hasNegativeTabIndex && frames[n].contentWindow && frames[n].contentWindow.$gwt_version) { gwtVersion = frames[n].contentWindow.$gwt_version; break; } } catch(e) {} } if(gwtVersion=='0.0.999') { gwtVersion = 'Google Internal'; } return { version: gwtVersion }; } return false; } }, 'Ink': { id: 'ink', icon: 'ink', url: 'http://ink.sapo.pt/', test: function(win) { if (win.Ink && win.Ink.createModule) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Vaadin': { id: 'vaadin', icon: 'vaadin', url: 'https://vaadin.com/', test: function(win) { if (win.vaadin && win.vaadin.registerWidgetset) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Bootstrap': { id: 'bootstrap', icon: 'bootstrap', url: 'http://getbootstrap.com/', npm: 'bootstrap', // look for a function Boostrap has added to jQuery - regex for BS 2 & 3 test: function(win) { var jQueryAvailable = win.$ && win.$.fn, RE_PREFIX_V2 = '\\$this\\.data\\((?:\'|")', RE_PREFIX_V3 = '\\$this\\.data\\((?:\'|")(?:bs\\.){1}', bootstrapComponents = [ 'affix', 'alert', 'button', 'carousel', 'collapse', 'dropdown', 'modal', 'popover', 'scrollspy', 'tab', 'tooltip' ]; if(jQueryAvailable) { var bootstrapVersion; bootstrapComponents.some(function(component) { if(win.$.fn[component]) { // Bootstrap >= 3.2.0 detection if(win.$.fn[component].Constructor && win.$.fn[component].Constructor.VERSION) { bootstrapVersion = win.$.fn[component].Constructor.VERSION; return true; // Bootstrap >= 2.0.0 and <= 3.1.0 detection } else if(new RegExp(RE_PREFIX_V3 + component).test(win.$.fn[component].toString())) { bootstrapVersion = '>= 3.0.0 & <= 3.1.1'; return true; // Bootstrap < 3.1.0 detection } else if(new RegExp(RE_PREFIX_V2 + component).test(win.$.fn[component].toString())) { bootstrapVersion = '>= 2.0.0 & <= 2.3.2'; return true; } } return false; }); if (bootstrapVersion) { return { version: bootstrapVersion }; } } return false; } }, 'Zurb': { id: 'zurb', icon: 'zurb', url: 'https://foundation.zurb.com/', npm: 'foundation-sites', test: function(win) { if(win.Foundation && win.Foundation.Toggler) { return { version: win.Foundation.version || UNKNOWN_VERSION }; } return false; } }, 'Polymer': { id: 'polymer', icon: 'polymer', url: 'https://www.polymer-project.org/', npm: '@polymer/polymer', test: function(win) { if(win.Polymer && win.Polymer.dom) { return { version: win.Polymer.version || UNKNOWN_VERSION }; } return false; } }, 'LitElement': { id: 'litelement', icon: 'polymer', url: 'https://lit-element.polymer-project.org/', npm: 'lit-element', test: function(win) { if(win.litElementVersions && win.litElementVersions.length) { // Get latest version if multiple versions are used var versions = [...win.litElementVersions].sort( (a, b) => a.localeCompare(b, undefined, { numeric:true }) ); return { version: versions[versions.length - 1] }; } return false; } }, 'lit-html': { id: 'lit-html', icon: 'polymer', url: 'https://lit-html.polymer-project.org/', npm: 'lit-element', test: function(win) { if(win.litHtmlVersions && win.litHtmlVersions.length) { // Get latest version if multiple versions are used var versions = [...win.litHtmlVersions].sort( (a, b) => a.localeCompare(b, undefined, { numeric:true }) ); return { version: versions[versions.length - 1] }; } return false; } }, 'Highcharts': { id: 'highcharts', icon: 'highcharts', url: 'http://www.highcharts.com', npm: 'highcharts', test: function(win) { if(win.Highcharts && win.Highcharts.Point) { return { version: win.Highcharts.version || UNKNOWN_VERSION }; } return false; } }, 'InfoVis': { id: 'jit', icon: 'jit', url: 'http://philogb.github.com/jit/', test: function test(win) { if(win.$jit && win.$jit.PieChart) { return { version: win.$jit.version || UNKNOWN_VERSION }; } return false; } }, 'FlotCharts': { id: 'flotcharts', icon: 'flotcharts', url: 'http://www.flotcharts.org/', npm: 'flot', test: function(win) { if(win.$ && win.$.plot) { return { version: win.$.plot.version || UNKNOWN_VERSION}; } return false; } }, 'CreateJS': { id: 'createjs', icon: 'createjs', url: 'https://createjs.com/', npm: 'createjs', test: function(win) { if(win.createjs && win.createjs.promote) { return { version: UNKNOWN_VERSION}; // no version info available } return false; } }, 'Google Maps': { id: 'gmaps', icon: 'gmaps', url: 'https://developers.google.com/maps/', test: function(win) { if (win.google && win.google.maps) { return { version: win.google.maps.version || UNKNOWN_VERSION }; } return false; } }, 'jQuery': { id: 'jquery', icon: 'jquery', url: 'http://jquery.com', npm: 'jquery', test: function(win) { var jq = win.jQuery || win.$; if (jq && jq.fn && jq.fn.jquery) { return { version: jq.fn.jquery.replace(/[^\d+\.+]/g, '') || UNKNOWN_VERSION}; } return false; } }, 'jQuery (Fast path)': { id: 'jquery-fast', icon: 'jquery', url: 'http://jquery.com', npm: 'jquery', test: function (win) { var jq = win.jQuery || win.$; if (jq && jq.fn) { return { version: UNKNOWN_VERSION }; } return false; } }, 'jQuery UI': { id: 'jquery_ui', icon: 'jquery_ui', url: 'http://jqueryui.com', npm: 'jquery-ui', test: function(win) { var jq = win.jQuery || win.$ || win.$jq || win.$j; if(jq && jq.fn && jq.fn.jquery && jq.ui) { var plugins = 'accordion,datepicker,dialog,draggable,droppable,progressbar,resizable,selectable,slider,menu,grid,tabs'.split(','), concat = []; for (var i=0; i < plugins.length; i++) { if(jq.ui[plugins[i]]) concat.push(plugins[i].substr(0,1).toUpperCase() + plugins[i].substr(1)); } return { version: jq.ui.version || UNKNOWN_VERSION, details: concat.length ? 'Plugins used: '+concat.join(',') : '' }; } return false; } }, 'Dojo': { id: 'dojo', icon: 'dojo', url: 'http://dojotoolkit.org', npm: 'dojo', test: function(win) { if(win.dojo && win.dojo.delegate) { var version = win.dojo.version ? win.dojo.version.toString() : UNKNOWN_VERSION; return { version: version, details: 'Details: '+(win.dijit ? 'Uses Dijit' : 'none') }; } return false; } }, 'Prototype': { id: 'prototype', icon: 'prototype', url: 'http://prototypejs.org', test: function(win) { if(win.Prototype && win.Prototype.BrowserFeatures) { return { version: win.Prototype.Version || UNKNOWN_VERSION }; } return false; } }, 'Scriptaculous': { id: 'scriptaculous', icon: 'scriptaculous', url: 'http://script.aculo.us', test: function(win) { if(win.Scriptaculous && win.Scriptaculous.load) { return { version: win.Scriptaculous.Version || UNKNOWN_VERSION }; } return false; } }, 'MooTools': { id: 'mootools', icon: 'mootools', url: 'https://mootools.net/', test: function(win) { if(win.MooTools && win.MooTools.build) { return { version: win.MooTools.version || UNKNOWN_VERSION }; } return false; } }, 'Spry': { id: 'spry', icon: 'spry', url: 'http://labs.adobe.com/technologies/spry', test: function(win) { if (win.Spry && win.Spry.Data) { return { version: UNKNOWN_VERSION }; } return false; } }, 'YUI 2': { id: 'yui', icon: 'yui', url: 'http://developer.yahoo.com/yui/2/', test: function(win) { if (win.YAHOO && win.YAHOO.util) { return { version: win.YAHOO.VERSION || UNKNOWN_VERSION }; } return false; } }, 'YUI 3': { id: 'yui3', icon: 'yui3', url: 'https://yuilibrary.com/', npm: 'yui', test: function(win) { if (win.YUI && win.YUI.Env) { return { version: win.YUI.version || UNKNOWN_VERSION }; } return false; } }, 'Qooxdoo': { id: 'qooxdoo', icon: 'qooxdoo', url: 'http://www.qooxdoo.org/', npm: 'qooxdoo', test: function(win) { if(win.qx && win.qx.Bootstrap) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Ext JS': { id: 'extjs', icon: 'extjs', url: 'https://www.sencha.com/products/extjs/', test: function(win) { if (win.Ext && win.Ext.versions) { return { version: win.Ext.versions.core.version }; } else if(win.Ext) { return { version: win.Ext.version || UNKNOWN_VERSION }; } return false; } }, 'Ezoic': { id: 'ezoic', icon: 'ezoic', url: 'https://www.ezoic.com/', test: function(win) { if (win.__ez && win.__ez.template) { return { version: UNKNOWN_VERSION }; } return false; } }, 'base2': { id: 'base2', icon: 'base2', url: 'http://code.google.com/p/base2', test: function(win) { if(win.base2 && win.base2.dom) { return { version: win.base2.version || UNKNOWN_VERSION }; } return false; } }, 'Closure Library': { id: 'closure', icon: 'closure', url: 'https://developers.google.com/closure/library/', npm: 'google-closure-library', test: function(win) { if(win.goog && win.goog.provide) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Rapha&euml;l': { id: 'raphael', icon: 'raphael', url: 'http://dmitrybaranovskiy.github.io/raphael/', test: function(win) { if (win.Raphael && win.Raphael.circle) { return { version: win.Raphael.version || UNKNOWN_VERSION }; } return false; } }, 'React': { id: 'react', icon: 'react', url: 'https://reactjs.org/', npm: 'react', test: function(win) { function isMatch(node) { return node!=null && node._reactRootContainer!=null; } function nodeFilter(node) { return isMatch(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; } var reactRoot = document.getElementById('react-root'); var altHasReact = document.querySelector('*[data-reactroot]'); var bodyReactRoot = isMatch(document.body) || isMatch(document.body.firstElementChild); var hasReactRoot = bodyReactRoot|| document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, nodeFilter).nextNode() != null; if (hasReactRoot || reactRoot && reactRoot.innerText.length > 0 || altHasReact || win.React && win.React.Component) { return { version: win.React && win.React.version || UNKNOWN_VERSION }; } return false; } }, 'React (Fast path)': { id: 'react-fast', icon: 'react', url: 'https://reactjs.org/', npm: 'react', test: function (win) { function isMatch(node) { return node != null && node._reactRootContainer != null; } var reactRoot = document.getElementById('react-root'); var altHasReact = document.querySelector('*[data-reactroot]'); var hasReactRoot = isMatch(document.body) || isMatch(document.body.firstElementChild); if (hasReactRoot || reactRoot || altHasReact || win.React) { return { version: win.React && win.React.version || UNKNOWN_VERSION }; } return false; } }, 'Next.js': { id: 'next', icon: 'next', url: 'https://nextjs.org/', npm: 'next', test: function(win) { if (win.__NEXT_DATA__ && win.__NEXT_DATA__.buildId) { return { version: window.next && window.next.version || UNKNOWN_VERSION }; } return false; } }, 'Next.js (Fast path)': { id: 'next-fast', icon: 'next', url: 'https://nextjs.org/', npm: 'next', test: function (win) { if (win.__NEXT_DATA__) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Preact': { id: 'preact', icon: 'preact', url: 'https://preactjs.com/', npm: 'preact', test: function(win) { var expando = typeof Symbol!='undefined' && Symbol.for && Symbol.for('preactattr'); function isMatch(node) { if ('__k' in node && 'props' in node.__k && 'type' in node.__k) { return true; } return '_component' in node || '__preactattr_' in node || expando && node[expando]!=null; } function getMatch(node) { return node!=null && isMatch(node) && node; } function nodeFilter(node) { return isMatch(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; } var preactRoot = getMatch(document.body) || getMatch(document.body.firstElementChild); if (!preactRoot) { preactRoot = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, nodeFilter).nextNode(); } if (preactRoot || win.preact) { var version = UNKNOWN_VERSION; if (preactRoot) { if ('__k' in preactRoot) { version = '10'; } if ('__preactattr_' in preactRoot) { version = '8'; } if (expando && preactRoot[expando]!=null) { version = '7'; } } return { version: version }; } return false; } }, 'Preact (Fast path)': { id: 'preact-fast', icon: 'preact', url: 'https://preactjs.com/', npm: 'preact', test: function (win) { var version = UNKNOWN_VERSION; function isMatch(node) { if (node.__k != null) { version = '10'; return true; } return node._component != null || node.__preactattr_ != null; } function getMatch(node) { return node != null && isMatch(node); } var preactRoot = getMatch(document.body) || getMatch(document.body.firstElementChild); if (preactRoot || win.preact) { return { version: version }; } return false; } }, 'Modernizr': { id: 'modernizr', icon: 'modernizr', url: 'https://modernizr.com/', npm: 'modernizr', test: function(win) { if (win.Modernizr && win.Modernizr.addTest) { return { version: win.Modernizr._version || UNKNOWN_VERSION }; } return false; } }, 'Processing.js': { id: 'processingjs', icon: 'processingjs', url: 'http://processingjs.org', npm: 'processing-js', test: function(win) { if(win.Processing && win.Processing.box) { return { version: Processing.version || UNKNOWN_VERSION }; } return false; } }, 'Backbone': { id: 'backbone', icon: 'backbone', url: 'http://backbonejs.org/', npm: 'backbone', test: function(win) { if (win.Backbone && win.Backbone.Model.extend) { return {version: win.Backbone.VERSION || UNKNOWN_VERSION}; } return false; } }, 'Leaflet': { id: 'leaflet', icon: 'leaflet', url: 'http://leafletjs.com', npm: 'leaflet', test: function(win) { // Leaflet 3.1 uses L.Marker and L.VERSION; later versions use L.marker and L.version if (win.L && win.L.GeoJSON && (win.L.marker || win.L.Marker)) { return { version: win.L.version || win.L.VERSION || UNKNOWN_VERSION }; } return false; } }, 'Mapbox': { id: 'mapbox', icon: 'mapbox', url: 'https://www.mapbox.com/', npm: 'mapbox-gl', test: function(win) { if (win.L && win.L.mapbox && win.L.mapbox.geocoder) { return { version: win.L.mapbox.VERSION || UNKNOWN_VERSION }; } return false; } }, 'Lo-Dash': { id: 'lodash', icon: 'lodash', url: 'https://lodash.com/', npm: 'lodash', test: function(win) { var _ = typeof (_ = win._) == 'function' && _, chain = typeof (chain = _ && _.chain) == 'function' && chain, wrapper = (chain || _ || function() { return {}; })(1); if (_ && wrapper.__wrapped__) { return { version: _.VERSION || UNKNOWN_VERSION }; } return false; } }, 'Underscore': { id: 'underscore', icon: 'underscore', url: 'http://underscorejs.org/', npm: 'underscore', test: function(win) { if (win._ && typeof win._.tap === 'function' && !d41d8cd98f00b204e9800998ecf8427e_LibraryDetectorTests['Lo-Dash'].test(win)) { return {version: win._.VERSION || UNKNOWN_VERSION}; } return false; } }, 'Sammy': { id: 'sammy', icon: 'sammy', url: 'http://sammyjs.org', test: function(win) { if (win.Sammy && win.Sammy.Application.curry) { return {version: win.Sammy.VERSION || UNKNOWN_VERSION}; } return false; } }, 'Rico': { id: 'rico', icon: 'rico', url: 'http://openrico.sourceforge.net/examples/index.html', test: function(win) { if (win.Rico && window.Rico.checkIfComplete) { return {version: win.Rico.Version || UNKNOWN_VERSION}; } return false; } }, 'MochiKit': { id: 'mochikit', icon: 'mochikit', url: 'https://mochi.github.io/mochikit/', test: function(win) { if (win.MochiKit && win.MochiKit.Base.module) { return {version: MochiKit.VERSION || UNKNOWN_VERSION}; } return false; } }, 'gRapha&euml;l': { id: 'graphael', icon: 'graphael', url: 'https://github.com/DmitryBaranovskiy/g.raphael', test: function(win) { if (win.Raphael && win.Raphael.fn.g) { return {version: UNKNOWN_VERSION}; } return false; } }, 'Glow': { id: 'glow', icon: 'glow', url: 'http://www.bbc.co.uk/glow/', test: function(win) { if (win.gloader && win.gloader.getRequests) { return {version: UNKNOWN_VERSION}; } else if (win.glow && win.glow.dom) { return {version: win.glow.VERSION || UNKNOWN_VERSION}; } else if (win.Glow) { return {version: win.Glow.version || UNKNOWN_VERSION}; } return false; } }, 'Socket.IO': { id: 'socketio', icon: 'socketio', // currently has no icon url: 'https://socket.io/', npm: 'socket.io', test: function(win) { // version 0.6.2 uses only io.Socket; more recent versions also have io.sockets if (win.io && (win.io.sockets || win.io.Socket)) { return {version: win.io.version || UNKNOWN_VERSION}; } return false; } }, 'Mustache': { id: 'mustache', icon: 'mustache', url: 'http://mustache.github.io/', npm: 'mustache', test: function(win) { if (win.Mustache && win.Mustache.to_html) { return {version: win.Mustache.version || UNKNOWN_VERSION}; } return false; } }, 'Fabric.js': { id: 'fabricjs', icon: 'icon38', // currently has no icon url: 'http://fabricjs.com/', npm: 'fabric', test: function(win) { if (win.fabric && win.fabric.util) { return {version: win.fabric.version || UNKNOWN_VERSION}; } return false; } }, 'FuseJS': { id: 'fusejs', icon: 'fusejs', url: 'http://fusejs.io/', npm: 'fuse.js', test: function(win) { if (win.Fuse) { return {version: UNKNOWN_VERSION}; } return false; } }, 'Tween.js': { id: 'tweenjs', icon: 'icon38', // currently has no icon url: 'https://github.com/tweenjs/tween.js', npm: 'tween.js', test: function(win) { if (win.TWEEN && win.TWEEN.Easing) { return {version: UNKNOWN_VERSION}; } return false; } }, 'SproutCore': { id: 'sproutcore', icon: 'sproutcore', url: 'http://sproutcore.com/', test: function(win) { if (win.SC && win.SC.Application) { return {version: UNKNOWN_VERSION}; } return false; } }, 'Zepto.js': { id: 'zepto', icon: 'zepto', url: 'http://zeptojs.com', npm: 'zepto', test: function(win) { if (win.Zepto && win.Zepto.fn) { return {version: UNKNOWN_VERSION}; } return false; } }, 'three.js': { id: 'threejs', icon: 'icon38', // currently has no icon url: 'https://threejs.org/', npm: 'three', test: function(win) { if (win.THREE && win.THREE.REVISION) { return {version: 'r' + win.THREE.REVISION}; } else if (win.THREE) { return {version: UNKNOWN_VERSION}; } return false; } }, 'PhiloGL': { id: 'philogl', icon: 'philogl', url: 'http://www.senchalabs.org/philogl/', npm: 'philogl', test: function(win) { if (win.PhiloGL && win.PhiloGL.Camera) { return {version: win.PhiloGL.version || UNKNOWN_VERSION}; } return false; } }, 'CamanJS': { id: 'camanjs', icon: 'camanjs', url: 'http://camanjs.com/', npm: 'caman', test: function(win) { if (win.Caman && win.Caman.version) { return {version: win.Caman.version.release}; } else if (win.Caman) { return {version: UNKNOWN_VERSION}; } return false; } }, 'yepnope': { id: 'yepnope', icon: 'yepnope', url: 'http://yepnopejs.com/', test: function(win) { if (win.yepnope && win.yepnope.injectJs) { return {version: UNKNOWN_VERSION}; } return false; } }, 'LABjs': { id: 'labjs', icon: 'icon38', url: 'https://github.com/getify/LABjs', test: function(win) { if (win.$LAB && win.$LAB.setOptions) { return {version: UNKNOWN_VERSION}; } return false; } }, 'Head JS': { id: 'headjs', icon: 'headjs', url: 'http://headjs.com/', npm: 'headjs', test: function(win) { if (win.head && win.head.js) { return {version: UNKNOWN_VERSION}; } return false; } }, 'ControlJS': { id: 'controljs', icon: 'icon38', url: 'http://stevesouders.com/controljs/', test: function(win) { if (win.CJS && win.CJS.start) { return {version: UNKNOWN_VERSION}; } return false; } }, 'RequireJS': { id: 'requirejs', icon: 'requirejs', url: 'http://requirejs.org/', npm: 'requirejs', test: function(win) { var req = win.require || win.requirejs; if (req && (req.load || (req.s && req.s.contexts && req.s.contexts._ && (req.s.contexts._.loaded || req.s.contexts._.load)))) { return { version: req.version || UNKNOWN_VERSION }; } return false; } }, 'RightJS': { id: 'rightjs', icon: 'rightjs', url: 'http://rightjs.org/', test: function(win) { if (win.RightJS && win.RightJS.isNode) { return { version: win.RightJS.version || UNKNOWN_VERSION }; } return false; } }, 'jQuery Tools': { id: 'jquerytools', icon: 'jquerytools', url: 'http://jquerytools.github.io/', test: function(win) { var jq = win.jQuery || win.$; if(jq && jq.tools) { return { version: jq.tools.version || UNKNOWN_VERSION }; } return false; } }, 'Pusher': { id: 'pusher', icon: 'pusher', url: 'https://pusher.com/docs/', npm: 'pusher-js', test: function(win) { if(win.Pusher && win.Pusher.Channel) { return { version: win.Pusher.VERSION || UNKNOWN_VERSION }; } return false; } }, 'Paper.js': { id: 'paperjs', icon: 'paperjs', url: 'http://paperjs.org/', npm: 'paper', test: function(win) { if(win.paper && win.paper.Point) { return { version: win.paper.version || UNKNOWN_VERSION }; } return false; } }, 'Swiffy': { id: 'swiffy', icon: 'icon38', url: 'https://developers.google.com/swiffy/', test: function(win) { if(win.swiffy && win.swiffy.Stage) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Move': { id: 'move', icon: 'move', url: 'https://github.com/rsms/move', npm: 'move', test: function(win) { if(win.move && win.move.compile) { return { version: win.move.version() || UNKNOWN_VERSION }; } return false; } }, 'AmplifyJS': { id: 'amplifyjs', icon: 'amplifyjs', url: 'http://amplifyjs.com/', npm: 'amplifyjs', test: function(win) { if(win.amplify && win.amplify.publish) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Popcorn.js': { id: 'popcornjs', icon: 'popcornjs', url: 'https://github.com/mozilla/popcorn-js/', test: function(win) { if (win.Popcorn && win.Popcorn.Events) { return { version: win.Popcorn.version || UNKNOWN_VERSION }; } return false; } }, 'D3': { id: 'd3', icon: 'd3', url: 'https://d3js.org/', npm: 'd3', test: function(win) { if (win.d3 && win.d3.select) { return { version: win.d3.version || UNKNOWN_VERSION }; } return false; } }, 'Handlebars': { id: 'handlebars', icon: 'handlebars', url: 'http://handlebarsjs.com/', npm: 'handlebars', test: function(win) { if(win.Handlebars && win.Handlebars.compile) { return { version: win.Handlebars.VERSION || UNKNOWN_VERSION }; } return false; } }, 'Handsontable': { id: 'handsontable', icon: 'handsontable', url: 'https://handsontable.com/', npm: 'handsontable', test: function(win) { if (win.Handsontable && win.Handsontable.Core) { return { version: win.Handsontable.version || UNKNOWN_VERSION }; } return false; } }, 'Knockout': { id: 'knockout', icon: 'knockout', url: 'http://knockoutjs.com/', npm: 'knockout', test: function(win) { if (win.ko && win.ko.applyBindings) { return { version: win.ko.version || UNKNOWN_VERSION }; } return false; } }, 'Spine': { id: 'spine', icon: 'icon38', url: 'http://spine.github.io/', test: function(win) { if (win.Spine && win.Spine.Controller) { return {version: win.Spine.version || UNKNOWN_VERSION}; } return false; } }, 'jQuery Mobile': { id: 'jquery-mobile', icon: 'jquery_mobile', url: 'http://jquerymobile.com/', npm: 'jquery-mobile', test: function(win) { var jq = win.jQuery || win.$ || win.$jq || win.$j; if(jq && jq.fn && jq.fn.jquery && jq.mobile) { return { version: jq.mobile.version || UNKNOWN_VERSION }; } return false; } }, 'WebFont Loader': { id: 'webfontloader', icon: 'icon38', url: 'https://github.com/typekit/webfontloader', npm: 'webfontloader', test: function(win) { if(win.WebFont && win.WebFont.load) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Angular': { id: 'angular', icon: 'angular', url: 'https://angular.io/', npm: '@angular/core', test: function(win) { var ngVersion = win.document.querySelector('[ng-version]'); if (ngVersion) { return { version: ngVersion.getAttribute('ng-version') || UNKNOWN_VERSION }; } else if (win.ng && win.ng.probe instanceof Function) { return { version: UNKNOWN_VERSION }; } return false; } }, 'AngularJS': { id: 'angularjs', icon: 'angularjs', url: 'https://angularjs.org/', npm: 'angular', test: function(win) { var ng = win.angular; if (ng && ng.version && ng.version.full) { return { version: ng.version.full }; } return false; } }, 'Ionic': { id: 'ionic', icon: 'ionic', url: 'https://ionicframework.com/', npm: '@ionic/cli', test: function(win) { var ion = win.document.querySelector('ion-app'); if (ion && ion.nodeName === 'ION-APP') { return { version: UNKNOWN_VERSION }; } return false; } }, 'Ember.js': { id: 'emberjs', icon: 'emberjs', url: 'https://emberjs.com/', npm: 'ember-source', test: function(win) { var ember = win.Ember || win.Em; if (ember && ember.GUID_KEY) { return { version: ember.VERSION || UNKNOWN_VERSION }; } return false; } }, 'Hammer.js': { id: 'hammerjs', icon: 'hammerjs', url: 'http://eightmedia.github.io/hammer.js/', npm: 'hammerjs', test: function(win) { if(win.Hammer && win.Hammer.Pinch) { // Hammer.VERSION available in 1.0.10+ return { version: win.Hammer.VERSION || "&lt; 1.0.10" }; } return false; } }, 'Visibility.js': { id: 'visibilityjs', icon: 'icon38', url: 'https://github.com/ai/visibilityjs', npm: 'visibilityjs', test: function(win) { if(win.Visibility && win.Visibility.every) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Velocity.js': { id: 'velocityjs', icon: 'icon38', url: 'http://velocityjs.org/', npm: 'velocity-animate', test: function(win) { var jq = win.jQuery || win.$, velocity = jq ? jq.Velocity : win.Velocity; if(velocity && velocity.RegisterEffect && velocity.version) { return { version: velocity.version.major + "." + velocity.version.minor + "." + velocity.version.patch }; } else if (velocity && velocity.RegisterEffect) { return { version: UNKNOWN_VERSION }; } return false; } }, 'IfVisible.js': { id: 'ifvisiblejs', icon: 'icon38', url: 'http://serkanyersen.github.io/ifvisible.js/', npm: 'ifvisible.js', test: function(win) { var iv = win.ifvisible; if(iv && iv.__ceGUID === "ifvisible.object.event.identifier") { return { version: UNKNOWN_VERSION }; } return false; } }, 'Pixi.js': { id: 'pixi', icon: 'pixi', url: 'http://www.pixijs.com/', npm: 'pixi.js', test: function(win) { var px = win.PIXI; if(px && px.WebGLRenderer && px.VERSION) { // version 4.4.3 returns simply "4.4.3"; version 1.5.2 returns "v1.5.2" return { version: px.VERSION.replace('v', '') || UNKNOWN_VERSION }; } return false; } }, 'DC.js': { id: 'dcjs', icon: 'dcjs', url: 'http://dc-js.github.io/dc.js/', npm: 'dc', test: function(win) { var dc = win.dc; if(dc && dc.registerChart) { return { version: dc.version || UNKNOWN_VERSION }; } return false; } }, 'GreenSock JS': { id: 'greensock', icon: 'greensock', url: 'https://greensock.com/gsap', npm: 'gsap', test: function(win) { if (win.TweenMax && win.TweenMax.pauseAll) { return { version: win.TweenMax.version || UNKNOWN_VERSION }; } return false; } }, 'FastClick': { id: 'fastclick', icon: 'fastclick', url: 'https://github.com/ftlabs/fastclick', npm: 'fastclick', test: function(win) { if(win.FastClick && win.FastClick.notNeeded) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Isotope': { id: 'isotope', icon: 'isotope', url: 'https://isotope.metafizzy.co/', npm: 'isotope-layout', test: function(win) { if(win.Isotope || (win.$ != null && win.$.Isotope)) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Marionette': { id: 'marionette', icon: 'marionette', url: 'https://marionettejs.com/', npm: 'backbone.marionette', test: function(win) { if(win.Marionette && win.Marionette.Application) { return { version: win.Marionette.VERSION || UNKNOWN_VERSION }; } return false; } }, 'Can': { id: 'canjs', icon: 'canjs', url: 'https://canjs.com/', npm: 'can', test: function (win) { if (win.can && win.can.Construct) { return { version: win.can.VERSION || UNKNOWN_VERSION }; } return false; } }, 'Vue': { id: 'vue', icon: 'vue', url: 'https://vuejs.org/', npm: 'vue', test: function(win) { function isVueNode(node) { return node.__vue__ != null ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; } var hasVueNode = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, isVueNode).nextNode() !== null; if (hasVueNode || win.Vue) { return { version: win.Vue && win.Vue.version || UNKNOWN_VERSION }; } return false; } }, 'Vue (Fast path)': { id: 'vue-fast', icon: 'vue', url: 'https://vuejs.org/', npm: 'vue', test: function (win) { if (win.Vue) { return { version: win.Vue && win.Vue.version || UNKNOWN_VERSION }; } return false; } }, 'Nuxt.js': { id: 'nuxt', icon: 'nuxt', url: 'https://nuxtjs.org/', npm: 'nuxt', test: function(win) { if (win.__NUXT__ || win.$nuxt || [...win.document.querySelectorAll('*')].some(el => el.__vue__?.nuxt)) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Nuxt.js (Fast path)': { id: 'nuxt-fast', icon: 'nuxt', url: 'https://nuxtjs.org/', npm: 'nuxt', test: function (win) { if (win.__NUXT__ || win.$nuxt) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Two': { id: 'two', icon: 'two', url: 'https://two.js.org/', npm: 'two.js', test: function(win) { if (win.Two && win.Two.Utils) { return { version: win.Two.Version || UNKNOWN_VERSION }; } return false; } }, 'Brewser': { id: 'brewser', icon: 'brewser', url: 'https://robertpataki.github.io/brewser/', npm: 'brewser', test: function(win) { if(win.BREWSER && win.BREWSER.ua) { return { version: BREWSER.VERSION || UNKNOWN_VERSION }; } return false; } }, 'Material Design Lite': { id: 'materialdesignlite', icon: 'mdl', url: 'https://getmdl.io/', npm: 'material-design-lite', test: function(win) { if(win.componentHandler && win.componentHandler.upgradeElement) { return { version: UNKNOWN_VERSION}; } return false; } }, 'Kendo UI': { id: 'kendoui', icon: 'kendoui', url: 'https://github.com/telerik/kendo-ui-core', npm: 'kendo-ui-core', test: function(win) { if (win.kendo && win.kendo.View && win.kendo.View.extend) { return {version: win.kendo.version || UNKNOWN_VERSION}; } return false; } }, 'Matter.js': { id: 'matterjs', icon: 'matter-js', url: 'http://brm.io/matter-js/', npm: 'matter-js', test: function(win) { if (win.Matter && win.Matter.Engine) { return {version: UNKNOWN_VERSION}; } return false; } }, 'Riot': { id: 'riot', icon: 'riot', url: 'http://riotjs.com/', npm: 'riot', test: function(win) { if (win.riot && win.riot.mixin) { return { version: win.riot.version || UNKNOWN_VERSION }; } return false; } }, 'Sea.js': { id: 'seajs', icon: 'icon38', url: 'https://seajs.github.io/seajs/docs/', npm: 'seajs', test: function(win) { if(win.seajs && win.seajs.use) { return { version: win.seajs.version || UNKNOWN_VERSION }; } return false; } }, 'Moment.js': { id: 'momentjs', icon: 'momentjs', url: 'http://momentjs.com/', npm: 'moment', test: function(win) { if(win.moment && (win.moment.isMoment || win.moment.lang)) { // version 1.0.0 has neither "isMoment" nor "version" return { version: win.moment.version || UNKNOWN_VERSION }; } return false; } }, 'Moment Timezone': { id: 'moment-timezone', icon: 'momentjs', url: 'http://momentjs.com/timezone/', npm: 'moment-timezone', test: function(win) { if (win.moment && win.moment.tz) { return { version: win.moment.tz.version || UNKNOWN_VERSION }; } return false; } }, 'ScrollMagic': { id: 'scrollmagic', icon: 'scrollmagic', url: 'http://scrollmagic.io/', npm: 'scrollmagic', test: function(win) { if (win.ScrollMagic && win.ScrollMagic.Controller) { return {version: ScrollMagic.version || UNKNOWN_VERSION}; } return false; } }, 'SWFObject': { id: 'swfobject', icon: 'icon38', // currently has no icon url: 'https://github.com/swfobject/swfobject', test: function(win) { if (win.swfobject && win.swfobject.embedSWF) { // 2.x - exact version only for 2.3 return { version: win.swfobject.version || UNKNOWN_VERSION }; } else if(win.deconcept && win.deconcept.SWFObject) { // 1.x return { version: UNKNOWN_VERSION }; } return false; } }, 'FlexSlider': { id: 'flexslider', icon: 'icon38', // currently has no icon url: 'https://woocommerce.com/flexslider/', npm: 'flexslider', test: function(win) { var jq = win.jQuery || win.$ || win.$jq || win.$j; if (jq && jq.fn && jq.fn.jquery && jq.flexslider){ return { version: UNKNOWN_VERSION }; } return false; } }, 'SPF': { id: 'spf', icon: 'icon38', // currently has no icon url: 'https://youtube.github.io/spfjs/', npm: 'spf', test: function(win) { if (win.spf && win.spf.init) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Numeral.js': { id: 'numeraljs', icon: 'icon38', // currently has no icon url: 'http://numeraljs.com/', npm: 'numeraljs', test: function(win) { if (win.numeral && win.isNumeral) { return { version: win.numeral.version || UNKNOWN_VERSION }; } return false; } }, 'boomerang.js': { id: 'boomerangjs', icon: 'icon38', // currently has no icon url: 'https://soasta.github.io/boomerang/', npm: 'boomerangjs', test: function(win) { if (win.BOOMR && win.BOOMR.utils && win.BOOMR.init) { return { version: win.BOOMR.version || UNKNOWN_VERSION }; } return false; } }, 'Framer': { id: 'framer', icon: 'framer', url: 'https://framer.com/', npm: 'framerjs', test: function(win) { if (win.Framer && win.Framer.Layer) { return { version: win.Framer.Version.build || UNKNOWN_VERSION }; } return false; } }, 'Marko': { id: 'marko', icon: 'marko', url: 'https://markojs.com/', npm: 'marko', test: function (win) { var selector = '[data-marko-key], [data-marko]'; var markoElement = document.querySelector(selector); if (markoElement) { return { version: UNKNOWN_VERSION }; } return false; } }, 'AMP': { id: 'amp', icon: 'amp', url: 'https://amp.dev/', npm: 'https://www.npmjs.com/org/ampproject', test: function (win) { var version = win.document.documentElement.getAttribute("amp-version"); return version ? { version: version } : false; } }, 'Gatsby': { id: 'gatsby', icon: 'gatsby', url: 'https://www.gatsbyjs.org/', npm: 'gatsby', test: function (win) { if (document.getElementById('___gatsby')) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Shopify': { id: 'shopify', icon: 'shopify', url: 'https://www.shopify.com/', npm: null, test: function (win) { if (win.Shopify && win.Shopify.shop) { return { version: UNKNOWN_VERSION }; } return false; } }, 'Magento': { id: 'magento', icon: 'magento', url: 'https://magento.com/', npm: null, test: function (win) { // Same detecton used in Magento 2 DevTools: https://github.com/magento/m2-devtools const reRequireScript = /\/static(?:\/version\d+)?\/frontend\/.+\/.+\/requirejs\/require(?:\.min)?\.js/; const scripts = Array.from(document.query