Replace tipuesearch's jQuery with a mix of JS and preact

This commit is contained in:
Stéphane Goetz 2019-09-18 23:16:35 +02:00
bovenliggende 75f34cae30
commit 194110ea6d
27 gewijzigde bestanden met toevoegingen van 3075 en 805 verwijderingen

4
.gitignore vendored
Bestand weergeven

@ -5,3 +5,7 @@ node_modules
static
/vendor
/prettier.config.js
/.eslintrc.js
/stylelint.config.js

Bestand weergeven

@ -22,7 +22,7 @@ COPY bin/ /daux/bin/
COPY libs/ /daux/libs/
COPY templates/ /daux/templates/
COPY themes/ /daux/themes/
COPY tipuesearch/ /daux/tipuesearch/
COPY search/ /daux/search/
COPY global.json /daux/global.json
COPY index.php /daux/index.php

Bestand weergeven

@ -1,48 +1,58 @@
module.exports = {
browsers: "> 0.25%, Edge >= 15, Safari >= 10, iOS >= 10, Chrome >= 56, Firefox >= 51, IE >= 11, not op_mini all",
browsers:
"> 0.25%, Edge >= 15, Safari >= 10, iOS >= 10, Chrome >= 56, Firefox >= 51, IE >= 11, not op_mini all",
presets: [
"@swissquote/crafty-preset-postcss",
"@swissquote/crafty-runner-gulp"
"@swissquote/crafty-preset-babel",
"@swissquote/crafty-runner-rollup",
"@swissquote/crafty-preset-postcss",
"@swissquote/crafty-runner-gulp"
],
destination_css: "themes",
destination_js: ".",
stylelint_pattern: [
"themes/daux/scss/**/*.scss",
"themes/daux_singlepage/scss/**/*.scss",
"!*.min.css",
"!**/vendor/**/*.scss"
"themes/daux/scss/**/*.scss",
"themes/daux_singlepage/scss/**/*.scss",
"!*.min.css",
"!**/vendor/**/*.scss"
],
stylelint: {
rules: {
"swissquote/no-type-outside-scope": null,
"plugin/no-unsupported-browser-features": null
}
rules: {
"swissquote/no-type-outside-scope": null,
"plugin/no-unsupported-browser-features": null
}
},
js: {
search: {
runner: "rollup",
source: "src/js/search/index.js",
destination: "search/search.min.js"
}
},
css: {
"theme_blue": {
source: "themes/daux/scss/theme-blue.scss",
destination: "daux/css/theme-blue.min.css",
watch: ["themes/daux/scss/**"]
},
"theme_green": {
source: "themes/daux/scss/theme-green.scss",
destination: "daux/css/theme-green.min.css",
watch: ["themes/daux/scss/**"]
},
"theme_navy": {
source: "themes/daux/scss/theme-navy.scss",
destination: "daux/css/theme-navy.min.css",
watch: ["themes/daux/scss/**"]
},
"theme_red": {
source: "themes/daux/scss/theme-red.scss",
destination: "daux/css/theme-red.min.css",
watch: ["themes/daux/scss/**"]
},
"daux_singlepage": {
source: "themes/daux_singlepage/scss/main.scss",
destination: "daux_singlepage/css/main.min.css",
watch: ["themes/daux_singlepage/scss/**"]
}
theme_blue: {
source: "themes/daux/scss/theme-blue.scss",
destination: "daux/css/theme-blue.min.css",
watch: ["themes/daux/scss/**"]
},
theme_green: {
source: "themes/daux/scss/theme-green.scss",
destination: "daux/css/theme-green.min.css",
watch: ["themes/daux/scss/**"]
},
theme_navy: {
source: "themes/daux/scss/theme-navy.scss",
destination: "daux/css/theme-navy.min.css",
watch: ["themes/daux/scss/**"]
},
theme_red: {
source: "themes/daux/scss/theme-red.scss",
destination: "daux/css/theme-red.min.css",
watch: ["themes/daux/scss/**"]
},
daux_singlepage: {
source: "themes/daux_singlepage/scss/main.scss",
destination: "daux_singlepage/css/main.min.css",
watch: ["themes/daux_singlepage/scss/**"]
}
}
};
};

Bestand weergeven

