refinerycms-project_portfolios 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/app/controllers/admin/project_portfolios_controller.rb +8 -0
  2. data/app/controllers/project_portfolios_controller.rb +33 -0
  3. data/app/helpers/project_portfolio_helper.rb +17 -0
  4. data/app/models/project_portfolio.rb +12 -0
  5. data/app/views/admin/project_portfolios/_actions.html.erb +28 -0
  6. data/app/views/admin/project_portfolios/_form.html.erb +86 -0
  7. data/app/views/admin/project_portfolios/_project_portfolio.html.erb +18 -0
  8. data/app/views/admin/project_portfolios/_project_portfolios.html.erb +2 -0
  9. data/app/views/admin/project_portfolios/_records.html.erb +18 -0
  10. data/app/views/admin/project_portfolios/_sortable_list.html.erb +7 -0
  11. data/app/views/admin/project_portfolios/edit.html.erb +1 -0
  12. data/app/views/admin/project_portfolios/index.html.erb +10 -0
  13. data/app/views/admin/project_portfolios/new.html.erb +1 -0
  14. data/app/views/project_portfolios/_popup_portfolio.html.erb +14 -0
  15. data/app/views/project_portfolios/index.html.erb +68 -0
  16. data/app/views/project_portfolios/show.html.erb +51 -0
  17. data/config/locales/en.yml +25 -0
  18. data/config/locales/fr.yml +25 -0
  19. data/config/locales/lolcat.yml +25 -0
  20. data/config/locales/nb.yml +21 -0
  21. data/config/locales/nl.yml +21 -0
  22. data/config/routes.rb +11 -0
  23. data/db/migrate/create_project_portfolios.rb +34 -0
  24. data/db/seeds/project_portfolios.rb +21 -0
  25. data/lib/generators/refinerycms_project_portfolios_generator.rb +6 -0
  26. data/lib/refinerycms-project_portfolios.rb +30 -0
  27. data/lib/tasks/project_portfolios.rake +13 -0
  28. data/public/images/close_yellow_icon.png +0 -0
  29. data/public/javascripts/jquery.bpopup.js +10 -0
  30. data/public/javascripts/jquery.easing.js +205 -0
  31. data/public/javascripts/jquery.quicksand.js +307 -0
  32. data/public/stylesheets/portfolio.css +130 -0
  33. metadata +125 -0
