"}});
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 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 ://
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: , term: , label: }
//
// 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: , term: , label: }
//
// 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;
});