Skip to content

Commit

Permalink
Merge branch 'develop' into executable-less
Browse files Browse the repository at this point in the history
  • Loading branch information
saschanaz committed Oct 20, 2019
2 parents 07517b2 + bc5abb6 commit f8873e9
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 48 deletions.
56 changes: 32 additions & 24 deletions src/core/biblio-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import { importIdb } from "./idb.js";
import { pub } from "./pubsubhub.js";
export const name = "core/biblio-db";

/**
* @typedef {keyof BilbioDb} AllowedType
* @type {Set<AllowedType>}
*/
const ALLOWED_TYPES = new Set(["alias", "reference"]);
const hasIndexedDB = typeof indexedDB !== "undefined";
const dbMaps = {
Expand All @@ -32,6 +36,21 @@ const dbMaps = {
/* Database initialization tracker */
const readyPromise = openIdb();

/**
* @typedef {object} BilbioDb
*
* @property {object} alias Object store for alias objects
* @property {string} alias.key
* @property {object} alias.value
* @property {object} alias.indexes
* @property {string} alias.aliasOf
*
* @property {object} reference Object store for reference objects
* @property {string} reference.key
* @property {object} reference.value
*
* @returns {Promise<import("idb").IDBPDatabase<BilbioDb>>}
*/
async function openIdb() {
if (!hasIndexedDB) {
return;
Expand Down Expand Up @@ -69,7 +88,7 @@ export const biblioDB = {
/**
* Checks if the database has an id for a given type.
*
* @param {String} type One of the ALLOWED_TYPES.
* @param {AllowedType} type One of the ALLOWED_TYPES.
* @param {String} id The reference to find.
* @return {Promise<Boolean>} True if it has it, false otherwise.
*/
Expand All @@ -84,7 +103,7 @@ export const biblioDB = {
return dbMaps[type].has(id);
}
const db = await this.ready;
const objectStore = db.transaction([type], "readonly").objectStore(type);
const objectStore = db.transaction(type, "readonly").store;
const range = IDBKeyRange.only(id);
const result = await objectStore.openCursor(range);
return !!result;
Expand All @@ -96,19 +115,10 @@ export const biblioDB = {
* @return {Promise<Boolean>} Resolves with true if found.
*/
async isAlias(id) {
if (!id) {
throw new TypeError("id is required");
}
if (!hasIndexedDB) {
return dbMaps.alias.has(id);
}
const db = await this.ready;
const objectStore = db
.transaction(["alias"], "readonly")
.objectStore("alias");
const range = IDBKeyRange.only(id);
const result = await objectStore.openCursor(range);
return !!result;
return await this.has("alias", id);
},
/**
* Resolves an alias to its corresponding reference id.
Expand All @@ -126,17 +136,15 @@ export const biblioDB = {
}
const db = await this.ready;

const objectStore = db
.transaction("alias", "readonly")
.objectStore("alias");
const objectStore = db.transaction("alias", "readonly").store;
const range = IDBKeyRange.only(id);
const result = await objectStore.openCursor(range);
return result ? result.value.aliasOf : result;
},
/**
* Get a reference or alias out of the database.
*
* @param {String} type The type as per ALLOWED_TYPES.
* @param {AllowedType} type The type as per ALLOWED_TYPES.
* @param {string} id The id for what to look up.
* @return {Promise<Object?>} Resolves with the retrieved object, or null.
*/
Expand All @@ -151,7 +159,7 @@ export const biblioDB = {
return dbMaps[type].get(id) || null;
}
const db = await this.ready;
const objectStore = db.transaction([type], "readonly").objectStore(type);
const objectStore = db.transaction(type, "readonly").store;
const range = IDBKeyRange.only(id);
const result = await objectStore.openCursor(range);
return result ? result.value : result;
Expand Down Expand Up @@ -189,8 +197,8 @@ export const biblioDB = {
aliasesAndRefs.reference.add(obj);
}
});
const promisesToAdd = Object.keys(aliasesAndRefs)
.map((/** @type {keyof typeof dbMaps} */ type) => {
const promisesToAdd = [...ALLOWED_TYPES]
.map(type => {
return Array.from(aliasesAndRefs[type]).map(details =>
this.add(type, details)
);
Expand All @@ -201,8 +209,8 @@ export const biblioDB = {
/**
* Adds a reference or alias to the database.
*
* @param {keyof typeof dbMaps} type The type as per ALLOWED_TYPES.
* @param {object} details The object to store.
* @param {AllowedType} type The type as per ALLOWED_TYPES.
* @param {Object} details The object to store.
*/
async add(type, details) {
if (!ALLOWED_TYPES.has(type)) {
Expand All @@ -219,14 +227,14 @@ export const biblioDB = {
}
const db = await this.ready;
const isInDB = await this.has(type, details.id);
const store = db.transaction([type], "readwrite").objectStore(type);
const store = db.transaction(type, "readwrite").store;
// update or add, depending of already having it in db
return isInDB ? await store.put(details) : await store.add(details);
},
/**
* Closes the underlying database.
*
* @return {Promise} Resolves after database closes.
* @return {Promise<void>} Resolves after database closes.
*/
async close() {
const db = await this.ready;
Expand All @@ -246,7 +254,7 @@ export const biblioDB = {
}
const db = await this.ready;
const storeNames = [...ALLOWED_TYPES];
const stores = await db.transaction(storeNames, "readwrite");
const stores = db.transaction(storeNames, "readwrite");
const clearStorePromises = storeNames.map(name => {
return stores.objectStore(name).clear();
});
Expand Down
15 changes: 13 additions & 2 deletions src/core/expose-modules.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// @ts-check
const needAmdLike = typeof window !== "undefined" && !window.require;
if (needAmdLike) {
window.require = function(deps, callback) {
/**
* @type {any}
* @param {string[]} deps
* @param {(...modules: any[]) => void} callback
*/
const require = function(deps, callback) {
const modules = deps.map(dep => {
if (!(dep in window.require.modules)) {
throw new Error(`Unsupported dependency name: ${dep}`);
Expand All @@ -9,9 +15,14 @@ if (needAmdLike) {
});
callback(...modules);
};
window.require.modules = {};
require.modules = {};
window.require = require;
}

/**
* @param {string} name
* @param {any} object
*/
export function expose(name, object) {
if (needAmdLike) {
window.require.modules[name] = object;
Expand Down
64 changes: 63 additions & 1 deletion src/core/inline-idl-parser.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-check
// Parses an inline IDL string (`{{ idl string }}`)
// and renders its components as HTML

Expand All @@ -15,7 +16,57 @@ const enumRegex = /^(\w+)\["([\w- ]*)"\]$/;
// https://github.com/w3c/respec/pull/1848/files#r225087385
const methodSplitRegex = /\.?(\w+\(.*\)$)/;

/** @param {string} str */
/**
* @typedef {object} IdlBase
* @property {"base"} type
* @property {string} identifier
* @property {boolean} renderParent
* @property {InlineIdl | null} [parent]
*
* @typedef {object} IdlAttribute
* @property {"attribute"} type
* @property {string} identifier
* @property {boolean} renderParent
* @property {InlineIdl | null} [parent]
*
* @typedef {object} IdlInternalSlot
* @property {"internal-slot"} type
* @property {string} identifier
* @property {boolean} renderParent
* @property {InlineIdl | null} [parent]
*
* @typedef {object} IdlMethod
* @property {"method"} type
* @property {string} identifier
* @property {string[]} args
* @property {boolean} renderParent
* @property {InlineIdl | null} [parent]
*
* @typedef {object} IdlEnum
* @property {"enum"} type
* @property {string} [identifier]
* @property {string} enumValue
* @property {boolean} renderParent
* @property {InlineIdl | null} [parent]
*
* @typedef {object} IdlException
* @property {"exception"} type
* @property {string} identifier
* @property {InlineIdl | null} [parent]
*
* @typedef {object} IdlPrimitive
* @property {"idl-primitive"} type
* @property {string} identifier
* @property {boolean} renderParent
* @property {InlineIdl | null} [parent]
*
* @typedef {IdlBase | IdlAttribute | IdlInternalSlot | IdlMethod | IdlEnum | IdlException | IdlPrimitive} InlineIdl
*/

/**
* @param {string} str
* @returns {InlineIdl[]}
*/
function parseInlineIDL(str) {
const [nonMethodPart, methodPart] = str.split(methodSplitRegex);
const tokens = nonMethodPart
Expand All @@ -24,6 +75,7 @@ function parseInlineIDL(str) {
.filter(s => s && s.trim())
.map(s => s.trim());
const renderParent = !str.includes("/");
/** @type {InlineIdl[]} */
const results = [];
while (tokens.length) {
const value = tokens.pop();
Expand Down Expand Up @@ -82,6 +134,9 @@ function parseInlineIDL(str) {
return results.reverse();
}

/**
* @param {IdlBase} details
*/
function renderBase(details) {
// Check if base is a local variable in a section
const { identifier, renderParent } = details;
Expand All @@ -92,6 +147,7 @@ function renderBase(details) {

/**
* Internal slot: .[[identifier]] or [[identifier]]
* @param {IdlInternalSlot} details
*/
function renderInternalSlot(details) {
const { identifier, parent, renderParent } = details;
Expand All @@ -107,6 +163,7 @@ function renderInternalSlot(details) {

/**
* Attribute: .identifier
* @param {IdlAttribute} details
*/
function renderAttribute(details) {
const { parent, identifier, renderParent } = details;
Expand All @@ -121,6 +178,7 @@ function renderAttribute(details) {

/**
* Method: .identifier(arg1, arg2, ...), identifier(arg1, arg2, ...)
* @param {IdlMethod} details
*/
function renderMethod(details) {
const { args, identifier, type, parent, renderParent } = details;
Expand All @@ -140,6 +198,7 @@ function renderMethod(details) {
* Enum:
* Identifier["enum value"]
* Identifer / "enum value"
* @param {IdlEnum} details
*/
function renderEnum(details) {
const { identifier, enumValue, parent } = details;
Expand All @@ -156,6 +215,7 @@ function renderEnum(details) {
/**
* Exception value: "NotAllowedError"
* Only the WebIDL spec can define exceptions
* @param {IdlException} details
*/
function renderException(details) {
const { identifier } = details;
Expand All @@ -169,6 +229,7 @@ function renderException(details) {
/**
* Interface types: {{ unrestricted double }} {{long long}}
* Only the WebIDL spec defines these types.
* @param {IdlPrimitive} details
*/
function renderIdlPrimitiveType(details) {
const { identifier } = details;
Expand All @@ -189,6 +250,7 @@ export function idlStringToHtml(str) {
try {
results = parseInlineIDL(str);
} catch (error) {
/** @type {HTMLSpanElement} */
const el = hyperHTML`<span>{{ ${str} }}</span>`;
showInlineError(el, error.message, "Error: Invalid inline IDL string");
return el;
Expand Down
7 changes: 5 additions & 2 deletions src/core/jquery-enhanced.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-check
import {
addId,
getDfnTitles,
Expand All @@ -16,7 +17,9 @@ window.$ = window.jQuery = $;
// return a jQuery object containing the new elements
window.$.fn.renameElement = function(name) {
const arr = [];
// @ts-ignore
this.each(function() {
// @ts-ignore
const elem = this;
const newElem = renameElement(elem, name);
arr.push(newElem);
Expand All @@ -38,8 +41,8 @@ window.$.fn.renameElement = function(name) {
//
// This method will publish a warning if a title is used on a definition
// instead of an @lt (as per specprod mailing list discussion).
window.$.fn.getDfnTitles = function(args) {
return getDfnTitles(this[0], args);
window.$.fn.getDfnTitles = function() {
return getDfnTitles(this[0]);
};

// For any element (usually <a>), returns an array of targets that
Expand Down
12 changes: 7 additions & 5 deletions src/core/ui.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-check
// Module core/ui
// Handles the ReSpec UI
/* jshint laxcomma:true */
Expand All @@ -12,6 +13,7 @@
import css from "text!../../assets/ui.css";
import hyperHTML from "hyperhtml";
import { markdownToHtml } from "./markdown.js";
// @ts-ignore
import shortcut from "../shortcut.js";
import { sub } from "./pubsubhub.js";
export const name = "core/ui";
Expand Down Expand Up @@ -46,7 +48,7 @@ sub("end-all", () => document.body.prepend(respecUI), { once: true });

const respecPill = hyperHTML`<button id='respec-pill' disabled>ReSpec</button>`;
respecUI.appendChild(respecPill);
respecPill.addEventListener("click", function(e) {
respecPill.addEventListener("click", e => {
e.stopPropagation();
if (menu.hidden) {
menu.classList.remove("respec-hidden");
Expand All @@ -55,7 +57,7 @@ respecPill.addEventListener("click", function(e) {
menu.classList.add("respec-hidden");
menu.classList.remove("respec-visible");
}
this.setAttribute("aria-expanded", String(menu.hidden));
respecPill.setAttribute("aria-expanded", String(menu.hidden));
menu.hidden = !menu.hidden;
});
document.documentElement.addEventListener("click", () => {
Expand Down Expand Up @@ -87,8 +89,8 @@ function errWarn(msg, arr, butName, title) {
function createWarnButton(butName, arr, title) {
const buttonId = `respec-pill-${butName}`;
const button = hyperHTML`<button id='${buttonId}' class='respec-info-button'>`;
button.addEventListener("click", function() {
this.setAttribute("aria-expanded", "true");
button.addEventListener("click", () => {
button.setAttribute("aria-expanded", "true");
const ol = hyperHTML`<ol class='${`respec-${butName}-list`}'></ol>`;
for (const err of arr) {
const fragment = document
Expand All @@ -104,7 +106,7 @@ function createWarnButton(butName, arr, title) {
}
ol.appendChild(li);
}
ui.freshModal(title, ol, this);
ui.freshModal(title, ol, button);
});
const ariaMap = new Map([
["expanded", "false"],
Expand Down
Loading

0 comments on commit f8873e9

Please sign in to comment.