radiant-forum-extension 2.0.1 → 2.0.2
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/VERSION +1 -1
- data/app/controllers/forum_base_controller.rb +9 -1
- data/app/controllers/post_attachments_controller.rb +13 -0
- data/app/models/post_attachment.rb +1 -1
- data/app/views/forums/_standard_parts.html.haml +4 -2
- data/app/views/forums/_statistics.html.haml +26 -0
- data/app/views/posts/_attachment.html.haml +2 -2
- data/app/views/posts/_attachments.html.haml +2 -2
- data/app/views/topics/index.html.haml +1 -0
- data/config/locales/en.yml +3 -0
- data/config/routes.rb +1 -0
- data/forum_extension.rb +1 -1
- data/lib/commentable_model.rb +11 -0
- data/lib/forum_reader.rb +10 -0
- data/public/javascripts/forum.js +11 -23
- data/public/javascripts/gallery.js +249 -0
- data/public/stylesheets/sass/forum.sass +183 -111
- data/radiant-forum-extension.gemspec +5 -3
- metadata +7 -5
- data/public/javascripts/jquery.tools.min.js +0 -195
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.0.
|
|
1
|
+
2.0.2
|
|
@@ -4,6 +4,7 @@ class ForumBaseController < ReaderActionController
|
|
|
4
4
|
radiant_layout { |c| Radiant::Config['forum.layout'] || Radiant::Config['reader.layout'] }
|
|
5
5
|
before_filter :require_login_unless_public
|
|
6
6
|
before_filter :establish_context
|
|
7
|
+
after_filter :clear_site_cache, :only => [:create, :update, :destroy]
|
|
7
8
|
helper :forum, :reader
|
|
8
9
|
|
|
9
10
|
protected
|
|
@@ -54,7 +55,10 @@ protected
|
|
|
54
55
|
|
|
55
56
|
def render_page_or_feed(template_name = action_name)
|
|
56
57
|
respond_to do |format|
|
|
57
|
-
format.html {
|
|
58
|
+
format.html {
|
|
59
|
+
expires_in SiteController.cache_timeout, :public => true, :private => false
|
|
60
|
+
render :action => template_name
|
|
61
|
+
}
|
|
58
62
|
format.rss { render :action => template_name, :layout => 'feed' }
|
|
59
63
|
format.js { render :action => template_name, :layout => false }
|
|
60
64
|
end
|
|
@@ -75,4 +79,8 @@ protected
|
|
|
75
79
|
false
|
|
76
80
|
end
|
|
77
81
|
|
|
82
|
+
def clear_site_cache
|
|
83
|
+
Radiant::Cache.clear if defined?(Radiant::Cache)
|
|
84
|
+
end
|
|
85
|
+
|
|
78
86
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class PostAttachmentsController < ForumBaseController
|
|
2
|
+
|
|
3
|
+
# this simple controller exists for two reasons: to use sendfile for attachments (but it doesn't, yet)
|
|
4
|
+
# and to allow other extensions (ie group_forum) to restrict access to post attachments
|
|
5
|
+
|
|
6
|
+
def show
|
|
7
|
+
@attachment = PostAttachment.find(params[:id])
|
|
8
|
+
size = params[:size] || 'original'
|
|
9
|
+
expires_in SiteController.cache_timeout, :public => true, :private => false
|
|
10
|
+
send_file @attachment.file.path(size.to_sym), :type => @attachment.file_content_type, :disposition => 'inline'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -37,7 +37,7 @@ class PostAttachment < ActiveRecord::Base
|
|
|
37
37
|
},
|
|
38
38
|
:whiny_thumbnails => false,
|
|
39
39
|
:url => "/:class/:id/:basename:no_original_style.:extension",
|
|
40
|
-
:path => ":rails_root
|
|
40
|
+
:path => ":rails_root/:class/:id/:basename:no_original_style.:extension" # attachments can only be accessed through the PostAttachments controller, in case file security is required
|
|
41
41
|
|
|
42
42
|
attr_protected :file_file_name, :file_content_type, :file_file_size
|
|
43
43
|
validates_attachment_presence :file, :message => t('error.no_file')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
- add_reader_css '/stylesheets/
|
|
1
|
+
- add_reader_css '/stylesheets/forum.css'
|
|
2
2
|
- if current_reader
|
|
3
3
|
- if Radiant::Config['forum.toolbar?']
|
|
4
4
|
- add_reader_js '/punymce/puny_mce_src.js'
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
- add_reader_js '/punymce/plugins/editsource/editsource.js'
|
|
9
9
|
- add_reader_js '/punymce/plugins/paste.js'
|
|
10
10
|
- add_reader_js '/javascripts/forum.js'
|
|
11
|
-
|
|
11
|
+
- add_reader_js '/javascripts/gallery.js'
|
|
12
12
|
|
|
13
13
|
- content_for :section_navigation do
|
|
14
14
|
= link_to t('navigation.forum'), topics_url, :class => 'section'
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
= link_to t('navigation.new_topic'), new_post_url
|
|
19
19
|
- if current_reader
|
|
20
20
|
= link_to t('navigation.your_account'), reader_account_url
|
|
21
|
+
= link_to t('log_out'), reader_logout_url
|
|
21
22
|
- else
|
|
22
23
|
= link_to t('log_in'), reader_login_url
|
|
23
24
|
- if Radiant::Config['forum.help_url']
|
|
@@ -47,3 +48,4 @@
|
|
|
47
48
|
- content_for :newtopic do
|
|
48
49
|
.newmessage
|
|
49
50
|
= link_to t('new_topic'), new_post_url
|
|
51
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
%h2
|
|
2
|
+
= t('busy_topics')
|
|
3
|
+
%ul
|
|
4
|
+
- Topic.most_commented(10).each do |topic|
|
|
5
|
+
%li
|
|
6
|
+
= link_to topic.name, forum_topic_url(topic.forum, topic), :class => 'title'
|
|
7
|
+
= t('started_by')
|
|
8
|
+
= link_to(topic.reader.name, reader_url(topic.reader))
|
|
9
|
+
%br
|
|
10
|
+
= topic.posts.count
|
|
11
|
+
= t('posts') + ','
|
|
12
|
+
= t('most_recently')
|
|
13
|
+
= friendly_date(topic.replied_at) + '.'
|
|
14
|
+
|
|
15
|
+
%h2
|
|
16
|
+
= t('busy_readers')
|
|
17
|
+
%ul
|
|
18
|
+
- Reader.most_commenting(10).each do |reader|
|
|
19
|
+
%li
|
|
20
|
+
= link_to reader.name, reader_url(reader), :class => 'title'
|
|
21
|
+
= reader.posts.count
|
|
22
|
+
= t('posts') + ','
|
|
23
|
+
%br
|
|
24
|
+
= t('last_seen')
|
|
25
|
+
= time_ago_in_words(reader.posts.first.created_at)
|
|
26
|
+
= t('ago')
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
- af ||= false
|
|
2
2
|
%li
|
|
3
3
|
- if attachment.image?
|
|
4
|
-
= link_to image_tag(attachment
|
|
4
|
+
= link_to image_tag(post_attachment_url(attachment, :size => :thumbnail)), post_attachment_url(attachment), :class => 'thumbnail'
|
|
5
5
|
- else
|
|
6
|
-
= link_to attachment.filename, attachment
|
|
6
|
+
= link_to attachment.filename, post_attachment_url(attachment), :class => "attachment #{attachment.extension}"
|
|
7
7
|
- if af
|
|
8
8
|
= af.check_box :_destroy, :class => 'checkbox'
|
|
9
9
|
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
= t('attached') + ':'
|
|
5
5
|
- post.attachments.images.each do |att|
|
|
6
6
|
- display_size = Radiant::Config['forum.image_zoom_size'] || :original
|
|
7
|
-
= link_to image_tag(att
|
|
7
|
+
= link_to image_tag(post_attachment_url(att, :size => :thumbnail)), post_attachment_url(att, :size => display_size), :class => :thumbnail, :rel => post_attachment_url(att, :size => :original)
|
|
8
8
|
- if post.attachments.non_images.any?
|
|
9
9
|
%ul.attachments
|
|
10
10
|
- post.attachments.non_images.each do |att|
|
|
11
11
|
%li
|
|
12
|
-
= link_to att.filename, att
|
|
12
|
+
= link_to att.filename, post_attachment_url(att), :class => "attachment #{att.extension}"
|
|
13
13
|
|
data/config/locales/en.yml
CHANGED
|
@@ -10,6 +10,8 @@ en:
|
|
|
10
10
|
attach_file: "attach a file"
|
|
11
11
|
author: "author"
|
|
12
12
|
begun_on: "begun on %{date}"
|
|
13
|
+
busy_topics: "Biggest topics"
|
|
14
|
+
busy_readers: "Biggest talkers"
|
|
13
15
|
by: "by"
|
|
14
16
|
by_content_and_author: "by content, author or category."
|
|
15
17
|
comment: "comment"
|
|
@@ -68,6 +70,7 @@ en:
|
|
|
68
70
|
name: "Discussion title"
|
|
69
71
|
sticky: "Sticky"
|
|
70
72
|
locked: "Locked"
|
|
73
|
+
last_seen: "last here"
|
|
71
74
|
latest_activity: "latest activity"
|
|
72
75
|
latest_discussion: "Latest topics"
|
|
73
76
|
latest_posts: "Latest comments"
|
data/config/routes.rb
CHANGED
|
@@ -3,6 +3,7 @@ ActionController::Routing::Routes.draw do |map|
|
|
|
3
3
|
forum.resources :forums, :only => [:index, :show], :has_many => [:topics]
|
|
4
4
|
forum.resources :topics, :only => [:index, :show], :has_many => [:posts]
|
|
5
5
|
forum.resources :posts, :member => { :remove => :get }
|
|
6
|
+
forum.resources :post_attachments, :only => [:show]
|
|
6
7
|
end
|
|
7
8
|
|
|
8
9
|
map.namespace :admin, :member => { :remove => :get }, :path_prefix => 'admin/forum' do |admin|
|
data/forum_extension.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require_dependency 'application_controller'
|
|
2
2
|
|
|
3
3
|
class ForumExtension < Radiant::Extension
|
|
4
|
-
version "2.0.
|
|
4
|
+
version "2.0.2"
|
|
5
5
|
description "Nice clean forums and page comments for inclusion in your radiant site. Requires the reader extension and share_layouts."
|
|
6
6
|
url "http://spanner.org/radiant/forum"
|
|
7
7
|
|
data/lib/commentable_model.rb
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
module CommentableModel # for inclusion into ActiveRecord::Base
|
|
2
2
|
def self.included(base)
|
|
3
3
|
base.extend ClassMethods
|
|
4
|
+
base.class_eval do
|
|
5
|
+
named_scope :most_commented, lambda { |count|
|
|
6
|
+
{
|
|
7
|
+
:select => "topics.*, count(posts.id) AS post_count",
|
|
8
|
+
:joins => "INNER JOIN posts ON posts.topic_id = topics.id",
|
|
9
|
+
:group => "topics.id",
|
|
10
|
+
:order => "post_count DESC",
|
|
11
|
+
:limit => count
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
end
|
|
4
15
|
end
|
|
5
16
|
|
|
6
17
|
module ClassMethods
|
data/lib/forum_reader.rb
CHANGED
|
@@ -4,6 +4,16 @@ module ForumReader
|
|
|
4
4
|
base.class_eval {
|
|
5
5
|
has_many :topics, :dependent => :nullify
|
|
6
6
|
has_many :posts, :order => 'posts.created_at desc', :dependent => :nullify
|
|
7
|
+
|
|
8
|
+
named_scope :most_commenting, lambda { |count|
|
|
9
|
+
{
|
|
10
|
+
:select => "readers.*, count(posts.id) AS post_count",
|
|
11
|
+
:joins => "INNER JOIN posts ON posts.reader_id = readers.id",
|
|
12
|
+
:group => "readers.id",
|
|
13
|
+
:order => "post_count DESC",
|
|
14
|
+
:limit => count
|
|
15
|
+
}
|
|
16
|
+
}
|
|
7
17
|
}
|
|
8
18
|
end
|
|
9
19
|
end
|
data/public/javascripts/forum.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
2
|
Sample jquery-based forum scripts.
|
|
3
3
|
|
|
4
|
-
Two functions are handled here:
|
|
5
4
|
* inline editing of posts by authors and administrators.
|
|
6
5
|
* attachment and upload of files.
|
|
6
|
+
* simple show and hide for first post
|
|
7
|
+
* toolbar hookup
|
|
8
|
+
* submit-button protection
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
11
|
(function($) {
|
|
@@ -153,21 +155,14 @@
|
|
|
153
155
|
});
|
|
154
156
|
}
|
|
155
157
|
|
|
156
|
-
$.tools.post = {
|
|
157
|
-
conf: {
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
|
|
162
158
|
$.fn.editable_post = function(conf) {
|
|
163
|
-
conf = $.extend({}, $.tools.post.conf, conf);
|
|
164
159
|
this.each(function() {
|
|
165
160
|
new EditablePost($(this), conf);
|
|
166
161
|
});
|
|
167
162
|
return this;
|
|
168
163
|
};
|
|
169
164
|
|
|
170
|
-
function
|
|
165
|
+
function HideablePost(container, conf) {
|
|
171
166
|
var self = this;
|
|
172
167
|
$.extend(self, {
|
|
173
168
|
head: container.find('.post_header'),
|
|
@@ -175,11 +170,11 @@
|
|
|
175
170
|
shower: null,
|
|
176
171
|
show: function () {
|
|
177
172
|
self.body.slideDown();
|
|
178
|
-
self.shower.text('Hide
|
|
173
|
+
self.shower.text('Hide');
|
|
179
174
|
},
|
|
180
175
|
hide: function () {
|
|
181
176
|
self.body.slideUp();
|
|
182
|
-
self.shower.text('Show
|
|
177
|
+
self.shower.text('Show');
|
|
183
178
|
},
|
|
184
179
|
toggle: function (event) {
|
|
185
180
|
squash(event);
|
|
@@ -188,14 +183,14 @@
|
|
|
188
183
|
}
|
|
189
184
|
});
|
|
190
185
|
|
|
191
|
-
self.shower = $('<a href="#" class="shower">Hide
|
|
186
|
+
self.shower = $('<a href="#" class="shower">Hide</a>').appendTo(self.head.find('p.context'));
|
|
192
187
|
self.shower.click(self.toggle);
|
|
193
188
|
if ($('a.prev_page').length > 0) self.hide();
|
|
194
189
|
}
|
|
195
190
|
|
|
196
|
-
$.fn.
|
|
191
|
+
$.fn.hideable_post = function() {
|
|
197
192
|
this.each(function() {
|
|
198
|
-
new
|
|
193
|
+
new HideablePost($(this));
|
|
199
194
|
});
|
|
200
195
|
return this;
|
|
201
196
|
};
|
|
@@ -215,7 +210,7 @@
|
|
|
215
210
|
addUpload: function(event) {
|
|
216
211
|
squash(event);
|
|
217
212
|
var upload_field = self.file_field.clone();
|
|
218
|
-
var nest_id = self.uploadCount() +
|
|
213
|
+
var nest_id = self.attachmentCount() + self.uploadCount(); // nb. starts at zero so this total is +1
|
|
219
214
|
var container = $('<li class="attachment">' + upload_field.val() + '</li>');
|
|
220
215
|
upload_field.attr("id", upload_field.attr('id').replace(/\d+/, nest_id));
|
|
221
216
|
upload_field.attr("name", upload_field.attr('name').replace(/\d+/, nest_id));
|
|
@@ -245,15 +240,8 @@
|
|
|
245
240
|
self.attachments_list.find('li').add_remover();
|
|
246
241
|
self.file_field.change(self.addUpload);
|
|
247
242
|
}
|
|
248
|
-
|
|
249
|
-
$.tools.stack = {
|
|
250
|
-
conf: {
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
243
|
|
|
255
244
|
$.fn.upload_stack = function(conf) {
|
|
256
|
-
conf = $.extend({}, $.tools.stack.conf, conf);
|
|
257
245
|
this.each(function() {
|
|
258
246
|
el = new UploadStack($(this), conf);
|
|
259
247
|
});
|
|
@@ -442,7 +430,7 @@
|
|
|
442
430
|
|
|
443
431
|
$(function() {
|
|
444
432
|
$(".post").editable_post({});
|
|
445
|
-
$(".post.first").
|
|
433
|
+
$(".post.first").hideable_post({});
|
|
446
434
|
$(".upload_stack").upload_stack({});
|
|
447
435
|
$(".toolbarred").add_editor({});
|
|
448
436
|
$("input:submit").live('click', function (event) {
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
(function($) {
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Some easing functions borrowed from the effects library to save loading the whole lot.
|
|
5
|
+
* Glide is really quartic out. Boing is back out. Bounce is bounce out.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
$.easing.glide = function (x, t, b, c, d) {
|
|
9
|
+
return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
$.easing.boing = function (x, t, b, c, d, s) {
|
|
13
|
+
if (s == undefined) s = 1.70158;
|
|
14
|
+
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function Gallery() {
|
|
18
|
+
var self = this;
|
|
19
|
+
var container = $('<div class="gallery"><img class="preview" /><p class="caption" /><div class="controls"><a href="#" class="previous" /><a href="#" class="download" /><a href="#" class="next" /></a></div><div class="closer"><a href="#" /></div></div>').hide().appendTo($('body'));
|
|
20
|
+
$.extend(self, {
|
|
21
|
+
container: container,
|
|
22
|
+
zoomer: new Zoomer(),
|
|
23
|
+
image: container.find('img.preview'),
|
|
24
|
+
caption: container.find('p.caption'),
|
|
25
|
+
controls: container.find('div.controls'),
|
|
26
|
+
closer: container.find('div.closer'),
|
|
27
|
+
stack: [],
|
|
28
|
+
item: null,
|
|
29
|
+
add: function (a) {
|
|
30
|
+
self.stack.push(new GalleryItem(a));
|
|
31
|
+
},
|
|
32
|
+
display: function (item) {
|
|
33
|
+
self.item = item;
|
|
34
|
+
if (self.visible()) self.crossfade();
|
|
35
|
+
else self.zoomUp();
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
mimic: function () {
|
|
39
|
+
self.zoomer.setImage(self.item.src);
|
|
40
|
+
self.image.attr('src', self.item.src);
|
|
41
|
+
if (self.item.caption.html()) self.caption.html(self.item.caption.html()).show();
|
|
42
|
+
else self.caption.hide();
|
|
43
|
+
},
|
|
44
|
+
zoomUp: function () {
|
|
45
|
+
self.hide();
|
|
46
|
+
self.mimic();
|
|
47
|
+
self.zoomer.zoomUp(self.item, self.show);
|
|
48
|
+
},
|
|
49
|
+
zoomDown: function () {
|
|
50
|
+
self.zoomer.zoomDown(self.item);
|
|
51
|
+
self.hide();
|
|
52
|
+
},
|
|
53
|
+
crossfade: function () {
|
|
54
|
+
self.fadeDown(self.fadeUp);
|
|
55
|
+
},
|
|
56
|
+
fadeDown: function (onFade) {
|
|
57
|
+
self.caption.fadeTo('fast', 0.2);
|
|
58
|
+
self.image.fadeTo('fast', 0.2, onFade);
|
|
59
|
+
},
|
|
60
|
+
fadeUp: function (onFade) {
|
|
61
|
+
self.mimic();
|
|
62
|
+
self.resize();
|
|
63
|
+
self.caption.fadeTo('fast', 1);
|
|
64
|
+
self.image.fadeTo('fast', 1, onFade);
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
current: function () {
|
|
68
|
+
return self.stack.indexOf(self.item);
|
|
69
|
+
},
|
|
70
|
+
next: function (e) {
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
var at = self.current();
|
|
73
|
+
var next = (at == self.stack.length-1) ? 0 : at + 1;
|
|
74
|
+
self.display(self.stack[next]);
|
|
75
|
+
},
|
|
76
|
+
previous: function (e) {
|
|
77
|
+
e.preventDefault();
|
|
78
|
+
var at = self.current();
|
|
79
|
+
var previous = (at == 0) ? self.stack.length-1 : at - 1;
|
|
80
|
+
self.display(self.stack[previous]);
|
|
81
|
+
},
|
|
82
|
+
close: function (e) {
|
|
83
|
+
e.preventDefault();
|
|
84
|
+
self.zoomDown();
|
|
85
|
+
},
|
|
86
|
+
show: function () {
|
|
87
|
+
self.zoomer.hide();
|
|
88
|
+
self.container.show();
|
|
89
|
+
},
|
|
90
|
+
hide: function () {
|
|
91
|
+
self.container.hide();
|
|
92
|
+
},
|
|
93
|
+
visible: function () {
|
|
94
|
+
return self.container.is(':visible');
|
|
95
|
+
},
|
|
96
|
+
showControls: function (e) {
|
|
97
|
+
self.controls.fadeIn("fast");
|
|
98
|
+
self.closer.fadeIn("fast");
|
|
99
|
+
self.controls.find('a.download').attr('href', self.item.download_url());
|
|
100
|
+
},
|
|
101
|
+
hideControls: function (e) {
|
|
102
|
+
self.controls.fadeOut("fast");
|
|
103
|
+
self.closer.fadeOut("fast");
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
resize: function (item) {
|
|
107
|
+
if (!item) item = self.item;
|
|
108
|
+
var w = $(window);
|
|
109
|
+
var d = item.imageSize();
|
|
110
|
+
var p = self.container.offset();
|
|
111
|
+
self.image.animate(d, 'fast');
|
|
112
|
+
self.container.animate({
|
|
113
|
+
left: p.left + (self.image.innerWidth() - d.width)/2,
|
|
114
|
+
top: p.top + (self.image.innerHeight() - d.height)/2
|
|
115
|
+
}, 'fast');
|
|
116
|
+
self.controls.css({left: (d.width - 96)/2});
|
|
117
|
+
},
|
|
118
|
+
reposition: function (item) {
|
|
119
|
+
if (!item) item = self.item;
|
|
120
|
+
var w = $(window);
|
|
121
|
+
var d = item.imageSize();
|
|
122
|
+
var p = {
|
|
123
|
+
top: w.scrollTop() + (w.height() - d.height)/2,
|
|
124
|
+
left: w.scrollLeft() + (w.width() - d.width)/2
|
|
125
|
+
};
|
|
126
|
+
if (self.visible) {
|
|
127
|
+
self.image.animate(d, 'fast');
|
|
128
|
+
self.container.animate(p, 'fast');
|
|
129
|
+
} else {
|
|
130
|
+
self.image.css(d);
|
|
131
|
+
self.container.css(p);
|
|
132
|
+
}
|
|
133
|
+
self.controls.css({left: (d.width - 96)/2});
|
|
134
|
+
return $.extend(d,p);
|
|
135
|
+
},
|
|
136
|
+
currentPosition: function () {
|
|
137
|
+
var p = self.container.offset();
|
|
138
|
+
return {
|
|
139
|
+
left: p.left,
|
|
140
|
+
top: p.top,
|
|
141
|
+
width: self.image.innerWidth(),
|
|
142
|
+
height: self.image.innerHeight()
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
self.closer.find('a').click(self.close);
|
|
148
|
+
self.controls.find('a.previous').click(self.previous);
|
|
149
|
+
self.controls.find('a.next').click(self.next);
|
|
150
|
+
self.container.hover(self.showControls, self.hideControls);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
function Zoomer() {
|
|
154
|
+
var self = this;
|
|
155
|
+
var sprite = $('<img class="grower" />').hide().appendTo($('body'));
|
|
156
|
+
$.extend(self, {
|
|
157
|
+
sprite: sprite,
|
|
158
|
+
defaultUpState: {position: 'absolute', opacity: 1, borderLeftWidth: 20, borderRightWidth: 20, borderTopWidth: 20, borderBottomWidth: 20},
|
|
159
|
+
defaultDownState: {position: 'absolute', opacity: 0, borderLeftWidth: 4, borderRightWidth: 4, borderTopWidth: 4, borderBottomWidth: 4},
|
|
160
|
+
zoomDuration: 'slow',
|
|
161
|
+
setImage: function (src) {
|
|
162
|
+
self.sprite.attr('src', src);
|
|
163
|
+
},
|
|
164
|
+
zoomUp: function (item, onZoom) {
|
|
165
|
+
if (!onZoom) onZoom = self.hide;
|
|
166
|
+
self.sprite.css($.extend(self.defaultDownState, item.position()));
|
|
167
|
+
self.show();
|
|
168
|
+
self.sprite.animate($.extend({}, self.defaultUpState, $.gallery.reposition()), self.zoomDuration, onZoom);
|
|
169
|
+
},
|
|
170
|
+
zoomDown: function (item, onZoom) {
|
|
171
|
+
if (!onZoom) onZoom = self.hide;
|
|
172
|
+
self.show();
|
|
173
|
+
self.sprite.css($.extend(self.defaultUpState, $.gallery.currentPosition()));
|
|
174
|
+
self.sprite.animate($.extend({}, self.defaultDownState, item.position()), self.zoomDuration, onZoom);
|
|
175
|
+
},
|
|
176
|
+
show: function () {
|
|
177
|
+
self.sprite.show();
|
|
178
|
+
},
|
|
179
|
+
hide: function () {
|
|
180
|
+
self.sprite.hide();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
function GalleryItem(a) {
|
|
187
|
+
var self = this;
|
|
188
|
+
var link = $(a);
|
|
189
|
+
$.extend(self, {
|
|
190
|
+
link: link,
|
|
191
|
+
thumb: link.find('img'),
|
|
192
|
+
image: $('<img class="preloader" />').css({visibility: 'hidden'}).appendTo($('body')),
|
|
193
|
+
caption: link.next('.caption'),
|
|
194
|
+
src: link.attr('href'),
|
|
195
|
+
deactivate: function (event) {
|
|
196
|
+
self.thumb.fadeTo('slow', 0.3);
|
|
197
|
+
self.thumb.css('cursor', 'text');
|
|
198
|
+
self.image.bind("load", self.activate);
|
|
199
|
+
self.image.attr('src', self.src);
|
|
200
|
+
},
|
|
201
|
+
activate: function () {
|
|
202
|
+
self.thumb.fadeTo('slow', 1);
|
|
203
|
+
self.thumb.css('cursor', 'pointer');
|
|
204
|
+
self.link.click(function (e) {
|
|
205
|
+
if (e) {
|
|
206
|
+
e.preventDefault();
|
|
207
|
+
e.stopPropagation();
|
|
208
|
+
}
|
|
209
|
+
$.gallery.display(self);
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
position: function () {
|
|
213
|
+
var p = self.thumb.offset();
|
|
214
|
+
return {
|
|
215
|
+
left: p.left,
|
|
216
|
+
top: p.top,
|
|
217
|
+
width: self.thumb.outerWidth(),
|
|
218
|
+
height: self.thumb.outerHeight()
|
|
219
|
+
};
|
|
220
|
+
},
|
|
221
|
+
imageSize: function () {
|
|
222
|
+
return {
|
|
223
|
+
width: self.image.innerWidth(),
|
|
224
|
+
height: self.image.innerHeight()
|
|
225
|
+
};
|
|
226
|
+
},
|
|
227
|
+
download_url: function () {
|
|
228
|
+
return self.link.attr('rel');
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
if (!self.image.complete) {
|
|
232
|
+
self.deactivate();
|
|
233
|
+
} else {
|
|
234
|
+
self.activate();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
$.fn.galleried = function() {
|
|
239
|
+
this.each(function() {
|
|
240
|
+
if (!$.gallery) $.gallery = new Gallery();
|
|
241
|
+
$.gallery.add(this);
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
})(jQuery);
|
|
246
|
+
|
|
247
|
+
$(function() {
|
|
248
|
+
$("a.thumbnail").galleried();
|
|
249
|
+
});
|