You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2866 lines
61 KiB

const propMap: Record<string, string> = {
/* GENERAL */
class: 'className',
contenteditable: 'contentEditable',
/* LABEL */
for: 'htmlFor',
/* INPUT */
readonly: 'readOnly',
maxlength: 'maxLength',
tabindex: 'tabIndex',
/* TABLE */
colspan: 'colSpan',
rowspan: 'rowSpan',
/* IMAGE */
usemap: 'useMap'
};
function attempt<T, U> ( fn: (( arg?: U ) => T), arg?: U ): T | U {
try {
return fn ( arg );
} catch {
return arg;
}
}
interface Event {
namespace: string,
data: any,
___cd?: boolean, // Delegate
___ifocus?: boolean, // Ignore focus
___iblur?: boolean, // Ignore blur
___ot?: string, // Original type
___td?: boolean // Trigger data
}
interface Cash {
[index: number]: EleLoose | undefined,
length: number,
splice ( start: number, deleteCount?: number ): EleLoose[],
splice ( start: number, deleteCount: number, ...items: Ele[] ): EleLoose[]
}
interface CashStatic {
fn: Cash
}
type falsy = undefined | null | false | 0 | '';
type Ele = Window | Document | HTMLElement | Element | Node;
type EleLoose = HTMLElement & Element & Node; //UGLY: Trick to remove some kind-of useless type errors //URL: https://github.com/fabiospampinato/cash/issues/278
type Selector = falsy | string | Function | HTMLCollection | NodeList | Ele | Ele[] | ArrayLike<Ele> | Cash;
type Comparator = string | Ele | Cash | (( this: EleLoose, index: number, ele: EleLoose ) => boolean);
type Context = Document | HTMLElement | Element;
type EventCallback = {
( event: any, data?: any ): any,
guid?: number
};
const doc = document,
win = window,
docEle = doc.documentElement,
createElement = doc.createElement.bind ( doc ),
div = createElement ( 'div' ),
table = createElement ( 'table' ),
tbody = createElement ( 'tbody' ),
tr = createElement ( 'tr' ),
{isArray, prototype: ArrayPrototype} = Array,
{concat, filter, indexOf, map, push, slice, some, splice} = ArrayPrototype;
const idRe = /^#[\w-]*$/,
classRe = /^\.[\w-]*$/,
htmlRe = /<.+>/,
tagRe = /^\w+$/;
// @require ./variables.ts
function find ( selector: string, context: Ele ): ArrayLike<Element> {
return !selector || ( !isDocument ( context ) && !isElement ( context ) )
? []
: classRe.test ( selector )
? context.getElementsByClassName ( selector.slice ( 1 ) )
: tagRe.test ( selector )
? context.getElementsByTagName ( selector )
: context.querySelectorAll ( selector );
}
// @require ./find.ts
// @require ./variables.ts
class Cash {
constructor ( selector?: Selector, context?: Context | Cash ) {
if ( !selector ) return;
if ( isCash ( selector ) ) return selector;
let eles: any = selector;
if ( isString ( selector ) ) {
const ctx = ( isCash ( context ) ? context[0] : context ) || doc;
eles = idRe.test ( selector )
? ( ctx as Document ).getElementById ( selector.slice ( 1 ) )
: htmlRe.test ( selector )
? parseHTML ( selector )
: find ( selector, ctx );
if ( !eles ) return;
} else if ( isFunction ( selector ) ) {
return this.ready ( selector ); //FIXME: `fn.ready` is not included in `core`, but it's actually a core functionality
}
if ( eles.nodeType || eles === win ) eles = [eles];
this.length = eles.length;
for ( let i = 0, l = this.length; i < l; i++ ) {
this[i] = eles[i];
}
}
init ( selector?: Selector, context?: Context | Cash ) {
return new Cash ( selector, context );
}
}
const fn = Cash.prototype,
cash = fn.init as typeof Cash.prototype.init & CashStatic;
cash.fn = cash.prototype = fn; // Ensuring that `cash () instanceof cash`
fn.length = 0;
fn.splice = splice; // Ensuring a cash collection gets printed as array-like in Chrome's devtools
if ( typeof Symbol === 'function' ) { // Ensuring a cash collection is iterable
fn[Symbol['iterator']] = ArrayPrototype[Symbol['iterator']];
}
// @require core/cash.ts
// @require core/variables.ts
type MapCallback<T> = ( this: T, index: number, ele: T ) => Ele;
interface Cash {
map ( callback: MapCallback<EleLoose> ): Cash;
}
fn.map = function ( this: Cash, callback: MapCallback<EleLoose> ) {
return cash ( concat.apply ( [], map.call ( this, ( ele: EleLoose, i: number ) => callback.call ( ele, i, ele ) ) ) );
};
// @require core/cash.ts
// @require core/variables.ts
interface Cash {
slice ( start?: number, end?: number ): Cash;
}
fn.slice = function ( this: Cash, start?: number, end?: number ) {
return cash ( slice.call ( this, start, end ) );
};
// @require ./cash.ts
const dashAlphaRe = /-([a-z])/g;
function camelCase ( str: string ): string {
return str.replace ( dashAlphaRe, ( match: string, letter: string ) => letter.toUpperCase () );
}
// @require ./cash.ts
type EachCallback<T> = ( this: T, index: number, ele: T ) => any;
interface CashStatic {
each<T> ( arr: ArrayLike<T>, callback: EachCallback<T> ): void;
}
function each<T, U extends ArrayLike<T> = ArrayLike<T>> ( arr: U, callback: EachCallback<U[0]>, _reverse?: boolean ): U {
if ( _reverse ) {
let i = arr.length;
while ( i-- ) {
if ( callback.call ( arr[i], i, arr[i] ) === false ) return arr;
}
} else {
for ( let i = 0, l = arr.length; i < l; i++ ) {
if ( callback.call ( arr[i], i, arr[i] ) === false ) return arr;
}
}
return arr;
}
cash.each = each;
// @require core/cash.ts
// @require core/each.ts
interface Cash {
each ( callback: EachCallback<EleLoose> ): this;
}
fn.each = function ( this: Cash, callback: EachCallback<EleLoose> ) {
return each ( this, callback );
};
// @require core/cash.ts
// @require collection/each.ts
// @require ./helpers/variables.ts
interface Cash {
removeProp ( prop: string ): this;
}
fn.removeProp = function ( this: Cash, prop: string ) {
return this.each ( ( i, ele ) => { delete ele[propMap[prop] || prop] } );
};
// @require ./cash.ts
interface CashStatic {
extend (): any;
extend ( target: any ): typeof cash;
extend ( target: any, ...objs: any[] ): any;
}
interface Cash {
extend ( plugins: Record<any, any> ): this;
}
function extend ( target?: any, ...objs: any[] ) {
const length = arguments.length;
if ( !length ) return {};
if ( length === 1 ) return extend ( cash, target );
for ( let i = 1; i < length; i++ ) {
for ( const key in arguments[i] ) {
target[key] = arguments[i][key];
}
}
return target;
}
cash.extend = extend;
fn.extend = function ( plugins: Record<string, any> ) {
return extend ( fn, plugins );
};
// @require ./cash.ts
interface CashStatic {
guid: number;
}
cash.guid = 1;
// @require ./cash.ts
function matches ( ele: any, selector: string ): boolean {
const matches = ele && ( ele['matches'] || ele['webkitMatchesSelector'] || ele['msMatchesSelector'] );
return !!matches && !!selector && matches.call ( ele, selector );
}
// @require ./cash.ts
// @require ./variables.ts
interface CashStatic {
isWindow ( x: any ): x is Window;
isFunction ( x: any ): x is Function;
isNumeric ( x: any ): boolean;
isArray ( x: any ): x is Array<any>;
}
function isCash ( x: any ): x is Cash {
return x instanceof Cash;
}
function isWindow ( x: any ): x is Window {
return !!x && x === x.window;
}
function isDocument ( x: any ): x is Document {
return !!x && x.nodeType === 9;
}
function isElement ( x: any ): x is HTMLElement {
return !!x && x.nodeType === 1;
}
function isFunction ( x: any ): x is Function {
return typeof x === 'function';
}
function isString ( x: any ): x is string {
return typeof x === 'string';
}
function isUndefined ( x: any ): x is undefined {
return x === undefined;
}
function isNull ( x: any ): x is null {
return x === null;
}
function isNumeric ( x: any ): boolean {
return !isNaN ( parseFloat ( x ) ) && isFinite ( x );
}
cash.isWindow = isWindow;
cash.isFunction = isFunction;
cash.isNumeric = isNumeric;
cash.isArray = isArray;
// @require core/cash.ts
// @require core/type_checking.ts
// @require collection/each.ts
// @require ./helpers/variables.ts
interface Cash {
prop ( prop: string ): any;
prop ( prop: string, value: any ): this;
prop ( props: Record<string, any> ): this;
}
fn.prop = function ( this: Cash, prop: string | Record<string, any>, value?: any ) {
if ( !prop ) return;
if ( isString ( prop ) ) {
prop = propMap[prop] || prop;
if ( arguments.length < 2 ) return this[0] && this[0][prop];
return this.each ( ( i, ele ) => { ele[prop] = value } );
}
for ( const key in prop ) {
this.prop ( key, prop[key] );
}
return this;
};
// @require core/cash.ts
// @require core/type_checking.ts
// @require core/variables.ts
interface Cash {
get (): EleLoose[];
get ( index: number ): EleLoose | undefined;
}
fn.get = function ( this: Cash, index?: number ) {
if ( isUndefined ( index ) ) return slice.call ( this );
index = Number ( index );
return this[index < 0 ? index + this.length : index];
};
// @require core/cash.ts
// @require ./get.ts
interface Cash {
eq ( index: number ): Cash;
}
fn.eq = function ( this: Cash, index: number ) {
return cash ( this.get ( index ) );
};
// @require core/cash.ts
// @require ./eq.ts
interface Cash {
first (): Cash;
}
fn.first = function ( this: Cash ) {
return this.eq ( 0 );
};
// @require core/cash.ts
// @require ./eq.ts
interface Cash {
last (): Cash;
}
fn.last = function ( this: Cash ) {
return this.eq ( -1 );
};
// @require ./matches.ts
// @require ./type_checking.ts
function getCompareFunction ( comparator?: Comparator ): (( i: number, ele: EleLoose ) => boolean) {
return isString ( comparator )
? ( i: number, ele: EleLoose ) => matches ( ele, comparator )
: isFunction ( comparator )
? comparator
: isCash ( comparator )
? ( i: number, ele: EleLoose ) => comparator.is ( ele )
: !comparator
? () => false
: ( i: number, ele: EleLoose ) => ele === comparator;
}
// @require core/cash.ts
// @require core/get_compare_function.ts
// @require core/type_checking.ts
// @require core/variables.ts
// @require collection/get.ts
interface Cash {
filter ( comparator?: Comparator ): Cash;
}
fn.filter = function ( this: Cash, comparator?: Comparator ) {
const compare = getCompareFunction ( comparator );
return cash ( filter.call ( this, ( ele: EleLoose, i: number ) => compare.call ( ele, i, ele ) ) );
};
// @require collection/filter.ts
function filtered ( collection: Cash, comparator?: Comparator ): Cash {
return !comparator ? collection : collection.filter ( comparator );
}
// @require ./type_checking.ts
const splitValuesRe = /\S+/g;
function getSplitValues ( str: string ) {
return isString ( str ) ? str.match ( splitValuesRe ) || [] : [];
}
// @require core/cash.ts
// @require core/get_split_values.ts
// @require core/type_checking.ts
// @require collection/each.ts
interface Cash {
hasClass ( cls: string ): boolean;
}
fn.hasClass = function ( this: Cash, cls: string ) {
return !!cls && some.call ( this, ( ele: EleLoose ) => isElement ( ele ) && ele.classList.contains ( cls ) );
};
// @require core/cash.ts
// @require core/get_split_values.ts
// @require collection/each.ts
interface Cash {
removeAttr ( attrs: string ): this;
}
fn.removeAttr = function ( this: Cash, attr: string ) {
const attrs = getSplitValues ( attr );
return this.each ( ( i, ele ) => {
if ( !isElement ( ele ) ) return;
each ( attrs, ( i, a ) => {
ele.removeAttribute ( a );
});
});
};
// @require core/cash.ts
// @require core/type_checking.ts
// @require collection/each.ts
// @require ./remove_attr.ts
interface Cash {
attr (): undefined;
attr ( attrs: string ): string | null;
attr ( attrs: string, value: string ): this;
attr ( attrs: Record<string, string> ): this;
}
function attr ( this: Cash ): undefined;
function attr ( this: Cash, attr: string ): string | null;
function attr ( this: Cash, attr: string, value: string ): Cash;
function attr ( this: Cash, attr: Record<string, string> ): Cash;
function attr ( this: Cash, attr?: string | Record<string, string>, value?: string ) {
if ( !attr ) return;
if ( isString ( attr ) ) {
if ( arguments.length < 2 ) {
if ( !this[0] || !isElement ( this[0] ) ) return;
const value = this[0].getAttribute ( attr );
return isNull ( value ) ? undefined : value;
}
if ( isUndefined ( value ) ) return this;
if ( isNull ( value ) ) return this.removeAttr ( attr );
return this.each ( ( i, ele ) => {
if ( !isElement ( ele ) ) return;
ele.setAttribute ( attr, value )
});
}
for ( const key in attr ) {
this.attr ( key, attr[key] );
}
return this;
}
fn.attr = attr;
// @require core/cash.ts
// @require core/each.ts
// @require core/get_split_values.ts
// @require core/type_checking.ts
// @require collection/each.ts
interface Cash {
toggleClass ( classes: string, force?: boolean ): this;
}
fn.toggleClass = function ( this: Cash, cls: string, force?: boolean ) {
const classes = getSplitValues ( cls ),
isForce = !isUndefined ( force );
return this.each ( ( i, ele ) => {
if ( !isElement ( ele ) ) return;
each ( classes, ( i, c ) => {
if ( isForce ) {
force ? ele.classList.add ( c ) : ele.classList.remove ( c );
} else {
ele.classList.toggle ( c );
}
});
});
};
// @require core/cash.ts
// @require ./toggle_class.ts
interface Cash {
addClass ( classes: string ): this;
}
fn.addClass = function ( this: Cash, cls: string ) {
return this.toggleClass ( cls, true );
};
// @require core/cash.ts
// @require ./attr.ts
// @require ./toggle_class.ts
interface Cash {
removeClass ( classes?: string ): this;
}
fn.removeClass = function ( this: Cash, cls?: string ) {
if ( arguments.length ) return this.toggleClass ( cls, false );
return this.attr ( 'class', '' );
};
// @optional ./add_class.ts
// @optional ./attr.ts
// @optional ./has_class.ts
// @optional ./prop.ts
// @optional ./remove_attr.ts
// @optional ./remove_class.ts
// @optional ./remove_prop.ts
// @optional ./toggle_class.ts
// @require ./get_compare_function.ts
// @require ./type_checking.ts
// @require ./variables.ts
type PluckCallback<T> = ( ele: T ) => ArrayLike<Ele>;
function pluck<T, U extends ArrayLike<T> = ArrayLike<T>> ( arr: U, prop: string | PluckCallback<U[0]>, deep?: boolean, until?: Comparator ): Array<Ele> {
const plucked: Array<Ele> = [],
isCallback = isFunction ( prop ),
compare = until && getCompareFunction ( until );
for ( let i = 0, l = arr.length; i < l; i++ ) {
if ( isCallback ) {
const val = prop ( arr[i] );
if ( val.length ) push.apply ( plucked, val );
} else {
let val = arr[i][prop];
while ( val != null ) {
if ( until && compare ( -1, val ) ) break;
plucked.push ( val );
val = deep ? val[prop] : null;
}
}
}
return plucked;
}
// @require ./cash.ts
// @require ./variables.ts
interface CashStatic {
unique<T> ( arr: ArrayLike<T> ): ArrayLike<T>;
}
function unique<T> ( arr: ArrayLike<T> ): ArrayLike<T> {
return arr.length > 1 ? filter.call ( arr, ( item: T, index: number, self: ArrayLike<T> ) => indexOf.call ( self, item ) === index ) : arr;
}
cash.unique = unique;
// @require core/cash.ts
// @require core/unique.ts
// @require ./get.ts
interface Cash {
add ( selector: Selector, context?: Context ): Cash;
}
fn.add = function ( this: Cash, selector: Selector, context?: Context ) {
return cash ( unique ( this.get ().concat ( cash ( selector, context ).get () ) ) );
};
// @require core/type_checking.ts
// @require core/variables.ts
function computeStyle ( ele: EleLoose, prop: string, isVariable?: boolean ): string | undefined {
if ( !isElement ( ele ) ) return;
const style = win.getComputedStyle ( ele, null );
return isVariable ? style.getPropertyValue ( prop ) || undefined : style[prop] || ele.style[prop];
}
// @require ./compute_style.ts
function computeStyleInt ( ele: EleLoose, prop: string ): number {
return parseInt ( computeStyle ( ele, prop ), 10 ) || 0;
}
const cssVariableRe = /^--/;
// @require ./variables.ts
function isCSSVariable ( prop: string ): boolean {
return cssVariableRe.test ( prop );
}
// @require core/camel_case.ts
// @require core/cash.ts
// @require core/each.ts
// @require core/variables.ts
// @require ./is_css_variable.ts
const prefixedProps: { [prop: string]: string } = {},
{style} = div,
vendorsPrefixes = ['webkit', 'moz', 'ms'];
function getPrefixedProp ( prop: string, isVariable: boolean = isCSSVariable ( prop ) ): string {
if ( isVariable ) return prop;
if ( !prefixedProps[prop] ) {
const propCC = camelCase ( prop ),
propUC = `${propCC[0].toUpperCase ()}${propCC.slice ( 1 )}`,
props = ( `${propCC} ${vendorsPrefixes.join ( `${propUC} ` )}${propUC}` ).split ( ' ' );
each ( props, ( i, p ) => {
if ( p in style ) {
prefixedProps[prop] = p;
return false;
}
});
}
return prefixedProps[prop];
};
// @require core/type_checking.ts
// @require ./is_css_variable.ts
const numericProps: { [prop: string]: true | undefined } = {
animationIterationCount: true,
columnCount: true,
flexGrow: true,
flexShrink: true,
fontWeight: true,
gridArea: true,
gridColumn: true,
gridColumnEnd: true,
gridColumnStart: true,
gridRow: true,
gridRowEnd: true,
gridRowStart: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
widows: true,
zIndex: true
};
function getSuffixedValue ( prop: string, value: number | string, isVariable: boolean = isCSSVariable ( prop ) ): string {
return !isVariable && !numericProps[prop] && isNumeric ( value ) ? `${value}px` : value;
}
// @require core/cash.ts
// @require core/type_checking.ts
// @require collection/each.ts
// @require ./helpers/compute_style.ts
// @require ./helpers/get_prefixed_prop.ts
// @require ./helpers/get_suffixed_value.ts
// @require ./helpers/is_css_variable.ts
interface Cash {
css ( prop: string ): string | undefined;
css ( prop: string, value: number | string ): this;
css ( props: Record<string, number | string> ): this;
}
function css ( this: Cash, prop: string ): string | undefined;
function css ( this: Cash, prop: string, value: number | string ): Cash;
function css ( this: Cash, prop: Record<string, number | string> ): Cash;
function css ( this: Cash, prop: string | Record<string, number | string>, value?: number | string ) {
if ( isString ( prop ) ) {
const isVariable = isCSSVariable ( prop );
prop = getPrefixedProp ( prop, isVariable );
if ( arguments.length < 2 ) return this[0] && computeStyle ( this[0], prop, isVariable );
if ( !prop ) return this;
value = getSuffixedValue ( prop, value, isVariable );
return this.each ( ( i, ele ) => {
if ( !isElement ( ele ) ) return;
if ( isVariable ) {
ele.style.setProperty ( prop, value );
} else {
ele.style[prop] = value;
}
});
}
for ( const key in prop ) {
this.css ( key, prop[key] );
}
return this;
};
fn.css = css;
// @optional ./css.ts
// @require core/attempt.ts
// @require core/camel_case.ts
const JSONStringRe = /^\s+|\s+$/;
function getData ( ele: EleLoose, key: string ): any {
const value = ele.dataset[key] || ele.dataset[camelCase ( key )];
if ( JSONStringRe.test ( value ) ) return value;
return attempt ( JSON.parse, value );
}
// @require core/attempt.ts
// @require core/camel_case.ts
function setData ( ele: EleLoose, key: string, value: any ): void {
value = attempt ( JSON.stringify, value );
ele.dataset[camelCase ( key )] = value;
}
// @require core/cash.ts
// @require core/type_checking.ts
// @require collection/each.ts
// @require ./helpers/get_data.ts
// @require ./helpers/set_data.ts
interface Cash {
data (): Record<string, any> | undefined;
data ( name: string ): any;
data ( name: string, value: any ): this;
data ( datas: Record<string, any> ): this;
}
function data ( this: Cash ): Record<string, any> | undefined;
function data ( this: Cash, name: string ): any;
function data ( this: Cash, name: string, value: any ): Cash;
function data ( this: Cash, name: Record<string, any> ): Cash;
function data ( this: Cash, name?: string | Record<string, any>, value?: any ) {
if ( !name ) {
if ( !this[0] ) return;
const datas: { [data: string]: any } = {};
for ( const key in this[0].dataset ) {
datas[key] = getData ( this[0], key );
}
return datas;
}
if ( isString ( name ) ) {
if ( arguments.length < 2 ) return this[0] && getData ( this[0], name );
if ( isUndefined ( value ) ) return this;
return this.each ( ( i, ele ) => { setData ( ele, name, value ) } );
}
for ( const key in name ) {
this.data ( key, name[key] );
}
return this;
}
fn.data = data;
// @optional ./data.ts
function getDocumentDimension ( doc: Document, dimension: 'Width' | 'Height' ): number {
const docEle = doc.documentElement;
return Math.max (
doc.body[`scroll${dimension}`],
docEle[`scroll${dimension}`],
doc.body[`offset${dimension}`],
docEle[`offset${dimension}`],
docEle[`client${dimension}`]
);
}
// @require css/helpers/compute_style_int.ts
function getExtraSpace ( ele: EleLoose, xAxis?: boolean ): number {
return computeStyleInt ( ele, `border${ xAxis ? 'Left' : 'Top' }Width` ) + computeStyleInt ( ele, `padding${ xAxis ? 'Left' : 'Top' }` ) + computeStyleInt ( ele, `padding${ xAxis ? 'Right' : 'Bottom' }` ) + computeStyleInt ( ele, `border${ xAxis ? 'Right' : 'Bottom' }Width` );
}
// @require core/cash.ts
// @require core/each.ts
// @require core/type_checking.ts
// @require core/variables.ts
// @require ./helpers/get_document_dimension.ts
interface Cash {
innerWidth (): number | undefined;
innerHeight (): number | undefined;
outerWidth ( includeMargins?: boolean ): number;
outerHeight ( includeMargins?: boolean ): number;
}
each ( [true, false], ( i, outer?: boolean ) => {
each ( ['Width', 'Height'], ( i, prop: 'Width' | 'Height' ) => {
const name: 'outerWidth' | 'innerHeight' = `${outer ? 'outer' : 'inner'}${prop}`;
fn[name] = function ( this: Cash, includeMargins?: boolean ) {
if ( !this[0] ) return;
if ( isWindow ( this[0] ) ) return outer ? this[0][`inner${prop}`] : this[0].document.documentElement[`client${prop}`];
if ( isDocument ( this[0] ) ) return getDocumentDimension ( this[0], prop );
return this[0][`${outer ? 'offset' : 'client'}${prop}`] + ( includeMargins && outer ? computeStyleInt ( this[0], `margin${ i ? 'Top' : 'Left' }` ) + computeStyleInt ( this[0], `margin${ i ? 'Bottom' : 'Right' }` ) : 0 );
};
});
});
// @require core/cash.ts
// @require core/each.ts
// @require core/type_checking.ts
// @require core/variables.ts
// @require css/helpers/compute_style.ts
// @require css/helpers/get_suffixed_value.ts
// @require ./helpers/get_extra_space.ts
// @require ./helpers/get_document_dimension.ts
interface Cash {
width (): number;
width ( value: number | string ): this;
height (): number;
height ( value: number | string ): this;
}
each ( ['Width', 'Height'], ( index: number, prop: 'Width' | 'Height' ) => {
const propLC = prop.toLowerCase ();
fn[propLC] = function ( this: Cash, value?: number | string ) {
if ( !this[0] ) return isUndefined ( value ) ? undefined : this;
if ( !arguments.length ) {
if ( isWindow ( this[0] ) ) return this[0].document.documentElement[`client${prop}`];
if ( isDocument ( this[0] ) ) return getDocumentDimension ( this[0], prop );
return this[0].getBoundingClientRect ()[propLC] - getExtraSpace ( this[0], !index );
}
const valueNumber = parseInt ( value, 10 );
return this.each ( ( i, ele ) => {
if ( !isElement ( ele ) ) return;
const boxSizing = computeStyle ( ele, 'boxSizing' );
ele.style[propLC] = getSuffixedValue ( propLC, valueNumber + ( boxSizing === 'border-box' ? getExtraSpace ( ele, !index ) : 0 ) );
});
};
});
// @optional ./inner_outer.ts
// @optional ./normal.ts
// @require css/helpers/compute_style.ts
const defaultDisplay: { [tagName: string]: string } = {};
function getDefaultDisplay ( tagName: string ): string {
if ( defaultDisplay[tagName] ) return defaultDisplay[tagName];
const ele = createElement ( tagName );
doc.body.insertBefore ( ele, null );
const display = computeStyle ( ele, 'display' );
doc.body.removeChild ( ele );
return defaultDisplay[tagName] = display !== 'none' ? display : 'block';
}
// @require css/helpers/compute_style.ts
function isHidden ( ele: EleLoose ): boolean {
return computeStyle ( ele, 'display' ) === 'none';
}
const displayProperty = '___cd';
// @require core/cash.ts
// @require core/type_checking.ts
// @require css/helpers/compute_style.ts
// @require ./helpers/get_default_display.ts
// @require ./helpers/variables.ts
interface Cash {
toggle ( force?: boolean ): this;
}
fn.toggle = function ( this: Cash, force?: boolean ) {
return this.each ( ( i, ele ) => {
if ( !isElement ( ele ) ) return;
const show = isUndefined ( force ) ? isHidden ( ele ) : force;
if ( show ) {
ele.style.display = ele[displayProperty] || '';
if ( isHidden ( ele ) ) {
ele.style.display = getDefaultDisplay ( ele.tagName );
}
} else {
ele[displayProperty] = computeStyle ( ele, 'display' );
ele.style.display = 'none';
}
});
};
// @require core/cash.ts
// @require ./toggle.ts
interface Cash {
hide (): this;
}
fn.hide = function ( this: Cash ) {
return this.toggle ( false );
};
// @require core/cash.ts
// @require ./toggle.ts
interface Cash {
show (): this;
}
fn.show = function ( this: Cash ) {
return this.toggle ( true );
};
// @optional ./hide.ts
// @optional ./show.ts
// @optional ./toggle.ts
function hasNamespaces ( ns1: string[], ns2?: string[] ): boolean {
return !ns2 || !some.call ( ns2, ( ns: string ) => ns1.indexOf ( ns ) < 0 );
}
const eventsNamespace = '___ce',
eventsNamespacesSeparator = '.',
eventsFocus: { [event: string]: string | undefined } = { focus: 'focusin', blur: 'focusout' },
eventsHover: { [event: string]: string | undefined } = { mouseenter: 'mouseover', mouseleave: 'mouseout' },
eventsMouseRe = /^(mouse|pointer|contextmenu|drag|drop|click|dblclick)/i;
// @require ./variables.ts
function getEventNameBubbling ( name: string ): string {
return eventsHover[name] || eventsFocus[name] || name;
}
// @require ./variables.ts
function getEventsCache ( ele: EleLoose ): { [event: string]: [string[], string, EventCallback][] } {
return ele[eventsNamespace] = ( ele[eventsNamespace] || {} );
}
// @require core/guid.ts
// @require events/helpers/get_events_cache.ts
function addEvent ( ele: EleLoose, name: string, namespaces: string[], selector: string, callback: EventCallback ): void {
const eventCache = getEventsCache ( ele );
eventCache[name] = ( eventCache[name] || [] );
eventCache[name].push ([ namespaces, selector, callback ]);
ele.addEventListener ( name, callback );
}
// @require ./variables.ts
function parseEventName ( eventName: string ): [string, string[]] {
const parts = eventName.split ( eventsNamespacesSeparator );
return [parts[0], parts.slice ( 1 ).sort ()]; // [name, namespace[]]
}
// @require ./get_events_cache.ts
// @require ./has_namespaces.ts
// @require ./parse_event_name.ts
function removeEvent ( ele: EleLoose, name?: string, namespaces?: string[], selector?: string, callback?: EventCallback ): void {
const cache = getEventsCache ( ele );
if ( !name ) {
for ( name in cache ) {
removeEvent ( ele, name, namespaces, selector, callback );
}
} else if ( cache[name] ) {
cache[name] = cache[name].filter ( ([ ns, sel, cb ]) => {
if ( ( callback && cb.guid !== callback.guid ) || !hasNamespaces ( ns, namespaces ) || ( selector && selector !== sel ) ) return true;
ele.removeEventListener ( name, cb );
});
}
}
// @require core/cash.ts
// @require core/each.ts
// @require core/type_checking.ts
// @require collection/each.ts
// @require ./helpers/get_event_name_bubbling.ts
// @require ./helpers/parse_event_name.ts
// @require ./helpers/remove_event.ts
interface Cash {
off (): this;
off ( events: string ): this;
off ( events: Record<string, EventCallback> ): this;
off ( events: string, callback: EventCallback ): this;
off ( events: string, selector: string, callback: EventCallback ): this;
}
fn.off = function ( this: Cash, eventFullName?: string | Record<string, EventCallback>, selector?: string | EventCallback, callback?: EventCallback ) {
if ( isUndefined ( eventFullName ) ) {
this.each ( ( i, ele ) => {
if ( !isElement ( ele ) && !isDocument ( ele ) && !isWindow ( ele ) ) return;
removeEvent ( ele );
});
} else if ( !isString ( eventFullName ) ) {
for ( const key in eventFullName ) {
this.off ( key, eventFullName[key] );
}
} else {
if ( isFunction ( selector ) ) {
callback = selector;
selector = '';
}
each ( getSplitValues ( eventFullName ), ( i, eventFullName ) => {
const [nameOriginal, namespaces] = parseEventName ( eventFullName ),
name = getEventNameBubbling ( nameOriginal ),
isEventBubblingProxy = ( nameOriginal !== name );
this.each ( ( i, ele ) => {
if ( !isElement ( ele ) && !isDocument ( ele ) && !isWindow ( ele ) ) return;
removeEvent ( ele, name, namespaces, selector, callback );
if ( isEventBubblingProxy ) removeEvent ( ele, nameOriginal, namespaces, selector, callback );
});
});
}
return this;
};
// @require core/cash.ts
// @require core/get_split_values.ts
// @require core/guid.ts
// @require core/matches.ts
// @require core/type_checking.ts
// @require collection/each.ts
// @require ./helpers/variables.ts
// @require ./helpers/add_event.ts
// @require ./helpers/get_event_name_bubbling.ts
// @require ./helpers/has_namespaces.ts
// @require ./helpers/parse_event_name.ts
// @require ./helpers/remove_event.ts
interface Cash {
on ( events: Record<string, EventCallback> ): this;
on ( events: Record<string, EventCallback>, selector: string ): this;
on ( events: Record<string, EventCallback>, data: any ): this;
on ( events: Record<string, EventCallback>, selector: string | null | undefined, data: any ): this;
on ( events: string, callback: EventCallback ): this;
on ( events: string, selector: string, callback: EventCallback ): this;
on ( events: string, data: any, callback: EventCallback ): this;
on ( events: string, selector: string | null | undefined, data: any, callback: EventCallback, _one?: boolean ): this;
}
function on ( this: Cash, eventFullName: Record<string, EventCallback> ): Cash;
function on ( this: Cash, eventFullName: Record<string, EventCallback>, selector: string ): Cash;
function on ( this: Cash, eventFullName: Record<string, EventCallback>, data: any ): Cash;
function on ( this: Cash, eventFullName: Record<string, EventCallback>, selector: string | null | undefined, data: any ): Cash;
function on ( this: Cash, eventFullName: string, callback: EventCallback ): Cash;
function on ( this: Cash, eventFullName: string, selector: string, callback: EventCallback ): Cash;
function on ( this: Cash, eventFullName: string, data: any, callback: EventCallback ): Cash;
function on ( this: Cash, eventFullName: string, selector: string | null | undefined, data: any, callback: EventCallback, _one?: boolean ): Cash;
function on ( this: Cash, eventFullName: Record<string, EventCallback> | string, selector?: any, data?: any, callback?: EventCallback, _one?: boolean ) {
if ( !isString ( eventFullName ) ) {
for ( const key in eventFullName ) {
this.on ( key, selector, data, eventFullName[key], _one );
}
return this;
}
if ( !isString ( selector ) ) {
if ( isUndefined ( selector ) || isNull ( selector ) ) {
selector = '';
} else if ( isUndefined ( data ) ) {
data = selector;
selector = '';
} else {
callback = data;
data = selector;
selector = '';
}
}
if ( !isFunction ( callback ) ) {
callback = data;
data = undefined;
}
if ( !callback ) return this;
each ( getSplitValues ( eventFullName ), ( i, eventFullName ) => {
const [nameOriginal, namespaces] = parseEventName ( eventFullName ),
name = getEventNameBubbling ( nameOriginal ),
isEventBubblingProxy = ( nameOriginal !== name ),
isEventFocus = ( nameOriginal in eventsFocus );
if ( !name ) return;
this.each ( ( i, ele ) => {
if ( !isElement ( ele ) && !isDocument ( ele ) && !isWindow ( ele ) ) return;
const finalCallback = function ( event: Event ) {
if ( isEventBubblingProxy && ( event.___ot ? event.___ot !== nameOriginal : event.type !== nameOriginal || ( event.target[`___i${nameOriginal}`] && ( delete event.target[`___i${nameOriginal}`], event.stopImmediatePropagation (), true ) ) ) ) return;
if ( event.namespace && !hasNamespaces ( namespaces, event.namespace.split ( eventsNamespacesSeparator ) ) ) return;
let thisArg: EventTarget = ele;
if ( selector ) {
let target = event.target;
while ( !matches ( target, selector ) ) {
if ( target === ele ) return;
target = target.parentNode;
if ( !target ) return;
}
thisArg = target;
event.___cd = true; // Delegate
} else if ( isEventFocus && event.___ot === nameOriginal && ele !== event.target && ele.contains ( event.target ) ) {
return;
}
if ( event.___cd ) {
Object.defineProperty ( event, 'currentTarget', {
configurable: true,
get () { // We need to define a getter for this to work everywhere
return thisArg;
}
});
}
Object.defineProperty ( event, 'data', {
configurable: true,
get () {
return data;
}
});
const returnValue = callback.call ( thisArg, event, event.___td );
if ( _one ) {
removeEvent ( ele, name, namespaces, selector, finalCallback );
}
if ( returnValue === false ) {
event.preventDefault ();
event.stopPropagation ();
}
};
finalCallback.guid = callback.guid = ( callback.guid || cash.guid++ );
addEvent ( ele, name, namespaces, selector, finalCallback );
if ( isEventBubblingProxy ) addEvent ( ele, nameOriginal, namespaces, selector, finalCallback );
});
});
return this;
}
fn.on = on;
// @require core/cash.ts
// @require ./on.ts
interface Cash {
one ( events: Record<string, EventCallback> ): this;
one ( events: Record<string, EventCallback>, selector: string ): this;
one ( events: Record<string, EventCallback>, data: any ): this;
one ( events: Record<string, EventCallback>, selector: string | null | undefined, data: any ): this;
one ( events: string, callback: EventCallback ): this;
one ( events: string, selector: string, callback: EventCallback ): this;
one ( events: string, data: any, callback: EventCallback ): this;
one ( events: string, selector: string | null | undefined, data: any, callback: EventCallback ): this;
}
function one ( this: Cash, eventFullName: Record<string, EventCallback> ): Cash;
function one ( this: Cash, eventFullName: Record<string, EventCallback>, selector: string ): Cash;
function one ( this: Cash, eventFullName: Record<string, EventCallback>, data: any ): Cash;
function one ( this: Cash, eventFullName: Record<string, EventCallback>, selector: string | null | undefined, data: any ): Cash;
function one ( this: Cash, eventFullName: string, callback: EventCallback ): Cash;
function one ( this: Cash, eventFullName: string, selector: string, callback: EventCallback ): Cash;
function one ( this: Cash, eventFullName: string, data: any, callback: EventCallback ): Cash;
function one ( this: Cash, eventFullName: string, selector: string | null | undefined, data: any, callback: EventCallback ): Cash;
function one ( this: Cash, eventFullName: Record<string, EventCallback> | string, selector?: any, data?: any, callback?: EventCallback ) {
return this.on ( eventFullName, selector, data, callback, true );
};
fn.one = one;
// @require core/cash.ts
// @require core/variables.ts
interface Cash {
ready ( callback: Function ): this;
}
fn.ready = function ( this: Cash, callback: ( $: typeof cash ) => any ) {
const cb = () => setTimeout ( callback, 0, cash );
if ( doc.readyState !== 'loading' ) {
cb ();
} else {
doc.addEventListener ( 'DOMContentLoaded', cb );
}
return this;
};
// @require core/cash.ts
// @require core/type_checking.ts
// @require core/variables.ts
// @require collection/each.ts
// @require ./helpers/get_event_name_bubbling.ts
// @require ./helpers/parse_event_name.ts
// @require ./helpers/variables.ts
interface Cash {
trigger ( event: Event | string, data?: any ): this;
}
fn.trigger = function ( this: Cash, event: Event | string, data?: any ) {
if ( isString ( event ) ) {
const [nameOriginal, namespaces] = parseEventName ( event ),
name = getEventNameBubbling ( nameOriginal );
if ( !name ) return this;
const type = eventsMouseRe.test ( name ) ? 'MouseEvents' : 'HTMLEvents';
event = doc.createEvent ( type );
event.initEvent ( name, true, true );
event.namespace = namespaces.join ( eventsNamespacesSeparator );
event.___ot = nameOriginal;
}
event.___td = data;
const isEventFocus = ( event.___ot in eventsFocus );
return this.each ( ( i, ele ) => {
if ( isEventFocus && isFunction ( ele[event.___ot] ) ) {
ele[`___i${event.___ot}`] = true; // Ensuring this event gets ignored
ele[event.___ot]();
}
ele.dispatchEvent ( event );
});
};
// @optional ./off.ts
// @optional ./on.ts
// @optional ./one.ts
// @optional ./ready.ts
// @optional ./trigger.ts
// @require core/pluck.ts
// @require core/variables.ts
function getValue ( ele: EleLoose ): string | string[] {
if ( ele.multiple && ele.options ) return pluck ( filter.call ( ele.options, option => option.selected && !option.disabled && !option.parentNode.disabled ), 'value' );
return ele.value || '';
}
const queryEncodeSpaceRe = /%20/g,
queryEncodeCRLFRe = /\r?\n/g;
function queryEncode ( prop: string, value: string ): string {
return `&${encodeURIComponent ( prop )}=${encodeURIComponent ( value.replace ( queryEncodeCRLFRe, '\r\n' ) ).replace ( queryEncodeSpaceRe, '+' )}`;
}
// @require core/cash.ts
// @require core/each.ts
// @require core/type_checking.ts
// @require ./helpers/get_value.ts
// @require ./helpers/query_encode.ts
interface Cash {
serialize (): string;
}
const skippableRe = /file|reset|submit|button|image/i,
checkableRe = /radio|checkbox/i;
fn.serialize = function ( this: Cash ) {
let query = '';
this.each ( ( i, ele ) => {
each ( ele.elements || [ele], ( i, ele: EleLoose ) => {
if ( ele.disabled || !ele.name || ele.tagName === 'FIELDSET' || skippableRe.test ( ele.type ) || ( checkableRe.test ( ele.type ) && !ele.checked ) ) return;
const value = getValue ( ele );
if ( !isUndefined ( value ) ) {
const values = isArray ( value ) ? value : [value];
each ( values, ( i, value ) => {
query += queryEncode ( ele.name, value );
});
}
});
});
return query.slice ( 1 );
};
// @require core/cash.ts
// @require core/each.ts
// @require core/type_checking.ts
// @require collection/each.ts
// @require ./helpers/get_value.ts
interface Cash {
val (): string | string[];
val ( value: string | string[] ): this;
}
function val ( this: Cash ): string | string[];
function val ( this: Cash, value: string | string[] ): Cash;
function val ( this: Cash, value?: string | string[] ) {
if ( !arguments.length ) return this[0] && getValue ( this[0] );
return this.each ( ( i, ele ) => {
const isSelect = ele.multiple && ele.options;
if ( isSelect || checkableRe.test ( ele.type ) ) {
const eleValue = isArray ( value ) ? map.call ( value, String ) : ( isNull ( value ) ? [] : [String ( value )] );
if ( isSelect ) {
each ( ele.options, ( i, option ) => {
option.selected = eleValue.indexOf ( option.value ) >= 0;
}, true );
} else {
ele.checked = eleValue.indexOf ( ele.value ) >= 0;
}
} else {
ele.value = isUndefined ( value ) || isNull ( value ) ? '' : value;
}
});
}
fn.val = val;
// @optional ./serialize.ts
// @optional ./val.ts
// @require core/cash.ts
// @require collection/map.ts
interface Cash {
clone (): this;
}
fn.clone = function ( this: Cash ) {
return this.map ( ( i, ele ) => ele.cloneNode ( true ) );
};
// @require core/cash.ts
// @require core/filtered.ts
// @require collection/each.ts
interface Cash {
detach ( comparator?: Comparator ): this;
}
fn.detach = function ( this: Cash, comparator?: Comparator ) {
filtered ( this, comparator ).each ( ( i, ele ) => {
if ( ele.parentNode ) {
ele.parentNode.removeChild ( ele );
}
});
return this;
};
// @require ./cash.ts
// @require ./variables.ts
// @require ./type_checking.ts
// @require collection/get.ts
// @require manipulation/detach.ts
interface CashStatic {
parseHTML ( html: string ): EleLoose[];
}
const fragmentRe = /^\s*<(\w+)[^>]*>/,
singleTagRe = /^<(\w+)\s*\/?>(?:<\/\1>)?$/;
const containers = {
'*': div,
tr: tbody,
td: tr,
th: tr,
thead: table,
tbody: table,
tfoot: table
};
//TODO: Create elements inside a document fragment, in order to prevent inline event handlers from firing
//TODO: Ensure the created elements have the fragment as their parent instead of null, this also ensures we can deal with detatched nodes more reliably
function parseHTML ( html: string ): EleLoose[] {
if ( !isString ( html ) ) return [];
if ( singleTagRe.test ( html ) ) return [createElement ( RegExp.$1 )];
const fragment = fragmentRe.test ( html ) && RegExp.$1,
container = containers[fragment] || containers['*'];
container.innerHTML = html;
return cash ( container.childNodes ).detach ().get ();
}
cash.parseHTML = parseHTML;
// @optional ./each.ts
// @optional ./extend.ts
// @optional ./find.ts
// @optional ./get_compare_function.ts
// @optional ./get_split_values.ts
// @optional ./guid.ts
// @optional ./parse_html.ts
// @optional ./unique.ts
// @require ./cash.ts
// @require ./type_checking.ts
// @require ./variables.ts
// @require core/cash.ts
// @require collection/each.ts
interface Cash {
empty (): this;
}
fn.empty = function ( this: Cash ) {
return this.each ( ( i, ele ) => {
while ( ele.firstChild ) {
ele.removeChild ( ele.firstChild );
}
});
};
// @require core/cash.ts
// @require core/type_checking.ts
// @require collection/each.ts
interface Cash {
html (): string;
html ( html: string ): this;
}
function html ( this: Cash ): string;
function html ( this: Cash, html: string ): Cash;
function html ( this: Cash, html?: string ) {
if ( !arguments.length ) return this[0] && this[0].innerHTML;
if ( isUndefined ( html ) ) return this;
return this.each ( ( i, ele ) => {
if ( !isElement ( ele ) ) return;
ele.innerHTML = html;
});
}
fn.html = html;
// @require core/cash.ts
// @require core/filtered.ts
// @require events/off.ts
// @require ./detach.ts
interface Cash {
remove ( comparator?: Comparator ): this;
}
fn.remove = function ( this: Cash, comparator?: Comparator ) {
filtered ( this, comparator ).detach ().off ();
return this;
};
// @require core/cash.ts
// @require core/type_checking.ts
// @require collection/each.ts
interface Cash {
text (): string;
text ( text: string ): this;
}
function text ( this: Cash ): string;
function text ( this: Cash, text: string ): Cash;
function text ( this: Cash, text?: string ) {
if ( isUndefined ( text ) ) return this[0] ? this[0].textContent : '';
return this.each ( ( i, ele ) => {
if ( !isElement ( ele ) ) return;
ele.textContent = text
});
};
fn.text = text;
// @require core/cash.ts
interface Cash {
unwrap (): this;
}
fn.unwrap = function ( this: Cash ) {
this.parent ().each ( ( i, ele ) => {
if ( ele.tagName === 'BODY' ) return;
const $ele = cash ( ele );
$ele.replaceWith ( $ele.children () );
});
return this;
};
// @require core/cash.ts
// @require core/variables.ts
interface Cash {
offset (): undefined | {
top: number,
left: number
};
}
fn.offset = function ( this: Cash ) {
const ele = this[0];
if ( !ele ) return;
const rect = ele.getBoundingClientRect ();
return {
top: rect.top + win.pageYOffset,
left: rect.left + win.pageXOffset
};
};
// @require core/cash.ts
// @require collection/map.ts
// @require css/helpers/compute_style.ts
interface Cash {
offsetParent (): Cash;
}
fn.offsetParent = function ( this: Cash ) {
return this.map ( ( i, ele ) => {
let offsetParent = ele.offsetParent;
while ( offsetParent && computeStyle ( offsetParent, 'position' ) === 'static' ) {
offsetParent = offsetParent.offsetParent;
}
return offsetParent || docEle;
});
};
// @require core/cash.ts
// @require core/type_checking.ts
// @require css/helpers/compute_style.ts
// @require css/helpers/compute_style_int.ts
// @require ./offset.ts
interface Cash {
position (): undefined | {
top: number,
left: number
};
}
fn.position = function ( this: Cash ) {
const ele = this[0];
if ( !ele ) return;
const isFixed = ( computeStyle ( ele, 'position' ) === 'fixed' ),
offset = isFixed ? ele.getBoundingClientRect () : this.offset ();
if ( !isFixed ) {
const doc = ele.ownerDocument;
let offsetParent = ele.offsetParent || doc.documentElement;
while ( ( offsetParent === doc.body || offsetParent === doc.documentElement ) && computeStyle ( offsetParent, 'position' ) === 'static' ) {
offsetParent = offsetParent.parentNode;
}
if ( offsetParent !== ele && isElement ( offsetParent ) ) {
const parentOffset = cash ( offsetParent ).offset ();
offset.top -= parentOffset.top + computeStyleInt ( offsetParent, 'borderTopWidth' );
offset.left -= parentOffset.left + computeStyleInt ( offsetParent, 'borderLeftWidth' );
}
}
return {
top: offset.top - computeStyleInt ( ele, 'marginTop' ),
left: offset.left - computeStyleInt ( ele, 'marginLeft' )
};
};
// @optional ./offset.ts
// @optional ./offset_parent.ts
// @optional ./position.ts
// @require core/cash.ts
// @require core/filtered.ts
// @require core/pluck.ts
// @require core/unique.ts
// @require core/variables.ts
// @require collection/each.ts
interface Cash {
children ( comparator?: Comparator ): Cash;
}
fn.children = function ( this: Cash, comparator?: Comparator ) {
return filtered ( cash ( unique ( pluck ( this, ele => ele.children ) ) ), comparator );
};
// @require core/cash.ts
// @require core/pluck.ts
// @require core/unique.ts
// @require collection/each.ts
interface Cash {
contents (): Cash;
}
fn.contents = function ( this: Cash ) {
return cash ( unique ( pluck ( this, ele => ele.tagName === 'IFRAME' ? [ele.contentDocument] : ( ele.tagName === 'TEMPLATE' ? ele.content.childNodes : ele.childNodes ) ) ) );
};
// @require core/cash.ts
// @require core/pluck.ts
// @require core/unique.ts
// @require core/find.ts
// @require core/variables.ts
interface Cash {
find ( selector: string ): Cash;
}
fn.find = function ( this: Cash, selector: string ) {
return cash ( unique ( pluck ( this, ele => find ( selector, ele ) ) ) );
};
// @require core/variables.ts
// @require collection/filter.ts
// @require traversal/find.ts
const HTMLCDATARe = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
scriptTypeRe = /^$|^module$|\/(java|ecma)script/i,
scriptAttributes: ('type' | 'src' | 'nonce' | 'noModule')[] = ['type', 'src', 'nonce', 'noModule'];
function evalScripts ( node: Node, doc: Document ): void {
const collection = cash ( node );
collection.filter ( 'script' ).add ( collection.find ( 'script' ) ).each ( ( i, ele: HTMLScriptElement ) => {
if ( scriptTypeRe.test ( ele.type ) && docEle.contains ( ele ) ) { // The script type is supported // The element is attached to the DOM // Using `documentElement` for broader browser support
const script = createElement ( 'script' );
script.text = ele.textContent.replace ( HTMLCDATARe, '' );
each ( scriptAttributes, ( i, attr ) => {
if ( ele[attr] ) script[attr] = ele[attr];
});
doc.head.insertBefore ( script, null );
doc.head.removeChild ( script );
}
});
}
// @require ./eval_scripts.ts
function insertElement ( anchor: EleLoose, target: EleLoose, left?: boolean, inside?: boolean, evaluate?: boolean ): void {
if ( inside ) { // prepend/append
anchor.insertBefore ( target, left ? anchor.firstChild : null );
} else { // before/after
anchor.parentNode.insertBefore ( target, left ? anchor : anchor.nextSibling );
}
if ( evaluate ) {
evalScripts ( target, anchor.ownerDocument );
}
}
// @require ./insert_element.ts
function insertSelectors<T extends ArrayLike<EleLoose> = ArrayLike<EleLoose>> ( selectors: ArrayLike<Selector>, anchors: T, inverse?: boolean, left?: boolean, inside?: boolean, reverseLoop1?: boolean, reverseLoop2?: boolean, reverseLoop3?: boolean ): T {
each ( selectors, ( si, selector: Selector ) => {
each ( cash ( selector ), ( ti, target ) => {
each ( cash ( anchors ), ( ai, anchor ) => {
const anchorFinal = inverse ? target : anchor,
targetFinal = inverse ? anchor : target,
indexFinal = inverse ? ti : ai;
insertElement ( anchorFinal, !indexFinal ? targetFinal : targetFinal.cloneNode ( true ), left, inside, !indexFinal );
}, reverseLoop3 );
}, reverseLoop2 );
}, reverseLoop1 );
return anchors;
}
// @require core/cash.ts
// @require ./helpers/insert_selectors.ts
interface Cash {
after ( ...selectors: Selector[] ): this;
}
fn.after = function ( this: Cash ) {
return insertSelectors ( arguments, this, false, false, false, true, true );
};
// @require core/cash.ts
// @require ./helpers/insert_selectors.ts
interface Cash {
append ( ...selectors: Selector[] ): this;
}
fn.append = function ( this: Cash ) {
return insertSelectors ( arguments, this, false, false, true );
};
// @require core/cash.ts
// @require ./helpers/insert_selectors.ts
interface Cash {
appendTo ( selector: Selector ): this;
}
fn.appendTo = function ( this: Cash, selector: Selector ) {
return insertSelectors ( arguments, this, true, false, true );
};
// @require core/cash.ts
// @require ./helpers/insert_selectors.ts
interface Cash {
before ( ...selectors: Selector[] ): this;
}
fn.before = function ( this: Cash ) {
return insertSelectors ( arguments, this, false, true );
};
// @require core/cash.ts
// @require ./helpers/insert_selectors.ts
interface Cash {
insertAfter ( selector: Selector ): this;
}
fn.insertAfter = function ( this: Cash, selector: Selector ) {
return insertSelectors ( arguments, this, true, false, false, false, false, true );
};
// @require core/cash.ts
// @require ./helpers/insert_selectors.ts
interface Cash {
insertBefore ( selector: Selector ): this;
}
fn.insertBefore = function ( this: Cash, selector: Selector ) {
return insertSelectors ( arguments, this, true, true );
};
// @require core/cash.ts
// @require ./helpers/insert_selectors.ts
interface Cash {
prepend ( ...selectors: Selector[] ): this;
}
fn.prepend = function ( this: Cash ) {
return insertSelectors ( arguments, this, false, true, true, true, true );
};
// @require core/cash.ts
// @require ./helpers/insert_selectors.ts
interface Cash {
prependTo ( selector: Selector ): this;
}
fn.prependTo = function ( this: Cash, selector: Selector ) {
return insertSelectors ( arguments, this, true, true, true, false, false, true );
};
// @require core/cash.ts
// @require ./before.ts
// @require ./remove.ts
interface Cash {
replaceWith ( selector: Selector ): this;
}
fn.replaceWith = function ( this: Cash, selector: Selector ) {
return this.before ( selector ).remove ();
};
// @require core/cash.ts
// @require ./replace_with.ts
interface Cash {
replaceAll ( selector: Selector ): this;
}
fn.replaceAll = function ( this: Cash, selector: Selector ) {
cash ( selector ).replaceWith ( this );
return this;
};
// @require core/cash.ts
// @require collection/first.ts
// @require manipulation/append_to.ts
// @require manipulation/before.ts
interface Cash {
wrapAll ( selector?: Selector ): this;
}
fn.wrapAll = function ( this: Cash, selector?: Selector ) {
let structure = cash ( selector ),
wrapper: Element = structure[0];
while ( wrapper.children.length ) wrapper = wrapper.firstElementChild;
this.first ().before ( structure );
return this.appendTo ( wrapper );
};
// @require core/cash.ts
// @require collection/each.ts
// @require ./wrap_all.ts
interface Cash {
wrap ( selector?: Selector ): this;
}
fn.wrap = function ( this: Cash, selector?: Selector ) {
return this.each ( ( i, ele ) => {
const wrapper = cash ( selector )[0];
cash ( ele ).wrapAll ( !i ? wrapper : wrapper.cloneNode ( true ) );
});
};
// @require core/cash.ts
// @require collection/first.ts
// @require manipulation/append_to.ts
interface Cash {
wrapInner ( selector?: Selector ): this;
}
fn.wrapInner = function ( this: Cash, selector?: Selector ) {
return this.each ( ( i, ele ) => {
const $ele = cash ( ele ),
contents = $ele.contents ();
contents.length ? contents.wrapAll ( selector ) : $ele.append ( selector );
});
};
// @optional ./after.ts
// @optional ./append.ts
// @optional ./append_to.ts
// @optional ./before.ts
// @optional ./clone.ts
// @optional ./detach.ts
// @optional ./empty.ts
// @optional ./html.ts
// @optional ./insert_after.ts
// @optional ./insert_before.ts
// @optional ./prepend.ts
// @optional ./prepend_to.ts
// @optional ./remove.ts
// @optional ./replace_all.ts
// @optional ./replace_with.ts
// @optional ./text.ts
// @optional ./unwrap.ts
// @optional ./wrap.ts
// @optional ./wrap_all.ts
// @optional ./wrap_inner.ts
// @require core/cash.ts
// @require core/find.ts
// @require core/type_checking.ts
// @require collection/filter.ts
interface Cash {
has ( selector: string | Node ): Cash;
}
fn.has = function ( this: Cash, selector: string | Node ) {
const comparator = isString ( selector )
? ( i: number, ele: EleLoose ) => find ( selector, ele ).length
: ( i: number, ele: EleLoose ) => ele.contains ( selector );
return this.filter ( comparator );
};
// @require core/cash.ts
// @require core/get_compare_function.ts
// @require core/variables.ts
// @require collection/each.ts
interface Cash {
is ( comparator?: Comparator ): boolean;
}
fn.is = function ( this: Cash, comparator?: Comparator ) {
const compare = getCompareFunction ( comparator );
return some.call ( this, ( ele: EleLoose, i: number ) => compare.call ( ele, i, ele ) );
};
// @require core/cash.ts
// @require core/filtered.ts
// @require core/pluck.ts
// @require core/unique.ts
interface Cash {
next ( comparator?: Comparator, _all?: boolean, _until?: Comparator ): Cash;
}
fn.next = function ( this: Cash, comparator?: Comparator, _all?: boolean, _until?: Comparator ) {
return filtered ( cash ( unique ( pluck ( this, 'nextElementSibling', _all, _until ) ) ), comparator );
};
// @require ./next.ts
interface Cash {
nextAll ( comparator?: Comparator): Cash;
}
fn.nextAll = function ( this: Cash, comparator?: Comparator ) {
return this.next ( comparator, true );
};
// @require ./next.ts
interface Cash {
nextUntil ( until?: Comparator, comparator?: Comparator): Cash;
}
fn.nextUntil = function ( this: Cash, until?: Comparator, comparator?: Comparator ) {
return this.next ( comparator, true, until );
};
// @require core/cash.ts
// @require core/get_compare_function.ts
// @require core/type_checking.ts
// @require collection/filter.ts
interface Cash {
not ( comparator?: Comparator ): Cash;
}
fn.not = function ( this: Cash, comparator?: Comparator ) {
const compare = getCompareFunction ( comparator );
return this.filter ( ( i: number, ele: EleLoose ) => ( !isString ( comparator ) || isElement ( ele ) ) && !compare.call ( ele, i, ele ) );
};
// @require core/cash.ts
// @require core/filtered.ts
// @require core/pluck.ts
// @require core/unique.ts
interface Cash {
parent ( comparator?: Comparator ): Cash;
}
fn.parent = function ( this: Cash, comparator?: Comparator ) {
return filtered ( cash ( unique ( pluck ( this, 'parentNode' ) ) ), comparator );
};
// @require core/cash.ts
// @require core/variables.ts
// @require traversal/children.ts
// @require traversal/parent.ts
// @require ./get.ts
interface Cash {
index ( selector?: Selector ): number;
}
fn.index = function ( this: Cash, selector?: Selector ) {
const child = selector ? cash ( selector )[0] : this[0],
collection = selector ? this : cash ( child ).parent ().children ();
return indexOf.call ( collection, child );
};
// @optional ./add.ts
// @optional ./each.ts
// @optional ./eq.ts
// @optional ./filter.ts
// @optional ./first.ts
// @optional ./get.ts
// @optional ./index_fn.ts
// @optional ./last.ts
// @optional ./map.ts
// @optional ./slice.ts
// @require core/cash.ts
// @require collection/filter.ts
// @require ./is.ts
// @require ./parent.ts
interface Cash {
closest ( comparator?: Comparator ): Cash;
}
fn.closest = function ( this: Cash, comparator?: Comparator ) {
const filtered = this.filter ( comparator );
if ( filtered.length ) return filtered;
const $parent = this.parent ();
if ( !$parent.length ) return filtered;
return $parent.closest ( comparator );
};
// @require core/cash.ts
// @require core/filtered.ts
// @require core/matches.ts
// @require core/unique.ts
// @require core/variables.ts
// @require collection/each.ts
interface Cash {
parents ( comparator?: Comparator, _until?: Comparator ): Cash;
}
fn.parents = function ( this: Cash, comparator?: Comparator, _until?: Comparator ) {
return filtered ( cash ( unique ( pluck ( this, 'parentElement', true, _until ) ) ), comparator );
};
// @require ./parents.ts
interface Cash {
parentsUntil ( until?: Comparator, comparator?: Comparator): Cash;
}
fn.parentsUntil = function ( this: Cash, until?: Comparator, comparator?: Comparator ) {
return this.parents ( comparator, until );
};
// @require core/cash.ts
// @require core/filtered.ts
// @require core/pluck.ts
// @require core/unique.ts
interface Cash {
prev ( comparator?: Comparator, _all?: boolean, _until?: Comparator ): Cash;
}
fn.prev = function ( this: Cash, comparator?: Comparator, _all?: boolean, _until?: Comparator ) {
return filtered ( cash ( unique ( pluck ( this, 'previousElementSibling', _all, _until ) ) ), comparator );
};
// @require ./prev.ts
interface Cash {
prevAll ( comparator?: Comparator ): Cash;
}
fn.prevAll = function ( this: Cash, comparator?: Comparator ) {
return this.prev ( comparator, true );
};
// @require ./prev.ts
interface Cash {
prevUntil ( until?: Comparator, comparator?: Comparator ): Cash;
}
fn.prevUntil = function ( this: Cash, until?: Comparator, comparator?: Comparator ) {
return this.prev ( comparator, true, until );
};
// @require core/cash.ts
// @require core/filtered.ts
// @require core/pluck.ts
// @require core/unique.ts
// @require core/variables.ts
// @require collection/each.ts
// @require ./children.ts
// @require ./not.ts
// @require ./parent.ts
interface Cash {
siblings ( comparator?: Comparator ): Cash;
}
fn.siblings = function ( this: Cash, comparator?: Comparator ) {
return filtered ( cash ( unique ( pluck ( this, ele => cash ( ele ).parent ().children ().not ( ele ) ) ) ), comparator );
};
// @optional ./children.ts
// @optional ./closest.ts
// @optional ./contents.ts
// @optional ./find.ts
// @optional ./has.ts
// @optional ./is.ts
// @optional ./next.ts
// @optional ./next_all.ts
// @optional ./next_until.ts
// @optional ./not.ts
// @optional ./parent.ts
// @optional ./parents.ts
// @optional ./parents_until.ts
// @optional ./prev.ts
// @optional ./prev_all.ts
// @optional ./prev_until.ts
// @optional ./siblings.ts
// @optional attributes/index.ts
// @optional collection/index.ts
// @optional css/index.ts
// @optional data/index.ts
// @optional dimensions/index.ts
// @optional effects/index.ts
// @optional events/index.ts
// @optional forms/index.ts
// @optional manipulation/index.ts
// @optional offset/index.ts
// @optional traversal/index.ts
// @require core/index.ts
// @priority -100
// @require ./cash.ts
export default cash;
export {Cash, CashStatic, Ele as Element, Selector, Comparator, Context};