narou 2.6.1 → 2.7.0

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

Potentially problematic release.


This version of narou might be problematic. Click here for more details.

Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +65 -0
  3. data/README.md +69 -22
  4. data/lib/command.rb +1 -0
  5. data/lib/command/alias.rb +2 -2
  6. data/lib/command/convert.rb +3 -3
  7. data/lib/command/csv.rb +108 -0
  8. data/lib/command/download.rb +13 -1
  9. data/lib/command/freeze.rb +1 -1
  10. data/lib/command/init.rb +5 -1
  11. data/lib/command/inspect.rb +1 -1
  12. data/lib/command/mail.rb +1 -1
  13. data/lib/command/send.rb +2 -2
  14. data/lib/command/setting.rb +17 -1
  15. data/lib/command/tag.rb +28 -9
  16. data/lib/command/update.rb +57 -30
  17. data/lib/commandbase.rb +3 -2
  18. data/lib/commandline.rb +2 -2
  19. data/lib/converterbase.rb +70 -7
  20. data/lib/database.rb +1 -1
  21. data/lib/device.rb +3 -0
  22. data/lib/device/ibooks.rb +2 -2
  23. data/lib/device/ibunko.rb +4 -0
  24. data/lib/diffviewer.rb +2 -2
  25. data/lib/downloader.rb +16 -9
  26. data/lib/helper.rb +53 -22
  27. data/lib/inventory.rb +6 -2
  28. data/lib/narou.rb +13 -6
  29. data/lib/novelconverter.rb +35 -13
  30. data/lib/novelsetting.rb +7 -1
  31. data/lib/version.rb +1 -1
  32. data/lib/web/appserver.rb +78 -8
  33. data/lib/web/public/resources/common.ui.js +0 -39
  34. data/lib/web/public/resources/dataTables.colVis.js +1 -1
  35. data/lib/web/public/resources/default-style.css +1 -1
  36. data/lib/web/public/resources/help/bookmarklet1.png +0 -0
  37. data/lib/web/public/resources/help/bookmarklet2.png +0 -0
  38. data/lib/web/public/resources/images/dl_button0.gif +0 -0
  39. data/lib/web/public/resources/images/dl_button1.gif +0 -0
  40. data/lib/web/public/resources/narou.library.js +268 -36
  41. data/lib/web/public/resources/narou.queue.js +51 -0
  42. data/lib/web/public/resources/narou.ui.js +156 -59
  43. data/lib/web/settingmessages.rb +2 -1
  44. data/lib/web/views/{js/widget.erb → bookmarklet/download.js.erb} +1 -1
  45. data/lib/web/views/bookmarklet/insert_button.js.erb +133 -0
  46. data/lib/web/views/help.haml +31 -14
  47. data/lib/web/views/index.haml +62 -0
  48. data/lib/web/views/layout.haml +8 -7
  49. data/lib/web/views/parts/csv_import.haml +68 -0
  50. data/lib/web/views/parts/download_form.haml +89 -0
  51. data/lib/web/views/settings.haml +8 -3
  52. data/lib/web/views/style.scss +200 -14
  53. data/lib/web/views/{widget.haml → widget/download.haml} +18 -4
  54. data/lib/web/views/widget/drag_and_drop.haml +97 -0
  55. data/lib/web/worker.rb +39 -1
  56. data/narou.gemspec +56 -56
  57. data/preset/custom_chuki_tag.txt +1 -1
  58. data/preset/doubledash.png +0 -0
  59. data/preset/singledash.png +0 -0
  60. data/preset/vertical_font.css +1 -1
  61. data/spec/convert_spec.rb +5 -1
  62. data/spec/data/convert_test/auto_join_line/correct_test_auto_join_line.txt +6 -0
  63. data/spec/data/convert_test/auto_join_line/test_auto_join_line.txt +8 -0
  64. data/spec/data/convert_test/double_dash_to_image/correct_test_double_dash_to_image.txt +14 -0
  65. data/spec/data/convert_test/double_dash_to_image/setting.ini +1 -0
  66. data/spec/data/convert_test/double_dash_to_image/test_double_dash_to_image.txt +12 -0
  67. data/spec/worker_spec.rb +21 -2
  68. metadata +97 -60
