You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
4.6KB

  1. function Редактор(события, имяОбласти)
  2. {
  3. this.создать = function()
  4. {
  5. this.установитьAce();
  6. this.улавливатьЗавершениеРедактирования();
  7. this.разобратьПараметрыЗапуска();
  8. this.задатьКодПриЗапуске();
  9. события.подписать(this);
  10. };
  11. this.задатьКодПриЗапуске = function()
  12. {
  13. var z64 = this.параметрыЗапуска["z64"];
  14. if (z64)
  15. {
  16. var код = this.изZ64(z64);
  17. this.ace.session.setValue(код);
  18. }
  19. };
  20. this.исполнитьКод = function()
  21. {
  22. var содержимое = this.ace.session.getValue();
  23. var z64 = this.вZ64(содержимое);
  24. var путь = window.location.pathname + "?z64=" + z64;
  25. history.pushState(null, "", путь);
  26. };
  27. this.обработатьСобытие = function(событие)
  28. {
  29. if (событие == "завершили редактирование")
  30. {
  31. this.проверитьКорректностьКода();
  32. }
  33. else if (событие == "код корректен")
  34. {
  35. this.исполнитьКод();
  36. }
  37. };
  38. this.разобратьПараметрыЗапуска = function()
  39. {
  40. this.параметрыЗапуска = {};
  41. var запрос = window.location.search.substring(1);
  42. var аргументы = запрос.split("&");
  43. for (var номер in аргументы)
  44. {
  45. var арг = аргументы[номер];
  46. var позицияЗнака = арг.indexOf("=");
  47. // Лишь ключ.
  48. if (позицияЗнака == -1)
  49. {
  50. var ключ = decodeURIComponent(арг);
  51. this.параметрыЗапуска[ключ] = null;
  52. }
  53. // Ключ со значением.
  54. else
  55. {
  56. var сыройКлюч = арг.slice(0, позицияЗнака);
  57. var сыроеЗначение = арг.slice(позицияЗнака + 1);
  58. var ключ = decodeURIComponent(сыройКлюч);
  59. var значение = decodeURIComponent(сыроеЗначение);
  60. this.параметрыЗапуска[ключ] = значение;
  61. }
  62. }
  63. };
  64. this.установитьAce = function()
  65. {
  66. var область = document.getElementById(имяОбласти);
  67. this.ace = window.ace.edit(имяОбласти);
  68. this.ace.session.setMode("ace/mode/javascript");
  69. this.ace.session.setUseWrapMode(true);
  70. }
  71. this.улавливатьЗавершениеРедактирования = function()
  72. {
  73. var тут = this;
  74. this.ace.session.on("change", function(дельта) {
  75. const билет = тут.uuid();
  76. тут.билет = билет;
  77. setTimeout(
  78. function()
  79. {
  80. if (билет == тут.билет)
  81. {
  82. события.уведомить("завершили редактирование");
  83. }
  84. },
  85. 1000
  86. );
  87. });
  88. };
  89. this.проверитьКорректностьКода = function()
  90. {
  91. try
  92. {
  93. eval(this.ace.session.getValue());
  94. события.уведомить("код корректен");
  95. }
  96. catch (ошибка)
  97. {
  98. события.уведомить("код некорректен");
  99. }
  100. };
  101. this.вZ64 = function(строка)
  102. {
  103. var байты = new TextEncoder("utf-8").encode(строка);
  104. var архив = pako.deflate(байты, { to: 'string' });
  105. return base64js.fromByteArray(архив);
  106. };
  107. this.изZ64 = function(строка)
  108. {
  109. var архив = base64js.toByteArray(строка);
  110. var байты = pako.inflate(архив);
  111. return new TextDecoder("utf-8").decode(байты);
  112. };
  113. this.uuid = function()
  114. {
  115. // https://stackoverflow.com/a/2117523
  116. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
  117. /[xy]/g,
  118. function(c)
  119. {
  120. var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
  121. return v.toString(16);
  122. }
  123. );
  124. };
  125. // Конструктор.
  126. this.создать();
  127. }