@wiris/mathtype-viewer 8.9.1 → 8.10.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.
- package/README.md +1 -4
- package/babel.config.js +3 -2
- package/dist/WIRISplugins.js +1 -1
- package/dist/WIRISplugins.js.LICENSE.txt +1 -1
- package/dist/app.d.ts +1 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/latex.d.ts +1 -1
- package/dist/latex.d.ts.map +1 -1
- package/dist/mathml.d.ts +1 -0
- package/dist/mathml.d.ts.map +1 -1
- package/dist/properties.d.ts +18 -17
- package/dist/properties.d.ts.map +1 -1
- package/dist/services.d.ts +1 -1
- package/dist/services.d.ts.map +1 -1
- package/docs/spec.md +25 -25
- package/index.html +19 -21
- package/jest.config.js +4 -0
- package/package.json +7 -2
- package/project.json +4 -12
- package/src/app.ts +11 -12
- package/src/latex.ts +19 -24
- package/src/mathml.spec.ts +189 -0
- package/src/mathml.ts +90 -43
- package/src/properties.ts +116 -89
- package/src/retro.ts +49 -44
- package/src/services.ts +65 -48
- package/tsconfig.json +26 -22
- package/typings/module-name.d.ts +1 -1
- package/webpack.config.js +10 -10
- package/dist/utils.d.ts +0 -3
- package/dist/utils.d.ts.map +0 -1
- package/src/utils.ts +0 -45
package/src/properties.ts
CHANGED
|
@@ -1,51 +1,50 @@
|
|
|
1
|
-
import { configurationJson, StatusError } from
|
|
2
|
-
import Util from
|
|
1
|
+
import { configurationJson, StatusError } from "./services";
|
|
2
|
+
import Util from "@wiris/mathtype-html-integration-devkit/src/util";
|
|
3
3
|
|
|
4
4
|
// Helper types for Config below
|
|
5
|
-
type Viewer =
|
|
6
|
-
type Wirispluginperformance =
|
|
5
|
+
type Viewer = "none" | "image" | "mathml" | "latex";
|
|
6
|
+
type Wirispluginperformance = "true" | "false";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Type representing all the configuration for the viewer.
|
|
10
10
|
*/
|
|
11
|
-
export
|
|
12
|
-
editorServicesRoot
|
|
13
|
-
editorServicesExtension
|
|
14
|
-
backendConfig
|
|
15
|
-
wirispluginperformance
|
|
16
|
-
wiriseditormathmlattribute
|
|
17
|
-
wiriscustomheaders
|
|
18
|
-
}
|
|
19
|
-
dpi
|
|
20
|
-
element
|
|
21
|
-
lang
|
|
22
|
-
viewer
|
|
23
|
-
zoom
|
|
24
|
-
}
|
|
11
|
+
export interface Config {
|
|
12
|
+
editorServicesRoot: string;
|
|
13
|
+
editorServicesExtension: string;
|
|
14
|
+
backendConfig: {
|
|
15
|
+
wirispluginperformance: Wirispluginperformance;
|
|
16
|
+
wiriseditormathmlattribute: string;
|
|
17
|
+
wiriscustomheaders: object;
|
|
18
|
+
};
|
|
19
|
+
dpi: number;
|
|
20
|
+
element: string;
|
|
21
|
+
lang: string;
|
|
22
|
+
viewer: Viewer;
|
|
23
|
+
zoom: number;
|
|
24
|
+
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Fallback values for the configurations that are not set.
|
|
28
28
|
*/
|
|
29
29
|
const defaultValues: Config = {
|
|
30
|
-
editorServicesRoot:
|
|
31
|
-
editorServicesExtension:
|
|
30
|
+
editorServicesRoot: "https://www.wiris.net/demo/plugins/app/",
|
|
31
|
+
editorServicesExtension: "",
|
|
32
32
|
backendConfig: {
|
|
33
|
-
wirispluginperformance:
|
|
34
|
-
wiriseditormathmlattribute:
|
|
33
|
+
wirispluginperformance: "true",
|
|
34
|
+
wiriseditormathmlattribute: "data-mathml",
|
|
35
35
|
wiriscustomheaders: {},
|
|
36
36
|
},
|
|
37
37
|
dpi: 96,
|
|
38
|
-
element:
|
|
39
|
-
lang:
|
|
40
|
-
viewer:
|
|
38
|
+
element: "body",
|
|
39
|
+
lang: "en",
|
|
40
|
+
viewer: "none",
|
|
41
41
|
zoom: 1,
|
|
42
|
-
}
|
|
42
|
+
};
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* This class will handle the parameters defined by the user.
|
|
46
46
|
*/
|
|
47
47
|
export class Properties {
|
|
48
|
-
|
|
49
48
|
private static instance: Properties | null = null;
|
|
50
49
|
|
|
51
50
|
render: () => Promise<void> = async () => {};
|
|
@@ -54,15 +53,15 @@ export class Properties {
|
|
|
54
53
|
config: Config = defaultValues;
|
|
55
54
|
|
|
56
55
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
56
|
+
* Private constructor to avoid multiple instances of the class.
|
|
57
|
+
* To instantiate the class, use the static method {@link Properties.getInstance}.
|
|
59
58
|
*/
|
|
60
|
-
private
|
|
59
|
+
private constructor() {}
|
|
61
60
|
|
|
62
|
-
static getInstance(): Properties {
|
|
61
|
+
static async getInstance(): Promise<Properties> {
|
|
63
62
|
if (!Properties.instance) {
|
|
64
63
|
Properties.instance = new Properties();
|
|
65
|
-
Properties.instance.initialize();
|
|
64
|
+
await Properties.instance.initialize();
|
|
66
65
|
}
|
|
67
66
|
return Properties.instance;
|
|
68
67
|
}
|
|
@@ -71,45 +70,35 @@ export class Properties {
|
|
|
71
70
|
* Creates and sets up a new instance of class Properties
|
|
72
71
|
*/
|
|
73
72
|
private async initialize(): Promise<void> {
|
|
73
|
+
if (!Properties.instance) {
|
|
74
|
+
console.error("Properties.instance is not set");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
74
77
|
// Get URL parameters from <script>
|
|
75
|
-
const pluginName =
|
|
76
|
-
const script: HTMLScriptElement = document.querySelector(`script[src*="${pluginName}"]`);
|
|
77
|
-
|
|
78
|
-
if (!!script) {
|
|
79
|
-
const pluginNamePosition: number = script.src.lastIndexOf(pluginName);
|
|
80
|
-
const params: string = script.src.substring(pluginNamePosition + pluginName.length);
|
|
81
|
-
const urlParams = new URLSearchParams(params);
|
|
78
|
+
const pluginName = "WIRISplugins.js";
|
|
79
|
+
const script: HTMLScriptElement | null = document.querySelector(`script[src*="${pluginName}"]`);
|
|
82
80
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (urlParams.get('element') !== null && urlParams.get('element') !== undefined) {
|
|
87
|
-
Properties.instance.config.element = urlParams.get('element');
|
|
88
|
-
}
|
|
89
|
-
if (urlParams.get('lang') !== null && urlParams.get('lang') !== undefined) {
|
|
90
|
-
Properties.instance.config.lang = urlParams.get('lang');
|
|
91
|
-
}
|
|
92
|
-
if (urlParams.get('viewer') !== null && urlParams.get('viewer') !== undefined) {
|
|
93
|
-
Properties.instance.config.viewer = (urlParams.get('viewer') as Viewer);
|
|
94
|
-
}
|
|
95
|
-
if (urlParams.get('zoom') !== null && urlParams.get('zoom') !== undefined) {
|
|
96
|
-
Properties.instance.config.zoom = +urlParams.get('zoom');
|
|
97
|
-
}
|
|
81
|
+
// If the absence of the script is an error maybe this should throw
|
|
82
|
+
if (script) {
|
|
83
|
+
this.setProperties(script, pluginName, Properties.instance);
|
|
98
84
|
}
|
|
99
85
|
|
|
100
|
-
Properties.instance.checkServices();
|
|
86
|
+
await Properties.instance.checkServices();
|
|
101
87
|
|
|
102
88
|
// Get backend parameters calling the configurationjson service
|
|
103
89
|
try {
|
|
104
90
|
Properties.instance.config.backendConfig = await configurationJson(
|
|
105
|
-
[
|
|
91
|
+
["wirispluginperformance", "wiriseditormathmlattribute", "wiriscustomheaders"],
|
|
106
92
|
Properties.instance.editorServicesRoot,
|
|
107
|
-
Properties.instance.editorServicesExtension
|
|
93
|
+
Properties.instance.editorServicesExtension,
|
|
94
|
+
false,
|
|
108
95
|
);
|
|
109
96
|
|
|
110
|
-
// We'll always get a string from the wiriscustomheaders backend parameter. It needs to be converted to an object.
|
|
111
|
-
Properties.instance.config.backendConfig.wiriscustomheaders = Util.convertStringToObject(
|
|
112
|
-
|
|
97
|
+
// We'll always get a string from the wiriscustomheaders backend parameter. It needs to be converted to an object.
|
|
98
|
+
Properties.instance.config.backendConfig.wiriscustomheaders = Util.convertStringToObject(
|
|
99
|
+
Properties.instance.config.backendConfig.wiriscustomheaders,
|
|
100
|
+
);
|
|
101
|
+
} catch (e) {
|
|
113
102
|
if (e instanceof StatusError) {
|
|
114
103
|
// Do nothing; leave default values.
|
|
115
104
|
console.error(e);
|
|
@@ -119,27 +108,73 @@ export class Properties {
|
|
|
119
108
|
}
|
|
120
109
|
}
|
|
121
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Initialize properties from <script>
|
|
113
|
+
* @param script
|
|
114
|
+
* @param pluginName
|
|
115
|
+
* @param instance
|
|
116
|
+
*/
|
|
117
|
+
private setProperties(script: HTMLScriptElement, pluginName: string, instance: Properties) {
|
|
118
|
+
const pluginNamePosition: number = script.src.lastIndexOf(pluginName);
|
|
119
|
+
const params: string = script.src.substring(pluginNamePosition + pluginName.length);
|
|
120
|
+
const urlParams = new URLSearchParams(params);
|
|
121
|
+
|
|
122
|
+
const dpi = urlParams.get("dpi");
|
|
123
|
+
if (dpi !== null && dpi !== undefined) {
|
|
124
|
+
instance.config.dpi = +dpi;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const element = urlParams.get("element");
|
|
128
|
+
if (element !== null && element !== undefined) {
|
|
129
|
+
instance.config.element = element;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const lang = urlParams.get("lang");
|
|
133
|
+
if (lang !== null && lang !== undefined) {
|
|
134
|
+
instance.config.lang = lang;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const viewer = urlParams.get("viewer");
|
|
138
|
+
if (viewer !== null && viewer !== undefined) {
|
|
139
|
+
instance.config.viewer = viewer as Viewer;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const zoom = urlParams.get("zoom");
|
|
143
|
+
if (zoom !== null && zoom !== undefined) {
|
|
144
|
+
instance.config.zoom = +zoom;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
122
148
|
/**
|
|
123
149
|
* Check if is inside Integrations Services
|
|
124
150
|
* @deprecated This will be removed once the viewer uncouple from the integration services.
|
|
125
151
|
*/
|
|
126
|
-
private checkServices()
|
|
127
|
-
const path = (
|
|
152
|
+
private async checkServices() {
|
|
153
|
+
const path = (document.currentScript as HTMLScriptElement).src;
|
|
128
154
|
|
|
129
|
-
if (path.includes(
|
|
130
|
-
// If the path includes pluginwiris_engine use Java Integrations Services
|
|
131
|
-
this.config.editorServicesRoot = path;
|
|
132
|
-
this.config.editorServicesExtension = '';
|
|
133
|
-
} else if (path.includes('integration/WIRISplugins')) {
|
|
155
|
+
if (path.includes("integration/WIRISplugins")) {
|
|
134
156
|
// If the path includes 'integration/WIRISplugins' use PHP Integrations Services
|
|
135
157
|
this.config.editorServicesRoot = path;
|
|
136
|
-
this.config.editorServicesExtension =
|
|
158
|
+
this.config.editorServicesExtension = ".php";
|
|
159
|
+
} else {
|
|
160
|
+
try {
|
|
161
|
+
// We want to know if we are using the integrations java services.
|
|
162
|
+
// So we call the configurationjson service assuming that the path is the one for the Java services.
|
|
163
|
+
// If we get an answer, we know we are using the Java services,
|
|
164
|
+
// otherwise, and since PHP has already been discarded, we'll set the services to wiris.net
|
|
165
|
+
await configurationJson(["wirispluginperformance"], path, "", true);
|
|
166
|
+
|
|
167
|
+
this.config.editorServicesRoot = path;
|
|
168
|
+
this.config.editorServicesExtension = "";
|
|
169
|
+
} catch (e) {
|
|
170
|
+
// We do noting.
|
|
171
|
+
// Getting here means that we are not using php nor Java services so we'll stick to the wiris.net default.
|
|
172
|
+
}
|
|
137
173
|
}
|
|
138
174
|
}
|
|
139
175
|
|
|
140
176
|
get editorServicesRoot(): string {
|
|
141
|
-
return this.config.editorServicesRoot ||
|
|
142
|
-
defaultValues.editorServicesRoot;
|
|
177
|
+
return this.config.editorServicesRoot || defaultValues.editorServicesRoot;
|
|
143
178
|
}
|
|
144
179
|
|
|
145
180
|
set editorServicesRoot(editorServicesRoot: string) {
|
|
@@ -148,8 +183,7 @@ export class Properties {
|
|
|
148
183
|
}
|
|
149
184
|
|
|
150
185
|
get editorServicesExtension(): string {
|
|
151
|
-
return this.config.editorServicesExtension ||
|
|
152
|
-
defaultValues.editorServicesExtension;
|
|
186
|
+
return this.config.editorServicesExtension || defaultValues.editorServicesExtension;
|
|
153
187
|
}
|
|
154
188
|
|
|
155
189
|
set editorServicesExtension(editorServicesExtension: string) {
|
|
@@ -167,11 +201,8 @@ export class Properties {
|
|
|
167
201
|
* @returns {string} Encoded language string.
|
|
168
202
|
*/
|
|
169
203
|
get lang(): string {
|
|
170
|
-
const configLang =
|
|
171
|
-
return configLang ||
|
|
172
|
-
document.getElementsByTagName('html')[0].lang ||
|
|
173
|
-
navigator.language ||
|
|
174
|
-
defaultValues.lang;
|
|
204
|
+
const configLang = this.config.lang === "inherit" ? null : this.config.lang;
|
|
205
|
+
return configLang || document.getElementsByTagName("html")[0].lang || navigator.language || defaultValues.lang;
|
|
175
206
|
}
|
|
176
207
|
|
|
177
208
|
set lang(lang: string) {
|
|
@@ -186,8 +217,7 @@ export class Properties {
|
|
|
186
217
|
* - none, by default.
|
|
187
218
|
*/
|
|
188
219
|
get viewer(): Viewer {
|
|
189
|
-
return this.config.viewer ||
|
|
190
|
-
defaultValues.viewer;
|
|
220
|
+
return this.config.viewer || defaultValues.viewer;
|
|
191
221
|
}
|
|
192
222
|
|
|
193
223
|
set viewer(viewer: Viewer) {
|
|
@@ -202,8 +232,7 @@ export class Properties {
|
|
|
202
232
|
* - 96, by default.
|
|
203
233
|
*/
|
|
204
234
|
get dpi(): number {
|
|
205
|
-
return this.config.dpi ||
|
|
206
|
-
defaultValues.dpi;
|
|
235
|
+
return this.config.dpi || defaultValues.dpi;
|
|
207
236
|
}
|
|
208
237
|
|
|
209
238
|
set dpi(dpi: number) {
|
|
@@ -218,8 +247,7 @@ export class Properties {
|
|
|
218
247
|
* - 1, by default.
|
|
219
248
|
*/
|
|
220
249
|
get zoom(): number {
|
|
221
|
-
return this.config.zoom ||
|
|
222
|
-
defaultValues.zoom;
|
|
250
|
+
return this.config.zoom || defaultValues.zoom;
|
|
223
251
|
}
|
|
224
252
|
|
|
225
253
|
set zoom(zoom: number) {
|
|
@@ -234,8 +262,7 @@ export class Properties {
|
|
|
234
262
|
* - 'body', by default.
|
|
235
263
|
*/
|
|
236
264
|
get element(): string {
|
|
237
|
-
return this.config.element ||
|
|
238
|
-
defaultValues.element;
|
|
265
|
+
return this.config.element || defaultValues.element;
|
|
239
266
|
}
|
|
240
267
|
|
|
241
268
|
set element(element: string) {
|
|
@@ -250,8 +277,7 @@ export class Properties {
|
|
|
250
277
|
* - true, by default.
|
|
251
278
|
*/
|
|
252
279
|
get wirispluginperformance(): Wirispluginperformance {
|
|
253
|
-
return this.config.backendConfig.wirispluginperformance ||
|
|
254
|
-
defaultValues.backendConfig.wirispluginperformance;
|
|
280
|
+
return this.config.backendConfig.wirispluginperformance || defaultValues.backendConfig.wirispluginperformance;
|
|
255
281
|
}
|
|
256
282
|
|
|
257
283
|
set wirispluginperformance(wirispluginperformance: Wirispluginperformance) {
|
|
@@ -266,8 +292,9 @@ export class Properties {
|
|
|
266
292
|
* - data-mathml, by default.
|
|
267
293
|
*/
|
|
268
294
|
get wiriseditormathmlattribute(): string {
|
|
269
|
-
return
|
|
270
|
-
defaultValues.backendConfig.wiriseditormathmlattribute
|
|
295
|
+
return (
|
|
296
|
+
this.config.backendConfig.wiriseditormathmlattribute || defaultValues.backendConfig.wiriseditormathmlattribute
|
|
297
|
+
);
|
|
271
298
|
}
|
|
272
299
|
|
|
273
300
|
set wiriseditormathmlattribute(wiriseditormathmlattribute: string) {
|
package/src/retro.ts
CHANGED
|
@@ -11,24 +11,29 @@ import { Properties } from "./properties";
|
|
|
11
11
|
export function bypassEncapsulation(properties: Properties, w: Window) {
|
|
12
12
|
const wany = w as any;
|
|
13
13
|
|
|
14
|
-
if (typeof wany.com ===
|
|
14
|
+
if (typeof wany.com === "undefined") {
|
|
15
15
|
wany.com = {};
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
if (typeof wany.com.wiris ===
|
|
18
|
+
if (typeof wany.com.wiris === "undefined") {
|
|
19
19
|
wany.com.wiris = {};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
if (typeof wany.com.wiris.js ===
|
|
22
|
+
if (typeof wany.com.wiris.js === "undefined") {
|
|
23
23
|
wany.com.wiris.js = {};
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
if (typeof wany.com.wiris.js.JsPluginViewer ===
|
|
26
|
+
if (typeof wany.com.wiris.js.JsPluginViewer === "undefined") {
|
|
27
27
|
wany.com.wiris.js.JsPluginViewer = JsPluginViewer.getInstance();
|
|
28
28
|
JsPluginViewer.properties = properties;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
interface MathMLPosition {
|
|
33
|
+
nextElement: Node;
|
|
34
|
+
safeMML: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
/**
|
|
33
38
|
* This class is a compatibility layer with the old Viewer.
|
|
34
39
|
* See haxe/src-haxe/com/wiris/js/JsPluginViewer.hx in in the repo wiris/plugins previous to commit df1248a.
|
|
@@ -58,12 +63,12 @@ class JsPluginViewer {
|
|
|
58
63
|
* Please consider using {@link renderLatex} or {@link renderMathML}.
|
|
59
64
|
*/
|
|
60
65
|
parseSafeMathMLElement(element: HTMLElement, asynchronously?: boolean, callbackFunc?: () => void): void {
|
|
61
|
-
var mathmlPositions = [];
|
|
66
|
+
var mathmlPositions: MathMLPosition[] = [];
|
|
62
67
|
JsPluginViewer.getMathMLPositionsAtElementAndChildren(element, mathmlPositions);
|
|
63
68
|
for (let i = 0; i < mathmlPositions.length; i++) {
|
|
64
69
|
var mathmlPosition = mathmlPositions[i];
|
|
65
70
|
var newNode = document.createElement("math");
|
|
66
|
-
mathmlPosition.nextElement.parentNode
|
|
71
|
+
mathmlPosition.nextElement.parentNode?.insertBefore(newNode, mathmlPosition.nextElement);
|
|
67
72
|
newNode.outerHTML = JsPluginViewer.decodeSafeMathML(mathmlPosition.safeMML);
|
|
68
73
|
}
|
|
69
74
|
}
|
|
@@ -122,7 +127,6 @@ class JsPluginViewer {
|
|
|
122
127
|
var doubleQuoteEntity = safeXMLCharactersEntities.doubleQuote;
|
|
123
128
|
var realDoubleQuoteEntity = safeXMLCharactersEntities.realDoubleQuote;
|
|
124
129
|
|
|
125
|
-
|
|
126
130
|
// Important to not change function parameter.
|
|
127
131
|
var inputCopy = input.slice();
|
|
128
132
|
|
|
@@ -148,25 +152,26 @@ class JsPluginViewer {
|
|
|
148
152
|
|
|
149
153
|
// We are replacing $ by & when its part of an entity for retrocompatibility.
|
|
150
154
|
// Now, the standard is replace § by &.
|
|
151
|
-
var returnValue =
|
|
152
|
-
var currentEntity = null;
|
|
155
|
+
var returnValue = "";
|
|
156
|
+
var currentEntity: string | null = null;
|
|
153
157
|
|
|
154
158
|
var i = 0;
|
|
155
159
|
while (i < inputCopy.length) {
|
|
156
160
|
var character = inputCopy.charAt(i);
|
|
157
161
|
if (currentEntity == null) {
|
|
158
|
-
if (character ==
|
|
159
|
-
currentEntity =
|
|
162
|
+
if (character == "$") {
|
|
163
|
+
currentEntity = "";
|
|
160
164
|
} else {
|
|
161
165
|
returnValue += character;
|
|
162
166
|
}
|
|
163
|
-
} else if (character ==
|
|
164
|
-
returnValue +=
|
|
167
|
+
} else if (character == ";") {
|
|
168
|
+
returnValue += "&" + currentEntity;
|
|
165
169
|
currentEntity = null;
|
|
166
|
-
} else if (character.match(/([a-zA-Z0-9#._-] | '-')/)) {
|
|
170
|
+
} else if (character.match(/([a-zA-Z0-9#._-] | '-')/)) {
|
|
171
|
+
// Character is part of an entity.
|
|
167
172
|
currentEntity += character;
|
|
168
173
|
} else {
|
|
169
|
-
returnValue +=
|
|
174
|
+
returnValue += "$" + "currentEntity"; // Is not an entity.
|
|
170
175
|
currentEntity = null;
|
|
171
176
|
i -= 1; // Parse again the current character.
|
|
172
177
|
}
|
|
@@ -176,7 +181,7 @@ class JsPluginViewer {
|
|
|
176
181
|
return returnValue;
|
|
177
182
|
}
|
|
178
183
|
|
|
179
|
-
private static getMathMLPositionsAtElementAndChildren(element: Node, mathmlPositions) {
|
|
184
|
+
private static getMathMLPositionsAtElementAndChildren(element: Node, mathmlPositions: MathMLPosition[]) {
|
|
180
185
|
JsPluginViewer.getMathMLPositionsAtNode(element, mathmlPositions);
|
|
181
186
|
// Copy current children because DOM will be changed and element.childNodes won't be
|
|
182
187
|
// consistent on call getMathMLPositionsAtElementAndChildren().
|
|
@@ -191,66 +196,66 @@ class JsPluginViewer {
|
|
|
191
196
|
|
|
192
197
|
private static getMathMLPositionsAtNode(node: Node, mathmlPositions) {
|
|
193
198
|
var safeXMLCharacters = JsCharacters.getSafeXMLCharacters();
|
|
194
|
-
if(node.nodeType == 3) {
|
|
199
|
+
if (node.nodeType == 3) {
|
|
195
200
|
var startMathmlTag = safeXMLCharacters.tagOpener + "math";
|
|
196
201
|
var endMathmlTag = safeXMLCharacters.tagOpener + "/math" + safeXMLCharacters.tagCloser;
|
|
197
|
-
var start = node.textContent
|
|
202
|
+
var start = node.textContent?.indexOf(startMathmlTag) ?? -1;
|
|
198
203
|
var end = 0;
|
|
199
|
-
while(start != -1) {
|
|
200
|
-
end = node.textContent
|
|
204
|
+
while (start != -1) {
|
|
205
|
+
end = node.textContent?.indexOf(endMathmlTag, start + startMathmlTag.length) ?? -1;
|
|
201
206
|
|
|
202
|
-
if(end == -1) break;
|
|
207
|
+
if (end == -1) break;
|
|
203
208
|
|
|
204
|
-
var nextMathML = node.textContent
|
|
209
|
+
var nextMathML = node.textContent?.indexOf(startMathmlTag, end + endMathmlTag.length) ?? -1;
|
|
205
210
|
|
|
206
|
-
if(nextMathML >= 0 && end > nextMathML) break;
|
|
211
|
+
if (nextMathML >= 0 && end > nextMathML) break;
|
|
207
212
|
|
|
208
|
-
var safeMathml = node.textContent
|
|
213
|
+
var safeMathml = node.textContent?.substring(start, end + endMathmlTag.length);
|
|
209
214
|
|
|
210
|
-
node.textContent =
|
|
215
|
+
node.textContent =
|
|
216
|
+
(node.textContent?.substring(0, start) ?? "") + node.textContent?.substring(end + endMathmlTag.length);
|
|
211
217
|
node = (node as Text).splitText(start);
|
|
212
|
-
start = node.textContent
|
|
218
|
+
start = node.textContent?.indexOf(startMathmlTag) ?? -1;
|
|
213
219
|
|
|
214
220
|
mathmlPositions.push({
|
|
215
221
|
safeMML: safeMathml,
|
|
216
|
-
nextElement: node
|
|
222
|
+
nextElement: node,
|
|
217
223
|
});
|
|
218
224
|
}
|
|
219
225
|
}
|
|
220
226
|
}
|
|
221
|
-
|
|
222
227
|
}
|
|
223
228
|
|
|
224
229
|
class JsCharacters {
|
|
225
230
|
static getSafeXMLCharactersEntities(): any {
|
|
226
231
|
return {
|
|
227
|
-
tagOpener:
|
|
228
|
-
tagCloser:
|
|
229
|
-
doubleQuote:
|
|
230
|
-
realDoubleQuote:
|
|
232
|
+
tagOpener: "«",
|
|
233
|
+
tagCloser: "»",
|
|
234
|
+
doubleQuote: "¨",
|
|
235
|
+
realDoubleQuote: """,
|
|
231
236
|
};
|
|
232
237
|
}
|
|
233
238
|
|
|
234
239
|
static getXMLCharacters(): any {
|
|
235
240
|
return {
|
|
236
|
-
id:
|
|
237
|
-
tagOpener:
|
|
238
|
-
tagCloser:
|
|
241
|
+
id: "xmlCharacters",
|
|
242
|
+
tagOpener: "<", // Hex: \x3C.
|
|
243
|
+
tagCloser: ">", // Hex: \x3E.
|
|
239
244
|
doubleQuote: '"', // Hex: \x22.
|
|
240
|
-
ampersand:
|
|
241
|
-
quote: '
|
|
245
|
+
ampersand: "&", // Hex: \x26.
|
|
246
|
+
quote: "'", // Hex: \x27.
|
|
242
247
|
};
|
|
243
248
|
}
|
|
244
249
|
|
|
245
250
|
static getSafeXMLCharacters(): any {
|
|
246
251
|
return {
|
|
247
|
-
id:
|
|
248
|
-
tagOpener:
|
|
249
|
-
tagCloser:
|
|
250
|
-
doubleQuote:
|
|
251
|
-
ampersand:
|
|
252
|
-
quote:
|
|
253
|
-
realDoubleQuote:
|
|
252
|
+
id: "safeXmlCharacters",
|
|
253
|
+
tagOpener: "«", // Hex: \xAB.
|
|
254
|
+
tagCloser: "»", // Hex: \xBB.
|
|
255
|
+
doubleQuote: "¨", // Hex: \xA8.
|
|
256
|
+
ampersand: "§", // Hex: \xA7.
|
|
257
|
+
quote: "`", // Hex: \x60.
|
|
258
|
+
realDoubleQuote: "¨",
|
|
254
259
|
};
|
|
255
260
|
}
|
|
256
261
|
}
|