Merge pull request #59488 from nextcloud/backport/59424/stable33

This commit is contained in:
Kate 2026-04-20 21:46:52 +02:00 committed by GitHub
commit f4fa0839fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 66 additions and 63 deletions

View file

@ -101,7 +101,7 @@ describe('Inline system tags action render tests', () => {
contents: [],
})
expect(result).toBeInstanceOf(HTMLElement)
expect(result!.outerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"></ul>"')
expect(result!.outerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"></div>"')
})
test('Render a single system tag', async () => {
@ -126,7 +126,7 @@ describe('Inline system tags action render tests', () => {
contents: [],
})
expect(result).toBeInstanceOf(HTMLElement)
expect(result!.outerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"><li class="files-list__system-tag" data-systemtag-name="Confidential">Confidential</li></ul>"')
expect(result!.outerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"><ul class="files-list__system-tags" aria-label="Assigned collaborative tags"><li class="files-list__system-tag" data-systemtag-name="Confidential">Confidential</li></ul></div>"')
})
test('Render two system tags', async () => {
@ -151,7 +151,7 @@ describe('Inline system tags action render tests', () => {
contents: [],
})
expect(result).toBeInstanceOf(HTMLElement)
expect(result!.outerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"><li class="files-list__system-tag" data-systemtag-name="Important">Important</li><li class="files-list__system-tag" data-systemtag-name="Confidential">Confidential</li></ul>"')
expect(result!.outerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"><ul class="files-list__system-tags" aria-label="Assigned collaborative tags"><li class="files-list__system-tag" data-systemtag-name="Important">Important</li><li class="files-list__system-tag" data-systemtag-name="Confidential">Confidential</li></ul></div>"')
})
test('Render multiple system tags', async () => {
@ -181,7 +181,7 @@ describe('Inline system tags action render tests', () => {
contents: [],
})
expect(result).toBeInstanceOf(HTMLElement)
expect(result!.outerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"><li class="files-list__system-tag" data-systemtag-name="Important">Important</li><li class="files-list__system-tag files-list__system-tag--more" data-systemtag-name="+3" title="Confidential, Secret, Classified" aria-hidden="true" role="presentation">+3</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Confidential">Confidential</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Secret">Secret</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Classified">Classified</li></ul>"')
expect(result!.outerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"><ul class="files-list__system-tags" aria-label="Assigned collaborative tags"><li class="files-list__system-tag" data-systemtag-name="Important">Important</li><li class="files-list__system-tag files-list__system-tag--more" data-systemtag-name="+3" title="Confidential, Secret, Classified" aria-hidden="true" role="presentation">+3</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Confidential">Confidential</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Secret">Secret</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Classified">Classified</li></ul></div>"')
})
test('Render gets updated on system tag change', async () => {
@ -212,7 +212,7 @@ describe('Inline system tags action render tests', () => {
}) as HTMLElement
document.body.appendChild(result)
expect(result).toBeInstanceOf(HTMLElement)
expect(document.body.innerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"><li class="files-list__system-tag" data-systemtag-name="Important">Important</li><li class="files-list__system-tag files-list__system-tag--more" data-systemtag-name="+3" title="Confidential, Secret, Classified" aria-hidden="true" role="presentation">+3</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Confidential">Confidential</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Secret">Secret</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Classified">Classified</li></ul>"')
expect(document.body.innerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"><ul class="files-list__system-tags" aria-label="Assigned collaborative tags"><li class="files-list__system-tag" data-systemtag-name="Important">Important</li><li class="files-list__system-tag files-list__system-tag--more" data-systemtag-name="+3" title="Confidential, Secret, Classified" aria-hidden="true" role="presentation">+3</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Confidential">Confidential</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Secret">Secret</li><li class="files-list__system-tag hidden-visually" data-systemtag-name="Classified">Classified</li></ul></div>"')
// Subscribe to the event
const eventPromise = new Promise((resolve) => {
@ -229,7 +229,7 @@ describe('Inline system tags action render tests', () => {
// Wait for the event to be processed
await eventPromise
expect(document.body.innerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"><li class="files-list__system-tag" data-systemtag-name="Public">Public</li></ul>"')
expect(document.body.innerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"><ul class="files-list__system-tags" aria-label="Assigned collaborative tags"><li class="files-list__system-tag" data-systemtag-name="Public">Public</li></ul></div>"')
})
})
@ -273,7 +273,7 @@ describe('Inline system tags action colors', () => {
contents: [],
})
expect(result).toBeInstanceOf(HTMLElement)
expect(result!.outerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"><li class="files-list__system-tag" data-systemtag-name="Confidential" style="--systemtag-color: #000000;" data-systemtag-color="true">Confidential</li></ul>"')
expect(result!.outerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"><ul class="files-list__system-tags" aria-label="Assigned collaborative tags"><li class="files-list__system-tag" data-systemtag-name="Confidential" style="--systemtag-color: #000000;" data-systemtag-color="true">Confidential</li></ul></div>"')
})
test('Render a single system tag with invalid WCAG color', async () => {
@ -300,7 +300,7 @@ describe('Inline system tags action colors', () => {
contents: [],
})
expect(result).toBeInstanceOf(HTMLElement)
expect(result!.outerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"><li class="files-list__system-tag" data-systemtag-name="Confidential" style="--systemtag-color: #646464;" data-systemtag-color="true">Confidential</li></ul>"')
expect(result!.outerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"><ul class="files-list__system-tags" aria-label="Assigned collaborative tags"><li class="files-list__system-tag" data-systemtag-name="Confidential" style="--systemtag-color: #646464;" data-systemtag-color="true">Confidential</li></ul></div>"')
document.body.removeAttribute('data-themes')
})
@ -328,7 +328,7 @@ describe('Inline system tags action colors', () => {
}) as HTMLElement
document.body.appendChild(result)
expect(result).toBeInstanceOf(HTMLElement)
expect(document.body.innerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"><li class="files-list__system-tag" data-systemtag-name="Confidential" style="--systemtag-color: #000000;" data-systemtag-color="true">Confidential</li></ul>"')
expect(document.body.innerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"><ul class="files-list__system-tags" aria-label="Assigned collaborative tags"><li class="files-list__system-tag" data-systemtag-name="Confidential" style="--systemtag-color: #000000;" data-systemtag-color="true">Confidential</li></ul></div>"')
// Subscribe to the event
const eventPromise = new Promise((resolve) => {
@ -344,6 +344,6 @@ describe('Inline system tags action colors', () => {
// Wait for the event to be processed
await eventPromise
expect(document.body.innerHTML).toMatchInlineSnapshot('"<ul class="files-list__system-tags" aria-label="Assigned collaborative tags" data-systemtags-fileid="1"><li class="files-list__system-tag" data-systemtag-name="Confidential" style="--systemtag-color: #456789;" data-systemtag-color="true">Confidential</li></ul>"')
expect(document.body.innerHTML).toMatchInlineSnapshot('"<div data-systemtags-fileid="1"><ul class="files-list__system-tags" aria-label="Assigned collaborative tags"><li class="files-list__system-tag" data-systemtag-name="Confidential" style="--systemtag-color: #456789;" data-systemtag-color="true">Confidential</li></ul></div>"')
})
})

View file

@ -34,12 +34,15 @@ export const action: IFileAction = {
return true
},
exec: async () => null,
renderInline: ({ nodes }) => {
async exec() {
return null
},
async renderInline({ nodes }) {
if (nodes.length !== 1 || !nodes[0]) {
return Promise.resolve(null)
return null
}
return renderInline(nodes[0])
return await renderInline(nodes[0])
},
order: 0,
@ -56,12 +59,12 @@ subscribe('systemtags:tag:updated', updateTag)
*
* @param node - The updated node
*/
function updateSystemTagsHtml(node: INode) {
renderInline(node).then((systemTagsHtml) => {
document.querySelectorAll(`[data-systemtags-fileid="${node.fileid}"]`).forEach((element) => {
element.replaceWith(systemTagsHtml)
})
})
async function updateSystemTagsHtml(node: INode) {
const systemTagsHtml = await renderInline(node)
const elements = document.querySelectorAll(`[data-systemtags-fileid="${node.id}"]`)
for (const element of elements) {
element.replaceWith(systemTagsHtml)
}
}
/**
@ -145,50 +148,50 @@ function renderTag(tag: string, isMore = false): HTMLElement {
async function renderInline(node: INode): Promise<HTMLElement> {
// Ensure we have the system tags as an array
const tags = getNodeSystemTags(node)
const systemTagsElementWrapper = document.createElement('div')
systemTagsElementWrapper.setAttribute('data-systemtags-fileid', node.id || '')
const systemTagsElement = document.createElement('ul')
systemTagsElement.classList.add('files-list__system-tags')
systemTagsElement.setAttribute('aria-label', t('files', 'Assigned collaborative tags'))
systemTagsElement.setAttribute('data-systemtags-fileid', node.fileid?.toString() || '')
if (tags.length > 0) {
const systemTagsElement = document.createElement('ul')
systemTagsElement.classList.add('files-list__system-tags')
systemTagsElement.setAttribute('aria-label', t('files', 'Assigned collaborative tags'))
systemTagsElementWrapper.appendChild(systemTagsElement)
if (tags.length === 0) {
return systemTagsElement
}
// Fetch the tags if the cache is empty
if (cache.length === 0) {
try {
// Best would be to support attributes from webdav,
// but currently the library does not support it
cache.push(...await fetchTags())
} catch (error) {
logger.error('Failed to fetch tags', { error })
}
}
// Fetch the tags if the cache is empty
if (cache.length === 0) {
try {
// Best would be to support attributes from webdav,
// but currently the library does not support it
cache.push(...await fetchTags())
} catch (error) {
logger.error('Failed to fetch tags', { error })
systemTagsElement.append(renderTag(tags[0]!))
if (tags.length === 2) {
// Special case only two tags:
// the overflow fake tag would take the same space as this, so render it
systemTagsElement.append(renderTag(tags[1]!))
} else if (tags.length > 1) {
// More tags than the one we're showing
// So we add a overflow element indicating there are more tags
const moreTagElement = renderTag('+' + (tags.length - 1), true)
moreTagElement.setAttribute('title', tags.slice(1).join(', '))
// because the title is not accessible we hide this element for screen readers (see alternative below)
moreTagElement.setAttribute('aria-hidden', 'true')
moreTagElement.setAttribute('role', 'presentation')
systemTagsElement.append(moreTagElement)
// For accessibility the tags are listed, as the title is not accessible
// but those tags are visually hidden
for (const tag of tags.slice(1)) {
const tagElement = renderTag(tag)
tagElement.classList.add('hidden-visually')
systemTagsElement.append(tagElement)
}
}
}
systemTagsElement.append(renderTag(tags[0]!))
if (tags.length === 2) {
// Special case only two tags:
// the overflow fake tag would take the same space as this, so render it
systemTagsElement.append(renderTag(tags[1]!))
} else if (tags.length > 1) {
// More tags than the one we're showing
// So we add a overflow element indicating there are more tags
const moreTagElement = renderTag('+' + (tags.length - 1), true)
moreTagElement.setAttribute('title', tags.slice(1).join(', '))
// because the title is not accessible we hide this element for screen readers (see alternative below)
moreTagElement.setAttribute('aria-hidden', 'true')
moreTagElement.setAttribute('role', 'presentation')
systemTagsElement.append(moreTagElement)
// For accessibility the tags are listed, as the title is not accessible
// but those tags are visually hidden
for (const tag of tags.slice(1)) {
const tagElement = renderTag(tag)
tagElement.classList.add('hidden-visually')
systemTagsElement.append(tagElement)
}
}
return systemTagsElement
return systemTagsElementWrapper
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long