diff --git a/administrator/components/com_content/tmpl/article/showdiff.php b/administrator/components/com_content/tmpl/article/showdiff.php new file mode 100644 index 0000000000000..f9e51c1be4698 --- /dev/null +++ b/administrator/components/com_content/tmpl/article/showdiff.php @@ -0,0 +1,82 @@ + 'auto', 'relative' => true)); +JHtml::_('script', 'vendor/diff/diff.js', array('version' => 'auto', 'relative' => true)); +JHtml::_('stylesheet', 'com_contenthistory/jquery.pretty-text-diff.css', array('version' => 'auto', 'relative' => true)); +JHtml::_('script', 'com_content/admin-article-showdiff.js', array('version' => 'auto', 'relative' => true)); + +$document = JFactory::getDocument(); +$this->eName = JFactory::getApplication()->input->getCmd('e_name', ''); +$this->eName = preg_replace('#[^A-Z0-9\-\_\[\]]#i', '', $this->eName); + +$document->setTitle(JText::_('COM_CONTENT_SHOWDIFF_DOC_TITLE')); + +$input = JFactory::getApplication()->input; + +/** @var Joomla\Component\Contenthistory\Administrator\Model\History $contentHistory */ +$contentHistory = new HistoryModel; + +$itemId = $contentHistory->getState('item_id', $input->get('id')); +$typeId = $contentHistory->getState('type_id', 5); +$previousVersion = 1; + +if ($itemId === 0) +{ + $itemId = $input->get('id'); +} + +if ($typeId === 0) +{ + $typeId = 1; +} + +$contentHistory->setState('item_id', $itemId); +$contentHistory->setState('type_id', $typeId); +$dbObject = $contentHistory->getItems(); + +?> + +
+ + +
+ +'; + +if (count($dbObject) > 1) +{ + $object = ContenthistoryHelper::decodeFields($dbObject[ $previousVersion ]->version_data); + + if ($object->fulltext != null) + { + echo $object->introtext . '
' . $object->fulltext; + } + else + { + echo $object->introtext; + } +} + +echo ''; diff --git a/administrator/language/en-GB/en-GB.com_content.ini b/administrator/language/en-GB/en-GB.com_content.ini index 3d1d876c06fc6..57cdbdce07848 100644 --- a/administrator/language/en-GB/en-GB.com_content.ini +++ b/administrator/language/en-GB/en-GB.com_content.ini @@ -154,6 +154,11 @@ COM_CONTENT_URL_FIELD_B_BROWSERNAV_LABEL="URL B Target Window" COM_CONTENT_URL_FIELD_C_BROWSERNAV_LABEL="URL C Target Window" COM_CONTENT_WARNING_PROVIDE_VALID_NAME="Please provide a valid, non-blank title." COM_CONTENT_XML_DESCRIPTION="Article management component." +COM_CONTENT_SHOWDIFF_DOC_TITLE="Compare" +COM_CONTENT_SHOWDIFF_BUTTON_COMPARE_HTML_DESC="Displays the changes as HTML-Code" +COM_CONTENT_SHOWDIFF_BUTTON_COMPARE_HTML="Display HTML-Code" +COM_CONTENT_SHOWDIFF_BUTTON_COMPARE_TEXT_DESC="Displays the changes as HTML-Code" +COM_CONTENT_SHOWDIFF_BUTTON_COMPARE_TEXT="Display text" JGLOBAL_NO_ITEM_SELECTED="No articles selected" JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE="You are not allowed to create new articles in this category." diff --git a/administrator/language/en-GB/en-GB.plg_editors-xtd_showdiff.ini b/administrator/language/en-GB/en-GB.plg_editors-xtd_showdiff.ini new file mode 100644 index 0000000000000..84d79323ed95b --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_editors-xtd_showdiff.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_SHOWDIFF="Button - Compare" +PLG_EDITORSXTD_SHOWDIFF_BUTTON_SHOWDIFF="Compare" +PLG_EDITORSXTD_SHOWDIFF_XML_DESCRIPTION="Provides a button to show differences between versions within a new window" \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_editors-xtd_showdiff.sys.ini b/administrator/language/en-GB/en-GB.plg_editors-xtd_showdiff.sys.ini new file mode 100644 index 0000000000000..9e3b0016f86a8 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_editors-xtd_showdiff.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_SHOWDIFF="Button - Compare" +PLG_EDITORSXTD_SHOWDIFF_XML_DESCRIPTION="Provides a button to show differences between versions within a new window" \ No newline at end of file diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql index 4051374c82c46..f8b7f02e2381f 100644 --- a/installation/sql/mysql/joomla.sql +++ b/installation/sql/mysql/joomla.sql @@ -641,6 +641,7 @@ INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `elem (483, 0, 'plg_media-action_crop', 'plugin', 'crop', 'media-action', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0, ''), (484, 0, 'plg_media-action_resize', 'plugin', 'resize', 'media-action', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0, ''), (485, 0, 'plg_media-action_rotate', 'plugin', 'rotate', 'media-action', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0, ''), +(486, 0, 'plg_editors-xtd_showdiff', 'plugin', 'showdiff', 'editors-xtd', 0, 1, 1, 0, '', '', 0, '0000-00-00 00:00:00', 5, 0, ''), (509, 0, 'atum', 'template', 'atum', '', 1, 1, 1, 0, '', '', 0, '0000-00-00 00:00:00', 0, 0, ''), (510, 0, 'cassiopeia', 'template', 'cassiopeia', '', 0, 1, 1, 0, '', '{"logoFile":"","fluidContainer":"0","sidebarLeftWidth":"3","sidebarRightWidth":"3"}', 0, '0000-00-00 00:00:00', 0, 0, ''), (600, 802, 'English (en-GB)', 'language', 'en-GB', '', 0, 1, 1, 1, '', '', 0, '0000-00-00 00:00:00', 0, 0, ''), diff --git a/media/com_content/js/admin-article-showdiff.js b/media/com_content/js/admin-article-showdiff.js new file mode 100644 index 0000000000000..54085c6b04a36 --- /dev/null +++ b/media/com_content/js/admin-article-showdiff.js @@ -0,0 +1,158 @@ +(function() { + 'use strict'; + + document.addEventListener('DOMContentLoaded', function() { + var diffArea = document.getElementById('diff_area'), + text1 = diffArea.innerHTML, + text2 = parent.document.getElementById('jform_articletext_ifr').contentDocument.getElementById('tinymce').innerHTML, + diffText, diffHtml, span, fragment, spanParent; + + parent.window.onresize = movePopup; + movePopup(); + + fragment = document.createDocumentFragment(); + + diffHtml = JsDiff.diffWords(cleanMCE(text1), cleanMCE(text2)); + diffHtml.forEach(function( part ) { + span = createDiffSpan(part); + span.className = 'diff_html'; + span.style.display = 'none'; + fragment.appendChild(span); + }); + + diffText = JsDiff.diffWords(cleanTags(text1), cleanTags(text2)); + diffText.forEach(function( part ) { + span = createDiffSpan(part); + span.className = 'diff_text'; + span.style.display = 'inline-block'; + fragment.appendChild(span); + }); + + spanParent = document.createElement('div'); + spanParent.id = 'diff_area'; + spanParent.appendChild(fragment); + + while ( diffArea.lastChild ) { + diffArea.removeChild(diffArea.lastChild); + } + + diffArea.appendChild(spanParent); + + document.querySelector('.diff-header').addEventListener('click', function() { + var diffClasses = + [ + ['show', document.querySelectorAll('.diff_html')], + ['show', document.querySelectorAll('.diffhtml-header')], + ['hide', document.querySelectorAll('.diff_text')], + ['hide', document.querySelectorAll('.diff-header')] + ]; + + hideOrShowNodeLists(diffClasses); + }); + + document.querySelector('.diffhtml-header').addEventListener('click', function() { + var diffClasses = + [ + ['hide', document.querySelectorAll('.diff_html')], + ['hide', document.querySelectorAll('.diffhtml-header')], + ['show-inline', document.querySelectorAll('.diff_text')], + ['show', document.querySelectorAll('.diff-header')] + ]; + + hideOrShowNodeLists(diffClasses); + }); + + }); +})(); + +/* +** set css display value, depending if just the text or the text with html-tags would be displayed. +** @param nodeLists +*/ +function hideOrShowNodeLists( nodeLists ) { + var i, j, jLength, + iLength = nodeLists.length; + + for ( i = 0; i < iLength; ++i ) { + jLength = nodeLists[i][1].length; + + if ( nodeLists[i][0] === 'show' ) { + for ( j = 0; j < jLength; j++ ) { + nodeLists[i][1][j].style.display = 'block'; + } + } + else if ( nodeLists[i][0] === 'show-inline' ) { + for ( j = 0; j < jLength; j++ ) { + nodeLists[i][1][j].style.display = 'inline-block'; + } + } + else if ( nodeLists[i][0] === 'hide' ) { + for ( j = 0; j < jLength; j++ ) { + nodeLists[i][1][j].style.display = 'none'; + } + } + } +} + + +// creating a span for diff_html and diff_text +function createDiffSpan( part ) { + var color, span; + + color = part.added ? '#a6f3a6' : part.removed ? '#f8cbcb' : ''; + span = document.createElement('span'); + span.style.backgroundColor = color; + span.style.borderRadius = '.2rem'; + span.appendChild(document.createTextNode(part.value)); + + return span; +} + +// Deletes all HTML-Text it finds in the given text +function cleanTags( text ) { + var textClean = String(text), + regexp = new RegExp('<.*?>'); + + while ( regexp.test(textClean) ) { + textClean = textClean.replace(regexp.exec(textClean).toString(), ''); + } + + return textClean; +} + +// Deletes all HTML-Text it finds in the given text +function cleanMCE( text ) { + var textClean = String(text), + regexp1 = new RegExp('data-mce-href=".*?/"'), + regexp2 = new RegExp('> <'); + + while ( regexp1.test(textClean) ) { + textClean = textClean.replace(regexp1.exec(textClean).toString(), ''); + } + while ( regexp2.test(textClean) ) { + textClean = textClean.replace(regexp2.exec(textClean).toString(), ''); + } + + return textClean; +} + +// positioning of the showdiff-popup. +function movePopup() { + var editor = parent.document.getElementById('jform_articletext_ifr').parentNode, + editTop = editor.getBoundingClientRect().top + 5, + editWidth = (editor.offsetWidth) - 10, + popupBody = window.frameElement.parentNode, + popupContainer = popupBody.parentNode.parentNode, + popupFoot = popupContainer.getElementsByClassName('mce-foot')[0], + popupFootChild = popupFoot.firstChild, + popupFootChildBtn = popupFootChild.getElementsByClassName('mce-btn')[0]; + + popupContainer.style.top = editTop + 'px'; + popupContainer.style.left = '36px'; + popupContainer.style.width = editWidth + 'px'; + popupBody.style.width = editWidth + 'px'; + popupFoot.style.width = editWidth + 'px'; + popupFootChild.style.width = editWidth + 'px'; + popupFootChildBtn.style.left = 'unset'; + popupFootChildBtn.style.right = '15px'; +} diff --git a/plugins/editors-xtd/showdiff/showdiff.php b/plugins/editors-xtd/showdiff/showdiff.php new file mode 100644 index 0000000000000..84579b48447ec --- /dev/null +++ b/plugins/editors-xtd/showdiff/showdiff.php @@ -0,0 +1,75 @@ +input; + $itemId = $input->get('id'); + $user = JFactory::getUser(); + + if ($user->authorise('core.create', 'com_content') + || $user->authorise('core.edit', 'com_content') + || $user->authorise('core.edit.own', 'com_content')) + { + if (JUri::getInstance($_SERVER['HTTP_REFERER'])->getVar('option') === 'com_associations') + { + JFactory::getDocument()->addScriptOptions('xtd-showdiff', array('editor' => $name)); + + $link = 'index.php?option=com_content&view=article&layout=showdiff&tmpl=component&e_name=' + . $name . '&id=' . $itemId; + + $button = new JObject; + $button->modal = true; + $button->class = 'btn'; + $button->link = $link; + $button->text = JText::_('PLG_EDITORSXTD_SHOWDIFF_BUTTON_SHOWDIFF'); + $button->name = 'shuffle'; + $button->options = array( + 'height' => '450px', + 'width' => '400px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + ); + + return $button; + } + } + + // TODO Missing return statement? + } +} diff --git a/plugins/editors-xtd/showdiff/showdiff.xml b/plugins/editors-xtd/showdiff/showdiff.xml new file mode 100644 index 0000000000000..e581a03b553d3 --- /dev/null +++ b/plugins/editors-xtd/showdiff/showdiff.xml @@ -0,0 +1,20 @@ + + + plg_editors-xtd_showdiff + Joomla! Project + August 2017 + Copyright (C) 2017 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 1.0.0 + PLG_EDITORSXTD_SHOWDIFF_XML_DESCRIPTION + + showdiff.php + + + en-GB.plg_editors-xtd_showdiff.ini + en-GB.plg_editors-xtd_showdiff.sys.ini + + +