tdiary 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/Gemfile.lock +11 -12
- data/doc/HOWTO-make-theme.md +3 -3
- data/js/draft.js +152 -52
- data/js/image.js +127 -28
- data/lib/tdiary/version.rb +1 -1
- data/misc/plugin/amazon.rb +37 -11
- data/misc/plugin/amazon_rakuten.rb +75 -0
- data/misc/plugin/draft.rb +75 -0
- data/misc/plugin/en/image.rb +5 -0
- data/misc/plugin/en/makerss.rb +4 -0
- data/misc/plugin/image.rb +14 -3
- data/misc/plugin/ja/makerss.rb +3 -0
- data/misc/plugin/makerss.rb +3 -2
- data/theme/default/default.css +33 -8
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/cgi-0.5.2/cgi/escape.so +0 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/cgi-0.5.2/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.5.1/date_core.so +0 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.5.1/gem_make.out +6 -6
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.5.1/mkmf.log +4 -4
- data/vendor/bundle/ruby/3.4.0/gems/cgi-0.5.2/ext/cgi/escape/Makefile +3 -3
- data/vendor/bundle/ruby/3.4.0/gems/cgi-0.5.2/lib/cgi/escape.so +0 -0
- data/vendor/bundle/ruby/3.4.0/gems/date-3.5.1/ext/date/Makefile +3 -3
- data/vendor/bundle/ruby/3.4.0/gems/date-3.5.1/lib/date_core.so +0 -0
- metadata +2 -3
- data/misc/plugin/amp.rb +0 -118
- data/views/amp.rhtml +0 -34
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0152dd908530b141b305017532d2fdbee7d61cacb8eeb955e7da169504b68604
|
|
4
|
+
data.tar.gz: 0ad54ddca02502bae29ba3d69cf7b972c6ecd5c4cec62800f21600f98d016a62
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d1655ec19c3d0079bd353cbd83593d5ecacbe15d75087daf08d9ecc5b747e4fc5ec61297dbd3a5722dcadc89c6a85745f2a6e7497cf0ac390daf3cd9b4ca6dd
|
|
7
|
+
data.tar.gz: 8192a8f3fe135f261f3cb942addf64bf6aabc8b9300fe6102e71053105c87f6ff73457e7e98ca9d60a677289011399327552a6d433951e30fa8fc53256854519
|
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
GIT
|
|
2
2
|
remote: https://github.com/tdiary/tdiary-contrib.git
|
|
3
|
-
revision:
|
|
3
|
+
revision: 1c265fc47175dbe7573b166fc865b5893036c771
|
|
4
4
|
specs:
|
|
5
|
-
tdiary-contrib (5.
|
|
5
|
+
tdiary-contrib (5.6.0)
|
|
6
6
|
coderay
|
|
7
7
|
holiday_japan
|
|
8
8
|
pushbullet_ruby
|
|
@@ -69,10 +69,10 @@ GEM
|
|
|
69
69
|
commonmarker (2.9.0-x86_64-linux-musl)
|
|
70
70
|
concurrent-ruby (1.3.8)
|
|
71
71
|
connection_pool (3.0.2)
|
|
72
|
-
cuprite (0.
|
|
72
|
+
cuprite (0.18)
|
|
73
73
|
capybara (~> 3.0)
|
|
74
|
-
ferrum (~> 0.
|
|
75
|
-
dalli (5.1.
|
|
74
|
+
ferrum (~> 0.18.0)
|
|
75
|
+
dalli (5.1.1)
|
|
76
76
|
logger
|
|
77
77
|
date (3.5.1)
|
|
78
78
|
diff-lcs (1.6.2)
|
|
@@ -82,11 +82,10 @@ GEM
|
|
|
82
82
|
faraday (0.17.6)
|
|
83
83
|
multipart-post (>= 1.2, < 3)
|
|
84
84
|
fastimage (2.4.1)
|
|
85
|
-
ferrum (0.
|
|
85
|
+
ferrum (0.18.0)
|
|
86
86
|
addressable (~> 2.5)
|
|
87
87
|
base64 (~> 0.2)
|
|
88
88
|
concurrent-ruby (~> 1.1)
|
|
89
|
-
webrick (~> 1.7)
|
|
90
89
|
websocket-driver (~> 0.7)
|
|
91
90
|
hashie (5.1.0)
|
|
92
91
|
logger
|
|
@@ -108,7 +107,7 @@ GEM
|
|
|
108
107
|
net-imap
|
|
109
108
|
net-pop
|
|
110
109
|
net-smtp
|
|
111
|
-
matrix (0.4.
|
|
110
|
+
matrix (0.4.3)
|
|
112
111
|
memcachier (0.0.2)
|
|
113
112
|
mime-types (3.7.0)
|
|
114
113
|
logger
|
|
@@ -214,7 +213,7 @@ GEM
|
|
|
214
213
|
rdtool (0.6.39)
|
|
215
214
|
nkf (>= 0.1, < 1.0)
|
|
216
215
|
redcarpet (3.6.1)
|
|
217
|
-
regexp_parser (2.
|
|
216
|
+
regexp_parser (2.12.0)
|
|
218
217
|
rexml (3.4.4)
|
|
219
218
|
rspec (3.13.2)
|
|
220
219
|
rspec-core (~> 3.13.0)
|
|
@@ -231,9 +230,9 @@ GEM
|
|
|
231
230
|
rspec-support (3.13.6)
|
|
232
231
|
ruby2_keywords (0.0.5)
|
|
233
232
|
securerandom (0.4.1)
|
|
234
|
-
sequel (5.
|
|
233
|
+
sequel (5.108.0)
|
|
235
234
|
bigdecimal
|
|
236
|
-
simplecov (1.
|
|
235
|
+
simplecov (1.3.1)
|
|
237
236
|
snaky_hash (2.0.7)
|
|
238
237
|
hashie (>= 0.1.0, < 6)
|
|
239
238
|
version_gem (~> 1.1, >= 1.1.14)
|
|
@@ -249,7 +248,7 @@ GEM
|
|
|
249
248
|
sqlite3 (2.9.6-x86_64-darwin)
|
|
250
249
|
sqlite3 (2.9.6-x86_64-linux-gnu)
|
|
251
250
|
sqlite3 (2.9.6-x86_64-linux-musl)
|
|
252
|
-
tdiary (5.
|
|
251
|
+
tdiary (5.6.0)
|
|
253
252
|
cgi
|
|
254
253
|
emot
|
|
255
254
|
fastimage
|
data/doc/HOWTO-make-theme.md
CHANGED
|
@@ -36,7 +36,7 @@ tDiaryテーマには、以下のような基本的な約束事があります
|
|
|
36
36
|
テーマ・ギャラリー用の説明
|
|
37
37
|
-------------
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
テーマ集に登録されたテーマは、[テーマ・ギャラリー](https://github.com/tdiary/tdiary-theme)で一覧できます。テーマ集のテーマには、作者名やコメントを一定のフォーマットで書いたREADMEが付いています。
|
|
40
40
|
|
|
41
41
|
最初からこのフォーマットで書いておくと、テーマ集に入った時に見栄えがします。以下にそのフォーマットについて解説します。
|
|
42
42
|
|
|
@@ -50,7 +50,7 @@ Comment: 四つ葉のクローバーの葉をあしらった、シンプルで
|
|
|
50
50
|
|
|
51
51
|
この説明は、READMEの最初の行から記述します。「キー」と「値」を「: 」で挟んだ形式で、1項目1行で書きます。日本語を書くときは、文字コードをUTF-8にして下さい。英語の説明があれば、README.enというファイルにしてください。
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
各項目の意味は以下のとおりです。
|
|
54
54
|
|
|
55
55
|
- Title: テーマのタイトルです。ファイル名だけでは味気ないと思ったら、この項目を書いてください。なくてもかまいません。
|
|
56
56
|
- Author: 作者名
|
|
@@ -63,5 +63,5 @@ Comment: 四つ葉のクローバーの葉をあしらった、シンプルで
|
|
|
63
63
|
テーマ・テストベンチ
|
|
64
64
|
----------
|
|
65
65
|
|
|
66
|
-
テーマの見え方を確認するための、[テストベンチ](
|
|
66
|
+
テーマの見え方を確認するための、[テストベンチ](https://tdiary.org/tdiary-theme/themebench.html)というページがあります。こちらでは様々なエレメントの見え方や、代表的なプラグインの表示を確認することができます。テーマ作成時に利用してください。
|
|
67
67
|
|
data/js/draft.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* draft.js: save draft data to Web Storage automatically
|
|
3
|
-
*
|
|
3
|
+
* and keep a copy of them on the server
|
|
4
|
+
*
|
|
4
5
|
* Copyright (c) MATSUOKA Kohei <http://www.machu.jp/>
|
|
5
6
|
* Distributed under the GPL2 or any later version.
|
|
6
7
|
*/
|
|
@@ -8,70 +9,122 @@ $(function() {
|
|
|
8
9
|
|
|
9
10
|
if (!localStorage) { return; }
|
|
10
11
|
|
|
11
|
-
var Draft = function(storage, text) {
|
|
12
|
+
var Draft = function(storage, text, server) {
|
|
12
13
|
// 保存先のストレージ
|
|
13
14
|
this.storage = storage;
|
|
14
15
|
// 下書きの保存件数
|
|
15
|
-
this.maxCount =
|
|
16
|
+
this.maxCount = server.max;
|
|
16
17
|
// 下書き一覧
|
|
17
18
|
this.items = [];
|
|
18
|
-
|
|
19
|
-
this.
|
|
19
|
+
// このページで編集している下書きの ID
|
|
20
|
+
this.current = null;
|
|
21
|
+
// 最後に保存したテキストエリアの内容
|
|
22
|
+
this.text = text;
|
|
23
|
+
// サーバーにある下書きの ID と更新日時
|
|
24
|
+
this.synced = {};
|
|
25
|
+
|
|
26
|
+
this.initialize(text, server);
|
|
20
27
|
};
|
|
21
28
|
|
|
22
29
|
Draft.prototype = {
|
|
23
|
-
//
|
|
24
|
-
initialize: function(text) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
// ローカルストレージの下書きにサーバーの下書きを統合する
|
|
31
|
+
initialize: function(text, server) {
|
|
32
|
+
var items = this.storage.drafts ? JSON.parse(this.storage.drafts) : new Array();
|
|
33
|
+
var synced = this.synced;
|
|
34
|
+
$.each(items, function(index, item) {
|
|
35
|
+
if (!item.id) { item.id = DraftUtils.newId(); }
|
|
36
|
+
});
|
|
37
|
+
$.each(server.drafts, function(index, remote) {
|
|
38
|
+
synced[remote.id] = remote.date;
|
|
39
|
+
var local = DraftUtils.find(items, remote.id);
|
|
40
|
+
if (!local) {
|
|
41
|
+
items.push(remote);
|
|
42
|
+
} else if (local.date < remote.date) {
|
|
43
|
+
local.date = remote.date;
|
|
44
|
+
local.value = remote.value;
|
|
31
45
|
}
|
|
32
|
-
return true;
|
|
33
46
|
});
|
|
34
|
-
|
|
47
|
+
// 空の下書きと、日記として投稿済みの下書きを削除する
|
|
48
|
+
this.items = $.grep(items, function(item) {
|
|
49
|
+
return typeof item.value == "string" && DraftUtils.trim(item.value) != "" &&
|
|
50
|
+
$.inArray(item.id, server.deleted) < 0;
|
|
51
|
+
});
|
|
52
|
+
this.truncate();
|
|
53
|
+
// テキストエリアと同じ下書きがあれば、それを続けて編集する
|
|
54
|
+
// 改行と空白文字を無視して比較(プレビュー時に末尾へ改行が付加されるため)
|
|
55
|
+
var trimmed = DraftUtils.trim(text);
|
|
56
|
+
var same = $.grep(this.items, function(item) {
|
|
57
|
+
return DraftUtils.trim(item.value) == trimmed;
|
|
58
|
+
});
|
|
59
|
+
if (trimmed != "" && same.length > 0) {
|
|
60
|
+
this.current = same.pop().id;
|
|
61
|
+
}
|
|
62
|
+
this.store();
|
|
35
63
|
// console.log("Draft.initialized");
|
|
36
64
|
},
|
|
37
65
|
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (this.items.length > this.maxCount) {
|
|
51
|
-
this.items.shift();
|
|
66
|
+
// 編集している下書きを更新する
|
|
67
|
+
// テキストエリアの内容が変わっていなければ何もしない
|
|
68
|
+
save: function(text) {
|
|
69
|
+
if (text == this.text) { return; }
|
|
70
|
+
this.text = text;
|
|
71
|
+
if (DraftUtils.trim(text) == "") { return; }
|
|
72
|
+
var item = DraftUtils.find(this.items, this.current);
|
|
73
|
+
if (item) {
|
|
74
|
+
this.items.splice($.inArray(item, this.items), 1);
|
|
75
|
+
} else {
|
|
76
|
+
item = { id: DraftUtils.newId() };
|
|
77
|
+
this.current = item.id;
|
|
52
78
|
}
|
|
53
|
-
|
|
79
|
+
item.date = new Date().getTime();
|
|
80
|
+
item.value = text;
|
|
81
|
+
this.items.push(item);
|
|
82
|
+
this.truncate();
|
|
83
|
+
this.store();
|
|
54
84
|
},
|
|
55
85
|
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.
|
|
86
|
+
// 指定した下書きを読み込み、それを続けて編集する
|
|
87
|
+
load: function(id) {
|
|
88
|
+
var item = DraftUtils.find(this.items, id);
|
|
89
|
+
if (!item) { return null; }
|
|
90
|
+
this.current = item.id;
|
|
91
|
+
this.text = item.value;
|
|
61
92
|
return item.value;
|
|
62
93
|
},
|
|
63
94
|
|
|
64
|
-
//
|
|
95
|
+
// サーバーにまだ無い版の下書き一覧を返す
|
|
96
|
+
pending: function() {
|
|
97
|
+
var synced = this.synced;
|
|
98
|
+
return $.grep(this.items, function(item) {
|
|
99
|
+
return !(synced[item.id] >= item.date);
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
// サーバーへ保存した下書きを記録する
|
|
104
|
+
markSynced: function(items) {
|
|
105
|
+
var synced = this.synced;
|
|
106
|
+
$.each(items, function(index, item) {
|
|
107
|
+
synced[item.id] = item.date;
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// 最大でmaxCount件数の履歴を保持
|
|
112
|
+
truncate: function() {
|
|
113
|
+
this.items.sort(function(a, b) { return a.date - b.date; });
|
|
114
|
+
this.items = this.items.slice(-this.maxCount);
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
store: function() {
|
|
118
|
+
this.storage.drafts = JSON.stringify(this.items);
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// 下書きの ID とタイトルの一覧を返す(表示用)
|
|
65
122
|
// タイトルは textarea の先頭1行目 + 更新日時
|
|
66
123
|
titles: function() {
|
|
67
124
|
return $.map(this.items, function(item) {
|
|
68
|
-
var date = new Date(item.date);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (item.value && typeof item.value == "string") {
|
|
72
|
-
title = item.value.match(/.*/)[0];
|
|
73
|
-
}
|
|
74
|
-
return title + " (" + date + ")";
|
|
125
|
+
var date = DraftUtils.dateToString(new Date(item.date));
|
|
126
|
+
var title = item.value.match(/.*/)[0] || "No-Name";
|
|
127
|
+
return { id: item.id, title: title + " (" + date + ")" };
|
|
75
128
|
});
|
|
76
129
|
}
|
|
77
130
|
|
|
@@ -99,6 +152,13 @@ var DraftUtils = {
|
|
|
99
152
|
// 文字列から改行と空白文字を取り除く
|
|
100
153
|
trim: function(str) {
|
|
101
154
|
return str.replace(/\s+/g, "");
|
|
155
|
+
},
|
|
156
|
+
// 下書きの ID を作る(サーバーが受け付けるのは英小文字と数字のみ)
|
|
157
|
+
newId: function() {
|
|
158
|
+
return new Date().getTime().toString(36) + Math.random().toString(36).slice(2, 10);
|
|
159
|
+
},
|
|
160
|
+
find: function(items, id) {
|
|
161
|
+
return $.grep(items, function(item) { return item.id == id; })[0];
|
|
102
162
|
}
|
|
103
163
|
};
|
|
104
164
|
|
|
@@ -108,12 +168,17 @@ var DraftUtils = {
|
|
|
108
168
|
|
|
109
169
|
// 保存対象のテキストエリア
|
|
110
170
|
var textarea = $("[name=body]");
|
|
171
|
+
// 日記の更新フォーム
|
|
172
|
+
var form = textarea.closest("form");
|
|
111
173
|
// 下書き一覧を表示するセレクトボックス
|
|
112
174
|
var select = $("[name=drafts]");
|
|
113
175
|
// 自動保存の間隔(ミリ秒)
|
|
114
176
|
var autoSaveInterval = 5 * 1000;
|
|
177
|
+
// サーバーへ保存する間隔(ミリ秒)
|
|
178
|
+
var syncInterval = $tDiary.plugin.draft.interval * 1000;
|
|
115
179
|
|
|
116
|
-
var draft = new Draft(localStorage, textarea.val());
|
|
180
|
+
var draft = new Draft(localStorage, textarea.val(), $tDiary.plugin.draft.server);
|
|
181
|
+
var syncing = false;
|
|
117
182
|
|
|
118
183
|
// 下書き保存
|
|
119
184
|
saveDraft = function() {
|
|
@@ -122,26 +187,61 @@ saveDraft = function() {
|
|
|
122
187
|
};
|
|
123
188
|
// 下書き読み込み
|
|
124
189
|
loadDraft = function() {
|
|
125
|
-
|
|
190
|
+
var value = draft.load(select.val());
|
|
191
|
+
if (value != null) {
|
|
192
|
+
textarea.val(value);
|
|
193
|
+
}
|
|
126
194
|
showSelectForm(false);
|
|
127
195
|
};
|
|
196
|
+
// サーバーに無い下書きをサーバーへ保存
|
|
197
|
+
syncDraft = function(keepalive) {
|
|
198
|
+
var items = $.map(draft.pending(), function(item) {
|
|
199
|
+
return { id: item.id, date: item.date, value: item.value };
|
|
200
|
+
});
|
|
201
|
+
if (syncing || items.length == 0) { return; }
|
|
202
|
+
var params = new URLSearchParams();
|
|
203
|
+
params.append("plugin", "draft");
|
|
204
|
+
params.append("plugin_draft_sync", JSON.stringify(items));
|
|
205
|
+
form.find("[name=csrf_protection_key]").each(function() {
|
|
206
|
+
params.append("csrf_protection_key", $(this).val());
|
|
207
|
+
});
|
|
208
|
+
syncing = true;
|
|
209
|
+
fetch(form.attr("action"), { method: "POST", body: params, keepalive: keepalive })
|
|
210
|
+
.then(function(response) {
|
|
211
|
+
if (response.ok) { draft.markSynced(items); }
|
|
212
|
+
}, function() {})
|
|
213
|
+
.then(function() { syncing = false; });
|
|
214
|
+
};
|
|
128
215
|
// 下書き選択用のセレクトボックスを描画
|
|
129
|
-
showSelectForm = function(
|
|
130
|
-
var
|
|
216
|
+
showSelectForm = function(keepSelection) {
|
|
217
|
+
var selected = select.val();
|
|
131
218
|
select.empty();
|
|
132
|
-
$.each(draft.titles(), function(i,
|
|
133
|
-
select.append($("<option/>").attr("value",
|
|
134
|
-
select.val(i);
|
|
219
|
+
$.each(draft.titles(), function(i, item) {
|
|
220
|
+
select.append($("<option/>").attr("value", item.id).text(item.title));
|
|
135
221
|
});
|
|
136
|
-
if (
|
|
137
|
-
select.val(
|
|
222
|
+
if (!(keepSelection && selected)) {
|
|
223
|
+
selected = draft.current || select.children().last().val();
|
|
138
224
|
}
|
|
225
|
+
select.val(selected);
|
|
139
226
|
};
|
|
140
227
|
|
|
141
228
|
// DOMイベント設定
|
|
142
229
|
$("#draft_load").click(loadDraft);
|
|
143
230
|
setInterval(saveDraft, autoSaveInterval);
|
|
231
|
+
setInterval(function() { syncDraft(false); }, syncInterval);
|
|
144
232
|
textarea.change(saveDraft);
|
|
233
|
+
// タブを閉じる・切り替える前に保存する
|
|
234
|
+
$(document).on("visibilitychange", function() {
|
|
235
|
+
if (document.visibilityState == "hidden") {
|
|
236
|
+
saveDraft();
|
|
237
|
+
syncDraft(true);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
// 日記として投稿する下書きをサーバーに知らせる
|
|
241
|
+
form.submit(function() {
|
|
242
|
+
saveDraft();
|
|
243
|
+
$("[name=plugin_draft_id]").val(draft.current || "");
|
|
244
|
+
});
|
|
145
245
|
|
|
146
246
|
showSelectForm(false);
|
|
147
247
|
// console.log("ready");
|
data/js/image.js
CHANGED
|
@@ -18,20 +18,57 @@ $(function(){
|
|
|
18
18
|
$(this).css('cursor', 'default');
|
|
19
19
|
})
|
|
20
20
|
.on('click', '.image-img', function(){
|
|
21
|
-
|
|
22
|
-
var w = $('#image-info-' + idx + ' .image-width').text();
|
|
23
|
-
var h = $('#image-info-' + idx + ' .image-height').text();
|
|
24
|
-
$('#body').insertAtCaret($.makePluginTag('image', function(){
|
|
25
|
-
return [idx, "'" + $tDiary.plugin.image.alt + "'", 'nil', '[' + w + ',' + h + ']']
|
|
26
|
-
}));
|
|
21
|
+
$('#body').insertAtCaret(imageTag(this));
|
|
27
22
|
});
|
|
28
|
-
|
|
23
|
+
|
|
24
|
+
var imageTag = function(img, context){
|
|
25
|
+
var idx = img.id.replace('image-index-', '');
|
|
26
|
+
var w = $('#image-info-' + idx + ' .image-width', context).text();
|
|
27
|
+
var h = $('#image-info-' + idx + ' .image-height', context).text();
|
|
28
|
+
return $.makePluginTag('image', function(){
|
|
29
|
+
return [idx, "'" + $tDiary.plugin.image.alt + "'", 'nil', '[' + w + ',' + h + ']']
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
var imageFiles = function(files){
|
|
34
|
+
return $.grep(files, function(file){
|
|
35
|
+
return /^image\//.test(file.type);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
var shrink = function(file){
|
|
40
|
+
if(!window.createImageBitmap || file.type == 'image/gif'){
|
|
41
|
+
return Promise.resolve(file);
|
|
42
|
+
}
|
|
43
|
+
return createImageBitmap(file, {imageOrientation: 'from-image'}).then(function(bitmap){
|
|
44
|
+
var scale = Math.min(1, $tDiary.plugin.image.resize / Math.max(bitmap.width, bitmap.height));
|
|
45
|
+
var type = file.type == 'image/png' && scale == 1 ? 'image/png' : 'image/jpeg';
|
|
46
|
+
var canvas = document.createElement('canvas');
|
|
47
|
+
canvas.width = Math.max(1, Math.round(bitmap.width * scale));
|
|
48
|
+
canvas.height = Math.max(1, Math.round(bitmap.height * scale));
|
|
49
|
+
var context = canvas.getContext('2d');
|
|
50
|
+
if(type == 'image/jpeg'){
|
|
51
|
+
context.fillStyle = '#fff';
|
|
52
|
+
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
53
|
+
}
|
|
54
|
+
context.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
|
|
55
|
+
bitmap.close();
|
|
56
|
+
return new Promise(function(resolve){
|
|
57
|
+
canvas.toBlob(function(blob){
|
|
58
|
+
resolve(blob || file);
|
|
59
|
+
}, type, 0.85);
|
|
60
|
+
});
|
|
61
|
+
}).catch(function(){
|
|
62
|
+
return file;
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
29
66
|
var ImagePlugin = function(url){
|
|
30
67
|
this.url =url;
|
|
31
68
|
};
|
|
32
69
|
ImagePlugin.prototype = {
|
|
33
|
-
upload: function(formData
|
|
34
|
-
$.ajax({
|
|
70
|
+
upload: function(formData){
|
|
71
|
+
return $.ajax({
|
|
35
72
|
url: this.url,
|
|
36
73
|
type: 'post',
|
|
37
74
|
data: formData,
|
|
@@ -41,9 +78,6 @@ $(function(){
|
|
|
41
78
|
$('#plugin-image-addimage input[type="submit"]').attr('disabled', 'disabled');
|
|
42
79
|
$('#plugin-image-uploading').show();
|
|
43
80
|
},
|
|
44
|
-
success: function(data){
|
|
45
|
-
callback(data);
|
|
46
|
-
},
|
|
47
81
|
complete: function(){
|
|
48
82
|
$('#plugin-image-addimage input[type="submit"]').removeAttr('disabled');
|
|
49
83
|
$('#plugin-image-uploading').hide();
|
|
@@ -74,40 +108,96 @@ $(function(){
|
|
|
74
108
|
}
|
|
75
109
|
e.preventDefault();
|
|
76
110
|
|
|
77
|
-
uploadFiles(this.plugin_image_file.files);
|
|
111
|
+
uploadFiles($.makeArray(this.plugin_image_file.files));
|
|
78
112
|
this.reset();
|
|
79
113
|
return false;
|
|
80
114
|
});
|
|
81
115
|
|
|
116
|
+
var replaceMarker = function(marker, text){
|
|
117
|
+
var body = $('#body').get(0);
|
|
118
|
+
var start = body.value.indexOf(marker);
|
|
119
|
+
if(start < 0){
|
|
120
|
+
if(text){
|
|
121
|
+
$('#body').insertAtCaret(text);
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
var end = start + marker.length;
|
|
126
|
+
body.setRangeText(text, start, end, body.selectionStart == end ? 'end' : 'preserve');
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
var uploads = 0;
|
|
130
|
+
var uploading = Promise.resolve();
|
|
82
131
|
var uploadFiles = function(files) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
132
|
+
if(!files.length){
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
var marker = '[Uploading image ' + (++uploads) + '...]';
|
|
136
|
+
$('#body').insertAtCaret(marker);
|
|
137
|
+
uploading = uploading.then(function(){
|
|
138
|
+
return files.reduce(function(shrunk, file){
|
|
139
|
+
return shrunk.then(function(images){
|
|
140
|
+
return shrink(file).then(function(image){
|
|
141
|
+
return images.concat([image]);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}, Promise.resolve([]));
|
|
145
|
+
}).then(function(images){
|
|
146
|
+
var formData = new FormData();
|
|
147
|
+
formData.append('plugin', 'image');
|
|
148
|
+
formData.append('plugin_image_addimage', 'true');
|
|
149
|
+
formData.append('date', $tDiary.plugin.image.date);
|
|
150
|
+
$('form.update [name=csrf_protection_key]').first().each(function(){
|
|
151
|
+
formData.append(this.name, this.value);
|
|
152
|
+
});
|
|
153
|
+
$.each(images, function(i, image){
|
|
154
|
+
formData.append('plugin_image_file', image, image.name || (image.type == 'image/png' ? 'image.png' : 'image.jpg'));
|
|
155
|
+
});
|
|
91
156
|
|
|
92
|
-
|
|
93
|
-
|
|
157
|
+
var imagePlugin = new ImagePlugin($('form.update').attr('action'));
|
|
158
|
+
return imagePlugin.upload(formData);
|
|
159
|
+
}).then(function(result){
|
|
160
|
+
var list = $('#plugin-image-delimage', result).parents('div.form');
|
|
161
|
+
var tags = $.map(list.find('.image-img[data-added]'), function(img){
|
|
162
|
+
return imageTag(img, list);
|
|
163
|
+
});
|
|
164
|
+
if(!tags.length){
|
|
165
|
+
throw new Error('no image was saved');
|
|
166
|
+
}
|
|
94
167
|
$('#plugin-image-delimage').parents('div.form').remove();
|
|
95
168
|
$('<div>')
|
|
96
169
|
.attr({
|
|
97
170
|
'class': 'form'
|
|
98
171
|
})
|
|
99
|
-
.append(
|
|
172
|
+
.append(list.html())
|
|
100
173
|
.insertBefore('#plugin-image-addimage');
|
|
101
174
|
var timestamp = new Date().getTime();
|
|
102
175
|
$.each($('#plugin-image-delimage img'), function(){
|
|
103
176
|
$(this).attr('src', $(this).attr('src') + '?' + timestamp);
|
|
104
177
|
});
|
|
178
|
+
replaceMarker(marker, tags.join("\n"));
|
|
179
|
+
}).catch(function(error){
|
|
180
|
+
replaceMarker(marker, '');
|
|
181
|
+
console.error(error);
|
|
182
|
+
alert($tDiary.plugin.image.failed);
|
|
105
183
|
});
|
|
106
184
|
return false;
|
|
107
185
|
};
|
|
108
186
|
|
|
109
|
-
$('#
|
|
110
|
-
|
|
187
|
+
$('#body').on('paste', function(e){
|
|
188
|
+
var clipboard = e.originalEvent.clipboardData;
|
|
189
|
+
if(!clipboard || $.inArray('text/plain', clipboard.types) >= 0){
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
var files = imageFiles(clipboard.files);
|
|
193
|
+
if(files.length){
|
|
194
|
+
e.preventDefault();
|
|
195
|
+
this.setRangeText('', this.selectionStart, this.selectionEnd, 'end');
|
|
196
|
+
uploadFiles(files);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
$(document).on('submit', '#plugin-image-delimage', function(e){
|
|
111
201
|
e.preventDefault();
|
|
112
202
|
|
|
113
203
|
var ids = $.map($('#image-table input[name="plugin_image_id"]:checked'), function(i){
|
|
@@ -147,14 +237,23 @@ $(function(){
|
|
|
147
237
|
$('#plugin_image_dnd').hide();
|
|
148
238
|
$(this).css('border', 'dashed 3px #CCC');
|
|
149
239
|
$('#plugin-image-addimage form').show();
|
|
150
|
-
|
|
151
|
-
uploadFiles(files);
|
|
240
|
+
uploadFiles($.makeArray(e.originalEvent.dataTransfer.files));
|
|
152
241
|
return false;
|
|
153
242
|
})
|
|
154
243
|
.text($tDiary.plugin.image.drop_here)
|
|
155
244
|
.hide()
|
|
156
245
|
.appendTo('#plugin-image-addimage');
|
|
157
246
|
|
|
247
|
+
$('#body').on('drop', function(e){
|
|
248
|
+
var files = imageFiles(e.originalEvent.dataTransfer.files);
|
|
249
|
+
if(files.length){
|
|
250
|
+
e.preventDefault();
|
|
251
|
+
$('#plugin_image_dnd').hide();
|
|
252
|
+
$('#plugin-image-addimage form').show();
|
|
253
|
+
uploadFiles(files);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
158
257
|
var dnd_timer = false;
|
|
159
258
|
$('body')
|
|
160
259
|
.on('dragenter', function() {
|
data/lib/tdiary/version.rb
CHANGED