Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: madrobby/microjs.com
base: cb36bd749b
...
head fork: madrobby/microjs.com
compare: da8009422c
Checking mergeability… Don't worry, you can still create the pull request.
  • 6 commits
  • 13 files changed
  • 0 commit comments
  • 1 contributor
View
8 atom.xml
@@ -1642,5 +1642,13 @@
<summary>Generate repeatable random data</summary>
</entry>
+ <entry>
+ <title>Async GA</title>
+ <link href="http://mathiasbynens.be/notes/async-analytics-snippet" />
+ <id>urn:uuid:b35eaf70-903c-11e1-80f8-93b1a4a3e96b</id>
+ <updated>2012-04-27'T'07:43:36Z</updated>
+ <summary>Reduced Google's original analytics snippet by one third, with better performance.</summary>
+ </entry>
+
</feed>
View
3  data.js
@@ -1280,6 +1280,8 @@ var MicroJS = [
url: "http://wavded.github.com/humane-js/",
source: "https://raw.github.com/wavded/humane-js/master/humane.js"
},
+ /*
+ user no longer on GitHub
{
name: "JSFace",
tags: ["oop", "language", "commonjs", "node", "class"],
@@ -1287,6 +1289,7 @@ var MicroJS = [
url: "https://github.com/tannhu/jsface",
source: "https://raw.github.com/tannhu/jsface/master/jsface.js"
},
+ */
{
name: "Radio.js",
tags: ["events", "pubsub"],
View
39 index.html
@@ -392,7 +392,7 @@
line-height: 56px;
font-size: 40px;
}
- .title .gh {
+ .title .stat {
margin-top: -14px;
text-align: left;
font-size: 11px;
@@ -400,18 +400,21 @@
height: 19px;
opacity: 0.5;
}
- .title .gh span {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAABECAYAAACI7LWAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlVJREFUeNrsls9LVFEUx9/zd+b4q5hFpmMYiCCI+0ChVbsWIQNC0m5WQaJEgrtauhVajTtdOaL/gLgzBJ9Ku8QfUJAQM+WiiPT5Pfq9cbpz38ygCS7egY+8e98533vfOXfu0Q/D0LuKVTnm0iAAolwgIefSRd6yA5IAOVAAGZBS71KcK9AnYd5pAXmxCtJWsBYZok/OFpCgQypnwwsTx0Ah9pY+h4z5KxBwi54ScFmWPhnGeD6rIH+amZYfZRI/CHbp122qsAeOQU8FlWuh754WMLZbgcC+q4yhKk26ghwkOE6ZHWyBUZDluBu8U+ssgWHwguNRxhy4ymjqHKiVV60DV1RGfZDMgckpgUAdpn8Okk7ic5Dn1vqsxEmJM3yXp2/Rb0F/TuBIYGC2rfFL/JxToI3P+fOEOcy/jvsgFogFYoH/KDAAZsEmmeWcV6q5CvfBCi+QL2AKTIADcAoWQYeO0cHPwDcGfwR14CHoA7fAjhJ+agtMcwVjY6BXjfvBGzX+AyYltoZf0ii3k5Ubnz3zlK1MWzX4aedgBBxxhW1wm59wDzSCfb77Cp64ciD0gHk6fgYzxORmwU5i1KUqLXwEPAINYB28BzvxrRwLxAKxwFUFkuAXWL6swF1QC44uIyDBC3xeK9eZbFp5Q5+AVy6fUsHtKvhllF9UcNIKruNuKhJIOlbeAB/YbMoKjDP4tZqbYz/M2P52FTpBF58/gTvskaYKTSxnZBXM6sIxGAaPwXfO/eb/DCVb2wm7sliNY66e48iDlFSOnmr/Yg908M3ojWcCDABDekqFJMdtvgAAAABJRU5ErkJggg==");
+ .title .stat span {
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAABeCAYAAAAqoZR9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAupJREFUeNrsmM9rE0EUx3e1Vq3Gxh/k4K9EKkhBMN4FA5689SAlUNB4y0lUFFEQFPQovRU8pTd7MqJ/QIo3Rehq8WZJWlCwIIn2oIjt+n363fA6O7tZWws97INP2Z197zuT92ZnuuP6vu+sx7ZY2srAA6LcIT7byiFvGQHJgDrogCrIq2d5tnXokwmeaQF5MA3KRrAWOUufuikgQQtUrvl/TRw9hdgD+iwwpivgcYiOErBZjT5VxjguqyB/9jAt33ok/jSYo18hqEITLIGhBJUbpG9TCwQ2l0CgZSujr0pTTpCDDO/zwQjegjFQ430BPFT9PAMlcJn3Y4yZt5UxqLOnep42JlyojHoiBROmrgQ8NZlWTSSdxIugzaENG4mTElf5rE3f0Lugf45nSaAXDFvjxrzOebCX1+0/CbOYuxHrQSqQCqQC/1HgFJgAM2SCbU7c5iocBi+4gHwCd8ANMA9WwFNwSMfo4AvgC4Pfg35wHAyDnWBWCY+YAnfZQ2CXwAl1fxLcVve/wE2J7eMvGZDVyciNyz1zhVuZtq3gu5mDUbDIHt6BXfwJB8EAaPHZZ3DelgNhCDyh40fwiAS5mTKTGLWoyhY+Cs6AHeAVeAxm01U5FUgFUoH1CuTAD/B8rQIHwDawuBYBCZ7i9cteO5NJliv0Mrhm84kL3qeCr0T5RQXnjOB+jiaRQM7S8xvwmptNT4HrDL6l2ia5H1ZNf7MKR8BRXn8A+7lHBlXYzXJGViHoXVgCJXAOfGXbT/7PELu1LXNXFuuztG3nfeREyilHR23/Ysd0cLo3pgKpwGYSSGR4YyugAcbjnK7KCmRpL6rvhKZ8bEQJjCunimpvWM5TKjaBkuHU5NBt1u6uSEqgwC+0bMLUyBFpq1sF13XlkG3yH3JbDHXGhDX8ZFaKSuZIguBadyLxiK+gNLKhM8PVJsfE981hzyQctlSmaBu2bN33pDwxgTLRQhVybfPBPAJlhZzNeZb2W4ABABjYikWzwWlLAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
display: inline-block;
padding: 1px 8px 0 24px;
}
- .title .gh .w {
+ .title .stat .w {
background-position: 4px -24px;
}
- .title .gh .f {
+ .title .stat .f {
background-position: 4px -50px;
}
+ .title .stat .t {
+ background-position: 4px -75px;
+ }
li div.size {
float: right;
margin: 0 0 0 30px;
@@ -527,6 +530,7 @@
background: #000;
border: solid 1px #555;
cursor: pointer;
+ z-index: 1;
}
#ineed_select > div {
height: 28px;
@@ -634,19 +638,19 @@ <h1 class="overlay">
return s
}
, render = function (results){
- var html = [], i = results.length;
+ var html = [], i = results.length, r
while (i--) {
- if (!results[i]._rendered) {
- results[i].gh = results[i].ghwatchers
- ? t('<div class="gh"><span class="w">{ghwatchers}</span><span class="f">{ghforks}</span></div>', results[i])
- : ''
- results[i]._rendered = t(
- '<li><a href="{url}"><div class="size">{size}</div><div class="title"><h3>{name}</h3>{gh}</div>{description}</a></li>'
- , results[i])
+ if (!(r = results[i])._rendered) {
+ r.stat =
+ '<div class="stat">'
+ + (r.ghwatchers ? t('<span class="w">{ghwatchers}</span><span class="f">{ghforks}</span>', r) : '')
+ + (r.tweets ? t('<span class="t">{tweets}</span>', r) : '')
+ + '</div>'
+ r._rendered = t('<li><a href="{url}"><div class="size">{size}</div><div class="title"><h3>{name}</h3>{stat}</div>{description}</a></li>', r)
}
html.push(results[i]._rendered)
}
- $results.innerHTML = html.join('');
+ $results.innerHTML = html.join('')
}
MicroJS.sort(function () { return 0.5 - Math.random() })
@@ -738,7 +742,7 @@ <h1 class="overlay">
, fn = args.shift(), timeout = args.shift()
return function() {
var _args = args.concat(Array.prototype.slice.call(arguments))
- if (!!tid) clearTimeout(tid)
+ if (tid) clearTimeout(tid)
tid = setTimeout(function() { fn.apply(null, _args) }, timeout)
}
}
@@ -749,7 +753,7 @@ <h1 class="overlay">
$ineedText.value = el.textContent || el.innerText
e && keydownListener({ keyCode: 13 })
}
- , keydownDelayed = cumulativeDelayed(function (e) { search() }, 250)
+ , keydownDelayed = cumulativeDelayed(function () { search() }, 250)
, showsearch = function () { showopt(); search() }
// make our pseudo-select box work as if it was a real select box
, keydownListener = function (e) {
@@ -764,8 +768,7 @@ <h1 class="overlay">
hideopt(); search()
break;
default:
- if (e.target.value) { hideopt(); keydownDelayed(e) }
- else showsearch()
+ hideopt(); keydownDelayed()
}
}
// arrow-up
View
4 lib/fetcher.js
@@ -1,11 +1,11 @@
var zip = require('zip')
, request = require('request')
- , requestPool = { maxSockets: 10 }
+ , requestPool = { maxSockets: 20 }
, unzip = function (zipEntry, buffer) {
var reader = zip.Reader(buffer)
- data = null
+ , data = null
// iterate through zipfile entries looking for the right name
reader.forEach(function(entry) {
if (zipEntry === entry._header.file_name) {
View
7 lib/gitstats.js
@@ -1,6 +1,6 @@
var request = require('request')
, githubSpecRegex = /^([^\/]+)\/(.*)$/
- , repoRegex = /github.com\/([\.\-\w]+)\/([^$/]+)/
+ , repoRegex = /github.com\/([\.\-\w]+)\/([^$\/]+)/
, GIT_API_REPO_URL = 'https://api.github.com/repos/{user}/{project}'
var GitStats = {
@@ -29,14 +29,14 @@ var GitStats = {
var data = JSON.parse(body)
if (!!data.forks && !!data.watchers) {
- this.success(lib, {
+ callback(null, {
forks: data.forks
, watchers: data.watchers
, url: data.html_url
, lastPush: data.pushed_at
//, user: user
//, project: project
- }, callback)
+ })
} else {
this.warn(lib, 'Looks like a GitHub project but can\'t get data from GitHub API')
callback()
@@ -48,7 +48,6 @@ var GitStats = {
module.exports.create = function (main, config) {
var gitStats = Object.create(GitStats)
- gitStats.success = main.gitSuccess.bind(main)
gitStats.warn = main.warn.bind(main)
gitStats.error = main.error.bind(main)
return gitStats
View
88 lib/main.js
@@ -33,55 +33,50 @@ var Main = {
return console.log(err.red)
this.data = data
- this.expectedTicks = data.length// * 2 // 2 ticks each lib, one for `process`, one for `gitstats`
+ this.expectedTicks = data.length
async.forEach(
data
- , this.tickWrap(this.processor.processLibrary, this.processor)
+ , this.processLibrary.bind(this)
, this.finish.bind(this)
)
}
- // wrap the function in another function that will increment 'ticks' and call progress() for us
- , tickWrap: function (fn, ctx) {
- return function (lib, callback) {
- fn.call(ctx, lib, function () {
- this.ticks++
- this.progress()
- callback()
- }.bind(this))
- }.bind(this)
- }
-
- // called when a library won't be included in the output, for whatever reason
- , error: function (lib, err, callback) {
- this.logger.log(ERROR, lib.name || 'UNKNOWN LIBRARY', err, lib.source ? lib.source : null)
- this.errorCount++
- callback()
- }
-
- // called when the library will be included but there is something odd
- , warn: function (lib, warning) {
- this.logger.log(WARNING, lib.name, warning)
- this.progress() // need to call this to redraw the progress bar after printing the warning
- }
-
- // called when the library is checked and sized and ready to pack into the output
- , success: function (lib, sizes, callback) {
- this.gitstats.processLibrary(lib, this.complete.bind(this, lib, sizes, callback))
+ , processLibrary: function (lib, callback) {
+ async.parallel(
+ {
+ sizes: this.processor.processLibrary.bind(this.processor, lib)
+ , ghstats: this.gitstats.processLibrary.bind(this.gitstats, lib)
+ , twstats: this.twitterstats.processLibrary.bind(this.twitterstats, lib)
+ }
+ , function (err, data) {
+ this.ticks++
+ if (err)
+ callback(err)
+ else
+ this.complete(lib, data.sizes, data.ghstats, data.twstats, callback)
+ this.progress()
+ }.bind(this)
+ )
}
- , complete: function (lib, sizes, callback) {
+ , complete: function (lib, sizes, ghstats, twstats, callback) {
+ if (ghstats) {
+ lib.ghwatchers = strings.prettyLong(ghstats.watchers)
+ lib.ghforks = strings.prettyLong(ghstats.forks)
+ lib.ghlastpush = ghstats.lastPush
+ }
if (lib.ghlastpush && new Date(lib.ghlastpush).isBefore(this.ghLastPushCutoff)) {
this.warn(lib,'Too old! Last pushed to GitHub @ ' + new Date(lib.ghlastpush).toFormat('DD/MMM/YY') + ', ignoring')
callback()
} else {
// cleanup so we don't waste space
delete lib.ghlastpush
- delete lib.source
- delete lib.github
+ ;delete lib.source
+ ;delete lib.github
// overwrite the original size estimate with actual size
lib.size = strings.sizeToString(sizes.gzipped)
+ lib.tweets = strings.prettyLong(twstats.count)
this.atom.processLibrary(lib, function (err) {
if (err) {
@@ -93,21 +88,28 @@ var Main = {
SUCCESS
, lib.name
, ( 'raw: ' + strings.lpad(strings.sizeToString(sizes.raw), 8)
- + ', minified: ' + strings.lpad(strings.sizeToString(sizes.minified), 8)
- + ', gzipped: ' + strings.lpad(strings.sizeToString(sizes.gzipped), 8)
+ + ', minified: ' + strings.lpad(strings.sizeToString(sizes.minified), 7)
+ + ', gzipped: ' + strings.lpad(strings.sizeToString(sizes.gzipped), 6)
+ + ', watchers: ' + strings.lpad(ghstats ? lib.ghwatchers : '-', 4)
+ + ', forks: ' + strings.lpad(ghstats ? lib.ghforks : '-', 3)
+ + ', tweets: ' + strings.lpad(lib.tweets, 4)
))
callback()
}.bind(this))
}
}
- , gitSuccess: function (lib, ghData, callback) {
- if (ghData) {
- lib.ghwatchers = strings.prettyLong(ghData.watchers)
- lib.ghforks = strings.prettyLong(ghData.forks)
- lib.ghlastpush = ghData.lastPush
- }
- callback()
+ // called when a library won't be included in the output, for whatever reason
+ , error: function (lib, err, callback) {
+ this.logger.log(ERROR, lib.name || 'UNKNOWN LIBRARY', err, lib.source ? lib.source : null)
+ this.errorCount++
+ callback(err)
+ }
+
+ // called when the library will be included but there is something odd
+ , warn: function (lib, warning) {
+ this.logger.log(WARNING, lib.name, warning)
+ this.progress() // need to call this to redraw the progress bar after printing the warning
}
// called on error or success, to iterate our counter and write the output if we're all done
@@ -137,11 +139,10 @@ var Main = {
}.bind(this))
}
- // shortcut
, progress: function () {
this.logger.progress(this.ticks, this.expectedTicks)
}
-}
+ }
module.exports.create = function (config) {
var main = Object.create(Main)
@@ -149,6 +150,7 @@ module.exports.create = function (config) {
main.output = require('./output').create(config.outFile)
main.processor = require('./processor').create(main, config)
main.gitstats = require('./gitstats').create(main, config)
+ main.twitterstats = require('./twitterstats').create(main, config)
main.atom = require('./atom')
main.logger = require('./logger').create(config)
main.ghLastPushCutoff = new Date().addMonths(-(config.githubLastPushCutoffMonths))
View
7 lib/processor.js
@@ -36,7 +36,7 @@ var Processor = {
if (!/^(http|ftp)/.test(source) && /function/.test(source)) {
lib.novalidate = true
data += source
- callback()
+ return callback()
} else {
// source is a zip with a bang-path to the file within the zip?
if (match = source.match(/^(.*\.zip)!\/(.*$)/)) {
@@ -76,15 +76,14 @@ var Processor = {
return this.error(lib, insane + ', ignoring', callback)
// holy moly! we got here?
- this.success(lib, sizes, callback)
+ callback(null, sizes)
}
}
module.exports.create = function (main, config) {
var processor = Object.create(Processor)
processor.error = main.error.bind(main)
- processor.success = main.success.bind(main)
processor.warn = main.warn.bind(main)
processor.validator = require('./validator').create(config)
return processor
-}
+}
View
16 lib/sizer.js
@@ -12,16 +12,14 @@ module.exports = function(source, callback) {
uglifyParser.parse(source))))
gzip(minified, function(err, data) {
- if (err) callback(err)
- else {
- callback(null, {
- raw: source.length
- , minified: minified.length
- , gzipped: data.length
- })
- }
+ if (err) return callback(err)
+ callback(null, {
+ raw: source.length
+ , minified: minified.length
+ , gzipped: data.length
+ })
})
} catch (ex) {
- callback && callback(ex)
+ callback(ex)
}
}
View
33 lib/twitterstats.js
@@ -0,0 +1,33 @@
+var request = require('request')
+ , TWITTER_API_URL = 'http://urls.api.twitter.com/1/urls/count.json?url={url}'
+
+var TwitterStats = {
+ processLibrary: function (lib, callback) {
+ request(
+ TWITTER_API_URL.replace('{url}', encodeURIComponent(lib.url))
+ , function (err, response, body) {
+ if (err)
+ return this.error(
+ lib
+ , 'Error requesting tweet count from Twitter for ' + lib.url + ': ' + err
+ , callback
+ )
+ var data = JSON.parse(body)
+
+ if (typeof data.count == 'number') {
+ callback(null, data)
+ } else {
+ this.warn(lib, 'Couldn\'t get tweet count from Twitter API')
+ callback()
+ }
+ }.bind(this)
+ )
+ }
+}
+
+module.exports.create = function (main, config) {
+ var twitterStats = Object.create(TwitterStats)
+ twitterStats.warn = main.warn.bind(main)
+ twitterStats.error = main.error.bind(main)
+ return twitterStats
+}
View
BIN  resources/github.png
Deleted file not rendered
View
BIN  resources/github.psd
Deleted file not rendered
View
BIN  resources/icons.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  resources/icons.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

No commit comments for this range

Something went wrong with that request. Please try again.