qiita-markdown 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of qiita-markdown might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f54a09d35de11e6c0b8048cfe8dde77a4b909896
4
- data.tar.gz: 367ea2b6458da0baaa0bd09d80713110bcdee391
3
+ metadata.gz: aeafaca650b98a99a00e0735bde849f99faff1fb
4
+ data.tar.gz: 2911b685bc654da88a608ba1ee7c4636027c9a40
5
5
  SHA512:
6
- metadata.gz: e9e187cc785090db99d4b1b9197a8b3f1f148ff681ddfd7be4ca84d66593e5e14a2921362228ee69e8cb577076bdb42a9d7884563d3a3feed8c6a87d86cf9983
7
- data.tar.gz: 6a54122f245928bd01551fbc2734da61643d77942238020cbc4045bb807eda27b0b62b3b44d27977dd7d0fa38b009be3aa32b05d9eb0bbb8c1579d5be50778ce
6
+ metadata.gz: 019f1dd78735350a0e5c43f0c869fc3656ae858aaeec5d659b9eab64a1d040f3e0685a26313facb6fa750b526aecf676ad5b874aca06a49e18867fa384a60030
7
+ data.tar.gz: 26232bd99bac696a6eb05cd37054a53c0227773db46f78f0406abc63f0076d1b84ad06ca0058d53d8d2dcb18a4fbc5966f3f867f1f49f7d50f65f8d2eacbe7ff
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 0.15.0
2
+ - Append rel=nofollow and target=_blank to all external a tags
3
+
1
4
  ## 0.14.0
2
5
  - Add some attributes to mentions for rendering hovercard
3
6
 
data/README.md CHANGED
@@ -15,7 +15,7 @@ Qiita-specified markdown processor.
15
15
  Qiita::Markdown::Processor provides markdown rendering logic.
16
16
 
17
17
  ```ruby
18
- processor = Qiita::Markdown::Processor.new
18
+ processor = Qiita::Markdown::Processor.new(hostname: "example.com")
19
19
  processor.call(markdown)
20
20
  # => {
21
21
  # codes: [
@@ -38,7 +38,7 @@ Qiita::Markdown is built on [jch/html-pipeline](https://github.com/jch/html-pipe
38
38
  Add your favorite html-pipeline-compatible filters.
39
39
 
40
40
  ```ruby
41
- processor = Qiita::Markdown::Processor.new
41
+ processor = Qiita::Markdown::Processor.new(hostname: "example.com")
42
42
  processor.filters << HTML::Pipeline::ImageMaxWidthFilter
43
43
  processor.call(text)
44
44
  ```
@@ -55,13 +55,14 @@ processor.call(text)
55
55
  :emoji_names - A list of allowed emoji names. (Array<String>)
56
56
  :emoji_url_generator - #call'able object that accepts emoji name as argument and returns emoji image URL. (#call)
57
57
  The original implementation is used when the generator returned a falsey value.
58
+ :hostname - FQDN. Used to check whether or not each URL of `href` attributes is external site. (String)
58
59
  :language_aliases - Alias table for some language names. (Hash)
59
60
  :rule - Sanitization rule table. (Hash)
60
61
  :script - A flag to allow to embed script element. (Boolean)
61
62
  ```
62
63
 
63
64
  ```ruby
64
- processor = Qiita::Markdown::Processor.new(asset_root: "http://example.com/assets")
65
+ processor = Qiita::Markdown::Processor.new(asset_root: "http://example.com/assets", hostname: "example.com")
65
66
  processor.call(text)
66
67
  ```
67
68
 
@@ -87,6 +88,6 @@ SummaryProcessor accepts the following context in addition to the Processor's co
87
88
  ```
88
89
 
89
90
  ```ruby
90
- processor = Qiita::Markdown::SummaryProcessor.new(truncate: { length: 80 })
91
+ processor = Qiita::Markdown::SummaryProcessor.new(truncate: { length: 80 }, hostname: "example.com")
91
92
  processor.call(text)
