98 lines
3.2 KiB
JavaScript
Executable File
98 lines
3.2 KiB
JavaScript
Executable File
import { ie, ios } from "./browser.js"
|
|
|
|
export function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
|
|
|
|
export let rmClass = function(node, cls) {
|
|
let current = node.className
|
|
let match = classTest(cls).exec(current)
|
|
if (match) {
|
|
let after = current.slice(match.index + match[0].length)
|
|
node.className = current.slice(0, match.index) + (after ? match[1] + after : "")
|
|
}
|
|
}
|
|
|
|
export function removeChildren(e) {
|
|
for (let count = e.childNodes.length; count > 0; --count)
|
|
e.removeChild(e.firstChild)
|
|
return e
|
|
}
|
|
|
|
export function removeChildrenAndAdd(parent, e) {
|
|
return removeChildren(parent).appendChild(e)
|
|
}
|
|
|
|
export function elt(tag, content, className, style) {
|
|
let e = document.createElement(tag)
|
|
if (className) e.className = className
|
|
if (style) e.style.cssText = style
|
|
if (typeof content == "string") e.appendChild(document.createTextNode(content))
|
|
else if (content) for (let i = 0; i < content.length; ++i) e.appendChild(content[i])
|
|
return e
|
|
}
|
|
// wrapper for elt, which removes the elt from the accessibility tree
|
|
export function eltP(tag, content, className, style) {
|
|
let e = elt(tag, content, className, style)
|
|
e.setAttribute("role", "presentation")
|
|
return e
|
|
}
|
|
|
|
export let range
|
|
if (document.createRange) range = function(node, start, end, endNode) {
|
|
let r = document.createRange()
|
|
r.setEnd(endNode || node, end)
|
|
r.setStart(node, start)
|
|
return r
|
|
}
|
|
else range = function(node, start, end) {
|
|
let r = document.body.createTextRange()
|
|
try { r.moveToElementText(node.parentNode) }
|
|
catch(e) { return r }
|
|
r.collapse(true)
|
|
r.moveEnd("character", end)
|
|
r.moveStart("character", start)
|
|
return r
|
|
}
|
|
|
|
export function contains(parent, child) {
|
|
if (child.nodeType == 3) // Android browser always returns false when child is a textnode
|
|
child = child.parentNode
|
|
if (parent.contains)
|
|
return parent.contains(child)
|
|
do {
|
|
if (child.nodeType == 11) child = child.host
|
|
if (child == parent) return true
|
|
} while (child = child.parentNode)
|
|
}
|
|
|
|
export function activeElt() {
|
|
// IE and Edge may throw an "Unspecified Error" when accessing document.activeElement.
|
|
// IE < 10 will throw when accessed while the page is loading or in an iframe.
|
|
// IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable.
|
|
let activeElement
|
|
try {
|
|
activeElement = document.activeElement
|
|
} catch(e) {
|
|
activeElement = document.body || null
|
|
}
|
|
while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
|
|
activeElement = activeElement.shadowRoot.activeElement
|
|
return activeElement
|
|
}
|
|
|
|
export function addClass(node, cls) {
|
|
let current = node.className
|
|
if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls
|
|
}
|
|
export function joinClasses(a, b) {
|
|
let as = a.split(" ")
|
|
for (let i = 0; i < as.length; i++)
|
|
if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]
|
|
return b
|
|
}
|
|
|
|
export let selectInput = function(node) { node.select() }
|
|
if (ios) // Mobile Safari apparently has a bug where select() is broken.
|
|
selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length }
|
|
else if (ie) // Suppress mysterious IE10 errors
|
|
selectInput = function(node) { try { node.select() } catch(_e) {} }
|