sequenceserver 0.7.8 → 0.7.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sequenceserver might be problematic. Click here for more details.

@@ -229,12 +229,6 @@ module SequenceServer
229
229
  # evaluate empty sequence as nil, otherwise as fasta
230
230
  sequence = sequence.empty? ? nil : to_fasta(sequence)
231
231
 
232
- # TODO: detect sequence type in the browser itself (no AJAX)
233
- if request.xhr?
234
- # if the AJAX request didn't specify a blast method, it must be interested in sequence type only
235
- return (sequence && type_of_sequences(sequence)).to_s unless method
236
- end
237
-
238
232
  # Raise ArgumentError if there is no database selected
239
233
  if db_type_param.nil?
240
234
  raise ArgumentError, "No BLAST database selected"
@@ -1,4 +1,8 @@
1
1
  /* generic */
2
+ html, body{
3
+ height: 100%;
4
+ }
5
+
2
6
  .offset-left {
3
7
  margin-left: 20px;
4
8
  }
@@ -26,6 +26,57 @@
26
26
  SS.blast = (function () {
27
27
  /* private methods */
28
28
 
29
+ // TODO: embedding magic numbers in the code is bad
30
+ // TODO: magic numbers in JS and Ruby should be in sync
31
+ var guess_sequence_type = function (sequence) {
32
+ var putative_NA_count, threshold, i;
33
+
34
+ putative_NA_count = 0;
35
+
36
+ // remove 'noisy' characters
37
+ sequence = sequence.replace(/[^A-Z]/gi, '') // non-letter characters
38
+ sequence = sequence.replace(/[NX]/gi, '') // ambiguous characters
39
+
40
+ // guessing the type of a small sequence is unsafe
41
+ if (sequence.length < 10) {
42
+ return undefined
43
+ }
44
+
45
+ // count the number of putative NA
46
+ for (i = 0; i < sequence.length; i++) {
47
+ if (sequence[i].match(/[ACGTU]/i)) {
48
+ putative_NA_count += 1;
49
+ }
50
+ }
51
+
52
+ threshold = 0.9 * sequence.length
53
+
54
+ return putative_NA_count > threshold ? 'nucleotide' : 'protein'
55
+ }
56
+
57
+ var type_of_sequences = function () {
58
+ var sequences = $('#sequence').val().split(/>.*/)
59
+ var type, tmp, i;
60
+
61
+ for (i = 0; i < sequences.length; i++) {
62
+ tmp = guess_sequence_type(sequences[i]);
63
+
64
+ // could not guess the sequence type; try the next sequence
65
+ if (!tmp) { continue }
66
+
67
+ if (!type) {
68
+ // successfully guessed the type of atleast one sequence
69
+ type = tmp
70
+ }
71
+ else if (tmp !== type) {
72
+ // user has mixed different type of sequences
73
+ return undefined
74
+ }
75
+ }
76
+
77
+ return type;
78
+ }
79
+
29
80
  /*
30
81
  check if blast is valid (sufficient input to blast or not)
31
82
  */
@@ -64,36 +115,22 @@ SS.blast = (function () {
64
115
  }
65
116
 
66
117
  /*
67
- determine input sequence type, store it, and trigger
68
- 'sequence_type_changed' event if the input sequence has changed
69
- (TODO: the method is doing too much; split it)
118
+ determine input sequence type, and trigger 'sequence_type_changed'
119
+ event if the input sequence type has changed
70
120
  */
71
121
  var signal_sequence_type_changed = function () {
72
- var prev_seq = prev_seq_type = '';
73
-
74
- (function poll () {
75
- setTimeout(function (){
76
- var seq, seq_type;
77
- seq = $('#sequence').val();
78
-
79
- //act only if user input has changed
80
- if (seq != prev_seq){
81
- prev_seq = seq;
82
- $('#sequence').change();
83
-
84
- //get input sequence type from the server
85
- $.post('', {sequence: seq}, function(seq_type){
86
- if (seq_type != prev_seq_type){
87
- prev_seq_type = seq_type;
88
-
89
- //store sequence type and notify listeners
90
- $('#sequence').data('sequence_type', seq_type).trigger('sequence_type_changed');
91
- }
92
- });
93
- }
94
- poll();
95
- }, 100)
96
- }());
122
+ var type, tmp;
123
+
124
+ $('#sequence').change(function () {
125
+ tmp = type_of_sequences();
126
+
127
+ if (tmp != type){
128
+ type = tmp;
129
+
130
+ //notify listeners
131
+ $(this).trigger('sequence_type_changed', type);
132
+ }
133
+ });
97
134
  };
98
135
 
99
136
 
@@ -52,6 +52,27 @@
52
52
  };
53
53
  })( jQuery );
