Kaynağa Gözat

Merge branch 'master' into t/1061

Piotrek Koszuliński 7 yıl önce
ebeveyn
işleme
6a0a4904e0

+ 111 - 0
docs/_snippets/builds/saving-data/autosave.html

@@ -0,0 +1,111 @@
+<div id="snippet-autosave">
+	<p>Test me!</p>
+</div>
+
+<div class="snippet-autosave-header">
+	<div class="snippet-autosave-status">
+		<div class="snippet-autosave-status_label">Status:</div>
+		<div class="snippet-autosave-status_spinner">
+			<span class="snippet-autosave-status_spinner-label"></span>
+			<span class="snippet-autosave-status_spinner-loader"></span>
+		</div>
+	</div>
+
+	<div class="snippet-autosave-server">
+		<div class="snippet-autosave-server_label">HTTP server lag (ms):</div>
+		<input id="snippet-autosave-lag" type="number" value="500" step="100" min="0" max="9000">
+	</div>
+</div>
+
+<p>Server data:</p>
+
+<pre>
+	<code id="snippet-autosave-console"></code>
+</pre>
+
+<style>
+	.snippet-autosave-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		background: var(--ck-color-toolbar-background);
+		border: 1px solid var(--ck-color-toolbar-border);
+		padding: 10px;
+		border-radius: var(--ck-border-radius);
+		margin-top: -1.5em;
+		margin-bottom: 1.5em;
+		border-top: 0;
+		border-top-left-radius: 0;
+		border-top-right-radius: 0;
+	}
+
+	.snippet-autosave-status_spinner{
+		display: flex;
+		align-items: center;
+		position: relative;
+	}
+	.snippet-autosave-status_spinner-label {
+		position: relative;
+	}
+
+	.snippet-autosave-status_spinner-label::after {
+		content: 'Saved!';
+		color: green;
+		display: inline-block;
+		margin-right: var(--ck-spacing-medium);
+	}
+
+	/* During "Saving" display spinner and change content of label. */
+	.snippet-autosave-status.busy .snippet-autosave-status_spinner-label::after  {
+		content: 'Saving...';
+		color: red;
+	}
+
+	.snippet-autosave-status.busy .snippet-autosave-status_spinner-loader {
+		display: block;
+		width: 16px;
+		height: 16px;
+		border-radius: 50%;
+		border-top: 3px solid hsl(0, 0%, 70%);
+		border-right: 2px solid transparent;
+		animation: autosave-status-spinner 1s linear infinite;
+	}
+
+	.snippet-autosave-status,
+	.snippet-autosave-server {
+		display: flex;
+		align-items: center;
+	}
+
+	.snippet-autosave-server_label,
+	.snippet-autosave-status_label {
+		font-weight: bold;
+		margin-right: var(--ck-spacing-medium);
+	}
+
+	#snippet-autosave-lag {
+		padding: 4px;
+	}
+
+	#snippet-autosave-console {
+		/* Lets wrap content. */
+		max-height: 300px;
+		overflow: auto;
+		white-space: normal;
+		background: #2b2c26;
+		transition: 300ms;
+	}
+
+	#snippet-autosave-console.received {
+		animation: autosave-received 1s ease 1;
+	}
+
+	@keyframes autosave-status-spinner {
+		to { transform: rotate( 360deg ); }
+	}
+
+	@keyframes autosave-received {
+		from { background: green; }
+		to { background: #2b2c26; }
+	}
+</style>

+ 67 - 0
docs/_snippets/builds/saving-data/autosave.js

@@ -0,0 +1,67 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals ClassicEditor, console, window, document, setTimeout */
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+let HTTP_SERVER_LAG = 500;
+
+document.querySelector( '#snippet-autosave-lag' ).addEventListener( 'change', evt => {
+	HTTP_SERVER_LAG = evt.target.value;
+} );
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-autosave' ), {
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			viewportTopOffset: 60
+		},
+		autosave: {
+			save( editor ) {
+				return saveData( editor.getData() );
+			}
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+
+		displayStatus( editor );
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );
+
+function saveData( data ) {
+	return new Promise( resolve => {
+		// Fake HTTP server's lag.
+		setTimeout( () => {
+			log( data );
+
+			resolve();
+		}, HTTP_SERVER_LAG );
+	} );
+}
+
+function displayStatus( editor ) {
+	const pendingActions = editor.plugins.get( 'PendingActions' );
+	const statusIndicator = document.querySelector( '.snippet-autosave-status' );
+	const console = document.querySelector( '#snippet-autosave-console' );
+
+	pendingActions.on( 'change:hasAny', ( evt, propertyName, newValue ) => {
+		if ( newValue ) {
+			statusIndicator.classList.add( 'busy' );
+			console.classList.remove( 'received' );
+		} else {
+			statusIndicator.classList.remove( 'busy' );
+			console.classList.add( 'received' );
+		}
+	} );
+}
+
+function log( msg ) {
+	const console = document.querySelector( '#snippet-autosave-console' );
+	console.textContent = msg;
+}

