Skip to content

Commit e490c51

Browse files
committed
sample(feat[outputType]) Add outputType toggle and span/script tests
why: Browsers sanitize <script> tags from DataTransfer HTML during drag-and-drop. The default outputType ('script') serializes equations as <script type="math/tex">, which is stripped by the browser on drop, causing equations to disappear. Ariel's production integration avoids this by using outputType: 'span' with forceOutputType: true, which serializes as <span class="math-tex"> — preserved by DataTransfer. what: - Add radio toggle to sample/index.html to switch between span and script output types with corresponding HTML templates - Default sample to span mode (matching ariel's working config) - Refactor sample/ckeditor.ts to support destroy/recreate on toggle, extract shared config into constants - Add outputType/forceOutputType test suites to mathdragdrop.ts: - span mode: downcast format, forced type on upcast from script tags, clipboard roundtrip, drag-drop simulation - script mode: downcast format for inline/display, type preservation for both span and script source HTML
1 parent 4ca6d69 commit e490c51

3 files changed

Lines changed: 378 additions & 65 deletions

File tree

sample/ckeditor.ts

Lines changed: 104 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
declare global {
33
interface Window {
44
editor: ClassicEditor;
5+
createMathEditor: ( outputType: 'span' | 'script' ) => Promise<void>;
56
}
67
}
78

@@ -36,67 +37,92 @@ import { Math, AutoformatMath } from '../src/index.js';
3637

3738
import 'ckeditor5/ckeditor5.css';
3839

39-
ClassicEditor
40-
.create( document.getElementById( 'editor' )!, {
41-
// eslint-disable-next-line max-len
42-
licenseKey: 'eyJhbGciOiJFUzI1NiJ9.eyJleHAiOjE3NzMyNzM1OTksImp0aSI6IjE4OWY5M2Q4LThjNGEtNDY1ZS1iM2NjLTExNjA4NmU5MmIxNSIsImRpc3RyaWJ1dGlvbkNoYW5uZWwiOlsic2giLCJkcnVwYWwiXSwid2hpdGVMYWJlbCI6dHJ1ZSwibGljZW5zZVR5cGUiOiJkZXZlbG9wbWVudCIsImZlYXR1cmVzIjpbIkRSVVAiLCJETyIsIkZQIiwiU0MiLCJUT0MiLCJUUEwiLCJQT0UiLCJDQyIsIk1GIiwiU0VFIiwiRUNIIiwiRUlTIiwiTEgiLCJGT08iLCJFMlAiLCJJVyIsIkUyVyJdLCJ2YyI6IjgwZTZiNGY3In0.fxiIg-S7r8GBeN52vnoAsC_OGpFm8LuvMC_MTHGFUJzNants9MKJ1gPiqGX3ZALW10PTJ4KADhrsLPkcsdM_-w',
40+
// eslint-disable-next-line max-len
41+
const LICENSE_KEY = 'eyJhbGciOiJFUzI1NiJ9.eyJleHAiOjE3NzMyNzM1OTksImp0aSI6IjE4OWY5M2Q4LThjNGEtNDY1ZS1iM2NjLTExNjA4NmU5MmIxNSIsImRpc3RyaWJ1dGlvbkNoYW5uZWwiOlsic2giLCJkcnVwYWwiXSwid2hpdGVMYWJlbCI6dHJ1ZSwibGljZW5zZVR5cGUiOiJkZXZlbG9wbWVudCIsImZlYXR1cmVzIjpbIkRSVVAiLCJETyIsIkZQIiwiU0MiLCJUT0MiLCJUUEwiLCJQT0UiLCJDQyIsIk1GIiwiU0VFIiwiRUNIIiwiRUlTIiwiTEgiLCJGT08iLCJFMlAiLCJJVyIsIkUyVyJdLCJ2YyI6IjgwZTZiNGY3In0.fxiIg-S7r8GBeN52vnoAsC_OGpFm8LuvMC_MTHGFUJzNants9MKJ1gPiqGX3ZALW10PTJ4KADhrsLPkcsdM_-w';
42+
43+
const SHARED_PLUGINS = [
44+
Math,
45+
AutoformatMath,
46+
Essentials,
47+
Autoformat,
48+
BlockQuote,
49+
Bold,
50+
Heading,
51+
Image,
52+
ImageCaption,
53+
ImageStyle,
54+
ImageToolbar,
55+
ImageUpload,
56+
Indent,
57+
Italic,
58+
Link,
59+
List,
60+
MediaEmbed,
61+
Paragraph,
62+
Table,
63+
TableToolbar,
64+
CodeBlock,
65+
Code,
66+
Base64UploadAdapter
67+
];
68+
69+
const SHARED_TOOLBAR = [
70+
'undo',
71+
'redo',
72+
'|',
73+
'math',
74+
'|',
75+
'heading',
76+
'|',
77+
'bold',
78+
'italic',
79+
'link',
80+
'code',
81+
'bulletedList',
82+
'numberedList',
83+
'|',
84+
'outdent',
85+
'indent',
86+
'|',
87+
'uploadImage',
88+
'blockQuote',
89+
'insertTable',
90+
'mediaEmbed',
91+
'codeBlock'
92+
];
93+
94+
function loadTemplate( outputType: 'span' | 'script' ): string {
95+
const tpl = document.getElementById( `tpl-${ outputType }` ) as HTMLTemplateElement | null;
96+
if ( !tpl ) {
97+
throw new Error( `Template #tpl-${ outputType } not found` );
98+
}
99+
const div = document.createElement( 'div' );
100+
div.appendChild( tpl.content.cloneNode( true ) );
101+
return div.innerHTML;
102+
}
103+
104+
async function createMathEditor( outputType: 'span' | 'script' ): Promise<void> {
105+
if ( window.editor && typeof window.editor.destroy === 'function' ) {
106+
await window.editor.destroy();
107+
}
108+
109+
const editorEl = document.getElementById( 'editor' )!;
110+
editorEl.innerHTML = loadTemplate( outputType );
111+
112+
const editor = await ClassicEditor.create( editorEl, {
113+
licenseKey: LICENSE_KEY,
43114
math: {
44115
engine: 'katex',
116+
outputType,
117+
forceOutputType: outputType === 'span',
45118
katexRenderOptions: {
46119
macros: {
47120
'\\test': '\\mathrel{\\char`≠}'
48121
}
49122
}
50123
},
51-
plugins: [
52-
Math,
53-
AutoformatMath,
54-
Essentials,
55-
Autoformat,
56-
BlockQuote,
57-
Bold,
58-
Heading,
59-
Image,
60-
ImageCaption,
61-
ImageStyle,
62-
ImageToolbar,
63-
ImageUpload,
64-
Indent,
65-
Italic,
66-
Link,
67-
List,
68-
MediaEmbed,
69-
Paragraph,
70-
Table,
71-
TableToolbar,
72-
CodeBlock,
73-
Code,
74-
Base64UploadAdapter
75-
],
76-
toolbar: [
77-
'undo',
78-
'redo',
79-
'|',
80-
'math',
81-
'|',
82-
'heading',
83-
'|',
84-
'bold',
85-
'italic',
86-
'link',
87-
'code',
88-
'bulletedList',
89-
'numberedList',
90-
'|',
91-
'outdent',
92-
'indent',
93-
'|',
94-
'uploadImage',
95-
'blockQuote',
96-
'insertTable',
97-
'mediaEmbed',
98-
'codeBlock'
99-
],
124+
plugins: SHARED_PLUGINS,
125+
toolbar: SHARED_TOOLBAR,
100126
image: {
101127
toolbar: [
102128
'imageStyle:inline',
@@ -113,12 +139,29 @@ ClassicEditor
113139
'mergeTableCells'
114140
]
115141
}
116-
} )
117-
.then( editor => {
118-
window.editor = editor;
119-
CKEditorInspector.attach( editor );
120-
window.console.log( 'CKEditor 5 is ready.', editor );
121-
} )
122-
.catch( err => {
123-
window.console.error( err.stack );
124142
} );
143+
144+
window.editor = editor;
145+
CKEditorInspector.attach( editor );
146+
window.console.log( `CKEditor 5 is ready (outputType: ${ outputType }).`, editor );
147+
}
148+
149+
window.createMathEditor = createMathEditor;
150+
151+
// Read initial selection from radio buttons
152+
const checkedRadio = document.querySelector<HTMLInputElement>(
153+
'input[name="outputType"]:checked'
154+
);
155+
const initialType = ( checkedRadio?.value === 'script' ? 'script' : 'span' ) as 'span' | 'script';
156+
157+
// Wire up radio change handler
158+
document.querySelectorAll<HTMLInputElement>( 'input[name="outputType"]' ).forEach( radio => {
159+
radio.addEventListener( 'change', () => {
160+
createMathEditor( radio.value as 'span' | 'script' );
161+
} );
162+
} );
163+
164+
// Create initial editor
165+
createMathEditor( initialType ).catch( err => {
166+
window.console.error( err.stack );
167+
} );

sample/index.html

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,96 @@
1313
src="https://cdn.jsdelivr.net/npm/katex@0.16.43/dist/katex.min.js"
1414
crossorigin="anonymous"
1515
></script>
16-
<style>body { max-width: 800px; margin: 20px auto; }</style>
16+
<style>
17+
body { max-width: 800px; margin: 20px auto; }
18+
#output-type-controls {
19+
display: flex;
20+
gap: 1.5em;
21+
align-items: center;
22+
padding: 0.5em 0.75em;
23+
margin-bottom: 0.75em;
24+
border: 1px solid #ccc;
25+
border-radius: 4px;
26+
font-size: 0.85em;
27+
background: #f8f8f8;
28+
}
29+
#output-type-controls legend {
30+
font-weight: bold;
31+
margin-right: 0.5em;
32+
}
33+
#output-type-controls label { cursor: pointer; }
34+
</style>
1735
</head>
1836
<body>
1937

