describe('Core htmx Regression Tests', function() {
  beforeEach(function() {
    this.server = makeServer()
    clearWorkArea()
  })
  afterEach(function() {
    this.server.restore()
    clearWorkArea()
  })

  it('SVGs process properly in IE11', function() {
    var btn = make('<svg onclick="document.getElementById(\'contents\').classList.toggle(\'show\')" class="hamburger" viewBox="0 0 100 80" width="25" height="25" style="margin-bottom:-5px">\n' +
            '<rect width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>\n' +
            '<rect y="30" width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>\n' +
            '<rect y="60" width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>\n' +
            '</svg>')
  })

  it('Handles https://github.com/bigskysoftware/htmx/issues/4 properly', function() {
    this.server.respondWith('GET', '/index2a.php',
      "<div id='message' hx-swap-oob='true'>I came from message oob swap I should be second</div>" +
            "<div id='message2' hx-swap-oob='true'>I came from a message2 oob swap I should be third  but I am in the wrong spot</div>" +
            "I'm page2 content (non-swap) I should be first")

    var h1 = make('' +
            "<div id='page2' ></div>" +
            "<div id='message'></div>" +
            "<div id='message2'></div>" +
        "<h1 hx-get='/index2a.php' hx-target='#page2' hx-trigger='click'>Kutty CLICK ME</h1>")
    h1.click()
    this.server.respond()
    htmx.find('#page2').innerHTML.should.equal("I'm page2 content (non-swap) I should be first")
    htmx.find('#message').innerHTML.should.equal('I came from message oob swap I should be second')
    htmx.find('#message2').innerHTML.should.equal('I came from a message2 oob swap I should be third  but I am in the wrong spot')
  })

  it('Handles https://github.com/bigskysoftware/htmx/issues/33 "empty values" properly', function() {
    this.server.respondWith('POST', '/htmx.php', function(xhr) {
      xhr.respond(200, {}, xhr.requestBody)
    })

    var form = make('<form hx-trigger="click" hx-post="/htmx.php">\n' +
            '<input type="text" name="variable" value="">\n' +
            '<button type="submit">Submit</button>\n' +
            '</form>')
    form.click()
    this.server.respond()
    form.innerHTML.should.equal('variable=')
  })

  it('name=id doesnt cause an error', function() {
    this.server.respondWith('GET', '/test', 'Foo<form><input name="id"/></form>')
    var div = make('<div hx-get="/test">Get It</div>')
    div.click()
    this.server.respond()
    div.innerText.should.contain('Foo')
  })

  it('empty id doesnt cause an error', function() {
    this.server.respondWith('GET', '/test', "Foo\n<div id=''></div>")
    var div = make('<div hx-get="/test">Get It</div>')
    div.click()
    this.server.respond()
    div.innerText.should.contain('Foo')
  })

  it('id with dot in value doesnt cause an error', function() {
    this.server.respondWith('GET', '/test', "Foo <div id='ViewModel.Test'></div>")
    var div = make('<div hx-get="/test">Get It</div>')
    div.click()
    this.server.respond()
    div.innerText.should.contain('Foo')
  })

  it('@ symbol in attributes does not break requests', function() {
    this.server.respondWith('GET', '/test', "<div id='d1' @foo='bar'>Foo</div>")
    var div = make('<div hx-get="/test">Get It</div>')
    div.click()
    this.server.respond()
    byId('d1').getAttribute('@foo').should.equal('bar')
  })

  it('@ symbol in attributes does not break attribute settling requests', function() {
    this.server.respondWith('GET', '/test', "<div id='d1' @foo='bar'>Foo</div>")
    var div = make('<div hx-get="/test"><div id="d1">Foo</div></div>')
    div.click()
    this.server.respond()
    byId('d1').getAttribute('@foo').should.equal('bar')
  })

  it('selected element with ID does not cause NPE when it disappears', function() {
    this.server.respondWith('GET', '/test', "<div id='d1'>Replaced</div>")
    var input = make('<input hx-trigger="click" hx-get="/test" id="i1" hx-swap="outerHTML">')
    input.focus()
    input.click()
    this.server.respond()
    byId('d1').innerText.should.equal('Replaced')
  })

  it('does not submit with a false condition on a form', function() {
    this.server.respondWith('POST', '/test', 'Submitted')
    var defaultPrevented = false
    htmx.on('click', function(evt) {
      defaultPrevented = evt.defaultPrevented
    })
    var form = make('<form hx-post="/test" hx-trigger="click[false]"></form>')
    form.click()
    this.server.respond()
    defaultPrevented.should.equal(true)
  })

  it('two elements can listen for the same event on another element', function() {
    this.server.respondWith('GET', '/test', 'triggered')

    make('<div id="d1" hx-trigger="click from:body" hx-get="/test"></div>' +
            '        <div id="d2" hx-trigger="click from:body" hx-get="/test"></div>')

    var div1 = byId('d1')
    var div2 = byId('d2')

    document.body.click()
    this.server.respond()

    div2.innerHTML.should.equal('triggered')
    div1.innerHTML.should.equal('triggered')
  })

  it('a form can reset based on the htmx:afterRequest event', function() {
    this.server.respondWith('POST', '/test', 'posted')

    var form = make('<div id="d1"></div><form _="on htmx:afterRequest reset() me" hx-post="/test" hx-target="#d1">' +
            '  <input type="text" name="input" id="i1"/>' +
            '  <input type="submit" id="s1"/>' +
            '</form>')
    htmx.trigger(form, 'htmx:load') // have to manually trigger the load event for non-AJAX dynamic content

    var div1 = byId('d1')
    var input = byId('i1')
    input.value = 'foo'
    var submit = byId('s1')

    input.value.should.equal('foo')
    submit.click()
    this.server.respond()

    div1.innerHTML.should.equal('posted')
    input.value.should.equal('') // form should be reset
  })

  it('supports image maps', function() {
    this.server.respondWith('GET', '/test', 'triggered')

    make('<div>' +
            '    <div id="d1"></div>' +
            '    <img src="img/bars.svg" usemap="#workmap" width="400" height="379">' +
            '' +
            '    <map name="workmap">' +
            '        <area shape="rect" coords="34,44,270,350" alt="Computer" hx-get="/test" hx-target="#d1">' +
            '    </map>' +
            '</div>')

    var div1 = byId('d1')
    var area = document.getElementsByTagName('area')[0]

    area.click()
    this.server.respond()

    div1.innerHTML.should.equal('triggered')
  })

  it('supports unset on hx-select', function() {
    this.server.respondWith('GET', '/test', "Foo<span id='example'>Bar</span>")
    make('<form hx-select="#example">\n' +
            '      <button id="b1" hx-select="unset" hx-get="/test">Initial</button>\n' +
            '</form>')
    var btn = byId('b1')
    btn.click()
    this.server.respond()

    btn.innerText.should.equal('FooBar')
  })

  it("can trigger swaps from fields that don't support setSelectionRange", function() {
    const template = '<form id="formtest"> \n' +
              '<input hx-get="/test" hx-target="#formtest" hx-trigger="click" type="text" id="id_email" value="test@test.com" />\n' +
              '</form>'

    const response = '<form id="formtest">\n' +
              '<input hx-get="/test" hx-target="#formtest" hx-trigger="click" type="email" id="id_email" value="supertest@test.com" />\n' +
              '</form>'
    this.server.respondWith('GET', '/test', response)
    make(template)
    var input = byId('id_email')
    // HTMX only attempts to restore the selection on inputs that have a current selection and are active.
    // additionally we can't set the selection on email inputs (that's the whole bug) so start as a text input where you can set selection
    // and replace with an email
    input.focus()
    input.selectionStart = 3
    input.selectionEnd = 3
    input.click()
    this.server.respond()
    var input = byId('id_email')
    input.value.should.equal('supertest@test.com')
  })

  it('script tags only execute once', function(done) {
    window.i = 0 // set count to 0
    this.server.respondWith('GET', '/test', '<script>console.trace(); window.i++</script>') // increment the count by 1

    // make a div w/ a short settle delay to make the problem more obvious
    var div = make('<div hx-get="/test" hx-swap="innerHTML settle:5ms"/>')
    div.click()
    this.server.respond()

    setTimeout(function() {
      window.i.should.equal(1)
      delete window.i
      done()
    }, 50)
  })

  it('script tags only execute once when nested', function(done) {
    window.i = 0 // set count to 0
    this.server.respondWith('GET', '/test', '<p>foo</p><div><script>console.trace(); window.i++</script></div>') // increment the count by 1

    // make a div w/ a short settle delay to make the problem more obvious
    var div = make('<div hx-get="/test" hx-swap="innerHTML settle:5ms"/>')
    div.click()
    this.server.respond()

    setTimeout(function() {
      window.i.should.equal(1)
      delete window.i
      done()
    }, 50)
  })

  it('htmx.config.allowScriptTags properly disables script tags', function(done) {
    htmx.config.allowScriptTags = false
    window.i = 0 // set count to 0
    this.server.respondWith('GET', '/test', '<script>console.trace(); window.i++</script>') // increment the count by 1

    // make a div w/ a short settle delay to make the problem more obvious
    var div = make('<div hx-get="/test" hx-swap="innerHTML settle:5ms"/>')
    div.click()
    this.server.respond()

    setTimeout(function() {
      window.i.should.equal(0)
      htmx.config.allowScriptTags = true
      delete window.i
      done()
    }, 50)
  })

  it('htmx.config.allowScriptTags properly disables script tags when nested', function(done) {
    htmx.config.allowScriptTags = false
    window.i = 0 // set count to 0
    this.server.respondWith('GET', '/test', '<div><script>console.trace(); window.i++</script></div>') // increment the count by 1

    // make a div w/ a short settle delay to make the problem more obvious
    var div = make('<div hx-get="/test" hx-swap="innerHTML settle:5ms"/>')
    div.click()
    this.server.respond()

    setTimeout(function() {
      window.i.should.equal(0)
      htmx.config.allowScriptTags = true
      delete window.i
      done()
    }, 50)
  })
})
