timeout = (ms, cb) -> return setTimeout cb, ms
+# xml 1.0 spec, chromium and firefox accept these, plus lots of unicode chars
+valid_attr_regex = new RegExp '^[a-zA-Z_:][-a-zA-Z0-9_:.]*$'
+# html5 spec is much more lax, but chromium won't let me make at attribute with the name "4"
+js_attr_regex = new RegExp '^[oO][nN].'
+
debug_dot_at = (doc, x, y) ->
return # disabled
el = doc.createElement 'div'
ret += '@keyframes blink {'
ret += 'to { visibility: hidden; }'
ret += '}'
+ ret += '.ann_box {'
+ ret += 'z-index: 5;'
+ ret += 'position: absolute;'
+ ret += 'border: 1px solid rgba(0,0,0,0.1);'
+ ret += 'outline: 1px solid rgba(255,255,255,0.1);' # in case there's a black background
+ ret += '}'
+ ret += '.ann_tag {'
+ ret += 'z-index: 10;'
+ ret += 'position: absolute;'
+ ret += 'font-size: 8px;'
+ ret += 'white-space: pre;'
+ ret += 'background: rgba(255,255,255,0.4);'
+ ret += '}'
return ret
-# key codes:
+
+ignore_key_codes =
+ '18': true # alt
+ '20': true # capslock
+ '17': true # ctrl
+ '144': true # numlock
+ '16': true # shift
+ '91': true # windows "start" key
+# key codes: (valid on keydown, not keypress)
KEY_LEFT = 37
KEY_UP = 38
KEY_RIGHT = 39
KEY_PAGE_UP = 33
KEY_PAGE_DOWN = 34
KEY_TAB = 9
-
-ignore_key_codes =
- '18': true # alt
- '20': true # capslock
- '17': true # ctrl
- '144': true # numlock
- '16': true # shift
- '91': true # windows "start" key
control_key_codes = # we react to these, but they aren't typing
'37': KEY_LEFT
'38': KEY_UP
if c.name in ['script', 'object', 'iframe', 'link']
# TODO put placeholders instead
remove.unshift i
+ continue
# TODO create in correct namespace
c.el = parent.ownerDocument.createElement c.name
for k, v of c.attrs
# FIXME if attr_whitelist[k]?
- c.el.setAttribute k, v
+ if valid_attr_regex.test k
+ unless js_attr_regex.test k
+ c.el.setAttribute k, v
parent.appendChild c.el
if c.children.length
instantiate_tree c.children, c.el
new_cursor = find_loc_cursor_position @tree, xy
if new_cursor?
@move_cursor new_cursor
+ else
+ @kill_cursor()
return false
ondoubleclick: (e) ->
return false
onkeypress: (e) ->
return if e.ctrlKey
return false if ignore_key_codes[e.keyCode]?
- return false if control_key_codes[e.keyCode]? # handled in keydown
+ # return false if control_key_codes[e.keyCode]? # handled in keydown
char = e.charCode ? e.keyCode
if char and @cursor?
char = String.fromCharCode char
@overlay.appendChild @cursor_el
@cursor_visible = true
@cursor_el.style.left = "#{loc.x + overlay_padding - 1}px"
- @cursor_el.style.top = "#{loc.y + overlay_padding}px"
+ if loc.h < 5
+ height = 12
+ else
+ height = loc.h
+ @cursor_el.style.top = "#{loc.y + overlay_padding + Math.round(height * .07)}px"
+ @cursor_el.style.height = "#{Math.round height * 0.82}px"
@matt cursor[0]
matt: (n) ->
while @matting.length > 0
if bounds.x is prev_bounds.x and bounds.y is prev_bounds.y and bounds.w is prev_bounds.w and bounds.h is prev_bounds.h
n = n.parent
continue
- matt = domify @outer_idoc, div: style: "position: absolute; left: #{bounds.x - 1 + overlay_padding}px; top: #{bounds.y - 1 + overlay_padding}px; width: #{bounds.w}px; height: #{bounds.h}px; outline: 1000px solid rgba(0,153,255,#{alpha}); border: 1px solid rgba(0,0,0,.1)"
+ matt = domify @outer_idoc, div: class: 'ann_box', style: "left: #{bounds.x - 1 + overlay_padding}px; top: #{bounds.y - 2 + overlay_padding}px; width: #{bounds.w}px; height: #{bounds.h}px" # outline: 1000px solid rgba(0,153,255,#{alpha});
@overlay.appendChild matt
@matting.push matt
- ann = domify @outer_idoc, div: style: "position: absolute; left: #{bounds.x - 2 + overlay_padding}px; top: #{bounds.y - 6 + overlay_padding}px; font-size: 8px", children: [domify @outer_idoc, text: "<#{n.name}>"]
+ ann = domify @outer_idoc, div: class: 'ann_tag', style: "left: #{bounds.x + 1 + overlay_padding}px; top: #{bounds.y - 7 + overlay_padding}px", children: [domify @outer_idoc, text: " #{n.name} "]
@overlay.appendChild ann
@matting.push ann
n = n.parent