/*
 * Copyright (C) 2011 Apple Inc. All Rights Reserved.
 * Copyright (C) 2012 Igalia S.L.
 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "AccessibilityUIElement.h"

#if HAVE(ACCESSIBILITY)

#include "InjectedBundle.h"
#include "InjectedBundlePage.h"
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/OpaqueJSString.h>
#include <WebCore/NotImplemented.h>
#include <WebKit/WKBundleFrame.h>
#include <atk/atk.h>
#include <wtf/Assertions.h>
#include <wtf/UniqueArray.h>
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/unicode/CharacterNames.h>

namespace WTR {

namespace {

enum RangeLimit {
    RangeLimitMinimum,
    RangeLimitMaximum
};

enum AtkAttributeType {
    ObjectAttributeType,
    TextAttributeType
};

enum AttributesIndex {
    // Attribute names.
    InvalidNameIndex = 0,
    ColumnCount,
    ColumnIndex,
    ColumnSpan,
    RowCount,
    RowIndex,
    RowSpan,
    PosInSetIndex,
    SetSizeIndex,
    PlaceholderNameIndex,
    SortNameIndex,
    CurrentNameIndex,
    AriaLiveNameIndex,
    AriaAtomicNameIndex,
    AriaRelevantNameIndex,
    BusyNameIndex,

    // Attribute values.
    SortAscendingValueIndex,
    SortDescendingValueIndex,
    SortUnknownValueIndex,

    NumberOfAttributes
};

// Attribute names & Values (keep on sync with enum AttributesIndex).
struct Attribute {
    String coreDomain;
    String atkDomain;
};
using Attributes = std::array<Attribute, NumberOfAttributes>;
static const Attributes& attributesMap()
{
    static NeverDestroyed<Attributes> attributes = Attributes({
        // Attribute names.
        Attribute { "AXInvalid", "invalid" },
        Attribute { "AXARIAColumnCount", "colcount" },
        Attribute { "AXARIAColumnIndex", "colindex" },
        Attribute { "AXARIAColumnSpan", "colspan" },
        Attribute { "AXARIARowCount", "rowcount" },
        Attribute { "AXARIARowIndex", "rowindex" },
        Attribute { "AXARIARowSpan", "rowspan" },
        Attribute { "AXARIAPosInSet", "posinset" },
        Attribute { "AXARIASetSize", "setsize" },
        Attribute { "AXPlaceholderValue", "placeholder-text" } ,
        Attribute { "AXSortDirection", "sort" },
        Attribute { "AXARIACurrent", "current" },
        Attribute { "AXARIALive", "live" },
        Attribute { "AXARIAAtomic", "atomic" },
        Attribute { "AXARIARelevant", "relevant" },
        Attribute { "AXElementBusy", "busy" },

        // Attribute values.
        Attribute { "AXAscendingSortDirection", "ascending" },
        Attribute { "AXDescendingSortDirection", "descending" },
        Attribute { "AXUnknownSortDirection", "unknown" },
    });
    return attributes.get();
}

const char* landmarkStringBanner = "AXLandmarkBanner";
const char* landmarkStringComplementary = "AXLandmarkComplementary";
const char* landmarkStringContentinfo = "AXLandmarkContentInfo";
const char* landmarkStringForm = "AXLandmarkForm";
const char* landmarkStringMain = "AXLandmarkMain";
const char* landmarkStringNavigation = "AXLandmarkNavigation";
const char* landmarkStringRegion = "AXLandmarkRegion";
const char* landmarkStringSearch = "AXLandmarkSearch";

String jsStringToWTFString(JSStringRef attribute)
{
    size_t bufferSize = JSStringGetMaximumUTF8CStringSize(attribute);
    GUniquePtr<gchar> buffer(static_cast<gchar*>(g_malloc(bufferSize)));
    JSStringGetUTF8CString(attribute, buffer.get(), bufferSize);

    return String::fromUTF8(buffer.get());
}

String coreAttributeToAtkAttribute(JSStringRef attribute)
{
    String attributeString = jsStringToWTFString(attribute);
    for (int i = 0; i < NumberOfAttributes; ++i) {
        if (attributesMap()[i].coreDomain == attributeString)
            return attributesMap()[i].atkDomain;
    }

    return attributeString;
}

String atkAttributeValueToCoreAttributeValue(AtkAttributeType type, const String& id, const String& value)
{
    if (type == ObjectAttributeType) {
        // We don't expose the "current" attribute if there is no author-provided value.
        if (id == attributesMap()[CurrentNameIndex].atkDomain && value.isEmpty())
            return "false";

        // We need to translate ATK values exposed for 'aria-sort' (e.g. 'ascending')
        // into those expected by the layout tests (e.g. 'AXAscendingSortDirection').
        if (id == attributesMap()[SortNameIndex].atkDomain && !value.isEmpty()) {
            if (value == attributesMap()[SortAscendingValueIndex].atkDomain)
                return attributesMap()[SortAscendingValueIndex].coreDomain;
            if (value == attributesMap()[SortDescendingValueIndex].atkDomain)
                return attributesMap()[SortDescendingValueIndex].coreDomain;

            return attributesMap()[SortUnknownValueIndex].coreDomain;
        }
    } else if (type == TextAttributeType) {
        // In case of 'aria-invalid' when the attribute empty or has "false" for ATK
        // it should not be mapped at all, but layout tests will expect 'false'.
        if (id == attributesMap()[InvalidNameIndex].atkDomain && value.isEmpty())
            return "false";
    }

    return value;
}

AtkAttributeSet* getAttributeSet(AtkObject* accessible, AtkAttributeType type)
{
    if (!accessible)
        return nullptr;

    if (type == ObjectAttributeType)
        return atk_object_get_attributes(accessible);

    if (type == TextAttributeType) {
        if (!ATK_IS_TEXT(accessible))
            return nullptr;

        return atk_text_get_default_attributes(ATK_TEXT(accessible));
    }

    ASSERT_NOT_REACHED();
    return nullptr;
}

String getAttributeSetValueForId(AtkObject* accessible, AtkAttributeType type, String id)
{
    AtkAttributeSet* attributeSet = getAttributeSet(accessible, type);
    if (!attributeSet)
        return String();

    String attributeValue;
    for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) {
        AtkAttribute* atkAttribute = static_cast<AtkAttribute*>(attributes->data);
        if (id == atkAttribute->name) {
            attributeValue = String::fromUTF8(atkAttribute->value);
            break;
        }
    }
    atk_attribute_set_free(attributeSet);

    return atkAttributeValueToCoreAttributeValue(type, id, attributeValue);
}

String attributeSetToString(AtkAttributeSet* attributeSet, String separator=", ")
{
    if (!attributeSet)
        return String();

    StringBuilder builder;
    for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) {
        AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data);
        builder.append(attribute->name);
        builder.append(':');
        builder.append(attribute->value);
        if (attributes->next)
            builder.append(separator);
    }
    atk_attribute_set_free(attributeSet);

    return builder.toString();
}

String getAtkAttributeSetAsString(AtkObject* accessible, AtkAttributeType type,  String separator=", ")
{
    return attributeSetToString(getAttributeSet(accessible, type), separator);
}

bool checkElementState(PlatformUIElement element, AtkStateType stateType)
{
    if (!ATK_IS_OBJECT(element.get()))
        return false;

    GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(element.get())));
    return atk_state_set_contains_state(stateSet.get(), stateType);
}

JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)
{
    GUniquePtr<gchar> rangeString(g_strdup("{0, 0}"));
    if (!ATK_IS_TABLE_CELL(element.get()))
        return JSStringCreateWithUTF8CString(rangeString.get());

    gint row = -1;
    gint column = -1;
    gint rowSpan = -1;
    gint columnSpan = -1;
    atk_table_cell_get_row_column_span(ATK_TABLE_CELL(element.get()), &row, &column, &rowSpan, &columnSpan);

    // Get the actual values, if row and columns are valid values.
    if (row != -1 && column != -1) {
        int base = 0;
        int length = 0;
        if (isRowRange) {
            base = row;
            length = rowSpan;
        } else {
            base = column;
            length = columnSpan;
        }
        rangeString.reset(g_strdup_printf("{%d, %d}", base, length));
    }

    return JSStringCreateWithUTF8CString(rangeString.get());
}

void alterCurrentValue(PlatformUIElement element, int factor)
{
    if (!ATK_IS_VALUE(element.get()))
        return;

    double currentValue;
    atk_value_get_value_and_text(ATK_VALUE(element.get()), &currentValue, nullptr);

    double increment = atk_value_get_increment(ATK_VALUE(element.get()));
    atk_value_set_value(ATK_VALUE(element.get()), currentValue + factor * increment);
}

gchar* replaceCharactersForResults(gchar* str)
{
    WTF::String uString = WTF::String::fromUTF8(str);

    // The object replacement character is passed along to ATs so we need to be
    // able to test for their presence and do so without causing test failures.
    uString.replace(objectReplacementCharacter, "<obj>");

    // The presence of newline characters in accessible text of a single object
    // is appropriate, but it makes test results (especially the accessible tree)
    // harder to read.
    uString.replace("\n", "<\\n>");

    return g_strdup(uString.utf8().data());
}

const gchar* roleToString(AtkObject* object)
{
    AtkRole role = atk_object_get_role(object);

    if (role == ATK_ROLE_LANDMARK) {
        String xmlRolesValue = getAttributeSetValueForId(object, ObjectAttributeType, "xml-roles");
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "banner"))
            return landmarkStringBanner;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "complementary"))
            return landmarkStringComplementary;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "contentinfo"))
            return landmarkStringContentinfo;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-acknowledgments"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-afterword"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-appendix"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-bibliography"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-chapter"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-conclusion"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-credits"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-endnotes"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-epilogue"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-errata"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-foreword"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-glossary"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-glossref"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-index"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-introduction"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-pagelist"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-part"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-preface"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-prologue"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "doc-toc"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "form"))
            return landmarkStringForm;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "main"))
            return landmarkStringMain;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "navigation"))
            return landmarkStringNavigation;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "region"))
            return landmarkStringRegion;
        if (equalLettersIgnoringASCIICase(xmlRolesValue, "search"))
            return landmarkStringSearch;
    }

    switch (role) {
    case ATK_ROLE_ALERT:
        return "AXAlert";
    case ATK_ROLE_DIALOG:
        return "AXDialog";
    case ATK_ROLE_CANVAS:
        return "AXCanvas";
    case ATK_ROLE_CAPTION:
        return "AXCaption";
    case ATK_ROLE_CHECK_BOX:
        return "AXCheckBox";
    case ATK_ROLE_COLOR_CHOOSER:
        return "AXColorWell";
    case ATK_ROLE_COLUMN_HEADER:
        return "AXColumnHeader";
    case ATK_ROLE_COMBO_BOX:
        return "AXComboBox";
    case ATK_ROLE_COMMENT:
        return "AXComment";
    case ATK_ROLE_DOCUMENT_FRAME:
        return "AXDocument";
    case ATK_ROLE_DOCUMENT_WEB:
        return "AXWebArea";
    case ATK_ROLE_EMBEDDED:
        return "AXEmbedded";
    case ATK_ROLE_ENTRY:
        return "AXTextField";
    case ATK_ROLE_FOOTER:
        return "AXFooter";
    case ATK_ROLE_FORM:
        return "AXForm";
    case ATK_ROLE_GROUPING:
        return "AXGroup";
    case ATK_ROLE_HEADING:
        return "AXHeading";
    case ATK_ROLE_IMAGE:
        return "AXImage";
    case ATK_ROLE_IMAGE_MAP:
        return "AXImageMap";
    case ATK_ROLE_INVALID:
        return "AXInvalid";
    case ATK_ROLE_LABEL:
        return "AXLabel";
    case ATK_ROLE_LEVEL_BAR:
        return "AXLevelIndicator";
    case ATK_ROLE_LINK:
        return "AXLink";
    case ATK_ROLE_LIST:
        return "AXList";
    case ATK_ROLE_LIST_BOX:
        return "AXListBox";
    case ATK_ROLE_LIST_ITEM:
        return "AXListItem";
    case ATK_ROLE_MENU:
        return "AXMenu";
    case ATK_ROLE_MENU_BAR:
        return "AXMenuBar";
    case ATK_ROLE_MENU_ITEM:
        return "AXMenuItem";
    case ATK_ROLE_PAGE_TAB:
        return "AXTab";
    case ATK_ROLE_PAGE_TAB_LIST:
        return "AXTabGroup";
    case ATK_ROLE_PANEL:
        return "AXGroup";
    case ATK_ROLE_PARAGRAPH:
        return "AXParagraph";
    case ATK_ROLE_PASSWORD_TEXT:
        return "AXPasswordField";
    case ATK_ROLE_PROGRESS_BAR:
        return "AXProgressIndicator";
    case ATK_ROLE_PUSH_BUTTON:
        return "AXButton";
    case ATK_ROLE_RADIO_BUTTON:
        return "AXRadioButton";
    case ATK_ROLE_RADIO_MENU_ITEM:
        return "AXRadioMenuItem";
    case ATK_ROLE_ROW_HEADER:
        return "AXRowHeader";
    case ATK_ROLE_CHECK_MENU_ITEM:
        return "AXCheckMenuItem";
    case ATK_ROLE_RULER:
        return "AXRuler";
    case ATK_ROLE_SCROLL_BAR:
        return "AXScrollBar";
    case ATK_ROLE_SCROLL_PANE:
        return "AXScrollArea";
    case ATK_ROLE_SECTION:
        return "AXSection";
    case ATK_ROLE_SEPARATOR:
        return "AXSeparator";
    case ATK_ROLE_SLIDER:
        return "AXSlider";
    case ATK_ROLE_SPIN_BUTTON:
        return "AXSpinButton";
    case ATK_ROLE_STATUSBAR:
        return "AXStatusBar";
    case ATK_ROLE_TABLE:
        return "AXTable";
    case ATK_ROLE_TABLE_CELL:
        return "AXCell";
    case ATK_ROLE_TABLE_COLUMN_HEADER:
        return "AXColumnHeader";
    case ATK_ROLE_TABLE_ROW:
        return "AXRow";
    case ATK_ROLE_TABLE_ROW_HEADER:
        return "AXRowHeader";
    case ATK_ROLE_TOGGLE_BUTTON:
        return "AXToggleButton";
    case ATK_ROLE_TOOL_BAR:
        return "AXToolbar";
    case ATK_ROLE_TOOL_TIP:
        return "AXUserInterfaceTooltip";
    case ATK_ROLE_TREE:
        return "AXTree";
    case ATK_ROLE_TREE_TABLE:
        return "AXTreeGrid";
    case ATK_ROLE_TREE_ITEM:
        return "AXTreeItem";
    case ATK_ROLE_WINDOW:
        return "AXWindow";
    case ATK_ROLE_UNKNOWN:
        return "AXUnknown";
    case ATK_ROLE_ARTICLE:
        return "AXArticle";
    case ATK_ROLE_AUDIO:
        return "AXAudio";
    case ATK_ROLE_BLOCK_QUOTE:
        return "AXBlockquote";
    case ATK_ROLE_DEFINITION:
        return "AXDefinition";
    case ATK_ROLE_LOG:
        return "AXLog";
    case ATK_ROLE_MARQUEE:
        return "AXMarquee";
    case ATK_ROLE_MATH:
        return "AXMath";
    case ATK_ROLE_TIMER:
        return "AXTimer";
    case ATK_ROLE_VIDEO:
        return "AXVideo";
    case ATK_ROLE_DESCRIPTION_LIST:
        return "AXDescriptionList";
    case ATK_ROLE_DESCRIPTION_TERM:
        return "AXDescriptionTerm";
    case ATK_ROLE_DESCRIPTION_VALUE:
        return "AXDescriptionValue";
    case ATK_ROLE_STATIC:
        return "AXStatic";
    case ATK_ROLE_MATH_FRACTION:
        return "AXMathFraction";
    case ATK_ROLE_MATH_ROOT:
        return "AXMathRoot";
    case ATK_ROLE_SUBSCRIPT:
        return "AXSubscript";
    case ATK_ROLE_SUPERSCRIPT:
        return "AXSuperscript";
#if ATK_CHECK_VERSION(2, 25, 2)
    case ATK_ROLE_FOOTNOTE:
        return "AXFootnote";
#endif
#if ATK_CHECK_VERSION(2, 33, 3)
    case ATK_ROLE_CONTENT_DELETION:
        return "AXDeletion";
    case ATK_ROLE_CONTENT_INSERTION:
        return "AXInsertion";
#endif
    default:
        // We want to distinguish ATK_ROLE_UNKNOWN from a known AtkRole which
        // our DRT isn't properly handling.
        return "FIXME not identified";
    }
}

String selectedText(AtkObject* accessible)
{
    if (!ATK_IS_TEXT(accessible))
        return String();

    AtkText* text = ATK_TEXT(accessible);

    gint start, end;
    g_free(atk_text_get_selection(text, 0, &start, &end));

    return atk_text_get_text(text, start, end);
}

String attributesOfElement(AccessibilityUIElement* element)
{
    StringBuilder builder;

    builder.append(element->role()->string());
    builder.append('\n');

    // For the parent we print its role and its name, if available.
    builder.appendLiteral("AXParent: ");
    RefPtr<AccessibilityUIElement> parent = element->parentElement();
    AtkObject* atkParent = parent ? parent->platformUIElement().get() : nullptr;
    if (atkParent) {
        builder.append(roleToString(atkParent));
        const char* parentName = atk_object_get_name(atkParent);
        if (parentName && parentName[0]) {
            builder.appendLiteral(": ");
            builder.append(parentName);
        }
    } else
        builder.appendLiteral("(null)");
    builder.append('\n');

    builder.appendLiteral("AXChildren: ");
    builder.appendNumber(element->childrenCount());
    builder.append('\n');

    builder.appendLiteral("AXPosition:  { ");
    builder.append(FormattedNumber::fixedPrecision(element->x(), 6, KeepTrailingZeros));
    builder.appendLiteral(", ");
    builder.append(FormattedNumber::fixedPrecision(element->y(), 6, KeepTrailingZeros));
    builder.appendLiteral(" }\n");

    builder.appendLiteral("AXSize: { ");
    builder.append(FormattedNumber::fixedPrecision(element->width(), 6, KeepTrailingZeros));
    builder.appendLiteral(", ");
    builder.append(FormattedNumber::fixedPrecision(element->height(), 6, KeepTrailingZeros));
    builder.appendLiteral(" }\n");

    String title = element->title()->string();
    if (!title.isEmpty()) {
        builder.append(title);
        builder.append('\n');
    }

    String description = element->description()->string();
    if (!description.isEmpty()) {
        builder.append(description.utf8().data());
        builder.append('\n');
    }

    String value = element->stringValue()->string();
    if (!value.isEmpty()) {
        builder.append(value);
        builder.append('\n');
    }

    builder.appendLiteral("AXFocusable: ");
    builder.appendNumber(element->isFocusable());
    builder.append('\n');

    builder.appendLiteral("AXFocused: ");
    builder.appendNumber(element->isFocused());
    builder.append('\n');

    builder.appendLiteral("AXSelectable: ");
    builder.appendNumber(element->isSelectable());
    builder.append('\n');

    builder.appendLiteral("AXSelected: ");
    builder.appendNumber(element->isSelected());
    builder.append('\n');

    builder.appendLiteral("AXMultiSelectable: ");
    builder.appendNumber(element->isMultiSelectable());
    builder.append('\n');

    builder.appendLiteral("AXEnabled: ");
    builder.appendNumber(element->isEnabled());
    builder.append('\n');

    builder.appendLiteral("AXExpanded: ");
    builder.appendNumber(element->isExpanded());
    builder.append('\n');

    builder.appendLiteral("AXRequired: ");
    builder.appendNumber(element->isRequired());
    builder.append('\n');

    builder.appendLiteral("AXChecked: ");
    builder.appendNumber(element->isChecked());
    builder.append('\n');

    String url = element->url()->string();
    if (!url.isEmpty()) {
        builder.append(url);
        builder.append('\n');
    }

    // We append the ATK specific attributes as a single line at the end.
    builder.appendLiteral("AXPlatformAttributes: ");
    builder.append(getAtkAttributeSetAsString(element->platformUIElement().get(), ObjectAttributeType));

    return builder.toString();
}

static JSRetainPtr<JSStringRef> createStringWithAttributes(const Vector<RefPtr<AccessibilityUIElement> >& elements)
{
    StringBuilder builder;

    for (Vector<RefPtr<AccessibilityUIElement> >::const_iterator it = elements.begin(); it != elements.end(); ++it) {
        builder.append(attributesOfElement(const_cast<AccessibilityUIElement*>(it->get())));
        builder.appendLiteral("\n------------\n");
    }

    return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
}

static Vector<RefPtr<AccessibilityUIElement> > getTableRowHeaders(AtkTable* accessible)
{
    Vector<RefPtr<AccessibilityUIElement> > rowHeaders;

    int rowsCount = atk_table_get_n_rows(accessible);
    for (int row = 0; row < rowsCount; ++row) {
        if (AtkObject* header = atk_table_get_row_header(accessible, row))
            rowHeaders.append(AccessibilityUIElement::create(header));
    }

    return rowHeaders;
}

static Vector<RefPtr<AccessibilityUIElement> > getTableColumnHeaders(AtkTable* accessible)
{
    Vector<RefPtr<AccessibilityUIElement> > columnHeaders;

    int columnsCount = atk_table_get_n_columns(accessible);
    for (int column = 0; column < columnsCount; ++column) {
        if (AtkObject* header = atk_table_get_column_header(accessible, column))
            columnHeaders.append(AccessibilityUIElement::create(header));
    }

    return columnHeaders;
}

static Vector<RefPtr<AccessibilityUIElement> > getVisibleCells(AccessibilityUIElement* element)
{
    Vector<RefPtr<AccessibilityUIElement> > visibleCells;

    AtkTable* accessible = ATK_TABLE(element->platformUIElement().get());
    int rowsCount = atk_table_get_n_rows(accessible);
    int columnsCount = atk_table_get_n_columns(accessible);

    for (int row = 0; row < rowsCount; ++row) {
        for (int column = 0; column < columnsCount; ++column)
            visibleCells.append(element->cellForColumnAndRow(column, row));
    }

    return visibleCells;
}

static Vector<RefPtr<AccessibilityUIElement>> convertGPtrArrayToVector(const GPtrArray* array)
{
    Vector<RefPtr<AccessibilityUIElement>> cells;
    for (guint i = 0; i < array->len; i++) {
        if (AtkObject* atkObject = static_cast<AtkObject*>(g_ptr_array_index(array, i)))
            cells.append(AccessibilityUIElement::create(atkObject));
    }
    return cells;
}

static JSValueRef convertToJSObjectArray(const Vector<RefPtr<AccessibilityUIElement>>& children)
{
    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);

    size_t elementCount = children.size();
    auto valueElements = makeUniqueArray<JSValueRef>(elementCount);
    for (size_t i = 0; i < elementCount; i++)
        valueElements[i] = JSObjectMake(context, children[i]->wrapperClass(), children[i].get());

    return JSObjectMakeArray(context, elementCount, valueElements.get(), nullptr);
}

static double rangeMinMaxValue(AtkValue* atkValue, RangeLimit rangeLimit)
{
    AtkRange* range = atk_value_get_range(atkValue);
    if (!range)
        return 0;

    double rangeValue = 0;
    switch (rangeLimit) {
    case RangeLimitMinimum:
        rangeValue = atk_range_get_lower_limit(range);
        break;
    case RangeLimitMaximum:
        rangeValue = atk_range_get_upper_limit(range);
        break;
    };

    atk_range_free(range);
    return rangeValue;
}

} // namespace

AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
    : m_element(element)
{
}

AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
    : JSWrappable()
    , m_element(other.m_element)
{
}

AccessibilityUIElement::~AccessibilityUIElement()
{
}

bool AccessibilityUIElement::isEqual(AccessibilityUIElement* otherElement)
{
    return m_element == otherElement->platformUIElement();
}

void AccessibilityUIElement::getChildren(Vector<RefPtr<AccessibilityUIElement> >& children)
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return;

    int count = childrenCount();
    for (int i = 0; i < count; i++) {
        GRefPtr<AtkObject> child = adoptGRef(atk_object_ref_accessible_child(ATK_OBJECT(m_element.get()), i));
        children.append(AccessibilityUIElement::create(child.get()));
    }
}

void AccessibilityUIElement::getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >& children, unsigned location, unsigned length)
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return;
    unsigned end = location + length;
    for (unsigned i = location; i < end; i++) {
        GRefPtr<AtkObject> child = adoptGRef(atk_object_ref_accessible_child(ATK_OBJECT(m_element.get()), i));
        children.append(AccessibilityUIElement::create(child.get()));
    }
}

int AccessibilityUIElement::childrenCount()
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return 0;

    return atk_object_get_n_accessible_children(ATK_OBJECT(m_element.get()));
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y)
{
    if (!ATK_IS_COMPONENT(m_element.get()))
        return nullptr;

    GRefPtr<AtkObject> objectAtPoint = adoptGRef(atk_component_ref_accessible_at_point(ATK_COMPONENT(m_element.get()), x, y, ATK_XY_WINDOW));
    return AccessibilityUIElement::create(objectAtPoint ? objectAtPoint.get() : m_element.get());
}

unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return 0;

    Vector<RefPtr<AccessibilityUIElement> > children;
    getChildren(children);

    unsigned count = children.size();
    for (unsigned i = 0; i < count; i++)
        if (children[i]->isEqual(element))
            return i;

    return 0;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned index)
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return nullptr;

    Vector<RefPtr<AccessibilityUIElement> > children;
    getChildrenWithRange(children, index, 1);

    if (children.size() == 1)
        return children[0];

    return nullptr;
}

static RefPtr<AccessibilityUIElement> accessibilityElementAtIndex(AtkObject* element, AtkRelationType relationType, unsigned index)
{
    if (!ATK_IS_OBJECT(element))
        return nullptr;

    AtkRelationSet* relationSet = atk_object_ref_relation_set(element);
    if (!relationSet)
        return nullptr;

    AtkRelation* relation = atk_relation_set_get_relation_by_type(relationSet, relationType);
    if (!relation)
        return nullptr;

    GPtrArray* targetList = atk_relation_get_target(relation);
    if (!targetList || !targetList->len || index >= targetList->len)
        return nullptr;

    AtkObject* target = static_cast<AtkObject*>(g_ptr_array_index(targetList, index));
    g_object_unref(relationSet);

    return target ? AccessibilityUIElement::create(target).ptr() : nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_NODE_PARENT_OF, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsReferencingElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_NODE_CHILD_OF, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_FLOWS_TO, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToReferencingElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_FLOWS_FROM, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaControlsElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_CONTROLLER_FOR, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaControlsReferencingElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_CONTROLLED_BY, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaLabelledByElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_LABELLED_BY, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaLabelledByReferencingElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_LABEL_FOR, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaDescribedByElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_DESCRIBED_BY, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaDescribedByReferencingElementAtIndex(unsigned index)
{
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_DESCRIPTION_FOR, index);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaDetailsElementAtIndex(unsigned index)
{
#if ATK_CHECK_VERSION(2, 25, 2)
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_DETAILS, index);
#endif
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaDetailsReferencingElementAtIndex(unsigned index)
{
#if ATK_CHECK_VERSION(2, 25, 2)
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_DETAILS_FOR, index);
#endif
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaErrorMessageElementAtIndex(unsigned index)
{
#if ATK_CHECK_VERSION(2, 25, 2)
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_ERROR_MESSAGE, index);
#endif
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaErrorMessageReferencingElementAtIndex(unsigned index)
{
#if ATK_CHECK_VERSION(2, 25, 2)
    return accessibilityElementAtIndex(m_element.get(), ATK_RELATION_ERROR_FOR, index);
#endif
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned index)
{
    // ATK doesn't have API to get an accessible row by index directly. It does, however, have
    // API to get cells in the row specified by index. The parent of a cell should be the row.
    AtkTable* axTable = ATK_TABLE(m_element.get());
    unsigned nColumns = columnCount();
    for (unsigned col = 0; col < nColumns; col++) {
        // Find the first cell in this row that only spans one row.
        if (atk_table_get_row_extent_at(axTable, index, col) == 1) {
            AtkObject* cell = atk_table_ref_at(axTable, index, col);
            return cell ? AccessibilityUIElement::create(atk_object_get_parent(cell)).ptr() : nullptr;
        }
    }

    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned index) const
{
    if (!ATK_SELECTION(m_element.get()))
        return nullptr;

    GRefPtr<AtkObject> child = adoptGRef(atk_selection_ref_selection(ATK_SELECTION(m_element.get()), index));
    return child ? AccessibilityUIElement::create(child.get()).ptr() : nullptr;
}

unsigned AccessibilityUIElement::selectedChildrenCount() const
{
    if (!ATK_IS_SELECTION(m_element.get()))
        return 0;
    return atk_selection_get_selection_count(ATK_SELECTION(m_element.get()));
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned index)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return nullptr;

    AtkRelationSet* set = atk_object_ref_relation_set(ATK_OBJECT(m_element.get()));
    if (!set)
        return nullptr;

    AtkObject* target = nullptr;
    int count = atk_relation_set_get_n_relations(set);
    for (int i = 0; i < count; i++) {
        AtkRelation* relation = atk_relation_set_get_relation(set, i);
        if (atk_relation_get_relation_type(relation) == ATK_RELATION_LABELLED_BY) {
            GPtrArray* targetList = atk_relation_get_target(relation);
            if (targetList->len)
                target = static_cast<AtkObject*>(g_ptr_array_index(targetList, 0));
        }
    }

    g_object_unref(set);
    return target ? AccessibilityUIElement::create(target).ptr() : nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return nullptr;

    AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element.get()));
    return parent ? AccessibilityUIElement::create(parent).ptr() : nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
{
    // FIXME: implement
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements()
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks()
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren()
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    Vector<RefPtr<AccessibilityUIElement> > children;
    getChildren(children);

    return createStringWithAttributes(children);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes()
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    return JSStringCreateWithUTF8CString(attributesOfElement(this).utf8().data());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringDescriptionOfAttributeValue(JSStringRef attribute)
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    String atkAttributeName = coreAttributeToAtkAttribute(attribute);

    // The value of AXSelectedText is not exposed through any AtkAttribute.
    if (atkAttributeName == "AXSelectedText") {
        String string = selectedText(m_element.get());
        return JSStringCreateWithUTF8CString(string.utf8().data());
    }

    // Try object attributes before text attributes.
    String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName);

    // Try text attributes if the requested one was not found and we have an AtkText object.
    if (attributeValue.isEmpty() && ATK_IS_TEXT(m_element.get()))
        attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), TextAttributeType, atkAttributeName);

    // Additional check to make sure that the exposure of the state ATK_STATE_INVALID_ENTRY
    // is consistent with the exposure of aria-invalid as a text attribute, if present.
    if (atkAttributeName == attributesMap()[InvalidNameIndex].atkDomain) {
        bool isInvalidState = checkElementState(m_element.get(), ATK_STATE_INVALID_ENTRY);
        if (attributeValue.isEmpty())
            return JSStringCreateWithUTF8CString(isInvalidState ? "true" : "false");

        // If the text attribute was there, check that it's consistent with
        // what the state says or force the test to fail otherwise.
        bool isAriaInvalid = attributeValue != "false";
        if (isInvalidState != isAriaInvalid)
            return JSStringCreateWithCharacters(0, 0);
    }

    return JSStringCreateWithUTF8CString(attributeValue.utf8().data());
}

double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return 0;

    String atkAttributeName = coreAttributeToAtkAttribute(attribute);
    if (atkAttributeName.isEmpty())
        return 0;

    if (atkAttributeName == "setsize" || atkAttributeName == "posinset") {
        String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName);
        if (!attributeValue.isEmpty())
            return attributeValue.toDouble();
    }

    if (atkAttributeName.startsWith("row") || atkAttributeName.startsWith("col")) {
        String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName);
        if (!attributeValue.isEmpty())
            return attributeValue.toInt();
    }

    return 0;
}

JSValueRef AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef attribute) const
{
    // FIXME: implement
    return nullptr;
}

JSValueRef AccessibilityUIElement::rowHeaders() const
{
    if (ATK_IS_TABLE(m_element.get()))
        return convertToJSObjectArray(getTableRowHeaders(ATK_TABLE(m_element.get())));

    Vector<RefPtr<AccessibilityUIElement>> headers;
    if (!ATK_IS_TABLE_CELL(m_element.get()))
        return convertToJSObjectArray(headers);

    if (GRefPtr<GPtrArray> array = adoptGRef(atk_table_cell_get_row_header_cells(ATK_TABLE_CELL(m_element.get()))))
        headers = convertGPtrArrayToVector(array.get());
    return convertToJSObjectArray(headers);
}

JSValueRef AccessibilityUIElement::columnHeaders() const
{
    if (ATK_IS_TABLE(m_element.get()))
        return convertToJSObjectArray(getTableColumnHeaders(ATK_TABLE(m_element.get())));

    Vector<RefPtr<AccessibilityUIElement>> headers;
    if (!ATK_IS_TABLE_CELL(m_element.get()))
        return convertToJSObjectArray(headers);

    if (GRefPtr<GPtrArray> array = adoptGRef(atk_table_cell_get_column_header_cells(ATK_TABLE_CELL(m_element.get()))))
        headers = convertGPtrArrayToVector(array.get());
    return convertToJSObjectArray(headers);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return nullptr;

    // ATK does not have this API. So we're "faking it" here on a case-by-case basis.
    String attributeString = jsStringToWTFString(attribute);
    AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
    if (role == ATK_ROLE_SPIN_BUTTON && const_cast<AccessibilityUIElement*>(this)->childrenCount() == 2) {
        if (attributeString == "AXDecrementButton")
            return const_cast<AccessibilityUIElement*>(this)->childAtIndex(0);
        if (attributeString == "AXIncrementButton")
            return const_cast<AccessibilityUIElement*>(this)->childAtIndex(1);
    }

    return nullptr;
}

bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return false;

    String attributeString = jsStringToWTFString(attribute);
    if (attributeString == "AXElementBusy")
        return checkElementState(m_element.get(), ATK_STATE_BUSY);
    if (attributeString == "AXChecked")
        return checkElementState(m_element.get(), ATK_STATE_CHECKED);
    if (attributeString == "AXEnabled")
        return checkElementState(m_element.get(), ATK_STATE_ENABLED);
    if (attributeString == "AXExpanded")
        return checkElementState(m_element.get(), ATK_STATE_EXPANDED);
    if (attributeString == "AXFocused")
        return checkElementState(m_element.get(), ATK_STATE_FOCUSED);
    if (attributeString == "AXInvalid")
        return checkElementState(m_element.get(), ATK_STATE_INVALID);
    if (attributeString == "AXModal")
        return checkElementState(m_element.get(), ATK_STATE_MODAL);
    if (attributeString == "AXMultiSelectable")
        return checkElementState(m_element.get(), ATK_STATE_MULTISELECTABLE);
    if (attributeString == "AXRequired")
        return checkElementState(m_element.get(), ATK_STATE_REQUIRED);
    if (attributeString == "AXSelected")
        return checkElementState(m_element.get(), ATK_STATE_SELECTED);
    if (attributeString == "AXSupportsAutoCompletion")
        return checkElementState(m_element.get(), ATK_STATE_SUPPORTS_AUTOCOMPLETION);
    if (attributeString == "AXVisited")
        return checkElementState(m_element.get(), ATK_STATE_VISITED);

    if (attributeString == "AXInterfaceTable")
        return ATK_IS_TABLE(m_element.get());
    if (attributeString == "AXInterfaceTableCell")
        return ATK_IS_TABLE_CELL(m_element.get());

    if (attributeString == "AXARIAAtomic") {
        String atkAttribute = coreAttributeToAtkAttribute(attribute);
        return getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttribute) == "true";
    }

    return false;
}

bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return false;

    String attributeString = jsStringToWTFString(attribute);
    if (attributeString != "AXValue")
        return false;

    // ATK does not have a single state or property to indicate whether or not the value
    // of an accessible object can be set. ATs look at several states and properties based
    // on the type of object. If nothing explicitly indicates the value can or cannot be
    // set, ATs make role- and interface-based decisions. We'll do something similar here.

    // This state is expected to be present only for text widgets and contenteditable elements.
    if (checkElementState(m_element.get(), ATK_STATE_EDITABLE))
        return true;

    // This state is applicable to checkboxes, radiobuttons, switches, etc.
    if (checkElementState(m_element.get(), ATK_STATE_CHECKABLE))
        return true;

    // This state is expected to be present only for controls and only if explicitly set.
    if (checkElementState(m_element.get(), ATK_STATE_READ_ONLY))
        return false;

    // We expose an object attribute to ATs when there is an author-provided ARIA property
    // and also when there is a supported ARIA role but no author-provided value.
    String isReadOnly = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "readonly");
    if (!isReadOnly.isEmpty())
        return isReadOnly == "true" ? false : true;

    // If we have a native listbox or combobox and the value can be set, the options should
    // have ATK_STATE_SELECTABLE.
    AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
    if (role == ATK_ROLE_LIST_BOX || role == ATK_ROLE_COMBO_BOX) {
        if (GRefPtr<AtkObject> child = adoptGRef(atk_object_ref_accessible_child(ATK_OBJECT(m_element.get()), 0))) {
            if (atk_object_get_role(ATK_OBJECT(child.get())) == ATK_ROLE_MENU)
                child = adoptGRef(atk_object_ref_accessible_child(ATK_OBJECT(child.get()), 0));
            return child && checkElementState(child.get(), ATK_STATE_SELECTABLE);
        }
    }

    // If we have a native element which exposes a range whose value can be set, it should
    // be focusable and have a true range.
    if (ATK_IS_VALUE(m_element.get()) && checkElementState(m_element.get(), ATK_STATE_FOCUSABLE))
        return minValue() != maxValue();

    return false;
}

bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return false;

    String atkAttributeName = coreAttributeToAtkAttribute(attribute);
    if (atkAttributeName.isEmpty())
        return false;

    // In ATK, "busy" is a state and is supported on all AtkObject instances.
    if (atkAttributeName == "busy")
        return true;

    // For now, an attribute is supported whether it's exposed as a object or a text attribute.
    String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName);
    if (attributeValue.isEmpty())
        attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), TextAttributeType, atkAttributeName);

    // When the aria-live value is "off", we expose that value via the "live" object attribute.
    if (atkAttributeName == "live" && attributeValue == "off")
        return false;

    return !attributeValue.isEmpty();
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames()
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::role()
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    GUniquePtr<char> roleStringWithPrefix(g_strdup_printf("AXRole: %s", roleToString(ATK_OBJECT(m_element.get()))));
    return JSStringCreateWithUTF8CString(roleStringWithPrefix.get());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole()
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription()
{
    String roleDescription = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "roledescription");
    GUniquePtr<gchar> axRoleDescription(g_strdup_printf("AXRoleDescription: %s", roleDescription.utf8().data()));

    return JSStringCreateWithUTF8CString(axRoleDescription.get());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::computedRoleString()
{
    String role = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "computed-role");
    if (!role.isEmpty())
        return JSStringCreateWithUTF8CString(role.utf8().data());

    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::title()
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    const gchar* name = atk_object_get_name(ATK_OBJECT(m_element.get()));
    GUniquePtr<gchar> axTitle(g_strdup_printf("AXTitle: %s", name ? name : ""));

    return JSStringCreateWithUTF8CString(axTitle.get());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::description()
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    const gchar* description = atk_object_get_description(ATK_OBJECT(m_element.get()));
    if (!description)
        return JSStringCreateWithCharacters(0, 0);

    GUniquePtr<gchar> axDesc(g_strdup_printf("AXDescription: %s", description));

    return JSStringCreateWithUTF8CString(axDesc.get());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    const gchar* axOrientation = nullptr;
    if (checkElementState(m_element.get(), ATK_STATE_HORIZONTAL))
        axOrientation = "AXOrientation: AXHorizontalOrientation";
    else if (checkElementState(m_element.get(), ATK_STATE_VERTICAL))
        axOrientation = "AXOrientation: AXVerticalOrientation";
    else
        axOrientation = "AXOrientation: AXUnknownOrientation";

    return JSStringCreateWithUTF8CString(axOrientation);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue()
{
    if (!ATK_IS_TEXT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    GUniquePtr<gchar> text(atk_text_get_text(ATK_TEXT(m_element.get()), 0, -1));
    GUniquePtr<gchar> textWithReplacedCharacters(replaceCharactersForResults(text.get()));
    GUniquePtr<gchar> axValue(g_strdup_printf("AXValue: %s", textWithReplacedCharacters.get()));

    return JSStringCreateWithUTF8CString(axValue.get());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::language()
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    const gchar* locale = atk_object_get_object_locale(ATK_OBJECT(m_element.get()));
    if (!locale)
        return JSStringCreateWithCharacters(0, 0);

    GUniquePtr<char> axValue(g_strdup_printf("AXLanguage: %s", locale));
    return JSStringCreateWithUTF8CString(axValue.get());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    AtkRelationSet* relationSet = atk_object_ref_relation_set(ATK_OBJECT(m_element.get()));
    if (!relationSet)
        return JSStringCreateWithCharacters(0, 0);

    AtkRelation* relation = atk_relation_set_get_relation_by_type(relationSet, ATK_RELATION_DESCRIBED_BY);
    if (!relation)
        return JSStringCreateWithCharacters(0, 0);

    GPtrArray* targetList = atk_relation_get_target(relation);
    if (!targetList || !targetList->len)
        return JSStringCreateWithCharacters(0, 0);

    StringBuilder builder;
    builder.appendLiteral("AXHelp: ");

    for (guint targetCount = 0; targetCount < targetList->len; targetCount++) {
        if (AtkObject* target = static_cast<AtkObject*>(g_ptr_array_index(targetList, targetCount))) {
            GUniquePtr<gchar> text(atk_text_get_text(ATK_TEXT(target), 0, -1));
            if (targetCount)
                builder.append(' ');
            builder.append(text.get());
        }
    }

    g_object_unref(relationSet);

    return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
}

double AccessibilityUIElement::x()
{
    if (!ATK_IS_COMPONENT(m_element.get()))
        return 0;

    int x;
    atk_component_get_extents(ATK_COMPONENT(m_element.get()), &x, nullptr, nullptr, nullptr, ATK_XY_SCREEN);
    return x;
}

double AccessibilityUIElement::y()
{
    if (!ATK_IS_COMPONENT(m_element.get()))
        return 0;

    int y;
    atk_component_get_extents(ATK_COMPONENT(m_element.get()), nullptr, &y, nullptr, nullptr, ATK_XY_SCREEN);
    return y;
}

double AccessibilityUIElement::width()
{
    if (!ATK_IS_COMPONENT(m_element.get()))
        return 0;

    int width;
    atk_component_get_extents(ATK_COMPONENT(m_element.get()), nullptr, nullptr, &width, nullptr, ATK_XY_WINDOW);
    return width;
}

double AccessibilityUIElement::height()
{
    if (!ATK_IS_COMPONENT(m_element.get()))
        return 0;

    int height;
    atk_component_get_extents(ATK_COMPONENT(m_element.get()), nullptr, nullptr, nullptr, &height, ATK_XY_WINDOW);
    return height;
}

double AccessibilityUIElement::clickPointX()
{
    if (!ATK_IS_COMPONENT(m_element.get()))
        return 0;

    int x, width;
    atk_component_get_extents(ATK_COMPONENT(m_element.get()), &x, nullptr, &width, nullptr, ATK_XY_WINDOW);
    return x + width / 2.0;
}

double AccessibilityUIElement::clickPointY()
{
    if (!ATK_IS_COMPONENT(m_element.get()))
        return 0;

    int y, height;
    atk_component_get_extents(ATK_COMPONENT(m_element.get()), nullptr, &y, nullptr, &height, ATK_XY_WINDOW);
    return y + height / 2.0;
}

double AccessibilityUIElement::intValue() const
{
    if (!ATK_IS_OBJECT(m_element.get()))
        return 0;

    if (ATK_IS_VALUE(m_element.get())) {
        double value;
        atk_value_get_value_and_text(ATK_VALUE(m_element.get()), &value, nullptr);
        return value;
    }

    // Consider headings as an special case when returning the "int value" of
    // an AccessibilityUIElement, so we can reuse some tests to check the level
    // both for HTML headings and objects with the aria-level attribute.
    if (atk_object_get_role(ATK_OBJECT(m_element.get())) == ATK_ROLE_HEADING) {
        String headingLevel = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "level");
        bool ok;
        double headingLevelValue = headingLevel.toDouble(&ok);
        if (ok)
            return headingLevelValue;
    }

    return 0;
}

double AccessibilityUIElement::minValue()
{
    if (!ATK_IS_VALUE(m_element.get()))
        return 0;

    return rangeMinMaxValue(ATK_VALUE(m_element.get()), RangeLimitMinimum);
}

double AccessibilityUIElement::maxValue()
{
    if (!ATK_IS_VALUE(m_element.get()))
        return 0;

    return rangeMinMaxValue(ATK_VALUE(m_element.get()), RangeLimitMaximum);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription()
{
    String valueText = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "valuetext");
    GUniquePtr<gchar> valueDescription(g_strdup_printf("AXValueDescription: %s", valueText.utf8().data()));
    return JSStringCreateWithUTF8CString(valueDescription.get());
}

int AccessibilityUIElement::insertionPointLineNumber()
{
    // FIXME: implement
    return -1;
}

bool AccessibilityUIElement::isPressActionSupported()
{
    if (!ATK_IS_ACTION(m_element.get()))
        return false;

    const gchar* actionName = atk_action_get_name(ATK_ACTION(m_element.get()), 0);
    return equalLettersIgnoringASCIICase(String(actionName), "press") || equalLettersIgnoringASCIICase(String(actionName), "jump");
}

bool AccessibilityUIElement::isIncrementActionSupported()
{
    // FIXME: implement
    return false;
}

bool AccessibilityUIElement::isDecrementActionSupported()
{
    // FIXME: implement
    return false;
}

bool AccessibilityUIElement::isEnabled()
{
    return checkElementState(m_element.get(), ATK_STATE_ENABLED);
}

bool AccessibilityUIElement::isRequired() const
{
    return checkElementState(m_element.get(), ATK_STATE_REQUIRED);
}

bool AccessibilityUIElement::isFocused() const
{
    return checkElementState(m_element.get(), ATK_STATE_FOCUSED);
}

bool AccessibilityUIElement::isSelected() const
{
    return checkElementState(m_element.get(), ATK_STATE_SELECTED);
}

bool AccessibilityUIElement::isSelectedOptionActive() const
{
    return checkElementState(m_element.get(), ATK_STATE_ACTIVE);
}

bool AccessibilityUIElement::isExpanded() const
{
    return checkElementState(m_element.get(), ATK_STATE_EXPANDED);
}

bool AccessibilityUIElement::isChecked() const
{
    return checkElementState(m_element.get(), ATK_STATE_CHECKED);
}

bool AccessibilityUIElement::isIndeterminate() const
{
    return checkElementState(m_element.get(), ATK_STATE_INDETERMINATE);
}

int AccessibilityUIElement::hierarchicalLevel() const
{
    String level = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "level");
    if (!level.isEmpty())
        return level.toInt();

    return 0;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::speakAs()
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

bool AccessibilityUIElement::ariaIsGrabbed() const
{
    return getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "grabbed") == "true";
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const
{
    String dropEffects = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "dropeffect");
    return dropEffects.isEmpty() ? JSStringCreateWithCharacters(0, 0) : JSStringCreateWithUTF8CString(dropEffects.utf8().data());
}

// parameterized attributes
int AccessibilityUIElement::lineForIndex(int index)
{
    if (!ATK_IS_TEXT(m_element.get()))
        return -1;

    if (index < 0 || index > atk_text_get_character_count(ATK_TEXT(m_element.get())))
        return -1;

    GUniquePtr<gchar> text(atk_text_get_text(ATK_TEXT(m_element.get()), 0, index));
    int lineNo = 0;
    for (gchar* offset = text.get(); *offset; ++offset) {
        if (*offset == '\n')
            ++lineNo;
    }

    return lineNo;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int line)
{
    if (!ATK_IS_TEXT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    AtkText* text = ATK_TEXT(m_element.get());
    gint startOffset = 0, endOffset = 0;
    for (int i = 0; i <= line; ++i)
        atk_text_get_string_at_offset(text, endOffset, ATK_TEXT_GRANULARITY_LINE, &startOffset, &endOffset);

    GUniquePtr<gchar> range(g_strdup_printf("{%d, %d}", startOffset, endOffset - startOffset));
    return JSStringCreateWithUTF8CString(range.get());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int x, int y)
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
{
    if (!ATK_IS_TEXT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    AtkTextRectangle rect;
    atk_text_get_range_extents(ATK_TEXT(m_element.get()), location, location + length, ATK_XY_WINDOW, &rect);

    GUniquePtr<gchar> bounds(g_strdup_printf("{%d, %d, %d, %d}", rect.x, rect.y, rect.width, rect.height));
    return JSStringCreateWithUTF8CString(bounds.get());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
{
    if (!ATK_IS_TEXT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    String string = atk_text_get_text(ATK_TEXT(m_element.get()), location, location + length);
    return JSStringCreateWithUTF8CString(string.utf8().data());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length)
{
    if (!ATK_IS_TEXT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    StringBuilder builder;

    // The default text attributes apply to the entire element.
    builder.appendLiteral("\n\tDefault text attributes:\n\t\t");
    builder.append(attributeSetToString(getAttributeSet(m_element.get(), TextAttributeType), "\n\t\t"));

    // The attribute run provides attributes specific to the range of text at the specified offset.
    AtkText* text = ATK_TEXT(m_element.get());
    gint start = 0, end = 0;
    for (unsigned i = location; i < location + length; i = end) {
        AtkAttributeSet* attributeSet = atk_text_get_run_attributes(text, i, &start, &end);
        GUniquePtr<gchar> substring(replaceCharactersForResults(atk_text_get_text(text, start, end)));
        builder.appendLiteral("\n\tRange attributes for '");
        builder.append(substring.get());
        builder.appendLiteral("':\n\t\t");
        builder.append(attributeSetToString(attributeSet, "\n\t\t"));
    }

    return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
}

bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
{
    // FIXME: implement
    return false;
}

unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
{
    // FIXME: implement
    return 0;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
{
    // FIXME: implement
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::selectTextWithCriteria(JSContextRef context, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity)
{
    // FIXME: implement
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
{
    if (!ATK_IS_TABLE(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    Vector<RefPtr<AccessibilityUIElement> > columnHeaders = getTableColumnHeaders(ATK_TABLE(m_element.get()));
    return createStringWithAttributes(columnHeaders);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders()
{
    if (!ATK_IS_TABLE(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    Vector<RefPtr<AccessibilityUIElement> > rowHeaders = getTableRowHeaders(ATK_TABLE(m_element.get()));
    return createStringWithAttributes(rowHeaders);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns()
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows()
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells()
{
    if (!ATK_IS_TABLE(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    Vector<RefPtr<AccessibilityUIElement> > visibleCells = getVisibleCells(this);
    return createStringWithAttributes(visibleCells);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader()
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

int AccessibilityUIElement::rowCount()
{
    if (!ATK_IS_TABLE(m_element.get()))
        return 0;

    return atk_table_get_n_rows(ATK_TABLE(m_element.get()));
}

int AccessibilityUIElement::columnCount()
{
    if (!ATK_IS_TABLE(m_element.get()))
        return 0;

    return atk_table_get_n_columns(ATK_TABLE(m_element.get()));
}

int AccessibilityUIElement::indexInTable()
{
    // FIXME: implement
    return -1;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange()
{
    // Range in table for rows.
    return indexRangeInTable(m_element.get(), true);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange()
{
    // Range in table for columns.
    return indexRangeInTable(m_element.get(), false);
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
{
    if (!ATK_IS_TABLE(m_element.get()))
        return nullptr;

    // Adopt the AtkObject representing the cell because
    // at_table_ref_at() transfers full ownership.
    GRefPtr<AtkObject> foundCell = adoptGRef(atk_table_ref_at(ATK_TABLE(m_element.get()), row, col));
    return foundCell ? AccessibilityUIElement::create(foundCell.get()).ptr() : nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
{
    // FIXME: implement
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange()
{
    if (!ATK_IS_TEXT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    gint start, end;
    g_free(atk_text_get_selection(ATK_TEXT(m_element.get()), 0, &start, &end));

    GUniquePtr<gchar> selection(g_strdup_printf("{%d, %d}", start, end - start));
    return JSStringCreateWithUTF8CString(selection.get());
}

bool AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
{
    if (!ATK_IS_TEXT(m_element.get()))
        return false;

    if (!length)
        return atk_text_set_caret_offset(ATK_TEXT(m_element.get()), location);

    return atk_text_set_selection(ATK_TEXT(m_element.get()), 0, location, location + length);
}

void AccessibilityUIElement::increment()
{
    alterCurrentValue(m_element.get(), 1);
}

void AccessibilityUIElement::decrement()
{
    alterCurrentValue(m_element.get(), -1);
}

void AccessibilityUIElement::showMenu()
{
    // FIXME: implement
}

void AccessibilityUIElement::press()
{
    if (!ATK_IS_ACTION(m_element.get()))
        return;

    // Only one action per object is supported so far.
    atk_action_do_action(ATK_ACTION(m_element.get()), 0);
}

void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
{
    // FIXME: implement
}

void AccessibilityUIElement::setSelectedChildAtIndex(unsigned index) const
{
    if (!ATK_IS_SELECTION(m_element.get()))
        return;

    atk_selection_add_selection(ATK_SELECTION(m_element.get()), index);
}

void AccessibilityUIElement::removeSelectionAtIndex(unsigned index) const
{
    if (!ATK_IS_SELECTION(m_element.get()))
        return;

    atk_selection_remove_selection(ATK_SELECTION(m_element.get()), index);
}

void AccessibilityUIElement::clearSelectedChildren() const
{
    if (!ATK_IS_SELECTION(m_element.get()))
        return;

    atk_selection_clear_selection(ATK_SELECTION(m_element.get()));
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding()
{
    if (!ATK_IS_DOCUMENT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
    if (role != ATK_ROLE_DOCUMENT_WEB)
        return JSStringCreateWithCharacters(0, 0);

    return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element.get()), "Encoding"));
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI()
{
    if (!ATK_IS_DOCUMENT(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
    if (role != ATK_ROLE_DOCUMENT_WEB)
        return JSStringCreateWithCharacters(0, 0);

    return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element.get()), "URI"));
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::url()
{
    if (!ATK_IS_HYPERLINK_IMPL(m_element.get()))
        return JSStringCreateWithCharacters(0, 0);

    AtkHyperlink* hyperlink = atk_hyperlink_impl_get_hyperlink(ATK_HYPERLINK_IMPL(m_element.get()));
    GUniquePtr<char> hyperlinkURI(atk_hyperlink_get_uri(hyperlink, 0));

    if (!hyperlinkURI.get())
        return JSStringCreateWithUTF8CString("AXURL: (null)");

    // Build the result string, stripping the absolute URL paths if present.
    char* localURI = g_strstr_len(hyperlinkURI.get(), -1, "LayoutTests");
    String axURL = makeString("AXURL: ", localURI ? localURI : hyperlinkURI.get());
    return JSStringCreateWithUTF8CString(axURL.utf8().data());
}

bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
{
    if (!functionCallback)
        return false;

    // Only one notification listener per element.
    if (m_notificationHandler)
        return false;

    m_notificationHandler = AccessibilityNotificationHandler::create();
    m_notificationHandler->setPlatformElement(platformUIElement());
    m_notificationHandler->setNotificationFunctionCallback(functionCallback);

    return true;
}

bool AccessibilityUIElement::removeNotificationListener()
{
    // Programmers should not be trying to remove a listener that's already removed.
    ASSERT(m_notificationHandler);
    m_notificationHandler = nullptr;

    return true;
}

bool AccessibilityUIElement::isFocusable() const
{
    return checkElementState(m_element.get(), ATK_STATE_FOCUSABLE);
}

bool AccessibilityUIElement::isSelectable() const
{
    return checkElementState(m_element.get(), ATK_STATE_SELECTABLE);
}

bool AccessibilityUIElement::isMultiSelectable() const
{
    return checkElementState(m_element.get(), ATK_STATE_MULTISELECTABLE);
}

bool AccessibilityUIElement::isVisible() const
{
    return checkElementState(m_element.get(), ATK_STATE_VISIBLE);
}

bool AccessibilityUIElement::isOffScreen() const
{
    // FIXME: implement
    return false;
}

bool AccessibilityUIElement::isCollapsed() const
{
    // FIXME: implement
    return false;
}

bool AccessibilityUIElement::isIgnored() const
{
    // FIXME: implement
    return false;
}

bool AccessibilityUIElement::isSingleLine() const
{
    return checkElementState(m_element.get(), ATK_STATE_SINGLE_LINE);
}

bool AccessibilityUIElement::isMultiLine() const
{
    return checkElementState(m_element.get(), ATK_STATE_MULTI_LINE);
}

bool AccessibilityUIElement::hasPopup() const
{
    return checkElementState(m_element.get(), ATK_STATE_HAS_POPUP);
}

void AccessibilityUIElement::takeFocus()
{
    // FIXME: implement
}

void AccessibilityUIElement::takeSelection()
{
    // FIXME: implement
}

void AccessibilityUIElement::addSelection()
{
    // FIXME: implement
}

void AccessibilityUIElement::removeSelection()
{
    // FIXME: implement
}

// Text markers
RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::lineTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
{
    // FIXME: implement
    return nullptr;
}

int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range)
{
    // FIXME: implement
    return 0;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker* textMarker)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker* textMarker)
{
    // FIXME: implement
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange* markerRange)
{
    // FIXME: implement
    return JSStringCreateWithCharacters(0, 0);
}

RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForBounds(int x, int y, int width, int height)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForBounds(int x, int y, int width, int height)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y)
{
    // FIXME: implement
    return nullptr;
}

RefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
{
    // FIXME: implement
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRange(AccessibilityTextMarkerRange*)
{
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRangeWithOptions(AccessibilityTextMarkerRange*, bool)
{
    return nullptr;
}

bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef attribute, AccessibilityTextMarkerRange* range)
{
    // FIXME: implement
    return false;
}

int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker* marker)
{
    // FIXME: implement
    return -1;
}

bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker* textMarker)
{
    // FIXME: implement
    return false;
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int textIndex)
{
    // FIXME: implement
    return nullptr;
}
    
RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarker()
{
    // FIXME: implement
    return nullptr;    
}

RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarker()
{
    // FIXME: implement
    return nullptr;
}

bool AccessibilityUIElement::setSelectedVisibleTextRange(AccessibilityTextMarkerRange*)
{
    return false;
}

void AccessibilityUIElement::scrollToMakeVisible()
{
#if ATK_CHECK_VERSION(2, 30, 0)
    if (!ATK_IS_COMPONENT(m_element.get()))
        return;

    atk_component_scroll_to(ATK_COMPONENT(m_element.get()), ATK_SCROLL_ANYWHERE);
#endif
}

void AccessibilityUIElement::scrollToGlobalPoint(int x, int y)
{
#if ATK_CHECK_VERSION(2, 30, 0)
    if (!ATK_IS_COMPONENT(m_element.get()))
        return;

    atk_component_scroll_to_point(ATK_COMPONENT(m_element.get()), ATK_XY_WINDOW, x, y);
#endif
}

void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height)
{
    // FIXME: implement
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const
{
    // FIXME: implement
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const
{
    notImplemented();
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPostscriptsDescription() const
{
    notImplemented();
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPrescriptsDescription() const
{
    notImplemented();
    return nullptr;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::classList() const
{
    notImplemented();
    return nullptr;
}

JSRetainPtr<JSStringRef> stringAtOffset(PlatformUIElement element, AtkTextBoundary boundary, int offset)
{
    if (!ATK_IS_TEXT(element.get()))
        return JSStringCreateWithCharacters(0, 0);

    gint startOffset, endOffset;
    StringBuilder builder;

    AtkTextGranularity granularity;
    switch (boundary) {
    case ATK_TEXT_BOUNDARY_CHAR:
        granularity = ATK_TEXT_GRANULARITY_CHAR;
        break;
    case ATK_TEXT_BOUNDARY_WORD_START:
        granularity = ATK_TEXT_GRANULARITY_WORD;
        break;
    case ATK_TEXT_BOUNDARY_LINE_START:
        granularity = ATK_TEXT_GRANULARITY_LINE;
        break;
    case ATK_TEXT_BOUNDARY_SENTENCE_START:
        granularity = ATK_TEXT_GRANULARITY_SENTENCE;
        break;
    default:
        return JSStringCreateWithCharacters(0, 0);
    }

    builder.append(atk_text_get_string_at_offset(ATK_TEXT(element.get()), offset, granularity, &startOffset, &endOffset));

    builder.appendLiteral(", ");
    builder.appendNumber(startOffset);
    builder.appendLiteral(", ");
    builder.appendNumber(endOffset);
    return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::characterAtOffset(int offset)
{
    return stringAtOffset(m_element, ATK_TEXT_BOUNDARY_CHAR, offset);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::wordAtOffset(int offset)
{
    return stringAtOffset(m_element, ATK_TEXT_BOUNDARY_WORD_START, offset);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::lineAtOffset(int offset)
{
    return stringAtOffset(m_element, ATK_TEXT_BOUNDARY_LINE_START, offset);
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::sentenceAtOffset(int offset)
{
    return stringAtOffset(m_element, ATK_TEXT_BOUNDARY_SENTENCE_START, offset);
}

bool AccessibilityUIElement::replaceTextInRange(JSStringRef, int, int)
{
    notImplemented();
    return false;
}

bool AccessibilityUIElement::insertText(JSStringRef)
{
    notImplemented();
    return false;
}

JSRetainPtr<JSStringRef> AccessibilityUIElement::popupValue() const
{
    notImplemented();
    return nullptr;
}

} // namespace WTR

#endif // HAVE(ACCESSIBILITY)
