Skip to content

Commit

Permalink
Start PDoc integration.
Browse files Browse the repository at this point in the history
  • Loading branch information
samleb authored and savetheclocktower committed Jan 12, 2009
1 parent 24fb692 commit b2597ec
Show file tree
Hide file tree
Showing 16 changed files with 1,001 additions and 16 deletions.
36 changes: 24 additions & 12 deletions Rakefile
Expand Up @@ -10,29 +10,41 @@ PROTOTYPE_TEST_UNIT_DIR = File.join(PROTOTYPE_TEST_DIR, 'unit')
PROTOTYPE_TMP_DIR = File.join(PROTOTYPE_TEST_UNIT_DIR, 'tmp')
PROTOTYPE_VERSION = '1.6.0.3'

$:.unshift File.join(PROTOTYPE_ROOT, 'lib')

task :default => [:dist, :dist_helper, :package, :clean_package_source]

desc "Builds the distribution."
task :dist do
$:.unshift File.join(PROTOTYPE_ROOT, 'lib')
require 'protodoc'

Dir.chdir(PROTOTYPE_SRC_DIR) do
File.open(File.join(PROTOTYPE_DIST_DIR, 'prototype.js'), 'w+') do |dist|
dist << Protodoc::Preprocessor.new('prototype.js')
end

File.open(File.join(PROTOTYPE_DIST_DIR, 'prototype.js'), 'w+') do |dist|
source = File.join(PROTOTYPE_SRC_DIR, 'prototype.js')
dist << Protodoc::Preprocessor.new(source, :strip_documentation => true)
end
end

desc "Builds the documentation."
task :doc do
require 'protodoc'
require 'pdoc'

Tempfile.open("prototype-doc") do |temp|
source = File.join(PROTOTYPE_SRC_DIR, 'prototype.js')
temp << Protodoc::Preprocessor.new(source, :strip_documentation => false)
temp.flush
rm_rf PROTOTYPE_DOC_DIR
PDoc::Runner.new(temp.path, :output => PROTOTYPE_DOC_DIR).run
end
end

desc "Builds the updating helper."
task :dist_helper do
$:.unshift File.join(PROTOTYPE_ROOT, 'lib')
require 'protodoc'

Dir.chdir(File.join(PROTOTYPE_ROOT, 'ext', 'update_helper')) do
File.open(File.join(PROTOTYPE_DIST_DIR, 'prototype_update_helper.js'), 'w+') do |dist|
dist << Protodoc::Preprocessor.new('prototype_update_helper.js')
end

File.open(File.join(PROTOTYPE_DIST_DIR, 'prototype_update_helper.js'), 'w+') do |dist|
source = File.join(PROTOTYPE_ROOT, 'ext', 'update_helper', 'prototype_update_helper.js')
dist << Protodoc::Preprocessor.new(source)
end
end

Expand Down
24 changes: 20 additions & 4 deletions lib/protodoc.rb
Expand Up @@ -8,27 +8,43 @@ def lines
def strip_whitespace_at_line_ends
lines.map {|line| line.gsub(/\s+$/, '')} * $/
end

def strip_pdoc_comments
gsub %r{\s*/\*\*.*?\*\*/}m, "\n"
end
end

module Protodoc
module Environment
def include(*filenames)
filenames.map {|filename| Preprocessor.new(filename).to_s}.join("\n")
filenames.map do |filename|
Preprocessor.new(expand_path(filename), @options).result
end.join("\n")
end
end

class Preprocessor
include Environment

def initialize(filename)
def initialize(filename, options = { })
filename = File.join(filename.split('/'))
@filename = File.expand_path(filename)
@template = ERB.new(IO.read(@filename), nil, '%')
@options = options
end

def to_s
@template.result(binding).strip_whitespace_at_line_ends
def expand_path(filename)
File.join(File.dirname(@filename), filename)
end

def result
result = @template.result(binding)
result = result.strip_whitespace_at_line_ends
result = result.strip_pdoc_comments if @options[:strip_documentation]
result
end