54
54
 
55
+ (function ($) {
56
+ $.fn.poll = function () {
57
+ var that, val, tmp;
58
+
59
+ that = this;
60
+
61
+ (function ping () {
62
+ tmp = that.val();
63
+
64
+ if (tmp != val){
65
+ val = tmp;
66
+ that.change();
67
+ }
68
+
69
+ setTimeout(ping, 100);
70
+ }());
71
+
72
+ return this;
73
+ };
74
+ }(jQuery));
75
+
55
76
  /*
56
77
  SS - SequenceServer's JavaScript module
57
78
 
@@ -80,6 +101,9 @@ if (!SS) {
80
101
  }()); //end SS module
81
102
 
82
103
  $(document).ready(function(){
104
+ // poll the sequence textbox for a change in user input
105
+ $('#sequence').poll();
106
+
83
107
  // start SequenceServer's event loop
84
108
  SS.main();
85
109
  $('input:submit').disable();
@@ -92,17 +116,16 @@ $(document).ready(function(){
92
116
  $('input:submit').disable();
93
117
  });
94
118
 
95
- $('#sequence').bind('sequence_type_changed', function(){
96
- var seq_type = $(this).data('sequence_type');
97
- if (seq_type == "nucleotide"){
119
+ $('#sequence').bind('sequence_type_changed', function(event, type){
120
+ if (type == "nucleotide"){
98
121
  $("#blastn, #tblastx, #blastx").enable();
99
122
  $("#blastp, #tblastn").uncheck().disable().first().change();
100
123
  }
101
- else if (seq_type == "protein"){
124
+ else if (type == "protein"){
102
125
  $("#blastp, #tblastn").enable();
103
126
  $("#blastn, #tblastx, #blastx").uncheck().disable().first().change();
104
127
  }
105
- else if (seq_type == ""){
128
+ else if (type == undefined){
106
129
  //reset blast methods
107
130
  $('.blastmethods input[type=radio]').enable().first().change();
108
131
  }
@@ -148,7 +171,13 @@ $(document).ready(function(){
148
171
  });
149
172
 
150
173
  $('#blast').submit(function(){
151
- var button = $(this);
174
+ //parse AJAX URL
175
+ var action = $(this).attr('action');
176
+ var index = action.indexOf('#');
177
+ var url = action.slice(0, index);
178
+ var hash = action.slice(index, action.length);
179
+
180
+ var button = $(this).find('input:submit');
152
181
 
153
182
  //prevent submitting another query while this one is being processed
154
183
  button.disable();
@@ -173,13 +202,13 @@ $(document).ready(function(){
173
202
  });
174
203
 
175
204
  // BLAST now
176
- $.post('', $('form').serialize()).
205
+ $.post(url, $('form').serialize()).
177
206
  done(function (data) {
178
207
  // BLASTed successfully
179
208
 
180
209
  // display the result
181
210
  $('#result').html(data);
182
- location.hash = '#result';
211
+ location.hash = hash;
183
212
  }).
184
213
  fail(function (jqXHR, status, error) {
185
214
  // BLAST failed
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  # meta
3
3
  s.name = 'sequenceserver'
4
- s.version = '0.7.8'
4
+ s.version = '0.7.9'
5
5
  s.authors = ['Anurag Priyam', 'Ben J Woodcroft', 'Yannick Wurm']
6
6
  s.email = 'anurag08priyam@gmail.com'
7
7
  s.homepage = 'http://sequenceserver.com'
data/views/search.erb CHANGED
@@ -216,7 +216,16 @@
216
216
  </div>
217
217
 
218
218
  <div id="underbar">
219
- <p>&copy; <a href='http://www.sequenceserver.com'>SequenceServer: BLAST search made easy!</a></p>
219
+ <p><strong><a href='http://www.sequenceserver.com'>
220
+ <%= [ "&copy; SequenceServer: BLAST search made easy!",
221
+ "Custom BLAST web interface by SequenceServer.",
222
+ "SequenceServer: Local BLAST with bespoke html interface.",
223
+ "Set up custom BLAST interface with SequenceServer.",
224
+ "Please cite: Priyam A, Woodcroft BJ, Wurm Y (<em>in prep</em>). " +
225
+ "Sequenceserver: BLAST searching made easy."
226
+ ][rand(5)]
227
+ %>
228
+ </a></strong></p>
220
229
  </div>
221
230
  </div> <!-- /page -->
222
231
  </div> <!-- /container -->
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequenceserver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.8
4
+ version: 0.7.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-02-21 00:00:00.000000000Z
14
+ date: 2012-04-11 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
18
- requirement: &21083000 !ruby/object:Gem::Requirement
18
+ requirement: &22947800 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *21083000
26
+ version_requirements: *22947800
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sinatra
29
- requirement: &21082380 !ruby/object:Gem::Requirement
29
+ requirement: &22947280 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: 1.2.0
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *21082380
37
+ version_requirements: *22947280
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: ptools
40
- requirement: &21081860 !ruby/object:Gem::Requirement
40
+ requirement: &22946860 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,7 +45,7 @@ dependencies:
45
45
  version: '0'
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *21081860
48
+ version_requirements: *22946860
49
49
  description: ! 'SequenceServer lets you rapidly set up a BLAST+ server with an intuitive
50
50
  user interface for use locally or over the web.
51
51
 
@@ -67,7 +67,6 @@ files:
67
67
  - views/search.erb
68
68
  - views/500.erb
69
69
  - public/favicon.ico
70
- - public/blastResult.js
71
70
  - public/css/bootstrap.min.css
72
71
  - public/css/custom.css
73
72
  - public/js/jquery.js
@@ -75,8 +74,6 @@ files:
75
74
  - public/js/sequenceserver.js
76
75
  - public/js/jquery.activity.js
77
76
  - public/js/sequenceserver.blast.js
78
- - public/js/bootstrap-modal.js
79
- - public/js/bootstrap-alerts.js
80
77
  - tests/test_sequencehelpers.rb
81
78
  - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.pin
82
79
  - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta
@@ -124,3 +121,4 @@ signing_key:
124
121
  specification_version: 3
125
122
  summary: iPod of BLAST searching
126
123
  test_files: []
124
+ has_rdoc:
@@ -1,99 +0,0 @@
1
-
2
- function finalSubmit(dbIsNt, targetForm, inputName, submitFormName, dbType){
3
- var formArr=targetForm.split(":");
4
- var idArray=new Array();
5
- if(dbType == 0){
6
- if(dbIsNt==1){
7
- document.forms[submitFormName].db.value="Nucleotide";
8
- }
9
- else{
10
- document.forms[submitFormName].db.value="Protein";
11
- }
12
- }
13
- for(j=0; j<formArr.length; j++){
14
- for(var i=0; i<document.forms[formArr[j]].elements.length; i++){
15
- var theElem=document.forms[formArr[j]].elements[i];
16
- if(theElem.type=="checkbox"&&theElem.name==inputName&&theElem.checked){
17
- if(!isIdIn(theElem.value, idArray)){
18
-
19
- idArray[idArray.length]=theElem.value;
20
- }
21
- }
22
- }
23
- if(dbType == 0){
24
- document.forms[submitFormName].term.value="";
25
- for(i=0; i<idArray.length; i++){
26
- if(i ==0 ) {
27
- document.forms[submitFormName].term.value += idArray[i];
28
- } else {
29
- document.forms[submitFormName].term.value += "," + idArray[i];
30
- }
31
- }
32
- } else if (dbType == 1){
33
- document.forms[submitFormName].val.value="";
34
- for(i=0; i<idArray.length; i++){
35
- if(i ==0 ) {
36
- document.forms[submitFormName].val.value += idArray[i];
37
- } else {
38
- document.forms[submitFormName].val.value += "," + idArray[i];
39
- }
40
- }
41
- }
42
- }
43
- document.forms[submitFormName].submit();
44
- }
45
-
46
- function isIdIn(id, idArray){
47
- var idSeen=false;
48
-
49
- for(i=0; i<idArray.length; i++){
50
- if(id==idArray[i]){
51
- idSeen=true;
52
- break;
53
- }
54
- }
55
- return idSeen;
56
- }
57
-
58
- function handleCheckAll(mode, targetForm, inputName){
59
-
60
- var formArr=targetForm.split(":");
61
- for(j=0; j<formArr.length; j++){
62
- for(var i=0; i<document.forms[formArr[j]].elements.length; i++){
63
- var theElem=document.forms[formArr[j]].elements[i];
64
- if(theElem.type=="checkbox"&&theElem.name==inputName){
65
- if(mode=="select"){
66
- theElem.checked=true;
67
- }
68
- else if(mode=="deselect"){
69
- theElem.checked=false;
70
- }
71
- }
72
- }
73
- }
74
-
75
- }
76
-
77
- function synchronizeCheck(id, formName, inputName, isChecked){
78
-
79
- for(var i=0; i<document.forms[formName].elements.length; i++){
80
- var theElem=document.forms[formName].elements[i];
81
- if(theElem.type=="checkbox"&&theElem.name==inputName&&id==theElem.value){
82
- theElem.checked=isChecked;
83
-
84
- }
85
- }
86
-
87
- }
88
-
89
-
90
- function uncheckable(formName, inputName){
91
- for(var i=0; i<document.forms[formName].elements.length; i++){
92
- var theElem=document.forms[formName].elements[i];
93
- if(theElem.type=="checkbox"&&theElem.name==inputName){
94
- theElem.checked=0;
95
-
96
- }
97
- }
98
-
99
- }
@@ -1,113 +0,0 @@
1
- /* ==========================================================
2
- * bootstrap-alerts.js v1.4.0
3
- * http://twitter.github.com/bootstrap/javascript.html#alerts
4
- * ==========================================================
5
- * Copyright 2011 Twitter, Inc.
6
- *
7
- * Licensed under the Apache License, Version 2.0 (the "License");
8
- * you may not use this file except in compliance with the License.
9
- * You may obtain a copy of the License at
10
- *
11
- * http://www.apache.org/licenses/LICENSE-2.0
12
- *
13
- * Unless required by applicable law or agreed to in writing, software
14
- * distributed under the License is distributed on an "AS IS" BASIS,
15
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- * See the License for the specific language governing permissions and
17
- * limitations under the License.
18
- * ========================================================== */
19
-
20
-
21
- !function( $ ){
22
-
23
- "use strict"
24
-
25
- /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
26
- * ======================================================= */
27
-
28
- var transitionEnd
29
-
30
- $(document).ready(function () {
31
-
32
- $.support.transition = (function () {
33
- var thisBody = document.body || document.documentElement
34
- , thisStyle = thisBody.style
35
- , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
36
- return support
37
- })()
38
-
39
- // set CSS transition event type
40
- if ( $.support.transition ) {
41
- transitionEnd = "TransitionEnd"
42
- if ( $.browser.webkit ) {
43
- transitionEnd = "webkitTransitionEnd"
44
- } else if ( $.browser.mozilla ) {
45
- transitionEnd = "transitionend"
46
- } else if ( $.browser.opera ) {
47
- transitionEnd = "oTransitionEnd"
48
- }
49
- }
50
-
51
- })
52
-
53
- /* ALERT CLASS DEFINITION
54
- * ====================== */
55
-
56
- var Alert = function ( content, options ) {
57
- this.settings = $.extend({}, $.fn.alert.defaults, options)
58
- this.$element = $(content)
59
- .delegate(this.settings.selector, 'click', this.close)
60
- }
61
-
62
- Alert.prototype = {
63
-
64
- close: function (e) {
65
- var $element = $(this).parent('.alert-message')
66
-
67
- e && e.preventDefault()
68
- $element.removeClass('in')
69
-
70
- function removeElement () {
71
- $element.remove()
72
- }
73
-
74
- $.support.transition && $element.hasClass('fade') ?
75
- $element.bind(transitionEnd, removeElement) :
76
- removeElement()
77
- }
78
-
79
- }
80
-
81
-
82
- /* ALERT PLUGIN DEFINITION
83
- * ======================= */
84
-
85
- $.fn.alert = function ( options ) {
86
-
87
- if ( options === true ) {
88
- return this.data('alert')
89
- }
90
-
91
- return this.each(function () {
92
- var $this = $(this)
93
-
94
- if ( typeof options == 'string' ) {
95
- return $this.data('alert')[options]()
96
- }
97
-
98
- $(this).data('alert', new Alert( this, options ))
99
-
100
- })
101
- }
102
-
103
- $.fn.alert.defaults = {
104
- selector: '.close'
105
- }
106
-
107
- $(document).ready(function () {
108
- new Alert($('body'), {
109
- selector: '.alert-message[data-alert] .close'
110
- })
111
- })
112
-
113
- }( window.jQuery || window.ender );
@@ -1,260 +0,0 @@
1
- /* =========================================================
2
- * bootstrap-modal.js v1.4.0
3
- * http://twitter.github.com/bootstrap/javascript.html#modal
4
- * =========================================================
5
- * Copyright 2011 Twitter, Inc.
6
- *
7
- * Licensed under the Apache License, Version 2.0 (the "License");
8
- * you may not use this file except in compliance with the License.
9
- * You may obtain a copy of the License at
10
- *
11
- * http://www.apache.org/licenses/LICENSE-2.0
12
- *
13
- * Unless required by applicable law or agreed to in writing, software
14
- * distributed under the License is distributed on an "AS IS" BASIS,
15
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- * See the License for the specific language governing permissions and
17
- * limitations under the License.
18
- * ========================================================= */
19
-
20
-
21
- !function( $ ){
22
-
23
- "use strict"
24
-
25
- /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
26
- * ======================================================= */
27
-
28
- var transitionEnd
29
-
30
- $(document).ready(function () {
31
-
32
- $.support.transition = (function () {
33
- var thisBody = document.body || document.documentElement
34
- , thisStyle = thisBody.style
35
- , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
36
- return support
37
- })()
38
-
39
- // set CSS transition event type
40
- if ( $.support.transition ) {
41
- transitionEnd = "TransitionEnd"
42
- if ( $.browser.webkit ) {
43
- transitionEnd = "webkitTransitionEnd"
44
- } else if ( $.browser.mozilla ) {
45
- transitionEnd = "transitionend"
46
- } else if ( $.browser.opera ) {
47
- transitionEnd = "oTransitionEnd"
48
- }
49
- }
50
-
51
- })
52
-
53
-
54
- /* MODAL PUBLIC CLASS DEFINITION
55
- * ============================= */
56
-
57
- var Modal = function ( content, options ) {
58
- this.settings = $.extend({}, $.fn.modal.defaults, options)
59
- this.$element = $(content)
60
- .delegate('.close', 'click.modal', $.proxy(this.hide, this))
61
-
62
- if ( this.settings.show ) {
63
- this.show()
64
- }
65
-
66
- return this
67
- }
68
-
69
- Modal.prototype = {
70
-
71
- toggle: function () {
72
- return this[!this.isShown ? 'show' : 'hide']()
73
- }
74
-
75
- , show: function () {
76
- var that = this
77
- this.isShown = true
78
- this.$element.trigger('show')
79
-
80
- escape.call(this)
81
- backdrop.call(this, function () {
82
- var transition = $.support.transition && that.$element.hasClass('fade')
83
-
84
- that.$element
85
- .appendTo(document.body)
86
- .show()
87
-
88
- if (transition) {
89
- that.$element[0].offsetWidth // force reflow
90
- }
91
-
92
- that.$element.addClass('in')
93
-
94
- transition ?
95
- that.$element.one(transitionEnd, function () { that.$element.trigger('shown') }) :
96
- that.$element.trigger('shown')
97
-
98
- })
99
-
100
- return this
101
- }
102
-
103
- , hide: function (e) {
104
- e && e.preventDefault()
105
-
106
- if ( !this.isShown ) {
107
- return this
108
- }
109
-
110
- var that = this
111
- this.isShown = false
112
-
113
- escape.call(this)
114
-
115
- this.$element
116
- .trigger('hide')
117
- .removeClass('in')
118
-
119
- $.support.transition && this.$element.hasClass('fade') ?
120
- hideWithTransition.call(this) :
121
- hideModal.call(this)
122
-
123
- return this
124
- }
125
-
126
- }
127
-
128
-
129
- /* MODAL PRIVATE METHODS
130
- * ===================== */
131
-
132
- function hideWithTransition() {
133
- // firefox drops transitionEnd events :{o
134
- var that = this
135
- , timeout = setTimeout(function () {
136
- that.$element.unbind(transitionEnd)
137
- hideModal.call(that)
138
- }, 500)
139
-
140
- this.$element.one(transitionEnd, function () {
141
- clearTimeout(timeout)
142
- hideModal.call(that)
143
- })
144
- }
145
-
146
- function hideModal (that) {
147
- this.$element
148
- .hide()
149
- .trigger('hidden')
150
-
151
- backdrop.call(this)
152
- }
153
-
154
- function backdrop ( callback ) {
155
- var that = this
156
- , animate = this.$element.hasClass('fade') ? 'fade' : ''
157
- if ( this.isShown && this.settings.backdrop ) {
158
- var doAnimate = $.support.transition && animate
159
-
160
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
161
- .appendTo(document.body)
162
-
163
- if ( this.settings.backdrop != 'static' ) {
164
- this.$backdrop.click($.proxy(this.hide, this))
165
- }
166
-
167
- if ( doAnimate ) {
168
- this.$backdrop[0].offsetWidth // force reflow
169
- }
170
-
171
- this.$backdrop.addClass('in')
172
-
173
- doAnimate ?
174
- this.$backdrop.one(transitionEnd, callback) :
175
- callback()
176
-
177
- } else if ( !this.isShown && this.$backdrop ) {
178
- this.$backdrop.removeClass('in')
179
-
180
- $.support.transition && this.$element.hasClass('fade')?
181
- this.$backdrop.one(transitionEnd, $.proxy(removeBackdrop, this)) :
182
- removeBackdrop.call(this)
183
-
184
- } else if ( callback ) {
185
- callback()
186
- }
187
- }
188
-
189
- function removeBackdrop() {
190
- this.$backdrop.remove()
191
- this.$backdrop = null
192
- }
193
-
194
- function escape() {
195
- var that = this
196
- if ( this.isShown && this.settings.keyboard ) {
197
- $(document).bind('keyup.modal', function ( e ) {
198
- if ( e.which == 27 ) {
199
- that.hide()
200
- }
201
- })
202
- } else if ( !this.isShown ) {
203
- $(document).unbind('keyup.modal')
204
- }
205
- }
206
-
207
-
208
- /* MODAL PLUGIN DEFINITION
209
- * ======================= */
210
-
211
- $.fn.modal = function ( options ) {
212
- var modal = this.data('modal')
213
-
214
- if (!modal) {
215
-
216
- if (typeof options == 'string') {
217
- options = {
218
- show: /show|toggle/.test(options)
219
- }
220
- }
221
-
222
- return this.each(function () {
223
- $(this).data('modal', new Modal(this, options))
224
- })
225
- }
226
-
227
- if ( options === true ) {
228
- return modal
229
- }
230
-
231
- if ( typeof options == 'string' ) {
232
- modal[options]()
233
- } else if ( modal ) {
234
- modal.toggle()
235
- }
236
-
237
- return this
238
- }
239
-
240
- $.fn.modal.Modal = Modal
241
-
242
- $.fn.modal.defaults = {
243
- backdrop: false
244
- , keyboard: false
245
- , show: false
246
- }
247
-
248
-
249
- /* MODAL DATA- IMPLEMENTATION
250
- * ========================== */
251
-
252
- $(document).ready(function () {
253
- $('body').delegate('[data-controls-modal]', 'click', function (e) {
254
- e.preventDefault()
255
- var $this = $(this).data('show', true)
256
- $('#' + $this.attr('data-controls-modal')).modal( $this.data() )
257
- })
258
- })
259
-
260
- }( window.jQuery || window.ender );