Skip to content

Commit

Permalink
Feature: Added Custom Properties lists to the editor view node inspec…
Browse files Browse the repository at this point in the history
…tor. Closes #16.
  • Loading branch information
oleq committed Mar 18, 2019
1 parent 2bce200 commit 8711452
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 10 deletions.
11 changes: 8 additions & 3 deletions src/components/propertylist.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
--ck-inspector-color-property-list-property-name: #D0363F;
--ck-inspector-color-property-list-property-value-true: green;
--ck-inspector-color-property-list-property-value-false: red;
--ck-inspector-color-property-list-property-value-undefined: #888;
--ck-inspector-color-property-list-property-value-unknown: #888;
--ck-inspector-color-property-list-background: #F5F5F5;
}

Expand Down Expand Up @@ -43,8 +43,13 @@
color: var(--ck-inspector-color-property-list-property-value-true);
}

&[value="undefined"] {
color: var(--ck-inspector-color-property-list-property-value-undefined);
&[value="undefined"],
&[value="function() {…}"] {
color: var(--ck-inspector-color-property-list-property-value-unknown);
}

&[value="function() {…}"] {
font-style: italic;
}
}
}
8 changes: 8 additions & 0 deletions src/components/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export function stringify( value, quotesAroundText = true ) {
return 'undefined';
}

if ( typeof value === 'function' ) {
return 'function() {…}';
}

const stringified = JSON.stringify( value );