@@ -17,7 +17,8 @@ module Narou
17
17
  "特殊な変数\n" \
18
18
  "<b>%NEW</b> : 最新データの差分用ファイルパス\n" \
19
19
  "<b>%OLD</b> : 古い方の差分用ファイルパス",
20
- "no-color" => "コンソールのカラー表示を無効にする\n※要WEB UIサーバ再起動"
20
+ "no-color" => "コンソールのカラー表示を無効にする\n※要WEB UIサーバ再起動",
21
+ "economy" => "容量節約に関する設定"
21
22
  }
22
23
  end
23
24
 
@@ -32,7 +32,7 @@
32
32
  var url, div, iframe, btn_close;
33
33
 
34
34
  url = '<%= "#{request.scheme}://#{env["SERVER_NAME"]}:#{env["SERVER_PORT"]}" %>' +
35
- "/widget/<%= params['mode'] %>?from=" + location.hostname + "&target=" +
35
+ "/widget/download?from=" + location.hostname + "&target=" +
36
36
  encodeURIComponent(location.href) + "&t=" + Date.now();
37
37
 
38
38
  // IE の場合、iframe は親のドキュメントモードが汚染して動かない可能性があるので対処
@@ -0,0 +1,133 @@
1
+ <%# vim: set ft=javascript : -%>
2
+ (function() {
3
+ // オフライン表記を先に消しておく
4
+ var offline = document.getElementById("narourb-offline");
5
+ offline.parentNode.removeChild(offline);
6
+
7
+ // 対応小説投稿サイトに関する情報
8
+ var site_settings = {
9
+ <%- Downloader.load_settings.each.with_index do |setting, i| -%>
10
+ "<%= setting["domain"] %>": {
11
+ <%- case setting["domain"] -%>
12
+ <%- when "www.mai-net.net" -%>
13
+ add_tail: "&n=0&count=1",
14
+ <%- when "ncode.syosetu.com", "novel18.syosetu.com", "novel.syosetu.org" -%>
15
+ add_tail: "/",
16
+ <%- when "www.akatsuki-novels.com" -%>
17
+ add_tail: "",
18
+ <%- end -%>
19
+ url: '(<%= setting["url"].gsub(/\?<.+?>/, "?:").gsub("\\", "\\\\\\\\") %>)'
20
+ }
21
+ <%= i == Downloader.load_settings.length - 1 ? "" : "," %>
22
+ <%- end -%>
23
+ };
24
+
25
+ // 管理している小説のURL一覧
26
+ var manage_novel_urls = [
27
+ <%-# バイナリーサーチ用にソートしておく -%>
28
+ <%- Database.instance.get_object.values.sort_by { |v| v["toc_url"] }.each do |data| -%>
29
+ '<%= data["toc_url"] %>',
30
+ <%- end -%>
31
+ ];
32
+
33
+ /*
34
+ * バイナリーサーチ
35
+ * 見つかったら見つかった位置のインデックス
36
+ * 見つからなかったら-1を返す
37
+ * array はソート済みである必要がある
38
+ */
39
+ var binarySearch = function(array, target) {
40
+ if (array.length === 0) return -1;
41
+ var left = 0, right = manage_novel_urls.length - 1;
42
+ while (left < right) {
43
+ var center = (left + right) / 2 | 0;
44
+ if (array[center] < target)
45
+ left = center + 1;
46
+ else if (array[center] > target)
47
+ right = center - 1;
48
+ else
49
+ return center;
50
+ }
51
+ if (array[left] === target) return left;
52
+ return -1;
53
+ };
54
+
55
+ /*
56
+ * 管理している小説のURLリストから検索
57
+ */
58
+ var searchRegisterURL = function(target) {
59
+ var result = binarySearch(manage_novel_urls, target);
60
+ if (result === -1)
61
+ return null;
62
+ return manage_novel_urls[result];
63
+ };
64
+
65
+ /*
66
+ * IE10未満のために自力でフォームエンコード
67
+ */
68
+ var encodeHTMLForm = function(data) {
69
+ var params = [];
70
+ for (var name in data) {
71
+ var value = data[name];
72
+ var param = encodeURIComponent(name) + '=' + encodeURIComponent(value);
73
+ params.push(param);
74
+ }
75
+ return params.join("&").replace(/%20/g, "+");
76
+ };
77
+
78
+ var server_origin = '<%= "#{request.scheme}://#{env["SERVER_NAME"]}:#{env["SERVER_PORT"]}" %>';
79
+
80
+ var createButtonElement = function(href) {
81
+ var span = document.createElement("span");
82
+ var img = document.createElement("img");
83
+ var space = span.cloneNode();
84
+ span.appendChild(img);
85
+ span.appendChild(space);
86
+ img.style.height = "1.15em";
87
+ img.style.cursor = "pointer";
88
+ space.textContent = " ";
89
+
90
+ var dl_listener = function(e) {
91
+ var url = server_origin + "/api/download";
92
+ try {
93
+ var xhr = new XMLHttpRequest;
94
+ xhr.open("POST", url);
95
+ xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
96
+ xhr.send(encodeHTMLForm({ targets: href }));
97
+ img.src = server_origin + "/resources/images/dl_button1.gif";
98
+ }
99
+ catch(e) {
100
+ // IE7モード(なろうのトップページをIEで見た場合)の時は xhr.open の時点で
101
+ // 例外が発生してWEBUIサーバまでデータが飛ばないので、画像のURLにパラメータ
102
+ // 仕込んでDLの通知を行う
103
+ img.src = server_origin + "/api/download4ie?target=" + encodeURIComponent(href);
104
+ }
105
+ // 登録したらもう押せないようにイベントを削除
106
+ img.onclick = null;
107
+ img.style.cursor = "default";
108
+ return false;
109
+ };
110
+
111
+ if (searchRegisterURL(href)) {
112
+ // すでにダンロード済みなら最初からグレー画像
113
+ img.src = server_origin + "/resources/images/dl_button1.gif";
114
+ img.style.cursor = "default";
115
+ }
116
+ else {
117
+ img.src = server_origin + "/resources/images/dl_button0.gif";
118
+ img.onclick = dl_listener;
119
+ }
120
+ return span;
121
+ };
122
+
123
+ var links = document.getElementsByTagName("a");
124
+ for (var i = 0; i < links.length; i++) {
125
+ //for (var i = 0; i < 3; i++) {
126
+ var link = links[i];
127
+ var setting = site_settings[link.hostname];
128
+ if (setting && link.href.match(setting.url)) {
129
+ var download_button = createButtonElement(RegExp.$1 + setting.add_tail);
130
+ link.parentNode.insertBefore(download_button, link);
131
+ }
132
+ }
133
+ })();
@@ -22,18 +22,20 @@
22
22
  },1000);
