Coder Social home page Coder Social logo

dialog-polyfill's Introduction

dialog-polyfill.js is a polyfill for <dialog> and <form method="dialog">. Check out some demos!

<dialog> is an element for a popup box in a web page, including a modal option which will make the rest of the page inert during use. This could be useful to block a user's interaction until they give you a response, or to confirm an action. See the HTML spec.

Usage

Installation

You may optionally install via NPM -

$ npm install dialog-polyfill

There are several ways that to include the dialog polyfill:

  • include dist/dialog-polyfill.js script directly in your HTML, which exposes a global dialogPolyfill function.
  • import (es modules)
  • require (commonjs/node)
// direct import (script module, deno)
import dialogPolyfill from './node_modules/dialog-polyfill/dist/dialog-polyfill.esm.js';

// *OR*

// modern es modules with rollup/webpack bundlers, and node via esm module
import dialogPolyfill from 'dialog-polyfill'

// *OR*

// traditional commonjs/node and browserify bundler
const dialogPolyfill = require('dialog-polyfill')

Supports

This polyfill works on modern versions of all major browsers. It also supports IE9 and above. It can work when used inside Shadow DOM, but it's not recommended.

Steps

  1. Include the CSS in the <head> of your document, and the JS anywhere before referencing dialogPolyfill.
  2. Create your dialog elements within the document. See limitations for more details.
  3. Register the elements using dialogPolyfill.registerDialog(), passing it one node at a time. This polyfill won't replace native support.
  4. Use your <dialog> elements!

Script Global Example

<head>
  <link rel="stylesheet" type="text/css" href="dist/dialog-polyfill.css" />
</head>
<body>
  <dialog>
    I'm a dialog!
    <form method="dialog">
      <input type="submit" value="Close" />
    </form>
  </dialog>
  <script src="dist/dialog-polyfill.js"></script>
  <script>
    var dialog = document.querySelector('dialog');
    dialogPolyfill.registerDialog(dialog);
    // Now dialog always acts like a native <dialog>.
    dialog.showModal();
  </script>
</body>

::backdrop

In native <dialog>, the backdrop is a pseudo-element. When using the polyfill, the backdrop will be an adjacent element:

dialog::backdrop { /* native */
  background-color: green;
}
dialog + .backdrop { /* polyfill */
  background-color: green;
}

Limitations

In the polyfill, modal dialogs have limitations-

  • They should not be contained by parents that create a stacking context, see below
  • The browser's chrome may not always be accessible via the tab key
  • Changes to the CSS top/bottom values while open aren't retained

Stacking Context

The major limitation of the polyfill is that dialogs should not have parents that create a stacking context. The easiest way to solve this is to move your <dialog> element to be a child of <body>.

If this isn't possible you may still be able to use the dialog. However, you may want to resolve it for two major reasons-

  1. The polyfill can't guarantee that the dialog will be the top-most element of your page
  2. The dialog may be positioned incorrectly as they are positioned as part of the page layout where they are opened (defined by spec), and not at a fixed position in the user's browser.

To position a dialog in the center (regardless of user scroll position or stacking context), you can specify the following CSS-

dialog {
  position: fixed;
  top: 50%;
  transform: translate(0, -50%);
}

This is also provided as a helper CSS class in the polyfill CSS, .fixed. You can apply by using HTML like <dialog class="fixed">.

Extensions

Focus

The WAI-ARIA doc suggests returning focus to the previously focused element after a modal dialog is closed. However, this is not part of the dialog spec itself. See this snippet to add this, even to the native dialog.

dialog-polyfill's People

Contributors

agektmr avatar blanchg avatar brunoeberhard avatar chadkillingsworth avatar craigfrancis avatar davidlehn avatar ebidel avatar ffuubarbuzz avatar garbee avatar hadriann avatar jf10r avatar karlhorky avatar krman009 avatar lfbayer avatar matzko avatar merih avatar mfalken avatar mreinstein avatar niksy avatar puf avatar qurben avatar rowno avatar samthor avatar staugaard avatar suhajdab avatar timoxley avatar uniqname avatar wowczarek avatar xballoy avatar zmitroc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dialog-polyfill's Issues

The tops of tall dialogs are out of viewport if the dialog is taller than the viewport

https://html.spec.whatwg.org/multipage/forms.html#centered-alignment

The spec says that "When an element subject is placed in centered alignment mode, and when it is in that mode and has new rendering boxes created, the user agent must set up the element such that its top static position, for the purposes of calculating the used value of the 'top' property, is the value that would place the element's top margin edge as far from the top of the viewport as the element's bottom margin edge from the bottom of the viewport, if the element's height is less than the height of the viewport, and otherwise is the value that would place the element's top margin edge at the top of the viewport."

