simplyview 2.0.3 → 2.1.1

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.
@@ -1,48 +0,0 @@
1
- <h1>Examples</h1>
2
- <h2>Counter</h2>
3
- <link rel="stylesheet" href="examples.css">
4
-
5
- <div id="todoApp">
6
- <form data-simply-command="addEntry">
7
- <input type="text" name="newItem" class="new-todo" placeholder="What needs to be done?" autocomplete="off">
8
- </form>
9
- <ul class="todo-list" data-simply-list="items">
10
- <template>
11
- <li>
12
- <label data-simply-field="item">Item</label>
13
- </li>
14
- </template>
15
- </ul>
16
- </div>
17
- <script src="//cdn.simplyedit.io/1/simply-edit.js"></script>
18
- <script src="../dist/simply.everything.js"></script>
19
- <script>
20
- var todoApp = simply.app({
21
- container: document.getElementById('todoApp'),
22
- commands: {
23
- addEntry: function(form, values) {
24
- todoApp.actions.addEntry(values.newItem);
25
- form.elements.newItem.value = '';
26
- }
27
- },
28
- actions: {
29
- addEntry: function(item) {
30
- todoApp.view.items.push({
31
- item: item,
32
- completed: 0
33
- });
34
- return Promise.resolve();
35
- }
36
- },
37
- view: {
38
- items: [
39
- {
40
- item: 'iets'
41
- },
42
- {
43
- item: 'iets anders'
44
- }
45
- ]
46
- }
47
- });
48
- </script>
@@ -1,359 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <script src="https://cdn.jsdelivr.net/npm/superagent"></script>
5
- <link rel="stylesheet" type="text/css" href="css/theds.css">
6
- <style>
7
- .loading-overlay {
8
- position: absolute;
9
- position: fixed;
10
- top: 0;
11
- left: 0;
12
- width: 100%;
13
- height: 100%;
14
- background-color: rgba(255,255,255,0.2);
15
- display: flex;
16
- align-items: center;
17
- justify-content: center;
18
- }
19
- body:not(.loading) .loading-overlay {
20
- display: none;
21
- }
22
-
23
- /* loading animation from loading.io/css/ */
24
- .lds-ring {
25
- display: inline-block;
26
- position: relative;
27
- width: 80px;
28
- height: 80px;
29
- }
30
- .lds-ring div {
31
- box-sizing: border-box;
32
- display: block;
33
- position: absolute;
34
- width: 64px;
35
- height: 64px;
36
- margin: 8px;
37
- border: 8px solid #666;
38
- border-radius: 50%;
39
- animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
40
- border-color: #666 transparent transparent transparent;
41
- }
42
- .lds-ring div:nth-child(1) {
43
- animation-delay: -0.45s;
44
- }
45
- .lds-ring div:nth-child(2) {
46
- animation-delay: -0.3s;
47
- }
48
- .lds-ring div:nth-child(3) {
49
- animation-delay: -0.15s;
50
- }
51
- @keyframes lds-ring {
52
- 0% {
53
- transform: rotate(0deg);
54
- }
55
- 100% {
56
- transform: rotate(360deg);
57
- }
58
- }
59
-
60
- </style>
61
- </head>
62
- <body class="loading">
63
- <header class="ds-space ds-navbar">
64
- <div class="demo-search">
65
- <input type="text" placeholder="Search..." data-simply-command="search" data-simply-immediate="1">
66
- </div>
67
- <div class="ds-paging ds-navbar-right" style="margin-right: 0">
68
- <ul class="ds-align-right ds-navbar-nav ds-paging">
69
- <li>
70
- <button data-simply-command="movies-prevpage" class="ds-button" disabled="" title="vorige pagina"
71
- data-simply-field="movies.paging.prev" data-simply-content="fixed" data-simply-transformer="enable">
72
- <svg class="ds-icon ds-icon-feather"><use xlink:href="css/feather-sprite.svg#chevron-left"></use></svg>
73
- </button>
74
- </li>
75
- <li class="ds-paging-info">
76
- <span data-simply-field="movies.paging.page">1</span> /
77
- <span data-simply-field="movies.paging.max">10</span>
78
- </li>
79
- <li>
80
- <button data-simply-command="movies-nextpage" class="ds-button" title="volgende pagina"
81
- data-simply-field="movies.paging.next" data-simply-content="fixed" data-simply-transformer="enable">
82
- <svg class="ds-icon ds-icon-feather"><use xlink:href="css/feather-sprite.svg#chevron-right"></use></svg>
83
- </button>
84
- </li>
85
- </ul>
86
-
87
- <select class="ds-align-right" style="width: 200px;"
88
- data-simply-list="movie-genres" data-simply-data="movie-genres" data-simply-entry="genre"
89
- data-simply-command="genre" data-simply-field="movies.genreFilter.genre"
90
- >
91
- <template>
92
- <option data-simply-field="genre"></option>
93
- </template>
94
- </select>
95
- </div>
96
- </header>
97
- <main class="ds-space ds-scrollbox" style="--ds-scrollbox-height: 65vh">
98
- <table class="ds-datatable ds-datatable-sticky-header ds-datatable-rulers">
99
- <thead>
100
- <tr>
101
- <th data-simply-command="sort" data-simply-value="title" data-simply-field="movies.sort.sort" data-simply-content="fixed" data-simply-transformer="movies-sort">title</th>
102
- <th data-simply-command="sort" data-simply-value="year" data-simply-field="movies.sort.sort" data-simply-content="fixed" data-simply-transformer="movies-sort">year</th>
103
- <th class="ds-datatable-disable-sort">genre</th>
104
- </tr>
105
- </thead>
106
- <tbody data-simply-list="movies" data-simply-data="movies">
107
- <template>
108
- <tr>
109
- <td data-simply-field="title"></td>
110
- <td data-simply-field="year"></td>
111
- <td data-simply-field="genres" data-simply-transformer="movies-genres"></td>
112
- </tr>
113
- </template>
114
- </tbody>
115
- </table>
116
- </main>
117
- <div class="loading-overlay">
118
- <div class="lds-ring"><div></div><div></div><div></div><div></div></div>
119
- </div>
120
- <script src="https://cdn.simplyedit.io/1/simply-edit.js"></script>
121
- <script src="../dist/simply.everything.js"></script>
122
- <script>
123
- // make these global for easier debugging
124
- var movies, movieApp;
125
-
126
- // wait for simplyedit to be loaded
127
- document.addEventListener('simply-content-loaded',function() {
128
-
129
- // fetch movie list
130
- superagent
131
- .get('https://raw.githubusercontent.com/prust/wikipedia-movie-data/master/movies.json')
132
- .then(function(result) {
133
- if (result.ok) {
134
- return JSON.parse(result.text);
135
- }
136
- })
137
- .then(function(json) {
138
-
139
- movies = (function() {
140
- // create a viewmodel named 'movies'
141
- // this will automatically add a datasource 'movies' in SimplyEdit.
142
- var m = simply.viewmodel.create('movies');
143
-
144
- // add a text search plugin that searches through titles
145
- // this goes first, in the 'select' pipe
146
- m.addPlugin('select', simply.viewmodel.createFilter({
147
- name: 'titleSearch',
148
- getMatch: function(params) {
149
- if (params.search && params.search.length>2) {
150
- var re = new RegExp(params.search, 'i');
151
- return function(movie) {
152
- return re.test(movie.title);
153
- }
154
- }
155
- }
156
- }));
157
-
158
- // add a genre select tool
159
- // first add a datasource of all available genres for all movies, before filtering
160
- var genres = json.flatMap(m => m.genres);
161
- var distinctGenres = Array.from(new Set(genres)).map(g => { return {value: g, innerHTML: g}});
162
-
163
- distinctGenres.unshift({ value: '', innerHTML: 'All genres'});
164
-
165
- editor.addDataSource('movie-genres',{
166
- load: function(el, callback) {
167
- callback(distinctGenres);
168
- }
169
- });
170
-
171
- // start with the 'select' pipe
172
-
173
- // if a previous filter has changed the view data
174
- // then find all available genres in the filtered dataset
175
- // and mark the others as disabled
176
- m.addPlugin('select', function() {
177
- if (this.view.changed) {
178
- var currentGenres = this.view.data.flatMap(m => m.genres);
179
- var distinctGenres = new Set(currentGenres);
180
- var genres = document.querySelector('[data-simply-data="movie-genres"]');
181
- Array.from(genres.options).forEach(function(genre) {
182
- if (genre.value && !distinctGenres.has(genre.value)) {
183
- genre.disabled = 'disabled';
184
- } else {
185
- genre.removeAttribute('disabled');
186
- }
187
- });
188
- }
189
- });
190
-
191
- // only then filter out all movies that don't match
192
- // the selected genre
193
- m.addPlugin('select', simply.viewmodel.createFilter({
194
- name: 'genreFilter',
195
- getMatch: function(params) {
196
- if (params.genre) {
197
- return function(movie) {
198
- return movie.genres && movie.genres.indexOf(params.genre)>=0;
199
- }
200
- }
201
- }
202
- }));
203
-
204
- // the movies dataset contains an array of genres per movie
205
- // this transformer turns it into a comma seperated string
206
- // used in the genre column of the table body
207
- editor.transformers['movies-genres'] = {
208
- render: function(data) {
209
- if (data) {
210
- this.originalValue = data;
211
- data = data.slice().join(', ');
212
- this.innerHTML = data;
213
- }
214
- return data;
215
- },
216
- extract: function() {
217
- return this.originalValue || [];
218
- }
219
- };
220
-
221
- // on with the 'order' pipe
222
-
223
- // add a sort function that can sort by title or year, both ascending and descending
224
- m.addPlugin('order', simply.viewmodel.createSort({
225
- name: 'sort',
226
- getSort: function(params) {
227
- if (params.sortOrder == 'ASC') {
228
- var order = -1;
229
- } else {
230
- var order = 1;
231
- }
232
- switch (params.sortBy) {
233
- case 'title':
234
- return function(a,b) {
235
- return a.title<b.title ? order : -order;
236
- }
237
- break;
238
- case 'year':
239
- return function(a,b) {
240
- return a.year<b.year ? order : -order;
241
- }
242
- break;
243
- };
244
- }
245
- }));
246
-
247
- // adds a transformer to update the table headings with the correct
248
- // sort order class
249
- // this uses the movies.options.sort.sort variable
250
- // which combines the sortBy and sortOrder in a single string
251
- // these are set by the command 'sort' in the movieApp
252
- editor.transformers['movies-sort'] = {
253
- render: function(data) {
254
- this.originalValue = data;
255
- this.classList.remove('ds-datatable-sorted-descending');
256
- this.classList.remove('ds-datatable-sorted-ascending');
257
- var sort = data.split(' ');
258
- if (sort[0]==this.innerHTML) {
259
- this.classList.add(sort[1]=='ASC' ? 'ds-datatable-sorted-ascending':'ds-datatable-sorted-descending');
260
- }
261
- return data;
262
- },
263
- extract: function() {
264
- return this.originalValue;
265
- }
266
- };
267
-
268
-
269
-
270
- // then the 'render' pipe
271
-
272
- // here we add a paging plugin
273
- m.addPlugin('render', simply.viewmodel.createPaging());
274
-
275
- // the paging buttons should be disabled when no further or earlier page
276
- // is available for the next/prev buttons respectively
277
- // the paging plugin has a next and prev value in the paging options
278
- // if no next or prev page is available, the value is set to 0
279
- // so this transformer sets the disabled property of an object
280
- // depending on whether the given data evaluates to true or false
281
- editor.transformers['enable'] = {
282
- render: function(data) {
283
- this.originalValue = data;
284
- if (data) {
285
- this.disabled = false;
286
- } else {
287
- this.disabled = true;
288
- }
289
- return data;
290
- },
291
- extract: function() {
292
- return this.originalValue;
293
- }
294
- };
295
-
296
- return m;
297
- })();
298
-
299
- movieApp = simply.app({
300
- commands: {
301
- 'search': function(el, value) {
302
- movies.update({
303
- titleSearch: {
304
- search: value
305
- }
306
- });
307
- },
308
- 'movies-nextpage': function(el, value) {
309
- movies.update({
310
- paging: {
311
- page: movies.options.paging.page + 1
312
- }
313
- });
314
- },
315
- 'movies-prevpage': function(el, value) {
316
- movies.update({
317
- paging: {
318
- page: movies.options.paging.page - 1
319
- }
320
- });
321
- },
322
- 'sort': function(el, value) {
323
- var newOrder = !el.classList.contains('ds-datatable-sorted-ascending') ? 'ASC' : 'DESC';
324
- movies.update({
325
- sort: {
326
- sortBy: value,
327
- sortOrder: newOrder,
328
- sort: value+' '+newOrder // this is added to pass all needed data in a single value for the sort order transformer
329
- }
330
- });
331
- },
332
- 'genre': function(el, value) {
333
- movies.update({
334
- genreFilter: {
335
- genre: value
336
- }
337
- });
338
- }
339
- }
340
- });
341
-
342
- // only copy the options into the app view, the data should only be
343
- // linked through a datasource - for performance
344
- movieApp.view.movies = movies.options;
345
- // this gives access to movies.options.paging, movies.options.sort, movies.options.genreFilter and movies.options.titleSearch
346
- // as data-simply-field="movies.paging", "movies.sort", "movies.genreFilter" and "movies.titleSearch"
347
-
348
- // load movies list from the fetched json
349
- movies.update({
350
- data: json
351
- });
352
-
353
- document.body.classList.remove('loading');
354
- })
355
- .catch(console.error);
356
- });
357
- </script>
358
- </body>
359
- </html>
package/make DELETED
@@ -1,18 +0,0 @@
1
- #!/bin/bash
2
- rm dist/simply.everything.js
3
- cat js/simply.observe.js \
4
- js/simply.render.js \
5
- js/simply.path.js \
6
- js/simply.route.js \
7
- js/simply.activate.js \
8
- js/simply.collect.js \
9
- js/simply.command.js \
10
- js/simply.keyboard.js \
11
- js/simply.action.js \
12
- js/simply.resize.js \
13
- js/simply.include.js \
14
- js/simply.view.js \
15
- js/simply.viewmodel.js \
16
- js/simply.api.js \
17
- js/simply.app.js > dist/simply.everything.js
18
- cp js/simply.include.next.js dist/
@@ -1,102 +0,0 @@
1
- simplyRoute = require('../js/simply.route.js');
2
-
3
- test('match fixed url', () => {
4
- simplyRoute.load({
5
- '/foo/': function(params) {
6
- return 'bar';
7
- }
8
- });
9
- expect(simplyRoute.match('/foo/')).toBe('bar');
10
- });
11
-
12
- test('match only from start', () => {
13
- simplyRoute.load({
14
- '/foo/': function(params) {
15
- return 'bar';
16
- },
17
- '/oo/': function(params) {
18
- return 'foobar';
19
- }
20
- });
21
- expect(simplyRoute.match('oo/')).toBe('foobar');
22
- });
23
-
24
- test('match parameter', () => {
25
- simplyRoute.load({
26
- '/bar/:id' : function(params) {
27
- return params.id;
28
- }
29
- });
30
- expect(simplyRoute.match('bar/foobar')).toBe('foobar');
31
- });
32
-
33
- test('multiple parameters', () => {
34
- simplyRoute.load({
35
- '/baz/:id/:page' : function(params) {
36
- return params.id+':'+params.page;
37
- }
38
- });
39
- expect(simplyRoute.match('baz/foobar/1')).toBe('foobar:1');
40
- });
41
-
42
- test('match listener', () => {
43
- simplyRoute.addListener('match', 'oo/', function(args) {
44
- args.path = 'foo/';
45
- return args;
46
- });
47
- simplyRoute.load({
48
- '/oo/': function(params) {
49
- return 'foobar';
50
- },
51
- '/foo/': function(params) {
52
- return 'bar';
53
- }
54
- });
55
- expect(simplyRoute.match('oo/')).toBe('bar');
56
- });
57
-
58
- test('call listener', () => {
59
- simplyRoute.clear();
60
- simplyRoute.addListener('call', 'foo/:id', function(args) {
61
- args.params.id = 'foo'+args.params.id;
62
- return args;
63
- });
64
- simplyRoute.load({
65
- '/foo/:id': function(params) {
66
- return params.id;
67
- }
68
- });
69
- expect(simplyRoute.match('foo/bar')).toBe('foobar');
70
- });
71
-
72
- test('remove listener', () => {
73
- simplyRoute.clear();
74
- var callback = function(args) {
75
- args.params.id = 'foo'+args.params.id;
76
- return args;
77
- };
78
- simplyRoute.addListener('call', 'foo/:id', callback);
79
- simplyRoute.load({
80
- '/foo/:id': function(params) {
81
- return params.id;
82
- }
83
- });
84
- simplyRoute.removeListener('call','foo/:id', callback);
85
- expect(simplyRoute.match('foo/bar')).toBe('bar');
86
- });
87
-
88
- test('multiple listeners', () => {
89
- simplyRoute.clear();
90
- simplyRoute.addListener('call', 'foo/:id', function(args) {
91
- args.params.id+='1';
92
- });
93
- simplyRoute.addListener('call', 'foo/:id', function(args) {
94
- args.params.id+='2';
95
- });
96
- simplyRoute.load({
97
- '/foo/:id': function(params) {
98
- return params.id;
99
- }
100
- });
101
- expect(simplyRoute.match('foo/bar')).toBe('bar12');
102
- });