Refactored JS to use observer-notifier system.
git-svn-id: file:///tmp/snv/trunk@9 12951d8a-c33d-4b7c-b961-822215c816e1master
parent
3d33406796
commit
0aa71851ef
@ -1,7 +1,7 @@
|
||||
move to JSON data format -- done
|
||||
XBL -- done
|
||||
format JS/refactor JS/Use FUEL -- done
|
||||
put license
|
||||
caching/db, threading, XUL templates
|
||||
new UI
|
||||
caching/db, threading
|
||||
new UI, icons, thumbnails
|
||||
JQuery
|
||||
put license
|
||||
|
@ -0,0 +1,355 @@
|
||||
/*
|
||||
JPath 1.0.3 - json equivalent to xpath
|
||||
Copyright (C) 2007 Bryan English <bryan at bluelinecity dot com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Usage:
|
||||
var jpath = new JPath( myjsonobj );
|
||||
|
||||
var somevalue = jpath.$('book/title').json; //results in title
|
||||
//or
|
||||
var somevalue = jpath.query('book/title'); //results in title
|
||||
|
||||
Supported XPath-like Syntax:
|
||||
/tagname
|
||||
//tagname
|
||||
tagname
|
||||
* wildcard
|
||||
[] predicates
|
||||
operators ( >=, ==, <= )
|
||||
array selection
|
||||
..
|
||||
*
|
||||
and, or
|
||||
nodename[0]
|
||||
nodename[last()]
|
||||
nodename[position()]
|
||||
nodename[last()-1]
|
||||
nodename[somenode > 3]/node
|
||||
nodename[count() > 3]/node
|
||||
|
||||
Tested With:
|
||||
Firefox 2-3, IE 6-7
|
||||
|
||||
Update Log:
|
||||
1.0.1 - Bugfix for zero-based element selection
|
||||
1.0.2 - Bugfix for IE not handling eval() and returning a function
|
||||
1.0.3 - Bugfix added support for underscore and dash in query() function
|
||||
Bugfix improper use of Array.concat which was flattening arrays
|
||||
Added support for single equal sign in query() function
|
||||
Added support for count() xpath function
|
||||
Added support for and, or boolean expression in predicate blocks
|
||||
Added support for global selector $$ and //
|
||||
Added support for wildcard (*) selector support
|
||||
*/
|
||||
|
||||
function JPath( json, parent )
|
||||
{
|
||||
this.json = json;
|
||||
this._parent = parent;
|
||||
}
|
||||
|
||||
JPath.prototype = {
|
||||
|
||||
/*
|
||||
Property: json
|
||||
Copy of current json segment to operate on
|
||||
*/
|
||||
json: null,
|
||||
|
||||
/*
|
||||
Property: parent
|
||||
Parent json object, null if root.
|
||||
*/
|
||||
parent: null,
|
||||
|
||||
/*
|
||||
Method: $
|
||||
Performs a find query on the current jpath object.
|
||||
|
||||
Parameters:
|
||||
str - mixed, find query to perform. Can consist of a nodename or nodename path or function object or integer.
|
||||
|
||||
Return:
|
||||
jpath - Returns the resulting jpath object after performing find query.
|
||||
|
||||
*/
|
||||
'$': function ( str )
|
||||
{
|
||||
var result = null;
|
||||
var working = this;
|
||||
|
||||
if ( this.json && str !== null )
|
||||
{
|
||||
switch ( typeof(str) )
|
||||
{
|
||||
case 'function':
|
||||
result = this.f(str).json;
|
||||
break;
|
||||
|
||||
case 'number':
|
||||
result = this.json[str] || null;
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
var names = str.split('/');
|
||||
|
||||
//foreach slash delimited node name//
|
||||
for ( var i=0; i<names.length ; i++ )
|
||||
{
|
||||
var name = new RegExp('^' + names[i].replace(/\*/g,'.*') + '$');
|
||||
var isArray = (working.json instanceof Array);
|
||||
var a = new Array();
|
||||
|
||||
//foreach working node property//
|
||||
for ( var p in working.json )
|
||||
{
|
||||
if ( typeof( working.json[p] ) != 'function' )
|
||||
{
|
||||
if ( isArray && (arguments.callee.caller != this.$$) )
|
||||
{
|
||||
a = a.concat( this.findAllByRegExp( name, working.json[p] ) );
|
||||
}
|
||||
else if ( name.test(p) )
|
||||
{
|
||||
a.push( working.json[p] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
working = new JPath( ( a.length==0 ? null : ( ( a.length == 1) ? a[0] : a ) ), working );
|
||||
}
|
||||
|
||||
return working;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new JPath( result, this );
|
||||
},
|
||||
|
||||
/*
|
||||
Method: $$
|
||||
Performs a global, recursive find query on the current jpath object.
|
||||
|
||||
Parameters:
|
||||
str - mixed, find query to perform. Can consist of a nodename or nodename path or function object or integer.
|
||||
|
||||
Return:
|
||||
jpath - Returns the resulting jpath object after performing find query.
|
||||
|
||||
*/
|
||||
'$$': function( str )
|
||||
{
|
||||
var r = this.$(str,true).json;
|
||||
var arr = new Array();
|
||||
|
||||
if ( r instanceof Array )
|
||||
arr = arr.concat(r);
|
||||
else if ( r !== null )
|
||||
arr.push(r);
|
||||
|
||||
for ( var p in this.json )
|
||||
{
|
||||
if ( typeof( this.json[p] ) == 'object' )
|
||||
{
|
||||
arr = arr.concat( new JPath( this.json[p], this ).$$(str).json );
|
||||
}
|
||||
}
|
||||
|
||||
return new JPath( arr, this );
|
||||
},
|
||||
|
||||
/*
|
||||
Method: findAllByRegExp
|
||||
Looks through a list of an object properties using a regular expression
|
||||
|
||||
Parameters:
|
||||
re - regular expression, to use to search with
|
||||
obj - object, the object to search through
|
||||
|
||||
Returns:
|
||||
array - resulting properties
|
||||
*/
|
||||
findAllByRegExp: function( re, obj )
|
||||
{
|
||||
var a = new Array();
|
||||
|
||||
for ( var p in obj )
|
||||
{
|
||||
if ( obj instanceof Array )
|
||||
{
|
||||
a = a.concat( this.findAllByRegExp( re, obj[p] ) );
|
||||
}
|
||||
else if ( typeof( obj[p] ) != 'function' && re.test(p) )
|
||||
{
|
||||
a.push( obj[p] );
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
},
|
||||
|
||||
/*
|
||||
Method: query (beta)
|
||||
Performs a find query on the current jpath object using a single string similar to xpath. This method
|
||||
is currently expirimental.
|
||||
|
||||
Parameters:
|
||||
str - string, full xpath-like query to perform on the current object.
|
||||
|
||||
Return:
|
||||
mixed - Returns the resulting json value after performing find query.
|
||||
|
||||
*/
|
||||
query: function( str )
|
||||
{
|
||||
var re = {
|
||||
" and ":" && ",
|
||||
" or ":" || ",
|
||||
"([\\#\\*\\@a-z\\_][\\*a-z0-9_\\-]*)(?=(?:\\s|$|\\[|\\]|\\/))" : "\$('$1').",
|
||||
"\\[([0-9])+\\]" : "\$($1).",
|
||||
"\\.\\." : "parent().",
|
||||
"\/\/" : "$",
|
||||
"(^|\\[|\\s)\\/" : "$1root().",
|
||||
"\\/" : '',
|
||||
"([^\\=\\>\\<\\!])\\=([^\\=])" : '$1==$2',
|
||||
"\\[" : "$(function(j){ with(j){return(",
|
||||
"\\]" : ");}}).",
|
||||
"\\(\\.":'(',
|
||||
"(\\.|\\])(?!\\$|\\p)":"$1json",
|
||||
"count\\(([^\\)]+)\\)":"count('$1')"
|
||||
};
|
||||
|
||||
//save quoted strings//
|
||||
var quotes = /(\'|\")([^\1]*)\1/;
|
||||
var saves = new Array();
|
||||
while ( quotes.test(str) )
|
||||
{
|
||||
saves.push( str.match(quotes)[2] );
|
||||
str = str.replace(quotes,'%'+ (saves.length-1) +'%');
|
||||
}
|
||||
|
||||
for ( var e in re )
|
||||
{
|
||||
str = str.replace( new RegExp(e,'ig'), re[e] );
|
||||
}
|
||||
//alert('this.' + str.replace(/\%(\d+)\%/g,'saves[$1]') + ";");
|
||||
|
||||
return eval('this.' + str.replace(/\%(\d+)\%/g,'saves[$1]') + ";");
|
||||
},
|
||||
|
||||
/*
|
||||
Method: f
|
||||
Performs the equivilant to an xpath predicate eval on the current nodeset.
|
||||
|
||||
Parameters:
|
||||
f - function, an iterator function that is executed for every json node and is expected to return a boolean
|
||||
value which determines if that particular node is selected. Alternativly you can submit a string which will be
|
||||
inserted into a prepared function.
|
||||
|
||||
Return:
|
||||
jpath - Returns the resulting jpath object after performing find query.
|
||||
|
||||
*/
|
||||
f: function ( iterator )
|
||||
{
|
||||
var a = new Array();
|
||||
|
||||
if ( typeof(iterator) == 'string' )
|
||||
{
|
||||
eval('iterator = function(j){with(j){return('+ iterator +');}}');
|
||||
}
|
||||
|
||||
for ( var p in this.json )
|
||||
{
|
||||
var j = new JPath(this.json[p], this);
|
||||
j.index = p;
|
||||
if ( iterator( j ) )
|
||||
{
|
||||
a.push( this.json[p] );
|
||||
}
|
||||
}
|
||||
|
||||
return new JPath( a, this );
|
||||
},
|
||||
|
||||
/*
|
||||
Method: parent
|
||||
Returns the parent jpath object or itself if its the root node
|
||||
|
||||
Return:
|
||||
jpath - Returns the parent jpath object or itself if its the root node
|
||||
|
||||
*/
|
||||
parent: function()
|
||||
{
|
||||
return ( (this._parent) ? this._parent : this );
|
||||
},
|
||||
|
||||
/*
|
||||
Method: position
|
||||
Returns the index position of the current node. Only valid within a function or predicate
|
||||
|
||||
Return:
|
||||
int - array index position of this json object.
|
||||
*/
|
||||
position: function()
|
||||
{
|
||||
return this.index;
|
||||
},
|
||||
|
||||
/*
|
||||
Method: last
|
||||
Returns true if this is the last node in the nodeset. Only valid within a function or predicate
|
||||
|
||||
Return:
|
||||
booean - Returns true if this is the last node in the nodeset
|
||||
*/
|
||||
last: function()
|
||||
{
|
||||
return (this.index == (this._parent.json.length-1));
|
||||
},
|
||||
|
||||
/*
|
||||
Method: count
|
||||
Returns the count of child nodes in the current node
|
||||
|
||||
Parameters:
|
||||
string - optional node name to count, defaults to all
|
||||
|
||||
Return:
|
||||
booean - Returns number of child nodes found
|
||||
*/
|
||||
count: function(n)
|
||||
{
|
||||
var found = this.$( n || '*').json;
|
||||
return ( found ? ( found instanceof Array ? found.length : 1 ) : 0 );
|
||||
},
|
||||
|
||||
/*
|
||||
Method: root
|
||||
Returns the root jpath object.
|
||||
|
||||
Return:
|
||||
jpath - The top level, root jpath object.
|
||||
*/
|
||||
root: function ()
|
||||
{
|
||||
return ( this._parent ? this._parent.root() : this );
|
||||
}
|
||||
|
||||
};
|
Loading…
Reference in New Issue