From 697ebcc02450a523e86c32abb2788975d2446245 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 26 Aug 2023 01:50:45 +0800 Subject: [PATCH 01/13] fix --- web_src/js/webcomponents/dir-auto.js | 12 ++++++++++++ web_src/js/webcomponents/webcomponents.js | 1 + 2 files changed, 13 insertions(+) create mode 100644 web_src/js/webcomponents/dir-auto.js diff --git a/web_src/js/webcomponents/dir-auto.js b/web_src/js/webcomponents/dir-auto.js new file mode 100644 index 0000000000000..0a94e6bb41046 --- /dev/null +++ b/web_src/js/webcomponents/dir-auto.js @@ -0,0 +1,12 @@ +const observer = new MutationObserver((mutationList) => { + for (const mutation of mutationList) { + for (const el of mutation.addedNodes) { + if (el.nodeType === Node.ELEMENT_NODE || el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + for (const child of el.querySelectorAll('input:not([dir]), textarea:not([dir])')) { + child.setAttribute('dir', 'auto'); + } + } + } + } +}); +observer.observe(document, {subtree: true, childList: true}); diff --git a/web_src/js/webcomponents/webcomponents.js b/web_src/js/webcomponents/webcomponents.js index b17a4a832f704..db08b970b00fa 100644 --- a/web_src/js/webcomponents/webcomponents.js +++ b/web_src/js/webcomponents/webcomponents.js @@ -3,3 +3,4 @@ import './polyfill.js'; import '@github/relative-time-element'; import './GiteaOriginUrl.js'; +import './dir-auto.js'; From 93abd9c094d3f3e634359ec7c1d0a7f39d37c1f5 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 26 Aug 2023 02:02:06 +0800 Subject: [PATCH 02/13] exclude some input types --- web_src/js/webcomponents/dir-auto.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web_src/js/webcomponents/dir-auto.js b/web_src/js/webcomponents/dir-auto.js index 0a94e6bb41046..29c0c84a693dd 100644 --- a/web_src/js/webcomponents/dir-auto.js +++ b/web_src/js/webcomponents/dir-auto.js @@ -1,8 +1,11 @@ +const excludeInputTypes = new Set(['hidden', 'checkbox', 'radio', 'range']); + const observer = new MutationObserver((mutationList) => { for (const mutation of mutationList) { for (const el of mutation.addedNodes) { if (el.nodeType === Node.ELEMENT_NODE || el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { for (const child of el.querySelectorAll('input:not([dir]), textarea:not([dir])')) { + if (excludeInputTypes.has(child.type)) continue; child.setAttribute('dir', 'auto'); } } From f1366c019d7fb0c228a12ecab1277f4e57e56a7c Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 25 Aug 2023 20:49:36 +0200 Subject: [PATCH 03/13] add css fix --- web_src/css/base.css | 1 + 1 file changed, 1 insertion(+) diff --git a/web_src/css/base.css b/web_src/css/base.css index d9c57932fc2ec..5fd77aee27cfd 100644 --- a/web_src/css/base.css +++ b/web_src/css/base.css @@ -475,6 +475,7 @@ a.label, /* fix Fomantic's line-height cutting off "g" on Windows Chrome with Segoe UI */ .ui.input > input { line-height: 1.3; + text-align: start; /* Override fomantic's `text-align: left` to make RTL work via HTML `dir="auto"` */ } .ui.input.focus > input, From 76ef3c8b92a30036a97fae0484cf9b5133e3031d Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 25 Aug 2023 20:50:51 +0200 Subject: [PATCH 04/13] remove not, add color type --- web_src/js/webcomponents/dir-auto.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_src/js/webcomponents/dir-auto.js b/web_src/js/webcomponents/dir-auto.js index 29c0c84a693dd..90bdc4d9ba0d7 100644 --- a/web_src/js/webcomponents/dir-auto.js +++ b/web_src/js/webcomponents/dir-auto.js @@ -1,10 +1,10 @@ -const excludeInputTypes = new Set(['hidden', 'checkbox', 'radio', 'range']); +const excludeInputTypes = new Set(['hidden', 'checkbox', 'radio', 'range', 'color']); const observer = new MutationObserver((mutationList) => { for (const mutation of mutationList) { for (const el of mutation.addedNodes) { if (el.nodeType === Node.ELEMENT_NODE || el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { - for (const child of el.querySelectorAll('input:not([dir]), textarea:not([dir])')) { + for (const child of el.querySelectorAll('input, textarea')) { if (excludeInputTypes.has(child.type)) continue; child.setAttribute('dir', 'auto'); } From 3bc452b9f9b575889b7bddff4b4be3a0975f3472 Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 25 Aug 2023 21:06:27 +0200 Subject: [PATCH 05/13] improve perf, add benchmark logging for debug --- web_src/js/webcomponents/dir-auto.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/web_src/js/webcomponents/dir-auto.js b/web_src/js/webcomponents/dir-auto.js index 90bdc4d9ba0d7..5e6f487ac7bfc 100644 --- a/web_src/js/webcomponents/dir-auto.js +++ b/web_src/js/webcomponents/dir-auto.js @@ -1,15 +1,22 @@ const excludeInputTypes = new Set(['hidden', 'checkbox', 'radio', 'range', 'color']); +const includeNodeTypes = new Set([Node.ELEMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE]); + +let timeSpent = 0; const observer = new MutationObserver((mutationList) => { + const start = performance.now(); for (const mutation of mutationList) { for (const el of mutation.addedNodes) { - if (el.nodeType === Node.ELEMENT_NODE || el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { - for (const child of el.querySelectorAll('input, textarea')) { - if (excludeInputTypes.has(child.type)) continue; - child.setAttribute('dir', 'auto'); - } + if (!includeNodeTypes.has(el.nodeType)) continue; + for (const child of el.querySelectorAll('input, textarea')) { + if (excludeInputTypes.has(child.type)) continue; + child.dir = 'auto'; } } } + timeSpent += performance.now() - start; }); + +setTimeout(() => console.log(timeSpent), 2000); + observer.observe(document, {subtree: true, childList: true}); From 926269107850f7cefefd5ec41eb2ba155892b693 Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 25 Aug 2023 21:25:07 +0200 Subject: [PATCH 06/13] add pre-check with querySelector --- web_src/js/webcomponents/dir-auto.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web_src/js/webcomponents/dir-auto.js b/web_src/js/webcomponents/dir-auto.js index 5e6f487ac7bfc..d3617e21ddef4 100644 --- a/web_src/js/webcomponents/dir-auto.js +++ b/web_src/js/webcomponents/dir-auto.js @@ -8,6 +8,7 @@ const observer = new MutationObserver((mutationList) => { for (const mutation of mutationList) { for (const el of mutation.addedNodes) { if (!includeNodeTypes.has(el.nodeType)) continue; + if (!el.querySelector('input, textarea')) continue; for (const child of el.querySelectorAll('input, textarea')) { if (excludeInputTypes.has(child.type)) continue; child.dir = 'auto'; From f839933669d0a9e0a60edb6cdfe4d05c412886c0 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 26 Aug 2023 10:32:25 +0800 Subject: [PATCH 07/13] optimize --- web_src/js/index.js | 2 ++ web_src/js/modules/dirauto.js | 43 +++++++++++++++++++++++ web_src/js/webcomponents/dir-auto.js | 23 ------------ web_src/js/webcomponents/webcomponents.js | 2 +- 4 files changed, 46 insertions(+), 24 deletions(-) create mode 100644 web_src/js/modules/dirauto.js delete mode 100644 web_src/js/webcomponents/dir-auto.js diff --git a/web_src/js/index.js b/web_src/js/index.js index 8bd219bbe1576..7ae4b0c0c7ac2 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -84,9 +84,11 @@ import {onDomReady} from './utils/dom.js'; import {initRepoIssueList} from './features/repo-issue-list.js'; import {initCommonIssueListQuickGoto} from './features/common-issue-list.js'; import {initRepoDiffCommitBranchesAndTags} from './features/repo-diff-commit.js'; +import {initDirAuto} from './modules/dirauto.js'; // Init Gitea's Fomantic settings initGiteaFomantic(); +initDirAuto(); onDomReady(() => { initGlobalCommon(); diff --git a/web_src/js/modules/dirauto.js b/web_src/js/modules/dirauto.js new file mode 100644 index 0000000000000..217b9f263af30 --- /dev/null +++ b/web_src/js/modules/dirauto.js @@ -0,0 +1,43 @@ +// for performance considerations, it only uses performant syntax + +function attachDirAuto(el) { + if (el.type !== 'hidden' && + el.type !== 'checkbox' && + el.type !== 'radio' && + el.type !== 'range' && + el.type !== 'color') { + el.dir = 'auto'; + } +} + +export function initDirAuto() { + let timeSpent = 0; + + const observer = new MutationObserver((mutationList) => { + const start = performance.now(); + for (let mutationIdx = 0; mutationIdx < mutationList.length; mutationIdx++) { + const mutation = mutationList[mutationIdx]; + for (let addedNodeIdx = 0; addedNodeIdx < mutation.addedNodes.length; addedNodeIdx++) { + const addedNode = mutation.addedNodes[addedNodeIdx]; + if (addedNode.nodeType !== Node.ELEMENT_NODE && addedNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) continue; + attachDirAuto(addedNode); + const children = addedNode.querySelectorAll('input, textarea'); + for (let childIdx = 0; childIdx < children.length; childIdx++) { + attachDirAuto(children[childIdx]); + } + } + } + timeSpent += performance.now() - start; + }); + + const start = performance.now(); + const docNodes = document.querySelectorAll('input, textarea'); + for (let i = 0; i < docNodes.length; i++) { + attachDirAuto(docNodes[i]); + } + timeSpent += performance.now() - start; + + setTimeout(() => console.log(timeSpent), 2000); + + observer.observe(document, {subtree: true, childList: true}); +} diff --git a/web_src/js/webcomponents/dir-auto.js b/web_src/js/webcomponents/dir-auto.js deleted file mode 100644 index d3617e21ddef4..0000000000000 --- a/web_src/js/webcomponents/dir-auto.js +++ /dev/null @@ -1,23 +0,0 @@ -const excludeInputTypes = new Set(['hidden', 'checkbox', 'radio', 'range', 'color']); -const includeNodeTypes = new Set([Node.ELEMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE]); - -let timeSpent = 0; - -const observer = new MutationObserver((mutationList) => { - const start = performance.now(); - for (const mutation of mutationList) { - for (const el of mutation.addedNodes) { - if (!includeNodeTypes.has(el.nodeType)) continue; - if (!el.querySelector('input, textarea')) continue; - for (const child of el.querySelectorAll('input, textarea')) { - if (excludeInputTypes.has(child.type)) continue; - child.dir = 'auto'; - } - } - } - timeSpent += performance.now() - start; -}); - -setTimeout(() => console.log(timeSpent), 2000); - -observer.observe(document, {subtree: true, childList: true}); diff --git a/web_src/js/webcomponents/webcomponents.js b/web_src/js/webcomponents/webcomponents.js index db08b970b00fa..f28ebc1ad9e32 100644 --- a/web_src/js/webcomponents/webcomponents.js +++ b/web_src/js/webcomponents/webcomponents.js @@ -3,4 +3,4 @@ import './polyfill.js'; import '@github/relative-time-element'; import './GiteaOriginUrl.js'; -import './dir-auto.js'; + From 17b1c3ee577c380efe5d27be7ae20f49e3ddf63d Mon Sep 17 00:00:00 2001 From: silverwind Date: Sat, 26 Aug 2023 11:49:37 +0200 Subject: [PATCH 08/13] Update web_src/js/webcomponents/webcomponents.js --- web_src/js/webcomponents/webcomponents.js | 1 - 1 file changed, 1 deletion(-) diff --git a/web_src/js/webcomponents/webcomponents.js b/web_src/js/webcomponents/webcomponents.js index f28ebc1ad9e32..b17a4a832f704 100644 --- a/web_src/js/webcomponents/webcomponents.js +++ b/web_src/js/webcomponents/webcomponents.js @@ -3,4 +3,3 @@ import './polyfill.js'; import '@github/relative-time-element'; import './GiteaOriginUrl.js'; - From 21494b47a51fbc982a84307e26f1fbff0377a827 Mon Sep 17 00:00:00 2001 From: silverwind Date: Wed, 6 Sep 2023 22:02:56 +0200 Subject: [PATCH 09/13] use i --- web_src/js/modules/dirauto.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_src/js/modules/dirauto.js b/web_src/js/modules/dirauto.js index 217b9f263af30..3a279838fb94e 100644 --- a/web_src/js/modules/dirauto.js +++ b/web_src/js/modules/dirauto.js @@ -15,8 +15,8 @@ export function initDirAuto() { const observer = new MutationObserver((mutationList) => { const start = performance.now(); - for (let mutationIdx = 0; mutationIdx < mutationList.length; mutationIdx++) { - const mutation = mutationList[mutationIdx]; + for (let i = 0; i < mutationList.length; i++) { + const mutation = mutationList[i]; for (let addedNodeIdx = 0; addedNodeIdx < mutation.addedNodes.length; addedNodeIdx++) { const addedNode = mutation.addedNodes[addedNodeIdx]; if (addedNode.nodeType !== Node.ELEMENT_NODE && addedNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) continue; From b853d6766fa8b475d85394be9c05274e1197aa6c Mon Sep 17 00:00:00 2001 From: silverwind Date: Wed, 6 Sep 2023 22:16:08 +0200 Subject: [PATCH 10/13] use Set --- web_src/js/modules/dirauto.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/web_src/js/modules/dirauto.js b/web_src/js/modules/dirauto.js index 3a279838fb94e..589f45643fc3a 100644 --- a/web_src/js/modules/dirauto.js +++ b/web_src/js/modules/dirauto.js @@ -1,11 +1,9 @@ // for performance considerations, it only uses performant syntax +const excludeTypes = new Set(['hidden', 'checkbox', 'radio', 'range', 'color']); + function attachDirAuto(el) { - if (el.type !== 'hidden' && - el.type !== 'checkbox' && - el.type !== 'radio' && - el.type !== 'range' && - el.type !== 'color') { + if (!excludeTypes.has(el.type)) { el.dir = 'auto'; } } From 10cb39c7d70001d072690fe667d1ff565da87897 Mon Sep 17 00:00:00 2001 From: silverwind Date: Wed, 6 Sep 2023 22:26:18 +0200 Subject: [PATCH 11/13] cache for lengths, remove measuring code --- web_src/js/modules/dirauto.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/web_src/js/modules/dirauto.js b/web_src/js/modules/dirauto.js index 589f45643fc3a..f878e97ce1212 100644 --- a/web_src/js/modules/dirauto.js +++ b/web_src/js/modules/dirauto.js @@ -9,33 +9,29 @@ function attachDirAuto(el) { } export function initDirAuto() { - let timeSpent = 0; - const observer = new MutationObserver((mutationList) => { - const start = performance.now(); - for (let i = 0; i < mutationList.length; i++) { + const len = mutationList.length; + for (let i = 0; i < len; i++) { const mutation = mutationList[i]; - for (let addedNodeIdx = 0; addedNodeIdx < mutation.addedNodes.length; addedNodeIdx++) { + const len = mutation.addedNodes.length; + for (let addedNodeIdx = 0; addedNodeIdx < len; addedNodeIdx++) { const addedNode = mutation.addedNodes[addedNodeIdx]; if (addedNode.nodeType !== Node.ELEMENT_NODE && addedNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) continue; attachDirAuto(addedNode); const children = addedNode.querySelectorAll('input, textarea'); - for (let childIdx = 0; childIdx < children.length; childIdx++) { + const len = children.length; + for (let childIdx = 0; childIdx < len; childIdx++) { attachDirAuto(children[childIdx]); } } } - timeSpent += performance.now() - start; }); - const start = performance.now(); const docNodes = document.querySelectorAll('input, textarea'); - for (let i = 0; i < docNodes.length; i++) { + const len = docNodes.length; + for (let i = 0; i < len; i++) { attachDirAuto(docNodes[i]); } - timeSpent += performance.now() - start; - - setTimeout(() => console.log(timeSpent), 2000); observer.observe(document, {subtree: true, childList: true}); } From e78c181f9fe6d228e735f1a1f2a941ec15ff284f Mon Sep 17 00:00:00 2001 From: silverwind Date: Thu, 7 Sep 2023 09:48:46 +0200 Subject: [PATCH 12/13] switch back to if --- web_src/js/modules/dirauto.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web_src/js/modules/dirauto.js b/web_src/js/modules/dirauto.js index f878e97ce1212..6d4b3b16d7346 100644 --- a/web_src/js/modules/dirauto.js +++ b/web_src/js/modules/dirauto.js @@ -1,9 +1,11 @@ // for performance considerations, it only uses performant syntax -const excludeTypes = new Set(['hidden', 'checkbox', 'radio', 'range', 'color']); - function attachDirAuto(el) { - if (!excludeTypes.has(el.type)) { + if (el.type !== 'hidden' && + el.type !== 'checkbox' && + el.type !== 'radio' && + el.type !== 'range' && + el.type !== 'color') { el.dir = 'auto'; } } From c24d544835a7049b4c97d056346ba665b9aca418 Mon Sep 17 00:00:00 2001 From: silverwind Date: Thu, 7 Sep 2023 09:52:29 +0200 Subject: [PATCH 13/13] use i in inner loop as well --- web_src/js/modules/dirauto.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_src/js/modules/dirauto.js b/web_src/js/modules/dirauto.js index 6d4b3b16d7346..91f71a5b853db 100644 --- a/web_src/js/modules/dirauto.js +++ b/web_src/js/modules/dirauto.js @@ -16,8 +16,8 @@ export function initDirAuto() { for (let i = 0; i < len; i++) { const mutation = mutationList[i]; const len = mutation.addedNodes.length; - for (let addedNodeIdx = 0; addedNodeIdx < len; addedNodeIdx++) { - const addedNode = mutation.addedNodes[addedNodeIdx]; + for (let i = 0; i < len; i++) { + const addedNode = mutation.addedNodes[i]; if (addedNode.nodeType !== Node.ELEMENT_NODE && addedNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) continue; attachDirAuto(addedNode); const children = addedNode.querySelectorAll('input, textarea');