/*
 * Copyright (C) 2004 Stephen Ostermiller
 * http://ostermiller.org/contact.pl?regarding=Bookmarklets
 *
 * This bookmarklet is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This bookmarklet 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 General Public License for more details.
 */
 
/**
 * Creates a new page that contains only the forms from the current page, with their current values.
 *
 * Traverses all frames on the current page find the forms, pulls the form and its elements out
 * into a new page.  This breaks on forms that have an element named action, and forms that contain
 * image elements that are not in the traversal list.
 * <p>
 * Once all the forms are in a new page, it is easy to save that page to a local file to store
 * the form data, or to manipulate the form before submitting it again.
 * 
 * @name Extract Forms
 *
 * @substitute popup_document_pointer          a
 * @substitute result_html                     b
 * @substitute caught_exception                c
 * @substitute current_frame                   d
 * @substitute frame_index                     e
 * @substitute document_forms                  f
 * @substitute form_index                      g
 * @substitute current_form                    h
 * @substitute element_index                   i
 * @substitute current_element                 j
 * @substitute lowercase_element_type          k
 * @substitute option_list                     l
 * @substitute option_index                    m
 * @substitute current_option                  n
 * @substitute current_form                    o
 * @substitute form_action                     p
 *
 * @compatible Firefox
 *
 * @category Form
 * @category Utilities 
 *
 * @keyword extract forms bookmarklet
 * @keyword form extraction bookmarklet
 */
void(
    (function(){
        var popup_document_pointer,result_html;
        // Build an html document with all the forms on the page
        result_html="<"+"html>\n<head>\n<base href='"+document.location+"'>\n</head>\n<body>\n\n";
        (function(current_frame){
            var frame_index,document_forms,form_index,current_form,element_index,current_element,lowercase_element_type,option_list,option_index,current_option;
            // For each frame in the current document
            for(frame_index=0;frame_index<current_frame.length;frame_index++){
                try{
                    arguments.callee(current_frame.frames[frame_index]); // Recurse frame
                }catch(caught_exception){}
            }
            document_forms=current_frame.document.forms;
            // For each form in the document
            for(form_index=0;form_index<document_forms.length;form_index++){
                current_form=document_forms[form_index];
                // pull out form (with blue border)
                var form_action=current_form.getAttribute("action");
                if (!form_action)form_action=current_frame.document.location;
                var form_method=current_form.getAttribute("method");
                if (!form_method)form_method="GET"; 
                result_html+="<div style='border:3px blue ridge'>\n<form action='"+form_action+"' method='"+form_method+"'>\n";
                // For each element in the frame (doesn't seem to get images)
                for(element_index=0;element_index<current_form.length;element_index++){
                    current_element=current_form[element_index];
                    lowercase_element_type=current_element.type.toLowerCase();
                    // text areas
                    if(lowercase_element_type=="textarea")result_html+="<textarea name='"+current_element.name+"'>"+current_element.value+"</textarea>\n";
                    // combo boxes and choose multiples
                    else if(lowercase_element_type.indexOf("select")==0){
                        result_html+="<select name='"+current_element.name+"'"+(lowercase_element_type=="select-multiple"?" multiple":"")+">\n";
                        option_list=current_element.options;
                        // for each of the options in the select
                        for(option_index=0;option_index<option_list.length;option_index++){
                            current_option=option_list[option_index];
                            result_html+="<option value='"+current_option.value+"'"+(current_option.selected?" selected":"")+">"+current_option.text+"</option>\n";
                        }
                        result_html+="</select>\n";
                    // text fields, radio buttons, check boxes, submits, buttons, etc 
                    }else result_html+="<input type='"+current_element.type+"' name='"+current_element.name+"' value='"+current_element.value+"'"+(((lowercase_element_type=="checkbox"||lowercase_element_type=="radio")&&current_element.checked)?" checked":"")+">\n";
                }
                result_html+="</form>\n</div>\n\n";
            }
        })(top); // Start with the top level frame
        result_html+="<pre>"+result_html.replace(/</g,"&lt;").replace(/>/g,"&gt;","g")+"</pre>";        
        result_html+="</body>\n</html>\n";
        // Open a pop-up window to show all the forms
        popup_document_pointer=window.open("","","width=200,height=300").document;
        popup_document_pointer.open();
        popup_document_pointer.write(result_html);
        popup_document_pointer.close();
    })()
)