// Note: Remove leading and trailing quotes (") from the output. By default it is:
Expand Down Expand Up @@ -37,6 +41,10 @@ export function uid() {

export function stringifyPropertyList( list ) {
return list.map( ( [ name, value ] ) => {
if ( typeof name === 'symbol' ) {
name = name.toString();
}

return [ name, stringify( value ) ];
} );
}
24 changes: 17 additions & 7 deletions src/components/view/nodeinspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
import { stringifyPropertyList } from '../utils';
import ObjectInspector from '../objectinspector';

const DOCS_URL_PREFIX = 'https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view';

class NodeInspector extends Component {
editorEventObserverConfig( props ) {
return {
Expand Down Expand Up @@ -61,6 +63,11 @@ class NodeInspector extends Component {
url: info.url,
items: info.properties
},
{
name: 'Custom Properties',
url: `${ DOCS_URL_PREFIX }_element-Element.html#function-getCustomProperty`,
items: info.customProperties
}
]}
/>;
}
Expand All @@ -84,29 +91,30 @@ class NodeInspector extends Component {
const info = {
editorNode: node,
properties: [],
attributes: []
attributes: [],
customProperties: []
};

if ( isViewElement( node ) ) {
if ( isViewRoot( node ) ) {
info.type = 'RootEditableElement';
info.name = node.rootName;
info.url = 'https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_rooteditableelement-RootEditableElement.html';
info.url = `${ DOCS_URL_PREFIX }_rooteditableelement-RootEditableElement.html`;
} else {
info.name = node.name;

if ( isViewAttributeElement( node ) ) {
info.type = 'AttributeElement';
info.url = 'https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_attributeelement-AttributeElement.html';
info.url = `${ DOCS_URL_PREFIX }_attributeelement-AttributeElement.html`;
} else if ( isViewEmptyElement( node ) ) {
info.type = 'EmptyElement';
info.url = 'https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_emptyelement-EmptyElement.html';
info.url = `${ DOCS_URL_PREFIX }_emptyelement-EmptyElement.html`;
} else if ( isViewUiElement( node ) ) {
info.type = 'UIElement';
info.url = 'https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_uielement-UIElement.html';
info.url = `${ DOCS_URL_PREFIX }_uielement-UIElement.html`;
} else {
info.type = 'ContainerElement';
info.url = 'https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_containerelement-ContainerElement.html';
info.url = `${ DOCS_URL_PREFIX }_containerelement-ContainerElement.html`;
}
}

Expand All @@ -116,17 +124,19 @@ class NodeInspector extends Component {
[ 'isEmpty', node.isEmpty ],
[ 'childCount', node.childCount ],
);
info.customProperties.push( ...node.getCustomProperties() );
} else {
info.name = node.data;
info.type = 'Text';
info.url = 'https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_text-Text.html';
info.url = `${ DOCS_URL_PREFIX }_text-Text.html`;

info.properties.push(
[ 'index', node.index ]
);
}

info.properties = stringifyPropertyList( info.properties );
info.customProperties = stringifyPropertyList( info.customProperties );
info.attributes = stringifyPropertyList( info.attributes );

return info;
Expand Down
4 changes: 4 additions & 0 deletions tests/inspector/components/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe( 'Utils', () => {
expect( stringify( 'foo' ) ).to.equal( '"foo"' );
expect( stringify( [ 'a' ] ) ).to.equal( '["a"]' );
expect( stringify( { a: false } ) ).to.equal( '{"a":false}' );
expect( stringify( () => 'foo' ) ).to.equal( 'function() {…}' );
} );

it( 'stringifies values (no quotes around text)', () => {
Expand All @@ -25,6 +26,7 @@ describe( 'Utils', () => {
expect( stringify( 'foo', false ) ).to.equal( 'foo' );
expect( stringify( [ 'a' ], false ) ).to.equal( '["a"]' );
expect( stringify( { a: false }, false ) ).to.equal( '{"a":false}' );
expect( stringify( () => 'foo' ), false ).to.equal( 'function() {…}' );
} );
} );

Expand All @@ -39,9 +41,11 @@ describe( 'Utils', () => {
expect( stringifyPropertyList( [
[ 'foo', 'bar' ],
[ 'baz', 'qux' ],
[ Symbol( '42' ), 'abc' ]
] ) ).to.have.deep.members( [
[ 'foo', '"bar"' ],
[ 'baz', '"qux"' ],
[ 'Symbol(42)', '"abc"' ]
] );
} );
} );
Expand Down
42 changes: 42 additions & 0 deletions tests/inspector/components/view/nodeinspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ describe( '<ViewNodeInspector />', () => {
it( 'renders for a RootElement', () => {
editor.setData( '<p>foo</p>' );

editor.editing.view.change( writer => {
writer.setCustomProperty( 'foo', 'bar', editor.editing.view.document.getRoot() );
} );

wrapper.setProps( {
inspectedNode: root
} );
Expand All @@ -133,11 +137,23 @@ describe( '<ViewNodeInspector />', () => {
[ 'isEmpty', 'false' ],
[ 'childCount', '1' ],
] );

expect( lists[ 2 ].name ).to.equal( 'Custom Properties' );

const items = lists[ 2 ].items;
expect( items[ 0 ] ).to.have.members( [ 'Symbol(rootName)', '"main"' ] );
expect( items[ 1 ][ 0 ] ).to.equal( 'Symbol(document)' );
expect( items[ 1 ][ 1 ] ).to.match( /^{/ );
expect( items[ 2 ] ).to.have.members( [ 'foo', '"bar"' ] );
} );

it( 'renders for a ContainerElement', () => {
editor.setData( '<p>foo</p>' );

editor.editing.view.change( writer => {
writer.setCustomProperty( 'foo', 'bar', editor.editing.view.document.getRoot().getChild( 0 ) );
} );

wrapper.setProps( {
inspectedNode: root.getChild( 0 )
} );
Expand All @@ -157,11 +173,20 @@ describe( '<ViewNodeInspector />', () => {
[ 'isEmpty', 'false' ],
[ 'childCount', '1' ],
] );

expect( lists[ 2 ].name ).to.equal( 'Custom Properties' );
expect( lists[ 2 ].items ).to.deep.equal( [
[ 'foo', '"bar"' ]
] );
} );

it( 'renders for an AttributeElement', () => {
editor.setData( '<p><b>foo</b></p>' );

editor.editing.view.change( writer => {
writer.setCustomProperty( 'foo', 'bar', editor.editing.view.document.getRoot().getChild( 0 ).getChild( 0 ) );
} );

wrapper.setProps( {
inspectedNode: root.getChild( 0 ).getChild( 0 )
} );
Expand All @@ -181,6 +206,11 @@ describe( '<ViewNodeInspector />', () => {
[ 'isEmpty', 'false' ],
[ 'childCount', '1' ],
] );

expect( lists[ 2 ].name ).to.equal( 'Custom Properties' );
expect( lists[ 2 ].items ).to.deep.equal( [
[ 'foo', '"bar"' ]
] );
} );

it( 'renders for an EmptyElement', () => {
Expand All @@ -189,6 +219,7 @@ describe( '<ViewNodeInspector />', () => {
editor.editing.view.change( writer => {
const foo = writer.createEmptyElement( 'foo' );
writer.insert( editor.editing.view.document.selection.getFirstPosition(), foo );
writer.setCustomProperty( 'foo', 'bar', foo );
} );

wrapper.setProps( {
Expand All @@ -210,6 +241,11 @@ describe( '<ViewNodeInspector />', () => {
[ 'isEmpty', 'true' ],
[ 'childCount', '0' ],
] );

expect( lists[ 2 ].name ).to.equal( 'Custom Properties' );
expect( lists[ 2 ].items ).to.deep.equal( [
[ 'foo', '"bar"' ]
] );
} );

it( 'renders for an UIElement', () => {
Expand All @@ -218,6 +254,7 @@ describe( '<ViewNodeInspector />', () => {
editor.editing.view.change( writer => {
const foo = writer.createUIElement( 'foo' );
writer.insert( editor.editing.view.document.selection.getFirstPosition(), foo );
writer.setCustomProperty( 'foo', 'bar', foo );
} );

wrapper.setProps( {
Expand All @@ -239,6 +276,11 @@ describe( '<ViewNodeInspector />', () => {
[ 'isEmpty', 'true' ],
[ 'childCount', '0' ],
] );

expect( lists[ 2 ].name ).to.equal( 'Custom Properties' );
expect( lists[ 2 ].items ).to.deep.equal( [
[ 'foo', '"bar"' ]
] );
} );

it( 'renders for a Text', () => {
Expand Down

0 comments on commit 8711452

Please sign in to comment.