diff --git a/.travis.sh b/.travis.sh deleted file mode 100755 index 3ea115f69..000000000 --- a/.travis.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016-2019 Martin Donath - -# 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} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index da748c8d8..000000000 --- a/.travis.yml +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2016-2019 Martin Donath - -# 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 diff --git a/material/base.html b/material/base.html index bda8023b4..ecbd6c7ff 100644 --- a/material/base.html +++ b/material/base.html @@ -226,6 +226,7 @@ "search.language", "search.pipeline.stopwords", "search.pipeline.trimmer", + "search.placeholder", "search.result.none", "search.result.one", "search.result.other", diff --git a/src/assets/javascripts/actions/search/result/index.ts b/src/assets/javascripts/actions/search/result/index.ts index 2696d2a8a..ba17f8cb6 100644 --- a/src/assets/javascripts/actions/search/result/index.ts +++ b/src/assets/javascripts/actions/search/result/index.ts @@ -20,10 +20,41 @@ * IN THE SOFTWARE. */ +import { translate } from "utilities" + /* ---------------------------------------------------------------------------- * 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 * diff --git a/src/assets/javascripts/components/search/result/index.ts b/src/assets/javascripts/components/search/result/index.ts index 1ad954155..2c6e85bc0 100644 --- a/src/assets/javascripts/components/search/result/index.ts +++ b/src/assets/javascripts/components/search/result/index.ts @@ -35,10 +35,15 @@ import { mapTo, observeOn, scan, - switchMap + switchMap, + tap } from "rxjs/operators" -import { addToSearchResultList, resetSearchResultList } from "actions" +import { + addToSearchResultList, + resetSearchResultList, + setSearchResultMeta +} from "actions" import { SearchResult } from "modules" import { renderSearchResult } from "templates" import { ViewportSize, watchElementOffset } from "utilities" @@ -81,6 +86,13 @@ export function paintSearchResult( /* Paint search results lazily */ const [meta, list] = Array.from(el.children) as HTMLElement[] return pipe( + + /* Paint search result metadata */ + tap(result => { + setSearchResultMeta(meta, result.length) + }), + + /* Paint search result list */ switchMap(result => render$ .pipe( diff --git a/src/assets/javascripts/extensions/jsx/index.ts b/src/assets/javascripts/extensions/jsx/index.ts index 337ef8af2..5af9143b0 100644 --- a/src/assets/javascripts/extensions/jsx/index.ts +++ b/src/assets/javascripts/extensions/jsx/index.ts @@ -38,7 +38,7 @@ type Attributes = /** * Child element */ -type Child = Child[] | Element | Text | string | number +type Child = Child[] | HTMLElement | Text | string | number /* ---------------------------------------------------------------------------- * Helper functions @@ -47,10 +47,10 @@ type Child = Child[] | Element | Text | string | number /** * Append a child node to an element * - * @param el - Element + * @param el - HTML element * @param child - Child node */ -function appendChild(el: Element, child: Child): void { +function appendChild(el: HTMLElement, child: Child): void { /* Handle primitive types (including raw HTML) */ if (typeof child === "string" || typeof child === "number") { @@ -78,12 +78,12 @@ function appendChild(el: Element, child: Child): void { * @param attributes - HTML attributes * @param children - Child elements * - * @return Element + * @return HTML element */ export function h( tag: string, attributes: Attributes | null, - ...children: Array -): Element { + ...children: Array +): HTMLElement { const el = document.createElement(tag) /* Set attributes, if any */ @@ -107,9 +107,9 @@ export function h( * * @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! } diff --git a/src/assets/javascripts/utilities/string/index.ts b/src/assets/javascripts/utilities/string/index.ts index 098b8c6b7..4f8704c04 100644 --- a/src/assets/javascripts/utilities/string/index.ts +++ b/src/assets/javascripts/utilities/string/index.ts @@ -20,6 +20,17 @@ * IN THE SOFTWARE. */ +import { getElement } from "../agent" + +/* ---------------------------------------------------------------------------- + * Data + * ------------------------------------------------------------------------- */ + +/** + * Translations + */ +let lang: Record + /* ---------------------------------------------------------------------------- * Functions * ------------------------------------------------------------------------- */ @@ -27,16 +38,37 @@ /** * 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 * - * @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 - if (string.length > i) { - while (string[i] !== " " && --i > 0); // tslint:disable-line - return `${string.substring(0, i)}...` + if (value.length > i) { + while (value[i] !== " " && --i > 0); // tslint:disable-line + 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] } diff --git a/src/base.html b/src/base.html index 9ab6cdd79..305885bf9 100644 --- a/src/base.html +++ b/src/base.html @@ -429,6 +429,7 @@ "search.language", "search.pipeline.stopwords", "search.pipeline.trimmer", + "search.placeholder", "search.result.none", "search.result.one", "search.result.other",