arbre2 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +30 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +75 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +93 -0
- data/LICENSE +20 -0
- data/README.md +92 -0
- data/Rakefile +7 -0
- data/arbre.gemspec +28 -0
- data/lib/arbre/child_element_collection.rb +86 -0
- data/lib/arbre/container.rb +20 -0
- data/lib/arbre/context.rb +83 -0
- data/lib/arbre/element/building.rb +151 -0
- data/lib/arbre/element.rb +194 -0
- data/lib/arbre/element_collection.rb +93 -0
- data/lib/arbre/html/attributes.rb +91 -0
- data/lib/arbre/html/class_list.rb +53 -0
- data/lib/arbre/html/comment.rb +47 -0
- data/lib/arbre/html/document.rb +93 -0
- data/lib/arbre/html/html_tags.rb +67 -0
- data/lib/arbre/html/querying.rb +256 -0
- data/lib/arbre/html/tag.rb +317 -0
- data/lib/arbre/rails/layouts.rb +126 -0
- data/lib/arbre/rails/legacy_document.rb +29 -0
- data/lib/arbre/rails/rendering.rb +76 -0
- data/lib/arbre/rails/rspec/arbre_support.rb +61 -0
- data/lib/arbre/rails/rspec.rb +2 -0
- data/lib/arbre/rails/template_handler.rb +32 -0
- data/lib/arbre/rails.rb +35 -0
- data/lib/arbre/rspec/be_rendered_as_matcher.rb +103 -0
- data/lib/arbre/rspec/be_scripted_as_matcher.rb +68 -0
- data/lib/arbre/rspec/contain_script_matcher.rb +64 -0
- data/lib/arbre/rspec.rb +3 -0
- data/lib/arbre/text_node.rb +35 -0
- data/lib/arbre/version.rb +3 -0
- data/lib/arbre.rb +27 -0
- data/spec/arbre/integration/html_document_spec.rb +90 -0
- data/spec/arbre/integration/html_spec.rb +283 -0
- data/spec/arbre/integration/querying_spec.rb +187 -0
- data/spec/arbre/integration/rails_spec.rb +183 -0
- data/spec/arbre/rails/rspec/arbre_support_spec.rb +75 -0
- data/spec/arbre/rspec/be_rendered_as_matcher_spec.rb +80 -0
- data/spec/arbre/rspec/be_scripted_as_matcher_spec.rb +61 -0
- data/spec/arbre/rspec/contain_script_matcher_spec.rb +40 -0
- data/spec/arbre/support/arbre_example_group.rb +0 -0
- data/spec/arbre/unit/child_element_collection_spec.rb +146 -0
- data/spec/arbre/unit/container_spec.rb +23 -0
- data/spec/arbre/unit/context_spec.rb +95 -0
- data/spec/arbre/unit/element/building_spec.rb +300 -0
- data/spec/arbre/unit/element_collection_spec.rb +169 -0
- data/spec/arbre/unit/element_spec.rb +297 -0
- data/spec/arbre/unit/html/attributes_spec.rb +219 -0
- data/spec/arbre/unit/html/class_list_spec.rb +109 -0
- data/spec/arbre/unit/html/comment_spec.rb +42 -0
- data/spec/arbre/unit/html/querying_spec.rb +32 -0
- data/spec/arbre/unit/html/tag_spec.rb +300 -0
- data/spec/arbre/unit/rails/layouts_spec.rb +127 -0
- data/spec/arbre/unit/text_node_spec.rb +40 -0
- data/spec/rails/app/controllers/example_controller.rb +18 -0
- data/spec/rails/app/views/example/_arbre_partial.html.arb +7 -0
- data/spec/rails/app/views/example/_erb_partial.html.erb +1 -0
- data/spec/rails/app/views/example/arbre.html.arb +1 -0
- data/spec/rails/app/views/example/arbre_partial_result.html.arb +3 -0
- data/spec/rails/app/views/example/erb.html.erb +5 -0
- data/spec/rails/app/views/example/erb_partial_result.html.arb +3 -0
- data/spec/rails/app/views/example/partials.html.arb +11 -0
- data/spec/rails/app/views/layouts/empty.html.arb +1 -0
- data/spec/rails/app/views/layouts/with_title.html.arb +5 -0
- data/spec/rails/config/routes.rb +4 -0
- data/spec/rails_spec_helper.rb +13 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/arbre_example_group.rb +19 -0
- metadata +254 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e3f1ac910f763cbfdb4e8eb7d0c5a85ed3b51339
|
4
|
+
data.tar.gz: eb1d640364da931397040de5742e175b9be1f18d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8f9fa5ca0ffa00691b8ad49fe6ab47cea7cecd4d318e4e9241cac16a70e8925b42d5ab6dee9db9716a5597b0f0ec100ca22fc02d6f093d283e7a76609551161a
|
7
|
+
data.tar.gz: 45ae2671b9ae6f1d549ccbe2bf068af665fc0ba3a3297843ed3a1dd9ca7fa759f66531a40c78a0b35118fbb7e227d73179a14eea40cf5318fdaedd7a97739789
|
data/.gitignore
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile ~/.gitignore_global
|
6
|
+
|
7
|
+
# Ignore .DS_Store
|
8
|
+
.DS_Store
|
9
|
+
|
10
|
+
# Ignore the output files.
|
11
|
+
/pkg
|
12
|
+
|
13
|
+
# Ignore bundler and database config and precompiled assets
|
14
|
+
/.bundle
|
15
|
+
/.env
|
16
|
+
|
17
|
+
# Ignore all logfiles and tempfiles.
|
18
|
+
/tmp
|
19
|
+
|
20
|
+
# Ignore TextMate projects
|
21
|
+
*.tmproj
|
22
|
+
*.sublime-project
|
23
|
+
*.sublime-workspace
|
24
|
+
|
25
|
+
# Documentation files and other stuff
|
26
|
+
.yardoc
|
27
|
+
/doc
|
28
|
+
/nbproject
|
29
|
+
/coverage
|
30
|
+
/spec/rails/log
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
flux
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.0.0-p247
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
## 2.1.0
|
2
|
+
|
3
|
+
* Added AJAX-rendering to `Arbre::Rails::LegacyDocument`
|
4
|
+
* Bug fix: classes specified in the class definition are not overwritten anymore by those passed to the
|
5
|
+
`build!` method.
|
6
|
+
* When using the `build!` method, any attributes that have a corresponding `<attribute>=` method on the
|
7
|
+
element class will cause this method to be invoked rather than the attributes array being updated.
|
8
|
+
* Bug fix: querying using multiple selectors now works (tag.find('a, button')).
|
9
|
+
* Bug fix using `render`: all child elements are now copied into the caller's element.
|
10
|
+
* Added public RSpec API.
|
11
|
+
|
12
|
+
## 2.0.1
|
13
|
+
|
14
|
+
* Added `app/views/arbre` as autoload path when using Rails
|
15
|
+
* Added DSL methods `Arbre::Html::Tag.tag`, `Arbre::Html::Tag.tag_id` and `Arbre::Html::Tag.tag_classes`
|
16
|
+
|
17
|
+
## 2.0.0
|
18
|
+
|
19
|
+
* Increased RSpec coverage to 100%
|
20
|
+
* Clear of specs failing when integrating into Flux framework
|
21
|
+
|
22
|
+
## 2.0.0.rc2
|
23
|
+
|
24
|
+
* Support for symbolic classes
|
25
|
+
* Various fixes & spec upgrades after integration into Flux framework
|
26
|
+
|
27
|
+
### Breaking changes
|
28
|
+
|
29
|
+
* Renaming `build` to `build!`
|
30
|
+
* Renaming `build_tag`/`build_element` to `build`
|
31
|
+
* Renaming `insert_tag`/`insert_element` to `insert`
|
32
|
+
|
33
|
+
## 2.0.0.rc1
|
34
|
+
|
35
|
+
* Rails: added content-layout structure
|
36
|
+
* Rails: optimized template output handling, removed need for String masquerading
|
37
|
+
* Added querying
|
38
|
+
* Increased RSpec coverage to near 100%
|
39
|
+
|
40
|
+
### Breaking changes
|
41
|
+
|
42
|
+
* Removal of `:for`-feature in tags
|
43
|
+
* Renamed `current_arbre_element` to `current_element`
|
44
|
+
* Renamed `Arbre::HTML` into `Arbre::Html`
|
45
|
+
|
46
|
+
*Joost Lubach*
|
47
|
+
|
48
|
+
## 1.0.1
|
49
|
+
|
50
|
+
* Template handler converts to string to satisfy Rack::Lint (@jpmckinney, #6)
|
51
|
+
* Fix to `Tag#add_class` when passing a string of classes to Tag build method
|
52
|
+
(@gregbell, #7)
|
53
|
+
* Not longer uses the default separator (@LTe, #4)
|
54
|
+
|
55
|
+
## 1.0.0
|
56
|
+
|
57
|
+
* Added support for the use of `:for` with non Active Model objects
|
58
|
+
|
59
|
+
## 1.0.0.rc4
|
60
|
+
|
61
|
+
* Fix issue where user could call `symbolize_keys!` on a
|
62
|
+
HashWithIndifferentAccess which doesn't implement the method
|
63
|
+
|
64
|
+
## 1.0.0.rc3
|
65
|
+
|
66
|
+
* Implemented `Arbre::Html::Tag#default_id_for_prefix`
|
67
|
+
|
68
|
+
## 1.0.0.rc2
|
69
|
+
|
70
|
+
* Fixed bug where Component's build methods were being rendered within the
|
71
|
+
parent context.
|
72
|
+
|
73
|
+
## 1.0.0.rc1
|
74
|
+
|
75
|
+
* Initial release and extraction from Active Admin
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
arbre2 (2.1.0)
|
5
|
+
activesupport (~> 3.2)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
actionpack (3.2.14)
|
11
|
+
activemodel (= 3.2.14)
|
12
|
+
activesupport (= 3.2.14)
|
13
|
+
builder (~> 3.0.0)
|
14
|
+
erubis (~> 2.7.0)
|
15
|
+
journey (~> 1.0.4)
|
16
|
+
rack (~> 1.4.5)
|
17
|
+
rack-cache (~> 1.2)
|
18
|
+
rack-test (~> 0.6.1)
|
19
|
+
sprockets (~> 2.2.1)
|
20
|
+
activemodel (3.2.14)
|
21
|
+
activesupport (= 3.2.14)
|
22
|
+
builder (~> 3.0.0)
|
23
|
+
activesupport (3.2.14)
|
24
|
+
i18n (~> 0.6, >= 0.6.4)
|
25
|
+
multi_json (~> 1.0)
|
26
|
+
atomic (1.1.14)
|
27
|
+
builder (3.0.4)
|
28
|
+
combustion (0.5.1)
|
29
|
+
activesupport (>= 3.0.0)
|
30
|
+
railties (>= 3.0.0)
|
31
|
+
thor (>= 0.14.6)
|
32
|
+
diff-lcs (1.2.5)
|
33
|
+
erubis (2.7.0)
|
34
|
+
hike (1.2.3)
|
35
|
+
i18n (0.6.9)
|
36
|
+
journey (1.0.4)
|
37
|
+
json (1.8.1)
|
38
|
+
multi_json (1.8.2)
|
39
|
+
rack (1.4.5)
|
40
|
+
rack-cache (1.2)
|
41
|
+
rack (>= 0.4)
|
42
|
+
rack-ssl (1.3.3)
|
43
|
+
rack
|
44
|
+
rack-test (0.6.2)
|
45
|
+
rack (>= 1.0)
|
46
|
+
railties (3.2.14)
|
47
|
+
actionpack (= 3.2.14)
|
48
|
+
activesupport (= 3.2.14)
|
49
|
+
rack-ssl (~> 1.3.2)
|
50
|
+
rake (>= 0.8.7)
|
51
|
+
rdoc (~> 3.4)
|
52
|
+
thor (>= 0.14.6, < 2.0)
|
53
|
+
rake (10.1.0)
|
54
|
+
rdoc (3.12.2)
|
55
|
+
json (~> 1.4)
|
56
|
+
rspec-core (2.14.7)
|
57
|
+
rspec-expectations (2.14.4)
|
58
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
59
|
+
rspec-mocks (2.14.4)
|
60
|
+
rspec-rails (2.14.0)
|
61
|
+
actionpack (>= 3.0)
|
62
|
+
activesupport (>= 3.0)
|
63
|
+
railties (>= 3.0)
|
64
|
+
rspec-core (~> 2.14.0)
|
65
|
+
rspec-expectations (~> 2.14.0)
|
66
|
+
rspec-mocks (~> 2.14.0)
|
67
|
+
simplecov (0.7.1)
|
68
|
+
multi_json (~> 1.0)
|
69
|
+
simplecov-html (~> 0.7.1)
|
70
|
+
simplecov-html (0.7.1)
|
71
|
+
sprockets (2.2.2)
|
72
|
+
hike (~> 1.2)
|
73
|
+
multi_json (~> 1.0)
|
74
|
+
rack (~> 1.0)
|
75
|
+
tilt (~> 1.1, != 1.3.0)
|
76
|
+
thor (0.18.1)
|
77
|
+
thread_safe (0.1.3)
|
78
|
+
atomic
|
79
|
+
tilt (1.4.1)
|
80
|
+
tzinfo (1.1.0)
|
81
|
+
thread_safe (~> 0.1)
|
82
|
+
|
83
|
+
PLATFORMS
|
84
|
+
ruby
|
85
|
+
|
86
|
+
DEPENDENCIES
|
87
|
+
arbre2!
|
88
|
+
bundler (~> 1.3)
|
89
|
+
combustion (~> 0.5)
|
90
|
+
rake
|
91
|
+
rspec-rails (~> 2.14)
|
92
|
+
simplecov
|
93
|
+
tzinfo
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Greg Bell
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# Arbre - Ruby Object Oriented HTML Views
|
2
|
+
|
3
|
+
Arbre is the DOM implemented in Ruby. This project is primarily used as
|
4
|
+
the object oriented view layer in Active Admin.
|
5
|
+
|
6
|
+
[<img src="https://secure.travis-ci.org/yoazt/arbre.png?branch=master" alt="Build Status" />](http://travis-ci.org/yoazt/arbre)
|
7
|
+
|
8
|
+
## Simple Usage
|
9
|
+
|
10
|
+
A simple example of setting up an Arbre context and creating some html
|
11
|
+
|
12
|
+
html = Arbre::Context.new do
|
13
|
+
h2 "Why Arbre is awesome?"
|
14
|
+
|
15
|
+
ul do
|
16
|
+
li "The DOM is implemented in ruby"
|
17
|
+
li "You can create object oriented views"
|
18
|
+
li "Templates suck"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
puts html.to_s #=> <h2>Why</h2><ul><li></li></ul>
|
23
|
+
|
24
|
+
|
25
|
+
## The DOM in Ruby
|
26
|
+
|
27
|
+
The purpose of Arbre is to leave the view as ruby objects as long
|
28
|
+
as possible. This allows OO Design to be used to implement the view layer.
|
29
|
+
|
30
|
+
|
31
|
+
html = Arbre::Context.new do
|
32
|
+
h2 "Why Arbre is awesome?"
|
33
|
+
end
|
34
|
+
|
35
|
+
html.children.size #=> 1
|
36
|
+
html.children.first #=> #<Arbre::Html::H2>
|
37
|
+
|
38
|
+
It is easy to extend your DOM tree as well.
|
39
|
+
|
40
|
+
arbre = Arbre::Context.new do
|
41
|
+
h2 "Why Arbre is awesome?"
|
42
|
+
|
43
|
+
ul do
|
44
|
+
li "The DOM is implemented in ruby"
|
45
|
+
li "You can create object oriented views"
|
46
|
+
end
|
47
|
+
|
48
|
+
within 'ul' do
|
49
|
+
li "Templates suck"
|
50
|
+
end
|
51
|
+
before 'li:last' do
|
52
|
+
li "I forgot:"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
## Custom elements
|
57
|
+
|
58
|
+
The purpose of Arbre is to be able to create shareable and extendable HTML
|
59
|
+
elements. To do this, you create a subclass of any Arbre HTML element:
|
60
|
+
|
61
|
+
For example:
|
62
|
+
|
63
|
+
class Panel < Arbre::Html::Section
|
64
|
+
builder_method :panel
|
65
|
+
|
66
|
+
def build!(title, attributes = {})
|
67
|
+
super attributes
|
68
|
+
|
69
|
+
h3 title, class: "panel-title"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
The `builder_method` defines the method that will be called to build this component
|
74
|
+
when using the DSL. The arguments passed into the `builder_method` will be passed
|
75
|
+
into the `#build!` method for you.
|
76
|
+
|
77
|
+
You can now use this panel in any Arbre context:
|
78
|
+
|
79
|
+
html = Arbre::Context.new do
|
80
|
+
panel "Hello World", id: "my-panel" do
|
81
|
+
span "Inside the panel"
|
82
|
+
|
83
|
+
after('h3') { sub "This is inserted after the title." }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
html.to_s #=>
|
88
|
+
# <div class='panel' id="my-panel">
|
89
|
+
# <h3 class='panel-title'>Hello World</h3>
|
90
|
+
# <sub>This is inserted after the title.</sub>
|
91
|
+
# <span>Inside the panel</span>
|
92
|
+
# </div>
|
data/Rakefile
ADDED
data/arbre.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "arbre/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "arbre2"
|
7
|
+
s.version = Arbre::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Greg Bell", "Joost Lubach"]
|
10
|
+
s.email = ["gregdbell@gmail.com", "joostlubach@gmail.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{An Object Oriented DOM Tree in Ruby}
|
13
|
+
s.description = %q{An Object Oriented DOM Tree in Ruby}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency "activesupport", "~> 3.2"
|
21
|
+
|
22
|
+
s.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
s.add_development_dependency "rake"
|
24
|
+
s.add_development_dependency "tzinfo"
|
25
|
+
s.add_development_dependency "combustion", "~> 0.5"
|
26
|
+
s.add_development_dependency "rspec-rails", "~> 2.14"
|
27
|
+
s.add_development_dependency "simplecov"
|
28
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Arbre
|
2
|
+
|
3
|
+
# An element collection used to hold some other element's children. Adds functionality to
|
4
|
+
# update a child's parent when it is added, and supports inserting at specific positions
|
5
|
+
# in the collection.
|
6
|
+
class ChildElementCollection < ElementCollection
|
7
|
+
|
8
|
+
######
|
9
|
+
# Initialization
|
10
|
+
|
11
|
+
def initialize(parent)
|
12
|
+
super([])
|
13
|
+
@parent = parent
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :parent
|
17
|
+
|
18
|
+
######
|
19
|
+
# Equality
|
20
|
+
|
21
|
+
def eql?(other)
|
22
|
+
super && parent == other.parent
|
23
|
+
end
|
24
|
+
|
25
|
+
######
|
26
|
+
# Adding and removing
|
27
|
+
|
28
|
+
def add(element)
|
29
|
+
insert_at length, element
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove(element)
|
33
|
+
return unless include?(element)
|
34
|
+
|
35
|
+
element.parent = nil
|
36
|
+
@elements.delete element
|
37
|
+
end
|
38
|
+
|
39
|
+
def clear
|
40
|
+
@elements.each { |element| element.parent = nil }
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
######
|
45
|
+
# Inserting
|
46
|
+
|
47
|
+
def insert_at(index, element)
|
48
|
+
if include?(element)
|
49
|
+
index -= 1 if @elements.index(element) <= index
|
50
|
+
@elements.delete element
|
51
|
+
else
|
52
|
+
assign_to_parent element
|
53
|
+
end
|
54
|
+
@elements.insert index, element
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def insert_after(existing, element)
|
59
|
+
index = @elements.index(existing) or
|
60
|
+
raise ArgumentError, "existing element #{existing} not found"
|
61
|
+
|
62
|
+
insert_at index+1, element
|
63
|
+
end
|
64
|
+
|
65
|
+
def insert_before(existing, element)
|
66
|
+
index = @elements.index(existing) or
|
67
|
+
raise ArgumentError, "existing element #{existing} not found"
|
68
|
+
|
69
|
+
insert_at index, element
|
70
|
+
end
|
71
|
+
|
72
|
+
######
|
73
|
+
# Parent
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Assigns the element to the parent of this collection, and removes it from the
|
78
|
+
# children of its current parent.
|
79
|
+
def assign_to_parent(element)
|
80
|
+
element.remove!
|
81
|
+
element.parent = parent
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Arbre
|
2
|
+
|
3
|
+
# This element is a simple container for children. When rendered, it will
|
4
|
+
# simply render the children, making this element 'invisible'. Use this
|
5
|
+
# class as a placeholder.
|
6
|
+
class Container < Element
|
7
|
+
def to_s
|
8
|
+
content
|
9
|
+
end
|
10
|
+
|
11
|
+
def indent_level
|
12
|
+
if parent
|
13
|
+
parent.indent_level
|
14
|
+
else
|
15
|
+
0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'arbre/element'
|
2
|
+
require 'active_support/core_ext/hash/keys'
|
3
|
+
|
4
|
+
module Arbre
|
5
|
+
|
6
|
+
# Root of any Arbre construct. Each elements in any Arbre construct will have a reference
|
7
|
+
# to this context, which provides information like what the current arbre element is.
|
8
|
+
class Context < Container
|
9
|
+
|
10
|
+
######
|
11
|
+
# Initialization
|
12
|
+
|
13
|
+
# Initialize a new Arbre::Context. Any passed block will be instance-exec'd.
|
14
|
+
#
|
15
|
+
# @param [Hash] assigns
|
16
|
+
# A hash of objects which will be made available as instance variables in the context,
|
17
|
+
# and in some Arbre elements.
|
18
|
+
#
|
19
|
+
# @param [Object] helpers
|
20
|
+
# An object that has methods on it which will become instance methods within the context.
|
21
|
+
# In a Rails set up, this is typically the +ActionView::Base+ instance used to render the
|
22
|
+
# view.
|
23
|
+
def initialize(assigns = nil, helpers = nil, &block)
|
24
|
+
@_assigns = (assigns || {}).symbolize_keys
|
25
|
+
@_helpers = helpers
|
26
|
+
@_element_stack = [ self ]
|
27
|
+
@_flow_stack = [ :append ]
|
28
|
+
|
29
|
+
# Pass ourselves as the arbre context to the element.
|
30
|
+
super self
|
31
|
+
|
32
|
+
instance_exec &block if block_given?
|
33
|
+
end
|
34
|
+
|
35
|
+
######
|
36
|
+
# Attributes
|
37
|
+
|
38
|
+
def assigns
|
39
|
+
@_assigns
|
40
|
+
end
|
41
|
+
|
42
|
+
def helpers
|
43
|
+
@_helpers
|
44
|
+
end
|
45
|
+
|
46
|
+
def parent=(*)
|
47
|
+
raise NotImplementedError, "Arbre::Context cannot have a parent"
|
48
|
+
end
|
49
|
+
|
50
|
+
def indent_level
|
51
|
+
-1
|
52
|
+
end
|
53
|
+
|
54
|
+
######
|
55
|
+
# Element & flow stack
|
56
|
+
|
57
|
+
def current_element
|
58
|
+
@_element_stack.last
|
59
|
+
end
|
60
|
+
|
61
|
+
def current_flow
|
62
|
+
@_flow_stack.last
|
63
|
+
end
|
64
|
+
|
65
|
+
def with_current(element: nil, flow: :append)
|
66
|
+
raise ArgumentError, "can't be in the context of nil" unless element
|
67
|
+
|
68
|
+
@_element_stack.push element
|
69
|
+
@_flow_stack.push flow
|
70
|
+
yield if block_given?
|
71
|
+
ensure
|
72
|
+
@_flow_stack.pop
|
73
|
+
@_element_stack.pop
|
74
|
+
end
|
75
|
+
|
76
|
+
# Replaces the current flow. For internal usie!
|
77
|
+
def replace_current_flow(flow)
|
78
|
+
@_flow_stack.pop
|
79
|
+
@_flow_stack.push flow
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|