paginator.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. 'use strict';
  2. const { htmlTag, url_for } = require('hexo-util');
  3. const createLink = (options, ctx) => {
  4. const { base, format } = options;
  5. return i => url_for.call(ctx, i === 1 ? base : base + format.replace('%d', i));
  6. };
  7. const createPageTag = (options, ctx) => {
  8. const link = createLink(options, ctx);
  9. const { current, escape, transform } = options;
  10. return i => {
  11. if (i === current) {
  12. return htmlTag('span', { class: 'page-number current' }, transform ? transform(i) : i, escape);
  13. }
  14. return htmlTag('a', { class: 'page-number', href: link(i) }, transform ? transform(i) : i, escape);
  15. };
  16. };
  17. const showAll = (tags, options, ctx) => {
  18. const { total } = options;
  19. const pageLink = createPageTag(options, ctx);
  20. for (let i = 1; i <= total; i++) {
  21. tags.push(pageLink(i));
  22. }
  23. };
  24. // It's too complicated. May need refactor.
  25. const pagenasionPartShow = (tags, options, ctx) => {
  26. const {
  27. current,
  28. total,
  29. space,
  30. end_size: endSize,
  31. mid_size: midSize
  32. } = options;
  33. const leftEnd = current <= endSize ? current - 1 : endSize;
  34. const rightEnd = total - current <= endSize ? current + 1 : total - endSize + 1;
  35. const leftMid = current - midSize <= endSize ? leftEnd + 1 : current - midSize;
  36. const rightMid = current + midSize + endSize > total ? rightEnd - 1 : current + midSize;
  37. const spaceHtml = htmlTag('span', { class: 'space' }, space, false);
  38. const pageTag = createPageTag(options, ctx);
  39. // Display pages on the left edge
  40. for (let i = 1; i <= leftEnd; i++) {
  41. tags.push(pageTag(i));
  42. }
  43. // Display spaces between edges and middle pages
  44. if (space && current - endSize - midSize > 1) {
  45. tags.push(spaceHtml);
  46. }
  47. // Display left middle pages
  48. if (leftMid > leftEnd) {
  49. for (let i = leftMid; i < current; i++) {
  50. tags.push(pageTag(i));
  51. }
  52. }
  53. // Display the current page
  54. tags.push(pageTag(current));
  55. // Display right middle pages
  56. if (rightMid < rightEnd) {
  57. for (let i = current + 1; i <= rightMid; i++) {
  58. tags.push(pageTag(i));
  59. }
  60. }
  61. // Display spaces between edges and middle pages
  62. if (space && total - endSize - midSize > current) {
  63. tags.push(spaceHtml);
  64. }
  65. // Display pages on the right edge
  66. for (let i = rightEnd; i <= total; i++) {
  67. tags.push(pageTag(i));
  68. }
  69. };
  70. function paginatorHelper(options = {}) {
  71. options = Object.assign({
  72. base: this.page.base || '',
  73. current: this.page.current || 0,
  74. format: `${this.config.pagination_dir}/%d/`,
  75. total: this.page.total || 1,
  76. end_size: 1,
  77. mid_size: 2,
  78. space: '&hellip;',
  79. next_text: 'Next',
  80. prev_text: 'Prev',
  81. prev_next: true,
  82. escape: true
  83. }, options);
  84. const {
  85. current,
  86. total,
  87. prev_text: prevText,
  88. next_text: nextText,
  89. prev_next: prevNext,
  90. escape
  91. } = options;
  92. if (!current) return '';
  93. const link = createLink(options, this);
  94. const tags = [];
  95. // Display the link to the previous page
  96. if (prevNext && current > 1) {
  97. tags.push(htmlTag('a', { class: 'extend prev', rel: 'prev', href: link(current - 1)}, prevText, escape));
  98. }
  99. if (options.show_all) {
  100. showAll(tags, options, this);
  101. } else {
  102. pagenasionPartShow(tags, options, this);
  103. }
  104. // Display the link to the next page
  105. if (prevNext && current < total) {
  106. tags.push(htmlTag('a', { class: 'extend next', rel: 'next', href: link(current + 1) }, nextText, escape));
  107. }
  108. return tags.join('');
  109. }
  110. module.exports = paginatorHelper;