pinokiod 3.183.0 → 3.184.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.183.0",
3
+ "version": "3.184.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -893,6 +893,93 @@ document.addEventListener("DOMContentLoaded", async () => {
893
893
  }
894
894
  }
895
895
  }
896
+ async collectFilesFromDataTransfer(dataTransfer) {
897
+ if (!dataTransfer) {
898
+ return []
899
+ }
900
+ const items = dataTransfer.items ? Array.from(dataTransfer.items) : []
901
+ const stringItems = items.filter((item) => item && item.kind === "string" && typeof item.getAsString === "function")
902
+ const collectedStrings = []
903
+ if (stringItems.length > 0) {
904
+ const stringValues = await Promise.all(stringItems.map((item) => new Promise((resolve) => {
905
+ try {
906
+ item.getAsString((value) => resolve({ type: item.type || "text/plain", value }))
907
+ } catch (_) {
908
+ resolve({ type: item.type || "text/plain", value: "" })
909
+ }
910
+ })))
911
+ for (const entry of stringValues) {
912
+ if (entry && typeof entry.value === "string" && entry.value.trim()) {
913
+ collectedStrings.push(entry)
914
+ }
915
+ }
916
+ } else if (typeof dataTransfer.getData === "function") {
917
+ const uriList = dataTransfer.getData("text/uri-list")
918
+ if (uriList && uriList.trim()) {
919
+ collectedStrings.push({ type: "text/uri-list", value: uriList })
920
+ }
921
+ const plain = dataTransfer.getData("text/plain")
922
+ if (plain && plain.trim()) {
923
+ collectedStrings.push({ type: "text/plain", value: plain })
924
+ }
925
+ }
926
+ if (!collectedStrings.length) {
927
+ return []
928
+ }
929
+ const origin = window.location.origin
930
+ const urls = new Set()
931
+ for (const { type, value } of collectedStrings) {
932
+ if (!value) {
933
+ continue
934
+ }
935
+ const trimmed = value.trim()
936
+ if (!trimmed) {
937
+ continue
938
+ }
939
+ const candidates = (type === "text/uri-list" ? trimmed.split(/\r?\n/) : [trimmed]).filter((line) => line && !line.startsWith("#"))
940
+ for (const candidate of candidates) {
941
+ let resolved
942
+ try {
943
+ resolved = new URL(candidate, origin)
944
+ } catch (_) {
945
+ continue
946
+ }
947
+ if (resolved.origin !== origin) {
948
+ continue
949
+ }
950
+ urls.add(resolved.href)
951
+ }
952
+ }
953
+ if (!urls.size) {
954
+ return []
955
+ }
956
+ const FileCtor = typeof window !== "undefined" ? window.File : null
957
+ if (typeof FileCtor !== "function") {
958
+ return []
959
+ }
960
+ const files = []
961
+ for (const href of urls) {
962
+ try {
963
+ const response = await fetch(href, { credentials: "include" })
964
+ if (!response || !response.ok) {
965
+ continue
966
+ }
967
+ const blob = await response.blob()
968
+ const nameSegment = href.split("/").pop() || "download"
969
+ let filename = nameSegment || "download"
970
+ try {
971
+ filename = decodeURIComponent(filename)
972
+ } catch (_) {}
973
+ if (!filename) {
974
+ filename = "download"
975
+ }
976
+ files.push(new FileCtor([blob], filename, { type: blob.type || "application/octet-stream", lastModified: Date.now() }))
977
+ } catch (error) {
978
+ console.warn("Failed to resolve dropped resource", href, error)
979
+ }
980
+ }
981
+ return files
982
+ }
896
983
  async createTerm (_theme) {
897
984
  console.log(xtermTheme)
898
985
  if (!this.term) {
@@ -964,11 +1051,26 @@ document.addEventListener("DOMContentLoaded", async () => {
964
1051
  prevent(event)
965
1052
  dragDepth = 0
966
1053
  dropOverlay.classList.remove("active")
967
- const dropped = Array.from(event.dataTransfer ? event.dataTransfer.files || [] : [])
968
- if (!dropped.length) {
1054
+ const files = Array.from(event.dataTransfer ? event.dataTransfer.files || [] : [])
1055
+ try {
1056
+ const extra = await this.collectFilesFromDataTransfer(event.dataTransfer)
1057
+ if (Array.isArray(extra) && extra.length) {
1058
+ const seen = new Set(files.map((file) => `${file.name}-${file.size}`))
1059
+ for (const file of extra) {
1060
+ const key = `${file.name}-${file.size}`
1061
+ if (!seen.has(key)) {
1062
+ seen.add(key)
1063
+ files.push(file)
1064
+ }
1065
+ }
1066
+ }
1067
+ } catch (error) {
1068
+ console.warn("Failed to collect files from drop payload", error)
1069
+ }
1070
+ if (!files.length) {
969
1071
  return
970
1072
  }
971
- await this.uploadFiles(dropped, dropOverlay)
1073
+ await this.uploadFiles(files, dropOverlay)
972
1074
  this.term.focus()
973
1075
  })
974
1076
  term.attachCustomKeyEventHandler(event => {
@@ -980,6 +980,93 @@ document.addEventListener("DOMContentLoaded", async () => {
980
980
  }
981
981
  }
982
982
  }
983
+ async collectFilesFromDataTransfer(dataTransfer) {
984
+ if (!dataTransfer) {
985
+ return []
986
+ }
987
+ const items = dataTransfer.items ? Array.from(dataTransfer.items) : []
988
+ const stringItems = items.filter((item) => item && item.kind === "string" && typeof item.getAsString === "function")
989
+ const collectedStrings = []
990
+ if (stringItems.length > 0) {
991
+ const stringValues = await Promise.all(stringItems.map((item) => new Promise((resolve) => {
992
+ try {
993
+ item.getAsString((value) => resolve({ type: item.type || "text/plain", value }))
994
+ } catch (_) {
995
+ resolve({ type: item.type || "text/plain", value: "" })
996
+ }
997
+ })))
998
+ for (const entry of stringValues) {
999
+ if (entry && typeof entry.value === "string" && entry.value.trim()) {
1000
+ collectedStrings.push(entry)
1001
+ }
1002
+ }
1003
+ } else if (typeof dataTransfer.getData === "function") {
1004
+ const uriList = dataTransfer.getData("text/uri-list")
1005
+ if (uriList && uriList.trim()) {
1006
+ collectedStrings.push({ type: "text/uri-list", value: uriList })
1007
+ }
1008
+ const plain = dataTransfer.getData("text/plain")
1009
+ if (plain && plain.trim()) {
1010
+ collectedStrings.push({ type: "text/plain", value: plain })
1011
+ }
1012
+ }
1013
+ if (!collectedStrings.length) {
1014
+ return []
1015
+ }
1016
+ const origin = window.location.origin
1017
+ const urls = new Set()
1018
+ for (const { type, value } of collectedStrings) {
1019
+ if (!value) {
1020
+ continue
1021
+ }
1022
+ const trimmed = value.trim()
1023
+ if (!trimmed) {
1024
+ continue
1025
+ }
1026
+ const candidates = (type === "text/uri-list" ? trimmed.split(/\r?\n/) : [trimmed]).filter((line) => line && !line.startsWith("#"))
1027
+ for (const candidate of candidates) {
1028
+ let resolved
1029
+ try {
1030
+ resolved = new URL(candidate, origin)
1031
+ } catch (_) {
1032
+ continue
1033
+ }
1034
+ if (resolved.origin !== origin) {
1035
+ continue
1036
+ }
1037
+ urls.add(resolved.href)
1038
+ }
1039
+ }
1040
+ if (!urls.size) {
1041
+ return []
1042
+ }
1043
+ const FileCtor = typeof window !== "undefined" ? window.File : null
1044
+ if (typeof FileCtor !== "function") {
1045
+ return []
1046
+ }
1047
+ const files = []
1048
+ for (const href of urls) {
1049
+ try {
1050
+ const response = await fetch(href, { credentials: "include" })
1051
+ if (!response || !response.ok) {
1052
+ continue
1053
+ }
1054
+ const blob = await response.blob()
1055
+ const nameSegment = href.split("/").pop() || "download"
1056
+ let filename = nameSegment || "download"
1057
+ try {
1058
+ filename = decodeURIComponent(filename)
1059
+ } catch (_) {}
1060
+ if (!filename) {
1061
+ filename = "download"
1062
+ }
1063
+ files.push(new FileCtor([blob], filename, { type: blob.type || "application/octet-stream", lastModified: Date.now() }))
1064
+ } catch (error) {
1065
+ console.warn("Failed to resolve dropped resource", href, error)
1066
+ }
1067
+ }
1068
+ return files
1069
+ }
983
1070
  async createTerm (_theme) {
984
1071
  if (!this.term) {
985
1072
  const theme = Object.assign({ }, _theme, {
@@ -1048,11 +1135,26 @@ document.addEventListener("DOMContentLoaded", async () => {
1048
1135
  prevent(event)
1049
1136
  dragDepth = 0
1050
1137
  dropOverlay.classList.remove("active")
1051
- const dropped = Array.from(event.dataTransfer ? event.dataTransfer.files || [] : [])
1052
- if (!dropped.length) {
1138
+ const files = Array.from(event.dataTransfer ? event.dataTransfer.files || [] : [])
1139
+ try {
1140
+ const extra = await this.collectFilesFromDataTransfer(event.dataTransfer)
1141
+ if (Array.isArray(extra) && extra.length) {
1142
+ const seen = new Set(files.map((file) => `${file.name}-${file.size}`))
1143
+ for (const file of extra) {
1144
+ const key = `${file.name}-${file.size}`
1145
+ if (!seen.has(key)) {
1146
+ seen.add(key)
1147
+ files.push(file)
1148
+ }
1149
+ }
1150
+ }
1151
+ } catch (error) {
1152
+ console.warn("Failed to collect files from drop payload", error)
1153
+ }
1154
+ if (!files.length) {
1053
1155
  return
1054
1156
  }
1055
- await this.uploadFiles(dropped, dropOverlay)
1157
+ await this.uploadFiles(files, dropOverlay)
1056
1158
  this.term.focus()
1057
1159
  })
1058
1160
  term.attachCustomKeyEventHandler(event => {