// $Id$
// map of instancename -> FCKeditor object
var fckInstances = {};
var fckActiveId = false;
// this object will store teaser information
var fckTeaser = { lookup : {}, lookupSetup : false, cache : {} };
/**
* Drupal behavior that adds FCKeditors to textareas
*/
Drupal.behaviors.fckeditor = function(context) {
$('textarea.fckeditor:not(.fckeditor-processed)', context).each(function() {
var textarea = $(this).addClass('fckeditor-processed');
var taid = textarea.attr('id');
if (fckInstances[taid]) {
var editorInstance = fckInstances[taid];
if (editorInstance.defaultState == 1) {
if (textarea.attr('class').indexOf("filterxss1") != -1 || textarea.attr('class').indexOf("filterxss2") != -1) {
$.post(Drupal.settings.basePath + 'index.php?q=fckeditor/xss', {
text: $('#' + taid).val(),
'filters[]': Drupal.settings.fckeditor_filters[fckInstances[taid].DrupalId]
},
function(text) {
textarea.val(text);
$('#img_assist-link-' + taid).hide();
$(".img_assist-button").hide();
editorInstance.ReplaceTextarea();
}
);
}
else {
editorInstance.ReplaceTextarea();
$('#img_assist-link-' + taid).hide();
$(".img_assist-button").hide();
}
}
}
});
}
/**
* This method takes care of replacing a textarea with an FCKeditor
* and vice versa.
*/
function Toggle(textareaID, TextTextarea, TextRTE, xss_check)
{
var swtch = $('#switch_'+textareaID);
// check if this FCKeditor was initially disabled
if (fckInstances[textareaID].defaultState == 0) {
fckInstances[textareaID].defaultState = 2;
if ($('#' + textareaID).attr('class').indexOf("filterxss2") != -1) {
$.post(Drupal.settings.basePath + 'index.php?q=fckeditor/xss', {
text: $('#' + textareaID).val(),
'filters[]': Drupal.settings.fckeditor_filters[fckInstances[textareaID].DrupalId]
},
function(text) {
$('#' + textareaID).val(text);
fckInstances[textareaID].ReplaceTextarea();
}
);
}
else {
fckInstances[textareaID].ReplaceTextarea();
}
swtch.text(TextTextarea);
$(".img_assist-button").hide();
// simply return: ReplaceTextarea will take the contents of the textarea for us
return;
}
var textArea = $('#'+textareaID);
var textAreaContainer = $('#'+textareaID).parents('.resizable-textarea');
var editorFrame = $('#'+textareaID+'___Frame');
var editorInstance = FCKeditorAPI.GetInstance(textareaID);
var text;
// execute the switch
if (textArea.is(':hidden')) {
// switch from fck to textarea
swtch.text(TextRTE);
text = editorInstance.GetData(true);
// #372150 and #374386
if (text == '
' || text == '
' || text == '
') {
text = '';
}
// check if we have to take care of teasers
var teaser = FCKeditor_TeaserInfo(textareaID);
if (teaser) {
var t = text.indexOf('');
if (t != -1) {
teaser.textarea.val(FCKeditor_trim(text.slice(0,t)));
text = FCKeditor_trim(text.slice(t+12));
teaser.textareaContainer.show();
teaser.textarea.attr('disabled', '');
if (teaser.button.attr('value') != Drupal.t('Join summary')) {
try {teaser.button.click();} catch(e) {teaser.button.val(Drupal.t('Join summary'));}
}
} else {
teaser.textarea.attr('disabled', 'disabled');
if (teaser.button.attr('value') != Drupal.t('Split summary at cursor')) {
try {teaser.button.click();} catch(e) {teaser.button.val(Drupal.t('Split summary at cursor'));}
}
}
teaser.buttonContainer.show();
} else {
text = textArea.val();
}
textArea.val(text);
textArea.show();
textAreaContainer.show();
editorFrame.hide();
$('#img_assist-link-' + textareaID).show();
$(".img_assist-button").show();
$(textArea).parent().children(".grippie").show();
} else {
// switch from textarea to fck
swtch.text(TextTextarea);
// check if we have to take care of teasers
var teaser = FCKeditor_TeaserInfo(textareaID);
if (teaser) {
if (teaser.textarea.val().length > 0) {
text = teaser.textarea.val() + '\n\n' + textArea.val();
} else {
text = textArea.val();
}
teaser.textarea.attr('disabled', '');
teaser.buttonContainer.hide();
teaser.textareaContainer.hide();
teaser.checkboxContainer.show();
}
editorInstance.SetData(text, true);
// Switch the DIVs display.
textArea.hide();
textAreaContainer.show();
$(editorInstance.LinkedField).parent().children(".grippie").hide();
editorFrame.show();
$('#img_assist-link-' + textareaID).hide();
$(".img_assist-button").hide();
}
}
// Update a global variable containing the active FCKeditor ID.
function DoFCKeditorUpdateId(editorInstance) {
fckActiveId = editorInstance.Name;
}
/**
* The FCKeditor_OnComplete function is a special function called everytime an
* editor instance is completely loaded and available for API interactions.
*/
function FCKeditor_OnComplete(editorInstance) {
// Enable the switch button. It is disabled at startup, waiting the editor to be loaded.
$('#switch_' + editorInstance.Name).show();
editorInstance.Events.AttachEvent('OnAfterLinkedFieldUpdate', FCKeditor_OnAfterLinkedFieldUpdate);
editorInstance.Events.AttachEvent('OnFocus', DoFCKeditorUpdateId);
var teaser = FCKeditor_TeaserInfo(editorInstance.Name);
if (teaser) {
// if there is a teaser, prepend it to the text, only when switched to FCKeditor using toggle
//if (fckInstances[editorInstance.Name].defaultState == 2) {
if (teaser.textarea.val().length > 0 && editorInstance.GetData(true).indexOf('') == -1 ) {
var text = teaser.textarea.val() + '\n\n' + editorInstance.GetData(true);
editorInstance.SetData(text);
}
//}
// hide the teaser
teaser.textarea.attr('disabled', '');
teaser.buttonContainer.hide();
teaser.textareaContainer.hide();
teaser.checkboxContainer.show();
}
$(editorInstance.LinkedField).parent().children(".grippie").hide();
// very ugly hack to circumvent FCKeditor from re-updating textareas on submission. We do that ourselves
// FCKeditor will happily update the fake textarea while we will use the proper one
editorInstance.LinkedField2 = editorInstance.LinkedField;
editorInstance.LinkedField = $('');
// Img_Assist integration
IntegrateWithImgAssist();
}
/**
* This method is executed for every FCKeditor instance just after the underlying text field is updated
* before the form is submitted.
*/
function FCKeditor_OnAfterLinkedFieldUpdate(editorInstance) {
var textArea = editorInstance.LinkedField2;
var taid = textArea.id;
var teaser = FCKeditor_TeaserInfo(taid);
// when textArea is hidden, FCKeditor is visible
if ($(textArea).is(':hidden')) {
var text = editorInstance.GetData(true);
// #372150 and #374386
if (text == '
' || text == '
' || text == '
') {
text = '';
}
textArea.value = text;
// only update the teaser field if this field is associated with a teaser field
if (teaser) {
var t = text.indexOf('');
if (t != -1) {
teaser.textarea.val(FCKeditor_trim(text.slice(0,t)));
textArea.value = FCKeditor_trim(text.slice(t+12));
} else {
teaser.textarea.val('');
teaser.textarea.attr('disabled', 'disabled');
var teaserbuttontxt = Drupal.t('Join summary');
if (teaser.button.attr('value') == teaserbuttontxt) {
try {
teaser.button.click();
} catch(e) {
teaserbutton.val(teaserbuttontxt);
}
}
}
}
}
}
function IntegrateWithImgAssist()
{
var link = document.getElementsByTagName("a");
for (var i = 0; i < link.length; i++) {
cl = link[i].className;
if ( cl == "img_assist-link") {
link[i].href = link[i].href.replace("/load/textarea", "/load/fckeditor");
}
}
}
/**
* Removes leading and trailing whitespace from the input
*/
function FCKeditor_trim(text) {
return text.replace(/^\s+/g, '').replace(/\s+$/g, '');
}
/**
* This function retrieves information about a possible teaser field
* associated with the mentioned field.
*
* @param taid string HTML id of the main text area
*/
function FCKeditor_TeaserInfo(taid) {
// if the result is cached, return it
if (fckTeaser.cache[taid]) {
return fckTeaser.cache[taid];
}
// build a lookup table
if (!fckTeaser.lookupSetup) {
fckTeaser.lookupSetup = true;
for(var x in Drupal.settings.teaser) {
fckTeaser.lookup[Drupal.settings.teaser[x]] = x;
}
}
// find the elements
if (fckTeaser.lookup[taid]) {
var obj = {
textarea : $('#'+fckTeaser.lookup[taid]),
checkbox : $('#'+Drupal.settings.teaserCheckbox[fckTeaser.lookup[taid]])
};
obj.textareaContainer = obj.textarea.parent();
obj.checkboxContainer = obj.checkbox.parent();
obj.button = $('input.teaser-button', obj.checkbox.parents('div.teaser-checkbox').get(0));
obj.buttonContainer = obj.button.parent();
fckTeaser.cache[taid] = obj;
} else {
fckTeaser.cache[taid] = null;
}
return fckTeaser.cache[taid];
}
/**
* Creates a screen wide popup window containing an FCKeditor
*/
function FCKeditor_OpenPopup(popupUrl, jsID, textareaID) {
popupUrl = popupUrl + '?var='+ jsID + '&el=' + textareaID;
var teaser = FCKeditor_TeaserInfo(textareaID);
if (teaser) {
popupUrl = popupUrl + '&teaser=' + teaser.textarea.attr('id');
}
window.open(popupUrl, null, 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=1,dependent=yes');
}
// Probably JsMin was used to compress the code.
// In such case, in IE FCKeditor_IsCompatibleBrowser() will always return false.
if (typeof(FCKeditor_IsCompatibleBrowser) == 'function' && !FCKeditor_IsCompatibleBrowser()) {
var FCKeditor_IsCompatibleBrowser = function() {
var sAgent = navigator.userAgent.toLowerCase() ;
// Internet Explorer 5.5+
if ( sAgent.indexOf("mac") == -1 && sAgent.indexOf("opera") == -1 && navigator.appVersion.match( /MSIE (.\..)/ ) )
{
var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1] ;
return ( sBrowserVersion >= 5.5 ) ;
}
return false;
}
}
/**
* Integration for ajax.module
*/
function doFCKeditorSave() {
for(var textareaid in fckInstances) {
FCKeditor_OnAfterLinkedFieldUpdate(FCKeditorAPI.GetInstance(textareaid));
}
}