diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index d25a1a4e..903caa2a 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -211,7 +211,7 @@ export default function DHApplicationMixin(Base) { const step = event.key === 'ArrowUp' ? 1 : event.key === 'ArrowDown' ? -1 : 0; if (step !== 0) { handleUpdate(step); - deltaInput.dispatchEvent(new Event("change", { bubbles: true })); + deltaInput.dispatchEvent(new Event('change', { bubbles: true })); } }); @@ -222,7 +222,7 @@ export default function DHApplicationMixin(Base) { if (deltaInput === document.activeElement) { event.preventDefault(); handleUpdate(Math.sign(-1 * event.deltaY)); - deltaInput.dispatchEvent(new Event("change", { bubbles: true })); + deltaInput.dispatchEvent(new Event('change', { bubbles: true })); } }, { passive: false } @@ -236,7 +236,7 @@ export default function DHApplicationMixin(Base) { // Handle contenteditable for (const input of htmlElement.querySelectorAll('[contenteditable][data-property]')) { const property = input.dataset.property; - input.addEventListener("blur", () => { + input.addEventListener('blur', () => { const selection = document.getSelection(); if (input.contains(selection.anchorNode)) { selection.empty(); @@ -244,12 +244,12 @@ export default function DHApplicationMixin(Base) { this.document.update({ [property]: input.textContent }); }); - input.addEventListener("keydown", event => { - if (event.key === "Enter") input.blur(); + input.addEventListener('keydown', event => { + if (event.key === 'Enter') input.blur(); }); // Chrome sometimes add
, which aren't a problem for the value but are for the placeholder - input.addEventListener("input", () => input.querySelectorAll("br").forEach((i) => i.remove())); + input.addEventListener('input', () => input.querySelectorAll('br').forEach(i => i.remove())); } } @@ -585,7 +585,9 @@ export default function DHApplicationMixin(Base) { if (!doc || !descriptionElement) continue; // localize the description (idk if it's still necessary) - const description = game.i18n.localize(doc.system?.description ?? doc.description); + const description = doc.system?.getEnrichedDescription + ? await doc.system.getEnrichedDescription() + : game.i18n.localize(doc.system?.description ?? doc.description); // Enrich the description and attach it; const isAction = doc.documentName === 'Action'; @@ -736,7 +738,7 @@ export default function DHApplicationMixin(Base) { }; if (inVault) data['system.inVault'] = true; if (disabled) data.disabled = true; - if (type === "domainCard" && parent?.system.domains?.length) { + if (type === 'domainCard' && parent?.system.domains?.length) { data.system.domain = parent.system.domains[0]; } diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index 42ed9426..4ef5f048 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -76,16 +76,10 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { /**@inheritdoc */ async _preparePartContext(partId, context, options) { await super._preparePartContext(partId, context, options); - const { TextEditor } = foundry.applications.ux; switch (partId) { case 'description': - const value = foundry.utils.getProperty(this.document, 'system.description') ?? ''; - context.enrichedDescription = await TextEditor.enrichHTML(value, { - relativeTo: this.item, - rollData: this.item.getRollData(), - secrets: this.item.isOwner - }); + context.enrichedDescription = await this.document.system.getEnrichedDescription(true); break; case 'effects': await this._prepareEffectsContext(context, options); diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index e35fae46..8f8e87ac 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -54,6 +54,22 @@ export default class DHArmor extends AttachableItem { ); } + /**@inheritdoc */ + async getDescriptionData(large) { + const baseDescription = await super.getDescriptionData(); + const allFeatures = CONFIG.DH.ITEM.allArmorFeatures(); + const features = this.armorFeatures.map(x => allFeatures[x.value]); + if (!features.length) return baseDescription; + + const prepend = await foundry.applications.handlebars.renderTemplate( + 'systems/daggerheart/templates/sheets/items/armor/description.hbs', + { features, large } + ); + + const mainDescription = baseDescription ? `\n
\n${baseDescription}` : ''; + return `${prepend}${mainDescription}`; + } + /**@inheritdoc */ async _preUpdate(changes, options, user) { const allowed = await super._preUpdate(changes, options, user); diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 11be0a52..65760be7 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -8,7 +8,7 @@ * @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item */ -import { addLinkedItemsDiff, createScrollText, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs'; +import { addLinkedItemsDiff, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs'; import { ActionsField } from '../fields/actionField.mjs'; import FormulaField from '../fields/formulaField.mjs'; @@ -124,6 +124,23 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { return [source, page ? `pg ${page}.` : null].filter(x => x).join('. '); } + /** */ + async getDescriptionData() { + return this.description; + } + + /** */ + async getEnrichedDescription(large) { + if (!this.metadata.hasDescription) return ''; + + const description = await this.getDescriptionData(large); + return await foundry.applications.ux.TextEditor.implementation.enrichHTML(description, { + relativeTo: this, + rollData: this.getRollData(), + secrets: this.isOwner + }); + } + /** * Obtain a data object used to evaluate any dice rolls associated with this Item Type * @param {object} [options] - Options which modify the getRollData method. diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 295cc0c5..205fb02a 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -110,6 +110,22 @@ export default class DHWeapon extends AttachableItem { ); } + /**@inheritdoc */ + async getDescriptionData(large) { + const baseDescription = await super.getDescriptionData(); + const allFeatures = CONFIG.DH.ITEM.allWeaponFeatures(); + const features = this.weaponFeatures.map(x => allFeatures[x.value]); + if (!features.length) return baseDescription; + + const prepend = await foundry.applications.handlebars.renderTemplate( + 'systems/daggerheart/templates/sheets/items/weapon/description.hbs', + { features, large } + ); + + const mainDescription = baseDescription ? `\n
\n${baseDescription}` : ''; + return `${prepend}${mainDescription}`; + } + prepareDerivedData() { this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait; } diff --git a/styles/less/global/inventory-item.less b/styles/less/global/inventory-item.less index c8a29795..a17e2b35 100644 --- a/styles/less/global/inventory-item.less +++ b/styles/less/global/inventory-item.less @@ -211,6 +211,18 @@ ul { list-style: disc; } + + .feature-descriptions { + .features-header { + font-size: 14px; + font-weight: bold; + text-decoration: underline; + + &.large { + font-size: 18px; + } + } + } } } .item-resources { diff --git a/styles/less/sheets/items/item-sheet-shared.less b/styles/less/sheets/items/item-sheet-shared.less index d0a8cc48..54b9c8c2 100644 --- a/styles/less/sheets/items/item-sheet-shared.less +++ b/styles/less/sheets/items/item-sheet-shared.less @@ -10,4 +10,16 @@ font-family: @font-body; color: light-dark(@chat-blue-bg, @beige-50); } + + .feature-descriptions { + .features-header { + font-size: 14px; + font-weight: bold; + text-decoration: underline; + + &.large { + font-size: 18px; + } + } + } } diff --git a/templates/sheets/items/armor/description.hbs b/templates/sheets/items/armor/description.hbs new file mode 100644 index 00000000..efd5c1e5 --- /dev/null +++ b/templates/sheets/items/armor/description.hbs @@ -0,0 +1,6 @@ +
+
{{localize "DAGGERHEART.SETTINGS.Homebrew.itemFeatures"}}
+ {{#each features as | feature |}} +
{{localize feature.label}}: {{{localize feature.description}}}
+ {{/each}} +
\ No newline at end of file diff --git a/templates/sheets/items/weapon/description.hbs b/templates/sheets/items/weapon/description.hbs new file mode 100644 index 00000000..efd5c1e5 --- /dev/null +++ b/templates/sheets/items/weapon/description.hbs @@ -0,0 +1,6 @@ +
+
{{localize "DAGGERHEART.SETTINGS.Homebrew.itemFeatures"}}
+ {{#each features as | feature |}} +
{{localize feature.label}}: {{{localize feature.description}}}
+ {{/each}} +
\ No newline at end of file