Skip to content

Commit

Permalink
Ensure that CanonicalData view works on rerender
Browse files Browse the repository at this point in the history
Issue #2541
  • Loading branch information
robyngit committed Oct 10, 2024
1 parent 4e95fa3 commit aa0dd4e
Showing 1 changed file with 48 additions and 29 deletions.
77 changes: 48 additions & 29 deletions src/js/views/CanonicalDatasetHandlerView.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,28 @@ define(["backbone"], (Backbone) => {

/** @inheritdoc */
render() {
if (this.detectCanonicalDataset()) {
this.getCitationInfo();
this.addFieldItem();
this.modifyCitationModal();
this.addInfoIcon();
this.removeAnnotations();
}
// In case it's a re-render, remove any modifications made previously
this.reset();
const hasCanonical = this.detectCanonicalDataset();
if (!hasCanonical) return this;
this.getCitationInfo();
this.fieldItem = this.addFieldItem();
this.modifyCitationModal();
this.infoIcon = this.addInfoIcon();
this.hideAnnotations();
return this;
},

/**
* Resets the MetadataView to its original state by removing any changes
* made by this view.
*/
reset() {
this.fieldItem?.remove();
this.infoIcon?.remove();
this.showAnnotations();
},

/**
* Inspects the MetadataView DOM to determine if a canonical dataset is
* present based on schema.org:sameAs and prov:wasDerivedFrom annotations.
Expand All @@ -121,11 +133,6 @@ define(["backbone"], (Backbone) => {
* otherwise.
*/
detectCanonicalDataset() {
if (this.canonicalUri) {
// On re-render, annotations might already be removed, leading to a
// false negative if we try to re-detect the canonical dataset.
return true;
}
// The annotation views provide the URI and value of annotations on the
// metadata. We consider the dataset to be canonical if the sameAs and
// derivedFrom annotations both point to the same URI.
Expand All @@ -146,7 +153,7 @@ define(["backbone"], (Backbone) => {
*/
getAnnotationViews() {
return this.metadataView[SUBVIEW_PROP].filter(
(view) => view.type === ANNO_VIEW_TYPE,
(view) => view?.type === ANNO_VIEW_TYPE,
);
},

Expand Down Expand Up @@ -182,22 +189,32 @@ define(["backbone"], (Backbone) => {
},

/**
* Removes the sameAs and derivedFrom annotations from the MetadataView.
* Hides the sameAs and derivedFrom annotations from the MetadataView.
* This is done to prevent redundancy in the metadata display.
*/
removeAnnotations() {
hideAnnotations() {
// Sometimes the MetadataView re-renders, so we must always query for
// the annotation views when we want to remove them.
const sameAsAnno = this.getSameAsAnnotationView();
const derivedFromAnno = this.getDerivedFromAnnotationView();
if (sameAsAnno?.value.uri === this.canonicalUri) {
sameAsAnno.remove();
sameAsAnno.el.style.display = "none";
this.hiddenSameAs = sameAsAnno;
}
if (derivedFromAnno?.value.uri === this.canonicalUri) {
derivedFromAnno.remove();
derivedFromAnno.el.style.display = "none";
this.hiddenDerivedFrom = derivedFromAnno;
}
},

/** Show previously hidden annotations in the MetadataView. */
showAnnotations() {
this.hiddenSameAs?.el.style.removeProperty("display");
this.hiddenSameAs = null;
this.hiddenDerivedFrom?.el.style.removeProperty("display");
this.hiddenDerivedFrom = null;
},

/**
* Adds a "row" in the MetadataView to display the canonical dataset URI.
*/
Expand All @@ -210,6 +227,11 @@ define(["backbone"], (Backbone) => {
METADATA_VIEW_CLASS_NAMES,
);

// Vivify the item so we can reference it later
const range = document.createRange();
const fragment = range.createContextualFragment(itemHTML);
const item = fragment.firstElementChild;

// Find the parent item that contains the field name the view should
// be inserted before
const labels = Array.from(
Expand All @@ -219,10 +241,8 @@ define(["backbone"], (Backbone) => {
(label) => label.textContent.trim() === this.insertFieldBefore,
);
// Insert the new field item before the label
insertBeforeLabel.parentElement.insertAdjacentHTML(
"beforebegin",
itemHTML,
);
insertBeforeLabel.parentElement.before(item);
return item;
},

/**
Expand All @@ -239,21 +259,20 @@ define(["backbone"], (Backbone) => {
* dataset being displayed is essentially a duplicate
*/
addInfoIcon() {
if (this.infoIcon) {
// Do not re-add the info icon if it already exists
return;
}
this.infoIcon = this.metadataView.addInfoIcon(
const infoIcon = this.metadataView.addInfoIcon(
"duplicate",
INFO_ICON_NAME,
INFO_ICON_CLASS,
INFO_ICON_TOOLTIP_TEXT,
);
return infoIcon;
},

// TODO: Do we need to remove the view from the DOM when the MetadataView
// is removed? Do we need methods to undo the changes made by this view?
remove() {},
/** Called when the view is removed. */
onClose() {
this.reset();
this.remove();
},
},
);

Expand Down

0 comments on commit aa0dd4e

Please sign in to comment.