ep_special_characters 0.0.60 → 0.0.62
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/.github/workflows/backend-tests.yml +1 -1
- package/.github/workflows/frontend-tests.yml +1 -1
- package/.github/workflows/npmpublish.yml +1 -1
- package/README.md +0 -5
- package/ep.json +1 -0
- package/package.json +1 -1
- package/static/js/hooks.js +4 -0
- package/static/js/main.js +22 -11
- package/static/tests/frontend-new/specs/smoke.spec.ts +23 -0
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
# OIDC trusted publishing needs npm >= 11.5.1, which requires
|
|
24
24
|
# Node >= 20.17.0. setup-node's `20` resolves to the latest
|
|
25
25
|
# 20.x, which satisfies that.
|
|
26
|
-
node-version:
|
|
26
|
+
node-version: 25
|
|
27
27
|
registry-url: https://registry.npmjs.org/
|
|
28
28
|
- name: Upgrade npm to >=11.5.1 (required for trusted publishing)
|
|
29
29
|
run: npm install -g npm@latest
|
package/README.md
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
[](https://github.com/ether/ep_special_characters/actions/workflows/test-and-release.yml)
|
|
2
2
|
|
|
3
|
-
> ⚠️ **Known issue:** Clicking a character in the picker currently throws
|
|
4
|
-
> `ReferenceError: require is not defined` because [`static/js/main.js:16`](static/js/main.js)
|
|
5
|
-
> uses a browser-side `require()` that Etherpad's current esbuild bundler
|
|
6
|
-
> doesn't expose. Tracking fix in [#87](https://github.com/ether/ep_special_characters/issues/87).
|
|
7
|
-
|
|
8
3
|
# Special Character Picker for Etherpad
|
|
9
4
|
TODO: Describe the plugin.
|
|
10
5
|
|
package/ep.json
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"eejsBlock_dd_insert" : "ep_special_characters/hooks"
|
|
11
11
|
},
|
|
12
12
|
"client_hooks": {
|
|
13
|
+
"postAceInit": "ep_special_characters/static/js/hooks:postAceInit",
|
|
13
14
|
"aceInitInnerdocbodyHead": "ep_special_characters/static/js/hooks:aceInitInnerdocbodyHead",
|
|
14
15
|
"aceAttribsToClasses": "ep_special_characters/static/js/hooks:aceAttribsToClasses",
|
|
15
16
|
"aceCreateDomLine": "ep_special_characters/static/js/hooks:aceCreateDomLine"
|
package/package.json
CHANGED
package/static/js/hooks.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
exports.postAceInit = (hookName, context) => {
|
|
4
|
+
window.epSpecialCharactersAce = context.ace;
|
|
5
|
+
};
|
|
6
|
+
|
|
3
7
|
exports.aceInitInnerdocbodyHead = (hookName, args, cb) => {
|
|
4
8
|
const path = '../static/plugins/ep_special_characters/static/css/ace.css';
|
|
5
9
|
args.iframeHTML.push(
|
package/static/js/main.js
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
$(document).ready(() => {
|
|
4
|
+
const SPECIAL_CHARACTER_START_CODE_POINT = 0x20;
|
|
5
|
+
const SPECIAL_CHARACTER_END_CODE_POINT = 0x2FF;
|
|
4
6
|
const module = $('#specialCharactersModal');
|
|
7
|
+
const specialChars = $('.specialChars');
|
|
8
|
+
let isSpecialCharactersPopulated = false;
|
|
9
|
+
|
|
10
|
+
const populateSpecialCharacters = () => {
|
|
11
|
+
if (isSpecialCharactersPopulated) return;
|
|
12
|
+
const chars = [];
|
|
13
|
+
for (let i = SPECIAL_CHARACTER_START_CODE_POINT; i <= SPECIAL_CHARACTER_END_CODE_POINT; i++) {
|
|
14
|
+
chars.push(`<li class='specialChar'>&#${i}</li>`);
|
|
15
|
+
}
|
|
16
|
+
specialChars.append(chars.join(''));
|
|
17
|
+
isSpecialCharactersPopulated = true;
|
|
18
|
+
};
|
|
19
|
+
|
|
5
20
|
$('.insertSpecialCharacter').click(() => {
|
|
21
|
+
populateSpecialCharacters();
|
|
6
22
|
module.toggleClass('popup-show');
|
|
7
23
|
});
|
|
8
24
|
|
|
@@ -13,18 +29,13 @@ $(document).ready(() => {
|
|
|
13
29
|
const char = ($(this).text());
|
|
14
30
|
$('.usedSpecialCharacters').append(this);
|
|
15
31
|
$('.usedSpecialCharactersLabel').show();
|
|
16
|
-
const
|
|
32
|
+
const ace = window.epSpecialCharactersAce;
|
|
17
33
|
module.toggleClass('popup-show');
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
34
|
+
if (!ace) return;
|
|
35
|
+
return ace.callWithAce((editor) => {
|
|
36
|
+
const rep = editor.ace_getRep();
|
|
37
|
+
editor.ace_replaceRange(rep.selStart, rep.selEnd, char);
|
|
38
|
+
editor.ace_focus();
|
|
22
39
|
}, 'specialCharacters');
|
|
23
40
|
});
|
|
24
|
-
|
|
25
|
-
let i = 0;
|
|
26
|
-
while (i <= 5000) {
|
|
27
|
-
$('.specialChars').append(`<li class='specialChar'>&#${i}</li>`);
|
|
28
|
-
i++;
|
|
29
|
-
}
|
|
30
41
|
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {expect, test} from '@playwright/test';
|
|
2
2
|
import {getPadBody, goToNewPad} from 'ep_etherpad-lite/tests/frontend-new/helper/padHelper';
|
|
3
3
|
|
|
4
|
+
const expectedSpecialCharacterCount = (0x2FF - 0x20) + 1;
|
|
5
|
+
|
|
4
6
|
test.beforeEach(async ({page}) => {
|
|
5
7
|
await goToNewPad(page);
|
|
6
8
|
});
|
|
@@ -10,4 +12,25 @@ test.describe('ep_special_characters', () => {
|
|
|
10
12
|
const padBody = await getPadBody(page);
|
|
11
13
|
await expect(padBody).toBeVisible();
|
|
12
14
|
});
|
|
15
|
+
|
|
16
|
+
test('special characters are populated lazily on first modal open', async ({page}) => {
|
|
17
|
+
await expect(page.locator('.specialChars .specialChar')).toHaveCount(0);
|
|
18
|
+
|
|
19
|
+
await page.locator('.insertSpecialCharacter').first().click();
|
|
20
|
+
await expect(page.locator('#specialCharactersModal')).toHaveClass(/popup-show/);
|
|
21
|
+
await expect(page.locator('.specialChars .specialChar')).toHaveCount(expectedSpecialCharacterCount);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('clicking a special character inserts it without page errors', async ({page}) => {
|
|
25
|
+
const pageErrors: Error[] = [];
|
|
26
|
+
page.on('pageerror', (error) => pageErrors.push(error));
|
|
27
|
+
const padBody = await getPadBody(page);
|
|
28
|
+
await padBody.click();
|
|
29
|
+
|
|
30
|
+
await page.locator('.insertSpecialCharacter').first().click();
|
|
31
|
+
await page.locator('.specialChars .specialChar', {hasText: 'Æ'}).first().click();
|
|
32
|
+
|
|
33
|
+
await expect(padBody).toContainText('Æ');
|
|
34
|
+
expect(pageErrors).toEqual([]);
|
|
35
|
+
});
|
|
13
36
|
});
|