summaryrefslogtreecommitdiffstats
path: root/packages/markdown/marked/docs/demo/demo.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/markdown/marked/docs/demo/demo.js')
-rw-r--r--packages/markdown/marked/docs/demo/demo.js534
1 files changed, 534 insertions, 0 deletions
diff --git a/packages/markdown/marked/docs/demo/demo.js b/packages/markdown/marked/docs/demo/demo.js
new file mode 100644
index 00000000..e7d97c59
--- /dev/null
+++ b/packages/markdown/marked/docs/demo/demo.js
@@ -0,0 +1,534 @@
+/* globals marked, unfetch, ES6Promise */
+
+if (!window.Promise) {
+ window.Promise = ES6Promise;
+}
+if (!window.fetch) {
+ window.fetch = unfetch;
+}
+
+onunhandledrejection = function (e) {
+ throw e.reason;
+};
+
+var $loadingElem = document.querySelector('#loading');
+var $mainElem = document.querySelector('#main');
+var $markdownElem = document.querySelector('#markdown');
+var $markedVerElem = document.querySelector('#markedVersion');
+var $commitVerElem = document.querySelector('#commitVersion');
+var $markedVer = document.querySelector('#markedCdn');
+var $optionsElem = document.querySelector('#options');
+var $outputTypeElem = document.querySelector('#outputType');
+var $inputTypeElem = document.querySelector('#inputType');
+var $responseTimeElem = document.querySelector('#responseTime');
+var $previewElem = document.querySelector('#preview');
+var $previewIframe = document.querySelector('#preview iframe');
+var $permalinkElem = document.querySelector('#permalink');
+var $clearElem = document.querySelector('#clear');
+var $htmlElem = document.querySelector('#html');
+var $lexerElem = document.querySelector('#lexer');
+var $panes = document.querySelectorAll('.pane');
+var $inputPanes = document.querySelectorAll('.inputPane');
+var lastInput = '';
+var inputDirty = true;
+var $activeOutputElem = null;
+var search = searchToObject();
+var markedVersions = {
+ master: 'https://cdn.jsdelivr.net/gh/markedjs/marked/lib/marked.js'
+};
+var markedVersionCache = {};
+var delayTime = 1;
+var checkChangeTimeout = null;
+var markedWorker;
+
+$previewIframe.addEventListener('load', handleIframeLoad);
+
+$outputTypeElem.addEventListener('change', handleOutputChange, false);
+
+$inputTypeElem.addEventListener('change', handleInputChange, false);
+
+$markedVerElem.addEventListener('change', handleVersionChange, false);
+
+$markdownElem.addEventListener('change', handleInput, false);
+$markdownElem.addEventListener('keyup', handleInput, false);
+$markdownElem.addEventListener('keypress', handleInput, false);
+$markdownElem.addEventListener('keydown', handleInput, false);
+
+$optionsElem.addEventListener('change', handleInput, false);
+$optionsElem.addEventListener('keyup', handleInput, false);
+$optionsElem.addEventListener('keypress', handleInput, false);
+$optionsElem.addEventListener('keydown', handleInput, false);
+
+$commitVerElem.style.display = 'none';
+$commitVerElem.addEventListener('keypress', handleAddVersion, false);
+
+$clearElem.addEventListener('click', handleClearClick, false);
+
+Promise.all([
+ setInitialQuickref(),
+ setInitialOutputType(),
+ setInitialText(),
+ setInitialVersion()
+ .then(setInitialOptions)
+]).then(function () {
+ handleInputChange();
+ handleOutputChange();
+ checkForChanges();
+ setScrollPercent(0);
+ $loadingElem.style.display = 'none';
+ $mainElem.style.display = 'block';
+});
+
+function setInitialText() {
+ if ('text' in search) {
+ $markdownElem.value = search.text;
+ } else {
+ return fetch('./initial.md')
+ .then(function (res) { return res.text(); })
+ .then(function (text) {
+ if ($markdownElem.value === '') {
+ $markdownElem.value = text;
+ }
+ });
+ }
+}
+
+function setInitialQuickref() {
+ return fetch('./quickref.md')
+ .then(function (res) { return res.text(); })
+ .then(function (text) {
+ document.querySelector('#quickref').value = text;
+ });
+}
+
+function setInitialVersion() {
+ return fetch('https://data.jsdelivr.com/v1/package/npm/marked')
+ .then(function (res) {
+ return res.json();
+ })
+ .then(function (json) {
+ for (var i = 0; i < json.versions.length; i++) {
+ var ver = json.versions[i];
+ markedVersions[ver] = 'https://cdn.jsdelivr.net/npm/marked@' + ver + '/lib/marked.js';
+ var opt = document.createElement('option');
+ opt.textContent = ver;
+ opt.value = ver;
+ $markedVerElem.appendChild(opt);
+ }
+ })
+ .then(function () {
+ return fetch('https://api.github.com/repos/markedjs/marked/commits')
+ .then(function (res) {
+ return res.json();
+ })
+ .then(function (json) {
+ markedVersions['master'] = 'https://cdn.jsdelivr.net/gh/markedjs/marked@' + json[0].sha + '/lib/marked.js';
+ })
+ .catch(function () {
+ // do nothing
+ // uses url without commit
+ });
+ })
+ .then(function () {
+ if (search.version) {
+ if (markedVersions[search.version]) {
+ return search.version;
+ } else {
+ var match = search.version.match(/^(\w+):(.+)$/);
+ if (match) {
+ switch (match[1]) {
+ case 'commit':
+ addCommitVersion(search.version, match[2].substring(0, 7), match[2]);
+ return search.version;
+ case 'pr':
+ return getPrCommit(match[2])
+ .then(function (commit) {
+ if (!commit) {
+ return 'master';
+ }
+ addCommitVersion(search.version, 'PR #' + match[2], commit);
+ return search.version;
+ });
+ }
+ }
+ }
+ }
+
+ return 'master';
+ })
+ .then(function (version) {
+ $markedVerElem.value = version;
+ })
+ .then(updateVersion);
+}
+
+function setInitialOptions() {
+ if ('options' in search) {
+ $optionsElem.value = search.options;
+ } else {
+ setDefaultOptions();
+ }
+}
+
+function setInitialOutputType() {
+ if (search.outputType) {
+ $outputTypeElem.value = search.outputType;
+ }
+}
+
+function handleIframeLoad() {
+ lastInput = '';
+ inputDirty = true;
+}
+
+function handleInput() {
+ inputDirty = true;
+};
+
+function handleVersionChange() {
+ if ($markedVerElem.value === 'commit' || $markedVerElem.value === 'pr') {
+ $commitVerElem.style.display = '';
+ } else {
+ $commitVerElem.style.display = 'none';
+ updateVersion();
+ }
+}
+
+function handleClearClick() {
+ $markdownElem.value = '';
+ $markedVerElem.value = 'master';
+ $commitVerElem.style.display = 'none';
+ updateVersion().then(setDefaultOptions);
+}
+
+function handleAddVersion(e) {
+ if (e.which === 13) {
+ switch ($markedVerElem.value) {
+ case 'commit':
+ var commit = $commitVerElem.value.toLowerCase();
+ if (!commit.match(/^[0-9a-f]{40}$/)) {
+ alert('That is not a valid commit');
+ return;
+ }
+ addCommitVersion('commit:' + commit, commit.substring(0, 7), commit);
+ $markedVerElem.value = 'commit:' + commit;
+ $commitVerElem.style.display = 'none';
+ $commitVerElem.value = '';
+ updateVersion();
+ break;
+ case 'pr':
+ $commitVerElem.disabled = true;
+ var pr = $commitVerElem.value.replace(/\D/g, '');
+ getPrCommit(pr)
+ .then(function (commit) {
+ $commitVerElem.disabled = false;
+ if (!commit) {
+ alert('That is not a valid PR');
+ return;
+ }
+ addCommitVersion('pr:' + pr, 'PR #' + pr, commit);
+ $markedVerElem.value = 'pr:' + pr;
+ $commitVerElem.style.display = 'none';
+ $commitVerElem.value = '';
+ updateVersion();
+ });
+ }
+ }
+}
+
+function handleInputChange() {
+ handleChange($inputPanes, $inputTypeElem.value);
+}
+
+function handleOutputChange() {
+ $activeOutputElem = handleChange($panes, $outputTypeElem.value);
+ updateLink();
+}
+
+function handleChange(panes, visiblePane) {
+ var active = null;
+ for (var i = 0; i < panes.length; i++) {
+ if (panes[i].id === visiblePane) {
+ panes[i].style.display = '';
+ active = panes[i];
+ } else {
+ panes[i].style.display = 'none';
+ }
+ }
+ return active;
+};
+
+function addCommitVersion(value, text, commit) {
+ if (markedVersions[value]) {
+ return;
+ }
+ markedVersions[value] = 'https://cdn.jsdelivr.net/gh/markedjs/marked@' + commit + '/lib/marked.js';
+ var opt = document.createElement('option');
+ opt.textContent = text;
+ opt.value = value;
+ $markedVerElem.insertBefore(opt, $markedVerElem.firstChild);
+}
+
+function getPrCommit(pr) {
+ return fetch('https://api.github.com/repos/markedjs/marked/pulls/' + pr + '/commits')
+ .then(function (res) {
+ return res.json();
+ })
+ .then(function (json) {
+ return json[json.length - 1].sha;
+ }).catch(function () {
+ // return undefined
+ });
+}
+
+function setDefaultOptions() {
+ if (window.Worker) {
+ messageWorker({
+ task: 'defaults',
+ version: markedVersions[$markedVerElem.value]
+ });
+ } else {
+ var defaults = marked.getDefaults();
+ setOptions(defaults);
+ }
+}
+
+function setOptions(opts) {
+ $optionsElem.value = JSON.stringify(
+ opts,
+ function (key, value) {
+ if (value && typeof value === 'object' && Object.getPrototypeOf(value) !== Object.prototype) {
+ return undefined;
+ }
+ return value;
+ }, ' ');
+}
+
+function searchToObject() {
+ // modified from https://stackoverflow.com/a/7090123/806777
+ var pairs = location.search.slice(1).split('&');
+ var obj = {};
+
+ for (var i = 0; i < pairs.length; i++) {
+ if (pairs[i] === '') {
+ continue;
+ }
+
+ var pair = pairs[i].split('=');
+
+ obj[decodeURIComponent(pair.shift())] = decodeURIComponent(pair.join('='));
+ }
+
+ return obj;
+}
+
+function jsonString(input) {
+ var output = (input + '')
+ .replace(/\n/g, '\\n')
+ .replace(/\r/g, '\\r')
+ .replace(/\t/g, '\\t')
+ .replace(/\f/g, '\\f')
+ .replace(/[\\"']/g, '\\$&')
+ .replace(/\u0000/g, '\\0');
+ return '"' + output + '"';
+};
+
+function getScrollSize() {
+ var e = $activeOutputElem;
+
+ return e.scrollHeight - e.clientHeight;
+};
+
+function getScrollPercent() {
+ var size = getScrollSize();
+
+ if (size <= 0) {
+ return 1;
+ }
+
+ return $activeOutputElem.scrollTop / size;
+};
+
+function setScrollPercent(percent) {
+ $activeOutputElem.scrollTop = percent * getScrollSize();
+};
+
+function updateLink() {
+ var outputType = '';
+ if ($outputTypeElem.value !== 'preview') {
+ outputType = 'outputType=' + $outputTypeElem.value + '&';
+ }
+
+ $permalinkElem.href = '?' + outputType + 'text=' + encodeURIComponent($markdownElem.value)
+ + '&options=' + encodeURIComponent($optionsElem.value)
+ + '&version=' + encodeURIComponent($markedVerElem.value);
+ history.replaceState('', document.title, $permalinkElem.href);
+}
+
+function updateVersion() {
+ if (window.Worker) {
+ handleInput();
+ return Promise.resolve();
+ }
+ var promise;
+ if (markedVersionCache[$markedVerElem.value]) {
+ promise = Promise.resolve(markedVersionCache[$markedVerElem.value]);
+ } else {
+ promise = fetch(markedVersions[$markedVerElem.value])
+ .then(function (res) { return res.text(); })
+ .then(function (text) {
+ markedVersionCache[$markedVerElem.value] = text;
+ return text;
+ });
+ }
+ return promise.then(function (text) {
+ var script = document.createElement('script');
+ script.textContent = text;
+
+ $markedVer.parentNode.replaceChild(script, $markedVer);
+ $markedVer = script;
+ }).then(handleInput);
+}
+
+function checkForChanges() {
+ if (inputDirty && $markedVerElem.value !== 'commit' && $markedVerElem.value !== 'pr' && (typeof marked !== 'undefined' || window.Worker)) {
+ inputDirty = false;
+
+ updateLink();
+
+ var options = {};
+ var optionsString = $optionsElem.value || '{}';
+ try {
+ var newOptions = JSON.parse(optionsString);
+ options = newOptions;
+ $optionsElem.classList.remove('error');
+ } catch (err) {
+ $optionsElem.classList.add('error');
+ }
+
+ var version = markedVersions[$markedVerElem.value];
+ var markdown = $markdownElem.value;
+ var hash = version + markdown + optionsString;
+ if (lastInput !== hash) {
+ lastInput = hash;
+ if (window.Worker) {
+ delayTime = 100;
+ messageWorker({
+ task: 'parse',
+ version: version,
+ markdown: markdown,
+ options: options
+ });
+ } else {
+ var startTime = new Date();
+ var lexed = marked.lexer(markdown, options);
+ var lexedList = [];
+ for (var i = 0; i < lexed.length; i++) {
+ var lexedLine = [];
+ for (var j in lexed[i]) {
+ lexedLine.push(j + ':' + jsonString(lexed[i][j]));
+ }
+ lexedList.push('{' + lexedLine.join(', ') + '}');
+ }
+ var parsed = marked.parser(lexed, options);
+ var scrollPercent = getScrollPercent();
+ setParsed(parsed, lexedList.join('\n'));
+ setScrollPercent(scrollPercent);
+ var endTime = new Date();
+ delayTime = endTime - startTime;
+ setResponseTime(delayTime);
+ if (delayTime < 50) {
+ delayTime = 50;
+ } else if (delayTime > 500) {
+ delayTime = 1000;
+ }
+ }
+ }
+ }
+ checkChangeTimeout = window.setTimeout(checkForChanges, delayTime);
+};
+
+function setResponseTime(ms) {
+ var amount = ms;
+ var suffix = 'ms';
+ if (ms > 1000 * 60 * 60) {
+ amount = 'Too Long';
+ suffix = '';
+ } else if (ms > 1000 * 60) {
+ amount = '>' + Math.floor(ms / (1000 * 60));
+ suffix = 'm';
+ } else if (ms > 1000) {
+ amount = '>' + Math.floor(ms / 1000);
+ suffix = 's';
+ }
+ $responseTimeElem.textContent = amount + suffix;
+}
+
+function setParsed(parsed, lexed) {
+ try {
+ $previewIframe.contentDocument.body.innerHTML = parsed;
+ } catch (ex) {}
+ $htmlElem.value = parsed;
+ $lexerElem.value = lexed;
+}
+
+function messageWorker(message) {
+ if (!markedWorker || markedWorker.working) {
+ if (markedWorker) {
+ clearTimeout(markedWorker.timeout);
+ markedWorker.terminate();
+ }
+ markedWorker = new Worker('worker.js');
+ markedWorker.onmessage = function (e) {
+ clearTimeout(markedWorker.timeout);
+ markedWorker.working = false;
+ switch (e.data.task) {
+ case 'defaults':
+ setOptions(e.data.defaults);
+ break;
+ case 'parse':
+ $previewElem.classList.remove('error');
+ $htmlElem.classList.remove('error');
+ $lexerElem.classList.remove('error');
+ var scrollPercent = getScrollPercent();
+ setParsed(e.data.parsed, e.data.lexed);
+ setScrollPercent(scrollPercent);
+ setResponseTime(e.data.time);
+ break;
+ }
+ clearTimeout(checkChangeTimeout);
+ delayTime = 10;
+ checkForChanges();
+ };
+ markedWorker.onerror = markedWorker.onmessageerror = function (err) {
+ clearTimeout(markedWorker.timeout);
+ var error = 'There was an error in the Worker';
+ if (err) {
+ if (err.message) {
+ error = err.message;
+ } else {
+ error = err;
+ }
+ }
+ error = error.replace(/^Uncaught Error: /, '');
+ $previewElem.classList.add('error');
+ $htmlElem.classList.add('error');
+ $lexerElem.classList.add('error');
+ setParsed(error, error);
+ setScrollPercent(0);
+ };
+ }
+ if (message.task !== 'defaults') {
+ markedWorker.working = true;
+ workerTimeout(0);
+ }
+ markedWorker.postMessage(message);
+}
+
+function workerTimeout(seconds) {
+ markedWorker.timeout = setTimeout(function () {
+ seconds++;
+ markedWorker.onerror('Marked has taken longer than ' + seconds + ' second' + (seconds > 1 ? 's' : '') + ' to respond...');
+ workerTimeout(seconds);
+ }, 1000);
+}