<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" onload="fillTestContent()">
  <script type="text/javascript">
  <![CDATA[
    
    if (window.testRunner)
        testRunner.waitUntilDone();
  
    var visibleValues = [ 'visible', 'hidden' ];
    var fillValues = ['none', 'orange' ];
    var strokeValues = ['none', 'blue' ];
  
    var pointerEventsValues = ['auto', 'visiblePainted', 'visibleFill', 'visibleStroke', 'visible', 'painted', 'fill', 'stroke', 'all', 'none'];
  
    var leftEdge = 100;
    var topEdge = 30;
    
    var rectSpacing = 57;
  
    var svgNS = "http://www.w3.org/2000/svg";
    
    function clickHit(event, identifierString) {
      var fillText = document.getElementById('fill-text' + identifierString);
      fillText.textContent = 'HIT';
    }
  
    function fillTestContent() {    
      var xOffset = leftEdge;
      var yOffset = topEdge;
    
      var testContent = document.getElementById("test-content");
    
      for (var pi = 0; pi < pointerEventsValues.length; pi++) {
        var eventLabel = document.createElementNS(svgNS, 'text');
        eventLabel.setAttribute('x', 0);
        eventLabel.setAttribute('y', yOffset + 30);
        eventLabel.textContent = pointerEventsValues[pi];
        testContent.appendChild(eventLabel);
      
        for (var vi = 0; vi < visibleValues.length; vi++) {
          for (var fi = 0; fi < fillValues.length; fi++) {
            for (var si = 0; si < strokeValues.length; si++) {
            
              var identString = "_" + pi + "_" + vi + "_" + fi + "_" + si;
            
              var txt = document.createElementNS(svgNS, 'text');
              txt.setAttribute('x', xOffset);
              txt.setAttribute('y', yOffset + 30);
              txt.setAttribute('font-size', 40);
              txt.setAttribute('visibility', visibleValues[vi]);
              txt.setAttribute('fill', fillValues[fi]);
              txt.setAttribute('stroke', strokeValues[si]);
              txt.setAttribute('pointer-events', pointerEventsValues[pi]);
              txt.setAttribute('onclick', 'clickHit(evt, "' + identString + '")');
              txt.appendChild(document.createTextNode("#"));
              
              testContent.appendChild(txt);
            
              var fillText = document.createElementNS(svgNS, 'text');
              fillText.setAttribute('x', xOffset + 5);
              fillText.setAttribute('y', yOffset + 20);
              fillText.textContent = "miss";
              fillText.setAttribute('id', 'fill-text' + identString);
              fillText.setAttribute('pointer-events', 'none');
              testContent.appendChild(fillText);
            
              if (window.eventSender) {
                // Cell click
                eventSender.mouseMoveTo(xOffset + 5, yOffset);
                eventSender.mouseDown();
                eventSender.mouseUp();
              }
              xOffset += rectSpacing;
            }
          }
        }
        xOffset = leftEdge;
        yOffset += rectSpacing;
      }
      
      if (window.testRunner)
        testRunner.notifyDone();
    }
  ]]>
  </script>
  
  <text x="110" y="20">Visibility: visible</text>
  <text x="340" y="20">Visibility: hidden</text>
  <g id="test-content"/>
</svg>
