/*
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
 * Copyright (C) 2009 Google Inc.  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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
 */

// http://w3c.github.io/selection-api/#idl-def-Selection

// TODO(yoichio): All long types should be unsigned long. crbug.com/391673
[
    ImplementedAs=DOMSelection,
] interface Selection {
    [MeasureAs=SelectionAnchorNode] readonly attribute Node? anchorNode;
    [MeasureAs=SelectionAnchorOffset] readonly attribute long anchorOffset;
    [MeasureAs=SelectionFocusNode] readonly attribute Node? focusNode;
    [MeasureAs=SelectionFocusOffset] readonly attribute long focusOffset;
    [MeasureAs=SelectionIsCollapsed] readonly attribute boolean isCollapsed;
    [MeasureAs=SelectionRangeCount] readonly attribute long rangeCount;
    [MeasureAs=SelectionType] readonly attribute DOMString type;
    [MeasureAs=SelectionGetRangeAt, RaisesException] Range getRangeAt(long index);
    [MeasureAs=SelectionAddRange] void addRange(Range range);
    // TODO(yoichio): Implement removeRange. crbug.com/391673
    //void removeRange(Range range);
    [MeasureAs=SelectionRemoveAllRanges] void removeAllRanges();
    [MeasureAs=SelectionEmpty] void empty();
    [MeasureAs=SelectionCollapse, RaisesException] void collapse(Node? node, optional long offset = 0);
    [ImplementedAs=collapse, MeasureAs=SelectionSetPosition, RaisesException] void setPosition(Node? node, optional long offset = 0);
    [MeasureAs=SelectionCollapseToStart, RaisesException] void collapseToStart();
    [MeasureAs=SelectionCollapseToEnd, RaisesException] void collapseToEnd();
    [MeasureAs=SelectionExtend, RaisesException] void extend(Node node, optional long offset = 0);
    // TODO(foolip): The arguments should be anchorNode, anchorOffset,
    // focusNode and focusOffset, and none of them are nullable in the spec.
    [MeasureAs=SelectionSetBaseAndExtent, RaisesException] void setBaseAndExtent(Node? baseNode, long baseOffset,
                                                                                 Node? extentNode, long extentOffset);
    [MeasureAs=SelectionSelectAllChildren, RaisesException] void selectAllChildren(Node node);
    [MeasureAs=SelectionDeleteDromDocument, CEReactions, CustomElementCallbacks] void deleteFromDocument();
    [MeasureAs=SelectionContainsNode] boolean containsNode(Node node, optional boolean allowPartialContainment = false);
    [MeasureAs=SelectionDOMString] stringifier;

    // Non-standard APIs

    // https://github.com/w3c/selection-api/issues/34
    [MeasureAs=SelectionBaseNode] readonly attribute Node? baseNode;
    [MeasureAs=SelectionBaseOffset] readonly attribute long baseOffset;
    [MeasureAs=SelectionExtentNode] readonly attribute Node? extentNode;
    [MeasureAs=SelectionExtentOffset] readonly attribute long extentOffset;

    // https://github.com/w3c/selection-api/issues/37
    [MeasureAs=SelectionModify] void modify([Default=Undefined] optional DOMString alter,
                                            [Default=Undefined] optional DOMString direction,
                                            [Default=Undefined] optional DOMString granularity);
};