2038
<h1>CKEditor 5 with ckeditor5-math – Development Sample</h1>
2139

22-
<div id="editor">
40+
<fieldset id="output-type-controls">
41+
<legend>outputType</legend>
42+
<label><input type="radio" name="outputType" value="span" checked> span (forceOutputType: true)</label>
43+
<label><input type="radio" name="outputType" value="script"> script (forceOutputType: false)</label>
44+
</fieldset>
45+
46+
<div id="editor"></div>
47+
48+
<template id="tpl-span">
49+
<h2>Development environment</h2>
50+
<p>
51+
This is a demo of the <a href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#classic-editor">classic editor build</a> that loads the <code>Math</code> and <code>AutoformatMath</code> plugin.
52+
</p>
53+
<p>
54+
<code>Math</code> inserts mathematical formulas into the editor. You can click the CKEditor 5 Math icon in the toolbar and see the results.
55+
</p>
56+
57+
<p>
58+
<span class="math-tex">\(e=mc^2\)</span>
59+
</p>
60+
61+
<p>
62+
<span class="math-tex">\(\displaystyle e=mc^2\)</span>
63+
</p>
64+
65+
<p>
66+
This should show "\test" as ≠ via katexRenderOptions.macros:
67+
<span class="math-tex">\(\test\)</span>
68+
</p>
69+
70+
<p>
71+
<span class="math-tex">\(e=mc^2\)</span>
72+
</p>
73+
74+
<h3>The directory structure</h3>
75+
76+
<p>
77+
The code snippet below presents the directory structure.
78+
</p>
79+
80+
<pre><code class="language-plaintext">.
81+
├─ sample
82+
│ ├─ dll.html # The editor initialized using the DLL builds. Check README for details.
83+
│ ├─ index.html # The currently displayed file.
84+
│ └─ ckeditor.js # The editor initialization script.
85+
├─ src
86+
│ ├─ autoformatmath.js # The AutoformatMath plugin.
87+
│ ├─ math.js # The Math plugin.
88+
│ ├─ index.js # The modules exported by the package when using the DLL builds.
89+
│ └─ **/*.js # JavaScript source files.
90+
├─ tests
91+
│ └─ **/*.js # Test files
92+
├─ theme
93+
│ ├─ icons
94+
│ │ ├─ math.svg # The Math icon displayed in the toolbar.
95+
│ └─ mathform.css # Math editor styles.
96+
├─ .editorconfig
97+
├─ ...
98+
└─ README.md</code></pre>
99+
100+
<h3>Reporting issues</h3>
101+
<p>If you found a problem with CKEditor 5 or the package generator, please, report an issue:</p>
102+
<p><a href="https://github.com/multiverse-io/ckeditor5-math/issues">CKEditor 5 Math</a></p>
103+
</template>
104+
105+
<template id="tpl-script">
23106
<h2>Development environment</h2>
24107
<p>
25108
This is a demo of the <a href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#classic-editor">classic editor build</a> that loads the <code>Math</code> and <code>AutoformatMath</code> plugin.
@@ -41,7 +124,6 @@ <h2>Development environment</h2>
41124
<script type="math/tex">\test</script>
42125
</p>
43126

44-
<!-- Quill Style Tag -->
45127
<p>
46128
<span class="ql-formula" data-value="e=mc^2"></span>
47129
</p>
@@ -75,7 +157,7 @@ <h3>The directory structure</h3>
75157
<h3>Reporting issues</h3>
76158
<p>If you found a problem with CKEditor 5 or the package generator, please, report an issue:</p>
77159
<p><a href="https://github.com/multiverse-io/ckeditor5-math/issues">CKEditor 5 Math</a></p>
78-
</div>
160+
</template>
79161

80162
<script src="./ckeditor.dist.js"></script>
81163
<script

0 commit comments

Comments
 (0)