Ticket #2852: 2852_4.patch
File 2852_4.patch, 91.7 KB (added by , 15 years ago) |
---|
-
_samples/api_dialog.html
56 56 57 57 // Remove the "Link Type" combo and the "Browser 58 58 // Server" button from the "info" tab. 59 infoTab.remove( ' protocol' );59 infoTab.remove( 'linkType' ); 60 60 infoTab.remove( 'browse' ); 61 61 62 62 // Set the default value for the URL field. -
_source/core/config.js
146 146 * @example 147 147 * config.plugins = 'basicstyles,button,htmldataprocessor,toolbar,wysiwygarea'; 148 148 */ 149 plugins : 'basicstyles,button,elementspath,horizontalrule,htmldataprocessor,keystrokes,newpage,pagebreak,removeformat,smiley, sourcearea,specialchar,tab,toolbar,wysiwygarea',149 plugins : 'basicstyles,button,elementspath,horizontalrule,htmldataprocessor,keystrokes,newpage,pagebreak,removeformat,smiley,link,sourcearea,specialchar,tab,toolbar,wysiwygarea', 150 150 151 151 /** 152 152 * The theme to be used to build the UI. -
_source/core/dom/element.js
685 685 } 686 686 }, 687 687 688 copyAttributes : function( target, skip ) 689 { 690 skip || ( skip = {} ); 691 var attributes = this.$.attributes ; 692 693 for ( var n = 0 ; n < attributes.length ; n++ ) 694 { 695 var attr = attributes[n] ; 696 697 if ( attr.specified ) 698 { 699 var attrName = attr.nodeName ; 700 if ( attrName in skip ) 701 continue ; 702 703 var attrValue = this.getAttribute( attrName ); 704 if ( !attrValue ) 705 attrValue = attr.nodeValue ; 706 707 target.setAttribute( attrName, attrValue ); 708 } 709 } 710 711 if ( this.$.style.cssText !== '' ) 712 target.$.style.cssText = this.$.style.cssText ; 713 }, 714 688 715 /** 689 716 * Shows this element (display it). 690 717 * @example -
_source/core/htmlparser/element.js
64 64 a = a[0]; 65 65 b = b[0]; 66 66 return a < b ? -1 : a > b ? 1 : 0; 67 }; 67 }, 68 ckeAttrRegex = /^_cke/, 69 ckeClassRegex = /cke_[^\s]*\s*/g; 68 70 69 71 CKEDITOR.htmlParser.element.prototype = 70 72 { … … 130 132 for ( var a in attributes ) 131 133 { 132 134 // Ignore all attributes starting with "_cke". 133 if ( !/^_cke/.test( a ) ) 134 attribsArray.push( [ a, this.attributes[ a ] ] ); 135 if ( ckeAttrRegex.test( a ) ) 136 continue; 137 138 // Ignore all cke_* CSS classes. 139 if ( a.toLowerCase() == 'class' ) 140 { 141 this.attributes[ a ] = CKEDITOR.tools.trim( this.attributes[ a ].replace( ckeClassRegex, '' ) ); 142 if ( this.attributes[ a ] == '' ) 143 continue; 144 } 145 146 attribsArray.push( [ a, this.attributes[ a ] ] ); 135 147 } 136 148 137 149 // Sort the attributes by name. -
_source/plugins/dialogui/plugin.js
884 884 accessKeyUp : function() 885 885 { 886 886 this.select(); 887 }, 888 889 /** 890 * Sets the value of this text input object. 891 * @param {Object} value The new value. 892 * @returns {CKEDITOR.ui.dialog.textInput} The current UI element. 893 * @example 894 * uiElement.setValue( 'Blamo' ); 895 */ 896 setValue : function( value ) 897 { 898 value = value || ''; 899 return CKEDITOR.ui.dialog.uiElement.prototype.setValue.call( this, value ); 887 900 } 888 901 }, commonPrototype, true ); 889 902 -
_source/plugins/fakeobjects/plugin.js
5 5 6 6 CKEDITOR.plugins.add( 'fakeobjects' ); 7 7 8 CKEDITOR.editor.prototype.createFakeElement = function( realElement, className )8 CKEDITOR.editor.prototype.createFakeElement = function( realElement, className, realElementType ) 9 9 { 10 return this.document.createElement( 'img', 11 { 12 attributes : 13 { 14 'class' : className, 15 src : CKEDITOR.getUrl( 'images/spacer.gif' ), 16 _cke_realelement : encodeURIComponent( realElement.getOuterHtml() ) 17 } 18 }); 10 var attributes = 11 { 12 'class' : className, 13 src : CKEDITOR.getUrl( 'images/spacer.gif' ), 14 _cke_realelement : encodeURIComponent( realElement.getOuterHtml() ) 15 }; 16 if ( realElementType ) 17 attributes._cke_real_element_type = realElementType; 18 19 return this.document.createElement( 'img', { attributes : attributes } ); 19 20 }; 21 22 CKEDITOR.editor.prototype.restoreRealElement = function( fakeElement ) 23 { 24 var html = decodeURIComponent( fakeElement.getAttribute( '_cke_realelement' ) ), 25 realElement = CKEDITOR.dom.element.createFromHtml( html, this.document ); 26 27 if ( fakeElement.$.style.width ) 28 realElement.setStyle( 'width', fakeElement.$.style.width ); 29 if ( fakeElement.$.style.height ) 30 realElement.setStyle( 'height', fakeElement.$.style.height ); 31 32 return realElement; 33 }; -
_source/plugins/link/plugin.js
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 CKEDITOR.plugins.add( 'link', 7 { 8 init : function( editor, pluginPath ) 9 { 10 // Add the link and unlink buttons. 11 editor.addCommand( 'link', new CKEDITOR.dialogCommand( 'link' ) ); 12 editor.addCommand( 'anchor', new CKEDITOR.dialogCommand( 'anchor' ) ); 13 editor.addCommand( 'unlink', new CKEDITOR.unlinkCommand() ); 14 editor.ui.addButton( 'Link', 15 { 16 label : editor.lang.link.toolbar, 17 command : 'link' 18 } ); 19 editor.ui.addButton( 'Unlink', 20 { 21 label : editor.lang.unlink, 22 command : 'unlink' 23 } ); 24 editor.ui.addButton( 'Anchor', 25 { 26 label : editor.lang.anchor.toolbar, 27 command : 'anchor' 28 } ); 29 CKEDITOR.dialog.add( 'link', this.path + 'dialogs/link.js' ); 30 CKEDITOR.dialog.add( 'anchor', this.path + 'dialogs/anchor.js' ); 31 32 // Add the CSS styles for anchor placeholders. 33 editor.addCss( 34 'img.cke_anchor' + 35 '{' + 36 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' + 37 'background-position: center center;' + 38 'background-repeat: no-repeat;' + 39 'border: 1px solid #a9a9a9;' + 40 'width: 18px;' + 41 'height: 18px;' + 42 '}\n' + 43 'a.cke_anchor' + 44 '{' + 45 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' + 46 'background-position: 0 center;' + 47 'background-repeat: no-repeat;' + 48 'border: 1px solid #a9a9a9;' + 49 'padding-left: 18px;' + 50 '}' 51 ); 52 53 // Register selection change handler for the unlink button. 54 editor.on( 'selectionChange', function( evt ) 55 { 56 /* 57 * Despite our initial hope, document.queryCommandEnabled() does not work 58 * for this in Firefox. So we must detect the state by element paths. 59 */ 60 var command = editor.getCommand( 'unlink' ), 61 element = evt.data.path.lastElement.getAscendant( 'a', true ); 62 if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) ) 63 command.state = CKEDITOR.TRISTATE_OFF; 64 else 65 command.state = CKEDITOR.TRISTATE_DISABLED; 66 command.fire( 'state' ); 67 } ); 68 69 // Register a contentDom handler for displaying placeholders after mode change. 70 editor.on( 'contentDom', function() 71 { 72 var rawAnchors = editor.document.$.anchors; 73 for ( var i = rawAnchors.length - 1, anchor ; i >= 0 ; i-- ) 74 { 75 anchor = new CKEDITOR.dom.element( rawAnchors[ i ] ); 76 77 // IE BUG: When an <a> tag doesn't have href, IE would return empty string 78 // instead of null on getAttribute. 79 if ( !anchor.getAttribute( 'href' ) ) 80 editor.createFakeElement( anchor, 'cke_anchor', 'anchor' ).replace( anchor ); 81 else 82 anchor.addClass( 'cke_anchor' ); 83 } 84 } ); 85 }, 86 87 requires : [ 'fakeobjects' ] 88 } ); 89 90 CKEDITOR.unlinkCommand = function(){}; 91 CKEDITOR.unlinkCommand.prototype = 92 { 93 /** @ignore */ 94 exec : function( editor ) 95 { 96 /* 97 * execCommand( 'unlink', ... ) in Firefox leaves behind <span> tags at where 98 * the <a> was, so again we have to remove the link ourselves. (See #430) 99 * 100 * TODO: Use the style system when it's complete. Let's use execCommand() 101 * as a stopgap solution for now. 102 */ 103 var selection = editor.getSelection(), 104 bookmarks = selection.createBookmarks(), 105 ranges = selection.getRanges(), 106 rangeRoot, 107 element; 108 109 for ( var i = 0 ; i < ranges.length ; i++ ) 110 { 111 rangeRoot = ranges[i].getCommonAncestor( true ); 112 element = rangeRoot.getAscendant( 'a', true ); 113 if ( !element ) 114 continue; 115 ranges[i].selectNodeContents( element ); 116 } 117 118 selection.selectRanges( ranges ); 119 editor.document.$.execCommand( 'unlink', false, null ); 120 selection.selectBookmarks( bookmarks ); 121 } 122 }; 123 124 CKEDITOR.config.link = 125 { 126 uploadTab : true, 127 browseServer : true, 128 uploadAction : 'nowhere.php', 129 showAdvancedTab : true, 130 showTargetTab : true, 131 defaultValues : 132 { 133 /** 134 * Startup values 135 * @type Text 136 * @default '' 137 */ 138 linkType : 'url', 139 protocol : 'http://', 140 target : 'notSet', 141 targetFrameName : '', 142 title : '', 143 type : '', 144 classes : '', 145 langDir : '', 146 langCode : '', 147 charset : '', 148 style : '' 149 } 150 }; -
_source/plugins/link/dialogs/anchor.js
Property changes on: _source\plugins\link\plugin.js ___________________________________________________________________ Name: svn:executable + *
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 CKEDITOR.dialog.add( 'anchor', function( editor ) 7 { 8 // Function called in onShow to load selected element. 9 var loadElements = function( editor, selection, ranges, element ) 10 { 11 this.saveSelection(); 12 this.editMode = true; 13 this.editObj = element; 14 15 var attributeValue = this.editObj.getAttribute( 'name' ); 16 if ( attributeValue == null ) 17 this.setValueOf( 'info','txtName', "" ); 18 else 19 this.setValueOf( 'info','txtName', attributeValue ); 20 }; 21 22 return { 23 title : editor.lang.anchor.title, 24 minWidth : 350, 25 minHeight : 150, 26 onOk : function() 27 { 28 // Always create a new anchor, because of IE BUG. 29 var name = this.getValueOf( 'info', 'txtName' ), 30 element = CKEDITOR.env.ie ? 31 editor.document.createElement( '<a name="' + CKEDITOR.tools.htmlEncode( name ) + '">' ) : 32 editor.document.createElement( 'a' ); 33 34 // Move contents and attributes of old anchor to new anchor. 35 if ( this.editMode ) 36 { 37 this.editObj.copyAttributes( element, { name : 1 } ); 38 this.editObj.moveChildren( element ); 39 } 40 41 // Set name. 42 element.setAttribute( 'name', name ); 43 44 // Insert a new anchor. 45 var fakeElement = editor.createFakeElement( element, 'cke_anchor', 'anchor' ); 46 if ( !this.editMode ) 47 { 48 // It doesn't work with IE. 49 this.restoreSelection(); 50 this.clearSavedSelection(); 51 52 editor.insertElement( fakeElement ); 53 } 54 else 55 fakeElement.replace( this.fakeObj ); 56 return true; 57 }, 58 onShow : function() 59 { 60 this.editObj = false; 61 this.fakeObj = false; 62 this.editMode = false; 63 64 // IE BUG: Selection must be in the editor for getSelection() to work. 65 this.restoreSelection(); 66 67 var editor = this.getParentEditor(), 68 selection = editor.getSelection(), 69 ranges = selection.getRanges(); 70 71 if ( ranges.length == 1 ) 72 { 73 ranges[0].enlarge( CKEDITOR.ENLARGE_ELEMENT ); 74 rangeRoot = ranges[0].getCommonAncestor( true ); 75 var element = rangeRoot.getAscendant( 'img', true ); 76 if ( element && element.getAttribute( '_cke_real_element_type' ) && element.getAttribute( '_cke_real_element_type' ) == 'anchor' ) 77 { 78 this.fakeObj = element; 79 element = editor.restoreRealElement( this.fakeObj ); 80 loadElements.apply( this, [ editor, selection, ranges, element ] ); 81 selection.selectElement( this.fakeObj ); 82 this.saveSelection(); 83 } 84 } 85 this.pushDefault(); 86 this.getContentElement( 'info', 'txtName' ).focus(); 87 }, 88 onHide : function() 89 { 90 // Pop the default values from default value set that are pushed in onShow(). 91 this.popDefault(); 92 }, 93 contents : [ 94 { 95 id : 'info', 96 label : editor.lang.anchor.title, 97 accessKey : 'I', 98 elements : 99 [ 100 { 101 type : 'text', 102 id : 'txtName', 103 label : editor.lang.anchor.name, 104 validate : function() 105 { 106 if ( this.getValue() == '' ) 107 { 108 alert( editor.lang.anchor.errorName ); 109 return false; 110 } 111 return true; 112 } 113 }, 114 ] 115 } 116 ] 117 }; 118 } ); -
_source/plugins/link/dialogs/link.js
Property changes on: _source\plugins\link\dialogs\anchor.js ___________________________________________________________________ Name: svn:executable + *
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 CKEDITOR.dialog.add( 'link', function( editor ) 7 { 8 // Handles the event when the "Target" selection box is changed. 9 var targetChanged = function() 10 { 11 var dialog = this.getDialog(), 12 popupFeatures = dialog.getContentElement( 'target', 'popupFeatures' ), 13 targetName = dialog.getContentElement( 'target', 'linkTargetName' ), 14 value = this.getValue(); 15 16 if ( !popupFeatures || !targetName ) 17 return; 18 19 popupFeatures = popupFeatures.getElement(); 20 21 if ( value == 'popup' ) 22 { 23 popupFeatures.show(); 24 targetName.setLabel( editor.lang.link.targetPopupName ); 25 } 26 else 27 { 28 popupFeatures.hide(); 29 targetName.setLabel( editor.lang.link.targetFrameName ); 30 this.getDialog().setValueOf( 'target', 'linkTargetName', value.charAt( 0 ) == '_' ? value : '' ); 31 } 32 }, 33 // Handles the event when the "Type" selection box is changed. 34 linkTypeChanged = function() 35 { 36 var dialog = this.getDialog(), 37 partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ], 38 typeValue = this.getValue(); 39 if ( typeValue == 'url' ) 40 { 41 if ( editor.config.link.showTargetTab ) 42 dialog.showPage( 'target' ); 43 if ( editor.config.link.uploadTab ) 44 dialog.showPage( 'upload' ); 45 } 46 else 47 { 48 dialog.hidePage( 'target' ); 49 dialog.hidePage( 'upload' ); 50 } 51 52 for ( var i = 0 ; i < partIds.length ; i++ ) 53 { 54 var element = dialog.getContentElement( 'info', partIds[i] ); 55 if ( !element ) 56 continue; 57 58 element = element.getElement().getParent().getParent(); 59 if ( partIds[i] == typeValue + 'Options' ) 60 element.show(); 61 else 62 element.hide(); 63 } 64 }, 65 // Loads the parameters in a selected link to the link dialog fields. 66 emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/, 67 emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/, 68 emailBodyRegex = /body=([^;?:@&=$,\/]*)/, 69 anchorRegex = /^#(.*)$/, 70 urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/, 71 selectableTargets = /^(_(?:self|top|parent|blank))$/, 72 popupRegex = 73 /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/, 74 popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/gi, 75 parseLink = function( editor, element ) 76 { 77 var href = element ? ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) : '', 78 emailMatch = '', 79 anchorMatch = '', 80 urlMatch = false, 81 retval = {}; 82 83 if ( href != null ) 84 { 85 emailMatch = href.match( emailRegex ); 86 anchorMatch = href.match( anchorRegex ); 87 urlMatch = href.match( urlRegex ); 88 } 89 90 // Load the link type and URL. 91 if ( emailMatch ) 92 { 93 var subjectMatch = href.match( emailSubjectRegex ), 94 bodyMatch = href.match( emailBodyRegex ); 95 retval.type = 'email'; 96 retval.email = {}; 97 retval.email.address = emailMatch[1]; 98 subjectMatch && ( retval.email.subject = decodeURIComponent( subjectMatch[1] ) ); 99 bodyMatch && ( retval.email.body = decodeURIComponent( bodyMatch[1] ) ); 100 } 101 else if ( anchorMatch ) 102 { 103 retval.type = 'anchor'; 104 retval.anchor = {}; 105 retval.anchor.name = retval.anchor.id = anchorMatch[1]; 106 } 107 else if ( href && urlMatch ) // urlRegex matches empty strings, so need to check for href as well. 108 { 109 retval.type = 'url'; 110 retval.url = {}; 111 retval.url.protocol = urlMatch[1]; 112 retval.url.url = urlMatch[2]; 113 } 114 else 115 retval.type = 'url'; 116 117 // Load target and popup settings. 118 if ( element ) 119 { 120 var target = element.getAttribute( 'target' ); 121 retval.target = {}; 122 retval.adv = {}; 123 124 // IE BUG: target attribute is an empty string instead of null in IE if it's not set. 125 if ( !target ) 126 { 127 var onclick = element.getAttribute( '_cke_saved_onclick' ) || element.getAttribute( 'onclick' ), 128 onclickMatch = onclick && onclick.match( popupRegex ); 129 if ( onclickMatch ) 130 { 131 retval.target.type = 'popup'; 132 retval.target.name = onclickMatch[1]; 133 134 var featureMatch; 135 while ( ( featureMatch = popupFeaturesRegex.exec( onclickMatch[2] ) ) ) 136 { 137 if ( featureMatch[2] == 'yes' || featureMatch[2] == '1' ) 138 retval.target[ featureMatch[1] ] = true; 139 else if ( isFinite( featureMatch[2] ) ) 140 retval.target[ featureMatch[1] ] = featureMatch[2]; 141 } 142 } 143 } 144 else 145 { 146 var targetMatch = target.match( selectableTargets ); 147 if ( targetMatch ) 148 retval.target.type = retval.target.name = target; 149 else 150 { 151 retval.target.type = 'frame'; 152 retval.target.name = target; 153 } 154 } 155 156 var me = this, 157 advAttr = function( inputName, attrName ) 158 { 159 var value = element.getAttribute( attrName ); 160 if ( value != null ) 161 retval.adv[ inputName ] = value || ''; 162 }; 163 advAttr( 'advId', 'id' ); 164 advAttr( 'advLangDir', 'dir' ); 165 advAttr( 'advAccessKey', 'accessKey' ); 166 advAttr( 'advName', 'name' ); 167 advAttr( 'advLangCode', 'lang' ); 168 advAttr( 'advTabIndex', 'tabindex' ); 169 advAttr( 'advTitle', 'title' ); 170 advAttr( 'advContentType', 'type' ); 171 advAttr( 'advCSSClasses', 'class' ); 172 advAttr( 'advCharset', 'charset' ); 173 advAttr( 'advStyles', 'style' ); 174 } 175 176 // Find out whether we have any anchors in the editor. 177 // Get all IMG elements in CK document. 178 var elements = editor.document.$.getElementsByTagName( 'img' ), 179 realAnchors = editor.document.$.anchors, 180 anchors = retval.anchors = []; 181 for( var i = 0; i < elements.length ; i++ ) 182 { 183 var item = elements.item( i ); 184 if ( item.getAttribute( '_cke_realelement' ) && item.getAttribute( '_cke_real_element_type' ) == 'anchor' ) 185 { 186 var domElement = new CKEDITOR.dom.element( item ); 187 domElement = editor.restoreRealElement( domElement ); 188 anchors.push( domElement ); 189 } 190 } 191 for ( var i = 0 ; i < realAnchors.length ; i++ ) 192 anchors.push( realAnchors[i] ); 193 for ( var i = 0, item, length = anchors.length ; i < length && ( item = anchors.shift() ) ; i++ ) 194 anchors.push( { name : item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) } ); 195 196 // Record down the selected element in the dialog. 197 this._.selectedElement = element; 198 199 return retval; 200 }, 201 setupParams = function( page, data ) 202 { 203 if ( data[page] ) 204 this.setValue( data[page][this.id] || '' ); 205 }, 206 setupPopupParams = function( data ) 207 { 208 return setupParams.call( this, 'target', data ); 209 }, 210 setupAdvParams = function( data ) 211 { 212 return setupParams.call( this, 'adv', data ); 213 }, 214 commitParams = function( page, data ) 215 { 216 if ( !data[page] ) 217 data[page] = {}; 218 219 data[page][this.id] = this.getValue() || ''; 220 }, 221 commitPopupParams = function( data ) 222 { 223 return commitParams.call( this, 'target', data ); 224 }, 225 commitAdvParams = function( data ) 226 { 227 return commitParams.call( this, 'adv', data ); 228 }; 229 230 return { 231 title : editor.lang.link.title, 232 minWidth : 400, 233 minHeight : 320, 234 contents : [ 235 { 236 id : 'info', 237 label : editor.lang.link.info, 238 title : editor.lang.link.info, 239 elements : 240 [ 241 { 242 id : 'linkType', 243 type : 'select', 244 label : editor.lang.link.type, 245 'default' : editor.config.link.defaultValues.linkType, 246 items : 247 [ 248 [ editor.lang.common.url, 'url' ], 249 [ editor.lang.link.toAnchor, 'anchor' ], 250 [ editor.lang.link.toEmail, 'email' ] 251 ], 252 onChange : linkTypeChanged, 253 setup : function( data ) 254 { 255 if ( data.type ) 256 this.setValue( data.type ); 257 }, 258 commit : function( data ) 259 { 260 data.type = this.getValue(); 261 } 262 }, 263 { 264 type : 'vbox', 265 id : 'urlOptions', 266 children : 267 [ 268 { 269 type : 'hbox', 270 widths : [ '25%', '75%' ], 271 children : 272 [ 273 { 274 id : 'protocol', 275 type : 'select', 276 label : editor.lang.common.protocol, 277 'default' : editor.config.link.defaultValues.protocol, 278 style : 'width : 100%;', 279 items : 280 [ 281 [ 'http://' ], 282 [ 'https//' ], 283 [ 'ftp://' ], 284 [ 'news://' ], 285 [ '<other>', '' ] 286 ], 287 setup : function( data ) 288 { 289 if ( data.url ) 290 this.setValue( data.url.protocol ); 291 }, 292 commit : function( data ) 293 { 294 if ( !data.url ) 295 data.url = {}; 296 297 data.url.protocol = this.getValue(); 298 } 299 }, 300 { 301 type : 'text', 302 id : 'url', 303 label : editor.lang.common.url, 304 validate : function() 305 { 306 var dialog = this.getDialog(); 307 308 if ( dialog.getContentElement( 'info', 'linkType' ) && 309 dialog.getValueOf( 'info', 'linkType' ) != 'url' ) 310 return true; 311 312 if ( this.getDialog().fakeObj != false ) // Edit Anchor. 313 return true; 314 315 var func = CKEDITOR.dialog.validate.notEmpty( editor.lang.link.noUrl ); 316 return func.apply( this ); 317 }, 318 setup : function( data ) 319 { 320 if ( data.url ) 321 this.setValue( data.url.url ); 322 323 var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); 324 if ( linkType && linkType.getValue() == 'url' ) 325 this.select(); 326 }, 327 commit : function( data ) 328 { 329 if ( !data.url ) 330 data.url = {}; 331 332 data.url.url = this.getValue(); 333 } 334 } 335 ], 336 setup : function( data ) 337 { 338 if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) 339 this.getElement().show(); 340 } 341 }, 342 { 343 type : 'button', 344 id : 'browse', 345 label : editor.lang.common.browseServer 346 } 347 ] 348 }, 349 { 350 type : 'vbox', 351 id : 'anchorOptions', 352 width : 260, 353 align : 'center', 354 padding : 0, 355 children : 356 [ 357 { 358 type : 'html', 359 id : 'selectAnchorText', 360 html : CKEDITOR.tools.htmlEncode( editor.lang.link.selectAnchor ), 361 setup : function( data ) 362 { 363 if ( data.anchors.length > 0 ) 364 this.getElement().show(); 365 else 366 this.getElement().hide(); 367 } 368 }, 369 { 370 type : 'html', 371 id : 'noAnchors', 372 style : 'text-align: center;', 373 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.link.noAnchors ) + '</div>', 374 setup : function( data ) 375 { 376 if ( data.anchors.length < 1 ) 377 this.getElement().show(); 378 else 379 this.getElement().hide(); 380 } 381 }, 382 { 383 type : 'hbox', 384 id : 'selectAnchor', 385 children : 386 [ 387 { 388 type : 'select', 389 id : 'anchorName', 390 'default' : '', 391 label : editor.lang.link.anchorName, 392 style : 'width: 100%;', 393 items : 394 [ 395 [ '' ] 396 ], 397 setup : function( data ) 398 { 399 this.clear(); 400 this.add( '' ); 401 for ( var i = 0 ; i < data.anchors.length ; i++ ) 402 { 403 if ( data.anchors[i].name ) 404 this.add( data.anchors[i].name ); 405 } 406 407 if ( data.anchor ) 408 this.setValue( data.anchor.name ); 409 410 var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); 411 if ( linkType && linkType.getValue() == 'email' ) 412 this.focus(); 413 }, 414 commit : function( data ) 415 { 416 if ( !data.anchor ) 417 data.anchor = {}; 418 419 data.anchor.name = this.getValue(); 420 } 421 }, 422 { 423 type : 'select', 424 id : 'anchorId', 425 'default' : '', 426 label : editor.lang.link.anchorId, 427 style : 'width: 100%;', 428 items : 429 [ 430 [ '' ] 431 ], 432 setup : function( data ) 433 { 434 this.clear(); 435 this.add( '' ); 436 for ( var i = 0 ; i < data.anchors.length ; i++ ) 437 { 438 if ( data.anchors[i].id ) 439 this.add( data.anchors[i].id ); 440 } 441 442 if ( data.anchor ) 443 this.setValue( data.anchor.id ); 444 }, 445 commit : function( data ) 446 { 447 if ( !data.anchor ) 448 data.anchor = {}; 449 450 data.anchor.id = this.getValue(); 451 } 452 } 453 ], 454 setup : function( data ) 455 { 456 if ( data.anchors.length > 0 ) 457 this.getElement().show(); 458 else 459 this.getElement().hide(); 460 } 461 } 462 ], 463 setup : function( data ) 464 { 465 if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) 466 this.getElement().hide(); 467 } 468 }, 469 { 470 type : 'vbox', 471 id : 'emailOptions', 472 padding : 1, 473 children : 474 [ 475 { 476 type : 'text', 477 id : 'emailAddress', 478 label : editor.lang.link.emailAddress, 479 validate : function() 480 { 481 var dialog = this.getDialog(); 482 483 if ( !dialog.getContentElement( 'info', 'linkType' ) || 484 dialog.getValueOf( 'info', 'linkType' ) != 'email' ) 485 return true; 486 487 var func = CKEDITOR.dialog.validate.notEmpty( editor.lang.link.noEmail ); 488 return func.apply( this ); 489 }, 490 setup : function( data ) 491 { 492 if ( data.email ) 493 this.setValue( data.email.address ); 494 495 var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); 496 if ( linkType && linkType.getValue() == 'email' ) 497 this.select(); 498 }, 499 commit : function( data ) 500 { 501 if ( !data.email ) 502 data.email = {}; 503 504 data.email.address = this.getValue(); 505 } 506 }, 507 { 508 type : 'text', 509 id : 'emailSubject', 510 label : editor.lang.link.emailSubject, 511 setup : function( data ) 512 { 513 if ( data.email ) 514 this.setValue( data.email.subject ); 515 }, 516 commit : function( data ) 517 { 518 if ( !data.email ) 519 data.email = {}; 520 521 data.email.subject = this.getValue(); 522 } 523 }, 524 { 525 type : 'textarea', 526 id : 'emailBody', 527 label : editor.lang.link.emailBody, 528 rows : 3, 529 'default' : '', 530 setup : function( data ) 531 { 532 if ( data.email ) 533 this.setValue( data.email.body ); 534 }, 535 commit : function( data ) 536 { 537 if ( !data.email ) 538 data.email = {}; 539 540 data.email.body = this.getValue(); 541 } 542 } 543 ], 544 setup : function( data ) 545 { 546 if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) 547 this.getElement().hide(); 548 } 549 } 550 ] 551 }, 552 { 553 id : 'target', 554 label : editor.lang.link.target, 555 title : editor.lang.link.target, 556 elements : 557 [ 558 { 559 type : 'hbox', 560 widths : [ '50%', '50%' ], 561 children : 562 [ 563 { 564 type : 'select', 565 id : 'linkTargetType', 566 label : editor.lang.link.target, 567 'default' : editor.config.link.defaultValues.target, 568 style : 'width : 100%;', 569 'items' : 570 [ 571 [ editor.lang.link.targetNotSet, 'notSet' ], 572 [ editor.lang.link.targetFrame, 'frame' ], 573 [ editor.lang.link.targetPopup, 'popup' ], 574 [ editor.lang.link.targetNew, '_blank' ], 575 [ editor.lang.link.targetTop, '_top' ], 576 [ editor.lang.link.targetSelf, '_self' ], 577 [ editor.lang.link.targetParent, '_parent' ] 578 ], 579 onChange : targetChanged, 580 setup : function( data ) 581 { 582 if ( data.target ) 583 this.setValue( data.target.type ); 584 }, 585 commit : function( data ) 586 { 587 if ( !data.target ) 588 data.target = {}; 589 590 data.target.type = this.getValue(); 591 } 592 }, 593 { 594 type : 'text', 595 id : 'linkTargetName', 596 label : editor.lang.link.targetFrameName, 597 'default' : editor.config.link.defaultValues.targetFrameName, 598 setup : function( data ) 599 { 600 if ( data.target ) 601 this.setValue( data.target.name ); 602 }, 603 commit : function( data ) 604 { 605 if ( !data.target ) 606 data.target = {}; 607 608 data.target.name = this.getValue(); 609 } 610 } 611 ] 612 }, 613 { 614 type : 'vbox', 615 width : 260, 616 align : 'center', 617 padding : 2, 618 id : 'popupFeatures', 619 children : 620 [ 621 { 622 type : 'html', 623 html : CKEDITOR.tools.htmlEncode( editor.lang.link.popupFeatures ) 624 }, 625 { 626 type : 'hbox', 627 children : 628 [ 629 { 630 type : 'checkbox', 631 id : 'resizable', 632 label : editor.lang.link.popupResizable, 633 setup : setupPopupParams, 634 commit : commitPopupParams 635 }, 636 { 637 type : 'checkbox', 638 id : 'status', 639 label : editor.lang.link.popupStatusBar, 640 setup : setupPopupParams, 641 commit : commitPopupParams 642 643 } 644 ] 645 }, 646 { 647 type : 'hbox', 648 children : 649 [ 650 { 651 type : 'checkbox', 652 id : 'location', 653 label : editor.lang.link.popupLocationBar, 654 setup : setupPopupParams, 655 commit : commitPopupParams 656 657 }, 658 { 659 type : 'checkbox', 660 id : 'toolbar', 661 label : editor.lang.link.popupToolbar, 662 setup : setupPopupParams, 663 commit : commitPopupParams 664 665 } 666 ] 667 }, 668 { 669 type : 'hbox', 670 children : 671 [ 672 { 673 type : 'checkbox', 674 id : 'menubar', 675 label : editor.lang.link.popupMenuBar, 676 setup : setupPopupParams, 677 commit : commitPopupParams 678 679 }, 680 { 681 type : 'checkbox', 682 id : 'fullscreen', 683 label : editor.lang.link.popupFullScreen, 684 setup : setupPopupParams, 685 commit : commitPopupParams 686 687 } 688 ] 689 }, 690 { 691 type : 'hbox', 692 children : 693 [ 694 { 695 type : 'checkbox', 696 id : 'scrollbars', 697 label : editor.lang.link.popupScrollBars, 698 setup : setupPopupParams, 699 commit : commitPopupParams 700 701 }, 702 { 703 type : 'checkbox', 704 id : 'dependent', 705 label : editor.lang.link.popupDependent, 706 setup : setupPopupParams, 707 commit : commitPopupParams 708 709 } 710 ] 711 }, 712 { 713 type : 'hbox', 714 children : 715 [ 716 { 717 type : 'text', 718 widths : [ '30%', '70%' ], 719 labelLayout : 'horizontal', 720 label : editor.lang.link.popupWidth, 721 id : 'width', 722 setup : setupPopupParams, 723 commit : commitPopupParams 724 725 }, 726 { 727 type : 'text', 728 labelLayout : 'horizontal', 729 widths : [ '55%', '45%' ], 730 label : editor.lang.link.popupLeft, 731 id : 'left', 732 setup : setupPopupParams, 733 commit : commitPopupParams 734 735 } 736 ] 737 }, 738 { 739 type : 'hbox', 740 children : 741 [ 742 { 743 type : 'text', 744 labelLayout : 'horizontal', 745 widths : [ '30%', '70%' ], 746 label : editor.lang.link.popupHeight, 747 id : 'height', 748 setup : setupPopupParams, 749 commit : commitPopupParams 750 751 }, 752 { 753 type : 'text', 754 labelLayout : 'horizontal', 755 label : editor.lang.link.popupTop, 756 widths : [ '55%', '45%' ], 757 id : 'top', 758 setup : setupPopupParams, 759 commit : commitPopupParams 760 761 } 762 ] 763 } 764 ] 765 } 766 ] 767 }, 768 { 769 id : 'upload', 770 label : editor.lang.link.upload, 771 title : editor.lang.link.upload, 772 elements : 773 [ 774 { 775 type : 'file', 776 id : 'upload', 777 label : editor.lang.common.upload, 778 action : editor.config.link.uploadAction, 779 size : 38 780 }, 781 { 782 type : 'fileButton', 783 id : 'uploadButton', 784 label : editor.lang.common.uploadSubmit, 785 'for' : [ 'upload', 'upload' ] 786 } 787 ] 788 }, 789 { 790 id : 'advanced', 791 label : editor.lang.link.advanced, 792 title : editor.lang.link.advanced, 793 elements : 794 [ 795 { 796 type : 'vbox', 797 padding : 1, 798 children : 799 [ 800 { 801 type : 'hbox', 802 widths : [ '45%', '35%', '20%' ], 803 children : 804 [ 805 { 806 type : 'text', 807 id : 'advId', 808 label : editor.lang.link.id, 809 setup : setupAdvParams, 810 commit : commitAdvParams 811 }, 812 { 813 type : 'select', 814 id : 'advLangDir', 815 label : editor.lang.link.langDir, 816 'default' : editor.config.link.defaultValues.langDir, 817 style : 'width: 100%;', 818 items : 819 [ 820 [ editor.lang.link.langDirNotSet, '' ], 821 [ editor.lang.link.langDirLTR, 'ltr' ], 822 [ editor.lang.link.langDirRTL, 'rtl' ] 823 ], 824 setup : setupAdvParams, 825 commit : commitAdvParams 826 }, 827 { 828 type : 'text', 829 id : 'advAccessKey', 830 label : editor.lang.link.acccessKey, 831 maxLength : 1, 832 setup : setupAdvParams, 833 commit : commitAdvParams 834 835 } 836 ] 837 }, 838 { 839 type : 'hbox', 840 widths : [ '45%', '35%', '20%' ], 841 children : 842 [ 843 { 844 type : 'text', 845 label : editor.lang.link.name, 846 id : 'advName', 847 setup : setupAdvParams, 848 commit : commitAdvParams 849 850 }, 851 { 852 type : 'text', 853 label : editor.lang.link.langCode, 854 id : 'advLangCode', 855 'default' : editor.config.link.defaultValues.langCode, 856 setup : setupAdvParams, 857 commit : commitAdvParams 858 859 }, 860 { 861 type : 'text', 862 label : editor.lang.link.tabIndex, 863 id : 'advTabIndex', 864 maxLength : 5, 865 setup : setupAdvParams, 866 commit : commitAdvParams 867 868 } 869 ] 870 } 871 ] 872 }, 873 { 874 type : 'vbox', 875 padding : 1, 876 children : 877 [ 878 { 879 type : 'hbox', 880 widths : [ '45%', '55%' ], 881 children : 882 [ 883 { 884 type : 'text', 885 label : editor.lang.link.advisoryTitle, 886 'default' : editor.config.link.defaultValues.title, 887 id : 'advTitle', 888 setup : setupAdvParams, 889 commit : commitAdvParams 890 891 }, 892 { 893 type : 'text', 894 label : editor.lang.link.advisoryContentType, 895 'default' : editor.config.link.defaultValues.type, 896 id : 'advContentType', 897 setup : setupAdvParams, 898 commit : commitAdvParams 899 900 } 901 ] 902 }, 903 { 904 type : 'hbox', 905 widths : [ '45%', '55%' ], 906 children : 907 [ 908 { 909 type : 'text', 910 label : editor.lang.link.cssClasses, 911 'default' : editor.config.link.defaultValues.classes, 912 id : 'advCSSClasses', 913 setup : setupAdvParams, 914 commit : commitAdvParams 915 916 }, 917 { 918 type : 'text', 919 label : editor.lang.link.charset, 920 'default' : editor.config.link.defaultValues.charset, 921 id : 'advCharset', 922 setup : setupAdvParams, 923 commit : commitAdvParams 924 925 } 926 ] 927 }, 928 { 929 type : 'hbox', 930 children : 931 [ 932 { 933 type : 'text', 934 label : editor.lang.link.styles, 935 'default' : editor.config.link.defaultValues.style, 936 id : 'advStyles', 937 setup : setupAdvParams, 938 commit : commitAdvParams 939 940 } 941 ] 942 } 943 ] 944 } 945 ] 946 } 947 ], 948 onShow : function() 949 { 950 this.fakeObj = false; 951 // IE BUG: Selection must be in the editor for getSelection() to work. 952 this.restoreSelection(); 953 var editor = this.getParentEditor(), 954 selection = editor.getSelection(), 955 ranges = selection.getRanges(), 956 element = null, 957 me = this; 958 959 // Fill in all the relevant fields if there's already one link selected. 960 if ( ranges.length == 1 ) 961 { 962 ranges[0].enlarge( CKEDITOR.ENLARGE_ELEMENT ); 963 964 var rangeRoot = ranges[0].getCommonAncestor( true ); 965 element = rangeRoot.getAscendant( 'a', true ); 966 if ( element && element.getAttribute( 'href' ) ) 967 { 968 selection.selectElement( element ); 969 this.saveSelection(); 970 } 971 else 972 { 973 element = rangeRoot.getAscendant( 'img', true ); 974 if ( element && element.getAttribute( '_cke_real_element_type' ) && element.getAttribute( '_cke_real_element_type' ) == 'anchor' ) 975 { 976 this.fakeObj = element; 977 element = editor.restoreRealElement( this.fakeObj ); 978 selection.selectElement( this.fakeObj ); 979 this.saveSelection(); 980 } 981 } 982 } 983 984 this.setupContent( parseLink.apply( this, [ editor, element ] ) ); 985 986 // Push the current values into the dialog default value stack. 987 this.pushDefault(); 988 }, 989 onOk : function() 990 { 991 var attributes = { href : 'javascript:void(0)/*' + CKEDITOR.tools.getNextNumber() + '*/' }, 992 removeAttributes = [], 993 data = { href : attributes.href }, 994 me = this, editor = this.getParentEditor(); 995 996 this.commitContent( data ); 997 998 // Compose the URL. 999 switch ( data.type || 'url' ) 1000 { 1001 case 'url': 1002 var protocol = ( data.url && data.url.protocol ) || 'http://', 1003 url = ( data.url && data.url.url ) || ''; 1004 attributes._cke_saved_href = protocol + url; 1005 break; 1006 case 'anchor': 1007 var name = ( data.anchor && data.anchor.name ), 1008 id = ( data.anchor && data.anchor.id ); 1009 attributes._cke_saved_href = '#' + ( name || id || '' ); 1010 break; 1011 case 'email': 1012 var address = ( data.email && data.email.address ), 1013 subject = ( data.email && encodeURIComponent( data.email.subject || '' ) ), 1014 body = ( data.email && encodeURIComponent( data.email.body || '' ) ), 1015 linkList = [ 'mailto:', address ]; 1016 if ( subject || body ) 1017 { 1018 var argList = []; 1019 linkList.push( '?' ); 1020 subject && argList.push( 'subject=' + subject ); 1021 body && argList.push( 'body=' + body ); 1022 linkList.push( argList.join( '&' ) ); 1023 } 1024 attributes._cke_saved_href = linkList.join( '' ); 1025 break; 1026 default: 1027 } 1028 1029 // Popups and target. 1030 if ( data.target ) 1031 { 1032 if ( data.target.type == 'popup' ) 1033 { 1034 var onclickList = [ 'window.open(this.href, \'', 1035 data.target.name || '', '\', \'' ], 1036 featureList = [ 'resizable', 'status', 'location', 'toolbar', 'menubar', 'fullscreen', 1037 'scrollbars', 'dependent' ], 1038 featureLength = featureList.length, 1039 addFeature = function( featureName ) 1040 { 1041 if ( data.target[ featureName ] ) 1042 featureList.push( featureName + '=' + data.target[ featureName ] ); 1043 }; 1044 1045 for ( var i = 0 ; i < featureLength ; i++ ) 1046 featureList[i] = featureList[i] + ( data.target[ featureList[i] ] ? '=yes' : '=no' ) ; 1047 addFeature( 'width' ); 1048 addFeature( 'left' ); 1049 addFeature( 'height' ); 1050 addFeature( 'top' ); 1051 1052 onclickList.push( featureList.join( ',' ), '\'); return false;' ); 1053 attributes._cke_saved_onclick = onclickList.join( '' ); 1054 } 1055 else 1056 { 1057 if ( data.target.type != 'notSet' && data.target.name ) 1058 attributes.target = data.target.name; 1059 removeAttributes.push( '_cke_saved_onclick', 'onclick' ); 1060 } 1061 } 1062 1063 // Advanced attributes. 1064 if ( data.adv ) 1065 { 1066 var advAttr = function( inputName, attrName ) 1067 { 1068 var value = data.adv[ inputName ]; 1069 if ( value ) 1070 attributes[attrName] = value; 1071 else 1072 removeAttributes.push( attrName ); 1073 }; 1074 1075 if ( this._.selectedElement ) 1076 advAttr( 'advId', 'id' ); 1077 advAttr( 'advLangDir', 'dir' ); 1078 advAttr( 'advAccessKey', 'accessKey' ); 1079 advAttr( 'advName', 'name' ); 1080 advAttr( 'advLangCode', 'lang' ); 1081 advAttr( 'advTabIndex', 'tabindex' ); 1082 advAttr( 'advTitle', 'title' ); 1083 advAttr( 'advContentType', 'type' ); 1084 advAttr( 'advCSSClasses', 'class' ); 1085 advAttr( 'advCharset', 'charset' ); 1086 advAttr( 'advStyles', 'style' ); 1087 } 1088 1089 if ( !this._.selectedElement ) 1090 { 1091 // IE BUG: Selection must be in the editor for getSelection() to work. 1092 this.restoreSelection(); 1093 this.clearSavedSelection(); 1094 1095 // Create element if current selection is collapsed. 1096 var selection = editor.getSelection(), 1097 ranges = selection.getRanges(); 1098 if ( ranges.length == 1 && ranges[0].collapsed ) 1099 { 1100 var text = new CKEDITOR.dom.text( attributes._cke_saved_href, editor.document ); 1101 ranges[0].insertNode( text ); 1102 ranges[0].selectNodeContents( text ); 1103 selection.selectRanges( ranges ); 1104 } 1105 1106 // Apply style. 1107 var style = new CKEDITOR.style( { element : 'a', attributes : attributes } ); 1108 style.type = CKEDITOR.STYLE_INLINE; // need to override... dunno why. 1109 style.apply( editor.document ); 1110 1111 // Id. Apply only to the first link. 1112 if ( data.adv && data.adv.advId != '' ) 1113 { 1114 var links = this.getParentEditor().document.$.getElementsByTagName( 'a' ); 1115 for ( var i = 0 ; i < links.length ; i++ ) 1116 { 1117 if ( links[i].href == attributes.href ) 1118 { 1119 links[i].id = data.adv.advId; 1120 break; 1121 } 1122 } 1123 } 1124 } 1125 else 1126 { 1127 // We're only editing an existing link, so just overwrite the attributes. 1128 var element = this._.selectedElement; 1129 1130 // IE BUG: Setting the name attribute to an existing link doesn't work. 1131 // Must re-create the link from weired syntax to workaround. 1132 if ( CKEDITOR.env.ie && attributes.name != element.getAttribute( 'name' ) ) 1133 { 1134 var newElement = new CKEDITOR.dom.element( '<a name="' + CKEDITOR.tools.htmlEncode( attributes.name ) + '">', 1135 editor.document ); 1136 1137 this.restoreSelection(); 1138 var selection = editor.getSelection(); 1139 1140 element.moveChildren( newElement ); 1141 element.copyAttributes( newElement, { name : 1 } ); 1142 newElement.replace( element ); 1143 element = newElement; 1144 1145 this.clearSavedSelection(); 1146 selection.selectElement( element ); 1147 } 1148 1149 element.setAttributes( attributes ); 1150 element.removeAttributes( removeAttributes ); 1151 1152 // Make the element display as an anchor if a name has been set. 1153 if ( element.getAttribute( 'name' ) ) 1154 element.addClass( 'cke_anchor' ); 1155 else 1156 element.removeClass( 'cke_anchor' ); 1157 1158 if ( this.fakeObj ) 1159 editor.createFakeElement( element, 'cke_anchor', 'anchor' ).replace( this.fakeObj ); 1160 1161 delete this._.selectedElement; 1162 } 1163 }, 1164 onLoad : function() 1165 { 1166 if ( editor.config.link.uploadTab == false ) 1167 this.hidePage( 'upload' ); //Hide Upload tab. 1168 1169 if ( editor.config.link.showAdvancedTab == false ) 1170 this.hidePage( 'advanced' ); //Hide Advanded tab. 1171 1172 if ( editor.config.link.browseServer == false ) 1173 this.getContentElement( 'info', 'browse' ).getElement().hide(); 1174 1175 if ( editor.config.link.showTargetTab == false ) 1176 this.hidePage( 'target' ); //Hide Target tab. 1177 1178 }, 1179 onHide : function() 1180 { 1181 // Pop the default values from default value set that are pushed in onShow(). 1182 this.popDefault(); 1183 } 1184 }; 1185 } ); -
_source/plugins/link/dialogs/anchor.js
Property changes on: _source\plugins\link\dialogs\link.js ___________________________________________________________________ Name: svn:executable + *
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 CKEDITOR.dialog.add( 'anchor', function( editor ) 7 { 8 // Function called in onShow to load selected element. 9 var loadElements = function( editor, selection, ranges, element ) 10 { 11 this.saveSelection(); 12 this.editMode = true; 13 this.editObj = element; 14 15 var attributeValue = this.editObj.getAttribute( 'name' ); 16 if ( attributeValue == null ) 17 this.setValueOf( 'info','txtName', "" ); 18 else 19 this.setValueOf( 'info','txtName', attributeValue ); 20 }; 21 22 return { 23 title : editor.lang.anchor.title, 24 minWidth : 350, 25 minHeight : 150, 26 onOk : function() 27 { 28 // Always create a new anchor, because of IE BUG. 29 var name = this.getValueOf( 'info', 'txtName' ), 30 element = CKEDITOR.env.ie ? 31 editor.document.createElement( '<a name="' + CKEDITOR.tools.htmlEncode( name ) + '">' ) : 32 editor.document.createElement( 'a' ); 33 34 // Move contents and attributes of old anchor to new anchor. 35 if ( this.editMode ) 36 { 37 this.editObj.copyAttributes( element, { name : 1 } ); 38 this.editObj.moveChildren( element ); 39 } 40 41 // Set name. 42 element.setAttribute( 'name', name ); 43 44 // Insert a new anchor. 45 var fakeElement = editor.createFakeElement( element, 'cke_anchor', 'anchor' ); 46 if ( !this.editMode ) 47 { 48 // It doesn't work with IE. 49 this.restoreSelection(); 50 this.clearSavedSelection(); 51 52 editor.insertElement( fakeElement ); 53 } 54 else 55 fakeElement.replace( this.fakeObj ); 56 return true; 57 }, 58 onShow : function() 59 { 60 this.editObj = false; 61 this.fakeObj = false; 62 this.editMode = false; 63 64 // IE BUG: Selection must be in the editor for getSelection() to work. 65 this.restoreSelection(); 66 67 var editor = this.getParentEditor(), 68 selection = editor.getSelection(), 69 ranges = selection.getRanges(); 70 71 if ( ranges.length == 1 ) 72 { 73 ranges[0].enlarge( CKEDITOR.ENLARGE_ELEMENT ); 74 rangeRoot = ranges[0].getCommonAncestor( true ); 75 var element = rangeRoot.getAscendant( 'img', true ); 76 if ( element && element.getAttribute( '_cke_real_element_type' ) && element.getAttribute( '_cke_real_element_type' ) == 'anchor' ) 77 { 78 this.fakeObj = element; 79 element = editor.restoreRealElement( this.fakeObj ); 80 loadElements.apply( this, [ editor, selection, ranges, element ] ); 81 selection.selectElement( this.fakeObj ); 82 this.saveSelection(); 83 } 84 } 85 this.pushDefault(); 86 this.getContentElement( 'info', 'txtName' ).focus(); 87 }, 88 onHide : function() 89 { 90 // Pop the default values from default value set that are pushed in onShow(). 91 this.popDefault(); 92 }, 93 contents : [ 94 { 95 id : 'info', 96 label : editor.lang.anchor.title, 97 accessKey : 'I', 98 elements : 99 [ 100 { 101 type : 'text', 102 id : 'txtName', 103 label : editor.lang.anchor.name, 104 validate : function() 105 { 106 if ( this.getValue() == '' ) 107 { 108 alert( editor.lang.anchor.errorName ); 109 return false; 110 } 111 return true; 112 } 113 }, 114 ] 115 } 116 ] 117 }; 118 } ); -
_source/plugins/link/dialogs/link.js
Property changes on: _source\plugins\link\dialogs\anchor.js ___________________________________________________________________ Name: svn:executable + *
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 CKEDITOR.dialog.add( 'link', function( editor ) 7 { 8 // Handles the event when the "Target" selection box is changed. 9 var targetChanged = function() 10 { 11 var dialog = this.getDialog(), 12 popupFeatures = dialog.getContentElement( 'target', 'popupFeatures' ), 13 targetName = dialog.getContentElement( 'target', 'linkTargetName' ), 14 value = this.getValue(); 15 16 if ( !popupFeatures || !targetName ) 17 return; 18 19 popupFeatures = popupFeatures.getElement(); 20 21 if ( value == 'popup' ) 22 { 23 popupFeatures.show(); 24 targetName.setLabel( editor.lang.link.targetPopupName ); 25 } 26 else 27 { 28 popupFeatures.hide(); 29 targetName.setLabel( editor.lang.link.targetFrameName ); 30 this.getDialog().setValueOf( 'target', 'linkTargetName', value.charAt( 0 ) == '_' ? value : '' ); 31 } 32 }, 33 // Handles the event when the "Type" selection box is changed. 34 linkTypeChanged = function() 35 { 36 var dialog = this.getDialog(), 37 partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ], 38 typeValue = this.getValue(); 39 if ( typeValue == 'url' ) 40 { 41 if ( editor.config.link.showTargetTab ) 42 dialog.showPage( 'target' ); 43 if ( editor.config.link.uploadTab ) 44 dialog.showPage( 'upload' ); 45 } 46 else 47 { 48 dialog.hidePage( 'target' ); 49 dialog.hidePage( 'upload' ); 50 } 51 52 for ( var i = 0 ; i < partIds.length ; i++ ) 53 { 54 var element = dialog.getContentElement( 'info', partIds[i] ); 55 if ( !element ) 56 continue; 57 58 element = element.getElement().getParent().getParent(); 59 if ( partIds[i] == typeValue + 'Options' ) 60 element.show(); 61 else 62 element.hide(); 63 } 64 }, 65 // Loads the parameters in a selected link to the link dialog fields. 66 emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/, 67 emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/, 68 emailBodyRegex = /body=([^;?:@&=$,\/]*)/, 69 anchorRegex = /^#(.*)$/, 70 urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/, 71 selectableTargets = /^(_(?:self|top|parent|blank))$/, 72 popupRegex = 73 /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/, 74 popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/gi, 75 parseLink = function( editor, element ) 76 { 77 var href = element ? ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) : '', 78 emailMatch = '', 79 anchorMatch = '', 80 urlMatch = false, 81 retval = {}; 82 83 if ( href != null ) 84 { 85 emailMatch = href.match( emailRegex ); 86 anchorMatch = href.match( anchorRegex ); 87 urlMatch = href.match( urlRegex ); 88 } 89 90 // Load the link type and URL. 91 if ( emailMatch ) 92 { 93 var subjectMatch = href.match( emailSubjectRegex ), 94 bodyMatch = href.match( emailBodyRegex ); 95 retval.type = 'email'; 96 retval.email = {}; 97 retval.email.address = emailMatch[1]; 98 subjectMatch && ( retval.email.subject = decodeURIComponent( subjectMatch[1] ) ); 99 bodyMatch && ( retval.email.body = decodeURIComponent( bodyMatch[1] ) ); 100 } 101 else if ( anchorMatch ) 102 { 103 retval.type = 'anchor'; 104 retval.anchor = {}; 105 retval.anchor.name = retval.anchor.id = anchorMatch[1]; 106 } 107 else if ( href && urlMatch ) // urlRegex matches empty strings, so need to check for href as well. 108 { 109 retval.type = 'url'; 110 retval.url = {}; 111 retval.url.protocol = urlMatch[1]; 112 retval.url.url = urlMatch[2]; 113 } 114 else 115 retval.type = 'url'; 116 117 // Load target and popup settings. 118 if ( element ) 119 { 120 var target = element.getAttribute( 'target' ); 121 retval.target = {}; 122 retval.adv = {}; 123 124 // IE BUG: target attribute is an empty string instead of null in IE if it's not set. 125 if ( !target ) 126 { 127 var onclick = element.getAttribute( '_cke_saved_onclick' ) || element.getAttribute( 'onclick' ), 128 onclickMatch = onclick && onclick.match( popupRegex ); 129 if ( onclickMatch ) 130 { 131 retval.target.type = 'popup'; 132 retval.target.name = onclickMatch[1]; 133 134 var featureMatch; 135 while ( ( featureMatch = popupFeaturesRegex.exec( onclickMatch[2] ) ) ) 136 { 137 if ( featureMatch[2] == 'yes' || featureMatch[2] == '1' ) 138 retval.target[ featureMatch[1] ] = true; 139 else if ( isFinite( featureMatch[2] ) ) 140 retval.target[ featureMatch[1] ] = featureMatch[2]; 141 } 142 } 143 } 144 else 145 { 146 var targetMatch = target.match( selectableTargets ); 147 if ( targetMatch ) 148 retval.target.type = retval.target.name = target; 149 else 150 { 151 retval.target.type = 'frame'; 152 retval.target.name = target; 153 } 154 } 155 156 var me = this, 157 advAttr = function( inputName, attrName ) 158 { 159 var value = element.getAttribute( attrName ); 160 if ( value != null ) 161 retval.adv[ inputName ] = value || ''; 162 }; 163 advAttr( 'advId', 'id' ); 164 advAttr( 'advLangDir', 'dir' ); 165 advAttr( 'advAccessKey', 'accessKey' ); 166 advAttr( 'advName', 'name' ); 167 advAttr( 'advLangCode', 'lang' ); 168 advAttr( 'advTabIndex', 'tabindex' ); 169 advAttr( 'advTitle', 'title' ); 170 advAttr( 'advContentType', 'type' ); 171 advAttr( 'advCSSClasses', 'class' ); 172 advAttr( 'advCharset', 'charset' ); 173 advAttr( 'advStyles', 'style' ); 174 } 175 176 // Find out whether we have any anchors in the editor. 177 // Get all IMG elements in CK document. 178 var elements = editor.document.$.getElementsByTagName( 'img' ), 179 realAnchors = editor.document.$.anchors, 180 anchors = retval.anchors = []; 181 for( var i = 0; i < elements.length ; i++ ) 182 { 183 var item = elements.item( i ); 184 if ( item.getAttribute( '_cke_realelement' ) && item.getAttribute( '_cke_real_element_type' ) == 'anchor' ) 185 { 186 var domElement = new CKEDITOR.dom.element( item ); 187 domElement = editor.restoreRealElement( domElement ); 188 anchors.push( domElement ); 189 } 190 } 191 for ( var i = 0 ; i < realAnchors.length ; i++ ) 192 anchors.push( realAnchors[i] ); 193 for ( var i = 0, item, length = anchors.length ; i < length && ( item = anchors.shift() ) ; i++ ) 194 anchors.push( { name : item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) } ); 195 196 // Record down the selected element in the dialog. 197 this._.selectedElement = element; 198 199 return retval; 200 }, 201 setupParams = function( page, data ) 202 { 203 if ( data[page] ) 204 this.setValue( data[page][this.id] || '' ); 205 }, 206 setupPopupParams = function( data ) 207 { 208 return setupParams.call( this, 'target', data ); 209 }, 210 setupAdvParams = function( data ) 211 { 212 return setupParams.call( this, 'adv', data ); 213 }, 214 commitParams = function( page, data ) 215 { 216 if ( !data[page] ) 217 data[page] = {}; 218 219 data[page][this.id] = this.getValue() || ''; 220 }, 221 commitPopupParams = function( data ) 222 { 223 return commitParams.call( this, 'target', data ); 224 }, 225 commitAdvParams = function( data ) 226 { 227 return commitParams.call( this, 'adv', data ); 228 }; 229 230 return { 231 title : editor.lang.link.title, 232 minWidth : 400, 233 minHeight : 320, 234 contents : [ 235 { 236 id : 'info', 237 label : editor.lang.link.info, 238 title : editor.lang.link.info, 239 elements : 240 [ 241 { 242 id : 'linkType', 243 type : 'select', 244 label : editor.lang.link.type, 245 'default' : editor.config.link.defaultValues.linkType, 246 items : 247 [ 248 [ editor.lang.common.url, 'url' ], 249 [ editor.lang.link.toAnchor, 'anchor' ], 250 [ editor.lang.link.toEmail, 'email' ] 251 ], 252 onChange : linkTypeChanged, 253 setup : function( data ) 254 { 255 if ( data.type ) 256 this.setValue( data.type ); 257 }, 258 commit : function( data ) 259 { 260 data.type = this.getValue(); 261 } 262 }, 263 { 264 type : 'vbox', 265 id : 'urlOptions', 266 children : 267 [ 268 { 269 type : 'hbox', 270 widths : [ '25%', '75%' ], 271 children : 272 [ 273 { 274 id : 'protocol', 275 type : 'select', 276 label : editor.lang.common.protocol, 277 'default' : editor.config.link.defaultValues.protocol, 278 style : 'width : 100%;', 279 items : 280 [ 281 [ 'http://' ], 282 [ 'https//' ], 283 [ 'ftp://' ], 284 [ 'news://' ], 285 [ '<other>', '' ] 286 ], 287 setup : function( data ) 288 { 289 if ( data.url ) 290 this.setValue( data.url.protocol ); 291 }, 292 commit : function( data ) 293 { 294 if ( !data.url ) 295 data.url = {}; 296 297 data.url.protocol = this.getValue(); 298 } 299 }, 300 { 301 type : 'text', 302 id : 'url', 303 label : editor.lang.common.url, 304 validate : function() 305 { 306 var dialog = this.getDialog(); 307 308 if ( dialog.getContentElement( 'info', 'linkType' ) && 309 dialog.getValueOf( 'info', 'linkType' ) != 'url' ) 310 return true; 311 312 if ( this.getDialog().fakeObj != false ) // Edit Anchor. 313 return true; 314 315 var func = CKEDITOR.dialog.validate.notEmpty( editor.lang.link.noUrl ); 316 return func.apply( this ); 317 }, 318 setup : function( data ) 319 { 320 if ( data.url ) 321 this.setValue( data.url.url ); 322 323 var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); 324 if ( linkType && linkType.getValue() == 'url' ) 325 this.select(); 326 }, 327 commit : function( data ) 328 { 329 if ( !data.url ) 330 data.url = {}; 331 332 data.url.url = this.getValue(); 333 } 334 } 335 ], 336 setup : function( data ) 337 { 338 if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) 339 this.getElement().show(); 340 } 341 }, 342 { 343 type : 'button', 344 id : 'browse', 345 label : editor.lang.common.browseServer 346 } 347 ] 348 }, 349 { 350 type : 'vbox', 351 id : 'anchorOptions', 352 width : 260, 353 align : 'center', 354 padding : 0, 355 children : 356 [ 357 { 358 type : 'html', 359 id : 'selectAnchorText', 360 html : CKEDITOR.tools.htmlEncode( editor.lang.link.selectAnchor ), 361 setup : function( data ) 362 { 363 if ( data.anchors.length > 0 ) 364 this.getElement().show(); 365 else 366 this.getElement().hide(); 367 } 368 }, 369 { 370 type : 'html', 371 id : 'noAnchors', 372 style : 'text-align: center;', 373 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.link.noAnchors ) + '</div>', 374 setup : function( data ) 375 { 376 if ( data.anchors.length < 1 ) 377 this.getElement().show(); 378 else 379 this.getElement().hide(); 380 } 381 }, 382 { 383 type : 'hbox', 384 id : 'selectAnchor', 385 children : 386 [ 387 { 388 type : 'select', 389 id : 'anchorName', 390 'default' : '', 391 label : editor.lang.link.anchorName, 392 style : 'width: 100%;', 393 items : 394 [ 395 [ '' ] 396 ], 397 setup : function( data ) 398 { 399 this.clear(); 400 this.add( '' ); 401 for ( var i = 0 ; i < data.anchors.length ; i++ ) 402 { 403 if ( data.anchors[i].name ) 404 this.add( data.anchors[i].name ); 405 } 406 407 if ( data.anchor ) 408 this.setValue( data.anchor.name ); 409 410 var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); 411 if ( linkType && linkType.getValue() == 'email' ) 412 this.focus(); 413 }, 414 commit : function( data ) 415 { 416 if ( !data.anchor ) 417 data.anchor = {}; 418 419 data.anchor.name = this.getValue(); 420 } 421 }, 422 { 423 type : 'select', 424 id : 'anchorId', 425 'default' : '', 426 label : editor.lang.link.anchorId, 427 style : 'width: 100%;', 428 items : 429 [ 430 [ '' ] 431 ], 432 setup : function( data ) 433 { 434 this.clear(); 435 this.add( '' ); 436 for ( var i = 0 ; i < data.anchors.length ; i++ ) 437 { 438 if ( data.anchors[i].id ) 439 this.add( data.anchors[i].id ); 440 } 441 442 if ( data.anchor ) 443 this.setValue( data.anchor.id ); 444 }, 445 commit : function( data ) 446 { 447 if ( !data.anchor ) 448 data.anchor = {}; 449 450 data.anchor.id = this.getValue(); 451 } 452 } 453 ], 454 setup : function( data ) 455 { 456 if ( data.anchors.length > 0 ) 457 this.getElement().show(); 458 else 459 this.getElement().hide(); 460 } 461 } 462 ], 463 setup : function( data ) 464 { 465 if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) 466 this.getElement().hide(); 467 } 468 }, 469 { 470 type : 'vbox', 471 id : 'emailOptions', 472 padding : 1, 473 children : 474 [ 475 { 476 type : 'text', 477 id : 'emailAddress', 478 label : editor.lang.link.emailAddress, 479 validate : function() 480 { 481 var dialog = this.getDialog(); 482 483 if ( !dialog.getContentElement( 'info', 'linkType' ) || 484 dialog.getValueOf( 'info', 'linkType' ) != 'email' ) 485 return true; 486 487 var func = CKEDITOR.dialog.validate.notEmpty( editor.lang.link.noEmail ); 488 return func.apply( this ); 489 }, 490 setup : function( data ) 491 { 492 if ( data.email ) 493 this.setValue( data.email.address ); 494 495 var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); 496 if ( linkType && linkType.getValue() == 'email' ) 497 this.select(); 498 }, 499 commit : function( data ) 500 { 501 if ( !data.email ) 502 data.email = {}; 503 504 data.email.address = this.getValue(); 505 } 506 }, 507 { 508 type : 'text', 509 id : 'emailSubject', 510 label : editor.lang.link.emailSubject, 511 setup : function( data ) 512 { 513 if ( data.email ) 514 this.setValue( data.email.subject ); 515 }, 516 commit : function( data ) 517 { 518 if ( !data.email ) 519 data.email = {}; 520 521 data.email.subject = this.getValue(); 522 } 523 }, 524 { 525 type : 'textarea', 526 id : 'emailBody', 527 label : editor.lang.link.emailBody, 528 rows : 3, 529 'default' : '', 530 setup : function( data ) 531 { 532 if ( data.email ) 533 this.setValue( data.email.body ); 534 }, 535 commit : function( data ) 536 { 537 if ( !data.email ) 538 data.email = {}; 539 540 data.email.body = this.getValue(); 541 } 542 } 543 ], 544 setup : function( data ) 545 { 546 if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) 547 this.getElement().hide(); 548 } 549 } 550 ] 551 }, 552 { 553 id : 'target', 554 label : editor.lang.link.target, 555 title : editor.lang.link.target, 556 elements : 557 [ 558 { 559 type : 'hbox', 560 widths : [ '50%', '50%' ], 561 children : 562 [ 563 { 564 type : 'select', 565 id : 'linkTargetType', 566 label : editor.lang.link.target, 567 'default' : editor.config.link.defaultValues.target, 568 style : 'width : 100%;', 569 'items' : 570 [ 571 [ editor.lang.link.targetNotSet, 'notSet' ], 572 [ editor.lang.link.targetFrame, 'frame' ], 573 [ editor.lang.link.targetPopup, 'popup' ], 574 [ editor.lang.link.targetNew, '_blank' ], 575 [ editor.lang.link.targetTop, '_top' ], 576 [ editor.lang.link.targetSelf, '_self' ], 577 [ editor.lang.link.targetParent, '_parent' ] 578 ], 579 onChange : targetChanged, 580 setup : function( data ) 581 { 582 if ( data.target ) 583 this.setValue( data.target.type ); 584 }, 585 commit : function( data ) 586 { 587 if ( !data.target ) 588 data.target = {}; 589 590 data.target.type = this.getValue(); 591 } 592 }, 593 { 594 type : 'text', 595 id : 'linkTargetName', 596 label : editor.lang.link.targetFrameName, 597 'default' : editor.config.link.defaultValues.targetFrameName, 598 setup : function( data ) 599 { 600 if ( data.target ) 601 this.setValue( data.target.name ); 602 }, 603 commit : function( data ) 604 { 605 if ( !data.target ) 606 data.target = {}; 607 608 data.target.name = this.getValue(); 609 } 610 } 611 ] 612 }, 613 { 614 type : 'vbox', 615 width : 260, 616 align : 'center', 617 padding : 2, 618 id : 'popupFeatures', 619 children : 620 [ 621 { 622 type : 'html', 623 html : CKEDITOR.tools.htmlEncode( editor.lang.link.popupFeatures ) 624 }, 625 { 626 type : 'hbox', 627 children : 628 [ 629 { 630 type : 'checkbox', 631 id : 'resizable', 632 label : editor.lang.link.popupResizable, 633 setup : setupPopupParams, 634 commit : commitPopupParams 635 }, 636 { 637 type : 'checkbox', 638 id : 'status', 639 label : editor.lang.link.popupStatusBar, 640 setup : setupPopupParams, 641 commit : commitPopupParams 642 643 } 644 ] 645 }, 646 { 647 type : 'hbox', 648 children : 649 [ 650 { 651 type : 'checkbox', 652 id : 'location', 653 label : editor.lang.link.popupLocationBar, 654 setup : setupPopupParams, 655 commit : commitPopupParams 656 657 }, 658 { 659 type : 'checkbox', 660 id : 'toolbar', 661 label : editor.lang.link.popupToolbar, 662 setup : setupPopupParams, 663 commit : commitPopupParams 664 665 } 666 ] 667 }, 668 { 669 type : 'hbox', 670 children : 671 [ 672 { 673 type : 'checkbox', 674 id : 'menubar', 675 label : editor.lang.link.popupMenuBar, 676 setup : setupPopupParams, 677 commit : commitPopupParams 678 679 }, 680 { 681 type : 'checkbox', 682 id : 'fullscreen', 683 label : editor.lang.link.popupFullScreen, 684 setup : setupPopupParams, 685 commit : commitPopupParams 686 687 } 688 ] 689 }, 690 { 691 type : 'hbox', 692 children : 693 [ 694 { 695 type : 'checkbox', 696 id : 'scrollbars', 697 label : editor.lang.link.popupScrollBars, 698 setup : setupPopupParams, 699 commit : commitPopupParams 700 701 }, 702 { 703 type : 'checkbox', 704 id : 'dependent', 705 label : editor.lang.link.popupDependent, 706 setup : setupPopupParams, 707 commit : commitPopupParams 708 709 } 710 ] 711 }, 712 { 713 type : 'hbox', 714 children : 715 [ 716 { 717 type : 'text', 718 widths : [ '30%', '70%' ], 719 labelLayout : 'horizontal', 720 label : editor.lang.link.popupWidth, 721 id : 'width', 722 setup : setupPopupParams, 723 commit : commitPopupParams 724 725 }, 726 { 727 type : 'text', 728 labelLayout : 'horizontal', 729 widths : [ '55%', '45%' ], 730 label : editor.lang.link.popupLeft, 731 id : 'left', 732 setup : setupPopupParams, 733 commit : commitPopupParams 734 735 } 736 ] 737 }, 738 { 739 type : 'hbox', 740 children : 741 [ 742 { 743 type : 'text', 744 labelLayout : 'horizontal', 745 widths : [ '30%', '70%' ], 746 label : editor.lang.link.popupHeight, 747 id : 'height', 748 setup : setupPopupParams, 749 commit : commitPopupParams 750 751 }, 752 { 753 type : 'text', 754 labelLayout : 'horizontal', 755 label : editor.lang.link.popupTop, 756 widths : [ '55%', '45%' ], 757 id : 'top', 758 setup : setupPopupParams, 759 commit : commitPopupParams 760 761 } 762 ] 763 } 764 ] 765 } 766 ] 767 }, 768 { 769 id : 'upload', 770 label : editor.lang.link.upload, 771 title : editor.lang.link.upload, 772 elements : 773 [ 774 { 775 type : 'file', 776 id : 'upload', 777 label : editor.lang.common.upload, 778 action : editor.config.link.uploadAction, 779 size : 38 780 }, 781 { 782 type : 'fileButton', 783 id : 'uploadButton', 784 label : editor.lang.common.uploadSubmit, 785 'for' : [ 'upload', 'upload' ] 786 } 787 ] 788 }, 789 { 790 id : 'advanced', 791 label : editor.lang.link.advanced, 792 title : editor.lang.link.advanced, 793 elements : 794 [ 795 { 796 type : 'vbox', 797 padding : 1, 798 children : 799 [ 800 { 801 type : 'hbox', 802 widths : [ '45%', '35%', '20%' ], 803 children : 804 [ 805 { 806 type : 'text', 807 id : 'advId', 808 label : editor.lang.link.id, 809 setup : setupAdvParams, 810 commit : commitAdvParams 811 }, 812 { 813 type : 'select', 814 id : 'advLangDir', 815 label : editor.lang.link.langDir, 816 'default' : editor.config.link.defaultValues.langDir, 817 style : 'width: 100%;', 818 items : 819 [ 820 [ editor.lang.link.langDirNotSet, '' ], 821 [ editor.lang.link.langDirLTR, 'ltr' ], 822 [ editor.lang.link.langDirRTL, 'rtl' ] 823 ], 824 setup : setupAdvParams, 825 commit : commitAdvParams 826 }, 827 { 828 type : 'text', 829 id : 'advAccessKey', 830 label : editor.lang.link.acccessKey, 831 maxLength : 1, 832 setup : setupAdvParams, 833 commit : commitAdvParams 834 835 } 836 ] 837 }, 838 { 839 type : 'hbox', 840 widths : [ '45%', '35%', '20%' ], 841 children : 842 [ 843 { 844 type : 'text', 845 label : editor.lang.link.name, 846 id : 'advName', 847 setup : setupAdvParams, 848 commit : commitAdvParams 849 850 }, 851 { 852 type : 'text', 853 label : editor.lang.link.langCode, 854 id : 'advLangCode', 855 'default' : editor.config.link.defaultValues.langCode, 856 setup : setupAdvParams, 857 commit : commitAdvParams 858 859 }, 860 { 861 type : 'text', 862 label : editor.lang.link.tabIndex, 863 id : 'advTabIndex', 864 maxLength : 5, 865 setup : setupAdvParams, 866 commit : commitAdvParams 867 868 } 869 ] 870 } 871 ] 872 }, 873 { 874 type : 'vbox', 875 padding : 1, 876 children : 877 [ 878 { 879 type : 'hbox', 880 widths : [ '45%', '55%' ], 881 children : 882 [ 883 { 884 type : 'text', 885 label : editor.lang.link.advisoryTitle, 886 'default' : editor.config.link.defaultValues.title, 887 id : 'advTitle', 888 setup : setupAdvParams, 889 commit : commitAdvParams 890 891 }, 892 { 893 type : 'text', 894 label : editor.lang.link.advisoryContentType, 895 'default' : editor.config.link.defaultValues.type, 896 id : 'advContentType', 897 setup : setupAdvParams, 898 commit : commitAdvParams 899 900 } 901 ] 902 }, 903 { 904 type : 'hbox', 905 widths : [ '45%', '55%' ], 906 children : 907 [ 908 { 909 type : 'text', 910 label : editor.lang.link.cssClasses, 911 'default' : editor.config.link.defaultValues.classes, 912 id : 'advCSSClasses', 913 setup : setupAdvParams, 914 commit : commitAdvParams 915 916 }, 917 { 918 type : 'text', 919 label : editor.lang.link.charset, 920 'default' : editor.config.link.defaultValues.charset, 921 id : 'advCharset', 922 setup : setupAdvParams, 923 commit : commitAdvParams 924 925 } 926 ] 927 }, 928 { 929 type : 'hbox', 930 children : 931 [ 932 { 933 type : 'text', 934 label : editor.lang.link.styles, 935 'default' : editor.config.link.defaultValues.style, 936 id : 'advStyles', 937 setup : setupAdvParams, 938 commit : commitAdvParams 939 940 } 941 ] 942 } 943 ] 944 } 945 ] 946 } 947 ], 948 onShow : function() 949 { 950 this.fakeObj = false; 951 // IE BUG: Selection must be in the editor for getSelection() to work. 952 this.restoreSelection(); 953 var editor = this.getParentEditor(), 954 selection = editor.getSelection(), 955 ranges = selection.getRanges(), 956 element = null, 957 me = this; 958 959 // Fill in all the relevant fields if there's already one link selected. 960 if ( ranges.length == 1 ) 961 { 962 ranges[0].enlarge( CKEDITOR.ENLARGE_ELEMENT ); 963 964 var rangeRoot = ranges[0].getCommonAncestor( true ); 965 element = rangeRoot.getAscendant( 'a', true ); 966 if ( element && element.getAttribute( 'href' ) ) 967 { 968 selection.selectElement( element ); 969 this.saveSelection(); 970 } 971 else 972 { 973 element = rangeRoot.getAscendant( 'img', true ); 974 if ( element && element.getAttribute( '_cke_real_element_type' ) && element.getAttribute( '_cke_real_element_type' ) == 'anchor' ) 975 { 976 this.fakeObj = element; 977 element = editor.restoreRealElement( this.fakeObj ); 978 selection.selectElement( this.fakeObj ); 979 this.saveSelection(); 980 } 981 } 982 } 983 984 this.setupContent( parseLink.apply( this, [ editor, element ] ) ); 985 986 // Push the current values into the dialog default value stack. 987 this.pushDefault(); 988 }, 989 onOk : function() 990 { 991 var attributes = { href : 'javascript:void(0)/*' + CKEDITOR.tools.getNextNumber() + '*/' }, 992 removeAttributes = [], 993 data = { href : attributes.href }, 994 me = this, editor = this.getParentEditor(); 995 996 this.commitContent( data ); 997 998 // Compose the URL. 999 switch ( data.type || 'url' ) 1000 { 1001 case 'url': 1002 var protocol = ( data.url && data.url.protocol ) || 'http://', 1003 url = ( data.url && data.url.url ) || ''; 1004 attributes._cke_saved_href = protocol + url; 1005 break; 1006 case 'anchor': 1007 var name = ( data.anchor && data.anchor.name ), 1008 id = ( data.anchor && data.anchor.id ); 1009 attributes._cke_saved_href = '#' + ( name || id || '' ); 1010 break; 1011 case 'email': 1012 var address = ( data.email && data.email.address ), 1013 subject = ( data.email && encodeURIComponent( data.email.subject || '' ) ), 1014 body = ( data.email && encodeURIComponent( data.email.body || '' ) ), 1015 linkList = [ 'mailto:', address ]; 1016 if ( subject || body ) 1017 { 1018 var argList = []; 1019 linkList.push( '?' ); 1020 subject && argList.push( 'subject=' + subject ); 1021 body && argList.push( 'body=' + body ); 1022 linkList.push( argList.join( '&' ) ); 1023 } 1024 attributes._cke_saved_href = linkList.join( '' ); 1025 break; 1026 default: 1027 } 1028 1029 // Popups and target. 1030 if ( data.target ) 1031 { 1032 if ( data.target.type == 'popup' ) 1033 { 1034 var onclickList = [ 'window.open(this.href, \'', 1035 data.target.name || '', '\', \'' ], 1036 featureList = [ 'resizable', 'status', 'location', 'toolbar', 'menubar', 'fullscreen', 1037 'scrollbars', 'dependent' ], 1038 featureLength = featureList.length, 1039 addFeature = function( featureName ) 1040 { 1041 if ( data.target[ featureName ] ) 1042 featureList.push( featureName + '=' + data.target[ featureName ] ); 1043 }; 1044 1045 for ( var i = 0 ; i < featureLength ; i++ ) 1046 featureList[i] = featureList[i] + ( data.target[ featureList[i] ] ? '=yes' : '=no' ) ; 1047 addFeature( 'width' ); 1048 addFeature( 'left' ); 1049 addFeature( 'height' ); 1050 addFeature( 'top' ); 1051 1052 onclickList.push( featureList.join( ',' ), '\'); return false;' ); 1053 attributes._cke_saved_onclick = onclickList.join( '' ); 1054 } 1055 else 1056 { 1057 if ( data.target.type != 'notSet' && data.target.name ) 1058 attributes.target = data.target.name; 1059 removeAttributes.push( '_cke_saved_onclick', 'onclick' ); 1060 } 1061 } 1062 1063 // Advanced attributes. 1064 if ( data.adv ) 1065 { 1066 var advAttr = function( inputName, attrName ) 1067 { 1068 var value = data.adv[ inputName ]; 1069 if ( value ) 1070 attributes[attrName] = value; 1071 else 1072 removeAttributes.push( attrName ); 1073 }; 1074 1075 if ( this._.selectedElement ) 1076 advAttr( 'advId', 'id' ); 1077 advAttr( 'advLangDir', 'dir' ); 1078 advAttr( 'advAccessKey', 'accessKey' ); 1079 advAttr( 'advName', 'name' ); 1080 advAttr( 'advLangCode', 'lang' ); 1081 advAttr( 'advTabIndex', 'tabindex' ); 1082 advAttr( 'advTitle', 'title' ); 1083 advAttr( 'advContentType', 'type' ); 1084 advAttr( 'advCSSClasses', 'class' ); 1085 advAttr( 'advCharset', 'charset' ); 1086 advAttr( 'advStyles', 'style' ); 1087 } 1088 1089 if ( !this._.selectedElement ) 1090 { 1091 // IE BUG: Selection must be in the editor for getSelection() to work. 1092 this.restoreSelection(); 1093 this.clearSavedSelection(); 1094 1095 // Create element if current selection is collapsed. 1096 var selection = editor.getSelection(), 1097 ranges = selection.getRanges(); 1098 if ( ranges.length == 1 && ranges[0].collapsed ) 1099 { 1100 var text = new CKEDITOR.dom.text( attributes._cke_saved_href, editor.document ); 1101 ranges[0].insertNode( text ); 1102 ranges[0].selectNodeContents( text ); 1103 selection.selectRanges( ranges ); 1104 } 1105 1106 // Apply style. 1107 var style = new CKEDITOR.style( { element : 'a', attributes : attributes } ); 1108 style.type = CKEDITOR.STYLE_INLINE; // need to override... dunno why. 1109 style.apply( editor.document ); 1110 1111 // Id. Apply only to the first link. 1112 if ( data.adv && data.adv.advId != '' ) 1113 { 1114 var links = this.getParentEditor().document.$.getElementsByTagName( 'a' ); 1115 for ( var i = 0 ; i < links.length ; i++ ) 1116 { 1117 if ( links[i].href == attributes.href ) 1118 { 1119 links[i].id = data.adv.advId; 1120 break; 1121 } 1122 } 1123 } 1124 } 1125 else 1126 { 1127 // We're only editing an existing link, so just overwrite the attributes. 1128 var element = this._.selectedElement; 1129 1130 // IE BUG: Setting the name attribute to an existing link doesn't work. 1131 // Must re-create the link from weired syntax to workaround. 1132 if ( CKEDITOR.env.ie && attributes.name != element.getAttribute( 'name' ) ) 1133 { 1134 var newElement = new CKEDITOR.dom.element( '<a name="' + CKEDITOR.tools.htmlEncode( attributes.name ) + '">', 1135 editor.document ); 1136 1137 this.restoreSelection(); 1138 var selection = editor.getSelection(); 1139 1140 element.moveChildren( newElement ); 1141 element.copyAttributes( newElement, { name : 1 } ); 1142 newElement.replace( element ); 1143 element = newElement; 1144 1145 this.clearSavedSelection(); 1146 selection.selectElement( element ); 1147 } 1148 1149 element.setAttributes( attributes ); 1150 element.removeAttributes( removeAttributes ); 1151 1152 // Make the element display as an anchor if a name has been set. 1153 if ( element.getAttribute( 'name' ) ) 1154 element.addClass( 'cke_anchor' ); 1155 else 1156 element.removeClass( 'cke_anchor' ); 1157 1158 if ( this.fakeObj ) 1159 editor.createFakeElement( element, 'cke_anchor', 'anchor' ).replace( this.fakeObj ); 1160 1161 delete this._.selectedElement; 1162 } 1163 }, 1164 onLoad : function() 1165 { 1166 if ( editor.config.link.uploadTab == false ) 1167 this.hidePage( 'upload' ); //Hide Upload tab. 1168 1169 if ( editor.config.link.showAdvancedTab == false ) 1170 this.hidePage( 'advanced' ); //Hide Advanded tab. 1171 1172 if ( editor.config.link.browseServer == false ) 1173 this.getContentElement( 'info', 'browse' ).getElement().hide(); 1174 1175 if ( editor.config.link.showTargetTab == false ) 1176 this.hidePage( 'target' ); //Hide Target tab. 1177 1178 }, 1179 onHide : function() 1180 { 1181 // Pop the default values from default value set that are pushed in onShow(). 1182 this.popDefault(); 1183 } 1184 }; 1185 } ); -
_source/plugins/link/plugin.js
Property changes on: _source\plugins\link\dialogs\link.js ___________________________________________________________________ Name: svn:executable + * Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: _source\plugins\link\images\anchor.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: _source\plugins\link\images\anchor.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 CKEDITOR.plugins.add( 'link', 7 { 8 init : function( editor, pluginPath ) 9 { 10 // Add the link and unlink buttons. 11 editor.addCommand( 'link', new CKEDITOR.dialogCommand( 'link' ) ); 12 editor.addCommand( 'anchor', new CKEDITOR.dialogCommand( 'anchor' ) ); 13 editor.addCommand( 'unlink', new CKEDITOR.unlinkCommand() ); 14 editor.ui.addButton( 'Link', 15 { 16 label : editor.lang.link.toolbar, 17 command : 'link' 18 } ); 19 editor.ui.addButton( 'Unlink', 20 { 21 label : editor.lang.unlink, 22 command : 'unlink' 23 } ); 24 editor.ui.addButton( 'Anchor', 25 { 26 label : editor.lang.anchor.toolbar, 27 command : 'anchor' 28 } ); 29 CKEDITOR.dialog.add( 'link', this.path + 'dialogs/link.js' ); 30 CKEDITOR.dialog.add( 'anchor', this.path + 'dialogs/anchor.js' ); 31 32 // Add the CSS styles for anchor placeholders. 33 editor.addCss( 34 'img.cke_anchor' + 35 '{' + 36 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' + 37 'background-position: center center;' + 38 'background-repeat: no-repeat;' + 39 'border: 1px solid #a9a9a9;' + 40 'width: 18px;' + 41 'height: 18px;' + 42 '}\n' + 43 'a.cke_anchor' + 44 '{' + 45 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ');' + 46 'background-position: 0 center;' + 47 'background-repeat: no-repeat;' + 48 'border: 1px solid #a9a9a9;' + 49 'padding-left: 18px;' + 50 '}' 51 ); 52 53 // Register selection change handler for the unlink button. 54 editor.on( 'selectionChange', function( evt ) 55 { 56 /* 57 * Despite our initial hope, document.queryCommandEnabled() does not work 58 * for this in Firefox. So we must detect the state by element paths. 59 */ 60 var command = editor.getCommand( 'unlink' ), 61 element = evt.data.path.lastElement.getAscendant( 'a', true ); 62 if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) ) 63 command.state = CKEDITOR.TRISTATE_OFF; 64 else 65 command.state = CKEDITOR.TRISTATE_DISABLED; 66 command.fire( 'state' ); 67 } ); 68 69 // Register a contentDom handler for displaying placeholders after mode change. 70 editor.on( 'contentDom', function() 71 { 72 var rawAnchors = editor.document.$.anchors; 73 for ( var i = rawAnchors.length - 1, anchor ; i >= 0 ; i-- ) 74 { 75 anchor = new CKEDITOR.dom.element( rawAnchors[ i ] ); 76 77 // IE BUG: When an <a> tag doesn't have href, IE would return empty string 78 // instead of null on getAttribute. 79 if ( !anchor.getAttribute( 'href' ) ) 80 editor.createFakeElement( anchor, 'cke_anchor', 'anchor' ).replace( anchor ); 81 else 82 anchor.addClass( 'cke_anchor' ); 83 } 84 } ); 85 }, 86 87 requires : [ 'fakeobjects' ] 88 } ); 89 90 CKEDITOR.unlinkCommand = function(){}; 91 CKEDITOR.unlinkCommand.prototype = 92 { 93 /** @ignore */ 94 exec : function( editor ) 95 { 96 /* 97 * execCommand( 'unlink', ... ) in Firefox leaves behind <span> tags at where 98 * the <a> was, so again we have to remove the link ourselves. (See #430) 99 * 100 * TODO: Use the style system when it's complete. Let's use execCommand() 101 * as a stopgap solution for now. 102 */ 103 var selection = editor.getSelection(), 104 bookmarks = selection.createBookmarks(), 105 ranges = selection.getRanges(), 106 rangeRoot, 107 element; 108 109 for ( var i = 0 ; i < ranges.length ; i++ ) 110 { 111 rangeRoot = ranges[i].getCommonAncestor( true ); 112 element = rangeRoot.getAscendant( 'a', true ); 113 if ( !element ) 114 continue; 115 ranges[i].selectNodeContents( element ); 116 } 117 118 selection.selectRanges( ranges ); 119 editor.document.$.execCommand( 'unlink', false, null ); 120 selection.selectBookmarks( bookmarks ); 121 } 122 }; 123 124 CKEDITOR.config.link = 125 { 126 uploadTab : true, 127 browseServer : true, 128 uploadAction : 'nowhere.php', 129 showAdvancedTab : true, 130 showTargetTab : true, 131 defaultValues : 132 { 133 /** 134 * Startup values 135 * @type Text 136 * @default '' 137 */ 138 linkType : 'url', 139 protocol : 'http://', 140 target : 'notSet', 141 targetFrameName : '', 142 title : '', 143 type : '', 144 classes : '', 145 langDir : '', 146 langCode : '', 147 charset : '', 148 style : '' 149 } 150 }; -
_source/plugins/pagebreak/plugin.js
Property changes on: _source\plugins\link\plugin.js ___________________________________________________________________ Name: svn:executable + *
49 49 div = divs.getItem( i ); 50 50 if ( div.getStyle( 'page-break-after' ) == 'always' && !/[^\s\u00A0]/.test( div.getText() ) ) 51 51 { 52 editor.createFakeElement( div, 'cke_pagebreak' ).replace( div );52 editor.createFakeElement( div, 'cke_pagebreak', 'div' ).replace( div ); 53 53 } 54 54 } 55 55 }); … … 65 65 var breakObject = CKEDITOR.dom.element.createFromHtml( '<div style="page-break-after: always;"><span style="display: none;"> </span></div>' ); 66 66 67 67 // Creates the fake image used for this element. 68 breakObject = editor.createFakeElement( breakObject, 'cke_pagebreak' );68 breakObject = editor.createFakeElement( breakObject, 'cke_pagebreak', 'div' ); 69 69 70 70 var ranges = editor.getSelection().getRanges(); 71 71 -
_source/plugins/toolbar/plugin.js
211 211 'Bold', 'Italic', 'Underline', 'Strike', '-', 212 212 'Subscript', 'Superscript', '-', 213 213 'SelectAll', 'RemoveFormat', '-', 214 ' Smiley', 'HorizontalRule', 'SpecialChar', 'PageBreak'214 'Link', 'Unlink', 'Anchor', 'Smiley', 'HorizontalRule', 'SpecialChar', 'PageBreak' 215 215 ] 216 216 ];