59 | | element.removeStyle( 'direction' ); |
60 | | element.removeAttribute( 'dir' ); |
| 65 | return selectedElement.type == CKEDITOR.NODE_ELEMENT |
| 66 | && ( selectedElement.getName() in elements ) |
| 67 | && selectedElement; |
| 68 | } |
| 69 | |
| 70 | function bidiCommand( dir, editor ) |
| 71 | { |
| 72 | function switchDir( element, dir, database ) |
| 73 | { |
| 74 | // Check first whether one of the ancestors |
| 75 | // has already been styled. |
| 76 | var parent = element; |
| 77 | while ( ( parent = parent.getParent() ) && !parent.is( 'body' ) ) |
| 78 | { |
| 79 | if ( parent.getCustomData( 'bidi_processed' ) ) |
| 80 | { |
| 81 | // Ancestor style must dominate. |
| 82 | element.removeStyle( 'direction' ); |
| 83 | element.removeAttribute( 'dir' ); |
| 84 | return; |
| 85 | } |
| 86 | } |
62 | | if ( state == CKEDITOR.TRISTATE_OFF && element.getComputedStyle( 'direction' ).toLowerCase() != dir ) |
| 88 | var useComputedState = ( 'useComputedState' in editor.config ) ? editor.config.useComputedState : 1; |
| 89 | |
| 90 | var elementDir = useComputedState ? element.getComputedStyle( 'direction' ) |
| 91 | : element.getStyle( 'direction' ) || element.hasAttribute( 'dir' ); |
| 92 | |
| 93 | // Stop if direction is same as present. |
| 94 | if ( elementDir == dir ) |
| 95 | return; |
| 96 | |
| 97 | // Reuse computedState if we already have it. |
| 98 | var dirBefore = useComputedState ? elementDir : element.getComputedStyle( 'direction' ); |
| 99 | |
| 100 | // Clear direction on this element. |
| 101 | element.removeStyle( 'direction' ); |
| 102 | |
| 103 | // Set new direction for this element. |
65 | | // If the element direction changed, we need to switch the margins of |
66 | | // the element and all its children, so it will get really reflected |
67 | | // like a mirror. (#5910) |
68 | | var dirAfter = element.getComputedStyle( 'direction' ); |
69 | | if ( dirAfter != dirBefore ) |
70 | | { |
71 | | var range = new CKEDITOR.dom.range( element.getDocument() ); |
72 | | range.setStartBefore( element ); |
73 | | range.setEndAfter( element ); |
| 106 | // If the element direction changed, we need to switch the margins of |
| 107 | // the element and all its children, so it will get really reflected |
| 108 | // like a mirror. (#5910) |
| 109 | if ( dir != dirBefore ) |
| 110 | { |
| 111 | var range = new CKEDITOR.dom.range( element.getDocument() ); |
| 112 | range.setStartBefore( element ); |
| 113 | range.setEndAfter( element ); |
77 | | var node; |
78 | | while ( ( node = walker.next() ) ) |
79 | | { |
80 | | if ( node.type == CKEDITOR.NODE_ELEMENT ) |
81 | | { |
82 | | // A child with dir defined is to be ignored. |
83 | | if ( !node.equals( element ) && node.hasAttribute( 'dir' ) ) |
84 | | { |
85 | | range.setStartAfter( node ); |
86 | | walker = new CKEDITOR.dom.walker( range ); |
87 | | continue; |
88 | | } |
| 117 | var node; |
| 118 | while ( ( node = walker.next() ) ) |
| 119 | { |
| 120 | if ( node.type == CKEDITOR.NODE_ELEMENT ) |
| 121 | { |
| 122 | // A child with dir defined is to be ignored. |
| 123 | if ( !node.equals( element ) && node.hasAttribute( 'dir' ) ) |
| 124 | { |
| 125 | range.setStartAfter( node ); |
| 126 | walker = new CKEDITOR.dom.walker( range ); |
| 127 | continue; |
| 128 | } |
103 | | function getFullySelected( selection, elements ) |
104 | | { |
105 | | var selectedElement = selection.getCommonAncestor(); |
106 | | while( selectedElement.type == CKEDITOR.NODE_ELEMENT |
107 | | && !( selectedElement.getName() in elements ) |
108 | | && selectedElement.getParent().getChildCount() == 1 |
109 | | ) |
110 | | selectedElement = selectedElement.getParent(); |
| 142 | CKEDITOR.dom.element.setMarker( database, element, 'bidi_processed', 1 ); |
136 | | if ( selectedElement ) |
137 | | { |
138 | | if ( !selectedElement.isReadOnly() ) |
139 | | switchDir( selectedElement, dir, editor, this.state ); |
140 | | } |
141 | | else |
142 | | { |
143 | | // Creates bookmarks for selection, as we may split some blocks. |
144 | | var bookmarks = selection.createBookmarks(); |
| 165 | if ( selectedElement && !selectedElement.isReadOnly() ) |
| 166 | switchDir( selectedElement, dir, database ); |
| 167 | |
| 168 | // Creates bookmarks for selection, as we may split some blocks. |
| 169 | var bookmarks = selection.createBookmarks(); |
149 | | for ( var i = ranges.length - 1 ; i >= 0 ; i-- ) |
150 | | { |
151 | | // Array of elements processed as guardElements. |
152 | | var processedElements = []; |
153 | | // Walker searching for guardElements. |
154 | | var walker = new CKEDITOR.dom.walker( ranges[ i ] ); |
155 | | walker.evaluator = function( node ){ |
156 | | return node.type == CKEDITOR.NODE_ELEMENT |
157 | | && node.getName() in guardElements |
158 | | && !( node.getName() == ( enterMode == CKEDITOR.ENTER_P ) ? 'p' : 'div' |
159 | | && node.getParent().type == CKEDITOR.NODE_ELEMENT |
160 | | && node.getParent().getName() == 'blockquote' |
161 | | ); |
162 | | }; |
| 174 | for ( var i = ranges.length - 1 ; i >= 0 ; i-- ) |
| 175 | { |
| 176 | // Array of elements processed as guardElements. |
| 177 | var processedElements = []; |
| 178 | // Walker searching for guardElements. |
| 179 | var walker = new CKEDITOR.dom.walker( ranges[ i ] ); |
| 180 | walker.evaluator = function( node ){ |
| 181 | return node.type == CKEDITOR.NODE_ELEMENT |
| 182 | && node.getName() in guardElements |
| 183 | && !( node.getName() == ( enterMode == CKEDITOR.ENTER_P ) ? 'p' : 'div' |
| 184 | && node.getParent().type == CKEDITOR.NODE_ELEMENT |
| 185 | && node.getParent().getName() == 'blockquote' |
| 186 | ); |
| 187 | }; |
173 | | while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) |
174 | | { |
175 | | if ( block.isReadOnly() ) |
176 | | continue; |
177 | | |
178 | | var _break = 0; |
179 | | |
180 | | // Check if block have been already processed by the walker above. |
181 | | for ( var ii = 0; ii < processedElements.length; ii++ ) |
182 | | { |
183 | | var parent = block.getParent(); |
184 | | |
185 | | while( parent && parent.getName() != 'body' ) |
186 | | { |
187 | | if ( ( parent.$.isSameNode && parent.$.isSameNode( processedElements[ ii ].$ ) ) |
188 | | || parent.$ == processedElements[ ii ].$ ) |
189 | | { |
190 | | _break = 1; |
191 | | break; |
192 | | } |
193 | | parent = parent.getParent(); |
194 | | } |
| 195 | while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) |
| 196 | !block.isReadOnly() && switchDir( block, dir, database ); |
| 197 | } |
238 | | addButtonCommand( 'BidiLtr', lang.ltr, 'bidiltr', bidiCommand( 'ltr' ) ); |
239 | | addButtonCommand( 'BidiRtl', lang.rtl, 'bidirtl', bidiCommand( 'rtl' ) ); |
| 231 | addButtonCommand( 'BidiLtr', lang.ltr, 'bidiltr', bidiCommand( 'ltr', editor ) ); |
| 232 | addButtonCommand( 'BidiRtl', lang.rtl, 'bidirtl', bidiCommand( 'rtl', editor ) ); |