arbre2 2.1.0
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.
- 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
|