import { DeesElement, property, html, customElement, type TemplateResult, css, state, cssManager, unsafeCSS, domtools, } from '@design.estate/dees-element'; import * as interfaces from '../../ts/interfaces/index.js'; import * as plugins from '../plugins.js'; export const defaultDocumentSettings: interfaces.IDocumentSettings = { enableTopDraftText: true, enableDefaultHeader: true, enableDefaultFooter: true, }; import { DePage } from './page.js'; import { DeContentInvoice } from './contentinvoice.js'; import * as shared from '../../ts/shared/index.js'; import { demoFunc } from './document.demo.js'; declare global { interface HTMLElementTagNameMap { 'dedocument-dedocument': DeDocument; } } @customElement('dedocument-dedocument') export class DeDocument extends DeesElement { public static demo = demoFunc; @property({ type: String, reflect: true, }) public format: 'a4' = 'a4'; @property({ type: Number, reflect: true, }) public viewWidth: number = null; @property({ type: Number, reflect: true, }) public viewHeight: number = null; @property({ type: Boolean, reflect: true, }) printMode = false; @property({ type: Object, reflect: true, converter: (valueArg) => { if (typeof valueArg === 'string') { return plugins.smartjson.parseBase64(valueArg) } else { return valueArg; } }, }) public letterData: plugins.tsclass.business.ILetter; @property({ type: Object, reflect: true, converter: (valueArg) => { if (typeof valueArg === 'string') { return plugins.smartjson.parseBase64(valueArg) } else { return valueArg; } }, }) public documentSettings: interfaces.IDocumentSettings = defaultDocumentSettings; constructor() { super(); domtools.DomTools.setupDomTools(); } public static styles = [ domtools.elementBasic.staticStyles, css` :host { display: block; color: #333; padding: 0px; position: relative; } .betweenPagesSpacer { height: 16px; } `, ]; public render(): TemplateResult { return html`
`; } public async firstUpdated(_changedProperties: Map) { const resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) { const width = entry.contentRect.width; const height = entry.contentRect.height; // Handle the new dimensions here this.adjustDePageScaling(); } }); resizeObserver.observe(this); this.registerGarbageFunction(() => { resizeObserver.disconnect(); }) } public latestRenderedLetterData: plugins.tsclass.business.ILetter = null; public async renderDocument() { const domtools = await this.domtoolsPromise; const documentBuildContainer = document.createElement('div'); document.body.appendChild(documentBuildContainer); let pages: DePage[] = []; let pageCounter = 0; let complete = false; // lets append the content const content: DeContentInvoice = new DeContentInvoice(); content.letterData = this.letterData; document.body.appendChild(content); await domtools.convenience.smartdelay.delayFor(0); let overallContentOffset: number = 0; let currentContentOffset: number; let trimmed: number; while (!complete) { pageCounter++; const currentContent = content.cloneNode(true) as DeContentInvoice; const newPage = new DePage(); newPage.printMode = this.printMode; newPage.letterData = this.letterData; pages.push(newPage); newPage.pageNumber = pageCounter; newPage.append(currentContent); newPage.pageTotalNumber = pageCounter; documentBuildContainer.append(newPage); await currentContent.elementDomReady; await currentContent.trimStartToOffset(overallContentOffset); let newPageOverflows = await newPage.checkOverflow(); trimmed = 0; while (newPageOverflows) { await currentContent.trimEndByOne(); trimmed++; newPageOverflows = await newPage.checkOverflow(); } currentContentOffset = await currentContent.getContentLength(); overallContentOffset = overallContentOffset + currentContentOffset; if (trimmed === 0) { complete = true; } // complete = true; console.log(currentContentOffset); } document.body.removeChild(content); document.body.removeChild(documentBuildContainer); const documentContainer = this.shadowRoot.querySelector('.documentContainer'); if (documentContainer) { const children = Array.from(documentContainer.children); children.forEach((child) => documentContainer.removeChild(child)); } for (const page of pages) { page.pageTotalNumber = pageCounter; documentContainer.append(page); // betweenPagesSpacer if (!this.printMode) { const betweenPagesSpacerDiv = document.createElement('div'); betweenPagesSpacerDiv.classList.add('betweenPagesSpacer'); documentContainer.appendChild(betweenPagesSpacerDiv); } } this.adjustDePageScaling(); this.latestRenderedLetterData = this.letterData; } async updated(changedProperties: Map): Promise { super.updated(changedProperties); const domtools = await this.domtoolsPromise; const renderedDocIsUpToDate = domtools.convenience.smartjson.deepEqualObjects(this.letterData, this.latestRenderedLetterData); if (!renderedDocIsUpToDate) { this.renderDocument(); } if (changedProperties.has('viewHeight') || changedProperties.has('viewWidth')) { this.adjustDePageScaling(); } } private adjustDePageScaling() { if (this.printMode) { return; } this.viewWidth = this.clientWidth; // Find all DePage instances within this DeDocument const pages = this.shadowRoot.querySelectorAll('dedocument-page'); // Update each DePage instance's viewHeight and viewWidth pages.forEach((page: DePage) => { if (this.viewHeight) { page.viewHeight = this.viewHeight; } if (this.viewWidth) { page.viewWidth = this.viewWidth; console.log('setting viewWidth: ', this.viewWidth); } }); } }