23
23
 
24
24
  u='#{request.scheme}://#{env["SERVER_NAME"]}:#{env["SERVER_PORT"]}'+
25
- '/js/widget.js?mode=download&t='+Date.now();
25
+ '/js/widget.js?mode=%MODE%&t='+Date.now();
26
26
  e=d.createElement('script');
27
27
  e.charset='utf-8';
28
28
  e.src=u;
29
29
  d.body.appendChild(e)
30
30
  };
31
31
 
32
- function createBookmarkletStrings(proc) {
33
- return ("javascript:(" + proc + ")(document)").replace(/ {2,}|\n/g, "");
32
+ function createBookmarkletStrings(proc, mode) {
33
+ var proc_string = proc.toString().replace("%MODE%", mode);
34
+ return ("javascript:(" + proc_string + ")(document)").replace(/ {2,}|\n/g, "");
34
35
  }
35
36
 
36
- $("#bookmarklet").attr("href", createBookmarkletStrings(bookmarklet));
37
+ $("#bookmarklet-download").attr("href", createBookmarkletStrings(bookmarklet, "download"));
38
+ $("#bookmarklet-insert-button").attr("href", createBookmarkletStrings(bookmarklet, "insert_button"));
37
39
  });
38
40
 
39
41
  .navbar.navbar-default.navbar-fixed-top(role="navigation")
@@ -58,16 +60,28 @@
58
60
  %span#queue 0
59
61
  #help-container.container.theme-showcase(role="main")
60
62
  %h2 ブックマークレット
