├── README.md ├── doc ├── Array.contain.md ├── EventsMouse.md ├── Number.int.md ├── Obj.method.md ├── Oct.ajax.md ├── Oct.browswer.md ├── Oct.cookie.read.md ├── Oct.cookie.remove.md ├── Oct.cookie.set.md ├── Oct.extend.md ├── Oct.global.namespace.md ├── Oct.hexToRgb.md ├── Oct.ieVerion.md ├── Oct.inheFn.md ├── Oct.inhePro.md ├── Oct.isArray.md ├── Oct.isEmpty.md ├── Oct.localStorage.read.md ├── Oct.localStorage.remove.md ├── Oct.localStorage.set.md ├── Oct.matrix.md ├── Oct.md ├── Oct.mergeSort.md ├── Oct.randomNum.md ├── Oct.rgbToHex.md ├── Oct.sort.fn.md ├── Oct.stopBubble.md ├── Oct.tag.md ├── Oct.trim.md ├── String.lengthdb.md ├── add.md ├── addEvent.md ├── getAttr.md ├── getCss.md ├── has.md ├── hasAttr.md ├── height.md ├── html.md ├── parent.md ├── remove.md ├── removeAttr.md ├── removeEvent.md ├── setAttr.md ├── setCss.md ├── setOpacity.md ├── son.md ├── temp.md └── width.md ├── octjs.js └── reference ├── Anyjs.js ├── browser.js ├── jq_reference_version.js ├── jquery-1.10.1.js ├── jquery-2.0.0.js ├── jquery.cookie.js ├── sizzle.js ├── youmightnotneedjquery.md └── zepto.js /README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | Include the oct.js file in your HTML. 3 | 4 | # Documents 5 | 6 | https://github.com/younglaker/octjs/tree/master/doc 7 | 8 | # Overview 9 | 10 | - `.addEvent()` Add event. 11 | - `.add()` Add id or class in a object. 12 | - `Array.contain()` Test for value in Javascript Array. 13 | - `Mouse Events` `click`, `hover` and so on 14 | - `.getCss()` Get the value of style properties for the element. 15 | - `.getAttr()` Get the value of attribute properties for the element. 16 | - `.has()` Select the object which has the specifical id, class or tag. 17 | - `.hasAttr()` Judge the element whether has the attribute property. 18 | - `.height()` Get or set height. 19 | - `.html()` Read and insert content. 20 | - `Number.int()` Get integer part of Number. 21 | - `Obj.method()` Extend method of basic types of objects. 22 | - `Oct.ajax()` Perform an asynchronous HTTP (Ajax) request. 23 | - `Oct.browswer()` Return the current browser name and version. Mainly chrome, firefox, etc. 24 | - `Oct.cookie.read()` Read cookies value by item name. 25 | - `Oct.cookie.remove()` Remove cookies by cookie item name. 26 | - `Oct.cookie.set()` Set cookies. 27 | - `Oct.extend()` Extend method of Oct object. 28 | - `Oct.global.namespace()` Creat namespace. 29 | - `Oct.hexToRgb()` Exchange HEX color to RGB color. 30 | - `Oct.ieVerion()` Test ie version. 31 | - `Oct.inheFn()` Inherit construct function. It should write inside the son class. 32 | - `Oct.inhePro()` Inherit prototype. It should write before the son class. 33 | - `Oct.isArray()` Check whether an element is an array. 34 | - `Oct.isEmpty()` Check whether a string is empty. 35 | - `Oct.localStorage.read()` Read localStorage value by item name. 36 | - `Oct.localStorage.remove()` Remove localStorages by localStorage item name. 37 | - `Oct.localStorage.set()` Set localStorages. 38 | - `Oct.matrix()` Create one or two- dimensional array. 39 | - `O() or Oct()` Create an Oct collection object by performing a CSS selector, wrapping DOM nodes, or creating elements from an HTML string. 40 | - `Oct.mergeSort()` Sort the Array through merge algorithm. 41 | - `Oct.randomNum()` Generate random number in specific range. 42 | - `Oct.rgbToHexr()` Exchange RGB color to HEX color. 43 | - `Oct.sort.fn()` Some sort method for javascript sort() function. 44 | - `Oct.stopBubble()` Cancle event bubbling. 45 | - `Oct.tag()` Create tag. 46 | - `Oct.trim()` Delete the space in the first and end of a string. 47 | - `.parent()` Get the first level of child nodes. 48 | - `.remove()` Remove id, class or tag in an object. 49 | - `.removeAttr()` Remove the attribute. 50 | - `.setCss()` Set css property. 51 | - `.setAttr()` Set attribute property. 52 | - `.setOpacity()` Set opacity. 53 | - `.son()` Get the first level of child nodes. 54 | - `String.lengthdb()` Count the double bytes words. 55 | - `.width()` Get or set width. 56 | 57 | # Structure 58 | 59 | How to write a JavaScript library 60 | http://laker.me/blog/2015/03/15/15_0315_octjs_1/ 61 | 62 | ## To do 63 | 64 | - Function animation 65 | - Function document.ready 66 | - Homepage and documentes 67 | - Funtion children 68 | - Function parents 69 | - Expand on() by event bubble to bind event dynamically 70 | -------------------------------------------------------------------------------- /doc/Array.contain.md: -------------------------------------------------------------------------------- 1 | ## Array.contain() 2 | 3 | ### Description 4 | 5 | Test for value in Javascript Array. 6 | 7 | ### Syntax 8 | Array.contain(value) => Bool 9 | 10 | 11 | ### Demo 12 | 13 | 1.Demo 14 | 15 | [1, 2, 3].contain(2); // true 16 | [1, 2, 3].contain(5); // false -------------------------------------------------------------------------------- /doc/EventsMouse.md: -------------------------------------------------------------------------------- 1 | ## Mouse Events: click, hover and so on 2 | 3 | - click(function() {}) 4 | 5 | - hover(function() {}) 6 | 7 | - mouseover(function() {}) 8 | 9 | - mouseout(function() {}) 10 | 11 | - mousemove(function() {}) 12 | 13 | - mousedown(function() {}) 14 | 15 | - mouseup(function() {}) 16 | 17 | ### Description 18 | 19 | The function can be recognized easily by the name. 20 | 21 | ### Syntax 22 | O("").eventName(function() {}) => self 23 | 24 | ### Demo 25 | 26 | 1.Set width and height as 150px for ".buddy", and when click it, alert "hi". 27 | 28 | O(".buddy").click(function(){ 29 | alert("hi"); 30 | }) 31 | .setCss({ 32 | width: "150px", 33 | height: "150px" 34 | }); 35 | 36 | -------------------------------------------------------------------------------- /doc/Number.int.md: -------------------------------------------------------------------------------- 1 | ## Number.int() 2 | 3 | ### Description 4 | 5 | Get integer part of Number. 6 | 7 | ### Syntax 8 | Number.int(); => value 9 | 10 | ### Demo 11 | 12 | 1.Get integer part of some numbers. 13 | 14 | var a = 6.3.int(); 15 | var b = -6.3.int(); 16 | console.log(a); // 6 17 | console.log(b); // -6 -------------------------------------------------------------------------------- /doc/Obj.method.md: -------------------------------------------------------------------------------- 1 | ## Obj.method() 2 | 3 | ### Description 4 | 5 | Extend method of basic types of objects. 6 | 7 | ### Syntax 8 | Obj.extend("methodName", function() {}); => self 9 | 10 | - Obj: Function/String/Number/Boolen/Array/RegExp 11 | 12 | ### Demo 13 | 14 | 1.Extend a method to get integer part for Number. 15 | 16 | Number.method("int", function() { 17 | return Math[this < 0 ? "ceil" : "floor"](this); 18 | }); 19 | var a = 6.3.int(); 20 | console.log(a); // 6 21 | 22 | 2.Extend a method to count double bytes words for Sting. 23 | 24 | String.method("lengthdb", function() { 25 | var counts = 0, len = this.length; 26 | if (len) { 27 | for (var i = len; i--;) { 28 | if (this.charCodeAt(i) > 255) { 29 | counts += 2; 30 | } else { 31 | counts++; 32 | } 33 | } 34 | return counts; 35 | } else { 36 | return 0; 37 | } 38 | }); 39 | var a = "你好".lengthdb(); 40 | console.log(a); //4 -------------------------------------------------------------------------------- /doc/Oct.ajax.md: -------------------------------------------------------------------------------- 1 | ## Oct.ajax() 2 | 3 | ### Description 4 | 5 | Perform an asynchronous HTTP (Ajax) request. 6 | 7 | ### Syntax 8 | Oct.ajax() => 9 | 10 | - method: "GET"(default), "POST". 11 | 12 | - datatype: "json"(default), "xml", "html", "script", "text". 13 | 14 | - "url" 15 | 16 | - "senddata": a hash table contains the data which will be send to the server. 17 | 18 | - "success": do something when ajax successes, it will return the respond send from remote. 19 | 20 | - "fail": do something when ajax failes. 21 | 22 | ### Demo 23 | 24 | 1.Demo 25 | 26 | Oct.ajax({ 27 | "method": "POST", 28 | "datatype": "json", 29 | "url": "http://hi.com/test", 30 | "senddata": {"act": state, "people": id}, 31 | "success": function(msg) { 32 | console.log(msg); 33 | }, 34 | "fail": function() { 35 | console.log("fail"); 36 | } 37 | }); -------------------------------------------------------------------------------- /doc/Oct.browswer.md: -------------------------------------------------------------------------------- 1 | ## Oct.browswer() 2 | 3 | ### Description 4 | 5 | Return the current browser name and version. Mainly chrome, firefox, etc. 6 | 7 | ### Syntax 8 | Oct.browswer()[.name/version]; => value 9 | 10 | 11 | ### Demo 12 | 13 | 1.Get the current browser information. 14 | 15 | console.log(Oct.browswer()); 16 | 17 | 2.Get the current browser name. 18 | 19 | console.log(Oct.browswer().name); 20 | 21 | -------------------------------------------------------------------------------- /doc/Oct.cookie.read.md: -------------------------------------------------------------------------------- 1 | ## Oct.cookie.read( ) 2 | 3 | ### Description 4 | 5 | Read cookies value by item name. 6 | 7 | ### Syntax 8 | Oct.cookie.read(item1[, item2, ... ]); => value 9 | 10 | - item: Cookie item name. 11 | 12 | ### Demo 13 | 14 | 1.Rread name, id items. 15 | 16 | console.log(Oct.cookie.read("name", "id")); -------------------------------------------------------------------------------- /doc/Oct.cookie.remove.md: -------------------------------------------------------------------------------- 1 | ## Oct.cookie.remove( ) 2 | 3 | ### Description 4 | 5 | Remove cookies by cookie item name. 6 | 7 | ### Syntax 8 | Oct.cookie.remove(item1[, item2, ... ]); => none 9 | 10 | - item: Cookie item name. If no item, it will remove all the cookies. 11 | 12 | ### Demo 13 | 14 | 1.Remove name, id items. 15 | 16 | Oct.cookie.remove("name", "id"); 17 | 18 | 2.Remove all the cookies. 19 | 20 | Oct.cookie.remove(); -------------------------------------------------------------------------------- /doc/Oct.cookie.set.md: -------------------------------------------------------------------------------- 1 | ## Oct.cookie.set( ) 2 | 3 | ### Description 4 | 5 | Set cookies. 6 | 7 | ### Syntax 8 | Oct.cookie.set({item: "item", value: "value"[, expires: expires, path: "path", domain: "domain", secure: "secure"}, {list2} ... ]); => none 9 | 10 | - item: Cookie item name. 11 | 12 | - value: Cookie value. 13 | 14 | - expires: Expires day. Unit is day. 15 | 16 | - path: Path 17 | 18 | - domain: Domain 19 | 20 | - secure: If true, use https, otherwise http. 21 | 22 | ### Demo 23 | 24 | 1.Set item1. 25 | 26 | Oct.cookie.set({item: "item1", value: "1"}); 27 | 28 | 2. Set more cookies and keep them for 7 days. 29 | 30 | Oct.cookie.set( 31 | {item: "id5", value: "5", expires: 7}, 32 | {item: "id6", value: "66", expires: 7} 33 | ); -------------------------------------------------------------------------------- /doc/Oct.extend.md: -------------------------------------------------------------------------------- 1 | ## Oct.extend( ) 2 | 3 | ### Description 4 | 5 | Extend method of Oct object. 6 | 7 | ### Syntax 8 | Oct.extend("methodName", function() {}); => self 9 | 10 | ### Demo 11 | 12 | 1.____ 13 | 14 | Oct.extend("hi", function() { 15 | console.log("hi"); 16 | }); 17 | Oct.hi(); -------------------------------------------------------------------------------- /doc/Oct.global.namespace.md: -------------------------------------------------------------------------------- 1 | ## Oct.global.namespace( ) 2 | 3 | ### Description 4 | 5 | Creat namespace. 6 | 7 | ### Syntax 8 | Oct.global.namespace(namespace) => none; 9 | 10 | - namespace: . Can be one or more level.It is global, so other function can use it. 11 | 12 | ### Demo 13 | 14 | 1.Create a namespace "me", and create a varible and a function. 15 | 16 | Oct.global.namespace("me"); 17 | Oct.global.me.name = "laker"; 18 | Oct.global.me.hi = function() { 19 | alert("Hi, my name is " + Oct.global.me.name); 20 | } 21 | Oct.global.me.hi(); 22 | 23 | 2.Create a namespace "A.cat", and create two varibles. 24 | 25 | Oct.global.namespace("A.cat"); 26 | Oct.global.A.cat.a = 5; 27 | Oct.global.A.cat.b = 10; 28 | console.log(Oct.global.A.cat.a); 29 | console.log(Oct.global.A.cat.b); 30 | 31 | -------------------------------------------------------------------------------- /doc/Oct.hexToRgb.md: -------------------------------------------------------------------------------- 1 | ## Oct.hexToRgb() 2 | 3 | ### Description 4 | 5 | Exchange HEX color to RGB color. 6 | 7 | ### Syntax 8 | Oct.hexToRgb(color); => value 9 | 10 | 11 | ### Demo 12 | 13 | 1. 14 | 15 | Oct.rgbToHex("#91199"); // 1rgb(145,25,145) 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/Oct.ieVerion.md: -------------------------------------------------------------------------------- 1 | ## Oct.ieVerion( ) 2 | 3 | ### Description 4 | 5 | Test ie version. 6 | 7 | ### Syntax 8 | Oct.ieVerion() => value 9 | 10 | - If it is ie, will return the version number, otherwise return "false". 11 | 12 | ### Demo 13 | 14 | 1.Log the ie version. 15 | 16 | console.log(Oct.ieVerion()); 17 | 18 | -------------------------------------------------------------------------------- /doc/Oct.inheFn.md: -------------------------------------------------------------------------------- 1 | ## Oct.inheFn( ) 2 | 3 | ### Description 4 | 5 | Inherit construct function. It should write inside the son class. 6 | 7 | ### Syntax 8 | Oct.inheFn(super_class, this, arg1[, arg2 ...]) => none 9 | 10 | - super_class: . Father class name. 11 | 12 | - this: Just use "this". 13 | 14 | - arg: The arguments should inherit from father. Make sure the order is the same as its father. 15 | 16 | ### Demo 17 | 18 | 1.Class Student inherit from Person. 19 | 20 | function Person(name, sex) { 21 | this.name = name; 22 | this.sex = sex; 23 | this.type = "animal"; 24 | this.say = function() { 25 | console.log("sex=" + sex); 26 | } 27 | } 28 | 29 | Person.prototype.sing = function() { 30 | console.log("sing"); 31 | } 32 | 33 | Oct.inhePro(Person, Student); 34 | 35 | function Student(name, sex, id) { 36 | Oct.inheFn(Person, this, name ,sex); 37 | this.id = id; 38 | } 39 | 40 | var m = new Student("mike", "man", 1010); 41 | m.say(); 42 | m.sing(); 43 | console.log(m.sex); -------------------------------------------------------------------------------- /doc/Oct.inhePro.md: -------------------------------------------------------------------------------- 1 | ## Oct.inhePro() 2 | 3 | ### Description 4 | 5 | Inherit prototype. It should write before the son class. 6 | 7 | ### Syntax 8 | Oct.inhePro(super_class, sub_class) => none 9 | 10 | - super_class: . Father class name. 11 | 12 | - sub_class: . Son class name. 13 | 14 | 15 | ### Demo 16 | 17 | 1.Class Student inherit from Person. 18 | 19 | function Person(name, sex) { 20 | this.name = name; 21 | this.sex = sex; 22 | this.type = "animal"; 23 | this.say = function() { 24 | console.log("sex=" + sex); 25 | } 26 | } 27 | 28 | Person.prototype.sing = function() { 29 | console.log("sing"); 30 | } 31 | 32 | Oct.inhePro(Person, Student); 33 | 34 | function Student(name, sex, id) { 35 | Oct.inheFn(Person, this, name ,sex); 36 | this.id = id; 37 | } 38 | 39 | var m = new Student("mike", "man", 1010); 40 | m.say(); 41 | m.sing(); 42 | console.log(m.sex); -------------------------------------------------------------------------------- /doc/Oct.isArray.md: -------------------------------------------------------------------------------- 1 | ## Oct.isArray( ) 2 | 3 | ### Description 4 | 5 | Check whether an element is an array. 6 | 7 | ### Syntax 8 | Oct.isArray(value) => bool 9 | 10 | ### Demo 11 | 12 | 1.Examples. 13 | 14 | var m ={p: 5, o: 6}; 15 | console.log(Oct.isArray(m)); // false 16 | var n = [1, 2, 3]; 17 | console.log(Oct.isArray(m)); // true 18 | console.log(Oct.isArray(5)); // false 19 | -------------------------------------------------------------------------------- /doc/Oct.isEmpty.md: -------------------------------------------------------------------------------- 1 | ## Oct.isEmpty( ) 2 | 3 | ### Description 4 | 5 | Check whether a string is empty. 6 | 7 | ### Syntax 8 | Oct.isEmpty(str); => boolean 9 | 10 | - If return true, means empty; otherwise not. PS: a sapce string will be recognized as empty. 11 | 12 | ### Demo 13 | 14 | 1.Check variable "buddy" whether is empty. 15 | 16 | var buddy = "hi"; 17 | console.log(Oct.isEmpty(buddy)); // false 18 | buddy = " "; 19 | console.log(Oct.isEmpty(buddy)); // true 20 | -------------------------------------------------------------------------------- /doc/Oct.localStorage.read.md: -------------------------------------------------------------------------------- 1 | ## Oct.localStorage.read( ) 2 | 3 | ### Description 4 | 5 | Read localStorage value by item name. 6 | 7 | ### Syntax 8 | Oct.localStorage.read(item1[, item2, ... ]); => value 9 | 10 | - item: localStorage item name. 11 | 12 | ### Demo 13 | 14 | 1.Rread name, id items. 15 | 16 | Oct.localStorage.set( 17 | {item: "name", value: "kobe"}, 18 | {item: "id", value: "66"} 19 | ); 20 | console.log(Oct.localStorage.read("name", "id")); -------------------------------------------------------------------------------- /doc/Oct.localStorage.remove.md: -------------------------------------------------------------------------------- 1 | ## Oct.localStorage.remove( ) 2 | 3 | ### Description 4 | 5 | Remove localStorages by localStorage item name. 6 | 7 | ### Syntax 8 | Oct.localStorage.remove(item1[, item2, ... ]); => none 9 | 10 | - item: localStorage item name. If no item, it will remove all the localStorages. 11 | 12 | ### Demo 13 | 14 | 1.Remove name, id items. 15 | 16 | Oct.localStorage.set( 17 | {item: "name", value: "kobe"}, 18 | {item: "id", value: "66"} 19 | ); 20 | Oct.localStorage.remove("name", "id"); 21 | 22 | 2.Remove all the localStorages. 23 | 24 | Oct.localStorage.remove(); -------------------------------------------------------------------------------- /doc/Oct.localStorage.set.md: -------------------------------------------------------------------------------- 1 | ## Oct.localStorage.set( ) 2 | 3 | ### Description 4 | 5 | Set localStorages. 6 | 7 | ### Syntax 8 | Oct.localStorage.set({item: "item", value: "value"}[, {list2} ... ]); => none 9 | 10 | - item: localStorage item name. 11 | 12 | - value: localStorage value. 13 | 14 | ### Demo 15 | 16 | 1.Set item1. 17 | 18 | Oct.localStorage.set({item: "item1", value: "1"}); 19 | 20 | 2. Set more localStorages. 21 | 22 | Oct.localStorage.set( 23 | {item: "id5", value: "5"}, 24 | {item: "id6", value: "66"} 25 | ); -------------------------------------------------------------------------------- /doc/Oct.matrix.md: -------------------------------------------------------------------------------- 1 | ## Oct.matrix( ) 2 | 3 | ### Description 4 | 5 | Create one or two-dimensional array. 6 | 7 | ### Syntax 8 | Oct.matrix(line, row, init) => array 9 | 10 | - line: . 11 | 12 | - row: . 13 | 14 | - init: . default = "1". 15 | 16 | ### Demo 17 | 18 | 1.Creat a one-dimensional array called m. 19 | 20 | var m = Oct.matrix(1,5,3); 21 | console.log(m); // [3, 3, 3, 3, 3] 22 | m[3] = 8; 23 | console.log(m[3]); //8 24 | 25 | 2.Creat a two-dimensional array called m. 26 | 27 | var m = Oct.matrix(2, 3, 0); 28 | console.log(m); // [[0, 0, 0], [0, 0,0 ]] 29 | console.log(m[3][2]); // 3 30 | m[3][2] = 8; 31 | console.log(m[3][2]); // 8 -------------------------------------------------------------------------------- /doc/Oct.md: -------------------------------------------------------------------------------- 1 | ## O() or Oct() 2 | 3 | ### Description 4 | 5 | Create an Oct collection object by performing a CSS selector, wrapping DOM nodes, or creating elements from an HTML string. 6 | 7 | ### Syntax 8 | O("selector[, root_id, tag]") => collection 9 | 10 | - selector: the elements you want. The id ueses prefix "#", class ueses ".", and tag ueses "&". 11 | 12 | - root_id: the root's id of the elements'root you want. 13 | 14 | - tag: point out the specific tag of the selector. If none, it's document. 15 | 16 | ### Demo 17 | 18 | 1.Select a id elememt. 19 | 20 | O("#buddy") 21 | 22 | 23 | 2.Select a class elememt. 24 | 25 | Oct(".buddy") 26 | 27 | 3.Select all the div tags. 28 | 29 | O("&div") // also O("&Div"), O("&DIV") 30 | 31 | 4.Select class buddy in all p tags. 32 | 33 | O(".buddy", null, "&p") 34 | 35 | 4.Select class buddy whose root have id dad. 36 | 37 | O(".buddy", "#dad") 38 | -------------------------------------------------------------------------------- /doc/Oct.mergeSort.md: -------------------------------------------------------------------------------- 1 | ## Oct.mergeSort( ) 2 | 3 | ### Description 4 | 5 | Sort the Array through merge algorithm. 6 | 7 | ### Syntax 8 | Oct.mergeSort(array[, positive]) => value 9 | 10 | - array: 11 | 12 | - positive: , . Whether is positive sequence. 13 | 14 | ### Demo 15 | 16 | 1.Sort [1,4,7,3,8,2,5,9]. 17 | 18 | var m = Oct.mergeSort([1,4,7,3,8,2,5,9]); 19 | console.log(m); // [1, 2, 3, 4, 5, 7, 8, 9]; 20 | var n = Oct.mergeSort([1,4,7,3,8,2,5,9], false); 21 | console.log(n); // [9, 8, 7, 5, 4, 3, 2, 1]; -------------------------------------------------------------------------------- /doc/Oct.randomNum.md: -------------------------------------------------------------------------------- 1 | ## Oct.randomNum( ) 2 | 3 | ### Description 4 | 5 | Generate random number in specific range. 6 | 7 | ### Syntax 8 | Oct.randomNum = function(start, stop, type) => number 9 | 10 | - start: , the minimum value (includes). 11 | 12 | - stop: , the max value (includes). 13 | 14 | - type: , "float"(default), "int" 15 | 16 | ### Demo 17 | 18 | 1.Log a rangdom float number range from 1.5 to 10: 19 | 20 | console.log(Oct.randomNum(1.5, 10)); 21 | 22 | 2.Log a rangdom int number range from 5 to 25: 23 | 24 | console.log(Oct.randomNum(1, 25, "int")); 25 | 26 | -------------------------------------------------------------------------------- /doc/Oct.rgbToHex.md: -------------------------------------------------------------------------------- 1 | ## Oct.rgbToHexr() 2 | 3 | ### Description 4 | 5 | Exchange RGB color to HEX color. 6 | 7 | ### Syntax 8 | Oct.rgbToHex(color); => value 9 | 10 | 11 | ### Demo 12 | 13 | 1. 14 | 15 | Oct.rgbToHex("rgb(145,25,145)"); // #911991 16 | 17 | 2.Exchange RGB backround color to HEX in chrome. 18 | 19 | Oct.rgbToHex(O(this).getCss("background-color")[0]); 20 | 21 | -------------------------------------------------------------------------------- /doc/Oct.sort.fn.md: -------------------------------------------------------------------------------- 1 | ## Oct.sort.fn 2 | 3 | ### Description 4 | 5 | Some sort method for javascript sort() function. 6 | 7 | ### Syntax 8 | 1.Ascending order. 9 | Oct.sort.asc => value 10 | 11 | 2.Descending order. 12 | Oct.sort.des => value 13 | 14 | 3.Separate the integer and floating point numbers. 15 | Oct.sort.depNum => value 16 | 17 | 4.Case insensitive and ascending order. 18 | Oct.sort.noCaseAsc => value 19 | 20 | 5.Case insensitive and descending order. 21 | Oct.sort.noCaseDes => value 22 | 23 | ### Demo 24 | 25 | 1.Examples. 26 | 27 | var a = [3, 6, 9, 8, 4, 10, 0]; 28 | a.sort(Oct.sort.asc); //[0, 3, 4, 6, 8, 9, 10] 29 | a.sort(Oct.sort.des); //[10, 9, 8, 6, 4, 3, 0] 30 | var b = [3.6, 6, 5.5, 9, 2.2]; 31 | b.sort(Oct.sort.depNum); //[6, 9, 2.2, 5.5, 3.6] 32 | var c = ["d", "C", "a", "b"]; 33 | c.sort(Oct.sort.noCaseAsc); //["A", "b", "C", "d"] 34 | c.sort(Oct.sort.noCaseDes); //["d", "C", "b", "A"] -------------------------------------------------------------------------------- /doc/Oct.stopBubble.md: -------------------------------------------------------------------------------- 1 | ## Oct.stopBubble() 2 | 3 | ### Description 4 | 5 | Cancle event bubbling. 6 | 7 | ### Syntax 8 | Oct.stopBubble(); => none 9 | 10 | ### Demo 11 | 12 | 1.Stop bubbling. 13 | 14 | O("#test2").setCss({height:"300px"}).click(function(){ 15 | alert("message"); 16 | Oct.stopBubble(); 17 | }); -------------------------------------------------------------------------------- /doc/Oct.tag.md: -------------------------------------------------------------------------------- 1 | ## Oct.tag( ) 2 | 3 | ### Description 4 | 5 | Create tag. 6 | 7 | ### Syntax 8 | Oct.tag("tagName"[, content]) => value 9 | 10 | ### Demo 11 | 12 | 1.Create a p tag. 13 | 14 | var a = Oct.tag("p","hello"); 15 | document.write(a); //

