8
0
Просмотр исходного кода

Merge pull request #152 from ckeditor/t/135

T/135: Implement a creator with sticky toolbar.
Piotrek Koszuliński 9 лет назад
Родитель
Сommit
e14e3f8ccc

+ 6 - 2
dev/tasks/build/utils.js

@@ -448,8 +448,12 @@ require( [ 'tests' ], bender.defer(), function( err ) {
 		function renderThemeFromEntryPoints( callback ) {
 			gutil.log( `Compiling '${ gutil.colors.cyan( fileName ) }' from ${ gutil.colors.cyan( paths.length ) } entry points...` );
 
-			// Note: Make sure windows\\style\\paths are preserved.
-			const dataToRender = paths.map( p => `@import "${ p.replace( /\\/g, '\\\\' ) }";` )
+			// Sort to make sure theme is the very first SASS to build. Otherwise,
+			// packages using mixins and variables from that theme will throw errors
+			// because such are not available at this stage of compilation.
+			const dataToRender = paths.sort( a => -a.indexOf( 'ckeditor5-theme' ) )
+				// Make sure windows\\style\\paths are preserved.
+				.map( p => `@import "${ p.replace( /\\/g, '\\\\' ) }";` )
 				.join( '\n' );
 
 			try {

+ 2 - 1
dev/tasks/test/tasks.js

@@ -85,7 +85,8 @@ module.exports = () => {
 			const src = [
 				...benderSrc,
 				'!build/cjs/tests/{ui,ui-*}/**/*.js',
-				'!build/cjs/tests/theme-*/**/*.js'
+				'!build/cjs/tests/theme-*/**/*.js',
+				'!build/cjs/tests/creator-*/**/*.js'
 			];
 
 			return gulp.src( src )

+ 8 - 6
dev/tests/build/utils.js

@@ -289,7 +289,7 @@ describe( 'build-utils', () => {
 					contents: new Buffer( 'foo()' )
 				} ) );
 			} );
-			
+
 			it( 'should process test file in cjs format', ( done ) => {
 				const buildDir = 'build/';
 				const formats = [ 'cjs' ];
@@ -677,12 +677,12 @@ describe( 'build-utils', () => {
 				const files = [
 					new Vinyl( {
 						cwd: './',
-						path: 'foo/bar/theme.scss',
+						path: 'aaa/aaa/theme.scss',
 						contents: new Buffer( '' )
 					} ),
 					new Vinyl( {
 						cwd: './',
-						path: 'baz/qux/theme.scss',
+						path: 'zzz/ckeditor5-theme-quz/theme.scss',
 						contents: new Buffer( '' )
 					} ),
 					new Vinyl( {
@@ -721,9 +721,11 @@ describe( 'build-utils', () => {
 				}, () => {
 					expect( compiledThemePath ).to.be.equal( 'abc.css' );
 					expect( compiledThemeCss.toString() ).to.be.equal(
-`/*! C:\\win\\dows\\theme.scss */
-/*! baz/qux/theme.scss */
-/*! foo/bar/theme.scss */
+// Note: Order matters. The first one should be ckeditor5-theme-* in order
+// to provide necessary dependencies (mixins, vars) for the following files.
+`/*! zzz/ckeditor5-theme-quz/theme.scss */
+/*! aaa/aaa/theme.scss */
+/*! C:\\win\\dows\\theme.scss */
 ` );
 
 					done();

+ 2 - 2
package.json

@@ -8,6 +8,7 @@
     "WYSIWYG"
   ],
   "dependencies": {
+    "ckeditor5-creator-classic": "ckeditor/ckeditor5-creator-classic",
     "ckeditor5-delete": "ckeditor/ckeditor5-delete",
     "ckeditor5-engine": "ckeditor/ckeditor5-engine",
     "ckeditor5-enter": "ckeditor/ckeditor5-enter",
@@ -47,7 +48,6 @@
     "gulp-plumber": "^1.1.0",
     "gulp-rename": "^1.2.2",
     "gulp-replace": "^0.5.4",
-    "gulp-sass": "^2.2.0",
     "gulp-sourcemaps": "^1.6.0",
     "gulp-svg-sprite": "^1.2.19",
     "gulp-util": "^3.0.7",
@@ -64,7 +64,7 @@
     "mockery": "^1.4.0",
     "multipipe": "^0.3.0",
     "ncp": "^2.0.0",
-    "node-sass": "^3.4.2",
+    "node-sass": "^3.7.0",
     "replace": "^0.3.0",
     "run-sequence": "^1.1.5",
     "semver": "^5.1.0",

+ 0 - 38
tests/_utils/ui/boxededitorui/boxededitorui.js

@@ -1,38 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import EditorUI from '/ckeditor5/ui/editorui/editorui.js';
-import ControllerCollection from '/ckeditor5/ui/controllercollection.js';
-
-export default class BoxedEditorUI extends EditorUI {
-	constructor( editor ) {
-		super( editor );
-
-		this.collections.add( new ControllerCollection( 'top' ) );
-		this.collections.add( new ControllerCollection( 'editable' ) );
-
-		const config = editor.config;
-
-		/**
-		 * @property {Number} width
-		 */
-		this.set( 'width', config.get( 'ui.width' ) );
-
-		/**
-		 * @property {Number} height
-		 */
-		this.set( 'height', config.get( 'ui.height' ) );
-	}
-
-	/**
-	 * @readonly
-	 * @property {Model} viewModel
-	 */
-	get viewModel() {
-		return this;
-	}
-}

+ 0 - 40
tests/_utils/ui/boxededitorui/boxededitoruiview.js

@@ -1,40 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import EditorUIView from '/ckeditor5/ui/editorui/editoruiview.js';
-
-export default class BoxedEditorUIView extends EditorUIView {
-	constructor( model, locale ) {
-		super( model, locale );
-
-		this.template = {
-			tag: 'div',
-
-			attributes: {
-				class: 'ck-reset ck-editor'
-			},
-
-			children: [
-				{
-					tag: 'div',
-					attributes: {
-						class: 'ck-editor-top ck-reset-all'
-					}
-				},
-				{
-					tag: 'div',
-					attributes: {
-						class: 'ck-editor-editable'
-					}
-				}
-			]
-		};
-
-		this.register( 'top', '.ck-editor-top' );
-		this.register( 'editable', '.ck-editor-editable' );
-	}
-}

+ 0 - 16
tests/_utils/ui/editableui/framed/framededitableui.js

@@ -1,16 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import EditableUI from '/ckeditor5/ui/editableui/editableui.js';
-
-export default class FramedEditableUI extends EditableUI {
-	constructor( editor, editableModel ) {
-		super( editor, editableModel );
-
-		this.viewModel.bind( 'width', 'height' ).to( editor.ui );
-	}
-}

+ 28 - 0
tests/_utils/ui/editableui/framed/framededitableuiiframe.js

@@ -0,0 +1,28 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import EditableUI from '/ckeditor5/ui/editableui/editableui.js';
+
+/**
+ * The basic implementation of an iframe-based {@link ui.editableUI.EditableUI}.
+ *
+ * @memberOf ui.editableUI.iframe
+ * @extends ui.editableUI.EditableUI
+ */
+export default class FramedEditableUIIframe extends EditableUI {
+	/**
+	 * Creates a new instance of the iframe–based {@link ui.editableUI.EditableUI EditableUI}.
+	 *
+	 * @param {ckeditor5.Editor} editor The editor instance.
+	 * @param {utils.Observable} editableModel The model for the editable.
+	 */
+	constructor( editor, editableModel ) {
+		super( editor, editableModel );
+
+		this.viewModel.bind( 'width', 'height' ).to( editor.ui );
+	}
+}

+ 104 - 0
tests/_utils/ui/editableui/framed/framededitableuiiframeview.js

@@ -0,0 +1,104 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import IframeView from '/ckeditor5/ui/iframe/iframeview.js';
+import FramedEditableUIView from './framededitableuiview.js';
+
+/**
+ * The basic implementation of an {@link ui.iframe.IframeView IframeView}-based
+ * {@link ui.editableUI.EditableUIView}.
+ *
+ * @memberOf ui.editableUI.iframe
+ * @extends ui.iframe.IframeView
+ */
+export default class FramedEditableUIIframeView extends IframeView {
+	/**
+	 * Creates a new instance of the {@link ui.iframe.IframeView IframeView}–based
+	 * {@link ui.editableUI.EditableUIView EditableUIView}.
+	 *
+	 * @param {utils.Observable} [model] (View)Model of this View.
+	 * @param {utils.Locale} [locale] The {@link ckeditor5.Editor#locale editor's locale} instance.
+	 */
+	constructor( model, locale ) {
+		super( model, locale );
+
+		const bind = this.attributeBinder;
+
+		this.template.attributes.class.push( 'ck-editor__editable-iframe' );
+		this.template.attributes.style = [
+			'width:',
+			bind.to( 'width', ( w ) => `${w}px` ),
+			';',
+			'height:',
+			bind.to( 'height', ( h ) => `${h}px`  )
+		];
+
+		this.on( 'loaded', this._iframeLoaded, this );
+
+		/**
+		 * A view which represents the editable `<body>` element within the iframe.
+		 *
+		 * @private
+		 * @member {FramedEditableUIView} ui.editableUI.iframe#_innerView
+		 */
+	}
+
+	/**
+	 * This getter exposes the {@link ui.editable.EditableUIView#editableElement}. It points to the
+	 * `<body>` inside the `<iframe>` document, which is provided by `FramedEditableUIView`.
+	 */
+	get editableElement() {
+		return this._innerView.editableElement;
+	}
+
+	/**
+	 * Destroys the View instance and child {@link _innerView}.
+	 */
+	destroy() {
+		super.destroy();
+
+		return this._innerView.destroy();
+	}
+
+	/**
+	 * When the iframe is loaded, it creates a child view out of <body> element
+	 * and initializes it. Element of this view is exposed through {@link editableElement}.
+	 *
+	 * @protected
+	 */
+	_iframeLoaded() {
+		this._innerView = new FramedEditableUIView(
+			this.model,
+			this.locale,
+			this.element.contentDocument.body
+		);
+
+		this._innerView.init();
+
+		this._iframeDeferred.resolve();
+	}
+}
+
+/**
+ * The view model interface for FramedEditableUIView.
+ *
+ * @memberOf ui.editableUI.iframe
+ * @interface FramedEditableUIViewModel
+ * @mixes utils.ObservableMixin
+ */
+
+/**
+ * The width of the iframe.
+ *
+ * @member {Number} ui.editableUI.iframe.FramedEditableUIViewModel#width
+ */
+
+/**
+ * The height of the iframe.
+ *
+ * @member {Number} ui.editableUI.iframe.FramedEditableUIViewModel#height
+ */

+ 3 - 42
tests/_utils/ui/editableui/framed/framededitableuiview.js

@@ -8,48 +8,9 @@
 import EditableUIView from '/ckeditor5/ui/editableui/editableuiview.js';
 
 export default class FramedEditableUIView extends EditableUIView {
-	constructor( model, locale ) {
-		super( model, locale );
+	constructor( model, locale, editableElement ) {
+		super( model, locale, editableElement );
 
-		const bind = this.attributeBinder;
-
-		// Here's the tricky part - we must return the promise from init()
-		// because iframe loading may be asynchronous. However, we can't start
-		// listening to 'load' in init(), because at this point the element is already in the DOM
-		// and the 'load' event might already be fired.
-		// So here we store both - the promise and the deferred object so we're able to resolve
-		// the promise in _iframeLoaded.
-		this._iframePromise = new Promise( ( resolve, reject ) => {
-			this._iframeDeferred = { resolve, reject };
-		} );
-
-		this.template = {
-			tag: 'iframe',
-			attributes: {
-				class: [ 'ck-framededitable ck-reset-all' ],
-				// It seems that we need to allow scripts in order to be able to listen to events.
-				// TODO: Research that. Perhaps the src must be set?
-				sandbox: 'allow-same-origin allow-scripts',
-				width: bind.to( 'width' ),
-				height: bind.to( 'height' )
-			},
-			on: {
-				load: 'loaded'
-			}
-		};
-
-		this.on( 'loaded', this._iframeLoaded, this );
-	}
-
-	init() {
-		super.init();
-
-		return this._iframePromise;
-	}
-
-	_iframeLoaded() {
-		this.setEditableElement( this.element.contentDocument.body );
-
-		this._iframeDeferred.resolve();
+		this.template.attributes.class.push( 'ck-editor__editable_framed' );
 	}
 }

+ 0 - 39
tests/_utils/ui/editableui/inline/inlineeditableuiview.js

@@ -1,39 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import EditableUIView from '/ckeditor5/ui/editableui/editableuiview.js';
-
-export default class InlineEditableView extends EditableUIView {
-	constructor( model, locale, editableElement ) {
-		super( model, locale );
-
-		if ( editableElement ) {
-			this.element = editableElement;
-		} else {
-			const bind = this.attributeBinder;
-
-			this.template = {
-				tag: 'div',
-				attributes: {
-					contentEditable: bind.to( 'isEditable' )
-				}
-			};
-		}
-	}
-
-	init() {
-		this.setEditableElement( this.element );
-
-		super.init();
-	}
-
-	destroy() {
-		super.destroy();
-
-		this.editableElement.contentEditable = false;
-	}
-}

+ 3 - 2
tests/creator/manual/_utils/creator/inlinecreator.js

@@ -15,11 +15,12 @@ import { createEditableUI, createEditorUI } from '/ckeditor5/ui/creator-utils.js
 import EditorUIView from '/ckeditor5/ui/editorui/editoruiview.js';
 import BoxlessEditorUI from '/tests/ckeditor5/_utils/ui/boxlesseditorui/boxlesseditorui.js';
 import EditableUI from '/ckeditor5/ui/editableui/editableui.js';
-import InlineEditableUIView from '/tests/ckeditor5/_utils/ui/editableui/inline/inlineeditableuiview.js';
+import InlineEditableUIView from '/ckeditor5/ui/editableui/inline/inlineeditableuiview.js';
 import Model from '/ckeditor5/ui/model.js';
 import FloatingToolbar from '/tests/ckeditor5/_utils/ui/floatingtoolbar/floatingtoolbar.js';
 import FloatingToolbarView from '/tests/ckeditor5/_utils/ui/floatingtoolbar/floatingtoolbarview.js';
-import { imitateFeatures, imitateDestroyFeatures } from '../imitatefeatures.js';
+
+import { imitateFeatures, imitateDestroyFeatures } from '/ckeditor5/creator-classic/utils/imitatefeatures.js';
 
 export default class InlineCreator extends StandardCreator {
 	constructor( editor ) {

+ 7 - 7
tests/creator/manual/_utils/creator/classiccreator.js → tests/creator/manual/_utils/creator/legacycreator.js

@@ -12,17 +12,17 @@ import Editable from '/ckeditor5/editable.js';
 
 import { createEditableUI, createEditorUI } from '/ckeditor5/ui/creator-utils.js';
 
-import BoxedEditorUI from '/tests/ckeditor5/_utils/ui/boxededitorui/boxededitorui.js';
-import BoxedEditorUIView from '/tests/ckeditor5/_utils/ui/boxededitorui/boxededitoruiview.js';
-import FramedEditableUI from '/tests/ckeditor5/_utils/ui/editableui/framed/framededitableui.js';
-import FramedEditableUIView from '/tests/ckeditor5/_utils/ui/editableui/framed/framededitableuiview.js';
+import BoxedEditorUI from '/ckeditor5/ui/editorui/boxed/boxededitorui.js';
+import BoxedEditorUIView from '/ckeditor5/ui/editorui/boxed/boxededitoruiview.js';
+import FramedEditableUIIframe from '/tests/ckeditor5/_utils/ui/editableui/framed/framededitableuiiframe.js';
+import FramedEditableUIIframeView from '/tests/ckeditor5/_utils/ui/editableui/framed/framededitableuiiframeview.js';
 import Model from '/ckeditor5/ui/model.js';
 import Toolbar from '/ckeditor5/ui/bindings/toolbar.js';
 import ToolbarView from '/ckeditor5/ui/toolbar/toolbarview.js';
 
-import { imitateFeatures, imitateDestroyFeatures } from '../imitatefeatures.js';
+import { imitateFeatures, imitateDestroyFeatures } from '/ckeditor5/creator-classic/utils/imitatefeatures.js';
 
-export default class ClassicCreator extends StandardCreator {
+export default class LegacyCreator extends StandardCreator {
 	constructor( editor ) {
 		super( editor, new HtmlDataProcessor() );
 
@@ -47,7 +47,7 @@ export default class ClassicCreator extends StandardCreator {
 		// UI.
 		this._replaceElement( editor.firstElement, editor.ui.view.element );
 		this._createToolbar();
-		editor.ui.add( 'editable', createEditableUI( editor, editable, FramedEditableUI, FramedEditableUIView ) );
+		editor.ui.add( 'main', createEditableUI( editor, editable, FramedEditableUIIframe, FramedEditableUIIframeView ) );
 
 		// Init.
 		return super.create()

+ 6 - 5
tests/creator/manual/_utils/creator/multicreator.js

@@ -12,14 +12,15 @@ import Editable from '/ckeditor5/editable.js';
 
 import { createEditableUI, createEditorUI } from '/ckeditor5/ui/creator-utils.js';
 
-import BoxedEditorUI from '/tests/ckeditor5/_utils/ui/boxededitorui/boxededitorui.js';
-import BoxedEditorUIView from '/tests/ckeditor5/_utils/ui/boxededitorui/boxededitoruiview.js';
+import BoxedEditorUI from '/ckeditor5/ui/editorui/boxed/boxededitorui.js';
+import BoxedEditorUIView from '/ckeditor5/ui/editorui/boxed/boxededitoruiview.js';
 import EditableUI from '/ckeditor5/ui/editableui/editableui.js';
-import InlineEditableUIView from '/tests/ckeditor5/_utils/ui/editableui/inline/inlineeditableuiview.js';
+import InlineEditableUIView from '/ckeditor5/ui/editableui/inline/inlineeditableuiview.js';
 import Model from '/ckeditor5/ui/model.js';
 import Toolbar from '/ckeditor5/ui/bindings/toolbar.js';
 import ToolbarView from '/ckeditor5/ui/toolbar/toolbarview.js';
-import { imitateFeatures, imitateDestroyFeatures } from '../imitatefeatures.js';
+
+import { imitateFeatures, imitateDestroyFeatures } from '/ckeditor5/creator-classic/utils/imitatefeatures.js';
 
 export default class MultiCreator extends StandardCreator {
 	constructor( editor ) {
@@ -45,7 +46,7 @@ export default class MultiCreator extends StandardCreator {
 		this._createToolbar();
 
 		for ( let editable of editor.editables ) {
-			editor.ui.add( 'editable', createEditableUI( editor, editable, EditableUI, InlineEditableUIView ) );
+			editor.ui.add( 'main', createEditableUI( editor, editable, EditableUI, InlineEditableUIView ) );
 		}
 
 		editor.elements.forEach( ( element ) => {

+ 0 - 59
tests/creator/manual/_utils/imitatefeatures.js

@@ -1,59 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-
-import Model from '/ckeditor5/ui/model.js';
-import Button from '/ckeditor5/ui/button/button.js';
-import ButtonView from '/ckeditor5/ui/button/buttonview.js';
-
-/**
- * Immitates that some features were loaded and did their job.
- *
- * @param {ckeditor5.Editor} editor
- */
-export function imitateFeatures( editor ) {
-	const t = editor.t;
-
-	const boldModel = new Model( {
-		isEnabled: true,
-		isOn: false,
-		label: t( 'Bold' ),
-		icon: 'bold'
-	} );
-
-	boldModel.on( 'execute', () => {
-		/* global console */
-		console.log( 'bold executed' );
-
-		boldModel.isOn = !boldModel.isOn;
-	} );
-
-	editor.ui.featureComponents.add( 'bold', Button, ButtonView, boldModel );
-
-	const italicModel = new Model( {
-		isEnabled: true,
-		isOn: false,
-		label: t( 'Italic' ),
-		icon: 'italic'
-	} );
-
-	italicModel.on( 'execute', () => {
-		/* global console */
-		console.log( 'italic executed' );
-
-		italicModel.isOn = !italicModel.isOn;
-	} );
-
-	editor.ui.featureComponents.add( 'italic', Button, ButtonView, italicModel );
-
-	window.boldModel = boldModel;
-	window.italicModel = italicModel;
-}
-
-export function imitateDestroyFeatures() {
-	delete window.boldModel;
-	delete window.italicModel;
-}

+ 0 - 0
tests/creator/manual/creator-classic.html → tests/creator/manual/creator-legacy.html


+ 2 - 2
tests/creator/manual/creator-classic.js → tests/creator/manual/creator-legacy.js

@@ -8,14 +8,14 @@
 'use strict';
 
 import CKEDITOR from '/ckeditor.js';
-import ClassicCreator from '/tests/ckeditor5/creator/manual/_utils/creator/classiccreator.js';
+import LegacyCreator from '/tests/ckeditor5/creator/manual/_utils/creator/legacycreator.js';
 import testUtils from '/tests/utils/_utils/utils.js';
 
 let editor, editable, observer;
 
 function initEditor() {
 	CKEDITOR.create( '#editor', {
-		creator: ClassicCreator,
+		creator: LegacyCreator,
 		ui: {
 			width: 400,
 			height: 400

+ 0 - 0
tests/creator/manual/creator-classic.md → tests/creator/manual/creator-legacy.md