61
- %p 小説掲載サイトを表示したまま直接ダウンロード出来るブックマークレットです。<br> |
62
- 下記のリンクをブックマークに登録して、ダウンロードしたい小説のページで実行して下さい。(WEB UIサーバ起動中に限ります)<br> |
63
- ブックマークバーにドラッグ&ドロップしたり、右クリックからブックマークにいれると簡単です。 |
64
- %p
65
- %a#bookmarklet(onclick="return false")
63
+ %h3 小説ページから直接ダウンロード
64
+ %div
65
+ %img#ss-bookmarklet1(src="/resources/help/bookmarklet1.png" class="img-thumbnail")
66
+ %p 小説掲載サイトを表示したまま直接ダウンロード出来るブックマークレットです。
67
+ %p 下記のリンクをブックマークに登録して、ダウンロードしたい小説のページで実行して下さい。(WEB UIサーバ起動中に限ります)
68
+ %p ブックマークバーにドラッグ&ドロップしたり、右クリックからブックマークにいれると簡単です。
69
+ %p
70
+ %span.glyphicon.glyphicon-bookmark
66
71
  %big
67
- %u Narou.rbでダウンロード
72
+ %a#bookmarklet-download(onclick="return false")
73
+ %u Narou.rbでダウンロード
68
74
 
69
- %p
70
- %small 基本的に小説ページ内にダウンロード中の表示が出ますが、IEを使っていてかつ小説家になろうの小説をダウンロードしようとした場合のみ、技術的制約から別ウィンドウが開きます。
75
+ %h3 ページ内の小説へのリンクにダウンロードボタンを付ける
76
+ %div
77
+ %img#ss-bookmarklet2(src="/resources/help/bookmarklet2.png" class="img-thumbnail")
78
+ %p 小説投稿サイト内の、各小説へのリンクの横にダウンロード用のボタンを埋め込みます。
79
+ %p ランキングページや一覧ページなどで実行するとダウンロードが一発で出来るようになったり、どれがダウンロード済みなのかが一目瞭然になります。
80
+ %p
81
+ %span.glyphicon.glyphicon-bookmark
82
+ %big
83
+ %a#bookmarklet-insert-button(onclick="return false")
84
+ %u DLボタン設置(Narou.rb)
71
85
 
72
86
  %hr
73
87
 
@@ -110,11 +124,14 @@
110
124
 
111
125
  %h4 シングル選択モード
112
126
  %div
113
- %p デフォルトの選択方法で、小説一覧をクリックしてひとつずつ選択するモードです。
127
+ %p 小説一覧をクリックしてひとつずつ選択するモードです。小説リストの文字情報を選択してコピー出来るのはこのモードだけです。
114
128
 
115
129
  %h4 範囲選択モード
116
130
  %div
117
131
  %img#ss-rect-select(src="/resources/help/rect_select.png" class="img-thumbnail")
118
- %p 一度に複数の小説を選択する場合に便利なモードです。始点をクリックしたあと終点をクリックして範囲を確定するか、始点から終点までをドラッグすることで範囲を決めることが出来ます。
132
+ %p 一度に複数の小説を選択する場合に便利なモードです。始点をクリックしたあと終点をクリックして範囲を確定するか、始点から終点までをドラッグすることで範囲を決めることが出来ます。範囲の始点と終点をクリック(タップ)のみで決定できるため、トラックパッドでの操作がし易いモードとなります。
119
133
  %p 範囲が確定された際にメニューが表示されるので、選択や解除等を選択します。反転は現在の選択状態を逆転させます。
120
134
 
135
+ %h4 ハイブリッド選択モード
136
+ %div
137
+ %p クリックで選択とドラッグで範囲選択を同時に行える、シングル選択モードと範囲選択モードの特徴を併せ持ったモードです。
@@ -63,6 +63,12 @@
63
63
  %span.active-ok.glyphicon.glyphicon-ok
64
64
  範囲選択モード
65
65
  %span.shortcut R
66
+ %li#action-select-mode-hybrid
67
+ %a(href="#")
68
+ %span
69
+ %span.active-ok.glyphicon.glyphicon-ok
70
+ ハイブリッド選択モード
71
+ %span.shortcut H
66
72
  %li.dropdown
