/modules/blogging/app/Volo.BloggingTestApp/wwwroot/libs/prismjs/plugins/jsonp-highlight/prism-jsonp-highlight.js

https://github.com/abpframework/abp · JavaScript · 206 lines · 142 code · 21 blank · 43 comment · 52 complexity · 00748da1a5246848fe2ea51203a7e8bb MD5 · raw file

  1. (function () {
  2. if (!self.Prism || !self.document || !document.querySelectorAll || ![].filter) return;
  3. /**
  4. * @callback Adapter
  5. * @param {any} response
  6. * @param {HTMLPreElement} [pre]
  7. * @returns {string}
  8. */
  9. /**
  10. * The list of adapter which will be used if `data-adapter` is not specified.
  11. *
  12. * @type {Array.<{adapter: Adapter, name: string}>}
  13. */
  14. var adapters = [];
  15. /**
  16. * Adds a new function to the list of adapters.
  17. *
  18. * If the given adapter is already registered or not a function or there is an adapter with the given name already,
  19. * nothing will happen.
  20. *
  21. * @param {Adapter} adapter The adapter to be registered.
  22. * @param {string} [name] The name of the adapter. Defaults to the function name of `adapter`.
  23. */
  24. function registerAdapter(adapter, name) {
  25. name = name || adapter.name;
  26. if (typeof adapter === "function" && !getAdapter(adapter) && !getAdapter(name)) {
  27. adapters.push({ adapter: adapter, name: name });
  28. }
  29. }
  30. /**
  31. * Returns the given adapter itself, if registered, or a registered adapter with the given name.
  32. *
  33. * If no fitting adapter is registered, `null` will be returned.
  34. *
  35. * @param {string|Function} adapter The adapter itself or the name of an adapter.
  36. * @returns {Adapter} A registered adapter or `null`.
  37. */
  38. function getAdapter(adapter) {
  39. if (typeof adapter === "function") {
  40. for (var i = 0, item; item = adapters[i++];) {
  41. if (item.adapter.valueOf() === adapter.valueOf()) {
  42. return item.adapter;
  43. }
  44. }
  45. }
  46. else if (typeof adapter === "string") {
  47. for (var i = 0, item; item = adapters[i++];) {
  48. if (item.name === adapter) {
  49. return item.adapter;
  50. }
  51. }
  52. }
  53. return null;
  54. }
  55. /**
  56. * Remove the given adapter or the first registered adapter with the given name from the list of
  57. * registered adapters.
  58. *
  59. * @param {string|Function} adapter The adapter itself or the name of an adapter.
  60. */
  61. function removeAdapter(adapter) {
  62. if (typeof adapter === "string") {
  63. adapter = getAdapter(adapter);
  64. }
  65. if (typeof adapter === "function") {
  66. var index = adapters.map(function (item) { return item.adapter; }).indexOf(adapter);
  67. if (index >= 0) {
  68. adapters.splice(index, 1);
  69. }
  70. }
  71. }
  72. registerAdapter(function github(rsp, el) {
  73. if (rsp && rsp.meta && rsp.data) {
  74. if (rsp.meta.status && rsp.meta.status >= 400) {
  75. return "Error: " + (rsp.data.message || rsp.meta.status);
  76. }
  77. else if (typeof (rsp.data.content) === "string") {
  78. return typeof (atob) === "function"
  79. ? atob(rsp.data.content.replace(/\s/g, ""))
  80. : "Your browser cannot decode base64";
  81. }
  82. }
  83. return null;
  84. }, 'github');
  85. registerAdapter(function gist(rsp, el) {
  86. if (rsp && rsp.meta && rsp.data && rsp.data.files) {
  87. if (rsp.meta.status && rsp.meta.status >= 400) {
  88. return "Error: " + (rsp.data.message || rsp.meta.status);
  89. }
  90. var files = rsp.data.files;
  91. var filename = el.getAttribute("data-filename");
  92. if (filename == null) {
  93. // Maybe in the future we can somehow render all files
  94. // But the standard <script> include for gists does that nicely already,
  95. // so that might be getting beyond the scope of this plugin
  96. for (var key in files) {
  97. if (files.hasOwnProperty(key)) {
  98. filename = key;
  99. break;
  100. }
  101. }
  102. }
  103. if (files[filename] !== undefined) {
  104. return files[filename].content;
  105. }
  106. return "Error: unknown or missing gist file " + filename;
  107. }
  108. return null;
  109. }, 'gist');
  110. registerAdapter(function bitbucket(rsp, el) {
  111. if (rsp && rsp.node && typeof (rsp.data) === "string") {
  112. return rsp.data;
  113. }
  114. return null;
  115. }, 'bitbucket');
  116. var jsonpcb = 0,
  117. loadMsg = "Loading\u2026";
  118. /**
  119. * Highlights all `pre` elements with an `data-jsonp` by requesting the specified JSON and using the specified adapter
  120. * or a registered adapter to extract the code to highlight from the response. The highlighted code will be inserted
  121. * into the `pre` element.
  122. */
  123. function highlight() {
  124. Array.prototype.slice.call(document.querySelectorAll("pre[data-jsonp]")).forEach(function (pre) {
  125. pre.textContent = "";
  126. var code = document.createElement("code");
  127. code.textContent = loadMsg;
  128. pre.appendChild(code);
  129. var adapterName = pre.getAttribute("data-adapter");
  130. var adapter = null;
  131. if (adapterName) {
  132. if (typeof window[adapterName] === "function") {
  133. adapter = window[adapterName];
  134. }
  135. else {
  136. code.textContent = "JSONP adapter function '" + adapterName + "' doesn't exist";
  137. return;
  138. }
  139. }
  140. var cb = "prismjsonp" + jsonpcb++;
  141. var uri = document.createElement("a");
  142. var src = uri.href = pre.getAttribute("data-jsonp");
  143. uri.href += (uri.search ? "&" : "?") + (pre.getAttribute("data-callback") || "callback") + "=" + cb;
  144. var timeout = setTimeout(function () {
  145. // we could clean up window[cb], but if the request finally succeeds, keeping it around is a good thing
  146. if (code.textContent === loadMsg) {
  147. code.textContent = "Timeout loading '" + src + "'";
  148. }
  149. }, 5000);
  150. var script = document.createElement("script");
  151. script.src = uri.href;
  152. window[cb] = function (rsp) {
  153. document.head.removeChild(script);
  154. clearTimeout(timeout);
  155. delete window[cb];
  156. var data = "";
  157. if (adapter) {
  158. data = adapter(rsp, pre);
  159. }
  160. else {
  161. for (var p in adapters) {
  162. data = adapters[p].adapter(rsp, pre);
  163. if (data !== null) {
  164. break;
  165. }
  166. }
  167. }
  168. if (data === null) {
  169. code.textContent = "Cannot parse response (perhaps you need an adapter function?)";
  170. }
  171. else {
  172. code.textContent = data;
  173. Prism.highlightElement(code);
  174. }
  175. };
  176. document.head.appendChild(script);
  177. });
  178. }
  179. Prism.plugins.jsonphighlight = {
  180. registerAdapter: registerAdapter,
  181. removeAdapter: removeAdapter,
  182. highlight: highlight
  183. };
  184. highlight();
  185. })();