qiita-markdown 0.32.0 → 0.37.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/CHANGELOG.md +19 -1
- data/lib/qiita/markdown.rb +1 -1
- data/lib/qiita/markdown/filters/custom_block.rb +63 -0
- data/lib/qiita/markdown/filters/greenmat.rb +1 -0
- data/lib/qiita/markdown/filters/user_input_sanitizer.rb +1 -1
- data/lib/qiita/markdown/processor.rb +1 -0
- data/lib/qiita/markdown/transformers/filter_iframe.rb +3 -3
- data/lib/qiita/markdown/transformers/filter_script.rb +3 -4
- data/lib/qiita/markdown/version.rb +1 -1
- data/qiita-markdown.gemspec +1 -1
- data/spec/qiita/markdown/processor_spec.rb +242 -80
- metadata +9 -9
- data/lib/qiita/markdown/embed/gist.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a632599e029a2372e999818df8cf19474233cdafe5b0454b944d6fe93d4423ca
|
4
|
+
data.tar.gz: 6ee085f30d1b6008fe9ada38b62c91f6a7d5b68e0f656f20afdc69b5aa067c96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7d84a2dd88cd53380b8b7c5ec3264ae3cbcdf29c718031dfb9d22038d7349ffeaa2cba6e6a8654b3d357c4c7a28994fecdc51f8381cdbff276930a4238ab866
|
7
|
+
data.tar.gz: 78bcee81ab1f08a311e7bf73f9bcbe6c79234c0ed999da679c285f10d69d482bf9c6e3373b2eb39896e2b8cdcd0890631539adf9fe6bfe69250f84ddcd1f4df1
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,26 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 0.37.0
|
4
|
+
- Change keyword of notation
|
5
|
+
|
6
|
+
## 0.36.0
|
7
|
+
- Support message notation
|
8
|
+
|
9
|
+
## 0.35.0
|
10
|
+
|
11
|
+
- Allow Relative URL in iframe src attributes
|
12
|
+
|
13
|
+
## 0.34.0
|
14
|
+
|
15
|
+
- Delete gist embed rule to avoid XSS
|
16
|
+
|
17
|
+
## 0.33.0
|
18
|
+
|
19
|
+
- Fix XSS possibility bug
|
20
|
+
|
3
21
|
## 0.32.0
|
4
22
|
|
5
|
-
-
|
23
|
+
- Fix XSS possibility bug
|
6
24
|
- Fix iframe width to be fixed at 100%
|
7
25
|
|
8
26
|
## 0.31.0
|
data/lib/qiita/markdown.rb
CHANGED
@@ -10,7 +10,6 @@ require "sanitize"
|
|
10
10
|
require "qiita/markdown/embed/code_pen"
|
11
11
|
require "qiita/markdown/embed/tweet"
|
12
12
|
require "qiita/markdown/embed/asciinema"
|
13
|
-
require "qiita/markdown/embed/gist"
|
14
13
|
require "qiita/markdown/embed/youtube"
|
15
14
|
require "qiita/markdown/embed/slide_share"
|
16
15
|
require "qiita/markdown/embed/google_slide"
|
@@ -21,6 +20,7 @@ require "qiita/markdown/transformers/filter_iframe"
|
|
21
20
|
require "qiita/markdown/transformers/strip_invalid_node"
|
22
21
|
require "qiita/markdown/filters/checkbox"
|
23
22
|
require "qiita/markdown/filters/code_block"
|
23
|
+
require "qiita/markdown/filters/custom_block"
|
24
24
|
require "qiita/markdown/filters/emoji"
|
25
25
|
require "qiita/markdown/filters/external_link"
|
26
26
|
require "qiita/markdown/filters/final_sanitizer"
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Qiita
|
2
|
+
module Markdown
|
3
|
+
module Filters
|
4
|
+
class CustomBlock < HTML::Pipeline::Filter
|
5
|
+
ALLOWED_TYPES = %w[note].freeze
|
6
|
+
|
7
|
+
def call
|
8
|
+
doc.search('div[data-type="customblock"]').each do |div|
|
9
|
+
metadata = Metadata.new(div["data-metadata"])
|
10
|
+
next unless ALLOWED_TYPES.include?(metadata.type)
|
11
|
+
klass = Object.const_get("#{self.class}::#{metadata.type.capitalize}")
|
12
|
+
klass.new(div, metadata.subtype).convert
|
13
|
+
end
|
14
|
+
doc
|
15
|
+
end
|
16
|
+
|
17
|
+
class Metadata
|
18
|
+
attr_reader :type, :subtype
|
19
|
+
|
20
|
+
# @param text [String, nil]
|
21
|
+
def initialize(text)
|
22
|
+
# Discared after the second word.
|
23
|
+
@type, @subtype = text.split(" ")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Note
|
28
|
+
attr_reader :node, :type
|
29
|
+
|
30
|
+
ALLOWED_TYPES = %w[info warn alert].freeze
|
31
|
+
DEFAULT_TYPE = "info".freeze
|
32
|
+
|
33
|
+
# @param node [Nokogiri::XML::Node]
|
34
|
+
# @param type [String, nil]
|
35
|
+
def initialize(node, type)
|
36
|
+
@node = node
|
37
|
+
@type = ALLOWED_TYPES.include?(type) ? type : DEFAULT_TYPE
|
38
|
+
end
|
39
|
+
|
40
|
+
def convert
|
41
|
+
node.inner_html = message
|
42
|
+
node["class"] = "note #{type}"
|
43
|
+
node.children.first.add_previous_sibling(icon) if icon
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def message
|
49
|
+
"<p>#{node.text}</p>"
|
50
|
+
end
|
51
|
+
|
52
|
+
def icon
|
53
|
+
{
|
54
|
+
info: %(<span class="fa fa-fw fa-check-circle"></span>),
|
55
|
+
warn: %(<span class="fa fa-fw fa-exclamation-circle"></span>),
|
56
|
+
alert: %(<span class="fa fa-fw fa-times-circle"></span>),
|
57
|
+
}[type.to_sym]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -20,6 +20,7 @@ module Qiita
|
|
20
20
|
Qiita::Markdown::Greenmat::HTMLRenderer.new(hard_wrap: true, with_toc_data: true),
|
21
21
|
autolink: true,
|
22
22
|
fenced_code_blocks: true,
|
23
|
+
fenced_custom_blocks: true,
|
23
24
|
footnotes: options[:footnotes],
|
24
25
|
no_intra_emphasis: true,
|
25
26
|
no_mention_emphasis: true,
|
@@ -13,7 +13,7 @@ module Qiita
|
|
13
13
|
"a" => %w[class href rel title],
|
14
14
|
"blockquote" => %w[cite] + Embed::Tweet::ATTRIBUTES,
|
15
15
|
"code" => %w[data-metadata],
|
16
|
-
"div" => %w[class],
|
16
|
+
"div" => %w[class data-type data-metadata],
|
17
17
|
"font" => %w[color],
|
18
18
|
"h1" => %w[id],
|
19
19
|
"h2" => %w[id],
|
@@ -42,10 +42,10 @@ module Qiita
|
|
42
42
|
|
43
43
|
def host_of(url)
|
44
44
|
if url
|
45
|
-
|
46
|
-
Addressable::URI.parse(url).host if [
|
45
|
+
scheme = URI.parse(url).scheme
|
46
|
+
Addressable::URI.parse(url).host if ["http", "https", nil].include? scheme
|
47
47
|
end
|
48
|
-
rescue Addressable::URI::InvalidURIError
|
48
|
+
rescue Addressable::URI::InvalidURIError, URI::InvalidURIError
|
49
49
|
nil
|
50
50
|
end
|
51
51
|
end
|
@@ -10,7 +10,6 @@ module Qiita
|
|
10
10
|
|
11
11
|
HOST_WHITE_LIST = [
|
12
12
|
Embed::Asciinema::SCRIPT_HOST,
|
13
|
-
Embed::Gist::SCRIPT_HOST,
|
14
13
|
].flatten.freeze
|
15
14
|
|
16
15
|
def self.call(*args)
|
@@ -44,10 +43,10 @@ module Qiita
|
|
44
43
|
|
45
44
|
def host_of(url)
|
46
45
|
if url
|
47
|
-
|
48
|
-
Addressable::URI.parse(url).host if [
|
46
|
+
scheme = URI.parse(url).scheme
|
47
|
+
Addressable::URI.parse(url).host if ["http", "https"].include? scheme
|
49
48
|
end
|
50
|
-
rescue Addressable::URI::InvalidURIError
|
49
|
+
rescue Addressable::URI::InvalidURIError, URI::InvalidURIError
|
51
50
|
nil
|
52
51
|
end
|
53
52
|
end
|
data/qiita-markdown.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "html-pipeline", "~> 2.0"
|
24
24
|
spec.add_dependency "mem"
|
25
25
|
spec.add_dependency "pygments.rb", "~> 1.0"
|
26
|
-
spec.add_dependency "greenmat", "3.5.1.
|
26
|
+
spec.add_dependency "greenmat", "3.5.1.2"
|
27
27
|
spec.add_dependency "sanitize"
|
28
28
|
spec.add_dependency "addressable"
|
29
29
|
spec.add_development_dependency "activesupport", "4.2.6"
|
@@ -1144,12 +1144,13 @@ describe Qiita::Markdown::Processor do
|
|
1144
1144
|
end
|
1145
1145
|
|
1146
1146
|
shared_examples_for "iframe element" do |allowed:|
|
1147
|
-
|
1147
|
+
shared_examples "iframe element example" do
|
1148
1148
|
let(:markdown) do
|
1149
1149
|
<<-MARKDOWN.strip_heredoc
|
1150
|
-
<iframe width="1" height="2" src="
|
1150
|
+
<iframe width="1" height="2" src="#{url}" frameborder="0" allowfullscreen></iframe>
|
1151
1151
|
MARKDOWN
|
1152
1152
|
end
|
1153
|
+
let(:url) { "#{scheme}//example.com" }
|
1153
1154
|
|
1154
1155
|
if allowed
|
1155
1156
|
it "allows iframe with some attributes" do
|
@@ -1161,6 +1162,20 @@ describe Qiita::Markdown::Processor do
|
|
1161
1162
|
end
|
1162
1163
|
end
|
1163
1164
|
end
|
1165
|
+
|
1166
|
+
context "with iframe" do
|
1167
|
+
context "with scheme" do
|
1168
|
+
let(:scheme) { "https:" }
|
1169
|
+
|
1170
|
+
include_examples "iframe element example"
|
1171
|
+
end
|
1172
|
+
|
1173
|
+
context "without scheme" do
|
1174
|
+
let(:scheme) { "" }
|
1175
|
+
|
1176
|
+
include_examples "iframe element example"
|
1177
|
+
end
|
1178
|
+
end
|
1164
1179
|
end
|
1165
1180
|
|
1166
1181
|
shared_examples_for "input element" do |allowed:|
|
@@ -1451,114 +1466,138 @@ describe Qiita::Markdown::Processor do
|
|
1451
1466
|
end
|
1452
1467
|
end
|
1453
1468
|
|
1454
|
-
context "with HTML embed code for
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1469
|
+
context "with HTML embed code for Youtube" do
|
1470
|
+
shared_examples "embed code youtube example" do
|
1471
|
+
let(:markdown) do
|
1472
|
+
<<-MARKDOWN.strip_heredoc
|
1473
|
+
<iframe width="100" height="100" src="#{url}"></iframe>
|
1474
|
+
MARKDOWN
|
1475
|
+
end
|
1476
|
+
let(:url) { "#{scheme}//www.youtube.com/embed/example" }
|
1460
1477
|
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1478
|
+
if allowed
|
1479
|
+
it "does not sanitize embed code" do
|
1480
|
+
should eq <<-HTML.strip_heredoc
|
1481
|
+
<iframe width="100" height="100" src="#{url}"></iframe>
|
1482
|
+
HTML
|
1483
|
+
end
|
1484
|
+
else
|
1485
|
+
it "forces width attribute on iframe" do
|
1486
|
+
should eq <<-HTML.strip_heredoc
|
1487
|
+
<iframe width="100%" height="100" src="#{url}"></iframe>
|
1488
|
+
HTML
|
1489
|
+
end
|
1466
1490
|
end
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1491
|
+
|
1492
|
+
context "when url is privacy enhanced mode" do
|
1493
|
+
let(:markdown) do
|
1494
|
+
<<-MARKDOWN.strip_heredoc
|
1495
|
+
<iframe width="100" height="100" src="#{url}"></iframe>
|
1496
|
+
MARKDOWN
|
1497
|
+
end
|
1498
|
+
let(:url) { "#{scheme}//www.youtube-nocookie.com/embed/example" }
|
1499
|
+
|
1500
|
+
if allowed
|
1501
|
+
it "does not sanitize embed code" do
|
1502
|
+
should eq <<-HTML.strip_heredoc
|
1503
|
+
<iframe width="100" height="100" src="#{url}"></iframe>
|
1504
|
+
HTML
|
1505
|
+
end
|
1506
|
+
else
|
1507
|
+
it "forces width attribute on iframe" do
|
1508
|
+
should eq <<-HTML.strip_heredoc
|
1509
|
+
<iframe width="100%" height="100" src="#{url}"></iframe>
|
1510
|
+
HTML
|
1511
|
+
end
|
1512
|
+
end
|
1472
1513
|
end
|
1473
1514
|
end
|
1474
|
-
end
|
1475
1515
|
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
MARKDOWN
|
1516
|
+
context "with scheme" do
|
1517
|
+
let(:scheme) { "https:" }
|
1518
|
+
|
1519
|
+
include_examples "embed code youtube example"
|
1481
1520
|
end
|
1482
1521
|
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
HTML
|
1488
|
-
end
|
1489
|
-
else
|
1490
|
-
it "forces width attribute on iframe" do
|
1491
|
-
should eq <<-HTML.strip_heredoc
|
1492
|
-
<iframe width="100%" height="100" src="https://www.youtube.com/embed/example"></iframe>
|
1493
|
-
HTML
|
1494
|
-
end
|
1522
|
+
context "without scheme" do
|
1523
|
+
let(:scheme) { "" }
|
1524
|
+
|
1525
|
+
include_examples "embed code youtube example"
|
1495
1526
|
end
|
1527
|
+
end
|
1496
1528
|
|
1497
|
-
|
1529
|
+
context "with HTML embed code for SlideShare" do
|
1530
|
+
shared_examples "embed code slideshare example" do
|
1498
1531
|
let(:markdown) do
|
1499
1532
|
<<-MARKDOWN.strip_heredoc
|
1500
|
-
<iframe width="100" height="100" src="
|
1533
|
+
<iframe width="100" height="100" src="#{url}"></iframe>
|
1501
1534
|
MARKDOWN
|
1502
1535
|
end
|
1536
|
+
let(:url) { "#{scheme}//www.slideshare.net/embed/example" }
|
1503
1537
|
|
1504
1538
|
if allowed
|
1505
1539
|
it "does not sanitize embed code" do
|
1506
1540
|
should eq <<-HTML.strip_heredoc
|
1507
|
-
<iframe width="100" height="100" src="
|
1541
|
+
<iframe width="100" height="100" src="#{url}"></iframe>
|
1508
1542
|
HTML
|
1509
1543
|
end
|
1510
1544
|
else
|
1511
1545
|
it "forces width attribute on iframe" do
|
1512
1546
|
should eq <<-HTML.strip_heredoc
|
1513
|
-
<iframe width="100%" height="100" src="
|
1547
|
+
<iframe width="100%" height="100" src="#{url}"></iframe>
|
1514
1548
|
HTML
|
1515
1549
|
end
|
1516
1550
|
end
|
1517
1551
|
end
|
1518
|
-
end
|
1519
1552
|
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
MARKDOWN
|
1553
|
+
context "with scheme" do
|
1554
|
+
let(:scheme) { "https:" }
|
1555
|
+
|
1556
|
+
include_examples "embed code slideshare example"
|
1525
1557
|
end
|
1526
1558
|
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
HTML
|
1532
|
-
end
|
1533
|
-
else
|
1534
|
-
it "forces width attribute on iframe" do
|
1535
|
-
should eq <<-HTML.strip_heredoc
|
1536
|
-
<iframe width="100%" height="100" src="https://www.slideshare.net/embed/example"></iframe>
|
1537
|
-
HTML
|
1538
|
-
end
|
1559
|
+
context "without scheme" do
|
1560
|
+
let(:scheme) { "" }
|
1561
|
+
|
1562
|
+
include_examples "embed code slideshare example"
|
1539
1563
|
end
|
1540
1564
|
end
|
1541
1565
|
|
1542
1566
|
context "with HTML embed code for GoogleSlide" do
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
if allowed
|
1550
|
-
it "does not sanitize embed code" do
|
1551
|
-
should eq <<-HTML.strip_heredoc
|
1552
|
-
<iframe src="https://docs.google.com/presentation/d/example/embed" frameborder="0" width="482" height="300" allowfullscreen="true"></iframe>
|
1553
|
-
HTML
|
1567
|
+
shared_examples "embed code googleslide example" do
|
1568
|
+
let(:markdown) do
|
1569
|
+
<<-MARKDOWN.strip_heredoc
|
1570
|
+
<iframe src="#{url}" frameborder="0" width="482" height="300" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
|
1571
|
+
MARKDOWN
|
1554
1572
|
end
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1573
|
+
let(:url) { "#{scheme}//docs.google.com/presentation/d/example/embed" }
|
1574
|
+
|
1575
|
+
if allowed
|
1576
|
+
it "does not sanitize embed code" do
|
1577
|
+
should eq <<-HTML.strip_heredoc
|
1578
|
+
<iframe src="#{url}" frameborder="0" width="482" height="300" allowfullscreen="true"></iframe>
|
1579
|
+
HTML
|
1580
|
+
end
|
1581
|
+
else
|
1582
|
+
it "forces width attribute on iframe" do
|
1583
|
+
should eq <<-HTML.strip_heredoc
|
1584
|
+
<iframe src="#{url}" frameborder="0" width="100%" height="300" allowfullscreen="true"></iframe>
|
1585
|
+
HTML
|
1586
|
+
end
|
1560
1587
|
end
|
1561
1588
|
end
|
1589
|
+
|
1590
|
+
context "with scheme" do
|
1591
|
+
let(:scheme) { "https:" }
|
1592
|
+
|
1593
|
+
include_examples "embed code googleslide example"
|
1594
|
+
end
|
1595
|
+
|
1596
|
+
context "without scheme" do
|
1597
|
+
let(:scheme) { "" }
|
1598
|
+
|
1599
|
+
include_examples "embed code googleslide example"
|
1600
|
+
end
|
1562
1601
|
end
|
1563
1602
|
|
1564
1603
|
context "with HTML embed code for SpeekerDeck" do
|
@@ -1604,11 +1643,15 @@ describe Qiita::Markdown::Processor do
|
|
1604
1643
|
<<-MARKDOWN.strip_heredoc
|
1605
1644
|
<script async class="speakerdeck-embed" data-id="example" data-ratio="1.33333333333333" src="javascript://speakerdeck.com/assets/embed.js"></script>
|
1606
1645
|
MARKDOWN
|
1646
|
+
end
|
1607
1647
|
|
1648
|
+
if allowed
|
1649
|
+
it "does not sanitize embed code" do
|
1650
|
+
should eq markdown
|
1651
|
+
end
|
1652
|
+
else
|
1608
1653
|
it "forces width attribute on iframe" do
|
1609
|
-
should eq
|
1610
|
-
\n
|
1611
|
-
HTML
|
1654
|
+
should eq "\n"
|
1612
1655
|
end
|
1613
1656
|
end
|
1614
1657
|
end
|
@@ -1616,14 +1659,129 @@ describe Qiita::Markdown::Processor do
|
|
1616
1659
|
context "with embed iframe code with xss" do
|
1617
1660
|
let(:markdown) do
|
1618
1661
|
<<-MARKDOWN.strip_heredoc
|
1619
|
-
<iframe src="javascript://docs.google.com
|
1662
|
+
<iframe src="javascript://docs.google.com:80/%0d%0aalert(document.domain)" frameborder="0" width="482" height="300" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
|
1620
1663
|
MARKDOWN
|
1664
|
+
end
|
1621
1665
|
|
1622
|
-
|
1666
|
+
if allowed
|
1667
|
+
it "does not sanitize embed code" do
|
1623
1668
|
should eq <<-HTML.strip_heredoc
|
1624
|
-
|
1669
|
+
<iframe src="javascript://docs.google.com:80/%0d%0aalert(document.domain)" frameborder="0" width="482" height="300" allowfullscreen="true"></iframe>
|
1625
1670
|
HTML
|
1626
1671
|
end
|
1672
|
+
else
|
1673
|
+
it "forces width attribute on iframe" do
|
1674
|
+
should eq "\n"
|
1675
|
+
end
|
1676
|
+
end
|
1677
|
+
end
|
1678
|
+
end
|
1679
|
+
|
1680
|
+
shared_examples_for "custom block" do |allowed:|
|
1681
|
+
context "with custom block" do
|
1682
|
+
let(:type) { "" }
|
1683
|
+
let(:subtype) { "" }
|
1684
|
+
|
1685
|
+
let(:markdown) do
|
1686
|
+
<<-MARKDOWN.strip_heredoc
|
1687
|
+
:::#{[type, subtype].join(' ').rstrip}
|
1688
|
+
Some kind of text is here.
|
1689
|
+
:::
|
1690
|
+
MARKDOWN
|
1691
|
+
end
|
1692
|
+
|
1693
|
+
context "when type is not allowed" do
|
1694
|
+
let(:type) { "anytype" }
|
1695
|
+
|
1696
|
+
if allowed
|
1697
|
+
it "returns simple div element" do
|
1698
|
+
should eq <<-HTML.strip_heredoc
|
1699
|
+
<div data-type="customblock" data-metadata="anytype">Some kind of text is here.
|
1700
|
+
</div>
|
1701
|
+
HTML
|
1702
|
+
end
|
1703
|
+
else
|
1704
|
+
it "returns simple div element" do
|
1705
|
+
should eq <<-HTML.strip_heredoc
|
1706
|
+
<div>Some kind of text is here.
|
1707
|
+
</div>
|
1708
|
+
HTML
|
1709
|
+
end
|
1710
|
+
end
|
1711
|
+
end
|
1712
|
+
|
1713
|
+
context "when type is note" do
|
1714
|
+
let(:type) { "note" }
|
1715
|
+
|
1716
|
+
context "when subtype is empty" do
|
1717
|
+
if allowed
|
1718
|
+
it "returns info note block with class including icon as default type" do
|
1719
|
+
should eq <<-HTML.strip_heredoc
|
1720
|
+
<div data-type="customblock" data-metadata="note" class="note info">
|
1721
|
+
<span class="fa fa-fw fa-check-circle"></span><p>Some kind of text is here.
|
1722
|
+
</p>
|
1723
|
+
</div>
|
1724
|
+
HTML
|
1725
|
+
end
|
1726
|
+
else
|
1727
|
+
it "returns note block with class including icon" do
|
1728
|
+
should eq <<-HTML.strip_heredoc
|
1729
|
+
<div class="note info">
|
1730
|
+
<span class="fa fa-fw fa-check-circle"></span><p>Some kind of text is here.
|
1731
|
+
</p>
|
1732
|
+
</div>
|
1733
|
+
HTML
|
1734
|
+
end
|
1735
|
+
end
|
1736
|
+
end
|
1737
|
+
|
1738
|
+
context "when subtype is warn" do
|
1739
|
+
let(:subtype) { "warn" }
|
1740
|
+
|
1741
|
+
if allowed
|
1742
|
+
it "returns warning note block with class including icon" do
|
1743
|
+
should eq <<-HTML.strip_heredoc
|
1744
|
+
<div data-type="customblock" data-metadata="note warn" class="note warn">
|
1745
|
+
<span class="fa fa-fw fa-exclamation-circle"></span><p>Some kind of text is here.
|
1746
|
+
</p>
|
1747
|
+
</div>
|
1748
|
+
HTML
|
1749
|
+
end
|
1750
|
+
else
|
1751
|
+
it "returns note block with class including icon" do
|
1752
|
+
should eq <<-HTML.strip_heredoc
|
1753
|
+
<div class="note warn">
|
1754
|
+
<span class="fa fa-fw fa-exclamation-circle"></span><p>Some kind of text is here.
|
1755
|
+
</p>
|
1756
|
+
</div>
|
1757
|
+
HTML
|
1758
|
+
end
|
1759
|
+
end
|
1760
|
+
end
|
1761
|
+
|
1762
|
+
context "when subtype is alert" do
|
1763
|
+
let(:subtype) { "alert" }
|
1764
|
+
|
1765
|
+
if allowed
|
1766
|
+
it "returns alerting note block with class including icon" do
|
1767
|
+
should eq <<-HTML.strip_heredoc
|
1768
|
+
<div data-type="customblock" data-metadata="note alert" class="note alert">
|
1769
|
+
<span class="fa fa-fw fa-times-circle"></span><p>Some kind of text is here.
|
1770
|
+
</p>
|
1771
|
+
</div>
|
1772
|
+
HTML
|
1773
|
+
end
|
1774
|
+
else
|
1775
|
+
it "returns note block with class including icon" do
|
1776
|
+
should eq <<-HTML.strip_heredoc
|
1777
|
+
<div class="note alert">
|
1778
|
+
<span class="fa fa-fw fa-times-circle"></span><p>Some kind of text is here.
|
1779
|
+
</p>
|
1780
|
+
</div>
|
1781
|
+
HTML
|
1782
|
+
end
|
1783
|
+
end
|
1784
|
+
end
|
1627
1785
|
end
|
1628
1786
|
end
|
1629
1787
|
end
|
@@ -1642,6 +1800,7 @@ describe Qiita::Markdown::Processor do
|
|
1642
1800
|
include_examples "class attribute", allowed: true
|
1643
1801
|
include_examples "background-color", allowed: true
|
1644
1802
|
include_examples "override embed code attributes", allowed: false
|
1803
|
+
include_examples "custom block", allowed: false
|
1645
1804
|
end
|
1646
1805
|
|
1647
1806
|
context "with script context" do
|
@@ -1658,6 +1817,7 @@ describe Qiita::Markdown::Processor do
|
|
1658
1817
|
include_examples "class attribute", allowed: true
|
1659
1818
|
include_examples "background-color", allowed: true
|
1660
1819
|
include_examples "override embed code attributes", allowed: true
|
1820
|
+
include_examples "custom block", allowed: true
|
1661
1821
|
end
|
1662
1822
|
|
1663
1823
|
context "with strict context" do
|
@@ -1674,6 +1834,7 @@ describe Qiita::Markdown::Processor do
|
|
1674
1834
|
include_examples "class attribute", allowed: false
|
1675
1835
|
include_examples "background-color", allowed: false
|
1676
1836
|
include_examples "override embed code attributes", allowed: false
|
1837
|
+
include_examples "custom block", allowed: false
|
1677
1838
|
end
|
1678
1839
|
|
1679
1840
|
context "with script and strict context" do
|
@@ -1690,6 +1851,7 @@ describe Qiita::Markdown::Processor do
|
|
1690
1851
|
include_examples "class attribute", allowed: false
|
1691
1852
|
include_examples "background-color", allowed: false
|
1692
1853
|
include_examples "override embed code attributes", allowed: false
|
1854
|
+
include_examples "custom block", allowed: true
|
1693
1855
|
end
|
1694
1856
|
end
|
1695
1857
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qiita-markdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.37.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gemoji
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - '='
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 3.5.1.
|
89
|
+
version: 3.5.1.2
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - '='
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 3.5.1.
|
96
|
+
version: 3.5.1.2
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: sanitize
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -234,7 +234,7 @@ dependencies:
|
|
234
234
|
- - '='
|
235
235
|
- !ruby/object:Gem::Version
|
236
236
|
version: 0.49.1
|
237
|
-
description:
|
237
|
+
description:
|
238
238
|
email:
|
239
239
|
- r7kamura@gmail.com
|
240
240
|
executables: []
|
@@ -258,7 +258,6 @@ files:
|
|
258
258
|
- lib/qiita/markdown/base_processor.rb
|
259
259
|
- lib/qiita/markdown/embed/asciinema.rb
|
260
260
|
- lib/qiita/markdown/embed/code_pen.rb
|
261
|
-
- lib/qiita/markdown/embed/gist.rb
|
262
261
|
- lib/qiita/markdown/embed/google_slide.rb
|
263
262
|
- lib/qiita/markdown/embed/slide_share.rb
|
264
263
|
- lib/qiita/markdown/embed/speeker_deck.rb
|
@@ -266,6 +265,7 @@ files:
|
|
266
265
|
- lib/qiita/markdown/embed/youtube.rb
|
267
266
|
- lib/qiita/markdown/filters/checkbox.rb
|
268
267
|
- lib/qiita/markdown/filters/code_block.rb
|
268
|
+
- lib/qiita/markdown/filters/custom_block.rb
|
269
269
|
- lib/qiita/markdown/filters/emoji.rb
|
270
270
|
- lib/qiita/markdown/filters/external_link.rb
|
271
271
|
- lib/qiita/markdown/filters/final_sanitizer.rb
|
@@ -301,7 +301,7 @@ homepage: https://github.com/increments/qiita-markdown
|
|
301
301
|
licenses:
|
302
302
|
- MIT
|
303
303
|
metadata: {}
|
304
|
-
post_install_message:
|
304
|
+
post_install_message:
|
305
305
|
rdoc_options: []
|
306
306
|
require_paths:
|
307
307
|
- lib
|
@@ -317,7 +317,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
317
317
|
version: '0'
|
318
318
|
requirements: []
|
319
319
|
rubygems_version: 3.0.3
|
320
|
-
signing_key:
|
320
|
+
signing_key:
|
321
321
|
specification_version: 4
|
322
322
|
summary: Qiita-specified markdown processor.
|
323
323
|
test_files:
|