Skip to content

Commit 7578f4f

Browse files
author
Dmitriy Kubyshkin
committed
Started to work on Document class and implemented dumb doc rendering.
1 parent 2567d5b commit 7578f4f

File tree

5 files changed

+123
-7
lines changed

5 files changed

+123
-7
lines changed

demo/index.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
<script type="text/javascript" src="http://localhost:4000/lib.js"></script>
1010
<script type="text/javascript" charset="utf-8">
1111
document.addEventListener('DOMContentLoaded', function(){
12-
var CanvasTextEditor = require('CanvasTextEditor');
13-
var editor = new CanvasTextEditor;
12+
var CanvasTextEditor = require('CanvasTextEditor'),
13+
Document = require('Document'),
14+
doc = new Document('Line1\nLine that is little bit longer\nLine4'),
15+
editor = new CanvasTextEditor(doc);
1416
document.body.appendChild(editor.getEl());
1517
}, false);
1618
</script>

lib/CanvasTextEditor.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
"use strict";
22

3-
var FontMetrics = require('FontMetrics');
3+
var FontMetrics = require('FontMetrics'),
4+
Document = require('Document');
45

56
/**
67
* Simple plain-text text editor using html5 canvas.
78
* @constructor
89
*/
9-
var CanvasTextEditor = function() {
10+
var CanvasTextEditor = function(doc) {
11+
this._document = doc || (new Document);
1012
this._metrics = new FontMetrics('"Courier New", Courier, monospace', 14);
1113
this._createWrapper();
1214
this._createCanvas();
@@ -45,9 +47,20 @@ CanvasTextEditor.prototype._createCanvas = function() {
4547
this.context = this.canvas.getContext('2d');
4648
this.resize(640, 480);
4749

48-
// Placeholder function just to see that it's working
49-
this.context.font = this._metrics.getSize() + 'px ' + this._metrics.getFamily()
50-
this.context.fillText('Test', 0, this._metrics.getBaseline());
50+
// For now just very dumb implementation of rendering
51+
var baselineOffset = this._metrics.getBaseline(),
52+
lineHeight = this._metrics.getHeight(),
53+
characterWidth = this._metrics.getWidth(),
54+
maxHeight = Math.ceil(640 / lineHeight),
55+
lineCount = this._document.getLineCount();
56+
57+
if (lineCount < maxHeight) maxHeight = lineCount;
58+
59+
for(var i = 0; i < maxHeight; ++i) {
60+
this.context.fillText(
61+
this._document.getLine(i), 2, lineHeight * i + baselineOffset
62+
);
63+
}
5164

5265
this.wrapper.appendChild(this.canvas);
5366
};
@@ -92,6 +105,8 @@ CanvasTextEditor.prototype.getEl = function() {
92105
CanvasTextEditor.prototype.resize = function(width, height) {
93106
this.canvas.width = width;
94107
this.canvas.height = height;
108+
// We need to update context settings every time we resize
109+
this.context.font = this._metrics.getSize() + 'px ' + this._metrics.getFamily();
95110
};
96111

97112
/**

lib/Document.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
/**
3+
* Creates new document from provided text.
4+
* @param {string} text Full document text.
5+
* @constructor
6+
*/
7+
Document = function(text) {
8+
text || (text = '');
9+
this.storage = Document.prepareText(text);
10+
};
11+
12+
module.exports = Document;
13+
14+
/**
15+
* Splits text into array of lines. Can't use .split('\n') because
16+
* we want to keep trailing \n at the ends of lines.
17+
* @param {string} text
18+
* @return {Array.{string}}
19+
*/
20+
Document.prepareText = function(text) {
21+
var lines = [],
22+
index = 0,
23+
newIndex;
24+
do {
25+
newIndex = text.indexOf('\n', index);
26+
// Adding from previous index to new one or to the end of the string
27+
lines.push(text.substr(index, newIndex !== -1 ? newIndex - index + 1 : void 0));
28+
// next search will be after found newline
29+
index = newIndex + 1;
30+
} while (newIndex !== -1);
31+
32+
return lines;
33+
};
34+
35+
/**
36+
* Returns line count for the document
37+
* @return {number}
38+
*/
39+
Document.prototype.getLineCount = function() {
40+
return this.storage.length;
41+
};
42+
43+
/**
44+
* Returns line on the corresponding index.
45+
* @param {number} 0-based index of the line
46+
* @return {string}
47+
*/
48+
Document.prototype.getLine = function(index) {
49+
return this.storage[index];
50+
};
51+
52+
/**
53+
* Returns linear length of the document.
54+
* @return {number}
55+
*/
56+
Document.prototype.getLength = function() {
57+
var sum = 0;
58+
for (var i = this.storage.length - 1; i >= 0; --i) {
59+
sum += this.storage[i].length
60+
};
61+
return sum;
62+
};
63+
64+
/**
65+
* Returns char at specified offset.
66+
* @param {number} offset
67+
* @return {string|undefined}
68+
*/
69+
Document.prototype.charAt = function(column, row) {
70+
var row = this.storage[row];
71+
if (row) return row.charAt(column);
72+
};

test/runner.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<!-- include spec files here... -->
1717
<script type="text/javascript" src="spec/EditorSpec.js"></script>
1818
<script type="text/javascript" src="spec/FontMetricsSpec.js"></script>
19+
<script type="text/javascript" src="spec/DocumentSpec.js"></script>
1920

2021
<script type="text/javascript">
2122
(function() {

test/spec/DocumentSpec.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
describe("CanvasTextEditor", function() {
2+
var Document = require('Document');
3+
var testText = 'Line1\n\nLine3\nLine4'
4+
5+
it("should have static method for parsing text into array of lines", function() {
6+
var lines = Document.prepareText(testText);
7+
expect(lines.length).toEqual(4);
8+
expect(lines[0]).toEqual('Line1\n');
9+
expect(lines[1]).toEqual('\n');
10+
expect(lines[2]).toEqual('Line3\n');
11+
expect(lines[3]).toEqual('Line4');
12+
});
13+
14+
it("should support getting lines and characters at positions", function(){
15+
var doc = new Document(testText);
16+
17+
expect(doc.getLineCount()).toEqual(4);
18+
expect(doc.charAt(0,2)).toEqual('L');
19+
expect(doc.charAt(4,2)).toEqual('3');
20+
expect(doc.charAt(100,2)).toBeFalsy();
21+
22+
expect(doc.getLine(3)).toEqual('Line4');
23+
expect(doc.getLine(4)).toBeFalsy();
24+
});
25+
26+
});

0 commit comments

Comments
 (0)