Skip to content

Commit

Permalink
Merge pull request #4 from denis-ok/ahrefs-fork-update
Browse files Browse the repository at this point in the history
The latest changes from original repo
  • Loading branch information
rusty-key authored May 6, 2022
2 parents ac70b3b + c3fed8c commit 9fdfb3d
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 28 deletions.
41 changes: 39 additions & 2 deletions commands/reshowcase
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ if (task !== "build" && task !== "start") {
process.exit(1);
}

// Servers can handle paths to HTML files differently.
// Allow using full path to HTML template in "src" attribute of iframe in case of possible issues.
const useFullframeUrl = (() => {
const prefix = `--full-iframe-url=`;
const arg = process.argv.find((item) => item.startsWith(prefix));
if (arg === undefined) {
return false;
} else {
const value = arg.replace(prefix, "");
if (value === "true") {
return true;
} else {
return false;
}
}
})();

const isBuild = task === "build";

const entryPath = getRequiredPathValue("entry");
Expand Down Expand Up @@ -88,14 +105,22 @@ const compiler = webpack({
patterns: [{ from: path.join(__dirname, "../src/favicon.png"), to: "" }],
}),
new HtmlWebpackPlugin({
filename: "index.html",
template: path.join(__dirname, "../src/ui-template.html"),
}),
new HtmlWebpackPlugin({
filename: "./demo/index.html",
template: process.argv.find((item) => item.startsWith("--template="))
? path.join(
process.cwd(),
process.argv
.find((item) => item.startsWith("--template="))
.replace(/--template=/, "")
)
: path.join(__dirname, "../src/index.html"),
: path.join(__dirname, "../src/demo-template.html"),
}),
new webpack.DefinePlugin({
USE_FULL_IFRAME_URL: JSON.stringify(useFullframeUrl),
}),
],
});
Expand Down Expand Up @@ -127,7 +152,19 @@ if (isBuild) {
index: "/index.html",
},
stats: "errors-only",
...(config.devServer || {})
...(config.devServer || {}),
});

['SIGINT', 'SIGTERM'].forEach((signal) => {
process.on(signal, () => {
if (server) {
server.close(() => {
process.exit();
})
} else {
process.exit();
}
})
});

if (config.devServer && config.devServer.socket) {
Expand Down
8 changes: 8 additions & 0 deletions example/Demo.res
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,12 @@ start()
)
})

demo(({addDemo: _, addCategory}) => {
addCategory("Test search", ({addDemo, addCategory: _}) => {
addDemo("OneTwoThreeFour", _ => React.null)
addDemo("OneTwoThreeFive", _ => React.null)
addDemo("OneTwoFourSeven", _ => React.null)
})
})

