瀏覽代碼

Merge branch 'master' into t/ckeditor5-image/134

Szymon Kupś 8 年之前
父節點
當前提交
9673d2edac

+ 9 - 9
docs/api/index.md

@@ -7,16 +7,16 @@ Use the navigation tree on the left to navigate through CKEditor API.
 
 ## Popular API pages
 
- * {@link module:core/editor/editorconfig~EditorConfig Configuration Reference} – CKEditor configuration settings explained.
- * {@link module:editor-classic/classiceditor~ClassicEditor `ClassicEditor`} – The entry point for the Classic editor integration.
- * {@link module:editor-inline/inlineeditor~InlineEditor `InlineEditor`} – The entry point for the Inline editor integration.
- * {@link module:editor-balloon/ballooneditor~BalloonEditor `BalloonEditor`} – The entry point for the Balloon editor integration.
- 
-## Documentation 
+* {@link module:core/editor/editorconfig~EditorConfig Configuration Reference} – CKEditor configuration settings explained.
+* {@link module:editor-classic/classiceditor~ClassicEditor `ClassicEditor`} – The entry point for the Classic editor integration.
+* {@link module:editor-inline/inlineeditor~InlineEditor `InlineEditor`} – The entry point for the Inline editor integration.
+* {@link module:editor-balloon/ballooneditor~BalloonEditor `BalloonEditor`} – The entry point for the Balloon editor integration.
 
- * {@link framework/index CKEditor 5 Framework} – Learn how to develop with CKEditor 5 Framework, customize it and create plugins.
- * {@link builds/guides/overview CKEditor 5 Builds} – Learn how to install, integrate and configure CKEditor 5 Builds. More complex aspects, like creating custom builds, are explained here, too.
- * {@link features/index Features} – Learn about some of the features included in CKEditor 5 Builds.
+## Documentation
+
+* {@link framework/index CKEditor 5 Framework} – Learn how to develop with CKEditor 5 Framework, customize it and create plugins.
+* {@link builds/guides/overview CKEditor 5 Builds} – Learn how to install, integrate and configure CKEditor 5 Builds. More complex aspects, like creating custom builds, are explained here, too.
+* {@link features/index Features} – Learn about some of the features included in CKEditor 5 Builds.
 
 ## Contribute
 

二進制
docs/assets/img/framework-architecture-engine-diagram.png


+ 14 - 9
docs/builds/guides/browser-compatibility.md

@@ -1,4 +1,9 @@
 ---
+# Scope:
+# * Explain browser compatibility of CKEditor 5.
+# * Document known compatibility issues and missing features.
+# * Discuss support for mobile environments.
+
 category: builds-guides
 order: 310
 ---
