import { EditorInitOptions, EditorLanguage, FableEditorApi } from './types';
export declare class FableEditor implements FableEditorApi {
private static instanceCounter;
private options;
private lang;
private contentClass;
private contentStyleEl;
private shell;
private menubar;
private toolbar;
private ed;
private statusbar;
private sbHelp;
private sbWords;
private imgInput;
private savedRange;
private foreColor;
private backColor;
private openPop;
/** Stack of currently-open flyout submenus, shallowest first (e.g. for
* Table > Cell > Cell background: [Cell flyout, Cell background flyout]).
* A single slot isn't enough past one level deep - opening a 2nd-level
* flyout would remove the 1st-level one still needed to bridge visually
* back to the top-level popup, leaving a gap. */
private subStack;
private popAnchor;
private dlgOvl;
private tblActive;
private tblCorner;
private tblColBars;
private tblCtx;
private tblCellMark;
private tblOpMark;
private tblOpMarkKind;
private imgActive;
private imgHandles;
private imgCtx;
private imgHideTimer;
private phActive;
private phCtx;
private phUploadTarget;
private imageUploadHandler?;
private onImageUploadError?;
private contentStyle?;
private vidInput;
private vidActive;
private vidCtx;
private vidHideTimer;
private vphActive;
private vphCtx;
private vphUploadTarget;
private videoUploadHandler?;
private onVideoUploadError?;
private selCtx;
private tbrMore;
private tbrExpanded;
private codeActive;
private codeCtx;
private tplActive;
private tplCtx;
private docInput;
private revisions;
private revTimer;
private draftTimer;
private draftStorageKey;
private listeners;
private isDestroyed;
constructor(options: EditorInitOptions);
private t;
private tArr;
private dir;
private initDOM;
/** Theme options land as CSS variables on the document root rather than the editor
* shell, because dialogs, popups and floating context toolbars are appended to
* document.body and would not inherit variables scoped to the shell. */
private applyTheme;
/** Rewrites the literal word `body` in a user-supplied `contentStyle` string to a
* selector scoped to this instance's content div. Everything else passes through
* verbatim, since `.ed` is a plain div in the host page (not an iframe) and an
* unscoped `body { ... }` rule would otherwise leak onto the host page's body. */
private scopeContentStyle;
private bindGrip;
private bindEvents;
private on;
private onDoc;
private onWin;
getContent(): string;
/** Same HTML as getContent(), wrapped so its RTL/LTR direction survives being
* dropped into a fixed-alignment host (e.g. an email template's
* `
`), which otherwise forces left alignment onto any
* descendant that has no `text-align` of its own — even one with its own
* dir="rtl". Elements that already carry their own dir (preserved as-is by
* the paste engine) each get their own matching text-align only if they
* don't already have one. Blocks with no reliable explicit dir (missing, or
* dir="auto" from plain-text paste) get their direction from a first-strong-
* character scan of their own text instead of silently inheriting the
* editor's configured UI language — mixed-direction content and any
* alignment the user explicitly set are left untouched either way. Only
* content with no strongly-directional character anywhere falls back to the
* editor's current direction. */
getContentForEmail(): string;
setContent(html: string): void;
insertContent(html: string): void;
setLanguage(lang: EditorLanguage): void;
focus(): void;
importWordFile(file: File | Blob): Promise;
restoreDraft(): boolean;
getRevisions(): Array<{
time: number;
html: string;
}>;
destroy(): void;
private saveSel;
private restoreSel;
private exec;
private closestBlock;
/** Enter on an empty last line inside a blockquote exits it into a plain paragraph, mirroring how lists exit on an empty item. */
private tryExitBlockquote;
private selectedBlocks;
private onChange;
private recordRevision;
private scheduleRevision;
private scheduleDraftSave;
private revisionDlg;
private closeSub;
/** Removes stacked flyouts from `level` (0 = shallowest) onward, keeping
* anything shallower - e.g. hovering a sibling item inside the "Cell"
* flyout should drop a deeper "Cell background" flyout but keep "Cell"
* itself and the top-level popup it bridges to. */
private closeSubFrom;
/** True if `node` is inside any currently-open flyout submenu (any depth). */
private subContains;
/** 0 for the top-level popup itself; otherwise this container's depth in
* the flyout stack + 1. Used to know how many deeper flyouts to close
* when opening or hovering within `container`. */
private subLevelOf;
private closePop;
private openSubFor;
private popup;
private menuItems;
private tbtn;
/** Font-size increase / decrease step button. */
private stepBtn;
/** Toolbar icon button that opens a popup menu anchored to itself. */
private menuTbtn;
/** Quick text-color chips plus a "more" chip that opens the full palette. */
private colorChips;
private group;
private tsel;
private setListStyle;
private listMenu;
/** Shared color-picker popup body — swatch grid plus the current-color /
* no-color / custom-picker footer — so the fore/back toolbar menus and the
* table cell-background menu all show the identical popup. */
private buildPaletteInto;
private colorMenu;
private applyColor;
private syncColorSwatches;
private fontItems;
private fontMenu;
private sizeItems;
private sizeMenu;
/** Font sizing needs a non-collapsed range. With a bare caret, grow the
selection to the word under it; in an empty spot, select a zero-width
space so the new size applies to what gets typed next. */
private ensureSizeTarget;
private applyFontSize;
private stepFontSize;
private transformCase;
private caseItems;
private caseMenu;
private applyBlockStyle;
private currentBlockStyle;
private blockStyleItems;
private lineHeightMenu;
private wordSpacingMenu;
private letterSpacingMenu;
private closestAnchor;
private linkDlg;
private blockItems;
private blocksMenu;
private alignItems;
private blockLabel;
private tableGrid;
private buildTableGridInto;
private insertTable;
private setDir;
/** Splits a toolbar layout string into groups of item names: `|` separates visual
* groups, whitespace separates items within a group. Empty groups/tokens (e.g. from
* leading/trailing/doubled separators) are dropped. Pure function. */
private parseToolbarString;
/** Maps every supported toolbar item name to a builder for that one control. Each
* entry is a direct lift of what used to be an inline call in `buildToolbar()` — no
* behavior changes, just named lookup. Only `forecolor` yields multiple elements
* (the quick color chips); everything else yields one. */
private buildToolbarRegistry;
private buildToolbar;
/** xs/sm/md editors (< 992px wide) collapse an overflowing toolbar to one row +
* "…" expander; at lg widths and up the toolbar wraps to multiple rows as before. */
private static readonly TBR_COLLAPSE_MAX;
/** Responsive one-line toolbar: on mobile/tablet widths (or a narrow host
* container) a toolbar that can't fit on a single row collapses to one
* clipped row plus a trailing "…" button that expands/collapses the full
* set. Driven by the editor's own width, so it also applies to narrow
* panels on desktop. */
private updateToolbarOverflow;
private mItem;
private buildMenubar;
private tableOp;
/** Reorders the current row/column: 'rowup'/'rowdown' swap the caret's row with
* its neighbour, 'colleft'/'colright' move the caret's column one position in
* DOM order across every row. The caret travels with the moved cell. */
private tableMove;
/** Align the whole table via auto margins — same semantics as the align
* field in the table-properties dialog. */
private alignTable;
/** Color grid applying a background to the caret's cell — the direct way to
* build header rows (the toolbar's backcolor highlights text, not cells). */
private buildCellFillInto;
/** style.backgroundColor reads back as rgb(...) — normalise to #rrggbb for the picker. */
private cssToHex;
private cellFillMenu;
private applyTableProps;
private tablePropsDlg;
private currentCell;
private toHexColor;
private formRow;
private formInput;
private formSelect;
private formBg;
private setOrClear;
private cellPropsDlg;
private rowPropsDlg;
private colPropsDlg;
private closeDlg;
private dialog;
private sourceDlg;
private helpDlg;
private wordCountDlg;
private previewDlg;
/** Two-pane picker shared by the special-character map and the emoji map:
* fixed category tabs on the left, the active category's glyphs on the right. */
private glyphPickerDlg;
private charMap;
private emojiMap;
private printDoc;
private pickImage;
private imgPhHTML;
private insertImagePlaceholder;
private clearImgPlaceholderSel;
private removeImgPlaceholder;
private selectImgPlaceholder;
private renderPhCtxButtons;
/** Swaps a template slot's placeholder between image and video kinds, so the
* same media slot can be filled with either. */
private swapPlaceholderKind;
private renderPhCtxUrlInput;
private readImageFileInto;
/** Runs the host-supplied imageUploadHandler instead of inlining base64,
* so apps can route the file to S3 / Azure Blob / their own server. */
private uploadImageFile;
private replacePlaceholderWithImage;
private positionImgPhCtx;
private pickVideo;
private vidPhHTML;
private insertVideoPlaceholder;
private clearVphPlaceholderSel;
private removeVphPlaceholder;
private selectVphPlaceholder;
private renderVphCtxButtons;
private renderVphCtxUrlInput;
private readVideoFileInto;
/** Runs the host-supplied videoUploadHandler instead of inlining base64,
* so apps can route the file to S3 / Azure Blob / their own server. */
private uploadVideoFile;
private replacePlaceholderWithVideo;
/** Swaps a video placeholder for a hosted player iframe (YouTube & co.). */
private replacePlaceholderWithEmbed;
private positionVphCtx;
private cancelVidHide;
private clearVidHandles;
private selectVideo;
private buildVideoCtxToolbar;
private setVideoAlign;
private positionVidCtx;
/** Maps a page URL from a known video host to its iframe player URL. Returns
* null for anything else (e.g. direct .mp4 file URLs). */
private videoEmbedUrl;
private videoEmbedHTML;
/** Insert/edit-video dialog with General (source/width/height), Embed (embed
* code) and Advanced (alternative source, poster image) tabs. Hosted page
* URLs (YouTube & co.) become iframe players; anything else becomes a
*