Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix for sveltekit #3

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
*.log
*.lock
pnpm-lock.yaml
package-lock.json
/dist
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "svelte-recaptcha-v2",
"version": "0.0.2",
"version": "0.0.3",
"description": "Google ReCaptcha v2 implementation for Svelte and SvelteKit",
"scripts": {
"build": "rollup -c",
Expand Down Expand Up @@ -49,6 +49,6 @@
"svelte": "^3.44.0"
},
"dependencies": {
"debug": "^4.3.2"
"debug": "npm:@milahu/debug-esm@^4.3.5"
}
}
}
160 changes: 80 additions & 80 deletions src/Recaptcha.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
which can then be accessed by parent components.

|-----------------------------------------------------------------┐
└-->
└-->
<script context="module">
import { defer } from "./lib";
import defer from "./lib/defer.js";

//svelte-ignore unused-export-let
export let recaptcha;
Expand All @@ -25,12 +25,12 @@ export let observer = defer();
</script>

<!----------------------------------------------------------------┐
└-->
└-->
<script>
import { createEventDispatcher } from "svelte";
import { onMount, onDestroy } from "svelte";
import { default as createDebug } from "debug";
import { browser } from "./lib";
import createDebug from "debug";
import browser from "./lib/browser.js";

const dbg = createDebug("{Recaptcha}");
const debug = dbg;
Expand Down Expand Up @@ -109,10 +109,10 @@ const eventEmitters = {
debug("captcha window was closed");
dispatch("close");
} /*
│close mutation fires twice, probably because
│of event bubbling or something. we also want
│to avoid signalling when user solves the captcha.
*/
│close mutation fires twice, probably because
│of event bubbling or something. we also want
│to avoid signalling when user solves the captcha.
*/
},
}; /*
│these emitters are referenced to google recaptcha so
Expand Down Expand Up @@ -214,9 +214,9 @@ const captcha = {

recaptcha = window.grecaptcha;
/*
│associate window component to svelte, this allows us
│to export grecaptcha methods in parent components.
*/
│associate window component to svelte, this allows us
│to export grecaptcha methods in parent components.
*/

window.grecaptcha.ready(() => {
instanceId = grecaptcha.render("googleRecaptchaDiv", {
Expand Down Expand Up @@ -264,11 +264,11 @@ const captcha = {
} catch (err) {
console.log(err.message);
} /*
│extremely important to cleanup our mess, otherwise
│everytime the component is invoked, a new recaptcha
│iframe will get instated. Also, with SSR we need to
│make sure all this stuff is wrapped within browser.
*/
│extremely important to cleanup our mess, otherwise
│everytime the component is invoked, a new recaptcha
│iframe will get instated. Also, with SSR we need to
│make sure all this stuff is wrapped within browser.
*/
},
};

Expand Down Expand Up @@ -326,32 +326,32 @@ const sleep = (seconds) =>
</script>

<!----------------------------------------------------------------┐
└-->
└-->

<div id="googleRecaptchaDiv" class="g-recaptcha" />

<!--------------------------------------------------- comments ----;

|\/\/\/| Google's recaptcha, or reCaptcha, or gReCaptcha
| | or greCaptcha is a valuable tool in defending your
| (o)(o) webforms.
C _)
|\/\/\/| Google's recaptcha, or reCaptcha, or gReCaptcha
| | or greCaptcha is a valuable tool in defending your
| (o)(o) webforms.
C _)
| / Final Update: There are different ways to inject
/____\ a piece of javascript into a template. They all come
/ \ with their own drawbacks.
/____\ a piece of javascript into a template. They all come
/ \ with their own drawbacks.


These drawbacks are mostly related to injecting code too fast,
too slow, not slow enough, not fast enough, and not being able to
tell if the injection has completed and the script api is
available for consumption.
These drawbacks are mostly related to injecting code too fast,
too slow, not slow enough, not fast enough, and not being able to
tell if the injection has completed and the script api is
available for consumption.

1.Inject with svelte:head
--------------------------
This works most of the time, but it could have problems during
component rerendering and cleanup. Like we have done in the demo,
when the user switches between different captcha methods, plain
svelte:head would fail.
1.Inject with svelte:head
--------------------------
This works most of the time, but it could have problems during
component rerendering and cleanup. Like we have done in the demo,
when the user switches between different captcha methods, plain
svelte:head would fail.

