JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.6.1
[ckeditor.git] / _source / plugins / pagebreak / plugin.js
1 /*\r
2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.\r
3 For licensing, see LICENSE.html or http://ckeditor.com/license\r
4 */\r
5 \r
6 /**\r
7  * @file Horizontal Page Break\r
8  */\r
9 \r
10 // Register a plugin named "pagebreak".\r
11 CKEDITOR.plugins.add( 'pagebreak',\r
12 {\r
13         init : function( editor )\r
14         {\r
15                 // Register the command.\r
16                 editor.addCommand( 'pagebreak', CKEDITOR.plugins.pagebreakCmd );\r
17 \r
18                 // Register the toolbar button.\r
19                 editor.ui.addButton( 'PageBreak',\r
20                         {\r
21                                 label : editor.lang.pagebreak,\r
22                                 command : 'pagebreak'\r
23                         });\r
24 \r
25                 var cssStyles = [\r
26                         '{' ,\r
27                                 'background: url(' + CKEDITOR.getUrl( this.path + 'images/pagebreak.gif' ) + ') no-repeat center center;' ,\r
28                                 'clear: both;' ,\r
29                                 'width:100%; _width:99.9%;' ,\r
30                                 'border-top: #999999 1px dotted;' ,\r
31                                 'border-bottom: #999999 1px dotted;' ,\r
32                                 'padding:0;' ,\r
33                                 'height: 5px;' ,\r
34                                 'cursor: default;' ,\r
35                         '}'\r
36                         ].join( '' ).replace(/;/g, ' !important;' );    // Increase specificity to override other styles, e.g. block outline.\r
37 \r
38                 // Add the style that renders our placeholder.\r
39                 editor.addCss( 'div.cke_pagebreak' + cssStyles );\r
40 \r
41                 // Opera needs help to select the page-break.\r
42                 CKEDITOR.env.opera && editor.on( 'contentDom', function()\r
43                 {\r
44                         editor.document.on( 'click', function( evt )\r
45                         {\r
46                                 var target = evt.data.getTarget();\r
47                                 if ( target.is( 'div' ) && target.hasClass( 'cke_pagebreak')  )\r
48                                         editor.getSelection().selectElement( target );\r
49                         });\r
50                 });\r
51         },\r
52 \r
53         afterInit : function( editor )\r
54         {\r
55                 var label = editor.lang.pagebreakAlt;\r
56 \r
57                 // Register a filter to displaying placeholders after mode change.\r
58                 var dataProcessor = editor.dataProcessor,\r
59                         dataFilter = dataProcessor && dataProcessor.dataFilter,\r
60                         htmlFilter = dataProcessor && dataProcessor.htmlFilter;\r
61 \r
62                 if ( htmlFilter )\r
63                 {\r
64                         htmlFilter.addRules(\r
65                         {\r
66                                 attributes : {\r
67                                         'class' : function( value, element )\r
68                                         {\r
69                                                 var className =  value.replace( 'cke_pagebreak', '' );\r
70                                                 if ( className != value )\r
71                                                 {\r
72                                                         var span = CKEDITOR.htmlParser.fragment.fromHtml( '<span style="display: none;">&nbsp;</span>' );\r
73                                                         element.children.length = 0;\r
74                                                         element.add( span );\r
75                                                         var attrs = element.attributes;\r
76                                                         delete attrs[ 'aria-label' ];\r
77                                                         delete attrs.contenteditable;\r
78                                                         delete attrs.title;\r
79                                                 }\r
80                                                 return className;\r
81                                         }\r
82                                 }\r
83                         }, 5 );\r
84                 }\r
85 \r
86                 if ( dataFilter )\r
87                 {\r
88                         dataFilter.addRules(\r
89                                 {\r
90                                         elements :\r
91                                         {\r
92                                                 div : function( element )\r
93                                                 {\r
94                                                         var attributes = element.attributes,\r
95                                                                 style = attributes && attributes.style,\r
96                                                                 child = style && element.children.length == 1 && element.children[ 0 ],\r
97                                                                 childStyle = child && ( child.name == 'span' ) && child.attributes.style;\r
98 \r
99                                                         if ( childStyle && ( /page-break-after\s*:\s*always/i ).test( style ) && ( /display\s*:\s*none/i ).test( childStyle ) )\r
100                                                         {\r
101                                                                 attributes.contenteditable = "false";\r
102                                                                 attributes[ 'class' ] = "cke_pagebreak";\r
103                                                                 attributes[ 'data-cke-display-name' ] = "pagebreak";\r
104                                                                 attributes[ 'aria-label' ] = label;\r
105                                                                 attributes[ 'title' ] = label;\r
106 \r
107                                                                 element.children.length = 0;\r
108                                                         }\r
109                                                 }\r
110                                         }\r
111                                 });\r
112                 }\r
113         },\r
114 \r
115         requires : [ 'fakeobjects' ]\r
116 });\r
117 \r
118 CKEDITOR.plugins.pagebreakCmd =\r
119 {\r
120         exec : function( editor )\r
121         {\r
122                 var label = editor.lang.pagebreakAlt;\r
123 \r
124                 // Create read-only element that represents a print break.\r
125                 var pagebreak = CKEDITOR.dom.element.createFromHtml(\r
126                         '<div style="' +\r
127                         'page-break-after: always;"' +\r
128                         'contenteditable="false" ' +\r
129                         'title="'+ label + '" ' +\r
130                         'aria-label="'+ label + '" ' +\r
131                         'data-cke-display-name="pagebreak" ' +\r
132                         'class="cke_pagebreak">' +\r
133                         '</div>', editor.document );\r
134 \r
135                 var ranges = editor.getSelection().getRanges( true );\r
136 \r
137                 editor.fire( 'saveSnapshot' );\r
138 \r
139                 for ( var range, i = ranges.length - 1 ; i >= 0; i-- )\r
140                 {\r
141                         range = ranges[ i ];\r
142 \r
143                         if ( i < ranges.length -1 )\r
144                                 pagebreak = pagebreak.clone( true );\r
145 \r
146                         range.splitBlock( 'p' );\r
147                         range.insertNode( pagebreak );\r
148                         if ( i == ranges.length - 1 )\r
149                         {\r
150                                 var next = pagebreak.getNext();\r
151                                 range.moveToPosition( pagebreak, CKEDITOR.POSITION_AFTER_END );\r
152 \r
153                                 // If there's nothing or a non-editable block followed by, establish a new paragraph\r
154                                 // to make sure cursor is not trapped.\r
155                                 if ( !next || next.type == CKEDITOR.NODE_ELEMENT && !next.isEditable() )\r
156                                         range.fixBlock( true, editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p'  );\r
157 \r
158                                 range.select();\r
159                         }\r
160                 }\r
161 \r
162                 editor.fire( 'saveSnapshot' );\r
163         }\r
164 };\r