merging
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@92557 467b73ca-7a2a-4603-9d3b-597d59a354a9
@ -28,13 +28,7 @@ class CalendarDateField extends DateField {
|
||||
}
|
||||
|
||||
|
||||
// javascript: concrete
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.class.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.specifity.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.matches.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.dat.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.concrete.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/dist/jquery.concrete-latest.js');
|
||||
|
||||
// javascript: custom
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/javascript/CalendarDateField.js');
|
||||
|
@ -1073,7 +1073,7 @@ class ComplexTableField_Popup extends Form {
|
||||
Requirements::css(CMS_DIR . '/css/typography.css');
|
||||
Requirements::css(CMS_DIR . '/css/cms_right.css');
|
||||
Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/prototype/prototype.js");
|
||||
Requirements::javascript(SAPPHIRE_dir . "/thirdparty/behaviour/behaviour.js");
|
||||
Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/behaviour/behaviour.js");
|
||||
Requirements::javascript(SAPPHIRE_DIR . "/javascript/prototype_improvements.js");
|
||||
Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/scriptaculous/scriptaculous.js");
|
||||
Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/scriptaculous/scriptaculous/controls.js");
|
||||
|
@ -58,13 +58,7 @@ class TabSet extends CompositeField {
|
||||
Requirements::css(SAPPHIRE_DIR . '/thirdparty/jquery-ui-themes/smoothness/ui.all.css');
|
||||
Requirements::css(SAPPHIRE_DIR . '/thirdparty/jquery-ui-themes/smoothness/ui.tabs.css');
|
||||
|
||||
// concrete
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.class.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.specifity.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.matches.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.dat.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.concrete.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/dist/jquery.concrete-latest.js');
|
||||
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/javascript/TabSet.js');
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
(function($) {
|
||||
$.concrete('ss', function($){
|
||||
/**
|
||||
* Formats a <input type="text"> field with a jQuery UI datepicker.
|
||||
*
|
||||
@ -6,17 +7,15 @@
|
||||
*
|
||||
* @author Ingo Schommer, SilverStripe Ltd.
|
||||
*/
|
||||
$('.calendardate').concrete('ss', function($){
|
||||
return {
|
||||
$('.calendardate').concrete({
|
||||
onmatch: function() {
|
||||
this.find('input').each(function() {
|
||||
var conf = $(this).metadata();
|
||||
if(conf.minDate) conf.minDate = new Date(Date.parse(conf.minDate));
|
||||
|
||||
//
|
||||
$(this).datepicker(conf);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
}(jQuery));
|
@ -1,4 +1,5 @@
|
||||
(function($){
|
||||
$.concrete('ss', function($){
|
||||
/**
|
||||
* Lightweight wrapper around jQuery UI tabs.
|
||||
* Ensures that anchor links are set properly,
|
||||
@ -6,8 +7,7 @@
|
||||
* their height explicitly set. This is important
|
||||
* for forms inside the CMS layout.
|
||||
*/
|
||||
$('.ss-tabset').concrete('ss', function($){
|
||||
return {
|
||||
$('.ss-tabset').concrete({
|
||||
onmatch: function() {
|
||||
this.rewriteHashlinks();
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
this.tabs({
|
||||
cookie: $.cookie ? { expires: 30, path: '/', name: 'ui-tabs-' + this.attr('id') } : false
|
||||
});
|
||||
|
||||
this._super();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -29,6 +31,6 @@
|
||||
if(href) $(this).attr('href', href);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
@ -342,13 +342,7 @@ class Security extends Controller {
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-ui/ui.core.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-ui/ui.tabs.js');
|
||||
|
||||
// concrete
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.class.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.specifity.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.matches.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.dat.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.concrete.js');
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/dist/jquery.concrete-latest.js');
|
||||
|
||||
Requirements::css(THIRDPARTY_DIR . '/jquery/themes/smoothness/ui.all.css');
|
||||
Requirements::css(THIRDPARTY_DIR . '/jquery/themes/smoothness/ui.tabs.css');
|
||||
|
BIN
thirdparty/jquery-concrete/.DS_Store
vendored
Normal file
4
thirdparty/jquery-concrete/.piston.yml
vendored
@ -1,8 +1,8 @@
|
||||
---
|
||||
format: 1
|
||||
handler:
|
||||
commit: c857ed5d684031115a2bb369f601c7147a2c69bc
|
||||
commit: 488376e8aa3c046cbf60adf43c42c76b5031fe20
|
||||
branch: master
|
||||
lock: false
|
||||
repository_url: git://github.com/hafriedlander/jquery.concrete.git
|
||||
repository_class: Piston::Git::Repository
|
||||
repository_url: git://github.com/hafriedlander/jquery.concrete.git
|
||||
|
68
thirdparty/jquery-concrete/README.textile
vendored
@ -1,8 +1,16 @@
|
||||
h1. Concrete - Support for ConcreteUI programming in jQuery
|
||||
|
||||
A basic desire for jQuery programming is some sort of OO or other organisational method for code. For your consideration,
|
||||
we provide a library for ConcreteUI style programming. In ConcreteUI you attach behavioral code to DOM objects. Concrete extends this
|
||||
concept beyond what is provided by other libraries to provide a very easy to use system with class like, ploymorphic, namespaced properties
|
||||
By Hamish Friedlander, with thanks to "SilverStripe":http://www.silverstripe.com/
|
||||
|
||||
Concrete tries to provide a new model of code organisation - a replacement for Object Oriented programming that is focused on adding functions to groups of DOM elements based on the structure and contents of those DOM elements. It's a merging of the model and view layer that initially seems weird, but can give very powerful results.
|
||||
|
||||
We're standing on the shoulders of giants here - combining ideas from Prototype's behaviour & lowpro and jQuery's effen & livequery (who themselves stole ideals from Self's Morphic UI and others), but extending & combining the concepts presented in those tools to provide a complete alternative to traditional OO concepts - self-aware methods, inheritance, polymorphisim and namespacing without a single class definition.
|
||||
|
||||
h2. Getting Started
|
||||
|
||||
* Walk through the "Tutorial":http://hafriedlander.github.com/jquery.concrete/tutorial/
|
||||
* Watch the "Screencast":http://www.vimeo.com/6353390 (shot during a introductory developer meeting at SilverStripe)
|
||||
* Join the "Google Group":http://groups.google.com/group/jquery-concrete and let us know what you think, or what other features you'd like to see
|
||||
|
||||
h2. Basic use
|
||||
|
||||
@ -226,17 +234,46 @@ And the concrete definitions
|
||||
|
||||
Then doing $('div').bar(); will _not_ display b. Even though the span rule could never match a div, because baz is defined for some rule in the foo namespace, the base namespace will never be checked
|
||||
|
||||
h4. Forcing base
|
||||
h4. Cleaner namespace blocks
|
||||
|
||||
In some situations (such as the last example) you may want to force using the base namespace. In this case you can call concrete without any arguments. For example, if the first definition in the previous example was
|
||||
When declaring a lot of namespaces, you can declare the namespace seperately from the concrete definitions, like so
|
||||
|
||||
<pre><code>
|
||||
$('div').concrete('foo', {
|
||||
bar: function() { this.concrete().baz(); }
|
||||
$.concrete('foo', function($){
|
||||
$('div').concrete({
|
||||
bar: function() { .. }
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
|
||||
Then b _would_ be output to the console. It is up to the developer to decide when they need to be explicit about using the base namespace
|
||||
You can also nest declarations. In this next example, we're defining the functions $().concrete('zap').bar() and $().concrete('zap.pow').baz()
|
||||
|
||||
<pre><code>
|
||||
$.concrete('zap', function($){
|
||||
$('div').concrete({
|
||||
bar: function() { .. }
|
||||
})
|
||||
$.concrete('pow', function($){
|
||||
$('div').concrete({
|
||||
baz: function() { .. }
|
||||
})
|
||||
})
|
||||
})
|
||||
</code></pre>
|
||||
|
||||
h4. Calling to another namespace (and forcing base)
|
||||
|
||||
Inside a namespace, namespace lookups are by default relative to the current namespace.
|
||||
|
||||
In some situations (such as the last example) you may want to force using the base namespace. In this case you can call concrete with the first argument being the base namespace code '.'. For example, if the first definition in the previous example was
|
||||
|
||||
<pre><code>
|
||||
$('div').concrete('foo', {
|
||||
bar: function() { this.concrete('.').baz(); }
|
||||
})
|
||||
</code></pre>
|
||||
|
||||
Then b _would_ be output to the console.
|
||||
|
||||
h4. Using
|
||||
|
||||
@ -252,8 +289,19 @@ Sometimes a block outside of a namespace will need to refer to that namespace re
|
||||
});
|
||||
</code></pre>
|
||||
|
||||
This equivilent to /with/ in javascript, and just like /with/, care should be taken to only use this construct in situations that merit it.
|
||||
|
||||
This equivalent to /with/ in javascript, and just like /with/, care should be taken to only use this construct in situations that merit it.
|
||||
|
||||
h2. License
|
||||
|
||||
Copyright (C) 2009 Hamish Friedlander (hamish@silverstripe.com) and SilverStripe Limited (www.silverstripe.com). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Hamish Friedlander nor SilverStripe nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
|
||||
|
54
thirdparty/jquery-concrete/build.sh
vendored
Executable file
@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
VER=$1
|
||||
|
||||
# Get the version - a tag if possible, otherwise a short ref (not well tested code)
|
||||
if [ "$VER " = " " ] ; then \
|
||||
VER=`git rev-parse --abbrev-ref=strict HEAD`
|
||||
fi
|
||||
if [ "$VER" = "master" ] ; then \
|
||||
VER=`git show --pretty=format:"%h" --quiet`
|
||||
fi
|
||||
|
||||
# Specify the output file's name
|
||||
FILE="dist/jquery.concrete-$VER.js"
|
||||
|
||||
mkdir -p dist
|
||||
rm dist/*.js
|
||||
|
||||
echo "/* jQuery.Concrete - Copyright 2009 Hamish Friedlander and SilverStripe. Version $VER. */" > $FILE
|
||||
|
||||
for x in \
|
||||
vendor/jquery.selector/jquery.class.js \
|
||||
vendor/jquery.selector/jquery.selector.js \
|
||||
vendor/jquery.selector/jquery.selector.specifity.js \
|
||||
vendor/jquery.selector/jquery.selector.matches.js \
|
||||
src/jquery.focusinout.js \
|
||||
src/jquery.concrete.js \
|
||||
src/jquery.concrete.dommaybechanged.js \
|
||||
src/jquery.concrete.events.js \
|
||||
src/jquery.concrete.ctors.js \
|
||||
src/jquery.concrete.properties.js
|
||||
do \
|
||||
echo >> $FILE
|
||||
echo "/* $x */" >> $FILE
|
||||
echo >> $FILE
|
||||
cat $x >> $FILE
|
||||
echo ';' >> $FILE
|
||||
echo >> $FILE
|
||||
done
|
||||
|
||||
ln -s `basename "$FILE"` dist/jquery.concrete-latest.js
|
||||
|
||||
# cp LICENSE /tmp/
|
||||
# cp $FILE /tmp/
|
||||
|
||||
# git checkout dist
|
||||
# mv /tmp/$FILE .
|
||||
# mv /tmp/LICENSE .
|
||||
|
||||
# git add $FILE
|
||||
# git add LICENSE
|
||||
# git commit -m "Update dist to master version $VER"
|
||||
|
||||
# git checkout master
|
1490
thirdparty/jquery-concrete/dist/jquery.concrete-0.9.js
vendored
Normal file
@ -0,0 +1,1490 @@
|
||||
/* jQuery.Concrete - Copyright 2009 Hamish Friedlander and SilverStripe. Version 0.9. */
|
||||
|
||||
/* vendor/jquery.selector/jquery.class.js */
|
||||
|
||||
/**
|
||||
* Very basic Class utility. Based on base and jquery.class.
|
||||
*
|
||||
* Class definition: var Foo = Base.extend({ init: function(){ Constructor }; method_name: function(){ Method } });
|
||||
*
|
||||
* Inheritance: var Bar = Foo.extend({ method_name: function(){ this._super(); } });
|
||||
*
|
||||
* new-less Constructor: new Foo(arg) <-same as-> Foo(arg)
|
||||
*/
|
||||
|
||||
var Base;
|
||||
|
||||
(function(){
|
||||
|
||||
var marker = {}, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
||||
|
||||
// The base Class implementation (does nothing)
|
||||
Base = function(){};
|
||||
|
||||
Base.addMethod = function(name, func) {
|
||||
var _super = this._super;
|
||||
if (_super && fnTest.test(func)) {
|
||||
this.prototype[name] = function(){
|
||||
var tmp = this._super;
|
||||
this._super = _super[name];
|
||||
try {
|
||||
var ret = func.apply(this, arguments);
|
||||
}
|
||||
finally {
|
||||
this._super = tmp;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else this.prototype[name] = func;
|
||||
}
|
||||
|
||||
Base.addMethods = function(props) {
|
||||
for (var name in props) {
|
||||
if (typeof props[name] == 'function') this.addMethod(name, props[name]);
|
||||
else this.prototype[name] = props[name];
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new Class that inherits from this class
|
||||
Base.extend = function(props) {
|
||||
|
||||
// The dummy class constructor
|
||||
var Kls = function() {
|
||||
if (arguments[0] === marker) return;
|
||||
|
||||
if (this instanceof Kls) {
|
||||
if (this.init) this.init.apply(this, arguments);
|
||||
}
|
||||
else {
|
||||
var ret = new Kls(marker); if (ret.init) ret.init.apply(ret, arguments); return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the common class variables and methods
|
||||
Kls.constructor = Kls;
|
||||
Kls.extend = Base.extend;
|
||||
Kls.addMethod = Base.addMethod;
|
||||
Kls.addMethods = Base.addMethods;
|
||||
Kls._super = this.prototype;
|
||||
|
||||
// Attach the parent object to the inheritance chain
|
||||
Kls.prototype = new this(marker);
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
Kls.addMethods(props);
|
||||
|
||||
return Kls;
|
||||
};
|
||||
})();;
|
||||
|
||||
|
||||
/* vendor/jquery.selector/jquery.selector.js */
|
||||
|
||||
(function($){
|
||||
|
||||
var tokens = {
|
||||
UNICODE: /\\[0-9a-f]{1,6}(?:\r\n|[ \n\r\t\f])?/,
|
||||
ESCAPE: /(?:UNICODE)|\\[^\n\r\f0-9a-f]/,
|
||||
NONASCII: /[^\x00-\x7F]/,
|
||||
NMSTART: /[_a-z]|(?:NONASCII)|(?:ESCAPE)/,
|
||||
NMCHAR: /[_a-z0-9-]|(?:NONASCII)|(?:ESCAPE)/,
|
||||
IDENT: /-?(?:NMSTART)(?:NMCHAR)*/,
|
||||
|
||||
NL: /\n|\r\n|\r|\f/,
|
||||
|
||||
STRING: /(?:STRING1)|(?:STRING2)|(?:STRINGBARE)/,
|
||||
STRING1: /"(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\"])*"/,
|
||||
STRING2: /'(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\'])*'/,
|
||||
STRINGBARE: /(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\]])*/,
|
||||
|
||||
FUNCTION: /(?:IDENT)\(\)/,
|
||||
|
||||
INTEGER: /[0-9]+/,
|
||||
|
||||
WITHN: /([-+])?(INTEGER)?(n)\s*(?:([-+])\s*(INTEGER))?/,
|
||||
WITHOUTN: /([-+])?(INTEGER)/
|
||||
}
|
||||
|
||||
var rx = {
|
||||
not: /:not\(/,
|
||||
not_end: /\)/,
|
||||
|
||||
tag: /((?:IDENT)|\*)/,
|
||||
id: /#(IDENT)/,
|
||||
cls: /\.(IDENT)/,
|
||||
attr: /\[\s*(IDENT)\s*(?:([^=]?=)\s*(STRING)\s*)?\]/,
|
||||
pseudo_el: /(?::(first-line|first-letter|before|after))|(?:::((?:FUNCTION)|(?:IDENT)))/,
|
||||
pseudo_cls_nth: /:nth-child\(\s*(?:(?:WITHN)|(?:WITHOUTN)|(odd|even))\s*\)/,
|
||||
pseudo_cls: /:(IDENT)/,
|
||||
|
||||
comb: /\s*(\+|~|>)\s*|\s+/,
|
||||
comma: /\s*,\s*/,
|
||||
important: /\s+!important\s*$/
|
||||
}
|
||||
|
||||
/* Replace placeholders with actual regex, and mark all as case insensitive */
|
||||
var token = /[A-Z][A-Z0-9]+/;
|
||||
for (var k in rx) {
|
||||
var src = rx[k].source;
|
||||
while (m = src.match(token)) src = src.replace(m[0], tokens[m[0]].source);
|
||||
rx[k] = new RegExp(src, 'gi');
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that matches itself against regexii, and keeps track of how much of itself has been matched
|
||||
*/
|
||||
var ConsumableString = Base.extend({
|
||||
init: function(str) {
|
||||
this.str = str;
|
||||
this.pos = 0;
|
||||
},
|
||||
match: function(rx) {
|
||||
var m;
|
||||
rx.lastIndex = this.pos;
|
||||
if ((m = rx.exec(this.str)) && m.index == this.pos ) {
|
||||
this.pos = rx.lastIndex ? rx.lastIndex : this.str.length ;
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
peek: function(rx) {
|
||||
var m;
|
||||
rx.lastIndex = this.pos;
|
||||
if ((m = rx.exec(this.str)) && m.index == this.pos ) return m;
|
||||
return null;
|
||||
},
|
||||
showpos: function() {
|
||||
return this.str.slice(0,this.pos)+'<HERE>' + this.str.slice(this.pos);
|
||||
},
|
||||
done: function() {
|
||||
return this.pos == this.str.length;
|
||||
}
|
||||
})
|
||||
|
||||
/* A base class that all Selectors inherit off */
|
||||
var SelectorBase = Base.extend({});
|
||||
|
||||
/**
|
||||
* A class representing a Simple Selector, as per the CSS3 selector spec
|
||||
*/
|
||||
var SimpleSelector = SelectorBase.extend({
|
||||
init: function() {
|
||||
this.tag = null;
|
||||
this.id = null;
|
||||
this.classes = [];
|
||||
this.attrs = [];
|
||||
this.nots = [];
|
||||
this.pseudo_classes = [];
|
||||
this.pseudo_els = [];
|
||||
},
|
||||
parse: function(selector) {
|
||||
var m;
|
||||
|
||||
/* Pull out the initial tag first, if there is one */
|
||||
if (m = selector.match(rx.tag)) this.tag = m[1];
|
||||
|
||||
/* Then for each selection type, try and find a match */
|
||||
do {
|
||||
if (m = selector.match(rx.not)) {
|
||||
this.nots[this.nots.length] = SelectorsGroup().parse(selector)
|
||||
if (!(m = selector.match(rx.not_end))) {
|
||||
throw 'Invalid :not term in selector';
|
||||
}
|
||||
}
|
||||
else if (m = selector.match(rx.id)) this.id = m[1];
|
||||
else if (m = selector.match(rx.cls)) this.classes[this.classes.length] = m[1];
|
||||
else if (m = selector.match(rx.attr)) this.attrs[this.attrs.length] = [ m[1], m[2], m[3] ];
|
||||
else if (m = selector.match(rx.pseudo_el)) this.pseudo_els[this.pseudo_els.length] = m[1] || m[2];
|
||||
else if (m = selector.match(rx.pseudo_cls_nth)) {
|
||||
if (m[3]) {
|
||||
var a = parseInt((m[1]||'')+(m[2]||'1'));
|
||||
var b = parseInt((m[4]||'')+(m[5]||'0'));
|
||||
}
|
||||
else {
|
||||
var a = m[8] ? 2 : 0;
|
||||
var b = m[8] ? (4-m[8].length) : parseInt((m[6]||'')+m[7]);
|
||||
}
|
||||
this.pseudo_classes[this.pseudo_classes.length] = ['nth-child', [a, b]];
|
||||
}
|
||||
else if (m = selector.match(rx.pseudo_cls)) this.pseudo_classes[this.pseudo_classes.length] = [m[1]];
|
||||
|
||||
} while(m && !selector.done());
|
||||
|
||||
return this;
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* A class representing a Selector, as per the CSS3 selector spec
|
||||
*/
|
||||
var Selector = SelectorBase.extend({
|
||||
init: function(){
|
||||
this.parts = [];
|
||||
},
|
||||
parse: function(cons){
|
||||
this.parts[this.parts.length] = SimpleSelector().parse(cons);
|
||||
|
||||
while (!cons.done() && !cons.peek(rx.comma) && (m = cons.match(rx.comb))) {
|
||||
this.parts[this.parts.length] = m[1] || ' ';
|
||||
this.parts[this.parts.length] = SimpleSelector().parse(cons);
|
||||
}
|
||||
|
||||
return this.parts.length == 1 ? this.parts[0] : this;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A class representing a sequence of selectors, as per the CSS3 selector spec
|
||||
*/
|
||||
var SelectorsGroup = SelectorBase.extend({
|
||||
init: function(){
|
||||
this.parts = [];
|
||||
},
|
||||
parse: function(cons){
|
||||
this.parts[this.parts.length] = Selector().parse(cons);
|
||||
|
||||
while (!cons.done() && (m = cons.match(rx.comma))) {
|
||||
this.parts[this.parts.length] = Selector().parse(cons);
|
||||
}
|
||||
|
||||
return this.parts.length == 1 ? this.parts[0] : this;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$.selector = function(s){
|
||||
var cons = ConsumableString(s);
|
||||
var res = SelectorsGroup().parse(cons);
|
||||
|
||||
res.selector = s;
|
||||
|
||||
if (!cons.done()) throw 'Could not parse selector - ' + cons.showpos() ;
|
||||
else return res;
|
||||
}
|
||||
|
||||
$.selector.SelectorBase = SelectorBase;
|
||||
$.selector.SimpleSelector = SimpleSelector;
|
||||
$.selector.Selector = Selector;
|
||||
$.selector.SelectorsGroup = SelectorsGroup;
|
||||
|
||||
})(jQuery)
|
||||
;
|
||||
|
||||
|
||||
/* vendor/jquery.selector/jquery.selector.specifity.js */
|
||||
|
||||
(function($) {
|
||||
|
||||
$.selector.SimpleSelector.addMethod('specifity', function() {
|
||||
if (this.spec) return this.spec;
|
||||
|
||||
var spec = [
|
||||
this.id ? 1 : 0,
|
||||
this.classes.length + this.attrs.length + this.pseudo_classes.length,
|
||||
((this.tag && this.tag != '*') ? 1 : 0) + this.pseudo_els.length
|
||||
];
|
||||
$.each(this.nots, function(i,not){
|
||||
var ns = not.specifity(); spec[0] += ns[0]; spec[1] += ns[1]; spec[2] += ns[2];
|
||||
});
|
||||
|
||||
return this.spec = spec;
|
||||
})
|
||||
|
||||
$.selector.Selector.addMethod('specifity', function(){
|
||||
if (this.spec) return this.spec;
|
||||
|
||||
var spec = [0,0,0];
|
||||
$.each(this.parts, function(i,part){
|
||||
if (i%2) return;
|
||||
var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2];
|
||||
});
|
||||
|
||||
return this.spec = spec;
|
||||
})
|
||||
|
||||
$.selector.SelectorsGroup.addMethod('specifity', function(){
|
||||
if (this.spec) return this.spec;
|
||||
|
||||
var spec = [0,0,0];
|
||||
$.each(this.parts, function(i,part){
|
||||
var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2];
|
||||
});
|
||||
|
||||
return this.spec = spec;
|
||||
})
|
||||
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
||||
|
||||
/* vendor/jquery.selector/jquery.selector.matches.js */
|
||||
|
||||
/*
|
||||
This attempts to do the opposite of Sizzle.
|
||||
Sizzle is good for finding elements for a selector, but not so good for telling if an individual element matches a selector
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
/**** CAPABILITY TESTS ****/
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = '<form id="test"><input name="id" type="text"/></form>';
|
||||
|
||||
// In IE 6-7, getAttribute often does the wrong thing (returns similar to el.attr), so we need to use getAttributeNode on that browser
|
||||
var getAttributeDodgy = div.firstChild.getAttribute('id') !== 'test';
|
||||
|
||||
// Does browser support Element.firstElementChild, Element.previousElementSibling, etc.
|
||||
var hasElementTraversal = div.firstElementChild && div.firstElementChild.tagName == 'FORM';
|
||||
|
||||
// Does browser support Element.children
|
||||
var hasChildren = div.children && div.children[0].tagName == 'FORM';
|
||||
|
||||
var FUNC_IN = /^\s*function\s*\([^)]*\)\s*{/;
|
||||
var FUNC_OUT = /}\s*$/;
|
||||
|
||||
var funcToString = function(f) {
|
||||
return (''+f).replace(FUNC_IN,'').replace(FUNC_OUT,'');
|
||||
}
|
||||
|
||||
// Can we use Function#toString ?
|
||||
try {
|
||||
var testFunc = function(){ return 'good' };
|
||||
if ((new Function('',funcToString(testFunc)))() != 'good') funcToString = false;
|
||||
}
|
||||
catch(e) { funcToString = false; console.log(e.message);/*pass*/ }
|
||||
|
||||
/**** INTRO ****/
|
||||
|
||||
var GOOD = /GOOD/g;
|
||||
var BAD = /BAD/g;
|
||||
|
||||
var STARTS_WITH_QUOTES = /^['"]/g;
|
||||
|
||||
var join = function(js) {
|
||||
return js.join('\n');
|
||||
}
|
||||
|
||||
var join_complex = function(js) {
|
||||
code = new String(js.join('\n')); // String objects can have properties set. strings can't
|
||||
code.complex = true;
|
||||
return code;
|
||||
}
|
||||
|
||||
/**** ATTRIBUTE ACCESSORS ****/
|
||||
|
||||
var getAttr;
|
||||
|
||||
// Good browsers
|
||||
if (!getAttributeDodgy) {
|
||||
getAttr = function(attr){ return 'var _'+attr+' = el.getAttribute("'+attr+'");' ; }
|
||||
}
|
||||
// IE 6, 7
|
||||
else {
|
||||
// On IE 6 + 7, getAttribute still has to be called with DOM property mirror name, not attribute name. Map attributes to those names
|
||||
var getAttrIEMap = { 'class': 'className', 'for': 'htmlFor' };
|
||||
|
||||
getAttr = function(attr) {
|
||||
var ieattr = getAttrIEMap[attr] || attr;
|
||||
return 'var _'+attr+' = el.getAttribute("'+ieattr+'",2) || (el.getAttributeNode("'+attr+'")||{}).nodeValue;';
|
||||
}
|
||||
}
|
||||
|
||||
/**** ATTRIBUTE COMPARITORS ****/
|
||||
|
||||
var attrchecks = {
|
||||
'-': '!_K',
|
||||
'=': '_K != "V"',
|
||||
'!=': '_K == "V"',
|
||||
'~=': '__K.indexOf(" V ") == -1',
|
||||
'^=': '!_K || _K.indexOf("V") != 0',
|
||||
'*=': '!_K || _K.indexOf("V") == -1',
|
||||
'$=': '!_K || _K.substr(_K.length-"V".length) != "V"'
|
||||
}
|
||||
|
||||
/**** STATE TRACKER ****/
|
||||
|
||||
var State = $.selector.State = Base.extend({
|
||||
init: function(){
|
||||
this.reset();
|
||||
},
|
||||
reset: function() {
|
||||
this.attrs = {}; this.wsattrs = {};
|
||||
},
|
||||
|
||||
prev: function(){
|
||||
this.reset();
|
||||
if (hasElementTraversal) return 'el = el.previousElementSibling';
|
||||
return 'while((el = el.previousSibling) && el.nodeType != 1) {}';
|
||||
},
|
||||
next: function() {
|
||||
this.reset();
|
||||
if (hasElementTraversal) return 'el = el.nextElementSibling';
|
||||
return 'while((el = el.nextSibling) && el.nodeType != 1) {}';
|
||||
},
|
||||
prevLoop: function(body){
|
||||
this.reset();
|
||||
if (hasElementTraversal) return join([ 'while(el = el.previousElementSibling){', body]);
|
||||
return join([
|
||||
'while(el = el.previousSibling){',
|
||||
'if (el.nodeType != 1) continue;',
|
||||
body,
|
||||
]);
|
||||
},
|
||||
parent: function() {
|
||||
this.reset();
|
||||
return 'el = el.parentNode;';
|
||||
},
|
||||
parentLoop: function(body) {
|
||||
this.reset();
|
||||
return join([
|
||||
'while((el = el.parentNode) && el.nodeType == 1){',
|
||||
body,
|
||||
'}'
|
||||
]);
|
||||
},
|
||||
|
||||
uses_attr: function(attr) {
|
||||
if (this.attrs[attr]) return;
|
||||
this.attrs[attr] = true;
|
||||
return getAttr(attr);
|
||||
},
|
||||
uses_wsattr: function(attr) {
|
||||
if (this.wsattrs[attr]) return;
|
||||
this.wsattrs[attr] = true;
|
||||
return join([this.uses_attr(attr), 'var __'+attr+' = " "+_'+attr+'+" ";']);
|
||||
},
|
||||
|
||||
save: function(lbl) {
|
||||
return 'var el'+lbl+' = el;';
|
||||
},
|
||||
restore: function(lbl) {
|
||||
this.reset();
|
||||
return 'el = el'+lbl+';';
|
||||
}
|
||||
});
|
||||
|
||||
/**** PSEUDO-CLASS DETAILS ****/
|
||||
|
||||
var pseudoclschecks = {
|
||||
'first-child': join([
|
||||
'var cel = el;',
|
||||
'while(cel = cel.previousSibling){ if (cel.nodeType === 1) BAD; }',
|
||||
]),
|
||||
'last-child': join([
|
||||
'var cel = el;',
|
||||
'while(cel = cel.nextSibling){ if (cel.nodeType === 1) BAD; }'
|
||||
]),
|
||||
'nth-child': function(a,b) {
|
||||
var get_i = join([
|
||||
'var i = 1, cel = el;',
|
||||
'while(cel = cel.previousSibling){',
|
||||
'if (cel.nodeType === 1) i++;',
|
||||
'}',
|
||||
]);
|
||||
|
||||
if (a == 0) return join([
|
||||
get_i,
|
||||
'if (i- '+b+' != 0) BAD;'
|
||||
]);
|
||||
else if (b == 0 && a >= 0) return join([
|
||||
get_i,
|
||||
'if (i%'+a+' != 0 || i/'+a+' < 0) BAD;'
|
||||
]);
|
||||
else if (b == 0 && a < 0) return join([
|
||||
'BAD;'
|
||||
]);
|
||||
else return join([
|
||||
get_i,
|
||||
'if ((i- '+b+')%'+a+' != 0 || (i- '+b+')/'+a+' < 0) BAD;'
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
// Needs to refence contents of object, so must be injected after definition
|
||||
pseudoclschecks['only-child'] = join([
|
||||
pseudoclschecks['first-child'],
|
||||
pseudoclschecks['last-child']
|
||||
]);
|
||||
|
||||
/**** SimpleSelector ****/
|
||||
|
||||
$.selector.SimpleSelector.addMethod('compile', function(el) {
|
||||
var js = [];
|
||||
|
||||
/* Check against element name */
|
||||
if (this.tag && this.tag != '*') {
|
||||
js[js.length] = 'if (el.tagName != "'+this.tag.toUpperCase()+'") BAD;';
|
||||
}
|
||||
|
||||
/* Check against ID */
|
||||
if (this.id) {
|
||||
js[js.length] = el.uses_attr('id');
|
||||
js[js.length] = 'if (_id !== "'+this.id+'") BAD;';
|
||||
}
|
||||
|
||||
/* Build className checking variable */
|
||||
if (this.classes.length) {
|
||||
js[js.length] = el.uses_wsattr('class');
|
||||
|
||||
/* Check against class names */
|
||||
$.each(this.classes, function(i, cls){
|
||||
js[js.length] = 'if (__class.indexOf(" '+cls+' ") == -1) BAD;';
|
||||
})
|
||||
}
|
||||
|
||||
/* Check against attributes */
|
||||
$.each(this.attrs, function(i, attr){
|
||||
js[js.length] = (attr[1] == '~=') ? el.uses_wsattr(attr[0]) : el.uses_attr(attr[0]);
|
||||
var check = attrchecks[ attr[1] || '-' ];
|
||||
check = check.replace( /K/g, attr[0]).replace( /V/g, attr[2] && attr[2].match(STARTS_WITH_QUOTES) ? attr[2].slice(1,-1) : attr[2] );
|
||||
js[js.length] = 'if ('+check+') BAD;';
|
||||
});
|
||||
|
||||
/* Check against nots */
|
||||
$.each(this.nots, function(i, not){
|
||||
var lbl = ++lbl_id;
|
||||
var func = join([
|
||||
'l'+lbl+':{',
|
||||
not.compile(el).replace(BAD, 'break l'+lbl).replace(GOOD, 'BAD'),
|
||||
'}'
|
||||
]);
|
||||
|
||||
if (!(not instanceof $.selector.SimpleSelector)) func = join([
|
||||
el.save(lbl),
|
||||
func,
|
||||
el.restore(lbl)
|
||||
])
|
||||
|
||||
js[js.length] = func;
|
||||
});
|
||||
|
||||
/* Check against pseudo-classes */
|
||||
$.each(this.pseudo_classes, function(i, pscls){
|
||||
var check = pseudoclschecks[pscls[0]];
|
||||
if (check) {
|
||||
js[js.length] = ( typeof check == 'function' ? check.apply(this, pscls[1]) : check );
|
||||
}
|
||||
else if (check = $.find.selectors.filters[pscls[0]]) {
|
||||
if (funcToString) {
|
||||
js[js.length] = funcToString(check).replace(/elem/g,'el').replace(/return([^;]+);/,'if (!($1)) BAD;');
|
||||
}
|
||||
else {
|
||||
js[js.length] = 'if (!$.find.selectors.filters.'+pscls[0]+'(el)) BAD;'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
js[js.length] = 'GOOD';
|
||||
|
||||
/* Pass */
|
||||
return join(js);
|
||||
});
|
||||
|
||||
var lbl_id = 0;
|
||||
/** Turns an compiled fragment into the first part of a combination */
|
||||
function as_subexpr(f) {
|
||||
if (f.complex)
|
||||
return join([
|
||||
'l'+(++lbl_id)+':{',
|
||||
f.replace(GOOD, 'break l'+lbl_id),
|
||||
'}',
|
||||
]);
|
||||
else
|
||||
return f.replace(GOOD, '');
|
||||
}
|
||||
|
||||
var combines = {
|
||||
' ': function(el, f1, f2) {
|
||||
return join_complex([
|
||||
f2,
|
||||
'while(true){',
|
||||
el.parent(),
|
||||
'if (!el || el.nodeType !== 1) BAD;',
|
||||
f1.compile(el).replace(BAD, 'continue'),
|
||||
'}'
|
||||
]);
|
||||
},
|
||||
|
||||
'>': function(el, f1, f2) {
|
||||
return join([
|
||||
f2,
|
||||
el.parent(),
|
||||
'if (!el || el.nodeType !== 1) BAD;',
|
||||
f1.compile(el)
|
||||
]);
|
||||
},
|
||||
|
||||
'~': function(el, f1, f2) {
|
||||
return join_complex([
|
||||
f2,
|
||||
el.prevLoop(),
|
||||
f1.compile(el).replace(BAD, 'continue'),
|
||||
'}',
|
||||
'BAD;'
|
||||
]);
|
||||
},
|
||||
|
||||
'+': function(el, f1, f2) {
|
||||
return join([
|
||||
f2,
|
||||
el.prev(),
|
||||
'if (!el) BAD;',
|
||||
f1.compile(el)
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
$.selector.Selector.addMethod('compile', function(el) {
|
||||
l = this.parts.length;
|
||||
|
||||
expr = this.parts[--l].compile(el);
|
||||
while (l) {
|
||||
combinator = this.parts[--l];
|
||||
expr = combines[combinator](el, this.parts[--l], as_subexpr(expr));
|
||||
}
|
||||
|
||||
return expr;
|
||||
});
|
||||
|
||||
$.selector.SelectorsGroup.addMethod('compile', function(el) {
|
||||
var expr = [], lbl = ++lbl_id;
|
||||
|
||||
for (var i=0; i < this.parts.length; i++) {
|
||||
expr[expr.length] = join([
|
||||
i == 0 ? el.save(lbl) : el.restore(lbl),
|
||||
'l'+lbl+'_'+i+':{',
|
||||
this.parts[i].compile(el).replace(BAD, 'break l'+lbl+'_'+i),
|
||||
'}'
|
||||
]);
|
||||
}
|
||||
|
||||
expr[expr.length] = 'BAD;';
|
||||
return join(expr);
|
||||
});
|
||||
|
||||
$.selector.SelectorBase.addMethod('matches', function(el){
|
||||
this.matches = new Function('el', join([
|
||||
'if (!el) return false;',
|
||||
this.compile(new State()).replace(BAD, 'return false').replace(GOOD, 'return true')
|
||||
]));
|
||||
return this.matches(el);
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
||||
;
|
||||
|
||||
|
||||
/* src/jquery.focusinout.js */
|
||||
|
||||
(function($){
|
||||
|
||||
/**
|
||||
* Add focusin and focusout support to bind and live for browers other than IE. Designed to be usable in a delegated fashion (like $.live)
|
||||
* Copyright (c) 2007 Jörn Zaefferer
|
||||
*/
|
||||
$.support.focusInOut = !!($.browser.msie);
|
||||
if (!$.support.focusInOut) {
|
||||
// Emulate focusin and focusout by binding focus and blur in capturing mode
|
||||
$.each({focus: 'focusin', blur: 'focusout'}, function(original, fix){
|
||||
$.event.special[fix] = {
|
||||
setup: function(){
|
||||
if (!this.addEventListener) return false;
|
||||
this.addEventListener(original, $.event.special[fix].handler, true);
|
||||
},
|
||||
teardown: function(){
|
||||
if (!this.removeEventListener) return false;
|
||||
this.removeEventListener(original, $.event.special[fix].handler, true);
|
||||
},
|
||||
handler: function(e){
|
||||
arguments[0] = $.event.fix(e);
|
||||
arguments[0].type = fix;
|
||||
return $.event.handle.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
(function(){
|
||||
//IE has some trouble with focusout with select and keyboard navigation
|
||||
var activeFocus = null;
|
||||
|
||||
$(document)
|
||||
.bind('focusin', function(e){
|
||||
var target = e.realTarget || e.target;
|
||||
if (activeFocus && activeFocus !== target) {
|
||||
e.type = 'focusout';
|
||||
$(activeFocus).trigger(e);
|
||||
e.type = 'focusin';
|
||||
e.target = target;
|
||||
}
|
||||
activeFocus = target;
|
||||
})
|
||||
.bind('focusout', function(e){
|
||||
activeFocus = null;
|
||||
});
|
||||
})();
|
||||
|
||||
})(jQuery);;
|
||||
|
||||
|
||||
/* src/jquery.concrete.js */
|
||||
|
||||
var console;
|
||||
|
||||
(function($) {
|
||||
|
||||
var namespaces = {};
|
||||
|
||||
$.concrete = function() {
|
||||
$.fn.concrete.apply(null, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* A couple of utility functions for accessing the store outside of this closure, and for making things
|
||||
* operate in a little more easy-to-test manner
|
||||
*/
|
||||
$.extend($.concrete, {
|
||||
/**
|
||||
* Get all the namespaces. Useful for introspection? Internal interface of Namespace not guaranteed consistant
|
||||
*/
|
||||
namespaces: namespaces,
|
||||
|
||||
/**
|
||||
* Remove all concrete rules
|
||||
*/
|
||||
clear_all_rules: function() {
|
||||
// Remove proxy functions
|
||||
for (var k in $.fn) { if ($.fn[k].concrete) delete $.fn[k] ; }
|
||||
// Remove namespaces, and start over again
|
||||
namespaces = $.concrete.namespaces = {};
|
||||
},
|
||||
|
||||
WARN_LEVEL_NONE: 0,
|
||||
WARN_LEVEL_IMPORTANT: 1,
|
||||
WARN_LEVEL_BESTPRACTISE: 2,
|
||||
|
||||
/**
|
||||
* Warning level. Set to a higher level to get warnings dumped to console.
|
||||
*/
|
||||
warningLevel: 0,
|
||||
|
||||
/** Utility to optionally display warning messages depending on level */
|
||||
warn: function(message, level) {
|
||||
if (level <= $.concrete.warningLevel && console && console.log) {
|
||||
console.warn(message);
|
||||
if (console.trace) console.trace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/** Stores a count of definitions, so that we can sort identical selectors by definition order */
|
||||
var rulecount = 0;
|
||||
|
||||
var Rule = Base.extend({
|
||||
init: function(selector, name) {
|
||||
this.selector = selector;
|
||||
this.specifity = selector.specifity();
|
||||
this.important = 0;
|
||||
this.name = name;
|
||||
this.rulecount = rulecount++;
|
||||
}
|
||||
});
|
||||
|
||||
Rule.compare = function(a, b) {
|
||||
var as = a.specifity, bs = b.specifity;
|
||||
|
||||
return (a.important - b.important) ||
|
||||
(as[0] - bs[0]) ||
|
||||
(as[1] - bs[1]) ||
|
||||
(as[2] - bs[2]) ||
|
||||
(a.rulecount - b.rulecount) ;
|
||||
}
|
||||
|
||||
$.concrete.RuleList = function() {
|
||||
var list = [];
|
||||
|
||||
list.addRule = function(selector, name){
|
||||
var rule = Rule(selector, name);
|
||||
|
||||
list[list.length] = rule;
|
||||
list.sort(Rule.compare);
|
||||
|
||||
return rule;
|
||||
};
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
var handlers = [];
|
||||
|
||||
/**
|
||||
* A Namespace holds all the information needed for adding concrete methods to a namespace (including the _null_ namespace)
|
||||
*/
|
||||
$.concrete.Namespace = Base.extend({
|
||||
init: function(name){
|
||||
if (name && !name.match(/^[A-Za-z0-9.]+$/)) $.concrete.warn('Concrete namespace '+name+' is not formatted as period seperated identifiers', $.concrete.WARN_LEVEL_BESTPRACTISE);
|
||||
name = name || '__base';
|
||||
|
||||
this.name = name;
|
||||
this.store = {};
|
||||
|
||||
namespaces[name] = this;
|
||||
|
||||
if (name == "__base") {
|
||||
this.injectee = $.fn
|
||||
this.$ = $;
|
||||
}
|
||||
else {
|
||||
// We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into
|
||||
var subfn = function(){}
|
||||
this.injectee = subfn.prototype = new $();
|
||||
|
||||
// And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building
|
||||
var bound$ = this.$ = function(a) {
|
||||
// Try the simple way first
|
||||
var jq = $.fn.init.apply(new subfn(), arguments);
|
||||
if (jq instanceof subfn) return jq;
|
||||
|
||||
// That didn't return a bound object, so now we need to copy it
|
||||
var rv = new subfn();
|
||||
rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length;
|
||||
while (i--) rv[i] = jq[i];
|
||||
return rv;
|
||||
}
|
||||
this.injectee.pushStack = function(elems, name, selector){
|
||||
var ret = bound$(elems);
|
||||
|
||||
// Add the old object onto the stack (as a reference)
|
||||
ret.prevObject = this;
|
||||
ret.context = this.context;
|
||||
|
||||
if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector;
|
||||
else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")";
|
||||
|
||||
// Return the newly-formed element set
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Copy static functions through from $ to this.$ so e.g. $.ajax still works
|
||||
// @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through
|
||||
$.extend(this.$, $);
|
||||
|
||||
// We override concrete to inject the name of this namespace when defining blocks inside this namespace
|
||||
var concrete_wrapper = this.injectee.concrete = function(spacename) {
|
||||
var args = arguments;
|
||||
|
||||
if (!spacename || typeof spacename != 'string') { args = $.makeArray(args); args.unshift(name); }
|
||||
else if (spacename.charAt(0) != '.') args[0] = name+'.'+spacename;
|
||||
|
||||
return $.fn.concrete.apply(this, args);
|
||||
}
|
||||
|
||||
this.$.concrete = function() {
|
||||
concrete_wrapper.apply(null, arguments);
|
||||
}
|
||||
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
var handler = handlers[i], builder;
|
||||
|
||||
// Inject jQuery object method overrides
|
||||
if (builder = handler.namespaceMethodOverrides) {
|
||||
var overrides = builder(this);
|
||||
for (var k in overrides) this.injectee[k] = overrides[k];
|
||||
}
|
||||
|
||||
// Inject $.concrete function overrides
|
||||
if (builder = handler.namespaceStaticOverrides) {
|
||||
var overrides = builder(this);
|
||||
for (var k in overrides) this.$.concrete[k] = overrides[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a function that does selector matching against the function list for a function name
|
||||
* Used by proxy for all calls, and by ctorProxy to handle _super calls
|
||||
* @param {String} name - name of the function as passed in the construction object
|
||||
* @param {String} funcprop - the property on the Rule object that gives the actual function to call
|
||||
*/
|
||||
one: function(name, funcprop) {
|
||||
var namespace = this;
|
||||
var funcs = this.store[name];
|
||||
|
||||
var one = function(el, args, i){
|
||||
if (i === undefined) i = funcs.length;
|
||||
while (i--) {
|
||||
if (funcs[i].selector.matches(el)) {
|
||||
var ret, tmp_i = el.i, tmp_f = el.f;
|
||||
el.i = i; el.f = one;
|
||||
try { ret = funcs[i][funcprop].apply(namespace.$(el), args); }
|
||||
finally { el.i = tmp_i; el.f = tmp_f; }
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return one;
|
||||
},
|
||||
|
||||
/**
|
||||
* A proxy is a function attached to a callable object (either the base jQuery.fn or a subspace object) which handles
|
||||
* finding and calling the correct function for each member of the current jQuery context
|
||||
* @param {String} name - name of the function as passed in the construction object
|
||||
*/
|
||||
build_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function() {
|
||||
var rv, ctx = $(this);
|
||||
|
||||
var i = ctx.length;
|
||||
while (i--) rv = one(ctx[i], arguments);
|
||||
return rv;
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
bind_proxy: function(selector, name, func) {
|
||||
var rulelist = this.store[name] || (this.store[name] = $.concrete.RuleList());
|
||||
|
||||
var rule = rulelist.addRule(selector, name); rule.func = func;
|
||||
|
||||
if (!this.injectee.hasOwnProperty(name)) {
|
||||
this.injectee[name] = this.build_proxy(name);
|
||||
this.injectee[name].concrete = true;
|
||||
}
|
||||
|
||||
if (!this.injectee[name].concrete) {
|
||||
$.concrete.warn('Warning: Concrete function '+name+' clashes with regular jQuery function - concrete function will not be callable directly on jQuery object', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
},
|
||||
|
||||
add: function(selector, data) {
|
||||
// For every item in the hash, try ever method handler, until one returns true
|
||||
for (var k in data) {
|
||||
var v = data[k];
|
||||
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
if (handlers[i].bind && handlers[i].bind.call(this, selector, k, v)) break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
has: function(ctx, name) {
|
||||
var rulelist = this.store[name];
|
||||
if (!rulelist) return false;
|
||||
|
||||
/* We go forward this time, since low specifity is likely to knock out a bunch of elements quickly */
|
||||
for (var i = 0 ; i < rulelist.length; i++) {
|
||||
ctx = ctx.not(rulelist[i].selector);
|
||||
if (!ctx.length) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* The default handlers provided (and included by default) are event, ctor and properties
|
||||
*/
|
||||
$.concrete.Namespace.addHandler = function(handler) {
|
||||
for (var i = 0; i < handlers.length && handlers[i].order < handler.order; i++) { /* Pass */ }
|
||||
handlers.splice(i, 0, handler);
|
||||
}
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 50,
|
||||
|
||||
bind: function(selector, k, v){
|
||||
if ($.isFunction(v)) {
|
||||
this.bind_proxy(selector, k, v);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.extend($.fn, {
|
||||
/**
|
||||
* Main concrete function. Used for new definitions, calling into a namespace (or forcing the base namespace) and entering a using block
|
||||
*
|
||||
*/
|
||||
concrete: function(spacename) {
|
||||
var i = 0;
|
||||
var selector = this.selector ? $.selector(this.selector) : null;
|
||||
|
||||
/* By default we operator on the base namespace */
|
||||
var namespace = namespaces.__base || $.concrete.Namespace();
|
||||
|
||||
/* If the first argument is a string, then it's the name of a namespace. Look it up */
|
||||
if (typeof spacename == 'string') {
|
||||
if (spacename.charAt('0') == '.') spacename = spacename.substr(1);
|
||||
if (spacename) namespace = namespaces[spacename] || $.concrete.Namespace(spacename);
|
||||
i=1;
|
||||
}
|
||||
|
||||
/* All remaining arguments should either be using blocks or definition hashs */
|
||||
while (i < arguments.length) {
|
||||
var res = arguments[i++];
|
||||
|
||||
// If it's a function, call it - either it's a using block or it's a namespaced concrete definition
|
||||
if ($.isFunction(res)) {
|
||||
if (res.length != 1) $.concrete.warn('Function block inside concrete definition does not take $ argument properly', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
res = res.call(namespace.$(this), namespace.$);
|
||||
}
|
||||
|
||||
// If we have a concrete definition hash, inject it into namespace
|
||||
if (res) {
|
||||
if (selector) namespace.add(selector, res);
|
||||
else $.concrete.warn('Concrete block given to concrete call without selector. Make sure you call $(selector).concrete when defining blocks', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Finally, return the jQuery object 'this' refers to, wrapped in the new namespace */
|
||||
return namespace.$(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calls the next most specific version of the current concrete method
|
||||
*/
|
||||
_super: function(){
|
||||
var rv, i = this.length;
|
||||
while (i--) {
|
||||
var el = this[0];
|
||||
rv = el.f(el, arguments, el.i);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
||||
|
||||
/* src/jquery.concrete.dommaybechanged.js */
|
||||
|
||||
(function($){
|
||||
|
||||
/** What to call to run a function 'soon'. Normally setTimeout, but for syncronous mode we override so soon === now */
|
||||
var runSoon = window.setTimeout;
|
||||
|
||||
/** The timer handle for the asyncronous matching call */
|
||||
var check_id = null;
|
||||
|
||||
/** Fire the change event. Only fires on the document node, so bind to that */
|
||||
var triggerEvent = function() {
|
||||
$(document).triggerHandler('DOMMaybeChanged');
|
||||
check_id = null;
|
||||
}
|
||||
|
||||
$.extend($.concrete, {
|
||||
/**
|
||||
* Make onmatch and onunmatch work in synchronous mode - that is, new elements will be detected immediately after
|
||||
* the DOM manipulation that made them match. This is only really useful for during testing, since it's pretty slow
|
||||
* (otherwise we'd make it the default).
|
||||
*/
|
||||
synchronous_mode: function() {
|
||||
if (check_id) clearTimeout(check_id); check_id = null;
|
||||
runSoon = function(func, delay){ func.call(this); return null; }
|
||||
},
|
||||
|
||||
/**
|
||||
* Trigger onmatch and onunmatch now - usefull for after DOM manipulation by methods other than through jQuery.
|
||||
* Called automatically on document.ready
|
||||
*/
|
||||
triggerMatching: function() {
|
||||
matching();
|
||||
}
|
||||
});
|
||||
|
||||
function registerMutateFunction() {
|
||||
$.each(arguments, function(i,func){
|
||||
var old = $.fn[func];
|
||||
$.fn[func] = function() {
|
||||
var rv = old.apply(this, arguments);
|
||||
if (!check_id) check_id = runSoon(triggerEvent, 100);
|
||||
return rv;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function registerSetterGetterFunction() {
|
||||
$.each(arguments, function(i,func){
|
||||
var old = $.fn[func];
|
||||
$.fn[func] = function(a, b) {
|
||||
var rv = old.apply(this, arguments);
|
||||
if (!check_id && (b !== undefined || typeof a != 'string')) check_id = runSoon(triggerEvent, 100);
|
||||
return rv;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Register core DOM manipulation methods
|
||||
registerMutateFunction('append', 'prepend', 'after', 'before', 'wrap', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');
|
||||
registerSetterGetterFunction('attr');
|
||||
|
||||
// And on DOM ready, trigger matching once
|
||||
$(function(){ triggerEvent(); })
|
||||
|
||||
})(jQuery);;
|
||||
|
||||
|
||||
/* src/jquery.concrete.events.js */
|
||||
|
||||
(function($) {
|
||||
|
||||
/* If we are any browser other than IE or Safari, we don't have to do anything special to handle
|
||||
* onchange delegation */
|
||||
$.support.bubblingChange = !($.browser.msie || $.browser.safari);
|
||||
|
||||
/* Return true if node b is the same as, or is a descendant of, node a */
|
||||
if (document.compareDocumentPosition) {
|
||||
var is_or_contains = function(a, b) {
|
||||
return a && b && (a == b || !!(a.compareDocumentPosition(b) & 16));
|
||||
}
|
||||
}
|
||||
else {
|
||||
var is_or_contains = function(a, b) {
|
||||
return a && b && (a == b || (a.contains ? a.contains(b) : true));
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the methods to handle event binding to the Namespace class */
|
||||
$.concrete.Namespace.addMethods({
|
||||
build_event_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function(e, originalevent) {
|
||||
e = originalevent || e;
|
||||
|
||||
var el = e.target;
|
||||
while (el && el != document && !e.isPropagationStopped()) {
|
||||
one(el, arguments);
|
||||
el = el.parentNode;
|
||||
}
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
build_mouseenterleave_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function(e) {
|
||||
var el = e.target;
|
||||
var rel = e.relatedTarget;
|
||||
|
||||
while (el && el != document && !e.isPropagationStopped()) {
|
||||
/* We know el contained target. If it also contains relatedTarget then we didn't mouseenter / leave. What's more, every ancestor will also
|
||||
contan el and rel, and so we can just stop bubbling */
|
||||
if (is_or_contains(el, rel)) break;
|
||||
|
||||
one(el, arguments);
|
||||
el = el.parentNode;
|
||||
}
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
build_change_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function(e) {
|
||||
var el = e.target;
|
||||
// If this is a keydown event, only worry about the enter key, since browsers only trigger onchange on enter or focus loss
|
||||
if (e.type === 'keydown' && e.keyCode !== 13) return;
|
||||
// Make sure this is event is for an input type we're interested in
|
||||
if (el.tagName !== 'INPUT' && el.tagName !== 'TEXTAREA' && el.tagName !== 'SELECT') return;
|
||||
|
||||
var $el = $(el), nowVal, oldVal = $el.data('changeVal');
|
||||
|
||||
// Detect changes on checkboxes & radiobuttons, which have different value logic. We don't use el.value, since el is part
|
||||
// of a set, and we only want to raise onchange once for a single user action.
|
||||
if (el.type == 'checkbox' || el.type == 'radio') {
|
||||
if (!el.disabled && e.type === 'click') {
|
||||
nowVal = el.checked;
|
||||
// If radio, we get two changes - the activation, and the deactivation. We only want to fire one change though
|
||||
if ((el.type === 'checkbox' || nowVal === true) && oldVal !== nowVal) e.type = 'change';
|
||||
}
|
||||
}
|
||||
// Detect changes on other input types. In this case value is OK.
|
||||
else {
|
||||
nowVal = el.value;
|
||||
if (oldVal !== undefined && oldVal !== nowVal) e.type = 'change';
|
||||
}
|
||||
|
||||
// Save the current value for next time
|
||||
if (nowVal !== undefined) $el.data('changeVal', nowVal);
|
||||
|
||||
// And if we decided that a change happened, do the actual triggering
|
||||
if (e.type == 'change') {
|
||||
while (el && el != document && !e.isPropagationStopped()) {
|
||||
one(el, arguments);
|
||||
el = el.parentNode;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
bind_event: function(selector, name, func, event) {
|
||||
var funcs = this.store[name] || (this.store[name] = $.concrete.RuleList()) ;
|
||||
var proxies = funcs.proxies || (funcs.proxies = {});
|
||||
|
||||
var rule = funcs.addRule(selector, name); rule.func = func;
|
||||
|
||||
if (!proxies[name]) {
|
||||
switch (name) {
|
||||
case 'onmouseenter':
|
||||
proxies[name] = this.build_mouseenterleave_proxy(name);
|
||||
event = 'mouseover';
|
||||
break;
|
||||
case 'onmouseleave':
|
||||
proxies[name] = this.build_mouseenterleave_proxy(name);
|
||||
event = 'mouseout';
|
||||
break;
|
||||
case 'onchange':
|
||||
if (!$.support.bubblingChange) {
|
||||
proxies[name] = this.build_change_proxy(name);
|
||||
event = 'click focusin focusout keydown';
|
||||
}
|
||||
break;
|
||||
case 'onsubmit':
|
||||
event = 'delegated_submit';
|
||||
case 'onfocus':
|
||||
case 'onblur':
|
||||
$.concrete.warn('Event '+event+' not supported - using focusin / focusout instead', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
|
||||
if (!proxies[name]) proxies[name] = this.build_event_proxy(name);
|
||||
$(document).bind(event, proxies[name]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 40,
|
||||
|
||||
bind: function(selector, k, v){
|
||||
if ($.isFunction(v) && (match = k.match(/^on(.*)/))) {
|
||||
event = match[1];
|
||||
this.bind_event(selector, k, v, event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Find all forms and bind onsubmit to trigger on the document too. This is the only event that can't be grabbed via delegation.
|
||||
|
||||
var form_binding_cache = $([]); // A cache for already-handled form elements
|
||||
var delegate_submit = function(e){ $(document).triggerHandler('delegated_submit', e); } // The function that handles the delegation
|
||||
|
||||
$(document).bind('DOMMaybeChanged', function(){
|
||||
var forms = $('form');
|
||||
// Only bind to forms we haven't processed yet
|
||||
forms.not(form_binding_cache).bind('submit', delegate_submit);
|
||||
// Then remember the current set of forms
|
||||
form_binding_cache = forms;
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
||||
|
||||
/* src/jquery.concrete.ctors.js */
|
||||
|
||||
(function($) {
|
||||
|
||||
/* Add the methods to handle constructor & destructor binding to the Namespace class */
|
||||
$.concrete.Namespace.addMethods({
|
||||
bind_condesc: function(selector, name, func) {
|
||||
var ctors = this.store.ctors || (this.store.ctors = $.concrete.RuleList()) ;
|
||||
|
||||
var rule;
|
||||
for (var i = 0 ; i < ctors.length; i++) {
|
||||
if (ctors[i].selector.selector == selector.selector) {
|
||||
rule = ctors[i]; break;
|
||||
}
|
||||
}
|
||||
if (!rule) {
|
||||
rule = ctors.addRule(selector, 'ctors');
|
||||
}
|
||||
|
||||
rule[name] = func;
|
||||
|
||||
if (!ctors[name+'proxy']) {
|
||||
var one = this.one('ctors', name);
|
||||
var namespace = this;
|
||||
|
||||
var proxy = function(els, i, func) {
|
||||
var j = els.length;
|
||||
while (j--) {
|
||||
var el = els[j];
|
||||
|
||||
var tmp_i = el.i, tmp_f = el.f;
|
||||
el.i = i; el.f = one;
|
||||
try { func.call(namespace.$(el)); }
|
||||
catch(e) { el.i = tmp_i; el.f = tmp_f; }
|
||||
}
|
||||
}
|
||||
|
||||
ctors[name+'proxy'] = proxy;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 30,
|
||||
|
||||
bind: function(selector, k, v) {
|
||||
if ($.isFunction(v) && (k == 'onmatch' || k == 'onunmatch')) {
|
||||
this.bind_condesc(selector, k, v);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Finds all the elements that now match a different rule (or have been removed) and call onmatch on onunmatch as appropriate
|
||||
*
|
||||
* Because this has to scan the DOM, and is therefore fairly slow, this is normally triggered off a short timeout, so that
|
||||
* a series of DOM manipulations will only trigger this once.
|
||||
*
|
||||
* The downside of this is that things like:
|
||||
* $('#foo').addClass('tabs'); $('#foo').tabFunctionBar();
|
||||
* won't work.
|
||||
*/
|
||||
$(document).bind('DOMMaybeChanged', function(){
|
||||
// For every namespace
|
||||
for (var k in $.concrete.namespaces) {
|
||||
// That has constructors or destructors
|
||||
var ctors = $.concrete.namespaces[k].store.ctors;
|
||||
if (ctors) {
|
||||
|
||||
// Keep a record of elements that have matched already
|
||||
var matched = $([]), match, add, rem;
|
||||
// Stepping through each selector from most to least specific
|
||||
var j = ctors.length;
|
||||
while (j--) {
|
||||
// Build some quick-acccess variables
|
||||
var sel = ctors[j].selector.selector, ctor = ctors[j].onmatch; dtor = ctors[j].onunmatch;
|
||||
// Get the list of elements that match this selector, that haven't yet matched a more specific selector
|
||||
res = add = $(sel).not(matched);
|
||||
|
||||
// If this selector has a list of elements it matched against last time
|
||||
if (ctors[j].cache) {
|
||||
// Find the ones that are extra this time
|
||||
add = res.not(ctors[j].cache);
|
||||
// Find the ones that are gone this time
|
||||
rem = ctors[j].cache.not(res);
|
||||
// And call the desctructor on them
|
||||
if (rem.length && dtor) ctors.onunmatchproxy(rem, j, dtor);
|
||||
}
|
||||
|
||||
// Call the constructor on the newly matched ones
|
||||
if (add.length && ctor) ctors.onmatchproxy(add, j, ctor);
|
||||
|
||||
// Add these matched ones to the list tracking all elements matched so far
|
||||
matched = matched.add(res);
|
||||
// And remember this list of matching elements again this selector, so next matching we can find the unmatched ones
|
||||
ctors[j].cache = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
||||
|
||||
/* src/jquery.concrete.properties.js */
|
||||
|
||||
(function($) {
|
||||
|
||||
var concrete_prepend = '__concrete!';
|
||||
|
||||
var getConcreteData = function(el, namespace, property) {
|
||||
return el.data(concrete_prepend + namespace + '!' + property);
|
||||
}
|
||||
|
||||
var setConcreteData = function(el, namespace, property, value) {
|
||||
return el.data(concrete_prepend + namespace + '!' + property, value);
|
||||
}
|
||||
|
||||
var getConcreteDataAsHash = function(el, namespace) {
|
||||
var hash = {};
|
||||
var id = jQuery.data(el[0]);
|
||||
|
||||
var matchstr = concrete_prepend + namespace + '!';
|
||||
var matchlen = matchstr.length;
|
||||
|
||||
var cache = jQuery.cache[id];
|
||||
for (var k in cache) {
|
||||
if (k.substr(0,matchlen) == matchstr) hash[k.substr(matchlen)] = cache[k];
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
var setConcreteDataFromHash = function(el, namespace, hash) {
|
||||
for (var k in hash) setConcreteData(namespace, k, hash[k]);
|
||||
}
|
||||
|
||||
var concreteData = function(el, namespace, args) {
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
return getConcreteDataAsHash(el, namespace);
|
||||
case 1:
|
||||
if (typeof args[0] == 'string') return getConcreteData(el, namespace, args[0]);
|
||||
else return setConcreteDataFromHash(el, namespace, args[0]);
|
||||
default:
|
||||
return setConcreteData(el, namespace, args[0], args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$.extend($.fn, {
|
||||
concreteData: function() {
|
||||
return concreteData(this, '__base', arguments);
|
||||
}
|
||||
});
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 60,
|
||||
|
||||
bind: function(selector, k, v) {
|
||||
if (k.charAt(0) != k.charAt(0).toUpperCase()) $.concrete.warn('Concrete property '+k+' does not start with a capital letter', $.concrete.WARN_LEVEL_BESTPRACTISE);
|
||||
|
||||
var namespace = this;
|
||||
g = function() { return this.concreteData(k) || v ; }
|
||||
s = function(v){ return this.concreteData(k, v); }
|
||||
|
||||
g.pname = s.pname = k;
|
||||
|
||||
this.bind_proxy(selector, 'get'+k, g);
|
||||
this.bind_proxy(selector, 'set'+k, s);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
namespaceMethodOverrides: function(namespace){
|
||||
return {
|
||||
concreteData: function() {
|
||||
return concreteData(this, namespace.name, arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
1490
thirdparty/jquery-concrete/dist/jquery.concrete-latest.js
vendored
Normal file
@ -0,0 +1,1490 @@
|
||||
/* jQuery.Concrete - Copyright 2009 Hamish Friedlander and SilverStripe. Version 0.9. */
|
||||
|
||||
/* vendor/jquery.selector/jquery.class.js */
|
||||
|
||||
/**
|
||||
* Very basic Class utility. Based on base and jquery.class.
|
||||
*
|
||||
* Class definition: var Foo = Base.extend({ init: function(){ Constructor }; method_name: function(){ Method } });
|
||||
*
|
||||
* Inheritance: var Bar = Foo.extend({ method_name: function(){ this._super(); } });
|
||||
*
|
||||
* new-less Constructor: new Foo(arg) <-same as-> Foo(arg)
|
||||
*/
|
||||
|
||||
var Base;
|
||||
|
||||
(function(){
|
||||
|
||||
var marker = {}, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
||||
|
||||
// The base Class implementation (does nothing)
|
||||
Base = function(){};
|
||||
|
||||
Base.addMethod = function(name, func) {
|
||||
var _super = this._super;
|
||||
if (_super && fnTest.test(func)) {
|
||||
this.prototype[name] = function(){
|
||||
var tmp = this._super;
|
||||
this._super = _super[name];
|
||||
try {
|
||||
var ret = func.apply(this, arguments);
|
||||
}
|
||||
finally {
|
||||
this._super = tmp;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else this.prototype[name] = func;
|
||||
}
|
||||
|
||||
Base.addMethods = function(props) {
|
||||
for (var name in props) {
|
||||
if (typeof props[name] == 'function') this.addMethod(name, props[name]);
|
||||
else this.prototype[name] = props[name];
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new Class that inherits from this class
|
||||
Base.extend = function(props) {
|
||||
|
||||
// The dummy class constructor
|
||||
var Kls = function() {
|
||||
if (arguments[0] === marker) return;
|
||||
|
||||
if (this instanceof Kls) {
|
||||
if (this.init) this.init.apply(this, arguments);
|
||||
}
|
||||
else {
|
||||
var ret = new Kls(marker); if (ret.init) ret.init.apply(ret, arguments); return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the common class variables and methods
|
||||
Kls.constructor = Kls;
|
||||
Kls.extend = Base.extend;
|
||||
Kls.addMethod = Base.addMethod;
|
||||
Kls.addMethods = Base.addMethods;
|
||||
Kls._super = this.prototype;
|
||||
|
||||
// Attach the parent object to the inheritance chain
|
||||
Kls.prototype = new this(marker);
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
Kls.addMethods(props);
|
||||
|
||||
return Kls;
|
||||
};
|
||||
})();;
|
||||
|
||||
|
||||
/* vendor/jquery.selector/jquery.selector.js */
|
||||
|
||||
(function($){
|
||||
|
||||
var tokens = {
|
||||
UNICODE: /\\[0-9a-f]{1,6}(?:\r\n|[ \n\r\t\f])?/,
|
||||
ESCAPE: /(?:UNICODE)|\\[^\n\r\f0-9a-f]/,
|
||||
NONASCII: /[^\x00-\x7F]/,
|
||||
NMSTART: /[_a-z]|(?:NONASCII)|(?:ESCAPE)/,
|
||||
NMCHAR: /[_a-z0-9-]|(?:NONASCII)|(?:ESCAPE)/,
|
||||
IDENT: /-?(?:NMSTART)(?:NMCHAR)*/,
|
||||
|
||||
NL: /\n|\r\n|\r|\f/,
|
||||
|
||||
STRING: /(?:STRING1)|(?:STRING2)|(?:STRINGBARE)/,
|
||||
STRING1: /"(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\"])*"/,
|
||||
STRING2: /'(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\'])*'/,
|
||||
STRINGBARE: /(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\]])*/,
|
||||
|
||||
FUNCTION: /(?:IDENT)\(\)/,
|
||||
|
||||
INTEGER: /[0-9]+/,
|
||||
|
||||
WITHN: /([-+])?(INTEGER)?(n)\s*(?:([-+])\s*(INTEGER))?/,
|
||||
WITHOUTN: /([-+])?(INTEGER)/
|
||||
}
|
||||
|
||||
var rx = {
|
||||
not: /:not\(/,
|
||||
not_end: /\)/,
|
||||
|
||||
tag: /((?:IDENT)|\*)/,
|
||||
id: /#(IDENT)/,
|
||||
cls: /\.(IDENT)/,
|
||||
attr: /\[\s*(IDENT)\s*(?:([^=]?=)\s*(STRING)\s*)?\]/,
|
||||
pseudo_el: /(?::(first-line|first-letter|before|after))|(?:::((?:FUNCTION)|(?:IDENT)))/,
|
||||
pseudo_cls_nth: /:nth-child\(\s*(?:(?:WITHN)|(?:WITHOUTN)|(odd|even))\s*\)/,
|
||||
pseudo_cls: /:(IDENT)/,
|
||||
|
||||
comb: /\s*(\+|~|>)\s*|\s+/,
|
||||
comma: /\s*,\s*/,
|
||||
important: /\s+!important\s*$/
|
||||
}
|
||||
|
||||
/* Replace placeholders with actual regex, and mark all as case insensitive */
|
||||
var token = /[A-Z][A-Z0-9]+/;
|
||||
for (var k in rx) {
|
||||
var src = rx[k].source;
|
||||
while (m = src.match(token)) src = src.replace(m[0], tokens[m[0]].source);
|
||||
rx[k] = new RegExp(src, 'gi');
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that matches itself against regexii, and keeps track of how much of itself has been matched
|
||||
*/
|
||||
var ConsumableString = Base.extend({
|
||||
init: function(str) {
|
||||
this.str = str;
|
||||
this.pos = 0;
|
||||
},
|
||||
match: function(rx) {
|
||||
var m;
|
||||
rx.lastIndex = this.pos;
|
||||
if ((m = rx.exec(this.str)) && m.index == this.pos ) {
|
||||
this.pos = rx.lastIndex ? rx.lastIndex : this.str.length ;
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
peek: function(rx) {
|
||||
var m;
|
||||
rx.lastIndex = this.pos;
|
||||
if ((m = rx.exec(this.str)) && m.index == this.pos ) return m;
|
||||
return null;
|
||||
},
|
||||
showpos: function() {
|
||||
return this.str.slice(0,this.pos)+'<HERE>' + this.str.slice(this.pos);
|
||||
},
|
||||
done: function() {
|
||||
return this.pos == this.str.length;
|
||||
}
|
||||
})
|
||||
|
||||
/* A base class that all Selectors inherit off */
|
||||
var SelectorBase = Base.extend({});
|
||||
|
||||
/**
|
||||
* A class representing a Simple Selector, as per the CSS3 selector spec
|
||||
*/
|
||||
var SimpleSelector = SelectorBase.extend({
|
||||
init: function() {
|
||||
this.tag = null;
|
||||
this.id = null;
|
||||
this.classes = [];
|
||||
this.attrs = [];
|
||||
this.nots = [];
|
||||
this.pseudo_classes = [];
|
||||
this.pseudo_els = [];
|
||||
},
|
||||
parse: function(selector) {
|
||||
var m;
|
||||
|
||||
/* Pull out the initial tag first, if there is one */
|
||||
if (m = selector.match(rx.tag)) this.tag = m[1];
|
||||
|
||||
/* Then for each selection type, try and find a match */
|
||||
do {
|
||||
if (m = selector.match(rx.not)) {
|
||||
this.nots[this.nots.length] = SelectorsGroup().parse(selector)
|
||||
if (!(m = selector.match(rx.not_end))) {
|
||||
throw 'Invalid :not term in selector';
|
||||
}
|
||||
}
|
||||
else if (m = selector.match(rx.id)) this.id = m[1];
|
||||
else if (m = selector.match(rx.cls)) this.classes[this.classes.length] = m[1];
|
||||
else if (m = selector.match(rx.attr)) this.attrs[this.attrs.length] = [ m[1], m[2], m[3] ];
|
||||
else if (m = selector.match(rx.pseudo_el)) this.pseudo_els[this.pseudo_els.length] = m[1] || m[2];
|
||||
else if (m = selector.match(rx.pseudo_cls_nth)) {
|
||||
if (m[3]) {
|
||||
var a = parseInt((m[1]||'')+(m[2]||'1'));
|
||||
var b = parseInt((m[4]||'')+(m[5]||'0'));
|
||||
}
|
||||
else {
|
||||
var a = m[8] ? 2 : 0;
|
||||
var b = m[8] ? (4-m[8].length) : parseInt((m[6]||'')+m[7]);
|
||||
}
|
||||
this.pseudo_classes[this.pseudo_classes.length] = ['nth-child', [a, b]];
|
||||
}
|
||||
else if (m = selector.match(rx.pseudo_cls)) this.pseudo_classes[this.pseudo_classes.length] = [m[1]];
|
||||
|
||||
} while(m && !selector.done());
|
||||
|
||||
return this;
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* A class representing a Selector, as per the CSS3 selector spec
|
||||
*/
|
||||
var Selector = SelectorBase.extend({
|
||||
init: function(){
|
||||
this.parts = [];
|
||||
},
|
||||
parse: function(cons){
|
||||
this.parts[this.parts.length] = SimpleSelector().parse(cons);
|
||||
|
||||
while (!cons.done() && !cons.peek(rx.comma) && (m = cons.match(rx.comb))) {
|
||||
this.parts[this.parts.length] = m[1] || ' ';
|
||||
this.parts[this.parts.length] = SimpleSelector().parse(cons);
|
||||
}
|
||||
|
||||
return this.parts.length == 1 ? this.parts[0] : this;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A class representing a sequence of selectors, as per the CSS3 selector spec
|
||||
*/
|
||||
var SelectorsGroup = SelectorBase.extend({
|
||||
init: function(){
|
||||
this.parts = [];
|
||||
},
|
||||
parse: function(cons){
|
||||
this.parts[this.parts.length] = Selector().parse(cons);
|
||||
|
||||
while (!cons.done() && (m = cons.match(rx.comma))) {
|
||||
this.parts[this.parts.length] = Selector().parse(cons);
|
||||
}
|
||||
|
||||
return this.parts.length == 1 ? this.parts[0] : this;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$.selector = function(s){
|
||||
var cons = ConsumableString(s);
|
||||
var res = SelectorsGroup().parse(cons);
|
||||
|
||||
res.selector = s;
|
||||
|
||||
if (!cons.done()) throw 'Could not parse selector - ' + cons.showpos() ;
|
||||
else return res;
|
||||
}
|
||||
|
||||
$.selector.SelectorBase = SelectorBase;
|
||||
$.selector.SimpleSelector = SimpleSelector;
|
||||
$.selector.Selector = Selector;
|
||||
$.selector.SelectorsGroup = SelectorsGroup;
|
||||
|
||||
})(jQuery)
|
||||
;
|
||||
|
||||
|
||||
/* vendor/jquery.selector/jquery.selector.specifity.js */
|
||||
|
||||
(function($) {
|
||||
|
||||
$.selector.SimpleSelector.addMethod('specifity', function() {
|
||||
if (this.spec) return this.spec;
|
||||
|
||||
var spec = [
|
||||
this.id ? 1 : 0,
|
||||
this.classes.length + this.attrs.length + this.pseudo_classes.length,
|
||||
((this.tag && this.tag != '*') ? 1 : 0) + this.pseudo_els.length
|
||||
];
|
||||
$.each(this.nots, function(i,not){
|
||||
var ns = not.specifity(); spec[0] += ns[0]; spec[1] += ns[1]; spec[2] += ns[2];
|
||||
});
|
||||
|
||||
return this.spec = spec;
|
||||
})
|
||||
|
||||
$.selector.Selector.addMethod('specifity', function(){
|
||||
if (this.spec) return this.spec;
|
||||
|
||||
var spec = [0,0,0];
|
||||
$.each(this.parts, function(i,part){
|
||||
if (i%2) return;
|
||||
var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2];
|
||||
});
|
||||
|
||||
return this.spec = spec;
|
||||
})
|
||||
|
||||
$.selector.SelectorsGroup.addMethod('specifity', function(){
|
||||
if (this.spec) return this.spec;
|
||||
|
||||
var spec = [0,0,0];
|
||||
$.each(this.parts, function(i,part){
|
||||
var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2];
|
||||
});
|
||||
|
||||
return this.spec = spec;
|
||||
})
|
||||
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
||||
|
||||
/* vendor/jquery.selector/jquery.selector.matches.js */
|
||||
|
||||
/*
|
||||
This attempts to do the opposite of Sizzle.
|
||||
Sizzle is good for finding elements for a selector, but not so good for telling if an individual element matches a selector
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
/**** CAPABILITY TESTS ****/
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = '<form id="test"><input name="id" type="text"/></form>';
|
||||
|
||||
// In IE 6-7, getAttribute often does the wrong thing (returns similar to el.attr), so we need to use getAttributeNode on that browser
|
||||
var getAttributeDodgy = div.firstChild.getAttribute('id') !== 'test';
|
||||
|
||||
// Does browser support Element.firstElementChild, Element.previousElementSibling, etc.
|
||||
var hasElementTraversal = div.firstElementChild && div.firstElementChild.tagName == 'FORM';
|
||||
|
||||
// Does browser support Element.children
|
||||
var hasChildren = div.children && div.children[0].tagName == 'FORM';
|
||||
|
||||
var FUNC_IN = /^\s*function\s*\([^)]*\)\s*{/;
|
||||
var FUNC_OUT = /}\s*$/;
|
||||
|
||||
var funcToString = function(f) {
|
||||
return (''+f).replace(FUNC_IN,'').replace(FUNC_OUT,'');
|
||||
}
|
||||
|
||||
// Can we use Function#toString ?
|
||||
try {
|
||||
var testFunc = function(){ return 'good' };
|
||||
if ((new Function('',funcToString(testFunc)))() != 'good') funcToString = false;
|
||||
}
|
||||
catch(e) { funcToString = false; console.log(e.message);/*pass*/ }
|
||||
|
||||
/**** INTRO ****/
|
||||
|
||||
var GOOD = /GOOD/g;
|
||||
var BAD = /BAD/g;
|
||||
|
||||
var STARTS_WITH_QUOTES = /^['"]/g;
|
||||
|
||||
var join = function(js) {
|
||||
return js.join('\n');
|
||||
}
|
||||
|
||||
var join_complex = function(js) {
|
||||
code = new String(js.join('\n')); // String objects can have properties set. strings can't
|
||||
code.complex = true;
|
||||
return code;
|
||||
}
|
||||
|
||||
/**** ATTRIBUTE ACCESSORS ****/
|
||||
|
||||
var getAttr;
|
||||
|
||||
// Good browsers
|
||||
if (!getAttributeDodgy) {
|
||||
getAttr = function(attr){ return 'var _'+attr+' = el.getAttribute("'+attr+'");' ; }
|
||||
}
|
||||
// IE 6, 7
|
||||
else {
|
||||
// On IE 6 + 7, getAttribute still has to be called with DOM property mirror name, not attribute name. Map attributes to those names
|
||||
var getAttrIEMap = { 'class': 'className', 'for': 'htmlFor' };
|
||||
|
||||
getAttr = function(attr) {
|
||||
var ieattr = getAttrIEMap[attr] || attr;
|
||||
return 'var _'+attr+' = el.getAttribute("'+ieattr+'",2) || (el.getAttributeNode("'+attr+'")||{}).nodeValue;';
|
||||
}
|
||||
}
|
||||
|
||||
/**** ATTRIBUTE COMPARITORS ****/
|
||||
|
||||
var attrchecks = {
|
||||
'-': '!_K',
|
||||
'=': '_K != "V"',
|
||||
'!=': '_K == "V"',
|
||||
'~=': '__K.indexOf(" V ") == -1',
|
||||
'^=': '!_K || _K.indexOf("V") != 0',
|
||||
'*=': '!_K || _K.indexOf("V") == -1',
|
||||
'$=': '!_K || _K.substr(_K.length-"V".length) != "V"'
|
||||
}
|
||||
|
||||
/**** STATE TRACKER ****/
|
||||
|
||||
var State = $.selector.State = Base.extend({
|
||||
init: function(){
|
||||
this.reset();
|
||||
},
|
||||
reset: function() {
|
||||
this.attrs = {}; this.wsattrs = {};
|
||||
},
|
||||
|
||||
prev: function(){
|
||||
this.reset();
|
||||
if (hasElementTraversal) return 'el = el.previousElementSibling';
|
||||
return 'while((el = el.previousSibling) && el.nodeType != 1) {}';
|
||||
},
|
||||
next: function() {
|
||||
this.reset();
|
||||
if (hasElementTraversal) return 'el = el.nextElementSibling';
|
||||
return 'while((el = el.nextSibling) && el.nodeType != 1) {}';
|
||||
},
|
||||
prevLoop: function(body){
|
||||
this.reset();
|
||||
if (hasElementTraversal) return join([ 'while(el = el.previousElementSibling){', body]);
|
||||
return join([
|
||||
'while(el = el.previousSibling){',
|
||||
'if (el.nodeType != 1) continue;',
|
||||
body,
|
||||
]);
|
||||
},
|
||||
parent: function() {
|
||||
this.reset();
|
||||
return 'el = el.parentNode;';
|
||||
},
|
||||
parentLoop: function(body) {
|
||||
this.reset();
|
||||
return join([
|
||||
'while((el = el.parentNode) && el.nodeType == 1){',
|
||||
body,
|
||||
'}'
|
||||
]);
|
||||
},
|
||||
|
||||
uses_attr: function(attr) {
|
||||
if (this.attrs[attr]) return;
|
||||
this.attrs[attr] = true;
|
||||
return getAttr(attr);
|
||||
},
|
||||
uses_wsattr: function(attr) {
|
||||
if (this.wsattrs[attr]) return;
|
||||
this.wsattrs[attr] = true;
|
||||
return join([this.uses_attr(attr), 'var __'+attr+' = " "+_'+attr+'+" ";']);
|
||||
},
|
||||
|
||||
save: function(lbl) {
|
||||
return 'var el'+lbl+' = el;';
|
||||
},
|
||||
restore: function(lbl) {
|
||||
this.reset();
|
||||
return 'el = el'+lbl+';';
|
||||
}
|
||||
});
|
||||
|
||||
/**** PSEUDO-CLASS DETAILS ****/
|
||||
|
||||
var pseudoclschecks = {
|
||||
'first-child': join([
|
||||
'var cel = el;',
|
||||
'while(cel = cel.previousSibling){ if (cel.nodeType === 1) BAD; }',
|
||||
]),
|
||||
'last-child': join([
|
||||
'var cel = el;',
|
||||
'while(cel = cel.nextSibling){ if (cel.nodeType === 1) BAD; }'
|
||||
]),
|
||||
'nth-child': function(a,b) {
|
||||
var get_i = join([
|
||||
'var i = 1, cel = el;',
|
||||
'while(cel = cel.previousSibling){',
|
||||
'if (cel.nodeType === 1) i++;',
|
||||
'}',
|
||||
]);
|
||||
|
||||
if (a == 0) return join([
|
||||
get_i,
|
||||
'if (i- '+b+' != 0) BAD;'
|
||||
]);
|
||||
else if (b == 0 && a >= 0) return join([
|
||||
get_i,
|
||||
'if (i%'+a+' != 0 || i/'+a+' < 0) BAD;'
|
||||
]);
|
||||
else if (b == 0 && a < 0) return join([
|
||||
'BAD;'
|
||||
]);
|
||||
else return join([
|
||||
get_i,
|
||||
'if ((i- '+b+')%'+a+' != 0 || (i- '+b+')/'+a+' < 0) BAD;'
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
// Needs to refence contents of object, so must be injected after definition
|
||||
pseudoclschecks['only-child'] = join([
|
||||
pseudoclschecks['first-child'],
|
||||
pseudoclschecks['last-child']
|
||||
]);
|
||||
|
||||
/**** SimpleSelector ****/
|
||||
|
||||
$.selector.SimpleSelector.addMethod('compile', function(el) {
|
||||
var js = [];
|
||||
|
||||
/* Check against element name */
|
||||
if (this.tag && this.tag != '*') {
|
||||
js[js.length] = 'if (el.tagName != "'+this.tag.toUpperCase()+'") BAD;';
|
||||
}
|
||||
|
||||
/* Check against ID */
|
||||
if (this.id) {
|
||||
js[js.length] = el.uses_attr('id');
|
||||
js[js.length] = 'if (_id !== "'+this.id+'") BAD;';
|
||||
}
|
||||
|
||||
/* Build className checking variable */
|
||||
if (this.classes.length) {
|
||||
js[js.length] = el.uses_wsattr('class');
|
||||
|
||||
/* Check against class names */
|
||||
$.each(this.classes, function(i, cls){
|
||||
js[js.length] = 'if (__class.indexOf(" '+cls+' ") == -1) BAD;';
|
||||
})
|
||||
}
|
||||
|
||||
/* Check against attributes */
|
||||
$.each(this.attrs, function(i, attr){
|
||||
js[js.length] = (attr[1] == '~=') ? el.uses_wsattr(attr[0]) : el.uses_attr(attr[0]);
|
||||
var check = attrchecks[ attr[1] || '-' ];
|
||||
check = check.replace( /K/g, attr[0]).replace( /V/g, attr[2] && attr[2].match(STARTS_WITH_QUOTES) ? attr[2].slice(1,-1) : attr[2] );
|
||||
js[js.length] = 'if ('+check+') BAD;';
|
||||
});
|
||||
|
||||
/* Check against nots */
|
||||
$.each(this.nots, function(i, not){
|
||||
var lbl = ++lbl_id;
|
||||
var func = join([
|
||||
'l'+lbl+':{',
|
||||
not.compile(el).replace(BAD, 'break l'+lbl).replace(GOOD, 'BAD'),
|
||||
'}'
|
||||
]);
|
||||
|
||||
if (!(not instanceof $.selector.SimpleSelector)) func = join([
|
||||
el.save(lbl),
|
||||
func,
|
||||
el.restore(lbl)
|
||||
])
|
||||
|
||||
js[js.length] = func;
|
||||
});
|
||||
|
||||
/* Check against pseudo-classes */
|
||||
$.each(this.pseudo_classes, function(i, pscls){
|
||||
var check = pseudoclschecks[pscls[0]];
|
||||
if (check) {
|
||||
js[js.length] = ( typeof check == 'function' ? check.apply(this, pscls[1]) : check );
|
||||
}
|
||||
else if (check = $.find.selectors.filters[pscls[0]]) {
|
||||
if (funcToString) {
|
||||
js[js.length] = funcToString(check).replace(/elem/g,'el').replace(/return([^;]+);/,'if (!($1)) BAD;');
|
||||
}
|
||||
else {
|
||||
js[js.length] = 'if (!$.find.selectors.filters.'+pscls[0]+'(el)) BAD;'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
js[js.length] = 'GOOD';
|
||||
|
||||
/* Pass */
|
||||
return join(js);
|
||||
});
|
||||
|
||||
var lbl_id = 0;
|
||||
/** Turns an compiled fragment into the first part of a combination */
|
||||
function as_subexpr(f) {
|
||||
if (f.complex)
|
||||
return join([
|
||||
'l'+(++lbl_id)+':{',
|
||||
f.replace(GOOD, 'break l'+lbl_id),
|
||||
'}',
|
||||
]);
|
||||
else
|
||||
return f.replace(GOOD, '');
|
||||
}
|
||||
|
||||
var combines = {
|
||||
' ': function(el, f1, f2) {
|
||||
return join_complex([
|
||||
f2,
|
||||
'while(true){',
|
||||
el.parent(),
|
||||
'if (!el || el.nodeType !== 1) BAD;',
|
||||
f1.compile(el).replace(BAD, 'continue'),
|
||||
'}'
|
||||
]);
|
||||
},
|
||||
|
||||
'>': function(el, f1, f2) {
|
||||
return join([
|
||||
f2,
|
||||
el.parent(),
|
||||
'if (!el || el.nodeType !== 1) BAD;',
|
||||
f1.compile(el)
|
||||
]);
|
||||
},
|
||||
|
||||
'~': function(el, f1, f2) {
|
||||
return join_complex([
|
||||
f2,
|
||||
el.prevLoop(),
|
||||
f1.compile(el).replace(BAD, 'continue'),
|
||||
'}',
|
||||
'BAD;'
|
||||
]);
|
||||
},
|
||||
|
||||
'+': function(el, f1, f2) {
|
||||
return join([
|
||||
f2,
|
||||
el.prev(),
|
||||
'if (!el) BAD;',
|
||||
f1.compile(el)
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
$.selector.Selector.addMethod('compile', function(el) {
|
||||
l = this.parts.length;
|
||||
|
||||
expr = this.parts[--l].compile(el);
|
||||
while (l) {
|
||||
combinator = this.parts[--l];
|
||||
expr = combines[combinator](el, this.parts[--l], as_subexpr(expr));
|
||||
}
|
||||
|
||||
return expr;
|
||||
});
|
||||
|
||||
$.selector.SelectorsGroup.addMethod('compile', function(el) {
|
||||
var expr = [], lbl = ++lbl_id;
|
||||
|
||||
for (var i=0; i < this.parts.length; i++) {
|
||||
expr[expr.length] = join([
|
||||
i == 0 ? el.save(lbl) : el.restore(lbl),
|
||||
'l'+lbl+'_'+i+':{',
|
||||
this.parts[i].compile(el).replace(BAD, 'break l'+lbl+'_'+i),
|
||||
'}'
|
||||
]);
|
||||
}
|
||||
|
||||
expr[expr.length] = 'BAD;';
|
||||
return join(expr);
|
||||
});
|
||||
|
||||
$.selector.SelectorBase.addMethod('matches', function(el){
|
||||
this.matches = new Function('el', join([
|
||||
'if (!el) return false;',
|
||||
this.compile(new State()).replace(BAD, 'return false').replace(GOOD, 'return true')
|
||||
]));
|
||||
return this.matches(el);
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
||||
;
|
||||
|
||||
|
||||
/* src/jquery.focusinout.js */
|
||||
|
||||
(function($){
|
||||
|
||||
/**
|
||||
* Add focusin and focusout support to bind and live for browers other than IE. Designed to be usable in a delegated fashion (like $.live)
|
||||
* Copyright (c) 2007 Jörn Zaefferer
|
||||
*/
|
||||
$.support.focusInOut = !!($.browser.msie);
|
||||
if (!$.support.focusInOut) {
|
||||
// Emulate focusin and focusout by binding focus and blur in capturing mode
|
||||
$.each({focus: 'focusin', blur: 'focusout'}, function(original, fix){
|
||||
$.event.special[fix] = {
|
||||
setup: function(){
|
||||
if (!this.addEventListener) return false;
|
||||
this.addEventListener(original, $.event.special[fix].handler, true);
|
||||
},
|
||||
teardown: function(){
|
||||
if (!this.removeEventListener) return false;
|
||||
this.removeEventListener(original, $.event.special[fix].handler, true);
|
||||
},
|
||||
handler: function(e){
|
||||
arguments[0] = $.event.fix(e);
|
||||
arguments[0].type = fix;
|
||||
return $.event.handle.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
(function(){
|
||||
//IE has some trouble with focusout with select and keyboard navigation
|
||||
var activeFocus = null;
|
||||
|
||||
$(document)
|
||||
.bind('focusin', function(e){
|
||||
var target = e.realTarget || e.target;
|
||||
if (activeFocus && activeFocus !== target) {
|
||||
e.type = 'focusout';
|
||||
$(activeFocus).trigger(e);
|
||||
e.type = 'focusin';
|
||||
e.target = target;
|
||||
}
|
||||
activeFocus = target;
|
||||
})
|
||||
.bind('focusout', function(e){
|
||||
activeFocus = null;
|
||||
});
|
||||
})();
|
||||
|
||||
})(jQuery);;
|
||||
|
||||
|
||||
/* src/jquery.concrete.js */
|
||||
|
||||
var console;
|
||||
|
||||
(function($) {
|
||||
|
||||
var namespaces = {};
|
||||
|
||||
$.concrete = function() {
|
||||
$.fn.concrete.apply(null, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* A couple of utility functions for accessing the store outside of this closure, and for making things
|
||||
* operate in a little more easy-to-test manner
|
||||
*/
|
||||
$.extend($.concrete, {
|
||||
/**
|
||||
* Get all the namespaces. Useful for introspection? Internal interface of Namespace not guaranteed consistant
|
||||
*/
|
||||
namespaces: namespaces,
|
||||
|
||||
/**
|
||||
* Remove all concrete rules
|
||||
*/
|
||||
clear_all_rules: function() {
|
||||
// Remove proxy functions
|
||||
for (var k in $.fn) { if ($.fn[k].concrete) delete $.fn[k] ; }
|
||||
// Remove namespaces, and start over again
|
||||
namespaces = $.concrete.namespaces = {};
|
||||
},
|
||||
|
||||
WARN_LEVEL_NONE: 0,
|
||||
WARN_LEVEL_IMPORTANT: 1,
|
||||
WARN_LEVEL_BESTPRACTISE: 2,
|
||||
|
||||
/**
|
||||
* Warning level. Set to a higher level to get warnings dumped to console.
|
||||
*/
|
||||
warningLevel: 0,
|
||||
|
||||
/** Utility to optionally display warning messages depending on level */
|
||||
warn: function(message, level) {
|
||||
if (level <= $.concrete.warningLevel && console && console.log) {
|
||||
console.warn(message);
|
||||
if (console.trace) console.trace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/** Stores a count of definitions, so that we can sort identical selectors by definition order */
|
||||
var rulecount = 0;
|
||||
|
||||
var Rule = Base.extend({
|
||||
init: function(selector, name) {
|
||||
this.selector = selector;
|
||||
this.specifity = selector.specifity();
|
||||
this.important = 0;
|
||||
this.name = name;
|
||||
this.rulecount = rulecount++;
|
||||
}
|
||||
});
|
||||
|
||||
Rule.compare = function(a, b) {
|
||||
var as = a.specifity, bs = b.specifity;
|
||||
|
||||
return (a.important - b.important) ||
|
||||
(as[0] - bs[0]) ||
|
||||
(as[1] - bs[1]) ||
|
||||
(as[2] - bs[2]) ||
|
||||
(a.rulecount - b.rulecount) ;
|
||||
}
|
||||
|
||||
$.concrete.RuleList = function() {
|
||||
var list = [];
|
||||
|
||||
list.addRule = function(selector, name){
|
||||
var rule = Rule(selector, name);
|
||||
|
||||
list[list.length] = rule;
|
||||
list.sort(Rule.compare);
|
||||
|
||||
return rule;
|
||||
};
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
var handlers = [];
|
||||
|
||||
/**
|
||||
* A Namespace holds all the information needed for adding concrete methods to a namespace (including the _null_ namespace)
|
||||
*/
|
||||
$.concrete.Namespace = Base.extend({
|
||||
init: function(name){
|
||||
if (name && !name.match(/^[A-Za-z0-9.]+$/)) $.concrete.warn('Concrete namespace '+name+' is not formatted as period seperated identifiers', $.concrete.WARN_LEVEL_BESTPRACTISE);
|
||||
name = name || '__base';
|
||||
|
||||
this.name = name;
|
||||
this.store = {};
|
||||
|
||||
namespaces[name] = this;
|
||||
|
||||
if (name == "__base") {
|
||||
this.injectee = $.fn
|
||||
this.$ = $;
|
||||
}
|
||||
else {
|
||||
// We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into
|
||||
var subfn = function(){}
|
||||
this.injectee = subfn.prototype = new $();
|
||||
|
||||
// And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building
|
||||
var bound$ = this.$ = function(a) {
|
||||
// Try the simple way first
|
||||
var jq = $.fn.init.apply(new subfn(), arguments);
|
||||
if (jq instanceof subfn) return jq;
|
||||
|
||||
// That didn't return a bound object, so now we need to copy it
|
||||
var rv = new subfn();
|
||||
rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length;
|
||||
while (i--) rv[i] = jq[i];
|
||||
return rv;
|
||||
}
|
||||
this.injectee.pushStack = function(elems, name, selector){
|
||||
var ret = bound$(elems);
|
||||
|
||||
// Add the old object onto the stack (as a reference)
|
||||
ret.prevObject = this;
|
||||
ret.context = this.context;
|
||||
|
||||
if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector;
|
||||
else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")";
|
||||
|
||||
// Return the newly-formed element set
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Copy static functions through from $ to this.$ so e.g. $.ajax still works
|
||||
// @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through
|
||||
$.extend(this.$, $);
|
||||
|
||||
// We override concrete to inject the name of this namespace when defining blocks inside this namespace
|
||||
var concrete_wrapper = this.injectee.concrete = function(spacename) {
|
||||
var args = arguments;
|
||||
|
||||
if (!spacename || typeof spacename != 'string') { args = $.makeArray(args); args.unshift(name); }
|
||||
else if (spacename.charAt(0) != '.') args[0] = name+'.'+spacename;
|
||||
|
||||
return $.fn.concrete.apply(this, args);
|
||||
}
|
||||
|
||||
this.$.concrete = function() {
|
||||
concrete_wrapper.apply(null, arguments);
|
||||
}
|
||||
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
var handler = handlers[i], builder;
|
||||
|
||||
// Inject jQuery object method overrides
|
||||
if (builder = handler.namespaceMethodOverrides) {
|
||||
var overrides = builder(this);
|
||||
for (var k in overrides) this.injectee[k] = overrides[k];
|
||||
}
|
||||
|
||||
// Inject $.concrete function overrides
|
||||
if (builder = handler.namespaceStaticOverrides) {
|
||||
var overrides = builder(this);
|
||||
for (var k in overrides) this.$.concrete[k] = overrides[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a function that does selector matching against the function list for a function name
|
||||
* Used by proxy for all calls, and by ctorProxy to handle _super calls
|
||||
* @param {String} name - name of the function as passed in the construction object
|
||||
* @param {String} funcprop - the property on the Rule object that gives the actual function to call
|
||||
*/
|
||||
one: function(name, funcprop) {
|
||||
var namespace = this;
|
||||
var funcs = this.store[name];
|
||||
|
||||
var one = function(el, args, i){
|
||||
if (i === undefined) i = funcs.length;
|
||||
while (i--) {
|
||||
if (funcs[i].selector.matches(el)) {
|
||||
var ret, tmp_i = el.i, tmp_f = el.f;
|
||||
el.i = i; el.f = one;
|
||||
try { ret = funcs[i][funcprop].apply(namespace.$(el), args); }
|
||||
finally { el.i = tmp_i; el.f = tmp_f; }
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return one;
|
||||
},
|
||||
|
||||
/**
|
||||
* A proxy is a function attached to a callable object (either the base jQuery.fn or a subspace object) which handles
|
||||
* finding and calling the correct function for each member of the current jQuery context
|
||||
* @param {String} name - name of the function as passed in the construction object
|
||||
*/
|
||||
build_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function() {
|
||||
var rv, ctx = $(this);
|
||||
|
||||
var i = ctx.length;
|
||||
while (i--) rv = one(ctx[i], arguments);
|
||||
return rv;
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
bind_proxy: function(selector, name, func) {
|
||||
var rulelist = this.store[name] || (this.store[name] = $.concrete.RuleList());
|
||||
|
||||
var rule = rulelist.addRule(selector, name); rule.func = func;
|
||||
|
||||
if (!this.injectee.hasOwnProperty(name)) {
|
||||
this.injectee[name] = this.build_proxy(name);
|
||||
this.injectee[name].concrete = true;
|
||||
}
|
||||
|
||||
if (!this.injectee[name].concrete) {
|
||||
$.concrete.warn('Warning: Concrete function '+name+' clashes with regular jQuery function - concrete function will not be callable directly on jQuery object', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
},
|
||||
|
||||
add: function(selector, data) {
|
||||
// For every item in the hash, try ever method handler, until one returns true
|
||||
for (var k in data) {
|
||||
var v = data[k];
|
||||
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
if (handlers[i].bind && handlers[i].bind.call(this, selector, k, v)) break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
has: function(ctx, name) {
|
||||
var rulelist = this.store[name];
|
||||
if (!rulelist) return false;
|
||||
|
||||
/* We go forward this time, since low specifity is likely to knock out a bunch of elements quickly */
|
||||
for (var i = 0 ; i < rulelist.length; i++) {
|
||||
ctx = ctx.not(rulelist[i].selector);
|
||||
if (!ctx.length) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* The default handlers provided (and included by default) are event, ctor and properties
|
||||
*/
|
||||
$.concrete.Namespace.addHandler = function(handler) {
|
||||
for (var i = 0; i < handlers.length && handlers[i].order < handler.order; i++) { /* Pass */ }
|
||||
handlers.splice(i, 0, handler);
|
||||
}
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 50,
|
||||
|
||||
bind: function(selector, k, v){
|
||||
if ($.isFunction(v)) {
|
||||
this.bind_proxy(selector, k, v);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.extend($.fn, {
|
||||
/**
|
||||
* Main concrete function. Used for new definitions, calling into a namespace (or forcing the base namespace) and entering a using block
|
||||
*
|
||||
*/
|
||||
concrete: function(spacename) {
|
||||
var i = 0;
|
||||
var selector = this.selector ? $.selector(this.selector) : null;
|
||||
|
||||
/* By default we operator on the base namespace */
|
||||
var namespace = namespaces.__base || $.concrete.Namespace();
|
||||
|
||||
/* If the first argument is a string, then it's the name of a namespace. Look it up */
|
||||
if (typeof spacename == 'string') {
|
||||
if (spacename.charAt('0') == '.') spacename = spacename.substr(1);
|
||||
if (spacename) namespace = namespaces[spacename] || $.concrete.Namespace(spacename);
|
||||
i=1;
|
||||
}
|
||||
|
||||
/* All remaining arguments should either be using blocks or definition hashs */
|
||||
while (i < arguments.length) {
|
||||
var res = arguments[i++];
|
||||
|
||||
// If it's a function, call it - either it's a using block or it's a namespaced concrete definition
|
||||
if ($.isFunction(res)) {
|
||||
if (res.length != 1) $.concrete.warn('Function block inside concrete definition does not take $ argument properly', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
res = res.call(namespace.$(this), namespace.$);
|
||||
}
|
||||
|
||||
// If we have a concrete definition hash, inject it into namespace
|
||||
if (res) {
|
||||
if (selector) namespace.add(selector, res);
|
||||
else $.concrete.warn('Concrete block given to concrete call without selector. Make sure you call $(selector).concrete when defining blocks', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Finally, return the jQuery object 'this' refers to, wrapped in the new namespace */
|
||||
return namespace.$(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calls the next most specific version of the current concrete method
|
||||
*/
|
||||
_super: function(){
|
||||
var rv, i = this.length;
|
||||
while (i--) {
|
||||
var el = this[0];
|
||||
rv = el.f(el, arguments, el.i);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
||||
|
||||
/* src/jquery.concrete.dommaybechanged.js */
|
||||
|
||||
(function($){
|
||||
|
||||
/** What to call to run a function 'soon'. Normally setTimeout, but for syncronous mode we override so soon === now */
|
||||
var runSoon = window.setTimeout;
|
||||
|
||||
/** The timer handle for the asyncronous matching call */
|
||||
var check_id = null;
|
||||
|
||||
/** Fire the change event. Only fires on the document node, so bind to that */
|
||||
var triggerEvent = function() {
|
||||
$(document).triggerHandler('DOMMaybeChanged');
|
||||
check_id = null;
|
||||
}
|
||||
|
||||
$.extend($.concrete, {
|
||||
/**
|
||||
* Make onmatch and onunmatch work in synchronous mode - that is, new elements will be detected immediately after
|
||||
* the DOM manipulation that made them match. This is only really useful for during testing, since it's pretty slow
|
||||
* (otherwise we'd make it the default).
|
||||
*/
|
||||
synchronous_mode: function() {
|
||||
if (check_id) clearTimeout(check_id); check_id = null;
|
||||
runSoon = function(func, delay){ func.call(this); return null; }
|
||||
},
|
||||
|
||||
/**
|
||||
* Trigger onmatch and onunmatch now - usefull for after DOM manipulation by methods other than through jQuery.
|
||||
* Called automatically on document.ready
|
||||
*/
|
||||
triggerMatching: function() {
|
||||
matching();
|
||||
}
|
||||
});
|
||||
|
||||
function registerMutateFunction() {
|
||||
$.each(arguments, function(i,func){
|
||||
var old = $.fn[func];
|
||||
$.fn[func] = function() {
|
||||
var rv = old.apply(this, arguments);
|
||||
if (!check_id) check_id = runSoon(triggerEvent, 100);
|
||||
return rv;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function registerSetterGetterFunction() {
|
||||
$.each(arguments, function(i,func){
|
||||
var old = $.fn[func];
|
||||
$.fn[func] = function(a, b) {
|
||||
var rv = old.apply(this, arguments);
|
||||
if (!check_id && (b !== undefined || typeof a != 'string')) check_id = runSoon(triggerEvent, 100);
|
||||
return rv;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Register core DOM manipulation methods
|
||||
registerMutateFunction('append', 'prepend', 'after', 'before', 'wrap', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');
|
||||
registerSetterGetterFunction('attr');
|
||||
|
||||
// And on DOM ready, trigger matching once
|
||||
$(function(){ triggerEvent(); })
|
||||
|
||||
})(jQuery);;
|
||||
|
||||
|
||||
/* src/jquery.concrete.events.js */
|
||||
|
||||
(function($) {
|
||||
|
||||
/* If we are any browser other than IE or Safari, we don't have to do anything special to handle
|
||||
* onchange delegation */
|
||||
$.support.bubblingChange = !($.browser.msie || $.browser.safari);
|
||||
|
||||
/* Return true if node b is the same as, or is a descendant of, node a */
|
||||
if (document.compareDocumentPosition) {
|
||||
var is_or_contains = function(a, b) {
|
||||
return a && b && (a == b || !!(a.compareDocumentPosition(b) & 16));
|
||||
}
|
||||
}
|
||||
else {
|
||||
var is_or_contains = function(a, b) {
|
||||
return a && b && (a == b || (a.contains ? a.contains(b) : true));
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the methods to handle event binding to the Namespace class */
|
||||
$.concrete.Namespace.addMethods({
|
||||
build_event_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function(e, originalevent) {
|
||||
e = originalevent || e;
|
||||
|
||||
var el = e.target;
|
||||
while (el && el != document && !e.isPropagationStopped()) {
|
||||
one(el, arguments);
|
||||
el = el.parentNode;
|
||||
}
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
build_mouseenterleave_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function(e) {
|
||||
var el = e.target;
|
||||
var rel = e.relatedTarget;
|
||||
|
||||
while (el && el != document && !e.isPropagationStopped()) {
|
||||
/* We know el contained target. If it also contains relatedTarget then we didn't mouseenter / leave. What's more, every ancestor will also
|
||||
contan el and rel, and so we can just stop bubbling */
|
||||
if (is_or_contains(el, rel)) break;
|
||||
|
||||
one(el, arguments);
|
||||
el = el.parentNode;
|
||||
}
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
build_change_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function(e) {
|
||||
var el = e.target;
|
||||
// If this is a keydown event, only worry about the enter key, since browsers only trigger onchange on enter or focus loss
|
||||
if (e.type === 'keydown' && e.keyCode !== 13) return;
|
||||
// Make sure this is event is for an input type we're interested in
|
||||
if (el.tagName !== 'INPUT' && el.tagName !== 'TEXTAREA' && el.tagName !== 'SELECT') return;
|
||||
|
||||
var $el = $(el), nowVal, oldVal = $el.data('changeVal');
|
||||
|
||||
// Detect changes on checkboxes & radiobuttons, which have different value logic. We don't use el.value, since el is part
|
||||
// of a set, and we only want to raise onchange once for a single user action.
|
||||
if (el.type == 'checkbox' || el.type == 'radio') {
|
||||
if (!el.disabled && e.type === 'click') {
|
||||
nowVal = el.checked;
|
||||
// If radio, we get two changes - the activation, and the deactivation. We only want to fire one change though
|
||||
if ((el.type === 'checkbox' || nowVal === true) && oldVal !== nowVal) e.type = 'change';
|
||||
}
|
||||
}
|
||||
// Detect changes on other input types. In this case value is OK.
|
||||
else {
|
||||
nowVal = el.value;
|
||||
if (oldVal !== undefined && oldVal !== nowVal) e.type = 'change';
|
||||
}
|
||||
|
||||
// Save the current value for next time
|
||||
if (nowVal !== undefined) $el.data('changeVal', nowVal);
|
||||
|
||||
// And if we decided that a change happened, do the actual triggering
|
||||
if (e.type == 'change') {
|
||||
while (el && el != document && !e.isPropagationStopped()) {
|
||||
one(el, arguments);
|
||||
el = el.parentNode;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
bind_event: function(selector, name, func, event) {
|
||||
var funcs = this.store[name] || (this.store[name] = $.concrete.RuleList()) ;
|
||||
var proxies = funcs.proxies || (funcs.proxies = {});
|
||||
|
||||
var rule = funcs.addRule(selector, name); rule.func = func;
|
||||
|
||||
if (!proxies[name]) {
|
||||
switch (name) {
|
||||
case 'onmouseenter':
|
||||
proxies[name] = this.build_mouseenterleave_proxy(name);
|
||||
event = 'mouseover';
|
||||
break;
|
||||
case 'onmouseleave':
|
||||
proxies[name] = this.build_mouseenterleave_proxy(name);
|
||||
event = 'mouseout';
|
||||
break;
|
||||
case 'onchange':
|
||||
if (!$.support.bubblingChange) {
|
||||
proxies[name] = this.build_change_proxy(name);
|
||||
event = 'click focusin focusout keydown';
|
||||
}
|
||||
break;
|
||||
case 'onsubmit':
|
||||
event = 'delegated_submit';
|
||||
case 'onfocus':
|
||||
case 'onblur':
|
||||
$.concrete.warn('Event '+event+' not supported - using focusin / focusout instead', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
|
||||
if (!proxies[name]) proxies[name] = this.build_event_proxy(name);
|
||||
$(document).bind(event, proxies[name]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 40,
|
||||
|
||||
bind: function(selector, k, v){
|
||||
if ($.isFunction(v) && (match = k.match(/^on(.*)/))) {
|
||||
event = match[1];
|
||||
this.bind_event(selector, k, v, event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Find all forms and bind onsubmit to trigger on the document too. This is the only event that can't be grabbed via delegation.
|
||||
|
||||
var form_binding_cache = $([]); // A cache for already-handled form elements
|
||||
var delegate_submit = function(e){ $(document).triggerHandler('delegated_submit', e); } // The function that handles the delegation
|
||||
|
||||
$(document).bind('DOMMaybeChanged', function(){
|
||||
var forms = $('form');
|
||||
// Only bind to forms we haven't processed yet
|
||||
forms.not(form_binding_cache).bind('submit', delegate_submit);
|
||||
// Then remember the current set of forms
|
||||
form_binding_cache = forms;
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
||||
|
||||
/* src/jquery.concrete.ctors.js */
|
||||
|
||||
(function($) {
|
||||
|
||||
/* Add the methods to handle constructor & destructor binding to the Namespace class */
|
||||
$.concrete.Namespace.addMethods({
|
||||
bind_condesc: function(selector, name, func) {
|
||||
var ctors = this.store.ctors || (this.store.ctors = $.concrete.RuleList()) ;
|
||||
|
||||
var rule;
|
||||
for (var i = 0 ; i < ctors.length; i++) {
|
||||
if (ctors[i].selector.selector == selector.selector) {
|
||||
rule = ctors[i]; break;
|
||||
}
|
||||
}
|
||||
if (!rule) {
|
||||
rule = ctors.addRule(selector, 'ctors');
|
||||
}
|
||||
|
||||
rule[name] = func;
|
||||
|
||||
if (!ctors[name+'proxy']) {
|
||||
var one = this.one('ctors', name);
|
||||
var namespace = this;
|
||||
|
||||
var proxy = function(els, i, func) {
|
||||
var j = els.length;
|
||||
while (j--) {
|
||||
var el = els[j];
|
||||
|
||||
var tmp_i = el.i, tmp_f = el.f;
|
||||
el.i = i; el.f = one;
|
||||
try { func.call(namespace.$(el)); }
|
||||
catch(e) { el.i = tmp_i; el.f = tmp_f; }
|
||||
}
|
||||
}
|
||||
|
||||
ctors[name+'proxy'] = proxy;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 30,
|
||||
|
||||
bind: function(selector, k, v) {
|
||||
if ($.isFunction(v) && (k == 'onmatch' || k == 'onunmatch')) {
|
||||
this.bind_condesc(selector, k, v);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Finds all the elements that now match a different rule (or have been removed) and call onmatch on onunmatch as appropriate
|
||||
*
|
||||
* Because this has to scan the DOM, and is therefore fairly slow, this is normally triggered off a short timeout, so that
|
||||
* a series of DOM manipulations will only trigger this once.
|
||||
*
|
||||
* The downside of this is that things like:
|
||||
* $('#foo').addClass('tabs'); $('#foo').tabFunctionBar();
|
||||
* won't work.
|
||||
*/
|
||||
$(document).bind('DOMMaybeChanged', function(){
|
||||
// For every namespace
|
||||
for (var k in $.concrete.namespaces) {
|
||||
// That has constructors or destructors
|
||||
var ctors = $.concrete.namespaces[k].store.ctors;
|
||||
if (ctors) {
|
||||
|
||||
// Keep a record of elements that have matched already
|
||||
var matched = $([]), match, add, rem;
|
||||
// Stepping through each selector from most to least specific
|
||||
var j = ctors.length;
|
||||
while (j--) {
|
||||
// Build some quick-acccess variables
|
||||
var sel = ctors[j].selector.selector, ctor = ctors[j].onmatch; dtor = ctors[j].onunmatch;
|
||||
// Get the list of elements that match this selector, that haven't yet matched a more specific selector
|
||||
res = add = $(sel).not(matched);
|
||||
|
||||
// If this selector has a list of elements it matched against last time
|
||||
if (ctors[j].cache) {
|
||||
// Find the ones that are extra this time
|
||||
add = res.not(ctors[j].cache);
|
||||
// Find the ones that are gone this time
|
||||
rem = ctors[j].cache.not(res);
|
||||
// And call the desctructor on them
|
||||
if (rem.length && dtor) ctors.onunmatchproxy(rem, j, dtor);
|
||||
}
|
||||
|
||||
// Call the constructor on the newly matched ones
|
||||
if (add.length && ctor) ctors.onmatchproxy(add, j, ctor);
|
||||
|
||||
// Add these matched ones to the list tracking all elements matched so far
|
||||
matched = matched.add(res);
|
||||
// And remember this list of matching elements again this selector, so next matching we can find the unmatched ones
|
||||
ctors[j].cache = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
||||
|
||||
/* src/jquery.concrete.properties.js */
|
||||
|
||||
(function($) {
|
||||
|
||||
var concrete_prepend = '__concrete!';
|
||||
|
||||
var getConcreteData = function(el, namespace, property) {
|
||||
return el.data(concrete_prepend + namespace + '!' + property);
|
||||
}
|
||||
|
||||
var setConcreteData = function(el, namespace, property, value) {
|
||||
return el.data(concrete_prepend + namespace + '!' + property, value);
|
||||
}
|
||||
|
||||
var getConcreteDataAsHash = function(el, namespace) {
|
||||
var hash = {};
|
||||
var id = jQuery.data(el[0]);
|
||||
|
||||
var matchstr = concrete_prepend + namespace + '!';
|
||||
var matchlen = matchstr.length;
|
||||
|
||||
var cache = jQuery.cache[id];
|
||||
for (var k in cache) {
|
||||
if (k.substr(0,matchlen) == matchstr) hash[k.substr(matchlen)] = cache[k];
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
var setConcreteDataFromHash = function(el, namespace, hash) {
|
||||
for (var k in hash) setConcreteData(namespace, k, hash[k]);
|
||||
}
|
||||
|
||||
var concreteData = function(el, namespace, args) {
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
return getConcreteDataAsHash(el, namespace);
|
||||
case 1:
|
||||
if (typeof args[0] == 'string') return getConcreteData(el, namespace, args[0]);
|
||||
else return setConcreteDataFromHash(el, namespace, args[0]);
|
||||
default:
|
||||
return setConcreteData(el, namespace, args[0], args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$.extend($.fn, {
|
||||
concreteData: function() {
|
||||
return concreteData(this, '__base', arguments);
|
||||
}
|
||||
});
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 60,
|
||||
|
||||
bind: function(selector, k, v) {
|
||||
if (k.charAt(0) != k.charAt(0).toUpperCase()) $.concrete.warn('Concrete property '+k+' does not start with a capital letter', $.concrete.WARN_LEVEL_BESTPRACTISE);
|
||||
|
||||
var namespace = this;
|
||||
g = function() { return this.concreteData(k) || v ; }
|
||||
s = function(v){ return this.concreteData(k, v); }
|
||||
|
||||
g.pname = s.pname = k;
|
||||
|
||||
this.bind_proxy(selector, 'get'+k, g);
|
||||
this.bind_proxy(selector, 'set'+k, s);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
namespaceMethodOverrides: function(namespace){
|
||||
return {
|
||||
concreteData: function() {
|
||||
return concreteData(this, namespace.name, arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
;
|
||||
|
30
thirdparty/jquery-concrete/spec/spec-dist.html
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- spec-dist is the same as spec, but runs on the distribution version of the library, to make sure no problems were introduced during building -->
|
||||
<link type="text/css" rel="stylesheet" href="../vendor/jspec/lib/jspec.css" />
|
||||
<script src="../vendor/jquery-1.3.2.js"></script>
|
||||
<script src="../vendor/jspec/lib/jspec.js"></script>
|
||||
<script src="../vendor/jspec/lib/jspec.jquery.js"></script>
|
||||
|
||||
<script src="../dist/jquery.concrete-latest.js"></script>
|
||||
|
||||
<script>
|
||||
function runSuites() {
|
||||
JSpec
|
||||
.exec('spec.concrete.basics.js')
|
||||
.exec('spec.concrete.namespaces.js')
|
||||
.exec('spec.concrete.super.js')
|
||||
.exec('spec.concrete.events.js')
|
||||
.exec('spec.concrete.ctors.js')
|
||||
.exec('spec.concrete.properties.js')
|
||||
.run()
|
||||
.report()
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="jspec" onLoad="runSuites();">
|
||||
<div id="jspec-top"><h2 id="jspec-title">JSpec <em><script>document.write(JSpec.version)</script></em></h2></div>
|
||||
<div id="jspec"><div class="loading"></div></div>
|
||||
<div id="jspec-bottom"></div>
|
||||
</body>
|
||||
</html>
|
72
thirdparty/jquery-concrete/spec/spec.concrete.basics.js
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
|
||||
describe 'Concrete'
|
||||
describe 'Basics'
|
||||
before
|
||||
$.concrete.warningLevel = $.concrete.WARN_LEVEL_BESTPRACTISE;
|
||||
$('body').append('<div id="dom_test"></div>')
|
||||
end
|
||||
after
|
||||
$('#dom_test').remove()
|
||||
end
|
||||
|
||||
before_each
|
||||
$.concrete.clear_all_rules()
|
||||
$('#dom_test').html('<div id="a" class="a b c"></div><div id="b" class="c d e"></div>')
|
||||
end
|
||||
|
||||
it 'can attach and call a base function'
|
||||
$('#a').concrete({
|
||||
foo: function(){return this.attr('id');}
|
||||
});
|
||||
$('.a').foo().should.equal 'a'
|
||||
end
|
||||
|
||||
it 'can attach and call several base functions'
|
||||
$('#a').concrete({
|
||||
foo: function(){return 'foo_' + this.attr('id');},
|
||||
bar: function(){return 'bar_' + this.attr('id');}
|
||||
});
|
||||
$('.a').foo().should.equal 'foo_a'
|
||||
$('.a').bar().should.equal 'bar_a'
|
||||
end
|
||||
|
||||
it 'can attach and call a namespaced function'
|
||||
$('#a').concrete('bar', function($){return{
|
||||
foo: function(){return this.attr('id');}
|
||||
}});
|
||||
$('.a').concrete('bar').foo().should.equal 'a'
|
||||
end
|
||||
|
||||
it 'can attach and call a nested namespaced function'
|
||||
$('#a').concrete('qux.baz.bar', function($){return{
|
||||
foo: function(){return this.attr('id');}
|
||||
}});
|
||||
$('.a').concrete('qux.baz.bar').foo().should.equal 'a'
|
||||
end
|
||||
|
||||
it 'can call two functions on two elements'
|
||||
var res = []
|
||||
$('#a').concrete({
|
||||
foo: function(){res.push(this.attr('id'));},
|
||||
})
|
||||
$('#b.c').concrete({
|
||||
foo: function(){res.push(this.attr('id'));},
|
||||
})
|
||||
$('#dom_test div').foo();
|
||||
res.should.eql ['b', 'a']
|
||||
end
|
||||
|
||||
it 'can call two namespaced functions on two elements'
|
||||
var res = []
|
||||
$('#a').concrete('bar', function($){return{
|
||||
foo: function(){res.push(this.attr('id'));},
|
||||
}})
|
||||
$('#b.c').concrete('bar', function($){return{
|
||||
foo: function(){res.push(this.attr('id'));},
|
||||
}})
|
||||
$('#dom_test div').concrete('bar').foo();
|
||||
res.should.eql ['b', 'a']
|
||||
end
|
||||
|
||||
end
|
||||
end
|
68
thirdparty/jquery-concrete/spec/spec.concrete.ctors.js
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
describe 'Concrete'
|
||||
describe 'Ctors'
|
||||
|
||||
before
|
||||
$('body').append('<div id="dom_test"></div>')
|
||||
end
|
||||
|
||||
after
|
||||
$('#dom_test').remove()
|
||||
end
|
||||
|
||||
before_each
|
||||
$.concrete.synchronous_mode();
|
||||
$.concrete.clear_all_rules()
|
||||
$('#dom_test').html('<div id="a" class="a b c"></div>')
|
||||
end
|
||||
|
||||
it 'calls onmatch when new element created'
|
||||
var a = false;
|
||||
$('#b').concrete({onmatch: function(){a = true;} });
|
||||
a.should.be_false
|
||||
$('#a').after('<div id="b"></div>');
|
||||
a.should.be_true
|
||||
end
|
||||
|
||||
it 'calls onunmatch when new element deleted'
|
||||
var a = 0;
|
||||
$('#b').concrete({onmatch: function(){a = 1;}, onunmatch: function(){a = 2;} });
|
||||
a.should.equal 0
|
||||
$('#a').after('<div id="b"></div>');
|
||||
a.should.equal 1
|
||||
$('#b').remove();
|
||||
a.should.equal 2
|
||||
end
|
||||
|
||||
it 'calls onmatch when ruleset matches after class added'
|
||||
var a = 0;
|
||||
$('#a.foo').concrete({onmatch: function(){a = 1;} });
|
||||
a.should.equal 0
|
||||
$('#a').addClass('foo');
|
||||
a.should.equal 1
|
||||
end
|
||||
|
||||
it 'calls onmatch in both direct and namespaced onmatch, does not call less specific onmatch'
|
||||
var a = 0, b=0, c=0, d=0;
|
||||
$('.foo').concrete({onmatch: function(){a = 1;}})
|
||||
$('.foo').concrete('bar', function($){return{onmatch: function(){b = 1;}}})
|
||||
$('#a.foo').concrete({onmatch: function(){c = 1;}})
|
||||
$('#a.foo').concrete('bar', function($){return{onmatch: function(){d = 1}}})
|
||||
[a, b, c, d].should.eql [0, 0, 0, 0]
|
||||
$('#a').addClass('foo');
|
||||
[a, b, c, d].should.eql [0, 0, 1, 1]
|
||||
end
|
||||
|
||||
it 'calls onmatch in both direct and namespaced onmatch, super works as expected'
|
||||
var a = 0, b=0, c=0, d=0;
|
||||
$('.foo').concrete({onmatch: function(){a += 1;}})
|
||||
$('.foo').concrete('bar', function($){return{onmatch: function(){b += 1;}}})
|
||||
$('#a.foo').concrete({onmatch: function(){this._super(); c = 1; this._super();}})
|
||||
$('#a.foo').concrete('bar', function($){return{onmatch: function(){this._super(); d = 1; this._super();}}})
|
||||
[a, b, c, d].should.eql [0, 0, 0, 0]
|
||||
$('#a').addClass('foo');
|
||||
[a, b, c, d].should.eql [2, 2, 1, 1]
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
68
thirdparty/jquery-concrete/spec/spec.concrete.events.js
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
describe 'Concrete'
|
||||
describe 'Events'
|
||||
|
||||
before
|
||||
$('body').append('<div id="dom_test"></div>')
|
||||
end
|
||||
|
||||
after
|
||||
$('#dom_test').remove()
|
||||
end
|
||||
|
||||
before_each
|
||||
$.concrete.synchronous_mode();
|
||||
$.concrete.clear_all_rules()
|
||||
$('#dom_test').html('<div id="a" class="a b c"></div>')
|
||||
end
|
||||
|
||||
it 'calls onfoo when foo triggered'
|
||||
var a = 0;
|
||||
$('#a').concrete({onfoo: function(){a = 1;} });
|
||||
a.should.equal 0
|
||||
$('#a').trigger('foo');
|
||||
a.should.equal 1
|
||||
end
|
||||
|
||||
it 'only calls most specific onfoo when foo triggered'
|
||||
var a = 0, b = 0;
|
||||
$('#a.a').concrete({onfoo: function(){a = 1;} });
|
||||
$('#a').concrete({onfoo: function(){b = 1;} });
|
||||
a.should.equal 0
|
||||
b.should.equal 0
|
||||
$('#a').trigger('foo');
|
||||
a.should.equal 1
|
||||
b.should.equal 0
|
||||
end
|
||||
|
||||
it 'calls namespaced onfoo when foo triggered'
|
||||
var a = 0;
|
||||
$('#a').concrete('bar', function($){return{onfoo: function(){a = 1;} }});
|
||||
a.should.equal 0
|
||||
$('#a').trigger('foo');
|
||||
a.should.equal 1
|
||||
end
|
||||
|
||||
it 'calls most specific namespaced onfoo and most specific non-namespaced onfoo when foo triggered'
|
||||
var a = 0, b = 0, c = 0, d = 0;
|
||||
$('#a.a').concrete({onfoo: function(){a = 1;} });
|
||||
$('#a').concrete({onfoo: function(){b = 1;} });
|
||||
$('#a.a').concrete('bar', function($){return{onfoo: function(){c = 1;} }});
|
||||
$('#a').concrete('bar', function($){return{onfoo: function(){d = 1;} }});
|
||||
[a, b, c, d].should.eql [0, 0, 0, 0]
|
||||
|
||||
$('#a').trigger('foo');
|
||||
[a, b, c, d].should.eql [1, 0, 1, 0]
|
||||
end
|
||||
|
||||
it 'calls up correctly on _super'
|
||||
var a = 0, b = 0;
|
||||
$('#a').concrete({onfoo: function(){a += 1;} });
|
||||
$('#a.a').concrete({onfoo: function(){this._super(); b += 1; this._super();} });
|
||||
|
||||
[a, b].should.eql [0, 0]
|
||||
$('#a').trigger('foo')
|
||||
[a, b].should.eql [2, 1]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
246
thirdparty/jquery-concrete/spec/spec.concrete.namespaces.js
vendored
Normal file
@ -0,0 +1,246 @@
|
||||
|
||||
describe 'Concrete'
|
||||
describe 'Namespaces'
|
||||
before
|
||||
$('body').append('<div id="dom_test"></div>')
|
||||
end
|
||||
after
|
||||
$('#dom_test').remove()
|
||||
end
|
||||
|
||||
before_each
|
||||
$.concrete.synchronous_mode();
|
||||
$.concrete.clear_all_rules()
|
||||
$('#dom_test').html('<div id="a" class="a b c"></div><div id="b" class="c d e"></div>')
|
||||
end
|
||||
|
||||
it 'namespaced functions work (single definition mode)'
|
||||
$('#a').concrete('bar', function($){return{
|
||||
bar: function(){return 'a';}
|
||||
}})
|
||||
$('#a').concrete('bar').bar().should.equal 'a'
|
||||
end
|
||||
|
||||
it 'namespaced functions work (block definition mode)'
|
||||
$.concrete('zap', function($){
|
||||
$('#a').concrete({
|
||||
bar: function(){return 'a';}
|
||||
})
|
||||
});
|
||||
$('#a').concrete('zap').bar().should.equal 'a'
|
||||
end
|
||||
|
||||
it 'double-namespaced functions work (block definition mode)'
|
||||
$.concrete('zap', function($){
|
||||
$.concrete('pow', function($){
|
||||
$('#a').concrete({
|
||||
bar: function(){return 'a';}
|
||||
})
|
||||
})
|
||||
})
|
||||
$('#a').concrete('zap.pow').bar().should.equal 'a'
|
||||
end
|
||||
|
||||
it 'revert to base namespacing work (block definition mode)'
|
||||
$.concrete('zap', function($){
|
||||
$.concrete('.pow', function($){
|
||||
$('#a').concrete({
|
||||
bar: function(){return 'a';}
|
||||
})
|
||||
})
|
||||
})
|
||||
$('#a').concrete('pow').bar().should.equal 'a'
|
||||
end
|
||||
|
||||
it 'internal to namespace, will look up functions in namespace before in base'
|
||||
var res = []
|
||||
$('#a').concrete({
|
||||
foo: function(){res.push(1);},
|
||||
bar: function(){res.push(2); this.foo();}
|
||||
})
|
||||
$('#a').concrete('bar', function($){return{
|
||||
foo: function(){res.push(3);},
|
||||
bar: function(){res.push(4); $(this).foo();}
|
||||
}})
|
||||
|
||||
$('#dom_test div').bar();
|
||||
res.should.eql [2, 1]
|
||||
$('#dom_test div').concrete('bar').bar();
|
||||
res.should.eql [2, 1, 4, 3]
|
||||
end
|
||||
|
||||
it 'internal to namespace, will look up functions in namespace before in base, even in closure'
|
||||
var res = []
|
||||
$('#a').concrete({
|
||||
foo: function(){res.push(1);},
|
||||
bar: function(){res.push(2); this.foo();}
|
||||
})
|
||||
$('#a').concrete('bar', function($){return{
|
||||
foo: function(){res.push(3);},
|
||||
bar: function(){res.push(4); $('#a').each(function(){ $(this).foo(); })}
|
||||
}})
|
||||
|
||||
$('#dom_test div').bar();
|
||||
res.should.eql [2, 1]
|
||||
$('#dom_test div').concrete('bar').bar();
|
||||
res.should.eql [2, 1, 4, 3]
|
||||
end
|
||||
|
||||
it 'internal to namespace, will look up functions in namespace before in base, even in onmatch'
|
||||
var res = []
|
||||
$('#a').concrete({
|
||||
foo: function(){res.push(1);},
|
||||
bar: function(){res.push(2); this.foo();}
|
||||
})
|
||||
$('#a').concrete('bar', function($){return{
|
||||
foo: function(){res.push(3);}
|
||||
}})
|
||||
$('#a.d').concrete('bar', function($){return{
|
||||
onmatch: function(){res.push(4); this.foo();}
|
||||
}})
|
||||
|
||||
$('#dom_test div').bar();
|
||||
res.should.eql [2, 1]
|
||||
|
||||
$('#a').addClass('d');
|
||||
res.should.eql [2, 1, 4, 3]
|
||||
end
|
||||
|
||||
it 'internal to namespace, will look up functions in base when not present in namespace'
|
||||
var res = []
|
||||
$('#a').concrete({
|
||||
foo: function(){res.push(1);},
|
||||
})
|
||||
$('#a').concrete('bar', function($){return{
|
||||
bar: function(){res.push(2); this.foo();}
|
||||
}})
|
||||
$('#dom_test div').concrete('bar').bar();
|
||||
res.should.eql [2, 1]
|
||||
end
|
||||
|
||||
it 'internal to namespace, will not look up functions in base if present in namespace, even when not applicable to selector'
|
||||
var res = []
|
||||
$('#a').concrete('bar', function($){return{
|
||||
foo: function(){this.bar();},
|
||||
}})
|
||||
$('#a').concrete({
|
||||
bar: function(){res.push(1);},
|
||||
})
|
||||
$('span').concrete('bar', function($){return{
|
||||
bar: function(){res.push(2);}
|
||||
}})
|
||||
|
||||
$('#a').concrete('bar').foo()
|
||||
res.should.eql []
|
||||
end
|
||||
|
||||
it 'internal to namespace, can be directed to base namespace'
|
||||
var res = []
|
||||
$('#a').concrete({
|
||||
foo: function(){res.push(1);},
|
||||
bar: function(){res.push(2); this.foo();}
|
||||
})
|
||||
$('#a').concrete('bar', function($){return{
|
||||
foo: function(){res.push(3);},
|
||||
bar: function(){res.push(4); this.foo(); this.concrete('.').foo();}
|
||||
}})
|
||||
$('#dom_test div').bar();
|
||||
res.should.eql [2, 1]
|
||||
$('#dom_test div').concrete('bar').bar();
|
||||
res.should.eql [2, 1, 4, 3, 1]
|
||||
end
|
||||
|
||||
it 'internal to namespace, will look up functions in namespace called the same as a regular jQuery base function'
|
||||
var res = []
|
||||
$('#a').concrete('bar', function($){return{
|
||||
load: function(){res.push(1);},
|
||||
bar: function(){res.push(2); this.load();}
|
||||
}})
|
||||
$('#dom_test div').concrete('bar').bar();
|
||||
res.should.eql [2, 1]
|
||||
end
|
||||
|
||||
it 'internal to namespace, can be directed to regular jQuery base function'
|
||||
var res = []
|
||||
$.fn.testy = function(){ res.push(1); }
|
||||
$('#a').concrete('bar', function($){return{
|
||||
testy: function(){res.push(3);},
|
||||
bar: function(){res.push(2); this.concrete('.').testy();}
|
||||
}})
|
||||
$('#dom_test div').concrete('bar').bar();
|
||||
res.should.eql [2, 1]
|
||||
end
|
||||
|
||||
it 'internal to namespace, can be directed to sub namespace'
|
||||
var res = []
|
||||
$.concrete('zap', function($){
|
||||
$('#a').concrete({
|
||||
foo: function(){ res.push(1); this.concrete('pow').bar(); }
|
||||
})
|
||||
|
||||
$.concrete('pow', function($){
|
||||
$('#a').concrete({
|
||||
bar: function(){ res.push(2); }
|
||||
})
|
||||
})
|
||||
})
|
||||
$('#dom_test div').concrete('zap').foo();
|
||||
res.should.eql [1, 2]
|
||||
end
|
||||
|
||||
it 'internal to namespace, can be directed to unrelated namespace'
|
||||
var res = []
|
||||
$.concrete('zap', function($){
|
||||
$('#a').concrete({
|
||||
foo: function(){ res.push(1); this.concrete('.pow').bar(); }
|
||||
})
|
||||
|
||||
$.concrete('pow', function($){
|
||||
$('#a').concrete({
|
||||
bar: function(){ res.push(2); }
|
||||
})
|
||||
})
|
||||
})
|
||||
$.concrete('pow', function($){
|
||||
$('#a').concrete({
|
||||
bar: function(){ res.push(3); }
|
||||
})
|
||||
})
|
||||
|
||||
$('#dom_test div').concrete('zap').foo();
|
||||
res.should.eql [1, 3]
|
||||
end
|
||||
|
||||
it 'a function passed out of a namespace will remember its namespace'
|
||||
var res = []
|
||||
var func = function(func) {
|
||||
func.call($('#a, #b'));
|
||||
}
|
||||
$('#a, #b').concrete('bar', function($){return{
|
||||
zap: function(){res.push($(this).attr('id'));},
|
||||
bar: function(){res.push(2); func(this.zap);}
|
||||
}})
|
||||
$('#dom_test #a').concrete('bar').bar();
|
||||
res.should.eql [2, 'b', 'a']
|
||||
end
|
||||
|
||||
it 'using block functions'
|
||||
var res = []
|
||||
$('#a').concrete({
|
||||
foo: function(){res.push(1);},
|
||||
})
|
||||
$('#a').concrete('bar', function($){return{
|
||||
foo: function(){res.push(3);},
|
||||
}})
|
||||
|
||||
$('#dom_test div').foo();
|
||||
res.should.eql [1]
|
||||
|
||||
$('#dom_test div').concrete('bar', function($){
|
||||
$(this).foo();
|
||||
})
|
||||
res.should.eql [1, 3]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
77
thirdparty/jquery-concrete/spec/spec.concrete.properties.js
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
|
||||
describe 'Concrete'
|
||||
describe 'Properties'
|
||||
before
|
||||
$('body').append('<div id="dom_test"></div>')
|
||||
end
|
||||
after
|
||||
$('#dom_test').remove()
|
||||
end
|
||||
|
||||
before_each
|
||||
$.concrete.clear_all_rules()
|
||||
$('#dom_test').html('<div id="a" class="a b c"></div><div id="b" class="b c"></div>')
|
||||
end
|
||||
|
||||
it 'can define and get a basic property'
|
||||
$('#a').concrete({
|
||||
Foo: null
|
||||
});
|
||||
$('.a').getFoo().should.be_null
|
||||
end
|
||||
|
||||
it 'can define and set a basic property'
|
||||
$('#a').concrete({
|
||||
Foo: null
|
||||
});
|
||||
$('.a').setFoo(1);
|
||||
$('.a').getFoo().should.equal 1
|
||||
end
|
||||
|
||||
it 'can define a default value'
|
||||
$('#a').concrete({
|
||||
Foo: 1
|
||||
});
|
||||
$('.a').getFoo().should.equal 1
|
||||
end
|
||||
|
||||
it 'should manage proprties in namespaces without clashing'
|
||||
$('#a').concrete({
|
||||
Foo: 1
|
||||
});
|
||||
|
||||
$.concrete('test', function($){
|
||||
$('#a').concrete({
|
||||
Foo: 2
|
||||
});
|
||||
});
|
||||
|
||||
$('.a').getFoo().should.equal 1
|
||||
$('.a').concrete('test').getFoo().should.equal 2
|
||||
|
||||
$('.a').setFoo(4);
|
||||
$('.a').concrete('test').setFoo(8);
|
||||
|
||||
$('.a').getFoo().should.equal 4
|
||||
$('.a').concrete('test').getFoo().should.equal 8
|
||||
end
|
||||
|
||||
it 'should manage directly setting proprties in namespaces without clashing'
|
||||
$('#a').concrete({
|
||||
Foo: null
|
||||
});
|
||||
|
||||
$.concrete('test', function($){
|
||||
$('#a').concrete({
|
||||
Foo: null
|
||||
});
|
||||
});
|
||||
|
||||
$('.a').concreteData('Foo', 4);
|
||||
$('.a').concrete('test').concreteData('Foo', 8);
|
||||
|
||||
$('.a').concreteData('Foo').should.equal 4
|
||||
$('.a').concrete('test').concreteData('Foo').should.equal 8
|
||||
end
|
||||
end
|
||||
end
|
54
thirdparty/jquery-concrete/spec/spec.concrete.super.js
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
describe 'Concrete'
|
||||
describe 'Super'
|
||||
before
|
||||
$('body').append('<div id="dom_test"></div>')
|
||||
end
|
||||
after
|
||||
$('#dom_test').remove()
|
||||
end
|
||||
|
||||
before_each
|
||||
$.concrete.clear_all_rules()
|
||||
$('#dom_test').html('<div id="a" class="a b c"></div><div id="b" class="c d e"></div>')
|
||||
end
|
||||
|
||||
it 'can call the super function'
|
||||
var a = 1;
|
||||
$('#a').concrete({
|
||||
foo: function(){a *= 2;}
|
||||
});
|
||||
$('#a.a').concrete({
|
||||
foo: function(){a += 2; this._super();}
|
||||
});
|
||||
$('#a').foo();
|
||||
a.should.equal 6
|
||||
end
|
||||
|
||||
it 'super to a non-existant class should be ignored'
|
||||
var a = 1;
|
||||
$('#a').concrete({
|
||||
foo: function(){a *= 2; this._super();}
|
||||
});
|
||||
$('#a.a').concrete({
|
||||
foo: function(){a += 2; this._super();}
|
||||
});
|
||||
$('#a').foo();
|
||||
a.should.equal 6
|
||||
end
|
||||
|
||||
it 'can call super from two different functions without screwing up what super points to'
|
||||
var list = [];
|
||||
$('#a').concrete({
|
||||
foo: function(){ list.push('foo'); this.bar(); },
|
||||
bar: function(){ list.push('bar'); }
|
||||
});
|
||||
$('#a.a').concrete({
|
||||
foo: function(){ list.push('foo2'); this._super(); list.push('foo2'); this._super(); },
|
||||
bar: function(){ list.push('bar2'); this._super(); }
|
||||
});
|
||||
$('#a').foo();
|
||||
list.should.eql [ 'foo2', 'foo', 'bar2', 'bar', 'foo2', 'foo', 'bar2', 'bar' ]
|
||||
end
|
||||
end
|
||||
end
|
38
thirdparty/jquery-concrete/spec/spec.html
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<html>
|
||||
<head>
|
||||
<link type="text/css" rel="stylesheet" href="../vendor/jspec/lib/jspec.css" />
|
||||
<script src="../vendor/jquery-1.3.2.js"></script>
|
||||
<script src="../vendor/jspec/lib/jspec.js"></script>
|
||||
<script src="../vendor/jspec/lib/jspec.jquery.js"></script>
|
||||
|
||||
<script src="../vendor/jquery.selector/jquery.class.js"></script>
|
||||
<script src="../vendor/jquery.selector/jquery.selector.js"></script>
|
||||
<script src="../vendor/jquery.selector/jquery.selector.specifity.js"></script>
|
||||
<script src="../vendor/jquery.selector/jquery.selector.matches.js"></script>
|
||||
|
||||
<script src="../src/jquery.concrete.js"></script>
|
||||
<script src="../src/jquery.concrete.dommaybechanged.js"></script>
|
||||
<script src="../src/jquery.concrete.events.js"></script>
|
||||
<script src="../src/jquery.concrete.ctors.js"></script>
|
||||
<script src="../src/jquery.concrete.properties.js"></script>
|
||||
|
||||
<script>
|
||||
function runSuites() {
|
||||
JSpec
|
||||
.exec('spec.concrete.basics.js')
|
||||
.exec('spec.concrete.namespaces.js')
|
||||
.exec('spec.concrete.super.js')
|
||||
.exec('spec.concrete.events.js')
|
||||
.exec('spec.concrete.ctors.js')
|
||||
.exec('spec.concrete.properties.js')
|
||||
.run()
|
||||
.report()
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="jspec" onLoad="runSuites();">
|
||||
<div id="jspec-top"><h2 id="jspec-title">JSpec <em><script>document.write(JSpec.version)</script></em></h2></div>
|
||||
<div id="jspec"><div class="loading"></div></div>
|
||||
<div id="jspec-bottom"></div>
|
||||
</body>
|
||||
</html>
|
102
thirdparty/jquery-concrete/src/jquery.concrete.ctors.js
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
(function($) {
|
||||
|
||||
/* Add the methods to handle constructor & destructor binding to the Namespace class */
|
||||
$.concrete.Namespace.addMethods({
|
||||
bind_condesc: function(selector, name, func) {
|
||||
var ctors = this.store.ctors || (this.store.ctors = $.concrete.RuleList()) ;
|
||||
|
||||
var rule;
|
||||
for (var i = 0 ; i < ctors.length; i++) {
|
||||
if (ctors[i].selector.selector == selector.selector) {
|
||||
rule = ctors[i]; break;
|
||||
}
|
||||
}
|
||||
if (!rule) {
|
||||
rule = ctors.addRule(selector, 'ctors');
|
||||
}
|
||||
|
||||
rule[name] = func;
|
||||
|
||||
if (!ctors[name+'proxy']) {
|
||||
var one = this.one('ctors', name);
|
||||
var namespace = this;
|
||||
|
||||
var proxy = function(els, i, func) {
|
||||
var j = els.length;
|
||||
while (j--) {
|
||||
var el = els[j];
|
||||
|
||||
var tmp_i = el.i, tmp_f = el.f;
|
||||
el.i = i; el.f = one;
|
||||
try { func.call(namespace.$(el)); }
|
||||
catch(e) { el.i = tmp_i; el.f = tmp_f; }
|
||||
}
|
||||
}
|
||||
|
||||
ctors[name+'proxy'] = proxy;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 30,
|
||||
|
||||
bind: function(selector, k, v) {
|
||||
if ($.isFunction(v) && (k == 'onmatch' || k == 'onunmatch')) {
|
||||
this.bind_condesc(selector, k, v);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Finds all the elements that now match a different rule (or have been removed) and call onmatch on onunmatch as appropriate
|
||||
*
|
||||
* Because this has to scan the DOM, and is therefore fairly slow, this is normally triggered off a short timeout, so that
|
||||
* a series of DOM manipulations will only trigger this once.
|
||||
*
|
||||
* The downside of this is that things like:
|
||||
* $('#foo').addClass('tabs'); $('#foo').tabFunctionBar();
|
||||
* won't work.
|
||||
*/
|
||||
$(document).bind('DOMMaybeChanged', function(){
|
||||
// For every namespace
|
||||
for (var k in $.concrete.namespaces) {
|
||||
// That has constructors or destructors
|
||||
var ctors = $.concrete.namespaces[k].store.ctors;
|
||||
if (ctors) {
|
||||
|
||||
// Keep a record of elements that have matched already
|
||||
var matched = $([]), match, add, rem;
|
||||
// Stepping through each selector from most to least specific
|
||||
var j = ctors.length;
|
||||
while (j--) {
|
||||
// Build some quick-acccess variables
|
||||
var sel = ctors[j].selector.selector, ctor = ctors[j].onmatch; dtor = ctors[j].onunmatch;
|
||||
// Get the list of elements that match this selector, that haven't yet matched a more specific selector
|
||||
res = add = $(sel).not(matched);
|
||||
|
||||
// If this selector has a list of elements it matched against last time
|
||||
if (ctors[j].cache) {
|
||||
// Find the ones that are extra this time
|
||||
add = res.not(ctors[j].cache);
|
||||
// Find the ones that are gone this time
|
||||
rem = ctors[j].cache.not(res);
|
||||
// And call the desctructor on them
|
||||
if (rem.length && dtor) ctors.onunmatchproxy(rem, j, dtor);
|
||||
}
|
||||
|
||||
// Call the constructor on the newly matched ones
|
||||
if (add.length && ctor) ctors.onmatchproxy(add, j, ctor);
|
||||
|
||||
// Add these matched ones to the list tracking all elements matched so far
|
||||
matched = matched.add(res);
|
||||
// And remember this list of matching elements again this selector, so next matching we can find the unmatched ones
|
||||
ctors[j].cache = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
})(jQuery);
|
64
thirdparty/jquery-concrete/src/jquery.concrete.dommaybechanged.js
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
(function($){
|
||||
|
||||
/** What to call to run a function 'soon'. Normally setTimeout, but for syncronous mode we override so soon === now */
|
||||
var runSoon = window.setTimeout;
|
||||
|
||||
/** The timer handle for the asyncronous matching call */
|
||||
var check_id = null;
|
||||
|
||||
/** Fire the change event. Only fires on the document node, so bind to that */
|
||||
var triggerEvent = function() {
|
||||
$(document).triggerHandler('DOMMaybeChanged');
|
||||
check_id = null;
|
||||
}
|
||||
|
||||
$.extend($.concrete, {
|
||||
/**
|
||||
* Make onmatch and onunmatch work in synchronous mode - that is, new elements will be detected immediately after
|
||||
* the DOM manipulation that made them match. This is only really useful for during testing, since it's pretty slow
|
||||
* (otherwise we'd make it the default).
|
||||
*/
|
||||
synchronous_mode: function() {
|
||||
if (check_id) clearTimeout(check_id); check_id = null;
|
||||
runSoon = function(func, delay){ func.call(this); return null; }
|
||||
},
|
||||
|
||||
/**
|
||||
* Trigger onmatch and onunmatch now - usefull for after DOM manipulation by methods other than through jQuery.
|
||||
* Called automatically on document.ready
|
||||
*/
|
||||
triggerMatching: function() {
|
||||
matching();
|
||||
}
|
||||
});
|
||||
|
||||
function registerMutateFunction() {
|
||||
$.each(arguments, function(i,func){
|
||||
var old = $.fn[func];
|
||||
$.fn[func] = function() {
|
||||
var rv = old.apply(this, arguments);
|
||||
if (!check_id) check_id = runSoon(triggerEvent, 100);
|
||||
return rv;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function registerSetterGetterFunction() {
|
||||
$.each(arguments, function(i,func){
|
||||
var old = $.fn[func];
|
||||
$.fn[func] = function(a, b) {
|
||||
var rv = old.apply(this, arguments);
|
||||
if (!check_id && (b !== undefined || typeof a != 'string')) check_id = runSoon(triggerEvent, 100);
|
||||
return rv;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Register core DOM manipulation methods
|
||||
registerMutateFunction('append', 'prepend', 'after', 'before', 'wrap', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');
|
||||
registerSetterGetterFunction('attr');
|
||||
|
||||
// And on DOM ready, trigger matching once
|
||||
$(function(){ triggerEvent(); })
|
||||
|
||||
})(jQuery);
|
169
thirdparty/jquery-concrete/src/jquery.concrete.events.js
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
(function($) {
|
||||
|
||||
/* If we are any browser other than IE or Safari, we don't have to do anything special to handle
|
||||
* onchange delegation */
|
||||
$.support.bubblingChange = !($.browser.msie || $.browser.safari);
|
||||
|
||||
/* Return true if node b is the same as, or is a descendant of, node a */
|
||||
if (document.compareDocumentPosition) {
|
||||
var is_or_contains = function(a, b) {
|
||||
return a && b && (a == b || !!(a.compareDocumentPosition(b) & 16));
|
||||
}
|
||||
}
|
||||
else {
|
||||
var is_or_contains = function(a, b) {
|
||||
return a && b && (a == b || (a.contains ? a.contains(b) : true));
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the methods to handle event binding to the Namespace class */
|
||||
$.concrete.Namespace.addMethods({
|
||||
build_event_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function(e, originalevent) {
|
||||
e = originalevent || e;
|
||||
|
||||
var el = e.target;
|
||||
while (el && el != document && !e.isPropagationStopped()) {
|
||||
var ret = one(el, arguments);
|
||||
if (ret !== undefined) e.result = ret;
|
||||
if (ret === false) { e.preventDefault(); e.stopPropagation(); }
|
||||
|
||||
el = el.parentNode;
|
||||
}
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
build_mouseenterleave_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function(e) {
|
||||
var el = e.target;
|
||||
var rel = e.relatedTarget;
|
||||
|
||||
while (el && el != document && !e.isPropagationStopped()) {
|
||||
/* We know el contained target. If it also contains relatedTarget then we didn't mouseenter / leave. What's more, every ancestor will also
|
||||
contan el and rel, and so we can just stop bubbling */
|
||||
if (is_or_contains(el, rel)) break;
|
||||
|
||||
var ret = one(el, arguments);
|
||||
if (ret !== undefined) e.result = ret;
|
||||
if (ret === false) { e.preventDefault(); e.stopPropagation(); }
|
||||
|
||||
el = el.parentNode;
|
||||
}
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
build_change_proxy: function(name) {
|
||||
var one = this.one(name, 'func');
|
||||
|
||||
var prxy = function(e) {
|
||||
var el = e.target;
|
||||
// If this is a keydown event, only worry about the enter key, since browsers only trigger onchange on enter or focus loss
|
||||
if (e.type === 'keydown' && e.keyCode !== 13) return;
|
||||
// Make sure this is event is for an input type we're interested in
|
||||
if (el.tagName !== 'INPUT' && el.tagName !== 'TEXTAREA' && el.tagName !== 'SELECT') return;
|
||||
|
||||
var $el = $(el), nowVal, oldVal = $el.data('changeVal');
|
||||
|
||||
// Detect changes on checkboxes & radiobuttons, which have different value logic. We don't use el.value, since el is part
|
||||
// of a set, and we only want to raise onchange once for a single user action.
|
||||
if (el.type == 'checkbox' || el.type == 'radio') {
|
||||
if (!el.disabled && e.type === 'click') {
|
||||
nowVal = el.checked;
|
||||
// If radio, we get two changes - the activation, and the deactivation. We only want to fire one change though
|
||||
if ((el.type === 'checkbox' || nowVal === true) && oldVal !== nowVal) e.type = 'change';
|
||||
}
|
||||
}
|
||||
// Detect changes on other input types. In this case value is OK.
|
||||
else {
|
||||
nowVal = el.value;
|
||||
if (oldVal !== undefined && oldVal !== nowVal) e.type = 'change';
|
||||
}
|
||||
|
||||
// Save the current value for next time
|
||||
if (nowVal !== undefined) $el.data('changeVal', nowVal);
|
||||
|
||||
// And if we decided that a change happened, do the actual triggering
|
||||
if (e.type == 'change') {
|
||||
while (el && el != document && !e.isPropagationStopped()) {
|
||||
var ret = one(el, arguments);
|
||||
if (ret !== undefined) e.result = ret;
|
||||
if (ret === false) { e.preventDefault(); e.stopPropagation(); }
|
||||
|
||||
el = el.parentNode;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return prxy;
|
||||
},
|
||||
|
||||
bind_event: function(selector, name, func, event) {
|
||||
var funcs = this.store[name] || (this.store[name] = $.concrete.RuleList()) ;
|
||||
var proxies = funcs.proxies || (funcs.proxies = {});
|
||||
|
||||
var rule = funcs.addRule(selector, name); rule.func = func;
|
||||
|
||||
if (!proxies[name]) {
|
||||
switch (name) {
|
||||
case 'onmouseenter':
|
||||
proxies[name] = this.build_mouseenterleave_proxy(name);
|
||||
event = 'mouseover';
|
||||
break;
|
||||
case 'onmouseleave':
|
||||
proxies[name] = this.build_mouseenterleave_proxy(name);
|
||||
event = 'mouseout';
|
||||
break;
|
||||
case 'onchange':
|
||||
if (!$.support.bubblingChange) {
|
||||
proxies[name] = this.build_change_proxy(name);
|
||||
event = 'click focusin focusout keydown';
|
||||
}
|
||||
break;
|
||||
case 'onsubmit':
|
||||
event = 'delegated_submit';
|
||||
case 'onfocus':
|
||||
case 'onblur':
|
||||
$.concrete.warn('Event '+event+' not supported - using focusin / focusout instead', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
|
||||
if (!proxies[name]) proxies[name] = this.build_event_proxy(name);
|
||||
$(document).bind(event, proxies[name]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 40,
|
||||
|
||||
bind: function(selector, k, v){
|
||||
if ($.isFunction(v) && (match = k.match(/^on(.*)/))) {
|
||||
event = match[1];
|
||||
this.bind_event(selector, k, v, event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Find all forms and bind onsubmit to trigger on the document too. This is the only event that can't be grabbed via delegation.
|
||||
|
||||
var form_binding_cache = $([]); // A cache for already-handled form elements
|
||||
var delegate_submit = function(e){ $(document).triggerHandler('delegated_submit', e); } // The function that handles the delegation
|
||||
|
||||
$(document).bind('DOMMaybeChanged', function(){
|
||||
var forms = $('form');
|
||||
// Only bind to forms we haven't processed yet
|
||||
forms.not(form_binding_cache).bind('submit', delegate_submit);
|
||||
// Then remember the current set of forms
|
||||
form_binding_cache = forms;
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
485
thirdparty/jquery-concrete/src/jquery.concrete.js
vendored
@ -2,70 +2,54 @@ var console;
|
||||
|
||||
(function($) {
|
||||
|
||||
/** What to call to run a function 'soon'. Normally setTimeout, but for syncronous mode we override so soon === now */
|
||||
var runSoon = window.setTimeout;
|
||||
var namespaces = {};
|
||||
|
||||
/** Stores a count of definitions, so that we can sort identical selectors by definition order */
|
||||
var rulecount = 0;
|
||||
$.concrete = function() {
|
||||
$.fn.concrete.apply(null, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* A couple of utility functions for accessing the store outside of this closure, and for making things
|
||||
* operate in a little more easy-to-test manner
|
||||
*/
|
||||
$.extend($.concrete, {
|
||||
/**
|
||||
* Get all the namespaces. Useful for introspection? Internal interface of Namespace not guaranteed consistant
|
||||
*/
|
||||
namespaces: namespaces,
|
||||
|
||||
/**
|
||||
* Remove all concrete rules
|
||||
*/
|
||||
clear_all_rules: function() {
|
||||
// Remove proxy functions
|
||||
for (var k in $.fn) { if ($.fn[k].concrete) delete $.fn[k] ; }
|
||||
// Remove namespaces, and start over again
|
||||
namespaces = $.concrete.namespaces = {};
|
||||
},
|
||||
|
||||
WARN_LEVEL_NONE: 0,
|
||||
WARN_LEVEL_IMPORTANT: 1,
|
||||
WARN_LEVEL_BESTPRACTISE: 2,
|
||||
|
||||
/**
|
||||
* Warning level. Set to a higher level to get warnings dumped to console.
|
||||
*/
|
||||
warningLevel: 0,
|
||||
|
||||
/** Utility to optionally display warning messages depending on level */
|
||||
var warn = function(message, level) {
|
||||
warn: function(message, level) {
|
||||
if (level <= $.concrete.warningLevel && console && console.log) {
|
||||
console.warn(message);
|
||||
if (console.trace) console.trace();
|
||||
}
|
||||
}
|
||||
|
||||
/** A property definition */
|
||||
$.property = function(options) {
|
||||
if (this instanceof $.property) this.options = options;
|
||||
else return new $.property(options);
|
||||
}
|
||||
$.extend($.property, {
|
||||
/**
|
||||
* Strings for how to cast a value to a specific type. Used in some nasty meta-programming stuff below to try and
|
||||
* keep property access as fast as possible
|
||||
*/
|
||||
casters: {
|
||||
'int': 'Math.round(parseFloat(v));',
|
||||
'float': 'parseFloat(v);',
|
||||
'string': '""+v;'
|
||||
},
|
||||
|
||||
getter: function(options) {
|
||||
options = options || {};
|
||||
|
||||
if (options.initial === undefined) return function(){ return this.d()[arguments.callee.pname] };
|
||||
|
||||
var getter = function(){
|
||||
var d = this.d(); var k = arguments.callee.pname;
|
||||
return d.hasOwnProperty(k) ? d[k] : (d[k] = arguments.callee.initial);
|
||||
};
|
||||
var v = options.initial;
|
||||
getter.initial = options.restrict ? eval($.property.casters[options.restrict]) : v;
|
||||
|
||||
return getter;
|
||||
},
|
||||
|
||||
setter: function(options){
|
||||
options = options || {};
|
||||
if (options.restrict) {
|
||||
var restrict = options.restrict;
|
||||
return new Function('v', 'return this.d()[arguments.callee.pname] = ' + $.property.casters[options.restrict]);
|
||||
}
|
||||
|
||||
return function(v){ return this.d()[arguments.callee.pname] = v; }
|
||||
}
|
||||
});
|
||||
$.extend($.property.prototype, {
|
||||
getter: function(){
|
||||
return $.property.getter(this.options);
|
||||
},
|
||||
setter: function(){
|
||||
return $.property.setter(this.options);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/** Stores a count of definitions, so that we can sort identical selectors by definition order */
|
||||
var rulecount = 0;
|
||||
|
||||
var Rule = Base.extend({
|
||||
init: function(selector, name) {
|
||||
this.selector = selector;
|
||||
@ -86,20 +70,29 @@ var console;
|
||||
(a.rulecount - b.rulecount) ;
|
||||
}
|
||||
|
||||
$.fn._super = function(){
|
||||
var rv, i = this.length;
|
||||
while (i--) {
|
||||
var el = this[0];
|
||||
rv = el.f(el, arguments, el.i);
|
||||
}
|
||||
return rv;
|
||||
$.concrete.RuleList = function() {
|
||||
var list = [];
|
||||
|
||||
list.addRule = function(selector, name){
|
||||
var rule = Rule(selector, name);
|
||||
|
||||
list[list.length] = rule;
|
||||
list.sort(Rule.compare);
|
||||
|
||||
return rule;
|
||||
};
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
var namespaces = {};
|
||||
var handlers = [];
|
||||
|
||||
var Namespace = Base.extend({
|
||||
/**
|
||||
* A Namespace holds all the information needed for adding concrete methods to a namespace (including the _null_ namespace)
|
||||
*/
|
||||
$.concrete.Namespace = Base.extend({
|
||||
init: function(name){
|
||||
if (name && !name.match(/^[A-Za-z0-9.]+$/)) warn('Concrete namespace '+name+' is not formatted as period seperated identifiers', $.concrete.WARN_LEVEL_BESTPRACTISE);
|
||||
if (name && !name.match(/^[A-Za-z0-9.]+$/)) $.concrete.warn('Concrete namespace '+name+' is not formatted as period seperated identifiers', $.concrete.WARN_LEVEL_BESTPRACTISE);
|
||||
name = name || '__base';
|
||||
|
||||
this.name = name;
|
||||
@ -113,18 +106,68 @@ var console;
|
||||
}
|
||||
else {
|
||||
// We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into
|
||||
var subfn = function(jq){
|
||||
this.selector = jq.selector; this.context = jq.context; this.setArray($.makeArray(jq));
|
||||
}
|
||||
var subfn = function(){}
|
||||
this.injectee = subfn.prototype = new $();
|
||||
|
||||
// And then we provide an overriding $ that returns objects of our new Class
|
||||
this.$ = function() {
|
||||
return new subfn($.apply(window, arguments));
|
||||
// And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building
|
||||
var bound$ = this.$ = function(a) {
|
||||
// Try the simple way first
|
||||
var jq = $.fn.init.apply(new subfn(), arguments);
|
||||
if (jq instanceof subfn) return jq;
|
||||
|
||||
// That didn't return a bound object, so now we need to copy it
|
||||
var rv = new subfn();
|
||||
rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length;
|
||||
while (i--) rv[i] = jq[i];
|
||||
return rv;
|
||||
}
|
||||
this.injectee.pushStack = function(elems, name, selector){
|
||||
var ret = bound$(elems);
|
||||
|
||||
// Add the old object onto the stack (as a reference)
|
||||
ret.prevObject = this;
|
||||
ret.context = this.context;
|
||||
|
||||
if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector;
|
||||
else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")";
|
||||
|
||||
// Return the newly-formed element set
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Copy static functions through from $ to this.$ so e.g. $.ajax still works
|
||||
// @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through
|
||||
$.extend(this.$, $);
|
||||
|
||||
// We override concrete to inject the name of this namespace when defining blocks inside this namespace
|
||||
var concrete_wrapper = this.injectee.concrete = function(spacename) {
|
||||
var args = arguments;
|
||||
|
||||
if (!spacename || typeof spacename != 'string') { args = $.makeArray(args); args.unshift(name); }
|
||||
else if (spacename.charAt(0) != '.') args[0] = name+'.'+spacename;
|
||||
|
||||
return $.fn.concrete.apply(this, args);
|
||||
}
|
||||
|
||||
this.$.concrete = function() {
|
||||
concrete_wrapper.apply(null, arguments);
|
||||
}
|
||||
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
var handler = handlers[i], builder;
|
||||
|
||||
// Inject jQuery object method overrides
|
||||
if (builder = handler.namespaceMethodOverrides) {
|
||||
var overrides = builder(this);
|
||||
for (var k in overrides) this.injectee[k] = overrides[k];
|
||||
}
|
||||
|
||||
// Inject $.concrete function overrides
|
||||
if (builder = handler.namespaceStaticOverrides) {
|
||||
var overrides = builder(this);
|
||||
for (var k in overrides) this.$.concrete[k] = overrides[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -174,10 +217,9 @@ var console;
|
||||
},
|
||||
|
||||
bind_proxy: function(selector, name, func) {
|
||||
var funcs = this.store[name] || (this.store[name] = []) ;
|
||||
var rulelist = this.store[name] || (this.store[name] = $.concrete.RuleList());
|
||||
|
||||
var rule = funcs[funcs.length] = Rule(selector, name); rule.func = func;
|
||||
funcs.sort(Rule.compare);
|
||||
var rule = rulelist.addRule(selector, name); rule.func = func;
|
||||
|
||||
if (!this.injectee.hasOwnProperty(name)) {
|
||||
this.injectee[name] = this.build_proxy(name);
|
||||
@ -185,102 +227,17 @@ var console;
|
||||
}
|
||||
|
||||
if (!this.injectee[name].concrete) {
|
||||
warn('Warning: Concrete function '+name+' clashes with regular jQuery function - concrete function will not be callable directly on jQuery object', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
},
|
||||
|
||||
bind_event: function(selector, name, func, event) {
|
||||
var funcs = this.store[name] || (this.store[name] = []) ;
|
||||
|
||||
var rule = funcs[funcs.length] = Rule(selector, name); rule.func = func;
|
||||
funcs.sort(Rule.compare);
|
||||
|
||||
if (!funcs.proxy) {
|
||||
funcs.proxy = this.build_proxy(name);
|
||||
$(selector.selector).live(event, funcs.proxy);
|
||||
}
|
||||
},
|
||||
|
||||
bind_condesc: function(selector, name, func) {
|
||||
var ctors = this.store.ctors || (this.store.ctors = []) ;
|
||||
|
||||
var rule;
|
||||
for (var i = 0 ; i < ctors.length; i++) {
|
||||
if (ctors[i].selector.selector == selector.selector) {
|
||||
rule = ctors[i]; break;
|
||||
}
|
||||
}
|
||||
if (!rule) {
|
||||
rule = ctors[ctors.length] = Rule(selector, 'ctors');
|
||||
ctors.sort(Rule.compare);
|
||||
}
|
||||
|
||||
rule[name] = func;
|
||||
|
||||
if (!ctors[name+'proxy']) {
|
||||
var one = this.one('ctors', name);
|
||||
var namespace = this;
|
||||
|
||||
var proxy = function(els, i, func) {
|
||||
var j = els.length;
|
||||
while (j--) {
|
||||
var el = els[j];
|
||||
|
||||
var tmp_i = el.i, tmp_f = el.f;
|
||||
el.i = i; el.f = one;
|
||||
try { func.call(namespace.$(el)); }
|
||||
catch(e) { el.i = tmp_i; el.f = tmp_f; }
|
||||
}
|
||||
}
|
||||
|
||||
ctors[name+'proxy'] = proxy;
|
||||
$.concrete.warn('Warning: Concrete function '+name+' clashes with regular jQuery function - concrete function will not be callable directly on jQuery object', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
},
|
||||
|
||||
add: function(selector, data) {
|
||||
var k, v, match, event;
|
||||
// For every item in the hash, try ever method handler, until one returns true
|
||||
for (var k in data) {
|
||||
var v = data[k];
|
||||
|
||||
for (k in data) {
|
||||
v = data[k];
|
||||
|
||||
if ($.isFunction(v)) {
|
||||
if (k == 'onmatch' || k == 'onunmatch') {
|
||||
this.bind_condesc(selector, k, v);
|
||||
}
|
||||
else if (match = k.match(/^on(.*)/)) {
|
||||
event = match[1];
|
||||
|
||||
if (!$.fn.liveHover && $.concrete.event_needs_extensions[event]) {
|
||||
warn('Event '+event+' requires live-extensions to function, which does not seem to be present', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
else if (event == 'submit') {
|
||||
warn('Event submit not currently supported', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
else if (event == 'focus' || event == 'blur') {
|
||||
warn('Event '+event+' not supported - use focusin / focusout instead', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
|
||||
this.bind_event(selector, k, v, event);
|
||||
}
|
||||
else {
|
||||
this.bind_proxy(selector, k, v);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var g, s, p;
|
||||
|
||||
if (k.charAt(0) != k.charAt(0).toUpperCase()) warn('Concrete property '+k+' does not start with a capital letter', $.concrete.WARN_LEVEL_BESTPRACTISE);
|
||||
|
||||
if (v == $.property || v instanceof $.property) {
|
||||
g = v.getter(); s = v.setter();
|
||||
}
|
||||
else {
|
||||
p = $.property({initial: v}); g = p.getter(); s = p.setter();
|
||||
}
|
||||
|
||||
g.pname = s.pname = k;
|
||||
this.bind_proxy(selector, k, g);
|
||||
this.bind_proxy(selector, 'set'+k, s);
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
if (handlers[i].bind && handlers[i].bind.call(this, selector, k, v)) break;
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -298,171 +255,79 @@ var console;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* The default handlers provided (and included by default) are event, ctor and properties
|
||||
*/
|
||||
$.concrete.Namespace.addHandler = function(handler) {
|
||||
for (var i = 0; i < handlers.length && handlers[i].order < handler.order; i++) { /* Pass */ }
|
||||
handlers.splice(i, 0, handler);
|
||||
}
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 50,
|
||||
|
||||
bind: function(selector, k, v){
|
||||
if ($.isFunction(v)) {
|
||||
this.bind_proxy(selector, k, v);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.extend($.fn, {
|
||||
/**
|
||||
* Main concrete function. Used for new definitions, calling into a namespace (or forcing the base namespace) and entering a using block
|
||||
*
|
||||
*/
|
||||
$.fn.concrete = function() {
|
||||
concrete: function(spacename) {
|
||||
var i = 0;
|
||||
var selector = $.selector(this.selector);
|
||||
var selector = this.selector ? $.selector(this.selector) : null;
|
||||
|
||||
var namespace = namespaces.__base || Namespace();
|
||||
if (typeof arguments[i] == 'string') {
|
||||
namespace = namespaces[arguments[i]] || Namespace(arguments[i]);
|
||||
i++;
|
||||
/* By default we operator on the base namespace */
|
||||
var namespace = namespaces.__base || $.concrete.Namespace();
|
||||
|
||||
/* If the first argument is a string, then it's the name of a namespace. Look it up */
|
||||
if (typeof spacename == 'string') {
|
||||
if (spacename.charAt('0') == '.') spacename = spacename.substr(1);
|
||||
if (spacename) namespace = namespaces[spacename] || $.concrete.Namespace(spacename);
|
||||
i=1;
|
||||
}
|
||||
|
||||
/* All remaining arguments should either be using blocks or definition hashs */
|
||||
while (i < arguments.length) {
|
||||
var res = arguments[i];
|
||||
// If it's a function, call it - either it's a using block or it's a concrete definition builder
|
||||
var res = arguments[i++];
|
||||
|
||||
// If it's a function, call it - either it's a using block or it's a namespaced concrete definition
|
||||
if ($.isFunction(res)) {
|
||||
if (res.length != 1) warn('Function block inside concrete definition does not take $ argument properly', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
res = res.call(this, namespace.$);
|
||||
}
|
||||
else if (namespace.name != '__base') warn('Raw object inside namespaced ('+namespace.name+') concrete definition - namespace lookup will not work properly', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
|
||||
// Now if we still have a concrete definition object, inject it into namespace
|
||||
if (res) namespace.add(selector, res);
|
||||
i++
|
||||
if (res.length != 1) $.concrete.warn('Function block inside concrete definition does not take $ argument properly', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
res = res.call(namespace.$(this), namespace.$);
|
||||
}
|
||||
|
||||
// If we have a concrete definition hash, inject it into namespace
|
||||
if (res) {
|
||||
if (selector) namespace.add(selector, res);
|
||||
else $.concrete.warn('Concrete block given to concrete call without selector. Make sure you call $(selector).concrete when defining blocks', $.concrete.WARN_LEVEL_IMPORTANT);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Finally, return the jQuery object 'this' refers to, wrapped in the new namespace */
|
||||
return namespace.$(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* A couple of utility functions for accessing the store outside of this closure, and for making things
|
||||
* operate in a little more easy-to-test manner
|
||||
*/
|
||||
$.concrete = {
|
||||
|
||||
/**
|
||||
* Get all the namespaces. Usefull for introspection? Internal interface of Namespace not guaranteed consistant
|
||||
*/
|
||||
namespaces: function() { return namespaces; },
|
||||
|
||||
/**
|
||||
* Remove all concrete rules
|
||||
*/
|
||||
clear_all_rules: function() {
|
||||
// Remove proxy functions
|
||||
for (var k in $.fn) { if ($.fn[k].concrete) delete $.fn[k] ; }
|
||||
// Remove namespaces, and start over again
|
||||
namespaces = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Make onmatch and onunmatch work in synchronous mode - that is, new elements will be detected immediately after
|
||||
* the DOM manipulation that made them match. This is only really useful for during testing, since it's pretty slow
|
||||
* (otherwise we'd make it the default).
|
||||
* Calls the next most specific version of the current concrete method
|
||||
*/
|
||||
synchronous_mode: function() {
|
||||
if (check_id) clearTimeout(check_id); check_id = null;
|
||||
runSoon = function(func, delay){ func.call(this); return null; }
|
||||
},
|
||||
|
||||
/**
|
||||
* Trigger onmatch and onunmatch now - usefull for after DOM manipulation by methods other than through jQuery.
|
||||
* Called automatically on document.ready
|
||||
*/
|
||||
triggerMatching: function() {
|
||||
matching();
|
||||
},
|
||||
|
||||
WARN_LEVEL_NONE: 0,
|
||||
WARN_LEVEL_IMPORTANT: 1,
|
||||
WARN_LEVEL_BESTPRACTISE: 2,
|
||||
|
||||
/**
|
||||
* Warning level. Set to a higher level to get warnings dumped to console.
|
||||
*/
|
||||
warningLevel: 0,
|
||||
|
||||
/**
|
||||
* These events need the live-extensions plugin
|
||||
*/
|
||||
event_needs_extensions: { mouseenter: true, mouseleave: true, change: true, focusin: true, focusout: true }
|
||||
_super: function(){
|
||||
var rv, i = this.length;
|
||||
while (i--) {
|
||||
var el = this[0];
|
||||
rv = el.f(el, arguments, el.i);
|
||||
}
|
||||
|
||||
var check_id = null;
|
||||
|
||||
/**
|
||||
* Finds all the elements that now match a different rule (or have been removed) and call onmatch on onunmatch as appropriate
|
||||
*
|
||||
* Because this has to scan the DOM, and is therefore fairly slow, this is normally triggered off a short timeout, so that
|
||||
* a series of DOM manipulations will only trigger this once.
|
||||
*
|
||||
* The downside of this is that things like:
|
||||
* $('#foo').addClass('tabs'); $('#foo').tabFunctionBar();
|
||||
* won't work.
|
||||
*/
|
||||
function matching() {
|
||||
// For every namespace
|
||||
for (var k in namespaces) {
|
||||
// That has constructors or destructors
|
||||
var ctors = namespaces[k].store.ctors;
|
||||
if (ctors) {
|
||||
|
||||
// Keep a record of elements that have matched already
|
||||
var matched = $([]), match, add, rem;
|
||||
// Stepping through each selector from most to least specific
|
||||
var j = ctors.length;
|
||||
while (j--) {
|
||||
// Build some quick-acccess variables
|
||||
var sel = ctors[j].selector.selector, ctor = ctors[j].onmatch; dtor = ctors[j].onunmatch;
|
||||
// Get the list of elements that match this selector, that haven't yet matched a more specific selector
|
||||
res = add = $(sel).not(matched);
|
||||
|
||||
// If this selector has a list of elements it matched against last time
|
||||
if (ctors[j].cache) {
|
||||
// Find the ones that are extra this time
|
||||
add = res.not(ctors[j].cache);
|
||||
// Find the ones that are gone this time
|
||||
rem = ctors[j].cache.not(res);
|
||||
// And call the desctructor on them
|
||||
if (rem.length && dtor) ctors.onunmatchproxy(rem, j, dtor);
|
||||
}
|
||||
|
||||
// Call the constructor on the newly matched ones
|
||||
if (add.length && ctor) ctors.onmatchproxy(add, j, ctor);
|
||||
|
||||
// Add these matched ones to the list tracking all elements matched so far
|
||||
matched = matched.add(res);
|
||||
// And remember this list of matching elements again this selector, so next matching we can find the unmatched ones
|
||||
ctors[j].cache = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check_id = null;
|
||||
}
|
||||
|
||||
function registerMutateFunction() {
|
||||
$.each(arguments, function(i,func){
|
||||
var old = $.fn[func];
|
||||
$.fn[func] = function() {
|
||||
var rv = old.apply(this, arguments);
|
||||
if (!check_id) check_id = runSoon(matching, 100);
|
||||
return rv;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function registerSetterGetterFunction() {
|
||||
$.each(arguments, function(i,func){
|
||||
var old = $.fn[func];
|
||||
$.fn[func] = function(a, b) {
|
||||
var rv = old.apply(this, arguments);
|
||||
if (!check_id && (b !== undefined || typeof a != 'string')) check_id = runSoon(matching, 100);
|
||||
return rv;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Register core DOM manipulation methods
|
||||
registerMutateFunction('append', 'prepend', 'after', 'before', 'wrap', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');
|
||||
registerSetterGetterFunction('attr');
|
||||
|
||||
// And on DOM ready, trigger matching once
|
||||
$(function(){ matching(); })
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
77
thirdparty/jquery-concrete/src/jquery.concrete.properties.js
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
(function($) {
|
||||
|
||||
var concrete_prepend = '__concrete!';
|
||||
|
||||
var getConcreteData = function(el, namespace, property) {
|
||||
return el.data(concrete_prepend + namespace + '!' + property);
|
||||
}
|
||||
|
||||
var setConcreteData = function(el, namespace, property, value) {
|
||||
return el.data(concrete_prepend + namespace + '!' + property, value);
|
||||
}
|
||||
|
||||
var getConcreteDataAsHash = function(el, namespace) {
|
||||
var hash = {};
|
||||
var id = jQuery.data(el[0]);
|
||||
|
||||
var matchstr = concrete_prepend + namespace + '!';
|
||||
var matchlen = matchstr.length;
|
||||
|
||||
var cache = jQuery.cache[id];
|
||||
for (var k in cache) {
|
||||
if (k.substr(0,matchlen) == matchstr) hash[k.substr(matchlen)] = cache[k];
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
var setConcreteDataFromHash = function(el, namespace, hash) {
|
||||
for (var k in hash) setConcreteData(namespace, k, hash[k]);
|
||||
}
|
||||
|
||||
var concreteData = function(el, namespace, args) {
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
return getConcreteDataAsHash(el, namespace);
|
||||
case 1:
|
||||
if (typeof args[0] == 'string') return getConcreteData(el, namespace, args[0]);
|
||||
else return setConcreteDataFromHash(el, namespace, args[0]);
|
||||
default:
|
||||
return setConcreteData(el, namespace, args[0], args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$.extend($.fn, {
|
||||
concreteData: function() {
|
||||
return concreteData(this, '__base', arguments);
|
||||
}
|
||||
});
|
||||
|
||||
$.concrete.Namespace.addHandler({
|
||||
order: 60,
|
||||
|
||||
bind: function(selector, k, v) {
|
||||
if (k.charAt(0) != k.charAt(0).toUpperCase()) $.concrete.warn('Concrete property '+k+' does not start with a capital letter', $.concrete.WARN_LEVEL_BESTPRACTISE);
|
||||
|
||||
var namespace = this;
|
||||
g = function() { return this.concreteData(k) || v ; }
|
||||
s = function(v){ return this.concreteData(k, v); }
|
||||
|
||||
g.pname = s.pname = k;
|
||||
|
||||
this.bind_proxy(selector, 'get'+k, g);
|
||||
this.bind_proxy(selector, 'set'+k, s);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
namespaceMethodOverrides: function(namespace){
|
||||
return {
|
||||
concreteData: function() {
|
||||
return concreteData(this, namespace.name, arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
49
thirdparty/jquery-concrete/src/jquery.focusinout.js
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
(function($){
|
||||
|
||||
/**
|
||||
* Add focusin and focusout support to bind and live for browers other than IE. Designed to be usable in a delegated fashion (like $.live)
|
||||
* Copyright (c) 2007 Jörn Zaefferer
|
||||
*/
|
||||
$.support.focusInOut = !!($.browser.msie);
|
||||
if (!$.support.focusInOut) {
|
||||
// Emulate focusin and focusout by binding focus and blur in capturing mode
|
||||
$.each({focus: 'focusin', blur: 'focusout'}, function(original, fix){
|
||||
$.event.special[fix] = {
|
||||
setup: function(){
|
||||
if (!this.addEventListener) return false;
|
||||
this.addEventListener(original, $.event.special[fix].handler, true);
|
||||
},
|
||||
teardown: function(){
|
||||
if (!this.removeEventListener) return false;
|
||||
this.removeEventListener(original, $.event.special[fix].handler, true);
|
||||
},
|
||||
handler: function(e){
|
||||
arguments[0] = $.event.fix(e);
|
||||
arguments[0].type = fix;
|
||||
return $.event.handle.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
(function(){
|
||||
//IE has some trouble with focusout with select and keyboard navigation
|
||||
var activeFocus = null;
|
||||
|
||||
$(document)
|
||||
.bind('focusin', function(e){
|
||||
var target = e.realTarget || e.target;
|
||||
if (activeFocus && activeFocus !== target) {
|
||||
e.type = 'focusout';
|
||||
$(activeFocus).trigger(e);
|
||||
e.type = 'focusin';
|
||||
e.target = target;
|
||||
}
|
||||
activeFocus = target;
|
||||
})
|
||||
.bind('focusout', function(e){
|
||||
activeFocus = null;
|
||||
});
|
||||
})();
|
||||
|
||||
})(jQuery);
|
105
thirdparty/jquery-concrete/vendor/firebug_lite/ChangeLog
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
== Firebug Lite Change Log ==
|
||||
2009-03-09 Azer Koculu <azer@kodfabrik.com>
|
||||
* firebug-lite.js: Removed getElementPosXY method.
|
||||
Added toggle method to settings object.
|
||||
|
||||
2009-03-07 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Fixed issue 1554: Text nodes could not be accessed through the inspect button.
|
||||
|
||||
2009-03-07 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Issue 1566: Added firebug.env.targetWindow variable to hold target window
|
||||
|
||||
2009-03-06 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Changed default for firebug.env.detectFirebug to false
|
||||
Fixed issue 1555: Ajax calls ... we should not assume that the same domain policy is applied, use try catch instead
|
||||
Fixed Issue 1541: Add XHR tab to Firebug Lite popup window
|
||||
progress.gif: Corrected mime type
|
||||
|
||||
2009-03-03 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js, firebug-lite.css, progress.gif: Fixed Issue 1544: Lite settings menu should have a "processing" gif
|
||||
|
||||
2009-02-21 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Fixed Issue 1542: FBLite F12 etc should dock the popup instead of hiding the panel
|
||||
|
||||
2009-02-21 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js, firebug-lite.css:
|
||||
o Issue 1513 ... added:
|
||||
- Settings dialog
|
||||
- Settings storage cookie (stores settings, panel height, popup window positions etc.)
|
||||
- firebug.env:
|
||||
openInPopup
|
||||
popupTop
|
||||
popupLeft
|
||||
popupWidth
|
||||
popupHeight
|
||||
o Various popup window bugfixes and performance improvements
|
||||
|
||||
2009-02-21 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js, firebug-lite.css, firebug_logo.png: Issue 1503: FBLite should have a visible sign it is running when starting hidden.
|
||||
Added FBLite icon when hidden and firebug.env.showIconWhenHidden (default true).
|
||||
|
||||
2009-02-18 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Fixed issue 1086 - FBLite can now be used locally over HTTPS if firebug.env.css is set.
|
||||
|
||||
2009-02-17 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Fixed problem with issue 1481 - A DIV was created instead of an IFRAME so the shield was ineffective.
|
||||
|
||||
2009-02-14 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Issue 1487 - Added firebug.env.liteFilename ... this allows for the renaming of the FBLite script for use in popup windows.
|
||||
|
||||
2009-02-12 Azer Koculu <azer@kodfabrik.com>
|
||||
* minifier.py, jsmin.py, minify: Added minifier library and compressing scripts.
|
||||
|
||||
2009-02-12 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Corrected 2 syntax errors
|
||||
|
||||
2009-02-11 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Issue 1400 - firebug.env.override is now false by default ... I have also added
|
||||
two methods to make it easier for the user to control the console:
|
||||
firebug.overrideConsole() & firebug.restoreConsole()
|
||||
|
||||
2009-02-09 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Issue 1400 - Re-implemented firebug.env.override. Default is now true ... it can only be manually changed in FBLite code.
|
||||
The reason this is needed is because a number of browsers have a window.console object.
|
||||
|
||||
2009-02-08 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Issue 1406 - Added firebug.env.hideDOMFunctions to allow hiding of DOM functions in the DOM tab.
|
||||
|
||||
2009-02-06 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Removed firebug.env.override to prevent problems when override is set in FF3 where window.console
|
||||
is a getter and allow more control over initialization.
|
||||
* firebug-lite.js: Refactored code to allow firebug.env.detectFirebug to be set from user code
|
||||
* firebug-lite.js: Moved console initialization code inside of the Firebug object to remove some global variables
|
||||
* firebug-lite.js & firebug-lite.css: Fixed Issue 1348 - String, Date and Boolean objects should be displayed similar
|
||||
to their primitive counterparts
|
||||
* firebug-lite.js & firebug-lite.css: Fixed Issue 1023 - Elements such as Flash in iframes and dropdowns in IE bleed through FBLite,
|
||||
I have put an iframe 'shield' behind FBLite to prevent this
|
||||
* Updated mime-types for all FBLite SVN files
|
||||
|
||||
2009-02-05 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Added firebug.env.detectFirebug to prevent FBLite opening when Firebug is enabled (actually the Firebug Console).
|
||||
To run FBLite and Firebug at the same time it is now necessary to change the value of detectFirebug directly in firebug-lite.js
|
||||
* Fixed multiple console initialization and override issues
|
||||
|
||||
2009-02-05 Azer Koculu <azer@kodfabrik.com>
|
||||
* firebug-lite.css: mime-type property has been set to "text/css".
|
||||
|
||||
2009-02-04 Azer Koculu <azer@kodfabrik.com>
|
||||
* firebug-lite.js: Changed default css url getfirebug.com to fbug.google.com
|
||||
* firebug-lite-compressed.js: It was unnecesseary, removed.
|
||||
|
||||
2009-02-02 Azer Koculu <azer@kodfabrik.com>
|
||||
* Copied latest source to googlecode repository.
|
||||
|
||||
2009-01-31 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js: Added extra hotkeys to show / hide FBLite:
|
||||
F12, (CTRL|CMD)+SHIFT+L, SHIFT+ENTER
|
||||
* firebug-lite.js: Added console.firebug command to show FBLite version number
|
||||
* firebug-lite.js: Fixed problem with Open in New Window in Safari
|
||||
* firebug-lite.js: Added debug="true/false" to show or hide FBLite on startup
|
||||
|
||||
2009-01-01 Mike Ratcliffe <sabine.michael.ratcliffe@gmail.com>
|
||||
* firebug-lite.js & firebug-lite.css: Added Open in New Window
|
||||
* firebug-lite.js: Fixed: HTML Inspect only worked in 1 very specific situation ... it now works in all situations
|
||||
* firebug-lite.js: Fixed: Permission was occasionally denied to inspect CSS or scripts when it should not have been
|
||||
* firebug-lite.js: Fixed: Domain check now works with domain names containing - and _
|
BIN
thirdparty/jquery-concrete/vendor/firebug_lite/errorIcon.png
vendored
Normal file
After Width: | Height: | Size: 457 B |
214
thirdparty/jquery-concrete/vendor/firebug_lite/firebug-lite.css
vendored
Normal file
@ -0,0 +1,214 @@
|
||||
/* */
|
||||
#Firebug div, #Firebug h3, #Firebug span, #Firebug input, #Firebug textarea, #Firebug select, #Firebug option, #Firebug a, #Firebug strong, #Firebug em, #Firebug label, #Firebug center {
|
||||
position:static; float:none; width:auto; height:auto; text-align:left; border:0; overflow:visible; background:transparent none repeat left top; color:#111; font-size:1em; font-weight:normal; font-style:normal; font-family:sans-serif; margin:0; padding:0; min-height:0;
|
||||
}
|
||||
#Firebug input, #Firebug select, #Firebug textarea { background:#fff; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; border:1px outset #aaa; padding:2px }
|
||||
#Firebug center { text-align:center; }
|
||||
#Firebug strong { font-weight:bold; }
|
||||
#Firebug em { font-style:italic; }
|
||||
/* */
|
||||
|
||||
#FirebugIFrame { position:fixed !important; position:absolute; z-index:99999998; left:0; bottom:0; width:100%; height:295px; background:#fff; border-width:0px; }
|
||||
|
||||
#Firebug { position:fixed !important; position:absolute; z-index:99999999; left:0; bottom:0; width:100%; height:295px; background:#fff; overflow:hidden; }
|
||||
#Firebug .Resizer { position:absolute; top:0; width:100%; height:5px; background:transparent; *background:url(spacer.gif); cursor:n-resize; -moz-user-select:none; }
|
||||
#Firebug .Header { height:38px; background:#ccc url(firebug.gif) 0 -85px; }
|
||||
#Firebug .Left, #Firebug > .Right { background:#fff; height:257px;}
|
||||
#Firebug .Left { float:left; width:100%; }
|
||||
#Firebug .Right { float:left; display:none; width:30%; overflow:hidden; }
|
||||
#Firebug .Right .Container { height:100%; border-left:1px solid #ccc; }
|
||||
|
||||
/*
|
||||
* buttonset
|
||||
*/
|
||||
|
||||
#Firebug .ButtonContainer { padding:8px 0 5px 10px; *margin-top:-3px; _margin-top:0; }
|
||||
#Firebug .ButtonContainer .Button { cursor:pointer; font:12px "MS Sans Serif", Geneva, sans-serif; color:#000; margin-right:5px; padding:4px 4px 4px 4px; border:1px solid transparent !important; border-color:#ccc; text-decoration:none; }
|
||||
#Firebug .ButtonContainer .Button:hover { border:1px outset #aaa !important; }
|
||||
#Firebug .ButtonContainer .Button:active { border-style:inset !important; background-color:#ccc; }
|
||||
#Firebug .ButtonContainer .Enabled { border:1px outset #aaa !important; }
|
||||
#Firebug .ButtonContainer .Logo { text-decoration:none; padding-left:24px; background:url(firebug.gif) no-repeat 5px 3px; border:0 !important; opacity:0.7; filter:Alpha(Opacity=70); }
|
||||
#Firebug .ButtonContainer .Logo:hover, #Firebug .ButtonContainer .Logo:active { border:0 !important; background-color:transparent; opacity:1; filter:Alpha(Opacity=100); }
|
||||
#Firebug .ButtonContainer .Maximize, #Firebug .ButtonContainer .Minimize, #Firebug .ButtonContainer .NewWindow, #Firebug .ButtonContainer .Dock, #Firebug .ButtonContainer .Close { position:absolute; right:0; top:12px; padding:6px 8px 8px 8px; background:url(firebug.gif) no-repeat -3px -48px; border:0 !important; opacity:0.7; filter:Alpha(Opacity:80); *padding:0px 7px 1px 7px; }
|
||||
#Firebug .ButtonContainer .Maximize:hover, #Firebug .ButtonContainer .Maximize:active, #Firebug .ButtonContainer .NewWindow:hover, #Firebug .ButtonContainer .NewWindow:active, #Firebug .ButtonContainer .Dock:hover, #Firebug .ButtonContainer .Dock:active, #Firebug .ButtonContainer .Minimize:hover, #Firebug .ButtonContainer .Minimize:active, #Firebug .ButtonContainer .Close:hover, #Firebug .ButtonContainer .Close:active { border:0 !important; background-color:transparent; opacity:1; filter:Alpha(Opacity:100); }
|
||||
#Firebug .ButtonContainer .Minimize { background-position:-3px -20px; right:40px; }
|
||||
#Firebug .ButtonContainer .Maximize { display:none; background-position:-3px -34px; right:40px; }
|
||||
#Firebug .ButtonContainer .NewWindow { background-position:-3px -123px; right:20px; }
|
||||
#Firebug .ButtonContainer .Dock { background-position:-3px -137px; }
|
||||
#Firebug .ButtonContainer .ButtonSet { border-left:1px solid #ccc; padding:0 0 0 3px; display:inline; }
|
||||
|
||||
/*
|
||||
* navigation
|
||||
*/
|
||||
|
||||
#Firebug .Nav { height:23px; background:url(firebug.gif) repeat-x 0 -62px; padding-left:10px; }
|
||||
#Firebug .Nav .Tab { display:block; width:auto; float:left; padding:3px 6px 2px 6px; cursor:pointer; border:1px outset transparent !important; border:0; font:bold 11px Arial, Helvetica, sans-serif; color:#666; }
|
||||
#Firebug .Nav .Tab:hover, #Firebug .Nav .Selected { border:1px outset #ccc !important; border-top-color:transparent !important; }
|
||||
#Firebug .Nav .Selected { color:#111; cursor:default; background-color:#f2f2f2; }
|
||||
#Firebug .Nav .Settings { float:right; }
|
||||
|
||||
/*
|
||||
* inspector
|
||||
*/
|
||||
|
||||
#FirebugBorderInspector { display:none; z-index:99999998; position:absolute; top:0; left:0; border:2px solid #0000ff; background:transparent; *background:url(spacer.gif); opacity:0.5; filter:Alpha(Opacity=50); padding:0; margin:0; }
|
||||
#FirebugBGInspector { display:none; z-index:99999998; position:absolute; top:0; left:0; background:rgb(0,150,255); opacity:0.5; filter:Alpha(Opacity=50); padding:0; margin:0; }
|
||||
|
||||
/*
|
||||
* dom
|
||||
*/
|
||||
|
||||
#Firebug .DOMRow { width:100% !important; width:90%; }
|
||||
#Firebug .DOMRow .DOMRowLeft { float:left; width:30%; overflow:hidden; }
|
||||
#Firebug .DOMRow .DOMRowLeft a { padding-left:15px; }
|
||||
#Firebug .DOMRow .DOMRowRight { float:left; width:60%; *width:60%; _overflow:hidden; white-space:nowrap; }
|
||||
#Firebug .DOMRow .DOMRowLeft .Object { background:url(tree_open.gif) no-repeat left center; cursor:pointer; }
|
||||
#Firebug .DOMRow .DOMRowLeft .Object:hover { text-decoration:underline; color:#0000ff; }
|
||||
#Firebug .DOMRow .DOMRowLeft .Opened { background-image:url(tree_close.gif) }
|
||||
#Firebug .DOMRow .DOMRowSubContainer { display:none; padding-left:25px; }
|
||||
|
||||
/*
|
||||
* console
|
||||
*/
|
||||
#Firebug .Left .Console { overflow:hidden; }
|
||||
#Firebug .Left .Console .Monitor { height:210px; border-bottom:1px solid #ccc; overflow:scroll; overflow-x:hidden; }
|
||||
#Firebug .Left .Console .Monitor .Error { background:#ffeff1; color:#ff0000; }
|
||||
#Firebug .Left .Console .Monitor .Error strong { color:#ff0000; }
|
||||
#Firebug .Left .Console .Monitor .Row { padding:2px 5px 2px 5px; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; overflow:hidden; border-bottom:1px solid #e5e5e5; }
|
||||
#Firebug .Left .Console .Monitor .Arrow { color:rgb(0,0,255); white-space:nowrap; }
|
||||
|
||||
#Firebug .Left .Console .InputArrow { position:absolute; left:0px; width:20px; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; color:#0000ff; padding:2px 4px 0 4px; }
|
||||
#Firebug .Left .Console .InputContainer { margin-left:35px; margin-right:5px; }
|
||||
#Firebug .Left .Console .Input { width:100% !important; margin-top:2px; width:98%; overflow:hidden; border:0; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; }
|
||||
#Firebug .Console .MLButton { cursor:pointer; position:absolute; top:276px; right:-22px; width:20px; padding:4px 10px 10px 10px; font-size:1px; *padding:2px 10px 10px 10px; background:url(firebug.gif) no-repeat -3px -34px; opacity:0.8; filter:Alpha(Opacity:80); }
|
||||
#Firebug .Console .MLButton:hover { opacity:1; filter:Alpha(Opacity:100); }
|
||||
#Firebug .Console .CloseML { background-position:-3px -20px; }
|
||||
|
||||
#Firebug .Right .Console { background:#eee; }
|
||||
#Firebug .Right .Console .Input { width:100%; _width:98%; height:228px; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; background:#fff; border:0; border-bottom:1px solid #ccc; margin-bottom:2px; *overflow:scroll; }
|
||||
#Firebug .Right .Console .Button { cursor:pointer; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:1px 4px 1px 4px; margin:0 4px 0 4px; background:#eee; border:1px solid #eee; text-decoration:none; *display:block; *width:auto; *float:left; *margin-top:-1px; }
|
||||
#Firebug .Right .Console .Button:hover { border:1px outset #ccc; background:#fff; }
|
||||
#Firebug .Right .Console .Button:active { border:1px inset #ccc; background:#ccc; }
|
||||
|
||||
#Firebug .Left .Console .Monitor .Warn { background:url(warningIcon.png) #00FFFF no-repeat 2px center; padding-left:20px; }
|
||||
#Firebug .Left .Console .Monitor .Info { background:url(infoIcon.png) #fff no-repeat 2px center; padding-left:20px; }
|
||||
#Firebug .Left .Console .Monitor .Error { background:url(errorIcon.png) #FFFFE0 no-repeat 2px center; padding-left:20px; }
|
||||
|
||||
|
||||
/*
|
||||
* html
|
||||
*/
|
||||
|
||||
#Firebug .Left .HTML { display:none; height:250px; overflow:scroll; padding:0 10px 2px 10px; }
|
||||
#Firebug .Left .HTML .Block { padding:0 0 0 0px; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; }
|
||||
#Firebug .Left .HTML .Block .Spacer { cursor:default; padding:2px 2px 2px 15px; }
|
||||
#Firebug .Left .HTML .Block .Link { display:block; color:#333; padding:2px 2px 2px 0; }
|
||||
#Firebug .Left .HTML .Block .Link .Content { padding:2px 2px 2px 2px; }
|
||||
#Firebug .Left .HTML .Block .Link .TagName { cursor:pointer; }
|
||||
#Firebug .Left .HTML .Block .Parent { font-weight:bold; color:#111; text-decoration:none; }
|
||||
#Firebug .Left .HTML .Block .Parent .Spacer { background:#fff center no-repeat; }
|
||||
#Firebug .Left .HTML .Block .Parent .Spacer { background-image:url(tree_open.gif); }
|
||||
#Firebug .Left .HTML .Block .Open .Spacer { background-image:url(tree_close.gif) }
|
||||
#Firebug .Left .HTML .Block .Selected { background-color:#4473c4; }
|
||||
#Firebug .Left .HTML .Block .Selected * { color:#fff; }
|
||||
#Firebug .Left .HTML .Block .SubContainer { padding-left:20px; height:0; font-size:0px; }
|
||||
#Firebug .Left .HTML .Block .OpenSubContainer { height:auto; }
|
||||
#Firebug .Left .HTML .Unvisible { opacity:0.5; filter:Alpha(Opacity=50); }
|
||||
|
||||
#Firebug .Right .HTML { display:none; }
|
||||
#Firebug .Right .HTML .Content { overflow:scroll; height:235px; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; }
|
||||
#Firebug .Right .HTML .Content .CSSItem { padding:5px; color:#333; height:6px }
|
||||
#Firebug .Right .HTML .Content .CSSProperty { width:45%; float:left; overflow:hidden; }
|
||||
#Firebug .Right .HTML .Content .CSSValue { width:55%; float:left; white-space:nowrap; overflow:visible !important; overflow:hidden; }
|
||||
#Firebug .Right .HTML .Content .CSSValue input { font:11px ArArial, Helvetica, sans-serif; color:#333; 3px 0 0 -3px; }
|
||||
#Firebug .Right .HTML .Content .CSSItem center { color:rgb(0,150,0); padding:0 0 3px 0; font:bold 12px Arial, Helvetica, sans-serif; }
|
||||
#Firebug .ButtonContainer .HTML { display:none; }
|
||||
|
||||
/*
|
||||
* CSS
|
||||
*/
|
||||
|
||||
#Firebug .Left .CSS { display:none; padding:5px; height:225px; overflow:scroll; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; }
|
||||
#Firebug .Right .CSS { display:none; }
|
||||
#Firebug .Left .CSS .Selector { margin-top:10px }
|
||||
#Firebug .Left .CSS .CSSText { padding-left:20px; }
|
||||
#Firebug .Left .CSS .CSSProperty { color:#005500; margin-top:10px; }
|
||||
#Firebug .Left .CSS .CSSValue { padding-left:5px; color:#000088; }
|
||||
#Firebug .ButtonContainer .CSS { display:none; }
|
||||
|
||||
#Firebug .Right .CSS { background:#eee; }
|
||||
#Firebug .Right .CSS .Input { width:100%; _width:98%; height:205px; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; background:#fff; border:0; border-bottom:1px solid #ccc; margin-bottom:2px; *overflow:scroll; }
|
||||
#Firebug .Right .CSS .Button { cursor:pointer; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:1px 4px 1px 4px; margin:0 4px 0 4px; background:#eee; border:1px solid #eee; text-decoration:none; *display:block; *width:auto; *float:left; *margin-top:-1px; }
|
||||
#Firebug .Right .CSS .Button:hover { border:1px outset #ccc; background:#fff; }
|
||||
#Firebug .Right .CSS .Button:active { border:1px inset #ccc; background:#ccc; }
|
||||
|
||||
/*
|
||||
* Scripts
|
||||
*/
|
||||
|
||||
#Firebug .Left .Scripts { display:none; height:225px; *height:235px; overflow:scroll; font:12px Verdana, Geneva, Arial, Helvetica, sans-serif; }
|
||||
#Firebug .Left .Scripts .LineNumber { float:left; width:30px; height:20px; padding:0 2px 0 0; background:#eee; color:#666; font-family:Courier; text-align:right; border-right:1px solid #ccc; }
|
||||
#Firebug .Left .Scripts .CodeContainer { padding:5px; }
|
||||
#Firebug .Left .Scripts .Code { height:20px; }
|
||||
#Firebug .Left .Scripts .CodeContainer, #Firebug .Left .Scripts .Code { word-wrap:normal; white-space:pre; }
|
||||
#Firebug .Right .Scripts { display:none; }
|
||||
#Firebug .ButtonContainer .Scripts { display:none; }
|
||||
|
||||
/*
|
||||
* DOM
|
||||
*/
|
||||
|
||||
#Firebug .Left .DOM { display:none; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:5px; overflow:scroll; height:225px; }
|
||||
#Firebug .Left .DOM .Object { font-weight:bold; }
|
||||
#Firebug .Right .DOM { display:none; overflow:scroll; }
|
||||
#Firebug .ButtonContainer .DOM { display:none; }
|
||||
#Firebug .ButtonContainer .DOM label { font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; }
|
||||
|
||||
/*
|
||||
* XHR
|
||||
*/
|
||||
|
||||
#Firebug .Left .XHR { display:none; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:5px; overflow:scroll; height:225px; }
|
||||
#Firebug .Left .XHR .Block { float:left; width:30%; }
|
||||
#Firebug .Left .XHR .BlockContent { padding:3px; border-right:1px dotted #aaa; }
|
||||
#Firebug .Left .XHR .Block strong { display:block; text-align:center; padding:3px; background:rgb(200,225,255); color:rgb(50,50,50); }
|
||||
#Firebug .Left .XHR .Block span { display:block; text-align:center; overflow:hidden; }
|
||||
#Firebug .Left .XHR .Block span a { cursor:pointer; color:rgb(0,0,200); }
|
||||
#Firebug .Right .XHR { display:none; overflow:scroll; }
|
||||
#Firebug .ButtonContainer .XHR { display:none; }
|
||||
#Firebug .ButtonContainer .XHR label { font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; }
|
||||
|
||||
#Firebug .Left .STR { display:none; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; padding:5px; overflow:scroll; height:225px; }
|
||||
|
||||
/*
|
||||
* settings
|
||||
*/
|
||||
#Firebug .SettingsDiv {position:absolute;width:190px;top:60px;border:1px outset #000;-x-system-font:none;color:#000;font-family:"MS Sans Serif",Geneva,sans-serif;font-size:12px;font-size-adjust:none;font-stretch:normal;font-style:normal;font-variant:normal;font-weight:normal;line-height:normal;display:none;background-color:#FFF;}
|
||||
#Firebug .SettingsDiv .Header {background:#CCC url(firebug.gif) repeat scroll 0 -85px;height:30px;border-bottom:1px inset #000;}
|
||||
#Firebug .SettingsDiv .Header .Title {padding-top:10px;text-align:center;}
|
||||
#Firebug .SettingsDiv .Content {padding:5px;}
|
||||
#Firebug .SettingsDiv .Content .SettingsCBX{position:relative;top:2px;margin: 4px 5px 0 0; border:0 !important; padding:0 !important; height: 15px !important;}
|
||||
#Firebug .SettingsDiv .Content .ButtonsLeft {float:left;padding:10px 0px 5px 0px;}
|
||||
#Firebug .SettingsDiv .Content .ButtonsRight {float:right;padding:10px 0px 5px 0px;}
|
||||
#Firebug .SettingsDiv .Content .ProgressDiv {background-color:#FFF;width:100%;height:100%;position:absolute;left:0;top:0;z-index:1;opacity:.8;filter:alpha(opacity=80);display:none;}
|
||||
#Firebug .SettingsDiv .Content .Progress {background-image:url(progress.gif);width:66px;height:66px;position:absolute;top:50%;left:50%;margin-left:-33px;margin-top:-33px;}
|
||||
|
||||
/*
|
||||
* element highlighting
|
||||
*/
|
||||
#Firebug .Italic { font-style:italic; }
|
||||
#Firebug .Strong { font-weight:bold; }
|
||||
#Firebug .NormalWeight { font-weight:normal; }
|
||||
#Firebug .Green { color:#008800; }
|
||||
#Firebug .Gray { color:#666; }
|
||||
#Firebug .Blue { color:#0000ee; }
|
||||
#Firebug .DarkBlue { color:#000099; }
|
||||
#Firebug .Red { color:#ee0000; }
|
||||
#Firebug .Maroon { color:#800000; font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; }
|
||||
#Firebug .Null { font:11px Verdana, Geneva, Arial, Helvetica, sans-serif; color:#fff; padding:0 2px 0 2px; background:#999; border:1px solid #666; }
|
||||
#Firebug .ObjectLink, #Firebug .ObjectLinkHover { cursor:pointer; }
|
||||
#Firebug .ObjectLinkHover { border-bottom:1px solid #008800; }
|
||||
|
||||
#Firebug .Clear { clear:both; height:0px; font-size:0px; }
|
||||
|
||||
#firebugIconDiv {width:38px;height:38px;right:15pt;bottom:5pt;border:2px solid #000;display:none;position:fixed;background-image:url(firebug_logo.png);text-decoration:underline;cursor:pointer;filter:alpha(opacity:60);opacity:.6;z-index:99999998;}
|
2518
thirdparty/jquery-concrete/vendor/firebug_lite/firebug-lite.js
vendored
Normal file
@ -0,0 +1,2518 @@
|
||||
var firebug = {
|
||||
version:[1.23,20090309],
|
||||
el:{},
|
||||
env:{
|
||||
"cache":{},
|
||||
"extConsole":null,
|
||||
"css":"http://getfirebug.com/releases/lite/1.2/firebug-lite.css",
|
||||
"debug":true,
|
||||
"detectFirebug":false,
|
||||
"dIndex":"console",
|
||||
"height":295,
|
||||
"hideDOMFunctions":false,
|
||||
"init":false,
|
||||
"isPopup":false,
|
||||
"liteFilename":"firebug-lite.js",
|
||||
"minimized":false,
|
||||
"openInPopup": false,
|
||||
"override":false,
|
||||
"ml":false,
|
||||
"popupWin":null,
|
||||
"showIconWhenHidden":true,
|
||||
"targetWindow":undefined,
|
||||
"popupTop":1,
|
||||
"popupLeft":1,
|
||||
"popupWidth":undefined,
|
||||
"popupHeight":undefined
|
||||
},
|
||||
initConsole:function(){
|
||||
/*
|
||||
* initialize the console - user defined values are not available within this method because FBLite is not yet initialized
|
||||
*/
|
||||
var command;
|
||||
try{
|
||||
if((!window.console || (window.console && !window.console.firebug)) || (firebug.env.override && !(/Firefox\/3/i.test(navigator.userAgent)))){
|
||||
window.console = { "provider":"Firebug Lite" };
|
||||
|
||||
for(command in firebug.d.console.cmd){
|
||||
window.console[command] = firebug.lib.util.Curry(firebug.d.console.run,window,command);
|
||||
};
|
||||
}
|
||||
window.onerror = function(_message,_file,_line){
|
||||
firebug.d.console.run('error',firebug.lib.util.String.format('{0} ({1},{2})',_message,firebug.getFileName(_file),_line));
|
||||
};
|
||||
} catch(e){}
|
||||
},
|
||||
overrideConsole:function(){
|
||||
with (firebug){
|
||||
env.override=true;
|
||||
try{
|
||||
env.extConsole=window.console;
|
||||
} catch(e){}
|
||||
initConsole();
|
||||
}
|
||||
},
|
||||
restoreConsole:function(){
|
||||
with(firebug){
|
||||
if(env.extConsole){
|
||||
env.override=false;
|
||||
try{
|
||||
window.console=env.extConsole;
|
||||
} catch(e){}
|
||||
env.extConsole=null;
|
||||
}
|
||||
}
|
||||
},
|
||||
init:function(_css){
|
||||
var iconTitle = "Click here or press F12, (CTRL|CMD)+SHIFT+L or SHIFT+ENTER to show Firebug Lite. CTRL|CMD click this icon to hide it.";
|
||||
|
||||
with(firebug){
|
||||
if(document.getElementsByTagName('html')[0].attributes.getNamedItem('debug')){
|
||||
env.debug = document.getElementsByTagName('html')[0].attributes.getNamedItem('debug').nodeValue !== "false";
|
||||
}
|
||||
|
||||
if(env.isPopup) {
|
||||
env.openInPopup = false;
|
||||
env.targetWindow = window.opener;
|
||||
env.popupWidth = window.opener.firebug.env.popupWidth || window.opener.firebug.lib.util.GetViewport().width;
|
||||
env.popupHeight = window.opener.firebug.env.popupHeight || window.opener.firebug.lib.util.GetViewport().height;
|
||||
} else {
|
||||
env.targetWindow = window;
|
||||
env.popupWidth = env.popupWidth || lib.util.GetViewport().width;
|
||||
env.popupHeight = env.popupHeight || lib.util.GetViewport().height;
|
||||
}
|
||||
|
||||
settings.readCookie();
|
||||
|
||||
if(env.init || (env.detectFirebug && window.console && window.console.firebug)) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementsByTagName("head")[0].appendChild(
|
||||
new lib.element("link").attribute.set("rel","stylesheet").attribute.set("type","text/css").attribute.set("href",env.css).element
|
||||
);
|
||||
|
||||
if(env.override){
|
||||
overrideConsole();
|
||||
}
|
||||
|
||||
/*
|
||||
* Firebug Icon
|
||||
*/
|
||||
el.firebugIcon = new lib.element("div").attribute.set("id","firebugIconDiv").attribute.set("title",iconTitle).attribute.set("alt",iconTitle).event.addListener("mousedown",win.iconClicked).insert(document.body);
|
||||
|
||||
/*
|
||||
* main interface
|
||||
*/
|
||||
el.content = {};
|
||||
el.mainiframe = new lib.element("IFRAME").attribute.set("id","FirebugIFrame").environment.addStyle({ "display":"none", "width":lib.util.GetViewport().width+"px" }).insert(document.body);
|
||||
el.main = new lib.element("DIV").attribute.set("id","Firebug").environment.addStyle({ "display":"none", "width":lib.util.GetViewport().width+"px" }).insert(document.body);
|
||||
if(!env.isPopup){
|
||||
el.resizer = new lib.element("DIV").attribute.addClass("Resizer").event.addListener("mousedown",win.resizer.start).insert(el.main);
|
||||
}
|
||||
el.header = new lib.element("DIV").attribute.addClass("Header").insert(el.main);
|
||||
el.left = {};
|
||||
el.left.container = new lib.element("DIV").attribute.addClass("Left").insert(el.main);
|
||||
el.right = {};
|
||||
el.right.container = new lib.element("DIV").attribute.addClass("Right").insert(el.main);
|
||||
el.main.child.add(new lib.element("DIV").attribute.addClass('Clear'));
|
||||
|
||||
/*
|
||||
* buttons
|
||||
*/
|
||||
el.button = {};
|
||||
el.button.container = new lib.element("DIV").attribute.addClass("ButtonContainer").insert(el.header);
|
||||
el.button.logo = new lib.element("A").attribute.set("title","Firebug Lite").attribute.set("target","_blank").attribute.set("href","http://getfirebug.com/lite.html").update(" ").attribute.addClass("Button Logo").insert(el.button.container);
|
||||
el.button.inspect = new lib.element("A").attribute.addClass("Button").event.addListener("click",env.targetWindow.firebug.d.inspector.toggle).update("Inspect").insert(el.button.container);
|
||||
el.button.dock = new lib.element("A").attribute.addClass("Button Dock").event.addListener("click", win.dock).insert(el.button.container);
|
||||
el.button.newWindow = new lib.element("A").attribute.addClass("Button NewWindow").event.addListener("click", win.newWindow).insert(el.button.container);
|
||||
|
||||
if(!env.isPopup){
|
||||
el.button.maximize = new lib.element("A").attribute.addClass("Button Maximize").event.addListener("click",win.maximize).insert(el.button.container);
|
||||
el.button.minimize = new lib.element("A").attribute.addClass("Button Minimize").event.addListener("click",win.minimize).insert(el.button.container);
|
||||
el.button.close = new lib.element("A").attribute.addClass("Button Close").event.addListener("click",win.hide).insert(el.button.container);
|
||||
}
|
||||
|
||||
if(lib.env.ie||lib.env.webkit){
|
||||
el.button.container.environment.addStyle({ "paddingTop":"12px" });
|
||||
}
|
||||
|
||||
/*
|
||||
* navigation
|
||||
*/
|
||||
el.nav = {};
|
||||
el.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.left.container);
|
||||
el.nav.console = new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.navigate,window,"console")).update("Console").insert(el.nav.container);
|
||||
el.nav.html = new lib.element("A").attribute.addClass("Tab").update("HTML").event.addListener("click",lib.util.Curry(d.navigate,window,"html")).insert(el.nav.container);
|
||||
el.nav.css = new lib.element("A").attribute.addClass("Tab").update("CSS").event.addListener("click",lib.util.Curry(d.navigate,window,"css")).insert(el.nav.container);
|
||||
if(!env.isPopup){
|
||||
el.nav.scripts = new lib.element("A").attribute.addClass("Tab").update("Script").event.addListener("click",lib.util.Curry(d.navigate,window,"scripts")).insert(el.nav.container);
|
||||
}
|
||||
el.nav.dom = new lib.element("A").attribute.addClass("Tab").update("DOM").event.addListener("click",lib.util.Curry(d.navigate,env.targetWindow,"dom")).insert(el.nav.container);
|
||||
el.nav.xhr = new lib.element("A").attribute.addClass("Tab").update("XHR").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).insert(el.nav.container);
|
||||
el.nav.optionsdiv = new lib.element("DIV").attribute.addClass("Settings").insert(el.nav.container);
|
||||
el.nav.options = new lib.element("A").attribute.addClass("Tab").update("Options ∨").event.addListener("click", settings.toggle).insert(el.nav.optionsdiv);
|
||||
|
||||
/*
|
||||
* inspector
|
||||
*/
|
||||
el.borderInspector = new lib.element("DIV").attribute.set("id","FirebugBorderInspector").event.addListener("click",listen.inspector).insert(document.body);
|
||||
el.bgInspector = new lib.element("DIV").attribute.set("id","FirebugBGInspector").insert(document.body);
|
||||
|
||||
/*
|
||||
* console
|
||||
*/
|
||||
el.left.console = {};
|
||||
el.left.console.container = new lib.element("DIV").attribute.addClass("Console").insert(el.left.container);
|
||||
el.left.console.mlButton = new lib.element("A").attribute.addClass("MLButton").event.addListener("click",d.console.toggleML).insert(el.left.console.container);
|
||||
el.left.console.monitor = new lib.element("DIV").insert(
|
||||
new lib.element("DIV").attribute.addClass("Monitor").insert(el.left.console.container)
|
||||
);
|
||||
el.left.console.container.child.add(
|
||||
new lib.element("DIV").attribute.addClass("InputArrow").update(">>>")
|
||||
);
|
||||
el.left.console.input = new lib.element("INPUT").attribute.set("type","text").attribute.addClass("Input").event.addListener("keydown",listen.consoleTextbox).insert(
|
||||
new lib.element("DIV").attribute.addClass("InputContainer").insert(el.left.console.container)
|
||||
);
|
||||
|
||||
el.right.console = {};
|
||||
el.right.console.container = new lib.element("DIV").attribute.addClass("Console Container").insert(el.right.container);
|
||||
el.right.console.mlButton = new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.console.container);
|
||||
el.right.console.input = new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.console.container);
|
||||
el.right.console.input.event.addListener("keydown",lib.util.Curry(tab,window,el.right.console.input.element));
|
||||
el.right.console.run = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runMultiline).update("Run").insert(el.right.console.container);
|
||||
el.right.console.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.console.input)).update("Clear").insert(el.right.console.container);
|
||||
|
||||
el.button.console = {};
|
||||
el.button.console.container = new lib.element("DIV").attribute.addClass("ButtonSet").insert(el.button.container);
|
||||
el.button.console.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",d.console.clear).update("Clear").insert(el.button.console.container);
|
||||
|
||||
/*
|
||||
* html
|
||||
*/
|
||||
|
||||
el.left.html = {};
|
||||
el.left.html.container = new lib.element("DIV").attribute.addClass("HTML").insert(el.left.container);
|
||||
|
||||
el.right.html = {};
|
||||
el.right.html.container = new lib.element("DIV").attribute.addClass("HTML Container").insert(el.right.container);
|
||||
|
||||
el.right.html.nav = {};
|
||||
el.right.html.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.right.html.container);
|
||||
el.right.html.nav.computedStyle = new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"computedStyle")).update("Computed Style").insert(el.right.html.nav.container);
|
||||
el.right.html.nav.dom = new lib.element("A").attribute.addClass("Tab").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"dom")).update("DOM").insert(el.right.html.nav.container);
|
||||
|
||||
el.right.html.content = new lib.element("DIV").attribute.addClass("Content").insert(el.right.html.container);
|
||||
|
||||
el.button.html = {};
|
||||
el.button.html.container = new lib.element("DIV").attribute.addClass("ButtonSet HTML").insert(el.button.container);
|
||||
|
||||
/*
|
||||
* css
|
||||
*/
|
||||
|
||||
el.left.css = {};
|
||||
el.left.css.container = new lib.element("DIV").attribute.addClass("CSS").insert(el.left.container);
|
||||
|
||||
el.right.css = {};
|
||||
el.right.css.container = new lib.element("DIV").attribute.addClass("CSS Container").insert(el.right.container);
|
||||
|
||||
el.right.css.nav = {};
|
||||
el.right.css.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.right.css.container);
|
||||
el.right.css.nav.runCSS = new lib.element("A").attribute.addClass("Tab Selected").update("Run CSS").insert(el.right.css.nav.container);
|
||||
|
||||
el.right.css.mlButton = new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.css.container);
|
||||
el.right.css.input = new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.css.container);
|
||||
el.right.css.input.event.addListener("keydown",lib.util.Curry(firebug.tab,window,el.right.css.input.element));
|
||||
el.right.css.run = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runCSS).update("Run").insert(el.right.css.container);
|
||||
el.right.css.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.css.input)).update("Clear").insert(el.right.css.container);
|
||||
|
||||
el.button.css = {};
|
||||
el.button.css.container = new lib.element("DIV").attribute.addClass("ButtonSet CSS").insert(el.button.container);
|
||||
el.button.css.selectbox = new lib.element("SELECT").event.addListener("change",listen.cssSelectbox).insert(el.button.css.container);
|
||||
|
||||
/*
|
||||
* scripts
|
||||
*/
|
||||
|
||||
el.left.scripts = {};
|
||||
el.left.scripts.container = new lib.element("DIV").attribute.addClass("Scripts").insert(el.left.container);
|
||||
|
||||
el.right.scripts = {};
|
||||
el.right.scripts.container = new lib.element("DIV").attribute.addClass("Scripts Container").insert(el.right.container);
|
||||
|
||||
el.button.scripts = {};
|
||||
el.button.scripts.container = new lib.element("DIV").attribute.addClass("ButtonSet Scripts").insert(el.button.container);
|
||||
el.button.scripts.selectbox = new lib.element("SELECT").event.addListener("change",listen.scriptsSelectbox).insert(el.button.scripts.container);
|
||||
el.button.scripts.lineNumbers = new lib.element("A").attribute.addClass("Button").event.addListener("click",d.scripts.toggleLineNumbers).update("Show Line Numbers").insert(el.button.scripts.container);
|
||||
|
||||
/*
|
||||
* dom
|
||||
*/
|
||||
|
||||
el.left.dom = {};
|
||||
el.left.dom.container = new lib.element("DIV").attribute.addClass("DOM").insert(el.left.container);
|
||||
|
||||
el.right.dom = {};
|
||||
el.right.dom.container = new lib.element("DIV").attribute.addClass("DOM Container").insert(el.right.container);
|
||||
|
||||
el.button.dom = {};
|
||||
el.button.dom.container = new lib.element("DIV").attribute.addClass("ButtonSet DOM").insert(el.button.container);
|
||||
el.button.dom.label = new lib.element("LABEL").update("Object Path:").insert(el.button.dom.container);
|
||||
el.button.dom.textbox = new lib.element("INPUT").event.addListener("keydown",listen.domTextbox).update(env.isPopup?"window.opener":"window").insert(el.button.dom.container);
|
||||
|
||||
/*
|
||||
* str
|
||||
*/
|
||||
el.left.str = {};
|
||||
el.left.str.container = new lib.element("DIV").attribute.addClass("STR").insert(el.left.container);
|
||||
|
||||
el.right.str = {};
|
||||
el.right.str.container = new lib.element("DIV").attribute.addClass("STR").insert(el.left.container);
|
||||
|
||||
el.button.str = {};
|
||||
el.button.str.container = new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container);
|
||||
el.button.str.watch = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).update("Back").insert(el.button.str.container);
|
||||
|
||||
/*
|
||||
* xhr
|
||||
*/
|
||||
el.left.xhr = {};
|
||||
el.left.xhr.container = new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container);
|
||||
|
||||
el.right.xhr = {};
|
||||
el.right.xhr.container = new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container);
|
||||
|
||||
|
||||
el.button.xhr = {};
|
||||
el.button.xhr.container = new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container);
|
||||
el.button.xhr.label = new lib.element("LABEL").update("XHR Path:").insert(el.button.xhr.container);
|
||||
el.button.xhr.textbox = new lib.element("INPUT").event.addListener("keydown",listen.xhrTextbox).insert(el.button.xhr.container);
|
||||
el.button.xhr.watch = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.addXhrObject).update("Watch").insert(el.button.xhr.container);
|
||||
|
||||
/*
|
||||
* settings
|
||||
*/
|
||||
el.settings = {};
|
||||
el.settings.container = new lib.element("DIV").child.add(
|
||||
new lib.element("DIV").attribute.addClass("Header").child.add(
|
||||
new lib.element().attribute.addClass("Title").update('Firebug Lite Settings')
|
||||
)
|
||||
).attribute.addClass("SettingsDiv").insert(el.main);
|
||||
el.settings.content = new lib.element("DIV").attribute.addClass("Content").insert(el.settings.container);
|
||||
el.settings.progressDiv = new lib.element("DIV").attribute.addClass("ProgressDiv").insert(el.settings.content);
|
||||
el.settings.progress = new lib.element("DIV").attribute.addClass("Progress").insert(el.settings.progressDiv);
|
||||
el.settings.cbxDebug = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);
|
||||
el.settings.content.child.add(document.createTextNode("Start visible"));
|
||||
new lib.element("BR").insert(el.settings.content);
|
||||
el.settings.cbxDetectFirebug = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);
|
||||
el.settings.content.child.add(document.createTextNode("Hide when Firebug active"));
|
||||
new lib.element("BR").insert(el.settings.content);
|
||||
el.settings.cbxHideDOMFunctions = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);
|
||||
el.settings.content.child.add(document.createTextNode("Hide DOM functions"));
|
||||
new lib.element("BR").insert(el.settings.content);
|
||||
el.settings.cbxOverride = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);
|
||||
el.settings.content.child.add(document.createTextNode("Override window.console"));
|
||||
new lib.element("BR").insert(el.settings.content);
|
||||
el.settings.cbxShowIcon = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);
|
||||
el.settings.content.child.add(document.createTextNode("Show icon when hidden"));
|
||||
new lib.element("BR").insert(el.settings.content);
|
||||
el.settings.cbxOpenInPopup = new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);
|
||||
el.settings.content.child.add(document.createTextNode("Open in popup"));
|
||||
el.settings.buttonDiv = new lib.element("DIV").insert(el.settings.content);
|
||||
el.settings.buttonLeftDiv = new lib.element("DIV").attribute.addClass("ButtonsLeft").insert(el.settings.buttonDiv);
|
||||
el.settings.resetButton = new lib.element("INPUT").attribute.set("type","button").update("Reset").event.addListener("click",settings.reset).insert(el.settings.buttonLeftDiv);
|
||||
el.settings.buttonRightDiv = new lib.element("DIV").attribute.addClass("ButtonsRight").insert(el.settings.buttonDiv);
|
||||
el.settings.cancelButton = new lib.element("INPUT").attribute.set("type","button").update("Cancel").event.addListener("click",settings.hide).insert(el.settings.buttonRightDiv);
|
||||
el.settings.buttonRightDiv.child.add(document.createTextNode(" "));
|
||||
el.settings.saveButton = new lib.element("INPUT").attribute.set("type","button").update("Save").event.addListener("click",settings.saveClicked).insert(el.settings.buttonRightDiv);
|
||||
|
||||
lib.util.AddEvent(document,"mousemove",listen.mouse)("mousemove",win.resizer.resize)("mouseup",win.resizer.stop)("keydown",listen.keyboard);
|
||||
|
||||
env.init = true;
|
||||
|
||||
for(var i=0, len=d.console.cache.length; i<len; i++){
|
||||
var item = d.console.cache[i];
|
||||
d.console.cmd[item.command].apply(window,item.arg);
|
||||
};
|
||||
|
||||
if(lib.env.ie6){
|
||||
window.onscroll = lib.util.Curry(win.setVerticalPosition,window,null);
|
||||
var buttons = [
|
||||
el.button.inspect,
|
||||
el.button.close,
|
||||
el.button.inspect,
|
||||
el.button.console.clear,
|
||||
el.right.console.run,
|
||||
el.right.console.clear,
|
||||
el.right.css.run,
|
||||
el.right.css.clear
|
||||
];
|
||||
for(var i=0, len=buttons.length; i<len; i++)
|
||||
buttons[i].attribute.set("href","#");
|
||||
win.refreshSize();
|
||||
}
|
||||
|
||||
if(env.showIconWhenHidden) {
|
||||
if(!env.popupWin) {
|
||||
el.firebugIcon.environment.addStyle({ "display": env.debug&&'none'||'block' });
|
||||
}
|
||||
}
|
||||
|
||||
lib.util.AddEvent(window, "unload", win.unload);
|
||||
|
||||
if (env.isPopup) {
|
||||
env.height=lib.util.GetViewport().height;
|
||||
lib.util.AddEvent(window, "resize", win.fitToPopup);
|
||||
win.fitToPopup();
|
||||
} else {
|
||||
lib.util.AddEvent(window, "resize", win.refreshSize);
|
||||
}
|
||||
|
||||
win.setHeight(env.height);
|
||||
|
||||
if(env.openInPopup&&!env.isPopup) {
|
||||
win.newWindow();
|
||||
} else {
|
||||
el.main.environment.addStyle({ "display":env.debug&&'block'||'none' });
|
||||
el.mainiframe.environment.addStyle({ "display":env.debug&&'block'||'none' });
|
||||
}
|
||||
}
|
||||
},
|
||||
inspect:function(){
|
||||
return firebug.d.html.inspect.apply(window,arguments);
|
||||
},
|
||||
watchXHR:function(){
|
||||
with(firebug){
|
||||
d.xhr.addObject.apply(window,arguments);
|
||||
if(env.dIndex!="xhr"){
|
||||
d.navigate("xhr");
|
||||
}
|
||||
}
|
||||
},
|
||||
settings:{
|
||||
isVisible:false,
|
||||
show: function() {
|
||||
with(firebug){
|
||||
var posXY=lib.util.Element.getPosition(firebug.el.nav.options.element);
|
||||
settings.refreshForm();
|
||||
|
||||
el.settings.container.environment.addStyle({
|
||||
"display": "block",
|
||||
"left": (posXY.offsetLeft-125)+"px"
|
||||
});
|
||||
el.settings.progressDiv.environment.addStyle({
|
||||
"display": "none"
|
||||
});
|
||||
firebug.settings.isVisible = true;
|
||||
}
|
||||
},
|
||||
hide: function() {
|
||||
with(firebug){
|
||||
firebug.el.settings.container.environment.addStyle({
|
||||
"display": "none"
|
||||
});
|
||||
firebug.settings.isVisible = false;
|
||||
}
|
||||
},
|
||||
toggle: function(){
|
||||
with(firebug){
|
||||
settings[!settings.isVisible && 'show' || 'hide']();
|
||||
}
|
||||
},
|
||||
saveClicked: function() {
|
||||
firebug.el.settings.progressDiv.environment.addStyle({
|
||||
"display": "block"
|
||||
});
|
||||
setTimeout(firebug.settings.formToSettings,0);
|
||||
},
|
||||
formToSettings: function() {
|
||||
var fe=firebug.env,
|
||||
ofe,
|
||||
elSet=firebug.el.settings,
|
||||
exdate;
|
||||
|
||||
fe.debug=elSet.cbxDebug.element.checked;
|
||||
fe.detectFirebug=elSet.cbxDetectFirebug.element.checked;
|
||||
fe.hideDOMFunctions=elSet.cbxHideDOMFunctions.element.checked;
|
||||
fe.override=elSet.cbxOverride.element.checked;
|
||||
fe.showIconWhenHidden=elSet.cbxShowIcon.element.checked;
|
||||
fe.openInPopup=elSet.cbxOpenInPopup.element.checked;
|
||||
|
||||
if(fe.isPopup) {
|
||||
ofe=window.opener.firebug.env;
|
||||
ofe.debug=fe.debug;
|
||||
ofe.detectFirebug=fe.detectFirebug;
|
||||
ofe.hideDOMFunctions=fe.hideDOMFunctions;
|
||||
ofe.override=fe.override;
|
||||
ofe.showIconWhenHidden=fe.showIconWhenHidden;
|
||||
ofe.openInPopup=fe.openInPopup;
|
||||
ofe.popupTop=fe.popupTop;
|
||||
ofe.popupLeft=fe.popupLeft;
|
||||
ofe.popupWidth=fe.popupWidth;
|
||||
ofe.popupHeight=fe.popupHeight;
|
||||
}
|
||||
|
||||
with(firebug) {
|
||||
settings.writeCookie();
|
||||
settings.hide();
|
||||
win.refreshDOM();
|
||||
}
|
||||
},
|
||||
reset: function() {
|
||||
var exdate=new Date();
|
||||
|
||||
exdate.setTime(exdate.getTime()-1);
|
||||
document.cookie='FBLiteSettings=;expires='+exdate.toGMTString();
|
||||
location.reload(true);
|
||||
},
|
||||
readCookie: function() {
|
||||
var i,cookieArr,valueArr,item,value;
|
||||
|
||||
with(firebug.env){
|
||||
if(targetWindow.document.cookie.length>0) {
|
||||
cookieArr=targetWindow.document.cookie.split('; ');
|
||||
|
||||
for(i=0;i<cookieArr.length;i++) {
|
||||
if(cookieArr[i].split('=')[0]=='FBLiteSettings') {
|
||||
valueArr=cookieArr[i].split('=')[1].split(',');
|
||||
}
|
||||
}
|
||||
|
||||
if(valueArr) {
|
||||
for(i=0;i<valueArr.length;i++) {
|
||||
item=valueArr[i].split(':')[0];
|
||||
value=valueArr[i].split(':')[1];
|
||||
|
||||
switch(item) {
|
||||
case 'debug':
|
||||
debug=value=="true";
|
||||
break;
|
||||
case 'detectFirebug':
|
||||
detectFirebug=value=="true";
|
||||
break;
|
||||
case 'hideDOMFunctions':
|
||||
hideDOMFunctions=value=="true";
|
||||
break;
|
||||
case 'override':
|
||||
override=value=="true";
|
||||
break;
|
||||
case 'showIconWhenHidden':
|
||||
showIconWhenHidden=value=="true";
|
||||
break;
|
||||
case 'openInPopup':
|
||||
openInPopup=value=="true";
|
||||
break;
|
||||
case 'popupTop':
|
||||
popupTop=parseInt(value,10);
|
||||
break;
|
||||
case 'popupLeft':
|
||||
popupLeft=parseInt(value,10);
|
||||
break;
|
||||
case 'popupWidth':
|
||||
popupWidth=parseInt(value,10);
|
||||
break;
|
||||
case 'popupHeight':
|
||||
popupHeight=parseInt(value,10);
|
||||
break;
|
||||
case 'height':
|
||||
height=parseInt(value,10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
writeCookie: function() {
|
||||
var values;
|
||||
|
||||
with(firebug.env){
|
||||
values='debug:'+debug+',';
|
||||
values+='detectFirebug:'+detectFirebug+',';
|
||||
values+='hideDOMFunctions:'+hideDOMFunctions+',';
|
||||
values+='override:'+override+',';
|
||||
values+='showIconWhenHidden:'+showIconWhenHidden+',';
|
||||
values+='openInPopup:'+openInPopup+',';
|
||||
|
||||
if(isPopup) {
|
||||
if(window.outerWidth===undefined) {
|
||||
values+='popupTop:'+(window.screenTop-56)+',';
|
||||
values+='popupLeft:'+(window.screenLeft-8)+',';
|
||||
values+='popupWidth:'+document.body.clientWidth+',';
|
||||
values+='popupHeight:'+document.body.clientHeight+',';
|
||||
} else {
|
||||
values+='popupTop:'+window.screenY+',';
|
||||
values+='popupLeft:'+window.screenX+',';
|
||||
values+='popupWidth:'+window.outerWidth+',';
|
||||
values+='popupHeight:'+window.outerHeight+',';
|
||||
}
|
||||
} else {
|
||||
values+='popupTop:'+popupTop+',';
|
||||
values+='popupLeft:'+popupLeft+',';
|
||||
values+='popupWidth:'+popupWidth+',';
|
||||
values+='popupHeight:'+popupHeight+',';
|
||||
}
|
||||
|
||||
values+='height:'+(parseInt(targetWindow.firebug.el.main.element.style.height.replace(/px/,''),10)-38);
|
||||
|
||||
exdate=new Date();
|
||||
exdate.setDate(exdate.getDate()+365);
|
||||
targetWindow.document.cookie='FBLiteSettings='+values+';expires='+exdate.toGMTString();
|
||||
}
|
||||
},
|
||||
refreshForm: function() {
|
||||
var fe=firebug.env,
|
||||
elSet=firebug.el.settings;
|
||||
|
||||
elSet.cbxDebug.element.checked=fe.debug;
|
||||
elSet.cbxDetectFirebug.element.checked=fe.detectFirebug;
|
||||
elSet.cbxHideDOMFunctions.element.checked=fe.hideDOMFunctions;
|
||||
elSet.cbxOverride.element.checked=fe.override;
|
||||
elSet.cbxShowIcon.element.checked=fe.showIconWhenHidden;
|
||||
elSet.cbxOpenInPopup.element.checked=fe.openInPopup;
|
||||
}
|
||||
},
|
||||
win:{
|
||||
hide:function(){
|
||||
with(firebug){
|
||||
el.main.environment.addStyle({
|
||||
"display": "none"
|
||||
});
|
||||
el.mainiframe.environment.addStyle({
|
||||
"display": "none"
|
||||
});
|
||||
if(env.showIconWhenHidden) {
|
||||
el.firebugIcon.environment.addStyle({
|
||||
"display": "block"
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
show:function(){
|
||||
with(firebug){
|
||||
el.main.environment.addStyle({
|
||||
"display": "block"
|
||||
});
|
||||
el.mainiframe.environment.addStyle({
|
||||
"display": "block"
|
||||
});
|
||||
if(env.showIconWhenHidden) {
|
||||
el.firebugIcon.environment.addStyle({
|
||||
"display": "none"
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
iconClicked:function(_event) {
|
||||
with(firebug) {
|
||||
if(_event.ctrlKey==true||_event.metaKey==true) {
|
||||
el.firebugIcon.environment.addStyle({ "display": "none" });
|
||||
env.showIconWhenHidden=false;
|
||||
} else {
|
||||
win.show();
|
||||
}
|
||||
}
|
||||
},
|
||||
minimize:function(){
|
||||
with(firebug){
|
||||
env.minimized=true;
|
||||
el.main.environment.addStyle({ "height":"35px" });
|
||||
el.mainiframe.environment.addStyle({ "height":"35px" });
|
||||
el.button.maximize.environment.addStyle({ "display":"block" });
|
||||
el.button.minimize.environment.addStyle({ "display":"none" });
|
||||
win.refreshSize();
|
||||
}
|
||||
},
|
||||
maximize:function(){
|
||||
with(firebug){
|
||||
env.minimized=false;
|
||||
el.button.minimize.environment.addStyle({ "display":"block" });
|
||||
el.button.maximize.environment.addStyle({ "display":"none" });
|
||||
win.setHeight(env.height);
|
||||
}
|
||||
},
|
||||
newWindow: function() {
|
||||
var interval,scripts,script,scriptPath,
|
||||
fe=firebug.env;
|
||||
|
||||
if (!fe.popupWin) {
|
||||
scripts = document.getElementsByTagName('script');
|
||||
|
||||
fe.popupWin = window.open("", "_firebug",
|
||||
"status=0,menubar=0,resizable=1,top="+fe.popupTop+",left="+fe.popupLeft+",width=" + fe.popupWidth +
|
||||
",height=" + fe.popupHeight + ",scrollbars=0,addressbar=0,outerWidth="+fe.popupWidth+",outerHeight="+fe.popupHeight+
|
||||
"toolbar=0,location=0,directories=0,dialog=0");
|
||||
|
||||
if(!fe.popupWin) {
|
||||
alert("Firebug Lite could not open a pop-up window, most likely because of a popup blocker.\nPlease enable popups for this domain");
|
||||
} else {
|
||||
firebug.settings.hide();
|
||||
|
||||
for (i=0,len=scripts.length; i<len; i++) {
|
||||
if (scripts[i].src.indexOf(fe.liteFilename) > -1) {
|
||||
scriptPath = scripts[i].src;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (scriptPath) {
|
||||
script = fe.popupWin.document.createElement('script'), done = false;
|
||||
script.type = 'text/javascript';
|
||||
script.src = scriptPath;
|
||||
|
||||
script[firebug.lib.env.ie?"onreadystatechange":"onload"] = function(){
|
||||
if(!done && (!firebug.lib.env.ie || this.readyState == "complete" || this.readyState=="loaded")){
|
||||
done = true;
|
||||
if(fe.popupWin.firebug) {
|
||||
with(fe.popupWin.firebug) {
|
||||
env.isPopup = true;
|
||||
env.css = fe.css;
|
||||
init();
|
||||
el.button.dock.environment.addStyle({ "display": "block"});
|
||||
el.button.newWindow.environment.addStyle({ "display": "none"});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!done && firebug.lib.env.webkit) {
|
||||
fe.popupWin.document.write('<html><head></head><body></body></html>');
|
||||
interval = setInterval(function() {
|
||||
if (fe.popupWin.firebug) {
|
||||
clearInterval(interval);
|
||||
done = true;
|
||||
with(fe.popupWin.firebug) {
|
||||
env.isPopup = true;
|
||||
env.css = fe.css;
|
||||
init();
|
||||
el.button.dock.environment.addStyle({ "display": "block"});
|
||||
el.button.newWindow.environment.addStyle({ "display": "none"});
|
||||
}
|
||||
}
|
||||
}, 10);
|
||||
};
|
||||
|
||||
if (!done) {
|
||||
fe.popupWin.document.getElementsByTagName('head')[0].appendChild(script);
|
||||
firebug.el.main.environment.addStyle({"display": "none"});
|
||||
firebug.el.mainiframe.environment.addStyle({"display": "none"});
|
||||
}
|
||||
} else {
|
||||
alert("Unable to detect the following script \"" + fe.liteFilename +
|
||||
"\" ... if the script has been renamed then please set the value of firebug.env.liteFilename to reflect this change");
|
||||
fe.popupWin.close();
|
||||
fe.popupWin=null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
dock: function() {
|
||||
with(opener.firebug) {
|
||||
env.popupWin = null;
|
||||
el.main.environment.addStyle({
|
||||
"display": "block"
|
||||
});
|
||||
el.mainiframe.environment.addStyle({
|
||||
"display": "block"
|
||||
});
|
||||
settings.readCookie();
|
||||
window.close();
|
||||
};
|
||||
},
|
||||
unload: function() {
|
||||
with(firebug){
|
||||
if(env.isPopup) {
|
||||
win.dock();
|
||||
} else if(env.popupWin) {
|
||||
env.popupWin.close();
|
||||
}
|
||||
}
|
||||
},
|
||||
fitToPopup: function() {
|
||||
with(firebug) {
|
||||
var viewport = lib.util.GetViewport(window);
|
||||
win.setHeight((window.innerHeight||viewport.height) - 38);
|
||||
el.main.environment.addStyle({
|
||||
"width": (viewport.width) + "px"
|
||||
});
|
||||
el.mainiframe.environment.addStyle({
|
||||
"width": (viewport.width) + "px"
|
||||
});
|
||||
}
|
||||
},
|
||||
resizer:{
|
||||
y:[], enabled:false,
|
||||
start:function(_event){
|
||||
with(firebug){
|
||||
if(env.minimized)return;
|
||||
win.resizer.y=[el.main.element.offsetHeight,_event.clientY];
|
||||
if(lib.env.ie6){
|
||||
win.resizer.y[3]=parseInt(el.main.environment.getPosition().top);
|
||||
}
|
||||
win.resizer.enabled=true;
|
||||
}
|
||||
},
|
||||
resize:function(_event){
|
||||
with(firebug){
|
||||
if(!win.resizer.enabled)return;
|
||||
win.resizer.y[2]=(win.resizer.y[0]+(win.resizer.y[1]-_event.clientY));
|
||||
el.main.environment.addStyle({ "height":win.resizer.y[2]+"px" });
|
||||
el.mainiframe.environment.addStyle({ "height":win.resizer.y[2]+"px" });
|
||||
if(lib.env.ie6){
|
||||
el.main.environment.addStyle({ "top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px" });
|
||||
el.mainiframe.environment.addStyle({ "top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px" });
|
||||
}
|
||||
}
|
||||
},
|
||||
stop:function(_event){
|
||||
with(firebug){
|
||||
if(win.resizer.enabled){
|
||||
win.resizer.enabled=false;
|
||||
win.setHeight(win.resizer.y[2]-35);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
setHeight:function(_height){
|
||||
with(firebug){
|
||||
env.height=_height;
|
||||
|
||||
el.left.container.environment.addStyle({ "height":_height+"px" });
|
||||
el.right.container.environment.addStyle({ "height":_height+"px" });
|
||||
el.main.environment.addStyle({ "height":_height+38+"px" });
|
||||
el.mainiframe.environment.addStyle({ "height":_height+38+"px" });
|
||||
|
||||
win.refreshSize();
|
||||
|
||||
// console
|
||||
el.left.console.monitor.element.parentNode.style.height=_height-47+"px";
|
||||
el.left.console.mlButton.environment.addStyle({ "top":_height+19+"px" });
|
||||
el.right.console.mlButton.environment.addStyle({ "top":_height+19+"px" });
|
||||
el.right.console.input.environment.addStyle({ "height":_height-29+"px" });
|
||||
|
||||
// html
|
||||
el.left.html.container.environment.addStyle({"height":_height-23+"px"});
|
||||
el.right.html.content.environment.addStyle({"height":_height-23+"px"});
|
||||
|
||||
// css
|
||||
el.left.css.container.environment.addStyle({"height":_height-33+"px"});
|
||||
el.right.css.input.environment.addStyle({ "height":_height-55+"px" });
|
||||
|
||||
// script
|
||||
el.left.scripts.container.environment.addStyle({"height":_height-23+"px"});
|
||||
|
||||
// dom
|
||||
el.left.dom.container.environment.addStyle({"height":_height-31+"px"});
|
||||
|
||||
// xhr
|
||||
el.left.xhr.container.environment.addStyle({"height":_height-32+"px"});
|
||||
|
||||
// string
|
||||
el.left.str.container.environment.addStyle({"height":_height-32+"px"});
|
||||
}
|
||||
},
|
||||
refreshDOM:function(){
|
||||
with(firebug){
|
||||
d.dom.open(eval(el.button.dom.textbox.environment.getElement().value),el.left.dom.container);
|
||||
if(d.html.nIndex=="dom"){
|
||||
firebug.d.html.navigate("dom")
|
||||
}
|
||||
}
|
||||
},
|
||||
refreshSize:function(){
|
||||
with(firebug){
|
||||
if(!env.init)
|
||||
return;
|
||||
|
||||
var dim = lib.util.GetViewport();
|
||||
el.main.environment.addStyle({ "width":dim.width+"px"});
|
||||
el.mainiframe.environment.addStyle({ "width":dim.width+"px"});
|
||||
if(lib.env.ie6)
|
||||
win.setVerticalPosition(dim);
|
||||
}
|
||||
},
|
||||
setVerticalPosition:function(_dim,_event){
|
||||
with(firebug){
|
||||
var dim = _dim||lib.util.GetViewport();
|
||||
el.main.environment.addStyle({ "top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px" });
|
||||
el.mainiframe.environment.addStyle({ "top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px" });
|
||||
}
|
||||
}
|
||||
},
|
||||
d: {
|
||||
clean:function(_element){
|
||||
with(firebug){
|
||||
_element.update("");
|
||||
}
|
||||
},
|
||||
console:{
|
||||
addLine:function(){
|
||||
with (firebug) {
|
||||
return new lib.element("DIV").attribute.addClass("Row").insert(el.left.console.monitor);
|
||||
}
|
||||
},
|
||||
cache:[],
|
||||
clear:function(){
|
||||
with(firebug){
|
||||
d.clean(el.left.console.monitor);
|
||||
d.console.cache = [];
|
||||
}
|
||||
},
|
||||
formatArgs:function(){
|
||||
with(firebug){
|
||||
var content = [];
|
||||
for(var i=0, len=arguments.length; i<len; i++){
|
||||
content.push( d.highlight(arguments[i],false,false,true) );
|
||||
}
|
||||
return content.join(" ");
|
||||
}
|
||||
},
|
||||
history:[], historyIndex:0,
|
||||
openObject:function(_index){
|
||||
with (firebug) {
|
||||
d.dom.open(d.console.cache[_index], el.left.dom.container, lib.env.ie);
|
||||
d.navigate("dom");
|
||||
}
|
||||
},
|
||||
print: function(_cmd,_text){
|
||||
with (firebug){
|
||||
d.console.addLine().attribute.addClass("Arrow").update(">>> "+_cmd);
|
||||
d.console.addLine().update(d.highlight(_text,false,false,true));
|
||||
d.console.scroll();
|
||||
}
|
||||
},
|
||||
printException: function(_exception){
|
||||
with(firebug){
|
||||
var message = _exception.description||_exception.message||_exception;
|
||||
if(_exception.fileName){
|
||||
message+=' ('+(_exception.name&&(_exception.name+', ')||'')+getFileName(_exception.fileName)+', '+_exception.lineNumber+')';
|
||||
}
|
||||
d.console.addLine().attribute.addClass("Error").update("<strong>Error: </strong>"+message,true);
|
||||
}
|
||||
},
|
||||
eval:function(_cmd){
|
||||
var result;
|
||||
with(firebug){
|
||||
if(_cmd.length==0)
|
||||
return;
|
||||
|
||||
el.left.console.input.environment.getElement().value = "";
|
||||
d.console.historyIndex = d.console.history.push(_cmd);
|
||||
|
||||
try {
|
||||
if(_cmd==='console.firebug') {
|
||||
d.console.addLine().attribute.addClass("Arrow").update(firebug.version);
|
||||
} else {
|
||||
result = eval.call(window,_cmd);
|
||||
d.console.print(_cmd,result);
|
||||
}
|
||||
} catch(e){
|
||||
d.console.addLine().attribute.addClass("Arrow").update(">>> "+_cmd);
|
||||
d.console.printException(e);
|
||||
}
|
||||
d.console.scroll();
|
||||
}
|
||||
},
|
||||
scroll:function(){
|
||||
with(firebug){
|
||||
el.left.console.monitor.environment.getElement().parentNode.scrollTop = Math.abs(el.left.console.monitor.environment.getSize().offsetHeight-(el.left.console.monitor.element.parentNode.offsetHeight-11));
|
||||
}
|
||||
},
|
||||
run:function(_command){
|
||||
with(firebug){
|
||||
if(!env.init){
|
||||
d.console.cache.push({ "command":_command, "arg":Array.prototype.slice.call(arguments,1) });
|
||||
} else {
|
||||
d.console.cmd[_command].apply(window,Array.prototype.slice.call(arguments,1));
|
||||
}
|
||||
}
|
||||
},
|
||||
toggleML:function(){
|
||||
with(firebug){
|
||||
var open = !env.ml;
|
||||
env.ml = !env.ml;
|
||||
d.navigateRightColumn("console",open);
|
||||
el[open?"left":"right"].console.mlButton.environment.addStyle({ display:"none" });
|
||||
el[!open?"left":"right"].console.mlButton.environment.addStyle({ display:"block" });
|
||||
el.left.console.mlButton.attribute[(open?"add":"remove")+"Class"]("CloseML");
|
||||
}
|
||||
},
|
||||
countMap:{}, timeMap: {},
|
||||
cmd:{
|
||||
log: function(_value){
|
||||
with(firebug){
|
||||
var args = d.console.formatArgs.apply(window,arguments);
|
||||
d.console.addLine().attribute.addClass("Log").update(args);
|
||||
d.console.scroll();
|
||||
}
|
||||
},
|
||||
warn: function(_value){
|
||||
with(firebug){
|
||||
var args = d.console.formatArgs.apply(window,arguments);
|
||||
d.console.addLine().attribute.addClass("Warn").update(args);
|
||||
d.console.scroll();
|
||||
}
|
||||
},
|
||||
info: function(_value){
|
||||
with(firebug){
|
||||
var args = d.console.formatArgs.apply(window,arguments);
|
||||
d.console.addLine().attribute.addClass("Info").update(args);
|
||||
d.console.scroll();
|
||||
}
|
||||
},
|
||||
debug: function(_value){
|
||||
with(firebug){
|
||||
var args = d.console.formatArgs.apply(window,arguments);
|
||||
d.console.addLine().attribute.addClass("Debug").update(args);
|
||||
d.console.scroll();
|
||||
}
|
||||
},
|
||||
error: function(_value){
|
||||
with(firebug){
|
||||
var args = d.console.formatArgs.apply(window,arguments);
|
||||
d.console.addLine().attribute.addClass("Error").update(args);
|
||||
d.console.scroll();
|
||||
}
|
||||
},
|
||||
trace: function(_value){
|
||||
with(firebug){
|
||||
var stackAmt = 3, f = arguments.caller, isArray = lib.util.IsArray(f); //function that called trace
|
||||
|
||||
if((!isArray&&f)||(isArray&&f.length>0)){
|
||||
d.console.addLine().attribute.addClass("Arrow").update(">>> console.trace(stack)");
|
||||
for(var i=0;i<stackAmt;i++){
|
||||
var func = f.toString(), args = f.arguments;
|
||||
d.dom.open({"function":func, "arguments":args},d.console.addLine());
|
||||
f = f.caller;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
dir:function(_value){
|
||||
with(firebug){
|
||||
d.console.addLine().attribute.addClass("Arrow").update(">>> console.dir("+_value+")");
|
||||
d.dom.open(_value,d.console.addLine());
|
||||
}
|
||||
},
|
||||
dirxml: function(){
|
||||
with(firebug){
|
||||
d.console.cmd.log.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
time: function(_name){
|
||||
with(firebug){
|
||||
d.console.timeMap[_name] = new Date().getTime();
|
||||
}
|
||||
},
|
||||
timeEnd: function(_name){
|
||||
with(firebug){
|
||||
if(_name in d.console.timeMap){
|
||||
var delta = new Date().getTime() - d.console.timeMap[_name],
|
||||
args = d.console.formatArgs.apply(window,[_name+":", delta+"ms"]);
|
||||
d.console.addLine().attribute.addClass("log").update(args);
|
||||
delete d.console.timeMap[_name];
|
||||
}
|
||||
}
|
||||
},
|
||||
count: function(_name){
|
||||
with(firebug){
|
||||
if(!d.console.countMap[_name])
|
||||
d.console.countMap[_name] = 0;
|
||||
d.console.countMap[_name]++;
|
||||
d.console.cmd.log.apply(window, [_name, d.console.countMap[_name]]);
|
||||
}
|
||||
},
|
||||
group:function(){
|
||||
with(firebug){
|
||||
d.console.cmd.log.apply(this, ["console.group is not supported"]);
|
||||
}
|
||||
},
|
||||
groupEnd:function(){
|
||||
with(firebug){
|
||||
d.console.cmd.log.apply(this, ["console.groupEnd is not supported"]);
|
||||
}
|
||||
},
|
||||
profile:function(){
|
||||
with(firebug){
|
||||
d.console.cmd.log.apply(this, ["console.profile is not supported"]);
|
||||
}
|
||||
},
|
||||
profileEnd:function(){
|
||||
with(firebug){
|
||||
d.console.cmd.log.apply(this, ["console.profileEnd is not supported"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
css:{
|
||||
index:-1,
|
||||
open:function(_index){
|
||||
with (firebug) {
|
||||
var item = env.targetWindow.document.styleSheets[_index],
|
||||
uri = item.href;
|
||||
try {
|
||||
var rules = item[lib.env.ie ? "rules" : "cssRules"], str = "";
|
||||
for (var i=0; i<rules.length; i++) {
|
||||
var item = rules[i];
|
||||
var selector = item.selectorText;
|
||||
var cssText = lib.env.ie?item.style.cssText:item.cssText.match(/\{(.*)\}/)[1];
|
||||
str+=d.css.printRule(selector, cssText.split(";"), el.left.css.container);
|
||||
}
|
||||
} catch(e) {
|
||||
str="<em>Access to restricted URI denied</em>";
|
||||
}
|
||||
el.left.css.container.update(str);
|
||||
}
|
||||
},
|
||||
printRule:function(_selector,_css,_layer){
|
||||
with(firebug){
|
||||
var str = "<div class='Selector'>"+_selector+" {</div>";
|
||||
for(var i=0,len=_css.length; i<len; i++){
|
||||
var item = _css[i];
|
||||
str += "<div class='CSSText'>"+item.replace(/(.+\:)(.+)/,"<span class='CSSProperty'>$1</span><span class='CSSValue'>$2;</span>")+"</div>";
|
||||
}
|
||||
str+="<div class='Selector'>}</div>";
|
||||
return str;
|
||||
}
|
||||
},
|
||||
refresh:function(){
|
||||
with(firebug){
|
||||
el.button.css.selectbox.update("");
|
||||
var collection = env.targetWindow.document.styleSheets;
|
||||
for(var i=0,len=collection.length; i<len; i++){
|
||||
var uri = getFileName(collection[i].href);
|
||||
d.css.index=d.css.index<0?i:d.css.index;
|
||||
el.button.css.selectbox.child.add(
|
||||
new lib.element("OPTION").attribute.set("value",i).update(uri)
|
||||
)
|
||||
};
|
||||
d.css.open(d.css.index);
|
||||
}
|
||||
}
|
||||
},
|
||||
dom: {
|
||||
open: function(_object,_layer){
|
||||
with (firebug) {
|
||||
_layer.clean();
|
||||
var container = new lib.element("DIV").attribute.addClass("DOMContent").insert(_layer);
|
||||
d.dom.print(_object, container);
|
||||
}
|
||||
},
|
||||
print:function(_object,_parent, _inTree){
|
||||
with (firebug) {
|
||||
var obj = _object || window, parentElement = _parent;
|
||||
parentElement.update("");
|
||||
|
||||
if(parentElement.opened&&parentElement!=el.left.dom.container){
|
||||
parentElement.environment.getParent().lib.child.get()[0].lib.child.get()[0].lib.attribute.removeClass("Opened");
|
||||
parentElement.opened = false;
|
||||
parentElement.environment.addStyle({ "display":"none" });
|
||||
return;
|
||||
}
|
||||
if(_inTree)
|
||||
parentElement.environment.getParent().lib.child.get()[0].lib.child.get()[0].lib.attribute.addClass("Opened");
|
||||
parentElement.opened = true;
|
||||
|
||||
for (var key in obj) {
|
||||
try {
|
||||
if (env.hideDOMFunctions && typeof(obj[key]) == "function") continue;
|
||||
var value = obj[key], property = key, container = new lib.element("DIV").attribute.addClass("DOMRow").insert(parentElement),
|
||||
left = new lib.element("DIV").attribute.addClass("DOMRowLeft").insert(container), right = new lib.element("DIV").attribute.addClass("DOMRowRight").insert(container);
|
||||
|
||||
container.child.add(
|
||||
new lib.element("DIV").attribute.addClass('Clear')
|
||||
);
|
||||
|
||||
var link = new lib.element("A").attribute.addClass(
|
||||
typeof value=="object"&&Boolean(value)?"Property Object":"Property"
|
||||
).update(property).insert(left);
|
||||
|
||||
right.update(d.highlight(value,false,true));
|
||||
|
||||
var subContainer = new lib.element("DIV").attribute.addClass("DOMRowSubContainer").insert(container);
|
||||
|
||||
if(typeof value!="object"||Boolean(value)==false)
|
||||
continue;
|
||||
|
||||
link.event.addListener("click",lib.util.Curry(d.dom.print,window,value, subContainer, true));
|
||||
}catch(e){
|
||||
}
|
||||
}
|
||||
parentElement.environment.addStyle({ "display":"block" });
|
||||
}
|
||||
}
|
||||
},
|
||||
highlight:function(_value,_inObject,_inArray,_link){
|
||||
with(firebug){
|
||||
var isArray = false, isHash, isElement = false, vtype=typeof _value, result=[];
|
||||
|
||||
if(vtype=="object"){
|
||||
if(Object.prototype.toString.call(_value) === "[object Date]"){
|
||||
vtype = "date";
|
||||
} else if(Object.prototype.toString.call(_value) === "[object String]"){
|
||||
vtype = "string";
|
||||
} else if(Object.prototype.toString.call(_value) === "[object Boolean]"){
|
||||
vtype = "boolean";
|
||||
} else if(Object.prototype.toString.call(_value) === "[object RegExp]"){
|
||||
vtype = "regexp";
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
isArray = lib.util.IsArray(_value);
|
||||
isHash = lib.util.IsHash(_value);
|
||||
isElement = _value!=undefined&&Boolean(_value.nodeName)&&Boolean(_value.nodeType);
|
||||
|
||||
// number, string, boolean, null, function
|
||||
if(_value==null||vtype=="number"||vtype=="string"||vtype=="boolean"||vtype=="function"||vtype=="regexp"||vtype=="date"){
|
||||
if(_value==null){
|
||||
result.push("<span class='Null'>null</span>");
|
||||
}else if (vtype=="regexp") {
|
||||
result.push("<span class='Maroon'>" + _value + "</span>");
|
||||
}else if (vtype=="date") {
|
||||
result.push("<span class='DarkBlue'>'" + _value + "'</span>");
|
||||
} else if (vtype=="boolean"||vtype=="number") {
|
||||
result.push("<span class='DarkBlue'>" + _value + "</span>");
|
||||
} else if(vtype=="function"){
|
||||
result.push("<span class='"+(_inObject?"Italic Gray":"Green")+"'>function()</span>");
|
||||
} else {
|
||||
result.push("<span class='Red'>\""+( !_inObject&&!_inArray?_value : _value.substring(0,35)+(_value.length>35?" ...":"") ).replace(/\n/g,"\\n").replace(/\s/g," ").replace(/>/g,">").replace(/</g,"<")+"\"</span>");
|
||||
}
|
||||
}
|
||||
// element
|
||||
else if(isElement){
|
||||
|
||||
if(_value.nodeType==3)
|
||||
result.push(d.highlight(_value.nodeValue));
|
||||
else if(_inObject){
|
||||
result.push("<span class='Gray Italic'>"+_value.nodeName.toLowerCase()+"</span>");
|
||||
} else {
|
||||
result.push("<span class='Blue"+ ( !_link?"'":" ObjectLink' onmouseover='this.className=this.className.replace(\"ObjectLink\",\"ObjectLinkHover\")' onmouseout='this.className=this.className.replace(\"ObjectLinkHover\",\"ObjectLink\")' onclick='firebug.d.html.inspect(firebug.d.console.cache[" +( d.console.cache.push( _value ) -1 )+"])'" ) + "'>");
|
||||
|
||||
if(_inArray){
|
||||
result.push(_value.nodeName.toLowerCase());
|
||||
if(_value.getAttribute){
|
||||
if(_value.getAttribute&&_value.getAttribute("id"))
|
||||
result.push("<span class='DarkBlue'>#"+_value.getAttribute("id")+"</span>");
|
||||
var elClass = _value.getAttribute(lib.env.ie&&!lib.env.ie8?"className":"class")||"";
|
||||
result.push(!elClass?"":"<span class='Red'>."+elClass.split(" ")[0]+"</span>");
|
||||
}
|
||||
result.push("</span>");
|
||||
} else {
|
||||
result.push("<span class='DarkBlue'><<span class='Blue TagName'>"+ _value.nodeName.toLowerCase());
|
||||
|
||||
if(_value.attributes){
|
||||
for(var i=0,len=_value.attributes.length; i<len; i++){
|
||||
var item = _value.attributes[i];
|
||||
|
||||
if(!lib.env.ie||item.nodeValue)
|
||||
result.push(" <span class='DarkBlue'>"+item.nodeName+"=\"<span class='Red'>"+item.nodeValue+"</span>\"</span>");
|
||||
}
|
||||
}
|
||||
|
||||
result.push("</span>></span>");
|
||||
}
|
||||
}
|
||||
}
|
||||
// array, hash
|
||||
else if(isArray||isHash){
|
||||
if(isArray){
|
||||
if(_inObject){
|
||||
result.push("<span class='Gray Italic'>["+_value.length+"]</span>");
|
||||
} else {
|
||||
result.push("<span class='Strong'>[ ");
|
||||
|
||||
for(var i=0,len=_value.length; i<len; i++){
|
||||
if((_inObject||_inArray)&&i>3){
|
||||
result.push(", <span class='Strong Gray'>"+(len-4)+" More...</span>");
|
||||
break;
|
||||
}
|
||||
result.push( (i > 0 ? ", " : "") + d.highlight(_value[i], false, true, true) );
|
||||
}
|
||||
|
||||
result.push(" ]</span>");
|
||||
}
|
||||
} else if(_inObject){
|
||||
result.push("<span class='Gray Italic'>Object</span>");
|
||||
} else {
|
||||
result.push("<span class='Strong Green"+ ( !_link?"'":" ObjectLink' onmouseover='this.className=this.className.replace(\"ObjectLink\",\"ObjectLinkHover\")' onmouseout='this.className=this.className.replace(\"ObjectLinkHover\",\"ObjectLink\")' onclick='firebug.d.console.openObject(" +( d.console.cache.push( _value ) -1 )+")'" ) + ">Object");
|
||||
var i=0;
|
||||
for(var key in _value){
|
||||
var value = _value[key];
|
||||
if((_inObject||_inArray)&&i>3){
|
||||
result.push(" <span class='Strong Gray'>More...</span>");
|
||||
break;
|
||||
}
|
||||
result.push(" "+key+"="+d.highlight(value,true));
|
||||
i++;
|
||||
}
|
||||
result.push("</span>");
|
||||
}
|
||||
} else {
|
||||
result.push(["<span class'Gray Italic'>"+_value+"</span>"]);
|
||||
}
|
||||
} catch(e){
|
||||
result.push("..");
|
||||
}
|
||||
return result.join("");
|
||||
}
|
||||
},
|
||||
html:{
|
||||
nIndex:"computedStyle",
|
||||
current:null,
|
||||
highlight:function(_element,_clear,_event){
|
||||
with(firebug){
|
||||
if(_element.firebugElement){
|
||||
return;
|
||||
}
|
||||
if(_clear){
|
||||
env.targetWindow.firebug.el.bgInspector.environment.addStyle({ "display":"none" });
|
||||
return;
|
||||
}
|
||||
d.inspector.inspect(_element,true);
|
||||
}
|
||||
},
|
||||
inspect:function(_element){
|
||||
var map = [],
|
||||
parentLayer,
|
||||
t,
|
||||
tagName,
|
||||
parent = _element;
|
||||
while (parent) {
|
||||
map.push(parent);
|
||||
if (parent == firebug.env.targetWindow.document.body) break;
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
map = map.reverse();
|
||||
with(firebug) {
|
||||
if (env.dIndex != "html") {
|
||||
env.targetWindow.firebug.d.navigate("html");
|
||||
}
|
||||
|
||||
env.targetWindow.firebug.d.inspector.toggle(false);
|
||||
|
||||
for (t = 0; t < el.left.html.container.child.get().length; t++) {
|
||||
if (el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0]) {
|
||||
if (el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].innerText) {
|
||||
tagName = el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].innerText;
|
||||
} else {
|
||||
tagName = el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].textContent;
|
||||
}
|
||||
|
||||
if (/<body/i.test(tagName)) {
|
||||
parentLayer = el.left.html.container.child.get()[t].childNodes[1].lib;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!parentLayer) {
|
||||
parentLayer = el.left.html.container.child.get()[3].childNodes[1].lib;
|
||||
}
|
||||
|
||||
for (t = 0, len = map.length; map[t]; t++) {
|
||||
if (t == len - 1) {
|
||||
var link = parentLayer.environment.getElement().previousSibling.lib;
|
||||
link.attribute.addClass("Selected");
|
||||
|
||||
if (d.html.current) {
|
||||
d.html.current[1].attribute.removeClass("Selected");
|
||||
}
|
||||
d.html.current = [_element, link];
|
||||
return;
|
||||
}
|
||||
parentLayer = d.html.openHtmlTree(map[t], parentLayer, map[t + 1]);
|
||||
}
|
||||
}
|
||||
},
|
||||
navigate:function(_index,_element){
|
||||
with(firebug){
|
||||
el.right.html.nav[d.html.nIndex].attribute.removeClass("Selected");
|
||||
el.right.html.nav[_index].attribute.addClass("Selected");
|
||||
d.html.nIndex = _index;
|
||||
d.html.openProperties();
|
||||
}
|
||||
},
|
||||
openHtmlTree:function(_element,_parent,_returnParentElementByElement,_event){
|
||||
with(firebug){
|
||||
var element = _element || env.targetWindow.document.documentElement,
|
||||
parent = _parent || el.left.html.container,
|
||||
returnParentEl = _returnParentElementByElement || null,
|
||||
returnParentVal = null,
|
||||
len = element.childNodes.length,
|
||||
nodeLink;
|
||||
|
||||
if(parent!=el.left.html.container){
|
||||
nodeLink = parent.environment.getParent().lib.child.get()[0].lib;
|
||||
if (d.html.current) {
|
||||
d.html.current[1].attribute.removeClass("Selected");
|
||||
}
|
||||
nodeLink.attribute.addClass("Selected");
|
||||
|
||||
d.html.current = [_element,nodeLink];
|
||||
d.html.openProperties();
|
||||
};
|
||||
|
||||
if(element.childNodes&&(len==0||(len==1&&element.childNodes[0].nodeType==3)))return;
|
||||
parent.clean();
|
||||
|
||||
if(parent.opened&&Boolean(_returnParentElementByElement)==false){
|
||||
parent.opened = false;
|
||||
parent.element.previousSibling.lib.attribute.removeClass("Open");
|
||||
parent.element.lib.attribute.removeClass("OpenSubContainer");
|
||||
return;
|
||||
};
|
||||
|
||||
if (parent != el.left.html.container) {
|
||||
parent.element.previousSibling.lib.attribute.addClass("Open");
|
||||
parent.element.lib.attribute.addClass("OpenSubContainer");
|
||||
parent.opened = true;
|
||||
};
|
||||
|
||||
if(element==document.documentElement){
|
||||
new lib.element("A").attribute.addClass("Block").update("<span class='DarkBlue'><<span class='Blue'>html</span>>").insert(parent);
|
||||
};
|
||||
|
||||
for(var i=0; i<=len; i++){
|
||||
if(i==len){
|
||||
new lib.element("A").attribute.addClass("Block").update("<span class='DarkBlue'></<span class='Blue'>"+element.nodeName.toLowerCase()+"</span>>").insert(container);
|
||||
break;
|
||||
}
|
||||
var item = element.childNodes[i];
|
||||
|
||||
if (item.nodeType != 3){
|
||||
var container = new lib.element().attribute.addClass("Block").insert(parent),
|
||||
link = new lib.element("A").attribute.addClass("Link").insert(container),
|
||||
spacer = new lib.element("SPAN").attribute.addClass("Spacer").update(" ").insert(link),
|
||||
html = new lib.element("SPAN").attribute.addClass("Content").update(d.highlight(item)).insert(link),
|
||||
subContainer = new lib.element("DIV").attribute.addClass("SubContainer").insert(container),
|
||||
view = lib.util.Element.getView(item);
|
||||
|
||||
link.event.addListener("click", lib.util.Curry(d.html.openHtmlTree, window, item, subContainer, false));
|
||||
link.event.addListener("mouseover", lib.util.Curry(d.html.highlight, window, item, false));
|
||||
link.event.addListener("mouseout", lib.util.Curry(d.html.highlight, window, item, true));
|
||||
|
||||
returnParentVal = returnParentEl == item ? subContainer : returnParentVal;
|
||||
|
||||
if(d.html.current==null&&item==document.body){
|
||||
link.attribute.addClass("Selected");
|
||||
d.html.current = [item,link];
|
||||
d.html.openHtmlTree(item,subContainer);
|
||||
}
|
||||
|
||||
if(element.nodeName!="HEAD"&&element!=document.documentElement&&(view.visibility=="hidden"||view.display=="none")){
|
||||
container.attribute.addClass("Unvisible");
|
||||
};
|
||||
|
||||
if (item.childNodes){
|
||||
var childLen = item.childNodes.length;
|
||||
if (childLen == 1 && item.childNodes[0].nodeType == 3) {
|
||||
html.child.add(document.createTextNode(item.childNodes[0].nodeValue.substring(0, 50)));
|
||||
html.child.add(document.createTextNode("</"));
|
||||
html.child.add(new lib.element("span").attribute.addClass("Blue").update(item.nodeName.toLowerCase()).environment.getElement());
|
||||
html.child.add(document.createTextNode(">"));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if (childLen > 0) {
|
||||
link.attribute.addClass("Parent");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return returnParentVal;
|
||||
}
|
||||
},
|
||||
openProperties:function(){
|
||||
with(firebug){
|
||||
var index = d.html.nIndex;
|
||||
var node = d.html.current[0];
|
||||
d.clean(el.right.html.content);
|
||||
var str = "";
|
||||
switch(index){
|
||||
case "computedStyle":
|
||||
var property = ["opacity","filter","azimuth","background","backgroundAttachment","backgroundColor","backgroundImage","backgroundPosition","backgroundRepeat","border","borderCollapse","borderColor","borderSpacing","borderStyle","borderTop","borderRight","borderBottom","borderLeft","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderWidth","bottom","captionSide","clear","clip","color","content","counterIncrement","counterReset","cue","cueAfter","cueBefore","cursor","direction","display","elevation","emptyCells","cssFloat","font","fontFamily","fontSize","fontSizeAdjust","fontStretch","fontStyle","fontVariant","fontWeight","height","left","letterSpacing","lineHeight","listStyle","listStyleImage","listStylePosition","listStyleType","margin","marginTop","marginRight","marginBottom","marginLeft","markerOffset","marks","maxHeight","maxWidth","minHeight","minWidth","orphans","outline","outlineColor","outlineStyle","outlineWidth","overflow","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","page","pageBreakAfter","pageBreakBefore","pageBreakInside","pause","pauseAfter","pauseBefore","pitch","pitchRange","playDuring","position","quotes","richness","right","size","speak","speakHeader","speakNumeral","speakPunctuation","speechRate","stress","tableLayout","textAlign","textDecoration","textIndent","textShadow","textTransform","top","unicodeBidi","verticalAlign","visibility","voiceFamily","volume","whiteSpace","widows","width","wordSpacing","zIndex"].sort();
|
||||
var view = document.defaultView?document.defaultView.getComputedStyle(node,null):node.currentStyle;
|
||||
for(var i=0,len=property.length; i<len; i++){
|
||||
var item = property[i];
|
||||
if(!view[item])continue;
|
||||
str+="<div class='CSSItem'><div class='CSSProperty'>"+item+"</div><div class='CSSValue'>"+d.highlight(view[item])+"</div></div>";
|
||||
}
|
||||
el.right.html.content.update(str);
|
||||
break;
|
||||
case "dom":
|
||||
d.dom.open(node,el.right.html.content,lib.env.ie);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
inspector:{
|
||||
enabled:false,
|
||||
el:null,
|
||||
inspect:function(_element,_bgInspector){
|
||||
with(firebug){
|
||||
var pos = env.targetWindow.firebug.lib.util.Element.getPosition(_element);
|
||||
|
||||
env.targetWindow.firebug.el[_bgInspector&&"bgInspector"||"borderInspector"].environment.addStyle({
|
||||
"width":_element.offsetWidth+"px", "height":_element.offsetHeight+"px",
|
||||
"top":pos.offsetTop-(_bgInspector?0:2)+"px", "left":pos.offsetLeft-(_bgInspector?0:2)+"px",
|
||||
"display":"block"
|
||||
});
|
||||
9
|
||||
if(!_bgInspector){
|
||||
d.inspector.el = _element;
|
||||
}
|
||||
};
|
||||
},
|
||||
toggle:function(_absoluteValue,_event){
|
||||
with (firebug) {
|
||||
if(_absoluteValue==d.inspector.enabled)
|
||||
return;
|
||||
d.inspector.enabled = _absoluteValue!=undefined&&!_absoluteValue.clientX?_absoluteValue:!d.inspector.enabled;
|
||||
el.button.inspect.attribute[(d.inspector.enabled ? "add" : "remove") + "Class"]("Enabled");
|
||||
if(d.inspector.enabled==false){
|
||||
el.borderInspector.environment.addStyle({ "display":"none" });
|
||||
d.inspector.el = null;
|
||||
} else if(lib.env.dIndex!="html") {
|
||||
if (env.popupWin) {
|
||||
env.popupWin.firebug.d.navigate("html");
|
||||
} else {
|
||||
d.navigate("html");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scripts:{
|
||||
index:-1,
|
||||
lineNumbers:false,
|
||||
open:function(_index){
|
||||
with(firebug){
|
||||
d.scripts.index = _index;
|
||||
el.left.scripts.container.update("");
|
||||
var script = document.getElementsByTagName("script")[_index],uri = script.src||document.location.href,source;
|
||||
try {
|
||||
if(uri!=document.location.href){
|
||||
source = env.cache[uri]||lib.xhr.get(uri).responseText;
|
||||
env.cache[uri] = source;
|
||||
} else {
|
||||
source = script.innerHTML;
|
||||
}
|
||||
source = source.replace(/<|>/g,function(_ch){
|
||||
return ({"<":"<",">":">"})[_ch];
|
||||
});
|
||||
|
||||
if(!d.scripts.lineNumbers)
|
||||
el.left.scripts.container.child.add(
|
||||
new lib.element("DIV").attribute.addClass("CodeContainer").update(source)
|
||||
);
|
||||
else {
|
||||
source = source.split("<br />");
|
||||
for (var i = 0; i < source.length; i++) {
|
||||
el.left.scripts.container.child.add(new lib.element("DIV").child.add(new lib.element("DIV").attribute.addClass("LineNumber").update(i + 1), new lib.element("DIV").attribute.addClass("Code").update(" " + source[i]), new lib.element("DIV").attribute.addClass('Clear')));
|
||||
};
|
||||
};
|
||||
} catch(e){
|
||||
el.left.scripts.container.child.add(
|
||||
new lib.element("DIV").attribute.addClass("CodeContainer").update("<em>Access to restricted URI denied</em>")
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
toggleLineNumbers:function(){
|
||||
with(firebug){
|
||||
d.scripts.lineNumbers = !d.scripts.lineNumbers;
|
||||
el.button.scripts.lineNumbers.attribute[(d.scripts.lineNumbers ? "add" : "remove") + "Class"]("Enabled");
|
||||
d.scripts.open( d.scripts.index );
|
||||
}
|
||||
},
|
||||
refresh:function(){
|
||||
with(firebug){
|
||||
el.button.scripts.selectbox.clean();
|
||||
var collection = env.targetWindow.document.getElementsByTagName("script");
|
||||
for(var i=0,len=collection.length; i<len; i++){
|
||||
var item = collection[i],
|
||||
fileName = getFileName(item.src||item.baseURI||"..");
|
||||
d.scripts.index=d.scripts.index<0?i:d.scripts.index;
|
||||
el.button.scripts.selectbox.child.add(
|
||||
new lib.element("OPTION").attribute.set("value",i).update(fileName)
|
||||
);
|
||||
}
|
||||
d.scripts.open( d.scripts.index );
|
||||
}
|
||||
}
|
||||
},
|
||||
str: {
|
||||
open:function(_str){
|
||||
with(firebug){
|
||||
d.navigate("str");
|
||||
el.left.str.container.update(_str.replace(/\n/g,"<br />"))
|
||||
}
|
||||
}
|
||||
},
|
||||
xhr:{
|
||||
objects:[],
|
||||
addObject:function(){
|
||||
with(firebug){
|
||||
for(var i=0,len=arguments.length; i<len; i++){
|
||||
try {
|
||||
var item = arguments[i],
|
||||
val = env.targetWindow.eval(item);
|
||||
d.xhr.objects.push([item, val]);
|
||||
} catch(e){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
open:function(){
|
||||
with(firebug){
|
||||
el.left.xhr.container.update("");
|
||||
el.left.xhr.name = new lib.element("DIV").attribute.addClass("BlockContent").insert(new lib.element("DIV").attribute.addClass("Block").environment.addStyle({ "width":"20%" }).insert(el.left.xhr.container));
|
||||
el.left.xhr.nameTitle = new lib.element("STRONG").update("Object Name:").insert(el.left.xhr.name);
|
||||
el.left.xhr.nameContent = new lib.element("DIV").insert(el.left.xhr.name);
|
||||
el.left.xhr.status = new lib.element("DIV").attribute.addClass("BlockContent").insert(new lib.element("DIV").attribute.addClass("Block").environment.addStyle({ "width":"10%" }).insert(el.left.xhr.container));
|
||||
el.left.xhr.statusTitle = new lib.element("STRONG").update("Status:").insert(el.left.xhr.status);
|
||||
el.left.xhr.statusContent = new lib.element("DIV").insert(el.left.xhr.status);
|
||||
el.left.xhr.readystate = new lib.element("DIV").attribute.addClass("BlockContent").insert(new lib.element("DIV").environment.addStyle({ "width":"15%" }).attribute.addClass("Block").insert(el.left.xhr.container));
|
||||
el.left.xhr.readystateTitle =el.left.xhr.nameTitle = new lib.element("STRONG").update("Ready State:").insert(el.left.xhr.readystate);
|
||||
el.left.xhr.readystateContent = new lib.element("DIV").insert(el.left.xhr.readystate);
|
||||
el.left.xhr.response = new lib.element("DIV").attribute.addClass("BlockContent").insert(new lib.element("DIV").environment.addStyle({ "width":(lib.env.ie?"50":"55")+"%" }).attribute.addClass("Block").insert(el.left.xhr.container));
|
||||
el.left.xhr.responseTitle = new lib.element("STRONG").update("Response:").insert(el.left.xhr.response);
|
||||
el.left.xhr.responseContent = new lib.element("DIV").insert(el.left.xhr.response);
|
||||
setTimeout(d.xhr.refresh,500);
|
||||
}
|
||||
},
|
||||
refresh:function(){
|
||||
with(firebug){
|
||||
el.left.xhr.nameContent.update("");
|
||||
el.left.xhr.statusContent.update("");
|
||||
el.left.xhr.readystateContent.update("");
|
||||
el.left.xhr.responseContent.update("");
|
||||
for(var i=0,len=d.xhr.objects.length; i<len; i++){
|
||||
var item = d.xhr.objects[i],
|
||||
response = item[1].responseText;
|
||||
if(Boolean(item[1])==false)continue;
|
||||
el.left.xhr.nameContent.child.add(new lib.element("span").update(item[0]));
|
||||
try {
|
||||
el.left.xhr.statusContent.child.add(new lib.element("span").update(item[1].status));
|
||||
} catch(e){ el.left.xhr.statusContent.child.add(new lib.element("span").update(" ")); }
|
||||
el.left.xhr.readystateContent.child.add(new lib.element("span").update(item[1].readyState));
|
||||
|
||||
el.left.xhr.responseContent.child.add(new lib.element("span").child.add(
|
||||
new lib.element("A").event.addListener("click",lib.util.Curry(d.str.open,window,response)).update(" "+response.substring(0,50))
|
||||
));
|
||||
};
|
||||
if(env.dIndex=="xhr")
|
||||
setTimeout(d.xhr.refresh,500);
|
||||
}
|
||||
}
|
||||
},
|
||||
navigateRightColumn:function(_index,_open){
|
||||
with(firebug){
|
||||
el.left.container.environment.addStyle({ "width":_open?"70%":"100%" });
|
||||
el.right.container.environment.addStyle({ "display":_open?"block":"none" });
|
||||
}
|
||||
},
|
||||
navigate:function(_index){
|
||||
with(firebug){
|
||||
var open = _index, close = env.dIndex;
|
||||
env.dIndex = open;
|
||||
|
||||
settings.hide();
|
||||
|
||||
el.button[close].container.environment.addStyle({ "display":"none" });
|
||||
el.left[close].container.environment.addStyle({ "display":"none" });
|
||||
el.right[close].container.environment.addStyle({ "display":"none" });
|
||||
|
||||
el.button[open].container.environment.addStyle({ "display":"inline" });
|
||||
el.left[open].container.environment.addStyle({ "display":"block" });
|
||||
el.right[open].container.environment.addStyle({ "display":"block" });
|
||||
|
||||
if(el.nav[close])
|
||||
el.nav[close].attribute.removeClass("Selected");
|
||||
if(el.nav[open])
|
||||
el.nav[open].attribute.addClass("Selected");
|
||||
|
||||
switch(open){
|
||||
case "console":
|
||||
d.navigateRightColumn(_index);
|
||||
break;
|
||||
case "html":
|
||||
d.navigateRightColumn(_index,true);
|
||||
if(!d.html.current){
|
||||
var t=Number(new Date);
|
||||
d.html.openHtmlTree();
|
||||
}
|
||||
break;
|
||||
case "css":
|
||||
d.navigateRightColumn(_index,true);
|
||||
d.css.refresh();
|
||||
break;
|
||||
case "scripts":
|
||||
d.navigateRightColumn(_index);
|
||||
d.scripts.refresh();
|
||||
break;
|
||||
case "dom":
|
||||
d.navigateRightColumn(_index);
|
||||
if(el.left.dom.container.environment.getElement().innerHTML==""){
|
||||
var t=Number(new Date);
|
||||
d.dom.open(eval(el.button.dom.textbox.environment.getElement().value),el.left.dom.container);
|
||||
}
|
||||
break;
|
||||
case "xhr":
|
||||
d.navigateRightColumn(_index);
|
||||
d.xhr.open();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getFileName:function(_path){
|
||||
var match = _path&&_path.match(/[\w\-\.\?\=\&]+$/);
|
||||
return match&&match[0]||_path;
|
||||
},
|
||||
cancelEvent:function(_event){
|
||||
if(_event.stopPropagation)
|
||||
_event.stopPropagation();
|
||||
if(_event.preventDefault)
|
||||
_event.preventDefault();
|
||||
},
|
||||
getSelection:function(_el){
|
||||
with(firebug){
|
||||
if(lib.env.ie){
|
||||
var range = document.selection.createRange(),stored = range.duplicate();
|
||||
stored.moveToElementText(_el);
|
||||
stored.setEndPoint('EndToEnd', range);
|
||||
_el.selectionStart = stored.text.length - range.text.length;
|
||||
_el.selectionEnd = _el.selectionStart + range.text.length;
|
||||
}
|
||||
return {
|
||||
start:_el.selectionStart,
|
||||
length:_el.selectionEnd-_el.selectionStart
|
||||
}
|
||||
}
|
||||
},
|
||||
tab:function(_el,_event){
|
||||
with(firebug){
|
||||
if(_event.keyCode==9){
|
||||
if(_el.setSelectionRange){
|
||||
var position = firebug.getSelection(_el);
|
||||
_el.value = _el.value.substring(0,position.start) + String.fromCharCode(9) + _el.value.substring(position.start+position.length,_el.value.length);
|
||||
_el.setSelectionRange(position.start+1,position.start+1);
|
||||
} else if(document.selection) {
|
||||
var range = document.selection.createRange(), isCollapsed = range.text == '';
|
||||
range.text = String.fromCharCode(9);
|
||||
range.moveStart('character', -1);
|
||||
}
|
||||
firebug.cancelEvent(_event);
|
||||
if(lib.env.ie)
|
||||
setTimeout(_el.focus,100);
|
||||
};
|
||||
}
|
||||
},
|
||||
listen: {
|
||||
addXhrObject:function(){
|
||||
with(firebug){
|
||||
d.xhr.addObject.apply(env.targetWindow, el.button.xhr.textbox.environment.getElement().value.split(","));
|
||||
}
|
||||
},
|
||||
consoleTextbox:function(_event){
|
||||
with(firebug){
|
||||
if(_event.keyCode==13&&(env.multilinemode==false||_event.shiftKey==false)){
|
||||
d.console.historyIndex = d.console.history.length;
|
||||
d.console.eval(el.left.console.input.environment.getElement().value);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(_event.keyCode){
|
||||
case 40:
|
||||
if(d.console.history[d.console.historyIndex+1]){
|
||||
d.console.historyIndex+=1;
|
||||
el.left.console.input.update( d.console.history[d.console.historyIndex] );
|
||||
}
|
||||
break;
|
||||
case 38:
|
||||
if(d.console.history[d.console.historyIndex-1]){
|
||||
d.console.historyIndex-=1;
|
||||
el.left.console.input.update( d.console.history[d.console.historyIndex] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
cssSelectbox:function(){
|
||||
with(firebug){
|
||||
d.css.open(el.button.css.selectbox.environment.getElement().selectedIndex);
|
||||
}
|
||||
},
|
||||
domTextbox:function(_event){
|
||||
with(firebug){
|
||||
if(_event.keyCode==13){
|
||||
d.dom.open(eval(el.button.dom.textbox.environment.getElement().value),el.left.dom.container);
|
||||
}
|
||||
}
|
||||
},
|
||||
inspector:function(){
|
||||
with(firebug){
|
||||
if (env.popupWin) {
|
||||
env.popupWin.firebug.d.html.inspect(firebug.d.inspector.el);
|
||||
} else {
|
||||
firebug.d.html.inspect(firebug.d.inspector.el);
|
||||
}
|
||||
}
|
||||
},
|
||||
keyboard:function(_event){
|
||||
with(firebug){
|
||||
if(_event.keyCode==27 && d.inspector.enabled){
|
||||
d.inspector.toggle();
|
||||
} else if(_event.keyCode === 123 && _event.ctrlKey || _event.metaKey) {
|
||||
if(env.isPopup){
|
||||
win.dock();
|
||||
}else {
|
||||
win.newWindow();
|
||||
}
|
||||
} else if(
|
||||
(_event.keyCode === 123 && !_event.ctrlKey && !_event.metaKey) ||
|
||||
(_event.keyCode === 76 && (_event.ctrlKey || _event.metaKey) && _event.shiftKey) ||
|
||||
(_event.keyCode === 13 && _event.shiftKey)) {
|
||||
|
||||
if(env.isPopup){
|
||||
win.dock();
|
||||
} else if (el.main.environment.getStyle("display") === 'none') {
|
||||
win.show();
|
||||
} else {
|
||||
win.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mouse:function(_event){
|
||||
with(firebug){
|
||||
var target;
|
||||
|
||||
if(document.elementFromPoint) {
|
||||
target = document.elementFromPoint(_event.clientX, _event.clientY);
|
||||
} else {
|
||||
if(lib.env.ie) {
|
||||
target = _event.srcElement;
|
||||
} else {
|
||||
target = _event.explicitOriginalTarget || _event.target;
|
||||
}
|
||||
}
|
||||
|
||||
if( d.inspector.enabled&&
|
||||
target!=document.body&&
|
||||
target!=document.firstChild&&
|
||||
target!=document.childNodes[1]&&
|
||||
target!=el.borderInspector.environment.getElement()&&
|
||||
target!=el.main.environment.getElement()&&
|
||||
target.offsetParent!=el.main.environment.getElement() ) {
|
||||
d.inspector.inspect(target);
|
||||
}
|
||||
}
|
||||
},
|
||||
runMultiline:function(){
|
||||
with(firebug){
|
||||
d.console.eval.call(window,el.right.console.input.environment.getElement().value);
|
||||
}
|
||||
},
|
||||
runCSS:function(){
|
||||
with(firebug){
|
||||
var source = el.right.css.input.environment.getElement().value.replace(/\n|\t/g,"").split("}");
|
||||
for(var i=0, len=source.length; i<len; i++){
|
||||
var item = source[i]+"}", rule = !lib.env.ie?item:item.split(/{|}/),
|
||||
styleSheet = document.styleSheets[0];
|
||||
console.log(rule);
|
||||
if(item.match(/.+\{.+\}/)){
|
||||
if(lib.env.ie)
|
||||
styleSheet.addRule(rule[0],rule[1]);
|
||||
else
|
||||
styleSheet.insertRule( rule, styleSheet.cssRules.length );
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scriptsSelectbox:function(){
|
||||
with(firebug){
|
||||
d.scripts.open(parseInt(el.button.scripts.selectbox.environment.getElement().value));
|
||||
}
|
||||
},
|
||||
xhrTextbox:function(_event){
|
||||
with(firebug){
|
||||
if(_event.keyCode==13){
|
||||
d.xhr.addObject.apply(env.targetWindow, el.button.xhr.textbox.environment.getElement().value.split(","));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(function(_scope){
|
||||
_scope.lib = {};
|
||||
var pi = _scope.lib; pi.version = [1.1,2008091000];
|
||||
|
||||
pi.env = {
|
||||
ie: /MSIE/i.test(navigator.userAgent),
|
||||
ie6: /MSIE 6/i.test(navigator.userAgent),
|
||||
ie7: /MSIE 7/i.test(navigator.userAgent),
|
||||
ie8: /MSIE 8/i.test(navigator.userAgent),
|
||||
firefox: /Firefox/i.test(navigator.userAgent),
|
||||
opera: /Opera/i.test(navigator.userAgent),
|
||||
webkit: /Webkit/i.test(navigator.userAgent),
|
||||
camino: /Camino/i.test(navigator.userAgent)
|
||||
};
|
||||
|
||||
pi.get = function(){
|
||||
return document.getElementById(arguments[0]);
|
||||
};
|
||||
pi.get.byTag = function(){
|
||||
return document.getElementsByTagName(arguments[0]);
|
||||
};
|
||||
pi.get.byClass = function(){ return document.getElementsByClassName.apply(document,arguments); };
|
||||
|
||||
pi.util = {
|
||||
Array:{
|
||||
clone:function(_array,_undeep){
|
||||
var tmp = [];
|
||||
Array.prototype.push.apply(tmp,_array);
|
||||
pi.util.Array.forEach(tmp,function(_item,_index,_source){
|
||||
if(_item instanceof Array&&!_undeep)
|
||||
_source[_index] = pi.util.Array.clone(_source[_index]);
|
||||
});
|
||||
return tmp;
|
||||
},
|
||||
count:function(_array,_value){
|
||||
var count = 0;
|
||||
pi.util.Array.forEach(_array,function(){
|
||||
count+=Number(arguments[0]==_value);
|
||||
});
|
||||
return count;
|
||||
},
|
||||
forEach:function(_array,_function){
|
||||
if(_array.forEach)
|
||||
return _array.forEach(_function);
|
||||
for(var i=0,len=_array.length; i<len; i++)
|
||||
_function.apply(_array,[_array[i],i,_array]);
|
||||
},
|
||||
getLatest:function(_array){
|
||||
return _array[_array.length-1];
|
||||
},
|
||||
indexOf:function(_array,_value){
|
||||
if(!pi.env.ie){
|
||||
return _array.indexOf(_value);
|
||||
};
|
||||
|
||||
var index = -1;
|
||||
for(var i=0, len=_array.length; i<len; i++){
|
||||
if(_array[i]==_value){
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
},
|
||||
remove:function(_array,_index){
|
||||
var result = _array.slice(0,_index);
|
||||
_array = Array.prototype.push.apply(result,_array.slice(_index+1));
|
||||
return result;
|
||||
}
|
||||
},
|
||||
Curry:function(_fn,_scope){
|
||||
var fn = _fn, scope = _scope||window, args = Array.prototype.slice.call(arguments,2);
|
||||
return function(){
|
||||
return fn.apply(scope,args.concat( Array.prototype.slice.call(arguments,0) ));
|
||||
};
|
||||
},
|
||||
Extend:function(_superClass,_prototype,_skipClonning){
|
||||
var object = new pi.base;
|
||||
if(_prototype["$Init"]){
|
||||
object.init = _prototype["$Init"];
|
||||
delete _prototype["$Init"];
|
||||
};
|
||||
|
||||
object.body = _superClass==pi.base?_prototype:pi.util.Hash.merge(_prototype,_superClass.prototype);
|
||||
object.init=object.init||function(){
|
||||
if(_superClass!=pi.base)
|
||||
_superClass.apply(this,arguments);
|
||||
};
|
||||
|
||||
return object.build(_skipClonning);
|
||||
},
|
||||
IsArray:function(_object){
|
||||
if(_object===null){
|
||||
return false;
|
||||
}
|
||||
if(window.NodeList&&window.NamedNodeMap&&!pi.env.ie8){
|
||||
if(_object instanceof Array||_object instanceof NodeList||_object instanceof NamedNodeMap||(window.HTMLCollection&&_object instanceof HTMLCollection))
|
||||
return true;
|
||||
};
|
||||
if(!_object||_object==window||typeof _object=="function"||typeof _object=="string"||typeof _object.length!="number"){
|
||||
return false
|
||||
};
|
||||
var len = _object.length;
|
||||
if(len>0&&_object[0]!=undefined&&_object[len-1]!=undefined){
|
||||
return true;
|
||||
} else {
|
||||
for(var key in _object){
|
||||
if(key!="item"&&key!="length"&&key!="setNamedItemNS"&&key!="setNamedItem"&&key!="getNamedItem"&&key!="removeNamedItem"&&key!="getNamedItemNS"&&key!="removeNamedItemNS"&&key!="tags"){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true
|
||||
};
|
||||
},
|
||||
IsHash:function(_object){
|
||||
return _object && typeof _object=="object"&&(_object==window||_object instanceof Object)&&!_object.nodeName&&!pi.util.IsArray(_object)
|
||||
},
|
||||
Init:[],
|
||||
AddEvent: function(_element,_eventName,_fn,_useCapture){
|
||||
_element[pi.env.ie?"attachEvent":"addEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false);
|
||||
return pi.util.Curry(pi.util.AddEvent,this,_element);
|
||||
},
|
||||
RemoveEvent: function(_element,_eventName,_fn,_useCapture){
|
||||
_element[pi.env.ie?"detachEvent":"removeEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false);
|
||||
return pi.util.Curry(pi.util.RemoveEvent,this,_element);
|
||||
},
|
||||
Element:{
|
||||
addClass:function(_element,_class){
|
||||
if( !pi.util.Element.hasClass(_element,_class) )
|
||||
pi.util.Element.setClass(_element, pi.util.Element.getClass(_element) + " " + _class );
|
||||
},
|
||||
getClass:function(_element){
|
||||
return _element.getAttribute(pi.env.ie&&!pi.env.ie8?"className":"class")||"";
|
||||
},
|
||||
hasClass:function(_element,_class){
|
||||
return pi.util.Array.indexOf(pi.util.Element.getClass(_element).split(" "),_class)>-1;
|
||||
},
|
||||
removeClass:function(_element,_class){
|
||||
if( pi.util.Element.hasClass(_element,_class) ){
|
||||
var names = pi.util.Element.getClass(_element,_class).split(" ");
|
||||
pi.util.Element.setClass(
|
||||
_element,
|
||||
pi.util.Array.remove(names,pi.util.Array.indexOf(names,_class)).join(" ")
|
||||
);
|
||||
}
|
||||
},
|
||||
setClass:function(_element,_value){
|
||||
if(pi.env.ie8){
|
||||
_element.setAttribute("className", _value );
|
||||
_element.setAttribute("class", _value );
|
||||
} else {
|
||||
_element.setAttribute(pi.env.ie?"className":"class", _value );
|
||||
}
|
||||
},
|
||||
toggleClass:function(){
|
||||
if(pi.util.Element.hasClass.apply(this,arguments))
|
||||
pi.util.Element.removeClass.apply(this,arguments);
|
||||
else
|
||||
pi.util.Element.addClass.apply(this,arguments);
|
||||
},
|
||||
getOpacity:function(_styleObject){
|
||||
var styleObject = _styleObject;
|
||||
if(!pi.env.ie)
|
||||
return styleObject["opacity"];
|
||||
|
||||
var alpha = styleObject["filter"].match(/opacity\=(\d+)/i);
|
||||
return alpha?alpha[1]/100:1;
|
||||
},
|
||||
setOpacity:function(_element,_value){
|
||||
if(!pi.env.ie)
|
||||
return pi.util.Element.addStyle(_element,{ "opacity":_value });
|
||||
_value*=100;
|
||||
pi.util.Element.addStyle(_element,{ "filter":"alpha(opacity="+_value+")" });
|
||||
return this._parent_;
|
||||
},
|
||||
getPosition:function(_element){
|
||||
var parent = _element,offsetLeft = document.body.offsetLeft, offsetTop = document.body.offsetTop, view = pi.util.Element.getView(_element);
|
||||
while(parent&&parent!=document.body&&parent!=document.firstChild){
|
||||
offsetLeft +=parseInt(parent.offsetLeft);
|
||||
offsetTop += parseInt(parent.offsetTop);
|
||||
parent = parent.offsetParent;
|
||||
};
|
||||
return {
|
||||
"bottom":view["bottom"],
|
||||
"clientLeft":_element.clientLeft,
|
||||
"clientTop":_element.clientTop,
|
||||
"left":view["left"],
|
||||
"marginTop":view["marginTop"],
|
||||
"marginLeft":view["marginLeft"],
|
||||
"offsetLeft":offsetLeft,
|
||||
"offsetTop":offsetTop,
|
||||
"position":view["position"],
|
||||
"right":view["right"],
|
||||
"top":view["top"],
|
||||
"zIndex":view["zIndex"]
|
||||
};
|
||||
},
|
||||
getSize:function(_element){
|
||||
var view = pi.util.Element.getView(_element);
|
||||
return {
|
||||
"height":view["height"],
|
||||
"clientHeight":_element.clientHeight,
|
||||
"clientWidth":_element.clientWidth,
|
||||
"offsetHeight":_element.offsetHeight,
|
||||
"offsetWidth":_element.offsetWidth,
|
||||
"width":view["width"]
|
||||
}
|
||||
},
|
||||
addStyle:function(_element,_style){
|
||||
for(var key in _style){
|
||||
key = key=="float"?pi.env.ie?"styleFloat":"cssFloat":key;
|
||||
if (key == "opacity" && pi.env.ie) {
|
||||
pi.util.Element.setOpacity(_element,_style[key]);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
_element.style[key] = _style[key];
|
||||
}catch(e){}
|
||||
}
|
||||
},
|
||||
getStyle:function(_element,_property){
|
||||
_property = _property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property;
|
||||
if(_property=="opacity"&&pi.env.ie)
|
||||
return pi.util.Element.getOpacity(_element.style);
|
||||
return typeof _property=="string"?_element.style[_property]:_element.style;
|
||||
},
|
||||
getValue:function(_element){
|
||||
switch(_element.nodeName.toLowerCase()){
|
||||
case "input":
|
||||
case "textarea":
|
||||
return _element.value;
|
||||
case "select":
|
||||
return _element.options[_element.selectedIndex].value;
|
||||
default:
|
||||
return _element.innerHTML;
|
||||
break;
|
||||
}
|
||||
},
|
||||
getView:function(_element,_property){
|
||||
var view = document.defaultView?document.defaultView.getComputedStyle(_element,null):_element.currentStyle;
|
||||
_property = _property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property;
|
||||
if(_property=="opacity"&&pi.env.ie)
|
||||
return pi.util.Element.getOpacity(_element,view);
|
||||
return typeof _property=="string"?view[_property]:view;
|
||||
}
|
||||
},
|
||||
Hash: {
|
||||
clone:function(_hash,_undeep){
|
||||
var tmp = {};
|
||||
for(var key in _hash){
|
||||
if( !_undeep&&pi.util.IsArray( _hash[key] ) ){
|
||||
tmp[key] = pi.util.Array.clone( _hash[key] );
|
||||
} else if( !_undeep&&pi.util.IsHash( _hash[key] ) ){
|
||||
tmp[ key ] = pi.util.Hash.clone(_hash[key]);
|
||||
} else {
|
||||
tmp[key] = _hash[key];
|
||||
}
|
||||
}
|
||||
return tmp;
|
||||
},
|
||||
merge:function(_hash,_source,_undeep){
|
||||
for(var key in _source){
|
||||
var value = _source[key];
|
||||
if (!_undeep&&pi.util.IsArray(_source[key])) {
|
||||
if(pi.util.IsArray( _hash[key] )){
|
||||
Array.prototype.push.apply( _source[key], _hash[key] )
|
||||
}
|
||||
else
|
||||
value = pi.util.Array.clone(_source[key]);
|
||||
}
|
||||
else if (!_undeep&&pi.util.IsHash(_source[key])) {
|
||||
if (pi.util.IsHash(_hash[key])) {
|
||||
value = pi.util.Hash.merge(_hash[key], _source[key]);
|
||||
} else {
|
||||
value = pi.util.Hash.clone( _source[key] );
|
||||
}
|
||||
} else if( _hash[key] )
|
||||
value = _hash[ key ];
|
||||
_hash[key] = value;
|
||||
};
|
||||
return _hash;
|
||||
}
|
||||
},
|
||||
String:{
|
||||
format:function(_str){
|
||||
var values = Array.prototype.slice.call(arguments,1);
|
||||
return _str.replace(/\{(\d)\}/g,function(){
|
||||
return values[arguments[1]];
|
||||
})
|
||||
}
|
||||
},
|
||||
GetViewport:function(){
|
||||
return {
|
||||
height:document.documentElement.clientHeight||document.body.clientHeight,
|
||||
width:document.documentElement.clientWidth||document.body.clientWidth
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pi.base = function(){
|
||||
this.body = {};
|
||||
this.init = null;
|
||||
|
||||
this.build = function(_skipClonning){
|
||||
var base = this, skipClonning = _skipClonning||false, _private = {},
|
||||
fn = function(){
|
||||
var _p = pi.util.Hash.clone(_private);
|
||||
if(!skipClonning){
|
||||
for(var key in this){
|
||||
if(pi.util.IsArray( this[ key ] ) ){
|
||||
this[key] = pi.util.Array.clone( this[key] );
|
||||
} else
|
||||
if( pi.util.IsHash(this[key]) ){
|
||||
this[key] = pi.util.Hash.clone(
|
||||
this[ key ],
|
||||
function(_key,_object){
|
||||
this[ _key ]._parent_ = this;
|
||||
}
|
||||
);
|
||||
//this[key]._parent_ = this;
|
||||
}
|
||||
}
|
||||
};
|
||||
base.createAccessors( _p, this );
|
||||
if(base.init)
|
||||
return base.init.apply(this,arguments);
|
||||
return this;
|
||||
};
|
||||
this.movePrivateMembers(this.body,_private);
|
||||
if(this.init){
|
||||
fn["$Init"] = this.init;
|
||||
};
|
||||
fn.prototype = this.body;
|
||||
return fn;
|
||||
};
|
||||
|
||||
this.createAccessors = function(_p, _branch){
|
||||
var getter = function(_property){ return this[_property]; },
|
||||
setter = function(_property,_value){ this[_property] = _value; return _branch._parent_||_branch; };
|
||||
|
||||
for (var name in _p) {
|
||||
var isPrivate = name.substring(0, 1) == "_", title = name.substring(1, 2).toUpperCase() + name.substring(2);
|
||||
|
||||
if (isPrivate) {
|
||||
_branch[(_branch["get" + title]?"_":"")+"get" + title] = pi.util.Curry(getter,_p,name);
|
||||
_branch[(_branch["set" + title]?"_":"")+"set" + title] = pi.util.Curry(setter,_p,name);
|
||||
}
|
||||
else
|
||||
if (pi.util.IsHash(_p[name])){
|
||||
_branch[name]._parent_ = _branch;
|
||||
if(!_branch[name])
|
||||
_branch[name] = {};
|
||||
this.createAccessors(_p[name], _branch[name]);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
this.movePrivateMembers = function(_object, _branch){
|
||||
for (var name in _object) {
|
||||
var isPrivate = name.substring(0, 1) == "_";
|
||||
|
||||
if (isPrivate) {
|
||||
_branch[name] = _object[name];
|
||||
delete _object[name];
|
||||
}
|
||||
else
|
||||
if (pi.util.IsHash(_object[name])){
|
||||
_branch[name] = {};
|
||||
this.movePrivateMembers(_object[name], _branch[name]);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pi.element = new pi.base;
|
||||
pi.element.init = function(_val){
|
||||
this.environment.setElement(
|
||||
typeof _val=="string"||!_val?
|
||||
document.createElement(_val||"DIV"):
|
||||
_val
|
||||
);
|
||||
return this;
|
||||
};
|
||||
|
||||
pi.element.body = {
|
||||
"addStyle":function(){
|
||||
return this.environment.addStyle.apply(this.environment,arguments);
|
||||
},
|
||||
"clean":function(){
|
||||
var childs = this.child.get();
|
||||
while(childs.length){
|
||||
childs[0].parentNode.removeChild(childs[0]);
|
||||
}
|
||||
},
|
||||
"clone":function(_deep){
|
||||
return this.environment.getElement().cloneNode(_deep);
|
||||
},
|
||||
"insert":function(_element){
|
||||
_element = _element.environment?_element.environment.getElement():_element;
|
||||
_element.appendChild(this.environment.getElement());
|
||||
return this;
|
||||
},
|
||||
"insertAfter":function(_referenceElement){
|
||||
_referenceElement = _referenceElement.environment?_referenceElement.environment.getElement():_referenceElement;
|
||||
_referenceElement.nextSibling?this.insertBefore(_referenceElement.nextSibling):this.insert(_referenceElement.parentNode);
|
||||
return this;
|
||||
},
|
||||
"insertBefore":function(_referenceElement){
|
||||
_referenceElement = _referenceElement.environment?_referenceElement.environment.getElement():_referenceElement;
|
||||
_referenceElement.parentNode.insertBefore(this.environment.getElement(),_referenceElement);
|
||||
return this;
|
||||
},
|
||||
"query":function(_expression,_resultType,namespaceResolver,_result){
|
||||
return pi.xpath(_expression,_resultType||"ORDERED_NODE_SNAPSHOT_TYPE",this.environment.getElement(),_namespaceResolver,_result);
|
||||
},
|
||||
"remove":function(){
|
||||
if (this.environment.getParent()) {
|
||||
this.environment.getParent().removeChild(this.environment.getElement());
|
||||
}
|
||||
},
|
||||
"update":function(_value){
|
||||
this.element[this.element.nodeName.toLowerCase()=="textarea"||this.element.nodeName.toLowerCase()=="input"?"value":"innerHTML"]=_value;
|
||||
return this;
|
||||
},
|
||||
"attribute":{
|
||||
"getAll":function(){
|
||||
return this._parent_.environment.getElement().attributes;
|
||||
},
|
||||
"clear":function(_name){
|
||||
this.set(_name,"");
|
||||
return this._parent_;
|
||||
},
|
||||
"get":function(_name){
|
||||
return this._parent_.environment.getElement().getAttribute(_name);
|
||||
},
|
||||
"has":function(_name){
|
||||
return pi.env.ie?(this.get(_name)!=null):this._parent_.environment.getElement().hasAttribute(_name);
|
||||
},
|
||||
"remove":function(_name){
|
||||
this._parent_.environment.getElement().removeAttribute(_name);
|
||||
return this._parent_;
|
||||
},
|
||||
"set":function(_name,_value){
|
||||
this._parent_.environment.getElement().setAttribute(_name,_value);
|
||||
return this._parent_;
|
||||
},
|
||||
"addClass":function(_classes){
|
||||
for(var i=0,len=arguments.length; i<len; i++){
|
||||
pi.util.Element.addClass(this._parent_.environment.getElement(),arguments[i]);
|
||||
};
|
||||
return this._parent_;
|
||||
},
|
||||
"clearClass":function(){
|
||||
this.setClass("");
|
||||
this._parent_;
|
||||
},
|
||||
"getClass":function(){
|
||||
return pi.util.Element.getClass( this._parent_.environment.getElement() );
|
||||
},
|
||||
"hasClass":function(_class){
|
||||
return pi.util.Element.hasClass( this._parent_.environment.getElement(), _class );
|
||||
},
|
||||
"setClass":function(_value){
|
||||
return pi.util.Element.setClass( this._parent_.environment.getElement(), _value );
|
||||
},
|
||||
"removeClass":function(_class){
|
||||
pi.util.Element.removeClass( this._parent_.environment.getElement(), _class );
|
||||
return this._parent_;
|
||||
},
|
||||
"toggleClass":function(_class){
|
||||
pi.util.Element.toggleClass( this._parent_.environment.getElement(), _class );
|
||||
}
|
||||
},
|
||||
"child":{
|
||||
"get":function(){
|
||||
return this._parent_.environment.getElement().childNodes;
|
||||
},
|
||||
"add":function(_elements){
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var el = arguments[i];
|
||||
this._parent_.environment.getElement().appendChild(
|
||||
el.environment ? el.environment.getElement() : el
|
||||
);
|
||||
}
|
||||
return this._parent_;
|
||||
},
|
||||
"addAfter":function(_element,_referenceElement){
|
||||
this.addBefore(
|
||||
_element.environment?_element.environment.getElement():_element,
|
||||
(_referenceElement.environment?_referenceElement.environment.getElement():_referenceElement).nextSibling
|
||||
);
|
||||
return this._parent_;
|
||||
},
|
||||
"addBefore":function(_element,_referenceElement){
|
||||
this._parent_.environment.getElement().insertBefore(
|
||||
_element.environment?_element.environment.getElement():_element,
|
||||
_referenceElement.environment?_referenceElement.environment.getElement():_referenceElement
|
||||
);
|
||||
return this._parent_;
|
||||
},
|
||||
"remove":function(_element){
|
||||
this._parent_.environment.getElement().removeChild(_element.environment?_element.environment.getElement():_element);
|
||||
}
|
||||
},
|
||||
"environment":{
|
||||
"_element":null,
|
||||
"setElement":function(_value){
|
||||
this._parent_.element = _value;
|
||||
this._parent_.element.lib = this._parent_;
|
||||
this._parent_.element.firebugElement = true;
|
||||
this._setElement(_value);
|
||||
},
|
||||
"getParent":function(){
|
||||
return this.getElement().parentNode;
|
||||
},
|
||||
"getPosition":function(){
|
||||
return pi.util.Element.getPosition(this.getElement());
|
||||
},
|
||||
"getSize":function(){
|
||||
return pi.util.Element.getSize( this.getElement() );
|
||||
},
|
||||
"addStyle":function(_styleObject){
|
||||
pi.util.Element.addStyle(this.getElement(),_styleObject);
|
||||
return this._parent_;
|
||||
},
|
||||
"getStyle":function(_property){
|
||||
return pi.util.Element.getStyle(this.getElement(),_property);
|
||||
},
|
||||
"getName":function(){
|
||||
return this.getElement().nodeName;
|
||||
},
|
||||
"getType":function(){
|
||||
return this.getElement().nodeType;
|
||||
},
|
||||
"getValue":function(){
|
||||
return pi.util.Element.getValue(this.getElement());
|
||||
},
|
||||
"getView":function(_property){
|
||||
return pi.util.Element.getView(this.getElement(),_property);
|
||||
}
|
||||
},
|
||||
"event":{
|
||||
"addListener":function(_event,_fn,_useCapture){
|
||||
pi.util.AddEvent(this._parent_.environment.getElement(),_event,_fn,_useCapture);
|
||||
return this._parent_;
|
||||
},
|
||||
"removeListener":function(_event,_fn,_useCapture){
|
||||
pi.util.RemoveEvent(this._parent_.environment.getElement(),_event,_fn,_useCapture);
|
||||
return this._parent_;
|
||||
}
|
||||
}
|
||||
};
|
||||
pi.element = pi.element.build();
|
||||
|
||||
pi.xhr = new pi.base;
|
||||
pi.xhr.init = function(_url){
|
||||
if(!window.XMLHttpRequest){
|
||||
var names = ["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
try {
|
||||
this.environment.setApi(new ActiveXObject(names[i]));
|
||||
break;
|
||||
} catch (e) { continue; }
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.environment.setApi(new XMLHttpRequest());
|
||||
}
|
||||
this.environment.getApi().onreadystatechange=pi.util.Curry(this.event.readystatechange,this);
|
||||
this.environment.setUrl(_url);
|
||||
this.environment.setCallback([]);
|
||||
|
||||
return this;
|
||||
};
|
||||
pi.xhr.body = {
|
||||
"addCallback": function(){
|
||||
return this.environment.addCallback.apply(this.environment,arguments);
|
||||
},
|
||||
"addData": function(){
|
||||
return this.environment.addData.apply(this.environment,arguments);
|
||||
},
|
||||
"abort":function(){
|
||||
this.environment.getApi().abort();
|
||||
return this;
|
||||
},
|
||||
"send":function(){
|
||||
var url = this.environment.getUrl(), data = this.environment.getData(),dataUrl = "";
|
||||
|
||||
if(!this.environment.getCache())
|
||||
data["forceCache"] = Number(new Date);
|
||||
|
||||
for (var key in data)
|
||||
dataUrl += pi.util.String.format("{0}={1}&",key, data[key]);
|
||||
|
||||
if (this.environment.getType()=="GET")
|
||||
url += (url.search("\\?")==-1?"?":"&")+pi.util.String.format("{0}",dataUrl);
|
||||
|
||||
this.api.open(this.environment.getType(),url,this.environment.getAsync());
|
||||
if(this.environment.getType()=="POST"){
|
||||
this.api.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
|
||||
};
|
||||
this.api.send(this.environment.getType()=="GET"?"":dataUrl);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
pi.xhr.body.environment = {
|
||||
"_async":true, "_api":null, "_cache":true, "_callback":null, "_data":{}, "_type":"GET", "_url":"",
|
||||
"setApi":function(_value){
|
||||
this._parent_.api = _value;
|
||||
this._setApi(_value);
|
||||
},
|
||||
"addCallback": function(_readyState,_fn){
|
||||
this.getCallback().push({ "fn":_fn, "readyState":_readyState });
|
||||
return this._parent_;
|
||||
},
|
||||
"addData": function(_key,_value){
|
||||
this.getData()[_key] = _value;
|
||||
return this._parent_;
|
||||
},
|
||||
"setType": function(_value){
|
||||
this._setType(_value);
|
||||
return this._parent_;
|
||||
}
|
||||
};
|
||||
pi.xhr.body.event = {
|
||||
"readystatechange":function(){
|
||||
var readyState = this.environment.getApi().readyState, callback=this.environment.getCallback();
|
||||
for (var i = 0, len=callback.length; i < len; i++) {
|
||||
if(pi.util.Array.indexOf(callback[i].readyState,readyState)>-1){
|
||||
callback[i].fn.apply(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
pi.xhr = pi.xhr.build();
|
||||
|
||||
/*
|
||||
* xml.xhr.get
|
||||
*/
|
||||
|
||||
pi.xhr.get = function(_url,_returnPiObject){
|
||||
var request = new pi.xhr();
|
||||
request.environment.setAsync(false);
|
||||
request.environment.setUrl(_url);
|
||||
request.send();
|
||||
return _returnPiObject?request:request.environment.getApi();
|
||||
};
|
||||
|
||||
/*
|
||||
* registering onload event for init functions
|
||||
*/
|
||||
pi.util.AddEvent(
|
||||
pi.env.ie?window:document,
|
||||
pi.env.ie?"load":"DOMContentLoaded",
|
||||
function(){
|
||||
for(var i=0,len=pi.util.Init.length; i<len; i++){
|
||||
pi.util.Init[ i ]();
|
||||
}
|
||||
}
|
||||
);
|
||||
})(firebug);
|
||||
|
||||
with(firebug){
|
||||
initConsole();
|
||||
lib.util.Init.push(firebug.init);
|
||||
}
|
BIN
thirdparty/jquery-concrete/vendor/firebug_lite/firebug.gif
vendored
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
thirdparty/jquery-concrete/vendor/firebug_lite/firebug_logo.png
vendored
Normal file
After Width: | Height: | Size: 499 B |
BIN
thirdparty/jquery-concrete/vendor/firebug_lite/infoIcon.png
vendored
Normal file
After Width: | Height: | Size: 524 B |
BIN
thirdparty/jquery-concrete/vendor/firebug_lite/progress.gif
vendored
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
thirdparty/jquery-concrete/vendor/firebug_lite/spacer.gif
vendored
Normal file
After Width: | Height: | Size: 64 B |
BIN
thirdparty/jquery-concrete/vendor/firebug_lite/tree_close.gif
vendored
Normal file
After Width: | Height: | Size: 300 B |
BIN
thirdparty/jquery-concrete/vendor/firebug_lite/tree_open.gif
vendored
Normal file
After Width: | Height: | Size: 202 B |
BIN
thirdparty/jquery-concrete/vendor/firebug_lite/warningIcon.png
vendored
Normal file
After Width: | Height: | Size: 516 B |
4376
thirdparty/jquery-concrete/vendor/jquery-1.3.2.js
vendored
Normal file
@ -0,0 +1,4376 @@
|
||||
/*!
|
||||
* jQuery JavaScript Library v1.3.2
|
||||
* http://jquery.com/
|
||||
*
|
||||
* Copyright (c) 2009 John Resig
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://docs.jquery.com/License
|
||||
*
|
||||
* Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
|
||||
* Revision: 6246
|
||||
*/
|
||||
(function(){
|
||||
|
||||
var
|
||||
// Will speed up references to window, and allows munging its name.
|
||||
window = this,
|
||||
// Will speed up references to undefined, and allows munging its name.
|
||||
undefined,
|
||||
// Map over jQuery in case of overwrite
|
||||
_jQuery = window.jQuery,
|
||||
// Map over the $ in case of overwrite
|
||||
_$ = window.$,
|
||||
|
||||
jQuery = window.jQuery = window.$ = function( selector, context ) {
|
||||
// The jQuery object is actually just the init constructor 'enhanced'
|
||||
return new jQuery.fn.init( selector, context );
|
||||
},
|
||||
|
||||
// A simple way to check for HTML strings or ID strings
|
||||
// (both of which we optimize for)
|
||||
quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
|
||||
// Is it a simple selector
|
||||
isSimple = /^.[^:#\[\.,]*$/;
|
||||
|
||||
jQuery.fn = jQuery.prototype = {
|
||||
init: function( selector, context ) {
|
||||
// Make sure that a selection was provided
|
||||
selector = selector || document;
|
||||
|
||||
// Handle $(DOMElement)
|
||||
if ( selector.nodeType ) {
|
||||
this[0] = selector;
|
||||
this.length = 1;
|
||||
this.context = selector;
|
||||
return this;
|
||||
}
|
||||
// Handle HTML strings
|
||||
if ( typeof selector === "string" ) {
|
||||
// Are we dealing with HTML string or an ID?
|
||||
var match = quickExpr.exec( selector );
|
||||
|
||||
// Verify a match, and that no context was specified for #id
|
||||
if ( match && (match[1] || !context) ) {
|
||||
|
||||
// HANDLE: $(html) -> $(array)
|
||||
if ( match[1] )
|
||||
selector = jQuery.clean( [ match[1] ], context );
|
||||
|
||||
// HANDLE: $("#id")
|
||||
else {
|
||||
var elem = document.getElementById( match[3] );
|
||||
|
||||
// Handle the case where IE and Opera return items
|
||||
// by name instead of ID
|
||||
if ( elem && elem.id != match[3] )
|
||||
return jQuery().find( selector );
|
||||
|
||||
// Otherwise, we inject the element directly into the jQuery object
|
||||
var ret = jQuery( elem || [] );
|
||||
ret.context = document;
|
||||
ret.selector = selector;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// HANDLE: $(expr, [context])
|
||||
// (which is just equivalent to: $(content).find(expr)
|
||||
} else
|
||||
return jQuery( context ).find( selector );
|
||||
|
||||
// HANDLE: $(function)
|
||||
// Shortcut for document ready
|
||||
} else if ( jQuery.isFunction( selector ) )
|
||||
return jQuery( document ).ready( selector );
|
||||
|
||||
// Make sure that old selector state is passed along
|
||||
if ( selector.selector && selector.context ) {
|
||||
this.selector = selector.selector;
|
||||
this.context = selector.context;
|
||||
}
|
||||
|
||||
return this.setArray(jQuery.isArray( selector ) ?
|
||||
selector :
|
||||
jQuery.makeArray(selector));
|
||||
},
|
||||
|
||||
// Start with an empty selector
|
||||
selector: "",
|
||||
|
||||
// The current version of jQuery being used
|
||||
jquery: "1.3.2",
|
||||
|
||||
// The number of elements contained in the matched element set
|
||||
size: function() {
|
||||
return this.length;
|
||||
},
|
||||
|
||||
// Get the Nth element in the matched element set OR
|
||||
// Get the whole matched element set as a clean array
|
||||
get: function( num ) {
|
||||
return num === undefined ?
|
||||
|
||||
// Return a 'clean' array
|
||||
Array.prototype.slice.call( this ) :
|
||||
|
||||
// Return just the object
|
||||
this[ num ];
|
||||
},
|
||||
|
||||
// Take an array of elements and push it onto the stack
|
||||
// (returning the new matched element set)
|
||||
pushStack: function( elems, name, selector ) {
|
||||
// Build a new jQuery matched element set
|
||||
var ret = jQuery( elems );
|
||||
|
||||
// Add the old object onto the stack (as a reference)
|
||||
ret.prevObject = this;
|
||||
|
||||
ret.context = this.context;
|
||||
|
||||
if ( name === "find" )
|
||||
ret.selector = this.selector + (this.selector ? " " : "") + selector;
|
||||
else if ( name )
|
||||
ret.selector = this.selector + "." + name + "(" + selector + ")";
|
||||
|
||||
// Return the newly-formed element set
|
||||
return ret;
|
||||
},
|
||||
|
||||
// Force the current matched set of elements to become
|
||||
// the specified array of elements (destroying the stack in the process)
|
||||
// You should use pushStack() in order to do this, but maintain the stack
|
||||
setArray: function( elems ) {
|
||||
// Resetting the length to 0, then using the native Array push
|
||||
// is a super-fast way to populate an object with array-like properties
|
||||
this.length = 0;
|
||||
Array.prototype.push.apply( this, elems );
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Execute a callback for every element in the matched set.
|
||||
// (You can seed the arguments with an array of args, but this is
|
||||
// only used internally.)
|
||||
each: function( callback, args ) {
|
||||
return jQuery.each( this, callback, args );
|
||||
},
|
||||
|
||||
// Determine the position of an element within
|
||||
// the matched set of elements
|
||||
index: function( elem ) {
|
||||
// Locate the position of the desired element
|
||||
return jQuery.inArray(
|
||||
// If it receives a jQuery object, the first element is used
|
||||
elem && elem.jquery ? elem[0] : elem
|
||||
, this );
|
||||
},
|
||||
|
||||
attr: function( name, value, type ) {
|
||||
var options = name;
|
||||
|
||||
// Look for the case where we're accessing a style value
|
||||
if ( typeof name === "string" )
|
||||
if ( value === undefined )
|
||||
return this[0] && jQuery[ type || "attr" ]( this[0], name );
|
||||
|
||||
else {
|
||||
options = {};
|
||||
options[ name ] = value;
|
||||
}
|
||||
|
||||
// Check to see if we're setting style values
|
||||
return this.each(function(i){
|
||||
// Set all the styles
|
||||
for ( name in options )
|
||||
jQuery.attr(
|
||||
type ?
|
||||
this.style :
|
||||
this,
|
||||
name, jQuery.prop( this, options[ name ], type, i, name )
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
css: function( key, value ) {
|
||||
// ignore negative width and height values
|
||||
if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
|
||||
value = undefined;
|
||||
return this.attr( key, value, "curCSS" );
|
||||
},
|
||||
|
||||
text: function( text ) {
|
||||
if ( typeof text !== "object" && text != null )
|
||||
return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
|
||||
|
||||
var ret = "";
|
||||
|
||||
jQuery.each( text || this, function(){
|
||||
jQuery.each( this.childNodes, function(){
|
||||
if ( this.nodeType != 8 )
|
||||
ret += this.nodeType != 1 ?
|
||||
this.nodeValue :
|
||||
jQuery.fn.text( [ this ] );
|
||||
});
|
||||
});
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
wrapAll: function( html ) {
|
||||
if ( this[0] ) {
|
||||
// The elements to wrap the target around
|
||||
var wrap = jQuery( html, this[0].ownerDocument ).clone();
|
||||
|
||||
if ( this[0].parentNode )
|
||||
wrap.insertBefore( this[0] );
|
||||
|
||||
wrap.map(function(){
|
||||
var elem = this;
|
||||
|
||||
while ( elem.firstChild )
|
||||
elem = elem.firstChild;
|
||||
|
||||
return elem;
|
||||
}).append(this);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
wrapInner: function( html ) {
|
||||
return this.each(function(){
|
||||
jQuery( this ).contents().wrapAll( html );
|
||||
});
|
||||
},
|
||||
|
||||
wrap: function( html ) {
|
||||
return this.each(function(){
|
||||
jQuery( this ).wrapAll( html );
|
||||
});
|
||||
},
|
||||
|
||||
append: function() {
|
||||
return this.domManip(arguments, true, function(elem){
|
||||
if (this.nodeType == 1)
|
||||
this.appendChild( elem );
|
||||
});
|
||||
},
|
||||
|
||||
prepend: function() {
|
||||
return this.domManip(arguments, true, function(elem){
|
||||
if (this.nodeType == 1)
|
||||
this.insertBefore( elem, this.firstChild );
|
||||
});
|
||||
},
|
||||
|
||||
before: function() {
|
||||
return this.domManip(arguments, false, function(elem){
|
||||
this.parentNode.insertBefore( elem, this );
|
||||
});
|
||||
},
|
||||
|
||||
after: function() {
|
||||
return this.domManip(arguments, false, function(elem){
|
||||
this.parentNode.insertBefore( elem, this.nextSibling );
|
||||
});
|
||||
},
|
||||
|
||||
end: function() {
|
||||
return this.prevObject || jQuery( [] );
|
||||
},
|
||||
|
||||
// For internal use only.
|
||||
// Behaves like an Array's method, not like a jQuery method.
|
||||
push: [].push,
|
||||
sort: [].sort,
|
||||
splice: [].splice,
|
||||
|
||||
find: function( selector ) {
|
||||
if ( this.length === 1 ) {
|
||||
var ret = this.pushStack( [], "find", selector );
|
||||
ret.length = 0;
|
||||
jQuery.find( selector, this[0], ret );
|
||||
return ret;
|
||||
} else {
|
||||
return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
|
||||
return jQuery.find( selector, elem );
|
||||
})), "find", selector );
|
||||
}
|
||||
},
|
||||
|
||||
clone: function( events ) {
|
||||
// Do the clone
|
||||
var ret = this.map(function(){
|
||||
if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
|
||||
// IE copies events bound via attachEvent when
|
||||
// using cloneNode. Calling detachEvent on the
|
||||
// clone will also remove the events from the orignal
|
||||
// In order to get around this, we use innerHTML.
|
||||
// Unfortunately, this means some modifications to
|
||||
// attributes in IE that are actually only stored
|
||||
// as properties will not be copied (such as the
|
||||
// the name attribute on an input).
|
||||
var html = this.outerHTML;
|
||||
if ( !html ) {
|
||||
var div = this.ownerDocument.createElement("div");
|
||||
div.appendChild( this.cloneNode(true) );
|
||||
html = div.innerHTML;
|
||||
}
|
||||
|
||||
return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
|
||||
} else
|
||||
return this.cloneNode(true);
|
||||
});
|
||||
|
||||
// Copy the events from the original to the clone
|
||||
if ( events === true ) {
|
||||
var orig = this.find("*").andSelf(), i = 0;
|
||||
|
||||
ret.find("*").andSelf().each(function(){
|
||||
if ( this.nodeName !== orig[i].nodeName )
|
||||
return;
|
||||
|
||||
var events = jQuery.data( orig[i], "events" );
|
||||
|
||||
for ( var type in events ) {
|
||||
for ( var handler in events[ type ] ) {
|
||||
jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
});
|
||||
}
|
||||
|
||||
// Return the cloned set
|
||||
return ret;
|
||||
},
|
||||
|
||||
filter: function( selector ) {
|
||||
return this.pushStack(
|
||||
jQuery.isFunction( selector ) &&
|
||||
jQuery.grep(this, function(elem, i){
|
||||
return selector.call( elem, i );
|
||||
}) ||
|
||||
|
||||
jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
|
||||
return elem.nodeType === 1;
|
||||
}) ), "filter", selector );
|
||||
},
|
||||
|
||||
closest: function( selector ) {
|
||||
var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
|
||||
closer = 0;
|
||||
|
||||
return this.map(function(){
|
||||
var cur = this;
|
||||
while ( cur && cur.ownerDocument ) {
|
||||
if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
|
||||
jQuery.data(cur, "closest", closer);
|
||||
return cur;
|
||||
}
|
||||
cur = cur.parentNode;
|
||||
closer++;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
not: function( selector ) {
|
||||
if ( typeof selector === "string" )
|
||||
// test special case where just one selector is passed in
|
||||
if ( isSimple.test( selector ) )
|
||||
return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
|
||||
else
|
||||
selector = jQuery.multiFilter( selector, this );
|
||||
|
||||
var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
|
||||
return this.filter(function() {
|
||||
return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
|
||||
});
|
||||
},
|
||||
|
||||
add: function( selector ) {
|
||||
return this.pushStack( jQuery.unique( jQuery.merge(
|
||||
this.get(),
|
||||
typeof selector === "string" ?
|
||||
jQuery( selector ) :
|
||||
jQuery.makeArray( selector )
|
||||
)));
|
||||
},
|
||||
|
||||
is: function( selector ) {
|
||||
return !!selector && jQuery.multiFilter( selector, this ).length > 0;
|
||||
},
|
||||
|
||||
hasClass: function( selector ) {
|
||||
return !!selector && this.is( "." + selector );
|
||||
},
|
||||
|
||||
val: function( value ) {
|
||||
if ( value === undefined ) {
|
||||
var elem = this[0];
|
||||
|
||||
if ( elem ) {
|
||||
if( jQuery.nodeName( elem, 'option' ) )
|
||||
return (elem.attributes.value || {}).specified ? elem.value : elem.text;
|
||||
|
||||
// We need to handle select boxes special
|
||||
if ( jQuery.nodeName( elem, "select" ) ) {
|
||||
var index = elem.selectedIndex,
|
||||
values = [],
|
||||
options = elem.options,
|
||||
one = elem.type == "select-one";
|
||||
|
||||
// Nothing was selected
|
||||
if ( index < 0 )
|
||||
return null;
|
||||
|
||||
// Loop through all the selected options
|
||||
for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
|
||||
var option = options[ i ];
|
||||
|
||||
if ( option.selected ) {
|
||||
// Get the specifc value for the option
|
||||
value = jQuery(option).val();
|
||||
|
||||
// We don't need an array for one selects
|
||||
if ( one )
|
||||
return value;
|
||||
|
||||
// Multi-Selects return an array
|
||||
values.push( value );
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
// Everything else, we just grab the value
|
||||
return (elem.value || "").replace(/\r/g, "");
|
||||
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if ( typeof value === "number" )
|
||||
value += '';
|
||||
|
||||
return this.each(function(){
|
||||
if ( this.nodeType != 1 )
|
||||
return;
|
||||
|
||||
if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
|
||||
this.checked = (jQuery.inArray(this.value, value) >= 0 ||
|
||||
jQuery.inArray(this.name, value) >= 0);
|
||||
|
||||
else if ( jQuery.nodeName( this, "select" ) ) {
|
||||
var values = jQuery.makeArray(value);
|
||||
|
||||
jQuery( "option", this ).each(function(){
|
||||
this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
|
||||
jQuery.inArray( this.text, values ) >= 0);
|
||||
});
|
||||
|
||||
if ( !values.length )
|
||||
this.selectedIndex = -1;
|
||||
|
||||
} else
|
||||
this.value = value;
|
||||
});
|
||||
},
|
||||
|
||||
html: function( value ) {
|
||||
return value === undefined ?
|
||||
(this[0] ?
|
||||
this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
|
||||
null) :
|
||||
this.empty().append( value );
|
||||
},
|
||||
|
||||
replaceWith: function( value ) {
|
||||
return this.after( value ).remove();
|
||||
},
|
||||
|
||||
eq: function( i ) {
|
||||
return this.slice( i, +i + 1 );
|
||||
},
|
||||
|
||||
slice: function() {
|
||||
return this.pushStack( Array.prototype.slice.apply( this, arguments ),
|
||||
"slice", Array.prototype.slice.call(arguments).join(",") );
|
||||
},
|
||||
|
||||
map: function( callback ) {
|
||||
return this.pushStack( jQuery.map(this, function(elem, i){
|
||||
return callback.call( elem, i, elem );
|
||||
}));
|
||||
},
|
||||
|
||||
andSelf: function() {
|
||||
return this.add( this.prevObject );
|
||||
},
|
||||
|
||||
domManip: function( args, table, callback ) {
|
||||
if ( this[0] ) {
|
||||
var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
|
||||
scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
|
||||
first = fragment.firstChild;
|
||||
|
||||
if ( first )
|
||||
for ( var i = 0, l = this.length; i < l; i++ )
|
||||
callback.call( root(this[i], first), this.length > 1 || i > 0 ?
|
||||
fragment.cloneNode(true) : fragment );
|
||||
|
||||
if ( scripts )
|
||||
jQuery.each( scripts, evalScript );
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
function root( elem, cur ) {
|
||||
return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
|
||||
(elem.getElementsByTagName("tbody")[0] ||
|
||||
elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
|
||||
elem;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Give the init function the jQuery prototype for later instantiation
|
||||
jQuery.fn.init.prototype = jQuery.fn;
|
||||
|
||||
function evalScript( i, elem ) {
|
||||
if ( elem.src )
|
||||
jQuery.ajax({
|
||||
url: elem.src,
|
||||
async: false,
|
||||
dataType: "script"
|
||||
});
|
||||
|
||||
else
|
||||
jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
|
||||
|
||||
if ( elem.parentNode )
|
||||
elem.parentNode.removeChild( elem );
|
||||
}
|
||||
|
||||
function now(){
|
||||
return +new Date;
|
||||
}
|
||||
|
||||
jQuery.extend = jQuery.fn.extend = function() {
|
||||
// copy reference to target object
|
||||
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
|
||||
|
||||
// Handle a deep copy situation
|
||||
if ( typeof target === "boolean" ) {
|
||||
deep = target;
|
||||
target = arguments[1] || {};
|
||||
// skip the boolean and the target
|
||||
i = 2;
|
||||
}
|
||||
|
||||
// Handle case when target is a string or something (possible in deep copy)
|
||||
if ( typeof target !== "object" && !jQuery.isFunction(target) )
|
||||
target = {};
|
||||
|
||||
// extend jQuery itself if only one argument is passed
|
||||
if ( length == i ) {
|
||||
target = this;
|
||||
--i;
|
||||
}
|
||||
|
||||
for ( ; i < length; i++ )
|
||||
// Only deal with non-null/undefined values
|
||||
if ( (options = arguments[ i ]) != null )
|
||||
// Extend the base object
|
||||
for ( var name in options ) {
|
||||
var src = target[ name ], copy = options[ name ];
|
||||
|
||||
// Prevent never-ending loop
|
||||
if ( target === copy )
|
||||
continue;
|
||||
|
||||
// Recurse if we're merging object values
|
||||
if ( deep && copy && typeof copy === "object" && !copy.nodeType )
|
||||
target[ name ] = jQuery.extend( deep,
|
||||
// Never move original objects, clone them
|
||||
src || ( copy.length != null ? [ ] : { } )
|
||||
, copy );
|
||||
|
||||
// Don't bring in undefined values
|
||||
else if ( copy !== undefined )
|
||||
target[ name ] = copy;
|
||||
|
||||
}
|
||||
|
||||
// Return the modified object
|
||||
return target;
|
||||
};
|
||||
|
||||
// exclude the following css properties to add px
|
||||
var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
|
||||
// cache defaultView
|
||||
defaultView = document.defaultView || {},
|
||||
toString = Object.prototype.toString;
|
||||
|
||||
jQuery.extend({
|
||||
noConflict: function( deep ) {
|
||||
window.$ = _$;
|
||||
|
||||
if ( deep )
|
||||
window.jQuery = _jQuery;
|
||||
|
||||
return jQuery;
|
||||
},
|
||||
|
||||
// See test/unit/core.js for details concerning isFunction.
|
||||
// Since version 1.3, DOM methods and functions like alert
|
||||
// aren't supported. They return false on IE (#2968).
|
||||
isFunction: function( obj ) {
|
||||
return toString.call(obj) === "[object Function]";
|
||||
},
|
||||
|
||||
isArray: function( obj ) {
|
||||
return toString.call(obj) === "[object Array]";
|
||||
},
|
||||
|
||||
// check if an element is in a (or is an) XML document
|
||||
isXMLDoc: function( elem ) {
|
||||
return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
|
||||
!!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
|
||||
},
|
||||
|
||||
// Evalulates a script in a global context
|
||||
globalEval: function( data ) {
|
||||
if ( data && /\S/.test(data) ) {
|
||||
// Inspired by code by Andrea Giammarchi
|
||||
// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
|
||||
var head = document.getElementsByTagName("head")[0] || document.documentElement,
|
||||
script = document.createElement("script");
|
||||
|
||||
script.type = "text/javascript";
|
||||
if ( jQuery.support.scriptEval )
|
||||
script.appendChild( document.createTextNode( data ) );
|
||||
else
|
||||
script.text = data;
|
||||
|
||||
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
|
||||
// This arises when a base node is used (#2709).
|
||||
head.insertBefore( script, head.firstChild );
|
||||
head.removeChild( script );
|
||||
}
|
||||
},
|
||||
|
||||
nodeName: function( elem, name ) {
|
||||
return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
|
||||
},
|
||||
|
||||
// args is for internal usage only
|
||||
each: function( object, callback, args ) {
|
||||
var name, i = 0, length = object.length;
|
||||
|
||||
if ( args ) {
|
||||
if ( length === undefined ) {
|
||||
for ( name in object )
|
||||
if ( callback.apply( object[ name ], args ) === false )
|
||||
break;
|
||||
} else
|
||||
for ( ; i < length; )
|
||||
if ( callback.apply( object[ i++ ], args ) === false )
|
||||
break;
|
||||
|
||||
// A special, fast, case for the most common use of each
|
||||
} else {
|
||||
if ( length === undefined ) {
|
||||
for ( name in object )
|
||||
if ( callback.call( object[ name ], name, object[ name ] ) === false )
|
||||
break;
|
||||
} else
|
||||
for ( var value = object[0];
|
||||
i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
|
||||
}
|
||||
|
||||
return object;
|
||||
},
|
||||
|
||||
prop: function( elem, value, type, i, name ) {
|
||||
// Handle executable functions
|
||||
if ( jQuery.isFunction( value ) )
|
||||
value = value.call( elem, i );
|
||||
|
||||
// Handle passing in a number to a CSS property
|
||||
return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
|
||||
value + "px" :
|
||||
value;
|
||||
},
|
||||
|
||||
className: {
|
||||
// internal only, use addClass("class")
|
||||
add: function( elem, classNames ) {
|
||||
jQuery.each((classNames || "").split(/\s+/), function(i, className){
|
||||
if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
|
||||
elem.className += (elem.className ? " " : "") + className;
|
||||
});
|
||||
},
|
||||
|
||||
// internal only, use removeClass("class")
|
||||
remove: function( elem, classNames ) {
|
||||
if (elem.nodeType == 1)
|
||||
elem.className = classNames !== undefined ?
|
||||
jQuery.grep(elem.className.split(/\s+/), function(className){
|
||||
return !jQuery.className.has( classNames, className );
|
||||
}).join(" ") :
|
||||
"";
|
||||
},
|
||||
|
||||
// internal only, use hasClass("class")
|
||||
has: function( elem, className ) {
|
||||
return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
|
||||
}
|
||||
},
|
||||
|
||||
// A method for quickly swapping in/out CSS properties to get correct calculations
|
||||
swap: function( elem, options, callback ) {
|
||||
var old = {};
|
||||
// Remember the old values, and insert the new ones
|
||||
for ( var name in options ) {
|
||||
old[ name ] = elem.style[ name ];
|
||||
elem.style[ name ] = options[ name ];
|
||||
}
|
||||
|
||||
callback.call( elem );
|
||||
|
||||
// Revert the old values
|
||||
for ( var name in options )
|
||||
elem.style[ name ] = old[ name ];
|
||||
},
|
||||
|
||||
css: function( elem, name, force, extra ) {
|
||||
if ( name == "width" || name == "height" ) {
|
||||
var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
|
||||
|
||||
function getWH() {
|
||||
val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
|
||||
|
||||
if ( extra === "border" )
|
||||
return;
|
||||
|
||||
jQuery.each( which, function() {
|
||||
if ( !extra )
|
||||
val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
|
||||
if ( extra === "margin" )
|
||||
val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
|
||||
else
|
||||
val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
|
||||
});
|
||||
}
|
||||
|
||||
if ( elem.offsetWidth !== 0 )
|
||||
getWH();
|
||||
else
|
||||
jQuery.swap( elem, props, getWH );
|
||||
|
||||
return Math.max(0, Math.round(val));
|
||||
}
|
||||
|
||||
return jQuery.curCSS( elem, name, force );
|
||||
},
|
||||
|
||||
curCSS: function( elem, name, force ) {
|
||||
var ret, style = elem.style;
|
||||
|
||||
// We need to handle opacity special in IE
|
||||
if ( name == "opacity" && !jQuery.support.opacity ) {
|
||||
ret = jQuery.attr( style, "opacity" );
|
||||
|
||||
return ret == "" ?
|
||||
"1" :
|
||||
ret;
|
||||
}
|
||||
|
||||
// Make sure we're using the right name for getting the float value
|
||||
if ( name.match( /float/i ) )
|
||||
name = styleFloat;
|
||||
|
||||
if ( !force && style && style[ name ] )
|
||||
ret = style[ name ];
|
||||
|
||||
else if ( defaultView.getComputedStyle ) {
|
||||
|
||||
// Only "float" is needed here
|
||||
if ( name.match( /float/i ) )
|
||||
name = "float";
|
||||
|
||||
name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
|
||||
|
||||
var computedStyle = defaultView.getComputedStyle( elem, null );
|
||||
|
||||
if ( computedStyle )
|
||||
ret = computedStyle.getPropertyValue( name );
|
||||
|
||||
// We should always get a number back from opacity
|
||||
if ( name == "opacity" && ret == "" )
|
||||
ret = "1";
|
||||
|
||||
} else if ( elem.currentStyle ) {
|
||||
var camelCase = name.replace(/\-(\w)/g, function(all, letter){
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
|
||||
ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
|
||||
|
||||
// From the awesome hack by Dean Edwards
|
||||
// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
|
||||
|
||||
// If we're not dealing with a regular pixel number
|
||||
// but a number that has a weird ending, we need to convert it to pixels
|
||||
if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
|
||||
// Remember the original values
|
||||
var left = style.left, rsLeft = elem.runtimeStyle.left;
|
||||
|
||||
// Put in the new values to get a computed value out
|
||||
elem.runtimeStyle.left = elem.currentStyle.left;
|
||||
style.left = ret || 0;
|
||||
ret = style.pixelLeft + "px";
|
||||
|
||||
// Revert the changed values
|
||||
style.left = left;
|
||||
elem.runtimeStyle.left = rsLeft;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
clean: function( elems, context, fragment ) {
|
||||
context = context || document;
|
||||
|
||||
// !context.createElement fails in IE with an error but returns typeof 'object'
|
||||
if ( typeof context.createElement === "undefined" )
|
||||
context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
|
||||
|
||||
// If a single string is passed in and it's a single tag
|
||||
// just do a createElement and skip the rest
|
||||
if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
|
||||
var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
|
||||
if ( match )
|
||||
return [ context.createElement( match[1] ) ];
|
||||
}
|
||||
|
||||
var ret = [], scripts = [], div = context.createElement("div");
|
||||
|
||||
jQuery.each(elems, function(i, elem){
|
||||
if ( typeof elem === "number" )
|
||||
elem += '';
|
||||
|
||||
if ( !elem )
|
||||
return;
|
||||
|
||||
// Convert html string into DOM nodes
|
||||
if ( typeof elem === "string" ) {
|
||||
// Fix "XHTML"-style tags in all browsers
|
||||
elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
|
||||
return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
|
||||
all :
|
||||
front + "></" + tag + ">";
|
||||
});
|
||||
|
||||
// Trim whitespace, otherwise indexOf won't work as expected
|
||||
var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
|
||||
|
||||
var wrap =
|
||||
// option or optgroup
|
||||
!tags.indexOf("<opt") &&
|
||||
[ 1, "<select multiple='multiple'>", "</select>" ] ||
|
||||
|
||||
!tags.indexOf("<leg") &&
|
||||
[ 1, "<fieldset>", "</fieldset>" ] ||
|
||||
|
||||
tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
|
||||
[ 1, "<table>", "</table>" ] ||
|
||||
|
||||
!tags.indexOf("<tr") &&
|
||||
[ 2, "<table><tbody>", "</tbody></table>" ] ||
|
||||
|
||||
// <thead> matched above
|
||||
(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
|
||||
[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
|
||||
|
||||
!tags.indexOf("<col") &&
|
||||
[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
|
||||
|
||||
// IE can't serialize <link> and <script> tags normally
|
||||
!jQuery.support.htmlSerialize &&
|
||||
[ 1, "div<div>", "</div>" ] ||
|
||||
|
||||
[ 0, "", "" ];
|
||||
|
||||
// Go to html and back, then peel off extra wrappers
|
||||
div.innerHTML = wrap[1] + elem + wrap[2];
|
||||
|
||||
// Move to the right depth
|
||||
while ( wrap[0]-- )
|
||||
div = div.lastChild;
|
||||
|
||||
// Remove IE's autoinserted <tbody> from table fragments
|
||||
if ( !jQuery.support.tbody ) {
|
||||
|
||||
// String was a <table>, *may* have spurious <tbody>
|
||||
var hasBody = /<tbody/i.test(elem),
|
||||
tbody = !tags.indexOf("<table") && !hasBody ?
|
||||
div.firstChild && div.firstChild.childNodes :
|
||||
|
||||
// String was a bare <thead> or <tfoot>
|
||||
wrap[1] == "<table>" && !hasBody ?
|
||||
div.childNodes :
|
||||
[];
|
||||
|
||||
for ( var j = tbody.length - 1; j >= 0 ; --j )
|
||||
if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
|
||||
tbody[ j ].parentNode.removeChild( tbody[ j ] );
|
||||
|
||||
}
|
||||
|
||||
// IE completely kills leading whitespace when innerHTML is used
|
||||
if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
|
||||
div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
|
||||
|
||||
elem = jQuery.makeArray( div.childNodes );
|
||||
}
|
||||
|
||||
if ( elem.nodeType )
|
||||
ret.push( elem );
|
||||
else
|
||||
ret = jQuery.merge( ret, elem );
|
||||
|
||||
});
|
||||
|
||||
if ( fragment ) {
|
||||
for ( var i = 0; ret[i]; i++ ) {
|
||||
if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
|
||||
scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
|
||||
} else {
|
||||
if ( ret[i].nodeType === 1 )
|
||||
ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
|
||||
fragment.appendChild( ret[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return scripts;
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
attr: function( elem, name, value ) {
|
||||
// don't set attributes on text and comment nodes
|
||||
if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
|
||||
return undefined;
|
||||
|
||||
var notxml = !jQuery.isXMLDoc( elem ),
|
||||
// Whether we are setting (or getting)
|
||||
set = value !== undefined;
|
||||
|
||||
// Try to normalize/fix the name
|
||||
name = notxml && jQuery.props[ name ] || name;
|
||||
|
||||
// Only do all the following if this is a node (faster for style)
|
||||
// IE elem.getAttribute passes even for style
|
||||
if ( elem.tagName ) {
|
||||
|
||||
// These attributes require special treatment
|
||||
var special = /href|src|style/.test( name );
|
||||
|
||||
// Safari mis-reports the default selected property of a hidden option
|
||||
// Accessing the parent's selectedIndex property fixes it
|
||||
if ( name == "selected" && elem.parentNode )
|
||||
elem.parentNode.selectedIndex;
|
||||
|
||||
// If applicable, access the attribute via the DOM 0 way
|
||||
if ( name in elem && notxml && !special ) {
|
||||
if ( set ){
|
||||
// We can't allow the type property to be changed (since it causes problems in IE)
|
||||
if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
|
||||
throw "type property can't be changed";
|
||||
|
||||
elem[ name ] = value;
|
||||
}
|
||||
|
||||
// browsers index elements by id/name on forms, give priority to attributes.
|
||||
if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
|
||||
return elem.getAttributeNode( name ).nodeValue;
|
||||
|
||||
// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
|
||||
// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
|
||||
if ( name == "tabIndex" ) {
|
||||
var attributeNode = elem.getAttributeNode( "tabIndex" );
|
||||
return attributeNode && attributeNode.specified
|
||||
? attributeNode.value
|
||||
: elem.nodeName.match(/(button|input|object|select|textarea)/i)
|
||||
? 0
|
||||
: elem.nodeName.match(/^(a|area)$/i) && elem.href
|
||||
? 0
|
||||
: undefined;
|
||||
}
|
||||
|
||||
return elem[ name ];
|
||||
}
|
||||
|
||||
if ( !jQuery.support.style && notxml && name == "style" )
|
||||
return jQuery.attr( elem.style, "cssText", value );
|
||||
|
||||
if ( set )
|
||||
// convert the value to a string (all browsers do this but IE) see #1070
|
||||
elem.setAttribute( name, "" + value );
|
||||
|
||||
var attr = !jQuery.support.hrefNormalized && notxml && special
|
||||
// Some attributes require a special call on IE
|
||||
? elem.getAttribute( name, 2 )
|
||||
: elem.getAttribute( name );
|
||||
|
||||
// Non-existent attributes return null, we normalize to undefined
|
||||
return attr === null ? undefined : attr;
|
||||
}
|
||||
|
||||
// elem is actually elem.style ... set the style
|
||||
|
||||
// IE uses filters for opacity
|
||||
if ( !jQuery.support.opacity && name == "opacity" ) {
|
||||
if ( set ) {
|
||||
// IE has trouble with opacity if it does not have layout
|
||||
// Force it by setting the zoom level
|
||||
elem.zoom = 1;
|
||||
|
||||
// Set the alpha filter to set the opacity
|
||||
elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
|
||||
(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
|
||||
}
|
||||
|
||||
return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
|
||||
(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
|
||||
"";
|
||||
}
|
||||
|
||||
name = name.replace(/-([a-z])/ig, function(all, letter){
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
|
||||
if ( set )
|
||||
elem[ name ] = value;
|
||||
|
||||
return elem[ name ];
|
||||
},
|
||||
|
||||
trim: function( text ) {
|
||||
return (text || "").replace( /^\s+|\s+$/g, "" );
|
||||
},
|
||||
|
||||
makeArray: function( array ) {
|
||||
var ret = [];
|
||||
|
||||
if( array != null ){
|
||||
var i = array.length;
|
||||
// The window, strings (and functions) also have 'length'
|
||||
if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
|
||||
ret[0] = array;
|
||||
else
|
||||
while( i )
|
||||
ret[--i] = array[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
inArray: function( elem, array ) {
|
||||
for ( var i = 0, length = array.length; i < length; i++ )
|
||||
// Use === because on IE, window == document
|
||||
if ( array[ i ] === elem )
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
},
|
||||
|
||||
merge: function( first, second ) {
|
||||
// We have to loop this way because IE & Opera overwrite the length
|
||||
// expando of getElementsByTagName
|
||||
var i = 0, elem, pos = first.length;
|
||||
// Also, we need to make sure that the correct elements are being returned
|
||||
// (IE returns comment nodes in a '*' query)
|
||||
if ( !jQuery.support.getAll ) {
|
||||
while ( (elem = second[ i++ ]) != null )
|
||||
if ( elem.nodeType != 8 )
|
||||
first[ pos++ ] = elem;
|
||||
|
||||
} else
|
||||
while ( (elem = second[ i++ ]) != null )
|
||||
first[ pos++ ] = elem;
|
||||
|
||||
return first;
|
||||
},
|
||||
|
||||
unique: function( array ) {
|
||||
var ret = [], done = {};
|
||||
|
||||
try {
|
||||
|
||||
for ( var i = 0, length = array.length; i < length; i++ ) {
|
||||
var id = jQuery.data( array[ i ] );
|
||||
|
||||
if ( !done[ id ] ) {
|
||||
done[ id ] = true;
|
||||
ret.push( array[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
} catch( e ) {
|
||||
ret = array;
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
grep: function( elems, callback, inv ) {
|
||||
var ret = [];
|
||||
|
||||
// Go through the array, only saving the items
|
||||
// that pass the validator function
|
||||
for ( var i = 0, length = elems.length; i < length; i++ )
|
||||
if ( !inv != !callback( elems[ i ], i ) )
|
||||
ret.push( elems[ i ] );
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
map: function( elems, callback ) {
|
||||
var ret = [];
|
||||
|
||||
// Go through the array, translating each of the items to their
|
||||
// new value (or values).
|
||||
for ( var i = 0, length = elems.length; i < length; i++ ) {
|
||||
var value = callback( elems[ i ], i );
|
||||
|
||||
if ( value != null )
|
||||
ret[ ret.length ] = value;
|
||||
}
|
||||
|
||||
return ret.concat.apply( [], ret );
|
||||
}
|
||||
});
|
||||
|
||||
// Use of jQuery.browser is deprecated.
|
||||
// It's included for backwards compatibility and plugins,
|
||||
// although they should work to migrate away.
|
||||
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
|
||||
// Figure out what browser is being used
|
||||
jQuery.browser = {
|
||||
version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
|
||||
safari: /webkit/.test( userAgent ),
|
||||
opera: /opera/.test( userAgent ),
|
||||
msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
|
||||
mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
|
||||
};
|
||||
|
||||
jQuery.each({
|
||||
parent: function(elem){return elem.parentNode;},
|
||||
parents: function(elem){return jQuery.dir(elem,"parentNode");},
|
||||
next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
|
||||
prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
|
||||
nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
|
||||
prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
|
||||
siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
|
||||
children: function(elem){return jQuery.sibling(elem.firstChild);},
|
||||
contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
|
||||
}, function(name, fn){
|
||||
jQuery.fn[ name ] = function( selector ) {
|
||||
var ret = jQuery.map( this, fn );
|
||||
|
||||
if ( selector && typeof selector == "string" )
|
||||
ret = jQuery.multiFilter( selector, ret );
|
||||
|
||||
return this.pushStack( jQuery.unique( ret ), name, selector );
|
||||
};
|
||||
});
|
||||
|
||||
jQuery.each({
|
||||
appendTo: "append",
|
||||
prependTo: "prepend",
|
||||
insertBefore: "before",
|
||||
insertAfter: "after",
|
||||
replaceAll: "replaceWith"
|
||||
}, function(name, original){
|
||||
jQuery.fn[ name ] = function( selector ) {
|
||||
var ret = [], insert = jQuery( selector );
|
||||
|
||||
for ( var i = 0, l = insert.length; i < l; i++ ) {
|
||||
var elems = (i > 0 ? this.clone(true) : this).get();
|
||||
jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
|
||||
ret = ret.concat( elems );
|
||||
}
|
||||
|
||||
return this.pushStack( ret, name, selector );
|
||||
};
|
||||
});
|
||||
|
||||
jQuery.each({
|
||||
removeAttr: function( name ) {
|
||||
jQuery.attr( this, name, "" );
|
||||
if (this.nodeType == 1)
|
||||
this.removeAttribute( name );
|
||||
},
|
||||
|
||||
addClass: function( classNames ) {
|
||||
jQuery.className.add( this, classNames );
|
||||
},
|
||||
|
||||
removeClass: function( classNames ) {
|
||||
jQuery.className.remove( this, classNames );
|
||||
},
|
||||
|
||||
toggleClass: function( classNames, state ) {
|
||||
if( typeof state !== "boolean" )
|
||||
state = !jQuery.className.has( this, classNames );
|
||||
jQuery.className[ state ? "add" : "remove" ]( this, classNames );
|
||||
},
|
||||
|
||||
remove: function( selector ) {
|
||||
if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
|
||||
// Prevent memory leaks
|
||||
jQuery( "*", this ).add([this]).each(function(){
|
||||
jQuery.event.remove(this);
|
||||
jQuery.removeData(this);
|
||||
});
|
||||
if (this.parentNode)
|
||||
this.parentNode.removeChild( this );
|
||||
}
|
||||
},
|
||||
|
||||
empty: function() {
|
||||
// Remove element nodes and prevent memory leaks
|
||||
jQuery(this).children().remove();
|
||||
|
||||
// Remove any remaining nodes
|
||||
while ( this.firstChild )
|
||||
this.removeChild( this.firstChild );
|
||||
}
|
||||
}, function(name, fn){
|
||||
jQuery.fn[ name ] = function(){
|
||||
return this.each( fn, arguments );
|
||||
};
|
||||
});
|
||||
|
||||
// Helper function used by the dimensions and offset modules
|
||||
function num(elem, prop) {
|
||||
return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
|
||||
}
|
||||
var expando = "jQuery" + now(), uuid = 0, windowData = {};
|
||||
|
||||
jQuery.extend({
|
||||
cache: {},
|
||||
|
||||
data: function( elem, name, data ) {
|
||||
elem = elem == window ?
|
||||
windowData :
|
||||
elem;
|
||||
|
||||
var id = elem[ expando ];
|
||||
|
||||
// Compute a unique ID for the element
|
||||
if ( !id )
|
||||
id = elem[ expando ] = ++uuid;
|
||||
|
||||
// Only generate the data cache if we're
|
||||
// trying to access or manipulate it
|
||||
if ( name && !jQuery.cache[ id ] )
|
||||
jQuery.cache[ id ] = {};
|
||||
|
||||
// Prevent overriding the named cache with undefined values
|
||||
if ( data !== undefined )
|
||||
jQuery.cache[ id ][ name ] = data;
|
||||
|
||||
// Return the named cache data, or the ID for the element
|
||||
return name ?
|
||||
jQuery.cache[ id ][ name ] :
|
||||
id;
|
||||
},
|
||||
|
||||
removeData: function( elem, name ) {
|
||||
elem = elem == window ?
|
||||
windowData :
|
||||
elem;
|
||||
|
||||
var id = elem[ expando ];
|
||||
|
||||
// If we want to remove a specific section of the element's data
|
||||
if ( name ) {
|
||||
if ( jQuery.cache[ id ] ) {
|
||||
// Remove the section of cache data
|
||||
delete jQuery.cache[ id ][ name ];
|
||||
|
||||
// If we've removed all the data, remove the element's cache
|
||||
name = "";
|
||||
|
||||
for ( name in jQuery.cache[ id ] )
|
||||
break;
|
||||
|
||||
if ( !name )
|
||||
jQuery.removeData( elem );
|
||||
}
|
||||
|
||||
// Otherwise, we want to remove all of the element's data
|
||||
} else {
|
||||
// Clean up the element expando
|
||||
try {
|
||||
delete elem[ expando ];
|
||||
} catch(e){
|
||||
// IE has trouble directly removing the expando
|
||||
// but it's ok with using removeAttribute
|
||||
if ( elem.removeAttribute )
|
||||
elem.removeAttribute( expando );
|
||||
}
|
||||
|
||||
// Completely remove the data cache
|
||||
delete jQuery.cache[ id ];
|
||||
}
|
||||
},
|
||||
queue: function( elem, type, data ) {
|
||||
if ( elem ){
|
||||
|
||||
type = (type || "fx") + "queue";
|
||||
|
||||
var q = jQuery.data( elem, type );
|
||||
|
||||
if ( !q || jQuery.isArray(data) )
|
||||
q = jQuery.data( elem, type, jQuery.makeArray(data) );
|
||||
else if( data )
|
||||
q.push( data );
|
||||
|
||||
}
|
||||
return q;
|
||||
},
|
||||
|
||||
dequeue: function( elem, type ){
|
||||
var queue = jQuery.queue( elem, type ),
|
||||
fn = queue.shift();
|
||||
|
||||
if( !type || type === "fx" )
|
||||
fn = queue[0];
|
||||
|
||||
if( fn !== undefined )
|
||||
fn.call(elem);
|
||||
}
|
||||
});
|
||||
|
||||
jQuery.fn.extend({
|
||||
data: function( key, value ){
|
||||
var parts = key.split(".");
|
||||
parts[1] = parts[1] ? "." + parts[1] : "";
|
||||
|
||||
if ( value === undefined ) {
|
||||
var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
|
||||
|
||||
if ( data === undefined && this.length )
|
||||
data = jQuery.data( this[0], key );
|
||||
|
||||
return data === undefined && parts[1] ?
|
||||
this.data( parts[0] ) :
|
||||
data;
|
||||
} else
|
||||
return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
|
||||
jQuery.data( this, key, value );
|
||||
});
|
||||
},
|
||||
|
||||
removeData: function( key ){
|
||||
return this.each(function(){
|
||||
jQuery.removeData( this, key );
|
||||
});
|
||||
},
|
||||
queue: function(type, data){
|
||||
if ( typeof type !== "string" ) {
|
||||
data = type;
|
||||
type = "fx";
|
||||
}
|
||||
|
||||
if ( data === undefined )
|
||||
return jQuery.queue( this[0], type );
|
||||
|
||||
return this.each(function(){
|
||||
var queue = jQuery.queue( this, type, data );
|
||||
|
||||
if( type == "fx" && queue.length == 1 )
|
||||
queue[0].call(this);
|
||||
});
|
||||
},
|
||||
dequeue: function(type){
|
||||
return this.each(function(){
|
||||
jQuery.dequeue( this, type );
|
||||
});
|
||||
}
|
||||
});/*!
|
||||
* Sizzle CSS Selector Engine - v0.9.3
|
||||
* Copyright 2009, The Dojo Foundation
|
||||
* Released under the MIT, BSD, and GPL Licenses.
|
||||
* More information: http://sizzlejs.com/
|
||||
*/
|
||||
(function(){
|
||||
|
||||
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
|
||||
done = 0,
|
||||
toString = Object.prototype.toString;
|
||||
|
||||
var Sizzle = function(selector, context, results, seed) {
|
||||
results = results || [];
|
||||
context = context || document;
|
||||
|
||||
if ( context.nodeType !== 1 && context.nodeType !== 9 )
|
||||
return [];
|
||||
|
||||
if ( !selector || typeof selector !== "string" ) {
|
||||
return results;
|
||||
}
|
||||
|
||||
var parts = [], m, set, checkSet, check, mode, extra, prune = true;
|
||||
|
||||
// Reset the position of the chunker regexp (start from head)
|
||||
chunker.lastIndex = 0;
|
||||
|
||||
while ( (m = chunker.exec(selector)) !== null ) {
|
||||
parts.push( m[1] );
|
||||
|
||||
if ( m[2] ) {
|
||||
extra = RegExp.rightContext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( parts.length > 1 && origPOS.exec( selector ) ) {
|
||||
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
|
||||
set = posProcess( parts[0] + parts[1], context );
|
||||
} else {
|
||||
set = Expr.relative[ parts[0] ] ?
|
||||
[ context ] :
|
||||
Sizzle( parts.shift(), context );
|
||||
|
||||
while ( parts.length ) {
|
||||
selector = parts.shift();
|
||||
|
||||
if ( Expr.relative[ selector ] )
|
||||
selector += parts.shift();
|
||||
|
||||
set = posProcess( selector, set );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var ret = seed ?
|
||||
{ expr: parts.pop(), set: makeArray(seed) } :
|
||||
Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
|
||||
set = Sizzle.filter( ret.expr, ret.set );
|
||||
|
||||
if ( parts.length > 0 ) {
|
||||
checkSet = makeArray(set);
|
||||
} else {
|
||||
prune = false;
|
||||
}
|
||||
|
||||
while ( parts.length ) {
|
||||
var cur = parts.pop(), pop = cur;
|
||||
|
||||
if ( !Expr.relative[ cur ] ) {
|
||||
cur = "";
|
||||
} else {
|
||||
pop = parts.pop();
|
||||
}
|
||||
|
||||
if ( pop == null ) {
|
||||
pop = context;
|
||||
}
|
||||
|
||||
Expr.relative[ cur ]( checkSet, pop, isXML(context) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !checkSet ) {
|
||||
checkSet = set;
|
||||
}
|
||||
|
||||
if ( !checkSet ) {
|
||||
throw "Syntax error, unrecognized expression: " + (cur || selector);
|
||||
}
|
||||
|
||||
if ( toString.call(checkSet) === "[object Array]" ) {
|
||||
if ( !prune ) {
|
||||
results.push.apply( results, checkSet );
|
||||
} else if ( context.nodeType === 1 ) {
|
||||
for ( var i = 0; checkSet[i] != null; i++ ) {
|
||||
if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
|
||||
results.push( set[i] );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( var i = 0; checkSet[i] != null; i++ ) {
|
||||
if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
|
||||
results.push( set[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
makeArray( checkSet, results );
|
||||
}
|
||||
|
||||
if ( extra ) {
|
||||
Sizzle( extra, context, results, seed );
|
||||
|
||||
if ( sortOrder ) {
|
||||
hasDuplicate = false;
|
||||
results.sort(sortOrder);
|
||||
|
||||
if ( hasDuplicate ) {
|
||||
for ( var i = 1; i < results.length; i++ ) {
|
||||
if ( results[i] === results[i-1] ) {
|
||||
results.splice(i--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
Sizzle.matches = function(expr, set){
|
||||
return Sizzle(expr, null, null, set);
|
||||
};
|
||||
|
||||
Sizzle.find = function(expr, context, isXML){
|
||||
var set, match;
|
||||
|
||||
if ( !expr ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
|
||||
var type = Expr.order[i], match;
|
||||
|
||||
if ( (match = Expr.match[ type ].exec( expr )) ) {
|
||||
var left = RegExp.leftContext;
|
||||
|
||||
if ( left.substr( left.length - 1 ) !== "\\" ) {
|
||||
match[1] = (match[1] || "").replace(/\\/g, "");
|
||||
set = Expr.find[ type ]( match, context, isXML );
|
||||
if ( set != null ) {
|
||||
expr = expr.replace( Expr.match[ type ], "" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !set ) {
|
||||
set = context.getElementsByTagName("*");
|
||||
}
|
||||
|
||||
return {set: set, expr: expr};
|
||||
};
|
||||
|
||||
Sizzle.filter = function(expr, set, inplace, not){
|
||||
var old = expr, result = [], curLoop = set, match, anyFound,
|
||||
isXMLFilter = set && set[0] && isXML(set[0]);
|
||||
|
||||
while ( expr && set.length ) {
|
||||
for ( var type in Expr.filter ) {
|
||||
if ( (match = Expr.match[ type ].exec( expr )) != null ) {
|
||||
var filter = Expr.filter[ type ], found, item;
|
||||
anyFound = false;
|
||||
|
||||
if ( curLoop == result ) {
|
||||
result = [];
|
||||
}
|
||||
|
||||
if ( Expr.preFilter[ type ] ) {
|
||||
match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
|
||||
|
||||
if ( !match ) {
|
||||
anyFound = found = true;
|
||||
} else if ( match === true ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( match ) {
|
||||
for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
|
||||
if ( item ) {
|
||||
found = filter( item, match, i, curLoop );
|
||||
var pass = not ^ !!found;
|
||||
|
||||
if ( inplace && found != null ) {
|
||||
if ( pass ) {
|
||||
anyFound = true;
|
||||
} else {
|
||||
curLoop[i] = false;
|
||||
}
|
||||
} else if ( pass ) {
|
||||
result.push( item );
|
||||
anyFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( found !== undefined ) {
|
||||
if ( !inplace ) {
|
||||
curLoop = result;
|
||||
}
|
||||
|
||||
expr = expr.replace( Expr.match[ type ], "" );
|
||||
|
||||
if ( !anyFound ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Improper expression
|
||||
if ( expr == old ) {
|
||||
if ( anyFound == null ) {
|
||||
throw "Syntax error, unrecognized expression: " + expr;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
old = expr;
|
||||
}
|
||||
|
||||
return curLoop;
|
||||
};
|
||||
|
||||
var Expr = Sizzle.selectors = {
|
||||
order: [ "ID", "NAME", "TAG" ],
|
||||
match: {
|
||||
ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
|
||||
CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
|
||||
NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
|
||||
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
|
||||
TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
|
||||
CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
|
||||
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
|
||||
PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
|
||||
},
|
||||
attrMap: {
|
||||
"class": "className",
|
||||
"for": "htmlFor"
|
||||
},
|
||||
attrHandle: {
|
||||
href: function(elem){
|
||||
return elem.getAttribute("href");
|
||||
}
|
||||
},
|
||||
relative: {
|
||||
"+": function(checkSet, part, isXML){
|
||||
var isPartStr = typeof part === "string",
|
||||
isTag = isPartStr && !/\W/.test(part),
|
||||
isPartStrNotTag = isPartStr && !isTag;
|
||||
|
||||
if ( isTag && !isXML ) {
|
||||
part = part.toUpperCase();
|
||||
}
|
||||
|
||||
for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
|
||||
if ( (elem = checkSet[i]) ) {
|
||||
while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
|
||||
|
||||
checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
|
||||
elem || false :
|
||||
elem === part;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isPartStrNotTag ) {
|
||||
Sizzle.filter( part, checkSet, true );
|
||||
}
|
||||
},
|
||||
">": function(checkSet, part, isXML){
|
||||
var isPartStr = typeof part === "string";
|
||||
|
||||
if ( isPartStr && !/\W/.test(part) ) {
|
||||
part = isXML ? part : part.toUpperCase();
|
||||
|
||||
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
|
||||
var elem = checkSet[i];
|
||||
if ( elem ) {
|
||||
var parent = elem.parentNode;
|
||||
checkSet[i] = parent.nodeName === part ? parent : false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
|
||||
var elem = checkSet[i];
|
||||
if ( elem ) {
|
||||
checkSet[i] = isPartStr ?
|
||||
elem.parentNode :
|
||||
elem.parentNode === part;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isPartStr ) {
|
||||
Sizzle.filter( part, checkSet, true );
|
||||
}
|
||||
}
|
||||
},
|
||||
"": function(checkSet, part, isXML){
|
||||
var doneName = done++, checkFn = dirCheck;
|
||||
|
||||
if ( !part.match(/\W/) ) {
|
||||
var nodeCheck = part = isXML ? part : part.toUpperCase();
|
||||
checkFn = dirNodeCheck;
|
||||
}
|
||||
|
||||
checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
|
||||
},
|
||||
"~": function(checkSet, part, isXML){
|
||||
var doneName = done++, checkFn = dirCheck;
|
||||
|
||||
if ( typeof part === "string" && !part.match(/\W/) ) {
|
||||
var nodeCheck = part = isXML ? part : part.toUpperCase();
|
||||
checkFn = dirNodeCheck;
|
||||
}
|
||||
|
||||
checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
|
||||
}
|
||||
},
|
||||
find: {
|
||||
ID: function(match, context, isXML){
|
||||
if ( typeof context.getElementById !== "undefined" && !isXML ) {
|
||||
var m = context.getElementById(match[1]);
|
||||
return m ? [m] : [];
|
||||
}
|
||||
},
|
||||
NAME: function(match, context, isXML){
|
||||
if ( typeof context.getElementsByName !== "undefined" ) {
|
||||
var ret = [], results = context.getElementsByName(match[1]);
|
||||
|
||||
for ( var i = 0, l = results.length; i < l; i++ ) {
|
||||
if ( results[i].getAttribute("name") === match[1] ) {
|
||||
ret.push( results[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return ret.length === 0 ? null : ret;
|
||||
}
|
||||
},
|
||||
TAG: function(match, context){
|
||||
return context.getElementsByTagName(match[1]);
|
||||
}
|
||||
},
|
||||
preFilter: {
|
||||
CLASS: function(match, curLoop, inplace, result, not, isXML){
|
||||
match = " " + match[1].replace(/\\/g, "") + " ";
|
||||
|
||||
if ( isXML ) {
|
||||
return match;
|
||||
}
|
||||
|
||||
for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
|
||||
if ( elem ) {
|
||||
if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
|
||||
if ( !inplace )
|
||||
result.push( elem );
|
||||
} else if ( inplace ) {
|
||||
curLoop[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
ID: function(match){
|
||||
return match[1].replace(/\\/g, "");
|
||||
},
|
||||
TAG: function(match, curLoop){
|
||||
for ( var i = 0; curLoop[i] === false; i++ ){}
|
||||
return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
|
||||
},
|
||||
CHILD: function(match){
|
||||
if ( match[1] == "nth" ) {
|
||||
// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
|
||||
var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
|
||||
match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
|
||||
!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
|
||||
|
||||
// calculate the numbers (first)n+(last) including if they are negative
|
||||
match[2] = (test[1] + (test[2] || 1)) - 0;
|
||||
match[3] = test[3] - 0;
|
||||
}
|
||||
|
||||
// TODO: Move to normal caching system
|
||||
match[0] = done++;
|
||||
|
||||
return match;
|
||||
},
|
||||
ATTR: function(match, curLoop, inplace, result, not, isXML){
|
||||
var name = match[1].replace(/\\/g, "");
|
||||
|
||||
if ( !isXML && Expr.attrMap[name] ) {
|
||||
match[1] = Expr.attrMap[name];
|
||||
}
|
||||
|
||||
if ( match[2] === "~=" ) {
|
||||
match[4] = " " + match[4] + " ";
|
||||
}
|
||||
|
||||
return match;
|
||||
},
|
||||
PSEUDO: function(match, curLoop, inplace, result, not){
|
||||
if ( match[1] === "not" ) {
|
||||
// If we're dealing with a complex expression, or a simple one
|
||||
if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
|
||||
match[3] = Sizzle(match[3], null, null, curLoop);
|
||||
} else {
|
||||
var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
|
||||
if ( !inplace ) {
|
||||
result.push.apply( result, ret );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return match;
|
||||
},
|
||||
POS: function(match){
|
||||
match.unshift( true );
|
||||
return match;
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
enabled: function(elem){
|
||||
return elem.disabled === false && elem.type !== "hidden";
|
||||
},
|
||||
disabled: function(elem){
|
||||
return elem.disabled === true;
|
||||
},
|
||||
checked: function(elem){
|
||||
return elem.checked === true;
|
||||
},
|
||||
selected: function(elem){
|
||||
// Accessing this property makes selected-by-default
|
||||
// options in Safari work properly
|
||||
elem.parentNode.selectedIndex;
|
||||
return elem.selected === true;
|
||||
},
|
||||
parent: function(elem){
|
||||
return !!elem.firstChild;
|
||||
},
|
||||
empty: function(elem){
|
||||
return !elem.firstChild;
|
||||
},
|
||||
has: function(elem, i, match){
|
||||
return !!Sizzle( match[3], elem ).length;
|
||||
},
|
||||
header: function(elem){
|
||||
return /h\d/i.test( elem.nodeName );
|
||||
},
|
||||
text: function(elem){
|
||||
return "text" === elem.type;
|
||||
},
|
||||
radio: function(elem){
|
||||
return "radio" === elem.type;
|
||||
},
|
||||
checkbox: function(elem){
|
||||
return "checkbox" === elem.type;
|
||||
},
|
||||
file: function(elem){
|
||||
return "file" === elem.type;
|
||||
},
|
||||
password: function(elem){
|
||||
return "password" === elem.type;
|
||||
},
|
||||
submit: function(elem){
|
||||
return "submit" === elem.type;
|
||||
},
|
||||
image: function(elem){
|
||||
return "image" === elem.type;
|
||||
},
|
||||
reset: function(elem){
|
||||
return "reset" === elem.type;
|
||||
},
|
||||
button: function(elem){
|
||||
return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
|
||||
},
|
||||
input: function(elem){
|
||||
return /input|select|textarea|button/i.test(elem.nodeName);
|
||||
}
|
||||
},
|
||||
setFilters: {
|
||||
first: function(elem, i){
|
||||
return i === 0;
|
||||
},
|
||||
last: function(elem, i, match, array){
|
||||
return i === array.length - 1;
|
||||
},
|
||||
even: function(elem, i){
|
||||
return i % 2 === 0;
|
||||
},
|
||||
odd: function(elem, i){
|
||||
return i % 2 === 1;
|
||||
},
|
||||
lt: function(elem, i, match){
|
||||
return i < match[3] - 0;
|
||||
},
|
||||
gt: function(elem, i, match){
|
||||
return i > match[3] - 0;
|
||||
},
|
||||
nth: function(elem, i, match){
|
||||
return match[3] - 0 == i;
|
||||
},
|
||||
eq: function(elem, i, match){
|
||||
return match[3] - 0 == i;
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
PSEUDO: function(elem, match, i, array){
|
||||
var name = match[1], filter = Expr.filters[ name ];
|
||||
|
||||
if ( filter ) {
|
||||
return filter( elem, i, match, array );
|
||||
} else if ( name === "contains" ) {
|
||||
return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
|
||||
} else if ( name === "not" ) {
|
||||
var not = match[3];
|
||||
|
||||
for ( var i = 0, l = not.length; i < l; i++ ) {
|
||||
if ( not[i] === elem ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
CHILD: function(elem, match){
|
||||
var type = match[1], node = elem;
|
||||
switch (type) {
|
||||
case 'only':
|
||||
case 'first':
|
||||
while (node = node.previousSibling) {
|
||||
if ( node.nodeType === 1 ) return false;
|
||||
}
|
||||
if ( type == 'first') return true;
|
||||
node = elem;
|
||||
case 'last':
|
||||
while (node = node.nextSibling) {
|
||||
if ( node.nodeType === 1 ) return false;
|
||||
}
|
||||
return true;
|
||||
case 'nth':
|
||||
var first = match[2], last = match[3];
|
||||
|
||||
if ( first == 1 && last == 0 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var doneName = match[0],
|
||||
parent = elem.parentNode;
|
||||
|
||||
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
|
||||
var count = 0;
|
||||
for ( node = parent.firstChild; node; node = node.nextSibling ) {
|
||||
if ( node.nodeType === 1 ) {
|
||||
node.nodeIndex = ++count;
|
||||
}
|
||||
}
|
||||
parent.sizcache = doneName;
|
||||
}
|
||||
|
||||
var diff = elem.nodeIndex - last;
|
||||
if ( first == 0 ) {
|
||||
return diff == 0;
|
||||
} else {
|
||||
return ( diff % first == 0 && diff / first >= 0 );
|
||||
}
|
||||
}
|
||||
},
|
||||
ID: function(elem, match){
|
||||
return elem.nodeType === 1 && elem.getAttribute("id") === match;
|
||||
},
|
||||
TAG: function(elem, match){
|
||||
return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
|
||||
},
|
||||
CLASS: function(elem, match){
|
||||
return (" " + (elem.className || elem.getAttribute("class")) + " ")
|
||||
.indexOf( match ) > -1;
|
||||
},
|
||||
ATTR: function(elem, match){
|
||||
var name = match[1],
|
||||
result = Expr.attrHandle[ name ] ?
|
||||
Expr.attrHandle[ name ]( elem ) :
|
||||
elem[ name ] != null ?
|
||||
elem[ name ] :
|
||||
elem.getAttribute( name ),
|
||||
value = result + "",
|
||||
type = match[2],
|
||||
check = match[4];
|
||||
|
||||
return result == null ?
|
||||
type === "!=" :
|
||||
type === "=" ?
|
||||
value === check :
|
||||
type === "*=" ?
|
||||
value.indexOf(check) >= 0 :
|
||||
type === "~=" ?
|
||||
(" " + value + " ").indexOf(check) >= 0 :
|
||||
!check ?
|
||||
value && result !== false :
|
||||
type === "!=" ?
|
||||
value != check :
|
||||
type === "^=" ?
|
||||
value.indexOf(check) === 0 :
|
||||
type === "$=" ?
|
||||
value.substr(value.length - check.length) === check :
|
||||
type === "|=" ?
|
||||
value === check || value.substr(0, check.length + 1) === check + "-" :
|
||||
false;
|
||||
},
|
||||
POS: function(elem, match, i, array){
|
||||
var name = match[2], filter = Expr.setFilters[ name ];
|
||||
|
||||
if ( filter ) {
|
||||
return filter( elem, i, match, array );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var origPOS = Expr.match.POS;
|
||||
|
||||
for ( var type in Expr.match ) {
|
||||
Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
|
||||
}
|
||||
|
||||
var makeArray = function(array, results) {
|
||||
array = Array.prototype.slice.call( array );
|
||||
|
||||
if ( results ) {
|
||||
results.push.apply( results, array );
|
||||
return results;
|
||||
}
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
// Perform a simple check to determine if the browser is capable of
|
||||
// converting a NodeList to an array using builtin methods.
|
||||
try {
|
||||
Array.prototype.slice.call( document.documentElement.childNodes );
|
||||
|
||||
// Provide a fallback method if it does not work
|
||||
} catch(e){
|
||||
makeArray = function(array, results) {
|
||||
var ret = results || [];
|
||||
|
||||
if ( toString.call(array) === "[object Array]" ) {
|
||||
Array.prototype.push.apply( ret, array );
|
||||
} else {
|
||||
if ( typeof array.length === "number" ) {
|
||||
for ( var i = 0, l = array.length; i < l; i++ ) {
|
||||
ret.push( array[i] );
|
||||
}
|
||||
} else {
|
||||
for ( var i = 0; array[i]; i++ ) {
|
||||
ret.push( array[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
var sortOrder;
|
||||
|
||||
if ( document.documentElement.compareDocumentPosition ) {
|
||||
sortOrder = function( a, b ) {
|
||||
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
|
||||
if ( ret === 0 ) {
|
||||
hasDuplicate = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
} else if ( "sourceIndex" in document.documentElement ) {
|
||||
sortOrder = function( a, b ) {
|
||||
var ret = a.sourceIndex - b.sourceIndex;
|
||||
if ( ret === 0 ) {
|
||||
hasDuplicate = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
} else if ( document.createRange ) {
|
||||
sortOrder = function( a, b ) {
|
||||
var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
|
||||
aRange.selectNode(a);
|
||||
aRange.collapse(true);
|
||||
bRange.selectNode(b);
|
||||
bRange.collapse(true);
|
||||
var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
|
||||
if ( ret === 0 ) {
|
||||
hasDuplicate = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
// Check to see if the browser returns elements by name when
|
||||
// querying by getElementById (and provide a workaround)
|
||||
(function(){
|
||||
// We're going to inject a fake input element with a specified name
|
||||
var form = document.createElement("form"),
|
||||
id = "script" + (new Date).getTime();
|
||||
form.innerHTML = "<input name='" + id + "'/>";
|
||||
|
||||
// Inject it into the root element, check its status, and remove it quickly
|
||||
var root = document.documentElement;
|
||||
root.insertBefore( form, root.firstChild );
|
||||
|
||||
// The workaround has to do additional checks after a getElementById
|
||||
// Which slows things down for other browsers (hence the branching)
|
||||
if ( !!document.getElementById( id ) ) {
|
||||
Expr.find.ID = function(match, context, isXML){
|
||||
if ( typeof context.getElementById !== "undefined" && !isXML ) {
|
||||
var m = context.getElementById(match[1]);
|
||||
return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
|
||||
}
|
||||
};
|
||||
|
||||
Expr.filter.ID = function(elem, match){
|
||||
var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
|
||||
return elem.nodeType === 1 && node && node.nodeValue === match;
|
||||
};
|
||||
}
|
||||
|
||||
root.removeChild( form );
|
||||
})();
|
||||
|
||||
(function(){
|
||||
// Check to see if the browser returns only elements
|
||||
// when doing getElementsByTagName("*")
|
||||
|
||||
// Create a fake element
|
||||
var div = document.createElement("div");
|
||||
div.appendChild( document.createComment("") );
|
||||
|
||||
// Make sure no comments are found
|
||||
if ( div.getElementsByTagName("*").length > 0 ) {
|
||||
Expr.find.TAG = function(match, context){
|
||||
var results = context.getElementsByTagName(match[1]);
|
||||
|
||||
// Filter out possible comments
|
||||
if ( match[1] === "*" ) {
|
||||
var tmp = [];
|
||||
|
||||
for ( var i = 0; results[i]; i++ ) {
|
||||
if ( results[i].nodeType === 1 ) {
|
||||
tmp.push( results[i] );
|
||||
}
|
||||
}
|
||||
|
||||
results = tmp;
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
}
|
||||
|
||||
// Check to see if an attribute returns normalized href attributes
|
||||
div.innerHTML = "<a href='#'></a>";
|
||||
if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
|
||||
div.firstChild.getAttribute("href") !== "#" ) {
|
||||
Expr.attrHandle.href = function(elem){
|
||||
return elem.getAttribute("href", 2);
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
if ( document.querySelectorAll ) (function(){
|
||||
var oldSizzle = Sizzle, div = document.createElement("div");
|
||||
div.innerHTML = "<p class='TEST'></p>";
|
||||
|
||||
// Safari can't handle uppercase or unicode characters when
|
||||
// in quirks mode.
|
||||
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sizzle = function(query, context, extra, seed){
|
||||
context = context || document;
|
||||
|
||||
// Only use querySelectorAll on non-XML documents
|
||||
// (ID selectors don't work in non-HTML documents)
|
||||
if ( !seed && context.nodeType === 9 && !isXML(context) ) {
|
||||
try {
|
||||
return makeArray( context.querySelectorAll(query), extra );
|
||||
} catch(e){}
|
||||
}
|
||||
|
||||
return oldSizzle(query, context, extra, seed);
|
||||
};
|
||||
|
||||
Sizzle.find = oldSizzle.find;
|
||||
Sizzle.filter = oldSizzle.filter;
|
||||
Sizzle.selectors = oldSizzle.selectors;
|
||||
Sizzle.matches = oldSizzle.matches;
|
||||
})();
|
||||
|
||||
if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
|
||||
var div = document.createElement("div");
|
||||
div.innerHTML = "<div class='test e'></div><div class='test'></div>";
|
||||
|
||||
// Opera can't find a second classname (in 9.6)
|
||||
if ( div.getElementsByClassName("e").length === 0 )
|
||||
return;
|
||||
|
||||
// Safari caches class attributes, doesn't catch changes (in 3.2)
|
||||
div.lastChild.className = "e";
|
||||
|
||||
if ( div.getElementsByClassName("e").length === 1 )
|
||||
return;
|
||||
|
||||
Expr.order.splice(1, 0, "CLASS");
|
||||
Expr.find.CLASS = function(match, context, isXML) {
|
||||
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
|
||||
return context.getElementsByClassName(match[1]);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
|
||||
var sibDir = dir == "previousSibling" && !isXML;
|
||||
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
|
||||
var elem = checkSet[i];
|
||||
if ( elem ) {
|
||||
if ( sibDir && elem.nodeType === 1 ){
|
||||
elem.sizcache = doneName;
|
||||
elem.sizset = i;
|
||||
}
|
||||
elem = elem[dir];
|
||||
var match = false;
|
||||
|
||||
while ( elem ) {
|
||||
if ( elem.sizcache === doneName ) {
|
||||
match = checkSet[elem.sizset];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( elem.nodeType === 1 && !isXML ){
|
||||
elem.sizcache = doneName;
|
||||
elem.sizset = i;
|
||||
}
|
||||
|
||||
if ( elem.nodeName === cur ) {
|
||||
match = elem;
|
||||
break;
|
||||
}
|
||||
|
||||
elem = elem[dir];
|
||||
}
|
||||
|
||||
checkSet[i] = match;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
|
||||
var sibDir = dir == "previousSibling" && !isXML;
|
||||
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
|
||||
var elem = checkSet[i];
|
||||
if ( elem ) {
|
||||
if ( sibDir && elem.nodeType === 1 ) {
|
||||
elem.sizcache = doneName;
|
||||
elem.sizset = i;
|
||||
}
|
||||
elem = elem[dir];
|
||||
var match = false;
|
||||
|
||||
while ( elem ) {
|
||||
if ( elem.sizcache === doneName ) {
|
||||
match = checkSet[elem.sizset];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( elem.nodeType === 1 ) {
|
||||
if ( !isXML ) {
|
||||
elem.sizcache = doneName;
|
||||
elem.sizset = i;
|
||||
}
|
||||
if ( typeof cur !== "string" ) {
|
||||
if ( elem === cur ) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
|
||||
} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
|
||||
match = elem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
elem = elem[dir];
|
||||
}
|
||||
|
||||
checkSet[i] = match;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var contains = document.compareDocumentPosition ? function(a, b){
|
||||
return a.compareDocumentPosition(b) & 16;
|
||||
} : function(a, b){
|
||||
return a !== b && (a.contains ? a.contains(b) : true);
|
||||
};
|
||||
|
||||
var isXML = function(elem){
|
||||
return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
|
||||
!!elem.ownerDocument && isXML( elem.ownerDocument );
|
||||
};
|
||||
|
||||
var posProcess = function(selector, context){
|
||||
var tmpSet = [], later = "", match,
|
||||
root = context.nodeType ? [context] : context;
|
||||
|
||||
// Position selectors must be done after the filter
|
||||
// And so must :not(positional) so we move all PSEUDOs to the end
|
||||
while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
|
||||
later += match[0];
|
||||
selector = selector.replace( Expr.match.PSEUDO, "" );
|
||||
}
|
||||
|
||||
selector = Expr.relative[selector] ? selector + "*" : selector;
|
||||
|
||||
for ( var i = 0, l = root.length; i < l; i++ ) {
|
||||
Sizzle( selector, root[i], tmpSet );
|
||||
}
|
||||
|
||||
return Sizzle.filter( later, tmpSet );
|
||||
};
|
||||
|
||||
// EXPOSE
|
||||
jQuery.find = Sizzle;
|
||||
jQuery.filter = Sizzle.filter;
|
||||
jQuery.expr = Sizzle.selectors;
|
||||
jQuery.expr[":"] = jQuery.expr.filters;
|
||||
|
||||
Sizzle.selectors.filters.hidden = function(elem){
|
||||
return elem.offsetWidth === 0 || elem.offsetHeight === 0;
|
||||
};
|
||||
|
||||
Sizzle.selectors.filters.visible = function(elem){
|
||||
return elem.offsetWidth > 0 || elem.offsetHeight > 0;
|
||||
};
|
||||
|
||||
Sizzle.selectors.filters.animated = function(elem){
|
||||
return jQuery.grep(jQuery.timers, function(fn){
|
||||
return elem === fn.elem;
|
||||
}).length;
|
||||
};
|
||||
|
||||
jQuery.multiFilter = function( expr, elems, not ) {
|
||||
if ( not ) {
|
||||
expr = ":not(" + expr + ")";
|
||||
}
|
||||
|
||||
return Sizzle.matches(expr, elems);
|
||||
};
|
||||
|
||||
jQuery.dir = function( elem, dir ){
|
||||
var matched = [], cur = elem[dir];
|
||||
while ( cur && cur != document ) {
|
||||
if ( cur.nodeType == 1 )
|
||||
matched.push( cur );
|
||||
cur = cur[dir];
|
||||
}
|
||||
return matched;
|
||||
};
|
||||
|
||||
jQuery.nth = function(cur, result, dir, elem){
|
||||
result = result || 1;
|
||||
var num = 0;
|
||||
|
||||
for ( ; cur; cur = cur[dir] )
|
||||
if ( cur.nodeType == 1 && ++num == result )
|
||||
break;
|
||||
|
||||
return cur;
|
||||
};
|
||||
|
||||
jQuery.sibling = function(n, elem){
|
||||
var r = [];
|
||||
|
||||
for ( ; n; n = n.nextSibling ) {
|
||||
if ( n.nodeType == 1 && n != elem )
|
||||
r.push( n );
|
||||
}
|
||||
|
||||
return r;
|
||||
};
|
||||
|
||||
return;
|
||||
|
||||
window.Sizzle = Sizzle;
|
||||
|
||||
})();
|
||||
/*
|
||||
* A number of helper functions used for managing events.
|
||||
* Many of the ideas behind this code originated from
|
||||
* Dean Edwards' addEvent library.
|
||||
*/
|
||||
jQuery.event = {
|
||||
|
||||
// Bind an event to an element
|
||||
// Original by Dean Edwards
|
||||
add: function(elem, types, handler, data) {
|
||||
if ( elem.nodeType == 3 || elem.nodeType == 8 )
|
||||
return;
|
||||
|
||||
// For whatever reason, IE has trouble passing the window object
|
||||
// around, causing it to be cloned in the process
|
||||
if ( elem.setInterval && elem != window )
|
||||
elem = window;
|
||||
|
||||
// Make sure that the function being executed has a unique ID
|
||||
if ( !handler.guid )
|
||||
handler.guid = this.guid++;
|
||||
|
||||
// if data is passed, bind to handler
|
||||
if ( data !== undefined ) {
|
||||
// Create temporary function pointer to original handler
|
||||
var fn = handler;
|
||||
|
||||
// Create unique handler function, wrapped around original handler
|
||||
handler = this.proxy( fn );
|
||||
|
||||
// Store data in unique handler
|
||||
handler.data = data;
|
||||
}
|
||||
|
||||
// Init the element's event structure
|
||||
var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
|
||||
handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
|
||||
// Handle the second event of a trigger and when
|
||||
// an event is called after a page has unloaded
|
||||
return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
|
||||
jQuery.event.handle.apply(arguments.callee.elem, arguments) :
|
||||
undefined;
|
||||
});
|
||||
// Add elem as a property of the handle function
|
||||
// This is to prevent a memory leak with non-native
|
||||
// event in IE.
|
||||
handle.elem = elem;
|
||||
|
||||
// Handle multiple events separated by a space
|
||||
// jQuery(...).bind("mouseover mouseout", fn);
|
||||
jQuery.each(types.split(/\s+/), function(index, type) {
|
||||
// Namespaced event handlers
|
||||
var namespaces = type.split(".");
|
||||
type = namespaces.shift();
|
||||
handler.type = namespaces.slice().sort().join(".");
|
||||
|
||||
// Get the current list of functions bound to this event
|
||||
var handlers = events[type];
|
||||
|
||||
if ( jQuery.event.specialAll[type] )
|
||||
jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
|
||||
|
||||
// Init the event handler queue
|
||||
if (!handlers) {
|
||||
handlers = events[type] = {};
|
||||
|
||||
// Check for a special event handler
|
||||
// Only use addEventListener/attachEvent if the special
|
||||
// events handler returns false
|
||||
if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
|
||||
// Bind the global event handler to the element
|
||||
if (elem.addEventListener)
|
||||
elem.addEventListener(type, handle, false);
|
||||
else if (elem.attachEvent)
|
||||
elem.attachEvent("on" + type, handle);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the function to the element's handler list
|
||||
handlers[handler.guid] = handler;
|
||||
|
||||
// Keep track of which events have been used, for global triggering
|
||||
jQuery.event.global[type] = true;
|
||||
});
|
||||
|
||||
// Nullify elem to prevent memory leaks in IE
|
||||
elem = null;
|
||||
},
|
||||
|
||||
guid: 1,
|
||||
global: {},
|
||||
|
||||
// Detach an event or set of events from an element
|
||||
remove: function(elem, types, handler) {
|
||||
// don't do events on text and comment nodes
|
||||
if ( elem.nodeType == 3 || elem.nodeType == 8 )
|
||||
return;
|
||||
|
||||
var events = jQuery.data(elem, "events"), ret, index;
|
||||
|
||||
if ( events ) {
|
||||
// Unbind all events for the element
|
||||
if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
|
||||
for ( var type in events )
|
||||
this.remove( elem, type + (types || "") );
|
||||
else {
|
||||
// types is actually an event object here
|
||||
if ( types.type ) {
|
||||
handler = types.handler;
|
||||
types = types.type;
|
||||
}
|
||||
|
||||
// Handle multiple events seperated by a space
|
||||
// jQuery(...).unbind("mouseover mouseout", fn);
|
||||
jQuery.each(types.split(/\s+/), function(index, type){
|
||||
// Namespaced event handlers
|
||||
var namespaces = type.split(".");
|
||||
type = namespaces.shift();
|
||||
var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
|
||||
|
||||
if ( events[type] ) {
|
||||
// remove the given handler for the given type
|
||||
if ( handler )
|
||||
delete events[type][handler.guid];
|
||||
|
||||
// remove all handlers for the given type
|
||||
else
|
||||
for ( var handle in events[type] )
|
||||
// Handle the removal of namespaced events
|
||||
if ( namespace.test(events[type][handle].type) )
|
||||
delete events[type][handle];
|
||||
|
||||
if ( jQuery.event.specialAll[type] )
|
||||
jQuery.event.specialAll[type].teardown.call(elem, namespaces);
|
||||
|
||||
// remove generic event handler if no more handlers exist
|
||||
for ( ret in events[type] ) break;
|
||||
if ( !ret ) {
|
||||
if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
|
||||
if (elem.removeEventListener)
|
||||
elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
|
||||
else if (elem.detachEvent)
|
||||
elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
|
||||
}
|
||||
ret = null;
|
||||
delete events[type];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Remove the expando if it's no longer used
|
||||
for ( ret in events ) break;
|
||||
if ( !ret ) {
|
||||
var handle = jQuery.data( elem, "handle" );
|
||||
if ( handle ) handle.elem = null;
|
||||
jQuery.removeData( elem, "events" );
|
||||
jQuery.removeData( elem, "handle" );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// bubbling is internal
|
||||
trigger: function( event, data, elem, bubbling ) {
|
||||
// Event object or event type
|
||||
var type = event.type || event;
|
||||
|
||||
if( !bubbling ){
|
||||
event = typeof event === "object" ?
|
||||
// jQuery.Event object
|
||||
event[expando] ? event :
|
||||
// Object literal
|
||||
jQuery.extend( jQuery.Event(type), event ) :
|
||||
// Just the event type (string)
|
||||
jQuery.Event(type);
|
||||
|
||||
if ( type.indexOf("!") >= 0 ) {
|
||||
event.type = type = type.slice(0, -1);
|
||||
event.exclusive = true;
|
||||
}
|
||||
|
||||
// Handle a global trigger
|
||||
if ( !elem ) {
|
||||
// Don't bubble custom events when global (to avoid too much overhead)
|
||||
event.stopPropagation();
|
||||
// Only trigger if we've ever bound an event for it
|
||||
if ( this.global[type] )
|
||||
jQuery.each( jQuery.cache, function(){
|
||||
if ( this.events && this.events[type] )
|
||||
jQuery.event.trigger( event, data, this.handle.elem );
|
||||
});
|
||||
}
|
||||
|
||||
// Handle triggering a single element
|
||||
|
||||
// don't do events on text and comment nodes
|
||||
if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
|
||||
return undefined;
|
||||
|
||||
// Clean up in case it is reused
|
||||
event.result = undefined;
|
||||
event.target = elem;
|
||||
|
||||
// Clone the incoming data, if any
|
||||
data = jQuery.makeArray(data);
|
||||
data.unshift( event );
|
||||
}
|
||||
|
||||
event.currentTarget = elem;
|
||||
|
||||
// Trigger the event, it is assumed that "handle" is a function
|
||||
var handle = jQuery.data(elem, "handle");
|
||||
if ( handle )
|
||||
handle.apply( elem, data );
|
||||
|
||||
// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
|
||||
if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
|
||||
event.result = false;
|
||||
|
||||
// Trigger the native events (except for clicks on links)
|
||||
if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
|
||||
this.triggered = true;
|
||||
try {
|
||||
elem[ type ]();
|
||||
// prevent IE from throwing an error for some hidden elements
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
this.triggered = false;
|
||||
|
||||
if ( !event.isPropagationStopped() ) {
|
||||
var parent = elem.parentNode || elem.ownerDocument;
|
||||
if ( parent )
|
||||
jQuery.event.trigger(event, data, parent, true);
|
||||
}
|
||||
},
|
||||
|
||||
handle: function(event) {
|
||||
// returned undefined or false
|
||||
var all, handlers;
|
||||
|
||||
event = arguments[0] = jQuery.event.fix( event || window.event );
|
||||
event.currentTarget = this;
|
||||
|
||||
// Namespaced event handlers
|
||||
var namespaces = event.type.split(".");
|
||||
event.type = namespaces.shift();
|
||||
|
||||
// Cache this now, all = true means, any handler
|
||||
all = !namespaces.length && !event.exclusive;
|
||||
|
||||
var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
|
||||
|
||||
handlers = ( jQuery.data(this, "events") || {} )[event.type];
|
||||
|
||||
for ( var j in handlers ) {
|
||||
var handler = handlers[j];
|
||||
|
||||
// Filter the functions by class
|
||||
if ( all || namespace.test(handler.type) ) {
|
||||
// Pass in a reference to the handler function itself
|
||||
// So that we can later remove it
|
||||
event.handler = handler;
|
||||
event.data = handler.data;
|
||||
|
||||
var ret = handler.apply(this, arguments);
|
||||
|
||||
if( ret !== undefined ){
|
||||
event.result = ret;
|
||||
if ( ret === false ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
if( event.isImmediatePropagationStopped() )
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
|
||||
|
||||
fix: function(event) {
|
||||
if ( event[expando] )
|
||||
return event;
|
||||
|
||||
// store a copy of the original event object
|
||||
// and "clone" to set read-only properties
|
||||
var originalEvent = event;
|
||||
event = jQuery.Event( originalEvent );
|
||||
|
||||
for ( var i = this.props.length, prop; i; ){
|
||||
prop = this.props[ --i ];
|
||||
event[ prop ] = originalEvent[ prop ];
|
||||
}
|
||||
|
||||
// Fix target property, if necessary
|
||||
if ( !event.target )
|
||||
event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
|
||||
|
||||
// check if target is a textnode (safari)
|
||||
if ( event.target.nodeType == 3 )
|
||||
event.target = event.target.parentNode;
|
||||
|
||||
// Add relatedTarget, if necessary
|
||||
if ( !event.relatedTarget && event.fromElement )
|
||||
event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
|
||||
|
||||
// Calculate pageX/Y if missing and clientX/Y available
|
||||
if ( event.pageX == null && event.clientX != null ) {
|
||||
var doc = document.documentElement, body = document.body;
|
||||
event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
|
||||
event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
|
||||
}
|
||||
|
||||
// Add which for key events
|
||||
if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
|
||||
event.which = event.charCode || event.keyCode;
|
||||
|
||||
// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
|
||||
if ( !event.metaKey && event.ctrlKey )
|
||||
event.metaKey = event.ctrlKey;
|
||||
|
||||
// Add which for click: 1 == left; 2 == middle; 3 == right
|
||||
// Note: button is not normalized, so don't use it
|
||||
if ( !event.which && event.button )
|
||||
event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
|
||||
|
||||
return event;
|
||||
},
|
||||
|
||||
proxy: function( fn, proxy ){
|
||||
proxy = proxy || function(){ return fn.apply(this, arguments); };
|
||||
// Set the guid of unique handler to the same of original handler, so it can be removed
|
||||
proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
|
||||
// So proxy can be declared as an argument
|
||||
return proxy;
|
||||
},
|
||||
|
||||
special: {
|
||||
ready: {
|
||||
// Make sure the ready event is setup
|
||||
setup: bindReady,
|
||||
teardown: function() {}
|
||||
}
|
||||
},
|
||||
|
||||
specialAll: {
|
||||
live: {
|
||||
setup: function( selector, namespaces ){
|
||||
jQuery.event.add( this, namespaces[0], liveHandler );
|
||||
},
|
||||
teardown: function( namespaces ){
|
||||
if ( namespaces.length ) {
|
||||
var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
|
||||
|
||||
jQuery.each( (jQuery.data(this, "events").live || {}), function(){
|
||||
if ( name.test(this.type) )
|
||||
remove++;
|
||||
});
|
||||
|
||||
if ( remove < 1 )
|
||||
jQuery.event.remove( this, namespaces[0], liveHandler );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jQuery.Event = function( src ){
|
||||
// Allow instantiation without the 'new' keyword
|
||||
if( !this.preventDefault )
|
||||
return new jQuery.Event(src);
|
||||
|
||||
// Event object
|
||||
if( src && src.type ){
|
||||
this.originalEvent = src;
|
||||
this.type = src.type;
|
||||
// Event type
|
||||
}else
|
||||
this.type = src;
|
||||
|
||||
// timeStamp is buggy for some events on Firefox(#3843)
|
||||
// So we won't rely on the native value
|
||||
this.timeStamp = now();
|
||||
|
||||
// Mark it as fixed
|
||||
this[expando] = true;
|
||||
};
|
||||
|
||||
function returnFalse(){
|
||||
return false;
|
||||
}
|
||||
function returnTrue(){
|
||||
return true;
|
||||
}
|
||||
|
||||
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
|
||||
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
|
||||
jQuery.Event.prototype = {
|
||||
preventDefault: function() {
|
||||
this.isDefaultPrevented = returnTrue;
|
||||
|
||||
var e = this.originalEvent;
|
||||
if( !e )
|
||||
return;
|
||||
// if preventDefault exists run it on the original event
|
||||
if (e.preventDefault)
|
||||
e.preventDefault();
|
||||
// otherwise set the returnValue property of the original event to false (IE)
|
||||
e.returnValue = false;
|
||||
},
|
||||
stopPropagation: function() {
|
||||
this.isPropagationStopped = returnTrue;
|
||||
|
||||
var e = this.originalEvent;
|
||||
if( !e )
|
||||
return;
|
||||
// if stopPropagation exists run it on the original event
|
||||
if (e.stopPropagation)
|
||||
e.stopPropagation();
|
||||
// otherwise set the cancelBubble property of the original event to true (IE)
|
||||
e.cancelBubble = true;
|
||||
},
|
||||
stopImmediatePropagation:function(){
|
||||
this.isImmediatePropagationStopped = returnTrue;
|
||||
this.stopPropagation();
|
||||
},
|
||||
isDefaultPrevented: returnFalse,
|
||||
isPropagationStopped: returnFalse,
|
||||
isImmediatePropagationStopped: returnFalse
|
||||
};
|
||||
// Checks if an event happened on an element within another element
|
||||
// Used in jQuery.event.special.mouseenter and mouseleave handlers
|
||||
var withinElement = function(event) {
|
||||
// Check if mouse(over|out) are still within the same parent element
|
||||
var parent = event.relatedTarget;
|
||||
// Traverse up the tree
|
||||
while ( parent && parent != this )
|
||||
try { parent = parent.parentNode; }
|
||||
catch(e) { parent = this; }
|
||||
|
||||
if( parent != this ){
|
||||
// set the correct event type
|
||||
event.type = event.data;
|
||||
// handle event if we actually just moused on to a non sub-element
|
||||
jQuery.event.handle.apply( this, arguments );
|
||||
}
|
||||
};
|
||||
|
||||
jQuery.each({
|
||||
mouseover: 'mouseenter',
|
||||
mouseout: 'mouseleave'
|
||||
}, function( orig, fix ){
|
||||
jQuery.event.special[ fix ] = {
|
||||
setup: function(){
|
||||
jQuery.event.add( this, orig, withinElement, fix );
|
||||
},
|
||||
teardown: function(){
|
||||
jQuery.event.remove( this, orig, withinElement );
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
jQuery.fn.extend({
|
||||
bind: function( type, data, fn ) {
|
||||
return type == "unload" ? this.one(type, data, fn) : this.each(function(){
|
||||
jQuery.event.add( this, type, fn || data, fn && data );
|
||||
});
|
||||
},
|
||||
|
||||
one: function( type, data, fn ) {
|
||||
var one = jQuery.event.proxy( fn || data, function(event) {
|
||||
jQuery(this).unbind(event, one);
|
||||
return (fn || data).apply( this, arguments );
|
||||
});
|
||||
return this.each(function(){
|
||||
jQuery.event.add( this, type, one, fn && data);
|
||||
});
|
||||
},
|
||||
|
||||
unbind: function( type, fn ) {
|
||||
return this.each(function(){
|
||||
jQuery.event.remove( this, type, fn );
|
||||
});
|
||||
},
|
||||
|
||||
trigger: function( type, data ) {
|
||||
return this.each(function(){
|
||||
jQuery.event.trigger( type, data, this );
|
||||
});
|
||||
},
|
||||
|
||||
triggerHandler: function( type, data ) {
|
||||
if( this[0] ){
|
||||
var event = jQuery.Event(type);
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
jQuery.event.trigger( event, data, this[0] );
|
||||
return event.result;
|
||||
}
|
||||
},
|
||||
|
||||
toggle: function( fn ) {
|
||||
// Save reference to arguments for access in closure
|
||||
var args = arguments, i = 1;
|
||||
|
||||
// link all the functions, so any of them can unbind this click handler
|
||||
while( i < args.length )
|
||||
jQuery.event.proxy( fn, args[i++] );
|
||||
|
||||
return this.click( jQuery.event.proxy( fn, function(event) {
|
||||
// Figure out which function to execute
|
||||
this.lastToggle = ( this.lastToggle || 0 ) % i;
|
||||
|
||||
// Make sure that clicks stop
|
||||
event.preventDefault();
|
||||
|
||||
// and execute the function
|
||||
return args[ this.lastToggle++ ].apply( this, arguments ) || false;
|
||||
}));
|
||||
},
|
||||
|
||||
hover: function(fnOver, fnOut) {
|
||||
return this.mouseenter(fnOver).mouseleave(fnOut);
|
||||
},
|
||||
|
||||
ready: function(fn) {
|
||||
// Attach the listeners
|
||||
bindReady();
|
||||
|
||||
// If the DOM is already ready
|
||||
if ( jQuery.isReady )
|
||||
// Execute the function immediately
|
||||
fn.call( document, jQuery );
|
||||
|
||||
// Otherwise, remember the function for later
|
||||
else
|
||||
// Add the function to the wait list
|
||||
jQuery.readyList.push( fn );
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
live: function( type, fn ){
|
||||
var proxy = jQuery.event.proxy( fn );
|
||||
proxy.guid += this.selector + type;
|
||||
|
||||
jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
die: function( type, fn ){
|
||||
jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
function liveHandler( event ){
|
||||
var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
|
||||
stop = true,
|
||||
elems = [];
|
||||
|
||||
jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
|
||||
if ( check.test(fn.type) ) {
|
||||
var elem = jQuery(event.target).closest(fn.data)[0];
|
||||
if ( elem )
|
||||
elems.push({ elem: elem, fn: fn });
|
||||
}
|
||||
});
|
||||
|
||||
elems.sort(function(a,b) {
|
||||
return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
|
||||
});
|
||||
|
||||
jQuery.each(elems, function(){
|
||||
if ( this.fn.call(this.elem, event, this.fn.data) === false )
|
||||
return (stop = false);
|
||||
});
|
||||
|
||||
return stop;
|
||||
}
|
||||
|
||||
function liveConvert(type, selector){
|
||||
return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
|
||||
}
|
||||
|
||||
jQuery.extend({
|
||||
isReady: false,
|
||||
readyList: [],
|
||||
// Handle when the DOM is ready
|
||||
ready: function() {
|
||||
// Make sure that the DOM is not already loaded
|
||||
if ( !jQuery.isReady ) {
|
||||
// Remember that the DOM is ready
|
||||
jQuery.isReady = true;
|
||||
|
||||
// If there are functions bound, to execute
|
||||
if ( jQuery.readyList ) {
|
||||
// Execute all of them
|
||||
jQuery.each( jQuery.readyList, function(){
|
||||
this.call( document, jQuery );
|
||||
});
|
||||
|
||||
// Reset the list of functions
|
||||
jQuery.readyList = null;
|
||||
}
|
||||
|
||||
// Trigger any bound ready events
|
||||
jQuery(document).triggerHandler("ready");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var readyBound = false;
|
||||
|
||||
function bindReady(){
|
||||
if ( readyBound ) return;
|
||||
readyBound = true;
|
||||
|
||||
// Mozilla, Opera and webkit nightlies currently support this event
|
||||
if ( document.addEventListener ) {
|
||||
// Use the handy event callback
|
||||
document.addEventListener( "DOMContentLoaded", function(){
|
||||
document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
|
||||
jQuery.ready();
|
||||
}, false );
|
||||
|
||||
// If IE event model is used
|
||||
} else if ( document.attachEvent ) {
|
||||
// ensure firing before onload,
|
||||
// maybe late but safe also for iframes
|
||||
document.attachEvent("onreadystatechange", function(){
|
||||
if ( document.readyState === "complete" ) {
|
||||
document.detachEvent( "onreadystatechange", arguments.callee );
|
||||
jQuery.ready();
|
||||
}
|
||||
});
|
||||
|
||||
// If IE and not an iframe
|
||||
// continually check to see if the document is ready
|
||||
if ( document.documentElement.doScroll && window == window.top ) (function(){
|
||||
if ( jQuery.isReady ) return;
|
||||
|
||||
try {
|
||||
// If IE is used, use the trick by Diego Perini
|
||||
// http://javascript.nwbox.com/IEContentLoaded/
|
||||
document.documentElement.doScroll("left");
|
||||
} catch( error ) {
|
||||
setTimeout( arguments.callee, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
// and execute any waiting functions
|
||||
jQuery.ready();
|
||||
})();
|
||||
}
|
||||
|
||||
// A fallback to window.onload, that will always work
|
||||
jQuery.event.add( window, "load", jQuery.ready );
|
||||
}
|
||||
|
||||
jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
|
||||
"mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
|
||||
"change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
|
||||
|
||||
// Handle event binding
|
||||
jQuery.fn[name] = function(fn){
|
||||
return fn ? this.bind(name, fn) : this.trigger(name);
|
||||
};
|
||||
});
|
||||
|
||||
// Prevent memory leaks in IE
|
||||
// And prevent errors on refresh with events like mouseover in other browsers
|
||||
// Window isn't included so as not to unbind existing unload events
|
||||
jQuery( window ).bind( 'unload', function(){
|
||||
for ( var id in jQuery.cache )
|
||||
// Skip the window
|
||||
if ( id != 1 && jQuery.cache[ id ].handle )
|
||||
jQuery.event.remove( jQuery.cache[ id ].handle.elem );
|
||||
});
|
||||
(function(){
|
||||
|
||||
jQuery.support = {};
|
||||
|
||||
var root = document.documentElement,
|
||||
script = document.createElement("script"),
|
||||
div = document.createElement("div"),
|
||||
id = "script" + (new Date).getTime();
|
||||
|
||||
div.style.display = "none";
|
||||
div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
|
||||
|
||||
var all = div.getElementsByTagName("*"),
|
||||
a = div.getElementsByTagName("a")[0];
|
||||
|
||||
// Can't get basic test support
|
||||
if ( !all || !all.length || !a ) {
|
||||
return;
|
||||
}
|
||||
|
||||
jQuery.support = {
|
||||
// IE strips leading whitespace when .innerHTML is used
|
||||
leadingWhitespace: div.firstChild.nodeType == 3,
|
||||
|
||||
// Make sure that tbody elements aren't automatically inserted
|
||||
// IE will insert them into empty tables
|
||||
tbody: !div.getElementsByTagName("tbody").length,
|
||||
|
||||
// Make sure that you can get all elements in an <object> element
|
||||
// IE 7 always returns no results
|
||||
objectAll: !!div.getElementsByTagName("object")[0]
|
||||
.getElementsByTagName("*").length,
|
||||
|
||||
// Make sure that link elements get serialized correctly by innerHTML
|
||||
// This requires a wrapper element in IE
|
||||
htmlSerialize: !!div.getElementsByTagName("link").length,
|
||||
|
||||
// Get the style information from getAttribute
|
||||
// (IE uses .cssText insted)
|
||||
style: /red/.test( a.getAttribute("style") ),
|
||||
|
||||
// Make sure that URLs aren't manipulated
|
||||
// (IE normalizes it by default)
|
||||
hrefNormalized: a.getAttribute("href") === "/a",
|
||||
|
||||
// Make sure that element opacity exists
|
||||
// (IE uses filter instead)
|
||||
opacity: a.style.opacity === "0.5",
|
||||
|
||||
// Verify style float existence
|
||||
// (IE uses styleFloat instead of cssFloat)
|
||||
cssFloat: !!a.style.cssFloat,
|
||||
|
||||
// Will be defined later
|
||||
scriptEval: false,
|
||||
noCloneEvent: true,
|
||||
boxModel: null
|
||||
};
|
||||
|
||||
script.type = "text/javascript";
|
||||
try {
|
||||
script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
|
||||
} catch(e){}
|
||||
|
||||
root.insertBefore( script, root.firstChild );
|
||||
|
||||
// Make sure that the execution of code works by injecting a script
|
||||
// tag with appendChild/createTextNode
|
||||
// (IE doesn't support this, fails, and uses .text instead)
|
||||
if ( window[ id ] ) {
|
||||
jQuery.support.scriptEval = true;
|
||||
delete window[ id ];
|
||||
}
|
||||
|
||||
root.removeChild( script );
|
||||
|
||||
if ( div.attachEvent && div.fireEvent ) {
|
||||
div.attachEvent("onclick", function(){
|
||||
// Cloning a node shouldn't copy over any
|
||||
// bound event handlers (IE does this)
|
||||
jQuery.support.noCloneEvent = false;
|
||||
div.detachEvent("onclick", arguments.callee);
|
||||
});
|
||||
div.cloneNode(true).fireEvent("onclick");
|
||||
}
|
||||
|
||||
// Figure out if the W3C box model works as expected
|
||||
// document.body must exist before we can do this
|
||||
jQuery(function(){
|
||||
var div = document.createElement("div");
|
||||
div.style.width = div.style.paddingLeft = "1px";
|
||||
|
||||
document.body.appendChild( div );
|
||||
jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
|
||||
document.body.removeChild( div ).style.display = 'none';
|
||||
});
|
||||
})();
|
||||
|
||||
var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
|
||||
|
||||
jQuery.props = {
|
||||
"for": "htmlFor",
|
||||
"class": "className",
|
||||
"float": styleFloat,
|
||||
cssFloat: styleFloat,
|
||||
styleFloat: styleFloat,
|
||||
readonly: "readOnly",
|
||||
maxlength: "maxLength",
|
||||
cellspacing: "cellSpacing",
|
||||
rowspan: "rowSpan",
|
||||
tabindex: "tabIndex"
|
||||
};
|
||||
jQuery.fn.extend({
|
||||
// Keep a copy of the old load
|
||||
_load: jQuery.fn.load,
|
||||
|
||||
load: function( url, params, callback ) {
|
||||
if ( typeof url !== "string" )
|
||||
return this._load( url );
|
||||
|
||||
var off = url.indexOf(" ");
|
||||
if ( off >= 0 ) {
|
||||
var selector = url.slice(off, url.length);
|
||||
url = url.slice(0, off);
|
||||
}
|
||||
|
||||
// Default to a GET request
|
||||
var type = "GET";
|
||||
|
||||
// If the second parameter was provided
|
||||
if ( params )
|
||||
// If it's a function
|
||||
if ( jQuery.isFunction( params ) ) {
|
||||
// We assume that it's the callback
|
||||
callback = params;
|
||||
params = null;
|
||||
|
||||
// Otherwise, build a param string
|
||||
} else if( typeof params === "object" ) {
|
||||
params = jQuery.param( params );
|
||||
type = "POST";
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
// Request the remote document
|
||||
jQuery.ajax({
|
||||
url: url,
|
||||
type: type,
|
||||
dataType: "html",
|
||||
data: params,
|
||||
complete: function(res, status){
|
||||
// If successful, inject the HTML into all the matched elements
|
||||
if ( status == "success" || status == "notmodified" )
|
||||
// See if a selector was specified
|
||||
self.html( selector ?
|
||||
// Create a dummy div to hold the results
|
||||
jQuery("<div/>")
|
||||
// inject the contents of the document in, removing the scripts
|
||||
// to avoid any 'Permission Denied' errors in IE
|
||||
.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
|
||||
|
||||
// Locate the specified elements
|
||||
.find(selector) :
|
||||
|
||||
// If not, just inject the full result
|
||||
res.responseText );
|
||||
|
||||
if( callback )
|
||||
self.each( callback, [res.responseText, status, res] );
|
||||
}
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
serialize: function() {
|
||||
return jQuery.param(this.serializeArray());
|
||||
},
|
||||
serializeArray: function() {
|
||||
return this.map(function(){
|
||||
return this.elements ? jQuery.makeArray(this.elements) : this;
|
||||
})
|
||||
.filter(function(){
|
||||
return this.name && !this.disabled &&
|
||||
(this.checked || /select|textarea/i.test(this.nodeName) ||
|
||||
/text|hidden|password|search/i.test(this.type));
|
||||
})
|
||||
.map(function(i, elem){
|
||||
var val = jQuery(this).val();
|
||||
return val == null ? null :
|
||||
jQuery.isArray(val) ?
|
||||
jQuery.map( val, function(val, i){
|
||||
return {name: elem.name, value: val};
|
||||
}) :
|
||||
{name: elem.name, value: val};
|
||||
}).get();
|
||||
}
|
||||
});
|
||||
|
||||
// Attach a bunch of functions for handling common AJAX events
|
||||
jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
|
||||
jQuery.fn[o] = function(f){
|
||||
return this.bind(o, f);
|
||||
};
|
||||
});
|
||||
|
||||
var jsc = now();
|
||||
|
||||
jQuery.extend({
|
||||
|
||||
get: function( url, data, callback, type ) {
|
||||
// shift arguments if data argument was ommited
|
||||
if ( jQuery.isFunction( data ) ) {
|
||||
callback = data;
|
||||
data = null;
|
||||
}
|
||||
|
||||
return jQuery.ajax({
|
||||
type: "GET",
|
||||
url: url,
|
||||
data: data,
|
||||
success: callback,
|
||||
dataType: type
|
||||
});
|
||||
},
|
||||
|
||||
getScript: function( url, callback ) {
|
||||
return jQuery.get(url, null, callback, "script");
|
||||
},
|
||||
|
||||
getJSON: function( url, data, callback ) {
|
||||
return jQuery.get(url, data, callback, "json");
|
||||
},
|
||||
|
||||
post: function( url, data, callback, type ) {
|
||||
if ( jQuery.isFunction( data ) ) {
|
||||
callback = data;
|
||||
data = {};
|
||||
}
|
||||
|
||||
return jQuery.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: data,
|
||||
success: callback,
|
||||
dataType: type
|
||||
});
|
||||
},
|
||||
|
||||
ajaxSetup: function( settings ) {
|
||||
jQuery.extend( jQuery.ajaxSettings, settings );
|
||||
},
|
||||
|
||||
ajaxSettings: {
|
||||
url: location.href,
|
||||
global: true,
|
||||
type: "GET",
|
||||
contentType: "application/x-www-form-urlencoded",
|
||||
processData: true,
|
||||
async: true,
|
||||
/*
|
||||
timeout: 0,
|
||||
data: null,
|
||||
username: null,
|
||||
password: null,
|
||||
*/
|
||||
// Create the request object; Microsoft failed to properly
|
||||
// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
|
||||
// This function can be overriden by calling jQuery.ajaxSetup
|
||||
xhr:function(){
|
||||
return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
|
||||
},
|
||||
accepts: {
|
||||
xml: "application/xml, text/xml",
|
||||
html: "text/html",
|
||||
script: "text/javascript, application/javascript",
|
||||
json: "application/json, text/javascript",
|
||||
text: "text/plain",
|
||||
_default: "*/*"
|
||||
}
|
||||
},
|
||||
|
||||
// Last-Modified header cache for next request
|
||||
lastModified: {},
|
||||
|
||||
ajax: function( s ) {
|
||||
// Extend the settings, but re-extend 's' so that it can be
|
||||
// checked again later (in the test suite, specifically)
|
||||
s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
|
||||
|
||||
var jsonp, jsre = /=\?(&|$)/g, status, data,
|
||||
type = s.type.toUpperCase();
|
||||
|
||||
// convert data if not already a string
|
||||
if ( s.data && s.processData && typeof s.data !== "string" )
|
||||
s.data = jQuery.param(s.data);
|
||||
|
||||
// Handle JSONP Parameter Callbacks
|
||||
if ( s.dataType == "jsonp" ) {
|
||||
if ( type == "GET" ) {
|
||||
if ( !s.url.match(jsre) )
|
||||
s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
|
||||
} else if ( !s.data || !s.data.match(jsre) )
|
||||
s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
|
||||
s.dataType = "json";
|
||||
}
|
||||
|
||||
// Build temporary JSONP function
|
||||
if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
|
||||
jsonp = "jsonp" + jsc++;
|
||||
|
||||
// Replace the =? sequence both in the query string and the data
|
||||
if ( s.data )
|
||||
s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
|
||||
s.url = s.url.replace(jsre, "=" + jsonp + "$1");
|
||||
|
||||
// We need to make sure
|
||||
// that a JSONP style response is executed properly
|
||||
s.dataType = "script";
|
||||
|
||||
// Handle JSONP-style loading
|
||||
window[ jsonp ] = function(tmp){
|
||||
data = tmp;
|
||||
success();
|
||||
complete();
|
||||
// Garbage collect
|
||||
window[ jsonp ] = undefined;
|
||||
try{ delete window[ jsonp ]; } catch(e){}
|
||||
if ( head )
|
||||
head.removeChild( script );
|
||||
};
|
||||
}
|
||||
|
||||
if ( s.dataType == "script" && s.cache == null )
|
||||
s.cache = false;
|
||||
|
||||
if ( s.cache === false && type == "GET" ) {
|
||||
var ts = now();
|
||||
// try replacing _= if it is there
|
||||
var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
|
||||
// if nothing was replaced, add timestamp to the end
|
||||
s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
|
||||
}
|
||||
|
||||
// If data is available, append data to url for get requests
|
||||
if ( s.data && type == "GET" ) {
|
||||
s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
|
||||
|
||||
// IE likes to send both get and post data, prevent this
|
||||
s.data = null;
|
||||
}
|
||||
|
||||
// Watch for a new set of requests
|
||||
if ( s.global && ! jQuery.active++ )
|
||||
jQuery.event.trigger( "ajaxStart" );
|
||||
|
||||
// Matches an absolute URL, and saves the domain
|
||||
var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
|
||||
|
||||
// If we're requesting a remote document
|
||||
// and trying to load JSON or Script with a GET
|
||||
if ( s.dataType == "script" && type == "GET" && parts
|
||||
&& ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
|
||||
|
||||
var head = document.getElementsByTagName("head")[0];
|
||||
var script = document.createElement("script");
|
||||
script.src = s.url;
|
||||
if (s.scriptCharset)
|
||||
script.charset = s.scriptCharset;
|
||||
|
||||
// Handle Script loading
|
||||
if ( !jsonp ) {
|
||||
var done = false;
|
||||
|
||||
// Attach handlers for all browsers
|
||||
script.onload = script.onreadystatechange = function(){
|
||||
if ( !done && (!this.readyState ||
|
||||
this.readyState == "loaded" || this.readyState == "complete") ) {
|
||||
done = true;
|
||||
success();
|
||||
complete();
|
||||
|
||||
// Handle memory leak in IE
|
||||
script.onload = script.onreadystatechange = null;
|
||||
head.removeChild( script );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
head.appendChild(script);
|
||||
|
||||
// We handle everything using the script element injection
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var requestDone = false;
|
||||
|
||||
// Create the request object
|
||||
var xhr = s.xhr();
|
||||
|
||||
// Open the socket
|
||||
// Passing null username, generates a login popup on Opera (#2865)
|
||||
if( s.username )
|
||||
xhr.open(type, s.url, s.async, s.username, s.password);
|
||||
else
|
||||
xhr.open(type, s.url, s.async);
|
||||
|
||||
// Need an extra try/catch for cross domain requests in Firefox 3
|
||||
try {
|
||||
// Set the correct header, if data is being sent
|
||||
if ( s.data )
|
||||
xhr.setRequestHeader("Content-Type", s.contentType);
|
||||
|
||||
// Set the If-Modified-Since header, if ifModified mode.
|
||||
if ( s.ifModified )
|
||||
xhr.setRequestHeader("If-Modified-Since",
|
||||
jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
|
||||
|
||||
// Set header so the called script knows that it's an XMLHttpRequest
|
||||
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
||||
|
||||
// Set the Accepts header for the server, depending on the dataType
|
||||
xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
|
||||
s.accepts[ s.dataType ] + ", */*" :
|
||||
s.accepts._default );
|
||||
} catch(e){}
|
||||
|
||||
// Allow custom headers/mimetypes and early abort
|
||||
if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
|
||||
// Handle the global AJAX counter
|
||||
if ( s.global && ! --jQuery.active )
|
||||
jQuery.event.trigger( "ajaxStop" );
|
||||
// close opended socket
|
||||
xhr.abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( s.global )
|
||||
jQuery.event.trigger("ajaxSend", [xhr, s]);
|
||||
|
||||
// Wait for a response to come back
|
||||
var onreadystatechange = function(isTimeout){
|
||||
// The request was aborted, clear the interval and decrement jQuery.active
|
||||
if (xhr.readyState == 0) {
|
||||
if (ival) {
|
||||
// clear poll interval
|
||||
clearInterval(ival);
|
||||
ival = null;
|
||||
// Handle the global AJAX counter
|
||||
if ( s.global && ! --jQuery.active )
|
||||
jQuery.event.trigger( "ajaxStop" );
|
||||
}
|
||||
// The transfer is complete and the data is available, or the request timed out
|
||||
} else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
|
||||
requestDone = true;
|
||||
|
||||
// clear poll interval
|
||||
if (ival) {
|
||||
clearInterval(ival);
|
||||
ival = null;
|
||||
}
|
||||
|
||||
status = isTimeout == "timeout" ? "timeout" :
|
||||
!jQuery.httpSuccess( xhr ) ? "error" :
|
||||
s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
|
||||
"success";
|
||||
|
||||
if ( status == "success" ) {
|
||||
// Watch for, and catch, XML document parse errors
|
||||
try {
|
||||
// process the data (runs the xml through httpData regardless of callback)
|
||||
data = jQuery.httpData( xhr, s.dataType, s );
|
||||
} catch(e) {
|
||||
status = "parsererror";
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that the request was successful or notmodified
|
||||
if ( status == "success" ) {
|
||||
// Cache Last-Modified header, if ifModified mode.
|
||||
var modRes;
|
||||
try {
|
||||
modRes = xhr.getResponseHeader("Last-Modified");
|
||||
} catch(e) {} // swallow exception thrown by FF if header is not available
|
||||
|
||||
if ( s.ifModified && modRes )
|
||||
jQuery.lastModified[s.url] = modRes;
|
||||
|
||||
// JSONP handles its own success callback
|
||||
if ( !jsonp )
|
||||
success();
|
||||
} else
|
||||
jQuery.handleError(s, xhr, status);
|
||||
|
||||
// Fire the complete handlers
|
||||
complete();
|
||||
|
||||
if ( isTimeout )
|
||||
xhr.abort();
|
||||
|
||||
// Stop memory leaks
|
||||
if ( s.async )
|
||||
xhr = null;
|
||||
}
|
||||
};
|
||||
|
||||
if ( s.async ) {
|
||||
// don't attach the handler to the request, just poll it instead
|
||||
var ival = setInterval(onreadystatechange, 13);
|
||||
|
||||
// Timeout checker
|
||||
if ( s.timeout > 0 )
|
||||
setTimeout(function(){
|
||||
// Check to see if the request is still happening
|
||||
if ( xhr && !requestDone )
|
||||
onreadystatechange( "timeout" );
|
||||
}, s.timeout);
|
||||
}
|
||||
|
||||
// Send the data
|
||||
try {
|
||||
xhr.send(s.data);
|
||||
} catch(e) {
|
||||
jQuery.handleError(s, xhr, null, e);
|
||||
}
|
||||
|
||||
// firefox 1.5 doesn't fire statechange for sync requests
|
||||
if ( !s.async )
|
||||
onreadystatechange();
|
||||
|
||||
function success(){
|
||||
// If a local callback was specified, fire it and pass it the data
|
||||
if ( s.success )
|
||||
s.success( data, status );
|
||||
|
||||
// Fire the global callback
|
||||
if ( s.global )
|
||||
jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
|
||||
}
|
||||
|
||||
function complete(){
|
||||
// Process result
|
||||
if ( s.complete )
|
||||
s.complete(xhr, status);
|
||||
|
||||
// The request was completed
|
||||
if ( s.global )
|
||||
jQuery.event.trigger( "ajaxComplete", [xhr, s] );
|
||||
|
||||
// Handle the global AJAX counter
|
||||
if ( s.global && ! --jQuery.active )
|
||||
jQuery.event.trigger( "ajaxStop" );
|
||||
}
|
||||
|
||||
// return XMLHttpRequest to allow aborting the request etc.
|
||||
return xhr;
|
||||
},
|
||||
|
||||
handleError: function( s, xhr, status, e ) {
|
||||
// If a local callback was specified, fire it
|
||||
if ( s.error ) s.error( xhr, status, e );
|
||||
|
||||
// Fire the global callback
|
||||
if ( s.global )
|
||||
jQuery.event.trigger( "ajaxError", [xhr, s, e] );
|
||||
},
|
||||
|
||||
// Counter for holding the number of active queries
|
||||
active: 0,
|
||||
|
||||
// Determines if an XMLHttpRequest was successful or not
|
||||
httpSuccess: function( xhr ) {
|
||||
try {
|
||||
// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
|
||||
return !xhr.status && location.protocol == "file:" ||
|
||||
( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
|
||||
} catch(e){}
|
||||
return false;
|
||||
},
|
||||
|
||||
// Determines if an XMLHttpRequest returns NotModified
|
||||
httpNotModified: function( xhr, url ) {
|
||||
try {
|
||||
var xhrRes = xhr.getResponseHeader("Last-Modified");
|
||||
|
||||
// Firefox always returns 200. check Last-Modified date
|
||||
return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
|
||||
} catch(e){}
|
||||
return false;
|
||||
},
|
||||
|
||||
httpData: function( xhr, type, s ) {
|
||||
var ct = xhr.getResponseHeader("content-type"),
|
||||
xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
|
||||
data = xml ? xhr.responseXML : xhr.responseText;
|
||||
|
||||
if ( xml && data.documentElement.tagName == "parsererror" )
|
||||
throw "parsererror";
|
||||
|
||||
// Allow a pre-filtering function to sanitize the response
|
||||
// s != null is checked to keep backwards compatibility
|
||||
if( s && s.dataFilter )
|
||||
data = s.dataFilter( data, type );
|
||||
|
||||
// The filter can actually parse the response
|
||||
if( typeof data === "string" ){
|
||||
|
||||
// If the type is "script", eval it in global context
|
||||
if ( type == "script" )
|
||||
jQuery.globalEval( data );
|
||||
|
||||
// Get the JavaScript object, if JSON is used.
|
||||
if ( type == "json" )
|
||||
data = window["eval"]("(" + data + ")");
|
||||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
// Serialize an array of form elements or a set of
|
||||
// key/values into a query string
|
||||
param: function( a ) {
|
||||
var s = [ ];
|
||||
|
||||
function add( key, value ){
|
||||
s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
||||
};
|
||||
|
||||
// If an array was passed in, assume that it is an array
|
||||
// of form elements
|
||||
if ( jQuery.isArray(a) || a.jquery )
|
||||
// Serialize the form elements
|
||||
jQuery.each( a, function(){
|
||||
add( this.name, this.value );
|
||||
});
|
||||
|
||||
// Otherwise, assume that it's an object of key/value pairs
|
||||
else
|
||||
// Serialize the key/values
|
||||
for ( var j in a )
|
||||
// If the value is an array then the key names need to be repeated
|
||||
if ( jQuery.isArray(a[j]) )
|
||||
jQuery.each( a[j], function(){
|
||||
add( j, this );
|
||||
});
|
||||
else
|
||||
add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
|
||||
|
||||
// Return the resulting serialization
|
||||
return s.join("&").replace(/%20/g, "+");
|
||||
}
|
||||
|
||||
});
|
||||
var elemdisplay = {},
|
||||
timerId,
|
||||
fxAttrs = [
|
||||
// height animations
|
||||
[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
|
||||
// width animations
|
||||
[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
|
||||
// opacity animations
|
||||
[ "opacity" ]
|
||||
];
|
||||
|
||||
function genFx( type, num ){
|
||||
var obj = {};
|
||||
jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
|
||||
obj[ this ] = type;
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
|
||||
jQuery.fn.extend({
|
||||
show: function(speed,callback){
|
||||
if ( speed ) {
|
||||
return this.animate( genFx("show", 3), speed, callback);
|
||||
} else {
|
||||
for ( var i = 0, l = this.length; i < l; i++ ){
|
||||
var old = jQuery.data(this[i], "olddisplay");
|
||||
|
||||
this[i].style.display = old || "";
|
||||
|
||||
if ( jQuery.css(this[i], "display") === "none" ) {
|
||||
var tagName = this[i].tagName, display;
|
||||
|
||||
if ( elemdisplay[ tagName ] ) {
|
||||
display = elemdisplay[ tagName ];
|
||||
} else {
|
||||
var elem = jQuery("<" + tagName + " />").appendTo("body");
|
||||
|
||||
display = elem.css("display");
|
||||
if ( display === "none" )
|
||||
display = "block";
|
||||
|
||||
elem.remove();
|
||||
|
||||
elemdisplay[ tagName ] = display;
|
||||
}
|
||||
|
||||
jQuery.data(this[i], "olddisplay", display);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the display of the elements in a second loop
|
||||
// to avoid the constant reflow
|
||||
for ( var i = 0, l = this.length; i < l; i++ ){
|
||||
this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
},
|
||||
|
||||
hide: function(speed,callback){
|
||||
if ( speed ) {
|
||||
return this.animate( genFx("hide", 3), speed, callback);
|
||||
} else {
|
||||
for ( var i = 0, l = this.length; i < l; i++ ){
|
||||
var old = jQuery.data(this[i], "olddisplay");
|
||||
if ( !old && old !== "none" )
|
||||
jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
|
||||
}
|
||||
|
||||
// Set the display of the elements in a second loop
|
||||
// to avoid the constant reflow
|
||||
for ( var i = 0, l = this.length; i < l; i++ ){
|
||||
this[i].style.display = "none";
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
},
|
||||
|
||||
// Save the old toggle function
|
||||
_toggle: jQuery.fn.toggle,
|
||||
|
||||
toggle: function( fn, fn2 ){
|
||||
var bool = typeof fn === "boolean";
|
||||
|
||||
return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
|
||||
this._toggle.apply( this, arguments ) :
|
||||
fn == null || bool ?
|
||||
this.each(function(){
|
||||
var state = bool ? fn : jQuery(this).is(":hidden");
|
||||
jQuery(this)[ state ? "show" : "hide" ]();
|
||||
}) :
|
||||
this.animate(genFx("toggle", 3), fn, fn2);
|
||||
},
|
||||
|
||||
fadeTo: function(speed,to,callback){
|
||||
return this.animate({opacity: to}, speed, callback);
|
||||
},
|
||||
|
||||
animate: function( prop, speed, easing, callback ) {
|
||||
var optall = jQuery.speed(speed, easing, callback);
|
||||
|
||||
return this[ optall.queue === false ? "each" : "queue" ](function(){
|
||||
|
||||
var opt = jQuery.extend({}, optall), p,
|
||||
hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
|
||||
self = this;
|
||||
|
||||
for ( p in prop ) {
|
||||
if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
|
||||
return opt.complete.call(this);
|
||||
|
||||
if ( ( p == "height" || p == "width" ) && this.style ) {
|
||||
// Store display property
|
||||
opt.display = jQuery.css(this, "display");
|
||||
|
||||
// Make sure that nothing sneaks out
|
||||
opt.overflow = this.style.overflow;
|
||||
}
|
||||
}
|
||||
|
||||
if ( opt.overflow != null )
|
||||
this.style.overflow = "hidden";
|
||||
|
||||
opt.curAnim = jQuery.extend({}, prop);
|
||||
|
||||
jQuery.each( prop, function(name, val){
|
||||
var e = new jQuery.fx( self, opt, name );
|
||||
|
||||
if ( /toggle|show|hide/.test(val) )
|
||||
e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
|
||||
else {
|
||||
var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
|
||||
start = e.cur(true) || 0;
|
||||
|
||||
if ( parts ) {
|
||||
var end = parseFloat(parts[2]),
|
||||
unit = parts[3] || "px";
|
||||
|
||||
// We need to compute starting value
|
||||
if ( unit != "px" ) {
|
||||
self.style[ name ] = (end || 1) + unit;
|
||||
start = ((end || 1) / e.cur(true)) * start;
|
||||
self.style[ name ] = start + unit;
|
||||
}
|
||||
|
||||
// If a +=/-= token was provided, we're doing a relative animation
|
||||
if ( parts[1] )
|
||||
end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
|
||||
|
||||
e.custom( start, end, unit );
|
||||
} else
|
||||
e.custom( start, val, "" );
|
||||
}
|
||||
});
|
||||
|
||||
// For JS strict compliance
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
stop: function(clearQueue, gotoEnd){
|
||||
var timers = jQuery.timers;
|
||||
|
||||
if (clearQueue)
|
||||
this.queue([]);
|
||||
|
||||
this.each(function(){
|
||||
// go in reverse order so anything added to the queue during the loop is ignored
|
||||
for ( var i = timers.length - 1; i >= 0; i-- )
|
||||
if ( timers[i].elem == this ) {
|
||||
if (gotoEnd)
|
||||
// force the next step to be the last
|
||||
timers[i](true);
|
||||
timers.splice(i, 1);
|
||||
}
|
||||
});
|
||||
|
||||
// start the next in the queue if the last step wasn't forced
|
||||
if (!gotoEnd)
|
||||
this.dequeue();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Generate shortcuts for custom animations
|
||||
jQuery.each({
|
||||
slideDown: genFx("show", 1),
|
||||
slideUp: genFx("hide", 1),
|
||||
slideToggle: genFx("toggle", 1),
|
||||
fadeIn: { opacity: "show" },
|
||||
fadeOut: { opacity: "hide" }
|
||||
}, function( name, props ){
|
||||
jQuery.fn[ name ] = function( speed, callback ){
|
||||
return this.animate( props, speed, callback );
|
||||
};
|
||||
});
|
||||
|
||||
jQuery.extend({
|
||||
|
||||
speed: function(speed, easing, fn) {
|
||||
var opt = typeof speed === "object" ? speed : {
|
||||
complete: fn || !fn && easing ||
|
||||
jQuery.isFunction( speed ) && speed,
|
||||
duration: speed,
|
||||
easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
|
||||
};
|
||||
|
||||
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
|
||||
jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
|
||||
|
||||
// Queueing
|
||||
opt.old = opt.complete;
|
||||
opt.complete = function(){
|
||||
if ( opt.queue !== false )
|
||||
jQuery(this).dequeue();
|
||||
if ( jQuery.isFunction( opt.old ) )
|
||||
opt.old.call( this );
|
||||
};
|
||||
|
||||
return opt;
|
||||
},
|
||||
|
||||
easing: {
|
||||
linear: function( p, n, firstNum, diff ) {
|
||||
return firstNum + diff * p;
|
||||
},
|
||||
swing: function( p, n, firstNum, diff ) {
|
||||
return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
|
||||
}
|
||||
},
|
||||
|
||||
timers: [],
|
||||
|
||||
fx: function( elem, options, prop ){
|
||||
this.options = options;
|
||||
this.elem = elem;
|
||||
this.prop = prop;
|
||||
|
||||
if ( !options.orig )
|
||||
options.orig = {};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jQuery.fx.prototype = {
|
||||
|
||||
// Simple function for setting a style value
|
||||
update: function(){
|
||||
if ( this.options.step )
|
||||
this.options.step.call( this.elem, this.now, this );
|
||||
|
||||
(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
|
||||
|
||||
// Set display property to block for height/width animations
|
||||
if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
|
||||
this.elem.style.display = "block";
|
||||
},
|
||||
|
||||
// Get the current size
|
||||
cur: function(force){
|
||||
if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
|
||||
return this.elem[ this.prop ];
|
||||
|
||||
var r = parseFloat(jQuery.css(this.elem, this.prop, force));
|
||||
return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
|
||||
},
|
||||
|
||||
// Start an animation from one number to another
|
||||
custom: function(from, to, unit){
|
||||
this.startTime = now();
|
||||
this.start = from;
|
||||
this.end = to;
|
||||
this.unit = unit || this.unit || "px";
|
||||
this.now = this.start;
|
||||
this.pos = this.state = 0;
|
||||
|
||||
var self = this;
|
||||
function t(gotoEnd){
|
||||
return self.step(gotoEnd);
|
||||
}
|
||||
|
||||
t.elem = this.elem;
|
||||
|
||||
if ( t() && jQuery.timers.push(t) && !timerId ) {
|
||||
timerId = setInterval(function(){
|
||||
var timers = jQuery.timers;
|
||||
|
||||
for ( var i = 0; i < timers.length; i++ )
|
||||
if ( !timers[i]() )
|
||||
timers.splice(i--, 1);
|
||||
|
||||
if ( !timers.length ) {
|
||||
clearInterval( timerId );
|
||||
timerId = undefined;
|
||||
}
|
||||
}, 13);
|
||||
}
|
||||
},
|
||||
|
||||
// Simple 'show' function
|
||||
show: function(){
|
||||
// Remember where we started, so that we can go back to it later
|
||||
this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
|
||||
this.options.show = true;
|
||||
|
||||
// Begin the animation
|
||||
// Make sure that we start at a small width/height to avoid any
|
||||
// flash of content
|
||||
this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
|
||||
|
||||
// Start by showing the element
|
||||
jQuery(this.elem).show();
|
||||
},
|
||||
|
||||
// Simple 'hide' function
|
||||
hide: function(){
|
||||
// Remember where we started, so that we can go back to it later
|
||||
this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
|
||||
this.options.hide = true;
|
||||
|
||||
// Begin the animation
|
||||
this.custom(this.cur(), 0);
|
||||
},
|
||||
|
||||
// Each step of an animation
|
||||
step: function(gotoEnd){
|
||||
var t = now();
|
||||
|
||||
if ( gotoEnd || t >= this.options.duration + this.startTime ) {
|
||||
this.now = this.end;
|
||||
this.pos = this.state = 1;
|
||||
this.update();
|
||||
|
||||
this.options.curAnim[ this.prop ] = true;
|
||||
|
||||
var done = true;
|
||||
for ( var i in this.options.curAnim )
|
||||
if ( this.options.curAnim[i] !== true )
|
||||
done = false;
|
||||
|
||||
if ( done ) {
|
||||
if ( this.options.display != null ) {
|
||||
// Reset the overflow
|
||||
this.elem.style.overflow = this.options.overflow;
|
||||
|
||||
// Reset the display
|
||||
this.elem.style.display = this.options.display;
|
||||
if ( jQuery.css(this.elem, "display") == "none" )
|
||||
this.elem.style.display = "block";
|
||||
}
|
||||
|
||||
// Hide the element if the "hide" operation was done
|
||||
if ( this.options.hide )
|
||||
jQuery(this.elem).hide();
|
||||
|
||||
// Reset the properties, if the item has been hidden or shown
|
||||
if ( this.options.hide || this.options.show )
|
||||
for ( var p in this.options.curAnim )
|
||||
jQuery.attr(this.elem.style, p, this.options.orig[p]);
|
||||
|
||||
// Execute the complete function
|
||||
this.options.complete.call( this.elem );
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
var n = t - this.startTime;
|
||||
this.state = n / this.options.duration;
|
||||
|
||||
// Perform the easing function, defaults to swing
|
||||
this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
|
||||
this.now = this.start + ((this.end - this.start) * this.pos);
|
||||
|
||||
// Perform the next step of the animation
|
||||
this.update();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
jQuery.extend( jQuery.fx, {
|
||||
speeds:{
|
||||
slow: 600,
|
||||
fast: 200,
|
||||
// Default speed
|
||||
_default: 400
|
||||
},
|
||||
step: {
|
||||
|
||||
opacity: function(fx){
|
||||
jQuery.attr(fx.elem.style, "opacity", fx.now);
|
||||
},
|
||||
|
||||
_default: function(fx){
|
||||
if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
|
||||
fx.elem.style[ fx.prop ] = fx.now + fx.unit;
|
||||
else
|
||||
fx.elem[ fx.prop ] = fx.now;
|
||||
}
|
||||
}
|
||||
});
|
||||
if ( document.documentElement["getBoundingClientRect"] )
|
||||
jQuery.fn.offset = function() {
|
||||
if ( !this[0] ) return { top: 0, left: 0 };
|
||||
if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
|
||||
var box = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
|
||||
clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
|
||||
top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
|
||||
left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
|
||||
return { top: top, left: left };
|
||||
};
|
||||
else
|
||||
jQuery.fn.offset = function() {
|
||||
if ( !this[0] ) return { top: 0, left: 0 };
|
||||
if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
|
||||
jQuery.offset.initialized || jQuery.offset.initialize();
|
||||
|
||||
var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
|
||||
doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
|
||||
body = doc.body, defaultView = doc.defaultView,
|
||||
prevComputedStyle = defaultView.getComputedStyle(elem, null),
|
||||
top = elem.offsetTop, left = elem.offsetLeft;
|
||||
|
||||
while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
|
||||
computedStyle = defaultView.getComputedStyle(elem, null);
|
||||
top -= elem.scrollTop, left -= elem.scrollLeft;
|
||||
if ( elem === offsetParent ) {
|
||||
top += elem.offsetTop, left += elem.offsetLeft;
|
||||
if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
|
||||
top += parseInt( computedStyle.borderTopWidth, 10) || 0,
|
||||
left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
|
||||
prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
|
||||
}
|
||||
if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
|
||||
top += parseInt( computedStyle.borderTopWidth, 10) || 0,
|
||||
left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
|
||||
prevComputedStyle = computedStyle;
|
||||
}
|
||||
|
||||
if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
|
||||
top += body.offsetTop,
|
||||
left += body.offsetLeft;
|
||||
|
||||
if ( prevComputedStyle.position === "fixed" )
|
||||
top += Math.max(docElem.scrollTop, body.scrollTop),
|
||||
left += Math.max(docElem.scrollLeft, body.scrollLeft);
|
||||
|
||||
return { top: top, left: left };
|
||||
};
|
||||
|
||||
jQuery.offset = {
|
||||
initialize: function() {
|
||||
if ( this.initialized ) return;
|
||||
var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
|
||||
html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
|
||||
|
||||
rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
|
||||
for ( prop in rules ) container.style[prop] = rules[prop];
|
||||
|
||||
container.innerHTML = html;
|
||||
body.insertBefore(container, body.firstChild);
|
||||
innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
|
||||
|
||||
this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
|
||||
this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
|
||||
|
||||
innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
|
||||
this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
|
||||
|
||||
body.style.marginTop = '1px';
|
||||
this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
|
||||
body.style.marginTop = bodyMarginTop;
|
||||
|
||||
body.removeChild(container);
|
||||
this.initialized = true;
|
||||
},
|
||||
|
||||
bodyOffset: function(body) {
|
||||
jQuery.offset.initialized || jQuery.offset.initialize();
|
||||
var top = body.offsetTop, left = body.offsetLeft;
|
||||
if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
|
||||
top += parseInt( jQuery.curCSS(body, 'marginTop', true), 10 ) || 0,
|
||||
left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
|
||||
return { top: top, left: left };
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
jQuery.fn.extend({
|
||||
position: function() {
|
||||
var left = 0, top = 0, results;
|
||||
|
||||
if ( this[0] ) {
|
||||
// Get *real* offsetParent
|
||||
var offsetParent = this.offsetParent(),
|
||||
|
||||
// Get correct offsets
|
||||
offset = this.offset(),
|
||||
parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
|
||||
|
||||
// Subtract element margins
|
||||
// note: when an element has margin: auto the offsetLeft and marginLeft
|
||||
// are the same in Safari causing offset.left to incorrectly be 0
|
||||
offset.top -= num( this, 'marginTop' );
|
||||
offset.left -= num( this, 'marginLeft' );
|
||||
|
||||
// Add offsetParent borders
|
||||
parentOffset.top += num( offsetParent, 'borderTopWidth' );
|
||||
parentOffset.left += num( offsetParent, 'borderLeftWidth' );
|
||||
|
||||
// Subtract the two offsets
|
||||
results = {
|
||||
top: offset.top - parentOffset.top,
|
||||
left: offset.left - parentOffset.left
|
||||
};
|
||||
}
|
||||
|
||||
return results;
|
||||
},
|
||||
|
||||
offsetParent: function() {
|
||||
var offsetParent = this[0].offsetParent || document.body;
|
||||
while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
|
||||
offsetParent = offsetParent.offsetParent;
|
||||
return jQuery(offsetParent);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Create scrollLeft and scrollTop methods
|
||||
jQuery.each( ['Left', 'Top'], function(i, name) {
|
||||
var method = 'scroll' + name;
|
||||
|
||||
jQuery.fn[ method ] = function(val) {
|
||||
if (!this[0]) return null;
|
||||
|
||||
return val !== undefined ?
|
||||
|
||||
// Set the scroll offset
|
||||
this.each(function() {
|
||||
this == window || this == document ?
|
||||
window.scrollTo(
|
||||
!i ? val : jQuery(window).scrollLeft(),
|
||||
i ? val : jQuery(window).scrollTop()
|
||||
) :
|
||||
this[ method ] = val;
|
||||
}) :
|
||||
|
||||
// Return the scroll offset
|
||||
this[0] == window || this[0] == document ?
|
||||
self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
|
||||
jQuery.boxModel && document.documentElement[ method ] ||
|
||||
document.body[ method ] :
|
||||
this[0][ method ];
|
||||
};
|
||||
});
|
||||
// Create innerHeight, innerWidth, outerHeight and outerWidth methods
|
||||
jQuery.each([ "Height", "Width" ], function(i, name){
|
||||
|
||||
var tl = i ? "Left" : "Top", // top or left
|
||||
br = i ? "Right" : "Bottom", // bottom or right
|
||||
lower = name.toLowerCase();
|
||||
|
||||
// innerHeight and innerWidth
|
||||
jQuery.fn["inner" + name] = function(){
|
||||
return this[0] ?
|
||||
jQuery.css( this[0], lower, false, "padding" ) :
|
||||
null;
|
||||
};
|
||||
|
||||
// outerHeight and outerWidth
|
||||
jQuery.fn["outer" + name] = function(margin) {
|
||||
return this[0] ?
|
||||
jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
|
||||
null;
|
||||
};
|
||||
|
||||
var type = name.toLowerCase();
|
||||
|
||||
jQuery.fn[ type ] = function( size ) {
|
||||
// Get window width or height
|
||||
return this[0] == window ?
|
||||
// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
|
||||
document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
|
||||
document.body[ "client" + name ] :
|
||||
|
||||
// Get document width or height
|
||||
this[0] == document ?
|
||||
// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
|
||||
Math.max(
|
||||
document.documentElement["client" + name],
|
||||
document.body["scroll" + name], document.documentElement["scroll" + name],
|
||||
document.body["offset" + name], document.documentElement["offset" + name]
|
||||
) :
|
||||
|
||||
// Get or set width or height on the element
|
||||
size === undefined ?
|
||||
// Get width or height on the element
|
||||
(this.length ? jQuery.css( this[0], type ) : null) :
|
||||
|
||||
// Set the width or height on the element (default to pixels if value is unitless)
|
||||
this.css( type, typeof size === "string" ? size : size + "px" );
|
||||
};
|
||||
|
||||
});
|
||||
})();
|
75
thirdparty/jquery-concrete/vendor/jquery.selector/jquery.class.js
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Very basic Class utility. Based on base and jquery.class.
|
||||
*
|
||||
* Class definition: var Foo = Base.extend({ init: function(){ Constructor }; method_name: function(){ Method } });
|
||||
*
|
||||
* Inheritance: var Bar = Foo.extend({ method_name: function(){ this._super(); } });
|
||||
*
|
||||
* new-less Constructor: new Foo(arg) <-same as-> Foo(arg)
|
||||
*/
|
||||
|
||||
var Base;
|
||||
|
||||
(function(){
|
||||
|
||||
var marker = {}, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
||||
|
||||
// The base Class implementation (does nothing)
|
||||
Base = function(){};
|
||||
|
||||
Base.addMethod = function(name, func) {
|
||||
var _super = this._super;
|
||||
if (_super && fnTest.test(func)) {
|
||||
this.prototype[name] = function(){
|
||||
var tmp = this._super;
|
||||
this._super = _super[name];
|
||||
try {
|
||||
var ret = func.apply(this, arguments);
|
||||
}
|
||||
finally {
|
||||
this._super = tmp;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else this.prototype[name] = func;
|
||||
}
|
||||
|
||||
Base.addMethods = function(props) {
|
||||
for (var name in props) {
|
||||
if (typeof props[name] == 'function') this.addMethod(name, props[name]);
|
||||
else this.prototype[name] = props[name];
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new Class that inherits from this class
|
||||
Base.extend = function(props) {
|
||||
|
||||
// The dummy class constructor
|
||||
var Kls = function() {
|
||||
if (arguments[0] === marker) return;
|
||||
|
||||
if (this instanceof Kls) {
|
||||
if (this.init) this.init.apply(this, arguments);
|
||||
}
|
||||
else {
|
||||
var ret = new Kls(marker); if (ret.init) ret.init.apply(ret, arguments); return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the common class variables and methods
|
||||
Kls.constructor = Kls;
|
||||
Kls.extend = Base.extend;
|
||||
Kls.addMethod = Base.addMethod;
|
||||
Kls.addMethods = Base.addMethods;
|
||||
Kls._super = this.prototype;
|
||||
|
||||
// Attach the parent object to the inheritance chain
|
||||
Kls.prototype = new this(marker);
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
Kls.addMethods(props);
|
||||
|
||||
return Kls;
|
||||
};
|
||||
})();
|
188
thirdparty/jquery-concrete/vendor/jquery.selector/jquery.selector.js
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
(function($){
|
||||
|
||||
var tokens = {
|
||||
UNICODE: /\\[0-9a-f]{1,6}(?:\r\n|[ \n\r\t\f])?/,
|
||||
ESCAPE: /(?:UNICODE)|\\[^\n\r\f0-9a-f]/,
|
||||
NONASCII: /[^\x00-\x7F]/,
|
||||
NMSTART: /[_a-z]|(?:NONASCII)|(?:ESCAPE)/,
|
||||
NMCHAR: /[_a-z0-9-]|(?:NONASCII)|(?:ESCAPE)/,
|
||||
IDENT: /-?(?:NMSTART)(?:NMCHAR)*/,
|
||||
|
||||
NL: /\n|\r\n|\r|\f/,
|
||||
|
||||
STRING: /(?:STRING1)|(?:STRING2)|(?:STRINGBARE)/,
|
||||
STRING1: /"(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\"])*"/,
|
||||
STRING2: /'(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\'])*'/,
|
||||
STRINGBARE: /(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\]])*/,
|
||||
|
||||
FUNCTION: /(?:IDENT)\(\)/,
|
||||
|
||||
INTEGER: /[0-9]+/,
|
||||
|
||||
WITHN: /([-+])?(INTEGER)?(n)\s*(?:([-+])\s*(INTEGER))?/,
|
||||
WITHOUTN: /([-+])?(INTEGER)/
|
||||
}
|
||||
|
||||
var rx = {
|
||||
not: /:not\(/,
|
||||
not_end: /\)/,
|
||||
|
||||
tag: /((?:IDENT)|\*)/,
|
||||
id: /#(IDENT)/,
|
||||
cls: /\.(IDENT)/,
|
||||
attr: /\[\s*(IDENT)\s*(?:([^=]?=)\s*(STRING)\s*)?\]/,
|
||||
pseudo_el: /(?::(first-line|first-letter|before|after))|(?:::((?:FUNCTION)|(?:IDENT)))/,
|
||||
pseudo_cls_nth: /:nth-child\(\s*(?:(?:WITHN)|(?:WITHOUTN)|(odd|even))\s*\)/,
|
||||
pseudo_cls: /:(IDENT)/,
|
||||
|
||||
comb: /\s*(\+|~|>)\s*|\s+/,
|
||||
comma: /\s*,\s*/,
|
||||
important: /\s+!important\s*$/
|
||||
}
|
||||
|
||||
/* Replace placeholders with actual regex, and mark all as case insensitive */
|
||||
var token = /[A-Z][A-Z0-9]+/;
|
||||
for (var k in rx) {
|
||||
var src = rx[k].source;
|
||||
while (m = src.match(token)) src = src.replace(m[0], tokens[m[0]].source);
|
||||
rx[k] = new RegExp(src, 'gi');
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that matches itself against regexii, and keeps track of how much of itself has been matched
|
||||
*/
|
||||
var ConsumableString = Base.extend({
|
||||
init: function(str) {
|
||||
this.str = str;
|
||||
this.pos = 0;
|
||||
},
|
||||
match: function(rx) {
|
||||
var m;
|
||||
rx.lastIndex = this.pos;
|
||||
if ((m = rx.exec(this.str)) && m.index == this.pos ) {
|
||||
this.pos = rx.lastIndex ? rx.lastIndex : this.str.length ;
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
peek: function(rx) {
|
||||
var m;
|
||||
rx.lastIndex = this.pos;
|
||||
if ((m = rx.exec(this.str)) && m.index == this.pos ) return m;
|
||||
return null;
|
||||
},
|
||||
showpos: function() {
|
||||
return this.str.slice(0,this.pos)+'<HERE>' + this.str.slice(this.pos);
|
||||
},
|
||||
done: function() {
|
||||
return this.pos == this.str.length;
|
||||
}
|
||||
})
|
||||
|
||||
/* A base class that all Selectors inherit off */
|
||||
var SelectorBase = Base.extend({});
|
||||
|
||||
/**
|
||||
* A class representing a Simple Selector, as per the CSS3 selector spec
|
||||
*/
|
||||
var SimpleSelector = SelectorBase.extend({
|
||||
init: function() {
|
||||
this.tag = null;
|
||||
this.id = null;
|
||||
this.classes = [];
|
||||
this.attrs = [];
|
||||
this.nots = [];
|
||||
this.pseudo_classes = [];
|
||||
this.pseudo_els = [];
|
||||
},
|
||||
parse: function(selector) {
|
||||
var m;
|
||||
|
||||
/* Pull out the initial tag first, if there is one */
|
||||
if (m = selector.match(rx.tag)) this.tag = m[1];
|
||||
|
||||
/* Then for each selection type, try and find a match */
|
||||
do {
|
||||
if (m = selector.match(rx.not)) {
|
||||
this.nots[this.nots.length] = SelectorsGroup().parse(selector)
|
||||
if (!(m = selector.match(rx.not_end))) {
|
||||
throw 'Invalid :not term in selector';
|
||||
}
|
||||
}
|
||||
else if (m = selector.match(rx.id)) this.id = m[1];
|
||||
else if (m = selector.match(rx.cls)) this.classes[this.classes.length] = m[1];
|
||||
else if (m = selector.match(rx.attr)) this.attrs[this.attrs.length] = [ m[1], m[2], m[3] ];
|
||||
else if (m = selector.match(rx.pseudo_el)) this.pseudo_els[this.pseudo_els.length] = m[1] || m[2];
|
||||
else if (m = selector.match(rx.pseudo_cls_nth)) {
|
||||
if (m[3]) {
|
||||
var a = parseInt((m[1]||'')+(m[2]||'1'));
|
||||
var b = parseInt((m[4]||'')+(m[5]||'0'));
|
||||
}
|
||||
else {
|
||||
var a = m[8] ? 2 : 0;
|
||||
var b = m[8] ? (4-m[8].length) : parseInt((m[6]||'')+m[7]);
|
||||
}
|
||||
this.pseudo_classes[this.pseudo_classes.length] = ['nth-child', [a, b]];
|
||||
}
|
||||
else if (m = selector.match(rx.pseudo_cls)) this.pseudo_classes[this.pseudo_classes.length] = [m[1]];
|
||||
|
||||
} while(m && !selector.done());
|
||||
|
||||
return this;
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* A class representing a Selector, as per the CSS3 selector spec
|
||||
*/
|
||||
var Selector = SelectorBase.extend({
|
||||
init: function(){
|
||||
this.parts = [];
|
||||
},
|
||||
parse: function(cons){
|
||||
this.parts[this.parts.length] = SimpleSelector().parse(cons);
|
||||
|
||||
while (!cons.done() && !cons.peek(rx.comma) && (m = cons.match(rx.comb))) {
|
||||
this.parts[this.parts.length] = m[1] || ' ';
|
||||
this.parts[this.parts.length] = SimpleSelector().parse(cons);
|
||||
}
|
||||
|
||||
return this.parts.length == 1 ? this.parts[0] : this;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A class representing a sequence of selectors, as per the CSS3 selector spec
|
||||
*/
|
||||
var SelectorsGroup = SelectorBase.extend({
|
||||
init: function(){
|
||||
this.parts = [];
|
||||
},
|
||||
parse: function(cons){
|
||||
this.parts[this.parts.length] = Selector().parse(cons);
|
||||
|
||||
while (!cons.done() && (m = cons.match(rx.comma))) {
|
||||
this.parts[this.parts.length] = Selector().parse(cons);
|
||||
}
|
||||
|
||||
return this.parts.length == 1 ? this.parts[0] : this;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$.selector = function(s){
|
||||
var cons = ConsumableString(s);
|
||||
var res = SelectorsGroup().parse(cons);
|
||||
|
||||
res.selector = s;
|
||||
|
||||
if (!cons.done()) throw 'Could not parse selector - ' + cons.showpos() ;
|
||||
else return res;
|
||||
}
|
||||
|
||||
$.selector.SelectorBase = SelectorBase;
|
||||
$.selector.SimpleSelector = SimpleSelector;
|
||||
$.selector.Selector = Selector;
|
||||
$.selector.SelectorsGroup = SelectorsGroup;
|
||||
|
||||
})(jQuery)
|
353
thirdparty/jquery-concrete/vendor/jquery.selector/jquery.selector.matches.js
vendored
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
This attempts to do the opposite of Sizzle.
|
||||
Sizzle is good for finding elements for a selector, but not so good for telling if an individual element matches a selector
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
/**** CAPABILITY TESTS ****/
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = '<form id="test"><input name="id" type="text"/></form>';
|
||||
|
||||
// In IE 6-7, getAttribute often does the wrong thing (returns similar to el.attr), so we need to use getAttributeNode on that browser
|
||||
var getAttributeDodgy = div.firstChild.getAttribute('id') !== 'test';
|
||||
|
||||
// Does browser support Element.firstElementChild, Element.previousElementSibling, etc.
|
||||
var hasElementTraversal = div.firstElementChild && div.firstElementChild.tagName == 'FORM';
|
||||
|
||||
// Does browser support Element.children
|
||||
var hasChildren = div.children && div.children[0].tagName == 'FORM';
|
||||
|
||||
var FUNC_IN = /^\s*function\s*\([^)]*\)\s*{/;
|
||||
var FUNC_OUT = /}\s*$/;
|
||||
|
||||
var funcToString = function(f) {
|
||||
return (''+f).replace(FUNC_IN,'').replace(FUNC_OUT,'');
|
||||
}
|
||||
|
||||
// Can we use Function#toString ?
|
||||
try {
|
||||
var testFunc = function(){ return 'good' };
|
||||
if ((new Function('',funcToString(testFunc)))() != 'good') funcToString = false;
|
||||
}
|
||||
catch(e) { funcToString = false; console.log(e.message);/*pass*/ }
|
||||
|
||||
/**** INTRO ****/
|
||||
|
||||
var GOOD = /GOOD/g;
|
||||
var BAD = /BAD/g;
|
||||
|
||||
var STARTS_WITH_QUOTES = /^['"]/g;
|
||||
|
||||
var join = function(js) {
|
||||
return js.join('\n');
|
||||
}
|
||||
|
||||
var join_complex = function(js) {
|
||||
code = new String(js.join('\n')); // String objects can have properties set. strings can't
|
||||
code.complex = true;
|
||||
return code;
|
||||
}
|
||||
|
||||
/**** ATTRIBUTE ACCESSORS ****/
|
||||
|
||||
var getAttr;
|
||||
|
||||
// Good browsers
|
||||
if (!getAttributeDodgy) {
|
||||
getAttr = function(attr){ return 'var _'+attr+' = el.getAttribute("'+attr+'");' ; }
|
||||
}
|
||||
// IE 6, 7
|
||||
else {
|
||||
// On IE 6 + 7, getAttribute still has to be called with DOM property mirror name, not attribute name. Map attributes to those names
|
||||
var getAttrIEMap = { 'class': 'className', 'for': 'htmlFor' };
|
||||
|
||||
getAttr = function(attr) {
|
||||
var ieattr = getAttrIEMap[attr] || attr;
|
||||
return 'var _'+attr+' = el.getAttribute("'+ieattr+'",2) || (el.getAttributeNode("'+attr+'")||{}).nodeValue;';
|
||||
}
|
||||
}
|
||||
|
||||
/**** ATTRIBUTE COMPARITORS ****/
|
||||
|
||||
var attrchecks = {
|
||||
'-': '!_K',
|
||||
'=': '_K != "V"',
|
||||
'!=': '_K == "V"',
|
||||
'~=': '__K.indexOf(" V ") == -1',
|
||||
'^=': '!_K || _K.indexOf("V") != 0',
|
||||
'*=': '!_K || _K.indexOf("V") == -1',
|
||||
'$=': '!_K || _K.substr(_K.length-"V".length) != "V"'
|
||||
}
|
||||
|
||||
/**** STATE TRACKER ****/
|
||||
|
||||
var State = $.selector.State = Base.extend({
|
||||
init: function(){
|
||||
this.reset();
|
||||
},
|
||||
reset: function() {
|
||||
this.attrs = {}; this.wsattrs = {};
|
||||
},
|
||||
|
||||
prev: function(){
|
||||
this.reset();
|
||||
if (hasElementTraversal) return 'el = el.previousElementSibling';
|
||||
return 'while((el = el.previousSibling) && el.nodeType != 1) {}';
|
||||
},
|
||||
next: function() {
|
||||
this.reset();
|
||||
if (hasElementTraversal) return 'el = el.nextElementSibling';
|
||||
return 'while((el = el.nextSibling) && el.nodeType != 1) {}';
|
||||
},
|
||||
prevLoop: function(body){
|
||||
this.reset();
|
||||
if (hasElementTraversal) return join([ 'while(el = el.previousElementSibling){', body]);
|
||||
return join([
|
||||
'while(el = el.previousSibling){',
|
||||
'if (el.nodeType != 1) continue;',
|
||||
body,
|
||||
]);
|
||||
},
|
||||
parent: function() {
|
||||
this.reset();
|
||||
return 'el = el.parentNode;';
|
||||
},
|
||||
parentLoop: function(body) {
|
||||
this.reset();
|
||||
return join([
|
||||
'while((el = el.parentNode) && el.nodeType == 1){',
|
||||
body,
|
||||
'}'
|
||||
]);
|
||||
},
|
||||
|
||||
uses_attr: function(attr) {
|
||||
if (this.attrs[attr]) return;
|
||||
this.attrs[attr] = true;
|
||||
return getAttr(attr);
|
||||
},
|
||||
uses_wsattr: function(attr) {
|
||||
if (this.wsattrs[attr]) return;
|
||||
this.wsattrs[attr] = true;
|
||||
return join([this.uses_attr(attr), 'var __'+attr+' = " "+_'+attr+'+" ";']);
|
||||
},
|
||||
|
||||
save: function(lbl) {
|
||||
return 'var el'+lbl+' = el;';
|
||||
},
|
||||
restore: function(lbl) {
|
||||
this.reset();
|
||||
return 'el = el'+lbl+';';
|
||||
}
|
||||
});
|
||||
|
||||
/**** PSEUDO-CLASS DETAILS ****/
|
||||
|
||||
var pseudoclschecks = {
|
||||
'first-child': join([
|
||||
'var cel = el;',
|
||||
'while(cel = cel.previousSibling){ if (cel.nodeType === 1) BAD; }',
|
||||
]),
|
||||
'last-child': join([
|
||||
'var cel = el;',
|
||||
'while(cel = cel.nextSibling){ if (cel.nodeType === 1) BAD; }'
|
||||
]),
|
||||
'nth-child': function(a,b) {
|
||||
var get_i = join([
|
||||
'var i = 1, cel = el;',
|
||||
'while(cel = cel.previousSibling){',
|
||||
'if (cel.nodeType === 1) i++;',
|
||||
'}',
|
||||
]);
|
||||
|
||||
if (a == 0) return join([
|
||||
get_i,
|
||||
'if (i- '+b+' != 0) BAD;'
|
||||
]);
|
||||
else if (b == 0 && a >= 0) return join([
|
||||
get_i,
|
||||
'if (i%'+a+' != 0 || i/'+a+' < 0) BAD;'
|
||||
]);
|
||||
else if (b == 0 && a < 0) return join([
|
||||
'BAD;'
|
||||
]);
|
||||
else return join([
|
||||
get_i,
|
||||
'if ((i- '+b+')%'+a+' != 0 || (i- '+b+')/'+a+' < 0) BAD;'
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
// Needs to refence contents of object, so must be injected after definition
|
||||
pseudoclschecks['only-child'] = join([
|
||||
pseudoclschecks['first-child'],
|
||||
pseudoclschecks['last-child']
|
||||
]);
|
||||
|
||||
/**** SimpleSelector ****/
|
||||
|
||||
$.selector.SimpleSelector.addMethod('compile', function(el) {
|
||||
var js = [];
|
||||
|
||||
/* Check against element name */
|
||||
if (this.tag && this.tag != '*') {
|
||||
js[js.length] = 'if (el.tagName != "'+this.tag.toUpperCase()+'") BAD;';
|
||||
}
|
||||
|
||||
/* Check against ID */
|
||||
if (this.id) {
|
||||
js[js.length] = el.uses_attr('id');
|
||||
js[js.length] = 'if (_id !== "'+this.id+'") BAD;';
|
||||
}
|
||||
|
||||
/* Build className checking variable */
|
||||
if (this.classes.length) {
|
||||
js[js.length] = el.uses_wsattr('class');
|
||||
|
||||
/* Check against class names */
|
||||
$.each(this.classes, function(i, cls){
|
||||
js[js.length] = 'if (__class.indexOf(" '+cls+' ") == -1) BAD;';
|
||||
})
|
||||
}
|
||||
|
||||
/* Check against attributes */
|
||||
$.each(this.attrs, function(i, attr){
|
||||
js[js.length] = (attr[1] == '~=') ? el.uses_wsattr(attr[0]) : el.uses_attr(attr[0]);
|
||||
var check = attrchecks[ attr[1] || '-' ];
|
||||
check = check.replace( /K/g, attr[0]).replace( /V/g, attr[2] && attr[2].match(STARTS_WITH_QUOTES) ? attr[2].slice(1,-1) : attr[2] );
|
||||
js[js.length] = 'if ('+check+') BAD;';
|
||||
});
|
||||
|
||||
/* Check against nots */
|
||||
$.each(this.nots, function(i, not){
|
||||
var lbl = ++lbl_id;
|
||||
var func = join([
|
||||
'l'+lbl+':{',
|
||||
not.compile(el).replace(BAD, 'break l'+lbl).replace(GOOD, 'BAD'),
|
||||
'}'
|
||||
]);
|
||||
|
||||
if (!(not instanceof $.selector.SimpleSelector)) func = join([
|
||||
el.save(lbl),
|
||||
func,
|
||||
el.restore(lbl)
|
||||
])
|
||||
|
||||
js[js.length] = func;
|
||||
});
|
||||
|
||||
/* Check against pseudo-classes */
|
||||
$.each(this.pseudo_classes, function(i, pscls){
|
||||
var check = pseudoclschecks[pscls[0]];
|
||||
if (check) {
|
||||
js[js.length] = ( typeof check == 'function' ? check.apply(this, pscls[1]) : check );
|
||||
}
|
||||
else if (check = $.find.selectors.filters[pscls[0]]) {
|
||||
if (funcToString) {
|
||||
js[js.length] = funcToString(check).replace(/elem/g,'el').replace(/return([^;]+);/,'if (!($1)) BAD;');
|
||||
}
|
||||
else {
|
||||
js[js.length] = 'if (!$.find.selectors.filters.'+pscls[0]+'(el)) BAD;'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
js[js.length] = 'GOOD';
|
||||
|
||||
/* Pass */
|
||||
return join(js);
|
||||
});
|
||||
|
||||
var lbl_id = 0;
|
||||
/** Turns an compiled fragment into the first part of a combination */
|
||||
function as_subexpr(f) {
|
||||
if (f.complex)
|
||||
return join([
|
||||
'l'+(++lbl_id)+':{',
|
||||
f.replace(GOOD, 'break l'+lbl_id),
|
||||
'}',
|
||||
]);
|
||||
else
|
||||
return f.replace(GOOD, '');
|
||||
}
|
||||
|
||||
var combines = {
|
||||
' ': function(el, f1, f2) {
|
||||
return join_complex([
|
||||
f2,
|
||||
'while(true){',
|
||||
el.parent(),
|
||||
'if (!el || el.nodeType !== 1) BAD;',
|
||||
f1.compile(el).replace(BAD, 'continue'),
|
||||
'}'
|
||||
]);
|
||||
},
|
||||
|
||||
'>': function(el, f1, f2) {
|
||||
return join([
|
||||
f2,
|
||||
el.parent(),
|
||||
'if (!el || el.nodeType !== 1) BAD;',
|
||||
f1.compile(el)
|
||||
]);
|
||||
},
|
||||
|
||||
'~': function(el, f1, f2) {
|
||||
return join_complex([
|
||||
f2,
|
||||
el.prevLoop(),
|
||||
f1.compile(el).replace(BAD, 'continue'),
|
||||
'}',
|
||||
'BAD;'
|
||||
]);
|
||||
},
|
||||
|
||||
'+': function(el, f1, f2) {
|
||||
return join([
|
||||
f2,
|
||||
el.prev(),
|
||||
'if (!el) BAD;',
|
||||
f1.compile(el)
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
$.selector.Selector.addMethod('compile', function(el) {
|
||||
l = this.parts.length;
|
||||
|
||||
expr = this.parts[--l].compile(el);
|
||||
while (l) {
|
||||
combinator = this.parts[--l];
|
||||
expr = combines[combinator](el, this.parts[--l], as_subexpr(expr));
|
||||
}
|
||||
|
||||
return expr;
|
||||
});
|
||||
|
||||
$.selector.SelectorsGroup.addMethod('compile', function(el) {
|
||||
var expr = [], lbl = ++lbl_id;
|
||||
|
||||
for (var i=0; i < this.parts.length; i++) {
|
||||
expr[expr.length] = join([
|
||||
i == 0 ? el.save(lbl) : el.restore(lbl),
|
||||
'l'+lbl+'_'+i+':{',
|
||||
this.parts[i].compile(el).replace(BAD, 'break l'+lbl+'_'+i),
|
||||
'}'
|
||||
]);
|
||||
}
|
||||
|
||||
expr[expr.length] = 'BAD;';
|
||||
return join(expr);
|
||||
});
|
||||
|
||||
$.selector.SelectorBase.addMethod('matches', function(el){
|
||||
this.matches = new Function('el', join([
|
||||
'if (!el) return false;',
|
||||
this.compile(new State()).replace(BAD, 'return false').replace(GOOD, 'return true')
|
||||
]));
|
||||
return this.matches(el);
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
42
thirdparty/jquery-concrete/vendor/jquery.selector/jquery.selector.specifity.js
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
(function($) {
|
||||
|
||||
$.selector.SimpleSelector.addMethod('specifity', function() {
|
||||
if (this.spec) return this.spec;
|
||||
|
||||
var spec = [
|
||||
this.id ? 1 : 0,
|
||||
this.classes.length + this.attrs.length + this.pseudo_classes.length,
|
||||
((this.tag && this.tag != '*') ? 1 : 0) + this.pseudo_els.length
|
||||
];
|
||||
$.each(this.nots, function(i,not){
|
||||
var ns = not.specifity(); spec[0] += ns[0]; spec[1] += ns[1]; spec[2] += ns[2];
|
||||
});
|
||||
|
||||
return this.spec = spec;
|
||||
})
|
||||
|
||||
$.selector.Selector.addMethod('specifity', function(){
|
||||
if (this.spec) return this.spec;
|
||||
|
||||
var spec = [0,0,0];
|
||||
$.each(this.parts, function(i,part){
|
||||
if (i%2) return;
|
||||
var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2];
|
||||
});
|
||||
|
||||
return this.spec = spec;
|
||||
})
|
||||
|
||||
$.selector.SelectorsGroup.addMethod('specifity', function(){
|
||||
if (this.spec) return this.spec;
|
||||
|
||||
var spec = [0,0,0];
|
||||
$.each(this.parts, function(i,part){
|
||||
var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2];
|
||||
});
|
||||
|
||||
return this.spec = spec;
|
||||
})
|
||||
|
||||
|
||||
})(jQuery);
|
8
thirdparty/jquery-concrete/vendor/jspec/.piston.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
format: 1
|
||||
lock: false
|
||||
repository_class: Piston::Git::Repository
|
||||
handler:
|
||||
commit: 75336bc94061b818f90361ff163436c8eb61d4c3
|
||||
branch: tags/2.8.4
|
||||
repository_url: git://github.com/visionmedia/jspec.git
|
473
thirdparty/jquery-concrete/vendor/jspec/History.rdoc
vendored
Normal file
@ -0,0 +1,473 @@
|
||||
|
||||
=== 2.8.4 / 2009-08-02
|
||||
|
||||
* Fixed error thrown when a module has no utilities
|
||||
|
||||
=== 2.8.3 / 2009-07-30
|
||||
|
||||
* Added JSpec.evalHook()
|
||||
* Added JSpec.paramsFor()
|
||||
* Refactored jspec.xhr.js
|
||||
* Fixed mock xhr HEAD method
|
||||
* Fixed node.js print() newline issue
|
||||
* Fixed specs preventing spec/spec.node.js from running
|
||||
|
||||
=== 2.8.2 / 2009-07-29
|
||||
|
||||
* Added JSpec.tryLoading()
|
||||
* Added JSpec.request used to reference the original XMLHttpRequest; used to fix [#149]
|
||||
* Fixed Mock XHR issue messing up JSpec request related utilities such as fixture() [#149]
|
||||
|
||||
=== 2.8.1 / 2009-07-27
|
||||
|
||||
* Added Lawrence Pit as a contributor
|
||||
* Fixed object hash equality [#146]
|
||||
{ a : '1', b : '2' } is now the same as:
|
||||
{ b : '2', a : '1' }
|
||||
|
||||
=== 2.8.0 / 2009-07-27
|
||||
|
||||
* Give readFile precendence over xhr so that fixtures work with mockRequest when using Rhino
|
||||
* Give XMLHttpRequest precedence over microsoft crap
|
||||
* Added Mock Ajax Support
|
||||
* Added mockRequest(), unmockRequest() utilities
|
||||
* Added jspec.xhr.js
|
||||
* Fixed be_visible, and be_hidden. Now implement the jQuery <= 1.3.1 method
|
||||
|
||||
=== 2.7.2 / 2009-07-24
|
||||
|
||||
* Fixed "end" in spec bodies when using the grammar
|
||||
* Fixed "it" in spec bodies when using the grammar [#142]
|
||||
* Changed; HTML entities in descriptions are now escaped for DOM formatter [#141]
|
||||
* Added enno84@gmx.net as a contributor (thanks for the bug reports)
|
||||
|
||||
=== 2.7.1 / 2009-07-17
|
||||
|
||||
* Changed; hash() now accepts null
|
||||
* Fixed should_receive issue with validating boolean args or return values
|
||||
* Fixed --server-only switch
|
||||
* Fixed jQuery dependency error message when jQuery is not available
|
||||
when using jspec.jquery.js
|
||||
|
||||
=== 2.7.0 / 2009-07-14
|
||||
|
||||
* Added fixture() utility function
|
||||
* Templates initialize with example paths to lib
|
||||
|
||||
=== 2.6.0 / 2009-07-09
|
||||
|
||||
* Added Ruby on Rails support
|
||||
* Added exporting of JSpec (node.js etc)
|
||||
* Added be_undefined matcher [#134]
|
||||
|
||||
=== 2.5.1 / 2009-07-07
|
||||
|
||||
* Added intermediate node.js support
|
||||
* Fixed; grammar now allows foo.bar.baz.stub() etc to convert to stub(foo.bar.baz)
|
||||
|
||||
=== 2.5.0 / 2009-07-03
|
||||
|
||||
* Added contrib in README (thanks to anyone who has helped)
|
||||
* Added more shared behavior specs
|
||||
* Added Module.DSLs support for extending / adding new DSLs (DSL exchange not yet fully implemented)
|
||||
* Added spec to make sure methods like end() will not fail due to the grammar
|
||||
* Changed; giving hook precedence to suite hooks (before_each, etc) over module hooks (beforeSuite, etc) ; (thanks mpd)
|
||||
* Changed; calls to stub() without and_return() now simply stub an arbitrary method with no return value
|
||||
* Changed JSpec.include(); now returns JSpec allowing chaining
|
||||
* Fixed having "end" in descriptions which would be replaced with '});'
|
||||
* Fixed negation of should.receive('foo') matcher
|
||||
* Fixed shared behavior assertion count issue
|
||||
|
||||
=== 2.4.3 / 2009-07-02
|
||||
|
||||
* Fixed matcher semicolon matcher issue when using the JSpec grammar
|
||||
* Added pass() util; Spec#pass() and Spec#fail() (thanks gisikw)
|
||||
* Removing Object.prototype.stubby() after specs are finished to prevent pollution
|
||||
|
||||
=== 2.4.2 / 2009-06-30
|
||||
|
||||
* Fixed trailing comma (thanks Kevin)
|
||||
|
||||
=== 2.4.1 / 2009-06-30
|
||||
|
||||
* Moved beforeSpec and afterSpec hook into proper positions
|
||||
allowing for additional assertions within afterSpec.
|
||||
|
||||
=== 2.4.0 / 2009-06-30
|
||||
|
||||
* Added hook() and hookImmutable()
|
||||
* Added support for matcher lists ('be enabled disabled selected') == be_enabled, be_disabled etc
|
||||
* Added JSpec.include()
|
||||
* Added several hooks
|
||||
* Added Module support
|
||||
* Added grammar conversion of Foo.stub('method') to stub(Foo, 'method')
|
||||
* Added grammar conversion of Foo.destub() to destub(Foo)
|
||||
* Require bind gem
|
||||
* Fixed `jspec` bin docs
|
||||
|
||||
=== 2.3.1 / 2009-06-25
|
||||
|
||||
* Fixed; all stubs generated with stub() are restored
|
||||
to their original methods after each 'it' block. See
|
||||
README for details.
|
||||
|
||||
=== 2.3.0 / 2009-06-25
|
||||
|
||||
* Added stub()
|
||||
* Added destub()
|
||||
* Changed; Server responses utilize Rack::Mime now for arbitrary requests
|
||||
|
||||
=== 2.2.1 / 2009-06-22
|
||||
|
||||
* Changed; reportToServer() now accepts url arg
|
||||
|
||||
* Fixed be_empty matcher; now considers {} empty, however { foo : bar } is not
|
||||
* Fixed throw_error error messages for Opera
|
||||
* Fixed throw_error in Rhino (Opera is broken now)
|
||||
* Fixed stray console.log() call
|
||||
|
||||
* Fixed some tab issues.
|
||||
When using the JSpec grammar option you should
|
||||
use the 'soft tabs' feature of your IDE or text editor.
|
||||
A patch for tabs is pending and should be available soon,
|
||||
however be aware that a 'parse error' may occur otherwise.
|
||||
|
||||
=== 2.2.0 / 2009-06-18
|
||||
|
||||
* Added link to JSpec in JSMag June 2009
|
||||
* Added Github gem source location to docs
|
||||
* Changed throw_error matcher; now accepts two arguments
|
||||
* Changed --server; serves from current working directory.
|
||||
This allows files in ../lib/* to be served rather than ./spec/* only.
|
||||
* Refactored argumentsToArray()
|
||||
|
||||
=== 2.1.0 / 2009-06-12
|
||||
|
||||
* Changed `jspec init` to utilize a single template
|
||||
which allows for all three suite running capabilities
|
||||
within a single template. Now after initializing a
|
||||
project you may `jspec run --server`, `jspec run --rhino`
|
||||
etc at any time without modifications.
|
||||
|
||||
=== 2.0.3 / 2009-05-15
|
||||
|
||||
* Table should span full width
|
||||
(Very week release I know, but improperly styled things bug me :) )
|
||||
|
||||
=== 2.0.2 / 2009-05-11
|
||||
|
||||
* Added rails integration link http://github.com/bhauman/jspec-rails
|
||||
* Changed; puts() now displays constructor name when available
|
||||
* Fixed Terminal output which was not displaying due to a recent commit
|
||||
* fixed IE bug : DOM elements don't have valueOf() method
|
||||
|
||||
=== 2.0.1 / 2009-05-01
|
||||
|
||||
* Added better failure messages for throw_error matcher
|
||||
* Renamed print() to puts() [#108]
|
||||
|
||||
=== 2.0.0 / 2009-04-27
|
||||
|
||||
* Added DOM loading indicator [#105]
|
||||
* Added wait() helper for additional async support
|
||||
* Added shared behavior support using should_behave_like('Another Suite')
|
||||
* Added CSS body toggling [#1]
|
||||
* Added receive matcher for Proxy Assertins
|
||||
* Added grammar-less support
|
||||
* Added an_instance_of() helper
|
||||
* Removed .this literal
|
||||
* Removed deprecated be_a_TYPE_input matchers
|
||||
|
||||
* Added ProxyAssertion
|
||||
* Added select() util
|
||||
* Added does() util for report-less assertions
|
||||
* Added find() util
|
||||
* Added JSpec.contentsOf()
|
||||
* Added matchers to body evaluation [#90]
|
||||
|
||||
=== 1.1.7 / 2009-04-22
|
||||
|
||||
* Removed trailing commas causing issues with IE (what a suprise ;) )
|
||||
|
||||
=== 1.1.6 / 2009-04-22
|
||||
|
||||
* Fixed typo in requires()
|
||||
* Added expect()
|
||||
|
||||
=== 1.1.5 / 2009-04-17
|
||||
|
||||
* Strengthened specs for cascading hooks
|
||||
* Fixed cascading hooks
|
||||
|
||||
=== 1.1.4 / 2009-04-17
|
||||
|
||||
* Added rhino and server template files
|
||||
* Added JSpec.hasXhr()
|
||||
* Added JSpec.xhr()
|
||||
* Added Ruby javascript testing server
|
||||
* Added support for options passed to run()
|
||||
* Added failuresOnly for Terminal formatter
|
||||
* Added terminal assertion graphs
|
||||
* Addec color() utility
|
||||
* Added main.puts() since we use print() as a utility
|
||||
* Added rhino support
|
||||
* Added fail() utility function
|
||||
* Added JSpec.Assertion
|
||||
* Added normalizeMatcherMessage()
|
||||
* Added normalizeMatcherBody()
|
||||
* Added have_classes [#19]
|
||||
* Added extend() utility
|
||||
* Added be_an_instance_of matcher
|
||||
* Added constructor checking support for throw_error matcher [#72]
|
||||
* Added file support for exception messages, making them much easier to debug
|
||||
* Added catching of exceptions throw within specs [#46]
|
||||
* Changed; executable aborts when template does not exist
|
||||
* Changed; matchers now normalized upon creation, accepts function, hash, or string.
|
||||
* Changed be() matcher to be strict [#57]
|
||||
* Changed error() to conditionally show line number when available
|
||||
* Renamed Jspec.addSuite to JSpec.describe and Suite#addSpec to Suite#it
|
||||
* Refactored be_a_TYPE_input matchers so that the deprication warning is logged only when calling the method
|
||||
* Fixed JSpec.requires() now works with latest version of JSpec.error()
|
||||
* Fixed error() now displays exceptions throw that do not respond to .message
|
||||
* Fixed commenting bug [#37]
|
||||
* Removed JSpec.main, now just using local main
|
||||
|
||||
=== 1.1.3 / 2009-04-14
|
||||
|
||||
* Removed /test used for the executable, causing gem to fail building
|
||||
|
||||
=== 1.1.2 / 2009-04-14
|
||||
|
||||
* Added `jspec update` sub-command [#63]
|
||||
|
||||
=== 1.1.1 / 2009-04-12
|
||||
|
||||
* Added gemspec
|
||||
|
||||
=== 1.1.0 / 2009-04-12
|
||||
|
||||
* jspec executable fully functional
|
||||
|
||||
=== 1.0.4 / 2009-04-09
|
||||
|
||||
* Added `jspec bind`
|
||||
* Added `jspec run`
|
||||
* Added `jspec init`
|
||||
* Added `jspec` executable
|
||||
* Added gemspec and manifest
|
||||
* Added command-line usage docs
|
||||
* Added custom matchers documentation
|
||||
* Removed double negation
|
||||
|
||||
=== 1.0.3 / 2009-04-08
|
||||
|
||||
* Added have_prop matcher, have_property is now strict [#56]
|
||||
|
||||
=== 1.0.2 / 2009-04-08
|
||||
|
||||
* Added be_selected, be_checked matchers
|
||||
* Added string support to each() each('some foo bar', ...)
|
||||
* Added have_ATTR matchers [#51]
|
||||
* Deprected be_a_TYPE_input matchers [#50]
|
||||
|
||||
=== 1.0.1 / 2009-04-07
|
||||
|
||||
* Added have_property matcher [#53]
|
||||
|
||||
=== 1.0.0 / 2009-04-06
|
||||
|
||||
* Added option() which gives the query string option precedence [#39]
|
||||
* Changed; Using JSpec.options.formatter not JSpec.formatter [#44]
|
||||
* Fixed Console formatter, now displays nested suites
|
||||
* Check out http://visionmedia.github.com/jspec for additional documentation!
|
||||
|
||||
=== 0.9.6 / 2009-04-03
|
||||
|
||||
* Added nesting support
|
||||
* Added printing of nested specs
|
||||
* Added assertion graphs to DOM formatter
|
||||
* Refactored preprocess()
|
||||
* Refactored most of the specs
|
||||
* Renamed preProcess() to preprocess()
|
||||
* Removed running of a single suite via ?suite= for now
|
||||
|
||||
=== 0.9.5 / 2009-04-02
|
||||
|
||||
* Added support for printing of function bodies and regexps [#27]
|
||||
* Added support for strings / regexp with should_throw_error [#26]
|
||||
* Added have_within matcher
|
||||
* Added have_at_most matcher
|
||||
* Added have_at_least matcher
|
||||
* Added have matcher [#24]
|
||||
|
||||
=== 0.9.4 / 2009-04-02
|
||||
|
||||
* Added be_a_TYPE_input matchers (be_a_checkbox_input, be_a_text_input, etc)
|
||||
* Added be_disabled matcher [#21]
|
||||
* Added be_enabled matcher [#20]
|
||||
* Refactored be_visible and be_hidden with $(elem).is()
|
||||
|
||||
=== 0.9.2 / 2009-04-02
|
||||
|
||||
* Added support for multi-arg failure messages [#2]
|
||||
* Better printing of jQuery objects [#15]
|
||||
|
||||
=== 0.9.1 / 2009-04-02
|
||||
|
||||
* Added support for dotted negation of assertions (foo.should.not.equal bar)
|
||||
* Added support for dot-style assertions [#17] (foo.should_not.equal bar)
|
||||
|
||||
=== 0.9.0 / 2009-04-01
|
||||
|
||||
* Added spec for strip()
|
||||
* Added strip()
|
||||
* Added any() util
|
||||
* Added new improved include matcher
|
||||
* Added have_many and have_one matchers
|
||||
* Added have_attr matcher [#14]
|
||||
* Added map() util
|
||||
* Added inject() util
|
||||
* Added escape() util
|
||||
* Added recursive array and object printing
|
||||
* Added DOM formatter option failuresOnly
|
||||
* Added support for running of a single squite via ?suite=...
|
||||
* Added query() util
|
||||
* Added last() util
|
||||
* Added be_within matcher, accepts a range literal
|
||||
* Added inclusive range literal n..n
|
||||
* Added row hover
|
||||
* Refactored range()
|
||||
* Refactored setMessage()
|
||||
* Refactored hash()
|
||||
* Changed; preprocessor passing array of args (multi-arg matcher support)
|
||||
* Changed jQuery to $ for internal usage
|
||||
|
||||
=== 0.8.0 / 2009-02-27
|
||||
|
||||
* Added a new style for the DOM formatter (not finished yet)
|
||||
|
||||
=== 0.7.0 / 2009-02-27
|
||||
|
||||
* Added Console formatter (anything implementing the console object. Firebug, Safari 4, etc)
|
||||
* Added JSpec.options.profile for optional profiling of specs
|
||||
* Added this. literal alternative (view readme)
|
||||
* Moved formatters into JSpec.formatters
|
||||
* Added error() util
|
||||
* Added savings raketask
|
||||
* Fixed parse error bug in Safari 4
|
||||
|
||||
=== 0.6.3 / 2009-02-26
|
||||
|
||||
* Added minification for jspec.jquery.js when packaging before release
|
||||
* Added compression of css when packaging before release
|
||||
|
||||
=== 0.6.2 / 2009-02-26
|
||||
|
||||
* Changed; using $ in jspec.jquery.js for JSpec, take that jQuery ;)
|
||||
* Added addMatchers, print, hash, and each as 'utility functions' this allows
|
||||
JSpec to do each(...) internally instead of JSpec.each(...), while still preventing
|
||||
pollution of the global scope.
|
||||
|
||||
=== 0.6.1 / 2009-02-26
|
||||
|
||||
* Added closrue literal -{ (view README)
|
||||
* Added option to DOM formatter, now allows you to specify which element id to output to
|
||||
|
||||
=== 0.6.0 / 2009-02-24
|
||||
|
||||
* Added JSpec.hash
|
||||
* Added be_null matcher
|
||||
* Allow recursive composite matching using should_eql and should_not_eql
|
||||
For example [1, 2, [3]].should_eql([1, 2, [3]]) is true, works with object
|
||||
'hashes' as well.
|
||||
|
||||
=== 0.5.1 / 2009-02-24
|
||||
|
||||
* Damn auto-release messed up
|
||||
|
||||
=== 0.5.0 / 2009-02-24
|
||||
|
||||
* Added async support for jQuery
|
||||
* Added JSpec.requires for dependencies
|
||||
* Added JSpec.throw
|
||||
* Added JSpec.runSpec
|
||||
* Refactored jspec.jquery.js
|
||||
* Fixed evalBody exceptions, previously was not showing exception message
|
||||
* Fixed bug of JSpec interpreting // in a string such as http:// to be a comment.
|
||||
|
||||
=== 0.4.1 / 2009-02-22
|
||||
|
||||
* Added elements() alias of element()
|
||||
* Added support for string passed to runSuite; runSuite('Matchers') is the same as
|
||||
runSuite(JSpec.suites['Matchers']).
|
||||
* Fixed some documentation
|
||||
|
||||
=== 0.4.0 / 2009-02-20
|
||||
|
||||
* Added comment literal (//)
|
||||
* Added pre-processor for convering matchers.
|
||||
For example 'test'.should_be_true becomes JSpec.match('test', 'should_be', 'true'),
|
||||
preventing pollution of core prototypes.
|
||||
|
||||
=== 0.3.2 / 2009-02-19
|
||||
|
||||
* Added TM bundle (go checkout my jspec.tmbundle repo on github)
|
||||
* Renamed have_length_of to have_length
|
||||
|
||||
=== 0.3.1 / 2009-02-19
|
||||
|
||||
* Added jquery js to package
|
||||
|
||||
=== 0.3.0 / 2009-02-19
|
||||
|
||||
* Added JSpec.match
|
||||
* Added options to report() which are passed to formatter
|
||||
* Added sandbox helpers (reg / jquery)
|
||||
* Added have_child and have_children
|
||||
* Added have_tag and have_tags
|
||||
* Changed exec to only load / eval file
|
||||
* Fixed parser token issue, was previously matching things like end() as literal end
|
||||
|
||||
=== 0.2.3 / 2009-02-18
|
||||
|
||||
* Changed test dir to spec
|
||||
* Changed test.js to core.spec.js
|
||||
|
||||
=== 0.2.2 / 2009-02-18
|
||||
|
||||
* Added contexts
|
||||
|
||||
=== 0.2.0 / 2009-02-18
|
||||
|
||||
* Added release rake task
|
||||
* Added package with minified alternative
|
||||
|
||||
=== 0.1.0 / 2009-02-18
|
||||
|
||||
* Added new sexy syntax (warning: you will have to re-write your specs)
|
||||
* Added pre-processor for optional matcher parens
|
||||
* Added several new matchers
|
||||
* Added matcher aliasing
|
||||
* Added simple matcher declarations
|
||||
* Added __END__
|
||||
* Added yet-to-be-implemented specs
|
||||
* Added loading of suites via JSpec.load
|
||||
|
||||
=== 0.0.4 / 2008-11-03
|
||||
|
||||
* Added ability to pass only a description to it(), meaning not yet implemented
|
||||
|
||||
=== 0.0.3 / 2008-10-28
|
||||
|
||||
* Added should_fail
|
||||
* Added should_match
|
||||
* Added should_not_match
|
||||
* Added should_be and should_not_be
|
||||
|
||||
=== 0.0.2 / 2008-10-28
|
||||
|
||||
* Fixed typo in documentation for pointing to the master repo
|
||||
|
||||
=== 0.0.1 / 2008-10-28
|
||||
|
||||
* Initial release
|
50
thirdparty/jquery-concrete/vendor/jspec/Manifest
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
bin/jspec
|
||||
History.rdoc
|
||||
jspec.gemspec
|
||||
lib/images/bg.png
|
||||
lib/images/hr.png
|
||||
lib/images/loading.gif
|
||||
lib/images/sprites.bg.png
|
||||
lib/images/sprites.png
|
||||
lib/images/vr.png
|
||||
lib/jspec.css
|
||||
lib/jspec.jquery.js
|
||||
lib/jspec.js
|
||||
lib/jspec.xhr.js
|
||||
Manifest
|
||||
Rakefile
|
||||
README.rdoc
|
||||
server/browsers.rb
|
||||
server/server.rb
|
||||
spec/async
|
||||
spec/env.js
|
||||
spec/fixtures/test.html
|
||||
spec/fixtures/test.json
|
||||
spec/fixtures/test.xml
|
||||
spec/modules.js
|
||||
spec/spec.dom.html
|
||||
spec/spec.fixtures.js
|
||||
spec/spec.grammar-less.js
|
||||
spec/spec.grammar.js
|
||||
spec/spec.jquery.js
|
||||
spec/spec.jquery.xhr.js
|
||||
spec/spec.js
|
||||
spec/spec.matchers.js
|
||||
spec/spec.modules.js
|
||||
spec/spec.node.js
|
||||
spec/spec.rhino.js
|
||||
spec/spec.server.html
|
||||
spec/spec.shared-behaviors.js
|
||||
spec/spec.utils.js
|
||||
spec/spec.xhr.js
|
||||
templates/default/History.rdoc
|
||||
templates/default/lib/yourlib.core.js
|
||||
templates/default/README.rdoc
|
||||
templates/default/spec/spec.core.js
|
||||
templates/default/spec/spec.dom.html
|
||||
templates/default/spec/spec.rhino.js
|
||||
templates/default/spec/spec.server.html
|
||||
templates/rails/spec.application.js
|
||||
templates/rails/spec.dom.html
|
||||
templates/rails/spec.rhino.js
|
||||
templates/rails/spec.server.html
|
724
thirdparty/jquery-concrete/vendor/jspec/README.rdoc
vendored
Normal file
@ -0,0 +1,724 @@
|
||||
|
||||
= JSpec
|
||||
|
||||
JSpec is a minimalistic JavaScript behavior driven development framework,
|
||||
providing simple installation, extremely low learning curve, absolutely no pollution
|
||||
to core prototypes, async request support, and incredibly sexy syntax, tons of matchers
|
||||
and much more.
|
||||
|
||||
== Features
|
||||
|
||||
* Highly readable
|
||||
* Framework / DOM independent
|
||||
* Modular via JSpec Module's and hooks
|
||||
* Mock Ajax Requests
|
||||
* Rhino support
|
||||
* Node.js support
|
||||
* Async support
|
||||
* Fixture support
|
||||
* Ruby JavaScript testing server
|
||||
* Nested describes
|
||||
* Does not pollute core object prototypes
|
||||
* Cascading before/after/before_each/after_each hooks
|
||||
* Extremely simple and intuitive matcher declaration
|
||||
* Over 45 core matchers
|
||||
* Allows parens to be optional when using matchers to increase readability
|
||||
* Several helpful formatters (DOM, Console, Terminal, ...)
|
||||
* Assertion graphs displaying how many, and which assertions pass or failed
|
||||
* Default / customizable evaluation contexts
|
||||
* DOM sandbox support
|
||||
* Great looking default DOM theme
|
||||
* `jspec` command-line utility for auto-running specs, and initializing project templates
|
||||
* Proxy or 'Spy' assertions
|
||||
* Method Stubbing
|
||||
* Shared behaviors
|
||||
* Profiling
|
||||
* Ruby on Rails Integration
|
||||
* Tiny (15 kb compressed, 1300-ish LOC)
|
||||
|
||||
== Installation
|
||||
|
||||
Simply download JSpec and include JSpec.css and JSpec.js in your markup.
|
||||
Head over to the downloads section on Github, clone this public repo, or
|
||||
add JSpec as a git submodule with in your project. Alternatively JSpec is
|
||||
also available as a Ruby Gem (though this is not required), which also
|
||||
provides the `jspec` executable. To install execute:
|
||||
$ gem sources -a http://gems.github.com (if you have not previously done so)
|
||||
$ sudo gem install visionmedia-jspec
|
||||
|
||||
At which point you may:
|
||||
$ jspec init myproject
|
||||
|
||||
JSpec scripts should NOT be referenced via the <script> tag, they should be
|
||||
loaded using the exec method (unless you are using the grammar-less alternative).
|
||||
Below is an example:
|
||||
|
||||
...
|
||||
<script>
|
||||
function runSuites() {
|
||||
JSpec
|
||||
.exec('spec.core.js')
|
||||
.exec('spec.jquery.js')
|
||||
.run({ failuresOnly : true })
|
||||
.report()
|
||||
}
|
||||
</script>
|
||||
<body onLoad="runSuites()">
|
||||
...
|
||||
|
||||
You may optionally want to use sources in the /pkg directory
|
||||
for your project, since it includes compressed alternatives generated
|
||||
each release.
|
||||
|
||||
== Example
|
||||
|
||||
describe 'ShoppingCart'
|
||||
before_each
|
||||
cart = new ShoppingCart
|
||||
end
|
||||
|
||||
describe 'addProducts'
|
||||
it 'should add several products'
|
||||
cart.addProduct('cookie')
|
||||
cart.addProduct('icecream')
|
||||
cart.should.have 2, 'products'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'checkout'
|
||||
it 'should throw an error when checking out with no products'
|
||||
-{ cart.clear().checkout() }.should.throw_error EmptyCart
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
== Grammar-less Example
|
||||
|
||||
JSpec's grammar is optional, you may also use the equivalent grammar-less
|
||||
alternative below using pure JavaScript (when using the JSpec grammar you
|
||||
may also use grammar-less assertions):
|
||||
|
||||
JSpec.describe('ShoppingCart', function(){
|
||||
before_each(function{
|
||||
cart = new ShoppingCart
|
||||
})
|
||||
|
||||
describe('addProducts', function(){
|
||||
it ('should add several products', function(){
|
||||
cart.addProducts('cookie')
|
||||
cart.addProducts('icecream')
|
||||
expect(cart).to(have, 2, 'products')
|
||||
})
|
||||
})
|
||||
|
||||
describe('checkout', function(){
|
||||
it ('should throw an error when checking out with no products', function(){
|
||||
expect(function(){ cart.clear().checkout() }).to(throw_error, EmptyCart)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
== Options
|
||||
|
||||
You may alter the way JSpec operates by assigning options via the
|
||||
JSpec.options hash, by passing string-based option values via the
|
||||
query string, or passing a hash to run(). For example
|
||||
JSpec.options.failuresOnly = true, and ?failuresOnly=1 will both work.
|
||||
|
||||
* profile {bool} when enabled, uses console.time() in order to display performance information in your console log as specs are completed. (DOM, Console)
|
||||
* failuresOnly {bool} displays only failing specs, making them quick to discover and fix (DOM, Terminal)
|
||||
* reportToId {string} an element id to report to when using the DOM formatter (DOM)
|
||||
|
||||
== Matchers
|
||||
|
||||
* Core
|
||||
|
||||
- equal, be ===
|
||||
- be_a, be_an have constructor of x
|
||||
- be_an_instance_of instanceof x
|
||||
- be_at_least >=
|
||||
- be_at_most <=
|
||||
- be_null == null
|
||||
- be_empty length < 0 or {}
|
||||
- be_true == true
|
||||
- be_false == false
|
||||
- be_type be type of x
|
||||
- be_greater_than >
|
||||
- be_less_than <
|
||||
- be_undefined check if variable passed is undefined
|
||||
- throw_error should throw an error, optionally supply the error string or regexp for message comparison
|
||||
- have object should have n of property (person.should.have(2, 'pets'))
|
||||
- have_at_least object should have at least n of property
|
||||
- have_at_most object should have a maximum n of property
|
||||
- have_within object should have within n..n of property (person.should.have_within(1..3, 'pets')
|
||||
- have_length length of n
|
||||
- have_prop object should have property x, optionally supplying an expected value
|
||||
- have_property strict version of have_prop
|
||||
- be_within checks if n is within the range passed
|
||||
- include include substring, array element, or hash key
|
||||
- match string should match regexp x
|
||||
- respond_to property x should be a function
|
||||
- eql matches simple literals (strings, numbers) with ==
|
||||
However composites like arrays or 'hashes' are recursively matched,
|
||||
meaning that [1, 2, [3]].should_eql([1, 2, [3]]) will be true.
|
||||
|
||||
* jQuery
|
||||
|
||||
- have_tag, have_one have exactly one tag
|
||||
- have_tags, have_many have more than one tag
|
||||
- have_child have exactly one child
|
||||
- have_children have more than one child
|
||||
- have_text have plain text
|
||||
- have_attr have an attribute, with optional value
|
||||
- have_type
|
||||
- have_id
|
||||
- have_title
|
||||
- have_alt
|
||||
- have_href
|
||||
- have_rel
|
||||
- have_rev
|
||||
- have_name
|
||||
- have_target
|
||||
- have_value
|
||||
- have_class
|
||||
- have_classes
|
||||
- be_visible
|
||||
- be_hidden
|
||||
- be_enabled
|
||||
- be_disabled
|
||||
- be_selected
|
||||
- be_checked
|
||||
|
||||
== Proxy Assertions
|
||||
|
||||
Proxy or 'Spy' assertions allow you to assert that a method is called n number
|
||||
of times, with x arguments, returning x value. For example:
|
||||
|
||||
person = { getPets : function(species){ return ['izzy'] }}
|
||||
person.should.receive('getPets', 'twice').with_args(an_instance_of(String))and_return(['izzy'])
|
||||
person.getPets('dog') // This will pass
|
||||
person.getPets() // This will fail because we asked an instance of String
|
||||
|
||||
This is a useful mechanism for testing the behavior of your object, as well as
|
||||
how other methods may interact with it. Below is another example:
|
||||
|
||||
array = ['foo', 'bar']
|
||||
array.should.receive('toString').and_return('foo,bar')
|
||||
'array: ' + array // This line causes the spec to pass due to calling toString()
|
||||
|
||||
For more examples view spec/spec.matchers.js
|
||||
|
||||
== Method Stubbing
|
||||
|
||||
JSpec currently provides very simple stubbing support shown below:
|
||||
|
||||
person = { toString : function(){ return '<Person>' } }
|
||||
stub(person, 'toString').and_return('Ive been stubbed!')
|
||||
|
||||
After each spec all stubs are restored to their original methods so
|
||||
there is no reason to explicitly call destub(). To persist stubs,
|
||||
use a before_each hook:
|
||||
|
||||
before_each
|
||||
stub(someObject, 'method').and_return({ some : thing })
|
||||
end
|
||||
|
||||
To destub a method simply call destub() at any time:
|
||||
|
||||
destub(person, 'toString')
|
||||
|
||||
If you would like to whipe an object clear of stubs simply pass it
|
||||
to destub() without an additional method argument:
|
||||
|
||||
destub(person)
|
||||
|
||||
Alternatively both these utility functions may be called as methods
|
||||
on any object when using the JSpec grammar:
|
||||
|
||||
someObject.stub('method').and_return('whatever')
|
||||
// Converted to stub(someObject, 'method').and_return('whatever')
|
||||
|
||||
== Helpers
|
||||
|
||||
* Core
|
||||
|
||||
- an_instance_of used in conjunction with the 'receive' matcher
|
||||
- mockRequest mock a request (requires jspec.xhr.js)
|
||||
- unmockRequest unmock requests (requests jspec.xhr.js)
|
||||
|
||||
* jQuery
|
||||
|
||||
- sandbox used to generate new DOM sandbox, using jQuery object
|
||||
- element same as invoking jQuery, just reads better and no need to worry about $ collisions
|
||||
- elements alias of element
|
||||
|
||||
== Shared Behaviors
|
||||
|
||||
JSpec's support for shared behaviors allows multiple suites or describe blocks to share
|
||||
common functionality. For example an Admin, would inherit all specs of User:
|
||||
|
||||
describe 'User'
|
||||
before
|
||||
User = function(name) { this.name = name }
|
||||
user = new User('joe')
|
||||
end
|
||||
|
||||
it 'should have a name'
|
||||
user.should.have_property 'name'
|
||||
end
|
||||
|
||||
describe 'Administrator'
|
||||
should_behave_like('User')
|
||||
|
||||
before
|
||||
Admin = function(name) { this.name = name }
|
||||
Admin.prototype.may = function(perm){ return true }
|
||||
user = new Admin('tj')
|
||||
end
|
||||
|
||||
it 'should have access to all permissions'
|
||||
user.may('edit pages').should.be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
NOTE: both User and Administrator's before hooks implement the 'user' variable
|
||||
|
||||
== Mock Ajax Requests
|
||||
|
||||
JSpec supports generic Ajax mocking which is usable with any JavaScript framework via 'jspec.xhr.js'. The
|
||||
API is comprised of two functions, mockRequest() and unmockRequest(). unmockRequest() is
|
||||
automatically called after each specification to restore the default functionality of XMLHttpRequest,
|
||||
so it is uncommon to call unmockRequest() directly. Below is a jQuery example:
|
||||
|
||||
it 'should mock requests'
|
||||
mockRequest().and_return('{ foo : "bar" }', 'application/json')
|
||||
$.getJSON('foo', function(response, statusText){
|
||||
response.foo.should.eql 'bar'
|
||||
})
|
||||
end
|
||||
|
||||
The mockRequest().and_return signature is as follows:
|
||||
|
||||
mockRequest().and_return(<data>, [content-type], [response-status-code], [headers-hash])
|
||||
|
||||
At the moment mockRequest() itself does not accept any arguments, however in the future
|
||||
this will be used to target specific uris for mocking.
|
||||
|
||||
NOTE: works with Rhino as well
|
||||
|
||||
== Hooks
|
||||
|
||||
Currently the following hooks are supported, and may be utilized any number of times as they
|
||||
are simply pushed to a stack. So for instance you may have two before_each blocks within the same
|
||||
scope, they will both run, but this can help keep your specs readable.
|
||||
|
||||
* before run once before the suite is executed
|
||||
* after run once after the suite is executed
|
||||
* before_each run before each specification
|
||||
* after_each run after each specification
|
||||
|
||||
== Custom Contexts
|
||||
|
||||
Custom contexts can be applied to supply helper
|
||||
methods or properties to all subsequent bodies (other hooks, or specs).
|
||||
|
||||
Keep in mind that when replacing the default context you will loose
|
||||
functionality provided by it, unless you manually merge it with your
|
||||
custom context.
|
||||
|
||||
To reset the context simply assign null to obtain the original context.
|
||||
|
||||
...
|
||||
before
|
||||
JSpec.context = { foo : 'bar' }
|
||||
end
|
||||
|
||||
after
|
||||
JSpec.context = null
|
||||
end
|
||||
|
||||
it 'will work ;)'
|
||||
foo.should_equal 'bar'
|
||||
end
|
||||
...
|
||||
|
||||
== Async Support
|
||||
|
||||
Currently only jspec.jquery.js supports async requests. JSpec uses jQuery.ajaxSetup and sets all
|
||||
requests to sync, which preserves execution order, and reports correctly.
|
||||
|
||||
it 'should load mah cookies (textfile)'
|
||||
$.post('async', function(text){
|
||||
text.should_eql 'cookies!'
|
||||
})
|
||||
end
|
||||
|
||||
== Pre-processor
|
||||
|
||||
The pre-processing capability of JSpec is extremely powerful. Your JavaScript
|
||||
code is not necessarily what it seems. For example when you seemingly invoke a
|
||||
object's prototype like below:
|
||||
|
||||
'foobar'.should.include 'bar'
|
||||
|
||||
First parens are added:
|
||||
|
||||
'foobar'.should.include('bar')
|
||||
|
||||
Secondly the matcher invocation is converted to a non-polluting match() call:
|
||||
|
||||
JSpec.match('foobar', 'should', 'include', 'bar')
|
||||
|
||||
This also means instead of:
|
||||
|
||||
var object = { foo : 'bar' }
|
||||
object.should.include 'foo'
|
||||
|
||||
We can do:
|
||||
|
||||
{ foo : 'bar' }.should.include 'foo'
|
||||
|
||||
=== Closure Literal
|
||||
|
||||
These are equivalent:
|
||||
|
||||
-{ throw 'test' }.should.throw_error
|
||||
function() { throw 'test' }.should.throw_error
|
||||
|
||||
=== Inclusive Range Literal
|
||||
|
||||
The following expands to the array of [1,2,3,4,5]
|
||||
|
||||
n.should.be_within 1..5
|
||||
|
||||
== Formatters
|
||||
|
||||
To change a formatter simply alter the options hash like below, assigning
|
||||
a new constructor, or pass it within the hash to run():
|
||||
|
||||
JSpec.options.formatter = JSpec.formatters.Console
|
||||
|
||||
OR
|
||||
|
||||
JSpec
|
||||
.exec('...')
|
||||
.run({ formatter : JSpec.formatters.Terminal })
|
||||
.report()
|
||||
|
||||
== Fixtures
|
||||
|
||||
The fixture() utility function may be used in order to load arbitrary file contents
|
||||
for use with your specifications. JSpec will resolve fixture('data') in the following
|
||||
manor:
|
||||
|
||||
- 'data'
|
||||
- 'spec/data'
|
||||
- 'spec/fixtures/data'
|
||||
- 'spec/fixtures/data.html'
|
||||
|
||||
So if the file 'spec/fixtures/data.html' exists, we can simply use fixture('data'),
|
||||
where as 'spec/fixtures/xml/data.xml' must be specified with fixture('xml/data.xml').
|
||||
|
||||
If you prefer not to store fixtures in the 'fixtures' directory you must be more specific
|
||||
with the path supplied.
|
||||
|
||||
== Testing DOM Elements
|
||||
|
||||
When using jQuery testing DOM elements is very easy. Many may think they require specific
|
||||
sandbox divs in their html, however you do not. Using the fixture support mentioned above
|
||||
you may simply load some HTML, and use the 'elements()' utility which is an alias of jQuery:
|
||||
|
||||
describe 'JSpec DOM testing'
|
||||
describe 'is so easy'
|
||||
before_each
|
||||
list = elements(fixture('users-list'))
|
||||
// or list = jQuery(fixture('users-list'))
|
||||
// or list = $(fixture('users-list'))
|
||||
end
|
||||
|
||||
it 'should have users'
|
||||
list.should.have_tag 'ul'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
You may also use simple strings, since jQuery's constructor will convert them to DOM elements:
|
||||
|
||||
describe 'Something'
|
||||
before_each
|
||||
html = elements('<p>Foo</p>')
|
||||
// or html = $('<p>Foo</p>') ...
|
||||
end
|
||||
|
||||
it 'should do something'
|
||||
html.should.have_text 'Foo'
|
||||
end
|
||||
end
|
||||
|
||||
== Custom Matchers
|
||||
|
||||
First lets create a simple equality matcher. In the case below JSpec is smart enough to realize
|
||||
this is simply a binary operator, and simply transforms this into 'actual === expected'
|
||||
|
||||
JSpec.addMatchers({
|
||||
equal : '==='
|
||||
})
|
||||
|
||||
To alias a method to keep your specs readable you may alias them like below:
|
||||
|
||||
JSpec.addMatchers({
|
||||
be : 'alias equal'
|
||||
})
|
||||
|
||||
'foo'.should.equal 'foo'
|
||||
true.should.be true
|
||||
|
||||
Matchers with string bodies implicitly return the expression value.
|
||||
The expanded version of the equal matcher would then be:
|
||||
|
||||
JSpec.addMatchers({
|
||||
equal : 'actual === expected'
|
||||
})
|
||||
|
||||
Large matchers or those which require several parameters may wish
|
||||
to utilize the hash method:
|
||||
|
||||
JSpec.addMatchers({
|
||||
equal : { match : function(actual, expected){
|
||||
return actual === expected
|
||||
}}
|
||||
})
|
||||
|
||||
To keep JSpec tiny, JSpec will default to generating failure messages
|
||||
for you, how ever this can be explicitly defined:
|
||||
|
||||
JSpec.addMatchers({
|
||||
equal : {
|
||||
match : function(actual, expected){
|
||||
return actual === expected
|
||||
},
|
||||
message : function(actual, expected, negate) {
|
||||
return 'a message here'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
When defining matchers that are extremely similar in functionality, however
|
||||
require different names, you may use a prefixed list of words like below which
|
||||
defines be_disabled, be_selected, be_checked, and have_type, have_id, etc. Each
|
||||
function must return the matcher body which will be used.
|
||||
|
||||
JSpec.addMatchers({
|
||||
'be disabled selected checked' : function(attr) {
|
||||
return 'jQuery(actual).attr("' + attr + '")'
|
||||
},
|
||||
|
||||
'have type id title alt href src sel rev name target' : function(attr) {
|
||||
return function(actual, value) {
|
||||
return value ? jQuery(actual).attr(attr) == value:
|
||||
jQuery(actual).attr(attr)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
== Extending Or Hooking Into JSpec
|
||||
|
||||
JSpec provides a hook architecture for extending or analyzing various
|
||||
points in its execution, through the use of 'Modules'. For a Module
|
||||
example view lib/jspec.jquery.js.
|
||||
|
||||
The following methods or properties are utilized by JSpec:
|
||||
|
||||
- init : called to initialize a module
|
||||
- utilities : hash of utility functions merged with JSpec.defaultContext
|
||||
- matchers : hash of matchers merged with JSpec's core matchers via JSpec.addMatchers()
|
||||
- DSLs : hash of DSL methods; for example DSLs.snake contains before_each, after_each, etc.
|
||||
Where as DSLs.camel may contain beforeEach, afterEach, etc.
|
||||
|
||||
Below is a list of hooks, descriptions, and valid return values which
|
||||
may simply be implemented as module methods. beforeSuite, afterSuite, beforeSpec, and afterSpec have lower
|
||||
precedence than before_each, after_each etc within the specs themselves, allowing them to override or undo
|
||||
anything that has been done by a Module.
|
||||
|
||||
- running(options) : started running JSpec with the options passed : returning 'stop' will halt running
|
||||
- loading(file) : loading a file : returning 'stop' will prevent loading
|
||||
- executing(file) : executing a file : returning 'stop' will prevent execution
|
||||
- posting(data, url) : posting data to a url : returning 'stop' will prevent request
|
||||
- reportingToServer(url) : reporting to server url : returning 'stop' will prevent reporting to server
|
||||
- preprocessing(input) : before input string is preprocessed : return input string for next hook to preprocess
|
||||
- stubbing(object, method, result) : called when stubbing an object's method, and return value (result). : (no return value)
|
||||
- requiring(dependency, message) : requiring a dependency : (no return value)
|
||||
- beforeAssertion(assertion) : before an assertion has been made : (no return value)
|
||||
- afterAssertion(assertion) : after an assertion has been made : (no return value)
|
||||
- addingMatcher(name, body) : unprocessed matcher name and body : (no return value)
|
||||
- addingSuite(suite) : adding Suite instance to JSpec : (no return value)
|
||||
- beforeSuite(suite) : before running of suite (describe block) : (no return value)
|
||||
- afterSuite(suite) : after running of suite (describe block) : (no return value)
|
||||
- beforeSpec(spec) : before running of spec (it block) : (no return value)
|
||||
- afterSpec(spec) : after running of spec (it block) : (no return value)
|
||||
- reporting(options) : called before reporting : (no return value)
|
||||
- evaluatingBody(dsl, matchers, context, contents) : evaluating body contents, with the given context, matchers and dsl. : (no return value)
|
||||
|
||||
For example you may wish to proxy files which are being executed, simply implement the
|
||||
executing method like below. This example will stop execution of any file matching /matchers/.
|
||||
|
||||
MyModule = {
|
||||
executing : function(file) {
|
||||
if (file.match(/matchers/))
|
||||
return 'stop'
|
||||
}
|
||||
}
|
||||
JSpec.include(MyModule)
|
||||
|
||||
Immutable values may also be passed to hooks using hookImmutable() internally. This allows
|
||||
for simple numbers, strings, etc to be utilized or altered within a hook implementation. Below
|
||||
is an example module which adds functionality to the JSpec grammar by converting SomeObject.stub('method')
|
||||
to stub(SomeObject, 'method'):
|
||||
|
||||
JSpec.include({
|
||||
preprocessing : function(input) {
|
||||
return input.replace(/(\w+)\.(stub|destub)\((.*?)\)$/gm, '$2($1, $3)')
|
||||
}
|
||||
})
|
||||
|
||||
== JSpec Command-line Utility
|
||||
|
||||
When installed as a Ruby Gem, the `jspec` executable will become available,
|
||||
allowing you to initialize project templates quickly, as well as auto-testing
|
||||
specifications when a file is altered.
|
||||
|
||||
Initialize JSpec-driven project template in directory 'myproject':
|
||||
$ jspec init myproject
|
||||
|
||||
Once within 'myproject' start testing by executing:
|
||||
$ jspec
|
||||
|
||||
For additional usage execute:
|
||||
$ jspec help
|
||||
|
||||
Or for specific usage:
|
||||
$ jspec help run
|
||||
|
||||
== Rhino
|
||||
|
||||
JSpec provides transparent support for Rhino, while using the Terminal formatter.
|
||||
Simply create a JavaScript file with contents similar to below, and then execute
|
||||
the command following it:
|
||||
|
||||
load('lib/jspec.js')
|
||||
|
||||
JSpec
|
||||
.exec('spec/spec.grammar.js')
|
||||
.exec('spec/spec.core.js')
|
||||
.run({ formatter : JSpec.formatters.Terminal, failuresOnly : true })
|
||||
.report()
|
||||
|
||||
Initialize project with:
|
||||
$ jspec init myproject
|
||||
|
||||
Run with:
|
||||
$ jspec run --rhino
|
||||
|
||||
Or bind (automated testing):
|
||||
$ jspec --rhino
|
||||
|
||||
== Server
|
||||
|
||||
The Ruby JavaScript testing server included with JSpec simply runs
|
||||
the spec suites within each browser you specify, while reporting result
|
||||
back to the terminal. It is essentially the same as using the DOM formatter
|
||||
and auto-testing each browser, however results are centralized to the terminal,
|
||||
removing the need to manually view each browser's output.
|
||||
|
||||
Initialize project with:
|
||||
$ jspec init myproject
|
||||
|
||||
Run with:
|
||||
$ jspec run --server
|
||||
|
||||
|
||||
== Ruby on Rails
|
||||
|
||||
No additional gems are required for JSpec to work with rails, although
|
||||
http://github.com/bhauman/jspec-rails has been created by 'bhauman'. JSpec
|
||||
supports Rails out of the box, simply execute:
|
||||
|
||||
$ jspec init --rails
|
||||
|
||||
Then while still in the root directory of your Rails project, run the following
|
||||
command which will bind to, and refresh your browsers automatically when any changes
|
||||
are made to ./public/javascripts/*.js or ./jspec/*.js
|
||||
|
||||
$ jspec
|
||||
|
||||
Or just like regular JSpec applications, run once:
|
||||
|
||||
$ jspec run
|
||||
|
||||
Or run via the terminal using Rhino:
|
||||
|
||||
$ jspec run --rhino
|
||||
|
||||
== Known Issues
|
||||
|
||||
* Tabs may cause a parse error. To prevent this use 'soft tabs' (setting in your IDE/Editor)
|
||||
or use JSpec's grammar-less alternative (mentioned above).
|
||||
|
||||
* The preprocessor is not (yet) capable of multiline conversions. For example the following is invalid
|
||||
|
||||
object.stub('getContentsOfURL').and_return(function(url){
|
||||
return 'html'
|
||||
})
|
||||
|
||||
In cases such as this, you may always revert to utilizing JSpec in a grammar-less form as follows:
|
||||
|
||||
stub(object, 'getContentsOfURL').and_return(function(url){
|
||||
return 'html'
|
||||
})
|
||||
|
||||
== More Information
|
||||
|
||||
* Featured article in JSMag: http://www.jsmag.com/main.issues.description/id=21/
|
||||
* Syntax comparison with other frameworks http://gist.github.com/92283
|
||||
* Get the TextMate bundle at https://github.com/visionmedia/jspec.tmbundle/tree
|
||||
* For more information consult the JSpec source code documentation or visit http://visionmedia.github.com/jspec
|
||||
* jQuery + HTML fixture example http://gist.github.com/147831
|
||||
|
||||
== Contributors
|
||||
|
||||
Many ideas and bug reports were contributed by
|
||||
the following developers, thankyou for making
|
||||
JSpec more enjoyable, and bug free ;)
|
||||
|
||||
* Lawrence Pit
|
||||
* mpd@jesters-court.ne
|
||||
* kevin.gisi@gmail.com
|
||||
* enno84@gmx.net
|
||||
|
||||
== License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2008 - 2009 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
73
thirdparty/jquery-concrete/vendor/jspec/Rakefile
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
|
||||
require 'rubygems'
|
||||
require 'rake'
|
||||
require 'echoe'
|
||||
|
||||
def version
|
||||
$1 if File.read('lib/jspec.js').match /version *: *'(.*?)'/
|
||||
end
|
||||
|
||||
Echoe.new "jspec", version do |p|
|
||||
p.author = "TJ Holowaychuk"
|
||||
p.email = "tj@vision-media.ca"
|
||||
p.summary = "JavaScript BDD Testing Framework"
|
||||
p.url = "http://visionmedia.github.com/jspec"
|
||||
p.runtime_dependencies << "visionmedia-commander >=3.2.9"
|
||||
p.runtime_dependencies << "visionmedia-bind >=0.2.6"
|
||||
end
|
||||
|
||||
namespace :pkg do
|
||||
desc 'Build package'
|
||||
task :build => ['pkg:clear'] do
|
||||
begin
|
||||
sh 'mkdir pkg'
|
||||
sh 'cp -fr lib/* pkg'
|
||||
minify 'lib/jspec.js', 'pkg/jspec.min.js'
|
||||
minify 'lib/jspec.jquery.js', 'pkg/jspec.jquery.min.js'
|
||||
compress 'lib/jspec.css', 'pkg/jspec.min.css'
|
||||
sh 'git add pkg/.'
|
||||
rescue Exception => e
|
||||
puts "Failed to package: #{e}."
|
||||
else
|
||||
puts "Packaging of JSpec-#{version} completed."
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Clear packaging'
|
||||
task :clear do
|
||||
if File.directory? 'pkg'
|
||||
sh 'rm -fr pkg/*'
|
||||
sh 'rmdir pkg'
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Display compression savings of last release'
|
||||
task :savings do
|
||||
totals = Hash.new { |h, k| h[k] = 0 }
|
||||
format = '%-20s : %0.3f kb'
|
||||
totals = %w( pkg/jspec.min.js pkg/jspec.jquery.min.js pkg/jspec.min.css ).inject totals do |total, file|
|
||||
uncompressed = File.size(file.sub('.min', '')).to_f / 1024
|
||||
compressed = File.size(file).to_f / 1024
|
||||
saved = uncompressed - compressed
|
||||
puts format % [file.sub('pkg/', ''), saved]
|
||||
totals[:saved] += saved
|
||||
totals[:uncompressed] += uncompressed
|
||||
totals[:compressed] += compressed
|
||||
totals
|
||||
end
|
||||
puts
|
||||
puts format % ['total uncompressed', totals[:uncompressed]]
|
||||
puts format % ['total compressed', totals[:compressed]]
|
||||
puts format % ['total saved', totals[:saved]]
|
||||
end
|
||||
end
|
||||
|
||||
def minify from, to
|
||||
sh "jsmin < #{from} > #{to}"
|
||||
end
|
||||
|
||||
def compress from, to
|
||||
File.open(to, 'w+') do |file|
|
||||
file.write File.read(from).gsub(/(^[\t ]*)|\n/, '')
|
||||
end
|
||||
end
|
182
thirdparty/jquery-concrete/vendor/jspec/bin/jspec
vendored
Executable file
@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
JSPEC_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
||||
$:.unshift JSPEC_ROOT
|
||||
|
||||
require 'rubygems'
|
||||
require 'commander'
|
||||
require 'bind'
|
||||
require 'fileutils'
|
||||
|
||||
RHINO = 'java org.mozilla.javascript.tools.shell.Main'
|
||||
|
||||
program :name, 'JSpec'
|
||||
program :version, '2.8.4'
|
||||
program :description, 'JavaScript BDD Testing Framework'
|
||||
default_command :bind
|
||||
|
||||
command :init do |c|
|
||||
c.syntax = 'jspec init [dest]'
|
||||
c.summary = 'Initialize a JSpec project template'
|
||||
c.description = 'Initialize a JSpec project template. Defaults to the current directory
|
||||
when [dest] is not specified. The template includes several files for
|
||||
running via Rhino, DOM, and the JSpec Rack server.'
|
||||
c.example 'Create a directory foo, initialized with a jspec template', 'jspec init foo'
|
||||
c.option '-R', '--rails', 'Initialize rails template'
|
||||
c.when_called do |args, options|
|
||||
dest = args.shift || '.'
|
||||
if options.rails
|
||||
initialize_rails_to dest
|
||||
else
|
||||
initialize_to dest
|
||||
end
|
||||
say "Template initialized at '#{dest}'"
|
||||
end
|
||||
end
|
||||
|
||||
command :update do |c|
|
||||
c.syntax = 'jspec update [path ...]'
|
||||
c.summary = 'Update JSpec releases'
|
||||
c.description = 'Update JSpec release in [paths], this will allow you to utilize
|
||||
the latest JSpec features. Execute from JSpec project root without [paths] to
|
||||
update the default template spec files.'
|
||||
c.when_called do |args, options|
|
||||
if args.empty?
|
||||
if rails?
|
||||
paths = 'jspec/spec.dom.html', 'jspec/spec.rhino.js'
|
||||
else
|
||||
paths = 'spec/spec.dom.html', 'spec/spec.rhino.js'
|
||||
end
|
||||
else
|
||||
paths = args
|
||||
end
|
||||
update_version_in *paths
|
||||
end
|
||||
end
|
||||
|
||||
command :run do |c|
|
||||
c.syntax = 'jspec run [path] [options]'
|
||||
c.summary = 'Run specifications'
|
||||
c.description = 'Run specifications, defaulting [path] to spec/spec.dom.html.
|
||||
You will need to supply [path] if your specs do not reside
|
||||
in this location. `run --bind` is the default sub-command of
|
||||
jspec so you may simply execute `jspec` in order to bind execution
|
||||
of your specs when a file is altered.
|
||||
|
||||
JSpec supports Rhino execution when installed. The [path] is assumed
|
||||
to be spec/spec.rhino.js unless specified. See examples below for
|
||||
using the --rhino switch.
|
||||
|
||||
JSpec\'s server is also available via --server, which defaults
|
||||
the [path] to spec/server.html'
|
||||
c.example 'Run once in Safari', 'jspec run'
|
||||
c.example 'Run once in Safari and Firefox', 'jspec run --browsers Safari,Firefox'
|
||||
c.example 'Run custom spec file', 'jspec run foo.html'
|
||||
c.example 'Auto-run browsers when a file is altered', 'jspec run --bind --browsers Safari,Firefox'
|
||||
c.example 'Shortcut for the previous example', 'jspec --browsers Safari,Firefox'
|
||||
c.example 'Auto-run rhino when a file is altered', 'jspec --rhino'
|
||||
c.example 'Run Rhino specs once', 'jspec run specs/something.js --rhino'
|
||||
c.option '-b', '--browsers BROWSERS', Array, 'Specify browsers to test, defaults to Safari'
|
||||
c.option '-p', '--paths PATHS', Array, 'Specify paths when binding, defaults to javascript within ./lib and ./spec'
|
||||
c.option '-B', '--bind', 'Auto-run specs when source files or specs are altered'
|
||||
c.option '-R', '--rhino', 'Run specs using Rhino'
|
||||
c.option '-S', '--server', 'Run specs using the JSpec server'
|
||||
c.option '-s', '--server-only', 'Start JSpec server without running browsers'
|
||||
c.when_called do |args, options|
|
||||
|
||||
# Rails
|
||||
if rails?
|
||||
options.default :browsers => %w( Safari ), :paths => ['public/javascripts/**/*.js', 'jspec/**/*.js']
|
||||
else
|
||||
options.default :browsers => %w( Safari ), :paths => ['lib/**/*.js', 'spec/**/*.js']
|
||||
end
|
||||
|
||||
# Actions
|
||||
if options.rhino
|
||||
spec = args.shift || path_to('spec.rhino.js')
|
||||
action = lambda { rhino spec }
|
||||
elsif options.server_only
|
||||
start_server options, nil
|
||||
elsif options.server
|
||||
spec = args.shift || path_to('spec.server.html')
|
||||
action = lambda { start_server options, spec }
|
||||
else
|
||||
spec = args.shift || path_to('spec.dom.html')
|
||||
action = Bind::Actions::RefreshBrowsers.new spec, *options.browsers
|
||||
end
|
||||
|
||||
# Binding
|
||||
if options.bind
|
||||
listener = Bind::Listener.new :paths => options.paths, :interval => 1, :actions => [action], :debug => $stdout
|
||||
listener.run!
|
||||
else
|
||||
action.call File.new(spec)
|
||||
end
|
||||
end
|
||||
end
|
||||
alias_command :bind, :run, '--bind'
|
||||
|
||||
def initialize_to dest
|
||||
unless Dir[dest + '/*'].empty?
|
||||
abort unless agree "'#{dest}' is not empty; continue? "
|
||||
end
|
||||
copy_template_to 'default', dest
|
||||
replace_root_in dest, 'spec/spec.dom.html', 'spec/spec.rhino.js'
|
||||
end
|
||||
|
||||
def initialize_rails_to dest
|
||||
unless looks_like_rails_root?(dest)
|
||||
abort unless agree "'#{dest}' does not look like root of a rails project; continue? "
|
||||
end
|
||||
copy_template_to 'rails', "#{dest}/jspec"
|
||||
replace_root_in "#{dest}/jspec", 'spec.dom.html', 'spec.rhino.js'
|
||||
end
|
||||
|
||||
def copy_template_to name, dest
|
||||
FileUtils.mkdir_p dest
|
||||
FileUtils.cp_r path_to_template(name), dest
|
||||
end
|
||||
|
||||
def path_to_template name
|
||||
File.join JSPEC_ROOT, 'templates', name, '.'
|
||||
end
|
||||
|
||||
def path_to file
|
||||
rails? ? "jspec/#{file}" : "spec/#{file}"
|
||||
end
|
||||
|
||||
def rhino file
|
||||
abort "#{file} not found" unless File.exists? file
|
||||
system "#{RHINO} #{file}"
|
||||
end
|
||||
|
||||
def start_server options, spec
|
||||
require 'server/server'
|
||||
JSpec::Server.start options, spec
|
||||
end
|
||||
|
||||
def rails?
|
||||
File.directory? 'jspec'
|
||||
end
|
||||
|
||||
def replace_root_in dest, *paths
|
||||
paths.each do |path|
|
||||
path = File.join dest, path
|
||||
contents = File.read(path).gsub 'JSPEC_ROOT', JSPEC_ROOT
|
||||
File.open(path, 'w') { |file| file.write contents }
|
||||
end
|
||||
end
|
||||
|
||||
def update_version_in *paths
|
||||
paths.each do |path|
|
||||
next unless File.exists? path
|
||||
contents = File.read(path).gsub /visionmedia-jspec-(\d+\.\d+\.\d+)/, "visionmedia-jspec-#{program(:version)}"
|
||||
File.open(path, 'r+'){ |file| file.write contents }
|
||||
say "Updated #{path}; #{$1} -> #{program(:version)}"
|
||||
end
|
||||
say "Finished updating JSpec"
|
||||
end
|
||||
|
||||
def looks_like_rails_root? path = '.'
|
||||
File.directory? "#{path}/vendor"
|
||||
end
|
38
thirdparty/jquery-concrete/vendor/jspec/jspec.gemspec
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = %q{jspec}
|
||||
s.version = "2.8.4"
|
||||
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
||||
s.authors = ["TJ Holowaychuk"]
|
||||
s.date = %q{2009-08-02}
|
||||
s.default_executable = %q{jspec}
|
||||
s.description = %q{JavaScript BDD Testing Framework}
|
||||
s.email = %q{tj@vision-media.ca}
|
||||
s.executables = ["jspec"]
|
||||
s.extra_rdoc_files = ["bin/jspec", "lib/images/bg.png", "lib/images/hr.png", "lib/images/loading.gif", "lib/images/sprites.bg.png", "lib/images/sprites.png", "lib/images/vr.png", "lib/jspec.css", "lib/jspec.jquery.js", "lib/jspec.js", "lib/jspec.xhr.js", "README.rdoc"]
|
||||
s.files = ["bin/jspec", "History.rdoc", "jspec.gemspec", "lib/images/bg.png", "lib/images/hr.png", "lib/images/loading.gif", "lib/images/sprites.bg.png", "lib/images/sprites.png", "lib/images/vr.png", "lib/jspec.css", "lib/jspec.jquery.js", "lib/jspec.js", "lib/jspec.xhr.js", "Manifest", "Rakefile", "README.rdoc", "server/browsers.rb", "server/server.rb", "spec/async", "spec/env.js", "spec/fixtures/test.html", "spec/fixtures/test.json", "spec/fixtures/test.xml", "spec/modules.js", "spec/spec.dom.html", "spec/spec.fixtures.js", "spec/spec.grammar-less.js", "spec/spec.grammar.js", "spec/spec.jquery.js", "spec/spec.jquery.xhr.js", "spec/spec.js", "spec/spec.matchers.js", "spec/spec.modules.js", "spec/spec.node.js", "spec/spec.rhino.js", "spec/spec.server.html", "spec/spec.shared-behaviors.js", "spec/spec.utils.js", "spec/spec.xhr.js", "templates/default/History.rdoc", "templates/default/lib/yourlib.core.js", "templates/default/README.rdoc", "templates/default/spec/spec.core.js", "templates/default/spec/spec.dom.html", "templates/default/spec/spec.rhino.js", "templates/default/spec/spec.server.html", "templates/rails/spec.application.js", "templates/rails/spec.dom.html", "templates/rails/spec.rhino.js", "templates/rails/spec.server.html"]
|
||||
s.homepage = %q{http://visionmedia.github.com/jspec}
|
||||
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Jspec", "--main", "README.rdoc"]
|
||||
s.require_paths = ["lib"]
|
||||
s.rubyforge_project = %q{jspec}
|
||||
s.rubygems_version = %q{1.3.5}
|
||||
s.summary = %q{JavaScript BDD Testing Framework}
|
||||
|
||||
if s.respond_to? :specification_version then
|
||||
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
||||
s.specification_version = 3
|
||||
|
||||
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
||||
s.add_runtime_dependency(%q<visionmedia-commander>, [">= 3.2.9"])
|
||||
s.add_runtime_dependency(%q<visionmedia-bind>, [">= 0.2.6"])
|
||||
else
|
||||
s.add_dependency(%q<visionmedia-commander>, [">= 3.2.9"])
|
||||
s.add_dependency(%q<visionmedia-bind>, [">= 0.2.6"])
|
||||
end
|
||||
else
|
||||
s.add_dependency(%q<visionmedia-commander>, [">= 3.2.9"])
|
||||
s.add_dependency(%q<visionmedia-bind>, [">= 0.2.6"])
|
||||
end
|
||||
end
|
BIN
thirdparty/jquery-concrete/vendor/jspec/lib/images/bg.png
vendored
Normal file
After Width: | Height: | Size: 154 B |
BIN
thirdparty/jquery-concrete/vendor/jspec/lib/images/hr.png
vendored
Normal file
After Width: | Height: | Size: 321 B |
BIN
thirdparty/jquery-concrete/vendor/jspec/lib/images/loading.gif
vendored
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
thirdparty/jquery-concrete/vendor/jspec/lib/images/sprites.bg.png
vendored
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
thirdparty/jquery-concrete/vendor/jspec/lib/images/sprites.png
vendored
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
thirdparty/jquery-concrete/vendor/jspec/lib/images/vr.png
vendored
Normal file
After Width: | Height: | Size: 145 B |
145
thirdparty/jquery-concrete/vendor/jspec/lib/jspec.css
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
body.jspec {
|
||||
margin: 45px 0;
|
||||
font: 12px "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
|
||||
background: #efefef url(images/bg.png) top left repeat-x;
|
||||
}
|
||||
#jspec {
|
||||
margin: 0 auto;
|
||||
padding-top: 25px;
|
||||
width: 1008px;
|
||||
background: url(images/vr.png) top left repeat-y;
|
||||
text-align: left;
|
||||
}
|
||||
#jspec-top {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 1008px;
|
||||
height: 40px;
|
||||
background: url(images/sprites.bg.png) top left no-repeat;
|
||||
}
|
||||
#jspec-bottom {
|
||||
margin: 0 auto;
|
||||
width: 1008px;
|
||||
height: 15px;
|
||||
background: url(images/sprites.bg.png) bottom left no-repeat;
|
||||
}
|
||||
#jspec .loading {
|
||||
margin-top: -45px;
|
||||
width: 1008px;
|
||||
height: 80px;
|
||||
background: url(images/loading.gif) 50% 50% no-repeat;
|
||||
}
|
||||
#jspec-title {
|
||||
position: relative;
|
||||
top: 35px;
|
||||
left: 20px;
|
||||
width: 160px;
|
||||
font-size: 22px;
|
||||
font-weight: normal;
|
||||
background: url(images/sprites.png) 0 -126px no-repeat;
|
||||
text-align: center;
|
||||
}
|
||||
#jspec-title em {
|
||||
font-size: 10px;
|
||||
font-style: normal;
|
||||
color: #BCC8D1;
|
||||
}
|
||||
#jspec-report * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
#jspec-report {
|
||||
padding: 15px 40px;
|
||||
font: 11px "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
|
||||
color: #7B8D9B;
|
||||
}
|
||||
#jspec-report.has-failures {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
#jspec-report .hidden {
|
||||
display: none;
|
||||
}
|
||||
#jspec-report .heading {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
#jspec-report .heading span {
|
||||
padding-right: 10px;
|
||||
}
|
||||
#jspec-report .heading .passes em {
|
||||
color: #0ea0eb;
|
||||
}
|
||||
#jspec-report .heading .failures em {
|
||||
color: #FA1616;
|
||||
}
|
||||
#jspec-report table {
|
||||
width: 100%;
|
||||
font-size: 11px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#jspec-report td {
|
||||
padding: 8px;
|
||||
text-indent: 30px;
|
||||
color: #7B8D9B;
|
||||
}
|
||||
#jspec-report tr.body {
|
||||
display: none;
|
||||
}
|
||||
#jspec-report tr.body pre {
|
||||
margin: 0;
|
||||
padding: 0 0 5px 25px;
|
||||
}
|
||||
#jspec-report tr:not(.body):hover + tr.body {
|
||||
display: block;
|
||||
}
|
||||
#jspec-report tr td:first-child em {
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
color: #7B8D9B;
|
||||
}
|
||||
#jspec-report tr:not(.description):hover {
|
||||
text-shadow: 1px 1px 1px #fff;
|
||||
background: #F2F5F7;
|
||||
}
|
||||
#jspec-report td + td {
|
||||
padding-right: 0;
|
||||
width: 15px;
|
||||
}
|
||||
#jspec-report td.pass {
|
||||
background: url(images/sprites.png) 3px -7px no-repeat;
|
||||
}
|
||||
#jspec-report td.fail {
|
||||
background: url(images/sprites.png) 3px -47px no-repeat;
|
||||
font-weight: bold;
|
||||
color: #FC0D0D;
|
||||
}
|
||||
#jspec-report td.requires-implementation {
|
||||
background: url(images/sprites.png) 3px -87px no-repeat;
|
||||
}
|
||||
#jspec-report tr.description td {
|
||||
margin-top: 25px;
|
||||
padding-top: 25px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
text-indent: 0;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
#jspec-report tr.description:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
#jspec-report .assertion {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 0 0 0 1px;
|
||||
padding: 0;
|
||||
width: 1px;
|
||||
height: 5px;
|
||||
background: #7B8D9B;
|
||||
}
|
||||
#jspec-report .assertion.failed {
|
||||
background: red;
|
||||
}
|
||||
.jspec-sandbox {
|
||||
display: none;
|
||||
}
|
70
thirdparty/jquery-concrete/vendor/jspec/lib/jspec.jquery.js
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
// JSpec - jQuery - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
|
||||
|
||||
JSpec
|
||||
.requires('jQuery', 'when using jspec.jquery.js')
|
||||
.include({
|
||||
|
||||
// --- Initialize
|
||||
|
||||
init : function() {
|
||||
jQuery.ajaxSetup({ async : false })
|
||||
},
|
||||
|
||||
// --- Utilities
|
||||
|
||||
utilities : {
|
||||
element : jQuery,
|
||||
elements : jQuery,
|
||||
sandbox : function() {
|
||||
return jQuery('<div class="sandbox"></div>')
|
||||
}
|
||||
},
|
||||
|
||||
// --- Matchers
|
||||
|
||||
matchers : {
|
||||
have_tag : "jQuery(expected, actual).length == 1",
|
||||
have_one : "alias have_tag",
|
||||
have_tags : "jQuery(expected, actual).length > 1",
|
||||
have_many : "alias have_tags",
|
||||
have_child : "jQuery(actual).children(expected).length == 1",
|
||||
have_children : "jQuery(actual).children(expected).length > 1",
|
||||
have_text : "jQuery(actual).text() == expected",
|
||||
have_value : "jQuery(actual).val() == expected",
|
||||
be_enabled : "!jQuery(actual).attr('disabled')",
|
||||
have_class : "jQuery(actual).hasClass(expected)",
|
||||
|
||||
be_visible : function(actual) {
|
||||
return jQuery(actual).css('display') != 'none' &&
|
||||
jQuery(actual).css('visibility') != 'hidden' &&
|
||||
jQuery(actual).attr('type') != 'hidden'
|
||||
},
|
||||
|
||||
be_hidden : function(actual) {
|
||||
return !JSpec.does(actual, 'be_visible')
|
||||
},
|
||||
|
||||
have_classes : function(actual) {
|
||||
return !JSpec.any(JSpec.argumentsToArray(arguments, 1), function(arg){
|
||||
return !JSpec.does(actual, 'have_class', arg)
|
||||
})
|
||||
},
|
||||
|
||||
have_attr : function(actual, attr, value) {
|
||||
return value ? jQuery(actual).attr(attr) == value:
|
||||
jQuery(actual).attr(attr)
|
||||
},
|
||||
|
||||
'be disabled selected checked' : function(attr) {
|
||||
return 'jQuery(actual).attr("' + attr + '")'
|
||||
},
|
||||
|
||||
'have type id title alt href src sel rev name target' : function(attr) {
|
||||
return function(actual, value) {
|
||||
return JSpec.does(actual, 'have_attr', attr, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
1715
thirdparty/jquery-concrete/vendor/jspec/lib/jspec.js
vendored
Normal file
@ -0,0 +1,1715 @@
|
||||
|
||||
// JSpec - Core - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
|
||||
|
||||
(function(){
|
||||
|
||||
JSpec = {
|
||||
|
||||
version : '2.8.4',
|
||||
cache : {},
|
||||
suites : [],
|
||||
modules : [],
|
||||
allSuites : [],
|
||||
matchers : {},
|
||||
stubbed : [],
|
||||
request : 'XMLHttpRequest' in this ? XMLHttpRequest : null,
|
||||
stats : { specs : 0, assertions : 0, failures : 0, passes : 0, specsFinished : 0, suitesFinished : 0 },
|
||||
options : { profile : false },
|
||||
|
||||
/**
|
||||
* Default context in which bodies are evaluated.
|
||||
*
|
||||
* Replace context simply by setting JSpec.context
|
||||
* to your own like below:
|
||||
*
|
||||
* JSpec.context = { foo : 'bar' }
|
||||
*
|
||||
* Contexts can be changed within any body, this can be useful
|
||||
* in order to provide specific helper methods to specific suites.
|
||||
*
|
||||
* To reset (usually in after hook) simply set to null like below:
|
||||
*
|
||||
* JSpec.context = null
|
||||
*
|
||||
*/
|
||||
|
||||
defaultContext : {
|
||||
|
||||
/**
|
||||
* Return an object used for proxy assertions.
|
||||
* This object is used to indicate that an object
|
||||
* should be an instance of _object_, not the constructor
|
||||
* itself.
|
||||
*
|
||||
* @param {function} constructor
|
||||
* @return {hash}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
an_instance_of : function(constructor) {
|
||||
return { an_instance_of : constructor }
|
||||
},
|
||||
|
||||
/**
|
||||
* Load fixture at _path_. This utility function
|
||||
* supplies the means to resolve, and cache fixture contents
|
||||
* via the DOM or Rhino.
|
||||
*
|
||||
* Fixtures are resolved as:
|
||||
*
|
||||
* - <path>
|
||||
* - fixtures/<path>
|
||||
* - fixtures/<path>.html
|
||||
*
|
||||
* @param {string} path
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
fixture : function(path) {
|
||||
if (JSpec.cache[path]) return JSpec.cache[path]
|
||||
return JSpec.cache[path] =
|
||||
JSpec.tryLoading(path) ||
|
||||
JSpec.tryLoading('fixtures/' + path) ||
|
||||
JSpec.tryLoading('fixtures/' + path + '.html') ||
|
||||
JSpec.tryLoading('spec/' + path) ||
|
||||
JSpec.tryLoading('spec/fixtures/' + path) ||
|
||||
JSpec.tryLoading('spec/fixtures/' + path + '.html')
|
||||
}
|
||||
},
|
||||
|
||||
// --- Objects
|
||||
|
||||
formatters : {
|
||||
|
||||
/**
|
||||
* Default formatter, outputting to the DOM.
|
||||
*
|
||||
* Options:
|
||||
* - reportToId id of element to output reports to, defaults to 'jspec'
|
||||
* - failuresOnly displays only suites with failing specs
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
DOM : function(results, options) {
|
||||
var id = option('reportToId') || 'jspec'
|
||||
var report = document.getElementById(id)
|
||||
var failuresOnly = option('failuresOnly')
|
||||
var classes = results.stats.failures ? 'has-failures' : ''
|
||||
if (!report) throw 'JSpec requires the element #' + id + ' to output its reports'
|
||||
|
||||
var markup =
|
||||
'<div id="jspec-report" class="' + classes + '"><div class="heading"> \
|
||||
<span class="passes">Passes: <em>' + results.stats.passes + '</em></span> \
|
||||
<span class="failures">Failures: <em>' + results.stats.failures + '</em></span> \
|
||||
</div><table class="suites">'
|
||||
|
||||
bodyContents = function(body) {
|
||||
return JSpec.
|
||||
escape(JSpec.contentsOf(body)).
|
||||
replace(/^ */gm, function(a){ return (new Array(Math.round(a.length / 3))).join(' ') }).
|
||||
replace("\n", '<br/>')
|
||||
}
|
||||
|
||||
renderSuite = function(suite) {
|
||||
var displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran
|
||||
if (displaySuite && suite.hasSpecs()) {
|
||||
markup += '<tr class="description"><td colspan="2">' + escape(suite.description) + '</td></tr>'
|
||||
each(suite.specs, function(i, spec){
|
||||
markup += '<tr class="' + (i % 2 ? 'odd' : 'even') + '">'
|
||||
if (spec.requiresImplementation())
|
||||
markup += '<td class="requires-implementation" colspan="2">' + escape(spec.description) + '</td>'
|
||||
else if (spec.passed() && !failuresOnly)
|
||||
markup += '<td class="pass">' + escape(spec.description)+ '</td><td>' + spec.assertionsGraph() + '</td>'
|
||||
else if(!spec.passed())
|
||||
markup += '<td class="fail">' + escape(spec.description) + ' <em>' + spec.failure().message + '</em>' + '</td><td>' + spec.assertionsGraph() + '</td>'
|
||||
markup += '<tr class="body"><td colspan="2"><pre>' + bodyContents(spec.body) + '</pre></td></tr>'
|
||||
})
|
||||
markup += '</tr>'
|
||||
}
|
||||
}
|
||||
|
||||
renderSuites = function(suites) {
|
||||
each(suites, function(suite){
|
||||
renderSuite(suite)
|
||||
if (suite.hasSuites()) renderSuites(suite.suites)
|
||||
})
|
||||
}
|
||||
|
||||
renderSuites(results.suites)
|
||||
markup += '</table></div>'
|
||||
report.innerHTML = markup
|
||||
},
|
||||
|
||||
/**
|
||||
* Terminal formatter.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Terminal : function(results, options) {
|
||||
failuresOnly = option('failuresOnly')
|
||||
print(color("\n Passes: ", 'bold') + color(results.stats.passes, 'green') +
|
||||
color(" Failures: ", 'bold') + color(results.stats.failures, 'red') + "\n")
|
||||
|
||||
indent = function(string) {
|
||||
return string.replace(/^(.)/gm, ' $1')
|
||||
}
|
||||
|
||||
renderSuite = function(suite) {
|
||||
displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran
|
||||
if (displaySuite && suite.hasSpecs()) {
|
||||
print(color(' ' + suite.description, 'bold'))
|
||||
each(suite.specs, function(spec){
|
||||
var assertionsGraph = inject(spec.assertions, '', function(graph, assertion){
|
||||
return graph + color('.', assertion.passed ? 'green' : 'red')
|
||||
})
|
||||
if (spec.requiresImplementation())
|
||||
print(color(' ' + spec.description, 'blue') + assertionsGraph)
|
||||
else if (spec.passed() && !failuresOnly)
|
||||
print(color(' ' + spec.description, 'green') + assertionsGraph)
|
||||
else if (!spec.passed())
|
||||
print(color(' ' + spec.description, 'red') + assertionsGraph +
|
||||
"\n" + indent(spec.failure().message) + "\n")
|
||||
})
|
||||
print("")
|
||||
}
|
||||
}
|
||||
|
||||
renderSuites = function(suites) {
|
||||
each(suites, function(suite){
|
||||
renderSuite(suite)
|
||||
if (suite.hasSuites()) renderSuites(suite.suites)
|
||||
})
|
||||
}
|
||||
|
||||
renderSuites(results.suites)
|
||||
},
|
||||
|
||||
/**
|
||||
* Console formatter, tested with Firebug and Safari 4.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Console : function(results, options) {
|
||||
console.log('')
|
||||
console.log('Passes: ' + results.stats.passes + ' Failures: ' + results.stats.failures)
|
||||
|
||||
renderSuite = function(suite) {
|
||||
if (suite.ran) {
|
||||
console.group(suite.description)
|
||||
each(suite.specs, function(spec){
|
||||
var assertionCount = spec.assertions.length + ':'
|
||||
if (spec.requiresImplementation())
|
||||
console.warn(spec.description)
|
||||
else if (spec.passed())
|
||||
console.log(assertionCount + ' ' + spec.description)
|
||||
else
|
||||
console.error(assertionCount + ' ' + spec.description + ', ' + spec.failure().message)
|
||||
})
|
||||
console.groupEnd()
|
||||
}
|
||||
}
|
||||
|
||||
renderSuites = function(suites) {
|
||||
each(suites, function(suite){
|
||||
renderSuite(suite)
|
||||
if (suite.hasSuites()) renderSuites(suite.suites)
|
||||
})
|
||||
}
|
||||
|
||||
renderSuites(results.suites)
|
||||
}
|
||||
},
|
||||
|
||||
Assertion : function(matcher, actual, expected, negate) {
|
||||
extend(this, {
|
||||
message : '',
|
||||
passed : false,
|
||||
actual : actual,
|
||||
negate : negate,
|
||||
matcher : matcher,
|
||||
expected : expected,
|
||||
|
||||
// Report assertion results
|
||||
|
||||
report : function() {
|
||||
this.passed ? JSpec.stats.passes++ : JSpec.stats.failures++
|
||||
return this
|
||||
},
|
||||
|
||||
// Run the assertion
|
||||
|
||||
run : function() {
|
||||
// TODO: remove unshifting
|
||||
expected.unshift(actual)
|
||||
this.result = matcher.match.apply(this, expected)
|
||||
this.passed = negate ? !this.result : this.result
|
||||
if (!this.passed) this.message = matcher.message.call(this, actual, expected, negate, matcher.name)
|
||||
return this
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
ProxyAssertion : function(object, method, times, negate) {
|
||||
var self = this
|
||||
var old = object[method]
|
||||
|
||||
// Proxy
|
||||
|
||||
object[method] = function(){
|
||||
args = argumentsToArray(arguments)
|
||||
result = old.apply(object, args)
|
||||
self.calls.push({ args : args, result : result })
|
||||
return result
|
||||
}
|
||||
|
||||
// Times
|
||||
|
||||
this.times = {
|
||||
'once' : 1,
|
||||
'twice' : 2
|
||||
}[times] || times || 1
|
||||
|
||||
extend(this, {
|
||||
calls : [],
|
||||
message : '',
|
||||
defer : true,
|
||||
passed : false,
|
||||
negate : negate,
|
||||
object : object,
|
||||
method : method,
|
||||
|
||||
// Proxy return value
|
||||
|
||||
and_return : function(result) {
|
||||
this.expectedResult = result
|
||||
return this
|
||||
},
|
||||
|
||||
// Proxy arguments passed
|
||||
|
||||
with_args : function() {
|
||||
this.expectedArgs = argumentsToArray(arguments)
|
||||
return this
|
||||
},
|
||||
|
||||
// Check if any calls have failing results
|
||||
|
||||
anyResultsFail : function() {
|
||||
return any(this.calls, function(call){
|
||||
return self.expectedResult.an_instance_of ?
|
||||
call.result.constructor != self.expectedResult.an_instance_of:
|
||||
hash(self.expectedResult) != hash(call.result)
|
||||
})
|
||||
},
|
||||
|
||||
// Check if any calls have passing results
|
||||
|
||||
anyResultsPass : function() {
|
||||
return any(this.calls, function(call){
|
||||
return self.expectedResult.an_instance_of ?
|
||||
call.result.constructor == self.expectedResult.an_instance_of:
|
||||
hash(self.expectedResult) == hash(call.result)
|
||||
})
|
||||
},
|
||||
|
||||
// Return the passing result
|
||||
|
||||
passingResult : function() {
|
||||
return this.anyResultsPass().result
|
||||
},
|
||||
|
||||
// Return the failing result
|
||||
|
||||
failingResult : function() {
|
||||
return this.anyResultsFail().result
|
||||
},
|
||||
|
||||
// Check if any arguments fail
|
||||
|
||||
anyArgsFail : function() {
|
||||
return any(this.calls, function(call){
|
||||
return any(self.expectedArgs, function(i, arg){
|
||||
if (arg == null) return call.args[i] == null
|
||||
return arg.an_instance_of ?
|
||||
call.args[i].constructor != arg.an_instance_of:
|
||||
hash(arg) != hash(call.args[i])
|
||||
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// Check if any arguments pass
|
||||
|
||||
anyArgsPass : function() {
|
||||
return any(this.calls, function(call){
|
||||
return any(self.expectedArgs, function(i, arg){
|
||||
return arg.an_instance_of ?
|
||||
call.args[i].constructor == arg.an_instance_of:
|
||||
hash(arg) == hash(call.args[i])
|
||||
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// Return the passing args
|
||||
|
||||
passingArgs : function() {
|
||||
return this.anyArgsPass().args
|
||||
},
|
||||
|
||||
// Return the failing args
|
||||
|
||||
failingArgs : function() {
|
||||
return this.anyArgsFail().args
|
||||
},
|
||||
|
||||
// Report assertion results
|
||||
|
||||
report : function() {
|
||||
this.passed ? JSpec.stats.passes++ : JSpec.stats.failures++
|
||||
return this
|
||||
},
|
||||
|
||||
// Run the assertion
|
||||
|
||||
run : function() {
|
||||
var methodString = 'expected ' + object.toString() + '.' + method + '()' + (negate ? ' not' : '' )
|
||||
|
||||
function times(n) {
|
||||
return n > 2 ? n + ' times' : { 1 : 'once', 2 : 'twice' }[n]
|
||||
}
|
||||
|
||||
if (this.expectedResult != null && (negate ? this.anyResultsPass() : this.anyResultsFail()))
|
||||
this.message = methodString + ' to return ' + puts(this.expectedResult) +
|
||||
' but ' + (negate ? 'it did' : 'got ' + puts(this.failingResult()))
|
||||
|
||||
if (this.expectedArgs && (negate ? !this.expectedResult && this.anyArgsPass() : this.anyArgsFail()))
|
||||
this.message = methodString + ' to be called with ' + puts.apply(this, this.expectedArgs) +
|
||||
' but was' + (negate ? '' : ' called with ' + puts.apply(this, this.failingArgs()))
|
||||
|
||||
if (negate ? !this.expectedResult && !this.expectedArgs && this.calls.length == this.times : this.calls.length != this.times)
|
||||
this.message = methodString + ' to be called ' + times(this.times) +
|
||||
', but ' + (this.calls.length == 0 ? ' was not called' : ' was called ' + times(this.calls.length))
|
||||
|
||||
if (!this.message.length)
|
||||
this.passed = true
|
||||
|
||||
return this
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Specification Suite block object.
|
||||
*
|
||||
* @param {string} description
|
||||
* @param {function} body
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Suite : function(description, body) {
|
||||
var self = this
|
||||
extend(this, {
|
||||
body: body,
|
||||
description: description,
|
||||
suites: [],
|
||||
specs: [],
|
||||
ran: false,
|
||||
hooks: { 'before' : [], 'after' : [], 'before_each' : [], 'after_each' : [] },
|
||||
|
||||
// Add a spec to the suite
|
||||
|
||||
addSpec : function(description, body) {
|
||||
var spec = new JSpec.Spec(description, body)
|
||||
this.specs.push(spec)
|
||||
JSpec.stats.specs++ // TODO: abstract
|
||||
spec.suite = this
|
||||
},
|
||||
|
||||
// Add a hook to the suite
|
||||
|
||||
addHook : function(hook, body) {
|
||||
this.hooks[hook].push(body)
|
||||
},
|
||||
|
||||
// Add a nested suite
|
||||
|
||||
addSuite : function(description, body) {
|
||||
var suite = new JSpec.Suite(description, body)
|
||||
JSpec.allSuites.push(suite)
|
||||
suite.name = suite.description
|
||||
suite.description = this.description + ' ' + suite.description
|
||||
this.suites.push(suite)
|
||||
suite.suite = this
|
||||
},
|
||||
|
||||
// Invoke a hook in context to this suite
|
||||
|
||||
hook : function(hook) {
|
||||
if (this.suite) this.suite.hook(hook)
|
||||
each(this.hooks[hook], function(body) {
|
||||
JSpec.evalBody(body, "Error in hook '" + hook + "', suite '" + self.description + "': ")
|
||||
})
|
||||
},
|
||||
|
||||
// Check if nested suites are present
|
||||
|
||||
hasSuites : function() {
|
||||
return this.suites.length
|
||||
},
|
||||
|
||||
// Check if this suite has specs
|
||||
|
||||
hasSpecs : function() {
|
||||
return this.specs.length
|
||||
},
|
||||
|
||||
// Check if the entire suite passed
|
||||
|
||||
passed : function() {
|
||||
return !any(this.specs, function(spec){
|
||||
return !spec.passed()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Specification block object.
|
||||
*
|
||||
* @param {string} description
|
||||
* @param {function} body
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Spec : function(description, body) {
|
||||
extend(this, {
|
||||
body : body,
|
||||
description : description,
|
||||
assertions : [],
|
||||
|
||||
// Add passing assertion
|
||||
|
||||
pass : function(message) {
|
||||
this.assertions.push({ passed : true, message : message })
|
||||
++JSpec.stats.passes
|
||||
},
|
||||
|
||||
// Add failing assertion
|
||||
|
||||
fail : function(message) {
|
||||
this.assertions.push({ passed : false, message : message })
|
||||
++JSpec.stats.failures
|
||||
},
|
||||
|
||||
// Run deferred assertions
|
||||
|
||||
runDeferredAssertions : function() {
|
||||
each(this.assertions, function(assertion){
|
||||
if (assertion.defer) assertion.run().report(), hook('afterAssertion', assertion)
|
||||
})
|
||||
},
|
||||
|
||||
// Find first failing assertion
|
||||
|
||||
failure : function() {
|
||||
return find(this.assertions, function(assertion){
|
||||
return !assertion.passed
|
||||
})
|
||||
},
|
||||
|
||||
// Find all failing assertions
|
||||
|
||||
failures : function() {
|
||||
return select(this.assertions, function(assertion){
|
||||
return !assertion.passed
|
||||
})
|
||||
},
|
||||
|
||||
// Weither or not the spec passed
|
||||
|
||||
passed : function() {
|
||||
return !this.failure()
|
||||
},
|
||||
|
||||
// Weither or not the spec requires implementation (no assertions)
|
||||
|
||||
requiresImplementation : function() {
|
||||
return this.assertions.length == 0
|
||||
},
|
||||
|
||||
// Sprite based assertions graph
|
||||
|
||||
assertionsGraph : function() {
|
||||
return map(this.assertions, function(assertion){
|
||||
return '<span class="assertion ' + (assertion.passed ? 'passed' : 'failed') + '"></span>'
|
||||
}).join('')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
Module : function(methods) {
|
||||
extend(this, methods)
|
||||
},
|
||||
|
||||
// --- DSLs
|
||||
|
||||
DSLs : {
|
||||
snake : {
|
||||
expect : function(actual){
|
||||
return JSpec.expect(actual)
|
||||
},
|
||||
|
||||
describe : function(description, body) {
|
||||
return JSpec.currentSuite.addSuite(description, body)
|
||||
},
|
||||
|
||||
it : function(description, body) {
|
||||
return JSpec.currentSuite.addSpec(description, body)
|
||||
},
|
||||
|
||||
before : function(body) {
|
||||
return JSpec.currentSuite.addHook('before', body)
|
||||
},
|
||||
|
||||
after : function(body) {
|
||||
return JSpec.currentSuite.addHook('after', body)
|
||||
},
|
||||
|
||||
before_each : function(body) {
|
||||
return JSpec.currentSuite.addHook('before_each', body)
|
||||
},
|
||||
|
||||
after_each : function(body) {
|
||||
return JSpec.currentSuite.addHook('after_each', body)
|
||||
},
|
||||
|
||||
should_behave_like : function(description) {
|
||||
return JSpec.shareBehaviorsOf(description)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// --- Methods
|
||||
|
||||
/**
|
||||
* Check if _value_ is 'stop'. For use as a
|
||||
* utility callback function.
|
||||
*
|
||||
* @param {mixed} value
|
||||
* @return {bool}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
haveStopped : function(value) {
|
||||
return value === 'stop'
|
||||
},
|
||||
|
||||
/**
|
||||
* Include _object_ which may be a hash or Module instance.
|
||||
*
|
||||
* @param {has, Module} object
|
||||
* @return {JSpec}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
include : function(object) {
|
||||
var module = object.constructor == JSpec.Module ? object : new JSpec.Module(object)
|
||||
this.modules.push(module)
|
||||
if ('init' in module) module.init()
|
||||
if ('utilities' in module) extend(this.defaultContext, module.utilities)
|
||||
if ('matchers' in module) this.addMatchers(module.matchers)
|
||||
if ('DSLs' in module)
|
||||
each(module.DSLs, function(name, methods){
|
||||
JSpec.DSLs[name] = JSpec.DSLs[name] || {}
|
||||
extend(JSpec.DSLs[name], methods)
|
||||
})
|
||||
return this
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a module hook _name_, which is immediately
|
||||
* called per module with the _args_ given. An array of
|
||||
* hook return values is returned.
|
||||
*
|
||||
* @param {name} string
|
||||
* @param {...} args
|
||||
* @return {array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
hook : function(name, args) {
|
||||
args = argumentsToArray(arguments, 1)
|
||||
return inject(JSpec.modules, [], function(results, module){
|
||||
if (typeof module[name] == 'function')
|
||||
results.push(JSpec.evalHook(module, name, args))
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Eval _module_ hook _name_ with _args_. Evaluates in context
|
||||
* to the module itself, JSpec, and JSpec.context.
|
||||
*
|
||||
* @param {Module} module
|
||||
* @param {string} name
|
||||
* @param {array} args
|
||||
* @return {mixed}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
evalHook : function(module, name, args) {
|
||||
var context = this.context || this.defaultContext
|
||||
var contents = this.contentsOf(module[name])
|
||||
var params = this.paramsFor(module[name])
|
||||
module.utilities = module.utilities || {}
|
||||
params.unshift('context'); args.unshift(context)
|
||||
hook('evaluatingHookBody', module, name, context)
|
||||
try { return new Function(params.join(), 'with (this.utilities) { with (context) { with (JSpec) { ' + contents + ' }}}').apply(module, args) }
|
||||
catch(e) { error('Error in hook ' + module.name + "." + name + ': ', e) }
|
||||
},
|
||||
|
||||
/**
|
||||
* Same as hook() however accepts only one _arg_ which is
|
||||
* considered immutable. This function passes the arg
|
||||
* to the first module, then passes the return value of the last
|
||||
* module called, to the following module.
|
||||
*
|
||||
* @param {string} name
|
||||
* @param {mixed} arg
|
||||
* @return {mixed}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
hookImmutable : function(name, arg) {
|
||||
return inject(JSpec.modules, arg, function(result, module){
|
||||
if (typeof module[name] == 'function')
|
||||
return JSpec.evalHook(module, name, [result])
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Find a suite by its description or name.
|
||||
*
|
||||
* @param {string} description
|
||||
* @return {Suite}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
findSuite : function(description) {
|
||||
return find(this.allSuites, function(suite){
|
||||
return suite.name == description || suite.description == description
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Share behaviors (specs) of the given suite with
|
||||
* the current suite.
|
||||
*
|
||||
* @param {string} description
|
||||
* @api public
|
||||
*/
|
||||
|
||||
shareBehaviorsOf : function(description) {
|
||||
if (suite = this.findSuite(description)) this.copySpecs(suite, this.currentSuite)
|
||||
else throw 'failed to share behaviors. ' + puts(description) + ' is not a valid Suite name'
|
||||
},
|
||||
|
||||
/**
|
||||
* Copy specs from one suite to another.
|
||||
*
|
||||
* @param {Suite} fromSuite
|
||||
* @param {Suite} toSuite
|
||||
* @api public
|
||||
*/
|
||||
|
||||
copySpecs : function(fromSuite, toSuite) {
|
||||
each(fromSuite.specs, function(spec){
|
||||
spec.assertions = []
|
||||
toSuite.specs.push(spec)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert arguments to an array.
|
||||
*
|
||||
* @param {object} arguments
|
||||
* @param {int} offset
|
||||
* @return {array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
argumentsToArray : function(arguments, offset) {
|
||||
return Array.prototype.slice.call(arguments, offset || 0)
|
||||
},
|
||||
|
||||
/**
|
||||
* Return ANSI-escaped colored string.
|
||||
*
|
||||
* @param {string} string
|
||||
* @param {string} color
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
color : function(string, color) {
|
||||
return "\u001B[" + {
|
||||
bold : 1,
|
||||
black : 30,
|
||||
red : 31,
|
||||
green : 32,
|
||||
yellow : 33,
|
||||
blue : 34,
|
||||
magenta : 35,
|
||||
cyan : 36,
|
||||
white : 37
|
||||
}[color] + 'm' + string + "\u001B[0m"
|
||||
},
|
||||
|
||||
/**
|
||||
* Default matcher message callback.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
defaultMatcherMessage : function(actual, expected, negate, name) {
|
||||
return 'expected ' + puts(actual) + ' to ' +
|
||||
(negate ? 'not ' : '') +
|
||||
name.replace(/_/g, ' ') +
|
||||
' ' + puts.apply(this, expected.slice(1))
|
||||
},
|
||||
|
||||
/**
|
||||
* Normalize a matcher message.
|
||||
*
|
||||
* When no messge callback is present the defaultMatcherMessage
|
||||
* will be assigned, will suffice for most matchers.
|
||||
*
|
||||
* @param {hash} matcher
|
||||
* @return {hash}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
normalizeMatcherMessage : function(matcher) {
|
||||
if (typeof matcher.message != 'function')
|
||||
matcher.message = this.defaultMatcherMessage
|
||||
return matcher
|
||||
},
|
||||
|
||||
/**
|
||||
* Normalize a matcher body
|
||||
*
|
||||
* This process allows the following conversions until
|
||||
* the matcher is in its final normalized hash state.
|
||||
*
|
||||
* - '==' becomes 'actual == expected'
|
||||
* - 'actual == expected' becomes 'return actual == expected'
|
||||
* - function(actual, expected) { return actual == expected } becomes
|
||||
* { match : function(actual, expected) { return actual == expected }}
|
||||
*
|
||||
* @param {mixed} body
|
||||
* @return {hash}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
normalizeMatcherBody : function(body) {
|
||||
switch (body.constructor) {
|
||||
case String:
|
||||
if (captures = body.match(/^alias (\w+)/)) return JSpec.matchers[last(captures)]
|
||||
if (body.length < 4) body = 'actual ' + body + ' expected'
|
||||
return { match : function(actual, expected) { return eval(body) }}
|
||||
|
||||
case Function:
|
||||
return { match : body }
|
||||
|
||||
default:
|
||||
return body
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get option value. This method first checks if
|
||||
* the option key has been set via the query string,
|
||||
* otherwise returning the options hash value.
|
||||
*
|
||||
* @param {string} key
|
||||
* @return {mixed}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
option : function(key) {
|
||||
return (value = query(key)) !== null ? value :
|
||||
JSpec.options[key] || null
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates a hash of the object passed.
|
||||
*
|
||||
* @param {object} object
|
||||
* @return {string}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
hash : function(object) {
|
||||
if (object == null) return 'null'
|
||||
if (object == undefined) return 'undefined'
|
||||
serialize = function(prefix) {
|
||||
return inject(object, prefix + ':', function(buffer, key, value){
|
||||
return buffer += hash(value)
|
||||
})
|
||||
}
|
||||
switch (object.constructor) {
|
||||
case Array : return serialize('a')
|
||||
case RegExp: return 'r:' + object.toString()
|
||||
case Number: return 'n:' + object.toString()
|
||||
case String: return 's:' + object.toString()
|
||||
case Object: return 'o:' + inject(object, [], function(array, key, value){
|
||||
array.push([key, hash(value)])
|
||||
}).sort()
|
||||
default: return object.toString()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return last element of an array.
|
||||
*
|
||||
* @param {array} array
|
||||
* @return {object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
last : function(array) {
|
||||
return array[array.length - 1]
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert object(s) to a print-friend string.
|
||||
*
|
||||
* @param {...} object
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
puts : function(object) {
|
||||
if (arguments.length > 1) {
|
||||
return map(argumentsToArray(arguments), function(arg){
|
||||
return puts(arg)
|
||||
}).join(', ')
|
||||
}
|
||||
if (object === undefined) return ''
|
||||
if (object === null) return 'null'
|
||||
if (object === true) return 'true'
|
||||
if (object === false) return 'false'
|
||||
if (object.an_instance_of) return 'an instance of ' + object.an_instance_of.name
|
||||
if (object.jquery && object.selector.length > 0) return 'selector ' + puts(object.selector) + ''
|
||||
if (object.jquery) return escape(object.html())
|
||||
if (object.nodeName) return escape(object.outerHTML)
|
||||
switch (object.constructor) {
|
||||
case String: return "'" + escape(object) + "'"
|
||||
case Number: return object
|
||||
case Function: return object.name || object
|
||||
case Array :
|
||||
return inject(object, '[', function(b, v){
|
||||
return b + ', ' + puts(v)
|
||||
}).replace('[,', '[') + ' ]'
|
||||
case Object:
|
||||
return inject(object, '{', function(b, k, v) {
|
||||
return b + ', ' + puts(k) + ' : ' + puts(v)
|
||||
}).replace('{,', '{') + ' }'
|
||||
default:
|
||||
return escape(object.toString())
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Escape HTML.
|
||||
*
|
||||
* @param {string} html
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
escape : function(html) {
|
||||
return html.toString().
|
||||
replace(/&/gmi, '&').
|
||||
replace(/"/gmi, '"').
|
||||
replace(/>/gmi, '>').
|
||||
replace(/</gmi, '<')
|
||||
},
|
||||
|
||||
/**
|
||||
* Perform an assertion without reporting.
|
||||
*
|
||||
* This method is primarily used for internal
|
||||
* matchers in order retain DRYness. May be invoked
|
||||
* like below:
|
||||
*
|
||||
* does('foo', 'eql', 'foo')
|
||||
* does([1,2], 'include', 1, 2)
|
||||
*
|
||||
* External hooks are not run for internal assertions
|
||||
* performed by does().
|
||||
*
|
||||
* @param {mixed} actual
|
||||
* @param {string} matcher
|
||||
* @param {...} expected
|
||||
* @return {mixed}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
does : function(actual, matcher, expected) {
|
||||
var assertion = new JSpec.Assertion(JSpec.matchers[matcher], actual, argumentsToArray(arguments, 2))
|
||||
return assertion.run().result
|
||||
},
|
||||
|
||||
/**
|
||||
* Perform an assertion.
|
||||
*
|
||||
* expect(true).to('be', true)
|
||||
* expect('foo').not_to('include', 'bar')
|
||||
* expect([1, [2]]).to('include', 1, [2])
|
||||
*
|
||||
* @param {mixed} actual
|
||||
* @return {hash}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
expect : function(actual) {
|
||||
assert = function(matcher, args, negate) {
|
||||
var expected = argumentsToArray(args, 1)
|
||||
matcher.negate = negate
|
||||
assertion = new JSpec.Assertion(matcher, actual, expected, negate)
|
||||
hook('beforeAssertion', assertion)
|
||||
if (matcher.defer) assertion.run()
|
||||
else JSpec.currentSpec.assertions.push(assertion.run().report()), hook('afterAssertion', assertion)
|
||||
return assertion.result
|
||||
}
|
||||
|
||||
to = function(matcher) {
|
||||
return assert(matcher, arguments, false)
|
||||
}
|
||||
|
||||
not_to = function(matcher) {
|
||||
return assert(matcher, arguments, true)
|
||||
}
|
||||
|
||||
return {
|
||||
to : to,
|
||||
should : to,
|
||||
not_to: not_to,
|
||||
should_not : not_to
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Strim whitespace or chars.
|
||||
*
|
||||
* @param {string} string
|
||||
* @param {string} chars
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
strip : function(string, chars) {
|
||||
return string.
|
||||
replace(new RegExp('[' + (chars || '\\s') + ']*$'), '').
|
||||
replace(new RegExp('^[' + (chars || '\\s') + ']*'), '')
|
||||
},
|
||||
|
||||
/**
|
||||
* Call an iterator callback with arguments a, or b
|
||||
* depending on the arity of the callback.
|
||||
*
|
||||
* @param {function} callback
|
||||
* @param {mixed} a
|
||||
* @param {mixed} b
|
||||
* @return {mixed}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
callIterator : function(callback, a, b) {
|
||||
return callback.length == 1 ? callback(b) : callback(a, b)
|
||||
},
|
||||
|
||||
/**
|
||||
* Extend an object with another.
|
||||
*
|
||||
* @param {object} object
|
||||
* @param {object} other
|
||||
* @api public
|
||||
*/
|
||||
|
||||
extend : function(object, other) {
|
||||
each(other, function(property, value){
|
||||
object[property] = value
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Iterate an object, invoking the given callback.
|
||||
*
|
||||
* @param {hash, array, string} object
|
||||
* @param {function} callback
|
||||
* @return {JSpec}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
each : function(object, callback) {
|
||||
if (typeof object == 'string') object = object.split(' ')
|
||||
for (key in object)
|
||||
if (object.hasOwnProperty(key))
|
||||
callIterator(callback, key, object[key])
|
||||
},
|
||||
|
||||
/**
|
||||
* Iterate with memo.
|
||||
*
|
||||
* @param {hash, array} object
|
||||
* @param {object} memo
|
||||
* @param {function} callback
|
||||
* @return {object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
inject : function(object, memo, callback) {
|
||||
each(object, function(key, value){
|
||||
memo = (callback.length == 2 ?
|
||||
callback(memo, value):
|
||||
callback(memo, key, value)) ||
|
||||
memo
|
||||
})
|
||||
return memo
|
||||
},
|
||||
|
||||
/**
|
||||
* Destub _object_'s _method_. When no _method_ is passed
|
||||
* all stubbed methods are destubbed. When no arguments
|
||||
* are passed every object found in JSpec.stubbed will be
|
||||
* destubbed.
|
||||
*
|
||||
* @param {mixed} object
|
||||
* @param {string} method
|
||||
* @api public
|
||||
*/
|
||||
|
||||
destub : function(object, method) {
|
||||
if (method) {
|
||||
if (object['__prototype__' + method])
|
||||
delete object[method]
|
||||
else
|
||||
object[method] = object['__original__' + method]
|
||||
delete object['__prototype__' + method]
|
||||
delete object['__original____' + method]
|
||||
}
|
||||
else if (object) {
|
||||
for (var key in object)
|
||||
if (captures = key.match(/^(?:__prototype__|__original__)(.*)/))
|
||||
destub(object, captures[1])
|
||||
}
|
||||
else
|
||||
while (JSpec.stubbed.length)
|
||||
destub(JSpec.stubbed.shift())
|
||||
},
|
||||
|
||||
/**
|
||||
* Stub _object_'s _method_.
|
||||
*
|
||||
* stub(foo, 'toString').and_return('bar')
|
||||
*
|
||||
* @param {mixed} object
|
||||
* @param {string} method
|
||||
* @return {hash}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
stub : function(object, method) {
|
||||
hook('stubbing', object, method)
|
||||
JSpec.stubbed.push(object)
|
||||
var type = object.hasOwnProperty(method) ? '__original__' : '__prototype__'
|
||||
object[type + method] = object[method]
|
||||
object[method] = function(){}
|
||||
return {
|
||||
and_return : function(value) {
|
||||
if (typeof value == 'function') object[method] = value
|
||||
else object[method] = function(){ return value }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Map callback return values.
|
||||
*
|
||||
* @param {hash, array} object
|
||||
* @param {function} callback
|
||||
* @return {array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
map : function(object, callback) {
|
||||
return inject(object, [], function(memo, key, value){
|
||||
memo.push(callIterator(callback, key, value))
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the first matching expression or null.
|
||||
*
|
||||
* @param {hash, array} object
|
||||
* @param {function} callback
|
||||
* @return {mixed}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
any : function(object, callback) {
|
||||
return inject(object, null, function(state, key, value){
|
||||
if (state == undefined)
|
||||
return callIterator(callback, key, value) ? value : state
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an array of values collected when the callback
|
||||
* given evaluates to true.
|
||||
*
|
||||
* @param {hash, array} object
|
||||
* @return {function} callback
|
||||
* @return {array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
select : function(object, callback) {
|
||||
return inject(object, [], function(selected, key, value){
|
||||
if (callIterator(callback, key, value))
|
||||
selected.push(value)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Define matchers.
|
||||
*
|
||||
* @param {hash} matchers
|
||||
* @api public
|
||||
*/
|
||||
|
||||
addMatchers : function(matchers) {
|
||||
each(matchers, function(name, body){
|
||||
JSpec.addMatcher(name, body)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Define a matcher.
|
||||
*
|
||||
* @param {string} name
|
||||
* @param {hash, function, string} body
|
||||
* @api public
|
||||
*/
|
||||
|
||||
addMatcher : function(name, body) {
|
||||
hook('addingMatcher', name, body)
|
||||
if (name.indexOf(' ') != -1) {
|
||||
var matchers = name.split(/\s+/)
|
||||
var prefix = matchers.shift()
|
||||
each(matchers, function(name) {
|
||||
JSpec.addMatcher(prefix + '_' + name, body(name))
|
||||
})
|
||||
}
|
||||
this.matchers[name] = this.normalizeMatcherMessage(this.normalizeMatcherBody(body))
|
||||
this.matchers[name].name = name
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a root suite to JSpec.
|
||||
*
|
||||
* @param {string} description
|
||||
* @param {body} function
|
||||
* @api public
|
||||
*/
|
||||
|
||||
describe : function(description, body) {
|
||||
var suite = new JSpec.Suite(description, body)
|
||||
hook('addingSuite', suite)
|
||||
this.allSuites.push(suite)
|
||||
this.suites.push(suite)
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the contents of a function body.
|
||||
*
|
||||
* @param {function} body
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
contentsOf : function(body) {
|
||||
return body.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1]
|
||||
},
|
||||
|
||||
/**
|
||||
* Return param names for a function body.
|
||||
*
|
||||
* @param {function} body
|
||||
* @return {array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
paramsFor : function(body) {
|
||||
return body.toString().match(/\((.*?)\)/)[1].match(/[\w]+/g) || []
|
||||
},
|
||||
|
||||
/**
|
||||
* Evaluate a JSpec capture body.
|
||||
*
|
||||
* @param {function} body
|
||||
* @param {string} errorMessage (optional)
|
||||
* @return {Type}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
evalBody : function(body, errorMessage) {
|
||||
var dsl = this.DSL || this.DSLs.snake
|
||||
var matchers = this.matchers
|
||||
var context = this.context || this.defaultContext
|
||||
var contents = this.contentsOf(body)
|
||||
hook('evaluatingBody', dsl, matchers, context, contents)
|
||||
try { eval('with (dsl){ with (context) { with (matchers) { ' + contents + ' }}}') }
|
||||
catch(e) { error(errorMessage, e) }
|
||||
},
|
||||
|
||||
/**
|
||||
* Pre-process a string of JSpec.
|
||||
*
|
||||
* @param {string} input
|
||||
* @return {string}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
preprocess : function(input) {
|
||||
input = hookImmutable('preprocessing', input)
|
||||
return input.
|
||||
replace(/([\w\.]+)\.(stub|destub)\((.*?)\)$/gm, '$2($1, $3)').
|
||||
replace(/describe\s+(.*?)$/gm, 'describe($1, function(){').
|
||||
replace(/^\s+it\s+(.*?)$/gm, ' it($1, function(){').
|
||||
replace(/^(?: *)(before_each|after_each|before|after)(?= |\n|$)/gm, 'JSpec.currentSuite.addHook("$1", function(){').
|
||||
replace(/^\s*end(?=\s|$)/gm, '});').
|
||||
replace(/-\{/g, 'function(){').
|
||||
replace(/(\d+)\.\.(\d+)/g, function(_, a, b){ return range(a, b) }).
|
||||
replace(/\.should([_\.]not)?[_\.](\w+)(?: |;|$)(.*)$/gm, '.should$1_$2($3)').
|
||||
replace(/([\/\s]*)(.+?)\.(should(?:[_\.]not)?)[_\.](\w+)\((.*)\)\s*;?$/gm, '$1 expect($2).$3($4, $5)').
|
||||
replace(/, \)/gm, ')').
|
||||
replace(/should\.not/gm, 'should_not')
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a range string which can be evaluated to a native array.
|
||||
*
|
||||
* @param {int} start
|
||||
* @param {int} end
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
range : function(start, end) {
|
||||
var current = parseInt(start), end = parseInt(end), values = [current]
|
||||
if (end > current) while (++current <= end) values.push(current)
|
||||
else while (--current >= end) values.push(current)
|
||||
return '[' + values + ']'
|
||||
},
|
||||
|
||||
/**
|
||||
* Report on the results.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
report : function() {
|
||||
hook('reporting', JSpec.options)
|
||||
new (JSpec.options.formatter || JSpec.formatters.DOM)(JSpec, JSpec.options)
|
||||
},
|
||||
|
||||
/**
|
||||
* Run the spec suites. Options are merged
|
||||
* with JSpec options when present.
|
||||
*
|
||||
* @param {hash} options
|
||||
* @return {JSpec}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
run : function(options) {
|
||||
if (any(hook('running'), haveStopped)) return this
|
||||
if (options) extend(this.options, options)
|
||||
if (option('profile')) console.group('Profile')
|
||||
each(this.suites, function(suite) { JSpec.runSuite(suite) })
|
||||
if (option('profile')) console.groupEnd()
|
||||
return this
|
||||
},
|
||||
|
||||
/**
|
||||
* Run a suite.
|
||||
*
|
||||
* @param {Suite} suite
|
||||
* @api public
|
||||
*/
|
||||
|
||||
runSuite : function(suite) {
|
||||
this.currentSuite = suite
|
||||
this.evalBody(suite.body)
|
||||
suite.ran = true
|
||||
hook('beforeSuite', suite), suite.hook('before')
|
||||
each(suite.specs, function(spec) {
|
||||
hook('beforeSpec', spec)
|
||||
suite.hook('before_each')
|
||||
JSpec.runSpec(spec)
|
||||
hook('afterSpec', spec)
|
||||
suite.hook('after_each')
|
||||
})
|
||||
if (suite.hasSuites()) {
|
||||
each(suite.suites, function(suite) {
|
||||
JSpec.runSuite(suite)
|
||||
})
|
||||
}
|
||||
hook('afterSuite', suite), suite.hook('after')
|
||||
this.stats.suitesFinished++
|
||||
},
|
||||
|
||||
/**
|
||||
* Report a failure for the current spec.
|
||||
*
|
||||
* @param {string} message
|
||||
* @api public
|
||||
*/
|
||||
|
||||
fail : function(message) {
|
||||
JSpec.currentSpec.fail(message)
|
||||
},
|
||||
|
||||
/**
|
||||
* Report a passing assertion for the current spec.
|
||||
*
|
||||
* @param {string} message
|
||||
* @api public
|
||||
*/
|
||||
|
||||
pass : function(message) {
|
||||
JSpec.currentSpec.pass(message)
|
||||
},
|
||||
|
||||
/**
|
||||
* Run a spec.
|
||||
*
|
||||
* @param {Spec} spec
|
||||
* @api public
|
||||
*/
|
||||
|
||||
runSpec : function(spec) {
|
||||
this.currentSpec = spec
|
||||
if (option('profile')) console.time(spec.description)
|
||||
try { this.evalBody(spec.body) }
|
||||
catch (e) { fail(e) }
|
||||
if (option('profile')) console.timeEnd(spec.description)
|
||||
spec.runDeferredAssertions()
|
||||
destub()
|
||||
this.stats.specsFinished++
|
||||
this.stats.assertions += spec.assertions.length
|
||||
},
|
||||
|
||||
/**
|
||||
* Require a dependency, with optional message.
|
||||
*
|
||||
* @param {string} dependency
|
||||
* @param {string} message (optional)
|
||||
* @return {JSpec}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
requires : function(dependency, message) {
|
||||
hook('requiring', dependency, message)
|
||||
try { eval(dependency) }
|
||||
catch (e) { throw 'JSpec depends on ' + dependency + ' ' + message }
|
||||
return this
|
||||
},
|
||||
|
||||
/**
|
||||
* Query against the current query strings keys
|
||||
* or the queryString specified.
|
||||
*
|
||||
* @param {string} key
|
||||
* @param {string} queryString
|
||||
* @return {string, null}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
query : function(key, queryString) {
|
||||
var queryString = (queryString || (main.location ? main.location.search : null) || '').substring(1)
|
||||
return inject(queryString.split('&'), null, function(value, pair){
|
||||
parts = pair.split('=')
|
||||
return parts[0] == key ? parts[1].replace(/%20|\+/gmi, ' ') : value
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Throw a JSpec related error.
|
||||
*
|
||||
* @param {string} message
|
||||
* @param {Exception} e
|
||||
* @api public
|
||||
*/
|
||||
|
||||
error : function(message, e) {
|
||||
throw (message ? message : '') + e.toString() +
|
||||
(e.line ? ' near line ' + e.line : '')
|
||||
},
|
||||
|
||||
/**
|
||||
* Ad-hoc POST request for JSpec server usage.
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {string} data
|
||||
* @api private
|
||||
*/
|
||||
|
||||
post : function(url, data) {
|
||||
if (any(hook('posting', url, data), haveStopped)) return
|
||||
var request = this.xhr()
|
||||
request.open('POST', url, false)
|
||||
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
|
||||
request.send(data)
|
||||
},
|
||||
|
||||
/**
|
||||
* Report to server with statistics.
|
||||
*
|
||||
* @param {string} url
|
||||
* @api private
|
||||
*/
|
||||
|
||||
reportToServer : function(url) {
|
||||
if (any(hook('reportingToServer', url), haveStopped)) return
|
||||
JSpec.post(url || 'http://localhost:4444', 'passes=' + JSpec.stats.passes + '&failures=' + JSpec.stats.failures)
|
||||
if ('close' in main) main.close()
|
||||
},
|
||||
|
||||
/**
|
||||
* Instantiate an XMLHttpRequest.
|
||||
*
|
||||
* @return {XMLHttpRequest, ActiveXObject}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
xhr : function() {
|
||||
return new (JSpec.request || ActiveXObject("Microsoft.XMLHTTP"))
|
||||
},
|
||||
|
||||
/**
|
||||
* Check for HTTP request support.
|
||||
*
|
||||
* @return {bool}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
hasXhr : function() {
|
||||
return JSpec.request || 'ActiveXObject' in main
|
||||
},
|
||||
|
||||
/**
|
||||
* Try loading _file_ returning the contents
|
||||
* string or null. Chain to locate / read a file.
|
||||
*
|
||||
* @param {string} file
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
tryLoading : function(file) {
|
||||
try { return JSpec.load(file) }
|
||||
catch (e) {}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load a _file_'s contents.
|
||||
*
|
||||
* @param {string} file
|
||||
* @param {function} callback
|
||||
* @return {string}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
load : function(file, callback) {
|
||||
if (any(hook('loading', file), haveStopped)) return
|
||||
if ('readFile' in main)
|
||||
return callback ? readFile(file, callback) : readFile(file)
|
||||
else if (this.hasXhr()) {
|
||||
var request = this.xhr()
|
||||
request.open('GET', file, false)
|
||||
request.send(null)
|
||||
if (request.readyState == 4) return request.responseText
|
||||
}
|
||||
else
|
||||
error("failed to load `" + file + "'")
|
||||
},
|
||||
|
||||
/**
|
||||
* Load, pre-process, and evaluate a file.
|
||||
*
|
||||
* @param {string} file
|
||||
* @param {JSpec}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exec : function(file) {
|
||||
if (any(hook('executing', file), haveStopped)) return this
|
||||
if ('node' in main)
|
||||
this.load(file, function(contents){
|
||||
eval('with (JSpec){ ' + JSpec.preprocess(contents) + ' }')
|
||||
})
|
||||
else
|
||||
eval('with (JSpec){' + this.preprocess(this.load(file)) + '}')
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
// --- Utility functions
|
||||
|
||||
var main = this
|
||||
var find = JSpec.any
|
||||
var utils = 'haveStopped stub hookImmutable hook destub map any last pass fail range each option inject select \
|
||||
error escape extend puts hash query strip color does addMatchers callIterator argumentsToArray'.split(/\s+/)
|
||||
while (utils.length) util = utils.shift(), eval('var ' + util + ' = JSpec.' + util)
|
||||
if (!main.setTimeout) main.setTimeout = function(callback){ callback() }
|
||||
|
||||
// --- Matchers
|
||||
|
||||
addMatchers({
|
||||
equal : "===",
|
||||
be : "alias equal",
|
||||
be_greater_than : ">",
|
||||
be_less_than : "<",
|
||||
be_at_least : ">=",
|
||||
be_at_most : "<=",
|
||||
be_a : "actual.constructor == expected",
|
||||
be_an : "alias be_a",
|
||||
be_an_instance_of : "actual instanceof expected",
|
||||
be_null : "actual == null",
|
||||
be_true : "actual == true",
|
||||
be_false : "actual == false",
|
||||
be_undefined : "typeof actual == 'undefined'",
|
||||
be_type : "typeof actual == expected",
|
||||
match : "typeof actual == 'string' ? actual.match(expected) : false",
|
||||
respond_to : "typeof actual[expected] == 'function'",
|
||||
have_length : "actual.length == expected",
|
||||
be_within : "actual >= expected[0] && actual <= last(expected)",
|
||||
have_length_within : "actual.length >= expected[0] && actual.length <= last(expected)",
|
||||
|
||||
eql : function(actual, expected) {
|
||||
return actual.constructor == Array ||
|
||||
actual instanceof Object ?
|
||||
hash(actual) == hash(expected):
|
||||
actual == expected
|
||||
},
|
||||
|
||||
receive : { defer : true, match : function(actual, method, times) {
|
||||
proxy = new JSpec.ProxyAssertion(actual, method, times, this.negate)
|
||||
JSpec.currentSpec.assertions.push(proxy)
|
||||
return proxy
|
||||
}},
|
||||
|
||||
be_empty : function(actual) {
|
||||
if (actual.constructor == Object && actual.length == undefined)
|
||||
for (var key in actual)
|
||||
return false;
|
||||
return !actual.length
|
||||
},
|
||||
|
||||
include : function(actual) {
|
||||
for (state = true, i = 1; i < arguments.length; i++) {
|
||||
arg = arguments[i]
|
||||
switch (actual.constructor) {
|
||||
case String:
|
||||
case Number:
|
||||
case RegExp:
|
||||
case Function:
|
||||
state = actual.toString().match(arg.toString())
|
||||
break
|
||||
|
||||
case Object:
|
||||
state = arg in actual
|
||||
break
|
||||
|
||||
case Array:
|
||||
state = any(actual, function(value){ return hash(value) == hash(arg) })
|
||||
break
|
||||
}
|
||||
if (!state) return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
|
||||
throw_error : { match : function(actual, expected, message) {
|
||||
try { actual() }
|
||||
catch (e) {
|
||||
this.e = e
|
||||
var assert = function(arg) {
|
||||
switch (arg.constructor) {
|
||||
case RegExp : return arg.test(e)
|
||||
case String : return arg == (e.message || e.toString())
|
||||
case Function : return (e.name || 'Error') == arg.name
|
||||
}
|
||||
}
|
||||
return message ? assert(expected) && assert(message) :
|
||||
expected ? assert(expected) :
|
||||
true
|
||||
}
|
||||
}, message : function(actual, expected, negate) {
|
||||
// TODO: refactor when actual is not in expected [0]
|
||||
var message_for = function(i) {
|
||||
if (expected[i] == undefined) return 'exception'
|
||||
switch (expected[i].constructor) {
|
||||
case RegExp : return 'exception matching ' + puts(expected[i])
|
||||
case String : return 'exception of ' + puts(expected[i])
|
||||
case Function : return expected[i].name || 'Error'
|
||||
}
|
||||
}
|
||||
exception = message_for(1) + (expected[2] ? ' and ' + message_for(2) : '')
|
||||
return 'expected ' + exception + (negate ? ' not ' : '' ) +
|
||||
' to be thrown, but ' + (this.e ? 'got ' + puts(this.e) : 'nothing was')
|
||||
}},
|
||||
|
||||
have : function(actual, length, property) {
|
||||
return actual[property].length == length
|
||||
},
|
||||
|
||||
have_at_least : function(actual, length, property) {
|
||||
return actual[property].length >= length
|
||||
},
|
||||
|
||||
have_at_most :function(actual, length, property) {
|
||||
return actual[property].length <= length
|
||||
},
|
||||
|
||||
have_within : function(actual, range, property) {
|
||||
length = actual[property].length
|
||||
return length >= range.shift() && length <= range.pop()
|
||||
},
|
||||
|
||||
have_prop : function(actual, property, value) {
|
||||
return actual[property] == null ||
|
||||
actual[property] instanceof Function ? false:
|
||||
value == null ? true:
|
||||
does(actual[property], 'eql', value)
|
||||
},
|
||||
|
||||
have_property : function(actual, property, value) {
|
||||
return actual[property] == null ||
|
||||
actual[property] instanceof Function ? false:
|
||||
value == null ? true:
|
||||
value === actual[property]
|
||||
}
|
||||
})
|
||||
|
||||
if ('exports' in main) exports.JSpec = JSpec
|
||||
|
||||
})()
|
173
thirdparty/jquery-concrete/vendor/jspec/lib/jspec.xhr.js
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
|
||||
// JSpec - XHR - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
|
||||
|
||||
(function(){
|
||||
|
||||
// --- Original XMLHttpRequest
|
||||
|
||||
var OriginalXMLHttpRequest = 'XMLHttpRequest' in this ?
|
||||
XMLHttpRequest :
|
||||
function(){}
|
||||
|
||||
// --- MockXMLHttpRequest
|
||||
|
||||
var MockXMLHttpRequest = function() {
|
||||
this.requestHeaders = {}
|
||||
}
|
||||
|
||||
MockXMLHttpRequest.prototype = {
|
||||
status : 0,
|
||||
async : true,
|
||||
readyState : 0,
|
||||
responseText : '',
|
||||
abort : function(){},
|
||||
onreadystatechange : function(){},
|
||||
|
||||
/**
|
||||
* Return response headers hash.
|
||||
*/
|
||||
|
||||
getAllResponseHeaders : function(){
|
||||
return this.responseHeaders
|
||||
},
|
||||
|
||||
/**
|
||||
* Return case-insensitive value for header _name_.
|
||||
*/
|
||||
|
||||
getResponseHeader : function(name) {
|
||||
return this.responseHeaders[name.toLowerCase()]
|
||||
},
|
||||
|
||||
/**
|
||||
* Set case-insensitive _value_ for header _name_.
|
||||
*/
|
||||
|
||||
setRequestHeader : function(name, value) {
|
||||
this.requestHeaders[name.toLowerCase()] = value
|
||||
},
|
||||
|
||||
/**
|
||||
* Open mock request.
|
||||
*/
|
||||
|
||||
open : function(method, url, async, user, password) {
|
||||
this.user = user
|
||||
this.password = password
|
||||
this.url = url
|
||||
this.readyState = 1
|
||||
this.method = method.toUpperCase()
|
||||
if (async != undefined) this.async = async
|
||||
if (this.async) this.onreadystatechange()
|
||||
},
|
||||
|
||||
/**
|
||||
* Send request _data_.
|
||||
*/
|
||||
|
||||
send : function(data) {
|
||||
this.data = data
|
||||
this.readyState = 4
|
||||
if (this.method == 'HEAD') this.responseText = null
|
||||
this.responseHeaders['content-length'] = (this.responseText || '').length
|
||||
if(this.async) this.onreadystatechange()
|
||||
}
|
||||
}
|
||||
|
||||
// --- Response status codes
|
||||
|
||||
JSpec.statusCodes = {
|
||||
100 : 'Continue',
|
||||
101 : 'Switching Protocols',
|
||||
200 : 'OK',
|
||||
201 : 'Created',
|
||||
202 : 'Accepted',
|
||||
203 : 'Non-Authoritative Information',
|
||||
204 : 'No Content',
|
||||
205 : 'Reset Content',
|
||||
206 : 'Partial Content',
|
||||
300 : 'Multiple Choice',
|
||||
301 : 'Moved Permanently',
|
||||
302 : 'Found',
|
||||
303 : 'See Other',
|
||||
304 : 'Not Modified',
|
||||
305 : 'Use Proxy',
|
||||
307 : 'Temporary Redirect',
|
||||
400 : 'Bad Request',
|
||||
401 : 'Unauthorized',
|
||||
402 : 'Payment Required',
|
||||
403 : 'Forbidden',
|
||||
404 : 'Not Found',
|
||||
405 : 'Method Not Allowed',
|
||||
406 : 'Not Acceptable',
|
||||
407 : 'Proxy Authentication Required',
|
||||
408 : 'Request Timeout',
|
||||
409 : 'Conflict',
|
||||
410 : 'Gone',
|
||||
411 : 'Length Required',
|
||||
412 : 'Precondition Failed',
|
||||
413 : 'Request Entity Too Large',
|
||||
414 : 'Request-URI Too Long',
|
||||
415 : 'Unsupported Media Type',
|
||||
416 : 'Requested Range Not Satisfiable',
|
||||
417 : 'Expectation Failed',
|
||||
422 : 'Unprocessable Entity',
|
||||
500 : 'Internal Server Error',
|
||||
501 : 'Not Implemented',
|
||||
502 : 'Bad Gateway',
|
||||
503 : 'Service Unavailable',
|
||||
504 : 'Gateway Timeout',
|
||||
505 : 'HTTP Version Not Supported'
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock XMLHttpRequest requests.
|
||||
*
|
||||
* mockRequest().and_return('some data', 'text/plain', 200, { 'X-SomeHeader' : 'somevalue' })
|
||||
*
|
||||
* @return {hash}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function mockRequest() {
|
||||
return { and_return : function(body, type, status, headers) {
|
||||
XMLHttpRequest = MockXMLHttpRequest
|
||||
status = status || 200
|
||||
headers = headers || {}
|
||||
headers['content-type'] = type
|
||||
JSpec.extend(XMLHttpRequest.prototype, {
|
||||
responseText : body,
|
||||
responseHeaders : headers,
|
||||
status : status,
|
||||
statusText : JSpec.statusCodes[status]
|
||||
})
|
||||
}}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmock XMLHttpRequest requests.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function unmockRequest() {
|
||||
XMLHttpRequest = OriginalXMLHttpRequest
|
||||
}
|
||||
|
||||
JSpec.include({
|
||||
|
||||
// --- Utilities
|
||||
|
||||
utilities : {
|
||||
mockRequest : mockRequest,
|
||||
unmockRequest : unmockRequest
|
||||
},
|
||||
|
||||
// --- Hooks
|
||||
|
||||
afterSpec : function() {
|
||||
this.utilities.unmockRequest()
|
||||
}
|
||||
|
||||
})
|
||||
})()
|
16
thirdparty/jquery-concrete/vendor/jspec/server/browsers.rb
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
module JSpec
|
||||
class Browser
|
||||
def open url
|
||||
`open -g -a #{name} #{url}`
|
||||
end
|
||||
|
||||
def name
|
||||
self.class.to_s.split('::').last
|
||||
end
|
||||
|
||||
class Firefox < self; end
|
||||
class Safari < self; end
|
||||
class Opera < self; end
|
||||
end
|
||||
end
|
100
thirdparty/jquery-concrete/vendor/jspec/server/server.rb
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
|
||||
require 'rubygems'
|
||||
require 'rack'
|
||||
require 'server/browsers'
|
||||
|
||||
module JSpec
|
||||
class Server
|
||||
attr_reader :responses, :browsers, :root
|
||||
|
||||
def initialize options = {}
|
||||
@responses = []
|
||||
@browsers = options.delete :browsers
|
||||
@root = options.delete :root
|
||||
end
|
||||
|
||||
def call env
|
||||
request = Rack::Request.new env
|
||||
path = request.path_info
|
||||
body = case path
|
||||
when '/'
|
||||
agent = env['HTTP_USER_AGENT']
|
||||
responses << browser(agent)
|
||||
display_results browser(agent), request['failures'], request['passes']
|
||||
type = 'text/plain'
|
||||
'close'
|
||||
when /jspec/
|
||||
type = 'application/javascript'
|
||||
File.read File.join(JSPEC_ROOT, 'lib', File.basename(path))
|
||||
else
|
||||
type = Rack::Mime.mime_type File.extname(path)
|
||||
File.read File.join(root, path) rescue ''
|
||||
end
|
||||
[200, { 'Content-Type' => type, 'Content-Length' => body.length.to_s }, body]
|
||||
end
|
||||
|
||||
def display_results browser, failures, passes
|
||||
puts '%-14s - passes: %s failures: %s' % [bold(browser), green(passes), red(failures)]
|
||||
end
|
||||
|
||||
def browser string
|
||||
case string
|
||||
when /Safari/ ; :Safari
|
||||
when /Firefox/ ; :Firefox
|
||||
when /MSIE/ ; :MSIE
|
||||
when /Opera/ ; :Opera
|
||||
end
|
||||
end
|
||||
|
||||
def bold string
|
||||
color string, 1
|
||||
end
|
||||
|
||||
def red string
|
||||
color string, 31
|
||||
end
|
||||
|
||||
def green string
|
||||
color string, 32
|
||||
end
|
||||
|
||||
def color string, code
|
||||
"\e[#{code}m#{string}\e[m"
|
||||
end
|
||||
|
||||
def when_finished &block
|
||||
Thread.new {
|
||||
sleep 0.1 while responses.length < browsers.length
|
||||
yield
|
||||
}
|
||||
end
|
||||
|
||||
def self.start options, spec
|
||||
app = Rack::Builder.new do
|
||||
server = JSpec::Server.new :browsers => options.browsers, :root => '.'
|
||||
server.when_finished { exit }
|
||||
run server
|
||||
end
|
||||
unless options.server_only
|
||||
Thread.new {
|
||||
sleep 2
|
||||
puts "Running browsers: #{options.browsers.join(', ')}\n\n"
|
||||
run_browsers options.browsers, spec
|
||||
}
|
||||
end
|
||||
puts "JSpec server started\n"
|
||||
Rack::Handler::Mongrel.run app, :Port => 4444
|
||||
self
|
||||
end
|
||||
|
||||
def self.run_browsers browsers, spec
|
||||
browsers.each do |name|
|
||||
browser(name).open "http://localhost:4444/#{spec}"
|
||||
end
|
||||
end
|
||||
|
||||
def self.browser name
|
||||
eval("JSpec::Browser::#{name}").new
|
||||
end
|
||||
end
|
||||
end
|
1
thirdparty/jquery-concrete/vendor/jspec/spec/async
vendored
Normal file
@ -0,0 +1 @@
|
||||
cookies!
|
695
thirdparty/jquery-concrete/vendor/jspec/spec/env.js
vendored
Normal file
@ -0,0 +1,695 @@
|
||||
/*
|
||||
* Simulated browser environment for Rhino
|
||||
* By John Resig <http://ejohn.org/>
|
||||
* Copyright 2007 John Resig, under the MIT License
|
||||
*/
|
||||
|
||||
// The window Object
|
||||
var window = this;
|
||||
|
||||
(function(){
|
||||
|
||||
// Browser Navigator
|
||||
|
||||
window.navigator = {
|
||||
get userAgent(){
|
||||
return "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3";
|
||||
}
|
||||
};
|
||||
|
||||
var curLocation = (new java.io.File("./")).toURL();
|
||||
|
||||
window.__defineSetter__("location", function(url){
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", url);
|
||||
xhr.onreadystatechange = function(){
|
||||
curLocation = new java.net.URL( curLocation, url );
|
||||
window.document = xhr.responseXML;
|
||||
|
||||
var event = document.createEvent();
|
||||
event.initEvent("load");
|
||||
window.dispatchEvent( event );
|
||||
};
|
||||
xhr.send();
|
||||
});
|
||||
|
||||
window.__defineGetter__("location", function(url){
|
||||
return {
|
||||
get protocol(){
|
||||
return curLocation.getProtocol() + ":";
|
||||
},
|
||||
get href(){
|
||||
return curLocation.toString();
|
||||
},
|
||||
toString: function(){
|
||||
return this.href;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Timers
|
||||
|
||||
var timers = [];
|
||||
|
||||
window.setTimeout = function(fn, time){
|
||||
var num;
|
||||
return num = setInterval(function(){
|
||||
fn();
|
||||
clearInterval(num);
|
||||
}, time);
|
||||
};
|
||||
|
||||
window.setInterval = function(fn, time){
|
||||
var num = timers.length;
|
||||
|
||||
timers[num] = new java.lang.Thread(new java.lang.Runnable({
|
||||
run: function(){
|
||||
while (true){
|
||||
java.lang.Thread.currentThread().sleep(time);
|
||||
fn();
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
timers[num].start();
|
||||
|
||||
return num;
|
||||
};
|
||||
|
||||
window.clearInterval = function(num){
|
||||
if ( timers[num] ) {
|
||||
timers[num].stop();
|
||||
delete timers[num];
|
||||
}
|
||||
};
|
||||
|
||||
// Window Events
|
||||
|
||||
var events = [{}];
|
||||
|
||||
window.addEventListener = function(type, fn){
|
||||
if ( !this.uuid || this == window ) {
|
||||
this.uuid = events.length;
|
||||
events[this.uuid] = {};
|
||||
}
|
||||
|
||||
if ( !events[this.uuid][type] )
|
||||
events[this.uuid][type] = [];
|
||||
|
||||
if ( events[this.uuid][type].indexOf( fn ) < 0 )
|
||||
events[this.uuid][type].push( fn );
|
||||
};
|
||||
|
||||
window.removeEventListener = function(type, fn){
|
||||
if ( !this.uuid || this == window ) {
|
||||
this.uuid = events.length;
|
||||
events[this.uuid] = {};
|
||||
}
|
||||
|
||||
if ( !events[this.uuid][type] )
|
||||
events[this.uuid][type] = [];
|
||||
|
||||
events[this.uuid][type] =
|
||||
events[this.uuid][type].filter(function(f){
|
||||
return f != fn;
|
||||
});
|
||||
};
|
||||
|
||||
window.dispatchEvent = function(event){
|
||||
if ( event.type ) {
|
||||
if ( this.uuid && events[this.uuid][event.type] ) {
|
||||
var self = this;
|
||||
|
||||
events[this.uuid][event.type].forEach(function(fn){
|
||||
fn.call( self, event );
|
||||
});
|
||||
}
|
||||
|
||||
if ( this["on" + event.type] )
|
||||
this["on" + event.type].call( self, event );
|
||||
}
|
||||
};
|
||||
|
||||
// DOM Document
|
||||
|
||||
window.DOMDocument = function(file){
|
||||
this._file = file;
|
||||
this._dom = Packages.javax.xml.parsers.
|
||||
DocumentBuilderFactory.newInstance()
|
||||
.newDocumentBuilder().parse(file);
|
||||
|
||||
if ( !obj_nodes.containsKey( this._dom ) )
|
||||
obj_nodes.put( this._dom, this );
|
||||
};
|
||||
|
||||
DOMDocument.prototype = {
|
||||
createTextNode: function(text){
|
||||
return makeNode( this._dom.createTextNode(
|
||||
text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")) );
|
||||
},
|
||||
createElement: function(name){
|
||||
return makeNode( this._dom.createElement(name.toLowerCase()) );
|
||||
},
|
||||
getElementsByTagName: function(name){
|
||||
return new DOMNodeList( this._dom.getElementsByTagName(
|
||||
name.toLowerCase()) );
|
||||
},
|
||||
getElementById: function(id){
|
||||
var elems = this._dom.getElementsByTagName("*");
|
||||
|
||||
for ( var i = 0; i < elems.length; i++ ) {
|
||||
var elem = elems.item(i);
|
||||
if ( elem.getAttribute("id") == id )
|
||||
return makeNode(elem);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
get body(){
|
||||
return this.getElementsByTagName("body")[0];
|
||||
},
|
||||
get documentElement(){
|
||||
return makeNode( this._dom.getDocumentElement() );
|
||||
},
|
||||
get ownerDocument(){
|
||||
return null;
|
||||
},
|
||||
addEventListener: window.addEventListener,
|
||||
removeEventListener: window.removeEventListener,
|
||||
dispatchEvent: window.dispatchEvent,
|
||||
get nodeName() {
|
||||
return "#document";
|
||||
},
|
||||
importNode: function(node, deep){
|
||||
return makeNode( this._dom.importNode(node._dom, deep) );
|
||||
},
|
||||
toString: function(){
|
||||
return "Document" + (typeof this._file == "string" ?
|
||||
": " + this._file : "");
|
||||
},
|
||||
get innerHTML(){
|
||||
return this.documentElement.outerHTML;
|
||||
},
|
||||
|
||||
get defaultView(){
|
||||
return {
|
||||
getComputedStyle: function(elem){
|
||||
return {
|
||||
getPropertyValue: function(prop){
|
||||
prop = prop.replace(/\-(\w)/g,function(m,c){
|
||||
return c.toUpperCase();
|
||||
});
|
||||
var val = elem.style[prop];
|
||||
|
||||
if ( prop == "opacity" && val == "" )
|
||||
val = "1";
|
||||
|
||||
return val;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
createEvent: function(){
|
||||
return {
|
||||
type: "",
|
||||
initEvent: function(type){
|
||||
this.type = type;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
function getDocument(node){
|
||||
return obj_nodes.get(node);
|
||||
}
|
||||
|
||||
// DOM NodeList
|
||||
|
||||
window.DOMNodeList = function(list){
|
||||
this._dom = list;
|
||||
this.length = list.getLength();
|
||||
|
||||
for ( var i = 0; i < this.length; i++ ) {
|
||||
var node = list.item(i);
|
||||
this[i] = makeNode( node );
|
||||
}
|
||||
};
|
||||
|
||||
DOMNodeList.prototype = {
|
||||
toString: function(){
|
||||
return "[ " +
|
||||
Array.prototype.join.call( this, ", " ) + " ]";
|
||||
},
|
||||
get outerHTML(){
|
||||
return Array.prototype.map.call(
|
||||
this, function(node){return node.outerHTML;}).join('');
|
||||
}
|
||||
};
|
||||
|
||||
// DOM Node
|
||||
|
||||
window.DOMNode = function(node){
|
||||
this._dom = node;
|
||||
};
|
||||
|
||||
DOMNode.prototype = {
|
||||
get nodeType(){
|
||||
return this._dom.getNodeType();
|
||||
},
|
||||
get nodeValue(){
|
||||
return this._dom.getNodeValue();
|
||||
},
|
||||
get nodeName() {
|
||||
return this._dom.getNodeName();
|
||||
},
|
||||
cloneNode: function(deep){
|
||||
return makeNode( this._dom.cloneNode(deep) );
|
||||
},
|
||||
get ownerDocument(){
|
||||
return getDocument( this._dom.ownerDocument );
|
||||
},
|
||||
get documentElement(){
|
||||
return makeNode( this._dom.documentElement );
|
||||
},
|
||||
get parentNode() {
|
||||
return makeNode( this._dom.getParentNode() );
|
||||
},
|
||||
get nextSibling() {
|
||||
return makeNode( this._dom.getNextSibling() );
|
||||
},
|
||||
get previousSibling() {
|
||||
return makeNode( this._dom.getPreviousSibling() );
|
||||
},
|
||||
toString: function(){
|
||||
return '"' + this.nodeValue + '"';
|
||||
},
|
||||
get outerHTML(){
|
||||
return this.nodeValue;
|
||||
}
|
||||
};
|
||||
|
||||
// DOM Element
|
||||
|
||||
window.DOMElement = function(elem){
|
||||
this._dom = elem;
|
||||
this.style = {
|
||||
get opacity(){ return this._opacity; },
|
||||
set opacity(val){ this._opacity = val + ""; }
|
||||
};
|
||||
|
||||
// Load CSS info
|
||||
var styles = (this.getAttribute("style") || "").split(/\s*;\s*/);
|
||||
|
||||
for ( var i = 0; i < styles.length; i++ ) {
|
||||
var style = styles[i].split(/\s*:\s*/);
|
||||
if ( style.length == 2 )
|
||||
this.style[ style[0] ] = style[1];
|
||||
}
|
||||
};
|
||||
|
||||
DOMElement.prototype = extend( new DOMNode(), {
|
||||
get nodeName(){
|
||||
return this.tagName.toUpperCase();
|
||||
},
|
||||
get tagName(){
|
||||
return this._dom.getTagName();
|
||||
},
|
||||
toString: function(){
|
||||
return "<" + this.tagName + (this.id ? "#" + this.id : "" ) + ">";
|
||||
},
|
||||
get outerHTML(){
|
||||
var ret = "<" + this.tagName, attr = this.attributes;
|
||||
|
||||
for ( var i in attr )
|
||||
ret += " " + i + "='" + attr[i] + "'";
|
||||
|
||||
if ( this.childNodes.length || this.nodeName == "SCRIPT" )
|
||||
ret += ">" + this.childNodes.outerHTML +
|
||||
"</" + this.tagName + ">";
|
||||
else
|
||||
ret += "/>";
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
get attributes(){
|
||||
var attr = {}, attrs = this._dom.getAttributes();
|
||||
|
||||
for ( var i = 0; i < attrs.getLength(); i++ )
|
||||
attr[ attrs.item(i).nodeName ] = attrs.item(i).nodeValue;
|
||||
|
||||
return attr;
|
||||
},
|
||||
|
||||
get innerHTML(){
|
||||
return this.childNodes.outerHTML;
|
||||
},
|
||||
set innerHTML(html){
|
||||
html = html.replace(/<\/?([A-Z]+)/g, function(m){
|
||||
return m.toLowerCase();
|
||||
});
|
||||
|
||||
var nodes = this.ownerDocument.importNode(
|
||||
new DOMDocument( new java.io.ByteArrayInputStream(
|
||||
(new java.lang.String("<wrap>" + html + "</wrap>"))
|
||||
.getBytes("UTF8"))).documentElement, true).childNodes;
|
||||
|
||||
while (this.firstChild)
|
||||
this.removeChild( this.firstChild );
|
||||
|
||||
for ( var i = 0; i < nodes.length; i++ )
|
||||
this.appendChild( nodes[i] );
|
||||
},
|
||||
|
||||
get textContent(){
|
||||
return nav(this.childNodes);
|
||||
|
||||
function nav(nodes){
|
||||
var str = "";
|
||||
for ( var i = 0; i < nodes.length; i++ )
|
||||
if ( nodes[i].nodeType == 3 )
|
||||
str += nodes[i].nodeValue;
|
||||
else if ( nodes[i].nodeType == 1 )
|
||||
str += nav(nodes[i].childNodes);
|
||||
return str;
|
||||
}
|
||||
},
|
||||
set textContent(text){
|
||||
while (this.firstChild)
|
||||
this.removeChild( this.firstChild );
|
||||
this.appendChild( this.ownerDocument.createTextNode(text));
|
||||
},
|
||||
|
||||
style: {},
|
||||
clientHeight: 0,
|
||||
clientWidth: 0,
|
||||
offsetHeight: 0,
|
||||
offsetWidth: 0,
|
||||
|
||||
get disabled() {
|
||||
var val = this.getAttribute("disabled");
|
||||
return val != "false" && !!val;
|
||||
},
|
||||
set disabled(val) { return this.setAttribute("disabled",val); },
|
||||
|
||||
get checked() {
|
||||
var val = this.getAttribute("checked");
|
||||
return val != "false" && !!val;
|
||||
},
|
||||
set checked(val) { return this.setAttribute("checked",val); },
|
||||
|
||||
get selected() {
|
||||
if ( !this._selectDone ) {
|
||||
this._selectDone = true;
|
||||
|
||||
if ( this.nodeName == "OPTION" && !this.parentNode.getAttribute("multiple") ) {
|
||||
var opt = this.parentNode.getElementsByTagName("option");
|
||||
|
||||
if ( this == opt[0] ) {
|
||||
var select = true;
|
||||
|
||||
for ( var i = 1; i < opt.length; i++ )
|
||||
if ( opt[i].selected ) {
|
||||
select = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( select )
|
||||
this.selected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var val = this.getAttribute("selected");
|
||||
return val != "false" && !!val;
|
||||
},
|
||||
set selected(val) { return this.setAttribute("selected",val); },
|
||||
|
||||
get className() { return this.getAttribute("class") || ""; },
|
||||
set className(val) {
|
||||
return this.setAttribute("class",
|
||||
val.replace(/(^\s*|\s*$)/g,""));
|
||||
},
|
||||
|
||||
get type() { return this.getAttribute("type") || ""; },
|
||||
set type(val) { return this.setAttribute("type",val); },
|
||||
|
||||
get value() { return this.getAttribute("value") || ""; },
|
||||
set value(val) { return this.setAttribute("value",val); },
|
||||
|
||||
get src() { return this.getAttribute("src") || ""; },
|
||||
set src(val) { return this.setAttribute("src",val); },
|
||||
|
||||
get id() { return this.getAttribute("id") || ""; },
|
||||
set id(val) { return this.setAttribute("id",val); },
|
||||
|
||||
getAttribute: function(name){
|
||||
return this._dom.hasAttribute(name) ?
|
||||
new String( this._dom.getAttribute(name) ) :
|
||||
null;
|
||||
},
|
||||
setAttribute: function(name,value){
|
||||
this._dom.setAttribute(name,value);
|
||||
},
|
||||
removeAttribute: function(name){
|
||||
this._dom.removeAttribute(name);
|
||||
},
|
||||
|
||||
get childNodes(){
|
||||
return new DOMNodeList( this._dom.getChildNodes() );
|
||||
},
|
||||
get firstChild(){
|
||||
return makeNode( this._dom.getFirstChild() );
|
||||
},
|
||||
get lastChild(){
|
||||
return makeNode( this._dom.getLastChild() );
|
||||
},
|
||||
appendChild: function(node){
|
||||
this._dom.appendChild( node._dom );
|
||||
},
|
||||
insertBefore: function(node,before){
|
||||
this._dom.insertBefore( node._dom, before ? before._dom : before );
|
||||
},
|
||||
removeChild: function(node){
|
||||
this._dom.removeChild( node._dom );
|
||||
},
|
||||
|
||||
getElementsByTagName: DOMDocument.prototype.getElementsByTagName,
|
||||
|
||||
addEventListener: window.addEventListener,
|
||||
removeEventListener: window.removeEventListener,
|
||||
dispatchEvent: window.dispatchEvent,
|
||||
|
||||
click: function(){
|
||||
var event = document.createEvent();
|
||||
event.initEvent("click");
|
||||
this.dispatchEvent(event);
|
||||
},
|
||||
submit: function(){
|
||||
var event = document.createEvent();
|
||||
event.initEvent("submit");
|
||||
this.dispatchEvent(event);
|
||||
},
|
||||
focus: function(){
|
||||
var event = document.createEvent();
|
||||
event.initEvent("focus");
|
||||
this.dispatchEvent(event);
|
||||
},
|
||||
blur: function(){
|
||||
var event = document.createEvent();
|
||||
event.initEvent("blur");
|
||||
this.dispatchEvent(event);
|
||||
},
|
||||
get elements(){
|
||||
return this.getElementsByTagName("*");
|
||||
},
|
||||
get contentWindow(){
|
||||
return this.nodeName == "IFRAME" ? {
|
||||
document: this.contentDocument
|
||||
} : null;
|
||||
},
|
||||
get contentDocument(){
|
||||
if ( this.nodeName == "IFRAME" ) {
|
||||
if ( !this._doc )
|
||||
this._doc = new DOMDocument(
|
||||
new java.io.ByteArrayInputStream((new java.lang.String(
|
||||
"<html><head><title></title></head><body></body></html>"))
|
||||
.getBytes("UTF8")));
|
||||
return this._doc;
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Helper method for extending one object with another
|
||||
|
||||
function extend(a,b) {
|
||||
for ( var i in b ) {
|
||||
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||
|
||||
if ( g || s ) {
|
||||
if ( g )
|
||||
a.__defineGetter__(i, g);
|
||||
if ( s )
|
||||
a.__defineSetter__(i, s);
|
||||
} else
|
||||
a[i] = b[i];
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
// Helper method for generating the right
|
||||
// DOM objects based upon the type
|
||||
|
||||
var obj_nodes = new java.util.HashMap();
|
||||
|
||||
function makeNode(node){
|
||||
if ( node ) {
|
||||
if ( !obj_nodes.containsKey( node ) )
|
||||
obj_nodes.put( node, node.getNodeType() ==
|
||||
Packages.org.w3c.dom.Node.ELEMENT_NODE ?
|
||||
new DOMElement( node ) : new DOMNode( node ) );
|
||||
|
||||
return obj_nodes.get(node);
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
// XMLHttpRequest
|
||||
// Originally implemented by Yehuda Katz
|
||||
|
||||
window.XMLHttpRequest = function(){
|
||||
this.headers = {};
|
||||
this.responseHeaders = {};
|
||||
};
|
||||
|
||||
XMLHttpRequest.prototype = {
|
||||
open: function(method, url, async, user, password){
|
||||
this.readyState = 1;
|
||||
if (async)
|
||||
this.async = true;
|
||||
this.method = method || "GET";
|
||||
this.url = url;
|
||||
this.onreadystatechange();
|
||||
},
|
||||
setRequestHeader: function(header, value){
|
||||
this.headers[header] = value;
|
||||
},
|
||||
getResponseHeader: function(header){ },
|
||||
send: function(data){
|
||||
var self = this;
|
||||
|
||||
function makeRequest(){
|
||||
var url = new java.net.URL(curLocation, self.url);
|
||||
|
||||
if ( url.getProtocol() == "file" ) {
|
||||
if ( self.method == "PUT" ) {
|
||||
var out = new java.io.FileWriter(
|
||||
new java.io.File( new java.net.URI( url.toString() ) ) ),
|
||||
text = new java.lang.String( data || "" );
|
||||
|
||||
out.write( text, 0, text.length() );
|
||||
out.flush();
|
||||
out.close();
|
||||
} else if ( self.method == "DELETE" ) {
|
||||
var file = new java.io.File( new java.net.URI( url.toString() ) );
|
||||
file["delete"]();
|
||||
} else {
|
||||
var connection = url.openConnection();
|
||||
connection.connect();
|
||||
handleResponse();
|
||||
}
|
||||
} else {
|
||||
var connection = url.openConnection();
|
||||
|
||||
connection.setRequestMethod( self.method );
|
||||
|
||||
// Add headers to Java connection
|
||||
for (var header in self.headers)
|
||||
connection.addRequestProperty(header, self.headers[header]);
|
||||
|
||||
connection.connect();
|
||||
|
||||
// Stick the response headers into responseHeaders
|
||||
for (var i = 0; ; i++) {
|
||||
var headerName = connection.getHeaderFieldKey(i);
|
||||
var headerValue = connection.getHeaderField(i);
|
||||
if (!headerName && !headerValue) break;
|
||||
if (headerName)
|
||||
self.responseHeaders[headerName] = headerValue;
|
||||
}
|
||||
|
||||
handleResponse();
|
||||
}
|
||||
|
||||
function handleResponse(){
|
||||
self.readyState = 4;
|
||||
self.status = parseInt(connection.responseCode) || undefined;
|
||||
self.statusText = connection.responseMessage || "";
|
||||
|
||||
var stream = new java.io.InputStreamReader(connection.getInputStream()),
|
||||
buffer = new java.io.BufferedReader(stream), line;
|
||||
|
||||
while ((line = buffer.readLine()) != null)
|
||||
self.responseText += line;
|
||||
|
||||
self.responseXML = null;
|
||||
|
||||
if ( self.responseText.match(/^\s*</) ) {
|
||||
try {
|
||||
self.responseXML = new DOMDocument(
|
||||
new java.io.ByteArrayInputStream(
|
||||
(new java.lang.String(
|
||||
self.responseText)).getBytes("UTF8")));
|
||||
} catch(e) {}
|
||||
}
|
||||
}
|
||||
|
||||
self.onreadystatechange();
|
||||
}
|
||||
|
||||
if (this.async)
|
||||
(new java.lang.Thread(new java.lang.Runnable({
|
||||
run: makeRequest
|
||||
}))).start();
|
||||
else
|
||||
makeRequest();
|
||||
},
|
||||
abort: function(){},
|
||||
onreadystatechange: function(){},
|
||||
getResponseHeader: function(header){
|
||||
if (this.readyState < 3)
|
||||
throw new Error("INVALID_STATE_ERR");
|
||||
else {
|
||||
var returnedHeaders = [];
|
||||
for (var rHeader in this.responseHeaders) {
|
||||
if (rHeader.match(new Regexp(header, "i")))
|
||||
returnedHeaders.push(this.responseHeaders[rHeader]);
|
||||
}
|
||||
|
||||
if (returnedHeaders.length)
|
||||
return returnedHeaders.join(", ");
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
getAllResponseHeaders: function(header){
|
||||
if (this.readyState < 3)
|
||||
throw new Error("INVALID_STATE_ERR");
|
||||
else {
|
||||
var returnedHeaders = [];
|
||||
|
||||
for (var header in this.responseHeaders)
|
||||
returnedHeaders.push( header + ": " + this.responseHeaders[header] );
|
||||
|
||||
return returnedHeaders.join("\r\n");
|
||||
}
|
||||
},
|
||||
async: true,
|
||||
readyState: 0,
|
||||
responseText: "",
|
||||
status: 0
|
||||
};
|
||||
})();
|
1
thirdparty/jquery-concrete/vendor/jspec/spec/fixtures/test.html
vendored
Normal file
@ -0,0 +1 @@
|
||||
<p>test</p>
|
1
thirdparty/jquery-concrete/vendor/jspec/spec/fixtures/test.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{ users : { tj : { email : 'tj@vision-media.ca' }}}
|
5
thirdparty/jquery-concrete/vendor/jspec/spec/fixtures/test.xml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<users>
|
||||
<user name="tj">
|
||||
<email>tj@vision-media.ca</email>
|
||||
</user>
|
||||
</users>
|
42
thirdparty/jquery-concrete/vendor/jspec/spec/modules.js
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
ExampleModule = {
|
||||
name : 'ExampleModule',
|
||||
utilities : {
|
||||
doFoo : function(){ return 'foo' },
|
||||
doBar : function(){ return 'bar' }
|
||||
},
|
||||
randomHook : function(a, b) {
|
||||
return [a, b]
|
||||
},
|
||||
beforeSpec : function() { addedBeforeSpec = true; doFoo() },
|
||||
afterSpec : function() { addedAfterSpec = true },
|
||||
beforeSuite : function() { addedBeforeSuite = true },
|
||||
afterSuite : function() { addedAfterSuite = true },
|
||||
checkJSpecContext : function(){ return each },
|
||||
checkContext : function() { return fixture('test') },
|
||||
checkModuleContext : function() { return this.name },
|
||||
checkUtilityContext : function() { return doFoo() },
|
||||
matchers : {
|
||||
be_foo_bar : function() {
|
||||
return true
|
||||
}
|
||||
},
|
||||
DSLs : {
|
||||
snake : {
|
||||
some_snake_case_stuff : function(){
|
||||
return true
|
||||
}
|
||||
},
|
||||
camel : {
|
||||
someCamelCaseStuff : function() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSpec.include(ExampleModule)
|
||||
|
||||
JSpec.include({
|
||||
name : 'EmptyModule'
|
||||
})
|
33
thirdparty/jquery-concrete/vendor/jspec/spec/spec.dom.html
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<html>
|
||||
<head>
|
||||
<link type="text/css" rel="stylesheet" href="../lib/jspec.css" />
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
|
||||
<script src="../lib/jspec.js"></script>
|
||||
<script src="../lib/jspec.jquery.js"></script>
|
||||
<script src="../lib/jspec.xhr.js"></script>
|
||||
<script src="modules.js"></script>
|
||||
<script src="spec.grammar-less.js"></script>
|
||||
<script>
|
||||
function runSuites() {
|
||||
JSpec
|
||||
.exec('spec.grammar.js')
|
||||
.exec('spec.js')
|
||||
.exec('spec.matchers.js')
|
||||
.exec('spec.utils.js')
|
||||
.exec('spec.fixtures.js')
|
||||
.exec('spec.shared-behaviors.js')
|
||||
.exec('spec.jquery.js')
|
||||
.exec('spec.modules.js')
|
||||
.exec('spec.xhr.js')
|
||||
.exec('spec.jquery.xhr.js')
|
||||
.run()
|
||||
.report()
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="jspec" onLoad="runSuites();">
|
||||
<div id="jspec-top"><h2 id="jspec-title">JSpec <em><script>document.write(JSpec.version)</script></em></h2></div>
|
||||
<div id="jspec"><div class="loading"></div></div>
|
||||
<div id="jspec-bottom"></div>
|
||||
</body>
|
||||
</html>
|
18
thirdparty/jquery-concrete/vendor/jspec/spec/spec.fixtures.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
describe 'Utility'
|
||||
describe 'fixture()'
|
||||
it 'should return a files contents'
|
||||
fixture('fixtures/test.html').should.eql '<p>test</p>'
|
||||
fixture('test.html').should.eql '<p>test</p>'
|
||||
fixture('test').should.eql '<p>test</p>'
|
||||
end
|
||||
|
||||
it 'should cache contents'
|
||||
contents = fixture('test')
|
||||
JSpec.cache['test'].should.eql contents
|
||||
JSpec.cache['test'] = 'foo'
|
||||
fixture('test').should.eql 'foo'
|
||||
delete JSpec.cache['test']
|
||||
end
|
||||
end
|
||||
end
|
34
thirdparty/jquery-concrete/vendor/jspec/spec/spec.grammar-less.js
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
JSpec.describe('Grammar-less', function(){
|
||||
before(function(){
|
||||
n = 1
|
||||
})
|
||||
|
||||
it('should work', function(){
|
||||
expect(true).to(be, true)
|
||||
expect(n).to(equal, 1)
|
||||
})
|
||||
|
||||
describe('with nested describes', function(){
|
||||
before(function(){
|
||||
hits = []
|
||||
})
|
||||
|
||||
before_each(function(){
|
||||
n++
|
||||
hits.push('before_each')
|
||||
})
|
||||
|
||||
it('should work', function(){
|
||||
expect(true).not_to(be, false)
|
||||
expect(n).to(eql, 2)
|
||||
expect(hits).to(eql, ['before_each'])
|
||||
})
|
||||
|
||||
it('should work again', function(){
|
||||
expect(n).to(eql, 3)
|
||||
expect(hits).to(eql, ['before_each', 'before_each'])
|
||||
})
|
||||
})
|
||||
|
||||
})
|
218
thirdparty/jquery-concrete/vendor/jspec/spec/spec.grammar.js
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
|
||||
describe 'Grammar'
|
||||
|
||||
it 'should allow "it" spec literal'
|
||||
true.should.be_true
|
||||
end
|
||||
|
||||
n = 10
|
||||
|
||||
it 'should allow literal javascript outside of blocks'
|
||||
n.should.eql 10
|
||||
end
|
||||
|
||||
it 'should escape <html> in <p>descriptions</p> and body'
|
||||
'<p></p>'.should.eql '<p></p>'
|
||||
end
|
||||
|
||||
it 'should parse correctly when "it" is within the body'
|
||||
text = 'Get it at Github'
|
||||
text.should.include 'it'
|
||||
end
|
||||
|
||||
it 'should parse correctly when "describe" is within the body'
|
||||
text = 'It should work with describe'
|
||||
text.should.include 'describe'
|
||||
end
|
||||
|
||||
it 'should parse correctly when "end" is within the body'
|
||||
text = 'This should not end the parsing :)'
|
||||
text.should.include 'not'
|
||||
end
|
||||
|
||||
it 'should parse correctly with "before" and "after" within the body'
|
||||
text = 'This comes before that, which is after the rest'
|
||||
text.should.include 'before'
|
||||
end
|
||||
|
||||
it 'should allow parens to be optional when no args are passed'
|
||||
true.should.be_true
|
||||
true.should.be_true()
|
||||
end
|
||||
|
||||
it 'should not mess up with words like it or append in descriptions'
|
||||
-{ element.append().end() }.should.throw_error
|
||||
end
|
||||
|
||||
it 'should not mess up "end" in strings'
|
||||
'foo end bar'.should.not.eql 'foo }); bar'
|
||||
end
|
||||
|
||||
it 'should allow semicolons'
|
||||
true.should.be_true;
|
||||
true.should.be_true();
|
||||
true.should.be_true() ;
|
||||
end
|
||||
|
||||
it 'should allow parens to be optional with args'
|
||||
'foobar'.should.include 'foo'
|
||||
'rawr'.should.not_include 'foo'
|
||||
end
|
||||
|
||||
it 'should allow literals without defining variables variables'
|
||||
{}.should.be_an Object
|
||||
end
|
||||
|
||||
it 'should allow alternative closure literal'
|
||||
-{ throw 'test' }.should.throw_error
|
||||
end
|
||||
|
||||
it 'should allow grammar-less assertions'
|
||||
expect(true).to(be, true)
|
||||
expect([1,2,3]).to(include, 1, 2, 3)
|
||||
expect(true).not_to(be, false)
|
||||
end
|
||||
|
||||
it 'should allow multi-line expect() assertions'
|
||||
expect(' \
|
||||
foo \
|
||||
bar \
|
||||
').to(include, 'foo', 'bar')
|
||||
end
|
||||
|
||||
it 'should allow commenting out of conversions'
|
||||
// -{ throw 'foo' }.should.throw_error
|
||||
// foo.should.not.eql 'bar'
|
||||
end
|
||||
|
||||
it 'should allow inclusive range literal n..n'
|
||||
1..5.should.eql [1,2,3,4,5]
|
||||
3..4.should.eql [3,4]
|
||||
1..1.should.eql [1]
|
||||
3..1.should.eql [3,2,1]
|
||||
end
|
||||
|
||||
it 'should allow snakecase style assertions'
|
||||
'foo'.should_equal('foo')
|
||||
'foo'.should_equal 'foo'
|
||||
'bar'.should_not_equal('foo')
|
||||
'bar'.should_not_equal 'foo'
|
||||
end
|
||||
|
||||
it 'should allow dot style assertions'
|
||||
'foo'.should.equal('foo')
|
||||
'foo'.should.equal 'foo'
|
||||
'bar'.should.not.equal('foo')
|
||||
'bar'.should.not.equal 'foo'
|
||||
end
|
||||
|
||||
describe 'with nested describe'
|
||||
it 'should work'
|
||||
true.should.be_true
|
||||
end
|
||||
|
||||
describe 'nested again'
|
||||
it 'should still work'
|
||||
true.should.be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'before / after blocks'
|
||||
before
|
||||
n = 1
|
||||
hits = []
|
||||
hits.push('before')
|
||||
end
|
||||
|
||||
after
|
||||
n = 0
|
||||
hits.push('after')
|
||||
end
|
||||
|
||||
it 'should work'
|
||||
n.should.eql 1
|
||||
hits.should.eql ['before']
|
||||
n++
|
||||
end
|
||||
|
||||
it 'should persist'
|
||||
n.should.eql 2
|
||||
hits.should.eql ['before']
|
||||
end
|
||||
|
||||
describe 'with nested describe'
|
||||
it 'should be accessable'
|
||||
n.should.eql 1
|
||||
hits.should.eql ['before']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'before_each / after_each blocks'
|
||||
hits = []
|
||||
|
||||
before_each
|
||||
n = 1
|
||||
hits.push('before_each')
|
||||
end
|
||||
|
||||
after_each
|
||||
o = 2
|
||||
hits.push('after_each')
|
||||
end
|
||||
|
||||
it 'should work'
|
||||
n.should.eql 1
|
||||
hits.should.eql ['before_each']
|
||||
n = 2
|
||||
end
|
||||
|
||||
it 'should not persist'
|
||||
n.should.eql 1
|
||||
o.should.eql 2
|
||||
hits.should.eql ['before_each', 'after_each', 'before_each']
|
||||
end
|
||||
|
||||
describe 'with nested describe'
|
||||
it 'should be accessable'
|
||||
n.should.eql 1
|
||||
o.should.eql 2
|
||||
hits.should.eql ['before_each', 'after_each', 'before_each', 'after_each', 'before_each']
|
||||
end
|
||||
|
||||
it 'should continue hits'
|
||||
hits.should.eql ['before_each', 'after_each', 'before_each', 'after_each', 'before_each', 'after_each', 'before_each']
|
||||
end
|
||||
|
||||
describe 'with more hooks'
|
||||
before_each
|
||||
hits.push('before_each')
|
||||
end
|
||||
|
||||
after_each
|
||||
hits.push('after_each')
|
||||
end
|
||||
|
||||
it 'should continue hits, while cascading properly'
|
||||
hits.should.eql ['before_each', 'after_each', 'before_each', 'after_each', 'before_each', 'after_each', 'before_each', 'after_each', 'before_each', 'before_each']
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with multiple hooks'
|
||||
before_each
|
||||
hits = []
|
||||
end
|
||||
|
||||
before_each
|
||||
hits.push('before_each')
|
||||
end
|
||||
|
||||
it 'should work'
|
||||
hits.should.eql ['before_each']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
173
thirdparty/jquery-concrete/vendor/jspec/spec/spec.jquery.js
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
|
||||
describe 'jQuery'
|
||||
describe 'sandbox()'
|
||||
before
|
||||
dom = sandbox()
|
||||
end
|
||||
|
||||
it 'should provide an empty DOM sandbox'
|
||||
dom.prepend('<em>test</em>')
|
||||
dom.should.have_text 'test'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'element() / elements()'
|
||||
it 'should alias jQuery'
|
||||
element.should.be jQuery
|
||||
elements.should.be jQuery
|
||||
end
|
||||
end
|
||||
|
||||
describe 'async'
|
||||
it 'should load mah cookies (textfile)'
|
||||
$.post('async', function(text){
|
||||
text.should_eql 'cookies!'
|
||||
})
|
||||
end
|
||||
|
||||
it 'should load mah cookies twice (ensure multiple async requests work)'
|
||||
$.post('async', function(text){
|
||||
text.should.eql 'cookies!'
|
||||
})
|
||||
$.post('async', function(text){
|
||||
text.should.not.eql 'rawr'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
describe 'matchers'
|
||||
before_each
|
||||
html = '<p><label><em>Save?</em></label> \
|
||||
<select class="save form-select" style="display: none;"> \
|
||||
<option value="0">No</option> \
|
||||
<option value="1">Yes</option> \
|
||||
</select> \
|
||||
<strong>test</strong> \
|
||||
<strong>test</strong> \
|
||||
</p>'
|
||||
elem = $(html)
|
||||
end
|
||||
|
||||
it 'should fail with pretty print of element'
|
||||
elem.should.not.have_tag 'label'
|
||||
end
|
||||
|
||||
describe 'have_tag / have_one'
|
||||
it 'should check if a single child is present'
|
||||
elem.should.have_tag 'label'
|
||||
elem.should.have_tag 'em'
|
||||
elem.should.have_one 'label'
|
||||
elem.should.not.have_tag 'input'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_tags / have_many'
|
||||
it 'should check if more than one child is present'
|
||||
elem.should.have_tags 'option'
|
||||
elem.should.have_many 'option'
|
||||
elem.should.not.have_many 'label'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_child'
|
||||
it 'should check if a direct child is present'
|
||||
elem.should.have_child 'label'
|
||||
elem.should.not.have_child 'em'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_children'
|
||||
it 'should check if more than one direct children are present'
|
||||
elem.should.have_children 'strong'
|
||||
elem.should.not.have_children 'select'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_text'
|
||||
it 'should check for plain text'
|
||||
elem.children('label').should.have_text 'Save?'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_value'
|
||||
it 'should check if an element has the given value'
|
||||
elem.find('option').get(1).should.have_value '1'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_class'
|
||||
it 'should check if an element has the given class'
|
||||
elem.children('select').should.have_class 'save'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_classes'
|
||||
it 'should check if an element has the classes given'
|
||||
elem.children('select').should.have_classes 'save', 'form-select'
|
||||
elem.children('select').should.not.have_classes 'save', 'foo'
|
||||
elem.children('select').should.not.have_classes 'foo', 'save'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_visible'
|
||||
it 'should check that an element is not hidden or set to display of none'
|
||||
element('#jspec-report').should.be_visible
|
||||
'#jspec-report'.should.be_visible
|
||||
'<input style="visibility: hidden;"/>'.should.not.be_visible
|
||||
'<input style="display: none;"/>'.should.not.be_visible
|
||||
'<input />'.should.be_visible
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_enabled'
|
||||
it 'should check that an element is currently enabled'
|
||||
'<input type="button"/>'.should.be_enabled
|
||||
'<input type="button" disabled="disabled" />'.should.not.be_enabled
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_BOOLATTR'
|
||||
it 'should check that an element is currently selected, disabled, checked etc'
|
||||
'<input type="button"/>'.should.not.be_disabled
|
||||
'<input type="button" disabled="disabled" />'.should.be_disabled
|
||||
'<option value="foo" selected="selected">Foo</option>'.should.be_selected
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_ATTR'
|
||||
it 'should check if an attribute exists'
|
||||
'<input type="checkbox"/>'.should.have_type
|
||||
end
|
||||
|
||||
it 'should check if an attribute has a specific value'
|
||||
'<input type="checkbox"/>'.should.have_type 'checkbox'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_hidden'
|
||||
it 'should check if an element is hidden'
|
||||
'<input style="display: none;" />'.should.be_hidden
|
||||
'<input style="visibility: hidden;" />'.should.be_hidden
|
||||
'<input />'.should.not.be_hidden
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_attr'
|
||||
before_each
|
||||
elem = '<input type="button" title="some foo" value="Foo" />'
|
||||
end
|
||||
|
||||
it 'should check that an element has the given attribute'
|
||||
elem.should.have_attr 'title'
|
||||
elem.should.not_have_attr 'rawr'
|
||||
end
|
||||
|
||||
it 'should check that the given attribute has a specific value'
|
||||
elem.should.have_attr 'title', 'some foo'
|
||||
elem.should.not.have_attr 'some', 'rawr'
|
||||
elem.should.not.have_attr 'title', 'bar'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
35
thirdparty/jquery-concrete/vendor/jspec/spec/spec.jquery.xhr.js
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
describe 'jQuery'
|
||||
describe '.getJSON()'
|
||||
it 'should work with mockRequest'
|
||||
mockRequest().and_return('{ foo : "bar" }')
|
||||
$.getJSON('foo', function(response, statusText){
|
||||
response.foo.should.eql 'bar'
|
||||
statusText.should.eql 'success'
|
||||
})
|
||||
end
|
||||
|
||||
it 'should work with a json fixture'
|
||||
mockRequest().and_return(fixture('test.json'))
|
||||
$.getJSON('foo', function(response){
|
||||
response.users.tj.email.should.eql 'tj@vision-media.ca'
|
||||
})
|
||||
end
|
||||
|
||||
it 'should not invoke callback when response status is 4xx'
|
||||
mockRequest().and_return('foo', 'text/plain', 404)
|
||||
$.getJSON('foo', function(){
|
||||
fail('callback was invoked')
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
describe '.post()'
|
||||
it 'should work with mockRequest'
|
||||
mockRequest().and_return('<p></p>', 'text/html')
|
||||
$.post('foo', function(response){
|
||||
response.should.eql '<p></p>'
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
127
thirdparty/jquery-concrete/vendor/jspec/spec/spec.js
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
|
||||
describe 'Negative specs'
|
||||
|
||||
it 'should fail'
|
||||
'test'.should.not_eql 'test'
|
||||
end
|
||||
|
||||
it 'should fail with one faulty assertion'
|
||||
'test'.should.equal 'test'
|
||||
'test'.should.equal 'foo'
|
||||
end
|
||||
|
||||
it 'should fail and print array with square braces'
|
||||
[1,2].should.equal [1,3]
|
||||
end
|
||||
|
||||
it 'should fail and print nested array'
|
||||
[1, ['foo']].should.equal [1, ['bar', ['whatever', 1.0, { foo : 'bar', bar : { 1 : 2 } }]]]
|
||||
end
|
||||
|
||||
it 'should fail and print html elements'
|
||||
elem = document.createElement('a')
|
||||
elem.setAttribute('href', 'http://vision-media.ca')
|
||||
elem.should.not.eql elem
|
||||
end
|
||||
|
||||
it 'should fail with selector for jQuery objects'
|
||||
elem = { jquery : '1.3.1', selector : '.foobar' }
|
||||
elem.should.eql 'foo'
|
||||
end
|
||||
|
||||
it 'should fail with negative message'
|
||||
'1'.should.not.be_true
|
||||
end
|
||||
|
||||
it 'should fail with positive message'
|
||||
false.should.be_true
|
||||
end
|
||||
|
||||
it 'should fail saying an error was throw'
|
||||
-{ throw 'foo' }.should.not.throw_error
|
||||
end
|
||||
|
||||
it 'should fail saying which error has been thrown'
|
||||
-{ throw 'foo' }.should.throw_error 'bar'
|
||||
end
|
||||
|
||||
it 'should fail saying no error was thrown'
|
||||
-{ }.should.throw_error 'foo'
|
||||
end
|
||||
|
||||
it 'should fail saying no error matching was thrown'
|
||||
-{ throw 'bar' }.should.throw_error(/foo/)
|
||||
end
|
||||
|
||||
it 'should fail saying no error matching foo should be thrown'
|
||||
-{ throw 'foo' }.should.not.throw_error(/foo/)
|
||||
end
|
||||
|
||||
it 'should fail saying constructors'
|
||||
-{ throw new TypeError('oh no') }.should.throw_error(Error)
|
||||
end
|
||||
|
||||
it 'should fail saying multiple arg messages'
|
||||
-{ throw new TypeError('oh no') }.should.throw_error(TypeError, /foo/)
|
||||
end
|
||||
|
||||
it 'should fail with constructor name'
|
||||
function Foo(){}
|
||||
function Bar(){}
|
||||
Bar.prototype.toString = function(){ return 'Bar error: oh no' }
|
||||
-{ throw new Bar }.should.throw_error Foo
|
||||
end
|
||||
|
||||
it 'should fail with function body string'
|
||||
-{ 'foo' }.should.not.include 'foo'
|
||||
end
|
||||
|
||||
it 'should fail with constructor name'
|
||||
function Foo(){ this.toString = function(){ return '<Foo>' }}
|
||||
foo = new Foo
|
||||
foo.should.not.be_an_instance_of Foo
|
||||
end
|
||||
|
||||
it 'should fail with message of first failure'
|
||||
true.should.be_true
|
||||
'bar'.should.match(/foo/gm)
|
||||
'bar'.should.include 'foo'
|
||||
end
|
||||
|
||||
it 'should fail with list'
|
||||
['foo', 'bar'].should.include 'foo', 'car'
|
||||
end
|
||||
|
||||
it 'should catch exceptions throw within specs'
|
||||
throw new Error('Oh noes!')
|
||||
end
|
||||
|
||||
it 'should catch improper exceptions'
|
||||
throw 'oh noes'
|
||||
end
|
||||
|
||||
it 'should catch proper exceptions'
|
||||
iDoNotExist.neitherDoI()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'Contexts'
|
||||
before
|
||||
JSpec.context = { iLike : 'cookies' }
|
||||
end
|
||||
|
||||
after
|
||||
JSpec.context = null
|
||||
end
|
||||
|
||||
it 'should be replaceable'
|
||||
iLike.should.equal 'cookies'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Misc'
|
||||
it 'requires implementation'
|
||||
end
|
||||
end
|
||||
|
492
thirdparty/jquery-concrete/vendor/jspec/spec/spec.matchers.js
vendored
Normal file
@ -0,0 +1,492 @@
|
||||
|
||||
describe 'Matchers'
|
||||
|
||||
describe 'eql'
|
||||
it 'should work with strings'
|
||||
'test'.should.eql 'test'
|
||||
'test'.should.not.eql 'foo'
|
||||
end
|
||||
|
||||
it 'should work with numbers'
|
||||
11.should.eql 11
|
||||
10.should.not.eql 11
|
||||
end
|
||||
|
||||
it 'should loosely compare numbers as strings'
|
||||
'11'.should.eql 11
|
||||
'10'.should.not.eql 11
|
||||
end
|
||||
|
||||
it 'should hash compare arrays'
|
||||
[1, 2].should.eql [1, 2]
|
||||
[1, 2].should.not.eql [1, 3]
|
||||
[1, 2, [3], { foo : 'bar' }].should.eql [1, 2, [3], { foo : 'bar' }]
|
||||
end
|
||||
|
||||
it 'should hash compare objects'
|
||||
{ foo : 'bar' }.should.eql { foo : 'bar' }
|
||||
end
|
||||
|
||||
it 'should hash compare objects with different orders'
|
||||
a = { one : 'two', three : 'four' }
|
||||
b = { three : 'four', one : 'two' }
|
||||
a.should.eql b
|
||||
end
|
||||
|
||||
it 'should hash compare arbitrary objects'
|
||||
Foo = function(){}, Bar = function(){}
|
||||
Bar.prototype = { doSomething : function(){ }}
|
||||
foo = new Foo, foo2 = new Foo, bar = new Bar
|
||||
foo.should.eql foo2
|
||||
foo.should.not.eql bar
|
||||
end
|
||||
|
||||
it 'should work with constructors'
|
||||
Array.should.eql Array
|
||||
Array.should.not.eql Object
|
||||
end
|
||||
end
|
||||
|
||||
describe 'equal'
|
||||
it 'should perform strict comparisons'
|
||||
'test'.should.equal 'test'
|
||||
'1'.should.not.equal 1
|
||||
true.should.be true
|
||||
'1'.should.not.be true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'match'
|
||||
it 'should match regular expressions'
|
||||
'foobar'.should.match(/foo/)
|
||||
'foobar'.should.not.match(/barfoo/)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_empty'
|
||||
it 'should consider any object with zero length to be empty'
|
||||
''.should.be_empty
|
||||
' '.should.not.be_empty
|
||||
[].should.be_empty
|
||||
{ length : 0 }.should.be_empty
|
||||
{}.should.be_empty
|
||||
'cookies'.should.not.be_empty
|
||||
[0].should.not.be_empty
|
||||
{ length : 1 }.should.not.be_empty
|
||||
{ foo : 'bar' }.should.not.be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_null'
|
||||
it 'should check if a value is null'
|
||||
a = 0
|
||||
b = null
|
||||
null.should.be_null
|
||||
0.should.not.be_null
|
||||
a.should.not.be_null
|
||||
b.should.be_null
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_undefined'
|
||||
it 'should check if a var is defined'
|
||||
var foo
|
||||
foo.should.be_undefined
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_length'
|
||||
it 'should compare the length of an object'
|
||||
'foo'.should.have_length 3
|
||||
[1, 2].should.have_length 2
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_length_within'
|
||||
it 'should check if an object has a length within the specified range'
|
||||
'foo'.should.have_length_within 2..4
|
||||
'f'.should.not.have_length_within 2..4
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_prop'
|
||||
it 'should check if a property exists'
|
||||
'foo'.should.have_prop 'length'
|
||||
end
|
||||
|
||||
it 'should check that a property has a specific value'
|
||||
'foo'.should.have_prop 'length', 3
|
||||
{ length : '3' }.should.have_prop 'length', 3
|
||||
end
|
||||
|
||||
it 'should check object hashes'
|
||||
{ foo : 1..3 }.should.have_prop 'foo', 1..3
|
||||
end
|
||||
|
||||
it 'should fail when the property does not exist'
|
||||
'foo'.should.not.have_prop 'foo'
|
||||
'foo'.should.not.have_prop 'foo', 'bar'
|
||||
end
|
||||
|
||||
it 'should fail when it is a function'
|
||||
'foo'.should.not.have_prop 'toString'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_property'
|
||||
it 'should check if a property exists'
|
||||
'foo'.should.have_property 'length'
|
||||
end
|
||||
|
||||
it 'should check that a property has a specific value'
|
||||
'foo'.should.have_property 'length', 3
|
||||
{ length : '3' }.should.not.have_property 'length', 3
|
||||
end
|
||||
|
||||
it 'should fail when the property does not exist'
|
||||
'foo'.should.not.have_property 'foo'
|
||||
'foo'.should.not.have_property 'foo', 'bar'
|
||||
end
|
||||
|
||||
it 'should fail when it is a function'
|
||||
'foo'.should.not.have_property 'toString'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'respond_to'
|
||||
it 'should check if an object contains a method'
|
||||
'test'.should.respond_to('toString')
|
||||
'test'.should.not.respond_to('rawr')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'include'
|
||||
it 'should check if an object includes a property'
|
||||
{ hey : 'there' }.should.include 'hey'
|
||||
{ hey : 'there' }.should.not.include 'foo'
|
||||
end
|
||||
|
||||
it 'should check if a regular expression includes a string'
|
||||
(/(foo)?bar/).should.include '(foo)'
|
||||
end
|
||||
|
||||
it 'should check if a function body includes a string'
|
||||
-{ return [foo, bar] }.should.include 'foo', 'bar'
|
||||
end
|
||||
|
||||
it 'should check if an array contains element(s)'
|
||||
[1,2,3].should.include 1
|
||||
[1,2,3].should.include 1, 2, 3
|
||||
[1].should.not.include 0
|
||||
['foo', 'bar'].should.include 'foo', 'bar'
|
||||
['foo', 'bar'].should.include 'bar', 'foo'
|
||||
['foo', 'bar'].should.not.include 'foo', 'rawr'
|
||||
['foo', 'bar'].should.not.include 'rawr', 'foo'
|
||||
end
|
||||
|
||||
it 'should check hashes of array elements'
|
||||
[1, [2]].should.include [2]
|
||||
[1, [2]].should.include [2], 1
|
||||
[1, { two : 'three' }].should.include { two : 'three' }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_a'
|
||||
it 'should compare the constructor of an object'
|
||||
'test'.should.be_a String
|
||||
[].should.be_an Array
|
||||
end
|
||||
end
|
||||
|
||||
describe 'throw_error'
|
||||
it 'should check if an error is thrown'
|
||||
-{ throw 'error' }.should.throw_error
|
||||
-{ return 'test' }.should.not.throw_error
|
||||
end
|
||||
|
||||
it 'should check if an error with a specific message is thrown'
|
||||
-{ throw 'some foo bar' }.should.throw_error('some foo bar')
|
||||
-{ throw 'some foo bar' }.should.throw_error(/foo bar/)
|
||||
-{ throw 'some foo bar' }.should.not.throw_error(/rawr/)
|
||||
-{ throw 'some foo bar' }.should.not.throw_error('rawr')
|
||||
end
|
||||
|
||||
it 'should check if an error of a specific constructor is thrown'
|
||||
-{ throw new Error('foo') }.should.throw_error(Error)
|
||||
-{ throw new TypeError('foo') }.should.throw_error(TypeError)
|
||||
-{ throw 'foo' }.should.throw_error Error
|
||||
-{ throw 'foo' }.should.not.throw_error TypeError
|
||||
end
|
||||
|
||||
it 'should check if an error with a specific constructor and message is thrown'
|
||||
-{ throw new TypeError('oh no!') }.should.throw_error(TypeError, 'oh no!')
|
||||
-{ throw new TypeError('oh no!') }.should.not.throw_error(TypeError, 'foo bar')
|
||||
-{ throw new TypeError('oh no!') }.should.throw_error(TypeError, /oh no/)
|
||||
-{ throw new TypeError('oh no!') }.should.not.throw_error(TypeError, /foo bar/)
|
||||
-{ throw new TypeError('oh no!') }.should.not.throw_error(Error, 'oh no!')
|
||||
-{ throw new TypeError('oh no!') }.should.not.throw_error(Error, 'foo bar')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_an_instance_of'
|
||||
it 'should check that an object is an instance of another'
|
||||
MyObject = function(){}
|
||||
myInstance = new MyObject()
|
||||
{}.should.be_an_instance_of Object
|
||||
[].should.be_an_instance_of Array
|
||||
MyObject.should.be_an_instance_of Function
|
||||
myInstance.should.be_an_instance_of MyObject
|
||||
myInstance.should.be_an_instance_of Object
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_type'
|
||||
it 'should compare the type of an object via typeof'
|
||||
'hey'.should.be_type 'string'
|
||||
{}.should.be_type 'object'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_within'
|
||||
it 'should check if a number is within a range'
|
||||
5.should.be_within 1..10
|
||||
15.should.not.be_within 10..5
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have'
|
||||
it 'should check the length of a property'
|
||||
person = { pets : ['izzy', 'niko'] }
|
||||
person.should.have 2, 'pets'
|
||||
person.should.not.have 3, 'pets'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_at_least'
|
||||
it 'should check if a object has at least n of a property'
|
||||
person = { pets : ['izzy', 'niko'] }
|
||||
person.should.have_at_least 1, 'pets'
|
||||
person.should.have_at_least 2, 'pets'
|
||||
person.should.not.have_at_least 3, 'pets'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'have_at_most'
|
||||
it 'should check if an object has at most n of a property'
|
||||
person = { pets : ['izzy', 'niko'] }
|
||||
person.should.have_at_most 2, 'pets'
|
||||
person.should.have_at_most 3, 'pets'
|
||||
person.should.not.have_at_most 1, 'pets'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'be_within'
|
||||
it 'should check that an object has within n..n of a property'
|
||||
person = { pets : ['izzy', 'niko'] }
|
||||
person.should.have_within 1..2, 'pets'
|
||||
person.should.have_within 2..5, 'pets'
|
||||
person.should.not.have_within 5..10, 'pets'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'receive'
|
||||
before_each
|
||||
person = { toString : function(){ return 'person' }}
|
||||
personWithPets = {
|
||||
toString : function(){ return 'personWithPets' },
|
||||
getPets : function() { return ['izzy'] },
|
||||
addPet : function(name) { return ['izzy', name] },
|
||||
addPets : function(a, b) { return ['izzy', a, b] }
|
||||
}
|
||||
end
|
||||
it 'should pass when the method is invoked'
|
||||
personWithPets.should.receive('getPets')
|
||||
personWithPets.getPets()
|
||||
end
|
||||
|
||||
it 'should pass and original method should still return its result'
|
||||
personWithPets.should.receive('getPets')
|
||||
personWithPets.getPets().should.eql ['izzy']
|
||||
end
|
||||
|
||||
it 'should pass when the proper value is returned'
|
||||
personWithPets.should.receive('getPets').and_return(['izzy'])
|
||||
personWithPets.getPets()
|
||||
end
|
||||
|
||||
it 'should pass when invoked the expected number of times'
|
||||
personWithPets.should.receive('getPets', 'twice').and_return(['izzy'])
|
||||
personWithPets.getPets()
|
||||
personWithPets.getPets()
|
||||
end
|
||||
|
||||
it 'should pass when a method is invoked with specific arguments'
|
||||
personWithPets.should.receive('addPet', 'once').with_args('suki')
|
||||
personWithPets.addPet('suki')
|
||||
end
|
||||
|
||||
it 'should pass with multiple arguments'
|
||||
personWithPets.should.receive('addPets').with_args('suki', 'max')
|
||||
personWithPets.addPets('suki', 'max')
|
||||
end
|
||||
|
||||
it 'should pass with arguments and return value'
|
||||
personWithPets.should.receive('addPet').with_args('suki').and_return(['izzy', 'suki'])
|
||||
personWithPets.addPet('suki')
|
||||
end
|
||||
|
||||
it 'should pass when argument is the correct type'
|
||||
personWithPets.should.receive('addPet').with_args(an_instance_of(String))
|
||||
personWithPets.addPet('suki')
|
||||
end
|
||||
|
||||
it 'should pass when return type is correct'
|
||||
personWithPets.should.receive('addPet').and_return(an_instance_of(Array))
|
||||
personWithPets.addPet('suki')
|
||||
end
|
||||
|
||||
it 'should pass when checking the type of multiple args and return types'
|
||||
personWithPets.should.receive('addPets').with_args(an_instance_of(String), an_instance_of(String)).and_return(an_instance_of(Array))
|
||||
personWithPets.addPets('suki', 'max')
|
||||
end
|
||||
|
||||
it 'should pass with negation when a method is not called'
|
||||
personWithPets.should.not.receive('addPets')
|
||||
end
|
||||
|
||||
it 'should pass with negation with args'
|
||||
personWithPets.should.not.receive('addPets').with_args('izzy')
|
||||
personWithPets.addPets('max')
|
||||
end
|
||||
|
||||
it 'should pass with negation with return values'
|
||||
personWithPets.should.not.receive('addPets').with_args('izzy').and_return('test')
|
||||
personWithPets.addPets('izzy')
|
||||
end
|
||||
|
||||
it 'should pass with negation with times'
|
||||
personWithPets.should.not.receive('addPets', 'twice')
|
||||
personWithPets.addPets('izzy')
|
||||
end
|
||||
|
||||
it 'should pass with boolean args'
|
||||
foo = { bar : function(arg){ return arg }}
|
||||
foo.should.receive('bar', 'twice').with_args(true)
|
||||
foo.bar(true)
|
||||
foo.bar(true)
|
||||
end
|
||||
|
||||
it 'should pass with null args'
|
||||
foo = { bar : function(arg){ return arg }}
|
||||
foo.should.receive('bar').with_args(null)
|
||||
foo.bar(null)
|
||||
end
|
||||
|
||||
it 'should pass with boolean return value true'
|
||||
foo = { bar : function(){ return true }}
|
||||
foo.should.receive('bar').and_return(true)
|
||||
foo.bar()
|
||||
end
|
||||
|
||||
it 'should pass with boolean return value false'
|
||||
foo = { bar : function(){ return false }}
|
||||
foo.should.receive('bar').and_return(false)
|
||||
foo.bar()
|
||||
end
|
||||
|
||||
it 'should pass with null return value'
|
||||
foo = { bar : function(){ return null }}
|
||||
foo.should.receive('bar').and_return(null)
|
||||
foo.bar()
|
||||
end
|
||||
|
||||
it 'should fail when the method does not exist'
|
||||
person.should.receive('getPets')
|
||||
end
|
||||
|
||||
it 'should fail when the method is never invoked'
|
||||
personWithPets.should.receive('getPets')
|
||||
end
|
||||
|
||||
it 'should fail when improper value is returned'
|
||||
personWithPets.should.receive('getPets').and_return(['niko'])
|
||||
personWithPets.getPets()
|
||||
end
|
||||
|
||||
it 'should fail when checking the type of multiple args and return types'
|
||||
personWithPets.should.receive('addPets').with_args(an_instance_of(String), an_instance_of(Array)).and_return(an_instance_of(Array))
|
||||
personWithPets.addPets('suki', 'max')
|
||||
end
|
||||
|
||||
it 'should fail when not invoked the expected number of times'
|
||||
personWithPets.should.receive('getPets', 'twice').and_return(['izzy'])
|
||||
personWithPets.getPets()
|
||||
end
|
||||
|
||||
it 'should fail when not invoked many times'
|
||||
personWithPets.should.receive('getPets', 3).and_return(['izzy'])
|
||||
personWithPets.getPets()
|
||||
personWithPets.getPets()
|
||||
end
|
||||
|
||||
it 'should fail when not invoked with specific arguments'
|
||||
personWithPets.should.receive('addPet', 'once').with_args('suki')
|
||||
personWithPets.addPet('niko')
|
||||
end
|
||||
|
||||
it 'should fail when expecting multiple arguments'
|
||||
personWithPets.should.receive('addPets').with_args('suki', 'max')
|
||||
personWithPets.addPets('suki')
|
||||
end
|
||||
|
||||
it 'should fail when argument is of the wrong type'
|
||||
personWithPets.should.receive('addPet').with_args(an_instance_of(String))
|
||||
personWithPets.addPet(['suki'])
|
||||
end
|
||||
|
||||
it 'should fail when return type is incorrect'
|
||||
personWithPets.should.receive('addPet').and_return(an_instance_of(String))
|
||||
personWithPets.addPet('suki')
|
||||
end
|
||||
|
||||
it 'should fail with negation when a method is called'
|
||||
personWithPets.should.not.receive('addPets')
|
||||
personWithPets.addPets('izzy')
|
||||
end
|
||||
|
||||
it 'should fail with negation with args'
|
||||
personWithPets.should.not.receive('addPets').with_args('izzy')
|
||||
personWithPets.addPets('izzy')
|
||||
end
|
||||
|
||||
it 'should fail with negation with return values'
|
||||
personWithPets.should.not.receive('addPets').with_args('izzy').and_return(an_instance_of(Array))
|
||||
personWithPets.addPets('izzy')
|
||||
end
|
||||
|
||||
it 'should fail with negation with times'
|
||||
personWithPets.should.not.receive('addPets', 'twice')
|
||||
personWithPets.addPets('izzy')
|
||||
personWithPets.addPets('max')
|
||||
end
|
||||
|
||||
it 'should fail with boolean args'
|
||||
foo = { bar : function(arg){ return arg }}
|
||||
foo.should.receive('bar').with_args(true)
|
||||
foo.bar(false)
|
||||
end
|
||||
|
||||
it 'should fail with boolean return value true'
|
||||
foo = { bar : function(){ return true }}
|
||||
foo.should.receive('bar').and_return(false)
|
||||
foo.bar()
|
||||
end
|
||||
|
||||
it 'should fail with boolean return value false'
|
||||
foo = { bar : function(){ return false }}
|
||||
foo.should.receive('bar').and_return(true)
|
||||
foo.bar()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
67
thirdparty/jquery-concrete/vendor/jspec/spec/spec.modules.js
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
|
||||
describe 'JSpec'
|
||||
describe 'module'
|
||||
describe 'hooks'
|
||||
it 'should run beforeSpec'
|
||||
addedBeforeSpec.should.be_true
|
||||
end
|
||||
|
||||
it 'should run afterSpec'
|
||||
addedAfterSpec.should.be_true
|
||||
end
|
||||
|
||||
describe 'with suites'
|
||||
it 'should run beforeSuite'
|
||||
addedBeforeSuite.should.be_true
|
||||
end
|
||||
end
|
||||
|
||||
it 'should run afterSuite'
|
||||
addedAfterSuite.should.be_true
|
||||
end
|
||||
|
||||
it 'should run in context with JSpec'
|
||||
hook('checkJSpecContext')[0].should.equal JSpec.each
|
||||
end
|
||||
|
||||
it 'should run in context to JSpecs default context'
|
||||
hook('checkContext')[0].should.eql fixture('test')
|
||||
end
|
||||
|
||||
it 'should run in context to the module itself'
|
||||
hook('checkModuleContext')[0].should.eql 'ExampleModule'
|
||||
end
|
||||
|
||||
it 'should run in context to the modules utilities'
|
||||
hook('checkUtilityContext')[0].should.eql 'foo'
|
||||
end
|
||||
end
|
||||
|
||||
describe '.hook()'
|
||||
it 'should invoke hooks, returning an array of results'
|
||||
results = hook('randomHook', 'foo', 'bar')
|
||||
results.should.eql [['foo', 'bar']]
|
||||
end
|
||||
end
|
||||
|
||||
describe '.utilities'
|
||||
it 'should be merged with the default utilities'
|
||||
doFoo().should.eql 'foo'
|
||||
doBar().should.eql 'bar'
|
||||
end
|
||||
end
|
||||
|
||||
describe '.matchers'
|
||||
it 'should be merged with default matchers'
|
||||
'test'.should.be_foo_bar
|
||||
end
|
||||
end
|
||||
|
||||
describe '.DSLs'
|
||||
it 'should be merged with default DSLs'
|
||||
JSpec.DSLs.snake.some_snake_case_stuff().should.be_true
|
||||
JSpec.DSLs.camel.someCamelCaseStuff().should.be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
46
thirdparty/jquery-concrete/vendor/jspec/spec/spec.node.js
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
__loading__ = []
|
||||
__loadDelay__ = 1000
|
||||
|
||||
originalPrint = print
|
||||
print = puts
|
||||
|
||||
readFile = function(path, callback) {
|
||||
__loading__.push(path)
|
||||
var promise = node.fs.cat(path, "utf8")
|
||||
promise.addErrback(function(){ throw "failed to read file `" + path + "'" })
|
||||
promise.addCallback(function(contents){
|
||||
setTimeout(function(){
|
||||
if (__loading__[0] == path)
|
||||
__loading__.shift(), callback(contents)
|
||||
else
|
||||
setTimeout(arguments.callee, 50)
|
||||
}, 50)
|
||||
})
|
||||
}
|
||||
|
||||
load = function(path) {
|
||||
readFile(path, function(contents){
|
||||
eval(contents)
|
||||
})
|
||||
}
|
||||
|
||||
load('lib/jspec.js')
|
||||
load('spec/modules.js')
|
||||
load('spec/spec.grammar-less.js')
|
||||
|
||||
setTimeout(function(){
|
||||
JSpec
|
||||
.exec('spec/spec.grammar.js')
|
||||
.exec('spec/spec.js')
|
||||
.exec('spec/spec.matchers.js')
|
||||
.exec('spec/spec.utils.js')
|
||||
.exec('spec/spec.shared-behaviors.js')
|
||||
setTimeout(function(){
|
||||
JSpec.run({ formatter : JSpec.formatters.Terminal, failuresOnly : false })
|
||||
setTimeout(function() {
|
||||
JSpec.report()
|
||||
}, __loadDelay__ / 3)
|
||||
}, __loadDelay__ / 3)
|
||||
}, __loadDelay__ / 3)
|
||||
|
17
thirdparty/jquery-concrete/vendor/jspec/spec/spec.rhino.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
load('lib/jspec.js')
|
||||
load('lib/jspec.xhr.js')
|
||||
load('spec/modules.js')
|
||||
load('spec/spec.grammar-less.js')
|
||||
|
||||
JSpec
|
||||
.exec('spec/spec.grammar.js')
|
||||
.exec('spec/spec.js')
|
||||
.exec('spec/spec.matchers.js')
|
||||
.exec('spec/spec.utils.js')
|
||||
.exec('spec/spec.fixtures.js')
|
||||
.exec('spec/spec.shared-behaviors.js')
|
||||
.exec('spec/spec.modules.js')
|
||||
.exec('spec/spec.xhr.js')
|
||||
.run({ formatter : JSpec.formatters.Terminal, failuresOnly : false })
|
||||
.report()
|
29
thirdparty/jquery-concrete/vendor/jspec/spec/spec.server.html
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
|
||||
<script src="jspec.js"></script>
|
||||
<script src="jspec.jquery.js"></script>
|
||||
<script src="jspec.xhr.js"></script>
|
||||
<script src="modules.js"></script>
|
||||
<script src="spec.grammar-less.js"></script>
|
||||
<script>
|
||||
function runSuites() {
|
||||
JSpec
|
||||
.exec('spec.grammar.js')
|
||||
.exec('spec.js')
|
||||
.exec('spec.matchers.js')
|
||||
.exec('spec.utils.js')
|
||||
.exec('spec.fixtures.js')
|
||||
.exec('spec.shared-behaviors.js')
|
||||
.exec('spec.jquery.js')
|
||||
.exec('spec.modules.js')
|
||||
.exec('spec.xhr.js')
|
||||
.exec('spec.jquery.xhr.js')
|
||||
.run()
|
||||
.reportToServer()
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="jspec" onLoad="runSuites();">
|
||||
</body>
|
||||
</html>
|
80
thirdparty/jquery-concrete/vendor/jspec/spec/spec.shared-behaviors.js
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
|
||||
describe 'Shared Behaviors'
|
||||
describe 'User'
|
||||
before
|
||||
User = function(name) { this.name = name }
|
||||
user = new User('joe')
|
||||
end
|
||||
|
||||
it 'should have a name'
|
||||
user.should.have_property 'name'
|
||||
end
|
||||
|
||||
describe 'Administrator'
|
||||
should_behave_like('User')
|
||||
|
||||
before
|
||||
Admin = function(name) { this.name = name }
|
||||
Admin.prototype.may = function(perm){ return true }
|
||||
user = new Admin('tj')
|
||||
end
|
||||
|
||||
it 'should have access to all permissions'
|
||||
user.may('edit pages').should.be_true
|
||||
user.may('delete users').should.be_true
|
||||
end
|
||||
|
||||
describe 'Super Administrator'
|
||||
should_behave_like('Administrator')
|
||||
|
||||
before
|
||||
SuperAdmin = function(name) { this.name = name }
|
||||
SuperAdmin.prototype.may = function(perm){ return true }
|
||||
user = new SuperAdmin('tj')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'User with toString()'
|
||||
before
|
||||
user = { toString : function() { return '<User tj>' }}
|
||||
end
|
||||
|
||||
it 'should return <User NAME>'
|
||||
user.toString().should.match(/\<User/)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Manager'
|
||||
should_behave_like('User')
|
||||
should_behave_like('User with toString()')
|
||||
|
||||
before
|
||||
Manager = function(name) { this.name = name }
|
||||
Manager.prototype.may = function(perm){ return perm == 'hire' || perm == 'fire' }
|
||||
Manager.prototype.toString = function(){ return '<User ' + this.name + '>' }
|
||||
user = new Manager('tj')
|
||||
end
|
||||
|
||||
it 'should have access to hire or fire employees'
|
||||
user.may('hire').should.be_true
|
||||
user.may('fire').should.be_true
|
||||
user.may('do anything else').should.be_false
|
||||
end
|
||||
end
|
||||
|
||||
describe 'findSuite'
|
||||
it 'should find a suite by full description'
|
||||
JSpec.findSuite('Shared Behaviors User Administrator').should.be_a JSpec.Suite
|
||||
end
|
||||
|
||||
it 'should find a suite by name'
|
||||
JSpec.findSuite('User').should.be_a JSpec.Suite
|
||||
end
|
||||
|
||||
it 'should return null when not found'
|
||||
JSpec.findSuite('Rawr').should.be_null
|
||||
end
|
||||
end
|
||||
end
|
276
thirdparty/jquery-concrete/vendor/jspec/spec/spec.utils.js
vendored
Normal file
@ -0,0 +1,276 @@
|
||||
|
||||
describe 'Utility'
|
||||
describe 'fail()'
|
||||
it 'should fail the current spec'
|
||||
fail('I failed!')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'pass()'
|
||||
it 'should pass the current spec'
|
||||
pass('yay')
|
||||
pass('wahoo')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'stubbing'
|
||||
before_each
|
||||
Object.prototype.stubby = function() { return 'Not stubbed' }
|
||||
object = { toString : function() { return '<Im an object>' }}
|
||||
stub(object, 'stubby').and_return('Im stubbed')
|
||||
stub(object, 'toString').and_return('<No im not>')
|
||||
end
|
||||
|
||||
after_each
|
||||
delete Object.prototype.stubby
|
||||
end
|
||||
|
||||
describe 'stub()'
|
||||
it 'should stub :)'
|
||||
object.stubby().should.eql 'Im stubbed'
|
||||
object.toString().should.eql '<No im not>'
|
||||
end
|
||||
|
||||
it 'should allow being called as a core prototype method'
|
||||
foo = { bar : function(){ return 'baz' }}
|
||||
foo.stub('bar').and_return('something else')
|
||||
foo.bar().should.eql 'something else'
|
||||
foo.destub()
|
||||
foo.bar().should.eql 'baz'
|
||||
end
|
||||
|
||||
it 'should stub methods starting with an underscore'
|
||||
object._foo = function(){ return 'bar' }
|
||||
object.stub('_foo').and_return('something else')
|
||||
object._foo().should.eql 'something else'
|
||||
object.destub()
|
||||
object._foo().should.eql 'bar'
|
||||
end
|
||||
|
||||
it 'should stub methods with whitespace'
|
||||
object['foo bar'] = function(){ return 'rawr' }
|
||||
object.stub('foo bar').and_return('baz')
|
||||
object['foo bar']().should.eql 'baz'
|
||||
object.destub()
|
||||
object['foo bar']().should.eql 'rawr'
|
||||
end
|
||||
|
||||
it 'should stub with arbitrary method when no return value is set'
|
||||
object.stub(' super cool ')
|
||||
object[' super cool '].should.be_a Function
|
||||
destub(object)
|
||||
object[' super cool '].should.be_null
|
||||
end
|
||||
|
||||
it 'should stub sub properties using the JSpec grammar'
|
||||
object = { foo : { bar : {}}}
|
||||
object.foo.bar.stub('kitten').and_return('meow')
|
||||
object.foo.bar.kitten().should.eql 'meow'
|
||||
object.foo.bar.destub()
|
||||
object.foo.bar.should.not.respond_to('kitten')
|
||||
end
|
||||
|
||||
it 'should allow functions to be passed as a method'
|
||||
stub(object, 'post').and_return(function(url, callback){
|
||||
if (url == 'http://jspec.info')
|
||||
callback('is awesome')
|
||||
})
|
||||
object.post('http://jspec.info', function(text){
|
||||
text.should_eql 'is awesome'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
describe 'destub()'
|
||||
it 'should restore old methods'
|
||||
destub(object, 'toString')
|
||||
destub(object, 'stubby')
|
||||
object.toString().should.eql '<Im an object>'
|
||||
object.stubby().should.eql 'Not stubbed'
|
||||
end
|
||||
|
||||
it 'should restore prototypal methods'
|
||||
Object.prototype.stubby = function() { return 'Oh no im new' }
|
||||
destub(object, 'stubby')
|
||||
object.stubby().should.eql 'Oh no im new'
|
||||
end
|
||||
|
||||
it 'should destub all methods stubbed related to the object passed when no method is given'
|
||||
destub(object)
|
||||
object.toString().should.eql '<Im an object>'
|
||||
object.stubby().should.eql 'Not stubbed'
|
||||
end
|
||||
|
||||
describe 'should restore after each spec'
|
||||
before
|
||||
a = { toString : function(){ return 'Wahoo' }}
|
||||
b = { toString : function(){ return 'Wahhhhhooo' }}
|
||||
end
|
||||
|
||||
it 'should stub'
|
||||
stub(a, 'toString').and_return('Oh no')
|
||||
stub(b, 'toString').and_return('Oh noooo')
|
||||
a.toString().should.eql 'Oh no'
|
||||
b.toString().should.eql 'Oh noooo'
|
||||
end
|
||||
|
||||
it 'should restore'
|
||||
a.toString().should.eql 'Wahoo'
|
||||
b.toString().should.eql 'Wahhhhhooo'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'query()'
|
||||
it 'should return a pairs value'
|
||||
query('suite', '?suite=Positive%20specs').should.equal 'Positive specs'
|
||||
end
|
||||
|
||||
it 'should return null when key is not present'
|
||||
query('foo', '?suite=Positive%20specs').should.be_null
|
||||
end
|
||||
end
|
||||
|
||||
describe 'strip()'
|
||||
it 'should strip whitespace by default'
|
||||
strip(" foo \n\n").should.equal 'foo'
|
||||
end
|
||||
|
||||
it 'should strip the characters passed'
|
||||
strip('[foo]', '\\[\\]').should.equal 'foo'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'each()'
|
||||
it 'should iterate an array'
|
||||
result = []
|
||||
each([1,2,3], function(value){
|
||||
result.push(value)
|
||||
})
|
||||
result.should.eql [1,2,3]
|
||||
end
|
||||
|
||||
it 'should iterate words in a string'
|
||||
result = []
|
||||
each('some foo bar', function(value){
|
||||
result.push(value)
|
||||
})
|
||||
result.should.eql ['some', 'foo', 'bar']
|
||||
end
|
||||
end
|
||||
|
||||
describe 'map()'
|
||||
it 'should return an array of mapped values'
|
||||
result = map([1,2,3], function(value){
|
||||
return value * 2
|
||||
})
|
||||
result.should.eql [2,4,6]
|
||||
end
|
||||
|
||||
it 'should inherit the ability to iterate words in a string'
|
||||
result = map('some foo bar', function(i, value){
|
||||
return i + '-' + value
|
||||
})
|
||||
result.should.eql ['0-some', '1-foo', '2-bar']
|
||||
end
|
||||
end
|
||||
|
||||
describe 'inject()'
|
||||
it 'should provide a memo object while iterating, not expecting returning of memo for composits'
|
||||
result = inject([1,2,3], [], function(memo, value){
|
||||
memo.push(value)
|
||||
})
|
||||
result.should.eql [1,2,3]
|
||||
end
|
||||
|
||||
it 'should require returning of memo for scalar variables'
|
||||
result = inject([1,2,3], false, function(memo, value){
|
||||
return memo ? memo : value == 2
|
||||
})
|
||||
result.should.be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'any()'
|
||||
it 'should return null when no matches are found'
|
||||
result = any('some foo bar', function(value){
|
||||
return value.length > 5
|
||||
})
|
||||
result.should.be_null
|
||||
end
|
||||
|
||||
it 'should return the value of the first matching expression'
|
||||
result = any('foo some bar', function(value){
|
||||
return value.length > 3
|
||||
})
|
||||
result.should.eql 'some'
|
||||
end
|
||||
|
||||
describe 'haveStopped'
|
||||
it 'should check if "stop" has been returned by a callback hook'
|
||||
any([true, 'stop'], haveStopped).should.eql 'stop'
|
||||
any([true, true], haveStopped).should.be_null
|
||||
any([true, null], haveStopped).should.be_null
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'select()'
|
||||
it 'should return an array of values when the callback evaluates to true'
|
||||
result = select('some foo bar baz stuff', function(value){
|
||||
return value.length > 3
|
||||
})
|
||||
result.should.eql ['some', 'stuff']
|
||||
end
|
||||
end
|
||||
|
||||
describe 'last()'
|
||||
it 'should return the last element in an array'
|
||||
last(['foo', 'bar']).should.eql 'bar'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'argumentsToArray()'
|
||||
it 'should return an array of arguments'
|
||||
func = function(){ return argumentsToArray(arguments) }
|
||||
func('foo', 'bar').should.eql ['foo', 'bar']
|
||||
end
|
||||
|
||||
it 'should return the offset of an arguments array'
|
||||
func = function(){ return argumentsToArray(arguments, 2) }
|
||||
func('foo', 'bar', 'baz').should.eql ['baz']
|
||||
end
|
||||
end
|
||||
|
||||
describe 'does()'
|
||||
it 'should assert without reporting'
|
||||
does('foo', 'eql', 'foo')
|
||||
JSpec.currentSpec.assertions.should.have_length 0
|
||||
end
|
||||
end
|
||||
|
||||
describe 'contentsOf()'
|
||||
it 'should return a function body'
|
||||
JSpec.contentsOf(-{ return 'foo' }).should.include 'return', 'foo'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'paramsFor()'
|
||||
it 'should return an array of function parameter names'
|
||||
JSpec.paramsFor(function(foo, bar){}).should.eql ['foo', 'bar']
|
||||
end
|
||||
|
||||
it 'should return only the params for the root function'
|
||||
foo = function(bar){
|
||||
function baz(test) {}
|
||||
var something = function(foo, bar){}
|
||||
}
|
||||
JSpec.paramsFor(foo).should.eql ['bar']
|
||||
end
|
||||
|
||||
it 'should return empty array when no params are present'
|
||||
JSpec.paramsFor(function(){}).should.eql []
|
||||
end
|
||||
end
|
||||
end
|
151
thirdparty/jquery-concrete/vendor/jspec/spec/spec.xhr.js
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
|
||||
describe 'JSpec'
|
||||
describe '.mockRequest'
|
||||
before
|
||||
responseFrom = function(path) {
|
||||
request = new XMLHttpRequest
|
||||
request.open('POST', path, false)
|
||||
request.send(null)
|
||||
return request.responseText
|
||||
}
|
||||
end
|
||||
|
||||
it 'should mock XMLHttpRequests if unmockRequest() is called or the spec block has finished'
|
||||
original = XMLHttpRequest
|
||||
mockRequest().and_return('test')
|
||||
XMLHttpRequest.should.not.equal original
|
||||
unmockRequest()
|
||||
XMLHttpRequest.should.equal original
|
||||
end
|
||||
|
||||
it 'should restore original XMLHttpRequest constructor after each spec'
|
||||
XMLHttpRequest.should.not.eql JSpec.XMLHttpRequest
|
||||
end
|
||||
|
||||
describe 'mock response'
|
||||
before_each
|
||||
mockRequest().and_return('bar', 'text/plain', 200, { 'x-foo' : 'bar' })
|
||||
request = new XMLHttpRequest
|
||||
request.open('GET', 'path', false, 'foo', 'bar')
|
||||
request.send('foo=bar')
|
||||
end
|
||||
|
||||
it 'should allow setting response status'
|
||||
mockRequest().and_return('bar', 'text/plain', 404)
|
||||
request = new XMLHttpRequest
|
||||
request.open('GET', 'path', false)
|
||||
request.send(null)
|
||||
request.status.should.eql 404
|
||||
request.statusText.should.eql 'Not Found'
|
||||
end
|
||||
|
||||
it 'should default readyState to 0'
|
||||
request = new XMLHttpRequest
|
||||
request.readyState.should.eql 0
|
||||
end
|
||||
|
||||
it 'should populate user'
|
||||
request.user.should.eql 'foo'
|
||||
end
|
||||
|
||||
it 'should populate password'
|
||||
request.password.should.eql 'bar'
|
||||
end
|
||||
|
||||
it 'should populate method'
|
||||
request.method.should.eql 'GET'
|
||||
end
|
||||
|
||||
it 'should populate readyState'
|
||||
request.readyState.should.eql 4
|
||||
end
|
||||
|
||||
it 'should populate url'
|
||||
request.url.should.eql 'path'
|
||||
end
|
||||
|
||||
it 'should populate status'
|
||||
request.status.should.eql 200
|
||||
end
|
||||
|
||||
it 'should populate statusText'
|
||||
request.statusText.should.eql 'OK'
|
||||
end
|
||||
|
||||
it 'should populate content type response header'
|
||||
request.getResponseHeader('Content-Type').should.eql 'text/plain'
|
||||
end
|
||||
|
||||
it 'should populate Content-Length response header'
|
||||
request.getResponseHeader('Content-Length').should.eql 3
|
||||
end
|
||||
|
||||
it 'should populate data'
|
||||
request.data.should.eql 'foo=bar'
|
||||
end
|
||||
|
||||
it 'should populate responseText'
|
||||
request.responseText.should.eql 'bar'
|
||||
end
|
||||
|
||||
it 'should populate headers'
|
||||
request.getResponseHeader('X-Foo').should.eql 'bar'
|
||||
end
|
||||
|
||||
it 'should not interrupt JSpec request related functionality'
|
||||
mockRequest().and_return('fail')
|
||||
(JSpec.tryLoading('async') || JSpec.tryLoading('spec/async')).should.eql 'cookies!'
|
||||
fixture('test').should.eql '<p>test</p>'
|
||||
fixture('test.json').should.include '{ user'
|
||||
end
|
||||
|
||||
describe '.onreadystatechange()'
|
||||
before_each
|
||||
mockRequest().and_return('bar', 'text/plain', 200)
|
||||
request = new XMLHttpRequest
|
||||
end
|
||||
|
||||
it 'should be called when opening request in context to the request'
|
||||
request.onreadystatechange = function(){
|
||||
this.readyState.should.eql 1
|
||||
}
|
||||
request.open('GET', 'path')
|
||||
end
|
||||
|
||||
it 'should be called when sending request'
|
||||
request.open('GET', 'path')
|
||||
request.onreadystatechange = function(){
|
||||
this.readyState.should.eql 4
|
||||
}
|
||||
request.send(null)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.setRequestHeader()'
|
||||
it 'should set request headers'
|
||||
mockRequest().and_return('bar', 'text/plain', 200)
|
||||
request.open('GET', 'path', false, 'foo', 'bar')
|
||||
request.setRequestHeader('Accept', 'foo')
|
||||
request.send(null)
|
||||
request.requestHeaders['accept'].should.eql 'foo'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'HEAD'
|
||||
it 'should respond with headers only'
|
||||
mockRequest().and_return('bar', 'text/plain', 200)
|
||||
request.open('HEAD', 'path', false)
|
||||
request.send(null)
|
||||
request.responseText.should.be_null
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with uri'
|
||||
it 'should mock only the uri specified'
|
||||
mockRequest('ilike').and_return('cookies')
|
||||
responseFrom('async').should.eql 'cookies'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
4
thirdparty/jquery-concrete/vendor/jspec/templates/default/History.rdoc
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
=== 0.0.1 / YYYY-MM-DD
|
||||
|
||||
* Initial release
|
29
thirdparty/jquery-concrete/vendor/jspec/templates/default/README.rdoc
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
= YourLib
|
||||
|
||||
Description
|
||||
|
||||
== License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2009 Your Name <Your Email>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
2
thirdparty/jquery-concrete/vendor/jspec/templates/default/lib/yourlib.core.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
// Your library here
|
8
thirdparty/jquery-concrete/vendor/jspec/templates/default/spec/spec.core.js
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
describe 'YourLib'
|
||||
describe '.someMethod()'
|
||||
it 'should do something'
|
||||
true.should.be true
|
||||
end
|
||||
end
|
||||
end
|
20
thirdparty/jquery-concrete/vendor/jspec/templates/default/spec/spec.dom.html
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<html>
|
||||
<head>
|
||||
<link type="text/css" rel="stylesheet" href="JSPEC_ROOT/lib/jspec.css" />
|
||||
<script src="JSPEC_ROOT/lib/jspec.js"></script>
|
||||
<script src="../lib/yourlib.core.js"></script>
|
||||
<script>
|
||||
function runSuites() {
|
||||
JSpec
|
||||
.exec('spec.core.js')
|
||||
.run()
|
||||
.report()
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="jspec" onLoad="runSuites();">
|
||||
<div id="jspec-top"><h2 id="jspec-title">JSpec <em><script>document.write(JSpec.version)</script></em></h2></div>
|
||||
<div id="jspec"></div>
|
||||
<div id="jspec-bottom"></div>
|
||||
</body>
|
||||
</html>
|
8
thirdparty/jquery-concrete/vendor/jspec/templates/default/spec/spec.rhino.js
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
load('JSPEC_ROOT/lib/jspec.js')
|
||||
load('lib/yourlib.core.js')
|
||||
|
||||
JSpec
|
||||
.exec('spec/spec.core.js')
|
||||
.run({ formatter : JSpec.formatters.Terminal })
|
||||
.report()
|
16
thirdparty/jquery-concrete/vendor/jspec/templates/default/spec/spec.server.html
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="jspec.js"></script>
|
||||
<script src="../lib/yourlib.core.js"></script>
|
||||
<script>
|
||||
function runSuites() {
|
||||
JSpec
|
||||
.exec('spec.core.js')
|
||||
.run()
|
||||
.reportToServer()
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="jspec" onLoad="runSuites();">
|
||||
</body>
|
||||
</html>
|
8
thirdparty/jquery-concrete/vendor/jspec/templates/rails/spec.application.js
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
describe 'YourLib'
|
||||
describe '.someMethod()'
|
||||
it 'should do something'
|
||||
true.should.be true
|
||||
end
|
||||
end
|
||||
end
|
20
thirdparty/jquery-concrete/vendor/jspec/templates/rails/spec.dom.html
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<html>
|
||||
<head>
|
||||
<link type="text/css" rel="stylesheet" href="JSPEC_ROOT/lib/jspec.css" />
|
||||
<script src="JSPEC_ROOT/lib/jspec.js"></script>
|
||||
<script src="../public/javascripts/application.js"></script>
|
||||
<script>
|
||||
function runSuites() {
|
||||
JSpec
|
||||
.exec('spec.application.js')
|
||||
.run()
|
||||
.report()
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="jspec" onLoad="runSuites();">
|
||||
<div id="jspec-top"><h2 id="jspec-title">JSpec <em><script>document.write(JSpec.version)</script></em></h2></div>
|
||||
<div id="jspec"></div>
|
||||
<div id="jspec-bottom"></div>
|
||||
</body>
|
||||
</html>
|
8
thirdparty/jquery-concrete/vendor/jspec/templates/rails/spec.rhino.js
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
load('JSPEC_ROOT/lib/jspec.js')
|
||||
load('public/javascripts/application.js')
|
||||
|
||||
JSpec
|
||||
.exec('spec/spec.application.js')
|
||||
.run({ formatter : JSpec.formatters.Terminal })
|
||||
.report()
|
16
thirdparty/jquery-concrete/vendor/jspec/templates/rails/spec.server.html
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="jspec.js"></script>
|
||||
<script src="../public/javascripts/application.js"></script>
|
||||
<script>
|
||||
function runSuites() {
|
||||
JSpec
|
||||
.exec('spec.application.js')
|
||||
.run()
|
||||
.reportToServer()
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="jspec" onLoad="runSuites();">
|
||||
</body>
|
||||
</html>
|