start()
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ahrefs/reshowcase",
"version": "5.1.2",
"version": "5.2.0",
"description": "> A tool to create demos for your ReScript React components",
"main": "index.js",
"directories": {
Expand Down
2 changes: 1 addition & 1 deletion src/Demos.res
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ let rec isNestedEntityMatchSearch = (demos: t, searchString) => {
->Js.Dict.entries
->Array.some(((entityName, entity)) => {
let isEntityNameMatchSearch =
HighlightTerms.getMatchingTerms(searchString, ~entityName)->Array.size > 0
HighlightTerms.getMatchingTerms(~searchString, ~entityName)->Array.size > 0
switch entity {
| Demo(_) => isEntityNameMatchSearch
| Category(demos) => isEntityNameMatchSearch || isNestedEntityMatchSearch(demos, searchString)
Expand Down
7 changes: 5 additions & 2 deletions src/ReshowcaseUi.res
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ module DemoListSidebar = {

demos
->Array.map(((entityName, entity)) => {
let searchMatchingTerms = HighlightTerms.getMatchingTerms(searchString, ~entityName)
let searchMatchingTerms = HighlightTerms.getMatchingTerms(~searchString, ~entityName)
let isEntityNameMatchSearch = searchString == "" || searchMatchingTerms->Belt.Array.size > 0
switch entity {
| Demo(_) =>
Expand Down Expand Up @@ -715,16 +715,19 @@ module DemoUnitFrame = {
(),
)

let useFullframeUrl: bool = %raw(`typeof USE_FULL_IFRAME_URL === "boolean" ? USE_FULL_IFRAME_URL : false`)

@react.component
let make = (~queryString: string, ~responsiveMode, ~onLoad: Js.t<'a> => unit) => {
let iframePath = useFullframeUrl ? "demo/index.html" : "demo"
<div name="DemoUnitFrame" style={container(responsiveMode)}>
<iframe
onLoad={event => {
let iframe = event->ReactEvent.Synthetic.target
let window = iframe["contentWindow"]
onLoad(window)
}}
src={`?iframe=true&${queryString}`}
src={`${iframePath}?iframe=true&${queryString}`}
style={ReactDOM.Style.make(
~height={
switch responsiveMode {
Expand Down
32 changes: 21 additions & 11 deletions src/ReshowcaseUi__HighlightTerms.res
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,39 @@ type textPart = Marked(string) | Unmarked(string)

type termPosition = Start | Middle | End

let getMatchingTerms = (searchString, ~entityName) => {
let getTermGroups = (~searchString, ~entityName) => {
switch searchString {
| "" => []
| _ =>
let searchString = searchString->String.toLowerCase
let entityName = entityName->String.toLowerCase

if entityName->String.includes(searchString) {
[searchString]
[[searchString]]
} else {
let terms =

let refinedSearchString =
searchString
->String.replaceByRe(%re("/\\s+/g"), " ")
->String.splitByRe(%re("/( |, |,)/"))
->Belt.Array.keepMap(s =>
switch s {
| None => None
| Some(s) => String.length(s) > 1 ? Some(s) : None // filter out meaningless one-char terms
}
)
terms->Array.filter(term => Js.String2.includes(entityName, term))
->String.replaceByRe(%re("/( , |, | ,)/g"), ",")

refinedSearchString
->String.split(",")
->Array.map(s => s->String.split(" "))
->Array.map(arr => arr->Belt.Array.keepMap(s => String.length(s) > 1 ? Some(s) : None))
// filter out meaningless one-char terms
}
}
}

let getMatchingTerms = (~searchString, ~entityName) => {
let entityName = entityName->String.toLowerCase
let termGroups = getTermGroups(~searchString, ~entityName)
let includedTerms =
termGroups->Array.filter(terms => terms->Array.every(term => String.includes(entityName, term)))
Belt.Array.concatMany(includedTerms)
}

let getMarkRangeIndexes = (text, substring) => {
let indexFrom = String.indexOf(String.toLowerCase(text), String.toLowerCase(substring))
let indexTo = indexFrom + String.length(substring)
Expand Down
15 changes: 15 additions & 0 deletions src/demo-template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>

<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Reshowcase demo</title>
<link rel="icon" href="favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</head>

<body>
<div id="root"></div>
</body>

</html>
103 changes: 101 additions & 2 deletions src/tests/HighlightTermsTest.res
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ let isEqual = (~msg="", v1, v2) => {
}
}

let test = () => {
let getTextPartsTest = () => {
isEqual(
~msg="Term at the start",
HighlightTerms.getTextParts(~text="OneTwoThreeFourFive", ~terms=["One"]),
Expand Down Expand Up @@ -62,4 +62,103 @@ let test = () => {
)
}

test()
let getTermGroupsTest = () => {
isEqual(
~msg="Empty search string, no groups",
HighlightTerms.getTermGroups(~entityName="OneTwoThreeFourFive", ~searchString=""),
[],
)

isEqual(
~msg="The same term as entity name is a group with a single item",
HighlightTerms.getTermGroups(
~entityName="OneTwoThreeFourFive",
~searchString="onetwothreefourfive",
),
[["onetwothreefourfive"]],
)

isEqual(
~msg="Two terms with space is a single group with two terms",
HighlightTerms.getTermGroups(~entityName="OneTwoThreeFourFive", ~searchString="one two"),
[["one", "two"]],
)

isEqual(
~msg="Two terms with comma are two groups.",
HighlightTerms.getTermGroups(~entityName="OneTwoThreeFourFive", ~searchString="one,two"),
[["one"], ["two"]],
)

isEqual(
~msg="Three terms with comma (2 and 1)",
HighlightTerms.getTermGroups(~entityName="OneTwoThreeFourFive", ~searchString="one two, three"),
[["one", "two"], ["three"]],
)

isEqual(
~msg="Three terms with comma (1 and 2)",
HighlightTerms.getTermGroups(~entityName="OneTwoThreeFourFive", ~searchString="one, two three"),
[["one"], ["two", "three"]],
)

isEqual(
~msg="One letter term is filtered out",
HighlightTerms.getTermGroups(~entityName="OneTwoThreeFourFive", ~searchString="one t"),
[["one"]],
)
}

let getMatchingTermsTest = () => {
// If we use spaces between terms we expect all of them to be included to get more precise search results.
// If we use commas between terms we expect terms from one or another group to be included.

isEqual(
~msg="One exact term match",
HighlightTerms.getMatchingTerms(
~entityName="OneTwoThreeFourFive",
~searchString="onetwothreefourfive",
),
["onetwothreefourfive"],
)

isEqual(
~msg="Single term match",
HighlightTerms.getMatchingTerms(~entityName="OneTwoThreeFourFive", ~searchString="one"),
["one"],
)

isEqual(
~msg="Two required terms match",
HighlightTerms.getMatchingTerms(~entityName="OneTwoThreeFourFive", ~searchString="one two"),
["one", "two"],
)

isEqual(
~msg="Two required terms or one required term, all match",
HighlightTerms.getMatchingTerms(
~entityName="OneTwoThreeFourFive",
~searchString="one two, three",
),
["one", "two", "three"],
)

isEqual(
~msg="Two terms, the alternative term is missing, one match",
HighlightTerms.getMatchingTerms(
~entityName="OneTwoThreeFourFive",
~searchString="missing, one",
),
["one"],
)

isEqual(
~msg="Two required terms, one of them is missing, no match",
HighlightTerms.getMatchingTerms(~entityName="OneTwoThreeFourFive", ~searchString="one missing"),
[],
)
}

getTextPartsTest()
getTermGroupsTest()
getMatchingTermsTest()
File renamed without changes.
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1299,9 +1299,9 @@ find-up@^3.0.0:
locate-path "^3.0.0"

follow-redirects@^1.0.0:
version "1.13.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267"
integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==
version "1.14.8"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==

for-in@^1.0.2:
version "1.0.2"
Expand Down Expand Up @@ -2092,9 +2092,9 @@ minimatch@^3.0.4:
brace-expansion "^1.1.7"

minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==

mixin-deep@^1.2.0:
version "1.3.2"
Expand Down Expand Up @@ -3325,9 +3325,9 @@ urix@^0.1.0:
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=

url-parse@^1.4.3, url-parse@^1.4.7:
version "1.5.3"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862"
integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==
version "1.5.10"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"
Expand Down

0 comments on commit 9fdfb3d

Please sign in to comment.