Parcourir la source

Merge pull request #2 from ckeditor/t/1

Initial implementation
Szymon Kupś il y a 9 ans
Parent
commit
d6c99a378d

+ 45 - 0
packages/ckeditor5-basic-styles/src/bold.js

@@ -0,0 +1,45 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import Feature from '../feature.js';
+import BoldEngine from './boldengine.js';
+import ButtonController from '../ui/button/button.js';
+import ButtonView from '../ui/button/buttonview.js';
+import Model from '../ui/model.js';
+
+export default class Bold extends Feature {
+	static get requires() {
+		return [ BoldEngine ];
+	}
+
+	init() {
+		const editor = this.editor;
+		const t = editor.t;
+		const command = editor.commands.get( 'bold' );
+
+		// Create button model.
+		const buttonModel = new Model( {
+			isEnabled: true,
+			isOn: false,
+			label: t( 'Bold' ),
+			icon: 'bold',
+			iconAlign: 'LEFT'
+		} );
+
+		// Bind button model to command.
+		buttonModel.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );
+
+		// Execute command.
+		this.listenTo( buttonModel, 'execute', () => editor.execute( 'bold' ) );
+
+		// Add bold button to feature components.
+		editor.ui.featureComponents.add( 'bold', ButtonController, ButtonView, buttonModel );
+
+		// Set the CTRL+B keystroke.
+		editor.keystrokes.set( 'CTRL+B', 'bold' );
+	}
+}

+ 39 - 0
packages/ckeditor5-basic-styles/src/boldengine.js

@@ -0,0 +1,39 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import Feature from '../feature.js';
+import BuildModelConverterFor from '../engine/conversion/model-converter-builder.js';
+import BuildViewConverterFor from '../engine/conversion/view-converter-builder.js';
+import AttributeCommand from '../command/attributecommand.js';
+
+const BOLD = 'bold';
+
+export default class BoldEngine extends Feature {
+	init() {
+		const editor = this.editor;
+		const data = editor.data;
+		const editing = editor.editing;
+
+		// Allow bold attribute on all inline nodes.
+		editor.document.schema.allow( { name: '$inline', attributes: [ BOLD ] } );
+
+		// Build converter from model to view for data and editing pipelines.
+		BuildModelConverterFor( data.modelToView, editing.modelToView )
+			.fromAttribute( BOLD )
+			.toElement( 'strong' );
+
+		// Build converter from view to model for data pipeline.
+		BuildViewConverterFor( data.viewToModel )
+			.fromElement( 'strong' )
+			.fromElement( 'b' )
+			.fromAttribute( 'style', { 'font-weight': 'bold' } )
+			.toAttribute( BOLD, true );
+
+		// Create bold command.
+		editor.commands.set( BOLD, new AttributeCommand( editor, BOLD ) );
+	}
+}

+ 45 - 0
packages/ckeditor5-basic-styles/src/italic.js

@@ -0,0 +1,45 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import Feature from '../feature.js';
+import ItalicEngine from './italicengine.js';
+import ButtonController from '../ui/button/button.js';
+import ButtonView from '../ui/button/buttonview.js';
+import Model from '../ui/model.js';
+
+export default class Italic extends Feature {
+	static get requires() {
+		return [ ItalicEngine ];
+	}
+
+	init() {
+		const editor = this.editor;
+		const t = editor.t;
+		const command = editor.commands.get( 'italic' );
+
+		// Create button model.
+		const buttonModel = new Model( {
+			isEnabled: true,
+			isOn: false,
+			label: t( 'Italic' ),
+			icon: 'italic',
+			iconAlign: 'LEFT'
+		} );
+
+		// Bind button model to command.
+		buttonModel.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );
+
+		// Execute command.
+		this.listenTo( buttonModel, 'execute', () => editor.execute( 'italic' ) );
+
+		// Add bold button to feature components.
+		editor.ui.featureComponents.add( 'italic', ButtonController, ButtonView, buttonModel );
+
+		// Set the CTRL+I keystroke.
+		editor.keystrokes.set( 'CTRL+I', 'italic' );
+	}
+}

+ 39 - 0
packages/ckeditor5-basic-styles/src/italicengine.js

