editor_js 0.0.1 → 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 +4 -4
- data/.rspec +0 -1
- data/.rubocop.yml +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +85 -1
- data/README.md +11 -1
- data/bin/console +4 -4
- data/editor_js.gemspec +7 -0
- data/lib/editor_js.rb +37 -3
- data/lib/editor_js/blocks/base.rb +114 -0
- data/lib/editor_js/blocks/checklist_block.rb +45 -0
- data/lib/editor_js/blocks/code_block.rb +29 -0
- data/lib/editor_js/blocks/delimiter_block.rb +22 -0
- data/lib/editor_js/blocks/embed_block.rb +59 -0
- data/lib/editor_js/blocks/header_block.rb +35 -0
- data/lib/editor_js/blocks/image_block.rb +55 -0
- data/lib/editor_js/blocks/list_block.rb +58 -0
- data/lib/editor_js/blocks/markdown_block.rb +66 -0
- data/lib/editor_js/blocks/paragraph_block.rb +42 -0
- data/lib/editor_js/blocks/qiniu_image_block.rb +8 -0
- data/lib/editor_js/blocks/quote_block.rb +60 -0
- data/lib/editor_js/blocks/table_block.rb +45 -0
- data/lib/editor_js/document.rb +58 -0
- data/lib/editor_js/version.rb +1 -1
- metadata +127 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 45e691b09b979e4afd888b80ec43cb81888affd974675ac383a3b87f75284f09
|
|
4
|
+
data.tar.gz: 96f7ed2d48805081e9abfd3fd828d90508d59c726301e8cc4b2448ca13758c62
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '09781ff6957c7bcfaed67300b6e2ad5b6deedb98c642ca58a7f3e0b3c1cbee9bcc7a41dcc96760750f649a60f930deeb288328354b840070b7a70ce8eb20b645'
|
|
7
|
+
data.tar.gz: 064a72ad6b97626c70c6e2a1767ba493d6c2b0c184de93136f4816dc0129130b2e9985777842772e08e136ef65b3eacb137beb51419ef51786d635fcea5222af
|
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
|
@@ -5,3 +5,9 @@ cache: bundler
|
|
|
5
5
|
rvm:
|
|
6
6
|
- 2.5.5
|
|
7
7
|
before_install: gem install bundler -v 2.0.2
|
|
8
|
+
before_script:
|
|
9
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
|
10
|
+
- chmod +x ./cc-test-reporter
|
|
11
|
+
- ./cc-test-reporter before-build
|
|
12
|
+
after_script:
|
|
13
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,72 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
editor_js (0.0
|
|
4
|
+
editor_js (0.1.0)
|
|
5
|
+
actionview (>= 4)
|
|
6
|
+
activesupport (>= 4)
|
|
7
|
+
coderay (~> 1.1, >= 1.1.2)
|
|
8
|
+
htmlentities (~> 4.3, >= 4.3.4)
|
|
9
|
+
json-schema (~> 2)
|
|
10
|
+
redcarpet (~> 3.5)
|
|
11
|
+
sanitize (~> 5.1)
|
|
5
12
|
|
|
6
13
|
GEM
|
|
7
14
|
remote: https://rubygems.org/
|
|
8
15
|
specs:
|
|
16
|
+
actionview (6.0.1)
|
|
17
|
+
activesupport (= 6.0.1)
|
|
18
|
+
builder (~> 3.1)
|
|
19
|
+
erubi (~> 1.4)
|
|
20
|
+
rails-dom-testing (~> 2.0)
|
|
21
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
22
|
+
activesupport (6.0.1)
|
|
23
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
24
|
+
i18n (>= 0.7, < 2)
|
|
25
|
+
minitest (~> 5.1)
|
|
26
|
+
tzinfo (~> 1.1)
|
|
27
|
+
zeitwerk (~> 2.2)
|
|
28
|
+
addressable (2.7.0)
|
|
29
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
30
|
+
ast (2.4.0)
|
|
31
|
+
builder (3.2.4)
|
|
32
|
+
coderay (1.1.2)
|
|
33
|
+
concurrent-ruby (1.1.5)
|
|
34
|
+
crass (1.0.5)
|
|
9
35
|
diff-lcs (1.3)
|
|
36
|
+
docile (1.3.2)
|
|
37
|
+
erubi (1.9.0)
|
|
38
|
+
htmlentities (4.3.4)
|
|
39
|
+
i18n (1.7.0)
|
|
40
|
+
concurrent-ruby (~> 1.0)
|
|
41
|
+
jaro_winkler (1.5.4)
|
|
42
|
+
json (2.3.0)
|
|
43
|
+
json-schema (2.8.1)
|
|
44
|
+
addressable (>= 2.4)
|
|
45
|
+
loofah (2.4.0)
|
|
46
|
+
crass (~> 1.0.2)
|
|
47
|
+
nokogiri (>= 1.5.9)
|
|
48
|
+
method_source (0.9.2)
|
|
49
|
+
mini_portile2 (2.4.0)
|
|
50
|
+
minitest (5.13.0)
|
|
51
|
+
nokogiri (1.10.7)
|
|
52
|
+
mini_portile2 (~> 2.4.0)
|
|
53
|
+
nokogumbo (2.0.2)
|
|
54
|
+
nokogiri (~> 1.8, >= 1.8.4)
|
|
55
|
+
parallel (1.19.1)
|
|
56
|
+
parser (2.6.5.0)
|
|
57
|
+
ast (~> 2.4.0)
|
|
58
|
+
pry (0.12.2)
|
|
59
|
+
coderay (~> 1.1.0)
|
|
60
|
+
method_source (~> 0.9.0)
|
|
61
|
+
public_suffix (4.0.1)
|
|
62
|
+
rails-dom-testing (2.0.3)
|
|
63
|
+
activesupport (>= 4.2.0)
|
|
64
|
+
nokogiri (>= 1.6)
|
|
65
|
+
rails-html-sanitizer (1.3.0)
|
|
66
|
+
loofah (~> 2.3)
|
|
67
|
+
rainbow (3.0.0)
|
|
10
68
|
rake (10.5.0)
|
|
69
|
+
redcarpet (3.5.0)
|
|
11
70
|
rspec (3.9.0)
|
|
12
71
|
rspec-core (~> 3.9.0)
|
|
13
72
|
rspec-expectations (~> 3.9.0)
|
|
@@ -21,6 +80,28 @@ GEM
|
|
|
21
80
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
22
81
|
rspec-support (~> 3.9.0)
|
|
23
82
|
rspec-support (3.9.0)
|
|
83
|
+
rubocop (0.77.0)
|
|
84
|
+
jaro_winkler (~> 1.5.1)
|
|
85
|
+
parallel (~> 1.10)
|
|
86
|
+
parser (>= 2.6)
|
|
87
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
88
|
+
ruby-progressbar (~> 1.7)
|
|
89
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
|
90
|
+
ruby-progressbar (1.10.1)
|
|
91
|
+
sanitize (5.1.0)
|
|
92
|
+
crass (~> 1.0.2)
|
|
93
|
+
nokogiri (>= 1.8.0)
|
|
94
|
+
nokogumbo (~> 2.0)
|
|
95
|
+
simplecov (0.17.1)
|
|
96
|
+
docile (~> 1.1)
|
|
97
|
+
json (>= 1.8, < 3)
|
|
98
|
+
simplecov-html (~> 0.10.0)
|
|
99
|
+
simplecov-html (0.10.2)
|
|
100
|
+
thread_safe (0.3.6)
|
|
101
|
+
tzinfo (1.2.5)
|
|
102
|
+
thread_safe (~> 0.1)
|
|
103
|
+
unicode-display_width (1.6.0)
|
|
104
|
+
zeitwerk (2.2.2)
|
|
24
105
|
|
|
25
106
|
PLATFORMS
|
|
26
107
|
ruby
|
|
@@ -28,8 +109,11 @@ PLATFORMS
|
|
|
28
109
|
DEPENDENCIES
|
|
29
110
|
bundler (~> 2.0)
|
|
30
111
|
editor_js!
|
|
112
|
+
pry (~> 0.12.2)
|
|
31
113
|
rake (~> 10.0)
|
|
32
114
|
rspec (~> 3.0)
|
|
115
|
+
rubocop (~> 0.77.0)
|
|
116
|
+
simplecov (~> 0.17.1)
|
|
33
117
|
|
|
34
118
|
BUNDLED WITH
|
|
35
119
|
2.0.2
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# EditorJs
|
|
2
2
|
|
|
3
|
+
[](https://badge.fury.io/rb/editor_js) [](https://travis-ci.org/xiaohui-zhangxh/editor_js) [](https://codeclimate.com/github/xiaohui-zhangxh/editor_js/maintainability) [](https://codeclimate.com/github/xiaohui-zhangxh/editor_js/test_coverage) 
|
|
4
|
+
|
|
3
5
|
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/editor_js`. To experiment with that code, run `bin/console` for an interactive prompt.
|
|
4
6
|
|
|
5
7
|
TODO: Delete this and the text above, and describe your gem
|
|
@@ -22,7 +24,15 @@ Or install it yourself as:
|
|
|
22
24
|
|
|
23
25
|
## Usage
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
**Parse document:**
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
doc = EditorJs::Document.new(editor_js_output)
|
|
31
|
+
doc.render # [String] render HTML for display
|
|
32
|
+
doc.plain # [String] render text for full-text searching
|
|
33
|
+
doc.output # [Hash] return sanitized data
|
|
34
|
+
|
|
35
|
+
```
|
|
26
36
|
|
|
27
37
|
## Development
|
|
28
38
|
|
data/bin/console
CHANGED
|
@@ -7,8 +7,8 @@ require "editor_js"
|
|
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
|
8
8
|
|
|
9
9
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
require "pry"
|
|
11
|
+
Pry.start
|
|
12
12
|
|
|
13
|
-
require "irb"
|
|
14
|
-
IRB.start(__FILE__)
|
|
13
|
+
# require "irb"
|
|
14
|
+
# IRB.start(__FILE__)
|
data/editor_js.gemspec
CHANGED
|
@@ -25,6 +25,13 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
|
|
26
26
|
spec.require_paths = ["lib"]
|
|
27
27
|
|
|
28
|
+
spec.add_dependency 'actionview', '>= 4'
|
|
29
|
+
spec.add_dependency 'activesupport', '>= 4'
|
|
30
|
+
spec.add_dependency 'json-schema', '~> 2'
|
|
31
|
+
spec.add_dependency 'sanitize', '~> 5.1'
|
|
32
|
+
spec.add_dependency 'htmlentities', '~> 4.3', '>= 4.3.4'
|
|
33
|
+
spec.add_dependency 'redcarpet', '~> 3.5'
|
|
34
|
+
spec.add_dependency 'coderay', '~> 1.1', '>= 1.1.2'
|
|
28
35
|
spec.add_development_dependency "bundler", "~> 2.0"
|
|
29
36
|
spec.add_development_dependency "rake", "~> 10.0"
|
|
30
37
|
spec.add_development_dependency "rspec", "~> 3.0"
|
data/lib/editor_js.rb
CHANGED
|
@@ -1,6 +1,40 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'active_support/core_ext/hash/keys'
|
|
3
|
+
require 'active_support/core_ext/string/inflections'
|
|
4
|
+
require 'active_support/core_ext/string/output_safety'
|
|
5
|
+
require 'active_support/core_ext/object/deep_dup'
|
|
6
|
+
require 'action_view'
|
|
7
|
+
require 'action_view/helpers'
|
|
8
|
+
require 'json-schema'
|
|
9
|
+
require 'sanitize'
|
|
10
|
+
require 'htmlentities'
|
|
11
|
+
require 'redcarpet'
|
|
12
|
+
require 'coderay'
|
|
13
|
+
require 'editor_js/version'
|
|
14
|
+
require 'editor_js/blocks/base'
|
|
15
|
+
require 'editor_js/blocks/checklist_block'
|
|
16
|
+
require 'editor_js/blocks/code_block'
|
|
17
|
+
require 'editor_js/blocks/delimiter_block'
|
|
18
|
+
require 'editor_js/blocks/embed_block'
|
|
19
|
+
require 'editor_js/blocks/header_block'
|
|
20
|
+
require 'editor_js/blocks/image_block'
|
|
21
|
+
require 'editor_js/blocks/list_block'
|
|
22
|
+
require 'editor_js/blocks/markdown_block'
|
|
23
|
+
require 'editor_js/blocks/paragraph_block'
|
|
24
|
+
require 'editor_js/blocks/qiniu_image_block'
|
|
25
|
+
require 'editor_js/blocks/quote_block'
|
|
26
|
+
require 'editor_js/blocks/table_block'
|
|
27
|
+
require 'editor_js/document'
|
|
2
28
|
|
|
3
29
|
module EditorJs
|
|
4
|
-
class
|
|
5
|
-
|
|
30
|
+
class << self
|
|
31
|
+
# css name prefix of blocks
|
|
32
|
+
def css_name_prefix
|
|
33
|
+
@css_name_prefix ||= 'editor_js--'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def css_name_prefix=(prefix)
|
|
37
|
+
@css_name_prefix = prefix
|
|
38
|
+
end
|
|
39
|
+
end
|
|
6
40
|
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module EditorJs
|
|
2
|
+
module Blocks
|
|
3
|
+
class Base
|
|
4
|
+
InvalidBlockDataError = Class.new(StandardError)
|
|
5
|
+
InvalidBlockTypeError = Class.new(StandardError)
|
|
6
|
+
include ActionView::Helpers::TagHelper
|
|
7
|
+
include ActionView::Helpers::TextHelper
|
|
8
|
+
include ERB::Util
|
|
9
|
+
|
|
10
|
+
# ActionView::Helpers::TagHelper requires output_buffer accessor
|
|
11
|
+
attr_accessor :raw, :output_buffer
|
|
12
|
+
|
|
13
|
+
def initialize(raw)
|
|
14
|
+
@raw = raw
|
|
15
|
+
@content = cast_block_data_to_hash(raw.deep_dup)
|
|
16
|
+
sanitize!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Define JSON format of data
|
|
20
|
+
def schema
|
|
21
|
+
raise NotImplementedError
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Render HTML
|
|
25
|
+
def render(_options = {})
|
|
26
|
+
raise NotImplementedError
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Sanitize content of data
|
|
30
|
+
def sanitize!; end
|
|
31
|
+
|
|
32
|
+
# Render plain text, for full-text searching
|
|
33
|
+
def plain; end
|
|
34
|
+
|
|
35
|
+
# Validate data
|
|
36
|
+
def valid?
|
|
37
|
+
JSON::Validator.validate(schema, data)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def type
|
|
41
|
+
self.class.type
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def data
|
|
45
|
+
@content['data']
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def decode_html(string)
|
|
49
|
+
html_decoder.decode(string)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def css_name(name = nil)
|
|
53
|
+
"#{css_prefix}#{name}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def output
|
|
57
|
+
@content
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.type
|
|
61
|
+
@type ||= self.to_s.underscore.split('/').last.gsub('_block', '')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self.inherited(parent)
|
|
65
|
+
@registry ||= {}
|
|
66
|
+
@registry[parent.type] = parent
|
|
67
|
+
super
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.load(block_data)
|
|
71
|
+
block_data = JSON.parse(block_data) unless block_data.is_a?(Hash)
|
|
72
|
+
klass = @registry[block_data['type']]
|
|
73
|
+
raise InvalidBlockTypeError, block_data['type'] if klass.nil?
|
|
74
|
+
|
|
75
|
+
klass.new(block_data)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def cast_block_data_to_hash(block_data)
|
|
81
|
+
raise InvalidBlockDataError, block_data unless block_data.is_a?(Hash)
|
|
82
|
+
|
|
83
|
+
block_data = block_data.deep_stringify_keys
|
|
84
|
+
raise InvalidBlockDataError, "block type <#{block_data['type']}> doesn't match <#{type}>" unless block_data['type'] == type
|
|
85
|
+
|
|
86
|
+
block_data
|
|
87
|
+
rescue JSON::ParserError => _e
|
|
88
|
+
raise InvalidBlockDataError, "Invalid JSON: #{block_data}"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def css_prefix
|
|
92
|
+
@css_prefix ||= "#{EditorJs.css_name_prefix}#{type}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def html_decoder
|
|
96
|
+
@html_decoder ||= begin
|
|
97
|
+
with_customized_html_mappings do
|
|
98
|
+
HTMLEntities::Decoder.new('expanded')
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def with_customized_html_mappings
|
|
104
|
+
original_mappings = HTMLEntities::MAPPINGS['expanded']
|
|
105
|
+
customized_mappings = original_mappings.dup
|
|
106
|
+
customized_mappings['nbsp'] = 32
|
|
107
|
+
HTMLEntities::MAPPINGS['expanded'] = customized_mappings
|
|
108
|
+
yield
|
|
109
|
+
ensure
|
|
110
|
+
HTMLEntities::MAPPINGS['expanded'] = original_mappings
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class ChecklistBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
properties:
|
|
11
|
+
items:
|
|
12
|
+
type: array
|
|
13
|
+
items:
|
|
14
|
+
type: object
|
|
15
|
+
additionalProperties: false
|
|
16
|
+
properties:
|
|
17
|
+
text:
|
|
18
|
+
type: string
|
|
19
|
+
checked:
|
|
20
|
+
type: boolean
|
|
21
|
+
required:
|
|
22
|
+
- text
|
|
23
|
+
YAML
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def render(_options = {})
|
|
27
|
+
content_tag :div, class: css_name do
|
|
28
|
+
data['items'].each do |item|
|
|
29
|
+
concat content_tag(:input, item['text'], type: 'checkbox', disabled: true, checked: item['checked'])
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def sanitize!
|
|
35
|
+
data['items'].each do |item|
|
|
36
|
+
item['text'] = Sanitize.fragment(item['text'], remove_contents: true).strip
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def plain
|
|
41
|
+
data['items'].map { |item| decode_html(item['text']).strip }.join(', ')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class CodeBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
properties:
|
|
11
|
+
code:
|
|
12
|
+
type: string
|
|
13
|
+
required:
|
|
14
|
+
- code
|
|
15
|
+
YAML
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def render(_options = {})
|
|
19
|
+
content_tag :code, class: css_name do
|
|
20
|
+
data['code']
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def plain
|
|
25
|
+
data['code'].strip
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class DelimiterBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
YAML
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def render(_options = {})
|
|
14
|
+
content_tag :hr, '', class: css_name
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def plain
|
|
18
|
+
''
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class EmbedBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
properties:
|
|
11
|
+
caption:
|
|
12
|
+
type: string
|
|
13
|
+
embed:
|
|
14
|
+
type: string
|
|
15
|
+
height:
|
|
16
|
+
type:
|
|
17
|
+
- number
|
|
18
|
+
- string
|
|
19
|
+
service:
|
|
20
|
+
type: string
|
|
21
|
+
source:
|
|
22
|
+
type: string
|
|
23
|
+
width:
|
|
24
|
+
type:
|
|
25
|
+
- number
|
|
26
|
+
- string
|
|
27
|
+
required:
|
|
28
|
+
- embed
|
|
29
|
+
- service
|
|
30
|
+
- source
|
|
31
|
+
- width
|
|
32
|
+
- height
|
|
33
|
+
YAML
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def render(options = {})
|
|
37
|
+
content_tag :div, class: css_name do
|
|
38
|
+
concat content_tag(:iframe, '',
|
|
39
|
+
src: data['embed'],
|
|
40
|
+
width: data['width'],
|
|
41
|
+
height: data['height'],
|
|
42
|
+
frameborder: options.fetch('frameborder', '0'),
|
|
43
|
+
allowfullscreen: options.fetch('allowfullscreen', true))
|
|
44
|
+
concat content_tag(:span, data['caption'])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def sanitize
|
|
49
|
+
%w(caption embed height service source width).each do |key|
|
|
50
|
+
data[key] = Sanitize.fragment(data[key], remove_contents: true).strip
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def plain
|
|
55
|
+
data['caption'].strip
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class HeaderBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
properties:
|
|
11
|
+
text:
|
|
12
|
+
type: string
|
|
13
|
+
level:
|
|
14
|
+
type: number
|
|
15
|
+
enum: [1,2,3,4,5,6]
|
|
16
|
+
required:
|
|
17
|
+
- text
|
|
18
|
+
- level
|
|
19
|
+
YAML
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def render(_options = {})
|
|
23
|
+
content_tag(:"h#{data['level']}", data['text'].html_safe, class: css_name)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def sanitize!
|
|
27
|
+
data['text'] = Sanitize.fragment(data['text'], remove_contents: true).strip
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def plain
|
|
31
|
+
decode_html data['text'].strip
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class ImageBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
properties:
|
|
11
|
+
caption:
|
|
12
|
+
type: string
|
|
13
|
+
url:
|
|
14
|
+
type: string
|
|
15
|
+
stretched:
|
|
16
|
+
type: boolean
|
|
17
|
+
withBackground:
|
|
18
|
+
type: boolean
|
|
19
|
+
withBorder:
|
|
20
|
+
type: boolean
|
|
21
|
+
required:
|
|
22
|
+
- url
|
|
23
|
+
YAML
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def render(_options = {})
|
|
27
|
+
content_tag :div, class: css_name do
|
|
28
|
+
url = data['url']
|
|
29
|
+
caption = data['caption']
|
|
30
|
+
withBorder = data['withBorder']
|
|
31
|
+
withBackground = data['withBackground']
|
|
32
|
+
stretched = data['stretched']
|
|
33
|
+
|
|
34
|
+
html_class = "#{css_name}__picture"
|
|
35
|
+
html_class += " #{css_name}__picture--stretched" if stretched
|
|
36
|
+
html_class += " #{css_name}__picture--with-background" if withBackground
|
|
37
|
+
html_class += " #{css_name}__picture--with-border" if withBorder
|
|
38
|
+
|
|
39
|
+
html_str = content_tag :div, class: html_class do
|
|
40
|
+
content_tag :img, '', src: url
|
|
41
|
+
end
|
|
42
|
+
html_str << content_tag(:div, caption.html_safe, class: "#{css_name}__caption").html_safe
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def sanitize!
|
|
47
|
+
data['caption'] = Sanitize.fragment(data['caption'], remove_contents: true)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def plain
|
|
51
|
+
decode_html data['caption'].strip
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class ListBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
properties:
|
|
11
|
+
style:
|
|
12
|
+
type: string
|
|
13
|
+
pattern: ^(un)?ordered$
|
|
14
|
+
items:
|
|
15
|
+
type: array
|
|
16
|
+
items:
|
|
17
|
+
type: string
|
|
18
|
+
YAML
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def render(_options = {})
|
|
22
|
+
tag = data['style'] == 'unordered' ? :ul : :ol
|
|
23
|
+
content_tag(tag, class: css_name) do
|
|
24
|
+
children_tag_string = ''
|
|
25
|
+
data['items'].each do |v|
|
|
26
|
+
children_tag_string += content_tag(:li, v.html_safe)
|
|
27
|
+
end
|
|
28
|
+
children_tag_string.html_safe
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def sanitize!
|
|
33
|
+
safe_tags = {
|
|
34
|
+
'b' => nil,
|
|
35
|
+
'i' => nil,
|
|
36
|
+
'a' => ['href'],
|
|
37
|
+
'mark' => ['class'],
|
|
38
|
+
'code' => ['class']
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
data['items'] = data['items'].map do |text|
|
|
42
|
+
Sanitize.fragment(
|
|
43
|
+
text,
|
|
44
|
+
elements: safe_tags.keys,
|
|
45
|
+
attributes: safe_tags.select {|k, v| v},
|
|
46
|
+
remove_contents: true
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def plain
|
|
52
|
+
data['items'].map do |text|
|
|
53
|
+
decode_html(Sanitize.fragment(text)).strip
|
|
54
|
+
end.join(', ')
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class HTMLwithCodeRay < Redcarpet::Render::HTML
|
|
6
|
+
def block_code(code, language)
|
|
7
|
+
CodeRay.scan(code, language || :text).div(css: :class)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def list_item(text, list_type)
|
|
11
|
+
if text.start_with?("[x]", "[X]")
|
|
12
|
+
text[0..2] = %(<input type='checkbox' checked='checked' disabled>)
|
|
13
|
+
elsif text.start_with?("[ ]")
|
|
14
|
+
text[0..2] = %(<input type='checkbox' disabled>)
|
|
15
|
+
end
|
|
16
|
+
%(<li>#{text}</li>)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class MarkdownBlock < Base
|
|
21
|
+
def schema
|
|
22
|
+
YAML.safe_load(<<~YAML)
|
|
23
|
+
type: object
|
|
24
|
+
additionalProperties: false
|
|
25
|
+
properties:
|
|
26
|
+
text:
|
|
27
|
+
type: string
|
|
28
|
+
YAML
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def render(_options = {})
|
|
32
|
+
content_tag :div, class: css_name do
|
|
33
|
+
content_text = data['text'] || ''
|
|
34
|
+
|
|
35
|
+
render_options = {
|
|
36
|
+
escape_html: true,
|
|
37
|
+
hard_wrap: true,
|
|
38
|
+
with_toc_data: true,
|
|
39
|
+
link_attributes: { rel: 'nofollow', target: '_blank' }
|
|
40
|
+
}
|
|
41
|
+
renderer = HTMLwithCodeRay.new(render_options)
|
|
42
|
+
|
|
43
|
+
options = {
|
|
44
|
+
autolink: true,
|
|
45
|
+
fenced_code_blocks: true,
|
|
46
|
+
lax_spacing: true,
|
|
47
|
+
no_intra_emphasis: true,
|
|
48
|
+
strikethrough: true,
|
|
49
|
+
tables: true,
|
|
50
|
+
superscript: true,
|
|
51
|
+
highlight: true,
|
|
52
|
+
quote: true,
|
|
53
|
+
footnotes: true
|
|
54
|
+
}
|
|
55
|
+
markdown_to_html = Redcarpet::Markdown.new(renderer, options)
|
|
56
|
+
|
|
57
|
+
markdown_to_html.render(content_text).html_safe
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def plain
|
|
62
|
+
data['text'].strip
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class ParagraphBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
properties:
|
|
11
|
+
text:
|
|
12
|
+
type: string
|
|
13
|
+
YAML
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def render(_options = {})
|
|
17
|
+
content_tag(:div, class: css_name) { data['text'].html_safe }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def sanitize!
|
|
21
|
+
safe_tags = {
|
|
22
|
+
'b' => nil,
|
|
23
|
+
'i' => nil,
|
|
24
|
+
'a' => ['href'],
|
|
25
|
+
'mark' => ['class'],
|
|
26
|
+
'code' => ['class']
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
data['text'] = Sanitize.fragment(
|
|
30
|
+
data['text'],
|
|
31
|
+
elements: safe_tags.keys,
|
|
32
|
+
attributes: safe_tags.select {|k, v| v},
|
|
33
|
+
remove_contents: true
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def plain
|
|
38
|
+
decode_html(Sanitize.fragment data['text']).strip
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class QuoteBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
properties:
|
|
11
|
+
text:
|
|
12
|
+
type: string
|
|
13
|
+
caption:
|
|
14
|
+
type: string
|
|
15
|
+
alignment:
|
|
16
|
+
type: string
|
|
17
|
+
YAML
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def render(_options = {})
|
|
21
|
+
text = data['text'].html_safe
|
|
22
|
+
caption = data['caption'].presence&.html_safe
|
|
23
|
+
|
|
24
|
+
content_tag :div, class: css_name do
|
|
25
|
+
html_str = content_tag :div, text, class: "#{css_name}__text"
|
|
26
|
+
html_str << content_tag(:div, caption, class: "#{css_name}__caption") if caption
|
|
27
|
+
html_str
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def sanitize!
|
|
32
|
+
safe_tags = {
|
|
33
|
+
'b' => nil,
|
|
34
|
+
'i' => nil,
|
|
35
|
+
'a' => ['href'],
|
|
36
|
+
'mark' => ['class'],
|
|
37
|
+
'code' => ['class']
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
%w(text caption).each do |key|
|
|
41
|
+
data[key] = Sanitize.fragment(
|
|
42
|
+
data[key],
|
|
43
|
+
elements: safe_tags.keys,
|
|
44
|
+
attributes: safe_tags.select {|k, v| v},
|
|
45
|
+
remove_contents: true
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
data['alignment'] = Sanitize.fragment(data['alignment'], remove_contents: true)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def plain
|
|
52
|
+
string = [
|
|
53
|
+
Sanitize.fragment(data['text']).strip,
|
|
54
|
+
Sanitize.fragment(data['caption']).strip
|
|
55
|
+
].join(', ')
|
|
56
|
+
decode_html(string)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EditorJs
|
|
4
|
+
module Blocks
|
|
5
|
+
class TableBlock < Base
|
|
6
|
+
def schema
|
|
7
|
+
YAML.safe_load(<<~YAML)
|
|
8
|
+
type: object
|
|
9
|
+
additionalProperties: false
|
|
10
|
+
properties:
|
|
11
|
+
content:
|
|
12
|
+
type: array
|
|
13
|
+
items:
|
|
14
|
+
type: array
|
|
15
|
+
items:
|
|
16
|
+
type: string
|
|
17
|
+
YAML
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def render(_options = {})
|
|
21
|
+
content_tag(:div, class: css_name) do
|
|
22
|
+
content_tag(:table) do
|
|
23
|
+
data['content'].map do |row|
|
|
24
|
+
content_tag(:tr) do
|
|
25
|
+
row.map { |col| content_tag :td, col.html_safe }.join().html_safe
|
|
26
|
+
end
|
|
27
|
+
end.join().html_safe
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def sanitize!
|
|
33
|
+
data['content'] = data['content'].map do |row|
|
|
34
|
+
row = (row || []).map do |cell_value|
|
|
35
|
+
Sanitize.fragment(cell_value, remove_contents: true)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def plain
|
|
41
|
+
decode_html data['content'].flatten.join(', ').gsub(/(, )+/, ', ')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
module EditorJs
|
|
5
|
+
class Document
|
|
6
|
+
SCHEMA = YAML.safe_load(<<~YAML)
|
|
7
|
+
type: object
|
|
8
|
+
additionalProperties: false
|
|
9
|
+
properties:
|
|
10
|
+
time:
|
|
11
|
+
type: number
|
|
12
|
+
blocks:
|
|
13
|
+
type: array
|
|
14
|
+
items:
|
|
15
|
+
type: object
|
|
16
|
+
version:
|
|
17
|
+
type: string
|
|
18
|
+
YAML
|
|
19
|
+
|
|
20
|
+
def initialize(str_or_hash)
|
|
21
|
+
str_or_hash = JSON.parse(str_or_hash) unless str_or_hash.is_a?(Hash)
|
|
22
|
+
@content = str_or_hash
|
|
23
|
+
@blocks = []
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def valid?
|
|
27
|
+
return @valid if instance_variable_defined?(:@valid)
|
|
28
|
+
|
|
29
|
+
@valid = JSON::Validator.validate(SCHEMA, @content)
|
|
30
|
+
return false unless @valid
|
|
31
|
+
|
|
32
|
+
blocks = @content['blocks'].map do |blk_data|
|
|
33
|
+
EditorJs::Blocks::Base.load(blk_data)
|
|
34
|
+
end
|
|
35
|
+
@valid = blocks.all?(&:valid?)
|
|
36
|
+
@blocks = blocks if @valid
|
|
37
|
+
@valid
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def render
|
|
41
|
+
return @renderred_html if instance_variable_defined?(:@renderred_html)
|
|
42
|
+
|
|
43
|
+
@renderred_html = valid? ? @blocks.map(&:render).join : ''
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def plain
|
|
47
|
+
return @renderred_plain if instance_variable_defined?(:@renderred_plain)
|
|
48
|
+
|
|
49
|
+
@renderred_plain = valid? ? @blocks.map(&:plain).join('. ') : ''
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def output
|
|
53
|
+
return @output if instance_variable_defined?(:@output)
|
|
54
|
+
|
|
55
|
+
@output = valid? ? @content.merge('blocks' => @blocks.map(&:output)) : {}
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/editor_js/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,125 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: editor_js
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- xiaohui
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-12-
|
|
11
|
+
date: 2019-12-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: actionview
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '4'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '4'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: activesupport
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '4'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '4'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: json-schema
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '2'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '2'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: sanitize
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '5.1'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '5.1'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: htmlentities
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '4.3'
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: 4.3.4
|
|
79
|
+
type: :runtime
|
|
80
|
+
prerelease: false
|
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
82
|
+
requirements:
|
|
83
|
+
- - "~>"
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '4.3'
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: 4.3.4
|
|
89
|
+
- !ruby/object:Gem::Dependency
|
|
90
|
+
name: redcarpet
|
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '3.5'
|
|
96
|
+
type: :runtime
|
|
97
|
+
prerelease: false
|
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '3.5'
|
|
103
|
+
- !ruby/object:Gem::Dependency
|
|
104
|
+
name: coderay
|
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '1.1'
|
|
110
|
+
- - ">="
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: 1.1.2
|
|
113
|
+
type: :runtime
|
|
114
|
+
prerelease: false
|
|
115
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
116
|
+
requirements:
|
|
117
|
+
- - "~>"
|
|
118
|
+
- !ruby/object:Gem::Version
|
|
119
|
+
version: '1.1'
|
|
120
|
+
- - ">="
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
version: 1.1.2
|
|
13
123
|
- !ruby/object:Gem::Dependency
|
|
14
124
|
name: bundler
|
|
15
125
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -61,6 +171,7 @@ extra_rdoc_files: []
|
|
|
61
171
|
files:
|
|
62
172
|
- ".gitignore"
|
|
63
173
|
- ".rspec"
|
|
174
|
+
- ".rubocop.yml"
|
|
64
175
|
- ".travis.yml"
|
|
65
176
|
- Gemfile
|
|
66
177
|
- Gemfile.lock
|
|
@@ -71,6 +182,20 @@ files:
|
|
|
71
182
|
- bin/setup
|
|
72
183
|
- editor_js.gemspec
|
|
73
184
|
- lib/editor_js.rb
|
|
185
|
+
- lib/editor_js/blocks/base.rb
|
|
186
|
+
- lib/editor_js/blocks/checklist_block.rb
|
|
187
|
+
- lib/editor_js/blocks/code_block.rb
|
|
188
|
+
- lib/editor_js/blocks/delimiter_block.rb
|
|
189
|
+
- lib/editor_js/blocks/embed_block.rb
|
|
190
|
+
- lib/editor_js/blocks/header_block.rb
|
|
191
|
+
- lib/editor_js/blocks/image_block.rb
|
|
192
|
+
- lib/editor_js/blocks/list_block.rb
|
|
193
|
+
- lib/editor_js/blocks/markdown_block.rb
|
|
194
|
+
- lib/editor_js/blocks/paragraph_block.rb
|
|
195
|
+
- lib/editor_js/blocks/qiniu_image_block.rb
|
|
196
|
+
- lib/editor_js/blocks/quote_block.rb
|
|
197
|
+
- lib/editor_js/blocks/table_block.rb
|
|
198
|
+
- lib/editor_js/document.rb
|
|
74
199
|
- lib/editor_js/version.rb
|
|
75
200
|
homepage: https://github.com/xiaohui-zhangxh/editor_js
|
|
76
201
|
licenses:
|