stormfront-rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/lib/stormfront/rails/version.rb +5 -0
- data/lib/stormfront/rails.rb +7 -0
- data/stormfront-rails.gemspec +22 -0
- data/vendor/assets/javascripts/stormfront/Alert.js +17 -0
- data/vendor/assets/javascripts/stormfront/Container.js +31 -0
- data/vendor/assets/javascripts/stormfront/Entity.js +53 -0
- data/vendor/assets/javascripts/stormfront/Errors.js +25 -0
- data/vendor/assets/javascripts/stormfront/KeyboardEvents.js +52 -0
- data/vendor/assets/javascripts/stormfront/Layout.js +60 -0
- data/vendor/assets/javascripts/stormfront/List.js +123 -0
- data/vendor/assets/javascripts/stormfront/MouseEvents.js +146 -0
- data/vendor/assets/javascripts/stormfront/Namespaces.js +5 -0
- data/vendor/assets/javascripts/stormfront/Overlay.js +178 -0
- data/vendor/assets/javascripts/stormfront/Reducer.js +9 -0
- data/vendor/assets/javascripts/stormfront/Request.js +39 -0
- data/vendor/assets/javascripts/stormfront/View.js +55 -0
- data/vendor/assets/javascripts/stormfront/ViewBase.js +57 -0
- data/vendor/assets/javascripts/stormfront/mixin/Dispatch.js +19 -0
- data/vendor/assets/javascripts/stormfront/mixin/Other.js +25 -0
- data/vendor/assets/javascripts/stormfront/support/Chaperone.js +69 -0
- data/vendor/assets/javascripts/stormfront/support/Template.js +75 -0
- data/vendor/assets/javascripts/stormfront/types/Arguments.js +27 -0
- data/vendor/assets/javascripts/stormfront/types/Class.js +25 -0
- data/vendor/assets/javascripts/stormfront/types/Hash.js +23 -0
- data/vendor/assets/javascripts/stormfront/types/Number.js +15 -0
- data/vendor/assets/javascripts/stormfront/types/Response.js +31 -0
- data/vendor/assets/javascripts/stormfront/types/String.js +44 -0
- data/vendor/assets/javascripts/stormfront/types/Time.js +29 -0
- data/vendor/assets/javascripts/stormfront.js +33 -0
- metadata +148 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 607f574ffebeed664fd07f4405364de3db985bb8
|
4
|
+
data.tar.gz: aeb81e1a7a89a8b1004c20ce422684bf5efdb96d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0ec6b5d716dfc4928e5680a64c0963bfcb498c3f6b0a8b15fdcde573b851d2afb560e86dc2c033a8a3ae5d0ccef92d78b6539ff581a851f5089138bcde448786
|
7
|
+
data.tar.gz: 0700879935004467d0538d2a483165d5ee2f6c8de0550c66fa4443c9afe9c64669691d6dcf3b4a9103632c515fef34d44212796c640756c20cc9acfcc19a2b57
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Chris G
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Stormfront::Rails
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'stormfront-rails'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install stormfront-rails
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it ( https://github.com/[my-github-username]/stormfront-rails/fork )
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'stormfront/rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'stormfront-rails'
|
8
|
+
spec.version = Stormfront::Rails::VERSION
|
9
|
+
spec.authors = ['Chris Gee']
|
10
|
+
spec.summary = %q{A framework built upon Backbone}
|
11
|
+
spec.description = %q{This is an initial extraction into a gem of the framework in use by my company}
|
12
|
+
spec.homepage = ''
|
13
|
+
spec.license = 'MIT'
|
14
|
+
spec.files = `git ls-files`.split("\n")
|
15
|
+
spec.require_paths = ['lib']
|
16
|
+
|
17
|
+
spec.add_dependency 'simple-jquery-rails'
|
18
|
+
spec.add_dependency 'simple-backbone-rails'
|
19
|
+
spec.add_dependency 'simple-momentjs-rails'
|
20
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
21
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
//TODO: This whole class depends on Bootstrap
|
2
|
+
Stormfront.Alert = Stormfront.View.extend({
|
3
|
+
className: 'alert',
|
4
|
+
when: {
|
5
|
+
rendering: function(){
|
6
|
+
this.$el.attr('role', 'alert').
|
7
|
+
addClass('alert-warning').
|
8
|
+
addClass('alert-dismissible');
|
9
|
+
|
10
|
+
var self = this;
|
11
|
+
this.$el.on('closed.bs.alert', function(){
|
12
|
+
self.trigger('closing');
|
13
|
+
self.close();
|
14
|
+
});
|
15
|
+
}
|
16
|
+
}
|
17
|
+
});
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Stormfront.Container = Stormfront.View.extend({
|
2
|
+
reducers: [],
|
3
|
+
store: null,
|
4
|
+
root: null,
|
5
|
+
when: {
|
6
|
+
initializing: function(){
|
7
|
+
this._reducers = _.map(this.reducers, this.createReducer, this);
|
8
|
+
},
|
9
|
+
rendering: function(){
|
10
|
+
this.store = new this.store();
|
11
|
+
this.root = new this.root({model: this.store});
|
12
|
+
this.listenToDispatches(this.root);
|
13
|
+
this.$el.append(this.root.render().$el);
|
14
|
+
}
|
15
|
+
},
|
16
|
+
createReducer: function(interaction){
|
17
|
+
var useCase = new interaction();
|
18
|
+
this.listenToDispatches(useCase);
|
19
|
+
return this.addReducer(useCase);
|
20
|
+
},
|
21
|
+
addReducer: function(useCase){
|
22
|
+
this._reducers[useCase.type] = useCase;
|
23
|
+
return useCase;
|
24
|
+
},
|
25
|
+
executeUseCase: function(event){
|
26
|
+
this._reducers[event.type].execute(this.store, event);
|
27
|
+
},
|
28
|
+
listenToDispatches: function(publisher){
|
29
|
+
this.listenTo(publisher, 'dispatch', this.executeUseCase);
|
30
|
+
}
|
31
|
+
});
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Stormfront.Entity = Stormfront.View.extend({
|
2
|
+
exceptions: {
|
3
|
+
model: {
|
4
|
+
error: function(collection, xhr){
|
5
|
+
var response = new Stormfront.Response(xhr);
|
6
|
+
if (response.isActionable()) {
|
7
|
+
this.handleException({error: response.getError()});
|
8
|
+
response.markAsHandled();
|
9
|
+
}
|
10
|
+
},
|
11
|
+
invalid: function(model, error){
|
12
|
+
this.handleException({error: error});
|
13
|
+
}
|
14
|
+
}
|
15
|
+
},
|
16
|
+
overlays: {
|
17
|
+
model: {
|
18
|
+
request: function(){
|
19
|
+
this.addOverlay();
|
20
|
+
},
|
21
|
+
sync: function(){
|
22
|
+
this.removeOverlay();
|
23
|
+
},
|
24
|
+
error: function(){
|
25
|
+
this.removeOverlay();
|
26
|
+
}
|
27
|
+
}
|
28
|
+
},
|
29
|
+
change: {
|
30
|
+
model: {
|
31
|
+
change: function(){
|
32
|
+
this.render();
|
33
|
+
}
|
34
|
+
}
|
35
|
+
},
|
36
|
+
initialize: function(){
|
37
|
+
this.addSubscriber(this.overlays);
|
38
|
+
this.addSubscriber(this.exceptions);
|
39
|
+
this.addSubscriber(this.change);
|
40
|
+
this.addPublisher(this.model);
|
41
|
+
Stormfront.View.prototype.initialize.apply(this, arguments);
|
42
|
+
},
|
43
|
+
addOverlay: function(){
|
44
|
+
this.removeOverlay();
|
45
|
+
this.overlay = new Stormfront.Overlay({selector: this.$el});
|
46
|
+
},
|
47
|
+
removeOverlay: function(){
|
48
|
+
if (this.overlay) {
|
49
|
+
this.overlay.close();
|
50
|
+
this.overlay = null;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
});
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Stormfront.Errors = {
|
2
|
+
FEEDBACK: 'An unexpected error was encountered',
|
3
|
+
/** @return {string} */
|
4
|
+
NO_SELECTOR: function() { return 'A template selector was not provided for your view' },
|
5
|
+
/** @return {string} */
|
6
|
+
NO_TEMPLATE: function(name) { return name +'\'s template was not found'; },
|
7
|
+
/** @return {string} */
|
8
|
+
INCOMPATIBLE_TEMPLATE: function(name) { return name +'\'s template and view model for your view are not compatible'; },
|
9
|
+
/** @return {string} */
|
10
|
+
VIEW_MODEL: function(name) { return name + '\'s view model for the child generated an error'; },
|
11
|
+
/** @return {string} */
|
12
|
+
NO_LOCATION: function(name) { return name + ' has no locations available to render'; },
|
13
|
+
/** @return {string} */
|
14
|
+
MULTIPLE_LOCATIONS: function(name) { return name + ' has multiple locations available to render'; },
|
15
|
+
/** @return {string} */
|
16
|
+
INITIALIZING: function(name) { return name + ' failed to initialize'; },
|
17
|
+
/** @return {string} */
|
18
|
+
RENDERING: function(name) { return name + ' failed to render'; },
|
19
|
+
/** @return {string} */
|
20
|
+
ATTACHING: function(name) { return name + ' failed to attach'; },
|
21
|
+
/** @return {string} */
|
22
|
+
CLOSING: function(name) { return name + ' failed to close'; },
|
23
|
+
/** @return {string} */
|
24
|
+
ADDING: function(name) { return name + ' failed to add'; }
|
25
|
+
};
|
@@ -0,0 +1,52 @@
|
|
1
|
+
Keys = {
|
2
|
+
Enter: 13,
|
3
|
+
LeftArrow: 37,
|
4
|
+
DownArrow: 40,
|
5
|
+
RightArrow: 39,
|
6
|
+
UpArrow: 38,
|
7
|
+
C: 67,
|
8
|
+
R: 82,
|
9
|
+
M: 77,
|
10
|
+
Tab: 9,
|
11
|
+
Override: 1000,
|
12
|
+
Shift: 2000
|
13
|
+
};
|
14
|
+
|
15
|
+
KeyboardEvents = Stormfront.Class.extend({
|
16
|
+
initialize: function(){
|
17
|
+
_.bindAll(this, 'onKeyDown');
|
18
|
+
_.extend(this, Backbone.Events);
|
19
|
+
$(window).on('keydown', this.onKeyDown);
|
20
|
+
},
|
21
|
+
onKeyDown: function(event){
|
22
|
+
function isInput(node){
|
23
|
+
switch(node){
|
24
|
+
case 'SELECT':
|
25
|
+
return true;
|
26
|
+
case 'TEXTAREA':
|
27
|
+
return true;
|
28
|
+
case 'INPUT':
|
29
|
+
return true;
|
30
|
+
case 'BUTTON':
|
31
|
+
return true;
|
32
|
+
default:
|
33
|
+
return false;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
var shift = event.shiftKey ? Keys.Shift : 0;
|
37
|
+
var override = isInput(document.activeElement.nodeName) ? Keys.Override : 0;
|
38
|
+
this.trigger(shift + override + event.which, event);
|
39
|
+
},
|
40
|
+
enterState: function(bindings){
|
41
|
+
var self = this;
|
42
|
+
this.off();
|
43
|
+
function addBinding(value, key) {
|
44
|
+
self.on(key, value);
|
45
|
+
}
|
46
|
+
_.each(bindings, addBinding);
|
47
|
+
},
|
48
|
+
close: function(){
|
49
|
+
$(window).off('keydown', this.onKeyDown);
|
50
|
+
this.off('all');
|
51
|
+
}
|
52
|
+
});
|
@@ -0,0 +1,60 @@
|
|
1
|
+
Stormfront.Layout = Stormfront.View.extend({
|
2
|
+
base: {
|
3
|
+
initializing: function(){
|
4
|
+
this._children = new Stormfront.Chaperone();
|
5
|
+
this.addPublisher(this._children, 'child');
|
6
|
+
},
|
7
|
+
rendering: function(){
|
8
|
+
_.each(this.children, this.composeChild, this);
|
9
|
+
},
|
10
|
+
closing: function(){
|
11
|
+
this._children.close();
|
12
|
+
},
|
13
|
+
child: {
|
14
|
+
created: function(child){
|
15
|
+
this._children.add(child);
|
16
|
+
},
|
17
|
+
added: function(child){
|
18
|
+
this.addPublisher(child);
|
19
|
+
this._children.render(child);
|
20
|
+
},
|
21
|
+
rendered: function(child){
|
22
|
+
var location = this.$('.' + child.getIdentity());
|
23
|
+
this._children.attach(child, location, 'replaceWith');
|
24
|
+
},
|
25
|
+
attached: function(child){
|
26
|
+
child.transition('rendered', child);
|
27
|
+
},
|
28
|
+
removed: function(child){
|
29
|
+
child.close();
|
30
|
+
this.stopListening(child);
|
31
|
+
},
|
32
|
+
error: function(error, innerException){
|
33
|
+
this.handleException(
|
34
|
+
new LayoutError(error, innerException)
|
35
|
+
);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
},
|
39
|
+
initialize: function(){
|
40
|
+
this.addSubscriber(this.base);
|
41
|
+
Stormfront.View.prototype.initialize.apply(this, arguments);
|
42
|
+
},
|
43
|
+
composeChild: function(childOptions, childClass){
|
44
|
+
this._children.create(childClass, childOptions, this);
|
45
|
+
},
|
46
|
+
findChild: function(identity){
|
47
|
+
return this._children.find(identity);
|
48
|
+
}
|
49
|
+
});
|
50
|
+
|
51
|
+
function LayoutError(message, innerException) {
|
52
|
+
var error = Error(message);
|
53
|
+
this.name = 'LayoutError';
|
54
|
+
this.message = error.message;
|
55
|
+
this.stack = error.stack;
|
56
|
+
this.innerException = innerException;
|
57
|
+
}
|
58
|
+
|
59
|
+
LayoutError.prototype = Object.create(Error.prototype);
|
60
|
+
LayoutError.prototype.constructor = LayoutError;
|
@@ -0,0 +1,123 @@
|
|
1
|
+
Stormfront.List = Stormfront.View.compose({
|
2
|
+
base: {
|
3
|
+
initializing: function(){
|
4
|
+
this.itemViews = {};
|
5
|
+
},
|
6
|
+
rendering: function(){
|
7
|
+
this.darkness = $('<div></div>').addClass('hidden');
|
8
|
+
this.getContent().after(this.darkness);
|
9
|
+
this.base.collection.sync.call(this);
|
10
|
+
},
|
11
|
+
collection: {
|
12
|
+
error: function(collection, xhr){
|
13
|
+
if (xhr.handled || xhr.status == 401)
|
14
|
+
return;
|
15
|
+
function requestAppearsAborted(xhr){
|
16
|
+
return xhr.readyState != 4;
|
17
|
+
}
|
18
|
+
if (requestAppearsAborted(xhr)){
|
19
|
+
xhr.handled = true;
|
20
|
+
console.warn('Request appears aborted', xhr);
|
21
|
+
} else {
|
22
|
+
try {
|
23
|
+
var message = JSON.parse(xhr.responseText);
|
24
|
+
var error = message.error || message.message;
|
25
|
+
this.alertUser(error);
|
26
|
+
xhr.handled = true;
|
27
|
+
}
|
28
|
+
catch(e) {
|
29
|
+
console.warn('Unhandled error', xhr, e);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
},
|
33
|
+
invalid: function(model, error){
|
34
|
+
this.alertUser(error);
|
35
|
+
},
|
36
|
+
add: function(model){
|
37
|
+
var options = this.getModel(model);
|
38
|
+
var type = this.getItemType();
|
39
|
+
var view = new type(options);
|
40
|
+
this.setView(model, view);
|
41
|
+
this.observeView(view);
|
42
|
+
this.appendContent(view.render().$el).and('item:rendered', view);
|
43
|
+
},
|
44
|
+
remove: function(model){
|
45
|
+
var view = this.getView(model);
|
46
|
+
this.removeView(view);
|
47
|
+
//Remove has a bug that causes sync not to happen
|
48
|
+
this.collection.trigger('sync', this.collection);
|
49
|
+
},
|
50
|
+
reset: function(){
|
51
|
+
this.each(this.removeView);
|
52
|
+
this.collection.each(this.base.collection.add, this);
|
53
|
+
//This is a handy re-use of other code paths
|
54
|
+
this.collection.trigger('sync', this.collection);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
},
|
58
|
+
initialize: function(options){
|
59
|
+
this.collection = options.collection;
|
60
|
+
this.register(this.collection, 'collection');
|
61
|
+
this.subscribe(this.base);
|
62
|
+
},
|
63
|
+
removeView: function(view){
|
64
|
+
this.stopListening(view);
|
65
|
+
view.close();
|
66
|
+
delete this.itemViews[view.model.cid];
|
67
|
+
this.trigger('item:removed', view);
|
68
|
+
},
|
69
|
+
observeView: function(view){
|
70
|
+
this.register(view, 'item');
|
71
|
+
this.forward(view);
|
72
|
+
},
|
73
|
+
|
74
|
+
getModel: function(model){
|
75
|
+
return { model: model };
|
76
|
+
},
|
77
|
+
getItemType: function(){
|
78
|
+
return this.itemView;
|
79
|
+
},
|
80
|
+
eject: function(){
|
81
|
+
this.getContent().children().appendTo(this.darkness);
|
82
|
+
},
|
83
|
+
|
84
|
+
alertUser: function(error){
|
85
|
+
this.alerts = this.alerts || [];
|
86
|
+
|
87
|
+
if (!_.contains(this.alerts, error)){
|
88
|
+
this.alerts.push(error);
|
89
|
+
alert(error);
|
90
|
+
this.alerts = _.without(this.alerts, error);
|
91
|
+
}
|
92
|
+
},
|
93
|
+
|
94
|
+
appendContent: function(el){
|
95
|
+
return new CollectionRenderContext(this).append(el);
|
96
|
+
},
|
97
|
+
getContent: function(other){
|
98
|
+
var selector = other ? '.collection > ' + other : '.collection';
|
99
|
+
return this.$(selector).first();
|
100
|
+
},
|
101
|
+
|
102
|
+
getView: function(model){
|
103
|
+
return this.itemViews[model.cid];
|
104
|
+
},
|
105
|
+
setView: function(model, view){
|
106
|
+
this.itemViews[model.cid] = view;
|
107
|
+
},
|
108
|
+
each: function(predicate){
|
109
|
+
_.each(this.itemViews, predicate, this);
|
110
|
+
}
|
111
|
+
});
|
112
|
+
|
113
|
+
var CollectionRenderContext = function(root){
|
114
|
+
this.append = function (el) {
|
115
|
+
root.getContent().append(el);
|
116
|
+
return this;
|
117
|
+
};
|
118
|
+
this.and = function(state) {
|
119
|
+
root.transition.apply(root, arguments);
|
120
|
+
return this;
|
121
|
+
};
|
122
|
+
return this;
|
123
|
+
};
|
@@ -0,0 +1,146 @@
|
|
1
|
+
MouseEvents = Stormfront.Class.extend({
|
2
|
+
initialize: function(options){
|
3
|
+
options = _.extend({delay: 175}, options);
|
4
|
+
this.delay = options.delay ? options.delay : 175;
|
5
|
+
this.public = _.clone(Backbone.Events);
|
6
|
+
this.internal = _.clone(Backbone.Events);
|
7
|
+
},
|
8
|
+
listen: function(target){
|
9
|
+
this.$el = target;
|
10
|
+
this.$el.global = $(document);
|
11
|
+
this.el = this.$el[0];
|
12
|
+
|
13
|
+
var self = this;
|
14
|
+
function enterStandardEventMode() {
|
15
|
+
self.$el.on('wheel.me', handleMouseWheel);
|
16
|
+
self.$el.on('mousewheel.me', handleMouseWheel);
|
17
|
+
self.$el.one('mousedown.me', handleFirstMouseDown);
|
18
|
+
|
19
|
+
function handleFirstMouseDown(eventArgs) {
|
20
|
+
self.$el.one('mousemove.me', enterDraggingMode);
|
21
|
+
|
22
|
+
self.$el.one('mousedown.me', handleSubsequentMouseDown);
|
23
|
+
self.internal.once("special:single-click:down", function() { handleSpecialMouseDown(eventArgs)});
|
24
|
+
self.$el.global.one('mouseup.me', handleFirstMouseUp);
|
25
|
+
delay("special:single-click:down", eventArgs);
|
26
|
+
}
|
27
|
+
|
28
|
+
function handleFirstMouseUp(eventArgs) {
|
29
|
+
self.$el.off('mousemove.me');
|
30
|
+
self.internal.once("special:single-click:up", function() { handleSpecialMouseUp(eventArgs); });
|
31
|
+
delay("special:single-click:up", eventArgs);
|
32
|
+
}
|
33
|
+
|
34
|
+
function delay(event, eventArgs){
|
35
|
+
setTimeout(function() { publishInternalEvent(event, eventArgs);}, self.delay);
|
36
|
+
}
|
37
|
+
|
38
|
+
function handleSpecialMouseDown(eventArgs) {
|
39
|
+
self.$el.off('mousedown.me');
|
40
|
+
self.$el.one('mousedown.me', handleFirstMouseDown);
|
41
|
+
publishExternalEvent("single-click:down", eventArgs);
|
42
|
+
}
|
43
|
+
|
44
|
+
function handleSpecialMouseUp(eventArgs) {
|
45
|
+
publishExternalEvent("single-click:up", eventArgs);
|
46
|
+
}
|
47
|
+
|
48
|
+
function handleSubsequentMouseDown(eventArgs) {
|
49
|
+
self.internal.off("special:single-click:down");
|
50
|
+
self.$el.one('mousedown.me', handleFirstMouseDown);
|
51
|
+
self.$el.global.one('mouseup.me', handleSubsequentMouseUp);
|
52
|
+
publishExternalEvent("double-click:down", eventArgs);
|
53
|
+
}
|
54
|
+
|
55
|
+
function handleSubsequentMouseUp(eventArgs) {
|
56
|
+
self.internal.off("special:single-click:up");
|
57
|
+
publishExternalEvent("double-click:up", eventArgs);
|
58
|
+
}
|
59
|
+
|
60
|
+
function handleMouseWheel(eventArgs) {
|
61
|
+
publishExternalEvent("mousewheel", eventArgs);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
function exitStandardEventMode() {
|
66
|
+
self.$el.off('mousedown.me');
|
67
|
+
self.$el.global.off('mouseup.me');
|
68
|
+
self.$el.off('mousemove.me');
|
69
|
+
self.$el.off('wheel.me');
|
70
|
+
self.$el.off('mousewheel.me');
|
71
|
+
self.internal.off("special:single-click:down");
|
72
|
+
self.internal.off("special:single-click:up");
|
73
|
+
}
|
74
|
+
|
75
|
+
function enterDraggingMode(eventArgs) {
|
76
|
+
function handleMouseMove(eventArgs) {
|
77
|
+
publishExternalEvent("dragging:move", eventArgs);
|
78
|
+
}
|
79
|
+
|
80
|
+
function handleMouseUp(eventArgs) {
|
81
|
+
publishExternalEvent("dragging:end", eventArgs);
|
82
|
+
exitDraggingMode();
|
83
|
+
enterStandardEventMode();
|
84
|
+
}
|
85
|
+
|
86
|
+
exitStandardEventMode();
|
87
|
+
publishExternalEvent("dragging:start", eventArgs);
|
88
|
+
self.$el.global.on('mousemove.me', handleMouseMove);
|
89
|
+
self.$el.global.one('mouseup.me', handleMouseUp);
|
90
|
+
}
|
91
|
+
|
92
|
+
function exitDraggingMode() {
|
93
|
+
self.$el.off('mouseup.me');
|
94
|
+
self.$el.global.off('mousemove.me');
|
95
|
+
self.$el.global.off('mousedown.me');
|
96
|
+
}
|
97
|
+
|
98
|
+
function disableUnsupportedEvents() {
|
99
|
+
self.$el.global.on('selectstart.me', function(eventArgs) {
|
100
|
+
eventArgs.preventDefault();
|
101
|
+
eventArgs.stopPropagation();
|
102
|
+
return false; });
|
103
|
+
self.$el.on("contextmenu.me", function(eventArgs) {
|
104
|
+
eventArgs.preventDefault();
|
105
|
+
eventArgs.stopPropagation();
|
106
|
+
return false; });
|
107
|
+
}
|
108
|
+
|
109
|
+
function publishInternalEvent(event, eventArgs){
|
110
|
+
publishEvent(self.internal, event, eventArgs);
|
111
|
+
}
|
112
|
+
function publishExternalEvent(event, eventArgs){
|
113
|
+
publishEvent(self.public, event, eventArgs);
|
114
|
+
}
|
115
|
+
function publishEvent(publisher, event, eventArgs){
|
116
|
+
function getMousePosition(eventArgs) {
|
117
|
+
var offset = self.$el.offset();
|
118
|
+
var relativeX = eventArgs.originalEvent.pageX - offset.left;
|
119
|
+
var relativeY = eventArgs.originalEvent.pageY - offset.top;
|
120
|
+
eventArgs.preventDefault();
|
121
|
+
eventArgs.stopPropagation();
|
122
|
+
return {
|
123
|
+
x: relativeX,
|
124
|
+
y: relativeY
|
125
|
+
};
|
126
|
+
}
|
127
|
+
var position = getMousePosition(eventArgs);
|
128
|
+
publisher.trigger(event, position, eventArgs.originalEvent);
|
129
|
+
}
|
130
|
+
|
131
|
+
enterStandardEventMode();
|
132
|
+
disableUnsupportedEvents();
|
133
|
+
},
|
134
|
+
on: function(event, callback){
|
135
|
+
this.public.on(event, callback);
|
136
|
+
return this;
|
137
|
+
},
|
138
|
+
off: function(event ,callback){
|
139
|
+
this.public.off(event, callback);
|
140
|
+
return this;
|
141
|
+
},
|
142
|
+
stopListening: function(){
|
143
|
+
this.$el && this.$el.off('.me');
|
144
|
+
this.$el.global && this.$el.global.off('.me');
|
145
|
+
}
|
146
|
+
});
|