draftjs_html 0.24.0 → 0.26.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/.github/workflows/ci.yml +36 -0
- data/README.md +35 -6
- data/lib/draftjs_html/from_html/char_list.rb +4 -0
- data/lib/draftjs_html/from_html/depth_stack.rb +3 -3
- data/lib/draftjs_html/from_html/elements.rb +3 -2
- data/lib/draftjs_html/from_html/pending_block.rb +24 -17
- data/lib/draftjs_html/from_html.rb +3 -1
- data/lib/draftjs_html/html_defaults.rb +1 -0
- data/lib/draftjs_html/spec_support/rspec.rb +42 -0
- data/lib/draftjs_html/spec_support.rb +23 -0
- data/lib/draftjs_html/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fe4601ed10ebae8924fe906ffad4cd56bebf7867ec80182876ad0a1b5a3b739
|
4
|
+
data.tar.gz: 5d14c45c7192c936fbbe524a72c4886acddaf20f1f2dff5ccf9c1ce3d8de8a5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38f78c86afbac0244a8eb967be90c6b647001e6a3bbbe3a6648190a45ac9cbecc2359c45f1fee5f995ed9584d037b2c337b8e267dece3c38e15a16a4dde8b775
|
7
|
+
data.tar.gz: 249423024673740842728d7b5cb8ca4ef1aa9bec1ee521be4402e21d5d89afa7f36563232de9c6af62831ae9cac3768c654537d75a8dbb44e25735f4d2dc0ac1
|
@@ -0,0 +1,36 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
pull_request:
|
6
|
+
workflow_dispatch:
|
7
|
+
# schedule:
|
8
|
+
# - cron: '42 5 * * *'
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
test:
|
12
|
+
strategy:
|
13
|
+
fail-fast: false
|
14
|
+
matrix:
|
15
|
+
ruby: [ '3.0' ]
|
16
|
+
|
17
|
+
runs-on: ubuntu-latest
|
18
|
+
name: Ruby ${{matrix.ruby}}
|
19
|
+
container: ruby:${{matrix.ruby}}
|
20
|
+
|
21
|
+
steps:
|
22
|
+
- uses: actions/checkout@v3
|
23
|
+
|
24
|
+
- name: Show ruby Version
|
25
|
+
run: |
|
26
|
+
ruby -v
|
27
|
+
|
28
|
+
- name: Install Modules
|
29
|
+
run: |
|
30
|
+
./bin/setup
|
31
|
+
|
32
|
+
- name: Run tests
|
33
|
+
run: |
|
34
|
+
rake spec
|
35
|
+
|
36
|
+
|
data/README.md
CHANGED
@@ -229,14 +229,43 @@ The callable should return a Hash with symbol keys. The supported values are:
|
|
229
229
|
- `data` (optional, default `{}`)
|
230
230
|
- an arbitrary data-bag (Hash) of entity data
|
231
231
|
|
232
|
-
|
232
|
+
### Spec support
|
233
233
|
|
234
|
-
|
234
|
+
To make it easier to test our own code, we've developed a few RSpec matchers that
|
235
|
+
make normalization and comparison of raw DraftJS use the RawBuilder DSL. To take
|
236
|
+
advantage of this, you can (for RSpec only, currently) include the following in
|
237
|
+
your `spec_helper`, or equivalent.
|
235
238
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
239
|
+
```ruby
|
240
|
+
require 'draftjs_html/spec_support/rspec'
|
241
|
+
|
242
|
+
RSpec.configure do |config|
|
243
|
+
config.include DraftjsHtml::SpecSupport::RSpecMatchers
|
244
|
+
end
|
245
|
+
```
|
246
|
+
|
247
|
+
Then, later in your tests, you can assert on raw DraftJS "json" like this:
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
my_raw_draftjs_hash = { blocks: [{ key: 'a-random-uuid', text: 'Hi!' }], entityMap: {} }
|
251
|
+
|
252
|
+
expect(my_raw_draftjs_hash).to eq_raw_draftjs {
|
253
|
+
text_block 'Hi!'
|
254
|
+
}
|
255
|
+
```
|
256
|
+
|
257
|
+
This will normalize the `key` values and other IDs to make _actual_ differences
|
258
|
+
easier to spot.
|
259
|
+
|
260
|
+
There's also a matcher called `eq_raw_draftjs_ignoring_keys` that takes an explicit
|
261
|
+
raw DraftJS hash on both sides.
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
my_raw_draftjs_hash = { blocks: [{ key: 'a-random-uuid', text: 'Hi!' }], entityMap: {} }
|
265
|
+
my_other_draftjs_hash = { blocks: [{ key: 'a-different-random-uuid', text: 'Hi!' }], entityMap: {} }
|
266
|
+
|
267
|
+
expect(my_raw_draftjs_hash).to eq_raw_draftjs_ignoring_keys my_other_draftjs_hash
|
268
|
+
```
|
240
269
|
|
241
270
|
## Development
|
242
271
|
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module DraftjsHtml
|
2
2
|
class FromHtml < Nokogiri::XML::SAX::Document
|
3
3
|
class DepthStack
|
4
|
-
def initialize(
|
4
|
+
def initialize(options)
|
5
5
|
@stack = []
|
6
6
|
@nodes = []
|
7
7
|
@list_depth = -1
|
8
8
|
@active_styles = []
|
9
|
-
@
|
9
|
+
@options = options
|
10
10
|
end
|
11
11
|
|
12
12
|
def push(tagname, attrs)
|
13
|
-
@stack << PendingBlock.from_tag(tagname, attrs, @nodes.dup, @list_depth,
|
13
|
+
@stack << PendingBlock.from_tag(tagname, attrs, @nodes.dup, @list_depth, options: @options)
|
14
14
|
track_block_node(tagname)
|
15
15
|
end
|
16
16
|
|
@@ -1,8 +1,9 @@
|
|
1
1
|
module DraftjsHtml
|
2
2
|
class FromHtml < Nokogiri::XML::SAX::Document
|
3
3
|
INLINE_STYLE_ELEMENTS = HtmlDefaults::HTML_STYLE_TAGS_TO_STYLE.keys.freeze
|
4
|
-
LIST_PARENT_ELEMENTS = %w[ol ul
|
5
|
-
INLINE_NON_STYLE_ELEMENTS = %w[a abbr cite font img output q samp span thead tbody td time var].freeze
|
4
|
+
LIST_PARENT_ELEMENTS = %w[ol ul].freeze
|
5
|
+
INLINE_NON_STYLE_ELEMENTS = %w[a abbr cite font img output q samp span table thead tbody td time var].freeze
|
6
6
|
BLOCK_CONTENT_ELEMENTS = %w[p dl h1 h2 h3 h4 h5 h6].freeze
|
7
|
+
FLUSH_BOUNDARIES = %w[OPENING div ol ul li tr].freeze
|
7
8
|
end
|
8
9
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module DraftjsHtml
|
2
2
|
class FromHtml < Nokogiri::XML::SAX::Document
|
3
|
-
PendingBlock = Struct.new(:tagname, :attrs, :chars, :entities, :pending_entities, :parent_tagnames, :depth, :
|
4
|
-
def self.from_tag(name, attrs, parent_tagnames, depth,
|
3
|
+
PendingBlock = Struct.new(:tagname, :attrs, :chars, :entities, :pending_entities, :parent_tagnames, :depth, :options, keyword_init: true) do
|
4
|
+
def self.from_tag(name, attrs, parent_tagnames, depth, options: {})
|
5
5
|
self.new(
|
6
6
|
tagname: name,
|
7
7
|
attrs: attrs,
|
@@ -10,7 +10,7 @@ module DraftjsHtml
|
|
10
10
|
pending_entities: [],
|
11
11
|
depth: depth,
|
12
12
|
parent_tagnames: parent_tagnames,
|
13
|
-
|
13
|
+
options: options
|
14
14
|
)
|
15
15
|
end
|
16
16
|
|
@@ -23,9 +23,7 @@ module DraftjsHtml
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def flushable?
|
26
|
-
|
27
|
-
(parent_tagnames.last == 'div' && tagname != 'div') ||
|
28
|
-
(!is_semantic_markup && tagname == 'div')
|
26
|
+
FLUSH_BOUNDARIES.include?(parent_tagnames.last)
|
29
27
|
end
|
30
28
|
|
31
29
|
def consume(other_pending_block)
|
@@ -35,21 +33,23 @@ module DraftjsHtml
|
|
35
33
|
end
|
36
34
|
|
37
35
|
def flush_to(draftjs)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
draftjs.typed_block(block_type, line.text, depth: [depth, 0].max)
|
36
|
+
text_buffer.each_line do |line|
|
37
|
+
block_type = line.atomic? ? 'atomic' : block_name
|
38
|
+
next unless should_flush_line?(line)
|
42
39
|
|
43
|
-
|
44
|
-
entity = entity_range.entity
|
45
|
-
draftjs.apply_entity entity[:type], entity_range.range, data: entity[:data], mutability: entity.fetch(:mutability, 'IMMUTABLE')
|
46
|
-
end
|
40
|
+
draftjs.typed_block(block_type, line.text, depth: [depth, 0].max)
|
47
41
|
|
48
|
-
|
49
|
-
|
50
|
-
|
42
|
+
line.entity_ranges.each do |entity_range|
|
43
|
+
entity = entity_range.entity
|
44
|
+
draftjs.apply_entity entity[:type], entity_range.range, data: entity[:data], mutability: entity.fetch(:mutability, 'IMMUTABLE')
|
45
|
+
end
|
46
|
+
|
47
|
+
line.style_ranges.each do |style_range|
|
48
|
+
draftjs.inline_style(style_range.style, style_range.range)
|
51
49
|
end
|
52
50
|
end
|
51
|
+
|
52
|
+
self.text_buffer = CharList.new
|
53
53
|
end
|
54
54
|
|
55
55
|
def block_name
|
@@ -65,6 +65,13 @@ module DraftjsHtml
|
|
65
65
|
def text_buffer=(other)
|
66
66
|
self[:chars] = other
|
67
67
|
end
|
68
|
+
|
69
|
+
def should_flush_line?(chars)
|
70
|
+
return true if chars.atomic?
|
71
|
+
return true unless options[:squeeze_whitespace_blocks]
|
72
|
+
|
73
|
+
options[:squeeze_whitespace_blocks] && chars.more_than_whitespace?
|
74
|
+
end
|
68
75
|
end
|
69
76
|
end
|
70
77
|
end
|
@@ -11,8 +11,8 @@ module DraftjsHtml
|
|
11
11
|
def initialize(options = {})
|
12
12
|
@draftjs = Draftjs::RawBuilder.new
|
13
13
|
@parser = Nokogiri::HTML4::SAX::Parser.new(self)
|
14
|
-
@depth_stack = DepthStack.new(is_semantic_markup: options.fetch(:is_semantic_markup, true))
|
15
14
|
@options = ensure_options!(options.dup)
|
15
|
+
@depth_stack = DepthStack.new(@options)
|
16
16
|
end
|
17
17
|
|
18
18
|
def convert(raw_html)
|
@@ -56,6 +56,7 @@ module DraftjsHtml
|
|
56
56
|
when *FromHtml::LIST_PARENT_ELEMENTS
|
57
57
|
@depth_stack.push_parent(name, attrs)
|
58
58
|
else
|
59
|
+
@depth_stack.flush_to(@draftjs) if FromHtml::FLUSH_BOUNDARIES.include?(name)
|
59
60
|
@depth_stack.push(name, attributes)
|
60
61
|
end
|
61
62
|
|
@@ -101,6 +102,7 @@ module DraftjsHtml
|
|
101
102
|
when 'img' then { type: 'IMAGE', mutability: 'IMMUTABLE', atomic: true, data: attrs }
|
102
103
|
end
|
103
104
|
}
|
105
|
+
opts[:squeeze_whitespace_blocks] ||= false
|
104
106
|
opts
|
105
107
|
end
|
106
108
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rspec/expectations'
|
2
|
+
require 'draftjs_html/spec_support'
|
3
|
+
|
4
|
+
module DraftjsHtml
|
5
|
+
module SpecSupport
|
6
|
+
module RSpecMatchers
|
7
|
+
extend RSpec::Matchers::DSL
|
8
|
+
|
9
|
+
matcher :eq_raw_draftjs do |expected|
|
10
|
+
include DraftjsHtml::SpecSupport::KeyNormalization
|
11
|
+
match do |actual|
|
12
|
+
@raw_draftjs = normalize_keys(DraftjsHtml::Draftjs::RawBuilder.build(&block_arg))
|
13
|
+
@actual = normalize_keys(actual)
|
14
|
+
|
15
|
+
values_match?(@raw_draftjs, @actual)
|
16
|
+
end
|
17
|
+
|
18
|
+
diffable
|
19
|
+
|
20
|
+
def expected
|
21
|
+
@raw_draftjs
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
matcher :eq_raw_draftjs_ignoring_keys do |expected|
|
26
|
+
include DraftjsHtml::SpecSupport::KeyNormalization
|
27
|
+
match do |actual|
|
28
|
+
@raw_draftjs = normalize_keys(expected)
|
29
|
+
@actual = normalize_keys(actual)
|
30
|
+
|
31
|
+
values_match?(@raw_draftjs, @actual)
|
32
|
+
end
|
33
|
+
|
34
|
+
diffable
|
35
|
+
|
36
|
+
def expected
|
37
|
+
@raw_draftjs
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DraftjsHtml
|
4
|
+
module SpecSupport
|
5
|
+
module KeyNormalization
|
6
|
+
def normalize_keys(raw_draftjs)
|
7
|
+
draftjs = DraftjsHtml::Draftjs::Content.parse(raw_draftjs)
|
8
|
+
draftjs.blocks.each.with_index do |block, i|
|
9
|
+
block.key = "block-key-#{i}"
|
10
|
+
end
|
11
|
+
|
12
|
+
draftjs.entity_map.keys.each.with_index do |entity_key, i|
|
13
|
+
new_key = "entity-key-#{i}"
|
14
|
+
draftjs.entity_map[new_key] = draftjs.entity_map.delete(entity_key)
|
15
|
+
matching_entity_ranges = draftjs.blocks.flat_map { |block| block.raw_entity_ranges.select { |entity_range| entity_range['key'] == entity_key } }
|
16
|
+
matching_entity_ranges.each { |range| range['key'] = new_key }
|
17
|
+
end
|
18
|
+
|
19
|
+
DraftjsHtml::Draftjs::ToRaw.new.convert(draftjs)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/draftjs_html/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: draftjs_html
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TJ Taylor
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -45,6 +45,7 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
+
- ".github/workflows/ci.yml"
|
48
49
|
- ".gitignore"
|
49
50
|
- ".rspec"
|
50
51
|
- ".travis.yml"
|
@@ -76,6 +77,8 @@ files:
|
|
76
77
|
- lib/draftjs_html/html_depth.rb
|
77
78
|
- lib/draftjs_html/node.rb
|
78
79
|
- lib/draftjs_html/overrideable_map.rb
|
80
|
+
- lib/draftjs_html/spec_support.rb
|
81
|
+
- lib/draftjs_html/spec_support/rspec.rb
|
79
82
|
- lib/draftjs_html/to_html.rb
|
80
83
|
- lib/draftjs_html/version.rb
|
81
84
|
homepage: https://github.com/dugancathal/draftjs_html
|