murlsh 0.11.0 → 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/.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');
|