RefsContext.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import * as url from 'url';
  2. import { customTagUtils, pathUtils } from 'growi-commons';
  3. const { TagContext, ArgsParser, OptionParser } = customTagUtils;
  4. /**
  5. * Context Object class for $refs() and $refsimg()
  6. */
  7. export default class RefsContext extends TagContext {
  8. /**
  9. * @param {object|TagContext|RefsContext} initArgs
  10. */
  11. constructor(initArgs, fromPagePath) {
  12. super(initArgs);
  13. this.fromPagePath = fromPagePath;
  14. // initialized after parse()
  15. this.pagePath = null;
  16. this.isParsed = null;
  17. this.options = {};
  18. }
  19. get isSingle() {
  20. return this.method.match(/^(ref|refimg)$/);
  21. }
  22. get isExtractImg() {
  23. return this.method.match(/^(refimg|refsimg)$/);
  24. }
  25. parse() {
  26. if (this.isParsed) {
  27. return;
  28. }
  29. const parsedArgs = ArgsParser.parse(this.args);
  30. this.options = parsedArgs.options;
  31. if (this.isSingle) {
  32. this.parseForSingle(parsedArgs);
  33. }
  34. else {
  35. this.parseForMulti(parsedArgs);
  36. }
  37. this.isParsed = true;
  38. }
  39. /**
  40. * parse method for 'ref' and 'refimg'
  41. */
  42. parseForSingle(parsedArgs) {
  43. // determine fileName
  44. // order:
  45. // 1: ref(file=..., ...)
  46. // 2: refs(firstArgs, ...)
  47. this.fileName = this.options.file
  48. || ((parsedArgs.firstArgsValue === true) ? parsedArgs.firstArgsKey : undefined);
  49. if (this.fileName == null) {
  50. throw new Error('fileName is not specified. set first argument or specify \'file\' option');
  51. }
  52. // determine pagePath
  53. // order:
  54. // 1: ref(page=..., ...)
  55. // 2: constructor argument
  56. const specifiedPath = this.options.page || this.fromPagePath;
  57. this.pagePath = this.getAbsolutePathFor(specifiedPath);
  58. }
  59. /**
  60. * parse method for 'refs' and 'refsimg'
  61. */
  62. parseForMulti(parsedArgs) {
  63. if (this.options.prefix) {
  64. this.prefix = this.resolvePath(this.options.prefix);
  65. }
  66. else {
  67. // determine pagePath
  68. // order:
  69. // 1: ref(page=..., ...)
  70. // 2: refs(firstArgs, ...)
  71. // 3: constructor argument
  72. const specifiedPath = this.options.page
  73. || ((parsedArgs.firstArgsValue === true) ? parsedArgs.firstArgsKey : undefined)
  74. || this.fromPagePath;
  75. this.pagePath = this.getAbsolutePathFor(specifiedPath);
  76. }
  77. }
  78. // resolve pagePath
  79. // when `fromPagePath`=/hoge and `specifiedPath`=./fuga,
  80. // `pagePath` to be /hoge/fuga
  81. // when `fromPagePath`=/hoge and `specifiedPath`=/fuga,
  82. // `pagePath` to be /fuga
  83. // when `fromPagePath`=/hoge and `specifiedPath`=undefined,
  84. // `pagePath` to be /hoge
  85. resolvePath(pagePath) {
  86. return decodeURIComponent(url.resolve(pathUtils.addTrailingSlash(this.fromPagePath), pagePath));
  87. }
  88. getOptDepth() {
  89. if (this.options.depth === undefined) {
  90. return undefined;
  91. }
  92. return OptionParser.parseRange(this.options.depth);
  93. }
  94. getOptColumnSize() {
  95. const { grid } = this.options;
  96. let columnSize = null;
  97. if (grid != null) {
  98. switch (grid) {
  99. case 'col-6':
  100. columnSize = 6;
  101. break;
  102. case 'col-4':
  103. columnSize = 4;
  104. break;
  105. case 'col-3':
  106. columnSize = 3;
  107. break;
  108. case 'col-2':
  109. columnSize = 2;
  110. break;
  111. case 'col-1':
  112. columnSize = 1;
  113. break;
  114. }
  115. }
  116. return columnSize;
  117. }
  118. /**
  119. * return absolute path for the specified path
  120. *
  121. * @param {string} relativePath relative path from `this.fromPagePath`
  122. */
  123. getAbsolutePathFor(relativePath) {
  124. return decodeURIComponent(
  125. pathUtils.normalizePath( // normalize like /foo/bar
  126. url.resolve(pathUtils.addTrailingSlash(this.fromPagePath), relativePath)
  127. ),
  128. );
  129. }
  130. }