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

Merge branch 'master' into t/35

Aleksander Nowodzinski 7 лет назад
Родитель
Сommit
0f9bdb3368
33 измененных файлов с 613 добавлено и 113 удалено
  1. 3 0
      packages/ckeditor5-media-embed/.travis.yml
  2. 6 0
      packages/ckeditor5-media-embed/CHANGELOG.md
  3. 1 1
      packages/ckeditor5-media-embed/CONTRIBUTING.md
  4. 1 1
      packages/ckeditor5-media-embed/README.md
  5. 1 1
      packages/ckeditor5-media-embed/docs/api/media-embed.md
  6. 66 30
      packages/ckeditor5-media-embed/docs/features/media-embed.md
  7. 1 0
      packages/ckeditor5-media-embed/lang/contexts.json
  8. 26 0
      packages/ckeditor5-media-embed/lang/translations/cs.po
  9. 26 0
      packages/ckeditor5-media-embed/lang/translations/de.po
  10. 26 0
      packages/ckeditor5-media-embed/lang/translations/en.po
  11. 26 0
      packages/ckeditor5-media-embed/lang/translations/fa.po
  12. 26 0
      packages/ckeditor5-media-embed/lang/translations/fr.po
  13. 26 0
      packages/ckeditor5-media-embed/lang/translations/gl.po
  14. 26 0
      packages/ckeditor5-media-embed/lang/translations/hr.po
  15. 26 0
      packages/ckeditor5-media-embed/lang/translations/hu.po
  16. 26 0
      packages/ckeditor5-media-embed/lang/translations/it.po
  17. 26 0
      packages/ckeditor5-media-embed/lang/translations/ne.po
  18. 26 0
      packages/ckeditor5-media-embed/lang/translations/no.po
  19. 26 0
      packages/ckeditor5-media-embed/lang/translations/pl.po
  20. 26 0
      packages/ckeditor5-media-embed/lang/translations/sq.po
  21. 26 0
      packages/ckeditor5-media-embed/lang/translations/tr.po
  22. 20 17
      packages/ckeditor5-media-embed/package.json
  23. 14 5
      packages/ckeditor5-media-embed/src/automediaembed.js
  24. 5 5
      packages/ckeditor5-media-embed/src/converters.js
  25. 20 18
      packages/ckeditor5-media-embed/src/mediaembed.js
  26. 2 2
      packages/ckeditor5-media-embed/src/mediaembedcommand.js
  27. 16 16
      packages/ckeditor5-media-embed/src/mediaregistry.js
  28. 8 8
      packages/ckeditor5-media-embed/src/ui/mediaformview.js
  29. 4 4
      packages/ckeditor5-media-embed/src/utils.js
  30. 49 1
      packages/ckeditor5-media-embed/tests/automediaembed.js
  31. 10 0
      packages/ckeditor5-media-embed/theme/mediaembed.css
  32. 6 4
      packages/ckeditor5-media-embed/theme/mediaembedediting.css
  33. 16 0
      packages/ckeditor5-media-embed/theme/mediaform.css

+ 3 - 0
packages/ckeditor5-media-embed/.travis.yml

@@ -12,6 +12,9 @@ node_js:
 - '6'
 cache:
 - node_modules
+branches:
+   except:
+   - stable
 before_install:
 - export DISPLAY=:99.0
 - sh -e /etc/init.d/xvfb start

+ 6 - 0
packages/ckeditor5-media-embed/CHANGELOG.md

@@ -0,0 +1,6 @@
+Changelog
+=========
+
+## [10.0.0](https://github.com/ckeditor/ckeditor5-media-embed/tree/v10.0.0) (2018-10-08)
+
+Initial implementation of the media embed feature.

+ 1 - 1
packages/ckeditor5-media-embed/CONTRIBUTING.md

@@ -1,4 +1,4 @@
 Contributing
 ========================================
 
