Krinkle has uploaded a new change for review.
https://gerrit.wikimedia.org/r/189507
Change subject: ve.utils: Apply whitelist in setDomAttributes() attribute
removal
......................................................................
ve.utils: Apply whitelist in setDomAttributes() attribute removal
Previously, the whitelist only affected setting of attributes.
Input that wants to remove attributes was always honoured, even
if the key was not whitelisted.
* Simplify test assertions.
* Test whitelist for attribute removal.
* Test case-insensitive nature of whitelist.
Change-Id: Id4ab9fb3d0609182f83724327b8b5b9258b1b86d
---
M src/ve.utils.js
M tests/ve.test.js
2 files changed, 52 insertions(+), 18 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor
refs/changes/07/189507/1
diff --git a/src/ve.utils.js b/src/ve.utils.js
index 05fa63a..74b3d78 100644
--- a/src/ve.utils.js
+++ b/src/ve.utils.js
@@ -554,9 +554,11 @@
/**
* Set the attributes of a DOM element as an object with key/value pairs.
*
+ * Use the `null` or `undefined` value to ensure an attribute's absence.
+ *
* @param {HTMLElement} element DOM element to apply attributes to
* @param {Object} attributes Attributes to apply
- * @param {string[]} [whitelist] List of attributes to exclusively allow (all
lower case names)
+ * @param {string[]} [whitelist] List of attributes to exclusively allow (all
lowercase names)
*/
ve.setDomAttributes = function ( element, attributes, whitelist ) {
var key;
@@ -565,12 +567,12 @@
return;
}
for ( key in attributes ) {
+ if ( whitelist && whitelist.indexOf( key.toLowerCase() ) === -1
) {
+ continue;
+ }
if ( attributes[key] === undefined || attributes[key] === null
) {
element.removeAttribute( key );
} else {
- if ( whitelist && whitelist.indexOf( key.toLowerCase()
) === -1 ) {
- continue;
- }
element.setAttribute( key, attributes[key] );
}
}
diff --git a/tests/ve.test.js b/tests/ve.test.js
index d598ae5..f411252 100644
--- a/tests/ve.test.js
+++ b/tests/ve.test.js
@@ -88,28 +88,60 @@
QUnit.test( 'getDomAttributes', 1, function ( assert ) {
assert.deepEqual(
- ve.getDomAttributes( $( '<div foo="bar" baz quux=3></div>'
).get( 0 ) ),
- { foo: 'bar', baz: '', quux: '3' },
+ ve.getDomAttributes( $.parseHTML( '<div string="foo" empty
number="0"></div>' )[ 0 ] ),
+ { string: 'foo', empty: '', number: '0' },
'getDomAttributes() returns object with correct attributes'
);
} );
-QUnit.test( 'setDomAttributes', 3, function ( assert ) {
- var element = document.createElement( 'div' );
- ve.setDomAttributes( element, { foo: 'bar', baz: '', quux: 3 } );
+QUnit.test( 'setDomAttributes', 7, function ( assert ) {
+ var target,
+ sample = $.parseHTML( '<div foo="one" bar="two"
baz="three"></div>' )[ 0 ];
+
+ target = {};
+ ve.setDomAttributes( target, { add: 'foo' } );
+ assert.deepEqual( target, {}, 'ignore incompatible target object' );
+
+ target = document.createElement( 'div' );
+ ve.setDomAttributes( target, { string: 'foo', empty: '', number: 0 } );
assert.deepEqual(
- ve.getDomAttributes( element ),
- { foo: 'bar', baz: '', quux: '3' },
- 'setDomAttributes() sets attributes correctly'
+ ve.getDomAttributes( target ),
+ { string: 'foo', empty: '', number: '0' },
+ 'add attributes'
);
- ve.setDomAttributes( element, { foo: null, bar: 1, baz: undefined,
quux: 5, whee: 'yay' } );
+
+ target = sample.cloneNode();
+ ve.setDomAttributes( target, { foo: null, bar: 'update', baz:
undefined, add: 'yay' } );
assert.deepEqual(
- ve.getDomAttributes( element ),
- { bar: '1', quux: '5', whee: 'yay' },
- 'setDomAttributes() overwrites attributes, removes attributes,
and sets new attributes'
+ ve.getDomAttributes( target ),
+ { bar: 'update', add: 'yay' },
+ 'add, update, and remove attributes'
);
- ve.setDomAttributes( element, { onclick: 'alert(1);' }, ['foo', 'bar',
'baz', 'quux', 'whee'] );
- assert.ok( !element.hasAttribute( 'onclick' ), 'event attributes are
blocked when sanitizing' );
+
+ target = sample.cloneNode();
+ ve.setDomAttributes( target, { onclick: 'alert(1);', foo: 'update',
add: 'whee' }, ['foo', 'add'] );
+ assert.ok( !target.hasAttribute( 'onclick' ), 'whitelist affects
creating attributes' );
+ assert.deepEqual(
+ ve.getDomAttributes( target ),
+ { foo: 'update', bar: 'two', baz: 'three', add: 'whee' },
+ 'whitelist does not affect pre-existing attributes'
+ );
+
+ target = document.createElement( 'div' );
+ ve.setDomAttributes( target, { Foo: 'add', Bar: 'add' }, ['bar'] );
+ assert.deepEqual(
+ ve.getDomAttributes( target ),
+ { bar: 'add' },
+ 'whitelist is case-insensitive'
+ );
+
+ target = sample.cloneNode();
+ ve.setDomAttributes( target, { foo: 'update', bar: null }, ['bar',
'baz'] );
+ assert.propEqual(
+ ve.getDomAttributes( target ),
+ { foo: 'one', baz: 'three' },
+ 'whitelist affects removal/updating of attributes'
+ );
} );
QUnit.test( 'getHtmlAttributes', 7, function ( assert ) {
--
To view, visit https://gerrit.wikimedia.org/r/189507
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Id4ab9fb3d0609182f83724327b8b5b9258b1b86d
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Krinkle <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits