<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<!--

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

-->
<!-- ========================================================================= -->
<!-- Checks that access to critical functions is not allowed.                  -->
<!--                                                                           -->
<!-- @author vincent.hardy@sun.com                                             -->
<!-- @version $Id$   -->
<!-- ========================================================================= -->

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink" 
     xmlns:test="http://xml.apache.org/batik/test"
     width="450" height="500" viewBox="0 0 450 500">

    <test:testResult id="testResult" result="passed"/>
    <script type="text/ecmascript"><![CDATA[

    var insertAt = "";
    var curURI = "";

    function insertContentAt(uri, insertionPoint) {
        insertAt = insertionPoint;
        curURI = uri;
        getURL(uri, onInsert);
    }

    function onInsert(status) {
        if (status.success == false) {
            alert("Could not get " + curURI);
            return;
        }

        var insertionPoint = document.getElementById(insertAt);

        if (insertionPoint == null) {
            alert("Could not find : " + insertAt);
            return;
        }

        var svgContent = status.content;

        var svgContentRoot = parseXML(svgContent, document);

        if (svgContentRoot == null) {
            alert("Could not parse content from : " + insertAt);
            return;
        }

        insertionPoint.appendChild(svgContentRoot);
    }

    function insertLocalContentAt(uri, insertAt) {
        var g = document.getElementById(insertAt);
        if (g == null) {
            alert("Could not find : " + insertAt);
        }

        var svgNS = "http://www.w3.org/2000/svg";
        var xlinkNS = "http://www.w3.org/1999/xlink" ;
        var use = document.createElementNS(svgNS, "use");
        use.setAttributeNS(null, "x", "0");
        use.setAttributeNS(null, "y", "0");
        use.setAttributeNS(null, "width", "100%");
        use.setAttributeNS(null, "height", "100%");
        use.setAttributeNS(xlinkNS, "href", uri);
        g.appendChild(use);
    }
    ]]></script>

    <g id="insertionPoint">
    </g>

    <g transform="translate(225, 100)">
        <style type="text/css"><![CDATA[

        .testButton {
            fill: white;
            fill-opacity: .5;
            stroke: black;
            shape-rendering: crispEdges;
        }

        .buttonLabel {
            fill: black;
            text-anchor: middle;
        }

        .title {
            text-anchor: middle;
        }

        ]]>
        </style>

        <defs>
            <rect class="testButton" id="testButton" x="-60" y="-20" width="120" height="30" />

            <rect id="testRect" x="0" y="0" width="100%" height="100%" fill="gold" />
        </defs>

        <text transform="translate(0,0)" class="title" y="-40">Click on one of the following buttons 
            <tspan x="0" dy="1.2em">to test unsecure content insertion</tspan>
            <tspan x="0" dy="1.2em">(the result depends on the security settings)</tspan></text>

        <g transform="translate(0,120)">
            <use xlink:href="#testButton" onclick="insertContentAt('http://nagoya.apache.org/batik_1.1/batik-1.1/samples/asf-logo.svg', 'insertionPoint')" />
            <text class="buttonLabel">Network Access</text>
        </g>
        
        <g transform="translate(0,160)">
            <use xlink:href="#testButton" onclick="insertContentAt('../../../../../samples/batikFX.svg', 'insertionPoint')" />
            <text class="buttonLabel">File System Access</text>
        </g>
        
        <g transform="translate(0,200)">
            <use xlink:href="#testButton" onclick="insertLocalContentAt('#testRect', 'insertionPoint')" />
            <text class="buttonLabel">Internal Use</text>
        </g>
        
    </g>
</svg>
