Skip to content

Commit

Permalink
Updates to Signal.frame, dom elements()
Browse files Browse the repository at this point in the history
  • Loading branch information
stephband committed Oct 14, 2024
1 parent 9e544f8 commit a2aadd1
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 72 deletions.
1 change: 1 addition & 0 deletions element/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export default function LiteralElement(tag, lifecycle = {}, properties = {}) {

const consts = { host: this, shadow, internals };
const renderer = Literal.fromFragment(name, template.content, this, consts);

shadow.appendChild(renderer.content);

// Call lifecycle.construct()
Expand Down
24 changes: 13 additions & 11 deletions literal-element/modules/lifecycle.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,18 @@ export default {
internals.attributes.reduce(assignProperty, {}) :
nothing ;

if (internals.src) {
internals.src.then((module) => {
// TODO: can't we just pass module as scope? Why not?
const scope = assign({}, module);
delete scope.default;
defineElement(internals.tag, this, module.default || {}, attributes, scope)
});
}
else {
defineElement(internals.tag, this, {}, attributes, {});
}
return [render(() => {
if (internals.src) {
internals.src.then((module) => {
// TODO: can't we just pass module as scope? Why not?
const scope = assign({}, module);
delete scope.default;
defineElement(internals.tag, this, module.default || {}, attributes, scope)
});
}
else {
defineElement(internals.tag, this, {}, attributes, {});
}
})];
}
}
53 changes: 15 additions & 38 deletions literal-html/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ library provides another template, `<template is="literal-shadow">`

import Signal from 'fn/signal.js';
import element, { getInternals } from 'dom/element.js';
import createObjectProperty from 'dom/element/create-object-property.js';
import assignDataset from '../modules/dom/assign-dataset.js';
import requestData from '../modules/request-data.js';
import DOMRenderer from '../modules/template.js';
import Literal from '../modules/template.js';
import { printError } from '../modules/print.js';


Expand All @@ -29,34 +30,31 @@ export default element('<template is="literal-html">', {
construct: function(shadow, internals) {
internals.initialised = false;
internals.pushed = false;
internals.data = Signal.of();
internals.renderer = DOMRenderer.fromTemplate(this, this.parentElement);
internals.renderer = Literal.fromTemplate(this, this.parentElement);
},

connect: function(shadow, internals) {
// If already initialised do nothing
if (internals.initialised) { return; }
internals.initialised = true;

// Observe signal listens to signal value changes and calls fn()
// immediately if signal already has value, and on next tick after
// signal mutates
Signal.observe(internals.data, (data) => {
const { renderer } = internals;
// If src or data was not set use data found in dataset
if (!internals.promise && !internals.pushed) {
this.data = assignDataset({}, this.dataset);
}

// Render data from signalling properties immediately once, and then
// on frame following signal invalidation
return [Signal.frame(() => {
if (!this.data) return;

if (!data) return;
const fragment = renderer.push(data);

// Replace DOM content on first push
// Replace DOM content on first push only
if (internals.pushed) return;
internals.pushed = true;
this.replaceWith(fragment);
});

// If src or data was not set use data found in dataset
if (!internals.promise && !internals.pushed) {
internals.data.value = assignDataset({}, this.dataset);
}
})];
}
}, {
/**
Expand Down Expand Up @@ -117,26 +115,5 @@ export default element('<template is="literal-html">', {
(well, not quite immediately – literal renders changes on the next frame).
**/

data: {
attribute: function(json) {
try {
this.data = JSON.parse(json);
}
catch(e) {
throw new Error('Invalid JSON in <template is="literal-template"> data attribute: "' + json + '"');
}
},

get: function() {
const internals = getInternals(this);
return internals.renderer ?
internals.renderer.data :
null ;
},

set: function(object) {
const internals = getInternals(this);
internals.data.value = object || null;
}
}
data: createObjectProperty()
}, null, 'stephen.band/literal/');
2 changes: 2 additions & 0 deletions literal-html/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
}</script>

