lightview 1.4.1-b → 1.4.2-b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/lightview.js +86 -57
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # lightview v1.4.1b (BETA)
1
+ # lightview v1.4.2b (BETA)
2
2
 
3
3
  Small, simple, powerful web UI and micro front end creation ...
4
4
 
package/lightview.js CHANGED
@@ -218,14 +218,20 @@ const {observe} = (() => {
218
218
  }
219
219
  });
220
220
  }
221
- const createObserver = (domNode) => {
221
+ const createObserver = (domNode,framed) => {
222
222
  const observer = new MutationObserver((mutations) => {
223
223
  mutations.forEach((mutation) => {
224
224
  if (mutation.type === "attributes") {
225
+ if(framed) debugger;
225
226
  const name = mutation.attributeName,
226
- target = mutation.target;
227
+ target = mutation.target,
228
+ value = target.getAttribute(name);
229
+ if(framed && name==="message" && target instanceof IFrameElement) {
230
+ if(value) console.log("message",value);
231
+ target.removeAttribute(name);
232
+ target.dispatchEvent("message",new CustomEvent("message",{detail:JSON.parse(value)}))
233
+ }
227
234
  if (target.observedAttributes && target.observedAttributes.includes(name)) {
228
- const value = target.getAttribute(name);
229
235
  if (value !== mutation.oldValue) {
230
236
  target.setValue(name, value);
231
237
  if (target.attributeChangedCallback) target.attributeChangedCallback(name, value, mutation.oldValue);
@@ -315,35 +321,35 @@ const {observe} = (() => {
315
321
  })
316
322
  }
317
323
  const bindInput = (input, name, component) => {
318
- const inputtype = input.tagName === "SELECT" ? "text" : input.getAttribute("type"),
319
- type = input.tagName === "SELECT" && input.hasAttribute("multiple") ? Array : inputTypeToType(inputtype),
320
- deflt = input.getAttribute("default"),
321
- value = input.getAttribute("value");
322
- let variable = component.vars[name] || {type};
323
- if (type !== variable.type) {
324
- if (variable.type === "any" || variable.type === "unknown") variable.type = type;
325
- else throw new TypeError(`Attempt to bind <input name="${name}" type="${type}"> to variable ${name}:${variable.type}`)
326
- }
327
- component.variables({[name]: type});
328
- let eventname = "change";
329
- if(input.tagName!=="SELECT" && (!inputtype || ["text","number","tel","email","url","search","password"].includes(inputtype))) {
330
- eventname = "input";
331
- }
332
- addListener(input,eventname, (event) => {
333
- event.stopImmediatePropagation();
334
- const target = event.target;
335
- let value = target.value;
336
- if (inputtype === "checkbox") {
337
- value = input.checked
338
- } else if (target.tagName === "SELECT") {
339
- if (target.hasAttribute("multiple")) {
340
- value = [...target.querySelectorAll("option")]
341
- .filter((option) => option.selected || resolveNode(option.attributes.value,component)==value || option.innerText == value)
342
- .map((option) => option.getAttribute("value") || option.innerText);
343
- }
324
+ const inputtype = input.tagName === "SELECT" ? "text" : input.getAttribute("type"),
325
+ type = input.tagName === "SELECT" && input.hasAttribute("multiple") ? Array : inputTypeToType(inputtype),
326
+ deflt = input.getAttribute("default"),
327
+ value = input.getAttribute("value");
328
+ let variable = component.vars[name] || {type};
329
+ if (type !== variable.type) {
330
+ if (variable.type === "any" || variable.type === "unknown") variable.type = type;
331
+ else throw new TypeError(`Attempt to bind <input name="${name}" type="${type}"> to variable ${name}:${variable.type}`)
332
+ }
333
+ component.variables({[name]: type});
334
+ let eventname = "change";
335
+ if(input.tagName!=="SELECT" && (!inputtype || ["text","number","tel","email","url","search","password"].includes(inputtype))) {
336
+ eventname = "input";
337
+ }
338
+ addListener(input,eventname, (event) => {
339
+ event.stopImmediatePropagation();
340
+ const target = event.target;
341
+ let value = target.value;
342
+ if (inputtype === "checkbox") {
343
+ value = input.checked
344
+ } else if (target.tagName === "SELECT") {
345
+ if (target.hasAttribute("multiple")) {
346
+ value = [...target.querySelectorAll("option")]
347
+ .filter((option) => option.selected || resolveNode(option.attributes.value,component)==value || option.innerText == value)
348
+ .map((option) => option.getAttribute("value") || option.innerText);
344
349
  }
345
- component.varsProxy[name] = coerce(value, type);
346
- })
350
+ }
351
+ component.varsProxy[name] = coerce(value, type);
352
+ })
347
353
  }
348
354
  const tryParse = (value) => {
349
355
  try {
@@ -362,7 +368,7 @@ const {observe} = (() => {
362
368
  exported: {value: true, constant: true},
363
369
  imported: {value: true, constant: true}
364
370
  };
365
- const createClass = (domElementNode, {observer, importAnchors}) => {
371
+ const createClass = (domElementNode, {observer, importAnchors, framed}) => {
366
372
  const instances = new Set(),
367
373
  dom = domElementNode.tagName === "TEMPLATE"
368
374
  ? domElementNode.content.cloneNode(true)
@@ -376,7 +382,7 @@ const {observe} = (() => {
376
382
  constructor() {
377
383
  super();
378
384
  instances.add(this);
379
- observer ||= createObserver(this);
385
+ observer ||= createObserver(this,framed);
380
386
  const currentComponent = this,
381
387
  shadow = this.attachShadow({mode: "open"}),
382
388
  eventlisteners = {};
@@ -406,6 +412,7 @@ const {observe} = (() => {
406
412
  };
407
413
  this.defaultAttributes = domElementNode.tagName === "TEMPLATE" ? domElementNode.attributes : dom.attributes;
408
414
  this.varsProxy = createVarsProxy(this.vars, this, CustomElement);
415
+ if(framed || CustomElement.lightviewFramed) this.variables({message:Object},{exported:true});
409
416
  ["getElementById", "querySelector", "querySelectorAll"]
410
417
  .forEach((fname) => {
411
418
  Object.defineProperty(this, fname, {
@@ -532,7 +539,7 @@ const {observe} = (() => {
532
539
  }
533
540
  }
534
541
 
535
- const [type, ...params] = name.split(":");
542
+ const [type, ...params] = name.split(":");
536
543
  if (type === "") { // name is :something
537
544
  render(!!attr.template, () => {
538
545
  const value = attr.value,
@@ -725,13 +732,17 @@ const {observe} = (() => {
725
732
  }
726
733
  }
727
734
  }
728
- const createComponent = (name, node, {observer, importAnchors} = {}) => {
735
+ const createComponent = (name, node, {observer, importAnchors,framed} = {}) => {
729
736
  let ctor = customElements.get(name);
730
737
  if (ctor) {
731
- console.warn(new Error(`${name} is already a CustomElement. Not redefining`));
738
+ if(framed && !ctor.lightviewFramed) {
739
+ ctor.lightviewFramed = true;
740
+ } else {
741
+ console.warn(new Error(`${name} is already a CustomElement. Not redefining`));
742
+ }
732
743
  return ctor;
733
744
  }
734
- ctor = createClass(node, {observer, importAnchors});
745
+ ctor = createClass(node, {observer, importAnchors,framed});
735
746
  customElements.define(name, ctor);
736
747
  return ctor;
737
748
  }
@@ -760,9 +771,9 @@ const {observe} = (() => {
760
771
  }
761
772
  }
762
773
 
763
- const bodyAsComponent = ({as = "x-body", unhide, importAnchors} = {}) => {
774
+ const bodyAsComponent = ({as = "x-body", unhide, importAnchors,framed} = {}) => {
764
775
  const parent = document.body.parentElement;
765
- createComponent(as, document.body, {importAnchors});
776
+ createComponent(as, document.body, {importAnchors,framed});
766
777
  const component = document.createElement(as);
767
778
  parent.replaceChild(component, document.body);
768
779
  Object.defineProperty(document, "body", {
@@ -804,7 +815,8 @@ const {observe} = (() => {
804
815
 
805
816
  const url = new URL(document.currentScript.getAttribute("src"), window.location.href);
806
817
  let domContentLoadedEvent;
807
- addListener(window,"DOMContentLoaded", (event) => domContentLoadedEvent = event);
818
+ if(!domContentLoadedEvent) addListener(window,"DOMContentLoaded", (event) => domContentLoadedEvent = event);
819
+ let OBSERVER;
808
820
  const loader = async (whenFramed) => {
809
821
  if (!!document.querySelector('meta[name="l-importLinks"]')) await importLinks();
810
822
  const importAnchors = !!document.querySelector('meta[name="l-importAnchors"]'),
@@ -812,7 +824,7 @@ const {observe} = (() => {
812
824
  isolated = !!document.querySelector('meta[name="l-isolate"]'),
813
825
  enableFrames = !!document.querySelector('meta[name="l-enableFrames"]');
814
826
  if (whenFramed) {
815
- whenFramed({unhide, importAnchors, isolated, enableFrames});
827
+ whenFramed({unhide, importAnchors, isolated, enableFrames, framed:true});
816
828
  if (!isolated) {
817
829
  postMessage.enabled = true;
818
830
  addListener(window,"message", ({data}) => {
@@ -876,7 +888,9 @@ const {observe} = (() => {
876
888
  }
877
889
  if (type === "setAttribute") {
878
890
  const [name, value] = [...argsList];
879
- if (iframe.getAttribute(name) !== value + "") iframe.setAttribute(name, value);
891
+ if (iframe.getAttribute(name) !== value + "") {
892
+ iframe.setAttribute(name, value);
893
+ }
880
894
  return;
881
895
  }
882
896
  if (type === "removeAttribute") {
@@ -886,30 +900,45 @@ const {observe} = (() => {
886
900
  }
887
901
  console.warn("iframe posted a message without providing an id", message);
888
902
  });
889
- const mutationCallback = (mutationsList) => {
890
- const console = document.getElementById("console");
891
- for (const {target, attributeName, oldValue} of mutationsList) {
892
- if (!["height", "width"].includes(attributeName)) {
903
+ if(!OBSERVER) {
904
+ const mutationCallback = (mutationsList) => {
905
+ const console = document.getElementById("console");
906
+ for (const {target, attributeName, oldValue} of mutationsList) {
893
907
  const value = target.getAttribute(attributeName);
894
- if (!value) postMessage({type: "removeAttribute", argsList: [attributeName]}, iframe)
895
- else if (value !== oldValue) postMessage({
896
- type: "setAttribute",
897
- argsList: [attributeName, value]
898
- }, iframe)
908
+ if (!["height", "width", "message"].includes(attributeName)) {
909
+ if (!value) postMessage({type: "removeAttribute", argsList: [attributeName]}, iframe)
910
+ else if (value !== oldValue) {
911
+ postMessage({
912
+ type: "setAttribute",
913
+ argsList: [attributeName, value]
914
+ }, iframe)
915
+ }
916
+ }
917
+ if(attributeName==="message") {
918
+ if(value) {
919
+ target.removeAttribute("message");
920
+ target.dispatchEvent(new CustomEvent("message",{target,detail:JSON.parse(value)}))
921
+ }
922
+ } else {
923
+ target.dispatchEvent(new CustomEvent("attribute.changed",{target,detail:{attributeName,value,oldValue}}))
924
+ }
899
925
  }
900
- }
901
- };
902
- const observer = new MutationObserver(mutationCallback),
903
- iframe = document.getElementById("myframe");
904
- observer.observe(iframe, {attributes: true, attributeOldValue: true});
926
+ };
927
+ const observer = OBSERVER = new MutationObserver(mutationCallback),
928
+ iframe = document.getElementById("myframe");
929
+ observer.observe(iframe, {attributes: true, attributeOldValue: true});
930
+ }
905
931
  }
906
932
  }
907
933
  const whenFramed = (f, {isolated} = {}) => {
934
+ // loads for framed content
908
935
  addListener(document,"DOMContentLoaded", (event) => loader(f));
909
936
  }
910
937
  Lightview.whenFramed = whenFramed;
911
938
  //Object.defineProperty(Lightview, "whenFramed", {configurable: true, writable: true, value: whenFramed});
912
- if (window.location === window.parent.location || !(window.parent instanceof Window) || window.parent !== window) { // CodePen mucks with window.parent
939
+ if (window.location === window.parent.location || !(window.parent instanceof Window) || window.parent !== window) {
940
+ // loads for unframed content
941
+ // CodePen mucks with window.parent
913
942
  addListener(document,"DOMContentLoaded", () => loader())
914
943
  }
915
944
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lightview",
3
- "version": "1.4.1b",
3
+ "version": "1.4.2b",
4
4
  "description": "Small, simple, powerful web UI and micro front end creation ... imagine a blend of Svelte, React, Vue, Riot and more.",
5
5
  "main": "lightview.js",
6
6
  "scripts": {