'use strict';
// borrowed code from https://stackoverflow.com/a/17590149/125981
// makeClass - By Hubert Kauker (MIT Licensed)
// original by John Resig (MIT Licensed).
var makeClass = (function(Void) {
return function() {
var constructor = function() {
var init = constructor.prototype.init,
hasInitMethod = (typeof init == "function"),
instance;
if (this instanceof constructor) {
if (hasInitMethod) init.apply(this, arguments);
} else {
Void.prototype = constructor.prototype;
instance = new Void();
if (hasInitMethod) init.apply(instance, arguments);
return instance;
}
};
return constructor;
};
})(function() {});
//make a class MyApp using above
var MyApp = makeClass();
// create MyApp functional part using the init:
MyApp.prototype.init = function(myItem, showmeClass = "showme", separator = "|", groupSeparator = "||") {
let eventChangeName = "change";
let textElement = document.getElementById(myItem);
let showme = textElement.closest(".container").getElementsByClassName(showmeClass)[0];
let lineSep = "|\n";
let myData = {
hard: [],
very_hard: []
};
this.sentData = {
hard: [],
very_hard: []
};
//so we can tell the lines
function getStyle(elId, styleProp) {
var x = document.getElementById(elId);
let y = {};
if (x.currentStyle) {
y = x.currentStyle[styleProp];
} else if (window.getComputedStyle) {
y = document.defaultView.getComputedStyle(x, null).getPropertyValue(styleProp);
}
return y;
}
function getTextareaThings(myTextarea) {
let taComputedStyles = window.getComputedStyle(myTextarea);
return {
height: myTextarea.style.height,
rows: myTextarea.rows,
clientHeight: myTextarea.clientHeight,
lineHeight: taComputedStyles.getPropertyValue('line-height'),
font: taComputedStyles.getPropertyValue('font-size')
};
}
function getLinesInString(myString) {
/* new line things: /r old Mac, /cr/lf some, /n some
all the "new line": regex: /\r\n|\n|\r/gm
above reduced regex: g and m are for global and multiline flags */
let nl = /[\r\n]+/gm;
let lines = [];
lines = myString.split(nl);
return lines;
}
function splitGroupString(myString, separator) {
let strings = [];
strings = myString.split(separator);
return strings;
}
function getGroupsInString(myString) {
return splitGroupString(myString, groupSeparator);
}
function getGroupItemsInString(myString) {
return splitGroupString(myString, separator);
}
function getCurrentValue() {
return textElement.value;
}
function addNewLines(text, count) {
let newLine = "\n";
return text + newLine.repeat(count);
}
// make stuff obvious
function onFocusTextareaValue(event) {
showForDebug(event);
}
function onChangeTextareaValue(event) {
if (event.type == eventChangeName) {
event.stopPropagation();
event.stopImmediatePropagation();
}
showForDebug(event);
}
function showForDebug(event) {
let what = "Event: " + event.type;
let b = "<br />";
let tat = getTextareaThings(event.target);
let v = getCurrentValue().replace(what, "");
showme.innerHTML = what + b + ": lines:" + getLinesInString(v).length + b + v;
}
function getStringLineCount(arr) {
arr.length;
}
function getGroupItems() {
let groups = getGroupsInString(getCurrentValue());
let groupItems = {
count: groups.length, // how many groups, two in the definition (top/bottom)
groups: []
};
groups.forEach(function(group, index, groupsArr) {
let items = getGroupItemsInString(group);
// determine how to define "group name", I use a string and the index here
let gname = "group" + index;
let g = {
itemCount: items.length // number in this group
};
g[gname] = {
items: []
};
items.forEach(function(item, itemindex, itemsArr) {
let itemName = "item" + itemindex;
let itemobj = {};
itemobj[itemName] = {
items: item
};
g[gname].items.push(itemobj);
});
groupItems.groups.push(g);
});
return groupItems;
}
// setup events
textElement.addEventListener(eventChangeName, onChangeTextareaValue, false);
textElement.addEventListener("focus", onFocusTextareaValue, false);
this.getGeometry = function() {
let geometry = {};
let element = textElement;
let rect = element.getBoundingClientRect();
geometry.top = rect.top;
geometry.right = rect.right;
geometry.bottom = rect.bottom;
geometry.left = rect.left;
geometry.offsetHeight = element.offsetHeight;
geometry.rows = element.rows;
geometry.clientHeight = element.clientHeight;
geometry.fontSize = this.getStyleProperty("font-size");
geometry.lineCount = this.getLines().length;
geometry.lineHeight = this.getLineHeight();
geometry.height = geometry.bottom - geometry.top;
geometry.width = geometry.right - geometry.left;
console.log("Geometry:",geometry);
};
this.getMetrics = function() {
let fSize = this.getStyleProperty("font-size");
let lineCount = this.getLines().length;
let lineHeight = this.getLineHeight();
let yh = lineHeight / lineCount;
let yfhPixel = parseInt(fSize, 10);
let yLineY = yh * yfhPixel;
console.log("LH:", lineHeight, "font:", fSize, "Lines:", lineCount, "lineHeight:", lineHeight, "yh:", yh, "yfPixel:", yfhPixel, "yLineY:", yLineY);
};
this.getStyleProperty = function(propertyName) {
return getStyle(textElement.id, propertyName)
};
// public functions and objects
this.getLines = function() {
return getLinesInString(getCurrentValue());
};
this.getGroups = function() {
return getGroupsInString(getCurrentValue());
};
this.setText = function(content) {
if (!content) {
content = this.sentData;
}
let hard = content.hard.join(lineSep);
let veryHard = content.very_hard.join(lineSep);
this.textElement.value = hard.concat("|" + lineSep, veryHard);
};
this.getLineHeight = function(element) {
if (!element) {
element = textElement;
}
let temp = document.createElement(element.nodeName);
temp.setAttribute("style", "margin:0px;padding:0px;font-family:" + element.style.fontFamily + ";font-size:" + element.style.fontSize);
temp.innerHTML = "test";
temp = element.parentNode.appendChild(temp);
let lineHeight = temp.clientHeight;
temp.parentNode.removeChild(temp);
return lineHeight;
};
this.getGroupItems = function() {
return getGroupItems();
};
this.textElement = textElement;
this.showme = showme;
};
let sentData = {
hard: [
"It's the possibility of having a dream come true that makes life interesting",
"I cannot fix on the hour, or the spot, or the look or the words, which laid the foundation."
],
very_hard: ["He stepped down, trying not to look long at her, as if she were the sun, yet he saw her, like the sun, even without looking."]
};
// create instances and use our app, pass the id
var containerApp = MyApp("textThing"); //default last three parameters
containerApp.sentData = sentData;
containerApp.setText();
let groups = containerApp.getGroups();
let groupItems = containerApp.getGroupItems();
containerApp.getMetrics();
containerApp.getGeometry();
// create instances and use our app, pass the id
var containerApp2 = MyApp("msgTwo", "showme", "|", "||");
//console.log("Second One Lines:", containerApp2.getLines().length);
//containerApp2.getMetrics();
//containerApp2.getGeometry();
.page-container {
display: flex;
/* center and stack the containers*/
justify-content: center;
flex-direction: column;
align-items: center;
font-size: 62.5%;
}
.container {
border: solid 1px black;
}
.container-block {
border: 2px dashed #AAAAAA;
}
.container-items {
width: 500px;
position: relative;
}
.container-items .format-custom,
.container-items label {
width: 100%;
}
.container-items .format-custom {
height: 10em
}
.message-hr {
border: 1px solid blue;
background-color: blue;
height: 0.05em;
width: 450px;
align-items: center;
margin: 0.5em;
}
.showme {
border: dotted 2px dodgerblue;
background-color: #EEEEEE;
padding: 1em;
}
textarea.format-custom,
.custom-underlay,
.underlay {
margin: 0;
box-sizing: border-box;
vertical-align: top;
display: block;
border: lime solid 1px;
}
textarea.format-custom {
width: 100%;
height: 3em;
background: transparent;
resize: none;
border: red solid 1px;
padding: 0.5em;
}
.underlay {
border: 1px solid #fff;
width: 100%;
height: 100%;
background: transparent;
top: 1em;
left: 0;
display: block;
z-index: -1;
position: absolute;
}
.custom-underlay {
width: 100%;
height: 50%;
margin: 0;
box-sizing: border-box;
vertical-align: top;
position: absolute;
}
.custom-underlay.top {
background-color: #FFFF00;
top: 0;
left: 0;
}
.custom-underlay.bottom {
background-color: #FFAAAA;
top: 50%;
left: 0;
}
<div class="page-container">
<div class="container">
<div class="container-block">
<div class="container-items">
<label for="textThing">Your message:</label>
<textarea id="textThing" name="textThing" class="format-custom">howdy, I am here|another one | cheese burgers
fries and a drink
||
bottom of here| bottom second</textarea>
<div class="underlay">
<div class="custom-underlay top"></div>
<div class="custom-underlay bottom"></div>
</div>
</div>
</div>
<div class="showme">xxxone</div>
</div>
<div class="container">
<div class="container-block">
<div class="message-hr container-items">
</div>
</div>
</div>
<div class="container">
<div class="container-block">
<div class="container-items">
<label for="msgTwo">Second message:</label>
<textarea id="msgTwo" name="msgTwo" class="format-custom">Not the same|Nxxt one
||
bottom of next</textarea>
<div class="underlay">
<div class="custom-underlay top"></div>
<div class="custom-underlay bottom"></div>
</div>
</div>
</div>
<div class="showme">xxxtwo</div>
</div>
</div>