mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-02-20 00:50:04 -05:00
Some checks are pending
/ release (push) Waiting to run
testing-integration / test-unit (push) Waiting to run
testing-integration / test-sqlite (push) Waiting to run
testing-integration / test-mariadb (v10.6) (push) Waiting to run
testing-integration / test-mariadb (v11.8) (push) Waiting to run
testing / backend-checks (push) Waiting to run
testing / frontend-checks (push) Waiting to run
testing / test-unit (push) Blocked by required conditions
testing / test-e2e (push) Blocked by required conditions
testing / test-remote-cacher (redis) (push) Blocked by required conditions
testing / test-remote-cacher (valkey) (push) Blocked by required conditions
testing / test-remote-cacher (garnet) (push) Blocked by required conditions
testing / test-remote-cacher (redict) (push) Blocked by required conditions
testing / test-mysql (push) Blocked by required conditions
testing / test-pgsql (push) Blocked by required conditions
testing / test-sqlite (push) Blocked by required conditions
testing / security-check (push) Blocked by required conditions
See #8222 for context (loosely related to #4595). ## Implemented changes The conversion logic is kept in the frontend and the related npm libraries are lazy-loaded (unchanged). ### Show some tabs on the preview of the `CITATION.*` file to switch between the formats:   ### Convert the "Cite repository" to a simple link to the citation file So that this change can be considered non-breaking ## Current state (before this PR) The last non-test call of `git.Blob.GetBlobContent` is made to retrieve the content of an eventual CITATION file. This is available in the `...` menu near the clone URL:  And is displayed as a popup:  Co-authored-by: 0ko <0ko@noreply.codeberg.org> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9103 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: oliverpool <git@olivier.pfad.fr> Co-committed-by: oliverpool <git@olivier.pfad.fr>
114 lines
3.6 KiB
JavaScript
114 lines
3.6 KiB
JavaScript
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
import '@citation-js/plugin-software-formats';
|
|
import '@citation-js/plugin-bibtex';
|
|
import {Cite, plugins} from '@citation-js/core';
|
|
|
|
import {getCurrentLocale} from '../utils.js';
|
|
import {initTab} from '../modules/tab.ts';
|
|
|
|
window.customElements.define(
|
|
'citation-information',
|
|
class extends HTMLElement {
|
|
connectedCallback() {
|
|
const children = this.children; // eslint-disable-line wc/no-child-traversal-in-connectedcallback
|
|
if (children.length !== 1) {
|
|
// developer error
|
|
throw new Error(
|
|
`<citation-information> expected one child, got ${children.length}`,
|
|
);
|
|
}
|
|
|
|
const lang = getCurrentLocale() || 'en-US';
|
|
|
|
const raw = children[0];
|
|
raw.dataset.tab = 'raw';
|
|
raw.classList.add('tab', 'active');
|
|
|
|
// like in copy-content
|
|
const lineEls = raw.querySelectorAll('.lines-code');
|
|
const code = Array.from(lineEls, (el) => el.textContent).join('');
|
|
|
|
const inputType = plugins.input.type(code);
|
|
let parsed;
|
|
try {
|
|
parsed = new Cite(code, {forceType: inputType});
|
|
} catch (err) {
|
|
const elContainer = document.createElement('div');
|
|
elContainer.classList.add('ui', 'warning', 'message');
|
|
|
|
const elHeader = document.createElement('div');
|
|
elHeader.classList.add('header');
|
|
elHeader.textContent = `Could not parse citation-information (format ${inputType})`; // ideally this message should be localized, however the error below will likely be in english
|
|
elContainer.append(elHeader);
|
|
|
|
const elParagraph = document.createElement('pre');
|
|
elParagraph.textContent = err;
|
|
elContainer.append(elParagraph);
|
|
this.prepend(elContainer);
|
|
return;
|
|
}
|
|
|
|
const toggleBar = document.createElement('div');
|
|
toggleBar.classList.add('switch');
|
|
|
|
const newButton = (txt, id, tooltip, active) => {
|
|
const el = document.createElement('button');
|
|
el.textContent = txt;
|
|
el.dataset.tab = id;
|
|
if (tooltip) {
|
|
el.dataset.tooltipContent = tooltip;
|
|
}
|
|
el.classList.add('item');
|
|
if (active) {
|
|
el.classList.add('active');
|
|
}
|
|
return el;
|
|
};
|
|
let originalText = 'Original';
|
|
let originalTooltip = '';
|
|
switch (inputType) {
|
|
case '@biblatex/text':
|
|
originalText = 'BibTeX';
|
|
break;
|
|
case '@else/yaml':
|
|
originalText = 'CFF';
|
|
originalTooltip = 'Citation File Format';
|
|
break;
|
|
}
|
|
toggleBar.append(newButton(originalText, 'raw', originalTooltip, true));
|
|
|
|
const appendTab = (id, btnLabel, btnTooltip, tabContent) => {
|
|
const el = document.createElement('pre');
|
|
el.textContent = tabContent;
|
|
el.dataset.tab = id;
|
|
el.classList.add('tab');
|
|
el.style.padding = '1rem';
|
|
el.style.margin = 0;
|
|
this.append(el);
|
|
toggleBar.append(newButton(btnLabel, id, btnTooltip));
|
|
};
|
|
if (inputType !== '@biblatex/text') {
|
|
appendTab(
|
|
'bibtex',
|
|
'BibTeX',
|
|
'',
|
|
parsed.format('bibtex', {lang}).trim(),
|
|
);
|
|
}
|
|
if (inputType !== '@else/yaml') {
|
|
appendTab(
|
|
'cff',
|
|
'CFF',
|
|
'Citation File Format',
|
|
parsed.format('cff', {lang}).trim(),
|
|
);
|
|
}
|
|
|
|
const toggleBarParent = document.querySelector('.file-header-left');
|
|
toggleBarParent.prepend(toggleBar);
|
|
initTab(toggleBarParent);
|
|
}
|
|
},
|
|
);
|