Преглед на файлове

Merge branch 'master' into t/924

Kamil Piechaczek преди 6 години
родител
ревизия
d645f19834
променени са 44 файла, в които са добавени 2252 реда и са изтрити 976 реда
  1. 2 2
      .travis.yml
  2. 65 1
      CHANGELOG.md
  3. 1 1
      docs/_snippets/examples/classic-editor.html
  4. 0 0
      docs/_snippets/features/build-ui-language-source.html
  5. 12 0
      docs/_snippets/features/build-ui-language-source.js
  6. 5 0
      docs/_snippets/features/mathtype.html
  7. 28 0
      docs/_snippets/features/mathtype.js
  8. 4 0
      docs/_snippets/features/ui-language-content.html
  9. 25 0
      docs/_snippets/features/ui-language-content.js
  10. 4 0
      docs/_snippets/features/ui-language-rtl.html
  11. 23 0
      docs/_snippets/features/ui-language-rtl.js
  12. 1 1
      docs/_snippets/features/ui-language.html
  13. 2 5
      docs/_snippets/features/ui-language.js
  14. 12 0
      docs/_snippets/features/wproofreader.html
  15. 22 0
      docs/_snippets/features/wproofreader.js
  16. BIN
      docs/assets/img/builds-content-styles.png
  17. 10 16
      docs/builds/guides/faq.md
  18. 54 2
      docs/builds/guides/frameworks/angular.md
  19. 288 211
      docs/builds/guides/frameworks/react.md
  20. 81 1
      docs/builds/guides/frameworks/vuejs.md
  21. 5 5
      docs/builds/guides/integration/advanced-setup.md
  22. 193 0
      docs/builds/guides/integration/content-styles.md
  23. 12 6
      docs/features/image-upload.md
  24. 71 0
      docs/features/mathtype.md
  25. 91 0
      docs/features/spell-checker.md
  26. 70 21
      docs/features/ui-language.md
  27. 1 1
      docs/framework/guides/contributing/contributing.md
  28. 29 18
      docs/framework/guides/contributing/development-environment.md
  29. 5 1
      docs/framework/guides/contributing/testing-environment.md
  30. 2 2
      docs/framework/guides/development-tools.md
  31. 6 6
      docs/framework/guides/quick-start.md
  32. 5 5
      docs/framework/guides/tutorials/implementing-a-block-widget.md
  33. 4 4
      docs/framework/guides/tutorials/implementing-an-inline-widget.md
  34. 8 1
      docs/umberto.json
  35. 1 7
      mgit.json
  36. 66 63
      package.json
  37. 3 3
      scripts/bump-year.js
  38. 241 0
      scripts/docs/build-content-styles.js
  39. 76 0
      scripts/docs/content-styles/ckeditor.js
  40. 35 0
      scripts/docs/content-styles/list-content-styles.js
  41. 56 3
      scripts/docs/snippetadapter.js
  42. 0 39
      scripts/release/update-mgit-branches.js
  43. 7 19
      scripts/update-stable-branches.sh
  44. 626 532
      yarn.lock

+ 2 - 2
.travis.yml

@@ -15,8 +15,8 @@ before_install:
 - sh -e /etc/init.d/xvfb start
 - npm i -g yarn
 install:
-- yarn add mgit2 --ignore-workspace-root-check
-- mgit sync --resolver-url-template="https://github.com/\${ path }.git"
+- yarn add mrgit --ignore-workspace-root-check
+- mrgit sync --resolver-url-template="https://github.com/\${ path }.git"
 - git checkout package.json yarn.lock
 - rm -rf node_modules
 - yarn install

Файловите разлики са ограничени, защото са твърде много
+ 65 - 1
CHANGELOG.md


+ 1 - 1
docs/_snippets/examples/classic-editor.html

@@ -4,7 +4,7 @@
 	<p>Like all the great things on earth traveling teaches us by example. Here are some of the most precious lessons I’ve learned over the years of traveling.</p>
 
 	<figure class="media">
-		<oembed url="https://www.youtube.com/watch?v=BLJ4GKKaiXw"></oembed>
+		<oembed url="https://www.youtube.com/watch?v=CB70skVw3nU"></oembed>
 	</figure>
 
 	<h3>Appreciation of diversity</h3>

+ 0 - 0
docs/_snippets/features/build-ui-language-source.html


+ 12 - 0
docs/_snippets/features/build-ui-language-source.js

@@ -0,0 +1,12 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals window */
+
+/* config { "additionalLanguages": [ "ar", "es" ] } */
+
+import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
+
+window.ClassicEditor = ClassicEditor;

+ 5 - 0
docs/_snippets/features/mathtype.html

@@ -0,0 +1,5 @@
+<div id="mathtype-editor">
+	<p>In elementary algebra, the <strong>quadratic formula</strong> is the solution of the quadratic equation.</p>
+
+	<p><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi><mo>=</mo><mfrac><mrow><mo>-</mo><mi>b</mi><mo>&#177;</mo><msqrt><msup><mi>b</mi><mn>2</mn></msup><mo>-</mo><mn>4</mn><mi>a</mi><mi>c</mi></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></math></p>
+</div>

+ 28 - 0
docs/_snippets/features/mathtype.js

