@humandialog/forms.svelte 1.2.2 → 1.2.3

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.
@@ -1,4 +1,5 @@
1
1
  <script>import { onMount, onDestroy, getContext } from "svelte";
2
+ import { session } from "@humandialog/auth.svelte";
2
3
  import { Editor } from "@tiptap/core";
3
4
  import StarterKit from "@tiptap/starter-kit";
4
5
  import Document from "@tiptap/extension-document";
@@ -8,6 +9,7 @@ import Heading from "@tiptap/extension-heading";
8
9
  import Blockquote from "@tiptap/extension-blockquote";
9
10
  import HardBreak from "@tiptap/extension-hard-break";
10
11
  import HorizontalRule from "@tiptap/extension-horizontal-rule";
12
+ import Image from "@tiptap/extension-image";
11
13
  import Bold from "@tiptap/extension-bold";
12
14
  import Code from "@tiptap/extension-code";
13
15
  import Italic from "@tiptap/extension-italic";
@@ -19,7 +21,7 @@ import { data_tick_store, contextItemsStore, contextTypesStore } from "../../sto
19
21
  import { informModification, pushChanges } from "../../updates.js";
20
22
  import { isDeviceSmallerThan, parseWidthDirective } from "../../utils.js";
21
23
  import Palette from "./internal/palette.svelte";
22
- import { FaFont, FaRemoveFormat, FaCode, FaComment, FaQuoteRight, FaExclamationTriangle, FaInfo } from "svelte-icons/fa";
24
+ import { FaFont, FaRemoveFormat, FaCode, FaComment, FaQuoteRight, FaExclamationTriangle, FaInfo, FaImage } from "svelte-icons/fa";
23
25
  import IcH1 from "./internal/h1.icon.svelte";
24
26
  import IcH2 from "./internal/h2.icon.svelte";
25
27
  import IcH3 from "./internal/h3.icon.svelte";
@@ -35,6 +37,8 @@ export let typename = "";
35
37
  export let compact = false;
36
38
  export let onFocusCb = void 0;
37
39
  export let onBlurCb = void 0;
40
+ export let onAddImage = void 0;
41
+ export let onRemoveImage = void 0;
38
42
  export let c = "";
39
43
  export let pushChangesImmediately = true;
40
44
  let onFinishEditing = void 0;
@@ -67,7 +71,9 @@ else
67
71
  dark:bg-stone-700 dark:border-stone-600
