jquery-entwine-rails 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in jquery-entwine-rails.gemspec
4
+ gemspec
@@ -0,0 +1,12 @@
1
+
2
+ ## Use Entwine in your Rails 3.1 application
3
+
4
+ in `Gemfile`
5
+
6
+ gem 'jquery-entwine-rails'
7
+
8
+ in `application.js`
9
+
10
+ //= require jquery.entwine
11
+
12
+ martini time.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "jquery-entwine-rails/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "jquery-entwine-rails"
7
+ s.version = Jquery::Entwine::Rails::VERSION
8
+ s.authors = ["The FrontSide"]
9
+ s.email = ["info@thefrontside.net"]
10
+ s.homepage = ""
11
+ s.summary = %q{Use the jquery-entwine plugin within Rails}
12
+ s.description = %q{Uses the Rails 3.1 Asset Pipeline to bring in the jquery-entwine library}
13
+
14
+ s.rubyforge_project = "jquery-entwine-rails"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib", "vendor"]
20
+
21
+ s.add_runtime_dependency "jquery-rails"
22
+ end
@@ -0,0 +1,9 @@
1
+ require "jquery-entwine-rails/version"
2
+
3
+ module JQuery
4
+ module Entwine
5
+ module Rails
6
+ require 'jquery-entwine-rails/engine'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+
2
+ module JQuery
3
+ module Entwine
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Jquery
2
+ module Entwine
3
+ module Rails
4
+ VERSION = "0.1.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,1675 @@
1
+ //= require jquery
2
+ /* jQuery.Entwine - Copyright 2009-2011 Hamish Friedlander and SilverStripe. Version . */
3
+
4
+ /* vendor/jquery.selector/jquery.class.js */
5
+
6
+ /**
7
+ * Very basic Class utility. Based on base and jquery.class.
8
+ *
9
+ * Class definition: var Foo = Base.extend({ init: function(){ Constructor }; method_name: function(){ Method } });
10
+ *
11
+ * Inheritance: var Bar = Foo.extend({ method_name: function(){ this._super(); } });
12
+ *
13
+ * new-less Constructor: new Foo(arg) <-same as-> Foo(arg)
14
+ */
15
+
16
+ var Base;
17
+
18
+ (function(){
19
+
20
+ var marker = {}, fnTest = /xyz/.test(function(){var xyz;}) ? /\b_super\b/ : /.*/;
21
+
22
+ // The base Class implementation (does nothing)
23
+ Base = function(){};
24
+
25
+ Base.addMethod = function(name, func) {
26
+ var parent = this._super && this._super.prototype;
27
+
28
+ if (parent && fnTest.test(func)) {
29
+ this.prototype[name] = function(){
30
+ var tmp = this._super;
31
+ this._super = parent[name];
32
+ try {
33
+ var ret = func.apply(this, arguments);
34
+ }
35
+ finally {
36
+ this._super = tmp;
37
+ }
38
+ return ret;
39
+ };
40
+ }
41
+ else this.prototype[name] = func;
42
+ };
43
+
44
+ Base.addMethods = function(props) {
45
+ for (var name in props) {
46
+ if (typeof props[name] == 'function') this.addMethod(name, props[name]);
47
+ else this.prototype[name] = props[name];
48
+ }
49
+ };
50
+
51
+ Base.subclassOf = function(parentkls) {
52
+ var kls = this;
53
+ while (kls) {
54
+ if (kls === parentkls) return true;
55
+ kls = kls._super;
56
+ }
57
+ };
58
+
59
+ // Create a new Class that inherits from this class
60
+ Base.extend = function(props) {
61
+
62
+ // The dummy class constructor
63
+ var Kls = function() {
64
+ if (arguments[0] === marker) return;
65
+
66
+ if (this instanceof Kls) {
67
+ if (this.init) this.init.apply(this, arguments);
68
+ }
69
+ else {
70
+ var ret = new Kls(marker); if (ret.init) ret.init.apply(ret, arguments); return ret;
71
+ }
72
+ };
73
+
74
+ // Add the common class variables and methods
75
+ Kls.constructor = Kls;
76
+ Kls.extend = Base.extend;
77
+ Kls.addMethod = Base.addMethod;
78
+ Kls.addMethods = Base.addMethods;
79
+ Kls.subclassOf = Base.subclassOf;
80
+
81
+ Kls._super = this;
82
+
83
+ // Attach the parent object to the inheritance chain
84
+ Kls.prototype = new this(marker);
85
+ Kls.prototype.constructor = Kls;
86
+
87
+ // Copy the properties over onto the new prototype
88
+ Kls.addMethods(props);
89
+
90
+ return Kls;
91
+ };
92
+ })();;
93
+
94
+
95
+ /* vendor/jquery.selector/jquery.selector.js */
96
+
97
+ (function($){
98
+
99
+ var tokens = {
100
+ UNICODE: /\\[0-9a-f]{1,6}(?:\r\n|[ \n\r\t\f])?/,
101
+ ESCAPE: /(?:UNICODE)|\\[^\n\r\f0-9a-f]/,
102
+ NONASCII: /[^\x00-\x7F]/,
103
+ NMSTART: /[_a-z]|(?:NONASCII)|(?:ESCAPE)/,
104
+ NMCHAR: /[_a-z0-9-]|(?:NONASCII)|(?:ESCAPE)/,
105
+ IDENT: /-?(?:NMSTART)(?:NMCHAR)*/,
106
+
107
+ NL: /\n|\r\n|\r|\f/,
108
+
109
+ STRING: /(?:STRING1)|(?:STRING2)|(?:STRINGBARE)/,
110
+ STRING1: /"(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\"])*"/,
111
+ STRING2: /'(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\'])*'/,
112
+ STRINGBARE: /(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\]])*/,
113
+
114
+ FUNCTION: /(?:IDENT)\(\)/,
115
+
116
+ INTEGER: /[0-9]+/,
117
+
118
+ WITHN: /([-+])?(INTEGER)?(n)\s*(?:([-+])\s*(INTEGER))?/,
119
+ WITHOUTN: /([-+])?(INTEGER)/
120
+ };
121
+
122
+ var rx = {
123
+ not: /:not\(/,
124
+ not_end: /\)/,
125
+
126
+ tag: /((?:IDENT)|\*)/,
127
+ id: /#(IDENT)/,
128
+ cls: /\.(IDENT)/,
129
+ attr: /\[\s*(IDENT)\s*(?:([^=]?=)\s*(STRING)\s*)?\]/,
130
+ pseudo_el: /(?::(first-line|first-letter|before|after))|(?:::((?:FUNCTION)|(?:IDENT)))/,
131
+ pseudo_cls_nth: /:nth-child\(\s*(?:(?:WITHN)|(?:WITHOUTN)|(odd|even))\s*\)/,
132
+ pseudo_cls: /:(IDENT)/,
133
+
134
+ comb: /\s*(\+|~|>)\s*|\s+/,
135
+ comma: /\s*,\s*/,
136
+ important: /\s+!important\s*$/
137
+ };
138
+
139
+ /* Replace placeholders with actual regex, and mark all as case insensitive */
140
+ var token = /[A-Z][A-Z0-9]+/;
141
+ for (var k in rx) {
142
+ var m, src = rx[k].source;
143
+ while (m = src.match(token)) src = src.replace(m[0], tokens[m[0]].source);
144
+ rx[k] = new RegExp(src, 'gi');
145
+ }
146
+
147
+ /**
148
+ * A string that matches itself against regexii, and keeps track of how much of itself has been matched
149
+ */
150
+ var ConsumableString = Base.extend({
151
+ init: function(str) {
152
+ this.str = str;
153
+ this.pos = 0;
154
+ },
155
+ match: function(rx) {
156
+ var m;
157
+ rx.lastIndex = this.pos;
158
+ if ((m = rx.exec(this.str)) && m.index == this.pos ) {
159
+ this.pos = rx.lastIndex ? rx.lastIndex : this.str.length ;
160
+ return m;
161
+ }
162
+ return null;
163
+ },
164
+ peek: function(rx) {
165
+ var m;
166
+ rx.lastIndex = this.pos;
167
+ if ((m = rx.exec(this.str)) && m.index == this.pos ) return m;
168
+ return null;
169
+ },
170
+ showpos: function() {
171
+ return this.str.slice(0,this.pos)+'<HERE>' + this.str.slice(this.pos);
172
+ },
173
+ done: function() {
174
+ return this.pos == this.str.length;
175
+ }
176
+ });
177
+
178
+ /* A base class that all Selectors inherit off */
179
+ var SelectorBase = Base.extend({});
180
+
181
+ /**
182
+ * A class representing a Simple Selector, as per the CSS3 selector spec
183
+ */
184
+ var SimpleSelector = SelectorBase.extend({
185
+ init: function() {
186
+ this.tag = null;
187
+ this.id = null;
188
+ this.classes = [];
189
+ this.attrs = [];
190
+ this.nots = [];
191
+ this.pseudo_classes = [];
192
+ this.pseudo_els = [];
193
+ },
194
+ parse: function(selector) {
195
+ var m;
196
+
197
+ /* Pull out the initial tag first, if there is one */
198
+ if (m = selector.match(rx.tag)) this.tag = m[1];
199
+
200
+ /* Then for each selection type, try and find a match */
201
+ do {
202
+ if (m = selector.match(rx.not)) {
203
+ this.nots[this.nots.length] = SelectorsGroup().parse(selector);
204
+ if (!(m = selector.match(rx.not_end))) {
205
+ throw 'Invalid :not term in selector';
206
+ }
207
+ }
208
+ else if (m = selector.match(rx.id)) this.id = m[1];
209
+ else if (m = selector.match(rx.cls)) this.classes[this.classes.length] = m[1];
210
+ else if (m = selector.match(rx.attr)) this.attrs[this.attrs.length] = [ m[1], m[2], m[3] ];
211
+ else if (m = selector.match(rx.pseudo_el)) this.pseudo_els[this.pseudo_els.length] = m[1] || m[2];
212
+ else if (m = selector.match(rx.pseudo_cls_nth)) {
213
+ if (m[3]) {
214
+ var a = parseInt((m[1]||'')+(m[2]||'1'));
215
+ var b = parseInt((m[4]||'')+(m[5]||'0'));
216
+ }
217
+ else {
218
+ var a = m[8] ? 2 : 0;
219
+ var b = m[8] ? (4-m[8].length) : parseInt((m[6]||'')+m[7]);
220
+ }
221
+ this.pseudo_classes[this.pseudo_classes.length] = ['nth-child', [a, b]];
222
+ }
223
+ else if (m = selector.match(rx.pseudo_cls)) this.pseudo_classes[this.pseudo_classes.length] = [m[1]];
224
+
225
+ } while(m && !selector.done());
226
+
227
+ return this;
228
+ }
229
+ });
230
+
231
+ /**
232
+ * A class representing a Selector, as per the CSS3 selector spec
233
+ */
234
+ var Selector = SelectorBase.extend({
235
+ init: function(){
236
+ this.parts = [];
237
+ },
238
+ parse: function(cons){
239
+ this.parts[this.parts.length] = SimpleSelector().parse(cons);
240
+
241
+ while (!cons.done() && !cons.peek(rx.comma) && (m = cons.match(rx.comb))) {
242
+ this.parts[this.parts.length] = m[1] || ' ';
243
+ this.parts[this.parts.length] = SimpleSelector().parse(cons);
244
+ }
245
+
246
+ return this.parts.length == 1 ? this.parts[0] : this;
247
+ }
248
+ });
249
+
250
+ /**
251
+ * A class representing a sequence of selectors, as per the CSS3 selector spec
252
+ */
253
+ var SelectorsGroup = SelectorBase.extend({
254
+ init: function(){
255
+ this.parts = [];
256
+ },
257
+ parse: function(cons){
258
+ this.parts[this.parts.length] = Selector().parse(cons);
259
+
260
+ while (!cons.done() && (m = cons.match(rx.comma))) {
261
+ this.parts[this.parts.length] = Selector().parse(cons);
262
+ }
263
+
264
+ return this.parts.length == 1 ? this.parts[0] : this;
265
+ }
266
+ });
267
+
268
+
269
+ $.selector = function(s){
270
+ var cons = ConsumableString(s);
271
+ var res = SelectorsGroup().parse(cons);
272
+
273
+ res.selector = s;
274
+
275
+ if (!cons.done()) throw 'Could not parse selector - ' + cons.showpos() ;
276
+ else return res;
277
+ };
278
+
279
+ $.selector.SelectorBase = SelectorBase;
280
+ $.selector.SimpleSelector = SimpleSelector;
281
+ $.selector.Selector = Selector;
282
+ $.selector.SelectorsGroup = SelectorsGroup;
283
+
284
+ })(jQuery);
285
+ ;
286
+
287
+
288
+ /* vendor/jquery.selector/jquery.selector.specifity.js */
289
+
290
+ (function($) {
291
+
292
+ $.selector.SimpleSelector.addMethod('specifity', function() {
293
+ if (this.spec) return this.spec;
294
+
295
+ var spec = [
296
+ this.id ? 1 : 0,
297
+ this.classes.length + this.attrs.length + this.pseudo_classes.length,
298
+ ((this.tag && this.tag != '*') ? 1 : 0) + this.pseudo_els.length
299
+ ];
300
+ $.each(this.nots, function(i,not){
301
+ var ns = not.specifity(); spec[0] += ns[0]; spec[1] += ns[1]; spec[2] += ns[2];
302
+ });
303
+
304
+ return this.spec = spec;
305
+ });
306
+
307
+ $.selector.Selector.addMethod('specifity', function(){
308
+ if (this.spec) return this.spec;
309
+
310
+ var spec = [0,0,0];
311
+ $.each(this.parts, function(i,part){
312
+ if (i%2) return;
313
+ var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2];
314
+ });
315
+
316
+ return this.spec = spec;
317
+ });
318
+
319
+ $.selector.SelectorsGroup.addMethod('specifity', function(){
320
+ if (this.spec) return this.spec;
321
+
322
+ var spec = [0,0,0];
323
+ $.each(this.parts, function(i,part){
324
+ var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2];
325
+ });
326
+
327
+ return this.spec = spec;
328
+ });
329
+
330
+
331
+ })(jQuery);
332
+ ;
333
+
334
+
335
+ /* vendor/jquery.selector/jquery.selector.matches.js */
336
+
337
+ /*
338
+ This attempts to do the opposite of Sizzle.
339
+ Sizzle is good for finding elements for a selector, but not so good for telling if an individual element matches a selector
340
+ */
341
+
342
+ (function($) {
343
+
344
+ /**** CAPABILITY TESTS ****/
345
+ var div = document.createElement('div');
346
+ div.innerHTML = '<form id="test"><input name="id" type="text"/></form>';
347
+
348
+ // In IE 6-7, getAttribute often does the wrong thing (returns similar to el.attr), so we need to use getAttributeNode on that browser
349
+ var getAttributeDodgy = div.firstChild.getAttribute('id') !== 'test';
350
+
351
+ // Does browser support Element.firstElementChild, Element.previousElementSibling, etc.
352
+ var hasElementTraversal = div.firstElementChild && div.firstElementChild.tagName == 'FORM';
353
+
354
+ // Does browser support Element.children
355
+ var hasChildren = div.children && div.children[0].tagName == 'FORM';
356
+
357
+ var FUNC_IN = /^\s*function\s*\([^)]*\)\s*\{/;
358
+ var FUNC_OUT = /}\s*$/;
359
+
360
+ var funcToString = function(f) {
361
+ return (''+f).replace(FUNC_IN,'').replace(FUNC_OUT,'');
362
+ };
363
+
364
+ // Can we use Function#toString ?
365
+ try {
366
+ var testFunc = function(){ return 'good'; };
367
+ if ((new Function('',funcToString(testFunc)))() != 'good') funcToString = false;
368
+ }
369
+ catch(e) { funcToString = false; console.log(e.message);/*pass*/ }
370
+
371
+ /**** INTRO ****/
372
+
373
+ var GOOD = /GOOD/g;
374
+ var BAD = /BAD/g;
375
+
376
+ var STARTS_WITH_QUOTES = /^['"]/g;
377
+
378
+ var join = function(js) {
379
+ return js.join('\n');
380
+ };
381
+
382
+ var join_complex = function(js) {
383
+ var code = new String(js.join('\n')); // String objects can have properties set. strings can't
384
+ code.complex = true;
385
+ return code;
386
+ };
387
+
388
+ /**** ATTRIBUTE ACCESSORS ****/
389
+
390
+ // Not all attribute names can be used as identifiers, so we encode any non-acceptable characters as hex
391
+ var varForAttr = function(attr) {
392
+ return '_' + attr.replace(/^[^A-Za-z]|[^A-Za-z0-9]/g, function(m){ return '_0x' + m.charCodeAt(0).toString(16) + '_'; });
393
+ };
394
+
395
+ var getAttr;
396
+
397
+ // Good browsers
398
+ if (!getAttributeDodgy) {
399
+ getAttr = function(attr){ return 'var '+varForAttr(attr)+' = el.getAttribute("'+attr+'");' ; };
400
+ }
401
+ // IE 6, 7
402
+ else {
403
+ // On IE 6 + 7, getAttribute still has to be called with DOM property mirror name, not attribute name. Map attributes to those names
404
+ var getAttrIEMap = { 'class': 'className', 'for': 'htmlFor' };
405
+
406
+ getAttr = function(attr) {
407
+ var ieattr = getAttrIEMap[attr] || attr;
408
+ return 'var '+varForAttr(attr)+' = el.getAttribute("'+ieattr+'",2) || (el.getAttributeNode("'+attr+'")||{}).nodeValue;';
409
+ };
410
+ }
411
+
412
+ /**** ATTRIBUTE COMPARITORS ****/
413
+
414
+ var attrchecks = {
415
+ '-': '!K',
416
+ '=': 'K != "V"',
417
+ '!=': 'K == "V"',
418
+ '~=': '_WS_K.indexOf(" V ") == -1',
419
+ '^=': '!K || K.indexOf("V") != 0',
420
+ '*=': '!K || K.indexOf("V") == -1',
421
+ '$=': '!K || K.substr(K.length-"V".length) != "V"'
422
+ };
423
+
424
+ /**** STATE TRACKER ****/
425
+
426
+ var State = $.selector.State = Base.extend({
427
+ init: function(){
428
+ this.reset();
429
+ },
430
+ reset: function() {
431
+ this.attrs = {}; this.wsattrs = {};
432
+ },
433
+
434
+ prev: function(){
435
+ this.reset();
436
+ if (hasElementTraversal) return 'el = el.previousElementSibling';
437
+ return 'while((el = el.previousSibling) && el.nodeType != 1) {}';
438
+ },
439
+ next: function() {
440
+ this.reset();
441
+ if (hasElementTraversal) return 'el = el.nextElementSibling';
442
+ return 'while((el = el.nextSibling) && el.nodeType != 1) {}';
443
+ },
444
+ prevLoop: function(body){
445
+ this.reset();
446
+ if (hasElementTraversal) return join([ 'while(el = el.previousElementSibling){', body]);
447
+ return join([
448
+ 'while(el = el.previousSibling){',
449
+ 'if (el.nodeType != 1) continue;',
450
+ body
451
+ ]);
452
+ },
453
+ parent: function() {
454
+ this.reset();
455
+ return 'el = el.parentNode;';
456
+ },
457
+ parentLoop: function(body) {
458
+ this.reset();
459
+ return join([
460
+ 'while((el = el.parentNode) && el.nodeType == 1){',
461
+ body,
462
+ '}'
463
+ ]);
464
+ },
465
+
466
+ uses_attr: function(attr) {
467
+ if (this.attrs[attr]) return;
468
+ this.attrs[attr] = true;
469
+ return getAttr(attr);
470
+ },
471
+ uses_wsattr: function(attr) {
472
+ if (this.wsattrs[attr]) return;
473
+ this.wsattrs[attr] = true;
474
+ return join([this.uses_attr(attr), 'var _WS_'+varForAttr(attr)+' = " "+'+varForAttr(attr)+'+" ";']);
475
+ },
476
+
477
+ save: function(lbl) {
478
+ return 'var el'+lbl+' = el;';
479
+ },
480
+ restore: function(lbl) {
481
+ this.reset();
482
+ return 'el = el'+lbl+';';
483
+ }
484
+ });
485
+
486
+ /**** PSEUDO-CLASS DETAILS ****/
487
+
488
+ var pseudoclschecks = {
489
+ 'first-child': join([
490
+ 'var cel = el;',
491
+ 'while(cel = cel.previousSibling){ if (cel.nodeType === 1) BAD; }'
492
+ ]),
493
+ 'last-child': join([
494
+ 'var cel = el;',
495
+ 'while(cel = cel.nextSibling){ if (cel.nodeType === 1) BAD; }'
496
+ ]),
497
+ 'nth-child': function(a,b) {
498
+ var get_i = join([
499
+ 'var i = 1, cel = el;',
500
+ 'while(cel = cel.previousSibling){',
501
+ 'if (cel.nodeType === 1) i++;',
502
+ '}'
503
+ ]);
504
+
505
+ if (a == 0) return join([
506
+ get_i,
507
+ 'if (i- '+b+' != 0) BAD;'
508
+ ]);
509
+ else if (b == 0 && a >= 0) return join([
510
+ get_i,
511
+ 'if (i%'+a+' != 0 || i/'+a+' < 0) BAD;'
512
+ ]);
513
+ else if (b == 0 && a < 0) return join([
514
+ 'BAD;'
515
+ ]);
516
+ else return join([
517
+ get_i,
518
+ 'if ((i- '+b+')%'+a+' != 0 || (i- '+b+')/'+a+' < 0) BAD;'
519
+ ]);
520
+ }
521
+ };
522
+
523
+ // Needs to refence contents of object, so must be injected after definition
524
+ pseudoclschecks['only-child'] = join([
525
+ pseudoclschecks['first-child'],
526
+ pseudoclschecks['last-child']
527
+ ]);
528
+
529
+ /**** SimpleSelector ****/
530
+
531
+ $.selector.SimpleSelector.addMethod('compile', function(el) {
532
+ var js = [];
533
+
534
+ /* Check against element name */
535
+ if (this.tag && this.tag != '*') {
536
+ js[js.length] = 'if (el.tagName != "'+this.tag.toUpperCase()+'") BAD;';
537
+ }
538
+
539
+ /* Check against ID */
540
+ if (this.id) {
541
+ js[js.length] = el.uses_attr('id');
542
+ js[js.length] = 'if (_id !== "'+this.id+'") BAD;';
543
+ }
544
+
545
+ /* Build className checking variable */
546
+ if (this.classes.length) {
547
+ js[js.length] = el.uses_wsattr('class');
548
+
549
+ /* Check against class names */
550
+ $.each(this.classes, function(i, cls){
551
+ js[js.length] = 'if (_WS__class.indexOf(" '+cls+' ") == -1) BAD;';
552
+ });
553
+ }
554
+
555
+ /* Check against attributes */
556
+ $.each(this.attrs, function(i, attr){
557
+ js[js.length] = (attr[1] == '~=') ? el.uses_wsattr(attr[0]) : el.uses_attr(attr[0]);
558
+ var check = attrchecks[ attr[1] || '-' ];
559
+ check = check.replace( /K/g, varForAttr(attr[0])).replace( /V/g, attr[2] && attr[2].match(STARTS_WITH_QUOTES) ? attr[2].slice(1,-1) : attr[2] );
560
+ js[js.length] = 'if ('+check+') BAD;';
561
+ });
562
+
563
+ /* Check against nots */
564
+ $.each(this.nots, function(i, not){
565
+ var lbl = ++lbl_id;
566
+ var func = join([
567
+ 'l'+lbl+':{',
568
+ not.compile(el).replace(BAD, 'break l'+lbl).replace(GOOD, 'BAD'),
569
+ '}'
570
+ ]);
571
+
572
+ if (!(not instanceof $.selector.SimpleSelector)) func = join([
573
+ el.save(lbl),
574
+ func,
575
+ el.restore(lbl)
576
+ ]);
577
+
578
+ js[js.length] = func;
579
+ });
580
+
581
+ /* Check against pseudo-classes */
582
+ $.each(this.pseudo_classes, function(i, pscls){
583
+ var check = pseudoclschecks[pscls[0]];
584
+ if (check) {
585
+ js[js.length] = ( typeof check == 'function' ? check.apply(this, pscls[1]) : check );
586
+ }
587
+ else if (check = $.find.selectors.filters[pscls[0]]) {
588
+ if (funcToString) {
589
+ js[js.length] = funcToString(check).replace(/elem/g,'el').replace(/return([^;]+);/,'if (!($1)) BAD;');
590
+ }
591
+ else {
592
+ js[js.length] = 'if (!$.find.selectors.filters.'+pscls[0]+'(el)) BAD;';
593
+ }
594
+ }
595
+ });
596
+
597
+ js[js.length] = 'GOOD';
598
+
599
+ /* Pass */
600
+ return join(js);
601
+ });
602
+
603
+ var lbl_id = 0;
604
+ /** Turns an compiled fragment into the first part of a combination */
605
+ function as_subexpr(f) {
606
+ if (f.complex)
607
+ return join([
608
+ 'l'+(++lbl_id)+':{',
609
+ f.replace(GOOD, 'break l'+lbl_id),
610
+ '}'
611
+ ]);
612
+ else
613
+ return f.replace(GOOD, '');
614
+ }
615
+
616
+ var combines = {
617
+ ' ': function(el, f1, f2) {
618
+ return join_complex([
619
+ f2,
620
+ 'while(true){',
621
+ el.parent(),
622
+ 'if (!el || el.nodeType !== 1) BAD;',
623
+ f1.compile(el).replace(BAD, 'continue'),
624
+ '}'
625
+ ]);
626
+ },
627
+
628
+ '>': function(el, f1, f2) {
629
+ return join([
630
+ f2,
631
+ el.parent(),
632
+ 'if (!el || el.nodeType !== 1) BAD;',
633
+ f1.compile(el)
634
+ ]);
635
+ },
636
+
637
+ '~': function(el, f1, f2) {
638
+ return join_complex([
639
+ f2,
640
+ el.prevLoop(),
641
+ f1.compile(el).replace(BAD, 'continue'),
642
+ '}',
643
+ 'BAD;'
644
+ ]);
645
+ },
646
+
647
+ '+': function(el, f1, f2) {
648
+ return join([
649
+ f2,
650
+ el.prev(),
651
+ 'if (!el) BAD;',
652
+ f1.compile(el)
653
+ ]);
654
+ }
655
+ };
656
+
657
+ $.selector.Selector.addMethod('compile', function(el) {
658
+ var l = this.parts.length;
659
+
660
+ var expr = this.parts[--l].compile(el);
661
+ while (l) {
662
+ var combinator = this.parts[--l];
663
+ expr = combines[combinator](el, this.parts[--l], as_subexpr(expr));
664
+ }
665
+
666
+ return expr;
667
+ });
668
+
669
+ $.selector.SelectorsGroup.addMethod('compile', function(el) {
670
+ var expr = [], lbl = ++lbl_id;
671
+
672
+ for (var i=0; i < this.parts.length; i++) {
673
+ expr[expr.length] = join([
674
+ i == 0 ? el.save(lbl) : el.restore(lbl),
675
+ 'l'+lbl+'_'+i+':{',
676
+ this.parts[i].compile(el).replace(BAD, 'break l'+lbl+'_'+i),
677
+ '}'
678
+ ]);
679
+ }
680
+
681
+ expr[expr.length] = 'BAD;';
682
+ return join(expr);
683
+ });
684
+
685
+ $.selector.SelectorBase.addMethod('matches', function(el){
686
+ this.matches = new Function('el', join([
687
+ 'if (!el) return false;',
688
+ this.compile(new State()).replace(BAD, 'return false').replace(GOOD, 'return true')
689
+ ]));
690
+ return this.matches(el);
691
+ });
692
+
693
+ })(jQuery);
694
+
695
+ ;
696
+
697
+
698
+ /* src/jquery.focusinout.js */
699
+
700
+ (function($){
701
+
702
+ /**
703
+ * Add focusin and focusout support to bind and live for browers other than IE. Designed to be usable in a delegated fashion (like $.live)
704
+ * Copyright (c) 2007 Jörn Zaefferer
705
+ */
706
+ $.support.focusInOut = !!($.browser.msie);
707
+ if (!$.support.focusInOut) {
708
+ // Emulate focusin and focusout by binding focus and blur in capturing mode
709
+ $.each({focus: 'focusin', blur: 'focusout'}, function(original, fix){
710
+ $.event.special[fix] = {
711
+ setup: function(){
712
+ if (!this.addEventListener) return false;
713
+ this.addEventListener(original, $.event.special[fix].handler, true);
714
+ },
715
+ teardown: function(){
716
+ if (!this.removeEventListener) return false;
717
+ this.removeEventListener(original, $.event.special[fix].handler, true);
718
+ },
719
+ handler: function(e){
720
+ arguments[0] = $.event.fix(e);
721
+ arguments[0].type = fix;
722
+ return $.event.handle.apply(this, arguments);
723
+ }
724
+ };
725
+ });
726
+ }
727
+
728
+ (function(){
729
+ //IE has some trouble with focusout with select and keyboard navigation
730
+ var activeFocus = null;
731
+
732
+ $(document)
733
+ .bind('focusin', function(e){
734
+ var target = e.realTarget || e.target;
735
+ if (activeFocus && activeFocus !== target) {
736
+ e.type = 'focusout';
737
+ $(activeFocus).trigger(e);
738
+ e.type = 'focusin';
739
+ e.target = target;
740
+ }
741
+ activeFocus = target;
742
+ })
743
+ .bind('focusout', function(e){
744
+ activeFocus = null;
745
+ });
746
+ })();
747
+
748
+ })(jQuery);;
749
+
750
+
751
+ /* src/jquery.entwine.js */
752
+
753
+ try {
754
+ console.log;
755
+ }
756
+ catch (e) {
757
+ window.console = undefined;
758
+ }
759
+
760
+ (function($) {
761
+
762
+ var namespaces = {};
763
+
764
+ $.entwine = function() {
765
+ $.fn.entwine.apply(null, arguments);
766
+ };
767
+
768
+ /**
769
+ * A couple of utility functions for accessing the store outside of this closure, and for making things
770
+ * operate in a little more easy-to-test manner
771
+ */
772
+ $.extend($.entwine, {
773
+ /**
774
+ * Get all the namespaces. Useful for introspection? Internal interface of Namespace not guaranteed consistant
775
+ */
776
+ namespaces: namespaces,
777
+
778
+ /**
779
+ * Remove all entwine rules
780
+ */
781
+ clear_all_rules: function() {
782
+ // Remove proxy functions
783
+ for (var k in $.fn) { if ($.fn[k].isentwinemethod) delete $.fn[k]; }
784
+ // Remove bound events - TODO: Make this pluggable, so this code can be moved to jquery.entwine.events.js
785
+ $(document).unbind('.entwine');
786
+ // Remove namespaces, and start over again
787
+ namespaces = $.entwine.namespaces = {};
788
+ },
789
+
790
+ WARN_LEVEL_NONE: 0,
791
+ WARN_LEVEL_IMPORTANT: 1,
792
+ WARN_LEVEL_BESTPRACTISE: 2,
793
+
794
+ /**
795
+ * Warning level. Set to a higher level to get warnings dumped to console.
796
+ */
797
+ warningLevel: 0,
798
+
799
+ /** Utility to optionally display warning messages depending on level */
800
+ warn: function(message, level) {
801
+ if (level <= $.entwine.warningLevel && console && console.warn) {
802
+ console.warn(message);
803
+ if (console.trace) console.trace();
804
+ }
805
+ },
806
+
807
+ warn_exception: function(where, /* optional: */ on, e) {
808
+ if ($.entwine.WARN_LEVEL_IMPORTANT <= $.entwine.warningLevel && console && console.warn) {
809
+ if (arguments.length == 2) { e = on; on = null; }
810
+
811
+ if (on) console.warn('Uncaught exception',e,'in',where,'on',on);
812
+ else console.warn('Uncaught exception',e,'in',where);
813
+
814
+ if (e.stack) console.warn("Stack Trace:\n" + e.stack);
815
+ }
816
+ }
817
+ });
818
+
819
+
820
+ /** Stores a count of definitions, so that we can sort identical selectors by definition order */
821
+ var rulecount = 0;
822
+
823
+ var Rule = Base.extend({
824
+ init: function(selector, name) {
825
+ this.selector = selector;
826
+ this.specifity = selector.specifity();
827
+ this.important = 0;
828
+ this.name = name;
829
+ this.rulecount = rulecount++;
830
+ }
831
+ });
832
+
833
+ Rule.compare = function(a, b) {
834
+ var as = a.specifity, bs = b.specifity;
835
+
836
+ return (a.important - b.important) ||
837
+ (as[0] - bs[0]) ||
838
+ (as[1] - bs[1]) ||
839
+ (as[2] - bs[2]) ||
840
+ (a.rulecount - b.rulecount) ;
841
+ };
842
+
843
+ $.entwine.RuleList = function() {
844
+ var list = [];
845
+
846
+ list.addRule = function(selector, name){
847
+ var rule = Rule(selector, name);
848
+
849
+ list[list.length] = rule;
850
+ list.sort(Rule.compare);
851
+
852
+ return rule;
853
+ };
854
+
855
+ return list;
856
+ };
857
+
858
+ var handlers = [];
859
+
860
+ /**
861
+ * A Namespace holds all the information needed for adding entwine methods to a namespace (including the _null_ namespace)
862
+ */
863
+ $.entwine.Namespace = Base.extend({
864
+ init: function(name){
865
+ if (name && !name.match(/^[A-Za-z0-9.]+$/)) $.entwine.warn('Entwine namespace '+name+' is not formatted as period seperated identifiers', $.entwine.WARN_LEVEL_BESTPRACTISE);
866
+ name = name || '__base';
867
+
868
+ this.name = name;
869
+ this.store = {};
870
+
871
+ namespaces[name] = this;
872
+
873
+ if (name == "__base") {
874
+ this.injectee = $.fn;
875
+ this.$ = $;
876
+ }
877
+ else {
878
+ // We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into
879
+
880
+ // jQuery 1.5 already provides a nice way to subclass, so use it
881
+ if ($.sub) {
882
+ this.$ = $.sub();
883
+ this.injectee = this.$.prototype;
884
+ }
885
+ // For jQuery < 1.5 we have to do it ourselves
886
+ else {
887
+ var subfn = function(){};
888
+ this.injectee = subfn.prototype = new $;
889
+
890
+ // And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building
891
+ var bound$ = this.$ = function(a) {
892
+ // Try the simple way first
893
+ var jq = $.fn.init.apply(new subfn(), arguments);
894
+ if (jq instanceof subfn) return jq;
895
+
896
+ // That didn't return a bound object, so now we need to copy it
897
+ var rv = new subfn();
898
+ rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length;
899
+ while (i--) rv[i] = jq[i];
900
+ return rv;
901
+ };
902
+
903
+ this.injectee.pushStack = function(elems, name, selector){
904
+ var ret = bound$(elems);
905
+
906
+ // Add the old object onto the stack (as a reference)
907
+ ret.prevObject = this;
908
+ ret.context = this.context;
909
+
910
+ if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector;
911
+ else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")";
912
+
913
+ // Return the newly-formed element set
914
+ return ret;
915
+ };
916
+
917
+ // Copy static functions through from $ to this.$ so e.g. $.ajax still works
918
+ // @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through
919
+ $.extend(this.$, $);
920
+ }
921
+
922
+ // We override entwine to inject the name of this namespace when defining blocks inside this namespace
923
+ var entwine_wrapper = this.injectee.entwine = function(spacename) {
924
+ var args = arguments;
925
+
926
+ if (!spacename || typeof spacename != 'string') { args = $.makeArray(args); args.unshift(name); }
927
+ else if (spacename.charAt(0) != '.') args[0] = name+'.'+spacename;
928
+
929
+ return $.fn.entwine.apply(this, args);
930
+ };
931
+
932
+ this.$.entwine = function() {
933
+ entwine_wrapper.apply(null, arguments);
934
+ };
935
+
936
+ for (var i = 0; i < handlers.length; i++) {
937
+ var handler = handlers[i], builder;
938
+
939
+ // Inject jQuery object method overrides
940
+ if (builder = handler.namespaceMethodOverrides) {
941
+ var overrides = builder(this);
942
+ for (var k in overrides) this.injectee[k] = overrides[k];
943
+ }
944
+
945
+ // Inject $.entwine function overrides
946
+ if (builder = handler.namespaceStaticOverrides) {
947
+ var overrides = builder(this);
948
+ for (var k in overrides) this.$.entwine[k] = overrides[k];
949
+ }
950
+ }
951
+ }
952
+ },
953
+
954
+ /**
955
+ * Returns a function that does selector matching against the function list for a function name
956
+ * Used by proxy for all calls, and by ctorProxy to handle _super calls
957
+ * @param {String} name - name of the function as passed in the construction object
958
+ * @param {String} funcprop - the property on the Rule object that gives the actual function to call
959
+ * @param {function} basefunc - the non-entwine function to use as the catch-all function at the bottom of the stack
960
+ */
961
+ one: function(name, funcprop, basefunc) {
962
+ var namespace = this;
963
+ var funcs = this.store[name];
964
+
965
+ var one = function(el, args, i){
966
+ if (i === undefined) i = funcs.length;
967
+ while (i--) {
968
+ if (funcs[i].selector.matches(el)) {
969
+ var ret, tmp_i = el.i, tmp_f = el.f;
970
+ el.i = i; el.f = one;
971
+ try { ret = funcs[i][funcprop].apply(namespace.$(el), args); }
972
+ finally { el.i = tmp_i; el.f = tmp_f; }
973
+ return ret;
974
+ }
975
+ }
976
+ // If we didn't find a entwine-defined function, but there is a non-entwine function to use as a base, try that
977
+ if (basefunc) return basefunc.apply(namespace.$(el), args);
978
+ };
979
+
980
+ return one;
981
+ },
982
+
983
+ /**
984
+ * A proxy is a function attached to a callable object (either the base jQuery.fn or a subspace object) which handles
985
+ * finding and calling the correct function for each member of the current jQuery context
986
+ * @param {String} name - name of the function as passed in the construction object
987
+ * @param {function} basefunc - the non-entwine function to use as the catch-all function at the bottom of the stack
988
+ */
989
+ build_proxy: function(name, basefunc) {
990
+ var one = this.one(name, 'func', basefunc);
991
+
992
+ var prxy = function() {
993
+ var rv, ctx = $(this);
994
+
995
+ var i = ctx.length;
996
+ while (i--) rv = one(ctx[i], arguments);
997
+ return rv;
998
+ };
999
+
1000
+ return prxy;
1001
+ },
1002
+
1003
+ bind_proxy: function(selector, name, func) {
1004
+ var rulelist = this.store[name] || (this.store[name] = $.entwine.RuleList());
1005
+
1006
+ var rule = rulelist.addRule(selector, name); rule.func = func;
1007
+
1008
+ if (!this.injectee.hasOwnProperty(name) || !this.injectee[name].isentwinemethod) {
1009
+ this.injectee[name] = this.build_proxy(name, this.injectee.hasOwnProperty(name) ? this.injectee[name] : null);
1010
+ this.injectee[name].isentwinemethod = true;
1011
+ }
1012
+
1013
+ if (!this.injectee[name].isentwinemethod) {
1014
+ $.entwine.warn('Warning: Entwine function '+name+' clashes with regular jQuery function - entwine function will not be callable directly on jQuery object', $.entwine.WARN_LEVEL_IMPORTANT);
1015
+ }
1016
+ },
1017
+
1018
+ add: function(selector, data) {
1019
+ // For every item in the hash, try ever method handler, until one returns true
1020
+ for (var k in data) {
1021
+ var v = data[k];
1022
+
1023
+ for (var i = 0; i < handlers.length; i++) {
1024
+ if (handlers[i].bind && handlers[i].bind.call(this, selector, k, v)) break;
1025
+ }
1026
+ }
1027
+ },
1028
+
1029
+ has: function(ctx, name) {
1030
+ var rulelist = this.store[name];
1031
+ if (!rulelist) return false;
1032
+
1033
+ /* We go forward this time, since low specifity is likely to knock out a bunch of elements quickly */
1034
+ for (var i = 0 ; i < rulelist.length; i++) {
1035
+ ctx = ctx.not(rulelist[i].selector);
1036
+ if (!ctx.length) return true;
1037
+ }
1038
+ return false;
1039
+ }
1040
+ });
1041
+
1042
+ /**
1043
+ * A handler is some javascript code that adds support for some time of key / value pair passed in the hash to the Namespace add method.
1044
+ * The default handlers provided (and included by default) are event, ctor and properties
1045
+ */
1046
+ $.entwine.Namespace.addHandler = function(handler) {
1047
+ for (var i = 0; i < handlers.length && handlers[i].order < handler.order; i++) { /* Pass */ }
1048
+ handlers.splice(i, 0, handler);
1049
+ };
1050
+
1051
+ $.entwine.Namespace.addHandler({
1052
+ order: 50,
1053
+
1054
+ bind: function(selector, k, v){
1055
+ if ($.isFunction(v)) {
1056
+ this.bind_proxy(selector, k, v);
1057
+ return true;
1058
+ }
1059
+ }
1060
+ });
1061
+
1062
+ $.extend($.fn, {
1063
+ /**
1064
+ * Main entwine function. Used for new definitions, calling into a namespace (or forcing the base namespace) and entering a using block
1065
+ *
1066
+ */
1067
+ entwine: function(spacename) {
1068
+ var i = 0;
1069
+ /* Don't actually work out selector until we try and define something on it - we might be opening a namespace on an function-traveresed object
1070
+ which have non-standard selectors like .parents(.foo).slice(0,1) */
1071
+ var selector = null;
1072
+
1073
+ /* By default we operator on the base namespace */
1074
+ var namespace = namespaces.__base || $.entwine.Namespace();
1075
+
1076
+ /* If the first argument is a string, then it's the name of a namespace. Look it up */
1077
+ if (typeof spacename == 'string') {
1078
+ if (spacename.charAt('0') == '.') spacename = spacename.substr(1);
1079
+ if (spacename) namespace = namespaces[spacename] || $.entwine.Namespace(spacename);
1080
+ i=1;
1081
+ }
1082
+
1083
+ /* All remaining arguments should either be using blocks or definition hashs */
1084
+ while (i < arguments.length) {
1085
+ var res = arguments[i++];
1086
+
1087
+ // If it's a function, call it - either it's a using block or it's a namespaced entwine definition
1088
+ if ($.isFunction(res)) {
1089
+ if (res.length != 1) $.entwine.warn('Function block inside entwine definition does not take $ argument properly', $.entwine.WARN_LEVEL_IMPORTANT);
1090
+ res = res.call(namespace.$(this), namespace.$);
1091
+ }
1092
+
1093
+ // If we have a entwine definition hash, inject it into namespace
1094
+ if (res) {
1095
+ if (selector === null) selector = this.selector ? $.selector(this.selector) : false;
1096
+
1097
+ if (selector) namespace.add(selector, res);
1098
+ else $.entwine.warn('Entwine block given to entwine call without selector. Make sure you call $(selector).entwine when defining blocks', $.entwine.WARN_LEVEL_IMPORTANT);
1099
+ }
1100
+ }
1101
+
1102
+ /* Finally, return the jQuery object 'this' refers to, wrapped in the new namespace */
1103
+ return namespace.$(this);
1104
+ },
1105
+
1106
+ /**
1107
+ * Calls the next most specific version of the current entwine method
1108
+ */
1109
+ _super: function(){
1110
+ var rv, i = this.length;
1111
+ while (i--) {
1112
+ var el = this[0];
1113
+ rv = el.f(el, arguments, el.i);
1114
+ }
1115
+ return rv;
1116
+ }
1117
+ });
1118
+
1119
+ })(jQuery);
1120
+ ;
1121
+
1122
+
1123
+ /* src/jquery.entwine.dommaybechanged.js */
1124
+
1125
+ (function($){
1126
+
1127
+ /** What to call to run a function 'soon'. Normally setTimeout, but for syncronous mode we override so soon === now */
1128
+ var runSoon = window.setTimeout;
1129
+
1130
+ /** The timer handle for the asyncronous matching call */
1131
+ var check_id = null;
1132
+
1133
+ /** Fire the change event. Only fires on the document node, so bind to that */
1134
+ var triggerEvent = function() {
1135
+ $(document).triggerHandler('DOMMaybeChanged');
1136
+ check_id = null;
1137
+ };
1138
+
1139
+ $.extend($.entwine, {
1140
+ /**
1141
+ * Make onmatch and onunmatch work in synchronous mode - that is, new elements will be detected immediately after
1142
+ * the DOM manipulation that made them match. This is only really useful for during testing, since it's pretty slow
1143
+ * (otherwise we'd make it the default).
1144
+ */
1145
+ synchronous_mode: function() {
1146
+ if (check_id) clearTimeout(check_id); check_id = null;
1147
+ runSoon = function(func, delay){ func.call(this); return null; };
1148
+ },
1149
+
1150
+ /**
1151
+ * Trigger onmatch and onunmatch now - usefull for after DOM manipulation by methods other than through jQuery.
1152
+ * Called automatically on document.ready
1153
+ */
1154
+ triggerMatching: function() {
1155
+ matching();
1156
+ }
1157
+ });
1158
+
1159
+ function registerMutateFunction() {
1160
+ $.each(arguments, function(i,func){
1161
+ var old = $.fn[func];
1162
+ $.fn[func] = function() {
1163
+ var rv = old.apply(this, arguments);
1164
+ if (!check_id) check_id = runSoon(triggerEvent, 100);
1165
+ return rv;
1166
+ };
1167
+ });
1168
+ }
1169
+
1170
+ function registerSetterGetterFunction() {
1171
+ $.each(arguments, function(i,func){
1172
+ var old = $.fn[func];
1173
+ $.fn[func] = function(a, b) {
1174
+ var rv = old.apply(this, arguments);
1175
+ if (!check_id && (b !== undefined || typeof a != 'string')) check_id = runSoon(triggerEvent, 100);
1176
+ return rv;
1177
+ };
1178
+ });
1179
+ }
1180
+
1181
+ // Register core DOM manipulation methods
1182
+ registerMutateFunction('append', 'prepend', 'after', 'before', 'wrap', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');
1183
+ registerSetterGetterFunction('attr');
1184
+
1185
+ // And on DOM ready, trigger matching once
1186
+ $(function(){ triggerEvent(); });
1187
+
1188
+ })(jQuery);;
1189
+
1190
+
1191
+ /* src/jquery.entwine.events.js */
1192
+
1193
+ (function($) {
1194
+
1195
+ /** Taken from jQuery 1.5.2 for backwards compatibility */
1196
+ if ($.support.changeBubbles == undefined) {
1197
+ $.support.changeBubbles = true;
1198
+
1199
+ var el = document.createElement("div");
1200
+ eventName = "onchange";
1201
+
1202
+ if (el.attachEvent) {
1203
+ var isSupported = (eventName in el);
1204
+ if (!isSupported) {
1205
+ el.setAttribute(eventName, "return;");
1206
+ isSupported = typeof el[eventName] === "function";
1207
+ }
1208
+
1209
+ $.support.changeBubbles = isSupported;
1210
+ }
1211
+ }
1212
+
1213
+ /* Return true if node b is the same as, or is a descendant of, node a */
1214
+ if (document.compareDocumentPosition) {
1215
+ var is_or_contains = function(a, b) {
1216
+ return a && b && (a == b || !!(a.compareDocumentPosition(b) & 16));
1217
+ };
1218
+ }
1219
+ else {
1220
+ var is_or_contains = function(a, b) {
1221
+ return a && b && (a == b || (a.contains ? a.contains(b) : true));
1222
+ };
1223
+ }
1224
+
1225
+ /* Add the methods to handle event binding to the Namespace class */
1226
+ $.entwine.Namespace.addMethods({
1227
+ build_event_proxy: function(name) {
1228
+ var one = this.one(name, 'func');
1229
+
1230
+ var prxy = function(e, data) {
1231
+ // For events that do not bubble we manually trigger delegation (see delegate_submit below)
1232
+ // If this event is a manual trigger, the event we actually want to bubble is attached as a property of the passed event
1233
+ e = e.delegatedEvent || e;
1234
+
1235
+ var el = e.target;
1236
+ while (el && el.nodeType == 1 && !e.isPropagationStopped()) {
1237
+ var ret = one(el, arguments);
1238
+ if (ret !== undefined) e.result = ret;
1239
+ if (ret === false) { e.preventDefault(); e.stopPropagation(); }
1240
+
1241
+ el = el.parentNode;
1242
+ }
1243
+ };
1244
+
1245
+ return prxy;
1246
+ },
1247
+
1248
+ build_mouseenterleave_proxy: function(name) {
1249
+ var one = this.one(name, 'func');
1250
+
1251
+ var prxy = function(e) {
1252
+ var el = e.target;
1253
+ var rel = e.relatedTarget;
1254
+
1255
+ while (el && el.nodeType == 1 && !e.isPropagationStopped()) {
1256
+ /* We know el contained target. If it also contains relatedTarget then we didn't mouseenter / leave. What's more, every ancestor will also
1257
+ contan el and rel, and so we can just stop bubbling */
1258
+ if (is_or_contains(el, rel)) break;
1259
+
1260
+ var ret = one(el, arguments);
1261
+ if (ret !== undefined) e.result = ret;
1262
+ if (ret === false) { e.preventDefault(); e.stopPropagation(); }
1263
+
1264
+ el = el.parentNode;
1265
+ }
1266
+ };
1267
+
1268
+ return prxy;
1269
+ },
1270
+
1271
+ build_change_proxy: function(name) {
1272
+ var one = this.one(name, 'func');
1273
+
1274
+ /*
1275
+ This change bubble emulation code is taken mostly from jQuery 1.6 - unfortunately we can't easily reuse any of
1276
+ it without duplication, so we'll have to re-migrate any bugfixes
1277
+ */
1278
+
1279
+ // Get the value of an item. Isn't supposed to be interpretable, just stable for some value, and different
1280
+ // once the value changes
1281
+ var getVal = function( elem ) {
1282
+ var type = elem.type, val = elem.value;
1283
+
1284
+ if (type === "radio" || type === "checkbox") {
1285
+ val = elem.checked;
1286
+ }
1287
+ else if (type === "select-multiple") {
1288
+ val = "";
1289
+ if (elem.selectedIndex > -1) {
1290
+ val = jQuery.map(elem.options, function(elem){ return elem.selected; }).join("-");
1291
+ }
1292
+ }
1293
+ else if (jQuery.nodeName(elem, "select")) {
1294
+ val = elem.selectedIndex;
1295
+ }
1296
+
1297
+ return val;
1298
+ };
1299
+
1300
+ // Test if a node name is a form input
1301
+ var rformElems = /^(?:textarea|input|select)$/i;
1302
+
1303
+ // Check if this event is a change, and bubble the change event if it is
1304
+ var testChange = function(e) {
1305
+ var elem = e.target, data, val;
1306
+
1307
+ if (!rformElems.test(elem.nodeName) || elem.readOnly) return;
1308
+
1309
+ data = jQuery.data(elem, "_entwine_change_data");
1310
+ val = getVal(elem);
1311
+
1312
+ // the current data will be also retrieved by beforeactivate
1313
+ if (e.type !== "focusout" || elem.type !== "radio") {
1314
+ jQuery.data(elem, "_entwine_change_data", val);
1315
+ }
1316
+
1317
+ if (data === undefined || val === data) return;
1318
+
1319
+ if (data != null || val) {
1320
+ e.type = "change";
1321
+
1322
+ while (elem && elem.nodeType == 1 && !e.isPropagationStopped()) {
1323
+ var ret = one(elem, arguments);
1324
+ if (ret !== undefined) e.result = ret;
1325
+ if (ret === false) { e.preventDefault(); e.stopPropagation(); }
1326
+
1327
+ elem = elem.parentNode;
1328
+ }
1329
+ }
1330
+ };
1331
+
1332
+ // The actual proxy - responds to several events, some of which triger a change check, some
1333
+ // of which just store the value for future change checks
1334
+ var prxy = function(e) {
1335
+ var event = e.type, elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
1336
+
1337
+ switch (event) {
1338
+ case 'focusout':
1339
+ case 'beforedeactivate':
1340
+ testChange.apply(this, arguments);
1341
+ break;
1342
+
1343
+ case 'click':
1344
+ if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
1345
+ testChange.apply(this, arguments);
1346
+ }
1347
+ break;
1348
+
1349
+ // Change has to be called before submit
1350
+ // Keydown will be called before keypress, which is used in submit-event delegation
1351
+ case 'keydown':
1352
+ if (
1353
+ (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
1354
+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
1355
+ type === "select-multiple"
1356
+ ) {
1357
+ testChange.apply(this, arguments);
1358
+ }
1359
+ break;
1360
+
1361
+ // Beforeactivate happens also before the previous element is blurred
1362
+ // with this event you can't trigger a change event, but you can store
1363
+ // information
1364
+ case 'focusin':
1365
+ case 'beforeactivate':
1366
+ jQuery.data( elem, "_entwine_change_data", getVal(elem) );
1367
+ break;
1368
+ }
1369
+ }
1370
+
1371
+ return prxy;
1372
+ },
1373
+
1374
+ bind_event: function(selector, name, func, event) {
1375
+ var funcs = this.store[name] || (this.store[name] = $.entwine.RuleList()) ;
1376
+ var proxies = funcs.proxies || (funcs.proxies = {});
1377
+
1378
+ var rule = funcs.addRule(selector, name); rule.func = func;
1379
+
1380
+ if (!proxies[name]) {
1381
+ switch (name) {
1382
+ case 'onmouseenter':
1383
+ proxies[name] = this.build_mouseenterleave_proxy(name);
1384
+ event = 'mouseover';
1385
+ break;
1386
+ case 'onmouseleave':
1387
+ proxies[name] = this.build_mouseenterleave_proxy(name);
1388
+ event = 'mouseout';
1389
+ break;
1390
+ case 'onchange':
1391
+ if (!$.support.changeBubbles) {
1392
+ proxies[name] = this.build_change_proxy(name);
1393
+ event = 'click keydown focusin focusout beforeactivate beforedeactivate';
1394
+ }
1395
+ break;
1396
+ case 'onsubmit':
1397
+ event = 'delegatedSubmit';
1398
+ break;
1399
+ case 'onfocus':
1400
+ case 'onblur':
1401
+ $.entwine.warn('Event '+event+' not supported - using focusin / focusout instead', $.entwine.WARN_LEVEL_IMPORTANT);
1402
+ }
1403
+
1404
+ // If none of the special handlers created a proxy, use the generic proxy
1405
+ if (!proxies[name]) proxies[name] = this.build_event_proxy(name);
1406
+
1407
+ $(document).bind(event.replace(/(\s+|$)/g, '.entwine$1'), proxies[name]);
1408
+ }
1409
+ }
1410
+ });
1411
+
1412
+ $.entwine.Namespace.addHandler({
1413
+ order: 40,
1414
+
1415
+ bind: function(selector, k, v){
1416
+ var match, event;
1417
+ if ($.isFunction(v) && (match = k.match(/^on(.*)/))) {
1418
+ event = match[1];
1419
+ this.bind_event(selector, k, v, event);
1420
+ return true;
1421
+ }
1422
+ }
1423
+ });
1424
+
1425
+ // Find all forms and bind onsubmit to trigger on the document too.
1426
+ // This is the only event that can't be grabbed via delegation
1427
+
1428
+ var form_binding_cache = $([]); // A cache for already-handled form elements
1429
+ var delegate_submit = function(e, data){
1430
+ var delegationEvent = $.Event('delegatedSubmit'); delegationEvent.delegatedEvent = e;
1431
+ return $(document).trigger(delegationEvent, data);
1432
+ };
1433
+
1434
+ $(document).bind('DOMMaybeChanged', function(){
1435
+ var forms = $('form');
1436
+ // Only bind to forms we haven't processed yet
1437
+ forms.not(form_binding_cache).bind('submit', delegate_submit);
1438
+ // Then remember the current set of forms
1439
+ form_binding_cache = forms;
1440
+ });
1441
+
1442
+ })(jQuery);
1443
+ ;
1444
+
1445
+
1446
+ /* src/jquery.entwine.ctors.js */
1447
+
1448
+ (function($) {
1449
+
1450
+ /* Add the methods to handle constructor & destructor binding to the Namespace class */
1451
+ $.entwine.Namespace.addMethods({
1452
+ bind_condesc: function(selector, name, func) {
1453
+ var ctors = this.store.ctors || (this.store.ctors = $.entwine.RuleList()) ;
1454
+
1455
+ var rule;
1456
+ for (var i = 0 ; i < ctors.length; i++) {
1457
+ if (ctors[i].selector.selector == selector.selector) {
1458
+ rule = ctors[i]; break;
1459
+ }
1460
+ }
1461
+ if (!rule) {
1462
+ rule = ctors.addRule(selector, 'ctors');
1463
+ }
1464
+
1465
+ rule[name] = func;
1466
+
1467
+ if (!ctors[name+'proxy']) {
1468
+ var one = this.one('ctors', name);
1469
+ var namespace = this;
1470
+
1471
+ var proxy = function(els, i, func) {
1472
+ var j = els.length;
1473
+ while (j--) {
1474
+ var el = els[j];
1475
+
1476
+ var tmp_i = el.i, tmp_f = el.f;
1477
+ el.i = i; el.f = one;
1478
+
1479
+ try { func.call(namespace.$(el)); }
1480
+ catch(e) { $.entwine.warn_exception(name, el, e); }
1481
+ finally { el.i = tmp_i; el.f = tmp_f; }
1482
+ }
1483
+ };
1484
+
1485
+ ctors[name+'proxy'] = proxy;
1486
+ }
1487
+ }
1488
+ });
1489
+
1490
+ $.entwine.Namespace.addHandler({
1491
+ order: 30,
1492
+
1493
+ bind: function(selector, k, v) {
1494
+ if ($.isFunction(v) && (k == 'onmatch' || k == 'onunmatch')) {
1495
+ this.bind_condesc(selector, k, v);
1496
+ return true;
1497
+ }
1498
+ }
1499
+ });
1500
+
1501
+ /**
1502
+ * Finds all the elements that now match a different rule (or have been removed) and call onmatch on onunmatch as appropriate
1503
+ *
1504
+ * Because this has to scan the DOM, and is therefore fairly slow, this is normally triggered off a short timeout, so that
1505
+ * a series of DOM manipulations will only trigger this once.
1506
+ *
1507
+ * The downside of this is that things like:
1508
+ * $('#foo').addClass('tabs'); $('#foo').tabFunctionBar();
1509
+ * won't work.
1510
+ */
1511
+ $(document).bind('DOMMaybeChanged', function(){
1512
+ // For every namespace
1513
+ for (var k in $.entwine.namespaces) {
1514
+ // That has constructors or destructors
1515
+ var ctors = $.entwine.namespaces[k].store.ctors;
1516
+ if (ctors) {
1517
+
1518
+ // Keep a record of elements that have matched already
1519
+ var matched = $([]), add, rem, res, rule, sel, ctor, dtor;
1520
+ // Stepping through each selector from most to least specific
1521
+ var j = ctors.length;
1522
+ while (j--) {
1523
+ // Build some quick-access variables
1524
+ rule = ctors[j];
1525
+ sel = rule.selector.selector;
1526
+ ctor = rule.onmatch;
1527
+ dtor = rule.onunmatch;
1528
+
1529
+ // Get the list of elements that match this selector, that haven't yet matched a more specific selector
1530
+ res = add = $(sel).not(matched);
1531
+
1532
+ // If this selector has a list of elements it matched against last time
1533
+ if (rule.cache) {
1534
+ // Find the ones that are extra this time
1535
+ add = res.not(rule.cache);
1536
+ if (dtor) {
1537
+ // Find the ones that are gone this time
1538
+ rem = rule.cache.not(res);
1539
+ // And call the destructor on them
1540
+ if (rem.length) ctors.onunmatchproxy(rem, j, dtor);
1541
+ }
1542
+ }
1543
+
1544
+ // Call the constructor on the newly matched ones
1545
+ if (add.length && ctor) ctors.onmatchproxy(add, j, ctor);
1546
+
1547
+ // Add these matched ones to the list tracking all elements matched so far
1548
+ matched = matched.add(res);
1549
+ // And remember this list of matching elements again this selector, so next matching we can find the unmatched ones
1550
+ ctors[j].cache = res;
1551
+ }
1552
+ }
1553
+ }
1554
+ });
1555
+
1556
+
1557
+ })(jQuery);
1558
+ ;
1559
+
1560
+
1561
+ /* src/jquery.entwine.properties.js */
1562
+
1563
+ (function($) {
1564
+
1565
+ var entwine_prepend = '__entwine!';
1566
+
1567
+ var getEntwineData = function(el, namespace, property) {
1568
+ return el.data(entwine_prepend + namespace + '!' + property);
1569
+ };
1570
+
1571
+ var setEntwineData = function(el, namespace, property, value) {
1572
+ return el.data(entwine_prepend + namespace + '!' + property, value);
1573
+ };
1574
+
1575
+ var getEntwineDataAsHash = function(el, namespace) {
1576
+ var hash = {};
1577
+ var id = jQuery.data(el[0]);
1578
+
1579
+ var matchstr = entwine_prepend + namespace + '!';
1580
+ var matchlen = matchstr.length;
1581
+
1582
+ var cache = jQuery.cache[id];
1583
+ for (var k in cache) {
1584
+ if (k.substr(0,matchlen) == matchstr) hash[k.substr(matchlen)] = cache[k];
1585
+ }
1586
+
1587
+ return hash;
1588
+ };
1589
+
1590
+ var setEntwineDataFromHash = function(el, namespace, hash) {
1591
+ for (var k in hash) setEntwineData(namespace, k, hash[k]);
1592
+ };
1593
+
1594
+ var entwineData = function(el, namespace, args) {
1595
+ switch (args.length) {
1596
+ case 0:
1597
+ return getEntwineDataAsHash(el, namespace);
1598
+ case 1:
1599
+ if (typeof args[0] == 'string') return getEntwineData(el, namespace, args[0]);
1600
+ else return setEntwineDataFromHash(el, namespace, args[0]);
1601
+ default:
1602
+ return setEntwineData(el, namespace, args[0], args[1]);
1603
+ }
1604
+ };
1605
+
1606
+ $.extend($.fn, {
1607
+ entwineData: function() {
1608
+ return entwineData(this, '__base', arguments);
1609
+ }
1610
+ });
1611
+
1612
+ $.entwine.Namespace.addHandler({
1613
+ order: 60,
1614
+
1615
+ bind: function(selector, k, v) {
1616
+ if (k.charAt(0) != k.charAt(0).toUpperCase()) $.entwine.warn('Entwine property '+k+' does not start with a capital letter', $.entwine.WARN_LEVEL_BESTPRACTISE);
1617
+
1618
+ // Create the getters and setters
1619
+
1620
+ var getterName = 'get'+k;
1621
+ var setterName = 'set'+k;
1622
+
1623
+ this.bind_proxy(selector, getterName, function() { var r = this.entwineData(k); return r === undefined ? v : r; });
1624
+ this.bind_proxy(selector, setterName, function(v){ return this.entwineData(k, v); });
1625
+
1626
+ // Get the get and set proxies we just created
1627
+
1628
+ var getter = this.injectee[getterName];
1629
+ var setter = this.injectee[setterName];
1630
+
1631
+ // And bind in the jQuery-style accessor
1632
+
1633
+ this.bind_proxy(selector, k, function(v){ return (arguments.length == 1 ? setter : getter).call(this, v) ; });
1634
+
1635
+ return true;
1636
+ },
1637
+
1638
+ namespaceMethodOverrides: function(namespace){
1639
+ return {
1640
+ entwineData: function() {
1641
+ return entwineData(this, namespace.name, arguments);
1642
+ }
1643
+ };
1644
+ }
1645
+ });
1646
+
1647
+ })(jQuery);
1648
+ ;
1649
+
1650
+
1651
+ /* src/jquery.entwine.legacy.js */
1652
+
1653
+ (function($) {
1654
+
1655
+ // Adds back concrete methods for backwards compatibility
1656
+ $.concrete = $.entwine;
1657
+ $.fn.concrete = $.fn.entwine;
1658
+ $.fn.concreteData = $.fn.entwineData;
1659
+
1660
+ // Use addHandler to hack in the namespace.$.concrete equivilent to the namespace.$.entwine namespace-injection
1661
+ $.entwine.Namespace.addHandler({
1662
+ order: 100,
1663
+ bind: function(selector, k, v) { return false; },
1664
+
1665
+ namespaceMethodOverrides: function(namespace){
1666
+ namespace.$.concrete = namespace.$.entwine;
1667
+ namespace.injectee.concrete = namespace.injectee.entwine;
1668
+ namespace.injectee.concreteData = namespace.injectee.entwineData;
1669
+ return {};
1670
+ }
1671
+ });
1672
+
1673
+ })(jQuery);
1674
+ ;
1675
+