summaryrefslogtreecommitdiff
path: root/js/error.highlight.js
diff options
context:
space:
mode:
authortimb <opuscule@gmail.com>2014-01-24 07:58:46 -0800
committertimb <opuscule@gmail.com>2014-01-24 07:58:46 -0800
commit89bf91e68f1fac2d88eb97c7fe324753a5ef76cf (patch)
treece0fc8c882fd1bff3e4cce5fdbf838e229232f3e /js/error.highlight.js
parent65d561be1d64767c3434137ae17b380067e1ef19 (diff)
a try at error highlighting
Diffstat (limited to 'js/error.highlight.js')
-rw-r--r--js/error.highlight.js160
1 files changed, 160 insertions, 0 deletions
diff --git a/js/error.highlight.js b/js/error.highlight.js
new file mode 100644
index 0000000..b7c583e
--- /dev/null
+++ b/js/error.highlight.js
@@ -0,0 +1,160 @@
+(function(){
+
+var html
+var textarea
+var dom = {}
+var style = {}
+var pos = {}
+// i use this because a plain <br> collapses vertically sometimes...
+var zero_width_space = '&#xfeff;'
+
+var off = function(){
+ dom.highlight.style.display = 'none'
+}
+
+var height_until_error = 0;
+var height_with_error = 0;
+
+var on = function(line_num){
+ pos = textarea.getBoundingClientRect()
+ var text = textarea.value;
+
+ var lines = text.split('\n')
+ var lines_until_error = lines.slice(0, line_num)
+ var line_with_error = lines[line_num]
+
+ if (lines_until_error.length === 1)
+ dom.textmeasure.innerHTML = lines_until_error + zero_width_space
+ else
+ dom.textmeasure.innerHTML = lines_until_error.join('<br>' + zero_width_space)
+
+ height_until_error = dom.textmeasure.offsetHeight
+
+ dom.textmeasure.innerHTML = line_with_error + zero_width_space
+
+ height_with_error = dom.textmeasure.offsetHeight
+
+ reposition_highlight()
+
+};
+
+var reposition_highlight = function(){
+ dom.highlight.style.display = 'block'
+
+ var bounds_bottom = pos.top + pos.height
+
+ if (textarea.scrollHeight > textarea.clientHeight) // scrollbar exists
+ dom.highlight.style.width = pos.width - scrollbar_width + "px"
+ else
+ dom.highlight.style.width = pos.width + "px"
+
+ dom.highlight.style.left = pos.left + "px"
+
+ var y_pos = pos.top + height_until_error - textarea.scrollTop
+
+ dom.highlight.style.top = y_pos + html.scrollTop + "px"
+
+ var height_of_highlight = height_with_error;
+
+ // nice clip on bottom
+ if (y_pos + height_of_highlight > bounds_bottom)
+ height_of_highlight = Math.max(0, bounds_bottom - y_pos)
+ // crap clip on top
+ if (y_pos < pos.top)
+ height_of_highlight = 0
+
+ dom.highlight.style.height = height_of_highlight + "px"
+}
+
+var calc_textarea_style = function(){
+ var $textarea = $("#shader")
+ textarea = $textarea[0]
+ // GG = textarea
+
+ var props = ['lineHeight', 'fontFamily', 'fontSize', 'padding', 'margin', 'borderWidth', 'width']
+
+ for (var i=0, p; p=props[i]; i++){
+ style[p] = $textarea.css(p)
+ }
+ console.log(style)
+
+}
+
+
+var calc_scrollbar_width = function() {
+ var outer = document.createElement("div");
+ outer.style.visibility = "hidden";
+ outer.style.width = "100px";
+ document.body.appendChild(outer);
+
+ var width_no_scroll = outer.offsetWidth;
+ // force scrollbars
+ outer.style.overflow = "scroll";
+
+ // add innerdiv
+ var inner = document.createElement("div");
+ inner.style.width = "100%";
+ outer.appendChild(inner);
+
+ var width_with_scroll = inner.offsetWidth;
+ // remove divs
+ outer.parentNode.removeChild(outer);
+
+ return width_no_scroll - width_with_scroll;
+}
+
+var create_el_textmeasure = function(){
+ var el = dom.textmeasure = document.createElement('div')
+ el.id = 'textmeasure'
+ var s = el.style
+ for (var key in style)
+ s[key] = style[key]
+
+ s.wordWrap = 'break-word'
+ s.wordBreak = 'break-all'
+ s.border = '1px solid red'
+ s.padding = '0'
+ s.display = 'block'
+ s.position = 'absolute'
+ s.left = "-5000px"
+ document.body.appendChild(el)
+}
+
+var create_el_highlight = function(){
+ var el = dom.highlight = document.createElement('div')
+ var s = el.style
+ for (var key in style)
+ s[key] = style[key]
+
+ s.pointerEvents = 'none'
+ s.opacity = '0.2'
+ s.backgroundColor = '#f00'
+ s.position = 'absolute'
+ s.lineHeight = '0'
+ s.fontSize = '0'
+ s.padding = '0'
+ s.borderWidth = '0'
+ s.display = 'block'
+ document.body.appendChild(el)
+}
+
+var scrollbar_width = 0;
+var init = function(){
+ calc_textarea_style()
+ create_el_highlight()
+ create_el_textmeasure()
+ scrollbar_width = calc_scrollbar_width()
+ textarea.addEventListener('scroll', reposition_highlight)
+ html = document.querySelector('html')
+}
+
+error_highlight = {
+ init: init,
+ on: on,
+ off: off
+}
+
+
+})();
+
+error_highlight.init()