+ 0 - 0
docs/_snippets/builds/saving-data/build-autosave-source.html


+ 14 - 0
docs/_snippets/builds/saving-data/build-autosave-source.js

@@ -0,0 +1,14 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals window */
+
+import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
+
+import Autosave from '@ckeditor/ckeditor5-autosave/src/autosave';
+
+ClassicEditor.builtinPlugins.push( Autosave );
+
+window.ClassicEditor = ClassicEditor;

+ 92 - 0
docs/_snippets/builds/saving-data/manualsave.html

@@ -0,0 +1,92 @@
+<div id="snippet-manual">
+	<p>Test me!</p>
+</div>
+
+<div class="snippet-manual-save-header">
+	<div class="snippet-manual-save-server">
+		<div class="snippet-manual-save-server_label">HTTP server lag (ms):</div>
+		<input id="snippet-manual-lag" type="number" value="500" step="100" min="0" max="9000">
+	</div>
+	<div class="snippet-manual-save-submit">
+		<input id="snippet-manual-save" type="submit" value="Save">
+	</div>
+</div>
+
+<p>Server data:</p>
+
+<pre>
+	<code id="snippet-manual-save-console"></code>
+</pre>
+
+<style>
+	.snippet-manual-save-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		background: var(--ck-color-toolbar-background);
+		border: 1px solid var(--ck-color-toolbar-border);
+		padding: 10px;
+		border-radius: var(--ck-border-radius);
+		margin-top: -1.5em;
+		margin-bottom: 1.5em;
+		border-top: 0;
+		border-top-left-radius: 0;
+		border-top-right-radius: 0;
+	}
+
+	.snippet-manual-save-server,
+	.snippet-manual-save-submit {
+		display: flex;
+		align-items: center;
+	}
+
+	.snippet-manual-save-server_label,
+	.snippet-manual-save-status_label {
+		font-weight: bold;
+		margin-right: var(--ck-spacing-medium);
+	}
+
+	#snippet-manual-save-lag {
+		padding: 4px;
+	}
+
+	#snippet-manual-save {
+		color: #fff;
+		background: hsl( 88, 73%, 39% );
+		opacity: 0.5;
+		padding: 4px 20px;
+		display: block;
+		border: 0;
+		border-radius: 2px;
+		font-weight: bold;
+		outline: none;
+		transition: 300ms ease background;
+		box-shadow: 0 2px 0 rgb(68, 117, 10);
+	}
+
+	#snippet-manual-save.active {
+		cursor: pointer;
+		opacity: 1;
+	}
+
+	#snippet-manual-save.saving {
+		background: hsl( 88, 73%, 34% );
+	}
+
+	#snippet-manual-save-console {
+		/* Lets wrap content. */
+		max-height: 300px;
+		overflow: auto;
+		white-space: normal;
+		background: #2b2c26;
+		transition: 300ms;
+	}
+
+	#snippet-manual-save-console.received {
+		animation: autosave-received 1s ease 1;
+	}
+	@keyframes autosave-received {
+		from { background: green; }
+		to { background: #2b2c26; }
+	}
+</style>

+ 106 - 0
docs/_snippets/builds/saving-data/manualsave.js

@@ -0,0 +1,106 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals ClassicEditor, console, window, document, setTimeout */
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+let HTTP_SERVER_LAG = 500;
+let isDirty = false;
+
+document.querySelector( '#snippet-manual-lag' ).addEventListener( 'change', evt => {
+	HTTP_SERVER_LAG = evt.target.value;
+} );
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-manual' ), {
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			viewportTopOffset: 60
+		}
+	} )
+	.then( editor => {
+		window.editor = editor;
+
+		handleStatusChanges( editor );
+		handleSaveButton( editor );
+		handleBeforeunload( editor );
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );
+
+// Handle clicking the "Save" button.
+function handleSaveButton( editor ) {
+	const saveButton = document.querySelector( '#snippet-manual-save' );
+	const pendingActions = editor.plugins.get( 'PendingActions' );
+
+	saveButton.addEventListener( 'click', evt => {
+		const data = editor.getData();
+		const action = pendingActions.add( 'Saving in progress.' );
+
+		evt.preventDefault();
+
+		// Fake HTTP server's lag.
+		setTimeout( () => {
+			log( data );
+
+			pendingActions.remove( action );
+
+			// Reset isDirty only if data didn't change in the meantime.
+			if ( data == editor.getData() ) {
+				isDirty = false;
+			}
+
+			updateStatus( editor );
+		}, HTTP_SERVER_LAG );
+	} );
+}
+
+function handleStatusChanges( editor ) {
+	const pendingActions = editor.plugins.get( 'PendingActions' );
+
+	pendingActions.on( 'change:hasAny', () => updateStatus( editor ) );
+
+	editor.model.document.on( 'change:data', () => {
+		isDirty = true;
+
+		updateStatus( editor );
+	} );
+}
+
+function handleBeforeunload( editor ) {
+	window.addEventListener( 'beforeunload', evt => {
+		if ( editor.plugins.get( 'PendingActions' ).hasAny ) {
+			evt.preventDefault();
+		}
+	} );
+}
+
+function updateStatus( editor ) {
+	const saveButton = document.querySelector( '#snippet-manual-save' );
+
+	if ( isDirty ) {
+		saveButton.classList.add( 'active' );
+	} else {
+		saveButton.classList.remove( 'active' );
+	}
+
+	if ( editor.plugins.get( 'PendingActions' ).hasAny ) {
+		document.querySelector( '#snippet-manual-save-console' ).classList.remove( 'received' );
+		saveButton.value = 'Saving...';
+		saveButton.classList.add( 'saving' );
+	} else {
+		saveButton.value = 'Save';
+		saveButton.classList.remove( 'saving' );
+	}
+}
+
+function log( msg ) {
+	const console = document.querySelector( '#snippet-manual-save-console' );
+
+	console.classList.add( 'received' );
+	console.textContent = msg;
+}

+ 21 - 22
docs/builds/guides/development/installing-plugins.md

@@ -186,35 +186,34 @@ All this works because a typical `src/ckeditor.js` module that you can find in e
 ```js
 import ClassicEditorBase from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 import EssentialsPlugin from '@ckeditor/ckeditor5-essentials/src/essentials';
-import UploadadapterPlugin from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
+import UploadAdapterPlugin from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
 import AutoformatPlugin from '@ckeditor/ckeditor5-autoformat/src/autoformat';
 import BoldPlugin from '@ckeditor/ckeditor5-basic-styles/src/bold';
 import ItalicPlugin from '@ckeditor/ckeditor5-basic-styles/src/italic';
-import BlockquotePlugin from '@ckeditor/ckeditor5-block-quote/src/blockquote';
+import BlockQuotePlugin from '@ckeditor/ckeditor5-block-quote/src/blockquote';
 // ...
 
 export default class ClassicEditor extends ClassicEditorBase {}
 
-ClassicEditor.build = {
-	plugins: [
-		EssentialsPlugin,
-		UploadadapterPlugin,
-		AutoformatPlugin,
-		BoldPlugin,
-		ItalicPlugin,
-		BlockquotePlugin,
-		// ...
-	],
-	config: {
-		toolbar: {
-			items: [
-				'heading',
-				'bold',
-				// ...
-			]
-		},
-		// ...
-	}
+ClassicEditor.builtInPlugins = [
+	EssentialsPlugin,
+	UploadAdapterPlugin,
+	AutoformatPlugin,
+	BoldPlugin,
+	ItalicPlugin,
+	BlockQuotePlugin,
+	// ...
+];
+
+ClassicEditor.defaultConfig = {
+	toolbar: {
+		items: [
+			'heading',
+			'bold',
+			// ...
+		]
+	},
+	// ...
 };
 ```
 

+ 63 - 65
docs/builds/guides/integration/advanced-setup.md

@@ -1,6 +1,6 @@
 ---
 category: builds-integration
-order: 40
+order: 50
 ---
 
 # Advanced setup
@@ -175,71 +175,69 @@ You can now import all the needed plugins and the creator directly into your cod
 ```js
 import ClassicEditorBase from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 import EssentialsPlugin from '@ckeditor/ckeditor5-essentials/src/essentials';
-import UploadadapterPlugin from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
+import UploadAdapterPlugin from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
 import AutoformatPlugin from '@ckeditor/ckeditor5-autoformat/src/autoformat';
 import BoldPlugin from '@ckeditor/ckeditor5-basic-styles/src/bold';
 import ItalicPlugin from '@ckeditor/ckeditor5-basic-styles/src/italic';
-import BlockquotePlugin from '@ckeditor/ckeditor5-block-quote/src/blockquote';
-import EasyimagePlugin from '@ckeditor/ckeditor5-easy-image/src/easyimage';
+import BlockQuotePlugin from '@ckeditor/ckeditor5-block-quote/src/blockquote';
+import EasyImagePlugin from '@ckeditor/ckeditor5-easy-image/src/easyimage';
 import HeadingPlugin from '@ckeditor/ckeditor5-heading/src/heading';
 import ImagePlugin from '@ckeditor/ckeditor5-image/src/image';
-import ImagecaptionPlugin from '@ckeditor/ckeditor5-image/src/imagecaption';
-import ImagestylePlugin from '@ckeditor/ckeditor5-image/src/imagestyle';
-import ImagetoolbarPlugin from '@ckeditor/ckeditor5-image/src/imagetoolbar';
-import ImageuploadPlugin from '@ckeditor/ckeditor5-image/src/imageupload';
+import ImageCaptionPlugin from '@ckeditor/ckeditor5-image/src/imagecaption';
+import ImageStylePlugin from '@ckeditor/ckeditor5-image/src/imagestyle';
+import ImageToolbarPlugin from '@ckeditor/ckeditor5-image/src/imagetoolbar';
+import ImageUploadPlugin from '@ckeditor/ckeditor5-image/src/imageupload';
 import LinkPlugin from '@ckeditor/ckeditor5-link/src/link';
 import ListPlugin from '@ckeditor/ckeditor5-list/src/list';
 import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 
 export default class ClassicEditor extends ClassicEditorBase {}
 
-ClassicEditor.build = {
-	plugins: [
-		EssentialsPlugin,
-		UploadadapterPlugin,
-		AutoformatPlugin,
-		BoldPlugin,
-		ItalicPlugin,
-		BlockquotePlugin,
-		EasyimagePlugin,
-		HeadingPlugin,
-		ImagePlugin,
-		ImagecaptionPlugin,
-		ImagestylePlugin,
-		ImagetoolbarPlugin,
-		ImageuploadPlugin,
-		LinkPlugin,
-		ListPlugin,
-		ParagraphPlugin
-	],
-	config: {
-		toolbar: {
-			items: [
-				'heading',
-				'|',
-				'bold',
-				'italic',
-				'link',
-				'bulletedList',
-				'numberedList',
-				'imageUpload',
-				'blockQuote',
-				'undo',
-				'redo'
-			]
-		},
-		image: {
-			toolbar: [
-				'imageStyle:full',
-				'imageStyle:side',
-				'|',
-				'imageTextAlternative'
-			]
-		},
-		language: 'en'
-	}
+ClassicEditor.builtinPlugins = [
+	EssentialsPlugin,
+	UploadAdapterPlugin,
+	AutoformatPlugin,
+	BoldPlugin,
+	ItalicPlugin,
+	BlockQuotePlugin,
+	EasyImagePlugin,
+	HeadingPlugin,
+	ImagePlugin,
+	ImageCaptionPlugin,
+	ImageStylePlugin,
+	ImageToolbarPlugin,
+	ImageUploadPlugin,
+	LinkPlugin,
+	ListPlugin,
+	ParagraphPlugin
+];
+
+ClassicEditor.defaultConfig = {
+	toolbar: {
+		items: [
+			'heading',
+			'|',
+			'bold',
+			'italic',
+			'link',
+			'bulletedList',
+			'numberedList',
+			'imageUpload',
+			'blockQuote',
+			'undo',
+			'redo'
+		]
+	},
+	image: {
+		toolbar: [
+			'imageStyle:full',
+			'imageStyle:side',
+			'|',
+			'imageTextAlternative'
+		]
+	},
+	language: 'en'
 };
-
 ```
 
 This module will export an editor creator class which has all the plugins and configuration that you need already built-in. To use such editor, simply import that class and call the static `.create()` method like in all {@link builds/guides/integration/basic-api#creating-an-editor examples}.
@@ -265,18 +263,18 @@ The second variant how to run the editor is to use the creator class directly, w
 ```js
 import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 import EssentialsPlugin from '@ckeditor/ckeditor5-essentials/src/essentials';
-import UploadadapterPlugin from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
+import UploadAdapterPlugin from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter';
 import AutoformatPlugin from '@ckeditor/ckeditor5-autoformat/src/autoformat';
 import BoldPlugin from '@ckeditor/ckeditor5-basic-styles/src/bold';
 import ItalicPlugin from '@ckeditor/ckeditor5-basic-styles/src/italic';
-import BlockquotePlugin from '@ckeditor/ckeditor5-block-quote/src/blockquote';
-import EasyimagePlugin from '@ckeditor/ckeditor5-easy-image/src/easyimage';
+import BlockQuotePlugin from '@ckeditor/ckeditor5-block-quote/src/blockquote';
+import EasyImagePlugin from '@ckeditor/ckeditor5-easy-image/src/easyimage';
 import HeadingPlugin from '@ckeditor/ckeditor5-heading/src/heading';
 import ImagePlugin from '@ckeditor/ckeditor5-image/src/image';
-import ImagecaptionPlugin from '@ckeditor/ckeditor5-image/src/imagecaption';
-import ImagestylePlugin from '@ckeditor/ckeditor5-image/src/imagestyle';
-import ImagetoolbarPlugin from '@ckeditor/ckeditor5-image/src/imagetoolbar';
-import ImageuploadPlugin from '@ckeditor/ckeditor5-image/src/imageupload';
+import ImageCaptionPlugin from '@ckeditor/ckeditor5-image/src/imagecaption';
+import ImageStylePlugin from '@ckeditor/ckeditor5-image/src/imagestyle';
+import ImageToolbarPlugin from '@ckeditor/ckeditor5-image/src/imagetoolbar';
+import ImageUploadPlugin from '@ckeditor/ckeditor5-image/src/imageupload';
 import LinkPlugin from '@ckeditor/ckeditor5-link/src/link';
 import ListPlugin from '@ckeditor/ckeditor5-list/src/list';
 import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph';
@@ -289,12 +287,12 @@ ClassicEditor
 			AutoformatPlugin,
 			BoldPlugin,
 			ItalicPlugin,
-			BlockquotePlugin,
+			BlockQuotePlugin,
 			HeadingPlugin,
 			ImagePlugin,
-			ImagecaptionPlugin,
-			ImagestylePlugin,
-			ImagetoolbarPlugin,
+			ImageCaptionPlugin,
+			ImageStylePlugin,
+			ImageToolbarPlugin,
 			LinkPlugin,
 			ListPlugin,
 			ParagraphPlugin

+ 1 - 1
docs/builds/guides/integration/configuration.md

@@ -59,7 +59,7 @@ ClassicEditor
 Each build has a number of plugins available. You can easily list all plugins available in your build:
 
 ```js
-ClassicEditor.build.plugins.map( plugin => plugin.pluginName );
+ClassicEditor.builtinPlugins.map( plugin => plugin.pluginName );
 ```
 
 ## Adding features

Dosya farkı çok büyük olduğundan ihmal edildi
+ 313 - 0
docs/builds/guides/integration/saving-data.md


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
docs/framework/guides/overview.md