Skip to content

Commit

Permalink
Documentation update
Browse files Browse the repository at this point in the history
  • Loading branch information
rosskouk committed Oct 22, 2022
1 parent 1b31056 commit 672ce84
Show file tree
Hide file tree
Showing 9 changed files with 433 additions and 163 deletions.
19 changes: 12 additions & 7 deletions docs/_sources/index.rst.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,21 @@ The following control intents are also supported:

Due to the way that Alexa skills operate there are some limitations. Full music Alexa skills require a catalog of content to be provided and this defeats
the purpose of being able to search and stream from your own server directly. Because of this a custom skill type is used along with the AudioPlayer interface,
but this has some limitations:
but this has some limitations in how the skill is invoked.

1. You need to open the skill to use it, say *Alexa, open Navisonic*.
2. Some intents that you would expect to be able to use when a track is playing need a full skill invocation. For example if you want to get
information on the track that is playing you will need to invoke the skill and call the intent by saying the following while the track is playing:
The following voice commands should be successful (thanks to Raul824)

- Alexa, open Navisonic
- What is playing?
- Alexa ask Navisonic What is Playing?
- Alexa ask Navisonic to star this song.
- Alexa ask Navisonic to unstar this song.
- Alexa ask Navisonic to play rock music
- Alexa ask Navisonic to play playlist "Playlist Name"

You will then be given information about the current track and it will automatically resume. This is also required for the *star* and *unstar* intents.
If you have any problems with these, you can open the skill manually with *Alexa, open Navisonic*. Similarly this can be done when a track is playing, for example
if you want to get information on the track that is playing you will need to invoke the skill and call the intent by saying the following while the track is playing:

- Alexa, open Navisonic
- What is playing?


Installation and Setup
Expand Down
130 changes: 11 additions & 119 deletions docs/_static/doctools.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
*/
"use strict";

const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
"TEXTAREA",
"INPUT",
"SELECT",
"BUTTON",
]);

const _ready = (callback) => {
if (document.readyState !== "loading") {
callback();
Expand All @@ -18,73 +25,11 @@ const _ready = (callback) => {
}
};

/**
* highlight a given string on a node by wrapping it in
* span elements with the given class name.
*/
const _highlight = (node, addItems, text, className) => {
if (node.nodeType === Node.TEXT_NODE) {
const val = node.nodeValue;
const parent = node.parentNode;
const pos = val.toLowerCase().indexOf(text);
if (
pos >= 0 &&
!parent.classList.contains(className) &&
!parent.classList.contains("nohighlight")
) {
let span;

const closestNode = parent.closest("body, svg, foreignObject");
const isInSVG = closestNode && closestNode.matches("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.classList.add(className);
}

span.appendChild(document.createTextNode(val.substr(pos, text.length)));
parent.insertBefore(
span,
parent.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling
)
);
node.nodeValue = val.substr(0, pos);

if (isInSVG) {
const rect = document.createElementNS(
"http://www.w3.org/2000/svg",
"rect"
);
const bbox = parent.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute("class", className);
addItems.push({ parent: parent, target: rect });
}
}
} else if (node.matches && !node.matches("button, select, textarea")) {
node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
}
};
const _highlightText = (thisNode, text, className) => {
let addItems = [];
_highlight(thisNode, addItems, text, className);
addItems.forEach((obj) =>
obj.parent.insertAdjacentElement("beforebegin", obj.target)
);
};

