nodebb-theme-persona 15.0.0-beta.2 → 15.0.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.
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const accountHelpers = require.main.require('./src/controllers/accounts/helpers');
4
- const helpers = require.main.require('./src/controllers/helpers');
3
+ const accountHelpers = nodebb.require('./src/controllers/accounts/helpers');
4
+ const helpers = nodebb.require('./src/controllers/helpers');
5
5
 
6
6
  const Controllers = module.exports;
7
7
 
package/library.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const meta = require.main.require('./src/meta');
3
+ const meta = nodebb.require('./src/meta');
4
4
 
5
5
  const controllers = require('./lib/controllers');
6
6
 
@@ -8,7 +8,7 @@ const library = module.exports;
8
8
 
9
9
  library.init = async function (params) {
10
10
  const { router, middleware } = params;
11
- const routeHelpers = require.main.require('./src/routes/helpers');
11
+ const routeHelpers = nodebb.require('./src/routes/helpers');
12
12
  routeHelpers.setupAdminPageRoute(router, '/admin/plugins/persona', [], controllers.renderAdminPage);
13
13
 
14
14
  routeHelpers.setupPageRoute(router, '/user/:userslug/theme', [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-theme-persona",
3
- "version": "15.0.0-beta.2",
3
+ "version": "15.0.0",
4
4
  "nbbpm": {
5
5
  "compatibility": "^4.14.0"
6
6
  },
@@ -45,8 +45,7 @@
45
45
  "pulling": "^2.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "eslint": "9.25.1",
49
- "eslint-config-nodebb": "^1.1.4",
50
- "eslint-plugin-import": "^2.31.0"
48
+ "eslint": "10.5.0",
49
+ "eslint-config-nodebb": "^2.0.3"
51
50
  }
52
51
  }
package/public/admin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  define('admin/plugins/persona', ['settings'], function (Settings) {
4
- var ACP = {};
4
+ const ACP = {};
5
5
 
6
6
  ACP.init = function () {
7
7
  Settings.load('persona', $('.persona-settings'));
package/public/persona.js CHANGED
@@ -23,7 +23,7 @@ $(document).ready(function () {
23
23
  document.documentElement.style.setProperty('--panel-offset', `${offset}px`);
24
24
  }
25
25
 
26
- var lastBSEnv = '';
26
+ let lastBSEnv = '';
27
27
  function configureNavbarHiding() {
28
28
  if (!$.fn.autoHidingNavbar) {
29
29
  return;
@@ -37,13 +37,13 @@ $(document).ready(function () {
37
37
  } catch (e) {
38
38
  console.warn('[persona/settings] Unable to parse value for navbar autohiding');
39
39
  }
40
- var env = utils.findBootstrapEnvironment();
40
+ const env = utils.findBootstrapEnvironment();
41
41
  // if env didn't change don't destroy and recreate
42
42
  if (env === lastBSEnv) {
43
43
  return;
44
44
  }
45
45
  lastBSEnv = env;
46
- var navbarEl = $('[component="navbar"]');
46
+ const navbarEl = $('[component="navbar"]');
47
47
  navbarEl.autoHidingNavbar('destroy').removeData('plugin_autoHidingNavbar');
48
48
  navbarEl.css('top', '');
49
49
 
@@ -69,7 +69,7 @@ $(document).ready(function () {
69
69
  if (ajaxify.data.template.topic) {
70
70
  $('.topic .topic-header').css({ top: topValue });
71
71
  } else {
72
- var topicListHeader = $('.topic-list-header');
72
+ const topicListHeader = $('.topic-list-header');
73
73
  if (topicListHeader.length) {
74
74
  topicListHeader.css({ top: topValue });
75
75
  }
@@ -119,24 +119,22 @@ $(document).ready(function () {
119
119
  function setupEditedByIcon() {
120
120
  function activateEditedTooltips() {
121
121
  $('[data-pid] [component="post/editor"]').each(function () {
122
- var el = $(this);
123
- var icon;
124
-
122
+ const el = $(this);
125
123
  if (!el.attr('data-editor')) {
126
124
  return;
127
125
  }
128
126
 
129
- icon = el.closest('[data-pid]').find('.edit-icon').first();
127
+ const icon = el.closest('[data-pid]').find('.edit-icon').first();
130
128
  icon.prop('title', el.text()).tooltip().removeClass('hidden');
131
129
  });
132
130
  }
133
131
 
134
132
  $(window).on('action:posts.edited', function (ev, data) {
135
- var parent = $('[data-pid="' + data.post.pid + '"]');
136
- var icon = parent.find('.edit-icon').filter(function (index, el) {
133
+ const parent = $('[data-pid="' + data.post.pid + '"]');
134
+ const icon = parent.find('.edit-icon').filter(function (index, el) {
137
135
  return parseInt($(el).closest('[data-pid]').attr('data-pid'), 10) === parseInt(data.post.pid, 10);
138
136
  });
139
- var el = parent.find('[component="post/editor"]').first();
137
+ const el = parent.find('[component="post/editor"]').first();
140
138
  icon.prop('title', el.text()).tooltip().removeClass('hidden');
141
139
  });
142
140
 
@@ -157,15 +155,15 @@ $(document).ready(function () {
157
155
  });
158
156
 
159
157
  $(window).on('action:posts.loading', function (ev, data) {
160
- for (var i = 0, ii = data.posts.length; i < ii; i++) {
158
+ for (let i = 0, ii = data.posts.length; i < ii; i++) {
161
159
  (ajaxify.data.topics || ajaxify.data.posts)[data.posts[i].index] = data.posts[i];
162
160
  }
163
161
  });
164
162
  }
165
163
 
166
164
  function generateUserCard(ev) {
167
- var avatar = $(this);
168
- var uid = avatar.parents('[data-uid]').attr('data-uid');
165
+ const avatar = $(this);
166
+ const uid = avatar.parents('[data-uid]').attr('data-uid');
169
167
  const topicOrPost = (ajaxify.data.topics || ajaxify.data.posts || []).find(d => String(d.uid) === String(uid));
170
168
  if (!topicOrPost) return;
171
169
  const user = topicOrPost.user;
@@ -182,7 +180,7 @@ $(document).ready(function () {
182
180
  }
183
181
 
184
182
  app.parseAndTranslate('modules/usercard', user, function (html) {
185
- var card = $(html);
183
+ const card = $(html);
186
184
  avatar.parents('a').after(card.hide());
187
185
 
188
186
  if (String(app.user.uid) === String(user.uid) || !app.user.uid) {
@@ -229,8 +227,8 @@ $(document).ready(function () {
229
227
  function setupFavouriteMorph(parent, uid, username) {
230
228
  require(['api', 'alerts'], function (api, alerts) {
231
229
  parent.find('.btn-morph').click(function (ev) {
232
- var type = $(this).hasClass('plus') ? 'follow' : 'unfollow';
233
- var method = $(this).hasClass('plus') ? 'put' : 'del';
230
+ const type = $(this).hasClass('plus') ? 'follow' : 'unfollow';
231
+ const method = $(this).hasClass('plus') ? 'put' : 'del';
234
232
 
235
233
  api[method]('/users/' + uid + '/follow').then(() => {
236
234
  alerts.success('[[global:alert.' + type + ', ' + username + ']]');
@@ -243,9 +241,9 @@ $(document).ready(function () {
243
241
  $(this).prepend('<b class="drop"></b>');
244
242
  }
245
243
 
246
- var drop = $(this).find('b.drop').removeClass('animate');
247
- var x = ev.pageX - (drop.width() / 2) - $(this).offset().left;
248
- var y = ev.pageY - (drop.height() / 2) - $(this).offset().top;
244
+ const drop = $(this).find('b.drop').removeClass('animate');
245
+ const x = ev.pageX - (drop.width() / 2) - $(this).offset().left;
246
+ const y = ev.pageY - (drop.height() / 2) - $(this).offset().top;
249
247
 
250
248
  drop.css({ top: y + 'px', left: x + 'px' }).addClass('animate');
251
249
  });
@@ -151,7 +151,7 @@
151
151
  {{{ end }}}
152
152
  </div>
153
153
  <p class="mb-1">
154
- <span class="reason">[[user:info.banned-reason-label]]: <strong>{./reason}</strong></span>
154
+ <span class="reason">[[user:info.banned-reason-label]]: <strong>{tx(./reason)}</strong></span>
155
155
  </p>
156
156
  <p>
157
157
  {{{ if ./until }}}
@@ -205,7 +205,7 @@
205
205
  {{{ end }}}
206
206
  </div>
207
207
  <p class="mb-1">
208
- <span class="reason">[[user:info.banned-reason-label]]: <strong>{./reason}</strong></span>
208
+ <span class="reason">[[user:info.banned-reason-label]]: <strong>{tx(./reason)}</strong></span>
209
209
  </p>
210
210
  <p>
211
211
  {{{ if ./until }}}
@@ -21,7 +21,7 @@
21
21
  </div>
22
22
 
23
23
  <!-- IF !posts.length -->
24
- <div class="alert alert-warning text-center">{noItemsFoundKey}</div>
24
+ <div class="alert alert-warning text-center">{tx(noItemsFoundKey)}</div>
25
25
  <!-- ENDIF !posts.length -->
26
26
 
27
27
  <div class="col-12">
@@ -32,7 +32,7 @@
32
32
 
33
33
 
34
34
  {{{ if !topics.length }}}
35
- <div class="alert alert-warning text-center">{noItemsFoundKey}</div>
35
+ <div class="alert alert-warning text-center">{tx(noItemsFoundKey)}</div>
36
36
  {{{ end }}}
37
37
 
38
38
  <div class="category">
@@ -8,7 +8,7 @@
8
8
  </div>
9
9
  <div class="post-content text-xs text-break line-clamp-sm-2 lh-sm position-relative flex-fill">
10
10
  <a class="stretched-link" tabindex="-1" href="{config.relative_path}/topic/{./topic.slug}{{{ if ./index }}}/{./index}{{{ end }}}" aria-label="[[global:lastpost]]"></a>
11
- {{./content}}
11
+ {{txEscape(./content)}}
12
12
  </div>
13
13
  </div>
14
14
  {{{ end }}}
@@ -1,3 +1,3 @@
1
1
  {{{ each tags }}}
2
- <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="tag tag-item fw-bold tag-class-{./class}" data-tag="{./value}">{./valueEscaped}</span></a>
2
+ <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="tag tag-item fw-bold tag-class-{./class}" data-tag="{./value}">{./value}</span></a>
3
3
  {{{ end }}}
@@ -5,7 +5,7 @@
5
5
  </a>
6
6
 
7
7
  <div component="post/content" class="content mb-3">
8
- {{../content}}
8
+ {{txEscape(../content)}}
9
9
  </div>
10
10
 
11
11
  <div class="mb-3">
@@ -15,7 +15,7 @@
15
15
  {{{ if ../topic.tags.length }}}
16
16
  <span class="tag-list">
17
17
  {{{ each ../topic.tags }}}
18
- <a href="{config.relative_path}/tags/{topic.tags.valueEncoded}"><span class="tag tag-item tag-class-{topic.tags.class}">{topic.tags.valueEscaped}</span></a>
18
+ <a href="{config.relative_path}/tags/{topic.tags.valueEncoded}"><span class="tag tag-item tag-class-{topic.tags.class}">{topic.tags.value}</span></a>
19
19
  {{{ end }}}
20
20
  </span>
21
21
  {{{ end }}}
@@ -3,7 +3,7 @@
3
3
  <div class="post-search-item">
4
4
  <div component="category/filter" class="dropdown" data-filter-name="category">
5
5
  <a component="category/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.categories.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
6
- <span class="filter-label">{{{ if filters.categories.active }}}{filters.categories.label}{{{ else }}}[[search:categories]]{{{ end }}}</span>
6
+ <span class="filter-label">{{{ if filters.categories.active }}}{tx(filters.categories.label)}{{{ else }}}[[search:categories]]{{{ end }}}</span>
7
7
  <span class="caret text-primary opacity-75"></span>
8
8
  </a>
9
9
 
@@ -29,7 +29,7 @@
29
29
  <div class="post-search-item">
30
30
  <div component="tag/filter" class="dropdown" data-filter-name="tag">
31
31
  <a component="tag/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.tags.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
32
- <span class="filter-label">{{{ if filters.tags.active }}}{filters.tags.label}{{{ else }}}[[search:tags]]{{{ end }}}</span>
32
+ <span class="filter-label">{{{ if filters.tags.active }}}{tx(filters.tags.label)}{{{ else }}}[[search:tags]]{{{ end }}}</span>
33
33
  <span class="caret text-primary opacity-75"></span>
34
34
  </a>
35
35
 
@@ -39,15 +39,15 @@
39
39
  <div component="tag/filter/selected" class="d-flex flex-wrap gap-2">
40
40
  {{{ each tagFilterSelected }}}
41
41
  <div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
42
- <div>{./valueEscaped}</div>
43
- <button component="tag/filter/delete" data-tag="{./valueEscaped}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
42
+ <div>{./value}</div>
43
+ <button component="tag/filter/delete" data-tag="{./value}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
44
44
  </div>
45
45
  {{{ end }}}
46
46
  </div>
47
47
  <hr class="my-2"/>
48
48
  <div component="tag/filter/results" class="d-flex flex-wrap gap-2">
49
49
  {{{ each tagFilterResults }}}
50
- <button class="btn btn-light btn-sm border" data-tag="{./valueEscaped}">{./valueEscaped}</button>
50
+ <button class="btn btn-light btn-sm border" data-tag="{./value}">{./value}</button>
51
51
  {{{ end }}}
52
52
  </div>
53
53
  </li>
@@ -59,7 +59,7 @@
59
59
  <div class="post-search-item">
60
60
  <div component="user/filter" class="dropdown" data-filter-name="user">
61
61
  <a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.users.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
62
- <span class="filter-label">{{{ if filters.users.active }}}{filters.users.label}{{{ else }}}[[search:posted-by]]{{{ end }}}</span>
62
+ <span class="filter-label">{{{ if filters.users.active }}}{tx(filters.users.label)}{{{ else }}}[[search:posted-by]]{{{ end }}}</span>
63
63
  <span class="caret text-primary opacity-75"></span>
64
64
  </a>
65
65
 
@@ -90,7 +90,7 @@
90
90
  <div class="post-search-item">
91
91
  <div class="dropdown" data-filter-name="replies">
92
92
  <a id="reply-count-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.replies.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
93
- <span class="filter-label">{{{ if filters.replies.active }}}{filters.replies.label}{{{ else }}}[[search:replies]]{{{ end }}}</span>
93
+ <span class="filter-label">{{{ if filters.replies.active }}}{tx(filters.replies.label)}{{{ else }}}[[search:replies]]{{{ end }}}</span>
94
94
  <span class="caret text-primary opacity-75"></span>
95
95
  </a>
96
96
 
@@ -110,7 +110,7 @@
110
110
  <div class="post-search-item">
111
111
  <div class="dropdown" data-filter-name="time">
112
112
  <a id="post-time-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.time.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
113
- <span class="filter-label">{{{ if filters.time.active }}}{filters.time.label}{{{ else }}}[[search:time]]{{{ end }}}</span>
113
+ <span class="filter-label">{{{ if filters.time.active }}}{tx(filters.time.label)}{{{ else }}}[[search:time]]{{{ end }}}</span>
114
114
  <span class="caret text-primary opacity-75"></span>
115
115
  </a>
116
116
 
@@ -139,7 +139,7 @@
139
139
  <div class="post-search-item">
140
140
  <div class="dropdown" data-filter-name="sort">
141
141
  <a id="sort-by-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.sort.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
142
- <span class="filter-label">{{{ if filters.sort.active }}}{filters.sort.label}{{{ else }}}[[search:sort]]{{{ end }}}</span>
142
+ <span class="filter-label">{{{ if filters.sort.active }}}{tx(filters.sort.label)}{{{ else }}}[[search:sort]]{{{ end }}}</span>
143
143
  <span class="caret text-primary opacity-75"></span>
144
144
  </a>
145
145
 
@@ -0,0 +1,4 @@
1
+ <span class="badge border {./classes}">
2
+ {{{ if ./icon }}}<i class="fa {./icon}"></i>{{{ end }}}
3
+ {{{ if ./label }}}<span> {tx(./label)}</span>{{{ end }}}
4
+ </span>
@@ -92,7 +92,7 @@
92
92
  {{{ end }}}
93
93
  </span>
94
94
 
95
- <span class="replies-count small" component="post/reply-count/text" data-replies="{posts.replies.count}">{posts.replies.text}</span>
95
+ <span class="replies-count small" component="post/reply-count/text" data-replies="{posts.replies.count}">{tx(posts.replies.text)}</span>
96
96
  <span class="replies-last hidden-xs small">[[topic:last-reply-time]] <span class="timeago" title="{posts.replies.timestampISO}"></span></span>
97
97
 
98
98
  <i class="fa fa-fw fa-chevron-down" component="post/replies/open"></i>
@@ -1 +1 @@
1
- <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="badge border border-gray-300 fw-normal tag tag-class-{./class}" data-tag="{./value}">{./valueEscaped}</span></a>
1
+ <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="badge border border-gray-300 fw-normal tag tag-class-{./class}" data-tag="{./value}">{./value}</span></a>
@@ -48,7 +48,7 @@
48
48
  <i class="fa fa-arrow-circle-right"></i>
49
49
  <span>[[topic:moved]]</span>
50
50
  </span>
51
- {{{each ./icons}}}<span class="lh-1">{@value}</span>{{{end}}}
51
+ {{{ each ./icons }}}<!-- IMPORT partials/topic/icon.tpl -->{{{ end }}}
52
52
 
53
53
  {{{ if (!template.category || (cid != ./cid)) }}}
54
54
  {{buildCategoryLabel(./category, "a", "border")}}
@@ -56,7 +56,7 @@
56
56
 
57
57
  <span data-tid="{./tid}" component="topic/tags" class="lh-1 tag-list d-flex flex-wrap gap-1 {{{ if !./tags.length }}}hidden{{{ end }}}">
58
58
  {{{ each ./tags }}}
59
- <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="badge border border-gray-300 fw-normal tag tag-class-{./class}" data-tag="{./value}">{./valueEscaped}</span></a>
59
+ <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="badge border border-gray-300 fw-normal tag tag-class-{./class}" data-tag="{./value}">{./value}</span></a>
60
60
  {{{ end }}}
61
61
  </span>
62
62
 
@@ -119,7 +119,7 @@
119
119
  </div>
120
120
  <div class="post-content text-xs ps-2 line-clamp-sm-2 lh-sm text-break position-relative flex-fill">
121
121
  <a class="stretched-link" tabindex="-1" href="{config.relative_path}/topic/{./slug}/{./teaser.index}" aria-label="[[global:lastpost]]"></a>
122
- {{./teaser.content}}
122
+ {{txEscape(./teaser.content)}}
123
123
  </div>
124
124
  {{{ end }}}
125
125
  {{{ end }}}
@@ -30,7 +30,7 @@
30
30
  <a component="topic/moved" href="{config.relative_path}/category/{oldCid}" class="badge badge border border-gray-300 text-body text-decoration-none {{{ if !oldCid }}}hidden{{{ end }}}">
31
31
  <i class="fa fa-arrow-circle-right"></i> {{{ if privileges.isAdminOrMod }}}[[topic:moved-from, {oldCategory.name}]]{{{ else }}}[[topic:moved]]{{{ end }}}
32
32
  </a>
33
- {{{each icons}}}<span class="lh-1">{@value}</span>{{{end}}}
33
+ {{{ each ./icons }}}<!-- IMPORT partials/topic/icon.tpl -->{{{ end }}}
34
34
  </span>
35
35
  {{buildCategoryLabel(category, "a", "border")}}
36
36
  <div data-tid="{./tid}" component="topic/tags" class="lh-1 tags tag-list d-flex flex-wrap hidden-xs hidden-empty gap-2"><!-- IMPORT partials/topic/tags.tpl --></div>