Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 52ffe6c

Browse files
Zyntondmo-odoo
authored andcommitted
[IMP] Fontawesome: only surround fa when close to range
1 parent c77b8c9 commit 52ffe6c

File tree

4 files changed

+84
-53
lines changed

4 files changed

+84
-53
lines changed

packages/plugin-dom-layout/test/DomLayout.test.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -880,11 +880,7 @@ describe('DomLayout', () => {
880880

881881
const engine = editor.plugins.get(Layout).engines.dom as DomLayoutEngine;
882882
const domFa = container.querySelector('i');
883-
expect(engine.getDomNodes(fa)).to.deep.equal([
884-
domFa.previousSibling,
885-
domFa,
886-
domFa.nextSibling,
887-
]);
883+
expect(engine.getDomNodes(fa)).to.deep.equal([domFa]);
888884
await editor.stop();
889885
});
890886
});

packages/plugin-fontawesome/src/FontAwesomeDomObjectRenderer.ts

Lines changed: 64 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
DomObjectElement,
99
} from '../../plugin-renderer-dom-object/src/DomObjectRenderingEngine';
1010
import { RenderingEngineWorker } from '../../plugin-renderer/src/RenderingEngineCache';
11+
import { RuleProperty } from '../../core/src/Mode';
12+
import { CharNode } from '../../plugin-char/src/CharNode';
1113

1214
const zeroWidthSpace = '\u200b';
1315

@@ -43,38 +45,71 @@ export class FontAwesomeDomObjectRenderer extends NodeRenderer<DomObject> {
4345
el.removeEventListener('mouseup', select, true);
4446
},
4547
};
46-
// Surround the fontawesome with two invisible characters so the
47-
// selection can navigate around it.
48-
const domObject: DomObjectFragment = {
49-
children: [
50-
// We are targetting the invisible character BEFORE the
51-
// fontawesome node.
52-
// If offset 1:
53-
// Moving from before the fontawesome node to after it.
54-
// (DOM is `<invisible/>[]<fontawesome/><invisible/>` but
55-
// should be `<invisible/><fontawesome/><invisible/>[]`).
56-
// else:
57-
// Stay before the fontawesome node.
58-
{ text: zeroWidthSpace },
59-
// If we are targetting the fontawesome directyle then stay
60-
// before the fontawesome node.
61-
fontawesome,
62-
// We are targetting the invisible character AFTER the
63-
// fontawesome node.
64-
// If offset 0:
65-
// Moving from after the fontawesome node to before it.
66-
// (DOM is `<invisible/><fontawesome/>[]<invisible/>` but
67-
// should be `[]<invisible/><fontawesome/><invisible/>`).
68-
// else:
69-
// Stay after the fontawesome node.
70-
{ text: zeroWidthSpace },
71-
],
72-
};
7348

74-
worker.locate([node], domObject.children[0] as DomObjectText);
49+
let domObject: DomObjectFragment;
50+
if (this.shouldAddNavigationHelpers(node)) {
51+
// Surround the fontawesome with two invisible characters so the
52+
// selection can navigate around it.
53+
domObject = {
54+
children: [
55+
// We are targetting the invisible character BEFORE the
56+
// fontawesome node.
57+
// If offset 1:
58+
// Moving from before the fontawesome node to after it.
59+
// (DOM is `<invisible/>[]<fontawesome/><invisible/>` but
60+
// should be `<invisible/><fontawesome/><invisible/>[]`).
61+
// else:
62+
// Stay before the fontawesome node.
63+
{ text: zeroWidthSpace },
64+
// If we are targetting the fontawesome directyle then stay
65+
// before the fontawesome node.
66+
fontawesome,
67+
// We are targetting the invisible character AFTER the
68+
// fontawesome node.
69+
// If offset 0:
70+
// Moving from after the fontawesome node to before it.
71+
// (DOM is `<invisible/><fontawesome/>[]<invisible/>` but
72+
// should be `[]<invisible/><fontawesome/><invisible/>`).
73+
// else:
74+
// Stay after the fontawesome node.
75+
{ text: zeroWidthSpace },
76+
],
77+
};
78+
79+
worker.locate([node], domObject.children[0] as DomObjectText);
80+
worker.locate([node], domObject.children[2] as DomObjectText);
81+
} else {
82+
domObject = { children: [fontawesome] };
83+
}
7584
worker.locate([node], fontawesome);
76-
worker.locate([node], domObject.children[2] as DomObjectText);
7785