/**
* Small JavaScript module for the documentation.
*/
const Documentation = {
init: () => {
Documentation.highlightSearchWords();
Documentation.initDomainIndexTable();
Documentation.initOnKeyListeners();
},
Expand Down Expand Up @@ -126,51 +71,6 @@ const Documentation = {
Documentation.LOCALE = catalog.locale;
},

/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords: () => {
const highlight =
new URLSearchParams(window.location.search).get("highlight") || "";
const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
if (terms.length === 0) return; // nothing to do

// There should never be more than one element matching "div.body"
const divBody = document.querySelectorAll("div.body");
const body = divBody.length ? divBody[0] : document.querySelector("body");
window.setTimeout(() => {
terms.forEach((term) => _highlightText(body, term, "highlighted"));
}, 10);

const searchBox = document.getElementById("searchbox");
if (searchBox === null) return;
searchBox.appendChild(
document
.createRange()
.createContextualFragment(
'<p class="highlight-link">' +
'<a href="javascript:Documentation.hideSearchWords()">' +
Documentation.gettext("Hide Search Matches") +
"</a></p>"
)
);
},

/**
* helper function to hide the search marks again
*/
hideSearchWords: () => {
document
.querySelectorAll("#searchbox .highlight-link")
.forEach((el) => el.remove());
document
.querySelectorAll("span.highlighted")
.forEach((el) => el.classList.remove("highlighted"));
const url = new URL(window.location);
url.searchParams.delete("highlight");
window.history.replaceState({}, "", url);
},

/**
* helper function to focus on search bar
*/
Expand Down Expand Up @@ -210,15 +110,11 @@ const Documentation = {
)
return;

const blacklistedElements = new Set([
"TEXTAREA",
"INPUT",
"SELECT",
"BUTTON",
]);
document.addEventListener("keydown", (event) => {
if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements
if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys
// bail for input elements
if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
// bail with special keys
if (event.altKey || event.ctrlKey || event.metaKey) return;

if (!event.shiftKey) {
switch (event.key) {
Expand All @@ -240,10 +136,6 @@ const Documentation = {
event.preventDefault();
}
break;
case "Escape":
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
Documentation.hideSearchWords();
event.preventDefault();
}
}

Expand Down
74 changes: 55 additions & 19 deletions docs/_static/searchtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ const _removeChildren = (element) => {
const _escapeRegExp = (string) =>
string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string

const _displayItem = (item, highlightTerms, searchTerms) => {
const _displayItem = (item, searchTerms) => {
const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;

const [docName, title, anchor, descr] = item;
const [docName, title, anchor, descr, score, _filename] = item;

let listItem = document.createElement("li");
let requestUrl;
Expand All @@ -82,10 +82,9 @@ const _displayItem = (item, highlightTerms, searchTerms) => {
requestUrl = docUrlRoot + docName + docFileSuffix;
linkUrl = docName + docLinkSuffix;
}
const params = new URLSearchParams();
params.set("highlight", [...highlightTerms].join(" "));
let linkEl = listItem.appendChild(document.createElement("a"));
linkEl.href = linkUrl + "?" + params.toString() + anchor;
linkEl.href = linkUrl + anchor;
linkEl.dataset.score = score;
linkEl.innerHTML = title;
if (descr)
listItem.appendChild(document.createElement("span")).innerHTML =
Expand All @@ -96,7 +95,7 @@ const _displayItem = (item, highlightTerms, searchTerms) => {
.then((data) => {
if (data)
listItem.appendChild(
Search.makeSearchSummary(data, searchTerms, highlightTerms)
Search.makeSearchSummary(data, searchTerms)
);
});
Search.output.appendChild(listItem);
Expand All @@ -116,15 +115,14 @@ const _finishSearch = (resultCount) => {
const _displayNextItem = (
results,
resultCount,
highlightTerms,
searchTerms
) => {
// results left, load the summary and display it
// this is intended to be dynamic (don't sub resultsCount)
if (results.length) {
_displayItem(results.pop(), highlightTerms, searchTerms);
_displayItem(results.pop(), searchTerms);
setTimeout(
() => _displayNextItem(results, resultCount, highlightTerms, searchTerms),
() => _displayNextItem(results, resultCount, searchTerms),
5
);
}
Expand Down Expand Up @@ -237,6 +235,12 @@ const Search = {
* execute search (requires search index to be loaded)
*/
query: (query) => {
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const titles = Search._index.titles;
const allTitles = Search._index.alltitles;
const indexEntries = Search._index.indexentries;

// stem the search terms and add them to the correct list
const stemmer = new Stemmer();
const searchTerms = new Set();
Expand Down Expand Up @@ -264,6 +268,10 @@ const Search = {
}
});

if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js
localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" "))
}

// console.debug("SEARCH: searching for:");
// console.info("required: ", [...searchTerms]);
// console.info("excluded: ", [...excludedTerms]);
Expand All @@ -272,6 +280,40 @@ const Search = {
let results = [];
_removeChildren(document.getElementById("search-progress"));

const queryLower = query.toLowerCase();
for (const [title, foundTitles] of Object.entries(allTitles)) {
if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) {
for (const [file, id] of foundTitles) {
let score = Math.round(100 * queryLower.length / title.length)
results.push([
docNames[file],
titles[file] !== title ? `${titles[file]} > ${title}` : title,
id !== null ? "#" + id : "",
null,
score,
filenames[file],
]);
}
}
}

// search for explicit entries in index directives
for (const [entry, foundEntries] of Object.entries(indexEntries)) {
if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {
for (const [file, id] of foundEntries) {
let score = Math.round(100 * queryLower.length / entry.length)
results.push([
docNames[file],
titles[file],
id ? "#" + id : "",
null,
score,
filenames[file],
]);
}
}
}

// lookup as object
objectTerms.forEach((term) =>
results.push(...Search.performObjectSearch(term, objectTerms))
Expand Down Expand Up @@ -318,7 +360,7 @@ const Search = {
// console.info("search results:", Search.lastresults);

// print the results
_displayNextItem(results, results.length, highlightTerms, searchTerms);
_displayNextItem(results, results.length, searchTerms);
},

/**
Expand Down Expand Up @@ -399,8 +441,8 @@ const Search = {
// prepare search
const terms = Search._index.terms;
const titleTerms = Search._index.titleterms;
const docNames = Search._index.docnames;
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const titles = Search._index.titles;

const scoreMap = new Map();
Expand Down Expand Up @@ -497,11 +539,9 @@ const Search = {
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, highlightWords is the list of normal, unstemmed
* words. the first one is used to find the occurrence, the
* latter for highlighting it.
* of stemmed words.
*/
makeSearchSummary: (htmlText, keywords, highlightWords) => {
makeSearchSummary: (htmlText, keywords) => {
const text = Search.htmlToText(htmlText);
if (text === "") return null;

Expand All @@ -519,10 +559,6 @@ const Search = {
summary.classList.add("context");
summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;

highlightWords.forEach((highlightWord) =>
_highlightText(summary, highlightWord, "highlighted")
);

return summary;
},
};
Expand Down
Loading

0 comments on commit 672ce84

Please sign in to comment.