Skip to content

Commit 2027a2e

Browse files
authored
Merge pull request #75 from SimplyEdit/feature/keyboardShortcuts
Feature/keyboard shortcuts
2 parents 47ad538 + 6e4ca8c commit 2027a2e

26 files changed

Lines changed: 315 additions & 12 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ Data API to store/fetch information.
3737
Changes the app State.
3838
Is triggered by code (usually a command or a route).
3939

40+
### Shortcuts (access keys, keyboard shortcuts)
41+
This component are handlers for keyboard input by a user. This can either be
42+
a 'global' keyboard shortcut, or one that is defined on a DOM element
43+
using the data-simply-accesskey attribute.
44+
Makes use of Actions to change editor State.
45+
4046
### Commands
4147
Is a component that is triggered by a user action. Usually triggered in the DOM, for example a user clicking a button.
4248
Can access DOM elements, is aware of a DOM structure.

base-components/automatic-preview/actions/getComponentNameField.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ function(component) {
55
'component', // componentTemplates
66
'action', // actions
77
'command', // commands
8+
'shortcuts', // shortcuts
89
'page', // pageTemplates
910
'method', // rawApi, dataApi
1011
'dataSource', // dataSources
@@ -17,6 +18,8 @@ function(component) {
1718
return 'component';
1819
case 'actions':
1920
return 'action';
21+
case 'shortcuts':
22+
return 'shortcut';
2023
case 'commands':
2124
return 'command';
2225
case 'pageTemplates':

components/component-builder-template/actions/build.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
function(builderTemplate, data) {
22
var build = builderTemplate;
33
let replacements = {
4+
"shortcuts" : editor.transformers.simplyPreviewShortcuts.render(data.shortcuts ?? []),
45
"actions" : editor.transformers.simplyPreviewActions.render(data.actions ?? []),
56
"commands" : editor.transformers.simplyPreviewCommands.render(data.commands ?? []),
67
"dataApi" : editor.transformers.simplyPreviewDataApi.render(data.dataApi ?? []),
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function(el) {
2+
editor.pageData.component.parts.shortcuts.push({});
3+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<details class="simplycode-component">
2+
<summary data-simply-command="initEditors" title="Shortcuts are keyboard shortcuts selected to call specific actions.">
3+
<span data-simply-field="count.shortcuts" data-simply-content="attributes" data-simply-attributes="data-count">
4+
Shortcuts
5+
</span>
6+
<span class="simplycode-controls">
7+
<button class="simplycode-button" data-simply-command="addShortcut">Add shortcuts</button>
8+
</span>
9+
</summary>
10+
<div class="simplycode-code-method" data-simply-list="component.parts.shortcuts">
11+
<template>
12+
<div class="simplycode-part" data-simply-field="deleted" data-simply-content="attributes" data-simply-attributes="data-deleted">
13+
<div class="simplycode-part-header">
14+
<div class="simplycode-tabs">
15+
<input class="simplycode-tab" data-simply-field="shortcut" placeholder="shortcut-key">
16+
<label class="simplycode-tab">
17+
<input type="radio" name="actionEditor" checked value="code" data-simply-field="editor">
18+
<span>Code</span>
19+
</label>
20+
<label class="simplycode-tab">
21+
<input type="radio" name="actionEditor" value="tests" data-simply-field="editor">
22+
<span>Tests</span>
23+
</label>
24+
</div>
25+
<div class="simplycode-options">
26+
<button class="simplycode-button" draggable="true">Drag to move</button>
27+
<button class="simplycode-button" data-simply-field="deleted" data-simply-content="attributes" data-simply-attributes="data-deleted" data-deleted="false" data-simply-command="deleteEntry">Delete shortcut</button>
28+
</div>
29+
</div>
30+
<div class="simplycode-editors" data-simply-field="editor" data-simply-content="template" data-simply-default-template="code">
31+
<template data-simply-template="code">
32+
<div class="simplycode-editor-code">
33+
<textarea data-codemirror-mode="javascript" data-simply-field="code" placeholder="function() {...}"></textarea>
34+
<simply-render rel="componentQUnitActionRunner"></simply-render>
35+
</div>
36+
</template>
37+
<template data-simply-template="tests">
38+
<div class="simplycode-editor-code">
39+
<simply-render rel="componentQUnitTests"></simply-render>
40+
</div>
41+
</template>
42+
</div>
43+
</div>
44+
</template>
45+
</div>
46+
</details>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id":"component-shortcuts","description":"Edit form for component shortcuts"}

components/data-format/dataApi/mergeComponent.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,44 @@ function(component) {
212212
componentPart.contents = JSON.stringify(Object.values(contents));
213213
}
214214
break;
215+
case "shortcuts":
216+
if (typeof componentPart.contents === "object") {
217+
var contents = {};
218+
componentPart.contents.forEach(function(partFile) {
219+
if (partFile.id.match(/\.js$/)) {
220+
partId = partFile.id.replace(/\.js$/, '');
221+
if (typeof contents[partId] === "undefined") {
222+
contents[partId] = {
223+
shortcut : partId
224+
}
225+
}
226+
contents[partId]['code'] = partFile.contents;
227+
}
228+
if (partFile.id.match(/^tests$/)) {
229+
tests = {};
230+
partFile.contents.forEach(function(testSet) {
231+
testSetPartId = testSet.id;
232+
if (typeof contents[testSetPartId] === "undefined") {
233+
contents[testSetPartId] = {
234+
shortcut : testSetPartId
235+
}
236+
}
237+
testSet.contents.forEach(function(test) {
238+
if (typeof tests[testSet.id] === "undefined") {
239+
tests[testSet.id] = [];
240+
}
241+
tests[testSet.id].push({
242+
name : test.id.replace(/\.js$/, ''),
243+
"test-code" : test.contents
244+
});
245+
});
246+
contents[testSet.id]['tests'] = Object.values(tests[testSet.id]);
247+
});
248+
}
249+
});
250+
componentPart.contents = JSON.stringify(Object.values(contents));
251+
}
252+
break;
215253
case "dataSources":
216254
if (typeof componentPart.contents === "object") {
217255
var contents = {};

components/data-format/dataApi/savePart.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,41 @@ function(basePath, part, contents) {
196196
}
197197
});
198198
break;
199+
case "shortcuts":
200+
contents.forEach(function(componentPart, componentIndex) {
201+
if (!componentPart.shortcut) {
202+
throw new Error("Required part name is empty");
203+
}
204+
if (componentPart.deleted == "true") {
205+
results.push(simplyRawApi.delete(basePath + "/" + part + "/" + componentPart.shortcut + ".js"));
206+
if (componentPart.tests && componentPart.tests.length) {
207+
results.push(simplyRawApi.delete(basePath + "/" + part + "/" + componentPart.shortcut + "/"));
208+
}
209+
contents.splice(componentIndex, 1);
210+
} else {
211+
results.push(simplyRawApi.putRaw(
212+
basePath + "/" + part + "/" + componentPart.shortcut + ".js", {},
213+
componentPart.code
214+
));
215+
if (componentPart.tests) {
216+
componentPart.tests.forEach(function(test, testIndex) {
217+
if (!test.name) {
218+
throw new Error("Required test name is empty");
219+
}
220+
if (test.deleted == "true") {
221+
results.push(simplyRawApi.delete(basePath + "/" + part + "/tests/" + componentPart.shortcut + "/" + test.name + ".js"));
222+
componentPart.tests.splice(testIndex, 1);
223+
} else {
224+
results.push(simplyRawApi.putRaw(
225+
basePath + "/" + part + "/tests/" + componentPart.shortcut + "/" + test.name + ".js", {},
226+
test['test-code']
227+
));
228+
}
229+
});
230+
}
231+
}
232+
});
233+
break;
199234
case "dataSources":
200235
contents.forEach(function(componentPart, componentIndex) {
201236
if (!componentPart.dataSource) {

components/previews/transformers/simplyPreviewComponent-render.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ function(data) {
55
let replacements = {
66
"componentPreview" : data,
77
"actions" : editor.transformers.simplyPreviewActions.render(editor.pageData.app.actions ?? []),
8+
"shortcuts" : editor.transformers.simplyPreviewShortcuts.render(editor.pageData.app.shortcuts ?? []),
89
"commands" : editor.transformers.simplyPreviewCommands.render(editor.pageData.app.commands ?? []),
910
"dataApi" : editor.transformers.simplyPreviewDataApi.render(editor.pageData.app.dataApi ?? []),
1011
"rawApi" : editor.transformers.simplyPreviewRawApi.render(editor.pageData.app.rawApi ?? []),

components/previews/transformers/simplyPreviewFullApp-render.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function(data) {
99
var fullApp = data.pageFrame.fullApp;
1010
let replacements = {
1111
"actions" : editor.transformers.simplyPreviewActions.render(data.actions ?? []),
12+
"shortcuts" : editor.transformers.simplyPreviewShortcuts.render(data.shortcuts ?? []),
1213
"commands" : editor.transformers.simplyPreviewCommands.render(data.commands ?? []),
1314
"dataApi" : editor.transformers.simplyPreviewDataApi.render(data.dataApi ?? []),
1415
"rawApi" : editor.transformers.simplyPreviewRawApi.render(data.rawApi ?? []),

0 commit comments

Comments
 (0)