META-INF.resources.primefaces.editor.editor.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of primefaces Show documentation
Show all versions of primefaces Show documentation
PrimeFaces is one of the most popular UI libraries in Java EE Ecosystem and widely used by software companies, world renowned brands, banks, financial institutions, insurance companies, universities and more.
/*!
CLEditor WYSIWYG HTML Editor v1.4.5
http://premiumsoftware.net/CLEditor
requires jQuery v1.4.2 or later
Copyright 2010, Chris Landowski, Premium Software, LLC
Dual licensed under the MIT or GPL Version 2 licenses.
*/
(function ($) {
//==============
// jQuery Plugin
//==============
$.cleditor = {
// Define the defaults used for all new cleditor instances
defaultOptions: {
width: 'auto', // width not including margins, borders or padding
height: 250, // height not including margins, borders or padding
controls: // controls to add to the toolbar
"bold italic underline strikethrough subscript superscript | font size " +
"style | color highlight removeformat | bullets numbering | outdent " +
"indent | alignleft center alignright justify | undo redo | " +
"rule image link unlink | cut copy paste pastetext | print source",
colors: // colors in the color popup
"FFF FCC FC9 FF9 FFC 9F9 9FF CFF CCF FCF " +
"CCC F66 F96 FF6 FF3 6F9 3FF 6FF 99F F9F " +
"BBB F00 F90 FC6 FF0 3F3 6CC 3CF 66C C6C " +
"999 C00 F60 FC3 FC0 3C0 0CC 36F 63F C3C " +
"666 900 C60 C93 990 090 399 33F 60C 939 " +
"333 600 930 963 660 060 366 009 339 636 " +
"000 300 630 633 330 030 033 006 309 303",
fonts: // font names in the font popup
"Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond," +
"Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",
sizes: // sizes in the font size popup
"1,2,3,4,5,6,7",
styles: // styles in the style popup
[["Paragraph", ""], ["Header 1", "
"], ["Header 2", ""],
["Header 3", ""], ["Header 4", ""], ["Header 5", ""],
["Header 6", ""]],
useCSS: true, // use CSS to style HTML when possible (not supported in ie)
docType: // Document type contained within the editor
'',
docCSSFile: // CSS file used to style the document contained within the editor
"",
bodyStyle: // style to assign to document body contained within the editor
"margin:4px; font:10pt Arial,Verdana; cursor:text"
},
// Define all usable toolbar buttons - the init string property is
// expanded during initialization back into the buttons object and
// separate object properties are created for each button.
// e.g. buttons.size.title = "Font Size"
buttons: {
// name,title,command,popupName (""=use name)
init:
"bold,,|" +
"italic,,|" +
"underline,,|" +
"strikethrough,,|" +
"subscript,,|" +
"superscript,,|" +
"font,,fontname,|" +
"size,Font Size,fontsize,|" +
"style,,formatblock,|" +
"color,Font Color,forecolor,|" +
"highlight,Text Highlight Color,hilitecolor,color|" +
"removeformat,Remove Formatting,|" +
"bullets,,insertunorderedlist|" +
"numbering,,insertorderedlist|" +
"outdent,,|" +
"indent,,|" +
"alignleft,Align Text Left,justifyleft|" +
"center,,justifycenter|" +
"alignright,Align Text Right,justifyright|" +
"justify,,justifyfull|" +
"undo,,|" +
"redo,,|" +
"rule,Insert Horizontal Rule,inserthorizontalrule|" +
"image,Insert Image,insertimage,url|" +
"link,Insert Hyperlink,createlink,url|" +
"unlink,Remove Hyperlink,|" +
"cut,,|" +
"copy,,|" +
"paste,,|" +
"pastetext,Paste as Text,inserthtml,|" +
"print,,|" +
"source,Show Source"
},
// imagesPath - returns the path to the images folder
imagesPath: function () { return imagesPath(); }
};
// cleditor - creates a new editor for each of the matched textareas
$.fn.cleditor = function (options) {
// Create a new jQuery object to hold the results
var $result = $([]);
// Loop through all matching textareas and create the editors
this.each(function (idx, elem) {
if (elem.tagName.toUpperCase() === "TEXTAREA") {
var data = $.data(elem, CLEDITOR);
if (!data) data = new cleditor(elem, options);
$result = $result.add(data);
}
});
// return the new jQuery object
return $result;
};
//==================
// Private Variables
//==================
var
// Misc constants
BACKGROUND_COLOR = "backgroundColor",
BLURRED = "blurred",
BUTTON = "button",
BUTTON_NAME = "buttonName",
CHANGE = "change",
CLEDITOR = "cleditor",
CLICK = "click",
DISABLED = "disabled",
DIV_TAG = "",
FOCUSED = "focused",
TRANSPARENT = "transparent",
UNSELECTABLE = "unselectable",
// Class name constants
MAIN_CLASS = "ui-editor ui-widget-content", // main containing div
TOOLBAR_CLASS = "ui-editor-toolbar", // toolbar div inside main div
GROUP_CLASS = "ui-editor-group", // group divs inside the toolbar div
BUTTON_CLASS = "ui-editor-button", // button divs inside group div
DISABLED_CLASS = "ui-editor-disabled",// disabled button divs
DIVIDER_CLASS = "ui-editor-divider", // divider divs inside group div
POPUP_CLASS = "ui-editor-popup", // popup divs inside body
LIST_CLASS = "ui-editor-list", // list popup divs inside body
COLOR_CLASS = "ui-editor-color", // color popup div inside body
PROMPT_CLASS = "ui-editor-prompt", // prompt popup divs inside body
MSG_CLASS = "ui-editor-message", // message popup div inside body
// Browser detection
ua = navigator.userAgent.toLowerCase(),
ie = /msie/.test(ua),
ie6 = /msie\s6/.test(ua),
iege11 = /(trident)(?:.*rv:([\w.]+))?/.test(ua),
webkit = /webkit/.test(ua),
// Test for iPhone/iTouch/iPad
iOS = /iPhone|iPad|iPod/i.test(ua),
// Popups are created once as needed and shared by all editor instances
popups = {},
// Used to prevent the document click event from being bound more than once
documentClickAssigned,
// Local copy of the buttons object
buttons = $.cleditor.buttons;
//===============
// Initialization
//===============
// Expand the buttons.init string back into the buttons object
// and create seperate object properties for each button.
// e.g. buttons.size.title = "Font Size"
$.each(buttons.init.split("|"), function (idx, button) {
var items = button.split(","), name = items[0];
buttons[name] = {
stripIndex: idx,
name: name,
title: items[1] === "" ? name.charAt(0).toUpperCase() + name.substr(1) : items[1],
command: items[2] === "" ? name : items[2],
popupName: items[3] === "" ? name : items[3]
};
});
delete buttons.init;
//============
// Constructor
//============
// cleditor - creates a new editor for the passed in textarea element
cleditor = function (area, options) {
var editor = this;
// Get the defaults and override with options
editor.options = options = $.extend({}, $.cleditor.defaultOptions, options);
// Hide the textarea and associate it with this editor
var $area = editor.$area = $(area)
.css({ border: "none", margin: 0, padding: 0 }) // Needed for IE6 & 7 (won't work in CSS file)
.hide()
.data(CLEDITOR, editor)
.blur(function () {
// Update the iframe when the textarea loses focus
updateFrame(editor, true);
});
// Create the main container
var $main = editor.$main = $(DIV_TAG)
.addClass(MAIN_CLASS)
.width(options.width)
.height(options.height);
// Create the toolbar
var $toolbar = editor.$toolbar = $(DIV_TAG)
.addClass(TOOLBAR_CLASS)
.appendTo($main);
// Add the first group to the toolbar
var $group = $(DIV_TAG)
.addClass(GROUP_CLASS)
.appendTo($toolbar);
// Initialize the group width
var groupWidth = 0;
// Add the buttons to the toolbar
$.each(options.controls.split(" "), function (idx, buttonName) {
if (buttonName === "") return true;
// Divider
if (buttonName === "|") {
// Add a new divider to the group
var $div = $(DIV_TAG)
.addClass(DIVIDER_CLASS)
.appendTo($group);
// Update the group width
$group.width(groupWidth + 1);
groupWidth = 0;
// Create a new group
$group = $(DIV_TAG)
.addClass(GROUP_CLASS)
.appendTo($toolbar);
}
// Button
else {
// Get the button definition
var button = buttons[buttonName];
// Add a new button to the group
var $buttonDiv = $(DIV_TAG)
.data(BUTTON_NAME, button.name)
.addClass(BUTTON_CLASS)
.attr("title", button.title)
.bind(CLICK, $.proxy(buttonClick, editor))
.appendTo($group)
.hover(hoverEnter, hoverLeave);
// Update the group width
groupWidth += 24;
$group.width(groupWidth + 1);
// Prepare the button image
var map = {};
if (button.css) map = button.css;
else if (button.image) map.backgroundImage = imageUrl(button.image);
if (button.stripIndex) map.backgroundPosition = button.stripIndex * -24;
$buttonDiv.css(map);
// Add the unselectable attribute for ie
if (ie)
$buttonDiv.attr(UNSELECTABLE, "on");
// Create the popup
if (button.popupName)
createPopup(button.popupName, options, button.popupClass,
button.popupContent, button.popupHover);
}
});
// Add the main div to the DOM and append the textarea
$main.insertBefore($area)
.append($area);
// Bind the document click event handler
if (!documentClickAssigned) {
$(document).click(function (e) {
// Dismiss all non-prompt popups
var $target = $(e.target);
if (!$target.add($target.parents()).is("." + PROMPT_CLASS))
hidePopups();
});
documentClickAssigned = true;
}
// Bind the window resize event when the width or height is auto or %
if (/auto|%/.test("" + options.width + options.height))
$(window).bind("resize.cleditor", function () { refresh(editor); });
// Create the iframe and resize the controls
refresh(editor);
};
//===============
// Public Methods
//===============
var fn = cleditor.prototype,
// Expose the following private functions as methods on the cleditor object.
// The closure compiler will rename the private functions. However, the
// exposed method names on the cleditor object will remain fixed.
methods = [
["clear", clear],
["disable", disable],
["execCommand", execCommand],
["focus", focus],
["hidePopups", hidePopups],
["sourceMode", sourceMode, true],
["refresh", refresh],
["select", select],
["selectedHTML", selectedHTML, true],
["selectedText", selectedText, true],
["showMessage", showMessage],
["updateFrame", updateFrame],
["updateTextArea", updateTextArea]
];
$.each(methods, function (idx, method) {
fn[method[0]] = function () {
var editor = this, args = [editor];
// using each here would cast booleans into objects!
for (var x = 0; x < arguments.length; x++) { args.push(arguments[x]); }
var result = method[1].apply(editor, args);
if (method[2]) return result;
return editor;
};
});
// blurred - shortcut for .bind("blurred", handler) or .trigger("blurred")
fn.blurred = function (handler) {
var $this = $(this);
return handler ? $this.bind(BLURRED, handler) : $this.trigger(BLURRED);
};
// change - shortcut for .bind("change", handler) or .trigger("change")
fn.change = function change(handler) {
var $this = $(this);
return handler ? $this.bind(CHANGE, handler) : $this.trigger(CHANGE);
};
// focused - shortcut for .bind("focused", handler) or .trigger("focused")
fn.focused = function (handler) {
var $this = $(this);
return handler ? $this.bind(FOCUSED, handler) : $this.trigger(FOCUSED);
};
//===============
// Event Handlers
//===============
// buttonClick - click event handler for toolbar buttons
function buttonClick(e) {
var editor = this,
buttonDiv = e.target,
buttonName = $.data(buttonDiv, BUTTON_NAME),
button = buttons[buttonName],
popupName = button.popupName,
popup = popups[popupName];
// Check if disabled
if (editor.disabled || $(buttonDiv).attr(DISABLED) === DISABLED)
return;
// Fire the buttonClick event
var data = {
editor: editor,
button: buttonDiv,
buttonName: buttonName,
popup: popup,
popupName: popupName,
command: button.command,
useCSS: editor.options.useCSS
};
if (button.buttonClick && button.buttonClick(e, data) === false)
return false;
// Toggle source
if (buttonName === "source") {
// Show the iframe
if (sourceMode(editor)) {
delete editor.range;
editor.$area.hide();
editor.$frame.show();
buttonDiv.title = button.title;
}
// Show the textarea
else {
editor.$frame.hide();
editor.$area.show();
buttonDiv.title = "Show Rich Text";
}
}
// Check for rich text mode
else if (!sourceMode(editor)) {
// Handle popups
if (popupName) {
var $popup = $(popup);
// URL
if (popupName === "url") {
// Check for selection before showing the link url popup
if (buttonName === "link" && selectedText(editor) === "") {
showMessage(editor, "A selection is required when inserting a link.", buttonDiv);
return false;
}
// Wire up the submit button click event handler
$popup.children(":button")
.unbind(CLICK)
.bind(CLICK, function () {
// Insert the image or link if a url was entered
var $text = $popup.find(":text"),
url = $.trim($text.val());
if (url !== "")
execCommand(editor, data.command, url, null, data.button);
// Reset the text, hide the popup and set focus
$text.val("http://");
hidePopups();
focus(editor);
});
}
// Paste as Text
else if (popupName === "pastetext") {
// Wire up the submit button click event handler
$popup.children(":button")
.unbind(CLICK)
.bind(CLICK, function () {
// Insert the unformatted text replacing new lines with break tags
var $textarea = $popup.find("textarea"),
text = $textarea.val().replace(/\n/g, "
");
if (text !== "")
execCommand(editor, data.command, text, null, data.button);
// Reset the text, hide the popup and set focus
$textarea.val("");
hidePopups();
focus(editor);
});
}
// Show the popup if not already showing for this button
if (buttonDiv !== $.data(popup, BUTTON)) {
showPopup(editor, popup, buttonDiv);
return false; // stop propagination to document click
}
// propaginate to document click
return;
}
// Print
else if (buttonName === "print")
editor.$frame[0].contentWindow.print();
// All other buttons
else if (!execCommand(editor, data.command, data.value, data.useCSS, buttonDiv))
return false;
}
// Focus the editor
focus(editor);
}
// hoverEnter - mouseenter event handler for buttons and popup items
function hoverEnter(e) {
var $div = $(e.target).closest("div");
$div.css(BACKGROUND_COLOR, $div.data(BUTTON_NAME) ? "#FFF" : "#FFC");
}
// hoverLeave - mouseleave event handler for buttons and popup items
function hoverLeave(e) {
$(e.target).closest("div").css(BACKGROUND_COLOR, "transparent");
}
// popupClick - click event handler for popup items
function popupClick(e) {
var editor = this,
popup = e.data.popup,
target = e.target;
// Check for message and prompt popups
if (popup === popups.msg || $(popup).hasClass(PROMPT_CLASS))
return;
// Get the button info
var buttonDiv = $.data(popup, BUTTON),
buttonName = $.data(buttonDiv, BUTTON_NAME),
button = buttons[buttonName],
command = button.command,
value,
useCSS = editor.options.useCSS;
// Get the command value
if (buttonName === "font")
// Opera returns the fontfamily wrapped in quotes
value = target.style.fontFamily.replace(/"/g, "");
else if (buttonName === "size") {
if (target.tagName.toUpperCase() === "DIV")
target = target.children[0];
value = target.innerHTML;
}
else if (buttonName === "style")
value = "<" + target.tagName + ">";
else if (buttonName === "color")
value = hex(target.style.backgroundColor);
else if (buttonName === "highlight") {
value = hex(target.style.backgroundColor);
if (ie) command = 'backcolor';
else useCSS = true;
}
// Fire the popupClick event
var data = {
editor: editor,
button: buttonDiv,
buttonName: buttonName,
popup: popup,
popupName: button.popupName,
command: command,
value: value,
useCSS: useCSS
};
if (button.popupClick && button.popupClick(e, data) === false)
return;
// Execute the command
if (data.command && !execCommand(editor, data.command, data.value, data.useCSS, buttonDiv))
return false;
// Hide the popup and focus the editor
hidePopups();
focus(editor);
}
//==================
// Private Functions
//==================
// checksum - returns a checksum using the Adler-32 method
function checksum(text) {
var a = 1, b = 0;
for (var index = 0; index < text.length; ++index) {
a = (a + text.charCodeAt(index)) % 65521;
b = (b + a) % 65521;
}
return (b << 16) | a;
}
// clear - clears the contents of the editor
function clear(editor) {
editor.$area.val("");
updateFrame(editor);
}
// createPopup - creates a popup and adds it to the body
function createPopup(popupName, options, popupTypeClass, popupContent, popupHover) {
// Check if popup already exists
if (popups[popupName])
return popups[popupName];
// Create the popup
var $popup = $(DIV_TAG)
.hide()
.addClass(POPUP_CLASS)
.appendTo("body");
// Add the content
// Custom popup
if (popupContent)
$popup.html(popupContent);
// Color
else if (popupName === "color") {
var colors = options.colors.split(" ");
if (colors.length < 10)
$popup.width("auto");
$.each(colors, function (idx, color) {
$(DIV_TAG).appendTo($popup)
.css(BACKGROUND_COLOR, "#" + color);
});
popupTypeClass = COLOR_CLASS;
}
// Font
else if (popupName === "font")
$.each(options.fonts.split(","), function (idx, font) {
$(DIV_TAG).appendTo($popup)
.css("fontFamily", font)
.html(font);
});
// Size
else if (popupName === "size")
$.each(options.sizes.split(","), function (idx, size) {
$(DIV_TAG).appendTo($popup)
.html('' + size + '');
});
// Style
else if (popupName === "style")
$.each(options.styles, function (idx, style) {
$(DIV_TAG).appendTo($popup)
.html(style[1] + style[0] + style[1].replace("<", "Enter URL:
');
popupTypeClass = PROMPT_CLASS;
}
// Paste as Text
else if (popupName === "pastetext") {
$popup.html('
');
popupTypeClass = PROMPT_CLASS;
}
// Add the popup type class name
if (!popupTypeClass && !popupContent)
popupTypeClass = LIST_CLASS;
$popup.addClass(popupTypeClass);
// Add the unselectable attribute to all items
if (ie) {
$popup.attr(UNSELECTABLE, "on")
.find("div,font,p,h1,h2,h3,h4,h5,h6")
.attr(UNSELECTABLE, "on");
}
// Add the hover effect to all items
if ($popup.hasClass(LIST_CLASS) || popupHover === true)
$popup.children().hover(hoverEnter, hoverLeave);
// Add the popup to the array and return it
popups[popupName] = $popup[0];
return $popup[0];
}
// disable - enables or disables the editor
function disable(editor, disabled) {
// Update the textarea and save the state
if (disabled) {
editor.$area.attr(DISABLED, DISABLED);
editor.disabled = true;
}
else {
editor.$area.removeAttr(DISABLED);
delete editor.disabled;
}
// Switch the iframe into design mode.
// ie6 does not support designMode.
// ie7 & ie8 do not properly support designMode="off".
try {
if (ie) editor.doc.body.contentEditable = !disabled;
else editor.doc.designMode = !disabled ? "on" : "off";
}
// Firefox 1.5 throws an exception that can be ignored
// when toggling designMode from off to on.
catch (err) { }
// Enable or disable the toolbar buttons
refreshButtons(editor);
}
// execCommand - executes a designMode command
function execCommand(editor, command, value, useCSS, button) {
// Restore the current ie selection
restoreRange(editor);
// Set the styling method
if (!ie) {
if (useCSS === undefined || useCSS === null)
useCSS = editor.options.useCSS;
editor.doc.execCommand("styleWithCSS", 0, useCSS.toString());
}
// Execute the command and check for error
var inserthtml = command.toLowerCase() === "inserthtml";
if (ie && inserthtml) {
/*
Despite having access to pasteHTML, IE8 will produce an 'unspecified error'
if it is invoked. The only way to detect this bug is via try catch.
*/
try{
getRange(editor).pasteHTML(value);
}
catch(e){
// An empty document needs selection beforehand
if(/^\s*$/.test(editor.doc.body.innerText)){
editor.doc.execCommand('selectAll',false, null);
}
// execCommand is the standard method for contentEditable elements
editor.doc.execCommand("Paste", 0, value || null);
}
}
else if (iege11 && inserthtml) {
var selection = getSelection(editor),
range = selection.getRangeAt(0);
range.deleteContents();
range.insertNode(range.createContextualFragment(value));
selection.removeAllRanges();
selection.addRange(range);
}
else {
var success = true, message;
try { success = editor.doc.execCommand(command, 0, value || null); }
catch (err) { message = err.message; success = false; }
if (!success) {
if ("cutcopypaste".indexOf(command) > -1)
showMessage(editor, "For security reasons, your browser does not support the " +
command + " command. Try using the keyboard shortcut or context menu instead.",
button);
else
showMessage(editor,
(message ? message : "Error executing the " + command + " command."),
button);
}
}
// Enable the buttons and update the textarea
refreshButtons(editor);
updateTextArea(editor, true);
return success;
}
// focus - sets focus to either the textarea or iframe
function focus(editor) {
setTimeout(function () {
if (sourceMode(editor)) editor.$area.focus();
else editor.$frame[0].contentWindow.focus();
refreshButtons(editor);
}, 0);
}
// getRange - gets the current text range object
function getRange(editor) {
if (ie) return getSelection(editor).createRange();
return getSelection(editor).getRangeAt(0);
}
// getSelection - gets the current text range object
function getSelection(editor) {
if (ie) return editor.doc.selection;
return editor.$frame[0].contentWindow.getSelection();
}
// hex - returns the hex value for the passed in color string
function hex(s) {
// hex("rgb(255, 0, 0)") returns #FF0000
var m = /rgba?\((\d+), (\d+), (\d+)/.exec(s);
if (m) {
s = (m[1] << 16 | m[2] << 8 | m[3]).toString(16);
while (s.length < 6)
s = "0" + s;
return "#" + s;
}
// hex("#F00") returns #FF0000
var c = s.split("");
if (s.length === 4)
return "#" + c[1] + c[1] + c[2] + c[2] + c[3] + c[3];
// hex("#FF0000") returns #FF0000
return s;
}
// hidePopups - hides all popups
function hidePopups() {
$.each(popups, function (idx, popup) {
$(popup)
.hide()
.unbind(CLICK)
.removeData(BUTTON);
});
}
// imagesPath - returns the path to the images folder
function imagesPath() {
var href = $("link[href*=cleditor]").attr("href");
return href.replace(/^(.*\/)[^\/]+$/, '$1') + "images/";
}
// imageUrl - Returns the css url string for a filemane
function imageUrl(filename) {
return "url(" + imagesPath() + filename + ")";
}
// refresh - creates the iframe and resizes the controls
function refresh(editor) {
var $main = editor.$main,
options = editor.options;
// Remove the old iframe
if (editor.$frame)
editor.$frame.remove();
// Create a new iframe
var $frame = editor.$frame = $('')
.hide()
.appendTo($main);
// Load the iframe document content
var contentWindow = $frame[0].contentWindow,
doc = editor.doc = contentWindow.document,
$doc = $(doc);
doc.open();
doc.write(
options.docType +
'' +
((options.docCSSFile === '') ? '' : '') +
''
);
doc.close();
// Work around for bug in IE which causes the editor to lose
// focus when clicking below the end of the document.
if (ie || iege11)
$doc.click(function () { focus(editor); });
// Load the content
updateFrame(editor);
// Bind the ie specific iframe event handlers
if (ie || iege11) {
// Save the current user selection. This code is needed since IE will
// reset the selection just after the beforedeactivate event and just
// before the beforeactivate event.
$doc.bind("beforedeactivate beforeactivate selectionchange keypress keyup", function (e) {
// Flag the editor as inactive
if (e.type === "beforedeactivate")
editor.inactive = true;
// Get rid of the bogus selection and flag the editor as active
else if (e.type === "beforeactivate") {
if (!editor.inactive && editor.range && editor.range.length > 1)
editor.range.shift();
delete editor.inactive;
}
// Save the selection when the editor is active
else if (!editor.inactive) {
if (!editor.range)
editor.range = [];
editor.range.unshift(getRange(editor));
// We only need the last 2 selections
while (editor.range.length > 2)
editor.range.pop();
}
});
// Restore the text range and trigger focused event when the iframe gains focus
$frame.focus(function () {
restoreRange(editor);
$(editor).triggerHandler(FOCUSED);
});
// Trigger blurred event when the iframe looses focus
$frame.blur(function () {
$(editor).triggerHandler(BLURRED);
});
}
// Trigger focused and blurred events for all other browsers
else {
$($frame[0].contentWindow)
.focus(function () { $(editor).triggerHandler(FOCUSED); })
.blur(function () { $(editor).triggerHandler(BLURRED); });
}
// Enable the toolbar buttons and update the textarea as the user types or clicks
$doc.click(hidePopups)
.keydown(function (e) {
// Prevent Internet Explorer from going to prior page when an image
// is selected and the backspace key is pressed.
if (ie && getSelection(editor).type == "Control" && e.keyCode == 8) {
getSelection(editor).clear();
e.preventDefault();
}
})
.bind("keyup mouseup", function () {
refreshButtons(editor);
updateTextArea(editor, true);
})
.bind("paste", function() {
setTimeout(function() {
refreshButtons(editor);
updateTextArea(editor, true);
}, 0)
});
// Show the textarea for iPhone/iTouch/iPad or
// the iframe when design mode is supported.
if (iOS) editor.$area.show();
else $frame.show();
// Wait for the layout to finish - shortcut for $(document).ready()
$(function () {
var $toolbar = editor.$toolbar,
$group = $toolbar.children("div:last"),
wid = $main.width();
// Resize the toolbar
var hgt = $group.offset().top + $group.outerHeight() - $toolbar.offset().top + 1;
$toolbar.height(hgt);
// Resize the iframe
hgt = (/%/.test("" + options.height) ? $main.height() : parseInt(options.height, 10)) - hgt;
$frame.width(wid).height(hgt);
// Resize the textarea. IE6 textareas have a 1px top
// & bottom margin that cannot be removed using css.
editor.$area.width(wid).height(ie6 ? hgt - 2 : hgt);
// Switch the iframe into design mode if enabled
disable(editor, editor.disabled);
// Enable or disable the toolbar buttons
refreshButtons(editor);
});
}
// refreshButtons - enables or disables buttons based on availability
function refreshButtons(editor) {
// Webkit requires focus before queryCommandEnabled will return anything but false
if (!iOS && webkit && !editor.focused) {
editor.$frame[0].contentWindow.focus();
window.focus();
editor.focused = true;
}
// Get the object used for checking queryCommandEnabled
var queryObj = editor.doc;
if (ie) queryObj = getRange(editor);
// Loop through each button
var inSourceMode = sourceMode(editor);
$.each(editor.$toolbar.find("." + BUTTON_CLASS), function (idx, elem) {
var $elem = $(elem),
button = $.cleditor.buttons[$.data(elem, BUTTON_NAME)],
command = button.command,
enabled = true;
// Determine the state
if (editor.disabled)
enabled = false;
else if (button.getEnabled) {
var data = {
editor: editor,
button: elem,
buttonName: button.name,
popup: popups[button.popupName],
popupName: button.popupName,
command: button.command,
useCSS: editor.options.useCSS
};
enabled = button.getEnabled(data);
if (enabled === undefined)
enabled = true;
}
else if (((inSourceMode || iOS) && button.name !== "source") ||
(ie && (command === "undo" || command === "redo")))
enabled = false;
else if (command && command !== "print") {
if (ie && command === "hilitecolor")
command = "backcolor";
// IE does not support inserthtml, so it's always enabled
if ((!ie && !iege11) || command !== "inserthtml") {
try { enabled = queryObj.queryCommandEnabled(command); }
catch (err) { enabled = false; }
}
}
// Enable or disable the button
if (enabled) {
$elem.removeClass(DISABLED_CLASS);
$elem.removeAttr(DISABLED);
}
else {
$elem.addClass(DISABLED_CLASS);
$elem.attr(DISABLED, DISABLED);
}
});
}
// restoreRange - restores the current ie selection
function restoreRange(editor) {
if (editor.range) {
if (ie)
editor.range[0].select();
else if (iege11)
getSelection(editor).addRange(editor.range[0]);
}
}
// select - selects all the text in either the textarea or iframe
function select(editor) {
setTimeout(function () {
if (sourceMode(editor)) editor.$area.select();
else execCommand(editor, "selectall");
}, 0);
}
// selectedHTML - returns the current HTML selection or and empty string
function selectedHTML(editor) {
restoreRange(editor);
var range = getRange(editor);
if (ie)
return range.htmlText;
var layer = $("")[0];
layer.appendChild(range.cloneContents());
var html = layer.innerHTML;
layer = null;
return html;
}
// selectedText - returns the current text selection or and empty string
function selectedText(editor) {
restoreRange(editor);
if (ie) return getRange(editor).text;
return getSelection(editor).toString();
}
// showMessage - alert replacement
function showMessage(editor, message, button) {
var popup = createPopup("msg", editor.options, MSG_CLASS);
popup.innerHTML = message;
showPopup(editor, popup, button);
}
// showPopup - shows a popup
function showPopup(editor, popup, button) {
var offset, left, top, $popup = $(popup);
// Determine the popup location
if (button) {
var $button = $(button);
offset = $button.offset();
left = --offset.left;
top = offset.top + $button.height();
}
else {
var $toolbar = editor.$toolbar;
offset = $toolbar.offset();
left = Math.floor(($toolbar.width() - $popup.width()) / 2) + offset.left;
top = offset.top + $toolbar.height() - 2;
}
// Position and show the popup
hidePopups();
$popup.css({ left: left, top: top })
.show();
// Assign the popup button and click event handler
if (button) {
$.data(popup, BUTTON, button);
$popup.bind(CLICK, { popup: popup }, $.proxy(popupClick, editor));
}
// Focus the first input element if any
setTimeout(function () {
$popup.find(":text,textarea").eq(0).focus().select();
}, 100);
}
// sourceMode - returns true if the textarea is showing
function sourceMode(editor) {
return editor.$area.is(":visible");
}
// updateFrame - updates the iframe with the textarea contents
function updateFrame(editor, checkForChange) {
var code = editor.$area.val(),
options = editor.options,
updateFrameCallback = options.updateFrame,
$body = $(editor.doc.body);
// Check for textarea change to avoid unnecessary firing
// of potentially heavy updateFrame callbacks.
if (updateFrameCallback) {
var sum = checksum(code);
if (checkForChange && editor.areaChecksum === sum)
return;
editor.areaChecksum = sum;
}
// Convert the textarea source code into iframe html
var html = updateFrameCallback ? updateFrameCallback(code) : code;
// Prevent script injection attacks by html encoding script tags
html = html.replace(/<(?=\/?script)/ig, "<");
// Update the iframe checksum
if (options.updateTextArea)
editor.frameChecksum = checksum(html);
// Update the iframe and trigger the change event
if (html !== $body.html()) {
$body.html(html);
$(editor).triggerHandler(CHANGE);
}
}
// updateTextArea - updates the textarea with the iframe contents
function updateTextArea(editor, checkForChange) {
var html = $(editor.doc.body).html(),
options = editor.options,
updateTextAreaCallback = options.updateTextArea,
$area = editor.$area;
// Check for iframe change to avoid unnecessary firing
// of potentially heavy updateTextArea callbacks.
if (updateTextAreaCallback) {
var sum = checksum(html);
if (checkForChange && editor.frameChecksum === sum)
return;
editor.frameChecksum = sum;
}
// Convert the iframe html into textarea source code
var code = updateTextAreaCallback ? updateTextAreaCallback(html) : html;
// Update the textarea checksum
if (options.updateFrame)
editor.areaChecksum = checksum(code);
// Update the textarea and trigger the change event
if (code !== $area.val()) {
$area.val(code);
$(editor).triggerHandler(CHANGE);
}
}
})(jQuery);
/**
* PrimeFaces Editor Widget
*/
PrimeFaces.widget.Editor = PrimeFaces.widget.DeferredWidget.extend({
init: function(cfg) {
this._super(cfg);
this.jqInput = $(this.jqId + '_input');
this.renderDeferred();
},
_render: function() {
this.editor = this.jqInput.cleditor(this.cfg)[0];
if(this.cfg.disabled) {
this.disable();
}
if(this.cfg.invalid) {
this.invalidate();
}
if(this.cfg.change) {
this.editor.change(this.cfg.change);
}
if(this.cfg.maxlength) {
this.bindMaxlength();
}
this.jq.css('visibility', '');
},
bindMaxlength: function() {
var $this = this,
frameDoc = this.editor.$frame[0].contentWindow.document;
$(frameDoc).bind('keydown.editor', function(event){
$this.editor.updateTextArea();
var text = $this.editor.$area.val();
if(text.length >= $this.cfg.maxlength &&
event.which != 8 && // back
event.which != 46 && // cancel
event.which != 37 && // left
event.which != 38 && // up
event.which != 39 && // right
event.which != 16 && // shift
event.which != 20 && // caps lock
event.which != 91 && // os special
event.which != 18 // alt
) {
$this.editor.$area.val(text.substr(0, $this.cfg.maxlength));
return false;
}
else{
$this.editor.updateTextArea();
return true;
}
});
},
saveHTML: function() {
this.editor.updateTextArea();
},
clear: function() {
this.editor.clear();
},
enable: function() {
this.editor.disable(false);
},
disable: function() {
this.editor.disable(true);
},
invalidate: function() {
this.jq.children('div.ui-editor').addClass('ui-state-error');
},
focus: function() {
this.editor.focus();
},
selectAll: function() {
this.editor.select();
},
getSelectedHTML: function() {
return this.editor.selectedHTML();
},
getSelectedText: function() {
return this.editor.selectedText();
}
});
© 2015 - 2024 Weber Informatics LLC | Privacy Policy