forked from coralproject/talk
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CORL-181] Comment Count Injection (coralproject#2581)
* feat: inject comment counts * fix: tests * feat: integrate stream embed with coral counts * chore: refactor constants * test: test for count bundle * test: test live comment count integration with stream embed * feat: use defer * fix: snapshot * feat: auto add count.js in when calling Coral.createStreamEmbed * fix: tests * fix: rm duplicate test * chore: remove unuse file
- Loading branch information
Showing
48 changed files
with
888 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* getCurrentScriptOrigin will try to find the script origin. | ||
* For legacy browsers a fallbackIdentifier is required. | ||
* | ||
* @argument fallbackID id attached to a script tag to get its origin from for legacy browsrs. | ||
*/ | ||
function getCurrentScriptOrigin(fallbackID?: string) { | ||
// Find current script (modern browsers). | ||
let script = document.currentScript as HTMLScriptElement | null; | ||
|
||
if (!script && fallbackID) { | ||
// Find script tag with `fallbackIdentifier` as its id. | ||
script = document.getElementById(fallbackID) as HTMLScriptElement | null; | ||
if (!script) { | ||
// Find script tag with `fallbackIdentifier` as its className. | ||
script = document.querySelector( | ||
`.${fallbackID}` | ||
) as HTMLScriptElement | null; | ||
} | ||
} | ||
if (!script) { | ||
throw new Error("Current script not found"); | ||
} | ||
return new URL(script.src).origin; | ||
} | ||
|
||
export default getCurrentScriptOrigin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Coral - Count</title> | ||
<meta charset="utf-8" /> | ||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> | ||
<meta name="viewport" content="width=device-width, user-scalable=no" /> | ||
<link rel="canonical" href="http://localhost:8080/" /> | ||
</head> | ||
|
||
<body> | ||
<h1>Comment Counts</h1> | ||
<h3>Specified by canonical link</h3> | ||
<p><a href="http://localhost:8080/">Default: <span class="coral-count"></span></a></p> | ||
|
||
<h3>Specified by data-coral-url</h3> | ||
<p><a href="http://localhost:8080/story.html">Story: <span class="coral-count" data-coral-url="http://localhost:8080/story.html"></span></a></p> | ||
<p><a href="http://localhost:8080/storyButton.html">Story With Button: <span class="coral-count" data-coral-url="http://localhost:8080/storyButton.html"></span></a></p> | ||
|
||
<h3>No text</h3> | ||
<p><a href="http://localhost:8080/">Default notext: <span class="coral-count" data-coral-notext="true" data-coral-url="http://localhost:8080/"></span></a></p> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
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(`${JSON.stringify(!!args.notext)};${args.id || args.url}`); | ||
} | ||
|
||
/** Detects count elements and use jsonp to inject the counts. */ | ||
function detectAndInject() { | ||
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) => { | ||
let url = element.dataset.coralUrl; | ||
const id = element.dataset.coralId; | ||
const notext = element.dataset.coralNotext === "true"; | ||
if (!url && !id) { | ||
url = STORY_URL; | ||
element.dataset.coralUrl = STORY_URL; | ||
} | ||
const args = { id, url, notext }; | ||
const ref = createCountQueryRef(args); | ||
if (!(ref in queryMap)) { | ||
queryMap[ref] = args; | ||
} | ||
element.dataset.coralRef = ref; | ||
}); | ||
|
||
// Call server using JSONP. | ||
Object.keys(queryMap).forEach(ref => { | ||
const { url, id, notext } = queryMap[ref]; | ||
const args = { url, id, notext: notext ? "true" : "false", ref }; | ||
jsonp(`${ORIGIN}/api/story/count.js`, "CoralCount.setCount", args); | ||
}); | ||
} | ||
|
||
export function main() { | ||
injectJSONPCallback(); | ||
detectAndInject(); | ||
} | ||
|
||
if (!detectCountScript() && process.env.NODE_ENV !== "test") { | ||
main(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { COUNT_SELECTOR } from "coral-framework/constants"; | ||
|
||
/** Injects a global CoralCount callback into the window object to be used in JSONP */ | ||
function injectJSONPCallback() { | ||
(window as any).CoralCount = { | ||
setCount: (data: { ref: string; html: string }) => { | ||
// Find all the elements with ref. | ||
const elements = document.querySelectorAll( | ||
`${COUNT_SELECTOR}[data-coral-ref='${data.ref}']` | ||
); | ||
Array.prototype.forEach.call(elements, (element: HTMLElement) => { | ||
element.innerHTML = data.html; | ||
}); | ||
}, | ||
}; | ||
} | ||
|
||
export default injectJSONPCallback; |
95 changes: 95 additions & 0 deletions
95
src/core/client/count/test/__snapshots__/basic.spec.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`Calls JSONP 1`] = ` | ||
<body> | ||
<span | ||
class="coral-count" | ||
data-coral-ref="ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwL3N0b3J5Lmh0bWw=" | ||
data-coral-url="http://localhost:8080/story.html" | ||
/> | ||
<span | ||
class="coral-count" | ||
data-coral-id="1234-5678-91021" | ||
data-coral-ref="ZmFsc2U7MTIzNC01Njc4LTkxMDIx" | ||
/> | ||
<span | ||
class="coral-count" | ||
data-coral-ref="ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwLw==" | ||
data-coral-url="http://localhost:8080/" | ||
data-notext="true" | ||
/> | ||
<span | ||
class="coral-count" | ||
data-coral-ref="ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwLw==" | ||
data-coral-url="http://localhost:8080/" | ||
/> | ||
<script | ||
src="http://localhost:8080/api/story/count.js?callback=CoralCount.setCount&url=http%3A%2F%2Flocalhost%3A8080%2Fstory.html¬ext=false&ref=ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwL3N0b3J5Lmh0bWw%3D" | ||
/> | ||
<script | ||
src="http://localhost:8080/api/story/count.js?callback=CoralCount.setCount&id=1234-5678-91021¬ext=false&ref=ZmFsc2U7MTIzNC01Njc4LTkxMDIx" | ||
/> | ||
<script | ||
src="http://localhost:8080/api/story/count.js?callback=CoralCount.setCount&url=http%3A%2F%2Flocalhost%3A8080%2F¬ext=false&ref=ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwLw%3D%3D" | ||
/> | ||
</body> | ||
`; | ||
|
||
exports[`Inject counts 1`] = ` | ||
<body> | ||
<span | ||
class="coral-count" | ||
data-coral-ref="ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwL3N0b3J5Lmh0bWw=" | ||
data-coral-url="http://localhost:8080/story.html" | ||
/> | ||
<span | ||
class="coral-count" | ||
data-coral-id="1234-5678-91021" | ||
data-coral-ref="ZmFsc2U7MTIzNC01Njc4LTkxMDIx" | ||
/> | ||
<span | ||
class="coral-count" | ||
data-coral-ref="ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwLw==" | ||
data-coral-url="http://localhost:8080/" | ||
data-notext="true" | ||
> | ||
<span | ||
class="coral-count-number" | ||
> | ||
5 | ||
</span> | ||
<span | ||
class="coral-count-text" | ||
> | ||
Comments | ||
</span> | ||
</span> | ||
<span | ||
class="coral-count" | ||
data-coral-ref="ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwLw==" | ||
data-coral-url="http://localhost:8080/" | ||
> | ||
<span | ||
class="coral-count-number" | ||
> | ||
5 | ||
</span> | ||
<span | ||
class="coral-count-text" | ||
> | ||
Comments | ||
</span> | ||
</span> | ||
<script | ||
src="http://localhost:8080/api/story/count.js?callback=CoralCount.setCount&url=http%3A%2F%2Flocalhost%3A8080%2Fstory.html¬ext=false&ref=ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwL3N0b3J5Lmh0bWw%3D" | ||
/> | ||
<script | ||
src="http://localhost:8080/api/story/count.js?callback=CoralCount.setCount&id=1234-5678-91021¬ext=false&ref=ZmFsc2U7MTIzNC01Njc4LTkxMDIx" | ||
/> | ||
<script | ||
src="http://localhost:8080/api/story/count.js?callback=CoralCount.setCount&url=http%3A%2F%2Flocalhost%3A8080%2F¬ext=false&ref=ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwLw%3D%3D" | ||
/> | ||
</body> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
beforeAll(async () => { | ||
const script = document.createElement("script"); | ||
script.src = "http://localhost:8080/assets/js/count.js"; | ||
Object.defineProperty(window.document, "currentScript", { | ||
value: script, | ||
}); | ||
|
||
const link = document.createElement("link"); | ||
link.rel = "canonical"; | ||
link.href = "http://localhost:8080/"; | ||
document.head.appendChild(link); | ||
}); | ||
|
||
beforeEach(async () => { | ||
document.body.innerHTML = ""; | ||
const tags = [ | ||
{ | ||
coralUrl: "http://localhost:8080/story.html", | ||
}, | ||
{ | ||
coralId: "1234-5678-91021", | ||
}, | ||
{ | ||
notext: "true", | ||
}, | ||
{}, | ||
]; | ||
|
||
tags.forEach(attrs => { | ||
const element = document.createElement("span"); | ||
element.className = "coral-count"; | ||
Object.assign(element.dataset, attrs); | ||
document.body.appendChild(element); | ||
}); | ||
(await import("../")).main(); | ||
}); | ||
|
||
it("Sets the JSONP callback", async () => { | ||
expect((window as any).CoralCount).toBeDefined(); | ||
}); | ||
|
||
it("Calls JSONP", async () => { | ||
expect(document.body).toMatchSnapshot(); | ||
}); | ||
|
||
it("Inject counts", async () => { | ||
(window as any).CoralCount.setCount({ | ||
ref: "ZmFsc2U7aHR0cDovL2xvY2FsaG9zdDo4MDgwLw==", | ||
html: | ||
'<span class="coral-count-number">5</span> <span class="coral-count-text">Comments</span>', | ||
}); | ||
expect(document.body).toMatchSnapshot(); | ||
}); |
Oops, something went wrong.