Skip to content

Commit

Permalink
Add metadata-specific aria labels to more/less buttons (fixes UV issu…
Browse files Browse the repository at this point in the history
…e 1081) (#33)
  • Loading branch information
jamesmisson authored Oct 24, 2024
1 parent 98e3f74 commit b4ea432
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from "@iiif/manifold";
import { BaseComponent, IBaseComponentOptions } from "@iiif/base-component";
import { Clipboard, Device, Strings } from "@edsilv/utils";
import toggleExpandTextByLines from "./toggleExpandTextByLines";

type csvvalue = string | null;

Expand All @@ -19,11 +20,13 @@ export interface IMetadataComponentContent {
description: string;
imageHeader: string;
less: string;
lessAriaLabelTemplate: string;
license: string;
rights: string;
logo: string;
manifestHeader: string;
more: string;
moreAriaLabelTemplate: string;
noData: string;
rangeHeader: string;
sequenceHeader: string;
Expand Down Expand Up @@ -142,11 +145,13 @@ export class MetadataComponent extends BaseComponent {
description: "Description",
imageHeader: "About the image",
less: "less",
lessAriaLabelTemplate: "Less information: Hide {0}",
license: "License",
rights: "Rights",
logo: "Logo",
manifestHeader: "About the item",
more: "more",
moreAriaLabelTemplate: "More information: Reveal {0}",
noData: "No data to display",
rangeHeader: "About the range",
sequenceHeader: "About the sequence"
Expand Down Expand Up @@ -403,14 +408,18 @@ export class MetadataComponent extends BaseComponent {
const $metadataGroup: JQuery = this._buildMetadataGroup(metadataGroup);
this._$metadataGroups.append($metadataGroup);
const $value: any = $metadataGroup.find(".value");
const $items: any = $metadataGroup.find(".item");

if (this._data.limit && this._data.content) {
if (this._data.limitType === LimitType.LINES) {
$value.toggleExpandTextByLines(
toggleExpandTextByLines(
$items,
this._data.limit,
this._data.content.less,
this._data.content.more,
() => {}
() => {},
this._data.content.lessAriaLabelTemplate,
this._data.content.moreAriaLabelTemplate,
);
} else if (this._data.limitType === LimitType.CHARS) {
$value.ellipsisHtmlFixed(this._data.limit, () => {});
Expand Down
127 changes: 127 additions & 0 deletions src/toggleExpandTextByLines.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { Strings } from "@edsilv/utils";

function switchClass(element: JQuery, class1: string, class2: string) {
return element.each(function () {
$(this).removeClass(class1).addClass(class2);
});
}

function removeLastWord(element: any, chars: number = 8, depth: number = 0) {
return element.each(function () {
const $self: JQuery = $(this);
if ($self.contents().length > 0) {
const $lastElement = $self.contents().last();
if ($lastElement[0].nodeType === 3) {
const words: string[] = $lastElement.text().trim().split(" ");
if (words.length > 1) {
words.splice(words.length - 1, 1);
(<any>$lastElement[0]).data = words.join(" "); // textnode.data
return;
} else if (
"undefined" !== typeof chars &&
words.length === 1 &&
words[0].length > chars
) {
(<any>$lastElement[0]).data = words.join(" ").substring(0, chars);
return;
}
}

removeLastWord($lastElement, chars, depth + 1); // Element
} else if (depth > 0) {
// Empty element
$self.remove();
}
});
}

export default function toggleExpandTextByLines(
items: JQuery,
lines: number,
lessText: string,
moreText: string,
cb: () => void,
lessAriaLabelTemplate: string = "Less information: Hide {0}",
moreAriaLabelTemplate: string = "More information: Reveal {0}"
) {
return items.each(function () {
const $self: JQuery = $(this);
const $label: JQuery = $self.find(".label");
const $value: JQuery = $self.find(".value");
const expandedText: string = $value.html();
const labelText: string = $label
.contents()
.filter(function () {
return this.nodeType === Node.TEXT_NODE;
})
.text()
.trim();
// add 'pad' to account for the right margin in the sidebar
const $buttonPad: JQuery = $(
'<span>&hellip; <a href="#" class="toggle more">morepad</a></span>'
);
// when height changes, store string, then pick from line counts
const stringsByLine: string[] = [expandedText];
let lastHeight = $self.height();
// Until empty
while ($value.text().length > 0) {
removeLastWord($value);
const html: string = $value.html();
$value.append($buttonPad);

const valueHeight = $value.height();
if (
valueHeight !== undefined &&
lastHeight !== undefined &&
lastHeight > valueHeight
) {
stringsByLine.unshift(html);
lastHeight = $value.height();
}

$buttonPad.remove();
}

if (stringsByLine.length <= lines) {
$value.html(expandedText);
return;
}

const collapsedText: string = stringsByLine[lines - 1];

// Toggle function
let expanded: boolean = false;

(<any>$value).toggle = function () {
$value.empty();
const $toggleButton: JQuery = $('<a href="#" class="toggle"></a>');
if (expanded) {
const lessAriaLabel: string = Strings.format(
lessAriaLabelTemplate,
labelText
);
$value.html(expandedText + " ");
$toggleButton.text(lessText);
switchClass($toggleButton, "less", "more");
$toggleButton.attr("aria-label", lessAriaLabel);
} else {
const moreAriaLabel: string = Strings.format(
moreAriaLabelTemplate,
labelText
);
$value.html(collapsedText + "&hellip; ");
$toggleButton.text(moreText);
switchClass($toggleButton, "more", "less");
$toggleButton.attr("aria-label", moreAriaLabel);
}
$toggleButton.one("click", function (e) {
e.preventDefault();
$value.toggle();
});
expanded = !expanded;
$value.append($toggleButton);
if (cb) cb();
};
$value.toggle();
});
}

0 comments on commit b4ea432

Please sign in to comment.