squiffy-runtime 6.0.0-alpha.7 → 6.0.0-alpha.8
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.
|
@@ -14,7 +14,7 @@ export interface SquiffyApi {
|
|
|
14
14
|
restart: () => void;
|
|
15
15
|
get: (attribute: string) => any;
|
|
16
16
|
set: (attribute: string, value: any) => void;
|
|
17
|
-
clickLink: (link: HTMLElement) =>
|
|
17
|
+
clickLink: (link: HTMLElement) => boolean;
|
|
18
18
|
update: (story: Story) => void;
|
|
19
19
|
}
|
|
20
20
|
interface SquiffyJsFunctionApi {
|
package/dist/squiffy.runtime.js
CHANGED
|
@@ -31,8 +31,11 @@ export const init = (options) => {
|
|
|
31
31
|
return JSON.parse(result);
|
|
32
32
|
}
|
|
33
33
|
function handleLink(link) {
|
|
34
|
+
const outputSection = link.closest('.squiffy-output-section');
|
|
35
|
+
if (outputSection !== currentSectionElement)
|
|
36
|
+
return false;
|
|
34
37
|
if (link.classList.contains('disabled'))
|
|
35
|
-
return;
|
|
38
|
+
return false;
|
|
36
39
|
let passage = link.getAttribute('data-passage');
|
|
37
40
|
let section = link.getAttribute('data-section');
|
|
38
41
|
const rotateAttr = link.getAttribute('data-rotate');
|
|
@@ -55,15 +58,16 @@ export const init = (options) => {
|
|
|
55
58
|
showPassage('@last');
|
|
56
59
|
}
|
|
57
60
|
}
|
|
61
|
+
return true;
|
|
58
62
|
}
|
|
59
|
-
|
|
60
|
-
disableLink(link);
|
|
63
|
+
if (section) {
|
|
61
64
|
section = processLink(section);
|
|
62
65
|
if (section) {
|
|
63
66
|
go(section);
|
|
64
67
|
}
|
|
68
|
+
return true;
|
|
65
69
|
}
|
|
66
|
-
|
|
70
|
+
if (rotateOrSequenceAttr) {
|
|
67
71
|
const result = rotate(rotateOrSequenceAttr, rotateAttr ? link.innerText : '');
|
|
68
72
|
link.innerHTML = result[0].replace(/"/g, '"').replace(/'/g, '\'');
|
|
69
73
|
const dataAttribute = rotateAttr ? 'data-rotate' : 'data-sequence';
|
|
@@ -76,7 +80,9 @@ export const init = (options) => {
|
|
|
76
80
|
set(attribute, result[0]);
|
|
77
81
|
}
|
|
78
82
|
save();
|
|
83
|
+
return true;
|
|
79
84
|
}
|
|
85
|
+
return false;
|
|
80
86
|
}
|
|
81
87
|
function handleClick(event) {
|
|
82
88
|
const target = event.target;
|
|
@@ -88,9 +94,6 @@ export const init = (options) => {
|
|
|
88
94
|
link.classList.add('disabled');
|
|
89
95
|
link.setAttribute('tabindex', '-1');
|
|
90
96
|
}
|
|
91
|
-
function disableLinks(links) {
|
|
92
|
-
links.forEach(disableLink);
|
|
93
|
-
}
|
|
94
97
|
function begin() {
|
|
95
98
|
if (!load()) {
|
|
96
99
|
go(story.start);
|
|
@@ -336,7 +339,6 @@ export const init = (options) => {
|
|
|
336
339
|
}
|
|
337
340
|
function newSection(sectionName) {
|
|
338
341
|
if (currentSectionElement) {
|
|
339
|
-
disableLinks(currentSectionElement.querySelectorAll('.squiffy-link'));
|
|
340
342
|
currentSectionElement.querySelectorAll('input').forEach(el => {
|
|
341
343
|
const attribute = el.getAttribute('data-attribute') || el.id;
|
|
342
344
|
if (attribute)
|
|
@@ -591,6 +593,7 @@ export const init = (options) => {
|
|
|
591
593
|
}
|
|
592
594
|
function update(newStory) {
|
|
593
595
|
// TODO: Re-disable clicked links after update
|
|
596
|
+
// TODO: Delete empty output blocks
|
|
594
597
|
for (const existingSection of Object.keys(story.sections)) {
|
|
595
598
|
const elements = getSectionContent(existingSection);
|
|
596
599
|
if (elements.length) {
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "squiffy-runtime",
|
|
3
|
-
"version": "6.0.0-alpha.
|
|
3
|
+
"version": "6.0.0-alpha.8",
|
|
4
4
|
"main": "dist/squiffy.runtime.js",
|
|
5
5
|
"types": "dist/squiffy.runtime.d.ts",
|
|
6
6
|
"scripts": {
|
|
7
|
+
"dev": "vitest",
|
|
7
8
|
"test": "vitest --run",
|
|
8
9
|
"build": "tsc",
|
|
9
10
|
"prepublishOnly": "npm run build && npm run test"
|
|
@@ -45,12 +45,12 @@ exports[`Click a section link 2`] = `
|
|
|
45
45
|
"
|
|
46
46
|
<div class="squiffy-output-section" id="squiffy-section-1" data-section="Introduction"><div class="squiffy-output-block"><div data-source="[[Introduction]]"><h1>Squiffy Test</h1>
|
|
47
47
|
<p>This is <a href="http://textadventures.co.uk">a website link</a>.</p>
|
|
48
|
-
<p>This should be <a class="squiffy-link link-passage
|
|
49
|
-
<p>You don't need to specify a name - for example, this <a class="squiffy-link link-passage
|
|
50
|
-
<p>And this goes to the <a class="squiffy-link link-section
|
|
51
|
-
<p>This line has links to <a class="squiffy-link link-section
|
|
52
|
-
<p>This line has links to <a class="squiffy-link link-passage
|
|
53
|
-
<p>Oh look - <a class="squiffy-link link-passage
|
|
48
|
+
<p>This should be <a class="squiffy-link link-passage" data-passage="passage" role="link" tabindex="0">a link to a passage</a>. Here's <a class="squiffy-link link-passage" data-passage="passage2" role="link" tabindex="0">another one</a>.</p>
|
|
49
|
+
<p>You don't need to specify a name - for example, this <a class="squiffy-link link-passage" data-passage="link" role="link" tabindex="0">link</a> and this <a class="squiffy-link link-section" data-section="section" role="link" tabindex="0">section</a>.</p>
|
|
50
|
+
<p>And this goes to the <a class="squiffy-link link-section" data-section="section2" role="link" tabindex="0">next section</a>.</p>
|
|
51
|
+
<p>This line has links to <a class="squiffy-link link-section" data-section="section 3" role="link" tabindex="0">section 3</a> and <a class="squiffy-link link-section" data-section="section four" role="link" tabindex="0">section 4</a>.</p>
|
|
52
|
+
<p>This line has links to <a class="squiffy-link link-passage" data-passage="passage 3" role="link" tabindex="0">passage 3</a> and <a class="squiffy-link link-passage" data-passage="passage four" role="link" tabindex="0">passage 4</a>.</p>
|
|
53
|
+
<p>Oh look - <a class="squiffy-link link-passage" data-passage="it's a passage with an apostrophe" role="link" tabindex="0">it's a passage with an apostrophe</a>.</p></div></div></div><div class="squiffy-output-section" id="squiffy-section-2" data-section="section 3"><div class="squiffy-output-block"><div data-source="[[section 3]]"><p>Another section is here, with passages <a class="squiffy-link link-passage" data-passage="a" role="link" tabindex="0">a</a> and <a class="squiffy-link link-passage" data-passage="b" role="link" tabindex="0">b</a>.</p></div></div></div>"
|
|
54
54
|
`;
|
|
55
55
|
|
|
56
56
|
exports[`Delete passage 1`] = `
|
|
@@ -65,12 +65,12 @@ exports[`Delete passage 2`] = `
|
|
|
65
65
|
|
|
66
66
|
exports[`Delete section 1`] = `
|
|
67
67
|
"
|
|
68
|
-
<div class="squiffy-output-section" id="squiffy-section-1" data-section="_default"><div class="squiffy-output-block"><div data-source="[[_default]]"><p>Click this: <a class="squiffy-link link-section
|
|
68
|
+
<div class="squiffy-output-section" id="squiffy-section-1" data-section="_default"><div class="squiffy-output-block"><div data-source="[[_default]]"><p>Click this: <a class="squiffy-link link-section" data-section="a" role="link" tabindex="0">a</a></p></div></div></div><div class="squiffy-output-section" id="squiffy-section-2" data-section="a"><div class="squiffy-output-block"><div data-source="[[a]]"><p>New section</p></div></div></div>"
|
|
69
69
|
`;
|
|
70
70
|
|
|
71
71
|
exports[`Delete section 2`] = `
|
|
72
72
|
"
|
|
73
|
-
<div class="squiffy-output-section" id="squiffy-section-1" data-section="_default"><div class="squiffy-output-block"><div data-source="[[_default]]"><p>Click this: <a class="squiffy-link link-section
|
|
73
|
+
<div class="squiffy-output-section" id="squiffy-section-1" data-section="_default"><div class="squiffy-output-block"><div data-source="[[_default]]"><p>Click this: <a class="squiffy-link link-section" data-section="a" role="link" tabindex="0">a</a></p></div></div></div><div class="squiffy-output-section" id="squiffy-section-2" data-section="a"><div class="squiffy-output-block"></div></div>"
|
|
74
74
|
`;
|
|
75
75
|
|
|
76
76
|
exports[`Update default section output 1`] = `
|
|
@@ -61,7 +61,7 @@ const initScript = async (script: string) => {
|
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
const findLink = (element: HTMLElement, linkType: string, linkText: string, onlyEnabled: boolean = false) => {
|
|
64
|
-
const links = element.querySelectorAll(
|
|
64
|
+
const links = element.querySelectorAll(`.squiffy-output-section:last-child a.squiffy-link.link-${linkType}`);
|
|
65
65
|
return Array.from(links).find(link => link.textContent === linkText && (onlyEnabled ? !link.classList.contains("disabled") : true)) as HTMLElement;
|
|
66
66
|
};
|
|
67
67
|
|
|
@@ -100,13 +100,14 @@ test('Click a section link', async () => {
|
|
|
100
100
|
expect(linkToPassage).not.toBeNull();
|
|
101
101
|
expect(section3Link).not.toBeNull();
|
|
102
102
|
expect(linkToPassage.classList).not.toContain('disabled');
|
|
103
|
-
expect(section3Link.classList).not.toContain('disabled');
|
|
104
103
|
|
|
105
|
-
squiffyApi.clickLink(section3Link);
|
|
104
|
+
const handled = squiffyApi.clickLink(section3Link);
|
|
105
|
+
expect(handled).toBe(true);
|
|
106
106
|
|
|
107
|
-
expect(linkToPassage.classList).toContain('disabled');
|
|
108
|
-
expect(section3Link.classList).toContain('disabled');
|
|
109
107
|
expect(element.innerHTML).toMatchSnapshot();
|
|
108
|
+
|
|
109
|
+
// passage link is from the previous section, so should be unclickable
|
|
110
|
+
expect(squiffyApi.clickLink(linkToPassage)).toBe(false);
|
|
110
111
|
});
|
|
111
112
|
|
|
112
113
|
test('Click a passage link', async () => {
|
|
@@ -121,13 +122,15 @@ test('Click a passage link', async () => {
|
|
|
121
122
|
expect(linkToPassage).not.toBeNull();
|
|
122
123
|
expect(section3Link).not.toBeNull();
|
|
123
124
|
expect(linkToPassage.classList).not.toContain('disabled');
|
|
124
|
-
expect(section3Link.classList).not.toContain('disabled');
|
|
125
125
|
|
|
126
|
-
squiffyApi.clickLink(linkToPassage);
|
|
126
|
+
const handled = squiffyApi.clickLink(linkToPassage);
|
|
127
|
+
expect(handled).toBe(true);
|
|
127
128
|
|
|
128
129
|
expect(linkToPassage.classList).toContain('disabled');
|
|
129
|
-
expect(section3Link.classList).not.toContain('disabled');
|
|
130
130
|
expect(element.innerHTML).toMatchSnapshot();
|
|
131
|
+
|
|
132
|
+
// shouldn't be able to click it again
|
|
133
|
+
expect(squiffyApi.clickLink(linkToPassage)).toBe(false);
|
|
131
134
|
});
|
|
132
135
|
|
|
133
136
|
test('Run JavaScript functions', async () => {
|
|
@@ -156,7 +159,8 @@ test('Run JavaScript functions', async () => {
|
|
|
156
159
|
const clickContinue = () => {
|
|
157
160
|
const continueLink = findLink(element, 'section', 'Continue...', true);
|
|
158
161
|
expect(continueLink).not.toBeNull();
|
|
159
|
-
squiffyApi.clickLink(continueLink);
|
|
162
|
+
const handled = squiffyApi.clickLink(continueLink);
|
|
163
|
+
expect(handled).toBe(true);
|
|
160
164
|
};
|
|
161
165
|
|
|
162
166
|
const { squiffyApi, element } = await initScript(script);
|
|
@@ -208,7 +212,8 @@ test('Update passage output', async () => {
|
|
|
208
212
|
Passage a content`);
|
|
209
213
|
|
|
210
214
|
const link = findLink(element, 'passage', 'a');
|
|
211
|
-
squiffyApi.clickLink(link);
|
|
215
|
+
const handled = squiffyApi.clickLink(link);
|
|
216
|
+
expect(handled).toBe(true);
|
|
212
217
|
|
|
213
218
|
let defaultOutput = getSectionContent(element, '_default');
|
|
214
219
|
expect(defaultOutput).toBe('Click this: a');
|
|
@@ -238,7 +243,8 @@ test('Delete section', async () => {
|
|
|
238
243
|
New section`);
|
|
239
244
|
|
|
240
245
|
const link = findLink(element, 'section', 'a');
|
|
241
|
-
squiffyApi.clickLink(link);
|
|
246
|
+
const handled = squiffyApi.clickLink(link);
|
|
247
|
+
expect(handled).toBe(true);
|
|
242
248
|
|
|
243
249
|
let defaultOutput = getSectionContent(element, '_default');
|
|
244
250
|
expect(defaultOutput).toBe('Click this: a');
|
|
@@ -265,7 +271,8 @@ test('Delete passage', async () => {
|
|
|
265
271
|
New passage`);
|
|
266
272
|
|
|
267
273
|
const link = findLink(element, 'passage', 'a');
|
|
268
|
-
squiffyApi.clickLink(link);
|
|
274
|
+
const handled = squiffyApi.clickLink(link);
|
|
275
|
+
expect(handled).toBe(true);
|
|
269
276
|
|
|
270
277
|
let defaultOutput = getSectionContent(element, '_default');
|
|
271
278
|
expect(defaultOutput).toBe('Click this: a');
|
package/src/squiffy.runtime.ts
CHANGED
|
@@ -16,7 +16,7 @@ export interface SquiffyApi {
|
|
|
16
16
|
restart: () => void;
|
|
17
17
|
get: (attribute: string) => any;
|
|
18
18
|
set: (attribute: string, value: any) => void;
|
|
19
|
-
clickLink: (link: HTMLElement) =>
|
|
19
|
+
clickLink: (link: HTMLElement) => boolean;
|
|
20
20
|
update: (story: Story) => void;
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -93,8 +93,12 @@ export const init = (options: SquiffyInitOptions): SquiffyApi => {
|
|
|
93
93
|
return JSON.parse(result);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
function handleLink(link: HTMLElement) {
|
|
97
|
-
|
|
96
|
+
function handleLink(link: HTMLElement): boolean {
|
|
97
|
+
const outputSection = link.closest('.squiffy-output-section');
|
|
98
|
+
if (outputSection !== currentSectionElement) return false;
|
|
99
|
+
|
|
100
|
+
if (link.classList.contains('disabled')) return false;
|
|
101
|
+
|
|
98
102
|
let passage = link.getAttribute('data-passage');
|
|
99
103
|
let section = link.getAttribute('data-section');
|
|
100
104
|
const rotateAttr = link.getAttribute('data-rotate');
|
|
@@ -117,15 +121,20 @@ export const init = (options: SquiffyInitOptions): SquiffyApi => {
|
|
|
117
121
|
showPassage('@last');
|
|
118
122
|
}
|
|
119
123
|
}
|
|
124
|
+
|
|
125
|
+
return true;
|
|
120
126
|
}
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
|
|
128
|
+
if (section) {
|
|
123
129
|
section = processLink(section);
|
|
124
130
|
if (section) {
|
|
125
131
|
go(section);
|
|
126
132
|
}
|
|
133
|
+
|
|
134
|
+
return true;
|
|
127
135
|
}
|
|
128
|
-
|
|
136
|
+
|
|
137
|
+
if (rotateOrSequenceAttr) {
|
|
129
138
|
const result = rotate(rotateOrSequenceAttr, rotateAttr ? link.innerText : '');
|
|
130
139
|
link.innerHTML = result[0]!.replace(/"/g, '"').replace(/'/g, '\'');
|
|
131
140
|
const dataAttribute = rotateAttr ? 'data-rotate' : 'data-sequence';
|
|
@@ -138,7 +147,11 @@ export const init = (options: SquiffyInitOptions): SquiffyApi => {
|
|
|
138
147
|
set(attribute, result[0]);
|
|
139
148
|
}
|
|
140
149
|
save();
|
|
150
|
+
|
|
151
|
+
return true;
|
|
141
152
|
}
|
|
153
|
+
|
|
154
|
+
return false;
|
|
142
155
|
}
|
|
143
156
|
|
|
144
157
|
function handleClick(event: Event) {
|
|
@@ -153,10 +166,6 @@ export const init = (options: SquiffyInitOptions): SquiffyApi => {
|
|
|
153
166
|
link.setAttribute('tabindex', '-1');
|
|
154
167
|
}
|
|
155
168
|
|
|
156
|
-
function disableLinks(links: NodeListOf<Element>) {
|
|
157
|
-
links.forEach(disableLink);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
169
|
function begin() {
|
|
161
170
|
if (!load()) {
|
|
162
171
|
go(story.start);
|
|
@@ -412,7 +421,6 @@ export const init = (options: SquiffyInitOptions): SquiffyApi => {
|
|
|
412
421
|
|
|
413
422
|
function newSection(sectionName: string | null) {
|
|
414
423
|
if (currentSectionElement) {
|
|
415
|
-
disableLinks(currentSectionElement.querySelectorAll('.squiffy-link'));
|
|
416
424
|
currentSectionElement.querySelectorAll('input').forEach(el => {
|
|
417
425
|
const attribute = el.getAttribute('data-attribute') || el.id;
|
|
418
426
|
if (attribute) set(attribute, el.value);
|
|
@@ -685,6 +693,7 @@ export const init = (options: SquiffyInitOptions): SquiffyApi => {
|
|
|
685
693
|
|
|
686
694
|
function update(newStory: Story) {
|
|
687
695
|
// TODO: Re-disable clicked links after update
|
|
696
|
+
// TODO: Delete empty output blocks
|
|
688
697
|
|
|
689
698
|
for (const existingSection of Object.keys(story.sections)) {
|
|
690
699
|
const elements = getSectionContent(existingSection);
|