So if the dialog is taller than the viewport, the dialog should be positioned at the top of the viewport. I opened a PR for this as well.

Improve support for `position: fixed`

The native dialog seems to be in a fixed position, always centered horizontally and vertically... It would be a lot easier if it was the case for the polyfill as well.

Open CustomEvent missing

For some reason, the open event is suddenly missing for the open & showModal methods; are there particular reason for its removal? I'm almost certain this is a very recent change (or I'm too familar with various dialog implementations that I didn't catch this sooner when using this polyfill the past few years).

Nonetheless, I've created a PR #90 in case it is missing without a good reason and it is in fact something that is to be expected with the dialog element.

Backdrop

I want to close the dialog by clicking on the backdrop. What should I do to reach this?

Code:

<html>
<head>
  <script src="dialog-polyfill.js"></script>
  <link rel="stylesheet" type="text/css" href="dialog-polyfill.css" />
  <style>
    dialog::backdrop {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.8);
    }
  </style>
</head>
<body>
  <dialog>
    I'm a dialog!
    <form method="dialog">
      <button type="button">Close</button>
    </form>
  </dialog>
  <script>
    var dialog = document.querySelector('dialog');
    var close = dialog.querySelector('button');
    dialogPolyfill.registerDialog(dialog);
    dialog.showModal();
    close.onclick = function() {
      dialog.close();
    }
  </script>
</body>
</html

dynamically inserted dialog not working properly

When I insert dynamicaly HTML code that contains a form with method=dialog
ie:

Reject

The form submission is not intercepted and the native browser submit is executed.

Forms with method=dialog are only filtered in the window.onload maybe forms could be filtered in the "dialogPolyfill.registerDialog"

Please tag version 0.1.0

Can you please tag the version 0.1.0 to make it available via bower install command?

$ bower install --dev
bower dialog-polyfill#~0.1.0       not-cached git://github.com/GoogleChrome/dialog-polyfill.git#~0.1.0
bower dialog-polyfill#~0.1.0          resolve git://github.com/GoogleChrome/dialog-polyfill.git#~0.1.0
bower dialog-polyfill#~0.1.0     ENORESTARGET No tag found that was able to satisfy ~0.1.0

Additional error details:
No versions found in git://github.com/GoogleChrome/dialog-polyfill.git

pressing ESC during showModal sometimes doesnt close the dialog

If a page already has a handler for "ESC", and you show a modal dialog, the "ESC" event is trapped by the previous handler and not by the dialog.
In my case, I use this great polyfill in an open-source chrome extension: https://github.com/zmandel/Plus-for-Trello/blob/1c2fa9ca36327211834fd8f2933cfb47ad69ecf1/source/card.js#L360
and in that line you can see that I had to manually catch the keydown and close()
That dialog code is injected into a trello "card" (trello.com) and without it Trello will close the card and leave my dialog floating. Not sure if this is specific with being on a chrome extension.

Dialog's overlay stacks over dialog

The contents of dialog was inaccessible because dialog's overlay were on top dialog and by passing z-index rules.

The solution I've used to get the dialog working was add a display block to _dialog_overlay class.

I'm running this on Firefox 49.0
screenshot from 2016-10-20 15-08-54

Not working on iOS (both iOS Chrome and iOS Safari)

I'm using the current version of dialog-polyfill with Material Design Lite 1.2.1. On iOS 10.1.1, in both Safari and Chrome, it's not possible to tap into an input field in a dialog, nor is it possible to tap on any of the buttons in a dialog.

I've put a code snippet up illustrating this on StackOverflow

