/**
 * Данная библиотека позволяет просматривать JavaScript Document Object Model для HTML
 * Инспектор активизируется вызовом функции inspectDOM ( obj, rej ) 
 *
 * Copyleft by Alexsander A. Tolmachev
 * Доработал Козарь. ( rej - битовая маска из констант см. ниже )
**/

const WITHOUT_CONST			= 1;	// Не показывать константы
const WITHOUT_FUNCTION		= 2;	// Не показывать функции
const WITH_COMPARE			= 4;	// Показать "старые" значения, если значения отличаются

function _hsc_ ( v ) { // HTML special characters
    /*
    var esc_str = String(v);

    esc_str = esc_str.replace(/&/g,"&amp;");
    esc_str = esc_str.replace(/</g,"&lt;"); //>
    esc_str = esc_str.replace(/>/g,"&gt;");

    return esc_str;
    */

    var d = document.createElement("div");
    d.appendChild( document.createTextNode(v) );
    return d.innerHTML;
}

function _href_to_next_obj_ ( el, next_obj_str, rej ) {
    var next_href = "javascript: opener._show_prop_(" + (rej & ~WITH_COMPARE) + ',' + next_obj_str + ")";
    return (typeof(el) == "object"  &&  el !== null
            ? "<a href=\""+ next_href +"\">"+el+"</a>" + (el.nodeName ? " <i>"+el.nodeName+"</i>" : "")
			: _hsc_(el))
}

var old_obj = {};

function _show_prop_ ( rej, next_obj ) {
	if ( next_obj )
		__objs[++__obj_i] = next_obj;

    if ( __obj_i <= 0 ) { //>
        __back_button.blur();
        __back_button.disabled = true;
        __obj_i = 0;
    } else {
        __back_button.disabled = false;
    }
    __obj = __objs[__obj_i];


    var propList = "<table border=1><caption>" + __obj + "</caption>";
	var fld, el, next_obj_str;
    for ( var i in __obj ) {
        try {
			fld = i;
			el = __obj[i];
			next_obj_str = "opener.__obj['"+i+"']";
        } catch ( e ) {
			fld = "<span style='color: red'>" + i + "</span>";
			el = e.toString();
            next_obj_str = "";
        }
    	var value = _href_to_next_obj_(el, next_obj_str, rej);

        if ( rej & WITHOUT_CONST && fld == fld.toUpperCase() )
//!!! Не показывать константы
        	continue;
        if ( rej & WITHOUT_FUNCTION && typeof(el) == "function" )
//!!! Не показывать функции
        	continue;

    	if ( rej & WITH_COMPARE && old_obj[fld] && old_obj[fld] != value )
    	{
//!!! Если режим WITH_COMPARE и значения отличаются
    		value += "<font color=magenta>(" + old_obj[fld] + ")</font>";
    	}
   		old_obj[fld] = _href_to_next_obj_(el, next_obj_str, rej);
		propList += "<tr><td>" + fld + "</td><td>" + value + "</td></tr>";
    }
    propList += "</table>";

    if ( typeof(__obj) == "object"  &&  typeof(__obj.length) == "number"  &&  typeof(__obj.item) == "function" ) {
        propList += "<table border=1><caption>Collection content</caption>";
        for ( var l=0; l<__obj.length; ++l ) {  //>
			fld = "item(" + l + ")";
            try {
				el = __obj.item(l);
				next_obj_str = "opener.__obj.item("+l+")";
            } catch ( e ) {
				fld = "<span style='color: red'>" + fld + "</span>";
				el = e.toString();
	            next_obj_str = "";
            }
            propList += "<tr><td>" + fld + "</td><td>" + _href_to_next_obj_(el, next_obj_str, rej) + "</td></tr>";
        }
        if ( __obj.length == 0 ) {
            propList += "<tr><td width='200' align='center'>Empty</td></tr>";
        }
        propList += "</table>";
    }

    __prop_disp.innerHTML = propList;
}

var __obj;
var __objs  = Array();
var __obj_i = 0;
var __back_button;
var __prop_disp;

function inspectDOM ( obj, rej )
{
	var w = window.open("","DOMInspector");
	var d = w.document;
	d.open();
	d.write(
"<html>" +
"<head><title>DOM Inspector</title></head>" +
"<body>" +
"<button id='back' type='button' onclick='opener._back_obj_(" + (rej & ~WITH_COMPARE) + ")' disabled>Back</button>" +
"<div id='display'></div>" +
"</body>" +
"</html>"
		);
	d.close();
	w.focus();

    __back_button = d.getElementById("back");
    __prop_disp   = d.getElementById("display");

    __obj = obj;
    __objs[__obj_i] = __obj;
    _show_prop_(rej);
}

function _back_obj_ (rej) {
    --__obj_i;
    _show_prop_(rej);
}


