worker.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* globals marked, unfetch, ES6Promise, Promise */ // eslint-disable-line no-redeclare
  2. if (!self.Promise) {
  3. self.importScripts('https://cdn.jsdelivr.net/npm/es6-promise/dist/es6-promise.js');
  4. self.Promise = ES6Promise;
  5. }
  6. if (!self.fetch) {
  7. self.importScripts('https://cdn.jsdelivr.net/npm/unfetch/dist/unfetch.umd.js');
  8. self.fetch = unfetch;
  9. }
  10. var versionCache = {};
  11. var currentVersion;
  12. onunhandledrejection = function(e) {
  13. throw e.reason;
  14. };
  15. onmessage = function(e) {
  16. if (e.data.version === currentVersion) {
  17. parse(e);
  18. } else {
  19. loadVersion(e.data.version).then(function() {
  20. parse(e);
  21. });
  22. }
  23. };
  24. function getDefaults() {
  25. var defaults = {};
  26. if (typeof marked.getDefaults === 'function') {
  27. defaults = marked.getDefaults();
  28. delete defaults.renderer;
  29. } else if ('defaults' in marked) {
  30. for (var prop in marked.defaults) {
  31. if (prop !== 'renderer') {
  32. defaults[prop] = marked.defaults[prop];
  33. }
  34. }
  35. }
  36. return defaults;
  37. }
  38. function mergeOptions(options) {
  39. var defaults = getDefaults();
  40. var opts = {};
  41. var invalidOptions = [
  42. 'renderer',
  43. 'tokenizer',
  44. 'walkTokens',
  45. 'extensions',
  46. 'highlight',
  47. 'sanitizer'
  48. ];
  49. for (var prop in defaults) {
  50. opts[prop] = invalidOptions.includes(prop) || !(prop in options)
  51. ? defaults[prop]
  52. : options[prop];
  53. }
  54. return opts;
  55. }
  56. function parse(e) {
  57. switch (e.data.task) {
  58. case 'defaults':
  59. postMessage({
  60. id: e.data.id,
  61. task: e.data.task,
  62. defaults: getDefaults()
  63. });
  64. break;
  65. case 'parse':
  66. var options = mergeOptions(e.data.options);
  67. var startTime = new Date();
  68. var lexed = marked.lexer(e.data.markdown, options);
  69. var lexedList = jsonString(lexed);
  70. var parsed = marked.parser(lexed, options);
  71. var endTime = new Date();
  72. postMessage({
  73. id: e.data.id,
  74. task: e.data.task,
  75. lexed: lexedList,
  76. parsed: parsed,
  77. time: endTime - startTime
  78. });
  79. break;
  80. }
  81. }
  82. function jsonString(input, level) {
  83. level = level || 0;
  84. if (Array.isArray(input)) {
  85. if (input.length === 0) {
  86. return '[]';
  87. }
  88. var items = [],
  89. i;
  90. if (!Array.isArray(input[0]) && typeof input[0] === 'object' && input[0] !== null) {
  91. for (i = 0; i < input.length; i++) {
  92. items.push(' '.repeat(2 * level) + jsonString(input[i], level + 1));
  93. }
  94. return '[\n' + items.join('\n') + '\n]';
  95. }
  96. for (i = 0; i < input.length; i++) {
  97. items.push(jsonString(input[i], level));
  98. }
  99. return '[' + items.join(', ') + ']';
  100. } else if (typeof input === 'object' && input !== null) {
  101. var props = [];
  102. for (var prop in input) {
  103. props.push(prop + ':' + jsonString(input[prop], level));
  104. }
  105. return '{' + props.join(', ') + '}';
  106. } else {
  107. return JSON.stringify(input);
  108. }
  109. }
  110. function loadVersion(ver) {
  111. var promise;
  112. if (versionCache[ver]) {
  113. promise = Promise.resolve(versionCache[ver]);
  114. } else {
  115. promise = fetch(ver)
  116. .then(function(res) { return res.text(); })
  117. .then(function(text) {
  118. versionCache[ver] = text;
  119. return text;
  120. });
  121. }
  122. return promise.then(function(text) {
  123. try {
  124. // eslint-disable-next-line no-new-func
  125. Function(text)();
  126. } catch (err) {
  127. throw new Error('Cannot load that version of marked');
  128. }
  129. currentVersion = ver;
  130. });
  131. }