virtual_renderer_test.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Distributed under the BSD license:
  3. *
  4. * Copyright (c) 2010, Ajax.org B.V.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of Ajax.org B.V. nor the
  15. * names of its contributors may be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * ***** END LICENSE BLOCK ***** */
  30. if (typeof process !== "undefined") {
  31. ace_require("amd-loader");
  32. ace_require("./test/mockdom");
  33. }
  34. define(function(ace_require, exports, module) {
  35. "use strict";
  36. var Range = ace_require("./range").Range;
  37. var Editor = ace_require("./editor").Editor;
  38. var EditSession = ace_require("./edit_session").EditSession;
  39. var VirtualRenderer = ace_require("./virtual_renderer").VirtualRenderer;
  40. var assert = ace_require("./test/assertions");
  41. ace_require("./ext/error_marker");
  42. function setScreenPosition(node, rect) {
  43. node.style.left = rect[0] + "px";
  44. node.style.top = rect[1] + "px";
  45. node.style.width = rect[2] + "px";
  46. node.style.height = rect[3] + "px";
  47. }
  48. var editor = null;
  49. module.exports = {
  50. setUp: function() {
  51. if (editor)
  52. editor.destroy();
  53. var el = document.createElement("div");
  54. el.style.left = "20px";
  55. el.style.top = "30px";
  56. el.style.width = "300px";
  57. el.style.height = "100px";
  58. document.body.appendChild(el);
  59. var renderer = new VirtualRenderer(el);
  60. editor = new Editor(renderer);
  61. editor.on("destroy", function() {
  62. document.body.removeChild(el);
  63. });
  64. },
  65. tearDown: function() {
  66. editor && editor.destroy();
  67. editor = null;
  68. },
  69. "test: screen2text the column should be rounded to the next character edge" : function(done) {
  70. var renderer = editor.renderer;
  71. renderer.setPadding(0);
  72. renderer.setSession(new EditSession("1234"));
  73. var r = renderer.scroller.getBoundingClientRect();
  74. function testPixelToText(x, y, row, column) {
  75. assert.position(renderer.screenToTextCoordinates(x+r.left, y+r.top), row, column);
  76. }
  77. renderer.characterWidth = 10;
  78. renderer.lineHeight = 15;
  79. testPixelToText(4, 0, 0, 0);
  80. testPixelToText(5, 0, 0, 1);
  81. testPixelToText(9, 0, 0, 1);
  82. testPixelToText(10, 0, 0, 1);
  83. testPixelToText(14, 0, 0, 1);
  84. testPixelToText(15, 0, 0, 2);
  85. done();
  86. },
  87. "test: handle css transforms" : function(done) {
  88. var renderer = editor.renderer;
  89. var fontMetrics = renderer.$fontMetrics;
  90. setScreenPosition(editor.container, [20, 30, 300, 100]);
  91. var measureNode = fontMetrics.$measureNode;
  92. setScreenPosition(measureNode, [0, 0, 10 * measureNode.textContent.length, 15]);
  93. setScreenPosition(fontMetrics.$main, [0, 0, 10 * measureNode.textContent.length, 15]);
  94. fontMetrics.$characterSize.width = 10;
  95. renderer.setPadding(0);
  96. renderer.onResize(true);
  97. assert.equal(fontMetrics.getCharacterWidth(), 1);
  98. renderer.characterWidth = 10;
  99. renderer.lineHeight = 15;
  100. renderer.gutterWidth = 40;
  101. editor.setOption("hasCssTransforms", true);
  102. editor.container.style.transform = "matrix3d(0.7, 0, 0, -0.00066, 0, 0.82, 0, -0.001, 0, 0, 1, 0, -100, -20, 10, 1)";
  103. editor.container.style.zoom = 1.5;
  104. var pos = renderer.pixelToScreenCoordinates(100, 200);
  105. var els = fontMetrics.els;
  106. var rects = [
  107. [0, 0],
  108. [-37.60084843635559, 161.62494659423828],
  109. [114.50254130363464, -6.890693664550781],
  110. [98.85665202140808, 179.16063690185547]
  111. ];
  112. rects.forEach(function(rect, i) {
  113. els[i].getBoundingClientRect = function() {
  114. return { left: rect[0], top: rect[1] };
  115. };
  116. });
  117. var r0 = els[0].getBoundingClientRect();
  118. pos = renderer.pixelToScreenCoordinates(r0.left + 100, r0.top + 200);
  119. assert.position(pos, 10, 11);
  120. var pos1 = fontMetrics.transformCoordinates(null, [0, 200]);
  121. assert.ok(pos1[0] - rects[2][0] < 10e-6);
  122. assert.ok(pos1[1] - rects[2][1] < 10e-6);
  123. editor.renderer.$loop._flush();
  124. done();
  125. },
  126. "test scrollmargin + autosize": function(done) {
  127. editor.setOptions({
  128. maxLines: 100,
  129. wrap: true
  130. });
  131. editor.renderer.setScrollMargin(10, 10);
  132. editor.setValue("\n\n");
  133. editor.setValue("\n\n\n\n");
  134. editor.renderer.once("afterRender", function() {
  135. setTimeout(function() {
  136. done();
  137. }, 0);
  138. });
  139. },
  140. "test invalid valus of minLines": function() {
  141. editor.setOptions({
  142. maxLines: Infinity,
  143. minLines: Infinity
  144. });
  145. editor.renderer.$loop._flush();
  146. editor.setOptions({
  147. maxLines: NaN,
  148. minLines: NaN
  149. });
  150. editor.renderer.$loop._flush();
  151. editor.setOptions({
  152. maxLines: Number.MAX_SAFE_INTEGER + 1,
  153. minLines: Number.MAX_SAFE_INTEGER + 1
  154. });
  155. editor.renderer.$loop._flush();
  156. },
  157. "test line widgets": function() {
  158. editor.session.setValue("a\nb|c\nd");
  159. editor.session.setAnnotations([{row: 1, column: 2, type: "error"}]);
  160. editor.execCommand(editor.commands.byName.goToNextError);
  161. assert.position(editor.getCursorPosition(), 1, 2);
  162. editor.renderer.$loop._flush();
  163. assert.ok(editor.session.lineWidgets[1]);
  164. },
  165. "test wrapped text rendering": function() {
  166. editor.setValue("a".repeat(452) + "\n" + "b".repeat(100) + "\nxxxxxx", -1);
  167. editor.container.style.height = "500px";
  168. editor.setOption("wrap", 40);
  169. editor.resize(true);
  170. editor.renderer.$loop._flush();
  171. assert.equal(editor.renderer.$changedLines, null);
  172. editor.session.remove(new Range(0, 10, 0, 350));
  173. editor.session.insert({row: 1, column: 1}, "l".repeat(350));
  174. editor.renderer.$loop._flush();
  175. var lines = editor.renderer.$textLayer.element.children;
  176. assert.notEqual(lines[0].style.height, lines[1].style.height);
  177. assert.equal(lines[0].style.height, lines[1].style.top);
  178. },
  179. "test resize": function() {
  180. editor.setValue("Juhu kinners!");
  181. editor.resize(true);
  182. },
  183. "test placeholder": function() {
  184. editor.setOption("placeholder", "hello");
  185. assert.equal(editor.renderer.content.textContent, "hello");
  186. editor.setOption("placeholder", "new");
  187. assert.equal(editor.renderer.content.textContent, "new");
  188. editor.setValue("test");
  189. editor.renderer.$loop._flush();
  190. assert.equal(editor.renderer.content.textContent, "test");
  191. editor.setOption("placeholder", "only visible for empty value");
  192. assert.equal(editor.renderer.content.textContent, "test");
  193. editor.setValue("");
  194. editor.renderer.$loop._flush();
  195. editor._signal("input", {});
  196. assert.equal(editor.renderer.content.textContent, "only visible for empty value");
  197. }
  198. // change tab size after setDocument (for text layer)
  199. };
  200. });
  201. if (typeof module !== "undefined" && module === ace_require.main) {
  202. ace_require("asyncjs").test.testcase(module.exports).exec();
  203. }