(Really hoping this is user error, and not a bug, as it's currently blocking progress!)

npm package?

I suggest that this project should also be published to npm for easier usage via browserify and other such tools.

'close' event should not bubble

According to the spec, when a dialog is closed, a simple event 'close' is fired, and a simple event "does not bubble (except where otherwise stated)". So the 'close' event of dialog should not bubble.

Cross-browser modal issue in Safari

Looks like the modal functionality has issue on the Safari. I have a login dialog modal. On firing up, the dialog came up fine. The moment you click any where on the screen (including the dialog), everything becomes unresponsive to the mouse click, including the dialog itself. I will not be able to access the form input fields or anything else for that matter.

Basically the whole page gets locked out including the dialog. To unlock it, I go into the console and disable the z-index for the _dialog_overlay. But this disables the dialog_overlay and hence breaking the modal functionality.

Is there any workaround for this problem? Is this a known modal issue with other browser like Safari?

Thanks

'submit' handler throws error when fired from a form without a 'method' attribute

Given this markup:

<form class="search-comp__form expanded">
  <button type="submit" class="search-comp__button">Search</button>
</form>

Clicking the button throws an error here:

/**
   * Global form 'dialog' method handler. Closes a dialog correctly on submit
   * and possibly sets its return value.
   */
  document.addEventListener('submit', function(ev) {
    var method = ev.target.getAttribute('method').toLowerCase(); // ERROR HERE

Because ev.target.getAttribute('method') is null.

I'll probably submit a PR to fix this later today.

returnValue isn't always set properly

In testing a simple <form method="dialog">, it's pretty easy to get the value of the focused element returned (rather than the value of the button used, which is what the spec days).

New release?

Hi @samthor! Thanks for doing this polyfill. I'm just wondering if it's possible to have a new tag/release here every now and then? The last tag was earlier this year and there have been plenty of commits since then (hence, the bower version getting pulled is pretty old).

Thanks a lot for your time.

edge and firefox dialog not responding to input and submit

can't input text and submit form with edge and firefox 45 have already corrected the positioning but can't figure out what is wrong on the input and submit.please stuck in a project with mdl really need help in to this issue thanks.

Create a dialog element

Can you add document.createElement("dialog"); to the script, some browsers don't recognize the element when they parse the DOM. They just make an empty node which gets scripted, but the content follows as a sibling.

Revision of what demos to provide to users of browsers without native dialog element support may be needed.

It seems the demo page provided only informs the user their browser doesn't support dialog, but it doesn't seem to implement the actual polypill to experience things regarding the demo like the one that can be found here.

The dialog demo page I've linked to in the last paragraph may be provided to readers of the repository in addition to the one currently in the readme.md ( or replace the existing one ).

Firefox, Mutation Events

When I use dialog polyfill in Firefox version 45.0.1, OSX I get the following warning in console: "Use of Mutation Events is deprecated. Use MutationObserver instead.". Shouldn't the polyfill use MutationObserver if provided by the browser?

Form with button does not return value as returnValue

ReturnValue is not set to the BUTTON value parameter on form submission.

When we press "Yes" in the following example dialog.close(undefined) is called instead of dialog.close('yes')

<dialog id="dialog">
  <form method="dialog">
    <p>Do you agree with terms of use?</p>
    <textarea class="form-control" disabled>Lorem ipsum dolor sit amet,....</textarea>
    <button type="submit" value="yes">Yes</button>
    <button type="submit" value="no" autofocus>No</button>
  </form>
</dialog>

Proposed fix: in the submit handler accept either 'INPUT' or 'BUTTON' nodeName.

Tag a new release

The last release was a year ago, and there have been many commits to master since then.

IE8 Support

Sorry if I missed this but are there any plans to support IE8?

Firefox - tab focus gets stuck on body

When focusing on an element outside a modal (i.e. with the tab key), the polyfill just tries to prevent the event and calls blur() on the target. There's a TODO note about focusing on browser chrome or the dialog itself depending on the tab direction.

The current behaviour appears to be sufficient for Chrome 45 and IE11 (at least for the cases I have tried), but on Firefox 35 the focus gets stuck on the <body>. Pressing tab tries to focus the next element in the body, but this is denied or blurred, and the focus ends up back on the <body>.

Dialogs should only be centered when shown modally

When dialogs are modal, they are put into the top layer. When they're not, they should be positioned using normal alignment, as per the spec.

Currently, we try to position them in the center no matter what.

Chrome's native implementation (as of M43) mostly does this. Dialogs shown normally are just positioned as per the user agent CSS. However, if a dialog is shown modally, closed, and then shown again, it's still centered: this is a bug.

Content doesn't fit dialog when page uses border-box

The core issue

When a page uses border-box, which is rather common because bootstrap uses it:

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

Then the content will not fit the dialog, because both this polyfill & Chrome set the dialog width to fit-content (which matches the content's width), but also set a padding of 1em. With border-box the padding must be included in the width.

An example

You can see this issue in action. Use Chrome as it doesn't include the polyfill. However I've locally tested with the polyfill as well and the issue is the same.

Prior art

This issue has been also reported on the Chromium tracker. It's over a year old by now, so probably won't get fixed any time soon.

Comment 4 on that issue mentions this polyfill, specifically issue #15. The comment claims that this issue was fixed in the polyfill, however the linked issue #15 contains roughly zero information and I wasn't able to find any related commits during the issue closing time either. In addition, I tested the polyfill just now and the issue seems alive and well.

Proposed solution

If we set the box-sizing of dialog to content-box:

dialog {
  -webkit-box-sizing: content-box;
  -moz-box-sizing: content-box;
  box-sizing: content-box;
}

Then the 1em padding doesn't have to be accounted for in the width and fit-content creates just enough width to fit the content, even when the rest of the page uses border-box.

In addition, because the CSS polyfill always applies even to Chrome, this would work as a fix for Chrome.

Dialog not working in Firefox, works in Chrome

Hi.,

I have an Angular 2 app with Google Material Design Lite library. I am using 'dialog-polyfill' for MDL. It works well in Chrome 51, but not working in Firefox 47 & Safari 5.1.7

The html elements for the dialog is always visible inline and not appearing as popup.

Please find the files below :

login-page.html

<div class="login">
  <div class="form wrapper text-center">
    <div class="mdl-card">
      <form action="#">
        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label textfield-demo">
          <input class="mdl-textfield__input" type="email" id="email"/>
          <label class="mdl-textfield__label" for="email">Email Id</label>
          <span class="mdl-textfield__error">Please enter a valid email address!</span>
        </div>
        <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label textfield-demo">
          <input class="mdl-textfield__input" type="password" id="password"/>
          <label class="mdl-textfield__label" for="password">Password</label>
        </div>
      </form>
    </div>
    <dialog id="dialog" class="mdl-dialog">
      <h4 class="mdl-dialog__title">Hello User</h4>
      <div class="mdl-dialog__content">
        <p>Hello world from dialog!
        <p>
      </div>
      <div class="mdl-dialog__actions">
        <button type="button" (click)="closeDialog()" class="mdl-button close">Disagree</button>
      </div>
    </dialog>
    <button (click)="showDialog()" id="show-info"
            class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button&#45;&#45;accent">
      Show Info
    </button>
    <div class="text-center">
      <a class="mdl-button mdl-js-button btn-white mdl-js-ripple-effect mdl-button--raised mdl-button--colored">
        Sign In
      </a>
    </div>
  </div>
</div>

login.component.ts :

@Component({
  selector: 'login',
  styles: [
    require('./login.component.less')
  ],
  template: require('./login.component.html'),
  encapsulation: ViewEncapsulation.Emulated
})
export class LoginComponent implements OnInit {
  dialog:HTMLElement = null;

  constructor() {
  }

  ngOnInit() {
    this.dialog = document.getElementById('dialog');
    window['dialogPolyfill'].registerDialog(this.dialog);    
  }

  showDialog() {
    this.dialog.showModal();
  }

  closeDialog(){ 
    this.dialog.close();
  } 
}

This is how it looks :

Firefox :

image

Safari :

image

Thanks in advance.

"ESC" key to close isn't an optional

Hi everyone,

There're some dialogs that I don't want user closes them when pressing on "ESC" key.
But I don't find anyway to prevent it.

Here is what I found so far.
dialogPolyfill.DialogManager.prototype.blockDocument = function() { document.body.appendChild(this.overlay); document.body.addEventListener('focus', this.handleFocus_, true); document.addEventListener('keydown', this.handleKey_); document.addEventListener('DOMNodeRemoved', this.handleRemove_); };

Is there anyway to do it? (I don't want to remove all "keydown" handlers of document!)
Thanks in advance.

Is this guaranteed to appear always on top?

Disappointed chrome requires the experimental flag turned on. I like the idea of because it would ensure that it will never get hidden below elements. I am creating a chrome extension and this is important for me that the dialog always appear on top of all other elements on a given page.

Nested Dialogs

The overlay appears in front of nested dialogs.

https://jsfiddle.net/4kdz00t5/4/

The fiddle will use the native support in Chrome and works ok, in IE11 it will use the Polyfill and you cannot interact with elements on the nested dialog.

Esc key while modal is open dismisses the modal and throws ReferenceError

Uncaught ReferenceError: InvalidStateError is not defined

The event dispatched at

if (dialog.dispatchEvent(cancelEvent)) {
removes the dialog and sets open=false (but doesn't remove any background styling--that's done in close()), however when close() is called, t.open is false so it thinks close() is being called on a closed dialog and tries to throw an exception type that doesn't exist.

I haven't figured out the best way to fix that.

Console warning when dialog is placed incorrectly

Can we fire a warning in the console if we detect the dialog is a child of an absolute or relative positioned element? Many developers get caught off-guard by this, at least within those using it for MDL. If the polyfill itself could detect and warn about this case directly then all developers would get feedback on this error and understand clearly why their code isn't working right.

Modal dialog and click events on backdrop

I'd like to hookup an event handler to close a modal dialog when the user clicks on the backdrop.

I see that click events for the backdrop are forwarded to the dialog element, but if I add a click handler here it will also cause the dialog to close if I click on the dialog itself.

Is there a way to distinguish between a click event on the dialog itself versus the backdrop?

CSS needs cross-browser work

In IE10, the default CSS does not make it look like in other browsers, the window is either the same width as the entire window, or it is left-aligned when it's centered in other browsers.

Scroll lock

This is a hard bug to reproduce, but, sometimes after closing a dialog my scroll will remain locked until I refresh the page.

Is there a way to disable the scroll lock feature?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.