hello

-------------------------------------------------------------------------------- /doc/Oct.trim.md: -------------------------------------------------------------------------------- 1 | ## Oct.trim() 2 | 3 | ### Description 4 | 5 | Delete the space in the first and end of a string. 6 | 7 | ### Syntax 8 | Oct.trim(str) => value 9 | 10 | 11 | ### Demo 12 | 13 | 1.Deal with " sss " 14 | 15 | console.log(Oct.trim(" sss ")); 16 | console.log(Oct.trim(" sss ").length); -------------------------------------------------------------------------------- /doc/String.lengthdb.md: -------------------------------------------------------------------------------- 1 | ## String.lengthdb( ) 2 | 3 | ### Description 4 | 5 | Count the double bytes words. 6 | 7 | ### Syntax 8 | str.trim() => value 9 | 10 | ### Demo 11 | 12 | 1.Count some string's length. 13 | 14 | console.log("你好".lengthdb()); // 4 15 | console.log("hi".lengthdb()); // 2 16 | console.log("你好hi".lengthdb()); // 6 17 | 18 | 2. Compare "String.lengthdb()" with "String.length". 19 | 20 | console.log("你好".length); // 2 21 | console.log("你好".lengthdb()); // 4 22 | console.log("你好22 ".length); // 4 23 | console.log("你好22 ".lengthdb()); // 8 -------------------------------------------------------------------------------- /doc/add.md: -------------------------------------------------------------------------------- 1 | ## add( ) 2 | 3 | ### Description 4 | 5 | Add id or class in a object. 6 | 7 | ### Syntax 8 | O("").add("#/.name1[, #/.name2 ... ]") => self 9 | 10 | - name: The id or class name. The id has prefix "#", and class has ".". 11 | 12 | ### Demo 13 | 14 | 1.Add id a and class b in #buddy. 15 | 16 | O("#buddy").add("#a, .b"); -------------------------------------------------------------------------------- /doc/addEvent.md: -------------------------------------------------------------------------------- 1 | ## addEvent( ) 2 | 3 | ### Description 4 | 5 | Add event. 6 | 7 | ### Syntax 8 | O("").addEvent(eventType, fn); => self 9 | 10 | - eventType: . "click", "mousemove", "keyup" and so on. 11 | 12 | - fn: . 13 | 14 | ### Demo 15 | 16 | 1.Set width and height as 150px for ".buddy", and when click it, alert "hi". 17 | 18 | O(".buddy").addEvent("click", function(){ 19 | alert("hi"); 20 | }) 21 | .setCss({ 22 | width: "150px", 23 | height: "150px" 24 | }); 25 | 26 | -------------------------------------------------------------------------------- /doc/getAttr.md: -------------------------------------------------------------------------------- 1 | ## .getAttr() 2 | 3 | ### Description 4 | 5 | Get the value of attribute properties for the element 6 | 7 | ### Syntax 8 | 9 | O("").getAttr(sting) => self 10 | 11 | ### Demo 12 | 13 | 1.Get the idvalue of #buddy 14 | 15 |
hi
16 | var a = O("#buddy").getAttr("id"); => return "buddy" 17 | -------------------------------------------------------------------------------- /doc/getCss.md: -------------------------------------------------------------------------------- 1 | ## .getCss() 2 | 3 | ### Description 4 | 5 | Get the value of style properties for the element. 6 | 7 | ### Syntax 8 | O("").getCss(sting1[, sting2, sting3 ...]) => value 9 | 10 | ### Demo 11 | 12 | 1.Get the left value of #buddy 13 | 14 |
hi
15 | var a = O("#buddy").getCss("left"); => return "30px" 16 | 17 | 2.Get the left and top value of #buddy 18 | 19 |
hi
20 | var a = O("#buddy").getCss("left", "top"); => return "30px, 100px" 21 | 22 | -------------------------------------------------------------------------------- /doc/has.md: -------------------------------------------------------------------------------- 1 | ## has( ) 2 | 3 | ### Description 4 | 5 | Select the object which has the specifical id, class or tag. 6 | 7 | ### Syntax 8 | O("").has("#/.name1[, #/.name2 ... ]") => self 9 | 10 | - name: The id or class name. The id ueses prefix "#", class ueses ".", and tag ueses "&". 11 | 12 | ### Demo 13 | 14 | 1.Select the .buddy which has id a and class b. 15 | 16 |
17 |
18 |
19 | 20 | O(".buddy").has("#a, .b").setCss({color:"#f0f"}); // the third one 21 | 22 | 2.Select the .buddy which has span tag. 23 | 24 |
25 | 26 |
27 |
28 |

29 |
30 | 31 | O(".buddy").has("&tag").setCss({color:"#f0f"}); // the first one -------------------------------------------------------------------------------- /doc/hasAttr.md: -------------------------------------------------------------------------------- 1 | ## .hasAttr() 2 | 3 | ### Description 4 | 5 | Judge the element whether has the attribute property. 6 | 7 | ### Syntax 8 | 9 | O("").hasAttr(sting) => Bool 10 | 11 | ### Demo 12 | 13 | 1.Judge #buddy whether has the attribute property. 14 | 15 |
hi
16 | var a = O("#buddy").hasAttr("id"); => return "true" 17 | var a = O("#buddy").hasAttr("class"); => return "false" 18 | -------------------------------------------------------------------------------- /doc/height.md: -------------------------------------------------------------------------------- 1 | ## height( ) 2 | 3 | ### Description 4 | 5 | Get or set height. 6 | 7 | ### Syntax 8 | O("").height() => value 9 | O("").height(string) => self 10 | 11 | ### Demo 12 | 13 | 1.Get height of #buddy 14 | 15 | var a = O("#buddy").height(); 16 | 17 | 2.Set the height as "50px"; 18 | 19 | O("").height("50px") => self -------------------------------------------------------------------------------- /doc/html.md: -------------------------------------------------------------------------------- 1 | ## html( ) 2 | 3 | ### Description 4 | 5 | Read and insert content. 6 | 7 | ### Syntax 8 | O("").html() => html 9 | O("").html(content) => self 10 | 11 | - content: . words or tags. 12 | 13 | ### Demo 14 | 15 | 1.Insert a image in #buddy. 16 | 17 | O("#buddy").html(""); 18 | 19 | 2.Insert a sentence in #buddy. 20 | 21 | O("#buddy").html("Hello world~"); 22 | 23 | 3.Read #buddy's html. 24 | 25 | O("#buddy").html(""); -------------------------------------------------------------------------------- /doc/parent.md: -------------------------------------------------------------------------------- 1 | ## parent( ) 2 | 3 | ### Description 4 | 5 | Get the first level of child nodes. 6 | 7 | ### Syntax 8 | O("").parent([selector]) => self 9 | 10 | - selector: The specific elements you want. The id ueses prefix "#", class ueses ".", and tag ueses "&". If no specific selector, it will get all the first level of child nodes. 11 | 12 | ### Demo 13 | 14 | 1.Make #buddy's parent 50px margin left. 15 | 16 |
01 17 |
02 18 |
03
19 |
20 |
21 | 22 | O("#buddy").parent().setCss({marginLeft: "50px"}); // 02 has 50px margin left. 23 | -------------------------------------------------------------------------------- /doc/remove.md: -------------------------------------------------------------------------------- 1 | ## remove( ) 2 | 3 | ### Description 4 | 5 | Remove id, class or tag in an object. 6 | 7 | ### Syntax 8 | O("").remove("#/./&name1[, #/./&name2 ... ]") => self 9 | 10 | - name: The id or class name. The id has prefix "#", class has ".", and tag had "&". 11 | 12 | ### Demo 13 | 14 | 1.remove the id a and class b in #buddy. 15 | 16 |
17 | 18 | O("#buddy").remove("#a, .b"); 19 | 20 | 2.remove the tag span in #buddy. 21 | 22 |
23 | 24 |
25 | 26 | O("#buddy").remove("&span"); 27 | -------------------------------------------------------------------------------- /doc/removeAttr.md: -------------------------------------------------------------------------------- 1 | ## .removeAttr() 2 | 3 | ### Description 4 | 5 | Remove the attribute. 6 | 7 | ### Syntax 8 | 9 | O("").removeAttr(sting) => self 10 | 11 | ### Demo 12 | 13 | 1.Remove the class #buddy. 14 | 15 |
hi
16 | var a = O("#buddy").removeAttr("class"); => return self 17 | -------------------------------------------------------------------------------- /doc/removeEvent.md: -------------------------------------------------------------------------------- 1 | ## removeEvent( ) 2 | 3 | ### Description 4 | 5 | Add event. 6 | 7 | ### Syntax 8 | 9 | O("").removeEvent(eventType, fn); // return self 10 | 11 | - eventType: . "click", "mousemove", "keyup" and so on. 12 | 13 | - fn: . 14 | 15 | ### Demo 16 | 17 | 1.Set width and height as 150px for ".buddy", and when click it, alert "hi". 18 | 19 | var buddy = O(".buddy"); 20 | buddy.addEvent("click", onclick); 21 | 22 | function onclick() { 23 | alert("Bye, I will be removed"); 24 | buddy.removeEvent("click", onclick); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /doc/setAttr.md: -------------------------------------------------------------------------------- 1 | ## .setAttr() 2 | 3 | ### Description 4 | 5 | set the value of attribute properties for the element 6 | 7 | ### Syntax 8 | 9 | O("").setAttr({ property: value, property2: value2, ... }) => this 10 | 11 | ### Demo 12 | 13 | 1.set the class and title value of #buddy 14 | 15 |
hi
16 | var a = O("#buddy").setAttr({ 17 | "title": "hello", 18 | "class":"sda" 19 | }); 20 | -------------------------------------------------------------------------------- /doc/setCss.md: -------------------------------------------------------------------------------- 1 | ## .setCss( ) 2 | 3 | ### Description 4 | 5 | Set css property. 6 | 7 | ### Syntax 8 | O("").setCss({ property: value, property2: value2, ... }) => self 9 | // PS: 10 | // 1: Make sure you have use "{}" in "()". 11 | // 2: Can use both "backgroundColor" and "background-color" and so on. If use "backgroundColor", you dont have to add double quotation, but "background-color" must. 12 | 13 | ### Demo 14 | 15 | 1.Set some css property for #buddy 16 | 17 | O("#buddy").setCss({ 18 | top: "20px", 19 | backgroundColor: "#f00" 20 | }); 21 | 22 | O("#buddy").setCss({ 23 | "left": "50px", 24 | "color": "#eee" 25 | }); 26 | // PS: the property can be wrap by double quotation marks or not. 27 | 28 | -------------------------------------------------------------------------------- /doc/setOpacity.md: -------------------------------------------------------------------------------- 1 | ## setOpacity( ) 2 | 3 | ### Description 4 | 5 | Set opacity. 6 | 7 | ### Syntax 8 | O("").setOpacity(number) => self 9 | 10 | - number: . Between 0 to 1. 11 | 12 | ### Demo 13 | 14 | 1.Set opacity as 0.4 15 | 16 | O("#buddy").setOpacity(0.4); -------------------------------------------------------------------------------- /doc/son.md: -------------------------------------------------------------------------------- 1 | ## son( ) 2 | 3 | ### Description 4 | 5 | Get the first level of child nodes. 6 | 7 | ### Syntax 8 | O("").son([selector]) => self 9 | 10 | - selector: The specific elements you want. The id ueses prefix "#", class ueses ".", and tag ueses "&". If no specific selector, it will get all the first level of child nodes. 11 | 12 | ### Demo 13 | 14 | 1.Make #box's son tag p into red. 15 | 16 |
17 |

01

18 |
02 19 |

03

20 |
21 |

04

22 |
23 | 24 | O("#box").son("&p").setCss({color: "red"}); // 01 and 04 turn to red. 25 | 26 | 2.Make #box's all sons into red. 27 | 28 |
29 |

01

30 |
02 31 |

03

32 |
33 |

04

