/*! * Aloha Editor * Author & Copyright (c) 2010 Gentics Software GmbH * aloha-sales@gentics.com * Licensed unter the terms of http://www.aloha-editor.com/license.html */ define( ['aloha', 'aloha/jquery', 'aloha/contenthandlermanager'], function(Aloha, jQuery, ContentHandlerManager) { var GENTICS = window.GENTICS; /** * Register the generic content handler */ var GenericContentHandler = ContentHandlerManager.createHandler({ /** * Handle the pasting. Remove all unwanted stuff. * @param content */ handleContent: function( content ) { if ( typeof content === 'string' ){ content = jQuery( '
' + content + '
' ); } else if ( content instanceof jQuery ) { content = jQuery( '
' ).append(content); } // If we find an aloha-block inside the pasted content, // we do not modify the pasted stuff, as it most probably // comes from Aloha and not from other sources, and does // not need to be cleaned up. if (content.find('.aloha-block').length > 0) { return; } // clean lists this.cleanLists(content); // transform tables this.transformTables(content); // remove comments this.removeComments(content); // unwrap font and span tags this.unwrapTags(content); // remove styles this.removeStyles(content); // remove namespaced elements this.removeNamespacedElements(content); // transform formattings this.transformFormattings(content); // transform links //this.transformLinks(content); return content.html(); }, /** * Clean lists: The only allowed children of ol or ul elements are li's. Everything else will be removed * @param content */ cleanLists: function(content) { content.find('ul,ol').each(function() { var $list = jQuery(this); $list.contents(':not(li,ul,ol)').each(function() { jQuery(this).remove(); }); // for all li's, trim the text contents $list.children('li').each(function() { var $li = jQuery(this); $li.contents().each(function() { if (this.nodeType === 3) { this.data = jQuery.trim(this.data); } }); }); }); }, /** * Transform tables which were pasted * @param content */ transformTables: function(content) { // remove border, cellspacing, cellpadding from all tables // @todo what about width, height? content.find('table').each(function() { jQuery(this).removeAttr('border').removeAttr('cellspacing').removeAttr('cellpadding'); }); // remove unwanted attributes and cleanup single empty p-tags content.find('td').each(function() { // remove width, height and valign from all table cells jQuery(this).removeAttr('width').removeAttr('height').removeAttr('valign'); if ( this.innerHTML.replace(/[\s\xA0]+/g,'') === '


' ) { this.innerHTML = ' '; } if ( jQuery(this).find('p').length == 1) { jQuery(this).find('p').contents().unwrap(); } }); // remove unwanted attributes from tr also? (tested with paste from open/libre office) // @todo or do this all via sanitize.js content.find('tr').each(function() { // remove width, height and valign from all table cells jQuery(this).removeAttr('width').removeAttr('height').removeAttr('valign'); }); // completely colgroup tags // @TODO should we remove colgroup? use sanitize for that? content.find('colgroup').remove(); }, /** * Transform formattings * @param content */ transformFormattings: function( content ) { // find all formattings we will transform content.find('strong,em,s,u').each(function() { if (this.nodeName.toLowerCase() == 'strong') { // transform strong to b Aloha.Markup.transformDomObject(jQuery(this), 'b'); } else if (this.nodeName.toLowerCase() == 'em') { // transform em to i Aloha.Markup.transformDomObject(jQuery(this), 'i'); } else if (this.nodeName.toLowerCase() == 's') { // transform s to del Aloha.Markup.transformDomObject(jQuery(this), 'del'); } else if (this.nodeName.toLowerCase() == 'u') { // transform u? jQuery(this).contents().unwrap(); } }); }, /** * Transform links * @param content */ transformLinks: function( content ) { // find all links and remove the links without href (will be destination anchors from word table of contents) // aloha is not supporting anchors at the moment -- maybe rewrite anchors in headings to "invisible" // in the test document there are anchors for whole paragraphs --> the whole P appear as link content.find('a').each(function() { if ( typeof jQuery(this).attr('href') === 'undefined' ) { jQuery(this).contents().unwrap(); } }); }, /** * Remove all comments * @param content */ removeComments: function( content ) { var that = this; // ok, remove all comments content.contents().each(function() { if (this.nodeType == 8) { jQuery(this).remove(); } else { // do recursion that.removeComments(jQuery(this)); } }); }, /** * Remove some unwanted tags from content pasted * @param content */ unwrapTags: function( content ) { var that = this; content.children('span,font,div').filter(function() { return this.contentEditable != 'false'; }).each(function() { if (this.nodeName == 'DIV') { // safari and chrome cleanup for plain text paste with working linebreaks if (this.innerHTML == '
') { jQuery(this).contents().unwrap(); } else { jQuery( Aloha.Markup.transformDomObject(jQuery(this), 'p').append('
') ).contents().unwrap(); } } else { jQuery(this).contents().unwrap(); } that.unwrapTags(jQuery(this)); }); }, /** * Remove styles * @param content */ removeStyles: function( content ) { var that = this; // completely remove style tags content.children('style').filter(function() { return this.contentEditable != 'false'; }).remove(); // remove style attributes and classes content.children().filter(function() { return this.contentEditable != 'false'; }).each(function() { jQuery(this).removeAttr('style').removeClass(); that.removeStyles(jQuery(this)); }); }, /** * Remove all elements which are in different namespaces * @param content */ removeNamespacedElements: function( content ) { // get all elements content.find('*').each(function() { // try to determine the namespace prefix ('prefix' works for W3C // compliant browsers, 'scopeName' for IE) var nsPrefix = this.prefix ? this.prefix : (this.scopeName ? this.scopeName : undefined); // when the prefix is set (and different from 'HTML'), we remove the // element if ((nsPrefix && nsPrefix != 'HTML') || this.nodeName.indexOf(':') >= 0 ) { var $this = jQuery(this), $contents = $this.contents(); if ($contents.length) { // the element has contents, so unwrap the contents $contents.unwrap(); } else { // the element is empty, so remove it $this.remove(); } } }); } }); return GenericContentHandler; });