From: Stanislas Rolland Date: Wed, 10 Nov 2010 06:29:20 +0000 (+0000) Subject: Added feature #8349: htmlArea RTE: Clean paste feature with three options X-Git-Tag: TYPO3_4-5-0beta1~148 X-Git-Url: http://git.typo3.org/Packages/TYPO3.CMS.git/commitdiff_plain/cffd2a26dc24643615aebec13e4b2a4836e4cf33?hp=17f560e0b50f6ff8992095d3d3cf418c65aa6275 Added feature #8349: htmlArea RTE: Clean paste feature with three options git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@9325 709f56b5-9817-0410-a4d7-c38de5d9e867 --- diff --git a/ChangeLog b/ChangeLog index 705687904e7..f9981362a90 100755 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-11-10 Stanislas Rolland + + * Added feature #8349: htmlArea RTE: Clean paste feature with three options + 2010-11-09 Jeff Segars * Fixed bug #16262: Link browser shows wrong title for pages and tt_content elements (Thanks to Reinhard Führicht) diff --git a/typo3/sysext/rtehtmlarea/ChangeLog b/typo3/sysext/rtehtmlarea/ChangeLog index bb0ec43b818..2b04c37c7ab 100644 --- a/typo3/sysext/rtehtmlarea/ChangeLog +++ b/typo3/sysext/rtehtmlarea/ChangeLog @@ -1,3 +1,7 @@ +2010-11-10 Stanislas Rolland + + * Added feature #8349: htmlArea RTE: Clean paste feature with three options + 2010-11-08 Stanislas Rolland * Fixed bug #16245: htmlArea RTE: When inserting link with IE8, trailing line break is also linked diff --git a/typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php b/typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php index 11fa67a655e..2651d10a7dd 100644 --- a/typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php +++ b/typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php @@ -568,7 +568,7 @@ class tx_rtehtmlarea_base extends t3lib_rteapi { bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, lefttoright, righttoleft, language, showlanguagemarks, bar, textcolor, bgcolor, textindicator, bar, emoticon, insertcharacter, link, unlink, image, table,' . (($this->thisConfig['hideTableOperationsInToolbar'] && is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['toggleborders.']) && $this->thisConfig['buttons.']['toggleborders.']['keepInToolbar']) ? ' toggleborders,': '') . ' user, acronym, bar, findreplace, spellcheck, - bar, chMode, inserttag, removeformat, bar, copy, cut, paste, pasteastext, bar, undo, redo, bar, showhelp, about, linebreak, + bar, chMode, inserttag, removeformat, bar, copy, cut, paste, pastetoggle, pastebehaviour, bar, undo, redo, bar, showhelp, about, linebreak, ' . ($this->thisConfig['hideTableOperationsInToolbar'] ? '': 'bar, toggleborders,') . ' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar, columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar, cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge'; diff --git a/typo3/sysext/rtehtmlarea/ext_emconf.php b/typo3/sysext/rtehtmlarea/ext_emconf.php index ecbfff6aa65..fcbd4736581 100644 --- a/typo3/sysext/rtehtmlarea/ext_emconf.php +++ b/typo3/sysext/rtehtmlarea/ext_emconf.php @@ -48,6 +48,7 @@ $EM_CONF[$_EXTKEY] = array( ), 'suggests' => array( 'rtehtmlarea_api_manual' => '', + 'setup' => '', ), ), 'suggests' => array( diff --git a/typo3/sysext/rtehtmlarea/ext_localconf.php b/typo3/sysext/rtehtmlarea/ext_localconf.php index 2bfb0454942..e639ca32809 100644 --- a/typo3/sysext/rtehtmlarea/ext_localconf.php +++ b/typo3/sysext/rtehtmlarea/ext_localconf.php @@ -240,6 +240,7 @@ $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins']['PlainText'] = array(); $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins']['PlainText']['objectReference'] = 'EXT:'.$_EXTKEY.'/extensions/PlainText/class.tx_rtehtmlarea_plaintext.php:&tx_rtehtmlarea_plaintext'; $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins']['PlainText']['addIconsToSkin'] = 0; $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins']['PlainText']['disableInFE'] = 0; +$TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins']['PlainText']['contextHelpFile'] = 'EXT:' . $_EXTKEY . '/extensions/PlainText/locallang_csh.xml'; $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins']['DefaultClean'] = array(); $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins']['DefaultClean']['objectReference'] = 'EXT:'.$_EXTKEY.'/extensions/DefaultClean/class.tx_rtehtmlarea_defaultclean.php:&tx_rtehtmlarea_defaultclean'; $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins']['TYPO3HtmlParser'] = array(); diff --git a/typo3/sysext/rtehtmlarea/ext_tables.php b/typo3/sysext/rtehtmlarea/ext_tables.php index bdb8db07fe8..62d870b7cf3 100644 --- a/typo3/sysext/rtehtmlarea/ext_tables.php +++ b/typo3/sysext/rtehtmlarea/ext_tables.php @@ -4,6 +4,7 @@ if (!defined ('TYPO3_MODE')) die ('Access denied.'); // Add static template for Click-enlarge rendering t3lib_extMgm::addStaticFile($_EXTKEY,'static/clickenlarge/','Clickenlarge Rendering'); + // Add acronyms table $TCA['tx_rtehtmlarea_acronym'] = Array ( 'ctrl' => Array ( 'title' => 'LLL:EXT:rtehtmlarea/locallang_db.xml:tx_rtehtmlarea_acronym', @@ -25,7 +26,27 @@ if (!defined ('TYPO3_MODE')) die ('Access denied.'); // Add contextual help files foreach ($TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins'] as $pluginName => $config) { if ($config['contextHelpFile']) { - t3lib_extMgm::addLLrefForTCAdescr('xEXT_' . $_EXTKEY . '_' . $pluginName, $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins']['RemoveFormat']['contextHelpFile']); + t3lib_extMgm::addLLrefForTCAdescr('xEXT_' . $_EXTKEY . '_' . $pluginName, $TYPO3_CONF_VARS['EXTCONF'][$_EXTKEY]['plugins'][$pluginName]['contextHelpFile']); } } + + // Extend TYPO3 User Settings Configuration +if (TYPO3_MODE === 'BE' && t3lib_extMgm::isLoaded('setup') && is_array($GLOBALS['TYPO3_USER_SETTINGS'])) { + $GLOBALS['TYPO3_USER_SETTINGS']['columns'] = array_merge( + $GLOBALS['TYPO3_USER_SETTINGS']['columns'], + array( + 'rteCleanPasteBehaviour' => array( + 'type' => 'select', + 'label' => 'LLL:EXT:rtehtmlarea/htmlarea/plugins/PlainText/locallang.xml:rteCleanPasteBehaviour', + 'items' => array( + 'plainText' => 'LLL:EXT:rtehtmlarea/htmlarea/plugins/PlainText/locallang.xml:plainText', + 'pasteStructure' => 'LLL:EXT:rtehtmlarea/htmlarea/plugins/PlainText/locallang.xml:pasteStructure', + 'pasteFormat' => 'LLL:EXT:rtehtmlarea/htmlarea/plugins/PlainText/locallang.xml:pasteFormat', + ), + 'csh' => 'xEXT_rtehtmlarea_PlainText:behaviour', + ), + ) + ); + $GLOBALS['TYPO3_USER_SETTINGS']['showitem'] .= ',--div--;LLL:EXT:rtehtmlarea/locallang.xml:rteSettings,rteResize,rteMaxHeight,rteCleanPasteBehaviour'; +} ?> \ No newline at end of file diff --git a/typo3/sysext/rtehtmlarea/extensions/PlainText/class.tx_rtehtmlarea_plaintext.php b/typo3/sysext/rtehtmlarea/extensions/PlainText/class.tx_rtehtmlarea_plaintext.php index 747d3b76abf..9e7fc90c9bb 100644 --- a/typo3/sysext/rtehtmlarea/extensions/PlainText/class.tx_rtehtmlarea_plaintext.php +++ b/typo3/sysext/rtehtmlarea/extensions/PlainText/class.tx_rtehtmlarea_plaintext.php @@ -38,12 +38,13 @@ class tx_rtehtmlarea_plaintext extends tx_rtehtmlarea_api { protected $thisConfig; // Reference to RTE PageTSConfig protected $toolbar; // Reference to RTE toolbar array protected $LOCAL_LANG; // Frontend language array - protected $pluginButtons = 'pasteastext'; + protected $pluginButtons = 'pastetoggle,pastebehaviour'; protected $convertToolbarForHtmlAreaArray = array ( - 'pasteastext' => 'PlainText', + 'pastetoggle' => 'PasteToggle', + 'pastebehaviour' => 'PasteBehaviour', ); - public function main($parentObject) { - // Opera has no onPaste event to hook on + public function main ($parentObject) { + // Opera has no onPaste event to handle return parent::main($parentObject) && $this->htmlAreaRTE->client['browser'] != 'opera'; } /** @@ -59,8 +60,37 @@ class tx_rtehtmlarea_plaintext extends tx_rtehtmlarea_api { */ public function buildJavascriptConfiguration($RTEcounter) { $registerRTEinJavascriptString = ''; + $button = 'pastebehaviour'; + // Get current TYPO3 User Setting, if available + if (TYPO3_MODE === 'BE' && t3lib_extMgm::isLoaded('setup') && is_array($GLOBALS['TYPO3_USER_SETTINGS']) && is_object($GLOBALS['BE_USER'])) { + if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][$button.'.'])) { + $registerRTEinJavascriptString .= ' + RTEarea[' . $RTEcounter . '].buttons.' . $button . ' = new Object();'; + } + $registerRTEinJavascriptString .= ' + RTEarea[' . $RTEcounter . '].buttons.' . $button . '.current = "' . (isset($GLOBALS['BE_USER']->uc['rteCleanPasteBehaviour']) ? $GLOBALS['BE_USER']->uc['rteCleanPasteBehaviour'] : 'plainText') . '";'; + } return $registerRTEinJavascriptString; } + /** + * Return an updated array of toolbar enabled buttons + * + * @param array $show: array of toolbar elements that will be enabled, unless modified here + * + * @return array toolbar button array, possibly updated + */ + public function applyToolbarConstraints ($show) { + $removeButtons = array(); + // Remove pastebehaviour button if pastetoggle is not configured + if (!in_array('pastetoggle', $show)) { + $removeButtons[] = 'pastebehaviour'; + } + // Remove pastebehaviour button if TYPO3 User Settings are available + if (TYPO3_MODE === 'BE' && t3lib_extMgm::isLoaded('setup') && is_array($GLOBALS['TYPO3_USER_SETTINGS']) && is_object($GLOBALS['BE_USER'])) { + $removeButtons[] = 'pastebehaviour'; + } + return array_diff($show, $removeButtons); + } } if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/extensions/PlainText/class.tx_rtehtmlarea_plaintext.php']) { include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/extensions/PlainText/class.tx_rtehtmlarea_plaintext.php']); diff --git a/typo3/sysext/rtehtmlarea/extensions/PlainText/locallang_csh.xml b/typo3/sysext/rtehtmlarea/extensions/PlainText/locallang_csh.xml new file mode 100644 index 00000000000..7789fa6e160 --- /dev/null +++ b/typo3/sysext/rtehtmlarea/extensions/PlainText/locallang_csh.xml @@ -0,0 +1,56 @@ + + + + CSH for Plain Text Extension of htmlArea RTE + CSH + xEXT_rtehtmlarea_PlainText + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/htmlarea.css b/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/htmlarea.css index 45a0f97a5dd..6a62b0cf374 100644 --- a/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/htmlarea.css +++ b/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/htmlarea.css @@ -1,6 +1,10 @@ /* Selectors for the PlainText extension of htmlArea RTE */ /* TYPO3 SVN ID: $Id: htmlarea.css 8281 2010-07-26 23:18:50Z stan $ */ -.htmlarea-action-paste-as-plain-text { - background-image: url('images/paste-as-plain-text.gif') !important; +.htmlarea-action-paste-toggle { + background-image: url('images/paste-toggle.gif') !important; + background-position: 0 0 !important; +} +.htmlarea-action-paste-behaviour { + background-image: url('images/paste-behaviour.gif') !important; background-position: 0 0 !important; } diff --git a/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/images/paste-as-plain-text.gif b/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/images/paste-as-plain-text.gif deleted file mode 100644 index 881378e676f..00000000000 Binary files a/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/images/paste-as-plain-text.gif and /dev/null differ diff --git a/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/images/paste-behaviour.gif b/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/images/paste-behaviour.gif new file mode 100644 index 00000000000..881378e676f Binary files /dev/null and b/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/images/paste-behaviour.gif differ diff --git a/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/images/paste-toggle.gif b/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/images/paste-toggle.gif new file mode 100644 index 00000000000..e6f1c2d1181 Binary files /dev/null and b/typo3/sysext/rtehtmlarea/extensions/PlainText/skin/images/paste-toggle.gif differ diff --git a/typo3/sysext/rtehtmlarea/htmlarea/plugins/PlainText/locallang.xml b/typo3/sysext/rtehtmlarea/htmlarea/plugins/PlainText/locallang.xml index c706bb6919a..acef9f92576 100644 --- a/typo3/sysext/rtehtmlarea/htmlarea/plugins/PlainText/locallang.xml +++ b/typo3/sysext/rtehtmlarea/htmlarea/plugins/PlainText/locallang.xml @@ -6,9 +6,21 @@ - - + + + + + + + + + + + + + + diff --git a/typo3/sysext/rtehtmlarea/htmlarea/plugins/PlainText/plain-text.js b/typo3/sysext/rtehtmlarea/htmlarea/plugins/PlainText/plain-text.js index b9b2986ba12..c46fae2e6c4 100644 --- a/typo3/sysext/rtehtmlarea/htmlarea/plugins/PlainText/plain-text.js +++ b/typo3/sysext/rtehtmlarea/htmlarea/plugins/PlainText/plain-text.js @@ -37,6 +37,7 @@ HTMLArea.PlainText = HTMLArea.Plugin.extend({ * This function gets called by the class constructor */ configurePlugin: function(editor) { + this.buttonsConfiguration = this.editorConfiguration.buttons; /* * Registering plugin "About" information */ @@ -45,43 +46,86 @@ HTMLArea.PlainText = HTMLArea.Plugin.extend({ developer : 'Stanislas Rolland', developerUrl : 'http://www.sjbr.ca/', copyrightOwner : 'Stanislas Rolland', - sponsor : 'SJBR', - sponsorUrl : 'http://www.sjbr.ca/', + sponsor : 'Otto van Bruggen', + sponsorUrl : 'http://www.webspinnerij.nl', license : 'GPL' }; this.registerPluginInformation(pluginInformation); /* - * Registering the button + * Registering the buttons */ - var buttonId = 'PlainText'; - var buttonConfiguration = { - id : buttonId, - tooltip : this.localize(buttonId + 'Tooltip'), - iconCls : 'htmlarea-action-paste-as-plain-text', - action : 'onButtonPress' - }; - this.registerButton(buttonConfiguration); + Ext.iterate(this.buttonList, function (buttonId, buttonConf) { + var buttonConfiguration = { + id : buttonId, + tooltip : this.localize(buttonId + 'Tooltip'), + iconCls : 'htmlarea-action-' + buttonConf[1], + action : 'onButtonPress', + dialog : buttonConf[2] + }; + this.registerButton(buttonConfiguration); + }, this); return true; }, + /* + * The list of buttons added by this plugin + */ + buttonList: { + PasteToggle: ['pastetoggle', 'paste-toggle', false], + PasteBehaviour: ['pastebehaviour', 'paste-behaviour', true] + }, + /* + * Cleaner configurations + */ + cleanerConfig: { + pasteStructure: { + keepTags: /^(a|p|h[0-6]|pre|address|blockquote|div|hr|br|table|thead|tbody|tfoot|caption|tr|th|td|ul|ol|dl|li|dt|dd)$/i, + removeAttributes: /^(id|on*|style|class|className|lang|align|valign|bgcolor|color|border|face|.*:.*)$/i + }, + pasteFormat: { + keepTags: /^(a|p|h[0-6]|pre|address|blockquote|div|hr|br|table|thead|tbody|tfoot|caption|tr|th|td|ul|ol|dl|li|dt|dd|b|bdo|big|cite|code|del|dfn|em|i|ins|kbd|label|q|samp|small|strike|strong|sub|sup|tt|u|var)$/i, + removeAttributes: /^(id|on*|style|class|className|lang|align|valign|bgcolor|color|border|face|.*:.*)$/i + } + }, /* * This function gets called when the plugin is generated */ onGenerate: function () { - // Initialize state of toggle - this.togglePasteAsPlainText(false); + // Create cleaners + if (this.buttonsConfiguration && this.buttonsConfiguration['pastebehaviour']) { + this.pasteBehaviourConfiguration = this.buttonsConfiguration['pastebehaviour']; + } + this.cleaners = {}; + Ext.iterate(this.cleanerConfig, function (behaviour) { + if (this.pasteBehaviourConfiguration && this.pasteBehaviourConfiguration[behaviour]) { + if (this.pasteBehaviourConfiguration[behaviour].keepTags) { + this.cleanerConfig[behaviour].keepTags = new RegExp( '^(' + this.pasteBehaviourConfiguration[behaviour].keepTags.split(',').join('|') + ')$', 'i'); + } + if (this.pasteBehaviourConfiguration[behaviour].removeAttributes) { + this.cleanerConfig[behaviour].removeAttributes = new RegExp( '^(' + this.pasteBehaviourConfiguration[behaviour].removeAttributes.split(',').join('|') + ')$', 'i'); + } + } + this.cleaners[behaviour] = new HTMLArea.DOM.Walker(this.cleanerConfig[behaviour]); + }, this); + // Initial behaviour + this.currentBehaviour = 'plainText'; + // May be set in TYPO3 User Settings + if (this.buttonsConfiguration && this.buttonsConfiguration['pastebehaviour'] && this.buttonsConfiguration['pastebehaviour']['current']) { + this.currentBehaviour = this.buttonsConfiguration['pastebehaviour']['current']; + } // Start monitoring paste events this.editor.iframe.mon(Ext.get(Ext.isIE ? this.editor.document.body : this.editor.document.documentElement), 'paste', this.onPaste, this); }, /* - * This function toggles the state of Paste as Plain text + * This function toggles the state of a button * - * @param boolean state: if defined, the specified state to set + * @param string buttonId: id of button to be toggled * * @return void */ - togglePasteAsPlainText: function (state) { + toggleButton: function (buttonId) { // Set new state - this.pasteAsPlainTextActive = (typeof(state) != 'undefined') ? state : !this.pasteAsPlainTextActive; + var button = this.getButton(buttonId); + button.setInactive(!button.inactive); }, /* * This function gets called when a button was pressed. @@ -95,97 +139,342 @@ HTMLArea.PlainText = HTMLArea.Plugin.extend({ // Could be a button or its hotkey var buttonId = this.translateHotKey(id); buttonId = buttonId ? buttonId : id; - this.togglePasteAsPlainText(); + switch (buttonId) { + case 'PasteBehaviour': + // Open dialogue window + this.openDialogue( + buttonId, + 'PasteBehaviourTooltip', + this.getWindowDimensions( + { + width: 260, + height:260 + }, + buttonId + ) + ); + break; + case 'PasteToggle': + this.toggleButton(buttonId); + this.editor.focus(); + break; + } return false; }, /* - * This function gets called when the toolbar is updated + * Open the dialogue window + * + * @param string buttonId: the button id + * @param string title: the window title + * @param object dimensions: the opening dimensions of the window * * @return void */ - onUpdateToolbar: function (button, mode, selectionEmpty, ancestors) { - if (this.getEditorMode() === 'wysiwyg' && this.editor.isEditable()) { - button.setInactive(!this.pasteAsPlainTextActive); - } + openDialogue: function (buttonId, title, dimensions) { + this.dialog = new Ext.Window({ + title: this.localize(title), + cls: 'htmlarea-window', + border: false, + width: dimensions.width, + height: 'auto', + // As of ExtJS 3.1, JS error with IE when the window is resizable + resizable: !Ext.isIE, + iconCls: this.getButton(buttonId).iconCls, + listeners: { + close: { + fn: this.onClose, + scope: this + } + }, + items: [{ + xtype: 'fieldset', + defaultType: 'radio', + title: this.getHelpTip('behaviour', title), + labelWidth: 170, + defaults: { + labelSeparator: '', + name: buttonId + }, + items: [{ + itemId: 'plainText', + fieldLabel: this.getHelpTip('plainText', 'plainText'), + checked: (this.currentBehaviour === 'plainText') + },{ + itemId: 'pasteStructure', + fieldLabel: this.getHelpTip('pasteStructure', 'pasteStructure'), + checked: (this.currentBehaviour === 'pasteStructure') + },{ + itemId: 'pasteFormat', + fieldLabel: this.getHelpTip('pasteFormat', 'pasteFormat'), + checked: (this.currentBehaviour === 'pasteFormat') + } + ] + } + ], + buttons: [ + this.buildButtonConfig('OK', this.onOK) + ] + }); + this.show(); + }, + /* + * Handler invoked when the OK button of the Clean Paste Behaviour window is pressed + */ + onOK: function () { + var fields = [ + 'plainText', + 'pasteStructure', + 'pasteFormat' + ]; + Ext.each(fields, function (field) { + if (this.dialog.find('itemId', field)[0].getValue()) { + this.currentBehaviour = field; + return false; + } + }, this); + this.close(); + return false; }, /* * Handler for paste event + * + * @param object event: the paste event + * + * @return boolean false, if the event was handled, true otherwise */ onPaste: function (event) { - if (this.pasteAsPlainTextActive) { - this.grabClipboardText(event); - if (this.clipboardText) { - // Direct access to the clipboard text was possible - this.pasteAsPlainText(); - } else { - // Get the text content from the hidden section - // after the paste operation is completed - this.getClipboardText.defer(10, this); + if (!this.getButton('PasteToggle').inactive) { + switch (this.currentBehaviour) { + case 'plainText': + // Only IE and WebKit will allow access to the clipboard content, in plain text only however + if (Ext.isIE || Ext.isWebKit) { + var clipboardText = this.grabClipboardText(event); + if (clipboardText) { + this.editor.insertHTML(clipboardText); + } + return !this.clipboardText; + } + case 'pasteStructure': + case 'pasteFormat': + if (Ext.isIE) { + // Save the current selection + this.editor.focus(); + this.bookmark = this.editor.getBookmark(this.editor._createRange(this.editor._getSelection())); + // Show the pasting pad + this.openPastingPad( + 'PasteToggle', + this.currentBehaviour, + this.getWindowDimensions( + { + width: 550, + height: 550 + }, + 'PasteToggle' + )); + event.browserEvent.returnValue = false; + return false; + } else { + // Redirect the paste operation to a hidden section + this.redirectPaste(); + // Process the content of the hidden section after the paste operation is completed + // WebKit seems to be pondering a very long time over what is happenning here... + this.processPastedContent.defer(Ext.isWebKit ? 500 : 50, this); + } + break; + default: + break; } - return !this.clipboardText; } + return true; }, /* - * Grab the text content directly from the clipboard or - * redirect the paste operation towards a hidden section + * Grab the text content directly from the clipboard + * If successful, stop the paste event * * @param object event: the paste event * - * @return void + * @return string clipboard content, in plain text, if access was granted */ grabClipboardText: function (event) { - this.clipboardText = null; - // Check if browser supports direct plaintext access (IE and WebKit) + var clipboardText = ''; + // Grab the text content if (window.clipboardData || event.browserEvent.clipboardData || event.browserEvent.dataTransfer) { - // Grab the text content - this.clipboardText = (window.clipboardData || event.browserEvent.clipboardData || event.browserEvent.dataTransfer).getData('Text'); - if (this.clipboardText) { - // Stop the event - event.stopEvent(); - } else { - TYPO3.Dialog.InformationDialog({ - title: this.localize('Paste-as-Plain-Text'), - msg: this.localize('Access-to-clipboard-denied') - }); - } + clipboardText = (window.clipboardData || event.browserEvent.clipboardData || event.browserEvent.dataTransfer).getData('text'); + } + if (clipboardText) { + // Stop the event + event.stopEvent(); } else { - // When direct access was not possible - // Save the current selection - var selection = this.editor._getSelection(); - var range = this.editor._createRange(selection); - this.bookmark = this.editor.getBookmark(range); - // Create and append hidden section - this.hiddenSection = this.editor.document.createElement('div'); - this.hiddenSection.id = this.editorId + 'htmlarea-paste-hidden-section'; - this.hiddenSection.style.position = 'absolute'; - this.hiddenSection.style.left = -10000; - this.hiddenSection.style.top = this.editor.document.body.scrollTop; - this.hiddenSection.style.overflow = 'hidden'; - this.hiddenSection = this.editor.document.body.appendChild(this.hiddenSection); - // Move the selection to the hidden section and - // let the browser paste into the hidden section - this.editor.selectNodeContents(this.hiddenSection, true); + // If the user denied access to the clipboard, let the browser paste without intervention + TYPO3.Dialog.InformationDialog({ + title: this.localize('Paste-as-Plain-Text'), + msg: this.localize('Access-to-clipboard-denied') + }); + } + return clipboardText; + }, + /* + * Redirect the paste operation towards a hidden section + * + * @return void + */ + redirectPaste: function () { + this.editor.focus(); + // Save the current selection + this.bookmark = this.editor.getBookmark(this.editor._createRange(this.editor._getSelection())); + // Create and append hidden section + var hiddenSection = this.editor.document.createElement('div'); + HTMLArea.DOM.addClass(hiddenSection, 'htmlarea-paste-hidden-section'); + hiddenSection.setAttribute('style', 'position: absolute; left: -10000px; top: ' + this.editor.document.body.scrollTop + 'px; overflow: hidden;'); + hiddenSection = this.editor.document.body.appendChild(hiddenSection); + if (Ext.isWebKit) { + hiddenSection.innerHTML = ' '; } + // Move the selection to the hidden section and let the browser paste into the hidden section + this.editor.selectNodeContents(hiddenSection); }, /* - * If the paste operation was redirected towards a hidden section - * get the text content from the section + * Process the pasted content that was redirected towards a hidden section + * and insert it at the original selection * * @return void */ - getClipboardText: function () { - // Get the text content - this.clipboardText = this.hiddenSection.textContent; - // Delete the hidden section - HTMLArea.removeFromParent(this.hiddenSection); + processPastedContent: function () { + this.editor.focus(); + // Get the hidden section + var divs = this.editor.document.getElementsByClassName('htmlarea-paste-hidden-section'); + var hiddenSection = divs[0]; + // Delete any other hidden sections + for (var i = divs.length; --i >= 1;) { + HTMLArea.removeFromParent(divs[i]); + } + var content = ''; + switch (this.currentBehaviour) { + case 'plainText': + // Get plain text content + content = hiddenSection.textContent; + break; + case 'pasteStructure': + case 'pasteFormat': + // Get clean content + content = this.cleaners[this.currentBehaviour].render(hiddenSection, false); + break; + } + // Remove the hidden section from the document + HTMLArea.removeFromParent(hiddenSection); // Restore the selection this.editor.selectRange(this.editor.moveToBookmark(this.bookmark)); - this.pasteAsPlainText(); + // Insert the cleaned content + if (content) { + this.editor.execCommand('insertHTML', false, content); + } + }, + /* + * Open the pasting pad window (for IE) + * + * @param string buttonId: the button id + * @param string title: the window title + * @param object dimensions: the opening dimensions of the window + * + * @return void + */ + openPastingPad: function (buttonId, title, dimensions) { + this.dialog = new Ext.Window({ + title: this.getHelpTip(title, title), + cls: 'htmlarea-window', + bodyCssClass: 'pasting-pad', + border: false, + width: dimensions.width, + height: 'auto', + // As of ExtJS 3.1, JS error with IE when the window is resizable + resizable: !Ext.isIE, + iconCls: this.getButton(buttonId).iconCls, + listeners: { + afterrender: { + // The document will not be immediately ready + fn: function (event) { this.onPastingPadAfterRender.defer(100, this, [event]); }, + scope: this + }, + close: { + fn: this.onClose, + scope: this + } + }, + items: [{ + xtype: 'tbtext', + text: this.getHelpTip('pasteInPastingPad', 'pasteInPastingPad'), + style: { + marginBottom: '5px' + } + },{ + // The iframe + xtype: 'box', + itemId: 'pasting-pad-iframe', + autoEl: { + name: 'contentframe', + tag: 'iframe', + cls: 'contentframe', + src: Ext.isGecko ? 'javascript:void(0);' : HTMLArea.editorUrl + 'popups/blank.html' + } + } + ], + buttons: [ + this.buildButtonConfig('OK', this.onPastingPadOK), + this.buildButtonConfig('Cancel', this.onCancel) + ] + }); + this.show(); + }, + /* + * Handler invoked after the pasting pad iframe has been rendered + */ + onPastingPadAfterRender: function () { + var iframe = this.dialog.getComponent('pasting-pad-iframe').getEl().dom; + var pastingPadDocument = iframe.contentWindow ? iframe.contentWindow.document : iframe.contentDocument; + this.pastingPadBody = pastingPadDocument.body; + this.pastingPadBody.contentEditable = true; + // Start monitoring paste events + this.dialog.mon(Ext.get(this.pastingPadBody), 'paste', this.onPastingPadPaste, this); + this.pastingPadBody.focus(); + }, + /* + * Handler invoked when content is pasted into the pasting pad + */ + onPastingPadPaste: function (event) { + // Let the paste operation complete before cleaning + this.cleanPastingPadContents.defer(50, this); }, /* - * Paste as plain text + * Clean the contents of the pasting pad */ - pasteAsPlainText: function () { - this.editor.insertHTML(this.clipboardText); + cleanPastingPadContents: function () { + this.pastingPadBody.innerHTML = this.cleaners[this.currentBehaviour].render(this.pastingPadBody, false); + this.pastingPadBody.focus(); + }, + /* + * Handler invoked when the OK button of the Pasting Pad window is pressed + */ + onPastingPadOK: function () { + // Restore the selection + this.editor.focus(); + this.restoreSelection(); + // Insert the cleaned pasting pad content + this.editor.insertHTML(this.pastingPadBody.innerHTML); + this.close(); + return false; + }, + /* + * This function gets called when the toolbar is updated + */ + onUpdateToolbar: function (button, mode, selectionEmpty, ancestors) { + if (mode === 'wysiwyg' && this.editor.isEditable()) { + switch (button.itemId) { + case 'PasteToggle': + button.setTooltip({ + title: this.localize((button.inactive ? 'enable' : 'disable') + this.currentBehaviour) + }); + break; + } + } } }); diff --git a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css index d1355f65478..cc34a920bc2 100644 --- a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css +++ b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css @@ -438,84 +438,85 @@ body.ext-ie6 .htmlarea-context-menu .x-menu-item-icon { background-position: 0 -15px; } /* Action icon selectors for toolbar, context menu and window headers */ -.htmlarea-action-abbreviation-edit { background-position: 0 0 !important; } -.htmlarea-action-bidi-override { background-position: 0 -58px !important; } -.htmlarea-action-big { background-position: 0 -116px !important; } -.htmlarea-action-blockquote { background-position: 0 -174px !important; } -.htmlarea-action-bold { background-position: 0 -232px !important; } -.htmlarea-action-cell-delete { background-position: 0 -290px !important; } -.htmlarea-action-cell-edit-properties { background-position: 0 -348px !important; } -.htmlarea-action-cell-insert-after { background-position: 0 -406px !important; } -.htmlarea-action-cell-insert-before { background-position: 0 -464px !important; } -.htmlarea-action-cell-merge { background-position: 0 -522px !important; } -.htmlarea-action-cell-split { background-position: 0 -580px !important; } -.htmlarea-action-character-insert-from-map { background-position: 0 -638px !important; } -.htmlarea-action-citation { background-position: 0 -696px !important; } -.htmlarea-action-code { background-position: 0 -754px !important; } -.htmlarea-action-color-background { background-position: 0 -812px !important; } -.htmlarea-action-color-foreground { background-position: 0 -870px !important; } -.htmlarea-action-column-delete { background-position: 0 -928px !important; } -.htmlarea-action-column-edit-properties { background-position: 0 -986px !important; } -.htmlarea-action-column-insert-after { background-position: 0 -1044px !important; } -.htmlarea-action-column-insert-before { background-position: 0 -1102px !important; } -.htmlarea-action-column-split { background-position: 0 -1160px !important; } -.htmlarea-action-copy { background-position: 0 -1218px !important; } -.htmlarea-action-cut { background-position: 0 -1276px !important; } -.htmlarea-action-definition-list-item { background-position: 0 -1334px !important; } -.htmlarea-action-definition-list { background-position: 0 -1392px !important; } -.htmlarea-action-definition { background-position: 0 -1450px !important; } -.htmlarea-action-delete-item { background-position: 0 -1508px !important; } -.htmlarea-action-deleted-text { background-position: 0 -1566px !important; } -.htmlarea-action-editor-show-about { background-position: 0 -1624px !important; } -.htmlarea-action-editor-toggle-mode { background-position: 0 -1682px !important; } -.htmlarea-action-emphasis { background-position: 0 -1740px !important; } -.htmlarea-action-find-replace { background-position: 0 -1798px !important; } -.htmlarea-action-horizontal-rule-insert { background-position: 0 -1856px !important; } -.htmlarea-action-image-edit { background-position: 0 -1914px !important; } -.htmlarea-action-indent { background-position: 0 -1972px !important; } -.htmlarea-action-inserted-text { background-position: 0 -2030px !important; } -.htmlarea-action-italic { background-position: 0 -2088px !important; } -.htmlarea-action-justify-center { background-position: 0 -2146px !important; } -.htmlarea-action-justify-full { background-position: 0 -2204px !important; } -.htmlarea-action-justify-left { background-position: 0 -2262px !important; } -.htmlarea-action-justify-right { background-position: 0 -2320px !important; } -.htmlarea-action-keyboard { background-position: 0 -2378px !important; } -.htmlarea-action-language-marks-show { background-position: 0 -2436px !important; } -.htmlarea-action-link-edit { background-position: 0 -2494px !important; } -.htmlarea-action-mono-spaced { background-position: 0 -2552px !important; } -.htmlarea-action-ordered-list { background-position: 0 -2610px !important; } -.htmlarea-action-outdent { background-position: 0 -2668px !important; } -.htmlarea-action-paragraph-insert-after { background-position: 0 -2726px !important; } -.htmlarea-action-paragraph-insert-before { background-position: 0 -2784px !important; } -.htmlarea-action-paste-as-plain-text { background-position: 0 -2842px !important; } -.htmlarea-action-paste { background-position: 0 -2900px !important; } -.htmlarea-action-quotation { background-position: 0 -2958px !important; } -.htmlarea-action-redo { background-position: 0 -3016px !important; } -.htmlarea-action-remove-format { background-position: 0 -3074px !important; } -.htmlarea-action-row-delete { background-position: 0 -3132px !important; } -.htmlarea-action-row-edit-properties { background-position: 0 -3190px !important; } -.htmlarea-action-row-insert-above { background-position: 0 -3248px !important; } -.htmlarea-action-row-insert-under { background-position: 0 -3306px !important; } -.htmlarea-action-row-split { background-position: 0 -3364px !important; } -.htmlarea-action-sample { background-position: 0 -3422px !important; } -.htmlarea-action-small { background-position: 0 -3480px !important; } -.htmlarea-action-smiley-insert { background-position: 0 -3538px !important; } -.htmlarea-action-span { background-position: 0 -3596px !important; } -.htmlarea-action-spell-check { background-position: 0 -3654px !important; } -.htmlarea-action-strike-through { background-position: 0 -3712px !important; } -.htmlarea-action-strong { background-position: 0 -3770px !important; } -.htmlarea-action-subscript { background-position: 0 -3828px !important; } -.htmlarea-action-superscript { background-position: 0 -3886px !important; } -.htmlarea-action-table-edit-properties { background-position: 0 -3944px !important; } -.htmlarea-action-table-insert { background-position: 0 -4002px !important; } -.htmlarea-action-table-restyle { background-position: 0 -4060px !important; } -.htmlarea-action-table-show-borders { background-position: 0 -4118px !important; } -.htmlarea-action-tag-insert { background-position: 0 -4176px !important; } -.htmlarea-action-text-direction-left-to-right { background-position: 0 -4234px !important; } -.htmlarea-action-text-direction-right-to-left { background-position: 0 -4292px !important; } -.htmlarea-action-underline { background-position: 0 -4350px !important; } -.htmlarea-action-undo { background-position: 0 -4408px !important; } -.htmlarea-action-unlink { background-position: 0 -4466px !important; } -.htmlarea-action-unordered-list { background-position: 0 -4524px !important; } -.htmlarea-action-user-element-edit { background-position: 0 -4582px !important; } -.htmlarea-action-variable { background-position: 0 -4640px !important; } +.htmlarea-action-abbreviation-edit{ background-position: 0 0 !important; } +.htmlarea-action-bidi-override{ background-position: 0 -58px !important; } +.htmlarea-action-big{ background-position: 0 -116px !important; } +.htmlarea-action-blockquote{ background-position: 0 -174px !important; } +.htmlarea-action-bold{ background-position: 0 -232px !important; } +.htmlarea-action-cell-delete{ background-position: 0 -290px !important; } +.htmlarea-action-cell-edit-properties{ background-position: 0 -348px !important; } +.htmlarea-action-cell-insert-after{ background-position: 0 -406px !important; } +.htmlarea-action-cell-insert-before{ background-position: 0 -464px !important; } +.htmlarea-action-cell-merge{ background-position: 0 -522px !important; } +.htmlarea-action-cell-split{ background-position: 0 -580px !important; } +.htmlarea-action-character-insert-from-map{ background-position: 0 -638px !important; } +.htmlarea-action-citation{ background-position: 0 -696px !important; } +.htmlarea-action-code{ background-position: 0 -754px !important; } +.htmlarea-action-color-background{ background-position: 0 -812px !important; } +.htmlarea-action-color-foreground{ background-position: 0 -870px !important; } +.htmlarea-action-column-delete{ background-position: 0 -928px !important; } +.htmlarea-action-column-edit-properties{ background-position: 0 -986px !important; } +.htmlarea-action-column-insert-after{ background-position: 0 -1044px !important; } +.htmlarea-action-column-insert-before{ background-position: 0 -1102px !important; } +.htmlarea-action-column-split{ background-position: 0 -1160px !important; } +.htmlarea-action-copy{ background-position: 0 -1218px !important; } +.htmlarea-action-cut{ background-position: 0 -1276px !important; } +.htmlarea-action-definition-list-item{ background-position: 0 -1334px !important; } +.htmlarea-action-definition-list{ background-position: 0 -1392px !important; } +.htmlarea-action-definition{ background-position: 0 -1450px !important; } +.htmlarea-action-delete-item{ background-position: 0 -1508px !important; } +.htmlarea-action-deleted-text{ background-position: 0 -1566px !important; } +.htmlarea-action-editor-show-about{ background-position: 0 -1624px !important; } +.htmlarea-action-editor-toggle-mode{ background-position: 0 -1682px !important; } +.htmlarea-action-emphasis{ background-position: 0 -1740px !important; } +.htmlarea-action-find-replace{ background-position: 0 -1798px !important; } +.htmlarea-action-horizontal-rule-insert{ background-position: 0 -1856px !important; } +.htmlarea-action-image-edit{ background-position: 0 -1914px !important; } +.htmlarea-action-indent{ background-position: 0 -1972px !important; } +.htmlarea-action-inserted-text{ background-position: 0 -2030px !important; } +.htmlarea-action-italic{ background-position: 0 -2088px !important; } +.htmlarea-action-justify-center{ background-position: 0 -2146px !important; } +.htmlarea-action-justify-full{ background-position: 0 -2204px !important; } +.htmlarea-action-justify-left{ background-position: 0 -2262px !important; } +.htmlarea-action-justify-right{ background-position: 0 -2320px !important; } +.htmlarea-action-keyboard{ background-position: 0 -2378px !important; } +.htmlarea-action-language-marks-show{ background-position: 0 -2436px !important; } +.htmlarea-action-link-edit{ background-position: 0 -2494px !important; } +.htmlarea-action-mono-spaced{ background-position: 0 -2552px !important; } +.htmlarea-action-ordered-list{ background-position: 0 -2610px !important; } +.htmlarea-action-outdent{ background-position: 0 -2668px !important; } +.htmlarea-action-paragraph-insert-after{ background-position: 0 -2726px !important; } +.htmlarea-action-paragraph-insert-before{ background-position: 0 -2784px !important; } +.htmlarea-action-paste-behaviour{ background-position: 0 -2842px !important; } +.htmlarea-action-paste-toggle{ background-position: 0 -2900px !important; } +.htmlarea-action-paste{ background-position: 0 -2958px !important; } +.htmlarea-action-quotation{ background-position: 0 -3016px !important; } +.htmlarea-action-redo{ background-position: 0 -3074px !important; } +.htmlarea-action-remove-format{ background-position: 0 -3132px !important; } +.htmlarea-action-row-delete{ background-position: 0 -3190px !important; } +.htmlarea-action-row-edit-properties{ background-position: 0 -3248px !important; } +.htmlarea-action-row-insert-above{ background-position: 0 -3306px !important; } +.htmlarea-action-row-insert-under{ background-position: 0 -3364px !important; } +.htmlarea-action-row-split{ background-position: 0 -3422px !important; } +.htmlarea-action-sample{ background-position: 0 -3480px !important; } +.htmlarea-action-small{ background-position: 0 -3538px !important; } +.htmlarea-action-smiley-insert{ background-position: 0 -3596px !important; } +.htmlarea-action-span{ background-position: 0 -3654px !important; } +.htmlarea-action-spell-check{ background-position: 0 -3712px !important; } +.htmlarea-action-strike-through{ background-position: 0 -3770px !important; } +.htmlarea-action-strong{ background-position: 0 -3828px !important; } +.htmlarea-action-subscript{ background-position: 0 -3886px !important; } +.htmlarea-action-superscript{ background-position: 0 -3944px !important; } +.htmlarea-action-table-edit-properties{ background-position: 0 -4002px !important; } +.htmlarea-action-table-insert{ background-position: 0 -4060px !important; } +.htmlarea-action-table-restyle{ background-position: 0 -4118px !important; } +.htmlarea-action-table-show-borders{ background-position: 0 -4176px !important; } +.htmlarea-action-tag-insert{ background-position: 0 -4234px !important; } +.htmlarea-action-text-direction-left-to-right{ background-position: 0 -4292px !important; } +.htmlarea-action-text-direction-right-to-left{ background-position: 0 -4350px !important; } +.htmlarea-action-underline{ background-position: 0 -4408px !important; } +.htmlarea-action-undo{ background-position: 0 -4466px !important; } +.htmlarea-action-unlink{ background-position: 0 -4524px !important; } +.htmlarea-action-unordered-list{ background-position: 0 -4582px !important; } +.htmlarea-action-user-element-edit{ background-position: 0 -4640px !important; } +.htmlarea-action-variable{ background-position: 0 -4698px !important; } diff --git a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/actions/paste-as-plain-text.gif b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/actions/paste-as-plain-text.gif deleted file mode 100644 index 881378e676f..00000000000 Binary files a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/actions/paste-as-plain-text.gif and /dev/null differ diff --git a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/actions/paste-behaviour.gif b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/actions/paste-behaviour.gif new file mode 100644 index 00000000000..881378e676f Binary files /dev/null and b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/actions/paste-behaviour.gif differ diff --git a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/actions/paste-toggle.gif b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/actions/paste-toggle.gif new file mode 100644 index 00000000000..e6f1c2d1181 Binary files /dev/null and b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/actions/paste-toggle.gif differ diff --git a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/sprites/actions.gif b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/sprites/actions.gif index 02e993e742e..c2c4abd9e4c 100644 Binary files a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/sprites/actions.gif and b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/sprites/actions.gif differ diff --git a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/sprites/actions.png b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/sprites/actions.png index f068b71165f..733977f1a85 100644 Binary files a/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/sprites/actions.png and b/typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/sprites/actions.png differ diff --git a/typo3/sysext/rtehtmlarea/locallang.xml b/typo3/sysext/rtehtmlarea/locallang.xml index dd096e31a64..5e47e20c974 100644 --- a/typo3/sysext/rtehtmlarea/locallang.xml +++ b/typo3/sysext/rtehtmlarea/locallang.xml @@ -18,6 +18,9 @@ + + + diff --git a/typo3/sysext/t3skin/rtehtmlarea/htmlarea.css b/typo3/sysext/t3skin/rtehtmlarea/htmlarea.css index 62af8fe2569..56ffc32ddd7 100644 --- a/typo3/sysext/t3skin/rtehtmlarea/htmlarea.css +++ b/typo3/sysext/t3skin/rtehtmlarea/htmlarea.css @@ -443,84 +443,85 @@ body.ext-ie6 .htmlarea-context-menu .x-menu-item-icon { background-position: 0 -15px; } /* Action icon selectors for toolbar, context menu and window headers */ -.htmlarea-action-abbreviation-edit { background-position: 0 0 !important; } -.htmlarea-action-bidi-override { background-position: 0 -58px !important; } -.htmlarea-action-big { background-position: 0 -116px !important; } -.htmlarea-action-blockquote { background-position: 0 -174px !important; } -.htmlarea-action-bold { background-position: 0 -232px !important; } -.htmlarea-action-cell-delete { background-position: 0 -290px !important; } -.htmlarea-action-cell-edit-properties { background-position: 0 -348px !important; } -.htmlarea-action-cell-insert-after { background-position: 0 -406px !important; } -.htmlarea-action-cell-insert-before { background-position: 0 -464px !important; } -.htmlarea-action-cell-merge { background-position: 0 -522px !important; } -.htmlarea-action-cell-split { background-position: 0 -580px !important; } -.htmlarea-action-character-insert-from-map { background-position: 0 -638px !important; } -.htmlarea-action-citation { background-position: 0 -696px !important; } -.htmlarea-action-code { background-position: 0 -754px !important; } -.htmlarea-action-color-background { background-position: 0 -812px !important; } -.htmlarea-action-color-foreground { background-position: 0 -870px !important; } -.htmlarea-action-column-delete { background-position: 0 -928px !important; } -.htmlarea-action-column-edit-properties { background-position: 0 -986px !important; } -.htmlarea-action-column-insert-after { background-position: 0 -1044px !important; } -.htmlarea-action-column-insert-before { background-position: 0 -1102px !important; } -.htmlarea-action-column-split { background-position: 0 -1160px !important; } -.htmlarea-action-copy { background-position: 0 -1218px !important; } -.htmlarea-action-cut { background-position: 0 -1276px !important; } -.htmlarea-action-definition-list-item { background-position: 0 -1334px !important; } -.htmlarea-action-definition-list { background-position: 0 -1392px !important; } -.htmlarea-action-definition { background-position: 0 -1450px !important; } -.htmlarea-action-delete-item { background-position: 0 -1508px !important; } -.htmlarea-action-deleted-text { background-position: 0 -1566px !important; } -.htmlarea-action-editor-show-about { background-position: 0 -1624px !important; } -.htmlarea-action-editor-toggle-mode { background-position: 0 -1682px !important; } -.htmlarea-action-emphasis { background-position: 0 -1740px !important; } -.htmlarea-action-find-replace { background-position: 0 -1798px !important; } -.htmlarea-action-horizontal-rule-insert { background-position: 0 -1856px !important; } -.htmlarea-action-image-edit { background-position: 0 -1914px !important; } -.htmlarea-action-indent { background-position: 0 -1972px !important; } -.htmlarea-action-inserted-text { background-position: 0 -2030px !important; } -.htmlarea-action-italic { background-position: 0 -2088px !important; } -.htmlarea-action-justify-center { background-position: 0 -2146px !important; } -.htmlarea-action-justify-full { background-position: 0 -2204px !important; } -.htmlarea-action-justify-left { background-position: 0 -2262px !important; } -.htmlarea-action-justify-right { background-position: 0 -2320px !important; } -.htmlarea-action-keyboard { background-position: 0 -2378px !important; } -.htmlarea-action-language-marks-show { background-position: 0 -2436px !important; } -.htmlarea-action-link-edit { background-position: 0 -2494px !important; } -.htmlarea-action-mono-spaced { background-position: 0 -2552px !important; } -.htmlarea-action-ordered-list { background-position: 0 -2610px !important; } -.htmlarea-action-outdent { background-position: 0 -2668px !important; } -.htmlarea-action-paragraph-insert-after { background-position: 0 -2726px !important; } -.htmlarea-action-paragraph-insert-before { background-position: 0 -2784px !important; } -.htmlarea-action-paste-as-plain-text { background-position: 0 -2842px !important; } -.htmlarea-action-paste { background-position: 0 -2900px !important; } -.htmlarea-action-quotation { background-position: 0 -2958px !important; } -.htmlarea-action-redo { background-position: 0 -3016px !important; } -.htmlarea-action-remove-format { background-position: 0 -3074px !important; } -.htmlarea-action-row-delete { background-position: 0 -3132px !important; } -.htmlarea-action-row-edit-properties { background-position: 0 -3190px !important; } -.htmlarea-action-row-insert-above { background-position: 0 -3248px !important; } -.htmlarea-action-row-insert-under { background-position: 0 -3306px !important; } -.htmlarea-action-row-split { background-position: 0 -3364px !important; } -.htmlarea-action-sample { background-position: 0 -3422px !important; } -.htmlarea-action-small { background-position: 0 -3480px !important; } -.htmlarea-action-smiley-insert { background-position: 0 -3538px !important; } -.htmlarea-action-span { background-position: 0 -3596px !important; } -.htmlarea-action-spell-check { background-position: 0 -3654px !important; } -.htmlarea-action-strike-through { background-position: 0 -3712px !important; } -.htmlarea-action-strong { background-position: 0 -3770px !important; } -.htmlarea-action-subscript { background-position: 0 -3828px !important; } -.htmlarea-action-superscript { background-position: 0 -3886px !important; } -.htmlarea-action-table-edit-properties { background-position: 0 -3944px !important; } -.htmlarea-action-table-insert { background-position: 0 -4002px !important; } -.htmlarea-action-table-restyle { background-position: 0 -4060px !important; } -.htmlarea-action-table-show-borders { background-position: 0 -4118px !important; } -.htmlarea-action-tag-insert { background-position: 0 -4176px !important; } -.htmlarea-action-text-direction-left-to-right { background-position: 0 -4234px !important; } -.htmlarea-action-text-direction-right-to-left { background-position: 0 -4292px !important; } -.htmlarea-action-underline { background-position: 0 -4350px !important; } -.htmlarea-action-undo { background-position: 0 -4408px !important; } -.htmlarea-action-unlink { background-position: 0 -4466px !important; } -.htmlarea-action-unordered-list { background-position: 0 -4524px !important; } -.htmlarea-action-user-element-edit { background-position: 0 -4582px !important; } -.htmlarea-action-variable { background-position: 0 -4640px !important; } +.htmlarea-action-abbreviation-edit{ background-position: 0 0 !important; } +.htmlarea-action-bidi-override{ background-position: 0 -58px !important; } +.htmlarea-action-big{ background-position: 0 -116px !important; } +.htmlarea-action-blockquote{ background-position: 0 -174px !important; } +.htmlarea-action-bold{ background-position: 0 -232px !important; } +.htmlarea-action-cell-delete{ background-position: 0 -290px !important; } +.htmlarea-action-cell-edit-properties{ background-position: 0 -348px !important; } +.htmlarea-action-cell-insert-after{ background-position: 0 -406px !important; } +.htmlarea-action-cell-insert-before{ background-position: 0 -464px !important; } +.htmlarea-action-cell-merge{ background-position: 0 -522px !important; } +.htmlarea-action-cell-split{ background-position: 0 -580px !important; } +.htmlarea-action-character-insert-from-map{ background-position: 0 -638px !important; } +.htmlarea-action-citation{ background-position: 0 -696px !important; } +.htmlarea-action-code{ background-position: 0 -754px !important; } +.htmlarea-action-color-background{ background-position: 0 -812px !important; } +.htmlarea-action-color-foreground{ background-position: 0 -870px !important; } +.htmlarea-action-column-delete{ background-position: 0 -928px !important; } +.htmlarea-action-column-edit-properties{ background-position: 0 -986px !important; } +.htmlarea-action-column-insert-after{ background-position: 0 -1044px !important; } +.htmlarea-action-column-insert-before{ background-position: 0 -1102px !important; } +.htmlarea-action-column-split{ background-position: 0 -1160px !important; } +.htmlarea-action-copy{ background-position: 0 -1218px !important; } +.htmlarea-action-cut{ background-position: 0 -1276px !important; } +.htmlarea-action-definition-list-item{ background-position: 0 -1334px !important; } +.htmlarea-action-definition-list{ background-position: 0 -1392px !important; } +.htmlarea-action-definition{ background-position: 0 -1450px !important; } +.htmlarea-action-delete-item{ background-position: 0 -1508px !important; } +.htmlarea-action-deleted-text{ background-position: 0 -1566px !important; } +.htmlarea-action-editor-show-about{ background-position: 0 -1624px !important; } +.htmlarea-action-editor-toggle-mode{ background-position: 0 -1682px !important; } +.htmlarea-action-emphasis{ background-position: 0 -1740px !important; } +.htmlarea-action-find-replace{ background-position: 0 -1798px !important; } +.htmlarea-action-horizontal-rule-insert{ background-position: 0 -1856px !important; } +.htmlarea-action-image-edit{ background-position: 0 -1914px !important; } +.htmlarea-action-indent{ background-position: 0 -1972px !important; } +.htmlarea-action-inserted-text{ background-position: 0 -2030px !important; } +.htmlarea-action-italic{ background-position: 0 -2088px !important; } +.htmlarea-action-justify-center{ background-position: 0 -2146px !important; } +.htmlarea-action-justify-full{ background-position: 0 -2204px !important; } +.htmlarea-action-justify-left{ background-position: 0 -2262px !important; } +.htmlarea-action-justify-right{ background-position: 0 -2320px !important; } +.htmlarea-action-keyboard{ background-position: 0 -2378px !important; } +.htmlarea-action-language-marks-show{ background-position: 0 -2436px !important; } +.htmlarea-action-link-edit{ background-position: 0 -2494px !important; } +.htmlarea-action-mono-spaced{ background-position: 0 -2552px !important; } +.htmlarea-action-ordered-list{ background-position: 0 -2610px !important; } +.htmlarea-action-outdent{ background-position: 0 -2668px !important; } +.htmlarea-action-paragraph-insert-after{ background-position: 0 -2726px !important; } +.htmlarea-action-paragraph-insert-before{ background-position: 0 -2784px !important; } +.htmlarea-action-paste-behaviour{ background-position: 0 -2842px !important; } +.htmlarea-action-paste-toggle{ background-position: 0 -2900px !important; } +.htmlarea-action-paste{ background-position: 0 -2958px !important; } +.htmlarea-action-quotation{ background-position: 0 -3016px !important; } +.htmlarea-action-redo{ background-position: 0 -3074px !important; } +.htmlarea-action-remove-format{ background-position: 0 -3132px !important; } +.htmlarea-action-row-delete{ background-position: 0 -3190px !important; } +.htmlarea-action-row-edit-properties{ background-position: 0 -3248px !important; } +.htmlarea-action-row-insert-above{ background-position: 0 -3306px !important; } +.htmlarea-action-row-insert-under{ background-position: 0 -3364px !important; } +.htmlarea-action-row-split{ background-position: 0 -3422px !important; } +.htmlarea-action-sample{ background-position: 0 -3480px !important; } +.htmlarea-action-small{ background-position: 0 -3538px !important; } +.htmlarea-action-smiley-insert{ background-position: 0 -3596px !important; } +.htmlarea-action-span{ background-position: 0 -3654px !important; } +.htmlarea-action-spell-check{ background-position: 0 -3712px !important; } +.htmlarea-action-strike-through{ background-position: 0 -3770px !important; } +.htmlarea-action-strong{ background-position: 0 -3828px !important; } +.htmlarea-action-subscript{ background-position: 0 -3886px !important; } +.htmlarea-action-superscript{ background-position: 0 -3944px !important; } +.htmlarea-action-table-edit-properties{ background-position: 0 -4002px !important; } +.htmlarea-action-table-insert{ background-position: 0 -4060px !important; } +.htmlarea-action-table-restyle{ background-position: 0 -4118px !important; } +.htmlarea-action-table-show-borders{ background-position: 0 -4176px !important; } +.htmlarea-action-tag-insert{ background-position: 0 -4234px !important; } +.htmlarea-action-text-direction-left-to-right{ background-position: 0 -4292px !important; } +.htmlarea-action-text-direction-right-to-left{ background-position: 0 -4350px !important; } +.htmlarea-action-underline{ background-position: 0 -4408px !important; } +.htmlarea-action-undo{ background-position: 0 -4466px !important; } +.htmlarea-action-unlink{ background-position: 0 -4524px !important; } +.htmlarea-action-unordered-list{ background-position: 0 -4582px !important; } +.htmlarea-action-user-element-edit{ background-position: 0 -4640px !important; } +.htmlarea-action-variable{ background-position: 0 -4698px !important; } diff --git a/typo3/sysext/t3skin/rtehtmlarea/images/actions/paste-as-plain-text.gif b/typo3/sysext/t3skin/rtehtmlarea/images/actions/paste-as-plain-text.gif deleted file mode 100644 index 881378e676f..00000000000 Binary files a/typo3/sysext/t3skin/rtehtmlarea/images/actions/paste-as-plain-text.gif and /dev/null differ diff --git a/typo3/sysext/t3skin/rtehtmlarea/images/actions/paste-behaviour.gif b/typo3/sysext/t3skin/rtehtmlarea/images/actions/paste-behaviour.gif new file mode 100644 index 00000000000..881378e676f Binary files /dev/null and b/typo3/sysext/t3skin/rtehtmlarea/images/actions/paste-behaviour.gif differ diff --git a/typo3/sysext/t3skin/rtehtmlarea/images/actions/paste-toggle.gif b/typo3/sysext/t3skin/rtehtmlarea/images/actions/paste-toggle.gif new file mode 100644 index 00000000000..e6f1c2d1181 Binary files /dev/null and b/typo3/sysext/t3skin/rtehtmlarea/images/actions/paste-toggle.gif differ diff --git a/typo3/sysext/t3skin/rtehtmlarea/images/sprites/actions.gif b/typo3/sysext/t3skin/rtehtmlarea/images/sprites/actions.gif index 02e993e742e..c2c4abd9e4c 100644 Binary files a/typo3/sysext/t3skin/rtehtmlarea/images/sprites/actions.gif and b/typo3/sysext/t3skin/rtehtmlarea/images/sprites/actions.gif differ diff --git a/typo3/sysext/t3skin/rtehtmlarea/images/sprites/actions.png b/typo3/sysext/t3skin/rtehtmlarea/images/sprites/actions.png index f068b71165f..733977f1a85 100644 Binary files a/typo3/sysext/t3skin/rtehtmlarea/images/sprites/actions.png and b/typo3/sysext/t3skin/rtehtmlarea/images/sprites/actions.png differ