67
73
  %a.dropdown-toggle(data-toggle="dropdown" href="#")
68
74
  タグ
@@ -75,6 +81,24 @@
75
81
  %a(href="#")
76
82
  %span
77
83
  選択した小説のタグを編集
84
+ %li.dropdown
85
+ %a.dropdown-toggle(data-toggle="dropdown" href="#")
86
+ ツール
87
+ %span.caret
88
+ %ul.dropdown-menu(role="menu")
89
+ %li#action-tool-open-dnd-window
90
+ %a(href="#")
91
+ %span
92
+ D&amp;Dウィンドウを開く
93
+ %li.divider
94
+ %li#action-tool-csv-download
95
+ %a(href="#")
96
+ %span
97
+ CSV形式でリストをダウンロード
98
+ %li#action-tool-csv-import
99
+ %a(href="#")
100
+ %span
101
+ CSVファイルからインポート
78
102
  %ul.nav.navbar-nav.navbar-right
79
103
  %li.dropdown
80
104
  %a.dropdown-toggle(data-toggle="dropdown" href="#")
@@ -131,6 +155,7 @@
131
155
  #console-container
132
156
  #console.console
133
157
  #console-buttons.console-buttons
158
+ %span.queue-cancel.glyphicon.glyphicon-remove-circle(data-toggle="tooltip" title="処理を中断")
134
159
  %span.console-trash.glyphicon.glyphicon-trash(data-toggle="tooltip" title="ログと履歴を削除")
135
160
  %span.console-expand
136
161
  %span.glyphicon.glyphicon-resize-full(data-toggle="tooltip" title="拡大")
@@ -161,6 +186,13 @@
161
186
  %a#button-update-force(href="#") 凍結済みでも更新
162
187
  .btn-group
163
188
  %button#button-send.btn.btn-warning(type="button") Send
189
+ - if Inventory.load("local_setting")["hotentry"]
190
+ %button.btn.btn-warning.dropdown-toggle(type="button" data-toggle="dropdown")
191
+ %span.caret
192
+ %span.sr-only Toggle Dropdown
193
+ %ul.dropdown-menu(role="menu")
194
+ %li
195
+ %a#button-send-hotentry(href="#") hotentry を送信
164
196
  .btn-group
165
197
  %button.btn.btn-info.dropdown-toggle.enable-selected(type="button" data-toggle="dropdown")
166
198
  Freeze
@@ -251,3 +283,33 @@
251
283
  .modal-footer
252
284
  %button.btn.btn-primary(type="button" data-dismiss="modal") 閉じる
253
285
 
286
+ %ul#select-color-menu.dropdown-menu(role="menu")
287
+ %li
288
+ %a#select-color-menu-green(href="#")
289
+ %big
290
+ %span.label.label-green.label-fixed-width Green
291
+ %li
292
+ %a#select-color-menu-yellow(href="#")
293
+ %big
294
+ %span.label.label-yellow.label-fixed-width Yellow
295
+ %li
296
+ %a#select-color-menu-blue(href="#")
297
+ %big
298
+ %span.label.label-blue.label-fixed-width Blue
299
+ %li
300
+ %a#select-color-menu-magenta(href="#")
301
+ %big
302
+ %span.label.label-magenta.label-fixed-width Magenta
303
+ %li
304
+ %a#select-color-menu-cyan(href="#")
305
+ %big
306
+ %span.label.label-cyan.label-fixed-width Cyan
307
+ %li
308
+ %a#select-color-menu-red(href="#")
309
+ %big
310
+ %span.label.label-red.label-fixed-width Red
311
+ %li
312
+ %a#select-color-menu-white(href="#")
313
+ %big
314
+ %span.label.label-white.label-fixed-width White
315
+
@@ -12,15 +12,15 @@
12
12
  %link{:href => "/theme/#{@bootstrap_theme}/bootstrap.min.css", :rel => "stylesheet"}/
13
13
  %link{:href => "/theme/#{@bootstrap_theme}/style.css", :rel => "stylesheet"}/
14
14
  - else
