nail_polish 0.1.1 → 0.2.6

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.
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
+ }));