Skip to content

Commit

Permalink
feat: loadCSS, loadScript to support options
Browse files Browse the repository at this point in the history
  • Loading branch information
kirillgroshkov committed Mar 15, 2024
1 parent 3c79808 commit 727d5bb
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 45 deletions.
2 changes: 1 addition & 1 deletion docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default defineConfig({
text: 'Features',
collapsed: false,
items: [
{ text: 'loadScript', link: '/loadScript' },
{ text: 'loadScript, loadCSS', link: '/loadScript' },
{ text: 'TranslationService', link: '/translation' },
{ text: 'Analytics', link: '/analytics' },
{ text: 'AdminService', link: '/adminService' },
Expand Down
34 changes: 29 additions & 5 deletions docs/components/LoadScriptDemo.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
<script setup lang="ts">
import { _stringifyAny } from '@naturalcycles/js-lib'
import { _stringify } from '@naturalcycles/js-lib'
import { ref } from 'vue'
import { loadScript } from '../../src'
import { loadCSS, loadScript } from '../../src'
const loading = ref(false)
async function loadGood() {
await load(`https://unpkg.com/jquery@3.6.0/dist/jquery.js`)
loading.value = false
}
async function loadBad() {
await load(`https://unpkg.com/jqueryNON_EXISTING`)
loading.value = false
}
async function loadGoodCSS() {
await loadStylesheet(`https://cdn.simplecss.org/simple.min.css`)
}
async function loadBadCSS() {
await loadStylesheet(`https://cdn.simplecss.org/simpleNOTFOUND.min.css`)
}
async function load(src: string) {
Expand All @@ -22,7 +28,22 @@ async function load(src: string) {
await loadScript(src)
alert('loaded ok')
} catch (err) {
alert(_stringifyAny(err))
alert(_stringify(err))
} finally {
loading.value = false
}
}
async function loadStylesheet(src: string) {
loading.value = true
try {
await loadCSS(src)
alert('loaded ok')
} catch (err) {
alert(_stringify(err))
} finally {
loading.value = false
}
}
</script>
Expand All @@ -31,6 +52,9 @@ async function load(src: string) {
<div class="app-content">
<button @click="loadGood">Load good script</button>
<button @click="loadBad">Load bad script</button>
<br /><br />
<button @click="loadGoodCSS">Load good CSS</button>
<button @click="loadBadCSS">Load bad CSS</button>
<p v-if="loading">loading...</p>
</div>
</template>
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ yarn add @naturalcycles/frontend-lib

## Features

- [loadScript](loadScript.md)
- [loadScript, loadCSS](loadScript.md)
- [TranslationService](translation.md) <Badge text="experimental" type="warning"/>
- [Analytics](analytics.md)
- loadGTag
Expand Down
4 changes: 2 additions & 2 deletions docs/loadScript.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# loadScript
# loadScript, loadCSS

```typescript
await loadScript('https://gtm.com/script.js')
Expand All @@ -8,7 +8,7 @@ await loadScript('https://gtm.com/script.js')
Works in old-school (and reliable) way by injecting a `<script>` tag into dom and attaching onload
event that resolves the promise. `onerror` rejects the promise.

See console output, but it will also do `alert(_stringifyAny(err))`.
See console output, but it will also do `alert(_stringify(err))`.

<script setup>
import LoadScriptDemo from './components/LoadScriptDemo.vue'
Expand Down
4 changes: 2 additions & 2 deletions src/admin/adminService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Promisable, _Memo, _stringifyAny, isServerSide } from '@naturalcycles/js-lib'
import { Promisable, _Memo, _stringify, isServerSide } from '@naturalcycles/js-lib'

export interface AdminModeCfg {
/**
Expand Down Expand Up @@ -117,7 +117,7 @@ export class AdminService {
} catch (err) {
console.error(err)
// ok to show alert to Admins, it's not user-facing
alert(_stringifyAny(err))
alert(_stringify(err))
return // treat as "not allowed"
}

Expand Down
22 changes: 0 additions & 22 deletions src/script/script.util.test.ts

This file was deleted.

60 changes: 48 additions & 12 deletions src/script/script.util.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,51 @@
/* eslint-disable unicorn/prefer-add-event-listener */

export async function loadScript(src: string, async = true): Promise<void> {
// eslint-disable-next-line @typescript-eslint/return-await
return new Promise<void>((resolve, reject) => {
const s = document.createElement('script')
s.src = src
s.onload = resolve as any
s.onerror = (_event, _source, _lineno, _colno, error) => {
reject(error || new Error(`loadScript failed: ${src}`))
}
if (async) s.async = true
import { _objectAssign, isServerSide } from '@naturalcycles/js-lib'

export type LoadScriptOptions = Partial<HTMLScriptElement>
export type LoadCSSOptions = Partial<HTMLLinkElement>

/**
* opt.async defaults to `true`.
* No other options are set by default.
*/
export async function loadScript(src: string, opt?: LoadScriptOptions): Promise<void> {
if (isServerSide()) return

return await new Promise<void>((resolve, reject) => {
const s = _objectAssign(document.createElement('script'), {
src,
async: true,
...opt,
onload: resolve as any,
onerror: (_event, _source, _lineno, _colno, err) => {
reject(err || new Error(`loadScript failed: ${src}`))
},
})
document.head.append(s)
})
}

/**
* Default options:
* rel: 'stylesheet'
*
* No other options are set by default.
*/
export async function loadCSS(href: string, opt?: LoadCSSOptions): Promise<void> {
if (isServerSide()) return

return await new Promise<void>((resolve, reject) => {
const link = _objectAssign(document.createElement('link'), {
href,
rel: 'stylesheet',
// type seems to be unnecessary: https://stackoverflow.com/a/5409146/4919972
// type: 'text/css',
...opt,
onload: resolve as any,
onerror: (_event, _source, _lineno, _colno, err) => {
reject(err || new Error(`loadCSS failed: ${href}`))
},
})

document.head.append(link)
})
}

0 comments on commit 727d5bb

Please sign in to comment.