34 |
35 | 36 | O("#box").son().setCss({color: "red"}); // 01, 02, 03, 04 turn into red. 03 is inherit 02 and turn into red. 37 | -------------------------------------------------------------------------------- /doc/temp.md: -------------------------------------------------------------------------------- 1 | ## ____funName 2 | 3 | ### Description 4 | 5 | ____Description 6 | 7 | ### Syntax 8 | ____O("").fun() => self / value 9 | 10 | - ____args: ____args description 11 | 12 | ### Demo 13 | 14 | 1.____ 15 | 16 | ____ -------------------------------------------------------------------------------- /doc/width.md: -------------------------------------------------------------------------------- 1 | ## width( ) 2 | 3 | ### Description 4 | 5 | Get or set width. 6 | 7 | ### Syntax 8 | O("").width() => value 9 | O("").width(string) => self 10 | 11 | ### Demo 12 | 13 | 1.Get width of #buddy 14 | 15 | var a = O("#buddy").width(); 16 | 17 | 2.Set the width as "50px"; 18 | 19 | O("#buddy").width("50px") => self -------------------------------------------------------------------------------- /octjs.js: -------------------------------------------------------------------------------- 1 | /* 2 | * OctJs JavaScript Toolkit v1.0 3 | * https://github.com/younglaker/octjs 4 | * Description: Contains many frequently-used functions for web devolepment. 5 | * Copyright 2013, Laker Huang 6 | * Released under the MIT Licenses. 7 | * Date: 2013-05-27 to one day 8 | */ 9 | 10 | // 立即执行的匿名函数 11 | // 开头的分号,意在防止与其他js文件合并压缩时,由于上一个文件没有用分号结尾而产生问题 12 | ;(function(window) { 13 | 14 | // 定义一个作为局部函数的Oct。有些库的做法是一开始就定义一个全局变量,而另一些的做法是先定义成局部变量,最后再赋值给一个全局变量。这里采用的是后者。 15 | // Create a global window object "window.O" 16 | window.O = Oct = function(selector, root_id, tag) { 17 | return new Octobj(selector, root_id, tag); 18 | }; 19 | 20 | Oct.version = "1.0"; 21 | 22 | // Octobj类似JQ里的jQuery.init(函数也是对象,也可以添加属性和方法) 23 | // selector: the elements you want. 24 | // root_id: the root's id of the elements'root you want. 25 | // tag: point out the specific tag of the selector. If none, it's document. 26 | var Octobj = function(selector, root_id, tag) { 27 | 28 | // args: the array stores the tags in "root_id". 29 | // type: id("#"), class(".") or tag("&"). 30 | // eles: temporary!!! store the str after"# . &" 31 | var agrs, type, eles; 32 | var selector_exp = /^(?:#(\w-_)+|\.(\w-_)+|(\w)+)$/; 33 | 34 | // this.elements: store the elements you want and return in the end of function. 35 | this.elements = []; 36 | 37 | // HANDLE: $(""), $(null), $(undefined), $(false) 38 | if (!selector) { 39 | return this; 40 | } 41 | 42 | if (root_id) { 43 | root_id = typeof root_id == "string" ? document.getElementById(root_id) : root_id; 44 | } else { 45 | root_id = document.body; 46 | } 47 | tag = tag || "*"; 48 | if (tag !== "*") { 49 | tag = tag.slice(1); 50 | } 51 | 52 | // deal with "this". "this" usually means a actual tag like"
​hello
​" 53 | if (typeof(selector) == "object") { 54 | this.elements.push(selector); 55 | return; 56 | } 57 | 58 | // "querySelector" for samrt browser 59 | if (document.querySelectorAll) { 60 | // "replace" is for tag 61 | var node_list = document.querySelectorAll(selector.replace("&", "")) 62 | for (var i in node_list) { 63 | // You can "console.log(node_list[i]);" to see, there are some function or non-tag elements 64 | if (node_list[i].tagName !== undefined) { 65 | this.elements.push(node_list[i]); 66 | } 67 | } 68 | } 69 | else { 70 | // use lowercase to judge,and delete the space initio,then slpite by one or more space. 71 | selector = selector.replace(/^\s+/, "").split(/\s+/); 72 | 73 | // if dont point out the "root_id" and "tag", "args" is all the tags in document 74 | args = root_id.getElementsByTagName(tag); 75 | type = selector[0].charAt(0); 76 | eles = selector[0].slice(1); 77 | 78 | if (type === ".") { 79 | for (var i in args) { 80 | if(args[i].className) { 81 | 82 | // className maybe have more than one class, so split it by spaces 83 | var r = args[i].className.split(/\s+/); 84 | for (var j in r) { 85 | if (r[j] === eles) { 86 | this.elements.push(args[i]); 87 | } 88 | } 89 | } 90 | } 91 | } 92 | 93 | else if (type === "#") { 94 | for (var i in args) { 95 | if(args[i].id) { 96 | var r = args[i].id.split(/\s+/); 97 | for (var j in r) { 98 | if (r[j] === eles) { 99 | this.elements.push(args[i]); 100 | } 101 | } 102 | } 103 | } 104 | } 105 | 106 | else if (type === "&") { 107 | for (var i in args) { 108 | // You can "console.log(args[i]);" to see the last one is "length" which has noe "tagName" 109 | if (i !== "length" && typeof args[i] !== "function") { 110 | 111 | // "args[i].tagName" in browswer recognize uppercase, so base on coding habbit, use lowercase to juge. 112 | if (args[i].tagName.toLowerCase() === eles.toLowerCase()) { 113 | this.elements.push(args[i]); 114 | } 115 | } 116 | } 117 | 118 | } 119 | } 120 | 121 | // be careful!! here return "this",not "this.elememts", so do all the function. 122 | // return this; 这是构造函数, 实例化之后自动返回this对象,不需要再返回this对象了 123 | }; 124 | 125 | /**************************** Octobj.Fn ***********************************/ 126 | // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures 127 | // 如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。 128 | // 例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。原因是这将导致每次构造器被调用,方法都会被重新赋值一次(也就是说,为每一个对象的创建) 129 | 130 | Octobj.prototype = { 131 | 132 | each: function(fn) { 133 | /* 134 | for (var c in this.elements) { 135 | fn.call(this, this.elements[c]); 136 | }*/ 137 | // use "this.elements[]" to raplace "this" in the "fn",so it doesn't have to use "this.elements" to call the "fn". 138 | var i = this.elements.length; 139 | while (i--) { 140 | fn.call(this, this.elements[i]); 141 | } 142 | 143 | // here, "this" is the "Octobj" object,so do all the function. 144 | return this; 145 | }, 146 | 147 | html: function(text) { 148 | if (arguments.length === 0) { 149 | return this.elements[0].innerHTML; 150 | } else if (arguments.length === 1) { 151 | this.each(function(eles) { 152 | // Warning: dont use "this.elements", use "eles" 153 | eles.innerHTML = text; 154 | }); 155 | return this; 156 | } 157 | }, 158 | 159 | add: function(str) { 160 | 161 | // list: store valliables splited by "," and one or more space. 162 | var list = str.split(/\,\s*/); 163 | for (var i in list ) { 164 | 165 | // I have add some extend function for Array like "contains", here is to stop execute when funtion appear. 166 | if (typeof list[i] === "function") { 167 | return this; 168 | } 169 | 170 | // type: id("#"), class(".") or tag("&"). 171 | // name: the name of id or class or tag. 172 | type = list[i].charAt(0); 173 | name = list[i].slice(1); 174 | 175 | if (type === ".") { 176 | // for smart browser 177 | if (document.documentElement.classList) { 178 | this.each(function(eles) { 179 | eles.classList.add(name); 180 | }); 181 | } 182 | else { 183 | this.each(function(eles) { 184 | 185 | // If it doesnt have className before, then add "name" directly. Else id has className before, then add a spcace and "name" . 186 | eles.className = eles.className + (eles.className == "" ? "" : " ") + name; 187 | }); 188 | } 189 | } 190 | 191 | else if (type === "#") { 192 | this.each(function(eles) { 193 | eles.id = eles.id + (eles.id == "" ? "" : " ") + name; 194 | }); 195 | } 196 | } 197 | return this; 198 | }, 199 | 200 | remove: function(str) { 201 | var list = str.split(/\,\s*/); 202 | for (var i in list ) { 203 | 204 | // I have add some extend function for Array like "contains", here is to stop execute when funtion appear. 205 | if (typeof list[i] === "function") { 206 | return this; 207 | } 208 | 209 | type = list[i].charAt(0); 210 | name = list[i].slice(1); 211 | 212 | if (type === ".") { 213 | if (document.documentElement.classList) { 214 | this.each(function(eles) { 215 | eles.classList.remove(name); 216 | }); 217 | } 218 | else { 219 | this.each(function(eles) { 220 | 221 | // There maybe a space before the name. 222 | eles.className = eles.className.replace(new RegExp("(^|\\s+)" + name), ""); 223 | }); 224 | } 225 | } 226 | 227 | else if (type === "#") { 228 | this.each(function(eles) { 229 | eles.id = eles.id.replace(new RegExp("(^|\\s+)" + name), ""); 230 | }); 231 | } 232 | 233 | else if (type === "&") { 234 | this.each(function(eles) { 235 | for (var j in eles.childNodes) { 236 | 237 | // "nodeType === 1" means ELEMENT_NODE. Because "childNodes" contains "TEXT_NODE" which doesnt have "tagName" and report error 238 | if (eles.childNodes[j].nodeType === 1) { 239 | if (eles.childNodes[j].tagName.toLowerCase() === name.toLowerCase()) { 240 | eles.removeChild(eles.childNodes[j]); 241 | } 242 | } 243 | } 244 | }); 245 | } 246 | 247 | } 248 | 249 | return this; 250 | }, 251 | 252 | has: function(str) { 253 | var list = str.split(/\,\s*/); 254 | var ele_arr = []; 255 | for (var i in list ) { 256 | 257 | // I have add some extend function for Array like "contains", here is to stop execute when funtion appear. 258 | if (typeof list[i] === "function") { 259 | return this; 260 | } 261 | 262 | type = list[i].charAt(0); 263 | name = list[i].slice(1); 264 | 265 | 266 | if (type === ".") { 267 | if (document.documentElement.classList.contains) { 268 | this.each(function(eles) { 269 | if(eles.classList.contains("qq")) { 270 | ele_arr.push(eles); 271 | } 272 | }); 273 | } 274 | else { 275 | this.each(function(eles) { 276 | if (eles.className.match(name)) { 277 | ele_arr.push(eles); 278 | } 279 | }); 280 | } 281 | } 282 | 283 | else if (type === "#") { 284 | this.each(function(eles) { 285 | if (eles.id.match(name)) { 286 | ele_arr.push(eles); 287 | } 288 | }); 289 | } 290 | 291 | 292 | else if (type === "&") { 293 | this.each(function(eles) { 294 | for (var j in eles.childNodes) { 295 | 296 | // "nodeType === 1" means ELEMENT_NODE. Because "childNodes" contains "TEXT_NODE" which doesnt have "tagName" and report error 297 | if (eles.childNodes[j].nodeType === 1) { 298 | if (eles.childNodes[j].tagName.toLowerCase() === name.toLowerCase()) { 299 | ele_arr.push(eles); 300 | } 301 | } 302 | } 303 | }); 304 | } 305 | 306 | this.elements = ele_arr; 307 | ele_arr = []; 308 | } 309 | 310 | return this; 311 | }, 312 | 313 | setCss: function(property_list) { 314 | 315 | this.each(function(eles) { 316 | 317 | // "property_list" is a hash table. 318 | // "name" stores the index of "property_list". 319 | for (var name in property_list) { 320 | 321 | // Deal with the situation like "background-color", turn into "backgroundColor". 322 | var new_name = name; 323 | /* if (name.match("-")) { 324 | var p = name.match("-").index + 1; 325 | var c = name.charAt(p).toUpperCase(); 326 | new_name = name.replace(/-\w/, c); 327 | }*/ 328 | eles.style[new_name] = property_list[name]; 329 | } 330 | }); 331 | 332 | return this; 333 | }, 334 | 335 | getCss: function() { 336 | 337 | // property_name: the property name array, get from "arguments".Because in "each" function, "arguments" is no longer means property, so use a variable to store it. 338 | // property_val: store the property value ans return 339 | var property_name = arguments; 340 | var property_val = []; 341 | 342 | // IE 343 | if (document.documentElement.currentStyle) { 344 | this.each(function(eles) { 345 | for (var name in property_name){ 346 | 347 | // Deal with the situation like "background-color", turn into "backgroundColor". 348 | var new_name = property_name[name]; 349 | if (name.match("-")) { 350 | var p = name.match("-").index + 1; 351 | var c = name.charAt(p).toUpperCase(); 352 | new_name = name.replace(/-\w/, c); 353 | } 354 | property_val.push(eles.currentStyle[new_name]); 355 | } 356 | }); 357 | 358 | // not IE 359 | } else if (window.getComputedStyle) { 360 | this.each(function(eles) { 361 | for (var name in property_name){ 362 | var new_name = property_name[name]; 363 | if (name.match("-")) { 364 | var p = name.match("-").index + 1; 365 | var c = name.charAt(p).toUpperCase(); 366 | new_name = name.replace(/-\w/, c); 367 | } 368 | property_val.push(window.getComputedStyle(eles, null).getPropertyValue(new_name)); 369 | } 370 | }); 371 | } 372 | 373 | // Turn array into string. 374 | return property_val; 375 | }, 376 | 377 | setAttr: function(property_list) { 378 | 379 | this.each(function(eles) { 380 | 381 | // "property_list" is a hash table. 382 | // "name" stores the index of "property_list". 383 | for (var name in property_list) { 384 | eles.setAttribute( name, property_list[name]); 385 | } 386 | }); 387 | 388 | return this; 389 | }, 390 | 391 | getAttr: function(property) { 392 | return this.elements[0].getAttribute(property); 393 | }, 394 | 395 | hasAttr: function(property) { 396 | // return true or false 397 | return this.elements[0].hasAttribute(property); 398 | }, 399 | 400 | removeAttr: function(property) { 401 | this.each(function(eles) { 402 | eles.removeAttribute(property); 403 | }); 404 | return this; 405 | }, 406 | 407 | height: function() { 408 | if (arguments.length === 0) { 409 | 410 | // Because "getCss" "setCss" is function of "Oct" object, so must use "this"(a Oct object) to call them, not "this.elements" 411 | return this.getCss("height"); 412 | } else if (arguments.length === 1) { 413 | this.setCss({height: arguments[1]}); 414 | return this; 415 | } 416 | 417 | }, 418 | 419 | width: function() { 420 | if (arguments.length === 0) { 421 | return this.getCss("width").toString(); 422 | } else if (arguments.length === 1) { 423 | this.setCss({"width": arguments[1]}); 424 | return this; 425 | } 426 | }, 427 | 428 | setOpacity: function(level) { 429 | if (this.elements[0].style.opacity) { 430 | this.each(function(eles) { 431 | eles.style.opacity = level; 432 | }); 433 | 434 | // IE9 and earlier 435 | } else { 436 | this.each(function(eles) { 437 | eles.style.filter = "alpha(opacity=" + level * 100 + ")"; 438 | }); 439 | } 440 | }, 441 | 442 | parent: function() { 443 | var parent = []; 444 | this.each(function(eles) { 445 | parent.push(eles.parentNode); 446 | }); 447 | this.elements = parent; 448 | return this; 449 | }, 450 | 451 | children: function(selector, level_start, level_stop) { 452 | /* var tem_elements = this.elements; 453 | var tem_tags = [], tags_array = []; 454 | this.elements = []; 455 | tags_array = tem_elements[0].children; 456 | console.log(tags_array); 457 | level_start = level_start || 0; 458 | level_stop = level_stop || level_start; 459 | // use lowercase to judge,and delete the space initio,then slpite by one or more space. 460 | selector = selector.replace(/^\s+/, "").split(/\s+/); 461 | type = selector[0].charAt(0); 462 | eles = selector[0].slice(1); 463 | if (type === ".") { 464 | for (var i = 0; i < tags_array.length; i++) { 465 | if (tags_array[i].className == eles) { 466 | this.elements.push(tags_array[i]); 467 | } 468 | } 469 | } 470 | if (type === "#") { 471 | this.elements.push(document.getElementById(eles)); 472 | } 473 | if (type === "&") { 474 | for (var i = 0; i <= level_stop; i++) { 475 | tem_tags = tags_array; 476 | } 477 | }*/ 478 | 479 | /* var tem_elements = this.elements[0].children; 480 | console.log(tem_elements); 481 | this.elements = []; 482 | for (var i = 0; i < tem_elements.length; i++) { 483 | // "nodeType"=1 means ELEMENT_NODE 484 | if (tem_elements[i].nodeType === 1) { 485 | this.elements.push(tem_elements[i]); 486 | } 487 | } 488 | console.log(this.elements); 489 | */ 490 | /* 491 | var curr_ele = this.elements[0]; 492 | selector = selector.slice(1); 493 | console.log(selector); 494 | this.elements = []; 495 | for (var i = 0; i <= level_stop; i++) { 496 | while(!curr_ele.firstElementChild) { 497 | curr_ele = curr_ele.nextElementSibling; 498 | console.log("1"); 499 | } 500 | curr_ele = curr_ele.firstElementChild; 501 | console.log(curr_ele.tagName); 502 | if (i >= level_start && curr_ele.tagName == selector) { 503 | this.elements.push(curr_ele); 504 | console.log("2"); 505 | } 506 | while (curr_ele.nextElementSibling) { 507 | curr_ele = curr_ele.nextElementSibling; 508 | // console.log(curr_ele); 509 | if (i >= level_start && curr_ele == selector) { 510 | console.log("4"); 511 | this.elements.push(curr_ele); 512 | } 513 | } 514 | if (i === 0) { 515 | console.log("5"); 516 | curr_ele = curr_ele.parentElement.firstElementChild; 517 | } 518 | while (i > 0 && curr_ele.parentElement.nextElementSibling) { 519 | console.log("6"); 520 | curr_ele = curr_ele.parentElement.nextElementSibling; 521 | } 522 | } 523 | console.log(this.elements); 524 | return this;*/ 525 | }, 526 | 527 | son: function(selector) { 528 | var curr; 529 | var sons = []; 530 | var type = selector ? selector[0].charAt(0) : ""; 531 | var name = selector ? selector.slice(1) : ""; 532 | 533 | if (type === ".") { 534 | this.each(function(eles) { 535 | curr = eles.firstElementChild; 536 | 537 | if (curr.className.match(name)) { 538 | sons.push(curr); 539 | } 540 | 541 | while (curr.nextElementSibling) { 542 | curr = curr.nextElementSibling; 543 | if (curr.className.match(name)) { 544 | sons.push(curr); 545 | } 546 | } 547 | }); 548 | } 549 | 550 | else if (type === "#") { 551 | this.each(function(eles) { 552 | curr = eles.firstElementChild; 553 | 554 | if (curr.id.match(name)) { 555 | sons.push(curr); 556 | } 557 | 558 | while (curr.nextElementSibling) { 559 | curr = curr.nextElementSibling; 560 | if (curr.id.match(name)) { 561 | sons.push(curr); 562 | } 563 | } 564 | }); 565 | } 566 | 567 | else if (type === "&") { 568 | this.each(function(eles) { 569 | curr = eles.firstElementChild; 570 | 571 | if (name === curr.tagName.toLowerCase()) { 572 | sons.push(curr); 573 | } 574 | 575 | while (curr.nextElementSibling) { 576 | curr = curr.nextElementSibling; 577 | if (name.toLowerCase() === curr.tagName.toLowerCase()) { 578 | sons.push(curr); 579 | } 580 | } 581 | }); 582 | } 583 | 584 | else if (type === "") { 585 | this.each(function(eles) { 586 | curr = eles.firstElementChild; 587 | sons.push(curr); 588 | 589 | while (curr.nextElementSibling) { 590 | curr = curr.nextElementSibling; 591 | sons.push(curr); 592 | } 593 | }); 594 | } 595 | 596 | this.elements = sons; 597 | return this; 598 | }, 599 | 600 | /* addEvent: function(event_type, fn) { 601 | this.each(function(eles) { 602 | if (eles.addEventListener) { 603 | eles.addEventListener(event_type, fn, false); 604 | } else if (eles.attachEvent) { 605 | eles.attachEvent("on" + event_type, fn); 606 | } 607 | }); 608 | return this; 609 | },*/ 610 | 611 | addEvent: function(event_type, fn) { 612 | document.addEventListener ? this.each(function(eles) { 613 | eles.addEventListener(event_type, fn, false); 614 | }) : this.each(function(eles) { 615 | eles.attachEvent("on" + event_type, fn); 616 | }); 617 | return this; 618 | }, 619 | 620 | removeEvent: function(event_type, fn) { 621 | document.removeEventListener ? this.each(function(eles) { 622 | eles.removeEventListener(event_type, fn, false); 623 | }) : this.each(function(eles) { 624 | eles.detachEvent("on" + event_type, fn); 625 | }); 626 | return this; 627 | }, 628 | 629 | hover: function(fn_1, fn_2) { 630 | return this.mouseover(fn_1).mouseout(fn_2); 631 | }, 632 | 633 | click: function(fn) { 634 | this.addEvent("click", fn); 635 | return this; 636 | }, 637 | 638 | mouseover: function(fn) { 639 | this.addEvent("mouseover", fn); 640 | return this; 641 | }, 642 | 643 | mouseout: function(fn) { 644 | this.addEvent("mouseout", fn); 645 | return this; 646 | }, 647 | 648 | mousemove: function(fn) { 649 | this.addEvent("mousemove", fn); 650 | return this; 651 | }, 652 | 653 | mousedown: function(fn) { 654 | this.addEvent("mousedown", fn); 655 | return this; 656 | }, 657 | 658 | mouseup: function(fn) { 659 | this.addEvent("onmouseup", fn); 660 | return this; 661 | } 662 | 663 | }; 664 | 665 | /**************************** Oct.Fn ***********************************/ 666 | Oct.ieVerion = function() { 667 | var ua = navigator.userAgent; 668 | return /msie/.test(ua) && parseFloat((ua.match(/.*(?:rv|ie)[\/: ](.+?)([ \);]|$)/) || [])[1]) || false; 669 | }; 670 | 671 | Oct.browswer = function() { 672 | var ua = navigator.userAgent, 673 | result = {name: "", version: ""}, 674 | webkitVersion = /version\/(\d+(\.\d+)?)/i; 675 | 676 | if (/msie/i.test(ua)){ 677 | result.name = "IE"; 678 | // Or "/chrome\/((\d+.)+\d+)/i" 679 | result.version = ua.match(/msie (\d+(\.\d+)+)+/i)[1]; 680 | 681 | } else if (/chrome/i.test(ua)){ 682 | result.name = "Chrome"; 683 | result.version = ua.match(/chrome\/(\d+(\.\d+)+)/i)[1]; 684 | 685 | } else if (/firefox/i.test(ua)){ 686 | result.name = "Firefox"; 687 | result.version = ua.match(/firefox\/(\d+(\.\d+)+)/i)[1]; 688 | 689 | } else if (/safari/i.test(ua) && !/chrome/i.test(ua)){ 690 | result.name = "Safari"; 691 | result.version = ua.match(webkitVersion)[1]; 692 | 693 | } else if (/opera/i.test(ua)){ 694 | result.name = "Opera"; 695 | result.version = ua.match(webkitVersion)[1]; 696 | 697 | } else { 698 | result.name = "Others"; 699 | result.version = "NaN"; 700 | } 701 | 702 | return result; 703 | }; 704 | 705 | Oct.stopBubble = function(e) { 706 | 707 | e = window.event || e; 708 | 709 | // IE 710 | if(document.all) { 711 | e.cancelBubble = true; 712 | } 713 | 714 | // not IE 715 | else { 716 | e.stopPropagation(); 717 | } 718 | 719 | }; 720 | 721 | Oct.alert = function(msg) { 722 | alert(msg); 723 | }; 724 | 725 | Oct.randomNum = function(start, stop, type) { 726 | 727 | var random_num = makeRandom(stop); 728 | start = start || 0; 729 | stop = stop || 1; 730 | type = type || "float"; 731 | 732 | while (random_num <= start){ //include the stop 733 | random_num = makeRandom(stop); 734 | } 735 | 736 | if (type === "int") { 737 | random_num = parseInt(random_num); 738 | } 739 | 740 | return random_num; 741 | }; 742 | 743 | 744 | var makeRandom = function(max) { 745 | return Math.random() * max; 746 | }; 747 | 748 | Oct.global = {}; 749 | Oct.global.namespace = function(str) { 750 | var arr = str.split("."), o = Oct.global; 751 | for (var i = (arr[0] === "global") ? 1 : 0; i < arr.length; i++) { 752 | o[arr[i]] = o[arr[i]] || {}; 753 | o = o[arr[i]]; 754 | } 755 | }; 756 | 757 | // "trim()" is for lower than ie8 758 | Oct.trim = function(str) { 759 | if (String.prototype.trim) { 760 | return str.trim(); 761 | } else { 762 | return str.replace(/^\s+|\s+$/g, ""); 763 | } 764 | }; 765 | 766 | Oct.isEmpty = function(str) { 767 | return /^\s*$/.test(str); 768 | }; 769 | 770 | Oct.type = function(arg) { 771 | // Avoid when typeof "null" value return "object" 772 | return (arg === "null") ? "null" : (typeof arg); 773 | }; 774 | 775 | /* Oct.extend = function(super_class, sub_class) { 776 | var Extend = function() {}; 777 | Extend.prototype = super_class.prototype; 778 | sub_class.prototype.constructor = super_class; 779 | sub_class.super_class = super_class.prototype; 780 | if (super_class.prototype.constructor == Object.prototype.constructor) { 781 | super_class.prototype.constructor = super_class; 782 | } 783 | }*/ 784 | 785 | Oct.inhePro = function(super_class, sub_class) { 786 | sub_class.prototype = super_class.prototype; 787 | }; 788 | 789 | Oct.inheFn = function(super_class, ds, name) { 790 | var args = []; 791 | for (var i = 2; i < arguments.length; i++) { 792 | args.push(arguments[i]); 793 | } 794 | super_class.apply(ds, args); 795 | }; 796 | 797 | Oct.isExist = function(arg) { 798 | return typeof arg !== undefined; 799 | }; 800 | 801 | Oct.cookie = { 802 | set: function(options) { 803 | for (var i in arguments) { 804 | if (arguments[i].value !== undefined) { 805 | if (arguments[i] === undefined) { 806 | arguments[i] = {expires: "", path: "", domain: "", secure: ""}; 807 | } else { 808 | arguments[i].expires = parseInt(arguments[i].expires); 809 | if (typeof arguments[i].expires === "number") { 810 | var days = arguments[i].expires, 811 | t = arguments[i].expires = new Date(); 812 | // Caculate the day and set. 813 | t.setDate(t.getDate() + days); 814 | } 815 | } 816 | 817 | document.cookie = [ 818 | arguments[i].item, 819 | "=", 820 | arguments[i].value, 821 | arguments[i].expires ? "; expires=" + arguments[i].expires.toUTCString() : "", 822 | arguments[i].path ? "; path=" + arguments[i].path : "", 823 | arguments[i].domain ? "; domain=" + arguments[i].domain : "", 824 | arguments[i].secure ? "; secure" : "" 825 | ].join(""); 826 | } 827 | } 828 | }, 829 | 830 | read: function() { 831 | if (document.cookie !== "") { 832 | var cookies_arr = document.cookie.split(/=|;\s?/); 833 | var result_arr = []; 834 | for (var i in arguments) { 835 | for (var j = 0; j < cookies_arr.length; j = j + 2) { 836 | if (cookies_arr[j] === arguments[i]) { 837 | result_arr.push(cookies_arr[j+1]); 838 | } 839 | } 840 | } 841 | } 842 | return result_arr; 843 | }, 844 | 845 | remove: function() { 846 | if (document.cookie !== "") { 847 | var cookies_arr = document.cookie.split(/=|;\s?/); 848 | if (arguments.length === 0) { 849 | for (var j = 0; j < cookies_arr.length; j = j + 2) { 850 | Oct.cookie.set({item: cookies_arr[j], value: cookies_arr[j+1], expires: -1}); 851 | } 852 | } 853 | 854 | for (var i in arguments) { 855 | for (var j = 0; j < cookies_arr.length; j = j + 2) { 856 | if (cookies_arr[j] === arguments[i]) { 857 | Oct.cookie.set({item: cookies_arr[j], value: cookies_arr[j+1], expires: -1}); 858 | } 859 | } 860 | } 861 | } 862 | } 863 | 864 | }; 865 | 866 | Oct.isArray = function(value) { 867 | return Object.prototype.toString.apply(value) === "[object Array]"; 868 | }; 869 | 870 | Oct.matrix = function(line, row, init) { 871 | var a = [], mat = []; 872 | init = init || ""; 873 | if (line === 1) { 874 | for (var i = row; i--;) { 875 | mat[i] = init; 876 | } 877 | } else { 878 | for (var i = line; i--;) { 879 | a = []; 880 | for (var j = row; j--;) { 881 | a[j] = init; 882 | } 883 | mat[i] = a; 884 | } 885 | } 886 | return mat; 887 | }; 888 | 889 | var merge = function(left, right, positive) { 890 | var result = []; 891 | while (left.length > 0 && right.length > 0) { 892 | if (left[0] < right[0]) { 893 | result.push(left.shift()); 894 | } else { 895 | result.push(right.shift()); 896 | } 897 | } 898 | return result.concat(left, right); 899 | }; 900 | 901 | Oct.mergeSort = function(items, positive) { 902 | // Cant use "positive = positive || true". Cuz if positive=false, the "||" will make positive true, and cant get false any way. 903 | positive = positive === true || positive === undefined ? true : false; 904 | if (items.length === 1) { 905 | return items; 906 | } 907 | 908 | var r = [], result = [], len_i = items.length, len_r; 909 | for (var i = 0; i < len_i; i++) { 910 | r.push([items[i]]); 911 | } 912 | 913 | for (var lim = len_i; lim > 1; lim = (lim + 1) / 2) { 914 | for (var j = 0, k = 0; k < lim; j++, k += 2) { 915 | r[j] = merge(r[k], r[k + 1], positive); 916 | } 917 | r[j] = []; 918 | } 919 | 920 | len_r = r.length; 921 | r = r[0]; 922 | if (positive === true) { 923 | result = r; 924 | } else { 925 | for (var i = 0; i < len_r; i++) { 926 | result[i] = r[len_r - 1 -i]; 927 | } 928 | } 929 | return result; 930 | }; 931 | 932 | Oct = { 933 | test: function() { 934 | console.log("message"); 935 | }, 936 | 937 | extend: function(name, func) { 938 | if (!this[name]) { 939 | this["bb"] = func; 940 | } 941 | return this; 942 | }, 943 | 944 | tag: function(tag, cxt) { 945 | var stag = "<" + tag + ">", 946 | etag = ""; 947 | ctx = cxt || "" 948 | return stag + ctx + etag; 949 | } 950 | }; 951 | 952 | 953 | Function.prototype.method = function(name, fn) { 954 | if (!this.prototype[name]) { 955 | this.prototype[name] = fn; 956 | return this; 957 | } 958 | }; 959 | 960 | String.method("lengthdb", function() { 961 | var counts = 0, len = this.length; 962 | if (len) { 963 | for (var i = len; i--;) { 964 | if (this.charCodeAt(i) > 255) { 965 | counts += 2; 966 | } else { 967 | counts++; 968 | } 969 | } 970 | return counts; 971 | } else { 972 | return 0; 973 | } 974 | }); 975 | 976 | Number.method("int", function() { 977 | return ~~this 978 | }); 979 | /* 980 | Array.method("contain", function(ctx) { 981 | var i = this.length; 982 | while (i--) { 983 | if (this[i] === ctx) { 984 | return true; 985 | } 986 | } 987 | return false; 988 | });*/ 989 | 990 | Oct.sort = { 991 | asc: function(a, b) { 992 | return a - b; 993 | }, 994 | des: function(a, b) { 995 | return b - a; 996 | }, 997 | depNum: function(a, b) { 998 | if (a > Math.floor(a)) { 999 | return 1; 1000 | } 1001 | if (b > Math.floor(b)) { 1002 | return -1; 1003 | } 1004 | }, 1005 | noCaseAsc: function(a, b) { 1006 | var a = a.toLowerCase(), 1007 | b = b.toLowerCase(); 1008 | if (a > b) { 1009 | return 1; 1010 | } else { 1011 | return -1; 1012 | } 1013 | }, 1014 | noCaseDes: function(a, b) { 1015 | var a = a.toLowerCase(), 1016 | b = b.toLowerCase(); 1017 | if (a < b) { 1018 | return 1; 1019 | } else { 1020 | return -1; 1021 | } 1022 | } 1023 | }; 1024 | 1025 | Oct.localStorage = { 1026 | set: function() { 1027 | if (window.localStorage) { 1028 | for (var i in arguments) { 1029 | localStorage.setItem(arguments[i].item, arguments[i].value); 1030 | } 1031 | } 1032 | }, 1033 | 1034 | read: function() { 1035 | if (window.localStorage) { 1036 | var result_arr = []; 1037 | for (var i in arguments) { 1038 | result_arr.push(localStorage.getItem(arguments[i])); 1039 | } 1040 | return Oct.rmArrayFn(result_arr); 1041 | } 1042 | }, 1043 | 1044 | remove: function() { 1045 | if (window.localStorage) { 1046 | if (arguments[0] === undefined) { 1047 | for (i in localStorage) { 1048 | localStorage.removeItem(i); 1049 | } 1050 | } 1051 | else { 1052 | for (var i in arguments) { 1053 | localStorage.removeItem(arguments[i]); 1054 | } 1055 | } 1056 | } 1057 | } 1058 | }; 1059 | 1060 | Oct.rmArrayFn = function(arr) { 1061 | for (var i = arr.length; i > 0; i--) { 1062 | if (typeof arr[i] === "function") { 1063 | arr.slice(i); 1064 | } 1065 | } 1066 | return arr; 1067 | }; 1068 | 1069 | Oct.ajax = function(ajax_data) { 1070 | var type = { 1071 | xml: "application/xml, text/xml", 1072 | html: "text/html", 1073 | script: "text/javascript, application/javascript", 1074 | json: "application/json, text/javascript", 1075 | text: "text/plain", 1076 | _default: "*/*" 1077 | }; 1078 | var xhr_obj = new jxhr; 1079 | 1080 | ajax_data.method = ajax_data.method.toUpperCase() || "GET"; 1081 | ajax_data.datatype = ajax_data.datatype || "json"; 1082 | ajax_data.asyn = ajax_data.asyn || true; 1083 | 1084 | if (xhr_obj) { 1085 | xhr_obj.open(ajax_data.method, ajax_data.url, ajax_data.asyn); 1086 | xhr_obj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 1087 | xhr_obj.setRequestHeader("Accept", ajax_data.datatype && type[ajax_data.datatype] ? type[ajax_data.datatype] + ", */*" : type._default); 1088 | xhr_obj.onreadystatechange = function() { 1089 | if (xhr_obj.readyState == 1) { 1090 | ajax_data.laoding(xhr_obj.response); 1091 | } else { 1092 | if (xhr_obj.readyState == 2) { 1093 | ajax_data.laoded(xhr_obj.response); 1094 | } else { 1095 | if (xhr_obj.readyState == 3) { 1096 | ajax_data.interactive(xhr_obj.response); 1097 | } else { 1098 | if (xhr_obj.readyState == 4) { 1099 | if (xhr_obj.status == 200) { 1100 | Oct.dataform(xhr_obj, ajax_data.datatype); 1101 | ajax_data.success(xhr_obj.response); 1102 | return xhr_obj; 1103 | } else { 1104 | } 1105 | } 1106 | } 1107 | } 1108 | } 1109 | }; 1110 | try { 1111 | xhr_obj.send(ajax_data.method === "POST" ? Oct.serialize(ajax_data.senddata) : null) 1112 | } catch (j) { 1113 | ajax_data.fail(xhr_obj.response); 1114 | } 1115 | } 1116 | }; 1117 | 1118 | Oct.dataform = function(g, e) { 1119 | var d = g.getResponseHeader("content-type") || "", 1120 | c = e === "xml" || !e && d.indexOf("xml") >= 0, 1121 | f = c ? g.responseXML : g.responseText; 1122 | if (typeof f === "string") { 1123 | if (e === "json" || !e && d.indexOf("json") >= 0) { 1124 | // f = Oct.trim(f); 1125 | return window.JSON && window.JSON.parse ? window.JSON.parse(f) : (new Function("return " + f))() 1126 | } 1127 | } 1128 | return f 1129 | }; 1130 | 1131 | Oct.serialize = function(data) { 1132 | var key = [], val = [], pair = [], str = ""; 1133 | for (var name in data) { 1134 | key.push(encodeURIComponent(name)); 1135 | val.push(encodeURIComponent(data[name])); 1136 | } 1137 | for (var i = 0; i < key.length; i++) { 1138 | pair[i] = key[i] + "=" + val[i]; 1139 | } 1140 | return str = pair.join("&"); 1141 | }; 1142 | 1143 | function Jxhr() { 1144 | if (window.XMLHttpRequest) { 1145 | return new XMLHttpRequest(); 1146 | } else { // for IE5/6 1147 | return new ActiveXObject("Microsoft.XMLHTTP"); 1148 | } 1149 | }; 1150 | 1151 | // var jxhr = new Jxhr; 1152 | window.jxhr = jxhr = function() { 1153 | return new Jxhr; 1154 | }; 1155 | 1156 | jxhr.done = function(data) { 1157 | console.log(data); 1158 | }; 1159 | 1160 | Oct.rgbToHex = function(rgb) { 1161 | // rgb's form is rgb(x, y, z) 1162 | var color = rgb.toString().match(/\d+/g); // push x,y,z to array color 1163 | var hex = "#"; 1164 | 1165 | for (var i = 0; i < 3; i++) { 1166 | // 'Number.toString(16)' can exchange decimalism to hexadecimal. 1167 | // 'color[i]' is a string, need to be exchanged to number. 1168 | // add 0 to the front and slice the last two one in order to avoid single number.eg: 0A instead of A 1169 | hex += ("0" + Number(color[i]).toString(16)).slice(-2); 1170 | } 1171 | return hex; 1172 | }; 1173 | 1174 | Oct.hexToRgb = function(hex) { 1175 | // hex's form is #axbycz or #abc 1176 | var color = [], rgb = []; 1177 | 1178 | hex = hex.replace(/#/,""); 1179 | 1180 | if (hex.length == 3) { // deal "#abc" to "#aabbcc" 1181 | var tmp = []; 1182 | for (var i = 0; i < 3; i++) { 1183 | tmp.push(hex.charAt(i) + hex.charAt(i)); 1184 | } 1185 | hex = tmp.join(""); 1186 | } 1187 | 1188 | for (var i = 0; i < 3; i++) { 1189 | color[i] = "0x" + hex.substr(i+2, 2); 1190 | rgb.push(parseInt(Number(color[i]))); 1191 | } 1192 | return "rgb(" + rgb.join(",") + ")"; 1193 | }; 1194 | 1195 | })(window); 1196 | //将全局对象window作为参数传入,则可以使之在匿名函数内部作为局部变量访问,提供访问速度。 1197 | //最末尾的分号则是防止与下一个js文件发生合并冲突。 1198 | -------------------------------------------------------------------------------- /reference/Anyjs.js: -------------------------------------------------------------------------------- 1 | function() { 2 | var b = window.$ = anyjs = function() { 3 | return new a(arguments) 4 | }; 5 | anyjs.version = "2.8"; 6 | anyjs.ie = !-[1, ]; 7 | anyjs.temp = false; 8 | anyjs.globalvar = []; 9 | var a = function(o) { 10 | this.elements = []; 11 | this.anyOk = (document.getElementById && document.createElement && Array.prototype.push); 12 | for (var f = 0; f < o.length; f++) { 13 | var g = o[f], c = [], l = [], k, n = [], h = []; 14 | if (typeof g === "string") { 15 | if (g.indexOf("#") >= 0) { 16 | if (g.indexOf(" ") >= 0) { 17 | c = g.split(" "); 18 | k = document.getElementById(c[0].split("#")[1]); 19 | if (k) { 20 | l = k.getElementsByTagName(c[1]); 21 | for (var d = 0; d < l.length; d++) { 22 | this.elements.push(l[d]) 23 | } 24 | } 25 | } else { 26 | k = document.getElementById(g.split("#")[1]); 27 | if (k) { 28 | this.elements.push(k) 29 | } 30 | } 31 | } else { 32 | if (g.indexOf(".") >= 0) { 33 | if (g.split(".")[0] == "") { 34 | alert("CLASS SELECTOR FAILED,NO TAG"); 35 | return false 36 | } 37 | if (g.indexOf(" ") >= 0) { 38 | c = g.split(" "); 39 | n = document.getElementsByTagName(c[0].split(".")[0]); 40 | for (var d = 0; d < n.length; d++) { 41 | if (n[d].className == c[0].split(".")[1]) { 42 | h = n[d].getElementsByTagName(c[1]); 43 | for (var e = 0; e < h.length; e++) { 44 | this.elements.push(h[e]) 45 | } 46 | } 47 | } 48 | } else { 49 | n = document.getElementsByTagName(g.split(".")[0]); 50 | for (var d = 0; d < n.length; d++) { 51 | if (n[d].className == g.split(".")[1]) { 52 | this.elements.push(n[d]) 53 | } 54 | } 55 | } 56 | } else { 57 | n = document.getElementsByTagName(g); 58 | for (var e = 0; e < n.length; e++) { 59 | this.elements.push(n[e]) 60 | } 61 | } 62 | } 63 | } else { 64 | this.elements.push(g) 65 | } 66 | } 67 | }; 68 | a.prototype = {hov: function(d, c) { 69 | return this.msover(d).msout(c) 70 | },click: function(c) { 71 | var d = this; 72 | this.each(function(e) { 73 | d.addEvent(e, "click", c) 74 | }); 75 | return this 76 | },msover: function(c) { 77 | var d = this; 78 | this.each(function(e) { 79 | d.addEvent(e, "mouseover", c) 80 | }); 81 | return this 82 | },msout: function(c) { 83 | var d = this; 84 | this.each(function(e) { 85 | d.addEvent(e, "mouseout", c) 86 | }); 87 | return this 88 | },msmv: function(c) { 89 | var d = this; 90 | this.each(function(e) { 91 | d.addEvent(e, "mousemove", c) 92 | }); 93 | return this 94 | },toggle: function(d, c) { 95 | var e = this, f = this.elements[0].id; 96 | if (!anyjs.globalvar[f + "togglefunc"] || anyjs.globalvar[f + "togglefunc"] == c) { 97 | anyjs.globalvar[f + "togglefunc"] = c; 98 | e.rmvEvent(this.elements[0], "click") 99 | } else { 100 | anyjs.globalvar[f + "togglefunc"] = c; 101 | e.rmvEvent(this.elements[0], "click") 102 | } 103 | },blur: function(c) { 104 | var d = this; 105 | this.each(function(e) { 106 | d.addEvent(e, "blur", c) 107 | }); 108 | return this 109 | },focus: function(c) { 110 | var d = this; 111 | this.each(function(e) { 112 | d.addEvent(e, "focus", c) 113 | }); 114 | return this 115 | },change: function(c) { 116 | var d = this; 117 | this.each(function(e) { 118 | d.addEvent(e, "change", c) 119 | }); 120 | return this 121 | },submit: function(c) { 122 | var d = this; 123 | this.each(function(e) { 124 | d.addEvent(e, "submit", c) 125 | }); 126 | return this 127 | },load: function(d) { 128 | var c = this.elements[0] || window; 129 | return this.addEvent(c, "load", d) 130 | },keypress: function(d) { 131 | var c = this.elements[0] || document; 132 | return this.addEvent(c, "keypress", d) 133 | },keyup: function(d) { 134 | var c = this.elements[0] || document; 135 | return this.addEvent(c, "keyup", d) 136 | },cs: function(d, c) { 137 | if (!c) { 138 | var c = this.elements[0]; 139 | if (c.currentStyle) { 140 | return parseInt(c.currentStyle[d]) 141 | } else { 142 | return parseInt(window.getComputedStyle(c, null)[d]) 143 | } 144 | } 145 | this.each(function(e) { 146 | if (d == "opacity") { 147 | e.style.filter = "alpha(opacity=" + parseInt(c * 100) + ")"; 148 | e.style.opacity = c 149 | } else { 150 | e.style[d] = c 151 | } 152 | }); 153 | return this 154 | },show: function() { 155 | var c = this; 156 | this.each(function() { 157 | c.cs("display", "block") 158 | }); 159 | return this 160 | },hide: function() { 161 | var c = this; 162 | this.each(function() { 163 | c.cs("display", "none") 164 | }); 165 | return this 166 | },get: function(d) { 167 | var c = d || "value"; 168 | if (d == "class") { 169 | return this.elements[0].className 170 | } 171 | return this.elements[0].getAttribute(c) 172 | },set: function(c, d) { 173 | this.each(function(e) { 174 | if (c == "html" || c == "h") { 175 | e.innerHTML = d 176 | } else { 177 | if (c == "class") { 178 | e.className = e.className + (e.className == "" ? "" : " ") + d 179 | } else { 180 | e.setAttribute(c, d) 181 | } 182 | } 183 | }); 184 | return this 185 | },rmvcls: function(c) { 186 | this.each(function(d) { 187 | d.className = d.className.replace(c, "") 188 | }); 189 | return this 190 | },h: function(d) { 191 | if (!d) { 192 | return this.elements[0].innerHTML 193 | } 194 | var c = this; 195 | this.each(function() { 196 | c.set("h", d) 197 | }); 198 | return this 199 | },apd: function(c) { 200 | return this.elements[0].appendChild(c) 201 | },ist: function(c) { 202 | if (this.elements[0].firstChild) { 203 | return this.elements[0].insertBefore(c, this.elements[0].firstChild) 204 | } else { 205 | return this.elements[0].appendChild(c) 206 | } 207 | },rmv: function() { 208 | if (this.elements) { 209 | for (var c = 0; c < this.elements.length; c++) { 210 | this.elements[c].parentNode.removeChild(this.elements[c]) 211 | } 212 | } 213 | return null 214 | },fout: function() { 215 | var c = this, d = 100; 216 | if (anyjs.temp) { 217 | clearInterval(anyjs.temp) 218 | } 219 | anyjs.temp = setInterval(function() { 220 | d -= 5; 221 | c.cs("opacity", (d / 100)); 222 | if (d <= 0) { 223 | clearInterval(anyjs.temp); 224 | anyjs.temp = null; 225 | c.hide(); 226 | c.cs("opacity", 100) 227 | } 228 | }, 10) 229 | },fin: function() { 230 | var d = 1, c = this; 231 | if (anyjs.temp) { 232 | clearInterval(anyjs.temp) 233 | } 234 | c.cs("opacity", (0.05)); 235 | c.show(); 236 | anyjs.temp = setInterval(function() { 237 | d += 5; 238 | c.cs("opacity", (d / 100)); 239 | if (d >= 100) { 240 | clearInterval(anyjs.temp); 241 | anyjs.temp = null 242 | } 243 | }, 10) 244 | },sout: function(d, g) { 245 | d = d || 5; 246 | g = g || "height"; 247 | var c = this, e = c.cs(g), f = this.elements[0].id; 248 | if (e == 0) { 249 | return false 250 | } 251 | if (!anyjs.globalvar[f + "slide"]) { 252 | anyjs.globalvar[f + "slide"] = e 253 | } 254 | if (anyjs.temp) { 255 | clearInterval(anyjs.temp) 256 | } 257 | anyjs.temp = setInterval(function() { 258 | e -= d; 259 | c.cs(g, e + "px"); 260 | if (e <= 0) { 261 | clearInterval(anyjs.temp); 262 | anyjs.temp = null; 263 | c.hide() 264 | } 265 | }, 10) 266 | },sin: function(d, f) { 267 | var c = this, e = 0; 268 | id = this.elements[0].id; 269 | if (!anyjs.globalvar[id + "slide"]) { 270 | return false 271 | } 272 | d = d || 5; 273 | f = f || "height"; 274 | if (anyjs.temp) { 275 | clearInterval(anyjs.temp) 276 | } 277 | c.cs(f, e + "px"); 278 | c.show(); 279 | anyjs.temp = setInterval(function() { 280 | e += d; 281 | c.cs(f, e + "px"); 282 | if (e >= anyjs.globalvar[id + "slide"]) { 283 | clearInterval(anyjs.temp); 284 | anyjs.temp = null 285 | } 286 | }, 10) 287 | },each: function(d) { 288 | for (var c = 0; c < this.elements.length; c++) { 289 | d.call(this, this.elements[c]) 290 | } 291 | return this 292 | },addEvent: function(d, e, c) { 293 | if (d.addEventListener) { 294 | d.addEventListener(e, c, false); 295 | return true 296 | } else { 297 | if (d.attachEvent) { 298 | d["e" + e + c] = c; 299 | d.attachEvent("on" + e, function() { 300 | d["e" + e + c](window.event) 301 | }); 302 | return true 303 | } 304 | } 305 | return false 306 | },rmvEvent: function(d, c) { 307 | this.each(function(e) { 308 | if (e.removeEventListener) { 309 | e.removeEventListener(d, c, false) 310 | } else { 311 | e.detachEvent("on" + d, e["e" + d + c]); 312 | e["e" + d + c] = null 313 | } 314 | }); 315 | return this 316 | },callThis: function(){ 317 | this.each(function(e){ 318 | console.log(e.nodeName); 319 | }); 320 | return this; 321 | } 322 | }; 323 | anyjs.x = function(d) { 324 | d.method = d.method.toUpperCase() || "GET"; 325 | d.datatype = d.datatype || "HTML"; 326 | d.msgid = document.getElementById(d.msgid) || null; 327 | var h = {xml: "application/xml, text/xml",html: "text/html",script: "text/javascript, application/javascript",json: "application/json, text/javascript",text: "text/plain",_default: "*/*"}; 328 | if (!window.XMLHttpRequest) { 329 | XMLHttpRequest = function() { 330 | return new ActiveXObject("Microsoft.XMLHTTP") 331 | } 332 | } 333 | var k = new XMLHttpRequest; 334 | if (k) { 335 | var g = "Please waiting..."; 336 | var f = "Please waiting,sending..."; 337 | var i = "Please waiting,receiving..."; 338 | var c = "Connecting failed,try refresh page"; 339 | k.open(d.method, d.url, true); 340 | k.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 341 | k.setRequestHeader("Accept", d.datatype && h[d.datatype] ? h[d.datatype] + ", */*" : h._default); 342 | k.onreadystatechange = function() { 343 | if (k.readyState == 1) { 344 | d.msgid ? d.msgid.innerHTML = g : "" 345 | } else { 346 | if (k.readyState == 2) { 347 | d.msgid ? d.msgid.innerHTML = f : "" 348 | } else { 349 | if (k.readyState == 3) { 350 | d.msgid ? d.msgid.innerHTML = i : "" 351 | } else { 352 | if (k.readyState == 4) { 353 | if (k.status == 200) { 354 | d.callbackfn(anyjs.dataform(k, d.datatype)) 355 | } else { 356 | d.msgid ? d.msgid.innerHTML = c : "" 357 | } 358 | } 359 | } 360 | } 361 | } 362 | }; 363 | try { 364 | k.send(d.method === "POST" ? d.senddata : null) 365 | } catch (j) { 366 | } 367 | } 368 | }; 369 | anyjs.dataform = function(g, e) { 370 | var d = g.getResponseHeader("content-type") || "", c = e === "xml" || !e && d.indexOf("xml") >= 0, f = c ? g.responseXML : g.responseText; 371 | if (typeof f === "string") { 372 | if (e === "json" || !e && d.indexOf("json") >= 0) { 373 | f = anyjs.trim(f); 374 | return window.JSON && window.JSON.parse ? window.JSON.parse(f) : (new Function("return " + f))() 375 | } 376 | } 377 | return f 378 | }; 379 | anyjs.xget = function(d, c, g, f, e) { 380 | return anyjs.x({method: "GET",url: d,callbackfn: c,msgid: g,datatype: f,senddata: e}) 381 | }; 382 | anyjs.post = function(d, e, c, g, f) { 383 | return anyjs.x({method: "POST",url: d,senddata: e,callbackfn: c,msgid: g,datatype: f}) 384 | }; 385 | anyjs.gjson = function(d, c, e) { 386 | return anyjs.xget(d, c, e, "json") 387 | }; 388 | anyjs.gxml = function(d, c, e) { 389 | return anyjs.xget(d, c, e, "xml") 390 | }; 391 | anyjs.gjsonp = function(d, c) { 392 | var f = document.getElementsByTagName("head")[0]; 393 | var e = anyjs.create("script"); 394 | anyjs(e).set("type", "text/javascript").set("src", d); 395 | anyjs(f).apd(e); 396 | if (anyjs.ie) { 397 | e.onreadystatechange = function() { 398 | if (e.readyState == "loaded" || e.readyState == "complete") { 399 | (c)(JSONP); 400 | JSONP = null; 401 | anyjs(e).rmv() 402 | } 403 | } 404 | } else { 405 | e.onload = function() { 406 | (c)(JSONP); 407 | JSONP = null; 408 | anyjs(e).rmv() 409 | } 410 | } 411 | return false 412 | }; 413 | anyjs.create = function(c) { 414 | var d = null; 415 | try { 416 | d = document.createElement("<" + c + ' name="_tag_name_demo">') 417 | } catch (f) { 418 | d = document.createElement(c); 419 | d.name = "_tag_name_demo" 420 | } 421 | return d 422 | }; 423 | anyjs.trim = function(c) { 424 | return (c || "").replace(/(^\s+)|(\s+$)/g, "") 425 | } 426 | })(); 427 | var $$ = function() { 428 | return (typeof arguments[0]) == "string" ? document.getElementById(arguments[0]) : "null" 429 | }; 430 | var $t = function() { 431 | return (typeof arguments[0]) == "string" ? document.getElementsByTagName(arguments[0]) : "null" 432 | }; 433 | function createCookie(c, d, e) { 434 | if (e) { 435 | var b = new Date(); 436 | b.setTime(b.getTime() + (e * 24 * 60 * 60 * 1000)); 437 | var a = "; expires=" + b.toGMTString() 438 | } else { 439 | var a = "" 440 | } 441 | document.cookie = c + "=" + d + a + "; path=/" 442 | } 443 | function readCookie(b) { 444 | var e = b + "="; 445 | var a = document.cookie.split(";"); 446 | for (var d = 0; d < a.length; d++) { 447 | var f = a; 448 | while (f.charAt(0) == " ") { 449 | f = f.substring(1, f.length) 450 | } 451 | if (f.indexOf(e) == 0) { 452 | return f.substring(e.length, f.length) 453 | } 454 | } 455 | return null 456 | } 457 | function eraseCookie(a) { 458 | createCookie(a, "", -1) 459 | }; -------------------------------------------------------------------------------- /reference/browser.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bowser - a browser detector 3 | * https://github.com/ded/bowser 4 | * MIT License | (c) Dustin Diaz 2011 5 | */ 6 | !function (name, definition) { 7 | if (typeof define == 'function') define(definition) 8 | else if (typeof module != 'undefined' && module.exports) module.exports['browser'] = definition() 9 | else this[name] = definition() 10 | }('bowser', function () { 11 | /** 12 | * navigator.userAgent => 13 | * Chrome: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.57 Safari/534.24" 14 | * Opera: "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.7; U; en) Presto/2.7.62 Version/11.01" 15 | * Safari: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1" 16 | * IE: "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)" 17 | * Firefox: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0) Gecko/20100101 Firefox/4.0" 18 | * iPhone: "Mozilla/5.0 (iPhone Simulator; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5" 19 | * iPad: "Mozilla/5.0 (iPad; U; CPU OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5", 20 | * Android: "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; T-Mobile G2 Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1" 21 | * Touchpad: "Mozilla/5.0 (hp-tabled;Linux;hpwOS/3.0.5; U; en-US)) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0" 22 | * PhantomJS: "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.5.0 Safari/534.34" 23 | */ 24 | 25 | var ua = navigator.userAgent 26 | , t = true 27 | , ie = /msie/i.test(ua) 28 | , chrome = /chrome/i.test(ua) 29 | , phantom = /phantom/i.test(ua) 30 | , safari = /safari/i.test(ua) && !chrome && !phantom 31 | , iphone = /iphone/i.test(ua) 32 | , ipad = /ipad/i.test(ua) 33 | , touchpad = /touchpad/i.test(ua) 34 | , android = /android/i.test(ua) 35 | , opera = /opera/i.test(ua) 36 | , firefox = /firefox/i.test(ua) 37 | , gecko = /gecko\//i.test(ua) 38 | , seamonkey = /seamonkey\//i.test(ua) 39 | , webkitVersion = /version\/(\d+(\.\d+)?)/i 40 | , o 41 | 42 | function detect() { 43 | 44 | if (ie) return { 45 | msie: t 46 | , version: ua.match(/msie (\d+(\.\d+)?);/i)[1] 47 | } 48 | if (chrome) return { 49 | webkit: t 50 | , chrome: t 51 | , version: ua.match(/chrome\/(\d+(\.\d+)?)/i)[1] 52 | } 53 | if (phantom) return { 54 | webkit: t 55 | , phantom: t 56 | , version: ua.match(/phantomjs\/(\d+(\.\d+)+)/i)[1] 57 | } 58 | if (touchpad) return { 59 | webkit: t 60 | , touchpad: t 61 | , version : ua.match(/touchpad\/(\d+(\.\d+)?)/i)[1] 62 | } 63 | if (iphone || ipad) { 64 | o = { 65 | webkit: t 66 | , mobile: t 67 | , ios: t 68 | , iphone: iphone 69 | , ipad: ipad 70 | } 71 | // WTF: version is not part of user agent in web apps 72 | if (webkitVersion.test(ua)) { 73 | o.version = ua.match(webkitVersion)[1] 74 | } 75 | return o 76 | } 77 | if (android) return { 78 | webkit: t 79 | , android: t 80 | , mobile: t 81 | , version: ua.match(webkitVersion)[1] 82 | } 83 | if (safari) return { 84 | webkit: t 85 | , safari: t 86 | , version: ua.match(webkitVersion)[1] 87 | } 88 | if (opera) return { 89 | opera: t 90 | , version: ua.match(webkitVersion)[1] 91 | } 92 | if (gecko) { 93 | o = { 94 | gecko: t 95 | , mozilla: t 96 | , version: ua.match(/firefox\/(\d+(\.\d+)?)/i)[1] 97 | } 98 | if (firefox) o.firefox = t 99 | return o 100 | } 101 | if (seamonkey) return { 102 | seamonkey: t 103 | , version: ua.match(/seamonkey\/(\d+(\.\d+)?)/i)[1] 104 | } 105 | } 106 | 107 | var bowser = detect() 108 | 109 | // Graded Browser Support 110 | // http://developer.yahoo.com/yui/articles/gbs 111 | if ((bowser.msie && bowser.version >= 7) || 112 | (bowser.chrome && bowser.version >= 10) || 113 | (bowser.firefox && bowser.version >= 4.0) || 114 | (bowser.safari && bowser.version >= 5) || 115 | (bowser.opera && bowser.version >= 10.0)) { 116 | bowser.a = t; 117 | } 118 | 119 | else if ((bowser.msie && bowser.version < 7) || 120 | (bowser.chrome && bowser.version < 10) || 121 | (bowser.firefox && bowser.version < 4.0) || 122 | (bowser.safari && bowser.version < 5) || 123 | (bowser.opera && bowser.version < 10.0)) { 124 | bowser.c = t 125 | } else bowser.x = t 126 | 127 | return bowser 128 | }) -------------------------------------------------------------------------------- /reference/jquery.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cookie Plugin v1.3.1 3 | * https://github.com/carhartl/jquery-cookie 4 | * 5 | * Copyright 2013 Klaus Hartl 6 | * Released under the MIT license 7 | */ 8 | (function (factory) { 9 | if (typeof define === 'function' && define.amd) { 10 | // AMD. Register as anonymous module. 11 | define(['jquery'], factory); 12 | } else { 13 | // Browser globals. 14 | factory(jQuery); 15 | } 16 | }(function ($) { 17 | 18 | var pluses = /\+/g; 19 | 20 | function raw(s) { 21 | return s; 22 | } 23 | 24 | function decoded(s) { 25 | return decodeURIComponent(s.replace(pluses, ' ')); 26 | } 27 | 28 | function converted(s) { 29 | if (s.indexOf('"') === 0) { 30 | // This is a quoted cookie as according to RFC2068, unescape 31 | s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 32 | } 33 | try { 34 | return config.json ? JSON.parse(s) : s; 35 | } catch(er) {} 36 | } 37 | 38 | var config = $.cookie = function (key, value, options) { 39 | 40 | // write 41 | if (value !== undefined) { 42 | options = $.extend({}, config.defaults, options); 43 | 44 | if (typeof options.expires === 'number') { 45 | var days = options.expires, t = options.expires = new Date(); 46 | t.setDate(t.getDate() + days); 47 | } 48 | 49 | value = config.json ? JSON.stringify(value) : String(value); 50 | 51 | return (document.cookie = [ 52 | config.raw ? key : encodeURIComponent(key), 53 | '=', 54 | config.raw ? value : encodeURIComponent(value), 55 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 56 | options.path ? '; path=' + options.path : '', 57 | options.domain ? '; domain=' + options.domain : '', 58 | options.secure ? '; secure' : '' 59 | ].join('')); 60 | } 61 | 62 | // read 63 | var decode = config.raw ? raw : decoded; 64 | var cookies = document.cookie.split('; '); 65 | var result = key ? undefined : {}; 66 | for (var i = 0, l = cookies.length; i < l; i++) { 67 | var parts = cookies[i].split('='); 68 | var name = decode(parts.shift()); 69 | var cookie = decode(parts.join('=')); 70 | 71 | if (key && key === name) { 72 | result = converted(cookie); 73 | break; 74 | } 75 | 76 | if (!key) { 77 | result[name] = converted(cookie); 78 | } 79 | } 80 | 81 | return result; 82 | }; 83 | 84 | config.defaults = {}; 85 | 86 | $.removeCookie = function (key, options) { 87 | if ($.cookie(key) !== undefined) { 88 | // Must not alter options, thus extending a fresh object... 89 | $.cookie(key, '', $.extend({}, options, { expires: -1 })); 90 | return true; 91 | } 92 | return false; 93 | }; 94 | 95 | })); -------------------------------------------------------------------------------- /reference/sizzle.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Sizzle CSS Selector Engine 3 | * Copyright 2012 jQuery Foundation and other contributors 4 | * Released under the MIT license 5 | * http://sizzlejs.com/ 6 | */ 7 | (function( window, undefined ) { 8 | 9 | var cachedruns, 10 | assertGetIdNotName, 11 | Expr, 12 | getText, 13 | isXML, 14 | contains, 15 | compile, 16 | sortOrder, 17 | hasDuplicate, 18 | outermostContext, 19 | 20 | strundefined = "undefined", 21 | 22 | // Used in sorting 23 | MAX_NEGATIVE = 1 << 31, 24 | baseHasDuplicate = true, 25 | 26 | expando = ( "sizcache" + Math.random() ).replace( ".", "" ), 27 | 28 | Token = String, 29 | document = window.document, 30 | docElem = document.documentElement, 31 | dirruns = 0, 32 | done = 0, 33 | pop = [].pop, 34 | push = [].push, 35 | slice = [].slice, 36 | // Use a stripped-down indexOf if a native one is unavailable 37 | indexOf = [].indexOf || function( elem ) { 38 | var i = 0, 39 | len = this.length; 40 | for ( ; i < len; i++ ) { 41 | if ( this[i] === elem ) { 42 | return i; 43 | } 44 | } 45 | return -1; 46 | }, 47 | 48 | // Augment a function for special use by Sizzle 49 | markFunction = function( fn, value ) { 50 | fn[ expando ] = value == null || value; 51 | return fn; 52 | }, 53 | 54 | createCache = function() { 55 | var cache = {}, 56 | keys = []; 57 | 58 | return markFunction(function( key, value ) { 59 | // Only keep the most recent entries 60 | if ( keys.push( key ) > Expr.cacheLength ) { 61 | delete cache[ keys.shift() ]; 62 | } 63 | 64 | // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) 65 | return (cache[ key + " " ] = value); 66 | }, cache ); 67 | }, 68 | 69 | classCache = createCache(), 70 | tokenCache = createCache(), 71 | compilerCache = createCache(), 72 | 73 | // Regex 74 | 75 | // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace 76 | whitespace = "[\\x20\\t\\r\\n\\f]", 77 | // http://www.w3.org/TR/css3-syntax/#characters 78 | characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", 79 | 80 | // Loosely modeled on CSS identifier characters 81 | // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) 82 | // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 83 | identifier = characterEncoding.replace( "w", "w#" ), 84 | 85 | // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors 86 | operators = "([*^$|!~]?=)", 87 | attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + 88 | "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", 89 | 90 | // Prefer arguments not in parens/brackets, 91 | // then attribute selectors and non-pseudos (denoted by :), 92 | // then anything else 93 | // These preferences are here to reduce the number of selectors 94 | // needing tokenize in the PSEUDO preFilter 95 | pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", 96 | 97 | // For matchExpr.POS and matchExpr.needsContext 98 | pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 99 | "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", 100 | 101 | // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 102 | rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), 103 | 104 | rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 105 | rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), 106 | rpseudo = new RegExp( pseudos ), 107 | 108 | // Easily-parseable/retrievable ID or TAG or CLASS selectors 109 | rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, 110 | 111 | rsibling = /[\x20\t\r\n\f]*[+~]/, 112 | 113 | rheader = /h\d/i, 114 | rinputs = /input|select|textarea|button/i, 115 | 116 | rbackslash = /\\(?!\\)/g, 117 | 118 | matchExpr = { 119 | "ID": new RegExp( "^#(" + characterEncoding + ")" ), 120 | "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), 121 | "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), 122 | "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), 123 | "ATTR": new RegExp( "^" + attributes ), 124 | "PSEUDO": new RegExp( "^" + pseudos ), 125 | "POS": new RegExp( pos, "i" ), 126 | "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + 127 | "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + 128 | "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 129 | // For use in libraries implementing .is() 130 | "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) 131 | }, 132 | 133 | // Support 134 | 135 | // Used for testing something on an element 136 | assert = function( fn ) { 137 | var div = document.createElement("div"); 138 | 139 | try { 140 | return fn( div ); 141 | } catch (e) { 142 | return false; 143 | } finally { 144 | // release memory in IE 145 | div = null; 146 | } 147 | }, 148 | 149 | // Check if getElementsByTagName("*") returns only elements 150 | assertTagNameNoComments = assert(function( div ) { 151 | div.appendChild( document.createComment("") ); 152 | return !div.getElementsByTagName("*").length; 153 | }), 154 | 155 | // Check if getAttribute returns normalized href attributes 156 | assertHrefNotNormalized = assert(function( div ) { 157 | div.innerHTML = ""; 158 | return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && 159 | div.firstChild.getAttribute("href") === "#"; 160 | }), 161 | 162 | // Check if attributes should be retrieved by attribute nodes 163 | assertAttributes = assert(function( div ) { 164 | div.innerHTML = ""; 165 | var type = typeof div.lastChild.getAttribute("multiple"); 166 | // IE8 returns a string for some attributes even when not present 167 | return type !== "boolean" && type !== "string"; 168 | }), 169 | 170 | // Check if getElementsByClassName can be trusted 171 | assertUsableClassName = assert(function( div ) { 172 | // Opera can't find a second classname (in 9.6) 173 | div.innerHTML = ""; 174 | if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { 175 | return false; 176 | } 177 | 178 | // Safari 3.2 caches class attributes and doesn't catch changes 179 | div.lastChild.className = "e"; 180 | return div.getElementsByClassName("e").length === 2; 181 | }), 182 | 183 | // Check if getElementById returns elements by name 184 | // Check if getElementsByName privileges form controls or returns elements by ID 185 | assertUsableName = assert(function( div ) { 186 | // Inject content 187 | div.id = expando + 0; 188 | div.innerHTML = "
"; 189 | docElem.insertBefore( div, docElem.firstChild ); 190 | 191 | // Test 192 | var pass = document.getElementsByName && 193 | // buggy browsers will return fewer than the correct 2 194 | document.getElementsByName( expando ).length === 2 + 195 | // buggy browsers will return more than the correct 0 196 | document.getElementsByName( expando + 0 ).length; 197 | assertGetIdNotName = !document.getElementById( expando ); 198 | 199 | // Cleanup 200 | docElem.removeChild( div ); 201 | 202 | return pass; 203 | }); 204 | 205 | // If slice is not available, provide a backup 206 | try { 207 | slice.call( docElem.childNodes, 0 )[0].nodeType; 208 | } catch ( e ) { 209 | slice = function( i ) { 210 | var elem, 211 | results = []; 212 | for ( ; (elem = this[i]); i++ ) { 213 | results.push( elem ); 214 | } 215 | return results; 216 | }; 217 | } 218 | 219 | function Sizzle( selector, context, results, seed ) { 220 | results = results || []; 221 | context = context || document; 222 | var match, elem, xml, m, 223 | nodeType = context.nodeType; 224 | 225 | if ( !selector || typeof selector !== "string" ) { 226 | return results; 227 | } 228 | 229 | if ( nodeType !== 1 && nodeType !== 9 ) { 230 | return []; 231 | } 232 | 233 | xml = isXML( context ); 234 | 235 | if ( !xml && !seed ) { 236 | if ( (match = rquickExpr.exec( selector )) ) { 237 | // Speed-up: Sizzle("#ID") 238 | if ( (m = match[1]) ) { 239 | if ( nodeType === 9 ) { 240 | elem = context.getElementById( m ); 241 | // Check parentNode to catch when Blackberry 4.6 returns 242 | // nodes that are no longer in the document #6963 243 | if ( elem && elem.parentNode ) { 244 | // Handle the case where IE, Opera, and Webkit return items 245 | // by name instead of ID 246 | if ( elem.id === m ) { 247 | results.push( elem ); 248 | return results; 249 | } 250 | } else { 251 | return results; 252 | } 253 | } else { 254 | // Context is not a document 255 | if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && 256 | contains( context, elem ) && elem.id === m ) { 257 | results.push( elem ); 258 | return results; 259 | } 260 | } 261 | 262 | // Speed-up: Sizzle("TAG") 263 | } else if ( match[2] ) { 264 | push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); 265 | return results; 266 | 267 | // Speed-up: Sizzle(".CLASS") 268 | } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { 269 | push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); 270 | return results; 271 | } 272 | } 273 | } 274 | 275 | // All others 276 | return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); 277 | } 278 | 279 | Sizzle.matches = function( expr, elements ) { 280 | return Sizzle( expr, null, null, elements ); 281 | }; 282 | 283 | Sizzle.matchesSelector = function( elem, expr ) { 284 | return Sizzle( expr, null, null, [ elem ] ).length > 0; 285 | }; 286 | 287 | // Returns a function to use in pseudos for input types 288 | function createInputPseudo( type ) { 289 | return function( elem ) { 290 | var name = elem.nodeName.toLowerCase(); 291 | return name === "input" && elem.type === type; 292 | }; 293 | } 294 | 295 | // Returns a function to use in pseudos for buttons 296 | function createButtonPseudo( type ) { 297 | return function( elem ) { 298 | var name = elem.nodeName.toLowerCase(); 299 | return (name === "input" || name === "button") && elem.type === type; 300 | }; 301 | } 302 | 303 | // Returns a function to use in pseudos for positionals 304 | function createPositionalPseudo( fn ) { 305 | return markFunction(function( argument ) { 306 | argument = +argument; 307 | return markFunction(function( seed, matches ) { 308 | var j, 309 | matchIndexes = fn( [], seed.length, argument ), 310 | i = matchIndexes.length; 311 | 312 | // Match elements found at the specified indexes 313 | while ( i-- ) { 314 | if ( seed[ (j = matchIndexes[i]) ] ) { 315 | seed[j] = !(matches[j] = seed[j]); 316 | } 317 | } 318 | }); 319 | }); 320 | } 321 | 322 | /** 323 | * Utility function for retrieving the text value of an array of DOM nodes 324 | * @param {Array|Element} elem 325 | */ 326 | getText = Sizzle.getText = function( elem ) { 327 | var node, 328 | ret = "", 329 | i = 0, 330 | nodeType = elem.nodeType; 331 | 332 | if ( nodeType ) { 333 | if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 334 | // Use textContent for elements 335 | // innerText usage removed for consistency of new lines (see #11153) 336 | if ( typeof elem.textContent === "string" ) { 337 | return elem.textContent; 338 | } else { 339 | // Traverse its children 340 | for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 341 | ret += getText( elem ); 342 | } 343 | } 344 | } else if ( nodeType === 3 || nodeType === 4 ) { 345 | return elem.nodeValue; 346 | } 347 | // Do not include comment or processing instruction nodes 348 | } else { 349 | 350 | // If no nodeType, this is expected to be an array 351 | for ( ; (node = elem[i]); i++ ) { 352 | // Do not traverse comment nodes 353 | ret += getText( node ); 354 | } 355 | } 356 | return ret; 357 | }; 358 | 359 | isXML = Sizzle.isXML = function( elem ) { 360 | // documentElement is verified for cases where it doesn't yet exist 361 | // (such as loading iframes in IE - #4833) 362 | var documentElement = elem && (elem.ownerDocument || elem).documentElement; 363 | return documentElement ? documentElement.nodeName !== "HTML" : false; 364 | }; 365 | 366 | // Element contains another 367 | contains = Sizzle.contains = docElem.contains ? 368 | function( a, b ) { 369 | var adown = a.nodeType === 9 ? a.documentElement : a, 370 | bup = b && b.parentNode; 371 | return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); 372 | } : 373 | docElem.compareDocumentPosition ? 374 | function( a, b ) { 375 | return b && !!( a.compareDocumentPosition( b ) & 16 ); 376 | } : 377 | function( a, b ) { 378 | while ( (b = b.parentNode) ) { 379 | if ( b === a ) { 380 | return true; 381 | } 382 | } 383 | return false; 384 | }; 385 | 386 | Sizzle.attr = function( elem, name ) { 387 | var val, 388 | xml = isXML( elem ); 389 | 390 | if ( !xml ) { 391 | name = name.toLowerCase(); 392 | } 393 | if ( (val = Expr.attrHandle[ name ]) ) { 394 | return val( elem ); 395 | } 396 | if ( xml || assertAttributes ) { 397 | return elem.getAttribute( name ); 398 | } 399 | val = elem.getAttributeNode( name ); 400 | return val ? 401 | typeof elem[ name ] === "boolean" ? 402 | elem[ name ] ? name : null : 403 | val.specified ? val.value : null : 404 | null; 405 | }; 406 | 407 | Expr = Sizzle.selectors = { 408 | 409 | // Can be adjusted by the user 410 | cacheLength: 50, 411 | 412 | createPseudo: markFunction, 413 | 414 | match: matchExpr, 415 | 416 | // IE6/7 return a modified href 417 | attrHandle: assertHrefNotNormalized ? 418 | {} : 419 | { 420 | "href": function( elem ) { 421 | return elem.getAttribute( "href", 2 ); 422 | }, 423 | "type": function( elem ) { 424 | return elem.getAttribute("type"); 425 | } 426 | }, 427 | 428 | find: { 429 | "ID": assertGetIdNotName ? 430 | function( id, context, xml ) { 431 | if ( typeof context.getElementById !== strundefined && !xml ) { 432 | var m = context.getElementById( id ); 433 | // Check parentNode to catch when Blackberry 4.6 returns 434 | // nodes that are no longer in the document #6963 435 | return m && m.parentNode ? [m] : []; 436 | } 437 | } : 438 | function( id, context, xml ) { 439 | if ( typeof context.getElementById !== strundefined && !xml ) { 440 | var m = context.getElementById( id ); 441 | 442 | return m ? 443 | m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? 444 | [m] : 445 | undefined : 446 | []; 447 | } 448 | }, 449 | 450 | "TAG": assertTagNameNoComments ? 451 | function( tag, context ) { 452 | if ( typeof context.getElementsByTagName !== strundefined ) { 453 | return context.getElementsByTagName( tag ); 454 | } 455 | } : 456 | function( tag, context ) { 457 | var results = context.getElementsByTagName( tag ); 458 | 459 | // Filter out possible comments 460 | if ( tag === "*" ) { 461 | var elem, 462 | tmp = [], 463 | i = 0; 464 | 465 | for ( ; (elem = results[i]); i++ ) { 466 | if ( elem.nodeType === 1 ) { 467 | tmp.push( elem ); 468 | } 469 | } 470 | 471 | return tmp; 472 | } 473 | return results; 474 | }, 475 | 476 | "NAME": assertUsableName && function( tag, context ) { 477 | if ( typeof context.getElementsByName !== strundefined ) { 478 | return context.getElementsByName( name ); 479 | } 480 | }, 481 | 482 | "CLASS": assertUsableClassName && function( className, context, xml ) { 483 | if ( typeof context.getElementsByClassName !== strundefined && !xml ) { 484 | return context.getElementsByClassName( className ); 485 | } 486 | } 487 | }, 488 | 489 | relative: { 490 | ">": { dir: "parentNode", first: true }, 491 | " ": { dir: "parentNode" }, 492 | "+": { dir: "previousSibling", first: true }, 493 | "~": { dir: "previousSibling" } 494 | }, 495 | 496 | preFilter: { 497 | "ATTR": function( match ) { 498 | match[1] = match[1].replace( rbackslash, "" ); 499 | 500 | // Move the given value to match[3] whether quoted or unquoted 501 | match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); 502 | 503 | if ( match[2] === "~=" ) { 504 | match[3] = " " + match[3] + " "; 505 | } 506 | 507 | return match.slice( 0, 4 ); 508 | }, 509 | 510 | "CHILD": function( match ) { 511 | /* matches from matchExpr["CHILD"] 512 | 1 type (only|nth|...) 513 | 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 514 | 3 xn-component of xn+y argument ([+-]?\d*n|) 515 | 4 sign of xn-component 516 | 5 x of xn-component 517 | 6 sign of y-component 518 | 7 y of y-component 519 | */ 520 | match[1] = match[1].toLowerCase(); 521 | 522 | if ( match[1] === "nth" ) { 523 | // nth-child requires argument 524 | if ( !match[2] ) { 525 | Sizzle.error( match[0] ); 526 | } 527 | 528 | // numeric x and y parameters for Expr.filter.CHILD 529 | // remember that false/true cast respectively to 0/1 530 | match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); 531 | match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); 532 | 533 | // other types prohibit arguments 534 | } else if ( match[2] ) { 535 | Sizzle.error( match[0] ); 536 | } 537 | 538 | return match; 539 | }, 540 | 541 | "PSEUDO": function( match ) { 542 | var unquoted, excess; 543 | if ( matchExpr["CHILD"].test( match[0] ) ) { 544 | return null; 545 | } 546 | 547 | if ( match[3] ) { 548 | match[2] = match[3]; 549 | } else if ( (unquoted = match[4]) ) { 550 | // Only check arguments that contain a pseudo 551 | if ( rpseudo.test(unquoted) && 552 | // Get excess from tokenize (recursively) 553 | (excess = tokenize( unquoted, true )) && 554 | // advance to the next closing parenthesis 555 | (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { 556 | 557 | // excess is a negative index 558 | unquoted = unquoted.slice( 0, excess ); 559 | match[0] = match[0].slice( 0, excess ); 560 | } 561 | match[2] = unquoted; 562 | } 563 | 564 | // Return only captures needed by the pseudo filter method (type and argument) 565 | return match.slice( 0, 3 ); 566 | } 567 | }, 568 | 569 | filter: { 570 | "ID": assertGetIdNotName ? 571 | function( id ) { 572 | id = id.replace( rbackslash, "" ); 573 | return function( elem ) { 574 | return elem.getAttribute("id") === id; 575 | }; 576 | } : 577 | function( id ) { 578 | id = id.replace( rbackslash, "" ); 579 | return function( elem ) { 580 | var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); 581 | return node && node.value === id; 582 | }; 583 | }, 584 | 585 | "TAG": function( nodeName ) { 586 | if ( nodeName === "*" ) { 587 | return function() { return true; }; 588 | } 589 | nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); 590 | 591 | return function( elem ) { 592 | return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 593 | }; 594 | }, 595 | 596 | "CLASS": function( className ) { 597 | var pattern = classCache[ expando ][ className + " " ]; 598 | 599 | return pattern || 600 | (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && 601 | classCache( className, function( elem ) { 602 | return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); 603 | }); 604 | }, 605 | 606 | "ATTR": function( name, operator, check ) { 607 | return function( elem ) { 608 | var result = Sizzle.attr( elem, name ); 609 | 610 | if ( result == null ) { 611 | return operator === "!="; 612 | } 613 | if ( !operator ) { 614 | return true; 615 | } 616 | 617 | result += ""; 618 | 619 | return operator === "=" ? result === check : 620 | operator === "!=" ? result !== check : 621 | operator === "^=" ? check && result.indexOf( check ) === 0 : 622 | operator === "*=" ? check && result.indexOf( check ) > -1 : 623 | operator === "$=" ? check && result.substr( result.length - check.length ) === check : 624 | operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : 625 | operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : 626 | false; 627 | }; 628 | }, 629 | 630 | "CHILD": function( type, argument, first, last ) { 631 | 632 | if ( type === "nth" ) { 633 | return function( elem ) { 634 | var node, diff, 635 | parent = elem.parentNode; 636 | 637 | if ( first === 1 && last === 0 ) { 638 | return true; 639 | } 640 | 641 | if ( parent ) { 642 | diff = 0; 643 | for ( node = parent.firstChild; node; node = node.nextSibling ) { 644 | if ( node.nodeType === 1 ) { 645 | diff++; 646 | if ( elem === node ) { 647 | break; 648 | } 649 | } 650 | } 651 | } 652 | 653 | // Incorporate the offset (or cast to NaN), then check against cycle size 654 | diff -= last; 655 | return diff === first || ( diff % first === 0 && diff / first >= 0 ); 656 | }; 657 | } 658 | 659 | return function( elem ) { 660 | var node = elem; 661 | 662 | switch ( type ) { 663 | case "only": 664 | case "first": 665 | while ( (node = node.previousSibling) ) { 666 | if ( node.nodeType === 1 ) { 667 | return false; 668 | } 669 | } 670 | 671 | if ( type === "first" ) { 672 | return true; 673 | } 674 | 675 | node = elem; 676 | 677 | /* falls through */ 678 | case "last": 679 | while ( (node = node.nextSibling) ) { 680 | if ( node.nodeType === 1 ) { 681 | return false; 682 | } 683 | } 684 | 685 | return true; 686 | } 687 | }; 688 | }, 689 | 690 | "PSEUDO": function( pseudo, argument ) { 691 | // pseudo-class names are case-insensitive 692 | // http://www.w3.org/TR/selectors/#pseudo-classes 693 | // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 694 | // Remember that setFilters inherits from pseudos 695 | var args, 696 | fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 697 | Sizzle.error( "unsupported pseudo: " + pseudo ); 698 | 699 | // The user may use createPseudo to indicate that 700 | // arguments are needed to create the filter function 701 | // just as Sizzle does 702 | if ( fn[ expando ] ) { 703 | return fn( argument ); 704 | } 705 | 706 | // But maintain support for old signatures 707 | if ( fn.length > 1 ) { 708 | args = [ pseudo, pseudo, "", argument ]; 709 | return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 710 | markFunction(function( seed, matches ) { 711 | var idx, 712 | matched = fn( seed, argument ), 713 | i = matched.length; 714 | while ( i-- ) { 715 | idx = indexOf.call( seed, matched[i] ); 716 | seed[ idx ] = !( matches[ idx ] = matched[i] ); 717 | } 718 | }) : 719 | function( elem ) { 720 | return fn( elem, 0, args ); 721 | }; 722 | } 723 | 724 | return fn; 725 | } 726 | }, 727 | 728 | pseudos: { 729 | "not": markFunction(function( selector ) { 730 | // Trim the selector passed to compile 731 | // to avoid treating leading and trailing 732 | // spaces as combinators 733 | var input = [], 734 | results = [], 735 | matcher = compile( selector.replace( rtrim, "$1" ) ); 736 | 737 | return matcher[ expando ] ? 738 | markFunction(function( seed, matches, context, xml ) { 739 | var elem, 740 | unmatched = matcher( seed, null, xml, [] ), 741 | i = seed.length; 742 | 743 | // Match elements unmatched by `matcher` 744 | while ( i-- ) { 745 | if ( (elem = unmatched[i]) ) { 746 | seed[i] = !(matches[i] = elem); 747 | } 748 | } 749 | }) : 750 | function( elem, context, xml ) { 751 | input[0] = elem; 752 | matcher( input, null, xml, results ); 753 | return !results.pop(); 754 | }; 755 | }), 756 | 757 | "has": markFunction(function( selector ) { 758 | return function( elem ) { 759 | return Sizzle( selector, elem ).length > 0; 760 | }; 761 | }), 762 | 763 | "contains": markFunction(function( text ) { 764 | return function( elem ) { 765 | return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; 766 | }; 767 | }), 768 | 769 | "enabled": function( elem ) { 770 | return elem.disabled === false; 771 | }, 772 | 773 | "disabled": function( elem ) { 774 | return elem.disabled === true; 775 | }, 776 | 777 | "checked": function( elem ) { 778 | // In CSS3, :checked should return both checked and selected elements 779 | // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 780 | var nodeName = elem.nodeName.toLowerCase(); 781 | return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); 782 | }, 783 | 784 | "selected": function( elem ) { 785 | // Accessing this property makes selected-by-default 786 | // options in Safari work properly 787 | if ( elem.parentNode ) { 788 | elem.parentNode.selectedIndex; 789 | } 790 | 791 | return elem.selected === true; 792 | }, 793 | 794 | "parent": function( elem ) { 795 | return !Expr.pseudos["empty"]( elem ); 796 | }, 797 | 798 | "empty": function( elem ) { 799 | // http://www.w3.org/TR/selectors/#empty-pseudo 800 | // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), 801 | // not comment, processing instructions, or others 802 | // Thanks to Diego Perini for the nodeName shortcut 803 | // Greater than "@" means alpha characters (specifically not starting with "#" or "?") 804 | var nodeType; 805 | elem = elem.firstChild; 806 | while ( elem ) { 807 | if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { 808 | return false; 809 | } 810 | elem = elem.nextSibling; 811 | } 812 | return true; 813 | }, 814 | 815 | "header": function( elem ) { 816 | return rheader.test( elem.nodeName ); 817 | }, 818 | 819 | "text": function( elem ) { 820 | var type, attr; 821 | // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 822 | // use getAttribute instead to test this case 823 | return elem.nodeName.toLowerCase() === "input" && 824 | (type = elem.type) === "text" && 825 | ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); 826 | }, 827 | 828 | // Input types 829 | "radio": createInputPseudo("radio"), 830 | "checkbox": createInputPseudo("checkbox"), 831 | "file": createInputPseudo("file"), 832 | "password": createInputPseudo("password"), 833 | "image": createInputPseudo("image"), 834 | 835 | "submit": createButtonPseudo("submit"), 836 | "reset": createButtonPseudo("reset"), 837 | 838 | "button": function( elem ) { 839 | var name = elem.nodeName.toLowerCase(); 840 | return name === "input" && elem.type === "button" || name === "button"; 841 | }, 842 | 843 | "input": function( elem ) { 844 | return rinputs.test( elem.nodeName ); 845 | }, 846 | 847 | "focus": function( elem ) { 848 | var doc = elem.ownerDocument; 849 | return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 850 | }, 851 | 852 | "active": function( elem ) { 853 | return elem === elem.ownerDocument.activeElement; 854 | }, 855 | 856 | // Positional types 857 | "first": createPositionalPseudo(function() { 858 | return [ 0 ]; 859 | }), 860 | 861 | "last": createPositionalPseudo(function( matchIndexes, length ) { 862 | return [ length - 1 ]; 863 | }), 864 | 865 | "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { 866 | return [ argument < 0 ? argument + length : argument ]; 867 | }), 868 | 869 | "even": createPositionalPseudo(function( matchIndexes, length ) { 870 | for ( var i = 0; i < length; i += 2 ) { 871 | matchIndexes.push( i ); 872 | } 873 | return matchIndexes; 874 | }), 875 | 876 | "odd": createPositionalPseudo(function( matchIndexes, length ) { 877 | for ( var i = 1; i < length; i += 2 ) { 878 | matchIndexes.push( i ); 879 | } 880 | return matchIndexes; 881 | }), 882 | 883 | "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { 884 | for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { 885 | matchIndexes.push( i ); 886 | } 887 | return matchIndexes; 888 | }), 889 | 890 | "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { 891 | for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { 892 | matchIndexes.push( i ); 893 | } 894 | return matchIndexes; 895 | }) 896 | } 897 | }; 898 | 899 | function siblingCheck( a, b ) { 900 | 901 | if ( a && b ) { 902 | var cur = a.nextSibling; 903 | 904 | while ( cur ) { 905 | if ( cur === b ) { 906 | return -1; 907 | } 908 | 909 | cur = cur.nextSibling; 910 | } 911 | } 912 | 913 | return a ? 1 : -1; 914 | } 915 | 916 | sortOrder = docElem.compareDocumentPosition ? 917 | function( a, b ) { 918 | var compare, parent; 919 | if ( a === b ) { 920 | hasDuplicate = true; 921 | return 0; 922 | } 923 | 924 | if ( a.compareDocumentPosition && b.compareDocumentPosition ) { 925 | if ( (compare = a.compareDocumentPosition( b )) & 1 || (( parent = a.parentNode ) && parent.nodeType === 11) ) { 926 | if ( a === document || contains(document, a) ) { 927 | return -1; 928 | } 929 | if ( b === document || contains(document, b) ) { 930 | return 1; 931 | } 932 | return 0; 933 | } 934 | return compare & 4 ? -1 : 1; 935 | } 936 | 937 | return a.compareDocumentPosition ? -1 : 1; 938 | } : 939 | function( a, b ) { 940 | // The nodes are identical, we can exit early 941 | if ( a === b ) { 942 | hasDuplicate = true; 943 | return 0; 944 | 945 | // Fallback to using sourceIndex (in IE) if it's available on both nodes 946 | } else if ( a.sourceIndex && b.sourceIndex ) { 947 | return ( ~b.sourceIndex || ( MAX_NEGATIVE ) ) - ( contains( document, a ) && ~a.sourceIndex || ( MAX_NEGATIVE ) ); 948 | } 949 | 950 | var i = 0, 951 | ap = [ a ], 952 | bp = [ b ], 953 | aup = a.parentNode, 954 | bup = b.parentNode, 955 | cur = aup; 956 | 957 | // If no parents were found then the nodes are disconnected 958 | if ( a === document ) { 959 | return -1; 960 | 961 | } else if ( b === document ) { 962 | return 1; 963 | 964 | } else if ( !aup && !bup ) { 965 | return 0; 966 | 967 | } else if ( !bup ) { 968 | return -1; 969 | 970 | } else if ( !aup ) { 971 | return 1; 972 | 973 | // If the nodes are siblings (or identical) we can do a quick check 974 | } else if ( aup === bup ) { 975 | return siblingCheck( a, b ); 976 | } 977 | 978 | // Otherwise they're somewhere else in the tree so we need 979 | // to build up a full list of the parentNodes for comparison 980 | while ( cur ) { 981 | ap.unshift( cur ); 982 | cur = cur.parentNode; 983 | } 984 | 985 | cur = bup; 986 | 987 | while ( cur ) { 988 | bp.unshift( cur ); 989 | cur = cur.parentNode; 990 | } 991 | 992 | // Walk down the tree looking for a discrepancy 993 | while ( ap[i] === bp[i] ) { 994 | i++; 995 | } 996 | 997 | // Prefer our document 998 | if ( i === 0 ) { 999 | if ( ap[0] === document || contains(document, ap[0]) ) { 1000 | return -1; 1001 | } 1002 | if ( bp[0] === document || contains(document, bp[0]) ) { 1003 | return 1; 1004 | } 1005 | return 0; 1006 | } 1007 | 1008 | // We ended someplace up the tree so do a sibling check 1009 | return siblingCheck( ap[i], bp[i] ); 1010 | }; 1011 | 1012 | // Always assume the presence of duplicates if sort doesn't 1013 | // pass them to our comparison function (as in Google Chrome). 1014 | [0, 0].sort( sortOrder ); 1015 | baseHasDuplicate = !hasDuplicate; 1016 | 1017 | // Document sorting and removing duplicates 1018 | Sizzle.uniqueSort = function( results ) { 1019 | var elem, 1020 | duplicates = [], 1021 | i = 1, 1022 | j = 0; 1023 | 1024 | hasDuplicate = baseHasDuplicate; 1025 | results.sort( sortOrder ); 1026 | 1027 | if ( hasDuplicate ) { 1028 | for ( ; (elem = results[i]); i++ ) { 1029 | if ( elem === results[ i - 1 ] ) { 1030 | j = duplicates.push( i ); 1031 | } 1032 | } 1033 | while ( j-- ) { 1034 | results.splice( duplicates[ j ], 1 ); 1035 | } 1036 | } 1037 | 1038 | return results; 1039 | }; 1040 | 1041 | Sizzle.error = function( msg ) { 1042 | throw new Error( "Syntax error, unrecognized expression: " + msg ); 1043 | }; 1044 | 1045 | function tokenize( selector, parseOnly ) { 1046 | var matched, match, tokens, type, 1047 | soFar, groups, preFilters, 1048 | cached = tokenCache[ expando ][ selector + " " ]; 1049 | 1050 | if ( cached ) { 1051 | return parseOnly ? 0 : cached.slice( 0 ); 1052 | } 1053 | 1054 | soFar = selector; 1055 | groups = []; 1056 | preFilters = Expr.preFilter; 1057 | 1058 | while ( soFar ) { 1059 | 1060 | // Comma and first run 1061 | if ( !matched || (match = rcomma.exec( soFar )) ) { 1062 | if ( match ) { 1063 | // Don't consume trailing commas as valid 1064 | soFar = soFar.slice( match[0].length ) || soFar; 1065 | } 1066 | groups.push( tokens = [] ); 1067 | } 1068 | 1069 | matched = false; 1070 | 1071 | // Combinators 1072 | if ( (match = rcombinators.exec( soFar )) ) { 1073 | tokens.push( matched = new Token( match.shift() ) ); 1074 | soFar = soFar.slice( matched.length ); 1075 | 1076 | // Cast descendant combinators to space 1077 | matched.type = match[0].replace( rtrim, " " ); 1078 | } 1079 | 1080 | // Filters 1081 | for ( type in Expr.filter ) { 1082 | if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || 1083 | (match = preFilters[ type ]( match ))) ) { 1084 | 1085 | tokens.push( matched = new Token( match.shift() ) ); 1086 | soFar = soFar.slice( matched.length ); 1087 | matched.type = type; 1088 | matched.matches = match; 1089 | } 1090 | } 1091 | 1092 | if ( !matched ) { 1093 | break; 1094 | } 1095 | } 1096 | 1097 | // Return the length of the invalid excess 1098 | // if we're just parsing 1099 | // Otherwise, throw an error or return tokens 1100 | return parseOnly ? 1101 | soFar.length : 1102 | soFar ? 1103 | Sizzle.error( selector ) : 1104 | // Cache the tokens 1105 | tokenCache( selector, groups ).slice( 0 ); 1106 | } 1107 | 1108 | function addCombinator( matcher, combinator, base ) { 1109 | var dir = combinator.dir, 1110 | checkNonElements = base && combinator.dir === "parentNode", 1111 | doneName = done++; 1112 | 1113 | return combinator.first ? 1114 | // Check against closest ancestor/preceding element 1115 | function( elem, context, xml ) { 1116 | while ( (elem = elem[ dir ]) ) { 1117 | if ( checkNonElements || elem.nodeType === 1 ) { 1118 | return matcher( elem, context, xml ); 1119 | } 1120 | } 1121 | } : 1122 | 1123 | // Check against all ancestor/preceding elements 1124 | function( elem, context, xml ) { 1125 | // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching 1126 | if ( !xml ) { 1127 | var cache, 1128 | dirkey = dirruns + " " + doneName + " ", 1129 | cachedkey = dirkey + cachedruns; 1130 | while ( (elem = elem[ dir ]) ) { 1131 | if ( checkNonElements || elem.nodeType === 1 ) { 1132 | if ( (cache = elem[ expando ]) === cachedkey ) { 1133 | return elem.sizset; 1134 | } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { 1135 | if ( elem.sizset ) { 1136 | return elem; 1137 | } 1138 | } else { 1139 | elem[ expando ] = cachedkey; 1140 | if ( matcher( elem, context, xml ) ) { 1141 | elem.sizset = true; 1142 | return elem; 1143 | } 1144 | elem.sizset = false; 1145 | } 1146 | } 1147 | } 1148 | } else { 1149 | while ( (elem = elem[ dir ]) ) { 1150 | if ( checkNonElements || elem.nodeType === 1 ) { 1151 | if ( matcher( elem, context, xml ) ) { 1152 | return elem; 1153 | } 1154 | } 1155 | } 1156 | } 1157 | }; 1158 | } 1159 | 1160 | function elementMatcher( matchers ) { 1161 | return matchers.length > 1 ? 1162 | function( elem, context, xml ) { 1163 | var i = matchers.length; 1164 | while ( i-- ) { 1165 | if ( !matchers[i]( elem, context, xml ) ) { 1166 | return false; 1167 | } 1168 | } 1169 | return true; 1170 | } : 1171 | matchers[0]; 1172 | } 1173 | 1174 | function condense( unmatched, map, filter, context, xml ) { 1175 | var elem, 1176 | newUnmatched = [], 1177 | i = 0, 1178 | len = unmatched.length, 1179 | mapped = map != null; 1180 | 1181 | for ( ; i < len; i++ ) { 1182 | if ( (elem = unmatched[i]) ) { 1183 | if ( !filter || filter( elem, context, xml ) ) { 1184 | newUnmatched.push( elem ); 1185 | if ( mapped ) { 1186 | map.push( i ); 1187 | } 1188 | } 1189 | } 1190 | } 1191 | 1192 | return newUnmatched; 1193 | } 1194 | 1195 | function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 1196 | if ( postFilter && !postFilter[ expando ] ) { 1197 | postFilter = setMatcher( postFilter ); 1198 | } 1199 | if ( postFinder && !postFinder[ expando ] ) { 1200 | postFinder = setMatcher( postFinder, postSelector ); 1201 | } 1202 | return markFunction(function( seed, results, context, xml ) { 1203 | var temp, i, elem, 1204 | preMap = [], 1205 | postMap = [], 1206 | preexisting = results.length, 1207 | 1208 | // Get initial elements from seed or context 1209 | elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), 1210 | 1211 | // Prefilter to get matcher input, preserving a map for seed-results synchronization 1212 | matcherIn = preFilter && ( seed || !selector ) ? 1213 | condense( elems, preMap, preFilter, context, xml ) : 1214 | elems, 1215 | 1216 | matcherOut = matcher ? 1217 | // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 1218 | postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 1219 | 1220 | // ...intermediate processing is necessary 1221 | [] : 1222 | 1223 | // ...otherwise use results directly 1224 | results : 1225 | matcherIn; 1226 | 1227 | // Find primary matches 1228 | if ( matcher ) { 1229 | matcher( matcherIn, matcherOut, context, xml ); 1230 | } 1231 | 1232 | // Apply postFilter 1233 | if ( postFilter ) { 1234 | temp = condense( matcherOut, postMap ); 1235 | postFilter( temp, [], context, xml ); 1236 | 1237 | // Un-match failing elements by moving them back to matcherIn 1238 | i = temp.length; 1239 | while ( i-- ) { 1240 | if ( (elem = temp[i]) ) { 1241 | matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); 1242 | } 1243 | } 1244 | } 1245 | 1246 | if ( seed ) { 1247 | if ( postFinder || preFilter ) { 1248 | if ( postFinder ) { 1249 | // Get the final matcherOut by condensing this intermediate into postFinder contexts 1250 | temp = []; 1251 | i = matcherOut.length; 1252 | while ( i-- ) { 1253 | if ( (elem = matcherOut[i]) ) { 1254 | // Restore matcherIn since elem is not yet a final match 1255 | temp.push( (matcherIn[i] = elem) ); 1256 | } 1257 | } 1258 | postFinder( null, (matcherOut = []), temp, xml ); 1259 | } 1260 | 1261 | // Move matched elements from seed to results to keep them synchronized 1262 | i = matcherOut.length; 1263 | while ( i-- ) { 1264 | if ( (elem = matcherOut[i]) && 1265 | (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { 1266 | 1267 | seed[temp] = !(results[temp] = elem); 1268 | } 1269 | } 1270 | } 1271 | 1272 | // Add elements to results, through postFinder if defined 1273 | } else { 1274 | matcherOut = condense( 1275 | matcherOut === results ? 1276 | matcherOut.splice( preexisting, matcherOut.length ) : 1277 | matcherOut 1278 | ); 1279 | if ( postFinder ) { 1280 | postFinder( null, results, matcherOut, xml ); 1281 | } else { 1282 | push.apply( results, matcherOut ); 1283 | } 1284 | } 1285 | }); 1286 | } 1287 | 1288 | function matcherFromTokens( tokens ) { 1289 | var checkContext, matcher, j, 1290 | len = tokens.length, 1291 | leadingRelative = Expr.relative[ tokens[0].type ], 1292 | implicitRelative = leadingRelative || Expr.relative[" "], 1293 | i = leadingRelative ? 1 : 0, 1294 | 1295 | // The foundational matcher ensures that elements are reachable from top-level context(s) 1296 | matchContext = addCombinator( function( elem ) { 1297 | return elem === checkContext; 1298 | }, implicitRelative, true ), 1299 | matchAnyContext = addCombinator( function( elem ) { 1300 | return indexOf.call( checkContext, elem ) > -1; 1301 | }, implicitRelative, true ), 1302 | matchers = [ function( elem, context, xml ) { 1303 | return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 1304 | (checkContext = context).nodeType ? 1305 | matchContext( elem, context, xml ) : 1306 | matchAnyContext( elem, context, xml ) ); 1307 | } ]; 1308 | 1309 | for ( ; i < len; i++ ) { 1310 | if ( (matcher = Expr.relative[ tokens[i].type ]) ) { 1311 | matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 1312 | } else { 1313 | matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); 1314 | 1315 | // Return special upon seeing a positional matcher 1316 | if ( matcher[ expando ] ) { 1317 | // Find the next relative operator (if any) for proper handling 1318 | j = ++i; 1319 | for ( ; j < len; j++ ) { 1320 | if ( Expr.relative[ tokens[j].type ] ) { 1321 | break; 1322 | } 1323 | } 1324 | return setMatcher( 1325 | i > 1 && elementMatcher( matchers ), 1326 | i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), 1327 | matcher, 1328 | i < j && matcherFromTokens( tokens.slice( i, j ) ), 1329 | j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), 1330 | j < len && tokens.join("") 1331 | ); 1332 | } 1333 | matchers.push( matcher ); 1334 | } 1335 | } 1336 | 1337 | return elementMatcher( matchers ); 1338 | } 1339 | 1340 | function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 1341 | var bySet = setMatchers.length > 0, 1342 | byElement = elementMatchers.length > 0, 1343 | superMatcher = function( seed, context, xml, results, expandContext ) { 1344 | var elem, j, matcher, 1345 | setMatched = [], 1346 | matchedCount = 0, 1347 | i = "0", 1348 | unmatched = seed && [], 1349 | outermost = expandContext != null, 1350 | contextBackup = outermostContext, 1351 | // We must always have either seed elements or context 1352 | elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), 1353 | // Nested matchers should use non-integer dirruns 1354 | dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); 1355 | 1356 | if ( outermost ) { 1357 | outermostContext = context !== document && context; 1358 | cachedruns = superMatcher.el; 1359 | } 1360 | 1361 | // Add elements passing elementMatchers directly to results 1362 | for ( ; (elem = elems[i]) != null; i++ ) { 1363 | if ( byElement && elem ) { 1364 | for ( j = 0; (matcher = elementMatchers[j]); j++ ) { 1365 | if ( matcher( elem, context, xml ) ) { 1366 | results.push( elem ); 1367 | break; 1368 | } 1369 | } 1370 | if ( outermost ) { 1371 | dirruns = dirrunsUnique; 1372 | cachedruns = ++superMatcher.el; 1373 | } 1374 | } 1375 | 1376 | // Track unmatched elements for set filters 1377 | if ( bySet ) { 1378 | // They will have gone through all possible matchers 1379 | if ( (elem = !matcher && elem) ) { 1380 | matchedCount--; 1381 | } 1382 | 1383 | // Lengthen the array for every element, matched or not 1384 | if ( seed ) { 1385 | unmatched.push( elem ); 1386 | } 1387 | } 1388 | } 1389 | 1390 | // Apply set filters to unmatched elements 1391 | matchedCount += i; 1392 | if ( bySet && i !== matchedCount ) { 1393 | for ( j = 0; (matcher = setMatchers[j]); j++ ) { 1394 | matcher( unmatched, setMatched, context, xml ); 1395 | } 1396 | 1397 | if ( seed ) { 1398 | // Reintegrate element matches to eliminate the need for sorting 1399 | if ( matchedCount > 0 ) { 1400 | while ( i-- ) { 1401 | if ( !(unmatched[i] || setMatched[i]) ) { 1402 | setMatched[i] = pop.call( results ); 1403 | } 1404 | } 1405 | } 1406 | 1407 | // Discard index placeholder values to get only actual matches 1408 | setMatched = condense( setMatched ); 1409 | } 1410 | 1411 | // Add matches to results 1412 | push.apply( results, setMatched ); 1413 | 1414 | // Seedless set matches succeeding multiple successful matchers stipulate sorting 1415 | if ( outermost && !seed && setMatched.length > 0 && 1416 | ( matchedCount + setMatchers.length ) > 1 ) { 1417 | 1418 | Sizzle.uniqueSort( results ); 1419 | } 1420 | } 1421 | 1422 | // Override manipulation of globals by nested matchers 1423 | if ( outermost ) { 1424 | dirruns = dirrunsUnique; 1425 | outermostContext = contextBackup; 1426 | } 1427 | 1428 | return unmatched; 1429 | }; 1430 | 1431 | superMatcher.el = 0; 1432 | return bySet ? 1433 | markFunction( superMatcher ) : 1434 | superMatcher; 1435 | } 1436 | 1437 | compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { 1438 | var i, 1439 | setMatchers = [], 1440 | elementMatchers = [], 1441 | cached = compilerCache[ expando ][ selector + " " ]; 1442 | 1443 | if ( !cached ) { 1444 | // Generate a function of recursive functions that can be used to check each element 1445 | if ( !group ) { 1446 | group = tokenize( selector ); 1447 | } 1448 | i = group.length; 1449 | while ( i-- ) { 1450 | cached = matcherFromTokens( group[i] ); 1451 | if ( cached[ expando ] ) { 1452 | setMatchers.push( cached ); 1453 | } else { 1454 | elementMatchers.push( cached ); 1455 | } 1456 | } 1457 | 1458 | // Cache the compiled function 1459 | cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 1460 | } 1461 | return cached; 1462 | }; 1463 | 1464 | function multipleContexts( selector, contexts, results ) { 1465 | var i = 0, 1466 | len = contexts.length; 1467 | for ( ; i < len; i++ ) { 1468 | Sizzle( selector, contexts[i], results ); 1469 | } 1470 | return results; 1471 | } 1472 | 1473 | function select( selector, context, results, seed, xml ) { 1474 | var i, tokens, token, type, find, 1475 | match = tokenize( selector ); 1476 | 1477 | if ( !seed ) { 1478 | // Try to minimize operations if there is only one group 1479 | if ( match.length === 1 ) { 1480 | 1481 | // Take a shortcut and set the context if the root selector is an ID 1482 | tokens = match[0] = match[0].slice( 0 ); 1483 | if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && 1484 | context.nodeType === 9 && !xml && 1485 | Expr.relative[ tokens[1].type ] ) { 1486 | 1487 | context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; 1488 | if ( !context ) { 1489 | return results; 1490 | } 1491 | 1492 | selector = selector.slice( tokens.shift().length ); 1493 | } 1494 | 1495 | // Fetch a seed set for right-to-left matching 1496 | for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { 1497 | token = tokens[i]; 1498 | 1499 | // Abort if we hit a combinator 1500 | if ( Expr.relative[ (type = token.type) ] ) { 1501 | break; 1502 | } 1503 | if ( (find = Expr.find[ type ]) ) { 1504 | // Search, expanding context for leading sibling combinators 1505 | if ( (seed = find( 1506 | token.matches[0].replace( rbackslash, "" ), 1507 | rsibling.test( tokens[0].type ) && context.parentNode || context, 1508 | xml 1509 | )) ) { 1510 | 1511 | // If seed is empty or no tokens remain, we can return early 1512 | tokens.splice( i, 1 ); 1513 | selector = seed.length && tokens.join(""); 1514 | if ( !selector ) { 1515 | push.apply( results, slice.call( seed, 0 ) ); 1516 | return results; 1517 | } 1518 | 1519 | break; 1520 | } 1521 | } 1522 | } 1523 | } 1524 | } 1525 | 1526 | // Compile and execute a filtering function 1527 | // Provide `match` to avoid retokenization if we modified the selector above 1528 | compile( selector, match )( 1529 | seed, 1530 | context, 1531 | xml, 1532 | results, 1533 | rsibling.test( selector ) 1534 | ); 1535 | return results; 1536 | } 1537 | 1538 | if ( document.querySelectorAll ) { 1539 | (function() { 1540 | var disconnectedMatch, 1541 | oldSelect = select, 1542 | rescape = /'|\\/g, 1543 | rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, 1544 | 1545 | // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA 1546 | // A support test would require too much code (would include document ready) 1547 | rbuggyQSA = [ ":focus" ], 1548 | 1549 | // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 1550 | // A support test would require too much code (would include document ready) 1551 | // just skip matchesSelector for :active 1552 | rbuggyMatches = [ ":active" ], 1553 | matches = docElem.matchesSelector || 1554 | docElem.mozMatchesSelector || 1555 | docElem.webkitMatchesSelector || 1556 | docElem.oMatchesSelector || 1557 | docElem.msMatchesSelector; 1558 | 1559 | // Build QSA regex 1560 | // Regex strategy adopted from Diego Perini 1561 | assert(function( div ) { 1562 | // Select is set to empty string on purpose 1563 | // This is to test IE's treatment of not explictly 1564 | // setting a boolean content attribute, 1565 | // since its presence should be enough 1566 | // http://bugs.jquery.com/ticket/12359 1567 | div.innerHTML = ""; 1568 | 1569 | // IE8 - Some boolean attributes are not treated correctly 1570 | if ( !div.querySelectorAll("[selected]").length ) { 1571 | rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); 1572 | } 1573 | 1574 | // Webkit/Opera - :checked should return selected option elements 1575 | // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1576 | // IE8 throws error here (do not put tests after this one) 1577 | if ( !div.querySelectorAll(":checked").length ) { 1578 | rbuggyQSA.push(":checked"); 1579 | } 1580 | }); 1581 | 1582 | assert(function( div ) { 1583 | 1584 | // Opera 10-12/IE9 - ^= $= *= and empty values 1585 | // Should not select anything 1586 | div.innerHTML = "

"; 1587 | if ( div.querySelectorAll("[test^='']").length ) { 1588 | rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); 1589 | } 1590 | 1591 | // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 1592 | // IE8 throws error here (do not put tests after this one) 1593 | div.innerHTML = ""; 1594 | if ( !div.querySelectorAll(":enabled").length ) { 1595 | rbuggyQSA.push(":enabled", ":disabled"); 1596 | } 1597 | }); 1598 | 1599 | // rbuggyQSA always contains :focus, so no need for a length check 1600 | rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); 1601 | 1602 | select = function( selector, context, results, seed, xml ) { 1603 | // Only use querySelectorAll when not filtering, 1604 | // when this is not xml, 1605 | // and when no QSA bugs apply 1606 | if ( !seed && !xml && !rbuggyQSA.test( selector ) ) { 1607 | var groups, i, 1608 | old = true, 1609 | nid = expando, 1610 | newContext = context, 1611 | newSelector = context.nodeType === 9 && selector; 1612 | 1613 | // qSA works strangely on Element-rooted queries 1614 | // We can work around this by specifying an extra ID on the root 1615 | // and working up from there (Thanks to Andrew Dupont for the technique) 1616 | // IE 8 doesn't work on object elements 1617 | if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { 1618 | groups = tokenize( selector ); 1619 | 1620 | if ( (old = context.getAttribute("id")) ) { 1621 | nid = old.replace( rescape, "\\$&" ); 1622 | } else { 1623 | context.setAttribute( "id", nid ); 1624 | } 1625 | nid = "[id='" + nid + "'] "; 1626 | 1627 | i = groups.length; 1628 | while ( i-- ) { 1629 | groups[i] = nid + groups[i].join(""); 1630 | } 1631 | newContext = rsibling.test( selector ) && context.parentNode || context; 1632 | newSelector = groups.join(","); 1633 | } 1634 | 1635 | if ( newSelector ) { 1636 | try { 1637 | push.apply( results, slice.call( newContext.querySelectorAll( 1638 | newSelector 1639 | ), 0 ) ); 1640 | return results; 1641 | } catch(qsaError) { 1642 | } finally { 1643 | if ( !old ) { 1644 | context.removeAttribute("id"); 1645 | } 1646 | } 1647 | } 1648 | } 1649 | 1650 | return oldSelect( selector, context, results, seed, xml ); 1651 | }; 1652 | 1653 | if ( matches ) { 1654 | assert(function( div ) { 1655 | // Check to see if it's possible to do matchesSelector 1656 | // on a disconnected node (IE 9) 1657 | disconnectedMatch = matches.call( div, "div" ); 1658 | 1659 | // This should fail with an exception 1660 | // Gecko does not error, returns false instead 1661 | try { 1662 | matches.call( div, "[test!='']:sizzle" ); 1663 | rbuggyMatches.push( "!=", pseudos ); 1664 | } catch ( e ) {} 1665 | }); 1666 | 1667 | // rbuggyMatches always contains :active and :focus, so no need for a length check 1668 | rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); 1669 | 1670 | Sizzle.matchesSelector = function( elem, expr ) { 1671 | // Make sure that attribute selectors are quoted 1672 | expr = expr.replace( rattributeQuotes, "='$1']" ); 1673 | 1674 | // rbuggyMatches always contains :active, so no need for an existence check 1675 | if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) { 1676 | try { 1677 | var ret = matches.call( elem, expr ); 1678 | 1679 | // IE 9's matchesSelector returns false on disconnected nodes 1680 | if ( ret || disconnectedMatch || 1681 | // As well, disconnected nodes are said to be in a document 1682 | // fragment in IE 9 1683 | elem.document && elem.document.nodeType !== 11 ) { 1684 | return ret; 1685 | } 1686 | } catch(e) {} 1687 | } 1688 | 1689 | return Sizzle( expr, null, null, [ elem ] ).length > 0; 1690 | }; 1691 | } 1692 | })(); 1693 | } 1694 | 1695 | // Deprecated 1696 | Expr.pseudos["nth"] = Expr.pseudos["eq"]; 1697 | 1698 | // Back-compat 1699 | function setFilters() {} 1700 | Expr.filters = setFilters.prototype = Expr.pseudos; 1701 | Expr.setFilters = new setFilters(); 1702 | 1703 | // EXPOSE 1704 | if ( typeof define === "function" && define.amd ) { 1705 | define(function() { return Sizzle; }); 1706 | } else { 1707 | window.Sizzle = Sizzle; 1708 | } 1709 | // EXPOSE 1710 | 1711 | })( window ); 1712 | -------------------------------------------------------------------------------- /reference/youmightnotneedjquery.md: -------------------------------------------------------------------------------- 1 | http://youmightnotneedjquery.com/ 2 | -------------------------------------------------------------------------------- /reference/zepto.js: -------------------------------------------------------------------------------- 1 | /* Zepto v1.0-1-ga3cab6c - polyfill zepto detect event ajax form fx - zeptojs.com/license */ 2 | 3 | 4 | ;(function(undefined){ 5 | if (String.prototype.trim === undefined) // fix for iOS 3.2 6 | String.prototype.trim = function(){ return this.replace(/^\s+|\s+$/g, '') } 7 | 8 | // For iOS 3.x 9 | // from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce 10 | if (Array.prototype.reduce === undefined) 11 | Array.prototype.reduce = function(fun){ 12 | if(this === void 0 || this === null) throw new TypeError() 13 | var t = Object(this), len = t.length >>> 0, k = 0, accumulator 14 | if(typeof fun != 'function') throw new TypeError() 15 | if(len == 0 && arguments.length == 1) throw new TypeError() 16 | 17 | if(arguments.length >= 2) 18 | accumulator = arguments[1] 19 | else 20 | do{ 21 | if(k in t){ 22 | accumulator = t[k++] 23 | break 24 | } 25 | if(++k >= len) throw new TypeError() 26 | } while (true) 27 | 28 | while (k < len){ 29 | if(k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t) 30 | k++ 31 | } 32 | return accumulator 33 | } 34 | 35 | })() 36 | 37 | var Zepto = (function() { 38 | var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice, filter = emptyArray.filter, 39 | document = window.document, 40 | elementDisplay = {}, classCache = {}, 41 | getComputedStyle = document.defaultView.getComputedStyle, 42 | cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 }, 43 | fragmentRE = /^\s*<(\w+|!)[^>]*>/, 44 | tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 45 | rootNodeRE = /^(?:body|html)$/i, 46 | 47 | // special attributes that should be get/set via method calls 48 | methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'], 49 | 50 | adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ], 51 | table = document.createElement('table'), 52 | tableRow = document.createElement('tr'), 53 | containers = { 54 | 'tr': document.createElement('tbody'), 55 | 'tbody': table, 'thead': table, 'tfoot': table, 56 | 'td': tableRow, 'th': tableRow, 57 | '*': document.createElement('div') 58 | }, 59 | readyRE = /complete|loaded|interactive/, 60 | classSelectorRE = /^\.([\w-]+)$/, 61 | idSelectorRE = /^#([\w-]*)$/, 62 | tagSelectorRE = /^[\w-]+$/, 63 | class2type = {}, 64 | toString = class2type.toString, 65 | zepto = {}, 66 | camelize, uniq, 67 | tempParent = document.createElement('div') 68 | 69 | zepto.matches = function(element, selector) { 70 | if (!element || element.nodeType !== 1) return false 71 | var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector || 72 | element.oMatchesSelector || element.matchesSelector 73 | if (matchesSelector) return matchesSelector.call(element, selector) 74 | // fall back to performing a selector: 75 | var match, parent = element.parentNode, temp = !parent 76 | if (temp) (parent = tempParent).appendChild(element) 77 | match = ~zepto.qsa(parent, selector).indexOf(element) 78 | temp && tempParent.removeChild(element) 79 | return match 80 | } 81 | 82 | function type(obj) { 83 | return obj == null ? String(obj) : 84 | class2type[toString.call(obj)] || "object" 85 | } 86 | 87 | function isFunction(value) { return type(value) == "function" } 88 | function isWindow(obj) { return obj != null && obj == obj.window } 89 | function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } 90 | function isObject(obj) { return type(obj) == "object" } 91 | function isPlainObject(obj) { 92 | return isObject(obj) && !isWindow(obj) && obj.__proto__ == Object.prototype 93 | } 94 | function isArray(value) { return value instanceof Array } 95 | function likeArray(obj) { return typeof obj.length == 'number' } 96 | 97 | function compact(array) { return filter.call(array, function(item){ return item != null }) } 98 | function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array } 99 | camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } 100 | function dasherize(str) { 101 | return str.replace(/::/g, '/') 102 | .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') 103 | .replace(/([a-z\d])([A-Z])/g, '$1_$2') 104 | .replace(/_/g, '-') 105 | .toLowerCase() 106 | } 107 | uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) } 108 | 109 | function classRE(name) { 110 | return name in classCache ? 111 | classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')) 112 | } 113 | 114 | function maybeAddPx(name, value) { 115 | return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value 116 | } 117 | 118 | function defaultDisplay(nodeName) { 119 | var element, display 120 | if (!elementDisplay[nodeName]) { 121 | element = document.createElement(nodeName) 122 | document.body.appendChild(element) 123 | display = getComputedStyle(element, '').getPropertyValue("display") 124 | element.parentNode.removeChild(element) 125 | display == "none" && (display = "block") 126 | elementDisplay[nodeName] = display 127 | } 128 | return elementDisplay[nodeName] 129 | } 130 | 131 | function children(element) { 132 | return 'children' in element ? 133 | slice.call(element.children) : 134 | $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node }) 135 | } 136 | 137 | // `$.zepto.fragment` takes a html string and an optional tag name 138 | // to generate DOM nodes nodes from the given html string. 139 | // The generated DOM nodes are returned as an array. 140 | // This function can be overriden in plugins for example to make 141 | // it compatible with browsers that don't support the DOM fully. 142 | zepto.fragment = function(html, name, properties) { 143 | if (html.replace) html = html.replace(tagExpanderRE, "<$1>") 144 | if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 145 | if (!(name in containers)) name = '*' 146 | 147 | var nodes, dom, container = containers[name] 148 | container.innerHTML = '' + html 149 | dom = $.each(slice.call(container.childNodes), function(){ 150 | container.removeChild(this) 151 | }) 152 | if (isPlainObject(properties)) { 153 | nodes = $(dom) 154 | $.each(properties, function(key, value) { 155 | if (methodAttributes.indexOf(key) > -1) nodes[key](value) 156 | else nodes.attr(key, value) 157 | }) 158 | } 159 | return dom 160 | } 161 | 162 | // `$.zepto.Z` swaps out the prototype of the given `dom` array 163 | // of nodes with `$.fn` and thus supplying all the Zepto functions 164 | // to the array. Note that `__proto__` is not supported on Internet 165 | // Explorer. This method can be overriden in plugins. 166 | zepto.Z = function(dom, selector) { 167 | dom = dom || [] 168 | dom.__proto__ = $.fn 169 | dom.selector = selector || '' 170 | return dom 171 | } 172 | 173 | // `$.zepto.isZ` should return `true` if the given object is a Zepto 174 | // collection. This method can be overriden in plugins. 175 | zepto.isZ = function(object) { 176 | return object instanceof zepto.Z 177 | } 178 | 179 | // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and 180 | // takes a CSS selector and an optional context (and handles various 181 | // special cases). 182 | // This method can be overriden in plugins. 183 | zepto.init = function(selector, context) { 184 | // If nothing given, return an empty Zepto collection 185 | if (!selector) return zepto.Z() 186 | // If a function is given, call it when the DOM is ready 187 | else if (isFunction(selector)) return $(document).ready(selector) 188 | // If a Zepto collection is given, juts return it 189 | else if (zepto.isZ(selector)) return selector 190 | else { 191 | var dom 192 | // normalize array if an array of nodes is given 193 | if (isArray(selector)) dom = compact(selector) 194 | // Wrap DOM nodes. If a plain object is given, duplicate it. 195 | else if (isObject(selector)) 196 | dom = [isPlainObject(selector) ? $.extend({}, selector) : selector], selector = null 197 | // If it's a html fragment, create nodes from it 198 | else if (fragmentRE.test(selector)) 199 | dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null 200 | // If there's a context, create a collection on that context first, and select 201 | // nodes from there 202 | else if (context !== undefined) return $(context).find(selector) 203 | // And last but no least, if it's a CSS selector, use it to select nodes. 204 | else dom = zepto.qsa(document, selector) 205 | // create a new Zepto collection from the nodes found 206 | return zepto.Z(dom, selector) 207 | } 208 | } 209 | 210 | // `$` will be the base `Zepto` object. When calling this 211 | // function just call `$.zepto.init, which makes the implementation 212 | // details of selecting nodes and creating Zepto collections 213 | // patchable in plugins. 214 | $ = function(selector, context){ 215 | return zepto.init(selector, context) 216 | } 217 | 218 | function extend(target, source, deep) { 219 | for (key in source) 220 | if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { 221 | if (isPlainObject(source[key]) && !isPlainObject(target[key])) 222 | target[key] = {} 223 | if (isArray(source[key]) && !isArray(target[key])) 224 | target[key] = [] 225 | extend(target[key], source[key], deep) 226 | } 227 | else if (source[key] !== undefined) target[key] = source[key] 228 | } 229 | 230 | // Copy all but undefined properties from one or more 231 | // objects to the `target` object. 232 | $.extend = function(target){ 233 | var deep, args = slice.call(arguments, 1) 234 | if (typeof target == 'boolean') { 235 | deep = target 236 | target = args.shift() 237 | } 238 | args.forEach(function(arg){ extend(target, arg, deep) }) 239 | return target 240 | } 241 | 242 | // `$.zepto.qsa` is Zepto's CSS selector implementation which 243 | // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`. 244 | // This method can be overriden in plugins. 245 | zepto.qsa = function(element, selector){ 246 | var found 247 | return (isDocument(element) && idSelectorRE.test(selector)) ? 248 | ( (found = element.getElementById(RegExp.$1)) ? [found] : [] ) : 249 | (element.nodeType !== 1 && element.nodeType !== 9) ? [] : 250 | slice.call( 251 | classSelectorRE.test(selector) ? element.getElementsByClassName(RegExp.$1) : 252 | tagSelectorRE.test(selector) ? element.getElementsByTagName(selector) : 253 | element.querySelectorAll(selector) 254 | ) 255 | } 256 | 257 | function filtered(nodes, selector) { 258 | return selector === undefined ? $(nodes) : $(nodes).filter(selector) 259 | } 260 | 261 | $.contains = function(parent, node) { 262 | return parent !== node && parent.contains(node) 263 | } 264 | 265 | function funcArg(context, arg, idx, payload) { 266 | return isFunction(arg) ? arg.call(context, idx, payload) : arg 267 | } 268 | 269 | function setAttribute(node, name, value) { 270 | value == null ? node.removeAttribute(name) : node.setAttribute(name, value) 271 | } 272 | 273 | // access className property while respecting SVGAnimatedString 274 | function className(node, value){ 275 | var klass = node.className, 276 | svg = klass && klass.baseVal !== undefined 277 | 278 | if (value === undefined) return svg ? klass.baseVal : klass 279 | svg ? (klass.baseVal = value) : (node.className = value) 280 | } 281 | 282 | // "true" => true 283 | // "false" => false 284 | // "null" => null 285 | // "42" => 42 286 | // "42.5" => 42.5 287 | // JSON => parse if valid 288 | // String => self 289 | function deserializeValue(value) { 290 | var num 291 | try { 292 | return value ? 293 | value == "true" || 294 | ( value == "false" ? false : 295 | value == "null" ? null : 296 | !isNaN(num = Number(value)) ? num : 297 | /^[\[\{]/.test(value) ? $.parseJSON(value) : 298 | value ) 299 | : value 300 | } catch(e) { 301 | return value 302 | } 303 | } 304 | 305 | $.type = type 306 | $.isFunction = isFunction 307 | $.isWindow = isWindow 308 | $.isArray = isArray 309 | $.isPlainObject = isPlainObject 310 | 311 | $.isEmptyObject = function(obj) { 312 | var name 313 | for (name in obj) return false 314 | return true 315 | } 316 | 317 | $.inArray = function(elem, array, i){ 318 | return emptyArray.indexOf.call(array, elem, i) 319 | } 320 | 321 | $.camelCase = camelize 322 | $.trim = function(str) { return str.trim() } 323 | 324 | // plugin compatibility 325 | $.uuid = 0 326 | $.support = { } 327 | $.expr = { } 328 | 329 | $.map = function(elements, callback){ 330 | var value, values = [], i, key 331 | if (likeArray(elements)) 332 | for (i = 0; i < elements.length; i++) { 333 | value = callback(elements[i], i) 334 | if (value != null) values.push(value) 335 | } 336 | else 337 | for (key in elements) { 338 | value = callback(elements[key], key) 339 | if (value != null) values.push(value) 340 | } 341 | return flatten(values) 342 | } 343 | 344 | $.each = function(elements, callback){ 345 | var i, key 346 | if (likeArray(elements)) { 347 | for (i = 0; i < elements.length; i++) 348 | if (callback.call(elements[i], i, elements[i]) === false) return elements 349 | } else { 350 | for (key in elements) 351 | if (callback.call(elements[key], key, elements[key]) === false) return elements 352 | } 353 | 354 | return elements 355 | } 356 | 357 | $.grep = function(elements, callback){ 358 | return filter.call(elements, callback) 359 | } 360 | 361 | if (window.JSON) $.parseJSON = JSON.parse 362 | 363 | // Populate the class2type map 364 | $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { 365 | class2type[ "[object " + name + "]" ] = name.toLowerCase() 366 | }) 367 | 368 | // Define methods that will be available on all 369 | // Zepto collections 370 | $.fn = { 371 | // Because a collection acts like an array 372 | // copy over these useful array functions. 373 | forEach: emptyArray.forEach, 374 | reduce: emptyArray.reduce, 375 | push: emptyArray.push, 376 | sort: emptyArray.sort, 377 | indexOf: emptyArray.indexOf, 378 | concat: emptyArray.concat, 379 | 380 | // `map` and `slice` in the jQuery API work differently 381 | // from their array counterparts 382 | map: function(fn){ 383 | return $($.map(this, function(el, i){ return fn.call(el, i, el) })) 384 | }, 385 | slice: function(){ 386 | return $(slice.apply(this, arguments)) 387 | }, 388 | 389 | ready: function(callback){ 390 | if (readyRE.test(document.readyState)) callback($) 391 | else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false) 392 | return this 393 | }, 394 | get: function(idx){ 395 | return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] 396 | }, 397 | toArray: function(){ return this.get() }, 398 | size: function(){ 399 | return this.length 400 | }, 401 | remove: function(){ 402 | return this.each(function(){ 403 | if (this.parentNode != null) 404 | this.parentNode.removeChild(this) 405 | }) 406 | }, 407 | each: function(callback){ 408 | emptyArray.every.call(this, function(el, idx){ 409 | return callback.call(el, idx, el) !== false 410 | }) 411 | return this 412 | }, 413 | filter: function(selector){ 414 | if (isFunction(selector)) return this.not(this.not(selector)) 415 | return $(filter.call(this, function(element){ 416 | return zepto.matches(element, selector) 417 | })) 418 | }, 419 | add: function(selector,context){ 420 | return $(uniq(this.concat($(selector,context)))) 421 | }, 422 | is: function(selector){ 423 | return this.length > 0 && zepto.matches(this[0], selector) 424 | }, 425 | not: function(selector){ 426 | var nodes=[] 427 | if (isFunction(selector) && selector.call !== undefined) 428 | this.each(function(idx){ 429 | if (!selector.call(this,idx)) nodes.push(this) 430 | }) 431 | else { 432 | var excludes = typeof selector == 'string' ? this.filter(selector) : 433 | (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector) 434 | this.forEach(function(el){ 435 | if (excludes.indexOf(el) < 0) nodes.push(el) 436 | }) 437 | } 438 | return $(nodes) 439 | }, 440 | has: function(selector){ 441 | return this.filter(function(){ 442 | return isObject(selector) ? 443 | $.contains(this, selector) : 444 | $(this).find(selector).size() 445 | }) 446 | }, 447 | eq: function(idx){ 448 | return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1) 449 | }, 450 | first: function(){ 451 | var el = this[0] 452 | return el && !isObject(el) ? el : $(el) 453 | }, 454 | last: function(){ 455 | var el = this[this.length - 1] 456 | return el && !isObject(el) ? el : $(el) 457 | }, 458 | find: function(selector){ 459 | var result, $this = this 460 | if (typeof selector == 'object') 461 | result = $(selector).filter(function(){ 462 | var node = this 463 | return emptyArray.some.call($this, function(parent){ 464 | return $.contains(parent, node) 465 | }) 466 | }) 467 | else if (this.length == 1) result = $(zepto.qsa(this[0], selector)) 468 | else result = this.map(function(){ return zepto.qsa(this, selector) }) 469 | return result 470 | }, 471 | closest: function(selector, context){ 472 | var node = this[0], collection = false 473 | if (typeof selector == 'object') collection = $(selector) 474 | while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector))) 475 | node = node !== context && !isDocument(node) && node.parentNode 476 | return $(node) 477 | }, 478 | parents: function(selector){ 479 | var ancestors = [], nodes = this 480 | while (nodes.length > 0) 481 | nodes = $.map(nodes, function(node){ 482 | if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) { 483 | ancestors.push(node) 484 | return node 485 | } 486 | }) 487 | return filtered(ancestors, selector) 488 | }, 489 | parent: function(selector){ 490 | return filtered(uniq(this.pluck('parentNode')), selector) 491 | }, 492 | children: function(selector){ 493 | return filtered(this.map(function(){ return children(this) }), selector) 494 | }, 495 | contents: function() { 496 | return this.map(function() { return slice.call(this.childNodes) }) 497 | }, 498 | siblings: function(selector){ 499 | return filtered(this.map(function(i, el){ 500 | return filter.call(children(el.parentNode), function(child){ return child!==el }) 501 | }), selector) 502 | }, 503 | empty: function(){ 504 | return this.each(function(){ this.innerHTML = '' }) 505 | }, 506 | // `pluck` is borrowed from Prototype.js 507 | pluck: function(property){ 508 | return $.map(this, function(el){ return el[property] }) 509 | }, 510 | show: function(){ 511 | return this.each(function(){ 512 | this.style.display == "none" && (this.style.display = null) 513 | if (getComputedStyle(this, '').getPropertyValue("display") == "none") 514 | this.style.display = defaultDisplay(this.nodeName) 515 | }) 516 | }, 517 | replaceWith: function(newContent){ 518 | return this.before(newContent).remove() 519 | }, 520 | wrap: function(structure){ 521 | var func = isFunction(structure) 522 | if (this[0] && !func) 523 | var dom = $(structure).get(0), 524 | clone = dom.parentNode || this.length > 1 525 | 526 | return this.each(function(index){ 527 | $(this).wrapAll( 528 | func ? structure.call(this, index) : 529 | clone ? dom.cloneNode(true) : dom 530 | ) 531 | }) 532 | }, 533 | wrapAll: function(structure){ 534 | if (this[0]) { 535 | $(this[0]).before(structure = $(structure)) 536 | var children 537 | // drill down to the inmost element 538 | while ((children = structure.children()).length) structure = children.first() 539 | $(structure).append(this) 540 | } 541 | return this 542 | }, 543 | wrapInner: function(structure){ 544 | var func = isFunction(structure) 545 | return this.each(function(index){ 546 | var self = $(this), contents = self.contents(), 547 | dom = func ? structure.call(this, index) : structure 548 | contents.length ? contents.wrapAll(dom) : self.append(dom) 549 | }) 550 | }, 551 | unwrap: function(){ 552 | this.parent().each(function(){ 553 | $(this).replaceWith($(this).children()) 554 | }) 555 | return this 556 | }, 557 | clone: function(){ 558 | return this.map(function(){ return this.cloneNode(true) }) 559 | }, 560 | hide: function(){ 561 | return this.css("display", "none") 562 | }, 563 | toggle: function(setting){ 564 | return this.each(function(){ 565 | var el = $(this) 566 | ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide() 567 | }) 568 | }, 569 | prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') }, 570 | next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') }, 571 | html: function(html){ 572 | return html === undefined ? 573 | (this.length > 0 ? this[0].innerHTML : null) : 574 | this.each(function(idx){ 575 | var originHtml = this.innerHTML 576 | $(this).empty().append( funcArg(this, html, idx, originHtml) ) 577 | }) 578 | }, 579 | text: function(text){ 580 | return text === undefined ? 581 | (this.length > 0 ? this[0].textContent : null) : 582 | this.each(function(){ this.textContent = text }) 583 | }, 584 | attr: function(name, value){ 585 | var result 586 | return (typeof name == 'string' && value === undefined) ? 587 | (this.length == 0 || this[0].nodeType !== 1 ? undefined : 588 | (name == 'value' && this[0].nodeName == 'INPUT') ? this.val() : 589 | (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result 590 | ) : 591 | this.each(function(idx){ 592 | if (this.nodeType !== 1) return 593 | if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) 594 | else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) 595 | }) 596 | }, 597 | removeAttr: function(name){ 598 | return this.each(function(){ this.nodeType === 1 && setAttribute(this, name) }) 599 | }, 600 | prop: function(name, value){ 601 | return (value === undefined) ? 602 | (this[0] && this[0][name]) : 603 | this.each(function(idx){ 604 | this[name] = funcArg(this, value, idx, this[name]) 605 | }) 606 | }, 607 | data: function(name, value){ 608 | var data = this.attr('data-' + dasherize(name), value) 609 | return data !== null ? deserializeValue(data) : undefined 610 | }, 611 | val: function(value){ 612 | return (value === undefined) ? 613 | (this[0] && (this[0].multiple ? 614 | $(this[0]).find('option').filter(function(o){ return this.selected }).pluck('value') : 615 | this[0].value) 616 | ) : 617 | this.each(function(idx){ 618 | this.value = funcArg(this, value, idx, this.value) 619 | }) 620 | }, 621 | offset: function(coordinates){ 622 | if (coordinates) return this.each(function(index){ 623 | var $this = $(this), 624 | coords = funcArg(this, coordinates, index, $this.offset()), 625 | parentOffset = $this.offsetParent().offset(), 626 | props = { 627 | top: coords.top - parentOffset.top, 628 | left: coords.left - parentOffset.left 629 | } 630 | 631 | if ($this.css('position') == 'static') props['position'] = 'relative' 632 | $this.css(props) 633 | }) 634 | if (this.length==0) return null 635 | var obj = this[0].getBoundingClientRect() 636 | return { 637 | left: obj.left + window.pageXOffset, 638 | top: obj.top + window.pageYOffset, 639 | width: Math.round(obj.width), 640 | height: Math.round(obj.height) 641 | } 642 | }, 643 | css: function(property, value){ 644 | if (arguments.length < 2 && typeof property == 'string') 645 | return this[0] && (this[0].style[camelize(property)] || getComputedStyle(this[0], '').getPropertyValue(property)) 646 | 647 | var css = '' 648 | if (type(property) == 'string') { 649 | if (!value && value !== 0) 650 | this.each(function(){ this.style.removeProperty(dasherize(property)) }) 651 | else 652 | css = dasherize(property) + ":" + maybeAddPx(property, value) 653 | } else { 654 | for (key in property) 655 | if (!property[key] && property[key] !== 0) 656 | this.each(function(){ this.style.removeProperty(dasherize(key)) }) 657 | else 658 | css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' 659 | } 660 | 661 | return this.each(function(){ this.style.cssText += ';' + css }) 662 | }, 663 | index: function(element){ 664 | return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0]) 665 | }, 666 | hasClass: function(name){ 667 | return emptyArray.some.call(this, function(el){ 668 | return this.test(className(el)) 669 | }, classRE(name)) 670 | }, 671 | addClass: function(name){ 672 | return this.each(function(idx){ 673 | classList = [] 674 | var cls = className(this), newName = funcArg(this, name, idx, cls) 675 | newName.split(/\s+/g).forEach(function(klass){ 676 | if (!$(this).hasClass(klass)) classList.push(klass) 677 | }, this) 678 | classList.length && className(this, cls + (cls ? " " : "") + classList.join(" ")) 679 | }) 680 | }, 681 | removeClass: function(name){ 682 | return this.each(function(idx){ 683 | if (name === undefined) return className(this, '') 684 | classList = className(this) 685 | funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){ 686 | classList = classList.replace(classRE(klass), " ") 687 | }) 688 | className(this, classList.trim()) 689 | }) 690 | }, 691 | toggleClass: function(name, when){ 692 | return this.each(function(idx){ 693 | var $this = $(this), names = funcArg(this, name, idx, className(this)) 694 | names.split(/\s+/g).forEach(function(klass){ 695 | (when === undefined ? !$this.hasClass(klass) : when) ? 696 | $this.addClass(klass) : $this.removeClass(klass) 697 | }) 698 | }) 699 | }, 700 | scrollTop: function(){ 701 | if (!this.length) return 702 | return ('scrollTop' in this[0]) ? this[0].scrollTop : this[0].scrollY 703 | }, 704 | position: function() { 705 | if (!this.length) return 706 | 707 | var elem = this[0], 708 | // Get *real* offsetParent 709 | offsetParent = this.offsetParent(), 710 | // Get correct offsets 711 | offset = this.offset(), 712 | parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset() 713 | 714 | // Subtract element margins 715 | // note: when an element has margin: auto the offsetLeft and marginLeft 716 | // are the same in Safari causing offset.left to incorrectly be 0 717 | offset.top -= parseFloat( $(elem).css('margin-top') ) || 0 718 | offset.left -= parseFloat( $(elem).css('margin-left') ) || 0 719 | 720 | // Add offsetParent borders 721 | parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0 722 | parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0 723 | 724 | // Subtract the two offsets 725 | return { 726 | top: offset.top - parentOffset.top, 727 | left: offset.left - parentOffset.left 728 | } 729 | }, 730 | offsetParent: function() { 731 | return this.map(function(){ 732 | var parent = this.offsetParent || document.body 733 | while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static") 734 | parent = parent.offsetParent 735 | return parent 736 | }) 737 | } 738 | } 739 | 740 | // for now 741 | $.fn.detach = $.fn.remove 742 | 743 | // Generate the `width` and `height` functions 744 | ;['width', 'height'].forEach(function(dimension){ 745 | $.fn[dimension] = function(value){ 746 | var offset, el = this[0], 747 | Dimension = dimension.replace(/./, function(m){ return m[0].toUpperCase() }) 748 | if (value === undefined) return isWindow(el) ? el['inner' + Dimension] : 749 | isDocument(el) ? el.documentElement['offset' + Dimension] : 750 | (offset = this.offset()) && offset[dimension] 751 | else return this.each(function(idx){ 752 | el = $(this) 753 | el.css(dimension, funcArg(this, value, idx, el[dimension]())) 754 | }) 755 | } 756 | }) 757 | 758 | function traverseNode(node, fun) { 759 | fun(node) 760 | for (var key in node.childNodes) traverseNode(node.childNodes[key], fun) 761 | } 762 | 763 | // Generate the `after`, `prepend`, `before`, `append`, 764 | // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods. 765 | adjacencyOperators.forEach(function(operator, operatorIndex) { 766 | var inside = operatorIndex % 2 //=> prepend, append 767 | 768 | $.fn[operator] = function(){ 769 | // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings 770 | var argType, nodes = $.map(arguments, function(arg) { 771 | argType = type(arg) 772 | return argType == "object" || argType == "array" || arg == null ? 773 | arg : zepto.fragment(arg) 774 | }), 775 | parent, copyByClone = this.length > 1 776 | if (nodes.length < 1) return this 777 | 778 | return this.each(function(_, target){ 779 | parent = inside ? target : target.parentNode 780 | 781 | // convert all methods to a "before" operation 782 | target = operatorIndex == 0 ? target.nextSibling : 783 | operatorIndex == 1 ? target.firstChild : 784 | operatorIndex == 2 ? target : 785 | null 786 | 787 | nodes.forEach(function(node){ 788 | if (copyByClone) node = node.cloneNode(true) 789 | else if (!parent) return $(node).remove() 790 | 791 | traverseNode(parent.insertBefore(node, target), function(el){ 792 | if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' && 793 | (!el.type || el.type === 'text/javascript') && !el.src) 794 | window['eval'].call(window, el.innerHTML) 795 | }) 796 | }) 797 | }) 798 | } 799 | 800 | // after => insertAfter 801 | // prepend => prependTo 802 | // before => insertBefore 803 | // append => appendTo 804 | $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){ 805 | $(html)[operator](this) 806 | return this 807 | } 808 | }) 809 | 810 | zepto.Z.prototype = $.fn 811 | 812 | // Export internal API functions in the `$.zepto` namespace 813 | zepto.uniq = uniq 814 | zepto.deserializeValue = deserializeValue 815 | $.zepto = zepto 816 | 817 | return $ 818 | })() 819 | 820 | window.Zepto = Zepto 821 | '$' in window || (window.$ = Zepto) 822 | 823 | ;(function($){ 824 | function detect(ua){ 825 | var os = this.os = {}, browser = this.browser = {}, 826 | webkit = ua.match(/WebKit\/([\d.]+)/), 827 | android = ua.match(/(Android)\s+([\d.]+)/), 828 | ipad = ua.match(/(iPad).*OS\s([\d_]+)/), 829 | iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/), 830 | webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/), 831 | touchpad = webos && ua.match(/TouchPad/), 832 | kindle = ua.match(/Kindle\/([\d.]+)/), 833 | silk = ua.match(/Silk\/([\d._]+)/), 834 | blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/), 835 | bb10 = ua.match(/(BB10).*Version\/([\d.]+)/), 836 | rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/), 837 | playbook = ua.match(/PlayBook/), 838 | chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/), 839 | firefox = ua.match(/Firefox\/([\d.]+)/) 840 | 841 | // Todo: clean this up with a better OS/browser seperation: 842 | // - discern (more) between multiple browsers on android 843 | // - decide if kindle fire in silk mode is android or not 844 | // - Firefox on Android doesn't specify the Android version 845 | // - possibly devide in os, device and browser hashes 846 | 847 | if (browser.webkit = !!webkit) browser.version = webkit[1] 848 | 849 | if (android) os.android = true, os.version = android[2] 850 | if (iphone) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.') 851 | if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.') 852 | if (webos) os.webos = true, os.version = webos[2] 853 | if (touchpad) os.touchpad = true 854 | if (blackberry) os.blackberry = true, os.version = blackberry[2] 855 | if (bb10) os.bb10 = true, os.version = bb10[2] 856 | if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2] 857 | if (playbook) browser.playbook = true 858 | if (kindle) os.kindle = true, os.version = kindle[1] 859 | if (silk) browser.silk = true, browser.version = silk[1] 860 | if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true 861 | if (chrome) browser.chrome = true, browser.version = chrome[1] 862 | if (firefox) browser.firefox = true, browser.version = firefox[1] 863 | 864 | os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) || (firefox && ua.match(/Tablet/))) 865 | os.phone = !!(!os.tablet && (android || iphone || webos || blackberry || bb10 || 866 | (chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) || (firefox && ua.match(/Mobile/)))) 867 | } 868 | 869 | detect.call($, navigator.userAgent) 870 | // make available to unit tests 871 | $.__detect = detect 872 | 873 | })(Zepto) 874 | 875 | ;(function($){ 876 | var $$ = $.zepto.qsa, handlers = {}, _zid = 1, specialEvents={}, 877 | hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' } 878 | 879 | specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents' 880 | 881 | function zid(element) { 882 | return element._zid || (element._zid = _zid++) 883 | } 884 | function findHandlers(element, event, fn, selector) { 885 | event = parse(event) 886 | if (event.ns) var matcher = matcherFor(event.ns) 887 | return (handlers[zid(element)] || []).filter(function(handler) { 888 | return handler 889 | && (!event.e || handler.e == event.e) 890 | && (!event.ns || matcher.test(handler.ns)) 891 | && (!fn || zid(handler.fn) === zid(fn)) 892 | && (!selector || handler.sel == selector) 893 | }) 894 | } 895 | function parse(event) { 896 | var parts = ('' + event).split('.') 897 | return {e: parts[0], ns: parts.slice(1).sort().join(' ')} 898 | } 899 | function matcherFor(ns) { 900 | return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)') 901 | } 902 | 903 | function eachEvent(events, fn, iterator){ 904 | if ($.type(events) != "string") $.each(events, iterator) 905 | else events.split(/\s/).forEach(function(type){ iterator(type, fn) }) 906 | } 907 | 908 | function eventCapture(handler, captureSetting) { 909 | return handler.del && 910 | (handler.e == 'focus' || handler.e == 'blur') || 911 | !!captureSetting 912 | } 913 | 914 | function realEvent(type) { 915 | return hover[type] || type 916 | } 917 | 918 | function add(element, events, fn, selector, getDelegate, capture){ 919 | var id = zid(element), set = (handlers[id] || (handlers[id] = [])) 920 | eachEvent(events, fn, function(event, fn){ 921 | var handler = parse(event) 922 | handler.fn = fn 923 | handler.sel = selector 924 | // emulate mouseenter, mouseleave 925 | if (handler.e in hover) fn = function(e){ 926 | var related = e.relatedTarget 927 | if (!related || (related !== this && !$.contains(this, related))) 928 | return handler.fn.apply(this, arguments) 929 | } 930 | handler.del = getDelegate && getDelegate(fn, event) 931 | var callback = handler.del || fn 932 | handler.proxy = function (e) { 933 | var result = callback.apply(element, [e].concat(e.data)) 934 | if (result === false) e.preventDefault(), e.stopPropagation() 935 | return result 936 | } 937 | handler.i = set.length 938 | set.push(handler) 939 | element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 940 | }) 941 | } 942 | function remove(element, events, fn, selector, capture){ 943 | var id = zid(element) 944 | eachEvent(events || '', fn, function(event, fn){ 945 | findHandlers(element, event, fn, selector).forEach(function(handler){ 946 | delete handlers[id][handler.i] 947 | element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 948 | }) 949 | }) 950 | } 951 | 952 | $.event = { add: add, remove: remove } 953 | 954 | $.proxy = function(fn, context) { 955 | if ($.isFunction(fn)) { 956 | var proxyFn = function(){ return fn.apply(context, arguments) } 957 | proxyFn._zid = zid(fn) 958 | return proxyFn 959 | } else if (typeof context == 'string') { 960 | return $.proxy(fn[context], fn) 961 | } else { 962 | throw new TypeError("expected function") 963 | } 964 | } 965 | 966 | $.fn.bind = function(event, callback){ 967 | return this.each(function(){ 968 | add(this, event, callback) 969 | }) 970 | } 971 | $.fn.unbind = function(event, callback){ 972 | return this.each(function(){ 973 | remove(this, event, callback) 974 | }) 975 | } 976 | $.fn.one = function(event, callback){ 977 | return this.each(function(i, element){ 978 | add(this, event, callback, null, function(fn, type){ 979 | return function(){ 980 | var result = fn.apply(element, arguments) 981 | remove(element, type, fn) 982 | return result 983 | } 984 | }) 985 | }) 986 | } 987 | 988 | var returnTrue = function(){return true}, 989 | returnFalse = function(){return false}, 990 | ignoreProperties = /^([A-Z]|layer[XY]$)/, 991 | eventMethods = { 992 | preventDefault: 'isDefaultPrevented', 993 | stopImmediatePropagation: 'isImmediatePropagationStopped', 994 | stopPropagation: 'isPropagationStopped' 995 | } 996 | function createProxy(event) { 997 | var key, proxy = { originalEvent: event } 998 | for (key in event) 999 | if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key] 1000 | 1001 | $.each(eventMethods, function(name, predicate) { 1002 | proxy[name] = function(){ 1003 | this[predicate] = returnTrue 1004 | return event[name].apply(event, arguments) 1005 | } 1006 | proxy[predicate] = returnFalse 1007 | }) 1008 | return proxy 1009 | } 1010 | 1011 | // emulates the 'defaultPrevented' property for browsers that have none 1012 | function fix(event) { 1013 | if (!('defaultPrevented' in event)) { 1014 | event.defaultPrevented = false 1015 | var prevent = event.preventDefault 1016 | event.preventDefault = function() { 1017 | this.defaultPrevented = true 1018 | prevent.call(this) 1019 | } 1020 | } 1021 | } 1022 | 1023 | $.fn.delegate = function(selector, event, callback){ 1024 | return this.each(function(i, element){ 1025 | add(element, event, callback, selector, function(fn){ 1026 | return function(e){ 1027 | var evt, match = $(e.target).closest(selector, element).get(0) 1028 | if (match) { 1029 | evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element}) 1030 | return fn.apply(match, [evt].concat([].slice.call(arguments, 1))) 1031 | } 1032 | } 1033 | }) 1034 | }) 1035 | } 1036 | $.fn.undelegate = function(selector, event, callback){ 1037 | return this.each(function(){ 1038 | remove(this, event, callback, selector) 1039 | }) 1040 | } 1041 | 1042 | $.fn.live = function(event, callback){ 1043 | $(document.body).delegate(this.selector, event, callback) 1044 | return this 1045 | } 1046 | $.fn.die = function(event, callback){ 1047 | $(document.body).undelegate(this.selector, event, callback) 1048 | return this 1049 | } 1050 | 1051 | $.fn.on = function(event, selector, callback){ 1052 | return !selector || $.isFunction(selector) ? 1053 | this.bind(event, selector || callback) : this.delegate(selector, event, callback) 1054 | } 1055 | $.fn.off = function(event, selector, callback){ 1056 | return !selector || $.isFunction(selector) ? 1057 | this.unbind(event, selector || callback) : this.undelegate(selector, event, callback) 1058 | } 1059 | 1060 | $.fn.trigger = function(event, data){ 1061 | if (typeof event == 'string' || $.isPlainObject(event)) event = $.Event(event) 1062 | fix(event) 1063 | event.data = data 1064 | return this.each(function(){ 1065 | // items in the collection might not be DOM elements 1066 | // (todo: possibly support events on plain old objects) 1067 | if('dispatchEvent' in this) this.dispatchEvent(event) 1068 | }) 1069 | } 1070 | 1071 | // triggers event handlers on current element just as if an event occurred, 1072 | // doesn't trigger an actual event, doesn't bubble 1073 | $.fn.triggerHandler = function(event, data){ 1074 | var e, result 1075 | this.each(function(i, element){ 1076 | e = createProxy(typeof event == 'string' ? $.Event(event) : event) 1077 | e.data = data 1078 | e.target = element 1079 | $.each(findHandlers(element, event.type || event), function(i, handler){ 1080 | result = handler.proxy(e) 1081 | if (e.isImmediatePropagationStopped()) return false 1082 | }) 1083 | }) 1084 | return result 1085 | } 1086 | 1087 | // shortcut methods for `.bind(event, fn)` for each event type 1088 | ;('focusin focusout load resize scroll unload click dblclick '+ 1089 | 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+ 1090 | 'change select keydown keypress keyup error').split(' ').forEach(function(event) { 1091 | $.fn[event] = function(callback) { 1092 | return callback ? 1093 | this.bind(event, callback) : 1094 | this.trigger(event) 1095 | } 1096 | }) 1097 | 1098 | ;['focus', 'blur'].forEach(function(name) { 1099 | $.fn[name] = function(callback) { 1100 | if (callback) this.bind(name, callback) 1101 | else this.each(function(){ 1102 | try { this[name]() } 1103 | catch(e) {} 1104 | }) 1105 | return this 1106 | } 1107 | }) 1108 | 1109 | $.Event = function(type, props) { 1110 | if (typeof type != 'string') props = type, type = props.type 1111 | var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true 1112 | if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]) 1113 | event.initEvent(type, bubbles, true, null, null, null, null, null, null, null, null, null, null, null, null) 1114 | event.isDefaultPrevented = function(){ return this.defaultPrevented } 1115 | return event 1116 | } 1117 | 1118 | })(Zepto) 1119 | 1120 | ;(function($){ 1121 | var jsonpID = 0, 1122 | document = window.document, 1123 | key, 1124 | name, 1125 | rscript = /)<[^<]*)*<\/script>/gi, 1126 | scriptTypeRE = /^(?:text|application)\/javascript/i, 1127 | xmlTypeRE = /^(?:text|application)\/xml/i, 1128 | jsonType = 'application/json', 1129 | htmlType = 'text/html', 1130 | blankRE = /^\s*$/ 1131 | 1132 | // trigger a custom event and return false if it was cancelled 1133 | function triggerAndReturn(context, eventName, data) { 1134 | var event = $.Event(eventName) 1135 | $(context).trigger(event, data) 1136 | return !event.defaultPrevented 1137 | } 1138 | 1139 | // trigger an Ajax "global" event 1140 | function triggerGlobal(settings, context, eventName, data) { 1141 | if (settings.global) return triggerAndReturn(context || document, eventName, data) 1142 | } 1143 | 1144 | // Number of active Ajax requests 1145 | $.active = 0 1146 | 1147 | function ajaxStart(settings) { 1148 | if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart') 1149 | } 1150 | function ajaxStop(settings) { 1151 | if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop') 1152 | } 1153 | 1154 | // triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelable 1155 | function ajaxBeforeSend(xhr, settings) { 1156 | var context = settings.context 1157 | if (settings.beforeSend.call(context, xhr, settings) === false || 1158 | triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false) 1159 | return false 1160 | 1161 | triggerGlobal(settings, context, 'ajaxSend', [xhr, settings]) 1162 | } 1163 | function ajaxSuccess(data, xhr, settings) { 1164 | var context = settings.context, status = 'success' 1165 | settings.success.call(context, data, status, xhr) 1166 | triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data]) 1167 | ajaxComplete(status, xhr, settings) 1168 | } 1169 | // type: "timeout", "error", "abort", "parsererror" 1170 | function ajaxError(error, type, xhr, settings) { 1171 | var context = settings.context 1172 | settings.error.call(context, xhr, type, error) 1173 | triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error]) 1174 | ajaxComplete(type, xhr, settings) 1175 | } 1176 | // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" 1177 | function ajaxComplete(status, xhr, settings) { 1178 | var context = settings.context 1179 | settings.complete.call(context, xhr, status) 1180 | triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings]) 1181 | ajaxStop(settings) 1182 | } 1183 | 1184 | // Empty function, used as default callback 1185 | function empty() {} 1186 | 1187 | $.ajaxJSONP = function(options){ 1188 | if (!('type' in options)) return $.ajax(options) 1189 | 1190 | var callbackName = 'jsonp' + (++jsonpID), 1191 | script = document.createElement('script'), 1192 | cleanup = function() { 1193 | clearTimeout(abortTimeout) 1194 | $(script).remove() 1195 | delete window[callbackName] 1196 | }, 1197 | abort = function(type){ 1198 | cleanup() 1199 | // In case of manual abort or timeout, keep an empty function as callback 1200 | // so that the SCRIPT tag that eventually loads won't result in an error. 1201 | if (!type || type == 'timeout') window[callbackName] = empty 1202 | ajaxError(null, type || 'abort', xhr, options) 1203 | }, 1204 | xhr = { abort: abort }, abortTimeout 1205 | 1206 | if (ajaxBeforeSend(xhr, options) === false) { 1207 | abort('abort') 1208 | return false 1209 | } 1210 | 1211 | window[callbackName] = function(data){ 1212 | cleanup() 1213 | ajaxSuccess(data, xhr, options) 1214 | } 1215 | 1216 | script.onerror = function() { abort('error') } 1217 | 1218 | script.src = options.url.replace(/=\?/, '=' + callbackName) 1219 | $('head').append(script) 1220 | 1221 | if (options.timeout > 0) abortTimeout = setTimeout(function(){ 1222 | abort('timeout') 1223 | }, options.timeout) 1224 | 1225 | return xhr 1226 | } 1227 | 1228 | $.ajaxSettings = { 1229 | // Default type of request 1230 | type: 'GET', 1231 | // Callback that is executed before request 1232 | beforeSend: empty, 1233 | // Callback that is executed if the request succeeds 1234 | success: empty, 1235 | // Callback that is executed the the server drops error 1236 | error: empty, 1237 | // Callback that is executed on request complete (both: error and success) 1238 | complete: empty, 1239 | // The context for the callbacks 1240 | context: null, 1241 | // Whether to trigger "global" Ajax events 1242 | global: true, 1243 | // Transport 1244 | xhr: function () { 1245 | return new window.XMLHttpRequest() 1246 | }, 1247 | // MIME types mapping 1248 | accepts: { 1249 | script: 'text/javascript, application/javascript', 1250 | json: jsonType, 1251 | xml: 'application/xml, text/xml', 1252 | html: htmlType, 1253 | text: 'text/plain' 1254 | }, 1255 | // Whether the request is to another domain 1256 | crossDomain: false, 1257 | // Default timeout 1258 | timeout: 0, 1259 | // Whether data should be serialized to string 1260 | processData: true, 1261 | // Whether the browser should be allowed to cache GET responses 1262 | cache: true, 1263 | } 1264 | 1265 | function mimeToDataType(mime) { 1266 | if (mime) mime = mime.split(';', 2)[0] 1267 | return mime && ( mime == htmlType ? 'html' : 1268 | mime == jsonType ? 'json' : 1269 | scriptTypeRE.test(mime) ? 'script' : 1270 | xmlTypeRE.test(mime) && 'xml' ) || 'text' 1271 | } 1272 | 1273 | function appendQuery(url, query) { 1274 | return (url + '&' + query).replace(/[&?]{1,2}/, '?') 1275 | } 1276 | 1277 | // serialize payload and append it to the URL for GET requests 1278 | function serializeData(options) { 1279 | if (options.processData && options.data && $.type(options.data) != "string") 1280 | options.data = $.param(options.data, options.traditional) 1281 | if (options.data && (!options.type || options.type.toUpperCase() == 'GET')) 1282 | options.url = appendQuery(options.url, options.data) 1283 | } 1284 | 1285 | $.ajax = function(options){ 1286 | var settings = $.extend({}, options || {}) 1287 | for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key] 1288 | 1289 | ajaxStart(settings) 1290 | 1291 | if (!settings.crossDomain) settings.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(settings.url) && 1292 | RegExp.$2 != window.location.host 1293 | 1294 | if (!settings.url) settings.url = window.location.toString() 1295 | serializeData(settings) 1296 | if (settings.cache === false) settings.url = appendQuery(settings.url, '_=' + Date.now()) 1297 | 1298 | var dataType = settings.dataType, hasPlaceholder = /=\?/.test(settings.url) 1299 | if (dataType == 'jsonp' || hasPlaceholder) { 1300 | if (!hasPlaceholder) settings.url = appendQuery(settings.url, 'callback=?') 1301 | return $.ajaxJSONP(settings) 1302 | } 1303 | 1304 | var mime = settings.accepts[dataType], 1305 | baseHeaders = { }, 1306 | protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol, 1307 | xhr = settings.xhr(), abortTimeout 1308 | 1309 | if (!settings.crossDomain) baseHeaders['X-Requested-With'] = 'XMLHttpRequest' 1310 | if (mime) { 1311 | baseHeaders['Accept'] = mime 1312 | if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0] 1313 | xhr.overrideMimeType && xhr.overrideMimeType(mime) 1314 | } 1315 | if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET')) 1316 | baseHeaders['Content-Type'] = (settings.contentType || 'application/x-www-form-urlencoded') 1317 | settings.headers = $.extend(baseHeaders, settings.headers || {}) 1318 | 1319 | xhr.onreadystatechange = function(){ 1320 | if (xhr.readyState == 4) { 1321 | xhr.onreadystatechange = empty; 1322 | clearTimeout(abortTimeout) 1323 | var result, error = false 1324 | if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) { 1325 | dataType = dataType || mimeToDataType(xhr.getResponseHeader('content-type')) 1326 | result = xhr.responseText 1327 | 1328 | try { 1329 | // http://perfectionkills.com/global-eval-what-are-the-options/ 1330 | if (dataType == 'script') (1,eval)(result) 1331 | else if (dataType == 'xml') result = xhr.responseXML 1332 | else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result) 1333 | } catch (e) { error = e } 1334 | 1335 | if (error) ajaxError(error, 'parsererror', xhr, settings) 1336 | else ajaxSuccess(result, xhr, settings) 1337 | } else { 1338 | ajaxError(null, xhr.status ? 'error' : 'abort', xhr, settings) 1339 | } 1340 | } 1341 | } 1342 | 1343 | var async = 'async' in settings ? settings.async : true 1344 | xhr.open(settings.type, settings.url, async) 1345 | 1346 | for (name in settings.headers) xhr.setRequestHeader(name, settings.headers[name]) 1347 | 1348 | if (ajaxBeforeSend(xhr, settings) === false) { 1349 | xhr.abort() 1350 | return false 1351 | } 1352 | 1353 | if (settings.timeout > 0) abortTimeout = setTimeout(function(){ 1354 | xhr.onreadystatechange = empty 1355 | xhr.abort() 1356 | ajaxError(null, 'timeout', xhr, settings) 1357 | }, settings.timeout) 1358 | 1359 | // avoid sending empty string (#319) 1360 | xhr.send(settings.data ? settings.data : null) 1361 | return xhr 1362 | } 1363 | 1364 | // handle optional data/success arguments 1365 | function parseArguments(url, data, success, dataType) { 1366 | var hasData = !$.isFunction(data) 1367 | return { 1368 | url: url, 1369 | data: hasData ? data : undefined, 1370 | success: !hasData ? data : $.isFunction(success) ? success : undefined, 1371 | dataType: hasData ? dataType || success : success 1372 | } 1373 | } 1374 | 1375 | $.get = function(url, data, success, dataType){ 1376 | return $.ajax(parseArguments.apply(null, arguments)) 1377 | } 1378 | 1379 | $.post = function(url, data, success, dataType){ 1380 | var options = parseArguments.apply(null, arguments) 1381 | options.type = 'POST' 1382 | return $.ajax(options) 1383 | } 1384 | 1385 | $.getJSON = function(url, data, success){ 1386 | var options = parseArguments.apply(null, arguments) 1387 | options.dataType = 'json' 1388 | return $.ajax(options) 1389 | } 1390 | 1391 | $.fn.load = function(url, data, success){ 1392 | if (!this.length) return this 1393 | var self = this, parts = url.split(/\s/), selector, 1394 | options = parseArguments(url, data, success), 1395 | callback = options.success 1396 | if (parts.length > 1) options.url = parts[0], selector = parts[1] 1397 | options.success = function(response){ 1398 | self.html(selector ? 1399 | $('
').html(response.replace(rscript, "")).find(selector) 1400 | : response) 1401 | callback && callback.apply(self, arguments) 1402 | } 1403 | $.ajax(options) 1404 | return this 1405 | } 1406 | 1407 | var escape = encodeURIComponent 1408 | 1409 | function serialize(params, obj, traditional, scope){ 1410 | var type, array = $.isArray(obj) 1411 | $.each(obj, function(key, value) { 1412 | type = $.type(value) 1413 | if (scope) key = traditional ? scope : scope + '[' + (array ? '' : key) + ']' 1414 | // handle data in serializeArray() format 1415 | if (!scope && array) params.add(value.name, value.value) 1416 | // recurse into nested objects 1417 | else if (type == "array" || (!traditional && type == "object")) 1418 | serialize(params, value, traditional, key) 1419 | else params.add(key, value) 1420 | }) 1421 | } 1422 | 1423 | $.param = function(obj, traditional){ 1424 | var params = [] 1425 | params.add = function(k, v){ this.push(escape(k) + '=' + escape(v)) } 1426 | serialize(params, obj, traditional) 1427 | return params.join('&').replace(/%20/g, '+') 1428 | } 1429 | })(Zepto) 1430 | 1431 | ;(function ($) { 1432 | $.fn.serializeArray = function () { 1433 | var result = [], el 1434 | $( Array.prototype.slice.call(this.get(0).elements) ).each(function () { 1435 | el = $(this) 1436 | var type = el.attr('type') 1437 | if (this.nodeName.toLowerCase() != 'fieldset' && 1438 | !this.disabled && type != 'submit' && type != 'reset' && type != 'button' && 1439 | ((type != 'radio' && type != 'checkbox') || this.checked)) 1440 | result.push({ 1441 | name: el.attr('name'), 1442 | value: el.val() 1443 | }) 1444 | }) 1445 | return result 1446 | } 1447 | 1448 | $.fn.serialize = function () { 1449 | var result = [] 1450 | this.serializeArray().forEach(function (elm) { 1451 | result.push( encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value) ) 1452 | }) 1453 | return result.join('&') 1454 | } 1455 | 1456 | $.fn.submit = function (callback) { 1457 | if (callback) this.bind('submit', callback) 1458 | else if (this.length) { 1459 | var event = $.Event('submit') 1460 | this.eq(0).trigger(event) 1461 | if (!event.defaultPrevented) this.get(0).submit() 1462 | } 1463 | return this 1464 | } 1465 | 1466 | })(Zepto) 1467 | 1468 | ;(function($, undefined){ 1469 | var prefix = '', eventPrefix, endEventName, endAnimationName, 1470 | vendors = { Webkit: 'webkit', Moz: '', O: 'o', ms: 'MS' }, 1471 | document = window.document, testEl = document.createElement('div'), 1472 | supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i, 1473 | transform, 1474 | transitionProperty, transitionDuration, transitionTiming, 1475 | animationName, animationDuration, animationTiming, 1476 | cssReset = {} 1477 | 1478 | function dasherize(str) { return downcase(str.replace(/([a-z])([A-Z])/, '$1-$2')) } 1479 | function downcase(str) { return str.toLowerCase() } 1480 | function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : downcase(name) } 1481 | 1482 | $.each(vendors, function(vendor, event){ 1483 | if (testEl.style[vendor + 'TransitionProperty'] !== undefined) { 1484 | prefix = '-' + downcase(vendor) + '-' 1485 | eventPrefix = event 1486 | return false 1487 | } 1488 | }) 1489 | 1490 | transform = prefix + 'transform' 1491 | cssReset[transitionProperty = prefix + 'transition-property'] = 1492 | cssReset[transitionDuration = prefix + 'transition-duration'] = 1493 | cssReset[transitionTiming = prefix + 'transition-timing-function'] = 1494 | cssReset[animationName = prefix + 'animation-name'] = 1495 | cssReset[animationDuration = prefix + 'animation-duration'] = 1496 | cssReset[animationTiming = prefix + 'animation-timing-function'] = '' 1497 | 1498 | $.fx = { 1499 | off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined), 1500 | speeds: { _default: 400, fast: 200, slow: 600 }, 1501 | cssPrefix: prefix, 1502 | transitionEnd: normalizeEvent('TransitionEnd'), 1503 | animationEnd: normalizeEvent('AnimationEnd') 1504 | } 1505 | 1506 | $.fn.animate = function(properties, duration, ease, callback){ 1507 | if ($.isPlainObject(duration)) 1508 | ease = duration.easing, callback = duration.complete, duration = duration.duration 1509 | if (duration) duration = (typeof duration == 'number' ? duration : 1510 | ($.fx.speeds[duration] || $.fx.speeds._default)) / 1000 1511 | return this.anim(properties, duration, ease, callback) 1512 | } 1513 | 1514 | $.fn.anim = function(properties, duration, ease, callback){ 1515 | var key, cssValues = {}, cssProperties, transforms = '', 1516 | that = this, wrappedCallback, endEvent = $.fx.transitionEnd 1517 | 1518 | if (duration === undefined) duration = 0.4 1519 | if ($.fx.off) duration = 0 1520 | 1521 | if (typeof properties == 'string') { 1522 | // keyframe animation 1523 | cssValues[animationName] = properties 1524 | cssValues[animationDuration] = duration + 's' 1525 | cssValues[animationTiming] = (ease || 'linear') 1526 | endEvent = $.fx.animationEnd 1527 | } else { 1528 | cssProperties = [] 1529 | // CSS transitions 1530 | for (key in properties) 1531 | if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') ' 1532 | else cssValues[key] = properties[key], cssProperties.push(dasherize(key)) 1533 | 1534 | if (transforms) cssValues[transform] = transforms, cssProperties.push(transform) 1535 | if (duration > 0 && typeof properties === 'object') { 1536 | cssValues[transitionProperty] = cssProperties.join(', ') 1537 | cssValues[transitionDuration] = duration + 's' 1538 | cssValues[transitionTiming] = (ease || 'linear') 1539 | } 1540 | } 1541 | 1542 | wrappedCallback = function(event){ 1543 | if (typeof event !== 'undefined') { 1544 | if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below" 1545 | $(event.target).unbind(endEvent, wrappedCallback) 1546 | } 1547 | $(this).css(cssReset) 1548 | callback && callback.call(this) 1549 | } 1550 | if (duration > 0) this.bind(endEvent, wrappedCallback) 1551 | 1552 | // trigger page reflow so new elements can animate 1553 | this.size() && this.get(0).clientLeft 1554 | 1555 | this.css(cssValues) 1556 | 1557 | if (duration <= 0) setTimeout(function() { 1558 | that.each(function(){ wrappedCallback.call(this) }) 1559 | }, 0) 1560 | 1561 | return this 1562 | } 1563 | 1564 | testEl = null 1565 | })(Zepto) 1566 | --------------------------------------------------------------------------------