import { Pipeline, Step } from '@ephox/agar';
import { Arr } from '@ephox/katamari';
import { LegacyUnit } from '@ephox/mcagar';
import Serializer from 'tinymce/core/api/dom/Serializer';
import DOMUtils from 'tinymce/core/api/dom/DOMUtils';
import TrimHtml from 'tinymce/core/dom/TrimHtml';
import ViewBlock from '../../module/test/ViewBlock';
import Zwsp from 'tinymce/core/text/Zwsp';
import { UnitTest } from '@ephox/bedrock';
declare const escape: any;
UnitTest.asynctest('browser.tinymce.core.dom.SerializerTest', function () {
const success = arguments[arguments.length - 2];
const failure = arguments[arguments.length - 1];
const suite = LegacyUnit.createSuite();
const DOM = DOMUtils.DOM;
const viewBlock = ViewBlock();
const teardown = function () {
viewBlock.update('');
};
const addTeardown = function (steps) {
return Arr.bind(steps, function (step) {
return [step, Step.sync(teardown)];
});
};
suite.test('Schema rules', function () {
let ser = Serializer({ fix_list_elements : true });
ser.setRules('@[id|title|class|style],div,img[src|alt|-style|border],span,hr');
DOM.setHTML('test', '
test
test
');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '', 'Output name and attribute rules');
ser.setRules('img[src|border=0|alt=]');
DOM.setHTML('test', '
');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '
', 'Default attribute with empty value');
ser.setRules('img[src|border=0|alt=],div[style|id],*[*]');
DOM.setHTML('test', '

');
LegacyUnit.equal(
ser.serialize(DOM.get('test')),
'

'
);
});
suite.test('allow_unsafe_link_target (default)', function () {
const ser = Serializer({ });
DOM.setHTML('test', 'ab');
LegacyUnit.equal(
ser.serialize(DOM.get('test'), { getInner: true }),
'ab'
);
DOM.setHTML('test', 'ab');
LegacyUnit.equal(
ser.serialize(DOM.get('test'), { getInner: true }),
'ab'
);
DOM.setHTML('test', 'ab');
LegacyUnit.equal(
ser.serialize(DOM.get('test'), { getInner: true }),
'ab'
);
DOM.setHTML('test', 'a');
LegacyUnit.equal(
ser.serialize(DOM.get('test'), { getInner: true }),
'a'
);
DOM.setHTML('test', 'a');
LegacyUnit.equal(
ser.serialize(DOM.get('test'), { getInner: true }),
'a'
);
});
suite.test('allow_unsafe_link_target (disabled)', function () {
const ser = Serializer({ allow_unsafe_link_target: true });
DOM.setHTML('test', 'ab');
LegacyUnit.equal(
ser.serialize(DOM.get('test'), { getInner: true }),
'ab'
);
});
suite.test('format tree', function () {
const ser = Serializer({ });
DOM.setHTML('test', 'a');
LegacyUnit.equal(
ser.serialize(DOM.get('test'), { format: 'tree' }).name,
'body'
);
});
suite.test('Entity encoding', function () {
let ser;
ser = Serializer({ entity_encoding : 'numeric' });
DOM.setHTML('test', '<>&" åäö');
LegacyUnit.equal(ser.serialize(DOM.get('test'), { getInner : true }), '<>&" åäö');
ser = Serializer({ entity_encoding : 'named' });
DOM.setHTML('test', '<>&" åäö');
LegacyUnit.equal(ser.serialize(DOM.get('test'), { getInner : true }), '<>&" åäö');
ser = Serializer({ entity_encoding : 'named+numeric', entities : '160,nbsp,34,quot,38,amp,60,lt,62,gt' });
DOM.setHTML('test', '<>&" åäö');
LegacyUnit.equal(ser.serialize(DOM.get('test'), { getInner : true }), '<>&" åäö');
ser = Serializer({ entity_encoding : 'raw' });
DOM.setHTML('test', '<>&" åäö');
LegacyUnit.equal(ser.serialize(DOM.get('test'), { getInner : true }), '<>&"\u00a0\u00e5\u00e4\u00f6');
});
suite.test('Form elements (general)', function () {
const ser = Serializer({ fix_list_elements : true });
ser.setRules(
'form[method],label[for],input[type|name|value|checked|disabled|readonly|length|maxlength],select[multiple],' +
'option[value|selected],textarea[name|disabled|readonly]'
);
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
// Edge will add an empty input value so remove that to normalize test since it doesn't break anything
LegacyUnit.equal(
ser.serialize(DOM.get('test')).replace(/ value=""/g, ''),
''
);
});
suite.test('Form elements (checkbox)', function () {
const ser = Serializer({ fix_list_elements : true });
ser.setRules('form[method],label[for],input[type|name|value|checked|disabled|readonly|length|maxlength],select[multiple],option[value|selected]');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
});
suite.test('Form elements (select)', function () {
const ser = Serializer({ fix_list_elements : true });
ser.setRules('form[method],label[for],input[type|name|value|checked|disabled|readonly|length|maxlength],select[multiple],option[value|selected]');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
DOM.setHTML('test', '');
LegacyUnit.equal(ser.serialize(DOM.get('test')), '');
});
suite.test('List elements', function () {
const ser = Serializer({ fix_list_elements : true });
ser.setRules('ul[compact],ol,li');
DOM.setHTML('test', 'test
'); LegacyUnit.equal(ser.serialize(DOM.get('test')), 'test
'); }); suite.test('Padd empty elements with BR', function () { const ser = Serializer({ padd_empty_with_br: true }); ser.setRules('#p,table,tr,#td,br'); DOM.setHTML('test', '
a
'); LegacyUnit.equal(ser.serialize(DOM.get('test')), 'a
a
a
'); LegacyUnit.equal(ser.serialize(DOM.get('test')), '
'); }); suite.test('Remove empty elements', function () { const ser = Serializer({ fix_list_elements : true }); ser.setRules('-p'); DOM.setHTML('test', '
test
'); LegacyUnit.equal(ser.serialize(DOM.get('test')), 'test
'); }); suite.test('Script with non JS type attribute', function () { const ser = Serializer({ fix_list_elements : true }); ser.setRules('script[type|language|src]'); DOM.setHTML('test', ''); LegacyUnit.equal(ser.serialize(DOM.get('test')), '
'); }); suite.test('Script with src attr', function () { const ser = Serializer({ fix_list_elements : true }); ser.setRules('script[type|language|src]'); DOM.setHTML('test', ''); }); suite.test('Script with block comment around cdata with element_format: xhtml', function () { const ser = Serializer({ fix_list_elements : true, element_format: 'xhtml' }); ser.setRules('script[type|language|src]'); DOM.setHTML('test', ''); }); suite.test('Script with html comment and block comment around cdata with element_format: xhtml', function () { const ser = Serializer({ fix_list_elements : true, element_format: 'xhtml' }); ser.setRules('script[type|language|src]'); DOM.setHTML('test', ''); }); suite.test('Script with line comment and html comment with element_format: xhtml', function () { const ser = Serializer({ fix_list_elements : true, element_format: 'xhtml' }); ser.setRules('script[type|language|src]'); DOM.setHTML('test', ''); }); suite.test('Script with block comment around html comment with element_format: xhtml', function () { const ser = Serializer({ fix_list_elements : true, element_format: 'xhtml' }); ser.setRules('script[type|language|src]'); DOM.setHTML('test', ''); }); suite.test('Protected blocks', function () { const ser = Serializer({ fix_list_elements : true }); ser.setRules('noscript[test]'); DOM.setHTML('test', ''); LegacyUnit.equal(ser.serialize(DOM.get('test')), ''); DOM.setHTML('test', ''); LegacyUnit.equal(ser.serialize(DOM.get('test')), ''); DOM.setHTML('test', '
a
a
'); DOM.setHTML('test', 'aa
'); LegacyUnit.equal(ser.serialize(DOM.get('test'), { getInner: 1 }), 'a
'); LegacyUnit.equal(TrimHtml.trimExternal(ser, 'a
'), 'a
'); }); suite.test('addTempAttr same attr twice', function () { const ser1 = Serializer({}); const ser2 = Serializer({}); ser1.addTempAttr('data-x'); ser2.addTempAttr('data-x'); DOM.setHTML('test', 'a
'); LegacyUnit.equal(ser1.serialize(DOM.get('test'), { getInner: 1 }), 'a
'); LegacyUnit.equal(TrimHtml.trimExternal(ser1, 'a
'), 'a
'); LegacyUnit.equal(ser2.serialize(DOM.get('test'), { getInner: 1 }), 'a
'); LegacyUnit.equal(TrimHtml.trimExternal(ser2, 'a
'), 'a
'); }); suite.test('trim data-mce-bougs="all"', function () { const ser = Serializer({}); DOM.setHTML('test', 'ab
c'); LegacyUnit.equal(ser.serialize(DOM.get('test'), { getInner: 1 }), 'ac'); LegacyUnit.equal(TrimHtml.trimExternal(ser, 'ab
c'), 'ac'); }); suite.test('zwsp should not be treated as contents', function () { const ser = Serializer({ }); DOM.setHTML('test', '' + Zwsp.ZWSP + '
'); LegacyUnit.equal( ser.serialize(DOM.get('test'), { getInner: true }), '' ); }); viewBlock.attach(); viewBlock.get().id = 'test'; Pipeline.async({}, addTeardown(suite.toSteps({})), function () { viewBlock.detach(); success(); }, failure); });