Explorar el Código

Merge pull request #80 from ckeditor/t/76

Feature: Introduced the `Superscript` and the `Subscript` features. Closes #76. Closes #74.

Thanks to @idleb!
Piotrek Koszuliński hace 7 años
padre
commit
f3aa0bde31
Se han modificado 25 ficheros con 646 adiciones y 14 borrados
  1. 1 1
      packages/ckeditor5-basic-styles/README.md
  2. 1 0
      packages/ckeditor5-basic-styles/docs/_snippets/features/basic-styles.html
  3. 1 1
      packages/ckeditor5-basic-styles/docs/_snippets/features/basic-styles.js
  4. 3 1
      packages/ckeditor5-basic-styles/docs/_snippets/features/build-basic-styles-source.js
  5. 3 1
      packages/ckeditor5-basic-styles/docs/api/basic-styles.md
  6. 9 3
      packages/ckeditor5-basic-styles/docs/features/basic-styles.md
  7. 3 1
      packages/ckeditor5-basic-styles/lang/contexts.json
  8. 0 1
      packages/ckeditor5-basic-styles/package.json
  9. 36 0
      packages/ckeditor5-basic-styles/src/subscript.js
  10. 49 0
      packages/ckeditor5-basic-styles/src/subscript/subscriptediting.js
  11. 49 0
      packages/ckeditor5-basic-styles/src/subscript/subscriptui.js
  12. 36 0
      packages/ckeditor5-basic-styles/src/superscript.js
  13. 49 0
      packages/ckeditor5-basic-styles/src/superscript/superscriptediting.js
  14. 49 0
      packages/ckeditor5-basic-styles/src/superscript/superscriptui.js
  15. 1 1
      packages/ckeditor5-basic-styles/tests/manual/basic-styles.html
  16. 4 2
      packages/ckeditor5-basic-styles/tests/manual/basic-styles.js
  17. 4 2
      packages/ckeditor5-basic-styles/tests/manual/basic-styles.md
  18. 18 0
      packages/ckeditor5-basic-styles/tests/subscript.js
  19. 87 0
      packages/ckeditor5-basic-styles/tests/subscript/subscriptediting.js
  20. 68 0
      packages/ckeditor5-basic-styles/tests/subscript/subscriptui.js
  21. 18 0
      packages/ckeditor5-basic-styles/tests/superscript.js
  22. 87 0
      packages/ckeditor5-basic-styles/tests/superscript/superscriptediting.js
  23. 68 0
      packages/ckeditor5-basic-styles/tests/superscript/superscriptui.js
  24. 1 0
      packages/ckeditor5-basic-styles/theme/icons/subscript.svg
  25. 1 0
      packages/ckeditor5-basic-styles/theme/icons/superscript.svg

+ 1 - 1
packages/ckeditor5-basic-styles/README.md

@@ -10,7 +10,7 @@ CKEditor 5 basic styles feature
 [![Dependency Status](https://david-dm.org/ckeditor/ckeditor5-basic-styles/status.svg)](https://david-dm.org/ckeditor/ckeditor5-basic-styles)
 [![devDependency Status](https://david-dm.org/ckeditor/ckeditor5-basic-styles/dev-status.svg)](https://david-dm.org/ckeditor/ckeditor5-basic-styles?type=dev)
 
-This package contains CKEditor 5 features allowing to apply basic text formatting such as bold, italic, underline and code in CKEditor 5.
+This package contains CKEditor 5 features allowing to apply basic text formatting such as bold, italic, underline, and code in CKEditor 5.
 
 ## Demo
 

+ 1 - 0
packages/ckeditor5-basic-styles/docs/_snippets/features/basic-styles.html

@@ -4,4 +4,5 @@
 	<p><u>This text is underlined</u>.</p>
 	<p><s>This is a strikethrough text</s>.</p>
 	<p><code>This is an inline code</code>.</p>
+	<p>These are <sub>a subscript</sub> and <sup>a superscript</sup>.</p>
 </div>

+ 1 - 1
packages/ckeditor5-basic-styles/docs/_snippets/features/basic-styles.js

@@ -11,7 +11,7 @@ ClassicEditor
 	.create( document.querySelector( '#snippet-basic-styles' ), {
 		toolbar: {
 			items: [
-				'bold', 'italic', 'underline', 'strikethrough', 'code', '|', 'undo', 'redo'
+				'bold', 'italic', 'underline', 'strikethrough', 'subscript', 'superscript', 'code', '|', 'undo', 'redo'
 			],
 			viewportTopOffset: 100
 		},

+ 3 - 1
packages/ckeditor5-basic-styles/docs/_snippets/features/build-basic-styles-source.js

@@ -11,8 +11,10 @@ import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
 import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
 import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough';
+import Subscript from '@ckeditor/ckeditor5-basic-styles/src/subscript';
+import Superscript from '@ckeditor/ckeditor5-basic-styles/src/superscript';
 import Code from '@ckeditor/ckeditor5-basic-styles/src/code';
 
-ClassicEditor.builtinPlugins.push( Bold, Italic, Underline, Strikethrough, Code );
+ClassicEditor.builtinPlugins.push( Bold, Italic, Underline, Strikethrough, Subscript, Superscript, Code );
 
 window.ClassicEditor = ClassicEditor;

+ 3 - 1
packages/ckeditor5-basic-styles/docs/api/basic-styles.md

@@ -6,7 +6,7 @@ category: api-reference
 
 [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-basic-styles.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles)
 
-This package contains features allowing to apply basic text formatting such as bold, italic, underline, strikethrough and code in CKEditor 5.
+This package contains features allowing to apply basic text formatting such as bold, italic, underline, strikethrough, subscript, superscript, and code in CKEditor 5.
 
 ## Demo
 
@@ -22,6 +22,8 @@ You can also check out the following plugins:
 * {@link module:basic-styles/italic~Italic}
 * {@link module:basic-styles/strikethrough~Strikethrough}
 * {@link module:basic-styles/underline~Underline}
+* {@link module:basic-styles/subscript~Subscript}
+* {@link module:basic-styles/superscript~Superscript}
 * {@link module:basic-styles/code~Code}
 
 ## Installation

+ 9 - 3
packages/ckeditor5-basic-styles/docs/features/basic-styles.md

@@ -5,7 +5,7 @@ category: features
 
 {@snippet features/build-basic-styles-source}
 
-The {@link api/basic-styles basic styles} package provides text formatting features such as bold, italic, underline, strikethrough and code.
+The {@link api/basic-styles basic styles} package provides text formatting features such as bold, italic, underline, strikethrough, subscript, superscript, and code.
 
 ## Demo
 
@@ -20,6 +20,8 @@ The {@link api/basic-styles basic styles} package provides text formatting featu
 | {@link module:basic-styles/underline~Underline} | `'underline'` | `'underline'` | `<u>underline</u>` |
 | {@link module:basic-styles/strikethrough~Strikethrough} | `'strikethrough'` | `'strikethrough'` | `<s>strikethrough</s>` |
 | {@link module:basic-styles/code~Code} | `'code'` | `'code'` | `<code>code</code>` |
+| {@link module:basic-styles/subscript~Subscript} | `'subscript'` | `'subscript'` | `<sub>subscript</sub>` |
+| {@link module:basic-styles/superscript~Superscript} | `'superscript'` | `'superscript'` | `<sup>superscript</sup>` |
 
 <info-box info>
 	{@link module:basic-styles/bold~Bold} and {@link module:basic-styles/italic~Italic} are available out–of–the–box in most of the {@link builds/guides/overview editor builds}.
@@ -36,6 +38,8 @@ By default, each feature can upcast more than one type of the content. Here's th
 | {@link module:basic-styles/underline~Underline} | `<u>`, `<* style="text-decoration: underline">` |
 | {@link module:basic-styles/strikethrough~Strikethrough} | `<s>`, `<del>`, `<strike>`, `<* style="text-decoration: line-through">` |
 | {@link module:basic-styles/code~Code} | `<code>`, `<* style="word-wrap: break-word">` |
+| {@link module:basic-styles/subscript~Subscript} | `<sub>`, `<* style="vertical-align: sub">` |
+| {@link module:basic-styles/superscript~Superscript} | `<sup>`, `<* style="vertical-align: super">` |
 
 ## Installation
 
@@ -53,12 +57,14 @@ import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
 import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough';
 import Code from '@ckeditor/ckeditor5-basic-styles/src/code';
+import Subscript from '@ckeditor/ckeditor5-basic-styles/src/subscript';
+import Superscript from '@ckeditor/ckeditor5-basic-styles/src/superscript';
 
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
-		plugins: [ Bold, Italic, Underline, Strikethrough, Code ],
+		plugins: [ Bold, Italic, Underline, Strikethrough, Code, Subscript, Superscript ],
 		image: {
-			toolbar: [ 'bold', 'italic', 'underline', 'strikethrough', 'code'  ]
+			toolbar: [ 'bold', 'italic', 'underline', 'strikethrough', 'code','subscript', 'superscript'  ]
 		}
 	} )
 	.then( ... )

+ 3 - 1
packages/ckeditor5-basic-styles/lang/contexts.json

@@ -3,5 +3,7 @@
 	"Italic": "Toolbar button tooltip for the Italic feature.",
 	"Underline": "Toolbar button tooltip for the Underline feature.",
 	"Code": "Toolbar button tooltip for the Code feature.",
-	"Strikethrough": "Toolbar button tooltip for the Strikethrough feature."
+	"Strikethrough": "Toolbar button tooltip for the Strikethrough feature.",
+	"Subscript": "Toolbar button tooltip for the Subscript feature.",
+	"Superscript": "Toolbar button tooltip for the Superscript feature."
 }

+ 0 - 1
packages/ckeditor5-basic-styles/package.json

@@ -11,7 +11,6 @@
   ],
   "dependencies": {
     "@ckeditor/ckeditor5-core": "^11.0.1",
-    "@ckeditor/ckeditor5-theme-lark": "^11.1.0",
     "@ckeditor/ckeditor5-ui": "^11.1.0"
   },
   "devDependencies": {

+ 36 - 0
packages/ckeditor5-basic-styles/src/subscript.js

@@ -0,0 +1,36 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module basic-styles/subscript
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import SubscriptEditing from './subscript/subscriptediting';
+import SubscriptUI from './subscript/subscriptui';
+
+/**
+ * The subscript feature.
+ *
+ * It loads the {@link module:basic-styles/subscript/subscriptediting~SubscriptEditing} and
+ * {@link module:basic-styles/subscript/subscriptui~SubscriptUI} plugins.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class Subscript extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	static get requires() {
+		return [ SubscriptEditing, SubscriptUI ];
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	static get pluginName() {
+		return 'Subscript';
+	}
+}

+ 49 - 0
packages/ckeditor5-basic-styles/src/subscript/subscriptediting.js

@@ -0,0 +1,49 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module basic-styles/subscript/subscriptediting
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import AttributeCommand from '../attributecommand';
+
+const SUBSCRIPT = 'subscript';
+
+/**
+ * The subscript editing feature.
+ *
+ * It registers the `sub` command and introduces the `sub` attribute in the model which renders to the view
+ * as a `<sub>` element.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class SubscriptEditing extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const editor = this.editor;
+		// Allow sub attribute on text nodes.
+		editor.model.schema.extend( '$text', { allowAttributes: SUBSCRIPT } );
+
+		// Build converter from model to view for data and editing pipelines.
+
+		editor.conversion.attributeToElement( {
+			model: SUBSCRIPT,
+			view: 'sub',
+			upcastAlso: [
+				{
+					styles: {
+						'vertical-align': 'sub'
+					}
+				}
+			]
+		} );
+
+		// Create sub command.
+		editor.commands.add( SUBSCRIPT, new AttributeCommand( editor, SUBSCRIPT ) );
+	}
+}

+ 49 - 0
packages/ckeditor5-basic-styles/src/subscript/subscriptui.js

@@ -0,0 +1,49 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module basic-styles/subscript/subscriptui
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+
+import subscriptIcon from '../../theme/icons/subscript.svg';
+
+const SUBSCRIPT = 'subscript';
+
+/**
+ * The subscript UI feature. It introduces the Subscript button.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class SubscriptUI extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const editor = this.editor;
+		const t = editor.t;
+
+		// Add subscript button to feature components.
+		editor.ui.componentFactory.add( SUBSCRIPT, locale => {
+			const command = editor.commands.get( SUBSCRIPT );
+			const view = new ButtonView( locale );
+
+			view.set( {
+				label: t( 'Subscript' ),
+				icon: subscriptIcon,
+				tooltip: true
+			} );
+
+			view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );
+
+			// Execute command.
+			this.listenTo( view, 'execute', () => editor.execute( SUBSCRIPT ) );
+
+			return view;
+		} );
+	}
+}

+ 36 - 0
packages/ckeditor5-basic-styles/src/superscript.js

@@ -0,0 +1,36 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module basic-styles/superscript
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import SuperscriptEditing from './superscript/superscriptediting';
+import SuperscriptUI from './superscript/superscriptui';
+
+/**
+ * The superscript feature.
+ *
+ * It loads the {@link module:basic-styles/superscript/superscriptediting~SuperscriptEditing} and
+ * {@link module:basic-styles/superscript/superscriptui~SuperscriptUI} plugins.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class Superscript extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	static get requires() {
+		return [ SuperscriptEditing, SuperscriptUI ];
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	static get pluginName() {
+		return 'Superscript';
+	}
+}

+ 49 - 0
packages/ckeditor5-basic-styles/src/superscript/superscriptediting.js

@@ -0,0 +1,49 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module basic-styles/superscript/superscriptediting
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import AttributeCommand from '../attributecommand';
+
+const SUPERSCRIPT = 'superscript';
+
+/**
+ * The superscript editing feature.
+ *
+ * It registers the `super` command and introduces the `super` attribute in the model which renders to the view
+ * as a `<super>` element.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class SuperscriptEditing extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const editor = this.editor;
+		// Allow super attribute on text nodes.
+		editor.model.schema.extend( '$text', { allowAttributes: SUPERSCRIPT } );
+
+		// Build converter from model to view for data and editing pipelines.
+
+		editor.conversion.attributeToElement( {
+			model: SUPERSCRIPT,
+			view: 'sup',
+			upcastAlso: [
+				{
+					styles: {
+						'vertical-align': 'super'
+					}
+				}
+			]
+		} );
+
+		// Create super command.
+		editor.commands.add( SUPERSCRIPT, new AttributeCommand( editor, SUPERSCRIPT ) );
+	}
+}

+ 49 - 0
packages/ckeditor5-basic-styles/src/superscript/superscriptui.js

@@ -0,0 +1,49 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module basic-styles/superscript/superscriptui
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+
+import superscriptIcon from '../../theme/icons/superscript.svg';
+
+const SUPERSCRIPT = 'superscript';
+
+/**
+ * The superscript UI feature. It introduces the Superscript button.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class SuperscriptUI extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const editor = this.editor;
+		const t = editor.t;
+
+		// Add superscript button to feature components.
+		editor.ui.componentFactory.add( SUPERSCRIPT, locale => {
+			const command = editor.commands.get( SUPERSCRIPT );
+			const view = new ButtonView( locale );
+
+			view.set( {
+				label: t( 'Superscript' ),
+				icon: superscriptIcon,
+				tooltip: true
+			} );
+
+			view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );
+
+			// Execute command.
+			this.listenTo( view, 'execute', () => editor.execute( SUPERSCRIPT ) );
+
+			return view;
+		} );
+	}
+}

+ 1 - 1
packages/ckeditor5-basic-styles/tests/manual/basic-styles.html

@@ -1,3 +1,3 @@
 <div id="editor">
-	<p><i>This</i> <s>is</s> <code>an</code> <strong>editor</strong> <u>instance</u>.</p>
+	<p><i>This</i> <s>is</s> <code>an</code> <strong>editor</strong> <u>instance</u>, X<sub>1</sub>, X<sup>2</sup>.</p>
 </div>

+ 4 - 2
packages/ckeditor5-basic-styles/tests/manual/basic-styles.js

@@ -13,11 +13,13 @@ import Italic from '../../src/italic';
 import Strikethrough from '../../src/strikethrough';
 import Underline from '../../src/underline';
 import Code from '../../src/code';
+import Subscript from '../../src/subscript';
+import Superscript from '../../src/Superscript';
 
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
-		plugins: [ Essentials, Paragraph, Bold, Italic, Strikethrough, Underline, Code ],
-		toolbar: [ 'bold', 'italic', 'strikethrough', 'underline', 'code', 'undo', 'redo' ]
+		plugins: [ Essentials, Paragraph, Bold, Italic, Strikethrough, Underline, Code, Subscript, Superscript ],
+		toolbar: [ 'bold', 'italic', 'strikethrough', 'underline', 'code', 'undo', 'redo', 'subscript', 'superscript' ]
 	} )
 	.then( editor => {
 		window.editor = editor;

+ 4 - 2
packages/ckeditor5-basic-styles/tests/manual/basic-styles.md

@@ -5,5 +5,7 @@
   * bold **"editor"**,
   * underline "instance",
   * strikethrough ~~"is"~~,
-  * code `"an"`.
-2. Test the bold, italic, strikethrough, underline and code features live.
+  * code `"an"`,
+  * subscript X<sub>1</sub>,
+  * superscript X<sup>2</sup>.
+2. Test the bold, italic, strikethrough, underline, code, subscript and superscript features live.

+ 18 - 0
packages/ckeditor5-basic-styles/tests/subscript.js

@@ -0,0 +1,18 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import Subscript from '../src/subscript';
+import SubEditing from '../src/subscript/subscriptediting';
+import SubUI from '../src/subscript/subscriptui';
+
+describe( 'Subscript', () => {
+	it( 'should require SubEditing and SubUI', () => {
+		expect( Subscript.requires ).to.deep.equal( [ SubEditing, SubUI ] );
+	} );
+
+	it( 'should be named', () => {
+		expect( Subscript.pluginName ).to.equal( 'Subscript' );
+	} );
+} );

+ 87 - 0
packages/ckeditor5-basic-styles/tests/subscript/subscriptediting.js

@@ -0,0 +1,87 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import SubEditing from '../../src/subscript/subscriptediting';
+
+import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import AttributeCommand from '../../src/attributecommand';
+
+import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
+
+describe( 'SubEditing', () => {
+	let editor, model;
+
+	beforeEach( () => {
+		return VirtualTestEditor
+			.create( {
+				plugins: [ Paragraph, SubEditing ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+			} );
+	} );
+
+	afterEach( () => {
+		return editor.destroy();
+	} );
+
+	it( 'should be loaded', () => {
+		expect( editor.plugins.get( SubEditing ) ).to.be.instanceOf( SubEditing );
+	} );
+
+	it( 'should set proper schema rules', () => {
+		expect( model.schema.checkAttribute( [ '$root', '$block', '$text' ], 'subscript' ) ).to.be.true;
+		expect( model.schema.checkAttribute( [ '$clipboardHolder', '$text' ], 'subscript' ) ).to.be.true;
+	} );
+
+	describe( 'command', () => {
+		it( 'should register subscript command', () => {
+			const command = editor.commands.get( 'subscript' );
+
+			expect( command ).to.be.instanceOf( AttributeCommand );
+			expect( command ).to.have.property( 'attributeKey', 'subscript' );
+		} );
+	} );
+
+	describe( 'data pipeline conversions', () => {
+		it( 'should convert <sub> to sub attribute', () => {
+			editor.setData( '<p><sub>foo</sub>bar</p>' );
+
+			expect( getModelData( model, { withoutSelection: true } ) )
+				.to.equal( '<paragraph><$text subscript="true">foo</$text>bar</paragraph>' );
+
+			expect( editor.getData() ).to.equal( '<p><sub>foo</sub>bar</p>' );
+		} );
+
+		it( 'should convert vertical-align:sub to sub attribute', () => {
+			editor.setData( '<p><span style="vertical-align: sub;">foo</span>bar</p>' );
+
+			expect( getModelData( model, { withoutSelection: true } ) )
+				.to.equal( '<paragraph><$text subscript="true">foo</$text>bar</paragraph>' );
+
+			expect( editor.getData() ).to.equal( '<p><sub>foo</sub>bar</p>' );
+		} );
+
+		it( 'should be integrated with autoparagraphing', () => {
+			editor.setData( '<sub>foo</sub>bar' );
+
+			expect( getModelData( model, { withoutSelection: true } ) )
+				.to.equal( '<paragraph><$text subscript="true">foo</$text>bar</paragraph>' );
+
+			expect( editor.getData() ).to.equal( '<p><sub>foo</sub>bar</p>' );
+		} );
+	} );
+
+	describe( 'editing pipeline conversion', () => {
+		it( 'should convert attribute', () => {
+			setModelData( model, '<paragraph><$text subscript="true">foo</$text>bar</paragraph>' );
+
+			expect( getViewData( editor.editing.view, { withoutSelection: true } ) ).to.equal( '<p><sub>foo</sub>bar</p>' );
+		} );
+	} );
+} );

+ 68 - 0
packages/ckeditor5-basic-styles/tests/subscript/subscriptui.js

@@ -0,0 +1,68 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals document */
+
+import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
+import SubscriptEditing from '../../src/subscript/subscriptediting';
+import SubscriptUI from '../../src/subscript/subscriptui';
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
+
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+
+describe( 'SubscriptUI', () => {
+	let editor, subView;
+
+	testUtils.createSinonSandbox();
+
+	beforeEach( () => {
+		const editorElement = document.createElement( 'div' );
+		document.body.appendChild( editorElement );
+
+		return ClassicTestEditor
+			.create( editorElement, {
+				plugins: [ Paragraph, SubscriptEditing, SubscriptUI ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+
+				subView = editor.ui.componentFactory.create( 'subscript' );
+			} );
+	} );
+
+	afterEach( () => {
+		return editor.destroy();
+	} );
+
+	it( 'should register subscript feature component', () => {
+		expect( subView ).to.be.instanceOf( ButtonView );
+		expect( subView.isOn ).to.be.false;
+		expect( subView.label ).to.equal( 'Subscript' );
+		expect( subView.icon ).to.match( /<svg / );
+	} );
+
+	it( 'should execute subscript command on model execute event', () => {
+		const executeSpy = testUtils.sinon.spy( editor, 'execute' );
+
+		subView.fire( 'execute' );
+
+		sinon.assert.calledOnce( executeSpy );
+		sinon.assert.calledWithExactly( executeSpy, 'subscript' );
+	} );
+
+	it( 'should bind model to subscript command', () => {
+		const command = editor.commands.get( 'subscript' );
+
+		expect( subView.isOn ).to.be.false;
+		expect( subView.isEnabled ).to.be.true;
+
+		command.value = true;
+		expect( subView.isOn ).to.be.true;
+
+		command.isEnabled = false;
+		expect( subView.isEnabled ).to.be.false;
+	} );
+} );

+ 18 - 0
packages/ckeditor5-basic-styles/tests/superscript.js

@@ -0,0 +1,18 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import Superscript from '../src/superscript';
+import SuperEditing from '../src/superscript/superscriptediting';
+import SuperUI from '../src/superscript/superscriptui';
+
+describe( 'Superscript', () => {
+	it( 'should require SuperEditing and SuperUI', () => {
+		expect( Superscript.requires ).to.deep.equal( [ SuperEditing, SuperUI ] );
+	} );
+
+	it( 'should be named', () => {
+		expect( Superscript.pluginName ).to.equal( 'Superscript' );
+	} );
+} );

+ 87 - 0
packages/ckeditor5-basic-styles/tests/superscript/superscriptediting.js

@@ -0,0 +1,87 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import SuperEditing from '../../src/superscript/superscriptediting';
+
+import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import AttributeCommand from '../../src/attributecommand';
+
+import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
+
+describe( 'SuperEditing', () => {
+	let editor, model;
+
+	beforeEach( () => {
+		return VirtualTestEditor
+			.create( {
+				plugins: [ Paragraph, SuperEditing ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+			} );
+	} );
+
+	afterEach( () => {
+		return editor.destroy();
+	} );
+
+	it( 'should be loaded', () => {
+		expect( editor.plugins.get( SuperEditing ) ).to.be.instanceOf( SuperEditing );
+	} );
+
+	it( 'should set proper schema rules', () => {
+		expect( model.schema.checkAttribute( [ '$root', '$block', '$text' ], 'superscript' ) ).to.be.true;
+		expect( model.schema.checkAttribute( [ '$clipboardHolder', '$text' ], 'superscript' ) ).to.be.true;
+	} );
+
+	describe( 'command', () => {
+		it( 'should register superscript command', () => {
+			const command = editor.commands.get( 'superscript' );
+
+			expect( command ).to.be.instanceOf( AttributeCommand );
+			expect( command ).to.have.property( 'attributeKey', 'superscript' );
+		} );
+	} );
+
+	describe( 'data pipeline conversions', () => {
+		it( 'should convert <sup> to superscript attribute', () => {
+			editor.setData( '<p><sup>foo</sup>bar</p>' );
+
+			expect( getModelData( model, { withoutSelection: true } ) )
+				.to.equal( '<paragraph><$text superscript="true">foo</$text>bar</paragraph>' );
+
+			expect( editor.getData() ).to.equal( '<p><sup>foo</sup>bar</p>' );
+		} );
+
+		it( 'should convert vertical-align:super to super attribute', () => {
+			editor.setData( '<p><span style="vertical-align: super;">foo</span>bar</p>' );
+
+			expect( getModelData( model, { withoutSelection: true } ) )
+				.to.equal( '<paragraph><$text superscript="true">foo</$text>bar</paragraph>' );
+
+			expect( editor.getData() ).to.equal( '<p><sup>foo</sup>bar</p>' );
+		} );
+
+		it( 'should be integrated with autoparagraphing', () => {
+			editor.setData( '<sup>foo</sup>bar' );
+
+			expect( getModelData( model, { withoutSelection: true } ) )
+				.to.equal( '<paragraph><$text superscript="true">foo</$text>bar</paragraph>' );
+
+			expect( editor.getData() ).to.equal( '<p><sup>foo</sup>bar</p>' );
+		} );
+	} );
+
+	describe( 'editing pipeline conversion', () => {
+		it( 'should convert attribute', () => {
+			setModelData( model, '<paragraph><$text superscript="true">foo</$text>bar</paragraph>' );
+
+			expect( getViewData( editor.editing.view, { withoutSelection: true } ) ).to.equal( '<p><sup>foo</sup>bar</p>' );
+		} );
+	} );
+} );

+ 68 - 0
packages/ckeditor5-basic-styles/tests/superscript/superscriptui.js

@@ -0,0 +1,68 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals document */
+
+import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
+import SuperscriptEditing from '../../src/superscript/superscriptediting';
+import SuperscriptUI from '../../src/superscript/superscriptui';
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
+
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+
+describe( 'SuperscriptUI', () => {
+	let editor, superView;
+
+	testUtils.createSinonSandbox();
+
+	beforeEach( () => {
+		const editorElement = document.createElement( 'div' );
+		document.body.appendChild( editorElement );
+
+		return ClassicTestEditor
+			.create( editorElement, {
+				plugins: [ Paragraph, SuperscriptEditing, SuperscriptUI ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+
+				superView = editor.ui.componentFactory.create( 'superscript' );
+			} );
+	} );
+
+	afterEach( () => {
+		return editor.destroy();
+	} );
+
+	it( 'should register superscript feature component', () => {
+		expect( superView ).to.be.instanceOf( ButtonView );
+		expect( superView.isOn ).to.be.false;
+		expect( superView.label ).to.equal( 'Superscript' );
+		expect( superView.icon ).to.match( /<svg / );
+	} );
+
+	it( 'should execute superscript command on model execute event', () => {
+		const executeSpy = testUtils.sinon.spy( editor, 'execute' );
+
+		superView.fire( 'execute' );
+
+		sinon.assert.calledOnce( executeSpy );
+		sinon.assert.calledWithExactly( executeSpy, 'superscript' );
+	} );
+
+	it( 'should bind model to superscript command', () => {
+		const command = editor.commands.get( 'superscript' );
+
+		expect( superView.isOn ).to.be.false;
+		expect( superView.isEnabled ).to.be.true;
+
+		command.value = true;
+		expect( superView.isOn ).to.be.true;
+
+		command.isEnabled = false;
+		expect( superView.isEnabled ).to.be.false;
+	} );
+} );

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
packages/ckeditor5-basic-styles/theme/icons/subscript.svg


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
packages/ckeditor5-basic-styles/theme/icons/superscript.svg