murlsh 0.11.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.htaccess +2 -0
- data/README.textile +3 -33
- data/Rakefile +12 -5
- data/VERSION +1 -1
- data/config.ru +10 -4
- data/config.yaml +6 -12
- data/lib/murlsh/dispatch.rb +0 -6
- data/lib/murlsh/img_store.rb +36 -0
- data/lib/murlsh/markup.rb +0 -1
- data/lib/murlsh/plugin.rb +2 -6
- data/lib/murlsh/uri_ask.rb +66 -22
- data/lib/murlsh/url.rb +0 -18
- data/lib/murlsh/url_body.rb +15 -23
- data/lib/murlsh/url_server.rb +5 -5
- data/murlsh.gemspec +44 -19
- data/plugins/add_post_50_update_feed.rb +17 -3
- data/plugins/add_post_50_update_podcast.rb +46 -0
- data/plugins/add_post_50_update_rss.rb +18 -2
- data/plugins/add_post_60_notify_hubs.rb +3 -1
- data/plugins/add_pre_40_convert_mobile.rb +30 -0
- data/plugins/add_pre_50_lookup_content_type_title.rb +11 -4
- data/plugins/add_pre_60_flickr.rb +38 -0
- data/plugins/add_pre_60_github_title.rb +5 -1
- data/plugins/add_pre_60_google_code_title.rb +5 -2
- data/plugins/add_pre_60_imageshack.rb +31 -0
- data/plugins/add_pre_60_imgur.rb +32 -0
- data/plugins/add_pre_60_s3_image.rb +34 -0
- data/plugins/add_pre_60_twitter.rb +35 -0
- data/plugins/add_pre_60_vimeo.rb +35 -0
- data/plugins/add_pre_60_youtube.rb +31 -0
- data/plugins/html_parse_50_hpricot.rb +2 -0
- data/plugins/url_display_add_45_mp3.rb +30 -0
- data/plugins/url_display_add_50_hostrec.rb +38 -0
- data/plugins/url_display_add_55_content_type.rb +27 -0
- data/plugins/url_display_add_60_via.rb +52 -0
- data/plugins/url_display_add_65_time.rb +22 -0
- data/public/css/jquery.jgrowl.css +0 -3
- data/public/css/screen.css +0 -18
- data/public/img/thumb/README +0 -0
- data/public/js/jquery-1.4.3.min.js +166 -0
- data/public/js/js.js +62 -234
- data/public/js/twitter-text-1.0.3.js +538 -0
- data/spec/img_store_spec.rb +53 -0
- data/spec/uri_ask_spec.rb +14 -4
- metadata +139 -37
- data/lib/murlsh/flickr_server.rb +0 -55
- data/lib/murlsh/twitter_server.rb +0 -45
- data/lib/murlsh/unwrap_jsonp.rb +0 -15
- data/lib/murlsh/xhtml_response.rb +0 -20
- data/plugins/hostrec_50_redundant.rb +0 -14
- data/plugins/hostrec_60_skip.rb +0 -24
- data/plugins/time_50_ago.rb +0 -16
- data/plugins/via_50_domain.rb +0 -36
- data/public/js/jquery-1.4.2.min.js +0 -154
- data/spec/unwrap_json_spec.rb +0 -21
- data/spec/xhtml_response_spec.rb +0 -112
data/public/js/js.js
CHANGED
@@ -3,35 +3,28 @@
|
|
3
3
|
"use strict";
|
4
4
|
|
5
5
|
var Murlsh = function (config, $, navigator, window) {
|
6
|
-
function compileRegexMap(regexMap) {
|
7
|
-
var result = {};
|
8
|
-
$.each(regexMap, function (reStr) {
|
9
|
-
result[reStr] = new RegExp('^' + reStr + '$', 'i');
|
10
|
-
});
|
11
|
-
|
12
|
-
return result;
|
13
|
-
}
|
14
6
|
|
15
7
|
var my = {},
|
16
8
|
hrefRes = {
|
17
|
-
flickr :
|
18
|
-
/^http:\/\/(?:www\.)?flickr\.com\/photos\/[@\w\-]+?\/([\d]+)/i,
|
19
9
|
imageshack :
|
20
|
-
/^
|
10
|
+
/^http:\/\/img\d+\.imageshack\.us\/img\d+\/\d+\/\w+\.jpe?g|gif|png$/i,
|
21
11
|
imgur :
|
22
|
-
/^
|
23
|
-
mp3 :
|
24
|
-
/\.mp3$/i,
|
12
|
+
/^http:\/\/(?:i\.)?imgur\.com\/[a-z\d]+\.(?:jpe?g|gif|png)$/i,
|
25
13
|
s3 :
|
26
|
-
/^
|
14
|
+
/^http:\/\/static\.mmb\.s3\.amazonaws\.com\/[\w\-]+\.(jpe?g|gif|pdf|png)$/i,
|
27
15
|
twitter :
|
28
|
-
/^https?:\/\/twitter\.com\/\w+\/status(?:es)
|
16
|
+
/^https?:\/\/twitter\.com\/\w+\/status(?:es)?\/\d+$/i,
|
29
17
|
vimeo :
|
30
18
|
/^http:\/\/(?:www\.)?vimeo\.com\/(\d+)$/i,
|
31
19
|
youtube :
|
32
20
|
/^http:\/\/(?:(?:www|uk)\.)?youtube\.com\/watch\?v=([\w\-]+)(?:&|$)/i
|
33
|
-
}
|
34
|
-
|
21
|
+
};
|
22
|
+
|
23
|
+
function setupClickHandler(jQueryObject, dataKey, dataValue, handler) {
|
24
|
+
if (!my.isIphone()) {
|
25
|
+
jQueryObject.data(dataKey, dataValue).click(handler);
|
26
|
+
}
|
27
|
+
}
|
35
28
|
|
36
29
|
function autoLink(s) {
|
37
30
|
// turn urls into links
|
@@ -42,8 +35,13 @@ var Murlsh = function (config, $, navigator, window) {
|
|
42
35
|
return result;
|
43
36
|
}
|
44
37
|
|
45
|
-
function
|
46
|
-
return
|
38
|
+
function makeIframe(src) {
|
39
|
+
return $('<iframe />').attr({
|
40
|
+
src: src,
|
41
|
+
width: 640,
|
42
|
+
height: 385,
|
43
|
+
frameborder: 0
|
44
|
+
});
|
47
45
|
}
|
48
46
|
|
49
47
|
function img(src, text) {
|
@@ -67,23 +65,6 @@ var Murlsh = function (config, $, navigator, window) {
|
|
67
65
|
}
|
68
66
|
}
|
69
67
|
|
70
|
-
function objectTag(data, height, width, params) {
|
71
|
-
// this does not use jQuery to build tags because building object
|
72
|
-
// tags is broken in IE
|
73
|
-
var result = '<object data="' + escapeXml(data) +
|
74
|
-
'" height="' + height +
|
75
|
-
'" type="application/x-shockwave-flash" width="' + width + '">';
|
76
|
-
|
77
|
-
$.each(params, function (i, v) {
|
78
|
-
result += '<param name="' + v.name + '" value="' +
|
79
|
-
escapeXml(v.value) + '" />';
|
80
|
-
});
|
81
|
-
|
82
|
-
result += '</object>';
|
83
|
-
|
84
|
-
return result;
|
85
|
-
}
|
86
|
-
|
87
68
|
function closerAdd(x, header) {
|
88
69
|
var html = (typeof x === 'object') ? $('<div />').append(x).html() : x;
|
89
70
|
|
@@ -97,116 +78,31 @@ var Murlsh = function (config, $, navigator, window) {
|
|
97
78
|
makeFit($(this), Math.round($(window).width() / 2),
|
98
79
|
Math.round($(window).height() - 100));
|
99
80
|
});
|
100
|
-
}
|
81
|
+
},
|
82
|
+
animateOpen : { width : 'show' },
|
83
|
+
animateClose : { width : 'hide' }
|
101
84
|
});
|
102
85
|
}
|
103
86
|
|
104
|
-
function
|
105
|
-
closerAdd(img($(
|
106
|
-
}
|
107
|
-
|
108
|
-
function flickrThumb(d) {
|
109
|
-
var base,
|
110
|
-
owner,
|
111
|
-
photo = d.photo,
|
112
|
-
zoom;
|
113
|
-
|
114
|
-
if (d.stat === 'ok') {
|
115
|
-
base = 'http://farm' + photo.farm + '.static.flickr.com/' +
|
116
|
-
photo.server + '/' + photo.id + '_';
|
117
|
-
zoom = base + photo.secret + '_m.jpg';
|
118
|
-
|
119
|
-
if (photo.originalsecret) {
|
120
|
-
zoom = base + photo.originalsecret + '_o.' +
|
121
|
-
photo.originalformat;
|
122
|
-
}
|
123
|
-
|
124
|
-
owner = photo.owner;
|
125
|
-
return img(base + photo.secret + '_s.jpg', photo.title._content +
|
126
|
-
(owner && owner.username ? ' by ' + owner.username : '')
|
127
|
-
).addClass('thumb flickr').data('zoom', zoom);
|
128
|
-
}
|
87
|
+
function imgClick(event) {
|
88
|
+
closerAdd(img($(event.target).data('href')));
|
129
89
|
}
|
130
90
|
|
131
|
-
function
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
function imgThumb() {
|
136
|
-
var i,
|
137
|
-
lastIndex,
|
138
|
-
urlParts = [];
|
139
|
-
|
140
|
-
for (i = 0; i < arguments.length; i += 1) {
|
141
|
-
urlParts.push(arguments[i]);
|
142
|
-
}
|
143
|
-
|
144
|
-
lastIndex = urlParts.length - 1;
|
145
|
-
|
146
|
-
// if pdf the thumbnail will be .png
|
147
|
-
if (urlParts[lastIndex].match(/^pdf$/i)) {
|
148
|
-
urlParts.splice(lastIndex, 1, 'png');
|
149
|
-
}
|
91
|
+
function vimeoClick(event) {
|
92
|
+
var iframe = makeIframe(
|
93
|
+
'http://player.vimeo.com/video/' + $(event.target).data('id'));
|
150
94
|
|
151
|
-
|
95
|
+
closerAdd(iframe);
|
152
96
|
}
|
153
97
|
|
154
|
-
function
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
img.click(clickFunction);
|
161
|
-
}
|
162
|
-
a.before(img);
|
163
|
-
}
|
164
|
-
}
|
165
|
-
}
|
166
|
-
|
167
|
-
function twitterAddLinks(s) {
|
168
|
-
// turn urls into links and Twitter usernames into links to Twitter
|
169
|
-
var result = autoLink(s);
|
170
|
-
|
171
|
-
result = result.replace(
|
172
|
-
/(^|[\s,(])@([0-9a-z_]+)($|[\s,.)])/gi,
|
173
|
-
'$1<a href="http://twitter.com/$2">@$2</a>$3');
|
174
|
-
|
175
|
-
return result;
|
176
|
-
}
|
177
|
-
|
178
|
-
function twitterThumb(d) {
|
179
|
-
return img(d.user.profile_image_url).addClass('thumb twitter');
|
180
|
-
}
|
181
|
-
|
182
|
-
function vimeoClick() {
|
183
|
-
closerAdd($(this).data('embedHtml'));
|
184
|
-
}
|
185
|
-
|
186
|
-
function vimeoThumb(d) {
|
187
|
-
return img(d.thumbnail_medium, d.title).addClass('thumb vimeo');
|
188
|
-
}
|
189
|
-
|
190
|
-
function youtubeClick() {
|
191
|
-
var movie = 'http://www.youtube.com/v/' + $(this).data('id') + '?' +
|
192
|
-
$.param({
|
193
|
-
fs : 1,
|
194
|
-
hd : 1,
|
195
|
-
hl : 'en',
|
196
|
-
iv_load_policy : 3,
|
197
|
-
showinfo : 0,
|
198
|
-
showsearch : 0
|
199
|
-
});
|
200
|
-
|
201
|
-
closerAdd(objectTag(movie, 505, 640, [{
|
202
|
-
name : 'movie',
|
203
|
-
value : movie
|
204
|
-
}]));
|
205
|
-
}
|
98
|
+
function youtubeClick(event) {
|
99
|
+
var iframe = makeIframe(
|
100
|
+
'http://www.youtube.com/embed/' + $(event.target).data('id')).attr({
|
101
|
+
'class': 'youtube-player',
|
102
|
+
type: 'text/html'
|
103
|
+
});
|
206
104
|
|
207
|
-
|
208
|
-
return img('http://img.youtube.com/vi/' + id + '/default.jpg',
|
209
|
-
'click to watch').addClass('thumb youtube').data('id', id);
|
105
|
+
closerAdd(iframe);
|
210
106
|
}
|
211
107
|
|
212
108
|
my.addComments = function (link, comments) {
|
@@ -240,111 +136,42 @@ var Murlsh = function (config, $, navigator, window) {
|
|
240
136
|
var thisA = $(this),
|
241
137
|
href = thisA.attr('href'),
|
242
138
|
match = {},
|
243
|
-
|
244
|
-
|
139
|
+
tweetMatch,
|
140
|
+
tweetLink,
|
141
|
+
formattedTweet;
|
245
142
|
|
246
143
|
$.each(hrefRes, function (x, re) {
|
247
144
|
return !(match[x] = re.exec(href));
|
248
145
|
});
|
249
146
|
|
250
|
-
if (match.
|
251
|
-
|
252
|
-
// url : 'http://api.flickr.com/services/rest/',
|
253
|
-
url : 'flickr',
|
254
|
-
data : {
|
255
|
-
format : 'json',
|
256
|
-
method : 'flickr.photos.getinfo',
|
257
|
-
photo_id : match.flickr[1]
|
258
|
-
},
|
259
|
-
dataType : 'jsonp',
|
260
|
-
jsonp : 'jsoncallback',
|
261
|
-
success : function (d) {
|
262
|
-
thumbInsert(flickrThumb(d), flickrClick, $(this));
|
263
|
-
},
|
264
|
-
context : thisA,
|
265
|
-
jsonpCallback : 'flickrCallback' + match.flickr[1]
|
266
|
-
});
|
267
|
-
} else if (match.imageshack) {
|
268
|
-
thumbInsert(imgThumb(match.imageshack[1], 'th.',
|
269
|
-
match.imageshack[2]).data('href', match.imageshack[0]),
|
270
|
-
imgClick, thisA.html('imageshack.us'));
|
271
|
-
} else if (match.imgur) {
|
272
|
-
thumbInsert(imgThumb(match.imgur[1], match.imgur[2], 's',
|
273
|
-
match.imgur[3]).data('href', match.imgur[0]), imgClick,
|
274
|
-
thisA.html('imgur/' + match.imgur[2] + match.imgur[3]));
|
275
|
-
} else if (match.mp3) {
|
276
|
-
thisA.before(objectTag(swf, 20, 200, [
|
277
|
-
{ name : 'bgcolor', value : '#000000' },
|
278
|
-
{ name : 'FlashVars', value : 'mp3=' + href },
|
279
|
-
{ name : 'movie', value : swf }
|
280
|
-
]));
|
147
|
+
if (match.imageshack || match.imgur) {
|
148
|
+
setupClickHandler(thisA.siblings('img'), 'href', href, imgClick);
|
281
149
|
} else if (match.s3) {
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
thisA.before(thumb).html('pdf');
|
286
|
-
} else {
|
287
|
-
if (my.isIphone()) {
|
288
|
-
thisA.html(thumb);
|
289
|
-
} else {
|
290
|
-
thisA.html('link');
|
291
|
-
thisA.before(thumb.data('href', match.s3[0]).click(
|
292
|
-
imgClick));
|
293
|
-
}
|
150
|
+
if (!(match.s3[1].match(/^pdf$/i))) {
|
151
|
+
setupClickHandler(thisA.siblings('img'), 'href', href,
|
152
|
+
imgClick);
|
294
153
|
}
|
295
154
|
} else if (match.twitter) {
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
thumbInsert(twitterThumb(d), null, nameLink);
|
312
|
-
|
313
|
-
$(this).replaceWith(tweet);
|
314
|
-
},
|
315
|
-
context : thisA,
|
316
|
-
jsonpCallback : 'twitterCallback' + match.twitter[1]
|
317
|
-
});
|
155
|
+
thisA.siblings('img').addClass('twitter');
|
156
|
+
tweetMatch = /^(@[0-9a-z_]+?): (.+)$/i.exec(thisA.text());
|
157
|
+
if (tweetMatch) {
|
158
|
+
tweetLink = $('<a />', {
|
159
|
+
href : href,
|
160
|
+
text : tweetMatch[1]
|
161
|
+
});
|
162
|
+
|
163
|
+
formattedTweet = $('<span />').addClass('tweet').append(
|
164
|
+
tweetLink).append(': ').append(
|
165
|
+
twttr.txt.autoLink(tweetMatch[2]));
|
166
|
+
|
167
|
+
thisA.replaceWith(formattedTweet);
|
168
|
+
}
|
318
169
|
} else if (match.vimeo) {
|
319
|
-
|
320
|
-
|
321
|
-
'.json',
|
322
|
-
dataType : 'jsonp',
|
323
|
-
success : function (d) {
|
324
|
-
var video = d[0],
|
325
|
-
movie = 'http://vimeo.com/moogaloop.swf?clip_id=' +
|
326
|
-
video.id;
|
327
|
-
|
328
|
-
thumbInsert(vimeoThumb(video).data('embedHtml',
|
329
|
-
objectTag(movie, video.height, video.width, [
|
330
|
-
{ name : 'movie', value : movie }
|
331
|
-
])), vimeoClick, $(this));
|
332
|
-
},
|
333
|
-
context : thisA,
|
334
|
-
jsonpCallback : 'vimeoCallback' + match.vimeo[1]
|
335
|
-
});
|
170
|
+
setupClickHandler(thisA.siblings('img'), 'id', match.vimeo[1],
|
171
|
+
vimeoClick);
|
336
172
|
} else if (match.youtube) {
|
337
|
-
|
338
|
-
|
339
|
-
$.each(config.thumb_locators, function (reStr) {
|
340
|
-
var re = thumbLocatorsCompiled[reStr];
|
341
|
-
if (href.match(re)) {
|
342
|
-
thumbInsert(img(href.replace(re,
|
343
|
-
config.thumb_locators[reStr])).addClass(
|
344
|
-
'thumb locator'), null, thisA);
|
345
|
-
return false;
|
346
|
-
}
|
347
|
-
});
|
173
|
+
setupClickHandler(thisA.siblings('img'), 'id', match.youtube[1],
|
174
|
+
youtubeClick);
|
348
175
|
}
|
349
176
|
};
|
350
177
|
|
@@ -425,7 +252,8 @@ $(document).ready(function () {
|
|
425
252
|
urls.each(murlsh.addExtra);
|
426
253
|
|
427
254
|
/*
|
428
|
-
// experimental comment support, to enable uncomment and edit
|
255
|
+
// experimental comment support, to enable uncomment and edit
|
256
|
+
// comments.json
|
429
257
|
$.getJSON('/js/comments.json', function (data) {
|
430
258
|
urls.each(function () {
|
431
259
|
var href = $(this).attr('href');
|