diff --git a/.eslintrc.yaml b/.eslintrc.yaml index f9d2d30e9e..f6a7fb3ed0 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -743,7 +743,7 @@ rules: wc/no-constructor-params: [2] wc/no-constructor: [2] wc/no-customized-built-in-elements: [2] - wc/no-exports-with-element: [2] + wc/no-exports-with-element: [0] wc/no-invalid-element-name: [2] wc/no-invalid-extends: [2] wc/no-method-prefixed-with-on: [2] diff --git a/web_src/js/webcomponents/GiteaOriginUrl.js b/web_src/js/webcomponents/GiteaOriginUrl.js index fca736064c..5d71d95c60 100644 --- a/web_src/js/webcomponents/GiteaOriginUrl.js +++ b/web_src/js/webcomponents/GiteaOriginUrl.js @@ -1,17 +1,21 @@ // Convert an absolute or relative URL to an absolute URL with the current origin +export function toOriginUrl(urlStr) { + try { + // only process absolute HTTP/HTTPS URL or relative URLs ('/xxx' or '//host/xxx') + if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) { + const {origin, protocol, hostname, port} = window.location; + const url = new URL(urlStr, origin); + url.protocol = protocol; + url.hostname = hostname; + url.port = port || (protocol === 'https:' ? '443' : '80'); + return url.toString(); + } + } catch {} + return urlStr; +} + window.customElements.define('gitea-origin-url', class extends HTMLElement { connectedCallback() { - const urlStr = this.getAttribute('data-url'); - try { - // only process absolute HTTP/HTTPS URL or relative URLs ('/xxx' or '//host/xxx') - if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) { - const url = new URL(urlStr, window.origin); - url.protocol = window.location.protocol; - url.host = window.location.host; - this.textContent = url.toString(); - return; - } - } catch {} - this.textContent = urlStr; + this.textContent = toOriginUrl(this.getAttribute('data-url')); } }); diff --git a/web_src/js/webcomponents/GiteaOriginUrl.test.js b/web_src/js/webcomponents/GiteaOriginUrl.test.js new file mode 100644 index 0000000000..f0629842b8 --- /dev/null +++ b/web_src/js/webcomponents/GiteaOriginUrl.test.js @@ -0,0 +1,17 @@ +import {toOriginUrl} from './GiteaOriginUrl.js'; + +test('toOriginUrl', () => { + const oldLocation = window.location; + for (const origin of ['https://example.com', 'https://example.com:3000']) { + window.location = new URL(`${origin}/`); + expect(toOriginUrl('/')).toEqual(`${origin}/`); + expect(toOriginUrl('/org/repo.git')).toEqual(`${origin}/org/repo.git`); + expect(toOriginUrl('https://another.com')).toEqual(`${origin}/`); + expect(toOriginUrl('https://another.com/')).toEqual(`${origin}/`); + expect(toOriginUrl('https://another.com/org/repo.git')).toEqual(`${origin}/org/repo.git`); + expect(toOriginUrl('https://another.com:4000')).toEqual(`${origin}/`); + expect(toOriginUrl('https://another.com:4000/')).toEqual(`${origin}/`); + expect(toOriginUrl('https://another.com:4000/org/repo.git')).toEqual(`${origin}/org/repo.git`); + } + window.location = oldLocation; +});