Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Machy8 committed Feb 22, 2024
1 parent ba732b2 commit e66000b
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 111 deletions.
2 changes: 1 addition & 1 deletion packages/signalizejs/src/Signalize.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import bind from './plugins/bind.js';
import dispatch from './plugins/dispatch.js'
import dispatch from './plugins/dispatch.js';
import domReady from './plugins/dom-ready.js';
import mutationsObserver from './plugins/mutation-observer.js';
import on from './plugins/on.js';
Expand Down
29 changes: 18 additions & 11 deletions packages/signalizejs/src/plugins/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,32 @@
export default ($) => {
const { signal, dispatch, scope } = $;

const componentAttribute = `${$.attributePrefix}component`;
const cloakAttribute = `${$.attributePrefix}cloak`;
$.componentAttribute = componentAttribute;

/**
* Creates a custom Web Component with the specified name and options.
* Creates a custom Web Component with the specified name and options
*
* @function
* @param {string} name - The name of the component.
* @param {ComponentOptions} [options] - Options for configuring the component.
* @param {ComponentOptions} [optionsOrSetup] - Options for configuring the component.
* @returns {typeof HTMLElement} The constructor function for the component.
*/
const component = (name, options) => {
const component = (name, optionsOrSetup) => {
let options = optionsOrSetup;
let setup = null;

if (typeof optionsOrSetup === 'function') {
options = {};
setup = optionsOrSetup;
} else {
setup = options?.setup;
}

let componentName = `${$.componentPrefix}${name}`;

if (customElements.get(componentName) !== undefined) {
throw new Error(`Custom element "${componentName}" already defined.`);
console.warn(`Custom element "${componentName}" already defined. Skipping.`);
return;
}

const properties = {};
Expand Down Expand Up @@ -150,8 +159,8 @@ export default ($) => {
this.attributeChangedCallback(attr.name, undefined, this.#scope.$el.getAttribute(attr.name));
}

if (options?.setup !== undefined) {
const data = await options?.setup?.call(undefined, {
if (setup !== undefined) {
const data = await setup?.call(undefined, {
...this.#scope,
$connected: (listener) => {
this.#connected = listener;
Expand Down Expand Up @@ -198,8 +207,6 @@ root
select('slot:not([name])', template.content)?.replaceWith(currentTemplate.content);
} */

this.setAttribute(componentAttribute, name);

dispatch('component:setuped', this.#scope, { target: this.#scope.$el, bubbles: true });
this.#scope._setuped = true;
}
Expand Down Expand Up @@ -235,7 +242,7 @@ root
valueToSet = valueToSet.length > 0 ? !!valueToSet : this.#scope.$el.hasAttribute(name);
}

currentProperty(valueTypeMap[valueToSet] ?? valueToSet);
currentProperty(valueToSet in valueTypeMap ? valueTypeMap[valueToSet] : valueToSet);
}

/**
Expand Down
21 changes: 13 additions & 8 deletions packages/signalizejs/src/plugins/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ export default () => {
const closeOnBackDropClickListener = (event) => {
let rect = event.target.getBoundingClientRect();

if (rect.left > event.clientX ||
if ((rect.left > event.clientX ||
rect.right < event.clientX ||
rect.top > event.clientY ||
rect.bottom < event.clientY
rect.bottom < event.clientY) &&
event.target.tagName.toLowerCase() === 'dialog'
) {
const dialog = event.target.closest('dialog');
closeDialog(dialog);
off('click', dialog, closeOnBackDropClickListener);
closeDialog(event.target);
off('click', event.target, closeOnBackDropClickListener);
}
};

Expand Down Expand Up @@ -118,15 +118,20 @@ export default () => {
};

on('dom:ready', () => {
on('click', `[${dialogCloseButtonAttribute}]`, ({ target }) => {
const dialog = target.getAttribute[`${dialogCloseButtonAttribute}`] ?? target.closest(`[${dialogAttribute}]`);
on('click', `[${dialogCloseButtonAttribute}]`, (event) => {
event.preventDefault();
const { target } = event;
const dialogId = target.getAttribute(dialogCloseButtonAttribute);
let dialog = dialogId.trim().length === 0 ? target.closest('dialog') : dialogId;

if (dialog !== null) {
closeDialog(dialog);
}
});

on('click', `[${dialogOpenButtonAttribute}]`, ({ target }) => {
on('click', `[${dialogOpenButtonAttribute}]`, (event) => {
event.preventDefault();
const { target } = event;
const dialog = getDialog(target.getAttribute(dialogOpenButtonAttribute));

if (dialog != null) {
Expand Down
4 changes: 2 additions & 2 deletions packages/signalizejs/src/plugins/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,12 @@ export default (pluginOptions) => {
const isShorthand = attribute.name.startsWith('{');
const attributeValue = isShorthand ? matches[3] : attribute.value;
const attributeName = isShorthand ? matches[3] : matches[1];
let trackedSignals;
let trackedSignals = [];
const get = (trackSignals) => {
const { result, signalsToWatch } = $.evaluate(attributeValue, scope, trackSignals);

if (trackSignals) {
trackedSignals = signalsToWatch ?? [];
trackedSignals = signalsToWatch;
}

return typeof result === 'function' ? result() : result;
Expand Down
32 changes: 17 additions & 15 deletions packages/signalizejs/src/plugins/offset.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,26 @@
* @property {number} right - The right offset value.
*/

/**
* @param {import('../Signalize').Signalize} $
* @returns {void}
*/
export default ($) => {
export default () => {
/**
* @param {Element} element
* @returns {Offset}
* @param {import('../Signalize').Signalize} $
* @returns {void}
*/
$.offset = (element) => {
const rect = element.getBoundingClientRect();
const defaultView = element.ownerDocument.defaultView;
return ($) => {
/**
* @param {Element} element
* @returns {Offset}
*/
$.offset = (element) => {
const rect = element.getBoundingClientRect();
const defaultView = element.ownerDocument.defaultView;

return {
top: rect.top + (defaultView !== null ? defaultView.scrollY : 0),
bottom: rect.bottom + (defaultView !== null ? defaultView.scrollY : 0),
left: rect.left + (defaultView !== null ? defaultView.scrollX : 0),
right: rect.right + (defaultView !== null ? defaultView.scrollX : 0)
return {
top: rect.top + (defaultView !== null ? defaultView.scrollY : 0),
bottom: rect.bottom + (defaultView !== null ? defaultView.scrollY : 0),
left: rect.left + (defaultView !== null ? defaultView.scrollX : 0),
right: rect.right + (defaultView !== null ? defaultView.scrollX : 0)
};
};
};
};
4 changes: 2 additions & 2 deletions packages/signalizejs/src/plugins/on.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@
export default ($) => {
/** @type {Record<string,CustomEventListener>} */
const customEventListeners = {
clickOutside: {
clickoutside: {
on: ({ target, listener, options }) => {
document.addEventListener('click', (listenerEvent) => {
/** @type {Element} */
const eventTarget = listenerEvent.target;

if ((typeof target === 'string' && (eventTarget.matches(target) || eventTarget.closest(target) !== null)) ||
(target instanceof Element && target === eventTarget)
(target instanceof Element && (target === eventTarget || target.contains(eventTarget)))
) {
return;
}
Expand Down
16 changes: 14 additions & 2 deletions packages/signalizejs/src/plugins/scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
export default ($) => {
const scopeKey = '__signalizeScope';
const refAttribute = `${$.attributePrefix}ref`;
const componentAttribute = $.componentAttribute;

class Scope {
/**
Expand Down Expand Up @@ -142,7 +141,20 @@ export default ($) => {
*/
$refs = (name) => {
return [...this.$el.querySelectorAll(`[${refAttribute}=${name}]`)].filter((element) => {
return element.closest(`[${componentAttribute}]`) !== this.$el;
const checkParentElement = (el) => {
const parentElement = el.parentNode;
if (parentElement === this.$el) {
return true;
}

if (parentElement.tagName.toLowerCase().includes('-')) {
return false;
}

return checkParentElement(parentElement);
};

return checkParentElement(element);
});
};
}
Expand Down
124 changes: 71 additions & 53 deletions packages/signalizejs/src/plugins/snippets.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,75 +35,93 @@ export default () => {
* @param {string} content
* @returns {void}
*/
$.redrawSnippet = (content) => {
$.redrawSnippet = async (content, options = {}) => {
const fragment = parseHtml(content);
const snippets = [...fragment.querySelectorAll(`[${snippetAttribute}]`)];

while (snippets.length > 0) {
const newSnippet = snippets.shift();
const redraw = () => {
while (snippets.length > 0) {
const newSnippet = snippets.shift();

if (newSnippet?.parentNode?.closest(`[${snippetAttribute}]`) !== null) {
continue;
}
if (newSnippet?.parentNode?.closest(`[${snippetAttribute}]`) !== null) {
continue;
}

const snippetId = newSnippet.getAttribute(snippetAttribute);
let existingSnippet = root.querySelector(`[${snippetAttribute}="${snippetId}"]`);
const snippetId = newSnippet.getAttribute(snippetAttribute);
let existingSnippet = root.querySelector(`[${snippetAttribute}="${snippetId}"]`);

if (existingSnippet === null) {
continue;
}

const snippetAction = newSnippet.getAttribute(`${snippetActionAttribute}`) ?? 'replace';
const eventDispatcherData = {
snippetId,
snippetAction,
newSnippet,
existingSnippet
};

existingSnippet.setAttribute(snippetStateAttribute, 'redrawing');
dispatch('snippets:redraw:start', eventDispatcherData);

if (snippetAction === 'replace') {
newSnippet.setAttribute(snippetStateAttribute, 'redrawing');
existingSnippet.replaceWith(newSnippet);
existingSnippet = newSnippet;
} else if (snippetAction === 'append-children') {
const childrenFragment = new DocumentFragment();
while (newSnippet.lastChild != null) {
childrenFragment.append(newSnippet.lastChild);
if (existingSnippet === null) {
continue;
}

existingSnippet.append(childrenFragment);
} else if (snippetAction === 'prepend-children') {
const childrenFragment = new DocumentFragment();
while (newSnippet.lastChild != null) {
childrenFragment.append(newSnippet.lastChild);
const snippetConfig = {
snippetId,
snippetActions: newSnippet.getAttribute(`${snippetActionAttribute}`)?.split(' ') ?? ['replace'],
newSnippet,
existingSnippet,
...options?.snippets?.[snippetId] ?? {}
};

const { snippetActions } = snippetConfig;

existingSnippet.setAttribute(snippetStateAttribute, 'redrawing');
dispatch('snippets:redraw:start', snippetConfig);

while(snippetActions.length) {
const snippetAction = snippetActions.shift();

if (snippetAction === 'replace') {
newSnippet.setAttribute(snippetStateAttribute, 'redrawing');
existingSnippet.replaceWith(newSnippet);
existingSnippet = newSnippet;
} else if (snippetAction === 'append-children') {
const childrenFragment = new DocumentFragment();
while (newSnippet.firstChild != null) {
childrenFragment.append(newSnippet.firstChild);
}

existingSnippet.append(childrenFragment);
} else if (snippetAction === 'prepend-children') {
const childrenFragment = new DocumentFragment();
while (newSnippet.lastChild != null) {
childrenFragment.append(newSnippet.lastChild);
}

existingSnippet.prepend(childrenFragment);
} else if (snippetAction === 'sync-attributes') {
for (const attribute of newSnippet.attributes) {
existingSnippet.setAttribute(attribute.name, attribute.value);
}
}
}

existingSnippet.prepend(childrenFragment);
} else if (snippetAction === 'attributes') {
for (const attribute of newSnippet.attributes) {
existingSnippet.setAttribute(attribute.name, attribute.value);
}
}
for (const script of existingSnippet.querySelectorAll('script')) {
const scriptElement = document.createElement('script');
scriptElement.innerHTML = script.innerHTML;
scriptElement.async = false;

for (const script of existingSnippet.querySelectorAll('script')) {
const scriptElement = document.createElement('script');
scriptElement.innerHTML = script.innerHTML;
scriptElement.async = false;
for (const { name, value } of [...script.attributes]) {
scriptElement.setAttribute(name, value);
}

for (const { name, value } of [...script.attributes]) {
scriptElement.setAttribute(name, value);
script.replaceWith(scriptElement);
}

script.replaceWith(scriptElement);
}

dispatch('snippets:redraw:end', eventDispatcherData);
dispatch('snippets:redraw:end', snippetConfig);

existingSnippet.setAttribute(snippetStateAttribute, 'redrawed');
existingSnippet.setAttribute(snippetStateAttribute, 'redrawed');
}
};

if (typeof document.startViewTransition === 'undefined') {
redraw();
} else {
dispatch('snippets:redraw:transition:start');
const transition = document.startViewTransition(() => redraw());
await transition.ready;
dispatch('snippets:redraw:transition:end');
}

};
};
};
Loading

0 comments on commit e66000b

Please sign in to comment.