@jackuait/blok 0.7.3 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-BmlbETK7.mjs → blok-Ddy2vDUq.mjs} +2158 -2147
- package/dist/chunks/{constants-WhLyFkza.mjs → constants-CuG2mgIj.mjs} +84 -84
- package/dist/chunks/{i18next-loader-CZARkla1.mjs → i18next-loader-p-7ioTwr.mjs} +1 -1
- package/dist/chunks/{lightweight-i18n-BQa0F2X6.mjs → lightweight-i18n-BPeH69Dl.mjs} +5 -1
- package/dist/{messages-BbLCMWln2.mjs → chunks/messages--aM83pib2.mjs} +14 -1
- package/dist/chunks/{messages-ni0ahgYk2.mjs → messages-4OvVdaG52.mjs} +14 -1
- package/dist/chunks/{messages-DnPkoMz1.mjs → messages-5ohIWynJ.mjs} +14 -1
- package/dist/{messages-CzSLUJQt.mjs → chunks/messages-5thhSeME.mjs} +14 -1
- package/dist/chunks/{messages-hngFJrES2.mjs → messages-8pf7gRQm2.mjs} +14 -1
- package/dist/chunks/{messages-DcPtg90i.mjs → messages-B-i-d1Bc.mjs} +14 -1
- package/dist/chunks/{messages-CRxkRJRN.mjs → messages-B9zocutJ.mjs} +14 -1
- package/dist/chunks/{messages-BUy3odZo.mjs → messages-BAC7nLeM.mjs} +14 -1
- package/dist/chunks/{messages-DjOY_EqX.mjs → messages-BARPMN7R.mjs} +14 -1
- package/dist/{messages-Bsz7Qgj_.mjs → chunks/messages-BAgTIgPH.mjs} +15 -2
- package/dist/{messages-C7R0m6oE2.mjs → chunks/messages-BDTgiBJY2.mjs} +14 -1
- package/dist/chunks/{messages-BM1Su_Uy2.mjs → messages-BHf_VcXb2.mjs} +14 -1
- package/dist/{messages-wRvz0vQ3.mjs → chunks/messages-BIrkzbBP.mjs} +14 -1
- package/dist/chunks/{messages-DotEkUpQ.mjs → messages-BKjLgO5d.mjs} +14 -1
- package/dist/{messages-gldjQk7M.mjs → chunks/messages-BMzmli1K.mjs} +14 -1
- package/dist/chunks/{messages-CficsmSH2.mjs → messages-BO_jtRbZ2.mjs} +14 -1
- package/dist/{messages-B2bHgIcC2.mjs → chunks/messages-B_fFjpX12.mjs} +14 -1
- package/dist/chunks/{messages-CnzaTbel.mjs → messages-Bdk5tBNu.mjs} +14 -1
- package/dist/{messages-CRMZ79Xf.mjs → chunks/messages-BgaGPFuy2.mjs} +14 -1
- package/dist/{messages-DCOKudVN.mjs → chunks/messages-BsYzg2le.mjs} +14 -1
- package/dist/chunks/{messages-Dxrg70jo.mjs → messages-BtS6JWMT.mjs} +14 -1
- package/dist/{messages-Cgy54529.mjs → chunks/messages-BvlSf_pu.mjs} +14 -1
- package/dist/{messages-oH0ADQ362.mjs → chunks/messages-C03I_oR-2.mjs} +14 -1
- package/dist/chunks/{messages-B_nVGWdk.mjs → messages-CDJLoStb.mjs} +14 -1
- package/dist/chunks/{messages-ClOxDE0y2.mjs → messages-CH_cexo62.mjs} +14 -1
- package/dist/chunks/{messages-DoDbCS02.mjs → messages-CIBuZccC.mjs} +14 -1
- package/dist/{messages-CkmVEyEQ2.mjs → chunks/messages-CIZkNCpW.mjs} +14 -1
- package/dist/{messages-CJYE0_hr2.mjs → chunks/messages-CIugNDDO2.mjs} +14 -1
- package/dist/{messages-DpY9s4Qi2.mjs → chunks/messages-COkQfKa72.mjs} +14 -1
- package/dist/{messages-Bw-GC0m5.mjs → chunks/messages-CSpfBhlK2.mjs} +14 -1
- package/dist/chunks/{messages-tBHnC2Rj2.mjs → messages-CWp6-Y8f2.mjs} +14 -1
- package/dist/{messages-GrVSCmXW.mjs → chunks/messages-Co4WFeQ8.mjs} +14 -1
- package/dist/{messages-voUPclMU.mjs → chunks/messages-CoRQE_Jc.mjs} +14 -1
- package/dist/{messages-DGZQXeav2.mjs → chunks/messages-CuRN1_ep2.mjs} +14 -1
- package/dist/{messages-BwdowdYD.mjs → chunks/messages-D0IKicWg.mjs} +14 -1
- package/dist/chunks/{messages-1C3OS98e.mjs → messages-D14soBOO.mjs} +14 -1
- package/dist/chunks/{messages-nE9Ko73n2.mjs → messages-D1SqLcxI2.mjs} +14 -1
- package/dist/{messages-COU4L-pL2.mjs → chunks/messages-D2uBlGXR2.mjs} +14 -1
- package/dist/{messages-m1uf_AMy2.mjs → chunks/messages-DDpgr0B1.mjs} +14 -1
- package/dist/{messages-CB0RKGVM.mjs → chunks/messages-DEGzGmEQ2.mjs} +14 -1
- package/dist/{messages--XEfVx572.mjs → chunks/messages-DKChC8Qu.mjs} +14 -1
- package/dist/{messages-BP8ZuVaD.mjs → chunks/messages-DKCoHa5D.mjs} +14 -1
- package/dist/chunks/{messages-C3AJz_i6.mjs → messages-DPoPrTiZ.mjs} +14 -1
- package/dist/{messages-CaJRIGUu2.mjs → chunks/messages-DQOk-dTH.mjs} +14 -1
- package/dist/chunks/{messages-uLIUXFmU.mjs → messages-DUp8NnKT.mjs} +15 -2
- package/dist/chunks/{messages-rJdSnvyi.mjs → messages-DVg69mRj.mjs} +14 -1
- package/dist/chunks/{messages-Cq6wj6FG.mjs → messages-DeLzropc.mjs} +14 -1
- package/dist/{messages-BlnZ8CkJ2.mjs → chunks/messages-Df69rfTF2.mjs} +15 -2
- package/dist/{messages-BZgGD0zf2.mjs → chunks/messages-DfsHFEWa.mjs} +14 -1
- package/dist/chunks/{messages-yJmwc3zD.mjs → messages-DgZnRQRS.mjs} +14 -1
- package/dist/chunks/{messages-m6bLP64R2.mjs → messages-DhGHk-Ma2.mjs} +14 -1
- package/dist/{messages-3aRjZXpv.mjs → chunks/messages-Di7mfvB8.mjs} +14 -1
- package/dist/chunks/{messages-C1iQkKu82.mjs → messages-DlM9TmqS2.mjs} +14 -1
- package/dist/chunks/{messages-CejEH4FW2.mjs → messages-DmrsEYQm2.mjs} +14 -1
- package/dist/chunks/{messages-DK6pBwD2.mjs → messages-Dr-Ig3sw.mjs} +14 -1
- package/dist/{messages-BOxe7ewT.mjs → chunks/messages-DrXNb1gu.mjs} +14 -1
- package/dist/chunks/{messages-CvLXClh9.mjs → messages-EDTq4Q52.mjs} +14 -1
- package/dist/{messages-huTzItxA.mjs → chunks/messages-Ehx9YYeb2.mjs} +14 -1
- package/dist/chunks/{messages-CxTq0x772.mjs → messages-FCmAVA792.mjs} +14 -1
- package/dist/{messages-q7HzQPVt.mjs → chunks/messages-LL3Tflph.mjs} +14 -1
- package/dist/chunks/{messages-D9qyilS0.mjs → messages-N72K1hw3.mjs} +14 -1
- package/dist/chunks/{messages-C9XSSqS5.mjs → messages-Nz8C7Znm.mjs} +15 -2
- package/dist/chunks/{messages-D6SAC8Lc2.mjs → messages-OIelQDL32.mjs} +14 -1
- package/dist/{messages-BQJzUYP-.mjs → chunks/messages-SsrFJhTN.mjs} +14 -1
- package/dist/{messages-CVBsztOg.mjs → chunks/messages-ohtcmr1w.mjs} +14 -1
- package/dist/chunks/{messages-CVzvKl6U.mjs → messages-stUQR58d.mjs} +14 -1
- package/dist/{messages-DlrZrm3s.mjs → chunks/messages-wUoSWFsJ2.mjs} +14 -1
- package/dist/chunks/{tools-BCb5bMO3.mjs → tools-F4UyWgGo.mjs} +1086 -802
- package/dist/full.mjs +15 -13
- package/dist/locales.mjs +72 -68
- package/dist/{messages-mVFAkdcY.mjs → messages-1_FCq0It.mjs} +14 -1
- package/dist/{messages-DkkrjINb2.mjs → messages-8zo-T-Nx2.mjs} +14 -1
- package/dist/{chunks/messages-DacahKek.mjs → messages-B21zLG6b.mjs} +14 -1
- package/dist/{messages-BBgyeB_N.mjs → messages-B9ythxux.mjs} +14 -1
- package/dist/{messages-C_RPN2GV.mjs → messages-BAZK-8Zb.mjs} +14 -1
- package/dist/{messages-D6Sr5cUE.mjs → messages-BB8umWL1.mjs} +14 -1
- package/dist/{chunks/messages-Dhe8_mnQ.mjs → messages-BD_U2EnE.mjs} +14 -1
- package/dist/{messages-6G0Eia-2.mjs → messages-BRC9E_sp.mjs} +14 -1
- package/dist/{messages-pgqtPci-.mjs → messages-BSLYh59S.mjs} +14 -1
- package/dist/{messages-K7ROT6ea.mjs → messages-BSwhWcYw.mjs} +14 -1
- package/dist/{messages-BztXgybv2.mjs → messages-BTR3QlIb2.mjs} +14 -1
- package/dist/{messages-C0gyqo4h2.mjs → messages-BZXBdD_S2.mjs} +14 -1
- package/dist/{chunks/messages-DDRCk44J2.mjs → messages-Bm8I_Li12.mjs} +15 -2
- package/dist/{chunks/messages-BKtWlK39.mjs → messages-BrcgNZOJ.mjs} +14 -1
- package/dist/{messages-Be1CCcsp2.mjs → messages-BzZ8LahA2.mjs} +14 -1
- package/dist/{chunks/messages-B_90PYaG.mjs → messages-C4HpNHfK.mjs} +14 -1
- package/dist/{messages-B8M4YRFO2.mjs → messages-C5hD5pSd2.mjs} +14 -1
- package/dist/{messages-ruU_e2LK.mjs → messages-C7Rz00Tp.mjs} +14 -1
- package/dist/{chunks/messages-C1lqY56F2.mjs → messages-C92tAUYT2.mjs} +14 -1
- package/dist/{messages-Kye1BINC.mjs → messages-C9LsEUfG.mjs} +14 -1
- package/dist/{chunks/messages-tg78NAmW.mjs → messages-CHWfj4ik.mjs} +14 -1
- package/dist/{chunks/messages-DziA-L3p.mjs → messages-CHeucLGl2.mjs} +14 -1
- package/dist/{messages-eCyczLYY.mjs → messages-CIxT1nSh.mjs} +14 -1
- package/dist/{chunks/messages-Cb-x47kY2.mjs → messages-CKX9iXIb2.mjs} +14 -1
- package/dist/{chunks/messages-BjkDJuqh.mjs → messages-CKmmJ9tW.mjs} +14 -1
- package/dist/{chunks/messages-Cn5n0nHe2.mjs → messages-CTFwu5-h2.mjs} +14 -1
- package/dist/{messages-DAssrN5L2.mjs → messages-CTPFrtK92.mjs} +14 -1
- package/dist/{chunks/messages-6EJxSImH.mjs → messages-CWzET_9H2.mjs} +14 -1
- package/dist/{chunks/messages-BZ45xBlV.mjs → messages-CkIRmpfZ2.mjs} +14 -1
- package/dist/{chunks/messages-kHTrX3wo2.mjs → messages-CmoTIebG2.mjs} +14 -1
- package/dist/{messages-DZbsds_k2.mjs → messages-Co26RSCV2.mjs} +14 -1
- package/dist/{messages-DrouoDgp.mjs → messages-CqNzlpWi.mjs} +15 -2
- package/dist/{chunks/messages-DDr8J4FE.mjs → messages-CrWsU4Xw2.mjs} +14 -1
- package/dist/{messages-TseLyyoU.mjs → messages-CsmTziC6.mjs} +14 -1
- package/dist/{messages-CAffVeAE2.mjs → messages-CsnglxbV2.mjs} +14 -1
- package/dist/{messages-CE305J0p.mjs → messages-Cu7Lr1wp.mjs} +14 -1
- package/dist/{chunks/messages-Ul43l29K2.mjs → messages-Cy3Ne_M9.mjs} +14 -1
- package/dist/{chunks/messages-CzCqu58X2.mjs → messages-CzZAfGif.mjs} +14 -1
- package/dist/{messages-C_4VGaBC.mjs → messages-D5rnT-BC.mjs} +14 -1
- package/dist/{messages-MaHxNgKA.mjs → messages-D8iCBMg7.mjs} +14 -1
- package/dist/{chunks/messages-BtNOlsMj.mjs → messages-DDJOu049.mjs} +14 -1
- package/dist/{messages-BU9luYgO.mjs → messages-DDiP6yex.mjs} +14 -1
- package/dist/{messages-DB9U3VIh.mjs → messages-DHJ1fZLL.mjs} +14 -1
- package/dist/{chunks/messages-3ePgbbpx2.mjs → messages-DToWAonn2.mjs} +14 -1
- package/dist/{messages-BxQ1gzJF2.mjs → messages-DV29fJMD2.mjs} +14 -1
- package/dist/{chunks/messages-DJWRON2S.mjs → messages-D_-rh8gl.mjs} +14 -1
- package/dist/{messages-e-KHuxtY2.mjs → messages-D_cAZ4Ic2.mjs} +14 -1
- package/dist/{chunks/messages-pKUiAqlX2.mjs → messages-Dc7ZzqYN.mjs} +14 -1
- package/dist/{chunks/messages-JRavIeeW.mjs → messages-DiSeSE8p.mjs} +14 -1
- package/dist/{chunks/messages-DbS9Oibb.mjs → messages-Djhu5RJd.mjs} +14 -1
- package/dist/{messages-BdJ1lCo_.mjs → messages-Dr9L1psl.mjs} +15 -2
- package/dist/{chunks/messages-IJhiftj5.mjs → messages-EIeWKoc5.mjs} +14 -1
- package/dist/{chunks/messages-CteKp81J.mjs → messages-EwoT2jof.mjs} +14 -1
- package/dist/{messages-C8iAUPzI.mjs → messages-F7cRf-20.mjs} +14 -1
- package/dist/{messages-B9qltgXa.mjs → messages-JZhs_0pf.mjs} +14 -1
- package/dist/{chunks/messages-C232njMF2.mjs → messages-JwMkLben.mjs} +14 -1
- package/dist/{messages-Cb5JJ8C_2.mjs → messages-LyzjEEIj2.mjs} +14 -1
- package/dist/{chunks/messages-DQ4VyVJf2.mjs → messages-SepwOOcg.mjs} +14 -1
- package/dist/{chunks/messages-DfTU2I8J.mjs → messages-TI0u6Ked.mjs} +14 -1
- package/dist/{chunks/messages-D7aoKTPD.mjs → messages-Tx25QErT.mjs} +14 -1
- package/dist/{chunks/messages-D9nReG4C2.mjs → messages-bRqMCja-2.mjs} +14 -1
- package/dist/{chunks/messages-h474TGR72.mjs → messages-lEyiemqU2.mjs} +14 -1
- package/dist/{messages-BENRci-_2.mjs → messages-mVLfVtQX2.mjs} +14 -1
- package/dist/{messages-CEhkWwqI.mjs → messages-ouO9js8Z.mjs} +14 -1
- package/dist/{chunks/messages-6z-ULVyk.mjs → messages-ouRGTAKo2.mjs} +14 -1
- package/dist/{chunks/messages-DNrK8lCg2.mjs → messages-qV14y_oA2.mjs} +14 -1
- package/dist/{chunks/messages-Yk__PXZQ.mjs → messages-rM6YFLZH.mjs} +15 -2
- package/dist/react.mjs +2 -2
- package/dist/tools.mjs +3 -3
- package/package.json +1 -1
- package/src/components/i18n/locales/am/messages.json +14 -1
- package/src/components/i18n/locales/ar/messages.json +14 -1
- package/src/components/i18n/locales/az/messages.json +14 -1
- package/src/components/i18n/locales/bg/messages.json +15 -2
- package/src/components/i18n/locales/bn/messages.json +14 -1
- package/src/components/i18n/locales/bs/messages.json +14 -1
- package/src/components/i18n/locales/cs/messages.json +14 -1
- package/src/components/i18n/locales/da/messages.json +14 -1
- package/src/components/i18n/locales/de/messages.json +14 -1
- package/src/components/i18n/locales/dv/messages.json +14 -1
- package/src/components/i18n/locales/el/messages.json +14 -1
- package/src/components/i18n/locales/en/messages.json +5 -1
- package/src/components/i18n/locales/es/messages.json +14 -1
- package/src/components/i18n/locales/et/messages.json +15 -2
- package/src/components/i18n/locales/fa/messages.json +14 -1
- package/src/components/i18n/locales/fi/messages.json +14 -1
- package/src/components/i18n/locales/fil/messages.json +14 -1
- package/src/components/i18n/locales/fr/messages.json +14 -1
- package/src/components/i18n/locales/gu/messages.json +14 -1
- package/src/components/i18n/locales/he/messages.json +14 -1
- package/src/components/i18n/locales/hi/messages.json +14 -1
- package/src/components/i18n/locales/hr/messages.json +14 -1
- package/src/components/i18n/locales/hu/messages.json +14 -1
- package/src/components/i18n/locales/hy/messages.json +14 -1
- package/src/components/i18n/locales/id/messages.json +14 -1
- package/src/components/i18n/locales/it/messages.json +14 -1
- package/src/components/i18n/locales/ja/messages.json +14 -1
- package/src/components/i18n/locales/ka/messages.json +14 -1
- package/src/components/i18n/locales/km/messages.json +14 -1
- package/src/components/i18n/locales/kn/messages.json +14 -1
- package/src/components/i18n/locales/ko/messages.json +14 -1
- package/src/components/i18n/locales/ku/messages.json +14 -1
- package/src/components/i18n/locales/lo/messages.json +14 -1
- package/src/components/i18n/locales/lt/messages.json +14 -1
- package/src/components/i18n/locales/lv/messages.json +14 -1
- package/src/components/i18n/locales/mk/messages.json +14 -1
- package/src/components/i18n/locales/ml/messages.json +14 -1
- package/src/components/i18n/locales/mn/messages.json +14 -1
- package/src/components/i18n/locales/mr/messages.json +14 -1
- package/src/components/i18n/locales/ms/messages.json +14 -1
- package/src/components/i18n/locales/my/messages.json +14 -1
- package/src/components/i18n/locales/ne/messages.json +14 -1
- package/src/components/i18n/locales/nl/messages.json +14 -1
- package/src/components/i18n/locales/no/messages.json +14 -1
- package/src/components/i18n/locales/pa/messages.json +14 -1
- package/src/components/i18n/locales/pl/messages.json +14 -1
- package/src/components/i18n/locales/ps/messages.json +14 -1
- package/src/components/i18n/locales/pt/messages.json +14 -1
- package/src/components/i18n/locales/ro/messages.json +14 -1
- package/src/components/i18n/locales/ru/messages.json +15 -2
- package/src/components/i18n/locales/sd/messages.json +14 -1
- package/src/components/i18n/locales/si/messages.json +14 -1
- package/src/components/i18n/locales/sk/messages.json +14 -1
- package/src/components/i18n/locales/sl/messages.json +14 -1
- package/src/components/i18n/locales/sq/messages.json +14 -1
- package/src/components/i18n/locales/sr/messages.json +14 -1
- package/src/components/i18n/locales/sv/messages.json +14 -1
- package/src/components/i18n/locales/sw/messages.json +14 -1
- package/src/components/i18n/locales/ta/messages.json +14 -1
- package/src/components/i18n/locales/te/messages.json +14 -1
- package/src/components/i18n/locales/th/messages.json +14 -1
- package/src/components/i18n/locales/tr/messages.json +14 -1
- package/src/components/i18n/locales/ug/messages.json +14 -1
- package/src/components/i18n/locales/uk/messages.json +15 -2
- package/src/components/i18n/locales/ur/messages.json +14 -1
- package/src/components/i18n/locales/vi/messages.json +14 -1
- package/src/components/i18n/locales/yi/messages.json +14 -1
- package/src/components/i18n/locales/zh/messages.json +14 -1
- package/src/components/icons/index.ts +18 -0
- package/src/components/inline-tools/inline-tool-strikethrough.ts +408 -0
- package/src/components/inline-tools/inline-tool-underline.ts +408 -0
- package/src/components/modules/paste/handlers/base.ts +14 -4
- package/src/components/modules/rectangleSelection.ts +48 -0
- package/src/components/modules/toolbar/index.ts +5 -2
- package/src/components/modules/toolbar/inline/shortcuts-manager.ts +4 -3
- package/src/components/shared/color-picker.ts +10 -2
- package/src/full.ts +7 -1
- package/src/stories/MarkerColors.stories.ts +13 -34
- package/src/styles/main.css +1 -1
- package/src/tools/header/index.ts +6 -4
- package/src/tools/index.ts +4 -0
- package/src/tools/list/constants.ts +3 -3
- package/src/tools/list/dom-builder.ts +1 -0
- package/src/tools/table/table-cell-blocks.ts +25 -0
- package/src/tools/toggle/constants.ts +12 -5
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import type { InlineTool, SanitizerConfig } from '../../../types';
|
|
2
|
+
import type { MenuConfig } from '../../../types/tools';
|
|
3
|
+
import { IconUnderline } from '../icons';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
isRangeFormatted,
|
|
7
|
+
findFormattingAncestor,
|
|
8
|
+
hasFormattingAncestor,
|
|
9
|
+
collectFormattingAncestors,
|
|
10
|
+
} from './utils/formatting-range-utils';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Check if an element is an underline tag (<u>)
|
|
14
|
+
* @param element - The element to check
|
|
15
|
+
*/
|
|
16
|
+
const isUnderlineTag = (element: Element): boolean => {
|
|
17
|
+
return element.tagName === 'U';
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Underline Tool
|
|
22
|
+
*
|
|
23
|
+
* Inline Toolbar Tool
|
|
24
|
+
*
|
|
25
|
+
* Style selected text with underline
|
|
26
|
+
*/
|
|
27
|
+
export class UnderlineInlineTool implements InlineTool {
|
|
28
|
+
/**
|
|
29
|
+
* Specifies Tool as Inline Toolbar Tool
|
|
30
|
+
* @returns {boolean}
|
|
31
|
+
*/
|
|
32
|
+
public static isInline = true;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Title for the Inline Tool
|
|
36
|
+
*/
|
|
37
|
+
public static title = 'Underline';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Translation key for i18n
|
|
41
|
+
*/
|
|
42
|
+
public static titleKey = 'underline';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Sanitizer Rule
|
|
46
|
+
* Leave <u> tags
|
|
47
|
+
* @returns {object}
|
|
48
|
+
*/
|
|
49
|
+
public static get sanitize(): SanitizerConfig {
|
|
50
|
+
return {
|
|
51
|
+
u: {},
|
|
52
|
+
} as SanitizerConfig;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create button for Inline Toolbar
|
|
57
|
+
*/
|
|
58
|
+
public render(): MenuConfig {
|
|
59
|
+
return {
|
|
60
|
+
icon: IconUnderline,
|
|
61
|
+
name: 'underline',
|
|
62
|
+
onActivate: () => {
|
|
63
|
+
this.toggleUnderline();
|
|
64
|
+
},
|
|
65
|
+
isActive: () => {
|
|
66
|
+
const selection = window.getSelection();
|
|
67
|
+
|
|
68
|
+
return selection ? this.isSelectionVisuallyUnderline(selection) : false;
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Shortcut for underline tool
|
|
75
|
+
*/
|
|
76
|
+
public static shortcut = 'CMD+U';
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Apply or remove underline formatting using modern Selection API
|
|
80
|
+
*/
|
|
81
|
+
private toggleUnderline(): void {
|
|
82
|
+
const selection = window.getSelection();
|
|
83
|
+
|
|
84
|
+
if (!selection || selection.rangeCount === 0) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const range = selection.getRangeAt(0);
|
|
89
|
+
|
|
90
|
+
if (range.collapsed) {
|
|
91
|
+
this.toggleCollapsedUnderline(range, selection);
|
|
92
|
+
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const shouldUnwrap = this.isRangeUnderline(range, { ignoreWhitespace: true });
|
|
97
|
+
|
|
98
|
+
if (shouldUnwrap) {
|
|
99
|
+
this.unwrapUnderlineTags(range);
|
|
100
|
+
} else {
|
|
101
|
+
this.wrapWithUnderline(range);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Handle toggle for collapsed selection (caret)
|
|
107
|
+
* @param range - Current range
|
|
108
|
+
* @param selection - Current selection
|
|
109
|
+
*/
|
|
110
|
+
private toggleCollapsedUnderline(range: Range, selection: Selection): void {
|
|
111
|
+
const isUnderline = this.isRangeUnderline(range, { ignoreWhitespace: true });
|
|
112
|
+
|
|
113
|
+
if (isUnderline) {
|
|
114
|
+
const textNode = document.createTextNode('\u200B');
|
|
115
|
+
|
|
116
|
+
range.insertNode(textNode);
|
|
117
|
+
range.selectNode(textNode);
|
|
118
|
+
this.unwrapUnderlineTags(range);
|
|
119
|
+
|
|
120
|
+
const newRange = document.createRange();
|
|
121
|
+
|
|
122
|
+
newRange.setStart(textNode, 1);
|
|
123
|
+
newRange.setEnd(textNode, 1);
|
|
124
|
+
|
|
125
|
+
selection.removeAllRanges();
|
|
126
|
+
selection.addRange(newRange);
|
|
127
|
+
} else {
|
|
128
|
+
const u = document.createElement('u');
|
|
129
|
+
const textNode = document.createTextNode('\u200B');
|
|
130
|
+
|
|
131
|
+
u.appendChild(textNode);
|
|
132
|
+
range.insertNode(u);
|
|
133
|
+
|
|
134
|
+
const newRange = document.createRange();
|
|
135
|
+
|
|
136
|
+
newRange.setStart(textNode, 1);
|
|
137
|
+
newRange.setEnd(textNode, 1);
|
|
138
|
+
|
|
139
|
+
selection.removeAllRanges();
|
|
140
|
+
selection.addRange(newRange);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Check if current selection is within an underline tag
|
|
146
|
+
* @param selection - The Selection object to check
|
|
147
|
+
*/
|
|
148
|
+
private isSelectionVisuallyUnderline(selection: Selection): boolean {
|
|
149
|
+
if (selection.rangeCount === 0) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const range = selection.getRangeAt(0);
|
|
154
|
+
|
|
155
|
+
return this.isRangeUnderline(range, { ignoreWhitespace: true });
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Check if a range contains underline text
|
|
160
|
+
* @param range - The range to check
|
|
161
|
+
* @param options - Options for checking underline status
|
|
162
|
+
*/
|
|
163
|
+
private isRangeUnderline(range: Range, options: { ignoreWhitespace: boolean }): boolean {
|
|
164
|
+
return isRangeFormatted(range, isUnderlineTag, options);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Wrap selection with <u> tag
|
|
169
|
+
* @param range - The Range object containing the selection to wrap
|
|
170
|
+
*/
|
|
171
|
+
private wrapWithUnderline(range: Range): void {
|
|
172
|
+
const html = this.getRangeHtmlWithoutUnderline(range);
|
|
173
|
+
const insertedRange = this.replaceRangeWithHtml(range, `<u>${html}</u>`);
|
|
174
|
+
const selection = window.getSelection();
|
|
175
|
+
|
|
176
|
+
if (selection && insertedRange) {
|
|
177
|
+
selection.removeAllRanges();
|
|
178
|
+
selection.addRange(insertedRange);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Remove underline tags (<u>) while preserving content
|
|
184
|
+
* @param range - The Range object containing the selection to unwrap
|
|
185
|
+
*/
|
|
186
|
+
private unwrapUnderlineTags(range: Range): void {
|
|
187
|
+
const underlineAncestors = this.collectUnderlineAncestors(range);
|
|
188
|
+
const selection = window.getSelection();
|
|
189
|
+
|
|
190
|
+
if (!selection) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const marker = document.createElement('span');
|
|
195
|
+
const fragment = range.extractContents();
|
|
196
|
+
|
|
197
|
+
marker.appendChild(fragment);
|
|
198
|
+
this.removeNestedUnderline(marker);
|
|
199
|
+
|
|
200
|
+
range.insertNode(marker);
|
|
201
|
+
|
|
202
|
+
const markerRange = document.createRange();
|
|
203
|
+
|
|
204
|
+
markerRange.selectNodeContents(marker);
|
|
205
|
+
selection.removeAllRanges();
|
|
206
|
+
selection.addRange(markerRange);
|
|
207
|
+
|
|
208
|
+
for (; ;) {
|
|
209
|
+
const currentUnderline = this.findUnderlineElement(marker);
|
|
210
|
+
|
|
211
|
+
if (!currentUnderline) {
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
this.moveMarkerOutOfUnderline(marker, currentUnderline);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const firstChild = marker.firstChild;
|
|
219
|
+
const lastChild = marker.lastChild;
|
|
220
|
+
|
|
221
|
+
this.unwrapElement(marker);
|
|
222
|
+
|
|
223
|
+
const finalRange = firstChild && lastChild ? (() => {
|
|
224
|
+
const newRange = document.createRange();
|
|
225
|
+
|
|
226
|
+
newRange.setStartBefore(firstChild);
|
|
227
|
+
newRange.setEndAfter(lastChild);
|
|
228
|
+
|
|
229
|
+
selection.removeAllRanges();
|
|
230
|
+
selection.addRange(newRange);
|
|
231
|
+
|
|
232
|
+
return newRange;
|
|
233
|
+
})() : undefined;
|
|
234
|
+
|
|
235
|
+
if (!finalRange) {
|
|
236
|
+
selection.removeAllRanges();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
underlineAncestors.forEach((element) => {
|
|
240
|
+
if (element.textContent.length === 0) {
|
|
241
|
+
element.remove();
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Check if a node or any of its parents is an underline tag
|
|
248
|
+
* @param node - The node to check
|
|
249
|
+
*/
|
|
250
|
+
private hasUnderlineParent(node: Node | null): boolean {
|
|
251
|
+
return hasFormattingAncestor(node, isUnderlineTag);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Find an underline element in the parent chain
|
|
256
|
+
* @param node - The node to start searching from
|
|
257
|
+
*/
|
|
258
|
+
private findUnderlineElement(node: Node | null): HTMLElement | null {
|
|
259
|
+
return findFormattingAncestor(node, isUnderlineTag);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Collect all underline ancestor elements within a range
|
|
264
|
+
* @param range - The range to search for underline ancestors
|
|
265
|
+
*/
|
|
266
|
+
private collectUnderlineAncestors(range: Range): HTMLElement[] {
|
|
267
|
+
return collectFormattingAncestors(range, isUnderlineTag);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Get HTML content of a range with underline tags removed
|
|
272
|
+
* @param range - The range to extract HTML from
|
|
273
|
+
*/
|
|
274
|
+
private getRangeHtmlWithoutUnderline(range: Range): string {
|
|
275
|
+
const contents = range.cloneContents();
|
|
276
|
+
|
|
277
|
+
this.removeNestedUnderline(contents);
|
|
278
|
+
|
|
279
|
+
const container = document.createElement('div');
|
|
280
|
+
|
|
281
|
+
container.appendChild(contents);
|
|
282
|
+
|
|
283
|
+
return container.innerHTML;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Remove nested underline tags from a root node
|
|
288
|
+
* @param root - The root node to process
|
|
289
|
+
*/
|
|
290
|
+
private removeNestedUnderline(root: ParentNode): void {
|
|
291
|
+
const underlineNodes = root.querySelectorAll('u');
|
|
292
|
+
|
|
293
|
+
underlineNodes.forEach((node) => {
|
|
294
|
+
this.unwrapElement(node);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Unwrap an element by moving its children to the parent
|
|
300
|
+
* @param element - The element to unwrap
|
|
301
|
+
*/
|
|
302
|
+
private unwrapElement(element: Element): void {
|
|
303
|
+
const parent = element.parentNode;
|
|
304
|
+
|
|
305
|
+
if (!parent) {
|
|
306
|
+
element.remove();
|
|
307
|
+
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
while (element.firstChild) {
|
|
312
|
+
parent.insertBefore(element.firstChild, element);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
parent.removeChild(element);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Replace the current range contents with provided HTML snippet
|
|
320
|
+
* @param range - Range to replace
|
|
321
|
+
* @param html - HTML string to insert
|
|
322
|
+
*/
|
|
323
|
+
private replaceRangeWithHtml(range: Range, html: string): Range | undefined {
|
|
324
|
+
const fragment = this.createFragmentFromHtml(html);
|
|
325
|
+
const firstInserted = fragment.firstChild ?? null;
|
|
326
|
+
const lastInserted = fragment.lastChild ?? null;
|
|
327
|
+
|
|
328
|
+
range.deleteContents();
|
|
329
|
+
|
|
330
|
+
if (!firstInserted || !lastInserted) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
range.insertNode(fragment);
|
|
335
|
+
|
|
336
|
+
const newRange = document.createRange();
|
|
337
|
+
|
|
338
|
+
newRange.setStartBefore(firstInserted);
|
|
339
|
+
newRange.setEndAfter(lastInserted);
|
|
340
|
+
|
|
341
|
+
return newRange;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Convert an HTML snippet to a document fragment
|
|
346
|
+
* @param html - HTML string to convert
|
|
347
|
+
*/
|
|
348
|
+
private createFragmentFromHtml(html: string): DocumentFragment {
|
|
349
|
+
const template = document.createElement('template');
|
|
350
|
+
|
|
351
|
+
template.innerHTML = html;
|
|
352
|
+
|
|
353
|
+
return template.content;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Move a temporary marker element outside of an underline ancestor while preserving content order
|
|
358
|
+
* @param marker - Marker element wrapping the selection contents
|
|
359
|
+
* @param underlineElement - Underline ancestor containing the marker
|
|
360
|
+
*/
|
|
361
|
+
private moveMarkerOutOfUnderline(marker: HTMLElement, underlineElement: HTMLElement): void {
|
|
362
|
+
const parent = underlineElement.parentNode;
|
|
363
|
+
|
|
364
|
+
if (!parent) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Remove empty text nodes to ensure accurate child count
|
|
369
|
+
Array.from(underlineElement.childNodes).forEach((node) => {
|
|
370
|
+
if (node.nodeType === Node.TEXT_NODE && (node.textContent ?? '').length === 0) {
|
|
371
|
+
node.remove();
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
const isOnlyChild = underlineElement.childNodes.length === 1 && underlineElement.firstChild === marker;
|
|
376
|
+
|
|
377
|
+
if (isOnlyChild) {
|
|
378
|
+
underlineElement.replaceWith(marker);
|
|
379
|
+
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const isFirstChild = underlineElement.firstChild === marker;
|
|
384
|
+
|
|
385
|
+
if (isFirstChild) {
|
|
386
|
+
parent.insertBefore(marker, underlineElement);
|
|
387
|
+
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const isLastChild = underlineElement.lastChild === marker;
|
|
392
|
+
|
|
393
|
+
if (isLastChild) {
|
|
394
|
+
parent.insertBefore(marker, underlineElement.nextSibling);
|
|
395
|
+
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const trailingClone = underlineElement.cloneNode(false) as HTMLElement;
|
|
400
|
+
|
|
401
|
+
while (marker.nextSibling) {
|
|
402
|
+
trailingClone.appendChild(marker.nextSibling);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
parent.insertBefore(trailingClone, underlineElement.nextSibling);
|
|
406
|
+
parent.insertBefore(marker, trailingClone);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
@@ -115,6 +115,13 @@ export abstract class BasePasteHandler implements PasteHandler {
|
|
|
115
115
|
if (isMultipleItems) {
|
|
116
116
|
this.redirectToTableParentIfNeeded(data, BlockManager);
|
|
117
117
|
|
|
118
|
+
const currentBlock = BlockManager.currentBlock;
|
|
119
|
+
const childContainer = currentBlock?.holder?.querySelector('[data-blok-toggle-children]') ?? null;
|
|
120
|
+
const isInContainerTitle = childContainer !== null &&
|
|
121
|
+
!childContainer.contains(currentBlock?.currentInput ?? null);
|
|
122
|
+
const contextParentId = isInContainerTitle
|
|
123
|
+
? (currentBlock?.id ?? null)
|
|
124
|
+
: (currentBlock?.parentId ?? null);
|
|
118
125
|
const insertedByIndex: Array<Awaited<ReturnType<BlokModules['BlockManager']['paste']>>> = [];
|
|
119
126
|
|
|
120
127
|
for (const [index, pasteData] of data.entries()) {
|
|
@@ -136,7 +143,7 @@ export abstract class BasePasteHandler implements PasteHandler {
|
|
|
136
143
|
Caret.setToBlock(block, Caret.positions.END);
|
|
137
144
|
insertedByIndex.push(block);
|
|
138
145
|
|
|
139
|
-
this.applyPastedBlockParent(block, pasteData, insertedByIndex, BlockManager);
|
|
146
|
+
this.applyPastedBlockParent(block, pasteData, insertedByIndex, BlockManager, contextParentId);
|
|
140
147
|
}
|
|
141
148
|
|
|
142
149
|
BlockManager.currentBlock && Caret.setToBlock(BlockManager.currentBlock, Caret.positions.END);
|
|
@@ -163,7 +170,8 @@ export abstract class BasePasteHandler implements PasteHandler {
|
|
|
163
170
|
block: Awaited<ReturnType<BlokModules['BlockManager']['paste']>>,
|
|
164
171
|
pasteData: PasteData,
|
|
165
172
|
insertedByIndex: Array<Awaited<ReturnType<BlokModules['BlockManager']['paste']>>>,
|
|
166
|
-
BlockManager: BlokModules['BlockManager']
|
|
173
|
+
BlockManager: BlokModules['BlockManager'],
|
|
174
|
+
contextParentId: string | null
|
|
167
175
|
): void {
|
|
168
176
|
if (pasteData.parentPasteIndex !== undefined) {
|
|
169
177
|
const parentBlock = insertedByIndex[pasteData.parentPasteIndex];
|
|
@@ -171,9 +179,11 @@ export abstract class BasePasteHandler implements PasteHandler {
|
|
|
171
179
|
if (parentBlock) {
|
|
172
180
|
BlockManager.setBlockParent(block, parentBlock.id);
|
|
173
181
|
}
|
|
182
|
+
} else if (contextParentId !== null) {
|
|
183
|
+
// Container-title paste context: assign all flat blocks to the container
|
|
184
|
+
BlockManager.setBlockParent(block, contextParentId);
|
|
174
185
|
} else if (block.parentId != null) {
|
|
175
|
-
// Root-level
|
|
176
|
-
// the predecessor (e.g. the previous child block that had a parent).
|
|
186
|
+
// Root-level paste context: clear any parent inherited from predecessor
|
|
177
187
|
BlockManager.setBlockParent(block, null);
|
|
178
188
|
}
|
|
179
189
|
}
|
|
@@ -65,6 +65,13 @@ export class RectangleSelection extends Module {
|
|
|
65
65
|
*/
|
|
66
66
|
private mousedown = false;
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Set when mousedown starts from a contentEditable element that is within the
|
|
70
|
+
* editor's horizontal content bounds. Prevents the toolbar from re-opening via
|
|
71
|
+
* the BlockHovered event while the user is dragging. Cleared on mouseup.
|
|
72
|
+
*/
|
|
73
|
+
private mouseDownWithinBoundsFromContentEditable = false;
|
|
74
|
+
|
|
68
75
|
/**
|
|
69
76
|
* Is scrolling now
|
|
70
77
|
*/
|
|
@@ -213,6 +220,7 @@ export class RectangleSelection extends Module {
|
|
|
213
220
|
*/
|
|
214
221
|
public endSelection(): void {
|
|
215
222
|
this.mousedown = false;
|
|
223
|
+
this.mouseDownWithinBoundsFromContentEditable = false;
|
|
216
224
|
this.startX = 0;
|
|
217
225
|
this.startY = 0;
|
|
218
226
|
this.anchorBlockIndex = null;
|
|
@@ -229,6 +237,18 @@ export class RectangleSelection extends Module {
|
|
|
229
237
|
return this.isRectSelectionActivated || this.mousedown;
|
|
230
238
|
}
|
|
231
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Returns true when the user pressed down a mouse button within the editor's horizontal
|
|
242
|
+
* content bounds, even if the click originated on a contentEditable element (in which
|
|
243
|
+
* case rubber-band selection is not started but the toolbar is still closed).
|
|
244
|
+
*
|
|
245
|
+
* Used by the Toolbar module to suppress toolbar reopening while the user is dragging
|
|
246
|
+
* inside the editor content area.
|
|
247
|
+
*/
|
|
248
|
+
public get isMouseDownWithinBounds(): boolean {
|
|
249
|
+
return this.mouseDownWithinBoundsFromContentEditable;
|
|
250
|
+
}
|
|
251
|
+
|
|
232
252
|
/**
|
|
233
253
|
* Mark that selection is end
|
|
234
254
|
*/
|
|
@@ -305,6 +325,24 @@ export class RectangleSelection extends Module {
|
|
|
305
325
|
|
|
306
326
|
if (!startedFromContentEditable) {
|
|
307
327
|
this.startSelection(mouseEvent.pageX, mouseEvent.pageY, mouseEvent.shiftKey);
|
|
328
|
+
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* When dragging starts from a contentEditable element, track whether the
|
|
334
|
+
* pointer is within the editor's horizontal content bounds.
|
|
335
|
+
* On the first subsequent mousemove (i.e. when the user actually drags rather
|
|
336
|
+
* than just clicking), the toolbar will be closed and hover-based reopening
|
|
337
|
+
* will be suppressed while the mouse button is held.
|
|
338
|
+
*/
|
|
339
|
+
const scrollLeft = this.getScrollLeft();
|
|
340
|
+
const pointerX = mouseEvent.pageX - scrollLeft;
|
|
341
|
+
const contentRect = this.Blok.UI.contentRect;
|
|
342
|
+
const withinEditorHorizontally = pointerX >= contentRect.left && pointerX <= contentRect.right;
|
|
343
|
+
|
|
344
|
+
if (withinEditorHorizontally) {
|
|
345
|
+
this.mouseDownWithinBoundsFromContentEditable = true;
|
|
308
346
|
}
|
|
309
347
|
}
|
|
310
348
|
|
|
@@ -313,6 +351,16 @@ export class RectangleSelection extends Module {
|
|
|
313
351
|
* @param {MouseEvent} mouseEvent - mouse event payload
|
|
314
352
|
*/
|
|
315
353
|
private processMouseMove(mouseEvent: MouseEvent): void {
|
|
354
|
+
/**
|
|
355
|
+
* When the user clicked inside a contentEditable element within the editor's
|
|
356
|
+
* horizontal bounds and is now dragging, close the toolbar on the first move.
|
|
357
|
+
* We defer this to mousemove (rather than mousedown) so that a plain click
|
|
358
|
+
* does not accidentally close the toolbar.
|
|
359
|
+
*/
|
|
360
|
+
if (this.mouseDownWithinBoundsFromContentEditable) {
|
|
361
|
+
this.Blok.Toolbar.close();
|
|
362
|
+
}
|
|
363
|
+
|
|
316
364
|
this.changingRectangle(mouseEvent);
|
|
317
365
|
this.scrollByZones(mouseEvent.clientY);
|
|
318
366
|
}
|
|
@@ -1009,9 +1009,12 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
1009
1009
|
*/
|
|
1010
1010
|
this.eventsDispatcher.on(BlockHovered, (data) => {
|
|
1011
1011
|
/**
|
|
1012
|
-
* Do not move toolbar during drag
|
|
1012
|
+
* Do not move toolbar during drag, rectangle selection, or when the user
|
|
1013
|
+
* started a mouse-drag from within the editor's content area (even if the
|
|
1014
|
+
* drag originated on a contentEditable element, i.e. rubber-band is not
|
|
1015
|
+
* activated but the toolbar was closed and should stay closed).
|
|
1013
1016
|
*/
|
|
1014
|
-
if (this.Blok.DragManager.isDragging || this.Blok.RectangleSelection.isRectActivated()) {
|
|
1017
|
+
if (this.Blok.DragManager.isDragging || this.Blok.RectangleSelection.isRectActivated() || this.Blok.RectangleSelection.isMouseDownWithinBounds) {
|
|
1015
1018
|
return;
|
|
1016
1019
|
}
|
|
1017
1020
|
|
|
@@ -172,13 +172,14 @@ export class InlineShortcutManager {
|
|
|
172
172
|
name: shortcut,
|
|
173
173
|
handler: (event) => {
|
|
174
174
|
const { BlockManager } = this.getBlok();
|
|
175
|
-
const
|
|
175
|
+
const block = BlockManager.currentBlock
|
|
176
|
+
?? BlockManager.getBlockByChildNode(window.getSelection()?.anchorNode as Node);
|
|
176
177
|
|
|
177
|
-
if (!
|
|
178
|
+
if (!block) {
|
|
178
179
|
return;
|
|
179
180
|
}
|
|
180
181
|
|
|
181
|
-
if (
|
|
182
|
+
if (block.tool.enabledInlineTools === false) {
|
|
182
183
|
return;
|
|
183
184
|
}
|
|
184
185
|
|
|
@@ -165,7 +165,11 @@ export function createColorPicker(options: ColorPickerOptions): ColorPickerHandl
|
|
|
165
165
|
defaultSwatch.addEventListener('click', () => {
|
|
166
166
|
onColorSelect(null, mode.key);
|
|
167
167
|
});
|
|
168
|
-
|
|
168
|
+
const defaultLabel = i18n.t('tools.colorPicker.defaultSwatchLabel')
|
|
169
|
+
.replace('{default}', i18n.t('tools.marker.default'))
|
|
170
|
+
.replace('{mode}', i18n.t(mode.labelKey).toLowerCase());
|
|
171
|
+
|
|
172
|
+
onHover(defaultSwatch, defaultLabel.charAt(0).toUpperCase() + defaultLabel.slice(1), { placement: 'top' });
|
|
169
173
|
grid.appendChild(defaultSwatch);
|
|
170
174
|
|
|
171
175
|
for (const preset of presets) {
|
|
@@ -193,7 +197,11 @@ export function createColorPicker(options: ColorPickerOptions): ColorPickerHandl
|
|
|
193
197
|
swatch.addEventListener('click', () => {
|
|
194
198
|
onColorSelect(swatchColor, mode.key);
|
|
195
199
|
});
|
|
196
|
-
|
|
200
|
+
const colorLabel = i18n.t('tools.colorPicker.colorSwatchLabel')
|
|
201
|
+
.replace('{color}', i18n.t('tools.colorPicker.color.' + preset.name))
|
|
202
|
+
.replace('{mode}', i18n.t(mode.labelKey).toLowerCase());
|
|
203
|
+
|
|
204
|
+
onHover(swatch, colorLabel.charAt(0).toUpperCase() + colorLabel.slice(1), { placement: 'top' });
|
|
197
205
|
grid.appendChild(swatch);
|
|
198
206
|
}
|
|
199
207
|
};
|
package/src/full.ts
CHANGED
|
@@ -19,6 +19,8 @@ import { BoldInlineTool as Bold } from './components/inline-tools/inline-tool-bo
|
|
|
19
19
|
import { ItalicInlineTool as Italic } from './components/inline-tools/inline-tool-italic';
|
|
20
20
|
import { LinkInlineTool as Link } from './components/inline-tools/inline-tool-link';
|
|
21
21
|
import { MarkerInlineTool as Marker } from './components/inline-tools/inline-tool-marker';
|
|
22
|
+
import { UnderlineInlineTool as Underline } from './components/inline-tools/inline-tool-underline';
|
|
23
|
+
import { StrikethroughInlineTool as Strikethrough } from './components/inline-tools/inline-tool-strikethrough';
|
|
22
24
|
import { Header } from './tools/header';
|
|
23
25
|
import { ListItem as List } from './tools/list';
|
|
24
26
|
import { Paragraph } from './tools/paragraph';
|
|
@@ -35,6 +37,8 @@ export {
|
|
|
35
37
|
Italic,
|
|
36
38
|
Link,
|
|
37
39
|
Marker,
|
|
40
|
+
Underline,
|
|
41
|
+
Strikethrough,
|
|
38
42
|
defaultBlockTools,
|
|
39
43
|
defaultInlineTools,
|
|
40
44
|
} from './tools';
|
|
@@ -68,6 +72,8 @@ export const allTools = {
|
|
|
68
72
|
...defaultTools,
|
|
69
73
|
bold: { class: Bold },
|
|
70
74
|
italic: { class: Italic },
|
|
71
|
-
link: { class: Link },
|
|
72
75
|
marker: { class: Marker },
|
|
76
|
+
underline: { class: Underline },
|
|
77
|
+
strikethrough: { class: Strikethrough },
|
|
78
|
+
link: { class: Link },
|
|
73
79
|
} as const;
|