nail_polish 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +29 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/nail_polish/app.js +58 -0
- data/app/assets/javascripts/nail_polish/events/flasher.js +17 -0
- data/app/assets/javascripts/nail_polish/events/redirector.js +3 -0
- data/app/assets/javascripts/nail_polish/events.js +28 -0
- data/app/assets/javascripts/nail_polish/nail_polish.js +25 -0
- data/app/assets/javascripts/nail_polish/overrides/auth_token_adder.js +44 -0
- data/app/assets/javascripts/nail_polish/overrides/for_backbone.js +14 -0
- data/app/assets/javascripts/nail_polish/overrides/function_bind.js +6 -0
- data/app/assets/javascripts/nail_polish/overrides/global_publisher_adder.js +28 -0
- data/app/assets/javascripts/nail_polish/presenter.js +43 -0
- data/app/assets/javascripts/nail_polish/presenters/collection.js +11 -0
- data/app/assets/javascripts/nail_polish/router.js +78 -0
- data/app/assets/javascripts/nail_polish/utils/text.js +36 -0
- data/app/assets/javascripts/nail_polish/view/parent_finder.js +46 -0
- data/app/assets/javascripts/nail_polish/view.js +80 -0
- data/app/assets/javascripts/nail_polish/widget/flash.js +36 -0
- data/app/assets/javascripts/nail_polish/widget/modal.js +40 -0
- data/app/assets/javascripts/nail_polish.js +21 -0
- data/app/assets/javascripts/nail_polish_legacy_base.js +2 -0
- data/app/assets/javascripts/nail_polish_modern_base.js +2 -0
- data/app/assets/javascripts/nail_polish_widgets.js +2 -0
- data/app/assets/javascripts/vendor/backbone.js +1571 -0
- data/app/assets/javascripts/vendor/jquery-1.8.3.js +9472 -0
- data/app/assets/javascripts/vendor/jquery.cookie.js +94 -0
- data/app/assets/javascripts/vendor/underscore.js +1200 -0
- data/app/assets/javascripts/vendor/zepto.cookie.js +22 -0
- data/app/assets/javascripts/vendor/zepto.js +1355 -0
- data/config/initializers/nail_polish.rb +1 -0
- data/config/routes.rb +2 -0
- data/lib/nail_polish/engine.rb +4 -0
- data/lib/nail_polish/version.rb +3 -0
- data/lib/nail_polish.rb +7 -0
- data/lib/tasks/nail_polish_tasks.rake +4 -0
- metadata +207 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 02093b432326e2623e61fc3bf74ba94d061c9039
|
4
|
+
data.tar.gz: 058bc41c0e48b1fa57ab187283305ecdfbbf743e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a01a5e64327c6ce39fd9d4c51833c38a197c34fbe0234ed28d173065dcc3d15f70956f682ddd2d08d84dec73542e0872f11b34db656b8eef1fd1f72806fc34fb
|
7
|
+
data.tar.gz: 304b28c76819afe5245e596dd4d96cb1211fbaa9e189b1db34fd583c14e5bc69646aa55654895a4b8d1b97d64f443620804da54771cb1c74a8da5cb179fbef75
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
= NailPolish: SocialChorus/SocialChorus OO FrontEnd
|
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
|
6
|
+
conventions.
|
7
|
+
|
8
|
+
== TODO
|
9
|
+
* Hogan compilation for performance
|
10
|
+
* template in page render to prevent large resources
|
11
|
+
* widgets
|
12
|
+
* Dropdown menu
|
13
|
+
* back button
|
14
|
+
* modal
|
15
|
+
* form view
|
16
|
+
* model view
|
17
|
+
* collection view
|
18
|
+
* generators
|
19
|
+
- view
|
20
|
+
- template
|
21
|
+
- presenter
|
22
|
+
- specs for presenter and view
|
23
|
+
* js models
|
24
|
+
* simplified CSS
|
25
|
+
|
26
|
+
== Development
|
27
|
+
The current jasmine gem does not play well with engines.
|
28
|
+
To modify and test javascript, go into the spec/dummy directory and then
|
29
|
+
run `rake jasmine` or `rake jasmine:ci`.
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'NailPolish'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
//specs to come
|
2
|
+
NailPolish.App = function() {};
|
3
|
+
NailPolish.App.extend = Backbone.Model.extend;
|
4
|
+
|
5
|
+
_.extend(NailPolish.App.prototype, {
|
6
|
+
initialize: function(parent, opts) {
|
7
|
+
this.parent = parent;
|
8
|
+
this.opts = opts;
|
9
|
+
this.init(parent, opts);
|
10
|
+
},
|
11
|
+
|
12
|
+
start: function () {
|
13
|
+
this.repository = this.bootstrap();
|
14
|
+
this.route();
|
15
|
+
this.render();
|
16
|
+
},
|
17
|
+
|
18
|
+
route: function() {
|
19
|
+
this.router = new (this.routerClass())();
|
20
|
+
this.router.repository = this.repository;
|
21
|
+
Backbone.history.start();
|
22
|
+
},
|
23
|
+
|
24
|
+
render: function() {
|
25
|
+
_.each(this.subViews(), function(view) {
|
26
|
+
view.parent = view.parent || this.parent;
|
27
|
+
view.render();
|
28
|
+
}.bind(this));
|
29
|
+
},
|
30
|
+
|
31
|
+
bootstrapData: function() {
|
32
|
+
var data = data || JSON.parse($('#bootstrap-json').text());
|
33
|
+
return data;
|
34
|
+
},
|
35
|
+
|
36
|
+
//Stuff for YOU to configure
|
37
|
+
|
38
|
+
init: function() {
|
39
|
+
//your init stuff here
|
40
|
+
},
|
41
|
+
|
42
|
+
bootstrap: function() {
|
43
|
+
//override this if you want specific models in your repo
|
44
|
+
return this.bootstrapData();
|
45
|
+
},
|
46
|
+
|
47
|
+
subViews: function() {
|
48
|
+
//fill me in
|
49
|
+
|
50
|
+
//return [
|
51
|
+
// new View.That.I.Want.To.Render({model: model})
|
52
|
+
//]
|
53
|
+
},
|
54
|
+
|
55
|
+
routerClass: function () {
|
56
|
+
//set this, yo
|
57
|
+
}
|
58
|
+
});
|
@@ -0,0 +1,17 @@
|
|
1
|
+
NailPolish.Events.Flasher = function (view) {
|
2
|
+
this.view = view;
|
3
|
+
};
|
4
|
+
|
5
|
+
_.extend(NailPolish.Events.Flasher.prototype, {
|
6
|
+
subscribe: function () {
|
7
|
+
NailPolish.Events.subscribe('flash', this.perform, this);
|
8
|
+
},
|
9
|
+
|
10
|
+
perform: function (data) {
|
11
|
+
this.view.model = data;
|
12
|
+
this.view.show();
|
13
|
+
}
|
14
|
+
});
|
15
|
+
|
16
|
+
NailPolish.Events.Flasher.extend = Backbone.Model.extend;
|
17
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
NailPolish.Events = {
|
2
|
+
isTouch: function() {
|
3
|
+
// taken from Modernizr: http://modernizr.com/license
|
4
|
+
return (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
|
5
|
+
},
|
6
|
+
|
7
|
+
isWindowsTouch: function() {
|
8
|
+
if (/Windows.NT.6/i.test(navigator.userAgent)){
|
9
|
+
return true;
|
10
|
+
}
|
11
|
+
return false;
|
12
|
+
},
|
13
|
+
startEvent: 'touchstart',
|
14
|
+
|
15
|
+
publisher: _.extend({}, Backbone.Events),
|
16
|
+
|
17
|
+
publish: function (event, args) {
|
18
|
+
this.publisher.trigger(event, args);
|
19
|
+
},
|
20
|
+
|
21
|
+
subscribe: function (event, callback, context) {
|
22
|
+
this.publisher.on(event, callback, context);
|
23
|
+
},
|
24
|
+
|
25
|
+
unsubscribe: function(event, callback, context) {
|
26
|
+
this.publisher.off(event, callback, context);
|
27
|
+
}
|
28
|
+
};
|
@@ -0,0 +1,25 @@
|
|
1
|
+
var NailPolish = {
|
2
|
+
apps: function () {
|
3
|
+
if (this._apps) return this._apps;
|
4
|
+
this._apps = [];
|
5
|
+
return this._apps;
|
6
|
+
},
|
7
|
+
|
8
|
+
add: function (app) {
|
9
|
+
if (this.apps().length <= 0) {
|
10
|
+
this.startServices();
|
11
|
+
}
|
12
|
+
if (!_.include(this.apps(), app)) {
|
13
|
+
this.apps().push(app);
|
14
|
+
}
|
15
|
+
},
|
16
|
+
|
17
|
+
startServices: function () {
|
18
|
+
Backbone.history.start();
|
19
|
+
_.each(this.subscriptions, function (callback, event) {
|
20
|
+
NailPolish.Events.subscribe(event, callback);
|
21
|
+
});
|
22
|
+
}
|
23
|
+
};
|
24
|
+
|
25
|
+
NailPolish.Widget = {};
|
@@ -0,0 +1,44 @@
|
|
1
|
+
// Backbone does not send model data with delete requests ...
|
2
|
+
// which means the authenticity token does not go there either.
|
3
|
+
// It sucks, but we unpack the data before each request, and send the
|
4
|
+
// token along
|
5
|
+
|
6
|
+
NailPolish.AuthTokenAdder = function (args) {
|
7
|
+
this.args = args;
|
8
|
+
this.type = args.type.toLowerCase();
|
9
|
+
this.data = _.clone(args.data || {});
|
10
|
+
this.authenticityToken = $('meta[name="csrf-token"]').attr('content');
|
11
|
+
};
|
12
|
+
|
13
|
+
NailPolish.AuthTokenAdder.prototype.perform = function () {
|
14
|
+
this.handlePostPutPatch();
|
15
|
+
this.handleDelete();
|
16
|
+
return this.args;
|
17
|
+
};
|
18
|
+
|
19
|
+
NailPolish.AuthTokenAdder.prototype.handleDelete = function () {
|
20
|
+
if ( this.type != 'delete' ) { return; }
|
21
|
+
|
22
|
+
this.args.url = this.args.url +
|
23
|
+
"?authenticity_token=" +
|
24
|
+
encodeURIComponent(this.authenticityToken);
|
25
|
+
};
|
26
|
+
|
27
|
+
NailPolish.AuthTokenAdder.prototype.handlePostPutPatch = function () {
|
28
|
+
if ( this.type != 'post' && this.type != 'put' && this.type != 'patch' ) { return; }
|
29
|
+
|
30
|
+
if ( _.isString(this.data) ) {
|
31
|
+
this.repackageStringData();
|
32
|
+
}
|
33
|
+
|
34
|
+
this.addAuthToken();
|
35
|
+
};
|
36
|
+
|
37
|
+
NailPolish.AuthTokenAdder.prototype.repackageStringData = function () {
|
38
|
+
this.data = JSON.parse(this.data);
|
39
|
+
};
|
40
|
+
|
41
|
+
NailPolish.AuthTokenAdder.prototype.addAuthToken = function () {
|
42
|
+
data = _.extend(this.data, {authenticity_token: this.authenticityToken});
|
43
|
+
this.args.data = this.data = JSON.stringify(data);
|
44
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Backbone.ajax = function() {
|
2
|
+
// adds the authenticity token
|
3
|
+
var args = _.map(arguments, function(a) {
|
4
|
+
return new NailPolish.AuthTokenAdder(a).perform();
|
5
|
+
});
|
6
|
+
|
7
|
+
// reads events from data, and does a global publish
|
8
|
+
args = _.map(args, function(a) {
|
9
|
+
return new NailPolish.GlobalPublisherAdder(a).perform();
|
10
|
+
});
|
11
|
+
|
12
|
+
return Backbone.$.ajax.apply(Backbone.$, args);
|
13
|
+
};
|
14
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
NailPolish.GlobalPublisherAdder = function (args) {
|
2
|
+
this.args = args;
|
3
|
+
};
|
4
|
+
|
5
|
+
_.extend(NailPolish.GlobalPublisherAdder.prototype, {
|
6
|
+
perform: function () {
|
7
|
+
this.args.complete = this.wrapComplete(this.args.complete);
|
8
|
+
return this.args;
|
9
|
+
},
|
10
|
+
|
11
|
+
wrapComplete: function (callback) {
|
12
|
+
return function(xhr, status) {
|
13
|
+
// call the original callback
|
14
|
+
callback && callback(xhr, status);
|
15
|
+
|
16
|
+
// extract the JSON data
|
17
|
+
|
18
|
+
response = xhr.response || "{}"
|
19
|
+
var data = JSON.parse(response);
|
20
|
+
var publisher = NailPolish.Events;
|
21
|
+
|
22
|
+
// publish each event received
|
23
|
+
_.each(data.events, function (value, key) {
|
24
|
+
publisher.publish(key, value);
|
25
|
+
});
|
26
|
+
};
|
27
|
+
}
|
28
|
+
});
|
@@ -0,0 +1,43 @@
|
|
1
|
+
NailPolish.Presenter = function(presented) {
|
2
|
+
this.presented = presented || {};
|
3
|
+
this.initialize();
|
4
|
+
this.init();
|
5
|
+
};
|
6
|
+
|
7
|
+
NailPolish.Presenter.prototype.initialize = function () {
|
8
|
+
//Put your stuff here
|
9
|
+
};
|
10
|
+
|
11
|
+
NailPolish.Presenter.prototype.init = function () {
|
12
|
+
//Put your stuff here
|
13
|
+
};
|
14
|
+
|
15
|
+
NailPolish.Presenter.extend = Backbone.Model.extend;
|
16
|
+
|
17
|
+
NailPolish.Presenter.prototype.presentedToJSON = function () {
|
18
|
+
var json;
|
19
|
+
if (this.presented && this.presented.toJSON) {
|
20
|
+
json = this.presented.toJSON();
|
21
|
+
}
|
22
|
+
return json || this.presented;
|
23
|
+
};
|
24
|
+
|
25
|
+
NailPolish.Presenter.prototype.inclusions = function () {
|
26
|
+
var inclusions = {};
|
27
|
+
_.each(this.include || [], function (prop) {
|
28
|
+
inclusions[prop] = this.inclusionFor(prop);
|
29
|
+
}.bind(this));
|
30
|
+
return inclusions;
|
31
|
+
};
|
32
|
+
|
33
|
+
NailPolish.Presenter.prototype.inclusionFor = function (attr) {
|
34
|
+
var prop = this[attr];
|
35
|
+
return _.isFunction(prop) ? prop.bind(this)() : prop;
|
36
|
+
};
|
37
|
+
|
38
|
+
NailPolish.Presenter.prototype.toJSON = function() {
|
39
|
+
var base = this.presentedToJSON();
|
40
|
+
var inclusions = this.inclusions();
|
41
|
+
return _.extend(base, inclusions);
|
42
|
+
};
|
43
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
NailPolish.Presenter.Collection = NailPolish.Presenter.extend({
|
2
|
+
presentedToJSON: function () {
|
3
|
+
var json;
|
4
|
+
if (this.presented && this.presented.toJSON) {
|
5
|
+
json = this.presented.toJSON();
|
6
|
+
}
|
7
|
+
var returnValue = {};
|
8
|
+
returnValue[this.name] = (json || this.presented);
|
9
|
+
return returnValue;
|
10
|
+
}
|
11
|
+
})
|
@@ -0,0 +1,78 @@
|
|
1
|
+
NailPolish.Router = Backbone.Router.extend({
|
2
|
+
initialize: function ($layout) {
|
3
|
+
this.$layout = $layout;
|
4
|
+
this.history = [];
|
5
|
+
this.on('route:start', this.storeHistory, this);
|
6
|
+
|
7
|
+
this.init();
|
8
|
+
},
|
9
|
+
|
10
|
+
init: function () {},
|
11
|
+
|
12
|
+
// We are overriding this method to add some events before and after
|
13
|
+
// a route happens. Unfortunately, the anonymous function in the middle
|
14
|
+
// doesn't allow us to call super and change just that behavior.
|
15
|
+
route: function (route, name, callback) {
|
16
|
+
if (!_.isRegExp(route)) route = this._routeToRegExp(route);
|
17
|
+
if (_.isFunction(name)) {
|
18
|
+
callback = name;
|
19
|
+
name = '';
|
20
|
+
}
|
21
|
+
if (!callback) callback = this[name];
|
22
|
+
|
23
|
+
var router = this;
|
24
|
+
Backbone.history.route(route, function(fragment) {
|
25
|
+
var args = router._extractParameters(route, fragment);
|
26
|
+
router.trigger('route:start', fragment, args);
|
27
|
+
callback && callback.apply(router, args);
|
28
|
+
router.trigger.apply(router, ['route:' + name].concat(args));
|
29
|
+
router.trigger('route', name, args);
|
30
|
+
Backbone.history.trigger('route', router, name, args);
|
31
|
+
});
|
32
|
+
|
33
|
+
return this;
|
34
|
+
},
|
35
|
+
|
36
|
+
page: function (views) {
|
37
|
+
NailPolish.Events.publish('page:new');
|
38
|
+
this.$layout.empty();
|
39
|
+
this.render(views);
|
40
|
+
},
|
41
|
+
|
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));
|
48
|
+
this.afterRender();
|
49
|
+
},
|
50
|
+
|
51
|
+
afterRender: function(){
|
52
|
+
//put your after render stuff here
|
53
|
+
},
|
54
|
+
|
55
|
+
// this is usually used for NailPolish.Events to publish a redirect event!
|
56
|
+
redirect: function (path) {
|
57
|
+
window.location = path;
|
58
|
+
},
|
59
|
+
|
60
|
+
go: function(fragment) {
|
61
|
+
this.navigate(fragment, {trigger: true});
|
62
|
+
},
|
63
|
+
|
64
|
+
goReplacingLastHistory: function(fragment) {
|
65
|
+
this.history.pop();
|
66
|
+
this.navigate(fragment, { trigger: true, replace: true });
|
67
|
+
},
|
68
|
+
|
69
|
+
back: function () {
|
70
|
+
this.history.pop();
|
71
|
+
var fragment = _.last(this.history);
|
72
|
+
this.goReplacingLastHistory(fragment);
|
73
|
+
},
|
74
|
+
|
75
|
+
storeHistory: function () {
|
76
|
+
this.history.push(Backbone.history.fragment);
|
77
|
+
}
|
78
|
+
});
|
@@ -0,0 +1,36 @@
|
|
1
|
+
NailPolish.TextUtils = {
|
2
|
+
camelize: function (word) {
|
3
|
+
return word
|
4
|
+
.replace(/^(\w)/, function(g) {
|
5
|
+
return g.toUpperCase();
|
6
|
+
}).replace(/(_\w)/g, function(g) {
|
7
|
+
return g[1].toUpperCase();
|
8
|
+
});
|
9
|
+
},
|
10
|
+
|
11
|
+
underscore: function (word) {
|
12
|
+
return word
|
13
|
+
.replace(/^(\w)/, function(g) {
|
14
|
+
return g.toLowerCase();
|
15
|
+
})
|
16
|
+
.replace(/([A-Z])/g, function (g) {
|
17
|
+
return "_" + g.toLowerCase();
|
18
|
+
});
|
19
|
+
},
|
20
|
+
|
21
|
+
shorten: function(text, n) {
|
22
|
+
if (!text || !n) { return; }
|
23
|
+
|
24
|
+
if (text.length > n) {
|
25
|
+
text = text.substr(0, n) + '...';
|
26
|
+
}
|
27
|
+
return text;
|
28
|
+
},
|
29
|
+
|
30
|
+
stripTags: function (text) {
|
31
|
+
return text
|
32
|
+
.replace(/<(?:.|\n)*?>/gm, ' ')
|
33
|
+
.replace(/\s+/g, ' ')
|
34
|
+
.replace(/^\s/, '');
|
35
|
+
}
|
36
|
+
};
|
@@ -0,0 +1,46 @@
|
|
1
|
+
NailPolish.View.ParentFinder = function (parent, selector, method) {
|
2
|
+
this.parent = parent;
|
3
|
+
this.selector = selector;
|
4
|
+
this.method = method;
|
5
|
+
};
|
6
|
+
|
7
|
+
_.extend(NailPolish.View.ParentFinder.prototype, {
|
8
|
+
perform: function () {
|
9
|
+
if (this.parent) {
|
10
|
+
// If it is a backbone view, use the $el for parent
|
11
|
+
if (this.parent.$el) { this.parent = this.parent.$el; }
|
12
|
+
|
13
|
+
if(this.selector) {
|
14
|
+
//pretends it is jquery
|
15
|
+
if (this.parentIsAttachable() && this.parentIsFindable()) {
|
16
|
+
return this.findLocally()
|
17
|
+
}
|
18
|
+
} else {
|
19
|
+
// is parent, no selector
|
20
|
+
return this.parent;
|
21
|
+
}
|
22
|
+
} else {
|
23
|
+
// no parent, but there is a selector
|
24
|
+
return this.findGlobally();
|
25
|
+
}
|
26
|
+
},
|
27
|
+
|
28
|
+
findLocally: function() {
|
29
|
+
var found = this.parent.find(this.selector)
|
30
|
+
if (found.length) { return found }
|
31
|
+
},
|
32
|
+
|
33
|
+
findGlobally: function() {
|
34
|
+
if (!this.selector || !$(this.selector).length) { return; }
|
35
|
+
|
36
|
+
return $(this.selector);
|
37
|
+
},
|
38
|
+
|
39
|
+
parentIsAttachable: function () {
|
40
|
+
return !!(this.parent && this.parent[this.method]);
|
41
|
+
},
|
42
|
+
|
43
|
+
parentIsFindable: function () {
|
44
|
+
return !!(this.parent && this.parent['find']);
|
45
|
+
}
|
46
|
+
});
|
@@ -0,0 +1,80 @@
|
|
1
|
+
NailPolish.View = Backbone.View.extend({
|
2
|
+
addListeners: {},
|
3
|
+
presenterClass: function () {
|
4
|
+
return NailPolish.Presenter;
|
5
|
+
},
|
6
|
+
|
7
|
+
initialize: function (opts) {
|
8
|
+
opts = opts || {};
|
9
|
+
this.parent = opts.parent;
|
10
|
+
this.repository = opts.repository;
|
11
|
+
this.attachmentMethod = this.attachmentMethod || 'append';
|
12
|
+
this.init(opts);
|
13
|
+
},
|
14
|
+
|
15
|
+
init: function (opts) {
|
16
|
+
// override in classes
|
17
|
+
},
|
18
|
+
|
19
|
+
render: function () {
|
20
|
+
this.renderTemplate();
|
21
|
+
this.renderSubviews();
|
22
|
+
this.attachToParent();
|
23
|
+
this.afterRender();
|
24
|
+
},
|
25
|
+
|
26
|
+
subviews: function () {
|
27
|
+
return [];
|
28
|
+
},
|
29
|
+
|
30
|
+
renderSubviews: function () {
|
31
|
+
_.each(this.subviews(), function (view) {
|
32
|
+
view.parent = this;
|
33
|
+
view.render();
|
34
|
+
}.bind(this));
|
35
|
+
},
|
36
|
+
|
37
|
+
attachToParent: function () {
|
38
|
+
var $parent = new NailPolish.View.ParentFinder(
|
39
|
+
this.parent, this.parentSelector, this.attachmentMethod
|
40
|
+
).perform();
|
41
|
+
$parent && $parent[this.attachmentMethod](this.el);
|
42
|
+
},
|
43
|
+
|
44
|
+
afterRender: function () { /* template method hook ! */
|
45
|
+
},
|
46
|
+
|
47
|
+
events: function () {
|
48
|
+
if (NailPolish.Events.isTouch() && !NailPolish.Events.isWindowsTouch()) {
|
49
|
+
var eventSet = {};
|
50
|
+
|
51
|
+
_.each(_.keys(this.addListeners), function (eventKey) {
|
52
|
+
var key = eventKey.replace('click', NailPolish.Events.startEvent);
|
53
|
+
eventSet[key] = this.addListeners[eventKey];
|
54
|
+
}.bind(this));
|
55
|
+
|
56
|
+
return eventSet;
|
57
|
+
}
|
58
|
+
return this.addListeners;
|
59
|
+
},
|
60
|
+
|
61
|
+
renderTemplate: function () {
|
62
|
+
var template = HoganTemplates[this.templateName];
|
63
|
+
if (!template) {
|
64
|
+
return;
|
65
|
+
}
|
66
|
+
var rendered = template.render(this.presenter(), this.partials());
|
67
|
+
this.$el.html(rendered);
|
68
|
+
},
|
69
|
+
|
70
|
+
presenter: function () {
|
71
|
+
var presented = this.model || this.collection || {};
|
72
|
+
var presenter = new (this.presenterClass())(presented);
|
73
|
+
return presenter.toJSON();
|
74
|
+
},
|
75
|
+
|
76
|
+
partials: function () {
|
77
|
+
// override with own partials if necessary
|
78
|
+
return {};
|
79
|
+
}
|
80
|
+
});
|
@@ -0,0 +1,36 @@
|
|
1
|
+
NailPolish.Widget.Flash = NailPolish.View.extend({
|
2
|
+
templateName: 'flash',
|
3
|
+
className: 'flash',
|
4
|
+
parentSelector: '#flash-container',
|
5
|
+
attachmentMethod: 'html',
|
6
|
+
animationLength: 500,
|
7
|
+
showFor: 2000,
|
8
|
+
|
9
|
+
addListeners: {
|
10
|
+
'click .close': 'hide'
|
11
|
+
},
|
12
|
+
|
13
|
+
perform: function (model) {
|
14
|
+
this.model = model;
|
15
|
+
this.render();
|
16
|
+
},
|
17
|
+
|
18
|
+
afterRender: function () {
|
19
|
+
this.show();
|
20
|
+
},
|
21
|
+
|
22
|
+
show: function () {
|
23
|
+
window.scrollTo(0, 0);
|
24
|
+
this.$el.css('opacity', 0);
|
25
|
+
this.$el.show();
|
26
|
+
this.$el.animate({opacity: 1}, this.animationLength);
|
27
|
+
|
28
|
+
setTimeout(this.hide.bind(this), this.showFor);
|
29
|
+
},
|
30
|
+
|
31
|
+
hide: function () {
|
32
|
+
this.$el.animate(
|
33
|
+
{opacity: 0}, this.animationLength, this.$el.hide.bind(this.$el)
|
34
|
+
);
|
35
|
+
}
|
36
|
+
});
|