New HTML Dialog Test

Experimentation with the new dialog element

by Jesper Brinch Korsbakke

HTML

<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perferendis alias ratione, nostrum praesentium, voluptates officiis non reprehenderit minus excepturi tempore a consequatur quod voluptas voluptate saepe quam, itaque assumenda adipisci.</p>

<dialog id="dialog">
  <p>This is a dialog</p>
  <button id="closeButton">Close the dialog</button>
</dialog>

<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque, accusantium cum expedita inventore adipisci ad tenetur odio odit magnam natus, architecto autem! Placeat, in, similique illo vitae deserunt magni pariatur.</p>

<button id="button">Click me to reveal the dialog</button>



<p id="result"></p>

CSS

dialog::backdrop {
  background-color: rgba(255, 0, 0, .4);
}

dialog + .backdrop {
  background-color: rgba(255, 0, 0, .4);
}

JavaScript

(function() {

  // nb. This is for IE10 and lower _only_.
  var supportCustomEvent = window.CustomEvent;
  if (!supportCustomEvent || typeof supportCustomEvent === 'object') {
    supportCustomEvent = function CustomEvent(event, x) {
      x = x || {};
      var ev = document.createEvent('CustomEvent');
      ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null);
      return ev;
    };
    supportCustomEvent.prototype = window.Event.prototype;
  }

  /**
   * @param {Element} el to check for stacking context
   * @return {boolean} whether this el or its parents creates a stacking context
   */
  function createsStackingContext(el) {
    while (el && el !== document.body) {
      var s = window.getComputedStyle(el);
      var invalid = function(k, ok) {
        return !(s[k] === undefined || s[k] === ok);
      }
      if (s.opacity < 1 ||
          invalid('zIndex', 'auto') ||
          invalid('transform', 'none') ||
          invalid('mixBlendMode', 'normal') ||
          invalid('filter', 'none') ||
          invalid('perspective', 'none') ||
          s['isolation'] === 'isolate' ||
          s.position === 'fixed' ||
          s.webkitOverflowScrolling === 'touch') {
        return true;
      }
      el = el.parentElement;
    }
    return false;
  }

  /**
   * Finds the nearest <dialog> from the passed element.
   *
   * @param {Element} el to search from
   * @return {HTMLDialogElement} dialog found
   */
  function findNearestDialog(el) {
    while (el) {
      if (el.localName === 'dialog') {
        return /** @type {HTMLDialogElement} */ (el);
      }
      el = el.parentElement;
    }
    return null;
  }

  /**
   * Blur the specified element, as long as it's not the HTML body element.
   * This works around an IE9/10 bug - blurring the body causes Windows to
   * blur the whole application.
   *
   * @param {Element} el to blur
   */
  function safeBlur(el) {
    if (el && el.blur && el !== document.body) {
      el.blur();
  ...