fb5941dffe89ededc684e95041997bff36017355
1 /***************************************************************
4 * (c) 2005, 2006 Stanislas Rolland <stanislas.rolland(arobas)fructifor.ca>
7 * This script is part of the TYPO3 project. The TYPO3 project is
8 * free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * The GNU General Public License can be found at
14 * http://www.gnu.org/copyleft/gpl.html.
15 * A copy is found in the textfile GPL.txt and important notices to the license
16 * from the author is found in LICENSE.txt distributed with these scripts.
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
27 * TYPO3 Image & Link Browsers Plugin for TYPO3 htmlArea RTE
32 TYPO3Browsers = function(editor
,args
) {
34 var cfg
= this.editor
.config
;
35 cfg
.btnList
.CreateLink
[1] = this.editor
.imgURL("ed_link.gif", "TYPO3Browsers");
38 TYPO3Browsers
.I18N
= TYPO3Browsers_langArray
;
40 TYPO3Browsers
._pluginInfo
= {
41 name
: "TYPO3Browsers",
43 developer
: "Stanislas Rolland",
44 developer_url
: "http://www.fructifor.ca/",
45 c_owner
: "Stanislas Rolland",
46 sponsor
: "Fructifor Inc.",
47 sponsor_url
: "http://www.fructifor.ca/",
52 * CreateLink: Typo3-RTE function, use this instead of the original.
54 HTMLArea
.prototype.renderPopup_link = function() {
55 var editorNumber
= this._editorNumber
,
56 addUrlParams
= "?" + RTEarea
[editorNumber
]["RTEtsConfigParams"],
58 sel
= this.getParentElement();
60 // Download the definition of special anchor classes if not yet done
61 if(RTEarea
[editorNumber
]["classesAnchorUrl"] && !this.classesAnchorSetup
) {
62 var classesAnchorData
= HTMLArea
._getScript(0, false, RTEarea
[editorNumber
]["classesAnchorUrl"]);
64 if(classesAnchorData
) eval(classesAnchorData
);
68 var el
= HTMLArea
.getElementObject(sel
,"a");
69 if (el
!= null && el
.tagName
&& el
.tagName
.toLowerCase() == "a") sel
= el
;
70 if (sel
!= null && sel
.tagName
&& sel
.tagName
.toLowerCase() == "a") {
71 addUrlParams
= "?curUrl[href]=" + encodeURIComponent(sel
.getAttribute("href"));
72 addUrlParams
+= "&curUrl[typo3ContentLanguage]=" + RTEarea
[editorNumber
]["typo3ContentLanguage"];
73 addUrlParams
+= "&curUrl[typo3ContentCharset]=" + RTEarea
[editorNumber
]["typo3ContentCharset"];
74 if (sel
.target
) addUrlParams
+= "&curUrl[target]=" + encodeURIComponent(sel
.target
);
75 if (sel
.className
) addUrlParams
+= "&curUrl[class]=" + encodeURIComponent(sel
.className
);
76 if (sel
.title
) addUrlParams
+= "&curUrl[title]=" + encodeURIComponent(sel
.title
);
77 addUrlParams
+= RTEarea
[editorNumber
]["RTEtsConfigParams"];
78 } else if (this.hasSelectedText()) {
79 var text
= this.getSelectedHTML();
80 if (text
&& text
!= null) {
81 var offset
= text
.toLowerCase().indexOf("<a");
83 var ATagContent
= text
.substring(offset
+2);
84 offset
= ATagContent
.toUpperCase().indexOf(">");
85 ATagContent
= ATagContent
.substring(0,offset
);
86 addUrlParams
= "?curUrl[all]=" + encodeURIComponent(ATagContent
);
87 addUrlParams
+= RTEarea
[editorNumber
]["RTEtsConfigParams"];
91 this._popupDialog(RTEarea
[0]["pathLinkModule"] + addUrlParams
+ "&editorNo=" + editorNumber
+ "&typo3ContentLanguage=" + RTEarea
[editorNumber
]["typo3ContentLanguage"] + "&typo3ContentCharset=" + encodeURIComponent(RTEarea
[editorNumber
]["typo3ContentCharset"]), null, backreturn
, 550, 350, null, "yes");
96 * Add a link to the selection.
97 * This function is called from the TYPO3 link popup.
99 HTMLArea
.prototype.renderPopup_addLink = function(theLink
,cur_target
,cur_class
,cur_title
) {
100 var a
, sel
= null, range
= null, node
= null, imageNode
= null;
102 node
= this.getParentElement();
103 var el
= HTMLArea
.getElementObject(node
,"a");
104 if (el
!= null && el
.tagName
&& el
.tagName
.toLowerCase() == "a") node
= el
;
105 if (node
!= null && node
.tagName
&& node
.tagName
.toLowerCase() == "a") this.selectNode(node
);
106 // Clean images from existing anchors otherwise Mozilla may create nested anchors
107 if (this.classesAnchorSetup
) {
108 sel
= this._getSelection();
109 range
= this._createRange(sel
);
110 this.cleanAllLinks(node
, range
, true);
113 this._doc
.execCommand("CreateLink", false, theLink
);
115 sel
= this._getSelection();
116 range
= this._createRange(sel
);
117 node
= this.getParentElement();
118 var el
= HTMLArea
.getElementObject(node
,"a");
119 if (el
!= null && el
.tagName
&& el
.tagName
.toLowerCase() == "a") node
= el
;
121 if (this.classesAnchorSetup
&& cur_class
) {
122 for (var i
= this.classesAnchorSetup
.length
; --i
>= 0;) {
123 var anchorClass
= this.classesAnchorSetup
[i
];
124 if(anchorClass
['name'] == cur_class
&& anchorClass
["image"]) {
125 imageNode
= this._doc
.createElement("img");
126 imageNode
.src
= anchorClass
["image"];
127 imageNode
.alt
= anchorClass
["altText"];
132 // We may have created multiple links in as many blocks
133 this.setLinkAttributes(node
, range
, cur_target
, cur_class
, cur_title
, imageNode
);
136 Dialog
._modal
.close();
137 this.updateToolbar();
141 * Set attributes of anchors intersecting a range in the given node
143 HTMLArea
.prototype.setLinkAttributes = function(node
,range
,cur_target
,cur_class
,cur_title
,imageNode
) {
144 if (node
.tagName
&& node
.tagName
.toLowerCase() == "a") {
145 var nodeInRange
= false;
146 if (HTMLArea
.is_gecko
) {
147 nodeInRange
= this.rangeIntersectsNode(range
, node
);
149 if (this._getSelection().type
.toLowerCase() == "control") {
150 // we assume an image is selected
153 var nodeRange
= this._doc
.body
.createTextRange();
154 nodeRange
.moveToElementText(node
);
155 nodeInRange
= range
.inRange(nodeRange
) || (range
.compareEndPoints("StartToStart", nodeRange
) == 0) || (range
.compareEndPoints("EndToEnd", nodeRange
) == 0);
159 if (imageNode
!= null) node
.insertBefore(imageNode
.cloneNode(false), node
.firstChild
);
160 if (cur_target
.trim()) node
.target
= cur_target
.trim();
161 else node
.removeAttribute("target");
162 if (cur_class
.trim()) {
163 node
.className
= cur_class
.trim();
165 if (HTMLArea
.is_gecko
) node
.removeAttribute('class');
166 else node
.removeAttribute('className');
168 if (cur_title
.trim()) {
169 node
.title
= cur_title
.trim();
171 node
.removeAttribute("title");
172 node
.removeAttribute("rtekeep");
176 for (var i
= node
.firstChild
;i
;i
= i
.nextSibling
) {
177 if (i
.nodeType
== 1 || i
.nodeType
== 11) this.setLinkAttributes(i
, range
, cur_target
, cur_class
, cur_title
, imageNode
);
183 * Clean up images in special anchor classes
185 HTMLArea
.prototype.cleanClassesAnchorImages = function(node
) {
186 var nodeArray
= [], splitArray1
= [], splitArray2
= [];
187 for (var childNode
= node
.firstChild
; childNode
; childNode
= childNode
.nextSibling
) {
188 if (childNode
.tagName
&& childNode
.tagName
.toLowerCase() == "img") {
189 splitArray1
= childNode
.src
.split("/");
190 for (var i
= this.classesAnchorSetup
.length
; --i
>= 0;) {
191 if (this.classesAnchorSetup
[i
]["image"]) {
192 splitArray2
= this.classesAnchorSetup
[i
]["image"].split("/");
193 if (splitArray1
[splitArray1
.length
-1] == splitArray2
[splitArray2
.length
-1]) {
194 nodeArray
.push(childNode
);
201 for (i
= nodeArray
.length
; --i
>= 0;) {
202 node
.removeChild(nodeArray
[i
]);
207 * Clean up all anchors intesecting with the range in the given node
209 HTMLArea
.prototype.cleanAllLinks = function(node
,range
,keepLinks
) {
210 if (node
.tagName
&& node
.tagName
.toLowerCase() == "a") {
211 var intersection
= false;
212 if (HTMLArea
.is_gecko
) {
213 intersection
= this.rangeIntersectsNode(range
, node
);
215 if (this._getSelection().type
.toLowerCase() == "control") {
216 // we assume an image is selected
219 var nodeRange
= this._doc
.body
.createTextRange();
220 nodeRange
.moveToElementText(node
);
221 intersection
= range
.inRange(nodeRange
) || ((range
.compareEndPoints("StartToStart", nodeRange
) > 0) && (range
.compareEndPoints("StartToEnd", nodeRange
) < 0)) || ((range
.compareEndPoints("EndToStart", nodeRange
) > 0) && (range
.compareEndPoints("EndToEnd", nodeRange
) < 0));
225 this.cleanClassesAnchorImages(node
);
227 while(node
.firstChild
) node
.parentNode
.insertBefore(node
.firstChild
, node
);
228 node
.parentNode
.removeChild(node
);
232 for (var i
= node
.firstChild
;i
;i
= i
.nextSibling
) {
233 if (i
.nodeType
== 1 || i
.nodeType
== 11) this.cleanAllLinks(i
, range
, keepLinks
);
239 * Unlink the selection.
240 * This function is called from the TYPO3 link popup and from the context menu.
242 HTMLArea
.prototype.renderPopup_unLink = function() {
244 var node
= this.getParentElement();
245 var el
= HTMLArea
.getElementObject(node
,"a");
246 if (el
!= null && el
.tagName
&& el
.tagName
.toLowerCase() == "a") node
= el
;
247 if (node
!= null && node
.tagName
&& node
.tagName
.toLowerCase() == "a") this.selectNode(node
);
248 if (this.classesAnchorSetup
) {
249 var sel
= this._getSelection();
250 var range
= this._createRange(sel
);
251 if (HTMLArea
.is_gecko
) {
252 this.cleanAllLinks(node
, range
, false);
254 this.cleanAllLinks(node
, range
, true);
255 this._doc
.execCommand("Unlink", false, "");
259 this._doc
.execCommand("Unlink", false, "");
261 if(Dialog
._modal
) Dialog
._modal
.close();
265 * IE-Browsers strip URL's to relative URL's. But for the TYPO3 backend we need absolute URL's.
266 * This function overloads the normal stripBaseURL-function (which generate relative URLs).
268 HTMLArea
.prototype.nonStripBaseURL = function(url
) {
272 TYPO3Browsers
.prototype.onGenerate = function() {
273 var editor
= this.editor
;
274 //editor._insertImage = editor.renderPopup_image;
275 editor
._createLink
= editor
.renderPopup_link
;
276 editor
.stripBaseURL
= editor
.nonStripBaseURL
;