aboutsummaryrefslogtreecommitdiff
path: root/ext/js/display/sandbox
diff options
context:
space:
mode:
Diffstat (limited to 'ext/js/display/sandbox')
-rw-r--r--ext/js/display/sandbox/pronunciation-generator.js236
-rw-r--r--ext/js/display/sandbox/structured-content-generator.js464
2 files changed, 0 insertions, 700 deletions
diff --git a/ext/js/display/sandbox/pronunciation-generator.js b/ext/js/display/sandbox/pronunciation-generator.js
deleted file mode 100644
index f28520be..00000000
--- a/ext/js/display/sandbox/pronunciation-generator.js
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2023-2024 Yomitan Authors
- * Copyright (C) 2021-2022 Yomichan Authors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-import {getKanaDiacriticInfo, isMoraPitchHigh} from '../../language/ja/japanese.js';
-
-/**
- * @param {string[]} morae
- * @param {number} downstepPosition
- * @param {number[]} nasalPositions
- * @param {number[]} devoicePositions
- * @returns {HTMLSpanElement}
- */
-export function createPronunciationText(morae, downstepPosition, nasalPositions, devoicePositions) {
- const nasalPositionsSet = nasalPositions.length > 0 ? new Set(nasalPositions) : null;
- const devoicePositionsSet = devoicePositions.length > 0 ? new Set(devoicePositions) : null;
- const container = document.createElement('span');
- container.className = 'pronunciation-text';
- for (let i = 0, ii = morae.length; i < ii; ++i) {
- const i1 = i + 1;
- const mora = morae[i];
- const highPitch = isMoraPitchHigh(i, downstepPosition);
- const highPitchNext = isMoraPitchHigh(i1, downstepPosition);
- const nasal = nasalPositionsSet !== null && nasalPositionsSet.has(i1);
- const devoice = devoicePositionsSet !== null && devoicePositionsSet.has(i1);
-
- const n1 = document.createElement('span');
- n1.className = 'pronunciation-mora';
- n1.dataset.position = `${i}`;
- n1.dataset.pitch = highPitch ? 'high' : 'low';
- n1.dataset.pitchNext = highPitchNext ? 'high' : 'low';
-
- const characterNodes = [];
- for (const character of mora) {
- const n2 = document.createElement('span');
- n2.className = 'pronunciation-character';
- n2.textContent = character;
- n1.appendChild(n2);
- characterNodes.push(n2);
- }
-
- if (devoice) {
- n1.dataset.devoice = 'true';
- const n3 = document.createElement('span');
- n3.className = 'pronunciation-devoice-indicator';
- n1.appendChild(n3);
- }
- if (nasal && characterNodes.length > 0) {
- n1.dataset.nasal = 'true';
-
- const group = document.createElement('span');
- group.className = 'pronunciation-character-group';
-
- const n2 = characterNodes[0];
- const character = /** @type {string} */ (n2.textContent);
-
- const characterInfo = getKanaDiacriticInfo(character);
- if (characterInfo !== null) {
- n1.dataset.originalText = mora;
- n2.dataset.originalText = character;
- n2.textContent = characterInfo.character;
- }
-
- let n3 = document.createElement('span');
- n3.className = 'pronunciation-nasal-diacritic';
- n3.textContent = '\u309a'; // Combining handakuten
- group.appendChild(n3);
-
- n3 = document.createElement('span');
- n3.className = 'pronunciation-nasal-indicator';
- group.appendChild(n3);
-
- /** @type {ParentNode} */ (n2.parentNode).replaceChild(group, n2);
- group.insertBefore(n2, group.firstChild);
- }
-
- const line = document.createElement('span');
- line.className = 'pronunciation-mora-line';
- n1.appendChild(line);
-
- container.appendChild(n1);
- }
- return container;
-}
-
-/**
- * @param {string[]} morae
- * @param {number} downstepPosition
- * @returns {SVGSVGElement}
- */
-export function createPronunciationGraph(morae, downstepPosition) {
- const ii = morae.length;
-
- const svgns = 'http://www.w3.org/2000/svg';
- const svg = document.createElementNS(svgns, 'svg');
- svg.setAttribute('xmlns', svgns);
- svg.setAttribute('class', 'pronunciation-graph');
- svg.setAttribute('focusable', 'false');
- svg.setAttribute('viewBox', `0 0 ${50 * (ii + 1)} 100`);
-
- if (ii <= 0) { return svg; }
-
- const path1 = document.createElementNS(svgns, 'path');
- svg.appendChild(path1);
-
- const path2 = document.createElementNS(svgns, 'path');
- svg.appendChild(path2);
-
- const pathPoints = [];
- for (let i = 0; i < ii; ++i) {
- const highPitch = isMoraPitchHigh(i, downstepPosition);
- const highPitchNext = isMoraPitchHigh(i + 1, downstepPosition);
- const x = i * 50 + 25;
- const y = highPitch ? 25 : 75;
- if (highPitch && !highPitchNext) {
- addGraphDotDownstep(svg, svgns, x, y);
- } else {
- addGraphDot(svg, svgns, x, y);
- }
- pathPoints.push(`${x} ${y}`);
- }
-
- path1.setAttribute('class', 'pronunciation-graph-line');
- path1.setAttribute('d', `M${pathPoints.join(' L')}`);
-
- pathPoints.splice(0, ii - 1);
- {
- const highPitch = isMoraPitchHigh(ii, downstepPosition);
- const x = ii * 50 + 25;
- const y = highPitch ? 25 : 75;
- addGraphTriangle(svg, svgns, x, y);
- pathPoints.push(`${x} ${y}`);
- }
-
- path2.setAttribute('class', 'pronunciation-graph-line-tail');
- path2.setAttribute('d', `M${pathPoints.join(' L')}`);
-
- return svg;
-}
-
-/**
- * @param {number} downstepPosition
- * @returns {HTMLSpanElement}
- */
-export function createPronunciationDownstepPosition(downstepPosition) {
- const downstepPositionString = `${downstepPosition}`;
-
- const n1 = document.createElement('span');
- n1.className = 'pronunciation-downstep-notation';
- n1.dataset.downstepPosition = downstepPositionString;
-
- let n2 = document.createElement('span');
- n2.className = 'pronunciation-downstep-notation-prefix';
- n2.textContent = '[';
- n1.appendChild(n2);
-
- n2 = document.createElement('span');
- n2.className = 'pronunciation-downstep-notation-number';
- n2.textContent = downstepPositionString;
- n1.appendChild(n2);
-
- n2 = document.createElement('span');
- n2.className = 'pronunciation-downstep-notation-suffix';
- n2.textContent = ']';
- n1.appendChild(n2);
-
- return n1;
-}
-
-// Private
-
-/**
- * @param {Element} container
- * @param {string} svgns
- * @param {number} x
- * @param {number} y
- */
-function addGraphDot(container, svgns, x, y) {
- container.appendChild(createGraphCircle(svgns, 'pronunciation-graph-dot', x, y, '15'));
-}
-
-/**
- * @param {Element} container
- * @param {string} svgns
- * @param {number} x
- * @param {number} y
- */
-function addGraphDotDownstep(container, svgns, x, y) {
- container.appendChild(createGraphCircle(svgns, 'pronunciation-graph-dot-downstep1', x, y, '15'));
- container.appendChild(createGraphCircle(svgns, 'pronunciation-graph-dot-downstep2', x, y, '5'));
-}
-
-/**
- * @param {Element} container
- * @param {string} svgns
- * @param {number} x
- * @param {number} y
- */
-function addGraphTriangle(container, svgns, x, y) {
- const node = document.createElementNS(svgns, 'path');
- node.setAttribute('class', 'pronunciation-graph-triangle');
- node.setAttribute('d', 'M0 13 L15 -13 L-15 -13 Z');
- node.setAttribute('transform', `translate(${x},${y})`);
- container.appendChild(node);
-}
-
-/**
- * @param {string} svgns
- * @param {string} className
- * @param {number} x
- * @param {number} y
- * @param {string} radius
- * @returns {Element}
- */
-function createGraphCircle(svgns, className, x, y, radius) {
- const node = document.createElementNS(svgns, 'circle');
- node.setAttribute('class', className);
- node.setAttribute('cx', `${x}`);
- node.setAttribute('cy', `${y}`);
- node.setAttribute('r', radius);
- return node;
-}
diff --git a/ext/js/display/sandbox/structured-content-generator.js b/ext/js/display/sandbox/structured-content-generator.js
deleted file mode 100644
index 90a47158..00000000
--- a/ext/js/display/sandbox/structured-content-generator.js
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright (C) 2023-2024 Yomitan Authors
- * Copyright (C) 2021-2022 Yomichan Authors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-import {getLanguageFromText} from '../../language/text-utilities.js';
-
-export class StructuredContentGenerator {
- /**
- * @param {import('../../display/display-content-manager.js').DisplayContentManager|import('../../templates/sandbox/anki-template-renderer-content-manager.js').AnkiTemplateRendererContentManager} contentManager
- * @param {Document} document
- */
- constructor(contentManager, document) {
- /** @type {import('../../display/display-content-manager.js').DisplayContentManager|import('../../templates/sandbox/anki-template-renderer-content-manager.js').AnkiTemplateRendererContentManager} */
- this._contentManager = contentManager;
- /** @type {Document} */
- this._document = document;
- }
-
- /**
- * @param {HTMLElement} node
- * @param {import('structured-content').Content} content
- * @param {string} dictionary
- */
- appendStructuredContent(node, content, dictionary) {
- node.classList.add('structured-content');
- this._appendStructuredContent(node, content, dictionary, null);
- }
-
- /**
- * @param {import('structured-content').Content} content
- * @param {string} dictionary
- * @returns {HTMLElement}
- */
- createStructuredContent(content, dictionary) {
- const node = this._createElement('span', 'structured-content');
- this._appendStructuredContent(node, content, dictionary, null);
- return node;
- }
-
- /**
- * @param {import('structured-content').ImageElement|import('dictionary-data').TermGlossaryImage} data
- * @param {string} dictionary
- * @returns {HTMLAnchorElement}
- */
- createDefinitionImage(data, dictionary) {
- const {
- path,
- width = 100,
- height = 100,
- preferredWidth,
- preferredHeight,
- title,
- alt,
- pixelated,
- imageRendering,
- appearance,
- background,
- collapsed,
- collapsible,
- verticalAlign,
- border,
- borderRadius,
- sizeUnits
- } = data;
-
- const hasPreferredWidth = (typeof preferredWidth === 'number');
- const hasPreferredHeight = (typeof preferredHeight === 'number');
- const invAspectRatio = (
- hasPreferredWidth && hasPreferredHeight ?
- preferredHeight / preferredWidth :
- height / width
- );
- const usedWidth = (
- hasPreferredWidth ?
- preferredWidth :
- (hasPreferredHeight ? preferredHeight / invAspectRatio : width)
- );
-
- const node = /** @type {HTMLAnchorElement} */ (this._createElement('a', 'gloss-image-link'));
- node.target = '_blank';
- node.rel = 'noreferrer noopener';
-
- const imageContainer = this._createElement('span', 'gloss-image-container');
- node.appendChild(imageContainer);
-
- const aspectRatioSizer = this._createElement('span', 'gloss-image-sizer');
- imageContainer.appendChild(aspectRatioSizer);
-
- const imageBackground = this._createElement('span', 'gloss-image-background');
- imageContainer.appendChild(imageBackground);
-
- const image = /** @type {HTMLImageElement} */ (this._createElement('img', 'gloss-image'));
- image.alt = typeof alt === 'string' ? alt : '';
- imageContainer.appendChild(image);
-
- const overlay = this._createElement('span', 'gloss-image-container-overlay');
- imageContainer.appendChild(overlay);
-
- const linkText = this._createElement('span', 'gloss-image-link-text');
- linkText.textContent = 'Image';
- node.appendChild(linkText);
-
- node.dataset.path = path;
- node.dataset.dictionary = dictionary;
- node.dataset.imageLoadState = 'not-loaded';
- node.dataset.hasAspectRatio = 'true';
- node.dataset.imageRendering = typeof imageRendering === 'string' ? imageRendering : (pixelated ? 'pixelated' : 'auto');
- node.dataset.appearance = typeof appearance === 'string' ? appearance : 'auto';
- node.dataset.background = typeof background === 'boolean' ? `${background}` : 'true';
- node.dataset.collapsed = typeof collapsed === 'boolean' ? `${collapsed}` : 'false';
- node.dataset.collapsible = typeof collapsible === 'boolean' ? `${collapsible}` : 'true';
- if (typeof verticalAlign === 'string') {
- node.dataset.verticalAlign = verticalAlign;
- }
- if (typeof sizeUnits === 'string' && (hasPreferredWidth || hasPreferredHeight)) {
- node.dataset.sizeUnits = sizeUnits;
- }
-
- imageContainer.style.width = `${usedWidth}em`;
- if (typeof border === 'string') { imageContainer.style.border = border; }
- if (typeof borderRadius === 'string') { imageContainer.style.borderRadius = borderRadius; }
- if (typeof title === 'string') {
- imageContainer.title = title;
- }
-
- aspectRatioSizer.style.paddingTop = `${invAspectRatio * 100}%`;
-
- if (this._contentManager !== null) {
- this._contentManager.loadMedia(
- path,
- dictionary,
- (url) => this._setImageData(node, image, imageBackground, url, false),
- () => this._setImageData(node, image, imageBackground, null, true)
- );
- }
-
- return node;
- }
-
- // Private
-
- /**
- * @param {HTMLElement} container
- * @param {import('structured-content').Content|undefined} content
- * @param {string} dictionary
- * @param {?string} language
- */
- _appendStructuredContent(container, content, dictionary, language) {
- if (typeof content === 'string') {
- if (content.length > 0) {
- container.appendChild(this._createTextNode(content));
- if (language === null) {
- const language2 = getLanguageFromText(content);
- if (language2 !== null) {
- container.lang = language2;
- }
- }
- }
- return;
- }
- if (!(typeof content === 'object' && content !== null)) {
- return;
- }
- if (Array.isArray(content)) {
- for (const item of content) {
- this._appendStructuredContent(container, item, dictionary, language);
- }
- return;
- }
- const node = this._createStructuredContentGenericElement(content, dictionary, language);
- if (node !== null) {
- container.appendChild(node);
- }
- }
-
- /**
- * @param {string} tagName
- * @param {string} className
- * @returns {HTMLElement}
- */
- _createElement(tagName, className) {
- const node = this._document.createElement(tagName);
- node.className = className;
- return node;
- }
-
- /**
- * @param {string} data
- * @returns {Text}
- */
- _createTextNode(data) {
- return this._document.createTextNode(data);
- }
-
- /**
- * @param {HTMLElement} element
- * @param {import('structured-content').Data} data
- */
- _setElementDataset(element, data) {
- for (let [key, value] of Object.entries(data)) {
- if (key.length > 0) {
- key = `${key[0].toUpperCase()}${key.substring(1)}`;
- }
- key = `sc${key}`;
- try {
- element.dataset[key] = value;
- } catch (e) {
- // DOMException if key is malformed
- }
- }
- }
-
- /**
- * @param {HTMLAnchorElement} node
- * @param {HTMLImageElement} image
- * @param {HTMLElement} imageBackground
- * @param {?string} url
- * @param {boolean} unloaded
- */
- _setImageData(node, image, imageBackground, url, unloaded) {
- if (url !== null) {
- image.src = url;
- node.href = url;
- node.dataset.imageLoadState = 'loaded';
- imageBackground.style.setProperty('--image', `url("${url}")`);
- } else {
- image.removeAttribute('src');
- node.removeAttribute('href');
- node.dataset.imageLoadState = unloaded ? 'unloaded' : 'load-error';
- imageBackground.style.removeProperty('--image');
- }
- }
-
- /**
- * @param {import('structured-content').Element} content
- * @param {string} dictionary
- * @param {?string} language
- * @returns {?HTMLElement}
- */
- _createStructuredContentGenericElement(content, dictionary, language) {
- const {tag} = content;
- switch (tag) {
- case 'br':
- return this._createStructuredContentElement(tag, content, dictionary, language, 'simple', false, false);
- case 'ruby':
- case 'rt':
- case 'rp':
- return this._createStructuredContentElement(tag, content, dictionary, language, 'simple', true, false);
- case 'table':
- return this._createStructuredContentTableElement(tag, content, dictionary, language);
- case 'thead':
- case 'tbody':
- case 'tfoot':
- case 'tr':
- return this._createStructuredContentElement(tag, content, dictionary, language, 'table', true, false);
- case 'th':
- case 'td':
- return this._createStructuredContentElement(tag, content, dictionary, language, 'table-cell', true, true);
- case 'div':
- case 'span':
- case 'ol':
- case 'ul':
- case 'li':
- return this._createStructuredContentElement(tag, content, dictionary, language, 'simple', true, true);
- case 'img':
- return this.createDefinitionImage(content, dictionary);
- case 'a':
- return this._createLinkElement(content, dictionary, language);
- }
- return null;
- }
-
- /**
- * @param {string} tag
- * @param {import('structured-content').UnstyledElement} content
- * @param {string} dictionary
- * @param {?string} language
- * @returns {HTMLElement}
- */
- _createStructuredContentTableElement(tag, content, dictionary, language) {
- const container = this._createElement('div', 'gloss-sc-table-container');
- const table = this._createStructuredContentElement(tag, content, dictionary, language, 'table', true, false);
- container.appendChild(table);
- return container;
- }
-
- /**
- * @param {string} tag
- * @param {import('structured-content').StyledElement|import('structured-content').UnstyledElement|import('structured-content').TableElement|import('structured-content').LineBreak} content
- * @param {string} dictionary
- * @param {?string} language
- * @param {'simple'|'table'|'table-cell'} type
- * @param {boolean} hasChildren
- * @param {boolean} hasStyle
- * @returns {HTMLElement}
- */
- _createStructuredContentElement(tag, content, dictionary, language, type, hasChildren, hasStyle) {
- const node = this._createElement(tag, `gloss-sc-${tag}`);
- const {data, lang} = content;
- if (typeof data === 'object' && data !== null) { this._setElementDataset(node, data); }
- if (typeof lang === 'string') {
- node.lang = lang;
- language = lang;
- }
- switch (type) {
- case 'table-cell':
- {
- const cell = /** @type {HTMLTableCellElement} */ (node);
- const {colSpan, rowSpan} = /** @type {import('structured-content').TableElement} */ (content);
- if (typeof colSpan === 'number') { cell.colSpan = colSpan; }
- if (typeof rowSpan === 'number') { cell.rowSpan = rowSpan; }
- }
- break;
- }
- if (hasStyle) {
- const {style, title} = /** @type {import('structured-content').StyledElement} */ (content);
- if (typeof style === 'object' && style !== null) {
- this._setStructuredContentElementStyle(node, style);
- }
- if (typeof title === 'string') { node.title = title; }
- }
- if (hasChildren) {
- this._appendStructuredContent(node, content.content, dictionary, language);
- }
- return node;
- }
-
- /**
- * @param {HTMLElement} node
- * @param {import('structured-content').StructuredContentStyle} contentStyle
- */
- _setStructuredContentElementStyle(node, contentStyle) {
- const {style} = node;
- const {
- fontStyle,
- fontWeight,
- fontSize,
- color,
- background,
- backgroundColor,
- textDecorationLine,
- textDecorationStyle,
- textDecorationColor,
- borderColor,
- borderStyle,
- borderRadius,
- borderWidth,
- clipPath,
- verticalAlign,
- textAlign,
- textEmphasis,
- textShadow,
- margin,
- marginTop,
- marginLeft,
- marginRight,
- marginBottom,
- padding,
- paddingTop,
- paddingLeft,
- paddingRight,
- paddingBottom,
- wordBreak,
- whiteSpace,
- cursor,
- listStyleType
- } = contentStyle;
- if (typeof fontStyle === 'string') { style.fontStyle = fontStyle; }
- if (typeof fontWeight === 'string') { style.fontWeight = fontWeight; }
- if (typeof fontSize === 'string') { style.fontSize = fontSize; }
- if (typeof color === 'string') { style.color = color; }
- if (typeof background === 'string') { style.background = background; }
- if (typeof backgroundColor === 'string') { style.backgroundColor = backgroundColor; }
- if (typeof verticalAlign === 'string') { style.verticalAlign = verticalAlign; }
- if (typeof textAlign === 'string') { style.textAlign = textAlign; }
- if (typeof textEmphasis === 'string') { style.textEmphasis = textEmphasis; }
- if (typeof textShadow === 'string') { style.textShadow = textShadow; }
- if (typeof textDecorationLine === 'string') {
- style.textDecoration = textDecorationLine;
- } else if (Array.isArray(textDecorationLine)) {
- style.textDecoration = textDecorationLine.join(' ');
- }
- if (typeof textDecorationStyle === 'string') {
- style.textDecorationStyle = textDecorationStyle;
- }
- if (typeof textDecorationColor === 'string') {
- style.textDecorationColor = textDecorationColor;
- }
- if (typeof borderColor === 'string') { style.borderColor = borderColor; }
- if (typeof borderStyle === 'string') { style.borderStyle = borderStyle; }
- if (typeof borderRadius === 'string') { style.borderRadius = borderRadius; }
- if (typeof borderWidth === 'string') { style.borderWidth = borderWidth; }
- if (typeof clipPath === 'string') { style.clipPath = clipPath; }
- if (typeof margin === 'string') { style.margin = margin; }
- if (typeof marginTop === 'number') { style.marginTop = `${marginTop}em`; }
- if (typeof marginTop === 'string') { style.marginTop = marginTop; }
- if (typeof marginLeft === 'number') { style.marginLeft = `${marginLeft}em`; }
- if (typeof marginLeft === 'string') { style.marginLeft = marginLeft; }
- if (typeof marginRight === 'number') { style.marginRight = `${marginRight}em`; }
- if (typeof marginRight === 'string') { style.marginRight = marginRight; }
- if (typeof marginBottom === 'number') { style.marginBottom = `${marginBottom}em`; }
- if (typeof marginBottom === 'string') { style.marginBottom = marginBottom; }
- if (typeof padding === 'string') { style.padding = padding; }
- if (typeof paddingTop === 'string') { style.paddingTop = paddingTop; }
- if (typeof paddingLeft === 'string') { style.paddingLeft = paddingLeft; }
- if (typeof paddingRight === 'string') { style.paddingRight = paddingRight; }
- if (typeof paddingBottom === 'string') { style.paddingBottom = paddingBottom; }
- if (typeof wordBreak === 'string') { style.wordBreak = wordBreak; }
- if (typeof whiteSpace === 'string') { style.whiteSpace = whiteSpace; }
- if (typeof cursor === 'string') { style.cursor = cursor; }
- if (typeof listStyleType === 'string') { style.listStyleType = listStyleType; }
- }
-
- /**
- * @param {import('structured-content').LinkElement} content
- * @param {string} dictionary
- * @param {?string} language
- * @returns {HTMLAnchorElement}
- */
- _createLinkElement(content, dictionary, language) {
- let {href} = content;
- const internal = href.startsWith('?');
- if (internal) {
- href = `${location.protocol}//${location.host}/search.html${href.length > 1 ? href : ''}`;
- }
-
- const node = /** @type {HTMLAnchorElement} */ (this._createElement('a', 'gloss-link'));
- node.dataset.external = `${!internal}`;
-
- const text = this._createElement('span', 'gloss-link-text');
- node.appendChild(text);
-
- const {lang} = content;
- if (typeof lang === 'string') {
- node.lang = lang;
- language = lang;
- }
-
- this._appendStructuredContent(text, content.content, dictionary, language);
-
- if (!internal) {
- const icon = this._createElement('span', 'gloss-link-external-icon icon');
- icon.dataset.icon = 'external-link';
- node.appendChild(icon);
- }
-
- this._contentManager.prepareLink(node, href, internal);
- return node;
- }
-}