@@ -0,0 +1,39 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import Feature from '../feature.js';
+import BuildModelConverterFor from '../engine/conversion/model-converter-builder.js';
+import BuildViewConverterFor from '../engine/conversion/view-converter-builder.js';
+import AttributeCommand from '../command/attributecommand.js';
+
+const ITALIC = 'italic';
+
+export default class ItalicEngine extends Feature {
+	init() {
+		const editor = this.editor;
+		const data = editor.data;
+		const editing = editor.editing;
+
+		// Allow italic attribute on all inline nodes.
+		editor.document.schema.allow( { name: '$inline', attributes: [ ITALIC ] } );
+
+		// Build converter from model to view for data and editing pipelines.
+		BuildModelConverterFor( data.modelToView, editing.modelToView )
+			.fromAttribute( ITALIC )
+			.toElement( 'em' );
+
+		// Build converter from view to model for data pipeline.
+		BuildViewConverterFor( data.viewToModel )
+			.fromElement( 'em' )
+			.fromElement( 'i' )
+			.fromAttribute( 'style', { 'font-style': 'italic' } )
+			.toAttribute( ITALIC, true );
+
+		// Create italic command.
+		editor.commands.set( ITALIC, new AttributeCommand( editor, ITALIC ) );
+	}
+}

+ 83 - 0
packages/ckeditor5-basic-styles/tests/bold.js

