[Confluence]配下ページの添付ファイルを階層構造で一覧表示する方法

#はじめに
以下issueのコメントより
[[CONFSERVER-11968] Option to see an attachment list for child pages - Create and track feature requests for Atlassian products.](https://jira.atlassian.com/browse/CONFSERVER-11968)

>Bill Arconati added a comment - 16/Jun/2014 7:17 AM
>
Thank you for raising this issue. While we can see how this feature would be useful, we have no plans to implement it in the foreseeable future. In order to set expectations, we're closing this request now.
>
Thanks again for your idea.
>
Bill Arconati,
>Confluence Group Product Manager

意訳：良いアイデアだね！でもこの先実装するつもり無いからクローズするね！

まじかよ。
しかも、どうやら、みんな困っている。
[Solved: Is there an attachment list macro that can show all attachments for child pages? - atlassian community](https://community.atlassian.com/t5/Questions/Is-there-an-attachment-list-macro-that-can-show-all-attachments/qaq-p/423276)
[Confluence - Get all attachments under a parent page - atlassian community](https://community.atlassian.com/t5/Confluence-questions/Confluence-Get-all-attachments-under-a-parent-page/qaq-p/227367)

なので、作った。

#作ったもの
以下のように表示してくれるJavascriptを作りました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214587/7a7e4461-30ef-db3f-f72b-31d83b980fe2.png)

[P]は、ページ。該当ページに遷移できます。
[A]は、添付ファイル。Previewが見れないファイルタイプ（.jsファイルなど）もありますが、一律でpreviewリンクを表示しています。
（良い方法が思いつかず、previewリンクの表示するかどうかの制御は諦めました。）

#前提
バージョン: Server 6.1.4

#使い方
1. htmlマクロ[^1]に以下コードを書く
2. コード中の`http://hostname`の部分を書き換える
3. おしまい！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214587/3ff1527f-2c55-3f34-07d7-e361b813be39.png)

[^1]: htmlマクロは設定を変更して有効化する必要があります。設定方法は[こちら](https://ja.confluence.atlassian.com/doc/html-macro-38273085.html)。

```html
<div id="descendants-attachments-list" data-url="this"></div>
<script type="text/javascript">
var baseURL = 'http://hostname';
//OK: var baseURL = 'http://hostname';
//NG: var baseURL = 'http://hostname/';

var apiPreURL = '/rest/api/content/';
var apiPostURL_attach = '/child/attachment?limit=100';
var apiPostURL_page = '/child/page?limit=100';
var $target = $('#descendants-attachments-list');
var root = ( $target.attr('data-url') == 'this' ) ? $('meta[name=ajs-page-id]').attr('content') : $target.attr('data-url');

function attachmentsList(contentId, $t){
	$t.append('<ul name="' + contentId +  '"></ul>');
	var $tul = $t.find('ul[name='  + contentId +   ']');
	$.when(
		$.getJSON(baseURL + apiPreURL + contentId +apiPostURL_attach , function(data) {
				for(let r in data.results) {
					$tul.append('<li>[A]' + 
						'<a href="' + baseURL + data.results[r]._links.download.toString() + '" download>DL</a> / ' + 
						'<a href="' + baseURL + data.results[r]._links.webui.toString() + '">Preview</a> : ' + 
						data.results[r].title.toString() + '</li>');
				}
	    })
	).done(function() {
		$.getJSON(baseURL + apiPreURL + contentId +apiPostURL_page , function(data) {
				for(let r in data.results) {
					$tul.append('<li name="' + data.results[r].id + '">[P]' + 
						'<a href="' + baseURL + data.results[r]._links.tinyui.toString() + ' ">' + 
						data.results[r].title.toString() + '</a></li>');
					attachmentsList(data.results[r].id, $tul);
				}
		});
	});
};

attachmentsList(root, $target);

</script>
```
もっと良い書き方があれば教えて下さい。。。

#注意事項
(2017/11/30追記　開始)

- 必要に応じてlimit指定を変更してください。
- divタグの `data-url` 属性に、任意のページIDを指定すると、そのページ配下の一覧になります。


(2017/11/30追記　終了)


#最後に
普段Javascript書かない人なので、非同期処理の順序制御にめっちゃ苦労しました。。。
Deferredとやらも、結局理解が追いつかなかったので、勉強せねば。。。

以上

---