Refactored JS to use observer-notifier system.
git-svn-id: file:///tmp/snv/trunk@9 12951d8a-c33d-4b7c-b961-822215c816e1
This commit is contained in:
parent
3d33406796
commit
0aa71851ef
@ -1,7 +1,7 @@
|
|||||||
move to JSON data format -- done
|
move to JSON data format -- done
|
||||||
XBL -- done
|
XBL -- done
|
||||||
format JS/refactor JS/Use FUEL -- done
|
format JS/refactor JS/Use FUEL -- done
|
||||||
put license
|
caching/db, threading
|
||||||
caching/db, threading, XUL templates
|
new UI, icons, thumbnails
|
||||||
new UI
|
|
||||||
JQuery
|
JQuery
|
||||||
|
put license
|
||||||
|
@ -1,9 +1,38 @@
|
|||||||
var DiggSidebar = {
|
/*
|
||||||
|
Digg Sidebar - Shows Digg stories in the Firefox sidebar in real time.
|
||||||
|
Copyright (C) 2008 Abhinav Sarkar <abhinav dot sarkar at gmail 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
DiggSidebar = {
|
||||||
prefs: Application.extensions.get("diggsidebar@abhinavsarkar.net").prefs,
|
prefs: Application.extensions.get("diggsidebar@abhinavsarkar.net").prefs,
|
||||||
|
storyListRefreshEventTopic: "extension-diggsidebar-abhinavsarkar-net-storylist-refresh",
|
||||||
|
endpoint: {
|
||||||
|
container: null,
|
||||||
|
topic: null,
|
||||||
|
category: "all"
|
||||||
|
},
|
||||||
|
updateInterval: 10,
|
||||||
|
updateIntervalDecay: 0,
|
||||||
|
shownStoriesCount: 30,
|
||||||
categories: ['All', 'Popular', 'Upcoming', 'Hot', 'Top'],
|
categories: ['All', 'Popular', 'Upcoming', 'Hot', 'Top'],
|
||||||
timerId : null,
|
timerId: null,
|
||||||
currentStories : new Array(),
|
storyIds: [],
|
||||||
playing : true,
|
playing: true,
|
||||||
|
stories: [],
|
||||||
|
|
||||||
fetchData: function(url, handler) {
|
fetchData: function(url, handler) {
|
||||||
DiggSidebar.diggIndicator.style.display = '';
|
DiggSidebar.diggIndicator.style.display = '';
|
||||||
@ -95,31 +124,36 @@ var DiggSidebar = {
|
|||||||
DiggSidebar.diggIndicator.style.display = 'none';
|
DiggSidebar.diggIndicator.style.display = 'none';
|
||||||
},
|
},
|
||||||
|
|
||||||
populateStoryList: function(e) {
|
populateStoryList: function() {
|
||||||
var XHR = e.target;
|
|
||||||
//Application.console.log(XHR.responseText);
|
|
||||||
var data = DiggSidebar.Utils.decodeJson(XHR.responseText);
|
|
||||||
var stories = data.stories;
|
|
||||||
|
|
||||||
while (DiggSidebar.storyList.firstChild) {
|
while (DiggSidebar.storyList.firstChild) {
|
||||||
DiggSidebar.storyList.removeChild(DiggSidebar.storyList.firstChild);
|
DiggSidebar.storyList.removeChild(DiggSidebar.storyList.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
var newStories = new Array();
|
var newStoryIds = new Array();
|
||||||
//Application.console.log(stories.length);
|
Application.console.log(DiggSidebar.stories.length);
|
||||||
|
|
||||||
stories.forEach(function (story) {
|
var jp = new JPath(DiggSidebar.stories);
|
||||||
newStories.push(story.id);
|
var filtedStories = DiggSidebar.stories;
|
||||||
//Application.console.log(i + " " + story.title + " " + story.id);
|
if (DiggSidebar.endpoint.topic)
|
||||||
|
filtedStories = jp.$(function(story){
|
||||||
|
return story.$("topic/short_name").json == DiggSidebar.endpoint.topic;
|
||||||
|
}).json;
|
||||||
|
if (DiggSidebar.endpoint.container)
|
||||||
|
filtedStories = jp.$(function(story){
|
||||||
|
return story.$("container/short_name").json == DiggSidebar.endpoint.container;
|
||||||
|
}).json;
|
||||||
|
|
||||||
var listitem = DiggSidebar.storyList.appendChild(document.createElement('richlistitem'));
|
filtedStories.forEach(function (story, index) {
|
||||||
listitem.id = "story_" + story.id;
|
if (index < DiggSidebar.shownStoriesCount) {
|
||||||
listitem.setAttribute('title', story.title);
|
var listitem = DiggSidebar.storyList.appendChild(document.createElement('richlistitem'));
|
||||||
|
listitem.id = "story_" + story.id;
|
||||||
if (DiggSidebar.currentStories.indexOf(story.id) != -1) listitem.new = false;
|
listitem.setAttribute('title', story.title);
|
||||||
|
if (DiggSidebar.storyIds.indexOf(story.id) != -1) listitem.new = false;
|
||||||
|
}
|
||||||
|
if (DiggSidebar.storyIds.indexOf(story.id) == -1) newStoryIds.push(story.id);
|
||||||
});
|
});
|
||||||
DiggSidebar.currentStories = newStories;
|
DiggSidebar.storyIds = DiggSidebar.storyIds.concat(newStoryIds);
|
||||||
DiggSidebar.setUpdateInterval(stories);
|
DiggSidebar.setUpdateInterval(DiggSidebar.stories.slice(-5));
|
||||||
DiggSidebar.diggIndicator.style.display = 'none';
|
DiggSidebar.diggIndicator.style.display = 'none';
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -178,7 +212,20 @@ var DiggSidebar = {
|
|||||||
DiggSidebar.fetchData("http://services.digg.com/stories" + ep.replace(/\/all/g, '') +
|
DiggSidebar.fetchData("http://services.digg.com/stories" + ep.replace(/\/all/g, '') +
|
||||||
"?count=30" + "&type=json" +
|
"?count=30" + "&type=json" +
|
||||||
"&appkey=" + encodeURIComponent("http://diggsidebar.googlepages.com"),
|
"&appkey=" + encodeURIComponent("http://diggsidebar.googlepages.com"),
|
||||||
DiggSidebar.populateStoryList);
|
function(e) {
|
||||||
|
var newStories = DiggSidebar.Utils.decodeJson(e.target.responseText).stories.filter(
|
||||||
|
function(story) {
|
||||||
|
return !(DiggSidebar.storyIds.indexOf(story.id) != -1);
|
||||||
|
});
|
||||||
|
newStories.forEach(function(story) {
|
||||||
|
story.category = DiggSidebar.endpoint.category;
|
||||||
|
story.read = false;
|
||||||
|
});
|
||||||
|
DiggSidebar.stories = newStories.concat(DiggSidebar.stories);
|
||||||
|
var observerService = Components.classes["@mozilla.org/observer-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIObserverService);
|
||||||
|
observerService.notifyObservers(null, DiggSidebar.storyListRefreshEventTopic, null);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getDescription: function(storyId) {
|
getDescription: function(storyId) {
|
||||||
@ -196,6 +243,12 @@ var DiggSidebar = {
|
|||||||
|
|
||||||
setUpdateInterval: function(stories) {
|
setUpdateInterval: function(stories) {
|
||||||
//Adaptive update interval code START
|
//Adaptive update interval code START
|
||||||
|
if (stories.length == 0) {
|
||||||
|
window.clearTimeout(DiggSidebar.timerId);
|
||||||
|
var timeout = Math.round(DiggSidebar.updateInterval*(Math.pow(1.5, DiggSidebar.updateIntervalDecay)));
|
||||||
|
DiggSidebar.timerId = window.setTimeout(DiggSidebar.getStories, timeout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
var sum = 0;
|
var sum = 0;
|
||||||
var weights = [4, 3, 2, 1]
|
var weights = [4, 3, 2, 1]
|
||||||
var date = (stories[0].promote_date != null) ? 'promote_date' : 'submit_date';
|
var date = (stories[0].promote_date != null) ? 'promote_date' : 'submit_date';
|
||||||
@ -216,32 +269,46 @@ var DiggSidebar = {
|
|||||||
//Application.console.log(updateInterval);
|
//Application.console.log(updateInterval);
|
||||||
|
|
||||||
if (updateInterval > 0) {
|
if (updateInterval > 0) {
|
||||||
var previousUpdateInterval = DiggSidebar.prefs.get("updateinterval").value;
|
var previousUpdateInterval = DiggSidebar.updateInterval;
|
||||||
DiggSidebar.prefs.get("updateinterval").value = updateInterval;
|
DiggSidebar.updateInterval = updateInterval;
|
||||||
|
|
||||||
var updateIntervalDecay = DiggSidebar.prefs.get("updateintervaldecay").value;
|
var updateIntervalDecay = DiggSidebar.updateIntervalDecay;
|
||||||
|
|
||||||
if (previousUpdateInterval == updateInterval)
|
if (previousUpdateInterval == updateInterval)
|
||||||
DiggSidebar.prefs.get("updateintervaldecay").value = updateIntervalDecay + 1;
|
DiggSidebar.updateIntervalDecay = updateIntervalDecay + 1;
|
||||||
else
|
else
|
||||||
DiggSidebar.prefs.get("updateintervaldecay").value = 0;
|
DiggSidebar.updateIntervalDecay = 0;
|
||||||
}
|
}
|
||||||
window.clearTimeout(DiggSidebar.timerId);
|
window.clearTimeout(DiggSidebar.timerId);
|
||||||
|
|
||||||
var updateInterval = DiggSidebar.prefs.get("updateinterval").value;
|
var timeout = Math.round(DiggSidebar.updateInterval*(Math.pow(1.5, DiggSidebar.updateIntervalDecay)));
|
||||||
var updateIntervalDecay = DiggSidebar.prefs.get("updateintervaldecay").value;
|
|
||||||
|
|
||||||
var timeout = Math.round(updateInterval*(Math.pow(1.5, updateIntervalDecay)));
|
|
||||||
DiggSidebar.timerId = window.setTimeout(DiggSidebar.getStories, timeout);
|
DiggSidebar.timerId = window.setTimeout(DiggSidebar.getStories, timeout);
|
||||||
//Adaptive update interval code END
|
//Adaptive update interval code END
|
||||||
},
|
},
|
||||||
|
|
||||||
setEndPoint: function(ep) {
|
setEndPoint: function(ep) {
|
||||||
DiggSidebar.prefs.get("endpoint").value = ep;
|
DiggSidebar.prefs.get("endpoint").value = ep;
|
||||||
|
DiggSidebar.endpoint = DiggSidebar.getEndpointParts(ep);
|
||||||
window.clearTimeout(DiggSidebar.timerId);
|
window.clearTimeout(DiggSidebar.timerId);
|
||||||
DiggSidebar.getStories();
|
DiggSidebar.getStories();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getEndpointParts: function(ep) {
|
||||||
|
var tmp = {
|
||||||
|
topic: null,
|
||||||
|
container: null,
|
||||||
|
category: "all"
|
||||||
|
};
|
||||||
|
parts = ep.split("/");
|
||||||
|
if (parts.length == 2)
|
||||||
|
tmp.category = parts[1];
|
||||||
|
else if (parts.length == 4) {
|
||||||
|
tmp[parts[1]] = parts[2];
|
||||||
|
tmp.category = parts[3];
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
},
|
||||||
|
|
||||||
togglePlayPause: function() {
|
togglePlayPause: function() {
|
||||||
if (DiggSidebar.playing) {
|
if (DiggSidebar.playing) {
|
||||||
window.clearTimeout(DiggSidebar.timerId);
|
window.clearTimeout(DiggSidebar.timerId);
|
||||||
@ -249,10 +316,7 @@ var DiggSidebar = {
|
|||||||
DiggSidebar.diggPlayPause.setAttribute("tooltiptext", "Click to Start autoupdate");
|
DiggSidebar.diggPlayPause.setAttribute("tooltiptext", "Click to Start autoupdate");
|
||||||
DiggSidebar.playing = false;
|
DiggSidebar.playing = false;
|
||||||
} else {
|
} else {
|
||||||
var updateInterval = DiggSidebar.prefs.get("updateinterval").value;
|
var timeout = Math.round(DiggSidebar.updateInterval*(Math.pow(1.5, DiggSidebar.updateIntervalDecay)));
|
||||||
var updateIntervalDecay = DiggSidebar.prefs.get("updateintervaldecay").value;
|
|
||||||
|
|
||||||
var timeout = Math.round(updateInterval*(Math.pow(1.5, updateIntervalDecay)));
|
|
||||||
DiggSidebar.timerId = window.setTimeout(DiggSidebar.getStories, timeout);
|
DiggSidebar.timerId = window.setTimeout(DiggSidebar.getStories, timeout);
|
||||||
DiggSidebar.diggPlayPause.image = "chrome://diggsidebar/content/image/Pause.png";
|
DiggSidebar.diggPlayPause.image = "chrome://diggsidebar/content/image/Pause.png";
|
||||||
DiggSidebar.diggPlayPause.setAttribute("tooltiptext", "Click to Pause autoupdate");
|
DiggSidebar.diggPlayPause.setAttribute("tooltiptext", "Click to Pause autoupdate");
|
||||||
@ -261,6 +325,7 @@ var DiggSidebar = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
initialize: function(){
|
initialize: function(){
|
||||||
|
DiggSidebar.endpoint = DiggSidebar.getEndpointParts(DiggSidebar.prefs.get("endpoint").value);
|
||||||
var $ = function(id) {return document.getElementById(id)};
|
var $ = function(id) {return document.getElementById(id)};
|
||||||
DiggSidebar.diggIndicator = $('diggIndicator');
|
DiggSidebar.diggIndicator = $('diggIndicator');
|
||||||
DiggSidebar.topicPopup = $('topicPopup');
|
DiggSidebar.topicPopup = $('topicPopup');
|
||||||
@ -268,8 +333,14 @@ var DiggSidebar = {
|
|||||||
DiggSidebar.storyList = $('storyList');
|
DiggSidebar.storyList = $('storyList');
|
||||||
DiggSidebar.diggEndPoint = $('diggEndPoint');
|
DiggSidebar.diggEndPoint = $('diggEndPoint');
|
||||||
DiggSidebar.diggPlayPause = $('diggPlayPause');
|
DiggSidebar.diggPlayPause = $('diggPlayPause');
|
||||||
|
|
||||||
|
DiggSidebar.storyListObserver = new StoryListObserver();
|
||||||
DiggSidebar.createMenu();
|
DiggSidebar.createMenu();
|
||||||
DiggSidebar.getStories();
|
DiggSidebar.getStories();
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function(){
|
||||||
|
DiggSidebar.storyListObserver.unregister();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -290,6 +361,38 @@ DiggSidebar.Utils = {
|
|||||||
return json.decode(string);
|
return json.decode(string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var StoryListObserver = function() {
|
||||||
|
this.registered = false;
|
||||||
|
this.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
StoryListObserver.prototype = {
|
||||||
|
observe: function(subject, topic, data) {
|
||||||
|
if (topic == window.DiggSidebar.storyListRefreshEventTopic) {
|
||||||
|
window.DiggSidebar.populateStoryList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
register: function() {
|
||||||
|
if (this.registered == false) {
|
||||||
|
var observerService = Components.classes["@mozilla.org/observer-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIObserverService);
|
||||||
|
observerService.addObserver(this, DiggSidebar.storyListRefreshEventTopic, false);
|
||||||
|
this.registered = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
unregister: function() {
|
||||||
|
if (this.registered == true) {
|
||||||
|
var observerService = Components.classes["@mozilla.org/observer-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIObserverService);
|
||||||
|
observerService.removeObserver(this, DiggSidebar.storyListRefreshEventTopic);
|
||||||
|
this.registered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*TODO
|
/*TODO
|
||||||
preferences
|
preferences
|
||||||
toolbar button
|
toolbar button
|
||||||
|
@ -6,8 +6,10 @@
|
|||||||
|
|
||||||
<page id="sbDiggSidebar" title="&diggsidebar.title;"
|
<page id="sbDiggSidebar" title="&diggsidebar.title;"
|
||||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
onload="DiggSidebar.initialize()">
|
onload="DiggSidebar.initialize()"
|
||||||
|
onunload="DiggSidebar.destroy()">
|
||||||
<script src="chrome://diggsidebar/content/diggsidebar.js" type="application/x-javascript" />
|
<script src="chrome://diggsidebar/content/diggsidebar.js" type="application/x-javascript" />
|
||||||
|
<script src="chrome://diggsidebar/content/jpath.js" type="application/x-javascript" />
|
||||||
<hbox>
|
<hbox>
|
||||||
<toolbar flex="1">
|
<toolbar flex="1">
|
||||||
<toolbaritem>
|
<toolbaritem>
|
||||||
|
355
chrome/content/jpath.js
Normal file
355
chrome/content/jpath.js
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -5,7 +5,7 @@
|
|||||||
<RDF:Description RDF:about="rdf:#$55wJ23"
|
<RDF:Description RDF:about="rdf:#$55wJ23"
|
||||||
em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
|
em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
|
||||||
em:minVersion="3.0"
|
em:minVersion="3.0"
|
||||||
em:maxVersion="3.1.*" />
|
em:maxVersion="3.1b1" />
|
||||||
<RDF:Description RDF:about="urn:mozilla:install-manifest"
|
<RDF:Description RDF:about="urn:mozilla:install-manifest"
|
||||||
em:id="diggsidebar@abhinavsarkar.net"
|
em:id="diggsidebar@abhinavsarkar.net"
|
||||||
em:name="Digg Sidebar"
|
em:name="Digg Sidebar"
|
||||||
|
Loading…
Reference in New Issue
Block a user