15
- %link{:href => "//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css", :rel => "stylesheet"}/
16
- %link{:href => "/resources/default-style.css", :rel => "stylesheet"}/
15
+ %link{:href => "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css", :rel => "stylesheet"}/
16
+ %link{:href => "/resources/default-style.css?_=#{Version}", :rel => "stylesheet"}/
17
17
  %link{:href => "//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.css", :rel => "stylesheet"}/
18
18
  %link{:href => "//cdn.datatables.net/colreorder/1.1.2/css/dataTables.colReorder.css", :rel => "stylesheet"}/
19
19
  %link{:href => "//cdn.datatables.net/colvis/1.1.1/css/dataTables.colVis.css", :rel => "stylesheet"}/
20
20
  %link{:href => "//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.5/css/bootstrap-select.min.css", :rel => "stylesheet"}/
21
21
  %link{:href => "/resources/perfect-scrollbar.min.css", :rel => "stylesheet"}/
22
22
  %link{:href => "/resources/toggle-switch.css", :rel => "stylesheet"}/
23
- %link{:href => "/style.css", :rel => "stylesheet"}/
23
+ %link{:href => "/style.css?_=#{Version}", :rel => "stylesheet"}/
24
24
  / HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries
25
25
  /[if lt IE 9]
26
26
  <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
@@ -37,7 +37,7 @@
37
37
  &= message
38
38
  != yield
39
39
  %script{:src => "//code.jquery.com/jquery-1.11.1.min.js"}
40
- %script{:src => "//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"}
40
+ %script{:src => "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"}
41
41
  %script{:src => "//cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"}
42
42
  %script{:src => "//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.js"}
43
43
  %script{:src => "//cdn.datatables.net/colreorder/1.1.2/js/dataTables.colReorder.min.js"}
@@ -49,8 +49,9 @@
49
49
  %script{:src => "/resources/jquery.outerclick.js"}
50
50
  %script{:src => "/resources/jquery.slidenavbar.js"}
51
51
  %script{:src => "/resources/jquery.moveto.js"}
52
- %script{:src => "/resources/narou.library.js"}
53
- %script{:src => "/resources/common.ui.js"}
52
+ %script{:src => "/resources/narou.library.js?_=#{Version}"}
53
+ %script{:src => "/resources/narou.queue.js?_=#{Version}"}
54
+ %script{:src => "/resources/common.ui.js?_=#{Version}"}
54
55
  :javascript
55
56
  $(document).ready(function($) {
56
57
  slideNavbar = $(".navbar-collapse").slideNavbar();
@@ -59,5 +60,5 @@
59
60
  });
60
61
  });
61
62
  - if env["PATH_INFO"] == "/"
62
- %script{:src => "/resources/narou.ui.js"}
63
+ %script{:src => "/resources/narou.ui.js?_=#{Version}"}
63
64
 