-Information about contributing can be found on the following page: <https://github.com/ckeditor/ckeditor5/blob/master/CONTRIBUTING.md>.
+See the [official contributors' guide to CKEditor 5](https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html) to learn more.

+ 1 - 1
packages/ckeditor5-media-embed/README.md

@@ -10,7 +10,7 @@ CKEditor 5 media embed feature
 [![Dependency Status](https://david-dm.org/ckeditor/ckeditor5-media-embed/status.svg)](https://david-dm.org/ckeditor/ckeditor5-media-embed)
 [![devDependency Status](https://david-dm.org/ckeditor/ckeditor5-media-embed/dev-status.svg)](https://david-dm.org/ckeditor/ckeditor5-media-embed?type=dev)
 
-This package implements the media embed feature for CKEditor 5.
+This package implements the media embed feature for CKEditor 5. You can use it to insert embeddable media such as YouTube or Vimeo videos and tweets into your rich text content.
 
 ## Demo
 

+ 1 - 1
packages/ckeditor5-media-embed/docs/api/media-embed.md

@@ -6,7 +6,7 @@ category: api-reference
 
 [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-media-embed.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-media-embed)
 
-This package implements the media embed feature for CKEditor 5.
+This package implements the media embed feature for CKEditor 5. You can use it to insert embeddable media such as YouTube or Vimeo videos and tweets into your rich-text content.
 
 ## Demo
 

+ 66 - 30
packages/ckeditor5-media-embed/docs/features/media-embed.md

@@ -6,7 +6,7 @@ category: features
 
 # Media embed
 
-The {@link module:media-embed/mediaembed~MediaEmbed} feature brings support for embeddable media (such as YouTube videos or tweets) in the editor content.
+The {@link module:media-embed/mediaembed~MediaEmbed} feature brings support for inserting embeddable media such as YouTube or Vimeo videos and tweets into your rich text content.
 
 ## Demo
 
@@ -48,9 +48,39 @@ ClassicEditor
 ```
 
 <info-box>
-	Depending on how you will configure this feature, you may need to use services like [Iframely](http://iframe.ly/) or [Embedly](https://embed.ly/) to display content of embedded media on your target website. Read more about [displaying embedded media](#displaying-embedded-media-on-your-website).
+	Depending on how you will configure this feature, you may need to use services like [Iframely](https://iframely.com/) or [Embedly](https://embed.ly/) to display content of embedded media on your target website. Read more about [displaying embedded media](#displaying-embedded-media-on-your-website).
 </info-box>
 
+## Previewable and non-previewable media
+
+When the media embed feature is asked to embed a specific media element via its URL it needs to make a decision how the media will be displayed in the editor.
+
+### Previewable media
+
+If, for instance, the URL to embed is `https://www.youtube.com/watch?v=H08tGjXNHO4`, the feature is able to predict that it needs to produce the following HTML to show this YouTube video:
+
+```html
+<div style="position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;">
+	<iframe src="https://www.youtube.com/embed/${ videoId }"
+		style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"
+		frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>
+	</iframe>
+</div>
+```
+
+Yes, it is quite complex, but this is the cost of creating responsive content for today's web. The crucial part, though, is the iframe's `src` which the media embed feature can predict based on the given video URL and the aspect ratio (which affects `padding-bottom`).
+
+Thanks to the ability to hardcode this URL to HTML transformation, the media embed feature is able to show previews of YouTube, Dailymotion and Vimeo videos as well as Spotify widgets without requesting any external service.
+
+### Non-previewable media
+
+Unfortunately, to show previews of media such as tweets, Instagram photos or Facebook posts, the editor would need to retrieve the content of those from an external service. Some of these media providers expose [oEmbed endpoints](https://oembed.com/) but not all and those endpoint responses often require further processing to be embeddable. Most importantly, though, the media embed feature is often not able to request those services due to [same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy).
+
+The above limitations can be overcome with the help of proxy services like Iframely or Embedly. However, the media embed feature [does not support asynchronous preview providers](https://github.com/ckeditor/ckeditor5-media-embed/issues/16) yet. Therefore, to still allow embedding tweets or Instagram photos, we chose to:
+
+1. Show a placeholder of the embedded media in the editor (see e.g. how a tweet is presented in the [demo](#demo) above).
+2. Produce a [semantic `<oembed url="...">` tag](#semantic-data-output-default) in the data output from the editor. This output makes it possible to later use proxy services to [display the content of these media on your website](#displaying-embedded-media-on-your-website).
+
 ## Configuration
 
 ### Data output format
@@ -58,12 +88,12 @@ ClassicEditor
 The data output format of the feature can be configured using the {@link module:media-embed/mediaembed~MediaEmbedConfig#previewsInData `config.mediaEmbed.previewsInData`} option.
 
 <info-box info>
-	This option does not change how media are displayed inside the editor – the previewable ones will still be displayed with previews. It only affects the output data (see below).
+	This option does not change how the media are displayed inside the editor &mdash; the previewable ones will still be displayed with previews. It only affects the output data (see below).
 </info-box>
 
 #### Semantic data output (default)
 
-By default, the media embed feature outputs semantic `<oembed>` tags for previewable and non-previewable media. That being so, it works best when the application processes (expands) the media on the serverside or [directly in the front–end](#displaying-embedded-media-on-your-website), preserving the versatile database representation:
+By default, the media embed feature outputs semantic `<oembed url="...">` tags for previewable and non-previewable media. That being so, it works best when the application processes (expands) the media on the server side or [directly in the front–end](#displaying-embedded-media-on-your-website), preserving the versatile database representation:
 
 ```html
 <figure class="media">
@@ -73,7 +103,7 @@ By default, the media embed feature outputs semantic `<oembed>` tags for preview
 
 #### Including previews in data
 
-Optionally, by setting `mediaEmbed.previewsInData` to `true` you can configure the media embed feature to output media in the same way they look in the editor, this is, if this media is "previewable", the media preview (HTML) is saved to the database:
+Optionally, by setting `mediaEmbed.previewsInData` to `true` you can configure the media embed feature to output media in the same way they look in the editor. So if the media element is "previewable", the media preview (HTML) is saved to the database:
 
 ```html
 <figure class="media">
@@ -83,7 +113,7 @@ Optionally, by setting `mediaEmbed.previewsInData` to `true` you can configure t
 </figure>
 ```
 
-Currently, the preview is only available for content providers for which CKEditor 5 can predict an `<iframe>` code – this is YouTube, Vimeo, Dailymotion, Spotify, etc. For other providers like Twitter or Instagram the editor cannot produce an `<iframe>` code and it does not, so far, allows retrieving this code from an external oEmbed service. Therefore, for non previewable media it produces the default semantic output:
+Currently, the preview is only available for content providers for which CKEditor 5 can predict the `<iframe>` code: YouTube, Vimeo, Dailymotion, Spotify, etc. For other providers like Twitter or Instagram the editor cannot produce an `<iframe>` code and it does not, so far, allow retrieving this code from an external oEmbed service. Therefore, for non-previewable media it produces the default semantic output:
 
 ```html
 <figure class="media">
@@ -91,11 +121,13 @@ Currently, the preview is only available for content providers for which CKEdito
 </figure>
 ```
 
-This means that, unless you [limited the list of providers](#media-providers) to only those which are previewable, you need to [make sure that media are displayed on your website](#displaying-embedded-media-on-your-website).
+This means that, unless you [limited the list of providers](#media-providers) to only those which are previewable, you need to [make sure that the media are displayed on your website](#displaying-embedded-media-on-your-website).
+
+Read more about [non-previewable media](#previewable-and-non-previewable-media).
 
 ### Media providers
 
-CKEditor comes with several supported media providers which can be extended or altered.
+CKEditor 5 comes with several supported media providers that can be extended or altered.
 
 Names of providers **with previews**:
 
@@ -116,15 +148,15 @@ Names of providers **without previews**:
 	The default media provider configuration does not support all possible media URLs, only the most common are included. Services like Iframely or Embedly support thousands of media providers and it is up to you to define which you want to allow.
 </info-box>
 
-#### Extending
+#### Extending media providers
 
-To extend the default list of default providers, use {@link module:media-embed/mediaembed~MediaEmbedConfig#extraProviders `config.mediaEmbed.extraProviders`}.
+To extend the default list of providers, use {@link module:media-embed/mediaembed~MediaEmbedConfig#extraProviders `config.mediaEmbed.extraProviders`}.
 
-#### Removing
+#### Removing media providers
 
 To remove certain providers, use {@link module:media-embed/mediaembed~MediaEmbedConfig#removeProviders `config.mediaEmbed.removeProviders`}.
 
-For instance, to leave only the previewable providers configure this feature as follows:
+For instance, to leave only the previewable providers, configure this feature as follows:
 
 ```js
 ClassicEditor
@@ -139,7 +171,7 @@ ClassicEditor
 	.catch( ... );
 ```
 
-#### Overriding
+#### Overriding media providers
 
 To override the default providers, use {@link module:media-embed/mediaembed~MediaEmbedConfig#providers `config.mediaEmbed.providers`} and define your set according to the {@link module:media-embed/mediaembed~MediaEmbedProvider provider syntax}:
 
@@ -151,10 +183,10 @@ ClassicEditor
 		mediaEmbed: {
 			providers: [
 				{
-					// An URL regexp or array of URL regexps:
+					// A URL regexp or an array of URL regexps:
 					url: /^example\.com\/media\/(\w+)/,
 
-					// To be defined only if the media is previewable:
+					// To be defined only if the media are previewable:
 					html: match => '...'
 				},
 				...
@@ -165,17 +197,21 @@ ClassicEditor
 	.catch( ... );
 ```
 
-You can take inspirtation from the default configuration of this feature which you can find in: https://github.com/ckeditor/ckeditor5-media-embed/blob/master/src/mediaembedediting.js
+You can take inspiration from the default configuration of this feature which you can find in: https://github.com/ckeditor/ckeditor5-media-embed/blob/master/src/mediaembedediting.js
 
 ## Displaying embedded media on your website
 
-By default, the media embed feature produces output that does not contain previews of embedded media, called the [semantic output](#semantic-data-output-default). That means that you need to transform the output `<oembed>` elements into real media on your target website.
+By default, the media embed feature produces output that does not contain previews of embedded media, called the [semantic output](#semantic-data-output-default). This means that you need to transform the output `<oembed>` elements into real media on your target website.
+
+There are many ways to do that. The simplest, plug-and-play solutions are described here. You can also implement this transformation as part of your back-end service or you can use different services than described in this section.
 
-There are many ways to do that. The simplest, plug-and-play solutions are described here. You can also implement this transformation as part of your backend service and you can use different services than described in this section.
+<info-box>
+	While the easiest solution (which is described below) is to replace embedded media on the client side, it is not necessarily the most optimal way. A more powerful and flexible solution is to request those services on your back-end. Refer to the documentation of the service of your choice for more information.
+</info-box>
 
 ### Iframely
 
-[Iframely](https://iframely.com) offers the [embed.js](https://iframely.com/docs/embedjs) library which converts [various media](https://iframely.com/docs/providers) URLs into rich previews. It works in the front–end and remains fully compatible with the output produced by CKEditor.
+[Iframely](https://iframely.com) offers the [embed.js](https://iframely.com/docs/embedjs) library which converts [various media](https://iframely.com/docs/providers) URLs into rich previews. It works in the front–end and remains fully compatible with the output produced by CKEditor 5.
 
 First, having [secured the API key](https://iframely.com/docs/allow-origins), load the `embed.js` library from the CDN into your website:
 
@@ -209,7 +245,7 @@ using this short code snippet:
 
 #### Non-semantic data
 
-When the feature is configured to [include media previews](#including-previews-in-data) in output, you can still use Iframely for media embeds like the following one:
+When the feature is configured to [include media previews](#including-previews-in-data) in the output, you can still use Iframely for media embeds like the following one:
 
 ```html
 <figure class="media">
@@ -306,15 +342,15 @@ In this case, the code is almost the same as with the semantic data but you shou
 
 By default, the {@link module:media-embed/mediaembed~MediaEmbed} plugin loads the {@link module:media-embed/automediaembed~AutoMediaEmbed} as a dependency.
 
-The {@link module:media-embed/automediaembed~AutoMediaEmbed} plugin recognizes media links in the pasted content and embeds them shortly after they are injected into the document to speed up the editing. Just like the "traditional" embedding (i.e. by using the button in the toolbar), the automatic embedding works for all media providers specified in the [configuration](#media-providers).
+The {@link module:media-embed/automediaembed~AutoMediaEmbed} plugin recognizes media links in the pasted content and embeds them shortly after they are injected into the document to speed up the editing. Just like the "traditional" embedding (i.e. by using the toolbar button), automatic embedding works for all media providers specified in the [configuration](#media-providers).
 
 <info-box>
-	The media URL must be the only content pasted to be properly embedded. Multiple links (`"http://media.url http://another.media.url"`) as well as bigger chunks of the content (`"This link http://media.url will not be auto–embedded when pasted."`) are ignored.
+	The media URL must be the only content pasted to be properly embedded. Multiple links (`"http://media.url http://another.media.url"`) as well as bigger chunks of content (`"This link http://media.url will not be auto–embedded when pasted."`) are ignored.
 </info-box>
 
 If the automatic embedding was unexpected, for instance when the link was meant to remain in the content as text, simply undo the action (by clicking the "Undo" button in the toolbar or using the <kbd>Ctrl/⌘</kbd>+<kbd>Z</kbd> keystrokes).
 
-## Styling media in editor content
+## Styling media in the editor content
 
 While the editor comes with default styles for popular media providers like Facebook, Instagram or Twitter, you can create additional styles for non-previewable media in your editor content to help users identify them.
 
@@ -338,9 +374,9 @@ The HTML structure of every non-previewable media in the editor is as follows:
 </figure>
 ```
 
-Let's create the dedicated style for media coming from the [ckeditor.com](https://ckeditor.com) domain. To do that, you'll need some additional styles included in your website.
+For example, you can create a dedicated style for media coming from the [ckeditor.com](https://ckeditor.com) domain. To do that, you will need some additional styles included in your website.
 
-First, we must hide the generic media icon displayed for non-previewable media:
+First, you must hide the generic media icon displayed for non-previewable media:
 
 ```css
 .ck-media__wrapper[data-oembed-url*="ckeditor.com"] .ck-media__placeholder__icon * {
@@ -348,7 +384,7 @@ First, we must hide the generic media icon displayed for non-previewable media:
 }
 ```
 
-Then, let's give the media a distinctive background color
+Then, give the media a distinctive background color:
 
 ```css
 .ck-media__wrapper[data-oembed-url*="ckeditor.com"] .ck-media__placeholder {
@@ -356,7 +392,7 @@ Then, let's give the media a distinctive background color
 }
 ```
 
-and introduce the custom icon identifying the media
+and introduce the custom icon identifying the media:
 
 ```css
 .ck-media__wrapper[data-oembed-url*="ckeditor.com"] .ck-media__placeholder__icon {
@@ -364,7 +400,7 @@ and introduce the custom icon identifying the media
 }
 ```
 
-Finally, let's make sure the URL in the placeholder has the right contrast:
+Finally, make sure the URL in the placeholder has the right contrast:
 
 ```css
 .ck-media__wrapper[data-oembed-url*="ckeditor.com"] .ck-media__placeholder__url .ck-media__placeholder__url__text {
@@ -376,7 +412,7 @@ Finally, let's make sure the URL in the placeholder has the right contrast:
 }
 ```
 
-Before you load the data, make sure the `ckeditor.com` provider is [enabled in your configuration](#extending). In its most basic form it could look like this:
+Before you load the data, make sure the `ckeditor.com` provider is [enabled in your configuration](#extending-media-providers). In its most basic form it could look like this:
 
 ```js
 mediaEmbed: {
@@ -399,7 +435,7 @@ The {@link module:media-embed/mediaembed~MediaEmbed} plugin registers:
 * the `'mediaEmbed'` UI button component,
 * the `'mediaEmbed'` command implemented by {@link module:media-embed/mediaembedcommand~MediaEmbedCommand}.
 
-	You can insert a new media or update the selected media URL by executing the following code:
+	You can insert a new media element or update the selected media URL by executing the following code:
 
 	```js
 	editor.execute( 'mediaEmbed', { url: 'http://url.to.the/media' } );

+ 1 - 0
packages/ckeditor5-media-embed/lang/contexts.json

@@ -1,4 +1,5 @@
 {
+	"media widget": "Label for the media widget.",
 	"Media URL": "Label for the URL input in the Media Embed URL editing balloon.",
 	"The URL must not be empty.": "An error message that informs about an empty value in the URL input.",
 	"This media URL is not supported.": "An error message that informs about unsupported media URL.",

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/cs.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Czech (https://www.transifex.com/ckeditor/teams/11143/cs/)\n"
+"Language: cs\n"
+"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "ovládací prvek médií"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "URL adresa"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "URL adresa musí být vyplněna."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "Tato adresa bohužel není podporována."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Vložit média"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/de.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: German (https://www.transifex.com/ckeditor/teams/11143/de/)\n"
+"Language: de\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "Medien-Widget"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "Medien-Url"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "Die Url darf nicht leer sein"
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "Diese Medien-Url wird nicht unterstützt"
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Medium einfügen"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/en.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language: \n"
+"Language-Team: \n"
+"Plural-Forms: \n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "media widget"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "Media URL"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "The URL must not be empty."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "This media URL is not supported."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Insert media"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/fa.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Persian (https://www.transifex.com/ckeditor/teams/11143/fa/)\n"
+"Language: fa\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "ویجت رسانه"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "آدرس اینترنتی رسانه"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "آدرس اینترنتی URL نباید خالی باشد."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "این آدرس اینترنتی رسانه پشتیبانی نمی‌شود"
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "وارد کردن رسانه"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/fr.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: French (https://www.transifex.com/ckeditor/teams/11143/fr/)\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "widget média"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "URL média"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "L'URL ne peut être vide."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "Cet URL média n'est pas supporté."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Insérez le média"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/gl.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Galician (https://www.transifex.com/ckeditor/teams/11143/gl/)\n"
+"Language: gl\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "trebello multimedia"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "URL multimedia"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "O URL non debe estar baleiro."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "Este URL multimedia non é compatible."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Inserir elemento multimedia"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/hr.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Croatian (https://www.transifex.com/ckeditor/teams/11143/hr/)\n"
+"Language: hr\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "dodatak za medije"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "URL medija"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "URL ne smije biti prazan."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "URL nije podržan."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Ubaci medij"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/hu.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Hungarian (https://www.transifex.com/ckeditor/teams/11143/hu/)\n"
+"Language: hu\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "Média widget"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "Média URL"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "Az URL nem lehet üres."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "Ez a média URL típus nem támogatott."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Média beszúrása"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/it.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Italian (https://www.transifex.com/ckeditor/teams/11143/it/)\n"
+"Language: it\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "widget media"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "URL media"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "L'URL non può essere vuoto."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "Questo URL di file multimediali non è supportato."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Inserisci media"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/ne.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Nepali (Nepal) (https://www.transifex.com/ckeditor/teams/11143/ne_NP/)\n"
+"Language: ne_NP\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "मिडिया विजेट"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "मिडिया यूआरएल"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "यूआरएल खाली हुनु हुँदैन।"
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "यो मिडिया यूआरएल समर्थित छैन।"
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "मिडिया सम्मिलित गर्नुहोस्।"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/no.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Norwegian (https://www.transifex.com/ckeditor/teams/11143/no/)\n"
+"Language: no\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "media-widget"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "Media-URL"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "URL-en kan ikke være tom."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "Denne media-URL-en er ikke støttet."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Sett inn media"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/pl.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Polish (https://www.transifex.com/ckeditor/teams/11143/pl/)\n"
+"Language: pl\n"
+"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "widget osadzenie mediów"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "Adres URL"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "Adres URL nie może być pusty."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "Ten rodzaj adresu URL nie jest obsługiwany."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Wstaw media"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/sq.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Albanian (https://www.transifex.com/ckeditor/teams/11143/sq/)\n"
+"Language: sq\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "Vegla e medies"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "URL e Medies"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "URL nuk duhet të jetë e zbrazët."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "URL e medies nuk mbështetet."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Shto Medie"

+ 26 - 0
packages/ckeditor5-media-embed/lang/translations/tr.po

@@ -0,0 +1,26 @@
+# Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+msgid ""
+msgstr ""
+"Language-Team: Turkish (https://www.transifex.com/ckeditor/teams/11143/tr/)\n"
+"Language: tr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgctxt "Label for the media widget."
+msgid "media widget"
+msgstr "Medya Aracı"
+
+msgctxt "Label for the URL input in the Media Embed URL editing balloon."
+msgid "Media URL"
+msgstr "Medya URL'si"
+
+msgctxt "An error message that informs about an empty value in the URL input."
+msgid "The URL must not be empty."
+msgstr "URL boş olamaz."
+
+msgctxt "An error message that informs about unsupported media URL."
+msgid "This media URL is not supported."
+msgstr "Desteklenmeyen Medya URL'si."
+
+msgctxt "Toolbar button tooltip for the Media Embed feature."
+msgid "Insert media"
+msgstr "Medya Ekle"

+ 20 - 17
packages/ckeditor5-media-embed/package.json

@@ -1,31 +1,34 @@
 {
   "name": "@ckeditor/ckeditor5-media-embed",
-  "version": "0.0.1",
+  "version": "10.0.0",
   "description": "Media Embed feature for CKEditor 5.",
   "keywords": [
     "ckeditor",
     "ckeditor5",
     "ckeditor 5",
-    "ckeditor5-feature"
+    "ckeditor5-feature",
+    "ckeditor5-plugin"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^11.0.0",
-    "@ckeditor/ckeditor5-clipboard": "^10.0.2",
-    "@ckeditor/ckeditor5-engine": "^10.2.0",
-    "@ckeditor/ckeditor5-enter": "^10.1.1",
-    "@ckeditor/ckeditor5-ui": "^11.0.0",
-    "@ckeditor/ckeditor5-utils": "^10.2.0",
-    "@ckeditor/ckeditor5-undo": "^10.0.2",
-    "@ckeditor/ckeditor5-widget": "^10.2.0"
+    "@ckeditor/ckeditor5-core": "^11.0.1",
+    "@ckeditor/ckeditor5-clipboard": "^10.0.3",
+    "@ckeditor/ckeditor5-engine": "^11.0.0",
+    "@ckeditor/ckeditor5-enter": "^10.1.2",
+    "@ckeditor/ckeditor5-image": "^11.0.0",
+    "@ckeditor/ckeditor5-theme-lark": "^11.1.0",
+    "@ckeditor/ckeditor5-ui": "^11.1.0",
+    "@ckeditor/ckeditor5-utils": "^11.0.0",
+    "@ckeditor/ckeditor5-undo": "^10.0.3",
+    "@ckeditor/ckeditor5-widget": "^10.3.0"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-basic-styles": "^10.0.2",
-    "@ckeditor/ckeditor5-editor-balloon": "^11.0.0",
-    "@ckeditor/ckeditor5-editor-classic": "^11.0.0",
-    "@ckeditor/ckeditor5-link": "^10.0.3",
-    "@ckeditor/ckeditor5-list": "^11.0.1",
-    "@ckeditor/ckeditor5-paragraph": "^10.0.2",
-    "@ckeditor/ckeditor5-typing": "^11.0.0",
+    "@ckeditor/ckeditor5-basic-styles": "^10.0.3",
+    "@ckeditor/ckeditor5-editor-balloon": "^11.0.1",
+    "@ckeditor/ckeditor5-editor-classic": "^11.0.1",
+    "@ckeditor/ckeditor5-link": "^10.0.4",
+    "@ckeditor/ckeditor5-list": "^11.0.2",
+    "@ckeditor/ckeditor5-paragraph": "^10.0.3",
+    "@ckeditor/ckeditor5-typing": "^11.0.1",
     "eslint": "^5.5.0",
     "eslint-config-ckeditor5": "^1.0.7",
     "husky": "^0.14.3",

+ 14 - 5
packages/ckeditor5-media-embed/src/automediaembed.js

@@ -46,7 +46,7 @@ export default class AutoMediaEmbed extends Plugin {
 		super( editor );
 
 		/**
-		 * A paste–to–embed `setTimeout` id. Stored as a property to allow
+		 * The paste–to–embed `setTimeout` ID. Stored as a property to allow
 		 * cleaning of the timeout.
 		 *
 		 * @private
@@ -55,7 +55,7 @@ export default class AutoMediaEmbed extends Plugin {
 		this._timeoutId = null;
 
 		/**
-		 * A position where the `<media>` element will be inserted after the timeout,
+		 * The position where the `<media>` element will be inserted after the timeout,
 		 * determined each time the new content is pasted into the document.
 		 *
 		 * @private
@@ -103,7 +103,7 @@ export default class AutoMediaEmbed extends Plugin {
 	}
 
 	/**
-	 * Analyzes the part of the document between provided positions in search for a URL representing a media.
+	 * Analyzes the part of the document between provided positions in search for a URL representing media.
 	 * When the URL is found, it is automatically converted into media.
 	 *
 	 * @protected
@@ -119,7 +119,9 @@ export default class AutoMediaEmbed extends Plugin {
 		let url = '';
 
 		for ( const node of walker ) {
-			url += node.item.data;
+			if ( node.item.is( 'textProxy' ) ) {
+				url += node.item.data;
+			}
 		}
 
 		url = url.trim();
@@ -134,6 +136,13 @@ export default class AutoMediaEmbed extends Plugin {
 			return;
 		}
 
+		const mediaEmbedCommand = editor.commands.get( 'mediaEmbed' );
+
+		// Do not anything if media element cannot be inserted at the current position (#47).
+		if ( !mediaEmbedCommand.isEnabled ) {
+			return;
+		}
+
 		// Position won't be available in the `setTimeout` function so let's clone it.
 		this._positionToInsert = LivePosition.createFromPosition( leftPosition );
 
@@ -149,7 +158,7 @@ export default class AutoMediaEmbed extends Plugin {
 					writer.setSelection( this._positionToInsert );
 				}
 
-				editor.commands.execute( 'mediaEmbed', url );
+				mediaEmbedCommand.execute( url );
 
 				this._positionToInsert.detach();
 				this._positionToInsert = null;

+ 5 - 5
packages/ckeditor5-media-embed/src/converters.js

@@ -13,13 +13,13 @@ import ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';
 /**
  * Returns a function that converts the model "url" attribute to the view representation.
  *
- * Depending on the configuration the view representation can be "sementaic" (for data pipeline):
+ * Depending on the configuration, the view representation can be "semantic" (for the data pipeline):
  *
  *		<figure class="media">
- *			<oembed url="foo"></div>
+ *			<oembed url="foo"></oembed>
  *		</figure>
  *
- * or "non-semantic" (for editing view pipeline):
+ * or "non-semantic" (for the editing view pipeline):
  *
  *		<figure class="media">
  *			<div data-oembed-url="foo">[ non-semantic media preview for "foo" ]</div>
@@ -31,7 +31,7 @@ import ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';
  * @param {module:media-embed/mediaregistry~MediaRegistry} registry The registry providing
  * the media and their content.
  * @param {Object} options
- * @param {String} [options.renderMediaPreview] When `true`, the converter will create view in the non-semantic form.
+ * @param {String} [options.renderMediaPreview] When `true`, the converter will create the view in the non-semantic form.
  * @param {String} [options.renderForEditingView] When `true`, the converter will create a view specific for the
  * editing pipeline (e.g. including CSS classes, content placeholders).
  * @returns {Function}
@@ -55,6 +55,6 @@ export function modelToViewUrlAttributeConverter( registry, options ) {
 
 		const mediaViewElement = registry.getMediaViewElement( viewWriter, url, options );
 
-		viewWriter.insert( ViewPosition.createAt( figure ), mediaViewElement );
+		viewWriter.insert( ViewPosition.createAt( figure, 0 ), mediaViewElement );
 	}
 }

+ 20 - 18
packages/ckeditor5-media-embed/src/mediaembed.js

@@ -13,6 +13,8 @@ import MediaEmbedUI from './mediaembedui';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import Widget from '@ckeditor/ckeditor5-widget/src/widget';
 
+import '../theme/mediaembed.css';
+
 /**
  * The media embed plugin.
  *
@@ -20,9 +22,9 @@ import Widget from '@ckeditor/ckeditor5-widget/src/widget';
  *
  * This is a "glue" plugin which loads the following plugins:
  *
- * * {@link module:media-embed/mediaembedediting~MediaEmbedEditing media embed editing feature},
- * * {@link module:media-embed/mediaembedui~MediaEmbedUI media embed UI feature} and
- * * {@link module:media-embed/automediaembed~AutoMediaEmbed auto-media embed feature}.
+ * * The {@link module:media-embed/mediaembedediting~MediaEmbedEditing media embed editing feature},
+ * * The {@link module:media-embed/mediaembedui~MediaEmbedUI media embed UI feature} and
+ * * The {@link module:media-embed/automediaembed~AutoMediaEmbed auto-media embed feature}.
  *
  * @extends module:core/plugin~Plugin
  */
@@ -76,7 +78,7 @@ export default class MediaEmbed extends Plugin {
  *			url: /^.+/
  *		}
  *
- * To implement a responsive media, you can use the following HTML structure:
+ * To implement responsive media, you can use the following HTML structure:
  *
  *		{
  *			...
@@ -92,14 +94,14 @@ export default class MediaEmbed extends Plugin {
  * @property {String} name The name of the provider. Used e.g. when
  * {@link module:media-embed/mediaembed~MediaEmbedConfig#removeProviders removing providers}.
  * @property {RegExp|Array.<RegExp>} url The `RegExp` object (or array of objects) defining the URL of the media.
- * If any URL matches the `RegExp`, it becomes the media in editor model, as defined by the provider. The result
+ * If any URL matches the `RegExp`, it becomes the media in the editor model, as defined by the provider. The result
  * of matching (output of `String.prototype.match()`) is passed to the `html` rendering function of the media.
  *
- * **Note:** You do not need to include the protocol (`http://`, `https://`) and `www` subdomain in your `RegExps`,
+ * **Note:** You do not need to include the protocol (`http://`, `https://`) and `www` subdomain in your `RegExps`,
  * they are stripped from the URLs before matching anyway.
- * @property {Function} [html] (optional) Rendering function of the media. The function receives the entire matching
+ * @property {Function} [html] (optional) The rendering function of the media. The function receives the entire matching
  * array from the corresponding `url` `RegExp` as an argument, allowing rendering a dedicated
- * preview of a media identified by a certain id or a hash. When not defined, the media embed feature
+ * preview of the media identified by a certain ID or a hash. When not defined, the media embed feature
  * will use a generic media representation in the view and output data.
  * Note that when
  * {@link module:media-embed/mediaembed~MediaEmbedConfig#previewsInData `config.mediaEmbed.previewsInData`}
@@ -134,14 +136,14 @@ export default class MediaEmbed extends Plugin {
 /**
  * The default media providers supported by the editor.
  *
- * Names of providers with rendering functions (previews):
+ * The names of providers with rendering functions (previews):
  *
  * * "dailymotion",
  * * "spotify",
  * * "youtube",
  * * "vimeo"
  *
- * Names of providers without rendering functions:
+ * The names of providers without rendering functions:
  *
  * * "instagram",
  * * "twitter",
@@ -155,15 +157,15 @@ export default class MediaEmbed extends Plugin {
  * **Note**: The default media provider configuration may not support all possible media URLs,
  * only the most common are included.
  *
- * **Note**: Media without are always represented in the data using the "semantic" markup. See
+ * Media without rendering functions are always represented in the data using the "semantic" markup. See
  * {@link module:media-embed/mediaembed~MediaEmbedConfig#previewsInData `config.mediaEmbed.previewsInData`} to
  * learn more about possible data outputs.
  *
- * **Note:**: The priority of media providers corresponds to the order of configuration. The first provider
- * to match the URL is always used, even if there are other providers which support a particular URL.
- * The URL is never matched against remaining providers.
+ * The priority of media providers corresponds to the order of configuration. The first provider
+ * to match the URL is always used, even if there are other providers that support a particular URL.
+ * The URL is never matched against the remaining providers.
  *
- * To discard **all** default media providers, simply override this config with your own
+ * To discard **all** default media providers, simply override this configuration with your own
  * {@link module:media-embed/mediaembed~MediaEmbedProvider definitions}:
  *
  *		ClassicEditor
@@ -183,7 +185,7 @@ export default class MediaEmbed extends Plugin {
  *			.then( ... )
  *			.catch( ... );
  *
- * You can take inspirtation from the default configuration of this feature which you can find in:
+ * You can take inspiration from the default configuration of this feature which you can find in:
  * https://github.com/ckeditor/ckeditor5-media-embed/blob/master/src/mediaembedediting.js
  *
  * To **extend** the list of default providers, use
@@ -222,7 +224,7 @@ export default class MediaEmbed extends Plugin {
  */
 
 /**
- * The list of media providers which should not be used despite being available in
+ * The list of media providers that should not be used despite being available in
  * {@link module:media-embed/mediaembed~MediaEmbedConfig#providers `config.mediaEmbed.providers`} and
  * {@link module:media-embed/mediaembed~MediaEmbedConfig#extraProviders `config.mediaEmbed.extraProviders`}
  *
@@ -252,7 +254,7 @@ export default class MediaEmbed extends Plugin {
  *			</div>
  *		</figure>
  *
- * **Note:** Preview–less media are always represented in the data using the "semantic" markup
+ * **Note:** Media without preview are always represented in the data using the "semantic" markup
  * regardless of the value of the `previewsInData`. Learn more about different kinds of media
  * in the {@link module:media-embed/mediaembed~MediaEmbedConfig#providers `config.mediaEmbed.providers`}
  * configuration description.

+ 2 - 2
packages/ckeditor5-media-embed/src/mediaembedcommand.js

@@ -16,7 +16,7 @@ import { getSelectedMediaElement } from './utils';
  *
  * The command is registered by the {@link module:media-embed/mediaembedediting~MediaEmbedEditing} as `'mediaEmbed'`.
  *
- * To insert a media at the current selection, execute the command and specify the URL:
+ * To insert media at the current selection, execute the command and specify the URL:
  *
  *		editor.execute( 'mediaEmbed', 'http://url.to.the/media' );
  *
@@ -46,7 +46,7 @@ export default class MediaEmbedCommand extends Command {
 	/**
 	 * Executes the command, which either:
 	 *
-	 * * updates the URL of a selected media,
+	 * * updates the URL of the selected media,
 	 * * inserts the new media into the editor and puts the selection around it.
 	 *
 	 * @fires execute

+ 16 - 16
packages/ckeditor5-media-embed/src/mediaregistry.js

@@ -16,7 +16,7 @@ import Template from '@ckeditor/ckeditor5-ui/src/template';
 const mediaPlaceholderIconViewBox = '0 0 64 42';
 
 /**
- * A bridge between the raw media content provider definitions and editor view content.
+ * A bridge between the raw media content provider definitions and the editor view content.
  *
  * It helps translating media URLs to corresponding {@link module:engine/view/element~Element view elements}.
  *
@@ -40,7 +40,7 @@ export default class MediaRegistry {
 
 				if ( !name ) {
 					/**
-					 * One of the providers (or extraProviders) specified in the mediaEmbed configuration
+					 * One of the providers (or extra providers) specified in the media embed configuration
 					 * has no name and will not be used by the editor. In order to get this media
 					 * provider working, double check your editor configuration.
 					 *
@@ -74,7 +74,7 @@ export default class MediaRegistry {
 	/**
 	 * Checks whether the passed URL is representing a certain media type allowed in the editor.
 	 *
-	 * @param {String} url The url to be checked
+	 * @param {String} url The URL to be checked
 	 * @returns {Boolean}
 	 */
 	hasMedia( url ) {
@@ -88,7 +88,7 @@ export default class MediaRegistry {
 	 * **Note:** If no URL is specified, an empty view element is returned.
 	 *
 	 * @param {module:engine/view/downcastwriter~DowncastWriter} writer The view writer used to produce a view element.
-	 * @param {String} url The url to be translated into a view element.
+	 * @param {String} url The URL to be translated into a view element.
 	 * @param {Object} options
 	 * @param {String} [options.renderMediaPreview]
 	 * @param {String} [options.renderForEditingView]
@@ -102,8 +102,8 @@ export default class MediaRegistry {
 	 * Returns a `Media` instance for the given URL.
 	 *
 	 * @protected
-	 * @param {String} url The url of the media.
-	 * @returns {module:media-embed/mediaregistry~Media|null} The `Media` instance or `null` when there's none.
+	 * @param {String} url The URL of the media.
+	 * @returns {module:media-embed/mediaregistry~Media|null} The `Media` instance or `null` when there is none.
 	 */
 	_getMedia( url ) {
 		if ( !url ) {
@@ -136,12 +136,12 @@ export default class MediaRegistry {
 	 * Tries to match `url` to `pattern`.
 	 *
 	 * @private
-	 * @param {String} url The url of the media.
-	 * @param {RegExp} pattern The pattern that should accept the media url.
+	 * @param {String} url The URL of the media.
+	 * @param {RegExp} pattern The pattern that should accept the media URL.
 	 * @returns {Array|null}
 	 */
 	_getUrlMatches( url, pattern ) {
-		// 1. Try to match without stripping the protocol and "www" sub-domain.
+		// 1. Try to match without stripping the protocol and "www" subdomain.
 		let match = url.match( pattern );
 
 		if ( match ) {
@@ -156,7 +156,7 @@ export default class MediaRegistry {
 			return match;
 		}
 
-		// 3. Try to match after stripping the "www" sub-domain.
+		// 3. Try to match after stripping the "www" subdomain.
 		rawUrl = rawUrl.replace( /^www\./, '' );
 		match = rawUrl.match( pattern );
 
@@ -169,9 +169,9 @@ export default class MediaRegistry {
 }
 
 /**
- * Represents a media defined by the provider configuration.
+ * Represents media defined by the provider configuration.
  *
- * It can be rendered to the {@link module:engine/view/element~Element view element} and used in editing or data pipeline.
+ * It can be rendered to the {@link module:engine/view/element~Element view element} and used in the editing or data pipeline.
  *
  * @private
  */
@@ -208,7 +208,7 @@ class Media {
 	}
 
 	/**
-	 * Returns view element representation of the media.
+	 * Returns the view element representation of the media.
 	 *
 	 * @param {module:engine/view/downcastwriter~DowncastWriter} writer The view writer used to produce a view element.
 	 * @param {Object} options
@@ -269,7 +269,7 @@ class Media {
 	}
 
 	/**
-	 * Returns the placeholder HTML when media has no content preview.
+	 * Returns the placeholder HTML when the media has no content preview.
 	 *
 	 * @returns {String}
 	 */
@@ -319,9 +319,9 @@ class Media {
 	}
 
 	/**
-	 * Returns full url to specified media.
+	 * Returns the full URL to the specified media.
 	 *
-	 * @param {String} url The url of the media.
+	 * @param {String} url The URL of the media.
 	 * @returns {String|null}
 	 */
 	_getValidUrl( url ) {

+ 8 - 8
packages/ckeditor5-media-embed/src/ui/mediaformview.js

@@ -79,7 +79,7 @@ export default class MediaFormView extends View {
 		this.cancelButtonView = this._createButton( t( 'Cancel' ), cancelIcon, 'ck-button-cancel', 'cancel' );
 
 		/**
-		 * A collection of views which can be focused in the form.
+		 * A collection of views that can be focused in the form.
 		 *
 		 * @readonly
 		 * @protected
@@ -108,7 +108,7 @@ export default class MediaFormView extends View {
 		} );
 
 		/**
-		 * An array of the form validators used by {@link #isValid}.
+		 * An array of form validators used by {@link #isValid}.
 		 *
 		 * @readonly
 		 * @protected
@@ -191,8 +191,8 @@ export default class MediaFormView extends View {
 	/**
 	 * The native DOM `value` of the {@link #urlInputView} element.
 	 *
-	 * **Note**: Do not confuse with the {@link module:ui/inputtext/inputtextview~InputTextView#value}
-	 * which works one way only and may not represent the actual state of the component in DOM.
+	 * **Note**: Do not confuse it with the {@link module:ui/inputtext/inputtextview~InputTextView#value}
+	 * which works one way only and may not represent the actual state of the component in the DOM.
 	 *
 	 * @type {Number}
 	 */
@@ -203,8 +203,8 @@ export default class MediaFormView extends View {
 	/**
 	 * Sets the native DOM `value` of the {@link #urlInputView} element.
 	 *
-	 * **Note**: Do not confuse with the {@link module:ui/inputtext/inputtextview~InputTextView#value}
-	 * which works one way only and may not represent the actual state of the component in DOM.
+	 * **Note**: Do not confuse it with the {@link module:ui/inputtext/inputtextview~InputTextView#value}
+	 * which works one way only and may not represent the actual state of the component in the DOM.
 	 *
 	 * @param {String} url
 	 */
@@ -223,7 +223,7 @@ export default class MediaFormView extends View {
 		for ( const validator of this._validators ) {
 			const errorText = validator( this );
 
-			// One error per-field is enough.
+			// One error per field is enough.
 			if ( errorText ) {
 				// Apply updated error.
 				this.urlInputView.errorText = errorText;
@@ -276,7 +276,7 @@ export default class MediaFormView extends View {
 	 *
 	 * @private
 	 * @param {String} label The button label.
-	 * @param {String} icon The button's icon.
+	 * @param {String} icon The button icon.
 	 * @param {String} className The additional button CSS class name.
 	 * @param {String} [eventName] An event name that the `ButtonView#execute` event will be delegated to.
 	 * @returns {module:ui/button/buttonview~ButtonView} The button view instance.

+ 4 - 4
packages/ckeditor5-media-embed/src/utils.js

@@ -42,10 +42,10 @@ export function isMediaWidget( viewElement ) {
  * Creates a view element representing the media. Either "semantic" one for the data pipeline:
  *
  *		<figure class="media">
- *			<oembed url="foo"></div>
+ *			<oembed url="foo"></oembed>
  *		</figure>
  *
- * or "non-semantic" (for editing view pipeline):
+ * or "non-semantic" (for the editing view pipeline):
  *
  *		<figure class="media">
  *			<div data-oembed-url="foo">[ non-semantic media preview for "foo" ]</div>
@@ -68,13 +68,13 @@ export function createMediaFigureElement( writer, registry, url, options ) {
 	// Note: The hack is a copy&paste from widget utils; it makes the figure act like it's a widget.
 	figure.getFillerOffset = getFillerOffset;
 
-	writer.insert( ViewPosition.createAt( figure ), registry.getMediaViewElement( writer, url, options ) );
+	writer.insert( ViewPosition.createAt( figure, 0 ), registry.getMediaViewElement( writer, url, options ) );
 
 	return figure;
 }
 
 /**
- * Returns a selected media element in model, if any.
+ * Returns a selected media element in the model, if any.
  *
  * @param {module:engine/model/selection~Selection} selection
  * @returns {module:engine/model/element~Element|null}

+ 49 - 1
packages/ckeditor5-media-embed/tests/automediaembed.js

@@ -17,6 +17,8 @@ import Undo from '@ckeditor/ckeditor5-undo/src/undo';
 import Typing from '@ckeditor/ckeditor5-typing/src/typing';
 import ModelRange from '@ckeditor/ckeditor5-engine/src/model/range';
 import ModelPosition from '@ckeditor/ckeditor5-engine/src/model/position';
+import Image from '@ckeditor/ckeditor5-image/src/image';
+import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
 import global from '@ckeditor/ckeditor5-utils/src/dom/global';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
@@ -29,7 +31,7 @@ describe( 'AutoMediaEmbed - integration', () => {
 
 		return ClassicTestEditor
 			.create( editorElement, {
-				plugins: [ MediaEmbed, AutoMediaEmbed, Link, List, Bold, Typing ]
+				plugins: [ MediaEmbed, AutoMediaEmbed, Link, List, Bold, Typing, Image, ImageCaption ]
 			} )
 			.then( newEditor => {
 				editor = newEditor;
@@ -302,6 +304,52 @@ describe( 'AutoMediaEmbed - integration', () => {
 			);
 		} );
 
+		// #47
+		it( 'does not transform a valid URL into a media if the element cannot be placed in the current position', () => {
+			setData( editor.model, '<image src="foo.png"><caption>Foo.[]</caption></image>' );
+			pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4' );
+
+			clock.tick( 100 );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<image src="foo.png"><caption>Foo.https://www.youtube.com/watch?v=H08tGjXNHO4[]</caption></image>'
+			);
+		} );
+
+		it( 'replaces a URL in media if pasted a link when other media element was selected', () => {
+			setData(
+				editor.model,
+				'[<media url="https://open.spotify.com/album/2IXlgvecaDqOeF3viUZnPI?si=ogVw7KlcQAGZKK4Jz9QzvA"></media>]'
+			);
+
+			pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4' );
+
+			clock.tick( 100 );
+
+			expect( getData( editor.model ) ).to.equal(
+				'[<media url="https://www.youtube.com/watch?v=H08tGjXNHO4"></media>]'
+			);
+		} );
+
+		it( 'inserts a new media element if pasted a link when other media element was selected in correct place', () => {
+			setData(
+				editor.model,
+				'<paragraph>Foo. <$text linkHref="https://cksource.com">Bar</$text></paragraph>' +
+				'[<media url="https://open.spotify.com/album/2IXlgvecaDqOeF3viUZnPI?si=ogVw7KlcQAGZKK4Jz9QzvA"></media>]' +
+				'<paragraph><$text bold="true">Bar</$text>.</paragraph>'
+			);
+
+			pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4' );
+
+			clock.tick( 100 );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<paragraph>Foo. <$text linkHref="https://cksource.com">Bar</$text></paragraph>' +
+				'[<media url="https://www.youtube.com/watch?v=H08tGjXNHO4"></media>]' +
+				'<paragraph><$text bold="true">Bar</$text>.</paragraph>'
+			);
+		} );
+
 		it( 'does nothing if URL match to media but it was removed', () => {
 			return ClassicTestEditor
 				.create( editorElement, {

+ 10 - 0
packages/ckeditor5-media-embed/theme/mediaembed.css

@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+.ck-content .media {
+	/* Don't allow floated content overlap the media.
+	https://github.com/ckeditor/ckeditor5-media-embed/issues/53 */
+	clear: both;
+}

+ 6 - 4
packages/ckeditor5-media-embed/theme/mediaembedediting.css

@@ -6,10 +6,6 @@
 @import "@ckeditor/ckeditor5-ui/theme/components/tooltip/mixins/_tooltip.css";
 
 .ck-media__wrapper {
-	& > *:not(.ck-media__placeholder) {
-		pointer-events: none;
-	}
-
 	& .ck-media__placeholder {
 		display: flex;
 		flex-direction: column;
@@ -43,3 +39,9 @@
 		}
 	}
 }
+
+/* Disable all mouse interaction as long as the editor is not read–only.
+   https://github.com/ckeditor/ckeditor5-media-embed/issues/58 */
+*[contenteditable=true] .ck-media__wrapper > *:not(.ck-media__placeholder) {
+	pointer-events: none;
+}

+ 16 - 0
packages/ckeditor5-media-embed/theme/mediaform.css

@@ -3,9 +3,13 @@
  * For licensing, see LICENSE.md.
  */
 
+@import "@ckeditor/ckeditor5-theme-lark/theme/mixins/_rwd.css";
+
 .ck.ck-media-form {
 	display: flex;
 	align-items: flex-start;
+	flex-direction: row;
+	flex-wrap: nowrap;
 
 	& .ck-labeled-input {
 		display: inline-block;
@@ -14,4 +18,16 @@
 	& .ck-label {
 		display: none;
 	}
+
+	@mixin ck-media-phone {
+		flex-wrap: wrap;
+
+		& .ck-labeled-input {
+			flex-basis: 100%;
+		}
+
+		& .ck-button {
+			flex-basis: 50%;
+		}
+	}
 }