@@ -17,22 +22,22 @@ CKEditor 5 is currently supported on the following desktop browsers:
 * Good support:
 	* Edge (latest stable release). Known issues:
 		* Minor issues with selection: [1](https://github.com/ckeditor/ckeditor5-engine/issues/974), [2](https://github.com/ckeditor/ckeditor5-engine/issues/928).
-		* The editor becomes unstable when F12 tools are enabled.
+		* The editor becomes unstable when F12 developer tools are enabled.
 
-Not yet supported:
+Not supported yet:
 
-* Internet Explorer 11 is not yet supported. See the [Compatibility with IE11](https://github.com/ckeditor/ckeditor5/issues/330) ticket.
+* Internet Explorer 11. See the [Compatibility with IE11](https://github.com/ckeditor/ckeditor5/issues/330) ticket.
 
 ### Notes
 
 Features known to not be fully supported yet:
 
-* Text composition (IME) – Input Method Engine is a mechanism which allows inputting text in languages such as Japanese and Chinese. It's so called "text composition". This mechanism is not yet fully supported and we'll be polishing that feature after 1.0.0.
-* Drag and drop inside editor doesn't work yet. It is possible to drop images from your system if the {@link module:upload/imageupload~ImageUpload} feature is enabled.
+* Text composition. Input Method Engine (IME) is a mechanism that allows the users to input text in languages such as Japanese and Chinese. This mechanism is not fully supported yet and we will be polishing that feature after 1.0.0.
+* Drag and drop inside the editor does not work yet. It is possible to drop images from your system if the {@link module:upload/imageupload~ImageUpload} feature is enabled.
 
 ## Mobile environment
 
-Although CKEditor 5 works on Safari for iOS and Chrome for Android it has not been fully tested yet and there are known bugs and inconveniences. Full support for mobile browsers will be our goal after releasing 1.0.0.
+Although CKEditor 5 works on Safari for iOS and Chrome for Android, it has not been fully tested yet and there are known bugs and inconveniences. Full support for mobile browsers will be our goal after releasing 1.0.0.
 
 When working on mobile support we need to consider two complex aspects:
 
@@ -40,10 +45,10 @@ When working on mobile support we need to consider two complex aspects:
 
 	During the design phase we understood that creating a responsive and touch-friendly UI will not guarantee a desired UX level by itself. Also, that the "mobile first" approach has no application in this case due to constraints of the mobile environment and specific editing method. Therefore, we plan to introduce a completely customized, mobile-oriented UI.
 
-	We begun research on how to display necessary UI controls on the screen and, sadly, it turned out that mobile Safari's viewport mechanics makes it extremely complicated to display the UI in a reliable way. You can read more in the [UX: Mobile editing](https://github.com/ckeditor/ckeditor5-design/issues/149) ticket.
+	We began research on how to display necessary UI controls on the screen and, sadly, it turned out that mobile Safari's viewport mechanics makes it extremely complicated to display the UI in a reliable way. You can read more in the [UX: Mobile editing](https://github.com/ckeditor/ckeditor5-design/issues/149) ticket.
 
 * **Handling mobile browsers' quirks.**
 
-	Mobile browsers (especially mobile Safari) work differently than their desktop equivalents. [Chrome's incomplete `keydown` event](https://bugs.chromium.org/p/chromium/issues/detail?id=118639) is just one of issues with which we need to deal with.
+	Mobile browsers (especially mobile Safari) work differently than their desktop equivalents. [Chrome's incomplete `keydown` event](https://bugs.chromium.org/p/chromium/issues/detail?id=118639) is just one of the issues that we need to deal with.
 
-	For several years we've worked with W3C on [fixing contentEditable](https://medium.com/content-uneditable/fixing-contenteditable-1a9a5073c35d) – a technology on which the entire browser-based editing is based. Recently, browser vendors started implementing the core part of [the new specifications](http://w3c.github.io/editing/)  the `beforeinput` event which has a chance to improve the situation. CKEditor 5's architecture was designed with this event in mind, so we will start taking advantage of it as soon as it proves to be stable enough.
+	For several years we have worked with W3C on [fixing `contentEditable`](https://medium.com/content-uneditable/fixing-contenteditable-1a9a5073c35d) — a technology on which the entire browser-based editing is based. Recently, browser vendors started implementing the core part of [the new specifications](http://w3c.github.io/editing/) — the `beforeinput` event which has a chance to improve the situation. CKEditor 5's architecture was designed with this event in mind, so we will start taking advantage of it as soon as it proves to be stable enough.

+ 11 - 11
docs/builds/guides/migrate.md

@@ -10,23 +10,23 @@ order: 260
 
 # Migration from CKEditor 4
 
-When compared to its previous versions, CKEditor 5 should be considered **a totally new editor**. Every single aspect of it was redesigned, from installation, to integration, to features, to its data model, and finally to its API. Therefore, moving applications using a previous version to version 5 cannot be simply called an "upgrade". It is something bigger, so the "migration" term fits better.
+When compared to its predecessor, CKEditor 5 should be considered **a totally new editor**. Every single aspect of it was redesigned — from installation, to integration, to features, to its data model, and finally to its API. Therefore, moving applications using a previous CKEditor version to version 5 cannot be simply called an "upgrade". It is something bigger, so the "migration" term fits better.
 
 There is no "drop in" solution for migrating. In this guide we hope to summarize the most important aspects to be taken into consideration before you proceed with installing CKEditor 5.
 
-Before starting, be sure that migrating is your best choice. Check {@link builds/guides/overview#When-NOT-to-use-builds When NOT to use CKEditor 5 Builds?}
+Before starting, be sure that migrating is your best choice. Refer to {@link builds/guides/overview#When-NOT-to-use-builds When NOT to use CKEditor 5 Builds?} for more information.
 
 ## Installation and integration
 
-The very first aspect that changed with CKEditor 5 is its installation procedure. It became much more modern with introduction of modular patterns, UMD, npm, etc. Check {@link builds/guides/integration/installation Installation} for more details.
+The very first aspect that changed with CKEditor 5 is its installation procedure. It became much more modern with the introduction of modular patterns, UMD, npm, etc. Check {@link builds/guides/integration/installation Installation} for more details.
 
 The API for integrating CKEditor with your pages also changed. It is worth checking {@link builds/guides/integration/basic-api Basic API} for an introduction.
 
 ## Features
 
-When it comes to features, there are two aspects to be taken into consideration:
+When it comes to features, there are two aspects that need to be taken into consideration:
 
-* CKEditor 5 may still not have the same features available in CKEditor 4.
+* CKEditor 5 may still not have the same features available as CKEditor 4.
 * Existing features may behave differently.
 
 Therefore, it is worth spending some time analyzing required features.
@@ -34,16 +34,16 @@ Therefore, it is worth spending some time analyzing required features.
 CKEditor 5 was designed with focus on creating quality content. There are thus good reasons for it to not support some old features. You should take this chance to rethink the features available in your application and in turn perhaps switch the approach towards a more modern reasoning.
 
 <info-box>
-Features like fonts, colors and alignment will be introduced in the future, when the new types of builds will be introduced with the purpose of satisfying document editing scenarios.
+Features like fonts, colors and alignment will be added in the future, when new types of builds will be introduced with the purpose of satisfying document editing scenarios.
 </info-box>
 
 <!-- TODO 4 -->
 
 ## Plugins
 
-The trickiest migration challenge to be faced may be related to custom plugins you could have developed for CKEditor 4. Although their concept may stay the same, their implementation is certainly different and will require rewriting them from scratch.
+The trickiest migration challenge to be faced may be related to custom plugins you have developed for CKEditor 4. Although their concept may stay the same, their implementation is certainly different and will require rewriting them from scratch.
 
-The same may apply for third party plugins which may not have been ported to CKEditor 5 yet.
+The same may apply for third-party plugins which may not have been ported to CKEditor 5 yet.
 
 Check the {@link builds/guides/development/plugins#Creating-plugins Creating plugins guide} for more information on the development of plugins.
 
@@ -51,7 +51,7 @@ Check the {@link builds/guides/development/plugins#Creating-plugins Creating plu
 
 In CKEditor 5, the previous concept of "skins" was reviewed and is now called "themes".
 
-If you have custom skins for CKEditor 4, these skins need to be recreated for CKEditor 5. Fortunately custom theming in CKEditor 5 is much more powerful and simpler than before.
+If you have custom skins for CKEditor 4, these skins need to be recreated for CKEditor 5. Fortunately {@link framework/guides/theme-customization custom theming} in CKEditor 5 is much more powerful and simpler than before.
 
 <!--
 For more information, check how to {@linkTODO create new themes in the CKEditor 5 Framework documentation}.
@@ -59,6 +59,6 @@ For more information, check how to {@linkTODO create new themes in the CKEditor
 
 ## Existing data
 
-An extremely important aspect to be remembered is that &mdash; because of the difference in features &mdash; the data produced with CKEditor 4 may not be compatible with CKEditor 5.
+An extremely important aspect to be remembered is that &mdash; because of the difference in features &mdash; the **data produced with CKEditor 4 may not be compatible with CKEditor 5**.
 
-Extensive analysis, data verification and tests should be performed on existing data. If necessary, conversion procedures should be developed to avoid data loss. A relatively simple yet efficient strategy of adopting CKEditor 5 into existing systems might be using CKEditor 5 for creating new content and the old editor for editing legacy content.
+Extensive analysis, data verification and tests should be performed on existing data. If necessary, you will need to develop conversion procedures to avoid data loss. A relatively simple yet efficient strategy of adopting CKEditor 5 into existing systems might be using CKEditor 5 for creating new content and the old editor for editing legacy content.

+ 2 - 3
docs/builds/guides/reporting-issues.md

@@ -24,7 +24,6 @@ Most of the issues are reproducible on the demo. If you have a different case th
 
 All issues should be reported in the [CKEditor 5 repositories](https://github.com/ckeditor?q=ckeditor5) on GitHub.
 
-Issues related to builds are usually caused by issues in the CKEditor 5 Framework components and plugins included in the build. You may report issues directly into the repositories that you think are related to them (like plugins) but, if you are unsure, the [`ckeditor5` issues page](https://github.com/ckeditor/ckeditor5/issues) should be used as the fallback place for any issue. The CKEditor 5 team will then take steps to move the issue to the right place or give you further instructions, if necessary.
-
-Issues with third party plugins should be reported directly to their developers.
+Issues related to builds are usually caused by issues in the CKEditor 5 Framework components and plugins included in the build. You may report issues directly into the repositories that you think are related to them (like plugins) but, if you are unsure, the [`ckeditor5` issues page](https://github.com/ckeditor/ckeditor5/issues) should be used as the fallback place for any issue. The CKEditor 5 team will then move the issue to the right place or give you further instructions, if necessary.
 
+Issues with third-party plugins should be reported directly to their developers.

+ 359 - 0
docs/framework/guides/architecture/intro.md

@@ -0,0 +1,359 @@
+---
+category: framework-architecture
+order: 10
+---
+
+# Introduction
+
+In this guide we will try to introduce all the most important parts of CKEditor 5's architecture. We assume that you have read the {@link framework/guides/overview Framework's overview} and saw some code in the {@link framework/guides/quick-start Quick start} guide. This should help you going through this one.
+
+<info-box>
+	CKEditor 5 reached its first alpha version. This means that it is feature complete and that we consider it stable enough for first production integrations. However, this means that **we are going to introduce many breaking changes** before the final 1.0.0 release. Many code refactorings were scheduled for after 1.0.0 alpha so a lot of API, including critical pieces, will still change. The goal is, in most cases, to simplify the API, so please excuse us some more cumbersome pieces. We will also avoid going too deep into details and creating many code samples, maintaining which would be a nightmare during upcoming code changes.
+</info-box>
+
+When implementing features you will usually work with these three CKEditor 5 packages:
+
+* [`@ckeditor/ckeditor5-core`](https://www.npmjs.com/package/@ckeditor/ckeditor5-core) – the core editor architecture – a couple of core classes and interfaces which glue all the things together.
+* [`@ckeditor/ckeditor5-engine`](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine) – the editing engine. The biggest and by far most complex package, implementing the custom data model, the view layer, conversion mechanisms, rendering engine responsible for [taming `contentEditable`](https://medium.com/content-uneditable/contenteditable-the-good-the-bad-and-the-ugly-261a38555e9c) and a lot more.
+* [`@ckeditor/ckeditor5-ui`](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui) – the standard UI library. Simple MVC implementation which main goal is to best fit CKEditor 5's needs.
+
+<!-- TODO link to package pages once https://github.com/cksource/umberto/issues/303 is resolved -->
+
+So, let's tackle one by one.
+
+## Core editor architecture
+
+The [`@ckeditor/ckeditor5-core`](https://www.npmjs.com/package/@ckeditor/ckeditor5-core) package is relatively simple. It comes with just a handful of classes. We present here the ones you need to know.
+
+### Editor classes
+
+The {@link module:core/editor/editor~Editor} and {@link module:core/editor/standardeditor~StandardEditor} are, respectively, the base editor class and its more typical implementation.
+
+The editor is a root object, gluing all the other components. It holds a couple of properties that you need to know:
+
+* {@link module:core/editor/editor~Editor#config} – the config object,
+* {@link module:core/editor/editor~Editor#plugins} and {@link module:core/editor/editor~Editor#commands} – the collection of loaded plugins and commands,
+* {@link module:core/editor/editor~Editor#document} – the document – the editing engine's entry point,
+* {@link module:core/editor/editor~Editor#data} – the data controller (there's also the {@link module:core/editor/editor~Editor#editing editing controller} but [we plan to merge it](https://github.com/ckeditor/ckeditor5-engine/issues/678) into the data controller) – a set of high-level utils to work on the document,
+* {@link module:core/editor/editor~Editor#keystrokes} – the keystroke handler – allows binding keystrokes to actions.
+
+Besides that, the editor exposes a couple of methods:
+
+* {@link module:core/editor/editor~Editor.create `create()`} – the static `create()` method. Editor constructors are protected and you should create editors using this static method. It allows the initialization process to be asynchronous.
+* {@link module:core/editor/editor~Editor#destroy `destroy()`} – destroys the editor.
+* {@link module:core/editor/editor~Editor#setData `setData()`} and {@link module:core/editor/editor~Editor#getData `getData()`} – a way to retrieve data from the editor and set data in the editor. The data format is controlled by the {@link module:engine/controller/datacontroller~DataController#processor data controller's data processor} and it does not need to be a string (can be e.g. JSON if you would implement such a {@link module:engine/dataprocessor/dataprocessor~DataProcessor data processor}). See e.g. how to {@link features/markdown produce Markdown output}.
+* {@link module:core/editor/editor~Editor#execute `execute()`} – executes the given command.
+
+The editor classes are a base to implement your own editors. CKEditor 5 Framework comes with a couple of editor types (e.g. {@link module:editor-classic/classiceditor~ClassicEditor classic}, {@link module:editor-inline/inlineeditor~InlineEditor inline} and {@link module:editor-balloon/ballooneditor~BalloonEditor balloon}) but you can freely implement editors which work and look completely differently. The only requirement is that you implement the {@link module:core/editor/editor~Editor} and {@link module:core/editor/standardeditor~StandardEditor} interfaces.
+
+<info-box>
+	You are right – mentioned editors are classes, not interfaces. This is a part of API [needs to be improved](https://github.com/ckeditor/ckeditor5/issues/327). Less inheritance, more interfaces and composition. It should also be clear which interfaces feature require to work (at the moment it is half of the `StandardEditor`).
+</info-box>
+
+### Plugins
+
+Plugins are the way to introduce editor features. In CKEditor 5 even {@link module:typing/typing~Typing typing} is a plugin. What's more – the {@link module:typing/typing~Typing} plugin requires {@link module:typing/input~Input} and {@link module:typing/delete~Delete} plugins which are responsible for handling, respectively, methods of inserting text and deleting content. At the same time, a couple of other plugins need to customize <kbd>Backspace</kbd> behavior in certain cases, which is handled by themselves. This leaves the base plugins free of any non-generic knowledge.
+
+Another important aspect of how existing CKEditor 5 plugins are implemented is the split into engine and UI parts. E.g. the {@link module:basic-styles/boldengine~BoldEngine} plugin introduces schema definition, mechanisms rendering `<strong>` tags, commands to apply and remove bold from text, while the {@link module:basic-styles/bold~Bold} plugin adds UI of the feature (i.e. a button). This feature split is meant to allow for greater reuse (one can take the engine part and implement their own UI for a feature) as well as for running CKEditor 5 on the server side. The feature split, though, [is not yet perfect and will be improved](https://github.com/ckeditor/ckeditor5/issues/488).
+
+The tl;dr of this is that:
+
+* every feature is implemented or at least enabled by a plugin,
+* plugins are highly granular,
+* plugins know everything about the editor,
+* plugins should know as little about other plugins as possible.
+
+These are the rules based on which the official plugins were implemented. When implementing your own plugins, if you do not plan to publish them, you can reduce this list to the first point.
+
+After this lengthy introduction (which aimed at making it easier for you to digest the existing plugins), let's talk about the plugin API.
+
+All plugins needs to implement the {@link module:core/plugin~PluginInterface}. The easiest way to do so is by inheriting from the {@link module:core/plugin~Plugin} class. The plugin initialization code should be located in the {@link module:core/plugin~PluginInterface#init `init()`} method (which can return a promise). If some piece of code needs to be executed after other plugins are initialized, you can put it in the {@link module:core/plugin~PluginInterface#afterInit `afterInit()`} method. The dependencies between plugins are implemented using the static {@link module:core/plugin~PluginInterface.requires} property.
+
+```js
+import MyDependency from 'some/other/plugin';
+
+class MyPlugin extends Plugin {
+	static get requires() {
+		return [ MyDependency ];
+	}
+
+	init() {
+		// Initialize your plugin here.
+
+		this.editor; // The editor instance which loaded this plugin.
+	}
+}
+```
+
+You can see how to implement a simple plugin in the {@link framework/guides/quick-start Quick start} guide.
+
+### Commands
+
+A command is combination of an action (a callback) and a state (a set of properties). For instance, the `bold` command applies or removes bold attribute from the selected text. If the text in which the selection is placed has bold applied already, the value of the command is `true`, `false` otherwise. If the `bold` command can be executed on the current selection, it is enabled. If not (because e.g. bold is not allowed in this place), it is disabled.
+
+All commands need to inherit from the {@link module:core/command~Command} class. Commands need to be added to editor's {@link module:core/editor/editor~Editor#commands command collection} so they can be executed by using the {@link module:core/editor/editor~Editor#execute `Editor#execute()`} method.
+
+Let's see an example:
+
+```js
+class MyCommand extends Command {
+	execute( message ) {
+		console.log( message );
+	}
+}
+
+class MyPlugin extends Plugin {
+	init() {
+		const editor = this.editor;
+
+		editor.commands.add( 'myCommand', new MyCommand( editor ) );
+	}
+}
+```
+
+Now, calling `editor.execute( 'myCommand', 'Foo!' )` will log `Foo!` on the console.
+
+To see how a state management of a typical command like `bold` is implemented, let's see pieces of the {@link module:basic-styles/attributecommand~AttributeCommand} class on which `bold` is based.
+
+First thing to notice is the {@link module:core/command~Command#refresh `refresh()`} method:
+
+```js
+refresh() {
+	const doc = this.editor.document;
+
+	this.value = doc.selection.hasAttribute( this.attributeKey );
+	this.isEnabled = doc.schema.checkAttributeInSelection(
+		doc.selection, this.attributeKey
+	);
+}
+```
+
+This method is automatically called (by the command itself) when {@link module:engine/model/document~Document#event:changesDone any changes are applied to the model}. This means that command automatically refreshes its own state when anything changes in the editor.
+
+The important thing about commands is that every change in their state as well as calling the `execute()` method fires an event (e.g. {@link module:core/command~Command#event:change:{attribute} `change:value`} or {@link module:core/command~Command#event:execute `execute`}).
+
+Those events make it possible to control the command from outside. For instance, if you want to disable specific commands when some condition is true (let's say – according to your application's logic, they should be temporarily disabled) and there is no other, cleaner mean to do that, you can block the command manually:
+
+```js
+const command = editor.commands.get( 'someCommand' );
+
+command.on( 'change:isEnabled', forceDisable, { priority: 'lowest' } );
+command.isEanabled = false;
+
+function forceDisabled() {
+	this.isEnabled = false;
+}
+```
+
+Now, the command will be disabled as long as you won't {@link module:utils/emittermixin~EmitterMixin#off off} this listener, regardless of how many times `someCommand.refresh()` is called.
+
+### Event system and observables
+
+CKEditor 5 has an event-based architecture so you can find {@link module:utils/emittermixin~EmitterMixin} and {@link module:utils/observablemixin~ObservableMixin} mixed all over the place. Both mechanisms allow decoupling the code and make it extensible.
+
+Most of the classes which we already mentioned are either emitters or observables (observable is an emitter too). Emitter can emit (fire events) as well as listen to ones.
+
+```js
+class MyPlugin extends Plugin {
+	init() {
+		// Make MyPlugin listen to someCommand#execute.
+		this.listenTo( someCommand, 'execute', () => {
+			console.log( 'someCommand was executed' );
+		} );
+
+		// Make MyPlugin listen to someOtherCommand#execute and block it.
+		// We listen with high priority to block the event before
+		// someOtherCommand's execute() method is called.
+		this.listenTo( someOtherCommand, 'execute', ( evt ) => {
+			evt.stop();
+		}, { priority: 'high' } );
+	}
+
+	// Inherited from Plugin:
+	destroy() {
+		// Removes all listeners added with this.listenTo();
+		this.stopListening();
+	}
+}
+```
+
+The second listener to `'execute'` shows one of the very common practice in CKEditor 5's code. Basically, the default action of `execute` (which is calling the `execute()` method) is registered as a listener of that event with a default priority. Thanks to that, by listening to the event using `'low'` or `'high'` priorities we can execute some code before or after `execute()` is really called. If we stop the event, then the `execute()` method will not be called at all. In this particular case, the {@link module:core/command~Command#execute `Command#execute()`} method was decorated with the event using the {@link module:utils/observablemixin~ObservableMixin#decorate `ObservableMixin#decorate()`} function:
+
+```js
+import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
+import mix from '@ckeditor/ckeditor5-utils/src/mix';
+
+class Command {
+	constructor() {
+		this.decorate( 'execute' );
+	}
+
+	// Will now fire the #execute event automatically.
+	execute() {}
+}
+
+// Mix ObservableMixin into Command.
+mix( Command, ObservableMixin );
+```
+
+Besides decorating methods with events, the observables allow to observe their chosen properties. For instance, the `Command` class makes its `#value` and `#isEnabled` observable by calling {@link module:utils/observablemixin~ObservableMixin#set `set()`}:
+
+```js
+class Command {
+	constructor() {
+		this.set( 'value', undefined );
+		this.set( 'isEnabled', undefined );
+	}
+}
+
+mix( Command, ObservableMixin );
+
+const command = new Command();
+
+command.on( 'change:value', ( evt, propertyName, newValue, oldValue ) => {
+	console.log(
+		`${ propertyName } has changed from ${ oldValue } to ${ newValue }`
+	);
+} )
+
+command.value = true; // -> 'value has changed from undefined to true'
+```
+
+<info-box>
+	Observable properties are marked in API doc strings with `@observable` keyword but we do not mark them in {@link api/index API docs} ([yet](https://github.com/ckeditor/ckeditor5-dev/issues/285)).
+</info-box>
+
+Observables have one more feature which is widely used by the editor (especially in the UI library) – this is the ability to bind value of one object's property to the value of some other property or properties (of one or more objects). This, of course, can also be processed by callbacks.
+
+Assuming that `target` and `source` are observables and that used properties are observable:
+
+```js
+target.bind( 'foo' ).to( source );
+
+source.foo = 1;
+target.foo; // -> 1
+
+// Or:
+target.bind( 'foo' ).to( source, 'bar' );
+
+source.bar = 1;
+target.foo; // -> 1
+```
+
+You can find more about bindings in the [UI library](#ui-library) section.
+
+## Editing engine
+
+The [`@ckeditor/ckeditor5-engine`](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine) package is by far the biggest package of all. Therefore, we will only scratch here the surface by introducing the main architecture layers and concepts. More detailed guides will follow.
+
+### Overview
+
+The editing engine implements an MVC architecture. The shape of it is not enforced by the engine itself but in most implementations it will create this structure:
+
+[{@img assets/img/framework-architecture-engine-diagram.png Diagram of engine's MVC architecture.}](%BASE_PATH%/assets/img/framework-architecture-engine-diagram.png)
+
+What you can see are three layers – **model**, **controller** and **view**. There is one **model document** which is **converted** to two views – **editing view** and **data view**. These two views represent, respectively, the content that the user is editing (DOM structure that you see in the browser) and the editor input and output data (in a format which the plugged data processor understands). Both views feature virtual DOM structures (custom, DOM-like structures) on which converters and features work and which are then **rendered** to the DOM.
+
+The green blocks are the code introduced by editor features (plugins). So features control what changes are done to the model, how they are converted to the view and how the model needs to be changed based on fired events (view's and model's ones).
+
+Let's now talk about each layer separately.
+
+### Model
+
+The model is implemented by a DOM-like tree structure of {@link module:engine/model/element~Element elements} and {@link module:engine/model/text~Text text nodes}. Like in the DOM, its central point is a {@link module:engine/model/document~Document document} which contains {@link module:engine/model/document~Document#roots root elements} (the model, as well as the view, may have multiple roots). The document also holds its {@link module:engine/model/documentselection~DocumentSelection selection}, {@link module:engine/model/history~History history of changes} and {@link module:engine/model/schema~Schema schema}.
+
+All changes made to the document's structure are done by applying {@link module:engine/model/operation/operation~Operation operations}. The concept of operations comes from [Operational Transformation](https://en.wikipedia.org/wiki/Operational_transformation) (in short: OT), a technology enabling collaboration functionalities. Since OT requires that a system is able to transform every operation by every other one (to figure out the result of concurrently applied operations), the set of operations needs to be small. CKEditor 5 features a non-linear model (normally, OT implementations use flat, array-like models while CKEditor 5 uses a tree structure) hence, the set of potential semantic changes is more complex. To handle that, the editing engine implements a small set of operations (6 to be precise) and a bigger set of {@link module:engine/model/delta/delta~Delta "deltas"} – groups of operations with additional semantics attached (there are 11 deltas and the number will grow). Finally, deltas are grouped in {@link module:engine/model/batch~Batch batches}. A batch can be understood as a single undo step.
+
+<info-box>
+	<!-- TODO review this with Szymon -->
+
+	The technology implemented by CKEditor 5 is experimental. The subject of applying Operational Transformation to tree structures is not yet well researched and, in early 2015 when we started designing and implementing our own system, we were aware of just one existing and proven implementation (of which there was little information).
+
+	During the last 3 years we changed our approach and reworked implementation multiple times. In fact, we are still learning about new types of issues and constantly align and improve the engine. One of the most important things that we learned was that implementing OT is just part of the job on your way to real-time collaborative editing. We needed to create additional mechanisms and change the whole architecture to enable concurrent editing by multiple users with features like undo and ability to display selections of other users.
+
+	As a result of all this, the API and some important concepts are constantly changing. We have the implementation well tested already, but the engine still requires [a lot of cleaning and some implementation tweaks](https://github.com/ckeditor/ckeditor5-engine/issues/1008).
+
+	This means that information from this guide may be a bit confusing when confronted with the existing APIs. For instance, you may find that [model elements and text nodes can be modified directly](https://github.com/ckeditor/ckeditor5-engine/issues/858) (without applying operations). Please keep that in mind, and when in doubt, [report issues](https://github.com/ckeditor/ckeditor5-engine/issues/new).
+</info-box>
+
+As we mentioned earlier, going into details would make an awfully long article, so here we will only mention a few more notable facts.
+
+#### Text attributes
+
+The text styles such as "bold" and "italic" are not kept in the model as elements but as text attributes (think – like element attributes). The following DOM structure:
+
+```html
+<p>
+	"Foo "
+	<strong>
+		"bar"
+	</strong>
+</p>
+```
+
+would translate to such a model structure:
+
+```html
+<paragraph>
+	"Foo "  // text node
+	"bar"   // text node with bold=true attribute
+</paragraph>
+```
+
+Such representation of inline text styling allows significantly reducing the complexity of algorithms operating on the model. For instance, if you have the following DOM structure:
+
+```html
+<p>
+	"Foo "
+	<strong>
+		"bar"
+	</strong>
+</p>
+```
+
+and you have a selection before the letter `"b"` (`"Foo ^bar"`), is this position inside or outside `<strong>`? If you use [native DOM Selection](https://developer.mozilla.org/en-US/docs/Web/API/Selection) you may get both positions – one anchored in `<p>` and second anchored in `<strong>`. In CKEditor 5 this position translates exactly to `"Foo ^bar"`.
+
+#### Selection attributes
+
+OK, but how to let CKEditor 5 know that I want the selection to "be bold" in the case described above? This is an important information because it affects whether typed text will be bold too or not.
+
+To handle that, selection {@link module:engine/model/selection~Selection#setAttribute has attributes} too. If the selection is placed in `"Foo ^bar"` and it has the attribute `bold=true` you know that the user will type bold text.
+
+#### Positions
+
+However, we have just said that inside `<paragraph>` there are two text nodes – `"Foo "` and `"bar"`. So, if you know how [native DOM Ranges](https://developer.mozilla.org/en-US/docs/Web/API/Range) work you might ask – "but if the selection is at the boundary of two text nodes, is it anchored in the left one, the right one or in the containing element?"
+
+This is, indeed, another problem with DOM APIs – not only can positions outside and inside some element be identical visually but also, they can be anchored inside or outside a text node (if the position is at a text node boundary). This all creates extreme complications when implementing editing algorithms.
+
+To avoid such troubles, and to make collaborative editing possible for real, in CKEditor 5 we use concepts of **indexes** and **offsets**. Indexes relate to nodes (elements and text nodes) while offsets to positions. For example, in the following structure:
+
+```html
+<paragraph>
+	"Foo "
+	<image></image>
+	"bar"
+</paragraph>
+```
+
+The `"Foo "` text node is at index `0` in its parent, `<image></image>` is at index `1` and `"bar"` is at index `2`.
+
+On the other hand, offset `x` in `<paragraph>` translates to:
+
+| offset | position                                         | node      |
+|--------|--------------------------------------------------|-----------|
+| `0`    | `<paragraph>^Foo <image></image>bar</paragraph>` | `"Foo "`  |
+| `1`    | `<paragraph>F^oo <image></image>bar</paragraph>` | `"Foo "`  |
+| `4`    | `<paragraph>Foo ^<image></image>bar</paragraph>` | `<image>` |
+| `6`    | `<paragraph>Foo <image></image>b^ar</paragraph>` | `"bar"`   |
+
+The engine defines also 3 main classes which operates on offsets:
+
+* A {@link module:engine/model/position~Position} instance contains an {@link module:engine/model/position~Position#path array of offsets} (which is called a "path"). See the examples in {@link module:engine/model/position~Position#path `Position#path` API docs} to better understand how paths work.
+* {@link module:engine/model/range~Range} contains two positions – {@link module:engine/model/range~Range#start start} and {@link module:engine/model/range~Range#end end} ones.
+* finally, there is {@link module:engine/model/selection~Selection} which contains one or more ranges and attributes.
+
+### View
+
+### Controller
+
+## UI library

+ 10 - 0
docs/framework/guides/error-codes.md

@@ -0,0 +1,10 @@
+---
+category: framework-guides
+order: 420
+---
+
+# Error codes
+
+CKEditor 5 Framework logs errors and warnings to the console. The following list contains more detailed descriptions of those issues.
+
+{@errors}

+ 2 - 2
docs/framework/guides/overview.md

@@ -49,8 +49,8 @@ There are a couple of groups of packages:
 
 ## What's next?
 
-To start using the framework read the:
+To start using the framework see the:
 
 * {@link framework/guides/quick-start Quick start} guide.
+* {@link framework/guides/architecture/intro Introduction to the framework's architecture} guide.
 * {@linkTODO framework/guides/creating-plugin Creating a plugin} guide.
-* {@linkTODO framework/guides/architecture/index Architecture} guide.

+ 1 - 1
docs/framework/guides/quick-start.md

@@ -188,7 +188,7 @@ Let's start from installing necessary dependencies:
 * the [`@ckeditor/ckeditor5-image`](https://www.npmjs.com/package/@ckeditor/ckeditor5-image) package which contains the image feature (on which our plugin will rely),
 * the [`@ckeditor/ckeditor5-core`](https://www.npmjs.com/package/@ckeditor/ckeditor5-core) package which contains the {@link module:core/plugin~Plugin} and {@link module:core/command~Command} classes.
 * the [`@ckeditor/ckeditor5-engine`](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine) package which contains the editing engine.
-* * the [`@ckeditor/ckeditor5-ui`](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui) package which contains the UI library and framework.
+* the [`@ckeditor/ckeditor5-ui`](https://www.npmjs.com/package/@ckeditor/ckeditor5-ui) package which contains the UI library and framework.
 
 ```bash
 npm install --save @ckeditor/ckeditor5-image @ckeditor/ckeditor5-core @ckeditor/ckeditor5-engine

+ 0 - 0
docs/framework/support.md → docs/framework/guides/support.md


+ 3 - 3
docs/umberto.json

@@ -30,9 +30,9 @@
 					"slug": "guides",
 					"categories": [
 						{
-							"name": "Editing engine",
-							"id": "framework-engine",
-							"slug": "engine",
+							"name": "Architecture",
+							"id": "framework-architecture",
+							"slug": "architecture",
 							"order": 100
 						},
 						{