@@ -0,0 +1,68 @@
1
+ :javascript
2
+ var $here = $("#csv-drop-here");
3
+ var form_data = new FormData;
4
+
5
+ var appendFiles = function(files) {
6
+ $.each(files, function(i, file) {
7
+ form_data.append("files[]", file);
8
+ $("#csv-file-list").append($("<div>" + file.name + "</div>"));
9
+ });
10
+ };
11
+
12
+ $("#csv-drop-cover").hide();
13
+ $here.on("dragenter", function(e) {
14
+ $("#csv-drop-cover").show();
15
+ });
16
+
17
+ $("#csv-drop-cover")
18
+ .on("dragenter", function(e) {
19
+ $here.addClass("dragover");
20
+ })
21
+ .on("dragover", function(e) {
22
+ e.preventDefault();
23
+ e.dataTransfer.dropEffect = "copy";
24
+ return false;
25
+ })
26
+ .on("dragleave", function(e) {
27
+ $here.removeClass("dragover");
28
+ $(this).hide();
29
+ })
30
+ .on("drop", function(e) {
31
+ e.preventDefault();
32
+ $here.removeClass("dragover");
33
+ $(this).hide();
34
+ appendFiles(e.dataTransfer.files);
35
+ });
36
+
37
+ $("#csv-select-file-button").on("click", function(e) {
38
+ $("#csv-select-file-input").click();
39
+ });
40
+
41
+ $("#csv-select-file-input").on("change", function(e) {
42
+ appendFiles(this.files);
43
+ });
44
+
45
+ $("#csv-import-files").on("click", function(e) {
46
+ $.ajax({
47
+ url: "/api/csv/import",
48
+ type: "post",
49
+ data: form_data,
50
+ processData: false,
51
+ contentType: false
52
+ });
53
+ });
54
+
55
+ #csv-drop-here
56
+ .inner
57
+ %div
58
+ %div ここにCSVファイルをドラッグ&ドロップ
59
+ %div.else もしくは…
60
+ %div
61
+ %input#csv-select-file-input.hidden(type="file" multiple="multiple")
62
+ %button#csv-select-file-button.btn.btn-warning.btn-xs
63
+ ファイルを選択
64
+ #csv-drop-cover.drop-cover(effectAllowed="all")
65
+ #csv-file-list
66
+
67
+ -# インポートダイアログの「インポート」ボタンから処理を移譲されてくる
68
+ #csv-import-files.hidden
@@ -0,0 +1,89 @@
1
+ :javascript
2
+ var $here = $("#download-link-drop-here");
3
+ var form_data = new FormData;
4
+ var dnd = new Narou.DragDrop;
5
+ var action = new Narou.Action(null);
6
+
7
+ var appendLinks = function(event) {
8
+ dnd.getLinkText(event, function(link) {
9
+ if (dnd.isValidNovelUrl(link)) {
10
+ action.download(link);
11
+ }
12
+ else {
13
+ $here.addClass("error").delay(1500).queue(function() {
14
+ $(this).removeClass("error").dequeue();
15
+ });
16
+ }
17
+ });
18
+ };
19
+
20
+ $("#download-link-drop-cover")
21
+ .on("dragenter", function(e) {
22
+ $here.addClass("dragover");
23
+ })
24
+ .on("dragover", function(e) {
25
+ e.preventDefault();
26
+ e.dataTransfer.dropEffect = "copy";
27
+ return false;
28
+ })
29
+ .on("dragleave", function(e) {
30
+ $here.removeClass("dragover");
31
+ })
32
+ .on("drop", function(e) {
33
+ e.preventDefault();
34
+ $here.removeClass("dragover");
35
+ appendLinks(e);
36
+ });
37
+
38
+ $("#download-link-submit").on("click", function(e) {
39
+ var targets = $("#download-input").val();
40
+ $.post("/api/download", { targets: targets });
41
+ });
42
+
43
+ :css
44
+ #download-link-drop-area {
45
+ margin-top: 15px;
46
+ margin-bottom: 15px;
47
+ }
48
+ #download-link-drop-here {
49
+ position: relative;
50
+ width: 100%;
51
+ height: 100px;
52
+ border: 4px dashed #ddd;
53
+ color: lightgray;
54
+ transition: border-color 0.4s ease, background-color 0.4s ease, color 0.4s ease;
55
+ }
56
+ #download-link-drop-here.dragover {
57
+ border-color: #ada;
58
+ background-color: #efe;
59
+ color: #5cb85c;
60
+ }
61
+ #download-link-drop-here.error {
62
+ border-color: #ebccd1;
63
+ background-color: #fff5f5;
64
+ color: #ebccc1;
65
+ }
66
+ #download-link-drop-here .inner {
67
+ position: absolute;
68
+ display: table;
69
+ width: 100%;
70
+ height: 100%;
71
+ text-align: center;
72
+ font-size: 1.2em;
73
+ font-weight: bold;
74
+ }
75
+ #download-link-drop-here .inner > div {
76
+ display: table-cell;
77
+ vertical-align: middle;
78
+ }
79
+
80
+ -# Downloadダイアログの「ダウンロード」ボタンから処理を移譲されてくる
81
+ #download-link-submit.hidden
82
+
83
+ %textarea#download-input.form-control(rows="4" placeholder="小説のURLを入力(複数入力する場合は半角スペースか改行で区切る)")
84
+
85
+ #download-link-drop-area
86
+ #download-link-drop-here
87
+ .inner
88
+ %div ここにリンクかショートカットファイルをドラッグ
89
+ #download-link-drop-cover.drop-cover(effectAllowed="all")