tab-catch test

by Laurens Maneschijn

HTML

Several methods trying to contain tab and shift-tab within part of a page:<br>
(could potentially be very annoying behaviour, so use sparingly)<br>
<div>
	<input><br>

	<tab-catch-start></tab-catch-start>
	
	AAA<input>BBB<input>CCC

	<tab-catch-end></tab-catch-end>

	<br>

	<input><br>
</div>

<div>
	<input><br>

	<tab-catch reverse></tab-catch>
	
	AAA<input>BBB<input>CCC<br>

	<tab-catch></tab-catch>

	<input><br>
</div>

<div>
	<input><br>

	<tab-catch-block start end>
		AAA<input>BBB<input>CCC
	</tab-catch-block><br>

	<input><br>
</div>

CSS

div {
	margin: 8px;
	padding: 4px;
	border: 1px solid #888;
	background: #4444;
}

JavaScript

customElements.define('tab-catch-start',
  class extends HTMLElement {
    constructor() {
      super();
      const shadowRoot = this.attachShadow({mode: 'open'});
	  shadowRoot.innerHTML = 
		`<input style="width:1px; height:1px;" onfocus="this.nextElementSibling.focus();">
		 <input style="width:1px; height:1px;">`;
}});
customElements.define('tab-catch-end',
  class extends HTMLElement {
    constructor() {
      super();
      const shadowRoot = this.attachShadow({mode: 'open'});
	  shadowRoot.innerHTML = 
		`<input style="width:1px; height:1px;">
		 <input style="width:1px; height:1px;" onfocus="this.previousElementSibling.focus();">`;
}});

// <tab-catch>         : prevent tabbing over this element.
// <tab-catch reverse> : prevent shift-tabbing over this element.
customElements.define('tab-catch',
  class extends HTMLElement {
    constructor() {
      super();
      const shadowRoot = this.attachShadow({mode: 'open'});
	  shadowRoot.innerHTML = ``;
      const span1 = document.createElement('span');
	  const span2 = document.createElement('span');
	  shadowRoot.appendChild(span1);
	  shadowRoot.appendChild(span2);
	  span1.setAttribute('tabindex','0');
	  span2.setAttribute('tabindex','0');
	  if (this.hasAttribute('reverse')) {
		  span1.onfocus = () => {span2.focus();}
	  } else {
		  span2.onfocus = () => {span1.focus();}
	  }
    }
  }
);




// <tab-catch-block> ... </tab-catch-block>
customElements.define('tab-catch-block',
	class extends HTMLElement {
		constructor() {
			super();
			const shadowRoot = this.attachShadow({mode: 'open'});
			const add_tab_element = () => {
				const span = document.createElement('span');
				shadowRoot.appendChild(span);
				span.setAttribute('tabindex','0');
				return span;
			}
			if (this.hasAttribute('start')) {
				const span1 = add_tab_element();
				const span2 = add_tab_element();
				span1.onfocus = () => {span2.focus();}
			}

			// keep original children (if...