alias_method :to_s, :result
end
end

Expand Down
122 changes: 122 additions & 0 deletions src/lang/array.js
@@ -1,3 +1,11 @@
/** section: lang, alias of: Array.from
* $A(iterable) -> Array
*
* Accepts an array-like collection (anything with numeric indices) and returns
* its equivalent as an actual Array object.
* This method is a convenience alias of [[Array.from]], but is the preferred way
* of casting to an Array.
**/
function $A(iterable) {
if (!iterable) return [];
if (iterable.toArray) return iterable.toArray();
Expand All @@ -21,6 +29,14 @@ if (Prototype.Browser.WebKit) {
};
}

/** section: lang
* $w(string) -> Array
* - string (String): A string with zero or more spaces.
*
* Splits a string into an array, treating all whitespace as delimiters.
*
* Equivalent to Ruby's `%w{foo bar}` or Perl's `qw(foo bar)`.
**/
function $w(string) {
if (!Object.isString(string)) return [];
string = string.strip();
Expand All @@ -29,6 +45,9 @@ function $w(string) {

Array.from = $A;

/** section: lang
* Array
**/
(function() {
var arrayProto = Array.prototype,
slice = arrayProto.slice,
Expand All @@ -40,25 +59,49 @@ Array.from = $A;
}
if (!_each) _each = each;

/**
* Array#clear() -> Array
* Empties an array.
**/
function clear() {
this.length = 0;
return this;
}

/**
* Array#first() -> ?
* Returns the array's first item.
**/
function first() {
return this[0];
}

/**
* Array#last() -> ?
* Returns the array's last item.
**/
function last() {
return this[this.length - 1];
}

/**
* Array#compact() -> Array
* Trims the array of `null`, `undefined`, or other "falsy" values.
**/
function compact() {
return this.select(function(value) {
return value != null;
});
}

/**
* Array#flatten() -> Array
* Returns a “flat” (one-dimensional) version of the array.
*
* Nested arrays are recursively injected “inline”. This can prove very
* useful when handling the results of a recursive collection algorithm,
* for instance.
**/
function flatten() {
return this.inject([], function(array, value) {
if (Object.isArray(value))
Expand All @@ -68,21 +111,48 @@ Array.from = $A;
});
}

/**
* Array#without(value...) -> Array
* - value (?): A value to exclude.
*
* Produces a new version of the array that does not contain any of the
* specified values.
**/
function without() {
var values = slice.call(arguments, 0);
return this.select(function(value) {
return !values.include(value);
});
}

/**
* Array#reverse([inline = false]) -> Array
* - inline (Boolean): Whether to modify the array in place. If `false`,
* clones the original array first.
*
* Returns the reversed version of the array.
**/
function reverse(inline) {
return (inline !== false ? this : this.toArray())._reverse();
}

/**
* Array#reduce() -> Array
* Reduces arrays: one-element arrays are turned into their unique item,
* while multiple-element arrays are returned untouched.
**/
function reduce() {
return this.length > 1 ? this : this[0];
}

/**
* Array#uniq([sorted = false]) -> Array
* - sorted (Boolean): Whether the array has already been sorted. If `true`,
* a less-costly algorithm will be used.
*
* Produces a duplicate-free version of an array. If no duplicates are
* found, the original array is returned.
**/
function uniq(sorted) {
return this.inject([], function(array, value, index) {
if (0 == index || (sorted ? array.last() != value : !array.include(value)))
Expand All @@ -91,24 +161,53 @@ Array.from = $A;
});
}

/**
* Array#intersect(array) -> Array
* - array (Array): A collection of values.
*
* Returns an array containing every item that is shared between the two
* given arrays.
**/
function intersect(array) {
return this.uniq().findAll(function(item) {
return array.detect(function(value) { return item === value });
});
}

/** alias of: Array#toArray
* Array#clone() -> Array
*
* Returns a duplicate of the array, leaving the original array intact.
**/
function clone() {
return slice.call(this, 0);
}

/** related to: Enumerable#size
* Array#size() -> Number
* Returns the size of the array.
*
* This is just a local optimization of the mixed-in [[Enumerable#size]]
* which avoids array cloning and uses the array’s native length property.
**/
function size() {
return this.length;
}

/** related to: Object.inspect
* Array#inspect() -> String
*
* Returns the debug-oriented string representation of an array.
**/
function inspect() {
return '[' + this.map(Object.inspect).join(', ') + ']';
}

/** related to: Object.toJSON
* Array#toJSON() -> String
*
* Returns a JSON string representation of the array.
**/
function toJSON() {
var results = [];
this.each(function(object) {
Expand All @@ -118,6 +217,15 @@ Array.from = $A;
return '[' + results.join(', ') + ']';
}

/**
* Array#indexOf(item[, offset = 0]) -> Number
* - item (?): A value that may or may not be in the array.
* - offset (Number): The number of initial items to skip before beginning the
* search.
*
* Returns the position of the first occurrence of `item` within the array — or
* `-1` if `item` doesn’t exist in the array.
**/
function indexOf(item, i) {
i || (i = 0);
var length = this.length;
Expand All @@ -127,12 +235,26 @@ Array.from = $A;
return -1;
}

/** related to: Array#indexOf
* Array#lastIndexOf(item[, offset]) -> Number
* - item (?): A value that may or may not be in the array.
* - offset (Number): The number of items at the end to skip before beginning
* the search.
*
* Returns the position of the last occurrence of `item` within the array — or
* `-1` if `item` doesn’t exist in the array.
**/
function lastIndexOf(item, i) {
i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
var n = this.slice(0, i).reverse().indexOf(item);
return (n < 0) ? n : i - n - 1;
}

/**
* Array#concat(args...) -> Array
*
* TODO: Array#concat
**/
function concat() {
var array = slice.call(this, 0), item;
for (var i = 0, length = arguments.length; i < length; i++) {
Expand Down
47 changes: 47 additions & 0 deletions src/lang/class.js
@@ -1,5 +1,35 @@
/* Based on Alex Arnell's inheritance implementation. */

/** section: lang
* Class
**/
var Class = (function() {
/**
* Class.create([superclass][, methods...]) -> Class
* - superclass (Class): The optional superclass to inherit methods from.
* - methods (Object): An object whose properties will be "mixed-in" to the
* new class. Any number of mixins can be added; later mixins take
* precedence.
*
* Creates a class.
*
* Class.create returns a function that, when called, will fire its own
* `initialize` method.
*
* `Class.create` accepts two kinds of arguments. If the first argument is
* a `Class`, it's treated as the new class's superclass, and all its
* methods are inherited. Otherwise, any arguments passed are treated as
* objects, and their methods are copied over as instance methods of the new
* class. Later arguments take precedence over earlier arguments.
*
* If a subclass overrides an instance method declared in a superclass, the
* subclass's method can still access the original method. To do so, declare
* the subclass's method as normal, but insert `$super` as the first
* argument. This makes `$super` available as a method for use within the
* function.
*
* To extend a class after it has been defined, use [[Class#addMethods]].
**/
function create() {
var parent = null, properties = $A(arguments);
if (Object.isFunction(properties[0]))
Expand Down Expand Up @@ -30,6 +60,23 @@ var Class = (function() {
return klass;
}

/**
* Class#addMethods(methods) -> Class
* - methods (Object): The methods to add to the class.
*
* Adds methods to an existing class.
*
* `Class#addMethods` is a method available on classes that have been
* defined with `Class.create`. It can be used to add new instance methods
* to that class, or overwrite existing methods, after the class has been
* defined.
*
* New methods propagate down the inheritance chain. If the class has
* subclasses, those subclasses will receive the new methods — even in the
* context of `$super` calls. The new methods also propagate to instances of
* the class and of all its subclasses, even those that have already been
* instantiated.
**/
function addMethods(source) {
var ancestor = this.superclass && this.superclass.prototype;
var properties = Object.keys(source);
Expand Down

0 comments on commit b2597ec

Please sign in to comment.