|
1 | 1 | "use strict"; |
2 | 2 |
|
3 | | -/*! cash-dom 1.3.4, https://github.com/kenwheeler/cash @license MIT */ |
4 | | -(function (root, factory) { |
| 3 | +/*! cash-dom 1.3.5, https://github.com/kenwheeler/cash @license MIT */ |
| 4 | +;(function (root, factory) { |
5 | 5 | if (typeof define === "function" && define.amd) { |
6 | 6 | define(factory); |
7 | 7 | } else if (typeof exports !== "undefined") { |
|
13 | 13 | var doc = document, win = window, ArrayProto = Array.prototype, slice = ArrayProto.slice, filter = ArrayProto.filter, push = ArrayProto.push; |
14 | 14 |
|
15 | 15 | var noop = function () {}, isFunction = function (item) { |
16 | | - return typeof item === typeof noop; |
| 16 | + // @see https://crbug.com/568448 |
| 17 | + return typeof item === typeof noop && item.call; |
17 | 18 | }, isString = function (item) { |
18 | 19 | return typeof item === typeof ""; |
19 | 20 | }; |
|
26 | 27 | return elems; |
27 | 28 | } |
28 | 29 |
|
29 | | - var frag, tmp; |
| 30 | + var frag; |
30 | 31 | function parseHTML(str) { |
31 | | - frag = frag || doc.createDocumentFragment(); |
32 | | - tmp = tmp || frag.appendChild(doc.createElement("div")); |
33 | | - tmp.innerHTML = str; |
34 | | - return tmp.childNodes; |
| 32 | + if (!frag) { |
| 33 | + frag = doc.implementation.createHTMLDocument(); |
| 34 | + var base = frag.createElement("base"); |
| 35 | + base.href = doc.location.href; |
| 36 | + frag.head.appendChild(base); |
| 37 | + } |
| 38 | + |
| 39 | + frag.body.innerHTML = str; |
| 40 | + |
| 41 | + return frag.body.childNodes; |
35 | 42 | } |
36 | 43 |
|
37 | 44 | function onReady(fn) { |
|
92 | 99 | } |
93 | 100 |
|
94 | 101 | var fn = cash.fn = cash.prototype = Init.prototype = { // jshint ignore:line |
95 | | - constructor: cash, |
96 | 102 | cash: true, |
97 | 103 | length: 0, |
98 | 104 | push: push, |
|
101 | 107 | init: Init |
102 | 108 | }; |
103 | 109 |
|
| 110 | + Object.defineProperty(fn, "constructor", { value: cash }); |
| 111 | + |
104 | 112 | cash.parseHTML = parseHTML; |
105 | 113 | cash.noop = noop; |
106 | 114 | cash.isFunction = isFunction; |
|
145 | 153 | return !!m && m.call(el, selector); |
146 | 154 | } |
147 | 155 |
|
| 156 | + function getCompareFunction(selector) { |
| 157 | + return ( |
| 158 | + /* Use browser's `matches` function if string */ |
| 159 | + isString(selector) ? matches : |
| 160 | + /* Match a cash element */ |
| 161 | + selector.cash ? function (el) { |
| 162 | + return selector.is(el); |
| 163 | + } : |
| 164 | + /* Direct comparison */ |
| 165 | + function (el, selector) { |
| 166 | + return el === selector; |
| 167 | + }); |
| 168 | + } |
| 169 | + |
148 | 170 | function unique(collection) { |
149 | 171 | return cash(slice.call(collection).filter(function (item, index, self) { |
150 | 172 | return self.indexOf(item) === index; |
|
374 | 396 | }, |
375 | 397 |
|
376 | 398 | filter: function (selector) { |
377 | | - return cash(filter.call(this, (isString(selector) ? function (e) { |
378 | | - return matches(e, selector); |
379 | | - } : selector))); |
| 399 | + if (!selector) { |
| 400 | + return this; |
| 401 | + } |
| 402 | + |
| 403 | + var comparator = (isFunction(selector) ? selector : getCompareFunction(selector)); |
| 404 | + |
| 405 | + return cash(filter.call(this, function (e) { |
| 406 | + return comparator(e, selector); |
| 407 | + })); |
380 | 408 | }, |
381 | 409 |
|
382 | 410 | first: function () { |
|
481 | 509 | } |
482 | 510 |
|
483 | 511 | function removeEvent(node, eventName, callback) { |
484 | | - var eventCache = getData(node, "_cashEvents")[eventName]; |
| 512 | + var events = getData(node, "_cashEvents"), eventCache = (events && events[eventName]), index; |
| 513 | + |
| 514 | + if (!eventCache) { |
| 515 | + return; |
| 516 | + } |
| 517 | + |
485 | 518 | if (callback) { |
486 | 519 | node.removeEventListener(eventName, callback); |
| 520 | + index = eventCache.indexOf(callback); |
| 521 | + if (index >= 0) { |
| 522 | + eventCache.splice(index, 1); |
| 523 | + } |
487 | 524 | } else { |
488 | 525 | each(eventCache, function (event) { |
489 | 526 | node.removeEventListener(eventName, event); |
|
571 | 608 | function encode(name, value) { |
572 | 609 | return "&" + encodeURIComponent(name) + "=" + encodeURIComponent(value).replace(/%20/g, "+"); |
573 | 610 | } |
574 | | - function isCheckable(field) { |
575 | | - return field.type === "radio" || field.type === "checkbox"; |
| 611 | + |
| 612 | + function getSelectMultiple_(el) { |
| 613 | + var values = []; |
| 614 | + each(el.options, function (o) { |
| 615 | + if (o.selected) { |
| 616 | + values.push(o.value); |
| 617 | + } |
| 618 | + }); |
| 619 | + return values.length ? values : null; |
576 | 620 | } |
577 | 621 |
|
578 | | - var formExcludes = ["file", "reset", "submit", "button"]; |
| 622 | + function getSelectSingle_(el) { |
| 623 | + var selectedIndex = el.selectedIndex; |
| 624 | + return selectedIndex >= 0 ? el.options[selectedIndex].value : null; |
| 625 | + } |
| 626 | + |
| 627 | + function getValue(el) { |
| 628 | + var type = el.type; |
| 629 | + if (!type) { |
| 630 | + return null; |
| 631 | + } |
| 632 | + switch (type.toLowerCase()) { |
| 633 | + case "select-one": |
| 634 | + return getSelectSingle_(el); |
| 635 | + case "select-multiple": |
| 636 | + return getSelectMultiple_(el); |
| 637 | + case "radio": |
| 638 | + return (el.checked) ? el.value : null; |
| 639 | + case "checkbox": |
| 640 | + return (el.checked) ? el.value : null; |
| 641 | + default: |
| 642 | + return el.value ? el.value : null; |
| 643 | + } |
| 644 | + } |
579 | 645 |
|
580 | 646 | fn.extend({ |
581 | 647 | serialize: function () { |
582 | | - var formEl = this[0].elements, query = ""; |
583 | | - |
584 | | - each(formEl, function (field) { |
585 | | - if (field.name && formExcludes.indexOf(field.type) < 0) { |
586 | | - if (field.type === "select-multiple") { |
587 | | - each(field.options, function (o) { |
588 | | - if (o.selected) { |
589 | | - query += encode(field.name, o.value); |
590 | | - } |
591 | | - }); |
592 | | - } else if (!isCheckable(field) || (isCheckable(field) && field.checked)) { |
593 | | - query += encode(field.name, field.value); |
594 | | - } |
| 648 | + var query = ""; |
| 649 | + |
| 650 | + each(this[0].elements || this, function (el) { |
| 651 | + if (el.disabled || el.tagName === "FIELDSET") { |
| 652 | + return; |
| 653 | + } |
| 654 | + var name = el.name; |
| 655 | + switch (el.type.toLowerCase()) { |
| 656 | + case "file": |
| 657 | + case "reset": |
| 658 | + case "submit": |
| 659 | + case "button": |
| 660 | + break; |
| 661 | + case "select-multiple": |
| 662 | + var values = getValue(el); |
| 663 | + if (values !== null) { |
| 664 | + each(values, function (value) { |
| 665 | + query += encode(name, value); |
| 666 | + }); |
| 667 | + } |
| 668 | + break; |
| 669 | + default: |
| 670 | + var value = getValue(el); |
| 671 | + if (value !== null) { |
| 672 | + query += encode(name, value); |
| 673 | + } |
595 | 674 | } |
596 | 675 | }); |
597 | 676 |
|
|
600 | 679 |
|
601 | 680 | val: function (value) { |
602 | 681 | if (value === undefined) { |
603 | | - return this[0].value; |
| 682 | + return getValue(this[0]); |
604 | 683 | } else { |
605 | 684 | return this.each(function (v) { |
606 | 685 | return v.value = value; |
|
755 | 834 |
|
756 | 835 | }); |
757 | 836 |
|
758 | | - function directCompare(el, selector) { |
759 | | - return el === selector; |
760 | | - } |
761 | | - |
762 | 837 | fn.extend({ |
763 | 838 | children: function (selector) { |
764 | 839 | var elems = []; |
|
773 | 848 | }, |
774 | 849 |
|
775 | 850 | closest: function (selector) { |
776 | | - if (!selector || matches(this[0], selector)) { |
777 | | - return this; |
| 851 | + if (!selector || this.length < 1) { |
| 852 | + return cash(); |
| 853 | + } |
| 854 | + if (this.is(selector)) { |
| 855 | + return this.filter(selector); |
778 | 856 | } |
779 | 857 | return this.parent().closest(selector); |
780 | 858 | }, |
|
784 | 862 | return false; |
785 | 863 | } |
786 | 864 |
|
787 | | - var match = false, comparator = (isString(selector) ? matches : selector.cash ? function (el) { |
788 | | - return selector.is(el); |
789 | | - } : directCompare); |
| 865 | + var match = false, comparator = getCompareFunction(selector); |
790 | 866 |
|
791 | | - this.each(function (el, i) { |
792 | | - match = comparator(el, selector, i); |
| 867 | + this.each(function (el) { |
| 868 | + match = comparator(el, selector); |
793 | 869 | return !match; |
794 | 870 | }); |
795 | 871 |
|
796 | 872 | return match; |
797 | 873 | }, |
798 | 874 |
|
799 | 875 | find: function (selector) { |
800 | | - if (!selector) { |
801 | | - return cash(); |
| 876 | + if (!selector || selector.nodeType) { |
| 877 | + return cash(selector && this.has(selector).length ? selector : null); |
802 | 878 | } |
803 | 879 |
|
804 | 880 | var elems = []; |
|
810 | 886 | }, |
811 | 887 |
|
812 | 888 | has: function (selector) { |
813 | | - return filter.call(this, function (el) { |
814 | | - return cash(el).find(selector).length !== 0; |
| 889 | + var comparator = (isString(selector) ? function (el) { |
| 890 | + return find(selector, el).length !== 0; |
| 891 | + } : function (el) { |
| 892 | + return el.contains(selector); |
815 | 893 | }); |
| 894 | + |
| 895 | + return this.filter(comparator); |
816 | 896 | }, |
817 | 897 |
|
818 | 898 | next: function () { |
819 | 899 | return cash(this[0].nextElementSibling); |
820 | 900 | }, |
821 | 901 |
|
822 | 902 | not: function (selector) { |
823 | | - return filter.call(this, function (el) { |
824 | | - return !matches(el, selector); |
| 903 | + if (!selector) { |
| 904 | + return this; |
| 905 | + } |
| 906 | + |
| 907 | + var comparator = getCompareFunction(selector); |
| 908 | + |
| 909 | + return this.filter(function (el) { |
| 910 | + return !comparator(el, selector); |
825 | 911 | }); |
826 | 912 | }, |
827 | 913 |
|
828 | 914 | parent: function () { |
829 | | - var result = this.map(function (item) { |
830 | | - return item.parentElement || doc.body.parentNode; |
| 915 | + var result = []; |
| 916 | + |
| 917 | + this.each(function (item) { |
| 918 | + if (item && item.parentNode) { |
| 919 | + result.push(item.parentNode); |
| 920 | + } |
831 | 921 | }); |
832 | 922 |
|
833 | 923 | return unique(result); |
|
839 | 929 | this.each(function (item) { |
840 | 930 | last = item; |
841 | 931 |
|
842 | | - while (last !== doc.body.parentNode) { |
843 | | - last = last.parentElement; |
| 932 | + while (last && last.parentNode && last !== doc.body.parentNode) { |
| 933 | + last = last.parentNode; |
844 | 934 |
|
845 | 935 | if (!selector || (selector && matches(last, selector))) { |
846 | 936 | result.push(last); |
|
858 | 948 | siblings: function () { |
859 | 949 | var collection = this.parent().children(), el = this[0]; |
860 | 950 |
|
861 | | - return filter.call(collection, function (i) { |
| 951 | + return collection.filter(function (i) { |
862 | 952 | return i !== el; |
863 | 953 | }); |
864 | 954 | } |
|
0 commit comments