former 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +8 -2
- data/Rakefile +0 -1
- data/former.gemspec +2 -2
- data/lib/former/builder.rb +12 -6
- data/lib/former/element.rb +10 -0
- data/lib/former/version.rb +1 -1
- data/test/builder_test.rb +17 -1
- metadata +73 -60
data/README.rdoc
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
= Former
|
2
|
+
{<img src="https://secure.travis-ci.org/opbandit/former.png?branch=master" alt="Build Status" />}[https://travis-ci.org/opbandit/former]
|
3
|
+
{<img src="https://gemnasium.com/opbandit/former.png" alt="Dependency Status" />}[https://gemnasium.com/opbandit/former]
|
2
4
|
|
3
5
|
Former turns an html string into a set of editable fields. For instance, if you want to give users the ability to edit certain parts of pregenerated HTML (like the href's of a's), this gem makes it easy to create the form and handle user input.
|
4
6
|
|
@@ -25,7 +27,7 @@ First, create a new parser that extends Builder class.
|
|
25
27
|
text "p", "a.important"
|
26
28
|
end
|
27
29
|
|
28
|
-
In this example, we want to be able to edit the location of all links that have a class of "important", the location of all images, and the text in any paragraphs or important links.
|
30
|
+
In this example, we want to be able to edit the location of all links that have a class of "important", the location of all images, and the text in any paragraphs or important links. Note that the text method takes any number of parameters which each will be evaluated for text children (or, if you give no parameters, all text nodes will be included).
|
29
31
|
|
30
32
|
To produce the input fields from some example input HTML, first create an instance of your parser.
|
31
33
|
|
@@ -40,6 +42,10 @@ This will output:
|
|
40
42
|
<input name="former_3" type="text" value="/an/image/path" />
|
41
43
|
<input name="former_4" type="text" value="last text" />
|
42
44
|
|
45
|
+
You can also convert the original html to json:
|
46
|
+
|
47
|
+
puts parsed.to_json
|
48
|
+
|
43
49
|
You can then set fields individually or as a group (with, say, the params from a POST/GET):
|
44
50
|
|
45
51
|
parsed[0] = "A New Description"
|
@@ -65,4 +71,4 @@ By default, the fields created are input's. If you pass a block to the attr/tex
|
|
65
71
|
"<textarea name='#{name}'></textarea>"
|
66
72
|
}
|
67
73
|
text "p", "a.important"
|
68
|
-
end
|
74
|
+
end
|
data/Rakefile
CHANGED
data/former.gemspec
CHANGED
@@ -14,8 +14,8 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
15
15
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
16
|
gem.require_paths = ["lib"]
|
17
|
-
gem.add_dependency("actionpack", ">=
|
18
|
-
gem.add_dependency("nokogiri", ">= 1.
|
17
|
+
gem.add_dependency("actionpack", ">= 4.0.3")
|
18
|
+
gem.add_dependency("nokogiri", ">= 1.6.0")
|
19
19
|
gem.add_development_dependency("rake")
|
20
20
|
gem.add_development_dependency("rdoc")
|
21
21
|
end
|
data/lib/former/builder.rb
CHANGED
@@ -2,13 +2,14 @@ require 'nokogiri'
|
|
2
2
|
|
3
3
|
module Former
|
4
4
|
class Builder
|
5
|
+
class << self; attr_accessor :queries end
|
5
6
|
attr_reader :editable
|
6
7
|
|
7
8
|
def initialize(html)
|
8
9
|
@html = Nokogiri::HTML.parse(html)
|
9
10
|
|
10
11
|
matches = {}
|
11
|
-
|
12
|
+
self.class.queries.each { |path, qs|
|
12
13
|
@html.search(path).each { |node|
|
13
14
|
# if all we need is the text, only include text kids
|
14
15
|
if qs.length == 1 and qs.first[:query] == :text
|
@@ -33,12 +34,16 @@ module Former
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def to_form_html
|
36
|
-
@editable.map
|
37
|
+
@editable.map(&:to_form_html).join("\n")
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_json
|
41
|
+
"[" + @editable.map(&:to_json).join(",") + "]"
|
37
42
|
end
|
38
43
|
|
39
44
|
def to_html
|
40
45
|
# nokogiri pads w/ xhtml/body elements
|
41
|
-
@html.search("//body").first.children.
|
46
|
+
@html.search("//body").first.children.map(&:to_html).join
|
42
47
|
end
|
43
48
|
|
44
49
|
def []=(index, value)
|
@@ -53,12 +58,13 @@ module Former
|
|
53
58
|
end
|
54
59
|
|
55
60
|
def self.attr(elem, attr, &block)
|
56
|
-
|
57
|
-
|
58
|
-
|
61
|
+
@queries ||= {}
|
62
|
+
@queries[elem] ||= []
|
63
|
+
@queries[elem] << { :query => attr, :block => block }
|
59
64
|
end
|
60
65
|
|
61
66
|
def self.text(*elems, &block)
|
67
|
+
attr("text()", :text, &block) if elems.length == 0
|
62
68
|
elems.each { |elem| attr(elem, :text, &block) }
|
63
69
|
end
|
64
70
|
end
|
data/lib/former/element.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'action_view'
|
2
|
+
require 'json'
|
2
3
|
|
3
4
|
module Former
|
4
5
|
class Element
|
@@ -12,6 +13,15 @@ module Former
|
|
12
13
|
@index = index
|
13
14
|
end
|
14
15
|
|
16
|
+
def to_json
|
17
|
+
h = {
|
18
|
+
:value => (@query == :text) ? @node.text : @node[@query],
|
19
|
+
:nodename => @node.name
|
20
|
+
}
|
21
|
+
h[:attr] = @query unless @query == :text
|
22
|
+
h.to_json
|
23
|
+
end
|
24
|
+
|
15
25
|
def to_form_html
|
16
26
|
name = "former_#{@index}"
|
17
27
|
return @block.call(@node, name) unless @block.nil?
|
data/lib/former/version.rb
CHANGED
data/test/builder_test.rb
CHANGED
@@ -7,15 +7,31 @@ class Parser < Former::Builder
|
|
7
7
|
text "p", "a.important"
|
8
8
|
end
|
9
9
|
|
10
|
+
class AllTextParser < Former::Builder
|
11
|
+
attr "a.important", :href
|
12
|
+
attr("img", :src)
|
13
|
+
text
|
14
|
+
end
|
15
|
+
|
10
16
|
class BuilderTest < Test::Unit::TestCase
|
11
17
|
def setup
|
12
18
|
@html_txt = '<p>some text<a class="important" href="http://alink.com">some link text<img src="/an/image/path"></a>last text</p>'
|
13
19
|
@parser = Parser.new @html_txt
|
14
|
-
puts @parser.to_form_html
|
15
20
|
end
|
16
21
|
|
17
22
|
def test_parsing
|
18
23
|
assert_equal @parser.editable.length, 5
|
24
|
+
|
25
|
+
html = '<img src="http://blah.com/example.jpg" /><p>This is some text</p>This is some more text'
|
26
|
+
json = [
|
27
|
+
{ "value" => "http://blah.com/example.jpg", "nodename" => "img", "attr" => "src"},
|
28
|
+
{ "value" => "This is some text", "nodename" => "text"}
|
29
|
+
]
|
30
|
+
assert_equal JSON.parse(Parser.new(html).to_json), json
|
31
|
+
|
32
|
+
# now, test with parsing all text (which will include the last bit now)
|
33
|
+
json << { "value" => "This is some more text", "nodename" => "text" }
|
34
|
+
assert_equal JSON.parse(AllTextParser.new(html).to_json), json
|
19
35
|
end
|
20
36
|
|
21
37
|
def test_building
|
metadata
CHANGED
@@ -1,71 +1,87 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: former
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
4
5
|
prerelease:
|
5
|
-
version: 0.0.1
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Brian Muller
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2014-02-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: actionpack
|
17
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
|
-
requirements:
|
20
|
-
- -
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version:
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 4.0.3
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements:
|
26
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 4.0.3
|
30
|
+
- !ruby/object:Gem::Dependency
|
27
31
|
name: nokogiri
|
28
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
29
33
|
none: false
|
30
|
-
requirements:
|
31
|
-
- -
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.6.0
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
|
-
version_requirements:
|
37
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.6.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
38
47
|
name: rake
|
39
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
40
49
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
version:
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
45
54
|
type: :development
|
46
55
|
prerelease: false
|
47
|
-
version_requirements:
|
48
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
49
63
|
name: rdoc
|
50
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
51
65
|
none: false
|
52
|
-
requirements:
|
53
|
-
- -
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version:
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
56
70
|
type: :development
|
57
71
|
prerelease: false
|
58
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
59
78
|
description: Converts HTML to form fields for editing values in the HTML
|
60
|
-
email:
|
79
|
+
email:
|
61
80
|
- bamuller@gmail.com
|
62
81
|
executables: []
|
63
|
-
|
64
82
|
extensions: []
|
65
|
-
|
66
83
|
extra_rdoc_files: []
|
67
|
-
|
68
|
-
files:
|
84
|
+
files:
|
69
85
|
- .gitignore
|
70
86
|
- Gemfile
|
71
87
|
- LICENSE.txt
|
@@ -80,36 +96,33 @@ files:
|
|
80
96
|
- test/builder_test.rb
|
81
97
|
homepage: http://github.com/opbandit/former
|
82
98
|
licenses: []
|
83
|
-
|
84
99
|
post_install_message:
|
85
100
|
rdoc_options: []
|
86
|
-
|
87
|
-
require_paths:
|
101
|
+
require_paths:
|
88
102
|
- lib
|
89
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
104
|
none: false
|
91
|
-
requirements:
|
92
|
-
- -
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
|
95
|
-
segments:
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
segments:
|
96
110
|
- 0
|
97
|
-
|
98
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
hash: 4374242057553143574
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
113
|
none: false
|
100
|
-
requirements:
|
101
|
-
- -
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
|
104
|
-
segments:
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
segments:
|
105
119
|
- 0
|
106
|
-
|
120
|
+
hash: 4374242057553143574
|
107
121
|
requirements: []
|
108
|
-
|
109
122
|
rubyforge_project:
|
110
|
-
rubygems_version: 1.8.
|
123
|
+
rubygems_version: 1.8.25
|
111
124
|
signing_key:
|
112
125
|
specification_version: 3
|
113
126
|
summary: Converts HTML to form fields for editing values in the HTML
|
114
|
-
test_files:
|
127
|
+
test_files:
|
115
128
|
- test/builder_test.rb
|