| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811 | require({cache:{'url:dojox/atom/widget/templates/FeedViewer.html':"<div class=\"feedViewerContainer\" dojoAttachPoint=\"feedViewerContainerNode\">\n\t<table cellspacing=\"0\" cellpadding=\"0\" class=\"feedViewerTable\">\n\t\t<tbody dojoAttachPoint=\"feedViewerTableBody\" class=\"feedViewerTableBody\">\n\t\t</tbody>\n\t</table>\n</div>\n",'url:dojox/atom/widget/templates/FeedViewerEntry.html':"<tr class=\"feedViewerEntry\" dojoAttachPoint=\"entryNode\" dojoAttachEvent=\"onclick:onClick\">\n    <td class=\"feedViewerEntryUpdated\" dojoAttachPoint=\"timeNode\">\n    </td>\n    <td>\n        <table border=\"0\" width=\"100%\" dojoAttachPoint=\"titleRow\">\n            <tr padding=\"0\" border=\"0\">\n                <td class=\"feedViewerEntryTitle\" dojoAttachPoint=\"titleNode\">\n                </td>\n                <td class=\"feedViewerEntryDelete\" align=\"right\">\n                    <span dojoAttachPoint=\"deleteButton\" dojoAttachEvent=\"onclick:deleteEntry\" class=\"feedViewerDeleteButton\" style=\"display:none;\">[delete]</span>\n                </td>\n            <tr>\n        </table>\n    </td>\n</tr>",'url:dojox/atom/widget/templates/FeedViewerGrouping.html':"<tr dojoAttachPoint=\"groupingNode\" class=\"feedViewerGrouping\">\n\t<td colspan=\"2\" dojoAttachPoint=\"titleNode\" class=\"feedViewerGroupingTitle\">\n\t</td>\n</tr>"}});define("dojox/atom/widget/FeedViewer", [	"dojo/_base/kernel",	"dojo/_base/lang",	"dojo/_base/array",	"dojo/_base/connect",	"dojo/dom-class",	"dijit/_Widget",	"dijit/_Templated",	"dijit/_Container",	"../io/Connection",	"dojo/text!./templates/FeedViewer.html",	"dojo/text!./templates/FeedViewerEntry.html",	"dojo/text!./templates/FeedViewerGrouping.html",	"dojo/i18n!./nls/FeedViewerEntry",	"dojo/_base/declare"], function (dojo, lang, arrayUtil, connect, domClass, _Widget, _Templated, _Container, Connection, template, entryTemplate, groupingTemplate, i18nViewer) {dojo.experimental("dojox.atom.widget.FeedViewer");var widget = dojo.getObject("dojox.atom.widget", true);widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/ [_Widget, _Templated, _Container],{	//	summary:	//		An ATOM feed viewer that allows for viewing a feed, deleting entries, and editing entries.	//	description:	//		An ATOM feed viewer that allows for viewing a feed, deleting entries, and editing entries.	feedViewerTableBody: null,	//The body of the feed viewer table so we can access it and populate it.  Will be assigned via template.	feedViewerTable: null,		//The overal table container which contains the feed viewer table.  Will be assigned via template.	entrySelectionTopic: "",	//The topic to broadcast when any entry is clicked so that a listener can pick up it and display it.	url: "",					//The URL to which to connect to initially on creation.	xmethod: false,	localSaveOnly: false,	//Templates for the HTML rendering.  Need to figure these out better, admittedly.	templateString: template,	_feed: null,	_currentSelection: null, // Currently selected entry	_includeFilters: null,	alertsEnabled: false,	postCreate: function(){		//	summary:		//		The postCreate function.		//	description:		//		The postCreate function.  Creates our AtomIO object for future interactions and subscribes to the		//		event given in markup/creation.		this._includeFilters = [];		if(this.entrySelectionTopic !== ""){			this._subscriptions = [dojo.subscribe(this.entrySelectionTopic, this, "_handleEvent")];		}		this.atomIO = new Connection();		this.childWidgets = [];	},		startup: function(){		//	summary:		//		The startup function.		//	description:		//		The startup function.  Parses the filters and sets the feed based on the given url.		this.containerNode = this.feedViewerTableBody;		var children = this.getDescendants();		for(var i in children){			var child = children[i];			if(child && child.isFilter){				this._includeFilters.push(new widget.FeedViewer.CategoryIncludeFilter(child.scheme, child.term, child.label));				child.destroy();			}		}				if(this.url !== ""){			this.setFeedFromUrl(this.url);		}	},	clear: function(){		//	summary:		//		Function clearing all current entries in the feed view.		//	description:		//		Function clearing all current entries in the feed view.		//		//	returns:		//		Nothing.		this.destroyDescendants();	},	setFeedFromUrl: function(/*string*/url){		//	summary:		//		Function setting the feed from a URL which to get the feed.		//	description:		//		Function setting the dojox.atom.io.model.Feed data into the view.		//		//	url:		//		The URL to the feed to load.		//		//	returns:		//		Nothing.		if(url !== ""){			if(this._isRelativeURL(url)){				var baseUrl = "";				if(url.charAt(0) !== '/'){					baseUrl = this._calculateBaseURL(window.location.href, true);				}else{					baseUrl = this._calculateBaseURL(window.location.href, false);				}				this.url = baseUrl + url;			}			this.atomIO.getFeed(url,lang.hitch(this,this.setFeed));		}	},	setFeed: function(/*object*/feed){		//	summary:		//		Function setting the dojox.atom.io.model.Feed data into the view.		//	description:		//		Function setting the dojox.atom.io.model.Feed data into the view.		//		//	entry:		//		The dojox.atom.io.model.Feed object to process		//		//	returns:		//		Nothing.		this._feed = feed;		this.clear();		var entrySorter=function(a,b){			var dispA = this._displayDateForEntry(a);			var dispB = this._displayDateForEntry(b);			if(dispA > dispB){return -1;}			if(dispA < dispB){return 1;}			return 0;		};		// This function may not be safe in different locales.		var groupingStr = function(dateStr){			var dpts = dateStr.split(',');						dpts.pop(); // remove year and time			return dpts.join(",");		};		var sortedEntries = feed.entries.sort(lang.hitch(this,entrySorter));		if(feed){			var lastSectionTitle = null;			for(var i=0;i<sortedEntries.length;i++){								var entry = sortedEntries[i];				if(this._isFilterAccepted(entry)){					var time = this._displayDateForEntry(entry);					var sectionTitle = "";					if(time !== null){						sectionTitle = groupingStr(time.toLocaleString());						if(sectionTitle === "" ){							//Generally an issue on Opera with how its toLocaleString() works, so do a quick and dirty date construction M/D/Y							sectionTitle = "" + (time.getMonth() + 1) + "/" + time.getDate() + "/" + time.getFullYear();						}					}					if((lastSectionTitle === null) || (lastSectionTitle != sectionTitle)){						this.appendGrouping(sectionTitle);						lastSectionTitle = sectionTitle;					}					this.appendEntry(entry);				}			}		}	},	_displayDateForEntry: function(/*object*/entry){		//	summary:		//		Internal function for determining the appropriate date to display.		//		description: Internal function for determining of a particular entry is editable.		//		//	entry:		//		The dojox.atom.io.model.Entry object to examine.		//		//	returns:		//		An appropriate date for the feed viewer display.		if(entry.updated){return entry.updated;}		if(entry.modified){return entry.modified;}		if(entry.issued){return entry.issued;}		return new Date();	},	appendGrouping: function(/*string*/titleText){		//	summary:		//		Function for appending a new grouping of entries to the feed view.		//	description:		//		Function for appending a grouping of entries to the feed view.		//		//	entry:		//		The title of the new grouping to create on the view.		//		//	returns:		//		Nothing.		var entryWidget = new widget.FeedViewerGrouping({});		entryWidget.setText(titleText);		this.addChild(entryWidget);		this.childWidgets.push(entryWidget);	},	appendEntry: function(/*object*/entry){		//	summary:		//		Function for appending an entry to the feed view.		//	description:		//		Function for appending an entry to the feed view.		//		//	entry:		//		The dojox.atom.io.model.Entry object to append		//		//	returns:		//		Nothing.		var entryWidget = new widget.FeedViewerEntry({"xmethod": this.xmethod});		entryWidget.setTitle(entry.title.value);		entryWidget.setTime(this._displayDateForEntry(entry).toLocaleTimeString());		entryWidget.entrySelectionTopic = this.entrySelectionTopic;		entryWidget.feed = this;		this.addChild(entryWidget);		this.childWidgets.push(entryWidget);		this.connect(entryWidget, "onClick", "_rowSelected");		entry.domNode = entryWidget.entryNode;				//Need to set up a bi-directional reference here to control events between the two.		entry._entryWidget = entryWidget;		entryWidget.entry = entry;	},		deleteEntry: function(/*object*/entryRow){		//	summary:		//		Function for deleting a row from the view		//	description:		//		Function for deleting a row from the view		if(!this.localSaveOnly){			this.atomIO.deleteEntry(entryRow.entry, lang.hitch(this, this._removeEntry, entryRow), null, this.xmethod);		}else{			this._removeEntry(entryRow, true);		}		dojo.publish(this.entrySelectionTopic, [{ action: "delete", source: this, entry: entryRow.entry }]);	},	_removeEntry: function(/*FeedViewerEntry*/ entry, /* boolean */success){		//	summary:		//		callback for when an entry is deleted from a feed.		//	description:		//		callback for when an entry is deleted from a feed.		if(success){			/* Check if this is the last Entry beneath the given date */			var idx = arrayUtil.indexOf(this.childWidgets, entry);			var before = this.childWidgets[idx-1];			var after = this.childWidgets[idx+1];			if( before.isInstanceOf(widget.FeedViewerGrouping) &&				(after === undefined || after.isInstanceOf(widget.FeedViewerGrouping))){				before.destroy();			}						/* Destroy the FeedViewerEntry to remove it from the view */			entry.destroy();		}else{}	},		_rowSelected: function(/*object*/evt){		//	summary:		//		Internal function for handling the selection of feed entries.		//	description:		//		Internal function for handling the selection of feed entries.		//		//	evt:		//		The click event that triggered a selection.		//		//	returns:		//		Nothing.		var selectedNode = evt.target;		while(selectedNode){			if(domClass.contains(selectedNode, 'feedViewerEntry')) {				break;			}			selectedNode = selectedNode.parentNode;		}		for(var i=0;i<this._feed.entries.length;i++){			var entry = this._feed.entries[i];			if( (selectedNode === entry.domNode) && (this._currentSelection !== entry) ){				//Found it and it isn't already selected.				domClass.add(entry.domNode, "feedViewerEntrySelected");				domClass.remove(entry._entryWidget.timeNode, "feedViewerEntryUpdated");				domClass.add(entry._entryWidget.timeNode, "feedViewerEntryUpdatedSelected");				this.onEntrySelected(entry);				if(this.entrySelectionTopic !== ""){					dojo.publish(this.entrySelectionTopic, [{ action: "set", source: this, feed: this._feed, entry: entry }]);				}				if(this._isEditable(entry)){					entry._entryWidget.enableDelete();				}				this._deselectCurrentSelection();				this._currentSelection = entry;				break;			}else if( (selectedNode === entry.domNode) && (this._currentSelection === entry) ){				//Found it and it is the current selection, we just want to de-select it so users can 'unselect rows' if they want.				dojo.publish(this.entrySelectionTopic, [{ action: "delete", source: this, entry: entry }]);				this._deselectCurrentSelection();				break;			}		}	},	_deselectCurrentSelection: function(){		//	summary:		//		Internal function for unselecting the current selection.		//	description:		//		Internal function for unselecting the current selection.		//		//	returns:		//		Nothing.		if(this._currentSelection){			domClass.add(this._currentSelection._entryWidget.timeNode, "feedViewerEntryUpdated");			domClass.remove(this._currentSelection.domNode, "feedViewerEntrySelected");			domClass.remove(this._currentSelection._entryWidget.timeNode, "feedViewerEntryUpdatedSelected");			this._currentSelection._entryWidget.disableDelete();			this._currentSelection = null;		}	},	_isEditable: function(/*object*/entry){		//	summary:		//		Internal function for determining of a particular entry is editable.		//	description:		//		Internal function for determining of a particular entry is editable.		//		This is used for determining if the delete action should be displayed or not.		//		//	entry:		//		The dojox.atom.io.model.Entry object to examine		//		//	returns:		//		Boolean denoting if the entry seems editable or not..		var retVal = false;		if(entry && entry !== null && entry.links && entry.links !== null){			for(var x in entry.links){				if(entry.links[x].rel && entry.links[x].rel == "edit"){					retVal = true;					break;				}			}		}		return retVal;	},	onEntrySelected: function(/*object*/entry){		//	summary:		//		Function intended for over-riding/replacement as an attachpoint to for other items to recieve		//		selection notification.		//	description: Function intended for over0-riding/replacement as an attachpoint to for other items to recieve		//		selection notification.		//		//	entry:		//		The dojox.atom.io.model.Entry object selected.		//		//	returns:		//		Nothing.	},	_isRelativeURL: function(/*string*/url){		//	summary:		//		Method to determine if the URL is relative or absolute.		//	description:		//		Method to determine if the URL is relative or absolute.  Basic assumption is if it doesn't start		//		with http:// or file://, it's relative to the current document.		//		//	url:		//		The URL to inspect.		//		//	returns:		//		boolean indicating whether it's a relative url or not.		var isFileURL = function(url){			var retVal = false;			if(url.indexOf("file://") === 0){				retVal = true;			}			return retVal;		}		var isHttpURL = function(url){			var retVal = false;			if(url.indexOf("http://") === 0){				retVal = true;			}			return retVal;		}		var retVal = false;		if(url !== null){			if(!isFileURL(url) && !isHttpURL(url)){				retVal = true;			}		}		return retVal;	},	_calculateBaseURL: function(/*string*/fullURL, /*boolean*/currentPageRelative){		//	summary:		//		Internal function to calculate a baseline URL from the provided full URL.		//	description:		//		Internal function to calculate a baseline URL from the provided full URL.		//		//	fullURL:		//		The full URL as a string.		//	currentPageRelative:		//		Flag to denote of the base URL should be calculated as just the server base, or relative to the current page/location in the URL.		//		//	returns:		//		String of the baseline URL		var baseURL = null;		if(fullURL !== null){			//Check to see if we need to strip off any query parameters from the URL.			var index = fullURL.indexOf("?");			if(index != -1){				fullURL = fullURL.substring(0,index);				//console.debug("Removed query parameters.  URL now: " + fullURL);			}			if(currentPageRelative){				//Relative to the 'current page' in the URL, so we need to trim that off.				//Now we need to trim if necessary.  If it ends in /, then we don't have a filename to trim off				//so we can return.				index = fullURL.lastIndexOf("/");				if((index > 0) && (index < fullURL.length) && (index !== (fullURL.length -1))){					//We want to include the terminating /					baseURL = fullURL.substring(0,(index + 1));				}else{					baseURL = fullURL;				}			}else{				//We want to find the first occurance of / after the <protocol>://				index = fullURL.indexOf("://");				if(index > 0){					index = index + 3;					var protocol = fullURL.substring(0,index);					var fragmentURL = fullURL.substring(index, fullURL.length);					index = fragmentURL.indexOf("/");					if((index < fragmentURL.length) && (index > 0) ){						baseURL = protocol + fragmentURL.substring(0,index);					}else{						baseURL = protocol + fragmentURL;					}				}			}		}		return baseURL;	},	_isFilterAccepted: function(/*object*/entry) {		//	summary:		//		Internal function to do matching of category filters to widgets.		//	description:		//		Internal function to do matching of category filters to widgets.		//		//	returns:		//		boolean denoting if this entry matched one of the accept filters.		var accepted = false;		if (this._includeFilters && (this._includeFilters.length > 0)) {			for (var i = 0; i < this._includeFilters.length; i++) {				var filter = this._includeFilters[i];				if (filter.match(entry)) {					accepted = true;					break;				}			}		}		else {			accepted = true;		}		return accepted;	},	addCategoryIncludeFilter: function(/*object*/filter) {		//	summary:		//		Function to add a filter for entry inclusion in the feed view.		//	description:		//		Function to add a filter for entry inclusion in the feed view.		//		//	filter:		//		The basic items to filter on and the values.		//		Should be of format: {scheme: <some text or null>, term: <some text or null>, label: <some text or null>}		//		//	returns:		//		Nothing.		if (filter) {			var scheme = filter.scheme;			var term = filter.term;			var label = filter.label;			var addIt = true;			if (!scheme) {				scheme = null;			}			if (!term) {				scheme = null;			}			if (!label) {				scheme = null;			}						if (this._includeFilters && this._includeFilters.length > 0) {				for (var i = 0; i < this._includeFilters.length; i++) {					var eFilter = this._includeFilters[i];					if ((eFilter.term === term) && (eFilter.scheme === scheme) && (eFilter.label === label)) {						//Verify we don't have this filter already.						addIt = false;						break;					}				}			}			if (addIt) {				this._includeFilters.push(widget.FeedViewer.CategoryIncludeFilter(scheme, term, label));			}		}	},	removeCategoryIncludeFilter: function(/*object*/filter) {		//	summary:		//		Function to remove a filter for entry inclusion in the feed view.		//	description:		//		Function to remove a filter for entry inclusion in the feed view.		//		//	filter:		//		The basic items to identify the filter that is present.		//		Should be of format: {scheme: <some text or null>, term: <some text or null>, label: <some text or null>}		//		//	returns:		//		Nothing.		if (filter) {			var scheme = filter.scheme;			var term = filter.term;			var label = filter.label;			if (!scheme) {				scheme = null;			}			if (!term) {				scheme = null;			}			if (!label) {				scheme = null;			}						var newFilters = [];			if (this._includeFilters && this._includeFilters.length > 0) {				for (var i = 0; i < this._includeFilters.length; i++) {					var eFilter = this._includeFilters[i];					if (!((eFilter.term === term) && (eFilter.scheme === scheme) && (eFilter.label === label))) {						//Keep only filters that do not match						newFilters.push(eFilter);					}				}				this._includeFilters = newFilters;			}		}	},	_handleEvent: function(/*object*/entrySelectionEvent) {		//	summary:		//		Internal function for listening to a topic that will handle entry notification.		//	description:		//		Internal function for listening to a topic that will handle entry notification.		//		//	entrySelectionEvent:		//		The topic message containing the entry that was selected for view.		//		//	returns:		//		Nothing.		if(entrySelectionEvent.source != this) {			if(entrySelectionEvent.action == "update" && entrySelectionEvent.entry) {                var evt = entrySelectionEvent;				if(!this.localSaveOnly){					this.atomIO.updateEntry(evt.entry, lang.hitch(evt.source,evt.callback), null, true);				}				this._currentSelection._entryWidget.setTime(this._displayDateForEntry(evt.entry).toLocaleTimeString());				this._currentSelection._entryWidget.setTitle(evt.entry.title.value);			} else if(entrySelectionEvent.action == "post" && entrySelectionEvent.entry) {				if(!this.localSaveOnly){					this.atomIO.addEntry(entrySelectionEvent.entry, this.url, lang.hitch(this,this._addEntry));				}else{					this._addEntry(entrySelectionEvent.entry);				}			}		}	},		_addEntry: function(/*object*/entry) {		//	summary:		//		callback function used when adding an entry to the feed.		//	description:		//		callback function used when adding an entry to the feed.  After the entry has been posted to the feed,		//		we add it to our feed representation (to show it on the page) and publish an event to update any entry viewers.		this._feed.addEntry(entry);		this.setFeed(this._feed);		dojo.publish(this.entrySelectionTopic, [{ action: "set", source: this, feed: this._feed, entry: entry }]);	},	destroy: function(){		//	summary:		//		Destroys this widget, including all descendants and subscriptions.		//	description:		//		Destroys this widget, including all descendants and subscriptions.		this.clear();		arrayUtil.forEach(this._subscriptions, dojo.unsubscribe);	}});widget.FeedViewerEntry = dojo.declare(/*===== "dojox.atom.widget.FeedViewerEntry", =====*/ [_Widget, _Templated],{	//	summary:	//		Widget for handling the display of an entry and specific events associated with it.	//		description: Widget for handling the display of an entry and specific events associated with it.	templateString: entryTemplate,	entryNode: null,	timeNode: null,	deleteButton: null,	entry: null,	feed: null,	postCreate: function(){		var _nlsResources = i18nViewer;		this.deleteButton.innerHTML = _nlsResources.deleteButton;	},	setTitle: function(/*string*/text){		//	summary:		//		Function to set the title of the entry.		//	description:		//		Function to set the title of the entry.		//		//	text:		//		The title.		//		//	returns:		//		Nothing.		if (this.titleNode.lastChild){this.titleNode.removeChild(this.titleNode.lastChild);}				var titleTextNode = document.createElement("div");		titleTextNode.innerHTML = text;		this.titleNode.appendChild(titleTextNode);	},	setTime: function(/*string*/timeText){		//	summary:		//		Function to set the time of the entry.		//	description:		//		Function to set the time of the entry.		//		//	timeText:		//		The string form of the date.		//		//	returns:		//		Nothing.		if (this.timeNode.lastChild){this.timeNode.removeChild(this.timeNode.lastChild);}		var timeTextNode = document.createTextNode(timeText);		this.timeNode.appendChild(timeTextNode);	},	enableDelete: function(){		//	summary:		//		Function to enable the delete action on this entry.		//	description:		//		Function to enable the delete action on this entry.		//		//	returns:		//		Nothing.		if (this.deleteButton !== null) {			//TODO Fix this			this.deleteButton.style.display = 'inline';		}	},	disableDelete: function(){		//	summary:		//		Function to disable the delete action on this entry.		//	description:		//		Function to disable the delete action on this entry.		//		// 	returns:		//		Nothing.		if (this.deleteButton !== null) {			this.deleteButton.style.display = 'none';		}	},	deleteEntry: function(/*object*/event) {		//	summary:		//		Function to handle the delete event and delete the entry.		// 	description:		//		Function to handle the delete event and delete the entry.		//		//	returns:		//		Nothing.		event.preventDefault();		event.stopPropagation();		this.feed.deleteEntry(this);	},	onClick: function(/*object*/e){		//	summary:		//		Attach point for when a row is clicked on.		// 	description:		//		Attach point for when a row is clicked on.		//		// 	e:		//		The event generated by the click.	}});widget.FeedViewerGrouping = dojo.declare(/*===== "dojox.atom.widget.FeedViewerGrouping", =====*/ [_Widget, _Templated],{	//	summary:	//		Grouping of feed entries.	//	description:	//		Grouping of feed entries.	templateString: groupingTemplate,		groupingNode: null,	titleNode: null,	setText: function(text){		//	summary:		//		Sets the text to be shown above this grouping.		//	description:		//		Sets the text to be shown above this grouping.		//		//	text:		//		The text to show.		if (this.titleNode.lastChild){this.titleNode.removeChild(this.titleNode.lastChild);}		var textNode = document.createTextNode(text);		this.titleNode.appendChild(textNode);	}});widget.AtomEntryCategoryFilter = dojo.declare(/*===== "dojox.atom.widget.AtomEntryCategoryFilter", =====*/ [_Widget, _Templated],{	//	summary:	//		A filter to be applied to the list of entries.	//	description:	//		A filter to be applied to the list of entries.	scheme: "",	term: "",	label: "",	isFilter: true});widget.FeedViewer.CategoryIncludeFilter = dojo.declare(/*===== "dojox.atom.widget.FeedViewer.CategoryIncludeFilter", =====*/ null,{	constructor: function(scheme, term, label){		//	summary:		//		The initializer function.		//	description:		//		The initializer function.		this.scheme = scheme;		this.term = term;		this.label = label;	},	match: function(entry) {		//	summary:		//		Function to determine if this category filter matches against a category on an atom entry		//	description:		//		Function to determine if this category filter matches against a category on an atom entry		//		//	returns:		//		boolean denoting if this category filter matched to this entry.		var matched = false;		if (entry !== null) {			var categories = entry.categories;			if (categories !== null) {				for (var i = 0; i < categories.length; i++) {					var category = categories[i];					if (this.scheme !== "") {						if (this.scheme !== category.scheme) {							break;						}					}										if (this.term !== "") {						if (this.term !== category.term) {							break;						}					}					if (this.label !== "") {						if (this.label !== category.label) {							break;						}					}					//Made it this far, everything matched.					matched = true;				}			}		}		return matched;	}});return widget.FeedViewer;});
 |