nali 0.2.9 → 0.3.0
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.
- data/README.md +26 -31
- data/lib/client/javascripts/nali/collection.js.coffee +14 -5
- data/lib/client/javascripts/nali/connection.js.coffee +4 -4
- data/lib/client/javascripts/nali/form2js.min.js +1 -0
- data/lib/client/javascripts/nali/index.js +1 -0
- data/lib/client/javascripts/nali/model.js.coffee +30 -37
- data/lib/client/javascripts/nali/nali.js.coffee +1 -1
- data/lib/client/javascripts/nali/notice.js.coffee +5 -8
- data/lib/client/javascripts/nali/view.js.coffee +17 -22
- data/lib/generator/app/client/stylesheets/{notices → notice}/error.css.sass +0 -0
- data/lib/generator/app/client/stylesheets/{notices → notice}/info.css.sass +0 -0
- data/lib/generator/app/client/stylesheets/{notices → notice}/warning.css.sass +0 -0
- data/lib/nali/connection.rb +14 -15
- data/lib/nali/controller.rb +3 -3
- data/lib/nali/generator.rb +8 -0
- data/lib/nali/model.rb +6 -4
- data/lib/nali/version.rb +1 -1
- metadata +6 -5
data/README.md
CHANGED
@@ -1,31 +1,26 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
**Nali** - это фреймворк для разработки асинхронных веб приложений, включающий в себя веб-сервер и инструменты для создания как клиентской, так и серверной части. Серверная часть разрабатывается на языке **Ruby**, клиентская часть на **Coffeescript** (или Javascript), **Sass** (или
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
***bundle exec thin start***
|
28
|
-
|
29
|
-
6. Откройте браузер и перейдите по адресу `http://localhost:3000`
|
30
|
-
|
31
|
-
Вы увидите первую подготовленную страницу "Welcome to Nali"
|
1
|
+
## Добро пожаловать в Nali
|
2
|
+
|
3
|
+
**Nali** - это фреймворк для разработки асинхронных веб приложений, включающий в себя веб-сервер и инструменты для создания как клиентской, так и серверной части. Серверная часть разрабатывается на языке **Ruby**, клиентская часть на **Coffeescript** (или Javascript), **Sass** (или scss, css) и **Html** (или erb)
|
4
|
+
|
5
|
+
#### Документация
|
6
|
+
|
7
|
+
* [**Начало работы**](../../wiki/Начало-работы)
|
8
|
+
* [**Структура приложения**](../../wiki/Структура-приложения)
|
9
|
+
* **Основные компоненты**
|
10
|
+
* [Модель](../../wiki/Модель)
|
11
|
+
* [Вид](../../wiki/Вид)
|
12
|
+
* [Контроллер](../../wiki/Контроллер)
|
13
|
+
* [Коллекция](../../wiki/Коллекция)
|
14
|
+
* **Клиентская часть**
|
15
|
+
* [Базовый объект Nali](../../wiki/Nali)
|
16
|
+
* [Старт приложения](../../wiki/Nali.Application)
|
17
|
+
* [Система событий](../../wiki/Система-событий)
|
18
|
+
* [Модель уведомлений Notice](../../wiki/Nali.Notice)
|
19
|
+
* [Роутер](../../wiki/Nali.Router)
|
20
|
+
* [Соединение с сервером](../../wiki/Nali.Connection)
|
21
|
+
* [Работа с Cookie](../../wiki/Nali.Cookie)
|
22
|
+
* **Серверная часть**
|
23
|
+
* [Работа с клиентами](../../Работа с клиентами)
|
24
|
+
* [Маршрутизация](../../Маршрутизация)
|
25
|
+
* [Генератор](../../Генератор)
|
26
|
+
* [Rake задачи](../../Rake задачи)
|
@@ -7,20 +7,25 @@ Nali.extend Collection:
|
|
7
7
|
cloning: ->
|
8
8
|
@subscribeTo @Model, "create.#{ @model._name.lower() }", @onModelCreated
|
9
9
|
@subscribeTo @Model, "update.#{ @model._name.lower() }", @onModelUpdated
|
10
|
+
@subscribeTo @Model, "destroy.#{ @model._name.lower() }", @onModelDestroyed
|
10
11
|
@adaptations = apply: [], cancel: []
|
11
12
|
@ordering = {}
|
12
13
|
@adaptCollection()
|
13
|
-
@
|
14
|
+
@refilter()
|
15
|
+
@
|
16
|
+
|
17
|
+
refilter: ->
|
18
|
+
@model.each ( model ) => @add model if model.isCorrect( @filters ) and not ( model in @ )
|
14
19
|
@
|
15
20
|
|
16
21
|
new: ( model, filters ) ->
|
17
22
|
@clone model: model, filters: filters
|
18
23
|
|
19
|
-
onModelCreated: (
|
24
|
+
onModelCreated: ( model ) ->
|
20
25
|
@add model if not @freezed and model.isCorrect @filters
|
21
26
|
@
|
22
27
|
|
23
|
-
onModelUpdated: (
|
28
|
+
onModelUpdated: ( model ) ->
|
24
29
|
if model.written()
|
25
30
|
if model in @
|
26
31
|
if @freezed or model.isCorrect @filters
|
@@ -32,7 +37,7 @@ Nali.extend Collection:
|
|
32
37
|
@
|
33
38
|
|
34
39
|
onModelDestroyed: ( model ) ->
|
35
|
-
@remove model
|
40
|
+
@remove model if model in @ and not @freezed
|
36
41
|
@
|
37
42
|
|
38
43
|
adaptCollection: ->
|
@@ -57,7 +62,6 @@ Nali.extend Collection:
|
|
57
62
|
for model in [].concat models...
|
58
63
|
Array::push.call @, model
|
59
64
|
@adaptModel model
|
60
|
-
@subscribeTo model, 'destroy', @onModelDestroyed
|
61
65
|
@reorder()
|
62
66
|
@trigger 'update.length.add', model
|
63
67
|
@trigger 'update.length', 'add', model
|
@@ -100,6 +104,7 @@ Nali.extend Collection:
|
|
100
104
|
|
101
105
|
unfreeze: ->
|
102
106
|
@freezed = false
|
107
|
+
@refilter()
|
103
108
|
@
|
104
109
|
|
105
110
|
where: ( filters ) ->
|
@@ -156,6 +161,10 @@ Nali.extend Collection:
|
|
156
161
|
model.hide viewName
|
157
162
|
@
|
158
163
|
|
164
|
+
hide: ( viewName, delay ) ->
|
165
|
+
model.hide viewName, delay for model in @
|
166
|
+
@
|
167
|
+
|
159
168
|
prepareViewToShow: ( view ) ->
|
160
169
|
unless view in @::toShowViews
|
161
170
|
@::toShowViews.push view
|
@@ -53,11 +53,11 @@ Nali.extend Connection:
|
|
53
53
|
@Model.sync message.params
|
54
54
|
@
|
55
55
|
|
56
|
-
|
57
|
-
if model
|
56
|
+
callMethod: ( { model, method, params } ) ->
|
57
|
+
if model is 'Notice' then @Notice[ method ] params
|
58
|
+
else
|
58
59
|
[ model, id ] = model.split '.'
|
59
|
-
@Model.
|
60
|
-
else @Notice[ notice ] params
|
60
|
+
@Model.callStackAdd model: model, id: id, method: method, params: params
|
61
61
|
@
|
62
62
|
|
63
63
|
success: ( message ) ->
|
@@ -0,0 +1 @@
|
|
1
|
+
(function(e,t){if(typeof define==="function"&&define.amd){define(t)}else{e.form2js=t()}})(this,function(){"use strict";function e(e,r,i,s,o,u){u=u?true:false;if(typeof i=="undefined"||i==null)i=true;if(typeof r=="undefined"||r==null)r=".";if(arguments.length<5)o=false;e=typeof e=="string"?document.getElementById(e):e;var a=[],f,l=0;if(e.constructor==Array||typeof NodeList!="undefined"&&e.constructor==NodeList){while(f=e[l++]){a=a.concat(n(f,s,o,u))}}else{a=n(e,s,o,u)}return t(a,i,r)}function t(e,t,n){var r={},i={},s,o,u,a,f,l,c,h,p,d,v,m,g;for(s=0;s<e.length;s++){f=e[s].value;if(t&&(f===""||f===null))continue;m=e[s].name;g=m.split(n);l=[];c=r;h="";for(o=0;o<g.length;o++){v=g[o].split("][");if(v.length>1){for(u=0;u<v.length;u++){if(u==0){v[u]=v[u]+"]"}else if(u==v.length-1){v[u]="["+v[u]}else{v[u]="["+v[u]+"]"}d=v[u].match(/([a-z_]+)?\[([a-z_][a-z0-9_]+?)\]/i);if(d){for(a=1;a<d.length;a++){if(d[a])l.push(d[a])}}else{l.push(v[u])}}}else l=l.concat(v)}for(o=0;o<l.length;o++){v=l[o];if(v.indexOf("[]")>-1&&o==l.length-1){p=v.substr(0,v.indexOf("["));h+=p;if(!c[p])c[p]=[];c[p].push(f)}else if(v.indexOf("[")>-1){p=v.substr(0,v.indexOf("["));d=v.replace(/(^([a-z_]+)?\[)|(\]$)/gi,"");h+="_"+p+"_"+d;if(!i[h])i[h]={};if(p!=""&&!c[p])c[p]=[];if(o==l.length-1){if(p==""){c.push(f);i[h][d]=c[c.length-1]}else{c[p].push(f);i[h][d]=c[p][c[p].length-1]}}else{if(!i[h][d]){if(/^[0-9a-z_]+\[?/i.test(l[o+1]))c[p].push({});else c[p].push([]);i[h][d]=c[p][c[p].length-1]}}c=i[h][d]}else{h+=v;if(o<l.length-1){if(!c[v])c[v]={};c=c[v]}else{c[v]=f}}}}return r}function n(e,t,n,s){var o=i(e,t,n,s);return o.length>0?o:r(e,t,n,s)}function r(e,t,n,r){var s=[],o=e.firstChild;while(o){s=s.concat(i(o,t,n,r));o=o.nextSibling}return s}function i(e,t,n,i){if(e.disabled&&!i)return[];var u,a,f,l=s(e,n);u=t&&t(e);if(u&&u.name){f=[u]}else if(l!=""&&e.nodeName.match(/INPUT|TEXTAREA/i)){a=o(e,i);if(null===a){f=[]}else{f=[{name:l,value:a}]}}else if(l!=""&&e.nodeName.match(/SELECT/i)){a=o(e,i);f=[{name:l.replace(/\[\]$/,""),value:a}]}else{f=r(e,t,n,i)}return f}function s(e,t){if(e.name&&e.name!="")return e.name;else if(t&&e.id&&e.id!="")return e.id;else return""}function o(e,t){if(e.disabled&&!t)return null;switch(e.nodeName){case"INPUT":case"TEXTAREA":switch(e.type.toLowerCase()){case"radio":if(e.checked&&e.value==="false")return false;case"checkbox":if(e.checked&&e.value==="true")return true;if(!e.checked&&e.value==="true")return false;if(e.checked)return e.value;break;case"button":case"reset":case"submit":case"image":return"";break;default:return e.value;break}break;case"SELECT":return u(e);break;default:break}return null}function u(e){var t=e.multiple,n=[],r,i,s;if(!t)return e.value;for(r=e.getElementsByTagName("option"),i=0,s=r.length;i<s;i++){if(r[i].selected)n.push(r[i].value)}return n}return e})
|
@@ -14,7 +14,7 @@ Nali.extend Model:
|
|
14
14
|
tables: {}
|
15
15
|
attributes: {}
|
16
16
|
updated: 0
|
17
|
-
|
17
|
+
callStack: []
|
18
18
|
destroyed: false
|
19
19
|
|
20
20
|
adapt: ->
|
@@ -36,18 +36,18 @@ Nali.extend Model:
|
|
36
36
|
unless @[ hideMethod = 'hide' + shortCap ]? then @[ hideMethod ] = -> @hide short
|
37
37
|
@
|
38
38
|
|
39
|
-
|
40
|
-
# добавляет
|
41
|
-
@
|
42
|
-
@
|
39
|
+
callStackAdd: ( params ) ->
|
40
|
+
# добавляет задачу в очередь на выполнение, запускает выполнение очереди
|
41
|
+
@callStack.push params
|
42
|
+
@runStack()
|
43
43
|
@
|
44
44
|
|
45
|
-
|
46
|
-
# запускает выполнение
|
47
|
-
for item, index in @
|
45
|
+
runStack: ->
|
46
|
+
# запускает выполнение задач у существующих моделей
|
47
|
+
for item, index in @callStack[ 0.. ]
|
48
48
|
if model = @extensions[ item.model ].find item.id
|
49
|
-
model[ item.
|
50
|
-
@
|
49
|
+
model[ item.method ] item.params
|
50
|
+
@callStack.splice @callStack.indexOf( item ), 1
|
51
51
|
@
|
52
52
|
|
53
53
|
# работа с моделями
|
@@ -58,13 +58,6 @@ Nali.extend Model:
|
|
58
58
|
@setRelations()
|
59
59
|
@
|
60
60
|
|
61
|
-
force: ( params = {} ) ->
|
62
|
-
# создает новую модель с заданными атрибутами
|
63
|
-
attributes = @defaultAttributes()
|
64
|
-
attributes[ name ] = value for name, value of params
|
65
|
-
attributes[ name ] = @normalizeValue value for name, value of attributes
|
66
|
-
@clone( attributes: attributes ).accessing()
|
67
|
-
|
68
61
|
save: ( success, failure ) ->
|
69
62
|
# отправляет на сервер запрос на сохранение модели, вызывает success в случае успеха и failure при неудаче
|
70
63
|
if @isValid()
|
@@ -109,7 +102,7 @@ Nali.extend Model:
|
|
109
102
|
@table.push @
|
110
103
|
@onCreate?()
|
111
104
|
@Model.trigger "create.#{ @_name.lower() }", @
|
112
|
-
@Model.
|
105
|
+
@Model.runStack()
|
113
106
|
@
|
114
107
|
|
115
108
|
remove: ->
|
@@ -119,13 +112,16 @@ Nali.extend Model:
|
|
119
112
|
delete @table.index[ @id ]
|
120
113
|
@table.splice @table.indexOf( @ ), 1
|
121
114
|
@trigger 'destroy'
|
115
|
+
@Model.trigger "destroy.#{ @_name.lower() }", @
|
122
116
|
@onDestroy?()
|
123
117
|
@unsubscribeAll()
|
124
118
|
@
|
125
119
|
|
126
120
|
new: ( attributes ) ->
|
127
121
|
# создает модель, не сохраняя её на сервере
|
128
|
-
@
|
122
|
+
model = @clone( attributes: @defaultAttributes() ).accessing()
|
123
|
+
model[ name ] = @normalizeValue value for name, value of attributes
|
124
|
+
model
|
129
125
|
|
130
126
|
create: ( attributes, success, failure ) ->
|
131
127
|
# создает модель, и сохраняет её на сервере, вызывает success в случае успеха и failure при неудаче
|
@@ -136,7 +132,7 @@ Nali.extend Model:
|
|
136
132
|
if not updated or updated > @updated
|
137
133
|
@created = created if created
|
138
134
|
changed = []
|
139
|
-
changed.push name for name, value of attributes when @
|
135
|
+
changed.push name for name, value of attributes when @updateProperty name, value
|
140
136
|
if changed.length
|
141
137
|
@updated = updated if updated
|
142
138
|
@onUpdate? changed
|
@@ -144,8 +140,8 @@ Nali.extend Model:
|
|
144
140
|
@Model.trigger "update.#{ @_name.lower() }", @
|
145
141
|
@
|
146
142
|
|
147
|
-
|
148
|
-
# обновляет один атрибут модели, проверяя его валидность, генерирует событие update.
|
143
|
+
updateProperty: ( name, value ) ->
|
144
|
+
# обновляет один атрибут модели, проверяя его валидность, генерирует событие update.propertyName
|
149
145
|
value = @normalizeValue value
|
150
146
|
if @[ name ] isnt value and @isValidAttributeValue( name, value )
|
151
147
|
@[ name ] = value
|
@@ -172,12 +168,7 @@ Nali.extend Model:
|
|
172
168
|
|
173
169
|
where: ( filters ) ->
|
174
170
|
# возвращает коллекцию моделей соответствующих фильтру
|
175
|
-
|
176
|
-
if @forced and not collection.length
|
177
|
-
attributes = {}
|
178
|
-
attributes[ key ] = value for key, value of filters when typeof value in [ 'number', 'string' ]
|
179
|
-
collection.add @new attributes
|
180
|
-
collection
|
171
|
+
@Collection.new @, filters
|
181
172
|
|
182
173
|
all: ->
|
183
174
|
# возвращает коллекцию всех моделей
|
@@ -203,8 +194,8 @@ Nali.extend Model:
|
|
203
194
|
attributes = id: @guid()
|
204
195
|
for name, value of @attributes
|
205
196
|
if value instanceof Object
|
206
|
-
attributes[ name ] = if value.default? then value.default else null
|
207
|
-
else attributes[ name ] = value
|
197
|
+
attributes[ name ] = if value.default? then @normalizeValue value.default else null
|
198
|
+
else attributes[ name ] = @normalizeValue value
|
208
199
|
attributes
|
209
200
|
|
210
201
|
normalizeValue: ( value ) ->
|
@@ -333,8 +324,8 @@ Nali.extend Model:
|
|
333
324
|
@[ name ] = model.where correct: ->
|
334
325
|
return true for model in @[ through ] when model[ key ] is @
|
335
326
|
false
|
336
|
-
@[ name ].subscribeTo @[ through ], 'update.length.add', (
|
337
|
-
@[ name ].subscribeTo @[ through ], 'update.length.remove', (
|
327
|
+
@[ name ].subscribeTo @[ through ], 'update.length.add', ( model ) -> @add model[ key ]
|
328
|
+
@[ name ].subscribeTo @[ through ], 'update.length.remove', ( model ) -> @remove model[ key ]
|
338
329
|
@[ name ]
|
339
330
|
@
|
340
331
|
|
@@ -354,10 +345,10 @@ Nali.extend Model:
|
|
354
345
|
# функция возвращает объект вида при успехе либо null при неудаче
|
355
346
|
if ( view = @view( name ) )? then view.show insertTo else null
|
356
347
|
|
357
|
-
hide: ( name ) ->
|
348
|
+
hide: ( name, delay ) ->
|
358
349
|
# удаляет html-код вида со страницы
|
359
350
|
# функция возвращает объект вида при успехе либо null при неудаче
|
360
|
-
if ( view = @view( name ) )? then view.hide
|
351
|
+
if ( view = @view( name ) )? then view.hide delay else null
|
361
352
|
|
362
353
|
# валидации
|
363
354
|
|
@@ -390,12 +381,14 @@ Nali.extend Model:
|
|
390
381
|
|
391
382
|
isValidAttributeValue: ( name, value ) ->
|
392
383
|
# проверяет валидно ли значение для определенного атрибута модели, вызывается при проверке
|
393
|
-
# валидности модели, а также в методе
|
384
|
+
# валидности модели, а также в методе updateProperty() перед изменением значения атрибута, если значение
|
394
385
|
# валидно то вызов model.isValidAttributeValue( name, value )? вернет true, иначе false
|
395
386
|
for validation, tester of @validations when ( filter = @::attributes[ name ]?[ validation ] )?
|
396
387
|
unless tester.call @, value, filter
|
397
388
|
console.warn 'Attribute %s of model %O has not validate %s', name, @, validation
|
398
|
-
|
399
|
-
|
389
|
+
if notice = @::attributes[ name ].notice
|
390
|
+
for type, params of notice
|
391
|
+
if @Notice[ type ]? then @Notice[ type ] params
|
392
|
+
else console.warn 'Unknown Notice type "%s"', type
|
400
393
|
return false
|
401
394
|
true
|
@@ -2,19 +2,16 @@ Nali.Model.extend Notice:
|
|
2
2
|
|
3
3
|
initialize: ->
|
4
4
|
@::::expand Notice: @
|
5
|
+
@addMethods()
|
5
6
|
|
6
7
|
prepare: ( params ) ->
|
7
8
|
params = message: params if typeof params is 'string'
|
8
9
|
params
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@new( @prepare params ).show 'warning'
|
15
|
-
|
16
|
-
error: ( params ) ->
|
17
|
-
@new( @prepare params ).show 'error'
|
11
|
+
addMethods: ->
|
12
|
+
for name of @views
|
13
|
+
do ( name ) =>
|
14
|
+
@[ name ] = ( params ) => @new( @prepare params ).show name
|
18
15
|
|
19
16
|
|
20
17
|
Nali.View.extend
|
@@ -28,7 +28,7 @@ Nali.extend View:
|
|
28
28
|
@subscribeTo source, event, @onSourceUpdated
|
29
29
|
|
30
30
|
insertTo: ->
|
31
|
-
if ( layout = @layout() )?.childOf? 'View' then layout.show().
|
31
|
+
if ( layout = @layout() )?.childOf? 'View' then layout.show().yield
|
32
32
|
else @Application.htmlContainer
|
33
33
|
|
34
34
|
draw: ->
|
@@ -45,6 +45,7 @@ Nali.extend View:
|
|
45
45
|
@subscribeTo @model, 'destroy', @onSourceDestroyed
|
46
46
|
@element.appendTo insertTo
|
47
47
|
setTimeout ( => @onShow() ), 5 if @onShow?
|
48
|
+
@trigger 'show'
|
48
49
|
@visible = true
|
49
50
|
@runModelCallback 'afterShow'
|
50
51
|
else
|
@@ -54,18 +55,19 @@ Nali.extend View:
|
|
54
55
|
hide: ( delay = 0 ) ->
|
55
56
|
if @visible
|
56
57
|
@runModelCallback 'beforeHide'
|
57
|
-
@hideDelay = delay if typeof( delay ) is 'number' and delay
|
58
58
|
@onHide?()
|
59
59
|
@trigger 'hide'
|
60
60
|
@runAssistants 'hide'
|
61
|
-
@hideElement
|
61
|
+
@hideElement delay or @hideDelay
|
62
62
|
@destroyObservation()
|
63
63
|
@visible = false
|
64
64
|
@runModelCallback 'afterHide'
|
65
65
|
@
|
66
66
|
|
67
|
-
hideElement: ->
|
68
|
-
if
|
67
|
+
hideElement: ( delay ) ->
|
68
|
+
if delay and typeof( delay ) is 'number'
|
69
|
+
setTimeout ( => @removeElement() ), delay
|
70
|
+
else @removeElement()
|
69
71
|
@
|
70
72
|
|
71
73
|
removeElement: ->
|
@@ -83,7 +85,7 @@ Nali.extend View:
|
|
83
85
|
|
84
86
|
runForm: ( event ) ->
|
85
87
|
event.preventDefault()
|
86
|
-
@runUrl event.currentTarget.getAttribute( 'action' ),
|
88
|
+
@runUrl event.currentTarget.getAttribute( 'action' ), form2js event.currentTarget, '.', false
|
87
89
|
@
|
88
90
|
|
89
91
|
runUrl: ( url, params ) ->
|
@@ -100,7 +102,7 @@ Nali.extend View:
|
|
100
102
|
|
101
103
|
parseUrlSegments: ( segments ) ->
|
102
104
|
params = []
|
103
|
-
for segment in segments
|
105
|
+
for segment in segments when segment isnt ''
|
104
106
|
[ name, value ] = segment.split ':'
|
105
107
|
if value
|
106
108
|
last = params[ params.length - 1 ]
|
@@ -109,17 +111,6 @@ Nali.extend View:
|
|
109
111
|
else params.push name
|
110
112
|
params
|
111
113
|
|
112
|
-
formToHash: ( form ) ->
|
113
|
-
params = {}
|
114
|
-
for element in form.elements
|
115
|
-
if name = element.name or element.id
|
116
|
-
property = ( keys = name.match /[^\[\]]+/g ).pop()
|
117
|
-
target = params
|
118
|
-
for key in keys
|
119
|
-
target = if target[ key ] instanceof Object then target[ key ] else target[ key ] = {}
|
120
|
-
target[ property ] = element.value
|
121
|
-
params
|
122
|
-
|
123
114
|
parseEvents: ->
|
124
115
|
@eventsMap = []
|
125
116
|
if @events
|
@@ -166,7 +157,6 @@ Nali.extend View:
|
|
166
157
|
if container = document.querySelector '#' + @_name.underscore()
|
167
158
|
@template = container.innerHTML.trim().replace( /\s+/g, ' ' )
|
168
159
|
.replace( /({\s*\+.+?\s*})/g, ' <assist>$1</assist>' )
|
169
|
-
.replace( /{\s*yield\s*}/g, '<div class="yield"></div>' )
|
170
160
|
unless RegExp( "^<[^>]+" + @_name ).test @template
|
171
161
|
@template = "<div class=\"#{ @_name }\">#{ @template }</div>"
|
172
162
|
@parseAssistants()
|
@@ -184,7 +174,9 @@ Nali.extend View:
|
|
184
174
|
|
185
175
|
scanAssistants: ( node, path = [] ) ->
|
186
176
|
if node.nodeType is 3
|
187
|
-
if
|
177
|
+
if /{\s*yield\s*}/.test( node.textContent.trim() ) and node.parentNode.childNodes.length is 1
|
178
|
+
@assistantsMap.push nodepath: path, type: 'Yield'
|
179
|
+
else if /^{\s*\w+ of @\w*\s*}$/.test( node.textContent.trim() ) and node.parentNode.childNodes.length is 1
|
188
180
|
@assistantsMap.push nodepath: path, type: 'Relation'
|
189
181
|
else if /{\s*.+?\s*}/.test node.textContent
|
190
182
|
@assistantsMap.push nodepath: path, type: 'Text'
|
@@ -238,7 +230,7 @@ Nali.extend View:
|
|
238
230
|
_node = @_ node
|
239
231
|
|
240
232
|
updateSource = ->
|
241
|
-
( params = {} )[ property ] = node.value
|
233
|
+
( params = {} )[ property ] = if node.type is 'checkbox' and !node.checked then null else node.value
|
242
234
|
source.update params
|
243
235
|
source.save() unless node.form?
|
244
236
|
|
@@ -251,7 +243,7 @@ Nali.extend View:
|
|
251
243
|
when node.type in [ 'checkbox', 'radio' ]
|
252
244
|
[
|
253
245
|
-> node.checked = source[ property ] + '' is node.value
|
254
|
-
-> _node.on 'change', => updateSource.call @ if node.checked is true
|
246
|
+
-> _node.on 'change', => updateSource.call @ if node.type is 'checkbox' or node.checked is true
|
255
247
|
]
|
256
248
|
when node.type is 'select-one'
|
257
249
|
[
|
@@ -268,6 +260,9 @@ Nali.extend View:
|
|
268
260
|
_node.off 'change'
|
269
261
|
@
|
270
262
|
|
263
|
+
addYieldAssistant: ( node ) ->
|
264
|
+
( @yield = node.parentNode ).removeChild node
|
265
|
+
|
271
266
|
addRelationAssistant: ( node ) ->
|
272
267
|
[ match, name, chain ] = node.textContent.match /{\s*(\w+) of @(\w*)\s*}/
|
273
268
|
( insertTo = node.parentNode ).removeChild node
|
File without changes
|
File without changes
|
File without changes
|
data/lib/nali/connection.rb
CHANGED
@@ -7,14 +7,16 @@ module EventMachine
|
|
7
7
|
@watches = {}
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def storage
|
11
11
|
@storage ||= {}
|
12
|
-
|
12
|
+
end
|
13
|
+
|
14
|
+
def []( name = nil )
|
15
|
+
name ? ( storage[ name ] or nil ) : storage
|
13
16
|
end
|
14
17
|
|
15
|
-
def []=( name, value
|
16
|
-
|
17
|
-
@storage[ name ] = value
|
18
|
+
def []=( name, value )
|
19
|
+
storage[ name ] = value
|
18
20
|
end
|
19
21
|
|
20
22
|
def watches
|
@@ -56,16 +58,13 @@ module EventMachine
|
|
56
58
|
end
|
57
59
|
end
|
58
60
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
message[ :params ] = params
|
68
|
-
send_json message
|
61
|
+
def call_method( method, model, params = nil )
|
62
|
+
model = "#{ model.class.name }.#{ model.id }" if model.is_a?( ActiveRecord::Base )
|
63
|
+
send_json action: 'callMethod', model: model, method: method, params: params
|
64
|
+
end
|
65
|
+
|
66
|
+
def notice( method, params = nil )
|
67
|
+
call_method method, 'Notice', params
|
69
68
|
end
|
70
69
|
|
71
70
|
def info( params )
|
data/lib/nali/controller.rb
CHANGED
@@ -33,10 +33,10 @@ module Nali
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def save
|
36
|
-
params[ :id ].to_i.to_s == params[ :id ].to_s ?
|
36
|
+
params[ :id ].to_i.to_s == params[ :id ].to_s ? _update : _create
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
39
|
+
def _create
|
40
40
|
model = model_class.new params
|
41
41
|
model.access_action( :create, client ) do |options|
|
42
42
|
permit_params options
|
@@ -47,7 +47,7 @@ module Nali
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
def
|
50
|
+
def _update
|
51
51
|
if model = model_class.find_by_id( params[ :id ] )
|
52
52
|
model.access_action( :update, client ) do |options|
|
53
53
|
permit_params options
|
data/lib/nali/generator.rb
CHANGED
@@ -23,10 +23,16 @@ module Nali
|
|
23
23
|
dirs << File.join( target_path, 'db' )
|
24
24
|
dirs << File.join( target_path, 'db/migrate' )
|
25
25
|
dirs << File.join( target_path, 'lib' )
|
26
|
+
dirs << File.join( target_path, 'lib/client' )
|
27
|
+
dirs << File.join( target_path, 'lib/client/javascripts' )
|
28
|
+
dirs << File.join( target_path, 'lib/client/stylesheets' )
|
26
29
|
dirs << File.join( target_path, 'public' )
|
27
30
|
dirs << File.join( target_path, 'public/client' )
|
28
31
|
dirs << File.join( target_path, 'tmp' )
|
29
32
|
dirs << File.join( target_path, 'vendor' )
|
33
|
+
dirs << File.join( target_path, 'vendor/client' )
|
34
|
+
dirs << File.join( target_path, 'vendor/client/javascripts' )
|
35
|
+
dirs << File.join( target_path, 'vendor/client/stylesheets' )
|
30
36
|
dirs << File.join( target_path, 'config/initializers' )
|
31
37
|
dirs.each { |path| Dir.mkdir( path ) unless Dir.exists?( path ) }
|
32
38
|
puts "Application #{ name } created"
|
@@ -116,6 +122,8 @@ end"
|
|
116
122
|
|
117
123
|
helpers: {}
|
118
124
|
|
125
|
+
onDraw: ->
|
126
|
+
|
119
127
|
onShow: ->
|
120
128
|
|
121
129
|
onHide: ->"
|
data/lib/nali/model.rb
CHANGED
@@ -38,7 +38,9 @@ module Nali
|
|
38
38
|
relations << value
|
39
39
|
elsif value.is_a?( ActiveRecord::Base )
|
40
40
|
relations << value
|
41
|
-
|
41
|
+
if reflection = self.class.reflections[ option ] and reflection.macro == :belongs_to
|
42
|
+
params[ :attributes ][ option.to_s + '_id' ] = value.id
|
43
|
+
end
|
42
44
|
else
|
43
45
|
params[ :attributes ][ option ] = value
|
44
46
|
end
|
@@ -64,9 +66,9 @@ module Nali
|
|
64
66
|
watches.flatten.each { |client| client.watch self }
|
65
67
|
clients.each { |client| client.sync self if client.watch?( self ) }
|
66
68
|
end
|
67
|
-
|
68
|
-
def
|
69
|
-
clients.each { |client| client.
|
69
|
+
|
70
|
+
def call_method( name, params )
|
71
|
+
clients.each { |client| client.call_method self, name, params if client.watch?( self ) }
|
70
72
|
end
|
71
73
|
|
72
74
|
private
|
data/lib/nali/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nali
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-11-
|
12
|
+
date: 2014-11-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thin
|
@@ -208,6 +208,7 @@ files:
|
|
208
208
|
- lib/client/javascripts/nali/collection.js.coffee
|
209
209
|
- lib/client/javascripts/nali/application.js.coffee
|
210
210
|
- lib/client/javascripts/nali/index.js
|
211
|
+
- lib/client/javascripts/nali/form2js.min.js
|
211
212
|
- lib/client/javascripts/nali/connection.js.coffee
|
212
213
|
- lib/nali.rb
|
213
214
|
- lib/nali/extensions.rb
|
@@ -230,10 +231,10 @@ files:
|
|
230
231
|
- lib/generator/app/client/templates/notice/warning.html
|
231
232
|
- lib/generator/app/client/templates/notice/info.html
|
232
233
|
- lib/generator/app/client/templates/home/index.html
|
234
|
+
- lib/generator/app/client/stylesheets/notice/info.css.sass
|
235
|
+
- lib/generator/app/client/stylesheets/notice/error.css.sass
|
236
|
+
- lib/generator/app/client/stylesheets/notice/warning.css.sass
|
233
237
|
- lib/generator/app/client/stylesheets/home/index.css.sass
|
234
|
-
- lib/generator/app/client/stylesheets/notices/info.css.sass
|
235
|
-
- lib/generator/app/client/stylesheets/notices/error.css.sass
|
236
|
-
- lib/generator/app/client/stylesheets/notices/warning.css.sass
|
237
238
|
- lib/generator/app/client/stylesheets/application.css.sass
|
238
239
|
- lib/generator/app/server/models/access.yml
|
239
240
|
- lib/generator/app/server/routes.rb
|