mirror of
https://github.com/joomla/joomla-cms.git
synced 2024-06-25 14:53:01 +00:00
[4.0] highlight js (#33089)
This commit is contained in:
parent
2126f03726
commit
fab283efd8
|
@ -1,111 +0,0 @@
|
|||
/**
|
||||
* @package Joomla.JavaScript
|
||||
* @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// Only define the Joomla namespace if not defined.
|
||||
if (typeof(Joomla) === 'undefined') {
|
||||
var Joomla = {};
|
||||
}
|
||||
|
||||
Joomla.Highlighter = function(_options){
|
||||
var $, words, options = {
|
||||
autoUnhighlight: true,
|
||||
caseSensitive: false,
|
||||
startElement: false,
|
||||
endElement: false,
|
||||
elements: [],
|
||||
className: 'highlight',
|
||||
onlyWords: true,
|
||||
tag: 'span'
|
||||
},
|
||||
|
||||
highlight = function (words) {
|
||||
if (words.constructor === String) {
|
||||
words = [words];
|
||||
}
|
||||
if (options.autoUnhighlight) {
|
||||
unhighlight(words);
|
||||
}
|
||||
var pattern = options.onlyWords ? '\b' + pattern + '\b' : '(' + words.join('\\b|\\b') + ')',
|
||||
regex = new RegExp(pattern, options.caseSensitive ? '' : 'i');
|
||||
options.elements.map(function(el){
|
||||
recurse(el, regex, options.className);
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
unhighlight = function (words) {
|
||||
if (words.constructor === String) {
|
||||
words = [words];
|
||||
}
|
||||
|
||||
var $elements, tn;
|
||||
words.map(function(word){
|
||||
word = (options.caseSensitive ? word : word.toUpperCase());
|
||||
if (words[word]) {
|
||||
$elements = $(words[word]);
|
||||
$elements.removeClass();
|
||||
$elements.each(function (index, el) {
|
||||
tn = document.createTextNode($(el).text());
|
||||
el.parentNode.replaceChild(tn, el);
|
||||
});
|
||||
}
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
recurse = function (node, regex, klass) {
|
||||
if (node.nodeType === 3) {
|
||||
var match = node.nodeValue.match(regex), highlight, $highlight, wordNode, wordClone, comparer, i;
|
||||
if (match) {
|
||||
highlight = document.createElement(options.tag);
|
||||
$highlight = $(highlight);
|
||||
$highlight.addClass(klass);
|
||||
wordNode = node.splitText(match.index);
|
||||
wordNode.splitText(match[0].length);
|
||||
wordClone = wordNode.cloneNode(true);
|
||||
$highlight.append(wordClone);
|
||||
$(wordNode).replaceWith(highlight)
|
||||
$highlight.attr('rel', $highlight.text());
|
||||
comparer = $highlight.text()
|
||||
if (!options.caseSensitive) {
|
||||
comparer = $highlight.text().toUpperCase();
|
||||
}
|
||||
if (!words[comparer]) {
|
||||
words[comparer] = [];
|
||||
}
|
||||
words[comparer].push(highlight);
|
||||
return 1;
|
||||
}
|
||||
} else if ((node.nodeType === 1 && node.childNodes) && !/(script|style|textarea|iframe)/i.test(node.tagName) && !(node.tagName === options.tag.toUpperCase() && node.className === klass)) {
|
||||
for (i = 0; i < node.childNodes.length; i++) {
|
||||
i += recurse(node.childNodes[i], regex, klass);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
|
||||
getElements = function ($start, $end) {
|
||||
var $next = $start.next();
|
||||
if ($next.attr('id') !== $end.attr('id')) {
|
||||
options.elements.push($next.get(0));
|
||||
getElements($next, $end);
|
||||
}
|
||||
},
|
||||
|
||||
initialize = function(_options) {
|
||||
$ = jQuery.noConflict();
|
||||
$.extend(options, _options);
|
||||
getElements($(options.startElement), $(options.endElement));
|
||||
words = [];
|
||||
};
|
||||
|
||||
initialize(_options);
|
||||
|
||||
return {
|
||||
highlight: highlight,
|
||||
unhighlight : unhighlight
|
||||
};
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
span.highlight {
|
||||
background-color:#FFFFCC;
|
||||
font-weight:bold;
|
||||
padding:1px 0;
|
||||
}
|
|
@ -135,6 +135,29 @@
|
|||
"dragula"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "highlight-legacy",
|
||||
"type": "script",
|
||||
"uri": "system/highlight-es5.min.js",
|
||||
"attributes": {
|
||||
"defer": true,
|
||||
"nomodule": true
|
||||
},
|
||||
"dependencies": [
|
||||
"core"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "highlight",
|
||||
"type": "script",
|
||||
"uri": "system/highlight.min.js",
|
||||
"attributes": {
|
||||
"type": "module"
|
||||
},
|
||||
"dependencies": [
|
||||
"highlight-legacy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "field.passwordview",
|
||||
"type": "script",
|
||||
|
|
70
build/media_source/system/js/highlight.es6.js
Normal file
70
build/media_source/system/js/highlight.es6.js
Normal file
|
@ -0,0 +1,70 @@
|
|||
import Mark from 'mark.js/src/vanilla';
|
||||
|
||||
// mark.js defaults
|
||||
const defaultOptions = {
|
||||
exclude: [],
|
||||
separateWordSearch: true,
|
||||
accuracy: 'partially',
|
||||
diacritics: true,
|
||||
synonyms: {},
|
||||
iframes: false,
|
||||
iframesTimeout: 5000,
|
||||
acrossElements: true,
|
||||
caseSensitive: false,
|
||||
ignoreJoiners: false,
|
||||
wildcards: 'disabled',
|
||||
compatibility: false,
|
||||
};
|
||||
|
||||
if (Joomla.getOptions && typeof Joomla.getOptions === 'function' && Joomla.getOptions('highlight')) {
|
||||
const scriptOptions = Joomla.getOptions('highlight');
|
||||
scriptOptions.forEach((currentOpts) => {
|
||||
const options = { ...defaultOptions, ...currentOpts };
|
||||
|
||||
// Continue only if the element exists
|
||||
if (!options.compatibility) {
|
||||
const element = document.querySelector(`.${options.class}`);
|
||||
|
||||
if (element) {
|
||||
const instance = new Mark(element);
|
||||
|
||||
// Loop through the terms
|
||||
options.highLight.forEach((term) => {
|
||||
instance.mark(term, options);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const start = document.querySelector(`#${options.start}`);
|
||||
const end = document.querySelector(`#${options.end}`);
|
||||
const parent = start.parentNode;
|
||||
const targetNodes = [];
|
||||
const allElems = Array.from(parent.childNodes);
|
||||
let startEl = false;
|
||||
let stopEl = false;
|
||||
|
||||
// Remove all elements till start element
|
||||
allElems.forEach((element) => {
|
||||
if (!startEl || stopEl) {
|
||||
return;
|
||||
}
|
||||
if (element === start) {
|
||||
startEl = true;
|
||||
return;
|
||||
}
|
||||
if (element === end) {
|
||||
stopEl = true;
|
||||
return;
|
||||
}
|
||||
if (startEl && !stopEl) {
|
||||
targetNodes.push(element);
|
||||
}
|
||||
});
|
||||
|
||||
targetNodes.forEach((node) => {
|
||||
const instance = new Mark(node);
|
||||
// Loop through the terms
|
||||
options.highLight.map((term) => instance.mark(term, options));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
|
@ -48,11 +47,19 @@ use Joomla\CMS\Uri\Uri;
|
|||
<?php endif; ?>
|
||||
<?php // Activate the highlighter if enabled. ?>
|
||||
<?php if (!empty($this->query->highlight) && $this->params->get('highlight_terms', 1)) : ?>
|
||||
<?php HTMLHelper::_('behavior.highlighter', $this->query->highlight); ?>
|
||||
<?php
|
||||
$this->document->getWebAssetManager()->useScript('highlight');
|
||||
$this->document->addScriptOptions(
|
||||
'highlight',
|
||||
[[
|
||||
'class' => 'js-highlight',
|
||||
'highLight' => $this->query->highlight,
|
||||
]]
|
||||
);
|
||||
?>
|
||||
<?php endif; ?>
|
||||
<?php // Display a list of results ?>
|
||||
<br id="highlighter-start" />
|
||||
<ol id="search-result-list" class="com-finder__results-list" start="<?php echo (int) $this->pagination->limitstart + 1; ?>">
|
||||
<ol id="search-result-list" class="js-highlight com-finder__results-list" start="<?php echo (int) $this->pagination->limitstart + 1; ?>">
|
||||
<?php $this->baseUrl = Uri::getInstance()->toString(array('scheme', 'host', 'port')); ?>
|
||||
<?php foreach ($this->results as $i => $result) : ?>
|
||||
<?php $this->result = &$result; ?>
|
||||
|
@ -61,7 +68,6 @@ use Joomla\CMS\Uri\Uri;
|
|||
<?php echo $this->loadTemplate($layout); ?>
|
||||
<?php endforeach; ?>
|
||||
</ol>
|
||||
<br id="highlighter-end" />
|
||||
<?php // Display the pagination ?>
|
||||
<div class="com-finder__navigation search-pagination">
|
||||
<?php if ($this->params->get('show_pagination', 1) > 0) : ?>
|
||||
|
|
|
@ -11,7 +11,6 @@ namespace Joomla\CMS\HTML\Helpers;
|
|||
\defined('JPATH_PLATFORM') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Filter\OutputFilter;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
/**
|
||||
|
@ -56,6 +55,7 @@ abstract class Behavior
|
|||
* @return void
|
||||
*
|
||||
* @since 3.4
|
||||
* @deprecated 5.0 Use the script directly
|
||||
*/
|
||||
public static function formvalidator()
|
||||
{
|
||||
|
@ -79,6 +79,7 @@ abstract class Behavior
|
|||
* @return void
|
||||
*
|
||||
* @since 1.5
|
||||
* @deprecated 5.0 Use the script directly
|
||||
*/
|
||||
public static function combobox()
|
||||
{
|
||||
|
@ -93,6 +94,7 @@ abstract class Behavior
|
|||
* @return void
|
||||
*
|
||||
* @since 1.7
|
||||
* @deprecated 5.0 Use the script directly
|
||||
*/
|
||||
public static function multiselect($id = 'adminForm')
|
||||
{
|
||||
|
@ -139,59 +141,29 @@ abstract class Behavior
|
|||
* @return void
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @deprecated 5.0 Use the script directly
|
||||
*/
|
||||
public static function highlighter(array $terms, $start = 'highlighter-start', $end = 'highlighter-end', $className = 'highlight', $tag = 'span')
|
||||
{
|
||||
$sig = md5(serialize(array($terms, $start, $end)));
|
||||
|
||||
if (isset(static::$loaded[__METHOD__][$sig]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$terms = array_filter($terms, 'strlen');
|
||||
|
||||
// Nothing to Highlight
|
||||
if (empty($terms))
|
||||
if (!empty($terms))
|
||||
{
|
||||
static::$loaded[__METHOD__][$sig] = true;
|
||||
$doc = Factory::getDocument();
|
||||
|
||||
return;
|
||||
$doc->getWebAssetManager()->useScript('highlight');
|
||||
$doc->addScriptOptions(
|
||||
'highlight',
|
||||
[[
|
||||
'class' => 'js-highlight',
|
||||
'highLight' => $terms,
|
||||
'compatibility' => true,
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
]]
|
||||
);
|
||||
}
|
||||
|
||||
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
|
||||
|
||||
$wa
|
||||
->registerScript('joomla.highlighter', 'legacy/highlighter.min.js', ['dependencies' => ['core', 'jquery']])
|
||||
->useScript('joomla.highlighter');
|
||||
|
||||
foreach ($terms as $i => $term)
|
||||
{
|
||||
$terms[$i] = OutputFilter::stringJSSafe($term);
|
||||
}
|
||||
|
||||
$document = Factory::getDocument();
|
||||
$document->addScriptDeclaration("
|
||||
jQuery(function ($) {
|
||||
var start = document.getElementById('" . $start . "');
|
||||
var end = document.getElementById('" . $end . "');
|
||||
if (!start || !end || !Joomla.Highlighter) {
|
||||
return true;
|
||||
}
|
||||
highlighter = new Joomla.Highlighter({
|
||||
startElement: start,
|
||||
endElement: end,
|
||||
className: '" . $className . "',
|
||||
onlyWords: false,
|
||||
tag: '" . $tag . "'
|
||||
}).highlight([\"" . implode('","', $terms) . "\"]);
|
||||
$(start).remove();
|
||||
$(end).remove();
|
||||
});"
|
||||
);
|
||||
|
||||
static::$loaded[__METHOD__][$sig] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
10339
package-lock.json
generated
10339
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -48,6 +48,7 @@
|
|||
"joomla-ui-custom-elements": "0.0.40",
|
||||
"jquery": "^3.6.0",
|
||||
"jquery-migrate": "^3.3.2",
|
||||
"mark.js": "^8.11.1",
|
||||
"mediaelement": "^4.2.16",
|
||||
"metismenujs": "^1.2.1",
|
||||
"punycode": "^2.1.1",
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Filter\InputFilter;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
use Joomla\Component\Finder\Administrator\Indexer\Result;
|
||||
|
||||
|
@ -86,12 +86,24 @@ class PlgSystemHighlight extends CMSPlugin
|
|||
}
|
||||
|
||||
// Activate the highlighter.
|
||||
HTMLHelper::_('behavior.highlighter', $cleanTerms);
|
||||
if (!empty($cleanTerms))
|
||||
{
|
||||
$doc = Factory::getDocument();
|
||||
|
||||
$doc->getWebAssetManager()->useScript('highlight');
|
||||
$doc->addScriptOptions(
|
||||
'highlight',
|
||||
[[
|
||||
'class' => 'js-highlight',
|
||||
'highLight' => $cleanTerms,
|
||||
]]
|
||||
);
|
||||
}
|
||||
|
||||
// Adjust the component buffer.
|
||||
$doc = $this->app->getDocument();
|
||||
$buf = $doc->getBuffer('component');
|
||||
$buf = '<br id="highlighter-start" />' . $buf . '<br id="highlighter-end" />';
|
||||
$buf = '<div class="js-highlight">' . $buf . '</div>';
|
||||
$doc->setBuffer($buf, 'component');
|
||||
}
|
||||
|
||||
|
|
|
@ -224,3 +224,6 @@ $state-warning-border: scale-color($warning, $lightness: -5%) !de
|
|||
$state-danger-text: $white !default;
|
||||
$state-danger-bg: $danger !default;
|
||||
$state-danger-border: scale-color($danger, $lightness: -5%) !default;
|
||||
|
||||
// Mark element
|
||||
$mark-bg: #fbeea8 !default;
|
||||
|
|
Loading…
Reference in New Issue
Block a user