diff --git a/package-lock.json b/package-lock.json index 482203dd..ee650dee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,23 +10,23 @@ "license": "MIT", "dependencies": { "@solid/better-simple-slideshow": "^0.1.0", - "activitystreams-pane": "1.0.3-4", - "chat-pane": "3.0.4-3", - "contacts-pane": "3.2.1-6", + "activitystreams-pane": "2.0.0-0", + "chat-pane": "4.0.0-0", + "contacts-pane": "4.0.0-0", "dompurify": "^3.4.4", - "folder-pane": "3.1.1-3", - "issue-pane": "3.0.3-1", + "folder-pane": "4.0.0-0", + "issue-pane": "4.0.0-0", "lit-html": "^3.3.2", "marked": "^18.0.3", - "meeting-pane": "3.0.3-1", + "meeting-pane": "4.0.0-0", "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", - "profile-pane": "3.2.3-4", + "pane-registry": "5.0.0-0", + "profile-pane": "4.0.0-0", "rdflib": "2.4.0", - "solid-logic": "4.0.8-3", + "solid-logic": "6.0.0-0", "solid-namespace": "^0.5.4", - "solid-ui": "3.1.3-17", - "source-pane": "3.1.1-7" + "solid-ui": "5.0.0-0", + "source-pane": "4.0.0-0" }, "devDependencies": { "@iconify/json": "2.2.494", @@ -123,9 +123,9 @@ "license": "MIT" }, "node_modules/@awesome.me/webawesome": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@awesome.me/webawesome/-/webawesome-3.11.0.tgz", - "integrity": "sha512-WM8kyP+AdAT3/zwNpc/YzN3Nu5pRD6ksREFZAct/DIn6KMnQs8lPVfiPbJrOpKMk8OaSnQX19iiwFGjoswXVXw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@awesome.me/webawesome/-/webawesome-3.12.0.tgz", + "integrity": "sha512-cO/vSvlyZqiki1upynxpk9q2N48U2+nflIj40OtCKYOs6ZXa4zXhW6+asXKOfeNw1AnD4nzsSIdZSt/Ti9QONA==", "license": "MIT", "dependencies": { "@ctrl/tinycolor": "4.1.0", @@ -2977,9 +2977,9 @@ } }, "node_modules/@marijn/find-cluster-break": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.3.tgz", - "integrity": "sha512-FY+MKLBoTsLNJF/eLWaOsXGdz6uh3Iu1axjPf6TUq92IYumcTcXWHoS747JARLkcdlJ/Waiaxc5wQfFO8jC6NA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.4.tgz", + "integrity": "sha512-Wy0V7+SGUjnF9/TkiM1hKVDPj7jKXduPNboMVtHTA8dySMURWqfg/JZ9E2Sq8JgSJmkl7k7Qe9FLeMSrSraWmQ==", "license": "MIT" }, "node_modules/@noble/curves": { @@ -3010,9 +3010,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.144.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.144.0.tgz", - "integrity": "sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==", + "version": "0.146.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.146.0.tgz", + "integrity": "sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" @@ -3060,10 +3060,26 @@ "@types/node": "*" } }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.5.tgz", + "integrity": "sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.4.tgz", - "integrity": "sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.5.tgz", + "integrity": "sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==", "cpu": [ "arm64" ], @@ -3077,9 +3093,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-Dc5mPD8F5F/FS8i01syd7FTF6yB2fVthH/TRkjwJkzUK6EpoxHtqvZQP5Zwq80/5z19TWYHIg1KOHboCgVx/aQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.5.tgz", + "integrity": "sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==", "cpu": [ "arm64" ], @@ -3093,9 +3109,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.4.tgz", - "integrity": "sha512-fpDm4oBo6SqLvWUYCmFhdde3U9KH2fRNNMeAnAPAIwxRL345xutL0EtEUcuoxsoazdJGv/MuDBQHlCDrtbvqOg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.5.tgz", + "integrity": "sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==", "cpu": [ "x64" ], @@ -3109,9 +3125,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.4.tgz", - "integrity": "sha512-rSJoreDE/HoIzoaib6MTp5jQtCTdMHKIvItAKT/ImS6Y6Ww76oUaeMyp4Vc/fAgd/ehji068IxetHXAnqUwN9A==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.5.tgz", + "integrity": "sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==", "cpu": [ "x64" ], @@ -3125,9 +3141,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.4.tgz", - "integrity": "sha512-/jm8OGHgn7oGaJu3i/qZI9spUGcJ+y/lk43ttQ/iO1tOd9NissG6o97bighBCiL+BKRngmcDuR6ikfwYdJmVuQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.5.tgz", + "integrity": "sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==", "cpu": [ "arm" ], @@ -3141,9 +3157,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.4.tgz", - "integrity": "sha512-tIP06BeD9EqvECBrPZ+sqdPlYrT+aYaAiu1wYziVx5elRK/ftm33JxVDy2bXGbr6J0CrtirCkR87/X5a2euEng==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.5.tgz", + "integrity": "sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==", "cpu": [ "arm64" ], @@ -3157,9 +3173,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.4.tgz", - "integrity": "sha512-Ql1Q0EQqVThvn9VAVlwNzsUvbSFtCMGjLpRRi4pk5i7NZZ4n5ISiLMjHYtus4VQ2PvkSw24zyaCVsiS+sXPj1w==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.5.tgz", + "integrity": "sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==", "cpu": [ "arm64" ], @@ -3173,9 +3189,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.4.tgz", - "integrity": "sha512-GjbjXD4XXfN19D0LZNbmiCBUoDiRACsYHr0yaIbbn8aFsXjHZifcYqu/W5Er5X2X990WjHXFrxarn5chzItorQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.5.tgz", + "integrity": "sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==", "cpu": [ "ppc64" ], @@ -3189,9 +3205,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.4.tgz", - "integrity": "sha512-p5WR0NOwaRmJ/B1b6IjEFLLivwEsf3PrdBIhRbhTCQisbo2SvHHpG4ELB/+FgQNnB88LTOF86upmJmbvZdQ2lw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.5.tgz", + "integrity": "sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==", "cpu": [ "s390x" ], @@ -3205,9 +3221,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.4.tgz", - "integrity": "sha512-4/GyVjmhR+Tc6HLJvwc1sOhPqAZtySiSMesOZyX6JQ5XBxoTDEMKQzvo07NIK6nTon/SivlZqvhzvuVBNQhObQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.5.tgz", + "integrity": "sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==", "cpu": [ "x64" ], @@ -3221,9 +3237,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.4.tgz", - "integrity": "sha512-l9eeLsCNvPpmSXUej0etw/J1eqV0Jj1D5G/xG6YTijmE6dkv6E2QezgWbTfQk63v952DPqrjOCoiqxq7Bw0YUQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.5.tgz", + "integrity": "sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==", "cpu": [ "x64" ], @@ -3237,9 +3253,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.4.tgz", - "integrity": "sha512-e0F355MSTMm3+UOqtV3L24gFUp2N5m1f8L/7d56deik6va+AXdrt9F8LbzGpeWGWRbZEDq4m8NVnJDeBtf9DZg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.5.tgz", + "integrity": "sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==", "cpu": [ "arm64" ], @@ -3253,9 +3269,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.4.tgz", - "integrity": "sha512-AWLi0uBRYh6QlE7OKhiz+phZC0qwtij2QZmhmOdsLdFn64m7oMpooE9ICE3lhm9xMb4SpDo2WbHcxX1iFLFtqw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.5.tgz", + "integrity": "sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==", "cpu": [ "arm64" ], @@ -3269,9 +3285,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.4.tgz", - "integrity": "sha512-UwSDJOg3dqCAejWdxclJjCsh3Qq4vLYMDxmyHqo1btz3stK2VqgwNd3mm5tuIwzSlGIQ/1H9Hr+Zn09mrezNqQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.5.tgz", + "integrity": "sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==", "cpu": [ "x64" ], @@ -3806,14 +3822,14 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", - "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.11.tgz", + "integrity": "sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==", "devOptional": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.10", + "@vitest/utils": "4.1.11", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", @@ -3827,8 +3843,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.1.10", - "vitest": "4.1.10" + "@vitest/browser": "4.1.11", + "vitest": "4.1.11" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -3837,15 +3853,15 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", - "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", + "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -3854,12 +3870,12 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", - "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", + "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.10", + "@vitest/spy": "4.1.11", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -3880,9 +3896,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", + "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", "license": "MIT", "dependencies": { "tinyrainbow": "^3.1.0" @@ -3892,12 +3908,12 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", - "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", + "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.10", + "@vitest/utils": "4.1.11", "pathe": "^2.0.3" }, "funding": { @@ -3905,13 +3921,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", - "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", + "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/pretty-format": "4.1.11", + "@vitest/utils": "4.1.11", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -3920,21 +3936,21 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", - "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", + "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", + "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", + "@vitest/pretty-format": "4.1.11", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -3972,9 +3988,9 @@ } }, "node_modules/@xmldom/xmldom": { - "version": "0.9.11", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.11.tgz", - "integrity": "sha512-tW8bcK3hsG0/uqSnNz6TK4BkcuZSezoU7DlnYssILmZDktPnSHHuDJJFM0AJv+13gz2r0iGdrj6qqKeUnxXEDg==", + "version": "0.9.12", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.12.tgz", + "integrity": "sha512-5AXjrcMClTryPe9LgZrygpB1lj7s0S9E0+W+AHaVKAVyHanafK86iPSvG5xHVSp/jC+VH1UXu0TAEmY279xH7A==", "license": "MIT", "engines": { "node": ">=14.6" @@ -4029,64 +4045,22 @@ } }, "node_modules/activitystreams-pane": { - "version": "1.0.3-4", - "resolved": "https://registry.npmjs.org/activitystreams-pane/-/activitystreams-pane-1.0.3-4.tgz", - "integrity": "sha512-ebE4D2mytgUM2cmSEZE7scRnh9sO6R85U6wiwQYUnoOkX7loCthk32buGZCIFjJ7T9jqc4cyDpFTNbO0I7Dstg==", + "version": "2.0.0-0", + "resolved": "https://registry.npmjs.org/activitystreams-pane/-/activitystreams-pane-2.0.0-0.tgz", + "integrity": "sha512-pVPm8x8anDnno7FDd2N9/hj2u5IobhfW2p1b0ueDssjK3ztGjcagwcCqXidSI2gEnNdMt46pqLAuepCE20gn0A==", "license": "MIT", "dependencies": { - "pane-registry": "3.1.2-2", + "pane-registry": "5.0.0-0", "patch-package": "^8.0.1", "rdflib": "2.4.0", "react": "^19.2.3", "react-dom": "^19.2.3", "react-jss": "^10.10.0", - "solid-logic": "4.0.8-1", - "solid-ui": "3.1.3-9", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0", "timeago.js": "^4.0.2" } }, - "node_modules/activitystreams-pane/node_modules/solid-logic": { - "version": "4.0.8-1", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", - "integrity": "sha512-9Vtg9ukEaDTIvBPqECORWRtEJ3nTlEvInJzUCJZDp1qjN9VIdJG0mSiPTIP9RXOEOSAA+Q+cP3d7BzsNyI/RVA==", - "license": "MIT", - "dependencies": { - "@uvdsl/solid-oidc-client-browser": "^0.2.3", - "solid-namespace": "^0.5.4" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/activitystreams-pane/node_modules/solid-ui": { - "version": "3.1.3-9", - "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-9.tgz", - "integrity": "sha512-36as6RIBflm2gsIFnEPLH6hzykXxyc9yJlhJ+E0E6JSLOyjgENGxEj55hMH8lIXzBcR5tkym3Y61vgMm/LIU8Q==", - "license": "MIT", - "dependencies": { - "@awesome.me/webawesome": "^3.9.0", - "@lit/context": "^1.1.6", - "@noble/curves": "^2.2.0", - "@noble/hashes": "^2.2.0", - "escape-html": "^1.0.3", - "lit": "^3.3.3", - "mime-types": "^3.0.2", - "pane-registry": "3.1.2-1", - "rdflib": "2.4.0", - "solid-logic": "4.0.8-1", - "solid-namespace": "^0.5.4", - "uuid": "^14.0.0" - }, - "optionalDependencies": { - "fsevents": "*" - } - }, - "node_modules/activitystreams-pane/node_modules/solid-ui/node_modules/pane-registry": { - "version": "3.1.2-1", - "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-3.1.2-1.tgz", - "integrity": "sha512-aibuyF8pAgHDnmywsMEKUddIcqC0oPF8fNx2TP7zRpRW9aYk2iv06td+br8wenbmu2V/l6Y6aJmCkckHWN/GpA==", - "license": "MIT" - }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -4435,9 +4409,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.11.15", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.15.tgz", - "integrity": "sha512-FwMjJJ7HnyZpWe+oWxegG0fezZyBZUagI5LZEoO3GCbtbKNwRfMH9Ue5d5v01PNePBy1QSfPSDTTeVL0Hb9EzA==", + "version": "2.11.18", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.18.tgz", + "integrity": "sha512-1iEmLEYSiE1SeBoAfPo/Mnx3PzfzHUkDK61ASkCpuk3YXugYLH5DYK1SzqV55F8FMI6s0F+/tCP7Polz1QRjxw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4672,58 +4646,20 @@ } }, "node_modules/chat-pane": { - "version": "3.0.4-3", - "resolved": "https://registry.npmjs.org/chat-pane/-/chat-pane-3.0.4-3.tgz", - "integrity": "sha512-m099X1Lb1qaOtaYNAaJ+NfqD/TMRnhX3Gfx5Xgb2HoZYllaxn1xN3Y5Am4Un21k6tLoPaiq1OIkBe09/gHN/sw==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/chat-pane/-/chat-pane-4.0.0-0.tgz", + "integrity": "sha512-MB1Pg8f76RnqcCrRMEpoFb/In5HyHyHC1N8LP9cik3F2/CLh1VHvJn7y6Yhc645okW0NfXGdVaUaI1kTd0R+AA==", "license": "MIT", "dependencies": { - "pane-registry": "3.1.2-2", "patch-package": "^8.0.1", - "rdflib": "^2.3.9", - "solid-logic": "^4.0.8-0", - "solid-ui": "3.1.3-13", + "rdflib": "^2.4.0", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0", "vite": "^8.0.16", "vitest": "^4.0.18", "vitest-axe": "^0.1.0" } }, - "node_modules/chat-pane/node_modules/solid-logic": { - "version": "4.0.8-1", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", - "integrity": "sha512-9Vtg9ukEaDTIvBPqECORWRtEJ3nTlEvInJzUCJZDp1qjN9VIdJG0mSiPTIP9RXOEOSAA+Q+cP3d7BzsNyI/RVA==", - "license": "MIT", - "dependencies": { - "@uvdsl/solid-oidc-client-browser": "^0.2.3", - "solid-namespace": "^0.5.4" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/chat-pane/node_modules/solid-ui": { - "version": "3.1.3-13", - "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-13.tgz", - "integrity": "sha512-0meJycoMXoelTD06W9A0S9Q4vg0I8BDSsui4BfwocfwFIpEZ02FBFZZf1LcanP7NNpAOs0So6HOQp4QlwSJE3w==", - "license": "MIT", - "dependencies": { - "@awesome.me/webawesome": "^3.9.0", - "@lit/context": "^1.1.6", - "@lit/task": "^1.0.3", - "@noble/curves": "^2.2.0", - "@noble/hashes": "^2.2.0", - "escape-html": "^1.0.3", - "lit": "^3.3.3", - "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", - "rdflib": "2.4.0", - "solid-logic": "4.0.8-1", - "solid-namespace": "^0.5.4", - "uuid": "^14.0.0" - }, - "optionalDependencies": { - "fsevents": "*" - } - }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -4798,13 +4734,17 @@ "license": "MIT" }, "node_modules/contacts-pane": { - "version": "3.2.1-6", - "resolved": "https://registry.npmjs.org/contacts-pane/-/contacts-pane-3.2.1-6.tgz", - "integrity": "sha512-Mf8OCx5Jp4bgTOI0QdDp/Ecs0Pl2SWqriqM/HSnVJ1Q69WOi081pBymR6shL4cP0hv2SHEBy7sjABTXEqjqMrg==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/contacts-pane/-/contacts-pane-4.0.0-0.tgz", + "integrity": "sha512-gGrXVp3w0bgSxu51WWrrmGZgXm361E9AM/0qLsOwfpqdTV3oLYga6WGpuMBeiuBps8Ya3Go3bzDY2D1FyDGDLA==", "license": "MIT", "dependencies": { "@lit/context": "^1.1.6", - "lit": "^3.3.3" + "lit": "^3.3.3", + "pane-registry": "5.0.0-0", + "rdflib": "2.4.0", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0" } }, "node_modules/convert-source-map": { @@ -5154,9 +5094,9 @@ "license": "MIT" }, "node_modules/dompurify": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz", - "integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==", + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.14.tgz", + "integrity": "sha512-dVoH9z+MY+C9IilgGCk3YfFqjLi3fChm2OiKJMzh6axrJ5qwxqWaZamgmHrpv22CN/KdbZJuGEGgfQoL00LTdg==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -5222,9 +5162,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.409", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.409.tgz", - "integrity": "sha512-ChI4N44d0B4A6C8prnNjMOaGgE59fUyEVYcRYm2XEXIjMbbvF5i9UL1cblDbpGqiU0uS8FE8UcKxqZqTXdmzbQ==", + "version": "1.5.412", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.412.tgz", + "integrity": "sha512-z4rMe3esBzlzovKHj4gxJnsCGZRK5l4baUvm+gCGJBPE+gsyUMKsuU9tnEUtI1dOebXz1ytAPGjvXhmQ7rIPwA==", "dev": true, "license": "ISC" }, @@ -5512,6 +5452,7 @@ "version": "9.39.5", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", @@ -6057,58 +5998,19 @@ "license": "ISC" }, "node_modules/folder-pane": { - "version": "3.1.1-3", - "resolved": "https://registry.npmjs.org/folder-pane/-/folder-pane-3.1.1-3.tgz", - "integrity": "sha512-8k4//XS60QeOnCFaSNrmrsI551/YQ7lhCHnJzQFg/zeU6ZPrX80Ca+bnUwpj1Uojb09ChTaNYN+sqh1OpbuCFw==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/folder-pane/-/folder-pane-4.0.0-0.tgz", + "integrity": "sha512-7HOmpCD2zAGQMZX6BUUAw4WG44ZpmpSCqO8w1MziF+Xhedb67q7dqaE8+Oy3YsogLY4BzJ/wSUUn2lfutDNWPg==", "license": "MIT", "dependencies": { - "rdflib": "2.4.0", - "solid-logic": "4.0.8-2", - "solid-ui": "3.1.3-14", + "rdflib": "^2.4.0", + "solid-logic": "^6.0.0-0", + "solid-ui": "^5.0.0-0", "vite": "^8.0.16", "vitest": "^4.0.18", "vitest-axe": "^0.1.0" } }, - "node_modules/folder-pane/node_modules/solid-logic": { - "version": "4.0.8-2", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-2.tgz", - "integrity": "sha512-1/QFgchqCSkmIKvN47t6/OuBays1Yk6MoVtENqesgcpL5t2Q9hzqpQA6ToZNvzDu7Ep6Gs50rJSB1jJJsFi23Q==", - "license": "MIT", - "dependencies": { - "@uvdsl/solid-oidc-client-browser": "^0.2.3", - "solid-namespace": "^0.5.4", - "vite": "^8.0.16", - "vitest": "^4.1.9" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/folder-pane/node_modules/solid-ui": { - "version": "3.1.3-14", - "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-14.tgz", - "integrity": "sha512-iroWIHNX1PJH70Rx9BkXDns0x06cibbdl8lQPsWx94Qbmg1WxrD7hCAxAwWy/OpfAypCEhxxU3hj0699elfqpA==", - "license": "MIT", - "dependencies": { - "@awesome.me/webawesome": "^3.9.0", - "@lit/context": "^1.1.6", - "@lit/task": "^1.0.3", - "@noble/curves": "^2.2.0", - "@noble/hashes": "^2.2.0", - "escape-html": "^1.0.3", - "lit": "^3.3.3", - "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", - "rdflib": "2.4.0", - "solid-logic": "4.0.8-2", - "solid-namespace": "^0.5.4", - "uuid": "^14.0.0" - }, - "optionalDependencies": { - "fsevents": "*" - } - }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -7296,13 +7198,16 @@ "license": "ISC" }, "node_modules/issue-pane": { - "version": "3.0.3-1", - "resolved": "https://registry.npmjs.org/issue-pane/-/issue-pane-3.0.3-1.tgz", - "integrity": "sha512-oB5Kqxn6px09hIv6wG4cTUt/H6q+MZsAmtp40HNQX2F515xmUYSakufliuQ0ONF30EVxjLGzJVB/X4xKYVZxpQ==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/issue-pane/-/issue-pane-4.0.0-0.tgz", + "integrity": "sha512-vA0Tlq4s1gTKRZNPNRitXfeV4fXoJtLlnH6kGWMe2Lx5eL+ziMAp1LZTsTdclQffxzm1q8COnXCFGrOdhDoc/Q==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6", - "patch-package": "^8.0.1" + "patch-package": "^8.0.1", + "rdflib": "2.4.0", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0" }, "engines": { "node": ">=20.19.2" @@ -8246,12 +8151,15 @@ "license": "CC0-1.0" }, "node_modules/meeting-pane": { - "version": "3.0.3-1", - "resolved": "https://registry.npmjs.org/meeting-pane/-/meeting-pane-3.0.3-1.tgz", - "integrity": "sha512-3oAWpeurkBjWDuLlCAGrZGNu0+dJjTBkX2Ymrd97g0uQbnvLol38CCxf8/yhWGCFXs4NtICummRLctR4kgp9kA==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/meeting-pane/-/meeting-pane-4.0.0-0.tgz", + "integrity": "sha512-l8+o/WXp0v0myGzKtgxgVQJJYLV48h8zB4hiJY+Adl9l6CmS4kRq5A6awPVDvSZVjuBaBTxpJ7+Q97nQnqgMUA==", "license": "MIT", "dependencies": { - "patch-package": "^8.0.1" + "patch-package": "^8.0.1", + "rdflib": "2.4.0", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0" } }, "node_modules/micromatch": { @@ -8376,9 +8284,9 @@ "license": "MIT" }, "node_modules/n3": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/n3/-/n3-2.2.0.tgz", - "integrity": "sha512-K/Orb5XrUPocfYfhUT+muvK1I0n2AvVMt93fIExlgjo23u7q0lU0eIFrhBJqooyFWAnpEBz3QZqjHzEHMs1RZg==", + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/n3/-/n3-2.2.8.tgz", + "integrity": "sha512-NsyaKvzajwp/HtkmNMBCqBNyGm0DAAWU+Rzm7uGHp/veQVGwOALn9OxpYq3rN3wn5UZDU4REmDCZxhj4X23INQ==", "license": "MIT", "dependencies": { "buffer": "^6.0.3", @@ -8981,26 +8889,13 @@ } }, "node_modules/pane-registry": { - "version": "3.1.2-2", - "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-3.1.2-2.tgz", - "integrity": "sha512-w+pCan1Umj+pLm5/uNlBMLw0YOKbKhHn5Qh62oqlKlbFrSHj4H3gNOXcKnI47liQFPQYepw5UPssP3aPdiowvA==", + "version": "5.0.0-0", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-5.0.0-0.tgz", + "integrity": "sha512-Yb+qcM4fIDFHxF9CM9PkhIAR1BteaRUCUpmoPOZyGVkqAs4pRbpKsh1QKr0r+ibfTnNUZZ2uBfybg1QUVlmlLA==", "license": "MIT", "dependencies": { "rdflib": "2.4.0", - "solid-logic": "4.0.8-1" - } - }, - "node_modules/pane-registry/node_modules/solid-logic": { - "version": "4.0.8-1", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", - "integrity": "sha512-9Vtg9ukEaDTIvBPqECORWRtEJ3nTlEvInJzUCJZDp1qjN9VIdJG0mSiPTIP9RXOEOSAA+Q+cP3d7BzsNyI/RVA==", - "license": "MIT", - "dependencies": { - "@uvdsl/solid-oidc-client-browser": "^0.2.3", - "solid-namespace": "^0.5.4" - }, - "engines": { - "node": ">=18" + "solid-logic": "6.0.0-0" } }, "node_modules/parent-module": { @@ -9340,63 +9235,26 @@ "license": "MIT" }, "node_modules/profile-pane": { - "version": "3.2.3-4", - "resolved": "https://registry.npmjs.org/profile-pane/-/profile-pane-3.2.3-4.tgz", - "integrity": "sha512-mtbOfS37mFazMu+3h0YaUP4BMqVvzAB4Mvlt9jivl41XQIBxulKP+xhKw2GSI6A4wGs9SIMa8JB7ykQJqiC1bg==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/profile-pane/-/profile-pane-4.0.0-0.tgz", + "integrity": "sha512-Pl9VFKRACkAwMOkJO6CWTpWkvJLMRacdy9P1ODhkaD5wN84ABNzFooqq6RoKFoHlVOUzzmac3fkLVxzmPO0wXw==", "license": "MIT", "dependencies": { "@solid-data-modules/contacts-rdflib": "^0.7.1", - "chat-pane": "3.0.4-3", + "chat-pane": "4.0.0-0", "lit-html": "^3.3.3", - "pane-registry": "3.1.2-2", + "pane-registry": "5.0.0-0", "patch-package": "^8.0.1", "qrcode": "^1.5.4", "rdflib": "2.4.0", - "solid-logic": "4.0.8-1", - "solid-ui": "3.1.3-13", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0", "validate-color": "^2.2.4", "vite": "^8.0.16", "vitest": "^4.0.18", "vitest-axe": "^0.1.0" } }, - "node_modules/profile-pane/node_modules/solid-logic": { - "version": "4.0.8-1", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-1.tgz", - "integrity": "sha512-9Vtg9ukEaDTIvBPqECORWRtEJ3nTlEvInJzUCJZDp1qjN9VIdJG0mSiPTIP9RXOEOSAA+Q+cP3d7BzsNyI/RVA==", - "license": "MIT", - "dependencies": { - "@uvdsl/solid-oidc-client-browser": "^0.2.3", - "solid-namespace": "^0.5.4" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/profile-pane/node_modules/solid-ui": { - "version": "3.1.3-13", - "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-13.tgz", - "integrity": "sha512-0meJycoMXoelTD06W9A0S9Q4vg0I8BDSsui4BfwocfwFIpEZ02FBFZZf1LcanP7NNpAOs0So6HOQp4QlwSJE3w==", - "license": "MIT", - "dependencies": { - "@awesome.me/webawesome": "^3.9.0", - "@lit/context": "^1.1.6", - "@lit/task": "^1.0.3", - "@noble/curves": "^2.2.0", - "@noble/hashes": "^2.2.0", - "escape-html": "^1.0.3", - "lit": "^3.3.3", - "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", - "rdflib": "2.4.0", - "solid-logic": "4.0.8-1", - "solid-namespace": "^0.5.4", - "uuid": "^14.0.0" - }, - "optionalDependencies": { - "fsevents": "*" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -9863,12 +9721,12 @@ } }, "node_modules/rolldown": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.4.tgz", - "integrity": "sha512-rSr7irW0K7QRWzjdJXqZowkcRdDtjRduh43rBltnVKd0VFq839l1lJoDvGJb6gl7+4rTTCrPWu+YfujUL8Ug7w==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.5.tgz", + "integrity": "sha512-VD2IE5PUG4Oj8zz2VGykiYd5wbnjdIiSsNQb8Qu5B+noEp+A78mu2iVvpp27g8es14Tk9rofNs5Tku9iQCS4fA==", "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.144.0", + "@oxc-project/types": "=0.146.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -9878,20 +9736,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.2.4", - "@rolldown/binding-darwin-arm64": "1.2.4", - "@rolldown/binding-darwin-x64": "1.2.4", - "@rolldown/binding-freebsd-x64": "1.2.4", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.4", - "@rolldown/binding-linux-arm64-gnu": "1.2.4", - "@rolldown/binding-linux-arm64-musl": "1.2.4", - "@rolldown/binding-linux-ppc64-gnu": "1.2.4", - "@rolldown/binding-linux-s390x-gnu": "1.2.4", - "@rolldown/binding-linux-x64-gnu": "1.2.4", - "@rolldown/binding-linux-x64-musl": "1.2.4", - "@rolldown/binding-openharmony-arm64": "1.2.4", - "@rolldown/binding-win32-arm64-msvc": "1.2.4", - "@rolldown/binding-win32-x64-msvc": "1.2.4" + "@rolldown/binding-android-arm-eabi": "1.2.5", + "@rolldown/binding-android-arm64": "1.2.5", + "@rolldown/binding-darwin-arm64": "1.2.5", + "@rolldown/binding-darwin-x64": "1.2.5", + "@rolldown/binding-freebsd-x64": "1.2.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.5", + "@rolldown/binding-linux-arm64-gnu": "1.2.5", + "@rolldown/binding-linux-arm64-musl": "1.2.5", + "@rolldown/binding-linux-ppc64-gnu": "1.2.5", + "@rolldown/binding-linux-s390x-gnu": "1.2.5", + "@rolldown/binding-linux-x64-gnu": "1.2.5", + "@rolldown/binding-linux-x64-musl": "1.2.5", + "@rolldown/binding-openharmony-arm64": "1.2.5", + "@rolldown/binding-win32-arm64-msvc": "1.2.5", + "@rolldown/binding-win32-x64-msvc": "1.2.5" } }, "node_modules/safe-array-concat": { @@ -10196,9 +10055,9 @@ "license": "MIT" }, "node_modules/solid-logic": { - "version": "4.0.8-3", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-4.0.8-3.tgz", - "integrity": "sha512-0HKcZJb5ZF2MvFzOid26LMilgL6jD1zaRpix5nb2fB1h3H9WB0kquyD/297L6jIiUTIYSMlVb7ivpvkiVNTTNQ==", + "version": "6.0.0-0", + "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-6.0.0-0.tgz", + "integrity": "sha512-ApPkheoF5Nu+7//WkPJw+tHZuGcktJ0lrkvbTsjNb594RW1DFUtLZY+OXRck45GJW0owoyTtJK7A0jZtlA33tw==", "license": "MIT", "dependencies": { "@uvdsl/solid-oidc-client-browser": "^0.2.3", @@ -10217,9 +10076,9 @@ "license": "MIT" }, "node_modules/solid-ui": { - "version": "3.1.3-17", - "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-3.1.3-17.tgz", - "integrity": "sha512-XVnz8u3lhW0AhmywMlEOif23lYkQcCmWiL5NUf8A5kmz3Ixw3E/qGiqmPpJ8VAOPZhEsj8+G7u+Y6pUDmhrLeA==", + "version": "5.0.0-0", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.0-0.tgz", + "integrity": "sha512-AHHhqeUcggQmudCHKi90ugJMdEHtFsT46MSl7oNbM/TGW2WpkpQv1d17Z4NU1ezq3YFhJPEK7j9iea5Nx5lHMw==", "license": "MIT", "dependencies": { "@awesome.me/webawesome": "^3.9.0", @@ -10242,9 +10101,9 @@ "escape-html": "^1.0.3", "lit": "^3.3.3", "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", + "pane-registry": "5.0.0-0", "rdflib": "2.4.0", - "solid-logic": "4.0.8-3", + "solid-logic": "6.0.0-0", "solid-namespace": "^0.5.4", "uuid": "^14.0.0" }, @@ -10253,9 +10112,9 @@ } }, "node_modules/solidos-toolkit": { - "version": "0.0.0-dev.761b46f81590c0224a612fba4771aa9c84e7944a", - "resolved": "https://registry.npmjs.org/solidos-toolkit/-/solidos-toolkit-0.0.0-dev.761b46f81590c0224a612fba4771aa9c84e7944a.tgz", - "integrity": "sha512-4KXTvJEYBuymrNTJoT15bT2Ml7a6871g4HExEgNNtmnTDhkl6f0H07BChXuotk/awCkJztaE4VHFJgzRqQYcwg==", + "version": "0.0.0-dev.998a984ddf8fda587eedb0c8125cb952ac28d191", + "resolved": "https://registry.npmjs.org/solidos-toolkit/-/solidos-toolkit-0.0.0-dev.998a984ddf8fda587eedb0c8125cb952ac28d191.tgz", + "integrity": "sha512-m2b3sZkKbjV5X/J8N25h3UIbsiQARdnXCGs1AeGqFiueoq8cWm+pdOyPpqiVuqRnnA5osmKG2wovUcBBYumL0Q==", "dev": true, "dependencies": { "@babel/core": "^7.29.0", @@ -10274,10 +10133,10 @@ "vite-plugin-lit-css": "^3.0.0" }, "peerDependencies": { - "pane-registry": "^3.1.1 || ^3.1.2-0", + "pane-registry": "^3.1.1 || ^3.1.2-0 || ^5.0.0 || ^5.0.0-0", "rdflib": "^2.3.6", - "solid-logic": "^4.0.7 || ^4.0.8-0", - "solid-ui": "^3.1.2 || ^3.1.3-0", + "solid-logic": "^4.0.7 || ^4.0.8-0 || ^6.0.0 || ^6.0.0-0", + "solid-ui": "^3.1.2 || ^3.1.3-0 || ^5.0.0 || ^5.0.0-0", "vite": "^8.0.0", "vitest": "^4.0.0" }, @@ -10312,18 +10171,18 @@ } }, "node_modules/source-pane": { - "version": "3.1.1-7", - "resolved": "https://registry.npmjs.org/source-pane/-/source-pane-3.1.1-7.tgz", - "integrity": "sha512-fssbKBXlm16/YA8S/5W/YNUZILlR54DeC71CIr5j0FJx/R8Ts2b7ClMtdpFput39vW7+WCpSH1NkBW+k97157w==", + "version": "4.0.0-0", + "resolved": "https://registry.npmjs.org/source-pane/-/source-pane-4.0.0-0.tgz", + "integrity": "sha512-kjo/pMUyN0JsOyVmNYNxwm+SId0cgHXETx+gIyjCIbGoxknH4BHUkTyCz2KTkS71QZXk2QLG2VmCCaUAehUOpA==", "license": "MIT", "dependencies": { "@lit/context": "^1.1.6", "@typescript-eslint/parser": "^8.63.0", "lit": "^3.3.3", - "pane-registry": "3.1.2-2", + "pane-registry": "5.0.0-0", "rdflib": "2.4.0", - "solid-logic": "4.0.8-3", - "solid-ui": "3.1.3-17", + "solid-logic": "6.0.0-0", + "solid-ui": "5.0.0-0", "vite": "^8.0.16", "vitest": "^4.0.18", "vitest-axe": "^0.1.0" @@ -11214,9 +11073,9 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.1.tgz", - "integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.2.tgz", + "integrity": "sha512-xZe/16rV4aa+HGSOCiY2YeLT1OybRLrrkL/Rqaq7p7GMVXjFh+6wN4oMYgjFmnSnhY8t6Xpdl2l9qmnHYuMHwQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -11243,15 +11102,15 @@ } }, "node_modules/vite": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.1.tgz", - "integrity": "sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", + "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", "license": "MIT", "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.5", - "postcss": "^8.5.25", - "rolldown": "~1.2.1", + "postcss": "^8.5.26", + "rolldown": "~1.2.4", "tinyglobby": "^0.2.17" }, "bin": { @@ -11268,7 +11127,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.4.0", + "@vitejs/devtools": "^0.4.0 || ^0.5.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -11343,18 +11202,18 @@ } }, "node_modules/vitest": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", - "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", - "license": "MIT", - "dependencies": { - "@vitest/expect": "4.1.10", - "@vitest/mocker": "4.1.10", - "@vitest/pretty-format": "4.1.10", - "@vitest/runner": "4.1.10", - "@vitest/snapshot": "4.1.10", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", + "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.11", + "@vitest/mocker": "4.1.11", + "@vitest/pretty-format": "4.1.11", + "@vitest/runner": "4.1.11", + "@vitest/snapshot": "4.1.11", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -11382,12 +11241,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.10", - "@vitest/browser-preview": "4.1.10", - "@vitest/browser-webdriverio": "4.1.10", - "@vitest/coverage-istanbul": "4.1.10", - "@vitest/coverage-v8": "4.1.10", - "@vitest/ui": "4.1.10", + "@vitest/browser-playwright": "4.1.11", + "@vitest/browser-preview": "4.1.11", + "@vitest/browser-webdriverio": "4.1.11", + "@vitest/coverage-istanbul": "4.1.11", + "@vitest/coverage-v8": "4.1.11", + "@vitest/ui": "4.1.11", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" diff --git a/package.json b/package.json index f74d8e9a..dd926161 100644 --- a/package.json +++ b/package.json @@ -57,23 +57,23 @@ "homepage": "https://github.com/SolidOS/solid-panes", "dependencies": { "@solid/better-simple-slideshow": "^0.1.0", - "activitystreams-pane": "1.0.3-4", - "chat-pane": "3.0.4-3", - "contacts-pane": "3.2.1-6", + "activitystreams-pane": "2.0.0-0", + "chat-pane": "4.0.0-0", + "contacts-pane": "4.0.0-0", "dompurify": "^3.4.4", - "folder-pane": "3.1.1-3", - "issue-pane": "3.0.3-1", + "folder-pane": "4.0.0-0", + "issue-pane": "4.0.0-0", "lit-html": "^3.3.2", "marked": "^18.0.3", - "meeting-pane": "3.0.3-1", + "meeting-pane": "4.0.0-0", "mime-types": "^3.0.2", - "pane-registry": "3.1.2-2", - "profile-pane": "3.2.3-4", + "pane-registry": "5.0.0-0", + "profile-pane": "4.0.0-0", "rdflib": "2.4.0", - "solid-logic": "4.0.8-3", + "solid-logic": "6.0.0-0", "solid-namespace": "^0.5.4", - "solid-ui": "3.1.3-17", - "source-pane": "3.1.1-7" + "solid-ui": "5.0.0-0", + "source-pane": "4.0.0-0" }, "overrides": { "rdflib": "$rdflib" diff --git a/src/outline/legacy.js b/src/outline/legacy.js new file mode 100644 index 00000000..a7251486 --- /dev/null +++ b/src/outline/legacy.js @@ -0,0 +1,72 @@ +// Legacy outline manager APIs kept for backward compatibility. + +export function createLegacyOutlineApis ({ outline, dom, kb }) { + // Legacy helper: used only by the old outline row delete affordance. + function removeAndRefresh (d) { + const parent = d.parentNode + const grandParent = parent.parentNode + const placeholder = dom.createElement('div') + placeholder.classList.add('placeholderTable') + grandParent.replaceChild(placeholder, parent) + parent.removeChild(d) + grandParent.replaceChild(parent, placeholder) // Attempt to + } + + // Legacy compatibility: keep this for older panes and toolbar handlers that + // still call the status bar click behavior directly. + function statusBarClick (event) { + const target = outline.targetOf(event) + if (target.label) { + window.content.location = target.label + // The following alternative does not work in the extension. + // var s = store.sym(target.label); + // outline.GotoSubject(s, true); + } + } + + // Legacy compatibility: kept for older forms and keyboard handlers that still + // route enter-key behavior through the outline manager. + function GotoFormURI_enterKey (e) { + if (e.keyCode === 13) outline.GotoFormURI(e) + } + + // Legacy compatibility: kept for code that still jumps to a URI from the + // outline manager instead of calling GotoSubject directly. + function GotoFormURI (_e) { + const uri = dom.getElementById('UserURI').value + const subject = kb.sym(uri) + outline.GotoSubject(subject, true) + } + + // Legacy compatibility: kept for callers that expect the old non-expanding + // URI initialization path on the outline manager. + function GotoURIinit (uri) { + const subject = kb.sym(uri) + outline.GotoSubject(subject) + } + + // Legacy compatibility: kept for older UI code that still asks the outline + // manager to build a tab-style URI from the current form field. + function createTabURI () { + dom.getElementById('UserURI').value = + dom.URL + '?uri=' + dom.getElementById('UserURI').value + } + + // Legacy helper: kept for the old outline row delete affordance. + // This is not part of the new folder-pane sidebar/content-view path. + function removeNodeIconMouseDownListener (e) { + const target = outline.targetOf(e) + let node = target.node + if (node.childNodes.length > 1) node = target.parentNode // parallel outline view @@ Hack + removeAndRefresh(node) + } + + return { + statusBarClick, + GotoFormURI_enterKey, + GotoFormURI, + GotoURIinit, + createTabURI, + removeNodeIconMouseDownListener + } +} \ No newline at end of file diff --git a/src/outline/manager.js b/src/outline/manager.js index 1207ad30..1f0f6f03 100644 --- a/src/outline/manager.js +++ b/src/outline/manager.js @@ -13,6 +13,8 @@ import { UserInput } from './userInput.js' import * as queryByExample from './queryByExample.js' import { loadContainerRepresentation } from '../utils/podUtils' import { isWebIdUri } from '../utils/webIdUtils' +import { createOutlineDomHelpers } from './outlineDomHelpers.js' +import { createLegacyOutlineApis } from './legacy.js' import '../components/file-explorer-header/FileExplorerProvider' export default function (context) { @@ -35,18 +37,47 @@ export default function (context) { dom.outline = this this.qs = new queryByExample.QuerySource() // Track queries in queryByExample + // Legacy compatibility APIs: keep these attached for older callers while the + // new outline/content-view split stabilizes. + const legacyApis = createLegacyOutlineApis({ outline: thisOutline, dom, kb }) + // var selection = [] // Array of statements which have been selected // this.focusTd // the that is being observed this.UserInput = new UserInput(this) this.clipboardAddress = 'tabulator:clipboard' // Weird this.UserInput.clipboardInit(this.clipboardAddress) - const outlineElement = this.outlineElement + + const { + outlineObjectDiv, + outlinePredicateDiv, + termWidget + } = createOutlineDomHelpers({ + dom, + UI, + kb: store, + outlineIcons, + expandMouseDownListener, + selectableTDClickListener, + setSelected, + viewAsBoringDefault, + removeNodeIconMouseDownListener: legacyApis.removeNodeIconMouseDownListener + }) + + this.outlineObjectDiv = outlineObjectDiv + this.outlinePredicateDiv = outlinePredicateDiv + // old name: outlineObjectTD + this.outlineObjectTD = outlineObjectDiv + // old name: outlinePredicateTD + this.outlinePredicateTD = outlinePredicateDiv + this.termWidget = termWidget this.init = function () { - const table = getOutlineContainer() - table.outline = this + const outlineHost = getOutlineContainer() + outlineHost.outline = this } + // Responsive layout detector shared by the outline and folder-pane views. + // Keep this in the new design. this.getLayoutMode = function () { const envLayout = this.context?.environment?.layout if (envLayout === 'mobile' || envLayout === 'desktop') return envLayout @@ -61,51 +92,13 @@ export default function (context) { return 'desktop' } - /** benchmark a function **/ - benchmark.lastkbsize = 0 - - function benchmark (f) { - const args = [] - for (let i = arguments.length - 1; i > 0; i--) args[i - 1] = arguments[i] - // UI.log.debug('BENCHMARK: args=' + args.join()); - const begin = new Date().getTime() - const returnValue = f.apply(f, args) - const end = new Date().getTime() - UI.log.info( - 'BENCHMARK: kb delta: ' + - (kb.statements.length - benchmark.lastkbsize) + - ', time elapsed for ' + - f + - ' was ' + - (end - begin) + - 'ms' - ) - benchmark.lastkbsize = kb.statements.length - return returnValue - } // benchmark - // / ////////////////////// Representing data - // Represent an object in summary form as a table cell - - function appendRemoveIcon (node, subject, removeNode) { - const image = UI.utils.AJARImage( - outlineIcons.src.icon_remove_node, - 'remove', - undefined, - dom - ) - image.addEventListener('click', removeNodeIconMouseDownListener) - // image.setAttribute('align', 'right') Causes icon to be moved down - image.node = removeNode - image.setAttribute('about', subject.toNT()) - image.style.marginLeft = '5px' - image.style.marginRight = '10px' - // image.style.border='solid #777 1px'; - node.appendChild(image) - return image - } + // Represent an object in summary form as a content block + // Adds access/fetch icons to resource labels in the outline and content + // views. Keep this in the new design because the folder-pane still renders + // shared resource summaries through the outline helpers. this.appendAccessIcons = function (kb, node, obj) { if (obj.termType !== 'NamedNode') return const uris = kb.uris(obj) @@ -118,6 +111,8 @@ export default function (context) { } } + // Chooses and wires one fetch-state icon for a single resource. Keep this in + // the new design for shared resource rendering. this.appendAccessIcon = function (node, uri) { if (!uri) return '' const docuri = $rdf.uri.docpart(uri) @@ -173,137 +168,19 @@ export default function (context) { return img } // appendAccessIcon - /** make the td for an object (grammatical object) - * @param obj - an RDF term - * @param view - a VIEW function (rather than a bool asImage) - **/ - - this.outlineObjectTD = function outlineObjectTD ( - obj, - view, - deleteNode, - statement - ) { - const td = dom.createElement('td') - td.classList.add('obj') - td.setAttribute('notSelectable', 'false') - if (!obj) { - td.textContent = 'No object available.' - return td - } - const theClass = 'obj' - - // set about and put 'expand' icon - if ( - obj.termType === 'NamedNode' || - obj.termType === 'BlankNode' || - (obj.termType === 'Literal' && - obj.value.slice && - (obj.value.slice(0, 6) === 'ftp://' || - obj.value.slice(0, 8) === 'https://' || - obj.value.slice(0, 7) === 'http://')) - ) { - td.setAttribute('about', obj.toNT()) - td.appendChild( - UI.utils.AJARImage( - UI.icons.originalIconBase + 'tbl-expand-trans.png', - 'expand', - undefined, - dom - ) - ).addEventListener('click', expandMouseDownListener) - } - td.setAttribute('class', theClass) // this is how you find an object - if (kb.whether(obj, UI.ns.rdf('type'), UI.ns.link('Request'))) { - td.className = 'undetermined' - } // @@? why-timbl - - if (!view) { - // view should be a function pointer - view = viewAsBoringDefault - } - td.appendChild(view(obj)) - if (deleteNode) { - appendRemoveIcon(td, obj, deleteNode) - } - - // set DOM methods - td.tabulatorSelect = function () { - setSelected(this, true) - } - td.tabulatorDeselect = function () { - setSelected(this, false) - } - - td.addEventListener('click', selectableTDClickListener) - return td - } // outlineObjectTD - - this.outlinePredicateTD = function outlinePredicateTD ( - predicate, - newTr, - inverse, - internal - ) { - const predicateTD = dom.createElement('TD') - predicateTD.setAttribute('about', predicate.toNT()) - predicateTD.setAttribute('class', internal ? 'pred internal' : 'pred') - - let lab - switch (predicate.termType) { - case 'BlankNode': // TBD - predicateTD.className = 'undetermined' - break - case 'NamedNode': - lab = UI.utils.predicateLabelForXML(predicate, inverse) - break - case 'Collection': // some choices of predicate - lab = UI.utils.predicateLabelForXML(predicate.elements[0], inverse) - } - lab = lab ? lab.slice(0, 1).toUpperCase() + lab.slice(1) : '...' - // if (kb.statementsMatching(predicate,rdf('type'), UI.ns.link('Request')).length) predicateTD.className='undetermined'; - - const labelTD = dom.createElement('TD') - labelTD.classList.add('labelTD') - labelTD.setAttribute('notSelectable', 'true') - labelTD.appendChild(dom.createTextNode(lab)) - predicateTD.appendChild(labelTD) - labelTD.style.width = '100%' - predicateTD.appendChild(termWidget.construct(dom)) // termWidget is global??? - for (const w in outlineIcons.termWidgets) { - if (!newTr || !newTr.AJAR_statement) break // case for TBD as predicate - // alert(Icon.termWidgets[w]+' '+Icon.termWidgets[w].filter) - if ( - outlineIcons.termWidgets[w].filter && - outlineIcons.termWidgets[w].filter( - newTr.AJAR_statement, - 'pred', - inverse - ) - ) { - termWidget.addIcon(predicateTD, outlineIcons.termWidgets[w]) - } - } - - // set DOM methods - predicateTD.tabulatorSelect = function () { - setSelected(this, true) - } - predicateTD.tabulatorDeselect = function () { - setSelected(this, false) - } - predicateTD.addEventListener('click', selectableTDClickListener) - return predicateTD - } // outlinePredicateTD - + // Gets the shared outline host element. Keep this in the new design while + // the folder-pane still renders content through the outline host. function getOutlineContainer () { return getOrCreateContainer('OutlineView', 'Resource browser') } + // Finds the shared Solid panes navbar. Keep this in the new design. function getNavbarElement () { return document.querySelector('solid-panes-navbar') } + // Reveals the shared navbar when the outline host is active. Keep this in + // the new design. function showSolidPanesNavbar () { const navbar = getNavbarElement() if (navbar) { @@ -318,12 +195,10 @@ export default function (context) { * @param {string} [ariaLabel] Optional aria-label for accessibility * @returns {HTMLElement} */ + // Creates the outline host container if needed. Keep this in the new design + // while the outline host remains the backing surface for rendered content. function getOrCreateContainer (id) { - const containerHost = - document.getElementById('MainContent') || - document.body - - // OutlineView is a table + // OutlineView is a simple block container if (id === 'OutlineView') { const existingOutline = document.getElementById('OutlineView') if (existingOutline) { @@ -335,7 +210,7 @@ export default function (context) { document.body if (containerHost) { - const OutlineView = document.createElement('table') + const OutlineView = document.createElement('div') OutlineView.id = 'OutlineView' OutlineView.classList.add('outline-view') OutlineView.setAttribute('aria-label', 'Resource browser') @@ -345,6 +220,9 @@ export default function (context) { } } + // Filters the pane registry down to panes that can render the current + // subject. Keep this in the new design because the folder-pane still uses it + // to choose ContentView panes. async function getRelevantPanes (subject, context) { // make sure container representation is loaded (when server returns index.html) if (subject.uri.endsWith('/')) { await loadContainerRepresentation(subject) } @@ -369,6 +247,8 @@ export default function (context) { : filteredPanes } + // Picks the pane that should actually render the subject. Keep this in the + // new design. function getPane (relevantPanes, subject) { return ( relevantPanes.find( @@ -377,6 +257,8 @@ export default function (context) { ) } + // Shows or hides the query button when a pane asks for it. Keep this in the + // new design. function setQueryButtonVisibility (shouldShow) { const queryButton = dom.getElementById('queryButton') if (!queryButton) return @@ -387,17 +269,8 @@ export default function (context) { } } - function findContainingTable (td) { - let containingTable - for (containingTable = td; containingTable.parentNode; containingTable = containingTable.parentNode) { - if (containingTable.nodeName === 'TABLE') break - } - if (containingTable.nodeName !== 'TABLE') { - throw new Error('outline: internal error.') - } - return containingTable - } - + // Renders the active pane into a provider node. Keep this in the new design + // because the folder-pane uses the same provider shell. function renderPaneIntoProvider (provider, subject, pane, options) { if (!provider || !pane) return @@ -422,15 +295,19 @@ export default function (context) { } } + // Swaps panes inside an already-rendered provider. Keep this in the new + // design because folder-pane still reuses the provider shell. function openPaneInPlace (subject, pane) { const outlineView = dom.getElementById('OutlineView') if (!outlineView) return const subjectId = subject.toNT() - const subjectTd = outlineView.querySelector('td.paneView[about="' + subjectId + '"]') - if (!subjectTd) return + const subjectNode = outlineView.querySelector('[about="' + subjectId + '"]') + if (!subjectNode) return - const provider = subjectTd.querySelector('file-explorer-provider') + const provider = subjectNode.matches?.('file-explorer-provider') + ? subjectNode + : subjectNode.querySelector('file-explorer-provider') if (!provider) return if (!pane) { UI.log.warn('outline: Unable to open pane in place: pane is undefined.') @@ -442,23 +319,19 @@ export default function (context) { renderPaneIntoProvider(provider, subject, pane, provider.paneRenderOptions) } - async function expandedProviderTR (subject, requiredPane, options) { + // Builds the provider wrapper for an expanded subject. Keep this in the new + // design because folder-pane still renders subjects through providers. + async function expandedProviderTR (subject, requiredPane, options, provider) { options = options || {} - // TODO: hide the main storage header - // const showHeader = !!requiredPane - const tr = dom.createElement('tr') + provider = provider || dom.createElement('file-explorer-provider') + provider.classList.add('paneView', 'tdFlex') + provider.setAttribute('notSelectable', 'true') + provider.setAttribute('about', subject.toNT()) if (options.hover) { // By default no hide till hover as community deems it confusing - tr.classList.add('hoverControl') + provider.classList.add('hoverControl') } - const td = tr.appendChild(dom.createElement('td')) - td.classList.add('paneView', 'tdFlex') - td.setAttribute('notSelectable', 'true') - td.setAttribute('about', subject.toNT()) - td.setAttribute('colspan', '2') - - const provider = td.appendChild(dom.createElement('file-explorer-provider')) provider.context = context provider.subjectUri = subject.uri provider.onBack = () => collapseMouseDownListener({ target: provider }) @@ -478,10 +351,9 @@ export default function (context) { provider.handleSharingClick = () => openPaneInPlace(subject, paneRegistry.byName('sharing')) if (provider.pane) { - tr.classList.add('outlinePaneRow') renderPaneIntoProvider(provider, subject, provider.pane, options) } - return tr + return provider } // / ////////////////////////////////////////////////////////////////////////// @@ -507,63 +379,51 @@ export default function (context) { // / /////////////////////////////////////////////////////////////////////////// - // Remove a node from the DOM so that Firefox refreshes the screen OK - // Just deleting it cause whitespace to accumulate. - function removeAndRefresh (d) { - const table = d.parentNode - const par = table.parentNode - const placeholder = dom.createElement('table') - placeholder.classList.add('placeholderTable') - par.replaceChild(placeholder, table) - table.removeChild(d) - par.replaceChild(table, placeholder) // Attempt to - } - + // Creates or refreshes the outer provider/table shell for a subject. Keep + // this in the new design because folder-pane still reaches it via GotoSubject. const propertyTable = (this.propertyTable = function propertyTable ( subject, table, requiredPane, options ) { - UI.log.debug('Property table for: ' + subject) + UI.log.debug('Property block for: ' + subject) subject = kb.canon(subject) // if (!requiredPane) requiredPane = panes.defaultPane; if (!table) { - // Create a new property table - table = dom.createElement('table') - table.classList.add('tableFullWidth') - expandedProviderTR(subject, requiredPane, options).then(providerTR => { - table.appendChild(providerTR) - }) - - return table + const provider = dom.createElement('file-explorer-provider') + expandedProviderTR(subject, requiredPane, options, provider) + return provider } else { - // New display of existing table, keeping expanded bits + const existingProvider = table.matches?.('file-explorer-provider') + ? table + : table.firstElementChild || table + expandedProviderTR(subject, requiredPane, options, existingProvider) UI.log.info('Re-expand: ' + table) - // do some other stuff here return table } }) /* propertyTable */ + // Builds one old-style property row inside the outline table view. Likely to + // shrink away once the remaining table-based outline path disappears. function propertyTR (doc, st, inverse) { - const tr = doc.createElement('TR') + const tr = doc.createElement('div') tr.AJAR_statement = st tr.AJAR_inverse = inverse // tr.AJAR_variable = null; // @@ ?? was just 'tr.AJAR_variable' tr.setAttribute('predTR', 'true') - const predicateTD = thisOutline.outlinePredicateTD(st.predicate, tr, inverse) + tr.setAttribute('role', 'row') + const predicateTD = thisOutline.outlinePredicateDiv(st.predicate, tr, inverse) tr.appendChild(predicateTD) // @@ add 'internal' to predicateTD's class for style? mno return tr } this.propertyTR = propertyTR // / ////////// Property list + // Expands grouped statements into the old multi-row outline table view. + // Likely to shrink away with the new design. function appendPropertyTRs (parent, plist, inverse, predicateFilter) { - // UI.log.info('@appendPropertyTRs, 'this' is %s, dom is %s, '+ // Gives 'can't access dead object' - // 'thisOutline.document is %s', this, dom.location, thisOutline.document.location); - // UI.log.info('@appendPropertyTRs, dom is now ' + this.document.location); - // UI.log.info('@appendPropertyTRs, dom is now ' + thisOutline.document.location); UI.log.debug('Property list length = ' + plist.length) if (plist.length === 0) return '' let sel, j, k @@ -629,7 +489,7 @@ export default function (context) { sel(plist[k]).lang.indexOf(outline.labeller.LanguagePreference) >= 0 ) { tr.appendChild( - thisOutline.outlineObjectTD( + thisOutline.outlineObjectDiv( sel(plist[k]), defaultpropview, undefined, @@ -644,7 +504,7 @@ export default function (context) { } tr.appendChild( - thisOutline.outlineObjectTD(sel(s), defaultpropview, undefined, s) + thisOutline.outlineObjectDiv(sel(s), defaultpropview, undefined, s) ) /* Note: showNobj shows between n to 2n objects. @@ -679,10 +539,9 @@ export default function (context) { displayed++ s = plist[j + l] defaultpropview = views.defaults[s.predicate.uri] - const trObj = dom.createElement('tr') - trObj.style.colspan = '1' + const trObj = dom.createElement('div') trObj.appendChild( - thisOutline.outlineObjectTD( + thisOutline.outlineObjectDiv( sel(plist[j + l]), defaultpropview, undefined, @@ -709,8 +568,8 @@ export default function (context) { if (show < predDups) { // Add the x more here - const moreTR = dom.createElement('tr') - const moreTD = moreTR.appendChild(dom.createElement('td')) + const moreTR = dom.createElement('div') + const moreTD = moreTR.appendChild(dom.createElement('div')) moreTD.setAttribute( 'style', 'margin: 0.2em; border: none; padding: 0; vertical-align: top;' @@ -782,71 +641,16 @@ export default function (context) { this.appendPropertyTRs = appendPropertyTRs - /* termWidget - ** - */ - const termWidget = {} // @@@@@@ global - globalThis.termWidget = termWidget - termWidget.construct = function (dom) { - dom = dom || document - const td = dom.createElement('TD') - td.setAttribute( - 'style', - 'margin: 0.2em; border: none; padding: 0; vertical-align: top;' - ) - td.setAttribute('class', 'iconTD') - td.setAttribute('notSelectable', 'true') - td.style.width = '0px' - return td - } - termWidget.addIcon = function (td, icon, listener) { - const iconTD = td.childNodes[1] - if (!iconTD) return - let width = iconTD.style.width - const img = UI.utils.AJARImage(icon.src, icon.alt, icon.tooltip, dom) - width = parseInt(width) - width = width + icon.width - iconTD.style.width = width + 'px' - iconTD.appendChild(img) - if (listener) { - img.addEventListener('click', listener) - } - } - termWidget.removeIcon = function (td, icon) { - const iconTD = td.childNodes[1] - let baseURI - if (!iconTD) return - let width = iconTD.style.width - width = parseInt(width) - width = width - icon.width - iconTD.style.width = width + 'px' - for (let x = 0; x < iconTD.childNodes.length; x++) { - const elt = iconTD.childNodes[x] - const eltSrc = elt.src - - // ignore first '?' and everything after it //Kenny doesn't know what this is for - try { - baseURI = dom.location.href.split('?')[0] - } catch (e) { - baseURI = '' - } - const relativeIconSrc = $rdf.uri.join(icon.src, baseURI) - if (eltSrc === relativeIconSrc) { - iconTD.removeChild(elt) - } - } - } - termWidget.replaceIcon = function (td, oldIcon, newIcon, listener) { - termWidget.removeIcon(td, oldIcon) - termWidget.addIcon(td, newIcon, listener) - } - // / /////////////////////////////////////////////////// VALUE BROWSER VIEW // / /////////////////////////////////////////////////////// TABLE VIEW // Summarize a thing as a table cell + // Wires request/done/fail callbacks so access icons update when a resource + // starts fetching, finishes, or fails. It is used by the shared resource + // summary icons, but the outline-specific callback wiring should go away + // once the new design replaces these legacy access-icon hooks. function addButtonCallbacks (target, fireOn) { UI.log.debug('Button callbacks for ' + fireOn + ' added') const makeIconCallback = function (icon) { @@ -873,6 +677,8 @@ export default function (context) { // Selection support + // Predicate/class helper used by the current selection-state logic. Will go + // away with new design. function selected (node) { const a = node.getAttribute('class') if (a && a.indexOf('selected') >= 0) return true @@ -880,6 +686,8 @@ export default function (context) { } // These woulkd be simpler using closer variables below + // Optional-property toggle handler for the old outline adornments. Will go + // away with new design. function optOnIconMouseDownListener (e) { // outlineIcons.src.icon_opton needed? const target = thisOutline.targetOf(e) @@ -893,6 +701,8 @@ export default function (context) { p.parentNode.parentNode.removeAttribute('optional') } + // Optional-property toggle handler for the old outline adornments. Will go + // away with new design. function optOffIconMouseDownListener (e) { // outlineIcons.src.icon_optoff needed? const target = thisOutline.targetOf(e) @@ -906,6 +716,8 @@ export default function (context) { p.parentNode.parentNode.setAttribute('optional', 'true') } + // Selection adornment bookkeeping for predicate/object rows. Will go away + // with new design. function setSelectedParent (node, inc) { const onIcon = outlineIcons.termWidgets.optOn const offIcon = outlineIcons.termWidgets.optOff @@ -941,16 +753,7 @@ export default function (context) { } } - this.statusBarClick = function (event) { - const target = UI.utils.getTarget(event) - if (target.label) { - window.content.location = target.label - // The following alternative does not work in the extension. - // var s = store.sym(target.label); - // outline.GotoSubject(s, true); - } - } - + // Current selection URI display helper. Will go away with new design. this.showURI = function showURI (about) { if (about && dom.getElementById('UserURI')) { dom.getElementById('UserURI').value = @@ -960,6 +763,10 @@ export default function (context) { /* global alert XPathResult sourceWidget */ + // Selection-source panel updater for the optional sourceWidget view. + // It is only active when that widget exists, but when it does this keeps the + // displayed sources in sync with the current outline selection. Keep it while + // the outline selection model still exists. this.showSource = function showSource () { if (typeof sourceWidget === 'undefined') return // deselect all before going on, this is necessary because you would switch tab, @@ -980,18 +787,26 @@ export default function (context) { } } + // Read-only accessor for the current outline selection array. It is used by + // outline-side code as a simple state bridge and may still matter while the + // folder-pane reuses outline selection for inline editing and rendering. this.getSelection = function getSelection () { return selection } + // Central selection-state mutator for the outline keyboard and mouse flows. + // The current outline handlers and the UserInput bridge still depend on it, + // and the folder-pane/content-view design still leans on outline selection + // state for inline editing and resource rendering. This only shrinks if the + // new design fully replaces outline-driven selection. function setSelected (node, newValue) { // UI.log.info('selection has ' +selection.map(function(item){return item.textContent;}).join(', ')); // UI.log.debug('@outline setSelected, intended to '+(newValue?'select ':'deselect ')+node+node.textContent); // if (newValue === selected(node)) return; //we might not need this anymore... - if (node.nodeName !== 'TD') { + if (node.nodeName !== 'TD' && node.nodeName !== 'DIV') { UI.log.debug('down' + node.nodeName) throw new Error( - 'Expected TD in setSelected: ' + + 'Expected TD or DIV in setSelected: ' + node.nodeName + ' : ' + node.textContent @@ -1051,12 +866,19 @@ export default function (context) { node.setAttribute('class', cla) } + // Bulk selection reset that delegates to setSelected() so the same side + // effects and cleanup happen when the outline needs to clear focus. It stays + // relevant while the folder-pane still uses outline selection state, and + // would only become disposable if that model is replaced end-to-end. function deselectAll () { const n = selection.length for (let i = n - 1; i >= 0; i--) setSelected(selection[i], false) selection = [] } - + // Shared event-target normalizer for the outline mouse handlers in this file. + // It is still needed because several listeners call it before inspecting the + // clicked node, including handlers that support the current sidebar/content-view flow. + /* SAM srcElement is the old IE-era version of event.target. */ /** Get the target of an event **/ this.targetOf = function (e) { let target @@ -1107,13 +929,8 @@ export default function (context) { ) { setSelected(selectedTd.nextSibling, true) } else { - const newSelected = dom.evaluate( - 'table/div/tr/td[2]', - selectedTd, - null, - XPathResult.FIRST_ORDERED_NODE_TYPE, - null - ).singleNodeValue + const nextRow = selectedTd.parentNode && selectedTd.parentNode.nextSibling + const newSelected = nextRow ? nextRow.lastChild : null setSelected(newSelected, true) } break @@ -1126,7 +943,7 @@ export default function (context) { setSelected(selectedTd.previousSibling, true) return true // do not shrink signal } else { - setSelected(UI.utils.ancestor(selectedTd.parentNode, 'TD'), true) + setSelected(selectedTd.parentNode && selectedTd.parentNode.firstChild, true) } // supplied by thieOutline.focusTd break case 'moveTo': @@ -1141,6 +958,10 @@ export default function (context) { // return newSelTd; } + // Outline-level keyboard dispatcher for Enter, arrows, delete/backspace, + // copy/paste, and the input-box up/down bridge from createInputBoxIn() in + // userInput.js. The folder-pane sidebar/content-view flow does not call this + // directly, but the outline still needs it for inline editing and navigation. // Keyboard Input: we can consider this as... // 1. a fast way to modify data - enter will go to next predicate // 2. an alternative way to input - enter at the end of a predicate will create a new statement @@ -1263,7 +1084,7 @@ export default function (context) { this.walk('right') return } - if (selectedTd.firstChild.tagName !== 'TABLE') { + if (selectedTd.firstChild.tagName !== 'SECTION') { // not expanded sf.addCallback('done', setSelectedAfterward) sf.addCallback('fail', setSelectedAfterward) @@ -1345,6 +1166,10 @@ export default function (context) { // select // visit/open a page + // Attached by outlineObjectDiv in outlineDomHelpers.js to the expand icon. + // Handles subject expansion, Shift-click refocus, and Alt-click internal + // pane debugging. Still used by the outline; the folder-pane uses it only + // indirectly when GotoSubject(..., true) renders ContentView content. function expandMouseDownListener (e) { // For icon (UI.icons.originalIconBase + 'tbl-expand-trans.png') const target = thisOutline.targetOf(e) @@ -1368,6 +1193,8 @@ export default function (context) { } } + // Used as the back action for expanded providers, and still the outline-side + // collapse handler for the old row-based outline view. function collapseMouseDownListener (e) { // for icon UI.icons.originalIconBase + 'tbl-collapse.png' const target = thisOutline.targetOf(e) @@ -1377,6 +1204,9 @@ export default function (context) { outlineCollapse(p, subject, pane) } + // Attached to access icons for fetch/retry failure states in + // appendAccessIcon(). Still used by both outline summaries and the + // folder-pane ContentView resource display. function failedIconMouseDownListener (e) { // outlineIcons.src.icon_failed const target = thisOutline.targetOf(e) @@ -1390,6 +1220,8 @@ export default function (context) { } } + // Attached to access icons after a document is fetched successfully. + // Same callers and future relevance as failedIconMouseDownListener. function fetchedIconMouseDownListener (e) { // outlineIcons.src.icon_fetched const target = thisOutline.targetOf(e) @@ -1403,20 +1235,18 @@ export default function (context) { } } + // Attached to access icons before a document has been requested yet. + // This keeps the resource-fetch affordance working in outline summaries and + // the folder-pane ContentView resource display. function unrequestedIconMouseDownListener (e) { const target = thisOutline.targetOf(e) const uri = target.getAttribute('uri') // Put on access buttons sf.fetch($rdf.uri.docpart(uri)) } - function removeNodeIconMouseDownListener (e) { - // icon_remove_node - const target = thisOutline.targetOf(e) - let node = target.node - if (node.childNodes.length > 1) node = target.parentNode // parallel outline view @@ Hack - removeAndRefresh(node) // @@ update icons for pane? - } - + // Attached by outlineObjectDiv and outlinePredicateDiv in outlineDomHelpers. + // Handles selection and edit-entry clicks on outline/content blocks; still + // needed for the outline and for resource summaries rendered in ContentView. function selectableTDClickListener (e) { // Is we are in editing mode already if (thisOutline.UserInput._tabulatorMode) { @@ -1428,9 +1258,9 @@ export default function (context) { // var p = target.parentNode let node for ( - node = UI.utils.ancestor(target, 'TD'); + node = UI.utils.ancestor(target, 'TD') || UI.utils.ancestor(target, 'DIV'); node && !(node.getAttribute('notSelectable') === 'false'); // Default now is not selectable - node = UI.utils.ancestor(node.parentNode, 'TD') + node = UI.utils.ancestor(node.parentNode, 'TD') || UI.utils.ancestor(node.parentNode, 'DIV') ) { // ... } @@ -1460,7 +1290,7 @@ export default function (context) { // go to UserInput let st if (node.parentNode) st = node.parentNode.AJAR_statement - if (!st) return // For example in the title TD of an expanded pane + if (!st) return // For example in the title block of an expanded pane const target = st.why const editable = store.updater.editable(target.uri, kb) if (sel && editable) thisOutline.UserInput.Click(e, selection[0]) // was next 2 lines @@ -1484,6 +1314,10 @@ export default function (context) { // this is important or conflict between deselect and user input happens } + // Legacy-style global mousedown cleanup for the outline keyboard/mouse model. + // Called from OutlinerMouseclickPanel() when the old tabulator mode is active. + // Likely to shrink or disappear if the new sidebar/content-view path fully + // replaces outline-wide mouse handling. function TabulatorMousedown (e) { UI.log.info('@TabulatorMousedown, dom.location is now ' + dom.location) const target = thisOutline.targetOf(e) @@ -1539,6 +1373,11 @@ export default function (context) { } } + // Low-level subject expansion for the outline host. + // Called from Enter, right-arrow, click-expand, and GotoSubject(..., true). + // The folder-pane sidebar/content-view flow reaches this indirectly through + // GotoSubject(..., true) when it renders a selected resource in ContentView. + // Keep it until that flow fully replaces outline-host expansion. /** Expand an outline view * @param p {Element} - container */ @@ -1566,27 +1405,12 @@ export default function (context) { // first expand newTable = propertyTable(subject, undefined, pane, options) } else { - UI.log.info(' ... p is ' + p) - for ( - newTable = p.firstChild; - newTable.nextSibling; - newTable = newTable.nextSibling - ) { - UI.log.info(' ... checking node ' + newTable) - if (newTable.nodeName === 'table') break - } - newTable = propertyTable(subject, newTable, pane, options) + newTable = propertyTable(subject, p, pane, options) } already = true - if ( - UI.utils.ancestor(p, 'TABLE') && - UI.utils.ancestor(p, 'TABLE').style.backgroundColor === 'white' - ) { - newTable.style.backgroundColor = '#eee' - } else { - newTable.style.backgroundColor = 'white' + if (newTable !== p) { + UI.utils.emptyNode(p).appendChild(newTable) } - UI.utils.emptyNode(p).appendChild(newTable) thisOutline.focusTd = p // I don't know why I couldn't use 'this'...because not defined in callbacks UI.log.debug('expand: Node for ' + subject + ' expanded') // fetch seeAlso when render() @@ -1670,23 +1494,11 @@ export default function (context) { sf.addCallback('done', expand) // @@@@@@@ This can really mess up existing work sf.addCallback('fail', expand) // Need to do if there s one a gentle resync of page with store - const returnConditions = [] // this is quite a general way to do cut and paste programming - // I might make a class for this if (subject.uri && subject.uri.split(':')[0] === 'rdf') { // what is this? -tim render() return } - - for (let i = 0; i < returnConditions.length; i++) { - let returnCode - if (returnCode === returnConditions[i](subject)) { - render() - UI.log.debug('outline 1815') - if (returnCode[1]) outlineElement.removeChild(outlineElement.lastChild) - return - } - } if ( subject.uri && !immediate && @@ -1761,22 +1573,10 @@ export default function (context) { } } // outlineExpand + // Collapse the currently expanded outline row back to a summary block. + // This still serves keyboard and mouse collapse actions. function outlineCollapse (p, subject) { - let row = UI.utils.ancestor(p, 'TR') - row = UI.utils.ancestor(row.parentNode, 'TR') // two levels up - let statement - if (row) statement = row.AJAR_statement - let level // find level (the enclosing TD) - for ( - level = p.parentNode; - level.tagName !== 'TD'; - level = level.parentNode - ) { - if (typeof level === 'undefined') { - alert('Not enclosed in TD!') - return - } - } + const statement = p.AJAR_statement || (p.parentNode && p.parentNode.AJAR_statement) UI.log.debug('Collapsing subject ' + subject) let myview @@ -1786,15 +1586,17 @@ export default function (context) { } UI.log.debug('view= ' + myview) let deleteNode - if (level.parentNode.parentNode.id === 'outline') { - deleteNode = level.parentNode + if (p.parentNode && p.parentNode.id === 'outline') { + deleteNode = p } thisOutline.replaceTD( - thisOutline.outlineObjectTD(subject, myview, deleteNode, statement), - level + thisOutline.outlineObjectDiv(subject, myview, deleteNode, statement), + p ) } // outlineCollapse + // Replace one DOM block with another while preserving selection state. + // User-input edits still rely on this swap behavior. this.replaceTD = function replaceTD (newTd, replacedTd) { let reselect if (selected(replacedTd)) reselect = true @@ -1813,17 +1615,13 @@ export default function (context) { if (reselect) setSelected(newTd, true) } + // Shift-click maximize the current subject by replacing the pane contents + // with the subject view. function outlineRefocus (p, subject) { - // Shift-expand or shift-collapse: Maximize - let outer = null - for (let level = p.parentNode; level; level = level.parentNode) { - UI.log.debug('level ' + level.tagName) - if (level.tagName === 'TD') outer = level - } // find outermost td - UI.utils.emptyNode(outer).appendChild(propertyTable(subject)) + UI.utils.emptyNode(p).appendChild(propertyTable(subject)) setUrlBarAndTitle(subject) // dom.title = UI.utils.label(subject) - outer.setAttribute('about', subject.toNT()) + p.setAttribute('about', subject.toNT()) } // outlineRefocus outline.outlineRefocus = outlineRefocus @@ -1837,22 +1635,6 @@ export default function (context) { } } */ - this.GotoFormURI_enterKey = function (e) { - if (e.keyCode === 13) outline.GotoFormURI(e) - } - this.GotoFormURI = function (_e) { - GotoURI(dom.getElementById('UserURI').value) - } - - function GotoURI (uri) { - const subject = kb.sym(uri) - this.GotoSubject(subject, true) - } - this.GotoURIinit = function (uri) { - const subject = kb.sym(uri) - this.GotoSubject(subject) - } - /** Display the subject in an outline view @param subject -- RDF term for the thing to be presented @@ -1860,69 +1642,71 @@ export default function (context) { @param pane -- optional -- pane to be used for expanded display @param solo -- optional -- the window will be cleared out and only the subject displayed @param referer -- optional -- where did we hear about this from anyway? - @param table -- option -- default is an HTML table element in which to put the outline. + @param host -- option -- default is the outline host element used for the view. @param showNavbar -- optional -- when false, suppress automatic navbar reveal */ - this.GotoSubject = function (subject, expand, pane, solo, referrer, table, showNavbar = true) { - const outlineContainer = getOutlineContainer() - if (showNavbar && (!table || table === outlineContainer)) { + this.GotoSubject = function (subject, expand, pane, solo, referrer, host, showNavbar = true) { + const outlineHost = getOutlineContainer() + + openSubjectInHost(subject, expand, pane, solo, host || outlineHost, showNavbar, outlineHost) + + updateHistoryForSubject(subject, pane, solo) + + return subject + } + + function openSubjectInHost (subject, expand, pane, solo, host, showNavbar, outlineHost) { + if (showNavbar && host === outlineHost) { showSolidPanesNavbar() } - table = table || outlineContainer // if does not exist create a compatible host in the current shell if (solo) { - UI.utils.emptyNode(table) - table.style.width = '100%' - } - - function GotoSubjectDefault () { - const tr = dom.createElement('tr') - tr.classList.add('outlineRow1') - tr.style.verticalAlign = 'top' - table.appendChild(tr) - const td = thisOutline.outlineObjectTD(subject, undefined, tr) - tr.appendChild(td) - return td + host.style.width = '100%' } - const td = GotoSubjectDefault() - if (solo) setUrlBarAndTitle(subject) // dom.title = UI.utils.label(subject) // 'Tabulator: '+ No need to advertize if (expand) { - outlineExpand(td, subject, { + outlineExpand(host, subject, { pane, solo }) + return } + const block = thisOutline.outlineObjectDiv(subject, undefined, host) + host.appendChild(block) + } + + function updateHistoryForSubject (subject, pane, solo) { if ( - solo && - dom && - dom.defaultView && - dom.defaultView.history + !solo || + !dom || + !dom.defaultView || + !dom.defaultView.history ) { - const currentState = dom.defaultView.history.state || {} - const paneState = pane ? { paneName: pane.name } : {} - if (pane && pane.subject && typeof pane.subject.uri === 'string') { - paneState.paneUri = pane.subject.uri - } - const stateObj = { ...currentState, ...paneState } - try { - const currentUrl = new URL(document.location.href) - const targetUrl = new URL(subject.uri, document.location.href) - if (currentUrl.origin === targetUrl.origin) { - if (document.location.href !== subject.uri) { - dom.defaultView.history.pushState(stateObj, subject.uri, subject.uri) - } else if (JSON.stringify(currentState) !== JSON.stringify(stateObj)) { - dom.defaultView.history.replaceState(stateObj, subject.uri, subject.uri) - } + return + } + + const currentState = dom.defaultView.history.state || {} + const paneState = pane ? { paneName: pane.name } : {} + if (pane && pane.subject && typeof pane.subject.uri === 'string') { + paneState.paneUri = pane.subject.uri + } + const stateObj = { ...currentState, ...paneState } + + try { + const currentUrl = new URL(document.location.href) + const targetUrl = new URL(subject.uri, document.location.href) + if (currentUrl.origin === targetUrl.origin) { + if (document.location.href !== subject.uri) { + dom.defaultView.history.pushState(stateObj, subject.uri, subject.uri) + } else if (JSON.stringify(currentState) !== JSON.stringify(stateObj)) { + dom.defaultView.history.replaceState(stateObj, subject.uri, subject.uri) } - } catch (e) { } + } catch (e) { } - - return subject } // / ///////////////////////////////////////////////////// @@ -1935,9 +1719,10 @@ export default function (context) { const views = propertyViews(dom) - // var thisOutline = this dup - /** some builtin simple views **/ - + // Current fallback renderer for outline objects and generic resource summaries. + // This will still be used by the existing folder-pane/content-view flow for plain + // resource display, but it may later be replaced by a dedicated content-view + // renderer that looks different from the sidebar for the folder-pane. function viewAsBoringDefault (obj) { // UI.log.debug('entered viewAsBoringDefault...'); let rep // representation in html @@ -1992,8 +1777,7 @@ export default function (context) { } } else if (obj.termType === 'Collection') { // obj.elements is an array of the elements in the collection - rep = dom.createElement('table') - rep.classList.add('tableFullWidth') + rep = dom.createElement('div') rep.setAttribute('about', obj.toNT()) /* Not sure which looks best -- with or without. I think without @@ -2003,13 +1787,13 @@ export default function (context) { */ for (let i = 0; i < obj.elements.length; i++) { const elt = obj.elements[i] - const row = rep.appendChild(dom.createElement('tr')) - const numcell = row.appendChild(dom.createElement('td')) + const row = rep.appendChild(dom.createElement('div')) + const numcell = row.appendChild(dom.createElement('div')) numcell.classList.add('obj') numcell.setAttribute('notSelectable', 'false') numcell.setAttribute('about', obj.toNT()) numcell.innerHTML = i + 1 + ')' - row.appendChild(thisOutline.outlineObjectTD(elt)) + row.appendChild(thisOutline.outlineObjectDiv(elt)) } } else if (obj.termType === 'Graph') { rep = paneRegistry @@ -2024,10 +1808,11 @@ export default function (context) { return rep } // boring_default - this.createTabURI = function () { - dom.getElementById('UserURI').value = - dom.URL + '?uri=' + dom.getElementById('UserURI').value - } + this.statusBarClick = legacyApis.statusBarClick + this.GotoFormURI_enterKey = legacyApis.GotoFormURI_enterKey + this.GotoFormURI = legacyApis.GotoFormURI + this.GotoURIinit = legacyApis.GotoURIinit + this.createTabURI = legacyApis.createTabURI // a way to expose variables to UserInput without making them propeties/methods this.UserInput.setSelected = setSelected diff --git a/src/outline/notused.js b/src/outline/notused.js new file mode 100644 index 00000000..8bea967d --- /dev/null +++ b/src/outline/notused.js @@ -0,0 +1,14 @@ +// Unused outline-manager helpers kept here for reference while the refactor +// settles. Move entries back into manager.js only if a caller still depends on +// them. + +/** benchmark a function **/ +export function benchmark (f, ...args) { + const begin = new Date().getTime() + const returnValue = f.apply(f, args) + const end = new Date().getTime() + return { + returnValue, + elapsedMs: end - begin + } +} \ No newline at end of file diff --git a/src/outline/outlineDomHelpers.js b/src/outline/outlineDomHelpers.js new file mode 100644 index 00000000..a1ecc444 --- /dev/null +++ b/src/outline/outlineDomHelpers.js @@ -0,0 +1,219 @@ +import { uri } from 'rdflib' +import { utils } from 'solid-ui' + +export function createOutlineDomHelpers ({ + dom, + UI, + kb, + outlineIcons, + expandMouseDownListener, + selectableTDClickListener, + setSelected, + viewAsBoringDefault, + removeNodeIconMouseDownListener +}) { + // old name: appendRemoveIcon + // Used by outlineCollapse when a row in the main OutlineView is collapsed back + // to a summary object and needs to keep the remove/delete affordance on that + // outline row. + function appendRemoveIcon (node, subject, removeNode) { + const image = utils.AJARImage( + outlineIcons.src.icon_remove_node, + 'remove', + undefined, + dom + ) + image.addEventListener('click', removeNodeIconMouseDownListener) + image.node = removeNode + image.setAttribute('about', subject.toNT()) + image.style.marginLeft = '5px' + image.style.marginRight = '10px' + node.appendChild(image) + return image + } + + const termWidget = {} + globalThis.termWidget = termWidget + + termWidget.construct = function (domArg) { + domArg = domArg || document + const iconContainer = domArg.createElement('div') + iconContainer.setAttribute( + 'style', + 'margin: 0.2em; border: none; padding: 0; vertical-align: top;' + ) + iconContainer.setAttribute('class', 'iconTD') + iconContainer.setAttribute('notSelectable', 'true') + iconContainer.style.width = '0px' + return iconContainer + } + + termWidget.addIcon = function (iconHost, icon, listener) { + const iconTD = iconHost.childNodes[1] + if (!iconTD) return + let width = iconTD.style.width + const img = utils.AJARImage(icon.src, icon.alt, icon.tooltip, dom) + width = parseInt(width) + width = width + icon.width + iconTD.style.width = width + 'px' + iconTD.appendChild(img) + if (listener) { + img.addEventListener('click', listener) + } + } + + termWidget.removeIcon = function (iconHost, icon) { + const iconTD = iconHost.childNodes[1] + let baseURI + if (!iconTD) return + let width = iconTD.style.width + width = parseInt(width) + width = width - icon.width + iconTD.style.width = width + 'px' + for (let x = 0; x < iconTD.childNodes.length; x++) { + const elt = iconTD.childNodes[x] + const eltSrc = elt.src + + try { + baseURI = dom.location.href.split('?')[0] + } catch (e) { + baseURI = '' + } + const relativeIconSrc = uri.join(icon.src, baseURI) + if (eltSrc === relativeIconSrc) { + iconTD.removeChild(elt) + } + } + } + + termWidget.replaceIcon = function (iconHost, oldIcon, newIcon, listener) { + termWidget.removeIcon(iconHost, oldIcon) + termWidget.addIcon(iconHost, newIcon, listener) + } + + // old name: outlineObjectTD + function outlineObjectDiv ( + obj, + view, + deleteNode, + statement + ) { + const objectDiv = dom.createElement('div') + objectDiv.classList.add('obj') + objectDiv.setAttribute('notSelectable', 'false') + objectDiv.setAttribute('role', 'option') + objectDiv.setAttribute('tabindex', '0') + objectDiv.setAttribute('data-outline-node', 'object') + if (!obj) { + objectDiv.textContent = 'No object available.' + return objectDiv + } + const theClass = 'obj' + + if ( + obj.termType === 'NamedNode' || + obj.termType === 'BlankNode' || + (obj.termType === 'Literal' && + obj.value.slice && + (obj.value.slice(0, 6) === 'ftp://' || + obj.value.slice(0, 8) === 'https://' || + obj.value.slice(0, 7) === 'http://')) + ) { + objectDiv.setAttribute('about', obj.toNT()) + objectDiv.appendChild( + UI.utils.AJARImage( + UI.icons.originalIconBase + 'tbl-expand-trans.png', + 'expand', + undefined, + dom + ) + ).addEventListener('click', expandMouseDownListener) + } + objectDiv.setAttribute('class', theClass) + if (kb.whether(obj, UI.ns.rdf('type'), UI.ns.link('Request'))) { + objectDiv.className = 'undetermined' + } + + if (!view) { + view = viewAsBoringDefault + } + objectDiv.appendChild(view(obj)) + if (deleteNode) { + appendRemoveIcon(objectDiv, obj, deleteNode) + } + + objectDiv.tabulatorSelect = function () { + setSelected(this, true) + } + objectDiv.tabulatorDeselect = function () { + setSelected(this, false) + } + + objectDiv.addEventListener('click', selectableTDClickListener) + return objectDiv + } + + // old name: outlinePredicateTD + function outlinePredicateDiv ( + predicate, + newTr, + inverse, + internal + ) { + const predicateTD = dom.createElement('div') + predicateTD.setAttribute('about', predicate.toNT()) + predicateTD.setAttribute('class', internal ? 'pred internal' : 'pred') + predicateTD.setAttribute('role', 'row') + predicateTD.setAttribute('data-outline-node', 'predicate') + + let lab + switch (predicate.termType) { + case 'BlankNode': + predicateTD.className = 'undetermined' + break + case 'NamedNode': + lab = UI.utils.predicateLabelForXML(predicate, inverse) + break + case 'Collection': + lab = UI.utils.predicateLabelForXML(predicate.elements[0], inverse) + } + lab = lab ? lab.slice(0, 1).toUpperCase() + lab.slice(1) : '...' + + const labelTD = dom.createElement('div') + labelTD.classList.add('labelTD') + labelTD.setAttribute('notSelectable', 'true') + labelTD.appendChild(dom.createTextNode(lab)) + predicateTD.appendChild(labelTD) + labelTD.style.width = '100%' + predicateTD.appendChild(termWidget.construct(dom)) + for (const w in outlineIcons.termWidgets) { + if (!newTr || !newTr.AJAR_statement) break + if ( + outlineIcons.termWidgets[w].filter && + outlineIcons.termWidgets[w].filter( + newTr.AJAR_statement, + 'pred', + inverse + ) + ) { + termWidget.addIcon(predicateTD, outlineIcons.termWidgets[w]) + } + } + + predicateTD.tabulatorSelect = function () { + setSelected(this, true) + } + predicateTD.tabulatorDeselect = function () { + setSelected(this, false) + } + predicateTD.addEventListener('click', selectableTDClickListener) + return predicateTD + } + + return { + appendRemoveIcon, + outlineObjectDiv, + outlinePredicateDiv, + termWidget + } +} \ No newline at end of file