# SETTINGS
overlay_padding = 10
-TYPE_TAG = peach_parser.TYPE_TAG
-TYPE_TEXT = peach_parser.TYPE_TEXT
-TYPE_COMMENT = peach_parser.TYPE_COMMENT
-TYPE_DOCTYPE = peach_parser.TYPE_DOCTYPE
-
timeout = (ms, cb) -> return setTimeout cb, ms
+# xml 1.0 says:
+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:
remove = []
for c, i in tree
switch c.type
- when TYPE_TEXT
+ when 'text'
c.el = parent.ownerDocument.createTextNode c.text
parent.appendChild c.el
- when TYPE_TAG
+ when 'tag'
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
return done
find_next_cursor_position = (tree, n, i) ->
- if n.type is TYPE_TEXT and n.text.length > i
+ if n.type is 'text' and n.text.length > i
orig_xyh = cursor_to_xyh n, i
unless orig_xyh?
console.log "ERROR: couldn't find xy for current cursor location"
state_before = true
found = null
traverse_tree tree, (node, state) ->
- if node.type is TYPE_TEXT and state_before is false
+ if node.type is 'text' and state_before is false
if cursor_to_xyh(node, 0)?
found = node
return true
return null
find_prev_cursor_position = (tree, n, i) ->
- if n? and n.type is TYPE_TEXT and i > 0
+ if n? and n.type is 'text' and i > 0
orig_xyh = cursor_to_xyh n, i
unless orig_xyh?
console.log "ERROR: couldn't find xy for current cursor location"
found_prev = n?
found = null
traverse_tree tree, (node) ->
- if node.type is TYPE_TEXT
+ if node.type is 'text'
if node is n
if found_prev?
found = found_prev
if found?
if cursor_to_xyh found, found.text.length # text visible?
return [found, found.text.length]
- return find_prev_cursor_position tree, ret[0], 0
+ return find_prev_cursor_position tree, found, 0
return null
find_loc_cursor_position = (tree, loc) ->
for c in tree
- if c.type is TYPE_TAG or c.type is TYPE_TEXT
+ if c.type is 'tag' or c.type is 'text'
bounds = get_el_bounds c.el
continue if loc.x < bounds.x
continue if loc.x > bounds.x + bounds.w
if c.children.length
ret = find_loc_cursor_position c.children, loc
return ret if ret?
- if c.type is TYPE_TEXT
+ if c.type is 'text'
# click is within bounding box that contains all text.
return [c, 0] if c.text.length is 0
before_i = 0
tree_remove_empty_text_nodes = (tree) ->
empties = []
traverse_tree tree, (n) ->
- if n.type is TYPE_TEXT
+ if n.type is 'text'
if n.text.length is 0
empties.unshift n
return false
for n in empties
# don't completely empty the tree
if tree.length is 1
- if tree[0].type is TYPE_TEXT
+ if tree[0].type is 'text'
console.log "oop, leaving a blank node because it's the only thing"
return
n.el.parentNode.removeChild n.el
iterate = (tree, cb) ->
for n in tree
- if n.type is TYPE_TEXT
+ if n.type is 'text'
i = 0
while i < n.text.length # don't foreach, cb might remove chars
advance = cb n, i
if advance
i += 1
- if n.type is TYPE_TAG
+ if n.type is 'tag'
block = is_display_block n.el
if block
cb null
prev_bounds = x: 0, y: 0, w: 0, h: 0
alpha = 0.1
while n?.el?
- if n.type is TYPE_TEXT
+ if n.type is 'text'
n = n.parent
continue
bounds = get_el_bounds n.el
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
inner_flags = want_nl: true
is_br = false
switch n.type
- when TYPE_TAG
+ when 'tag'
if n.name is 'br'
is_br = true
is_text = false
inner_flags.block = true
is_block = true
in_flow_block = in_flow
- when TYPE_TEXT
+ when 'text'
is_text = true
is_block = false
in_flow = true
in_flow_block = false
- else # TYPE_COMMENT, TYPE_DOCTYPE
+ else # 'comment', 'doctype'
is_text = false
is_block = false
in_flow = false
ret += "\n"
ret += indent
switch n.type
- when TYPE_TAG
+ when 'tag'
ret += '<' + n.name
attr_keys = []
for k of n.attrs
if n.children.length
ret += @pretty_html n.children, next_indent, inner_flags
ret += "</#{n.name}>"
- when TYPE_TEXT
+ when 'text'
ret += enc_text n.text
- when TYPE_COMMENT
+ when 'comment'
ret += "<!--#{n.text}-->" # TODO encode?
- when TYPE_DOCTYPE
+ when 'doctype'
ret += "<!DOCTYPE #{n.name}"
if n.public_identifier? and n.public_identifier.length > 0
ret += " \"#{n.public_identifier}\""