ep_small_list 0.4.0 → 0.6.0

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.
Files changed (3) hide show
  1. package/README.md +46 -0
  2. package/index.js +127 -19
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -8,3 +8,49 @@ A small script for [etherpad-lite](https://github.com/ether/etherpad-lite) which
8
8
  npm install ep_small_list
9
9
  ```
10
10
  Restart your etherpad-lite instance to recognice new addon.
11
+
12
+ ## Compatibility
13
+ * Requires a minimum Node.js version of 7.10.1.
14
+
15
+ ## Configuration
16
+
17
+ The plugin works without configuration. But there are several configuration settings available. In your `settings.json`, add:
18
+
19
+ ### Limit number of entries
20
+
21
+ ```json
22
+ "ep_small_list": {
23
+ "limit": 10
24
+ }
25
+ ```
26
+
27
+ By default the number of entries is not limited ("limit": 0).
28
+
29
+ ### Sort by last change
30
+
31
+ ```json
32
+ "ep_small_list": {
33
+ "sortmode": "lastchange"
34
+ }
35
+ ```
36
+
37
+ The following sorting modes are available:
38
+ * "default": Use the order in which the API returns the pads (this is also the default sortmode).
39
+ * "lastchange": Sort the pads by last change.
40
+
41
+ ### Reverse order
42
+
43
+ ```json
44
+ "ep_small_list": {
45
+ "sortorder": "reverse"
46
+ }
47
+ ```
48
+
49
+ The following sorting orders are available:
50
+ * "normal": Use the normal order generated by the choosen sortmode.
51
+ * "reverse": Reverse the order generated by the choosen sortmode.
52
+
53
+
54
+ ## Features
55
+ * Supports [ep\_set\_title\_on\_pad](https://github.com/JohnMcLear/ep_set_title_on_pad)
56
+
package/index.js CHANGED
@@ -1,33 +1,141 @@
1
1
  var padManager = require('ep_etherpad-lite/node/db/PadManager');
2
- exports.eejsBlock_indexWrapper = function(hook_name, args, cb) {
3
- args.content += '<div id="small_list"></div><script src="./static/js/jquery.js"></script><script>$(function () { $("#small_list").load("./small_list"); });</script>';
2
+ var db = require('ep_etherpad-lite/node/db/DB').db;
3
+ var settings = require('ep_etherpad-lite/node/utils/Settings');
4
+
5
+ const sortmodes = {
6
+ DEFAULT: 'default',
7
+ LASTCHANGE: 'lastchange'
8
+ }
9
+
10
+ const sortorders = {
11
+ NORMAL: 'normal',
12
+ REVERSE: 'reverse'
13
+ }
14
+
15
+
16
+ var sortmode = sortmodes.DEFAULT;
17
+ var sortorder = sortorders.NORMAL;
18
+ var limit = 0;
19
+
20
+ if (settings.ep_small_list) {
21
+ if (settings.ep_small_list.sortmode) {
22
+ sortmode = settings.ep_small_list.sortmode.trim().toLowerCase() === sortmodes.LASTCHANGE ? sortmodes.LASTCHANGE : sortmodes.DEFAULT;
23
+ console.log("ep_small_list setting sortmode: " + sortmode);
24
+ }
25
+ if (settings.ep_small_list.sortorder) {
26
+ sortorder = settings.ep_small_list.sortorder.trim().toLowerCase() === sortorders.REVERSE ? sortorders.REVERSE : sortorders.NORMAL;
27
+ console.log("ep_small_list setting sortorder: " + sortorder);
28
+ }
29
+ if (settings.ep_small_list.limit) {
30
+ let settingsValue = parseInt(settings.ep_small_list.limit, 10);
31
+ if(Number.isNaN(settingsValue) || !Number.isFinite(settingsValue) || settingsValue < 0){
32
+ settingsValue = 0;
33
+ }
34
+ limit = settingsValue;
35
+ console.log("ep_small_list setting limit: " + limit);
36
+ }
37
+ }
38
+
39
+ exports.eejsBlock_indexWrapper = function(hook_name, args) {
40
+ args.content += `
41
+ <div id="small_list"></div>
42
+ <script>
43
+ document.addEventListener('DOMContentLoaded', async function() {
44
+ const container = document.getElementById('small_list');
45
+ if (!container) return;
46
+
47
+ try {
48
+ const response = await fetch('./small_list');
49
+ if (!response.ok) {
50
+ throw new Error('HTTP ' + response.status);
51
+ }
52
+ container.innerHTML = await response.text();
53
+ } catch (error) {
54
+ console.error('ep_small_list:', error);
55
+ }
56
+ });
57
+ </script>
58
+ `;
4
59
  };
5
60
 
6
61
  exports.registerRoute = function(hook_name, args, cb) {
7
- args.app.get("/small_list", function(req, res) {
8
- var pads = padManager.listAllPads(function(err, data){
9
- if(err){
10
- return res.send("<div> Error:" + err + "</div>");
11
- }
12
- return res.send(createList(data));
62
+ args.app.get("/small_list", function(req, res) {
63
+ padManager.listAllPads().then(function(pads) {
64
+ createList(pads).then(function(html){
65
+ res.send(html);
13
66
  });
14
- if(pads){
15
- pads.then(function(data){
16
- res.send(createList(data));
17
- }).catch(function(err){
18
- res.send("<div> Error:" + err + "</div>");
19
- })
20
- }
67
+ }).catch(function(err) {
68
+ res.send("<div> Error:" + err + "</div>");
21
69
  });
70
+ });
71
+ return cb();
22
72
  };
23
73
 
24
- function createList(data){
25
- r = "<ul>";
74
+ function escapeHtml(value) {
75
+ return String(value).replace(/[&<>"']/g, char => ({
76
+ '&': '&amp;',
77
+ '<': '&lt;',
78
+ '>': '&gt;',
79
+ '"': '&quot;',
80
+ "'": '&#39;'
81
+ })[char]);
82
+ }
83
+
84
+ async function createList(data){
85
+ let dataCache = [];
26
86
  if(data && data.padIDs){
27
87
  for (var i = 0; i < data.padIDs.length; i++) {
28
- r += '<li><a href="./p/' + data.padIDs[i] + '">' + data.padIDs[i] + '</li>';
88
+ let padData = {};
89
+ let padID = data.padIDs[i];
90
+ let title = padID;
91
+
92
+ const pad = await padManager.getPad(padID);
93
+ if (!pad) {
94
+ continue;
95
+ }
96
+ const lastEdit = await pad.getLastEdit();
97
+ padData.lastChange = lastEdit;
98
+
99
+ // support custom titles from ep_set_title_on_pad.
100
+ try {
101
+ const storedTitle = await db.get("title:" + padID);
102
+ if (storedTitle) {
103
+ title = storedTitle;
104
+ }
105
+ } catch (err) {
106
+ console.error("ep_small_list: Could not read title for pad", padID, err);
107
+ }
108
+
109
+ padData.html = '<li><a href="./p/' +
110
+ encodeURIComponent(padID) + '">' +
111
+ escapeHtml(title) + '</a></li>';
112
+ padData.createIndex = i;
113
+
114
+ dataCache.push(padData);
29
115
  }
30
116
  }
117
+
118
+ dataCache.sort(function (a, b) {
119
+ let indicator = 0;
120
+ if(sortmode === sortmodes.DEFAULT) {
121
+ indicator = a.createIndex - b.createIndex;
122
+ } else {
123
+ // sortmodes.LASTCHANGE
124
+ indicator = a.lastChange - b.lastChange;
125
+ }
126
+ return indicator;
127
+ });
128
+
129
+ if(sortorder === sortorders.REVERSE) {
130
+ dataCache.reverse();
131
+ }
132
+
133
+ if(limit > 0 && dataCache.length > limit) {
134
+ dataCache.length = limit;
135
+ }
136
+
137
+ let r = "<ul>";
138
+ r += dataCache.map(x => x.html).join("");
31
139
  r += "</ul>";
32
140
  return r;
33
- }
141
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ep_small_list",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Adds a list of all pads on the index-page",
5
5
  "main": "index.js",
6
6
  "scripts": {