7886
return domObject;
7987
}
88+
89+
//--------------------------------------------------------------------------
90+
// Private
91+
//--------------------------------------------------------------------------
92+
93+
/**
94+
* Return true if the current context justifies putting a mechanism in place
95+
* to permit navigation around the rendered font awesome node.
96+
*
97+
* @param node
98+
*/
99+
shouldAddNavigationHelpers(node: FontAwesomeNode): boolean {
100+
const range = this.engine.editor.selection.range;
101+
// Is parent editable.
102+
if (node.parent && !range.mode.is(node.parent, RuleProperty.EDITABLE)) {
103+
return false;
104+
}
105+
// Is node next to range.
106+
if (range.start.nextSibling() === node ||
107+
range.start.previousSibling() === node ||
108+
range.end.nextSibling() === node ||
109+
range.end.previousSibling() === node) {
110+
return true;
111+
} else {
112+
return false;
113+
}
114+
}
80115
}

packages/plugin-fontawesome/test/FontAwesome.test.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,88 +17,88 @@ describePlugin(FontAwesome, testEditor => {
1717
it('should parse an old-school fontawesome', async () => {
1818
await testEditor(BasicEditor, {
1919
contentBefore: '<p><i class="fa fa-star"></i></p>',
20-
contentAfter: '<p>\u200b<i class="fa fa-star"></i>\u200b</p>',
20+
contentAfter: '<p><i class="fa fa-star"></i></p>',
2121
});
2222
});
2323
it('should parse a brand fontawesome', async () => {
2424
await testEditor(BasicEditor, {
2525
contentBefore: '<p><i class="fab fa-opera"></i></p>',
26-
contentAfter: '<p>\u200b<i class="fab fa-opera"></i>\u200b</p>',
26+
contentAfter: '<p><i class="fab fa-opera"></i></p>',
2727
});
2828
});
2929
it('should parse a duotone fontawesome', async () => {
3030
await testEditor(BasicEditor, {
3131
contentBefore: '<p><i class="fad fa-bus-alt"></i></p>',
32-
contentAfter: '<p>\u200b<i class="fad fa-bus-alt"></i>\u200b</p>',
32+
contentAfter: '<p><i class="fad fa-bus-alt"></i></p>',
3333
});
3434
});
3535
it('should parse a light fontawesome', async () => {
3636
await testEditor(BasicEditor, {
3737
contentBefore: '<p><i class="fab fa-accessible-icon"></i></p>',
38-
contentAfter: '<p>\u200b<i class="fab fa-accessible-icon"></i>\u200b</p>',
38+
contentAfter: '<p><i class="fab fa-accessible-icon"></i></p>',
3939
});
4040
});
4141
it('should parse a regular fontawesome', async () => {
4242
await testEditor(BasicEditor, {
4343
contentBefore: '<p><i class="far fa-money-bill-alt"></i></p>',
44-
contentAfter: '<p>\u200b<i class="far fa-money-bill-alt"></i>\u200b</p>',
44+
contentAfter: '<p><i class="far fa-money-bill-alt"></i></p>',
4545
});
4646
});
4747
it('should parse a solid fontawesome', async () => {
4848
await testEditor(BasicEditor, {
4949
contentBefore: '<p><i class="fa fa-pastafarianism"></i></span></p>',
50-
contentAfter: '<p>\u200b<i class="fa fa-pastafarianism"></i>\u200b</p>',
50+
contentAfter: '<p><i class="fa fa-pastafarianism"></i></p>',
5151
});
5252
});
5353
it('should parse a fontawesome in a <span>', async () => {
5454
await testEditor(BasicEditor, {
5555
contentBefore: '<p><span class="fa fa-pastafarianism"></span></p>',
56-
contentAfter: '<p>\u200b<span class="fa fa-pastafarianism"></span>\u200b</p>',
56+
contentAfter: '<p><span class="fa fa-pastafarianism"></span></p>',
5757
});
5858
});
5959
it('should parse a fontawesome in a <i>', async () => {
6060
await testEditor(BasicEditor, {
6161
contentBefore: '<p><i class="fa fa-pastafarianism"></i></i></p>',
62-
contentAfter: '<p>\u200b<i class="fa fa-pastafarianism"></i>\u200b</p>',
62+
contentAfter: '<p><i class="fa fa-pastafarianism"></i></p>',
6363
});
6464
});
6565
it('should parse a fontawesome with more classes', async () => {
6666
await testEditor(BasicEditor, {
6767
contentBefore: '<p><i class="red fa bordered fa-pastafarianism big"></i></p>',
6868
contentAfter:
69-
'<p>\u200b<i class="red fa bordered fa-pastafarianism big"></i>\u200b</p>',
69+
'<p><i class="red fa bordered fa-pastafarianism big"></i></p>',
7070
});
7171
});
7272
it('should parse a fontawesome with multi-line classes', async () => {
7373
await testEditor(BasicEditor, {
7474
contentBefore: `<p><i class="fa
7575
fa-pastafarianism"></i></p>`,
76-
contentAfter: `<p>\u200b<i class="fa fa-pastafarianism"></i>\u200b</p>`,
76+
contentAfter: `<p><i class="fa fa-pastafarianism"></i></p>`,
7777
});
7878
});
7979
it('should parse a fontawesome with more multi-line classes', async () => {
8080
await testEditor(BasicEditor, {
8181
contentBefore: `<p><i class="red fa bordered
8282
big fa-pastafarianism scary"></i></p>`,
83-
contentAfter: `<p>\u200b<i class="red fa bordered big fa-pastafarianism scary"></i>\u200b</p>`,
83+
contentAfter: `<p><i class="red fa bordered big fa-pastafarianism scary"></i></p>`,
8484
});
8585
});
8686
it('should parse a fontawesome at the beginning of a paragraph', async () => {
8787
await testEditor(BasicEditor, {
8888
contentBefore: '<p><i class="fa fa-pastafarianism"></i>a[b]c</p>',
89-
contentAfter: '<p>\u200b<i class="fa fa-pastafarianism"></i>\u200ba[b]c</p>',
89+
contentAfter: '<p><i class="fa fa-pastafarianism"></i>a[b]c</p>',
9090
});
9191
});
9292
it('should parse a fontawesome in the middle of a paragraph', async () => {
9393
await testEditor(BasicEditor, {
9494
contentBefore: '<p>a[b]c<i class="fa fa-pastafarianism"></i>def</p>',
95-
contentAfter: '<p>a[b]c\u200b<i class="fa fa-pastafarianism"></i>\u200bdef</p>',
95+
contentAfter: '<p>a[b]c<i class="fa fa-pastafarianism"></i>def</p>',
9696
});
9797
});
9898
it('should parse a fontawesome at the end of a paragraph', async () => {
9999
await testEditor(BasicEditor, {
100100
contentBefore: '<p>a[b]c<i class="fa fa-pastafarianism"></i></p>',
101-
contentAfter: '<p>a[b]c\u200b<i class="fa fa-pastafarianism"></i>\u200b</p>',
101+
contentAfter: '<p>a[b]c<i class="fa fa-pastafarianism"></i></p>',
102102
});
103103
});
104104
});
@@ -117,7 +117,7 @@ describePlugin(FontAwesome, testEditor => {
117117
contentBefore: '<p>ab<i class="fa fa-pastafarianism"></i>[]cd</p>',
118118
stepFunction: deleteForward,
119119
contentAfter:
120-
'<p>ab\u200b<i class="fa fa-pastafarianism"></i>\u200b[]d</p>',
120+
'<p>ab\u200B<i class="fa fa-pastafarianism"></i>\u200B[]d</p>',
121121
});
122122
});
123123
});
@@ -156,7 +156,7 @@ describePlugin(FontAwesome, testEditor => {
156156
contentBefore: '<p>ab[]<i class="fa fa-pastafarianism"></i>cd</p>',
157157
stepFunction: deleteBackward,
158158
contentAfter:
159-
'<p>a[]\u200b<i class="fa fa-pastafarianism"></i>\u200bcd</p>',
159+
'<p>a[]\u200B<i class="fa fa-pastafarianism"></i>\u200Bcd</p>',
160160
});
161161
});
162162
});
@@ -187,7 +187,7 @@ describePlugin(FontAwesome, testEditor => {
187187
stepFunction: async editor => {
188188
await editor.execCommand<Char>('insertText', { text: 's' });
189189
},
190-
contentAfter: '<p>abs[]\u200b<i class="fa fa-pastafarianism"></i>\u200bcd</p>',
190+
contentAfter: '<p>abs[]\u200B<i class="fa fa-pastafarianism"></i>\u200Bcd</p>',
191191
});
192192
});
193193
it('should insert a character after', async () => {
@@ -196,7 +196,7 @@ describePlugin(FontAwesome, testEditor => {
196196
stepFunction: async editor => {
197197
await editor.execCommand<Char>('insertText', { text: 's' });
198198
},
199-
contentAfter: '<p>ab\u200b<i class="fa fa-pastafarianism"></i>\u200bs[]cd</p>',
199+
contentAfter: '<p>ab<i class="fa fa-pastafarianism"></i>s[]cd</p>',
200200
});
201201
});
202202
});

packages/plugin-odoo/src/OdooFontAwesomeDomObjectRenderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class OdooFontAwesomeDomObjectRenderer extends FontAwesomeDomObjectRender
1212
): Promise<DomObject> {
1313
const domObject: DomObject = await super.render(node, worker);
1414
if (domObject && 'children' in domObject) {
15-
const fa = domObject.children[1];
15+
const fa = domObject.children[1] || domObject.children[0];
1616

1717
if ('tag' in fa) {
1818
const dbclickCallback = (): void => {

0 commit comments

Comments
 (0)