solid-panes 5.1.0-0 → 5.1.0-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/README.md +17 -0
  2. package/dist/RDFXMLPane2.esm.js +1 -2
  3. package/dist/_virtual/~icons/lucide/cake.esm.js +1 -2
  4. package/dist/_virtual/~icons/lucide/camera.esm.js +1 -2
  5. package/dist/_virtual/~icons/lucide/circle-user-round.esm.js +1 -2
  6. package/dist/_virtual/~icons/lucide/folder-open.esm.js +1 -2
  7. package/dist/_virtual/~icons/lucide/help-circle.esm.js +1 -2
  8. package/dist/_virtual/~icons/lucide/layout-dashboard.esm.js +1 -2
  9. package/dist/_virtual/~icons/lucide/mail.esm.js +1 -2
  10. package/dist/_virtual/~icons/lucide/map-pin.esm.js +1 -2
  11. package/dist/_virtual/~icons/lucide/pencil.esm.js +1 -2
  12. package/dist/_virtual/~icons/lucide/phone.esm.js +1 -2
  13. package/dist/_virtual/~icons/lucide/settings-2.esm.js +1 -2
  14. package/dist/_virtual/~icons/lucide/user-round-plus.esm.js +1 -2
  15. package/dist/_virtual/~icons/lucide/user.esm.js +1 -2
  16. package/dist/_virtual/~icons/lucide/users.esm.js +1 -2
  17. package/dist/_virtual/~icons/lucide/x.esm.js +1 -2
  18. package/dist/audio/audioPane.esm.js +1 -2
  19. package/dist/classInstancePane.esm.js +1 -2
  20. package/dist/components/editor-card/EditorCard.cjs.js +1 -1
  21. package/dist/components/editor-card/EditorCard.cjs.js.map +1 -1
  22. package/dist/components/editor-card/EditorCard.esm.js +6 -7
  23. package/dist/components/editor-card/EditorCard.styles.esm.js +1 -2
  24. package/dist/components/header/Header.cjs.js +1 -1
  25. package/dist/components/header/Header.cjs.js.map +1 -1
  26. package/dist/components/header/Header.esm.js +7 -8
  27. package/dist/components/header/Header.styles.esm.js +1 -2
  28. package/dist/components/navbar/Navbar.cjs.js +2 -2
  29. package/dist/components/navbar/Navbar.cjs.js.map +1 -1
  30. package/dist/components/navbar/Navbar.esm.js +8 -9
  31. package/dist/components/navbar/Navbar.styles.esm.js +1 -2
  32. package/dist/components/profile-heading/ProfileHeading.cjs.js +17 -17
  33. package/dist/components/profile-heading/ProfileHeading.cjs.js.map +1 -1
  34. package/dist/components/profile-heading/ProfileHeading.esm.js +28 -29
  35. package/dist/components/profile-heading/ProfileHeading.styles.esm.js +1 -2
  36. package/dist/components/profile-heading/editor/sections/heading/HeadingEditDialog.cjs.js +1 -1
  37. package/dist/components/profile-heading/editor/sections/heading/HeadingEditDialog.esm.js +2 -3
  38. package/dist/components/profile-heading/editor/sections/heading/dateHelpers.esm.js +1 -2
  39. package/dist/components/profile-heading/editor/sections/heading/imageHelpers.esm.js +1 -2
  40. package/dist/components/profile-heading/editor/sections/heading/imagePreview.esm.js +1 -2
  41. package/dist/components/profile-heading/editor/sections/heading/mutations.esm.js +1 -2
  42. package/dist/components/profile-heading/editor/sections/shared/contactTypeUtils.esm.js +1 -2
  43. package/dist/components/profile-heading/editor/sections/shared/idNodeFactory.esm.js +1 -2
  44. package/dist/components/profile-heading/editor/sections/shared/phoneCountries.esm.js +0 -1
  45. package/dist/components/profile-heading/editor/sections/shared/rdfMutationHelpers.esm.js +1 -2
  46. package/dist/components/profile-heading/editor/sections/shared/rowState.esm.js +1 -2
  47. package/dist/components/profile-heading/editor/sections/shared/sanitizeUtils.esm.js +1 -2
  48. package/dist/components/profile-heading/editor/textUtils.esm.js +1 -2
  49. package/dist/components/profile-heading/editor/texts/dialogTexts.esm.js +1 -2
  50. package/dist/components/profile-heading/editor/texts/messageTexts.esm.js +1 -2
  51. package/dist/components/profile-heading/editor/ui/dialog2.cjs.js +3 -3
  52. package/dist/components/profile-heading/editor/ui/dialog2.cjs.js.map +1 -1
  53. package/dist/components/profile-heading/editor/ui/dialog2.esm.js +4 -19
  54. package/dist/components/profile-heading/editor/ui/dialog2.esm.js.map +1 -1
  55. package/dist/components/profile-heading/editor/ui/spinner.esm.js +1 -2
  56. package/dist/components/profile-heading/editor/utils/errorDisplay.esm.js +1 -2
  57. package/dist/components/profile-heading/friendActions.esm.js +1 -2
  58. package/dist/components/profile-heading/profileHeadingData.esm.js +1 -2
  59. package/dist/dashboard/basicPreferences.esm.js +1 -2
  60. package/dist/dashboard/dashboardPane.esm.js +0 -1
  61. package/dist/dashboard/homepage.esm.js +1 -2
  62. package/dist/dashboard/ontologyData.esm.js +1 -2
  63. package/dist/dashboard/preferencesFormText.esm.js +1 -2
  64. package/dist/dataContentPane2.cjs.js +1 -1
  65. package/dist/dataContentPane2.esm.js +2 -3
  66. package/dist/defaultPane2.cjs.js +1 -1
  67. package/dist/defaultPane2.esm.js +2 -3
  68. package/dist/dokieli/dokieliPane.cjs.js +1 -1
  69. package/dist/dokieli/dokieliPane.cjs.js.map +1 -1
  70. package/dist/dokieli/dokieliPane.esm.js +7 -12
  71. package/dist/dokieli/dokieliPane.esm.js.map +1 -1
  72. package/dist/dokieli/new.esm.js +1 -2
  73. package/dist/form/pane.esm.js +1 -2
  74. package/dist/home/homePane.esm.js +1 -2
  75. package/dist/humanReadablePane.d.ts +3 -0
  76. package/dist/humanReadablePane.d.ts.map +1 -1
  77. package/dist/humanReadablePane2.cjs.js +276 -1
  78. package/dist/humanReadablePane2.cjs.js.map +1 -1
  79. package/dist/humanReadablePane2.esm.js +428 -31
  80. package/dist/humanReadablePane2.esm.js.map +1 -1
  81. package/dist/icons/folder.esm.js +1 -2
  82. package/dist/icons/friends.esm.js +1 -2
  83. package/dist/icons/person.esm.js +1 -2
  84. package/dist/imagePane.d.ts.map +1 -1
  85. package/dist/imagePane2.cjs.js +1 -1
  86. package/dist/imagePane2.cjs.js.map +1 -1
  87. package/dist/imagePane2.esm.js +2 -3
  88. package/dist/imagePane2.esm.js.map +1 -1
  89. package/dist/index.esm.js +1 -2
  90. package/dist/internal/internalPane2.cjs.js +1 -1
  91. package/dist/internal/internalPane2.esm.js +2 -3
  92. package/dist/mainPage/header.esm.js +1 -2
  93. package/dist/mainPage/index.cjs.js +1 -1
  94. package/dist/mainPage/index.cjs.js.map +1 -1
  95. package/dist/mainPage/index.d.ts +1 -1
  96. package/dist/mainPage/index.d.ts.map +1 -1
  97. package/dist/mainPage/index.esm.js +6 -2
  98. package/dist/mainPage/index.esm.js.map +1 -1
  99. package/dist/mainPage/navbar.esm.js +1 -2
  100. package/dist/mainPage/navigation.cjs.js +1 -1
  101. package/dist/mainPage/navigation.cjs.js.map +1 -1
  102. package/dist/mainPage/navigation.d.ts.map +1 -1
  103. package/dist/mainPage/navigation.esm.js +14 -11
  104. package/dist/mainPage/navigation.esm.js.map +1 -1
  105. package/dist/mainPage/profileHeading2.esm.js +1 -2
  106. package/dist/n3Pane2.esm.js +1 -2
  107. package/dist/navigation/browserEvents.esm.js +1 -2
  108. package/dist/navigation/chrome.esm.js +1 -2
  109. package/dist/navigation/controller.cjs.js +1 -1
  110. package/dist/navigation/controller.cjs.js.map +1 -1
  111. package/dist/navigation/controller.esm.js +6 -7
  112. package/dist/navigation/controller.esm.js.map +1 -1
  113. package/dist/navigation/events.esm.js +1 -2
  114. package/dist/navigation/navbarVisibility.esm.js +1 -2
  115. package/dist/navigation/options.esm.js +1 -2
  116. package/dist/navigation/podContext.esm.js +1 -2
  117. package/dist/navigation/state.esm.js +1 -2
  118. package/dist/outline/context.esm.js +1 -2
  119. package/dist/outline/fileExplorerHelpers.cjs.js +2 -0
  120. package/dist/outline/fileExplorerHelpers.cjs.js.map +1 -0
  121. package/dist/outline/fileExplorerHelpers.d.ts +13 -0
  122. package/dist/outline/fileExplorerHelpers.d.ts.map +1 -0
  123. package/dist/outline/fileExplorerHelpers.esm.js +24 -0
  124. package/dist/outline/fileExplorerHelpers.esm.js.map +1 -0
  125. package/dist/outline/manager2.cjs.js +1 -1
  126. package/dist/outline/manager2.cjs.js.map +1 -1
  127. package/dist/outline/manager2.esm.js +422 -433
  128. package/dist/outline/manager2.esm.js.map +1 -1
  129. package/dist/outline/outlineDomHelpers.cjs.js +2 -0
  130. package/dist/outline/outlineDomHelpers.cjs.js.map +1 -0
  131. package/dist/outline/outlineDomHelpers.d.ts +30 -0
  132. package/dist/outline/outlineDomHelpers.d.ts.map +1 -0
  133. package/dist/outline/outlineDomHelpers.esm.js +79 -0
  134. package/dist/outline/outlineDomHelpers.esm.js.map +1 -0
  135. package/dist/outline/outlineIcons.esm.js +1 -2
  136. package/dist/outline/propertyViews.esm.js +1 -2
  137. package/dist/outline/queryByExample.cjs.js.map +1 -1
  138. package/dist/outline/queryByExample.esm.js +1 -2
  139. package/dist/outline/queryByExample.esm.js.map +1 -1
  140. package/dist/outline/userInput.cjs.js +9 -9
  141. package/dist/outline/userInput.cjs.js.map +1 -1
  142. package/dist/outline/userInput.esm.js +50 -40
  143. package/dist/outline/userInput.esm.js.map +1 -1
  144. package/dist/outline/viewAsImage.esm.js +1 -2
  145. package/dist/outline/viewAsMbox.esm.js +1 -2
  146. package/dist/pad/padPane2.cjs.js +1 -1
  147. package/dist/pad/padPane2.esm.js +2 -3
  148. package/dist/playlist/playlistPane.esm.js +1 -2
  149. package/dist/registerPanes.esm.js +1 -2
  150. package/dist/schedule/formsForSchedule.esm.js +1 -2
  151. package/dist/schedule/schedulePane.d.ts.map +1 -1
  152. package/dist/schedule/schedulePane2.cjs.js +1 -1
  153. package/dist/schedule/schedulePane2.cjs.js.map +1 -1
  154. package/dist/schedule/schedulePane2.esm.js +60 -59
  155. package/dist/schedule/schedulePane2.esm.js.map +1 -1
  156. package/dist/sharing/sharingPane.esm.js +1 -2
  157. package/dist/slideshow/slideshowPane.esm.js +1 -2
  158. package/dist/social/editProfileDetails.cjs.js +1 -1
  159. package/dist/social/editProfileDetails.esm.js +1 -2
  160. package/dist/social/icons.esm.js +1 -2
  161. package/dist/social/socialPane2.cjs.js +1 -1
  162. package/dist/social/socialPane2.esm.js +2 -3
  163. package/dist/social/socialSections.cjs.js +1 -1
  164. package/dist/social/socialSections.cjs.js.map +1 -1
  165. package/dist/social/socialSections.d.ts +0 -1
  166. package/dist/social/socialSections.d.ts.map +1 -1
  167. package/dist/social/socialSections.esm.js +15 -18
  168. package/dist/social/socialSections.esm.js.map +1 -1
  169. package/dist/social/triage.esm.js +1 -2
  170. package/dist/tabbed/tabbedPane.esm.js +1 -2
  171. package/dist/tableViewPane.esm.js +1 -2
  172. package/dist/transaction/pane.esm.js +1 -2
  173. package/dist/transaction/period.esm.js +1 -2
  174. package/dist/trip/tripPane.esm.js +1 -2
  175. package/dist/trustedApplications/trustedApplications.dom.esm.js +1 -2
  176. package/dist/trustedApplications/trustedApplications.utils.esm.js +1 -2
  177. package/dist/trustedApplications/trustedApplications.view.esm.js +1 -2
  178. package/dist/ui/pane.esm.js +1 -2
  179. package/dist/utils/paneUtils.cjs.js +1 -1
  180. package/dist/utils/paneUtils.cjs.js.map +1 -1
  181. package/dist/utils/paneUtils.d.ts +5 -3
  182. package/dist/utils/paneUtils.d.ts.map +1 -1
  183. package/dist/utils/paneUtils.esm.js +36 -29
  184. package/dist/utils/paneUtils.esm.js.map +1 -1
  185. package/dist/utils/podUtils.cjs.js +1 -1
  186. package/dist/utils/podUtils.cjs.js.map +1 -1
  187. package/dist/utils/podUtils.d.ts +9 -1
  188. package/dist/utils/podUtils.d.ts.map +1 -1
  189. package/dist/utils/podUtils.esm.js +22 -95
  190. package/dist/utils/podUtils.esm.js.map +1 -1
  191. package/dist/utils/viewerUtils.esm.js +1 -2
  192. package/dist/utils/webIdUtils.esm.js +1 -2
  193. package/dist/versionInfo.cjs.js +1 -1
  194. package/dist/versionInfo.cjs.js.map +1 -1
  195. package/dist/versionInfo.esm.js +4 -5
  196. package/dist/versionInfo.esm.js.map +1 -1
  197. package/dist/video/videoPane.esm.js +1 -2
  198. package/package.json +7 -6
  199. package/dist/_virtual/~icons/lucide/arrow-left.cjs.js +0 -2
  200. package/dist/_virtual/~icons/lucide/arrow-left.cjs.js.map +0 -1
  201. package/dist/_virtual/~icons/lucide/arrow-left.esm.js +0 -11
  202. package/dist/_virtual/~icons/lucide/arrow-left.esm.js.map +0 -1
  203. package/dist/_virtual/~icons/lucide/ellipsis-vertical.cjs.js +0 -2
  204. package/dist/_virtual/~icons/lucide/ellipsis-vertical.cjs.js.map +0 -1
  205. package/dist/_virtual/~icons/lucide/ellipsis-vertical.esm.js +0 -11
  206. package/dist/_virtual/~icons/lucide/ellipsis-vertical.esm.js.map +0 -1
  207. package/dist/_virtual/~icons/lucide/folder.cjs.js +0 -2
  208. package/dist/_virtual/~icons/lucide/folder.cjs.js.map +0 -1
  209. package/dist/_virtual/~icons/lucide/folder.esm.js +0 -11
  210. package/dist/_virtual/~icons/lucide/folder.esm.js.map +0 -1
  211. package/dist/_virtual/~icons/lucide/globe.cjs.js +0 -2
  212. package/dist/_virtual/~icons/lucide/globe.cjs.js.map +0 -1
  213. package/dist/_virtual/~icons/lucide/globe.esm.js +0 -11
  214. package/dist/_virtual/~icons/lucide/globe.esm.js.map +0 -1
  215. package/dist/_virtual/~icons/lucide/lock-keyhole.cjs.js +0 -2
  216. package/dist/_virtual/~icons/lucide/lock-keyhole.cjs.js.map +0 -1
  217. package/dist/_virtual/~icons/lucide/lock-keyhole.esm.js +0 -11
  218. package/dist/_virtual/~icons/lucide/lock-keyhole.esm.js.map +0 -1
  219. package/dist/_virtual/~icons/lucide/share-2.cjs.js +0 -2
  220. package/dist/_virtual/~icons/lucide/share-2.cjs.js.map +0 -1
  221. package/dist/_virtual/~icons/lucide/share-2.esm.js +0 -11
  222. package/dist/_virtual/~icons/lucide/share-2.esm.js.map +0 -1
  223. package/dist/_virtual/~icons/lucide/user-round-cog.cjs.js +0 -2
  224. package/dist/_virtual/~icons/lucide/user-round-cog.cjs.js.map +0 -1
  225. package/dist/_virtual/~icons/lucide/user-round-cog.esm.js +0 -11
  226. package/dist/_virtual/~icons/lucide/user-round-cog.esm.js.map +0 -1
  227. package/dist/components/file-explorer-header/FileExplorerHeader.cjs.js +0 -14
  228. package/dist/components/file-explorer-header/FileExplorerHeader.cjs.js.map +0 -1
  229. package/dist/components/file-explorer-header/FileExplorerHeader.d.ts +0 -18
  230. package/dist/components/file-explorer-header/FileExplorerHeader.d.ts.map +0 -1
  231. package/dist/components/file-explorer-header/FileExplorerHeader.esm.js +0 -292
  232. package/dist/components/file-explorer-header/FileExplorerHeader.esm.js.map +0 -1
  233. package/dist/components/file-explorer-header/FileExplorerHeader.styles.cjs.js +0 -2
  234. package/dist/components/file-explorer-header/FileExplorerHeader.styles.cjs.js.map +0 -1
  235. package/dist/components/file-explorer-header/FileExplorerHeader.styles.esm.js +0 -7
  236. package/dist/components/file-explorer-header/FileExplorerHeader.styles.esm.js.map +0 -1
  237. package/dist/components/file-explorer-header/FileExplorerHeaderControls.cjs.js +0 -32
  238. package/dist/components/file-explorer-header/FileExplorerHeaderControls.cjs.js.map +0 -1
  239. package/dist/components/file-explorer-header/FileExplorerHeaderControls.d.ts +0 -21
  240. package/dist/components/file-explorer-header/FileExplorerHeaderControls.d.ts.map +0 -1
  241. package/dist/components/file-explorer-header/FileExplorerHeaderControls.esm.js +0 -294
  242. package/dist/components/file-explorer-header/FileExplorerHeaderControls.esm.js.map +0 -1
  243. package/dist/components/file-explorer-header/FileExplorerHeaderControls.styles.cjs.js +0 -2
  244. package/dist/components/file-explorer-header/FileExplorerHeaderControls.styles.cjs.js.map +0 -1
  245. package/dist/components/file-explorer-header/FileExplorerHeaderControls.styles.esm.js +0 -7
  246. package/dist/components/file-explorer-header/FileExplorerHeaderControls.styles.esm.js.map +0 -1
  247. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.cjs.js +0 -34
  248. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.cjs.js.map +0 -1
  249. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.d.ts +0 -20
  250. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.d.ts.map +0 -1
  251. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.esm.js +0 -346
  252. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.esm.js.map +0 -1
  253. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.styles.cjs.js +0 -2
  254. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.styles.cjs.js.map +0 -1
  255. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.styles.esm.js +0 -7
  256. package/dist/components/file-explorer-header/FileExplorerHeaderSummary.styles.esm.js.map +0 -1
  257. package/dist/components/file-explorer-header/FileExplorerProvider.cjs.js +0 -13
  258. package/dist/components/file-explorer-header/FileExplorerProvider.cjs.js.map +0 -1
  259. package/dist/components/file-explorer-header/FileExplorerProvider.d.ts +0 -36
  260. package/dist/components/file-explorer-header/FileExplorerProvider.d.ts.map +0 -1
  261. package/dist/components/file-explorer-header/FileExplorerProvider.esm.js +0 -470
  262. package/dist/components/file-explorer-header/FileExplorerProvider.esm.js.map +0 -1
  263. package/dist/components/file-explorer-header/FileExplorerProvider.styles.cjs.js +0 -2
  264. package/dist/components/file-explorer-header/FileExplorerProvider.styles.cjs.js.map +0 -1
  265. package/dist/components/file-explorer-header/FileExplorerProvider.styles.esm.js +0 -7
  266. package/dist/components/file-explorer-header/FileExplorerProvider.styles.esm.js.map +0 -1
  267. package/dist/components/file-explorer-header/index.cjs.js +0 -1
  268. package/dist/components/file-explorer-header/index.d.ts +0 -3
  269. package/dist/components/file-explorer-header/index.d.ts.map +0 -1
  270. package/dist/components/file-explorer-header/index.esm.js +0 -2
  271. package/dist/components/file-explorer-header/types.d.ts +0 -10
  272. package/dist/components/file-explorer-header/types.d.ts.map +0 -1
  273. package/dist/components/resource-actions-menu/DeleteResourceDialog.d.ts +0 -8
  274. package/dist/components/resource-actions-menu/DeleteResourceDialog.d.ts.map +0 -1
  275. package/dist/components/resource-actions-menu/ResourceActionsMenu.cjs.js +0 -32
  276. package/dist/components/resource-actions-menu/ResourceActionsMenu.cjs.js.map +0 -1
  277. package/dist/components/resource-actions-menu/ResourceActionsMenu.d.ts +0 -19
  278. package/dist/components/resource-actions-menu/ResourceActionsMenu.d.ts.map +0 -1
  279. package/dist/components/resource-actions-menu/ResourceActionsMenu.esm.js +0 -322
  280. package/dist/components/resource-actions-menu/ResourceActionsMenu.esm.js.map +0 -1
  281. package/dist/components/resource-actions-menu/ResourceActionsMenu.styles.cjs.js +0 -2
  282. package/dist/components/resource-actions-menu/ResourceActionsMenu.styles.cjs.js.map +0 -1
  283. package/dist/components/resource-actions-menu/ResourceActionsMenu.styles.esm.js +0 -7
  284. package/dist/components/resource-actions-menu/ResourceActionsMenu.styles.esm.js.map +0 -1
