mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-24 22:35:41 +00:00
Add a getDirectionFromRange Method to ve.ce.Document
getDirectionFromRange returns the direction property of the ce nodes under that range. That method is mostly useful to recognize the overall block direction of a selection or fragment. The method is currently used in the following locations: * ve.ui.Toolbar onContextChange - as a means to recognize the current context's block direction for the icon directionality. * ve.ui.MWExtensionInspector - if the selection is text and not an existing node the input directionality adjusts to the context direction. Bug: 57421 Change-Id: Ifc01b8e5dc0a2fe39d221e59e452c5cfad709a2d
This commit is contained in:
parent
da14b51b7e
commit
95d99192b4
|
@ -59,6 +59,9 @@ ve.ui.MWExtensionInspector.prototype.initialize = function () {
|
|||
* @inheritdoc
|
||||
*/
|
||||
ve.ui.MWExtensionInspector.prototype.setup = function ( data ) {
|
||||
var dir,
|
||||
fragment = this.surface.getModel().getFragment( null, true );
|
||||
|
||||
// Parent method
|
||||
ve.ui.Inspector.prototype.setup.call( this, data );
|
||||
|
||||
|
@ -66,12 +69,16 @@ ve.ui.MWExtensionInspector.prototype.setup = function ( data ) {
|
|||
this.node = this.surface.getView().getFocusedNode();
|
||||
this.input.setValue( this.node ? this.node.getModel().getAttribute( 'mw' ).body.extsrc : '' );
|
||||
|
||||
// By default, the direction of the input element should be the same
|
||||
// as the direction of the content it applies to
|
||||
if ( this.node ) {
|
||||
// Direction of the input textarea should correspond to the
|
||||
// direction of the surrounding content of the node itself
|
||||
// rather than the GUI direction:
|
||||
this.input.setRTL( this.node.$element.css( 'direction' ) === 'rtl' );
|
||||
// The node is being edited
|
||||
dir = this.node.$element.css( 'direction' );
|
||||
} else {
|
||||
// New insertion, base direction on the fragment range
|
||||
dir = this.surface.getView().documentView.getDirectionFromRange( fragment.getRange() );
|
||||
}
|
||||
this.input.setRTL( dir === 'rtl' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -268,3 +268,34 @@ ve.ce.Document.prototype.getRelativeRange = function ( range, direction, unit, e
|
|||
return new ve.Range( contentOrSlugOffset );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the directionality of some range.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.Range} range Selection range
|
||||
* @returns {String} 'rtl' or 'ltr' as response
|
||||
*/
|
||||
ve.ce.Document.prototype.getDirectionFromRange = function ( range ) {
|
||||
var effectiveNode,
|
||||
selectedNodes = this.selectNodes( range, 'covered' );
|
||||
|
||||
if ( selectedNodes.length > 1 ) {
|
||||
// Selection of multiple nodes
|
||||
// Get the common parent node
|
||||
effectiveNode = this.selectNodes( range, 'siblings' )[0].node.getParent();
|
||||
} else {
|
||||
// selection of a single node
|
||||
effectiveNode = selectedNodes[0].node;
|
||||
|
||||
while ( effectiveNode.isContent() ) {
|
||||
// This means that we're in a leaf node, like TextNode
|
||||
// those don't read the directionality properly, we will
|
||||
// have to climb up the parentage chain until we find a
|
||||
// wrapping node like paragraph or list item, etc.
|
||||
effectiveNode = effectiveNode.parent;
|
||||
}
|
||||
}
|
||||
|
||||
return effectiveNode.$element.css( 'direction' );
|
||||
};
|
||||
|
|
|
@ -156,14 +156,7 @@ ve.ui.Toolbar.prototype.onSurfaceViewKeyUp = function () {
|
|||
*/
|
||||
ve.ui.Toolbar.prototype.onContextChange = function () {
|
||||
var i, len, leafNodes, dirInline, dirBlock, fragmentAnnotation,
|
||||
currentNodes = {
|
||||
fragNodes: null,
|
||||
fragAnnotations: null,
|
||||
'dm': {},
|
||||
'ce': {}
|
||||
},
|
||||
fragment = this.surface.getModel().getFragment( null, false ),
|
||||
doc = this.surface.getView().getDocument(),
|
||||
nodes = [];
|
||||
|
||||
leafNodes = fragment.getLeafNodes();
|
||||
|
@ -172,27 +165,17 @@ ve.ui.Toolbar.prototype.onContextChange = function () {
|
|||
nodes.push( leafNodes[i].node );
|
||||
}
|
||||
}
|
||||
// Update context direction for button icons UI:
|
||||
// Update context direction for button icons UI
|
||||
|
||||
// block direction (direction of the current node)
|
||||
currentNodes.fragNodes = fragment.getCoveredNodes();
|
||||
if ( currentNodes.fragNodes.length > 1 ) {
|
||||
// selection of multiple nodes
|
||||
currentNodes.dm.block = fragment.getSiblingNodes()[0].node.parent;
|
||||
} else {
|
||||
// selection of a single node
|
||||
currentNodes.dm.block = currentNodes.fragNodes[0].node;
|
||||
}
|
||||
// get the direction of the block:
|
||||
currentNodes.ce.block = doc.getNodeFromOffset( currentNodes.dm.block.getRange().start );
|
||||
dirBlock = currentNodes.ce.block.$element.css( 'direction' );
|
||||
// by default, inline and block are the same, unless there's an inline-specific direction
|
||||
dirInline = dirBlock;
|
||||
// 'inline' direction is set by language annotation:
|
||||
// by default, inline and block directions are the same
|
||||
dirInline = dirBlock = this.surface.getView().documentView.getDirectionFromRange( fragment.getRange() );
|
||||
|
||||
// 'inline' direction is different only if we are inside a language annotation
|
||||
fragmentAnnotation = fragment.getAnnotations();
|
||||
if ( fragmentAnnotation.hasAnnotationWithName( 'meta/language' ) ) {
|
||||
dirInline = fragmentAnnotation.getAnnotationsByName( 'meta/language' ).get( 0 ).getAttribute( 'dir' );
|
||||
}
|
||||
|
||||
if ( dirInline !== this.contextDirection.inline ) {
|
||||
// remove previous class:
|
||||
this.$element.removeClass( 've-ui-dir-inline-rtl ve-ui-dir-inline-ltr' );
|
||||
|
|
Loading…
Reference in a new issue