html_surgeon 0.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 +10 -0
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/Gemfile +14 -0
- data/README.md +209 -0
- data/Rakefile +11 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/html_surgeon.gemspec +36 -0
- data/lib/html_surgeon.rb +16 -0
- data/lib/html_surgeon/abstract_method_error.rb +4 -0
- data/lib/html_surgeon/change.rb +64 -0
- data/lib/html_surgeon/change_set.rb +52 -0
- data/lib/html_surgeon/changes/add_css_class.rb +40 -0
- data/lib/html_surgeon/changes/replace_tag_name.rb +28 -0
- data/lib/html_surgeon/service.rb +29 -0
- data/lib/html_surgeon/version.rb +3 -0
- metadata +160 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 184ce38f2ca801e35b52003637cdba997487557c
|
4
|
+
data.tar.gz: 23741ef09a0cf4e12150171fcbb93417c86ceef2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e567d65954530da7c2f33c562f0890813280b7274d68978d6419552aa933fe49e4cac1d5e5110ac454c99c1393381fade85b73d374750e96e92ebc96f7d8cc38
|
7
|
+
data.tar.gz: a25d072d6c15964317a440e5857d24f60ced9ce620b87acfd5f5f48af3b82c507daa8a4edb3c2382fb8078669a6123e2c1d608d3ff34537386ff80ee0a311a25
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.1.2
|
4
|
+
before_install: gem install bundler -v 1.10.3
|
5
|
+
|
6
|
+
addons:
|
7
|
+
code_climate:
|
8
|
+
repo_token: ecc7b46e36ad6c2bda5d5b91fc86cbf594b8b5903c72a1fa838e53426093280d
|
9
|
+
|
10
|
+
script: 'bundle exec rake spec'
|
11
|
+
|
12
|
+
notifications:
|
13
|
+
email:
|
14
|
+
recipients:
|
15
|
+
- eturino@eturino.com
|
16
|
+
on_failure: change
|
17
|
+
on_success: never
|
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in html_surgeon.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'pry'
|
8
|
+
gem 'pry-nav'
|
9
|
+
gem 'pry-stack_explorer'
|
10
|
+
gem 'pry-doc'
|
11
|
+
gem 'pry-rescue'
|
12
|
+
end
|
13
|
+
|
14
|
+
gem 'codeclimate-test-reporter', :group => :test, :require => nil
|
data/README.md
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
# HtmlSurgeon
|
2
|
+
|
3
|
+
|
4
|
+
[](http://badge.fury.io/rb/html_surgeon)
|
5
|
+
[](https://travis-ci.org/eturino/html_surgeon)
|
6
|
+
[](https://codeclimate.com/github/eturino/html_surgeon)
|
7
|
+
[](https://codeclimate.com/github/eturino/html_surgeon)
|
8
|
+
|
9
|
+
Make specific changes in a HTML string, optionally adding html attributes with the audit trail of the changes. Uses [Nokogiri](http://www.nokogiri.org/).
|
10
|
+
|
11
|
+
## Basic Usage
|
12
|
+
|
13
|
+
First, you create a HtmlSurgeon service instance for the given html fragment
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
GIVEN_HTML = <<-HTML
|
17
|
+
<div>
|
18
|
+
<h1>Something</h1>
|
19
|
+
<div id="1" class="lol to-be-changed">1</div>
|
20
|
+
<span>Other</span>
|
21
|
+
<div id="2" class="another to-be-changed">
|
22
|
+
<ul>
|
23
|
+
<li>1</li>
|
24
|
+
<li>2</li>
|
25
|
+
</ul>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
HTML
|
29
|
+
|
30
|
+
surgeon = HtmlSurgeon.for(GIVEN_HTML)
|
31
|
+
```
|
32
|
+
|
33
|
+
if you want to add audit attributes in the HTML tags changed, pass the option in the surgeon service creation
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
surgeon = HtmlSurgeon.for(GIVEN_HTML, audit: true)
|
37
|
+
```
|
38
|
+
|
39
|
+
with the surgeon service, you can prepare several change sets. A change set is defined by a node set and a list of changes to be applied on each selected node.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
change_set = surgeon.css('div.to-be-changed') # => will return a change_set
|
43
|
+
|
44
|
+
change_set.node_set # => will return a Nokogiri's Node Set with the selected nodes (right now it'll get us div ID 1 and div ID 2.
|
45
|
+
|
46
|
+
# to prepare a change replace the tag name 'div' for 'article'
|
47
|
+
change_set.replace_tag_name('article')
|
48
|
+
|
49
|
+
# to prepare another change to add a css class in the selected nodes
|
50
|
+
change_set.add_css_class('added-class')
|
51
|
+
|
52
|
+
# we can add a second one
|
53
|
+
change_set.add_css_class('another-added-class')
|
54
|
+
|
55
|
+
```
|
56
|
+
|
57
|
+
The changes are not made yet. In order to do it, we call `run` on the change set
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
change_set.run
|
61
|
+
|
62
|
+
surgeon.html # => html with the changes applied
|
63
|
+
# =>
|
64
|
+
# <div>
|
65
|
+
# <h1>Something</h1>
|
66
|
+
# <article id="1" class="lol to-be-changed added-class another-added-class">1</div>
|
67
|
+
# <span>Other</span>
|
68
|
+
# <article id="2" class="another to-be-changed added-class another-added-class">
|
69
|
+
# <ul>
|
70
|
+
# <li>1</li>
|
71
|
+
# <li>2</li>
|
72
|
+
# </ul>
|
73
|
+
# </div>
|
74
|
+
# </div>
|
75
|
+
|
76
|
+
|
77
|
+
# original html still in
|
78
|
+
surgeon.given_html == GIVEN_HTML # => true
|
79
|
+
|
80
|
+
# you can review what was changed in the change set
|
81
|
+
change_set.changes
|
82
|
+
# =>
|
83
|
+
# [
|
84
|
+
# "replace tag name with article",
|
85
|
+
# "add css class added-class",
|
86
|
+
# "add css class another-added-class",
|
87
|
+
# ]
|
88
|
+
```
|
89
|
+
|
90
|
+
We can also chain call the changes in a changeset
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
surgeon = HtmlService.for(GIVEN_HTML)
|
94
|
+
surgeon.css('.lol').replace_tag_name('span').add_css_class('hey').run
|
95
|
+
surgeon.html # =>
|
96
|
+
# <div>
|
97
|
+
# <h1>Something</h1>
|
98
|
+
# <span id="1" class="lol to-be-changed hey">1</span>
|
99
|
+
# <span>Other</span>
|
100
|
+
# <div id="2" class="another to-be-changed">
|
101
|
+
# <ul>
|
102
|
+
# <li>1</li>
|
103
|
+
# <li>2</li>
|
104
|
+
# </ul>
|
105
|
+
# </div>
|
106
|
+
# </div>
|
107
|
+
```
|
108
|
+
|
109
|
+
If we have enabled audit, we'll get the changes applied to an element in an data attribute.
|
110
|
+
It will store, in JSON, an array with all the changes.
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
surgeon = HtmlService.for(GIVEN_HTML)
|
114
|
+
surgeon.css('.lol').replace_tag_name('span').add_css_class('hey').run
|
115
|
+
surgeon.html # =>
|
116
|
+
# <div>
|
117
|
+
# <h1>Something</h1>
|
118
|
+
# <span id="1" class="lol to-be-changed hey" data-surgeon-audit='[{"change_set":"830e96dc-fa07-40ce-8968-ea5c55ec4b84","changed_at":"2015-07-02T12:52:43.874Z","type":"replace_tag_name","old":"div","new":"span"},{"change_set":"830e96dc-fa07-40ce-8968-ea5c55ec4b84","changed_at":"2015-07-02T12:52:43.874Z","type":"add_css_class","existed_before":false,"class":"hey"}]'>1</span>
|
119
|
+
# <span>Other</span>
|
120
|
+
# <div id="2" class="another to-be-changed">
|
121
|
+
# <ul>
|
122
|
+
# <li>1</li>
|
123
|
+
# <li>2</li>
|
124
|
+
# </ul>
|
125
|
+
# </div>
|
126
|
+
# </div>#
|
127
|
+
```
|
128
|
+
|
129
|
+
the attribute's value (formatted) is:
|
130
|
+
|
131
|
+
```json
|
132
|
+
[
|
133
|
+
{
|
134
|
+
"change_set":"830e96dc-fa07-40ce-8968-ea5c55ec4b84",
|
135
|
+
"changed_at":"2015-07-02T12:52:43.874Z",
|
136
|
+
"type":"replace_tag_name",
|
137
|
+
"old":"div",
|
138
|
+
"new":"span"
|
139
|
+
},
|
140
|
+
{
|
141
|
+
"change_set":"830e96dc-fa07-40ce-8968-ea5c55ec4b84",
|
142
|
+
"changed_at":"2015-07-02T12:52:43.874Z",
|
143
|
+
"type":"add_css_class",
|
144
|
+
"existed_before":false,
|
145
|
+
"class":"hey"
|
146
|
+
}
|
147
|
+
]
|
148
|
+
```
|
149
|
+
|
150
|
+
it has a `change_set` with the UUID of the change set, `changed_at` with the moment it was applied, and the rest define the change.
|
151
|
+
|
152
|
+
## Selecting the Node Set
|
153
|
+
|
154
|
+
we use Nokogiri's selections.
|
155
|
+
|
156
|
+
### using css
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
change_set = surgeon.css('div.to-be-changed')
|
160
|
+
```
|
161
|
+
|
162
|
+
### using xpath
|
163
|
+
|
164
|
+
not implemented yet.
|
165
|
+
|
166
|
+
|
167
|
+
## Available Changes
|
168
|
+
|
169
|
+
### Replace Tag Name
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
surgeon.css('div.to-be-changed').replace_name_tag('article')
|
173
|
+
```
|
174
|
+
|
175
|
+
### Add CSS Class
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
surgeon.css('div.to-be-changed').add_css_class('applied-some-stuff')
|
179
|
+
```
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
## Installation
|
184
|
+
|
185
|
+
Add this line to your application's Gemfile:
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
gem 'html_surgeon'
|
189
|
+
```
|
190
|
+
|
191
|
+
And then execute:
|
192
|
+
|
193
|
+
$ bundle
|
194
|
+
|
195
|
+
Or install it yourself as:
|
196
|
+
|
197
|
+
$ gem install html_surgeon
|
198
|
+
|
199
|
+
|
200
|
+
## Development
|
201
|
+
|
202
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
203
|
+
|
204
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
205
|
+
|
206
|
+
## Contributing
|
207
|
+
|
208
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/eturino/html_surgeon.
|
209
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "html_surgeon"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'html_surgeon/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'html_surgeon'
|
8
|
+
spec.version = HtmlSurgeon::VERSION
|
9
|
+
spec.authors = ['Eduardo Turiño']
|
10
|
+
spec.email = ['eturino@eturino.com']
|
11
|
+
|
12
|
+
spec.summary = %q{Ruby gem for surgical changes in HTML fragment strings, using Nokogiri, with optional audit trail in html attributes}
|
13
|
+
# spec.description = %q{TODO: Write a longer description or delete this line.}
|
14
|
+
spec.homepage = 'https://github.com/eturino/html_surgeon'
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
17
|
+
# delete this section to allow pushing this gem to any host.
|
18
|
+
# if spec.respond_to?(:metadata)
|
19
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
20
|
+
# else
|
21
|
+
# raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
|
22
|
+
# end
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
spec.bindir = 'exe'
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
|
29
|
+
spec.add_dependency 'nokogiri'
|
30
|
+
spec.add_dependency 'activesupport'
|
31
|
+
spec.add_dependency 'oj'
|
32
|
+
spec.add_dependency 'oj_mimic_json'
|
33
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
34
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
35
|
+
spec.add_development_dependency 'rspec'
|
36
|
+
end
|
data/lib/html_surgeon.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'oj_mimic_json'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'active_support/all'
|
4
|
+
require 'html_surgeon/version'
|
5
|
+
require 'html_surgeon/abstract_method_error'
|
6
|
+
require 'html_surgeon/service'
|
7
|
+
require 'html_surgeon/change_set'
|
8
|
+
require 'html_surgeon/change'
|
9
|
+
require 'html_surgeon/changes/add_css_class'
|
10
|
+
require 'html_surgeon/changes/replace_tag_name'
|
11
|
+
|
12
|
+
module HtmlSurgeon
|
13
|
+
def self.for(html_string, **options)
|
14
|
+
Service.new html_string, **options
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module HtmlSurgeon
|
2
|
+
|
3
|
+
class Change
|
4
|
+
DATA_CHANGE_AUDIT_ATTRIBUTE = 'data-surgeon-audit'.freeze
|
5
|
+
|
6
|
+
attr_reader :change_set
|
7
|
+
|
8
|
+
def initialize(change_set:)
|
9
|
+
@change_set = change_set
|
10
|
+
end
|
11
|
+
|
12
|
+
delegate :audit?, to: :change_set
|
13
|
+
delegate :uuid, :run_time, to: :change_set, prefix: true
|
14
|
+
|
15
|
+
def apply(element)
|
16
|
+
prepare_audit_change(element) if audit?
|
17
|
+
|
18
|
+
apply_in element
|
19
|
+
|
20
|
+
apply_audit_change(element) if audit?
|
21
|
+
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def log
|
26
|
+
raise AbstractMethodError, "a lazy developer has not implemented this method in #{self.class}"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def prepare_audit_change(element)
|
32
|
+
@audit_data = audit_data(element)
|
33
|
+
end
|
34
|
+
|
35
|
+
def apply_audit_change(element)
|
36
|
+
current = current_audit_data(element)
|
37
|
+
current << @audit_data
|
38
|
+
element[DATA_CHANGE_AUDIT_ATTRIBUTE] = Oj.dump current
|
39
|
+
end
|
40
|
+
|
41
|
+
def current_audit_data(element)
|
42
|
+
current = element[DATA_CHANGE_AUDIT_ATTRIBUTE].presence
|
43
|
+
return [] unless current
|
44
|
+
|
45
|
+
Oj.load current
|
46
|
+
end
|
47
|
+
|
48
|
+
def basic_audit_data
|
49
|
+
{
|
50
|
+
change_set: change_set_uuid,
|
51
|
+
changed_at: change_set_run_time
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def audit_data(element)
|
56
|
+
raise AbstractMethodError, "a lazy developer has not implemented this method in #{self.class}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def apply_in(_element)
|
60
|
+
raise AbstractMethodError, "a lazy developer has not implemented this method in #{self.class}"
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module HtmlSurgeon
|
2
|
+
|
3
|
+
class ChangeSet
|
4
|
+
attr_reader :node_set, :base, :change_list, :uuid, :run_time
|
5
|
+
|
6
|
+
def initialize(node_set, base)
|
7
|
+
@node_set = node_set
|
8
|
+
@base = base
|
9
|
+
@change_list = []
|
10
|
+
@uuid = SecureRandom.uuid
|
11
|
+
@run_time = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
delegate :audit?, :html, to: :base
|
15
|
+
|
16
|
+
# TODO: #preview, like run but in another doc, does not change it yet.
|
17
|
+
|
18
|
+
def run
|
19
|
+
@run_time = Time.now.utc
|
20
|
+
|
21
|
+
node_set.each do |element|
|
22
|
+
apply_on_element(element)
|
23
|
+
end
|
24
|
+
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def changes
|
29
|
+
change_list.map &:log
|
30
|
+
end
|
31
|
+
|
32
|
+
# CHANGES
|
33
|
+
|
34
|
+
def replace_tag_name(new_tag_name)
|
35
|
+
change_list << Changes::ReplaceTagName.new(change_set: self, new_tag_name: new_tag_name)
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_css_class(css_class)
|
40
|
+
change_list << Changes::AddCssClass.new(change_set: self, css_class: css_class)
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def apply_on_element(element)
|
47
|
+
change_list.each do |change|
|
48
|
+
change.apply(element)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module HtmlSurgeon
|
2
|
+
module Changes
|
3
|
+
class AddCssClass < Change
|
4
|
+
attr_reader :css_class
|
5
|
+
CLASS_ATTRIBUTE = 'class'.freeze
|
6
|
+
CLASS_SEPARATOR = ' '.freeze
|
7
|
+
|
8
|
+
def initialize(css_class:, **other)
|
9
|
+
@css_class = css_class
|
10
|
+
|
11
|
+
super **other
|
12
|
+
end
|
13
|
+
|
14
|
+
def log
|
15
|
+
"add css class #{css_class}"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def apply_in(element)
|
20
|
+
classes = element_classes element
|
21
|
+
classes << css_class
|
22
|
+
element.set_attribute(CLASS_ATTRIBUTE, classes.join(CLASS_SEPARATOR))
|
23
|
+
end
|
24
|
+
|
25
|
+
def audit_data(element)
|
26
|
+
basic_audit_data.merge type: :add_css_class,
|
27
|
+
existed_before: had_class?(element),
|
28
|
+
class: css_class
|
29
|
+
end
|
30
|
+
|
31
|
+
def element_classes(element)
|
32
|
+
element.get_attribute(CLASS_ATTRIBUTE).to_s.split(CLASS_SEPARATOR)
|
33
|
+
end
|
34
|
+
|
35
|
+
def had_class?(element)
|
36
|
+
element_classes(element).include? css_class
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module HtmlSurgeon
|
2
|
+
module Changes
|
3
|
+
class ReplaceTagName < Change
|
4
|
+
attr_reader :new_tag_name
|
5
|
+
|
6
|
+
def initialize(new_tag_name:, **other)
|
7
|
+
@new_tag_name = new_tag_name
|
8
|
+
|
9
|
+
super **other
|
10
|
+
end
|
11
|
+
|
12
|
+
def log
|
13
|
+
"replace tag name with #{new_tag_name}"
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def apply_in(element)
|
18
|
+
element.name = new_tag_name
|
19
|
+
end
|
20
|
+
|
21
|
+
def audit_data(element)
|
22
|
+
basic_audit_data.merge type: :replace_tag_name,
|
23
|
+
old: element.name,
|
24
|
+
new: new_tag_name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module HtmlSurgeon
|
2
|
+
class Service
|
3
|
+
attr_reader :given_html, :options
|
4
|
+
|
5
|
+
def initialize(html_string, audit: false, **extra_options)
|
6
|
+
@given_html = html_string
|
7
|
+
@audit = audit
|
8
|
+
@options = extra_options.merge audit: audit
|
9
|
+
end
|
10
|
+
|
11
|
+
def html
|
12
|
+
@html ||= doc.to_html
|
13
|
+
end
|
14
|
+
|
15
|
+
def audit?
|
16
|
+
!!@audit
|
17
|
+
end
|
18
|
+
|
19
|
+
def css(css_selector)
|
20
|
+
node_set = doc.css(css_selector)
|
21
|
+
ChangeSet.new(node_set, self)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def doc
|
26
|
+
@doc ||= Nokogiri::HTML.fragment @given_html.dup
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: html_surgeon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eduardo Turiño
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: oj
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: oj_mimic_json
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.10'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.10'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description:
|
112
|
+
email:
|
113
|
+
- eturino@eturino.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".rspec"
|
120
|
+
- ".travis.yml"
|
121
|
+
- Gemfile
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- bin/console
|
125
|
+
- bin/setup
|
126
|
+
- html_surgeon.gemspec
|
127
|
+
- lib/html_surgeon.rb
|
128
|
+
- lib/html_surgeon/abstract_method_error.rb
|
129
|
+
- lib/html_surgeon/change.rb
|
130
|
+
- lib/html_surgeon/change_set.rb
|
131
|
+
- lib/html_surgeon/changes/add_css_class.rb
|
132
|
+
- lib/html_surgeon/changes/replace_tag_name.rb
|
133
|
+
- lib/html_surgeon/service.rb
|
134
|
+
- lib/html_surgeon/version.rb
|
135
|
+
homepage: https://github.com/eturino/html_surgeon
|
136
|
+
licenses: []
|
137
|
+
metadata: {}
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 2.4.6
|
155
|
+
signing_key:
|
156
|
+
specification_version: 4
|
157
|
+
summary: Ruby gem for surgical changes in HTML fragment strings, using Nokogiri, with
|
158
|
+
optional audit trail in html attributes
|
159
|
+
test_files: []
|
160
|
+
has_rdoc:
|