Skip to content

Commit

Permalink
fix: style loaded when sprite is missing
Browse files Browse the repository at this point in the history
resolves #359
  • Loading branch information
kevinchappell committed Nov 7, 2024
1 parent 46771a8 commit 846710d
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 24 deletions.
53 changes: 38 additions & 15 deletions src/lib/js/common/loaders.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import dom from './dom.js'
import {
CSS_URL,
FALLBACK_CSS_URL,
FALLBACK_SVG_SPRITE_URL,
POLYFILLS,
SVG_SPRITE_URL,
formeoSpriteId,
} from '../constants.js'
import { FALLBACK_CSS_URL, FALLBACK_SVG_SPRITE_URL, POLYFILLS, SVG_SPRITE_URL, formeoSpriteId } from '../constants.js'
import { noop } from './utils/index.mjs'

/* global fetch */

const loaded = {
js: new Set(),
css: new Set(),
Expand All @@ -31,7 +22,6 @@ export const ajax = (fileUrl, callback, onError = noop) => {

const onLoadStylesheet = (elem, cb) => {
elem.removeEventListener('load', onLoadStylesheet)
elem.rel = 'stylesheet'
cb(elem.src)
}

Expand Down Expand Up @@ -79,9 +69,8 @@ export const insertStyle = srcs => {
const styleLink = dom.create({
tag: 'link',
attrs: {
rel: 'preload',
rel: 'stylesheet',
href: src,
as: 'style',
},
action: {
load: () => onLoadStylesheet(styleLink, resolve),
Expand All @@ -96,6 +85,12 @@ export const insertStyle = srcs => {
return Promise.all(promises)
}

/**
* Inserts multiple script elements into the document.
*
* @param {string|string[]} srcs - A single script source URL or an array of script source URLs.
* @returns {Promise<void[]>} A promise that resolves when all scripts have been loaded.
*/
export const insertScripts = srcs => {
srcs = Array.isArray(srcs) ? srcs : [srcs]
const promises = srcs.map(src => insertScript(src))
Expand Down Expand Up @@ -145,6 +140,11 @@ export const insertIcons = iconSvgStr => {
* @returns {Promise<void>} A promise that resolves when the icons are fetched and inserted.
*/
export const fetchIcons = async (iconSpriteUrl = SVG_SPRITE_URL) => {
const formeoSprite = document.getElementById(formeoSpriteId)
if (formeoSprite) {
return
}

const parseResp = async resp => insertIcons(await resp.text())
return ajax(iconSpriteUrl, parseResp, () => ajax(FALLBACK_SVG_SPRITE_URL, parseResp))
}
Expand All @@ -161,24 +161,47 @@ export const LOADER_MAP = {
css: insertStyles,
}

/**
* Fetches and loads the specified dependencies.
*
* @param {Object} dependencies - An object where keys are dependency types and values are the source URLs.
* @returns {Promise<Array>} A promise that resolves to an array of results from loading each dependency.
*/
export const fetchDependencies = dependencies => {
const promises = Object.entries(dependencies).map(([type, src]) => {
return LOADER_MAP[type](src)
})
return Promise.all(promises)
}

/**
* Checks if the CSS for the Formeo sprite is loaded.
*
* This function determines if the CSS for the Formeo sprite is loaded by checking
* the visibility property of the sprite's computed style. If the visibility is
* 'hidden', it is assumed that the CSS is loaded.
*
* @returns {boolean} True if formeo CSS is loaded, false otherwise.
*/
export const isCssLoaded = () => {
const formeoSprite = document.getElementById(formeoSpriteId)
const computedStyle = window.getComputedStyle(formeoSprite)

return computedStyle.visibility === 'hidden'
}

export const fetchFormeoStyle = async () => {
/**
* Fetches and inserts the Formeo style sheet from the given URL.
* If the necessary styles are not loaded, it attempts to insert the style sheet.
* If the styles are still not loaded, it uses a fallback URL to insert the style sheet.
*
* @param {string} cssUrl - The URL of the CSS file to be loaded.
* @returns {Promise<void>} A promise that resolves when the style sheet is loaded.
*/
export const fetchFormeoStyle = async cssUrl => {
// check if necessary styles were loaded
if (!isCssLoaded()) {
await insertStyle(CSS_URL)
await insertStyle(cssUrl)
// check again and use fallback if necessary styles were not loaded
if (!isCssLoaded()) {
return await insertStyle(FALLBACK_CSS_URL)
Expand Down
3 changes: 2 additions & 1 deletion src/lib/js/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import mi18n from '@draggable/i18n'
import { isIE } from './common/helpers'
import { SVG_SPRITE_URL } from './constants'
import { CSS_URL, SVG_SPRITE_URL } from './constants'
const enUS = import.meta.env.enUS

mi18n.addLanguage('en-US', enUS)
Expand All @@ -16,6 +16,7 @@ export const defaults = {
editorContainer: null, // element or selector to attach editor to
external: {}, // assign external data to be used in conditions autolinker
svgSprite: SVG_SPRITE_URL, // change to null
style: CSS_URL, // change to null
iconFont: null, // 'glyphicons' || 'font-awesome' || 'fontello'
config: {}, // stages, rows, columns, fields
events: {},
Expand Down
12 changes: 4 additions & 8 deletions src/lib/js/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import Events from './common/events.js'
import Actions from './common/actions.js'
import Controls from './components/controls/index.js'
import Components from './components/index.js'
import { loadPolyfills, insertStyle, fetchIcons, isCssLoaded, fetchFormeoStyle } from './common/loaders.js'
import { SESSION_LOCALE_KEY, CSS_URL } from './constants.js'
import { loadPolyfills, fetchIcons, fetchFormeoStyle } from './common/loaders.js'
import { SESSION_LOCALE_KEY } from './constants.js'
import { merge } from './common/utils/index.mjs'
import { defaults } from './config.js'
import '../sass/formeo.scss'
Expand Down Expand Up @@ -65,19 +65,15 @@ export class FormeoEditor {
loadPolyfills(this.opts.polyfills)
}

if (this.opts.style) {
promises.push(insertStyle(this.opts.style))
}

// Ajax load svgSprite and inject into markup.
promises.push(fetchIcons(this.opts.svgSprite))
await fetchIcons(this.opts.svgSprite)
promises.push(fetchFormeoStyle(this.opts.style))

promises.push(i18n.init({ ...this.opts.i18n, locale: window.sessionStorage?.getItem(SESSION_LOCALE_KEY) }))

const resolvedPromises = await Promise.all(promises)

fetchFormeoStyle()

if (this.opts.allowEdit) {
this.init()
}
Expand Down

0 comments on commit 846710d

Please sign in to comment.