@@ -0,0 +1,28 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals document, console */
+
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
+import Heading from '@ckeditor/ckeditor5-heading/src/heading';
+import MathType from '@wiris/mathtype-ckeditor5';
+
+ClassicEditor
+	.create( document.querySelector( '#mathtype-editor' ), {
+		plugins: [
+			Essentials,
+			Bold,
+			Italic,
+			Heading,
+			MathType
+		],
+		toolbar: [ 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo', '|', 'MathType', 'ChemType' ]
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

Файловите разлики са ограничени, защото са твърде много
+ 4 - 0
docs/_snippets/features/ui-language-content.html


+ 25 - 0
docs/_snippets/features/ui-language-content.js

@@ -0,0 +1,25 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals ClassicEditor, console, window, document */
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-ui-language-content' ), {
+		language: {
+			content: 'ar'
+		},
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

Файловите разлики са ограничени, защото са твърде много
+ 4 - 0
docs/_snippets/features/ui-language-rtl.html


+ 23 - 0
docs/_snippets/features/ui-language-rtl.js

@@ -0,0 +1,23 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals ClassicEditor, console, window, document */
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-ui-language-rtl' ), {
+		language: 'ar',
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
docs/_snippets/features/ui-language.html


+ 2 - 5
docs/_snippets/features/ui-language.js

@@ -3,16 +3,13 @@
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
 
-/* globals console, window, document */
-
-/* config { "language": "de" } */
-
-import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
+/* globals ClassicEditor, console, window, document */
 
 import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
 
 ClassicEditor
 	.create( document.querySelector( '#snippet-ui-language' ), {
+		language: 'es',
 		cloudServices: CS_CONFIG,
 		toolbar: {
 			viewportTopOffset: window.getViewportTopOffsetConfig()

+ 12 - 0
docs/_snippets/features/wproofreader.html

@@ -0,0 +1,12 @@
+<script type="text/javascript" src="https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js"></script>
+<script>
+	window.WEBSPELLCHECKER_CONFIG = {
+		autoSearch: true,
+		enableGrammar: true,
+		serviceId: '1:Eebp63-lWHbt2-ASpHy4-AYUpy2-fo3mk4-sKrza1-NsuXy4-I1XZC2-0u2F54-aqYWd1-l3Qf14-umd'
+	};
+</script>
+<div id="snippet-wproofreader">
+	<p>Typos hapen. We striving to correct them. Hover on the marked words for instant correction suggestions or click the dialog icon in the bottom right corner to have the whole text proofread at once.</p>
+	<p>You can also paste your own text here to have its spelling and grammar checked.</p>
+</div>

+ 22 - 0
docs/_snippets/features/wproofreader.js

@@ -0,0 +1,22 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals ClassicEditor, console, window, document */
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-wproofreader' ), {
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

BIN
docs/assets/img/builds-content-styles.png


+ 10 - 16
docs/builds/guides/faq.md

@@ -10,7 +10,7 @@ order: 40
 
 Unlike [CKEditor 4](https://ckeditor.com/ckeditor-4/), CKEditor 5 implements a custom {@link framework/guides/architecture/editing-engine data model}. This means that every piece of content that is loaded into the editor needs to be converted to that model and then rendered back to the view.
 
-Each kind of content must be handled by some feature. For instance the [ckeditor5-basic-styles](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles) package handles HTML elements such as `<b>`, `<i>`, `<u>`, etc. along with their representation in the model. The feature defines the two–way conversion between the HTML (view) and the editor model.
+Each kind of content must be handled by some feature. For instance the [`ckeditor5-basic-styles`](https://www.npmjs.com/package/@ckeditor/ckeditor5-basic-styles) package handles HTML elements such as `<b>`, `<i>`, `<u>`, etc. along with their representation in the model. The feature defines the two–way conversion between the HTML (view) and the editor model.
 
 If you load some content unknown to any editor feature, it will be dropped. If you want all the HTML5 elements to be supported, you need to write plugins to support them. Once you do that, CKEditor 5 will not filter anything out.
 
@@ -22,15 +22,9 @@ See the [relevant issue](https://github.com/ckeditor/ckeditor5/issues/592) on Gi
 
 ## What happened to the `contents.css` file? How do I style the content of the editor?
 
-There is no such thing as the `contents.css` file because in CKEditor 5 features bring their own content styles, which are by default included in the JavaScript build and {@link framework/guides/theme-customization#styles-processing-and-bundling loaded by the style–loader} (they can be {@link builds/guides/integration/advanced-setup#option-extracting-css extracted}, too). It optimizes the size of the builds as the styles of unused features are simply excluded.
+There is no such thing as the `contents.css` file because in CKEditor 5 features bring their own content styles, which are by default included in the JavaScript build and {@link framework/guides/theme-customization#styles-processing-and-bundling loaded by the style loader}. It optimizes the size of the builds as the styles of unused features are simply excluded.
 
-Although some styles are provided by the features, it is up to the developers to make sure the content created by CKEditor 5 is properly styled, both in the front–end and in the back–end. To style the content in the editor (back–end), use the `.ck-content` CSS class:
-
-```css
-.ck-content a {
-	color: teal;
-}
-```
+You can get the full list of editor content styles in a {@link builds/guides/integration/content-styles dedicated guide}. You can also {@link builds/guides/integration/advanced-setup#option-extracting-css extract all CSS} brought by CKEditor 5 (content and UI) to a separate file when creating a custom editor build.
 
 ## The build I downloaded is missing some features. How do I add them?
 
@@ -40,7 +34,7 @@ You can learn which editor features are available in the {@link features/index f
 
 ## Where are the `editor.insertHtml()` and `editor.insertText()` methods? How to insert some content?
 
-Because CKEditor 5 uses a custom {@link framework/guides/architecture/editing-engine data model}, whenever you want to insert anything, you should modify the model first, which is then converted back to the view where the users input their content (called editable). In CKEditor 5, HTML is just one of many possible output formats. You can learn more about the ways of changing the model in the {@link framework/guides/architecture/editing-engine#changing-the-model dedicated guide}.
+Because CKEditor 5 uses a custom {@link framework/guides/architecture/editing-engine data model}, whenever you want to insert anything, you should modify the model first, which is then converted back to the view where the users input their content (called "editable"). In CKEditor 5, HTML is just one of many possible output formats. You can learn more about the ways of changing the model in the {@link framework/guides/architecture/editing-engine#changing-the-model dedicated guide}.
 
 To insert a new link at the current position, use the following snippet:
 
@@ -80,11 +74,11 @@ By default, CKEditor 5 has no global registry of editor instances. But if necess
 
 The {@link features/image Image} and {@link features/image-upload Image upload} features are enabled by default in all editor builds. However, to fully enable image upload when installing CKEditor 5 you need to configure one of the available upload adapters. Check out the {@link features/image-upload comprehensive "Image upload" guide} to find out the best image upload strategy for your project.
 
-## How to use CKEditor 5 with frameworks (Angular, React, etc.)?
+## How to use CKEditor 5 with frameworks (Angular, React, Vue, etc.)?
 
 For the full list of official integrations see the {@link builds/guides/frameworks/overview#official-wysiwyg-editor-integrations "Official integrations"} section.
 
-If an official integration for the framework of your choice does not exist yet, make sure to read the {@link builds/guides/frameworks/overview "Integrating CKEditor 5 with JavaScript frameworks"} guide. CKEditor 5 offers a rich JavaScript API and ready to use builds which make it possible to use CKEditor 5 with whichever framework you need.
+If an official integration for the framework of your choice does not exist yet, make sure to read the {@link builds/guides/frameworks/overview "Integrating CKEditor 5 with JavaScript frameworks"} guide. CKEditor 5 offers a rich JavaScript API and ready-to-use builds that make it possible to use CKEditor 5 with whichever framework you need.
 
 We plan to provide more official integrations with time. [Your feedback on what should we work on next](https://github.com/ckeditor/ckeditor5/issues/1002) will be most welcome!
 
@@ -114,7 +108,7 @@ Learn more about {@link builds/guides/integration/advanced-setup#webpack-configu
 
 ## How to get the editor instance object from the DOM element?
 
-If you have a reference to the editor editable's DOM element (that's the one with the `.ck-editor__editable` class and the `contenteditable` attribute), you can access the editor instance this editable element belongs to using the `ckeditorInstance` property:
+If you have a reference to the editor editable's DOM element (the one with the `.ck-editor__editable` class and the `contenteditable` attribute), you can access the editor instance this editable element belongs to using the `ckeditorInstance` property:
 
 ```html
 <!-- The editable element in the editor's DOM structure. -->
@@ -124,7 +118,7 @@ If you have a reference to the editor editable's DOM element (that's the one wit
 ```
 
 ```js
-// A reference to the editor editable element in DOM.
+// A reference to the editor editable element in the DOM.
 const domEditableElement = document.querySelector( '.ck-editor__editable' );
 
 // Get the editor instance from the editable element.
@@ -146,14 +140,14 @@ editor.editing.view.change( writer => {
 } );
 ```
 
-If you do not have the reference to the editor instance but you have access to the editable element in DOM, you can [access it using the `ckeditorInstance` property](#how-to-get-the-editor-instance-object-from-the-dom-element) and then use the same API to set the attribute:
+If you do not have the reference to the editor instance but you have access to the editable element in the DOM, you can [access it using the `ckeditorInstance` property](#how-to-get-the-editor-instance-object-from-the-dom-element) and then use the same API to set the attribute:
 
 ```js
 const domEditableElement = document.querySelector( '.ck-editor__editable' );
 const editorInstance = domEditableElement.ckeditorInstance;
 
 editorInstance.editing.view.change( writer => {
-	// Map the editable element in DOM to the editable element in editor's view.
+	// Map the editable element in the DOM to the editable element in the editor's view.
 	const viewEditableRoot = editorInstance.editing.view.domConverter.mapDomToView( domEditableElement );
 
 	writer.setAttribute( 'myAttribute', 'value', viewEditableRoot );

+ 54 - 2
docs/builds/guides/frameworks/angular.md

@@ -24,7 +24,7 @@ In your existing Angular project, install the [CKEditor 5 WYSIWYG editor compone
 npm install --save @ckeditor/ckeditor5-angular
 ```
 
-Install one of the {@link builds/guides/overview#available-builds official editor builds} or {@link builds/guides/development/custom-builds create a custom one} (e.g. if you want to install more plugins or customize something that cannot be controlled with the {@link builds/guides/integration/configuration editor configuration}).
+Install one of the {@link builds/guides/overview#available-builds official editor builds} or [create a custom one](#using-a-custom-ckeditor-5-build).
 
 Assuming that you picked [`@ckeditor/ckeditor5-build-classic`](https://www.npmjs.com/package/@ckeditor/ckeditor5-build-classic):
 
@@ -68,7 +68,7 @@ Finally, use the `<ckeditor>` tag in the template to run the rich text editor:
 
 Rebuild your application and CKEditor 5 should greet you with "Hello, world!".
 
-### Note: Using the Document editor build
+### Using the Document editor build
 
 If you want to use the {@link framework/guides/document-editor document editor build}, you need to {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create add the toolbar to the DOM manually}.
 
@@ -77,6 +77,7 @@ import * as DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
 
 @Component( {
 	// ...
+} )
 export class MyComponent {
 	public Editor = DecoupledEditor;
 
@@ -95,6 +96,57 @@ And then, in the template:
 <ckeditor [editor]="Editor" data="<p>Hello, world!</p>" (ready)="onReady($event)"></ckeditor>
 ```
 
+### Using a custom CKEditor 5 build
+
+If you want to add more plugins to the existing build or customize something that cannot be controlled with the {@link builds/guides/integration/configuration editor configuration} you should create a custom build first, using the {@link builds/guides/development/custom-builds create a custom build guide}.
+
+You should finish the above tutorial with the generated `ckeditor.js` file (and corresponding translation files). In the next step you should copy it to the `src` directory and import it to the component file.
+
+```ts
+import * as Editor from 'path/to/the/ckeditor';
+
+@Component( {
+	// ...
+} )
+export class MyComponent {
+	public Editor = Editor;
+	// ...
+}
+```
+
+Note that to allow importing JavaScript files without providing their corresponding types you need to set `allowJs` to `true` in the `tsconfig.json` file. Also, make sure that you target `ES6` or higher, otherwise you are likely to end up with [a weird transpilation error](https://github.com/ckeditor/ckeditor5-angular/issues/20) in the production build.
+
+```json
+"compilerOptions": {
+	"allowJs": true,
+	"target": "es2015"
+	// other options
+}
+```
+
+<info-box>
+	If you cannot set the target higher than `es5`, try to set `"buildOptimizer": false` which will produce a bigger, but correct production build.
+</info-box>
+
+### Strict mode project tips
+
+If you have the strict mode set in your project, you need to specify types for CKEditor 5 packages. Otherwise you will get the `Could not find a declaration file for module` error.
+
+To fix that you need to create a TypeScript declaration file and declare modules that miss their types:
+
+```ts
+// typings.d.ts
+
+// You should specify the CKEditor 5 build you use here:
+declare module '@ckeditor/ckeditor5-build-classic' {
+	const ClassicEditorBuild: any;
+
+	export = ClassicEditorBuild;
+}
+```
+
+Unfortunately, CKEditor 5 builds do not ship with corresponding TypeScript typings yet. If you are interested in this topic you can add your vote or a comment [here](https://github.com/ckeditor/ckeditor5/issues/504).
+
 ## Integration with `ngModel`
 
 The component implements the [`ControlValueAccessor`](https://angular.io/api/forms/ControlValueAccessor) interface and works with the `ngModel`. Here is how to use it:

+ 288 - 211
docs/builds/guides/frameworks/react.md

@@ -30,31 +30,31 @@ import CKEditor from '@ckeditor/ckeditor5-react';
 import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
 
 class App extends Component {
-    render() {
-        return (
-            <div className="App">
-                <h2>Using CKEditor 5 build in React</h2>
-                <CKEditor
-                    editor={ ClassicEditor }
-                    data="<p>Hello from CKEditor 5!</p>"
-                    onInit={ editor => {
-                        // You can store the "editor" and use when it is needed.
-                        console.log( 'Editor is ready to use!', editor );
-                    } }
-                    onChange={ ( event, editor ) => {
-                        const data = editor.getData();
-                        console.log( { event, editor, data } );
-                    } }
-                    onBlur={ editor => {
-                        console.log( 'Blur.', editor );
-                    } }
-                    onFocus={ editor => {
-                        console.log( 'Focus.', editor );
-                    } }
-                />
-            </div>
-        );
-    }
+	render() {
+		return (
+			<div className="App">
+				<h2>Using CKEditor 5 build in React</h2>
+				<CKEditor
+					editor={ ClassicEditor }
+					data="<p>Hello from CKEditor 5!</p>"
+					onInit={ editor => {
+						// You can store the "editor" and use when it is needed.
+						console.log( 'Editor is ready to use!', editor );
+					} }
+					onChange={ ( event, editor ) => {
+						const data = editor.getData();
+						console.log( { event, editor, data } );
+					} }
+					onBlur={ ( event, editor ) => {
+						console.log( 'Blur.', editor );
+					} }
+					onFocus={ ( event, editor ) => {
+						console.log( 'Focus.', editor );
+					} }
+				/>
+			</div>
+		);
+	}
 }
 
 export default App;
@@ -67,16 +67,16 @@ The `<CKEditor>` component supports the following properties:
 * `editor` (required) &ndash; The {@link module:core/editor/editor~Editor `Editor`} constructor to use.
 * `data` &ndash; The initial data for the created editor. See the {@link builds/guides/integration/basic-api#interacting-with-the-editor Basic API} guide.
 * `config` &ndash; The editor configuration. See the {@link builds/guides/integration/configuration Configuration} guide.
-* `onChange` &ndash; A function called when the editor's data has changed. See the {@link module:engine/model/document~Document#event:change:data `editor.model.document#change:data`} event.
+* `onInit` &ndash; A function called when the editor was initialized. It receives the initialized {@link module:core/editor/editor~Editor `editor`} as a parameter.
+* `disabled` &ndash; A Boolean value. The {@link module:core/editor/editor~Editor `editor`} is being switched to read-only mode if the property is set to `true`.
+* `onChange` &ndash; A function called when the editor data has changed. See the {@link module:engine/model/document~Document#event:change:data `editor.model.document#change:data`} event.
+* `onBlur` &ndash; A function called when the editor was blurred. See the {@link module:engine/view/document~Document#event:blur `editor.editing.view.document#blur`} event.
+* `onFocus` &ndash; A function called when the editor was focused. See the {@link module:engine/view/document~Document#event:focus `editor.editing.view.document#focus`} event.
 
-	The callback receives two parameters:
+The editor events callbacks (`onChange`, `onBlur`, `onFocus`) receive two parameters:
 
-	1. An {@link module:utils/eventinfo~EventInfo `EventInfo`} object,
-	2. An {@link module:core/editor/editor~Editor `Editor`} instance.
-* `onInit` &ndash; A function called when the editor was initialized. It receives the initialized {@link module:core/editor/editor~Editor `editor`} as a parameter.
-* `onBlur` &ndash; A function called when the editor was blurred. It receives the blurred {@link module:core/editor/editor~Editor `editor`} as a parameter.
-* `onFocus` &ndash; A function called when the editor was focused. It receives the focused {@link module:core/editor/editor~Editor `editor`} as a parameter.
-* `disabled` &ndash; A boolean. The {@link module:core/editor/editor~Editor `editor`} is being switched to read-only mode if the property is set to `true`.
+1. An {@link module:utils/eventinfo~EventInfo `EventInfo`} object.
+2. An {@link module:core/editor/editor~Editor `Editor`} instance.
 
 ### Customizing the builds
 
@@ -113,27 +113,27 @@ If you use the {@link framework/guides/document-editor Document editor}, you nee
 import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
 
 class App extends Component {
-    render() {
-        return (
-            <div className="App">
-                <h2>CKEditor 5 using a custom build - DecoupledEditor</h2>
-                <CKEditor
-                    onInit={ editor => {
-                        console.log( 'Editor is ready to use!', editor );
-
-                        // Insert the toolbar before the editable area.
-                        editor.ui.getEditableElement().parentElement.insertBefore(
-                            editor.ui.view.toolbar.element,
-                            editor.ui.getEditableElement()
-                        );
-                    } }
-                    onChange={ ( event, editor ) => console.log( { event, editor } ) }
-                    editor={ DecoupledEditor }
-                    data="<p>Hello from CKEditor 5's DecoupledEditor!</p>"
-                    config={ /* the editor configuration */ }
-                />
-        );
-    }
+	render() {
+		return (
+			<div className="App">
+				<h2>CKEditor 5 using a custom build - DecoupledEditor</h2>
+				<CKEditor
+					onInit={ editor => {
+						console.log( 'Editor is ready to use!', editor );
+
+						// Insert the toolbar before the editable area.
+						editor.ui.getEditableElement().parentElement.insertBefore(
+							editor.ui.view.toolbar.element,
+							editor.ui.getEditableElement()
+						);
+					} }
+					onChange={ ( event, editor ) => console.log( { event, editor } ) }
+					editor={ DecoupledEditor }
+					data="<p>Hello from CKEditor 5's DecoupledEditor!</p>"
+					config={ /* the editor configuration */ }
+				/>
+		);
+	}
 }
 
 export default App;
@@ -175,14 +175,14 @@ Before you start modifying the webpack configuration, first install some CKEdito
 
 ```bash
 yarn add \
-  raw-loader \
-  @ckeditor/ckeditor5-dev-utils \
-  @ckeditor/ckeditor5-theme-lark \
-  @ckeditor/ckeditor5-react \
-  @ckeditor/ckeditor5-editor-classic \
-  @ckeditor/ckeditor5-essentials \
-  @ckeditor/ckeditor5-paragraph \
-  @ckeditor/ckeditor5-basic-styles
+	raw-loader@3 \
+	@ckeditor/ckeditor5-dev-utils \
+	@ckeditor/ckeditor5-theme-lark \
+	@ckeditor/ckeditor5-react \
+	@ckeditor/ckeditor5-editor-classic \
+	@ckeditor/ckeditor5-essentials \
+	@ckeditor/ckeditor5-paragraph \
+	@ckeditor/ckeditor5-basic-styles
 ```
 
 #### Modifying webpack configuration
@@ -199,28 +199,28 @@ Then, add two new elements to the exported object under the `module.rules` array
 
 ```js
 {
-  test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
-  use: [ 'raw-loader' ]
+	test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+	use: [ 'raw-loader' ]
 },
 {
-  test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  use: [
-    {
-      loader: 'style-loader',
-      options: {
-        singleton: true
-      }
-    },
-    {
-      loader: 'postcss-loader',
-      options: styles.getPostCssConfig( {
-        themeImporter: {
-          themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
-        },
-        minify: true
-      } )
-    }
-  ]
+	test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
+	use: [
+		{
+			loader: 'style-loader',
+			options: {
+				injectType: 'singletonStyleTag'
+			}
+		},
+		{
+			loader: 'postcss-loader',
+			options: styles.getPostCssConfig( {
+				themeImporter: {
+					themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
+				},
+				minify: true
+			} )
+		}
+	]
 },
 ```
 
@@ -230,12 +230,12 @@ First, find a loader that starts its definition with the following code: `test:
 
 ```js
 {
-  test: cssRegex,
-  exclude: [
-    cssModuleRegex,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  ],
-  // (...)
+	test: cssRegex,
+	exclude: [
+		cssModuleRegex,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
+	],
+	// (...)
 }
 ```
 
@@ -243,11 +243,11 @@ Below it, you will find another loader that handles CSS files. You need to disab
 
 ```js
 {
-  test: cssModuleRegex,
-  exclude: [
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  ],
-  // (...)
+	test: cssModuleRegex,
+	exclude: [
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
+	],
+	// (...)
 }
 ```
 
@@ -255,21 +255,21 @@ Finally, exclude CKEditor 5 SVG and CSS files from `file-loader` . Find the last
 
 ```js
 {
-  loader: require.resolve('file-loader'),
-  // Exclude `js` files to keep the "css" loader working as it injects
-  // its runtime that would otherwise be processed through the "file" loader.
-  // Also exclude `html` and `json` extensions so they get processed
-  // by webpack's internal loaders.
-  exclude: [
-    /\.(js|mjs|jsx|ts|tsx)$/,
-    /\.html$/,
-    /\.json$/,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/
-  ],
-  options: {
-    name: 'static/media/[name].[hash:8].[ext]',
-  }
+	loader: require.resolve( 'file-loader' ),
+	// Exclude `js` files to keep the "css" loader working as it injects
+	// its runtime that would otherwise be processed through the "file" loader.
+	// Also exclude `html` and `json` extensions so they get processed
+	// by webpack's internal loaders.
+	exclude: [
+		/\.(js|mjs|jsx|ts|tsx)$/,
+		/\.html$/,
+		/\.json$/,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/
+	],
+	options: {
+		name: 'static/media/[name].[hash:8].[ext]',
+	}
 }
 ```
 
@@ -291,37 +291,37 @@ import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 
 const editorConfiguration = {
-  plugins: [ Essentials, Bold, Italic, Paragraph ],
-  toolbar: [ 'bold', 'italic' ]
+	plugins: [ Essentials, Bold, Italic, Paragraph ],
+	toolbar: [ 'bold', 'italic' ]
 };
 
 class App extends Component {
-  render() {
-    return (
-      <div className="App">
-        <h2>Using CKEditor 5 from source in React</h2>
-        <CKEditor
-          editor={ ClassicEditor }
-          config={ editorConfiguration }
-          data="<p>Hello from CKEditor 5!</p>"
-          onInit={ editor => {
-            // You can store the "editor" and use when it is needed.
-            console.log( 'Editor is ready to use!', editor );
-          } }
-          onChange={ ( event, editor ) => {
-            const data = editor.getData();
-            console.log( { event, editor, data } );
-          } }
-          onBlur={ editor => {
-            console.log( 'Blur.', editor );
-          } }
-          onFocus={ editor => {
-            console.log( 'Focus.', editor );
-          } }
-        />
-      </div>
-    );
-  }
+	render() {
+		return (
+			<div className="App">
+				<h2>Using CKEditor 5 from source in React</h2>
+				<CKEditor
+					editor={ ClassicEditor }
+					config={ editorConfiguration }
+					data="<p>Hello from CKEditor 5!</p>"
+					onInit={ editor => {
+						// You can store the "editor" and use when it is needed.
+						console.log( 'Editor is ready to use!', editor );
+					} }
+					onChange={ ( event, editor ) => {
+						const data = editor.getData();
+						console.log( { event, editor, data } );
+					} }
+					onBlur={ ( event, editor ) => {
+						console.log( 'Blur.', editor );
+					} }
+					onFocus={ ( event, editor ) => {
+						console.log( 'Focus.', editor );
+					} }
+				/>
+			</div>
+		);
+	}
 }
 
 export default App;
@@ -400,26 +400,26 @@ In the end, the entire plugin definition should look as follows:
 ```js
 // Minify the code.
 new UglifyJsWebpackPlugin( {
-  uglifyOptions: {
-    compress: {
-      warnings: false,
-      // Disabled because of an issue with Uglify breaking seemingly valid code:
-      // https://github.com/facebookincubator/create-react-app/issues/2376
-      // Pending further investigation:
-      // https://github.com/mishoo/UglifyJS2/issues/2011
-      comparisons: false,
-    },
-    mangle: {
-        safari10: true,
-    },
-    output: {
-        comments: false,
-        // Turned on because emoji and regex is not minified properly using default
-        // https://github.com/facebookincubator/create-react-app/issues/2488
-        ascii_only: true,
-    },
-  },
-  sourceMap: shouldUseSourceMap,
+	uglifyOptions: {
+		compress: {
+			warnings: false,
+			// Disabled because of an issue with Uglify breaking seemingly valid code:
+			// https://github.com/facebookincubator/create-react-app/issues/2376
+			// Pending further investigation:
+			// https://github.com/mishoo/UglifyJS2/issues/2011
+			comparisons: false,
+		},
+		mangle: {
+			safari10: true,
+		},
+		output: {
+			comments: false,
+			// Turned on because emoji and regex is not minified properly using default
+			// https://github.com/facebookincubator/create-react-app/issues/2488
+			ascii_only: true,
+		},
+	},
+	sourceMap: shouldUseSourceMap,
 } )
 ```
 
@@ -444,28 +444,28 @@ Then add two new elements to the exported object under the `module.rules` array
 
 ```js
 {
-  test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
-  use: [ 'raw-loader' ]
+	test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+	use: [ 'raw-loader' ]
 },
 {
-  test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  use: [
-    {
-      loader: 'style-loader',
-      options: {
-        singleton: true
-      }
-    },
-    {
-      loader: 'postcss-loader',
-      options: styles.getPostCssConfig( {
-        themeImporter: {
-          themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
-        },
-        minify: true
-      } )
-    }
-  ]
+	test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
+	use: [
+		{
+			loader: 'style-loader',
+			options: {
+				injectType: 'singletonStyleTag'
+			}
+		},
+		{
+			loader: 'postcss-loader',
+			options: styles.getPostCssConfig( {
+				themeImporter: {
+					themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
+				},
+				minify: true
+			} )
+		}
+	]
 },
 ```
 
@@ -473,9 +473,9 @@ Exclude CSS files used by CKEditor 5 from project's CSS loader:
 
 ```js
 {
-  test: /\.css$/,
-  exclude: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
-  // (...)
+	test: /\.css$/,
+	exclude: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/,
+	// (...)
 }
 ```
 
@@ -483,21 +483,21 @@ And exclude CKEditor 5 SVG and CSS files from `file-loader` because these files
 
 ```js
 {
-  loader: require.resolve('file-loader'),
-  // Exclude `js` files to keep the "css" loader working as it injects
-  // its runtime that would otherwise be processed through the "file" loader.
-  // Also exclude `html` and `json` extensions so they get processed
-  // by webpack's internal loaders.
-  exclude: [
-    /\.(js|jsx|mjs)$/,
-    /\.html$/,
-    /\.json$/,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
-    /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/
-  ],
-  options: {
-    name: 'static/media/[name].[hash:8].[ext]'
-  }
+	loader: require.resolve( 'file-loader' ),
+	// Exclude `js` files to keep the "css" loader working as it injects
+	// its runtime that would otherwise be processed through the "file" loader.
+	// Also exclude `html` and `json` extensions so they get processed
+	// by webpack's internal loaders.
+	exclude: [
+		/\.(js|jsx|mjs)$/,
+		/\.html$/,
+		/\.json$/,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
+		/ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css/
+	],
+	options: {
+		name: 'static/media/[name].[hash:8].[ext]'
+	}
 }
 ```
 
@@ -537,28 +537,105 @@ import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 import Heading from '@ckeditor/ckeditor5-heading/src/heading';
 
 class App extends Component {
-    render() {
-        return (
-            <div className="App">
-                <h2>Using CKEditor 5 Framework in React</h2>
-                <CKEditor
-                    onInit={ editor => console.log( 'Editor is ready to use!', editor ) }
-                    onChange={ ( event, editor ) => console.log( { event, editor } ) }
-                    config={ {
-                        plugins: [ Essentials, Paragraph, Bold, Italic, Heading ],
-                        toolbar: [ 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo', ]
-                    } }
-                    editor={ ClassicEditor }
-                    data="<p>Hello from CKEditor 5!</p>"
-                />
-            </div>
-        );
-    }
+	render() {
+		return (
+			<div className="App">
+				<h2>Using CKEditor 5 Framework in React</h2>
+				<CKEditor
+					onInit={ editor => console.log( 'Editor is ready to use!', editor ) }
+					onChange={ ( event, editor ) => console.log( { event, editor } ) }
+					config={ {
+						plugins: [ Essentials, Paragraph, Bold, Italic, Heading ],
+						toolbar: [ 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo', ]
+					} }
+					editor={ ClassicEditor }
+					data="<p>Hello from CKEditor 5!</p>"
+				/>
+			</div>
+		);
+	}
 }
 
 export default App;
 ```
 
+## Localization
+
+CKEditor 5 supports {@link features/ui-language multiple UI languages}, and so does the official React component. Follow the instructions below to translate CKEditor 5 in your React application.
+
+### Ready-to-use builds
+
+When using one of the {@link builds/guides/overview#available-builds official editor builds}, you need to import the translations first:
+
+```js
+import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
+
+// Import translations for the German language.
+import '@ckeditor/ckeditor5-build-classic/build/translations/de';
+
+// ...
+```
+
+Then, {@link builds/guides/integration/configuration configure} the language of the editor in the component:
+
+```jsx
+<CKEditor
+	config={ {
+		// Use the German language for this editor.
+		language: 'de',
+
+		// ...
+	} }
+	editor={ ClassicEditor }
+	data="<p>Hello from CKEditor 5!</p>"
+/>
+```
+
+For more information, please refer to the {@link features/ui-language "Setting UI language"} guide.
+
+### CKEditor 5 built from source
+
+Using the editor [built from source](#integrating-ckeditor-5-built-from-source) requires you to modify the webpack configuration. First, install the [official webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin) that allows localizing editor builds:
+
+```bash
+npm install @ckeditor/ckeditor5-dev-webpack-plugin --save-dev
+```
+
+Then, add the installed plugin to the webpack configuration:
+
+<info-box>
+	We assume that you use `create-react-app@2`. For earlier versions, make sure to modify [both webpack configuration files](#changes-required-in-webpacks-production-configuration).
+</info-box>
+
+```js
+// webpack.config.js
+'use strict';
+
+// ...
+const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
+
+module.exports = {
+	// ...
+
+	plugins: [
+		// ....
+
+		new CKEditorWebpackPlugin( {
+			// The UI language. Language codes follow the https://en.wikipedia.org/wiki/ISO_639-1 format.
+			language: 'de'
+		} ),
+
+		// ....
+	],
+
+	// ...
+};
+```
+
+After building the application, CKEditor 5 will run with the UI translated to the specified language.
+
+For more information, please refer to the {@link features/ui-language "Setting UI language"} guide.
+
 ## Contributing and reporting issues
 
 The source code of rich text editor component for React is available on GitHub in https://github.com/ckeditor/ckeditor5-react.

+ 81 - 1
docs/builds/guides/frameworks/vuejs.md

@@ -192,7 +192,7 @@ npm install --save \
     @ckeditor/ckeditor5-vue \
     @ckeditor/ckeditor5-dev-webpack-plugin \
     @ckeditor/ckeditor5-dev-utils \
-    postcss-loader \
+    postcss-loader@3 \
     raw-loader@0.5.1
 ```
 
@@ -388,6 +388,86 @@ Since accessing the editor toolbar is not possible until after the editor instan
 </script>
 ```
 
+## Localization
+
+CKEditor 5 supports {@link features/ui-language multiple UI languages}, and so does the official Vue.js component. Follow the instructions below to translate CKEditor 5 in your Vue.js application.
+
+### Ready-to-use builds
+
+When using one of the {@link builds/guides/overview#available-builds official editor builds}, you need to import the translations first.
+
+* When using a [direct script include](#direct-script-include):
+	```html
+	<!-- Import translations for the German language. -->
+	<script src="../node_modules/@ckeditor/ckeditor5-build-classic/build/translations/de.js"></script>
+	<script src="../node_modules/@ckeditor/ckeditor5-build-classic/build/ckeditor.js"></script>
+	<script src="../node_modules/@ckeditor/ckeditor5-vue/dist/ckeditor.js"></script>
+	```
+* When using [ES6 modules](#using-es6-modules):
+	```js
+	import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
+
+	// Import translations for the German language.
+	import '@ckeditor/ckeditor5-build-classic/build/translations/de';
+	```
+
+Then, {@link builds/guides/integration/configuration configure} the language of the editor in the component:
+
+```html
+<ckeditor :editor="editor" v-model="editorData" :config="editorConfig"></ckeditor>
+```
+
+```js
+export default {
+	name: 'app',
+	data() {
+		return {
+			editor: ClassicEditor,
+			editorData: '<p>Content of the editor.</p>',
+			editorConfig: {
+				// Run the editor with the German UI.
+				language: 'de'
+			}
+		};
+	}
+}
+```
+
+For more information, please refer to the {@link features/ui-language "Setting UI language"} guide.
+
+### CKEditor 5 built from source
+
+Using the editor [built from source](#using-ckeditor-from-source) requires you to modify the webpack configuration. Pass the `language` (also `additionalLanguages`) to the constructor of  [`CKEditorWebpackPlugin`](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin) to localize your editor:
+
+```js
+// vue.config.js
+// ...
+
+const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' );
+
+// ...
+
+module.exports = {
+	// ...
+
+	configureWebpack: {
+		plugins: [
+			// CKEditor needs its own plugin to be built using webpack.
+			new CKEditorWebpackPlugin( {
+				// The UI language. Language codes follow the https://en.wikipedia.org/wiki/ISO_639-1 format.
+				language: 'de'
+			} )
+		]
+	},
+
+	// ...
+}
+```
+
+After building the application, CKEditor 5 will run with the UI translated to the specified language.
+
+For more information, please refer to the {@link features/ui-language "Setting UI language"} guide.
+
 ## Component directives
 
 ### `editor`

+ 5 - 5
docs/builds/guides/integration/advanced-setup.md

@@ -99,9 +99,9 @@ The second step is to install dependencies needed to build the editor. The list
 npm install --save \
 	@ckeditor/ckeditor5-dev-webpack-plugin \
 	@ckeditor/ckeditor5-dev-utils \
-	postcss-loader \
-	raw-loader \
-	style-loader \
+	postcss-loader@3 \
+	raw-loader@3 \
+	style-loader@1 \
 	webpack@4 \
 	webpack-cli@3 \
 ```
@@ -133,7 +133,7 @@ module.exports = {
 	module: {
 		rules: [
 			{
-				// Or /ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/ if you want to limit this loader
+				// Or /ckeditor5-[^/]+\/theme\/icons\/.+\.svg$/ if you want to limit this loader
 				// to CKEditor 5 icons only.
 				test: /\.svg$/,
 
@@ -147,7 +147,7 @@ module.exports = {
 					{
 						loader: 'style-loader',
 						options: {
-							singleton: true
+							injectType: 'singletonStyleTag'
 						}
 					},
 					{

Файловите разлики са ограничени, защото са твърде много
+ 193 - 0
docs/builds/guides/integration/content-styles.md


+ 12 - 6
docs/features/image-upload.md

@@ -8,16 +8,16 @@ order: 10
 
 Inserting images into content created with CKEditor 5 is a very common task. In a properly configured rich-text editor, there are several ways for the end user to insert images:
 
-* **Pasting** it from the clipboard.
+* **Pasting** an image from the clipboard.
 * **Dragging** a file from the file system.
-* Selecting it through a **file system dialog**.
-* Selecting it from a **media management tool** in your application.
+* Selecting an image through a **file system dialog**.
+* Selecting an image from a **media management tool** in your application.
 
 Excluding the last option, all other ways require the image to be uploaded to a server. The server will then be responsible for providing the image URL used by CKEditor 5 to display the image in the document.
 
 {@img assets/img/image-upload-animation.svg 650 The visualization of the image upload process in a WYSIWYG editor.}
 
-The software that makes the image upload possible is called an **upload adapter**. It is a callback which tells the editor how to send the file to the server. There are two main strategies of getting the image upload work you can adopt in your project:
+The software that makes the image upload possible is called an **upload adapter**. It is a callback that tells the WYSIWYG editor how to send the file to the server. There are two main strategies of getting the image upload to work that you can adopt in your project:
 
 * [**Official upload adapters**](#official-upload-adapters) &ndash; There are several features providing upload adapters developed and maintained by the CKEditor team. Pick the best one for your integration and let it handle the image upload in your project.
 * [**Custom upload adapters**](#implementing-your-own-upload-adapter) &ndash; Create your own upload adapter from scratch using the open API architecture of CKEditor 5.
@@ -40,7 +40,7 @@ The demo below uses the {@link builds/guides/overview#classic-editor Classic edi
 
 CKEditor 5 introduces a new way of handling images, with a strong focus on the end–user experience. This feature is called {@link features/easy-image Easy Image} and its goal is to make the image upload as effortless and intuitive as possible.
 
-Easy Image is part of the [CKEditor Cloud Services](https://ckeditor.com/ckeditor-cloud-services/) offer. It is a <abbr title="Software as a service">SaaS</abbr> product which:
+Easy Image is part of the [CKEditor Cloud Services](https://ckeditor.com/ckeditor-cloud-services/) offer. It is a <abbr title="Software as a service">SaaS</abbr> product that:
 
 * securely uploads images,
 * takes care of rescaling and optimizing them as well as providing various image sizes (responsive images),
@@ -68,7 +68,13 @@ There are two ways you can integrate CKEditor 5 with the CKFinder file manager:
 
 {@link features/ckfinder **Learn how to integrate CKEditor 5 with CKFinder in your project**}.
 
-### Base64
+### Simple adapter
+
+The {@link features/simple-upload-adapter Simple upload adapter} allows uploading images to your server using the [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) API with a minimal editor configuration.
+
+{@link features/simple-upload-adapter **Learn how to use the Simple upload adapter in CKEditor 5**}.
+
+### Base64 adapter
 
 The {@link features/base64-upload-adapter Base64 upload feature} converts images inserted into the editor into [Base64 strings](https://en.wikipedia.org/wiki/Base64) in the {@link builds/guides/integration/saving-data editor output}.
 

+ 71 - 0
docs/features/mathtype.md

@@ -0,0 +1,71 @@
+---
+category: features
+menu-title: Math and chemical formulas
+---
+
+# Math equations and chemical formulas
+
+<info-box>
+	This feature is provided as a commercial solution called MathType delivered by our partner, [Wiris](http://www.wiris.com).
+	You can report any issues in the official CKEditor 5 [GitHub repository](https://github.com/ckeditor/ckeditor5/issues). A license can be purchased [here](https://ckeditor.com/contact/).
+</info-box>
+
+[MathType](http://www.wiris.com/en/mathtype) is a popular mathematical and science formula editor with classical and handwriting input modes. You can use it to create math equations or chemical formulas right inside the CKEditor 5 content.
+
+MathType is based upon standards like MathML for internal representation and the PNG image format for displaying formulas. It can also handle other formats like LaTeX, Flash, SVG and EPS.
+
+Additionally, MathType offers a special tool designed to help you work with chemical notation. When enabled, ChemType adds a specialized toolbar with the common chemical symbols as well as changes the notation to make it more intuitive to work with chemical formulas.
+
+## Demo
+
+In order to start creating math or chemical formulas in the WYSIWYG editor below, click the MathType or ChemType buttons in the toolbar. This will open the relevant dialog on the screen.
+
+Use the toolbar to write your equation or formula. At any time you can also click the "Go to handwritten mode" button on the right side of the MathType editor to switch to handwriting.
+
+When you are done creating your scientific content, click the "OK" button to insert your formula into CKEditor 5. You can also edit any existing formulas by double-clicking them in your document.
+
+{@snippet features/mathtype}
+
+## Usage
+
+The MathType window is split into two main areas: a [tabbed toolbar](https://docs.wiris.com/en/mathtype/mathtype_web/toolbar) that contains a large number of icons that are useful for creating math equations and chemical formulas, and an editing area where you can see your current formula, the location of the cursor, and the text currently selected (if any).
+
+The following resources can come in handy if you want to become proficient at working with this tool:
+* [Using MathType Web](https://docs.wiris.com/en/mathtype/mathtype_web/using_mathtype) covers the basics of creating formulas, using your keyboard, moving the cursor in templates, formatting your content or writing on mobile devices.
+* [Introductory tutorials](https://docs.wiris.com/en/mathtype/mathtype_web/intro_tutorials) are intended to get you started using MathType.
+* [ChemType](https://docs.wiris.com/en/mathtype/mathtype_web/chemistry) explains the features of the dedicated chemistry toolbar.
+* [MathType documentation](https://docs.wiris.com/en/mathtype/mathtype_web/start) is a complete reference to all MathType features and settings.
+
+## Editing modes
+
+MathType lets you choose between two editing modes:
+* **Classic input mode** provides options to choose symbols and templates from the MathType or ChemType toolbars and combine them to build the equation.
+* **Handwritten input mode** lets you write the equation in your own handwriting. After checking the equation preview to ensure its accuracy, you can insert the equation or switch to classic input for further editing. [Read more here](https://docs.wiris.com/en/mathtype/mathtype_web/handwritten-input).
+
+If you visit a page using MathType with your mobile device, the handwriting interface will appear by default. However, if you visit the same page with a laptop or desktop computer, the classic input will be displayed. The user is always free to change between the two interfaces.
+
+## Installation
+
+To add MathType features to your editor, install the [`@wiris/mathtype-ckeditor5`](https://www.npmjs.com/package/@wiris/mathtype-ckeditor5) package:
+
+```bash
+npm install --save @wiris/mathtype-ckeditor5
+```
+
+Then add it to your plugin list and the toolbar configuration:
+
+```js
+import MathType from '@wiris/mathtype-ckeditor5';
+
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ MathType, ... ],
+		toolbar: [ 'MathType', 'ChemType', ... ]
+	} )
+	.then( ... )
+	.catch( ... );
+```
+
+<info-box info>
+	Read more about {@link builds/guides/integration/installing-plugins installing plugins}.
+</info-box>

+ 91 - 0
docs/features/spell-checker.md

@@ -0,0 +1,91 @@
+---
+category: features
+menu-title: Spelling and grammar checking
+---
+
+# Proofreading, spelling and grammar checking
+
+{@snippet build-classic-source}
+
+<info-box>
+	The spell checker for CKEditor 5 is a commercial solution provided by our partner, [WebSpellChecker](https://webspellchecker.com/). You can report any issues in its [GitHub repository](https://github.com/WebSpellChecker/wproofreader). The license can be purchased [here](https://ckeditor.com/contact/).
+</info-box>
+
+[WProofreader](https://webspellchecker.com/wsc-proofreader) is an innovative proofreading tool that combines the functionality of "spell check as you type" and "spell check in a dialog" in a modern, distraction-free UI. Spelling and grammar suggestions are available on hover with no clicking needed.
+
+## Demo
+
+Click in the editor below to enable the spelling and grammar checking. Hover an underlined word to display the proofreader suggestions for any of the spelling and grammar mistakes found.
+
+The proofreader badge in the bottom right-hand corner shows you the number of mistakes detected. It also gives you access to proofreader settings. If you want to see an overview of all spelling and grammar mistakes, click the "Proofread in dialog" icon in the badge.
+
+{@snippet features/wproofreader}
+
+## Supported languages
+
+By default the spell checker supports 17 languages: American English, British English, Brazilian Portuguese, Canadian English, Canadian French, Danish, Dutch, Finnish, French, German, Greek, Italian, Norwegian Bokmal, Portuguese, Spanish, Swedish and Ukrainian. Grammar checking is available for 15 of them &mdash; there is no grammar checking for Finnish and Norwegian.
+
+There are also over 150 additional languages and specialized dictionaries such as medical and legal available for an additional fee. You can check the full list [here](https://webspellchecker.com/additional-dictionaries/).
+
+## Installation
+
+WProofreader is installed separately from CKEditor 5 and does not need to be combined into an editor build as other features. To use this tool, it is necessary to load the WProofreader script on your page and provide the configuration.
+
+The proofreader can be used either as a [cloud solution](#wproofreader-cloud) or [hosted on your own server](#wproofreader-server).
+
+### WProofreader Cloud
+
+After signing up for a [trial or paid version](https://ckeditor.com/contact/), you will receive your service ID which is used to activate the service.
+
+Add the following configuration to your page:
+
+```html
+<script>
+	window.WEBSPELLCHECKER_CONFIG = {
+		autoSearch: true,
+		enableGrammar: true,
+		serviceId: 'your-service-ID'
+	};
+</script>
+```
+
+And then load the proofreader script:
+
+```html
+<script src="https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js"></script>
+```
+
+Refer to the [official documentation](https://github.com/WebSpellChecker/wproofreader#wproofreader-cloud) for more details about the cloud setup and available configuration options.
+
+### WProofreader Server
+
+After signing up for a [trial or paid version](https://ckeditor.com/contact/), you will receive access to the WebSpellChecker Server package to install on your own server.
+
+You will need to add the following configuration to your page:
+
+```html
+<script>
+	window.WEBSPELLCHECKER_CONFIG = {
+		autoSearch: true,
+		enableGrammar: true,
+		servicePort: '2880',
+		servicePath: '/'
+	};
+</script>
+```
+
+Then specify the path to the service on your page:
+
+```html
+<script src="http(s)://your_host_name/spellcheck/wscbundle/wscbundle.js"></script>
+```
+
+Refer to the [official documentation](https://github.com/WebSpellChecker/wproofreader#wproofreader-server) for more details about the server setup and available configuration options.
+
+## Configuration
+
+WProofreader configuration is set outside the CKEditor 5 configuration. Refer to the [WProofreader API](http://dev.webspellchecker.net/api/wscbundle/) for further information.
+
+## Contribute
+
+You can report issues and request features in the [official WProofreader repository](https://github.com/WebSpellChecker/wproofreader/issues).

Файловите разлики са ограничени, защото са твърде много
+ 70 - 21
docs/features/ui-language.md


+ 1 - 1
docs/framework/guides/contributing/contributing.md

@@ -87,7 +87,7 @@ Some additional things you should keep in mind:
 * Make sure you signed the [Contributor License Agreement (CLA)](#contributor-license-agreement-cla) and that tests pass. Test your changes!
 
 <info-box>
-	If want your changes to be permanent in your development environment, make sure your `mgit.json` file {@link framework/guides/contributing/development-environment#using-mgit-for-custom-packages points to your forked version of the repository} so next time you execute `mgit sync` to refresh the project, the utility will use your fork.
+	If want your changes to be permanent in your development environment, make sure your `mrgit.json` file {@link framework/guides/contributing/development-environment#using-mrgit-for-custom-packages points to your forked version of the repository} so next time you execute `mrgit sync` to refresh the project, the utility will use your fork.
 </info-box>
 
 ## Translating

+ 29 - 18
docs/framework/guides/contributing/development-environment.md

@@ -8,7 +8,7 @@ order: 10
 The CKEditor 5 codebase is divided into multiple [npm](http://npmjs.com/) packages, each developed in a separate Git repository. The main package is [`ckeditor5`](https://github.com/ckeditor/ckeditor5) which installs all project dependencies and various development-related resources such as:
 
 * the testing environment setup,
-* configuration for [mgit](https://www.npmjs.com/package/mgit2) (a multi-repo management tool) and [Yarn](https://yarnpkg.com/) (a dependency management tool),
+* configuration for [Mr. Git](https://www.npmjs.com/package/mrgit) (a multi-repo management tool) and [Yarn](https://yarnpkg.com/) (a dependency management tool),
 * translation management tools,
 * documentation generator,
 * and release tools.
@@ -26,13 +26,13 @@ In order to start developing CKEditor 5 you will require:
 
 First, you need to install a couple of tools which you will be using later:
 
-* [mgit2](https://www.npmjs.com/package/mgit2) &mdash; A multi-repo management tool,
+* [mrgit](https://www.npmjs.com/package/mrgit) &mdash; A multi-repo management tool,
 * [Yarn](https://yarnpkg.com/) &mdash; A dependency management tool.
 
 It is best to install them globally in your system for an easier use later on:
 
 ```bash
-npm install -g yarn mgit2
+npm install -g yarn mrgit
 ```
 
 **Note:** [Read how to avoid using `sudo` to install packages globally](https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md) or use [nvm](https://github.com/creationix/nvm).
@@ -56,12 +56,12 @@ yarn install
 
 The steps above should install all the packages from npm, which means that you will have the latest releases of all of them. They are available in `node_modules/@ckeditor/` (we are using [scoped packages](https://docs.npmjs.com/misc/scope), hence the unusual directory).
 
-In order to work with development versions of all the official packages, it is recommended to use mgit. This tool will clone all package repositories to the `packages/` directory. Then, those packages need to be installed in a way understandable by Node.js-compliant tools (like webpack or Browserify). In order to achieve that we use Yarn's feature called [workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) which creates symlinks to these packages.
+In order to work with development versions of all the official packages, it is recommended to use `mrgit`. This tool will clone all package repositories to the `packages/` directory. Then, those packages need to be installed in a way understandable by Node.js-compliant tools (like webpack or Browserify). In order to achieve that we use Yarn's feature called [workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) which creates symlinks to these packages.
 
 First, clone all the repositories:
 
 ```bash
-mgit sync
+mrgit sync
 ```
 
 Expected result:
@@ -138,7 +138,7 @@ Whenever you want to update all packages to their latest versions call:
 git pull
 
 # To update pull changes to all the packages:
-mgit sync
+mrgit sync
 
 # To install missing dependencies:
 yarn install
@@ -151,23 +151,23 @@ git pull
 yarn run reinstall
 ```
 
-The `reinstall` script first calls `yarn run clean` to remove `node_modules/` directories from all packages (including `ckeditor5`) and then `yarn run bootstrap` which is a shorthand for `mgit sync && yarn install`.
+The `reinstall` script first calls `yarn run clean` to remove `node_modules/` directories from all packages (including `ckeditor5`) and then `yarn run bootstrap` which is a shorthand for `mrgit sync && yarn install`.
 
 ### Working with multiple repositories
 
-Mgit implements many useful commands, such as:
+Mr. Git implements many useful commands, such as:
 
-* `mgit exec 'command'` – executing a shell command in all repositories,
-* `mgit checkout <branch>` – checking all repositories to given branch (or hash),
-* `mgit status` – displaying information about all repositories.
+* `mrgit exec 'command'` – executing a shell command in all repositories,
+* `mrgit checkout <branch>` – checking all repositories to given branch (or hash),
+* `mrgit status` – displaying information about all repositories.
 
-Read more about those commands in [mgit's documentation](https://github.com/cksource/mgit2).
+Read more about those commands in [mrgit's documentation](https://github.com/cksource/mrgit).
 
-Mgit has been developed by the [CKSource team](https://cksource.com/) and we are relying on it heavily, hence you can expect more features and improvements to come. However, it is not a CKEditor-specific tool and should be suitable for any multi-repository project (though it best fits JavaScript projects).
+Mr. Git has been developed by the [CKSource team](https://cksource.com/) and we are relying on it heavily, hence you can expect more features and improvements to come. However, it is not a CKEditor-specific tool and should be suitable for any multi-repository project (though it best fits JavaScript projects).
 
-### Using mgit for custom packages
+### Using `mrgit` for custom packages
 
-If you are developing custom packages or forked any of the official packages and want mgit to work with it, change the dependencies configuration in [`mgit.json`](https://github.com/ckeditor/ckeditor5/blob/master/mgit.json). Note that mgit is able to clone the package from any Git URL. Refer to [its documentation](https://github.com/cksource/mgit2) for more details.
+If you are developing custom packages or forked any of the official packages and want `mrgit` to work with it, change the dependencies configuration in [`mrgit.json`](https://github.com/ckeditor/ckeditor5/blob/master/mrgit.json). Note that `mrgit` is able to clone the package from any Git URL. Refer to [its documentation](https://github.com/cksource/mrgit) for more details.
 
 ## Running tests
 
@@ -193,7 +193,7 @@ To create a server for manual tests use the `manual` task:
 yarn run manual
 ```
 
-It accepts the `--source-map` (`-s`) option. Note that it watches for changes in the JavaScript files only (see the [bug](https://github.com/ckeditor/ckeditor5-dev/issues/52)).
+It accepts the `--source-map` (`-s`) and `--additionalLanguages="ar,pl,..."` options. Note that it watches for changes in the JavaScript files only (see the [bug](https://github.com/ckeditor/ckeditor5-dev/issues/52)).
 
 You can read more about the {@link framework/guides/contributing/testing-environment Testing environment}.
 
@@ -223,11 +223,22 @@ Note: These arguments must be passed after additional `--`:
 yarn run docs --skip-api
 ```
 
+## Generating content styles
+
+It is possible to generate a stylesheet containing content styles brought by all CKEditor 5 features. In order to do that, execute:
+
+```bash
+yarn docs:content-styles
+```
+The stylesheet will be saved in the `build/content-styles` folder.
+
+To learn more, refer to the {@link builds/guides/integration/content-styles Content styles} guide.
+
 ## Bisecting through a multi-repository
 
 CKEditor 5 is a multi-repository project. It means that [`git bisect`](https://git-scm.com/docs/git-bisect) (which is super handy when tracking which commit introduced a bug) will not work out of the box.
 
-Fortunately, every commit made to any of the `master` branches of all CKEditor 5 subpackages will update this subpackage's hash in `mgit.json` in the [`master-revisions`](https://github.com/ckeditor/ckeditor5/commits/master-revisions) branch.
+Fortunately, every commit made to any of the `master` branches of all CKEditor 5 subpackages will update this subpackage's hash in `mrgit.json` in the [`master-revisions`](https://github.com/ckeditor/ckeditor5/commits/master-revisions) branch.
 
 Thanks to that, `master-revisions` contains an ordered history of all changes which makes it possible to go back to any point in history:
 
@@ -240,7 +251,7 @@ git pull
 git co master-revisions~30
 
 # Check out subpackages to correct hashes.
-mgit co
+mrgit co
 ```
 
 Once you found the point in history which interests you, you can go straight to a commit in a subpackage and PR. For example:

+ 5 - 1
docs/framework/guides/contributing/testing-environment.md

@@ -25,6 +25,7 @@ It accepts the following arguments (must be passed after the `--` option):
 * `--verbose` (alias `-v`) &ndash; Allows switching on webpack logs.
 * `--files` &ndash; Specifies tests files to run. Accepts a package name or a glob. Read more about the [rules for converting the `--files` option to a glob pattern](https://github.com/ckeditor/ckeditor5-dev/tree/master/packages/ckeditor5-dev-tests#rules-for-converting---files-option-to-glob-pattern).
 * `--browsers` &ndash; Browsers which will be used to run the tests. Defaults to `Chrome`.
+* `--debug` (alias `-d`) &ndash; Allows specifying custom debug flags. For example, the `--debug engine` option uncomments the `// @if CK_DEBUG_ENGINE //` lines in the code. The `--debug false` option turns the debugging mechanism off and leaves the lines starting with `// @if CK_DEBUG //` untouched.
 
 ### Examples
 
@@ -50,7 +51,10 @@ yarn run test -cw --files=basic-styles/bold*.js
 
 In order to start the manual tests server use the `yarn run manual` task.
 
-The task accepts the `--source-map` (alias `-s`) option.
+The task accepts the following options:
+
+* `--source-map` (alias `-s`) that generates useful source maps for the code.
+* `--additionalLanguages="ar,pl,..."` that passes extra languages to the [CKEditor 5 webpack plugin](https://www.npmjs.com/package/@ckeditor/ckeditor5-dev-webpack-plugin). Check out the {@link features/ui-language UI language guide} to learn more.
 
 It starts the server available at http://localhost:8125.
 

+ 2 - 2
docs/framework/guides/development-tools.md

@@ -60,8 +60,8 @@ You can specify the name of the editor when attaching to make working with multi
 
 ```js
 // Inspecting two editor instances at the same time.
-CKEditorInspector.attach( 'header-editor' editor );
-CKEditorInspector.attach( 'body-editor' editor );
+CKEditorInspector.attach( 'header-editor', editor );
+CKEditorInspector.attach( 'body-editor', editor );
 ```
 
 The editor switcher is in the upper–right corner of the inspector panel.

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

@@ -26,9 +26,9 @@ First, install packages needed to build CKEditor 5:
 
 ```bash
 npm install --save \
-	postcss-loader \
-	raw-loader \
-	style-loader \
+	postcss-loader@3 \
+	raw-loader@3 \
+	style-loader@1 \
 	webpack@4 \
 	webpack-cli@3
 ```
@@ -56,14 +56,14 @@ module.exports = {
 	module: {
 		rules: [
 			{
-				// Or /ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/ if you want to limit this loader
+				// Or /ckeditor5-[^/]+\/theme\/icons\/.+\.svg$/ if you want to limit this loader
 				// to CKEditor 5 icons only.
 				test: /\.svg$/,
 
 				use: [ 'raw-loader' ]
 			},
 			{
-				// Or /ckeditor5-[^/]+\/theme\/[^/]+\.css$/ if you want to limit this loader
+				// Or /ckeditor5-[^/]+\/theme\/.+\.css$/ if you want to limit this loader
 				// to CKEditor 5 theme only.
 				test: /\.css$/,
 
@@ -71,7 +71,7 @@ module.exports = {
 					{
 						loader: 'style-loader',
 						options: {
-							singleton: true
+							injectType: 'singletonStyleTag'
 						}
 					},
 					{

+ 5 - 5
docs/framework/guides/tutorials/implementing-a-block-widget.md

@@ -5,7 +5,7 @@ order: 10
 
 # Implementing a block widget
 
-In this tutorial, you will learn how to implement a more complex CKEditor 5 plugin. 
+In this tutorial, you will learn how to implement a more complex CKEditor 5 plugin.
 
 You will build a "Simple box" feature which will allow the user to insert a custom box with a title and body fields into the document. You will use the widget utilities and work with the model-view conversion in order to properly set up the behavior of this feature. Later on, you will create a UI which will allow for inserting new simple boxes into the document with the toolbar button.
 
@@ -29,9 +29,9 @@ First, install packages needed to build and set up a basic CKEditor 5 instance.
 
 ```bash
 npm install --save \
-	postcss-loader \
-	raw-loader \
-	style-loader \
+	postcss-loader@3 \
+	raw-loader@3 \
+	style-loader@1 \
 	webpack@4 \
 	webpack-cli@3 \
 	@ckeditor/ckeditor5-dev-utils \
@@ -74,7 +74,7 @@ module.exports = {
 					{
 						loader: 'style-loader',
 						options: {
-							singleton: true
+							injectType: 'singletonStyleTag'
 						}
 					},
 					{

+ 4 - 4
docs/framework/guides/tutorials/implementing-an-inline-widget.md

@@ -25,9 +25,9 @@ First, install required dependencies:
 
 ```bash
 npm install --save \
-	postcss-loader \
-	raw-loader \
-	style-loader \
+	postcss-loader@3 \
+	raw-loader@3 \
+	style-loader@1 \
 	webpack@4 \
 	webpack-cli@3 \
 	@ckeditor/ckeditor5-basic-styles \
@@ -75,7 +75,7 @@ module.exports = {
 					{
 						loader: 'style-loader',
 						options: {
-							singleton: true
+							injectType: 'singletonStyleTag'
 						}
 					},
 					{

+ 8 - 1
docs/umberto.json

@@ -24,7 +24,9 @@
 		"features/image-upload.html": "features/image-upload/image-upload.html",
 		"features/ckfinder.html": "features/image-upload/ckfinder.html",
 		"features/easy-image.html": "features/image-upload/easy-image.html",
-		"features/collaboration/comments/integrate-comments-with-application.html": "features/collaboration/comments/comments-integration.html"
+		"features/collaboration/comments/integrate-comments-with-application.html": "features/collaboration/comments/comments-integration.html",
+		"features/collaboration/track-changes.html": "features/collaboration/track-changes/track-changes.html",
+		"features/paste-from-word.html": "features/pasting/paste-from-word.html"
 	},
 	"scripts": {
 		"snippet-adapter": "../scripts/docs/snippetadapter",
@@ -215,6 +217,11 @@
 					"name": "Image upload",
 					"id": "features-image-upload",
 					"slug": "image-upload"
+				},
+				{
+					"name": "Pasting",
+					"id": "features-pasting",
+					"slug": "pasting"
 				}
 			]
 		},

+ 1 - 7
mgit.json

@@ -1,9 +1,6 @@
 {
   "packages": "packages/",
-  "packagesPrefix": [
-    "@ckeditor/ckeditor-",
-    "@ckeditor/ckeditor5-"
-  ],
+  "packagesPrefix": "@ckeditor/ckeditor5-",
   "dependencies": {
     "@ckeditor/ckeditor-cloud-services-core": "ckeditor/ckeditor-cloud-services-core",
     "@ckeditor/ckeditor5-adapter-ckfinder": "ckeditor/ckeditor5-adapter-ckfinder",
@@ -52,8 +49,5 @@
     "@ckeditor/ckeditor5-widget": "ckeditor/ckeditor5-widget",
     "@ckeditor/ckeditor5-watchdog": "ckeditor/ckeditor5-watchdog",
     "@ckeditor/ckeditor5-word-count": "ckeditor/ckeditor5-word-count"
-  },
-  "overrideDirectoryNames": {
-    "@ckeditor/ckeditor-cloud-services-core": "ckeditor5-cloud-services-core"
   }
 }

+ 66 - 63
package.json

@@ -1,6 +1,6 @@
 {
   "name": "ckeditor5",
-  "version": "12.3.1",
+  "version": "12.4.0",
   "description": "The development environment of CKEditor 5 – the best browser-based rich text editor.",
   "private": true,
   "keywords": [
@@ -22,80 +22,82 @@
   ],
   "dependencies": {
     "@ckeditor/ckeditor-cloud-services-core": "^4.0.0",
-    "@ckeditor/ckeditor5-adapter-ckfinder": "^11.0.4",
-    "@ckeditor/ckeditor5-alignment": "^11.1.3",
-    "@ckeditor/ckeditor5-autoformat": "^11.0.4",
-    "@ckeditor/ckeditor5-autosave": "^11.0.4",
-    "@ckeditor/ckeditor5-basic-styles": "^11.1.3",
-    "@ckeditor/ckeditor5-block-quote": "^11.1.2",
-    "@ckeditor/ckeditor5-build-balloon": "^12.3.1",
-    "@ckeditor/ckeditor5-build-balloon-block": "^12.3.1",
-    "@ckeditor/ckeditor5-build-classic": "^12.3.1",
-    "@ckeditor/ckeditor5-build-decoupled-document": "^12.3.1",
-    "@ckeditor/ckeditor5-build-inline": "^12.3.1",
-    "@ckeditor/ckeditor5-ckfinder": "^11.0.4",
-    "@ckeditor/ckeditor5-clipboard": "^12.0.1",
-    "@ckeditor/ckeditor5-cloud-services": "^11.0.4",
-    "@ckeditor/ckeditor5-core": "^12.2.1",
-    "@ckeditor/ckeditor5-easy-image": "^11.0.4",
-    "@ckeditor/ckeditor5-editor-balloon": "^12.2.1",
-    "@ckeditor/ckeditor5-editor-classic": "^12.1.3",
-    "@ckeditor/ckeditor5-editor-decoupled": "^12.2.1",
-    "@ckeditor/ckeditor5-editor-inline": "^12.2.1",
-    "@ckeditor/ckeditor5-engine": "^13.2.1",
-    "@ckeditor/ckeditor5-enter": "^11.0.4",
-    "@ckeditor/ckeditor5-essentials": "^11.0.4",
-    "@ckeditor/ckeditor5-font": "^11.2.1",
-    "@ckeditor/ckeditor5-heading": "^11.0.4",
-    "@ckeditor/ckeditor5-highlight": "^11.0.4",
-    "@ckeditor/ckeditor5-image": "^13.1.2",
-    "@ckeditor/ckeditor5-indent": "^10.0.1",
-    "@ckeditor/ckeditor5-link": "^11.1.1",
-    "@ckeditor/ckeditor5-list": "^12.0.4",
-    "@ckeditor/ckeditor5-markdown-gfm": "^11.0.4",
-    "@ckeditor/ckeditor5-media-embed": "^11.1.3",
-    "@ckeditor/ckeditor5-mention": "^12.0.1",
-    "@ckeditor/ckeditor5-paragraph": "^11.0.4",
-    "@ckeditor/ckeditor5-paste-from-office": "^11.0.4",
-    "@ckeditor/ckeditor5-remove-format": "^10.0.3",
-    "@ckeditor/ckeditor5-table": "^13.0.2",
-    "@ckeditor/ckeditor5-theme-lark": "^14.1.1",
-    "@ckeditor/ckeditor5-typing": "^12.1.1",
-    "@ckeditor/ckeditor5-ui": "^13.0.2",
-    "@ckeditor/ckeditor5-undo": "^11.0.4",
-    "@ckeditor/ckeditor5-upload": "^11.1.1",
-    "@ckeditor/ckeditor5-utils": "^13.0.1",
-    "@ckeditor/ckeditor5-watchdog": "^10.0.1",
-    "@ckeditor/ckeditor5-widget": "^11.0.4",
-    "@ckeditor/ckeditor5-word-count": "^10.0.1"
+    "@ckeditor/ckeditor5-adapter-ckfinder": "^11.0.5",
+    "@ckeditor/ckeditor5-alignment": "^11.2.0",
+    "@ckeditor/ckeditor5-autoformat": "^11.0.5",
+    "@ckeditor/ckeditor5-autosave": "^11.0.5",
+    "@ckeditor/ckeditor5-basic-styles": "^11.1.4",
+    "@ckeditor/ckeditor5-block-quote": "^11.1.3",
+    "@ckeditor/ckeditor5-build-balloon": "^12.4.0",
+    "@ckeditor/ckeditor5-build-balloon-block": "^12.4.0",
+    "@ckeditor/ckeditor5-build-classic": "^12.4.0",
+    "@ckeditor/ckeditor5-build-decoupled-document": "^12.4.0",
+    "@ckeditor/ckeditor5-build-inline": "^12.4.0",
+    "@ckeditor/ckeditor5-ckfinder": "^11.0.5",
+    "@ckeditor/ckeditor5-clipboard": "^12.0.2",
+    "@ckeditor/ckeditor5-cloud-services": "^11.0.5",
+    "@ckeditor/ckeditor5-core": "^12.3.0",
+    "@ckeditor/ckeditor5-easy-image": "^11.0.5",
+    "@ckeditor/ckeditor5-editor-balloon": "^12.2.2",
+    "@ckeditor/ckeditor5-editor-classic": "^12.1.4",
+    "@ckeditor/ckeditor5-editor-decoupled": "^12.2.2",
+    "@ckeditor/ckeditor5-editor-inline": "^12.3.0",
+    "@ckeditor/ckeditor5-engine": "^14.0.0",
+    "@ckeditor/ckeditor5-enter": "^11.1.0",
+    "@ckeditor/ckeditor5-essentials": "^11.0.5",
+    "@ckeditor/ckeditor5-font": "^11.2.2",
+    "@ckeditor/ckeditor5-heading": "^11.0.5",
+    "@ckeditor/ckeditor5-highlight": "^11.0.5",
+    "@ckeditor/ckeditor5-image": "^14.0.0",
+    "@ckeditor/ckeditor5-indent": "^10.1.0",
+    "@ckeditor/ckeditor5-link": "^11.1.2",
+    "@ckeditor/ckeditor5-list": "^12.1.0",
+    "@ckeditor/ckeditor5-markdown-gfm": "^11.0.5",
+    "@ckeditor/ckeditor5-media-embed": "^11.1.4",
+    "@ckeditor/ckeditor5-mention": "^13.0.0",
+    "@ckeditor/ckeditor5-paragraph": "^11.0.5",
+    "@ckeditor/ckeditor5-paste-from-office": "^11.1.0",
+    "@ckeditor/ckeditor5-remove-format": "^10.0.4",
+    "@ckeditor/ckeditor5-table": "^14.0.0",
+    "@ckeditor/ckeditor5-theme-lark": "^14.2.0",
+    "@ckeditor/ckeditor5-typing": "^12.2.0",
+    "@ckeditor/ckeditor5-ui": "^14.0.0",
+    "@ckeditor/ckeditor5-undo": "^11.0.5",
+    "@ckeditor/ckeditor5-upload": "^12.0.0",
+    "@ckeditor/ckeditor5-utils": "^14.0.0",
+    "@ckeditor/ckeditor5-watchdog": "^11.0.0",
+    "@ckeditor/ckeditor5-widget": "^11.1.0",
+    "@ckeditor/ckeditor5-word-count": "^10.0.2"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-comments": "^3.2.0",
-    "@ckeditor/ckeditor5-dev-docs": "^11.0.2",
-    "@ckeditor/ckeditor5-dev-env": "^14.1.1",
-    "@ckeditor/ckeditor5-dev-tests": "^16.4.0",
-    "@ckeditor/ckeditor5-dev-utils": "^12.0.1",
-    "@ckeditor/ckeditor5-dev-webpack-plugin": "^8.0.1",
-    "@ckeditor/ckeditor5-inspector": "^1.2.0",
-    "@ckeditor/ckeditor5-real-time-collaboration": "^12.3.0",
-    "@ckeditor/ckeditor5-track-changes": "^1.0.0",
+    "@ckeditor/ckeditor5-comments": "^4.0.0",
+    "@ckeditor/ckeditor5-dev-docs": "^11.0.5",
+    "@ckeditor/ckeditor5-dev-env": "^16.0.0",
+    "@ckeditor/ckeditor5-dev-tests": "^16.7.1",
+    "@ckeditor/ckeditor5-dev-utils": "^12.0.3",
+    "@ckeditor/ckeditor5-dev-webpack-plugin": "^8.0.3",
+    "@ckeditor/ckeditor5-inspector": "^1.3.0",
+    "@ckeditor/ckeditor5-real-time-collaboration": "^12.4.0",
+    "@ckeditor/ckeditor5-track-changes": "^1.1.0",
+    "@wiris/mathtype-ckeditor5": "^7.16.1",
     "css-loader": "^1.0.0",
     "eslint": "^5.5.0",
     "eslint-config-ckeditor5": "^2.0.0",
+    "file-loader": "^4.1.0",
     "glob": "^7.1.2",
     "husky": "^1.3.1",
     "lint-staged": "^7.0.0",
-    "mgit2": "^0.10.0",
     "mini-css-extract-plugin": "^0.4.0",
     "minimatch": "^3.0.4",
+    "mrgit": "^1.0.0",
     "postcss-loader": "^3.0.0",
     "progress-bar-webpack-plugin": "^1.12.1",
-    "raw-loader": "^1.0.0",
-    "style-loader": "^0.23.0",
+    "raw-loader": "^3.1.0",
+    "style-loader": "^1.0.0",
     "svgo": "^1.1.0",
-    "uglifyjs-webpack-plugin": "^1.2.7",
+    "uglifyjs-webpack-plugin": "^1.3.0",
     "umberto": "^1.0.0",
-    "webpack": "^4.15.0"
+    "webpack": "^4.39.1"
   },
   "engines": {
     "node": ">=8.0.0",
@@ -113,14 +115,15 @@
     "lint": "eslint --quiet '**/*.js'",
     "test": "node --max_old_space_size=4096 node_modules/@ckeditor/ckeditor5-dev-tests/bin/test.js",
     "manual": "node --max_old_space_size=4096 node_modules/@ckeditor/ckeditor5-dev-tests/bin/test-manual.js",
-    "bootstrap": "mgit sync && yarn install",
-    "clean": "rm -rf node_modules && mgit exec 'rm -rf node_modules'",
+    "bootstrap": "mrgit sync && yarn install",
+    "clean": "rm -rf node_modules && mrgit exec 'rm -rf node_modules'",
     "reset": "rm -rf ./packages ./node_modules && yarn run bootstrap",
     "reinstall": "yarn run clean && yarn run bootstrap",
     "docs": "node --max-old-space-size=4096 ./scripts/docs/build-docs.js",
     "docs:api": "node ./scripts/docs/build-api-docs.js",
     "docs:build-and-publish": "node ./scripts/docs/build-and-publish.js",
     "docs:build-and-publish-nightly": "node ./scripts/docs/build-and-publish-nightly.js",
+    "docs:content-styles": "node ./scripts/docs/build-content-styles.js",
     "translations:collect": "ckeditor5-dev-env-translations collect",
     "translations:download": "ckeditor5-dev-env-translations download",
     "translations:upload": "ckeditor5-dev-env-translations upload",

+ 3 - 3
scripts/bump-year.js

@@ -10,14 +10,14 @@
 /*
 
 Usage:
-mgit exec 'node ../../scripts/bump-year.js'
+mrgit exec 'node ../../scripts/bump-year.js'
 node scripts/bump-year.js
 
 Full command to update the entire project:
-git pull && mgit sync && mgit exec 'node ../../scripts/bump-year.js' && node scripts/bump-year.js
+git pull && mrgit sync && mrgit exec 'node ../../scripts/bump-year.js' && node scripts/bump-year.js
 
 And after reviewing the changes:
-mgit commit -m "Internal: Bumped the year. [skip ci]" && mgit push git commit -am "Internal: Bumped the year." && git push
+mrgit commit -m "Internal: Bumped the year. [skip ci]" && mrgit push git commit -am "Internal: Bumped the year." && git push
 
 */
 

+ 241 - 0
scripts/docs/build-content-styles.js

@@ -0,0 +1,241 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* eslint-env node */
+
+const path = require( 'path' );
+const fs = require( 'fs' );
+const webpack = require( 'webpack' );
+const { styles } = require( '@ckeditor/ckeditor5-dev-utils' );
+const { version } = require( '../../package.json' );
+
+const DESTINATION_DIRECTORY = path.join( __dirname, '..', '..', 'build', 'content-styles' );
+const DOCUMENTATION_URL = 'https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/content-styles.html';
+const VARIABLE_DEFINITION_REGEXP = /(--[\w-]+):\s+(.*);/g;
+const VARIABLE_USAGE_REGEXP = /var\((--[\w-]+)\)/g;
+
+const contentRules = {
+	selector: [],
+	variables: []
+};
+
+const webpackConfig = getWebpackConfig();
+const packagesPath = path.join( process.cwd(), 'packages' );
+
+runWebpack( webpackConfig )
+	.then( () => {
+		// All variables are placed inside the `:root` selector. Let's extract their names and values as a map.
+		const cssVariables = new Map( contentRules.variables
+			.map( rule => {
+				// Let's extract all of them as an array of pairs: [ name, value ].
+				const allRules = [];
+				let match;
+
+				while ( ( match = VARIABLE_DEFINITION_REGEXP.exec( rule.css ) ) ) {
+					allRules.push( [ match[ 1 ], match[ 2 ] ] );
+				}
+
+				return allRules;
+			} )
+			.reduce( ( previousValue, currentValue ) => {
+				// And simplify nested arrays as a flattened array.
+				previousValue.push( ...currentValue );
+
+				return previousValue;
+			}, [] ) );
+
+		// CSS variables that are used by the `.ck-content` selector.
+		const usedVariables = new Set();
+
+		const selectorCss = contentRules.selector
+			.map( rule => {
+				// Removes all comments from the rule definition.
+				const cssAsArray = rule.css.replace( /\/\*[^*]+\*\//g, '' ).split( '\n' );
+
+				// We want to fix invalid indentations. We need to find a number of how many indentations we want to remove.
+				// Because the last line ends the block, we can use this value.
+				const lastLineIndent = cssAsArray[ cssAsArray.length - 1 ].length - 1;
+
+				const css = cssAsArray
+					.filter( line => line.trim().length > 0 )
+					.map( ( line, index ) => {
+						// Do not touch the first line. It is always correct.
+						if ( index === 0 ) {
+							return line;
+						}
+
+						return line.slice( lastLineIndent );
+					} )
+					.join( '\n' );
+
+				return `/* ${ rule.file.replace( packagesPath + path.sep, '' ) } */\n${ css }`;
+			} )
+			.filter( rule => {
+				// 1st: path to the CSS file, 2nd: selector definition - start block, 3rd: end block
+				// If the rule contains only 3 lines, it means that it does not define any rules.
+				return rule.split( '\n' ).length > 3;
+			} )
+			.join( '\n' );
+
+		// Find all CSS variables inside the `.ck-content` selector.
+		let match;
+
+		while ( ( match = VARIABLE_USAGE_REGEXP.exec( selectorCss ) ) ) {
+			usedVariables.add( match[ 1 ] );
+		}
+
+		// We need to also look at whether any of the used variables requires the value of other variables.
+		let clearRun = false;
+
+		// We need to process all variables as long as the entire collection won't be changed.
+		while ( !clearRun ) {
+			clearRun = true;
+
+			// For every used variable...
+			for ( const variable of usedVariables ) {
+				const value = cssVariables.get( variable );
+
+				let match;
+
+				// ...find its value and check whether it requires another variable.
+				while ( ( match = VARIABLE_USAGE_REGEXP.exec( value ) ) ) {
+					// If so, mark the entire `while()` block as it should be checked once again.
+					// Also, add the new variable to the used variables collection.
+					if ( !usedVariables.has( match[ 1 ] ) ) {
+						clearRun = false;
+						usedVariables.add( match[ 1 ] );
+					}
+				}
+			}
+		}
+
+		// Build the final content of the CSS file.
+		let data = [
+			'/*',
+			` * CKEditor 5 (v${ version }) content styles.`,
+			` * Generated on ${ new Date().toUTCString() }.`,
+			` * For more information, check out ${ DOCUMENTATION_URL }`,
+			' */\n\n',
+		].join( '\n' );
+
+		data += ':root {\n';
+
+		for ( const variable of [ ...usedVariables ].sort() ) {
+			data += `\t${ variable }: ${ cssVariables.get( variable ) };\n`;
+		}
+
+		data += '}\n\n';
+		data += selectorCss;
+
+		return writeFile( path.join( DESTINATION_DIRECTORY, 'content-styles.css' ), data );
+	} )
+	.then( () => {
+		console.log( `Content styles have been extracted to ${ path.join( DESTINATION_DIRECTORY, 'content-styles.css' ) }` );
+	} )
+	.catch( err => {
+		console.log( err );
+	} );
+
+/**
+ * Prepares the configuration for webpack.
+ *
+ * @returns {Object}
+ */
+function getWebpackConfig() {
+	const postCssConfig = styles.getPostCssConfig( {
+		themeImporter: {
+			themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' )
+		},
+		minify: false
+	} );
+
+	const contentStylesPlugin = require( './content-styles/list-content-styles' )( { contentRules } );
+
+	postCssConfig.plugins.push( contentStylesPlugin );
+
+	return {
+		mode: 'development',
+
+		devtool: 'source-map',
+
+		entry: {
+			ckeditor5: path.join( __dirname, 'content-styles', 'ckeditor.js' )
+		},
+
+		output: {
+			path: DESTINATION_DIRECTORY,
+			filename: '[name].js'
+		},
+
+		// Configure the paths so building CKEditor 5 snippets work even if the script
+		// is triggered from a directory outside `ckeditor5` (e.g. in a multi-project case).
+		resolve: {
+			modules: getModuleResolvePaths()
+		},
+
+		resolveLoader: {
+			modules: getModuleResolvePaths()
+		},
+
+		module: {
+			rules: [
+				{
+					test: /\.svg$/,
+					use: [ 'raw-loader' ]
+				},
+				{
+					test: /\.css$/,
+					use: [
+						'style-loader',
+						{
+							loader: 'postcss-loader',
+							options: postCssConfig
+						}
+					]
+				}
+			]
+		}
+	};
+}
+
+/**
+ * @param {Object} webpackConfig
+ * @returns {Promise}
+ */
+function runWebpack( webpackConfig ) {
+	return new Promise( ( resolve, reject ) => {
+		webpack( webpackConfig, ( err, stats ) => {
+			if ( err ) {
+				reject( err );
+			} else if ( stats.hasErrors() ) {
+				reject( new Error( stats.toString() ) );
+			} else {
+				resolve();
+			}
+		} );
+	} );
+}
+
+/**
+ * @returns {Array.<String>}
+ */
+function getModuleResolvePaths() {
+	return [
+		path.resolve( __dirname, '..', '..', 'node_modules' ),
+		'node_modules'
+	];
+}
+
+function writeFile( file, data ) {
+	return new Promise( ( resolve, reject ) => {
+		fs.writeFile( file, data, err => {
+			if ( err ) {
+				return reject( err );
+			}
+
+			return resolve();
+		} );
+	} );
+}

+ 76 - 0
scripts/docs/content-styles/ckeditor.js

@@ -0,0 +1,76 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+// The editor creator to use.
+import ClassicEditorBase from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+
+import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
+import UploadAdapter from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
+import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Code from '@ckeditor/ckeditor5-basic-styles/src/code';
+import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
+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 Underline from '@ckeditor/ckeditor5-basic-styles/src/underline';
+import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote';
+import CKFinder from '@ckeditor/ckeditor5-ckfinder/src/ckfinder';
+import EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage';
+import Heading from '@ckeditor/ckeditor5-heading/src/heading';
+import Image from '@ckeditor/ckeditor5-image/src/image';
+import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
+import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize';
+import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle';
+import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar';
+import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload';
+import Link from '@ckeditor/ckeditor5-link/src/link';
+import List from '@ckeditor/ckeditor5-list/src/list';
+import TodoList from '@ckeditor/ckeditor5-list/src/todolist';
+import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice';
+import Table from '@ckeditor/ckeditor5-table/src/table';
+import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
+import Font from '@ckeditor/ckeditor5-font/src/font';
+import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight';
+import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment';
+
+export default class ClassicEditor extends ClassicEditorBase {}
+
+// Plugins to include in the build.
+ClassicEditor.builtinPlugins = [
+	Essentials,
+	UploadAdapter,
+	Autoformat,
+	Bold,
+	Code,
+	Italic,
+	Strikethrough,
+	Subscript,
+	Superscript,
+	Underline,
+	BlockQuote,
+	CKFinder,
+	EasyImage,
+	Heading,
+	Image,
+	ImageCaption,
+	ImageResize,
+	ImageStyle,
+	ImageToolbar,
+	ImageUpload,
+	Link,
+	List,
+	TodoList,
+	MediaEmbed,
+	Paragraph,
+	PasteFromOffice,
+	Table,
+	TableToolbar,
+	Font,
+	Highlight,
+	Alignment
+];

+ 35 - 0
scripts/docs/content-styles/list-content-styles.js

@@ -0,0 +1,35 @@
+#!/usr/bin/env node
+
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* eslint-env node */
+
+const postcss = require( 'postcss' );
+
+module.exports = postcss.plugin( 'list-content-styles', function( options ) {
+	const selectorStyles = options.contentRules.selector;
+	const variables = options.contentRules.variables;
+
+	return root => {
+		root.walkRules( rule => {
+			rule.selectors.forEach( selector => {
+				if ( selector.match( ':root' ) ) {
+					variables.push( {
+						file: root.source.input.file,
+						css: rule.toString()
+					} );
+				}
+
+				if ( selector.match( '.ck-content' ) ) {
+					selectorStyles.push( {
+						file: root.source.input.file,
+						css: rule.toString()
+					} );
+				}
+			} );
+		} );
+	};
+} );

+ 56 - 3
scripts/docs/snippetadapter.js

@@ -16,6 +16,7 @@ const UglifyJsWebpackPlugin = require( 'uglifyjs-webpack-plugin' );
 const ProgressBarPlugin = require( 'progress-bar-webpack-plugin' );
 
 const DEFAULT_LANGUAGE = 'en';
+const MULTI_LANGUAGE = 'multi-language';
 
 /**
  * @param {Set.<Snippet>} snippets Snippet collection extracted from documentation files.
@@ -91,6 +92,12 @@ module.exports = function snippetAdapter( snippets, options, umbertoHelpers ) {
 	// Group snippets by language. There is no way to build different languages in a single Webpack process.
 	// Webpack must be called as many times as different languages are being used in snippets.
 	for ( const snippetData of snippets ) {
+		// Multi-languages editors must be built separately.
+		if ( snippetData.snippetConfig.additionalLanguages ) {
+			snippetData.snippetConfig.additionalLanguages.push( snippetData.snippetConfig.language );
+			snippetData.snippetConfig.language = MULTI_LANGUAGE;
+		}
+
 		if ( !groupedSnippetsByLanguage[ snippetData.snippetConfig.language ] ) {
 			groupedSnippetsByLanguage[ snippetData.snippetConfig.language ] = new Set();
 		}
@@ -178,6 +185,13 @@ module.exports = function snippetAdapter( snippets, options, umbertoHelpers ) {
 					if ( wasCSSGenerated ) {
 						cssFiles.unshift( path.join( snippetData.relativeOutputPath, snippetData.snippetName, 'snippet.css' ) );
 					}
+
+					// Additional languages must be imported by the HTML code.
+					if ( snippetData.snippetConfig.additionalLanguages ) {
+						snippetData.snippetConfig.additionalLanguages.forEach( language => {
+							jsFiles.push( path.join( snippetData.relativeOutputPath, 'translations', `${ language }.js` ) );
+						} );
+					}
 				}
 
 				const cssImportsHTML = getHTMLImports( cssFiles, importPath => {
@@ -261,6 +275,27 @@ function getWebpackConfig( snippets, config ) {
 		definitions[ definitionKey ] = JSON.stringify( config.definitions[ definitionKey ] );
 	}
 
+	const ckeditorWebpackPluginOptions = {};
+
+	if ( config.language === MULTI_LANGUAGE ) {
+		const additionalLanguages = new Set();
+
+		// Find all additional languages that must be built.
+		for ( const snippetData of snippets ) {
+			for ( const language of snippetData.snippetConfig.additionalLanguages ) {
+				additionalLanguages.add( language );
+			}
+		}
+
+		// Pass unique values of `additionalLanguages` to `CKEditorWebpackPlugin`.
+		ckeditorWebpackPluginOptions.additionalLanguages = [ ...additionalLanguages ];
+
+		// Also, set the default language because of the warning that comes from the plugin.
+		ckeditorWebpackPluginOptions.language = DEFAULT_LANGUAGE;
+	} else {
+		ckeditorWebpackPluginOptions.language = config.language;
+	}
+
 	const webpackConfig = {
 		mode: config.production ? 'production' : 'development',
 
@@ -288,9 +323,7 @@ function getWebpackConfig( snippets, config ) {
 
 		plugins: [
 			new MiniCssExtractPlugin( { filename: '[name]/snippet.css' } ),
-			new CKEditorWebpackPlugin( {
-				language: config.language
-			} ),
+			new CKEditorWebpackPlugin( ckeditorWebpackPluginOptions ),
 			new webpack.BannerPlugin( {
 				banner: bundler.getLicenseBanner(),
 				raw: true
@@ -332,6 +365,24 @@ function getWebpackConfig( snippets, config ) {
 							} )
 						}
 					]
+				},
+				// `file-loader` is used to handle assets introduced by 3rd party plugins.
+				// All guides in the documentation that could use images should be named as follow: `guide-type/guide-name`
+				//
+				// NOTE: You cannot use more than single slash `/` in the guide name.
+				// All images will be saved in the `snippets/` directory as `assets/images/[file]`.
+				// Unfortunately, compiled JS/CSS file that requires images will be looking for those assets in:
+				// `snippets/[guide-type/guide-name]/assets/images/` so we need to manually go up twice.
+				// ATM there is no easy way to find the number how many directories we need to go up so the assumption about names of
+				// the guides seems to be a safer solution.
+				{
+					test: /\.(png|jpe?g|gif)$/,
+					loader: 'file-loader',
+					options: {
+						name: config.production ? '[sha512:hash:base64:7].[ext]' : '[name].[ext]',
+						outputPath: path.join( 'assets', 'images' ),
+						publicPath: [ '..', '..', 'assets', 'images' ].join( '/' )
+					},
 				}
 			]
 		}
@@ -451,4 +502,6 @@ function getHTMLImports( files, mapFunction ) {
  * @property {String} [language] A language that will be used for building the editor.
  *
  * @property {Array.<String>} [dependencies] Names of samples that are required to working.
+ *
+ * @property {Array.<String>} [additionalLanguages] Additional languages that are required by the snippet.
  */

+ 0 - 39
scripts/release/update-mgit-branches.js

@@ -1,39 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-/* eslint-env node */
-
-'use strict';
-
-const branchName = process.argv[ 2 ];
-
-if ( !branchName ) {
-	throw new Error( 'Missing branch name.' );
-}
-
-const path = require( 'path' );
-const { tools, logger } = require( '@ckeditor/ckeditor5-dev-utils' );
-const log = logger();
-const mgitJsonPath = path.resolve( __dirname, '..', '..', 'mgit.json' );
-
-log.info( 'Updating the "mgit.json"...' );
-
-tools.updateJSONFile( mgitJsonPath, mgitJson => {
-	const dependencies = mgitJson.dependencies;
-
-	for ( const packageName of Object.keys( dependencies ) ) {
-		dependencies[ packageName ] = dependencies[ packageName ].split( '#' )[ 0 ];
-
-		if ( branchName !== 'master' ) {
-			dependencies[ packageName ] += '#' + branchName;
-		}
-	}
-
-	return mgitJson;
-} );
-
-log.info( `Done. "mgit.json" uses the "${ branchName }" branch now.` );

+ 7 - 19
scripts/update-stable-branches.sh

@@ -10,30 +10,18 @@ echo ""
 
 if [[ $REPLY =~ ^[Yy]$ ]]
 then
-	# Update the `stable` branch in the ckeditor5 repository.
+	# Update the `stable` branch in the `ckeditor5` repository.
 	git checkout stable && git merge master && git checkout master
 
-	# Add `stable` branches in all repos which don't have them yet.
-	mgit exec 'git checkout -b stable 2> /dev/null && git push origin stable && git checkout master'
+	# Add `#stable` branches in all repos which don't have them yet.
+	mrgit exec 'git checkout -b stable 2> /dev/null && git push origin stable && git checkout master'
 
-	# Update all `stable` branches in all packages.
-	mgit exec 'git checkout stable && git pull origin stable && git merge master && git checkout master'
+	# Update all `#stable` branches in all packages.
+	mrgit exec 'git checkout stable && git pull origin stable && git merge master && git checkout master'
 
-	# Make sure that `mgit.json` for `stable` and `master` branches is correct.
-	# `stable` branch.
-	git checkout stable && \
-	node ./scripts/release/update-mgit-branches stable && \
-	git commit -a -m "Internal: Use stable branches. [skip ci]"
-
-	# `master` branch.
-	git checkout master && \
-	git merge stable && \
-	node ./scripts/release/update-mgit-branches master && \
-	git commit -a -m "Internal: Use master branches. [skip ci]"
-
-	# Push the `stable` branches.
+	# Push the `#stable` branches.
 	git push origin stable master && \
-	mgit exec 'git push origin stable'
+	mrgit exec 'git push origin stable'
 
 	echo "Success! 🎂"
 fi

Файловите разлики са ограничени, защото са твърде много
+ 626 - 532
yarn.lock