mirror of
https://github.com/wassname/talk.git
synced 2026-07-16 11:22:16 +08:00
* feat: added reset option for count.js * fix: adjust reset beheviour * fix: switched to bundlesize2 * fix: added flag to enable github checks Co-authored-by: Vinh <vinh@vinh.tech>
102 lines
3.1 KiB
TypeScript
102 lines
3.1 KiB
TypeScript
import { COUNT_SELECTOR, ORIGIN_FALLBACK_ID } from "coral-framework/constants";
|
|
import detectCountScript from "coral-framework/helpers/detectCountScript";
|
|
import resolveStoryURL from "coral-framework/helpers/resolveStoryURL";
|
|
import jsonp from "coral-framework/utils/jsonp";
|
|
|
|
import getCurrentScriptOrigin from "./getCurrentScriptOrigin";
|
|
import injectJSONPCallback from "./injectJSONPCallback";
|
|
|
|
/** Arguments that will be send to the server. */
|
|
interface CountQueryArgs {
|
|
id?: string;
|
|
url?: string;
|
|
notext: boolean;
|
|
}
|
|
|
|
/** createCountQueryRef creates a unique reference from the query args */
|
|
function createCountQueryRef(args: CountQueryArgs) {
|
|
return btoa(`${args.notext ? "true" : "false"};${args.id || args.url}`);
|
|
}
|
|
|
|
interface DetectAndInjectArgs {
|
|
reset?: boolean;
|
|
}
|
|
|
|
/** Detects count elements and use jsonp to inject the counts. */
|
|
function detectAndInject(opts: DetectAndInjectArgs = {}) {
|
|
const ORIGIN = getCurrentScriptOrigin(ORIGIN_FALLBACK_ID);
|
|
const STORY_URL = resolveStoryURL();
|
|
|
|
/** A map of references pointing to the count query arguments */
|
|
const queryMap: Record<string, CountQueryArgs> = {};
|
|
|
|
// Find all the selected elements and fill the queryMap.
|
|
const elements = document.querySelectorAll(COUNT_SELECTOR);
|
|
Array.prototype.forEach.call(elements, (element: HTMLElement) => {
|
|
const id = element.dataset.coralId;
|
|
const notext = element.dataset.coralNotext === "true";
|
|
|
|
// If there is no URL or ID on the element, add one based on the story url
|
|
// that we detected.
|
|
let url = element.dataset.coralUrl;
|
|
if (!url && !id) {
|
|
url = STORY_URL;
|
|
element.dataset.coralUrl = STORY_URL;
|
|
}
|
|
|
|
// Construct the args for generating the ref.
|
|
const args = { id, url, notext };
|
|
|
|
// Get or create a ref.
|
|
let ref = element.dataset.coralRef;
|
|
if (!ref) {
|
|
ref = createCountQueryRef(args);
|
|
element.dataset.coralRef = ref;
|
|
} else {
|
|
// The element already had a ref attached to it, which means it's already
|
|
// been processed. If we aren't resetting, we should skip this.
|
|
if (!opts.reset) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Add it to the managed set if we haven't already.
|
|
if (!(ref in queryMap)) {
|
|
queryMap[ref] = args;
|
|
}
|
|
});
|
|
|
|
// Call server using JSONP.
|
|
Object.keys(queryMap).forEach((ref) => {
|
|
const { url, id, notext } = queryMap[ref];
|
|
|
|
// Compile the arguments used to generate the
|
|
const args: Record<string, string | number | undefined> = {
|
|
url,
|
|
id,
|
|
notext: notext ? "true" : "false",
|
|
ref,
|
|
};
|
|
|
|
// Special handling for when the count is reset.
|
|
if (opts.reset) {
|
|
// Add the date as an argument to cache bust.
|
|
args.d = Date.now().toString();
|
|
}
|
|
|
|
// Add the script element with the specified options to the page.
|
|
jsonp(`${ORIGIN}/api/story/count.js`, "CoralCount.setCount", args);
|
|
});
|
|
}
|
|
|
|
export function main() {
|
|
// Inject the JSONP callback with the detection script to be used as the
|
|
// CoralCount.getCount callback.
|
|
injectJSONPCallback(detectAndInject);
|
|
detectAndInject();
|
|
}
|
|
|
|
if (!detectCountScript() && process.env.NODE_ENV !== "test") {
|
|
main();
|
|
}
|