mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-24 14:46:48 +09:00
Hello world
First open source release of Campfire 🎉
This commit is contained in:
commit
df76a227dc
664 files changed
+36235
No files matched your search
@@ -0,0 +1,103 @@
|
||||
export function generateUUID() {
|
||||
const template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
|
||||
return template.replace(/[xy]/g, function(char) {
|
||||
const rand = (Math.random() * 16) | 0
|
||||
const value = char === "x" ? rand : ((rand & 0x3)|0x8)
|
||||
return value.toString(16)
|
||||
})
|
||||
}
|
||||
|
||||
export function synchronize(fn) {
|
||||
const monitorCallbacks = new WeakMap
|
||||
return function(callback) {
|
||||
let callbacks = monitorCallbacks.get(this)
|
||||
if (!callbacks) {
|
||||
monitorCallbacks.set(this, (callbacks = []))
|
||||
}
|
||||
callbacks.push(callback)
|
||||
|
||||
if (callbacks.length === 1) {
|
||||
return fn.call(this, () => {
|
||||
Array.from(callbacks).forEach((callback) => { callback?.() })
|
||||
return monitorCallbacks.delete(this)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function transitionElementWithClass(element, className, callback) {
|
||||
return applyClassAwaitingEvent(element, className, "transitionend", callback)
|
||||
}
|
||||
|
||||
const applyClassAwaitingEvent = function(element, className, eventName, callback) {
|
||||
let timeout
|
||||
let uninstalled = false
|
||||
|
||||
const uninstall = function() {
|
||||
if (!uninstalled) {
|
||||
uninstalled = true
|
||||
element.removeEventListener(eventName, uninstall)
|
||||
return requestAnimationFrame(function() {
|
||||
element.classList.remove(className)
|
||||
return callback?.()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
element.addEventListener(eventName, uninstall)
|
||||
element.classList.add(className)
|
||||
|
||||
// Failsafe: If we don't receive a {transition,animation}end event
|
||||
// for some reason, ensure that uninstall is still called.
|
||||
const duration = getDuration(element, eventName)
|
||||
if (duration) {
|
||||
timeout = duration + 50
|
||||
} else {
|
||||
timeout = 50
|
||||
}
|
||||
|
||||
return setTimeout(uninstall, timeout)
|
||||
}
|
||||
|
||||
const getDuration = function(element, eventName) {
|
||||
const type = eventName === "animationend" ? "animation" : "transition"
|
||||
const duration = getComputedStyle(element)[`${type}Duration`]
|
||||
|
||||
if (duration) {
|
||||
if (/ms/.test(duration)) {
|
||||
return parseInt(duration, 10)
|
||||
} else {
|
||||
return parseFloat(duration) * 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getElementMargin(element) {
|
||||
const result = {}
|
||||
const style = window.getComputedStyle(element);
|
||||
|
||||
["Top", "Right", "Bottom", "Left"].forEach((side) => {
|
||||
result[side.toLowerCase()] = parseInt(style[`margin${side}`], 10)
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export function getAbsolutePositionForOffsets({ top, right, bottom, left }) {
|
||||
return {
|
||||
top: top + window.scrollY,
|
||||
right: right + window.scrollX,
|
||||
bottom: bottom + window.scrollY,
|
||||
left: left + window.scrollX
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function getViewportRect() {
|
||||
return {
|
||||
top: window.scrollY,
|
||||
right: window.scrollX + window.innerWidth,
|
||||
bottom: window.scrollY + window.innerHeight,
|
||||
left: window.scrollX
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user