mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 18:39:52 +00:00
Merge branch 'dmrewrite' of ssh://review/mediawiki/extensions/VisualEditor into dmrewrite
This commit is contained in:
commit
5b52e5320a
|
@ -207,19 +207,35 @@ ve.dm.Document.isContentOffset = function( data, offset ) {
|
|||
/**
|
||||
* Checks if structure can be inserted at an offset in document data.
|
||||
*
|
||||
* If the {unrestricted} param is true than only offsets where any kind of element can be inserted
|
||||
* will return true. This can be used to detect the difference between a location that a paragraph
|
||||
* can be inserted, such as between two tables but not direclty inside a table.
|
||||
*
|
||||
* This method assumes that any value that has a type property that's a string is an element object.
|
||||
*
|
||||
* @example Structural offsets:
|
||||
* @example Structural offsets (unrestricted = false):
|
||||
* <heading> a </heading> <paragraph> b c <img> </img> </paragraph>
|
||||
* ^ . . ^ . . . . . ^
|
||||
*
|
||||
* @example Structural offsets (unrestricted = true):
|
||||
* <heading> a </heading> <paragraph> b c <img> </img> </paragraph>
|
||||
* ^ . . ^ . . . . . ^
|
||||
*
|
||||
* @example Structural offsets (unrestricted = false):
|
||||
* <list> <listItem> </listItem> <list>
|
||||
* ^ ^ ^ ^ ^
|
||||
*
|
||||
* @example Content branch offsets (unrestricted = true):
|
||||
* <list> <listItem> </listItem> <list>
|
||||
* ^ . ^ . ^
|
||||
*
|
||||
* @static
|
||||
* @method
|
||||
* @param {Array} data Document data
|
||||
* @param {Integer} offset Document offset
|
||||
* @returns {Boolean} Structure can be inserted at offset
|
||||
*/
|
||||
ve.dm.Document.isStructuralOffset = function( data, offset ) {
|
||||
ve.dm.Document.isStructuralOffset = function( data, offset, unrestricted ) {
|
||||
// Edges are always structural
|
||||
if ( offset === 0 || offset === data.length ) {
|
||||
return true;
|
||||
|
@ -242,15 +258,31 @@ ve.dm.Document.isStructuralOffset = function( data, offset ) {
|
|||
// Is a closing
|
||||
left.type.charAt( 0 ) === '/' &&
|
||||
// Is a branch
|
||||
factory.canNodeHaveChildren( left.type.substr( 1 ) )
|
||||
factory.canNodeHaveChildren( left.type.substr( 1 ) ) &&
|
||||
(
|
||||
// Only apply this rule in unrestricted mode
|
||||
!unrestricted ||
|
||||
// Right of an unrestricted branch
|
||||
// <list><listItem><paragraph>a</paragraph>|</listItem></list>|
|
||||
// Both are non-content branches that can have any kind of child
|
||||
factory.getParentNodeTypes( left.type.substr( 1 ) ) === null
|
||||
)
|
||||
) ||
|
||||
// Left of branch
|
||||
// Left of a branch
|
||||
// |<list>|<listItem>|<paragraph>a</paragraph></listItem></list>
|
||||
(
|
||||
// Is not a closing
|
||||
right.type.charAt( 0 ) !== '/' &&
|
||||
// Is a branch
|
||||
factory.canNodeHaveChildren( right.type )
|
||||
factory.canNodeHaveChildren( right.type ) &&
|
||||
(
|
||||
// Only apply this rule in unrestricted mode
|
||||
!unrestricted ||
|
||||
// Left of an unrestricted branch
|
||||
// |<list><listItem>|<paragraph>a</paragraph></listItem></list>
|
||||
// Both are non-content branches that can have any kind of child
|
||||
factory.getParentNodeTypes( right.type ) === null
|
||||
)
|
||||
) ||
|
||||
// Inside empty non-content branch
|
||||
// <list>|</list> or <list><listItem>|</listItem></list>
|
||||
|
@ -258,7 +290,13 @@ ve.dm.Document.isStructuralOffset = function( data, offset ) {
|
|||
// Inside empty element
|
||||
'/' + left.type === right.type &&
|
||||
// Both are non-content branches (right is the same type)
|
||||
factory.canNodeHaveGrandchildren( left.type )
|
||||
factory.canNodeHaveGrandchildren( left.type ) &&
|
||||
(
|
||||
// Only apply this rule in unrestricted mode
|
||||
!unrestricted ||
|
||||
// Both are non-content branches that can have any kind of child
|
||||
factory.getChildNodeTypes( left.type ) === null
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -554,14 +554,14 @@ test( 'isContentOffset', function() {
|
|||
{ 'msg': 'between content branches', 'expected': false },
|
||||
{ 'msg': 'inside emtpy content branch', 'expected': true },
|
||||
{ 'msg': 'between content branches', 'expected': false },
|
||||
{ 'msg': 'begining of content branch and left of inline leaf', 'expected': true },
|
||||
{ 'msg': 'inside content branch with only non-text inline leaf', 'expected': false },
|
||||
{ 'msg': 'end of content branch and right of block leaf', 'expected': true },
|
||||
{ 'msg': 'between content and non-content branches', 'expected': false },
|
||||
{ 'msg': 'between parent and child branches, descending', 'expected': false },
|
||||
{ 'msg': 'begining of content branch, left of inline leaf', 'expected': true },
|
||||
{ 'msg': 'inside content branch with non-text inline leaf', 'expected': false },
|
||||
{ 'msg': 'end of content branch, right of block leaf', 'expected': true },
|
||||
{ 'msg': 'between content, non-content branches', 'expected': false },
|
||||
{ 'msg': 'between parent, child branches, descending', 'expected': false },
|
||||
{ 'msg': 'inside empty non-content branch', 'expected': false },
|
||||
{ 'msg': 'between parent and child branches, ascending', 'expected': false },
|
||||
{ 'msg': 'between non-content branch and block leaf', 'expected': false },
|
||||
{ 'msg': 'between parent, child branches, ascending', 'expected': false },
|
||||
{ 'msg': 'between non-content branch, block leaf', 'expected': false },
|
||||
{ 'msg': 'inside block leaf', 'expected': false },
|
||||
{ 'msg': 'right of document', 'expected': false }
|
||||
];
|
||||
|
@ -594,30 +594,41 @@ test( 'isStructuralOffset', function() {
|
|||
{ 'type': '/alienBlock' }
|
||||
],
|
||||
cases = [
|
||||
{ 'msg': 'left of document', 'expected': true },
|
||||
{ 'msg': 'begining of content branch', 'expected': false },
|
||||
{ 'msg': 'left of non-text inline leaf', 'expected': false },
|
||||
{ 'msg': 'inside non-text inline leaf', 'expected': false },
|
||||
{ 'msg': 'right of non-text inline leaf', 'expected': false },
|
||||
{ 'msg': 'between characters', 'expected': false },
|
||||
{ 'msg': 'end of content branch', 'expected': false },
|
||||
{ 'msg': 'between content branches', 'expected': true },
|
||||
{ 'msg': 'inside emtpy content branch', 'expected': false },
|
||||
{ 'msg': 'between content branches', 'expected': true },
|
||||
{ 'msg': 'begining of content branch and left of inline leaf', 'expected': false },
|
||||
{ 'msg': 'inside content branch with only non-text inline leaf', 'expected': false },
|
||||
{ 'msg': 'end of content branch and right of inline leaf', 'expected': false },
|
||||
{ 'msg': 'between content and non-content branches', 'expected': true },
|
||||
{ 'msg': 'between parent and child branches, descending', 'expected': true },
|
||||
{ 'msg': 'inside empty non-content branch', 'expected': true },
|
||||
{ 'msg': 'between parent and child branches, ascending', 'expected': true },
|
||||
{ 'msg': 'between non-content branch and block leaf', 'expected': true },
|
||||
{ 'msg': 'inside block leaf', 'expected': false },
|
||||
{ 'msg': 'right of document', 'expected': true }
|
||||
{ 'msg': 'left of document', 'expected': [true, true] },
|
||||
{ 'msg': 'begining of content branch', 'expected': [false, false] },
|
||||
{ 'msg': 'left of non-text inline leaf', 'expected': [false, false] },
|
||||
{ 'msg': 'inside non-text inline leaf', 'expected': [false, false] },
|
||||
{ 'msg': 'right of non-text inline leaf', 'expected': [false, false] },
|
||||
{ 'msg': 'between characters', 'expected': [false, false] },
|
||||
{ 'msg': 'end of content branch', 'expected': [false, false] },
|
||||
{ 'msg': 'between content branches', 'expected': [true, true] },
|
||||
{ 'msg': 'inside emtpy content branch', 'expected': [false, false] },
|
||||
{ 'msg': 'between content branches', 'expected': [true, true] },
|
||||
{ 'msg': 'begining of content branch, left of inline leaf', 'expected': [false, false] },
|
||||
{ 'msg': 'inside content branch with non-text inline leaf', 'expected': [false, false] },
|
||||
{ 'msg': 'end of content branch, right of inline leaf', 'expected': [false, false] },
|
||||
{ 'msg': 'between content, non-content branches', 'expected': [true, true] },
|
||||
{ 'msg': 'between parent, child branches, descending', 'expected': [true, false] },
|
||||
{ 'msg': 'inside empty non-content branch', 'expected': [true, true] },
|
||||
{ 'msg': 'between parent, child branches, ascending', 'expected': [true, false] },
|
||||
{ 'msg': 'between non-content branch, block leaf', 'expected': [true, true] },
|
||||
{ 'msg': 'inside block leaf', 'expected': [false, false] },
|
||||
{ 'msg': 'right of document', 'expected': [true, true] }
|
||||
];
|
||||
expect( data.length + 1 );
|
||||
expect( ( data.length + 1 ) * 2 );
|
||||
for ( var i = 0; i < cases.length; i++ ) {
|
||||
strictEqual( ve.dm.Document.isStructuralOffset( data, i ), cases[i].expected, cases[i].msg );
|
||||
var left = data[i - 1] ? ( data[i - 1].type || data[i - 1][0] ) : '[start]',
|
||||
right = data[i] ? ( data[i].type || data[i][0] ) : '[end]';
|
||||
strictEqual(
|
||||
ve.dm.Document.isStructuralOffset( data, i ),
|
||||
cases[i].expected[0],
|
||||
cases[i].msg + ' (' + left + '|' + right + ' @ ' + i + ')'
|
||||
);
|
||||
strictEqual(
|
||||
ve.dm.Document.isStructuralOffset( data, i, true ),
|
||||
cases[i].expected[1],
|
||||
cases[i].msg + ', unrestricted (' + left + '|' + right + ' @ ' + i + ')'
|
||||
);
|
||||
}
|
||||
} );
|
||||
|
||||
|
@ -654,14 +665,14 @@ test( 'isElementData', 1, function() {
|
|||
{ 'msg': 'between content branches', 'expected': true },
|
||||
{ 'msg': 'inside emtpy content branch', 'expected': true },
|
||||
{ 'msg': 'between content branches', 'expected': true },
|
||||
{ 'msg': 'begining of content branch and left of inline leaf', 'expected': true },
|
||||
{ 'msg': 'inside content branch with only non-text leaf', 'expected': true },
|
||||
{ 'msg': 'end of content branch and right of inline leaf', 'expected': true },
|
||||
{ 'msg': 'between content and non-content branches', 'expected': true },
|
||||
{ 'msg': 'between parent and child branches, descending', 'expected': true },
|
||||
{ 'msg': 'begining of content branch, left of inline leaf', 'expected': true },
|
||||
{ 'msg': 'inside content branch with non-text leaf', 'expected': true },
|
||||
{ 'msg': 'end of content branch, right of inline leaf', 'expected': true },
|
||||
{ 'msg': 'between content, non-content branches', 'expected': true },
|
||||
{ 'msg': 'between parent, child branches, descending', 'expected': true },
|
||||
{ 'msg': 'inside empty non-content branch', 'expected': true },
|
||||
{ 'msg': 'between parent and child branches, ascending', 'expected': true },
|
||||
{ 'msg': 'between non-content branch and block leaf', 'expected': true },
|
||||
{ 'msg': 'between parent, child branches, ascending', 'expected': true },
|
||||
{ 'msg': 'between non-content branch, block leaf', 'expected': true },
|
||||
{ 'msg': 'inside block leaf', 'expected': true },
|
||||
{ 'msg': 'right of document', 'expected': false }
|
||||
];
|
||||
|
|
Loading…
Reference in a new issue