@@ -1,2 +1,277 @@
1
- (function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`.human-readable-pane{box-sizing:border-box;width:100%;min-width:0;max-width:100%;display:block}.human-readable-pane__container{box-sizing:border-box;width:100%;min-width:0;max-width:100%;display:block;overflow-x:hidden}.human-readable-pane__frame{border:1px solid var(--solid-ui-color-gray-200,#cbd5e1);height:var(--human-readable-pane-height,30rem);box-sizing:border-box;resize:both;width:100%;min-width:0;max-width:100%;padding:1rem;display:block;overflow:auto}.human-readable-pane__frame--iframe{background:var(--color-background,white);width:100%;max-width:100%;min-height:18rem;padding:0;overflow:hidden}.human-readable-pane__frame--markdown{overflow-wrap:anywhere;word-break:break-word}.human-readable-pane__frame--plain-text{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;margin:0;font-family:monospace}.human-readable-pane__frame--markdown>*{box-sizing:border-box;max-width:100%}.human-readable-pane__frame--markdown img,.human-readable-pane__frame--markdown video,.human-readable-pane__frame--markdown canvas,.human-readable-pane__frame--markdown iframe{max-width:100%;height:auto}.human-readable-pane__frame--markdown pre,.human-readable-pane__frame--markdown code{overflow-wrap:anywhere;word-break:break-word;max-width:100%}.human-readable-pane__frame--markdown pre{white-space:pre-wrap}.human-readable-pane__frame--markdown table{box-sizing:border-box;width:100%;max-width:100%;display:block;overflow-x:auto}.human-readable-pane__frame--markdown th,.human-readable-pane__frame--markdown td{white-space:normal;overflow-wrap:anywhere;word-break:break-word}.human-readable-pane[data-layout=mobile] .human-readable-pane__frame{resize:none;min-width:0;padding:.75rem}.human-readable-pane[data-layout=mobile] .human-readable-pane__frame--markdown,.human-readable-pane[data-layout=mobile] .human-readable-pane__frame--plain-text{overflow-wrap:anywhere;word-break:break-word}.human-readable-pane[data-layout=mobile] .human-readable-pane__frame--iframe{width:100%;max-width:100%;min-height:16rem;height:min(var(--human-readable-pane-height,30rem), 75vh)}@media (width<=576px){.human-readable-pane__frame{resize:none;min-width:0;padding:.75rem}.human-readable-pane__frame--markdown,.human-readable-pane__frame--plain-text{overflow-wrap:anywhere;word-break:break-word}.human-readable-pane__frame--iframe{width:100%;max-width:100%;min-height:16rem;height:min(var(--human-readable-pane-height,30rem), 75vh)}}`)),document.head.appendChild(e)}}catch(e){console.error(`vite-plugin-css-injected-by-js`,e)}})();const e=require("./_virtual/_rolldown/runtime.cjs.js");;let t=require("solid-ui"),n=require("rdflib"),r=require("marked"),i=require("dompurify");i=e.__toESM(i);var a=e=>{if(!e)return!1;let t=e.split(`?`)[0].split(`#`)[0];return/\.(md|markdown|mdown|mkd|mkdn)$/i.test(t)},o=new Map;function s(e,t,n){e.className=``,e.classList.add(`human-readable-pane__frame`),e.classList.add(`human-readable-pane__frame--${t}`),e.style.setProperty(`--human-readable-pane-height`,`${n}em`)}var c={icon:function(e,n){if(e&&a(e.uri))return t.icons.iconBase+`markdown.svg`;if(e){let r=n.session.store,i=o.get(e.uri);if(i===`dokieli`)return t.icons.iconBase+`dokieli-logo.png`;if(i===`html`)return t.icons.originalIconBase+`tango/22-text-x-generic.png`;let a=r.fetcher.getHeader(e.doc(),`content`);if(a&&a.length>0){let n=a[0],r=n.includes(`<script src="https://dokie.li/scripts/dokieli.js">`)||n.includes(`dokieli.css`);return o.set(e.uri,r?`dokieli`:`html`),r?t.icons.iconBase+`dokieli-logo.png`:t.icons.originalIconBase+`tango/22-text-x-generic.png`}let s=r.fetcher.getHeader(e.doc(),`content-type`);if((s?s[0].split(`;`,1)[0].trim():null)===`text/html`)return r.fetcher._fetch(e.uri).then(e=>e.text()).then(n=>{let r=n.includes(`<script src="https://dokie.li/scripts/dokieli.js">`)||n.includes(`dokieli.css`);return o.set(e.uri,r?`dokieli`:`html`),r?t.icons.iconBase+`dokieli-logo.png`:t.icons.originalIconBase+`tango/22-text-x-generic.png`}).catch(()=>(o.set(e.uri,`html`),t.icons.originalIconBase+`tango/22-text-x-generic.png`))}return t.icons.originalIconBase+`tango/22-text-x-generic.png`},name:`humanReadable`,label:function(e,r){let i=r.session.store,s=[`text/plain`,`text/html`,`text/markdown`,`application/xhtml+xml`,`image/png`,`image/jpeg`,`application/pdf`,`video/mp4`],c=function(e,t,n){let r=e.fetcher.getHeader(t,`content-type`);if(r){for(let e=0;e<r.length;e++)for(let t=0;t<n.length;t++)if(r[e].indexOf(n[t])>=0)return!0}return!1},l=function(e,t,r){let i=e.findTypeURIs(t);for(let e=0;e<r.length;e++)if(n.Util.mediaTypeClass(r[e]).uri in i)return!0;return!1};if(!e.uri)return null;if(i.findTypeURIs(e)[t.ns.link(`WebPage`).uri])return`Webpage`;if(a(e.uri))return`View`;if(c(i,e,s)||l(i,e,s)){let t=i.fetcher.getHeader(e.doc(),`content-type`);return(t?t[0].split(`;`,1)[0].trim():null)===`text/html`&&!o.has(e.uri)&&i.fetcher._fetch(e.uri).then(e=>e.text()).then(t=>{let n=t.includes(`<script src="https://dokie.li/scripts/dokieli.js">`)||t.includes(`dokieli.css`);o.set(e.uri,n?`dokieli`:`html`)}).catch(()=>{o.set(e.uri,`html`)}),`View`}return null},render:function(e,t){let n=t.dom,c=n.createElement(`div`),l=t.session.store;function u(e){let n=t.environment??{};e.dataset.layout=n.layout??`desktop`}let d=l.fetcher.getHeader(e.doc(),`content-type`),f=d?d[0].split(`;`,1)[0].trim():null,p=f===`text/markdown`||a(e.uri),m=f===`text/plain`;f||console.log(`humanReadablePane: unknown content-type?`),c.classList.add(`human-readable-pane`),u(c);let h=function(t){l.fetcher.webOperation(`GET`,e.uri).then(e=>{let n=e.responseText??``,a=Math.min(30,n.split(/\n/).length+5),o=r.marked.parse(n,{async:!1});t.innerHTML=i.default.sanitize(o),s(t,`markdown`,a)}).catch(e=>{console.error(`Error fetching markdown content:`,e),t.innerHTML=`<p>Error loading content</p>`})},g=function(t){l.fetcher.webOperation(`GET`,e.uri).then(e=>{let n=e.responseText??``,r=Math.min(30,n.split(/\n/).length+5);t.textContent=n,s(t,`plain-text`,r)}).catch(e=>{console.error(`Error fetching plain text content:`,e),t.textContent=`Error loading content`})},_=(t,n)=>{t.setAttribute(`src`,e.uri),s(t,`iframe`,n)};if(p){let e=n.createElement(`div`);h(e);let t=n.createElement(`div`);t.classList.add(`human-readable-pane__container`),t.appendChild(e),c.appendChild(t)}else if(m){let e=n.createElement(`pre`);g(e);let t=n.createElement(`div`);t.classList.add(`human-readable-pane__container`),t.appendChild(e),c.appendChild(t)}else{let t=n.createElement(`iframe`);(f===`text/html`||f===`application/xhtml+xml`)&&t.setAttribute(`sandbox`,`allow-scripts allow-same-origin allow-forms`),l.fetcher.webOperation(`GET`,e.uri).then(n=>{let r=n.responseText??``,i=r.includes(`<script src="https://dokie.li/scripts/dokieli.js">`)?-10:5,a=Math.min(30,r.split(/\n/).length+i),s=r.includes(`<script src="https://dokie.li/scripts/dokieli.js">`)||r.includes(`dokieli.css`);o.set(e.uri,s?`dokieli`:`html`),_(t,a)}).catch(e=>{console.error(`Error fetching content for line calculation:`,e),_(t,30)});let r=n.createElement(`div`);r.classList.add(`human-readable-pane__container`),r.appendChild(t),c.appendChild(r)}return c}};exports.default=c;
1
+ (function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`.human-readable-pane{box-sizing:border-box;flex-direction:column;width:100%;min-width:0;max-width:100%;margin:0;padding:0 40px;display:flex;overflow:hidden}.human-readable-pane__container{box-sizing:border-box;width:100%;min-width:0;max-width:100%;margin:0;padding:0;display:block;overflow-x:hidden}.human-readable-pane__frame{border:1px solid var(--solid-ui-color-slate-200,#e2e8f0);height:var(--human-readable-pane-height,30rem);box-sizing:border-box;resize:both;width:100%;min-width:0;max-width:100%;padding:1rem;display:block;overflow:auto}.human-readable-pane__frame--iframe{box-sizing:border-box;background:var(--color-background,white);width:100%;max-width:100%;min-height:18rem;padding:0;display:block;overflow:auto}.human-readable-pane--iframe,solid-ui-file-explorer-provider>.paneDiv.human-readable-pane--iframe{flex:1;height:100%;min-height:0;display:flex;overflow:hidden}.human-readable-pane__container--iframe{flex-direction:column;flex:auto;min-height:0;display:flex}.human-readable-pane__container--iframe>.human-readable-pane__frame--iframe{resize:none;flex:1;height:auto;min-height:0}.human-readable-pane__frame--markdown{overflow-wrap:anywhere;word-break:break-word}.human-readable-pane__frame--plain-text{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;margin:0;font-family:monospace}.human-readable-pane__frame--markdown>*{box-sizing:border-box;max-width:100%}.human-readable-pane__frame--markdown img,.human-readable-pane__frame--markdown video,.human-readable-pane__frame--markdown canvas,.human-readable-pane__frame--markdown iframe{max-width:100%;height:auto}.human-readable-pane__frame--markdown pre,.human-readable-pane__frame--markdown code{overflow-wrap:anywhere;word-break:break-word;max-width:100%}.human-readable-pane__frame--markdown pre{white-space:pre-wrap}.human-readable-pane__frame--markdown table{box-sizing:border-box;width:100%;max-width:100%;display:block;overflow-x:auto}.human-readable-pane__frame--markdown th,.human-readable-pane__frame--markdown td{white-space:normal;overflow-wrap:anywhere;word-break:break-word}.human-readable-pane[data-layout=mobile] .human-readable-pane__frame{resize:none;min-width:0;padding:.75rem}.human-readable-pane[data-layout=mobile]{padding:0}.human-readable-pane[data-layout=mobile] .human-readable-pane__frame--markdown,.human-readable-pane[data-layout=mobile] .human-readable-pane__frame--plain-text{overflow-wrap:anywhere;word-break:break-word}.human-readable-pane[data-layout=mobile] .human-readable-pane__frame--iframe{width:100%;max-width:100%;min-height:0;height:max(16rem, min(var(--human-readable-pane-height,30rem), 75vh))}@media (width<=576px){.human-readable-pane{padding:0}.human-readable-pane__frame{resize:none;min-width:0;padding:.75rem}.human-readable-pane__frame--markdown,.human-readable-pane__frame--plain-text{overflow-wrap:anywhere;word-break:break-word}.human-readable-pane__frame--iframe{width:100%;max-width:100%;min-height:0;height:max(16rem, min(var(--human-readable-pane-height,30rem), 75vh))}}`)),document.head.appendChild(e)}}catch(e){console.error(`vite-plugin-css-injected-by-js`,e)}})();const e=require("./_virtual/_rolldown/runtime.cjs.js");;let t=require("solid-ui"),n=require("rdflib"),r=require("marked"),i=require("dompurify");i=e.__toESM(i);var a=e=>{if(!e)return!1;let t=e.split(`?`)[0].split(`#`)[0];return/\.(md|markdown|mdown|mkd|mkdn)$/i.test(t)},o=new Map;function s(e,t,n){e.className=``,e.classList.add(`human-readable-pane__frame`),e.classList.add(`human-readable-pane__frame--${t}`),n!==void 0&&e.style.setProperty(`--human-readable-pane-height`,`${n}em`)}var c=`solidos-human-readable-preview`,l=`allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-modals`,u=e=>e.includes(`<script src="https://dokie.li/scripts/dokieli.js">`)||e.includes(`dokieli.css`);function d(e){return e.replace(/&/g,`&amp;`).replace(/"/g,`&quot;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}function f(e,t){let n=e.match(/<base(\s[^>]*)?>/i);if(n&&n.index!==void 0){let r=n[0].match(/\bhref\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i),i=r?.[1]??r?.[2]??r?.[3];if(!r||i===void 0||/^[a-z][a-z\d+.-]*:/i.test(i)||i.startsWith(`//`))return e;let a;try{a=new URL(i,t).href}catch{return e}let o=n[0].replace(r[0],`href="${d(a)}"`);return e.slice(0,n.index)+o+e.slice(n.index+n[0].length)}let r=`<base href="${d(t)}">`,i=e.match(/<head(\s[^>]*)?>/i);if(i&&i.index!==void 0){let t=i.index+i[0].length;return e.slice(0,t)+r+e.slice(t)}return r+e}function p(e){let t=e.split(`/`).pop()||e;try{return decodeURIComponent(t)}catch{return t}}function m(e,t){let n=p(t);try{return new DOMParser().parseFromString(e,`text/html`).querySelector(`title`)?.textContent?.trim()||n}catch{return n}}var h=`solidos-preview-request`,g=`solidos-preview-response`,_=new Set([`GET`,`PUT`,`PATCH`,`DELETE`]);function v(e){return e===`about:srcdoc`||/^file:\/\/srcdoc\/?(?:[?#].*)?$/i.test(e)}function y(e,t){let n=new URL(e,t).href;return v(n)?t:n}function b(e,t,n){let r=`<script>
2
+ (() => {
3
+ const documentUri = ${JSON.stringify(t)}
4
+ const nonce = ${JSON.stringify(n)}
5
+ const pending = new Map()
6
+ let requestId = 0
7
+ try {
8
+ history.replaceState(null, '', documentUri)
9
+ } catch {
10
+ // Sandboxed documents may reject cross-origin history URLs.
11
+ }
12
+ // Opaque sandbox origins cannot use IndexedDB. Dokieli uses it for local
13
+ // preferences and history, so provide an in-memory implementation without
14
+ // granting the preview a persistent storage capability.
15
+ try {
16
+ window.indexedDB.open('__solidos_probe__')
17
+ } catch {
18
+ const databases = new Map()
19
+ const request = (result) => ({ result, error: null, onsuccess: null, onerror: null, onupgradeneeded: null })
20
+ const isolatedIndexedDB = {
21
+ open (name) {
22
+ const stores = databases.get(name) || new Map()
23
+ databases.set(name, stores)
24
+ const database = {
25
+ objectStoreNames: { contains: storeName => stores.has(storeName) },
26
+ createObjectStore (storeName) {
27
+ if (!stores.has(storeName)) stores.set(storeName, new Map())
28
+ return database.transaction(storeName, 'readwrite').objectStore(storeName)
29
+ },
30
+ transaction (storeName, mode = 'readonly') {
31
+ const store = stores.get(storeName) || new Map()
32
+ stores.set(storeName, store)
33
+ let pending = 0
34
+ let completed = false
35
+ const transaction = {
36
+ oncomplete: null,
37
+ onerror: null,
38
+ onabort: null,
39
+ objectStore: () => {
40
+ const run = (result, change) => {
41
+ const operation = request(result)
42
+ pending++
43
+ queueMicrotask(() => {
44
+ try {
45
+ change?.()
46
+ operation.onsuccess?.({ target: operation })
47
+ } catch (error) {
48
+ operation.error = error
49
+ operation.onerror?.({ target: operation })
50
+ } finally {
51
+ pending--
52
+ if (!pending && !completed) {
53
+ completed = true
54
+ transaction.oncomplete?.({ target: transaction })
55
+ }
56
+ }
57
+ })
58
+ return operation
59
+ }
60
+ return {
61
+ get: key => run(store.get(key)),
62
+ getAll: () => run(Array.from(store.values())),
63
+ getAllKeys: () => run(Array.from(store.keys())),
64
+ count: () => run(store.size),
65
+ openKeyCursor () {
66
+ const keys = Array.from(store.keys())
67
+ const operation = request(null)
68
+ pending++
69
+ let index = 0
70
+ const emit = () => {
71
+ operation.result = index < keys.length
72
+ ? { key: keys[index], continue: () => { index++; queueMicrotask(emit) } }
73
+ : null
74
+ operation.onsuccess?.({ target: operation })
75
+ if (!operation.result) {
76
+ pending--
77
+ if (!pending && !completed) {
78
+ completed = true
79
+ transaction.oncomplete?.({ target: transaction })
80
+ }
81
+ }
82
+ }
83
+ queueMicrotask(emit)
84
+ return operation
85
+ },
86
+ put: (value, key) => run(undefined, () => store.set(key, value)),
87
+ add: (value, key) => run(undefined, () => store.set(key, value)),
88
+ delete: key => run(undefined, () => store.delete(key)),
89
+ clear: () => run(undefined, () => store.clear())
90
+ }
91
+ }
92
+ }
93
+ return transaction
94
+ },
95
+ close () {}
96
+ }
97
+ const operation = request(database)
98
+ queueMicrotask(() => {
99
+ operation.onupgradeneeded?.({ target: operation })
100
+ operation.onsuccess?.({ target: operation })
101
+ })
102
+ return operation
103
+ },
104
+ deleteDatabase (name) {
105
+ databases.delete(name)
106
+ const operation = request(undefined)
107
+ queueMicrotask(() => operation.onsuccess?.({ target: operation }))
108
+ return operation
109
+ }
110
+ }
111
+ Object.defineProperty(window, 'indexedDB', { configurable: true, value: isolatedIndexedDB })
112
+ }
113
+ const nativeFetch = window.fetch.bind(window)
114
+
115
+ function isSrcdocUrl (url) {
116
+ return url === 'about:srcdoc' || /^file:\\/\\/srcdoc\\/?(?:[?#].*)?$/i.test(url)
117
+ }
118
+
119
+ function documentRequestUrl (url) {
120
+ const resolvedUrl = new URL(url, documentUri).href
121
+ // srcdoc keeps this URL even when history.replaceState is unavailable in
122
+ // an opaque sandbox. Dokieli saves via document.location.href.
123
+ return isSrcdocUrl(resolvedUrl) ? documentUri : resolvedUrl
124
+ }
125
+
126
+ function requestParent (url, init) {
127
+ const id = String(++requestId)
128
+ return new Promise((resolve, reject) => {
129
+ pending.set(id, { resolve, reject })
130
+ window.parent.postMessage({
131
+ type: ${JSON.stringify(h)},
132
+ nonce,
133
+ id,
134
+ url,
135
+ method: init.method,
136
+ headers: init.headers,
137
+ body: init.body
138
+ }, '*')
139
+ })
140
+ }
141
+
142
+ window.addEventListener('message', event => {
143
+ const message = event.data
144
+ if (!message || message.type !== ${JSON.stringify(g)} || message.nonce !== nonce) return
145
+ const entry = pending.get(message.id)
146
+ if (!entry) return
147
+ pending.delete(message.id)
148
+ if (!message.ok) {
149
+ entry.reject(new Error(message.error || 'Preview request failed'))
150
+ return
151
+ }
152
+ const responseBody = [204, 205, 304].includes(message.status) ? null : message.body
153
+ entry.resolve(new Response(responseBody, {
154
+ status: message.status,
155
+ headers: message.headers
156
+ }))
157
+ })
158
+
159
+ window.fetch = async (input, init = {}) => {
160
+ const request = input instanceof Request ? input : null
161
+ const url = documentRequestUrl(request ? request.url : input)
162
+ const method = (init.method || (request && request.method) || 'GET').toUpperCase()
163
+ if (url !== documentUri || !${JSON.stringify(Array.from(_))}.includes(method)) {
164
+ return nativeFetch(input, init)
165
+ }
166
+ const headers = new Headers(request ? request.headers : undefined)
167
+ for (const [key, value] of new Headers(init.headers || {}).entries()) headers.set(key, value)
168
+ const body = method === 'GET' || method === 'HEAD'
169
+ ? undefined
170
+ : (init.body || (request ? await request.clone().text() : undefined))
171
+ return requestParent(url, {
172
+ method,
173
+ headers: Object.fromEntries(headers.entries()),
174
+ body
175
+ })
176
+ }
177
+
178
+ const NativeXMLHttpRequest = window.XMLHttpRequest
179
+ window.XMLHttpRequest = class PreviewXMLHttpRequest {
180
+ constructor () {
181
+ this._native = new NativeXMLHttpRequest()
182
+ this._headers = {}
183
+ this._listeners = {}
184
+ this._intercepted = false
185
+ this.readyState = 0
186
+ this.status = 0
187
+ this.statusText = ''
188
+ this.response = null
189
+ this.responseText = ''
190
+ }
191
+
192
+ addEventListener (type, listener) {
193
+ this._listeners[type] = this._listeners[type] || []
194
+ this._listeners[type].push(listener)
195
+ }
196
+
197
+ _emit (type) {
198
+ const event = { target: this, currentTarget: this, type }
199
+ if (typeof this['on' + type] === 'function') this['on' + type](event)
200
+ for (const listener of this._listeners[type] || []) listener.call(this, event)
201
+ }
202
+
203
+ open (method, url, async = true, user, password) {
204
+ const resolvedUrl = documentRequestUrl(url)
205
+ this._method = String(method || 'GET').toUpperCase()
206
+ this._url = resolvedUrl
207
+ this._intercepted = resolvedUrl === documentUri &&
208
+ ${JSON.stringify(Array.from(_))}.includes(this._method)
209
+ if (!this._intercepted) {
210
+ this._native.open(method, url, async, user, password)
211
+ for (const type of ['abort', 'error', 'load', 'loadend', 'progress', 'readystatechange', 'timeout']) {
212
+ this._native.addEventListener(type, event => this._emitNative(type, event))
213
+ }
214
+ }
215
+ this.readyState = 1
216
+ this._emit('readystatechange')
217
+ }
218
+
219
+ _emitNative (type, event) {
220
+ this.readyState = this._native.readyState
221
+ this.status = this._native.status
222
+ this.statusText = this._native.statusText
223
+ this.response = this._native.response
224
+ this.responseText = this._native.responseText
225
+ this._emit(type)
226
+ }
227
+
228
+ setRequestHeader (name, value) {
229
+ if (this._intercepted) this._headers[name] = value
230
+ else this._native.setRequestHeader(name, value)
231
+ }
232
+
233
+ send (body) {
234
+ if (!this._intercepted) {
235
+ this._native.send(body)
236
+ return
237
+ }
238
+ requestParent(this._url, {
239
+ method: this._method,
240
+ headers: this._headers,
241
+ body: this._method === 'GET' || this._method === 'HEAD' ? undefined : body
242
+ }).then(async response => {
243
+ this.status = response.status
244
+ this.statusText = response.statusText
245
+ this._responseHeaders = response.headers
246
+ this.responseText = await response.text()
247
+ this.response = this.responseText
248
+ this.readyState = 4
249
+ this._emit('readystatechange')
250
+ this._emit(response.ok ? 'load' : 'error')
251
+ this._emit('loadend')
252
+ }).catch(() => {
253
+ this.readyState = 4
254
+ this._emit('readystatechange')
255
+ this._emit('error')
256
+ this._emit('loadend')
257
+ })
258
+ }
259
+
260
+ abort () {
261
+ if (!this._intercepted) this._native.abort()
262
+ this._emit('abort')
263
+ }
264
+
265
+ getResponseHeader (name) {
266
+ return this._responseHeaders?.get(name) || null
267
+ }
268
+
269
+ getAllResponseHeaders () {
270
+ return this._responseHeaders
271
+ ? Array.from(this._responseHeaders.entries()).map(([key, value]) => key + ': ' + value).join('\\r\\n')
272
+ : ''
273
+ }
274
+ }
275
+ })()
276
+ <\/script>`;return f(e,t).replace(/<head(\s[^>]*)?>/i,e=>`${e}${r}`)}function x(e,t,n,r){let i=e.ownerDocument.defaultView;if(!i)return;let a=new Uint32Array(4);i.crypto.getRandomValues(a);let o=Array.from(a,e=>e.toString(16)).join(`-`),s=new URL(t).href;i.addEventListener(`message`,t=>{let n=t.data;if(t.source!==e.contentWindow||!n||n.type!==h||n.nonce!==o||y(n.url,s)!==s||!_.has(n.method))return;let i=t=>{e.contentWindow?.postMessage(t,`*`)};r(s,{method:n.method,headers:n.headers,body:n.method===`GET`?void 0:n.body}).then(async e=>{i({type:g,nonce:o,id:n.id,ok:e.ok,status:e.status,headers:Array.from(e.headers.entries()),body:await e.text()})}).catch(e=>{i({type:g,nonce:o,id:n.id,ok:!1,status:0,headers:[],body:``,error:e instanceof Error?e.message:String(e)})})}),e.setAttribute(`sandbox`,l),e.srcdoc=b(n,s,o)}var S={icon:function(e,n){if(e&&a(e.uri))return t.icons.iconBase+`markdown.svg`;if(e){let r=n.session.store,i=o.get(e.uri);if(i===`dokieli`)return t.icons.iconBase+`dokieli-logo.png`;if(i===`html`)return t.icons.originalIconBase+`tango/22-text-x-generic.png`;let a=r.fetcher.getHeader(e.doc(),`content`);if(a&&a.length>0){let n=a[0],r=n.includes(`<script src="https://dokie.li/scripts/dokieli.js">`)||n.includes(`dokieli.css`);return o.set(e.uri,r?`dokieli`:`html`),r?t.icons.iconBase+`dokieli-logo.png`:t.icons.originalIconBase+`tango/22-text-x-generic.png`}let s=r.fetcher.getHeader(e.doc(),`content-type`);if((s?s[0].split(`;`,1)[0].trim():null)===`text/html`)return r.fetcher._fetch(e.uri).then(e=>e.text()).then(n=>{let r=n.includes(`<script src="https://dokie.li/scripts/dokieli.js">`)||n.includes(`dokieli.css`);return o.set(e.uri,r?`dokieli`:`html`),r?t.icons.iconBase+`dokieli-logo.png`:t.icons.originalIconBase+`tango/22-text-x-generic.png`}).catch(()=>(o.set(e.uri,`html`),t.icons.originalIconBase+`tango/22-text-x-generic.png`))}return t.icons.originalIconBase+`tango/22-text-x-generic.png`},name:`humanReadable`,label:function(e,r){let i=r.session.store,s=[`text/plain`,`text/html`,`text/markdown`,`application/xhtml+xml`,`application/pdf`,`video/mp4`],c=function(e,t,n){let r=e.fetcher.getHeader(t,`content-type`);if(r){for(let e=0;e<r.length;e++)for(let t=0;t<n.length;t++)if(r[e].indexOf(n[t])>=0)return!0}return!1},l=function(e,t,r){let i=e.findTypeURIs(t);for(let e=0;e<r.length;e++)if(n.Util.mediaTypeClass(r[e]).uri in i)return!0;return!1};if(!e.uri)return null;if(i.findTypeURIs(e)[t.ns.link(`WebPage`).uri])return`Webpage`;if(a(e.uri))return`View`;if(c(i,e,s)||l(i,e,s)){let t=i.fetcher.getHeader(e.doc(),`content-type`);return(t?t[0].split(`;`,1)[0].trim():null)===`text/html`&&!o.has(e.uri)&&i.fetcher._fetch(e.uri).then(e=>e.text()).then(t=>{let n=t.includes(`<script src="https://dokie.li/scripts/dokieli.js">`)||t.includes(`dokieli.css`);o.set(e.uri,n?`dokieli`:`html`)}).catch(()=>{o.set(e.uri,`html`)}),`View`}return null},render:function(e,t){let n=t.dom,h=n.createElement(`div`),g=t.session.store;function _(e){let n=t.environment??{};e.dataset.layout=n.layout??`desktop`}let v=g.fetcher.getHeader(e.doc(),`content-type`),y=v?v[0].split(`;`,1)[0].trim():null,b=y===`text/markdown`||a(e.uri),S=y===`text/plain`;y||console.log(`humanReadablePane: unknown content-type?`),h.classList.add(`human-readable-pane`),_(h);let C=function(t){g.fetcher.webOperation(`GET`,e.uri).then(e=>{let n=e.responseText??``,a=Math.min(30,n.split(/\n/).length+5),o=r.marked.parse(n,{async:!1});t.innerHTML=i.default.sanitize(o),s(t,`markdown`,a)}).catch(e=>{console.error(`Error fetching markdown content:`,e),t.innerHTML=`<p>Error loading content</p>`})},w=function(t){g.fetcher.webOperation(`GET`,e.uri).then(e=>{let n=e.responseText??``,r=Math.min(30,n.split(/\n/).length+5);t.textContent=n,s(t,`plain-text`,r)}).catch(e=>{console.error(`Error fetching plain text content:`,e),t.textContent=`Error loading content`})};if(b){let e=n.createElement(`div`);C(e);let t=n.createElement(`div`);t.classList.add(`human-readable-pane__container`),t.appendChild(e),h.appendChild(t)}else if(S){let e=n.createElement(`pre`);w(e);let t=n.createElement(`div`);t.classList.add(`human-readable-pane__container`),t.appendChild(e),h.appendChild(t)}else{let t=n.createElement(`iframe`);t.name=c,t.title=p(e.uri),s(t,`iframe`);let r=y===`text/html`||y===`application/xhtml+xml`,i=null,a=!1,_=!1,v=typeof MutationObserver>`u`?null:new MutationObserver(e=>{let t=e.some(e=>Array.from(e.addedNodes).some(e=>e===h||e.nodeType===Node.ELEMENT_NODE&&e.contains(h)));h.isConnected?_=!0:(_||t)&&(a=!0,i&&=(URL.revokeObjectURL(i),null),v?.disconnect())});v?.observe(n,{childList:!0,subtree:!0});let b=e=>{t.removeAttribute(`src`),t.setAttribute(`sandbox`,``),t.srcdoc=`<p style="font-family: sans-serif">${d(e)}</p>`};r?g.fetcher.webOperation(`GET`,e.uri).then(n=>{let r=n.responseText??``;t.title=m(r,e.uri);let i=u(r);o.set(e.uri,i?`dokieli`:`html`),i?x(t,e.uri,r,(e,t)=>g.fetcher._fetch(e,t)):(t.setAttribute(`sandbox`,l),t.srcdoc=f(r,e.uri))}).catch(e=>{console.error(`Error fetching HTML content:`,e),b(`Error loading content`)}):g.fetcher._fetch(e.uri).then(async n=>{if(!n.ok)throw Error(`HTTP ${n.status}`);let r=n.headers.get(`content-type`)?.split(`;`,1)[0].trim().toLowerCase();if(r===`text/html`||r===`application/xhtml+xml`){let r=await n.text();t.title=m(r,e.uri);let i=u(r);o.set(e.uri,i?`dokieli`:`html`),i?x(t,e.uri,r,(e,t)=>g.fetcher._fetch(e,t)):(t.setAttribute(`sandbox`,l),t.srcdoc=f(r,e.uri));return}t.setAttribute(`sandbox`,l);let s=URL.createObjectURL(await n.blob());a?URL.revokeObjectURL(s):(i=s,t.src=s)}).catch(e=>{console.error(`Error fetching content:`,e),b(`Error loading content`)});let S=n.createElement(`div`);S.classList.add(`human-readable-pane__container`),S.classList.add(`human-readable-pane__container--iframe`),S.appendChild(t),h.appendChild(S),h.classList.add(`human-readable-pane--iframe`)}return h}};exports.HUMAN_READABLE_PREVIEW_FRAME_NAME=c,exports.default=S,exports.previewRequestUrl=y,exports.withBaseHref=f;
2
277
  //# sourceMappingURL=humanReadablePane2.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"humanReadablePane2.cjs.js","names":["icons","Util","ns","DOMPurify","require_runtime","solid_ui","rdflib","marked","dompurify","isMarkdownFile","uri","path","dokieliCache","applyFrameClasses","frame","modifier","lines","humanReadablePane","subject","kb","context","cachedResult","responseText","text","isDokieli","cts","response","allowed","hasContentTypeIn","x","j","k","displayables","hasContentTypeIn2","t","myDocument","div","applyEnvironmentAttributes","environment","ct","isMarkdown","isPlainText","renderMarkdownContent","markdownText","res","error","renderPlainTextContent","plainText","setIframeAttributes","frameContainer","blobText","newLines"],"sources":["../src/humanReadablePane.ts"],"sourcesContent":["/* Human-readable Pane\n **\n ** This outline pane contains the document contents for an HTML document\n ** This is for peeking at a page, because the user might not want to leave the data browser.\n */\nimport { icons, ns } from 'solid-ui'\nimport { Util } from 'rdflib'\nimport { marked } from 'marked'\nimport DOMPurify from 'dompurify'\nimport type { DataBrowserContext, RenderEnvironment } from 'pane-registry'\nimport type { NamedNode } from 'rdflib'\nimport './humanReadablePane.css'\n\n// Helper function to check if a URI has a markdown file extension\ntype DokieliCacheValue = 'dokieli' | 'html'\n\ntype HumanReadableIcon = string | Promise<string>\n\ntype HumanReadablePaneDefinition = {\n icon: (subject: NamedNode, context: DataBrowserContext) => HumanReadableIcon\n name: string\n label: (subject: NamedNode, context: DataBrowserContext) => 'Webpage' | 'View' | null\n render: (subject: NamedNode, context: DataBrowserContext) => HTMLDivElement\n}\n\nconst isMarkdownFile = (uri?: string | null): boolean => {\n if (!uri) return false\n const path = uri.split('?')[0].split('#')[0] // Remove query string and fragment\n return /\\.(md|markdown|mdown|mkd|mkdn)$/i.test(path)\n}\n\n// Cache for dokieli detection results (keyed by subject URI)\nconst dokieliCache = new Map<string, DokieliCacheValue>()\n\nfunction applyFrameClasses (\n frame: HTMLElement,\n modifier: 'markdown' | 'plain-text' | 'iframe',\n lines: number\n): void {\n frame.className = ''\n frame.classList.add('human-readable-pane__frame')\n frame.classList.add(`human-readable-pane__frame--${modifier}`)\n frame.style.setProperty('--human-readable-pane-height', `${lines}em`)\n}\n\nconst humanReadablePane: HumanReadablePaneDefinition = {\n icon: function (subject: NamedNode, context: DataBrowserContext): HumanReadableIcon {\n // Markdown files detected by extension\n if (subject && isMarkdownFile(subject.uri)) {\n return icons.iconBase + 'markdown.svg'\n }\n\n // Dokieli files detected by content check\n if (subject) {\n const kb = context.session.store\n\n // Check cache from previous detection\n const cachedResult = dokieliCache.get(subject.uri)\n if (cachedResult === 'dokieli') {\n return icons.iconBase + 'dokieli-logo.png'\n } else if (cachedResult === 'html') {\n return icons.originalIconBase + 'tango/22-text-x-generic.png'\n }\n\n // Check if content already fetched (synchronous)\n const responseText = kb.fetcher.getHeader(subject.doc(), 'content')\n if (responseText && responseText.length > 0) {\n const text = responseText[0]\n const isDokieli = text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n text.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n return isDokieli\n ? icons.iconBase + 'dokieli-logo.png'\n : icons.originalIconBase + 'tango/22-text-x-generic.png'\n }\n\n // Content not yet fetched - return a promise (async detection)\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null\n\n if (ct === 'text/html') {\n return kb.fetcher._fetch(subject.uri)\n .then(response => response.text())\n .then(text => {\n const isDokieli = text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n text.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n return isDokieli\n ? icons.iconBase + 'dokieli-logo.png'\n : icons.originalIconBase + 'tango/22-text-x-generic.png'\n })\n .catch(() => {\n dokieliCache.set(subject.uri, 'html')\n return icons.originalIconBase + 'tango/22-text-x-generic.png'\n })\n }\n }\n\n // Default for all other human-readable content\n return icons.originalIconBase + 'tango/22-text-x-generic.png'\n },\n\n name: 'humanReadable',\n\n label: function (\n subject: NamedNode,\n context: DataBrowserContext\n ): 'Webpage' | 'View' | null {\n const kb = context.session.store\n\n // See also the source pane, which has lower precedence.\n\n const allowed = [\n 'text/plain',\n 'text/html',\n 'text/markdown',\n 'application/xhtml+xml',\n 'image/png',\n 'image/jpeg',\n 'application/pdf',\n 'video/mp4'\n ]\n\n const hasContentTypeIn = function (\n kb: typeof context.session.store,\n x: NamedNode,\n displayables: string[]\n ): boolean {\n const cts = kb.fetcher.getHeader(x, 'content-type')\n if (cts) {\n for (let j = 0; j < cts.length; j++) {\n for (let k = 0; k < displayables.length; k++) {\n if (cts[j].indexOf(displayables[k]) >= 0) {\n return true\n }\n }\n }\n }\n return false\n }\n\n // This data could come from a fetch OR from ldp container\n const hasContentTypeIn2 = function (\n kb: typeof context.session.store,\n x: NamedNode,\n displayables: string[]\n ): boolean {\n const t = kb.findTypeURIs(x)\n for (let k = 0; k < displayables.length; k++) {\n if (Util.mediaTypeClass(displayables[k]).uri in t) {\n return true\n }\n }\n return false\n }\n\n if (!subject.uri) return null // no bnodes\n\n const t = kb.findTypeURIs(subject)\n if (t[ns.link('WebPage').uri]) return 'Webpage'\n\n // Check file extension for markdown files\n if (isMarkdownFile(subject.uri)) {\n return 'View'\n }\n\n if (\n hasContentTypeIn(kb, subject, allowed) ||\n hasContentTypeIn2(kb, subject, allowed)\n ) {\n // For HTML files, check if it's dokieli (async check, store result for later)\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null\n\n if (ct === 'text/html' && !dokieliCache.has(subject.uri)) {\n // Async check for dokieli, don't wait for result\n kb.fetcher._fetch(subject.uri)\n .then(response => response.text())\n .then(text => {\n const isDokieli = text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n text.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n })\n .catch(() => {\n dokieliCache.set(subject.uri, 'html')\n })\n }\n\n return 'View'\n }\n\n return null\n },\n\n render: function (\n subject: NamedNode,\n context: DataBrowserContext\n ): HTMLDivElement {\n const myDocument = context.dom\n const div = myDocument.createElement('div')\n const kb = context.session.store\n\n function applyEnvironmentAttributes (element: HTMLDivElement): void {\n const environment = (context.environment ?? {}) as Partial<RenderEnvironment>\n element.dataset.layout = environment.layout ?? 'desktop'\n }\n\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null // remove content-type parameters\n\n // Fallback: detect markdown by file extension if content-type is not text/markdown\n const isMarkdown = ct === 'text/markdown' || isMarkdownFile(subject.uri)\n const isPlainText = ct === 'text/plain'\n\n if (ct) {\n // console.log('humanReadablePane: c-t:' + ct)\n } else {\n console.log('humanReadablePane: unknown content-type?')\n }\n\n // @@ When we can, use CSP to turn off scripts within the iframe\n div.classList.add('human-readable-pane')\n applyEnvironmentAttributes(div)\n\n // render markdown to html in a DIV element\n const renderMarkdownContent = function (frame: HTMLDivElement) {\n kb.fetcher.webOperation('GET', subject.uri).then(response => {\n const markdownText = response.responseText ?? ''\n const lines = Math.min(30, markdownText.split(/\\n/).length + 5)\n const res = marked.parse(markdownText, { async: false })\n const clean = DOMPurify.sanitize(res)\n frame.innerHTML = clean\n applyFrameClasses(frame, 'markdown', lines)\n }).catch(error => {\n console.error('Error fetching markdown content:', error)\n frame.innerHTML = '<p>Error loading content</p>'\n })\n }\n\n // render plain text in a PRE element\n const renderPlainTextContent = function (frame: HTMLPreElement) {\n kb.fetcher.webOperation('GET', subject.uri).then(response => {\n const plainText = response.responseText ?? ''\n const lines = Math.min(30, plainText.split(/\\n/).length + 5)\n frame.textContent = plainText\n applyFrameClasses(frame, 'plain-text', lines)\n }).catch(error => {\n console.error('Error fetching plain text content:', error)\n frame.textContent = 'Error loading content'\n })\n }\n\n const setIframeAttributes = (frame: HTMLIFrameElement, lines: number) => {\n frame.setAttribute('src', subject.uri)\n applyFrameClasses(frame, 'iframe', lines)\n }\n\n if (isMarkdown) {\n // For markdown, use a DIV element and render the content\n const frame = myDocument.createElement('div')\n renderMarkdownContent(frame)\n const frameContainer = myDocument.createElement('div')\n frameContainer.classList.add('human-readable-pane__container')\n frameContainer.appendChild(frame)\n div.appendChild(frameContainer)\n } else if (isPlainText) {\n // For plain text, use a PRE element and render the content\n const frame = myDocument.createElement('pre')\n renderPlainTextContent(frame)\n const frameContainer = myDocument.createElement('div')\n frameContainer.classList.add('human-readable-pane__container')\n frameContainer.appendChild(frame)\n div.appendChild(frameContainer)\n } else {\n // For other content types, use IFRAME\n const frame = myDocument.createElement('iframe')\n\n // Apply sandbox for HTML/XHTML\n if (ct === 'text/html' || ct === 'application/xhtml+xml') {\n frame.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms')\n }\n\n // Fetch content to calculate lines dynamically\n kb.fetcher.webOperation('GET', subject.uri).then(response => {\n const blobText = response.responseText ?? ''\n const newLines = blobText.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ? -10 : 5\n const lines = Math.min(30, blobText.split(/\\n/).length + newLines)\n\n // Cache dokieli detection result\n const isDokieli = blobText.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n blobText.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n\n setIframeAttributes(frame, lines)\n }).catch(error => {\n console.error('Error fetching content for line calculation:', error)\n // Fallback to default height\n setIframeAttributes(frame, 30)\n })\n\n const frameContainer = myDocument.createElement('div')\n frameContainer.classList.add('human-readable-pane__container')\n frameContainer.appendChild(frame)\n div.appendChild(frameContainer)\n }\n\n return div\n }\n}\n\nexport default humanReadablePane\n// ends\n"],"mappings":"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"}
1
+ {"version":3,"file":"humanReadablePane2.cjs.js","names":["icons","Util","ns","DOMPurify","require_runtime","solid_ui","rdflib","marked","dompurify","isMarkdownFile","uri","path","dokieliCache","applyFrameClasses","frame","modifier","lines","HUMAN_READABLE_PREVIEW_FRAME_NAME","HTML_PREVIEW_SANDBOX","isDokieliHtml","text","escapeAttribute","value","withBaseHref","existingBase","html","href","existingHref","resolvedHref","baseUri","resolvedBase","base","headMatch","insertAt","resourceFilename","encodedFilename","documentTitle","fallback","PREVIEW_REQUEST_TYPE","PREVIEW_RESPONSE_TYPE","PREVIEW_METHODS","isSrcdocUrl","url","previewRequestUrl","resolvedUrl","documentUri","createPreviewBridge","bridge","nonce","match","mountDokieliBridge","ownerWindow","randomValues","expectedUri","request","event","respond","response","authenticatedFetch","error","humanReadablePane","subject","kb","context","cachedResult","responseText","isDokieli","cts","allowed","hasContentTypeIn","x","j","k","displayables","hasContentTypeIn2","t","myDocument","div","applyEnvironmentAttributes","environment","ct","isMarkdown","isPlainText","renderMarkdownContent","markdownText","res","renderPlainTextContent","plainText","frameContainer","isHtml","previewUrl","disposed","wasConnected","mutationObserver","wasAdded","records","record","node","showError","message","init","responseContentType","objectUrl"],"sources":["../src/humanReadablePane.ts"],"sourcesContent":["/* Human-readable Pane\n **\n ** This outline pane contains the document contents for an HTML document\n ** This is for peeking at a page, because the user might not want to leave the data browser.\n */\nimport { icons, ns } from 'solid-ui'\nimport { Util } from 'rdflib'\nimport { marked } from 'marked'\nimport DOMPurify from 'dompurify'\nimport type { DataBrowserContext, RenderEnvironment } from 'pane-registry'\nimport type { NamedNode } from 'rdflib'\nimport './humanReadablePane.css'\n\n// Helper function to check if a URI has a markdown file extension\ntype DokieliCacheValue = 'dokieli' | 'html'\n\ntype HumanReadableIcon = string | Promise<string>\n\ntype HumanReadablePaneDefinition = {\n icon: (subject: NamedNode, context: DataBrowserContext) => HumanReadableIcon\n name: string\n label: (subject: NamedNode, context: DataBrowserContext) => 'Webpage' | 'View' | null\n render: (subject: NamedNode, context: DataBrowserContext) => HTMLDivElement\n}\n\nconst isMarkdownFile = (uri?: string | null): boolean => {\n if (!uri) return false\n const path = uri.split('?')[0].split('#')[0] // Remove query string and fragment\n return /\\.(md|markdown|mdown|mkd|mkdn)$/i.test(path)\n}\n\n// Cache for dokieli detection results (keyed by subject URI)\nconst dokieliCache = new Map<string, DokieliCacheValue>()\n\nfunction applyFrameClasses (\n frame: HTMLElement,\n modifier: 'markdown' | 'plain-text' | 'iframe',\n lines?: number\n): void {\n frame.className = ''\n frame.classList.add('human-readable-pane__frame')\n frame.classList.add(`human-readable-pane__frame--${modifier}`)\n if (lines !== undefined) {\n frame.style.setProperty('--human-readable-pane-height', `${lines}em`)\n }\n}\n\n// window.name of preview iframes; initMainPage refuses to boot SolidOS inside such a frame.\nexport const HUMAN_READABLE_PREVIEW_FRAME_NAME = 'solidos-human-readable-preview'\n\n// Scripts may run but get an opaque origin, so previewed pages cannot reach the SolidOS session.\nconst HTML_PREVIEW_SANDBOX = 'allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-modals'\n\nconst isDokieliHtml = (text: string): boolean =>\n text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') || text.includes('dokieli.css')\n\nfunction escapeAttribute (value: string): string {\n return value.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\n// srcdoc documents resolve relative URLs against about:srcdoc, so point them back at the resource.\nexport function withBaseHref (html: string, baseUri: string): string {\n const existingBase = html.match(/<base(\\s[^>]*)?>/i)\n if (existingBase && existingBase.index !== undefined) {\n const href = existingBase[0].match(/\\bhref\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+))/i)\n const existingHref = href?.[1] ?? href?.[2] ?? href?.[3]\n if (!href || existingHref === undefined) return html\n if (/^[a-z][a-z\\d+.-]*:/i.test(existingHref) || existingHref.startsWith('//')) return html\n let resolvedHref: string\n try {\n resolvedHref = new URL(existingHref, baseUri).href\n } catch {\n return html\n }\n const resolvedBase = existingBase[0].replace(href[0], `href=\"${escapeAttribute(resolvedHref)}\"`)\n return html.slice(0, existingBase.index) + resolvedBase + html.slice(existingBase.index + existingBase[0].length)\n }\n const base = `<base href=\"${escapeAttribute(baseUri)}\">`\n const headMatch = html.match(/<head(\\s[^>]*)?>/i)\n if (headMatch && headMatch.index !== undefined) {\n const insertAt = headMatch.index + headMatch[0].length\n return html.slice(0, insertAt) + base + html.slice(insertAt)\n }\n return base + html\n}\n\nfunction resourceFilename (uri: string): string {\n const encodedFilename = uri.split('/').pop() || uri\n try {\n return decodeURIComponent(encodedFilename)\n } catch {\n return encodedFilename\n }\n}\n\nfunction documentTitle (html: string, uri: string): string {\n const fallback = resourceFilename(uri)\n try {\n const title = new DOMParser().parseFromString(html, 'text/html').querySelector('title')?.textContent?.trim()\n return title || fallback\n } catch {\n return fallback\n }\n}\n\ntype PreviewRequest = {\n type: 'solidos-preview-request'\n nonce: string\n id: string\n url: string\n method: string\n headers?: Record<string, string>\n body?: string\n}\n\ntype PreviewResponse = {\n type: 'solidos-preview-response'\n nonce: string\n id: string\n ok: boolean\n status: number\n headers: Array<[string, string]>\n body: string\n error?: string\n}\n\nconst PREVIEW_REQUEST_TYPE = 'solidos-preview-request'\nconst PREVIEW_RESPONSE_TYPE = 'solidos-preview-response'\nconst PREVIEW_METHODS = new Set(['GET', 'PUT', 'PATCH', 'DELETE'])\n\nfunction isSrcdocUrl (url: string): boolean {\n return url === 'about:srcdoc' || /^file:\\/\\/srcdoc\\/?(?:[?#].*)?$/i.test(url)\n}\n\nexport function previewRequestUrl (url: string, documentUri: string): string {\n const resolvedUrl = new URL(url, documentUri).href\n return isSrcdocUrl(resolvedUrl) ? documentUri : resolvedUrl\n}\n\nfunction createPreviewBridge (html: string, uri: string, nonce: string): string {\n const bridge = `<script>\n(() => {\n const documentUri = ${JSON.stringify(uri)}\n const nonce = ${JSON.stringify(nonce)}\n const pending = new Map()\n let requestId = 0\n try {\n history.replaceState(null, '', documentUri)\n } catch {\n // Sandboxed documents may reject cross-origin history URLs.\n }\n // Opaque sandbox origins cannot use IndexedDB. Dokieli uses it for local\n // preferences and history, so provide an in-memory implementation without\n // granting the preview a persistent storage capability.\n try {\n window.indexedDB.open('__solidos_probe__')\n } catch {\n const databases = new Map()\n const request = (result) => ({ result, error: null, onsuccess: null, onerror: null, onupgradeneeded: null })\n const isolatedIndexedDB = {\n open (name) {\n const stores = databases.get(name) || new Map()\n databases.set(name, stores)\n const database = {\n objectStoreNames: { contains: storeName => stores.has(storeName) },\n createObjectStore (storeName) {\n if (!stores.has(storeName)) stores.set(storeName, new Map())\n return database.transaction(storeName, 'readwrite').objectStore(storeName)\n },\n transaction (storeName, mode = 'readonly') {\n const store = stores.get(storeName) || new Map()\n stores.set(storeName, store)\n let pending = 0\n let completed = false\n const transaction = {\n oncomplete: null,\n onerror: null,\n onabort: null,\n objectStore: () => {\n const run = (result, change) => {\n const operation = request(result)\n pending++\n queueMicrotask(() => {\n try {\n change?.()\n operation.onsuccess?.({ target: operation })\n } catch (error) {\n operation.error = error\n operation.onerror?.({ target: operation })\n } finally {\n pending--\n if (!pending && !completed) {\n completed = true\n transaction.oncomplete?.({ target: transaction })\n }\n }\n })\n return operation\n }\n return {\n get: key => run(store.get(key)),\n getAll: () => run(Array.from(store.values())),\n getAllKeys: () => run(Array.from(store.keys())),\n count: () => run(store.size),\n openKeyCursor () {\n const keys = Array.from(store.keys())\n const operation = request(null)\n pending++\n let index = 0\n const emit = () => {\n operation.result = index < keys.length\n ? { key: keys[index], continue: () => { index++; queueMicrotask(emit) } }\n : null\n operation.onsuccess?.({ target: operation })\n if (!operation.result) {\n pending--\n if (!pending && !completed) {\n completed = true\n transaction.oncomplete?.({ target: transaction })\n }\n }\n }\n queueMicrotask(emit)\n return operation\n },\n put: (value, key) => run(undefined, () => store.set(key, value)),\n add: (value, key) => run(undefined, () => store.set(key, value)),\n delete: key => run(undefined, () => store.delete(key)),\n clear: () => run(undefined, () => store.clear())\n }\n }\n }\n return transaction\n },\n close () {}\n }\n const operation = request(database)\n queueMicrotask(() => {\n operation.onupgradeneeded?.({ target: operation })\n operation.onsuccess?.({ target: operation })\n })\n return operation\n },\n deleteDatabase (name) {\n databases.delete(name)\n const operation = request(undefined)\n queueMicrotask(() => operation.onsuccess?.({ target: operation }))\n return operation\n }\n }\n Object.defineProperty(window, 'indexedDB', { configurable: true, value: isolatedIndexedDB })\n }\n const nativeFetch = window.fetch.bind(window)\n\n function isSrcdocUrl (url) {\n return url === 'about:srcdoc' || /^file:\\\\/\\\\/srcdoc\\\\/?(?:[?#].*)?$/i.test(url)\n }\n\n function documentRequestUrl (url) {\n const resolvedUrl = new URL(url, documentUri).href\n // srcdoc keeps this URL even when history.replaceState is unavailable in\n // an opaque sandbox. Dokieli saves via document.location.href.\n return isSrcdocUrl(resolvedUrl) ? documentUri : resolvedUrl\n }\n\n function requestParent (url, init) {\n const id = String(++requestId)\n return new Promise((resolve, reject) => {\n pending.set(id, { resolve, reject })\n window.parent.postMessage({\n type: ${JSON.stringify(PREVIEW_REQUEST_TYPE)},\n nonce,\n id,\n url,\n method: init.method,\n headers: init.headers,\n body: init.body\n }, '*')\n })\n }\n\n window.addEventListener('message', event => {\n const message = event.data\n if (!message || message.type !== ${JSON.stringify(PREVIEW_RESPONSE_TYPE)} || message.nonce !== nonce) return\n const entry = pending.get(message.id)\n if (!entry) return\n pending.delete(message.id)\n if (!message.ok) {\n entry.reject(new Error(message.error || 'Preview request failed'))\n return\n }\n const responseBody = [204, 205, 304].includes(message.status) ? null : message.body\n entry.resolve(new Response(responseBody, {\n status: message.status,\n headers: message.headers\n }))\n })\n\n window.fetch = async (input, init = {}) => {\n const request = input instanceof Request ? input : null\n const url = documentRequestUrl(request ? request.url : input)\n const method = (init.method || (request && request.method) || 'GET').toUpperCase()\n if (url !== documentUri || !${JSON.stringify(Array.from(PREVIEW_METHODS))}.includes(method)) {\n return nativeFetch(input, init)\n }\n const headers = new Headers(request ? request.headers : undefined)\n for (const [key, value] of new Headers(init.headers || {}).entries()) headers.set(key, value)\n const body = method === 'GET' || method === 'HEAD'\n ? undefined\n : (init.body || (request ? await request.clone().text() : undefined))\n return requestParent(url, {\n method,\n headers: Object.fromEntries(headers.entries()),\n body\n })\n }\n\n const NativeXMLHttpRequest = window.XMLHttpRequest\n window.XMLHttpRequest = class PreviewXMLHttpRequest {\n constructor () {\n this._native = new NativeXMLHttpRequest()\n this._headers = {}\n this._listeners = {}\n this._intercepted = false\n this.readyState = 0\n this.status = 0\n this.statusText = ''\n this.response = null\n this.responseText = ''\n }\n\n addEventListener (type, listener) {\n this._listeners[type] = this._listeners[type] || []\n this._listeners[type].push(listener)\n }\n\n _emit (type) {\n const event = { target: this, currentTarget: this, type }\n if (typeof this['on' + type] === 'function') this['on' + type](event)\n for (const listener of this._listeners[type] || []) listener.call(this, event)\n }\n\n open (method, url, async = true, user, password) {\n const resolvedUrl = documentRequestUrl(url)\n this._method = String(method || 'GET').toUpperCase()\n this._url = resolvedUrl\n this._intercepted = resolvedUrl === documentUri &&\n ${JSON.stringify(Array.from(PREVIEW_METHODS))}.includes(this._method)\n if (!this._intercepted) {\n this._native.open(method, url, async, user, password)\n for (const type of ['abort', 'error', 'load', 'loadend', 'progress', 'readystatechange', 'timeout']) {\n this._native.addEventListener(type, event => this._emitNative(type, event))\n }\n }\n this.readyState = 1\n this._emit('readystatechange')\n }\n\n _emitNative (type, event) {\n this.readyState = this._native.readyState\n this.status = this._native.status\n this.statusText = this._native.statusText\n this.response = this._native.response\n this.responseText = this._native.responseText\n this._emit(type)\n }\n\n setRequestHeader (name, value) {\n if (this._intercepted) this._headers[name] = value\n else this._native.setRequestHeader(name, value)\n }\n\n send (body) {\n if (!this._intercepted) {\n this._native.send(body)\n return\n }\n requestParent(this._url, {\n method: this._method,\n headers: this._headers,\n body: this._method === 'GET' || this._method === 'HEAD' ? undefined : body\n }).then(async response => {\n this.status = response.status\n this.statusText = response.statusText\n this._responseHeaders = response.headers\n this.responseText = await response.text()\n this.response = this.responseText\n this.readyState = 4\n this._emit('readystatechange')\n this._emit(response.ok ? 'load' : 'error')\n this._emit('loadend')\n }).catch(() => {\n this.readyState = 4\n this._emit('readystatechange')\n this._emit('error')\n this._emit('loadend')\n })\n }\n\n abort () {\n if (!this._intercepted) this._native.abort()\n this._emit('abort')\n }\n\n getResponseHeader (name) {\n return this._responseHeaders?.get(name) || null\n }\n\n getAllResponseHeaders () {\n return this._responseHeaders\n ? Array.from(this._responseHeaders.entries()).map(([key, value]) => key + ': ' + value).join('\\\\r\\\\n')\n : ''\n }\n }\n})()\n</script>`\n return withBaseHref(html, uri).replace(/<head(\\s[^>]*)?>/i, match => `${match}${bridge}`)\n}\n\nfunction mountDokieliBridge (\n frame: HTMLIFrameElement,\n uri: string,\n html: string,\n authenticatedFetch: (url: string, init?: RequestInit) => Promise<Response>\n): void {\n const ownerWindow = frame.ownerDocument.defaultView\n if (!ownerWindow) return\n\n const randomValues = new Uint32Array(4)\n ownerWindow.crypto.getRandomValues(randomValues)\n const nonce = Array.from(randomValues, value => value.toString(16)).join('-')\n const expectedUri = new URL(uri).href\n const listener = (event: MessageEvent<PreviewRequest>) => {\n const request = event.data\n if (\n event.source !== frame.contentWindow ||\n !request ||\n request.type !== PREVIEW_REQUEST_TYPE ||\n request.nonce !== nonce ||\n previewRequestUrl(request.url, expectedUri) !== expectedUri ||\n !PREVIEW_METHODS.has(request.method)\n ) return\n\n const respond = (response: PreviewResponse) => {\n frame.contentWindow?.postMessage(response, '*')\n }\n\n authenticatedFetch(expectedUri, {\n method: request.method,\n headers: request.headers,\n body: request.method === 'GET' ? undefined : request.body\n }).then(async response => {\n respond({\n type: PREVIEW_RESPONSE_TYPE,\n nonce,\n id: request.id,\n ok: response.ok,\n status: response.status,\n headers: Array.from(response.headers.entries()),\n body: await response.text()\n })\n }).catch(error => {\n respond({\n type: PREVIEW_RESPONSE_TYPE,\n nonce,\n id: request.id,\n ok: false,\n status: 0,\n headers: [],\n body: '',\n error: error instanceof Error ? error.message : String(error)\n })\n })\n }\n\n ownerWindow.addEventListener('message', listener)\n frame.setAttribute('sandbox', HTML_PREVIEW_SANDBOX)\n frame.srcdoc = createPreviewBridge(html, expectedUri, nonce)\n}\n\nconst humanReadablePane: HumanReadablePaneDefinition = {\n icon: function (subject: NamedNode, context: DataBrowserContext): HumanReadableIcon {\n // Markdown files detected by extension\n if (subject && isMarkdownFile(subject.uri)) {\n return icons.iconBase + 'markdown.svg'\n }\n\n // Dokieli files detected by content check\n if (subject) {\n const kb = context.session.store\n\n // Check cache from previous detection\n const cachedResult = dokieliCache.get(subject.uri)\n if (cachedResult === 'dokieli') {\n return icons.iconBase + 'dokieli-logo.png'\n } else if (cachedResult === 'html') {\n return icons.originalIconBase + 'tango/22-text-x-generic.png'\n }\n\n // Check if content already fetched (synchronous)\n const responseText = kb.fetcher.getHeader(subject.doc(), 'content')\n if (responseText && responseText.length > 0) {\n const text = responseText[0]\n const isDokieli = text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n text.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n return isDokieli\n ? icons.iconBase + 'dokieli-logo.png'\n : icons.originalIconBase + 'tango/22-text-x-generic.png'\n }\n\n // Content not yet fetched - return a promise (async detection)\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null\n\n if (ct === 'text/html') {\n return kb.fetcher._fetch(subject.uri)\n .then(response => response.text())\n .then(text => {\n const isDokieli = text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n text.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n return isDokieli\n ? icons.iconBase + 'dokieli-logo.png'\n : icons.originalIconBase + 'tango/22-text-x-generic.png'\n })\n .catch(() => {\n dokieliCache.set(subject.uri, 'html')\n return icons.originalIconBase + 'tango/22-text-x-generic.png'\n })\n }\n }\n\n // Default for all other human-readable content\n return icons.originalIconBase + 'tango/22-text-x-generic.png'\n },\n\n name: 'humanReadable',\n\n label: function (\n subject: NamedNode,\n context: DataBrowserContext\n ): 'Webpage' | 'View' | null {\n const kb = context.session.store\n\n // See also the source pane, which has lower precedence.\n\n const allowed = [\n 'text/plain',\n 'text/html',\n 'text/markdown',\n 'application/xhtml+xml',\n 'application/pdf',\n 'video/mp4'\n ]\n\n const hasContentTypeIn = function (\n kb: typeof context.session.store,\n x: NamedNode,\n displayables: string[]\n ): boolean {\n const cts = kb.fetcher.getHeader(x, 'content-type')\n if (cts) {\n for (let j = 0; j < cts.length; j++) {\n for (let k = 0; k < displayables.length; k++) {\n if (cts[j].indexOf(displayables[k]) >= 0) {\n return true\n }\n }\n }\n }\n return false\n }\n\n // This data could come from a fetch OR from ldp container\n const hasContentTypeIn2 = function (\n kb: typeof context.session.store,\n x: NamedNode,\n displayables: string[]\n ): boolean {\n const t = kb.findTypeURIs(x)\n for (let k = 0; k < displayables.length; k++) {\n if (Util.mediaTypeClass(displayables[k]).uri in t) {\n return true\n }\n }\n return false\n }\n\n if (!subject.uri) return null // no bnodes\n\n const t = kb.findTypeURIs(subject)\n if (t[ns.link('WebPage').uri]) return 'Webpage'\n\n // Check file extension for markdown files\n if (isMarkdownFile(subject.uri)) {\n return 'View'\n }\n\n if (\n hasContentTypeIn(kb, subject, allowed) ||\n hasContentTypeIn2(kb, subject, allowed)\n ) {\n // For HTML files, check if it's dokieli (async check, store result for later)\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null\n\n if (ct === 'text/html' && !dokieliCache.has(subject.uri)) {\n // Async check for dokieli, don't wait for result\n kb.fetcher._fetch(subject.uri)\n .then(response => response.text())\n .then(text => {\n const isDokieli = text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n text.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n })\n .catch(() => {\n dokieliCache.set(subject.uri, 'html')\n })\n }\n\n return 'View'\n }\n\n return null\n },\n\n render: function (\n subject: NamedNode,\n context: DataBrowserContext\n ): HTMLDivElement {\n const myDocument = context.dom\n const div = myDocument.createElement('div')\n const kb = context.session.store\n\n function applyEnvironmentAttributes (element: HTMLDivElement): void {\n const environment = (context.environment ?? {}) as Partial<RenderEnvironment>\n element.dataset.layout = environment.layout ?? 'desktop'\n }\n\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null // remove content-type parameters\n\n // Fallback: detect markdown by file extension if content-type is not text/markdown\n const isMarkdown = ct === 'text/markdown' || isMarkdownFile(subject.uri)\n const isPlainText = ct === 'text/plain'\n\n if (ct) {\n // console.log('humanReadablePane: c-t:' + ct)\n } else {\n console.log('humanReadablePane: unknown content-type?')\n }\n\n // @@ When we can, use CSP to turn off scripts within the iframe\n div.classList.add('human-readable-pane')\n applyEnvironmentAttributes(div)\n\n // render markdown to html in a DIV element\n const renderMarkdownContent = function (frame: HTMLDivElement) {\n kb.fetcher.webOperation('GET', subject.uri).then(response => {\n const markdownText = response.responseText ?? ''\n const lines = Math.min(30, markdownText.split(/\\n/).length + 5)\n const res = marked.parse(markdownText, { async: false })\n const clean = DOMPurify.sanitize(res)\n frame.innerHTML = clean\n applyFrameClasses(frame, 'markdown', lines)\n }).catch(error => {\n console.error('Error fetching markdown content:', error)\n frame.innerHTML = '<p>Error loading content</p>'\n })\n }\n\n // render plain text in a PRE element\n const renderPlainTextContent = function (frame: HTMLPreElement) {\n kb.fetcher.webOperation('GET', subject.uri).then(response => {\n const plainText = response.responseText ?? ''\n const lines = Math.min(30, plainText.split(/\\n/).length + 5)\n frame.textContent = plainText\n applyFrameClasses(frame, 'plain-text', lines)\n }).catch(error => {\n console.error('Error fetching plain text content:', error)\n frame.textContent = 'Error loading content'\n })\n }\n\n if (isMarkdown) {\n // For markdown, use a DIV element and render the content\n const frame = myDocument.createElement('div')\n renderMarkdownContent(frame)\n const frameContainer = myDocument.createElement('div')\n frameContainer.classList.add('human-readable-pane__container')\n frameContainer.appendChild(frame)\n div.appendChild(frameContainer)\n } else if (isPlainText) {\n // For plain text, use a PRE element and render the content\n const frame = myDocument.createElement('pre')\n renderPlainTextContent(frame)\n const frameContainer = myDocument.createElement('div')\n frameContainer.classList.add('human-readable-pane__container')\n frameContainer.appendChild(frame)\n div.appendChild(frameContainer)\n } else {\n // For other content types, use IFRAME.\n // The iframe's own request would be anonymous (Solid auth is not cookie based), so the\n // content is fetched with the authenticated fetcher and handed to the frame directly.\n const frame = myDocument.createElement('iframe')\n frame.name = HUMAN_READABLE_PREVIEW_FRAME_NAME\n frame.title = resourceFilename(subject.uri)\n applyFrameClasses(frame, 'iframe')\n const isHtml = ct === 'text/html' || ct === 'application/xhtml+xml'\n let previewUrl: string | null = null\n let disposed = false\n let wasConnected = false\n const mutationObserver = typeof MutationObserver === 'undefined'\n ? null\n : new MutationObserver(records => {\n const wasAdded = records.some(record =>\n Array.from(record.addedNodes).some(node =>\n node === div || (node.nodeType === Node.ELEMENT_NODE && (node as Element).contains(div))\n )\n )\n if (div.isConnected) {\n wasConnected = true\n } else if (wasConnected || wasAdded) {\n disposed = true\n if (previewUrl) {\n URL.revokeObjectURL(previewUrl)\n previewUrl = null\n }\n mutationObserver?.disconnect()\n }\n })\n mutationObserver?.observe(myDocument, { childList: true, subtree: true })\n\n const showError = (message: string) => {\n frame.removeAttribute('src')\n frame.setAttribute('sandbox', '')\n frame.srcdoc = `<p style=\"font-family: sans-serif\">${escapeAttribute(message)}</p>`\n }\n\n if (isHtml) {\n kb.fetcher.webOperation('GET', subject.uri).then(response => {\n const html = response.responseText ?? ''\n frame.title = documentTitle(html, subject.uri)\n const isDokieli = isDokieliHtml(html)\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n if (isDokieli) {\n mountDokieliBridge(frame, subject.uri, html, (url, init) => kb.fetcher._fetch(url, init))\n } else {\n frame.setAttribute('sandbox', HTML_PREVIEW_SANDBOX)\n frame.srcdoc = withBaseHref(html, subject.uri)\n }\n }).catch(error => {\n console.error('Error fetching HTML content:', error)\n showError('Error loading content')\n })\n } else {\n kb.fetcher._fetch(subject.uri).then(async response => {\n if (!response.ok) throw new Error(`HTTP ${response.status}`)\n const responseContentType = response.headers.get('content-type')?.split(';', 1)[0].trim().toLowerCase()\n if (responseContentType === 'text/html' || responseContentType === 'application/xhtml+xml') {\n const html = await response.text()\n frame.title = documentTitle(html, subject.uri)\n const isDokieli = isDokieliHtml(html)\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n if (isDokieli) {\n mountDokieliBridge(frame, subject.uri, html, (url, init) => kb.fetcher._fetch(url, init))\n } else {\n frame.setAttribute('sandbox', HTML_PREVIEW_SANDBOX)\n frame.srcdoc = withBaseHref(html, subject.uri)\n }\n return\n }\n frame.setAttribute('sandbox', HTML_PREVIEW_SANDBOX)\n const objectUrl = URL.createObjectURL(await response.blob())\n if (disposed) {\n URL.revokeObjectURL(objectUrl)\n return\n }\n previewUrl = objectUrl\n frame.src = objectUrl\n }).catch(error => {\n console.error('Error fetching content:', error)\n showError('Error loading content')\n })\n }\n\n const frameContainer = myDocument.createElement('div')\n frameContainer.classList.add('human-readable-pane__container')\n frameContainer.classList.add('human-readable-pane__container--iframe')\n frameContainer.appendChild(frame)\n div.appendChild(frameContainer)\n div.classList.add('human-readable-pane--iframe')\n }\n\n return div\n }\n}\n\nexport default humanReadablePane\n// ends\n"],"mappings":"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"}