nokodiff 0.1.0 → 0.2.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 +4 -4
- data/README.md +49 -1
- data/app/assets/stylesheets/nokodiff.scss +75 -0
- data/lib/nokodiff/changes_in_fragments.rb +67 -0
- data/lib/nokodiff/differ.rb +103 -0
- data/lib/nokodiff/engine.rb +7 -0
- data/lib/nokodiff/formatting_helpers.rb +11 -0
- data/lib/nokodiff/text_node_diffs.rb +56 -0
- data/lib/nokodiff/version.rb +1 -1
- data/lib/nokodiff.rb +46 -1
- metadata +49 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bd5f28a6d69fffa081eb6dd4ade65be6aa8b2e309c7be553ab6820ffb7ab480e
|
|
4
|
+
data.tar.gz: 9b54a7aa1d6437c41ae47c5b3a6869ce97544426a9fae655940c227de34f5867
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f6088d65f6e4e007a39a4b30c07d6cc99080714952c68dd3ecc34cac4a10881910f3ce9d99826db4ecbd45917e8161e4f0f6b134c54d1d2ca31217b857b336e
|
|
7
|
+
data.tar.gz: af6c8bcaf758d33001c07f23d94d6897a83e3425c3093d342e05dde16fc6a6a0f59c6cfe2d46f1356da75c7c51babaf496947d1f01f4cb921d58908fa8c2be2d
|
data/README.md
CHANGED
|
@@ -1,6 +1,54 @@
|
|
|
1
1
|
# Nokodiff
|
|
2
2
|
|
|
3
|
-
A Ruby Gem to highlight additions, deletions and character level changes while preserving original HTML
|
|
3
|
+
A Ruby Gem to highlight additions, deletions and character level changes while preserving original HTML.
|
|
4
|
+
|
|
5
|
+
It includes functionality to:
|
|
6
|
+
* Compare two HTML fragments and output diffs with semantic HTML
|
|
7
|
+
* Inline character differences highlighting using `<strong>` tagging
|
|
8
|
+
* Blocks of added or removed content wrapped in aria labelled `<ins>` and `<del>` tags
|
|
9
|
+
* Optional CSS for styling the visual differences
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Install the gem:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
gem install nokodiff
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
or add it to your Gemfile
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
gem "nokodiff"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
In the controller:
|
|
28
|
+
```ruby
|
|
29
|
+
require 'nokodiff'
|
|
30
|
+
|
|
31
|
+
before_html = < YOUR HTML >
|
|
32
|
+
after_html = < YOUR HTML >
|
|
33
|
+
|
|
34
|
+
@differ = Nokodiff.diff(before_html, after_html)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
In the erb file:
|
|
38
|
+
```erb
|
|
39
|
+
<div>
|
|
40
|
+
<%= @differ %>
|
|
41
|
+
</div>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Including the CSS
|
|
45
|
+
|
|
46
|
+
In your application.scss file include:
|
|
47
|
+
```scss
|
|
48
|
+
@import "nokodiff";
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This will include the styling for `<del>`, `<ins>` and `<strong>` tags to allow colour coding, highlighting and underlining of changes.
|
|
4
52
|
|
|
5
53
|
## Licence
|
|
6
54
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// stylelint-disable selector-no-qualifying-type, max-nesting-depth
|
|
2
|
+
// Diff of two editions
|
|
3
|
+
$added-color: #e6fff3;
|
|
4
|
+
$strong-added-color: #99ffcf;
|
|
5
|
+
$removed-color: #fadede;
|
|
6
|
+
$strong-removed-color: #f3aeac;
|
|
7
|
+
$text-colour: #0b0c0c;
|
|
8
|
+
$light-grey: #f3f2f1;
|
|
9
|
+
$black: #0b0c0c;
|
|
10
|
+
|
|
11
|
+
.compare-editions {
|
|
12
|
+
border: 1px solid $light-grey;
|
|
13
|
+
border-left: 40px solid $light-grey;
|
|
14
|
+
padding: 15px;
|
|
15
|
+
|
|
16
|
+
.diff {
|
|
17
|
+
margin: 0 -15px;
|
|
18
|
+
padding: 0 15px;
|
|
19
|
+
word-wrap: break-word;
|
|
20
|
+
margin-bottom: 10px;
|
|
21
|
+
position: relative;
|
|
22
|
+
|
|
23
|
+
del,
|
|
24
|
+
ins {
|
|
25
|
+
text-decoration: none;
|
|
26
|
+
display: block;
|
|
27
|
+
padding: 2px 4px;
|
|
28
|
+
border-radius: 3px;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
del {
|
|
33
|
+
background-color: $removed-color;
|
|
34
|
+
padding-bottom: 2px;
|
|
35
|
+
|
|
36
|
+
strong {
|
|
37
|
+
font-weight: normal;
|
|
38
|
+
background-color: $strong-removed-color;
|
|
39
|
+
border-bottom: 2px dashed $black;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
ins {
|
|
44
|
+
background-color: $added-color;
|
|
45
|
+
padding-bottom: 2px;
|
|
46
|
+
|
|
47
|
+
strong {
|
|
48
|
+
font-weight: normal;
|
|
49
|
+
background-color: $strong-added-color;
|
|
50
|
+
border-bottom: 2px dashed $black;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
del::before,
|
|
55
|
+
ins::before {
|
|
56
|
+
position: absolute;
|
|
57
|
+
margin-left: -59px;
|
|
58
|
+
width: 40px;
|
|
59
|
+
text-align: center;
|
|
60
|
+
top: 0;
|
|
61
|
+
bottom: 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
del::before {
|
|
65
|
+
color: $text-colour;
|
|
66
|
+
background-color: $strong-removed-color;
|
|
67
|
+
content: "−";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
ins::before {
|
|
71
|
+
color: $text-colour;
|
|
72
|
+
background-color: $strong-added-color;
|
|
73
|
+
content: "+";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Nokodiff
|
|
2
|
+
class ChangesInFragments
|
|
3
|
+
include FormattingHelpers
|
|
4
|
+
def initialize(diff)
|
|
5
|
+
@diff = diff
|
|
6
|
+
@before_fragment = Nokogiri::HTML::DocumentFragment.parse("")
|
|
7
|
+
@after_fragment = Nokogiri::HTML::DocumentFragment.parse("")
|
|
8
|
+
|
|
9
|
+
@accumulated_before_text = ""
|
|
10
|
+
@accumulated_after_text = ""
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call
|
|
14
|
+
@diff.each do |change|
|
|
15
|
+
case change.action
|
|
16
|
+
when "="
|
|
17
|
+
no_change_emphasis(change)
|
|
18
|
+
when "!"
|
|
19
|
+
emphasise_change(change)
|
|
20
|
+
when "-"
|
|
21
|
+
emphasise_deletion(change)
|
|
22
|
+
when "+"
|
|
23
|
+
emphasise_addition(change)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
append_accumulated_text(before_fragment, accumulated_before_text)
|
|
28
|
+
append_accumulated_text(after_fragment, accumulated_after_text)
|
|
29
|
+
|
|
30
|
+
[before_fragment, after_fragment]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
attr_accessor :before_fragment, :after_fragment, :accumulated_before_text, :accumulated_after_text
|
|
36
|
+
|
|
37
|
+
def no_change_emphasis(change)
|
|
38
|
+
accumulated_before_text << change.old_element
|
|
39
|
+
accumulated_after_text << change.new_element
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def emphasise_change(change)
|
|
43
|
+
append_accumulated_text(before_fragment, accumulated_before_text)
|
|
44
|
+
append_accumulated_text(after_fragment, accumulated_after_text)
|
|
45
|
+
|
|
46
|
+
before_fragment.add_child(wrap_in_strong(change.old_element, before_fragment))
|
|
47
|
+
after_fragment.add_child(wrap_in_strong(change.new_element, after_fragment))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def emphasise_deletion(change)
|
|
51
|
+
append_accumulated_text(before_fragment, accumulated_before_text)
|
|
52
|
+
before_fragment.add_child(wrap_in_strong(change.old_element, before_fragment))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def emphasise_addition(change)
|
|
56
|
+
append_accumulated_text(after_fragment, accumulated_after_text)
|
|
57
|
+
after_fragment.add_child(wrap_in_strong(change.new_element, after_fragment))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def append_accumulated_text(fragment, accumulated_text)
|
|
61
|
+
return if accumulated_text.empty?
|
|
62
|
+
|
|
63
|
+
fragment.add_child(Nokogiri::XML::Text.new(accumulated_text, fragment))
|
|
64
|
+
accumulated_text.clear
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module Nokodiff
|
|
2
|
+
class Differ
|
|
3
|
+
def initialize(before_html, after_html)
|
|
4
|
+
@before = Nokogiri::HTML.fragment(before_html)
|
|
5
|
+
@after = Nokogiri::HTML.fragment(after_html)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def to_html
|
|
9
|
+
compared_blocks.map { |diff|
|
|
10
|
+
case diff[:status]
|
|
11
|
+
when :unchanged
|
|
12
|
+
unchanged_block(diff[:before])
|
|
13
|
+
when :changed
|
|
14
|
+
deleted_block(char_diff_html(diff[:before], diff[:after]).first) + added_block(char_diff_html(diff[:before], diff[:after]).last)
|
|
15
|
+
when :deleted
|
|
16
|
+
deleted_block(diff[:before])
|
|
17
|
+
when :added
|
|
18
|
+
added_block(diff[:after])
|
|
19
|
+
end
|
|
20
|
+
}.join("\n")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def compared_blocks
|
|
26
|
+
before_nodes = @before.children.to_a
|
|
27
|
+
after_nodes = @after.children.to_a
|
|
28
|
+
|
|
29
|
+
max = [before_nodes.length, after_nodes.length].max
|
|
30
|
+
|
|
31
|
+
max.times.map do |i|
|
|
32
|
+
before_node = before_nodes[i]
|
|
33
|
+
after_node = after_nodes[i]
|
|
34
|
+
|
|
35
|
+
set_change_status(before_node, after_node)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def char_diff_html(before_html, after_html)
|
|
40
|
+
before_dup = before_html.dup
|
|
41
|
+
after_dup = after_html.dup
|
|
42
|
+
|
|
43
|
+
before_fragment, after_fragment = Nokodiff::TextNodeDiffs.new(before_dup, after_dup).call
|
|
44
|
+
|
|
45
|
+
merge_adjacent_strong_tags(before_fragment)
|
|
46
|
+
merge_adjacent_strong_tags(after_fragment)
|
|
47
|
+
|
|
48
|
+
[before_fragment.to_html, after_fragment.to_html]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def set_change_status(before_node, after_node)
|
|
52
|
+
if before_node && after_node
|
|
53
|
+
if before_node.to_html.strip == after_node.to_html.strip
|
|
54
|
+
{ status: :unchanged, before: before_node, after: after_node }
|
|
55
|
+
else
|
|
56
|
+
{ status: :changed, before: before_node, after: after_node }
|
|
57
|
+
end
|
|
58
|
+
elsif before_node
|
|
59
|
+
{ status: :deleted, before: before_node, after: nil }
|
|
60
|
+
elsif after_node
|
|
61
|
+
{ status: :added, before: nil, after: after_node }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def merge_adjacent_strong_tags(node)
|
|
66
|
+
return unless node.element?
|
|
67
|
+
|
|
68
|
+
node.children.each do |child|
|
|
69
|
+
merge_adjacent_strong_tags(child) if child.element?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
node.children.each_cons(2) do |left, right|
|
|
73
|
+
next unless left.name == "strong" && right.name == "strong"
|
|
74
|
+
|
|
75
|
+
left.content = left.content + right.content
|
|
76
|
+
right.remove
|
|
77
|
+
|
|
78
|
+
merge_adjacent_strong_tags(node)
|
|
79
|
+
break
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def unchanged_block(html)
|
|
84
|
+
html.to_s
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def deleted_block(html)
|
|
88
|
+
%(
|
|
89
|
+
<div class="diff">
|
|
90
|
+
<del aria-label="removed content">#{html}</del>
|
|
91
|
+
</div>
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def added_block(html)
|
|
96
|
+
%(
|
|
97
|
+
<div class="diff">
|
|
98
|
+
<ins aria-label="added content">#{html}</ins>
|
|
99
|
+
</div>
|
|
100
|
+
)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Nokodiff
|
|
2
|
+
module FormattingHelpers
|
|
3
|
+
def wrap_in_strong(char, fragment)
|
|
4
|
+
Nokogiri::XML::Node.new("strong", fragment.document).tap { |n| n.content = char }
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def strong(text_node)
|
|
8
|
+
text_node.replace(wrap_in_strong(text_node.to_html, text_node.parent))
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Nokodiff
|
|
2
|
+
class TextNodeDiffs
|
|
3
|
+
include FormattingHelpers
|
|
4
|
+
def initialize(before_fragment, after_fragment)
|
|
5
|
+
@before_fragment = before_fragment
|
|
6
|
+
@after_fragment = after_fragment
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def call
|
|
10
|
+
diff_text_nodes(before_fragment, after_fragment)
|
|
11
|
+
[before_fragment, after_fragment]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
attr_accessor :before_fragment, :after_fragment
|
|
17
|
+
|
|
18
|
+
def diff_text_nodes(before_node, after_node)
|
|
19
|
+
if before_node&.text? || after_node&.text?
|
|
20
|
+
diff_text_node_content(before_node, after_node)
|
|
21
|
+
elsif before_node&.element? || after_node&.element?
|
|
22
|
+
before_children = before_node ? before_node.children.to_a : []
|
|
23
|
+
after_children = after_node ? after_node.children.to_a : []
|
|
24
|
+
|
|
25
|
+
max_child_count = [before_children.length, after_children.length].max
|
|
26
|
+
|
|
27
|
+
(0..max_child_count).each do |i|
|
|
28
|
+
diff_text_nodes(before_children[i], after_children[i])
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def diff_text_node_content(before_text_node, after_text_node)
|
|
34
|
+
return strong(before_text_node) if text_removed?(before_text_node, after_text_node)
|
|
35
|
+
return strong(after_text_node) if text_added?(before_text_node, after_text_node)
|
|
36
|
+
|
|
37
|
+
before_chars = before_text_node.text.chars
|
|
38
|
+
after_chars = after_text_node.text.chars
|
|
39
|
+
|
|
40
|
+
diff = Diff::LCS.sdiff(before_chars, after_chars)
|
|
41
|
+
|
|
42
|
+
before_fragment, after_fragment = Nokodiff::ChangesInFragments.new(diff).call
|
|
43
|
+
|
|
44
|
+
before_text_node.replace(before_fragment)
|
|
45
|
+
after_text_node.replace(after_fragment)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def text_removed?(before_node, after_node)
|
|
49
|
+
before_node && after_node.nil?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def text_added?(before_node, after_node)
|
|
53
|
+
before_node.nil? && after_node
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/nokodiff/version.rb
CHANGED
data/lib/nokodiff.rb
CHANGED
|
@@ -1,8 +1,53 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "nokogiri"
|
|
4
|
+
require "diff-lcs"
|
|
5
|
+
|
|
6
|
+
require_relative "nokodiff/formatting_helpers"
|
|
3
7
|
require_relative "nokodiff/version"
|
|
8
|
+
require_relative "nokodiff/differ"
|
|
9
|
+
require_relative "nokodiff/engine"
|
|
10
|
+
require_relative "nokodiff/text_node_diffs"
|
|
11
|
+
require_relative "nokodiff/changes_in_fragments"
|
|
4
12
|
|
|
5
13
|
module Nokodiff
|
|
14
|
+
def self.diff(before_html, after_html)
|
|
15
|
+
HTMLFragmentValidator.validate_html!(before_html)
|
|
16
|
+
HTMLFragmentValidator.validate_html!(after_html)
|
|
17
|
+
|
|
18
|
+
html = Differ.new(before_html, after_html).to_html
|
|
19
|
+
safe_html(html)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.safe_html(html)
|
|
23
|
+
html.respond_to?(:html_safe) ? html.html_safe : html
|
|
24
|
+
end
|
|
25
|
+
|
|
6
26
|
class Error < StandardError; end
|
|
7
|
-
|
|
27
|
+
|
|
28
|
+
module HTMLFragmentValidator
|
|
29
|
+
module_function
|
|
30
|
+
|
|
31
|
+
def validate_html!(html)
|
|
32
|
+
document = Nokogiri::HTML::DocumentFragment.parse(html)
|
|
33
|
+
|
|
34
|
+
invalid_text_nodes = document.children.select do |node|
|
|
35
|
+
if node.element?
|
|
36
|
+
false
|
|
37
|
+
elsif node.comment?
|
|
38
|
+
false
|
|
39
|
+
elsif node.text?
|
|
40
|
+
!node.text.strip.empty?
|
|
41
|
+
else
|
|
42
|
+
true
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
unless invalid_text_nodes.empty?
|
|
47
|
+
raise ArgumentError, "Invalid HTML input"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
document
|
|
51
|
+
end
|
|
52
|
+
end
|
|
8
53
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nokodiff
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GOV.UK Dev
|
|
@@ -9,6 +9,20 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: rake
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -88,7 +102,7 @@ dependencies:
|
|
|
88
102
|
version: '6'
|
|
89
103
|
- - "<"
|
|
90
104
|
- !ruby/object:Gem::Version
|
|
91
|
-
version: 8.1.
|
|
105
|
+
version: 8.1.3
|
|
92
106
|
type: :runtime
|
|
93
107
|
prerelease: false
|
|
94
108
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -98,21 +112,41 @@ dependencies:
|
|
|
98
112
|
version: '6'
|
|
99
113
|
- - "<"
|
|
100
114
|
- !ruby/object:Gem::Version
|
|
101
|
-
version: 8.1.
|
|
115
|
+
version: 8.1.3
|
|
116
|
+
- !ruby/object:Gem::Dependency
|
|
117
|
+
name: diff-lcs
|
|
118
|
+
requirement: !ruby/object:Gem::Requirement
|
|
119
|
+
requirements:
|
|
120
|
+
- - ">="
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
version: '0'
|
|
123
|
+
type: :runtime
|
|
124
|
+
prerelease: false
|
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
126
|
+
requirements:
|
|
127
|
+
- - ">="
|
|
128
|
+
- !ruby/object:Gem::Version
|
|
129
|
+
version: '0'
|
|
102
130
|
- !ruby/object:Gem::Dependency
|
|
103
131
|
name: gds-api-adapters
|
|
104
132
|
requirement: !ruby/object:Gem::Requirement
|
|
105
133
|
requirements:
|
|
106
|
-
- - "
|
|
134
|
+
- - ">="
|
|
135
|
+
- !ruby/object:Gem::Version
|
|
136
|
+
version: '101.0'
|
|
137
|
+
- - "<"
|
|
107
138
|
- !ruby/object:Gem::Version
|
|
108
|
-
version: 101.
|
|
139
|
+
version: '101.3'
|
|
109
140
|
type: :runtime
|
|
110
141
|
prerelease: false
|
|
111
142
|
version_requirements: !ruby/object:Gem::Requirement
|
|
112
143
|
requirements:
|
|
113
|
-
- - "
|
|
144
|
+
- - ">="
|
|
145
|
+
- !ruby/object:Gem::Version
|
|
146
|
+
version: '101.0'
|
|
147
|
+
- - "<"
|
|
114
148
|
- !ruby/object:Gem::Version
|
|
115
|
-
version: 101.
|
|
149
|
+
version: '101.3'
|
|
116
150
|
- !ruby/object:Gem::Dependency
|
|
117
151
|
name: govspeak
|
|
118
152
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -136,7 +170,7 @@ dependencies:
|
|
|
136
170
|
version: '6'
|
|
137
171
|
- - "<"
|
|
138
172
|
- !ruby/object:Gem::Version
|
|
139
|
-
version: 8.1.
|
|
173
|
+
version: 8.1.3
|
|
140
174
|
type: :runtime
|
|
141
175
|
prerelease: false
|
|
142
176
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -146,7 +180,7 @@ dependencies:
|
|
|
146
180
|
version: '6'
|
|
147
181
|
- - "<"
|
|
148
182
|
- !ruby/object:Gem::Version
|
|
149
|
-
version: 8.1.
|
|
183
|
+
version: 8.1.3
|
|
150
184
|
- !ruby/object:Gem::Dependency
|
|
151
185
|
name: view_component
|
|
152
186
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -169,7 +203,13 @@ extra_rdoc_files: []
|
|
|
169
203
|
files:
|
|
170
204
|
- LICENCE.txt
|
|
171
205
|
- README.md
|
|
206
|
+
- app/assets/stylesheets/nokodiff.scss
|
|
172
207
|
- lib/nokodiff.rb
|
|
208
|
+
- lib/nokodiff/changes_in_fragments.rb
|
|
209
|
+
- lib/nokodiff/differ.rb
|
|
210
|
+
- lib/nokodiff/engine.rb
|
|
211
|
+
- lib/nokodiff/formatting_helpers.rb
|
|
212
|
+
- lib/nokodiff/text_node_diffs.rb
|
|
173
213
|
- lib/nokodiff/version.rb
|
|
174
214
|
homepage: https://github.com/alphagov/nokodiff
|
|
175
215
|
licenses:
|