├── test
├── fixtures
│ ├── require.coffee
│ ├── require.js
│ ├── package.json
│ ├── require.js.html
│ └── package.json.html
├── test_setup.js
├── test_utils.js
├── test_manifest_remote.js
├── test_manifest_local.js
├── test_require_remote.js
└── test_require_local.js
├── .gitignore
├── .travis.yml
├── .editorconfig
├── .jshintrc
├── index.js
├── .jscs.json
├── README.md
├── lib
├── utils.js
├── manifest.js
└── require.js
├── package.json
└── gulpfile.js
/test/fixtures/require.coffee:
--------------------------------------------------------------------------------
1 | require "path"
2 | lodash = require("lodash")
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | temp/
3 | coverage/
4 | npm-debug.log
5 | .DS_Store
6 | .idea
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '0.10'
4 | after_script:
5 | - npm run coveralls
6 |
--------------------------------------------------------------------------------
/test/test_setup.js:
--------------------------------------------------------------------------------
1 | var registries = require('github-linker-registries');
2 |
3 | before(function() {
4 | registries.npm = {
5 | lodash: 'https://github.com/lodash/lodash'
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | # We recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "curly": true,
3 | "eqeqeq": true,
4 | "immed": true,
5 | "latedef": true,
6 | "newcap": true,
7 | "noarg": true,
8 | "sub": true,
9 | "undef": true,
10 | "unused": true,
11 | "boss": true,
12 | "eqnull": true,
13 | "node": true,
14 | "expr": true,
15 | "globals": {
16 | "describe" : false,
17 | "it" : false,
18 | "before" : false,
19 | "beforeEach" : false,
20 | "after" : false,
21 | "afterEach" : false,
22 | "window" : false
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test/fixtures/require.js:
--------------------------------------------------------------------------------
1 |
2 | require('path');
3 | require('lodash');
4 | require('unknown-package-name');
5 | require('./file.js');
6 | require('./folder/file.js');
7 | require('./file-or-folder');
8 | require('../file.js');
9 | require('../folder/file.js');
10 | require('../file-or-folder');
11 | require('../../file.js');
12 | require('../../folder/file.js');
13 | require('../../file-or-folder');
14 | require('./');
15 | require('..');
16 | require('../');
17 | require('../..');
18 | require('../../');
19 | require('.');
20 | require('...');
21 | require('/');
22 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * github-linker-core
3 | * https://github.com/stefanbuck/github-linker
4 | *
5 | * Copyright (c) 2014 Stefan Buck
6 | * Licensed under the MIT license.
7 | */
8 |
9 | 'use strict';
10 |
11 | var utils = require('./lib/utils');
12 | var manifest = require('./lib/manifest');
13 | var reqr = require('./lib/require');
14 |
15 | module.exports = function($, url, cb) {
16 |
17 | if ($('.github-linker').length > 0) {
18 | return cb(null);
19 | }
20 |
21 | if (utils.manifestType(url)) {
22 | manifest($, url, cb);
23 | } else if (utils.requireType(url)) {
24 | reqr($, url, cb);
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/.jscs.json:
--------------------------------------------------------------------------------
1 | {
2 | "requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"],
3 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
4 | "disallowSpaceBeforeBinaryOperators": [",", ":"],
5 | "disallowSpaceAfterBinaryOperators": ["!"],
6 | "requireSpaceBeforeBinaryOperators": ["?", "+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
7 | "requireSpaceAfterBinaryOperators": ["?", "+", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
8 | "disallowImplicitTypeConversion": ["string"],
9 | "disallowKeywords": ["with"],
10 | "disallowMultipleLineBreaks": true,
11 | "disallowKeywordsOnNewLine": ["else"],
12 | "disallowTrailingWhitespace": true,
13 | "requireLineFeedAtFileEnd": true,
14 | "validateIndentation": 2,
15 | "validateJSDoc": {
16 | "checkParamNames": true,
17 | "requireParamTypes": true
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # github-linker-core
2 | [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-url]][daviddm-image] [![Coverage Status][coveralls-image]][coveralls-url]
3 |
4 | > The [GitHub-Linker](https://github.com/stefanbuck/github-linker) core
5 |
6 |
7 | ## License
8 |
9 | Copyright (c) 2014 Stefan Buck. Licensed under the MIT license.
10 |
11 |
12 |
13 | [npm-url]: https://npmjs.org/package/github-linker-core
14 | [npm-image]: https://badge.fury.io/js/github-linker-core.svg
15 | [travis-url]: https://travis-ci.org/stefanbuck/github-linker-core
16 | [travis-image]: https://travis-ci.org/stefanbuck/github-linker-core.svg?branch=master
17 | [daviddm-url]: https://david-dm.org/stefanbuck/github-linker-core.svg?theme=shields.io
18 | [daviddm-image]: https://david-dm.org/stefanbuck/github-linker-core
19 | [coveralls-url]: https://coveralls.io/r/stefanbuck/github-linker-core
20 | [coveralls-image]: https://coveralls.io/repos/stefanbuck/github-linker-core/badge.png
21 |
--------------------------------------------------------------------------------
/lib/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _ = require('lodash');
4 |
5 | var getType = function(url, lookup) {
6 |
7 | var urlContains = function(indicator) {
8 | return url.indexOf(indicator) === url.length - indicator.length;
9 | };
10 |
11 | return _.find(lookup, function(type, urlFragment) {
12 | return urlContains(urlFragment);
13 | });
14 | };
15 |
16 | var stripQuotes = function(jqElement) {
17 | return jqElement.html().replace(/"|'/g, '');
18 | };
19 |
20 | var manifestType = function(url) {
21 | var lookup = {
22 | '/package.json': 'npm',
23 | '/bower.json': 'bower'
24 | };
25 | return getType(url, lookup);
26 | };
27 |
28 | var requireType = function(url) {
29 | var lookup = {
30 | '.js': 'js',
31 | '.coffee': 'coffee'
32 | };
33 | return getType(url, lookup);
34 | };
35 |
36 | var showLoader = function($) {
37 | var $loaderContainer = $('.page-context-loader');
38 | $loaderContainer.addClass('is-context-loading');
39 | };
40 |
41 | module.exports = {
42 | stripQuotes: stripQuotes,
43 | manifestType: manifestType,
44 | requireType: requireType,
45 | showLoader: showLoader
46 | };
47 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "github-linker-core",
3 | "description": "The GitHub Linker core",
4 | "version": "0.0.1",
5 | "homepage": "https://github.com/stefanbuck/github-linker",
6 | "bugs": "https://github.com/stefanbuck/github-linker-core/issues",
7 | "license": "MIT",
8 | "main": "index.js",
9 | "author": {
10 | "name": "Stefan Buck",
11 | "email": "dev@stefanbuck.com",
12 | "url": "http://stefanbuck.com"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/stefanbuck/github-linker-core"
17 | },
18 | "keywords": [],
19 | "dependencies": {
20 | "github-linker-registries": "^1.0.0",
21 | "jquery": "^2.1.1",
22 | "lodash": "2.4.1"
23 | },
24 | "devDependencies": {
25 | "coveralls": "^2.10.0",
26 | "gulp": "^3.6.2",
27 | "gulp-bump": "^0.1.8",
28 | "gulp-istanbul": "^0.2.0",
29 | "gulp-jscs": "^0.4.2",
30 | "gulp-jshint": "^1.5.5",
31 | "gulp-load-plugins": "^0.5.1",
32 | "gulp-mocha": "^0.4.1",
33 | "gulp-plumber": "^0.6.2",
34 | "gulp-util": "2.2.16",
35 | "jshint-stylish": "^0.2.0",
36 | "should": "^3.3.1",
37 | "jsdom": "^1.0.0-pre.3"
38 | },
39 | "scripts": {
40 | "coveralls": "gulp test && cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
41 | "test": "gulp test"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/test/fixtures/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "playground-repo",
3 | "description": "My personal playground",
4 | "version": "0.0.1",
5 | "homepage": "https://github.com/stefanbuck/playground-repo",
6 | "bugs": "https://github.com/stefanbuck/playground-repo/issues",
7 | "license": "MIT",
8 | "main": "index.js",
9 | "author": {
10 | "name": "Stefan Buck",
11 | "email": "dev@stefanbuck.com",
12 | "url": "http://stefanbuck.com"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/stefanbuck/playground-repo"
17 | },
18 | "keywords": [],
19 | "dependencies": {
20 | "lodash": "2.4.1",
21 | "request": "^2.40.0",
22 | "modernizr": "Modernizr/Modernizr",
23 | "backbone": "jashkenas/backbone#master",
24 | "jquery": "jquery/jquery#1.x-master",
25 | "unknown-package-name": "latest"
26 | },
27 | "devDependencies": {
28 | "chai": "^1.9.1",
29 | "gulp": "^3.6.2"
30 | },
31 | "optionalDependencies": {
32 | "should": "^3.3.1"
33 | },
34 | "peerDependencies": {
35 | "yo": ">=1.0.0"
36 | },
37 | "scripts": {
38 | "coveralls": "gulp test && cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
39 | "test": "gulp test"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 | var plugins = require('gulp-load-plugins')();
5 |
6 | var paths = {
7 | lint: ['./gulpfile.js', './lib/**/*.js', './index.js'],
8 | watch: ['./gulpfile.js', './lib/**/*.js', './index.js', './test/**/*.js', '!test/{temp,temp/**}'],
9 | tests: ['./test/**/*.js', '!test/{temp,temp/**}', '!test/fixtures/**'],
10 | source: ['./lib/**/*.js', './index.js']
11 | };
12 |
13 | gulp.task('lint', function () {
14 | return gulp.src(paths.lint)
15 | .pipe(plugins.jshint('.jshintrc'))
16 | .pipe(plugins.jscs())
17 | .pipe(plugins.jshint.reporter('jshint-stylish'));
18 | });
19 |
20 | gulp.task('istanbul', function (cb) {
21 | gulp.src(paths.source)
22 | .pipe(plugins.istanbul()) // Covering files
23 | .on('finish', function () {
24 | gulp.src(paths.tests)
25 | .pipe(plugins.plumber())
26 | .pipe(plugins.mocha())
27 | .pipe(plugins.istanbul.writeReports()) // Creating the reports after tests runned
28 | .on('finish', function() {
29 | process.chdir(__dirname);
30 | cb();
31 | });
32 | });
33 | });
34 |
35 | gulp.task('bump', ['test'], function () {
36 | var bumpType = plugins.util.env.type || 'patch'; // major.minor.patch
37 |
38 | return gulp.src(['./package.json'])
39 | .pipe(plugins.bump({ type: bumpType }))
40 | .pipe(gulp.dest('./'));
41 | });
42 |
43 | gulp.task('watch', ['test'], function () {
44 | gulp.watch(paths.watch, ['test']);
45 | });
46 |
47 | gulp.task('test', ['lint', 'istanbul']);
48 |
49 | gulp.task('release', ['bump']);
50 |
51 | gulp.task('default', ['test']);
52 |
--------------------------------------------------------------------------------
/lib/manifest.js:
--------------------------------------------------------------------------------
1 | /*
2 | * github-linker-core
3 | * https://github.com/stefanbuck/github-linker
4 | *
5 | * Copyright (c) 2014 Stefan Buck
6 | * Licensed under the MIT license.
7 | */
8 |
9 | 'use strict';
10 |
11 | var registries = require('github-linker-registries');
12 | var utils = require('./utils');
13 |
14 | var SORRY = 'Sorry, there is no link for this package available';
15 |
16 | module.exports = function($, url, cb) {
17 |
18 | var type = utils.manifestType(url);
19 | var $root, $row, $name, $version, name, version, link;
20 | var types = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'];
21 | var result = [];
22 | var registryList = registries[type];
23 |
24 | types.forEach(function(selector) {
25 | $root = $('.nt:contains(\'' + selector + '\')');
26 |
27 | if (!$root || $root.length === 0) {
28 | return;
29 | }
30 |
31 | $row = $root.closest('tr').next();
32 |
33 | while ($row) {
34 | $name = $row.find('.nt');
35 | $version = $row.find('.s2');
36 |
37 | if (!$name.length || !$version.length) {
38 | return;
39 | }
40 |
41 | name = utils.stripQuotes($name);
42 | version = utils.stripQuotes($version);
43 |
44 | link = registryList[name];
45 |
46 | if (version.split('/').length === 2) {
47 | link = 'https://github.com/' + version.replace('#', '/tree/');
48 |
49 | } else if (!link && type === 'npm' ) {
50 | link = 'https://www.npmjs.org/package/' + name;
51 | }
52 |
53 | if (link) {
54 | var $link = $('');
55 | $link.attr('href', link);
56 | $name.wrap($link);
57 |
58 | } else {
59 | $name.addClass('tooltipped tooltipped-e').attr('aria-label', SORRY);
60 | }
61 |
62 | result.push({
63 | el: $name,
64 | version: version,
65 | name: name,
66 | link: link
67 | });
68 |
69 | $row = $row.next();
70 | }
71 | });
72 |
73 | cb(null, result);
74 | };
75 |
--------------------------------------------------------------------------------
/test/test_utils.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('../lib/utils');
4 | var assert = require('should');
5 |
6 | describe('utils', function() {
7 |
8 | describe('manifestType', function() {
9 |
10 | it('package.json', function() {
11 | utils.manifestType('https://github.com/stefanbuck/github-linker-core/blob/master/package.json').should.equal('npm');
12 | });
13 |
14 | it('bower.json', function() {
15 | utils.manifestType('https://github.com/stefanbuck/github-linker-core/blob/master/bower.json').should.equal('bower');
16 | });
17 |
18 | it('unknown.json', function() {
19 | (utils.manifestType('https://github.com/stefanbuck/github-linker-core/blob/master/unknown.json') === undefined).should.equal(true);
20 | });
21 | });
22 |
23 | describe('requireType', function() {
24 |
25 | it('file.js', function() {
26 | utils.requireType('https://github.com/stefanbuck/github-linker-core/blob/master/file.js').should.equal('js');
27 | });
28 |
29 | it('file.coffee', function() {
30 | utils.requireType('https://github.com/stefanbuck/github-linker-core/blob/master/file.coffee').should.equal('coffee');
31 | });
32 |
33 | it('file.txt', function() {
34 | (utils.requireType('https://github.com/stefanbuck/github-linker-core/blob/master/file.txt') === undefined).should.equal(true);
35 | });
36 | });
37 |
38 | describe('stripQuotes', function() {
39 |
40 | it('lodash', function() {
41 | utils.stripQuotes({html: function(){return 'lodash';}}).should.equal('lodash');
42 | });
43 |
44 | it('"lodash"', function() {
45 | utils.stripQuotes({html: function(){return '"lodash"';}}).should.equal('lodash');
46 | });
47 |
48 | it('\'lodash\'', function() {
49 | utils.stripQuotes({html: function(){return '\'lodash\'';}}).should.equal('lodash');
50 | });
51 |
52 | it('"lodash\'', function() {
53 | utils.stripQuotes({html: function(){return '"lodash\'';}}).should.equal('lodash');
54 | });
55 |
56 | });
57 | });
58 |
--------------------------------------------------------------------------------
/test/test_manifest_remote.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var githubLinkerCore = require('../');
4 | var assert = require('should');
5 | var _ = require('lodash');
6 | var env = require('jsdom').env;
7 |
8 | describe('manifest', function() {
9 |
10 | describe('package.json', function() {
11 |
12 | describe('remote', function() {
13 |
14 | this.timeout(4000);
15 |
16 | var $, result;
17 | var url = 'https://github.com/stefanbuck/github-linker-core/blob/master/test/fixtures/package.json';
18 |
19 | before(function(done) {
20 | $ = result = null;
21 |
22 | env(url, function(err, window) {
23 | if (err) {
24 | return done(err);
25 | }
26 | $ = require('jquery')(window);
27 | githubLinkerCore($, url, function(err, _result) {
28 | if (err) {
29 | throw err;
30 | }
31 | result = _result;
32 | done();
33 | });
34 | });
35 | });
36 |
37 | it('found dependencies', function() {
38 |
39 | // TODO Evaluate why this doesn't work
40 | // result.should.have.length(10);
41 |
42 | result.length.should.equal(10);
43 | });
44 |
45 | it('check order', function() {
46 | result.length.should.equal(10);
47 | var pkgNames = ['lodash', 'request', 'modernizr', 'backbone', 'jquery', 'unknown-package-name', 'chai', 'gulp', 'yo', 'should'];
48 | _.each(result, function(item, index) {
49 | item.name.should.equal( pkgNames[index] );
50 | });
51 | });
52 |
53 | it('check link replacement', function() {
54 | $('a.github-linker').length.should.equal(10);
55 | });
56 |
57 | it('link https://github.com/lodash/lodash', function() {
58 | var item = _.findWhere(result, {
59 | name: 'lodash'
60 | });
61 |
62 | (item.link === null).should.equal(false);
63 | item.link.should.equal('https://github.com/lodash/lodash');
64 | });
65 |
66 | it('link https://www.npmjs.org/package/request', function() {
67 | var item = _.findWhere(result, {
68 | name: 'request'
69 | });
70 |
71 | (item.link === null).should.equal(false);
72 | item.link.should.equal('https://www.npmjs.org/package/request');
73 | });
74 |
75 | it('link https://github.com/Modernizr/Modernizr', function() {
76 | var item = _.findWhere(result, {
77 | name: 'modernizr'
78 | });
79 |
80 | (item.link === null).should.equal(false);
81 | item.link.should.equal('https://github.com/Modernizr/Modernizr');
82 | });
83 |
84 | it('link https://github.com/jashkenas/backbone/tree/master', function() {
85 | var item = _.findWhere(result, {
86 | name: 'backbone'
87 | });
88 |
89 | (item.link === null).should.equal(false);
90 | item.link.should.equal('https://github.com/jashkenas/backbone/tree/master');
91 | });
92 |
93 | it('link https://github.com/jquery/jquery/tree/1.x-master', function() {
94 | var item = _.findWhere(result, {
95 | name: 'jquery'
96 | });
97 |
98 | (item.link === null).should.equal(false);
99 | item.link.should.equal('https://github.com/jquery/jquery/tree/1.x-master');
100 | });
101 |
102 | it('link https://www.npmjs.org/package/unknown-package-name', function() {
103 | var item = _.findWhere(result, {
104 | name: 'unknown-package-name'
105 | });
106 |
107 | (item.link === null).should.equal(false);
108 | item.link.should.equal('https://www.npmjs.org/package/unknown-package-name');
109 | });
110 | });
111 | });
112 | });
113 |
--------------------------------------------------------------------------------
/test/test_manifest_local.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var githubLinkerCore = require('../');
4 | var fs = require('fs');
5 | var path = require('path');
6 | var assert = require('should');
7 | var _ = require('lodash');
8 | var env = require('jsdom').env;
9 |
10 | describe('manifest', function() {
11 |
12 | describe('package.json', function() {
13 |
14 | describe('local', function() {
15 | var $, result;
16 | var url = 'https://github.com/stefanbuck/github-linker-core/blob/master/test/fixtures/package.json';
17 | var file = path.resolve(__dirname, 'fixtures/package.json.html');
18 |
19 | before(function(done) {
20 | $ = result = null;
21 | var html = fs.readFileSync(file, 'utf-8');
22 |
23 | env(html, function(err, window) {
24 | if (err) {
25 | return done(err);
26 | }
27 | $ = require('jquery')(window);
28 |
29 | githubLinkerCore($, url, function(err, _result) {
30 | if (err) {
31 | throw err;
32 | }
33 | result = _result;
34 | done();
35 | });
36 | });
37 | });
38 |
39 | it('found dependencies', function() {
40 |
41 | // TODO Evaluate why this doesn't work
42 | // result.should.have.length(10);
43 |
44 | result.length.should.equal(10);
45 | });
46 |
47 | it('check order', function() {
48 | result.length.should.equal(10);
49 | var pkgNames = ['lodash', 'request', 'modernizr', 'backbone', 'jquery', 'unknown-package-name', 'chai', 'gulp', 'yo', 'should'];
50 | _.each(result, function(item, index) {
51 | item.name.should.equal( pkgNames[index] );
52 | });
53 | });
54 |
55 | it('check link replacement', function() {
56 | $('a.github-linker').length.should.equal(10);
57 | });
58 |
59 | it('link https://github.com/lodash/lodash', function() {
60 | var item = _.findWhere(result, {
61 | name: 'lodash'
62 | });
63 |
64 | (item.link === null).should.equal(false);
65 | item.link.should.equal('https://github.com/lodash/lodash');
66 | });
67 |
68 | it('link https://www.npmjs.org/package/request', function() {
69 | var item = _.findWhere(result, {
70 | name: 'request'
71 | });
72 |
73 | (item.link === null).should.equal(false);
74 | item.link.should.equal('https://www.npmjs.org/package/request');
75 | });
76 |
77 | it('link https://github.com/Modernizr/Modernizr', function() {
78 | var item = _.findWhere(result, {
79 | name: 'modernizr'
80 | });
81 |
82 | (item.link === null).should.equal(false);
83 | item.link.should.equal('https://github.com/Modernizr/Modernizr');
84 | });
85 |
86 | it('link https://github.com/jashkenas/backbone/tree/master', function() {
87 | var item = _.findWhere(result, {
88 | name: 'backbone'
89 | });
90 |
91 | (item.link === null).should.equal(false);
92 | item.link.should.equal('https://github.com/jashkenas/backbone/tree/master');
93 | });
94 |
95 | it('link https://github.com/jquery/jquery/tree/1.x-master', function() {
96 | var item = _.findWhere(result, {
97 | name: 'jquery'
98 | });
99 |
100 | (item.link === null).should.equal(false);
101 | item.link.should.equal('https://github.com/jquery/jquery/tree/1.x-master');
102 | });
103 |
104 | it('link https://www.npmjs.org/package/unknown-package-name', function() {
105 | var item = _.findWhere(result, {
106 | name: 'unknown-package-name'
107 | });
108 |
109 | (item.link === null).should.equal(false);
110 | item.link.should.equal('https://www.npmjs.org/package/unknown-package-name');
111 | });
112 | });
113 | });
114 | });
115 |
--------------------------------------------------------------------------------
/lib/require.js:
--------------------------------------------------------------------------------
1 | /*
2 | * github-linker-core
3 | * https://github.com/stefanbuck/github-linker
4 | *
5 | * Copyright (c) 2014 Stefan Buck
6 | * Licensed under the MIT license.
7 | */
8 |
9 | 'use strict';
10 |
11 | var util = require('util');
12 | var path = require('path');
13 | var registries = require('github-linker-registries').npm;
14 | var utils = require('./utils');
15 |
16 | // List of nodejs core modules (v0.11.13)
17 | // see: https://github.com/joyent/node/blob/master/lib/repl.js#L72
18 | var coreModules = ['assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'net', 'os', 'path', 'punycode', 'querystring', 'readline', 'stream', 'string_decoder', 'tls', 'tty', 'url', 'util', 'vm', 'zlib', 'smalloc', 'tracing'];
19 | var GITHUBCOM = 'https://github.com';
20 | var NODEAPICOM = 'http://nodejs.org/api/%s.html';
21 | var SORRY = 'Can\'t resolve this require for you, sorry.';
22 |
23 | var getRequireLink = function(url, requireValue) {
24 |
25 | var link = '';
26 |
27 | if (coreModules.indexOf(requireValue) !== -1 ) {
28 |
29 | link = util.format(NODEAPICOM, requireValue);
30 |
31 | } else if (registries[requireValue]) {
32 |
33 | link = registries[requireValue];
34 |
35 | } else {
36 | var basePath = url.replace(GITHUBCOM, '');
37 | var requirePath = path.resolve(path.dirname(basePath), requireValue);
38 | if (path.extname(requirePath)) {
39 | link = requirePath;
40 | } else {
41 | link = 'resolve:' + requirePath;
42 | }
43 | }
44 |
45 | return link;
46 | };
47 |
48 | var attemptToLoadURL = function($, urls, cb) {
49 | var url = urls.shift();
50 | $.ajax({
51 | url: url,
52 | type: 'HEAD'
53 | }).then(function() {
54 | cb(url);
55 | }).fail(function() {
56 | if (urls.length > 0) {
57 | attemptToLoadURL($, urls, cb);
58 | } else {
59 | cb(null);
60 | }
61 | });
62 | };
63 |
64 | var registerClickListener = function($, fileExtension) {
65 | fileExtension = '.' + fileExtension;
66 |
67 | $('body').on('click', 'a.github-linker', function(e) {
68 | utils.showLoader($);
69 | var $el = $(this);
70 | var link = $el.data('href');
71 |
72 | if (link) {
73 | e.stopPropagation();
74 |
75 | if (link.charAt(link.length - 1) === '/') {
76 | link = link.slice(0, -1);
77 | }
78 | var urls = [
79 | GITHUBCOM + link + fileExtension,
80 | GITHUBCOM + link + '/index' + fileExtension,
81 | GITHUBCOM + link.replace('blob', 'tree')
82 | ];
83 |
84 | $el.addClass('tooltipped tooltipped-e').attr('aria-label', 'Loadingg ...');
85 | attemptToLoadURL($, urls, function(link) {
86 | if (link) {
87 | window.location.href = link;
88 | } else {
89 | $el.attr('aria-label', SORRY);
90 | }
91 | });
92 | }
93 | });
94 | };
95 |
96 | module.exports = function($, url, cb) {
97 |
98 | var $requires, $coffeeRequires, $item, name, link, resolveLink;
99 | var result = [];
100 | var type = utils.requireType(url);
101 |
102 | // Search for require dom elements
103 | $requires = $('span.nx').filter(function() {
104 | return $(this).text() === 'require';
105 | }).next().next();
106 |
107 | if (type === 'coffee') {
108 | $coffeeRequires = $('span.nx').filter(function() {
109 | return $(this).text() === 'require';
110 | }).next();
111 | $requires = $.merge($coffeeRequires, $requires);
112 | }
113 |
114 | $requires.each(function(index, item) {
115 | $item = $(item);
116 |
117 | name = utils.stripQuotes($item);
118 | link = getRequireLink(url, name);
119 | resolveLink = false;
120 |
121 | if ( link.indexOf('resolve:') === 0) {
122 | link = link.replace('resolve:', '');
123 | resolveLink = true;
124 | $item.wrap('');
125 | } else {
126 | $item.wrap('');
127 | }
128 |
129 | result.push({
130 | el: $item,
131 | name: name,
132 | link: link,
133 | resolveLink: resolveLink
134 | });
135 | });
136 |
137 | registerClickListener($, type);
138 |
139 | cb(null, result);
140 | };
141 |
--------------------------------------------------------------------------------
/test/test_require_remote.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var githubLinkerCore = require('../');
4 | var assert = require('should');
5 | var _ = require('lodash');
6 | var env = require('jsdom').env;
7 |
8 | describe('require.js', function() {
9 |
10 | describe('local', function() {
11 | var $, result;
12 | var url = 'https://github.com/stefanbuck/github-linker-core/blob/master/test/fixtures/require.js';
13 |
14 | before(function(done) {
15 | $ = result = null;
16 |
17 | env(url, function(err, window) {
18 | if (err) {
19 | return done(err);
20 | }
21 | $ = require('jquery')(window);
22 |
23 | githubLinkerCore($, url, function(err, _result) {
24 | if (err) {
25 | throw err;
26 | }
27 | result = _result;
28 | done();
29 | });
30 | });
31 | });
32 |
33 |
34 | it('found dependencies', function() {
35 |
36 | // TODO Evaluate why this doesn't work
37 | // result.should.have.length(20);
38 |
39 | result.length.should.equal(20);
40 | });
41 |
42 | it('http://nodejs.org/api/path.html', function() {
43 | var item = _.findWhere(result, {
44 | name: 'path'
45 | });
46 |
47 | (item.link === null).should.equal(false);
48 | item.link.should.equal('http://nodejs.org/api/path.html');
49 | });
50 |
51 | it('https://github.com/lodash/lodash', function() {
52 | var item = _.findWhere(result, {
53 | name: 'lodash'
54 | });
55 |
56 | (item.link === null).should.equal(false);
57 | item.link.should.equal('https://github.com/lodash/lodash');
58 | });
59 |
60 | it.skip('unknown-package-name', function() {
61 | var item = _.findWhere(result, {
62 | name: 'unknown-package-name'
63 | });
64 |
65 | (item.link === null).should.equal(false);
66 | item.link.should.equal('tbd');
67 | });
68 |
69 | it('./file.js', function() {
70 | var item = _.findWhere(result, {
71 | name: './file.js'
72 | });
73 |
74 | (item.link === null).should.equal(false);
75 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/fixtures/file.js');
76 | });
77 |
78 | it('./folder/file.js', function() {
79 | var item = _.findWhere(result, {
80 | name: './folder/file.js'
81 | });
82 |
83 | (item.link === null).should.equal(false);
84 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/fixtures/folder/file.js');
85 | });
86 |
87 | it('./file-or-folder', function() {
88 | var item = _.findWhere(result, {
89 | name: './file-or-folder'
90 | });
91 |
92 | (item.link === null).should.equal(false);
93 | item.resolveLink.should.be.ok;
94 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/fixtures/file-or-folder');
95 | });
96 |
97 | it('../file.js', function() {
98 | var item = _.findWhere(result, {
99 | name: '../file.js'
100 | });
101 |
102 | (item.link === null).should.equal(false);
103 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/file.js');
104 | });
105 |
106 | it('../folder/file.js', function() {
107 | var item = _.findWhere(result, {
108 | name: '../folder/file.js'
109 | });
110 |
111 | (item.link === null).should.equal(false);
112 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/folder/file.js');
113 | });
114 |
115 | it('../file-or-folder', function() {
116 | var item = _.findWhere(result, {
117 | name: '../file-or-folder'
118 | });
119 |
120 | (item.link === null).should.equal(false);
121 | item.resolveLink.should.be.ok;
122 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/file-or-folder');
123 | });
124 |
125 | it('../../file.js', function() {
126 | var item = _.findWhere(result, {
127 | name: '../../file.js'
128 | });
129 |
130 | (item.link === null).should.equal(false);
131 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/file.js');
132 | });
133 |
134 | it('../../folder/file.js', function() {
135 | var item = _.findWhere(result, {
136 | name: '../../folder/file.js'
137 | });
138 |
139 | (item.link === null).should.equal(false);
140 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/folder/file.js');
141 | });
142 |
143 | it('../../file-or-folder', function() {
144 | var item = _.findWhere(result, {
145 | name: '../../file-or-folder'
146 | });
147 |
148 | (item.link === null).should.equal(false);
149 | item.resolveLink.should.be.ok;
150 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/file-or-folder');
151 | });
152 |
153 | it('./', function() {
154 | var item = _.findWhere(result, {
155 | name: './'
156 | });
157 |
158 | (item.link === null).should.equal(false);
159 | item.resolveLink.should.be.ok;
160 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/fixtures');
161 | });
162 |
163 | it('..', function() {
164 | var item = _.findWhere(result, {
165 | name: '..'
166 | });
167 |
168 | (item.link === null).should.equal(false);
169 | item.resolveLink.should.be.ok;
170 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test');
171 | });
172 |
173 | it('../', function() {
174 | var item = _.findWhere(result, {
175 | name: '../'
176 | });
177 |
178 | (item.link === null).should.equal(false);
179 | item.resolveLink.should.be.ok;
180 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test');
181 | });
182 |
183 | it('../..', function() {
184 | var item = _.findWhere(result, {
185 | name: '../..'
186 | });
187 |
188 | (item.link === null).should.equal(false);
189 | item.resolveLink.should.be.ok;
190 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master');
191 | });
192 |
193 | it('../../', function() {
194 | var item = _.findWhere(result, {
195 | name: '../../'
196 | });
197 |
198 | (item.link === null).should.equal(false);
199 | item.resolveLink.should.be.ok;
200 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master');
201 | });
202 |
203 | it.skip('.', function() {
204 | var item = _.findWhere(result, {
205 | name: '.'
206 | });
207 |
208 | (item.link === null).should.equal(false);
209 | item.link.should.equal('tbd');
210 | });
211 |
212 | it.skip('...', function() {
213 | var item = _.findWhere(result, {
214 | name: '...'
215 | });
216 |
217 | (item.link === null).should.equal(false);
218 | item.link.should.equal('tbd');
219 | });
220 |
221 | it.skip('/', function() {
222 | var item = _.findWhere(result, {
223 | name: '/'
224 | });
225 |
226 | (item.link === null).should.equal(false);
227 | item.link.should.equal('tbd');
228 | });
229 |
230 | });
231 | });
232 |
--------------------------------------------------------------------------------
/test/test_require_local.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var githubLinkerCore = require('../');
4 | var fs = require('fs');
5 | var path = require('path');
6 | var assert = require('should');
7 | var _ = require('lodash');
8 | var env = require('jsdom').env;
9 |
10 | describe('require.js', function() {
11 |
12 | describe('local', function() {
13 | var $, result;
14 | var url = 'https://github.com/stefanbuck/github-linker-core/blob/master/test/fixtures/require.js';
15 | var file = path.resolve(__dirname, 'fixtures/require.js.html');
16 |
17 | before(function(done) {
18 | $ = result = null;
19 | var html = fs.readFileSync(file, 'utf-8');
20 |
21 | env(html, function(err, window) {
22 | if (err) {
23 | return done(err);
24 | }
25 | $ = require('jquery')(window);
26 |
27 | githubLinkerCore($, url, function(err, _result) {
28 | if (err) {
29 | throw err;
30 | }
31 | result = _result;
32 | done();
33 | });
34 | });
35 | });
36 |
37 | it('found dependencies', function() {
38 |
39 | // TODO Evaluate why this doesn't work
40 | // result.should.have.length(20);
41 |
42 | result.length.should.equal(20);
43 | });
44 |
45 | it('http://nodejs.org/api/path.html', function() {
46 | var item = _.findWhere(result, {
47 | name: 'path'
48 | });
49 |
50 | (item.link === null).should.equal(false);
51 | item.link.should.equal('http://nodejs.org/api/path.html');
52 | });
53 |
54 | it('https://github.com/lodash/lodash', function() {
55 | var item = _.findWhere(result, {
56 | name: 'lodash'
57 | });
58 |
59 | (item.link === null).should.equal(false);
60 | item.link.should.equal('https://github.com/lodash/lodash');
61 | });
62 |
63 | it.skip('unknown-package-name', function() {
64 | var item = _.findWhere(result, {
65 | name: 'unknown-package-name'
66 | });
67 |
68 | (item.link === null).should.equal(false);
69 | item.link.should.equal('tbd');
70 | });
71 |
72 | it('./file.js', function() {
73 | var item = _.findWhere(result, {
74 | name: './file.js'
75 | });
76 |
77 | (item.link === null).should.equal(false);
78 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/fixtures/file.js');
79 | });
80 |
81 | it('./folder/file.js', function() {
82 | var item = _.findWhere(result, {
83 | name: './folder/file.js'
84 | });
85 |
86 | (item.link === null).should.equal(false);
87 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/fixtures/folder/file.js');
88 | });
89 |
90 | it('./file-or-folder', function() {
91 | var item = _.findWhere(result, {
92 | name: './file-or-folder'
93 | });
94 |
95 | (item.link === null).should.equal(false);
96 | item.resolveLink.should.be.ok;
97 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/fixtures/file-or-folder');
98 | });
99 |
100 | it('../file.js', function() {
101 | var item = _.findWhere(result, {
102 | name: '../file.js'
103 | });
104 |
105 | (item.link === null).should.equal(false);
106 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/file.js');
107 | });
108 |
109 | it('../folder/file.js', function() {
110 | var item = _.findWhere(result, {
111 | name: '../folder/file.js'
112 | });
113 |
114 | (item.link === null).should.equal(false);
115 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/folder/file.js');
116 | });
117 |
118 | it('../file-or-folder', function() {
119 | var item = _.findWhere(result, {
120 | name: '../file-or-folder'
121 | });
122 |
123 | (item.link === null).should.equal(false);
124 | item.resolveLink.should.be.ok;
125 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/file-or-folder');
126 | });
127 |
128 | it('../../file.js', function() {
129 | var item = _.findWhere(result, {
130 | name: '../../file.js'
131 | });
132 |
133 | (item.link === null).should.equal(false);
134 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/file.js');
135 | });
136 |
137 | it('../../folder/file.js', function() {
138 | var item = _.findWhere(result, {
139 | name: '../../folder/file.js'
140 | });
141 |
142 | (item.link === null).should.equal(false);
143 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/folder/file.js');
144 | });
145 |
146 | it('../../file-or-folder', function() {
147 | var item = _.findWhere(result, {
148 | name: '../../file-or-folder'
149 | });
150 |
151 | (item.link === null).should.equal(false);
152 | item.resolveLink.should.be.ok;
153 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/file-or-folder');
154 | });
155 |
156 | it('./', function() {
157 | var item = _.findWhere(result, {
158 | name: './'
159 | });
160 |
161 | (item.link === null).should.equal(false);
162 | item.resolveLink.should.be.ok;
163 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test/fixtures');
164 | });
165 |
166 | it('..', function() {
167 | var item = _.findWhere(result, {
168 | name: '..'
169 | });
170 |
171 | (item.link === null).should.equal(false);
172 | item.resolveLink.should.be.ok;
173 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test');
174 | });
175 |
176 | it('../', function() {
177 | var item = _.findWhere(result, {
178 | name: '../'
179 | });
180 |
181 | (item.link === null).should.equal(false);
182 | item.resolveLink.should.be.ok;
183 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master/test');
184 | });
185 |
186 | it('../..', function() {
187 | var item = _.findWhere(result, {
188 | name: '../..'
189 | });
190 |
191 | (item.link === null).should.equal(false);
192 | item.resolveLink.should.be.ok;
193 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master');
194 | });
195 |
196 | it('../../', function() {
197 | var item = _.findWhere(result, {
198 | name: '../../'
199 | });
200 |
201 | (item.link === null).should.equal(false);
202 | item.resolveLink.should.be.ok;
203 | item.link.should.equal('/stefanbuck/github-linker-core/blob/master');
204 | });
205 |
206 | it.skip('.', function() {
207 | var item = _.findWhere(result, {
208 | name: '.'
209 | });
210 |
211 | (item.link === null).should.equal(false);
212 | item.link.should.equal('tbd');
213 | });
214 |
215 | it.skip('...', function() {
216 | var item = _.findWhere(result, {
217 | name: '...'
218 | });
219 |
220 | (item.link === null).should.equal(false);
221 | item.link.should.equal('tbd');
222 | });
223 |
224 | it.skip('/', function() {
225 | var item = _.findWhere(result, {
226 | name: '/'
227 | });
228 |
229 | (item.link === null).should.equal(false);
230 | item.link.should.equal('tbd');
231 | });
232 |
233 | it('resolve url', function() {
234 | var item = _.findWhere(result, {
235 | name: '../../file-or-folder'
236 | });
237 |
238 | item.el.trigger('click');
239 | });
240 |
241 | });
242 | });
243 |
--------------------------------------------------------------------------------
/test/fixtures/require.js.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |