flashtastic 0.0.1
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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +98 -0
- data/Rakefile +1 -0
- data/flashtastic.gemspec +23 -0
- data/lib/flashtastic.rb +21 -0
- data/lib/flashtastic/version.rb +3 -0
- data/lib/generators/flashtastic/install/install_generator.rb +40 -0
- data/lib/generators/flashtastic/install/templates/flashtastic_initializer.js.coffee +74 -0
- data/vendor/assets/javascripts/messenger-theme-flat.js +33 -0
- data/vendor/assets/javascripts/messenger-theme-future.js +33 -0
- data/vendor/assets/javascripts/messenger.js +1228 -0
- data/vendor/assets/javascripts/messenger.min.js +2 -0
- data/vendor/assets/stylesheets/messenger-spinner.css +235 -0
- data/vendor/assets/stylesheets/messenger-theme-air.css +443 -0
- data/vendor/assets/stylesheets/messenger-theme-block.css +96 -0
- data/vendor/assets/stylesheets/messenger-theme-flat.css +462 -0
- data/vendor/assets/stylesheets/messenger-theme-future.css +496 -0
- data/vendor/assets/stylesheets/messenger-theme-ice.css +118 -0
- data/vendor/assets/stylesheets/messenger.css +93 -0
- metadata +100 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Amit Gaur
|
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,98 @@
|
|
1
|
+
# Flashtastic
|
2
|
+
|
3
|
+
Flashtastic is a Rails (3.1 and above) gem that replaces rails flash messages with [Messenger](http://github.hubspot.com/messenger/) (Version 1.3.6) javascript library for notifications.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
* Adds Messenger js and css into your asset pipeline
|
8
|
+
* Out of the box integration with rails flash messages
|
9
|
+
* Works for ajax requests
|
10
|
+
* Adds a default notification handler for ajax errors
|
11
|
+
|
12
|
+
## About Messenger
|
13
|
+
|
14
|
+
- Show transactional messages in your app.
|
15
|
+
- Wrap AJAX requests with progress, success and error messages, and add retry to your failed requests.
|
16
|
+
- Add actions (undo, cancel, etc.) to your messages.
|
17
|
+
- 4kb minified and compressed.
|
18
|
+
- Works in everything modern, and IE7 and above.
|
19
|
+
|
20
|
+
<a href="http://hubspot.github.com/messenger">
|
21
|
+
<img src="https://raw.github.com/HubSpot/messenger/master/promotional-images/messenger.gif" title="Thanks for checking out Messenger!" style="max-width: 100%;padding:30px;"/>
|
22
|
+
</a>
|
23
|
+
|
24
|
+
[Demo and Usage of Messenger](http://hubspot.github.com/messenger)
|
25
|
+
|
26
|
+
## Requirement/Dependency:
|
27
|
+
|
28
|
+
1. jQuery
|
29
|
+
|
30
|
+
2. Plays well with, but doesn't require, Bootstrap
|
31
|
+
|
32
|
+
## Installation
|
33
|
+
|
34
|
+
Add this line to your application's Gemfile:
|
35
|
+
|
36
|
+
gem 'flashtastic'
|
37
|
+
|
38
|
+
And then execute:
|
39
|
+
|
40
|
+
$ bundle
|
41
|
+
|
42
|
+
Or install it yourself as:
|
43
|
+
|
44
|
+
$ gem install flashtastic
|
45
|
+
|
46
|
+
After gem installation do:
|
47
|
+
|
48
|
+
$ rails g flashtastic:install
|
49
|
+
|
50
|
+
Thats it!
|
51
|
+
|
52
|
+
## Alternative Manual Installation
|
53
|
+
After installing the gem, if you don't want to run `rails g flashtastic:install`, do the following:
|
54
|
+
|
55
|
+
Copy the following coffeescript file in your assets:
|
56
|
+
|
57
|
+
[flashtastic_initializer.js.coffee](https://github.com/websymphony/flashtastic/blob/master/lib/generators/flashtastic/install/templates/flashtastic_initializer.js.coffee)
|
58
|
+
|
59
|
+
Add the following directive to your application.coffee / application.js.
|
60
|
+
|
61
|
+
//= require messenger
|
62
|
+
//= require messenger-theme-flat
|
63
|
+
//= require flashtastic_initializer // This will add integration with rails flash messages.
|
64
|
+
|
65
|
+
Add the following directive to your application.scss / application.css.
|
66
|
+
There are Five themes/styles provided (flat, future, air, block and ice), change required stylesheet as needed.
|
67
|
+
|
68
|
+
*= require messenger
|
69
|
+
*= require messenger-spinner
|
70
|
+
*= require messenger-theme-flat
|
71
|
+
|
72
|
+
Include Flashtastic module in Application controller
|
73
|
+
|
74
|
+
include Flashtastic
|
75
|
+
|
76
|
+
Thats it!
|
77
|
+
|
78
|
+
## Usage
|
79
|
+
|
80
|
+
If you have included [flashtastic_initializer.js.coffee](https://github.com/websymphony/flashtastic/blob/master/lib/generators/flashtastic/install/templates/flashtastic_initializer.js.coffee) in your assets, your regular rails flash messages will show up as messenger messages. Even for ajax requests.
|
81
|
+
|
82
|
+
Modify [flashtastic_initializer.js.coffee](https://github.com/websymphony/flashtastic/blob/master/lib/generators/flashtastic/install/templates/flashtastic_initializer.js.coffee) as needed.
|
83
|
+
|
84
|
+
[Demo and Usage of Messenger](http://hubspot.github.com/messenger)
|
85
|
+
|
86
|
+
## Contributing
|
87
|
+
|
88
|
+
1. Fork it
|
89
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
90
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
91
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
92
|
+
5. Create new Pull Request
|
93
|
+
|
94
|
+
## Author
|
95
|
+
**Amit Gaur**
|
96
|
+
|
97
|
+
+ [http://websymphony.net](http://websymphony.net)
|
98
|
+
+ [http://twitter.com/websymphony](http://twitter.com/websymphony)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/flashtastic.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'flashtastic/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "flashtastic"
|
8
|
+
spec.version = Flashtastic::VERSION
|
9
|
+
spec.authors = ["Amit Gaur"]
|
10
|
+
spec.email = ["amitgaur.web@gmail.com"]
|
11
|
+
spec.description = %q{Adds Hubspot Messenger js and css into your asset pipeline. Integrates seamlessly with rails flash messages, even for ajax requests.}
|
12
|
+
spec.summary = %q{Hubspot Messenger for Rails Flash Messages}
|
13
|
+
spec.homepage = "https://github.com/websymphony/flashtastic/"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
data/lib/flashtastic.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "flashtastic/version"
|
2
|
+
|
3
|
+
module Flashtastic
|
4
|
+
class Engine < ::Rails::Engine
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.after_filter :flash_to_cookie
|
9
|
+
end
|
10
|
+
|
11
|
+
def flash_to_cookie
|
12
|
+
cookies.delete :flashtastic_cookie #starting with clean slate on each request.
|
13
|
+
flash_json = Hash[flash.map{|k,v| [k,ERB::Util.h(v)] }].to_json
|
14
|
+
cookies[:flashtastic_cookie] = {
|
15
|
+
:value => flash_json,
|
16
|
+
:expires => 1.year.from_now
|
17
|
+
}
|
18
|
+
flash.discard
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Flashtastic
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
def copy_flashtastic_initializer
|
7
|
+
say_status("copying", "flashtastic_initializer.js.coffee file to your assets directory", :green)
|
8
|
+
copy_file "flashtastic_initializer.js.coffee", "app/assets/javascripts/flashtastic_initializer.js.coffee"
|
9
|
+
end
|
10
|
+
|
11
|
+
def include_flashtastic_module_in_application_controller
|
12
|
+
say_status("inserting", "Flashtastic module in your ApplicationController ", :green)
|
13
|
+
inject_into_class "app/controllers/application_controller.rb", ApplicationController, " include Flashtastic\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
def include_messenger_js_references
|
17
|
+
say_status("inserting", "messenger js references in your application.js ", :green)
|
18
|
+
insert_into_file "app/assets/javascripts/application.js", :after => "//= require jquery\n" do
|
19
|
+
<<-JS
|
20
|
+
//= require messenger
|
21
|
+
//= require messenger-theme-flat
|
22
|
+
//= require flashtastic_initializer
|
23
|
+
JS
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def include_messenger_css_references
|
28
|
+
say_status("inserting", "messenger css references in your application.css ", :green)
|
29
|
+
insert_into_file "app/assets/stylesheets/application.css", :after => "*= require_self\n" do
|
30
|
+
<<-CSS
|
31
|
+
*= require messenger
|
32
|
+
*= require messenger-spinner
|
33
|
+
*= require messenger-theme-flat
|
34
|
+
CSS
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Global Options for Messenger Plugin
|
2
|
+
Messenger.options = {
|
3
|
+
extraClasses: 'messenger-fixed messenger-on-top messenger-on-right', # define the position of notification
|
4
|
+
theme: 'flat' # define styles here
|
5
|
+
}
|
6
|
+
|
7
|
+
$(document).on
|
8
|
+
ready: (e) -> # This handles non ajax flash messages
|
9
|
+
Flashtastic().showFlashMessage()
|
10
|
+
|
11
|
+
ajaxSuccess: (e, r) -> # This handles ajax flash messages
|
12
|
+
Flashtastic().showFlashMessage()
|
13
|
+
|
14
|
+
ajaxError: (e) -> # This handles ajax errors
|
15
|
+
opts = {
|
16
|
+
# Catch All message for all ajax errors. Feel Free to customize.
|
17
|
+
message: "There was an error while processing your request. Please try reloading the page."
|
18
|
+
type: "error"
|
19
|
+
}
|
20
|
+
Flashtastic().showFlashMessage(opts)
|
21
|
+
|
22
|
+
|
23
|
+
#==================================================
|
24
|
+
# Flashtastic script that handles Rails flash messages
|
25
|
+
#==================================================
|
26
|
+
|
27
|
+
do window.Flashtastic = ->
|
28
|
+
|
29
|
+
# private
|
30
|
+
# This function reads the cookie. duh!
|
31
|
+
readCookie = (name, c, C, i) ->
|
32
|
+
return cookies[name] if cookies
|
33
|
+
c = document.cookie.split("; ")
|
34
|
+
cookies = {}
|
35
|
+
i = c.length - 1
|
36
|
+
while i >= 0
|
37
|
+
C = c[i].split("=")
|
38
|
+
cookies[C[0]] = C[1]
|
39
|
+
i--
|
40
|
+
cookies[name]
|
41
|
+
|
42
|
+
# private
|
43
|
+
# This function deletes the cookie. duh!
|
44
|
+
deleteCookie = (name) ->
|
45
|
+
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
46
|
+
|
47
|
+
# private
|
48
|
+
# This function cleans up junk from message.
|
49
|
+
cleanUpMessage = (msg) ->
|
50
|
+
msg.replace(/\+/g,' ')
|
51
|
+
|
52
|
+
# private
|
53
|
+
# This function uses cookie info
|
54
|
+
# and constructs Messenger post
|
55
|
+
flashMessageHandler = (opts) ->
|
56
|
+
if opts?
|
57
|
+
Messenger().post
|
58
|
+
type: opts['type']
|
59
|
+
message: opts['message']
|
60
|
+
hideAfter: 3
|
61
|
+
showCloseButton: true
|
62
|
+
else
|
63
|
+
flash_hash = $.parseJSON(decodeURIComponent(readCookie("flashtastic_cookie")))
|
64
|
+
deleteCookie('flashtastic_cookie')
|
65
|
+
if flash_hash
|
66
|
+
$.each flash_hash, (type, msg) ->
|
67
|
+
Messenger().post
|
68
|
+
type: type
|
69
|
+
message: cleanUpMessage(msg)
|
70
|
+
hideAfter: 3
|
71
|
+
showCloseButton: true
|
72
|
+
|
73
|
+
|
74
|
+
showFlashMessage: flashMessageHandler # exposed it for public consumption
|
@@ -0,0 +1,33 @@
|
|
1
|
+
(function() {
|
2
|
+
var $, FlatMessage, spinner_template,
|
3
|
+
__hasProp = {}.hasOwnProperty,
|
4
|
+
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
5
|
+
|
6
|
+
$ = jQuery;
|
7
|
+
|
8
|
+
spinner_template = '<div class="messenger-spinner">\n <span class="messenger-spinner-side messenger-spinner-side-left">\n <span class="messenger-spinner-fill"></span>\n </span>\n <span class="messenger-spinner-side messenger-spinner-side-right">\n <span class="messenger-spinner-fill"></span>\n </span>\n</div>';
|
9
|
+
|
10
|
+
FlatMessage = (function(_super) {
|
11
|
+
|
12
|
+
__extends(FlatMessage, _super);
|
13
|
+
|
14
|
+
function FlatMessage() {
|
15
|
+
return FlatMessage.__super__.constructor.apply(this, arguments);
|
16
|
+
}
|
17
|
+
|
18
|
+
FlatMessage.prototype.template = function(opts) {
|
19
|
+
var $message;
|
20
|
+
$message = FlatMessage.__super__.template.apply(this, arguments);
|
21
|
+
$message.append($(spinner_template));
|
22
|
+
return $message;
|
23
|
+
};
|
24
|
+
|
25
|
+
return FlatMessage;
|
26
|
+
|
27
|
+
})(window.Messenger.Message);
|
28
|
+
|
29
|
+
window.Messenger.themes.flat = {
|
30
|
+
Message: FlatMessage
|
31
|
+
};
|
32
|
+
|
33
|
+
}).call(this);
|
@@ -0,0 +1,33 @@
|
|
1
|
+
(function() {
|
2
|
+
var $, FutureMessage, spinner_template,
|
3
|
+
__hasProp = {}.hasOwnProperty,
|
4
|
+
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
5
|
+
|
6
|
+
$ = jQuery;
|
7
|
+
|
8
|
+
spinner_template = '<div class="messenger-spinner">\n <span class="messenger-spinner-side messenger-spinner-side-left">\n <span class="messenger-spinner-fill"></span>\n </span>\n <span class="messenger-spinner-side messenger-spinner-side-right">\n <span class="messenger-spinner-fill"></span>\n </span>\n</div>';
|
9
|
+
|
10
|
+
FutureMessage = (function(_super) {
|
11
|
+
|
12
|
+
__extends(FutureMessage, _super);
|
13
|
+
|
14
|
+
function FutureMessage() {
|
15
|
+
return FutureMessage.__super__.constructor.apply(this, arguments);
|
16
|
+
}
|
17
|
+
|
18
|
+
FutureMessage.prototype.template = function(opts) {
|
19
|
+
var $message;
|
20
|
+
$message = FutureMessage.__super__.template.apply(this, arguments);
|
21
|
+
$message.append($(spinner_template));
|
22
|
+
return $message;
|
23
|
+
};
|
24
|
+
|
25
|
+
return FutureMessage;
|
26
|
+
|
27
|
+
})(window.Messenger.Message);
|
28
|
+
|
29
|
+
window.Messenger.themes.future = {
|
30
|
+
Message: FutureMessage
|
31
|
+
};
|
32
|
+
|
33
|
+
}).call(this);
|
@@ -0,0 +1,1228 @@
|
|
1
|
+
/*! messenger 1.3.6 */
|
2
|
+
/*
|
3
|
+
* This file begins the output concatenated into messenger.js
|
4
|
+
*
|
5
|
+
* It establishes the Messenger object while preserving whatever it was before
|
6
|
+
* (for noConflict), and making it a callable function.
|
7
|
+
*/
|
8
|
+
|
9
|
+
(function(){
|
10
|
+
var _prevMessenger = window.Messenger;
|
11
|
+
var localMessenger;
|
12
|
+
|
13
|
+
localMessenger = window.Messenger = function(){
|
14
|
+
return localMessenger._call.apply(this, arguments);
|
15
|
+
}
|
16
|
+
|
17
|
+
window.Messenger.noConflict = function(){
|
18
|
+
window.Messenger = _prevMessenger;
|
19
|
+
|
20
|
+
return localMessenger;
|
21
|
+
}
|
22
|
+
})();
|
23
|
+
|
24
|
+
/*
|
25
|
+
* This file contains shims for when Underscore and Backbone
|
26
|
+
* are not included.
|
27
|
+
*
|
28
|
+
* Portions taken from Underscore.js and Backbone.js
|
29
|
+
* Both of which are Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud
|
30
|
+
*/
|
31
|
+
window.Messenger._ = (function() {
|
32
|
+
if (window._)
|
33
|
+
return window._
|
34
|
+
|
35
|
+
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
36
|
+
|
37
|
+
// Create quick reference variables for speed access to core prototypes.
|
38
|
+
var push = ArrayProto.push,
|
39
|
+
slice = ArrayProto.slice,
|
40
|
+
concat = ArrayProto.concat,
|
41
|
+
toString = ObjProto.toString,
|
42
|
+
hasOwnProperty = ObjProto.hasOwnProperty;
|
43
|
+
|
44
|
+
// All **ECMAScript 5** native function implementations that we hope to use
|
45
|
+
// are declared here.
|
46
|
+
var
|
47
|
+
nativeForEach = ArrayProto.forEach,
|
48
|
+
nativeMap = ArrayProto.map,
|
49
|
+
nativeReduce = ArrayProto.reduce,
|
50
|
+
nativeReduceRight = ArrayProto.reduceRight,
|
51
|
+
nativeFilter = ArrayProto.filter,
|
52
|
+
nativeEvery = ArrayProto.every,
|
53
|
+
nativeSome = ArrayProto.some,
|
54
|
+
nativeIndexOf = ArrayProto.indexOf,
|
55
|
+
nativeLastIndexOf = ArrayProto.lastIndexOf,
|
56
|
+
nativeIsArray = Array.isArray,
|
57
|
+
nativeKeys = Object.keys,
|
58
|
+
nativeBind = FuncProto.bind;
|
59
|
+
|
60
|
+
// Create a safe reference to the Underscore object for use below.
|
61
|
+
var _ = {};
|
62
|
+
|
63
|
+
// Establish the object that gets returned to break out of a loop iteration.
|
64
|
+
var breaker = {};
|
65
|
+
|
66
|
+
var each = _.each = _.forEach = function(obj, iterator, context) {
|
67
|
+
if (obj == null) return;
|
68
|
+
if (nativeForEach && obj.forEach === nativeForEach) {
|
69
|
+
obj.forEach(iterator, context);
|
70
|
+
} else if (obj.length === +obj.length) {
|
71
|
+
for (var i = 0, l = obj.length; i < l; i++) {
|
72
|
+
if (iterator.call(context, obj[i], i, obj) === breaker) return;
|
73
|
+
}
|
74
|
+
} else {
|
75
|
+
for (var key in obj) {
|
76
|
+
if (_.has(obj, key)) {
|
77
|
+
if (iterator.call(context, obj[key], key, obj) === breaker) return;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
};
|
82
|
+
|
83
|
+
_.result = function(object, property) {
|
84
|
+
if (object == null) return null;
|
85
|
+
var value = object[property];
|
86
|
+
return _.isFunction(value) ? value.call(object) : value;
|
87
|
+
};
|
88
|
+
|
89
|
+
_.once = function(func) {
|
90
|
+
var ran = false, memo;
|
91
|
+
return function() {
|
92
|
+
if (ran) return memo;
|
93
|
+
ran = true;
|
94
|
+
memo = func.apply(this, arguments);
|
95
|
+
func = null;
|
96
|
+
return memo;
|
97
|
+
};
|
98
|
+
};
|
99
|
+
|
100
|
+
var idCounter = 0;
|
101
|
+
_.uniqueId = function(prefix) {
|
102
|
+
var id = ++idCounter + '';
|
103
|
+
return prefix ? prefix + id : id;
|
104
|
+
};
|
105
|
+
|
106
|
+
_.filter = _.select = function(obj, iterator, context) {
|
107
|
+
var results = [];
|
108
|
+
if (obj == null) return results;
|
109
|
+
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
|
110
|
+
each(obj, function(value, index, list) {
|
111
|
+
if (iterator.call(context, value, index, list)) results[results.length] = value;
|
112
|
+
});
|
113
|
+
return results;
|
114
|
+
};
|
115
|
+
|
116
|
+
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
|
117
|
+
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
|
118
|
+
_['is' + name] = function(obj) {
|
119
|
+
return toString.call(obj) == '[object ' + name + ']';
|
120
|
+
};
|
121
|
+
});
|
122
|
+
|
123
|
+
_.defaults = function(obj) {
|
124
|
+
each(slice.call(arguments, 1), function(source) {
|
125
|
+
if (source) {
|
126
|
+
for (var prop in source) {
|
127
|
+
if (obj[prop] == null) obj[prop] = source[prop];
|
128
|
+
}
|
129
|
+
}
|
130
|
+
});
|
131
|
+
return obj;
|
132
|
+
};
|
133
|
+
|
134
|
+
_.extend = function(obj) {
|
135
|
+
each(slice.call(arguments, 1), function(source) {
|
136
|
+
if (source) {
|
137
|
+
for (var prop in source) {
|
138
|
+
obj[prop] = source[prop];
|
139
|
+
}
|
140
|
+
}
|
141
|
+
});
|
142
|
+
return obj;
|
143
|
+
};
|
144
|
+
|
145
|
+
_.keys = nativeKeys || function(obj) {
|
146
|
+
if (obj !== Object(obj)) throw new TypeError('Invalid object');
|
147
|
+
var keys = [];
|
148
|
+
for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
|
149
|
+
return keys;
|
150
|
+
};
|
151
|
+
|
152
|
+
_.bind = function(func, context) {
|
153
|
+
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
154
|
+
var args = slice.call(arguments, 2);
|
155
|
+
return function() {
|
156
|
+
return func.apply(context, args.concat(slice.call(arguments)));
|
157
|
+
};
|
158
|
+
};
|
159
|
+
|
160
|
+
_.isObject = function(obj) {
|
161
|
+
return obj === Object(obj);
|
162
|
+
};
|
163
|
+
|
164
|
+
return _;
|
165
|
+
})();
|
166
|
+
|
167
|
+
window.Messenger.Events = (function() {
|
168
|
+
if (window.Backbone && Backbone.Events) {
|
169
|
+
return Backbone.Events;
|
170
|
+
}
|
171
|
+
|
172
|
+
var eventsShim = function() {
|
173
|
+
var eventSplitter = /\s+/;
|
174
|
+
|
175
|
+
var eventsApi = function(obj, action, name, rest) {
|
176
|
+
if (!name) return true;
|
177
|
+
if (typeof name === 'object') {
|
178
|
+
for (var key in name) {
|
179
|
+
obj[action].apply(obj, [key, name[key]].concat(rest));
|
180
|
+
}
|
181
|
+
} else if (eventSplitter.test(name)) {
|
182
|
+
var names = name.split(eventSplitter);
|
183
|
+
for (var i = 0, l = names.length; i < l; i++) {
|
184
|
+
obj[action].apply(obj, [names[i]].concat(rest));
|
185
|
+
}
|
186
|
+
} else {
|
187
|
+
return true;
|
188
|
+
}
|
189
|
+
};
|
190
|
+
|
191
|
+
var triggerEvents = function(events, args) {
|
192
|
+
var ev, i = -1, l = events.length;
|
193
|
+
switch (args.length) {
|
194
|
+
case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx);
|
195
|
+
return;
|
196
|
+
case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0]);
|
197
|
+
return;
|
198
|
+
case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1]);
|
199
|
+
return;
|
200
|
+
case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1], args[2]);
|
201
|
+
return;
|
202
|
+
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
|
203
|
+
}
|
204
|
+
};
|
205
|
+
|
206
|
+
var Events = {
|
207
|
+
|
208
|
+
on: function(name, callback, context) {
|
209
|
+
if (!(eventsApi(this, 'on', name, [callback, context]) && callback)) return this;
|
210
|
+
this._events || (this._events = {});
|
211
|
+
var list = this._events[name] || (this._events[name] = []);
|
212
|
+
list.push({callback: callback, context: context, ctx: context || this});
|
213
|
+
return this;
|
214
|
+
},
|
215
|
+
|
216
|
+
once: function(name, callback, context) {
|
217
|
+
if (!(eventsApi(this, 'once', name, [callback, context]) && callback)) return this;
|
218
|
+
var self = this;
|
219
|
+
var once = _.once(function() {
|
220
|
+
self.off(name, once);
|
221
|
+
callback.apply(this, arguments);
|
222
|
+
});
|
223
|
+
once._callback = callback;
|
224
|
+
this.on(name, once, context);
|
225
|
+
return this;
|
226
|
+
},
|
227
|
+
|
228
|
+
off: function(name, callback, context) {
|
229
|
+
var list, ev, events, names, i, l, j, k;
|
230
|
+
if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
|
231
|
+
if (!name && !callback && !context) {
|
232
|
+
this._events = {};
|
233
|
+
return this;
|
234
|
+
}
|
235
|
+
|
236
|
+
names = name ? [name] : _.keys(this._events);
|
237
|
+
for (i = 0, l = names.length; i < l; i++) {
|
238
|
+
name = names[i];
|
239
|
+
if (list = this._events[name]) {
|
240
|
+
events = [];
|
241
|
+
if (callback || context) {
|
242
|
+
for (j = 0, k = list.length; j < k; j++) {
|
243
|
+
ev = list[j];
|
244
|
+
if ((callback && callback !== ev.callback &&
|
245
|
+
callback !== ev.callback._callback) ||
|
246
|
+
(context && context !== ev.context)) {
|
247
|
+
events.push(ev);
|
248
|
+
}
|
249
|
+
}
|
250
|
+
}
|
251
|
+
this._events[name] = events;
|
252
|
+
}
|
253
|
+
}
|
254
|
+
|
255
|
+
return this;
|
256
|
+
},
|
257
|
+
|
258
|
+
trigger: function(name) {
|
259
|
+
if (!this._events) return this;
|
260
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
261
|
+
if (!eventsApi(this, 'trigger', name, args)) return this;
|
262
|
+
var events = this._events[name];
|
263
|
+
var allEvents = this._events.all;
|
264
|
+
if (events) triggerEvents(events, args);
|
265
|
+
if (allEvents) triggerEvents(allEvents, arguments);
|
266
|
+
return this;
|
267
|
+
},
|
268
|
+
|
269
|
+
listenTo: function(obj, name, callback) {
|
270
|
+
var listeners = this._listeners || (this._listeners = {});
|
271
|
+
var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
|
272
|
+
listeners[id] = obj;
|
273
|
+
obj.on(name, typeof name === 'object' ? this : callback, this);
|
274
|
+
return this;
|
275
|
+
},
|
276
|
+
|
277
|
+
stopListening: function(obj, name, callback) {
|
278
|
+
var listeners = this._listeners;
|
279
|
+
if (!listeners) return;
|
280
|
+
if (obj) {
|
281
|
+
obj.off(name, typeof name === 'object' ? this : callback, this);
|
282
|
+
if (!name && !callback) delete listeners[obj._listenerId];
|
283
|
+
} else {
|
284
|
+
if (typeof name === 'object') callback = this;
|
285
|
+
for (var id in listeners) {
|
286
|
+
listeners[id].off(name, callback, this);
|
287
|
+
}
|
288
|
+
this._listeners = {};
|
289
|
+
}
|
290
|
+
return this;
|
291
|
+
}
|
292
|
+
};
|
293
|
+
|
294
|
+
Events.bind = Events.on;
|
295
|
+
Events.unbind = Events.off;
|
296
|
+
return Events;
|
297
|
+
};
|
298
|
+
return eventsShim();
|
299
|
+
})();
|
300
|
+
|
301
|
+
(function() {
|
302
|
+
var $, ActionMessenger, BaseView, Events, RetryingMessage, _, _Message, _Messenger, _ref, _ref1, _ref2,
|
303
|
+
__hasProp = {}.hasOwnProperty,
|
304
|
+
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
305
|
+
__slice = [].slice,
|
306
|
+
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
307
|
+
|
308
|
+
$ = jQuery;
|
309
|
+
|
310
|
+
_ = (_ref = window._) != null ? _ref : window.Messenger._;
|
311
|
+
|
312
|
+
Events = (_ref1 = typeof Backbone !== "undefined" && Backbone !== null ? Backbone.Events : void 0) != null ? _ref1 : window.Messenger.Events;
|
313
|
+
|
314
|
+
BaseView = (function() {
|
315
|
+
|
316
|
+
function BaseView(options) {
|
317
|
+
$.extend(this, Events);
|
318
|
+
if (_.isObject(options)) {
|
319
|
+
if (options.el) {
|
320
|
+
this.setElement(options.el);
|
321
|
+
}
|
322
|
+
this.model = options.model;
|
323
|
+
}
|
324
|
+
this.initialize.apply(this, arguments);
|
325
|
+
}
|
326
|
+
|
327
|
+
BaseView.prototype.setElement = function(el) {
|
328
|
+
this.$el = $(el);
|
329
|
+
return this.el = this.$el[0];
|
330
|
+
};
|
331
|
+
|
332
|
+
BaseView.prototype.delegateEvents = function(events) {
|
333
|
+
var delegateEventSplitter, eventName, key, match, method, selector, _results;
|
334
|
+
if (!(events || (events = _.result(this, 'events')))) {
|
335
|
+
return;
|
336
|
+
}
|
337
|
+
delegateEventSplitter = /^(\S+)\s*(.*)$/;
|
338
|
+
this.undelegateEvents();
|
339
|
+
_results = [];
|
340
|
+
for (key in events) {
|
341
|
+
method = events[key];
|
342
|
+
if (!_.isFunction(method)) {
|
343
|
+
method = this[events[key]];
|
344
|
+
}
|
345
|
+
if (!method) {
|
346
|
+
throw new Error("Method " + events[key] + " does not exist");
|
347
|
+
}
|
348
|
+
match = key.match(delegateEventSplitter);
|
349
|
+
eventName = match[1];
|
350
|
+
selector = match[2];
|
351
|
+
method = _.bind(method, this);
|
352
|
+
eventName += ".delegateEvents" + this.cid;
|
353
|
+
if (selector === '') {
|
354
|
+
_results.push(this.jqon(eventName, method));
|
355
|
+
} else {
|
356
|
+
_results.push(this.jqon(eventName, selector, method));
|
357
|
+
}
|
358
|
+
}
|
359
|
+
return _results;
|
360
|
+
};
|
361
|
+
|
362
|
+
BaseView.prototype.jqon = function(eventName, selector, method) {
|
363
|
+
var _ref2;
|
364
|
+
if (this.$el.on != null) {
|
365
|
+
return (_ref2 = this.$el).on.apply(_ref2, arguments);
|
366
|
+
} else {
|
367
|
+
if (!(method != null)) {
|
368
|
+
method = selector;
|
369
|
+
selector = void 0;
|
370
|
+
}
|
371
|
+
if (selector != null) {
|
372
|
+
return this.$el.delegate(selector, eventName, method);
|
373
|
+
} else {
|
374
|
+
return this.$el.bind(eventName, method);
|
375
|
+
}
|
376
|
+
}
|
377
|
+
};
|
378
|
+
|
379
|
+
BaseView.prototype.jqoff = function(eventName) {
|
380
|
+
var _ref2;
|
381
|
+
if (this.$el.off != null) {
|
382
|
+
return (_ref2 = this.$el).off.apply(_ref2, arguments);
|
383
|
+
} else {
|
384
|
+
this.$el.undelegate();
|
385
|
+
return this.$el.unbind(eventName);
|
386
|
+
}
|
387
|
+
};
|
388
|
+
|
389
|
+
BaseView.prototype.undelegateEvents = function() {
|
390
|
+
return this.jqoff(".delegateEvents" + this.cid);
|
391
|
+
};
|
392
|
+
|
393
|
+
BaseView.prototype.remove = function() {
|
394
|
+
this.undelegateEvents();
|
395
|
+
return this.$el.remove();
|
396
|
+
};
|
397
|
+
|
398
|
+
return BaseView;
|
399
|
+
|
400
|
+
})();
|
401
|
+
|
402
|
+
_Message = (function(_super) {
|
403
|
+
|
404
|
+
__extends(_Message, _super);
|
405
|
+
|
406
|
+
function _Message() {
|
407
|
+
return _Message.__super__.constructor.apply(this, arguments);
|
408
|
+
}
|
409
|
+
|
410
|
+
_Message.prototype.defaults = {
|
411
|
+
hideAfter: 10,
|
412
|
+
scroll: true
|
413
|
+
};
|
414
|
+
|
415
|
+
_Message.prototype.initialize = function(opts) {
|
416
|
+
if (opts == null) {
|
417
|
+
opts = {};
|
418
|
+
}
|
419
|
+
this.shown = false;
|
420
|
+
this.rendered = false;
|
421
|
+
this.messenger = opts.messenger;
|
422
|
+
return this.options = $.extend({}, this.options, opts, this.defaults);
|
423
|
+
};
|
424
|
+
|
425
|
+
_Message.prototype.show = function() {
|
426
|
+
var wasShown;
|
427
|
+
if (!this.rendered) {
|
428
|
+
this.render();
|
429
|
+
}
|
430
|
+
this.$message.removeClass('messenger-hidden');
|
431
|
+
wasShown = this.shown;
|
432
|
+
this.shown = true;
|
433
|
+
if (!wasShown) {
|
434
|
+
return this.trigger('show');
|
435
|
+
}
|
436
|
+
};
|
437
|
+
|
438
|
+
_Message.prototype.hide = function() {
|
439
|
+
var wasShown;
|
440
|
+
if (!this.rendered) {
|
441
|
+
return;
|
442
|
+
}
|
443
|
+
this.$message.addClass('messenger-hidden');
|
444
|
+
wasShown = this.shown;
|
445
|
+
this.shown = false;
|
446
|
+
if (wasShown) {
|
447
|
+
return this.trigger('hide');
|
448
|
+
}
|
449
|
+
};
|
450
|
+
|
451
|
+
_Message.prototype.cancel = function() {
|
452
|
+
return this.hide();
|
453
|
+
};
|
454
|
+
|
455
|
+
_Message.prototype.update = function(opts) {
|
456
|
+
var _ref2,
|
457
|
+
_this = this;
|
458
|
+
if (_.isString(opts)) {
|
459
|
+
opts = {
|
460
|
+
message: opts
|
461
|
+
};
|
462
|
+
}
|
463
|
+
$.extend(this.options, opts);
|
464
|
+
this.lastUpdate = new Date();
|
465
|
+
this.rendered = false;
|
466
|
+
this.events = (_ref2 = this.options.events) != null ? _ref2 : {};
|
467
|
+
this.render();
|
468
|
+
this.actionsToEvents();
|
469
|
+
this.delegateEvents();
|
470
|
+
this.checkClickable();
|
471
|
+
if (this.options.hideAfter) {
|
472
|
+
this.$message.addClass('messenger-will-hide-after');
|
473
|
+
if (this._hideTimeout != null) {
|
474
|
+
clearTimeout(this._hideTimeout);
|
475
|
+
}
|
476
|
+
this._hideTimeout = setTimeout(function() {
|
477
|
+
return _this.hide();
|
478
|
+
}, this.options.hideAfter * 1000);
|
479
|
+
} else {
|
480
|
+
this.$message.removeClass('messenger-will-hide-after');
|
481
|
+
}
|
482
|
+
if (this.options.hideOnNavigate) {
|
483
|
+
this.$message.addClass('messenger-will-hide-on-navigate');
|
484
|
+
if ((typeof Backbone !== "undefined" && Backbone !== null ? Backbone.history : void 0) != null) {
|
485
|
+
Backbone.history.on('route', function() {
|
486
|
+
return _this.hide();
|
487
|
+
});
|
488
|
+
}
|
489
|
+
} else {
|
490
|
+
this.$message.removeClass('messenger-will-hide-on-navigate');
|
491
|
+
}
|
492
|
+
return this.trigger('update', this);
|
493
|
+
};
|
494
|
+
|
495
|
+
_Message.prototype.scrollTo = function() {
|
496
|
+
if (!this.options.scroll) {
|
497
|
+
return;
|
498
|
+
}
|
499
|
+
return $.scrollTo(this.$el, {
|
500
|
+
duration: 400,
|
501
|
+
offset: {
|
502
|
+
left: 0,
|
503
|
+
top: -20
|
504
|
+
}
|
505
|
+
});
|
506
|
+
};
|
507
|
+
|
508
|
+
_Message.prototype.timeSinceUpdate = function() {
|
509
|
+
if (this.lastUpdate) {
|
510
|
+
return (new Date) - this.lastUpdate;
|
511
|
+
} else {
|
512
|
+
return null;
|
513
|
+
}
|
514
|
+
};
|
515
|
+
|
516
|
+
_Message.prototype.actionsToEvents = function() {
|
517
|
+
var act, name, _ref2, _results,
|
518
|
+
_this = this;
|
519
|
+
_ref2 = this.options.actions;
|
520
|
+
_results = [];
|
521
|
+
for (name in _ref2) {
|
522
|
+
act = _ref2[name];
|
523
|
+
_results.push(this.events["click [data-action=\"" + name + "\"] a"] = (function(act) {
|
524
|
+
return function(e) {
|
525
|
+
e.preventDefault();
|
526
|
+
e.stopPropagation();
|
527
|
+
_this.trigger("action:" + name, act, e);
|
528
|
+
return act.action.call(_this, e, _this);
|
529
|
+
};
|
530
|
+
})(act));
|
531
|
+
}
|
532
|
+
return _results;
|
533
|
+
};
|
534
|
+
|
535
|
+
_Message.prototype.checkClickable = function() {
|
536
|
+
var evt, name, _ref2, _results;
|
537
|
+
_ref2 = this.events;
|
538
|
+
_results = [];
|
539
|
+
for (name in _ref2) {
|
540
|
+
evt = _ref2[name];
|
541
|
+
if (name === 'click') {
|
542
|
+
_results.push(this.$message.addClass('messenger-clickable'));
|
543
|
+
} else {
|
544
|
+
_results.push(void 0);
|
545
|
+
}
|
546
|
+
}
|
547
|
+
return _results;
|
548
|
+
};
|
549
|
+
|
550
|
+
_Message.prototype.undelegateEvents = function() {
|
551
|
+
var _ref2;
|
552
|
+
_Message.__super__.undelegateEvents.apply(this, arguments);
|
553
|
+
return (_ref2 = this.$message) != null ? _ref2.removeClass('messenger-clickable') : void 0;
|
554
|
+
};
|
555
|
+
|
556
|
+
_Message.prototype.parseActions = function() {
|
557
|
+
var act, actions, n_act, name, _ref2, _ref3;
|
558
|
+
actions = [];
|
559
|
+
_ref2 = this.options.actions;
|
560
|
+
for (name in _ref2) {
|
561
|
+
act = _ref2[name];
|
562
|
+
n_act = $.extend({}, act);
|
563
|
+
n_act.name = name;
|
564
|
+
if ((_ref3 = n_act.label) == null) {
|
565
|
+
n_act.label = name;
|
566
|
+
}
|
567
|
+
actions.push(n_act);
|
568
|
+
}
|
569
|
+
return actions;
|
570
|
+
};
|
571
|
+
|
572
|
+
_Message.prototype.template = function(opts) {
|
573
|
+
var $action, $actions, $cancel, $link, $message, $text, action, _i, _len, _ref2,
|
574
|
+
_this = this;
|
575
|
+
$message = $("<div class='messenger-message message alert " + opts.type + " message-" + opts.type + " alert-" + opts.type + "'>");
|
576
|
+
if (opts.showCloseButton) {
|
577
|
+
$cancel = $('<button type="button" class="messenger-close" data-dismiss="alert">×</button>');
|
578
|
+
$cancel.click(function() {
|
579
|
+
_this.cancel();
|
580
|
+
return true;
|
581
|
+
});
|
582
|
+
$message.append($cancel);
|
583
|
+
}
|
584
|
+
$text = $("<div class=\"messenger-message-inner\">" + opts.message + "</div>");
|
585
|
+
$message.append($text);
|
586
|
+
if (opts.actions.length) {
|
587
|
+
$actions = $('<div class="messenger-actions">');
|
588
|
+
}
|
589
|
+
_ref2 = opts.actions;
|
590
|
+
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
591
|
+
action = _ref2[_i];
|
592
|
+
$action = $('<span>');
|
593
|
+
$action.attr('data-action', "" + action.name);
|
594
|
+
$link = $('<a>');
|
595
|
+
$link.html(action.label);
|
596
|
+
$action.append($('<span class="messenger-phrase">'));
|
597
|
+
$action.append($link);
|
598
|
+
$actions.append($action);
|
599
|
+
}
|
600
|
+
$message.append($actions);
|
601
|
+
return $message;
|
602
|
+
};
|
603
|
+
|
604
|
+
_Message.prototype.render = function() {
|
605
|
+
var opts;
|
606
|
+
if (this.rendered) {
|
607
|
+
return;
|
608
|
+
}
|
609
|
+
if (!this._hasSlot) {
|
610
|
+
this.setElement(this.messenger._reserveMessageSlot(this));
|
611
|
+
this._hasSlot = true;
|
612
|
+
}
|
613
|
+
opts = $.extend({}, this.options, {
|
614
|
+
actions: this.parseActions()
|
615
|
+
});
|
616
|
+
this.$message = $(this.template(opts));
|
617
|
+
this.$el.html(this.$message);
|
618
|
+
this.shown = true;
|
619
|
+
this.rendered = true;
|
620
|
+
return this.trigger('render');
|
621
|
+
};
|
622
|
+
|
623
|
+
return _Message;
|
624
|
+
|
625
|
+
})(BaseView);
|
626
|
+
|
627
|
+
RetryingMessage = (function(_super) {
|
628
|
+
|
629
|
+
__extends(RetryingMessage, _super);
|
630
|
+
|
631
|
+
function RetryingMessage() {
|
632
|
+
return RetryingMessage.__super__.constructor.apply(this, arguments);
|
633
|
+
}
|
634
|
+
|
635
|
+
RetryingMessage.prototype.initialize = function() {
|
636
|
+
RetryingMessage.__super__.initialize.apply(this, arguments);
|
637
|
+
return this._timers = {};
|
638
|
+
};
|
639
|
+
|
640
|
+
RetryingMessage.prototype.cancel = function() {
|
641
|
+
this.clearTimers();
|
642
|
+
this.hide();
|
643
|
+
if ((this._actionInstance != null) && (this._actionInstance.abort != null)) {
|
644
|
+
return this._actionInstance.abort();
|
645
|
+
}
|
646
|
+
};
|
647
|
+
|
648
|
+
RetryingMessage.prototype.clearTimers = function() {
|
649
|
+
var name, timer, _ref2, _ref3;
|
650
|
+
_ref2 = this._timers;
|
651
|
+
for (name in _ref2) {
|
652
|
+
timer = _ref2[name];
|
653
|
+
clearTimeout(timer);
|
654
|
+
}
|
655
|
+
this._timers = {};
|
656
|
+
return (_ref3 = this.$message) != null ? _ref3.removeClass('messenger-retry-soon messenger-retry-later') : void 0;
|
657
|
+
};
|
658
|
+
|
659
|
+
RetryingMessage.prototype.render = function() {
|
660
|
+
var action, name, _ref2, _results;
|
661
|
+
RetryingMessage.__super__.render.apply(this, arguments);
|
662
|
+
this.clearTimers();
|
663
|
+
_ref2 = this.options.actions;
|
664
|
+
_results = [];
|
665
|
+
for (name in _ref2) {
|
666
|
+
action = _ref2[name];
|
667
|
+
if (action.auto) {
|
668
|
+
_results.push(this.startCountdown(name, action));
|
669
|
+
} else {
|
670
|
+
_results.push(void 0);
|
671
|
+
}
|
672
|
+
}
|
673
|
+
return _results;
|
674
|
+
};
|
675
|
+
|
676
|
+
RetryingMessage.prototype.renderPhrase = function(action, time) {
|
677
|
+
var phrase;
|
678
|
+
phrase = action.phrase.replace('TIME', this.formatTime(time));
|
679
|
+
return phrase;
|
680
|
+
};
|
681
|
+
|
682
|
+
RetryingMessage.prototype.formatTime = function(time) {
|
683
|
+
var pluralize;
|
684
|
+
pluralize = function(num, str) {
|
685
|
+
num = Math.floor(num);
|
686
|
+
if (num !== 1) {
|
687
|
+
str = str + 's';
|
688
|
+
}
|
689
|
+
return 'in ' + num + ' ' + str;
|
690
|
+
};
|
691
|
+
if (Math.floor(time) === 0) {
|
692
|
+
return 'now...';
|
693
|
+
}
|
694
|
+
if (time < 60) {
|
695
|
+
return pluralize(time, 'second');
|
696
|
+
}
|
697
|
+
time /= 60;
|
698
|
+
if (time < 60) {
|
699
|
+
return pluralize(time, 'minute');
|
700
|
+
}
|
701
|
+
time /= 60;
|
702
|
+
return pluralize(time, 'hour');
|
703
|
+
};
|
704
|
+
|
705
|
+
RetryingMessage.prototype.startCountdown = function(name, action) {
|
706
|
+
var $phrase, remaining, tick, _ref2,
|
707
|
+
_this = this;
|
708
|
+
if (this._timers[name] != null) {
|
709
|
+
return;
|
710
|
+
}
|
711
|
+
$phrase = this.$message.find("[data-action='" + name + "'] .messenger-phrase");
|
712
|
+
remaining = (_ref2 = action.delay) != null ? _ref2 : 3;
|
713
|
+
if (remaining <= 10) {
|
714
|
+
this.$message.removeClass('messenger-retry-later');
|
715
|
+
this.$message.addClass('messenger-retry-soon');
|
716
|
+
} else {
|
717
|
+
this.$message.removeClass('messenger-retry-soon');
|
718
|
+
this.$message.addClass('messenger-retry-later');
|
719
|
+
}
|
720
|
+
tick = function() {
|
721
|
+
var delta;
|
722
|
+
$phrase.text(_this.renderPhrase(action, remaining));
|
723
|
+
if (remaining > 0) {
|
724
|
+
delta = Math.min(remaining, 1);
|
725
|
+
remaining -= delta;
|
726
|
+
return _this._timers[name] = setTimeout(tick, delta * 1000);
|
727
|
+
} else {
|
728
|
+
_this.$message.removeClass('messenger-retry-soon messenger-retry-later');
|
729
|
+
delete _this._timers[name];
|
730
|
+
return action.action();
|
731
|
+
}
|
732
|
+
};
|
733
|
+
return tick();
|
734
|
+
};
|
735
|
+
|
736
|
+
return RetryingMessage;
|
737
|
+
|
738
|
+
})(_Message);
|
739
|
+
|
740
|
+
_Messenger = (function(_super) {
|
741
|
+
|
742
|
+
__extends(_Messenger, _super);
|
743
|
+
|
744
|
+
function _Messenger() {
|
745
|
+
return _Messenger.__super__.constructor.apply(this, arguments);
|
746
|
+
}
|
747
|
+
|
748
|
+
_Messenger.prototype.tagName = 'ul';
|
749
|
+
|
750
|
+
_Messenger.prototype.className = 'messenger';
|
751
|
+
|
752
|
+
_Messenger.prototype.messageDefaults = {
|
753
|
+
type: 'info'
|
754
|
+
};
|
755
|
+
|
756
|
+
_Messenger.prototype.initialize = function(options) {
|
757
|
+
this.options = options != null ? options : {};
|
758
|
+
this.history = [];
|
759
|
+
return this.messageDefaults = $.extend({}, this.messageDefaults, this.options.messageDefaults);
|
760
|
+
};
|
761
|
+
|
762
|
+
_Messenger.prototype.render = function() {
|
763
|
+
return this.updateMessageSlotClasses();
|
764
|
+
};
|
765
|
+
|
766
|
+
_Messenger.prototype.findById = function(id) {
|
767
|
+
return _.filter(this.history, function(rec) {
|
768
|
+
return rec.msg.options.id === id;
|
769
|
+
});
|
770
|
+
};
|
771
|
+
|
772
|
+
_Messenger.prototype._reserveMessageSlot = function(msg) {
|
773
|
+
var $slot, dmsg,
|
774
|
+
_this = this;
|
775
|
+
$slot = $('<li>');
|
776
|
+
$slot.addClass('messenger-message-slot');
|
777
|
+
this.$el.prepend($slot);
|
778
|
+
this.history.push({
|
779
|
+
msg: msg,
|
780
|
+
$slot: $slot
|
781
|
+
});
|
782
|
+
this._enforceIdConstraint(msg);
|
783
|
+
msg.on('update', function() {
|
784
|
+
return _this._enforceIdConstraint(msg);
|
785
|
+
});
|
786
|
+
while (this.options.maxMessages && this.history.length > this.options.maxMessages) {
|
787
|
+
dmsg = this.history.shift();
|
788
|
+
dmsg.msg.remove();
|
789
|
+
dmsg.$slot.remove();
|
790
|
+
}
|
791
|
+
return $slot;
|
792
|
+
};
|
793
|
+
|
794
|
+
_Messenger.prototype._enforceIdConstraint = function(msg) {
|
795
|
+
var entry, _i, _len, _msg, _ref2;
|
796
|
+
if (msg.options.id == null) {
|
797
|
+
return;
|
798
|
+
}
|
799
|
+
_ref2 = this.history;
|
800
|
+
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
801
|
+
entry = _ref2[_i];
|
802
|
+
_msg = entry.msg;
|
803
|
+
if ((_msg.options.id != null) && _msg.options.id === msg.options.id && msg !== _msg) {
|
804
|
+
if (msg.options.singleton) {
|
805
|
+
msg.hide();
|
806
|
+
return;
|
807
|
+
} else {
|
808
|
+
_msg.hide();
|
809
|
+
}
|
810
|
+
}
|
811
|
+
}
|
812
|
+
};
|
813
|
+
|
814
|
+
_Messenger.prototype.newMessage = function(opts) {
|
815
|
+
var msg, _ref2, _ref3, _ref4,
|
816
|
+
_this = this;
|
817
|
+
if (opts == null) {
|
818
|
+
opts = {};
|
819
|
+
}
|
820
|
+
opts.messenger = this;
|
821
|
+
_Message = (_ref2 = (_ref3 = Messenger.themes[(_ref4 = opts.theme) != null ? _ref4 : this.options.theme]) != null ? _ref3.Message : void 0) != null ? _ref2 : RetryingMessage;
|
822
|
+
msg = new _Message(opts);
|
823
|
+
msg.on('show', function() {
|
824
|
+
if (opts.scrollTo && _this.$el.css('position') !== 'fixed') {
|
825
|
+
return msg.scrollTo();
|
826
|
+
}
|
827
|
+
});
|
828
|
+
msg.on('hide show render', this.updateMessageSlotClasses, this);
|
829
|
+
return msg;
|
830
|
+
};
|
831
|
+
|
832
|
+
_Messenger.prototype.updateMessageSlotClasses = function() {
|
833
|
+
var anyShown, last, rec, willBeFirst, _i, _len, _ref2;
|
834
|
+
willBeFirst = true;
|
835
|
+
last = null;
|
836
|
+
anyShown = false;
|
837
|
+
_ref2 = this.history;
|
838
|
+
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
839
|
+
rec = _ref2[_i];
|
840
|
+
rec.$slot.removeClass('messenger-first messenger-last messenger-shown');
|
841
|
+
if (rec.msg.shown && rec.msg.rendered) {
|
842
|
+
rec.$slot.addClass('messenger-shown');
|
843
|
+
anyShown = true;
|
844
|
+
last = rec;
|
845
|
+
if (willBeFirst) {
|
846
|
+
willBeFirst = false;
|
847
|
+
rec.$slot.addClass('messenger-first');
|
848
|
+
}
|
849
|
+
}
|
850
|
+
}
|
851
|
+
if (last != null) {
|
852
|
+
last.$slot.addClass('messenger-last');
|
853
|
+
}
|
854
|
+
return this.$el["" + (anyShown ? 'remove' : 'add') + "Class"]('messenger-empty');
|
855
|
+
};
|
856
|
+
|
857
|
+
_Messenger.prototype.hideAll = function() {
|
858
|
+
var rec, _i, _len, _ref2, _results;
|
859
|
+
_ref2 = this.history;
|
860
|
+
_results = [];
|
861
|
+
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
862
|
+
rec = _ref2[_i];
|
863
|
+
_results.push(rec.msg.hide());
|
864
|
+
}
|
865
|
+
return _results;
|
866
|
+
};
|
867
|
+
|
868
|
+
_Messenger.prototype.post = function(opts) {
|
869
|
+
var msg;
|
870
|
+
if (_.isString(opts)) {
|
871
|
+
opts = {
|
872
|
+
message: opts
|
873
|
+
};
|
874
|
+
}
|
875
|
+
opts = $.extend(true, {}, this.messageDefaults, opts);
|
876
|
+
msg = this.newMessage(opts);
|
877
|
+
msg.update(opts);
|
878
|
+
return msg;
|
879
|
+
};
|
880
|
+
|
881
|
+
return _Messenger;
|
882
|
+
|
883
|
+
})(BaseView);
|
884
|
+
|
885
|
+
ActionMessenger = (function(_super) {
|
886
|
+
|
887
|
+
__extends(ActionMessenger, _super);
|
888
|
+
|
889
|
+
function ActionMessenger() {
|
890
|
+
return ActionMessenger.__super__.constructor.apply(this, arguments);
|
891
|
+
}
|
892
|
+
|
893
|
+
ActionMessenger.prototype.doDefaults = {
|
894
|
+
progressMessage: null,
|
895
|
+
successMessage: null,
|
896
|
+
errorMessage: "Error connecting to the server.",
|
897
|
+
showSuccessWithoutError: true,
|
898
|
+
retry: {
|
899
|
+
auto: true,
|
900
|
+
allow: true
|
901
|
+
},
|
902
|
+
action: $.ajax
|
903
|
+
};
|
904
|
+
|
905
|
+
ActionMessenger.prototype.hookBackboneAjax = function(msgr_opts) {
|
906
|
+
var _ajax,
|
907
|
+
_this = this;
|
908
|
+
if (msgr_opts == null) {
|
909
|
+
msgr_opts = {};
|
910
|
+
}
|
911
|
+
if (!(window.Backbone != null)) {
|
912
|
+
throw 'Expected Backbone to be defined';
|
913
|
+
}
|
914
|
+
msgr_opts = _.defaults(msgr_opts, {
|
915
|
+
id: 'BACKBONE_ACTION',
|
916
|
+
errorMessage: false,
|
917
|
+
successMessage: "Request completed successfully.",
|
918
|
+
showSuccessWithoutError: false
|
919
|
+
});
|
920
|
+
_ajax = function(options) {
|
921
|
+
var sync_msgr_opts;
|
922
|
+
sync_msgr_opts = _.extend({}, msgr_opts, options.messenger);
|
923
|
+
return _this["do"](sync_msgr_opts, options);
|
924
|
+
};
|
925
|
+
if (Backbone.ajax != null) {
|
926
|
+
if (Backbone.ajax._withoutMessenger) {
|
927
|
+
Backbone.ajax = Backbone.ajax._withoutMessenger;
|
928
|
+
}
|
929
|
+
if (!(msgr_opts.action != null) || msgr_opts.action === this.doDefaults.action) {
|
930
|
+
msgr_opts.action = Backbone.ajax;
|
931
|
+
}
|
932
|
+
_ajax._withoutMessenger = Backbone.ajax;
|
933
|
+
return Backbone.ajax = _ajax;
|
934
|
+
} else {
|
935
|
+
return Backbone.sync = _.wrap(Backbone.sync, function() {
|
936
|
+
var args, _old_ajax, _old_sync;
|
937
|
+
_old_sync = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
938
|
+
_old_ajax = $.ajax;
|
939
|
+
$.ajax = _ajax;
|
940
|
+
_old_sync.call.apply(_old_sync, [this].concat(__slice.call(args)));
|
941
|
+
return $.ajax = _old_ajax;
|
942
|
+
});
|
943
|
+
}
|
944
|
+
};
|
945
|
+
|
946
|
+
ActionMessenger.prototype._getHandlerResponse = function(returnVal) {
|
947
|
+
if (returnVal === false) {
|
948
|
+
return false;
|
949
|
+
}
|
950
|
+
if (returnVal === true || !(returnVal != null)) {
|
951
|
+
return true;
|
952
|
+
}
|
953
|
+
return returnVal;
|
954
|
+
};
|
955
|
+
|
956
|
+
ActionMessenger.prototype._parseEvents = function(events) {
|
957
|
+
var desc, firstSpace, func, label, out, type, _ref2;
|
958
|
+
if (events == null) {
|
959
|
+
events = {};
|
960
|
+
}
|
961
|
+
out = {};
|
962
|
+
for (label in events) {
|
963
|
+
func = events[label];
|
964
|
+
firstSpace = label.indexOf(' ');
|
965
|
+
type = label.substring(0, firstSpace);
|
966
|
+
desc = label.substring(firstSpace + 1);
|
967
|
+
if ((_ref2 = out[type]) == null) {
|
968
|
+
out[type] = {};
|
969
|
+
}
|
970
|
+
out[type][desc] = func;
|
971
|
+
}
|
972
|
+
return out;
|
973
|
+
};
|
974
|
+
|
975
|
+
ActionMessenger.prototype._normalizeResponse = function() {
|
976
|
+
var data, elem, resp, type, xhr, _i, _len;
|
977
|
+
resp = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
978
|
+
type = null;
|
979
|
+
xhr = null;
|
980
|
+
data = null;
|
981
|
+
for (_i = 0, _len = resp.length; _i < _len; _i++) {
|
982
|
+
elem = resp[_i];
|
983
|
+
if (elem === 'success' || elem === 'timeout' || elem === 'abort') {
|
984
|
+
type = elem;
|
985
|
+
} else if (((elem != null ? elem.readyState : void 0) != null) && ((elem != null ? elem.responseText : void 0) != null)) {
|
986
|
+
xhr = elem;
|
987
|
+
} else if (_.isObject(elem)) {
|
988
|
+
data = elem;
|
989
|
+
}
|
990
|
+
}
|
991
|
+
return [type, data, xhr];
|
992
|
+
};
|
993
|
+
|
994
|
+
ActionMessenger.prototype.run = function() {
|
995
|
+
var args, attr, events, getMessageText, handler, handlers, m_opts, msg, old, opts, promiseAttrs, type, _i, _len, _ref2, _ref3,
|
996
|
+
_this = this;
|
997
|
+
m_opts = arguments[0], opts = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
998
|
+
if (opts == null) {
|
999
|
+
opts = {};
|
1000
|
+
}
|
1001
|
+
m_opts = $.extend(true, {}, this.messageDefaults, this.doDefaults, m_opts != null ? m_opts : {});
|
1002
|
+
events = this._parseEvents(m_opts.events);
|
1003
|
+
getMessageText = function(type, xhr) {
|
1004
|
+
var message;
|
1005
|
+
message = m_opts[type + 'Message'];
|
1006
|
+
if (_.isFunction(message)) {
|
1007
|
+
return message.call(_this, type, xhr);
|
1008
|
+
}
|
1009
|
+
return message;
|
1010
|
+
};
|
1011
|
+
msg = (_ref2 = m_opts.messageInstance) != null ? _ref2 : this.newMessage(m_opts);
|
1012
|
+
if (m_opts.id != null) {
|
1013
|
+
msg.options.id = m_opts.id;
|
1014
|
+
}
|
1015
|
+
if (m_opts.progressMessage != null) {
|
1016
|
+
msg.update($.extend({}, m_opts, {
|
1017
|
+
message: getMessageText('progress', null),
|
1018
|
+
type: 'info'
|
1019
|
+
}));
|
1020
|
+
}
|
1021
|
+
handlers = {};
|
1022
|
+
_.each(['error', 'success'], function(type) {
|
1023
|
+
var originalHandler;
|
1024
|
+
originalHandler = opts[type];
|
1025
|
+
return handlers[type] = function() {
|
1026
|
+
var data, defaultOpts, handlerResp, msgOpts, reason, resp, responseOpts, xhr, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
|
1027
|
+
resp = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
1028
|
+
_ref3 = _this._normalizeResponse.apply(_this, resp), reason = _ref3[0], data = _ref3[1], xhr = _ref3[2];
|
1029
|
+
if (type === 'success' && !(msg.errorCount != null) && m_opts.showSuccessWithoutError === false) {
|
1030
|
+
m_opts['successMessage'] = null;
|
1031
|
+
}
|
1032
|
+
if (type === 'error') {
|
1033
|
+
if ((_ref4 = m_opts.errorCount) == null) {
|
1034
|
+
m_opts.errorCount = 0;
|
1035
|
+
}
|
1036
|
+
m_opts.errorCount += 1;
|
1037
|
+
}
|
1038
|
+
handlerResp = m_opts.returnsPromise ? resp[0] : typeof originalHandler === "function" ? originalHandler.apply(null, resp) : void 0;
|
1039
|
+
responseOpts = _this._getHandlerResponse(handlerResp);
|
1040
|
+
if (_.isString(responseOpts)) {
|
1041
|
+
responseOpts = {
|
1042
|
+
message: responseOpts
|
1043
|
+
};
|
1044
|
+
}
|
1045
|
+
if (type === 'error' && ((xhr != null ? xhr.status : void 0) === 0 || reason === 'abort')) {
|
1046
|
+
msg.hide();
|
1047
|
+
return;
|
1048
|
+
}
|
1049
|
+
if (type === 'error' && ((m_opts.ignoredErrorCodes != null) && (_ref5 = xhr != null ? xhr.status : void 0, __indexOf.call(m_opts.ignoredErrorCodes, _ref5) >= 0))) {
|
1050
|
+
msg.hide();
|
1051
|
+
return;
|
1052
|
+
}
|
1053
|
+
defaultOpts = {
|
1054
|
+
message: getMessageText(type, xhr),
|
1055
|
+
type: type,
|
1056
|
+
events: (_ref6 = events[type]) != null ? _ref6 : {},
|
1057
|
+
hideOnNavigate: type === 'success'
|
1058
|
+
};
|
1059
|
+
msgOpts = $.extend({}, m_opts, defaultOpts, responseOpts);
|
1060
|
+
if (typeof ((_ref7 = msgOpts.retry) != null ? _ref7.allow : void 0) === 'number') {
|
1061
|
+
msgOpts.retry.allow--;
|
1062
|
+
}
|
1063
|
+
if (type === 'error' && (xhr != null ? xhr.status : void 0) >= 500 && ((_ref8 = msgOpts.retry) != null ? _ref8.allow : void 0)) {
|
1064
|
+
if (msgOpts.retry.delay == null) {
|
1065
|
+
if (msgOpts.errorCount < 4) {
|
1066
|
+
msgOpts.retry.delay = 10;
|
1067
|
+
} else {
|
1068
|
+
msgOpts.retry.delay = 5 * 60;
|
1069
|
+
}
|
1070
|
+
}
|
1071
|
+
if (msgOpts.hideAfter) {
|
1072
|
+
if ((_ref9 = msgOpts._hideAfter) == null) {
|
1073
|
+
msgOpts._hideAfter = msgOpts.hideAfter;
|
1074
|
+
}
|
1075
|
+
msgOpts.hideAfter = msgOpts._hideAfter + msgOpts.retry.delay;
|
1076
|
+
}
|
1077
|
+
msgOpts._retryActions = true;
|
1078
|
+
msgOpts.actions = {
|
1079
|
+
retry: {
|
1080
|
+
label: 'retry now',
|
1081
|
+
phrase: 'Retrying TIME',
|
1082
|
+
auto: msgOpts.retry.auto,
|
1083
|
+
delay: msgOpts.retry.delay,
|
1084
|
+
action: function() {
|
1085
|
+
msgOpts.messageInstance = msg;
|
1086
|
+
return setTimeout(function() {
|
1087
|
+
return _this["do"].apply(_this, [msgOpts, opts].concat(__slice.call(args)));
|
1088
|
+
}, 0);
|
1089
|
+
}
|
1090
|
+
},
|
1091
|
+
cancel: {
|
1092
|
+
action: function() {
|
1093
|
+
return msg.cancel();
|
1094
|
+
}
|
1095
|
+
}
|
1096
|
+
};
|
1097
|
+
} else if (msgOpts._retryActions) {
|
1098
|
+
delete msgOpts.actions.retry;
|
1099
|
+
delete msgOpts.actions.cancel;
|
1100
|
+
delete m_opts._retryActions;
|
1101
|
+
}
|
1102
|
+
msg.update(msgOpts);
|
1103
|
+
if (responseOpts && msgOpts.message) {
|
1104
|
+
Messenger();
|
1105
|
+
return msg.show();
|
1106
|
+
} else {
|
1107
|
+
return msg.hide();
|
1108
|
+
}
|
1109
|
+
};
|
1110
|
+
});
|
1111
|
+
if (!m_opts.returnsPromise) {
|
1112
|
+
for (type in handlers) {
|
1113
|
+
handler = handlers[type];
|
1114
|
+
old = opts[type];
|
1115
|
+
opts[type] = handler;
|
1116
|
+
}
|
1117
|
+
}
|
1118
|
+
msg._actionInstance = m_opts.action.apply(m_opts, [opts].concat(__slice.call(args)));
|
1119
|
+
if (m_opts.returnsPromise) {
|
1120
|
+
msg._actionInstance.then(handlers.success, handlers.error);
|
1121
|
+
}
|
1122
|
+
promiseAttrs = ['done', 'progress', 'fail', 'state', 'then'];
|
1123
|
+
for (_i = 0, _len = promiseAttrs.length; _i < _len; _i++) {
|
1124
|
+
attr = promiseAttrs[_i];
|
1125
|
+
if (msg[attr] != null) {
|
1126
|
+
delete msg[attr];
|
1127
|
+
}
|
1128
|
+
msg[attr] = (_ref3 = msg._actionInstance) != null ? _ref3[attr] : void 0;
|
1129
|
+
}
|
1130
|
+
return msg;
|
1131
|
+
};
|
1132
|
+
|
1133
|
+
ActionMessenger.prototype["do"] = ActionMessenger.prototype.run;
|
1134
|
+
|
1135
|
+
ActionMessenger.prototype.ajax = function() {
|
1136
|
+
var args, m_opts;
|
1137
|
+
m_opts = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
1138
|
+
m_opts.action = $.ajax;
|
1139
|
+
return this.run.apply(this, [m_opts].concat(__slice.call(args)));
|
1140
|
+
};
|
1141
|
+
|
1142
|
+
ActionMessenger.prototype.expectPromise = function(action, m_opts) {
|
1143
|
+
m_opts = _.extend({}, m_opts, {
|
1144
|
+
action: action,
|
1145
|
+
returnsPromise: true
|
1146
|
+
});
|
1147
|
+
return this.run(m_opts);
|
1148
|
+
};
|
1149
|
+
|
1150
|
+
return ActionMessenger;
|
1151
|
+
|
1152
|
+
})(_Messenger);
|
1153
|
+
|
1154
|
+
$.fn.messenger = function() {
|
1155
|
+
var $el, args, func, instance, opts, _ref2, _ref3, _ref4;
|
1156
|
+
func = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
1157
|
+
if (func == null) {
|
1158
|
+
func = {};
|
1159
|
+
}
|
1160
|
+
$el = this;
|
1161
|
+
if (!(func != null) || !_.isString(func)) {
|
1162
|
+
opts = func;
|
1163
|
+
if (!($el.data('messenger') != null)) {
|
1164
|
+
_Messenger = (_ref2 = (_ref3 = Messenger.themes[opts.theme]) != null ? _ref3.Messenger : void 0) != null ? _ref2 : ActionMessenger;
|
1165
|
+
$el.data('messenger', instance = new _Messenger($.extend({
|
1166
|
+
el: $el
|
1167
|
+
}, opts)));
|
1168
|
+
instance.render();
|
1169
|
+
}
|
1170
|
+
return $el.data('messenger');
|
1171
|
+
} else {
|
1172
|
+
return (_ref4 = $el.data('messenger'))[func].apply(_ref4, args);
|
1173
|
+
}
|
1174
|
+
};
|
1175
|
+
|
1176
|
+
window.Messenger._call = function(opts) {
|
1177
|
+
var $el, $parent, choosen_loc, chosen_loc, classes, defaultOpts, inst, loc, locations, _i, _len;
|
1178
|
+
defaultOpts = {
|
1179
|
+
extraClasses: 'messenger-fixed messenger-on-bottom messenger-on-right',
|
1180
|
+
theme: 'future',
|
1181
|
+
maxMessages: 9,
|
1182
|
+
parentLocations: ['body']
|
1183
|
+
};
|
1184
|
+
opts = $.extend(defaultOpts, $._messengerDefaults, Messenger.options, opts);
|
1185
|
+
if (opts.theme != null) {
|
1186
|
+
opts.extraClasses += " messenger-theme-" + opts.theme;
|
1187
|
+
}
|
1188
|
+
inst = opts.instance || Messenger.instance;
|
1189
|
+
if (opts.instance == null) {
|
1190
|
+
locations = opts.parentLocations;
|
1191
|
+
$parent = null;
|
1192
|
+
choosen_loc = null;
|
1193
|
+
for (_i = 0, _len = locations.length; _i < _len; _i++) {
|
1194
|
+
loc = locations[_i];
|
1195
|
+
$parent = $(loc);
|
1196
|
+
if ($parent.length) {
|
1197
|
+
chosen_loc = loc;
|
1198
|
+
break;
|
1199
|
+
}
|
1200
|
+
}
|
1201
|
+
if (!inst) {
|
1202
|
+
$el = $('<ul>');
|
1203
|
+
$parent.prepend($el);
|
1204
|
+
inst = $el.messenger(opts);
|
1205
|
+
inst._location = chosen_loc;
|
1206
|
+
Messenger.instance = inst;
|
1207
|
+
} else if ($(inst._location) !== $(chosen_loc)) {
|
1208
|
+
inst.$el.detach();
|
1209
|
+
$parent.prepend(inst.$el);
|
1210
|
+
}
|
1211
|
+
}
|
1212
|
+
if (inst._addedClasses != null) {
|
1213
|
+
inst.$el.removeClass(inst._addedClasses);
|
1214
|
+
}
|
1215
|
+
inst.$el.addClass(classes = "" + inst.className + " " + opts.extraClasses);
|
1216
|
+
inst._addedClasses = classes;
|
1217
|
+
return inst;
|
1218
|
+
};
|
1219
|
+
|
1220
|
+
$.extend(Messenger, {
|
1221
|
+
Message: RetryingMessage,
|
1222
|
+
Messenger: ActionMessenger,
|
1223
|
+
themes: (_ref2 = Messenger.themes) != null ? _ref2 : {}
|
1224
|
+
});
|
1225
|
+
|
1226
|
+
$.globalMessenger = window.Messenger = Messenger;
|
1227
|
+
|
1228
|
+
}).call(this);
|