jquery-entwine-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+