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( 'removeformat',
|
---|
7 | {
|
---|
8 | requires : [ 'selection' ],
|
---|
9 |
|
---|
10 | init : function( editor )
|
---|
11 | {
|
---|
12 | editor.addCommand( 'removeFormat', CKEDITOR.plugins.removeformat.commands.removeformat );
|
---|
13 | editor.ui.addButton( 'RemoveFormat',
|
---|
14 | {
|
---|
15 | label : editor.lang.removeFormat,
|
---|
16 | command : 'removeFormat'
|
---|
17 | });
|
---|
18 | }
|
---|
19 | });
|
---|
20 |
|
---|
21 | CKEDITOR.plugins.removeformat =
|
---|
22 | {
|
---|
23 | commands :
|
---|
24 | {
|
---|
25 | removeformat :
|
---|
26 | {
|
---|
27 | exec : function( editor )
|
---|
28 | {
|
---|
29 | var tagsRegex = editor._.removeFormatRegex ||
|
---|
30 | ( editor._.removeFormatRegex = new RegExp( '^(?:' + editor.config.removeFormatTags.replace( /,/g,'|' ) + ')$', 'i' ) );
|
---|
31 |
|
---|
32 | var removeAttributes = editor._.removeAttributes ||
|
---|
33 | ( editor._.removeAttributes = editor.config.removeFormatAttributes.split( ',' ) );
|
---|
34 |
|
---|
35 | var ranges = editor.getSelection().getRanges();
|
---|
36 |
|
---|
37 | for ( var i = 0, range ; range = ranges[ i ] ; i++ )
|
---|
38 | {
|
---|
39 | if ( range.collapsed )
|
---|
40 | continue;
|
---|
41 |
|
---|
42 | range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
|
---|
43 |
|
---|
44 | // Bookmark the range so we can re-select it after processing.
|
---|
45 | var bookmark = range.createBookmark();
|
---|
46 |
|
---|
47 | // The style will be applied within the bookmark boundaries.
|
---|
48 | var startNode = bookmark.startNode;
|
---|
49 | var endNode = bookmark.endNode;
|
---|
50 |
|
---|
51 | // We need to check the selection boundaries (bookmark spans) to break
|
---|
52 | // the code in a way that we can properly remove partially selected nodes.
|
---|
53 | // For example, removing a <b> style from
|
---|
54 | // <b>This is [some text</b> to show <b>the] problem</b>
|
---|
55 | // ... where [ and ] represent the selection, must result:
|
---|
56 | // <b>This is </b>[some text to show the]<b> problem</b>
|
---|
57 | // The strategy is simple, we just break the partial nodes before the
|
---|
58 | // removal logic, having something that could be represented this way:
|
---|
59 | // <b>This is </b>[<b>some text</b> to show <b>the</b>]<b> problem</b>
|
---|
60 |
|
---|
61 | var breakParent = function( node )
|
---|
62 | {
|
---|
63 | // Let's start checking the start boundary.
|
---|
64 | var path = new CKEDITOR.dom.elementPath( node );
|
---|
65 | var pathElements = path.elements;
|
---|
66 |
|
---|
67 | for ( var i = 1, pathElement ; pathElement = pathElements[ i ] ; i++ )
|
---|
68 | {
|
---|
69 | if ( pathElement.equals( path.block ) || pathElement.equals( path.blockLimit ) )
|
---|
70 | break;
|
---|
71 |
|
---|
72 | // If this element can be removed (even partially).
|
---|
73 | if ( tagsRegex.test( pathElement.getName() ) )
|
---|
74 | node.breakParent( pathElement );
|
---|
75 | }
|
---|
76 | };
|
---|
77 |
|
---|
78 | breakParent( startNode );
|
---|
79 | breakParent( endNode );
|
---|
80 |
|
---|
81 | // Navigate through all nodes between the bookmarks.
|
---|
82 | var currentNode = startNode.getNextSourceNode( true, CKEDITOR.NODE_ELEMENT );
|
---|
83 |
|
---|
84 | while ( currentNode )
|
---|
85 | {
|
---|
86 | // If we have reached the end of the selection, stop looping.
|
---|
87 | if ( currentNode.equals( endNode ) )
|
---|
88 | break;
|
---|
89 |
|
---|
90 | // Cache the next node to be processed. Do it now, because
|
---|
91 | // currentNode may be removed.
|
---|
92 | var nextNode = currentNode.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT );
|
---|
93 |
|
---|
94 | // This node must not be a fake element.
|
---|
95 | if ( currentNode.getName() != 'img' || !currentNode.getAttribute( '_cke_protected_html' ) )
|
---|
96 | {
|
---|
97 | // Remove elements nodes that match with this style rules.
|
---|
98 | if ( tagsRegex.test( currentNode.getName() ) )
|
---|
99 | currentNode.remove( true );
|
---|
100 | else
|
---|
101 | currentNode.removeAttributes( removeAttributes );
|
---|
102 | }
|
---|
103 |
|
---|
104 | currentNode = nextNode;
|
---|
105 | }
|
---|
106 |
|
---|
107 | range.moveToBookmark( bookmark );
|
---|
108 | }
|
---|
109 |
|
---|
110 | editor.getSelection().selectRanges( ranges );
|
---|
111 | }
|
---|
112 | }
|
---|
113 | }
|
---|
114 | };
|
---|
115 |
|
---|
116 | /**
|
---|
117 | * A comma separated list of elements to be removed when executing the "remove
|
---|
118 | " format" command. Note that only inline elements are allowed.
|
---|
119 | * @type String
|
---|
120 | * @default 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var'
|
---|
121 | * @example
|
---|
122 | */
|
---|
123 | CKEDITOR.config.removeFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var';
|
---|
124 |
|
---|
125 | /**
|
---|
126 | * A comma separated list of elements attributes to be removed when executing
|
---|
127 | * the "remove format" command.
|
---|
128 | * @type String
|
---|
129 | * @default 'class,style,lang,width,height,align,hspace,valign'
|
---|
130 | * @example
|
---|
131 | */
|
---|
132 | CKEDITOR.config.removeFormatAttributes = 'class,style,lang,width,height,align,hspace,valign';
|
---|