@@ -0,0 +1,25 @@
1
+ lolcat:
2
+ shared:
3
+ admin:
4
+ image_picker:
5
+ image: IMAGE
6
+ plugins:
7
+ project_portfolios:
8
+ title: Project Portfolios
9
+ admin:
10
+ project_portfolios:
11
+ actions:
12
+ create_new: CREATE NEW Project Portfolio
13
+ reorder: REORDR Project Portfolios
14
+ reorder_done: DUN REORDERIN Project Portfolios
15
+ records:
16
+ title: Project Portfolios
17
+ sorry_no_results: SRY! THAR R NO RESULTS FINDZ.
18
+ no_items_yet: THAR R NO Project Portfolios YET. CLICK "CREATE NEW Project Portfolio" 2 ADD UR FURST project portfolio.
19
+ project_portfolio:
20
+ view_live_html: VIEW DIS project portfolio LIV <BR/><EM>(OPENS IN NEW WINDOW)</EM>
21
+ edit: EDIT DIS project portfolio
22
+ delete: REMOOV DIS project portfolio FOREVR
23
+ project_portfolios:
24
+ show:
25
+ other: OTHR Project Portfolios
@@ -0,0 +1,21 @@
1
+ nb:
2
+ plugins:
3
+ project_portfolios:
4
+ title: Project Portfolios
5
+ admin:
6
+ project_portfolios:
7
+ actions:
8
+ create_new: Lag en ny Project Portfolio
9
+ reorder: Endre rekkefølgen på Project Portfolios
10
+ reorder_done: Ferdig å endre rekkefølgen Project Portfolios
11
+ records:
12
+ title: Project Portfolios
13
+ sorry_no_results: Beklager! Vi fant ikke noen resultater.
14
+ no_items_yet: Det er ingen Project Portfolios enda. Klikk på "Lag en ny Project Portfolio" for å legge til din første project portfolio.
15
+ project_portfolio:
16
+ view_live_html: Vis hvordan denne project portfolio ser ut offentlig <br/><em>(åpner i et nytt vindu)</em>
17
+ edit: Rediger denne project portfolio
18
+ delete: Fjern denne project portfolio permanent
19
+ project_portfolios:
20
+ show:
21
+ other: Andre Project Portfolios
@@ -0,0 +1,21 @@
1
+ nl:
2
+ plugins:
3
+ project_portfolios:
4
+ title: Project Portfolios
5
+ admin:
6
+ project_portfolios:
7
+ actions:
8
+ create_new: Maak een nieuwe Project Portfolio
9
+ reorder: Wijzig de volgorde van de Project Portfolios
10
+ reorder_done: Klaar met het wijzingen van de volgorde van de Project Portfolios
11
+ records:
12
+ title: Project Portfolios
13
+ sorry_no_results: Helaas! Er zijn geen resultaten gevonden.
14
+ no_items_yet: Er zijn nog geen Project Portfolios. Druk op 'Maak een nieuwe Project Portfolio' om de eerste aan te maken.
15
+ project_portfolio:
16
+ view_live_html: Bekijk deze project portfolio op de website <br/><em>(opent een nieuw venster)</em>
17
+ edit: Bewerk deze project portfolio
18
+ delete: Verwijder deze project portfolio voor eeuwig
19
+ project_portfolios:
20
+ show:
21
+ other: Andere Project Portfolios
data/config/routes.rb ADDED
@@ -0,0 +1,11 @@
1
+ ::Refinery::Application.routes.draw do
2
+ resources :project_portfolios, :only => [:index, :show]
3
+
4
+ scope(:path => 'refinery', :as => 'admin', :module => 'admin') do
5
+ resources :project_portfolios, :except => :show do
6
+ collection do
7
+ post :update_positions
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ class CreateProjectPortfolios < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ create_table :project_portfolios do |t|
5
+ t.string :project_name
6
+ t.string :title
7
+ t.integer :thumbnail_id
8
+ t.string :thumbnail_url
9
+ t.integer :image_id
10
+ t.string :image_url
11
+ t.text :description
12
+ t.integer :position
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ add_index :project_portfolios, :id
18
+
19
+ load(Rails.root.join('db', 'seeds', 'project_portfolios.rb'))
20
+ end
21
+
22
+ def self.down
23
+ if defined?(UserPlugin)
24
+ UserPlugin.destroy_all({:name => "project_portfolios"})
25
+ end
26
+
27
+ if defined?(Page)
28
+ Page.delete_all({:link_url => "/project_portfolios"})
29
+ end
30
+
31
+ drop_table :project_portfolios
32
+ end
33
+
34
+ end
@@ -0,0 +1,21 @@
1
+ if defined?(User)
2
+ User.all.each do |user|
3
+ if user.plugins.where(:name => 'project_portfolios').blank?
4
+ user.plugins.create(:name => 'project_portfolios',
5
+ :position => (user.plugins.maximum(:position) || -1) +1)
6
+ end
7
+ end
8
+ end
9
+
10
+ if defined?(Page)
11
+ page = Page.create(
12
+ :title => 'Project Portfolios',
13
+ :link_url => '/project_portfolios',
14
+ :deletable => false,
15
+ :position => ((Page.maximum(:position, :conditions => {:parent_id => nil}) || -1)+1),
16
+ :menu_match => '^/project_portfolios(\/|\/.+?|)$'
17
+ )
18
+ Page.default_parts.each do |default_page_part|
19
+ page.parts.create(:title => default_page_part, :body => nil)
20
+ end
21
+ end
@@ -0,0 +1,6 @@
1
+ class RefinerycmsProjectPortfolios < Refinery::Generators::EngineInstaller
2
+
3
+ source_root File.expand_path('../../../', __FILE__)
4
+ engine_name "project_portfolios"
5
+
6
+ end
@@ -0,0 +1,30 @@
1
+ require 'refinerycms-base'
2
+
3
+ module Refinery
4
+ module ProjectPortfolios
5
+
6
+ class << self
7
+ attr_accessor :root
8
+ def root
9
+ @root ||= Pathname.new(File.expand_path('../../', __FILE__))
10
+ end
11
+ end
12
+
13
+ class Engine < Rails::Engine
14
+ initializer "static assets" do |app|
15
+ app.middleware.insert_after ::ActionDispatch::Static, ::ActionDispatch::Static, "#{root}/public"
16
+ end
17
+
18
+ config.after_initialize do
19
+ Refinery::Plugin.register do |plugin|
20
+ plugin.name = "project_portfolios"
21
+ plugin.pathname = root
22
+ plugin.activity = {
23
+ :class => ProjectPortfolio,
24
+ :title => 'project_name'
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ namespace :refinery do
2
+
3
+ namespace :project_portfolios do
4
+
5
+ # call this task my running: rake refinery:project_portfolios:my_task
6
+ # desc "Description of my task below"
7
+ # task :my_task => :environment do
8
+ # # add your logic here
9
+ # end
10
+
11
+ end
12
+
13
+ end
Binary file
@@ -0,0 +1,10 @@
1
+ /************************************************************************
2
+ * @name: bPopup
3
+ * @author: Bjoern Klinggaard (http://dinbror.dk/bpopup)
4
+ * @version: 0.3.6.min
5
+ ************************************************************************/
6
+ (function(a){a.fn.openPopup=function(f,i){function s(){var b=a("input[type=text]",c).length!=0,j=o.vStart!=null?o.vStart:d.scrollTop()+g;if(o.xLink){a("a#bContinue").attr({href:a("a.xlink").attr("href")});a("a#bContinue .btnLink").text(a("a.xlink").attr("title"))}c.css({left:d.scrollLeft()+h,position:"absolute",top:j,"z-index":o.zIndex}).appendTo(o.appendTo).hide(function(){b&&c.each(function(){c.find("input[type=text]").val("")});o.loadUrl!=null&&c.load(o.loadUrl)}).fadeIn(o.fadeSpeed,function(){b&&
7
+ c.find("input[type=text]:first").focus();a.isFunction(i)&&i()});t()}function l(){o.modal&&a("#bModal").fadeOut(o.fadeSpeed,function(){a("#bModal").remove()});c.fadeOut(o.fadeSpeed,function(){o.loadUrl!=null&&c.empty()});o.scrollBar||a("html").css("overflow","auto");a("."+o.closeClass).die("click");d.unbind("keydown.bPopup");e.unbind(".bPopup")}function u(){if(m){var b=[d.height(),d.width()];return{"background-color":o.modalColor,height:b[0],left:k(),opacity:0,position:"absolute",top:0,width:b[1],
8
+ "z-index":o.zIndex-1}}else return{"background-color":o.modalColor,height:"100%",left:0,opacity:0,position:"fixed",top:0,width:"100%","z-index":o.zIndex-1}}function t(){a("."+o.closeClass).live("click",function(){l();return false});o.follow&&e.bind("scroll.bPopup",function(){c.stop().animate({left:d.scrollLeft()+h,top:d.scrollTop()+g},o.followSpeed)}).bind("resize.bPopup",function(){if(o.modal&&m){var b=[d.height(),d.width()];n.css({height:b[0],width:b[1],left:k()})}b=p(c,o.amsl);g=b[0];h=b[1];c.stop().animate({left:d.scrollLeft()+
9
+ h,top:d.scrollTop()+g},o.followSpeed)});o.escClose&&d.bind("keydown.bPopup",function(b){b.which==27&&l()})}function k(){return e.width()<a("body").width()?0:(a("body").width()-e.width())/2}function p(b,j){var q=(e.height()-b.height())/2-j,v=(e.width()-b.width())/2+k();return[q<20?20:q,v]}if(a.isFunction(f)){i=f;f=null}o=a.extend({},a.fn.openPopup.defaults,f);o.scrollBar||a("html").css("overflow","hidden");var c=a(this),n=a('<div id="bModal"></div>'),d=a(document),e=a(window),r=p(c,o.amsl),g=r[0],
10
+ h=r[1],m=a.browser.msie&&parseInt(a.browser.version)==6&&typeof window.XMLHttpRequest!="object";return this.each(function(){o.modal&&n.css(u()).appendTo(o.appendTo).animate({opacity:o.opacity},o.fadeSpeed);s()})};a.fn.openPopup.defaults={amsl:150,appendTo:"body",closeClass:"bClose",escClose:true,fadeSpeed:250,follow:true,followSpeed:500,loadUrl:null,modal:true,modalColor:"#000",opacity:0.5,scrollBar:true,xLink:false,zIndex:9999};a.fn.closePopup=function(){a(this).trigger("click")}})(jQuery);
@@ -0,0 +1,205 @@
1
+ /*
2
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
3
+ *
4
+ * Uses the built in easing capabilities added In jQuery 1.1
5
+ * to offer multiple easing options
6
+ *
7
+ * TERMS OF USE - jQuery Easing
8
+ *
9
+ * Open source under the BSD License.
10
+ *
11
+ * Copyright © 2008 George McGinley Smith
12
+ * All rights reserved.
13
+ *
14
+ * Redistribution and use in source and binary forms, with or without modification,
15
+ * are permitted provided that the following conditions are met:
16
+ *
17
+ * Redistributions of source code must retain the above copyright notice, this list of
18
+ * conditions and the following disclaimer.
19
+ * Redistributions in binary form must reproduce the above copyright notice, this list
20
+ * of conditions and the following disclaimer in the documentation and/or other materials
21
+ * provided with the distribution.
22
+ *
23
+ * Neither the name of the author nor the names of contributors may be used to endorse
24
+ * or promote products derived from this software without specific prior written permission.
25
+ *
26
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
27
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
31
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
35
+ *
36
+ */
37
+
38
+ // t: current time, b: begInnIng value, c: change In value, d: duration
39
+ jQuery.easing['jswing'] = jQuery.easing['swing'];
40
+
41
+ jQuery.extend( jQuery.easing,
42
+ {
43
+ def: 'easeOutQuad',
44
+ swing: function (x, t, b, c, d) {
45
+ //alert(jQuery.easing.default);
46
+ return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
47
+ },
48
+ easeInQuad: function (x, t, b, c, d) {
49
+ return c*(t/=d)*t + b;
50
+ },
51
+ easeOutQuad: function (x, t, b, c, d) {
52
+ return -c *(t/=d)*(t-2) + b;
53
+ },
54
+ easeInOutQuad: function (x, t, b, c, d) {
55
+ if ((t/=d/2) < 1) return c/2*t*t + b;
56
+ return -c/2 * ((--t)*(t-2) - 1) + b;
57
+ },
58
+ easeInCubic: function (x, t, b, c, d) {
59
+ return c*(t/=d)*t*t + b;
60
+ },
61
+ easeOutCubic: function (x, t, b, c, d) {
62
+ return c*((t=t/d-1)*t*t + 1) + b;
63
+ },
64
+ easeInOutCubic: function (x, t, b, c, d) {
65
+ if ((t/=d/2) < 1) return c/2*t*t*t + b;
66
+ return c/2*((t-=2)*t*t + 2) + b;
67
+ },
68
+ easeInQuart: function (x, t, b, c, d) {
69
+ return c*(t/=d)*t*t*t + b;
70
+ },
71
+ easeOutQuart: function (x, t, b, c, d) {
72
+ return -c * ((t=t/d-1)*t*t*t - 1) + b;
73
+ },
74
+ easeInOutQuart: function (x, t, b, c, d) {
75
+ if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
76
+ return -c/2 * ((t-=2)*t*t*t - 2) + b;
77
+ },
78
+ easeInQuint: function (x, t, b, c, d) {
79
+ return c*(t/=d)*t*t*t*t + b;
80
+ },
81
+ easeOutQuint: function (x, t, b, c, d) {
82
+ return c*((t=t/d-1)*t*t*t*t + 1) + b;
83
+ },
84
+ easeInOutQuint: function (x, t, b, c, d) {
85
+ if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
86
+ return c/2*((t-=2)*t*t*t*t + 2) + b;
87
+ },
88
+ easeInSine: function (x, t, b, c, d) {
89
+ return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
90
+ },
91
+ easeOutSine: function (x, t, b, c, d) {
92
+ return c * Math.sin(t/d * (Math.PI/2)) + b;
93
+ },
94
+ easeInOutSine: function (x, t, b, c, d) {
95
+ return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
96
+ },
97
+ easeInExpo: function (x, t, b, c, d) {
98
+ return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
99
+ },
100
+ easeOutExpo: function (x, t, b, c, d) {
101
+ return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
102
+ },
103
+ easeInOutExpo: function (x, t, b, c, d) {
104
+ if (t==0) return b;
105
+ if (t==d) return b+c;
106
+ if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
107
+ return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
108
+ },
109
+ easeInCirc: function (x, t, b, c, d) {
110
+ return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
111
+ },
112
+ easeOutCirc: function (x, t, b, c, d) {
113
+ return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
114
+ },
115
+ easeInOutCirc: function (x, t, b, c, d) {
116
+ if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
117
+ return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
118
+ },
119
+ easeInElastic: function (x, t, b, c, d) {
120
+ var s=1.70158;var p=0;var a=c;
121
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
122
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
123
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
124
+ return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
125
+ },
126
+ easeOutElastic: function (x, t, b, c, d) {
127
+ var s=1.70158;var p=0;var a=c;
128
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
129
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
130
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
131
+ return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
132
+ },
133
+ easeInOutElastic: function (x, t, b, c, d) {
134
+ var s=1.70158;var p=0;var a=c;
135
+ if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
136
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
137
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
138
+ if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
139
+ return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
140
+ },
141
+ easeInBack: function (x, t, b, c, d, s) {
142
+ if (s == undefined) s = 1.70158;
143
+ return c*(t/=d)*t*((s+1)*t - s) + b;
144
+ },
145
+ easeOutBack: function (x, t, b, c, d, s) {
146
+ if (s == undefined) s = 1.70158;
147
+ return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
148
+ },
149
+ easeInOutBack: function (x, t, b, c, d, s) {
150
+ if (s == undefined) s = 1.70158;
151
+ if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
152
+ return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
153
+ },
154
+ easeInBounce: function (x, t, b, c, d) {
155
+ return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
156
+ },
157
+ easeOutBounce: function (x, t, b, c, d) {
158
+ if ((t/=d) < (1/2.75)) {
159
+ return c*(7.5625*t*t) + b;
160
+ } else if (t < (2/2.75)) {
161
+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
162
+ } else if (t < (2.5/2.75)) {
163
+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
164
+ } else {
165
+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
166
+ }
167
+ },
168
+ easeInOutBounce: function (x, t, b, c, d) {
169
+ if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
170
+ return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
171
+ }
172
+ });
173
+
174
+ /*
175
+ *
176
+ * TERMS OF USE - EASING EQUATIONS
177
+ *
178
+ * Open source under the BSD License.
179
+ *
180
+ * Copyright © 2001 Robert Penner
181
+ * All rights reserved.
182
+ *
183
+ * Redistribution and use in source and binary forms, with or without modification,
184
+ * are permitted provided that the following conditions are met:
185
+ *
186
+ * Redistributions of source code must retain the above copyright notice, this list of
187
+ * conditions and the following disclaimer.
188
+ * Redistributions in binary form must reproduce the above copyright notice, this list
189
+ * of conditions and the following disclaimer in the documentation and/or other materials
190
+ * provided with the distribution.
191
+ *
192
+ * Neither the name of the author nor the names of contributors may be used to endorse
193
+ * or promote products derived from this software without specific prior written permission.
194
+ *
195
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
196
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
197
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
198
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
199
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
200
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
201
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
202
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
203
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
204
+ *
205
+ */
@@ -0,0 +1,307 @@
1
+ /*
2
+
3
+ Quicksand 1.2.2
4
+
5
+ Reorder and filter items with a nice shuffling animation.
6
+
7
+ Copyright (c) 2010 Jacek Galanciak (razorjack.net) and agilope.com
8
+ Big thanks for Piotr Petrus (riddle.pl) for deep code review and wonderful docs & demos.
9
+
10
+ Dual licensed under the MIT and GPL version 2 licenses.
11
+ http://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt
12
+ http://github.com/jquery/jquery/blob/master/GPL-LICENSE.txt
13
+
14
+ Project site: http://razorjack.net/quicksand
15
+ Github site: http://github.com/razorjack/quicksand
16
+
17
+ */
18
+
19
+ (function ($) {
20
+ $.fn.quicksand = function (collection, customOptions) {
21
+ var options = {
22
+ duration: 750,
23
+ easing: 'swing',
24
+ attribute: 'data-id', // attribute to recognize same items within source and dest
25
+ adjustHeight: 'auto', // 'dynamic' animates height during shuffling (slow), 'auto' adjusts it before or after the animation, false leaves height constant
26
+ useScaling: true, // disable it if you're not using scaling effect or want to improve performance
27
+ enhancement: function(c) {}, // Visual enhacement (eg. font replacement) function for cloned elements
28
+ selector: '> *',
29
+ dx: 0,
30
+ dy: 0
31
+ };
32
+ $.extend(options, customOptions);
33
+
34
+ if ($.browser.msie || (typeof($.fn.scale) == 'undefined')) {
35
+ // Got IE and want scaling effect? Kiss my ass.
36
+ options.useScaling = false;
37
+ }
38
+
39
+ var callbackFunction;
40
+ if (typeof(arguments[1]) == 'function') {
41
+ var callbackFunction = arguments[1];
42
+ } else if (typeof(arguments[2] == 'function')) {
43
+ var callbackFunction = arguments[2];
44
+ }
45
+
46
+
47
+ return this.each(function (i) {
48
+ var val;
49
+ var animationQueue = []; // used to store all the animation params before starting the animation; solves initial animation slowdowns
50
+ var $collection = $(collection).clone(); // destination (target) collection
51
+ var $sourceParent = $(this); // source, the visible container of source collection
52
+ var sourceHeight = $(this).css('height'); // used to keep height and document flow during the animation
53
+
54
+ var destHeight;
55
+ var adjustHeightOnCallback = false;
56
+
57
+ var offset = $($sourceParent).offset(); // offset of visible container, used in animation calculations
58
+ var offsets = []; // coordinates of every source collection item
59
+
60
+ var $source = $(this).find(options.selector); // source collection items
61
+
62
+ // Replace the collection and quit if IE6
63
+ if ($.browser.msie && $.browser.version.substr(0,1)<7) {
64
+ $sourceParent.html('').append($collection);
65
+ return;
66
+ }
67
+
68
+ // Gets called when any animation is finished
69
+ var postCallbackPerformed = 0; // prevents the function from being called more than one time
70
+ var postCallback = function () {
71
+
72
+ if (!postCallbackPerformed) {
73
+ postCallbackPerformed = 1;
74
+
75
+ // hack:
76
+ // used to be: $sourceParent.html($dest.html()); // put target HTML into visible source container
77
+ // but new webkit builds cause flickering when replacing the collections
78
+ $toDelete = $sourceParent.find('> *');
79
+ $sourceParent.prepend($dest.find('> *'));
80
+ $toDelete.remove();
81
+
82
+ if (adjustHeightOnCallback) {
83
+ $sourceParent.css('height', destHeight);
84
+ }
85
+ options.enhancement($sourceParent); // Perform custom visual enhancements on a newly replaced collection
86
+ if (typeof callbackFunction == 'function') {
87
+ callbackFunction.call(this);
88
+ }
89
+ }
90
+ };
91
+
92
+ // Position: relative situations
93
+ var $correctionParent = $sourceParent.offsetParent();
94
+ var correctionOffset = $correctionParent.offset();
95
+ if ($correctionParent.css('position') == 'relative') {
96
+ if ($correctionParent.get(0).nodeName.toLowerCase() == 'body') {
97
+
98
+ } else {
99
+ correctionOffset.top += (parseFloat($correctionParent.css('border-top-width')) || 0);
100
+ correctionOffset.left +=( parseFloat($correctionParent.css('border-left-width')) || 0);
101
+ }
102
+ } else {
103
+ correctionOffset.top -= (parseFloat($correctionParent.css('border-top-width')) || 0);
104
+ correctionOffset.left -= (parseFloat($correctionParent.css('border-left-width')) || 0);
105
+ correctionOffset.top -= (parseFloat($correctionParent.css('margin-top')) || 0);
106
+ correctionOffset.left -= (parseFloat($correctionParent.css('margin-left')) || 0);
107
+ }
108
+
109
+ // perform custom corrections from options (use when Quicksand fails to detect proper correction)
110
+ if (isNaN(correctionOffset.left)) {
111
+ correctionOffset.left = 0;
112
+ }
113
+ if (isNaN(correctionOffset.top)) {
114
+ correctionOffset.top = 0;
115
+ }
116
+
117
+ correctionOffset.left -= options.dx;
118
+ correctionOffset.top -= options.dy;
119
+
120
+ // keeps nodes after source container, holding their position
121
+ $sourceParent.css('height', $(this).height());
122
+
123
+ // get positions of source collections
124
+ $source.each(function (i) {
125
+ offsets[i] = $(this).offset();
126
+ });
127
+
128
+ // stops previous animations on source container
129
+ $(this).stop();
130
+ var dx = 0; var dy = 0;
131
+ $source.each(function (i) {
132
+ $(this).stop(); // stop animation of collection items
133
+ var rawObj = $(this).get(0);
134
+ if (rawObj.style.position == 'absolute') {
135
+ dx = -options.dx;
136
+ dy = -options.dy;
137
+ } else {
138
+ dx = options.dx;
139
+ dy = options.dy;
140
+ }
141
+
142
+ rawObj.style.position = 'absolute';
143
+ rawObj.style.margin = '0';
144
+
145
+ rawObj.style.top = (offsets[i].top - parseFloat(rawObj.style.marginTop) - correctionOffset.top + dy) + 'px';
146
+ rawObj.style.left = (offsets[i].left - parseFloat(rawObj.style.marginLeft) - correctionOffset.left + dx) + 'px';
147
+ });
148
+
149
+ // create temporary container with destination collection
150
+ var $dest = $($sourceParent).clone();
151
+ var rawDest = $dest.get(0);
152
+ rawDest.innerHTML = '';
153
+ rawDest.setAttribute('id', '');
154
+ rawDest.style.height = 'auto';
155
+ rawDest.style.width = $sourceParent.width() + 'px';
156
+ $dest.append($collection);
157
+ // insert node into HTML
158
+ // Note that the node is under visible source container in the exactly same position
159
+ // The browser render all the items without showing them (opacity: 0.0)
160
+ // No offset calculations are needed, the browser just extracts position from underlayered destination items
161
+ // and sets animation to destination positions.
162
+ $dest.insertBefore($sourceParent);
163
+ $dest.css('opacity', 0.0);
164
+ rawDest.style.zIndex = -1;
165
+
166
+ rawDest.style.margin = '0';
167
+ rawDest.style.position = 'absolute';
168
+ rawDest.style.top = offset.top - correctionOffset.top + 'px';
169
+ rawDest.style.left = offset.left - correctionOffset.left + 'px';
170
+
171
+
172
+
173
+
174
+
175
+ if (options.adjustHeight === 'dynamic') {
176
+ // If destination container has different height than source container
177
+ // the height can be animated, adjusting it to destination height
178
+ $sourceParent.animate({height: $dest.height()}, options.duration, options.easing);
179
+ } else if (options.adjustHeight === 'auto') {
180
+ destHeight = $dest.height();
181
+ if (parseFloat(sourceHeight) < parseFloat(destHeight)) {
182
+ // Adjust the height now so that the items don't move out of the container
183
+ $sourceParent.css('height', destHeight);
184
+ } else {
185
+ // Adjust later, on callback
186
+ adjustHeightOnCallback = true;
187
+ }
188
+ }
189
+
190
+ // Now it's time to do shuffling animation
191
+ // First of all, we need to identify same elements within source and destination collections
192
+ $source.each(function (i) {
193
+ var destElement = [];
194
+ if (typeof(options.attribute) == 'function') {
195
+
196
+ val = options.attribute($(this));
197
+ $collection.each(function() {
198
+ if (options.attribute(this) == val) {
199
+ destElement = $(this);
200
+ return false;
201
+ }
202
+ });
203
+ } else {
204
+ destElement = $collection.filter('[' + options.attribute + '=' + $(this).attr(options.attribute) + ']');
205
+ }
206
+ if (destElement.length) {
207
+ // The item is both in source and destination collections
208
+ // It it's under different position, let's move it
209
+ if (!options.useScaling) {
210
+ animationQueue.push(
211
+ {
212
+ element: $(this),
213
+ animation:
214
+ {top: destElement.offset().top - correctionOffset.top,
215
+ left: destElement.offset().left - correctionOffset.left,
216
+ opacity: 1.0
217
+ }
218
+ });
219
+
220
+ } else {
221
+ animationQueue.push({
222
+ element: $(this),
223
+ animation: {top: destElement.offset().top - correctionOffset.top,
224
+ left: destElement.offset().left - correctionOffset.left,
225
+ opacity: 1.0,
226
+ scale: '1.0'
227
+ }
228
+ });
229
+
230
+ }
231
+ } else {
232
+ // The item from source collection is not present in destination collections
233
+ // Let's remove it
234
+ if (!options.useScaling) {
235
+ animationQueue.push({element: $(this),
236
+ animation: {opacity: '0.0'}});
237
+ } else {
238
+ animationQueue.push({element: $(this), animation: {opacity: '0.0',
239
+ scale: '0.0'}});
240
+ }
241
+ }
242
+ });
243
+
244
+ $collection.each(function (i) {
245
+ // Grab all items from target collection not present in visible source collection
246
+
247
+ var sourceElement = [];
248
+ var destElement = [];
249
+ if (typeof(options.attribute) == 'function') {
250
+ val = options.attribute($(this));
251
+ $source.each(function() {
252
+ if (options.attribute(this) == val) {
253
+ sourceElement = $(this);
254
+ return false;
255
+ }
256
+ });
257
+
258
+ $collection.each(function() {
259
+ if (options.attribute(this) == val) {
260
+ destElement = $(this);
261
+ return false;
262
+ }
263
+ });
264
+ } else {
265
+ sourceElement = $source.filter('[' + options.attribute + '=' + $(this).attr(options.attribute) + ']');
266
+ destElement = $collection.filter('[' + options.attribute + '=' + $(this).attr(options.attribute) + ']');
267
+ }
268
+
269
+ var animationOptions;
270
+ if (sourceElement.length === 0) {
271
+ // No such element in source collection...
272
+ if (!options.useScaling) {
273
+ animationOptions = {
274
+ opacity: '1.0'
275
+ };
276
+ } else {
277
+ animationOptions = {
278
+ opacity: '1.0',
279
+ scale: '1.0'
280
+ };
281
+ }
282
+ // Let's create it
283
+ d = destElement.clone();
284
+ var rawDestElement = d.get(0);
285
+ rawDestElement.style.position = 'absolute';
286
+ rawDestElement.style.margin = '0';
287
+ rawDestElement.style.top = destElement.offset().top - correctionOffset.top + 'px';
288
+ rawDestElement.style.left = destElement.offset().left - correctionOffset.left + 'px';
289
+ d.css('opacity', 0.0); // IE
290
+ if (options.useScaling) {
291
+ d.css('transform', 'scale(0.0)');
292
+ }
293
+ d.appendTo($sourceParent);
294
+
295
+ animationQueue.push({element: $(d),
296
+ animation: animationOptions});
297
+ }
298
+ });
299
+
300
+ $dest.remove();
301
+ options.enhancement($sourceParent); // Perform custom visual enhancements during the animation
302
+ for (i = 0; i < animationQueue.length; i++) {
303
+ animationQueue[i].element.animate(animationQueue[i].animation, options.duration, options.easing, postCallback);
304
+ }
305
+ });
306
+ };
307
+ })(jQuery);