|
|
@@ -3,7 +3,7 @@ if (typeof window === 'undefined') {
|
|
|
}
|
|
|
|
|
|
// Copy from https://github.com/primetwig/react-nestable/blob/dacea9dc191399a3520f5dc7623f5edebc83e7b7/dist/utils.js
|
|
|
-export var closest = function closest (target, selector) {
|
|
|
+export const closest = (target, selector) => {
|
|
|
// closest(e.target, '.field')
|
|
|
while (target) {
|
|
|
if (target.matches && target.matches(selector)) return target
|
|
|
@@ -12,41 +12,42 @@ export var closest = function closest (target, selector) {
|
|
|
return null
|
|
|
}
|
|
|
|
|
|
-export var getOffsetRect = function getOffsetRect (elem) {
|
|
|
+export const getOffsetRect = (elem) => {
|
|
|
// (1)
|
|
|
- var box = elem.getBoundingClientRect()
|
|
|
+ const box = elem.getBoundingClientRect(),
|
|
|
+ body = document.body,
|
|
|
+ docElem = document.documentElement,
|
|
|
+ // (2)
|
|
|
+ scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop,
|
|
|
+ scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft,
|
|
|
|
|
|
- var body = document.body
|
|
|
- var docElem = document.documentElement
|
|
|
+ // (3)
|
|
|
+ clientTop = docElem.clientTop || body.clientTop || 0,
|
|
|
+ clientLeft = docElem.clientLeft || body.clientLeft || 0,
|
|
|
|
|
|
- // (2)
|
|
|
- var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop
|
|
|
- var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft
|
|
|
+ // (4)
|
|
|
+ top = box.top + scrollTop - clientTop,
|
|
|
+ left = box.left + scrollLeft - clientLeft;
|
|
|
|
|
|
- // (3)
|
|
|
- var clientTop = docElem.clientTop || body.clientTop || 0
|
|
|
- var clientLeft = docElem.clientLeft || body.clientLeft || 0
|
|
|
-
|
|
|
- // (4)
|
|
|
- var top = box.top + scrollTop - clientTop
|
|
|
- var left = box.left + scrollLeft - clientLeft
|
|
|
-
|
|
|
- return { top: Math.round(top), left: Math.round(left) }
|
|
|
+ return {
|
|
|
+ top: Math.round(top),
|
|
|
+ left: Math.round(left)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// jquery focus
|
|
|
-export var focus = function (elem) {
|
|
|
+export const focus = (elem) => {
|
|
|
return elem === document.activeElement &&
|
|
|
document.hasFocus() &&
|
|
|
!!(elem.type || elem.href || ~elem.tabIndex)
|
|
|
}
|
|
|
|
|
|
// copied from https://stackoverflow.com/a/32180863
|
|
|
-export var timeConversion = function (millisec) {
|
|
|
- var seconds = (millisec / 1000).toFixed(0)
|
|
|
- var minutes = (millisec / (1000 * 60)).toFixed(0)
|
|
|
- var hours = (millisec / (1000 * 60 * 60)).toFixed(1)
|
|
|
- var days = (millisec / (1000 * 60 * 60 * 24)).toFixed(1)
|
|
|
+export const timeConversion = (millisec) => {
|
|
|
+ let seconds = (millisec / 1000).toFixed(0),
|
|
|
+ minutes = (millisec / (1000 * 60)).toFixed(0),
|
|
|
+ hours = (millisec / (1000 * 60 * 60)).toFixed(1),
|
|
|
+ days = (millisec / (1000 * 60 * 60 * 24)).toFixed(1);
|
|
|
|
|
|
if (seconds < 60) {
|
|
|
return seconds + 's'
|
|
|
@@ -59,7 +60,7 @@ export var timeConversion = function (millisec) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-export var getSelectionText = function () {
|
|
|
+export const getSelectionText = () => {
|
|
|
const selection = (window.getSelection() || '').toString().trim()
|
|
|
if (selection) {
|
|
|
return selection
|
|
|
@@ -79,7 +80,7 @@ export var getSelectionText = function () {
|
|
|
|
|
|
// Modified from https://github.com/GoogleChromeLabs/browser-nativefs
|
|
|
// because shadow-cljs doesn't handle this babel transform
|
|
|
-export var getFiles = async function (dirHandle, recursive, cb, path = dirHandle.name) {
|
|
|
+export const getFiles = async (dirHandle, recursive, cb, path = dirHandle.name) => {
|
|
|
const dirs = []
|
|
|
const files = []
|
|
|
for await (const entry of dirHandle.values()) {
|
|
|
@@ -88,30 +89,28 @@ export var getFiles = async function (dirHandle, recursive, cb, path = dirHandle
|
|
|
cb(nestedPath, entry)
|
|
|
files.push(
|
|
|
entry.getFile().then((file) => {
|
|
|
- Object.defineProperty(file, 'webkitRelativePath', {
|
|
|
- configurable: true,
|
|
|
- enumerable: true,
|
|
|
- get: () => nestedPath,
|
|
|
- })
|
|
|
- Object.defineProperty(file, 'handle', {
|
|
|
- configurable: true,
|
|
|
- enumerable: true,
|
|
|
- get: () => entry,
|
|
|
- })
|
|
|
- return file
|
|
|
- }
|
|
|
- )
|
|
|
+ Object.defineProperty(file, 'webkitRelativePath', {
|
|
|
+ configurable: true,
|
|
|
+ enumerable: true,
|
|
|
+ get: () => nestedPath,
|
|
|
+ })
|
|
|
+ Object.defineProperty(file, 'handle', {
|
|
|
+ configurable: true,
|
|
|
+ enumerable: true,
|
|
|
+ get: () => entry,
|
|
|
+ })
|
|
|
+ return file
|
|
|
+ })
|
|
|
)
|
|
|
} else if (entry.kind === 'directory' && recursive) {
|
|
|
cb(nestedPath, entry)
|
|
|
dirs.push(getFiles(entry, recursive, cb, nestedPath))
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
return [(await Promise.all(dirs)), (await Promise.all(files))]
|
|
|
}
|
|
|
|
|
|
-export var verifyPermission = async function (handle, readWrite) {
|
|
|
+export const verifyPermission = async (handle, readWrite) => {
|
|
|
const options = {}
|
|
|
if (readWrite) {
|
|
|
options.mode = 'readwrite'
|
|
|
@@ -130,14 +129,16 @@ export var verifyPermission = async function (handle, readWrite) {
|
|
|
|
|
|
// NOTE: Need externs to prevent `options.recursive` been munged
|
|
|
// When building with release.
|
|
|
-export var openDirectory = async function (options = {}, cb) {
|
|
|
+export const openDirectory = async (options = {}, cb) => {
|
|
|
options.recursive = options.recursive || false;
|
|
|
- const handle = await window.showDirectoryPicker({ mode: 'readwrite' });
|
|
|
+ const handle = await window.showDirectoryPicker({
|
|
|
+ mode: 'readwrite'
|
|
|
+ });
|
|
|
const _ask = await verifyPermission(handle, true);
|
|
|
return [handle, getFiles(handle, options.recursive, cb)];
|
|
|
};
|
|
|
|
|
|
-export var writeFile = async function (fileHandle, contents) {
|
|
|
+export const writeFile = async (fileHandle, contents) => {
|
|
|
// Create a FileSystemWritableFileStream to write to.
|
|
|
const writable = await fileHandle.createWritable()
|
|
|
|
|
|
@@ -151,7 +152,7 @@ export var writeFile = async function (fileHandle, contents) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-export var nfsSupported = function () {
|
|
|
+export const nfsSupported = () => {
|
|
|
if ('chooseFileSystemEntries' in self) {
|
|
|
return 'chooseFileSystemEntries'
|
|
|
} else if ('showOpenFilePicker' in self) {
|
|
|
@@ -172,7 +173,9 @@ export const triggerInputChange = (node, value = '', name = 'change') => {
|
|
|
if (inputTypes.indexOf(node.__proto__.constructor) > -1) {
|
|
|
|
|
|
const setValue = Object.getOwnPropertyDescriptor(node.__proto__, 'value').set
|
|
|
- const event = new Event('change', { bubbles: true })
|
|
|
+ const event = new Event('change', {
|
|
|
+ bubbles: true
|
|
|
+ })
|
|
|
|
|
|
setValue.call(node, value)
|
|
|
node.dispatchEvent(event)
|
|
|
@@ -182,7 +185,7 @@ export const triggerInputChange = (node, value = '', name = 'change') => {
|
|
|
// Copied from https://github.com/google/diff-match-patch/issues/29#issuecomment-647627182
|
|
|
export const reversePatch = patch => {
|
|
|
return patch.map(patchObj => ({
|
|
|
- diffs: patchObj.diffs.map(([ op, val ]) => [
|
|
|
+ diffs: patchObj.diffs.map(([op, val]) => [
|
|
|
op * -1, // The money maker
|
|
|
val
|
|
|
]),
|
|
|
@@ -196,30 +199,33 @@ export const reversePatch = patch => {
|
|
|
// Copied from https://github.com/sindresorhus/path-is-absolute/blob/main/index.js
|
|
|
export const win32 = path => {
|
|
|
// https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56
|
|
|
- var splitDeviceRe = /^([a-zA-Z]:|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)?([\\/])?([\s\S]*?)$/;
|
|
|
- var result = splitDeviceRe.exec(path);
|
|
|
- var device = result[1] || '';
|
|
|
- var isUnc = Boolean(device && device.charAt(1) !== ':');
|
|
|
+ const splitDeviceRe = /^([a-zA-Z]:|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)?([\\/])?([\s\S]*?)$/,
|
|
|
+ result = splitDeviceRe.exec(path),
|
|
|
+ device = result[1] || '',
|
|
|
+ isUnc = Boolean(device && device.charAt(1) !== ':');
|
|
|
|
|
|
// UNC paths are always absolute
|
|
|
return Boolean(result[2] || isUnc);
|
|
|
};
|
|
|
|
|
|
-export const ios = function () {
|
|
|
+export const ios = () => {
|
|
|
return [
|
|
|
- 'iPad Simulator',
|
|
|
- 'iPhone Simulator',
|
|
|
- 'iPod Simulator',
|
|
|
- 'iPad',
|
|
|
- 'iPhone',
|
|
|
- 'iPod'
|
|
|
- ].includes(navigator.platform)
|
|
|
- // iPad on iOS 13 detection
|
|
|
- || (navigator.userAgent.includes("Mac") && "ontouchend" in document)
|
|
|
+ 'iPad Simulator',
|
|
|
+ 'iPhone Simulator',
|
|
|
+ 'iPod Simulator',
|
|
|
+ 'iPad',
|
|
|
+ 'iPhone',
|
|
|
+ 'iPod'
|
|
|
+ ].includes(navigator.platform)
|
|
|
+ // iPad on iOS 13 detection
|
|
|
+ ||
|
|
|
+ (navigator.userAgent.includes("Mac") && "ontouchend" in document)
|
|
|
}
|
|
|
|
|
|
-export const getClipText = function (cb, errorHandler) {
|
|
|
- navigator.permissions.query({ name: "clipboard-read" }).then((result) => {
|
|
|
+export const getClipText = (cb, errorHandler) => {
|
|
|
+ navigator.permissions.query({
|
|
|
+ name: "clipboard-read"
|
|
|
+ }).then((result) => {
|
|
|
if (result.state == "granted" || result.state == "prompt") {
|
|
|
navigator.clipboard.readText()
|
|
|
.then(text => {
|
|
|
@@ -232,21 +238,31 @@ export const getClipText = function (cb, errorHandler) {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-export const writeClipboard = function(text, isHtml) {
|
|
|
- if (isHtml) {
|
|
|
- var blob = new Blob([text], {type:["text/plain", "text/html"]})
|
|
|
- var data = [new ClipboardItem({["text/plain"]: blob, ["text/html"]:blob})];
|
|
|
- } else{
|
|
|
- var blob = new Blob([text], {type:["text/plain"]})
|
|
|
- var data = [new ClipboardItem({["text/plain"]: blob})];
|
|
|
- }
|
|
|
- navigator.permissions.query({ name: "clipboard-write" }).then((result) => {
|
|
|
- if (result.state == "granted" || result.state == "prompt") {
|
|
|
- navigator.clipboard.write(data).then(function() {
|
|
|
- /* success */
|
|
|
- }, function(e) {
|
|
|
- console.log(e, "fail")
|
|
|
- })
|
|
|
- }
|
|
|
+export const writeClipboard = (text, isHtml) => {
|
|
|
+ let blob = new Blob([text], {
|
|
|
+ type: ["text/plain"]
|
|
|
+ });
|
|
|
+ let data = [new ClipboardItem({
|
|
|
+ ["text/plain"]: blob
|
|
|
+ })];
|
|
|
+ if (isHtml) {
|
|
|
+ blob = new Blob([text], {
|
|
|
+ type: ["text/plain", "text/html"]
|
|
|
})
|
|
|
-}
|
|
|
+ data = [new ClipboardItem({
|
|
|
+ ["text/plain"]: blob,
|
|
|
+ ["text/html"]: blob
|
|
|
+ })];
|
|
|
+ }
|
|
|
+ navigator.permissions.query({
|
|
|
+ name: "clipboard-write"
|
|
|
+ }).then((result) => {
|
|
|
+ if (result.state == "granted" || result.state == "prompt") {
|
|
|
+ navigator.clipboard.write(data).then(() => {
|
|
|
+ /* success */
|
|
|
+ }).catch(e => {
|
|
|
+ console.log(e, "fail")
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|