68
72
  px-2.5`;
69
73
  let last_tick = -1;
70
- $: {
74
+ $:
75
+ updateAfterUIChanges($data_tick_store);
76
+ function updateAfterUIChanges(...args) {
71
77
  if (last_tick < $data_tick_store) {
72
78
  if (hasChangedValue)
73
79
  saveData();
@@ -312,6 +318,77 @@ const QuoteBlock = Paragraph.extend({
312
318
  };
313
319
  }
314
320
  });
321
+ function prepareFullImagePath(url) {
322
+ if (!url.startsWith("/json/")) {
323
+ const apiVer = $session.configuration.api_version ?? "anyv";
324
+ if (url.startsWith("/"))
325
+ url = `/json/${apiVer}${url}`;
326
+ else
327
+ url = `/json/${apiVer}/${url}`;
328
+ }
329
+ let fullPath = "";
330
+ let absolute_pattern = /^https?:\/\//i;
331
+ if (!absolute_pattern.test(url)) {
332
+ fullPath = $session.apiAddress;
333
+ if (fullPath.endsWith("/")) {
334
+ if (url.startsWith("/"))
335
+ fullPath = fullPath + url.substr(1);
336
+ else
337
+ fullPath = fullPath + url;
338
+ } else {
339
+ if (url.startsWith("/"))
340
+ fullPath = fullPath + url;
341
+ else
342
+ fullPath = fullPath + "/" + url;
343
+ }
344
+ } else
345
+ fullPath = url;
346
+ if ($session.tenants.length > 0) {
347
+ const currentGroupInfo = $session.tenants.find((t) => t.id == $session.tid);
348
+ if (currentGroupInfo && currentGroupInfo.headers && currentGroupInfo.headers.length > 0) {
349
+ const paramsNo = currentGroupInfo.headers.length;
350
+ for (let i = 0; i < paramsNo; i++) {
351
+ const param = currentGroupInfo.headers[i];
352
+ if (i == 0) {
353
+ if (fullPath.includes("?")) {
354
+ fullPath += "&";
355
+ } else {
356
+ fullPath += "?";
357
+ }
358
+ }
359
+ fullPath += param.key.toLowerCase();
360
+ fullPath += "=" + param.value;
361
+ }
362
+ }
363
+ }
364
+ return fullPath;
365
+ }
366
+ const CrossImage = Image.extend({
367
+ addAttributes() {
368
+ return {
369
+ crossorigin: {
370
+ default: "use-credentials"
371
+ },
372
+ dataPath: {
373
+ default: null,
374
+ parseHTML: (element) => {
375
+ return element.getAttribute("data-path");
376
+ },
377
+ renderHTML: (attributes) => {
378
+ const dataPath = attributes.dataPath;
379
+ if (dataPath) {
380
+ return {
381
+ "data-path": dataPath,
382
+ src: prepareFullImagePath(dataPath)
383
+ };
384
+ } else {
385
+ return {};
386
+ }
387
+ }
388
+ }
389
+ };
390
+ }
391
+ });
315
392
  onMount(() => {
316
393
  editor = new Editor({
317
394
  editorProps: {
@@ -327,6 +404,12 @@ onMount(() => {
327
404
  Heading.configure({
328
405
  levels: [1, 2]
329
406
  }),
407
+ /*Image.configure({
408
+ HTMLAttributes: {
409
+ crossorigin: 'use-credentials'
410
+ }
411
+ }),*/
412
+ CrossImage,
330
413
  HardBreak,
331
414
  HorizontalRule,
332
415
  // custom
@@ -351,6 +434,7 @@ onMount(() => {
351
434
  onTransaction({ editor: editor2, transaction }) {
352
435
  hasChangedValue = true;
353
436
  changedValue = editor2.getHTML();
437
+ handleImagesDeletions(transaction);
354
438
  },
355
439
  onFocus({ editor: editor2, event }) {
356
440
  if (onFocusCb)
@@ -468,6 +552,36 @@ function show_command_palette() {
468
552
  else
469
553
  palette.show(x, y, show_above);
470
554
  }
555
+ function onAddedImageReady(dataPath) {
556
+ const imgFullPath = prepareFullImagePath(dataPath);
557
+ editor.commands.insertContent({
558
+ type: "image",
559
+ attrs: {
560
+ src: imgFullPath,
561
+ dataPath
562
+ }
563
+ });
564
+ }
565
+ function handleImagesDeletions(transaction) {
566
+ if (!onRemoveImage)
567
+ return;
568
+ const getImageSrcs = (fragment) => {
569
+ let srcs = /* @__PURE__ */ new Set();
570
+ fragment.forEach((node) => {
571
+ if (node.type.name === "image") {
572
+ srcs.add(node.attrs.dataPath);
573
+ }
574
+ });
575
+ return srcs;
576
+ };
577
+ let currentSrcs = getImageSrcs(transaction.doc.content);
578
+ let previousSrcs = getImageSrcs(transaction.before.content);
579
+ if (currentSrcs.size === 0 && previousSrcs.size === 0) {
580
+ return;
581
+ }
582
+ let deletedImageSrcs = [...previousSrcs].filter((src) => !currentSrcs.has(src));
583
+ deletedImageSrcs.forEach((src) => onRemoveImage(src));
584
+ }
471
585
  let commands = [
472
586
  { caption: "Normal", description: "This is normal text style", tags: "text", icon: FaRemoveFormat, on_choice: (range) => {
473
587
  if (range)
@@ -516,6 +630,12 @@ let commands = [
516
630
  editor.chain().focus().deleteRange(range).setAsInfo().run();
517
631
  else
518
632
  editor.commands.setAsInfo();
633
+ } },
634
+ { caption: "Image", description: "Add image to document", icon: FaImage, on_choice: (range) => {
635
+ if (range)
636
+ editor.chain().focus().deleteRange(range).run();
637
+ if (onAddImage)
638
+ onAddImage(onAddedImageReady);
519
639
  } }
520
640
  ];
521
641
  </script>
@@ -11,6 +11,8 @@ declare const __propDef: {
11
11
  compact?: boolean | undefined;
12
12
  onFocusCb?: undefined;
13
13
  onBlurCb?: undefined;
14
+ onAddImage?: undefined;
15
+ onRemoveImage?: undefined;
14
16
  c?: string | undefined;
15
17
  pushChangesImmediately?: boolean | undefined;
16
18
  run?: ((onStop?: undefined) => void) | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humandialog/forms.svelte",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "Basic Svelte UI components for Object Reef applications",
5
5
  "devDependencies": {
6
6
  "@playwright/test": "^1.28.1",
@@ -28,10 +28,12 @@
28
28
  "dependencies": {
29
29
  "@humandialog/auth.svelte": "^1.8.3",
30
30
  "@tiptap/core": "^2.11.0",
31
+ "@tiptap/extension-image": "^2.11.0",
31
32
  "@tiptap/pm": "^2.11.0",
32
33
  "@tiptap/starter-kit": "^2.11.0",
33
34
  "@tiptap/suggestion": "^2.11.0",
34
35
  "flowbite-svelte": "^0.44.4",
36
+ "pdfjs-dist": "^4.10.38",
35
37
  "svelte-icons": "^2.1.0",
36
38
  "svelte-spa-router": "^4.0.1"
37
39
  },
package/utils.js CHANGED
@@ -23,6 +23,11 @@ export function isDeviceSmallerThan(br)
23
23
  export function selectItem(itm)
24
24
  {
25
25
  let data_context = get(contextItemsStore);
26
+
27
+ const prevSel = data_context['sel'];
28
+ if(prevSel === itm)
29
+ return;
30
+
26
31
  data_context['sel'] = itm;
27
32
  data_context.focused = 'sel';
28
33
  contextItemsStore.set( {...data_context} )
@@ -43,6 +48,7 @@ export function activateItem(context_level, itm, operations=null)
43
48
  data_context.focused = context_level;
44
49
  contextItemsStore.set( {...data_context} )
45
50
 
51
+
46
52
  let ticket = get(data_tick_store)
47
53
  ticket++;
48
54
  data_tick_store.set(ticket)
@@ -60,6 +66,7 @@ export function clearActiveItem(context_level)
60
66
  data_context.focused = context_level;
61
67
  contextItemsStore.set( {...data_context} )
62
68
 
69
+
63
70
  let ticket = get(data_tick_store)
64
71
  ticket++;
65
72
  data_tick_store.set(ticket)