My theory lasted until QA told me it happened in Safari on the Mac too. Then I tried it in FireFox on Linux. Same deal. After simply submitting the form 3 times the browser became unusable and eventually crashed. So much for the IE sucks theory.
In this form, if the user doesn't make any edits then submitting the form should return them the exact same HTML. I decided that I wanted to make sure that was really the case. My co-worker, Peter Leonard, suggested I use HTTP::Proxy to monitor the connection between the browser and the server. I did and was able to log each successive response to a separate file. I then ran a diff of each response. The results showed the problem clearly. Where there should be a single hidden field I saw around 50 hidden fields concatenated together. On each request the list of hidden fields grew longer. The name on the hidden input tags was "name".
Eventually I found the problem code:
return scalar $query->hidden(name => $param, default => ($element->data() || ""), override => 1);
It looks like a call to the CGI::hidden method using named parameters, doesn't it? But CGI.pm requires named params to start with '-'! This call was being interpreted as a request to setup a hidden input called "name" and without the "-override" option that will pull in whatever CGI::param() has for "name"! Thus, each time the form is submitted the list of hidden fields grows. Eventually it grows so large that the browser can't handle it.
Three dashes later and the code was working again:
return scalar $query->hidden(-name => $param, -default => ($element->data() || ""), -override => 1);
-sam