@@ -41,34 +41,61 @@ export const TextAlign = Extension.create({
4141 */
4242 setTextAlign :
4343 ( alignment ) =>
44- ( { commands, state } ) => {
44+ ( { commands, state, tr , dispatch } ) => {
4545 const containsAlignment = this . options . alignments . includes ( alignment ) ;
4646 if ( ! containsAlignment ) return false ;
47- const $from = state ?. selection ?. $from ;
48- let paragraphNode = null ;
49- let paragraphDepth = - 1 ;
50-
51- if ( $from ) {
52- for ( let depth = $from . depth ; depth >= 0 ; depth -- ) {
53- const nodeAtDepth = $from . node ( depth ) ;
54- if ( nodeAtDepth ?. type ?. name === 'paragraph' ) {
55- paragraphNode = nodeAtDepth ;
56- paragraphDepth = depth ;
57- break ;
58- }
59- }
47+
48+ if ( ! state ?. doc || ! state ?. selection || ! tr ) {
49+ const paragraphProperties = getSelectionParagraphProperties ( this . editor , state ) ;
50+ const storedAlignment = mapDisplayAlignmentToStoredJustification (
51+ alignment ,
52+ paragraphProperties ?. rightToLeft ,
53+ ) ;
54+ return commands . updateAttributes ( 'paragraph' , { 'paragraphProperties.justification' : storedAlignment } ) ;
6055 }
6156
62- let paragraphProperties = paragraphNode ?. attrs ?. paragraphProperties ?? { } ;
57+ const visitedPositions = new Set ( ) ;
58+ let touched = false ;
6359
64- if ( this . editor && $from && paragraphNode && paragraphDepth > 0 ) {
65- const paragraphStartPos = $from . before ( paragraphDepth ) ;
66- const paragraphPos = state . doc . resolve ( paragraphStartPos ) ;
67- paragraphProperties = calculateResolvedParagraphProperties ( this . editor , paragraphNode , paragraphPos ) ;
68- }
60+ const updateParagraph = ( node , pos ) => {
61+ if ( node . type . name !== 'paragraph' ) return true ;
62+ if ( visitedPositions . has ( pos ) ) return false ;
63+ visitedPositions . add ( pos ) ;
64+
65+ const paragraphProperties = this . editor
66+ ? calculateResolvedParagraphProperties ( this . editor , node , state . doc . resolve ( pos ) )
67+ : ( node . attrs ?. paragraphProperties ?? { } ) ;
68+ const storedAlignment = mapDisplayAlignmentToStoredJustification (
69+ alignment ,
70+ paragraphProperties ?. rightToLeft ,
71+ ) ;
72+ const existingParagraphProperties = node . attrs ?. paragraphProperties ?? { } ;
73+
74+ if ( existingParagraphProperties . justification === storedAlignment ) return false ;
75+
76+ tr . setNodeMarkup ( pos , undefined , {
77+ ...node . attrs ,
78+ paragraphProperties : {
79+ ...existingParagraphProperties ,
80+ justification : storedAlignment ,
81+ } ,
82+ } ) ;
83+ touched = true ;
84+ return false ;
85+ } ;
6986
70- const storedAlignment = mapDisplayAlignmentToStoredJustification ( alignment , paragraphProperties ?. rightToLeft ) ;
71- return commands . updateAttributes ( 'paragraph' , { 'paragraphProperties.justification' : storedAlignment } ) ;
87+ state . selection . ranges . forEach ( ( range ) => {
88+ if ( range . $from . pos === range . $to . pos ) {
89+ const paragraph = getParagraphAtSelection ( range . $from ) ;
90+ if ( paragraph ) updateParagraph ( paragraph . node , paragraph . pos ) ;
91+ return ;
92+ }
93+
94+ state . doc . nodesBetween ( range . $from . pos , range . $to . pos , updateParagraph ) ;
95+ } ) ;
96+
97+ if ( touched && dispatch ) dispatch ( tr ) ;
98+ return true ;
7299 } ,
73100
74101 /**
@@ -94,3 +121,21 @@ export const TextAlign = Extension.create({
94121 } ;
95122 } ,
96123} ) ;
124+
125+ function getSelectionParagraphProperties ( editor , state ) {
126+ const paragraph = getParagraphAtSelection ( state ?. selection ?. $from ) ;
127+ if ( ! paragraph ) return { } ;
128+ if ( ! editor || ! state ?. doc ) return paragraph . node ?. attrs ?. paragraphProperties ?? { } ;
129+ return calculateResolvedParagraphProperties ( editor , paragraph . node , state . doc . resolve ( paragraph . pos ) ) ;
130+ }
131+
132+ function getParagraphAtSelection ( $pos ) {
133+ if ( ! $pos ) return null ;
134+ for ( let depth = $pos . depth ; depth >= 0 ; depth -- ) {
135+ const node = $pos . node ( depth ) ;
136+ if ( node ?. type ?. name === 'paragraph' ) {
137+ return { node, pos : depth > 0 ? $pos . before ( depth ) : 0 } ;
138+ }
139+ }
140+ return null ;
141+ }
0 commit comments