seed.js 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701
  1. ;(function (undefined) {
  2. /**
  3. * Require the given path.
  4. *
  5. * @param {String} path
  6. * @return {Object} exports
  7. * @api public
  8. */
  9. function require(path, parent, orig) {
  10. var resolved = require.resolve(path);
  11. // lookup failed
  12. if (null == resolved) {
  13. orig = orig || path;
  14. parent = parent || 'root';
  15. var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
  16. err.path = orig;
  17. err.parent = parent;
  18. err.require = true;
  19. throw err;
  20. }
  21. var module = require.modules[resolved];
  22. // perform real require()
  23. // by invoking the module's
  24. // registered function
  25. if (!module.exports) {
  26. module.exports = {};
  27. module.client = module.component = true;
  28. module.call(this, module.exports, require.relative(resolved), module);
  29. }
  30. return module.exports;
  31. }
  32. /**
  33. * Registered modules.
  34. */
  35. require.modules = {};
  36. /**
  37. * Registered aliases.
  38. */
  39. require.aliases = {};
  40. /**
  41. * Resolve `path`.
  42. *
  43. * Lookup:
  44. *
  45. * - PATH/index.js
  46. * - PATH.js
  47. * - PATH
  48. *
  49. * @param {String} path
  50. * @return {String} path or null
  51. * @api private
  52. */
  53. require.resolve = function(path) {
  54. if (path.charAt(0) === '/') path = path.slice(1);
  55. var paths = [
  56. path,
  57. path + '.js',
  58. path + '.json',
  59. path + '/index.js',
  60. path + '/index.json'
  61. ];
  62. for (var i = 0; i < paths.length; i++) {
  63. var path = paths[i];
  64. if (require.modules.hasOwnProperty(path)) return path;
  65. if (require.aliases.hasOwnProperty(path)) return require.aliases[path];
  66. }
  67. };
  68. /**
  69. * Normalize `path` relative to the current path.
  70. *
  71. * @param {String} curr
  72. * @param {String} path
  73. * @return {String}
  74. * @api private
  75. */
  76. require.normalize = function(curr, path) {
  77. var segs = [];
  78. if ('.' != path.charAt(0)) return path;
  79. curr = curr.split('/');
  80. path = path.split('/');
  81. for (var i = 0; i < path.length; ++i) {
  82. if ('..' == path[i]) {
  83. curr.pop();
  84. } else if ('.' != path[i] && '' != path[i]) {
  85. segs.push(path[i]);
  86. }
  87. }
  88. return curr.concat(segs).join('/');
  89. };
  90. /**
  91. * Register module at `path` with callback `definition`.
  92. *
  93. * @param {String} path
  94. * @param {Function} definition
  95. * @api private
  96. */
  97. require.register = function(path, definition) {
  98. require.modules[path] = definition;
  99. };
  100. /**
  101. * Alias a module definition.
  102. *
  103. * @param {String} from
  104. * @param {String} to
  105. * @api private
  106. */
  107. require.alias = function(from, to) {
  108. if (!require.modules.hasOwnProperty(from)) {
  109. throw new Error('Failed to alias "' + from + '", it does not exist');
  110. }
  111. require.aliases[to] = from;
  112. };
  113. /**
  114. * Return a require function relative to the `parent` path.
  115. *
  116. * @param {String} parent
  117. * @return {Function}
  118. * @api private
  119. */
  120. require.relative = function(parent) {
  121. var p = require.normalize(parent, '..');
  122. /**
  123. * lastIndexOf helper.
  124. */
  125. function lastIndexOf(arr, obj) {
  126. var i = arr.length;
  127. while (i--) {
  128. if (arr[i] === obj) return i;
  129. }
  130. return -1;
  131. }
  132. /**
  133. * The relative require() itself.
  134. */
  135. function localRequire(path) {
  136. var resolved = localRequire.resolve(path);
  137. return require(resolved, parent, path);
  138. }
  139. /**
  140. * Resolve relative to the parent.
  141. */
  142. localRequire.resolve = function(path) {
  143. var c = path.charAt(0);
  144. if ('/' == c) return path.slice(1);
  145. if ('.' == c) return require.normalize(p, path);
  146. // resolve deps by returning
  147. // the dep in the nearest "deps"
  148. // directory
  149. var segs = parent.split('/');
  150. var i = lastIndexOf(segs, 'deps') + 1;
  151. if (!i) i = 0;
  152. path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
  153. return path;
  154. };
  155. /**
  156. * Check if module is defined at `path`.
  157. */
  158. localRequire.exists = function(path) {
  159. return require.modules.hasOwnProperty(localRequire.resolve(path));
  160. };
  161. return localRequire;
  162. };
  163. require.register("component-indexof/index.js", function(exports, require, module){
  164. module.exports = function(arr, obj){
  165. if (arr.indexOf) return arr.indexOf(obj);
  166. for (var i = 0; i < arr.length; ++i) {
  167. if (arr[i] === obj) return i;
  168. }
  169. return -1;
  170. };
  171. });
  172. require.register("component-emitter/index.js", function(exports, require, module){
  173. /**
  174. * Module dependencies.
  175. */
  176. var index = require('indexof');
  177. /**
  178. * Expose `Emitter`.
  179. */
  180. module.exports = Emitter;
  181. /**
  182. * Initialize a new `Emitter`.
  183. *
  184. * @api public
  185. */
  186. function Emitter(obj) {
  187. if (obj) return mixin(obj);
  188. };
  189. /**
  190. * Mixin the emitter properties.
  191. *
  192. * @param {Object} obj
  193. * @return {Object}
  194. * @api private
  195. */
  196. function mixin(obj) {
  197. for (var key in Emitter.prototype) {
  198. obj[key] = Emitter.prototype[key];
  199. }
  200. return obj;
  201. }
  202. /**
  203. * Listen on the given `event` with `fn`.
  204. *
  205. * @param {String} event
  206. * @param {Function} fn
  207. * @return {Emitter}
  208. * @api public
  209. */
  210. Emitter.prototype.on = function(event, fn){
  211. this._callbacks = this._callbacks || {};
  212. (this._callbacks[event] = this._callbacks[event] || [])
  213. .push(fn);
  214. return this;
  215. };
  216. /**
  217. * Adds an `event` listener that will be invoked a single
  218. * time then automatically removed.
  219. *
  220. * @param {String} event
  221. * @param {Function} fn
  222. * @return {Emitter}
  223. * @api public
  224. */
  225. Emitter.prototype.once = function(event, fn){
  226. var self = this;
  227. this._callbacks = this._callbacks || {};
  228. function on() {
  229. self.off(event, on);
  230. fn.apply(this, arguments);
  231. }
  232. fn._off = on;
  233. this.on(event, on);
  234. return this;
  235. };
  236. /**
  237. * Remove the given callback for `event` or all
  238. * registered callbacks.
  239. *
  240. * @param {String} event
  241. * @param {Function} fn
  242. * @return {Emitter}
  243. * @api public
  244. */
  245. Emitter.prototype.off =
  246. Emitter.prototype.removeListener =
  247. Emitter.prototype.removeAllListeners = function(event, fn){
  248. this._callbacks = this._callbacks || {};
  249. // all
  250. if (0 == arguments.length) {
  251. this._callbacks = {};
  252. return this;
  253. }
  254. // specific event
  255. var callbacks = this._callbacks[event];
  256. if (!callbacks) return this;
  257. // remove all handlers
  258. if (1 == arguments.length) {
  259. delete this._callbacks[event];
  260. return this;
  261. }
  262. // remove specific handler
  263. var i = index(callbacks, fn._off || fn);
  264. if (~i) callbacks.splice(i, 1);
  265. return this;
  266. };
  267. /**
  268. * Emit `event` with the given args.
  269. *
  270. * @param {String} event
  271. * @param {Mixed} ...
  272. * @return {Emitter}
  273. */
  274. Emitter.prototype.emit = function(event){
  275. this._callbacks = this._callbacks || {};
  276. var args = [].slice.call(arguments, 1)
  277. , callbacks = this._callbacks[event];
  278. if (callbacks) {
  279. callbacks = callbacks.slice(0);
  280. for (var i = 0, len = callbacks.length; i < len; ++i) {
  281. callbacks[i].apply(this, args);
  282. }
  283. }
  284. return this;
  285. };
  286. /**
  287. * Return array of callbacks for `event`.
  288. *
  289. * @param {String} event
  290. * @return {Array}
  291. * @api public
  292. */
  293. Emitter.prototype.listeners = function(event){
  294. this._callbacks = this._callbacks || {};
  295. return this._callbacks[event] || [];
  296. };
  297. /**
  298. * Check if this emitter has `event` handlers.
  299. *
  300. * @param {String} event
  301. * @return {Boolean}
  302. * @api public
  303. */
  304. Emitter.prototype.hasListeners = function(event){
  305. return !! this.listeners(event).length;
  306. };
  307. });
  308. require.register("seed/src/main.js", function(exports, require, module){
  309. var config = require('./config'),
  310. Seed = require('./seed'),
  311. directives = require('./directives'),
  312. filters = require('./filters'),
  313. textParser = require('./text-parser')
  314. var controllers = config.controllers,
  315. datum = config.datum,
  316. api = {},
  317. reserved = ['datum', 'controllers'],
  318. booted = false
  319. /*
  320. * Store a piece of plain data in config.datum
  321. * so it can be consumed by sd-data
  322. */
  323. api.data = function (id, data) {
  324. if (!data) return datum[id]
  325. datum[id] = data
  326. }
  327. /*
  328. * Store a controller function in config.controllers
  329. * so it can be consumed by sd-controller
  330. */
  331. api.controller = function (id, extensions) {
  332. if (!extensions) return controllers[id]
  333. controllers[id] = extensions
  334. }
  335. /*
  336. * Allows user to create a custom directive
  337. */
  338. api.directive = function (name, fn) {
  339. if (!fn) return directives[name]
  340. directives[name] = fn
  341. }
  342. /*
  343. * Allows user to create a custom filter
  344. */
  345. api.filter = function (name, fn) {
  346. if (!fn) return filters[name]
  347. filters[name] = fn
  348. }
  349. /*
  350. * Bootstrap the whole thing
  351. * by creating a Seed instance for top level nodes
  352. * that has either sd-controller or sd-data
  353. */
  354. api.bootstrap = function (opts) {
  355. if (booted) return
  356. if (opts) {
  357. for (var key in opts) {
  358. if (reserved.indexOf(key) === -1) {
  359. config[key] = opts[key]
  360. }
  361. }
  362. }
  363. textParser.buildRegex()
  364. var el,
  365. ctrlSlt = '[' + config.prefix + '-controller]',
  366. dataSlt = '[' + config.prefix + '-data]',
  367. seeds = []
  368. /* jshint boss: true */
  369. while (el = document.querySelector(ctrlSlt) || document.querySelector(dataSlt)) {
  370. seeds.push((new Seed(el)).scope)
  371. }
  372. booted = true
  373. return seeds.length > 1 ? seeds : seeds[0]
  374. }
  375. module.exports = api
  376. });
  377. require.register("seed/src/config.js", function(exports, require, module){
  378. module.exports = {
  379. prefix : 'sd',
  380. debug : false,
  381. datum : {},
  382. controllers : {},
  383. interpolateTags : {
  384. open : '{{',
  385. close : '}}'
  386. }
  387. }
  388. });
  389. require.register("seed/src/utils.js", function(exports, require, module){
  390. var Emitter = require('emitter'),
  391. toString = Object.prototype.toString,
  392. aproto = Array.prototype,
  393. arrayMutators = ['push','pop','shift','unshift','splice','sort','reverse']
  394. var arrayAugmentations = {
  395. remove: function (index) {
  396. if (typeof index !== 'number') index = index.$index
  397. this.splice(index, 1)
  398. },
  399. replace: function (index, data) {
  400. if (typeof index !== 'number') index = index.$index
  401. this.splice(index, 1, data)
  402. }
  403. }
  404. /*
  405. * get accurate type of an object
  406. */
  407. function typeOf (obj) {
  408. return toString.call(obj).slice(8, -1)
  409. }
  410. /*
  411. * Recursively dump stuff...
  412. */
  413. function dumpValue (val) {
  414. var type = typeOf(val)
  415. if (type === 'Array') {
  416. return val.map(dumpValue)
  417. } else if (type === 'Object') {
  418. if (val.get) { // computed property
  419. return val.get()
  420. } else { // object / child scope
  421. var ret = {}
  422. for (var key in val) {
  423. if (val.hasOwnProperty(key) &&
  424. typeof val[key] !== 'function' &&
  425. key.charAt(0) !== '$')
  426. {
  427. ret[key] = dumpValue(val[key])
  428. }
  429. }
  430. return ret
  431. }
  432. } else if (type !== 'Function') {
  433. return val
  434. }
  435. }
  436. module.exports = {
  437. typeOf: typeOf,
  438. dumpValue: dumpValue,
  439. /*
  440. * Get a value from an object based on a path array
  441. */
  442. getNestedValue: function (obj, path) {
  443. if (path.length === 1) return obj[path[0]]
  444. var i = 0
  445. /* jshint boss: true */
  446. while (obj[path[i]]) {
  447. obj = obj[path[i]]
  448. i++
  449. }
  450. return i === path.length ? obj : undefined
  451. },
  452. /*
  453. * augment an Array so that it emit events when mutated
  454. */
  455. watchArray: function (collection) {
  456. Emitter(collection)
  457. arrayMutators.forEach(function (method) {
  458. collection[method] = function () {
  459. var result = aproto[method].apply(this, arguments)
  460. collection.emit('mutate', {
  461. method: method,
  462. args: aproto.slice.call(arguments),
  463. result: result
  464. })
  465. }
  466. })
  467. for (var method in arrayAugmentations) {
  468. collection[method] = arrayAugmentations[method]
  469. }
  470. }
  471. }
  472. });
  473. require.register("seed/src/seed.js", function(exports, require, module){
  474. var config = require('./config'),
  475. Scope = require('./scope'),
  476. Binding = require('./binding'),
  477. DirectiveParser = require('./directive-parser'),
  478. TextParser = require('./text-parser'),
  479. depsParser = require('./deps-parser')
  480. var slice = Array.prototype.slice,
  481. ctrlAttr = config.prefix + '-controller',
  482. eachAttr = config.prefix + '-each'
  483. /*
  484. * The main ViewModel class
  485. * scans a node and parse it to populate data bindings
  486. */
  487. function Seed (el, options) {
  488. if (typeof el === 'string') {
  489. el = document.querySelector(el)
  490. }
  491. this.el = el
  492. el.seed = this
  493. this._bindings = {}
  494. this._computed = []
  495. // copy options
  496. options = options || {}
  497. for (var op in options) {
  498. this[op] = options[op]
  499. }
  500. // check if there's passed in data
  501. var dataAttr = config.prefix + '-data',
  502. dataId = el.getAttribute(dataAttr),
  503. data = (options && options.data) || config.datum[dataId]
  504. if (config.debug && dataId && !data) {
  505. console.warn('data "' + dataId + '" is not defined.')
  506. }
  507. data = data || {}
  508. el.removeAttribute(dataAttr)
  509. // if the passed in data is the scope of a Seed instance,
  510. // make a copy from it
  511. if (data.$seed instanceof Seed) {
  512. data = data.$dump()
  513. }
  514. // initialize the scope object
  515. var scope = this.scope = new Scope(this, options)
  516. // copy data
  517. for (var key in data) {
  518. scope[key] = data[key]
  519. }
  520. // if has controller function, apply it so we have all the user definitions
  521. var ctrlID = el.getAttribute(ctrlAttr)
  522. if (ctrlID) {
  523. el.removeAttribute(ctrlAttr)
  524. var factory = config.controllers[ctrlID]
  525. if (factory) {
  526. factory(this.scope)
  527. } else if (config.debug) {
  528. console.warn('controller "' + ctrlID + '" is not defined.')
  529. }
  530. }
  531. // now parse the DOM
  532. this._compileNode(el, true)
  533. // extract dependencies for computed properties
  534. depsParser.parse(this._computed)
  535. delete this._computed
  536. }
  537. // for better compression
  538. var SeedProto = Seed.prototype
  539. /*
  540. * Compile a DOM node (recursive)
  541. */
  542. SeedProto._compileNode = function (node, root) {
  543. var seed = this
  544. if (node.nodeType === 3) { // text node
  545. seed._compileTextNode(node)
  546. } else if (node.nodeType === 1) {
  547. var eachExp = node.getAttribute(eachAttr),
  548. ctrlExp = node.getAttribute(ctrlAttr)
  549. if (eachExp) { // each block
  550. var directive = DirectiveParser.parse(eachAttr, eachExp)
  551. if (directive) {
  552. directive.el = node
  553. seed._bind(directive)
  554. }
  555. } else if (ctrlExp && !root) { // nested controllers
  556. new Seed(node, {
  557. child: true,
  558. parentSeed: seed
  559. })
  560. } else { // normal node
  561. // parse if has attributes
  562. if (node.attributes && node.attributes.length) {
  563. // forEach vs for loop perf comparison: http://jsperf.com/for-vs-foreach-case
  564. // takeaway: not worth it to wrtie manual loops.
  565. slice.call(node.attributes).forEach(function (attr) {
  566. if (attr.name === ctrlAttr) return
  567. var valid = false
  568. attr.value.split(',').forEach(function (exp) {
  569. var directive = DirectiveParser.parse(attr.name, exp)
  570. if (directive) {
  571. valid = true
  572. directive.el = node
  573. seed._bind(directive)
  574. }
  575. })
  576. if (valid) node.removeAttribute(attr.name)
  577. })
  578. }
  579. // recursively compile childNodes
  580. if (node.childNodes.length) {
  581. slice.call(node.childNodes).forEach(seed._compileNode, seed)
  582. }
  583. }
  584. }
  585. }
  586. /*
  587. * Compile a text node
  588. */
  589. SeedProto._compileTextNode = function (node) {
  590. var tokens = TextParser.parse(node)
  591. if (!tokens) return
  592. var seed = this,
  593. dirname = config.prefix + '-text',
  594. el, token, directive
  595. for (var i = 0, l = tokens.length; i < l; i++) {
  596. token = tokens[i]
  597. el = document.createTextNode()
  598. if (token.key) {
  599. directive = DirectiveParser.parse(dirname, token.key)
  600. if (directive) {
  601. directive.el = el
  602. seed._bind(directive)
  603. }
  604. } else {
  605. el.nodeValue = token
  606. }
  607. node.parentNode.insertBefore(el, node)
  608. }
  609. node.parentNode.removeChild(node)
  610. }
  611. /*
  612. * Add a directive instance to the correct binding & scope
  613. */
  614. SeedProto._bind = function (directive) {
  615. var key = directive.key,
  616. seed = directive.seed = this
  617. // deal with each block
  618. if (this.each) {
  619. if (key.indexOf(this.eachPrefix) === 0) {
  620. key = directive.key = key.replace(this.eachPrefix, '')
  621. } else {
  622. seed = this.parentSeed
  623. }
  624. }
  625. // deal with nesting
  626. seed = traceOwnerSeed(directive, seed)
  627. var binding = seed._bindings[key] || seed._createBinding(key)
  628. // add directive to this binding
  629. binding.instances.push(directive)
  630. directive.binding = binding
  631. // invoke bind hook if exists
  632. if (directive.bind) {
  633. directive.bind(binding.value)
  634. }
  635. // set initial value
  636. directive.update(binding.value)
  637. if (binding.isComputed) {
  638. directive.refresh()
  639. }
  640. }
  641. /*
  642. * Create binding and attach getter/setter for a key to the scope object
  643. */
  644. SeedProto._createBinding = function (key) {
  645. var binding = new Binding(this, key)
  646. this._bindings[key] = binding
  647. if (binding.isComputed) this._computed.push(binding)
  648. return binding
  649. }
  650. /*
  651. * Call unbind() of all directive instances
  652. * to remove event listeners, destroy child seeds, etc.
  653. */
  654. SeedProto._unbind = function () {
  655. var i, ins
  656. for (var key in this._bindings) {
  657. ins = this._bindings[key].instances
  658. i = ins.length
  659. while (i--) {
  660. if (ins[i].unbind) ins[i].unbind()
  661. }
  662. }
  663. }
  664. /*
  665. * Unbind and remove element
  666. */
  667. SeedProto._destroy = function () {
  668. this._unbind()
  669. this.el.parentNode.removeChild(this.el)
  670. }
  671. // Helpers --------------------------------------------------------------------
  672. /*
  673. * determine which scope a key belongs to based on nesting symbols
  674. */
  675. function traceOwnerSeed (key, seed) {
  676. if (key.nesting) {
  677. var levels = key.nesting
  678. while (seed.parentSeed && levels--) {
  679. seed = seed.parentSeed
  680. }
  681. } else if (key.root) {
  682. while (seed.parentSeed) {
  683. seed = seed.parentSeed
  684. }
  685. }
  686. return seed
  687. }
  688. module.exports = Seed
  689. });
  690. require.register("seed/src/scope.js", function(exports, require, module){
  691. var utils = require('./utils')
  692. function Scope (seed, options) {
  693. this.$seed = seed
  694. this.$el = seed.el
  695. this.$index = options.index
  696. this.$parent = options.parentSeed && options.parentSeed.scope
  697. this.$watchers = {}
  698. }
  699. var ScopeProto = Scope.prototype
  700. /*
  701. * watch a key on the scope for changes
  702. * fire callback with new value
  703. */
  704. ScopeProto.$watch = function (key, callback) {
  705. var self = this
  706. // yield and wait for seed to finish compiling
  707. setTimeout(function () {
  708. var scope = self.$seed.scope,
  709. binding = self.$seed._bindings[key],
  710. watcher = self.$watchers[key] = {
  711. refresh: function () {
  712. callback(scope[key])
  713. },
  714. deps: binding.deps
  715. }
  716. binding.deps.forEach(function (dep) {
  717. dep.subs.push(watcher)
  718. })
  719. }, 0)
  720. }
  721. /*
  722. * remove watcher
  723. */
  724. ScopeProto.$unwatch = function (key) {
  725. var self = this
  726. setTimeout(function () {
  727. var watcher = self.$watchers[key]
  728. if (!watcher) return
  729. watcher.deps.forEach(function (dep) {
  730. dep.subs.splice(dep.subs.indexOf(watcher))
  731. })
  732. delete self.$watchers[key]
  733. }, 0)
  734. }
  735. /*
  736. * Dump a copy of current scope data, excluding seed-exposed properties.
  737. * @param key (optional): key for the value to dump
  738. */
  739. ScopeProto.$dump = function (key) {
  740. var bindings = this.$seed._bindings
  741. return utils.dumpValue(key ? bindings[key].value : this)
  742. }
  743. /*
  744. * stringify the result from $dump
  745. */
  746. ScopeProto.$serialize = function (key) {
  747. return JSON.stringify(this.$dump(key))
  748. }
  749. /*
  750. * unbind everything, remove everything
  751. */
  752. ScopeProto.$destroy = function () {
  753. this.$seed._destroy()
  754. }
  755. module.exports = Scope
  756. });
  757. require.register("seed/src/binding.js", function(exports, require, module){
  758. var utils = require('./utils'),
  759. observer = require('./deps-parser').observer,
  760. def = Object.defineProperty
  761. /*
  762. * Binding class.
  763. *
  764. * each property on the scope has one corresponding Binding object
  765. * which has multiple directive instances on the DOM
  766. * and multiple computed property dependents
  767. */
  768. function Binding (seed, key) {
  769. this.seed = seed
  770. this.key = key
  771. var path = key.split('.')
  772. this.inspect(utils.getNestedValue(seed.scope, path))
  773. this.def(seed.scope, path)
  774. this.instances = []
  775. this.subs = []
  776. this.deps = []
  777. }
  778. var BindingProto = Binding.prototype
  779. /*
  780. * Pre-process a passed in value based on its type
  781. */
  782. BindingProto.inspect = function (value) {
  783. var type = utils.typeOf(value),
  784. self = this
  785. // preprocess the value depending on its type
  786. if (type === 'Object') {
  787. if (value.get || value.set) { // computed property
  788. self.isComputed = true
  789. }
  790. } else if (type === 'Array') {
  791. utils.watchArray(value)
  792. value.on('mutate', function () {
  793. self.pub()
  794. })
  795. }
  796. self.value = value
  797. }
  798. /*
  799. * Define getter/setter for this binding on scope
  800. * recursive for nested objects
  801. */
  802. BindingProto.def = function (scope, path) {
  803. var self = this,
  804. key = path[0]
  805. if (path.length === 1) {
  806. // here we are! at the end of the path!
  807. // define the real value accessors.
  808. def(scope, key, {
  809. get: function () {
  810. if (observer.isObserving) {
  811. observer.emit('get', self)
  812. }
  813. return self.isComputed
  814. ? self.value.get()
  815. : self.value
  816. },
  817. set: function (value) {
  818. if (self.isComputed) {
  819. // computed properties cannot be redefined
  820. // no need to call binding.update() here,
  821. // as dependency extraction has taken care of that
  822. if (self.value.set) {
  823. self.value.set(value)
  824. }
  825. } else if (value !== self.value) {
  826. self.update(value)
  827. }
  828. }
  829. })
  830. } else {
  831. // we are not there yet!!!
  832. // create an intermediate subscope
  833. // which also has its own getter/setters
  834. var subScope = scope[key]
  835. if (!subScope) {
  836. subScope = {}
  837. def(scope, key, {
  838. get: function () {
  839. return subScope
  840. },
  841. set: function (value) {
  842. // when the subScope is given a new value,
  843. // copy everything over to trigger the setters
  844. for (var prop in value) {
  845. subScope[prop] = value[prop]
  846. }
  847. }
  848. })
  849. }
  850. // recurse
  851. this.def(subScope, path.slice(1))
  852. }
  853. }
  854. /*
  855. * Process the value, then trigger updates on all dependents
  856. */
  857. BindingProto.update = function (value) {
  858. this.inspect(value)
  859. var i = this.instances.length
  860. while (i--) {
  861. this.instances[i].update(value)
  862. }
  863. this.pub()
  864. }
  865. /*
  866. * Notify computed properties that depend on this binding
  867. * to update themselves
  868. */
  869. BindingProto.pub = function () {
  870. var i = this.subs.length
  871. while (i--) {
  872. this.subs[i].refresh()
  873. }
  874. }
  875. module.exports = Binding
  876. });
  877. require.register("seed/src/directive-parser.js", function(exports, require, module){
  878. var config = require('./config'),
  879. directives = require('./directives'),
  880. filters = require('./filters')
  881. var KEY_RE = /^[^\|<]+/,
  882. ARG_RE = /([^:]+):(.+)$/,
  883. FILTERS_RE = /\|[^\|<]+/g,
  884. FILTER_TOKEN_RE = /[^\s']+|'[^']+'/g,
  885. INVERSE_RE = /^!/,
  886. NESTING_RE = /^\^+/,
  887. ONEWAY_RE = /-oneway$/
  888. /*
  889. * Directive class
  890. * represents a single directive instance in the DOM
  891. */
  892. function Directive (directiveName, expression, oneway) {
  893. var prop,
  894. definition = directives[directiveName]
  895. // mix in properties from the directive definition
  896. if (typeof definition === 'function') {
  897. this._update = definition
  898. } else {
  899. this._update = definition.update
  900. for (prop in definition) {
  901. if (prop !== 'update') {
  902. this[prop] = definition[prop]
  903. }
  904. }
  905. }
  906. this.oneway = !!oneway
  907. this.directiveName = directiveName
  908. this.expression = expression.trim()
  909. this.rawKey = expression.match(KEY_RE)[0].trim()
  910. this.parseKey(this.rawKey)
  911. var filterExps = expression.match(FILTERS_RE)
  912. this.filters = filterExps
  913. ? filterExps.map(parseFilter)
  914. : null
  915. }
  916. var DirProto = Directive.prototype
  917. /*
  918. * called when a new value is set
  919. * for computed properties, this will only be called once
  920. * during initialization.
  921. */
  922. DirProto.update = function (value) {
  923. if (value && (value === this.value)) return
  924. this.value = value
  925. this.apply(value)
  926. }
  927. /*
  928. * called when a dependency has changed
  929. * computed properties only
  930. */
  931. DirProto.refresh = function () {
  932. var value = this.value.get()
  933. if (value === this.computedValue) return
  934. this.computedValue = value
  935. this.apply(value)
  936. this.binding.pub()
  937. }
  938. /*
  939. * Actually invoking the _update from the directive's definition
  940. */
  941. DirProto.apply = function (value) {
  942. if (this.inverse) value = !value
  943. this._update(
  944. this.filters
  945. ? this.applyFilters(value)
  946. : value
  947. )
  948. }
  949. /*
  950. * pipe the value through filters
  951. */
  952. DirProto.applyFilters = function (value) {
  953. var filtered = value
  954. this.filters.forEach(function (filter) {
  955. if (!filter.apply) throw new Error('Unknown filter: ' + filter.name)
  956. filtered = filter.apply(filtered, filter.args)
  957. })
  958. return filtered
  959. }
  960. /*
  961. * parse a key, extract argument and nesting/root info
  962. */
  963. DirProto.parseKey = function (rawKey) {
  964. var argMatch = rawKey.match(ARG_RE)
  965. var key = argMatch
  966. ? argMatch[2].trim()
  967. : rawKey.trim()
  968. this.arg = argMatch
  969. ? argMatch[1].trim()
  970. : null
  971. this.inverse = INVERSE_RE.test(key)
  972. if (this.inverse) {
  973. key = key.slice(1)
  974. }
  975. var nesting = key.match(NESTING_RE)
  976. this.nesting = nesting
  977. ? nesting[0].length
  978. : false
  979. this.root = key.charAt(0) === '$'
  980. if (this.nesting) {
  981. key = key.replace(NESTING_RE, '')
  982. } else if (this.root) {
  983. key = key.slice(1)
  984. }
  985. this.key = key
  986. }
  987. /*
  988. * parse a filter expression
  989. */
  990. function parseFilter (filter) {
  991. var tokens = filter.slice(1)
  992. .match(FILTER_TOKEN_RE)
  993. .map(function (token) {
  994. return token.replace(/'/g, '').trim()
  995. })
  996. return {
  997. name : tokens[0],
  998. apply : filters[tokens[0]],
  999. args : tokens.length > 1
  1000. ? tokens.slice(1)
  1001. : null
  1002. }
  1003. }
  1004. module.exports = {
  1005. /*
  1006. * make sure the directive and expression is valid
  1007. * before we create an instance
  1008. */
  1009. parse: function (dirname, expression) {
  1010. var prefix = config.prefix
  1011. if (dirname.indexOf(prefix) === -1) return null
  1012. dirname = dirname.slice(prefix.length + 1)
  1013. var oneway = ONEWAY_RE.test(dirname)
  1014. if (oneway) {
  1015. dirname = dirname.slice(0, -7)
  1016. }
  1017. var dir = directives[dirname],
  1018. valid = KEY_RE.test(expression)
  1019. if (config.debug) {
  1020. if (!dir) console.warn('unknown directive: ' + dirname)
  1021. if (!valid) console.warn('invalid directive expression: ' + expression)
  1022. }
  1023. return dir && valid
  1024. ? new Directive(dirname, expression, oneway)
  1025. : null
  1026. }
  1027. }
  1028. });
  1029. require.register("seed/src/text-parser.js", function(exports, require, module){
  1030. var config = require('./config'),
  1031. ESCAPE_RE = /[-.*+?^${}()|[\]\/\\]/g,
  1032. BINDING_RE
  1033. /*
  1034. * Escapes a string so that it can be used to construct RegExp
  1035. */
  1036. function escapeRegex (val) {
  1037. return val.replace(ESCAPE_RE, '\\$&')
  1038. }
  1039. module.exports = {
  1040. /*
  1041. * Parse a piece of text, return an array of tokens
  1042. */
  1043. parse: function (node) {
  1044. var text = node.nodeValue
  1045. if (!BINDING_RE.test(text)) return null
  1046. var m, i, tokens = []
  1047. do {
  1048. m = text.match(BINDING_RE)
  1049. if (!m) break
  1050. i = m.index
  1051. if (i > 0) tokens.push(text.slice(0, i))
  1052. tokens.push({ key: m[1] })
  1053. text = text.slice(i + m[0].length)
  1054. } while (true)
  1055. if (text.length) tokens.push(text)
  1056. return tokens
  1057. },
  1058. /*
  1059. * Build interpolate tag regex from config settings
  1060. */
  1061. buildRegex: function () {
  1062. var open = escapeRegex(config.interpolateTags.open),
  1063. close = escapeRegex(config.interpolateTags.close)
  1064. BINDING_RE = new RegExp(open + '(.+?)' + close)
  1065. }
  1066. }
  1067. });
  1068. require.register("seed/src/deps-parser.js", function(exports, require, module){
  1069. var Emitter = require('emitter'),
  1070. observer = new Emitter()
  1071. /*
  1072. * Auto-extract the dependencies of a computed property
  1073. * by recording the getters triggered when evaluating it.
  1074. *
  1075. * However, the first pass will contain duplicate dependencies
  1076. * for computed properties. It is therefore necessary to do a
  1077. * second pass in injectDeps()
  1078. */
  1079. function catchDeps (binding) {
  1080. observer.on('get', function (dep) {
  1081. binding.deps.push(dep)
  1082. })
  1083. binding.value.get()
  1084. observer.off('get')
  1085. }
  1086. /*
  1087. * The second pass of dependency extraction.
  1088. * Only include dependencies that don't have dependencies themselves.
  1089. */
  1090. function filterDeps (binding) {
  1091. var i = binding.deps.length, dep
  1092. while (i--) {
  1093. dep = binding.deps[i]
  1094. if (!dep.deps.length) {
  1095. dep.subs.push.apply(dep.subs, binding.instances)
  1096. } else {
  1097. binding.deps.splice(i, 1)
  1098. }
  1099. }
  1100. }
  1101. module.exports = {
  1102. /*
  1103. * the observer that catches events triggered by getters
  1104. */
  1105. observer: observer,
  1106. /*
  1107. * parse a list of computed property bindings
  1108. */
  1109. parse: function (bindings) {
  1110. observer.isObserving = true
  1111. bindings.forEach(catchDeps)
  1112. bindings.forEach(filterDeps)
  1113. observer.isObserving = false
  1114. }
  1115. }
  1116. });
  1117. require.register("seed/src/filters.js", function(exports, require, module){
  1118. var keyCodes = {
  1119. enter: 13,
  1120. tab: 9,
  1121. 'delete': 46,
  1122. up: 38,
  1123. left: 37,
  1124. right: 39,
  1125. down: 40
  1126. }
  1127. module.exports = {
  1128. capitalize: function (value) {
  1129. value = value.toString()
  1130. return value.charAt(0).toUpperCase() + value.slice(1)
  1131. },
  1132. uppercase: function (value) {
  1133. return value.toString().toUpperCase()
  1134. },
  1135. lowercase: function (value) {
  1136. return value.toString().toLowerCase()
  1137. },
  1138. currency: function (value, args) {
  1139. if (!value) return value
  1140. var sign = (args && args[0]) || '$',
  1141. i = value % 3,
  1142. f = '.' + value.toFixed(2).slice(-2),
  1143. s = Math.floor(value).toString()
  1144. return sign + s.slice(0, i) + s.slice(i).replace(/(\d{3})(?=\d)/g, '$1,') + f
  1145. },
  1146. key: function (handler, args) {
  1147. var code = keyCodes[args[0]]
  1148. if (!code) {
  1149. code = parseInt(args[0], 10)
  1150. }
  1151. return function (e) {
  1152. if (e.originalEvent.keyCode === code) {
  1153. handler.call(this, e)
  1154. }
  1155. }
  1156. }
  1157. }
  1158. });
  1159. require.register("seed/src/directives/index.js", function(exports, require, module){
  1160. module.exports = {
  1161. on : require('./on'),
  1162. each : require('./each'),
  1163. attr: function (value) {
  1164. this.el.setAttribute(this.arg, value)
  1165. },
  1166. text: function (value) {
  1167. this.el.textContent =
  1168. (typeof value === 'string' || typeof value === 'number')
  1169. ? value : ''
  1170. },
  1171. html: function (value) {
  1172. this.el.innerHTML =
  1173. (typeof value === 'string' || typeof value === 'number')
  1174. ? value : ''
  1175. },
  1176. show: function (value) {
  1177. this.el.style.display = value ? '' : 'none'
  1178. },
  1179. visible: function (value) {
  1180. this.el.style.visibility = value ? '' : 'hidden'
  1181. },
  1182. focus: function (value) {
  1183. // yield so it work when toggling visibility
  1184. var el = this.el
  1185. setTimeout(function () {
  1186. el[value ? 'focus' : 'blur']()
  1187. }, 0)
  1188. },
  1189. class: function (value) {
  1190. if (this.arg) {
  1191. this.el.classList[value ? 'add' : 'remove'](this.arg)
  1192. } else {
  1193. if (this.lastVal) {
  1194. this.el.classList.remove(this.lastVal)
  1195. }
  1196. this.el.classList.add(value)
  1197. this.lastVal = value
  1198. }
  1199. },
  1200. value: {
  1201. bind: function () {
  1202. if (this.oneway) return
  1203. var el = this.el, self = this
  1204. this.change = function () {
  1205. self.seed.scope[self.key] = el.value
  1206. }
  1207. el.addEventListener('change', this.change)
  1208. },
  1209. update: function (value) {
  1210. this.el.value = value
  1211. },
  1212. unbind: function () {
  1213. if (this.oneway) return
  1214. this.el.removeEventListener('change', this.change)
  1215. }
  1216. },
  1217. checked: {
  1218. bind: function () {
  1219. if (this.oneway) return
  1220. var el = this.el, self = this
  1221. this.change = function () {
  1222. self.seed.scope[self.key] = el.checked
  1223. }
  1224. el.addEventListener('change', this.change)
  1225. },
  1226. update: function (value) {
  1227. this.el.checked = !!value
  1228. },
  1229. unbind: function () {
  1230. if (this.oneway) return
  1231. this.el.removeEventListener('change', this.change)
  1232. }
  1233. },
  1234. 'if': {
  1235. bind: function () {
  1236. this.parent = this.el.parentNode
  1237. this.ref = document.createComment('sd-if-' + this.key)
  1238. var next = this.el.nextSibling
  1239. if (next) {
  1240. this.parent.insertBefore(this.ref, next)
  1241. } else {
  1242. this.parent.appendChild(this.ref)
  1243. }
  1244. },
  1245. update: function (value) {
  1246. if (!value) {
  1247. if (this.el.parentNode) {
  1248. this.parent.removeChild(this.el)
  1249. }
  1250. } else {
  1251. if (!this.el.parentNode) {
  1252. this.parent.insertBefore(this.el, this.ref)
  1253. }
  1254. }
  1255. }
  1256. },
  1257. style: {
  1258. bind: function () {
  1259. this.arg = convertCSSProperty(this.arg)
  1260. },
  1261. update: function (value) {
  1262. this.el.style[this.arg] = value
  1263. }
  1264. }
  1265. }
  1266. /*
  1267. * convert hyphen style CSS property to Camel style
  1268. */
  1269. var CONVERT_RE = /-(.)/g
  1270. function convertCSSProperty (prop) {
  1271. if (prop.charAt(0) === '-') prop = prop.slice(1)
  1272. return prop.replace(CONVERT_RE, function (m, char) {
  1273. return char.toUpperCase()
  1274. })
  1275. }
  1276. });
  1277. require.register("seed/src/directives/each.js", function(exports, require, module){
  1278. var config = require('../config')
  1279. /*
  1280. * Mathods that perform precise DOM manipulation
  1281. * based on mutator method triggered
  1282. */
  1283. var mutationHandlers = {
  1284. push: function (m) {
  1285. var self = this
  1286. m.args.forEach(function (data, i) {
  1287. var seed = self.buildItem(data, self.collection.length + i)
  1288. self.container.insertBefore(seed.el, self.ref)
  1289. })
  1290. },
  1291. pop: function (m) {
  1292. m.result.$destroy()
  1293. },
  1294. unshift: function (m) {
  1295. var self = this
  1296. m.args.forEach(function (data, i) {
  1297. var seed = self.buildItem(data, i),
  1298. ref = self.collection.length > m.args.length
  1299. ? self.collection[m.args.length].$el
  1300. : self.ref
  1301. self.container.insertBefore(seed.el, ref)
  1302. })
  1303. self.updateIndexes()
  1304. },
  1305. shift: function (m) {
  1306. m.result.$destroy()
  1307. var self = this
  1308. self.updateIndexes()
  1309. },
  1310. splice: function (m) {
  1311. var self = this,
  1312. index = m.args[0],
  1313. removed = m.args[1],
  1314. added = m.args.length - 2
  1315. m.result.forEach(function (scope) {
  1316. scope.$destroy()
  1317. })
  1318. if (added > 0) {
  1319. m.args.slice(2).forEach(function (data, i) {
  1320. var seed = self.buildItem(data, index + i),
  1321. pos = index - removed + added + 1,
  1322. ref = self.collection[pos]
  1323. ? self.collection[pos].$el
  1324. : self.ref
  1325. self.container.insertBefore(seed.el, ref)
  1326. })
  1327. }
  1328. if (removed !== added) {
  1329. self.updateIndexes()
  1330. }
  1331. },
  1332. sort: function () {
  1333. var self = this
  1334. self.collection.forEach(function (scope, i) {
  1335. scope.$index = i
  1336. self.container.insertBefore(scope.$el, self.ref)
  1337. })
  1338. }
  1339. }
  1340. mutationHandlers.reverse = mutationHandlers.sort
  1341. module.exports = {
  1342. bind: function () {
  1343. this.el.removeAttribute(config.prefix + '-each')
  1344. var ctn = this.container = this.el.parentNode
  1345. // create a comment node as a reference node for DOM insertions
  1346. this.ref = document.createComment('sd-each-' + this.arg)
  1347. ctn.insertBefore(this.ref, this.el)
  1348. ctn.removeChild(this.el)
  1349. },
  1350. update: function (collection) {
  1351. this.unbind(true)
  1352. if (!Array.isArray(collection)) return
  1353. this.collection = collection
  1354. // attach an object to container to hold handlers
  1355. this.container.sd_dHandlers = {}
  1356. // listen for collection mutation events
  1357. // the collection has been augmented during Binding.set()
  1358. var self = this
  1359. collection.on('mutate', function (mutation) {
  1360. mutationHandlers[mutation.method].call(self, mutation)
  1361. })
  1362. // create child-seeds and append to DOM
  1363. collection.forEach(function (data, i) {
  1364. var seed = self.buildItem(data, i)
  1365. self.container.insertBefore(seed.el, self.ref)
  1366. })
  1367. },
  1368. buildItem: function (data, index) {
  1369. var Seed = require('../seed'),
  1370. node = this.el.cloneNode(true)
  1371. var spore = new Seed(node, {
  1372. each: true,
  1373. eachPrefix: this.arg + '.',
  1374. parentSeed: this.seed,
  1375. index: index,
  1376. data: data,
  1377. delegator: this.container
  1378. })
  1379. this.collection[index] = spore.scope
  1380. return spore
  1381. },
  1382. updateIndexes: function () {
  1383. this.collection.forEach(function (scope, i) {
  1384. scope.$index = i
  1385. })
  1386. },
  1387. unbind: function (reset) {
  1388. if (this.collection && this.collection.length) {
  1389. var fn = reset ? '_destroy' : '_unbind'
  1390. this.collection.forEach(function (scope) {
  1391. scope.$seed[fn]()
  1392. })
  1393. this.collection = null
  1394. }
  1395. var ctn = this.container,
  1396. handlers = ctn.sd_dHandlers
  1397. for (var key in handlers) {
  1398. ctn.removeEventListener(handlers[key].event, handlers[key])
  1399. }
  1400. delete ctn.sd_dHandlers
  1401. }
  1402. }
  1403. });
  1404. require.register("seed/src/directives/on.js", function(exports, require, module){
  1405. function delegateCheck (current, top, identifier) {
  1406. if (current[identifier]) {
  1407. return current
  1408. } else if (current === top) {
  1409. return false
  1410. } else {
  1411. return delegateCheck(current.parentNode, top, identifier)
  1412. }
  1413. }
  1414. module.exports = {
  1415. expectFunction : true,
  1416. bind: function () {
  1417. if (this.seed.each) {
  1418. // attach an identifier to the el
  1419. // so it can be matched during event delegation
  1420. this.el[this.expression] = true
  1421. // attach the owner scope of this directive
  1422. this.el.sd_scope = this.seed.scope
  1423. }
  1424. },
  1425. update: function (handler) {
  1426. this.unbind()
  1427. if (!handler) return
  1428. var seed = this.seed,
  1429. event = this.arg
  1430. if (seed.each && event !== 'blur' && event !== 'blur') {
  1431. // for each blocks, delegate for better performance
  1432. // focus and blur events dont bubble so exclude them
  1433. var delegator = seed.delegator,
  1434. identifier = this.expression,
  1435. dHandler = delegator.sd_dHandlers[identifier]
  1436. if (dHandler) return
  1437. // the following only gets run once for the entire each block
  1438. dHandler = delegator.sd_dHandlers[identifier] = function (e) {
  1439. var target = delegateCheck(e.target, delegator, identifier)
  1440. if (target) {
  1441. handler.call(seed.scope, {
  1442. el: target,
  1443. scope: target.sd_scope,
  1444. originalEvent: e
  1445. })
  1446. }
  1447. }
  1448. dHandler.event = event
  1449. delegator.addEventListener(event, dHandler)
  1450. } else {
  1451. // a normal, single element handler
  1452. this.handler = function (e) {
  1453. handler.call(seed.scope, {
  1454. el: e.currentTarget,
  1455. scope: seed.scope,
  1456. originalEvent: e
  1457. })
  1458. }
  1459. this.el.addEventListener(event, this.handler)
  1460. }
  1461. },
  1462. unbind: function () {
  1463. this.el.removeEventListener(this.arg, this.handler)
  1464. }
  1465. }
  1466. });
  1467. require.alias("component-emitter/index.js", "seed/deps/emitter/index.js");
  1468. require.alias("component-emitter/index.js", "emitter/index.js");
  1469. require.alias("component-indexof/index.js", "component-emitter/deps/indexof/index.js");
  1470. require.alias("seed/src/main.js", "seed/index.js");
  1471. window.Seed = window.Seed || require('seed')
  1472. Seed.version = '0.1.1'
  1473. })();