jquery-console-rails 1.0.0
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/.rvmrc +52 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/jquery-console-rails.gemspec +19 -0
- data/lib/jquery-console-rails.rb +1 -0
- data/lib/jquery/console/rails.rb +9 -0
- data/lib/jquery/console/rails/engine.rb +8 -0
- data/lib/jquery/console/rails/version.rb +7 -0
- data/vendor/assets/javascripts/jquery.console.js +649 -0
- metadata +75 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
+
# development environment upon cd'ing into the directory
|
5
|
+
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
7
|
+
# Only full ruby name is supported here, for short names use:
|
8
|
+
# echo "rvm use 1.9.3" > .rvmrc
|
9
|
+
environment_id="ruby-1.9.3-p194@jquery-console-rails"
|
10
|
+
|
11
|
+
# Uncomment the following lines if you want to verify rvm version per project
|
12
|
+
# rvmrc_rvm_version="1.14.1 (stable)" # 1.10.1 seams as a safe start
|
13
|
+
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
14
|
+
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
15
|
+
# return 1
|
16
|
+
# }
|
17
|
+
|
18
|
+
# First we attempt to load the desired environment directly from the environment
|
19
|
+
# file. This is very fast and efficient compared to running through the entire
|
20
|
+
# CLI and selector. If you want feedback on which environment was used then
|
21
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
22
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
|
23
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
24
|
+
then
|
25
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
26
|
+
[[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
|
27
|
+
\. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
|
28
|
+
if [[ $- == *i* ]] # check for interactive shells
|
29
|
+
then echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
|
30
|
+
else echo "Using: $GEM_HOME" # don't use colors in non-interactive shells
|
31
|
+
fi
|
32
|
+
else
|
33
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
34
|
+
rvm --create use "$environment_id" || {
|
35
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
36
|
+
return 1
|
37
|
+
}
|
38
|
+
fi
|
39
|
+
|
40
|
+
# If you use bundler, this might be useful to you:
|
41
|
+
# if [[ -s Gemfile ]] && {
|
42
|
+
# ! builtin command -v bundle >/dev/null ||
|
43
|
+
# builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
|
44
|
+
# }
|
45
|
+
# then
|
46
|
+
# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
|
47
|
+
# gem install bundler
|
48
|
+
# fi
|
49
|
+
# if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
|
50
|
+
# then
|
51
|
+
# bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
|
52
|
+
# fi
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# jquery-console-rails
|
2
|
+
|
3
|
+
A library for binding the [jquery-console][jquery-console] console emulation
|
4
|
+
library, written by Chris, to Ruby on Rails. Among other things, this library
|
5
|
+
ensures that your version of [jquery-rails][jquery-rails] is compatible with the
|
6
|
+
console library.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'jquery-console-rails'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install jquery-console-rails
|
21
|
+
|
22
|
+
## Contributing
|
23
|
+
|
24
|
+
1. Fork it
|
25
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
26
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
27
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
28
|
+
5. Create new Pull Request
|
29
|
+
|
30
|
+
[jquery-console]: https://github.com/chrisdone/jquery-console
|
31
|
+
[jquery-rails]: https://github.com/rails/jquery-rails
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/jquery/console/rails/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "jquery-console-rails"
|
6
|
+
gem.version = Jquery::Console::Rails::VERSION
|
7
|
+
gem.authors = ["Nathaniel Bibler"]
|
8
|
+
gem.email = ["git@nathanielbibler.com"]
|
9
|
+
gem.description = %q{This gem provides jQuery and the jquery-console library for your Rails application.}
|
10
|
+
gem.summary = %q{Use jquery-console with Rails}
|
11
|
+
gem.homepage = "http://rubygems.org/gems/jquery-console-rails"
|
12
|
+
|
13
|
+
gem.files = `git ls-files`.split($\)
|
14
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
15
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
|
18
|
+
gem.add_dependency 'jquery-rails', '>= 0.2'
|
19
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'jquery/console/rails'
|
@@ -0,0 +1,649 @@
|
|
1
|
+
// JQuery Console 1.0
|
2
|
+
// Sun Feb 21 20:28:47 GMT 2010
|
3
|
+
//
|
4
|
+
// Copyright 2010 Chris Done, Simon David Pratt. All rights reserved.
|
5
|
+
//
|
6
|
+
// Redistribution and use in source and binary forms, with or without
|
7
|
+
// modification, are permitted provided that the following conditions
|
8
|
+
// are met:
|
9
|
+
//
|
10
|
+
// 1. Redistributions of source code must retain the above
|
11
|
+
// copyright notice, this list of conditions and the following
|
12
|
+
// disclaimer.
|
13
|
+
//
|
14
|
+
// 2. Redistributions in binary form must reproduce the above
|
15
|
+
// copyright notice, this list of conditions and the following
|
16
|
+
// disclaimer in the documentation and/or other materials
|
17
|
+
// provided with the distribution.
|
18
|
+
//
|
19
|
+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
20
|
+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
21
|
+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
22
|
+
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
23
|
+
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
24
|
+
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
25
|
+
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
26
|
+
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
28
|
+
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
29
|
+
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
30
|
+
// POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
|
32
|
+
// TESTED ON
|
33
|
+
// Internet Explorer 6
|
34
|
+
// Opera 10.01
|
35
|
+
// Chromium 4.0.237.0 (Ubuntu build 31094)
|
36
|
+
// Firefox 3.5.8, 3.6.2 (Mac)
|
37
|
+
// Safari 4.0.5 (6531.22.7) (Mac)
|
38
|
+
// Google Chrome 5.0.375.55 (Mac)
|
39
|
+
|
40
|
+
(function($){
|
41
|
+
$.fn.console = function(config){
|
42
|
+
////////////////////////////////////////////////////////////////////////
|
43
|
+
// Constants
|
44
|
+
// Some are enums, data types, others just for optimisation
|
45
|
+
var keyCodes = {
|
46
|
+
// left
|
47
|
+
37: moveBackward,
|
48
|
+
// right
|
49
|
+
39: moveForward,
|
50
|
+
// up
|
51
|
+
38: previousHistory,
|
52
|
+
// down
|
53
|
+
40: nextHistory,
|
54
|
+
// backspace
|
55
|
+
8: backDelete,
|
56
|
+
// delete
|
57
|
+
46: forwardDelete,
|
58
|
+
// end
|
59
|
+
35: moveToEnd,
|
60
|
+
// start
|
61
|
+
36: moveToStart,
|
62
|
+
// return
|
63
|
+
13: commandTrigger,
|
64
|
+
// tab
|
65
|
+
18: doNothing
|
66
|
+
};
|
67
|
+
var ctrlCodes = {
|
68
|
+
// C-a
|
69
|
+
65: moveToStart,
|
70
|
+
// C-e
|
71
|
+
69: moveToEnd,
|
72
|
+
// C-d
|
73
|
+
68: forwardDelete,
|
74
|
+
// C-n
|
75
|
+
78: nextHistory,
|
76
|
+
// C-p
|
77
|
+
80: previousHistory,
|
78
|
+
// C-b
|
79
|
+
66: moveBackward,
|
80
|
+
// C-f
|
81
|
+
70: moveForward,
|
82
|
+
// C-k
|
83
|
+
75: deleteUntilEnd
|
84
|
+
};
|
85
|
+
var altCodes = {
|
86
|
+
// M-f
|
87
|
+
70: moveToNextWord,
|
88
|
+
// M-b
|
89
|
+
66: moveToPreviousWord,
|
90
|
+
// M-d
|
91
|
+
68: deleteNextWord
|
92
|
+
};
|
93
|
+
var cursor = '<span class="jquery-console-cursor"> </span>';
|
94
|
+
|
95
|
+
////////////////////////////////////////////////////////////////////////
|
96
|
+
// Globals
|
97
|
+
var container = $(this);
|
98
|
+
var inner = $('<div class="jquery-console-inner"></div>');
|
99
|
+
// erjiang: changed this from a text input to a textarea so we
|
100
|
+
// can get pasted newlines
|
101
|
+
var typer = $('<textarea class="jquery-console-typer"></textarea>');
|
102
|
+
// Prompt
|
103
|
+
var promptBox;
|
104
|
+
var prompt;
|
105
|
+
var promptLabel = config && config.promptLabel? config.promptLabel : "> ";
|
106
|
+
var continuedPromptLabel = config && config.continuedPromptLabel?
|
107
|
+
config.continuedPromptLabel : "> ";
|
108
|
+
var column = 0;
|
109
|
+
var promptText = '';
|
110
|
+
var restoreText = '';
|
111
|
+
var continuedText = '';
|
112
|
+
// Prompt history stack
|
113
|
+
var history = [];
|
114
|
+
var ringn = 0;
|
115
|
+
// For reasons unknown to The Sword of Michael himself, Opera
|
116
|
+
// triggers and sends a key character when you hit various
|
117
|
+
// keys like PgUp, End, etc. So there is no way of knowing
|
118
|
+
// when a user has typed '#' or End. My solution is in the
|
119
|
+
// typer.keydown and typer.keypress functions; I use the
|
120
|
+
// variable below to ignore the keypress event if the keydown
|
121
|
+
// event succeeds.
|
122
|
+
var cancelKeyPress = 0;
|
123
|
+
// When this value is false, the prompt will not respond to input
|
124
|
+
var acceptInput = true;
|
125
|
+
// When this value is true, the command has been canceled
|
126
|
+
var cancelCommand = false;
|
127
|
+
|
128
|
+
// External exports object
|
129
|
+
var extern = {};
|
130
|
+
|
131
|
+
////////////////////////////////////////////////////////////////////////
|
132
|
+
// Main entry point
|
133
|
+
(function(){
|
134
|
+
container.append(inner);
|
135
|
+
inner.append(typer);
|
136
|
+
typer.css({position:'absolute',top:0,left:'-9999px'});
|
137
|
+
if (config.welcomeMessage)
|
138
|
+
message(config.welcomeMessage,'jquery-console-welcome');
|
139
|
+
newPromptBox();
|
140
|
+
if (config.autofocus) {
|
141
|
+
inner.addClass('jquery-console-focus');
|
142
|
+
typer.focus();
|
143
|
+
setTimeout(function(){
|
144
|
+
inner.addClass('jquery-console-focus');
|
145
|
+
typer.focus();
|
146
|
+
},100);
|
147
|
+
}
|
148
|
+
extern.inner = inner;
|
149
|
+
extern.typer = typer;
|
150
|
+
extern.scrollToBottom = scrollToBottom;
|
151
|
+
})();
|
152
|
+
|
153
|
+
////////////////////////////////////////////////////////////////////////
|
154
|
+
// Reset terminal
|
155
|
+
extern.reset = function(){
|
156
|
+
var welcome = (typeof config.welcomeMessage != 'undefined');
|
157
|
+
inner.parent().fadeOut(function(){
|
158
|
+
inner.find('div').each(function(){
|
159
|
+
if (!welcome) {
|
160
|
+
$(this).remove();
|
161
|
+
} else {
|
162
|
+
welcome = false;
|
163
|
+
}
|
164
|
+
});
|
165
|
+
newPromptBox();
|
166
|
+
inner.parent().fadeIn(function(){
|
167
|
+
inner.addClass('jquery-console-focus');
|
168
|
+
typer.focus();
|
169
|
+
});
|
170
|
+
});
|
171
|
+
};
|
172
|
+
|
173
|
+
////////////////////////////////////////////////////////////////////////
|
174
|
+
// Reset terminal
|
175
|
+
extern.notice = function(msg,style){
|
176
|
+
var n = $('<div class="notice"></div>').append($('<div></div>').text(msg))
|
177
|
+
.css({visibility:'hidden'});
|
178
|
+
container.append(n);
|
179
|
+
var focused = true;
|
180
|
+
if (style=='fadeout')
|
181
|
+
setTimeout(function(){
|
182
|
+
n.fadeOut(function(){
|
183
|
+
n.remove();
|
184
|
+
});
|
185
|
+
},4000);
|
186
|
+
else if (style=='prompt') {
|
187
|
+
var a = $('<br/><div class="action"><a href="javascript:">OK</a><div class="clear"></div></div>');
|
188
|
+
n.append(a);
|
189
|
+
focused = false;
|
190
|
+
a.click(function(){ n.fadeOut(function(){ n.remove();inner.css({opacity:1}) }); });
|
191
|
+
}
|
192
|
+
var h = n.height();
|
193
|
+
n.css({height:'0px',visibility:'visible'})
|
194
|
+
.animate({height:h+'px'},function(){
|
195
|
+
if (!focused) inner.css({opacity:0.5});
|
196
|
+
});
|
197
|
+
n.css('cursor','default');
|
198
|
+
return n;
|
199
|
+
};
|
200
|
+
|
201
|
+
////////////////////////////////////////////////////////////////////////
|
202
|
+
// Make a new prompt box
|
203
|
+
function newPromptBox() {
|
204
|
+
column = 0;
|
205
|
+
promptText = '';
|
206
|
+
ringn = 0; // Reset the position of the history ring
|
207
|
+
enableInput();
|
208
|
+
promptBox = $('<div class="jquery-console-prompt-box"></div>');
|
209
|
+
var label = $('<span class="jquery-console-prompt-label"></span>');
|
210
|
+
var labelText = extern.continuedPrompt? continuedPromptLabel : promptLabel;
|
211
|
+
promptBox.append(label.text(labelText).show());
|
212
|
+
label.html(label.html().replace(' ',' '));
|
213
|
+
prompt = $('<span class="jquery-console-prompt"></span>');
|
214
|
+
promptBox.append(prompt);
|
215
|
+
inner.append(promptBox);
|
216
|
+
updatePromptDisplay();
|
217
|
+
};
|
218
|
+
|
219
|
+
////////////////////////////////////////////////////////////////////////
|
220
|
+
// Handle setting focus
|
221
|
+
container.click(function(){
|
222
|
+
inner.addClass('jquery-console-focus');
|
223
|
+
inner.removeClass('jquery-console-nofocus');
|
224
|
+
typer.focus();
|
225
|
+
scrollToBottom();
|
226
|
+
return false;
|
227
|
+
});
|
228
|
+
|
229
|
+
////////////////////////////////////////////////////////////////////////
|
230
|
+
// Handle losing focus
|
231
|
+
typer.blur(function(){
|
232
|
+
inner.removeClass('jquery-console-focus');
|
233
|
+
inner.addClass('jquery-console-nofocus');
|
234
|
+
});
|
235
|
+
|
236
|
+
////////////////////////////////////////////////////////////////////////
|
237
|
+
// Bind to the paste event of the input box so we know when we
|
238
|
+
// get pasted data
|
239
|
+
typer.bind('paste', function(e) {
|
240
|
+
// wipe typer input clean just in case
|
241
|
+
typer.val("");
|
242
|
+
// this timeout is required because the onpaste event is
|
243
|
+
// fired *before* the text is actually pasted
|
244
|
+
setTimeout(function() {
|
245
|
+
typer.consoleInsert(typer.val());
|
246
|
+
typer.val("");
|
247
|
+
}, 0);
|
248
|
+
});
|
249
|
+
|
250
|
+
////////////////////////////////////////////////////////////////////////
|
251
|
+
// Handle key hit before translation
|
252
|
+
// For picking up control characters like up/left/down/right
|
253
|
+
|
254
|
+
typer.keydown(function(e){
|
255
|
+
cancelKeyPress = 0;
|
256
|
+
var keyCode = e.keyCode;
|
257
|
+
// C-c: cancel the execution
|
258
|
+
if(e.ctrlKey && keyCode == 67) {
|
259
|
+
cancelKeyPress = keyCode;
|
260
|
+
cancelExecution();
|
261
|
+
return false;
|
262
|
+
}
|
263
|
+
if (acceptInput) {
|
264
|
+
if (keyCode in keyCodes) {
|
265
|
+
cancelKeyPress = keyCode;
|
266
|
+
(keyCodes[keyCode])();
|
267
|
+
return false;
|
268
|
+
} else if (e.ctrlKey && keyCode in ctrlCodes) {
|
269
|
+
cancelKeyPress = keyCode;
|
270
|
+
(ctrlCodes[keyCode])();
|
271
|
+
return false;
|
272
|
+
} else if (e.altKey && keyCode in altCodes) {
|
273
|
+
cancelKeyPress = keyCode;
|
274
|
+
(altCodes[keyCode])();
|
275
|
+
return false;
|
276
|
+
}
|
277
|
+
}
|
278
|
+
});
|
279
|
+
|
280
|
+
////////////////////////////////////////////////////////////////////////
|
281
|
+
// Handle key press
|
282
|
+
typer.keypress(function(e){
|
283
|
+
var keyCode = e.keyCode || e.which;
|
284
|
+
if (isIgnorableKey(e)) {
|
285
|
+
return false;
|
286
|
+
}
|
287
|
+
// // C-v: don't insert on paste event
|
288
|
+
if ((e.ctrlKey || e.metaKey) && String.fromCharCode(keyCode).toLowerCase() == 'v') {
|
289
|
+
return true;
|
290
|
+
}
|
291
|
+
if (acceptInput && cancelKeyPress != keyCode && keyCode >= 32){
|
292
|
+
if (cancelKeyPress) return false;
|
293
|
+
if (typeof config.charInsertTrigger == 'undefined' ||
|
294
|
+
(typeof config.charInsertTrigger == 'function' &&
|
295
|
+
config.charInsertTrigger(keyCode,promptText)))
|
296
|
+
typer.consoleInsert(keyCode);
|
297
|
+
}
|
298
|
+
if ($.browser.webkit) return false;
|
299
|
+
});
|
300
|
+
|
301
|
+
function isIgnorableKey(e) {
|
302
|
+
// for now just filter alt+tab that we receive on some platforms when
|
303
|
+
// user switches windows (goes away from the browser)
|
304
|
+
return ((e.keyCode == keyCodes.tab || e.keyCode == 192) && e.altKey);
|
305
|
+
};
|
306
|
+
|
307
|
+
////////////////////////////////////////////////////////////////////////
|
308
|
+
// Rotate through the command history
|
309
|
+
function rotateHistory(n){
|
310
|
+
if (history.length == 0) return;
|
311
|
+
ringn += n;
|
312
|
+
if (ringn < 0) ringn = history.length;
|
313
|
+
else if (ringn > history.length) ringn = 0;
|
314
|
+
var prevText = promptText;
|
315
|
+
if (ringn == 0) {
|
316
|
+
promptText = restoreText;
|
317
|
+
} else {
|
318
|
+
promptText = history[ringn - 1];
|
319
|
+
}
|
320
|
+
if (config.historyPreserveColumn) {
|
321
|
+
if (promptText.length < column + 1) {
|
322
|
+
column = promptText.length;
|
323
|
+
} else if (column == 0) {
|
324
|
+
column = promptText.length;
|
325
|
+
}
|
326
|
+
} else {
|
327
|
+
column = promptText.length;
|
328
|
+
}
|
329
|
+
updatePromptDisplay();
|
330
|
+
};
|
331
|
+
|
332
|
+
function previousHistory() {
|
333
|
+
rotateHistory(-1);
|
334
|
+
};
|
335
|
+
|
336
|
+
function nextHistory() {
|
337
|
+
rotateHistory(1);
|
338
|
+
};
|
339
|
+
|
340
|
+
// Add something to the history ring
|
341
|
+
function addToHistory(line){
|
342
|
+
history.push(line);
|
343
|
+
restoreText = '';
|
344
|
+
};
|
345
|
+
|
346
|
+
// Delete the character at the current position
|
347
|
+
function deleteCharAtPos(){
|
348
|
+
if (column < promptText.length){
|
349
|
+
promptText =
|
350
|
+
promptText.substring(0,column) +
|
351
|
+
promptText.substring(column+1);
|
352
|
+
restoreText = promptText;
|
353
|
+
return true;
|
354
|
+
} else return false;
|
355
|
+
};
|
356
|
+
|
357
|
+
function backDelete() {
|
358
|
+
if (moveColumn(-1)){
|
359
|
+
deleteCharAtPos();
|
360
|
+
updatePromptDisplay();
|
361
|
+
}
|
362
|
+
};
|
363
|
+
|
364
|
+
function forwardDelete() {
|
365
|
+
if (deleteCharAtPos())
|
366
|
+
updatePromptDisplay();
|
367
|
+
};
|
368
|
+
|
369
|
+
function deleteUntilEnd() {
|
370
|
+
while(deleteCharAtPos()) {
|
371
|
+
updatePromptDisplay();
|
372
|
+
}
|
373
|
+
};
|
374
|
+
|
375
|
+
function deleteNextWord() {
|
376
|
+
// A word is defined within this context as a series of alphanumeric
|
377
|
+
// characters.
|
378
|
+
// Delete up to the next alphanumeric character
|
379
|
+
while(column < promptText.length &&
|
380
|
+
!isCharAlphanumeric(promptText[column])) {
|
381
|
+
deleteCharAtPos();
|
382
|
+
updatePromptDisplay();
|
383
|
+
}
|
384
|
+
// Then, delete until the next non-alphanumeric character
|
385
|
+
while(column < promptText.length &&
|
386
|
+
isCharAlphanumeric(promptText[column])) {
|
387
|
+
deleteCharAtPos();
|
388
|
+
updatePromptDisplay();
|
389
|
+
}
|
390
|
+
};
|
391
|
+
|
392
|
+
////////////////////////////////////////////////////////////////////////
|
393
|
+
// Validate command and trigger it if valid, or show a validation error
|
394
|
+
function commandTrigger() {
|
395
|
+
var line = promptText;
|
396
|
+
if (typeof config.commandValidate == 'function') {
|
397
|
+
var ret = config.commandValidate(line);
|
398
|
+
if (ret == true || ret == false) {
|
399
|
+
if (ret) {
|
400
|
+
handleCommand();
|
401
|
+
}
|
402
|
+
} else {
|
403
|
+
commandResult(ret,"jquery-console-message-error");
|
404
|
+
}
|
405
|
+
} else {
|
406
|
+
handleCommand();
|
407
|
+
}
|
408
|
+
};
|
409
|
+
|
410
|
+
// Scroll to the bottom of the view
|
411
|
+
function scrollToBottom() {
|
412
|
+
if (jQuery.fn.jquery > "1.6") {
|
413
|
+
inner.prop({ scrollTop: inner.prop("scrollHeight") });
|
414
|
+
}
|
415
|
+
else {
|
416
|
+
inner.attr({ scrollTop: inner.attr("scrollHeight") });
|
417
|
+
}
|
418
|
+
};
|
419
|
+
|
420
|
+
function cancelExecution() {
|
421
|
+
if(typeof config.cancelHandle == 'function') {
|
422
|
+
config.cancelHandle();
|
423
|
+
}
|
424
|
+
}
|
425
|
+
|
426
|
+
////////////////////////////////////////////////////////////////////////
|
427
|
+
// Handle a command
|
428
|
+
function handleCommand() {
|
429
|
+
if (typeof config.commandHandle == 'function') {
|
430
|
+
disableInput();
|
431
|
+
addToHistory(promptText);
|
432
|
+
var text = promptText;
|
433
|
+
if (extern.continuedPrompt) {
|
434
|
+
if (continuedText)
|
435
|
+
continuedText += '\n' + promptText;
|
436
|
+
else continuedText = promptText;
|
437
|
+
} else continuedText = undefined;
|
438
|
+
if (continuedText) text = continuedText;
|
439
|
+
var ret = config.commandHandle(text,function(msgs){
|
440
|
+
commandResult(msgs);
|
441
|
+
});
|
442
|
+
if (extern.continuedPrompt && !continuedText)
|
443
|
+
continuedText = promptText;
|
444
|
+
if (typeof ret == 'boolean') {
|
445
|
+
if (ret) {
|
446
|
+
// Command succeeded without a result.
|
447
|
+
commandResult();
|
448
|
+
} else {
|
449
|
+
commandResult('Command failed.',
|
450
|
+
"jquery-console-message-error");
|
451
|
+
}
|
452
|
+
} else if (typeof ret == "string") {
|
453
|
+
commandResult(ret,"jquery-console-message-success");
|
454
|
+
} else if (typeof ret == 'object' && ret.length) {
|
455
|
+
commandResult(ret);
|
456
|
+
} else if (extern.continuedPrompt) {
|
457
|
+
commandResult();
|
458
|
+
}
|
459
|
+
}
|
460
|
+
};
|
461
|
+
|
462
|
+
////////////////////////////////////////////////////////////////////////
|
463
|
+
// Disable input
|
464
|
+
function disableInput() {
|
465
|
+
acceptInput = false;
|
466
|
+
};
|
467
|
+
|
468
|
+
// Enable input
|
469
|
+
function enableInput() {
|
470
|
+
acceptInput = true;
|
471
|
+
}
|
472
|
+
|
473
|
+
////////////////////////////////////////////////////////////////////////
|
474
|
+
// Reset the prompt in invalid command
|
475
|
+
function commandResult(msg,className) {
|
476
|
+
column = -1;
|
477
|
+
updatePromptDisplay();
|
478
|
+
if (typeof msg == 'string') {
|
479
|
+
message(msg,className);
|
480
|
+
} else if ($.isArray(msg)) {
|
481
|
+
for (var x in msg) {
|
482
|
+
var ret = msg[x];
|
483
|
+
message(ret.msg,ret.className);
|
484
|
+
}
|
485
|
+
} else { // Assume it's a DOM node or jQuery object.
|
486
|
+
inner.append(msg);
|
487
|
+
}
|
488
|
+
newPromptBox();
|
489
|
+
};
|
490
|
+
|
491
|
+
////////////////////////////////////////////////////////////////////////
|
492
|
+
// Display a message
|
493
|
+
function message(msg,className) {
|
494
|
+
var mesg = $('<div class="jquery-console-message"></div>');
|
495
|
+
if (className) mesg.addClass(className);
|
496
|
+
mesg.filledText(msg).hide();
|
497
|
+
inner.append(mesg);
|
498
|
+
mesg.show();
|
499
|
+
};
|
500
|
+
|
501
|
+
////////////////////////////////////////////////////////////////////////
|
502
|
+
// Handle normal character insertion
|
503
|
+
// data can either be a number, which will be interpreted as the
|
504
|
+
// numeric value of a single character, or a string
|
505
|
+
typer.consoleInsert = function(data){
|
506
|
+
// TODO: remove redundant indirection
|
507
|
+
var text = isNaN(data) ? data : String.fromCharCode(data);
|
508
|
+
var before = promptText.substring(0,column);
|
509
|
+
var after = promptText.substring(column);
|
510
|
+
promptText = before + text + after;
|
511
|
+
moveColumn(text.length);
|
512
|
+
restoreText = promptText;
|
513
|
+
updatePromptDisplay();
|
514
|
+
};
|
515
|
+
|
516
|
+
////////////////////////////////////////////////////////////////////////
|
517
|
+
// Move to another column relative to this one
|
518
|
+
// Negative means go back, positive means go forward.
|
519
|
+
function moveColumn(n){
|
520
|
+
if (column + n >= 0 && column + n <= promptText.length){
|
521
|
+
column += n;
|
522
|
+
return true;
|
523
|
+
} else return false;
|
524
|
+
};
|
525
|
+
|
526
|
+
function moveForward() {
|
527
|
+
if(moveColumn(1)) {
|
528
|
+
updatePromptDisplay();
|
529
|
+
return true;
|
530
|
+
}
|
531
|
+
return false;
|
532
|
+
};
|
533
|
+
|
534
|
+
function moveBackward() {
|
535
|
+
if(moveColumn(-1)) {
|
536
|
+
updatePromptDisplay();
|
537
|
+
return true;
|
538
|
+
}
|
539
|
+
return false;
|
540
|
+
};
|
541
|
+
|
542
|
+
function moveToStart() {
|
543
|
+
if (moveColumn(-column))
|
544
|
+
updatePromptDisplay();
|
545
|
+
};
|
546
|
+
|
547
|
+
function moveToEnd() {
|
548
|
+
if (moveColumn(promptText.length-column))
|
549
|
+
updatePromptDisplay();
|
550
|
+
};
|
551
|
+
|
552
|
+
function moveToNextWord() {
|
553
|
+
while(column < promptText.length &&
|
554
|
+
!isCharAlphanumeric(promptText[column]) &&
|
555
|
+
moveForward()) {
|
556
|
+
}
|
557
|
+
while(column < promptText.length &&
|
558
|
+
isCharAlphanumeric(promptText[column]) &&
|
559
|
+
moveForward()) {
|
560
|
+
}
|
561
|
+
};
|
562
|
+
|
563
|
+
function moveToPreviousWord() {
|
564
|
+
// Move backward until we find the first alphanumeric
|
565
|
+
while(column -1 >= 0 &&
|
566
|
+
!isCharAlphanumeric(promptText[column-1]) &&
|
567
|
+
moveBackward()) {
|
568
|
+
}
|
569
|
+
// Move until we find the first non-alphanumeric
|
570
|
+
while(column -1 >= 0 &&
|
571
|
+
isCharAlphanumeric(promptText[column-1]) &&
|
572
|
+
moveBackward()) {
|
573
|
+
}
|
574
|
+
};
|
575
|
+
|
576
|
+
function isCharAlphanumeric(charToTest) {
|
577
|
+
if(typeof charToTest == 'string') {
|
578
|
+
var code = charToTest.charCodeAt();
|
579
|
+
return (code >= 'A'.charCodeAt() && code <= 'Z'.charCodeAt()) ||
|
580
|
+
(code >= 'a'.charCodeAt() && code <= 'z'.charCodeAt()) ||
|
581
|
+
(code >= '0'.charCodeAt() && code <= '9'.charCodeAt());
|
582
|
+
}
|
583
|
+
return false;
|
584
|
+
};
|
585
|
+
|
586
|
+
function doNothing() {};
|
587
|
+
|
588
|
+
extern.promptText = function(text){
|
589
|
+
if (text) {
|
590
|
+
promptText = text;
|
591
|
+
column = promptText.length;
|
592
|
+
updatePromptDisplay();
|
593
|
+
}
|
594
|
+
return promptText;
|
595
|
+
};
|
596
|
+
|
597
|
+
////////////////////////////////////////////////////////////////////////
|
598
|
+
// Update the prompt display
|
599
|
+
function updatePromptDisplay(){
|
600
|
+
var line = promptText;
|
601
|
+
var html = '';
|
602
|
+
if (column > 0 && line == ''){
|
603
|
+
// When we have an empty line just display a cursor.
|
604
|
+
html = cursor;
|
605
|
+
} else if (column == promptText.length){
|
606
|
+
// We're at the end of the line, so we need to display
|
607
|
+
// the text *and* cursor.
|
608
|
+
html = htmlEncode(line) + cursor;
|
609
|
+
} else {
|
610
|
+
// Grab the current character, if there is one, and
|
611
|
+
// make it the current cursor.
|
612
|
+
var before = line.substring(0, column);
|
613
|
+
var current = line.substring(column,column+1);
|
614
|
+
if (current){
|
615
|
+
current =
|
616
|
+
'<span class="jquery-console-cursor">' +
|
617
|
+
htmlEncode(current) +
|
618
|
+
'</span>';
|
619
|
+
}
|
620
|
+
var after = line.substring(column+1);
|
621
|
+
html = htmlEncode(before) + current + htmlEncode(after);
|
622
|
+
}
|
623
|
+
prompt.html(html);
|
624
|
+
scrollToBottom();
|
625
|
+
};
|
626
|
+
|
627
|
+
// Simple HTML encoding
|
628
|
+
// Simply replace '<', '>' and '&'
|
629
|
+
// TODO: Use jQuery's .html() trick, or grab a proper, fast
|
630
|
+
// HTML encoder.
|
631
|
+
function htmlEncode(text){
|
632
|
+
return (
|
633
|
+
text.replace(/&/g,'&')
|
634
|
+
.replace(/</g,'<')
|
635
|
+
.replace(/</g,'<')
|
636
|
+
.replace(/ /g,' ')
|
637
|
+
.replace(/\n/g,'<br />')
|
638
|
+
);
|
639
|
+
};
|
640
|
+
|
641
|
+
return extern;
|
642
|
+
};
|
643
|
+
// Simple utility for printing messages
|
644
|
+
$.fn.filledText = function(txt){
|
645
|
+
$(this).text(txt);
|
646
|
+
$(this).html($(this).html().replace(/\n/g,'<br/>'));
|
647
|
+
return this;
|
648
|
+
};
|
649
|
+
})(jQuery);
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jquery-console-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nathaniel Bibler
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: jquery-rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.2'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.2'
|
30
|
+
description: This gem provides jQuery and the jquery-console library for your Rails
|
31
|
+
application.
|
32
|
+
email:
|
33
|
+
- git@nathanielbibler.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- .gitignore
|
39
|
+
- .rvmrc
|
40
|
+
- CHANGELOG.md
|
41
|
+
- Gemfile
|
42
|
+
- LICENSE
|
43
|
+
- README.md
|
44
|
+
- Rakefile
|
45
|
+
- jquery-console-rails.gemspec
|
46
|
+
- lib/jquery-console-rails.rb
|
47
|
+
- lib/jquery/console/rails.rb
|
48
|
+
- lib/jquery/console/rails/engine.rb
|
49
|
+
- lib/jquery/console/rails/version.rb
|
50
|
+
- vendor/assets/javascripts/jquery.console.js
|
51
|
+
homepage: http://rubygems.org/gems/jquery-console-rails
|
52
|
+
licenses: []
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
requirements: []
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.8.23
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Use jquery-console with Rails
|
75
|
+
test_files: []
|