Permalink
Browse files

Merge branch 'packaging'

fixes #3
  • Loading branch information...
2 parents 766f8e9 + bfb9ac2 commit 1ba446a885706dca12ed0e8262aede62d46111fe @jneen committed Jan 5, 2012
Showing with 79 additions and 21 deletions.
  1. +29 −10 Makefile
  2. +1 −1 index.js
  3. +1 −0 package.json
  4. +1 −0 src/p.amd.post.js
  5. +1 −0 src/p.commonjs.post.js
  6. +46 −10 src/p.js
View
@@ -1,17 +1,36 @@
-SRC = src/p.js
-UGLY = build/p.min.js
-UGLIFYJS ?= uglifyjs
-CLEAN += $(UGLY)
-
+# -*- globals -*- #
+SRC_DIR = src
+BUILD_DIR = build
+CLEAN += $(BUILD_DIR)/*
+SRC = $(SRC_DIR)/p.js
-all: $(UGLY) report
+.PHONY: all
+all: minify commonjs amd report
# -*- minification -*- #
+UGLIFYJS ?= uglifyjs
+UGLIFY_OPTS += --lift-vars --unsafe
+UGLY = $(BUILD_DIR)/p.min.js
+
$(UGLY): $(SRC)
- $(UGLIFYJS) $(SRC) > $(UGLY)
+ $(UGLIFYJS) $< > $@
+
+$(BUILD_DIR)/%.min.js: $(BUILD_DIR)/%.js
+ $(UGLIFYJS) $< > $@
+
+minify: $(UGLY)
+
+# special builds
+COMMONJS = $(BUILD_DIR)/p.commonjs.js
+
+$(BUILD_DIR)/p.%.js: $(SRC) $(SRC_DIR)/p.%.post.js
+ cat $^ > $@
+
+.PHONY: commonjs
+commonjs: $(COMMONJS) $(BUILD_DIR)/p.commonjs.min.js
-$(PRETTY): $(SRC)
- $(UGLIFYJS) -b $(SRC) > $(UGLY)
+.PHONY: amd
+amd: $(BUILD_DIR)/p.amd.js $(BUILD_DIR)/p.amd.min.js
.PHONY: report
report: $(UGLY)
@@ -21,7 +40,7 @@ report: $(UGLY)
MOCHA ?= mocha
TESTS = ./test/*.test.js
.PHONY: test
-test: $(UGLY)
+test: $(COMMONJS)
$(MOCHA) $(TESTS)
# -*- packaging -*- #
View
@@ -1,2 +1,2 @@
-exports.P = require('./src/p').P;
+exports.P = require('./build/p.commonjs').P;
exports.version = JSON.parse(require('fs').readFileSync(__dirname + '/package.json')).version;
View
@@ -12,6 +12,7 @@
"mocha": "0.8.1"
},
"scripts": {
+ "install": "make commonjs",
"test": "make test"
}
}
View
@@ -0,0 +1 @@
+define('pjs', P);
View
@@ -0,0 +1 @@
+exports.P = P;
View
@@ -1,36 +1,70 @@
var P = (function(slice, prototype, hasOwnProperty, undefined) {
+ // helper functions that also help minification
function isObject(o) { return typeof o === 'object'; }
function isFunction(f) { return typeof f === 'function'; }
- function P(_superclass, definition) {
+ function P(_superclass /* = Object */, definition) {
+ // handle the case where no superclass is given
+ if (definition === undefined) {
+ definition = _superclass;
+ _superclass = Object;
+ }
+
+ // C is the class to be returned.
+ // There are three ways C will be called:
+ //
+ // 1) We call `new C` to create a new uninitialized object.
+ // The behavior is similar to Object.create, where the prototype
+ // relationship is set up, but the ::init method is not run.
+ // Note that in this case we have `this instanceof C`, so we don't
+ // spring the first trap. Also, `args` is undefined, so the initializer
+ // doesn't get run.
+ //
+ // 2) A user will simply call C(a, b, c, ...) to create a new object with
+ // initialization. This allows the user to create objects without `new`,
+ // and in particular to initialize objects with variable arguments, which
+ // is impossible with tne `new` keyword. Note that in this case,
+ // !(this instanceof C) springs the return trap at the beginning, and
+ // C is called with the `new` keyword and one argument, which is the
+ // Arguments object passed in.
+ //
+ // 3) For internal use only, if new C(args) is called, where args is an
+ // Arguments object. In this case, the presence of `new` means the
+ // return trap is not sprung, but the initializer is called if present.
+ //
+ // TODO: the Chrome inspector shows all created objects as `C` rather than `Object`.
+ // Setting the .name property seems to have no effect. Is there a way to override
+ // this behavior?
function C(args) {
var self = this;
if (!(self instanceof C)) return new C(arguments);
if (args && isFunction(self.init)) self.init.apply(self, args);
}
- if (definition === undefined) {
- definition = _superclass;
- _superclass = Object;
- }
- else if (isObject(_superclass[prototype])) {
- C[prototype] = new _superclass;
- }
+ // set up the prototype of the new class
+ // note that this resolves to `new Object`
+ // if the superclass isn't given
+ C[prototype] = new _superclass;
var proto = C[prototype]
, _super = _superclass[prototype]
, extensions = {}
;
+ // set the constructor property, for convenience
proto.constructor = C;
if (isFunction(definition)) {
+ // call the defining function with all the arguments you need
+ // extensions captures the return value.
extensions = definition.call(C, proto, _super, C, _superclass);
}
else if (isObject(definition)) {
+ // if you passed an object instead, we'll take it
extensions = definition;
}
+ // ...and extend it
if (isObject(extensions)) {
for (var ext in extensions) {
if (hasOwnProperty.call(extensions, ext)) {
@@ -42,7 +76,9 @@ var P = (function(slice, prototype, hasOwnProperty, undefined) {
return C;
}
+ // ship it
return P;
-})([].slice, 'prototype', ({}).hasOwnProperty);
-if (typeof exports !== 'undefined') exports.P = P
+ // as a minifier optimization, we've closured in a few helper functions
+ // and the string 'prototype' (C[p] is much shorter than C.prototype)
+})([].slice, 'prototype', ({}).hasOwnProperty);

0 comments on commit 1ba446a

Please sign in to comment.