@@ -54,6 +54,7 @@ function drawSelectionRange(cm, range, output) {
5454 let fragment = document . createDocumentFragment ( )
5555 let padding = paddingH ( cm . display ) , leftSide = padding . left
5656 let rightSide = Math . max ( display . sizerWidth , displayWidth ( cm ) - display . sizer . offsetLeft ) - padding . right
57+ let docLTR = doc . direction == "ltr"
5758
5859 function add ( left , top , width , bottom ) {
5960 if ( top < 0 ) top = 0
@@ -72,42 +73,43 @@ function drawSelectionRange(cm, range, output) {
7273 return charCoords ( cm , Pos ( line , ch ) , "div" , lineObj , bias )
7374 }
7475
76+ function wrapX ( pos , dir , side ) {
77+ let extent = wrappedLineExtentChar ( cm , lineObj , null , pos )
78+ let prop = ( dir == "ltr" ) == ( side == "after" ) ? "left" : "right"
79+ let ch = side == "after" ? extent . begin : extent . end - ( / \s / . test ( lineObj . text . charAt ( extent . end - 1 ) ) ? 2 : 1 )
80+ return coords ( ch , prop ) [ prop ]
81+ }
82+
7583 let order = getOrder ( lineObj , doc . direction )
7684 iterateBidiSections ( order , fromArg || 0 , toArg == null ? lineLen : toArg , ( from , to , dir , i ) => {
77- let fromPos = coords ( from , dir == "ltr" ? "left" : "right" )
78- let toPos = coords ( to - 1 , dir == "ltr" ? "right" : "left" )
79- if ( dir == "ltr" ) {
80- let fromLeft = fromArg == null && from == 0 ? leftSide : fromPos . left
81- let toRight = toArg == null && to == lineLen ? rightSide : toPos . right
82- if ( toPos . top - fromPos . top <= 3 ) { // Single line
83- add ( fromLeft , toPos . top , toRight - fromLeft , toPos . bottom )
84- } else { // Multiple lines
85- add ( fromLeft , fromPos . top , null , fromPos . bottom )
86- if ( fromPos . bottom < toPos . top ) add ( leftSide , fromPos . bottom , null , toPos . top )
87- add ( leftSide , toPos . top , toPos . right , toPos . bottom )
88- }
89- } else if ( from < to ) { // RTL
90- let fromRight = fromArg == null && from == 0 ? rightSide : fromPos . right
91- let toLeft = toArg == null && to == lineLen ? leftSide : toPos . left
92- if ( toPos . top - fromPos . top <= 3 ) { // Single line
93- add ( toLeft , toPos . top , fromRight - toLeft , toPos . bottom )
94- } else { // Multiple lines
95- let topLeft = leftSide
96- if ( i ) {
97- let topEnd = wrappedLineExtentChar ( cm , lineObj , null , from ) . end
98- // The coordinates returned for an RTL wrapped space tend to
99- // be complete bogus, so try to skip that here.
100- topLeft = coords ( topEnd - ( / \s / . test ( lineObj . text . charAt ( topEnd - 1 ) ) ? 2 : 1 ) , "left" ) . left
101- }
102- add ( topLeft , fromPos . top , fromRight - topLeft , fromPos . bottom )
103- if ( fromPos . bottom < toPos . top ) add ( leftSide , fromPos . bottom , null , toPos . top )
104- let botWidth = null
105- if ( i < order . length - 1 || true ) {
106- let botStart = wrappedLineExtentChar ( cm , lineObj , null , to ) . begin
107- botWidth = coords ( botStart , "right" ) . right - toLeft
108- }
109- add ( toLeft , toPos . top , botWidth , toPos . bottom )
85+ let ltr = dir == "ltr"
86+ let fromPos = coords ( from , ltr ? "left" : "right" )
87+ let toPos = coords ( to - 1 , ltr ? "right" : "left" )
88+
89+ let openStart = fromArg == null && from == 0 , openEnd = toArg == null && to == lineLen
90+ let first = i == 0 , last = ! order || i == order . length - 1
91+ if ( toPos . top - fromPos . top <= 3 ) { // Single line
92+ let openLeft = ( docLTR ? openStart : openEnd ) && first
93+ let openRight = ( docLTR ? openEnd : openStart ) && last
94+ let left = openLeft ? leftSide : ( ltr ? fromPos : toPos ) . left
95+ let right = openRight ? rightSide : ( ltr ? toPos : fromPos ) . right
96+ add ( left , fromPos . top , right - left , fromPos . bottom )
97+ } else { // Multiple lines
98+ let topLeft , topRight , botLeft , botRight
99+ if ( ltr ) {
100+ topLeft = docLTR && openStart && first ? leftSide : fromPos . left
101+ topRight = docLTR ? rightSide : wrapX ( from , dir , "before" )
102+ botLeft = docLTR ? leftSide : wrapX ( to , dir , "after" )
103+ botRight = docLTR && openEnd && last ? rightSide : toPos . right
104+ } else {
105+ topLeft = ! docLTR ? leftSide : wrapX ( from , dir , "before" )
106+ topRight = ! docLTR && openStart && first ? rightSide : fromPos . right
107+ botLeft = ! docLTR && openEnd && last ? leftSide : toPos . left
108+ botRight = ! docLTR ? rightSide : wrapX ( to , dir , "after" )
110109 }
110+ add ( topLeft , fromPos . top , topRight - topLeft , fromPos . bottom )
111+ if ( fromPos . bottom < toPos . top ) add ( leftSide , fromPos . bottom , null , toPos . top )
112+ add ( botLeft , toPos . top , botRight - botLeft , toPos . bottom )
111113 }
112114
113115 if ( ! start || cmpCoords ( fromPos , start ) < 0 ) start = fromPos
0 commit comments