openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Oquery.js (7050B)


      1 /*! OQuery */
      2 /**
      3  * OQuery is a very light ES6-ready replacement for JQuery
      4  *
      5  */
      6 let query = function (selector ) {
      7 
      8 	if   ( typeof selector === 'string' )
      9 		return query.createQuery( document.querySelectorAll(selector) );
     10 	else if ( selector instanceof HTMLElement )
     11 		return query.createQuery([selector] );
     12 	else if ( selector instanceof OQuery )
     13 		return selector;
     14 	else
     15 		//console.warn( new Error("Illegal argument '"+selector+"' of type "+(typeof selector)) );
     16 		return query.createQuery( [] );
     17 
     18 }
     19 
     20 query.createQuery = function(nodeList ) {
     21 	return new OQuery( nodeList );
     22 }
     23 
     24 query.create = function(tagName ) {
     25 	return query.createQuery( [document.createElement( tagName )] );
     26 };
     27 
     28 query.id = function(id ) {
     29 	let el = document.getElementById( id );
     30 	if   ( el )
     31 		return query.createQuery( [el] );
     32 	else
     33 		return query.createQuery( [] );
     34 };
     35 
     36 query.one = function(selector ) {
     37 	return query.createQuery( [document.querySelector( selector )] );
     38 };
     39 
     40 query.extend = function() {
     41 	for(let i=1; i<arguments.length; i++)
     42 		for(let key in arguments[i])
     43 			if(arguments[i].hasOwnProperty(key))
     44 				arguments[0][key] = arguments[i][key];
     45 	return arguments[0];
     46 }
     47 
     48 export default query;
     49 
     50 
     51 export class OQuery {
     52 
     53 	static fn = OQuery.prototype;
     54 	
     55 	createNew(nodeList) {
     56 		return new OQuery(nodeList)
     57 	};
     58 
     59 	constructor( nodeList ) {
     60 
     61 		this.nodes = Array.isArray(nodeList) ? nodeList : Array.from(nodeList)
     62 	}
     63 
     64 	get( idx ) {
     65 		return this.nodes[idx];
     66 	}
     67 	first() {
     68 		return this.createNew( this.nodes.length > 0 ? [this.nodes[0]] : [] );
     69 	};
     70 
     71 
     72 	/**
     73 	 * 'length' property is the size of all nodes in this object.
     74 	 * this property is readonly.
     75 	 *
     76 	 * @return size of all elements
     77 	 */
     78 	get length() {
     79 		return this.nodes.length;
     80 	}
     81 
     82 
     83 	/**
     84 	 * Reads the direct parent of all nodes, optionally filtered by a selector.
     85 	 * @param selector
     86 	 * @return {OQuery}
     87 	 */
     88 	parent( selector = null ) {
     89 		return this.createNew(
     90 			this.nodes.map(node => node.parentElement )
     91 				.filter( node => !!node ) // Filter non-existent parents
     92 				.filter( node => !selector || node.matches(selector) )
     93 		);
     94 	};
     95 
     96 
     97 	/**
     98 	 * Reads all parents of all nodes, optionally filtered by a selector.
     99 	 *
    100 	 * @param selector
    101 	 * @return {OQuery}
    102 	 */
    103 	parents( selector = null ) {
    104 		let parents = [];
    105 		for( let node of this.nodes )
    106 			while (node) {
    107 				node = node.parentElement;
    108 				if   ( node && (!selector || node.matches(selector)) )
    109 					parents.unshift(node);
    110 			}
    111 		return this.createNew( parents );
    112 	};
    113 
    114 
    115 	/**
    116 	 * reads the closest anchestor that meets the selector.
    117 	 *
    118 	 * @param selector
    119 	 * @return {OQuery}
    120 	 */
    121 	closest( selector ) {
    122 		return this.createNew( this.nodes.map(node => node.closest( selector ) ).filter( node => node !== null ) );
    123 	};
    124 
    125 	children( selector ) {
    126 		let result = [];
    127 		for( let node of this.nodes )
    128 			result = result.concat( Array.from(node.children).filter( node => !selector || node.matches(selector) ) );
    129 		return this.createNew( result );
    130 	};
    131 
    132 	find(selector) {
    133 		let result = [];
    134 		for( let node of this.nodes )
    135 			result = result.concat( Array.from(node.querySelectorAll(selector)) );
    136 		return this.createNew( result );
    137 	};
    138 
    139 	text( value ) {
    140 
    141 		if   ( typeof value !== 'undefined'  ) {
    142 			this.nodes.forEach(node => node.textContent = value );
    143 			return this;
    144 		}
    145 		else {
    146 			return this.nodes[0].textContent;
    147 		}
    148 	};
    149 
    150 	addClass( name ) {
    151 		this.nodes.forEach(node => node.classList.add( name ) );
    152 		return this;
    153 	};
    154 
    155 	removeClass ( name )  {
    156 
    157 		this.nodes.forEach(
    158 			node => node.classList.remove( name )
    159 		);
    160 		return this;
    161 	};
    162 
    163 	hasClass( name ) {
    164 		for( let node of this.nodes )
    165 			if  ( node.classList.contains( name ) )
    166 				return true;
    167 
    168 		return false;
    169 	};
    170 
    171 	toggleClass( name ) {
    172 		if   ( this.hasClass( name ) )
    173 			this.removeClass( name );
    174 		else
    175 			this.addClass( name );
    176 
    177 		return this;
    178 	};
    179 
    180 
    181 	remove() {
    182 		this.nodes.forEach(node => node.remove() );
    183 		return this;
    184 	};
    185 
    186 
    187 
    188 	click ( handler ) {
    189 		this.on( 'click',handler );
    190 		return this;
    191 	};
    192 	dblclick ( handler ) {
    193 		this.on( 'dblclick',handler );
    194 		return this;
    195 	};
    196 	mouseover( handler ) {
    197 		this.on( 'mouseover',handler );
    198 		return this;
    199 	};
    200 	keypress( handler ) {
    201 		this.on( 'keypress',handler );
    202 		return this;
    203 	};
    204 	keyup( handler ) {
    205 		this.on( 'keyup',handler );
    206 		return this;
    207 	};
    208 	submit( handler ) {
    209 		this.on( 'submit',handler );
    210 		return this;
    211 	}
    212 	change( handler ) {
    213 		this.on( 'change',handler )
    214 		return this;
    215 	}
    216 	input( handler ) {
    217 		this.on( 'input',handler )
    218 		return this;
    219 	}
    220 
    221 
    222 
    223 	on ( event,handler ) {
    224 		if   ( typeof handler !== 'undefined')
    225 			this.nodes.forEach(node => node.addEventListener( event,handler.bind(node) ) );
    226 		else
    227 			this.nodes.forEach(node => node.dispatchEvent( new Event(event) ) );
    228 		return this;
    229 	};
    230 
    231 	each( handler ) {
    232 		let idx = -1;
    233 		for( let node of this.nodes )
    234 			if   ( handler.call(node,idx,node) === false )
    235 				break;
    236 
    237 		return this;
    238 	}
    239 
    240 	toggle( handler ) {
    241 		let idx = -1;
    242 		for( let node of this.nodes )
    243 			if   ( handler.call(node,idx,node) === false )
    244 				node.style.display = 'none';
    245 			else
    246 				node.style.display = '';
    247 
    248 		return this;
    249 	}
    250 
    251 	hide() {
    252 		this.nodes.forEach(node => node.style.display = 'none' );
    253 		return this;
    254 	}
    255 
    256 	show() {
    257 		this.nodes.forEach(node => node.style.display = '' );
    258 		return this;
    259 	}
    260 
    261 	append( el ) {
    262 		this.nodes.forEach(node => el.nodes.forEach(elnode => node.appendChild(elnode) ) );
    263 		return this;
    264 	}
    265 
    266 	appendTo( el ) {
    267 		let to = query( el );
    268 		to.append( this )
    269 		return this;
    270 	}
    271 
    272 	attr( name,value ) {
    273 		if   ( typeof value === 'undefined' )
    274 			return this.nodes.length > 0 ? this.nodes[0].getAttribute(name) : '';
    275 
    276 		this.nodes.forEach(node => node.setAttribute(name,value) );
    277 		return this;
    278 	}
    279 
    280 	data( name,value) {
    281 		if   ( typeof value === 'undefined' )
    282 			if   ( typeof name === 'undefined' )
    283 				return this.nodes.length > 0 ? this.nodes[0].dataset : {};
    284 			else
    285 				return this.nodes.length > 0 ? this.nodes[0].dataset[name] : null;
    286 
    287 		this.nodes.forEach(node => node.dataset[name] = value );
    288 		return this;
    289 
    290 	}
    291 
    292 	html( value ) {
    293 		if   ( typeof value === 'undefined')
    294 			return this.nodes.length > 0 ? this.nodes[0].innerHTML : '';
    295 
    296 		this.nodes.forEach(node => node.innerHTML = value );
    297 		return this;
    298 	}
    299 
    300 	val( value = null ) {
    301 		if   ( value !== null ) {
    302 			this.nodes.forEach(node => node.value = value );
    303 			return this;
    304 		}
    305 		else
    306 			return this.nodes.length > 0 ? this.nodes[0].value : '';
    307 	}
    308 
    309 	empty() {
    310 		this.nodes.forEach(node => {
    311 			while (node.firstChild) {
    312 				node.removeChild(node.firstChild);
    313 			}
    314 		} );
    315 
    316 		return this;
    317 	}
    318 
    319 	is( selector ) {
    320 		for( let node of this.nodes )
    321 			if   ( node.matches(selector) )
    322 				return true;
    323 
    324 		return false;
    325 	}
    326 
    327 	toArray() {
    328 		return this.nodes;
    329 	}
    330 
    331 	eq( index ) {
    332 		return this.createNew( [ this.nodes[index] ] );
    333 	}
    334 
    335 	index() {
    336 		if   ( this.nodes.length == 0 )
    337 			return -1;
    338 
    339 		let node = this.nodes[0];
    340 
    341 		let children = node.parentNode.childNodes;
    342 		let num = 0;
    343 		for (let i=0; i<children.length; i++) {
    344 			if ( children[i] == node) return num;
    345 			if ( children[i].nodeType==1) num++;
    346 		}
    347 		return -1;
    348 	}
    349 
    350 }