dojox/atom/widget/FeedEntryEditor.js

  • Provides:

    • dojox.atom.widget.FeedEntryEditor
  • Requires:

    • dojox.atom.widget.FeedEntryViewer in common
    • dijit._Widget in common in project dijit
    • dijit._Templated in common in project dijit
    • dijit._Container in common in project dijit
    • dijit.Editor in common in project dijit
    • dijit.form.TextBox in common in project dijit
    • dijit.form.SimpleTextarea in common in project dijit
  • dojox.atom.widget.FeedEntryEditor

    • type
      Function
    • chains:
      • dojox.atom.widget.FeedEntryViewer: (prototype)
      • dojox.atom.widget.FeedEntryViewer: (call)
    • summary
      An ATOM feed entry editor that allows viewing of the individual attributes of an entry.
    • description
      An ATOM feed entry editor that allows viewing of the individual attributes of an entry.
  • dojox.atom.widget.FeedEntryEditor._contentEditor

    • summary
  • dojox.atom.widget.FeedEntryEditor._oldContent

    • summary
  • dojox.atom.widget.FeedEntryEditor._setObject

    • summary
  • dojox.atom.widget.FeedEntryEditor.enableEdit

    • summary
  • dojox.atom.widget.FeedEntryEditor._contentEditorCreator

    • summary
  • dojox.atom.widget.FeedEntryEditor._editors

    • type
      Object
    • summary
  • dojox.atom.widget.FeedEntryEditor.entryNewButton

    • summary
  • dojox.atom.widget.FeedEntryEditor._editable

    • summary
  • dojox.atom.widget.FeedEntryEditor.templateString

    • summary
  • dojox.atom.widget.FeedEntryEditor.postCreate

    • type
      Function
    • source: [view]
        if(this.entrySelectionTopic !== ""){
         this._subscriptions = [dojo.subscribe(this.entrySelectionTopic, this, "_handleEvent")];
        }
        var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
        this.displayOptions.innerHTML = _nlsResources.displayOptions;
        this.feedEntryCheckBoxLabelTitle.innerHTML = _nlsResources.title;
        this.feedEntryCheckBoxLabelAuthors.innerHTML = _nlsResources.authors;
        this.feedEntryCheckBoxLabelContributors.innerHTML = _nlsResources.contributors;
        this.feedEntryCheckBoxLabelId.innerHTML = _nlsResources.id;
        this.close.innerHTML = _nlsResources.close;
        this.feedEntryCheckBoxLabelUpdated.innerHTML = _nlsResources.updated;
        this.feedEntryCheckBoxLabelSummary.innerHTML = _nlsResources.summary;
        this.feedEntryCheckBoxLabelContent.innerHTML = _nlsResources.content;


        _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryEditor");
        this.doNew.innerHTML = _nlsResources.doNew;
        this.edit.innerHTML = _nlsResources.edit;
        this.save.innerHTML = _nlsResources.save;
        this.cancel.innerHTML = _nlsResources.cancel;
    • summary
  • dojox.atom.widget.FeedEntryEditor.setEntry

    • type
      Function
    • parameters:
      • entry: (typeof object)
        Instance of dojox.atom.io.model.Entry to display for reading/editing.
      • feed: (typeof object)
      • leaveMenuState: (typeof boolean)
    • source: [view]
        if(this._entry !== entry){
         //If we swap entries, we don't want to keep the menu states and modes.
         this._editMode=false;
         leaveMenuState=false;
        }else{
         leaveMenuState = true;
        }
        dojox.atom.widget.FeedEntryEditor.superclass.setEntry.call(this, entry, feed);
        this._editable = this._isEditable(entry);
        if(!leaveMenuState && !this._editable){
         dojo.style(this.entryEditButton, 'display', 'none');
         dojo.style(this.entrySaveCancelButtons, 'display', 'none');
        }
        if(this._editable && this.enableEdit){
         if(!leaveMenuState){
          dojo.style(this.entryEditButton, 'display', '');
          //TODO double check this &&...
          if(this.enableMenuFade && this.entrySaveCancelButton){
           dojo.fadeOut({node: this.entrySaveCancelButton,duration: 250}).play();
          }
         }
        }
    • summary
      Function to set the current entry that is being edited.
    • description
      Function to set the current entry that is being edited.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass.setEntry: (call)
  • dojox.atom.widget.FeedEntryEditor._toggleEdit

    • type
      Function
    • source: [view]
        if(this._editable && this.enableEdit){
         dojo.style(this.entryEditButton, 'display', 'none');
         dojo.style(this.entrySaveCancelButtons, 'display', '');
         this._editMode = true;


         //Rebuild the view using the same entry and feed.
         this.setEntry(this._entry, this._feed, true);
        }
    • summary
      Internal function for toggling/enabling the display of edit mode
    • description
      Internal function for toggling/enabling the display of edit mode
    • return_summary
      Nothing.
  • dojox.atom.widget.FeedEntryEditor._handleEvent

    • type
      Function
    • parameters:
      • entrySelectionEvent: (typeof object)
        The topic message containing the entry that was selected for view.
    • source: [view]
        if(entrySelectionEvent.source != this && entrySelectionEvent.action == "delete" &&
         entrySelectionEvent.entry && entrySelectionEvent.entry == this._entry){
          dojo.style(this.entryEditButton, 'display', 'none');
        }
        dojox.atom.widget.FeedEntryEditor.superclass._handleEvent.call(this, 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.
    • return_summary
      Nothing.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass._handleEvent: (call)
  • dojox.atom.widget.FeedEntryEditor._isEditable

    • type
      Function
    • parameters:
      • entry: (typeof object)
        The dojox.atom.io.model.Entry object to examine
    • source: [view]
        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;
    • 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.
    • return_summary
      Boolean denoting if the entry seems editable or not..
  • dojox.atom.widget.FeedEntryEditor.setTitle

    • type
      Function
    • parameters:
      • titleAnchorNode: (typeof DOM node)
        The DOM node to attach the title data to.
      • editMode: (typeof boolean)
        Boolean to indicate if the display should be in edit mode or not.
      • entry: (typeof object)
        The Feed Entry to work with.
    • source: [view]
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setTitle.call(this, titleAnchorNode, editMode, entry);
         if(entry.title && entry.title.value && entry.title.value !== null){
          this.setFieldValidity("title", true);
         }
        }else{
         if(entry.title && entry.title.value && entry.title.value !== null){
          if(!this._toLoad){
           this._toLoad = [];
          }
          this.entryTitleSelect.value = entry.title.type;

          
          var editor = this._createEditor(titleAnchorNode, entry.title, true, entry.title.type === "html" || entry.title.type === "xhtml");
          editor.name = "title";
          this._toLoad.push(editor);
          this.setFieldValidity("titleedit",true);
          this.setFieldValidity("title",true);
         }
        }
    • summary
      Function to set the contents of the title node in the template to some value from the entry.
    • description
      Function to set the contents of the title node in the template to some value from the entry.
      This exists specifically so users can over-ride how the title data is filled out from an entry.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass.setTitle: (call)
  • dojox.atom.widget.FeedEntryEditor.setAuthors

    • type
      Function
    • parameters:
      • authorsAnchorNode: (typeof DOM node)
        The DOM node to attach the author data to.
      • editMode: (typeof boolean)
        Boolean to indicate if the display should be in edit mode or not.
      • entry: (typeof object)
        The Feed Entry to work with.
    • source: [view]
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setAuthors.call(this, authorsAnchorNode, editMode, entry);
         if(entry.authors && entry.authors.length > 0){
          this.setFieldValidity("authors", true);
         }
        }else{
         if(entry.authors && entry.authors.length > 0){
          this._editors.authors = this._createPeopleEditor(this.entryAuthorNode, {data: entry.authors, name: "Author"});
          this.setFieldValidity("authors", true);
         }
        }
    • summary
      Function to set the contents of the author node in the template to some value from the entry.
    • description
      Function to set the contents of the author node in the template to some value from the entry.
      This exists specifically so users can over-ride how the title data is filled out from an entry.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass.setAuthors: (call)
  • dojox.atom.widget.FeedEntryEditor.setContributors

    • type
      Function
    • parameters:
      • contributorsAnchorNode: (typeof DOM node)
        The DOM node to attach the contributor data to.
      • editMode: (typeof boolean)
        Boolean to indicate if the display should be in edit mode or not.
      • entry: (typeof object)
        The Feed Entry to work with.
    • source: [view]
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setContributors.call(this, contributorsAnchorNode, editMode, entry);
         if(entry.contributors && entry.contributors.length > 0){
          this.setFieldValidity("contributors", true);
         }
        }else{
         if(entry.contributors && entry.contributors.length > 0){
          this._editors.contributors = this._createPeopleEditor(this.entryContributorNode, {data: entry.contributors, name: "Contributor"});
          this.setFieldValidity("contributors", true);
         }
        }
    • summary
      Function to set the contents of the contributor node in the template to some value from the entry.
    • description
      Function to set the contents of the contributor node in the template to some value from the entry.
      This exists specifically so users can over-ride how the title data is filled out from an entry.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass.setContributors: (call)
  • dojox.atom.widget.FeedEntryEditor.setId

    • type
      Function
    • parameters:
      • idAnchorNode: (typeof DOM node)
        The DOM node to attach the ID data to.
      • editMode: (typeof boolean)
        Boolean to indicate if the display should be in edit mode or not.
      • entry: (typeof object)
        The Feed Entry to work with.
    • source: [view]
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setId.call(this, idAnchorNode, editMode, entry);
         if(entry.id && entry.id !== null){
          this.setFieldValidity("id", true);
         }
        }else{
         if(entry.id && entry.id !== null){
          this._editors.id = this._createEditor(idAnchorNode, entry.id);
          this.setFieldValidity("id",true);
         }
        }
    • summary
      Function to set the contents of the ID  node in the template to some value from the entry.
    • description
      Function to set the contents of the ID node in the template to some value from the entry.
      This exists specifically so users can over-ride how the title data is filled out from an entry.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass.setId: (call)
  • dojox.atom.widget.FeedEntryEditor.setUpdated

    • type
      Function
    • parameters:
      • updatedAnchorNode: (typeof DOM node)
        The DOM node to attach the udpated data to.
      • editMode: (typeof boolean)
        Boolean to indicate if the display should be in edit mode or not.
      • entry: (typeof object)
        The Feed Entry to work with.
    • source: [view]
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setUpdated.call(this, updatedAnchorNode, editMode, entry);
         if(entry.updated && entry.updated !== null){
          this.setFieldValidity("updated", true);
         }
        }else{
         if(entry.updated && entry.updated !== null){
          this._editors.updated = this._createEditor(updatedAnchorNode, entry.updated);
          this.setFieldValidity("updated",true);
         }
        }
    • summary
      Function to set the contents of the updated  node in the template to some value from the entry.
    • description
      Function to set the contents of the updated node in the template to some value from the entry.
      This exists specifically so users can over-ride how the title data is filled out from an entry.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass.setUpdated: (call)
  • dojox.atom.widget.FeedEntryEditor.setSummary

    • type
      Function
    • parameters:
      • summaryAnchorNode: (typeof DOM node)
        The DOM node to attach the summary data to.
      • editMode: (typeof boolean)
        Boolean to indicate if the display should be in edit mode or not.
      • entry: (typeof object)
        The Feed Entry to work with.
    • source: [view]
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setSummary.call(this, summaryAnchorNode, editMode, entry);
         if(entry.summary && entry.summary.value && entry.summary.value !== null){
          this.setFieldValidity("summary", true);
         }
        }else{
         if(entry.summary && entry.summary.value && entry.summary.value !== null){
          if(!this._toLoad){
           this._toLoad = [];
          }
          this.entrySummarySelect.value = entry.summary.type;

          
          var editor = this._createEditor(summaryAnchorNode, entry.summary, true, entry.summary.type === "html" || entry.summary.type === "xhtml");
          editor.name = "summary";
          this._toLoad.push(editor);
          this.setFieldValidity("summaryedit",true);
          this.setFieldValidity("summary",true);
         }
        }
    • summary
      Function to set the contents of the summary  node in the template to some value from the entry.
    • description
      Function to set the contents of the summary node in the template to some value from the entry.
      This exists specifically so users can over-ride how the title data is filled out from an entry.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass.setSummary: (call)
  • dojox.atom.widget.FeedEntryEditor.setContent

    • type
      Function
    • parameters:
      • contentAnchorNode: (typeof DOM node)
      • editMode: (typeof boolean)
        Boolean to indicate if the display should be in edit mode or not.
      • entry: (typeof object)
        The Feed Entry to work with.
    • source: [view]
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setContent.call(this, contentAnchorNode, editMode, entry);
         if(entry.content && entry.content.value && entry.content.value !== null){
          this.setFieldValidity("content",true);
         }
        }else{
         if(entry.content && entry.content.value && entry.content.value !== null){
          if(!this._toLoad){
           this._toLoad = [];
          }
          this.entryContentSelect.value = entry.content.type;
          var editor = this._createEditor(contentAnchorNode, entry.content, true, entry.content.type === "html" || entry.content.type === "xhtml");
          editor.name = "content";
          this._toLoad.push(editor);
          this.setFieldValidity("contentedit",true);
          this.setFieldValidity("content",true);
         }
        }
    • summary
      Function to set the contents of the content node in the template to some value from the entry.
    • description
      Function to set the contents of the content node in the template to some value from the entry.
      This exists specifically so users can over-ride how the title data is filled out from an entry.
      
      summaryAnchorNode:
      The DOM node to attach the content data to.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass.setContent: (call)
  • dojox.atom.widget.FeedEntryEditor._createEditor

    • type
      Function
    • parameters:
      • anchorNode: (typeof DOM node)
        The DOM node to attach the editor widget to.
      • node: (typeof DOM node)
        An object containing the value to be put into the editor.  This ranges from an anonymous object
        with a value parameter to a dojox.atom.io.model.Content object.
      • multiline: (typeof boolean)
        A boolean indicating whether the content should be multiline (such as a textarea) instead of a
        single line (such as a textbox).
      • rte: (typeof object)
        A boolean indicating whether the content should be a rich text editor widget.
    • source: [view]
        var viewNode;
        var box;
        if(!node){
         if(rte){
          // Returns an anonymous object which would then be loaded later, after the containing element
          // exists on the page.
          return {anchorNode: anchorNode,
            entryValue: "",
            editor: null,
            generateEditor: function(){
             // The only way I found I could get the editor to behave consistently was to
             // create the content on a span, and allow the content editor to replace it.
             // This gets around the dynamic/delayed way in which content editors get created.
             var node = document.createElement("div");
             node.innerHTML = this.entryValue;
             this.anchorNode.appendChild(node);
             var _editor = new dijit.Editor({}, node);
             this.editor = _editor;
             return _editor;
            }
          };
         }
         if(multiline){
          // If multiline, create a textarea
          viewNode = document.createElement("textarea");
          anchorNode.appendChild(viewNode);
          dojo.style(viewNode, 'width', '90%');
          box = new dijit.form.SimpleTextarea({},viewNode);
         }else{
          // If single line, create a textbox.
          viewNode = document.createElement("input");
          anchorNode.appendChild(viewNode);
          dojo.style(viewNode, 'width', '95%');
          box = new dijit.form.TextBox({},viewNode);
         }
         box.attr('value', '');
         return box;
        }


        // Check through the node parameter to get the value to be used.
        var value;
        if(node.value !== undefined){
         value = node.value;
        }else if(node.attr){
         value = node.attr('value');
        }else{
         value = node;
        }
        if(rte){
         // Returns an anonymous object which would then be loaded later, after the containing element
         // exists on the page.
         if(value.indexOf("<") != -1){
          value = value.replace(/   }
         return {anchorNode: anchorNode,
           entryValue: value,
           editor: null,
           generateEditor: function(){
            // The only way I found I could get the editor to behave consistently was to
            // create the content on a span, and allow the content editor to replace it.
            // This gets around the dynamic/delayed way in which content editors get created.
            var node = document.createElement("div");
            node.innerHTML = this.entryValue;
            this.anchorNode.appendChild(node);
            var _editor = new dijit.Editor({}, node);
            this.editor = _editor;
            return _editor;
           }
         };
        }
        if(multiline){
         // If multiline, create a textarea
         viewNode = document.createElement("textarea");
         anchorNode.appendChild(viewNode);
         dojo.style(viewNode, 'width', '90%');
         box = new dijit.form.SimpleTextarea({},viewNode);
        }else{
         // If single line, create a textbox.
         viewNode = document.createElement("input");
         anchorNode.appendChild(viewNode);
         dojo.style(viewNode, 'width', '95%');
         box = new dijit.form.TextBox({},viewNode);
        }
        box.attr('value', value);
        return box;
    • summary
      Function to create an appropriate text editor widget based on the given parameters.
    • description
      Function to create an appropriate text editor widget based on the given parameters.
    • return_summary
      Either a widget (for textarea or textbox widgets) or an anonymous object to be used to create a
      rich text area widget.
  • dojox.atom.widget.FeedEntryEditor._switchEditor

    • type
      Function
    • parameters:
      • event: (typeof object)
        The event generated by the change in the select box on the page.
    • source: [view]
        var type = null;
        var target = null;
        var parent = null;

        
        // Determine the source/target of this event (to determine which editor we're switching)
        if(dojo.isIE){
         target = event.srcElement;
        }else{
         target = event.target;
        }

         
        // Determine which editor (title, summary, or content)
        if(target === this.entryTitleSelect){
         parent = this.entryTitleNode;
         type = "title";
        } else if(target === this.entrySummarySelect){
         parent = this.entrySummaryNode;
         type = "summary";
        }else{
         parent = this.entryContentNode;
         type = "content";
        }


        // Grab the existing editor.
        var editor = this._editors[type];
        var newEditor;
        var value;

        
        if(target.value === "text"){
         if(editor.declaredClass === "dijit.Editor"){
          // If we're changing the type to text and our existing editor is a rich text editor, we need to destroy
          // it and switch to a multiline editor.
          value = editor.attr('value', false);
          editor.close(false,true);
          editor.destroy();
          while(parent.firstChild){
           dojo.destroy(parent.firstChild);
          }
          newEditor = this._createEditor(parent, {value: value}, true, false);
          this._editors[type] = newEditor;
         }
        }else{
         if(editor.declaredClass != "dijit.Editor"){
          // Otherwise, we're switching to a html or xhtml type, but we currently have a textarea widget. We need
          // to destroy the existing RTE and create a multiline textarea widget.
          value = editor.attr('value');
          editor.destroy();
          while(parent.firstChild){
           dojo.destroy(parent.firstChild);
          }
          newEditor = this._createEditor(parent, {value: value}, true, true);
          newEditor = dojo.hitch(newEditor, newEditor.generateEditor)();
          this._editors[type] = newEditor;
         }
        }
    • summary
      Function to switch between editor types.
    • description
      Function to switch between a rich text editor and a textarea widget.  Used for title, summary,
      And content when switching between text and html/xhtml content.
  • dojox.atom.widget.FeedEntryEditor._createPeopleEditor

    • type
      Function
    • parameters:
      • anchorNode: (typeof DOM node)
        The node to attach the editor to.
      • node: (typeof DOM node)
        An object containing the value to be put into the editor. Typically, this is an
        dojox.atom.io.model.Person object.
    • source: [view]
        var viewNode = document.createElement("div");
        anchorNode.appendChild(viewNode);
        return new dojox.atom.widget.PeopleEditor(node,viewNode);
    • summary
      Creates a People Editor widget and returns it.
    • description
      Creates a People Editor widget, sets its value, and returns it.
    • return_summary
      A new People Editor object.
  • dojox.atom.widget.FeedEntryEditor.saveEdits

    • type
      Function
    • source: [view]
        dojo.style(this.entrySaveCancelButtons, 'display', 'none');
        dojo.style(this.entryEditButton, 'display', '');
        dojo.style(this.entryNewButton, 'display', '');
        var modifiedEntry = false;
        var value;
        var i;
        var changed;
        var entry;
        var authors;
        var contributors;
        if(!this._new){
         entry = this.getEntry();
         if(this._editors.title && (this._editors.title.attr('value') != entry.title.value || this.entryTitleSelect.value != entry.title.type)){
          value = this._editors.title.attr('value');
          if(this.entryTitleSelect.value === "xhtml"){
           value = this._enforceXhtml(value);
           if(value.indexOf('
      ') !== 0){
            value = '
      ' + value + '
      ';
           }
          }
          entry.title = new dojox.atom.io.model.Content("title", value, null, this.entryTitleSelect.value);
          modifiedEntry = true;
         }

         
         if(this._editors.id.attr('value') != entry.id){
          entry.id = this._editors.id.attr('value');
          modifiedEntry = true;
         }

         
         if(this._editors.summary && (this._editors.summary.attr('value') != entry.summary.value || this.entrySummarySelect.value != entry.summary.type)){
          value = this._editors.summary.attr('value');
          if(this.entrySummarySelect.value === "xhtml"){
           value = this._enforceXhtml(value);
           if(value.indexOf('
      ') !== 0){
            value = '
      ' + value + '
      ';
           }
          }
          entry.summary = new dojox.atom.io.model.Content("summary", value, null, this.entrySummarySelect.value);
          modifiedEntry = true;
         }

         
         if(this._editors.content && (this._editors.content.attr('value') != entry.content.value || this.entryContentSelect.value != entry.content.type)){
          value = this._editors.content.attr('value');
          if(this.entryContentSelect.value === "xhtml"){
           value = this._enforceXhtml(value);
           if(value.indexOf('
      ') !== 0){
            value = '
      ' + value + '
      ';
           }
          }
          entry.content = new dojox.atom.io.model.Content("content", value, null, this.entryContentSelect.value);
          modifiedEntry = true;
         }

         
         if(this._editors.authors){
          if(modifiedEntry){
           entry.authors = [];
           authors = this._editors.authors.getValues();
           for(i in authors){
            if(authors[i].name || authors[i].email || authors[i].uri){
             entry.addAuthor(authors[i].name, authors[i].email, authors[i].uri);
            }
           }
          }else{
           var currentAuthors = entry.authors;
           var searchAuthors = function(name, email, uri){
            for(i in currentAuthors){
             if(currentAuthors[i].name === name && currentAuthors[i].email === email && currentAuthors[i].uri === uri){
              return true;
             }
            }
            return false;
           };
           authors = this._editors.authors.getValues();
           changed = false;
           for(i in authors){
            if(!searchAuthors(authors[i].name, authors[i].email, authors[i].uri)){
             changed = true;
             break;
            }
           }
           if(changed){
            entry.authors = [];
            for(i in authors){
             if(authors[i].name || authors[i].email || authors[i].uri){
              entry.addAuthor(authors[i].name, authors[i].email, authors[i].uri);
             }
            }
            modifiedEntry = true;
           }
          }
         }

         
         if(this._editors.contributors){
         if(modifiedEntry){
           entry.contributors = [];
           contributors = this._editors.contributors.getValues();
           for(i in contributors){
            if(contributors[i].name || contributors[i].email || contributors[i].uri){
             entry.addAuthor(contributors[i].name, contributors[i].email, contributors[i].uri);
            }
           }
          }else{
           var currentContributors = entry.contributors;
           var searchContributors = function(name, email, uri){
            for(i in currentContributors){
             if(currentContributors[i].name === name && currentContributors[i].email === email && currentContributors[i].uri === uri){
              return true;
             }
            }
            return false;
           };
           contributors = this._editors.contributors.getValues();
           changed = false;
           for(i in contributors){
            if(searchContributors(contributors[i].name, contributors[i].email, contributors[i].uri)){
             changed = true;
             break;
            }
           }
           if(changed){
            entry.contributors = [];
            for(i in contributors){
             if(contributors[i].name || contributors[i].email || contributors[i].uri){
              entry.addContributor(contributors[i].name, contributors[i].email, contributors[i].uri);
             }
            }
            modifiedEntry = true;
           }
          }
         }


         if(modifiedEntry){
          dojo.publish(this.entrySelectionTopic, [{action: "update", source: this, entry: entry, callback: this._handleSave }]);
          //TODO: REMOVE BELOW
          //var atomIO = new dojox.atom.io.Connection();
          //atomIO.updateEntry(entry, dojo.hitch(this,this._handleSave));
          //WARNING: Use above when testing with SimpleProxy (or any other servlet which
          //    doesn't actually create a new entry and return it properly)
          //atomIO.updateEntry(entry, dojo.hitch(this,this._handleSave), true);
         }
        }else{
         this._new = false;
         entry = new dojox.atom.io.model.Entry();

         
         value = this._editors.title.attr('value');
         if(this.entryTitleSelect.value === "xhtml"){
          value = this._enforceXhtml(value);
          value = '
      ' + value + '
      ';
         }
         entry.setTitle(value, this.entryTitleSelect.value);
         entry.id = this._editors.id.attr('value');

         
         authors = this._editors.authors.getValues();
         for(i in authors){
          if(authors[i].name || authors[i].email || authors[i].uri){
           entry.addAuthor(authors[i].name, authors[i].email, authors[i].uri);
          }
         }

           
         contributors = this._editors.contributors.getValues();
         for(i in contributors){
          if(contributors[i].name || contributors[i].email || contributors[i].uri){
           entry.addContributor(contributors[i].name, contributors[i].email, contributors[i].uri);
          }
         }



         
         value = this._editors.summary.attr('value');
         if(this.entrySummarySelect.value === "xhtml"){
          value = this._enforceXhtml(value);
          value = '
      ' + value + '
      ';
         }
         entry.summary = new dojox.atom.io.model.Content("summary", value, null, this.entrySummarySelect.value);


         value = this._editors.content.attr('value');
         if(this.entryContentSelect.value === "xhtml"){
          value = this._enforceXhtml(value);
          value = '
      ' + value + '
      ';
         }
         entry.content = new dojox.atom.io.model.Content("content", value, null, this.entryContentSelect.value);


         dojo.style(this.entryNewButton, 'display', '');
         dojo.publish(this.entrySelectionTopic, [{action: "post", source: this, entry: entry }]);
        }
        this._editMode = false;

        
        //Rebuild the view using the same entry and feed.
        this.setEntry(entry, this._feed, true);
    • summary
      Saves edits submitted when the 'save' button is pressed.
    • description
      Saves edits submitted when the 'save' button is pressed.  Distinguishes between new and existing
      entries and saves appropriately.  Fetches the values of the editors, and, if existing, compares them to
      the existing values and submits the updates, otherwise creates a new entry and posts it as a new entry.
    • return_summary
      Nothing.
  • dojox.atom.widget.FeedEntryEditor._handleSave

    • type
      Function
    • parameters:
      • entry: (typeof object)
        dojox.atom.io.model.Entry object
        The entry that was saved.
        Location: String
        A URL to be used, not used here, but part of the call back from the AtomIO
      • location: (typeof string)
    • source: [view]
        this._editMode = false;

        
        //Rebuild the view using the same entry and feed.
        this.clear();
        this.setEntry(entry, this.getFeed(), true);
    • summary
      Function for handling the save of an entry, cleaning up the display after the edit is completed.
    • description
      Function for handling the save of an entry, cleaning up the display after the edit is completed.
    • return_summary
      Nothing.
      Close the editor and revert out.
  • dojox.atom.widget.FeedEntryEditor.cancelEdits

    • type
      Function
    • source: [view]
        this._new = false;
        dojo.style(this.entrySaveCancelButtons, 'display', 'none');
        if(this._editable){
         dojo.style(this.entryEditButton, 'display', '');
        }
        dojo.style(this.entryNewButton, 'display', '');
        this._editMode = false;

        
        //Rebuild the view using the same entry and feed.
        this.clearEditors();
        this.setEntry(this.getEntry(), this.getFeed(), true);
    • summary
      Cancels edits and reverts the editor to its previous state (display mode)
    • description
      Cancels edits and reverts the editor to its previous state (display mode)
    • return_summary
      Nothing.
  • dojox.atom.widget.FeedEntryEditor.clear

    • type
      Function
    • source: [view]
        this._editable=false;
        this.clearEditors();
        dojox.atom.widget.FeedEntryEditor.superclass.clear.apply(this);
        if(this._contentEditor){
         // Note that the superclass clear destroys the widget since it's in the child widget list,
         // so this is just ref clearing.
         this._contentEditor = this._setObject = this._oldContent = this._contentEditorCreator = null;
         this._editors = {};
        }
    • summary
      Clears the editor, destorys all editors, leaving the editor completely clear
    • description
      Clears the editor, destorys all editors, leaving the editor completely clear
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass.clear: (call)
  • dojox.atom.widget.FeedEntryEditor.clearEditors

    • type
      Function
    • source: [view]
        for(var key in this._editors){
         if(this._editors[key].declaredClass === "dijit.Editor"){
          this._editors[key].close(false, true);
         }
         this._editors[key].destroy();
        }
        this._editors = {};
    • summary
  • dojox.atom.widget.FeedEntryEditor._enforceXhtml

    • type
      Function
    • parameters:
      • html: (typeof string)
        HTML string to be enforced as xhtml.
    • source: [view]
        var xhtml = null;
        if(html){
         //Handle

         var brRegExp = /
      /g;
         xhtml = html.replace(brRegExp, "
      ");


         //Handle

         xhtml = this._closeTag(xhtml, "hr");


         //Handle
         xhtml = this._closeTag(xhtml, "img");
        }
        return xhtml;
    • summary
      Function for cleaning up/enforcing the XHTML standard in HTML returned from the editor2 widget.
    • description
      Function for cleaning up/enforcing the XHTML standard in HTML returned from the editor2 widget.
    • return_summary
      string of cleaned up HTML.
  • dojox.atom.widget.FeedEntryEditor._closeTag

    • type
      Function
    • parameters:
      • xhtml: (typeof string)
        String
        XHTML string which needs the closing tag.
      • tag: (typeof string)
        The tag to close.
    • source: [view]
        var tagStart = "<" + tag;
        var tagIndex = xhtml.indexOf(tagStart);
        if(tagIndex !== -1){
         while (tagIndex !== -1){
          var tempString = "";
          var foundTagEnd = false;
          for (var i = 0; i < xhtml.length; i++){
           var c = xhtml.charAt(i);
           if(i <= tagIndex ||foundTagEnd){
            tempString += c;
           }
           else
           {
            if(c === '>'){
             tempString += "/";
             foundTagEnd = true;
            }
            tempString +=c;
           }
          }
          xhtml = tempString;
          tagIndex = xhtml.indexOf(tagStart, tagIndex + 1);
         }
        }
        return xhtml;
    • summary
      Function for closing tags in a text of HTML/XHTML
    • description
      Function for closing tags in a text of HTML/XHTML
    • return_summary
      string of cleaned up HTML.
      
      NOTE:  Probably should redo this function in a more efficient way.  This could get expensive.
  • dojox.atom.widget.FeedEntryEditor._toggleNew

    • type
      Function
    • source: [view]
        dojo.style(this.entryNewButton, 'display', 'none');
        dojo.style(this.entryEditButton, 'display', 'none');
        dojo.style(this.entrySaveCancelButtons, 'display', '');

        
        // Reset the type select boxes to text.
        this.entrySummarySelect.value = "text";
        this.entryContentSelect.value = "text";
        this.entryTitleSelect.value = "text";

        
        // Clear all nodes.
        this.clearNodes();
        this._new = true;

        
        var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
        // Create all headers and editors.
        var titleHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.title});
        this.entryTitleHeader.appendChild(titleHeader.domNode);

        
        this._editors.title = this._createEditor(this.entryTitleNode, null);
        this.setFieldValidity("title",true);

        
        var authorHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.authors});
        this.entryAuthorHeader.appendChild(authorHeader.domNode);


        this._editors.authors = this._createPeopleEditor(this.entryAuthorNode, {name: "Author"});
        this.setFieldValidity("authors", true);

        
        var contributorHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.contributors});
        this.entryContributorHeader.appendChild(contributorHeader.domNode);


        this._editors.contributors = this._createPeopleEditor(this.entryContributorNode, {name: "Contributor"});
        this.setFieldValidity("contributors", true);

        
        var idHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.id});
        this.entryIdHeader.appendChild(idHeader.domNode);

        
        this._editors.id = this._createEditor(this.entryIdNode, null);
        this.setFieldValidity("id",true);


        var updatedHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.updated});
        this.entryUpdatedHeader.appendChild(updatedHeader.domNode);

        
        this._editors.updated = this._createEditor(this.entryUpdatedNode, null);
        this.setFieldValidity("updated",true);


        var summaryHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.summary});
        this.entrySummaryHeader.appendChild(summaryHeader.domNode);

        
        this._editors.summary = this._createEditor(this.entrySummaryNode, null, true);
        this.setFieldValidity("summaryedit",true);
        this.setFieldValidity("summary",true);


        var contentHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.content});
        this.entryContentHeader.appendChild(contentHeader.domNode);

        
        this._editors.content = this._createEditor(this.entryContentNode, null, true);
        this.setFieldValidity("contentedit",true);
        this.setFieldValidity("content",true);


        // Show the sections.
        this._displaySections();
    • summary
      Function to put the editor into a state to create a new entry.
    • description
      Function to put the editor into a state to create a new entry.
      
      Hide the edit/new buttons and show the save/cancel buttons.
  • dojox.atom.widget.FeedEntryEditor._displaySections

    • type
      Function
    • source: [view]
        dojo.style(this.entrySummarySelect, 'display', 'none');
        dojo.style(this.entryContentSelect, 'display', 'none');
        dojo.style(this.entryTitleSelect, 'display', 'none');


        // Show select boxes if the flags are set.
        if(this.isFieldValid("contentedit")){
         dojo.style(this.entryContentSelect, 'display', '');
        }
        if(this.isFieldValid("summaryedit")){
         dojo.style(this.entrySummarySelect, 'display', '');
        }
        if(this.isFieldValid("titleedit")){
         dojo.style(this.entryTitleSelect, 'display', '');
        }
        // Call super's _displaySections.
        dojox.atom.widget.FeedEntryEditor.superclass._displaySections.apply(this);

        
        // If we have editors to load after the nodes are created on the page, execute those now.
        if(this._toLoad){
         for(var i in this._toLoad){
          var editor;
          if(this._toLoad[i].generateEditor){
           editor = dojo.hitch(this._toLoad[i], this._toLoad[i].generateEditor)();
          }else{
           editor = this._toLoad[i];
          }
          this._editors[this._toLoad[i].name] = editor;
          this._toLoad[i] = null;
         }
         this._toLoad = null;
        }
    • summary
      Function to display the appropriate sections based on validity.
    • description
      Function to display the appropriate sections based on validity.
      
      Hide select boxes.
    • chains:
      • dojox.atom.widget.FeedEntryEditor.superclass._displaySections: (call)
  • dojox.atom.widget.FeedEntryEditor._subscriptions

    • summary
  • dojox.atom.widget.FeedEntryEditor.displayOptions.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.feedEntryCheckBoxLabelTitle.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.feedEntryCheckBoxLabelAuthors.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.feedEntryCheckBoxLabelContributors.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.feedEntryCheckBoxLabelId.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.close.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.feedEntryCheckBoxLabelUpdated.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.feedEntryCheckBoxLabelSummary.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.feedEntryCheckBoxLabelContent.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.doNew.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.edit.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.save.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor.cancel.innerHTML

    • summary
  • dojox.atom.widget.FeedEntryEditor._editMode

    • summary
  • dojox.atom.widget.FeedEntryEditor._toLoad

    • summary
  • dojox.atom.widget.FeedEntryEditor.entryTitleSelect.value

    • summary
  • dojox.atom.widget.FeedEntryEditor._editors.authors

    • summary
  • dojox.atom.widget.FeedEntryEditor._editors.contributors

    • summary
  • dojox.atom.widget.FeedEntryEditor._editors.id

    • summary
  • dojox.atom.widget.FeedEntryEditor._editors.updated

    • summary
  • dojox.atom.widget.FeedEntryEditor.entrySummarySelect.value

    • summary
  • dojox.atom.widget.FeedEntryEditor.entryContentSelect.value

    • summary
  • dojox.atom.widget.FeedEntryEditor.editor

    • summary
  • dojox.atom.widget.FeedEntryEditor._new

    • summary
  • dojox.atom.widget.FeedEntryEditor._editors.title

    • summary
  • dojox.atom.widget.FeedEntryEditor._editors.summary

    • summary
  • dojox.atom.widget.FeedEntryEditor._editors.content

    • summary
  • dojox.atom.widget.PeopleEditor

    • type
      Function
    • chains:
      • dijit._Widget: (prototype)
      • dijit._Widget: (call)
      • dijit._Templated: (call)
      • dijit._Container: (call)
    • mixins:
      • dijit._Templated.prototype: (prototype)
      • dijit._Container.prototype: (prototype)
    • summary
      An editor for dojox.atom.io.model.Person objects.
    • description
      An editor for dojox.atom.io.model.Person objects.  Displays multiple rows for the respective arrays
      of people.  Can add/remove rows on the fly.
  • dojox.atom.widget.PeopleEditor.templateString

    • summary
  • dojox.atom.widget.PeopleEditor._rows

    • summary
  • dojox.atom.widget.PeopleEditor._editors

    • summary
  • dojox.atom.widget.PeopleEditor._index

    • summary
  • dojox.atom.widget.PeopleEditor._numRows

    • summary
  • dojox.atom.widget.PeopleEditor.postCreate

    • type
      Function
    • source: [view]
      dojo.provide("dojox.atom.widget.FeedEntryEditor");


      dojo.require("dojox.atom.widget.FeedEntryViewer");
      dojo.require("dijit._Widget");
      dojo.require("dijit._Templated");
      dojo.require("dijit._Container");
      dojo.require("dijit.Editor");
      dojo.require("dijit.form.TextBox");
      dojo.require("dijit.form.SimpleTextarea");
      dojo.requireLocalization("dojox.atom.widget", "FeedEntryEditor");
      dojo.requireLocalization("dojox.atom.widget", "PeopleEditor");


      dojo.experimental("dojox.atom.widget.FeedEntryEditor");


      dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryViewer,{
       // summary:
       //  An ATOM feed entry editor that allows viewing of the individual attributes of an entry.
       // description:
       //  An ATOM feed entry editor that allows viewing of the individual attributes of an entry.
       _contentEditor: null,
       _oldContent: null,
       _setObject: null,
       enableEdit: false,
       _contentEditorCreator: null,
       _editors: {},
       entryNewButton: null,
       _editable: false,  //Flag denoting if the current entry is editable or not.


       //Templates for the HTML rendering. Need to figure these out better, admittedly.
       templateString: dojo.cache("dojox.atom", "widget/templates/FeedEntryEditor.html"),


       postCreate: function(){
        if(this.entrySelectionTopic !== ""){
         this._subscriptions = [dojo.subscribe(this.entrySelectionTopic, this, "_handleEvent")];
        }
        var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
        this.displayOptions.innerHTML = _nlsResources.displayOptions;
        this.feedEntryCheckBoxLabelTitle.innerHTML = _nlsResources.title;
        this.feedEntryCheckBoxLabelAuthors.innerHTML = _nlsResources.authors;
        this.feedEntryCheckBoxLabelContributors.innerHTML = _nlsResources.contributors;
        this.feedEntryCheckBoxLabelId.innerHTML = _nlsResources.id;
        this.close.innerHTML = _nlsResources.close;
        this.feedEntryCheckBoxLabelUpdated.innerHTML = _nlsResources.updated;
        this.feedEntryCheckBoxLabelSummary.innerHTML = _nlsResources.summary;
        this.feedEntryCheckBoxLabelContent.innerHTML = _nlsResources.content;


        _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryEditor");
        this.doNew.innerHTML = _nlsResources.doNew;
        this.edit.innerHTML = _nlsResources.edit;
        this.save.innerHTML = _nlsResources.save;
        this.cancel.innerHTML = _nlsResources.cancel;
       },

       
       setEntry: function(/*object*/entry, /*object*/feed, /*boolean*/leaveMenuState){
        // summary:
        //  Function to set the current entry that is being edited.
        // description:
        //  Function to set the current entry that is being edited.
        //
        // entry:
        //  Instance of dojox.atom.io.model.Entry to display for reading/editing.
        if(this._entry !== entry){
         //If we swap entries, we don't want to keep the menu states and modes.
         this._editMode=false;
         leaveMenuState=false;
        }else{
         leaveMenuState = true;
        }
        dojox.atom.widget.FeedEntryEditor.superclass.setEntry.call(this, entry, feed);
        this._editable = this._isEditable(entry);
        if(!leaveMenuState && !this._editable){
         dojo.style(this.entryEditButton, 'display', 'none');
         dojo.style(this.entrySaveCancelButtons, 'display', 'none');
        }
        if(this._editable && this.enableEdit){
         if(!leaveMenuState){
          dojo.style(this.entryEditButton, 'display', '');
          //TODO double check this &&...
          if(this.enableMenuFade && this.entrySaveCancelButton){
           dojo.fadeOut({node: this.entrySaveCancelButton,duration: 250}).play();
          }
         }
        }
       },


       _toggleEdit: function(){
        // summary:
        //  Internal function for toggling/enabling the display of edit mode
        // description:
        //  Internal function for toggling/enabling the display of edit mode
        //
        // returns:
        //  Nothing.
        if(this._editable && this.enableEdit){
         dojo.style(this.entryEditButton, 'display', 'none');
         dojo.style(this.entrySaveCancelButtons, 'display', '');
         this._editMode = true;


         //Rebuild the view using the same entry and feed.
         this.setEntry(this._entry, this._feed, true);
        }
       },


       _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 && entrySelectionEvent.action == "delete" &&
         entrySelectionEvent.entry && entrySelectionEvent.entry == this._entry){
          dojo.style(this.entryEditButton, 'display', 'none');
        }
        dojox.atom.widget.FeedEntryEditor.superclass._handleEvent.call(this, entrySelectionEvent);
       },


       _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;
       },

       
       // The following set functions override the corresponding functions in FeedEntryViewer. These handle
       // the editMode flag by inserting appropriate editor widgets inside of just splashing the content in the page.
       setTitle: function(/*DOM node*/titleAnchorNode, /*boolean*/editMode, /*object*/entry){
        // summary:
        //  Function to set the contents of the title node in the template to some value from the entry.
        // description:
        //  Function to set the contents of the title node in the template to some value from the entry.
        //  This exists specifically so users can over-ride how the title data is filled out from an entry.
        //
        // titleAnchorNode:
        //  The DOM node to attach the title data to.
        // editMode:
        //   Boolean to indicate if the display should be in edit mode or not.
        // entry:
        //  The Feed Entry to work with.
        //
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setTitle.call(this, titleAnchorNode, editMode, entry);
         if(entry.title && entry.title.value && entry.title.value !== null){
          this.setFieldValidity("title", true);
         }
        }else{
         if(entry.title && entry.title.value && entry.title.value !== null){
          if(!this._toLoad){
           this._toLoad = [];
          }
          this.entryTitleSelect.value = entry.title.type;

          
          var editor = this._createEditor(titleAnchorNode, entry.title, true, entry.title.type === "html" || entry.title.type === "xhtml");
          editor.name = "title";
          this._toLoad.push(editor);
          this.setFieldValidity("titleedit",true);
          this.setFieldValidity("title",true);
         }
        }
       },


       setAuthors: function(/*DOM node*/authorsAnchorNode, /*boolean*/editMode, /*object*/entry){
        // summary:
        //  Function to set the contents of the author node in the template to some value from the entry.
        // description:
        //  Function to set the contents of the author node in the template to some value from the entry.
        //  This exists specifically so users can over-ride how the title data is filled out from an entry.
        //
        // authorsAnchorNode:
        //  The DOM node to attach the author data to.
        // editMode:
        //   Boolean to indicate if the display should be in edit mode or not.
        // entry:
        //   The Feed Entry to work with.
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setAuthors.call(this, authorsAnchorNode, editMode, entry);
         if(entry.authors && entry.authors.length > 0){
          this.setFieldValidity("authors", true);
         }
        }else{
         if(entry.authors && entry.authors.length > 0){
          this._editors.authors = this._createPeopleEditor(this.entryAuthorNode, {data: entry.authors, name: "Author"});
          this.setFieldValidity("authors", true);
         }
        }
       },




       setContributors: function(/*DOM node*/contributorsAnchorNode, /*boolean*/editMode, /*object*/entry){
        // summary:
        //  Function to set the contents of the contributor node in the template to some value from the entry.
        // description:
        //  Function to set the contents of the contributor node in the template to some value from the entry.
        //  This exists specifically so users can over-ride how the title data is filled out from an entry.
        //
        // contributorsAnchorNode:
        //  The DOM node to attach the contributor data to.
        // editMode:
        //  Boolean to indicate if the display should be in edit mode or not.
        // entry:
        //  The Feed Entry to work with.
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setContributors.call(this, contributorsAnchorNode, editMode, entry);
         if(entry.contributors && entry.contributors.length > 0){
          this.setFieldValidity("contributors", true);
         }
        }else{
         if(entry.contributors && entry.contributors.length > 0){
          this._editors.contributors = this._createPeopleEditor(this.entryContributorNode, {data: entry.contributors, name: "Contributor"});
          this.setFieldValidity("contributors", true);
         }
        }
       },




       setId: function(/*DOM node*/idAnchorNode, /*boolean*/editMode, /*object*/entry){
        // summary:
        //  Function to set the contents of the ID node in the template to some value from the entry.
        // description:
        //  Function to set the contents of the ID node in the template to some value from the entry.
        //  This exists specifically so users can over-ride how the title data is filled out from an entry.
        //
        // idAnchorNode:
        //  The DOM node to attach the ID data to.
        // editMode:
        //  Boolean to indicate if the display should be in edit mode or not.
        // entry:
        //  The Feed Entry to work with.
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setId.call(this, idAnchorNode, editMode, entry);
         if(entry.id && entry.id !== null){
          this.setFieldValidity("id", true);
         }
        }else{
         if(entry.id && entry.id !== null){
          this._editors.id = this._createEditor(idAnchorNode, entry.id);
          this.setFieldValidity("id",true);
         }
        }
       },


       setUpdated: function(/*DOM node*/updatedAnchorNode, /*boolean*/editMode, /*object*/entry){
        // summary:
        //  Function to set the contents of the updated node in the template to some value from the entry.
        // description:
        //  Function to set the contents of the updated node in the template to some value from the entry.
        //  This exists specifically so users can over-ride how the title data is filled out from an entry.
        //
        // updatedAnchorNode:
        //  The DOM node to attach the udpated data to.
        // editMode:
        //  Boolean to indicate if the display should be in edit mode or not.
        // entry:
        //  The Feed Entry to work with.
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setUpdated.call(this, updatedAnchorNode, editMode, entry);
         if(entry.updated && entry.updated !== null){
          this.setFieldValidity("updated", true);
         }
        }else{
         if(entry.updated && entry.updated !== null){
          this._editors.updated = this._createEditor(updatedAnchorNode, entry.updated);
          this.setFieldValidity("updated",true);
         }
        }
       },




       setSummary: function(/*DOM node*/summaryAnchorNode, /*boolean*/editMode, /*object*/entry){
        // summary:
        //  Function to set the contents of the summary node in the template to some value from the entry.
        // description:
        //  Function to set the contents of the summary node in the template to some value from the entry.
        //  This exists specifically so users can over-ride how the title data is filled out from an entry.
        //
        // summaryAnchorNode:
        //  The DOM node to attach the summary data to.
        // editMode:
        //  Boolean to indicate if the display should be in edit mode or not.
        // entry:
        //  The Feed Entry to work with.
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setSummary.call(this, summaryAnchorNode, editMode, entry);
         if(entry.summary && entry.summary.value && entry.summary.value !== null){
          this.setFieldValidity("summary", true);
         }
        }else{
         if(entry.summary && entry.summary.value && entry.summary.value !== null){
          if(!this._toLoad){
           this._toLoad = [];
          }
          this.entrySummarySelect.value = entry.summary.type;

          
          var editor = this._createEditor(summaryAnchorNode, entry.summary, true, entry.summary.type === "html" || entry.summary.type === "xhtml");
          editor.name = "summary";
          this._toLoad.push(editor);
          this.setFieldValidity("summaryedit",true);
          this.setFieldValidity("summary",true);
         }
        }
       },


       setContent: function(/*DOM node*/contentAnchorNode, /*boolean*/editMode, /*object*/entry){
        // summary:
        //  Function to set the contents of the content node in the template to some value from the entry.
        // description:
        //  Function to set the contents of the content node in the template to some value from the entry.
        //  This exists specifically so users can over-ride how the title data is filled out from an entry.
        //
        // summaryAnchorNode:
        //  The DOM node to attach the content data to.
        // editMode:
        //  Boolean to indicate if the display should be in edit mode or not.
        //  entry:
        //  The Feed Entry to work with.
        if(!editMode){
         dojox.atom.widget.FeedEntryEditor.superclass.setContent.call(this, contentAnchorNode, editMode, entry);
         if(entry.content && entry.content.value && entry.content.value !== null){
          this.setFieldValidity("content",true);
         }
        }else{
         if(entry.content && entry.content.value && entry.content.value !== null){
          if(!this._toLoad){
           this._toLoad = [];
          }
          this.entryContentSelect.value = entry.content.type;
          var editor = this._createEditor(contentAnchorNode, entry.content, true, entry.content.type === "html" || entry.content.type === "xhtml");
          editor.name = "content";
          this._toLoad.push(editor);
          this.setFieldValidity("contentedit",true);
          this.setFieldValidity("content",true);
         }
        }
       },

       
       _createEditor: function(/*DOM node*/anchorNode, /*DOM node*/node, /*boolean*/multiline, /*object*/rte){
        // summary:
        //  Function to create an appropriate text editor widget based on the given parameters.
        // description:
        //  Function to create an appropriate text editor widget based on the given parameters.
        //
        // anchorNode:
        //  The DOM node to attach the editor widget to.
        // node:
        //  An object containing the value to be put into the editor. This ranges from an anonymous object
        //  with a value parameter to a dojox.atom.io.model.Content object.
        // multiline:
        //  A boolean indicating whether the content should be multiline (such as a textarea) instead of a
        //  single line (such as a textbox).
        // rte:
        //  A boolean indicating whether the content should be a rich text editor widget.
        //
        // returns:
        //  Either a widget (for textarea or textbox widgets) or an anonymous object to be used to create a
        //  rich text area widget.
        var viewNode;
        var box;
        if(!node){
         if(rte){
          // Returns an anonymous object which would then be loaded later, after the containing element
          // exists on the page.
          return {anchorNode: anchorNode,
            entryValue: "",
            editor: null,
            generateEditor: function(){
             // The only way I found I could get the editor to behave consistently was to
             // create the content on a span, and allow the content editor to replace it.
             // This gets around the dynamic/delayed way in which content editors get created.
             var node = document.createElement("div");
             node.innerHTML = this.entryValue;
             this.anchorNode.appendChild(node);
             var _editor = new dijit.Editor({}, node);
             this.editor = _editor;
             return _editor;
            }
          };
         }
         if(multiline){
          // If multiline, create a textarea
          viewNode = document.createElement("textarea");
          anchorNode.appendChild(viewNode);
          dojo.style(viewNode, 'width', '90%');
          box = new dijit.form.SimpleTextarea({},viewNode);
         }else{
          // If single line, create a textbox.
          viewNode = document.createElement("input");
          anchorNode.appendChild(viewNode);
          dojo.style(viewNode, 'width', '95%');
          box = new dijit.form.TextBox({},viewNode);
         }
         box.attr('value', '');
         return box;
        }


        // Check through the node parameter to get the value to be used.
        var value;
        if(node.value !== undefined){
         value = node.value;
        }else if(node.attr){
         value = node.attr('value');
        }else{
         value = node;
        }
        if(rte){
         // Returns an anonymous object which would then be loaded later, after the containing element
         // exists on the page.
         if(value.indexOf("<") != -1){
          value = value.replace(/   }
         return {anchorNode: anchorNode,
           entryValue: value,
           editor: null,
           generateEditor: function(){
            // The only way I found I could get the editor to behave consistently was to
            // create the content on a span, and allow the content editor to replace it.
            // This gets around the dynamic/delayed way in which content editors get created.
            var node = document.createElement("div");
            node.innerHTML = this.entryValue;
            this.anchorNode.appendChild(node);
            var _editor = new dijit.Editor({}, node);
            this.editor = _editor;
            return _editor;
           }
         };
        }
        if(multiline){
         // If multiline, create a textarea
         viewNode = document.createElement("textarea");
         anchorNode.appendChild(viewNode);
         dojo.style(viewNode, 'width', '90%');
         box = new dijit.form.SimpleTextarea({},viewNode);
        }else{
         // If single line, create a textbox.
         viewNode = document.createElement("input");
         anchorNode.appendChild(viewNode);
         dojo.style(viewNode, 'width', '95%');
         box = new dijit.form.TextBox({},viewNode);
        }
        box.attr('value', value);
        return box;
       },

       
       _switchEditor: function(/*object*/event){
        // summary:
        //  Function to switch between editor types.
        // description:
        //  Function to switch between a rich text editor and a textarea widget. Used for title, summary,
        //  And content when switching between text and html/xhtml content.
        //
        // event:
        //  The event generated by the change in the select box on the page.
        var type = null;
        var target = null;
        var parent = null;

        
        // Determine the source/target of this event (to determine which editor we're switching)
        if(dojo.isIE){
         target = event.srcElement;
        }else{
         target = event.target;
        }

         
        // Determine which editor (title, summary, or content)
        if(target === this.entryTitleSelect){
         parent = this.entryTitleNode;
         type = "title";
        } else if(target === this.entrySummarySelect){
         parent = this.entrySummaryNode;
         type = "summary";
        }else{
         parent = this.entryContentNode;
         type = "content";
        }


        // Grab the existing editor.
        var editor = this._editors[type];
        var newEditor;
        var value;

        
        if(target.value === "text"){
         if(editor.declaredClass === "dijit.Editor"){
          // If we're changing the type to text and our existing editor is a rich text editor, we need to destroy
          // it and switch to a multiline editor.
          value = editor.attr('value', false);
          editor.close(false,true);
          editor.destroy();
          while(parent.firstChild){
           dojo.destroy(parent.firstChild);
          }
          newEditor = this._createEditor(parent, {value: value}, true, false);
          this._editors[type] = newEditor;
         }
        }else{
         if(editor.declaredClass != "dijit.Editor"){
          // Otherwise, we're switching to a html or xhtml type, but we currently have a textarea widget. We need
          // to destroy the existing RTE and create a multiline textarea widget.
          value = editor.attr('value');
          editor.destroy();
          while(parent.firstChild){
           dojo.destroy(parent.firstChild);
          }
          newEditor = this._createEditor(parent, {value: value}, true, true);
          newEditor = dojo.hitch(newEditor, newEditor.generateEditor)();
          this._editors[type] = newEditor;
         }
        }
       },

       
       _createPeopleEditor: function(/*DOM node*/anchorNode, /*DOM node*/node){
        // summary:
        //  Creates a People Editor widget and returns it.
        // description:
        //  Creates a People Editor widget, sets its value, and returns it.
        //
        // anchorNode:
        //  The node to attach the editor to.
        // node:
        //  An object containing the value to be put into the editor. Typically, this is an
        //  dojox.atom.io.model.Person object.
        //
        // returns: A new People Editor object.
        var viewNode = document.createElement("div");
        anchorNode.appendChild(viewNode);
        return new dojox.atom.widget.PeopleEditor(node,viewNode);
       },


       saveEdits: function(){
        // summary:
        //  Saves edits submitted when the 'save' button is pressed.
        // description:
        //  Saves edits submitted when the 'save' button is pressed. Distinguishes between new and existing
        //  entries and saves appropriately. Fetches the values of the editors, and, if existing, compares them to
        //  the existing values and submits the updates, otherwise creates a new entry and posts it as a new entry.
        //
        // returns:
        //  Nothing.
        dojo.style(this.entrySaveCancelButtons, 'display', 'none');
        dojo.style(this.entryEditButton, 'display', '');
        dojo.style(this.entryNewButton, 'display', '');
        var modifiedEntry = false;
        var value;
        var i;
        var changed;
        var entry;
        var authors;
        var contributors;
        if(!this._new){
         entry = this.getEntry();
         if(this._editors.title && (this._editors.title.attr('value') != entry.title.value || this.entryTitleSelect.value != entry.title.type)){
          value = this._editors.title.attr('value');
          if(this.entryTitleSelect.value === "xhtml"){
           value = this._enforceXhtml(value);
           if(value.indexOf('
      ') !== 0){
            value = '
      ' + value + '
      ';
           }
          }
          entry.title = new dojox.atom.io.model.Content("title", value, null, this.entryTitleSelect.value);
          modifiedEntry = true;
         }

         
         if(this._editors.id.attr('value') != entry.id){
          entry.id = this._editors.id.attr('value');
          modifiedEntry = true;
         }

         
         if(this._editors.summary && (this._editors.summary.attr('value') != entry.summary.value || this.entrySummarySelect.value != entry.summary.type)){
          value = this._editors.summary.attr('value');
          if(this.entrySummarySelect.value === "xhtml"){
           value = this._enforceXhtml(value);
           if(value.indexOf('
      ') !== 0){
            value = '
      ' + value + '
      ';
           }
          }
          entry.summary = new dojox.atom.io.model.Content("summary", value, null, this.entrySummarySelect.value);
          modifiedEntry = true;
         }

         
         if(this._editors.content && (this._editors.content.attr('value') != entry.content.value || this.entryContentSelect.value != entry.content.type)){
          value = this._editors.content.attr('value');
          if(this.entryContentSelect.value === "xhtml"){
           value = this._enforceXhtml(value);
           if(value.indexOf('
      ') !== 0){
            value = '
      ' + value + '
      ';
           }
          }
          entry.content = new dojox.atom.io.model.Content("content", value, null, this.entryContentSelect.value);
          modifiedEntry = true;
         }

         
         if(this._editors.authors){
          if(modifiedEntry){
           entry.authors = [];
           authors = this._editors.authors.getValues();
           for(i in authors){
            if(authors[i].name || authors[i].email || authors[i].uri){
             entry.addAuthor(authors[i].name, authors[i].email, authors[i].uri);
            }
           }
          }else{
           var currentAuthors = entry.authors;
           var searchAuthors = function(name, email, uri){
            for(i in currentAuthors){
             if(currentAuthors[i].name === name && currentAuthors[i].email === email && currentAuthors[i].uri === uri){
              return true;
             }
            }
            return false;
           };
           authors = this._editors.authors.getValues();
           changed = false;
           for(i in authors){
            if(!searchAuthors(authors[i].name, authors[i].email, authors[i].uri)){
             changed = true;
             break;
            }
           }
           if(changed){
            entry.authors = [];
            for(i in authors){
             if(authors[i].name || authors[i].email || authors[i].uri){
              entry.addAuthor(authors[i].name, authors[i].email, authors[i].uri);
             }
            }
            modifiedEntry = true;
           }
          }
         }

         
         if(this._editors.contributors){
         if(modifiedEntry){
           entry.contributors = [];
           contributors = this._editors.contributors.getValues();
           for(i in contributors){
            if(contributors[i].name || contributors[i].email || contributors[i].uri){
             entry.addAuthor(contributors[i].name, contributors[i].email, contributors[i].uri);
            }
           }
          }else{
           var currentContributors = entry.contributors;
           var searchContributors = function(name, email, uri){
            for(i in currentContributors){
             if(currentContributors[i].name === name && currentContributors[i].email === email && currentContributors[i].uri === uri){
              return true;
             }
            }
            return false;
           };
           contributors = this._editors.contributors.getValues();
           changed = false;
           for(i in contributors){
            if(searchContributors(contributors[i].name, contributors[i].email, contributors[i].uri)){
             changed = true;
             break;
            }
           }
           if(changed){
            entry.contributors = [];
            for(i in contributors){
             if(contributors[i].name || contributors[i].email || contributors[i].uri){
              entry.addContributor(contributors[i].name, contributors[i].email, contributors[i].uri);
             }
            }
            modifiedEntry = true;
           }
          }
         }


         if(modifiedEntry){
          dojo.publish(this.entrySelectionTopic, [{action: "update", source: this, entry: entry, callback: this._handleSave }]);
          //TODO: REMOVE BELOW
          //var atomIO = new dojox.atom.io.Connection();
          //atomIO.updateEntry(entry, dojo.hitch(this,this._handleSave));
          //WARNING: Use above when testing with SimpleProxy (or any other servlet which
          //    doesn't actually create a new entry and return it properly)
          //atomIO.updateEntry(entry, dojo.hitch(this,this._handleSave), true);
         }
        }else{
         this._new = false;
         entry = new dojox.atom.io.model.Entry();

         
         value = this._editors.title.attr('value');
         if(this.entryTitleSelect.value === "xhtml"){
          value = this._enforceXhtml(value);
          value = '
      ' + value + '
      ';
         }
         entry.setTitle(value, this.entryTitleSelect.value);
         entry.id = this._editors.id.attr('value');

         
         authors = this._editors.authors.getValues();
         for(i in authors){
          if(authors[i].name || authors[i].email || authors[i].uri){
           entry.addAuthor(authors[i].name, authors[i].email, authors[i].uri);
          }
         }

           
         contributors = this._editors.contributors.getValues();
         for(i in contributors){
          if(contributors[i].name || contributors[i].email || contributors[i].uri){
           entry.addContributor(contributors[i].name, contributors[i].email, contributors[i].uri);
          }
         }



         
         value = this._editors.summary.attr('value');
         if(this.entrySummarySelect.value === "xhtml"){
          value = this._enforceXhtml(value);
          value = '
      ' + value + '
      ';
         }
         entry.summary = new dojox.atom.io.model.Content("summary", value, null, this.entrySummarySelect.value);


         value = this._editors.content.attr('value');
         if(this.entryContentSelect.value === "xhtml"){
          value = this._enforceXhtml(value);
          value = '
      ' + value + '
      ';
         }
         entry.content = new dojox.atom.io.model.Content("content", value, null, this.entryContentSelect.value);


         dojo.style(this.entryNewButton, 'display', '');
         dojo.publish(this.entrySelectionTopic, [{action: "post", source: this, entry: entry }]);
        }
        this._editMode = false;

        
        //Rebuild the view using the same entry and feed.
        this.setEntry(entry, this._feed, true);
       },

       
       _handleSave: function(/*object*/entry, /*string*/location){
        // summary:
        //  Function for handling the save of an entry, cleaning up the display after the edit is completed.
        // description:
        //  Function for handling the save of an entry, cleaning up the display after the edit is completed.
        //
        // entry: dojox.atom.io.model.Entry object
        //  The entry that was saved.
        // Location: String
        //  A URL to be used, not used here, but part of the call back from the AtomIO
        // returns:
        //  Nothing.
        //Close the editor and revert out.
        this._editMode = false;

        
        //Rebuild the view using the same entry and feed.
        this.clear();
        this.setEntry(entry, this.getFeed(), true);
       },


       cancelEdits: function(){
        // summary:
        //  Cancels edits and reverts the editor to its previous state (display mode)
        // description:
        //  Cancels edits and reverts the editor to its previous state (display mode)
        //
        // returns:
        //  Nothing.
        this._new = false;
        dojo.style(this.entrySaveCancelButtons, 'display', 'none');
        if(this._editable){
         dojo.style(this.entryEditButton, 'display', '');
        }
        dojo.style(this.entryNewButton, 'display', '');
        this._editMode = false;

        
        //Rebuild the view using the same entry and feed.
        this.clearEditors();
        this.setEntry(this.getEntry(), this.getFeed(), true);
       },


       clear: function(){
        // summary:
        //  Clears the editor, destorys all editors, leaving the editor completely clear
        // description:
        //  Clears the editor, destorys all editors, leaving the editor completely clear
        this._editable=false;
        this.clearEditors();
        dojox.atom.widget.FeedEntryEditor.superclass.clear.apply(this);
        if(this._contentEditor){
         // Note that the superclass clear destroys the widget since it's in the child widget list,
         // so this is just ref clearing.
         this._contentEditor = this._setObject = this._oldContent = this._contentEditorCreator = null;
         this._editors = {};
        }
       },

       
       clearEditors: function(){
        for(var key in this._editors){
         if(this._editors[key].declaredClass === "dijit.Editor"){
          this._editors[key].close(false, true);
         }
         this._editors[key].destroy();
        }
        this._editors = {};
       },


       _enforceXhtml: function(/*string*/html){
        // summary:
        //  Function for cleaning up/enforcing the XHTML standard in HTML returned from the editor2 widget.
        // description:
        //  Function for cleaning up/enforcing the XHTML standard in HTML returned from the editor2 widget.
        //
        //  html:
        //  HTML string to be enforced as xhtml.
        //
        //  returns:
        //  string of cleaned up HTML.
        var xhtml = null;
        if(html){
         //Handle

         var brRegExp = /
      /g;
         xhtml = html.replace(brRegExp, "
      ");


         //Handle

         xhtml = this._closeTag(xhtml, "hr");


         //Handle
         xhtml = this._closeTag(xhtml, "img");
        }
        return xhtml;
       },


       _closeTag: function(/*string*/xhtml, /*string*/tag){
        // summary:
        //  Function for closing tags in a text of HTML/XHTML
        // description:
        //  Function for closing tags in a text of HTML/XHTML
        //
        // xhtml: String
        //  XHTML string which needs the closing tag.
        // tag:
        //  The tag to close.
        //
        // returns: string of cleaned up HTML.
        //
        // NOTE: Probably should redo this function in a more efficient way. This could get expensive.
        var tagStart = "<" + tag;
        var tagIndex = xhtml.indexOf(tagStart);
        if(tagIndex !== -1){
         while (tagIndex !== -1){
          var tempString = "";
          var foundTagEnd = false;
          for (var i = 0; i < xhtml.length; i++){
           var c = xhtml.charAt(i);
           if(i <= tagIndex ||foundTagEnd){
            tempString += c;
           }
           else
           {
            if(c === '>'){
             tempString += "/";
             foundTagEnd = true;
            }
            tempString +=c;
           }
          }
          xhtml = tempString;
          tagIndex = xhtml.indexOf(tagStart, tagIndex + 1);
         }
        }
        return xhtml;
       },

       
       _toggleNew: function(){
        // summary:
        //  Function to put the editor into a state to create a new entry.
        // description:
        //  Function to put the editor into a state to create a new entry.

        
        // Hide the edit/new buttons and show the save/cancel buttons.
        dojo.style(this.entryNewButton, 'display', 'none');
        dojo.style(this.entryEditButton, 'display', 'none');
        dojo.style(this.entrySaveCancelButtons, 'display', '');

        
        // Reset the type select boxes to text.
        this.entrySummarySelect.value = "text";
        this.entryContentSelect.value = "text";
        this.entryTitleSelect.value = "text";

        
        // Clear all nodes.
        this.clearNodes();
        this._new = true;

        
        var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
        // Create all headers and editors.
        var titleHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.title});
        this.entryTitleHeader.appendChild(titleHeader.domNode);

        
        this._editors.title = this._createEditor(this.entryTitleNode, null);
        this.setFieldValidity("title",true);

        
        var authorHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.authors});
        this.entryAuthorHeader.appendChild(authorHeader.domNode);


        this._editors.authors = this._createPeopleEditor(this.entryAuthorNode, {name: "Author"});
        this.setFieldValidity("authors", true);

        
        var contributorHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.contributors});
        this.entryContributorHeader.appendChild(contributorHeader.domNode);


        this._editors.contributors = this._createPeopleEditor(this.entryContributorNode, {name: "Contributor"});
        this.setFieldValidity("contributors", true);

        
        var idHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.id});
        this.entryIdHeader.appendChild(idHeader.domNode);

        
        this._editors.id = this._createEditor(this.entryIdNode, null);
        this.setFieldValidity("id",true);


        var updatedHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.updated});
        this.entryUpdatedHeader.appendChild(updatedHeader.domNode);

        
        this._editors.updated = this._createEditor(this.entryUpdatedNode, null);
        this.setFieldValidity("updated",true);


        var summaryHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.summary});
        this.entrySummaryHeader.appendChild(summaryHeader.domNode);

        
        this._editors.summary = this._createEditor(this.entrySummaryNode, null, true);
        this.setFieldValidity("summaryedit",true);
        this.setFieldValidity("summary",true);


        var contentHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.content});
        this.entryContentHeader.appendChild(contentHeader.domNode);

        
        this._editors.content = this._createEditor(this.entryContentNode, null, true);
        this.setFieldValidity("contentedit",true);
        this.setFieldValidity("content",true);


        // Show the sections.
        this._displaySections();
       },

       
       _displaySections: function(){
        // summary: Function to display the appropriate sections based on validity.
        // description: Function to display the appropriate sections based on validity.

        
        // Hide select boxes.
        dojo.style(this.entrySummarySelect, 'display', 'none');
        dojo.style(this.entryContentSelect, 'display', 'none');
        dojo.style(this.entryTitleSelect, 'display', 'none');


        // Show select boxes if the flags are set.
        if(this.isFieldValid("contentedit")){
         dojo.style(this.entryContentSelect, 'display', '');
        }
        if(this.isFieldValid("summaryedit")){
         dojo.style(this.entrySummarySelect, 'display', '');
        }
        if(this.isFieldValid("titleedit")){
         dojo.style(this.entryTitleSelect, 'display', '');
        }
        // Call super's _displaySections.
        dojox.atom.widget.FeedEntryEditor.superclass._displaySections.apply(this);

        
        // If we have editors to load after the nodes are created on the page, execute those now.
        if(this._toLoad){
         for(var i in this._toLoad){
          var editor;
          if(this._toLoad[i].generateEditor){
           editor = dojo.hitch(this._toLoad[i], this._toLoad[i].generateEditor)();
          }else{
           editor = this._toLoad[i];
          }
          this._editors[this._toLoad[i].name] = editor;
          this._toLoad[i] = null;
         }
         this._toLoad = null;
        }
       }
      });


      dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated, dijit._Container],{
        // summary:
        //  An editor for dojox.atom.io.model.Person objects.
        // description:
        //  An editor for dojox.atom.io.model.Person objects. Displays multiple rows for the respective arrays
        //  of people. Can add/remove rows on the fly.
        templateString: dojo.cache("dojox.atom", "widget/templates/PeopleEditor.html"),


        _rows: [],
        _editors: [],
        _index: 0,
        _numRows: 0,

        
        postCreate: function(){
         // Initializer function for the PeopleEditor widget.
         var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "PeopleEditor");
         if(this.name){
          if(this.name == "Author"){
           this.peopleEditorButton.appendChild(document.createTextNode("["+_nlsResources.addAuthor+"]"));
          }else if(this.name == "Contributor"){
           this.peopleEditorButton.appendChild(document.createTextNode("["+_nlsResources.addContributor+"]"));
          }
         }else{
          this.peopleEditorButton.appendChild(document.createTextNode("["+_nlsResources.add+"]"));
         }
         this._editors = [];


         if(!this.data || this.data.length===0){
          this._createEditors(null, null, null, 0, this.name);
          this._index = 1;
         }else{
          for(var i in this.data){
           this._createEditors(this.data[i].name, this.data[i].email, this.data[i].uri, i);
           this._index++;
           this._numRows++;
          }
         }
    • summary
  • dojox.atom.widget.PeopleEditor.destroy

    • type
      Function
    • source: [view]
         for(var key in this._editors){
          for(var key2 in this._editors[key]){
           this._editors[key][key2].destroy();
          }
         }
         this._editors = [];
    • summary
  • dojox.atom.widget.PeopleEditor._createEditors

    • type
      Function
    • parameters:
      • name: (typeof string)
        The name of this Person.
      • email: (typeof string)
        The email of this Person.
      • uri: (typeof string)
        The Person's URI.
      • index: (typeof int)
        The row index to use for this Person.
      • widgetName: (typeof string)
    • source: [view]
         var row = document.createElement("tr");
         this.peopleEditorEditors.appendChild(row);
         row.id = "removeRow"+index;

         
         var node = document.createElement("td");
         node.setAttribute('align', 'right');
         row.appendChild(node);
         node.colSpan = 2;

         
         if(this._numRows>0){
          var hr = document.createElement("hr");
          node.appendChild(hr);
          hr.id = "hr"+index;
         }

         
         row = document.createElement("span");
         node.appendChild(row);
         row.className = "peopleEditorButton";
         dojo.style(row, 'font-size', 'x-small');
         dojo.connect(row, "onclick", this, "_removeEditor");
         row.id = "remove"+index;

         
         node = document.createTextNode("[X]");
         row.appendChild(node);

         
         row = document.createElement("tr");
         this.peopleEditorEditors.appendChild(row);
         row.id = "editorsRow"+index;

         
         var labelNode = document.createElement("td");
         row.appendChild(labelNode);
         dojo.style(labelNode, 'width', '20%');

         
         node = document.createElement("td");
         row.appendChild(node);

         
         row = document.createElement("table");
         labelNode.appendChild(row);
         dojo.style(row, 'width', '100%');

         
         labelNode = document.createElement("tbody");
         row.appendChild(labelNode);

         
         row = document.createElement("table");
         node.appendChild(row);
         dojo.style(row, 'width', '100%');

         
         node = document.createElement("tbody");
         row.appendChild(node);


         this._editors[index] = [];
         this._editors[index].push(this._createEditor(name, widgetName+'name'+index, 'Name:', labelNode, node));
         this._editors[index].push(this._createEditor(email, widgetName+'email'+index, 'Email:', labelNode, node));
         this._editors[index].push(this._createEditor(uri, widgetName+'uri'+index, 'URI:', labelNode, node));
    • summary
      creates editor boxes (textbox widgets) for the individual values of a Person.
    • description
      creates editor boxes (textbox widgets) for the individual values of a Person.
  • dojox.atom.widget.PeopleEditor._createEditor

    • type
      Function
    • parameters:
      • value: (typeof string)
        The initial value of the textbox
      • id: (typeof string)
        The id the textbox should have.
      • name: (typeof string)
        The text to put in the label element for this textbox.
      • labelNode: (typeof DOM node)
        The node to attach the label to.
      • node: (typeof DOM node)
        The node to attach the editor rows to.
    • source: [view]
         var row = document.createElement("tr");
         labelNode.appendChild(row);

         
         var label = document.createElement("label");
         label.setAttribute('for', id);
         label.appendChild(document.createTextNode(name));
         labelNode = document.createElement("td");
         labelNode.appendChild(label);
         row.appendChild(labelNode);

         
         row = document.createElement("tr");
         node.appendChild(row);

          
         node = document.createElement("td");
         row.appendChild(node);

         
         var viewNode = document.createElement("input");
         viewNode.setAttribute('id', id);
         node.appendChild(viewNode);
         dojo.style(viewNode, 'width', '95%');

         
         var box = new dijit.form.TextBox({},viewNode);
         box.attr('value', value);
         return box;
    • summary
      Creates an individual editor widget (textbox) for a value.
    • description
      Creates an individual editor widget (textbox) for a value.
    • return_summary
      Editor widget.
  • dojox.atom.widget.PeopleEditor._removeEditor

    • type
      Function
    • parameters:
      • event: (typeof object)
        The event generated when the remove button is pressed on the page.
    • source: [view]
         var target = null;

        
         if(dojo.isIE){
          target = event.srcElement;
         }else{
          target = event.target;
         }

          
         var id = target.id;
         id = id.substring(6);
         for(var key in this._editors[id]){
          this._editors[id][key].destroy();
         }

         
         var node = dojo.byId("editorsRow"+id);
         var parent = node.parentNode;
         parent.removeChild(node);

         
         node = dojo.byId("removeRow"+id);
         parent = node.parentNode;
         parent.removeChild(node);


         this._numRows--;
         if(this._numRows === 1 && parent.firstChild.firstChild.firstChild.tagName.toLowerCase() === "hr"){
          node = parent.firstChild.firstChild;
          node.removeChild(node.firstChild);
         }
         this._editors[id] = null;
    • summary
      Removes a Person from our list of editors.
    • description
      Removes a Person from our list of editors by removing the block of editors that
      make up that Person.
  • dojox.atom.widget.PeopleEditor._add

    • type
      Function
    • source: [view]
         this._createEditors(null, null, null, this._index);
         this._index++;
         this._numRows++;
    • summary
      Adds a new block of blank editors to represent a Person.
    • description
      Adds a new block of blank editors to represent a Person.
  • dojox.atom.widget.PeopleEditor.getValues

    • type
      Function
    • source: [view]
         var values = [];
         for(var i in this._editors){
          if(this._editors[i]){
           values.push({name: this._editors[i][0].attr('value'), email: this._editors[i][1].attr('value'), uri: this._editors[i][2].attr('value')});
          }
         }
         return values;
    • summary
      Gets the values of this editor in an array.
    • description
      Gets the values of this editor in an array, with each Person as an object within the array.
    • return_summary
      An array of anonymous objects representing dojox.atom.io.model.Persons.
  • dojox.atom.widget.PeopleEditor.name

    • summary
  • dojox.atom.widget.PeopleEditor.data.length

    • summary
  • dojox.atom.widget

    • type
      Object
    • summary
  • dojox.atom

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary