magic-editor-x 1.2.2 → 1.3.0

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.
@@ -7,10 +7,10 @@ const admin = require("@strapi/strapi/admin");
7
7
  const styled = require("styled-components");
8
8
  const outline = require("@heroicons/react/24/outline");
9
9
  const EditorJS = require("@editorjs/editorjs");
10
- const getTranslation = require("./getTranslation-DxG1pB5q.js");
11
- const tools = require("./tools-Dn4jPdJs.js");
12
- const index = require("./index-C_SiBh7v.js");
13
- const LicensePage = require("./LicensePage-VwKQMnUO.js");
10
+ const getTranslation = require("./getTranslation-DB9tlKh9.js");
11
+ const tools = require("./tools-3bMqs3Or.js");
12
+ const index = require("./index-DO-QpiC9.js");
13
+ const LicensePage = require("./LicensePage-BIaCAB4C.js");
14
14
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
15
15
  const styled__default = /* @__PURE__ */ _interopDefault(styled);
16
16
  const EditorJS__default = /* @__PURE__ */ _interopDefault(EditorJS);
@@ -5,10 +5,10 @@ import { useFetchClient, useNotification, Page } from "@strapi/strapi/admin";
5
5
  import styled, { css, keyframes } from "styled-components";
6
6
  import { HashtagIcon, DocumentTextIcon, ListBulletIcon, CheckIcon, ChatBubbleBottomCenterTextIcon, CodeBracketIcon, PhotoIcon, TableCellsIcon, LinkIcon, ExclamationTriangleIcon, PaperClipIcon, BellAlertIcon, SparklesIcon, BeakerIcon, PlayCircleIcon, ArrowPathIcon, EyeIcon, DocumentDuplicateIcon, ChevronRightIcon, CubeTransparentIcon, Cog6ToothIcon, UserGroupIcon, BookOpenIcon, CommandLineIcon, UserPlusIcon, TrashIcon, CheckCircleIcon, XMarkIcon, KeyIcon } from "@heroicons/react/24/outline";
7
7
  import EditorJS from "@editorjs/editorjs";
8
- import { u as useIntl, g as getTranslation, L as Loader, a as Box, T as Typography, F as Flex, c as TextInput, B as Button$2 } from "./getTranslation-ChB_HlBd.mjs";
9
- import { g as getTools } from "./tools-BAvbiUHr.mjs";
10
- import { P as PLUGIN_ID } from "./index-CtyxDZ0S.mjs";
11
- import LicensePage from "./LicensePage-oxUnaZmr.mjs";
8
+ import { u as useIntl, g as getTranslation, L as Loader, a as Box, T as Typography, F as Flex, c as TextInput, B as Button$2 } from "./getTranslation-CZ77ytJY.mjs";
9
+ import { g as getTools } from "./tools-CNqrBm-q.mjs";
10
+ import { P as PLUGIN_ID } from "./index-BNxjfrVK.mjs";
11
+ import LicensePage from "./LicensePage-Cj6-z6rO.mjs";
12
12
  const fadeInUp = keyframes`
13
13
  from { opacity: 0; transform: translateY(20px); }
14
14
  to { opacity: 1; transform: translateY(0); }
@@ -3,9 +3,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
5
  const admin = require("@strapi/strapi/admin");
6
- const getTranslation = require("./getTranslation-DxG1pB5q.js");
6
+ const getTranslation = require("./getTranslation-DB9tlKh9.js");
7
7
  const styled = require("styled-components");
8
- const index = require("./index-C_SiBh7v.js");
8
+ const index = require("./index-DO-QpiC9.js");
9
9
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
10
10
  const styled__default = /* @__PURE__ */ _interopDefault(styled);
11
11
  const Container = styled__default.default(getTranslation.Box)`
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useState, useEffect } from "react";
3
3
  import { useFetchClient, useNotification } from "@strapi/strapi/admin";
4
- import { u as useIntl, F as Flex, L as Loader, T as Typography, d as Badge, a as Box, g as getTranslation, B as Button } from "./getTranslation-ChB_HlBd.mjs";
4
+ import { u as useIntl, F as Flex, L as Loader, T as Typography, d as Badge, a as Box, g as getTranslation, B as Button } from "./getTranslation-CZ77ytJY.mjs";
5
5
  import styled from "styled-components";
6
- import { F as ForwardRef$2o, a as ForwardRef$26, b as ForwardRef$o, c as ForwardRef$1g, d as ForwardRef$y } from "./index-CtyxDZ0S.mjs";
6
+ import { F as ForwardRef$2o, a as ForwardRef$26, b as ForwardRef$o, c as ForwardRef$1g, d as ForwardRef$y } from "./index-BNxjfrVK.mjs";
7
7
  const Container = styled(Box)`
8
8
  padding: 32px;
9
9
  max-width: 1400px;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
- const getTranslation = require("./getTranslation-DxG1pB5q.js");
5
+ const getTranslation = require("./getTranslation-DB9tlKh9.js");
6
6
  const styled = require("styled-components");
7
7
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
8
8
  const styled__default = /* @__PURE__ */ _interopDefault(styled);
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useState, useEffect, useMemo } from "react";
3
- import { u as useIntl, F as Flex, g as getTranslation } from "./getTranslation-ChB_HlBd.mjs";
3
+ import { u as useIntl, F as Flex, g as getTranslation } from "./getTranslation-CZ77ytJY.mjs";
4
4
  import styled, { css, keyframes } from "styled-components";
5
5
  const pulse = keyframes`
