UNPKG

solid-ui

Version:

UI library for writing Solid read-write-web applications

237 lines (226 loc) • 10.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ACLControlBox5 = ACLControlBox5; exports.handleDrop = handleDrop; exports.preventBrowserDropEvents = preventBrowserDropEvents; exports.preventDrag = preventDrag; exports.setGlobalWindow = setGlobalWindow; exports.shortNameForFolder = shortNameForFolder; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var ns = _interopRequireWildcard(require("../ns")); var utils = _interopRequireWildcard(require("../utils")); var _acl = require("./acl"); var _accessController = require("./access-controller"); var style = _interopRequireWildcard(require("../style")); var _debug = require("../debug"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); } /** * Functions for rendering the ACL User Interface. * See https://github.com/solidos/userguide/blob/main/views/sharing/userguide.md#view * for a screenshot. * @packageDocumentation */ var global = window; var preventBrowserDropEventsDone = Symbol('prevent double triggering of drop event'); /** * See https://coshx.com/preventing-drag-and-drop-disasters-with-a-chrome-userscript * Without this dropping anything onto a browser page will cause chrome etc to jump to diff page * throwing away all the user's work. * * In apps which may use drag and drop, this utility takes care of the fact * by default in a browser, an uncaught user drop into a browser window * causes the browser to lose all its work in that window and navigate to another page * * @param document The DOM * @returns void */ function preventBrowserDropEvents(document) { (0, _debug.log)('preventBrowserDropEvents called.'); if (typeof global !== 'undefined') { if (global[preventBrowserDropEventsDone]) return; global[preventBrowserDropEventsDone] = true; } document.addEventListener('drop', handleDrop, false); document.addEventListener('dragenter', preventDrag, false); document.addEventListener('dragover', preventDrag, false); } /** @internal */ function preventDrag(e) { e.stopPropagation(); e.preventDefault(); } /** @internal */ function handleDrop(e) { if (e.dataTransfer.files.length > 0) { if (!global.confirm('Are you sure you want to drop this file here? (Cancel opens it in a new tab)')) { e.stopPropagation(); e.preventDefault(); (0, _debug.log)('@@@@ document-level DROP suppressed: ' + e.dataTransfer.dropEffect); } } } /** * Get a folder's own filename in the directory tree. Also works for * domain names; the URL protocol ('https://') acts as the tree root * with short name '/' (see also test/unit/acl/acl-control.test.ts). * * ```typescript * shortNameForFolder($rdf.namedNode('http://example.com/some/folder/')) * // 'folder' * * shortNameForFolder($rdf.namedNode('http://example.com/some/folder')) * // 'folder' * * shortNameForFolder($rdf.namedNode('http://example.com/')) * // 'example.com' * * shortNameForFolder($rdf.namedNode('http://example.com')) * // 'example.com' * * shortNameForFolder($rdf.namedNode('http://')) * // '/' * ``` * * It also works with relative URLs: * ```typescript * shortNameForFolder($rdf.namedNode('../folder/')) * // 'folder' * ``` * * @param x RDF Node for the folder URL * @returns Short name for the folder */ function shortNameForFolder(x) { var str = x.uri; // Strip the trailing slash if (str.slice(-1) === '/') { str = str.slice(0, -1); } // Remove the path if present, keeping only the part // after the last slash. var slash = str.lastIndexOf('/'); if (slash >= 0) { str = str.slice(slash + 1); } // Return the folder's filename, or '/' if nothing found // (but see https://github.com/solidos/solid-ui/issues/196 // regarding whether this happens at the domain root or // not) return str || '/'; } /** * A wrapper that retrieves ACL data and uses it * to render an [[AccessController]] component. * Presumably the '5' is a version number of some sort, * but all we know is it was already called ACLControlBox5 * when it was introduced into solid-ui in * https://github.com/solidos/solid-ui/commit/948b874bd93e7bf5160e6e224821b888f07d15f3#diff-4192a29f38a0ababd563b36b47eba5bbR54 */ function ACLControlBox5(subject, context, noun, kb) { var dom = context.dom; var doc = subject.doc(); // The ACL is actually to the doc describing the thing var container = dom.createElement('div'); container.setAttribute('style', style.aclControlBoxContainer); var header = container.appendChild(dom.createElement('h1')); header.textContent = "Sharing for ".concat(noun, " ").concat(utils.label(subject)); header.setAttribute('style', style.aclControlBoxHeader); var status = container.appendChild(dom.createElement('div')); status.setAttribute('style', style.aclControlBoxStatus); try { loadController(doc, kb, subject, noun, context, dom, status).then(function (controller) { return container.appendChild(controller.render()); }); } catch (error) { status.innerText = error; } return container; } function loadController(_x, _x2, _x3, _x4, _x5, _x6, _x7) { return _loadController.apply(this, arguments); } function _loadController() { _loadController = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2(doc, kb, subject, noun, context, dom, status) { return _regenerator["default"].wrap(function (_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: return _context2.abrupt("return", new Promise(function (resolve, reject) { return (0, _acl.getACLorDefault)(doc, /*#__PURE__*/function () { var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(ok, isDirectACL, targetDoc, targetACLDoc, defaultHolder, defaultACLDoc) { var targetDirectory, targetIsProtected, prospectiveDefaultHolder, getController, _t; return _regenerator["default"].wrap(function (_context) { while (1) switch (_context.prev = _context.next) { case 0: getController = function _getController(prospectiveDefaultHolder) { return new _accessController.AccessController(subject, noun, context, status, targetIsProtected, targetDoc, targetACLDoc, defaultHolder, defaultACLDoc, prospectiveDefaultHolder, kb, dom); }; if (ok) { _context.next = 1; break; } return _context.abrupt("return", reject(new Error("Error reading ".concat(isDirectACL ? '' : ' default ', "ACL. status ").concat(targetDoc, ": ").concat(targetACLDoc)))); case 1: targetDirectory = getDirectory(targetDoc); targetIsProtected = isStorage(targetDoc, targetACLDoc, kb) || hasProtectedAcl(targetDoc); if (!(!targetIsProtected && targetDirectory)) { _context.next = 5; break; } _context.prev = 2; _context.next = 3; return (0, _acl.getProspectiveHolder)(targetDirectory); case 3: prospectiveDefaultHolder = _context.sent; return _context.abrupt("return", resolve(getController(prospectiveDefaultHolder))); case 4: _context.prev = 4; _t = _context["catch"](2); // No need to show this error in status, but good to warn about it in console (0, _debug.warn)(_t); case 5: return _context.abrupt("return", resolve(getController())); case 6: case "end": return _context.stop(); } }, _callee, null, [[2, 4]]); })); return function (_x8, _x9, _x0, _x1, _x10, _x11) { return _ref.apply(this, arguments); }; }()); })); case 1: case "end": return _context2.stop(); } }, _callee2); })); return _loadController.apply(this, arguments); } function getDirectory(doc) { var str = doc.uri.split('#')[0]; var p = str.slice(0, -1).lastIndexOf('/'); var q = str.indexOf('//'); return q >= 0 && p < q + 2 || p < 0 ? null : str.slice(0, p + 1); } function isStorage(doc, aclDoc, store) { // @@ TODO: The methods used for targetIsStorage are HACKs - it should not be relied upon, and work is // @@ underway to standardize a behavior that does not rely upon this hack // @@ hopefully fixed as part of https://github.com/solidos/data-interoperability-panel/issues/10 return store.holds(doc, ns.rdf('type'), ns.space('Storage'), aclDoc); } function hasProtectedAcl(targetDoc) { // @@ TODO: This is hacky way of knowing whether or not a certain ACL file can be removed // Hopefully we'll find a better, standardized solution to this - https://github.com/solidos/specification/issues/37 return targetDoc.uri === targetDoc.site().uri; } /** @internal */ function setGlobalWindow(window) { global = window; } //# sourceMappingURL=acl-control.js.map