uwa_files 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/lib/uwa_files/config.rb +20 -0
- data/lib/uwa_files/widget.rb +109 -0
- data/resources/ajax.gif +0 -0
- data/resources/del.png +0 -0
- data/resources/parent.gif +0 -0
- data/resources/rename.png +0 -0
- data/resources/script.js +201 -0
- data/resources/sha1.js +99 -0
- data/resources/style.css +82 -0
- data/resources/upload.js +46 -0
- metadata +63 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'uwa'
|
2
|
+
require 'digest/sha1'
|
3
|
+
require 'json'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module UWA
|
7
|
+
module Widget
|
8
|
+
class Files < UWA::Handler
|
9
|
+
NAME = 'uwa_files'
|
10
|
+
VERSION = '0.1'
|
11
|
+
COPYRIGHT = 'Copyright (C) 2007 Florent Solt'
|
12
|
+
DESC = 'UWA Files widget'
|
13
|
+
AUTHOR = 'Florent Solt'
|
14
|
+
EMAIL = 'florent@solt.biz'
|
15
|
+
HOMEPAGE = 'http://gnetvibes.rubyforge.org'
|
16
|
+
LICENSE = 'BSD'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'uwa_files/config'
|
2
|
+
|
3
|
+
module UWA
|
4
|
+
module Widget
|
5
|
+
class Files
|
6
|
+
def initialize
|
7
|
+
super
|
8
|
+
@author = AUTHOR
|
9
|
+
@title = 'My Files'
|
10
|
+
@icon = 'http://www.netvibes.com/img/icons/folder.gif'
|
11
|
+
@tokens = {}
|
12
|
+
@preferences << {:name => :login, :type => :text, :label => 'Login'}
|
13
|
+
@preferences << {:name => :password, :type => :text, :label => 'Password'}
|
14
|
+
@start = '/tmp'
|
15
|
+
@users = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def login_token
|
19
|
+
token = new_token
|
20
|
+
@tokens[token] = {:login => query['login'], :auth => false, :files => {}}
|
21
|
+
self << token
|
22
|
+
end
|
23
|
+
|
24
|
+
def login
|
25
|
+
token = query['token']
|
26
|
+
login = @tokens[token][:login]
|
27
|
+
if Digest::SHA1.new(token + @users[login].to_s).hexdigest == query['digest']
|
28
|
+
UWA::Server.log(:info, "Login successful for \"#{login}\"")
|
29
|
+
self << token
|
30
|
+
@tokens[token][:auth] = true
|
31
|
+
else
|
32
|
+
UWA::Server.log(:warning, "Login failed for \"#{login}\"")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def files
|
37
|
+
return unless auth?
|
38
|
+
answer = {:type => nil, :data => []}
|
39
|
+
target = @token[:files][query['target']] || @start
|
40
|
+
|
41
|
+
if File.directory?(target)
|
42
|
+
@token[:files] = {} # Security: remove all unused tokens
|
43
|
+
answer[:type] = :dir
|
44
|
+
files = Dir[File.join(target, '*')].sort
|
45
|
+
files.unshift(File.join(target, '..'))
|
46
|
+
files.unshift(File.join(target, '.'))
|
47
|
+
files.each do |f|
|
48
|
+
ftoken = new_token
|
49
|
+
@token[:files][ftoken] = File.expand_path(f)
|
50
|
+
answer[:data] << {
|
51
|
+
:name => File.basename(f),
|
52
|
+
:type => File.directory?(f) ? :dir : :file,
|
53
|
+
:token => ftoken }
|
54
|
+
answer[:data].last[:path] = File.expand_path(f) if f[-1] == 46 # the dot dir
|
55
|
+
end
|
56
|
+
end
|
57
|
+
self << JSON.unparse(answer)
|
58
|
+
end
|
59
|
+
|
60
|
+
def download
|
61
|
+
return unless auth?
|
62
|
+
target = @token[:files][query['target']]
|
63
|
+
unless target.nil?
|
64
|
+
send_file(target)
|
65
|
+
else
|
66
|
+
response.status = '403'
|
67
|
+
self << 'Forbidden'
|
68
|
+
end
|
69
|
+
@token[:files].delete(query['target']) # Security: remove used file token
|
70
|
+
end
|
71
|
+
|
72
|
+
def upload
|
73
|
+
return unless auth?
|
74
|
+
target = @token[:files][query['target']]
|
75
|
+
File.open(File.join(target, query['file']['filename'] ), 'w') do |fd|
|
76
|
+
fd.write query['file']['tempfile'].read
|
77
|
+
end
|
78
|
+
self << "File #{query['file']['filename'].inspect} uploaded"
|
79
|
+
end
|
80
|
+
|
81
|
+
def delete
|
82
|
+
return unless auth?
|
83
|
+
target = @token[:files][query['target']]
|
84
|
+
FileUtils.rm_rf(target)
|
85
|
+
end
|
86
|
+
|
87
|
+
def rename
|
88
|
+
return unless auth?
|
89
|
+
target = @token[:files][query['target']]
|
90
|
+
new = query['new']
|
91
|
+
File.rename(target, File.join(File.dirname(target), File.basename(new)))
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def auth?
|
97
|
+
@token = query['token']
|
98
|
+
@token = @tokens[@token]
|
99
|
+
auth = @token[:auth] rescue false
|
100
|
+
UWA::Server.log(:warning, "Auth failed for token #{query['token'].inspect}") if not auth
|
101
|
+
auth
|
102
|
+
end
|
103
|
+
|
104
|
+
def new_token
|
105
|
+
Digest::SHA1.new(Time.now.to_s + rand(0xffffffff).to_s).hexdigest
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/resources/ajax.gif
ADDED
Binary file
|
data/resources/del.png
ADDED
Binary file
|
Binary file
|
Binary file
|
data/resources/script.js
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
|
2
|
+
widget.onLoad = function() {
|
3
|
+
widget.files = widget.createElement('ul');
|
4
|
+
widget.files.className = 'uwa_files_list';
|
5
|
+
widget.footer = widget.createElement('div');
|
6
|
+
widget.footer.className = 'uwa_files_footer';
|
7
|
+
|
8
|
+
// Form creation
|
9
|
+
widget.form = widget.createElement('form');
|
10
|
+
widget.form.method = 'POST';
|
11
|
+
widget.form.enctype = 'multipart/form-data';
|
12
|
+
widget.form.onsubmit = function() {
|
13
|
+
this.action = this.url + '&target=' + widget.current;
|
14
|
+
return Uploader.submit(this, {
|
15
|
+
onStart : widget.setFooterUpload,
|
16
|
+
onComplete : function(msg) {
|
17
|
+
widget.setFooterForm(msg);
|
18
|
+
widget.onRefresh();
|
19
|
+
}});
|
20
|
+
}.bind(widget.form);
|
21
|
+
widget.file = widget.createElement('input');
|
22
|
+
widget.file.type = 'file';
|
23
|
+
widget.file.name = 'file';
|
24
|
+
widget.form.appendChild(widget.file);
|
25
|
+
var submit = widget.createElement('input');
|
26
|
+
submit.type = 'submit';
|
27
|
+
submit.value = 'Upload';
|
28
|
+
widget.form.appendChild(submit);
|
29
|
+
widget.footer.appendChild(widget.form);
|
30
|
+
|
31
|
+
// Message creation
|
32
|
+
widget.indicator = widget.createElement('img');
|
33
|
+
widget.indicator.src = widget.remoteUrl + 'resources/ajax.gif';
|
34
|
+
widget.footer.appendChild(widget.indicator);
|
35
|
+
widget.message = widget.createElement('div');
|
36
|
+
widget.message.className = 'uwa_files_message';
|
37
|
+
widget.message.setStyle('display', 'none');
|
38
|
+
widget.footer.appendChild(widget.message);
|
39
|
+
|
40
|
+
login = widget.getValue('login');
|
41
|
+
widget.remoteText('login_token?login=' + encodeURIComponent(login),
|
42
|
+
widget.onLoginToken);
|
43
|
+
}
|
44
|
+
|
45
|
+
widget.onLoginToken = function(token) {
|
46
|
+
digest = sha1(token + sha1(widget.getValue('password')));
|
47
|
+
widget.remoteText('login?token=' + token + '&digest=' + digest,
|
48
|
+
widget.onLogin);
|
49
|
+
}
|
50
|
+
|
51
|
+
widget.onLogin = function(token) {
|
52
|
+
if (token) {
|
53
|
+
widget.token = token;
|
54
|
+
widget.setBody(widget.files);
|
55
|
+
widget.body.appendChild(widget.footer);
|
56
|
+
widget.form.url = widget.remoteUrl + 'upload?token=' + widget.token;
|
57
|
+
widget.setFooterForm(null);
|
58
|
+
widget.refreshDir(null);
|
59
|
+
widget.onRefresh = function() {
|
60
|
+
widget.refreshDir(widget.current);
|
61
|
+
};
|
62
|
+
} else {
|
63
|
+
widget.setBody('Login failed !')
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
widget.setFooterForm = function(msg) {
|
68
|
+
widget.file.value = '';
|
69
|
+
widget.form.setStyle('display', 'block');
|
70
|
+
widget.indicator.setStyle('display', 'none');
|
71
|
+
if (msg) {
|
72
|
+
widget.message.setText(msg);
|
73
|
+
widget.message.setStyle('display', 'block');
|
74
|
+
} else {
|
75
|
+
widget.message.setStyle('display', 'none');
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
widget.setFooterUpload = function() {
|
80
|
+
widget.form.setStyle('display', 'none');
|
81
|
+
var filename = widget.file.value.split(/[\/\\]/);
|
82
|
+
widget.message.setText('Uploading ' + filename[filename.length-1]);
|
83
|
+
widget.message.setStyle('display', 'block');
|
84
|
+
widget.indicator.setStyle('display', 'block');
|
85
|
+
return true;
|
86
|
+
}
|
87
|
+
|
88
|
+
widget.refreshDir = function(target) {
|
89
|
+
widget.remoteJson('files?token=' + widget.token + '&target=' + encodeURIComponent(target || ''),
|
90
|
+
widget.onFiles);
|
91
|
+
}
|
92
|
+
|
93
|
+
widget.onFiles = function(answer) {
|
94
|
+
switch(answer.type) {
|
95
|
+
case 'dir':
|
96
|
+
widget.files.empty();
|
97
|
+
widget.current = answer.data[0].token;
|
98
|
+
var li = widget.createElement('li');
|
99
|
+
li.className = 'parent';
|
100
|
+
|
101
|
+
var a = widget.createElement('a');
|
102
|
+
a.className = 'parent';
|
103
|
+
a.href = '#';
|
104
|
+
a.token = answer.data[1].token;
|
105
|
+
a.onclick = function() {
|
106
|
+
widget.refreshDir(this.token);
|
107
|
+
return false;
|
108
|
+
}.bind(a);
|
109
|
+
|
110
|
+
var img = widget.createElement('img');
|
111
|
+
img.src = widget.remoteUrl + 'resource/parent.gif';
|
112
|
+
a.appendChild(img);
|
113
|
+
|
114
|
+
li.appendChild(a);
|
115
|
+
li.appendText(answer.data[0].path);
|
116
|
+
widget.files.appendChild(li);
|
117
|
+
|
118
|
+
for (var i = 2; i < answer.data.length; i++) {
|
119
|
+
widget.files.appendChild(widget.printLink(answer.data[i]))
|
120
|
+
}
|
121
|
+
break;
|
122
|
+
|
123
|
+
default:
|
124
|
+
alert('Answer type :' + answer.type + ' not supported');
|
125
|
+
break;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
widget.printLink = function(file) {
|
130
|
+
var li = widget.createElement('li');
|
131
|
+
var a = widget.createElement('a');
|
132
|
+
var action = null;
|
133
|
+
var img = null;
|
134
|
+
|
135
|
+
// del action
|
136
|
+
action = widget.createElement('a');
|
137
|
+
action.href = '#';
|
138
|
+
action.className = 'action';
|
139
|
+
img = widget.createElement('img');
|
140
|
+
img.src = widget.remoteUrl + 'resources/del.png';
|
141
|
+
action.appendChild(img);
|
142
|
+
action.onclick = function() {
|
143
|
+
if (confirm('Are you sure you want to delete "' + this.firstChild.nodeValue + '" ? ')) {
|
144
|
+
widget.remoteText('delete?token=' + widget.token + '&target=' + this.token,
|
145
|
+
function() { widget.refreshDir(widget.current); });
|
146
|
+
}
|
147
|
+
return false;
|
148
|
+
}.bind(a);
|
149
|
+
li.appendChild(action);
|
150
|
+
|
151
|
+
// rename action
|
152
|
+
action = widget.createElement('a');
|
153
|
+
action.href = '#';
|
154
|
+
action.className = 'action';
|
155
|
+
img = widget.createElement('img');
|
156
|
+
img.src = widget.remoteUrl + 'resources/rename.png';
|
157
|
+
action.appendChild(img);
|
158
|
+
action.onclick = function() {
|
159
|
+
var li = this.parentNode;
|
160
|
+
var input = widget.createElement('input');
|
161
|
+
input.type = 'text';
|
162
|
+
input.token = this.token;
|
163
|
+
input.value = this.firstChild.nodeValue;
|
164
|
+
Event.observe(input, 'keyup', function(ev) {
|
165
|
+
if (ev.keyCode == 27) { // Esc
|
166
|
+
widget.refreshDir(widget.current);
|
167
|
+
} else if (ev.keyCode == 13) { // Return
|
168
|
+
this.blur();
|
169
|
+
}
|
170
|
+
}.bind(input));
|
171
|
+
input.onblur = function() {
|
172
|
+
widget.remoteText('rename?token=' + widget.token +
|
173
|
+
'&target=' + this.token +
|
174
|
+
'&new=' + encodeURIComponent(this.value),
|
175
|
+
function() { widget.refreshDir(widget.current); });
|
176
|
+
}.bind(input);
|
177
|
+
li.setContent(input);
|
178
|
+
input.focus();
|
179
|
+
}.bind(a);
|
180
|
+
li.appendChild(action);
|
181
|
+
|
182
|
+
// download action
|
183
|
+
a.token = file.token;
|
184
|
+
a.className = 'file';
|
185
|
+
if (file.type == 'dir') {
|
186
|
+
img = 'http://www.netvibes.com/img/icons/folder.gif';
|
187
|
+
a.href = '#';
|
188
|
+
a.onclick = function() {
|
189
|
+
widget.refreshDir(this.token);
|
190
|
+
return false;
|
191
|
+
}.bind(a);
|
192
|
+
} else {
|
193
|
+
img = 'http://www.netvibes.com/img/icons/page_white.gif';
|
194
|
+
a.href = widget.remoteUrl + 'download?token=' + widget.token + '&target=' + file.token;
|
195
|
+
}
|
196
|
+
li.setStyle('backgroundImage', 'url(' + img +')');
|
197
|
+
a.appendText(file.name);
|
198
|
+
li.appendChild(a);
|
199
|
+
return li;
|
200
|
+
}
|
201
|
+
|
data/resources/sha1.js
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
function sha1(msg)
|
2
|
+
{
|
3
|
+
//
|
4
|
+
// function 'f' [4.1.1]
|
5
|
+
//
|
6
|
+
function f(s, x, y, z)
|
7
|
+
{
|
8
|
+
switch (s) {
|
9
|
+
case 0: return (x & y) ^ (~x & z);
|
10
|
+
case 1: return x ^ y ^ z;
|
11
|
+
case 2: return (x & y) ^ (x & z) ^ (y & z);
|
12
|
+
case 3: return x ^ y ^ z;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
//
|
17
|
+
// rotate left (circular left shift) value x by n positions [3.2.5]
|
18
|
+
//
|
19
|
+
function ROTL(x, n)
|
20
|
+
{
|
21
|
+
return (x<<n) | (x>>>(32-n));
|
22
|
+
}
|
23
|
+
|
24
|
+
// constants [4.2.1]
|
25
|
+
var K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
|
26
|
+
|
27
|
+
// PREPROCESSING
|
28
|
+
|
29
|
+
msg += String.fromCharCode(0x80); // add trailing '1' bit to string [5.1.1]
|
30
|
+
|
31
|
+
// convert string msg into 512-bit/16-integer blocks arrays of ints [5.2.1]
|
32
|
+
var l = Math.ceil(msg.length/4) + 2; // long enough to contain msg plus 2-word length
|
33
|
+
var N = Math.ceil(l/16); // in N 16-int blocks
|
34
|
+
var M = new Array(N);
|
35
|
+
for (var i=0; i<N; i++) {
|
36
|
+
M[i] = new Array(16);
|
37
|
+
for (var j=0; j<16; j++) { // encode 4 chars per integer, big-endian encoding
|
38
|
+
M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) |
|
39
|
+
(msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3));
|
40
|
+
}
|
41
|
+
}
|
42
|
+
// add length (in bits) into final pair of 32-bit integers (big-endian) [5.1.1]
|
43
|
+
// note: most significant word would be ((len-1)*8 >>> 32, but since JS converts
|
44
|
+
// bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
|
45
|
+
M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14])
|
46
|
+
M[N-1][15] = ((msg.length-1)*8) & 0xffffffff;
|
47
|
+
|
48
|
+
// set initial hash value [5.3.1]
|
49
|
+
var H0 = 0x67452301;
|
50
|
+
var H1 = 0xefcdab89;
|
51
|
+
var H2 = 0x98badcfe;
|
52
|
+
var H3 = 0x10325476;
|
53
|
+
var H4 = 0xc3d2e1f0;
|
54
|
+
|
55
|
+
// HASH COMPUTATION [6.1.2]
|
56
|
+
|
57
|
+
var W = new Array(80); var a, b, c, d, e;
|
58
|
+
for (var i=0; i<N; i++) {
|
59
|
+
|
60
|
+
// 1 - prepare message schedule 'W'
|
61
|
+
for (var t=0; t<16; t++) W[t] = M[i][t];
|
62
|
+
for (var t=16; t<80; t++) W[t] = ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
|
63
|
+
|
64
|
+
// 2 - initialise five working variables a, b, c, d, e with previous hash value
|
65
|
+
a = H0; b = H1; c = H2; d = H3; e = H4;
|
66
|
+
|
67
|
+
// 3 - main loop
|
68
|
+
for (var t=0; t<80; t++) {
|
69
|
+
var s = Math.floor(t/20); // seq for blocks of 'f' functions and 'K' constants
|
70
|
+
var T = (ROTL(a,5) + f(s,b,c,d) + e + K[s] + W[t]) & 0xffffffff;
|
71
|
+
e = d;
|
72
|
+
d = c;
|
73
|
+
c = ROTL(b, 30);
|
74
|
+
b = a;
|
75
|
+
a = T;
|
76
|
+
}
|
77
|
+
|
78
|
+
// 4 - compute the new intermediate hash value
|
79
|
+
H0 = (H0+a) & 0xffffffff; // note 'addition modulo 2^32'
|
80
|
+
H1 = (H1+b) & 0xffffffff;
|
81
|
+
H2 = (H2+c) & 0xffffffff;
|
82
|
+
H3 = (H3+d) & 0xffffffff;
|
83
|
+
H4 = (H4+e) & 0xffffffff;
|
84
|
+
}
|
85
|
+
|
86
|
+
return H0.toHexStr() + H1.toHexStr() + H2.toHexStr() + H3.toHexStr() + H4.toHexStr();
|
87
|
+
}
|
88
|
+
|
89
|
+
//
|
90
|
+
// extend Number class with a tailored hex-string method
|
91
|
+
// (note toString(16) is implementation-dependant, and
|
92
|
+
// in IE returns signed numbers when used on full words)
|
93
|
+
//
|
94
|
+
Number.prototype.toHexStr = function()
|
95
|
+
{
|
96
|
+
var s="", v;
|
97
|
+
for (var i=7; i>=0; i--) { v = (this>>>(i*4)) & 0xf; s += v.toString(16); }
|
98
|
+
return s;
|
99
|
+
}
|
data/resources/style.css
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
.uwa_files_list {
|
2
|
+
display: block;
|
3
|
+
margin: 2px;
|
4
|
+
padding: 2px;
|
5
|
+
}
|
6
|
+
|
7
|
+
.uwa_files_list LI {
|
8
|
+
margin: 2px;
|
9
|
+
padding-left: 20px;
|
10
|
+
background-repeat: no-repeat;
|
11
|
+
background-position: left center;
|
12
|
+
line-height: 16px;
|
13
|
+
height: 16px;
|
14
|
+
clear: both;
|
15
|
+
}
|
16
|
+
|
17
|
+
.uwa_files_list LI INPUT {
|
18
|
+
width: 80%;
|
19
|
+
border: 1px inset #999;
|
20
|
+
}
|
21
|
+
|
22
|
+
/* This prevent word wrapping */
|
23
|
+
.uwa_files_list LI A.file {
|
24
|
+
display: block;
|
25
|
+
float: left;
|
26
|
+
overflow: hidden;
|
27
|
+
white-space: nowrap;
|
28
|
+
margin: 0px;
|
29
|
+
padding: 0px;
|
30
|
+
line-height: 16px;
|
31
|
+
}
|
32
|
+
|
33
|
+
.uwa_files_list IMG {
|
34
|
+
vertical-align: bottom;
|
35
|
+
margin-right: 4px;
|
36
|
+
}
|
37
|
+
|
38
|
+
.uwa_files_list LI A.action {
|
39
|
+
display: block;
|
40
|
+
float: right;
|
41
|
+
}
|
42
|
+
|
43
|
+
.uwa_files_list A.action IMG {
|
44
|
+
margin: 0px 2px;
|
45
|
+
padding: 0px;
|
46
|
+
}
|
47
|
+
|
48
|
+
.uwa_files_list A {
|
49
|
+
border: none;
|
50
|
+
}
|
51
|
+
|
52
|
+
.uwa_files_footer {
|
53
|
+
clear: both;
|
54
|
+
background-color: #eee;
|
55
|
+
padding: 4px;
|
56
|
+
}
|
57
|
+
|
58
|
+
.uwa_files_list .parent {
|
59
|
+
display: block;
|
60
|
+
list-style-type: none;
|
61
|
+
background: none;
|
62
|
+
background-color: #eee;
|
63
|
+
line-height: 16px;
|
64
|
+
padding: 2px;
|
65
|
+
}
|
66
|
+
.uwa_files_list .parent A {
|
67
|
+
float: right;
|
68
|
+
display: block;
|
69
|
+
margin: 0px;
|
70
|
+
padding: 0px;
|
71
|
+
}
|
72
|
+
|
73
|
+
.uwa_files_message {
|
74
|
+
font-style: italic;
|
75
|
+
padding: 4px;
|
76
|
+
}
|
77
|
+
|
78
|
+
.uwa_files_footer IMG {
|
79
|
+
display: block;
|
80
|
+
float: right;
|
81
|
+
margin: 3px;
|
82
|
+
}
|
data/resources/upload.js
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
/*
|
2
|
+
* Inpired by http://www.webtoolkit.info/ajax-file-upload.html
|
3
|
+
*/
|
4
|
+
|
5
|
+
Uploader = {}
|
6
|
+
|
7
|
+
Uploader.submit = function(form, options) {
|
8
|
+
var iframe = widget.createElement('iframe');
|
9
|
+
iframe.setStyle('display', 'none');
|
10
|
+
iframe.src = 'about:blank';
|
11
|
+
iframe.id = 'uploader' + Math.floor(Math.random() * 100000);
|
12
|
+
iframe.name = iframe.id;
|
13
|
+
iframe.onload = function() {
|
14
|
+
Uploader.loaded(this);
|
15
|
+
}.bind(iframe);
|
16
|
+
form.appendChild(iframe);
|
17
|
+
if (options && typeof(options.onComplete) == 'function') {
|
18
|
+
iframe.onComplete = options.onComplete;
|
19
|
+
}
|
20
|
+
form.target = iframe.name;
|
21
|
+
|
22
|
+
if (options && typeof(options.onStart) == 'function') {
|
23
|
+
return options.onStart();
|
24
|
+
} else {
|
25
|
+
return true;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
Uploader.loaded = function(iframe) {
|
30
|
+
if (iframe.contentDocument) {
|
31
|
+
var doc = iframe.contentDocument;
|
32
|
+
} else if (iframe.contentWindow) {
|
33
|
+
var doc = iframe.contentWindow.document;
|
34
|
+
}
|
35
|
+
|
36
|
+
if (doc.location.href == "about:blank") {
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
|
40
|
+
if (typeof(iframe.onComplete) == 'function') {
|
41
|
+
iframe.onComplete(doc.body.innerHTML);
|
42
|
+
}
|
43
|
+
|
44
|
+
// iframe.parentNode.removeChild(iframe);
|
45
|
+
// delete iframe;
|
46
|
+
}
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: uwa_files
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.1"
|
7
|
+
date: 2007-04-12 00:00:00 +02:00
|
8
|
+
summary: UWA Files widget
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: florent@solt.biz
|
12
|
+
homepage: http://gnetvibes.rubyforge.org
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Florent Solt
|
31
|
+
files:
|
32
|
+
- lib/uwa_files/widget.rb
|
33
|
+
- lib/uwa_files/config.rb
|
34
|
+
- resources/parent.gif
|
35
|
+
- resources/script.js
|
36
|
+
- resources/sha1.js
|
37
|
+
- resources/style.css
|
38
|
+
- resources/upload.js
|
39
|
+
- resources/ajax.gif
|
40
|
+
- resources/del.png
|
41
|
+
- resources/rename.png
|
42
|
+
test_files: []
|
43
|
+
|
44
|
+
rdoc_options: []
|
45
|
+
|
46
|
+
extra_rdoc_files: []
|
47
|
+
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
requirements: []
|
53
|
+
|
54
|
+
dependencies:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: uwa
|
57
|
+
version_requirement:
|
58
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.0.0
|
63
|
+
version:
|