Added search result metadata

This commit is contained in:
squidfunk 2019-12-19 14:44:22 +01:00
parent a18ac26f59
commit 87e3bc2410
8 changed files with 94 additions and 133 deletions

View File

@ -1,63 +0,0 @@
#!/bin/bash
# Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
# Exit, if one command fails
set -e
# Deploy documentation to GitHub pages
if [ "$TRAVIS_BRANCH" == "master" -a "$TRAVIS_PULL_REQUEST" == "false" ]; then
REMOTE="https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material"
# Set configuration for repository and deploy documentation
git config --global user.name "${GH_NAME}"
git config --global user.email "${GH_EMAIL}"
git remote set-url origin ${REMOTE}
# Install Material, so we can use it as a base template and add overrides
python setup.py install
# Build documentation with overrides and publish to GitHub pages
mkdocs gh-deploy --force
mkdocs --version
fi
# Terminate if we're not on a release branch
echo "${TRAVIS_BRANCH}" | grep -qvE "^[0-9.]+$" && exit 0; :;
# Install dependencies for release build
pip install --upgrade setuptools wheel twine
# Build and install theme and Docker image
python setup.py build sdist bdist_wheel --universal
docker build -t ${TRAVIS_REPO_SLUG} .
# Test Docker image build
docker run --rm -it -v $(pwd):/docs ${TRAVIS_REPO_SLUG} build --theme material
# Push release to PyPI
twine upload -u ${PYPI_USERNAME} -p ${PYPI_PASSWORD} dist/*
# Push image to Docker Hub
docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD}
docker tag ${TRAVIS_REPO_SLUG} ${TRAVIS_REPO_SLUG}:${TRAVIS_BRANCH}
docker tag ${TRAVIS_REPO_SLUG} ${TRAVIS_REPO_SLUG}:latest
docker push ${TRAVIS_REPO_SLUG}

View File

@ -1,53 +0,0 @@
# Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
language: python
sudo: false
# Python, Node.js version and necessary services
python: "3.6"
node_js: "10"
services:
- docker
# Limit clone depth to 5, to speed up build
git:
depth: 5
# Cache dependencies
cache:
pip: true
directories:
- node_modules
# Install dependencies
install:
- npm install
- pip install -r requirements.txt
# Perform build and release
script:
# - npm run lint
- npm run clean
- npm run build
# Deploy artifacts
after_success:
- ./.travis.sh

View File

@ -226,6 +226,7 @@
"search.language", "search.language",
"search.pipeline.stopwords", "search.pipeline.stopwords",
"search.pipeline.trimmer", "search.pipeline.trimmer",
"search.placeholder",
"search.result.none", "search.result.none",
"search.result.one", "search.result.one",
"search.result.other", "search.result.other",

View File

@ -20,10 +20,41 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
import { translate } from "utilities"
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* Functions * Functions
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
/**
* Set number of search results
*
* @param el - Search result metadata element
* @param value - Number of results
*/
export function setSearchResultMeta(
el: HTMLElement, value: number
): void {
el.textContent = value > 1
? translate("search.result.other", value.toString())
: value === 1
? translate("search.result.one")
: translate("search.result.none")
}
/**
* Reset number of search results
*
* @param el - Search result metadata element
*/
export function resetSearchResultMeta(
el: HTMLElement
): void {
el.textContent = translate("search.placeholder")
}
/* ------------------------------------------------------------------------- */
/** /**
* Add an element to the search result list * Add an element to the search result list
* *

View File

@ -35,10 +35,15 @@ import {
mapTo, mapTo,
observeOn, observeOn,
scan, scan,
switchMap switchMap,
tap
} from "rxjs/operators" } from "rxjs/operators"
import { addToSearchResultList, resetSearchResultList } from "actions" import {
addToSearchResultList,
resetSearchResultList,
setSearchResultMeta
} from "actions"
import { SearchResult } from "modules" import { SearchResult } from "modules"
import { renderSearchResult } from "templates" import { renderSearchResult } from "templates"
import { ViewportSize, watchElementOffset } from "utilities" import { ViewportSize, watchElementOffset } from "utilities"
@ -81,6 +86,13 @@ export function paintSearchResult(
/* Paint search results lazily */ /* Paint search results lazily */
const [meta, list] = Array.from(el.children) as HTMLElement[] const [meta, list] = Array.from(el.children) as HTMLElement[]
return pipe( return pipe(
/* Paint search result metadata */
tap(result => {
setSearchResultMeta(meta, result.length)
}),
/* Paint search result list */
switchMap(result => render$ switchMap(result => render$
.pipe( .pipe(

View File

@ -38,7 +38,7 @@ type Attributes =
/** /**
* Child element * Child element
*/ */
type Child = Child[] | Element | Text | string | number type Child = Child[] | HTMLElement | Text | string | number
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* Helper functions * Helper functions
@ -47,10 +47,10 @@ type Child = Child[] | Element | Text | string | number
/** /**
* Append a child node to an element * Append a child node to an element
* *
* @param el - Element * @param el - HTML element
* @param child - Child node * @param child - Child node
*/ */
function appendChild(el: Element, child: Child): void { function appendChild(el: HTMLElement, child: Child): void {
/* Handle primitive types (including raw HTML) */ /* Handle primitive types (including raw HTML) */
if (typeof child === "string" || typeof child === "number") { if (typeof child === "string" || typeof child === "number") {
@ -78,12 +78,12 @@ function appendChild(el: Element, child: Child): void {
* @param attributes - HTML attributes * @param attributes - HTML attributes
* @param children - Child elements * @param children - Child elements
* *
* @return Element * @return HTML element
*/ */
export function h( export function h(
tag: string, attributes: Attributes | null, tag: string, attributes: Attributes | null,
...children: Array<Element | Text | string | number> ...children: Array<HTMLElement | Text | string | number>
): Element { ): HTMLElement {
const el = document.createElement(tag) const el = document.createElement(tag)
/* Set attributes, if any */ /* Set attributes, if any */
@ -107,9 +107,9 @@ export function h(
* *
* @param el - JSX element * @param el - JSX element
* *
* @return Element * @return HTML element
*/ */
export function toElement(el: JSXInternal.Element): Element { export function toHTMLElement(el: JSXInternal.Element): HTMLElement {
return el as any // Hack: if you have a better idea, PR! return el as any // Hack: if you have a better idea, PR!
} }

View File

@ -20,6 +20,17 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
import { getElement } from "../agent"
/* ----------------------------------------------------------------------------
* Data
* ------------------------------------------------------------------------- */
/**
* Translations
*/
let lang: Record<string, string>
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* Functions * Functions
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
@ -27,16 +38,37 @@
/** /**
* Truncate a string after the given number of characters * Truncate a string after the given number of characters
* *
* @param string - String to be truncated * @param value - Value to be truncated
* @param n - Number of characters * @param n - Number of characters
* *
* @return Truncated string * @return Truncated value
*/ */
export function truncate(string: string, n: number): string { export function truncate(value: string, n: number): string {
let i = n let i = n
if (string.length > i) { if (value.length > i) {
while (string[i] !== " " && --i > 0); // tslint:disable-line while (value[i] !== " " && --i > 0); // tslint:disable-line
return `${string.substring(0, i)}...` return `${value.substring(0, i)}...`
} }
return string return value
}
/**
* Translate the given key
*
* @param key - Key to be translated
* @param value - Value to be replaced
*
* @return Translation
*/
export function translate(key: string, value?: string): string {
if (typeof lang === "undefined") {
const el = getElement("#__lang")!
lang = JSON.parse(el.innerText)
}
if (typeof lang[key] === "undefined") {
throw new ReferenceError(`Invalid translation: ${key}`)
}
return typeof value !== "undefined"
? lang[key].replace("#", value)
: lang[key]
} }

View File

@ -429,6 +429,7 @@
"search.language", "search.language",
"search.pipeline.stopwords", "search.pipeline.stopwords",
"search.pipeline.trimmer", "search.pipeline.trimmer",
"search.placeholder",
"search.result.none", "search.result.none",
"search.result.one", "search.result.one",
"search.result.other", "search.result.other",