|
var getPositionedAncestor = (node, root=node.ownerDocument.body) => { |
|
var element = node.nodeType === Node.ELEMENT_NODE |
|
? node |
|
: node.parentElement |
|
|
|
while (element != root) { |
|
if (getComputedStyle(element).position != 'static') { |
|
return element |
|
} else { |
|
element = element.parentElement |
|
} |
|
} |
|
return element || root |
|
} |
|
|
|
|
|
var setRect = ({style}, {top, left, height, width}) => { |
|
style.top = `${top}px`; |
|
style.left = `${left}px`; |
|
style.height = `${height}px`; |
|
style.width = `${width}px`; |
|
} |
|
|
|
|
|
var SVG = class SVG { |
|
static createElement(document, name) { |
|
return document.createElementNS('http://www.w3.org/2000/svg', name) |
|
} |
|
} |
|
|
|
var mark = (container, range) => { |
|
const document = container.ownerDocument |
|
const selection = document.createElement('article') |
|
selection.className = 'selection' |
|
selection.style.position = 'absolute' |
|
selection.style.pointerEvents = 'none' |
|
selection.style.opacity = '0.3' |
|
selection.style.width = '100%' |
|
selection.style.height = '100%' |
|
selection.style.zIndex = '99998' |
|
selection.style.top = '0' |
|
selection.style.left = '0' |
|
|
|
|
|
|
|
var rects = range.getClientRects() |
|
var offset = container.getBoundingClientRect() |
|
|
|
for (let {left, top, height, width} of rects) { |
|
const range = document.createElement('section') |
|
|
|
range.style.position = 'absolute' |
|
range.style.backgroundColor = 'yellow' |
|
range.style.left = `${left - offset.left}px` |
|
range.style.top = `${top - offset.top}px` |
|
range.style.height = `${height}px` |
|
range.style.width = `${width}px` |
|
|
|
selection.appendChild(range) |
|
} |
|
|
|
container.appendChild(selection) |
|
} |
|
|
|
var getRect = (element) => { |
|
const document = element.ownerDocument |
|
const {body, documentElement} = document |
|
|
|
const scrollTop |
|
= 0 |
|
+ (body ? body.scrollTop : 0) |
|
+ (documentElement ? documentElement.scrollTop : 0) |
|
|
|
const scrollLeft |
|
= 0 |
|
+ (body ? body.scrollLeft : 0) |
|
+ (documentElement ? documentElement.scrollLeft : 0) |
|
|
|
const {top, left, height, width} = element.getBoundingClientRect(); |
|
|
|
return { |
|
top: top + scrollTop, |
|
left: left + scrollLeft, |
|
height, |
|
width |
|
} |
|
} |
|
|
|
var highlight = (range) => |
|
mark(getPositionedAncestor(range.commonAncestorContainer), range) |
|
|
|
|
|
highlight(document.getSelection().getRangeAt(0)) |
This is a good idea, but the highlights are a bit opaque. Is there a better way than wrapping tags, like tags?