/*
 * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
 * Copyright (C) 2004, 2005, 2010 Rob Buis <buis@kde.org>
 * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
 * Copyright (C) 2006-2019 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

[
    JSGenerateToNativeObject,
    ExportMacro=WEBCORE_EXPORT,
    Exposed=Window
] interface SVGSVGElement : SVGGraphicsElement {
    [SameObject] readonly attribute SVGAnimatedLength x;
    [SameObject] readonly attribute SVGAnimatedLength y;
    [SameObject] readonly attribute SVGAnimatedLength width;
    [SameObject] readonly attribute SVGAnimatedLength height;

    attribute float currentScale;
    [SameObject] readonly attribute SVGPoint currentTranslate;
    
    readonly attribute boolean useCurrentView;
    readonly attribute SVGViewSpec currentView;

    NodeList getIntersectionList(SVGRect rect, SVGElement? referenceElement);
    NodeList getEnclosureList(SVGRect rect, SVGElement? referenceElement);
    boolean checkIntersection(SVGElement element, SVGRect rect);
    boolean checkEnclosure(SVGElement element, SVGRect rect);

    undefined deselectAll();

    [NewObject] SVGNumber createSVGNumber();
    [NewObject] SVGLength createSVGLength();
    [NewObject] SVGAngle createSVGAngle();
    [NewObject] SVGPoint createSVGPoint();
    [NewObject] SVGMatrix createSVGMatrix();
    [NewObject] SVGRect createSVGRect();
    [NewObject] SVGTransform createSVGTransform();
    [NewObject] SVGTransform createSVGTransformFromMatrix(optional DOMMatrix2DInit matrix);

    Element getElementById([RequiresExistingAtomString] DOMString elementId);

    // SVG animations extensions
    // https://svgwg.org/specs/animations/#InterfaceSVGSVGElement
    undefined pauseAnimations();
    undefined unpauseAnimations();
    boolean animationsPaused();
    unrestricted float getCurrentTime();
    undefined setCurrentTime(optional unrestricted float seconds = NaN);

    // Deprecated SVG redrawing
    unsigned long suspendRedraw(optional unsigned long maxWaitMilliseconds = 0);
    undefined unsuspendRedraw(optional unsigned long suspendHandleId = 0);
    undefined unsuspendRedrawAll();
    undefined forceRedraw();
};

SVGSVGElement includes SVGFitToViewBox;
SVGSVGElement includes SVGZoomAndPan;
// SVGSVGElement includes WindowEventHandlers;
