__all__ = ('ResolutionError', 'Module', 'JSResolver',)
-import sys, re
+import sys, re, json
from itertools import chain, repeat
from collections import defaultdict
from subprocess import Popen, check_output, STDOUT, PIPE
import pystache
+AT_REQUIRE_PAT = re.compile(r'//@require\(\s*([\'"])(.*?)\1\s*\)')
LINE_COMMENT_PAT = re.compile(r'(.*?)(//.*?)(?:\n|$)')
PAIR_COMMENT_PAT = re.compile(r'(.*?)(/\*.*?\*/)')
REQUIRE_PAT = re.compile(r'\brequire\(\s*([\'"])(.*?)\1\s*\)')
+
ROOT = path(__file__).abspath().dirname().dirname()
LIB = ROOT/'lib/cjs'
CWD = path('.')
BLANK = path('')
+
MODULE_TEMPLATE = ''
+DUMMY_TEMPLATE = ''
+DEPS_TEMPLATE = ''
try:
- with (LIB/'module.js').open('rU') as f :
+ with (LIB/'module.js').open('rU') as f:
MODULE_TEMPLATE = f.read()
+ with (LIB/'dummy.js').open('rU') as f:
+ DUMMY_TEMPLATE = f.read()
+ with (LIB/'deps.js').open('rU') as f:
+ DEPS_TEMPLATE = f.read()
except Exception as ex:
print
- print 'Error reading module template file!'
+ print 'Error reading template file!'
print ' ROOT={ROOT}, LIB={LIB}, module.js={}'.format(LIB/'module.js', **locals())
raise
return str(id)
-class Repo(object):
- def __init__(self, filepath, url):
- self.path = filepath
- self.url = url
-
- def __repr__(self):
- return 'Repo({}, url={})'.format(self.path, self.url)
-
- def __str__(self):
- return repr(self)
-
-
class Module(Bunch):
DEFAULTS = {
- 'id' : '', # Canonical Module ID
- 'file' : None, # path
- 'name' : '', # Module Name
- 'uri' : '', # Module URI (TODO)
- 'text' : None, # Unmodified module text
- 'contents' : None, # Compiled module text
- '_requires' : None,
- 'outpath' : None,
+ 'id' : '', # Canonical Module ID
+ 'file' : None, # path
+ 'name' : '', # Module Name
+ 'uri' : '', # Module URI (TODO)
+ 'text' : None, # Unmodified module text
+ 'contents' : None, # Compiled module text
+ 'outpath' : None, # Build directory
+ '_requires' : None,
+ '_at_requires' : None,
}
- def __init__(self, id, file, uri='', out=None, compile=True):
+ def __init__(self, id, file, uri=BLANK, out=None, compile=True):
self.update(Module.DEFAULTS)
self.id = id
self.file = path(file)
- self.name = self.id.split('/').pop().capitalize()
+ self.name = re.subn(r'\W', '', self.id.split('/').pop().capitalize())[0]
if out:
- out = (path(out) / self.id) + '.js'
+ out = path(out)
+ outpath = (out / self.id) + '.js'
else:
- out = self.file.replace('.cjs', '.js')
- self.outpath = path(out)
- self.uri = uri
+ out = BLANK
+ outpath = self.file.replace('.cjs', '.js')
+ self.outpath = path(outpath)
+ self.uri = str(out/uri/self.id)+'.js'
- if compile: self.compile()
+ self.compile()
# print "new!", repr(self)
def compile(self):
- # if uri: self.uri = uri.format(**self) # TODO: calc uri
-
- if not self.file.endswith('.cjs'):
- return self
-
outdir = self.outpath.dirname()
if not outdir.exists():
outdir.makedirs()
with self.file.open('rU') as f:
txt = f.read()
self['text'] = txt
- self['contents'] = pystache.render(MODULE_TEMPLATE, self)
+ template = MODULE_TEMPLATE if self.file.endswith('.cjs') else DUMMY_TEMPLATE
+ self['contents'] = pystache.render(template, self)
return self[attr]
@property
def contents(self):
return self.read('contents')
+ def findDirectives(self, text):
+ for areq in AT_REQUIRE_PAT.finditer(text):
+ yield canonicalise(areq.group(2), self)
+
def findRequires(self, text):
text = LINE_COMMENT_PAT.subn(r'\1 ', text)[0]
text = PAIR_COMMENT_PAT.subn(r'\1 ', text)[0]
for mreq in REQUIRE_PAT.finditer(text):
yield canonicalise(mreq.group(2), self)
+ def calcRequires(self, attr):
+ if self._requires is None or self._at_requires is None:
+ self._at_requires = list(self.findDirectives(self.text))
+ self._requires = list(self.findRequires(self.text))
+ return getattr(self, attr)
+
+ @property
+ def atRequires(self):
+ return self.calcRequires('_at_requires')
+
+ @property
+ def nonAtRequires(self):
+ return self.calcRequires('_requires')
+
@property
def requires(self):
- if self._requires is None:
- self._requires = list(self.findRequires(self.text))
- return self._requires
+ return self.calcRequires('_at_requires') + self._requires
def __hash__(self):
return hash(self.id)
req = cjs.lookup(query, mod)
if req not in seen:
queue.append(req)
+ if cjs.deps_name:
+ cjs.genDepLoader()
return cjs
repos = []
modules = {} # id -> Module
- _graph = None # id -> set(dependants)
-
-
- def __init__(self, repos, out='build', clean=True):
- self.modules = {}
- self.repos = set( path(path(p).abspath()+'/') for p in repos)
- self.out = None if out is '' else out
+ _graph = None # id -> set(dependants)
+ _at_graph = None # id -> set(dependants)
+
+ def __init__(self, repos, out='build', deps_name=None, clean=True, **options):
+ self.modules = {}
+ self.options = options
+ self.deps_name = deps_name
+ self.repos = set( path(path(p).abspath()+'/') for p in repos)
+ self.out = None if out is '' else out
if self.out is not None and clean:
out = path(self.out)
- if out.exists(): out.rmtree()
+ for f in out.glob('*'):
+ if f.isdir():
+ f.rmtree()
+ elif f.isfile():
+ f.remove()
def register(self, id, file):
mod = self.modules[id] = Module(id=id, file=file, out=self.out)
for k, mod in self.modules.iteritems():
yield k, mod
- @property
- def graph(self):
+ def calcGraph(self, attr):
if self._graph is None:
- graph = self._graph = defaultdict(set)
+ graph = self._graph = defaultdict(set)
+ atgraph = self._at_graph = defaultdict(set)
for mod in self.modules.values():
- for req in mod.requires:
+ for req in mod.nonAtRequires:
graph[req].add(mod)
- return self._graph
+ for req in mod.atRequires:
+ atgraph[req].add(mod)
+ return getattr(self, attr)
@property
- def deplist(self):
- return '\n'.join( '%s %s' % (id, dep.id) for (id, deps) in self.graph.iteritems() for dep in deps )
+ def graph(self):
+ return self.calcGraph('_graph')
@property
- def dependencies(self):
+ def atGraph(self):
+ return self.calcGraph('_at_graph')
+
+ def tsort(self, graph):
p = Popen(['tsort'], stderr=STDOUT, stdin=PIPE, stdout=PIPE)
- p.stdin.write( self.deplist )
+ deps = '\n'.join( '%s %s' % (id, dep.id) for (id, deps) in graph.iteritems() for dep in deps )
+ p.stdin.write(deps)
p.stdin.close()
if p.wait() != 0:
raise ResolutionError('Cannot resolve dependencies! Requirements must be acyclic!')
- return p.stdout.read().strip().split('\n')
+ return p.stdout.read()
+
+ @property
+ def dependencies(self):
+ deps = (self.tsort(self.atGraph)+self.tsort(self.graph)).strip().split('\n')
+ for i, dep in reversed(list(enumerate(deps[:]))):
+ try:
+ idx = deps.index(dep, 0, i-1)
+ if i != idx:
+ del deps[idx]
+ except ValueError: pass
+ return deps
+
+ def dumpDependencies(self):
+ column = Popen(['column', '-s', '\t', '-t'], stderr=sys.stderr, stdin=PIPE, stdout=PIPE)
+ mods = self.modules.values()
+ for mod in sorted(mods, key=lambda m: len(m.requires), reverse=True):
+ column.stdin.write('%s\t->\t%r\n' % (mod, sorted(mod.requires)))
+ # print '%s\t->\t%r' % (mod, sorted(mod.requires))
+ column.stdin.close()
+ if column.wait() != 0:
+ print >> sys.stderr, 'Some sort of error has occurred!'
+ return column.stdout.read()
- def cat(self):
- for dep in self.dependencies:
- print self.modules[dep].contents
+ def genDepLoader(self):
+ with (path(self.out)/self.deps_name).open('w') as deps:
+ deps.write( pystache.render(DEPS_TEMPLATE, uris=json.dumps(self.uris)) )
+ @property
+ def uris(self):
+ return [ self.modules[d].uri for d in self.dependencies ]
+
+ @property
+ def scriptTags(self):
+ return '\n'.join( '<script src="{}" type="text/javascript"></script>'.format(uri) for uri in self.uris )
usage = 'usage: %prog [options] file[...] [-- [repo_path[...]]]',
description = 'Compiles CommonJS modules.',
version = '%prog'+" %i.%i.%i" % __version__)
- parser.add_option("-p", "--repo-paths", dest='repos', default='',
+ parser.add_option("-p", "--repo-paths", default='',
help="Comma-seperated paths to search for unqualified modules. "
"If a path contains :, the portion afterward will be taken as the repo URL. [default: .]")
parser.add_option("-o", "--out", default='build',
help="Root directory to write compiled JS files. Specify '' to write to module's dir. [default: build]")
parser.add_option("-C", "--no-clean", dest='clean', default=True, action="store_false",
help="Do not clean the out-dir of compiled files. [default: False if -o, True otherwise]")
- parser.add_option("-d", "--print-deps", default=False, action="store_true",
+ parser.add_option("--print-deps", default=False, action="store_true",
help="Prints module dependencies after compiling. [default: %default]")
+ parser.add_option("-g", "--gen-deps-script", dest='deps_name', default=None,
+ help="Generates a JS script with the given name which doc-writes tags for this set of modules.")
+ parser.add_option("-s", "--script-tags", default=False, action="store_true",
+ help="Emits script-tags for this set of modules in dependency order. [default: %default]")
(options, args) = parser.parse_args()
(files, sep, repos) = partition(sys.argv, '--')
files = filter(lambda f: f in args, files)
repos = filter(lambda f: f in args, repos)
- repos.extend( filter(None, options.repos.split(',')) )
+ repos.extend( filter(None, options.repo_paths.split(',')) )
# print 'files:', files, 'repos:', (repos or ['.'])
- js = CommonJS.discover(files=files, repos=repos or ['.'], **options.__dict__)
+ try:
+ js = CommonJS.discover(files=files, repos=repos or ['.'], **options.__dict__)
+ except ResolutionError as ex:
+ print >> sys.stderr, str(ex)
+ return 1
+
+ if options.script_tags:
+ print js.scriptTags
if options.print_deps:
- column = Popen(['column', '-s', '\t', '-t'], stderr=sys.stderr, stdin=PIPE, stdout=PIPE)
- mods = js.modules.values()
- for mod in sorted(mods, key=lambda m: len(m.requires), reverse=True):
- column.stdin.write('%s\t->\t%r\n' % (mod, sorted(mod.requires)))
- # print '%s\t->\t%r' % (mod, sorted(mod.requires))
-
- column.stdin.close()
- if column.wait() != 0: print 'Some sort of error has occurred!'
- print column.stdout.read()
+ print >> sys.stderr, 'All Dependencies:'
+ print >> sys.stderr, js.dumpDependencies()
+ print >> sys.stderr, ''
+ print >> sys.stderr, 'Resolution:'
+ print >> sys.stderr, '\n'.join(js.dependencies)
return 0
- Tanks seem to get stuck on some corners
# TODOs
-- How-to overlay
-- Restart level button
-- AI: Line-of-sight for dodging, firing
+- change @require to @ensure
+
- AI: Don't shoot if it'll kill you or your friends
- AI: Lead shots on moving targets
- Config-driven unit-types (name, stats, properties; pointers to behavior scripts, assets)
</div></div>
<div id="scripts">
-<?php require "tanks.php"; Tanks::writeTags( Tanks::ALL_SCRIPTS ); ?>
+<?php
+ /* require "tanks.php"; Tanks::writeTags( Tanks::ALL_SCRIPTS ); */
+ require "tanks.php"; Tanks::writeLoaders();
+?>
</div>
</body>
--- /dev/null
+{{{uris}}}.forEach(function(uri){
+ document.write('<scr'+'ipt src="'+uri+'" type="text/javascript"></scr'+'ipt>');
+});
--- /dev/null
+require.install(
+// Module ID
+'{{{id}}}',
+
+// Module metadata
+{
+ 'name' : '{{{name}}}',
+ 'id' : '{{{id}}}',
+ 'uri' : '{{{uri}}}'
+},
+// Dummy module: setup does nothing
+function setup{{{name}}}(require, exports, module){});
+
+{{{text}}}
require.install(
// Module ID
-'{{id}}',
+'{{{id}}}',
// Module metadata
{
- 'name' : '{{name}}',
- 'id' : '{{id}}',
- 'uri' : '{{uri}}'
+ 'name' : '{{{name}}}',
+ 'id' : '{{{id}}}',
+ 'uri' : '{{{uri}}}'
},
// Module Setup function
-function setup{{name}}(require, exports, module){
+function setup{{{name}}}(require, exports, module){
-{{text}}
+{{{text}}}
});
\ No newline at end of file
--- /dev/null
+jquery-1.4.3.min.js
\ No newline at end of file
// Inspired by John Resig's "Simple Class Inheritence" -- http://ejohn.org/blog/simple-javascript-inheritance/
-var Y = require('Y').Y
-, type = require('Y/type')
+var type = require('Y/type')
+, YFunction = require('Y/types/function').YFunction
+, core = require('Y/core')
+, slice = core.slice
+
, KNOWN_CLASSES = type.type.KNOWN_CLASSES
, classToString = function toString(){ return this.className+"()"; }
;
prototype[k] = members[k];
}
- if (prototype.init) NewClass.init = Y(prototype.init);
+ if (prototype.init) NewClass.init = YFunction(prototype.init);
KNOWN_CLASSES[className] = NewClass;
-
-/// Other Class Utilities ///
-
-function bindName(v, k){
- if ( isFunction(v) )
- this[k] = Y(v).bind(this);
-}
-// bindName = Y(bindName).curry();
-
-function bindAll(o, names){
- var names = new Y(arguments, 1);
- Y(names.size() ? names.generate(Y.op.get(o)) : o).forEach( bindName, o );
- return o;
-}
-
-// Y.chainDelegates = chainDelegates;
-function chainDelegates(type, name){
- var names = Y(arguments, 1),
- proto = type.prototype;
- names.forEach(function(name){
- proto[name] = function(){
- var o = this._o || this;
- o[name].apply(o, Y(arguments));
- return this;
- };
- });
- return type;
-}
-
-// Y.mixinNames = mixinNames;
-function mixinNames(o, Donor, names, override, yWrap){
- var target = ( isFunction(o) ? o.prototype : o)
- , proto = ( isFunction(Donor) ? Donor.prototype : Donor);
-
- // Need a closure to capture the name
- names.forEach(function(name){
- if ( isFunction(proto[name]) && (override || !target[name]) )
- target[name] = function(){
- var r = proto[name].apply(this._o || target, arguments);
- return (yWrap ? Y(r) : r);
- };
- });
-
- return o;
-}
-
exports['Class'] =
exports['subclass'] = Class;
exports['instantiate'] = Class.instantiate.bind(Class);
exports['fabricate'] = Class.fabricate.bind(Class);
-
-exports['YBase'] = YBase;
-exports['bindAll'] = bindAll;
-exports['chainDelegates'] = chainDelegates;
-exports['mixinNames'] = mixinNames;
+exports['YBase'] = YBase;
// Generic Collection Functions
+var undefined
+, globals = (function(){ return this; })()
+, _Function = globals.Function
+, _Array = globals.Array
+, PT = "prototype"
+, slice = _Array[PT].slice
+;
+
+// function slice(a){
+// return _asl.apply(a, _asl.call(arguments, 1));
+// }
function notWrapped(fn){
var self = arguments.callee.caller;
if ( !o )
return acc;
- fn = Function.toFunction(fn);
+ fn = _Function.toFunction(fn);
var cxt = arguments[3] || o;
if ( notWrapped(o.reduce) )
return o.reduce.apply(o, [fn, acc, cxt]);
if ( !o )
return o;
- fn = Function.toFunction(fn);
+ fn = _Function.toFunction(fn);
var acc = {}, cxt = arguments[2] || o;
if ( notWrapped(o.map) )
return o.map.apply(o, [fn, cxt]);
if ( !o )
return o;
- fn = Function.toFunction(fn);
+ fn = _Function.toFunction(fn);
var acc = {}, cxt = arguments[2] || o;
if ( notWrapped(o.filter) )
return o.filter.apply(o, [fn, cxt]);
exports['dset'] = dset;
exports['dattr'] = dattr;
exports['dextend'] = dextend;
+exports['slice'] = slice;
\ No newline at end of file
+// -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
/// Import our external deps first ///
-// require('lessly/future');
-// require('functional/to-function');
+//@require('lessly/future');
+//@require('functional/to-function');
/// Set up core and utilities ///
var core = require('Y/core')
// Attach core & type to Y
core.extend(Y, core, type);
+delete Y.slice; // grr
// Make top-level setters refer to the delegating versions
Y['core'] = core;
// Curry all operators
var op = require('Y/op');
core.forEach(op, YFunction);
-Y['op'] = op.extend({}, core.map(yfn.curry, op));
+Y['op'] = op['curried'] = op.extend({}, core.map(yfn.curry, op));
// Y['op'] = core.reduce(op, function(Yop, fn, k){
// Yop[k] = yfn.curry(fn);
// return Yop;
-(function(Y, undefined){ if (!Y) return;
-
var _document = document
+, Y = require('Y').Y
, enc = encodeURIComponent
, dec = decodeURIComponent
-, ns = Y.cookies = {}
;
-ns.get =
+Y['cookies'] = exports;
+
+exports['get'] =
function getCookie(k){
var cookies = Y(_document.cookie+'').fromKV('; ');
if (k !== undefined)
return cookies;
};
-ns.set =
+exports['set'] =
function setCookie(k, v, expires, path){
expires = 'expires='+(expires || "Sun, 24-Mar-2024 11:11:11 GMT");
path = 'path='+(path || "/");
};
// TODO: YCollection methods on ns over kv pairs.
-
-})(this.Y);
-(function(Y, undefined){
-
-var
-ns = Y.event = {}
+Y['event'] = exports;
/**
* A simple event.
* TODO: If DOM event, wrap with consistent API.
* TODO: use jQuery if present to wrap events.
*/
-, YEvent = ns.YEvent =
+var YEvent = exports['YEvent'] =
Y.YObject.subclass('YEvent', {
init : function init( type, target, trigger, data ){
data = data || {};
delegate[k] = methods[k].bind(this);
return delegate;
}
-}
+},
-, Emitter = ns.Emitter =
+Emitter = exports['Emitter'] =
Y.YObject.subclass('Emitter',
Y.extend({
'init' : function(target, parent){
// Global Event Hub
Emitter.global = new Emitter()
-Emitter.global.decorate(Y.event);
-
-
-})(this.Y);
+Emitter.global.decorate(exports);
-(function(Y){
+var Y = require('Y').Y;
function toJSON(o, k){
var prefix = typeof(k) === 'string' ? '"'+k+'":' : '',
}
function install(json_fn){
- var args = new Y(arguments),
- tojson = args.shift();
- args.each(function(YThing){
+ var args = Y(arguments,1);
+ args.forEach(function(YThing){
YThing.prototype.toJSON = json_fn;
});
}
// Collections
function reducer(acc, v, k, o){
- var json = toJSON(v, Y.is.array(o) ? 0 : k);
+ var json = toJSON(v, Y.isArray(o) ? 0 : k);
return json ? (acc ? acc+','+json : json) : acc;
}
// Public API
-Y.toJSON = toJSON;
+Y['toJSON'] = exports['toJSON'] = toJSON;
-install( yNoJSON, Y.YGeneric, Y.YFunction, Y.YRegExp );
-install( yToJSON, Y, Y.YBoolean, Y.YNumber );
+// install( yNoJSON, Y.YBase, Y.YFunction, Y.YRegExp );
+// install( yToJSON, Y, Y.YBoolean, Y.YNumber );
+install( yNoJSON, Y.YBase, Y.YFunction );
+install( yToJSON, Y, Y.YNumber );
install( quoteJSON, Y.YString );
-install( collectJSON.partial('{', '}'), Y.YCollection );
+install( collectJSON.partial('{', '}'), Y.YCollection, Y.YObject );
install( collectJSON.partial('[', ']'), Y.YArray );
-
-
-})(this.Y);
-(function(Y, undefined){ if (!Y) return;
-
-var enc = encodeURIComponent
+var Y = require('Y').Y
+, enc = encodeURIComponent
, dec = decodeURIComponent
;
}, {});
};
-})(this.Y);
/* A subset of the functional operators, used in Y's core */
-var Y = require('Y').Y
-, core = require('Y/core')
+var core = require('Y/core')
+, slice = core.slice
, op = { // XXX: Make these function statements?
// comparison
nop: function(x){},
I: function(x){ return x; },
K: function(k){ return function(){ return k; }; },
+ nth: function(n){ return function(){ return arguments[n]; }; },
val: function(def,o){ return o !== undefined ? o : def; },
ok: function(o){ return o !== undefined && o !== null; },
set: core.set, // set( o, key, value, def )
attr: core.attr, // attr( o, key, value, def )
method: function(name){
- var args = Y(arguments,1);
+ var args = slice.call(arguments,1);
return function(obj){
if (obj && obj[name])
- return obj[name].apply( obj, args.concat(Y(arguments)) );
+ return obj[name].apply( obj, args.concat(slice.call(arguments)) );
else
return obj;
};
-var Y = require('Y').Y;
+var YCollection = require('Y/types/collection').YCollection
+, mixin = require('Y/utils').mixin
+, slice = require('Y/core').slice
+;
exports['YArray'] =
-Y.YCollection.subclass('YArray', function(YArray){
- var yclass = require('Y/class');
+YCollection.subclass('YArray', function(YArray){
- yclass.chainDelegates(YArray, 'push', 'unshift', 'sort', 'splice', 'reverse');
- yclass.mixinNames(YArray, Array, ['reduce', 'map', 'forEach', 'filter', 'slice', 'some', 'every'], true, true);
- yclass.mixinNames(YArray, Array, ['indexOf', 'lastIndexOf', 'shift', 'pop', 'join'], true, false);
+ mixin(YArray, { donor:Array, chain:true,
+ names:'push unshift sort splice reverse'.split(' ') });
+ mixin(YArray, { donor:Array, wrap:YArray,
+ names:'map forEach filter slice'.split(' ') });
+ mixin(YArray, { donor:Array,
+ names:'reduce some every indexOf lastIndexOf shift pop join'.split(' ') });
-
-
- this.init = function(o){
- // YCollection.init.call(this, o || []);
+ this.init = function initYArray(o){
this._o = o || [];
};
this.merge =
this.concat =
function concat( donor ){
- var A = this._o;
- new Y(arguments).forEach(function( donor ){
- A = A.concat(donor instanceof YArray ? donor.end() : donor);
- });
- return Y(A);
+ return new YArray( slice.call(arguments).reduce(function(A, donor ){
+ return A.concat(donor instanceof YArray ? donor.end() : donor);
+ }, this._o) );
};
this.remove =
function remove(v){
if (arguments.length > 1)
- Y(arguments).forEach(this.remove, this);
+ slice.call(arguments).forEach(this.remove, this);
else {
var idx = this.indexOf(v);
if ( idx != -1 )
// });
};
+ // this.zip =
+ // function zip(){
+ // var sequences = new YArray(slice.call(arguments)).map( Y.limit(1) ).unshift(this);
+ // return this.map(function(_, k){
+ // return sequences.invoke('attr', k);
+ // }).invoke('end');
+ // };
+
// Like map, but produces a dict
// Y(["Foo?", "R&D"]).generate(encodeURIComponent)
// -> Y({"Foo?":"Foo%3F", "R&D":"R%26D"})
this.generate =
function generate(fn, acc){
- var args = Y(arguments),
+ var args = slice.call(arguments),
fn = args.shift(),
acc = args.shift();
return this.reduce(function(acc, v, i){
this.clone =
function clone(){
- return Y(this._o.slice(0));
+ return new YArray(this._o.slice(0));
};
this.size =
/** YCollection is the core of Y. */
-var Y = require('Y').Y
+var YBase = require('Y/class').YBase
, isFunction = require('Y/type').isFunction
-, extend = require('Y/core').extend
-, bool = require('Y/op').bool
+, core = require('Y/core')
+, op = require('Y/op')
+, slice = core.slice
+, extend = core.extend
+, attr = core.attr
+, bool = op.bool
;
function extendY(){
- extend.apply(this, [this._o].concat(Y(arguments)));
+ extend.apply(this, [this._o].concat(slice.call(arguments)));
return this;
}
exports['YCollection'] =
-Y.YBase.subclass('YCollection', {
+YBase.subclass('YCollection', {
'init' : function(o){
this._o = o || {};
},
'attr' : function attr(k, v, def){
- var r = Y.attr(this._o, k, v, def);
+ var r = attr(this._o, k, v, def);
if (r === this._o)
return this;
else
},
'clone' : function clone(){
- return Y({}).extend(this);
+ return new this.constructor().extend(this);
},
+ // 'remove' : function remove(v){
+ // var o = this._o
+ // , toRemove = new Y(arguments);
+ //
+ // for (var k in o) {
+ // var v = o[k];
+ // if ( toRemove.has(v) ) {
+ // delete o[k];
+ // toRemove.remove(v);
+ // }
+ // }
+ // return this;
+ // },
+
'remove' : function remove(v){
var o = this._o
- , toRemove = new Y(arguments);
+ , toRemove = slice.call(arguments);
for (var k in o) {
- var v = o[k];
- if ( toRemove.has(v) ) {
+ var v = o[k], idx = toRemove.indexOf(v);
+ if ( idx !== -1 ) {
delete o[k];
- toRemove.remove(v);
+ toRemove.splice(idx,1);
}
+ if (!toRemove.length)
+ break;
}
return this;
},
},
'zip' : function zip(){
- var sequences = new Y(arguments).map( Y.limit(1) ).unshift(this);
+ var sequences = slice.call(arguments);
+ sequences.unshift(this);
return this.map(function(_, k){
- return sequences.invoke('attr', k);
- }).invoke('end');
+ return sequences.map(op.curried.kget(k));
+ });
},
'pluck' : function pluck(key){
},
'invoke' : function invoke(name){
- var args = Y(arguments),
- name = args.shift();
- return this.map(function(o){
+ var args = slice.call(arguments,1);
+ return core.map(this, function(o){
return o && o[name].apply(o, args);
});
},
, WRAPS = "__wraps__"
, globals = (function(){ r