@windward/core 0.25.0 → 0.25.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## Hotfix [0.25.1] - 2025-11-07
4
+
5
+ * Merged in feature/LE-2108/revise-text-fix (pull request #453)
6
+ * Merged in feature/LE-2123/open-res-gen-fix (pull request #452)
7
+
8
+
3
9
  ## Release [0.25.0] - 2025-10-29
4
10
 
5
11
  * Merged in bugfix/LE-2067-scorm-provider (pull request #451)
@@ -3,7 +3,8 @@
3
3
  <v-container
4
4
  v-if="
5
5
  block.metadata.config.title ||
6
- block.metadata.config.instructions
6
+ block.metadata.config.instructions ||
7
+ block.metadata.config.starting_text
7
8
  "
8
9
  class="pa-0"
9
10
  >
@@ -24,6 +25,14 @@
24
25
  >
25
26
  {{ block.metadata.config.instructions }}
26
27
  </p>
28
+
29
+ <p
30
+ v-if="block.metadata.config.starting_text"
31
+ tabindex="0"
32
+ class="pt-3"
33
+ >
34
+ {{ block.metadata.config.starting_text }}
35
+ </p>
27
36
  </v-container>
28
37
  <div v-if="stateLoaded">
29
38
  <div v-if="block.body && !submitted">
@@ -173,6 +182,7 @@ export default {
173
182
  }
174
183
  if (_.isEmpty(this.block.metadata.config.starting_text)) {
175
184
  this.block.metadata.config.starting_text = ''
185
+
176
186
  }
177
187
  },
178
188
  mounted() {},
@@ -610,6 +610,26 @@ export default {
610
610
  return
611
611
  }
612
612
 
613
+ const findBlockAncestor = (node) => {
614
+ try {
615
+ if (!node) return null
616
+ const body = editor ? editor.getBody() : null
617
+ let current = node
618
+ const isBlock = (n) => {
619
+ if (!n || n.nodeType !== Node.ELEMENT_NODE) return false
620
+ const name = n.nodeName || ''
621
+ return /^(P|DIV|LI|UL|OL|H1|H2|H3|H4|H5|H6)$/.test(name)
622
+ }
623
+ while (current && current !== body) {
624
+ if (isBlock(current)) return current
625
+ current = current.parentNode
626
+ }
627
+ return null
628
+ } catch (_e) {
629
+ return null
630
+ }
631
+ }
632
+
613
633
  if (useSelection) {
614
634
  const range = selection.getRng()
615
635
  if (
@@ -703,43 +723,83 @@ export default {
703
723
 
704
724
  editor.undoManager.transact(() => {
705
725
  if (useSelection) {
706
- const range = selection.getRng()
707
- const fragment = editor.dom.createFragment(
708
- responseData.html
709
- )
710
-
711
- if (!fragment.hasChildNodes()) {
712
- return
713
- }
714
-
715
- const firstNode = fragment.firstChild
716
- const lastNode = fragment.lastChild
717
-
718
- if (!firstNode || !lastNode) {
719
- return
720
- }
721
-
722
- range.deleteContents()
723
- range.insertNode(fragment)
724
-
725
- const newRange = editor.dom.createRng()
726
+ try {
727
+ const rng = selection.getRng()
728
+ const startBlock = findBlockAncestor(
729
+ rng ? rng.startContainer : null
730
+ )
731
+ const endBlock = findBlockAncestor(
732
+ rng ? rng.endContainer : null
733
+ )
726
734
 
727
- if (firstNode.nodeType === Node.TEXT_NODE) {
728
- newRange.setStart(firstNode, 0)
729
- } else {
730
- newRange.setStartBefore(firstNode)
735
+ // If selection spans multiple block elements, expand to full blocks
736
+ if (
737
+ startBlock &&
738
+ endBlock &&
739
+ startBlock !== endBlock
740
+ ) {
741
+ const expanded = editor.dom.createRng()
742
+ expanded.setStartBefore(startBlock)
743
+ expanded.setEndAfter(endBlock)
744
+ editor.selection.setRng(expanded)
745
+ }
746
+ } catch (_e) {
747
+ // If expansion fails, fall back to current selection
731
748
  }
732
749
 
733
- if (lastNode.nodeType === Node.TEXT_NODE) {
734
- newRange.setEnd(
735
- lastNode,
736
- lastNode.textContent ? lastNode.textContent.length : 0
737
- )
738
- } else {
739
- newRange.setEndAfter(lastNode)
750
+ // Wrap response with temporary markers so we can reselect inserted content
751
+ const startId = `ww-revise-start-${this.seed}-${Date.now()}-${Math.random()
752
+ .toString(36)
753
+ .slice(2)}`
754
+ const endId = `ww-revise-end-${this.seed}-${Date.now()}-${Math.random()
755
+ .toString(36)
756
+ .slice(2)}`
757
+ const wrappedHtml =
758
+ `<span id="${startId}" data-ww-revise="s"></span>` +
759
+ responseData.html +
760
+ `<span id="${endId}" data-ww-revise="e"></span>`
761
+
762
+ editor.selection.setContent(wrappedHtml)
763
+
764
+ // Try to reselect the inserted content and remove markers
765
+ try {
766
+ const doc = editor.getDoc()
767
+ const startEl = doc.getElementById(startId)
768
+ const endEl = doc.getElementById(endId)
769
+ if (startEl && endEl) {
770
+ const selectRange = editor.dom.createRng()
771
+ // Select everything between markers
772
+ if (selectRange.setStartAfter && selectRange.setEndBefore) {
773
+ selectRange.setStartAfter(startEl)
774
+ selectRange.setEndBefore(endEl)
775
+ } else {
776
+ // Fallback to parent/offset if needed
777
+ const startParent = startEl.parentNode
778
+ const endParent = endEl.parentNode
779
+ const childIndex = (node) => {
780
+ let i = 0
781
+ let cur = node
782
+ while (cur && cur.previousSibling) {
783
+ i++
784
+ cur = cur.previousSibling
785
+ }
786
+ return i
787
+ }
788
+ const startIndex = childIndex(startEl) + 1
789
+ const endIndex = childIndex(endEl)
790
+ selectRange.setStart(startParent, startIndex)
791
+ selectRange.setEnd(endParent, endIndex)
792
+ }
793
+ editor.selection.setRng(selectRange)
794
+
795
+ // Remove markers after selection is set
796
+ if (startEl.parentNode) startEl.parentNode.removeChild(startEl)
797
+ if (endEl.parentNode) endEl.parentNode.removeChild(endEl)
798
+
799
+ }
800
+ } catch (_e) {
801
+ // Ignore selection restoration errors
740
802
  }
741
-
742
- editor.selection.setRng(newRange)
743
803
  } else {
744
804
  editor.setContent(responseData.html)
745
805
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windward/core",
3
- "version": "0.25.0",
3
+ "version": "0.25.1",
4
4
  "description": "Windward UI Core Plugins",
5
5
  "main": "plugin.js",
6
6
  "scripts": {