dojo.provide("dojox.atom.widget.FeedViewer"); dojo.require("dijit._Widget"); dojo.require("dijit._Templated"); dojo.require("dijit._Container"); dojo.require("dojox.atom.io.Connection"); dojo.requireLocalization("dojox.atom.widget", "FeedViewerEntry"); dojo.experimental("dojox.atom.widget.FeedViewer"); dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, dijit._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. templatePath: dojo.moduleUrl("dojox.atom", "widget/templates/FeedViewer.html"), _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 dojox.atom.io.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 dojox.atom.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,dojo.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(dojo.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(dojox.atom.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, dojo.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, dojo.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(); dojo.forEach(this._subscriptions, dojo.unsubscribe); } }); dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget, dijit._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. templatePath: dojo.moduleUrl("dojox.atom", "widget/templates/FeedViewerEntry.html"), entryNode: null, timeNode: null, deleteButton: null, entry: null, feed: null, postCreate: function(){ var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedViewerEntry"); 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. } }); dojo.declare("dojox.atom.widget.FeedViewerGrouping",[dijit._Widget, dijit._Templated],{ // summary: // Grouping of feed entries. // description: // Grouping of feed entries. templatePath: dojo.moduleUrl("dojox.atom", "widget/templates/FeedViewerGrouping.html"), 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); } }); dojo.declare("dojox.atom.widget.AtomEntryCategoryFilter",[dijit._Widget, dijit._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 }); 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; } });