diff --git a/web/app/components/document/sidebar/related-resources/add/external-resource.hbs b/web/app/components/document/sidebar/related-resources/add/external-resource.hbs index 6ef1bdc0c..480171df6 100644 --- a/web/app/components/document/sidebar/related-resources/add/external-resource.hbs +++ b/web/app/components/document/sidebar/related-resources/add/external-resource.hbs @@ -19,7 +19,7 @@ {{@url}}
- +
diff --git a/web/app/components/document/sidebar/related-resources/list-item/resource.hbs b/web/app/components/document/sidebar/related-resources/list-item/resource.hbs index 1cafa3dec..0ab4d9db4 100644 --- a/web/app/components/document/sidebar/related-resources/list-item/resource.hbs +++ b/web/app/components/document/sidebar/related-resources/list-item/resource.hbs @@ -6,10 +6,7 @@ {{else}} - + {{/if}} diff --git a/web/app/components/document/sidebar/related-resources/list-item/resource.ts b/web/app/components/document/sidebar/related-resources/list-item/resource.ts index 54017d1f3..c3a1a45eb 100644 --- a/web/app/components/document/sidebar/related-resources/list-item/resource.ts +++ b/web/app/components/document/sidebar/related-resources/list-item/resource.ts @@ -51,10 +51,11 @@ export default class DocumentSidebarRelatedResourcesListItemResourceComponent ex /** * The full URL of an ExternalResource */ - private get url() { + protected get url() { assert("url must exist in the resource", "url" in this.args.resource); return this.args.resource.url; } + /** * The url to display in the ResourceList. * Strips the protocol, "www" and path. diff --git a/web/app/components/favicon.hbs b/web/app/components/favicon.hbs new file mode 100644 index 000000000..eb1338e93 --- /dev/null +++ b/web/app/components/favicon.hbs @@ -0,0 +1,17 @@ +{{#if this.fallbackIconIsShown}} + +{{else}} + +{{/if}} diff --git a/web/app/components/favicon.ts b/web/app/components/favicon.ts new file mode 100644 index 000000000..0ff42c36a --- /dev/null +++ b/web/app/components/favicon.ts @@ -0,0 +1,26 @@ +import { action } from "@ember/object"; +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; + +interface FaviconComponentSignature { + Element: SVGElement | HTMLImageElement; + Args: { + url: string; + }; +} + +export default class FaviconComponent extends Component { + @tracked protected fallbackIconIsShown = false; + + protected readonly faviconURL = `https://www.google.com/s2/favicons?sz=64&domain=${this.args.url}`; + + @action protected showFallbackIcon() { + this.fallbackIconIsShown = true; + } +} + +declare module "@glint/environment-ember-loose/registry" { + export default interface Registry { + Favicon: typeof FaviconComponent; + } +} diff --git a/web/app/helpers/get-link-icon.ts b/web/app/helpers/get-link-icon.ts deleted file mode 100644 index 09b56bc1a..000000000 --- a/web/app/helpers/get-link-icon.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { helper } from "@ember/component/helper"; - -export interface GetLinkIconSignature { - Args: { - Positional: [string | undefined]; - }; - Return: string; -} - -const getLinkIconHelper = helper(([url]) => { - if (url) { - const urlParts = url.split("/"); - let domain = urlParts[2]; - - if (domain) { - const domainParts = domain.split("."); - - domain = domainParts[domainParts.length - 2]; - - if (domain) { - if (domain.includes("figma")) { - return "figma-color"; - } - if (domain.includes("google")) { - return "google-color"; - } - if (domain.includes("datadog")) { - return "datadog-color"; - } - if (domain.includes("github")) { - return "github-color"; - } - if (domain.includes("codepen")) { - return "codepen-color"; - } - if (domain.includes("slack")) { - return "slack-color"; - } - if (domain.includes("loom")) { - return "loom-color"; - } - } - } - } - return "globe"; -}); - -export default getLinkIconHelper; - -declare module "@glint/environment-ember-loose/registry" { - export default interface Registry { - "get-link-icon": typeof getLinkIconHelper; - } -} diff --git a/web/tests/integration/components/favicon-test.ts b/web/tests/integration/components/favicon-test.ts new file mode 100644 index 000000000..afab56cc4 --- /dev/null +++ b/web/tests/integration/components/favicon-test.ts @@ -0,0 +1,39 @@ +import { module, test } from "qunit"; +import { setupRenderingTest } from "ember-qunit"; +import { find, render, waitFor } from "@ember/test-helpers"; +import { hbs } from "ember-cli-htmlbars"; + +const FALLBACK_ICON_SELECTOR = "[data-test-fallback-favicon]"; +const FAVICON_SELECTOR = "[data-test-favicon]"; + +module("Integration | Component | favicon", function (hooks) { + setupRenderingTest(hooks); + + test("it appends the passed-in URL to the google favicon path", async function (assert) { + await render(hbs` + + `); + + assert + .dom(FAVICON_SELECTOR) + .hasAttribute( + "src", + "https://www.google.com/s2/favicons?sz=64&domain=https://hashicorp.com" + ); + }); + + test("it shows a fallback icon when the favicon URL is invalid", async function (assert) { + await render(hbs` + + `); + + assert.dom(FALLBACK_ICON_SELECTOR).doesNotExist(); + + find(FAVICON_SELECTOR)?.dispatchEvent(new Event("error")); + + await waitFor(FALLBACK_ICON_SELECTOR); + + assert.dom(FALLBACK_ICON_SELECTOR).exists(); + assert.dom(FAVICON_SELECTOR).doesNotExist(); + }); +});