define(['jquery', 'underscore', 'backbone', 'models/SolrResult'], function($, _, Backbone, SolrResult) { 'use strict'; var CitationView = Backbone.View.extend({ type: "Citation", initialize: function(options){ if((options === undefined) || (!options)) var options = {}; this.id = options.id || null; this.attributes = options.attributes || null; this.className += options.className || ""; this.model = options.model || null; this.metadata = options.metadata || null; this.title = options.title || null; this.createLink = (options.createLink === false) ? false : true; this.createTitleLink = (options.createTitleLink === false) ? false : true; //If a metadata doc was passed but no data or package model, then save the metadata as our model, too if(!this.model && this.metadata) this.model = this.metadata; //If the model is a Package, then get the metadata doc in this package else if(this.model && this.model.type == "Package") this.metadata = this.model.getMetadata(); //If the model is a metadata doc and there was no other metadata specified, then use the model else if(this.model && (this.model.getType && this.model.getType() == "metadata") && !this.metadata) this.metadata = this.model; //Check if the given metadata object is a portal or collection if( this.metadata ){ this.isCollection = this.metadata.getType() == "collection" || this.metadata.getType() == "portal"; } if( !this.metadata ){ this.metadata = this.model; } }, tagName : "cite", className : "citation", /* * Creates a citation */ render: function(){ if (!this.model && !this.metadata && !this.id) return this; else if(!this.model && !this.metadata && this.id){ //Create a model this.metadata = new SolrResult({id: this.id}); this.model = this.metadata; //Retrieve the citation info for this model and render once we have it var view = this; this.model.on("change", function(){ view.render.call(view); }); this.model.getCitationInfo(); return; } // If the model is retreived from the Metrics Service // and of type CitationModel, simply set the fields as // retrieved from the response else if(this.model.type == "CitationModel") { var authorText = this.model.get("origin") || "", datasource = this.model.get("journal"), dateUploaded = this.model.get("year_of_publishing"), sourceUrl = this.model.get("source_url"), sourceId = this.model.get("source_id"), title = this.model.get("title"), journal =this.model.get("publisher"), volume =this.model.get("volume"), page =this.model.get("page"), citationMetadata =this.model.get("citationMetadata"); // Format the Author textarea else if (this.model.type == "CitationModel") { if (authorText.length > 0) { var authors = authorText.split(", "), count = 0, authorText = ""; _.each(authors, function (author) { count++; if(count == 6){ authorText += ", et al. "; return; } else if(count > 6) return; if(count > 1){ if(authors.length > 2) authorText += ","; if (count == authors.length) authorText += " and"; if (authors.length > 1) authorText += " "; } // Checking for incorrectly escaped characters if (/&[A-Za-z0-9]/.test(author)) { // initializing the DOM parser var parser = new DOMParser(); // parsing the incorrectly escaped `&` var unescapeAmpersand = parser.parseFromString(author, 'text/html'); // unescaping the & and retrieving the actual character var unescapedString = parser.parseFromString(unescapeAmpersand.body.textContent, 'text/html'); // saving the correct author text before displaying author = unescapedString.body.textContent; } authorText += author; if (count == authors.length) authorText += ". "; }); } } else if(this.metadata && this.metadata.get("archived") && !MetacatUI.appModel.get("archivedContentIsIndexed")){ this.$el.append('This content has been archived. '); //The ID var idEl = this.createIDElement(); this.$el.append(idEl); return this; } //Create the citation from the metadata doc if we have one else if (this.metadata) { //If this object is in progress of saving, don't RErender this view. if(this.metadata.get("uploadStatus") == "p" && this.$el.children().length) return; //Clear the element this.$el.html(""); var pubDate = this.metadata.get("pubDate"), dateUploaded = this.metadata.get("dateUploaded"), title = Array.isArray(this.metadata.get("title")) ? (this.metadata.get("title")[0] || this.title || "") : this.metadata.get("title") || this.title || "", datasource = this.metadata.get("datasource"); //Format the author text if(this.metadata.type == "EML"){ var authors = this.metadata.get("creator"), count = 0, authorText = ""; _.each(authors, function (author) { count++; if(count == 6){ authorText += ", et al. "; return; } else if(count > 6) return; //Get the individual's name, or position name, or organization name, in that order var name = author.get("individualName") ? _.flatten([author.get("individualName").givenName, author.get("individualName").surName]).join(" ") : author.get("positionName") || author.get("organizationName"); if(count > 1){ if(authors.length > 2) authorText += ","; if (count == authors.length) authorText += " and"; if (authors.length > 1) authorText += " "; } authorText += name; if (count == authors.length) authorText += ". "; }); } else{ var authors = this.metadata.get("origin"), count = 0, authorText = ""; _.each(authors, function (author) { count++; if(count == 6){ authorText += ", et al. "; return; } else if(count > 6) return; if(count > 1){ if(authors.length > 2) authorText += ","; if (count == authors.length) authorText += " and"; if (authors.length > 1) authorText += " "; } authorText += author; if (count == authors.length) authorText += ". "; }); } } //If there is no metadata doc, then this is probably a data doc without science metadata. //So create the citation from the index values else { var authorText = this.model.get("rightsHolder") || this.model.get("submitter") || "", dateUploaded = this.model.get("dateUploaded"), datasource = this.model.get("datasource"); } if( !this.isCollection ){ //The author var authorEl = $(document.createElement("span")).addClass("author").text(authorText); //The publication date var pubDateText = ""; if ((typeof pubDate !== "undefined") && pubDate) { var pubDateFormatted = new Date(pubDate).getUTCFullYear(); if (!isNaN(pubDateFormatted)) pubDateText += pubDateFormatted; } if (dateUploaded && (isNaN(pubDateFormatted) || !pubDate)) { var dateUploadedFormatted = dateUploaded; if (!isNaN(dateUploadedFormatted)) pubDateText += dateUploadedFormatted; } var pubDateEl = $(document.createElement("span")).addClass("pubdate") // Only set text if we have a non-zero-length pubDate string if (pubDateText.length > 0) { pubDateEl.text(pubDateText + ". "); } //The publisher (source member node) var publisherText = ""; if (typeof datasource !== "undefined" && datasource) { var memberNode = MetacatUI.nodeModel.getMember(datasource); if(memberNode) publisherText = memberNode.name + ". "; else publisherText = datasource + ". "; } else{ var memberNode = MetacatUI.nodeModel.getMember(MetacatUI.nodeModel.get("currentMemberNode")); if(memberNode) publisherText = memberNode.name + ". "; } var publisherEl = $(document.createElement("span")).addClass('publisher'); // Only set text if we have a non-zero-length publisherText string if (publisherText) { publisherEl.text(publisherText); } } //Collections will get the collection class added else{ this.$el.addClass("collection"); } if(this.model.type == "CitationModel") { // displaying decoded source url var idEl = $(document.createElement("span")).addClass("publisher-id"); idEl.append(decodeURIComponent(sourceUrl), $(document.createElement("span")).text(". ")); } else { //The ID var idEl = this.createIDElement(); } var model = this.metadata || this.model, id = model.get("id"), seriesId = model.get("seriesId"); if ((typeof title !== "undefined") && title){ if(title.trim().charAt(title.length-1) != ".") title = title.trim() + ". "; else title = title.trim() + " "; if(this.model.type == "CitationModel") { // Appending the title as a link var titleEl = $(document.createElement("a")) .addClass("metrics-route-to-metadata") .attr("data-id", id) .attr("href", sourceUrl) .attr("target", "_blank") .append(title); } else { var titleEl = $(document.createElement("span")) .addClass("title") .attr("data-id", this.metadata.get("id")) .text(title); } } else var titleEl = document.createElement("span"); //Create a link and put all the citation parts together if (this.createLink){ if(this.model.type == "CitationModel") { // Creating a volume element to display in Citations Modal Window if(volume === "NULL") { var volumeText = ""; } else { var volumeText = "Vol. " + volume + ". "; } var volumeEl = $(document.createElement("span")).addClass("publisher").text(volumeText); // Creating a 'pages' element to display in Citations Modal Window if(page === "NULL") { var pageText = ""; } else { var pageText = "pp. " + page + ". "; } var pageEl = $(document.createElement("span")).addClass("publisher").text(pageText); var datasetLinkEl = $(document.createElement("span")) .text("Cites Data: "); // Generate links for the cited datasets var citationMetadataCounter = 0; if (citationMetadata != undefined) { for (var key in citationMetadata) { citationMetadataCounter += 1; var commaSeperator = (citationMetadataCounter < Object.keys(citationMetadata).length) ? "," : "."; var mdPID = key, mdAuthorText = "", additionalAuthors = "", mdText = "", mdDateText = ""; // Display first author in the dataset link if (citationMetadata[key]["origin"] != undefined && Array.isArray(citationMetadata[key]["origin"])) { mdAuthorText = citationMetadata[key]["origin"][0]; additionalAuthors = citationMetadata[key]["origin"].length > 1 ? " et al." : ""; mdText = "(" + mdAuthorText + additionalAuthors + " "; } // save the date if (citationMetadata[key]["datePublished"] != undefined) { mdDateText = (citationMetadata[key]["datePublished"]).slice(0,4); if (mdText.length == 0) { mdText = "("; } mdText += mdDateText; } else if (citationMetadata[key]["dateUpdated"] != undefined) { mdDateText = (citationMetadata[key]["dateUpdated"]).slice(0,4); if (mdText.length == 0) { mdText = "("; } mdText += mdDateText; } else if (citationMetadata[key]["dateModified"] != undefined) { mdDateText = (citationMetadata[key]["dateModified"]).slice(0,4); if (mdText.length == 0) { mdText = "("; } mdText += mdDateText; } // retrieve the PID if (citationMetadata[key]["id"] != undefined) { mdPID = citationMetadata[key]["id"]; } else if (key.startsWith("10.")) { mdPID = "doi:" + key } if (mdText.length > 0) { mdText += ")" + commaSeperator + " "; var targetLinkEl = $(document.createElement("a")) .addClass("metrics-route-to-metadata") .attr("data-id", key) .attr("href", MetacatUI.root + "/view/" + encodeURIComponent(mdPID)) .attr("target", "_blank") .text(mdText); datasetLinkEl.append(targetLinkEl); } } } // creating citation display string var linkEl = $(document.createElement("span")) .append(authorEl, pubDateEl, titleEl, publisherEl, volumeEl, pageEl, idEl); } else { var linkEl = $(document.createElement("a")) .addClass("route-to-metadata") .attr("data-id", id) .attr("href", this.metadata.createViewURL()) .append(authorEl, pubDateEl, titleEl, publisherEl, idEl); } this.$el.append(linkEl); // Only append the citation link when we have non-zero datasets // Append the cited dataset text to the link element if ( datasetLinkEl !== "undefined" && citationMetadataCounter > 0) { // Displaying the cites data on the new line this.$el.append("
"); this.$el.append(datasetLinkEl); } } else if(this.createTitleLink){ var linkEl = $(document.createElement("a")) .addClass("route-to-metadata") .attr("data-id", seriesId) .attr("href", this.metadata.createViewURL()) .append(titleEl); this.$el.append(authorEl, pubDateEl, linkEl, publisherEl, idEl); } else{ this.$el.append(authorEl, pubDateEl, titleEl, publisherEl, idEl); } this.setUpListeners(); return this; }, createIDElement: function(){ var model = this.metadata || this.model, id = model.get("id"), seriesId = model.get("seriesId"), datasource = model.get("datasource"); var idEl = $(document.createElement("span")).addClass("id"); if(seriesId){ //Create a link for the identifier if it is a DOI if( model.isDOI(seriesId) && !this.createLink ){ var doiURL = this.createDoiUrl(seriesId), doiLink = $(document.createElement("a")) .attr("href", doiURL) .text(seriesId); // Begin PANGAEA-specific override 1 (this is temporary) // If this is a PENGAEA dataset with a seriesId, then don't show the pid. if (typeof datasource !== "undefined" && datasource === "urn:node:PANGAEA") { idEl.append(doiLink, $(document.createElement("span")).text(". ")); } // End PANGAEA-specific override 1 else{ idEl.append(doiLink, $(document.createElement("span")).text(", version: ")); } } else{ // Begin PANGAEA-specific override 2 (this is temporary) // If this is a PENGAEA dataset with a seriesId, then don't show the pid. if (typeof datasource !== "undefined" && datasource === "urn:node:PANGAEA") { idEl.html($(document.createElement("span")).text(seriesId + ". ")); } // End PANGAEA-specific override 2 else{ idEl.html($(document.createElement("span")).text(seriesId + ", version: ")); } } } // Begin PANGAEA-specific override 3 (this is temporary) // If this is a PENGAEA dataset with a seriesId, then don't show the pid. Return now. if(typeof datasource !== "undefined" && datasource === "urn:node:PANGAEA" && seriesId){ return idEl; } // End PANGAEA-specific override 3 else if( model.isDOI(id) && !this.createLink ){ var doiURL = this.createDoiUrl(id), doiLink = $(document.createElement("a")) .attr("href", doiURL) .text(id); idEl.append(doiLink, $(document.createElement("span")).text(". ")); } else{ idEl.append($(document.createElement("span")).text(id + ". ")); } return idEl; }, createDoiUrl: function(doi){ if( doi.indexOf("http") == 0 ){ return doi; } else if( doi.indexOf("doi:") == 0){ return "https://doi.org/" + doi.substring(4); } else{ return "https://doi.org/" + doi; } }, setUpListeners: function(){ if (!this.metadata) return; this.stopListening(); //If anything in the model changes, rerender this citation this.listenTo(this.metadata, "change:origin change:creator change:pubDate change:dateUploaded change:title change:seriesId change:id change:datasource", this.render); //If this model is an EML211 model, then listen differently if(this.metadata.type == "EML"){ var creators = this.metadata.get("creator"); //Listen to the names for(var i=0; i