|
| 1 | +import { Plugin } from "@html_editor/plugin"; |
| 2 | +import { registry } from "@web/core/registry"; |
| 3 | +import { _t } from "@web/core/l10n/translation"; |
| 4 | +import { getCommonAncestor } from "@html_editor/utils/dom_traversal"; |
| 5 | +import { withSequence } from "@html_editor/utils/resource"; |
| 6 | + |
| 7 | +class InstagramOptionPlugin extends Plugin { |
| 8 | + static id = "instagramOption"; |
| 9 | + static dependencies = ["history"]; |
| 10 | + |
| 11 | + resources = { |
| 12 | + builder_options: [ |
| 13 | + withSequence(40, { |
| 14 | + template: "html_builder.InstagramOption", |
| 15 | + selector: ".s_instagram_page", |
| 16 | + }), |
| 17 | + ], |
| 18 | + builder_actions: { |
| 19 | + instagramPageAction: { |
| 20 | + getValue: ({ editingElement }) => editingElement.dataset["instagramPage"], |
| 21 | + apply: ({ editingElement, value }) => { |
| 22 | + delete editingElement.dataset.instagramPageIsDefault; |
| 23 | + if (value.includes(this.instagramUrlStr)) { |
| 24 | + value = this.instagramPageNameFromUrl(value) || ""; |
| 25 | + } |
| 26 | + editingElement.dataset["instagramPage"] = value; |
| 27 | + if (value === "") { |
| 28 | + this.services.notification.add(_t("The Instagram page name is not valid"), { |
| 29 | + type: "warning", |
| 30 | + }); |
| 31 | + } |
| 32 | + }, |
| 33 | + }, |
| 34 | + }, |
| 35 | + normalize_handlers: this.normalize.bind(this), |
| 36 | + }; |
| 37 | + |
| 38 | + setup() { |
| 39 | + this.instagramUrlStr = "instagram.com/"; |
| 40 | + } |
| 41 | + |
| 42 | + normalize(root) { |
| 43 | + const SELECTOR = ".s_instagram_page[data-instagram-page-is-default]"; |
| 44 | + const nodes = [ |
| 45 | + ...root.querySelectorAll(SELECTOR), |
| 46 | + ...(root.matches(SELECTOR) ? [root] : []), |
| 47 | + ]; |
| 48 | + if (nodes.length) { |
| 49 | + this.loadAndSetPage(nodes); |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + async loadAndSetPage(nodes) { |
| 54 | + // TODO: look in shared cache with social info: was SocialMediaOption.getDbSocialValuesCache() |
| 55 | + if (this.instagramUrl) { |
| 56 | + this.setPage(nodes); |
| 57 | + return; |
| 58 | + } |
| 59 | + // Fetches the default url for instagram page from website config |
| 60 | + const res = await this.services.orm.read( |
| 61 | + "website", |
| 62 | + [this.services.website.currentWebsite.id], |
| 63 | + ["social_instagram"] |
| 64 | + ); |
| 65 | + if (res && res[0].social_instagram) { |
| 66 | + this.instagramUrl = this.instagramPageNameFromUrl(res[0].social_instagram); |
| 67 | + |
| 68 | + // WARNING: the call to ignoreDOMMutations is very dangerous, |
| 69 | + // and should be avoided in most cases (if you think you need those, ask html_editor team) |
| 70 | + const hasChanged = this.dependencies.history.ignoreDOMMutations(() => |
| 71 | + this.setPage(nodes) |
| 72 | + ); |
| 73 | + |
| 74 | + if (hasChanged) { |
| 75 | + const commonAncestor = getCommonAncestor(nodes, this.editable); |
| 76 | + this.dispatchTo("content_manually_updated_handlers", commonAncestor); |
| 77 | + this.config.onChange({ isPreviewing: false }); |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + |
| 82 | + setPage(nodes) { |
| 83 | + let hasChanged = false; |
| 84 | + for (const element of nodes) { |
| 85 | + if (element.dataset.instagramPageIsDefault) { |
| 86 | + delete element.dataset.instagramPageIsDefault; |
| 87 | + if (this.instagramUrl) { |
| 88 | + element.dataset.instagramPage = this.instagramUrl; |
| 89 | + } |
| 90 | + hasChanged = true; |
| 91 | + } |
| 92 | + } |
| 93 | + return hasChanged; |
| 94 | + } |
| 95 | + |
| 96 | + /** |
| 97 | + * Returns the instagram page name from the given url. |
| 98 | + * |
| 99 | + * @private |
| 100 | + * @param {string} url |
| 101 | + * @returns {string|undefined} |
| 102 | + */ |
| 103 | + instagramPageNameFromUrl(url) { |
| 104 | + const pageName = url.split(this.instagramUrlStr)[1]; |
| 105 | + if ( |
| 106 | + !pageName || |
| 107 | + pageName.includes("?") || |
| 108 | + pageName.includes("#") || |
| 109 | + (pageName.includes("/") && pageName.split("/")[1].length > 0) |
| 110 | + ) { |
| 111 | + return; |
| 112 | + } |
| 113 | + return pageName.split("/")[0]; |
| 114 | + } |
| 115 | +} |
| 116 | + |
| 117 | +registry.category("website-plugins").add(InstagramOptionPlugin.id, InstagramOptionPlugin); |
0 commit comments