Skip to content

Commit b7a7aa7

Browse files
committed
fix image domparser when rewrite is in use
This also uses the browser's URL parser instead of parsing it ourselves.
1 parent e35b45a commit b7a7aa7

File tree

1 file changed

+67
-58
lines changed

1 file changed

+67
-58
lines changed

script/schema.js

+67-58
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
* extends the basic schemas provided by ProseMirror
55
*/
66

7-
import { schema as schemaBasic } from 'prosemirror-schema-basic';
8-
import { tableNodes } from 'prosemirror-tables';
9-
import { bulletList, listItem, orderedList } from 'prosemirror-schema-list';
7+
import {schema as schemaBasic} from 'prosemirror-schema-basic';
8+
import {tableNodes} from 'prosemirror-tables';
9+
import {bulletList, listItem, orderedList} from 'prosemirror-schema-list';
1010

1111
export default function getSpec() {
12-
let { nodes, marks } = schemaBasic.spec;
12+
let {nodes, marks} = schemaBasic.spec;
1313

1414
const doc = nodes.get('doc');
1515
doc.content = '(block | baseonly | container | protected_block | substitution_block)+';
1616
doc.attrs = {
17-
nocache: { default: false },
18-
notoc: { default: false },
17+
nocache: {default: false},
18+
notoc: {default: false},
1919
};
2020
nodes = nodes.update('doc', doc);
2121

@@ -58,7 +58,7 @@ export default function getSpec() {
5858

5959
const tableNode = nodes.get('table');
6060
tableNode.toDOM = function toDOM() {
61-
return ['div', { class: 'table' }, ['table', { class: 'inline' }, ['tbody', 0]]];
61+
return ['div', {class: 'table'}, ['table', {class: 'inline'}, ['tbody', 0]]];
6262
};
6363
nodes.update('table', tableNode);
6464

@@ -69,15 +69,15 @@ export default function getSpec() {
6969
group: 'protected_block',
7070
code: true,
7171
toDOM() {
72-
return ['pre', { class: 'code' }, 0];
72+
return ['pre', {class: 'code'}, 0];
7373
},
7474
});
7575

7676
const codeBlock = nodes.get('code_block');
7777
codeBlock.attrs = {
78-
class: { default: 'code' },
79-
'data-filename': { default: '' },
80-
'data-language': { default: '' },
78+
class: {default: 'code'},
79+
'data-filename': {default: ''},
80+
'data-language': {default: ''},
8181
};
8282
codeBlock.toDOM = function toDOM(node) {
8383
return ['pre', node.attrs, 0];
@@ -88,16 +88,16 @@ export default function getSpec() {
8888
const quote = nodes.get('blockquote');
8989
quote.content = '(block | blockquote | protected_block)+';
9090
quote.group = 'container';
91-
quote.toDom = () => ['blockquote', {}, ['div', { class: 'no' }, 0]];
91+
quote.toDom = () => ['blockquote', {}, ['div', {class: 'no'}, 0]];
9292
nodes.update('blockquote', quote);
9393

9494
const imageNode = nodes.get('image');
95-
imageNode.attrs.width = { default: '' };
96-
imageNode.attrs.height = { default: '' };
97-
imageNode.attrs.align = { default: '' };
98-
imageNode.attrs.linking = { default: '' };
99-
imageNode.attrs.cache = { default: '' };
100-
imageNode.attrs['data-resolvedHtml'] = { default: '' };
95+
imageNode.attrs.width = {default: ''};
96+
imageNode.attrs.height = {default: ''};
97+
imageNode.attrs.align = {default: ''};
98+
imageNode.attrs.linking = {default: ''};
99+
imageNode.attrs.cache = {default: ''};
100+
imageNode.attrs['data-resolvedHtml'] = {default: ''};
101101
imageNode.attrs.id = {};
102102
delete imageNode.attrs.src;
103103
imageNode.parseDOM = [
@@ -106,16 +106,24 @@ export default function getSpec() {
106106
getAttrs: function getAttrs(dom) {
107107
const src = dom.getAttribute('src');
108108
const dokuWikiFetch = `${DOKU_BASE}lib/exe/fetch.php`;
109-
if (!src.includes(dokuWikiFetch)) {
109+
const dokuWikiMedia = `${DOKU_BASE}_media/`;
110+
111+
let id = '';
112+
let url;
113+
try {
114+
url = new URL(src, window.location.href);
115+
} catch (e) {
110116
return undefined; // let another rule handle this case
111117
}
112-
const [, query] = src.split('?');
113-
const attrs = query.split('&')
114-
.map(item => item.split('='))
115-
.reduce((acc, [key, value]) => {
116-
acc[key] = decodeURIComponent(value);
117-
return acc;
118-
}, {});
118+
119+
if (src.includes(dokuWikiFetch)) {
120+
id = url.searchParams.get('media');
121+
} else if (src.includes(dokuWikiMedia)) {
122+
id = url.pathname.split('/').pop();
123+
id = id.replaceAll(';', ':'); // on windows, semicolons might be used as namespace separator
124+
}
125+
if (!id) return undefined; // let another rule handle this case
126+
119127
let align = '';
120128
if (dom.classList.contains('medialeft')) {
121129
align = 'left';
@@ -124,12 +132,13 @@ export default function getSpec() {
124132
} else if (dom.classList.contains('mediacenter')) {
125133
align = 'center';
126134
}
135+
127136
return {
128137
// a relative ID might be preferred (see imgpaste plugin)
129-
id: dom.dataset.relID || attrs.media,
138+
id: dom.dataset.relid || id,
130139
title: dom.getAttribute('alt'),
131-
width: attrs.w,
132-
height: attrs.h,
140+
width: url.searchParams.get('w'),
141+
height: url.searchParams.get('h'),
133142
align,
134143
'data-resolvedHtml': dom.outerHTML,
135144
};
@@ -153,7 +162,7 @@ export default function getSpec() {
153162

154163
const imageAttrs = {};
155164
Object.keys(imageNode.attrs).forEach((key) => {
156-
imageAttrs[`image-${key}`] = { default: null };
165+
imageAttrs[`image-${key}`] = {default: null};
157166
});
158167

159168
nodes = nodes.addToEnd('link', {
@@ -162,13 +171,13 @@ export default function getSpec() {
162171
attrs: {
163172
'data-type': {},
164173
'data-inner': {},
165-
'data-name': { default: null },
166-
'data-resolvedID': { default: null },
167-
'data-resolvedUrl': { default: null },
168-
'data-resolvedName': { default: null },
169-
'data-resolvedClass': { default: null },
170-
'data-resolvedTitle': { default: null },
171-
'data-resolvedImage': { default: '' },
174+
'data-name': {default: null},
175+
'data-resolvedID': {default: null},
176+
'data-resolvedUrl': {default: null},
177+
'data-resolvedName': {default: null},
178+
'data-resolvedClass': {default: null},
179+
'data-resolvedTitle': {default: null},
180+
'data-resolvedImage': {default: ''},
172181
...imageAttrs,
173182
},
174183
toDOM(node) {
@@ -180,7 +189,7 @@ export default function getSpec() {
180189
content: '',
181190
marks: '',
182191
attrs: {
183-
contentJSON: { default: '' },
192+
contentJSON: {default: ''},
184193
},
185194
group: 'inline',
186195
inline: true,
@@ -209,7 +218,7 @@ export default function getSpec() {
209218
return false;
210219
}
211220
const syntax = dom.getAttribute('alt');
212-
return { icon, syntax };
221+
return {icon, syntax};
213222
},
214223
}],
215224
});
@@ -218,24 +227,24 @@ export default function getSpec() {
218227
group: 'substitution_block',
219228
atom: true,
220229
attrs: {
221-
class: { default: 'rss' },
230+
class: {default: 'rss'},
222231
url: {},
223-
max: { default: 8 },
224-
reverse: { default: null },
225-
author: { default: null },
226-
date: { default: null },
227-
details: { default: null },
228-
refresh: { default: '' },
229-
renderedHTML: { default: null },
232+
max: {default: 8},
233+
reverse: {default: null},
234+
author: {default: null},
235+
date: {default: null},
236+
details: {default: null},
237+
refresh: {default: ''},
238+
renderedHTML: {default: null},
230239
},
231240
});
232241

233242
nodes = nodes.addToEnd('dwplugin_block', {
234243
content: 'text*',
235244
marks: '',
236245
attrs: {
237-
class: { default: 'dwplugin' },
238-
'data-pluginname': { default: ' ' },
246+
class: {default: 'dwplugin'},
247+
'data-pluginname': {default: ' '},
239248
},
240249
draggable: true,
241250
inline: false,
@@ -252,8 +261,8 @@ export default function getSpec() {
252261
nodes = nodes.addToEnd('dwplugin_inline', {
253262
content: 'text*',
254263
attrs: {
255-
class: { default: 'dwplugin' },
256-
'data-pluginname': { default: ' ' },
264+
class: {default: 'dwplugin'},
265+
'data-pluginname': {default: ' '},
257266
},
258267
marks: '',
259268
draggable: true,
@@ -275,7 +284,7 @@ export default function getSpec() {
275284

276285
marks = marks.addToEnd('deleted', {
277286
parseDOM: [
278-
{ tag: 'del' },
287+
{tag: 'del'},
279288
{
280289
style: 'text-decoration',
281290
// https://discuss.prosemirror.net/t/dom-parsing-and-getattrs/612
@@ -289,7 +298,7 @@ export default function getSpec() {
289298

290299
marks = marks.addToEnd('underline', {
291300
parseDOM: [
292-
{ tag: 'u' },
301+
{tag: 'u'},
293302
{
294303
style: 'text-decoration',
295304
getAttrs: value => value === 'underline' && null,
@@ -302,7 +311,7 @@ export default function getSpec() {
302311

303312
marks = marks.addToEnd('subscript', {
304313
parseDOM: [
305-
{ tag: 'sub' },
314+
{tag: 'sub'},
306315
{
307316
style: 'vertical-align',
308317
getAttrs: value => value === 'sub' && null,
@@ -315,7 +324,7 @@ export default function getSpec() {
315324

316325
marks = marks.addToEnd('superscript', {
317326
parseDOM: [
318-
{ tag: 'sup' },
327+
{tag: 'sup'},
319328
{
320329
style: 'vertical-align',
321330
getAttrs: value => value === 'super' && null,
@@ -329,15 +338,15 @@ export default function getSpec() {
329338
marks = marks.addToEnd('unformatted', {
330339
excludes: '_',
331340
toDOM() {
332-
return ['span', { class: 'unformatted' }];
341+
return ['span', {class: 'unformatted'}];
333342
},
334343
});
335344

336345
if (window.Prosemirror && window.Prosemirror.pluginSchemas) {
337346
window.Prosemirror.pluginSchemas.forEach((addSchema) => {
338-
({ nodes, marks } = addSchema(nodes, marks));
347+
({nodes, marks} = addSchema(nodes, marks));
339348
});
340349
}
341350

342-
return { nodes, marks };
351+
return {nodes, marks};
343352
}

0 commit comments

Comments
 (0)