/** * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ 'use strict'; ( function() { var validLinkRegExp = /^]+href="([^"]+)"[^>]*>([^<]+)<\/a>$/i; CKEDITOR.plugins.add( 'autoembed', { requires: 'autolink,undo', lang: 'ar,az,bg,ca,cs,da,de,de-ch,el,en,en-au,eo,es,es-mx,et,eu,fa,fr,gl,hr,hu,it,ja,km,ko,ku,lt,lv,mk,nb,nl,oc,pl,pt,pt-br,ro,ru,sk,sq,sr,sr-latn,sv,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% init: function( editor ) { var currentId = 1, embedCandidatePasted; editor.on( 'paste', function( evt ) { if ( evt.data.dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_INTERNAL ) { embedCandidatePasted = 0; return; } var match = evt.data.dataValue.match( validLinkRegExp ); embedCandidatePasted = match != null && decodeURI( match[ 1 ] ) == decodeURI( match[ 2 ] ); // Expecting exactly one tag spanning the whole pasted content. // The tag has to have same href as content. if ( embedCandidatePasted ) { evt.data.dataValue = ' element instead of inside it. // So, if user hasn't changed selection, bookmark is inserted right after . // Then, after pasting embedded content, bookmark is still in DOM but it is // inside the original element. After selection recreation it would end up before widget: //

A

B

-->

A

B

-->

A ^

B

// We have to fix this IE8 behavior so it is the same as on other browsers. if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && !bookmark.endNode && startNode.equals( anchor.getNext() ) ) { anchor.append( startNode ); } insertRange.setStartBefore( anchor ); insertRange.setEndAfter( anchor ); editable.insertElement( wrapper, insertRange ); // If both bookmarks are still in DOM, it means that selection was not inside // an anchor that got substituted. We can safely recreate that selection. (https://dev.ckeditor.com/ticket/13429) if ( editable.contains( startNode ) && editable.contains( endNode ) ) { selection.selectBookmarks( [ bookmark ] ); } else { // If one of bookmarks is not in DOM, clean up leftovers. startNode.remove(); endNode.remove(); } editor.fire( 'unlockSnapshot' ); } notification.hide(); finalizeCreation(); }, errorCallback: function() { notification.hide(); editor.widgets.destroy( instance, true ); editor.showNotification( lang.embeddingFailed, 'info' ); } } ); function finalizeCreation() { editor.widgets.finalizeCreation( temp ); } } CKEDITOR.plugins.autoEmbed = { /** * Gets the definition of the widget that should be used to automatically embed the specified link. * * This method uses the value of the {@link CKEDITOR.config#autoEmbed_widget} option. * * @since 4.5.0 * @member CKEDITOR.plugins.autoEmbed * @param {CKEDITOR.editor} editor * @param {String} url The URL to be embedded. * @returns {CKEDITOR.plugins.widget.definition/null} The definition of the widget to be used to embed the link. */ getWidgetDefinition: function( editor, url ) { var opt = editor.config.autoEmbed_widget || 'embed,embedSemantic', name, widgets = editor.widgets.registered; if ( typeof opt == 'string' ) { opt = opt.split( ',' ); while ( ( name = opt.shift() ) ) { if ( widgets[ name ] ) { return widgets[ name ]; } } } else if ( typeof opt == 'function' ) { return widgets[ opt( url ) ]; } return null; } }; /** * Specifies the widget to use to automatically embed a link. The default value * of this option defines that either the [Media Embed](https://ckeditor.com/cke4/addon/embed) or * [Semantic Media Embed](https://ckeditor.com/cke4/addon/embedsemantic) widgets will be used, depending on which is enabled. * * The general behavior: * * * If a string (widget names separated by commas) is provided, then the first of the listed widgets which is registered * will be used. For example, if `'foo,bar,bom'` is set and widgets `'bar'` and `'bom'` are registered, then `'bar'` * will be used. * * If a callback is specified, then it will be executed with the URL to be embedded and it should return the * name of the widget to be used. It allows to use different embed widgets for different URLs. * * Example: * * ```js * // Defines that embedSemantic should be used (regardless of whether embed is defined). * config.autoEmbed_widget = 'embedSemantic'; * ``` * * Using with custom embed widgets: * * ```js * config.autoEmbed_widget = 'customEmbed'; * ``` * * **Note:** Plugin names are always lower case, while widget names are not, so widget names do not have to equal plugin names. * For example, there is the `embedsemantic` plugin and the `embedSemantic` widget. * * Read more in the {@glink features/media_embed#automatic-embedding-on-paste documentation} * and see the {@glink examples/mediaembed example}. * * @since 4.5.0 * @cfg {String/Function} [autoEmbed_widget='embed,embedSemantic'] * @member CKEDITOR.config */ } )();