6
6
  0%, 100% {
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
- const getTranslation = require("./getTranslation-DxG1pB5q.js");
5
+ const getTranslation = require("./getTranslation-DB9tlKh9.js");
6
6
  const admin = require("@strapi/strapi/admin");
7
7
  const outline = require("@heroicons/react/24/outline");
8
8
  const styled = require("styled-components");
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { useState, useEffect } from "react";
3
- import { u as useIntl, L as Loader, a as Box, A as Alert, F as Flex, T as Typography, B as Button, d as Badge, e as Accordion, g as getTranslation } from "./getTranslation-ChB_HlBd.mjs";
3
+ import { u as useIntl, L as Loader, a as Box, A as Alert, F as Flex, T as Typography, B as Button, d as Badge, e as Accordion, g as getTranslation } from "./getTranslation-CZ77ytJY.mjs";
4
4
  import { useFetchClient, useNotification } from "@strapi/strapi/admin";
5
5
  import { ArrowPathIcon, DocumentDuplicateIcon, ArrowDownTrayIcon, UserIcon, UsersIcon, ShieldCheckIcon, SparklesIcon, ChartBarIcon } from "@heroicons/react/24/outline";
6
6
  import styled, { css, keyframes } from "styled-components";
@@ -4,7 +4,7 @@ import { styled, css, keyframes, createGlobalStyle, useTheme } from "styled-comp
4
4
  import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
5
5
  import * as ReactDOM from "react-dom";
6
6
  import ReactDOM__default, { flushSync, createPortal } from "react-dom";
7
- import { a as ForwardRef$26, e as ForwardRef$2n, f as ForwardRef$2, g as ForwardRef$1l, h as ForwardRef$1b, i as ForwardRef$2v, j as ForwardRef$1U, k as ForwardRef$2j, l as ForwardRef$12, m as ForwardRef$2k, n as ForwardRef$2x, o as ForwardRef$2h, p as ForwardRef$v, P as PLUGIN_ID } from "./index-CtyxDZ0S.mjs";
7
+ import { a as ForwardRef$26, e as ForwardRef$2n, f as ForwardRef$2, g as ForwardRef$1l, h as ForwardRef$1b, i as ForwardRef$2v, j as ForwardRef$1U, k as ForwardRef$2j, l as ForwardRef$12, m as ForwardRef$2k, n as ForwardRef$2x, o as ForwardRef$2h, p as ForwardRef$v, P as PLUGIN_ID } from "./index-BNxjfrVK.mjs";
8
8
  var __assign = function() {
9
9
  __assign = Object.assign || function __assign2(t2) {
10
10
  for (var s, i = 1, n = arguments.length; i < n; i++) {
@@ -3,7 +3,7 @@ const React = require("react");
3
3
  const styled = require("styled-components");
4
4
  const jsxRuntime = require("react/jsx-runtime");
5
5
  const ReactDOM = require("react-dom");
6
- const index$1 = require("./index-C_SiBh7v.js");
6
+ const index$1 = require("./index-DO-QpiC9.js");
7
7
  function _interopNamespace(e) {
8
8
  if (e && e.__esModule) return e;
9
9
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -2383,7 +2383,7 @@ const index = {
2383
2383
  icon: PluginIcon,
2384
2384
  // Input component for Content Manager
2385
2385
  components: {
2386
- Input: async () => import("./index-IYdGq7Rl.mjs").then((module) => ({
2386
+ Input: async () => import("./index-Byp_IaHi.mjs").then((module) => ({
2387
2387
  default: module.default
2388
2388
  }))
2389
2389
  },
@@ -2445,7 +2445,7 @@ const index = {
2445
2445
  defaultMessage: "Magic Editor X"
2446
2446
  },
2447
2447
  // Use lazy import without async wrapper to avoid deprecation warning
2448
- Component: () => import("./App-LgFoHtyD.mjs"),
2448
+ Component: () => import("./App-Czke2os9.mjs"),
2449
2449
  permissions: []
2450
2450
  });
2451
2451
  app.createSettingSection(
@@ -2464,7 +2464,7 @@ const index = {
2464
2464
  id: "upgrade",
2465
2465
  // relative path (no leading slash)
2466
2466
  to: `${PLUGIN_ID}/upgrade`,
2467
- Component: () => import("./LicensePage-oxUnaZmr.mjs")
2467
+ Component: () => import("./LicensePage-Cj6-z6rO.mjs")
2468
2468
  },
2469
2469
  {
2470
2470
  intlLabel: {
@@ -2474,7 +2474,7 @@ const index = {
2474
2474
  id: "license",
2475
2475
  // relative path (no leading slash)
2476
2476
  to: `${PLUGIN_ID}/license`,
2477
- Component: () => import("./Settings-BI9zxX3k.mjs")
2477
+ Component: () => import("./Settings-CsaF0hO7.mjs")
2478
2478
  }
2479
2479
  ]
2480
2480
  );
@@ -2484,7 +2484,7 @@ const index = {
2484
2484
  * Bootstrap the plugin
2485
2485
  */
2486
2486
  async bootstrap(app) {
2487
- const { default: LiveCollaborationPanel } = await import("./LiveCollaborationPanel-elejZRkh.mjs");
2487
+ const { default: LiveCollaborationPanel } = await import("./LiveCollaborationPanel-D11eAcKk.mjs");
2488
2488
  try {
2489
2489
  const contentManagerPlugin = app.getPlugin("content-manager");
2490
2490
  if (contentManagerPlugin && contentManagerPlugin.apis) {
@@ -2,13 +2,13 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
- const getTranslation = require("./getTranslation-DxG1pB5q.js");
5
+ const getTranslation = require("./getTranslation-DB9tlKh9.js");
6
6
  const styled = require("styled-components");
7
7
  const outline = require("@heroicons/react/24/outline");
8
8
  const EditorJS = require("@editorjs/editorjs");
9
- const tools = require("./tools-Dn4jPdJs.js");
9
+ const tools = require("./tools-3bMqs3Or.js");
10
10
  const admin = require("@strapi/strapi/admin");
11
- const index = require("./index-C_SiBh7v.js");
11
+ const index = require("./index-DO-QpiC9.js");
12
12
  const socket_ioClient = require("socket.io-client");
13
13
  const Y = require("yjs");
14
14
  const yIndexeddb = require("y-indexeddb");
@@ -2136,19 +2136,118 @@ const FullscreenGlobalStyle = styled.createGlobalStyle`
2136
2136
  }
2137
2137
  `;
2138
2138
  const EditorJSGlobalStyles = styled.createGlobalStyle`
2139
- /* Popover rendered at document body */
2140
- body > .ce-popover,
2141
- body > .ce-popover--opened,
2142
- body > .ce-popover__container,
2143
- body > .ce-settings,
2144
- body > .ce-conversion-toolbar,
2145
- body > .ce-inline-toolbar {
2139
+ /* ============================================
2140
+ INLINE TOOLBAR - EditorJS 2.31
2141
+ Structure: .ce-inline-toolbar > .ce-popover--inline > .ce-popover__items > .ce-popover-item-html > .ce-inline-tool
2142
+ ============================================ */
2143
+
2144
+ /* Hide "Nothing found" message when inline tools ARE present */
2145
+ .ce-popover--inline .ce-popover__nothing-found-message {
2146
+ display: none !important;
2147
+ }
2148
+
2149
+ /* Inline Toolbar Popover - horizontal layout for tool buttons */
2150
+ .ce-popover--inline.ce-popover--opened {
2151
+ display: block !important;
2152
+ opacity: 1 !important;
2153
+ visibility: visible !important;
2146
2154
  z-index: 99999 !important;
2155
+ background: white !important;
2156
+ border: 1px solid #e2e8f0 !important;
2157
+ border-radius: 8px !important;
2158
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12) !important;
2159
+ padding: 4px !important;
2147
2160
  }
2148
2161
 
2149
- /* Ensure popovers are visible above Strapi modals */
2150
- .ce-popover,
2151
- .ce-popover--opened {
2162
+ .ce-popover--inline .ce-popover__container {
2163
+ display: block !important;
2164
+ }
2165
+
2166
+ /* Items container - HORIZONTAL layout for inline tools */
2167
+ .ce-popover--inline .ce-popover__items {
2168
+ display: flex !important;
2169
+ flex-direction: row !important;
2170
+ flex-wrap: wrap !important;
2171
+ align-items: center !important;
2172
+ gap: 2px !important;
2173
+ opacity: 1 !important;
2174
+ visibility: visible !important;
2175
+ }
2176
+
2177
+ /* Custom HTML wrapper for inline tools */
2178
+ .ce-popover--inline .ce-popover-item-html {
2179
+ display: flex !important;
2180
+ opacity: 1 !important;
2181
+ visibility: visible !important;
2182
+ }
2183
+
2184
+ /* The actual inline tool buttons (Bold, Italic, etc.) */
2185
+ .ce-popover--inline .ce-inline-tool {
2186
+ display: flex !important;
2187
+ align-items: center !important;
2188
+ justify-content: center !important;
2189
+ width: 32px !important;
2190
+ height: 32px !important;
2191
+ opacity: 1 !important;
2192
+ visibility: visible !important;
2193
+ background: transparent !important;
2194
+ border: none !important;
2195
+ border-radius: 6px !important;
2196
+ cursor: pointer !important;
2197
+ color: #64748b !important;
2198
+ transition: background 0.15s ease, color 0.15s ease !important;
2199
+ }
2200
+
2201
+ .ce-popover--inline .ce-inline-tool:hover {
2202
+ background: #f1f5f9 !important;
2203
+ color: #334155 !important;
2204
+ }
2205
+
2206
+ .ce-popover--inline .ce-inline-tool--active {
2207
+ background: #ede9fe !important;
2208
+ color: #7C3AED !important;
2209
+ }
2210
+
2211
+ .ce-popover--inline .ce-inline-tool svg {
2212
+ width: 18px !important;
2213
+ height: 18px !important;
2214
+ }
2215
+
2216
+ /* Convert-to button (block type changer) */
2217
+ .ce-popover--inline .ce-popover-item[data-item-name="convert-to"] {
2218
+ display: flex !important;
2219
+ align-items: center !important;
2220
+ padding: 4px 8px !important;
2221
+ border-radius: 6px !important;
2222
+ cursor: pointer !important;
2223
+ }
2224
+
2225
+ .ce-popover--inline .ce-popover-item[data-item-name="convert-to"]:hover {
2226
+ background: #f1f5f9 !important;
2227
+ }
2228
+
2229
+ /* Separator line between convert-to and inline tools */
2230
+ .ce-popover--inline .ce-popover-item-separator {
2231
+ width: 1px !important;
2232
+ height: 24px !important;
2233
+ background: #e2e8f0 !important;
2234
+ margin: 0 4px !important;
2235
+ }
2236
+
2237
+ .ce-popover--inline .ce-popover-item-separator__line {
2238
+ display: none !important;
2239
+ }
2240
+
2241
+ /* ============================================
2242
+ GLOBAL Z-INDEX FOR ALL EDITOR POPOVERS
2243
+ ============================================ */
2244
+
2245
+ body > .ce-popover,
2246
+ body > .ce-inline-toolbar,
2247
+ .ce-popover--opened,
2248
+ .ce-inline-toolbar,
2249
+ .ce-settings,
2250
+ .ce-conversion-toolbar {
2152
2251
  z-index: 99999 !important;
2153
2252
  }
2154
2253
 
@@ -2954,19 +3053,29 @@ const EditorWrapper = styled__default.default.div`
2954
3053
  TOOLBAR INSIDE EDITOR - Position Fix
2955
3054
  ============================================ */
2956
3055
 
2957
- /* Centered content area */
3056
+ /* Content area - full container width */
2958
3057
  .codex-editor__redactor {
2959
3058
  padding-bottom: 100px !important;
2960
3059
  padding-left: 0 !important;
2961
- margin: 0 auto !important;
2962
- max-width: 800px !important;
3060
+ padding-right: 0 !important;
3061
+ margin: 0 !important;
3062
+ max-width: 100% !important;
3063
+ width: 100% !important;
2963
3064
  }
2964
3065
 
2965
- /* Content blocks - centered */
3066
+ /* Content blocks - full width, no centering */
2966
3067
  .ce-block__content {
2967
- max-width: 100%;
2968
- margin: 0 auto;
2969
- padding: 0 16px;
3068
+ max-width: 100% !important;
3069
+ margin: 0 !important;
3070
+ padding: 0 16px !important;
3071
+ }
3072
+
3073
+ /* Paragraph and other editable elements - full width */
3074
+ .ce-paragraph,
3075
+ .ce-header,
3076
+ .cdx-block {
3077
+ max-width: 100% !important;
3078
+ width: 100% !important;
2970
3079
  }
2971
3080
 
2972
3081
  /* ============================================
@@ -3015,18 +3124,20 @@ const EditorWrapper = styled__default.default.div`
3015
3124
  border-radius: 6px;
3016
3125
  }
3017
3126
 
3018
- /* Toolbar positioning - centered with content */
3127
+ /* Toolbar positioning - full width */
3019
3128
  .ce-toolbar__content {
3020
- max-width: 800px;
3021
- margin: 0 auto;
3022
- padding: 0 16px;
3129
+ max-width: 100% !important;
3130
+ margin: 0 !important;
3131
+ padding: 0 16px !important;
3023
3132
  }
3024
3133
 
3025
3134
  .ce-toolbar {
3026
- left: 50% !important;
3027
- transform: translateX(-50%) !important;
3135
+ left: 0 !important;
3136
+ right: 0 !important;
3137
+ transform: none !important;
3028
3138
  width: 100% !important;
3029
- max-width: 832px !important;
3139
+ max-width: 100% !important;
3140
+ padding-left: 8px !important;
3030
3141
  }
3031
3142
 
3032
3143
  .ce-toolbar__plus {
@@ -4024,6 +4135,7 @@ const Editor = React.forwardRef(({
4024
4135
  const bindAllBlocksToYText = React.useCallback(() => {
4025
4136
  if (!collabEnabled || !editorInstanceRef.current || !yTextMap) return;
4026
4137
  const editor = editorInstanceRef.current;
4138
+ if (!editor.blocks || typeof editor.blocks.getBlocksCount !== "function") return;
4027
4139
  const blockCount = editor.blocks.getBlocksCount();
4028
4140
  console.log("[Magic Editor X] [CHAR-SYNC] Binding", blockCount, "blocks to Y.Text");
4029
4141
  for (let i = 0; i < blockCount; i++) {
@@ -4443,6 +4555,11 @@ const Editor = React.forwardRef(({
4443
4555
  pendingRenderRef.current = pendingRenderRef.current || true;
4444
4556
  return;
4445
4557
  }
4558
+ if (!editor.blocks || typeof editor.blocks.getBlocksCount !== "function") {
4559
+ console.warn("[Magic Editor X] Editor blocks API not ready for renderFromYDoc");
4560
+ pendingRenderRef.current = pendingRenderRef.current || true;
4561
+ return;
4562
+ }
4446
4563
  if (isApplyingRemoteRef.current) {
4447
4564
  return;
4448
4565
  }
@@ -4695,6 +4812,7 @@ const Editor = React.forwardRef(({
4695
4812
  return;
4696
4813
  }
4697
4814
  const editor = editorInstanceRef.current;
4815
+ if (!editor.blocks || typeof editor.blocks.getBlocksCount !== "function") return;
4698
4816
  const lastIndex = editor.blocks.getBlocksCount();
4699
4817
  editor.blocks.insert(blockType, {}, {}, lastIndex, true);
4700
4818
  editor.caret.setToBlock(lastIndex);
@@ -4742,6 +4860,18 @@ const Editor = React.forwardRef(({
4742
4860
  editorRef.current.classList.add("editor-readonly");
4743
4861
  }
4744
4862
  }
4863
+ console.log("[Magic Editor X] Registered tools:", Object.keys(tools$1));
4864
+ const inlineTools = Object.entries(tools$1).filter(([name2, config]) => {
4865
+ const toolClass = config.class || config;
4866
+ const isInline = toolClass?.isInline === true;
4867
+ if (isInline) {
4868
+ console.log(`[Magic Editor X] Found inline tool: ${name2}`, toolClass);
4869
+ }
4870
+ return isInline;
4871
+ }).map(([name2]) => name2);
4872
+ console.log("[Magic Editor X] Inline tools found:", inlineTools);
4873
+ console.log("[Magic Editor X] Marker isInline:", tools$1.marker?.class?.isInline);
4874
+ console.log("[Magic Editor X] Bold isInline:", tools$1.bold?.class?.isInline);
4745
4875
  const editor = new EditorJS__default.default({
4746
4876
  holder: editorRef.current,
4747
4877
  tools: tools$1,
@@ -4750,23 +4880,35 @@ const Editor = React.forwardRef(({
4750
4880
  placeholder: customPlaceholder,
4751
4881
  minHeight: 200,
4752
4882
  autofocus: false,
4883
+ // Note: Do NOT set inlineToolbar here - each block tool controls its own inline toolbar
4884
+ // The inline tools (bold, italic, marker, etc.) are automatically available when block tools have inlineToolbar: true
4753
4885
  onReady: async () => {
4754
4886
  isReadyRef.current = true;
4755
4887
  setIsReady(true);
4756
4888
  console.log("[Magic Editor X] [READY] Editor onReady fired");
4757
4889
  console.log("[Magic Editor X] [READY] Editor holder:", editorRef.current?.id);
4758
- try {
4759
- tools.initUndoRedo(editor);
4760
- console.log("[Magic Editor X] [SUCCESS] Undo/Redo initialized");
4761
- } catch (e) {
4762
- console.warn("[Magic Editor X] Could not initialize Undo/Redo:", e);
4763
- }
4764
- try {
4765
- tools.initDragDrop(editor);
4766
- console.log("[Magic Editor X] [SUCCESS] Drag & Drop initialized");
4767
- } catch (e) {
4768
- console.warn("[Magic Editor X] Could not initialize Drag & Drop:", e);
4769
- }
4890
+ setTimeout(() => {
4891
+ try {
4892
+ if (editor && editor.blocks && typeof editor.blocks.getBlocksCount === "function") {
4893
+ tools.initUndoRedo(editor);
4894
+ console.log("[Magic Editor X] [SUCCESS] Undo/Redo initialized");
4895
+ } else {
4896
+ console.warn("[Magic Editor X] Editor blocks API not ready for Undo/Redo");
4897
+ }
4898
+ } catch (e) {
4899
+ console.warn("[Magic Editor X] Could not initialize Undo/Redo:", e);
4900
+ }
4901
+ try {
4902
+ if (editor && editor.blocks && typeof editor.blocks.getBlocksCount === "function") {
4903
+ tools.initDragDrop(editor);
4904
+ console.log("[Magic Editor X] [SUCCESS] Drag & Drop initialized");
4905
+ } else {
4906
+ console.warn("[Magic Editor X] Editor blocks API not ready for Drag & Drop");
4907
+ }
4908
+ } catch (e) {
4909
+ console.warn("[Magic Editor X] Could not initialize Drag & Drop:", e);
4910
+ }
4911
+ }, 500);
4770
4912
  if (pendingRenderRef.current) {
4771
4913
  try {
4772
4914
  if (typeof pendingRenderRef.current === "object" && pendingRenderRef.current.blocks) {
@@ -4794,6 +4936,47 @@ const Editor = React.forwardRef(({
4794
4936
  bindAllBlocksToYText();
4795
4937
  }, 100);
4796
4938
  }
4939
+ if (isWebtoolsAvailable && webtoolsOpenLinkPicker && editorRef.current) {
4940
+ const handleLinkClick = async (e) => {
4941
+ const anchor = e.target.closest("a");
4942
+ if (anchor && editorRef.current?.contains(anchor)) {
4943
+ e.preventDefault();
4944
+ e.stopPropagation();
4945
+ const existingHref = anchor.href || "";
4946
+ const existingText = anchor.textContent || "";
4947
+ console.log("[Magic Editor X] Link clicked, opening editor:", existingHref);
4948
+ try {
4949
+ const selection = window.getSelection();
4950
+ const range = document.createRange();
4951
+ range.selectNodeContents(anchor);
4952
+ selection.removeAllRanges();
4953
+ selection.addRange(range);
4954
+ const result = await webtoolsOpenLinkPicker({
4955
+ initialText: existingText,
4956
+ initialHref: existingHref
4957
+ });
4958
+ if (result && result.href) {
4959
+ anchor.href = result.href;
4960
+ if (result.label && result.label !== existingText) {
4961
+ anchor.textContent = result.label;
4962
+ }
4963
+ console.log("[Magic Editor X] Link updated:", result.href);
4964
+ } else if (result === null) {
4965
+ console.log("[Magic Editor X] Link edit cancelled");
4966
+ }
4967
+ } catch (err) {
4968
+ console.error("[Magic Editor X] Error editing link:", err);
4969
+ }
4970
+ }
4971
+ };
4972
+ editorRef.current.addEventListener("click", handleLinkClick);
4973
+ const cleanup = () => {
4974
+ editorRef.current?.removeEventListener("click", handleLinkClick);
4975
+ };
4976
+ if (!editorRef.current._linkClickCleanup) {
4977
+ editorRef.current._linkClickCleanup = cleanup;
4978
+ }
4979
+ }
4797
4980
  },
4798
4981
  onChange: async (api) => {
4799
4982
  try {
@@ -4828,6 +5011,10 @@ const Editor = React.forwardRef(({
4828
5011
  console.log("[Magic Editor X] [CLEANUP] Editor component unmounting, destroying editor");
4829
5012
  isReadyRef.current = false;
4830
5013
  setIsReady(false);
5014
+ if (editorRef.current?._linkClickCleanup) {
5015
+ editorRef.current._linkClickCleanup();
5016
+ delete editorRef.current._linkClickCleanup;
5017
+ }
4831
5018
  if (editorInstanceRef.current && editorInstanceRef.current.destroy) {
4832
5019
  try {
4833
5020
  editorInstanceRef.current.destroy();
@@ -1,12 +1,12 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import React__default, { useState, useEffect, useCallback, useRef, useMemo, forwardRef } from "react";
3
- import { u as useIntl, F as Flex, T as Typography, B as Button$2, D as Divider, a as Box, g as getTranslation, b as Field, L as Loader } from "./getTranslation-ChB_HlBd.mjs";
3
+ import { u as useIntl, F as Flex, T as Typography, B as Button$2, D as Divider, a as Box, g as getTranslation, b as Field, L as Loader } from "./getTranslation-CZ77ytJY.mjs";
4
4
  import styled, { createGlobalStyle, css } from "styled-components";
5
5
  import { ClockIcon, ExclamationTriangleIcon, SparklesIcon as SparklesIcon$1, Bars3BottomLeftIcon, ListBulletIcon, CheckCircleIcon, PhotoIcon, LinkIcon, CodeBracketIcon, TableCellsIcon, ChatBubbleBottomCenterTextIcon, MinusIcon, DocumentDuplicateIcon, TrashIcon, ArrowsPointingInIcon, ArrowsPointingOutIcon, EyeIcon, PencilSquareIcon } from "@heroicons/react/24/outline";
6
6
  import EditorJS from "@editorjs/editorjs";
7
- import { M as MagicEditorAPI, t as toastManager, g as getTools, i as initUndoRedo, a as initDragDrop, A as AIToast, b as AIInlineToolbar } from "./tools-BAvbiUHr.mjs";
7
+ import { M as MagicEditorAPI, t as toastManager, g as getTools, i as initUndoRedo, a as initDragDrop, A as AIToast, b as AIInlineToolbar } from "./tools-CNqrBm-q.mjs";
8
8
  import { useStrapiApp, useFetchClient, useAuth } from "@strapi/strapi/admin";
9
- import { P as PLUGIN_ID } from "./index-CtyxDZ0S.mjs";
9
+ import { P as PLUGIN_ID } from "./index-BNxjfrVK.mjs";
10
10
  import { io } from "socket.io-client";
11
11
  import * as Y from "yjs";
12
12
  import { IndexeddbPersistence } from "y-indexeddb";
@@ -2112,19 +2112,118 @@ const FullscreenGlobalStyle = createGlobalStyle`
2112
2112
  }
2113
2113
  `;
2114
2114
  const EditorJSGlobalStyles = createGlobalStyle`
2115
- /* Popover rendered at document body */
2116
- body > .ce-popover,
2117
- body > .ce-popover--opened,
2118
- body > .ce-popover__container,
2119
- body > .ce-settings,
2120
- body > .ce-conversion-toolbar,
2121
- body > .ce-inline-toolbar {
2115
+ /* ============================================
2116
+ INLINE TOOLBAR - EditorJS 2.31
2117
+ Structure: .ce-inline-toolbar > .ce-popover--inline > .ce-popover__items > .ce-popover-item-html > .ce-inline-tool
2118
+ ============================================ */
2119
+
2120
+ /* Hide "Nothing found" message when inline tools ARE present */
2121
+ .ce-popover--inline .ce-popover__nothing-found-message {
2122
+ display: none !important;
2123
+ }
2124
+
2125
+ /* Inline Toolbar Popover - horizontal layout for tool buttons */
2126
+ .ce-popover--inline.ce-popover--opened {
2127
+ display: block !important;
2128
+ opacity: 1 !important;
2129
+ visibility: visible !important;
2122
2130
  z-index: 99999 !important;
2131
+ background: white !important;
2132
+ border: 1px solid #e2e8f0 !important;
2133
+ border-radius: 8px !important;
2134
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12) !important;
2135
+ padding: 4px !important;
2123
2136
  }
2124
2137
 
2125
- /* Ensure popovers are visible above Strapi modals */
2126
- .ce-popover,
2127
- .ce-popover--opened {
2138
+ .ce-popover--inline .ce-popover__container {
2139
+ display: block !important;
2140
+ }
2141
+
2142
+ /* Items container - HORIZONTAL layout for inline tools */
2143
+ .ce-popover--inline .ce-popover__items {
2144
+ display: flex !important;
2145
+ flex-direction: row !important;
2146
+ flex-wrap: wrap !important;
2147
+ align-items: center !important;
2148
+ gap: 2px !important;
2149
+ opacity: 1 !important;
2150
+ visibility: visible !important;
2151
+ }
2152
+
2153
+ /* Custom HTML wrapper for inline tools */
2154
+ .ce-popover--inline .ce-popover-item-html {
2155
+ display: flex !important;
2156
+ opacity: 1 !important;
2157
+ visibility: visible !important;
2158
+ }
2159
+
2160
+ /* The actual inline tool buttons (Bold, Italic, etc.) */
2161
+ .ce-popover--inline .ce-inline-tool {
2162
+ display: flex !important;
2163
+ align-items: center !important;
2164
+ justify-content: center !important;
2165
+ width: 32px !important;
2166
+ height: 32px !important;
2167
+ opacity: 1 !important;
2168
+ visibility: visible !important;
2169
+ background: transparent !important;
2170
+ border: none !important;
2171
+ border-radius: 6px !important;
2172
+ cursor: pointer !important;
2173
+ color: #64748b !important;
2174
+ transition: background 0.15s ease, color 0.15s ease !important;
2175
+ }
2176
+
2177
+ .ce-popover--inline .ce-inline-tool:hover {
2178
+ background: #f1f5f9 !important;
2179
+ color: #334155 !important;
2180
+ }
2181
+
2182
+ .ce-popover--inline .ce-inline-tool--active {
2183
+ background: #ede9fe !important;
2184
+ color: #7C3AED !important;
2185
+ }
2186
+
2187
+ .ce-popover--inline .ce-inline-tool svg {
2188
+ width: 18px !important;
2189
+ height: 18px !important;
2190
+ }
2191
+
2192
+ /* Convert-to button (block type changer) */
2193
+ .ce-popover--inline .ce-popover-item[data-item-name="convert-to"] {
2194
+ display: flex !important;
2195
+ align-items: center !important;
2196
+ padding: 4px 8px !important;
2197
+ border-radius: 6px !important;
2198
+ cursor: pointer !important;
2199
+ }
2200
+
2201
+ .ce-popover--inline .ce-popover-item[data-item-name="convert-to"]:hover {
2202
+ background: #f1f5f9 !important;
2203
+ }
2204
+
2205
+ /* Separator line between convert-to and inline tools */
2206
+ .ce-popover--inline .ce-popover-item-separator {
2207
+ width: 1px !important;
2208
+ height: 24px !important;
2209
+ background: #e2e8f0 !important;
2210
+ margin: 0 4px !important;
2211
+ }
2212
+
2213
+ .ce-popover--inline .ce-popover-item-separator__line {
2214
+ display: none !important;
2215
+ }
2216
+
2217
+ /* ============================================
2218
+ GLOBAL Z-INDEX FOR ALL EDITOR POPOVERS
2219
+ ============================================ */
2220
+
2221
+ body > .ce-popover,
2222
+ body > .ce-inline-toolbar,
2223
+ .ce-popover--opened,
2224
+ .ce-inline-toolbar,
2225
+ .ce-settings,
2226
+ .ce-conversion-toolbar {
2128
2227
  z-index: 99999 !important;
2129
2228
  }
2130
2229
 
@@ -2930,19 +3029,29 @@ const EditorWrapper = styled.div`
2930
3029
  TOOLBAR INSIDE EDITOR - Position Fix
2931
3030
  ============================================ */
2932
3031
 
2933
- /* Centered content area */
3032
+ /* Content area - full container width */
2934
3033
  .codex-editor__redactor {
2935
3034
  padding-bottom: 100px !important;
2936
3035
  padding-left: 0 !important;
2937
- margin: 0 auto !important;
2938
- max-width: 800px !important;
3036
+ padding-right: 0 !important;
3037
+ margin: 0 !important;
3038
+ max-width: 100% !important;
3039
+ width: 100% !important;
2939
3040
  }
2940
3041
 
2941
- /* Content blocks - centered */
3042
+ /* Content blocks - full width, no centering */
2942
3043
  .ce-block__content {
2943
- max-width: 100%;
2944
- margin: 0 auto;
2945
- padding: 0 16px;
3044
+ max-width: 100% !important;
3045
+ margin: 0 !important;
3046
+ padding: 0 16px !important;
3047
+ }
3048
+
3049
+ /* Paragraph and other editable elements - full width */
3050
+ .ce-paragraph,
3051
+ .ce-header,
3052
+ .cdx-block {
3053
+ max-width: 100% !important;
3054
+ width: 100% !important;
2946
3055
  }
2947
3056
 
2948
3057
  /* ============================================
@@ -2991,18 +3100,20 @@ const EditorWrapper = styled.div`
2991
3100
  border-radius: 6px;
2992
3101
  }
2993
3102
 
2994
- /* Toolbar positioning - centered with content */
3103
+ /* Toolbar positioning - full width */
2995
3104
  .ce-toolbar__content {
2996
- max-width: 800px;
2997
- margin: 0 auto;
2998
- padding: 0 16px;
3105
+ max-width: 100% !important;
3106
+ margin: 0 !important;
3107
+ padding: 0 16px !important;
2999
3108
  }
3000
3109
 
3001
3110
  .ce-toolbar {
3002
- left: 50% !important;
3003
- transform: translateX(-50%) !important;
3111
+ left: 0 !important;
3112
+ right: 0 !important;
3113
+ transform: none !important;
3004
3114
  width: 100% !important;
3005
- max-width: 832px !important;
3115
+ max-width: 100% !important;
3116
+ padding-left: 8px !important;
3006
3117
  }
3007
3118
 
3008
3119
  .ce-toolbar__plus {
@@ -4000,6 +4111,7 @@ const Editor = forwardRef(({
4000
4111
  const bindAllBlocksToYText = useCallback(() => {
4001
4112
  if (!collabEnabled || !editorInstanceRef.current || !yTextMap) return;
4002
4113
  const editor = editorInstanceRef.current;
4114
+ if (!editor.blocks || typeof editor.blocks.getBlocksCount !== "function") return;
4003
4115
  const blockCount = editor.blocks.getBlocksCount();
4004
4116
  console.log("[Magic Editor X] [CHAR-SYNC] Binding", blockCount, "blocks to Y.Text");
4005
4117
  for (let i = 0; i < blockCount; i++) {
@@ -4419,6 +4531,11 @@ const Editor = forwardRef(({
4419
4531
  pendingRenderRef.current = pendingRenderRef.current || true;
4420
4532
  return;
4421
4533
  }
4534
+ if (!editor.blocks || typeof editor.blocks.getBlocksCount !== "function") {
4535
+ console.warn("[Magic Editor X] Editor blocks API not ready for renderFromYDoc");
4536
+ pendingRenderRef.current = pendingRenderRef.current || true;
4537
+ return;
4538
+ }
4422
4539
  if (isApplyingRemoteRef.current) {
4423
4540
  return;
4424
4541
  }
@@ -4671,6 +4788,7 @@ const Editor = forwardRef(({
4671
4788
  return;
4672
4789
  }
4673
4790
  const editor = editorInstanceRef.current;
4791
+ if (!editor.blocks || typeof editor.blocks.getBlocksCount !== "function") return;
4674
4792
  const lastIndex = editor.blocks.getBlocksCount();
4675
4793
  editor.blocks.insert(blockType, {}, {}, lastIndex, true);
4676
4794
  editor.caret.setToBlock(lastIndex);
@@ -4718,6 +4836,18 @@ const Editor = forwardRef(({
4718
4836
  editorRef.current.classList.add("editor-readonly");
4719
4837
  }
4720
4838
  }
4839
+ console.log("[Magic Editor X] Registered tools:", Object.keys(tools));
4840
+ const inlineTools = Object.entries(tools).filter(([name2, config]) => {
4841
+ const toolClass = config.class || config;
4842
+ const isInline = toolClass?.isInline === true;
4843
+ if (isInline) {
4844
+ console.log(`[Magic Editor X] Found inline tool: ${name2}`, toolClass);
4845
+ }
4846
+ return isInline;
4847
+ }).map(([name2]) => name2);
4848
+ console.log("[Magic Editor X] Inline tools found:", inlineTools);
4849
+ console.log("[Magic Editor X] Marker isInline:", tools.marker?.class?.isInline);
4850
+ console.log("[Magic Editor X] Bold isInline:", tools.bold?.class?.isInline);
4721
4851
  const editor = new EditorJS({
4722
4852
  holder: editorRef.current,
4723
4853
  tools,
@@ -4726,23 +4856,35 @@ const Editor = forwardRef(({
4726
4856
  placeholder: customPlaceholder,
4727
4857
  minHeight: 200,
4728
4858
  autofocus: false,
4859
+ // Note: Do NOT set inlineToolbar here - each block tool controls its own inline toolbar
4860
+ // The inline tools (bold, italic, marker, etc.) are automatically available when block tools have inlineToolbar: true
4729
4861
  onReady: async () => {
4730
4862
  isReadyRef.current = true;
4731
4863
  setIsReady(true);
4732
4864
  console.log("[Magic Editor X] [READY] Editor onReady fired");
4733
4865
  console.log("[Magic Editor X] [READY] Editor holder:", editorRef.current?.id);
4734
- try {
4735
- initUndoRedo(editor);
4736
- console.log("[Magic Editor X] [SUCCESS] Undo/Redo initialized");
4737
- } catch (e) {
4738
- console.warn("[Magic Editor X] Could not initialize Undo/Redo:", e);
4739
- }
4740
- try {
4741
- initDragDrop(editor);
4742
- console.log("[Magic Editor X] [SUCCESS] Drag & Drop initialized");
4743
- } catch (e) {
4744
- console.warn("[Magic Editor X] Could not initialize Drag & Drop:", e);
4745
- }
4866
+ setTimeout(() => {
4867
+ try {
4868
+ if (editor && editor.blocks && typeof editor.blocks.getBlocksCount === "function") {
4869
+ initUndoRedo(editor);
4870
+ console.log("[Magic Editor X] [SUCCESS] Undo/Redo initialized");
4871
+ } else {
4872
+ console.warn("[Magic Editor X] Editor blocks API not ready for Undo/Redo");
4873
+ }
4874
+ } catch (e) {
4875
+ console.warn("[Magic Editor X] Could not initialize Undo/Redo:", e);
4876
+ }
4877
+ try {
4878
+ if (editor && editor.blocks && typeof editor.blocks.getBlocksCount === "function") {
4879
+ initDragDrop(editor);
4880
+ console.log("[Magic Editor X] [SUCCESS] Drag & Drop initialized");
4881
+ } else {
4882
+ console.warn("[Magic Editor X] Editor blocks API not ready for Drag & Drop");
4883
+ }
4884
+ } catch (e) {
4885
+ console.warn("[Magic Editor X] Could not initialize Drag & Drop:", e);
4886
+ }
4887
+ }, 500);
4746
4888
  if (pendingRenderRef.current) {
4747
4889
  try {
4748
4890
  if (typeof pendingRenderRef.current === "object" && pendingRenderRef.current.blocks) {
@@ -4770,6 +4912,47 @@ const Editor = forwardRef(({
4770
4912
  bindAllBlocksToYText();
4771
4913
  }, 100);
4772
4914
  }
4915
+ if (isWebtoolsAvailable && webtoolsOpenLinkPicker && editorRef.current) {
4916
+ const handleLinkClick = async (e) => {
4917
+ const anchor = e.target.closest("a");
4918
+ if (anchor && editorRef.current?.contains(anchor)) {
4919
+ e.preventDefault();
4920
+ e.stopPropagation();
4921
+ const existingHref = anchor.href || "";
4922
+ const existingText = anchor.textContent || "";
4923
+ console.log("[Magic Editor X] Link clicked, opening editor:", existingHref);
4924
+ try {
4925
+ const selection = window.getSelection();
4926
+ const range = document.createRange();
4927
+ range.selectNodeContents(anchor);
4928
+ selection.removeAllRanges();
4929
+ selection.addRange(range);
4930
+ const result = await webtoolsOpenLinkPicker({
4931
+ initialText: existingText,
4932
+ initialHref: existingHref
4933
+ });
4934
+ if (result && result.href) {
4935
+ anchor.href = result.href;
4936
+ if (result.label && result.label !== existingText) {
4937
+ anchor.textContent = result.label;
4938
+ }
4939
+ console.log("[Magic Editor X] Link updated:", result.href);
4940
+ } else if (result === null) {
4941
+ console.log("[Magic Editor X] Link edit cancelled");
4942
+ }
4943
+ } catch (err) {
4944
+ console.error("[Magic Editor X] Error editing link:", err);
4945
+ }
4946
+ }
4947
+ };
4948
+ editorRef.current.addEventListener("click", handleLinkClick);
4949
+ const cleanup = () => {
4950
+ editorRef.current?.removeEventListener("click", handleLinkClick);
4951
+ };
4952
+ if (!editorRef.current._linkClickCleanup) {
4953
+ editorRef.current._linkClickCleanup = cleanup;
4954
+ }
4955
+ }
4773
4956
  },
4774
4957
  onChange: async (api) => {
4775
4958
  try {
@@ -4804,6 +4987,10 @@ const Editor = forwardRef(({
4804
4987
  console.log("[Magic Editor X] [CLEANUP] Editor component unmounting, destroying editor");
4805
4988
  isReadyRef.current = false;
4806
4989
  setIsReady(false);
4990
+ if (editorRef.current?._linkClickCleanup) {
4991
+ editorRef.current._linkClickCleanup();
4992
+ delete editorRef.current._linkClickCleanup;
4993
+ }
4807
4994
  if (editorInstanceRef.current && editorInstanceRef.current.destroy) {
4808
4995
  try {
4809
4996
  editorInstanceRef.current.destroy();
@@ -2384,7 +2384,7 @@ const index = {
2384
2384
  icon: PluginIcon,
2385
2385
  // Input component for Content Manager
2386
2386
  components: {
2387
- Input: async () => Promise.resolve().then(() => require("./index-DGRg45vZ.js")).then((module2) => ({
2387
+ Input: async () => Promise.resolve().then(() => require("./index-BmWx_nJX.js")).then((module2) => ({
2388
2388
  default: module2.default
2389
2389
  }))
2390
2390
  },
@@ -2446,7 +2446,7 @@ const index = {
2446
2446
  defaultMessage: "Magic Editor X"
2447
2447
  },
2448
2448
  // Use lazy import without async wrapper to avoid deprecation warning
2449
- Component: () => Promise.resolve().then(() => require("./App-BHNqY71z.js")),
2449
+ Component: () => Promise.resolve().then(() => require("./App-CWXreQMz.js")),
2450
2450
  permissions: []
2451
2451
  });
2452
2452
  app.createSettingSection(
@@ -2465,7 +2465,7 @@ const index = {
2465
2465
  id: "upgrade",
2466
2466
  // relative path (no leading slash)
2467
2467
  to: `${PLUGIN_ID}/upgrade`,
2468
- Component: () => Promise.resolve().then(() => require("./LicensePage-VwKQMnUO.js"))
2468
+ Component: () => Promise.resolve().then(() => require("./LicensePage-BIaCAB4C.js"))
2469
2469
  },
2470
2470
  {
2471
2471
  intlLabel: {
@@ -2475,7 +2475,7 @@ const index = {
2475
2475
  id: "license",
2476
2476
  // relative path (no leading slash)
2477
2477
  to: `${PLUGIN_ID}/license`,
2478
- Component: () => Promise.resolve().then(() => require("./Settings-4wUHMbn0.js"))
2478
+ Component: () => Promise.resolve().then(() => require("./Settings-BsoK7S5l.js"))
2479
2479
  }
2480
2480
  ]
2481
2481
  );
@@ -2485,7 +2485,7 @@ const index = {
2485
2485
  * Bootstrap the plugin
2486
2486
  */
2487
2487
  async bootstrap(app) {
2488
- const { default: LiveCollaborationPanel } = await Promise.resolve().then(() => require("./LiveCollaborationPanel-CqtkFWJs.js"));
2488
+ const { default: LiveCollaborationPanel } = await Promise.resolve().then(() => require("./LiveCollaborationPanel-BmAFvNll.js"));
2489
2489
  try {
2490
2490
  const contentManagerPlugin = app.getPlugin("content-manager");
2491
2491
  if (contentManagerPlugin && contentManagerPlugin.apis) {
@@ -1729,6 +1729,80 @@ class MediaLibAdapter {
1729
1729
  };
1730
1730
  }
1731
1731
  }
1732
+ class BoldInlineTool {
1733
+ static get isInline() {
1734
+ return true;
1735
+ }
1736
+ static get title() {
1737
+ return "Bold";
1738
+ }
1739
+ static get sanitize() {
1740
+ return {
1741
+ b: {},
1742
+ strong: {}
1743
+ };
1744
+ }
1745
+ constructor({ api }) {
1746
+ this.api = api;
1747
+ this.button = null;
1748
+ this._state = false;
1749
+ }
1750
+ render() {
1751
+ this.button = document.createElement("button");
1752
+ this.button.type = "button";
1753
+ this.button.innerHTML = '<svg width="12" height="14" xmlns="http://www.w3.org/2000/svg"><path d="M5.997 14H1.72c-.618 0-1.058-.138-1.323-.415C.132 13.308 0 12.924 0 12.435V1.565C0 1.076.132.692.397.415.662.138 1.102 0 1.72 0h4.418c.862 0 1.592.175 2.189.526.597.35 1.047.818 1.35 1.403.302.585.454 1.236.454 1.952 0 .603-.13 1.144-.388 1.624-.26.48-.617.871-1.072 1.174.659.225 1.182.608 1.57 1.147.388.54.583 1.173.583 1.9 0 .792-.19 1.496-.57 2.111-.38.616-.91 1.1-1.592 1.451-.682.352-1.465.527-2.35.527H6zm-.02-8.393h2.341c.444 0 .804-.13 1.08-.39.278-.26.416-.618.416-1.072 0-.467-.152-.838-.457-1.114-.305-.276-.677-.414-1.115-.414H5.977v2.99zm0 6.182h2.593c.478 0 .862-.152 1.152-.456.29-.305.436-.69.436-1.155 0-.467-.152-.858-.456-1.172-.304-.315-.709-.472-1.214-.472H5.977v3.255z" fill="currentColor"/></svg>';
1754
+ this.button.classList.add("ce-inline-tool");
1755
+ return this.button;
1756
+ }
1757
+ surround(range) {
1758
+ document.execCommand("bold");
1759
+ }
1760
+ checkState() {
1761
+ const isActive = document.queryCommandState("bold");
1762
+ this.button.classList.toggle("ce-inline-tool--active", isActive);
1763
+ return isActive;
1764
+ }
1765
+ get shortcut() {
1766
+ return "CMD+B";
1767
+ }
1768
+ }
1769
+ class ItalicInlineTool {
1770
+ static get isInline() {
1771
+ return true;
1772
+ }
1773
+ static get title() {
1774
+ return "Italic";
1775
+ }
1776
+ static get sanitize() {
1777
+ return {
1778
+ i: {},
1779
+ em: {}
1780
+ };
1781
+ }
1782
+ constructor({ api }) {
1783
+ this.api = api;
1784
+ this.button = null;
1785
+ this._state = false;
1786
+ }
1787
+ render() {
1788
+ this.button = document.createElement("button");
1789
+ this.button.type = "button";
1790
+ this.button.innerHTML = '<svg width="6" height="14" xmlns="http://www.w3.org/2000/svg"><path d="M3.289 14L4.867 3.286H3.267L3.496 1.59h4.555L8 0H1.49l-.498 1.59h1.594L.844 12.304H.265L0 14h3.289z" fill="currentColor"/></svg>';
1791
+ this.button.classList.add("ce-inline-tool");
1792
+ return this.button;
1793
+ }
1794
+ surround(range) {
1795
+ document.execCommand("italic");
1796
+ }
1797
+ checkState() {
1798
+ const isActive = document.queryCommandState("italic");
1799
+ this.button.classList.toggle("ce-inline-tool--active", isActive);
1800
+ return isActive;
1801
+ }
1802
+ get shortcut() {
1803
+ return "CMD+I";
1804
+ }
1805
+ }
1732
1806
  Personality__default.default.isReadOnlySupported = true;
1733
1807
  MediaLibAdapter.isReadOnlySupported = true;
1734
1808
  ButtonTool.isReadOnlySupported = true;
@@ -1761,7 +1835,7 @@ const getTools = ({ mediaLibToggleFunc, pluginId, openLinkPicker }) => {
1761
1835
  */
1762
1836
  header: {
1763
1837
  class: Header__default.default,
1764
- inlineToolbar: true,
1838
+ inlineToolbar: ["bold", "italic", "marker", "inlineCode", "underline", "strikethrough"],
1765
1839
  tunes: ["alignmentTune"],
1766
1840
  config: {
1767
1841
  placeholder: "Enter a heading",
@@ -1776,7 +1850,7 @@ const getTools = ({ mediaLibToggleFunc, pluginId, openLinkPicker }) => {
1776
1850
  */
1777
1851
  paragraph: {
1778
1852
  class: Paragraph__default.default,
1779
- inlineToolbar: true,
1853
+ inlineToolbar: ["bold", "italic", "marker", "inlineCode", "underline", "strikethrough", "hyperlink"],
1780
1854
  tunes: ["alignmentTune", "indentTune"],
1781
1855
  config: {
1782
1856
  placeholder: "Start writing or press Tab to add a block...",
@@ -1789,7 +1863,7 @@ const getTools = ({ mediaLibToggleFunc, pluginId, openLinkPicker }) => {
1789
1863
  */
1790
1864
  list: {
1791
1865
  class: NestedList__default.default,
1792
- inlineToolbar: true,
1866
+ inlineToolbar: ["bold", "italic", "marker", "inlineCode", "underline", "strikethrough"],
1793
1867
  tunes: ["indentTune"],
1794
1868
  config: {
1795
1869
  defaultStyle: "unordered"
@@ -2057,6 +2131,26 @@ const getTools = ({ mediaLibToggleFunc, pluginId, openLinkPicker }) => {
2057
2131
  inlineToolbar: false
2058
2132
  },
2059
2133
  // ============================================
2134
+ // CORE INLINE TOOLS (Bold & Italic)
2135
+ // These are essential for basic text formatting
2136
+ // ============================================
2137
+ /**
2138
+ * Bold Tool (Custom Implementation)
2139
+ * Essential inline formatting tool
2140
+ */
2141
+ bold: {
2142
+ class: BoldInlineTool,
2143
+ shortcut: "CMD+B"
2144
+ },
2145
+ /**
2146
+ * Italic Tool (Custom Implementation)
2147
+ * Essential inline formatting tool
2148
+ */
2149
+ italic: {
2150
+ class: ItalicInlineTool,
2151
+ shortcut: "CMD+I"
2152
+ },
2153
+ // ============================================
2060
2154
  // OFFICIAL INLINE TOOLS (3 Tools)
2061
2155
  // ============================================
2062
2156
  /**
@@ -1696,6 +1696,80 @@ class MediaLibAdapter {
1696
1696
  };
1697
1697
  }
1698
1698
  }
1699
+ class BoldInlineTool {
1700
+ static get isInline() {
1701
+ return true;
1702
+ }
1703
+ static get title() {
1704
+ return "Bold";
1705
+ }
1706
+ static get sanitize() {
1707
+ return {
1708
+ b: {},
1709
+ strong: {}
1710
+ };
1711
+ }
1712
+ constructor({ api }) {
1713
+ this.api = api;
1714
+ this.button = null;
1715
+ this._state = false;
1716
+ }
1717
+ render() {
1718
+ this.button = document.createElement("button");
1719
+ this.button.type = "button";
1720
+ this.button.innerHTML = '<svg width="12" height="14" xmlns="http://www.w3.org/2000/svg"><path d="M5.997 14H1.72c-.618 0-1.058-.138-1.323-.415C.132 13.308 0 12.924 0 12.435V1.565C0 1.076.132.692.397.415.662.138 1.102 0 1.72 0h4.418c.862 0 1.592.175 2.189.526.597.35 1.047.818 1.35 1.403.302.585.454 1.236.454 1.952 0 .603-.13 1.144-.388 1.624-.26.48-.617.871-1.072 1.174.659.225 1.182.608 1.57 1.147.388.54.583 1.173.583 1.9 0 .792-.19 1.496-.57 2.111-.38.616-.91 1.1-1.592 1.451-.682.352-1.465.527-2.35.527H6zm-.02-8.393h2.341c.444 0 .804-.13 1.08-.39.278-.26.416-.618.416-1.072 0-.467-.152-.838-.457-1.114-.305-.276-.677-.414-1.115-.414H5.977v2.99zm0 6.182h2.593c.478 0 .862-.152 1.152-.456.29-.305.436-.69.436-1.155 0-.467-.152-.858-.456-1.172-.304-.315-.709-.472-1.214-.472H5.977v3.255z" fill="currentColor"/></svg>';
1721
+ this.button.classList.add("ce-inline-tool");
1722
+ return this.button;
1723
+ }
1724
+ surround(range) {
1725
+ document.execCommand("bold");
1726
+ }
1727
+ checkState() {
1728
+ const isActive = document.queryCommandState("bold");
1729
+ this.button.classList.toggle("ce-inline-tool--active", isActive);
1730
+ return isActive;
1731
+ }
1732
+ get shortcut() {
1733
+ return "CMD+B";
1734
+ }
1735
+ }
1736
+ class ItalicInlineTool {
1737
+ static get isInline() {
1738
+ return true;
1739
+ }
1740
+ static get title() {
1741
+ return "Italic";
1742
+ }
1743
+ static get sanitize() {
1744
+ return {
1745
+ i: {},
1746
+ em: {}
1747
+ };
1748
+ }
1749
+ constructor({ api }) {
1750
+ this.api = api;
1751
+ this.button = null;
1752
+ this._state = false;
1753
+ }
1754
+ render() {
1755
+ this.button = document.createElement("button");
1756
+ this.button.type = "button";
1757
+ this.button.innerHTML = '<svg width="6" height="14" xmlns="http://www.w3.org/2000/svg"><path d="M3.289 14L4.867 3.286H3.267L3.496 1.59h4.555L8 0H1.49l-.498 1.59h1.594L.844 12.304H.265L0 14h3.289z" fill="currentColor"/></svg>';
1758
+ this.button.classList.add("ce-inline-tool");
1759
+ return this.button;
1760
+ }
1761
+ surround(range) {
1762
+ document.execCommand("italic");
1763
+ }
1764
+ checkState() {
1765
+ const isActive = document.queryCommandState("italic");
1766
+ this.button.classList.toggle("ce-inline-tool--active", isActive);
1767
+ return isActive;
1768
+ }
1769
+ get shortcut() {
1770
+ return "CMD+I";
1771
+ }
1772
+ }
1699
1773
  Personality.isReadOnlySupported = true;
1700
1774
  MediaLibAdapter.isReadOnlySupported = true;
1701
1775
  ButtonTool.isReadOnlySupported = true;
@@ -1728,7 +1802,7 @@ const getTools = ({ mediaLibToggleFunc, pluginId, openLinkPicker }) => {
1728
1802
  */
1729
1803
  header: {
1730
1804
  class: Header,
1731
- inlineToolbar: true,
1805
+ inlineToolbar: ["bold", "italic", "marker", "inlineCode", "underline", "strikethrough"],
1732
1806
  tunes: ["alignmentTune"],
1733
1807
  config: {
1734
1808
  placeholder: "Enter a heading",
@@ -1743,7 +1817,7 @@ const getTools = ({ mediaLibToggleFunc, pluginId, openLinkPicker }) => {
1743
1817
  */
1744
1818
  paragraph: {
1745
1819
  class: Paragraph,
1746
- inlineToolbar: true,
1820
+ inlineToolbar: ["bold", "italic", "marker", "inlineCode", "underline", "strikethrough", "hyperlink"],
1747
1821
  tunes: ["alignmentTune", "indentTune"],
1748
1822
  config: {
1749
1823
  placeholder: "Start writing or press Tab to add a block...",
@@ -1756,7 +1830,7 @@ const getTools = ({ mediaLibToggleFunc, pluginId, openLinkPicker }) => {
1756
1830
  */
1757
1831
  list: {
1758
1832
  class: NestedList,
1759
- inlineToolbar: true,
1833
+ inlineToolbar: ["bold", "italic", "marker", "inlineCode", "underline", "strikethrough"],
1760
1834
  tunes: ["indentTune"],
1761
1835
  config: {
1762
1836
  defaultStyle: "unordered"
@@ -2024,6 +2098,26 @@ const getTools = ({ mediaLibToggleFunc, pluginId, openLinkPicker }) => {
2024
2098
  inlineToolbar: false
2025
2099
  },
2026
2100
  // ============================================
2101
+ // CORE INLINE TOOLS (Bold & Italic)
2102
+ // These are essential for basic text formatting
2103
+ // ============================================
2104
+ /**
2105
+ * Bold Tool (Custom Implementation)
2106
+ * Essential inline formatting tool
2107
+ */
2108
+ bold: {
2109
+ class: BoldInlineTool,
2110
+ shortcut: "CMD+B"
2111
+ },
2112
+ /**
2113
+ * Italic Tool (Custom Implementation)
2114
+ * Essential inline formatting tool
2115
+ */
2116
+ italic: {
2117
+ class: ItalicInlineTool,
2118
+ shortcut: "CMD+I"
2119
+ },
2120
+ // ============================================
2027
2121
  // OFFICIAL INLINE TOOLS (3 Tools)
2028
2122
  // ============================================
2029
2123
  /**
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-C_SiBh7v.js");
2
+ const index = require("../_chunks/index-DO-QpiC9.js");
3
3
  module.exports = index.index;
@@ -1,4 +1,4 @@
1
- import { q } from "../_chunks/index-CtyxDZ0S.mjs";
1
+ import { q } from "../_chunks/index-BNxjfrVK.mjs";
2
2
  export {
3
3
  q as default
4
4
  };
@@ -37941,7 +37941,7 @@ var snapshotService$1 = ({ strapi: strapi2 }) => {
37941
37941
  };
37942
37942
  };
37943
37943
  const name = "magic-editor-x";
37944
- const version = "1.2.1";
37944
+ const version = "1.2.2";
37945
37945
  const description = "Advanced block-based editor for Strapi v5 with Editor.js, Media Library integration, and real-time collaboration support";
37946
37946
  const keywords = [
37947
37947
  "strapi",
@@ -37922,7 +37922,7 @@ var snapshotService$1 = ({ strapi: strapi2 }) => {
37922
37922
  };
37923
37923
  };
37924
37924
  const name = "magic-editor-x";
37925
- const version = "1.2.1";
37925
+ const version = "1.2.2";
37926
37926
  const description = "Advanced block-based editor for Strapi v5 with Editor.js, Media Library integration, and real-time collaboration support";
37927
37927
  const keywords = [
37928
37928
  "strapi",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magic-editor-x",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "Advanced block-based editor for Strapi v5 with Editor.js, Media Library integration, and real-time collaboration support",
5
5
  "keywords": [
6
6
  "strapi",