@ -74,11 +74,11 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
if ($params['html']['search']) {
GeneratorHelper::copyRecursive(
$this->daux->local_base . DIRECTORY_SEPARATOR . 'tipuesearch' . DIRECTORY_SEPARATOR,
$destination . DIRECTORY_SEPARATOR . 'tipuesearch'
$this->daux->local_base . DIRECTORY_SEPARATOR . 'search' . DIRECTORY_SEPARATOR,
$destination . DIRECTORY_SEPARATOR . 'search'
);
file_put_contents(
$destination . DIRECTORY_SEPARATOR . 'tipuesearch' . DIRECTORY_SEPARATOR . 'tipuesearch_content.json',
$destination . DIRECTORY_SEPARATOR . 'search' . DIRECTORY_SEPARATOR . 'search_index.json',
json_encode(['pages' => $this->indexed_pages])
);

Bestand weergeven

@ -4,8 +4,11 @@
"private": true,
"devDependencies": {
"@swissquote/crafty": "^1.7.3",
"@swissquote/crafty-preset-babel": "^1.8.0",
"@swissquote/crafty-preset-postcss": "^1.7.3",
"@swissquote/crafty-runner-gulp": "^1.7.3"
"@swissquote/crafty-runner-gulp": "^1.7.3",
"@swissquote/crafty-runner-rollup": "^1.8.0",
"preact": "^8.5.2"
},
"scripts": {
"build": "crafty run",

Bestand weergeven

@ -1,10 +1,3 @@
/*
Tipue Search 5.0
Copyright (c) 2015 Tipue
Tipue Search is released under the MIT License
http://www.tipue.com/search
*/
body.with-search {
overflow: hidden;
}
@ -16,7 +9,7 @@ body.with-search {
margin: 0;
z-index: 100;
position:absolute;
position: absolute;
top: 0;
left: 0;
bottom: 0;
@ -27,18 +20,17 @@ body.with-search {
.SearchResultsBackdrop {
z-index: 90;
width:100%;
width: 100%;
position:absolute;
position: absolute;
top: 0;
left: 0;
bottom: 0;
background: #000;
opacity: .6;
opacity: 0.6;
}
.homepage .SearchResults,
.homepage .SearchResultsBackdrop {
top: 50px;
@ -54,11 +46,12 @@ body.with-search {
}
.SearchResults__warning {
font-weight:300;
font-size:15px;
font-weight: 300;
font-size: 15px;
line-height: 1.6;
color: #555;
margin: 7px 0;
clear: both;
}
.SearchResults__warning a {
@ -71,8 +64,8 @@ body.with-search {
}
.SearchResults__count {
font-weight:300;
font-size:15px;
font-weight: 300;
font-size: 15px;
line-height: 1.7;
color: #555;
}
@ -86,12 +79,12 @@ body.with-search {
cursor: pointer;
padding: 0;
margin: 0;
line-height: .8em;
line-height: 0.8em;
}
.SearchResults__title {
font-weight:300;
font-size:21px;
font-weight: 300;
font-size: 21px;
line-height: 1.7;
margin-top: 23px;
}
@ -106,8 +99,8 @@ body.with-search {
}
.SearchResults__url {
font-weight:300;
font-size:14px;
font-weight: 300;
font-size: 14px;
line-height: 1.9;
word-wrap: break-word;
hyphens: auto;
@ -123,8 +116,8 @@ body.with-search {
}
.SearchResults__text {
font-weight:300;
font-size:15px;
font-weight: 300;
font-size: 15px;
line-height: 1.6;
color: #555;
word-wrap: break-word;
@ -133,8 +126,8 @@ body.with-search {
}
.SearchResults__debug {
font-weight:300;
font-size:13px;
font-weight: 300;
font-size: 13px;
line-height: 1.6;
color: #555;
margin: 5px 0;
@ -164,7 +157,6 @@ body.with-search {
border: 1px solid #e2e2e2;
}
/* spinner */
@media (min-width: 650px) {

2
search/search.min.js vendored Normal file

Bestand-diff onderdrukt omdat een of meer regels te lang zijn

1
search/search.min.js.map Normal file

Bestand-diff onderdrukt omdat een of meer regels te lang zijn

Bestand weergeven

@ -0,0 +1,64 @@
import preact from "preact";
import { textLinkPrevious, textLinkNext } from "./translation";
/** @jsx preact.h */
export default function Pagination({ counter, start, settings, onPageSelect }) {
const pages = Math.ceil(counter / settings.show);
const page = start / settings.show;
let displayedPages;
if (page <= 2) {
// Display max three pages
displayedPages = Math.min(pages, 3);
} else {
// Display two more pages, but don't overflow
displayedPages = Math.min(pages, page + 2);
}
const items = [];
for (let f = 0; f < displayedPages; f++) {
if (f === page) {
items.push(<li className="current">{f + 1}</li>);
} else {
items.push(
<li>
<a
className="SearchResults__footer__link"
onClick={() => onPageSelect(f * settings.show)}
>
{f + 1}
</a>
</li>
);
}
}
return (
<div className="SearchResults__footer">
<ul className="SearchResults__footer__links Pager">
{start > 0 && (
<li className="Pager--prev">
<a
className="SearchResults__footer__link"
onClick={() => onPageSelect(start - settings.show)}
>
{textLinkPrevious}
</a>
</li>
)}
{items}
{page + 1 !== pages && (
<li className="Pager--next">
<a
className="SearchResults__footer__link"
onClick={() => onPageSelect(start + settings.show)}
>
{textLinkNext}
</a>
</li>
)}
</ul>
</div>
);
}

55
src/js/search/Result.js Normal file
Bestand weergeven

@ -0,0 +1,55 @@
import preact from "preact";
/** @jsx preact.h */
// TODO :: restore highlight
/*function highlightText(search, text) {
if (settings.highlightTerms) {
var pattern = new RegExp(
`(${search})`,
settings.highlightEveryTerm ? "gi" : "i"
);
text = text.replace(
pattern,
'<span class="SearchResults__highlight">$1</span>'
);
}
return text;
}*/
export default function Result({ settings, item }) {
let description;
if (item.desc) {
description = item.desc
.split(" ")
.slice(0, settings.descriptiveWords)
.join(" ");
if (
item.desc.length < description.length &&
description.charAt(description.length - 1) !== "."
) {
description += " ...";
}
}
return (
<div className="SearchResult">
<div className="SearchResults__title">
<a href={settings.base_url + item.url}>{item.title}</a>
</div>
{settings.debug && (
<div className="SearchResults__debug">Score: {item.score}</div>
)}
{settings.showURL && (
<div className="SearchResults__url">
<a href={settings.base_url + item.url}>
{item.url.toLowerCase().replace(/https?:\/\//g, "")}
</a>
</div>
)}
{description.desc && (
<div className="SearchResults__text">{description}</div>
)}
</div>
);
}

161
src/js/search/Search.js Normal file
Bestand weergeven

@ -0,0 +1,161 @@
import preact from "preact";
import Pagination from "./Pagination";
import Result from "./Result";
import {
textSearchCommonWordsIgnored,
textSearchNoResults,
textSearchOneCharacterOrMore,
textSearchOneResult,
textSearchResults,
textSearchShouldBeXOrMore,
textSearchTooShort
} from "./translation";
import { getResults, getSearchString } from "./utils";
/** @jsx preact.h */
export default class Search extends preact.Component {
constructor(props) {
super(props);
this.state = {
search: this.props.settings.field.value || "",
start: 0
};
}
// "click", ".SearchResults__close"
handleClose = () => {
this.props.onClose();
};
scrollTop = () => {
if (this.resultRef) {
this.resultRef.scrollTop = 0;
}
};
handlePaginate = start => {
this.setState({ start }, this.scrollTop);
};
handleChange = event => {
this.setState({ search: event.target.value, start: 0 }, this.scrollTop);
this.props.settings.field.value = event.target.value;
};
getResults() {
const { settings, searchIndex } = this.props;
const { start } = this.state;
const searchString = getSearchString(
this.state.search.toLowerCase().trim()
);
const searchFor = searchString.searchFor;
const warnings = [];
let counter = 0;
let results = [];
if (searchFor.length < settings.minimumLength) {
if (searchString.hasStopWords) {
warnings.push(
`${textSearchNoResults}. ${textSearchCommonWordsIgnored}`
);
} else {
warnings.push(textSearchTooShort);
warnings.push(
settings.minimumLength === 1
? textSearchOneCharacterOrMore
: textSearchShouldBeXOrMore.replace(
"!min",
settings.minimumLength
)
);
}
return { warnings, counter, results, start };
}
const found = getResults(
searchIndex,
searchString.searchFor,
searchString.isStandard
);
counter = found.length;
if (counter === 0) {
warnings.push(textSearchNoResults);
return { warnings, counter, results, start };
}
if (settings.showTitleCount) {
this.props.onTitleChange(`(${counter})`);
}
results = found.filter(
(item, itemNumber) =>
itemNumber >= start && itemNumber < settings.show + start
);
return { warnings, counter, results, start };
}
render() {
const { settings } = this.props;
const { warnings, counter, results, start } = this.getResults();
return (
<div>
<div className="SearchResultsBackdrop" />
<div
className="SearchResults"
ref={el => (this.resultRef = el)}
>
<input
className="Search__field"
placeholder="Search..."
autoComplete="on"
autoSave="text_search"
type="search"
value={this.state.search}
onInput={this.handleChange}
/>
<button
className="SearchResults__close"
onClick={this.handleClose}
>
&times;
</button>
<div className="SearchResults__count">
{counter === 1
? textSearchOneResult
: textSearchResults.replace("!count", counter)}
</div>
{warnings.map(warning => (
<div key={warning} className="SearchResults__warning">
{warning}
</div>
))}
{results.map(result => (
<Result
key={result.title}
item={result}
settings={settings}
/>
))}
{counter > settings.show && (
<Pagination
counter={counter}
start={start}
settings={settings}
onPageSelect={this.handlePaginate}
/>
)}
</div>
</div>
);
}
}

118
src/js/search/index.js Normal file
Bestand weergeven

@ -0,0 +1,118 @@
import preact from "preact";
import Search from "./Search";
import { getURLP } from "./utils";
/** @jsx preact.h */
const originalTitle = document.title;
class SearchEngine {
constructor(options) {
this.settings = {
field: document.getElementById("search_input"),
show: 10,
showURL: true,
showTitleCount: true,
minimumLength: 3,
descriptiveWords: 25,
highlightTerms: true,
highlightEveryTerm: false,
contentLocation: "search/search_index.json",
debug: false,
...options
};
this.searchIndex = {
pages: []
};
}
loadData() {
if (!this.loadingPromise) {
this.loadingPromise = fetch(
this.settings.base_url + this.settings.contentLocation
)
.then(data => data.json())
.then(json => {
this.searchIndex = json;
});
}
return this.loadingPromise;
}
run() {
if (getURLP("q")) {
this.settings.field.value = getURLP("q");
this.loadData().then(() => {
this.displaySearch();
});
}
this.settings.field.addEventListener("keyup", event => {
// Start loading index once the user types text in the field, not before
this.loadData();
if (parseInt(event.keyCode, 10) === 13) {
this.loadData().then(() => {
this.displaySearch();
});
}
});
}
keyUpHandler = e => {
if (e.which === 27) {
//escape
this.handleClose();
}
};
handleClose = () => {
document.title = originalTitle;
document.removeEventListener("keyup", this.keyUpHandler);
document.body.classList.remove("with-search");
preact.render("", this.resultContainer, this.renderedElement);
this.resultContainer = null;
this.renderedElement = null;
};
displaySearch() {
if (!this.resultContainer) {
this.resultContainer = document.createElement("div");
document.body.appendChild(this.resultContainer);
}
document.addEventListener("keyup", this.keyUpHandler);
this.renderedElement = preact.render(
<Search
searchIndex={this.searchIndex}
onClose={this.handleClose}
onTitleChange={title => {
document.title = `${title} ${originalTitle}`;
}}
settings={this.settings}
/>,
this.resultContainer
);
document.body.classList.add("with-search");
document.body.scrollTop = 0;
}
}
// Main containers
function search(options) {
const instance = new SearchEngine(options);
instance.run();
}
// Declare globally
window.search = search;

177
src/js/search/stopwords.js Normal file
Bestand weergeven

@ -0,0 +1,177 @@
// Stop words (list from http://www.ranks.nl/stopwords)
export default [
"a",
"about",
"above",
"after",
"again",
"against",
"all",
"am",
"an",
"and",
"any",
"are",
"aren't",
"as",
"at",
"be",
"because",
"been",
"before",
"being",
"below",
"between",
"both",
"but",
"by",
"can't",
"cannot",
"could",
"couldn't",
"did",
"didn't",
"do",
"does",
"doesn't",
"doing",
"don't",
"down",
"during",
"each",
"few",
"for",
"from",
"further",
"had",
"hadn't",
"has",
"hasn't",
"have",
"haven't",
"having",
"he",
"he'd",
"he'll",
"he's",
"her",
"here",
"here's",
"hers",
"herself",
"him",
"himself",
"his",
"how",
"how's",
"i",
"i'd",
"i'll",
"i'm",
"i've",
"if",
"in",
"into",
"is",
"isn't",
"it",
"it's",
"its",
"itself",
"let's",
"me",
"more",
"most",
"mustn't",
"my",
"myself",
"no",
"nor",
"not",
"of",
"off",
"on",
"once",
"only",
"or",
"other",
"ought",
"our",
"ours",
"ourselves",
"out",
"over",
"own",
"same",
"shan't",
"she",
"she'd",
"she'll",
"she's",
"should",
"shouldn't",
"so",
"some",
"such",
"than",
"that",
"that's",
"the",
"their",
"theirs",
"them",
"themselves",
"then",
"there",
"there's",
"these",
"they",
"they'd",
"they'll",
"they're",
"they've",
"this",
"those",
"through",
"to",
"too",
"under",
"until",
"up",
"very",
"was",
"wasn't",
"we",
"we'd",
"we'll",
"we're",
"we've",
"were",
"weren't",
"what",
"what's",
"when",
"when's",
"where",
"where's",
"which",
"while",
"who",
"who's",
"whom",
"why",
"why's",
"with",
"won't",
"would",
"wouldn't",
"you",
"you'd",
"you'll",
"you're",
"you've",
"your",
"yours",
"yourself",
"yourselves"
];

Bestand weergeven

@ -0,0 +1,35 @@
/* eslint-disable camelcase */
const {
Link_previous,
Link_next,
Search_common_words_ignored,
Search_no_results,
Search_one_character_or_more,
Search_one_result,
Search_results,
Search_should_be_x_or_more,
Search_too_short
} = window.searchTranslation;
const textLinkPrevious = Link_previous;
const textLinkNext = Link_next;
const textSearchCommonWordsIgnored = Search_common_words_ignored;
const textSearchNoResults = Search_no_results;
const textSearchOneCharacterOrMore = Search_one_character_or_more;
const textSearchOneResult = Search_one_result;
const textSearchResults = Search_results;
const textSearchShouldBeXOrMore = Search_should_be_x_or_more;
const textSearchTooShort = Search_too_short;
/* eslint-enable camelcase */
export {
textLinkPrevious,
textLinkNext,
textSearchCommonWordsIgnored,
textSearchNoResults,
textSearchOneCharacterOrMore,
textSearchOneResult,
textSearchResults,
textSearchShouldBeXOrMore,
textSearchTooShort
};

120
src/js/search/utils.js Normal file
Bestand weergeven

@ -0,0 +1,120 @@
import stopWords from "./stopwords";
export function getURLP(name) {
const elements = new RegExp(`[?|&]${name}=([^&;]+?)(&|#|;|$)`).exec(
window.location.search
);
return (
decodeURIComponent(
((elements && elements[1]) || "").replace(/\+/g, "%20")
) || null
);
}
function getScore(searchFor, page) {
let score = 0;
const pat = new RegExp(searchFor, "gi");
if (page.title.search(pat) !== -1) {
score += 20 * page.title.match(pat).length;
}
if (page.text.search(pat) !== -1) {
score += 20 * page.text.match(pat).length;
}
if (page.tags.search(pat) !== -1) {
score += 10 * page.tags.match(pat).length;
}
if (page.url.search(pat) !== -1) {
score += 20;
}
return score;
}
function getStandardScore(searchWords, page) {
let score = 0;
for (let f = 0; f < searchWords.length; f++) {
if (searchWords[f].match("^-")) {
const pat = new RegExp(searchWords[f].substring(1), "i");
if (
page.title.search(pat) !== -1 ||
page.text.search(pat) !== -1 ||
page.tags.search(pat) !== -1
) {
score = 0;
}
} else {
score += getScore(searchWords[f], page);
}
}
return score;
}
export function getSearchString(search) {
let isStandard = true;
let hasStopWords = false;
if (
(search.match('^"') && search.match('"$')) ||
(search.match("^'") && search.match("'$"))
) {
isStandard = false;
}
let searchFor;
if (isStandard) {
const searchWords = search.split(" ");
searchFor = searchWords
.filter(word => stopWords.indexOf(word) === -1)
.join(" ");
hasStopWords = search !== searchFor;
} else {
searchFor = searchFor.substring(1, searchFor.length - 1);
}
return {
hasStopWords,
isStandard,
searchFor
};
}
function makeResult(score, { title, url }, desc) {
return {
score,
title,
desc,
url
};
}
export function getResults(index, searchFor, standard) {
const found = [];
let pages = index.pages;
// If a searchLanguage is set, filter out all other pages
if (window.searchLanguage) {
pages = pages.filter(
item => item.url.indexOf(`${window.searchLanguage}/`) === 0
);
}
const searchWords = searchFor.split(" ");
for (let i = 0; i < pages.length; i++) {
const score = standard
? getStandardScore(searchWords, pages[i])
: getScore(searchFor, pages[i]);
if (score !== 0) {
found.push(makeResult(score, pages[i], pages[i].text));
}
}
found.sort((a, b) => b.score - a.score);
return found;
}

Bestand weergeven

@ -40,8 +40,8 @@
} ?>
<?php if ($params['html']['search']) { ?>
<!-- Tipue Search -->
<link href="<?= $base_url; ?>tipuesearch/tipuesearch.css" rel="stylesheet">
<!-- Search -->
<link href="<?= $base_url; ?>search/search.css" rel="stylesheet">
<?php } ?>
</head>
<body class="<?= $params['html']['float'] ? 'with-float' : ''; ?> <?= $this->section('classes'); ?>">

Bestand weergeven

@ -5,7 +5,7 @@
<svg class="Search__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 451 451">
<path d="M447.05 428l-109.6-109.6c29.4-33.8 47.2-77.9 47.2-126.1C384.65 86.2 298.35 0 192.35 0 86.25 0 .05 86.3.05 192.3s86.3 192.3 192.3 192.3c48.2 0 92.3-17.8 126.1-47.2L428.05 447c2.6 2.6 6.1 4 9.5 4s6.9-1.3 9.5-4c5.2-5.2 5.2-13.8 0-19zM26.95 192.3c0-91.2 74.2-165.3 165.3-165.3 91.2 0 165.3 74.2 165.3 165.3s-74.1 165.4-165.3 165.4c-91.1 0-165.3-74.2-165.3-165.4z"/>
</svg>
<input type="search" id="tipue_search_input" class="Search__field" placeholder="<?=$this->translate("Search_placeholder") ?>" autocomplete="on"
<input type="search" id="search_input" class="Search__field" placeholder="<?=$this->translate("Search_placeholder") ?>" autocomplete="on"
results=25 autosave=text_search>
</div>
<?php } ?>

Bestand weergeven

@ -22,16 +22,10 @@
window.searchTranslation = <?= json_encode($search_translations) ?>;
</script>
<!-- Tipue Search -->
<script type="text/javascript" src="<?php echo $base_url; ?>tipuesearch/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="<?php echo $base_url; ?>tipuesearch/tipuesearch.js"></script>
<!-- Search -->
<script type="text/javascript" src="<?php echo $base_url; ?>search/search.min.js"></script>
<script>
window.onunload = function(){}; // force $(document).ready to be called on back/forward navigation in firefox
$(function() {
tipuesearch({
'base_url': '<?php echo $base_url?>'
});
});
window.search({'base_url': '<?php echo $base_url?>'})
</script>
<?php } ?>

Bestand-diff onderdrukt omdat een of meer regels te lang zijn

Bestand-diff onderdrukt omdat een of meer regels te lang zijn

Bestand-diff onderdrukt omdat een of meer regels te lang zijn

Bestand-diff onderdrukt omdat een of meer regels te lang zijn

Bestand weergeven

@ -144,6 +144,8 @@ Components
vertical-align: middle;
}
}
/* stylelint-disable-next-line selector-class-pattern */
.no-js .CodeToggler {
display: none;
}
@ -199,6 +201,7 @@ Components
.Nav .Nav {
margin-left: 15px;
/* stylelint-disable-next-line selector-class-pattern */
html:not(.no-js) & {
height: 0;
transition: height 400ms ease-in-out;

Bestand weergeven

@ -43,6 +43,7 @@ body {
@media (max-width: 768px) {
// mobile friendly sub-nav
/* stylelint-disable-next-line selector-class-pattern */
html:not(.no-js) .Collapsible__content {
height: 0;
overflow: hidden;

Bestand-diff onderdrukt omdat een of meer regels te lang zijn

Bestand weergeven

@ -1,374 +0,0 @@
/*
Tipue Search 5.0
Copyright (c) 2015 Tipue
Tipue Search is released under the MIT License
http://www.tipue.com/search
*/
(function ($) {
var originalTitle = document.title;
// Stop words (list from http://www.ranks.nl/stopwords)
var tipuesearch_stop_words = ["a", "about", "above", "after", "again", "against", "all", "am", "an", "and", "any", "are", "aren't", "as", "at", "be", "because", "been", "before", "being", "below", "between", "both", "but", "by", "can't", "cannot", "could", "couldn't", "did", "didn't", "do", "does", "doesn't", "doing", "don't", "down", "during", "each", "few", "for", "from", "further", "had", "hadn't", "has", "hasn't", "have", "haven't", "having", "he", "he'd", "he'll", "he's", "her", "here", "here's", "hers", "herself", "him", "himself", "his", "how", "how's", "i", "i'd", "i'll", "i'm", "i've", "if", "in", "into", "is", "isn't", "it", "it's", "its", "itself", "let's", "me", "more", "most", "mustn't", "my", "myself", "no", "nor", "not", "of", "off", "on", "once", "only", "or", "other", "ought", "our", "ours", "ourselves", "out", "over", "own", "same", "shan't", "she", "she'd", "she'll", "she's", "should", "shouldn't", "so", "some", "such", "than", "that", "that's", "the", "their", "theirs", "them", "themselves", "then", "there", "there's", "these", "they", "they'd", "they'll", "they're", "they've", "this", "those", "through", "to", "too", "under", "until", "up", "very", "was", "wasn't", "we", "we'd", "we'll", "we're", "we've", "were", "weren't", "what", "what's", "when", "when's", "where", "where's", "which", "while", "who", "who's", "whom", "why", "why's", "with", "won't", "would", "wouldn't", "you", "you'd", "you'll", "you're", "you've", "your", "yours", "yourself", "yourselves"];
// Internal strings
var tipuesearch_string_one_result = window.searchTranslation.Search_one_result;
var tipuesearch_string_results = window.searchTranslation.Search_results;
var tipuesearch_string_prev = window.searchTranslation.Link_previous;
var tipuesearch_string_next = window.searchTranslation.Link_next;
var tipuesearch_string_no_results = window.searchTranslation.Search_no_results;
var tipuesearch_string_common_words_ignored = window.searchTranslation.Search_common_words_ignored;
var tipuesearch_string_too_short = window.searchTranslation.Search_too_short;
var tipuesearch_string_one_character_or_more = window.searchTranslation.Search_one_character_or_more;
var tipuesearch_string_should_be_x_or_more = window.searchTranslation.Search_should_be_x_or_more;
// Main containers
var tipue_container, tipue_backdrop;
function getURLP(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [, ""])[1].replace(/\+/g, '%20')) || null;
}
function closeSearch() {
document.title = originalTitle;
$(document).off("keyup", keyUpHandler);
$("body").removeClass("with-search");
tipue_container.hide();
tipue_backdrop.hide();
}
function keyUpHandler(e) {
if (e.which == 27) { //escape
closeSearch();
}
}
function getSearchString(searchFor) {
var standard = true;
var hasStopWords = false;
if ((searchFor.match("^\"") && searchFor.match("\"$")) || (searchFor.match("^'") && searchFor.match("'$"))) {
standard = false;
}
if (standard) {
var d_w = searchFor.split(' ');
searchFor = '';
for (var i = 0; i < d_w.length; i++) {
var isStopWord = false;
for (var f = 0; f < tipuesearch_stop_words.length; f++) {
if (d_w[i] == tipuesearch_stop_words[f]) {
isStopWord = true;
hasStopWords = true;
}
}
if (!isStopWord) {
searchFor = searchFor + ' ' + d_w[i];
}
}
searchFor = $.trim(searchFor);
} else {
searchFor = searchFor.substring(1, searchFor.length - 1);
}
return {
hasStopWords: hasStopWords,
isStandard: standard,
searchFor: searchFor
};
}
function getScore(searchFor, page) {
var score = 0;
var pat = new RegExp(searchFor, 'gi');
if (page.title.search(pat) != -1) {
score += (20 * page.title.match(pat).length);
}
if (page.text.search(pat) != -1) {
score += (20 * page.text.match(pat).length);
}
if (page.tags.search(pat) != -1) {
score += (10 * page.tags.match(pat).length);
}
if (page.url.search(pat) != -1) {
score += 20;
}
return score;
}
function makeResult(score, page, text) {
return {
"score": score,
"title": page.title,
"desc": text,
"url": page.url
}
}
window.tipuesearch = function (options) {
var settings = $.extend(
{
'field': $('#tipue_search_input'),
'show': 10,
'showURL': true,
'showTitleCount': true,
'minimumLength': 3,
'descriptiveWords': 25,
'highlightTerms': true,
'highlightEveryTerm': false,
'contentLocation': 'tipuesearch/tipuesearch_content.json',
'debug': false
}, options);
var tipuesearch_in = {
pages: []
};
$.ajax(
{
dataType: "json",
url: settings.base_url + settings.contentLocation,
async: false
})
.done(
function (json) {
tipuesearch_in = $.extend({}, json);
});
if (getURLP('q')) {
settings.field.val(getURLP('q'));
getTipueSearch(0, true);
}
settings.field.keyup(
function (event) {
if (event.keyCode == '13') {
getTipueSearch(0, true);
}
});
function highlightText(search, text) {
if (settings.highlightTerms) {
var pattern = new RegExp('(' + search + ')', settings.highlightEveryTerm ? 'gi' : 'i');
text = text.replace(pattern, "<span class=\"SearchResults__highlight\">$1</span>");
}
return text;
}
function getResults(searchFor, standard) {
var found = [];
var pages = tipuesearch_in.pages;
// If a searchLanguage is set, filter out all other pages
if (window.searchLanguage) {
pages = pages.filter(function(item) {
return item.url.indexOf(window.searchLanguage + "/") === 0;
})
}
if (standard) {
var d_w = searchFor.split(' ');
for (var i = 0; i < pages.length; i++) {
var score = 0;
var text = pages[i].text;
for (var f = 0; f < d_w.length; f++) {
if (d_w[f].match('^-')) {
var pat = new RegExp(d_w[f].substring(1), 'i');
if (pages[i].title.search(pat) != -1 || pages[i].text.search(pat) != -1 || pages[i].tags.search(pat) != -1) {
score = 0;
}
} else {
score += getScore(d_w[f], pages[i]);
text = highlightText(d_w[f], text);
}
}
if (score != 0) {
found.push(makeResult(score, pages[i], text));
}
}
} else {
for (var i = 0; i < pages.length; i++) {
var score = getScore(searchFor, pages[i]);
if (score != 0) {
found.push(makeResult(score, pages[i], highlightText(searchFor, pages[i].text)));
}
}
}
found.sort(function (a, b) {
return b.score - a.score
});
return found
}
function getTipueSearch(start, replace) {
if (!tipue_container) {
tipue_container = $(document.createElement("div"));
tipue_container.addClass('SearchResults');
document.body.appendChild(tipue_container.get(0));
tipue_backdrop = $(document.createElement("div"));
tipue_backdrop.addClass("SearchResultsBackdrop");
document.body.appendChild(tipue_backdrop.get(0));
tipue_container.on('click', '.SearchResults__close', closeSearch);
tipue_container.on('click', '.SearchResults__footer__link', function () {
var id_v = $(this).attr('id');
var id_a = id_v.split('_');
getTipueSearch(parseInt(id_a[0]), id_a[1]);
tipue_container.scrollTop(0);
});
tipue_container.on('keyup paste', '.Search__field', function(event) {
settings.field.val($(this).val());
if (event.keyCode == '13') {
getTipueSearch(0, true);
}
})
}
$(document).keyup(keyUpHandler);
var output = '<input class="Search__field" placeholder="Search..." autocomplete="on" autosave="text_search" type="search" value="'+ settings.field.val() +'"><button class=SearchResults__close>&times;</button>';
var search = getSearchString($.trim(settings.field.val().toLowerCase()));
var searchFor = search.searchFor;
if (searchFor.length >= settings.minimumLength) {
var found = getResults(search.searchFor, search.isStandard);
var counter = found.length;
if (counter == 0) {
output += '<div class=SearchResults__warning>' + tipuesearch_string_no_results + '</div>';
} else {
if (settings.showTitleCount) {
document.title = '(' + counter + ') ' + originalTitle;
}
if (counter == 1) {
output += '<div class="SearchResults__count">' + tipuesearch_string_one_result + '</div>';
} else {
output += '<div class="SearchResults__count">' + tipuesearch_string_results.replace('!count', counter) + '</div>';
}
var l_o = 0;
for (var i = 0; i < found.length; i++) {
if (l_o >= start && l_o < settings.show + start) {
output += '<div class="SearchResults__title"><a href="' + settings.base_url + found[i].url + '"' + '>' + found[i].title + '</a></div>';
if (settings.debug) {
output += '<div class="SearchResults__debug">Score: ' + found[i].score + '</div>';
}
if (settings.showURL) {
var s_u = found[i].url.toLowerCase();
if (s_u.indexOf('http://') == 0) {
s_u = s_u.slice(7);
}
output += '<div class="SearchResults__url"><a href="' + settings.base_url + found[i].url + '"' + '>' + s_u + '</a></div>';
}
if (found[i].desc) {
var t = found[i].desc;
var t_d = '';
var t_w = t.split(' ');
if (t_w.length < settings.descriptiveWords) {
t_d = t;
} else {
for (var f = 0; f < settings.descriptiveWords; f++) {
t_d += t_w[f] + ' ';
}
}
t_d = $.trim(t_d);
if (t_d.charAt(t_d.length - 1) != '.') {
t_d += ' ...';
}
output += '<div class="SearchResults__text">' + t_d + '</div>';
}
}
l_o++;
}
if (counter > settings.show) {
var pages = Math.ceil(counter / settings.show);
var page = (start / settings.show);
output += '<div class="SearchResults__footer"><ul class="SearchResults__footer__links Pager">';
if (start > 0) {
output += '<li class="Pager--prev"><a class="SearchResults__footer__link" id="' + (start - settings.show) + '_' + replace + '">' + tipuesearch_string_prev + '</a></li>';
}
if (page <= 2) {
var p_b = pages;
if (pages > 3) {
p_b = 3;
}
for (var f = 0; f < p_b; f++) {
if (f == page) {
output += '<li class="current">' + (f + 1) + '</li>';
} else {
output += '<li><a class="SearchResults__footer__link" id="' + (f * settings.show) + '_' + replace + '">' + (f + 1) + '</a></li>';
}
}
} else {
var p_b = page + 2;
if (p_b > pages) {
p_b = pages;
}
for (var f = page - 1; f < p_b; f++) {
if (f == page) {
output += '<li class="current">' + (f + 1) + '</li>';
} else {
output += '<li><a class="SearchResults__footer__link" id="' + (f * settings.show) + '_' + replace + '">' + (f + 1) + '</a></li>';
}
}
}
if (page + 1 != pages) {
output += '<li class="Pager--next"><a class="SearchResults__footer__link" id="' + (start + settings.show) + '_' + replace + '">' + tipuesearch_string_next + '</a></li>';
}
output += '</ul></div>';
}
}
} else {
if (search.hasStopWords) {
output += '<div class=SearchResults__warning>' + tipuesearch_string_no_results + '. ' + tipuesearch_string_common_words_ignored + '</div>';
} else {
output += '<div class=SearchResults__warning>' + tipuesearch_string_too_short + '</div>';
if (settings.minimumLength == 1) {
output += '<div class=SearchResults__warning>' + tipuesearch_string_one_character_or_more + '</div>';
} else {
output += '<div class=SearchResults__warning>' + tipuesearch_string_should_be_x_or_more.replace("!min", settings.minimumLength) + '</div>';
}
}
}
$("body").addClass("with-search").scrollTop(0);
tipue_backdrop.show();
tipue_container.scrollTop(0);
tipue_container.show().html(output);
}
};
})(jQuery);

2591
yarn.lock

Diff onderdrukt omdat het te groot bestand Laad Diff