mount-observer 0.0.76 → 0.0.78

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.
package/MountObserver.js CHANGED
@@ -434,6 +434,7 @@ export class MountObserver extends EventTarget {
434
434
  return false;
435
435
  if (!x.matches(match))
436
436
  return true;
437
+ //TODO: add check for outside
437
438
  if (whereSatisfies !== undefined) {
438
439
  if (!whereSatisfies(x, this, { stage: 'Inspecting', initializing: false }))
439
440
  return true;
@@ -446,13 +447,26 @@ export class MountObserver extends EventTarget {
446
447
  this.#mountedList = Array.from(returnSet).map(x => new WeakRef(x));
447
448
  return returnSet;
448
449
  }
450
+ #outsideCheck(oElement, matchCandidate, outside) {
451
+ const elementsToExclude = Array.from(oElement.querySelectorAll(outside));
452
+ for (const elementToExclude of elementsToExclude) {
453
+ if (elementToExclude === matchCandidate || elementToExclude.contains(matchCandidate))
454
+ return false;
455
+ }
456
+ return true;
457
+ }
449
458
  async #filterAndMount(els, target, checkMatch, initializing) {
450
- const { whereSatisfies, whereInstanceOf, assigner } = this.#mountInit;
459
+ const { whereSatisfies, whereInstanceOf, assigner, outside } = this.#mountInit;
451
460
  const match = await this.#selector();
452
461
  const elsToMount = els.filter(x => {
453
462
  if (checkMatch) {
454
463
  if (!x.matches(match))
455
464
  return false;
465
+ //TODO: check for outside
466
+ }
467
+ if (outside !== undefined) {
468
+ if (!this.#outsideCheck(this.objNde.deref(), x, outside))
469
+ return false;
456
470
  }
457
471
  if (whereSatisfies !== undefined) {
458
472
  if (!whereSatisfies(x, this, { stage: 'Inspecting', initializing }))
@@ -470,6 +484,8 @@ export class MountObserver extends EventTarget {
470
484
  }
471
485
  }
472
486
  await bindishIt(els, target, { assigner });
487
+ if (elsToMount.length === 0)
488
+ return;
473
489
  this.#mount(elsToMount, initializing);
474
490
  }
475
491
  async #inspectWithin(within, initializing) {
package/MountObserver.ts CHANGED
@@ -466,6 +466,7 @@ export class MountObserver extends EventTarget implements IMountObserver{
466
466
  const elsToUnMount = previouslyMounted.filter(x => {
467
467
  if(x === undefined) return false;
468
468
  if(!x.matches(match)) return true;
469
+ //TODO: add check for outside
469
470
  if(whereSatisfies !== undefined){
470
471
  if(!whereSatisfies(x, this, {stage: 'Inspecting', initializing: false})) return true;
471
472
  }
@@ -478,12 +479,25 @@ export class MountObserver extends EventTarget implements IMountObserver{
478
479
  return returnSet;
479
480
  }
480
481
 
482
+ #outsideCheck(oElement: Element, matchCandidate: Element, outside: string){
483
+ const elementsToExclude = Array.from(oElement.querySelectorAll(outside));
484
+ for(const elementToExclude of elementsToExclude){
485
+ if(elementToExclude === matchCandidate || elementToExclude.contains(matchCandidate)) return false;
486
+ }
487
+ return true;
488
+ }
489
+
481
490
  async #filterAndMount(els: Array<Element>, target: Node, checkMatch: boolean, initializing: boolean){
482
- const {whereSatisfies, whereInstanceOf, assigner} = this.#mountInit;
491
+ const {whereSatisfies, whereInstanceOf, assigner, outside} = this.#mountInit;
483
492
  const match = await this.#selector();
484
493
  const elsToMount = els.filter(x => {
485
494
  if(checkMatch){
486
495
  if(!x.matches(match)) return false;
496
+
497
+ //TODO: check for outside
498
+ }
499
+ if(outside !== undefined){
500
+ if(!this.#outsideCheck(this.objNde!.deref() as Element, x, outside)) return false;
487
501
  }
488
502
  if(whereSatisfies !== undefined){
489
503
  if(!whereSatisfies(x, this, {stage: 'Inspecting', initializing})) return false;
@@ -500,6 +514,7 @@ export class MountObserver extends EventTarget implements IMountObserver{
500
514
 
501
515
  }
502
516
  await bindishIt(els, target, {assigner});
517
+ if(elsToMount.length === 0) return;
503
518
  this.#mount(elsToMount, initializing);
504
519
  }
505
520
 
package/README.md CHANGED
@@ -48,6 +48,8 @@ There is quite a bit of functionality this proposal would open up, that is excee
48
48
 
49
49
  3. Knowing when an element, previously being monitored for, passes totally "out-of-scope", so that no more hard references to the element remain. This would allow for cleanup of no longer needed weak references without requiring polling.
50
50
 
51
+ 4. Some css selectors, such as the [scope donut hole range](https://css-tricks.com/solved-by-css-donuts-scopes/#aa-donut-scoping-with-scope) aren't supported by oEl.querySelectorAll(...) or oEl.matches(...).
52
+
51
53
  ### Most significant use cases.
52
54
 
53
55
  The amount of code necessary to accomplish these common tasks designed to improve the user experience is significant. Building it into the platform would potentially:
@@ -439,6 +441,48 @@ So I believe the prudent thing to do is wait for all the conditions to be satisf
439
441
 
440
442
  The alternative to providing this feature, which I'm leaning towards, is to just ask the developer to create "specialized" mountObserver construction arguments, that turn on and off precisely when the developer needs to know.
441
443
 
444
+
445
+ ## Support for "donut hole scoping"
446
+
447
+ While browsers are getting support for css based donut hole scoping, such support appears to be elusive for oElement.querySelectorAll(...) and oElement.matches(...). In fact it is unclear how oElement.matches(...) would ever support it. Such support would be quite useful. for microdata-based binding.
448
+
449
+ Ideally, should this proposal be built into the browser, it would as a matter of course support donut hole scoping.
450
+
451
+ For the polyfill, we need to support it as follows:
452
+
453
+ ```html
454
+ <div id=myTest itemscope>
455
+ <span itemprop=name>
456
+ </div>
457
+ ```
458
+
459
+ ```JavaScript
460
+ const oElement = document.getElementById('myTest');
461
+ const observer = new MountObserver({
462
+ on:'[itemprop]',
463
+ outside: '[itemscope]'
464
+ do: {
465
+ mount: ({localName}, {modules, observer}) => {
466
+ ...
467
+ },
468
+ },
469
+ disconnectedSignal: new AbortController().signal
470
+ });
471
+ observer.observe(oElement);
472
+ ```
473
+
474
+ The check for "outside" is done via script:
475
+
476
+ ```JavaScript
477
+ outsideCheck(oElement: Element, matchCandidate: Element, outside: string){
478
+ const elementsToExclude = Array.from(oElement.querySelectorAll(outside));
479
+ for(const elementToExclude of elementsToExclude){
480
+ if(elementToExclude === matchCandidate || elementToExclude.contains(matchCandidate)) return false;
481
+ }
482
+ return true;
483
+ }
484
+ ```
485
+
442
486
  ## A tribute to attributes
443
487
 
444
488
  Attributes of DOM elements are tricky. They've been around since the get-go of the Web, and they've survived multiple eras of web development, where different philosophies have prevailed, so prepare yourself for some esoteric discussions in what follows.
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "mount-observer",
3
- "version": "0.0.76",
3
+ "version": "0.0.78",
4
4
  "description": "Observe and act on css matches.",
5
5
  "main": "MountObserver.js",
6
6
  "module": "MountObserver.js",
7
7
  "devDependencies": {
8
- "@playwright/test": "1.53.2",
8
+ "@playwright/test": "1.54.1",
9
9
  "ssi-server": "0.0.1"
10
10
  },
11
11
  "exports": {
@@ -87,7 +87,7 @@
87
87
  ],
88
88
  "types": "./ts-refs/mount-observer/types.d.ts",
89
89
  "scripts": {
90
- "serve": "python3 ./node_modules/ssi-server/ssi_server.py",
90
+ "serve": "python ./node_modules/ssi-server/ssi_server.py",
91
91
  "test": "playwright test",
92
92
  "safari": "npx playwright wk http://localhost:8000",
93
93
  "update": "ncu -u && npm install"
@@ -0,0 +1,43 @@
1
+ import {IEnhancement, BEAllProps} from '../trans-render/be/types';
2
+
3
+ /**
4
+ *
5
+ */
6
+ export interface DirectoryPickerOptions {
7
+ /**
8
+ * By specifying an ID, the browser can remember different directories for different IDs. If the same ID is used for another picker, the picker opens in the same directory.
9
+ */
10
+ id?: string;
11
+
12
+ /**
13
+ * A string that defaults to "read" for read-only access or "readwrite" for read and write access to the directory.
14
+ */
15
+ mode?: 'read' | 'readwrite';
16
+
17
+ /**
18
+ * A FileSystemHandle or a well known directory ("desktop", "documents", "downloads", "music", "pictures", or "videos") to open the dialog in.
19
+ *
20
+ */
21
+ startIn?: 'documents' | 'downloads' | 'music' | 'pictures' | 'videos' | 'home' | 'desktop' | File;
22
+ }
23
+ export interface EndUserProps extends IEnhancement{
24
+ options: DirectoryPickerOptions;
25
+ noNudge: boolean;
26
+ }
27
+
28
+ export interface AllProps extends EndUserProps{
29
+ directoryHandle?: FileSystemDirectoryHandle;
30
+ }
31
+
32
+ export type AP = AllProps;
33
+
34
+ export type PAP = Partial<AP>;
35
+
36
+ export type ProPAP = Promise<PAP>;
37
+
38
+ export type BAP = AP & BEAllProps;
39
+
40
+ export interface Actions{
41
+ hydrate(self: BAP): ProPAP;
42
+ }
43
+
@@ -20,6 +20,7 @@ export interface EndUserProps extends IEnhancement<HTMLTemplateElement>{
20
20
  hiddenStyle?: string;
21
21
  toggleInert?: boolean;
22
22
  deferRendering?: boolean;
23
+ /** delete content when condition evaluates to false */
23
24
  minMem?: boolean;
24
25
  /**
25
26
  * Works with beOosoom decorator, so becomes inert when out of view
@@ -27,6 +28,10 @@ export interface EndUserProps extends IEnhancement<HTMLTemplateElement>{
27
28
  beOosoom?: string;
28
29
  js?: string;
29
30
  transitional: boolean;
31
+ /**
32
+ * Use comments rather a DOM element to wrap multiple elements
33
+ */
34
+ cmtWrap?: boolean;
30
35
  }
31
36
 
32
37
  export interface AllProps extends EndUserProps{
@@ -1,6 +1,7 @@
1
1
 
2
2
  export interface JSONSerializableMountInit{
3
3
  readonly on?: CSSMatch,
4
+ readonly outside?: CSSMatch,
4
5
  readonly observedAttrsWhenMounted?: (string | ObservedSourceOfTruthAttribute)[],
5
6
  readonly whereAttr?: WhereAttr,
6
7
  readonly whereElementIntersectsWith?: IntersectionObserverInit,
@@ -143,7 +143,11 @@ export interface Specifier {
143
143
  */
144
144
  is$cope?: boolean;
145
145
 
146
- $copeDetail?: $copeDetail
146
+ $copeDetail?: $copeDetail;
147
+
148
+ constVal?: any;
149
+
150
+ enhBase?: string;
147
151
  }
148
152
 
149
153
  export type Modulo = 'aria-rowindex' | 'aria-colindex' | 'aria-rowindextext'
@@ -405,7 +405,8 @@ export interface AttrMap{
405
405
  export interface QueryInfo{
406
406
  isRootQry?: boolean,
407
407
  localPropCamelCase?: string,
408
- cssQuery?: string,
408
+ cssQuery?: CSSQuery,
409
+ outside?: CSSQuery,
409
410
  o?: string[],
410
411
  s?: string[],
411
412
  localName?: string,
@@ -0,0 +1,29 @@
1
+ import {IEnhancement, BEAllProps} from '../trans-render/be/types';
2
+ import { Specifier } from "../trans-render/dss/types";
3
+
4
+ export interface EndUserProps extends IEnhancement{
5
+ }
6
+
7
+ export interface AllProps extends EndUserProps{
8
+ parsedStatements: Array<ResolvingParameters>,
9
+ rawStatements?: Array<string>
10
+ }
11
+
12
+ export type AP = AllProps;
13
+
14
+ export type PAP = Partial<AP>;
15
+
16
+ export type ProPAP = Promise<PAP>;
17
+
18
+ export type BAP = AP & BEAllProps;
19
+
20
+ export interface Actions{
21
+ hydrate(self: BAP): ProPAP;
22
+ }
23
+
24
+ export interface ResolvingParameters{
25
+ remoteSpecifierString: string;
26
+ remoteSpecifier: Specifier;
27
+ localSpecifierString: string;
28
+ localSpecifier: Specifier;
29
+ }