@@ -0,0 +1,83 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import ClassicTestEditor from '/tests/ckeditor5/_utils/classictesteditor.js';
+import Bold from '/ckeditor5/basic-styles/bold.js';
+import BoldEngine from '/ckeditor5/basic-styles/boldengine.js';
+import ButtonController from '/ckeditor5/ui/button/button.js';
+import testUtils from '/tests/ckeditor5/_utils/utils.js';
+import { keyCodes } from '/ckeditor5/utils/keyboard.js';
+
+testUtils.createSinonSandbox();
+
+describe( 'Bold', () => {
+	let editor, boldController;
+
+	beforeEach( () => {
+		const editorElement = document.createElement( 'div' );
+		document.body.appendChild( editorElement );
+
+		return ClassicTestEditor.create( editorElement, {
+				features: [ Bold ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+
+				boldController = editor.ui.featureComponents.create( 'bold' );
+			} );
+	} );
+
+	afterEach( () => {
+		return editor.destroy();
+	} );
+
+	it( 'should be loaded', () => {
+		expect( editor.plugins.get( Bold ) ).to.be.instanceOf( Bold );
+	} );
+
+	it( 'should load BoldEngine', () => {
+		expect( editor.plugins.get( BoldEngine ) ).to.be.instanceOf( BoldEngine );
+	} );
+
+	it( 'should register bold feature component', () => {
+		expect( boldController ).to.be.instanceOf( ButtonController );
+	} );
+
+	it( 'should execute bold command on model execute event', () => {
+		const executeSpy = testUtils.sinon.spy( editor, 'execute' );
+		const model = boldController.model;
+
+		model.fire( 'execute' );
+
+		sinon.assert.calledOnce( executeSpy );
+		sinon.assert.calledWithExactly( executeSpy, 'bold' );
+	} );
+
+	it( 'should bind model to bold command', () => {
+		const model = boldController.model;
+		const command = editor.commands.get( 'bold' );
+
+		expect( model.isOn ).to.be.false;
+
+		expect( model.isEnabled ).to.be.true;
+
+		command.value = true;
+		expect( model.isOn ).to.be.true;
+
+		command.isEnabled = false;
+		expect( model.isEnabled ).to.be.false;
+	} );
+
+	it( 'should set CTRL+B keystroke', () => {
+		const spy = sinon.spy( editor, 'execute' );
+
+		const wasHandled = editor.keystrokes.press( { keyCode: keyCodes.b, ctrlKey: true } );
+
+		expect( wasHandled ).to.be.true;
+		expect( spy.calledOnce ).to.be.true;
+	} );
+} );

+ 80 - 0
packages/ckeditor5-basic-styles/tests/boldengine.js

@@ -0,0 +1,80 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import BoldEngine from '/ckeditor5/basic-styles/boldengine.js';
+import VirtualTestEditor from '/tests/ckeditor5/_utils/virtualtesteditor.js';
+import { getData as getModelData } from '/tests/engine/_utils/model.js';
+import { getData as getViewData } from '/tests/engine/_utils/view.js';
+import AttributeCommand from '/ckeditor5/command/attributecommand.js';
+
+describe( 'BoldEngine', () => {
+	let editor, doc;
+
+	beforeEach( () => {
+		return VirtualTestEditor.create( {
+				features: [ BoldEngine ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+
+				doc = editor.document;
+
+				doc.schema.allow( { name: '$text', inside: '$root' } );
+			} );
+	} );
+
+	it( 'should be loaded', () => {
+		expect( editor.plugins.get( BoldEngine ) ).to.be.instanceOf( BoldEngine );
+	} );
+
+	it( 'should set proper schema rules', () => {
+		expect( doc.schema.check( { name: '$inline', attributes: [ 'bold' ] } ) ).to.be.true;
+	} );
+
+	describe( 'command', () => {
+		it( 'should register bold command', () => {
+			expect( editor.commands.has( 'bold' ) ).to.be.true;
+
+			const command = editor.commands.get( 'bold' );
+
+			expect( command ).to.be.instanceOf( AttributeCommand );
+			expect( command ).to.have.property( 'attributeKey', 'bold' );
+		} );
+	} );
+
+	describe( 'data pipeline conversions', () => {
+		it( 'should convert <strong> to bold attribute', () => {
+			editor.setData( '<strong>foo</strong>bar' );
+
+			expect( getModelData( doc, { withoutSelection: true } ) ).to.equal( '<$text bold=true>foo</$text>bar' );
+			expect( editor.getData() ).to.equal( '<strong>foo</strong>bar' );
+		} );
+
+		it( 'should convert <b> to bold attribute', () => {
+			editor.setData( '<b>foo</b>bar' );
+
+			expect( getModelData( doc, { withoutSelection: true } ) ).to.equal( '<$text bold=true>foo</$text>bar' );
+			expect( editor.getData() ).to.equal( '<strong>foo</strong>bar' );
+		} );
+
+		it( 'should convert font-weight:bold to bold attribute', () => {
+			editor.setData( '<span style="font-weight: bold;">foo</span>bar' );
+
+			expect( getModelData( doc, { withoutSelection: true } ) ).to.equal( '<$text bold=true>foo</$text>bar' );
+			expect( editor.getData() ).to.equal( '<strong>foo</strong>bar' );
+		} );
+	} );
+
+	describe( 'editing pipeline conversion', () => {
+		it( 'should convert paragraph', () => {
+			// Workaround for setting model data: https://github.com/ckeditor/ckeditor5-engine/issues/455
+			editor.setData( '<strong>foo</strong>bar' );
+
+			expect( getViewData( editor.editing.view, { withoutSelection: true } ) ).to.equal( '<strong>foo</strong>bar' );
+		} );
+	} );
+} );

+ 83 - 0
packages/ckeditor5-basic-styles/tests/italic.js

@@ -0,0 +1,83 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import ClassicTestEditor from '/tests/ckeditor5/_utils/classictesteditor.js';
+import Italic from '/ckeditor5/basic-styles/italic.js';
+import ItalicEngine from '/ckeditor5/basic-styles/italicengine.js';
+import ButtonController from '/ckeditor5/ui/button/button.js';
+import testUtils from '/tests/ckeditor5/_utils/utils.js';
+import { keyCodes } from '/ckeditor5/utils/keyboard.js';
+
+testUtils.createSinonSandbox();
+
+describe( 'Italic', () => {
+	let editor, italicController;
+
+	beforeEach( () => {
+		const editorElement = document.createElement( 'div' );
+		document.body.appendChild( editorElement );
+
+		return ClassicTestEditor.create( editorElement, {
+				features: [ Italic ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+
+				italicController = editor.ui.featureComponents.create( 'italic' );
+			} );
+	} );
+
+	afterEach( () => {
+		return editor.destroy();
+	} );
+
+	it( 'should be loaded', () => {
+		expect( editor.plugins.get( Italic ) ).to.be.instanceOf( Italic );
+	} );
+
+	it( 'should load ItalicEngine', () => {
+		expect( editor.plugins.get( ItalicEngine ) ).to.be.instanceOf( ItalicEngine );
+	} );
+
+	it( 'should register italic feature component', () => {
+		expect( italicController ).to.be.instanceOf( ButtonController );
+	} );
+
+	it( 'should execute italic command on model execute event', () => {
+		const executeSpy = testUtils.sinon.spy( editor, 'execute' );
+		const model = italicController.model;
+
+		model.fire( 'execute' );
+
+		sinon.assert.calledOnce( executeSpy );
+		sinon.assert.calledWithExactly( executeSpy, 'italic' );
+	} );
+
+	it( 'should bind model to italic command', () => {
+		const model = italicController.model;
+		const command = editor.commands.get( 'italic' );
+
+		expect( model.isOn ).to.be.false;
+
+		expect( model.isEnabled ).to.be.true;
+
+		command.value = true;
+		expect( model.isOn ).to.be.true;
+
+		command.isEnabled = false;
+		expect( model.isEnabled ).to.be.false;
+	} );
+
+	it( 'should set CTRL+I keystroke', () => {
+		const spy = sinon.spy( editor, 'execute' );
+
+		const wasHandled = editor.keystrokes.press( { keyCode: keyCodes.i, ctrlKey: true } );
+
+		expect( wasHandled ).to.be.true;
+		expect( spy.calledOnce ).to.be.true;
+	} );
+} );

+ 80 - 0
packages/ckeditor5-basic-styles/tests/italicengine.js

@@ -0,0 +1,80 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import ItalicEngine from '/ckeditor5/basic-styles/italicengine.js';
+import VirtualTestEditor from '/tests/ckeditor5/_utils/virtualtesteditor.js';
+import { getData as getModelData } from '/tests/engine/_utils/model.js';
+import { getData as getViewData } from '/tests/engine/_utils/view.js';
+import AttributeCommand from '/ckeditor5/command/attributecommand.js';
+
+describe( 'ItalicEngine', () => {
+	let editor, doc;
+
+	beforeEach( () => {
+		return VirtualTestEditor.create( {
+				features: [ ItalicEngine ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+
+				doc = editor.document;
+
+				doc.schema.allow( { name: '$text', inside: '$root' } );
+			} );
+	} );
+
+	it( 'should be loaded', () => {
+		expect( editor.plugins.get( ItalicEngine ) ).to.be.instanceOf( ItalicEngine );
+	} );
+
+	it( 'should set proper schema rules', () => {
+		expect( doc.schema.check( { name: '$inline', attributes: [ 'italic' ] } ) ).to.be.true;
+	} );
+
+	describe( 'command', () => {
+		it( 'should register italic command', () => {
+			expect( editor.commands.has( 'italic' ) ).to.be.true;
+
+			const command = editor.commands.get( 'italic' );
+
+			expect( command ).to.be.instanceOf( AttributeCommand );
+			expect( command ).to.have.property( 'attributeKey', 'italic' );
+		} );
+	} );
+
+	describe( 'data pipeline conversions', () => {
+		it( 'should convert <em> to italic attribute', () => {
+			editor.setData( '<em>foo</em>bar' );
+
+			expect( getModelData( doc, { withoutSelection: true } ) ).to.equal( '<$text italic=true>foo</$text>bar' );
+			expect( editor.getData() ).to.equal( '<em>foo</em>bar' );
+		} );
+
+		it( 'should convert <i> to italic attribute', () => {
+			editor.setData( '<i>foo</i>bar' );
+
+			expect( getModelData( doc, { withoutSelection: true } ) ).to.equal( '<$text italic=true>foo</$text>bar' );
+			expect( editor.getData() ).to.equal( '<em>foo</em>bar' );
+		} );
+
+		it( 'should convert font-weight:italic to italic attribute', () => {
+			editor.setData( '<span style="font-style: italic;">foo</span>bar' );
+
+			expect( getModelData( doc, { withoutSelection: true } ) ).to.equal( '<$text italic=true>foo</$text>bar' );
+			expect( editor.getData() ).to.equal( '<em>foo</em>bar' );
+		} );
+	} );
+
+	describe( 'editing pipeline conversion', () => {
+		it( 'should convert paragraph', () => {
+			// Workaround for setting model data: https://github.com/ckeditor/ckeditor5-engine/issues/455
+			editor.setData( '<em>foo</em>bar' );
+
+			expect( getViewData( editor.editing.view, { withoutSelection: true } ) ).to.equal( '<em>foo</em>bar' );
+		} );
+	} );
+} );

+ 7 - 0
packages/ckeditor5-basic-styles/tests/manual/basic-styles.html

@@ -0,0 +1,7 @@
+<head>
+	<link rel="stylesheet" href="%APPS_DIR%ckeditor/build/amd/theme/ckeditor.css">
+</head>
+
+<div id="editor">
+	<p><em>This</em> is an <strong>editor</strong> instance.</p>
+</div>

+ 21 - 0
packages/ckeditor5-basic-styles/tests/manual/basic-styles.js

@@ -0,0 +1,21 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* global console:false */
+
+'use strict';
+
+import ClassicEditor from '/ckeditor5/creator-classic/classic.js';
+
+ClassicEditor.create( document.querySelector( '#editor' ), {
+	features: [ 'delete', 'enter', 'typing', 'paragraph', 'undo', 'basic-styles/bold', 'basic-styles/italic' ],
+	toolbar: [ 'bold', 'italic', 'undo', 'redo' ]
+} )
+.then( editor => {
+	window.editor = editor;
+} )
+.catch( err => {
+	console.error( err.stack );
+} );

+ 8 - 0
packages/ckeditor5-basic-styles/tests/manual/basic-styles.md

@@ -0,0 +1,8 @@
+@bender-ui: collapsed
+
+## Basic styles
+
+1. The data should be loaded with:
+  * italic "This",
+  * bold "editor".
+2. Test the bold and italic features live.

Fichier diff supprimé car celui-ci est trop grand
+ 9 - 0
packages/ckeditor5-basic-styles/theme/icons/bold.svg


+ 14 - 0
packages/ckeditor5-basic-styles/theme/icons/italic.svg

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
+    <!-- Generator: Sketch 3.5.2 (25235) - http://www.bohemiancoding.com/sketch -->
+    <title>italic</title>
+    <desc>Created with Sketch.</desc>
+    <defs></defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
+        <g id="italic" sketch:type="MSArtboardGroup" fill="#454545">
+            <g id="icon:italic" sketch:type="MSLayerGroup" transform="translate(5.000000, 3.000000)">
+                <path d="M8.82538319,0.9140625 L8.6985333,1.47220203 C8.52376146,1.47783984 8.29543393,1.50320956 8.01354387,1.54831197 C7.73165381,1.59341438 7.52305829,1.63569726 7.38775106,1.67516187 C7.1509634,1.74845328 6.9818319,1.86120762 6.88035148,2.01342825 C6.77887106,2.16564888 6.70558074,2.33196153 6.66047833,2.51237117 L4.63088002,11.2819272 C4.61960442,11.3213918 4.61114784,11.3664935 4.60551004,11.4172337 C4.59987224,11.467974 4.59705338,11.5130757 4.59705338,11.5525403 C4.59705338,11.6822097 4.62524197,11.7921452 4.68161998,11.88235 C4.73799799,11.9725548 4.83947689,12.0514829 4.98605973,12.1191365 C5.07062674,12.1586011 5.2566714,12.2051123 5.54419926,12.2586714 C5.83172712,12.3122305 6.04596036,12.3446474 6.18690539,12.355923 L6.0600555,12.9140625 L0.65625,12.9140625 L0.783099894,12.355923 C0.94095833,12.3446474 1.166467,12.3277342 1.45963266,12.305183 C1.75279833,12.2826318 1.96139385,12.2488055 2.08542548,12.2037031 C2.30529973,12.1247739 2.47161237,12.0162478 2.58436839,11.8781217 C2.69712442,11.7399956 2.77323359,11.5722735 2.8126982,11.3749504 L4.83383985,2.59693776 C4.84511545,2.54619755 4.85357203,2.4954581 4.85920983,2.44471789 C4.86484763,2.39397768 4.86766649,2.34323823 4.86766649,2.29249802 C4.86766649,2.17974199 4.84370619,2.08108195 4.79578488,1.99651493 C4.74786357,1.91194791 4.6477941,1.83583874 4.49557347,1.76818512 C4.34335283,1.70053151 4.13616674,1.63710719 3.87400899,1.57791028 C3.61185123,1.51871337 3.41875943,1.48347764 3.2947278,1.47220203 L3.4215777,0.9140625 L8.82538319,0.9140625 Z" id="I" sketch:type="MSShapeGroup"></path>
+            </g>
+        </g>
+    </g>
+</svg>

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff