Add text fragments flag and functionality
This commit is contained in:
parent
da52e0f7bf
commit
873a18fbc9
|
@ -846,6 +846,29 @@ if (!$_SESSION['admin_username']) {
|
|||
} else $_POST['os_s_show_filetype_html'] = 0;
|
||||
OS_setValue('s_show_filetype_html', $_POST['os_s_show_filetype_html']);
|
||||
|
||||
if (isset($_POST['os_s_text_fragments']) && $_POST['os_s_text_fragments'] == '1') {
|
||||
$_POST['os_s_text_fragments'] = 1;
|
||||
if (strpos($_ODATA['s_result_template'], ' href="{{url}}" rel="noopener" ') === false) {
|
||||
OS_setValue('s_result_template', str_replace(
|
||||
' href="{{url}}" ',
|
||||
' href="{{url}}" rel="noopener" ',
|
||||
$_ODATA['s_result_template']
|
||||
));
|
||||
$_SESSION['message'][] = <<<ORCINUS
|
||||
Note: <code>rel="noopener"</code> has been added to the links in your result template.
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/Text_fragments#:~:text=noopener" rel="noopener" target="_blank">More info...</a>
|
||||
ORCINUS;
|
||||
}
|
||||
} else {
|
||||
$_POST['os_s_text_fragments'] = 0;
|
||||
OS_setValue('s_result_template', str_replace(
|
||||
' href="{{url}}" rel="noopener" ',
|
||||
' href="{{url}}" ',
|
||||
$_ODATA['s_result_template']
|
||||
));
|
||||
}
|
||||
OS_setValue('s_text_fragments', $_POST['os_s_text_fragments']);
|
||||
|
||||
$_SESSION['message'][] = 'Search settings have been saved.';
|
||||
break;
|
||||
|
||||
|
@ -1004,6 +1027,7 @@ if (!$_SESSION['admin_username']) {
|
|||
's_limit_term_length' => $_ODATA['s_limit_term_length'],
|
||||
's_limit_matchtext' => $_ODATA['s_limit_matchtext'],
|
||||
's_show_filetype_html' => $_ODATA['s_show_filetype_html'],
|
||||
's_text_fragments' => $_ODATA['s_text_fragments'],
|
||||
's_results_pagination' => $_ODATA['s_results_pagination'],
|
||||
's_limit_results' => $_ODATA['s_limit_results'],
|
||||
's_result_template' => json_encode(preg_replace('/\s{2,}/', ' ', $_ODATA['s_result_template']), JSON_INVALID_UTF8_IGNORE),
|
||||
|
@ -1360,7 +1384,7 @@ if (!$_SESSION['admin_username']) {
|
|||
while ($error = array_shift($_SESSION['error'])) { ?>
|
||||
<div class="col-10 col-sm-8 col-md-7">
|
||||
<div class="alert alert-danger alert-dismissible fade show mx-auto" role="alert"><?php
|
||||
echo htmlspecialchars($error); ?>
|
||||
echo $error; ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div><?php
|
||||
|
@ -1368,7 +1392,7 @@ if (!$_SESSION['admin_username']) {
|
|||
while ($message = array_shift($_SESSION['message'])) { ?>
|
||||
<div class="col-10 col-sm-8 col-md-7">
|
||||
<div class="alert alert-info alert-dismissible fade show mx-auto" role="alert"><?php
|
||||
echo htmlspecialchars($message); ?>
|
||||
echo $message; ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div><?php
|
||||
|
@ -2537,6 +2561,14 @@ if (!$_SESSION['admin_username']) {
|
|||
if ($_ODATA['s_show_filetype_html']) echo ' checked="checked"'; ?>>
|
||||
<label for="os_s_show_filetype_html" class="form-check-label">Show [HTML] filetype in search results</label>
|
||||
</li>
|
||||
<li class="form-check mb-1">
|
||||
<input type="checkbox" name="os_s_text_fragments" id="os_s_text_fragments" value="1" class="form-check-input"
|
||||
data-bs-toggle="tooltip" data-bs-placement="top" title="Use special links that try to highlight the first match of each term on the target page."<?php
|
||||
if ($_ODATA['s_text_fragments']) echo ' checked="checked"'; ?>>
|
||||
<label for="os_s_text_fragments" class="form-check-label">
|
||||
Use <a href="https://developer.mozilla.org/en-US/docs/Web/Text_fragments#:~:text=Text%20fragment" rel="noopener" target="_blank">text fragments</a> in result links
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -117,6 +117,7 @@ if (!in_array($_DDATA['tbprefix'].'config', $_DDATA['tables'], true)) {
|
|||
`s_weight_css` TEXT NOT NULL,
|
||||
`s_show_orphans` BOOLEAN NOT NULL,
|
||||
`s_show_filetype_html` BOOLEAN NOT NULL,
|
||||
`s_text_fragments` BOOLEAN NOT NULL,
|
||||
`s_charset` TINYTEXT NOT NULL,
|
||||
`s_result_template` TEXT NOT NULL,
|
||||
`s_limit_query_log` TINYINT UNSIGNED NOT NULL,
|
||||
|
@ -200,6 +201,7 @@ if (!count($testConf->fetchAll())) {
|
|||
`s_weight_css`=\'.important dt h1 h2 h3\',
|
||||
`s_show_orphans`=0,
|
||||
`s_show_filetype_html`=0,
|
||||
`s_text_fragments`=0,
|
||||
`s_charset`=\'UTF-8\',
|
||||
`s_result_template`=\'\',
|
||||
`s_limit_query_log`=14,
|
||||
|
|
|
@ -54,6 +54,7 @@ function os_page(content_mime, url, category, priority, last_modified, title, de
|
|||
this.content = content;
|
||||
|
||||
this.matchtext = [];
|
||||
this.fragment = [];
|
||||
|
||||
this.relevance = 0;
|
||||
this.multi = -1;
|
||||
|
@ -354,8 +355,11 @@ if (os_crawldata.length) {
|
|||
if (splitter.length == 1) {
|
||||
// Grab some random content if there were no
|
||||
// matches in the content
|
||||
let offset = Math.floor(Math.random() * os_sdata.results[x].content.length - {{s_limit_matchtext}});
|
||||
} else offset = Math.floor(Math.max(0, caret - (splitter[z].length + {{s_limit_matchtext}}) / 2));
|
||||
offset = Math.floor(Math.random() * os_sdata.results[x].content.length - {{s_limit_matchtext}});
|
||||
} else {
|
||||
os_sdata.results[x].fragment.push(splitter[z]);
|
||||
offset = Math.floor(Math.max(0, caret - (splitter[z].length + {{s_limit_matchtext}}) / 2));
|
||||
}
|
||||
let match = os_sdata.results[x].content.substring(offset, offset + {{s_limit_matchtext}}).trim();
|
||||
|
||||
// Add appropriate ellipses
|
||||
|
@ -484,6 +488,17 @@ if (os_crawldata.length) {
|
|||
}
|
||||
}
|
||||
|
||||
// Append text fragment(s) to the URL if applicable
|
||||
if ({{s_text_fragments}} && resultsPage[x].fragment.length) {
|
||||
resultsPage[x].fragment = resultsPage[x].fragment.filter(function(v, i, a) {
|
||||
return a.indexOf(v) === i;
|
||||
});
|
||||
resultsPage[x].fragment = resultsPage[x].fragment.map(function(x) {
|
||||
return x.replace(',', '%2C').replace('-', '%2D');
|
||||
});
|
||||
result.url += '#:~:text=' + resultsPage[x].fragment.join('&text=');
|
||||
}
|
||||
|
||||
os_TEMPLATE.searchable.searched.results.result_list.push(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -462,6 +462,7 @@ if ($_RDATA['s_searchable_pages']) {
|
|||
// proper match text for each
|
||||
foreach ($_SDATA['results'] as $key => $row) {
|
||||
$_SDATA['results'][$key]['matchtext'] = array();
|
||||
$_SDATA['results'][$key]['fragment'] = array();
|
||||
|
||||
// Add the page description to use as a default match text
|
||||
if (trim($row['description'])) {
|
||||
|
@ -495,7 +496,10 @@ if ($_RDATA['s_searchable_pages']) {
|
|||
// Grab some random content if there were no
|
||||
// matches in the content
|
||||
$offset = mt_rand(0, mb_strlen($row['content'], 'UTF-8') - $_ODATA['s_limit_matchtext']);
|
||||
} else $offset = floor(max(0, $split[1] - (mb_strlen($term, 'UTF-8') + $_ODATA['s_limit_matchtext']) / 2));
|
||||
} else {
|
||||
$_SDATA['results'][$key]['fragment'][] = $split[0];
|
||||
$offset = floor(max(0, $split[1] - (mb_strlen($term, 'UTF-8') + $_ODATA['s_limit_matchtext']) / 2));
|
||||
}
|
||||
$match = trim(mb_substr($row['content'], $offset, $_ODATA['s_limit_matchtext'], 'UTF-8'));
|
||||
|
||||
// Add appropriate ellipses
|
||||
|
@ -735,6 +739,14 @@ if ($_RDATA['s_searchable_pages']) {
|
|||
), true);
|
||||
}
|
||||
|
||||
// Append text fragment(s) to the URL if applicable
|
||||
if ($_ODATA['s_text_fragments'] && count($result['fragment'])) {
|
||||
$result['fragment'] = array_map(function($a) {
|
||||
return str_replace(array(',', '-'), array('%2C', '%2D'), urlencode($a));
|
||||
}, array_values(array_unique($result['fragment'])));
|
||||
$_RESULT->url .= '#:~:text='.implode('&text=', $result['fragment']);
|
||||
}
|
||||
|
||||
$_ORCINUS->searchable->searched->results->result_list[] = $_RESULT;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue