sortable_element_for_nested_set 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/Manifest +29 -0
  2. data/README.rdoc +71 -0
  3. data/Rakefile +24 -0
  4. data/init.rb +2 -0
  5. data/lib/sortable_element_for_nested_set.rb +33 -0
  6. data/lib/sortable_element_for_nested_set_helper.rb +41 -0
  7. data/lib/tree_calc.rb +136 -0
  8. data/sortable_element_for_nested_set.gemspec +40 -0
  9. data/spec/controllers/sorting_controller_spec.rb +61 -0
  10. data/spec/helpers/sortable_element_for_nested_set_helper_spec.rb +114 -0
  11. data/spec/models/tree_move_calculator_spec.rb +91 -0
  12. data/spec/railsenv/app/controllers/application_controller.rb +10 -0
  13. data/spec/railsenv/config/boot.rb +110 -0
  14. data/spec/railsenv/config/database.yml +22 -0
  15. data/spec/railsenv/config/environment.rb +41 -0
  16. data/spec/railsenv/config/environments/development.rb +17 -0
  17. data/spec/railsenv/config/environments/production.rb +28 -0
  18. data/spec/railsenv/config/environments/test.rb +28 -0
  19. data/spec/railsenv/config/initializers/backtrace_silencers.rb +7 -0
  20. data/spec/railsenv/config/initializers/inflections.rb +10 -0
  21. data/spec/railsenv/config/initializers/mime_types.rb +5 -0
  22. data/spec/railsenv/config/initializers/new_rails_defaults.rb +19 -0
  23. data/spec/railsenv/config/initializers/session_store.rb +15 -0
  24. data/spec/railsenv/config/locales/en.yml +5 -0
  25. data/spec/railsenv/config/routes.rb +43 -0
  26. data/spec/railsenv/db/test.sqlite3 +0 -0
  27. data/spec/sortable_element_for_nested_set_spec.rb +1 -0
  28. data/spec/spec.opts +3 -0
  29. data/spec/spec_helper.rb +17 -0
  30. data/tasks/sortable_element_for_nested_set_tasks.rake +4 -0
  31. metadata +162 -0
