This source file includes following definitions.
- setFocusForModalDialog
- inertSubtreesChanged
- m_returnValue
- create
- close
- closeDialog
- forceLayoutForCentering
- show
- showModal
- removedFrom
- setCentered
- setNotCentered
- isPresentationAttribute
- defaultEventHandler
#include "config.h"
#include "core/html/HTMLDialogElement.h"
#include "bindings/v8/ExceptionState.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/NodeTraversal.h"
#include "core/html/HTMLFormControlElement.h"
#include "core/frame/FrameView.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/style/RenderStyle.h"
namespace WebCore {
using namespace HTMLNames;
static void setFocusForModalDialog(HTMLDialogElement* dialog)
{
Element* focusableDescendant = 0;
Node* next = 0;
for (Node* node = dialog->firstChild(); node; node = next) {
if (isHTMLDialogElement(*node))
next = NodeTraversal::nextSkippingChildren(*node, dialog);
else
next = NodeTraversal::next(*node, dialog);
if (!node->isElementNode())
continue;
Element* element = toElement(node);
if (element->isFormControlElement()) {
HTMLFormControlElement* control = toHTMLFormControlElement(node);
if (control->isAutofocusable()) {
control->focus();
return;
}
}
if (!focusableDescendant && element->isFocusable())
focusableDescendant = element;
}
if (focusableDescendant) {
focusableDescendant->focus();
return;
}
if (dialog->isFocusable()) {
dialog->focus();
return;
}
dialog->document().setFocusedElement(nullptr);
}
static void inertSubtreesChanged(Document& document)
{
Document& topDocument = document.topDocument();
topDocument.clearAXObjectCache();
if (AXObjectCache* cache = topDocument.axObjectCache())
cache->childrenChanged(cache->getOrCreate(&topDocument));
}
HTMLDialogElement::HTMLDialogElement(Document& document)
: HTMLElement(dialogTag, document)
, m_centeringMode(NotCentered)
, m_centeredPosition(0)
, m_returnValue("")
{
ScriptWrappable::init(this);
}
PassRefPtr<HTMLDialogElement> HTMLDialogElement::create(Document& document)
{
return adoptRef(new HTMLDialogElement(document));
}
void HTMLDialogElement::close(const String& returnValue, ExceptionState& exceptionState)
{
if (!fastHasAttribute(openAttr)) {
exceptionState.throwDOMException(InvalidStateError, "The element does not have an 'open' attribute, and therefore cannot be closed.");
return;
}
closeDialog(returnValue);
}
void HTMLDialogElement::closeDialog(const String& returnValue)
{
if (!fastHasAttribute(openAttr))
return;
setBooleanAttribute(openAttr, false);
HTMLDialogElement* activeModalDialog = document().activeModalDialog();
document().removeFromTopLayer(this);
if (activeModalDialog == this)
inertSubtreesChanged(document());
if (!returnValue.isNull())
m_returnValue = returnValue;
dispatchScopedEvent(Event::create(EventTypeNames::close));
}
void HTMLDialogElement::forceLayoutForCentering()
{
m_centeringMode = NeedsCentering;
document().updateLayoutIgnorePendingStylesheets();
if (m_centeringMode == NeedsCentering)
setNotCentered();
}
void HTMLDialogElement::show()
{
if (fastHasAttribute(openAttr))
return;
setBooleanAttribute(openAttr, true);
}
void HTMLDialogElement::showModal(ExceptionState& exceptionState)
{
if (fastHasAttribute(openAttr)) {
exceptionState.throwDOMException(InvalidStateError, "The element already has an 'open' attribute, and therefore cannot be opened modally.");
return;
}
if (!inDocument()) {
exceptionState.throwDOMException(InvalidStateError, "The element is not in a Document.");
return;
}
document().addToTopLayer(this);
setBooleanAttribute(openAttr, true);
inertSubtreesChanged(document());
forceLayoutForCentering();
setFocusForModalDialog(this);
}
void HTMLDialogElement::removedFrom(ContainerNode* insertionPoint)
{
HTMLElement::removedFrom(insertionPoint);
setNotCentered();
}
void HTMLDialogElement::setCentered(LayoutUnit centeredPosition)
{
ASSERT(m_centeringMode == NeedsCentering);
m_centeredPosition = centeredPosition;
m_centeringMode = Centered;
}
void HTMLDialogElement::setNotCentered()
{
m_centeringMode = NotCentered;
}
bool HTMLDialogElement::isPresentationAttribute(const QualifiedName& name) const
{
if (name == openAttr)
return true;
return HTMLElement::isPresentationAttribute(name);
}
void HTMLDialogElement::defaultEventHandler(Event* event)
{
if (event->type() == EventTypeNames::cancel) {
closeDialog();
event->setDefaultHandled();
return;
}
HTMLElement::defaultEventHandler(event);
}
}