mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-09-27 20:26:46 +00:00
74b8807df5
This is done by using the computed property value rather than the literal attribute value when rendering href and src attributes. Helpfully, this provides perfect URL resolution natively in the browser, which means the document's <base> is respected and all that good stuff. For GeneratedContentNodes, we also need to find all DOM elements inside the rendered DOM that have href or src attributes and resolve those. This is done in the new getRenderedDomElements() function, which the existing cleanup steps (remove <link>/<meta>/<style>, clone for correct document) were moved into. In order to make sure that the computed values are always computed correctly, we need to make sure that in cases where HTML strings in data-mw are parsed, they're parsed in the context of the correct document so the correct <base> is applied. We still need to solve this problem for models that actually store and edit an href or src as an attribute. I'll post more about that on bug 48915. Bug: 48915 Change-Id: Iaccb9e3fc05cd151a0f5e632c8d3bd3568735309
139 lines
4.4 KiB
JavaScript
139 lines
4.4 KiB
JavaScript
/*!
|
|
* VisualEditor test utilities.
|
|
*
|
|
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
*/
|
|
|
|
/**
|
|
* @class
|
|
* @singleton
|
|
* @ignore
|
|
*/
|
|
ve.test = { 'utils': {} };
|
|
|
|
ve.test.utils.runIsolateTest = function ( assert, type, range, expected, label ) {
|
|
var doc = ve.dm.example.createExampleDocument( 'isolationData' ),
|
|
surface = new ve.dm.Surface( doc ),
|
|
fragment = new ve.dm.SurfaceFragment( surface, range ),
|
|
data;
|
|
|
|
data = ve.copy( doc.getFullData() );
|
|
fragment.isolateAndUnwrap( type );
|
|
expected( data );
|
|
|
|
assert.deepEqual( doc.getFullData(), data, label );
|
|
};
|
|
|
|
ve.test.utils.runFormatConverterTest = function ( assert, range, type, attributes, expectedSelection, expectedData, msg ) {
|
|
var surface = ve.test.utils.createSurfaceFromHtml( ve.dm.example.isolationHtml ),
|
|
formatAction = new ve.ui.FormatAction( surface ),
|
|
data = ve.copy( surface.getModel().getDocument().getFullData() ),
|
|
originalData = ve.copy( data );
|
|
|
|
expectedData( data );
|
|
|
|
surface.getModel().setSelection( range );
|
|
formatAction.convert( type, attributes );
|
|
|
|
assert.deepEqual( surface.getModel().getDocument().getFullData(), data, msg + ': data models match' );
|
|
assert.deepEqual( surface.getModel().getSelection(), expectedSelection, msg + ': selections match' );
|
|
|
|
surface.getModel().undo();
|
|
|
|
assert.deepEqual( surface.getModel().getDocument().getFullData(), originalData, msg + ' (undo): data models match' );
|
|
assert.deepEqual( surface.getModel().getSelection(), range, msg + ' (undo): selections match' );
|
|
|
|
surface.destroy();
|
|
};
|
|
|
|
ve.test.utils.runGetDataFromDomTests = function( assert, cases ) {
|
|
var msg, doc, store, internalList, i, length, hash, data, html, n = 0;
|
|
|
|
// TODO: this is a hack to make normal heading/preformatted
|
|
// nodes the most recently registered, instead of the MW versions
|
|
ve.dm.modelRegistry.register( ve.dm.HeadingNode );
|
|
ve.dm.modelRegistry.register( ve.dm.PreformattedNode );
|
|
|
|
for ( msg in cases ) {
|
|
if ( cases[msg].html !== undefined ) {
|
|
n++;
|
|
if ( cases[msg].storeItems ) {
|
|
n += cases[msg].storeItems.length;
|
|
}
|
|
}
|
|
}
|
|
QUnit.expect( n );
|
|
|
|
for ( msg in cases ) {
|
|
if ( cases[msg].html !== undefined ) {
|
|
doc = new ve.dm.Document( [] );
|
|
store = doc.getStore();
|
|
internalList = doc.getInternalList();
|
|
|
|
html = '';
|
|
if ( cases[msg].head ) {
|
|
html = '<head>' + cases[msg].head + '</head>';
|
|
}
|
|
html += cases[msg].html;
|
|
|
|
data = ve.dm.converter.getDataFromDom(
|
|
ve.createDocumentFromHtml( html ), store, internalList
|
|
).getData();
|
|
ve.dm.example.preprocessAnnotations( cases[msg].data, store );
|
|
assert.deepEqualWithDomElements( data, cases[msg].data, msg );
|
|
// check storeItems have been added to store
|
|
if ( cases[msg].storeItems ) {
|
|
for ( i = 0, length = cases[msg].storeItems.length; i < length; i++ ) {
|
|
hash = cases[msg].storeItems[i].hash || OO.getHash( cases[msg].storeItems[i].value );
|
|
assert.deepEqualWithDomElements(
|
|
store.value( store.indexOfHash( hash ) ) || {},
|
|
cases[msg].storeItems[i].value,
|
|
msg + ': store item ' + i + ' found'
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
ve.test.utils.runGetDomFromDataTests = function( assert, cases ) {
|
|
var msg, originalData, doc, store, i, length, n = 0;
|
|
|
|
for ( msg in cases ) {
|
|
n++;
|
|
}
|
|
QUnit.expect( 2*n );
|
|
|
|
for ( msg in cases ) {
|
|
store = new ve.dm.IndexValueStore();
|
|
// Load storeItems into store
|
|
if ( cases[msg].storeItems ) {
|
|
for ( i = 0, length = cases[msg].storeItems.length; i < length; i++ ) {
|
|
store.index( cases[msg].storeItems[i].value, cases[msg].storeItems[i].hash );
|
|
}
|
|
}
|
|
if ( cases[msg].modify ) {
|
|
cases[msg].modify( cases[msg].data );
|
|
}
|
|
doc = new ve.dm.Document( ve.dm.example.preprocessAnnotations( cases[msg].data, store ) );
|
|
originalData = ve.copy( doc.getFullData() );
|
|
assert.equalDomElement(
|
|
ve.dm.converter.getDomFromData( doc.getFullData(), doc.getStore(), doc.getInternalList() ),
|
|
ve.createDocumentFromHtml( cases[msg].normalizedHtml || cases[msg].html ),
|
|
msg
|
|
);
|
|
assert.deepEqualWithDomElements( doc.getFullData(), originalData, msg + ' (data hasn\'t changed)' );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Create a UI surface from some HTML
|
|
*
|
|
* @param {string} html Document HTML
|
|
* @returns {ve.ui.Surface} UI surface
|
|
*/
|
|
ve.test.utils.createSurfaceFromHtml = function ( html ) {
|
|
var target = new ve.init.sa.Target( $( '#qunit-fixture' ), ve.createDocumentFromHtml( html ) );
|
|
return target.surface;
|
|
}; |