1
+ /**
2
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
3
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
4
+ */
5
+
6
+ 'use strict' ;
7
+
8
+ ( function ( ) {
9
+ CKEDITOR . plugins . add ( 'autoembed' , {
10
+ requires : 'autolink,undo' ,
11
+
12
+ init : function ( editor ) {
13
+ var currentId = 1 ;
14
+
15
+ editor . on ( 'paste' , function ( evt ) {
16
+ if ( evt . data . dataTransfer . getTransferType ( editor ) == CKEDITOR . DATA_TRANSFER_INTERNAL ) {
17
+ return ;
18
+ }
19
+
20
+ var data = evt . data . dataValue ,
21
+ parsedData ,
22
+ link ;
23
+
24
+ // Expecting exactly one <a> tag spanning the whole pasted content.
25
+ if ( data . match ( / ^ < a [ ^ < ] + < \/ a > $ / i ) ) {
26
+ parsedData = CKEDITOR . htmlParser . fragment . fromHtml ( data ) ;
27
+
28
+ // Embed only links with a single text node with a href attr which equals its text.
29
+ if ( parsedData . children . length != 1 )
30
+ return ;
31
+
32
+ link = parsedData . children [ 0 ] ;
33
+
34
+ if ( link . type == CKEDITOR . NODE_ELEMENT && link . getHtml ( ) == link . attributes . href ) {
35
+ evt . data . dataValue = '<a data-cke-autoembed="' + ( ++ currentId ) + '"' + data . substr ( 2 ) ;
36
+ }
37
+ }
38
+
39
+ } , null , null , 20 ) ; // Execute after autolink.
40
+
41
+ editor . on ( 'afterPaste' , function ( ) {
42
+ autoEmbedLink ( editor , currentId ) ;
43
+ } ) ;
44
+ }
45
+ } ) ;
46
+
47
+ function autoEmbedLink ( editor , id ) {
48
+ var anchor = editor . editable ( ) . findOne ( 'a[data-cke-autoembed="' + id + '"]' ) ;
49
+
50
+ if ( ! anchor || ! anchor . data ( 'cke-saved-href' ) ) {
51
+ return ;
52
+ }
53
+
54
+ var href = anchor . data ( 'cke-saved-href' ) ,
55
+ widgetDef = CKEDITOR . plugins . autoEmbed . getWidgetDefinition ( editor , href ) ;
56
+
57
+ if ( ! widgetDef ) {
58
+ window . console && window . console . log (
59
+ '[CKEDITOR.plugins.autoEmbed] Incorrect config.autoEmbed_widget value. ' +
60
+ 'No widget definition found.'
61
+ ) ;
62
+ return ;
63
+ }
64
+
65
+ // TODO Move this to a method in the widget plugin. #13408
66
+ var defaults = typeof widgetDef . defaults == 'function' ? widgetDef . defaults ( ) : widgetDef . defaults ,
67
+ element = CKEDITOR . dom . element . createFromHtml ( widgetDef . template . output ( defaults ) ) ,
68
+ instance ,
69
+ wrapper = editor . widgets . wrapElement ( element , widgetDef . name ) ,
70
+ temp = new CKEDITOR . dom . documentFragment ( wrapper . getDocument ( ) ) ;
71
+
72
+ temp . append ( wrapper ) ;
73
+ instance = editor . widgets . initOn ( element , widgetDef ) ;
74
+
75
+ if ( ! instance ) {
76
+ finalizeCreation ( ) ;
77
+ return ;
78
+ }
79
+
80
+ instance . loadContent ( href , {
81
+ callback : function ( ) {
82
+ // DOM might be invalidated in the meantime, so find the anchor again.
83
+ var anchor = editor . editable ( ) . findOne ( 'a[data-cke-autoembed="' + id + '"]' ) ,
84
+ range = editor . createRange ( ) ;
85
+
86
+ // Anchor might be removed in the meantime.
87
+ if ( anchor ) {
88
+ range . setStartAt ( anchor , CKEDITOR . POSITION_BEFORE_START ) ;
89
+ range . setEndAt ( anchor , CKEDITOR . POSITION_AFTER_END ) ;
90
+
91
+ editor . editable ( ) . insertElementIntoRange ( wrapper , range ) ;
92
+ }
93
+
94
+ finalizeCreation ( ) ;
95
+ } ,
96
+
97
+ error : finalizeCreation
98
+ } ) ;
99
+
100
+ function finalizeCreation ( ) {
101
+ editor . widgets . finalizeCreation ( temp ) ;
102
+ }
103
+ }
104
+
105
+ CKEDITOR . plugins . autoEmbed = {
106
+ /**
107
+ * Gets definition of a widget that should be used to automatically embed the specified link.
108
+ *
109
+ * This method uses value of the {@link CKEDITOR.config#autoEmbed_widget} option.
110
+ *
111
+ * @since 4.5.0
112
+ * @param {CKEDITOR.editor } editor
113
+ * @param {String } url URL to be embedded.
114
+ * @returns {CKEDITOR.plugins.widget.definition/null } Definition of the widget to be used to embed the link.
115
+ */
116
+ getWidgetDefinition : function ( editor , url ) {
117
+ var opt = editor . config . autoEmbed_widget || 'embed,embedSemantic' ,
118
+ name ,
119
+ widgets = editor . widgets . registered ;
120
+
121
+ if ( typeof opt == 'string' ) {
122
+ opt = opt . split ( ',' ) ;
123
+
124
+ while ( ( name = opt . shift ( ) ) ) {
125
+ if ( widgets [ name ] ) {
126
+ return widgets [ name ] ;
127
+ }
128
+ }
129
+ } else if ( typeof opt == 'function' ) {
130
+ return widgets [ opt ( url ) ] ;
131
+ }
132
+
133
+ return null ;
134
+ }
135
+ } ;
136
+
137
+ /**
138
+ * Specifies which widget to use to automatically embed a link. The default value
139
+ * of this option defines that either the [Embed](ckeditor.com/addon/embed) or
140
+ * [Semantic Embed](ckeditor.com/addon/embedsemantic) widgets will be used, depending on which is enabled.
141
+ *
142
+ * The general behavior:
143
+ *
144
+ * * If string (widget names separated by commas) is provided, then first of the listed widgets which is registered
145
+ * will be used. For example, if `'foo,bar,bom'` is set and widgets `'bar'` and `'bom'` are registered, then `'bar'`
146
+ * will be used.
147
+ * * If a callback is specified, then it will be executed with the URL to be embedded and it should return a
148
+ * name of the widget to be used. It allows to use different embed widgets for different URLs.
149
+ *
150
+ * Example:
151
+ *
152
+ * // Defines that embedSemantic should be used (regardless of whether embed is defined).
153
+ * config.autoEmbed_widget = 'embedSemantic';
154
+ *
155
+ * Using with custom embed widgets:
156
+ *
157
+ * config.autoEmbed_widget = 'customEmbed';
158
+ *
159
+ * **Note:** Plugin names are always lower case, while widget names are not, so widget names do not have to equal plugin names.
160
+ * For example, there is the `embedsemantic` plugin and `embedSemantic` widget.
161
+ *
162
+ * @since 4.5.0
163
+ * @cfg {String/Function} [autoEmbed_widget='embed,embedSemantic']
164
+ * @member CKEDITOR.config
165
+ */
166
+ } ) ( ) ;
0 commit comments