var Hiqus= new function (){<br><br>Version: 1<br>Description: "parse, serialize and merge any 'HIerarhical QUery String'" <br>License: 'public domain' <br><br>Implementation:<br><br> var sepHiqusList= '/|; &' <br> var sepPathList= '=:_' <br><br> var sepHiqusDefault= sepHiqusList.charAt(0)<br> var sepPathDefault= sepPathList.charAt(0)<br><br> var sepHiqusRegexp= RegExp( '[' + sepHiqusList + ']' , 'g' )<br> var sepPathRegexp= RegExp( '[' + sepPathList + ']' , 'g' )<br><br> var encode= function ( str ){<br> return encodeURIComponent( str ).split( '_' ).join( '%5F' )<br>}<br> var decode= function ( str ){<br> return decodeURIComponent( str )<br>}<br><br> var splitHiqus= function ( str ){<br> return str.split( sepHiqusRegexp )<br>}<br> var splitPath= function ( str ){<br> var path= String( str ).split( sepPathRegexp )<br> for ( var j= path.length - 1; j >= 0; --j ) path[ j ]= decode( path[ j ] )<br> return path<br>}<br><br> var get= function ( ){<br> var obj= this <br> for ( var i= 0, len= arguments.length; i < len; ++i ){<br> var name= arguments[ i ]<br> if ( !name ) throw new Error( 'name is empty' )<br> obj= obj[ name ]<br> if ( typeof obj !== 'object' ) return obj<br> }<br> return obj<br>}<br><br> var placin= function ( ){<br> var obj= this <br> for ( var i= 0, len= arguments.length; i < len; ++i ){<br> var name= arguments[ i ]<br> if ( name && Number( name ) != name ){<br> var o= obj[ name ]<br> if (( !o )||( typeof o !== 'object' )) o= obj[ name ]= []<br> } else {<br> var o= []<br> obj.push( o )<br> }<br> obj= o<br> }<br> return obj<br>}<br><br> var put= function ( ){<br> var obj= this <br> var len= arguments.length<br> if ( !len ) return this <br> var val= arguments[ len - 1 ]<br> var key= arguments[ len - 2 ]<br> if ( len > 2 ){<br> var path= []<br> for ( var i= len - 2; i-- ;) path[ i ]= arguments[ i ]<br> obj= placin.apply( obj, path )<br> }<br> if ( typeof val === 'object' ){<br> var v= ( len === 1 ) ? obj : placin.call( obj, key )<br> for ( var i in val ) if ( val.hasOwnProperty( i ) ) put.call( v, i, val[ i ] )<br> } else {<br> val= String( val )<br> if ( !key || Number( key ) == key ) obj.push( val )<br> else obj[ key ]= val<br> }<br> return this <br>}<br><br> var parsin= function ( str ){ <br> var chunks= splitHiqus( str )<br> for ( var i= 0, len= chunks.length; i < len; ++i ){<br> var path= chunks[i]<br> if ( !path ) continue <br> path= splitPath( path )<br> put.apply( this , path )<br> }<br> return this <br>}<br><br> var serialize= function ( prefix, obj ){<br> if ( !obj ) return '' <br> if ( typeof obj !== 'object' ){<br> if ( prefix === sepPathDefault ) prefix= '' <br> return prefix+= encode( obj )<br> }<br> var list= []<br> for ( var key in obj ) if ( obj.hasOwnProperty( key ) ){<br> var k= ( Number( key ) == key ) ? '' : encode( key )<br> var chunk= serialize( prefix + k + sepPathDefault, obj[ key ] )<br> if ( chunk ) list.push( chunk )<br> }<br> return list.join( sepHiqusDefault )<br>}<br><br> var Hiqus= function ( ){<br> var hiqus= ( this instanceof Hiqus ) ? this : new Hiqus<br> var data= placin.call( hiqus, '_data' )<br> for ( var i= 0, len= arguments.length; i < len; ++i ){<br> var arg= arguments[i]<br> if ( arg instanceof Hiqus ) arg= arg._data<br> var invoke= ( Object( arg ) instanceof String ) ? parsin : put<br> invoke.call( data, arg )<br> }<br> return hiqus<br>}<br><br>Hiqus.prototype= new function (){<br><br> this .put= function (){<br> var hiqus= Hiqus( this )<br> put.apply( hiqus._data, arguments )<br> return hiqus<br> }<br> <br> this .get= function ( ){<br> var val= get.apply( this ._data, arguments )<br> if ( typeof val === 'object' ) val= put.call( [], val )<br> return val<br> }<br> <br> this .sub= function (){<br> var hiqus= Hiqus()<br> var val= get.apply( this ._data, arguments )<br> if ( typeof val !== 'object' ) val= [ val ]<br> hiqus._data= val<br> return hiqus<br> }<br><br> this .toString = function (){<br> var str= serialize( '' , this ._data )<br> this .toString= function (){ return str }<br> return str<br> }<br><br>}<br><br>Export: return Hiqus<br><br>Usage:<br><br>alert(<br> Hiqus<br> ( Hiqus( '| a:b:c:1 / a:b: ; a:b::c & a=b__d' )<br> .sub( 'a' , 'b' )<br> .put( [ 'e' , 'f' ] )<br> , 'g/h' <br> )<br> .get( 4 )<br>) // alerts 'g' <br><br>}
;( function ( x, y ){<br> if ( '' + x == y ) return arguments.callee<br> console.log( x, y )<br> throw new Error( 'fail test: [ ' + x + ' ]!=[ ' + y + ' ]' )<br>})<br><br>( Hiqus( ), '' )<br>( Hiqus( {} ), '' )<br>( Hiqus( [] ), '' )<br>( Hiqus( [1] ), '1' )<br>( Hiqus( { '' :1} ), '1' )<br>( Hiqus( { '' :{ '' :1}} ), '==1' )<br>( Hiqus( [1,2] ), '1/2' )<br>( Hiqus( {1:2} ), '2' )<br>( Hiqus( {a:1} ), 'a=1' )<br>( Hiqus( { 'a_b' :1} ), 'a%5Fb=1' )<br>( Hiqus( {a:{b:1}} ), 'a=b=1' )<br>( Hiqus( {a:1,b:2} ), 'a=1/b=2' )<br>( Hiqus( {a:1},{b:2} ), 'a=1/b=2' )<br>( Hiqus( {a:1}, 'b:2' ), 'a=1/b=2' )<br>( Hiqus( {a:1},{b:2} ), new Hiqus( {a:1},{b:2} ) )<br>( Hiqus( Hiqus({a:1}), Hiqus({b:2}) ), 'a=1/b=2' )<br><br>( Hiqus( '' ), '' )<br>( Hiqus( 'a' ), 'a' )<br>( Hiqus( '=a' ), 'a' )<br>( Hiqus( '==1' ), '==1' )<br>( Hiqus( 'a=1' ), 'a=1' )<br>( Hiqus( 'a:1' ), 'a=1' )<br>( Hiqus( 'a_1' ), 'a=1' )<br>( Hiqus( 'a=b=1' ), 'a=b=1' )<br>( Hiqus( 'a=1/b=2' ), 'a=1/b=2' )<br>( Hiqus( 'a=1;b=2' ), 'a=1/b=2' )<br>( Hiqus( 'a=1 b=2' ), 'a=1/b=2' )<br>( Hiqus( 'a=1&b=2' ), 'a=1/b=2' )<br>( Hiqus( 'a=1|b=2' ), 'a=1/b=2' )<br><br>( Hiqus( '1/2' ).get(), '1,2' )<br>( Hiqus( 'a=1/b=2' ).get( 'a' ), '1' )<br>( Hiqus( 'a=1=2/b=2=3' ).get( 'b' ,'0'), '3' )<br>( ( ( a= Hiqus( 'a=1/b=2' ) ).get( 'a' ), a ), 'a=1/b=2' )<br><br>( Hiqus( 'a=1/b=2' ).sub(), 'a=1/b=2' )<br>( Hiqus( 'a=b=1/a=c=2/d=3' ).sub( 'a' ), 'b=1/c=2' )<br>( Hiqus( 'a=b==1/a=b==2' ).sub( 'a' , 'b' ), '1/2' )<br>( ( a= Hiqus( 'a=1/b=2' ) ).sub( 'a' ) && a, 'a=1/b=2' )<br><br>( Hiqus( 'a=1' ).put( {b:2} ), 'a=1/b=2' )<br>( Hiqus( 'a=1' ).put( 'a' , {b:2} ), 'a=b=2' )<br>( ( a= Hiqus( 'a=1' ) ).put( 'b=2' ) && a, 'a=1' )<br>;
Source: https://habr.com/ru/post/92300/
All Articles