-
Notifications
You must be signed in to change notification settings - Fork 0
/
linebreak-algorithm.js
100 lines (78 loc) · 2.76 KB
/
linebreak-algorithm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
function applyLineBreaks(textarea) {
"use strict";
// Requires the css rule "line-break" to be "strict" or "loose".
// {line-break: strict;}
// Also requires the attribte "wrap" to be "hard".
function getPaddingAndBorder() {
var borderLeft = parseInt(window.getComputedStyle( textarea, null).getPropertyValue('border-left-width'));
var paddingLeft = parseInt(window.getComputedStyle( textarea, null).getPropertyValue('padding-left'));
var borderRight = parseInt(window.getComputedStyle( textarea, null).getPropertyValue('border-right-width'));
var paddingRight = parseInt(window.getComputedStyle( textarea, null).getPropertyValue('padding-right'));
return borderLeft + paddingLeft + borderRight + paddingRight;
}
function getTextWidthCanvas(text, font) {
var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
document.body.appendChild(canvas);
var context = canvas.getContext("2d");
context.font = font;
var metrics = context.measureText(text);
return metrics.width;
}
function getFontInfo(){
return {
family: window.getComputedStyle( textarea, null).getPropertyValue('font-family'),
pixels: window.getComputedStyle( textarea, null).getPropertyValue('font-size')
}
}
var font = getFontInfo();
function getTextWidth(text) {
var width = getTextWidthCanvas(text, font.pixels + " " + font.family);
return width;
}
var re=/\r\n|\n\r|\n|\r/g;
var lines = textarea.value.replace(re,"\n").split("\n"); // 4 lines
var maxLineWidth = textarea.offsetWidth;
var spaceCharWidth = getTextWidth(" ");
var outer = [];
outer.push([]);
var lineCount = 0;
var spaceLeft = maxLineWidth;
var paddingAndBorder = getPaddingAndBorder();
for (var lineIndex = 0; lineIndex < lines.length; lineIndex++) {
var line = lines[lineIndex]; // string
var words = line.split(' ');
for (var wordIndex = 0; wordIndex < words.length; wordIndex++) {
var word = words[wordIndex];
var width = getTextWidth(word);
spaceLeft -= (width + spaceCharWidth);
if (spaceLeft > (0 + paddingAndBorder)) { // close to zero
outer[lineCount].push(word);
} else {
// linebreak here.
lineCount++;
outer.push([]); // empty array.
outer[lineCount].push(word);
spaceLeft = (maxLineWidth - width);
}
}
spaceLeft = maxLineWidth;
lineCount++;
outer.push([]);
}
var lastArray = outer[outer.length - 1];
if (lastArray.length === 0) {
// DROP THE LAST ARRAY!
outer.pop();
}
var newString = "";
for (var i = 0; i < outer.length; i++) {
newString += outer[i].join(' ');
if (i !== (outer.length - 1)) {
// only add the new line if it is not the last line.
newString += "\n";
}
}
// remove the canvas so it doesn't interfere.
document.body.removeChild(getTextWidth.canvas);
return newString;
}