Advertisement
Guest User

Untitled

a guest
Feb 10th, 2016
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.32 KB | None | 0 0
  1. /* gaido v1.0.0 (c) 2016~ nodegin */
  2. !function() {
  3. var container = document.querySelector('#gaido');
  4. var script = document.querySelector('script[type="text/gaido"]').innerHTML;
  5. script = script.split('\n').slice(1, -1);
  6. var getIndentLength = function(line) {
  7. matches = line.match(/^\s+/);
  8. return matches ? matches[0].length : 0;
  9. };
  10. var raise = function(message, i) {
  11. throw new Error(message + (i ? ' at line ' + (i + 1) : ''));
  12. };
  13. if (script.length < 2) {
  14. raise('Invalid gaido script');
  15. }
  16. var trimIndent = new RegExp('^\\s{' + getIndentLength(script[0]) + '}');
  17. script = script.map(function(line) {
  18. return line.replace(trimIndent, '');
  19. });
  20. var questions = {};
  21. var current = null;
  22. var lastIndent = 0;
  23. var currentIndent = 0;
  24. var levels = [];
  25. var indentSpaces = getIndentLength(script[1]);
  26. if (indentSpaces < 1 || indentSpaces % 2 !== 0) {
  27. raise('Unexpected indentation at line 2');
  28. }
  29. script.forEach(function(line, _i) {
  30. var _choice = null;
  31. if (_choice = line.match(/^\d+?\:$/)) {
  32. current = parseInt(_choice);
  33. if (questions[current]) {
  34. raise('Duplicate key for Question #' + current);
  35. } else {
  36. questions[current] = {};
  37. }
  38. } else {
  39. currentIndent = getIndentLength(line);
  40. if (currentIndent % indentSpaces !== 0) {
  41. raise('Unexpected indentation', _i);
  42. }
  43. /* Parse choice */
  44. if (currentIndent > lastIndent) {
  45. // enter level
  46. levels.push(line);
  47. } else if (currentIndent < lastIndent) {
  48. // exit levels
  49. for (var i = 0; i < lastIndent / currentIndent; i++)
  50. levels.pop();
  51. levels.push(line);
  52. } else if (currentIndent === lastIndent) {
  53. // update level
  54. levels.pop();
  55. levels.push(line);
  56. }
  57. var levMessage = line.match(/message:\s"(.+?)"$/);
  58. var levChoices = line.match(/choices:$/);
  59. if (levMessage) {
  60. questions[current].message = levMessage[1];
  61. } else if (levChoices) {
  62. questions[current].choices = [];
  63. } else if (currentIndent >= lastIndent) {
  64. // entered from last level (>) or in same level (===)
  65. var lastLevel = levels[levels.length - 2];
  66. if (lastLevel.indexOf('choices') > -1) {
  67. // entered from choices, add new choice
  68. var matches = line.match(/^\s+?"(.+?)"\s=>\s(\d+)$/);
  69. if (!matches) {
  70. raise('Syntax error', _i);
  71. }
  72. questions[current].choices.push({
  73. next: +matches[2],
  74. text: matches[1]
  75. });
  76. }
  77. }
  78. lastIndent = currentIndent;
  79. }
  80. });
  81. // start building ui
  82. var fragment = document.createDocumentFragment();
  83. var currentArticle = null;
  84. var firstArticle = null;
  85. var articles = {};
  86. for (var q in questions) {
  87. var qstn = questions[q];
  88. var article = document.createElement('article');
  89. article.qid = q;
  90. articles[q] = article;
  91. var section = document.createElement('section');
  92. // display message
  93. var msgWrap = document.createElement('div');
  94. msgWrap.innerHTML = qstn.message;
  95. msgWrap.className = 'message-container';
  96. section.appendChild(msgWrap);
  97. // build buttons
  98. if (qstn.choices) {
  99. var buttonsWrap = document.createElement('div');
  100. buttonsWrap.className = 'buttons-container';
  101. qstn.choices.forEach(function(c) {
  102. var button = document.createElement('button');
  103. button.onclick = function() {
  104. currentArticle.style.display = 'none';
  105. currentArticle = articles[c.next];
  106. history.pushState(c.next, document.title, location.pathname);
  107. currentArticle.style.display = 'block';
  108. };
  109. button.appendChild(document.createTextNode(c.text));
  110. buttonsWrap.appendChild(button);
  111. });
  112. section.appendChild(buttonsWrap);
  113. }
  114. article.appendChild(section);
  115. article.style.display = 'none';
  116. fragment.appendChild(article);
  117. // show first
  118. if (null === currentArticle) {
  119. currentArticle = firstArticle = article;
  120. }
  121. }
  122. window.onpopstate = function(e) {
  123. var qid = e.state;
  124. if (null === qid) {
  125. qid = firstArticle.qid;
  126. }
  127. currentArticle.style.display = 'none';
  128. currentArticle = articles[qid];
  129. currentArticle.style.display = 'block';
  130. };
  131. container.appendChild(fragment);
  132. currentArticle.style.display = 'block';
  133. }();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement