nail_polish 0.1.1 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +2 -4
  3. data/app/assets/images/nail_polish/elements/link_action.png +0 -0
  4. data/app/assets/images/nail_polish/elements/white_down_arrow.png +0 -0
  5. data/app/assets/javascripts/nail_polish.js +6 -1
  6. data/app/assets/javascripts/nail_polish/app.js +32 -18
  7. data/app/assets/javascripts/nail_polish/events.js +2 -0
  8. data/app/assets/javascripts/nail_polish/model.js +49 -0
  9. data/app/assets/javascripts/nail_polish/models/dropdown.js +9 -0
  10. data/app/assets/javascripts/nail_polish/models/menu.js +1 -0
  11. data/app/assets/javascripts/nail_polish/nail_polish.js +2 -0
  12. data/app/assets/javascripts/nail_polish/presenter.js +34 -7
  13. data/app/assets/javascripts/nail_polish/presenter_with_errors.js +61 -0
  14. data/app/assets/javascripts/nail_polish/presenters/dropdown.js +7 -12
  15. data/app/assets/javascripts/nail_polish/presenters/menu.js +7 -0
  16. data/app/assets/javascripts/nail_polish/router.js +23 -13
  17. data/app/assets/javascripts/nail_polish/templates/dropdown.mustache +14 -0
  18. data/app/assets/javascripts/nail_polish/templates/menu.mustache +22 -0
  19. data/app/assets/javascripts/nail_polish/templates/modal.mustache +5 -0
  20. data/app/assets/javascripts/nail_polish/utils/subview_manager.js +28 -0
  21. data/app/assets/javascripts/nail_polish/validator.js +147 -0
  22. data/app/assets/javascripts/nail_polish/view.js +17 -8
  23. data/app/assets/javascripts/nail_polish/views/form.js +44 -0
  24. data/app/assets/javascripts/nail_polish/widget/dropdown.js +37 -9
  25. data/app/assets/javascripts/nail_polish/widget/flash.js +8 -8
  26. data/app/assets/javascripts/nail_polish/widget/menu.js +61 -0
  27. data/app/assets/javascripts/nail_polish/widget/modal.js +35 -5
  28. data/app/assets/javascripts/nail_polish_widgets.js +1 -0
  29. data/app/assets/stylesheets/nail_polish/base.scss +1 -1
  30. data/app/assets/stylesheets/nail_polish/base/buttons.scss +5 -0
  31. data/app/assets/stylesheets/nail_polish/base/form_elements.scss +15 -1
  32. data/app/assets/stylesheets/nail_polish/base/grid.scss +8 -6
  33. data/app/assets/stylesheets/nail_polish/base/layout.scss +3 -2
  34. data/app/assets/stylesheets/nail_polish/base/oo_styles.scss +37 -2
  35. data/app/assets/stylesheets/nail_polish/base/reset.scss +5 -0
  36. data/app/assets/stylesheets/nail_polish/base/typography_and_tags.scss +4 -0
  37. data/app/assets/stylesheets/nail_polish/desktop.scss +1 -1
  38. data/app/assets/stylesheets/nail_polish/desktop/grid.scss +6 -1
  39. data/app/assets/stylesheets/nail_polish/desktop/widgets/menu.scss +61 -0
  40. data/app/assets/stylesheets/nail_polish/tablet.scss +0 -1
  41. data/app/assets/stylesheets/nail_polish/tablet/grid.scss +3 -0
  42. data/lib/nail_polish/version.rb +1 -1
  43. metadata +43 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e3ba67ec01b5c63e131ad9ef42ab33f1bd34f6ce
4
- data.tar.gz: f3e8829feb282e2baf0e71a0d6ca50291b8619f1
3
+ metadata.gz: eb99e0ed36d22ea73bd7d1adefe6a7761b352ce1
4
+ data.tar.gz: 15306c6b03975c3562fc6f3158298e44938f52c8
5
5
  SHA512:
6
- metadata.gz: a95ed0112c6e6ddf26a19c6beef730d187cdc6be5b68cfce253a71d9f4792a8570aa7f0d9b2a214449c415c29ab3264b42c07e7a78919a880ddb651e0d7bb5af
7
- data.tar.gz: f975b6189559c5b01c0fc262b4b4225719a03a4a365211fd0399a4e42c481b9211e43c457657c723011bf8d911255e54f039d6a1e3fcdd73c0ceaada4e0627c7
6
+ metadata.gz: fef3dd7d58bcd1d924f02b1ecb6ae2055d34ccd2dea0d4dea1c7e237a8aee288f3ad6bd03435d56409197f1199af983482ec24086205c43f6481d1281be63305
7
+ data.tar.gz: 1d58bcd96212a35041f8f19551b789060c72016b5c003b83ea0e2a463883c0447268d4b0d69313b44ec927b1e4c64c42b8c51cbc95dfd37be0e4778c3023daf5
@@ -1,8 +1,6 @@
1
- = NailPolish: SocialChorus/SocialChorus OO FrontEnd
1
+ = NailPolish: SocialChorus/SocialChorus OO Frontend
2
2
 
3
- NailPolish is a front-end framework used by the SocialCoder's a SocialChorus.
4
-
5
- SocialCoders use a modified version of OOCSS, and have an set of Backbone
3
+ NailPolish is a frontend framework used by the SocialCoders at SocialChorus. With NailPolish, SocialCoders provide a modified version of OOCSS and a set of Backbone
6
4
  conventions.
7
5
 
8
6
  == TODO
@@ -9,13 +9,18 @@
9
9
  //= require nail_polish/overrides/global_publisher_adder
10
10
  //= require nail_polish/overrides/for_backbone
11
11
  //
12
+ //= require ./nail_polish/model
13
+ //= require ./nail_polish/validator
14
+ //= require_tree ./nail_polish/templates
12
15
  //= require nail_polish/events
13
16
  //= require nail_polish/events/redirector
14
17
  //= require nail_polish/events/flasher
15
18
  //= require nail_polish/view
16
19
  //= require nail_polish/view/parent_finder
17
20
  //= require nail_polish/presenter
21
+ //= require nail_polish/presenter_with_errors
18
22
  //= require_tree ./nail_polish/presenters
23
+ //= require_tree ./nail_polish/models
24
+ //= require_tree ./nail_polish/views
19
25
  //= require nail_polish/router
20
26
  //= require nail_polish/app
21
-
@@ -1,36 +1,48 @@
1
- //specs to come
2
- NailPolish.App = function() {};
1
+ NailPolish.App = function(parent, opts) {
2
+ this.initialize(parent, opts);
3
+ };
4
+
3
5
  NailPolish.App.extend = Backbone.Model.extend;
4
6
 
