root / drupal7 / sites / all / modules / ckeditor / plugins / drupalbreaks / plugin.js @ fc2c1c7a
1 |
/*
|
---|---|
2 |
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
|
3 |
For licensing, see LICENSE.html or http://ckeditor.com/license
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
* @file Plugin for inserting Drupal teaser and page breaks.
|
8 |
*/
|
9 |
( function() {
|
10 |
var pluginRequires = [ 'fakeobjects' ]; |
11 |
if (Drupal.ckeditor_ver == 3) { |
12 |
pluginRequires = [ 'fakeobjects', 'htmldataprocessor' ]; |
13 |
} |
14 |
|
15 |
CKEDITOR.plugins.add( 'drupalbreaks',
|
16 |
{ |
17 |
requires : pluginRequires,
|
18 |
|
19 |
init : function( editor ) |
20 |
{ |
21 |
var addCssObj = CKEDITOR;
|
22 |
|
23 |
if (Drupal.ckeditor_ver == 3) { |
24 |
addCssObj = editor; |
25 |
} |
26 |
// Add the styles that renders our fake objects.
|
27 |
addCssObj.addCss( |
28 |
'img.cke_drupal_pagebreak,img.cke_drupal_break' +
|
29 |
'{' +
|
30 |
'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/pagebreak.gif' ) + ');' + |
31 |
'background-position: center center;' +
|
32 |
'background-repeat: no-repeat;' +
|
33 |
'clear: both;' +
|
34 |
'display: block;' +
|
35 |
'float: none;' +
|
36 |
'width: 100%;' +
|
37 |
'border-top: #999999 1px dotted;' +
|
38 |
'border-bottom: #999999 1px dotted;' +
|
39 |
'height: 5px;' +
|
40 |
'}' +
|
41 |
'img.cke_drupal_break' +
|
42 |
'{' +
|
43 |
'border-top: #FF0000 1px dotted;' +
|
44 |
'border-bottom: #FF0000 1px dotted;' +
|
45 |
'}'
|
46 |
); |
47 |
|
48 |
// Register the toolbar buttons.
|
49 |
editor.ui.addButton( 'DrupalBreak',
|
50 |
{ |
51 |
label : Drupal.t('Insert Teaser Break'), |
52 |
icon : this.path + 'images/drupalbreak.png', |
53 |
command : 'drupalbreak' |
54 |
}); |
55 |
|
56 |
editor.addCommand( 'drupalbreak',
|
57 |
{ |
58 |
exec : function() |
59 |
{ |
60 |
// There should be only one <!--break--> in document. So, look
|
61 |
// for an image with class "cke_drupal_break" (the fake element).
|
62 |
var images = editor.document.getElementsByTag( 'img' ); |
63 |
for ( var i = 0, len = images.count() ; i < len ; i++ ) |
64 |
{ |
65 |
var img = images.getItem( i );
|
66 |
if ( img.hasClass( 'cke_drupal_break' ) ) |
67 |
{ |
68 |
if ( confirm( Drupal.t( 'The document already contains a teaser break. Do you want to proceed by removing it first?' ) ) ) |
69 |
{ |
70 |
img.remove(); |
71 |
break;
|
72 |
} |
73 |
else
|
74 |
return;
|
75 |
} |
76 |
} |
77 |
|
78 |
insertComment( 'break' );
|
79 |
} |
80 |
} ); |
81 |
|
82 |
editor.ui.addButton( 'DrupalPageBreak',
|
83 |
{ |
84 |
label : Drupal.t( 'Insert Page Break' ), |
85 |
icon : this.path + 'images/drupalpagebreak.png', |
86 |
command : 'drupalpagebreak' |
87 |
}); |
88 |
|
89 |
editor.addCommand( 'drupalpagebreak',
|
90 |
{ |
91 |
exec : function() |
92 |
{ |
93 |
insertComment( 'pagebreak' );
|
94 |
} |
95 |
} ); |
96 |
|
97 |
// This function effectively inserts the comment into the editor.
|
98 |
function insertComment( text ) |
99 |
{ |
100 |
// Create the fake element that will be inserted into the document.
|
101 |
// The trick is declaring it as an <hr>, so it will behave like a
|
102 |
// block element (and in effect it behaves much like an <hr>).
|
103 |
if ( !CKEDITOR.dom.comment.prototype.getAttribute ) {
|
104 |
CKEDITOR.dom.comment.prototype.getAttribute = function() { |
105 |
return ''; |
106 |
}; |
107 |
CKEDITOR.dom.comment.prototype.attributes = { |
108 |
align : '' |
109 |
}; |
110 |
} |
111 |
var fakeElement = editor.createFakeElement( new CKEDITOR.dom.comment( text ), 'cke_drupal_' + text, 'hr' ); |
112 |
|
113 |
// This is the trick part. We can't use editor.insertElement()
|
114 |
// because we need to put the comment directly at <body> level.
|
115 |
// We need to do range manipulation for that.
|
116 |
|
117 |
// Get a DOM range from the current selection.
|
118 |
var range = editor.getSelection().getRanges()[0], |
119 |
elementsPath = new CKEDITOR.dom.elementPath( range.getCommonAncestor( true ) ), |
120 |
element = ( elementsPath.block && elementsPath.block.getParent() ) || elementsPath.blockLimit, |
121 |
hasMoved; |
122 |
|
123 |
// If we're not in <body> go moving the position to after the
|
124 |
// elements until reaching it. This may happen when inside tables,
|
125 |
// lists, blockquotes, etc.
|
126 |
while ( element && element.getName() != 'body' ) |
127 |
{ |
128 |
range.moveToPosition( element, CKEDITOR.POSITION_AFTER_END ); |
129 |
hasMoved = 1;
|
130 |
element = element.getParent(); |
131 |
} |
132 |
|
133 |
// Split the current block.
|
134 |
if ( !hasMoved )
|
135 |
range.splitBlock( 'p' );
|
136 |
|
137 |
// Insert the fake element into the document.
|
138 |
range.insertNode( fakeElement ); |
139 |
|
140 |
// Now, we move the selection to the best possible place following
|
141 |
// our fake element.
|
142 |
var next = fakeElement;
|
143 |
while ( ( next = next.getNext() ) && !range.moveToElementEditStart( next ) )
|
144 |
{} |
145 |
|
146 |
range.select(); |
147 |
} |
148 |
}, |
149 |
|
150 |
afterInit : function( editor ) |
151 |
{ |
152 |
// Adds the comment processing rules to the data filter, so comments
|
153 |
// are replaced by fake elements.
|
154 |
editor.dataProcessor.dataFilter.addRules( |
155 |
{ |
156 |
comment : function( value ) |
157 |
{ |
158 |
if ( !CKEDITOR.htmlParser.comment.prototype.getAttribute ) {
|
159 |
CKEDITOR.htmlParser.comment.prototype.getAttribute = function() { |
160 |
return ''; |
161 |
}; |
162 |
CKEDITOR.htmlParser.comment.prototype.attributes = { |
163 |
align : '' |
164 |
}; |
165 |
} |
166 |
|
167 |
if ( value == 'break' || value == 'pagebreak' ) |
168 |
return editor.createFakeParserElement( new CKEDITOR.htmlParser.comment( value ), 'cke_drupal_' + value, 'hr' ); |
169 |
|
170 |
return value;
|
171 |
} |
172 |
}); |
173 |
} |
174 |
}); |
175 |
} )(); |