Файловый менеджер - Редактировать - /var/www/html/mediawiki-1.43.1/extensions/VisualEditor/lib/ve/tests/ce/ve.ce.test.js
Ðазад
/*! * VisualEditor ContentEditable tests. * * @copyright See AUTHORS.txt */ QUnit.module( 've.ce' ); /* Tests */ QUnit.test( 'getDomHash/getDomText (with ve.dm.Converter)', ( assert ) => { const cases = [ { msg: 'Nested annotations', html: '<p><span>a<b><a href="#">b</a></b><span> </span><i>c</i>d</span></p>', hash: '<DIV><P><SPAN>#<B><A>#</A></B><SPAN>#</SPAN><I>#</I>#</SPAN></P></DIV>', text: 'ab cd' }, { msg: 'Inline nodes produce snowmen', html: '<p>Foo <span rel="ve:Alien">Alien</span> bar</p>', hash: '<DIV><P>#<SPAN>#</SPAN>#</P></DIV>', text: 'Foo ☃☃ bar' }, { msg: 'About grouped aliens produce one pair of snowmen', html: ve.dm.example.singleLine` <p> Foo <span about="g1" rel="ve:Alien">Alien</span> <span about="g1" rel="ve:Alien">Aliens</span> <span about="g1" rel="ve:Alien">Alien³</span> bar </p> `, hash: '<DIV><P>#<SPAN>#</SPAN><SPAN>#</SPAN><SPAN>#</SPAN>#</P></DIV>', text: 'Foo ☃☃ bar' }, { msg: 'Block slugs are ignored', html: '<table><tr><td>Foo</td></tr></table>', hash: '<DIV><TABLE><TBODY><TR><TD><P>#</P></TD></TR></TBODY></TABLE></DIV>', text: 'Foo' } ]; cases.forEach( ( caseItem ) => { const view = ve.test.utils.createSurfaceViewFromHtml( caseItem.html ); const documentView = view.getDocument(); assert.strictEqual( ve.ce.getDomHash( documentView.getDocumentNode().$element[ 0 ] ), caseItem.hash, 'getDomHash: ' + caseItem.msg ); assert.strictEqual( ve.ce.getDomText( documentView.getDocumentNode().$element[ 0 ] ), caseItem.text, 'getDomText: ' + caseItem.msg ); view.destroy(); } ); } ); QUnit.test( 'getDomHash/getDomText (without ve.dm.Converter)', ( assert ) => { const cases = [ { msg: 'Block slugs are ignored', html: '<div><p>foo</p><div class="ve-ce-branchNode-blockSlug">x</div><p>bar</p></div>', hash: '<DIV><P>#</P><P>#</P></DIV>', text: 'foobar' }, { msg: 'Cursor holders are ignored', html: '<div><p>foo</p><div class="ve-ce-cursorHolder">x</div><p>bar</p></div>', hash: '<DIV><P>#</P><P>#</P></DIV>', text: 'foobar' } ]; const view = ve.test.utils.createSurfaceViewFromHtml( '' ); const element = view.getDocument().getDocumentNode().$element[ 0 ]; cases.forEach( ( caseItem ) => { element.innerHTML = caseItem.html; assert.strictEqual( ve.ce.getDomHash( element.firstChild ), caseItem.hash, 'getDomHash: ' + caseItem.msg ); assert.strictEqual( ve.ce.getDomText( element.firstChild ), caseItem.text, 'getDomText: ' + caseItem.msg ); } ); view.destroy(); } ); QUnit.test( 'getOffset', ( assert ) => { const cases = [ { msg: 'Empty paragraph', html: '<p></p>', // CE HTML summary: // <p><span [inlineSlug]><img /></span></p> // Linmod: // [<p>, </p>] expected: [ 0, 1, 1, 1, 1, 1, 2 ] }, { msg: 'Annotations', html: '<p><i><b>Foo</b></i></p>', // Linmod: // [<p>, F, o, o, </p>] expected: [ 0, 1, 1, 1, 1, 2, 3, 4, 4, 4, 4, 5 ] }, { msg: 'Multiple siblings', html: '<p><b><i>Foo</i><s><u>Bar</u><span>Baz</span></s></b></p>', // Linmod: // [<p>, F, o, o, B, a, r, B, a, z, </p>] expected: [ 0, 1, 1, 1, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 7, 7, 7, 7, 8, 9, 10, 10, 10, 10, 10, 11 ] }, { msg: 'Annotated alien', html: '<p>Foo<b><span rel="ve:Alien">Bar</span></b>Baz</p>', // CE HTML summary; // <p>Foo<b><span [alien]>Bar</span></b>Baz</p> // Linmod: // [<p>, F, o, o, <alineinline>, </alineinline>, B, a, z, </p>] expected: [ 0, 1, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 7, 8, 9, 9, 10 ] }, { msg: 'Block alien', html: '<p>Foo</p><div rel="ve:Alien">Bar</div><p>Baz</p>', // Linmod: // [<p>, F, o, o, </p>, <alienBlock>, </alienBlock>, <p>, B, a, z, </p>] expected: [ 0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 6, 6, 6, 6, 7, 8, 8, 9, 10, 11, 11, 12 ] }, { msg: 'Table with block slugs', html: '<table><tr><td>Foo</td></tr></table>', // CE HTML summary; // <div [slug]>(ignored)</div> // <table><tbody><tr><td> // <p>Foo</p> // </td></tr></tbody></table> // <div [slug]>(ignored)</div> // Linmod: // [<table>, <tbody>, <tr>, <td>, <p>, F, o, o, </p>, </td>, </tr>, </tbody>, </table>] expected: [ 0, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 13 ] }, { msg: 'Paragraph with inline slugs', html: '<p><span rel="ve:Alien">Foo</span><span rel="ve:Alien">Bar</span><br></p>', // CE HTML summary: // <p><span [inlineSlug]><img /></span><span [alien]>Foo</span> // <span [inlineSlug]><img /></span><span [alien]>Bar</span> // <span [inlineSlug]><img /></span><br></br><span [inlineSlug]><img /></span></p> // Linmod: // [<p>, <alineinline>, </alineinline>, <alineinline>, </alineinline>, <break>, </break>, </p>] expected: [ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 8 ] } ]; function testOffsets( parent, testCase, expectedIndex ) { let i; switch ( parent.nodeType ) { case Node.ELEMENT_NODE: for ( i = 0; i <= parent.childNodes.length; i++ ) { expectedIndex++; assert.strictEqual( ve.ce.getOffset( parent, i ), testCase.expected[ expectedIndex ], testCase.msg + ': offset ' + i + ' in <' + parent.nodeName.toLowerCase() + '>' ); if ( parent.childNodes[ i ] && !$( parent.childNodes[ i ] ).hasClass( 've-ce-branchNode-blockSlug' ) ) { expectedIndex = testOffsets( parent.childNodes[ i ], testCase, expectedIndex ); } } break; case Node.TEXT_NODE: for ( i = 0; i <= parent.data.length; i++ ) { expectedIndex++; assert.strictEqual( ve.ce.getOffset( parent, i ), testCase.expected[ expectedIndex ], testCase.msg + ': offset ' + i + ' in "' + parent.data + '"' ); } break; } return expectedIndex; } cases.forEach( ( caseItem ) => { const view = ve.test.utils.createSurfaceViewFromHtml( caseItem.html ), documentView = view.getDocument(); testOffsets( documentView.getDocumentNode().$element[ 0 ], caseItem, -1 ); view.destroy(); } ); } ); // TODO: ve.ce.getOffsetOfSlug QUnit.test( 'isShortcutKey', ( assert ) => { assert.strictEqual( ve.ce.isShortcutKey( { ctrlKey: true } ), true, 'ctrlKey' ); assert.strictEqual( ve.ce.isShortcutKey( { metaKey: true } ), true, 'metaKey' ); assert.strictEqual( ve.ce.isShortcutKey( {} ), false, 'Not set' ); } ); QUnit.test( 'nextCursorOffset', ( assert ) => { function dumpnode( node ) { if ( node.nodeType === Node.TEXT_NODE ) { return '#' + node.data; } else { return node.nodeName.toLowerCase(); } } const cases = [ { html: '<p>foo<img>bar</p>', expected: [ '#bar', 0 ] }, { html: '<p>foo<b><i><img></i></b></p>', expected: [ 'i', 1 ] }, { html: '<p><b>foo</b><img>bar</p>', expected: [ '#bar', 0 ] }, { html: '<p>foo<b><i><img></i></b></p>', expected: [ 'i', 1 ] }, { html: '<p><b>foo</b><img></p>', expected: [ 'p', 2 ] }, { html: '<p><img><b>foo</b></p>', expected: [ 'p', 1 ] }, { html: '<p><b>foo</b><img><b>bar</b></p>', expected: [ 'p', 2 ] } ]; const elt = ve.createDocumentFromHtml( '' ).createElement( 'div' ); cases.forEach( ( caseItem ) => { elt.innerHTML = caseItem.html; const img = elt.getElementsByTagName( 'img' )[ 0 ]; const nextOffset = ve.ce.nextCursorOffset( img ); assert.deepEqual( [ dumpnode( nextOffset.node ), nextOffset.offset ], caseItem.expected, caseItem.html ); } ); } ); QUnit.test( 'resolveTestOffset', ( assert ) => { const cases = [ [ ...'ok' ], // TODO: doesn't handle tags correctly yet! // [ 'w', '<b>', 'x', 'y', '</b>', 'z' ], // [ 'q', '<b>', 'r', '<b>', 's', 't', '</b>', 'u', '</b>', 'v' ] [ ...'hello' ] ]; const dom = ve.createDocumentFromHtml( '' ); const elt = dom.createElement( 'div' ); cases.forEach( ( caseItem ) => { elt.innerHTML = caseItem.join( '' ); for ( let j = 0, jlen = caseItem.length; j < jlen + 1; j++ ) { let testOffset = new ve.ce.TestOffset( 'forward', j ); let pre = caseItem.slice( 0, j ).join( '' ); let post = caseItem.slice( j ).join( '' ); assert.strictEqual( testOffset.resolve( elt ).slice, pre + '|' + post ); testOffset = new ve.ce.TestOffset( 'backward', j ); pre = caseItem.slice( 0, jlen - j ).join( '' ); post = caseItem.slice( jlen - j ).join( '' ); assert.strictEqual( testOffset.resolve( elt ).slice, pre + '|' + post ); } } ); } ); QUnit.test( 'fakeImes', ( assert ) => { let testsFailAt; if ( Function.prototype.bind === undefined ) { // Assume we are in PhantomJS (which breaks different tests than a real browser) testsFailAt = ve.ce.imetestsPhantomFailAt; } else { testsFailAt = ve.ce.imetestsFailAt; } // TODO: make this function actually affect the events triggered const fakePreventDefault = function () {}; const fakeIsPreventDefault = function () { return false; }; ve.ce.imetests.forEach( ( caseItem ) => { const testName = caseItem[ 0 ]; const failAt = testsFailAt[ testName ] || null; const testActions = caseItem[ 1 ]; let foundEndLoop = false; // First element is the testInfo const testInfo = testActions[ 0 ]; const view = ve.test.utils.createSurfaceViewFromHtml( testInfo.startDom || '' ); view.getModel().setLinearSelection( new ve.Range( 1 ) ); const testRunner = new ve.ce.TestRunner( view ); // Start at 1 to omit the testInfo let died = false; for ( let j = 1, jlen = testActions.length; j < jlen; j++ ) { const action = testActions[ j ].action; const args = testActions[ j ].args; const seq = testActions[ j ].seq; if ( !died ) { if ( action === 'sendEvent' ) { // TODO: make preventDefault work args[ 1 ].preventDefault = fakePreventDefault; args[ 1 ].isDefaultPrevented = fakeIsPreventDefault; } try { testRunner[ action ].apply( testRunner, args ); } catch ( ex ) { died = ex; } } // Check synchronization at the end of each event loop if ( action === 'endLoop' ) { foundEndLoop = true; if ( failAt === null || seq < failAt ) { // If no expected failure yet, test the code ran and the // model and CE surface are in sync if ( died ) { testRunner.failDied( assert, testName, seq, died ); } else { testRunner.testEqual( assert, testName, seq ); } } else if ( seq === failAt ) { // If *at* expected failure, check something failed if ( died ) { testRunner.ok( assert, testName + ' (fail expected)', seq ); } else { testRunner.testNotEqual( assert, testName + ' (fail expected)', seq ); } } else { // If *after* expected failure, allow anything testRunner.ok( assert, testName, seq ); } } } // Test that there is at least one endLoop assert.strictEqual( foundEndLoop, true, testName + ' found at least one endLoop' ); view.destroy(); } ); } ); QUnit.test( 'isAfterAnnotationBoundary', ( assert ) => { const div = ve.createDocumentFromHtml( '' ).createElement( 'div' ); div.innerHTML = 'Q<b>R<i>S</i>T</b><s>U</s>V<u>W</u>'; // In the following tests, the 'path' properties are a list of descent offsets to find a // particular descendant node from the top-level div. E.g. a path of [ 5, 7 ] refers to // the node div.childNodes[ 5 ].childNodes[ 7 ] . const cases = [ { path: [], offset: 0, expected: false }, { path: [ 0 ], offset: 0, expected: false }, { path: [ 0 ], offset: 1, expected: false }, { path: [], offset: 1, expected: false }, { path: [ 1 ], offset: 0, expected: true }, { path: [ 1, 0 ], offset: 0, expected: true }, { path: [ 1, 0 ], offset: 1, expected: false }, { path: [ 1 ], offset: 1, expected: false }, { path: [ 1, 1 ], offset: 0, expected: true }, { path: [ 1, 1, 0 ], offset: 0, expected: true }, { path: [ 1, 1, 0 ], offset: 1, expected: false }, { path: [ 1, 1 ], offset: 1, expected: false }, { path: [ 1 ], offset: 2, expected: true }, { path: [ 1, 2 ], offset: 0, expected: true }, { path: [ 1, 2 ], offset: 1, expected: false }, { path: [ 1 ], offset: 3, expected: false }, // The next position *is* a after a boundary (though also before one) { path: [], offset: 2, expected: true }, { path: [ 2 ], offset: 0, expected: true }, { path: [ 2, 0 ], offset: 0, expected: true }, { path: [ 2, 0 ], offset: 1, expected: false }, { path: [ 2 ], offset: 1, expected: false }, { path: [], offset: 3, expected: true }, { path: [ 3 ], offset: 0, expected: true }, { path: [ 3 ], offset: 1, expected: false }, { path: [], offset: 4, expected: false }, { path: [ 4 ], offset: 0, expected: true }, { path: [ 4, 0 ], offset: 0, expected: true }, { path: [ 4, 0 ], offset: 1, expected: false }, { path: [ 4 ], offset: 1, expected: false }, { path: [], offset: 5, expected: true } ]; cases.forEach( ( caseItem ) => { let node = div; for ( let j = 0, jLen = caseItem.path.length; j < jLen; j++ ) { node = node.childNodes[ caseItem.path[ j ] ]; } assert.strictEqual( ve.ce.isAfterAnnotationBoundary( node, caseItem.offset ), caseItem.expected, `node=${ caseItem.path.join( ',' ) } offset=${ caseItem.offset }` ); } ); } );
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка