joosy 1.2.0.alpha.37 → 1.2.0.alpha.38
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -1
- data/Gruntfile.coffee +0 -3
- data/README.md +7 -6
- data/bower.json +1 -1
- data/joosy.gemspec +9 -8
- data/lib/extensions/resources-form.js +6 -6
- data/lib/joosy.js +54 -47
- data/package.json +1 -1
- data/spec/joosy/core/application_spec.coffee +0 -2
- data/spec/joosy/core/layout_spec.coffee +1 -1
- data/spec/joosy/core/modules/container_spec.coffee +120 -94
- data/spec/joosy/core/modules/widget_manager_spec.coffee +13 -10
- data/spec/joosy/core/page_spec.coffee +1 -1
- data/spec/joosy/core/widget_spec.coffee +1 -1
- data/spec/joosy/extensions/form/form_spec.coffee +29 -29
- data/src/joosy/core/application.coffee +0 -4
- data/src/joosy/core/joosy.coffee +7 -0
- data/src/joosy/core/layout.coffee +2 -2
- data/src/joosy/core/modules/container.coffee +26 -36
- data/src/joosy/core/modules/widgets_manager.coffee +12 -18
- data/src/joosy/core/page.coffee +2 -2
- data/src/joosy/core/widget.coffee +2 -2
- data/src/joosy/extensions/resources-form/form.coffee +5 -5
- data/templates/application/base/pages/welcome/index.coffee +4 -4
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4b561d444a57bfd3a4d64ff5b106e663122563b
|
4
|
+
data.tar.gz: 0a51e8ca9ea31faae650610fe23612f3d963c69c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3290124949732e0c8c94c1e9df8346fd90443bf093546fe0e1276a177702ebfb6a9c5e3c12c10ddf06303774265e590f9179173911467137678504236b9ab693
|
7
|
+
data.tar.gz: 33466aae0b6c8a9efd02d9692b7f6d23a2786301b430800277e27320f382b52818b520a432a3ef0d65de28b3820bc93e9c640568c936b35321b2006b1c654716
|
data/.travis.yml
CHANGED
data/Gruntfile.coffee
CHANGED
@@ -112,9 +112,6 @@ module.exports = (grunt) ->
|
|
112
112
|
src: [locations.source.build].include ['preloaders', 'resources', 'resources-form'].map (x) ->
|
113
113
|
locations.source.extensions(x).build
|
114
114
|
|
115
|
-
grunt.event.on 'watch', (action, filepath) ->
|
116
|
-
grunt.config ['coffee', 'specs', 'src'], filepath
|
117
|
-
|
118
115
|
#
|
119
116
|
# Tasks
|
120
117
|
#
|
data/README.md
CHANGED
@@ -93,13 +93,14 @@ You assets are at `public/` directory, enjoy!
|
|
93
93
|
While current repository is at the same time NPM package, Ruby gem and Bower component, – the main Core
|
94
94
|
environment is Node.js.
|
95
95
|
|
96
|
-
##
|
96
|
+
## Maintainers
|
97
97
|
|
98
|
-
* Boris Staal
|
99
|
-
* Andrew Shaydurov
|
100
|
-
* Alexander Pavlenko
|
101
|
-
* Peter Zotov ([@whitequark](http://twitter.com/#!/whitequark))
|
98
|
+
* Boris Staal, [@inossidabile](http://staal.io)
|
99
|
+
* Andrew Shaydurov, [@ImGearHead](http://twitter.com/ImGearHead)
|
100
|
+
* Alexander Pavlenko, [@alerticus](http://twitter.com/alerticus)
|
102
101
|
|
103
|
-
##
|
102
|
+
## License
|
103
|
+
|
104
|
+
Copyright 2011-2013 [Boris Staal](http://staal.io)
|
104
105
|
|
105
106
|
It is free software, and may be redistributed under the terms of MIT license.
|
data/bower.json
CHANGED
data/joosy.gemspec
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
require File.expand_path("../lib/joosy.rb", __FILE__)
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
4
|
+
s.name = 'joosy'
|
5
5
|
s.version = Joosy::VERSION
|
6
6
|
s.platform = Gem::Platform::RUBY
|
7
|
-
s.summary =
|
8
|
-
s.email =
|
9
|
-
s.homepage =
|
10
|
-
s.description =
|
11
|
-
s.authors = ['Boris Staal', 'Andrew Shaydurov', '
|
7
|
+
s.summary = 'Joosy Framework'
|
8
|
+
s.email = 'boris@staal.io'
|
9
|
+
s.homepage = 'http://github.com/joosy/joosy'
|
10
|
+
s.description = 'A gem wrapper to include Joosy via the asset pipeline'
|
11
|
+
s.authors = ['Boris Staal', 'Andrew Shaydurov', 'Alexander Pavlenko']
|
12
|
+
s.license = 'MIT'
|
12
13
|
|
13
14
|
s.files = `git ls-files`.split("\n")
|
14
|
-
s.require_paths = [
|
15
|
+
s.require_paths = ['lib']
|
15
16
|
|
16
17
|
s.add_dependency 'sprockets'
|
17
18
|
s.add_dependency 'haml_coffee_assets', '>= 1.12.0'
|
18
|
-
end
|
19
|
+
end
|
@@ -18,9 +18,9 @@ Joosy.Form = (function(_super) {
|
|
18
18
|
|
19
19
|
Form.prototype.substitutions = {};
|
20
20
|
|
21
|
-
Form.
|
21
|
+
Form.mapElements({
|
22
22
|
'fields': 'input,select,textarea'
|
23
|
-
};
|
23
|
+
});
|
24
24
|
|
25
25
|
Form.submit = function(form, options) {
|
26
26
|
if (options == null) {
|
@@ -57,7 +57,7 @@ Joosy.Form = (function(_super) {
|
|
57
57
|
if (this.container.length === 0) {
|
58
58
|
return;
|
59
59
|
}
|
60
|
-
this.
|
60
|
+
this.__assignElements();
|
61
61
|
this.__delegateEvents();
|
62
62
|
method = (_ref = this.container.get(0).getAttribute('method')) != null ? _ref.toLowerCase() : void 0;
|
63
63
|
if (method && !['get', 'post'].any(method)) {
|
@@ -135,7 +135,7 @@ Joosy.Form = (function(_super) {
|
|
135
135
|
Object.each(data, function(property, val) {
|
136
136
|
var entity, i, input, key, _i, _len, _ref, _results;
|
137
137
|
key = _this.concatFieldName(scope, property);
|
138
|
-
input = _this.$fields
|
138
|
+
input = _this.$fields("[name='" + key + "']:not(:file),[name='" + (key.underscore()) + "']:not(:file),[name='" + (key.camelize(false)) + "']:not(:file)");
|
139
139
|
if (input.length > 0) {
|
140
140
|
if (input.is(':checkbox')) {
|
141
141
|
if (val) {
|
@@ -206,7 +206,7 @@ Joosy.Form = (function(_super) {
|
|
206
206
|
|
207
207
|
Form.prototype.__before = function(xhr, settings) {
|
208
208
|
if ((this.before == null) || this.before.apply(this, arguments) === true) {
|
209
|
-
return this.$fields.removeClass(this.invalidationClass);
|
209
|
+
return this.$fields().removeClass(this.invalidationClass);
|
210
210
|
}
|
211
211
|
};
|
212
212
|
|
@@ -250,7 +250,7 @@ Joosy.Form = (function(_super) {
|
|
250
250
|
};
|
251
251
|
|
252
252
|
Form.prototype.findField = function(field) {
|
253
|
-
return this.$fields
|
253
|
+
return this.$fields("[name='" + field + "']");
|
254
254
|
};
|
255
255
|
|
256
256
|
Form.prototype.__markMethod = function(method) {
|
data/lib/joosy.js
CHANGED
@@ -44,6 +44,10 @@ this.Joosy = {
|
|
44
44
|
return (_ref = Joosy.Modules.Events).synchronize.apply(_ref, arguments);
|
45
45
|
}
|
46
46
|
},
|
47
|
+
uid: function() {
|
48
|
+
this.__uid || (this.__uid = 0);
|
49
|
+
return "__joosy" + (this.__uid++);
|
50
|
+
},
|
47
51
|
uuid: function() {
|
48
52
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
49
53
|
var r, v;
|
@@ -217,10 +221,7 @@ Joosy.Application = {
|
|
217
221
|
}
|
218
222
|
this.mergeConfig(options);
|
219
223
|
this.templater = new Joosy.Templaters.RailsJST(this.name);
|
220
|
-
Joosy.Router.__setupRoutes();
|
221
|
-
this.sandboxSelector = Joosy.uuid();
|
222
|
-
this.content().after("<div id='" + this.sandboxSelector + "' style='display:none'></div>");
|
223
|
-
return this.sandboxSelector = '#' + this.sandboxSelector;
|
224
|
+
return Joosy.Router.__setupRoutes();
|
224
225
|
},
|
225
226
|
content: function() {
|
226
227
|
return $(this.selector);
|
@@ -524,9 +525,21 @@ Joosy.Events.SynchronizationContext = (function() {
|
|
524
525
|
/*** src/joosy/core/modules/container ***/
|
525
526
|
|
526
527
|
Joosy.Modules.Container = {
|
527
|
-
events: false,
|
528
|
-
elements: false,
|
529
528
|
eventSplitter: /^(\S+)\s*(.*)$/,
|
529
|
+
included: function() {
|
530
|
+
this.mapElements = function(map) {
|
531
|
+
if (!this.prototype.hasOwnProperty("__elements")) {
|
532
|
+
this.prototype.__elements = Object.clone(this.__super__.__elements) || {};
|
533
|
+
}
|
534
|
+
return Object.merge(this.prototype.__elements, map);
|
535
|
+
};
|
536
|
+
return this.mapEvents = function(map) {
|
537
|
+
if (!this.prototype.hasOwnProperty("__events")) {
|
538
|
+
this.prototype.__events = Object.clone(this.__super__.__events) || {};
|
539
|
+
}
|
540
|
+
return Object.merge(this.prototype.__events, map);
|
541
|
+
};
|
542
|
+
},
|
530
543
|
onRefresh: function(callback) {
|
531
544
|
if (!this.hasOwnProperty("__onRefreshes")) {
|
532
545
|
this.__onRefreshes = [];
|
@@ -538,7 +551,6 @@ Joosy.Modules.Container = {
|
|
538
551
|
},
|
539
552
|
refreshElements: function() {
|
540
553
|
var _this = this;
|
541
|
-
this.__assignElements();
|
542
554
|
if (this.hasOwnProperty("__onRefreshes")) {
|
543
555
|
this.__onRefreshes.each(function(callback) {
|
544
556
|
return callback.apply(_this);
|
@@ -558,24 +570,6 @@ Joosy.Modules.Container = {
|
|
558
570
|
container.html(data);
|
559
571
|
return container;
|
560
572
|
},
|
561
|
-
__collectElements: function() {
|
562
|
-
var elements, klass;
|
563
|
-
elements = Object.extended(this.elements || {});
|
564
|
-
klass = this;
|
565
|
-
while (klass = klass.constructor.__super__) {
|
566
|
-
Joosy.Module.merge(elements, klass.elements, false);
|
567
|
-
}
|
568
|
-
return elements;
|
569
|
-
},
|
570
|
-
__collectEvents: function() {
|
571
|
-
var events, klass;
|
572
|
-
events = Object.extended(this.events || {});
|
573
|
-
klass = this;
|
574
|
-
while (klass = klass.constructor.__super__) {
|
575
|
-
Joosy.Module.merge(events, klass.events, false);
|
576
|
-
}
|
577
|
-
return events;
|
578
|
-
},
|
579
573
|
__extractSelector: function(selector) {
|
580
574
|
var _this = this;
|
581
575
|
selector = selector.replace(/(\$[A-z0-9\.\$]+)/g, function(path) {
|
@@ -594,13 +588,21 @@ Joosy.Modules.Container = {
|
|
594
588
|
__assignElements: function(root, entries) {
|
595
589
|
var _this = this;
|
596
590
|
root || (root = this);
|
597
|
-
entries || (entries = this.
|
591
|
+
entries || (entries = this.__elements);
|
592
|
+
if (!entries) {
|
593
|
+
return;
|
594
|
+
}
|
598
595
|
return Object.each(entries, function(key, value) {
|
599
596
|
if (Object.isObject(value)) {
|
600
597
|
return _this.__assignElements(root['$' + key] = {}, value);
|
601
598
|
} else {
|
602
599
|
value = _this.__extractSelector(value);
|
603
|
-
root['$' + key] =
|
600
|
+
root['$' + key] = function(filter) {
|
601
|
+
if (!filter) {
|
602
|
+
return _this.$(value);
|
603
|
+
}
|
604
|
+
return _this.$(value).filter(filter);
|
605
|
+
};
|
604
606
|
return root['$' + key].selector = value;
|
605
607
|
}
|
606
608
|
});
|
@@ -609,14 +611,17 @@ Joosy.Modules.Container = {
|
|
609
611
|
var events, module,
|
610
612
|
_this = this;
|
611
613
|
module = this;
|
612
|
-
events = this.
|
613
|
-
|
614
|
+
events = this.__events;
|
615
|
+
if (!events) {
|
616
|
+
return;
|
617
|
+
}
|
618
|
+
return Object.each(events, function(key, method) {
|
614
619
|
var callback, eventName, match, selector;
|
615
620
|
if (!Object.isFunction(method)) {
|
616
621
|
method = _this[method];
|
617
622
|
}
|
618
623
|
callback = function(event) {
|
619
|
-
return method.call(module, this, event);
|
624
|
+
return method.call(module, $(this), event);
|
620
625
|
};
|
621
626
|
match = key.match(_this.eventSplitter);
|
622
627
|
eventName = match[1];
|
@@ -1361,6 +1366,14 @@ Joosy.Modules.TimeManager = {
|
|
1361
1366
|
/*** src/joosy/core/modules/widgets_manager ***/
|
1362
1367
|
|
1363
1368
|
Joosy.Modules.WidgetsManager = {
|
1369
|
+
included: function() {
|
1370
|
+
return this.mapWidgets = function(map) {
|
1371
|
+
if (!this.prototype.hasOwnProperty("__widgets")) {
|
1372
|
+
this.prototype.__widgets = Object.clone(this.__super__.__widgets) || {};
|
1373
|
+
}
|
1374
|
+
return Object.merge(this.prototype.__widgets, map);
|
1375
|
+
};
|
1376
|
+
},
|
1364
1377
|
registerWidget: function(container, widget) {
|
1365
1378
|
if (Joosy.Module.hasAncestor(widget, Joosy.Widget)) {
|
1366
1379
|
widget = new widget();
|
@@ -1376,27 +1389,21 @@ Joosy.Modules.WidgetsManager = {
|
|
1376
1389
|
widget.__unload();
|
1377
1390
|
return this.__activeWidgets.splice(this.__activeWidgets.indexOf(widget), 1);
|
1378
1391
|
},
|
1379
|
-
__collectWidgets: function() {
|
1380
|
-
var klass, widgets;
|
1381
|
-
widgets = Object.extended(this.widgets || {});
|
1382
|
-
klass = this;
|
1383
|
-
while (klass = klass.constructor.__super__) {
|
1384
|
-
Joosy.Module.merge(widgets, klass.widgets, false);
|
1385
|
-
}
|
1386
|
-
return widgets;
|
1387
|
-
},
|
1388
1392
|
__setupWidgets: function() {
|
1389
1393
|
var registered, widgets,
|
1390
1394
|
_this = this;
|
1391
|
-
widgets = this.
|
1395
|
+
widgets = this.__widgets;
|
1392
1396
|
registered = Object.extended();
|
1393
|
-
widgets
|
1394
|
-
|
1397
|
+
if (!widgets) {
|
1398
|
+
return;
|
1399
|
+
}
|
1400
|
+
Object.each(widgets, function(selector, widget) {
|
1401
|
+
var activeSelector;
|
1395
1402
|
if (selector === '$container') {
|
1396
1403
|
activeSelector = _this.container;
|
1397
1404
|
} else {
|
1398
|
-
if (
|
1399
|
-
selector = _this.
|
1405
|
+
if (_this.__extractSelector != null) {
|
1406
|
+
selector = _this.__extractSelector(selector);
|
1400
1407
|
}
|
1401
1408
|
activeSelector = $(selector, _this.container);
|
1402
1409
|
}
|
@@ -1539,7 +1546,7 @@ Joosy.Layout = (function(_super) {
|
|
1539
1546
|
|
1540
1547
|
Layout.prototype.__load = function(container) {
|
1541
1548
|
this.container = container;
|
1542
|
-
this.
|
1549
|
+
this.__assignElements();
|
1543
1550
|
this.__delegateEvents();
|
1544
1551
|
this.__setupWidgets();
|
1545
1552
|
return this.__runAfterLoads();
|
@@ -1717,7 +1724,7 @@ Joosy.Page = (function(_super) {
|
|
1717
1724
|
};
|
1718
1725
|
|
1719
1726
|
Page.prototype.__load = function() {
|
1720
|
-
this.
|
1727
|
+
this.__assignElements();
|
1721
1728
|
this.__delegateEvents();
|
1722
1729
|
this.__setupWidgets();
|
1723
1730
|
this.__runAfterLoads(this.params, this.previous);
|
@@ -2232,7 +2239,7 @@ Joosy.Widget = (function(_super) {
|
|
2232
2239
|
if (render && this.__renderer) {
|
2233
2240
|
this.swapContainer(this.container, this.__renderer(this.data || {}));
|
2234
2241
|
}
|
2235
|
-
this.
|
2242
|
+
this.__assignElements();
|
2236
2243
|
this.__delegateEvents();
|
2237
2244
|
this.__setupWidgets();
|
2238
2245
|
this.__runAfterLoads();
|
data/package.json
CHANGED
@@ -11,8 +11,6 @@ describe "Joosy.Application", ->
|
|
11
11
|
Joosy.Application.initialize 'app', '#application', router: {foo: 'bar'}
|
12
12
|
expect(Joosy.Application.page).toBeUndefined()
|
13
13
|
expect(Joosy.Application.selector).toEqual '#application'
|
14
|
-
expect(Joosy.Application.sandboxSelector).toMatch /#[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}/
|
15
|
-
expect($(Joosy.Application.sandboxSelector).length).toEqual 1
|
16
14
|
expect(Joosy.Router.__setupRoutes.callCount).toEqual 1
|
17
15
|
expect(Joosy.Application.name).toEqual 'app'
|
18
16
|
expect(Joosy.Application.config.router.foo).toEqual 'bar'
|
@@ -23,7 +23,7 @@ describe "Joosy.Layout", ->
|
|
23
23
|
|
24
24
|
it "should load itself", ->
|
25
25
|
spies = []
|
26
|
-
spies.push sinon.spy(@box, '
|
26
|
+
spies.push sinon.spy(@box, '__assignElements')
|
27
27
|
spies.push sinon.spy(@box, '__delegateEvents')
|
28
28
|
spies.push sinon.spy(@box, '__setupWidgets')
|
29
29
|
spies.push sinon.spy(@box, '__runAfterLoads')
|
@@ -2,123 +2,149 @@ describe "Joosy.Modules.Container", ->
|
|
2
2
|
|
3
3
|
beforeEach ->
|
4
4
|
@seedGround()
|
5
|
+
|
5
6
|
class @TestContainer extends Joosy.Module
|
6
7
|
@include Joosy.Modules.Container
|
7
|
-
|
8
|
+
@mapElements
|
9
|
+
posts: '.post'
|
8
10
|
content:
|
9
11
|
post1: '#post1'
|
10
12
|
post2: '#post2'
|
11
13
|
footer: '.footer'
|
12
|
-
|
14
|
+
@mapEvents
|
13
15
|
'test': 'onContainerTest'
|
14
16
|
container: $('#application', @ground)
|
17
|
+
|
15
18
|
@box = new @TestContainer()
|
16
19
|
|
17
|
-
it "
|
18
|
-
@box.
|
19
|
-
|
20
|
+
it "reinitializes container", ->
|
21
|
+
oldContainer = @box.container
|
22
|
+
parent = oldContainer.parent()
|
23
|
+
callback = sinon.spy()
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
expect(
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
oldContainer.bind 'test', callback
|
26
|
+
oldContainer.trigger 'test'
|
27
|
+
expect(callback.callCount).toEqual 1
|
28
|
+
|
29
|
+
newContainer = Joosy.Modules.Container.swapContainer oldContainer, 'new content'
|
30
|
+
newContainer.trigger 'test'
|
31
|
+
expect(newContainer.html()).toEqual 'new content'
|
32
|
+
expect(newContainer.parent().get(0)).toBe parent.get 0
|
33
|
+
expect(callback.callCount).toEqual 1
|
34
|
+
|
35
|
+
it "calls afterRefreshes", ->
|
32
36
|
callback = sinon.spy()
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
expect(new_container.html()).toEqual 'new content'
|
38
|
-
expect(new_container.parent().get(0)).toBe parent.get 0
|
37
|
+
@box.onRefresh -> callback()
|
38
|
+
|
39
|
+
@box.refreshElements()
|
40
|
+
@box.refreshElements()
|
39
41
|
expect(callback.callCount).toEqual 1
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
describe "elements", ->
|
44
|
+
it "declares", ->
|
45
|
+
class SubContainerA extends @TestContainer
|
46
|
+
@mapElements
|
47
|
+
first: 'first'
|
48
|
+
second: 'second'
|
49
|
+
class SubContainerB extends SubContainerA
|
50
|
+
@mapElements
|
51
|
+
first: 'overrided'
|
52
|
+
third: 'third'
|
53
|
+
|
54
|
+
expect((new SubContainerB()).__elements).toEqual Object.extended
|
55
|
+
posts: '.post'
|
56
|
+
content:
|
57
|
+
post1: '#post1'
|
58
|
+
post2: '#post2'
|
48
59
|
first: 'overrided'
|
60
|
+
second: 'second'
|
49
61
|
third: 'third'
|
50
|
-
|
51
|
-
target = subBox.__collectElements()
|
52
|
-
expect(target).toEqual Object.extended
|
53
|
-
content:
|
54
|
-
post1: '#post1'
|
55
|
-
post2: '#post2'
|
56
|
-
first: 'overrided'
|
57
|
-
second: 'second'
|
58
|
-
third: 'third'
|
59
|
-
footer: '.footer'
|
60
|
-
target = (new @TestContainer()).__collectElements()
|
61
|
-
expect(target).toEqual Object.extended
|
62
|
-
footer: '.footer'
|
63
|
-
content:
|
64
|
-
post1: '#post1'
|
65
|
-
post2: '#post2'
|
66
|
-
|
67
|
-
it "should resolve element selector", ->
|
68
|
-
@box.refreshElements()
|
62
|
+
footer: '.footer'
|
69
63
|
|
70
|
-
|
71
|
-
|
64
|
+
expect((new @TestContainer()).__elements).toEqual Object.extended
|
65
|
+
posts: '.post'
|
66
|
+
footer: '.footer'
|
67
|
+
content:
|
68
|
+
post1: '#post1'
|
69
|
+
post2: '#post2'
|
70
|
+
|
71
|
+
console.log (new @TestContainer)
|
72
|
+
|
73
|
+
it "resolve selector", ->
|
74
|
+
@box.__assignElements()
|
75
|
+
|
76
|
+
target = @box.__extractSelector '$footer'
|
77
|
+
expect(target).toEqual '.footer'
|
78
|
+
|
79
|
+
target = @box.__extractSelector '$content.$post1'
|
80
|
+
expect(target).toEqual '#post1'
|
81
|
+
|
82
|
+
target = @box.__extractSelector '$footer tr'
|
83
|
+
expect(target).toEqual '.footer tr'
|
84
|
+
|
85
|
+
target = @box.__extractSelector '$footer $content.$post1'
|
86
|
+
expect(target).toEqual '.footer #post1'
|
87
|
+
|
88
|
+
it "nesteds get assigned", ->
|
89
|
+
@box.__assignElements()
|
90
|
+
expect(@box.$content.$post1().get 0).toBe $('#post1').get 0
|
91
|
+
|
92
|
+
it "get assigned", ->
|
93
|
+
@box.__assignElements()
|
72
94
|
|
73
|
-
|
74
|
-
|
95
|
+
target = @box.$footer().get 0
|
96
|
+
expect(target).toBeTruthy()
|
97
|
+
expect(target).toBe $('.footer', @box.container).get 0
|
98
|
+
expect(target).toBe @box.$('.footer').get 0
|
75
99
|
|
76
|
-
|
77
|
-
|
100
|
+
it "allow to filter", ->
|
101
|
+
@box.__assignElements()
|
78
102
|
|
79
|
-
|
80
|
-
|
103
|
+
target = @box.$posts('#post1').get 0
|
104
|
+
expect(target).toBeTruthy()
|
105
|
+
expect(target).toBe $('#post1', @box.container).get 0
|
81
106
|
|
82
|
-
|
83
|
-
|
84
|
-
|
107
|
+
it "respect container boundaries", ->
|
108
|
+
@box.__assignElements()
|
109
|
+
|
110
|
+
@ground.prepend('<div class="footer" />') # out of container
|
111
|
+
target = @box.$footer().get 0
|
112
|
+
expect(target).toBeTruthy()
|
113
|
+
expect(target).toBe $('.footer', @box.container).get 0
|
114
|
+
expect(target).toBe @box.$('.footer').get 0
|
115
|
+
|
116
|
+
describe "events", ->
|
117
|
+
it "declares", ->
|
118
|
+
class SubContainerA extends @TestContainer
|
119
|
+
@mapEvents
|
120
|
+
'test .post': 'callback2'
|
121
|
+
'custom' : 'method'
|
122
|
+
class SubContainerB extends SubContainerA
|
123
|
+
@mapEvents
|
124
|
+
'test $footer': 'onFooterTest'
|
125
|
+
'custom' : 'overrided'
|
126
|
+
target = (new SubContainerB()).__events
|
127
|
+
expect(target).toEqual Object.extended
|
128
|
+
'test': 'onContainerTest'
|
85
129
|
'test .post': 'callback2'
|
86
|
-
'custom' : 'method'
|
87
|
-
class SubContainerB extends SubContainerA
|
88
|
-
events:
|
89
130
|
'test $footer': 'onFooterTest'
|
90
131
|
'custom' : 'overrided'
|
91
|
-
|
92
|
-
|
93
|
-
expect(target).toEqual Object.extended
|
94
|
-
'test': 'onContainerTest'
|
95
|
-
'test .post': 'callback2'
|
96
|
-
'test $footer': 'onFooterTest'
|
97
|
-
'custom' : 'overrided'
|
98
|
-
target = (new @TestContainer()).__collectEvents()
|
99
|
-
expect(target).toEqual Object.extended('test': 'onContainerTest')
|
100
|
-
|
101
|
-
it "should delegate events", ->
|
102
|
-
@box.refreshElements()
|
103
|
-
callback = 1.upto(3).map -> sinon.spy()
|
104
|
-
@box.events = Object.extended(@box.events).merge
|
105
|
-
'test .post': callback[2]
|
106
|
-
'test $footer': 'onFooterTest'
|
107
|
-
|
108
|
-
@box.onContainerTest = callback[0]
|
109
|
-
@box.onFooterTest = callback[1]
|
110
|
-
@box.__delegateEvents()
|
111
|
-
@box.container.trigger 'test'
|
112
|
-
$('.footer', @box.container).trigger 'test'
|
113
|
-
$('.post', @box.container).trigger 'test'
|
114
|
-
expect(callback[0].callCount).toEqual 5
|
115
|
-
expect(callback[1].callCount).toEqual 1
|
116
|
-
expect(callback[2].callCount).toEqual 3
|
132
|
+
target = (new @TestContainer()).__events
|
133
|
+
expect(target).toEqual Object.extended('test': 'onContainerTest')
|
117
134
|
|
118
|
-
|
119
|
-
|
120
|
-
|
135
|
+
it "delegate", ->
|
136
|
+
@box.__assignElements()
|
137
|
+
callbacks = 1.upto(3).map -> sinon.spy()
|
138
|
+
@box.__events = Object.extended(@box.__events).merge
|
139
|
+
'test .post': callbacks[2]
|
140
|
+
'test $footer': 'onFooterTest'
|
121
141
|
|
122
|
-
|
123
|
-
|
124
|
-
|
142
|
+
@box.onContainerTest = callbacks[0]
|
143
|
+
@box.onFooterTest = callbacks[1]
|
144
|
+
@box.__delegateEvents()
|
145
|
+
@box.container.trigger 'test'
|
146
|
+
$('.footer', @box.container).trigger 'test'
|
147
|
+
$('.post', @box.container).trigger 'test'
|
148
|
+
expect(callbacks[0].callCount).toEqual 5
|
149
|
+
expect(callbacks[1].callCount).toEqual 1
|
150
|
+
expect(callbacks[2].callCount).toEqual 3
|
@@ -3,6 +3,8 @@ describe "Joosy.Modules.WidgetsManager", ->
|
|
3
3
|
beforeEach ->
|
4
4
|
class @TestWidgetManager extends Joosy.Module
|
5
5
|
@include Joosy.Modules.WidgetsManager
|
6
|
+
@include Joosy.Modules.Container
|
7
|
+
|
6
8
|
@box = new @TestWidgetManager()
|
7
9
|
@widgetMock = Object.extended(
|
8
10
|
__load: sinon.stub()
|
@@ -27,17 +29,17 @@ describe "Joosy.Modules.WidgetsManager", ->
|
|
27
29
|
|
28
30
|
it "should inherit widget declarations", ->
|
29
31
|
@box.container = @ground
|
30
|
-
@TestWidgetManager::
|
32
|
+
@TestWidgetManager::__widgets =
|
31
33
|
'test': 'widget'
|
32
34
|
class SubWidgetManagerA extends @TestWidgetManager
|
33
|
-
|
35
|
+
@mapWidgets
|
34
36
|
'selector': 'widget'
|
35
37
|
class SubWidgetManagerB extends SubWidgetManagerA
|
36
|
-
|
38
|
+
@mapWidgets
|
37
39
|
'widgets': 'widget'
|
38
40
|
'selector': 'overriden'
|
39
41
|
subBox = new SubWidgetManagerB()
|
40
|
-
target = subBox.
|
42
|
+
target = subBox.__widgets
|
41
43
|
expect(target).toEqual Object.extended
|
42
44
|
'test': 'widget'
|
43
45
|
'widgets': 'widget'
|
@@ -46,16 +48,17 @@ describe "Joosy.Modules.WidgetsManager", ->
|
|
46
48
|
it "should register widgets per declaration", ->
|
47
49
|
@seedGround()
|
48
50
|
@box.container = $('#application')
|
49
|
-
@box.
|
50
|
-
@box.
|
51
|
+
@box.__elements = {footer: '.footer'}
|
52
|
+
@box.__widgets =
|
51
53
|
'$container': Joosy.Widget
|
52
54
|
'$footer': Joosy.Widget
|
53
55
|
'.post': sinon.stub()
|
54
|
-
@box.
|
56
|
+
@box.__widgets['.post'].returns @widgetMock
|
57
|
+
@box.__assignElements()
|
55
58
|
@box.__setupWidgets()
|
56
59
|
expect(@box.__activeWidgets.length).toEqual 5
|
57
|
-
expect(@box.
|
58
|
-
expect(@box.
|
60
|
+
expect(@box.__widgets['.post'].callCount).toEqual 3
|
61
|
+
expect(@box.__widgets['.post'].getCall(0).calledOn @box).toBeTruthy()
|
59
62
|
|
60
63
|
it "should bootstrap widget properly", ->
|
61
64
|
class TextWidget extends Joosy.Widget
|
@@ -64,7 +67,7 @@ describe "Joosy.Modules.WidgetsManager", ->
|
|
64
67
|
|
65
68
|
@seedGround()
|
66
69
|
@box.container = $('#application')
|
67
|
-
@box.
|
70
|
+
@box.__widgets =
|
68
71
|
'.post:first': TextWidget
|
69
72
|
'.widget:first': (i) -> new TextWidget i
|
70
73
|
@box.__setupWidgets()
|
@@ -65,7 +65,7 @@ describe "Joosy.Page", ->
|
|
65
65
|
|
66
66
|
it "should load itself", ->
|
67
67
|
spies = []
|
68
|
-
spies.push sinon.spy(@box, '
|
68
|
+
spies.push sinon.spy(@box, '__assignElements')
|
69
69
|
spies.push sinon.spy(@box, '__delegateEvents')
|
70
70
|
spies.push sinon.spy(@box, '__setupWidgets')
|
71
71
|
spies.push sinon.spy(@box, '__runAfterLoads')
|
@@ -23,7 +23,7 @@ describe "Joosy.Widget", ->
|
|
23
23
|
spies = [sinon.spy()]
|
24
24
|
@TestWidget.view spies[0]
|
25
25
|
@parent = new Joosy.Layout()
|
26
|
-
spies.push sinon.spy(@box, '
|
26
|
+
spies.push sinon.spy(@box, '__assignElements')
|
27
27
|
spies.push sinon.spy(@box, '__delegateEvents')
|
28
28
|
spies.push sinon.spy(@box, '__runAfterLoads')
|
29
29
|
target = @box.__load @parent, @ground
|
@@ -54,7 +54,7 @@ describe "Joosy.Form", ->
|
|
54
54
|
formWithProperties = new Joosy.Form @nudeForm, invalidationClass: 'fluffy'
|
55
55
|
expect(formWithProperties.container).toEqual @nudeForm
|
56
56
|
expect(formWithProperties.invalidationClass).toEqual 'fluffy'
|
57
|
-
expect(formWithProperties.$fields.length).toEqual 5
|
57
|
+
expect(formWithProperties.$fields().length).toEqual 5
|
58
58
|
|
59
59
|
expect(@spy.callCount).toEqual 1
|
60
60
|
|
@@ -63,7 +63,7 @@ describe "Joosy.Form", ->
|
|
63
63
|
expect(formWithCallback.container).toEqual @putForm
|
64
64
|
expect(formWithCallback.invalidationClass).toEqual 'field_with_errors'
|
65
65
|
expect(formWithCallback.success).toBe callback
|
66
|
-
expect(formWithCallback.$fields.length).toEqual
|
66
|
+
expect(formWithCallback.$fields().length).toEqual 2
|
67
67
|
|
68
68
|
expect(@spy.callCount).toEqual 1
|
69
69
|
|
@@ -97,40 +97,40 @@ describe "Joosy.Form", ->
|
|
97
97
|
|
98
98
|
it "should fill form, set proper action and method and store resource", ->
|
99
99
|
@nudeForm.fill @resource
|
100
|
-
expect(@nudeForm.$fields[0].value).toEqual 'foo'
|
101
|
-
expect(@nudeForm.$fields[1].value).toEqual 'bar'
|
102
|
-
expect(@nudeForm.$fields[2].checked).toEqual true
|
103
|
-
expect(@nudeForm.$fields[2].value).toEqual '1'
|
104
|
-
expect(@nudeForm.$fields[3].value).toEqual 'qwe'
|
105
|
-
expect(@nudeForm.$fields[3].checked).toEqual false
|
106
|
-
expect(@nudeForm.$fields[4].value).toEqual 'zxc'
|
107
|
-
expect(@nudeForm.$fields[4].checked).toEqual true
|
100
|
+
expect(@nudeForm.$fields()[0].value).toEqual 'foo'
|
101
|
+
expect(@nudeForm.$fields()[1].value).toEqual 'bar'
|
102
|
+
expect(@nudeForm.$fields()[2].checked).toEqual true
|
103
|
+
expect(@nudeForm.$fields()[2].value).toEqual '1'
|
104
|
+
expect(@nudeForm.$fields()[3].value).toEqual 'qwe'
|
105
|
+
expect(@nudeForm.$fields()[3].checked).toEqual false
|
106
|
+
expect(@nudeForm.$fields()[4].value).toEqual 'zxc'
|
107
|
+
expect(@nudeForm.$fields()[4].checked).toEqual true
|
108
108
|
expect(@nudeForm.container.attr('method').toLowerCase()).toEqual 'post'
|
109
109
|
expect(@nudeForm.container.attr 'action').toEqual '/tests/1'
|
110
110
|
expect(@nudeForm.__resource).toEqual @resource
|
111
111
|
|
112
112
|
it "should fill form with camelized properties", ->
|
113
113
|
@putForm.fill @resource
|
114
|
-
expect(@putForm.$fields[0].value).toEqual 'baz'
|
114
|
+
expect(@putForm.$fields()[0].value).toEqual 'baz'
|
115
115
|
expect(@putForm.container.attr('method').toLowerCase()).toEqual 'post'
|
116
116
|
expect(@putForm.container.attr 'action').toEqual '/tests/1'
|
117
117
|
|
118
118
|
it "should fill form with any properties", ->
|
119
119
|
@exactForm.fill @resource
|
120
|
-
expect(@exactForm.$fields[0].value).toEqual 'works'
|
120
|
+
expect(@exactForm.$fields()[0].value).toEqual 'works'
|
121
121
|
|
122
122
|
it "should fill form with decorator", ->
|
123
123
|
@moreForm.fill @resource,
|
124
124
|
decorator: (e) ->
|
125
125
|
e.ololo = e.camelBaz
|
126
126
|
e
|
127
|
-
expect(@moreForm.$fields[0].value).toEqual 'baz'
|
127
|
+
expect(@moreForm.$fields()[0].value).toEqual 'baz'
|
128
128
|
|
129
129
|
it "should fill form with extended action", ->
|
130
130
|
@nudeForm.fill @resource,
|
131
131
|
action: @resource.memberPath(from: 'calculate')
|
132
|
-
expect(@nudeForm.$fields[0].value).toEqual 'foo'
|
133
|
-
expect(@nudeForm.$fields[1].value).toEqual 'bar'
|
132
|
+
expect(@nudeForm.$fields()[0].value).toEqual 'foo'
|
133
|
+
expect(@nudeForm.$fields()[1].value).toEqual 'bar'
|
134
134
|
expect(@nudeForm.container.attr 'action').toEqual '/tests/1/calculate'
|
135
135
|
|
136
136
|
resource = @Test.build 'someId'
|
@@ -156,14 +156,14 @@ describe "Joosy.Form", ->
|
|
156
156
|
|
157
157
|
it "should fill nested attributes and resources", ->
|
158
158
|
@nestedForm.fill @resource
|
159
|
-
expect(@nestedForm.$fields[0].value).toEqual 'test'
|
160
|
-
expect(@nestedForm.$fields[1].value).toEqual 'one'
|
161
|
-
expect(@nestedForm.$fields[2].value).toEqual 'two'
|
162
|
-
expect(@nestedForm.$fields[3].value).toEqual 'sin'
|
159
|
+
expect(@nestedForm.$fields()[0].value).toEqual 'test'
|
160
|
+
expect(@nestedForm.$fields()[1].value).toEqual 'one'
|
161
|
+
expect(@nestedForm.$fields()[2].value).toEqual 'two'
|
162
|
+
expect(@nestedForm.$fields()[3].value).toEqual 'sin'
|
163
163
|
|
164
164
|
it 'should fill array-like attributes', ->
|
165
165
|
@arrayForm.fill @resource
|
166
|
-
expect(@arrayForm.$fields[0].value).toEqual 'here'
|
166
|
+
expect(@arrayForm.$fields()[0].value).toEqual 'here'
|
167
167
|
|
168
168
|
it "should break cross-references", ->
|
169
169
|
@resource('single')('trololo', @resource)
|
@@ -237,13 +237,13 @@ describe "Joosy.Form", ->
|
|
237
237
|
|
238
238
|
it "should fill class for invalidated fields by default", ->
|
239
239
|
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
240
|
-
expect($(@nudeForm.$fields[0]).attr 'class').toEqual 'field_with_errors'
|
240
|
+
expect($(@nudeForm.$fields()[0]).attr 'class').toEqual 'field_with_errors'
|
241
241
|
|
242
242
|
it "should trigger 'error' and complete default action if it returned true", ->
|
243
243
|
@nudeForm.error = sinon.spy ->
|
244
244
|
true
|
245
245
|
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
246
|
-
expect($(@nudeForm.$fields[0]).attr 'class').toEqual 'field_with_errors'
|
246
|
+
expect($(@nudeForm.$fields()[0]).attr 'class').toEqual 'field_with_errors'
|
247
247
|
expect(@nudeForm.error.callCount).toEqual 1
|
248
248
|
expect(@nudeForm.error.args[0][0]).toEqual
|
249
249
|
"foo": "error!"
|
@@ -252,31 +252,31 @@ describe "Joosy.Form", ->
|
|
252
252
|
@nudeForm.error = sinon.spy ->
|
253
253
|
false
|
254
254
|
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
255
|
-
expect($(@nudeForm.$fields[0]).attr 'class').toNotEqual 'field_with_errors'
|
255
|
+
expect($(@nudeForm.$fields()[0]).attr 'class').toNotEqual 'field_with_errors'
|
256
256
|
expect(@nudeForm.error.callCount).toEqual 1
|
257
257
|
|
258
258
|
it "should clear fields before another submit", ->
|
259
259
|
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
260
|
-
expect($(@nudeForm.$fields[0]).attr 'class').toEqual 'field_with_errors'
|
260
|
+
expect($(@nudeForm.$fields()[0]).attr 'class').toEqual 'field_with_errors'
|
261
261
|
@nudeForm.container.submit()
|
262
|
-
expect($(@nudeForm.$fields[0]).attr 'class').toNotEqual 'field_with_errors'
|
262
|
+
expect($(@nudeForm.$fields()[0]).attr 'class').toNotEqual 'field_with_errors'
|
263
263
|
|
264
264
|
it "should trigger 'before' and do default action if it returns true", ->
|
265
265
|
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
266
|
-
expect($(@nudeForm.$fields[0]).attr 'class').toEqual 'field_with_errors'
|
266
|
+
expect($(@nudeForm.$fields()[0]).attr 'class').toEqual 'field_with_errors'
|
267
267
|
@nudeForm.before = sinon.spy ->
|
268
268
|
true
|
269
269
|
@nudeForm.container.submit()
|
270
|
-
expect($(@nudeForm.$fields[0]).attr 'class').toNotEqual 'field_with_errors'
|
270
|
+
expect($(@nudeForm.$fields()[0]).attr 'class').toNotEqual 'field_with_errors'
|
271
271
|
expect(@nudeForm.before.callCount).toEqual 1
|
272
272
|
|
273
273
|
it "should trigger 'before' and skip default action if it returns false", ->
|
274
274
|
@target.respond 422, 'Content-Type': 'application/json', '{"foo": "error!"}'
|
275
|
-
expect($(@nudeForm.$fields[0]).attr 'class').toEqual 'field_with_errors'
|
275
|
+
expect($(@nudeForm.$fields()[0]).attr 'class').toEqual 'field_with_errors'
|
276
276
|
@nudeForm.before = sinon.spy ->
|
277
277
|
false
|
278
278
|
@nudeForm.container.submit()
|
279
|
-
expect($(@nudeForm.$fields[0]).attr 'class').toEqual 'field_with_errors'
|
279
|
+
expect($(@nudeForm.$fields()[0]).attr 'class').toEqual 'field_with_errors'
|
280
280
|
expect(@nudeForm.before.callCount).toEqual 1
|
281
281
|
|
282
282
|
describe "Error response handling", ->
|
@@ -35,10 +35,6 @@ Joosy.Application =
|
|
35
35
|
|
36
36
|
Joosy.Router.__setupRoutes()
|
37
37
|
|
38
|
-
@sandboxSelector = Joosy.uuid()
|
39
|
-
@content().after "<div id='#{@sandboxSelector}' style='display:none'></div>"
|
40
|
-
@sandboxSelector = '#' + @sandboxSelector
|
41
|
-
|
42
38
|
#
|
43
39
|
# Gets current application root node
|
44
40
|
#
|
data/src/joosy/core/joosy.coffee
CHANGED
@@ -133,12 +133,12 @@ class Joosy.Layout extends Joosy.Module
|
|
133
133
|
#
|
134
134
|
# Layout bootstrap proccess.
|
135
135
|
#
|
136
|
-
# * {Joosy.Modules.Container.
|
136
|
+
# * {Joosy.Modules.Container.__assignElements}
|
137
137
|
# * {Joosy.Modules.Container.__delegateEvents}
|
138
138
|
# * {Joosy.Modules.WidgetsManager.__setupWidgets}
|
139
139
|
#
|
140
140
|
__load: (@container) ->
|
141
|
-
@
|
141
|
+
@__assignElements()
|
142
142
|
@__delegateEvents()
|
143
143
|
@__setupWidgets()
|
144
144
|
@__runAfterLoads()
|
@@ -8,11 +8,19 @@
|
|
8
8
|
# @mixin
|
9
9
|
#
|
10
10
|
Joosy.Modules.Container =
|
11
|
-
events: false
|
12
|
-
elements: false
|
13
|
-
|
14
11
|
eventSplitter: /^(\S+)\s*(.*)$/
|
15
12
|
|
13
|
+
included: ->
|
14
|
+
@mapElements = (map) ->
|
15
|
+
unless @::hasOwnProperty "__elements"
|
16
|
+
@::__elements = Object.clone(@.__super__.__elements) || {}
|
17
|
+
Object.merge @::__elements, map
|
18
|
+
|
19
|
+
@mapEvents = (map) ->
|
20
|
+
unless @::hasOwnProperty "__events"
|
21
|
+
@::__events = Object.clone(@.__super__.__events) || {}
|
22
|
+
Object.merge @::__events, map
|
23
|
+
|
16
24
|
onRefresh: (callback) ->
|
17
25
|
@__onRefreshes = [] unless @hasOwnProperty "__onRefreshes"
|
18
26
|
@__onRefreshes.push callback
|
@@ -24,8 +32,6 @@ Joosy.Modules.Container =
|
|
24
32
|
# Rebinds selectors defined in 'elements' hash to object properties
|
25
33
|
#
|
26
34
|
refreshElements: ->
|
27
|
-
@__assignElements()
|
28
|
-
|
29
35
|
if @hasOwnProperty "__onRefreshes"
|
30
36
|
@__onRefreshes.each (callback) => callback.apply @
|
31
37
|
@__onRefreshes = []
|
@@ -51,30 +57,6 @@ Joosy.Modules.Container =
|
|
51
57
|
container.html data
|
52
58
|
container
|
53
59
|
|
54
|
-
#
|
55
|
-
# Gathers 'elements' from current and super classes
|
56
|
-
#
|
57
|
-
__collectElements: ->
|
58
|
-
elements = Object.extended @elements || {}
|
59
|
-
|
60
|
-
klass = this
|
61
|
-
while klass = klass.constructor.__super__
|
62
|
-
Joosy.Module.merge elements, klass.elements, false
|
63
|
-
|
64
|
-
elements
|
65
|
-
|
66
|
-
#
|
67
|
-
# Gathers 'events' from current and super classes
|
68
|
-
#
|
69
|
-
__collectEvents: ->
|
70
|
-
events = Object.extended @events || {}
|
71
|
-
|
72
|
-
klass = this
|
73
|
-
while klass = klass.constructor.__super__
|
74
|
-
Joosy.Module.merge events, klass.events, false
|
75
|
-
|
76
|
-
events
|
77
|
-
|
78
60
|
#
|
79
61
|
# Converts '$...' notation to selector from 'elements'
|
80
62
|
#
|
@@ -96,40 +78,48 @@ Joosy.Modules.Container =
|
|
96
78
|
# Assigns elements defined in 'elements'
|
97
79
|
#
|
98
80
|
# @example Sample elements
|
99
|
-
#
|
81
|
+
# @mapElements
|
100
82
|
# foo: '.foo'
|
101
83
|
# bar: '.bar'
|
102
84
|
#
|
103
85
|
__assignElements: (root, entries) ->
|
104
86
|
root ||= @
|
105
|
-
entries ||= @
|
87
|
+
entries ||= @__elements
|
88
|
+
|
89
|
+
return unless entries
|
106
90
|
|
107
91
|
Object.each entries, (key, value) =>
|
108
92
|
if Object.isObject(value)
|
109
93
|
@__assignElements root['$'+key]={}, value
|
110
94
|
else
|
111
95
|
value = @__extractSelector value
|
112
|
-
|
96
|
+
|
97
|
+
root['$'+key] = (filter) =>
|
98
|
+
return @$(value) unless filter
|
99
|
+
return @$(value).filter(filter)
|
100
|
+
|
113
101
|
root['$'+key].selector = value
|
114
102
|
|
115
103
|
#
|
116
104
|
# Binds events defined in 'events' to container
|
117
105
|
#
|
118
106
|
# @example Sample events
|
119
|
-
#
|
107
|
+
# @mapEvents
|
120
108
|
# 'click': -> # this will raise on container click
|
121
109
|
# 'click .foo': -> # this will raise on .foo click
|
122
110
|
# 'click $foo': -> #this will search for selector of foo element
|
123
111
|
#
|
124
112
|
__delegateEvents: ->
|
125
113
|
module = @
|
126
|
-
events = @
|
114
|
+
events = @__events
|
115
|
+
|
116
|
+
return unless events
|
127
117
|
|
128
|
-
|
118
|
+
Object.each events, (key, method) =>
|
129
119
|
unless Object.isFunction method
|
130
120
|
method = @[method]
|
131
121
|
callback = (event) ->
|
132
|
-
method.call module, this, event
|
122
|
+
method.call module, $(this), event
|
133
123
|
|
134
124
|
match = key.match @eventSplitter
|
135
125
|
eventName = match[1]
|
@@ -7,6 +7,12 @@
|
|
7
7
|
#
|
8
8
|
Joosy.Modules.WidgetsManager =
|
9
9
|
|
10
|
+
included: ->
|
11
|
+
@mapWidgets = (map) ->
|
12
|
+
unless @::hasOwnProperty "__widgets"
|
13
|
+
@::__widgets = Object.clone(@.__super__.__widgets) || {}
|
14
|
+
Object.merge @::__widgets, map
|
15
|
+
|
10
16
|
#
|
11
17
|
# Registeres and runs widget inside specified container
|
12
18
|
#
|
@@ -21,7 +27,7 @@ Joosy.Modules.WidgetsManager =
|
|
21
27
|
widget = widget()
|
22
28
|
|
23
29
|
@__activeWidgets ||= []
|
24
|
-
@__activeWidgets.push widget.__load(
|
30
|
+
@__activeWidgets.push widget.__load(@, $(container))
|
25
31
|
|
26
32
|
widget
|
27
33
|
|
@@ -35,32 +41,20 @@ Joosy.Modules.WidgetsManager =
|
|
35
41
|
|
36
42
|
@__activeWidgets.splice @__activeWidgets.indexOf(widget), 1
|
37
43
|
|
38
|
-
#
|
39
|
-
# Gathers widgets definitions from current and super classes
|
40
|
-
#
|
41
|
-
__collectWidgets: ->
|
42
|
-
widgets = Object.extended @widgets || {}
|
43
|
-
|
44
|
-
klass = this
|
45
|
-
while klass = klass.constructor.__super__
|
46
|
-
Joosy.Module.merge widgets, klass.widgets, false
|
47
|
-
|
48
|
-
widgets
|
49
|
-
|
50
44
|
#
|
51
45
|
# Intialize all widgets for current object
|
52
46
|
#
|
53
47
|
__setupWidgets: ->
|
54
|
-
widgets = @
|
48
|
+
widgets = @__widgets
|
55
49
|
registered = Object.extended()
|
56
50
|
|
57
|
-
|
51
|
+
return unless widgets
|
52
|
+
|
53
|
+
Object.each widgets, (selector, widget) =>
|
58
54
|
if selector == '$container'
|
59
55
|
activeSelector = @container
|
60
56
|
else
|
61
|
-
|
62
|
-
selector = @elements[r[1]]
|
63
|
-
|
57
|
+
selector = @__extractSelector(selector) if @__extractSelector?
|
64
58
|
activeSelector = $(selector, @container)
|
65
59
|
|
66
60
|
registered[selector] = Object.extended()
|
data/src/joosy/core/page.coffee
CHANGED
@@ -250,13 +250,13 @@ class Joosy.Page extends Joosy.Module
|
|
250
250
|
#
|
251
251
|
# Page bootstrap proccess
|
252
252
|
#
|
253
|
-
# * {Joosy.Modules.Container.
|
253
|
+
# * {Joosy.Modules.Container.__assignElements}
|
254
254
|
# * {Joosy.Modules.Container.__delegateEvents}
|
255
255
|
# * {Joosy.Modules.WidgetsManager.__setupWidgets}
|
256
256
|
# * Scrolling
|
257
257
|
#
|
258
258
|
__load: ->
|
259
|
-
@
|
259
|
+
@__assignElements()
|
260
260
|
@__delegateEvents()
|
261
261
|
@__setupWidgets()
|
262
262
|
@__runAfterLoads @params, @previous
|
@@ -58,7 +58,7 @@ class Joosy.Widget extends Joosy.Module
|
|
58
58
|
# Widget bootstrap proccess
|
59
59
|
#
|
60
60
|
# * Rendering (if required)
|
61
|
-
# * {Joosy.Modules.Container.
|
61
|
+
# * {Joosy.Modules.Container.__assignElements}
|
62
62
|
# * {Joosy.Modules.Container.__delegateEvents}
|
63
63
|
#
|
64
64
|
# @param [Joosy.Page, Joosy.Layout] Page or Layout to attach to
|
@@ -68,7 +68,7 @@ class Joosy.Widget extends Joosy.Module
|
|
68
68
|
@__runBeforeLoads()
|
69
69
|
if render && @__renderer
|
70
70
|
@swapContainer @container, @__renderer(@data || {})
|
71
|
-
@
|
71
|
+
@__assignElements()
|
72
72
|
@__delegateEvents()
|
73
73
|
@__setupWidgets()
|
74
74
|
@__runAfterLoads()
|
@@ -40,7 +40,7 @@ class Joosy.Form extends Joosy.Module
|
|
40
40
|
#
|
41
41
|
# List of elements for internal usage
|
42
42
|
#
|
43
|
-
|
43
|
+
@mapElements
|
44
44
|
'fields': 'input,select,textarea'
|
45
45
|
|
46
46
|
#
|
@@ -104,7 +104,7 @@ class Joosy.Form extends Joosy.Module
|
|
104
104
|
@container = $(form)
|
105
105
|
return if @container.length == 0
|
106
106
|
|
107
|
-
@
|
107
|
+
@__assignElements()
|
108
108
|
@__delegateEvents()
|
109
109
|
|
110
110
|
method = @container.get(0).getAttribute('method')?.toLowerCase()
|
@@ -179,7 +179,7 @@ class Joosy.Form extends Joosy.Module
|
|
179
179
|
data.__joosy_form_filler_lock = true
|
180
180
|
Object.each data, (property, val) =>
|
181
181
|
key = @concatFieldName scope, property
|
182
|
-
input = @$fields
|
182
|
+
input = @$fields("[name='#{key}']:not(:file),[name='#{key.underscore()}']:not(:file),[name='#{key.camelize(false)}']:not(:file)")
|
183
183
|
if input.length > 0
|
184
184
|
if input.is ':checkbox'
|
185
185
|
if val
|
@@ -246,7 +246,7 @@ class Joosy.Form extends Joosy.Module
|
|
246
246
|
#
|
247
247
|
__before: (xhr, settings) ->
|
248
248
|
if !@before? || @before(arguments...) is true
|
249
|
-
@$fields.removeClass @invalidationClass
|
249
|
+
@$fields().removeClass @invalidationClass
|
250
250
|
|
251
251
|
#
|
252
252
|
# Inner error callback.
|
@@ -292,7 +292,7 @@ class Joosy.Form extends Joosy.Module
|
|
292
292
|
# @param [String] field Name of field to find
|
293
293
|
#
|
294
294
|
findField: (field) ->
|
295
|
-
@$fields
|
295
|
+
@$fields("[name='#{field}']")
|
296
296
|
|
297
297
|
#
|
298
298
|
# Simulates REST methods by adding hidden _method input with real method
|
@@ -6,17 +6,17 @@ Joosy.namespace 'Welcome', ->
|
|
6
6
|
|
7
7
|
@afterLoad ->
|
8
8
|
@startHeartbeat()
|
9
|
-
@$content.css
|
9
|
+
@$content().css
|
10
10
|
'padding-top': "#{$(window).height() / 2 - 80}px"
|
11
11
|
|
12
|
-
|
12
|
+
@mapElements
|
13
13
|
content: '#content'
|
14
14
|
joosy: '.joosy'
|
15
15
|
|
16
|
-
|
16
|
+
@mapEvents
|
17
17
|
'mouseover $joosy': -> clearInterval @heartbeat
|
18
18
|
'mouseout $joosy': 'startHeartbeat'
|
19
19
|
|
20
20
|
startHeartbeat: ->
|
21
21
|
@heartbeat = @setInterval 1500, =>
|
22
|
-
@$joosy.animate({opacity: 0.8}, 300).animate({opacity: 1}, 300)
|
22
|
+
@$joosy().animate({opacity: 0.8}, 300).animate({opacity: 1}, 300)
|
metadata
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: joosy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.0.alpha.
|
4
|
+
version: 1.2.0.alpha.38
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boris Staal
|
8
8
|
- Andrew Shaydurov
|
9
|
-
- Peter Zotov
|
10
9
|
- Alexander Pavlenko
|
11
10
|
autorequire:
|
12
11
|
bindir: bin
|
13
12
|
cert_chain: []
|
14
|
-
date: 2013-07-
|
13
|
+
date: 2013-07-16 00:00:00.000000000 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: sprockets
|
@@ -150,7 +149,8 @@ files:
|
|
150
149
|
- templates/widget/basic.coffee
|
151
150
|
- templates/widget/namespaced.coffee
|
152
151
|
homepage: http://github.com/joosy/joosy
|
153
|
-
licenses:
|
152
|
+
licenses:
|
153
|
+
- MIT
|
154
154
|
metadata: {}
|
155
155
|
post_install_message:
|
156
156
|
rdoc_options: []
|