5
- _.extend(NailPolish.App.prototype, {
7
+ _.extend(NailPolish.App.prototype, _.extend(_.clone(NailPolish.SubviewManager), {
6
8
  initialize: function(parent, opts) {
7
- this.parent = parent;
9
+ this.$el = parent; // will act like a view when the parent finder encounters it
10
+ // TODO: switch naming to el/$el everywhere???
8
11
  this.opts = opts;
9
12
  this.init(parent, opts);
10
13
  },
11
14
 
12
15
  start: function () {
13
- this.repository = this.bootstrap();
14
- this.route();
16
+ this.repository = this.buildRepository();
15
17
  this.render();
18
+ this.route();
16
19
  },
17
20
 
18
21
  route: function() {
19
- this.router = new (this.routerClass())();
22
+ this.router = new (this.routerClass(this.$el))();
20
23
  this.router.repository = this.repository;
21
24
  Backbone.history.start();
22
25
  },
23
26
 
24
27
  render: function() {
25
- _.each(this.subViews(), function(view) {
26
- view.parent = view.parent || this.parent;
27
- view.render();
28
- }.bind(this));
28
+ this.renderEach(this.subviews());
29
+ this.afterRender();
29
30
  },
30
31
 
31
- bootstrapData: function() {
32
- var data = data || JSON.parse($('#bootstrap-json').text());
33
- return data;
32
+ afterRender: function(){
33
+
34
+ },
35
+
36
+ buildRepository: function() {
37
+ return this.bootstrap();
38
+ },
39
+
40
+ bootstrapData: function(selector) {
41
+ try {
42
+ return JSON.parse($(selector).html());
43
+ } catch(e) {
44
+ return {};
45
+ }
34
46
  },
35
47
 
36
48
  //Stuff for YOU to configure
@@ -39,12 +51,14 @@ _.extend(NailPolish.App.prototype, {
39
51
  //your init stuff here
40
52
  },
41
53
 
54
+ bootstrapDataSelector: "#bootstrap-json",
55
+
42
56
  bootstrap: function() {
43
57
  //override this if you want specific models in your repo
44
- return this.bootstrapData();
58
+ return this.bootstrapData(this.bootstrapDataSelector);
45
59
  },
46
60
 
47
- subViews: function() {
61
+ subviews: function() {
48
62
  //fill me in
49
63
 
50
64
  //return [
@@ -52,7 +66,7 @@ _.extend(NailPolish.App.prototype, {
52
66
  //]
53
67
  },
54
68
 
55
- routerClass: function () {
69
+ routerClass: function() {
56
70
  //set this, yo
57
71
  }
58
- });
72
+ }));
@@ -26,3 +26,5 @@ NailPolish.Events = {
26
26
  this.publisher.off(event, callback, context);
27
27
  }
28
28
  };
29
+
30
+ NailPolish.Events['click'] = NailPolish.Events.isTouch() ? NailPolish.Events.startEvent+' ' : 'click ';
@@ -0,0 +1,49 @@
1
+ /*
2
+ Base model class for NailPolish apps.
3
+ It is fully backwards-compatible with Backbone.Model.
4
+
5
+ It automatically populates `validationError` with server errors, if
6
+ there were any, i.e. given 422 JSON response from server:
7
+
8
+ {
9
+ errors: {
10
+ "username": ["is already in use"]
11
+ }
12
+ }
13
+
14
+ it populates model's `validationError` with:
15
+
16
+ {
17
+ "username": ["is already in use"]
18
+ }
19
+
20
+ This would also trigger an 'invalid' event on the model.
21
+ */
22
+ NailPolish.Model = Backbone.Model.extend({
23
+ constructor: function() {
24
+ var result = Backbone.Model.apply(this, arguments);
25
+ this._initializeInternalEvents();
26
+ return result;
27
+ },
28
+
29
+ _initializeInternalEvents: function() {
30
+ this.listenTo(this, 'error', this._populateServerErrors);
31
+ },
32
+
33
+ _populateServerErrors: function(model, response, options) {
34
+ var errors = this._errors(response);
35
+ if (errors) {
36
+ model.validationError = errors;
37
+ model.trigger('invalid', model, errors, _.extend(options, { validationError: errors }));
38
+ }
39
+ },
40
+
41
+ _errors: function (response) {
42
+ var errors;
43
+ try {
44
+ return JSON.parse(response.responseText).errors;
45
+ } catch(e) {
46
+ return;
47
+ }
48
+ }
49
+ });
@@ -0,0 +1,9 @@
1
+ NailPolish.Models.Dropdown = Backbone.Model.extend({
2
+ initialize: function(){
3
+ this.set({"options": this.options }, {silent: true})
4
+ },
5
+
6
+ selected: function(){
7
+ return this.get('selected_key') || _.keys(this.get('options'))[0];
8
+ }
9
+ });
@@ -0,0 +1 @@
1
+ NailPolish.Models.Menu = Backbone.Model.extend({});
@@ -23,3 +23,5 @@ var NailPolish = {
23
23
  };
24
24
 
25
25
  NailPolish.Widget = {};
26
+ NailPolish.Models = {};
27
+ NailPolish.Views = {};
@@ -4,17 +4,17 @@ NailPolish.Presenter = function(presented) {
4
4
  this.init();
5
5
  };
6
6
 
7
- NailPolish.Presenter.prototype.initialize = function () {
7
+ NailPolish.Presenter.prototype.initialize = function() {
8
8
  //Put your stuff here
9
9
  };
10
10
 
11
- NailPolish.Presenter.prototype.init = function () {
11
+ NailPolish.Presenter.prototype.init = function() {
12
12
  //Put your stuff here
13
13
  };
14
14
 
15
15
  NailPolish.Presenter.extend = Backbone.Model.extend;
16
16
 
17
- NailPolish.Presenter.prototype.presentedToJSON = function () {
17
+ NailPolish.Presenter.prototype.presentedToJSON = function() {
18
18
  var json;
19
19
  if (this.presented && this.presented.toJSON) {
20
20
  json = this.presented.toJSON();
@@ -22,22 +22,49 @@ NailPolish.Presenter.prototype.presentedToJSON = function () {
22
22
  return json || this.presented;
23
23
  };
24
24
 
25
- NailPolish.Presenter.prototype.inclusions = function () {
25
+ NailPolish.Presenter.prototype.inclusions = function() {
26
26
  var inclusions = {};
27
- _.each(this.include || [], function (prop) {
27
+ _.each(this.include || [], function(prop) {
28
28
  inclusions[prop] = this.inclusionFor(prop);
29
29
  }.bind(this));
30
30
  return inclusions;
31
31
  };
32
32
 
33
- NailPolish.Presenter.prototype.inclusionFor = function (attr) {
33
+ NailPolish.Presenter.prototype.inclusionFor = function(attr) {
34
34
  var prop = this[attr];
35
35
  return _.isFunction(prop) ? prop.bind(this)() : prop;
36
36
  };
37
37
 
38
+ /*
39
+ Returns a template-friendly json representation of `presented`.
40
+
41
+ Example:
42
+
43
+ var model = new Backbone.Model({ username: "socialcoder" });
44
+
45
+ var MyPresenter = NailPolish.Presenter.extend({
46
+ include: ["status", "likes"],
47
+
48
+ status: "better than ever",
49
+
50
+ likes: function() {
51
+ return ["clean code", "nice documentation"];
52
+ }
53
+ });
54
+
55
+ var presenter = new MyPresenter(model);
56
+
57
+ presenter.toJSON();
58
+
59
+ // {
60
+ // "likes": ["clean code", "nice documentation"],
61
+ // "status": "better than ever",
62
+ // "username": "socialcoder",
63
+ // "username_error": "is too awesome"
64
+ // }
65
+ */
38
66
  NailPolish.Presenter.prototype.toJSON = function() {
39
67
  var base = this.presentedToJSON();
40
68
  var inclusions = this.inclusions();
41
69
  return _.extend(base, inclusions);
42
70
  };
43
-
@@ -0,0 +1,61 @@
1
+ // Will become default after transition has finished
2
+ NailPolish.PresenterWithErrors = NailPolish.Presenter.extend({});
3
+
4
+ NailPolish.PresenterWithErrors.prototype.errors = function() {
5
+ if (!_.isObject(this.presented.validationError)) {
6
+ return {};
7
+ }
8
+
9
+ return _.reduce(this.presented.validationError, function(memo, attrErrors, attrName) {
10
+ memo[attrName + "_errors"] = attrErrors;
11
+ memo[attrName + "_error"] = attrErrors[0];
12
+ return memo;
13
+ }, {});
14
+ };
15
+
16
+ /*
17
+ Returns a template-friendly json representation of `presented`.
18
+
19
+ Example:
20
+
21
+ var MyModel = Backbone.Model.extend({
22
+ validate: function(attributes) {
23
+ var validate = new NailPolish.Validator();
24
+ validate.
25
+ attribute("username").
26
+ addRule("is too awesome", validate.is.notMatching(/^kaboom$/)).
27
+ addRule("is too long", validate.is.tooLong(5));
28
+ return validate.validate(attributes);
29
+ }
30
+ });
31
+
32
+ var model = new MyModel({ username: "socialcoder" });
33
+
34
+ var MyPresenter = NailPolish.Presenter.extend({
35
+ include: ["status", "likes"],
36
+
37
+ status: "better than ever",
38
+
39
+ likes: function() {
40
+ return ["clean code", "nice documentation"];
41
+ }
42
+ });
43
+
44
+ var presenter = new MyPresenter(model);
45
+ model.isValid();
46
+
47
+ presenter.toJSON();
48
+
49
+ // {
50
+ // "likes": ["clean code", "nice documentation"],
51
+ // "status": "better than ever",
52
+ // "username": "socialcoder",
53
+ // "username_error": "is too awesome",
54
+ // "username_errors": ["is too awesome", "is too long"]
55
+ // }
56
+ */
57
+ NailPolish.PresenterWithErrors.prototype.toJSON = function() {
58
+ var base = NailPolish.Presenter.prototype.toJSON.apply(this);
59
+ var errors = this.errors();
60
+ return _.extend(base, errors);
61
+ };
@@ -1,22 +1,17 @@
1
1
  NailPolish.Presenter.Dropdown = NailPolish.Presenter.extend({
2
- include: ["selected_value", "selectable_items", "selected_key"],
2
+ include: ["selected_value", "selectable_items"],
3
3
 
4
- selected_value: function(){
5
- selected_option = this.presented.options[this.presented.selected]
6
- return selected_option || _.values(this.presented.options)[0];
4
+ init: function() {
5
+ this.options = this.presented.get('options');
7
6
  },
8
7
 
9
- selected_key: function() {
10
- return this.presented.selected || _.keys(this.presented.options)[0];
8
+ selected_value: function(){
9
+ return this.options[this.presented.selected()];
11
10
  },
12
11
 
13
12
  selectable_items: function(){
14
- returnValue = [];
15
-
16
- _.each(this.presented.options, function(value, key){
17
- returnValue.unshift({key: key, value: value});
13
+ return _.map(this.options, function(value, key){
14
+ return {key: key, value: value};
18
15
  });
19
-
20
- return returnValue;
21
16
  }
22
17
  });
@@ -0,0 +1,7 @@
1
+ NailPolish.Presenter.Menu = NailPolish.Presenter.extend({
2
+ include: ['items'],
3
+
4
+ items: function() {
5
+ return [];
6
+ }
7
+ });
@@ -1,6 +1,6 @@
1
- NailPolish.Router = Backbone.Router.extend({
2
- initialize: function ($layout) {
3
- this.$layout = $layout;
1
+ NailPolish.Router = Backbone.Router.extend(_.extend(_.clone(NailPolish.SubviewManager), {
2
+ initialize: function ($el) {
3
+ this.$el = $el;
4
4
  this.history = [];
5
5
  this.on('route:start', this.storeHistory, this);
6
6
 
@@ -33,21 +33,31 @@ NailPolish.Router = Backbone.Router.extend({
33
33
  return this;
34
34
  },
35
35
 
36
+ fullPath: function() {
37
+ var history = Backbone.history
38
+ var path = history.location.pathname
39
+ if (history.getFragment().length) {
40
+ path = path + '#' + history.getFragment();
41
+ }
42
+ return path;
43
+ },
44
+
36
45
  page: function (views) {
37
- NailPolish.Events.publish('page:new');
38
- this.$layout.empty();
46
+ NailPolish.Events.publish('page:new');
47
+ this.remove();
48
+ this.$el.empty();
39
49
  this.render(views);
40
50
  },
41
51
 
42
- render: function (args) {
43
- _.each(args, function (view) {
44
- view.parent = view.parent || this.$layout;
45
- view.repository = view.repository || this.repository;
46
- view.render();
47
- }.bind(this));
52
+ render: function (subviews) {
53
+ this.renderEach(subviews);
48
54
  this.afterRender();
49
55
  },
50
56
 
57
+ defaultParent: function() {
58
+ return this.$el;
59
+ },
60
+
51
61
  afterRender: function(){
52
62
  //put your after render stuff here
53
63
  },
@@ -55,7 +65,7 @@ NailPolish.Router = Backbone.Router.extend({
55
65
  // this is usually used for NailPolish.Events to publish a redirect event!
56
66
  redirect: function (path) {
57
67
  window.location = path;
58
- },
68
+ },
59
69
 
60
70
  go: function(fragment) {
61
71
  this.navigate(fragment, {trigger: true});
@@ -75,4 +85,4 @@ NailPolish.Router = Backbone.Router.extend({
75
85
  storeHistory: function () {
76
86
  this.history.push(Backbone.history.fragment);
77
87
  }
78
- });
88
+ }));