...

Expand All @@ -376,66 +376,66 @@ const sleep = (seconds) =>
{/await}
</svelte:head>

That await upthere doesn't really wait for the sleep, but it
seems to trigger the necessary gap for this to work with forcing
rerenders.
That await upthere doesn't really wait for the sleep, but it
seems to trigger the necessary gap for this to work with forcing
rerenders.

Besides that, this was the most straight forward approach.
Besides that, this was the most straight forward approach.


2.Write to document
---------------------------
Very straight forward, works fine with forcing dynamic rerender.
It injects and cleans up artifacts smoothly, but when it comes
to creating the link between svelte and 3rd party script, it
could try to do it too fast, and we would get an "undefined"
`recaptcha` export.
2.Write to document
---------------------------
Very straight forward, works fine with forcing dynamic rerender.
It injects and cleans up artifacts smoothly, but when it comes
to creating the link between svelte and 3rd party script, it
could try to do it too fast, and we would get an "undefined"
`recaptcha` export.

To circumvent the problem, we not only track the script load state
with our custom observer, but also track if the google `recaptcha`
is actually available and ready to be consumed via using good old
setInterval.
To circumvent the problem, we not only track the script load state
with our custom observer, but also track if the google `recaptcha`
is actually available and ready to be consumed via using good old
setInterval.


3.Rendering of reCaptcha
---------------------------
Google fills in a destination you provide with the recaptcha
button, that is if you are using one of the normal or compact
sizes.
3.Rendering of reCaptcha
---------------------------
Google fills in a destination you provide with the recaptcha
button, that is if you are using one of the normal or compact
sizes.

Our div is called `googleRecaptchaDiv` and we are rendering it
through window.grecaptcha provided by google. This is when we
let recaptcha know about our event emitters and what to do for
each case.
Our div is called `googleRecaptchaDiv` and we are rendering it
through window.grecaptcha provided by google. This is when we
let recaptcha know about our event emitters and what to do for
each case.

Finally, the callback functions for the recaptha object
could be defined in the div tag probably in another universe.
Finally, the callback functions for the recaptha object
could be defined in the div tag probably in another universe.

<div id="recaptcha" class="g-recaptcha"
data-callback="onSuccess"
data-error-callback="onError"
data-expired-callback="onExpired"
data-size={invisible ? "invisible" : ""}
<div id="recaptcha" class="g-recaptcha"
data-callback="onSuccess"
data-error-callback="onError"
data-expired-callback="onExpired"
data-size={invisible ? "invisible" : ""}


Flow of Events
---------------------------
.inject script and provide google a function to callback onLoad
.start waiting
.onLoad -> apiOnLoad proceed
.wait for recaptcha to become available
.render 3rd party API
.fire events to keep svelte in loop.
Flow of Events
---------------------------
.inject script and provide google a function to callback onLoad
.start waiting
.onLoad -> apiOnLoad proceed
.wait for recaptcha to become available
.render 3rd party API
.fire events to keep svelte in loop.


Notes to Future Self
---------------------------
Remind yourself to smile whether you are reading, writing or coding.
Especially when coding.
Notes to Future Self
---------------------------
Remind yourself to smile whether you are reading, writing or coding.
Especially when coding.


Notes to Fellow Programmer
---------------------------
Same. Hope you find this useful.
Notes to Fellow Programmer
---------------------------
Same. Hope you find this useful.

|------------------------------------------------------------------>
3 changes: 2 additions & 1 deletion src/lib/browser.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const browser = (() => {
const browser = (() => {
return typeof window === "object" && typeof window.document === "object";
})();
export default browser;
6 changes: 4 additions & 2 deletions src/lib/defer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const defer = () => {
const defer = () => {
var res, rej;

var promise = new Promise((resolve, reject) => {
Expand All @@ -10,4 +10,6 @@ export const defer = () => {
promise.reject = rej;

return promise;
};
};

export default defer;
2 changes: 0 additions & 2 deletions src/lib/index.js

This file was deleted.