15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)cr.define('cr.ui.dialogs', function() {
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function BaseDialog(parentNode) {
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.parentNode_ = parentNode;
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.document_ = parentNode.ownerDocument;
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The DOM element from the dialog which should receive focus when the
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // dialog is first displayed.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.initialFocusElement_ = null;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The DOM element from the parent which had focus before we were displayed,
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // so we can restore it when we're hidden.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.previousActiveElement_ = null;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.initDom_();
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /**
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * Default text for Ok and Cancel buttons.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   *
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * Clients should override these with localized labels.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.OK_LABEL = '[LOCALIZE ME] Ok';
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.CANCEL_LABEL = '[LOCALIZE ME] Cancel';
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /**
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * Number of miliseconds animation is expected to take, plus some margin for
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * error.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.ANIMATE_STABLE_DURATION = 500;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.initDom_ = function() {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var doc = this.document_;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.container_ = doc.createElement('div');
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.container_.className = 'cr-dialog-container';
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.container_.addEventListener('keydown',
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     this.onContainerKeyDown_.bind(this));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.shield_ = doc.createElement('div');
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.shield_.className = 'cr-dialog-shield';
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.container_.appendChild(this.shield_);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.container_.addEventListener('mousedown',
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     this.onContainerMouseDown_.bind(this));
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.frame_ = doc.createElement('div');
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.frame_.className = 'cr-dialog-frame';
505e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    // Elements that have negative tabIndex can be focused but are not traversed
515e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    // by Tab key.
525e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    this.frame_.tabIndex = -1;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.container_.appendChild(this.frame_);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.title_ = doc.createElement('div');
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.title_.className = 'cr-dialog-title';
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.frame_.appendChild(this.title_);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.closeButton_ = doc.createElement('div');
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.closeButton_.className = 'cr-dialog-close';
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.closeButton_.addEventListener('click',
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        this.onCancelClick_.bind(this));
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.frame_.appendChild(this.closeButton_);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.text_ = doc.createElement('div');
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.text_.className = 'cr-dialog-text';
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.frame_.appendChild(this.text_);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var buttons = doc.createElement('div');
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buttons.className = 'cr-dialog-buttons';
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.frame_.appendChild(buttons);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.okButton_ = doc.createElement('button');
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.okButton_.className = 'cr-dialog-ok';
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.okButton_.textContent = BaseDialog.OK_LABEL;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.okButton_.addEventListener('click', this.onOkClick_.bind(this));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buttons.appendChild(this.okButton_);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.cancelButton_ = doc.createElement('button');
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.cancelButton_.className = 'cr-dialog-cancel';
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.cancelButton_.textContent = BaseDialog.CANCEL_LABEL;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.cancelButton_.addEventListener('click',
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        this.onCancelClick_.bind(this));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buttons.appendChild(this.cancelButton_);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.initialFocusElement_ = this.okButton_;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.onOk_ = null;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.onCancel_ = null;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.onContainerKeyDown_ = function(event) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Handle Escape.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event.keyCode == 27 && !this.cancelButton_.disabled) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.onCancelClick_(event);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event.preventDefault();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.onContainerMouseDown_ = function(event) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event.target == this.container_) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var classList = this.frame_.classList;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Start 'pulse' animation.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      classList.remove('pulse');
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      setTimeout(classList.add.bind(classList, 'pulse'), 0);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event.preventDefault();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.onOkClick_ = function(event) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.hide();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (this.onOk_)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.onOk_();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.onCancelClick_ = function(event) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.hide();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (this.onCancel_)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.onCancel_();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.setOkLabel = function(label) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.okButton_.textContent = label;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.setCancelLabel = function(label) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.cancelButton_.textContent = label;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.setInitialFocusOnCancel = function() {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.initialFocusElement_ = this.cancelButton_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.show = function(message, onOk, onCancel, onShow) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.showWithTitle(null, message, onOk, onCancel, onShow);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.showHtml = function(title, message,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      onOk, onCancel, onShow) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.text_.innerHTML = message;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.show_(title, onOk, onCancel, onShow);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.findFocusableElements_ = function(doc) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var elements = Array.prototype.filter.call(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        doc.querySelectorAll('*'),
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        function(n) { return n.tabIndex >= 0; });
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var iframes = doc.querySelectorAll('iframe');
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (var i = 0; i < iframes.length; i++) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Some iframes have an undefined contentDocument for security reasons,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // such as chrome://terms (which is used in the chromeos OOBE screens).
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var contentDoc = iframes[i].contentDocument;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (contentDoc)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        elements = elements.concat(this.findFocusableElements_(contentDoc));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return elements;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.showWithTitle = function(title, message,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      onOk, onCancel, onShow) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.text_.textContent = message;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.show_(title, onOk, onCancel, onShow);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.show_ = function(title, onOk, onCancel, onShow) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make all outside nodes unfocusable while the dialog is active.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.deactivatedNodes_ = this.findFocusableElements_(this.document_);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.tabIndexes_ = this.deactivatedNodes_.map(
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        function(n) { return n.getAttribute('tabindex'); });
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.deactivatedNodes_.forEach(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        function(n) { n.tabIndex = -1; });
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.previousActiveElement_ = this.document_.activeElement;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.parentNode_.appendChild(this.container_);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.onOk_ = onOk;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.onCancel_ = onCancel;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (title) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.title_.textContent = title;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.title_.hidden = false;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.title_.textContent = '';
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.title_.hidden = true;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var self = this;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    setTimeout(function() {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Note that we control the opacity of the *container*, but the top/left
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // of the *frame*.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.container_.classList.add('shown');
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.initialFocusElement_.focus();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      setTimeout(function() {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (onShow)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          onShow();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }, BaseDialog.ANIMATE_STABLE_DURATION);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }, 0);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BaseDialog.prototype.hide = function(onHide) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restore focusability.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (var i = 0; i < this.deactivatedNodes_.length; i++) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var node = this.deactivatedNodes_[i];
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (this.tabIndexes_[i] === null)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        node.removeAttribute('tabindex');
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        node.setAttribute('tabindex', this.tabIndexes_[i]);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.deactivatedNodes_ = null;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.tabIndexes_ = null;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that we control the opacity of the *container*, but the top/left
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of the *frame*.
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.container_.classList.remove('shown');
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (this.previousActiveElement_) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.previousActiveElement_.focus();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.document_.body.focus();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.frame_.classList.remove('pulse');
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var self = this;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    setTimeout(function() {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Wait until the transition is done before removing the dialog.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.parentNode_.removeChild(self.container_);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (onHide)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        onHide();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }, BaseDialog.ANIMATE_STABLE_DURATION);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /**
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * AlertDialog contains just a message and an ok button.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function AlertDialog(parentNode) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BaseDialog.apply(this, [parentNode]);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.cancelButton_.style.display = 'none';
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AlertDialog.prototype = {__proto__: BaseDialog.prototype};
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AlertDialog.prototype.show = function(message, onOk, onShow) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return BaseDialog.prototype.show.apply(this, [message, onOk, onOk, onShow]);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /**
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * ConfirmDialog contains a message, an ok button, and a cancel button.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function ConfirmDialog(parentNode) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BaseDialog.apply(this, [parentNode]);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfirmDialog.prototype = {__proto__: BaseDialog.prototype};
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /**
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * PromptDialog contains a message, a text input, an ok button, and a
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * cancel button.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function PromptDialog(parentNode) {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BaseDialog.apply(this, [parentNode]);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.input_ = this.document_.createElement('input');
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.input_.setAttribute('type', 'text');
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.input_.addEventListener('focus', this.onInputFocus.bind(this));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.input_.addEventListener('keydown', this.onKeyDown_.bind(this));
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.initialFocusElement_ = this.input_;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.frame_.insertBefore(this.input_, this.text_.nextSibling);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PromptDialog.prototype = {__proto__: BaseDialog.prototype};
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PromptDialog.prototype.onInputFocus = function(event) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.input_.select();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PromptDialog.prototype.onKeyDown_ = function(event) {
2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (event.keyCode == 13) {  // Enter
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.onOkClick_(event);
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      event.preventDefault();
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PromptDialog.prototype.show = function(message, defaultValue, onOk, onCancel,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        onShow) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.input_.value = defaultValue || '';
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return BaseDialog.prototype.show.apply(this, [message, onOk, onCancel,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  onShow]);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PromptDialog.prototype.getValue = function() {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return this.input_.value;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PromptDialog.prototype.onOkClick_ = function(event) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this.hide();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (this.onOk_)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this.onOk_(this.getValue());
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BaseDialog: BaseDialog,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AlertDialog: AlertDialog,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConfirmDialog: ConfirmDialog,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PromptDialog: PromptDialog
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)});
307