tdiary-contrib 5.6.0 → 5.6.1
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/lib/tdiary/contrib/version.rb +1 -1
- data/plugin/amp.rb +156 -0
- data/spec/amp_spec.rb +125 -0
- data/spec/spec_helper.rb +10 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 947fdef94c86aaa2494241b7f6d874dcd49dd9d0302d2a582c0afc183573dec0
|
|
4
|
+
data.tar.gz: 27162faca3152d2a496dff50aa8c507ca3cc66666983544deb04a1f843a2c017
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b8370f2699f00fd4907b9386f45fe647d46698bd618814c0a680e0fe4c4c5e2fa280625b5802515980503f56be0f2af01f2f48d1053eb85d7b2ad2627cdd397a
|
|
7
|
+
data.tar.gz: a5ac4cccedccd02007b7c729e425361401705e6bdced0f2497778ea76fa84e648c2d97eb48eb7af329796414cf05b711903a94f461c26e1706e2f5a3db52951e
|
data/plugin/amp.rb
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# amp.rb
|
|
2
|
+
#
|
|
3
|
+
# generate AMP style HTML
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2016 MATSUOKA Kohei
|
|
6
|
+
# Distributed under the GPL2 or any later version.
|
|
7
|
+
#
|
|
8
|
+
module AMP
|
|
9
|
+
def amp_header_procs
|
|
10
|
+
@amp_header_procs ||= []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def amp_body_enter_procs
|
|
14
|
+
@amp_body_enter_procs ||= []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_amp_header_proc(&block)
|
|
18
|
+
amp_header_procs << block if block_given?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def add_amp_body_enter_proc(&block)
|
|
22
|
+
amp_body_enter_procs << block if block_given?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def amp_header_proc
|
|
26
|
+
amp_header_procs.map{|proc| proc.call }.join("\n")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def amp_body_enter_proc
|
|
30
|
+
amp_body_enter_procs.map {|proc| proc.call }.join("\n")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
extend AMP
|
|
34
|
+
|
|
35
|
+
add_header_proc do
|
|
36
|
+
if @mode == 'day'
|
|
37
|
+
begin
|
|
38
|
+
diary = @diaries[@date.strftime('%Y%m%d')]
|
|
39
|
+
%Q|<link rel="amphtml" href="#{amp_html_url(diary)}">|
|
|
40
|
+
rescue NoMethodError
|
|
41
|
+
''
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
add_content_proc('amp') do |date|
|
|
47
|
+
begin
|
|
48
|
+
diary = @diaries[date]
|
|
49
|
+
ERB.new(amp_template).result(binding)
|
|
50
|
+
rescue NoMethodError
|
|
51
|
+
raise TDiary::NotFound
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def amp_body(diary)
|
|
56
|
+
apply_plugin(diary.to_html)
|
|
57
|
+
.gsub(/<img\s/, '<amp-img layout="responsive" ')
|
|
58
|
+
.gsub(/<script[^<]+<\/script>/, '')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def amp_canonical_url(diary)
|
|
62
|
+
URI.join(@conf.base_url, anchor(diary.date.strftime('%Y%m%d')))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def amp_day_title(diary)
|
|
66
|
+
title_proc(Time::at(@date.to_i), diary.title)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def amp_html_url(diary)
|
|
70
|
+
uri = amp_canonical_url(diary)
|
|
71
|
+
uri.query = [uri.query, "plugin=amp"].compact.join '&'
|
|
72
|
+
uri
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def amp_style
|
|
76
|
+
base_css = amp_base_css
|
|
77
|
+
theme_css = amp_theme_css
|
|
78
|
+
.gsub(/^@charset.*$/, '')
|
|
79
|
+
.gsub(/!important/, '')
|
|
80
|
+
|
|
81
|
+
<<-EOL
|
|
82
|
+
#{base_css}
|
|
83
|
+
#{theme_css}
|
|
84
|
+
EOL
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def amp_base_css
|
|
88
|
+
base_css_path = theme_paths_local.map {|path|
|
|
89
|
+
File.join(File.dirname(path), "base.css")
|
|
90
|
+
}.find {|path|
|
|
91
|
+
File.exist?(path)
|
|
92
|
+
}
|
|
93
|
+
base_css_path ? File.read(base_css_path) : ''
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def amp_theme_css
|
|
97
|
+
_, location, theme = @conf.theme.match(%r|(\w+)/(\w+)|).to_a
|
|
98
|
+
case location
|
|
99
|
+
when 'online'
|
|
100
|
+
require 'uri'
|
|
101
|
+
require 'open-uri'
|
|
102
|
+
uri = URI.parse(theme_url_online(theme))
|
|
103
|
+
uri.scheme ||= 'https'
|
|
104
|
+
URI.parse(uri.to_s).read
|
|
105
|
+
when 'local'
|
|
106
|
+
theme_path = theme_paths_local.map {|path|
|
|
107
|
+
File.join(File.dirname(path), "#{theme}/#{theme}.css")
|
|
108
|
+
}.find {|path|
|
|
109
|
+
File.exist?(path)
|
|
110
|
+
}
|
|
111
|
+
theme_path ? File.read(theme_path) : ''
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def amp_title
|
|
116
|
+
@conf.html_title
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def amp_template
|
|
120
|
+
<<~'HTML'
|
|
121
|
+
<!doctype html>
|
|
122
|
+
<html ⚡ lang="ja">
|
|
123
|
+
<head>
|
|
124
|
+
<meta charset="utf-8">
|
|
125
|
+
<%= amp_header_proc %>
|
|
126
|
+
<script async src="https://cdn.ampproject.org/v0.js"></script>
|
|
127
|
+
<title><%= amp_title %></title>
|
|
128
|
+
<link rel="canonical" href="<%= amp_canonical_url(diary) %>" />
|
|
129
|
+
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
|
|
130
|
+
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
|
|
131
|
+
<style amp-custom>
|
|
132
|
+
<%= amp_style %>
|
|
133
|
+
</style>
|
|
134
|
+
</head>
|
|
135
|
+
<body>
|
|
136
|
+
<%= amp_body_enter_proc %>
|
|
137
|
+
<div class="whole-content">
|
|
138
|
+
<div class="adminmenu">
|
|
139
|
+
<%= navi_user %>
|
|
140
|
+
</div>
|
|
141
|
+
<div class="content">
|
|
142
|
+
<h1><a href="<%= amp_canonical_url(diary) %>"><%= amp_title %></a></h1>
|
|
143
|
+
<div class="day">
|
|
144
|
+
<h2><%= amp_day_title(diary) %></h2>
|
|
145
|
+
<div class="body">
|
|
146
|
+
<%= amp_body(diary) %>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
<div class="footer">
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</body>
|
|
154
|
+
</html>
|
|
155
|
+
HTML
|
|
156
|
+
end
|
data/spec/amp_spec.rb
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'tdiary'
|
|
4
|
+
require 'tdiary/plugin'
|
|
5
|
+
|
|
6
|
+
describe "amp plugin w/" do
|
|
7
|
+
before do
|
|
8
|
+
# stub of TDiary::IO::Diary
|
|
9
|
+
@diary = Object.new.tap {|diary|
|
|
10
|
+
allow(diary).to receive(:title) { 'Example Diary' }
|
|
11
|
+
allow(diary).to receive(:date) { Time.parse('2017/3/2') }
|
|
12
|
+
}
|
|
13
|
+
@conf = PluginFake::Config.new.tap {|conf|
|
|
14
|
+
# an empty directory, so that only amp.rb is loaded
|
|
15
|
+
conf.plugin_path = @cache_path
|
|
16
|
+
conf.lang = 'ja'
|
|
17
|
+
allow(conf).to receive(:base_url) { 'http://example.com/index.rb' }
|
|
18
|
+
}
|
|
19
|
+
@plugin = TDiary::Plugin.new(
|
|
20
|
+
debug: true,
|
|
21
|
+
conf: @conf,
|
|
22
|
+
date: Time.parse('2017/3/2'),
|
|
23
|
+
diaries: { '20170302' => @diary }
|
|
24
|
+
).tap {|plugin|
|
|
25
|
+
plugin.load_plugin(plugin_path(:amp))
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "#amp_canonical_url" do
|
|
30
|
+
subject { @plugin.amp_canonical_url(@diary).to_s }
|
|
31
|
+
it { expect(subject).to eq('http://example.com/index.rb?date=20170302') }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "#header_proc" do
|
|
35
|
+
subject { @plugin.__send__(:header_proc) }
|
|
36
|
+
|
|
37
|
+
describe "when @mode == 'day'" do
|
|
38
|
+
before { @plugin.instance_variable_set(:@mode, 'day') }
|
|
39
|
+
it { expect(subject).to eq('<link rel="amphtml" href="http://example.com/index.rb?date=20170302&plugin=amp">') }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "when @mode != 'day'" do
|
|
43
|
+
before { @plugin.instance_variable_set(:@mode, 'latest') }
|
|
44
|
+
it { expect(subject).to eq('') }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "#amp_theme_css" do
|
|
49
|
+
subject { @plugin.amp_theme_css }
|
|
50
|
+
|
|
51
|
+
describe "when local theme" do
|
|
52
|
+
before {
|
|
53
|
+
@conf.theme = 'local/default'
|
|
54
|
+
allow(@plugin).to receive(:theme_paths_local) { [File.join(TDiary.root, 'theme/*')] }
|
|
55
|
+
}
|
|
56
|
+
it { expect(subject).to include('Title: tDiary3 default') }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "when online theme" do
|
|
60
|
+
before {
|
|
61
|
+
@conf.theme = 'online/default'
|
|
62
|
+
allow(@plugin).to receive(:theme_url_online) { '//tdiary.github.io/tdiary-theme/default/default.css' }
|
|
63
|
+
stub_request(:get, 'https://tdiary.github.io/tdiary-theme/default/default.css')
|
|
64
|
+
.to_return(body: File.read(File.join(TDiary.root, 'theme/default/default.css')))
|
|
65
|
+
}
|
|
66
|
+
it { expect(subject).to include('Title: tDiary3 default') }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "#amp_day_title" do
|
|
71
|
+
subject { @plugin.amp_day_title(@diary) }
|
|
72
|
+
it { expect(subject).to eq('Example Diary') }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe "#amp_body" do
|
|
76
|
+
subject { @plugin.amp_body(@diary) }
|
|
77
|
+
|
|
78
|
+
describe "when contain img element" do
|
|
79
|
+
before { allow(@diary).to receive(:to_html) {
|
|
80
|
+
<<-HTML
|
|
81
|
+
<h3>subsection</h3>
|
|
82
|
+
<p>This is a test diary.</p>
|
|
83
|
+
<img src="image.jpg" weight="640" height="480">
|
|
84
|
+
HTML
|
|
85
|
+
} }
|
|
86
|
+
it { expect(subject).to include('<h3>subsection</h3>') }
|
|
87
|
+
it { expect(subject).to include('<amp-img layout="responsive" src="image.jpg" weight="640" height="480">') }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe "when contain script element" do
|
|
91
|
+
before { allow(@diary).to receive(:to_html) {
|
|
92
|
+
<<-HTML
|
|
93
|
+
<h3>subsection</h3>
|
|
94
|
+
<p>This is a test diary.</p>
|
|
95
|
+
<script>
|
|
96
|
+
console.log("test");
|
|
97
|
+
</script>
|
|
98
|
+
<noscript>noscript</noscript>
|
|
99
|
+
HTML
|
|
100
|
+
} }
|
|
101
|
+
it { expect(subject).to include('<h3>subsection</h3>') }
|
|
102
|
+
it { expect(subject).not_to include('<script>') }
|
|
103
|
+
it { expect(subject).to include('<noscript>noscript</noscript>') }
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "#content_proc" do
|
|
108
|
+
subject { @plugin.__send__(:content_proc, 'amp', '20170302') }
|
|
109
|
+
before {
|
|
110
|
+
@conf.theme = 'local/default'
|
|
111
|
+
allow(@plugin).to receive(:theme_paths_local) { [File.join(TDiary.root, 'theme/*')] }
|
|
112
|
+
allow(@plugin).to receive(:navi_user) { '' }
|
|
113
|
+
allow(@diary).to receive(:to_html) { '<h3>sample</h3>' }
|
|
114
|
+
}
|
|
115
|
+
it { expect(subject).to include('<html ⚡ lang="ja">') }
|
|
116
|
+
it { expect(subject).to include('<h3>sample</h3>') }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe "AMP module" do
|
|
120
|
+
subject { @plugin }
|
|
121
|
+
it { expect(subject.singleton_class.constants).to include(:AMP) }
|
|
122
|
+
it { expect(subject.methods).to include(:add_amp_header_proc) }
|
|
123
|
+
it { expect(subject.methods).to include(:amp_body_enter_proc) }
|
|
124
|
+
end
|
|
125
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -115,7 +115,9 @@ class PluginFake
|
|
|
115
115
|
|
|
116
116
|
class Config
|
|
117
117
|
|
|
118
|
-
attr_accessor :index, :
|
|
118
|
+
attr_accessor :index, :update, :author_name, :author_mail, :index_page,
|
|
119
|
+
:html_title, :theme, :css, :date_format, :referer_table, :options, :cgi,
|
|
120
|
+
:plugin_path, :lang, :io_class
|
|
119
121
|
|
|
120
122
|
def initialize
|
|
121
123
|
@cgi = CGIFake.new
|
|
@@ -123,6 +125,7 @@ class PluginFake
|
|
|
123
125
|
@options2 = {}
|
|
124
126
|
@index = './'
|
|
125
127
|
@html_title = ''
|
|
128
|
+
@io_class = DummyIO
|
|
126
129
|
|
|
127
130
|
bot = ["bot", "spider", "antenna", "crawler", "moget", "slurp"]
|
|
128
131
|
bot += @options['bot'] || []
|
|
@@ -190,6 +193,12 @@ class CGIFake
|
|
|
190
193
|
end
|
|
191
194
|
end
|
|
192
195
|
|
|
196
|
+
class DummyIO
|
|
197
|
+
def self.plugin_open(conf); nil; end
|
|
198
|
+
def self.plugin_close(storage); end
|
|
199
|
+
def self.plugin_transaction(storage, plugin); end
|
|
200
|
+
end
|
|
201
|
+
|
|
193
202
|
def fake_plugin( name_sym, cgi=nil, base=nil, &block )
|
|
194
203
|
plugin = PluginFake.new
|
|
195
204
|
yield plugin if block_given?
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tdiary-contrib
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.6.
|
|
4
|
+
version: 5.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tDiary contributors
|
|
@@ -248,6 +248,7 @@ files:
|
|
|
248
248
|
- misc/section_footer2/twitter.yaml
|
|
249
249
|
- misc/section_footer2/yahoo.yaml
|
|
250
250
|
- plugin/add_bookmark.rb
|
|
251
|
+
- plugin/amp.rb
|
|
251
252
|
- plugin/apple_webclip.rb
|
|
252
253
|
- plugin/appstore.rb
|
|
253
254
|
- plugin/bigpresen.rb
|
|
@@ -412,6 +413,7 @@ files:
|
|
|
412
413
|
- plugin/youtube.rb
|
|
413
414
|
- plugin/yshop.rb
|
|
414
415
|
- plugin/zenback.rb
|
|
416
|
+
- spec/amp_spec.rb
|
|
415
417
|
- spec/apple_webclip_spec.rb
|
|
416
418
|
- spec/fixtures/flickr/5950109223.flickr.photos.getInfo.xml
|
|
417
419
|
- spec/fixtures/flickr/5950109223.flickr.photos.getSizes.xml
|
|
@@ -550,6 +552,7 @@ rubygems_version: 3.6.9
|
|
|
550
552
|
specification_version: 4
|
|
551
553
|
summary: tDiary contributions package
|
|
552
554
|
test_files:
|
|
555
|
+
- spec/amp_spec.rb
|
|
553
556
|
- spec/apple_webclip_spec.rb
|
|
554
557
|
- spec/fixtures/flickr/5950109223.flickr.photos.getInfo.xml
|
|
555
558
|
- spec/fixtures/flickr/5950109223.flickr.photos.getSizes.xml
|