Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit bc1c3e5

Browse files
author
Piotr Jasiun
authored
Merge pull request #1242 from ckeditor/t/1239
Feature: Allowed passing `true` as `view.Matcher`'s attribute match to check if that attribute is set. Closes #1239.
2 parents 131e9c8 + f0d37a7 commit bc1c3e5

File tree

4 files changed

+46
-5
lines changed

4 files changed

+46
-5
lines changed

src/view/element.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ export default class Element extends Node {
329329
* @fires module:engine/view/node~Node#change
330330
*/
331331
setAttribute( key, value ) {
332+
value = String( value );
333+
332334
this._fireChange( 'attributes', this );
333335

334336
if ( key == 'class' ) {

src/view/matcher.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ export default class Matcher {
4141
*
4242
* matcher.add( {
4343
* attribute: {
44-
* title: 'foobar',
45-
* foo: /^\w+/
44+
* title: 'foobar', // Attribute title should equal 'foobar'.
45+
* foo: /^\w+/, // Attribute foo should match /^\w+/ regexp.
46+
* bar: true // Attribute bar should be set (can be empty).
4647
* }
4748
* } );
4849
*
@@ -95,8 +96,10 @@ export default class Matcher {
9596
* {@link module:engine/view/matcher~Matcher#match match} or {@link module:engine/view/matcher~Matcher#matchAll matchAll} methods.
9697
* @param {String|RegExp} [pattern.name] Name or regular expression to match element's name.
9798
* @param {Object} [pattern.attribute] Object with key-value pairs representing attributes to match. Each object key
98-
* represents attribute name. Value under that key can be either a string or a regular expression and it will be
99-
* used to match attribute value.
99+
* represents attribute name. Value under that key can be either:
100+
* * `true` - then attribute is just required (can be empty),
101+
* * a string - then attribute has to be equal, or
102+
* * a regular expression - then attribute has to match the expression.
100103
* @param {String|RegExp|Array} [pattern.class] Class name or array of class names to match. Each name can be
101104
* provided in a form of string or regular expression.
102105
* @param {Object} [pattern.style] Object with key-value pairs representing styles to match. Each object key
@@ -295,7 +298,9 @@ function matchAttributes( patterns, element ) {
295298
if ( element.hasAttribute( name ) ) {
296299
const attribute = element.getAttribute( name );
297300

298-
if ( pattern instanceof RegExp ) {
301+
if ( pattern === true ) {
302+
match.push( name );
303+
} else if ( pattern instanceof RegExp ) {
299304
if ( pattern.test( attribute ) ) {
300305
match.push( name );
301306
} else {

tests/view/element.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,12 @@ describe( 'Element', () => {
430430
expect( el._attrs.get( 'foo' ) ).to.equal( 'bar' );
431431
} );
432432

433+
it( 'should cast attribute value to a string', () => {
434+
el.setAttribute( 'foo', true );
435+
436+
expect( el._attrs.get( 'foo' ) ).to.equal( 'true' );
437+
} );
438+
433439
it( 'should fire change event with attributes type', done => {
434440
el.once( 'change:attributes', eventInfo => {
435441
expect( eventInfo.source ).to.equal( el );

tests/view/matcher.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,34 @@ describe( 'Matcher', () => {
126126
expect( matcher.match( el3 ) ).to.be.null;
127127
} );
128128

129+
it( 'should match if element has given attribute', () => {
130+
const pattern = {
131+
attribute: {
132+
title: true
133+
}
134+
};
135+
const matcher = new Matcher( pattern );
136+
const el1 = new Element( 'p', { title: 'foobar' } );
137+
const el2 = new Element( 'p', { title: '' } );
138+
const el3 = new Element( 'p' );
139+
140+
let result = matcher.match( el1 );
141+
expect( result ).to.be.an( 'object' );
142+
expect( result ).to.have.property( 'element' ).that.equal( el1 );
143+
expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
144+
expect( result ).to.have.property( 'match' ).that.has.property( 'attribute' ).that.is.an( 'array' );
145+
expect( result.match.attribute[ 0 ] ).equal( 'title' );
146+
147+
result = matcher.match( el2 );
148+
expect( result ).to.be.an( 'object' );
149+
expect( result ).to.have.property( 'element' ).that.equal( el2 );
150+
expect( result ).to.have.property( 'pattern' ).that.equal( pattern );
151+
expect( result ).to.have.property( 'match' ).that.has.property( 'attribute' ).that.is.an( 'array' );
152+
expect( result.match.attribute[ 0 ] ).equal( 'title' );
153+
154+
expect( matcher.match( el3 ) ).to.be.null;
155+
} );
156+
129157
it( 'should match element class names', () => {
130158
const pattern = { class: 'foobar' };
131159
const matcher = new Matcher( pattern );

0 commit comments

Comments
 (0)