stormfront-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +31 -0
  6. data/Rakefile +2 -0
  7. data/lib/stormfront/rails/version.rb +5 -0
  8. data/lib/stormfront/rails.rb +7 -0
  9. data/stormfront-rails.gemspec +22 -0
  10. data/vendor/assets/javascripts/stormfront/Alert.js +17 -0
  11. data/vendor/assets/javascripts/stormfront/Container.js +31 -0
  12. data/vendor/assets/javascripts/stormfront/Entity.js +53 -0
  13. data/vendor/assets/javascripts/stormfront/Errors.js +25 -0
  14. data/vendor/assets/javascripts/stormfront/KeyboardEvents.js +52 -0
  15. data/vendor/assets/javascripts/stormfront/Layout.js +60 -0
  16. data/vendor/assets/javascripts/stormfront/List.js +123 -0
  17. data/vendor/assets/javascripts/stormfront/MouseEvents.js +146 -0
  18. data/vendor/assets/javascripts/stormfront/Namespaces.js +5 -0
  19. data/vendor/assets/javascripts/stormfront/Overlay.js +178 -0
  20. data/vendor/assets/javascripts/stormfront/Reducer.js +9 -0
  21. data/vendor/assets/javascripts/stormfront/Request.js +39 -0
  22. data/vendor/assets/javascripts/stormfront/View.js +55 -0
  23. data/vendor/assets/javascripts/stormfront/ViewBase.js +57 -0
  24. data/vendor/assets/javascripts/stormfront/mixin/Dispatch.js +19 -0
  25. data/vendor/assets/javascripts/stormfront/mixin/Other.js +25 -0
  26. data/vendor/assets/javascripts/stormfront/support/Chaperone.js +69 -0
  27. data/vendor/assets/javascripts/stormfront/support/Template.js +75 -0
  28. data/vendor/assets/javascripts/stormfront/types/Arguments.js +27 -0
  29. data/vendor/assets/javascripts/stormfront/types/Class.js +25 -0
  30. data/vendor/assets/javascripts/stormfront/types/Hash.js +23 -0
  31. data/vendor/assets/javascripts/stormfront/types/Number.js +15 -0
  32. data/vendor/assets/javascripts/stormfront/types/Response.js +31 -0
  33. data/vendor/assets/javascripts/stormfront/types/String.js +44 -0
  34. data/vendor/assets/javascripts/stormfront/types/Time.js +29 -0
  35. data/vendor/assets/javascripts/stormfront.js +33 -0
  36. 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
@@ -0,0 +1,15 @@
1
+ .idea/*
2
+ /.bundle/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in stormfront-rails.gemspec
4
+ gemspec
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,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,5 @@
1
+ module Stormfront
2
+ module Rails
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'stormfront/rails/version'
2
+
3
+ module Stormfront
4
+ module Rails
5
+ class Engine < ::Rails::Engine; end
6
+ end
7
+ end
@@ -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
+ });
@@ -0,0 +1,5 @@
1
+ stormfront = { };
2
+
3
+ Stormfront = {
4
+ Mixin: { }
5
+ };