92
93
  ```
@@ -10,6 +10,7 @@ require "sanitize"
10
10
  require "qiita/markdown/filters/checkbox"
11
11
  require "qiita/markdown/filters/code"
12
12
  require "qiita/markdown/filters/emoji"
13
+ require "qiita/markdown/filters/external_link"
13
14
  require "qiita/markdown/filters/footnote"
14
15
  require "qiita/markdown/filters/greenmat"
15
16
  require "qiita/markdown/filters/group_mention"
@@ -0,0 +1,41 @@
1
+ require "addressable/uri"
2
+
3
+ module Qiita
4
+ module Markdown
5
+ module Filters
6
+ class ExternalLink < HTML::Pipeline::Filter
7
+ def call
8
+ doc.search("a").each do |anchor|
9
+ next unless anchor["href"]
10
+ href = anchor["href"].strip
11
+ href_host = host_of(href)
12
+ next unless href_host
13
+ if href_host != hostname
14
+ anchor["rel"] = "nofollow"
15
+ anchor["target"] = "_blank"
16
+ end
17
+ end
18
+
19
+ doc
20
+ end
21
+
22
+ def validate
23
+ needs :hostname
24
+ end
25
+
26
+ private
27
+
28
+ def host_of(url)
29
+ uri = Addressable::URI.parse(url)
30
+ uri.host
31
+ rescue Addressable::URI::InvalidURIError
32
+ nil
33
+ end
34
+
35
+ def hostname
36
+ context[:hostname]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -49,6 +49,7 @@ module Qiita
49
49
  "data-hovercard-target-name",
50
50
  "data-hovercard-target-type",
51
51
  "href",
52
+ "rel",
52
53
  ],
53
54
  "iframe" => [
54
55
  "allowfullscreen",
@@ -15,6 +15,7 @@ module Qiita
15
15
  Filters::SyntaxHighlight,
16
16
  Filters::Mention,
17
17
  Filters::GroupMention,
18
+ Filters::ExternalLink,
18
19
  Filters::Sanitize,
19
20
  ]
20
21
 
@@ -9,6 +9,7 @@ module Qiita
9
9
  Filters::Simplify,
10
10
  Filters::Emoji,
11
11
  Filters::Mention,
12
+ Filters::ExternalLink,
12
13
  Filters::Sanitize,
13
14
  Filters::Truncate,
14
15
  ]
@@ -1,5 +1,5 @@
1
1
  module Qiita
2
2
  module Markdown
3
- VERSION = "0.14.0"
3
+ VERSION = "0.15.0"
4
4
  end
5
5
  end
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency "pygments.rb"
26
26
  spec.add_dependency "greenmat", ">= 3.2.0.2", "< 4"
27
27
  spec.add_dependency "sanitize"
28
+ spec.add_dependency "addressable"
28
29
  spec.add_development_dependency "activesupport", "4.2.6"
29
30
  spec.add_development_dependency "benchmark-ips", "~> 1.2"
30
31
  spec.add_development_dependency "bundler", "~> 1.7"
@@ -7,7 +7,7 @@ describe Qiita::Markdown::Processor do
7
7
  end
8
8
 
9
9
  let(:context) do
10
- {}
10
+ { hostname: "example.com" }
11
11
  end
12
12
 
13
13
  let(:markdown) do
@@ -482,7 +482,7 @@ describe Qiita::Markdown::Processor do
482
482
 
483
483
  it "replaces it with preferred link and updates :mentioned_groups" do
484
484
  is_expected.to eq <<-EOS.strip_heredoc
485
- <p><a href="https://alice.example.com/groups/bob">@alice/bob</a></p>
485
+ <p><a href="https://alice.example.com/groups/bob" rel="nofollow" target="_blank">@alice/bob</a></p>
486
486
  EOS
487
487
  expect(result[:mentioned_groups]).to eq [{
488
488
  group_url_name: "bob",
@@ -517,13 +517,13 @@ describe Qiita::Markdown::Processor do
517
517
 
518
518
  context "with raw URL" do
519
519
  let(:markdown) do
520
- "http://qiita.com/search?q=日本語"
520
+ "http://example.com/search?q=日本語"
521
521
  end
522
522
 
523
523
  it "creates link for that with .autolink class" do
524
524
  should eq(
525
- '<p><a href="http://qiita.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E" class="autolink">' \
526
- "http://qiita.com/search?q=日本語</a></p>\n"
525
+ '<p><a href="http://example.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E" class="autolink">' \
526
+ "http://example.com/search?q=日本語</a></p>\n"
527
527
  )
528
528
  end
529
529
  end
@@ -745,7 +745,7 @@ describe Qiita::Markdown::Processor do
745
745
 
746
746
  it "generates footnotes elements" do
747
747
  should eq <<-EOS.strip_heredoc
748
- <p><sup id="fnref1"><a href="#fn1" title="test">1</a></sup></p>
748
+ <p><sup id="fnref1"><a href="#fn1" rel="footnote" title="test">1</a></sup></p>
749
749
 
750
750
  <div class="footnotes">
751
751
  <hr>
@@ -764,13 +764,13 @@ describe Qiita::Markdown::Processor do
764
764
  context "with manually written link inside of <sup> tag" do
765
765
  let(:markdown) do
766
766
  <<-EOS.strip_heredoc
767
- <sup>[Qiita](http://qiita.com/)</sup>
767
+ <sup>[Example](http://example.com/)</sup>
768
768
  EOS
769
769
  end
770
770
 
771
771
  it "does not confuse the structure with automatically generated footnote reference" do
772
772
  should eq <<-EOS.strip_heredoc
773
- <p><sup><a href="http://qiita.com/">Qiita</a></sup></p>
773
+ <p><sup><a href="http://example.com/">Example</a></sup></p>
774
774
  EOS
775
775
  end
776
776
  end
@@ -847,5 +847,137 @@ describe Qiita::Markdown::Processor do
847
847
  )
848
848
  end
849
849
  end
850
+
851
+ context "with internal URL" do
852
+ let(:markdown) do
853
+ "http://qiita.com/?a=b"
854
+ end
855
+
856
+ let(:context) do
857
+ { hostname: "qiita.com" }
858
+ end
859
+
860
+ it "creates link which does not have rel='nofollow' and target='_blank'" do
861
+ should eq(
862
+ '<p><a href="http://qiita.com/?a=b" class="autolink">' \
863
+ "http://qiita.com/?a=b</a></p>\n"
864
+ )
865
+ end
866
+ end
867
+
868
+ context "with external URL" do
869
+ let(:markdown) do
870
+ "http://external.com/?a=b"
871
+ end
872
+
873
+ let(:context) do
874
+ { hostname: "qiita.com" }
875
+ end
876
+
877
+ it "creates link which has rel='nofollow' and target='_blank'" do
878
+ should eq(
879
+ '<p><a href="http://external.com/?a=b" class="autolink" rel="nofollow" target="_blank">' \
880
+ "http://external.com/?a=b</a></p>\n"
881
+ )
882
+ end
883
+ end
884
+
885
+ context "with internal anchor tag" do
886
+ let(:markdown) do
887
+ '<a href="http://qiita.com/?a=b">foobar</a>'
888
+ end
889
+
890
+ let(:context) do
891
+ { hostname: "qiita.com" }
892
+ end
893
+
894
+ it "creates link which does not have rel='nofollow' and target='_blank'" do
895
+ should eq(
896
+ "<p><a href=\"http://qiita.com/?a=b\">foobar</a></p>\n"
897
+ )
898
+ end
899
+ end
900
+
901
+ context "with external anchor tag" do
902
+ let(:markdown) do
903
+ '<a href="http://external.com/?a=b">foobar</a>'
904
+ end
905
+
906
+ let(:context) do
907
+ { hostname: "qiita.com" }
908
+ end
909
+
910
+ it "creates link which has rel='nofollow' and target='_blank'" do
911
+ should eq(
912
+ "<p><a href=\"http://external.com/?a=b\" rel=\"nofollow\" target=\"_blank\">foobar</a></p>\n"
913
+ )
914
+ end
915
+ end
916
+
917
+ context "with external URL which ends with the hostname parameter" do
918
+ let(:markdown) do
919
+ "http://qqqqqqiita.com/?a=b"
920
+ end
921
+
922
+ let(:context) do
923
+ { hostname: "qiita.com" }
924
+ end
925
+
926
+ it "creates link which has rel='nofollow' and target='_blank'" do
927
+ should eq(
928
+ '<p><a href="http://qqqqqqiita.com/?a=b" class="autolink" rel="nofollow" target="_blank">' \
929
+ "http://qqqqqqiita.com/?a=b</a></p>\n"
930
+ )
931
+ end
932
+ end
933
+
934
+ context "with external anchor tag which ends with the hostname parameter" do
935
+ let(:markdown) do
936
+ '<a href="http://qqqqqqiita.com/?a=b">foobar</a>'
937
+ end
938
+
939
+ let(:context) do
940
+ { hostname: "qiita.com" }
941
+ end
942
+
943
+ it "creates link which has rel='nofollow' and target='_blank'" do
944
+ should eq(
945
+ "<p><a href=\"http://qqqqqqiita.com/?a=b\" rel=\"nofollow\" target=\"_blank\">foobar</a></p>\n"
946
+ )
947
+ end
948
+ end
949
+
950
+ context "with sub-domain URL of hostname parameter" do
951
+ let(:markdown) do
952
+ "http://sub.qiita.com/?a=b"
953
+ end
954
+
955
+ let(:context) do
956
+ { hostname: "qiita.com" }
957
+ end
958
+
959
+ it "creates link which has rel='nofollow' and target='_blank'" do
960
+ should eq(
961
+ '<p><a href="http://sub.qiita.com/?a=b" class="autolink" rel="nofollow" target="_blank">' \
962
+ "http://sub.qiita.com/?a=b</a></p>\n"
963
+ )
964
+ end
965
+ end
966
+
967
+ context "with external anchor tag which has rel attribute" do
968
+ let(:markdown) do
969
+ '<a href="http://external.com/?a=b" rel="url">foobar</a>'
970
+ end
971
+
972
+ let(:context) do
973
+ { hostname: "qiita.com" }
974
+ end
975
+
976
+ it "creates link which has rel='nofollow' and target='_blank', and rel value is overwritten" do
977
+ should eq(
978
+ "<p><a href=\"http://external.com/?a=b\" rel=\"nofollow\" target=\"_blank\">foobar</a></p>\n"
979
+ )
980
+ end
981
+ end
850
982
  end
851
983
  end
@@ -7,7 +7,7 @@ describe Qiita::Markdown::SummaryProcessor do
7
7
  end
8
8
 
9
9
  let(:context) do
10
- {}
10
+ { hostname: "example.com" }
11
11
  end
12
12
 
13
13
  let(:markdown) do
@@ -185,17 +185,17 @@ describe Qiita::Markdown::SummaryProcessor do
185
185
 
186
186
  context "with a long document consisting of nested elements" do
187
187
  before do
188
- context[:truncate] = { length: 10 }
188
+ context[:truncate] = { length: 12 }
189
189
  end
190
190
 
191
191
  let(:markdown) do
192
192
  <<-EOS.strip_heredoc
193
- _[Qiita](http://qiita.com/) is **a technical knowledge sharing and collaboration platform for programmers**._
193
+ _[Example](http://example.com/) is **a technical knowledge sharing and collaboration platform for programmers**._
194
194
  EOS
195
195
  end
196
196
 
197
197
  it "truncates it while honoring the document structure" do
198
- should eq '<em><a href="http://qiita.com/">Qiita</a> is <strong>…</strong></em>'
198
+ should eq '<em><a href="http://example.com/">Example</a> is <strong>…</strong></em>'
199
199
  end
200
200
  end
201
201
 
@@ -206,13 +206,13 @@ describe Qiita::Markdown::SummaryProcessor do
206
206
 
207
207
  let(:markdown) do
208
208
  <<-EOS.strip_heredoc
209
- **12** 4 [ 6](http://qiita.com/)_7
209
+ **12** 4 [ 6](http://example.com/)_7
210
210
  9_ 123
211
211
  EOS
212
212
  end
213
213
 
214
214
  it "truncates it while counting the consecutive whilespaces as one" do
215
- should eq "<strong>12</strong> 4 <a href=\"http://qiita.com/\"> 6</a><em>7\n9</em>…"
215
+ should eq "<strong>12</strong> 4 <a href=\"http://example.com/\"> 6</a><em>7\n9</em>…"
216
216
  end
217
217
  end
218
218
 
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.14.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-22 00:00:00.000000000 Z
11
+ date: 2016-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gemoji
@@ -114,6 +114,20 @@ dependencies:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: addressable
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
117
131
  - !ruby/object:Gem::Dependency
118
132
  name: activesupport
119
133
  requirement: !ruby/object:Gem::Requirement
@@ -250,6 +264,7 @@ files:
250
264
  - lib/qiita/markdown/filters/checkbox.rb
251
265
  - lib/qiita/markdown/filters/code.rb
252
266
  - lib/qiita/markdown/filters/emoji.rb
267
+ - lib/qiita/markdown/filters/external_link.rb
253
268
  - lib/qiita/markdown/filters/footnote.rb
254
269
  - lib/qiita/markdown/filters/greenmat.rb
255
270
  - lib/qiita/markdown/filters/group_mention.rb
@@ -301,4 +316,3 @@ test_files:
301
316
  - spec/qiita/markdown/processor_spec.rb
302
317
  - spec/qiita/markdown/summary_processor_spec.rb
303
318
  - spec/spec_helper.rb
304
- has_rdoc: