JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.4.3
[ckeditor.git] / _source / plugins / link / plugin.js
1 /*\r
2 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\r
3 For licensing, see LICENSE.html or http://ckeditor.com/license\r
4 */\r
5 \r
6 CKEDITOR.plugins.add( 'link',\r
7 {\r
8         init : function( editor )\r
9         {\r
10                 // Add the link and unlink buttons.\r
11                 editor.addCommand( 'link', new CKEDITOR.dialogCommand( 'link' ) );\r
12                 editor.addCommand( 'anchor', new CKEDITOR.dialogCommand( 'anchor' ) );\r
13                 editor.addCommand( 'unlink', new CKEDITOR.unlinkCommand() );\r
14                 editor.ui.addButton( 'Link',\r
15                         {\r
16                                 label : editor.lang.link.toolbar,\r
17                                 command : 'link'\r
18                         } );\r
19                 editor.ui.addButton( 'Unlink',\r
20                         {\r
21                                 label : editor.lang.unlink,\r
22                                 command : 'unlink'\r
23                         } );\r
24                 editor.ui.addButton( 'Anchor',\r
25                         {\r
26                                 label : editor.lang.anchor.toolbar,\r
27                                 command : 'anchor'\r
28                         } );\r
29                 CKEDITOR.dialog.add( 'link', this.path + 'dialogs/link.js' );\r
30                 CKEDITOR.dialog.add( 'anchor', this.path + 'dialogs/anchor.js' );\r
31 \r
32                 // Add the CSS styles for anchor placeholders.\r
33                 editor.addCss(\r
34                         'img.cke_anchor' +\r
35                         '{' +\r
36                                 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' +\r
37                                 'background-position: center center;' +\r
38                                 'background-repeat: no-repeat;' +\r
39                                 'border: 1px solid #a9a9a9;' +\r
40                                 'width: 18px !important;' +\r
41                                 'height: 18px !important;' +\r
42                         '}\n' +\r
43                         'a.cke_anchor' +\r
44                         '{' +\r
45                                 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' +\r
46                                 'background-position: 0 center;' +\r
47                                 'background-repeat: no-repeat;' +\r
48                                 'border: 1px solid #a9a9a9;' +\r
49                                 'padding-left: 18px;' +\r
50                         '}'\r
51                         );\r
52 \r
53                 // Register selection change handler for the unlink button.\r
54                  editor.on( 'selectionChange', function( evt )\r
55                         {\r
56                                 /*\r
57                                  * Despite our initial hope, document.queryCommandEnabled() does not work\r
58                                  * for this in Firefox. So we must detect the state by element paths.\r
59                                  */\r
60                                 var command = editor.getCommand( 'unlink' ),\r
61                                         element = evt.data.path.lastElement && evt.data.path.lastElement.getAscendant( 'a', true );\r
62                                 if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) )\r
63                                         command.setState( CKEDITOR.TRISTATE_OFF );\r
64                                 else\r
65                                         command.setState( CKEDITOR.TRISTATE_DISABLED );\r
66                         } );\r
67 \r
68                 editor.on( 'doubleclick', function( evt )\r
69                         {\r
70                                 var element = CKEDITOR.plugins.link.getSelectedLink( editor ) || evt.data.element;\r
71 \r
72                                 if ( !element.isReadOnly() )\r
73                                 {\r
74                                         if ( element.is( 'a' ) )\r
75                                                 evt.data.dialog =  ( element.getAttribute( 'name' ) && !element.getAttribute( 'href' ) ) ? 'anchor' : 'link';\r
76                                         else if ( element.is( 'img' ) && element.getAttribute( '_cke_real_element_type' ) == 'anchor' )\r
77                                                 evt.data.dialog = 'anchor';\r
78                                 }\r
79                         });\r
80 \r
81                 // If the "menu" plugin is loaded, register the menu items.\r
82                 if ( editor.addMenuItems )\r
83                 {\r
84                         editor.addMenuItems(\r
85                                 {\r
86                                         anchor :\r
87                                         {\r
88                                                 label : editor.lang.anchor.menu,\r
89                                                 command : 'anchor',\r
90                                                 group : 'anchor'\r
91                                         },\r
92 \r
93                                         link :\r
94                                         {\r
95                                                 label : editor.lang.link.menu,\r
96                                                 command : 'link',\r
97                                                 group : 'link',\r
98                                                 order : 1\r
99                                         },\r
100 \r
101                                         unlink :\r
102                                         {\r
103                                                 label : editor.lang.unlink,\r
104                                                 command : 'unlink',\r
105                                                 group : 'link',\r
106                                                 order : 5\r
107                                         }\r
108                                 });\r
109                 }\r
110 \r
111                 // If the "contextmenu" plugin is loaded, register the listeners.\r
112                 if ( editor.contextMenu )\r
113                 {\r
114                         editor.contextMenu.addListener( function( element, selection )\r
115                                 {\r
116                                         if ( !element || element.isReadOnly() )\r
117                                                 return null;\r
118 \r
119                                         var isAnchor = ( element.is( 'img' ) && element.getAttribute( '_cke_real_element_type' ) == 'anchor' );\r
120 \r
121                                         if ( !isAnchor )\r
122                                         {\r
123                                                 if ( !( element = CKEDITOR.plugins.link.getSelectedLink( editor ) ) )\r
124                                                         return null;\r
125 \r
126                                                 isAnchor = ( element.getAttribute( 'name' ) && !element.getAttribute( 'href' ) );\r
127                                         }\r
128 \r
129                                         return isAnchor ?\r
130                                                         { anchor : CKEDITOR.TRISTATE_OFF } :\r
131                                                         { link : CKEDITOR.TRISTATE_OFF, unlink : CKEDITOR.TRISTATE_OFF };\r
132                                 });\r
133                 }\r
134         },\r
135 \r
136         afterInit : function( editor )\r
137         {\r
138                 // Register a filter to displaying placeholders after mode change.\r
139 \r
140                 var dataProcessor = editor.dataProcessor,\r
141                         dataFilter = dataProcessor && dataProcessor.dataFilter;\r
142 \r
143                 if ( dataFilter )\r
144                 {\r
145                         dataFilter.addRules(\r
146                                 {\r
147                                         elements :\r
148                                         {\r
149                                                 a : function( element )\r
150                                                 {\r
151                                                         var attributes = element.attributes;\r
152                                                         if ( attributes.name && !attributes.href )\r
153                                                                 return editor.createFakeParserElement( element, 'cke_anchor', 'anchor' );\r
154                                                 }\r
155                                         }\r
156                                 });\r
157                 }\r
158         },\r
159 \r
160         requires : [ 'fakeobjects' ]\r
161 } );\r
162 \r
163 CKEDITOR.plugins.link =\r
164 {\r
165         /**\r
166          *  Get the surrounding link element of current selection.\r
167          * @param editor\r
168          * @example CKEDITOR.plugins.link.getSelectedLink( editor );\r
169          * @since 3.2.1\r
170          * The following selection will all return the link element.\r
171          *       <pre>\r
172          *  <a href="#">li^nk</a>\r
173          *  <a href="#">[link]</a>\r
174          *  text[<a href="#">link]</a>\r
175          *  <a href="#">li[nk</a>]\r
176          *  [<b><a href="#">li]nk</a></b>]\r
177          *  [<a href="#"><b>li]nk</b></a>\r
178          * </pre>\r
179          */\r
180         getSelectedLink : function( editor )\r
181         {\r
182                 try\r
183                 {\r
184                         var selection = editor.getSelection();\r
185                         if ( selection.getType() == CKEDITOR.SELECTION_ELEMENT )\r
186                         {\r
187                                 var selectedElement = selection.getSelectedElement();\r
188                                 if ( selectedElement.is( 'a' ) )\r
189                                         return selectedElement;\r
190                         }\r
191 \r
192                         var range = selection.getRanges( true )[ 0 ];\r
193                         range.shrink( CKEDITOR.SHRINK_TEXT );\r
194                         var root = range.getCommonAncestor();\r
195                         return root.getAscendant( 'a', true );\r
196                 }\r
197                 catch( e ) { return null; }\r
198         }\r
199 };\r
200 \r
201 CKEDITOR.unlinkCommand = function(){};\r
202 CKEDITOR.unlinkCommand.prototype =\r
203 {\r
204         /** @ignore */\r
205         exec : function( editor )\r
206         {\r
207                 /*\r
208                  * execCommand( 'unlink', ... ) in Firefox leaves behind <span> tags at where\r
209                  * the <a> was, so again we have to remove the link ourselves. (See #430)\r
210                  *\r
211                  * TODO: Use the style system when it's complete. Let's use execCommand()\r
212                  * as a stopgap solution for now.\r
213                  */\r
214                 var selection = editor.getSelection(),\r
215                         bookmarks = selection.createBookmarks(),\r
216                         ranges = selection.getRanges(),\r
217                         rangeRoot,\r
218                         element;\r
219 \r
220                 for ( var i = 0 ; i < ranges.length ; i++ )\r
221                 {\r
222                         rangeRoot = ranges[i].getCommonAncestor( true );\r
223                         element = rangeRoot.getAscendant( 'a', true );\r
224                         if ( !element )\r
225                                 continue;\r
226                         ranges[i].selectNodeContents( element );\r
227                 }\r
228 \r
229                 selection.selectRanges( ranges );\r
230                 editor.document.$.execCommand( 'unlink', false, null );\r
231                 selection.selectBookmarks( bookmarks );\r
232         },\r
233 \r
234         startDisabled : true\r
235 };\r
236 \r
237 CKEDITOR.tools.extend( CKEDITOR.config,\r
238 {\r
239         linkShowAdvancedTab : true,\r
240         linkShowTargetTab : true\r
241 } );\r