refinerycms-project_portfolios 0.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.
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);