Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Machy8 committed Nov 7, 2023
1 parent ea772dc commit 285c6e0
Show file tree
Hide file tree
Showing 23 changed files with 512 additions and 511 deletions.
25 changes: 13 additions & 12 deletions packages/signalizejs/ajax/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Signalize, CustomEventListener } from 'signalizejs';
import type { Signalize, SignalizePlugin, CustomEventListener } from 'signalizejs';

declare module 'signalizejs' {
interface Signalize {
Expand All @@ -11,26 +11,27 @@ declare module 'signalizejs' {
'ajax:request:error': CustomEventListener
'ajax:request:end': CustomEventListener
}

interface SignalizeConfig {
ajaxRequestedWithHeader: string
}
}

export interface AjaxReturn {
response: Response | null
error: any
}

export interface AjaxOptions extends RequestInit {
export interface AjaxRequestOptions extends RequestInit {
url: string
data?: Record<string, any>
}

export default ($: Signalize): void => {
$.on('signalize:ready', () => {
const { config, dispatch } = $;
$.ajax = async (options: AjaxOptions): Promise<AjaxReturn> => {
export interface AjaxOptions {
requestedWithHeader: string
}

export default (pluginOptions?: AjaxOptions): SignalizePlugin => {
return ($: Signalize) => {
const { dispatch } = $;

$.ajax = async (options: AjaxRequestOptions): Promise<AjaxReturn> => {
let response: Response | null = null;
let error: Error | null = null

Expand All @@ -54,7 +55,7 @@ export default ($: Signalize): void => {
const url = options.url;

const requestInit = { ...options };
requestInit.headers = { ...{ 'X-Requested-With': config.ajaxRequestedWithHeader ?? 'XMLHttpRequest' }, ...requestInit.headers ?? {} }
requestInit.headers = { ...{ 'X-Requested-With': pluginOptions?.requestedWithHeader ?? 'XMLHttpRequest' }, ...requestInit.headers ?? {} }

delete requestInit.url;

Expand Down Expand Up @@ -87,5 +88,5 @@ export default ($: Signalize): void => {
error
}
}
});
}
}
54 changes: 28 additions & 26 deletions packages/signalizejs/asset-loader/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
import type { Signalize, CustomEventListener } from 'signalizejs';
import type { Signalize, SignalizePlugin, CustomEventListener } from 'signalizejs';

declare module 'signalizejs' {
interface Signalize {
loadAssets: (assets: Array<HTMLLinkElement | HTMLScriptElement>) => Promise<void>
}
}

export default ($: Signalize): void => {
$.loadAssets = async (assets: Array<HTMLLinkElement | HTMLScriptElement>): Promise<void> => {
const assetsPromises: Array<Promise<void>> = [];
export default (): SignalizePlugin => {
return ($: Signalize) => {
$.loadAssets = async (assets: Array<HTMLLinkElement | HTMLScriptElement>): Promise<void> => {
const assetsPromises: Array<Promise<void>> = [];

for (const asset of assets) {
const isAsset = 'src' in asset;
const tagName = isAsset ? 'script' : 'link';
const attributeName = isAsset ? 'src' : 'href';
for (const asset of assets) {
const isAsset = 'src' in asset;
const tagName = isAsset ? 'script' : 'link';
const attributeName = isAsset ? 'src' : 'href';

if ($.select(`${tagName}[${attributeName}="${asset[attributeName]}"]`) !== null) {
continue;
}

const assetElement = document.createElement(tagName);
if ($.select(`${tagName}[${attributeName}="${asset[attributeName]}"]`) !== null) {
continue;
}

for (const [key, value] of Object.entries(asset)) {
assetElement.setAttribute(key, value)
}
const assetElement = document.createElement(tagName);

assetsPromises.push(new Promise((resolve, reject) => {
assetElement.onload = () => {
resolve({ asset, assetElement });
for (const [key, value] of Object.entries(asset)) {
assetElement.setAttribute(key, value)
}

assetElement.onerror = (error) => {
reject(error);
assetElement.remove();
}
}))
assetsPromises.push(new Promise((resolve, reject) => {
assetElement.onload = () => {
resolve({ asset, assetElement });
}

assetElement.onerror = (error) => {
reject(error);
assetElement.remove();
}
}))

document.head.appendChild(assetElement);
document.head.appendChild(assetElement);
}
await Promise.all(assetsPromises);
}
await Promise.all(assetsPromises);
}
}
18 changes: 9 additions & 9 deletions packages/signalizejs/dialog/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Signalize, CustomEventListener } from 'signalizejs';
import type { Signalize, SignalizePlugin, CustomEventListener } from 'signalizejs';

declare module 'signalizejs' {

Expand All @@ -14,13 +14,13 @@ declare module 'signalizejs' {
}
}

export default ($: Signalize): void => {
$.on('signalize:ready', () => {
const { dispatch, config, select, on } = $
const dialogAttribute = `${config.attributePrefix}dialog`;
const dialogModelessAttribute = `${dialogAttribute}${config.attributeSeparator}modeless`;
const dialogCloseButtonAttribute = `${dialogAttribute}${config.attributeSeparator}close`;
const dialogOpenButtonAttribute = `${dialogAttribute}${config.attributeSeparator}open`;
export default (): SignalizePlugin => {
return ($: Signalize): void => {
const { dispatch, attributePrefix, attributeSeparator, select, on } = $
const dialogAttribute = `${attributePrefix}dialog`;
const dialogModelessAttribute = `${dialogAttribute}${attributeSeparator}modeless`;
const dialogCloseButtonAttribute = `${dialogAttribute}${attributeSeparator}close`;
const dialogOpenButtonAttribute = `${dialogAttribute}${attributeSeparator}open`;

const getDialog = (id: string): HTMLDialogElement | null => select<HTMLDialogElement>(`[${dialogAttribute}=${id}]`);

Expand Down Expand Up @@ -89,5 +89,5 @@ export default ($: Signalize): void => {
$.openDialog = openDialog;
$.closeDialog = closeDialog;
$.dialog = getDialog;
})
}
}
76 changes: 38 additions & 38 deletions packages/signalizejs/directives/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
import type { Signalize, Scope } from 'signalizejs'
import type { Signalize, SignalizePlugin, Scope } from 'signalizejs'

declare module '..' {
interface Signalize {
directive: (name: string, data: Directive) => void
createDirectiveFunction: (options: CreateFunctionOptions) => () => Promise<any>
AsyncFunction: () => Promise<any>
}

interface SignalizeConfig {
directivesRenderedBlockStart: string
directivesRenderedBlockEnd: string
}
}

type DirectiveCallback = (data: DirectiveCallbackData) => Promise<void> | void;

interface DirectiveCallbackData extends Scope {
element: HTMLElement
matches: RegExpMatchArray
attribute: Attr
}

interface DirectiveMatcherParameters {
element: HTMLElement
element: Element
attribute: Attr
}

Expand All @@ -40,33 +34,39 @@ interface RegisteredDirective extends Directive {
}

interface ProcessDirectiveOptions {
root?: HTMLElement
root?: Element
directiveName?: string
}

interface CreateFunctionOptions {
functionString: string
context: Record<string, any>
element?: HTMLElement | Document | DocumentFragment
element?: Element | Document | DocumentFragment
}

interface PluginOptions {
renderedBlockStart?: string
renderedBlockEnd?: string
}

export default ($: Signalize): void => {
$.on('signalize:ready', () => {
const { bind, on, Signal, scope, signal, config, globals } = $;
export default (options?: PluginOptions): SignalizePlugin => {

return ($: Signalize) => {
const { bind, on, Signal, scope, signal, globals, attributePrefix, attributeSeparator } = $;
const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
const directives: Record<string, RegisteredDirective> = {};
const directivesAttribute = `${config.attributePrefix}directives`;
const ignoreAttribute = `${directivesAttribute}${config.attributeSeparator}ignore`;
const orderAttribute = `${directivesAttribute}${config.attributeSeparator}order`
const renderedTemplateStartComment = config.directivesRenderedBlockStart ?? 'template';
const renderedTemplateEndComment = config.directivesRenderedBlockEnd ?? '/template';
const directivesAttribute = `${attributePrefix}directives`;
const ignoreAttribute = `${directivesAttribute}${attributeSeparator}ignore`;
const orderAttribute = `${directivesAttribute}${attributeSeparator}order`
const renderedTemplateStartComment = options?.renderedBlockStart ?? 'template';
const renderedTemplateEndComment = options?.renderedBlockEnd ?? '/template';
let inited = false;

const processElement = async (element: HTMLElement, directivesToProcess?: string[]): Promise<HTMLElement> => {
const elementClosestScope = element.closest(`[${config.scopeAttribute}]`);
const processElement = async (element: Element, directivesToProcess?: string[]): Promise<Element> => {
const elementClosestScope = element.closest(`[${$.scopeAttribute}]`);
let scopeInitPromise = null;

if (elementClosestScope && typeof elementClosestScope[config.scopeKey] === 'undefined') {
if (elementClosestScope && typeof elementClosestScope[$.scopeKey] === 'undefined') {
scopeInitPromise = new Promise((resolve) => {
on('scope:inited', ({ detail }) => {
if (detail.element === elementClosestScope) {
Expand Down Expand Up @@ -120,7 +120,7 @@ export default ($: Signalize): void => {
elementScope.directives.add(directiveName);
});

countdown --;
countdown--;
directivesPromises.push(
directive.callback({
...elementScope,
Expand All @@ -144,24 +144,24 @@ export default ($: Signalize): void => {

await processDirectiveFromQueue(directivesQueue.shift());

element.removeAttribute(config.cloakAttribute);
element.removeAttribute($.cloakAttribute);
}

return element;
};

const processDirectives = async (options: ProcessDirectiveOptions = {}): Promise<HTMLElement | Document | DocumentFragment> => {
const { root = config.root, directiveName } = options;
const processDirectives = async (options: ProcessDirectiveOptions = { root: $.root }): Promise<Element | Document | DocumentFragment> => {
let { root, directiveName } = options;
const directivesToProcess = directiveName === undefined ? Object.keys(directives) : [directiveName];

const processElements = async (root): Promise<void> => {
const rootIsHtmlElement = root instanceof HTMLElement;
const rootIsElement = root instanceof Element;

if (rootIsHtmlElement && root?.closest(`[${ignoreAttribute}]`)) {
if (rootIsElement && root?.closest(`[${ignoreAttribute}]`)) {
return;
}

if (rootIsHtmlElement) {
if (rootIsElement) {
await processElement(root, directivesToProcess);
}

Expand Down Expand Up @@ -219,11 +219,11 @@ export default ($: Signalize): void => {
return null
}
}
return createFunctionCache[cacheKey].bind(undefined)
return createFunctionCache[cacheKey];
}

directive('signal', {
matcher: new RegExp(`(?:\\$|${config.attributePrefix}signal${config.attributeSeparator})(\\S+)`),
matcher: new RegExp(`(?:\\$|${attributePrefix}signal${attributeSeparator})(\\S+)`),
callback: async ({ matches, element, data, attribute }): Promise<void> => {
const fn = createFunction({
functionString: `return ${attribute.value.length ? attribute.value : "''"}`,
Expand All @@ -246,7 +246,7 @@ export default ($: Signalize): void => {
return;
}

return new RegExp(`(?::|${config.attributePrefix})for`);
return new RegExp(`(?::|${attributePrefix})for`);
},
callback: async ({ element, data, attribute }) => {
if (element.tagName.toLowerCase() !== 'template') {
Expand Down Expand Up @@ -486,7 +486,7 @@ export default ($: Signalize): void => {
return;
}

return new RegExp(`(?::|${config.attributePrefix})if`);
return new RegExp(`(?::|${attributePrefix})if`);
},
callback: async ({ element, data, attribute }) => {
const fn = createFunction({
Expand All @@ -500,7 +500,7 @@ export default ($: Signalize): void => {
const signalsToWatch = [];

for (const signal of Object.values(data)) {
if (!(signal instanceof Signal)) {
if (!(signal instanceof $.Signal)) {
continue;
}

Expand Down Expand Up @@ -611,7 +611,7 @@ export default ($: Signalize): void => {
return;
}

return new RegExp(`(?::|${config.attributePrefix}bind${config.attributeSeparator})(\\S+)|(\\{([^{}]+)\\})`)
return new RegExp(`(?::|${attributePrefix}bind${attributeSeparator})(\\S+)|(\\{([^{}]+)\\})`)
},
callback: async ({ matches, element, data, attribute }) => {
const isShorthand = attribute.name.startsWith('{');
Expand All @@ -630,7 +630,7 @@ export default ($: Signalize): void => {
let signalsToWatch = [];

for (const signal of Object.values(data)) {
if (!(signal instanceof Signal)) {
if (!(signal instanceof $.Signal)) {
continue;
}

Expand All @@ -649,7 +649,7 @@ export default ($: Signalize): void => {
});

directive('on', {
matcher: new RegExp(`(?:\\@|${config.attributePrefix}on${config.attributeSeparator})(\\S+)`),
matcher: new RegExp(`(?:\\@|${attributePrefix}on${attributeSeparator})(\\S+)`),
callback: async (scope) => {
const { matches, element, data, attribute } = scope;

Expand Down Expand Up @@ -684,7 +684,7 @@ export default ($: Signalize): void => {

on('dom:mutation:node:added', (event) => {
const node = event.detail;
if (!(node instanceof HTMLElement) || scope(node)?.directives !== undefined) {
if (!(node instanceof Element) || scope(node)?.directives !== undefined) {
return;
}

Expand All @@ -695,5 +695,5 @@ export default ($: Signalize): void => {
$.AsyncFunction = AsyncFunction;
$.createDirectiveFunction = createFunction;
$.directive = directive;
})
}
}
Loading

0 comments on commit 285c6e0

Please sign in to comment.