Skip to content

Commit 444d0c2

Browse files
committed
Skip leading/trailing whitespace when adding a mark in toggleMark
FIX: `toggleMark` will now skip whitespace at the start and end of the selection when adding a mark. See https://discuss.prosemirror.net/t/doubleclick-selection-of-word-and-applying-marks-in-ms-windows/3404
1 parent 6e5785d commit 444d0c2

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

src/commands.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,15 @@ export function toggleMark(markType, attrs) {
503503
}
504504
for (let i = 0; i < ranges.length; i++) {
505505
let {$from, $to} = ranges[i]
506-
if (has) tr.removeMark($from.pos, $to.pos, markType)
507-
else tr.addMark($from.pos, $to.pos, markType.create(attrs))
506+
if (has) {
507+
tr.removeMark($from.pos, $to.pos, markType)
508+
} else {
509+
let from = $from.pos, to = $to.pos, start = $from.nodeAfter, end = $to.nodeBefore
510+
let spaceStart = start && start.isText ? /^\s*/.exec(start.text)[0].length : 0
511+
let spaceEnd = end && end.isText ? /\s*$/.exec(end.text)[0].length : 0
512+
if (from + spaceStart < to) { from += spaceStart; to -= spaceEnd }
513+
tr.addMark(from, to, markType.create(attrs))
514+
}
508515
}
509516
dispatch(tr.scrollIntoView())
510517
}

test/test-commands.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,3 +463,42 @@ describe("autoJoin", () => {
463463
autoJoin(lift, ["bullet_list"]),
464464
doc(ul(li(p("a")), li(p("b")), li(p("c"))))))
465465
})
466+
467+
describe("toggleMark", () => {
468+
let toggleEm = toggleMark(schema.marks.em), toggleStrong = toggleMark(schema.marks.strong)
469+
470+
it("can add a mark", () => {
471+
apply(doc(p("one <a>two<b>")), toggleEm,
472+
doc(p("one ", em("two"))))
473+
})
474+
475+
it("can stack marks", () => {
476+
apply(doc(p("one <a>tw", strong("o<b>"))), toggleEm,
477+
doc(p("one ", em("tw", strong("o")))))
478+
})
479+
480+
it("can remove marks", () => {
481+
apply(doc(p(em("one <a>two<b>"))), toggleEm,
482+
doc(p(em("one "), "two")))
483+
})
484+
485+
it("can toggle pending marks", () => {
486+
let state = mkState(doc(p("hell<a>o")))
487+
toggleEm(state, tr => state = state.apply(tr))
488+
ist(state.storedMarks.length, 1)
489+
toggleStrong(state, tr => state = state.apply(tr))
490+
ist(state.storedMarks.length, 2)
491+
toggleEm(state, tr => state = state.apply(tr))
492+
ist(state.storedMarks.length, 1)
493+
})
494+
495+
it("skips whitespace at selection ends when adding marks", () => {
496+
apply(doc(p("one<a> two <b>three")), toggleEm,
497+
doc(p("one ", em("two"), " three")))
498+
})
499+
500+
it("doesn't skip whitespace-only selections", () => {
501+
apply(doc(p("one<a> <b>two")), toggleEm,
502+
doc(p("one", em(" "), "two")))
503+
})
504+
})

0 commit comments

Comments
 (0)