@@ -0,0 +1,29 @@
1
+ tasks/sortable_element_for_nested_set_tasks.rake
2
+ init.rb
3
+ lib/tree_calc.rb
4
+ lib/sortable_element_for_nested_set.rb
5
+ lib/sortable_element_for_nested_set_helper.rb
6
+ README.rdoc
7
+ Rakefile
8
+ spec/helpers/sortable_element_for_nested_set_helper_spec.rb
9
+ spec/railsenv/app/controllers/application_controller.rb
10
+ spec/railsenv/config/routes.rb
11
+ spec/railsenv/config/initializers/backtrace_silencers.rb
12
+ spec/railsenv/config/initializers/mime_types.rb
13
+ spec/railsenv/config/initializers/inflections.rb
14
+ spec/railsenv/config/initializers/session_store.rb
15
+ spec/railsenv/config/initializers/new_rails_defaults.rb
16
+ spec/railsenv/config/environment.rb
17
+ spec/railsenv/config/locales/en.yml
18
+ spec/railsenv/config/boot.rb
19
+ spec/railsenv/config/database.yml
20
+ spec/railsenv/config/environments/development.rb
21
+ spec/railsenv/config/environments/test.rb
22
+ spec/railsenv/config/environments/production.rb
23
+ spec/railsenv/db/test.sqlite3
24
+ spec/spec_helper.rb
25
+ spec/sortable_element_for_nested_set_spec.rb
26
+ spec/spec.opts
27
+ spec/controllers/sorting_controller_spec.rb
28
+ spec/models/tree_move_calculator_spec.rb
29
+ Manifest
@@ -0,0 +1,71 @@
1
+ = SortableElementForNestedSet
2
+
3
+ Sorting a tree using the script.aculo.us helper that comes with Rails is nice.
4
+ But if your tree is backed by a nested set, the default request parameter sent to
5
+ your controllers might not really fit your needs.
6
+
7
+ This plugin allows you to easily find out which html element was moved (dragged) and
8
+ between which two elements it ended up.
9
+
10
+ Your work will be to make the update to your nested set model.
11
+
12
+ === Usage
13
+ The plugin has two parts. One view helper method and one controller module.
14
+
15
+ Assuming you have a tree where the node elements are named using the dom_id helper method,
16
+ in your view, use the sortable_element_reporting_target helper pretty much as your would
17
+ use the sortable_element helper that comes with Rails.
18
+ There is however a second argument that sets the parameter name of where the (record) id of
19
+ the element that was moved will be available.
20
+ The third (optional) options argument is the same as for sortable_element, except that
21
+ <tt>:onChange</tt> and <tt>:with</tt> are not allowed.
22
+
23
+ <tt>
24
+ <%= sortable_element_reporting_target("tree_element", "moved_element_id") %>
25
+ </tt>
26
+
27
+ In your controller, include the util methods with <tt>handles_sorting_of_nested_set</tt>.
28
+ To get the new position of a moved element use the these methods in a similar way
29
+ to this example controller:
30
+
31
+
32
+ class MyController < ApplicationController
33
+ handles_sorting_of_nested_set
34
+
35
+ def move
36
+ new_position = position_of(:moved_element_id).in_tree(:tree_element)
37
+ end
38
+ end
39
+
40
+
41
+ The new_position variable will be a hash with information about the moved elements new position.
42
+ The keys in the hash (<tt>:parent, :move_to_right_of, :move_to_left_of</tt>) all point to active
43
+ record id:s. It up to you to move your model accordingly.
44
+
45
+ For a more complete sample, the relevant parts of a simple rails application can be found
46
+ in this gist[http://gist.github.com/128779].
47
+
48
+
49
+ === Install
50
+
51
+ ==== As gem
52
+
53
+ Add the following to config/environment.rb
54
+
55
+ config.gem "robinsp-sortable_element_for_nested_set",
56
+ :lib => "sortable_element_for_nested_set",
57
+ :source => "http://gems.github.com"
58
+
59
+ Then run
60
+
61
+ <tt>sudo rake gems:install</tt>
62
+
63
+ ==== As plugin
64
+
65
+ <tt>./script/plugin install git://github.com/robinsp/sortable_element_for_nested_set.git</tt>
66
+
67
+
68
+
69
+
70
+
71
+ Copyright (c) 2009 RobinSpainhour.com, released under the MIT license
@@ -0,0 +1,24 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+ require 'echoe'
4
+
5
+ Echoe.new('sortable_element_for_nested_set', '0.1.3') do |p|
6
+ p.description = "Rails plugin for using script.aculo.us sortable_element for trees backed by nested sets."
7
+ p.url = "http://github.com/robinsp/sortable_element_for_nested_set"
8
+ p.author = "Robin Spainhour"
9
+ p.email = "robin@robinspainhour.com"
10
+ p.ignore_pattern = ["tmp/*"]
11
+ p.development_dependencies = ["rspec >= 1.2.4",
12
+ "rspec-rails >= 1.2.4",
13
+ "mocha >= 0.9.5"]
14
+ end
15
+
16
+
17
+ desc 'Default: run specs.'
18
+ task :default => :spec
19
+
20
+ desc 'Run the specs'
21
+ Spec::Rake::SpecTask.new(:spec) do |t|
22
+ t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
23
+ t.spec_files = FileList['spec/**/*_spec.rb']
24
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'sortable_element_for_nested_set'
2
+ require 'sortable_element_for_nested_set_helper'
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/tree_calc")
2
+ require File.expand_path(File.dirname(__FILE__) + "/sortable_element_for_nested_set_helper")
3
+
4
+ # SortableElementForNestedSet
5
+ module SortableElementForNestedSet
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def handles_sorting_of_nested_set
12
+ include SortableElementForNestedSet::InstanceMethods
13
+ attr_reader :dragged_record_id
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+ protected
19
+
20
+ def position_of(record_id_param_name)
21
+ @dragged_record_id = params[record_id_param_name].to_i
22
+ self
23
+ end
24
+
25
+ def in_tree(tree_param_name)
26
+ calculator = TreeMoveCalculator.new( params[tree_param_name] )
27
+ calculator.placement_of(self.dragged_record_id)
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ ActionController::Base.send( :include, SortableElementForNestedSet)
@@ -0,0 +1,41 @@
1
+ module SortableElementForNestedSetHelper
2
+
3
+ class OptsGenerator
4
+ attr_reader :element_id, :param_name
5
+
6
+ def initialize(element_id, target_param_name)
7
+ raise "Arg error" if element_id.blank? || target_param_name.blank?
8
+ @element_id = element_id
9
+ @param_name = target_param_name
10
+ end
11
+
12
+ def with_value
13
+ "'#{@param_name}='+ $(#{@element_id.to_json}).moved_element.split('_').last() + '&' + Sortable.serialize(#{@element_id.to_json})"
14
+ end
15
+
16
+ def on_change_value
17
+ "function(e) { $('#{@element_id}').moved_element = e.id; }"
18
+ end
19
+
20
+ def opts
21
+ {:with => with_value, :onChange => on_change_value}
22
+ end
23
+ end
24
+
25
+ def sortable_element_reporting_target(element_id, target_param_name, options = {})
26
+ javascript_tag(sortable_element_reporting_target_js(element_id, target_param_name, options) )
27
+ end
28
+
29
+ def sortable_element_reporting_target_js(element_id, target_param_name, options = {})
30
+ raise "target_param_name is required" if target_param_name.blank?
31
+
32
+ [:onChange, :with].each do |key|
33
+ raise "#{key} is set by this helper and is not allowed" if options.has_key? key
34
+ end
35
+ opts_gen = OptsGenerator.new(element_id, target_param_name)
36
+
37
+ sortable_element_js(element_id, options.merge(opts_gen.opts))
38
+ end
39
+ end
40
+
41
+ ActionView::Base.send(:include, SortableElementForNestedSetHelper)
@@ -0,0 +1,136 @@
1
+ module SortableElementForNestedSet
2
+ # Calculate the new position of a moved tree within a nested set.
3
+ # The new placement and sort order is given as a hash, as created by draggable_element
4
+ # Javascript helper.
5
+ class TreeMoveCalculator
6
+ attr_reader :nodes
7
+
8
+ # Calculate the left, right and parent values from
9
+ # the parameter generated by draggable_element JS helper
10
+ def initialize(sort_order)
11
+ @nodes = TreeMoveCalculator.create_tree_nodes(sort_order)
12
+ end
13
+
14
+ def right_of(target_id)
15
+ array_with_target_node = find_array_with_target_node(target_id)
16
+
17
+ if (array_with_target_node.last.id == target_id)
18
+ return nil
19
+ else
20
+ return array_with_target_node[array_with_target_node.collect(&:id).index(target_id) + 1].id
21
+ end
22
+ end
23
+
24
+ def placement_of(target_id)
25
+ # Note that this swaps left and right as the consumer views it differently.
26
+
27
+ {:parent => parent_of(target_id),
28
+ :move_to_right_of => left_of(target_id),
29
+ :move_to_left_of => right_of(target_id) }
30
+ end
31
+
32
+ def left_of(target_id)
33
+ array_with_target_node = find_array_with_target_node(target_id)
34
+
35
+ if (array_with_target_node.first.id == target_id)
36
+ return nil
37
+ else
38
+ return array_with_target_node[array_with_target_node.collect(&:id).index(target_id) - 1].id
39
+ end
40
+ end
41
+
42
+ def parent_of(val_to_find)
43
+ return nil if @nodes.collect(&:id).include?(val_to_find)
44
+
45
+ parent = nil
46
+
47
+ @nodes.each do |node|
48
+ parent = find_parent_of(val_to_find, node)
49
+ return parent if parent
50
+ end
51
+ end
52
+
53
+ # Create Array of TreeNodes from the parameter generated by draggable_element JS helper.
54
+ def self.create_tree_nodes(tree)
55
+ tree = to_hash(tree) if tree.is_a?(Array)
56
+
57
+ result = []
58
+
59
+ tree.keys.sort.each do |key|
60
+ node = TreeNode.new(tree[key]["id"].to_i)
61
+ node.children = create_tree_nodes( tree[key].reject {|k, v| k == "id"} ) if tree[key].many?
62
+ result << node
63
+ end
64
+
65
+ return result
66
+ end
67
+
68
+ # Convert an array of ids to the required hash format.
69
+ def self.to_hash(array)
70
+ result = {}
71
+
72
+ array.each_with_index {|id, i| result[i.to_s] = {"id" => id.to_s } }
73
+
74
+ return result
75
+ end
76
+
77
+ private
78
+ def root?(target_id)
79
+ parent = parent_of(target_id)
80
+ parent.nil?
81
+ end
82
+
83
+ def find_array_with_target_node(target_id)
84
+ unless root?(target_id)
85
+ parent_node_of(target_id).children
86
+ else
87
+ @nodes
88
+ end
89
+ end
90
+
91
+ def parent_node_of(target_id)
92
+ parent_node = (flattened_nodes.select {|x| x.id == parent_of(target_id) }).first
93
+ end
94
+
95
+ def flattened_nodes
96
+ @flattened_nodes ||= flatten_node_tree(@nodes).flatten
97
+ end
98
+
99
+ def find_parent_of(val_to_find, node)
100
+ return node.id if node.children.collect(&:id).include?(val_to_find)
101
+
102
+ parent = nil
103
+ node.children.each do |child|
104
+ parent = find_parent_of(val_to_find, child)
105
+ return parent if parent
106
+ end
107
+
108
+ return nil
109
+ end
110
+
111
+ def flatten_node_tree(nodes)
112
+ result = []
113
+ result << nodes
114
+
115
+ (nodes.select{|x| !x.children.empty?}).each {|x| result << flatten_node_tree(x.children)}
116
+ return result
117
+ end
118
+
119
+ end
120
+
121
+ class TreeNode
122
+ attr_accessor :id, :children, :parent_id
123
+ attr_accessor :left, :right
124
+
125
+ def initialize(id, children = nil)
126
+ @id = id
127
+ @children = children.nil? ? [] : children
128
+ end
129
+
130
+ def children=(new_children)
131
+ new_children.each {|c| c.parent_id = self.id }
132
+ @children = new_children
133
+ end
134
+ end
135
+
136
+ end
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{sortable_element_for_nested_set}
5
+ s.version = "0.1.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Robin Spainhour"]
9
+ s.date = %q{2009-05-29}
10
+ s.description = %q{Rails plugin for using script.aculo.us sortable_element for trees backed by nested sets.}
11
+ s.email = %q{robin@robinspainhour.com}
12
+ s.extra_rdoc_files = ["tasks/sortable_element_for_nested_set_tasks.rake", "lib/tree_calc.rb", "lib/sortable_element_for_nested_set.rb", "lib/sortable_element_for_nested_set_helper.rb", "README.rdoc"]
13
+ s.files = ["tasks/sortable_element_for_nested_set_tasks.rake", "init.rb", "lib/tree_calc.rb", "lib/sortable_element_for_nested_set.rb", "lib/sortable_element_for_nested_set_helper.rb", "README.rdoc", "Rakefile", "spec/helpers/sortable_element_for_nested_set_helper_spec.rb", "spec/railsenv/app/controllers/application_controller.rb", "spec/railsenv/config/routes.rb", "spec/railsenv/config/initializers/backtrace_silencers.rb", "spec/railsenv/config/initializers/mime_types.rb", "spec/railsenv/config/initializers/inflections.rb", "spec/railsenv/config/initializers/session_store.rb", "spec/railsenv/config/initializers/new_rails_defaults.rb", "spec/railsenv/config/environment.rb", "spec/railsenv/config/locales/en.yml", "spec/railsenv/config/boot.rb", "spec/railsenv/config/database.yml", "spec/railsenv/config/environments/development.rb", "spec/railsenv/config/environments/test.rb", "spec/railsenv/config/environments/production.rb", "spec/railsenv/db/test.sqlite3", "spec/spec_helper.rb", "spec/sortable_element_for_nested_set_spec.rb", "spec/spec.opts", "spec/controllers/sorting_controller_spec.rb", "spec/models/tree_move_calculator_spec.rb", "Manifest", "sortable_element_for_nested_set.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/robinsp/sortable_element_for_nested_set}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Sortable_element_for_nested_set", "--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{sortable_element_for_nested_set}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Rails plugin for using script.aculo.us sortable_element for trees backed by nested sets.}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_development_dependency(%q<rspec>, [">= 0", "= 1.2.4"])
28
+ s.add_development_dependency(%q<rspec-rails>, [">= 0", "= 1.2.4"])
29
+ s.add_development_dependency(%q<mocha>, [">= 0", "= 0.9.5"])
30
+ else
31
+ s.add_dependency(%q<rspec>, [">= 0", "= 1.2.4"])
32
+ s.add_dependency(%q<rspec-rails>, [">= 0", "= 1.2.4"])
33
+ s.add_dependency(%q<mocha>, [">= 0", "= 0.9.5"])
34
+ end
35
+ else
36
+ s.add_dependency(%q<rspec>, [">= 0", "= 1.2.4"])
37
+ s.add_dependency(%q<rspec-rails>, [">= 0", "= 1.2.4"])
38
+ s.add_dependency(%q<mocha>, [">= 0", "= 0.9.5"])
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class SortableElementForNestedSet::SortingController < ActionController::Base
4
+ handles_sorting_of_nested_set
5
+
6
+ def move
7
+ # This action is defined to let the specs set up the state of the controller easily
8
+ render :nothing => true
9
+ end
10
+ end
11
+
12
+ describe SortableElementForNestedSet::SortingController do
13
+ before do
14
+ @moved_id = "1234"
15
+ @tree = ["sort", "order", "array"]
16
+
17
+ xhr :post, :move, :moved_element_id => @moved_id, :tree_param => @tree
18
+ end
19
+
20
+ describe "position_of" do
21
+ it "should save the value of the given param in instance variable" do
22
+ @controller.instance_eval { position_of(:moved_element_id) }
23
+ @controller.dragged_record_id.should == @moved_id.to_i
24
+ end
25
+
26
+ it "should return the controller instance" do
27
+ result = @controller.instance_eval { position_of(:moved_element_id) }
28
+ result.should == @controller
29
+ end
30
+ end
31
+
32
+ describe "in_tree" do
33
+ before do
34
+ @calculator_class = SortableElementForNestedSet::TreeMoveCalculator
35
+
36
+ @placement_hash = {:new => "placement"}
37
+
38
+ @calc_mock = mock
39
+
40
+ @calc_mock.stubs(:placement_of).returns(@placement_hash)
41
+ @calculator_class.stubs(:new).returns(@calc_mock)
42
+ end
43
+
44
+ it "should create TreeMoveCalculator" do
45
+ @calculator_class.expects(:new).with(@tree).returns(@calc_mock)
46
+ @controller.instance_eval{ in_tree(:tree_param) }
47
+ end
48
+
49
+ it "should ask TreeMoveCalculator for the new placement" do
50
+ @controller.expects(:dragged_record_id).returns(321)
51
+ @calc_mock.expects(:placement_of).with(321)
52
+
53
+ @controller.instance_eval{ in_tree(:tree_param) }
54
+ end
55
+
56
+ it "should return hash with the position of the moved item" do
57
+ result = @controller.instance_eval{ in_tree(:tree_param) }
58
+ result.should == @placement_hash
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,114 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe SortableElementForNestedSetHelper do
4
+
5
+ # Shorten the class name a bit for the specs
6
+ OptsGenerator = SortableElementForNestedSetHelper::OptsGenerator
7
+
8
+ describe "sortable_element_reporting_target OptsGenerator" do
9
+ before do
10
+ @element_id = "el_name"
11
+ @param_name = "param_name"
12
+ @generator = OptsGenerator.new(@element_id, @param_name)
13
+ end
14
+
15
+ it "should require two non-blank init args" do
16
+ lambda {OptsGenerator.new()}.should raise_error
17
+ lambda {OptsGenerator.new("", "val")}.should raise_error
18
+ lambda {OptsGenerator.new("val", "")}.should raise_error
19
+ lambda {OptsGenerator.new("val", "val")}.should_not raise_error
20
+ end
21
+
22
+ it "should create hash of options" do
23
+ @generator.opts.should == {:with => @generator.with_value, :onChange => @generator.on_change_value }
24
+ end
25
+
26
+ it "should create javascript for 'onChange' attribute" do
27
+ @generator.on_change_value.should ==
28
+ "function(e) { $('#{@element_id}').moved_element = e.id; }"
29
+ end
30
+
31
+ it "should create javascript for 'with' attribute" do
32
+ @generator.with_value.should ==
33
+ "'#{@param_name}='+ $(#{@element_id.to_json}).moved_element.split('_').last() + '&' + Sortable.serialize(#{@element_id.to_json})"
34
+ end
35
+
36
+ end
37
+
38
+ describe "sortable_element_reporting_target" do
39
+ it "should forward args to sortable_element_reporting_target_js " do
40
+ helper.expects(:sortable_element_reporting_target_js).with("arg1", "arg2", "arg3")
41
+ helper.sortable_element_reporting_target("arg1", "arg2", "arg3")
42
+ end
43
+
44
+ it "should wrap the javascript with the javascript_tag helper" do
45
+ helper.stubs(:sortable_element_reporting_target_js).returns("raw_javascript")
46
+ helper.expects(:javascript_tag).with("raw_javascript").returns("result")
47
+
48
+ helper.sortable_element_reporting_target("arg1", "arg1").should == "result"
49
+ end
50
+
51
+ end
52
+
53
+ describe "sortable_element_reporting_target_js" do
54
+
55
+ before do
56
+ @opts_generator = mock("OptsGenerator") do
57
+ stubs(:opts).returns({:hash => "of", :generated => "options"})
58
+ end
59
+
60
+ OptsGenerator.stubs(:new).returns(@opts_generator)
61
+ helper.stubs(:sortable_element_js).returns("result")
62
+ end
63
+
64
+ describe "argument validation" do
65
+ after do
66
+ @illegal_call.should raise_error
67
+ end
68
+
69
+ it "should not allow the 'onChange' attribute" do
70
+ @illegal_call = lambda do
71
+ helper.sortable_element_reporting_target_js("element_id", "targetparam", :onChange => "causes failure" )
72
+ end
73
+ end
74
+
75
+ it "should not allow the 'with' attribute" do
76
+ @illegal_call = lambda do
77
+ helper.sortable_element_reporting_target_js("element_id", "targetparam", :with => "causes failure" )
78
+ end
79
+ end
80
+
81
+ it "should require the target_param_name parameter" do
82
+ @illegal_call = lambda do
83
+ helper.sortable_element_reporting_target_js("element_id", "")
84
+ end
85
+ end
86
+ end
87
+
88
+ it "should not require an options hash" do
89
+ legal_call = lambda do
90
+ helper.sortable_element_reporting_target_js("element_id", "targetparam")
91
+ end
92
+ legal_call.should_not raise_error
93
+ end
94
+
95
+ it "should use sortable_element_js helper" do
96
+ helper.expects(:sortable_element_js).with("element_id", @opts_generator.opts ).returns("result")
97
+ helper.sortable_element_reporting_target_js("element_id", "targetparam").should == "result"
98
+ end
99
+
100
+ it "should merge generated options into the options hash passed to sortable_element" do
101
+ opts_from_view = {:options => "from view"}
102
+ expected_opts = opts_from_view.merge(@opts_generator.opts)
103
+
104
+ helper.expects(:sortable_element_js).with("element_id", expected_opts )
105
+
106
+ helper.sortable_element_reporting_target_js("element_id", "targetparam", opts_from_view)
107
+ end
108
+
109
+ it "should create OptsGenerator using element_id and target_param arguments" do
110
+ OptsGenerator.expects(:new).with("my_element_id", "my_target_param").returns(@opts_generator)
111
+ helper.sortable_element_reporting_target_js("my_element_id", "my_target_param")
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,91 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe SortableElementForNestedSet::TreeMoveCalculator do
4
+ before do
5
+ @class_under_test = SortableElementForNestedSet::TreeMoveCalculator
6
+
7
+ @sort_order =
8
+ {
9
+ "0" => {"id" => "100",
10
+ "0" => {"id" => "200"},
11
+ "1" => {"id" => "300",
12
+ "1" => {"id" => "500"},
13
+ "0" => {"id" => "600"}
14
+ },
15
+ "2" => {"id" => "400"}
16
+ },
17
+ "1" => {"id" => "700" }
18
+ }
19
+
20
+ @calculator = @class_under_test.new(@sort_order)
21
+ end
22
+
23
+ it "should return placement details in a hash" do
24
+ target_id = 1
25
+ @calculator.expects(:parent_of).with(target_id).returns(11)
26
+ @calculator.expects(:left_of).with(target_id).returns(12)
27
+ @calculator.expects(:right_of).with(target_id).returns(13)
28
+
29
+ @calculator.placement_of(target_id).should == {:parent => 11,
30
+ :move_to_right_of => 12, :move_to_left_of => 13}
31
+ end
32
+
33
+ it "should find right_of" do
34
+ @calculator.right_of(100).should == 700
35
+ @calculator.right_of(200).should == 300
36
+ @calculator.right_of(300).should == 400
37
+ @calculator.right_of(400).should be_nil
38
+ @calculator.right_of(500).should be_nil
39
+ @calculator.right_of(600).should == 500
40
+ @calculator.right_of(700).should be_nil
41
+ end
42
+
43
+ it "should find left_of" do
44
+ @calculator.left_of(100).should be_nil
45
+ @calculator.left_of(200).should be_nil
46
+ @calculator.left_of(300).should == 200
47
+ @calculator.left_of(400).should == 300
48
+ @calculator.left_of(500).should == 600
49
+ @calculator.left_of(600).should be_nil
50
+ @calculator.left_of(700).should == 100
51
+ end
52
+
53
+ it "should find parent" do
54
+ @calculator.parent_of(100).should be_nil
55
+ @calculator.parent_of(700).should be_nil
56
+
57
+ @calculator.parent_of(200).should == 100
58
+ @calculator.parent_of(300).should == 100
59
+ @calculator.parent_of(400).should == 100
60
+
61
+ @calculator.parent_of(500).should == 300
62
+ @calculator.parent_of(600).should == 300
63
+ end
64
+
65
+ it "create tree nodes with parents" do
66
+ result = @class_under_test.create_tree_nodes(@sort_order)
67
+ result.size.should == 2
68
+
69
+ result.first.id.should == 100
70
+ result.first.children.collect {|x| [x.parent_id, x.id] }.should == [ [100,200], [100, 300], [100,400] ]
71
+ result.first.children.second.children.collect {|x| [x.parent_id, x.id] }.should == [[300,600], [300,500] ]
72
+
73
+ result.last.id.should == 700
74
+ end
75
+
76
+ describe "to_hash()" do
77
+ it "should return empty hash if array is empty" do
78
+ @class_under_test.to_hash([]).should == {}
79
+ end
80
+
81
+ it "should convert flat array to hash" do
82
+ array = ["3", "2", "1"]
83
+ expected_hash = { "0" => {"id" => "3"},
84
+ "1" => {"id" => "2"},
85
+ "2" => {"id" => "1"}
86
+ }
87
+
88
+ @class_under_test.to_hash(array).should == expected_hash
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,10 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ helper :all # include all helpers, all the time
6
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
7
+
8
+ # Scrub sensitive parameters from your log
9
+ # filter_parameter_logging :password
10
+ end
@@ -0,0 +1,110 @@
1
+ # Don't change this file!
2
+ # Configure your app in config/environment.rb and config/environments/*.rb
3
+
4
+ RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
5
+
6
+ module Rails
7
+ class << self
8
+ def boot!
9
+ unless booted?
10
+ preinitialize
11
+ pick_boot.run
12
+ end
13
+ end
14
+
15
+ def booted?
16
+ defined? Rails::Initializer
17
+ end
18
+
19
+ def pick_boot
20
+ (vendor_rails? ? VendorBoot : GemBoot).new
21
+ end
22
+
23
+ def vendor_rails?
24
+ File.exist?("#{RAILS_ROOT}/vendor/rails")
25
+ end
26
+
27
+ def preinitialize
28
+ load(preinitializer_path) if File.exist?(preinitializer_path)
29
+ end
30
+
31
+ def preinitializer_path
32
+ "#{RAILS_ROOT}/config/preinitializer.rb"
33
+ end
34
+ end
35
+
36
+ class Boot
37
+ def run
38
+ load_initializer
39
+ Rails::Initializer.run(:set_load_path)
40
+ end
41
+ end
42
+
43
+ class VendorBoot < Boot
44
+ def load_initializer
45
+ require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
46
+ Rails::Initializer.run(:install_gem_spec_stubs)
47
+ Rails::GemDependency.add_frozen_gem_path
48
+ end
49
+ end
50
+
51
+ class GemBoot < Boot
52
+ def load_initializer
53
+ self.class.load_rubygems
54
+ load_rails_gem
55
+ require 'initializer'
56
+ end
57
+
58
+ def load_rails_gem
59
+ if version = self.class.gem_version
60
+ gem 'rails', version
61
+ else
62
+ gem 'rails'
63
+ end
64
+ rescue Gem::LoadError => load_error
65
+ $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
66
+ exit 1
67
+ end
68
+
69
+ class << self
70
+ def rubygems_version
71
+ Gem::RubyGemsVersion rescue nil
72
+ end
73
+
74
+ def gem_version
75
+ if defined? RAILS_GEM_VERSION
76
+ RAILS_GEM_VERSION
77
+ elsif ENV.include?('RAILS_GEM_VERSION')
78
+ ENV['RAILS_GEM_VERSION']
79
+ else
80
+ parse_gem_version(read_environment_rb)
81
+ end
82
+ end
83
+
84
+ def load_rubygems
85
+ require 'rubygems'
86
+ min_version = '1.3.1'
87
+ unless rubygems_version >= min_version
88
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
89
+ exit 1
90
+ end
91
+
92
+ rescue LoadError
93
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
94
+ exit 1
95
+ end
96
+
97
+ def parse_gem_version(text)
98
+ $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
99
+ end
100
+
101
+ private
102
+ def read_environment_rb
103
+ File.read("#{RAILS_ROOT}/config/environment.rb")
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ # All that for this:
110
+ Rails.boot!
@@ -0,0 +1,22 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3-ruby (not necessary on OS X Leopard)
3
+ development:
4
+ adapter: sqlite3
5
+ database: db/development.sqlite3
6
+ pool: 5
7
+ timeout: 5000
8
+
9
+ # Warning: The database defined as "test" will be erased and
10
+ # re-generated from your development database when you run "rake".
11
+ # Do not set this db to the same as development or production.
12
+ test:
13
+ adapter: sqlite3
14
+ database: db/test.sqlite3
15
+ pool: 5
16
+ timeout: 5000
17
+
18
+ production:
19
+ adapter: sqlite3
20
+ database: db/production.sqlite3
21
+ pool: 5
22
+ timeout: 5000
@@ -0,0 +1,41 @@
1
+ # Be sure to restart your server when you modify this file
2
+
3
+ # Specifies gem version of Rails to use when vendor/rails is not present
4
+ RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION
5
+
6
+ # Bootstrap the Rails environment, frameworks, and default configuration
7
+ require File.join(File.dirname(__FILE__), 'boot')
8
+
9
+ Rails::Initializer.run do |config|
10
+ # Settings in config/environments/* take precedence over those specified here.
11
+ # Application configuration should go into files in config/initializers
12
+ # -- all .rb files in that directory are automatically loaded.
13
+
14
+ # Add additional load paths for your own custom dirs
15
+ # config.load_paths += %W( #{RAILS_ROOT}/extras )
16
+
17
+ # Specify gems that this application depends on and have them installed with rake gems:install
18
+ # config.gem "bj"
19
+ # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
20
+ # config.gem "sqlite3-ruby", :lib => "sqlite3"
21
+ # config.gem "aws-s3", :lib => "aws/s3"
22
+
23
+ # Only load the plugins named here, in the order given (default is alphabetical).
24
+ # :all can be used as a placeholder for all plugins not explicitly named
25
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
26
+
27
+ # Skip frameworks you're not going to use. To use Rails without a database,
28
+ # you must remove the Active Record framework.
29
+ # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
30
+
31
+ # Activate observers that should always be running
32
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
33
+
34
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
35
+ # Run "rake -D time" for a list of tasks for finding time zone names.
36
+ config.time_zone = 'UTC'
37
+
38
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
39
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
40
+ # config.i18n.default_locale = :de
41
+ end
@@ -0,0 +1,17 @@
1
+ # Settings specified here will take precedence over those in config/environment.rb
2
+
3
+ # In the development environment your application's code is reloaded on
4
+ # every request. This slows down response time but is perfect for development
5
+ # since you don't have to restart the webserver when you make code changes.
6
+ config.cache_classes = false
7
+
8
+ # Log error messages when you accidentally call methods on nil.
9
+ config.whiny_nils = true
10
+
11
+ # Show full error reports and disable caching
12
+ config.action_controller.consider_all_requests_local = true
13
+ config.action_view.debug_rjs = true
14
+ config.action_controller.perform_caching = false
15
+
16
+ # Don't care if the mailer can't send
17
+ config.action_mailer.raise_delivery_errors = false
@@ -0,0 +1,28 @@
1
+ # Settings specified here will take precedence over those in config/environment.rb
2
+
3
+ # The production environment is meant for finished, "live" apps.
4
+ # Code is not reloaded between requests
5
+ config.cache_classes = true
6
+
7
+ # Full error reports are disabled and caching is turned on
8
+ config.action_controller.consider_all_requests_local = false
9
+ config.action_controller.perform_caching = true
10
+ config.action_view.cache_template_loading = true
11
+
12
+ # See everything in the log (default is :info)
13
+ # config.log_level = :debug
14
+
15
+ # Use a different logger for distributed setups
16
+ # config.logger = SyslogLogger.new
17
+
18
+ # Use a different cache store in production
19
+ # config.cache_store = :mem_cache_store
20
+
21
+ # Enable serving of images, stylesheets, and javascripts from an asset server
22
+ # config.action_controller.asset_host = "http://assets.example.com"
23
+
24
+ # Disable delivery errors, bad email addresses will be ignored
25
+ # config.action_mailer.raise_delivery_errors = false
26
+
27
+ # Enable threaded mode
28
+ # config.threadsafe!
@@ -0,0 +1,28 @@
1
+ # Settings specified here will take precedence over those in config/environment.rb
2
+
3
+ # The test environment is used exclusively to run your application's
4
+ # test suite. You never need to work with it otherwise. Remember that
5
+ # your test database is "scratch space" for the test suite and is wiped
6
+ # and recreated between test runs. Don't rely on the data there!
7
+ config.cache_classes = true
8
+
9
+ # Log error messages when you accidentally call methods on nil.
10
+ config.whiny_nils = true
11
+
12
+ # Show full error reports and disable caching
13
+ config.action_controller.consider_all_requests_local = true
14
+ config.action_controller.perform_caching = false
15
+ config.action_view.cache_template_loading = true
16
+
17
+ # Disable request forgery protection in test environment
18
+ config.action_controller.allow_forgery_protection = false
19
+
20
+ # Tell Action Mailer not to deliver emails to the real world.
21
+ # The :test delivery method accumulates sent emails in the
22
+ # ActionMailer::Base.deliveries array.
23
+ config.action_mailer.delivery_method = :test
24
+
25
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
26
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
27
+ # like if you have constraints or database-specific column types
28
+ # config.active_record.schema_format = :sql
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4
+ # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5
+
6
+ # You can also remove all the silencers if you're trying do debug a problem that might steem from framework code.
7
+ # Rails.backtrace_cleaner.remove_silencers!
@@ -0,0 +1,10 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new inflection rules using the following format
4
+ # (all these examples are active by default):
5
+ # ActiveSupport::Inflector.inflections do |inflect|
6
+ # inflect.plural /^(ox)$/i, '\1en'
7
+ # inflect.singular /^(ox)en/i, '\1'
8
+ # inflect.irregular 'person', 'people'
9
+ # inflect.uncountable %w( fish sheep )
10
+ # end
@@ -0,0 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new mime types for use in respond_to blocks:
4
+ # Mime::Type.register "text/richtext", :rtf
5
+ # Mime::Type.register_alias "text/html", :iphone
@@ -0,0 +1,19 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # These settings change the behavior of Rails 2 apps and will be defaults
4
+ # for Rails 3. You can remove this initializer when Rails 3 is released.
5
+
6
+ if defined?(ActiveRecord)
7
+ # Include Active Record class name as root for JSON serialized output.
8
+ ActiveRecord::Base.include_root_in_json = true
9
+
10
+ # Store the full class name (including module namespace) in STI type column.
11
+ ActiveRecord::Base.store_full_sti_class = true
12
+ end
13
+
14
+ # Use ISO 8601 format for JSON serialized times and dates.
15
+ ActiveSupport.use_standard_json_time_format = true
16
+
17
+ # Don't escape HTML entities in JSON, leave that for the #json_escape helper.
18
+ # if you're including raw json in an HTML page.
19
+ ActiveSupport.escape_html_entities_in_json = false
@@ -0,0 +1,15 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key for verifying cookie session data integrity.
4
+ # If you change this key, all old sessions will become invalid!
5
+ # Make sure the secret is at least 30 characters and all random,
6
+ # no regular words or you'll be exposed to dictionary attacks.
7
+ ActionController::Base.session = {
8
+ :key => '_railsenv_session',
9
+ :secret => '5eea0426c25c0db25fb5a2e355216ce600e4c09909abc217f25ed64311de6c1d49bd422e244d04e76dd00b020a8f8c535b10a353f0b0d697350ac22f8a487294'
10
+ }
11
+
12
+ # Use the database for sessions instead of the cookie-based default,
13
+ # which shouldn't be used to store highly confidential information
14
+ # (create the session table with "rake db:sessions:create")
15
+ # ActionController::Base.session_store = :active_record_store
@@ -0,0 +1,5 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ hello: "Hello world"
@@ -0,0 +1,43 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ # The priority is based upon order of creation: first created -> highest priority.
3
+
4
+ # Sample of regular route:
5
+ # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
6
+ # Keep in mind you can assign values other than :controller and :action
7
+
8
+ # Sample of named route:
9
+ # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
10
+ # This route can be invoked with purchase_url(:id => product.id)
11
+
12
+ # Sample resource route (maps HTTP verbs to controller actions automatically):
13
+ # map.resources :products
14
+
15
+ # Sample resource route with options:
16
+ # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
17
+
18
+ # Sample resource route with sub-resources:
19
+ # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
20
+
21
+ # Sample resource route with more complex sub-resources
22
+ # map.resources :products do |products|
23
+ # products.resources :comments
24
+ # products.resources :sales, :collection => { :recent => :get }
25
+ # end
26
+
27
+ # Sample resource route within a namespace:
28
+ # map.namespace :admin do |admin|
29
+ # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
30
+ # admin.resources :products
31
+ # end
32
+
33
+ # You can have the root of your site routed with map.root -- just remember to delete public/index.html.
34
+ # map.root :controller => "welcome"
35
+
36
+ # See how all your routes lay out with "rake routes"
37
+
38
+ # Install the default routes as the lowest priority.
39
+ # Note: These default routes make all actions in every controller accessible via GET requests. You should
40
+ # consider removing the them or commenting them out if you're using named routes and resources.
41
+ map.connect ':controller/:action/:id'
42
+ map.connect ':controller/:action/:id.:format'
43
+ end
File without changes
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
@@ -0,0 +1,17 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path(File.dirname(__FILE__) + "/railsenv/config/environment")
3
+ require 'spec'
4
+ require 'spec/rails'
5
+
6
+ Spec::Runner.configure do |config|
7
+ config.use_transactional_fixtures = true
8
+ config.use_instantiated_fixtures = false
9
+ config.mock_with :mocha
10
+ end
11
+
12
+ plugin_spec_dir = File.dirname(__FILE__)
13
+ ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
14
+
15
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/sortable_element_for_nested_set")
16
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/sortable_element_for_nested_set_helper")
17
+
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :sortable_element_for_nested_set do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sortable_element_for_nested_set
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 3
9
+ version: 0.1.3
10
+ platform: ruby
11
+ authors:
12
+ - Robin Spainhour
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2009-05-29 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ - - "="
32
+ - !ruby/object:Gem::Version
33
+ segments:
34
+ - 1
35
+ - 2
36
+ - 4
37
+ version: 1.2.4
38
+ type: :development
39
+ version_requirements: *id001
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec-rails
42
+ prerelease: false
43
+ requirement: &id002 !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ - - "="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 1
55
+ - 2
56
+ - 4
57
+ version: 1.2.4
58
+ type: :development
59
+ version_requirements: *id002
60
+ - !ruby/object:Gem::Dependency
61
+ name: mocha
62
+ prerelease: false
63
+ requirement: &id003 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ - - "="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ - 9
76
+ - 5
77
+ version: 0.9.5
78
+ type: :development
79
+ version_requirements: *id003
80
+ description: Rails plugin for using script.aculo.us sortable_element for trees backed by nested sets.
81
+ email: robin@robinspainhour.com
82
+ executables: []
83
+
84
+ extensions: []
85
+
86
+ extra_rdoc_files:
87
+ - tasks/sortable_element_for_nested_set_tasks.rake
88
+ - lib/tree_calc.rb
89
+ - lib/sortable_element_for_nested_set.rb
90
+ - lib/sortable_element_for_nested_set_helper.rb
91
+ - README.rdoc
92
+ files:
93
+ - tasks/sortable_element_for_nested_set_tasks.rake
94
+ - init.rb
95
+ - lib/tree_calc.rb
96
+ - lib/sortable_element_for_nested_set.rb
97
+ - lib/sortable_element_for_nested_set_helper.rb
98
+ - README.rdoc
99
+ - Rakefile
100
+ - spec/helpers/sortable_element_for_nested_set_helper_spec.rb
101
+ - spec/railsenv/app/controllers/application_controller.rb
102
+ - spec/railsenv/config/routes.rb
103
+ - spec/railsenv/config/initializers/backtrace_silencers.rb
104
+ - spec/railsenv/config/initializers/mime_types.rb
105
+ - spec/railsenv/config/initializers/inflections.rb
106
+ - spec/railsenv/config/initializers/session_store.rb
107
+ - spec/railsenv/config/initializers/new_rails_defaults.rb
108
+ - spec/railsenv/config/environment.rb
109
+ - spec/railsenv/config/locales/en.yml
110
+ - spec/railsenv/config/boot.rb
111
+ - spec/railsenv/config/database.yml
112
+ - spec/railsenv/config/environments/development.rb
113
+ - spec/railsenv/config/environments/test.rb
114
+ - spec/railsenv/config/environments/production.rb
115
+ - spec/railsenv/db/test.sqlite3
116
+ - spec/spec_helper.rb
117
+ - spec/sortable_element_for_nested_set_spec.rb
118
+ - spec/spec.opts
119
+ - spec/controllers/sorting_controller_spec.rb
120
+ - spec/models/tree_move_calculator_spec.rb
121
+ - Manifest
122
+ - sortable_element_for_nested_set.gemspec
123
+ has_rdoc: true
124
+ homepage: http://github.com/robinsp/sortable_element_for_nested_set
125
+ licenses: []
126
+
127
+ post_install_message:
128
+ rdoc_options:
129
+ - --line-numbers
130
+ - --inline-source
131
+ - --title
132
+ - Sortable_element_for_nested_set
133
+ - --main
134
+ - README.rdoc
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ segments:
143
+ - 0
144
+ version: "0"
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ segments:
151
+ - 1
152
+ - 2
153
+ version: "1.2"
154
+ requirements: []
155
+
156
+ rubyforge_project: sortable_element_for_nested_set
157
+ rubygems_version: 1.3.7
158
+ signing_key:
159
+ specification_version: 2
160
+ summary: Rails plugin for using script.aculo.us sortable_element for trees backed by nested sets.
161
+ test_files: []
162
+