From 4fe1c1a585d8dc6ababe0f8504dc65b333c02723 Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Mon, 8 Aug 2022 04:31:25 -0400 Subject: [PATCH] fix: text editor enriching and broken journals --- module.json | 4 +- src/index.ts | 51 +++++---- src/module/pf2e-persistent-damage.ts | 102 ++++++++---------- .../types/foundry/client/core/texteditor.d.ts | 5 +- 4 files changed, 78 insertions(+), 84 deletions(-) diff --git a/module.json b/module.json index dedf53e..adfd4e6 100644 --- a/module.json +++ b/module.json @@ -3,7 +3,7 @@ "title": "pf2e Persistent Damage", "description": "Macros that create effects to handle persistent damage", "author": "Supe", - "version": "0.10.0", + "version": "0.10.1", "compatibleCoreVersion": "10", "minimumCoreVersion": "10", "minimumSystemVersion": "3.1.0", @@ -38,5 +38,5 @@ ], "url": "https://github.com/CarlosFdez/pf2e-persistent-damage", "manifest": "https://github.com/CarlosFdez/pf2e-persistent-damage/releases/latest/download/module.json", - "download": "https://github.com/CarlosFdez/pf2e-persistent-damage/releases/download/v0.10.0/module.zip" + "download": "https://github.com/CarlosFdez/pf2e-persistent-damage/releases/download/v0.10.1/module.zip" } diff --git a/src/index.ts b/src/index.ts index 53845be..80ec953 100644 --- a/src/index.ts +++ b/src/index.ts @@ -94,35 +94,40 @@ Hooks.on("renderTokenHUD", (_app, html: JQuery, tokenData: foundry.data.TokenDat const persistentConditionId = "lDVqvLKA6eF3Df60"; const originalEnrichHTML = TextEditor.enrichHTML; TextEditor.enrichHTML = function (...args) { - const content = originalEnrichHTML.call(this, ...args); + const result = originalEnrichHTML.call(this, ...args) as Promise | string; - const html = document.createElement("div"); - html.innerHTML = String(content); + function transformResult(result: string) { + const html = document.createElement("div"); + html.innerHTML = String(result); - html.querySelectorAll(".inline-roll:not(.inline-result)").forEach(rollElement => { - // Attempt to pull persistent damage from the roll first - const result = parseInlineRollHTML(rollElement); - if (!result) return; + html.querySelectorAll(".inline-roll:not(.inline-result)").forEach((rollElement) => { + // Attempt to pull persistent damage from the roll first + const result = parseInlineRollHTML(rollElement); + if (!result) return; - const { formula, damageType } = result; + const { formula, damageType } = result; - // Remove the persistent effect condition image first - const compendiumLink = $(rollElement).next(); - if (compendiumLink.hasClass("entity-link") && compendiumLink.attr("data-id") === persistentConditionId) { - compendiumLink.remove(); - } + // Remove the persistent effect condition image first + const compendiumLink = rollElement.nextElementSibling as HTMLElement; + const compendiumLinkIsEntityLink = compendiumLink?.classList.contains("entity-link"); + if (compendiumLinkIsEntityLink && compendiumLink?.dataset.id === persistentConditionId) { + compendiumLink.remove(); + } - const newTitle = createPersistentTitle({ damageType, value: formula, dc: 15 }); - rollElement.classList.add("persistent-link"); - rollElement.draggable = true; - rollElement.dataset.value = formula; - rollElement.dataset.damageType = damageType; - rollElement.innerHTML = ` ${newTitle}`; - rollElement.setAttribute("ondragstart", "PF2EPersistentDamage._startDrag(event)"); - }); + const newTitle = createPersistentTitle({ damageType, value: formula, dc: 15 }); + rollElement.classList.add("persistent-link"); + rollElement.draggable = true; + rollElement.dataset.value = formula; + rollElement.dataset.damageType = damageType; + rollElement.innerHTML = ` ${newTitle}`; + rollElement.setAttribute("ondragstart", "PF2EPersistentDamage._startDrag(event)"); + }); - return html.innerHTML; -} + return html.innerHTML; + } + + return result instanceof Promise ? result.then(transformResult) : result; +}; /** Pulls */ function parseInlineRollHTML(rollElement: HTMLElement) { diff --git a/src/module/pf2e-persistent-damage.ts b/src/module/pf2e-persistent-damage.ts index deb03f6..b5c6ee9 100644 --- a/src/module/pf2e-persistent-damage.ts +++ b/src/module/pf2e-persistent-damage.ts @@ -2,13 +2,7 @@ import type { ActorPF2e } from "@pf2e/module/actor/index"; import type { TokenPF2e } from "@pf2e/module/canvas/token"; import type { ChatMessagePF2e } from "@pf2e/module/chat-message/index"; import type { ItemPF2e } from "@pf2e/module/item/index"; -import { - createPersistentEffect, - DamageType, - getPersistentData, - PersistentData, - typeImages, -} from "./persistent-effect"; +import { createPersistentEffect, DamageType, getPersistentData, PersistentData, typeImages } from "./persistent-effect"; import { AutoRecoverMode, MODULE_NAME, RollHideMode } from "./settings"; import { calculateRoll } from "./utils"; @@ -31,16 +25,18 @@ type TokenOrActorInput = TokenPF2e | ExtendedActor | Array }[] { const arr = Array.isArray(documents) ? documents : [documents]; - return arr.map((document) => { - if (document instanceof Actor) { - return { actor: document, token: document.token?.object }; - } else if (document?.data?.actorId && !document.actor) { - ui.notifications.warn("TOKEN.WarningNoActor", { localize: true }); - return null; - } else { - return { actor: document.actor, token: document }; - } - }).filter(arr => arr); + return arr + .map((document) => { + if (document instanceof Actor) { + return { actor: document, token: document.token?.object }; + } else if (document?.data?.actorId && !document.actor) { + ui.notifications.warn("TOKEN.WarningNoActor", { localize: true }); + return null; + } else { + return { actor: document.actor, token: document }; + } + }) + .filter((arr) => arr); } /** @@ -67,9 +63,7 @@ export class PersistentDamagePF2e { return false; }; - const yesMessage = game.i18n.localize( - actor ? "PF2E-PD.Dialog.Apply" : "PF2E-PD.Dialog.Add", - ); + const yesMessage = game.i18n.localize(actor ? "PF2E-PD.Dialog.Apply" : "PF2E-PD.Dialog.Add"); const types = Object.keys(typeImages).map(getTypeData); const dialog = new Dialog( @@ -125,12 +119,7 @@ export class PersistentDamagePF2e { * @param dc DC for the flat check to remove it * @returns */ - async addPersistentDamage( - actor: ActorPF2e | ActorPF2e[], - damageType: DamageType, - formula: string, - dc = 15, - ) { + async addPersistentDamage(actor: ActorPF2e | ActorPF2e[], damageType: DamageType, formula: string, dc = 15) { // Test for invalid parameters const errors = []; if (!damageType) errors.push("Missing damage type"); @@ -157,9 +146,7 @@ export class PersistentDamagePF2e { const effect = createPersistentEffect({ damageType, value: formula, dc }); for (const actor of actors) { const existing = PF2EPersistentDamage.getPersistentDamage(actor, damageType); - const { average: existingAverage } = calculateRoll( - existing?.data.flags.persistent?.value, - ); + const { average: existingAverage } = calculateRoll(existing?.data.flags.persistent?.value); const { average: newAverage } = calculateRoll(formula); if (!existing || newAverage >= existingAverage) { // Overwrite if greater or equal @@ -187,7 +174,10 @@ export class PersistentDamagePF2e { */ async removePersistentDamage(actor: ActorPF2e, type: DamageType) { const effects = actor.items.filter((i) => i.data.flags.persistent?.damageType === type); - await actor?.deleteEmbeddedDocuments("Item", effects.map((i) => i.id)); + await actor?.deleteEmbeddedDocuments( + "Item", + effects.map((i) => i.id), + ); } getPersistentDamage(actor: ActorPF2e, type: DamageType) { @@ -202,9 +192,7 @@ export class PersistentDamagePF2e { */ async rollRecoveryCheck(actor: ActorPF2e, damageType: DamageType | Embedded) { const effect = - damageType instanceof Item - ? damageType - : PF2EPersistentDamage.getPersistentDamage(actor, damageType); + damageType instanceof Item ? damageType : PF2EPersistentDamage.getPersistentDamage(actor, damageType); const data = effect?.data.flags.persistent as PersistentData; if (!data) return; @@ -248,8 +236,7 @@ export class PersistentDamagePF2e { const isPlayer = actor.hasPlayerOwner; const autoCheck = - autoRecover === AutoRecoverMode.Always || - (autoRecover === AutoRecoverMode.NPCOnly && !isPlayer); + autoRecover === AutoRecoverMode.Always || (autoRecover === AutoRecoverMode.NPCOnly && !isPlayer); for (const effect of persistentDamageElements) { const data = getPersistentData(effect.data); @@ -257,11 +244,10 @@ export class PersistentDamagePF2e { const typeName = game.i18n.localize(CONFIG.PF2E.damageTypes[damageType]); const roll = await new Roll(value, { item: effect.data }).evaluate({ async: true }); - const inlineCheck = autoCheck && TextEditor.enrichHTML("[[1d20]]"); + const inlineCheck = autoCheck && (await TextEditor.enrichHTML("[[1d20]]", { async: true })); const success = autoCheck && Number($(inlineCheck).text()) >= dc; - const templateName = - "modules/pf2e-persistent-damage/templates/chat/persistent-card.html"; + const templateName = "modules/pf2e-persistent-damage/templates/chat/persistent-card.html"; const ChatMessage = CONFIG.ChatMessage.documentClass as typeof ChatMessagePF2e; const speaker = ChatMessage.getSpeaker({ actor, token }); @@ -278,22 +264,26 @@ export class PersistentDamagePF2e { tokenId, }); - const rollMode = rollHideMode === RollHideMode.Never - ? "publicroll" - : rollHideMode === RollHideMode.Always - ? "blindroll" - : game.settings.get('core', 'rollMode'); - - const message = await ChatMessage.create({ - speaker, - flavor, - flags: { - persistent: data, + const rollMode = + rollHideMode === RollHideMode.Never + ? "publicroll" + : rollHideMode === RollHideMode.Always + ? "blindroll" + : game.settings.get("core", "rollMode"); + + const message = await ChatMessage.create( + { + speaker, + flavor, + flags: { + persistent: data, + }, + type: CONST.CHAT_MESSAGE_TYPES.ROLL, + roll, + sound: CONFIG.sounds.dice, }, - type: CONST.CHAT_MESSAGE_TYPES.ROLL, - roll, - sound: CONFIG.sounds.dice, - }, { rollMode }); + { rollMode }, + ); // Auto-remove the condition if enabled and it passes the DC if (autoCheck && autoResolve && success) { @@ -318,9 +308,7 @@ export class PersistentDamagePF2e { const dc = Number(target.dataset.dc) || 15; const effect = createPersistentEffect({ value, damageType, dc }); - dataTransfer.setData('text/plain', JSON.stringify({ - type: "Item", - data: effect - })); + const transferData = JSON.stringify({ type: "Item", data: effect }); + dataTransfer.setData("text/plain", transferData); } } diff --git a/types/types/foundry/client/core/texteditor.d.ts b/types/types/foundry/client/core/texteditor.d.ts index da9de5c..9a0fb9d 100644 --- a/types/types/foundry/client/core/texteditor.d.ts +++ b/types/types/foundry/client/core/texteditor.d.ts @@ -4,6 +4,7 @@ declare interface EnrichHTMLOptions { links?: boolean; rolls?: boolean; rollData?: boolean; + async?: boolean; } /** @@ -30,8 +31,8 @@ declare class TextEditor { */ static enrichHTML( content: string, - { secrets, entities, links, rolls, rollData }?: EnrichHTMLOptions, - ): string; + { secrets, entities, links, rolls, rollData, async }?: EnrichHTMLOptions, + ): Promise | string; /** * Preview an HTML fragment by constructing a substring of a given length from its inner text.