<link rel="stylesheet" href="../../bolt/elements/html.css" />
<link rel="stylesheet" href="../../bolt/elements/type.css" />
<link rel="stylesheet" href="../../bolt/elements/table.css" />
<link rel="stylesheet" href="../../bolt/elements/form.css" />
<link rel="stylesheet" href="../../bolt/elements/input-range.css" />
<link rel="stylesheet" href="../../bolt/classes/text.css" />
<link rel="stylesheet" href="../../bolt/classes/block.css" />
<link rel="stylesheet" href="../../bolt/classes/button.css" />
<link rel="stylesheet" href="../../bolt/classes/select-button.css" />
Expand Down
2 changes: 0 additions & 2 deletions modules/compile/compile-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,6 @@ const compileNode = overload((targets, node) => toType(node), {
return targets;
}
catch(error) {
console.log('COMPILE ERROR', node, printError(target, error));
node.textContent = 'HHHEEEEELLLLPPPPP!!';
node.replaceWith(printError(target, error));
return targets;
}
Expand Down
4 changes: 2 additions & 2 deletions modules/dom/get-by-id.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

export default function getById(src) {
const id = src.slice(1);
const template = document.getElementById(id);
const id = src.slice(1);
const template = document.getElementById(id);

if (!template) {
throw new Error('Template ' + src + ' not found');
Expand Down
8 changes: 2 additions & 6 deletions modules/renderer/cue.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import Signal from 'fn/signal.js';
import { stats } from './renderer.js';

const renderers = [];
let cued;

const render = window.DEBUG && window.DEBUG.literal !== false ? function render(t) {
let t0 = window.performance.now() / 1000;

Expand Down Expand Up @@ -54,7 +52,6 @@ const render = window.DEBUG && window.DEBUG.literal !== false ? function render(
'#ba4029');
}

cued = undefined;
renderers.length = 0;
} : function render() {
let n = -1;
Expand All @@ -65,7 +62,6 @@ const render = window.DEBUG && window.DEBUG.literal !== false ? function render(
renderer.status = 'idle';
}

cued = undefined;
renderers.length = 0;
} ;

Expand All @@ -80,10 +76,10 @@ export function cue(renderer) {
// Create a new cued render process by promise...
//if (!cued) cued = promise.then(render);
// ...or by animation frame
if (cued === undefined) cued = requestAnimationFrame(render);
if (!renderers.length) requestAnimationFrame(render);
renderers.push(renderer);
renderer.status = 'cued';
return cued;
return renderer;
}

/**
Expand Down
18 changes: 9 additions & 9 deletions modules/renderer/renderer.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

import { remove } from 'fn/remove.js';
import { ObserveSignal } from 'fn/signal.js';
import Data from 'fn/data.js';
import scope from '../scope.js';
import { cue, uncue } from './cue.js';
import toText from './to-text.js';
import { remove } from 'fn/remove.js';
import { Observer } from 'fn/signal.js';
import Data from 'fn/data.js';
import scope from '../scope.js';
import { cue, uncue } from './cue.js';
import toText from './to-text.js';


const assign = Object.assign;
Expand Down Expand Up @@ -185,7 +185,7 @@ export default class Renderer {
// signals to invalidate. It does have status.
if (this.status === 'done' || this.status === 'cued') return;

// Stop async values being rendered
// Stop async values from the last evaluation from being rendered
this.asyncs && this.asyncs.forEach(stop);

// Cue evaluation on next frame
Expand All @@ -200,8 +200,8 @@ export default class Renderer {
uncue(this);
}

// Set this.status = 'done'
ObserveSignal.prototype.stop.apply(this);
// Set this.status = 'done', removes from signal graph
Observer.prototype.stop.apply(this);

// Stop async values being rendered
this.asyncs && this.asyncs.forEach(stop);
Expand Down
8 changes: 4 additions & 4 deletions modules/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export default class Literal {
Literal.compile(identifier, fragment, options)
**/

static compile(id, fragment, options) {
static compile(id, fragment, options = {}) {
if(cache[id]) return cache[id];

if (window.DEBUG) {
Expand Down Expand Up @@ -155,9 +155,9 @@ export default class Literal {
return Literal.fromTemplate(create('template', html), element, consts, data);
}

#data;
#first;
#last;
#data;

constructor(fragment, targets, parent = template.parentElement, consts = {}, data) {
const children = fragment.childNodes;
Expand Down Expand Up @@ -290,8 +290,8 @@ export default class Literal {

/**
.remove()
Removes rendered content from the DOM, placing it back in the
`.content` fragment.
Removes rendered content from the DOM and places it back in the `.content`
fragment.
**/

remove() {
Expand Down

0 comments on commit a2aadd1

Please sign in to comment.