Index: kioslave/http/http.cc
===================================================================
--- kioslave/http/http.cc	(revision 607008)
+++ kioslave/http/http.cc	(working copy)
@@ -2491,7 +2491,7 @@
       header += "\r\n";
     }
 
-    if (m_request.method == HTTP_POST)
+    if (m_request.method == HTTP_POST || m_request.method == HTTP_PUT)
     {
       header += metaData("content-type");
       header += "\r\n";
@@ -2588,7 +2588,7 @@
     }
   }
 
-  kdDebug(7103) << "(" << m_pid << ") ============ Sending Header:" << endl;
+  kdDebug(7103) << "(" << m_pid << ") ============ NKS Sending Header:" << endl;
 
   QStringList headerOutput = QStringList::split("\r\n", header);
   QStringList::Iterator it = headerOutput.begin();
Index: khtml/khtml_part.h
===================================================================
--- khtml/khtml_part.h	(revision 607008)
+++ khtml/khtml_part.h	(working copy)
@@ -1616,6 +1616,7 @@
   bool requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() );
 
   DOM::EventListener *createHTMLEventListener( QString code, QString name, DOM::NodeImpl *node );
+  DOM::EventListener *createHTMLEventListenerNoHook( QString code, QString name, DOM::NodeImpl *node );
 
   DOM::HTMLDocumentImpl *docImpl() const;
   DOM::DocumentImpl *xmlDocImpl() const;
@@ -1624,7 +1625,8 @@
   khtml::ChildFrame *recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url, const KParts::URLArgs &args, bool callParent = true );
 
   bool checkLinkSecurity( const KURL &linkURL,const QString &message = QString::null, const QString &button = QString::null );
-  QVariant executeScript( const QString& filename, int baseLine, const DOM::Node &n, const QString& script );
+  QVariant executeScript( const QString& filename, int baseLine, const DOM::Node &n, 
+			  const QString& script, DOM::NodeImpl* curnode);
 
   KJSProxy *jScript();
 
Index: khtml/misc/loader.h
===================================================================
--- khtml/misc/loader.h	(revision 607008)
+++ khtml/misc/loader.h	(working copy)
@@ -53,6 +53,7 @@
 
 #include <khtml_settings.h>
 #include <dom/dom_string.h>
+#include <xml/dom_nodeimpl.h>
 
 class QMovie;
 class KHTMLPart;
@@ -241,11 +242,14 @@
 	void checkNotify();
 
         bool isLoaded() const { return !m_loading; }
-        void setCharset( const QString& charset ) { m_charset = charset; }
-
+      void setCharset( const QString& charset ) { m_charset = charset; }
+      void setScriptElementNode(DOM::NodeImpl *n) { scriptElementNode = n; scriptElementNode->ref();}
+      DOM::NodeImpl* getScriptElementNode() { return scriptElementNode; }
+      
     protected:
-        QString m_charset;
-	DOM::DOMString m_script;
+      QString m_charset;
+      DOM::DOMString m_script;
+      DOM::NodeImpl *scriptElementNode;
     };
 
     class ImageSource;
Index: khtml/khtml_part.cpp
===================================================================
--- khtml/khtml_part.cpp	(revision 607008)
+++ khtml/khtml_part.cpp	(working copy)
@@ -186,7 +186,7 @@
     if (m_jscript) {
         // we have a jscript => a part in an iframe
         KJS::Completion cmp;
-        m_jscript->evaluate(QString::null, 1, script, 0L, &cmp);
+        m_jscript->evaluate(QString::null, 1, script, 0L, &cmp, 0);
     } else
         part->executeScript(m_frame->element(), script);
 }
@@ -1139,8 +1139,10 @@
   KApplication::kdeinitExec( "kcmshell", args );
 }
 
-QVariant KHTMLPart::executeScript(const QString& filename, int baseLine, const DOM::Node& n, const QString& script)
-{
+QVariant KHTMLPart::executeScript(const QString& filename, int baseLine, 
+				  const DOM::Node& n, const QString& script,
+				  DOM::NodeImpl *enclosingNode) 
+  {
 #ifdef KJS_VERBOSE
   // The script is now printed by KJS's Parser::parse
   kdDebug(6070) << "executeScript: caller='" << name() << "' filename=" << filename << " baseLine=" << baseLine /*<< " script=" << script*/ << endl;
@@ -1152,7 +1154,7 @@
 
   KJS::Completion comp;
 
-  QVariant ret = proxy->evaluate(filename, baseLine, script, n, &comp);
+  QVariant ret = proxy->evaluate(filename, baseLine, script, n, &comp, enclosingNode);
 
   /*
    *  Error handling
@@ -1175,9 +1177,9 @@
       t->abort();
     d->m_redirectionTimer.start( 0, true );
   }
-
+  
   return ret;
-}
+  }
 
 QVariant KHTMLPart::executeScript( const QString &script )
 {
@@ -1190,12 +1192,12 @@
   kdDebug(6070) << "KHTMLPart::executeScript caller='" << name() << "' node=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " /* << script */ << endl;
 #endif
   KJSProxy *proxy = jScript();
-
+  
   if (!proxy || proxy->paused())
     return QVariant();
   ++(d->m_runningScripts);
   KJS::Completion comp;
-  const QVariant ret = proxy->evaluate( QString::null, 1, script, n, &comp );
+  const QVariant ret = proxy->evaluate( QString::null, 1, script, n, &comp, 0);
   --(d->m_runningScripts);
 
   /*
@@ -6926,8 +6928,17 @@
 
   if (!proxy)
     return 0;
+  return proxy->createHTMLEventHandler( m_url.url(), name, code, node, true);
+}
 
-  return proxy->createHTMLEventHandler( m_url.url(), name, code, node );
+//event listener set through the DOM interface -- i.e. via javascript; so don't run the hook
+DOM::EventListener *KHTMLPart::createHTMLEventListenerNoHook( QString code, QString name, NodeImpl* node )
+{
+  KJSProxy *proxy = jScript();
+
+  if (!proxy)
+    return 0;
+  return proxy->createHTMLEventHandler( m_url.url(), name, code, node, false);
 }
 
 KHTMLPart *KHTMLPart::opener()
Index: khtml/html/htmltokenizer.cpp
===================================================================
--- khtml/html/htmltokenizer.cpp	(revision 607008)
+++ khtml/html/htmltokenizer.cpp	(working copy)
@@ -134,6 +134,7 @@
     m_executingScript = 0;
     m_autoCloseTimer = 0;
     onHold = false;
+    currTokenNode = 0;
 
     reset();
 }
@@ -149,6 +150,7 @@
     m_executingScript = 0;
     m_autoCloseTimer = 0;
     onHold = false;
+    currTokenNode = 0;
 
     reset();
 }
@@ -176,7 +178,7 @@
         killTimer(m_autoCloseTimer);
         m_autoCloseTimer = 0;
     }
-
+    currTokenNode = 0;
     currToken.reset();
 }
 
@@ -381,7 +383,8 @@
 
     processListing(TokenizerString(scriptCode, scriptCodeSize));
     QString exScript( buffer, dest-buffer );
-
+    
+    NodeImpl *scriptElementNode = this->currTokenNode;
     processToken();
     currToken.tid = ID_SCRIPT + ID_CLOSE_TAG;
     processToken();
@@ -397,7 +400,8 @@
         // forget what we just got, load from src url instead
         if ( !currentScriptSrc.isEmpty() &&
              (cs = parser->doc()->docLoader()->requestScript(currentScriptSrc, scriptSrcCharset) )) {
-            cachedScript.enqueue(cs);
+	  cachedScript.enqueue(cs); //should also enqueue the scriptElementNode ... so that when it runs eventually we can pass in the context
+	  cs->setScriptElementNode(scriptElementNode);
         }
 
         if (cs) {
@@ -413,7 +417,7 @@
             pendingQueue.push(src);
             setSrc(TokenizerString());
             scriptCodeSize = scriptCodeResync = 0;
-            scriptExecution( exScript, QString::null, tagStartLineno /*scriptStartLineno*/ );
+            scriptExecution( exScript, QString::null, tagStartLineno, scriptElementNode /*scriptStartLineno*/ );
         } else {
             // script was filtered or disallowed
             effectiveScript = false;
@@ -436,8 +440,11 @@
     }
 }
 
+//This should be called on the contents of a <script> element 
+//only after processToken has already executed
+//In that case, parser->
 void HTMLTokenizer::scriptExecution( const QString& str, const QString& scriptURL,
-                                     int baseLine)
+                                     int baseLine, DOM::NodeImpl *scriptElementNode)
 {
     bool oldscript = script;
     m_executingScript++;
@@ -447,9 +454,9 @@
       url = static_cast<DocumentImpl*>(view->part()->document().handle())->URL().url();
     else
       url = scriptURL;
+    if (view) 
+      view->part()->executeScript(url,baseLine+1,Node(),str,scriptElementNode);
 
-    if (view)
-	view->part()->executeScript(url,baseLine+1,Node(),str);
     m_executingScript--;
     script = oldscript;
 }
@@ -1681,7 +1688,7 @@
     m_executingScript++;
 
     // pass the token over to the parser, the parser DOES NOT delete the token
-    parser->parseToken(&currToken);
+    currTokenNode = parser->parseToken(&currToken);
 
     m_executingScript--;
 
@@ -1728,6 +1735,7 @@
 
         CachedScript* cs = cachedScript.dequeue();
         DOMString scriptSource = cs->script();
+	DOM::NodeImpl *scn = cs->getScriptElementNode();
 #ifdef TOKEN_DEBUG
         kdDebug( 6036 ) << "External script is:" << endl << scriptSource.string() << endl;
 #endif
@@ -1738,8 +1746,9 @@
         QString cachedScriptUrl( cs->url().string() );
         cs->deref(this);
 
-	scriptExecution( scriptSource.string(), cachedScriptUrl );
-
+	scriptExecution( scriptSource.string(), cachedScriptUrl, 0, scn );
+	scn->deref();
+	
         done = cachedScript.isEmpty();
 
         // 'script' is true when we are called synchronously from
Index: khtml/html/html_blockimpl.cpp
===================================================================
--- khtml/html/html_blockimpl.cpp	(revision 607008)
+++ khtml/html/html_blockimpl.cpp	(working copy)
@@ -37,7 +37,7 @@
 using namespace khtml;
 using namespace DOM;
 
-void HTMLDivElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLDivElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -55,7 +55,7 @@
         break;
     }
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -66,7 +66,7 @@
     return ID_HR;
 }
 
-void HTMLHRElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLHRElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch( attr->id() )
     {
@@ -99,7 +99,7 @@
     }
     break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -170,7 +170,7 @@
     return ID_MARQUEE;
 }
 
-void HTMLMarqueeElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLMarqueeElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -250,7 +250,7 @@
             m_minimumDelay = attr->val() ? 0 : defaultMinimumDelay;
             break;
         default:
-            HTMLElementImpl::parseAttribute(attr);
+            HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -262,7 +262,7 @@
     transparent = fixed = false;
 }
 
-void HTMLLayerElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLLayerElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     // Layers are evil
     // They are mainly implemented here to correctly parse the hidden attribute
@@ -326,7 +326,7 @@
             }
             //fallthrough
         default:
-            HTMLElementImpl::parseAttribute(attr);
+            HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
Index: khtml/html/html_elementimpl.h
===================================================================
--- khtml/html/html_elementimpl.h	(revision 607008)
+++ khtml/html/html_elementimpl.h	(working copy)
@@ -48,7 +48,7 @@
     virtual DOMString localName() const;
     virtual DOMString namespaceURI() const;
 
-    virtual void parseAttribute(AttributeImpl *token);
+    virtual void parseAttribute(AttributeImpl *token, bool hook);
 
     void addCSSLength(int id, const DOMString &value, bool numOnly = false, bool multiLength = false);
     void addCSSProperty(int id, const DOMString &value);
Index: khtml/html/html_headimpl.cpp
===================================================================
--- khtml/html/html_headimpl.cpp	(revision 607008)
+++ khtml/html/html_headimpl.cpp	(working copy)
@@ -50,7 +50,7 @@
     return ID_BASE;
 }
 
-void HTMLBaseElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLBaseElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -63,7 +63,7 @@
 	process();
 	break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -111,7 +111,7 @@
     return ID_LINK;
 }
 
-void HTMLLinkElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLLinkElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch (attr->id())
     {
@@ -163,7 +163,7 @@
         break;
     }
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -290,7 +290,7 @@
     return ID_META;
 }
 
-void HTMLMetaElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLMetaElementImpl::parseAttribute(AttributeImpl *attr,bool hook)
 {
     switch(attr->id())
     {
@@ -303,7 +303,7 @@
 	process();
 	break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -523,7 +523,7 @@
 }
 
 // other stuff...
-void HTMLStyleElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLStyleElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch (attr->id())
     {
@@ -534,7 +534,7 @@
         m_media = attr->value().string().lower();
         break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
Index: khtml/html/html_formimpl.cpp
===================================================================
--- khtml/html/html_formimpl.cpp	(revision 607008)
+++ khtml/html/html_formimpl.cpp	(working copy)
@@ -684,7 +684,7 @@
     m_inreset = false;
 }
 
-void HTMLFormElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLFormElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -712,11 +712,11 @@
         break;
     case ATTR_ONSUBMIT:
         setHTMLEventListener(EventImpl::SUBMIT_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onsubmit", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onsubmit", this, hook));
         break;
     case ATTR_ONRESET:
         setHTMLEventListener(EventImpl::RESET_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onreset", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onreset", this, hook));
         break;
     case ATTR_NAME:
         if (inDocument() && m_name != attr->value()) {
@@ -726,7 +726,7 @@
         m_name = attr->value();
         //Fallthrough intentional
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -832,7 +832,7 @@
     if (m_name) m_name->deref();
 }
 
-void HTMLGenericFormElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLGenericFormElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -847,7 +847,7 @@
         break;
     }
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -1098,7 +1098,7 @@
     getDocument()->setFocusNode(this);
 }
 
-void HTMLButtonElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLButtonElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -1119,7 +1119,7 @@
     case ATTR_ALIGN:
         break;
     default:
-        HTMLGenericFormElementImpl::parseAttribute(attr);
+        HTMLGenericFormElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -1207,9 +1207,9 @@
     _style->deref();
 }
 
-void HTMLFieldSetElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLFieldSetElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
-    HTMLElementImpl::parseAttribute(attr);
+    HTMLElementImpl::parseAttribute(attr, hook);
 }
 
 // -------------------------------------------------------------------------
@@ -1372,7 +1372,7 @@
     dispatchMouseEvent(&me,EventImpl::CLICK_EVENT, 1);
 }
 
-void HTMLInputElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLInputElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -1432,14 +1432,14 @@
         break;
     case ATTR_ONSELECT:
         setHTMLEventListener(EventImpl::SELECT_EVENT,
-            getDocument()->createHTMLEventListener(attr->value().string(), "onselect", this));
+            getDocument()->createHTMLEventListener(attr->value().string(), "onselect", this, hook));
         break;
     case ATTR_ONCHANGE:
         setHTMLEventListener(EventImpl::CHANGE_EVENT,
-            getDocument()->createHTMLEventListener(attr->value().string(), "onchange", this));
+            getDocument()->createHTMLEventListener(attr->value().string(), "onchange", this, hook));
         break;
     default:
-        HTMLGenericFormElementImpl::parseAttribute(attr);
+        HTMLGenericFormElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -1959,14 +1959,14 @@
     _style->deref();
 }
 
-void HTMLLegendElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLLegendElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
     case ATTR_ACCESSKEY:
         break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -2242,7 +2242,7 @@
     return HTMLGenericFormElementImpl::addChild(newChild);
 }
 
-void HTMLSelectElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLSelectElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -2263,10 +2263,10 @@
         break;
     case ATTR_ONCHANGE:
         setHTMLEventListener(EventImpl::CHANGE_EVENT,
-            getDocument()->createHTMLEventListener(attr->value().string(), "onchange", this));
+            getDocument()->createHTMLEventListener(attr->value().string(), "onchange", this, hook));
         break;
     default:
-        HTMLGenericFormElementImpl::parseAttribute(attr);
+        HTMLGenericFormElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -2480,7 +2480,7 @@
     return ID_KEYGEN;
 }
 
-void HTMLKeygenElementImpl::parseAttribute(AttributeImpl* attr)
+void HTMLKeygenElementImpl::parseAttribute(AttributeImpl* attr, bool hook)
 {
     switch(attr->id())
     {
@@ -2488,7 +2488,7 @@
         break;
     default:
         // skip HTMLSelectElementImpl parsing!
-        HTMLGenericFormElementImpl::parseAttribute(attr);
+        HTMLGenericFormElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -2576,7 +2576,7 @@
     // ###
 }
 
-void HTMLOptionElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLOptionElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -2587,7 +2587,7 @@
         m_value = attr->value();
         break;
     default:
-        HTMLGenericFormElementImpl::parseAttribute(attr);
+        HTMLGenericFormElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -2671,7 +2671,7 @@
     onSelect();
 }
 
-void HTMLTextAreaElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLTextAreaElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -2709,14 +2709,14 @@
         break;
     case ATTR_ONSELECT:
         setHTMLEventListener(EventImpl::SELECT_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onselect", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onselect", this, hook));
         break;
     case ATTR_ONCHANGE:
         setHTMLEventListener(EventImpl::CHANGE_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onchange", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onchange", this, hook));
         break;
     default:
-        HTMLGenericFormElementImpl::parseAttribute(attr);
+        HTMLGenericFormElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -2939,11 +2939,11 @@
     return ID_ISINDEX;
 }
 
-void HTMLIsIndexElementImpl::parseAttribute(AttributeImpl* attr)
+void HTMLIsIndexElementImpl::parseAttribute(AttributeImpl* attr, bool hook)
 {
     // don't call HTMLInputElement::parseAttribute here, as it would
     // accept attributes this element does not support
-    HTMLGenericFormElementImpl::parseAttribute(attr);
+    HTMLGenericFormElementImpl::parseAttribute(attr, hook);
 }
 
 DOMString HTMLIsIndexElementImpl::prompt() const
Index: khtml/html/html_objectimpl.cpp
===================================================================
--- khtml/html/html_objectimpl.cpp	(revision 607008)
+++ khtml/html/html_objectimpl.cpp	(working copy)
@@ -62,7 +62,7 @@
         serviceType.truncate( pos );
 }
 
-void HTMLObjectBaseElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLObjectBaseElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch ( attr->id() )
     {
@@ -95,7 +95,7 @@
             m_name = attr->value();
             //fallthrough
         default:
-            HTMLElementImpl::parseAttribute( attr );
+            HTMLElementImpl::parseAttribute( attr, hook );
     }
 }
 
@@ -233,7 +233,7 @@
     return ID_APPLET;
 }
 
-void HTMLAppletElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLAppletElementImpl::parseAttribute(AttributeImpl *attr,bool hook)
 {
     switch( attr->id() )
     {
@@ -258,7 +258,7 @@
         addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value().lower() );
         break;
     default:
-        HTMLObjectBaseElementImpl::parseAttribute(attr);
+        HTMLObjectBaseElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -297,7 +297,7 @@
     return ID_EMBED;
 }
 
-void HTMLEmbedElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLEmbedElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
   switch ( attr->id() )
   {
@@ -339,7 +339,7 @@
            hidden = false;
         break;
      default:
-        HTMLObjectBaseElementImpl::parseAttribute( attr );
+        HTMLObjectBaseElementImpl::parseAttribute( attr, hook );
   }
 }
 
@@ -377,7 +377,7 @@
   return 0;
 }
 
-void HTMLObjectElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLObjectElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
   switch ( attr->id() )
   {
@@ -391,11 +391,11 @@
       break;
     case ATTR_ONLOAD: // ### support load/unload on object elements
         setHTMLEventListener(EventImpl::LOAD_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onload", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onload", this, hook));
         break;
     case ATTR_ONUNLOAD:
         setHTMLEventListener(EventImpl::UNLOAD_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onunload", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onunload", this, hook));
         break;
      case ATTR_VSPACE:
         addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
@@ -412,7 +412,7 @@
         addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value().lower() );
         break;
     default:
-      HTMLObjectBaseElementImpl::parseAttribute( attr );
+      HTMLObjectBaseElementImpl::parseAttribute( attr, hook );
   }
 }
 
@@ -443,7 +443,7 @@
     return ID_PARAM;
 }
 
-void HTMLParamElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLParamElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch( attr->id() )
     {
@@ -457,7 +457,7 @@
         m_name = attr->value().string();
         // fall through
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
Index: khtml/html/html_baseimpl.cpp
===================================================================
--- khtml/html/html_baseimpl.cpp	(revision 607008)
+++ khtml/html/html_baseimpl.cpp	(working copy)
@@ -65,7 +65,7 @@
     return ID_BODY;
 }
 
-void HTMLBodyElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLBodyElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -140,40 +140,40 @@
     }
     case ATTR_ONLOAD:
         getDocument()->setHTMLWindowEventListener(EventImpl::LOAD_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onload", NULL));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onload", NULL, hook));
         break;
     case ATTR_ONUNLOAD:
         getDocument()->setHTMLWindowEventListener(EventImpl::UNLOAD_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onunload", NULL));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onunload", NULL, hook));
         break;
     case ATTR_ONBLUR:
         getDocument()->setHTMLWindowEventListener(EventImpl::BLUR_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onblur", NULL));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onblur", NULL, hook));
         break;
     case ATTR_ONFOCUS:
         getDocument()->setHTMLWindowEventListener(EventImpl::FOCUS_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onfocus", NULL));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onfocus", NULL, hook));
         break;
     case ATTR_ONRESIZE:
         getDocument()->setHTMLWindowEventListener(EventImpl::RESIZE_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onresize", NULL));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onresize", NULL, hook));
         break;
     case ATTR_ONKEYUP:
         getDocument()->setHTMLWindowEventListener(EventImpl::KEYUP_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeyup", NULL));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeyup", NULL, hook));
         break;
     case ATTR_ONKEYDOWN:
         getDocument()->setHTMLWindowEventListener(EventImpl::KEYDOWN_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeydown", NULL));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeydown", NULL, hook));
         break;
     case ATTR_ONKEYPRESS:
         getDocument()->setHTMLWindowEventListener(EventImpl::KEYPRESS_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeypress", NULL));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeypress", NULL, hook));
         break;
     case ATTR_NOSAVE:
 	break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -254,7 +254,11 @@
     return ID_FRAME;
 }
 
-void HTMLFrameElementImpl::parseAttribute(AttributeImpl *attr)
+// void HTMLFrameElementImpl::parseAttribute(AttributeImpl *attr) {
+//   parseAttribute(attr, false)
+// }
+
+void HTMLFrameElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -291,11 +295,11 @@
         break;
     case ATTR_ONLOAD:
         setHTMLEventListener(EventImpl::LOAD_EVENT,
-            getDocument()->createHTMLEventListener(attr->value().string(), "onload", this));
+            getDocument()->createHTMLEventListener(attr->value().string(), "onload", this, hook));
         break;
     case ATTR_ONUNLOAD:
         setHTMLEventListener(EventImpl::UNLOAD_EVENT,
-            getDocument()->createHTMLEventListener(attr->value().string(), "onunload", this));
+            getDocument()->createHTMLEventListener(attr->value().string(), "onunload", this, hook));
         break;
     case ATTR_ID:
     case ATTR_NAME:
@@ -304,7 +308,7 @@
         name = attr->value();
         //fallthrough intentional, let the base handle it
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -470,7 +474,7 @@
     return ID_FRAMESET;
 }
 
-void HTMLFrameSetElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLFrameSetElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -503,15 +507,15 @@
             frameborder = false;
         break;
     case ATTR_ONLOAD:
-        m_onLoad = getDocument()->createHTMLEventListener(attr->value().string(), "onload", this);
+        m_onLoad = getDocument()->createHTMLEventListener(attr->value().string(), "onload", this, hook);
         getDocument()->setHTMLEventListener(EventImpl::LOAD_EVENT, m_onLoad);
         break;
     case ATTR_ONUNLOAD:
-        m_onUnLoad = getDocument()->createHTMLEventListener(attr->value().string(), "onunload", this);
+        m_onUnLoad = getDocument()->createHTMLEventListener(attr->value().string(), "onunload", this, hook);
         getDocument()->setHTMLEventListener(EventImpl::UNLOAD_EVENT, m_onUnLoad);
         break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -608,7 +612,7 @@
     return ID_IFRAME;
 }
 
-void HTMLIFrameElementImpl::parseAttribute(AttributeImpl *attr )
+void HTMLIFrameElementImpl::parseAttribute(AttributeImpl *attr, bool hook )
 {
     switch (  attr->id() )
     {
@@ -626,7 +630,7 @@
         break;
     case ATTR_SRC:
         needWidgetUpdate = true; // ### do this for scrolling, margins etc?
-        HTMLFrameElementImpl::parseAttribute( attr );
+        HTMLFrameElementImpl::parseAttribute( attr, hook );
         break;
     case ATTR_FRAMEBORDER:
     {
@@ -634,7 +638,7 @@
         if (attached()) updateFrame();
     }
     default:
-        HTMLFrameElementImpl::parseAttribute( attr );
+        HTMLFrameElementImpl::parseAttribute( attr, hook );
     }
 }
 
Index: khtml/html/htmlparser.h
===================================================================
--- khtml/html/htmlparser.h	(revision 607008)
+++ khtml/html/htmlparser.h	(working copy)
@@ -59,8 +59,8 @@
 
 namespace khtml {
 
-class Token;
-
+  class Token;
+  class HTMLTokenizer;
 /**
  * The parser for html. It receives a stream of tokens from the HTMLTokenizer, and
  * builds up the Document structure form it.
@@ -75,7 +75,7 @@
     /**
      * parses one token delivered by the tokenizer
      */
-    void parseToken(Token *_t);
+    DOM::NodeImpl* parseToken(Token *_t);
 
     /**
      * resets the parser
@@ -86,12 +86,11 @@
     bool noSpaces() const { return (inSelect || !m_inline  || !inBody); }
     bool selectMode() const { return inSelect; }
 
-    DOM::HTMLDocumentImpl *doc() const { return static_cast<DOM::HTMLDocumentImpl *>(document->document()); }
-    DOM::DocumentPtr *docPtr() const { return document; }
-
+  DOM::HTMLDocumentImpl *doc() const { return static_cast<DOM::HTMLDocumentImpl *>(document->document()); }
+  DOM::DocumentPtr *docPtr() const { return document; }
+  
 protected:
-
-    KHTMLView *HTMLWidget;
+  KHTMLView *HTMLWidget;
     DOM::DocumentPtr *document;
 
     /*
@@ -114,7 +113,8 @@
     }
 
 private:
-    DOM::NodeImpl *current;
+  friend class HTMLTokenizer; //want to access the current node 
+  DOM::NodeImpl *current;
 
     HTMLStackElem *blockStack;
 
Index: khtml/html/html_listimpl.h
===================================================================
--- khtml/html/html_listimpl.h	(revision 607008)
+++ khtml/html/html_listimpl.h	(working copy)
@@ -41,7 +41,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *);
+    virtual void parseAttribute(AttributeImpl *,bool hook);
 
     virtual int start() const { return 1; }
 };
@@ -76,7 +76,7 @@
         : HTMLUListElementImpl(doc), _start(1) {}
 
     virtual Id id() const;
-    virtual void parseAttribute(AttributeImpl *);
+    virtual void parseAttribute(AttributeImpl *,bool hook);
 
     int start() const { return _start; }
 private:
@@ -92,7 +92,7 @@
         : HTMLElementImpl(doc) {}
 
     virtual Id id() const;
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
     virtual void attach();
 };
 
Index: khtml/html/html_imageimpl.cpp
===================================================================
--- khtml/html/html_imageimpl.cpp	(revision 607008)
+++ khtml/html/html_imageimpl.cpp	(working copy)
@@ -76,7 +76,8 @@
     return ID_IMG;
 }
 
-void HTMLImageElementImpl::parseAttribute(AttributeImpl *attr)
+
+void HTMLImageElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch (attr->id())
     {
@@ -158,15 +159,15 @@
         break;
     case ATTR_ONABORT: // ### add support for this
         setHTMLEventListener(EventImpl::ABORT_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onabort", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onabort", this, hook));
         break;
     case ATTR_ONERROR:
         setHTMLEventListener(EventImpl::ERROR_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onerror", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onerror", this, hook));
         break;
     case ATTR_ONLOAD:
         setHTMLEventListener(EventImpl::LOAD_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onload", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onload", this, hook));
         break;
     case ATTR_NOSAVE:
 	break;
@@ -178,7 +179,7 @@
         m_name = attr->value();
         //fallthrough
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -399,13 +400,13 @@
     return false;
 }
 
-void HTMLMapElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLMapElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch (attr->id())
     {
     case ATTR_ID:
         if (getDocument()->htmlMode() != DocumentImpl::XHtml) {
-            HTMLElementImpl::parseAttribute(attr);
+            HTMLElementImpl::parseAttribute(attr,hook);
             break;
         } 
         else {
@@ -429,7 +430,7 @@
         //fallthrough
     }
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -455,7 +456,7 @@
     return ID_AREA;
 }
 
-void HTMLAreaElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLAreaElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch (attr->id())
     {
@@ -484,7 +485,7 @@
     case ATTR_ACCESSKEY:
         break;
     default:
-        HTMLAnchorElementImpl::parseAttribute(attr);
+        HTMLAnchorElementImpl::parseAttribute(attr, hook);
     }
 }
 
Index: khtml/html/html_inlineimpl.h
===================================================================
--- khtml/html/html_inlineimpl.h	(revision 607008)
+++ khtml/html/html_inlineimpl.h	(working copy)
@@ -38,7 +38,7 @@
 
     virtual bool isFocusable() const { return m_hasAnchor; }
     virtual Id id() const;
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
     virtual void defaultEventHandler(EventImpl *evt);
     void click();
 protected:
@@ -54,7 +54,7 @@
         : HTMLElementImpl(doc) {}
 
     virtual Id id() const;
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
     virtual void attach();
 };
 
@@ -67,7 +67,7 @@
         : HTMLElementImpl(doc) {}
 
     virtual Id id() const;
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
 };
 
 } //namespace
Index: khtml/html/html_elementimpl.cpp
===================================================================
--- khtml/html/html_elementimpl.cpp	(revision 607008)
+++ khtml/html/html_elementimpl.cpp	(working copy)
@@ -152,7 +152,7 @@
     return tn;
 }
 
-void HTMLElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     DOMString indexstring;
     switch( attr->id() )
@@ -213,51 +213,51 @@
 // standard events
     case ATTR_ONCLICK:
 	setHTMLEventListener(EventImpl::KHTML_ECMA_CLICK_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onclick", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onclick", this, hook));
         break;
     case ATTR_ONDBLCLICK:
 	setHTMLEventListener(EventImpl::KHTML_ECMA_DBLCLICK_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "ondblclick", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "ondblclick", this, hook));
         break;
     case ATTR_ONMOUSEDOWN:
         setHTMLEventListener(EventImpl::MOUSEDOWN_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onmousedown", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onmousedown", this, hook));
         break;
     case ATTR_ONMOUSEMOVE:
         setHTMLEventListener(EventImpl::MOUSEMOVE_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onmousemove", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onmousemove", this, hook));
         break;
     case ATTR_ONMOUSEOUT:
         setHTMLEventListener(EventImpl::MOUSEOUT_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onmouseout", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onmouseout", this, hook));
         break;
     case ATTR_ONMOUSEOVER:
         setHTMLEventListener(EventImpl::MOUSEOVER_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onmouseover", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onmouseover", this, hook));
         break;
     case ATTR_ONMOUSEUP:
         setHTMLEventListener(EventImpl::MOUSEUP_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onmouseup", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onmouseup", this, hook));
         break;
     case ATTR_ONKEYDOWN:
         setHTMLEventListener(EventImpl::KEYDOWN_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeydown", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeydown", this, hook));
 	break;
     case ATTR_ONKEYPRESS:
         setHTMLEventListener(EventImpl::KEYPRESS_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeypress", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeypress", this, hook));
 	break;
     case ATTR_ONKEYUP:
         setHTMLEventListener(EventImpl::KEYUP_EVENT,
-	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeyup", this));
+	    getDocument()->createHTMLEventListener(attr->value().string(), "onkeyup", this, hook));
         break;
     case ATTR_ONFOCUS:
         setHTMLEventListener(EventImpl::FOCUS_EVENT,
-            getDocument()->createHTMLEventListener(attr->value().string(), "onfocus", this));
+            getDocument()->createHTMLEventListener(attr->value().string(), "onfocus", this, hook));
         break;
     case ATTR_ONBLUR:
         setHTMLEventListener(EventImpl::BLUR_EVENT,
-            getDocument()->createHTMLEventListener(attr->value().string(), "onblur", this));
+            getDocument()->createHTMLEventListener(attr->value().string(), "onblur", this, hook));
         break;
 // other misc attributes
     default:
Index: khtml/html/html_tableimpl.h
===================================================================
--- khtml/html/html_tableimpl.h	(revision 607008)
+++ khtml/html/html_tableimpl.h	(working copy)
@@ -57,7 +57,7 @@
         : HTMLElementImpl(doc)
         { }
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
 };
 
 // -------------------------------------------------------------------------
@@ -119,7 +119,7 @@
     int rowSpan() const { return rSpan; }
 
     virtual Id id() const { return _id; }
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
     virtual void attach();
 
 protected:
@@ -145,7 +145,7 @@
     void setTable(HTMLTableElementImpl *t) { table = t; }
 
     // overrides
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
 
     int span() const { return _span; }
 
@@ -167,7 +167,7 @@
         : HTMLTablePartElementImpl(doc) {}
 
     virtual Id id() const;
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
 };
 
 // -------------------------------------------------------------------------
@@ -281,7 +281,7 @@
     virtual NodeImpl *removeChild ( NodeImpl *oldChild, int &exceptioncode );
     virtual NodeImpl *appendChild ( NodeImpl *newChild, int &exceptioncode );
     
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
     virtual void attach();
     virtual void close();
 
Index: khtml/html/htmltokenizer.h
===================================================================
--- khtml/html/htmltokenizer.h	(revision 607008)
+++ khtml/html/htmltokenizer.h	(working copy)
@@ -152,7 +152,8 @@
     void parseEntity(khtml::TokenizerString &str, QChar *&dest, bool start = false);
     void parseProcessingInstruction(khtml::TokenizerString &str);
     void scriptHandler();
-    void scriptExecution(const QString& script, const QString& scriptURL = QString::null, int baseLine = 0);
+    void scriptExecution(const QString& script, const QString& scriptURL = QString::null, 
+			 int baseLine = 0, DOM::NodeImpl *scriptElementNode = 0);
     void setSrc(const TokenizerString& source);
 
     // check if we have enough space in the buffer.
@@ -180,7 +181,8 @@
     QChar *buffer;
     QChar *dest;
 
-    khtml::Token currToken;
+  khtml::Token currToken;
+  DOM::NodeImpl* currTokenNode;
 
     // the size of buffer
     int size;
Index: khtml/html/html_blockimpl.h
===================================================================
--- khtml/html/html_blockimpl.h	(revision 607008)
+++ khtml/html/html_blockimpl.h	(working copy)
@@ -39,7 +39,7 @@
     HTMLDivElementImpl(DocumentPtr *doc, ushort _tagid)
         : HTMLGenericElementImpl(doc, _tagid) {}
 
-    virtual void parseAttribute(AttributeImpl *token);
+    virtual void parseAttribute(AttributeImpl *token, bool hook);
 };
 
 // -------------------------------------------------------------------------
@@ -51,7 +51,7 @@
         : HTMLElementImpl(doc) {}
 
     virtual NodeImpl::Id id() const;
-    virtual void parseAttribute(AttributeImpl *);
+    virtual void parseAttribute(AttributeImpl *, bool hook);
     virtual void attach();
 };
 
@@ -75,7 +75,7 @@
     HTMLMarqueeElementImpl(DocumentPtr *doc);
 
     virtual NodeImpl::Id id() const;
-    virtual void parseAttribute(AttributeImpl *token);
+    virtual void parseAttribute(AttributeImpl *token, bool hook);
 
     int minimumDelay() const { return m_minimumDelay; }
 
@@ -90,7 +90,7 @@
 public:
     HTMLLayerElementImpl( DocumentPtr *doc, ushort _tagid );
 
-    virtual void parseAttribute(AttributeImpl *);
+    virtual void parseAttribute(AttributeImpl *,bool hook);
     virtual NodeImpl *addChild(NodeImpl *child);
 
     virtual void removedFromDocument();
Index: khtml/html/html_headimpl.h
===================================================================
--- khtml/html/html_headimpl.h	(revision 607008)
+++ khtml/html/html_headimpl.h	(working copy)
@@ -53,7 +53,7 @@
     DOMString target() const { return m_target; }
 
     virtual Id id() const;
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
 
@@ -83,7 +83,7 @@
     StyleSheetImpl* sheet() { return m_sheet; }
 
     // overload from HTMLElementImpl
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
 
     void process();
 
@@ -123,7 +123,7 @@
         : HTMLElementImpl(doc) {}
 
     virtual Id id() const;
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
     virtual void insertedIntoDocument();
 
     void process();
@@ -194,7 +194,7 @@
     CSSStyleSheetImpl *sheet() { return m_sheet; }
 
     // overload from HTMLElementImpl
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
     virtual void childrenChanged();
Index: khtml/html/html_formimpl.h
===================================================================
--- khtml/html/html_formimpl.h	(revision 607008)
+++ khtml/html/html_formimpl.h	(working copy)
@@ -87,7 +87,7 @@
     void doAutoFill();
     void walletOpened(KWallet::Wallet *w);
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
 
     void radioClicked( HTMLGenericFormElementImpl *caller );
 
@@ -142,7 +142,7 @@
 
     HTMLFormElementImpl *form() { return m_form; }
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
     virtual void attach();
     virtual void reset() {}
 
@@ -204,7 +204,7 @@
 
     DOMString type() const;
     typeEnum buttonType() const { return m_type; }
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
     virtual void defaultEventHandler(EventImpl *evt);
     virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
     void activate();
@@ -233,7 +233,7 @@
 
     virtual Id id() const;
     virtual void attach();
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
 
 };
 
@@ -294,7 +294,7 @@
     void select();
     void click();
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
 
     virtual void attach();
     virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
@@ -369,7 +369,7 @@
 
     virtual Id id() const;
     virtual void attach();
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
 };
 
 
@@ -420,7 +420,7 @@
 
     virtual void childrenChanged();
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
 
     virtual void attach();
     virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
@@ -469,7 +469,7 @@
     // ### this is just a rough guess
     virtual bool isEnumeratable() const { return false; }
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
     virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
 
 };
@@ -502,7 +502,7 @@
 
     long index() const;
     void setIndex( long );
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
     DOMString value() const;
     void setValue(DOMStringImpl* value);
 
@@ -551,7 +551,7 @@
 
     void select (  );
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
     virtual void attach();
     virtual bool encoding(const QTextCodec*, khtml::encodingList&, bool);
     virtual void reset();
@@ -592,7 +592,7 @@
     ~HTMLIsIndexElementImpl();
 
     virtual Id id() const;
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
 
     DOMString prompt() const;
     void setPrompt(const DOMString& _value);
Index: khtml/html/htmlparser.cpp
===================================================================
--- khtml/html/htmlparser.cpp	(revision 607008)
+++ khtml/html/htmlparser.cpp	(working copy)
@@ -206,12 +206,12 @@
     discard_until = 0;
 }
 
-void KHTMLParser::parseToken(Token *t)
+DOM::NodeImpl* KHTMLParser::parseToken(Token *t)
 {
     if (t->tid > 2*ID_CLOSE_TAG)
     {
       kdDebug( 6035 ) << "Unknown tag!! tagID = " << t->tid << endl;
-      return;
+      return 0;
     }
     if(discard_until) {
         if(t->tid == discard_until)
@@ -219,7 +219,7 @@
 
         // do not skip </iframe>
         if ( discard_until || current->id() + ID_CLOSE_TAG != t->tid )
-            return;
+            return 0;
     }
 
 #ifdef PARSER_DEBUG
@@ -236,7 +236,7 @@
     if(t->tid > ID_CLOSE_TAG)
     {
         processCloseTag(t);
-        return;
+        return 0;
     }
 
     // ignore spaces, if we're not inside a paragraph or other inline code
@@ -253,7 +253,7 @@
     NodeImpl *n = getElement(t);
     // just to be sure, and to catch currently unimplemented stuff
     if(!n)
-        return;
+        return 0;
 
     // set attributes
     if(n->isElementNode() && t->tid != ID_ISINDEX)
@@ -306,7 +306,9 @@
             form = 0;
         }
         delete n;
+	return 0;
     }
+    return n;
 }
 
 static bool isTableRelatedTag(int id)
Index: khtml/html/html_objectimpl.h
===================================================================
--- khtml/html/html_objectimpl.h	(revision 607008)
+++ khtml/html/html_objectimpl.h	(working copy)
@@ -42,7 +42,7 @@
 public:
     HTMLObjectBaseElementImpl(DocumentPtr *doc);
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
     virtual void attach();
 
     virtual void recalcStyle( StyleChange ch );
@@ -78,7 +78,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *token);
+    virtual void parseAttribute(AttributeImpl *token, bool hook);
     virtual void attach();
 protected:
     khtml::VAlign valign;
@@ -94,7 +94,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
     virtual void attach();
 
     QString pluginPage;
@@ -114,7 +114,7 @@
 
     HTMLFormElementImpl *form() const;
 
-    virtual void parseAttribute(AttributeImpl *token);
+    virtual void parseAttribute(AttributeImpl *token,bool hook);
 
     virtual void attach();
 
@@ -131,7 +131,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *token);
+    virtual void parseAttribute(AttributeImpl *token, bool hook);
 
     QString name() const { return m_name; }
     QString value() const { return m_value; }
Index: khtml/html/html_listimpl.cpp
===================================================================
--- khtml/html/html_listimpl.cpp	(revision 607008)
+++ khtml/html/html_listimpl.cpp	(working copy)
@@ -37,7 +37,7 @@
     return ID_UL;
 }
 
-void HTMLUListElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLUListElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -45,7 +45,7 @@
         addCSSProperty(CSS_PROP_LIST_STYLE_TYPE, attr->value());
         break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -70,7 +70,7 @@
     return ID_OL;
 }
 
-void HTMLOListElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLOListElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -90,7 +90,7 @@
         _start = attr->val() ? attr->val()->toInt() : 1;
         break;
     default:
-        HTMLUListElementImpl::parseAttribute(attr);
+        HTMLUListElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -101,7 +101,7 @@
     return ID_LI;
 }
 
-void HTMLLIElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLLIElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -124,7 +124,7 @@
             addCSSProperty(CSS_PROP_LIST_STYLE_TYPE, attr->value());
         break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
Index: khtml/html/html_inlineimpl.cpp
===================================================================
--- khtml/html/html_inlineimpl.cpp	(revision 607008)
+++ khtml/html/html_inlineimpl.cpp	(working copy)
@@ -170,7 +170,7 @@
     dispatchMouseEvent(&me,EventImpl::CLICK_EVENT, 1);
 }
 
-void HTMLAnchorElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLAnchorElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -187,7 +187,7 @@
     case ATTR_ACCESSKEY:
         break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -198,7 +198,7 @@
     return ID_BR;
 }
 
-void HTMLBRElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLBRElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -211,7 +211,7 @@
         break;
     }
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -241,7 +241,7 @@
     return ID_FONT;
 }
 
-void HTMLFontElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLFontElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -286,7 +286,7 @@
         addCSSProperty(CSS_PROP_FONT_FAMILY, attr->value());
         break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
Index: khtml/html/html_baseimpl.h
===================================================================
--- khtml/html/html_baseimpl.h	(revision 607008)
+++ khtml/html/html_baseimpl.h	(working copy)
@@ -58,7 +58,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *);
+    virtual void parseAttribute(AttributeImpl *, bool hook);
     virtual void attach();
 
     virtual void insertedIntoDocument();
@@ -86,7 +86,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *);
+    virtual void parseAttribute(AttributeImpl *, bool hook);
     virtual void attach();
 
     bool noResize() { return noresize; }
@@ -122,7 +122,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *);
+    virtual void parseAttribute(AttributeImpl *, bool hook);
     virtual void attach();
 
     virtual void defaultEventHandler(EventImpl *evt);
@@ -188,7 +188,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr,bool hook);
     virtual void attach();
     virtual void recalcStyle( StyleChange ch );
 
Index: khtml/html/html_tableimpl.cpp
===================================================================
--- khtml/html/html_tableimpl.cpp	(revision 607008)
+++ khtml/html/html_tableimpl.cpp	(working copy)
@@ -406,7 +406,7 @@
     return HTMLElementImpl::removeChild( oldChild, exceptioncode);
 }
 
-void HTMLTableElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLTableElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     // ### to CSS!!
     switch(attr->id())
@@ -551,7 +551,7 @@
     case ATTR_NOSAVE:
 	break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -594,7 +594,7 @@
 
 // --------------------------------------------------------------------------
 
-void HTMLTablePartElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLTablePartElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -658,7 +658,7 @@
     case ATTR_NOSAVE:
 	break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -862,7 +862,7 @@
     return index;
 }
 
-void HTMLTableCellElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLTableCellElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -897,7 +897,7 @@
     case ATTR_NOSAVE:
 	break;
     default:
-        HTMLTablePartElementImpl::parseAttribute(attr);
+        HTMLTablePartElementImpl::parseAttribute(attr, hook);
     }
 }
 
@@ -946,7 +946,7 @@
 }
 
 
-void HTMLTableColElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLTableColElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -966,7 +966,7 @@
             removeCSSProperty(CSS_PROP_VERTICAL_ALIGN);
         break;
     default:
-        HTMLTablePartElementImpl::parseAttribute(attr);
+        HTMLTablePartElementImpl::parseAttribute(attr, hook);
     }
 
 }
@@ -979,7 +979,7 @@
 }
 
 
-void HTMLTableCaptionElementImpl::parseAttribute(AttributeImpl *attr)
+void HTMLTableCaptionElementImpl::parseAttribute(AttributeImpl *attr, bool hook)
 {
     switch(attr->id())
     {
@@ -990,7 +990,7 @@
             removeCSSProperty(CSS_PROP_CAPTION_SIDE);
         break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLElementImpl::parseAttribute(attr, hook);
     }
 
 }
Index: khtml/html/html_imageimpl.h
===================================================================
--- khtml/html/html_imageimpl.h	(revision 607008)
+++ khtml/html/html_imageimpl.h	(working copy)
@@ -45,7 +45,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *);
+    virtual void parseAttribute(AttributeImpl *, bool hook);
 
     virtual void attach();
     virtual void removedFromDocument();
@@ -100,7 +100,7 @@
 
     virtual Id id() const;
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
 
     bool isDefault() const { return shape==Default; }
 
@@ -135,7 +135,7 @@
 
     virtual DOMString getName() const { return name; }
 
-    virtual void parseAttribute(AttributeImpl *attr);
+    virtual void parseAttribute(AttributeImpl *attr, bool hook);
 
     bool mapMouseEvent(int x_, int y_, int width_, int height_,
                        khtml::RenderObject::NodeInfo& info);
Index: khtml/ecma/kjs_proxy.h
===================================================================
--- khtml/ecma/kjs_proxy.h	(revision 607008)
+++ khtml/ecma/kjs_proxy.h	(working copy)
@@ -55,9 +55,12 @@
 public:
   KJSProxy() { m_handlerLineno = 0; }
   virtual ~KJSProxy() { }
-  virtual QVariant evaluate(QString filename, int baseLine, const QString &, const DOM::Node &n,
-			    KJS::Completion *completion = 0) = 0;
+  virtual QVariant evaluate(QString filename, int baseLine, const QString &, 
+			    const DOM::Node &n, KJS::Completion *completion = 0,
+			    DOM::NodeImpl *curnode = 0) = 0;
+			    
   virtual void clear() = 0;
+  virtual DOM::EventListener *createHTMLEventHandler(QString sourceUrl, QString name, QString code, DOM::NodeImpl* node, bool hook) = 0;
   virtual DOM::EventListener *createHTMLEventHandler(QString sourceUrl, QString name, QString code, DOM::NodeImpl* node) = 0;
   virtual void finishedWithEvent(const DOM::Event &event) = 0;
   virtual KJS::Interpreter *interpreter() = 0;
Index: khtml/ecma/xmlhttprequest.cpp
===================================================================
--- khtml/ecma/xmlhttprequest.cpp	(revision 607008)
+++ khtml/ecma/xmlhttprequest.cpp	(working copy)
@@ -341,8 +341,15 @@
     if(contentType.isNull())
       job->addMetaData( "content-type", "Content-type: text/plain" );
     else
-      job->addMetaData( "content-type", contentType );
+      job->addMetaData( "content-type", contentType);
   }
+  else if (method == "put") {
+    QByteArray buf;
+    buf.duplicate(_body.utf8().data(), _body.length());
+    
+    job = KIO::storedPut(buf, url, -1, false, false);
+    job->addMetaData( "content-type", "Content-type: text/html" );
+  }
   else {
     job = KIO::get( url, false, false );
   }
@@ -356,7 +363,6 @@
         rh += "\r\n";
       rh += i.key() + ": " + i.data();
     }
-
     job->addMetaData("customHTTPHeader", rh);
   }
 
Index: khtml/ecma/kjs_proxy.cpp
===================================================================
--- khtml/ecma/kjs_proxy.cpp	(revision 607008)
+++ khtml/ecma/kjs_proxy.cpp	(working copy)
@@ -20,6 +20,7 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <stdio.h>
 #include <config.h>
 
 #if defined(HAVE_VALGRIND_MEMCHECK_H) && !defined(NDEBUG)
@@ -31,11 +32,13 @@
 
 
 #include "kjs_proxy.h"
-
+#include "misc/htmlattrs.h"
 #include "kjs_window.h"
 #include "kjs_events.h"
 #include "kjs_debugwin.h"
 #include "xml/dom_nodeimpl.h"
+#include "xml/dom_elementimpl.h"
+#include "dom/dom_string.h"
 #include "khtmlpart_p.h"
 #include <khtml_part.h>
 #include <kprotocolmanager.h>
@@ -47,6 +50,10 @@
 #include <sys/time.h>
 #include <assert.h>
 #include <kjs/function.h>
+#include <kjs/context.h>
+#include <kjs/object.h>
+#include <kjs/list.h>
+//#include <kjs/nodes.h>
 
 using namespace KJS;
 
@@ -60,9 +67,16 @@
 public:
   KJSProxyImpl(khtml::ChildFrame *frame);
   virtual ~KJSProxyImpl();
-  virtual QVariant evaluate(QString filename, int baseLine, const QString &, const DOM::Node &n,
-			    Completion *completion = 0);
+  bool runTimedHook(KJS::ScriptInterpreter *interp, KJS::Value thisNode, 
+		    UString &code, DOM::NodeImpl *curnode);
+  bool runHook(KJS::ScriptInterpreter *interp, KJS::Value thisNode, 
+	       UString &code, DOM::NodeImpl *curnode);
+  virtual QVariant evaluate(QString filename, int baseLine, const QString &, 
+			    const DOM::Node &n,Completion *completion = 0,
+			    DOM::NodeImpl *curnode = 0);
+  
   virtual void clear();
+  virtual DOM::EventListener *createHTMLEventHandler(QString sourceUrl, QString name, QString code, DOM::NodeImpl *node, bool hook);
   virtual DOM::EventListener *createHTMLEventHandler(QString sourceUrl, QString name, QString code, DOM::NodeImpl *node);
   virtual void finishedWithEvent(const DOM::Event &event);
   virtual KJS::Interpreter *interpreter();
@@ -85,6 +99,7 @@
 
 } // namespace KJS
 
+
 #ifndef NDEBUG
 int KJSProxyImpl::s_count = 0;
 #endif
@@ -128,8 +143,118 @@
 #endif
 }
 
+static FILE *timerLogFile = 0;
+static int logEntryCount = 0;
+#include <sys/timeb.h>
+
+void closeJSSecurityLog() {
+  if(!timerLogFile)
+    return;
+  fclose(timerLogFile);
+}
+
+bool KJSProxyImpl::runTimedHook(KJS::ScriptInterpreter *interp, 
+				KJS::Value thisNode, 
+				UString &code, 
+				DOM::NodeImpl *curnode) {
+  if(!timerLogFile) {
+    timerLogFile = fopen("jssecurity.log", "a");
+  }
+  struct timeb startTime;
+  struct timeb endTime;
+
+  ftime(&startTime);
+  bool result = runHook(interp, thisNode, code, curnode);
+  ftime(&endTime);
+
+  double elapsedTime = 
+    (endTime.time + (endTime.millitm * 0.001)) -
+    (startTime.time + (startTime.millitm * 0.001));
+  
+  const char *msg = 0;
+  QString script = QString::fromLatin1("SCRIPT");
+  const char *ctx = 0;
+  if(curnode && curnode->isElementNode()) {
+    DOM::ElementImpl *el = (DOM::ElementImpl*)curnode;
+    if(el->tagName().string() == script) {
+      DOM::DOMString srcatt = el->getAttribute(ATTR_SRC);
+      if(srcatt.length() > 0) {
+	msg = srcatt.string().latin1();
+	ctx = "SRC ATT";
+      }
+    }
+  }
+  
+  if(!msg) {
+    if(code.size() > 50) {
+      msg = code.substr(0, 50).ascii();
+    }
+    else {
+      msg = code.ascii();
+    }
+    ctx = "CODE";
+  }
+  
+  fprintf(timerLogFile, "%d: Result = %s Time = %f Context=%s Val=%s\n", ++logEntryCount, result ? "AUTH" : "DENY", elapsedTime, ctx, msg);
+  fflush(timerLogFile);
+  return result;
+}
+
+bool KJSProxyImpl::runHook(KJS::ScriptInterpreter *interp, KJS::Value thisNode, 
+			   UString &code, DOM::NodeImpl *curnode) {
+  ExecState *exec = interp->globalExec();
+
+  //can we cache this lookup? 
+  //must be careful a stale hook is not applied to a document
+  //for now ... no caching
+  UString windowHook("window.top.JSSecurity.afterParseHook");
+  Completion comp = interp->evaluate(windowHook, Window::retrieve(m_frame->m_part));
+
+  if(comp.value().type() == KJS::UndefinedType)
+    return true; //permissive backward compatibility; default allow
+  
+  if((comp.complType() == Normal || 
+      comp.complType() == ReturnValue) &&
+     comp.isValueCompletion()) {
+    Object hookFunc = comp.value().toObject(exec);
+    //       Identifier hookIdent("hook");
+    //       fprintf(stderr, "runHook 3\n");
+    //     Object hookFunc = exec->lookupIdentifier(hookIdent);
+    if(!hookFunc.isValid() || !hookFunc.implementsCall()) {
+      fprintf(stderr, "window.hook is not a function\n");
+      return true;
+    }
+    Object nullObj = Object::dynamicCast(Null());
+    List args;
+    if(curnode && curnode->isElementNode()) {
+      DOM::Node n(curnode);
+      DOM::Element e(n);
+      //can't stack allocate this thing ... 
+      //looks like KJS calls this function in a different context 
+      //reliable crash if I stack allocate
+      DOMElement *de = new DOMElement(exec, e); //instance of ObjectImp
+      Object curnodeObject (de);
+      args.append(curnodeObject);
+    }
+    else {
+      args.append(Undefined()); //don't have the current element
+    }
+    String codeArg(code);
+    //pass in the code of the script that's being loaded
+    args.append(codeArg); 
+    Value result = hookFunc.call((KJS::ExecState *)exec, 
+				 interp->globalObject(),  //hook always executes in the context of "window"
+				 args);
+    //do some error checking on result ... the hook can throw an exception
+    //i.e. check result.type() == BooleanType
+    return result.toBoolean(exec);
+  }
+  return true;
+}
+
 QVariant KJSProxyImpl::evaluate(QString filename, int baseLine,
-                                const QString&str, const DOM::Node &n, Completion *completion) {
+                                const QString&str, const DOM::Node &n, 
+				Completion *completion, DOM::NodeImpl *currentNode) {
   // evaluate code. Returns the JS return value or an invalid QVariant
   // if there was none, an error occurred or the type couldn't be converted.
 
@@ -158,10 +283,12 @@
   KJS::Value thisNode = n.isNull() ? Window::retrieve( m_frame->m_part ) : getDOMNode(m_script->globalExec(),n);
 
   UString code( str );
-
+  //  fprintf(stderr, "NKS: About to evaluate script: %s\n", code.ascii());
+  
   KJSCPUGuard guard;
   guard.start();
-  Completion comp = m_script->evaluate(code, thisNode);
+  Completion comp = runTimedHook(m_script, thisNode, code, currentNode) ? 
+    m_script->evaluate(code, thisNode) : Completion();//Throw, Undefined());
   guard.stop();
 
   bool success = ( comp.complType() == Normal ) || ( comp.complType() == ReturnValue );
@@ -237,10 +364,10 @@
   }
 }
 
-DOM::EventListener *KJSProxyImpl::createHTMLEventHandler(QString sourceUrl, QString name, QString code, DOM::NodeImpl *node)
-{
+DOM::EventListener *KJSProxyImpl::createHTMLEventHandler(QString sourceUrl, QString name, 
+							 QString code, DOM::NodeImpl *node, bool hook) {
   initScript();
-
+  
 #ifdef KJS_DEBUGGER
   if (KJSDebugWin::debugWindow()) {
     KJSDebugWin::debugWindow()->attach(m_script);
@@ -249,8 +376,16 @@
 #else
   Q_UNUSED(sourceUrl);
 #endif
+  UString _code(code);
+  if(!hook || runTimedHook(m_script, Undefined(), _code, node)) {
+    return KJS::Window::retrieveWindow(m_frame->m_part)->getJSLazyEventListener(code,name,node);
+  }
+  return 0;
+}
 
-  return KJS::Window::retrieveWindow(m_frame->m_part)->getJSLazyEventListener(code,name,node);
+DOM::EventListener *KJSProxyImpl::createHTMLEventHandler(QString sourceUrl, QString name, QString code, DOM::NodeImpl *node)
+{
+  return createHTMLEventHandler(sourceUrl, name, code, node, false);
 }
 
 void KJSProxyImpl::finishedWithEvent(const DOM::Event &event)
Index: khtml/xml/dom_elementimpl.cpp
===================================================================
--- khtml/xml/dom_elementimpl.cpp	(revision 607008)
+++ khtml/xml/dom_elementimpl.cpp	(working copy)
@@ -361,6 +361,7 @@
         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
         return;
     }
+    
     attributes()->setValue(id, value.implementation(), (qName.isEmpty() ? 0: qName.implementation()));
     attributeChanged(id);
 }
@@ -394,6 +395,10 @@
     attributeChanged(id);
 }
 
+//this should only be called directly from the htmlparser; 
+//it is not exposed from dom_element.h which is the interfaced used by KJS
+//so all event handlers installed through this function should 
+//should be authorized by the hook
 void ElementImpl::setAttributeMap( NamedAttrMapImpl* list )
 {
     // If setting the whole map changes the id attribute, we need to
@@ -418,7 +423,8 @@
         namedAttrMap->setElement(this);
         unsigned long len = namedAttrMap->length();
         for (unsigned long i = 0; i < len; i++)
-            parseAttribute(&namedAttrMap->m_attrs[i]);
+	  //true signals that the hook should run; see comment at top of function definition
+	  parseAttribute(&namedAttrMap->m_attrs[i], true);
     }
 }
 
Index: khtml/xml/dom_elementimpl.h
===================================================================
--- khtml/xml/dom_elementimpl.h	(revision 607008)
+++ khtml/xml/dom_elementimpl.h	(working copy)
@@ -172,7 +172,10 @@
     }
 
     //This is always called, whenever an attribute changed
-    virtual void parseAttribute(AttributeImpl *) {}
+    virtual void parseAttribute(AttributeImpl *a, bool hook) { }
+  
+    void parseAttribute(AttributeImpl *a) { parseAttribute(a, false); }
+  
     void parseAttribute(NodeImpl::Id attrId, DOMStringImpl *value) {
 	AttributeImpl aimpl;
 	aimpl.m_attrId = attrId;
@@ -180,6 +183,7 @@
 	parseAttribute(&aimpl);
     }
 
+
     // not part of the DOM
     void setAttributeMap ( NamedAttrMapImpl* list );
 
Index: khtml/xml/dom_docimpl.cpp
===================================================================
--- khtml/xml/dom_docimpl.cpp	(revision 607008)
+++ khtml/xml/dom_docimpl.cpp	(working copy)
@@ -2469,9 +2469,14 @@
     return m_windowEventListeners.hasEventListener(id);
 }
 
+EventListener *DocumentImpl::createHTMLEventListener(const QString& code, const QString& name, NodeImpl* node, bool hook) {
+  return part() ? 
+    (hook ? part()->createHTMLEventListener(code, name, node) : part()->createHTMLEventListenerNoHook(code, name, node)) : 0;
+}
+
 EventListener *DocumentImpl::createHTMLEventListener(const QString& code, const QString& name, NodeImpl* node)
 {
-    return part() ? part()->createHTMLEventListener(code, name, node) : 0;
+  return createHTMLEventListener(code, name, node, false);
 }
 
 void DocumentImpl::dispatchImageLoadEventSoon(HTMLImageElementImpl *image)
Index: khtml/xml/dom_docimpl.h
===================================================================
--- khtml/xml/dom_docimpl.h	(revision 607008)
+++ khtml/xml/dom_docimpl.h	(working copy)
@@ -449,6 +449,7 @@
     virtual void setHTMLWindowEventListener(int id, EventListener *listener);
     EventListener *getHTMLWindowEventListener(int id);
     EventListener *createHTMLEventListener(const QString& code, const QString& name, NodeImpl* node);
+    EventListener *createHTMLEventListener(const QString& code, const QString& name, NodeImpl* node, bool hook);
 
     void addWindowEventListener(int id, EventListener *listener, const bool useCapture);
     void removeWindowEventListener(int id, EventListener *listener, bool useCapture);
Index: kjs/crypto_object.cpp
===================================================================
--- kjs/crypto_object.cpp	(revision 0)
+++ kjs/crypto_object.cpp	(revision 0)
@@ -0,0 +1,659 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <assert.h>
+#include <iostream>
+
+#include "value.h"
+#include "object.h"
+#include "types.h"
+#include "interpreter.h"
+#include "operations.h"
+#include "crypto_object.h"
+
+#include "crypto_object.lut.h"
+
+/**
+ * ------------------------------ SHA1 ------------------------------
+ */
+/* h files included here to make this just one file ... */
+
+/* global.h */
+
+#ifndef _GLOBAL_H_
+#define _GLOBAL_H_ 1
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT4 defines a four byte word */
+typedef unsigned long int UINT4;
+
+/* BYTE defines a unsigned character */
+typedef unsigned char BYTE;
+
+#ifndef TRUE
+  #define FALSE	0
+  #define TRUE	( !FALSE )
+#endif /* TRUE */
+
+#endif /* end _GLOBAL_H_ */
+
+/* sha.h */
+
+#ifndef _SHA_H_
+#define _SHA_H_ 1
+
+/* #include "global.h" */
+
+/* The structure for storing SHS info */
+
+typedef struct 
+{
+	UINT4 digest[ 5 ];            /* Message digest */
+	UINT4 countLo, countHi;       /* 64-bit bit count */
+	UINT4 data[ 16 ];             /* SHS data buffer */
+	int Endianness;
+} SHA_CTX;
+
+/* Message digest functions */
+
+void SHAInit(SHA_CTX *);
+void SHAUpdate(SHA_CTX *, BYTE *buffer, int count);
+void SHAFinal(BYTE *output, SHA_CTX *);
+
+#endif /* end _SHA_H_ */
+
+/* endian.h */
+
+#ifndef _ENDIAN_H_
+#define _ENDIAN_H_ 1
+
+void endianTest(int *endianness);
+
+#endif /* end _ENDIAN_H_ */
+
+/* sha.c */
+
+#include <stdio.h>
+#include <string>
+
+static void SHAtoByte(BYTE *output, UINT4 *input, unsigned int len);
+
+/* The SHS block size and message digest sizes, in bytes */
+
+#define SHS_DATASIZE    64
+#define SHS_DIGESTSIZE  20
+
+
+/* The SHS f()-functions.  The f1 and f3 functions can be optimized to
+   save one boolean operation each - thanks to Rich Schroeppel,
+   rcs@cs.arizona.edu for discovering this */
+
+/*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) )          // Rounds  0-19 */
+#define f1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )           /* Rounds  0-19 */
+#define f2(x,y,z)   ( x ^ y ^ z )                       /* Rounds 20-39 */
+/*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) )   // Rounds 40-59 */
+#define f3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )   /* Rounds 40-59 */
+#define f4(x,y,z)   ( x ^ y ^ z )                       /* Rounds 60-79 */
+
+/* The SHS Mysterious Constants */
+
+#define K1  0x5A827999L                                 /* Rounds  0-19 */
+#define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
+#define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
+#define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
+
+/* SHS initial values */
+
+#define h0init  0x67452301L
+#define h1init  0xEFCDAB89L
+#define h2init  0x98BADCFEL
+#define h3init  0x10325476L
+#define h4init  0xC3D2E1F0L
+
+/* Note that it may be necessary to add parentheses to these macros if they
+   are to be called with expressions as arguments */
+/* 32-bit rotate left - kludged with shifts */
+
+#define ROTL(n,X)  ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
+
+/* The initial expanding function.  The hash function is defined over an
+   80-UINT2 expanded input array W, where the first 16 are copies of the input
+   data, and the remaining 64 are defined by
+
+        W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
+
+   This implementation generates these values on the fly in a circular
+   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
+   optimization.
+
+   The updated SHS changes the expanding function by adding a rotate of 1
+   bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
+   for this information */
+
+#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
+                                                 W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
+
+
+/* The prototype SHS sub-round.  The fundamental sub-round is:
+
+        a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
+        b' = a;
+        c' = ROTL( 30, b );
+        d' = c;
+        e' = d;
+
+   but this is implemented by unrolling the loop 5 times and renaming the
+   variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
+   This code is then replicated 20 times for each of the 4 functions, using
+   the next 20 values from the W[] array each time */
+
+#define subRound(a, b, c, d, e, f, k, data) \
+    ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
+
+/* Initialize the SHS values */
+
+void SHAInit(SHA_CTX *shsInfo)
+{
+    endianTest(&shsInfo->Endianness);
+    /* Set the h-vars to their initial values */
+    shsInfo->digest[ 0 ] = h0init;
+    shsInfo->digest[ 1 ] = h1init;
+    shsInfo->digest[ 2 ] = h2init;
+    shsInfo->digest[ 3 ] = h3init;
+    shsInfo->digest[ 4 ] = h4init;
+
+    /* Initialise bit count */
+    shsInfo->countLo = shsInfo->countHi = 0;
+}
+
+
+/* Perform the SHS transformation.  Note that this code, like MD5, seems to
+   break some optimizing compilers due to the complexity of the expressions
+   and the size of the basic block.  It may be necessary to split it into
+   sections, e.g. based on the four subrounds
+
+   Note that this corrupts the shsInfo->data area */
+
+static void SHSTransform(UINT4 *digest, UINT4 *data)
+    {
+    UINT4 A, B, C, D, E;     /* Local vars */
+    UINT4 eData[ 16 ];       /* Expanded data */
+
+    /* Set up first buffer and local data buffer */
+    A = digest[ 0 ];
+    B = digest[ 1 ];
+    C = digest[ 2 ];
+    D = digest[ 3 ];
+    E = digest[ 4 ];
+    memcpy( (POINTER)eData, (POINTER)data, SHS_DATASIZE );
+
+    /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
+    subRound( A, B, C, D, E, f1, K1, eData[  0 ] );
+    subRound( E, A, B, C, D, f1, K1, eData[  1 ] );
+    subRound( D, E, A, B, C, f1, K1, eData[  2 ] );
+    subRound( C, D, E, A, B, f1, K1, eData[  3 ] );
+    subRound( B, C, D, E, A, f1, K1, eData[  4 ] );
+    subRound( A, B, C, D, E, f1, K1, eData[  5 ] );
+    subRound( E, A, B, C, D, f1, K1, eData[  6 ] );
+    subRound( D, E, A, B, C, f1, K1, eData[  7 ] );
+    subRound( C, D, E, A, B, f1, K1, eData[  8 ] );
+    subRound( B, C, D, E, A, f1, K1, eData[  9 ] );
+    subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
+    subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
+    subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
+    subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
+    subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
+    subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
+    subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
+    subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
+    subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
+    subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
+
+    subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
+    subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
+    subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
+    subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
+    subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
+    subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
+    subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
+    subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
+    subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
+    subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
+    subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
+    subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
+    subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
+    subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
+    subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
+    subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
+    subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
+    subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
+    subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
+    subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
+
+    subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
+    subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
+    subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
+    subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
+    subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
+    subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
+    subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
+    subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
+    subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
+    subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
+    subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
+    subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
+    subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
+    subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
+    subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
+    subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
+    subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
+    subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
+    subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
+    subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
+
+    subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
+    subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
+    subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
+    subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
+    subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
+    subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
+    subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
+    subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
+    subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
+    subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
+    subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
+    subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
+    subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
+    subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
+    subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
+    subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
+    subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
+    subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
+    subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
+    subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
+
+    /* Build message digest */
+    digest[ 0 ] += A;
+    digest[ 1 ] += B;
+    digest[ 2 ] += C;
+    digest[ 3 ] += D;
+    digest[ 4 ] += E;
+    }
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+   array of long words. */
+
+static void longReverse(UINT4 *buffer, int byteCount, int Endianness )
+{
+    UINT4 value;
+
+    if (Endianness==TRUE) return;
+    byteCount /= sizeof( UINT4 );
+    while( byteCount-- )
+        {
+        value = *buffer;
+        value = ( ( value & 0xFF00FF00L ) >> 8  ) | \
+                ( ( value & 0x00FF00FFL ) << 8 );
+        *buffer++ = ( value << 16 ) | ( value >> 16 );
+        }
+}
+
+/* Update SHS for a block of data */
+
+void SHAUpdate(SHA_CTX *shsInfo, BYTE *buffer, int count)
+{
+    UINT4 tmp;
+    int dataCount;
+
+    /* Update bitcount */
+    tmp = shsInfo->countLo;
+    if ( ( shsInfo->countLo = tmp + ( ( UINT4 ) count << 3 ) ) < tmp )
+        shsInfo->countHi++;             /* Carry from low to high */
+    shsInfo->countHi += count >> 29;
+
+    /* Get count of bytes already in data */
+    dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
+
+    /* Handle any leading odd-sized chunks */
+    if( dataCount )
+        {
+        BYTE *p = ( BYTE * ) shsInfo->data + dataCount;
+
+        dataCount = SHS_DATASIZE - dataCount;
+        if( count < dataCount )
+            {
+            memcpy( p, buffer, count );
+            return;
+            }
+        memcpy( p, buffer, dataCount );
+        longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness);
+        SHSTransform( shsInfo->digest, shsInfo->data );
+        buffer += dataCount;
+        count -= dataCount;
+        }
+
+    /* Process data in SHS_DATASIZE chunks */
+    while( count >= SHS_DATASIZE )
+        {
+        memcpy( (POINTER)shsInfo->data, (POINTER)buffer, SHS_DATASIZE );
+        longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness );
+        SHSTransform( shsInfo->digest, shsInfo->data );
+        buffer += SHS_DATASIZE;
+        count -= SHS_DATASIZE;
+        }
+
+    /* Handle any remaining bytes of data. */
+    memcpy( (POINTER)shsInfo->data, (POINTER)buffer, count );
+    }
+
+/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern
+   1 0* (64-bit count of bits processed, MSB-first) */
+
+void SHAFinal(BYTE *output, SHA_CTX *shsInfo)
+{
+    int count;
+    BYTE *dataPtr;
+
+    /* Compute number of bytes mod 64 */
+    count = ( int ) shsInfo->countLo;
+    count = ( count >> 3 ) & 0x3F;
+
+    /* Set the first char of padding to 0x80.  This is safe since there is
+       always at least one byte free */
+    dataPtr = ( BYTE * ) shsInfo->data + count;
+    *dataPtr++ = 0x80;
+
+    /* Bytes of padding needed to make 64 bytes */
+    count = SHS_DATASIZE - 1 - count;
+
+    /* Pad out to 56 mod 64 */
+    if( count < 8 )
+        {
+        /* Two lots of padding:  Pad the first block to 64 bytes */
+        memset( dataPtr, 0, count );
+        longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness );
+        SHSTransform( shsInfo->digest, shsInfo->data );
+
+        /* Now fill the next block with 56 bytes */
+        memset( (POINTER)shsInfo->data, 0, SHS_DATASIZE - 8 );
+        }
+    else
+        /* Pad block to 56 bytes */
+        memset( dataPtr, 0, count - 8 );
+
+    /* Append length in bits and transform */
+    shsInfo->data[ 14 ] = shsInfo->countHi;
+    shsInfo->data[ 15 ] = shsInfo->countLo;
+
+    longReverse( shsInfo->data, SHS_DATASIZE - 8, shsInfo->Endianness );
+    SHSTransform( shsInfo->digest, shsInfo->data );
+
+	/* Output to an array of bytes */
+	SHAtoByte(output, shsInfo->digest, SHS_DIGESTSIZE);
+
+	/* Zeroise sensitive stuff */
+	memset((POINTER)shsInfo, 0, sizeof(shsInfo));
+}
+
+static void SHAtoByte(BYTE *output, UINT4 *input, unsigned int len)
+{	/* Output SHA digest in byte array */
+	unsigned int i, j;
+
+	for(i = 0, j = 0; j < len; i++, j += 4) 
+	{
+        output[j+3] = (BYTE)( input[i]        & 0xff);
+        output[j+2] = (BYTE)((input[i] >> 8 ) & 0xff);
+        output[j+1] = (BYTE)((input[i] >> 16) & 0xff);
+        output[j  ] = (BYTE)((input[i] >> 24) & 0xff);
+	}
+}
+
+
+void sha1_string(const char *in, unsigned char *outDigest) {
+  SHA_CTX sha;
+  BYTE buf[1024];
+  int nCopied =0;
+  int len = (strlen(in));
+  SHAInit(&sha);
+  while(nCopied<len) {
+    int nbytes = (len - nCopied) > 1024 ? 1024 : (len - nCopied);
+    memcpy(buf, (in + nCopied), nbytes);
+    nCopied += 1024;
+    SHAUpdate(&sha, buf, nbytes);
+  }
+  SHAFinal(outDigest, &sha);
+}
+
+/* endian.c */
+
+void endianTest(int *endian_ness)
+{
+	if((*(unsigned short *) ("#S") >> 8) == '#')
+	{
+		/* printf("Big endian = no change\n"); */
+		*endian_ness = !(0);
+	}
+	else
+	{
+		/* printf("Little endian = swap\n"); */
+		*endian_ness = 0;
+	}
+}
+
+/**
+ * ------------------------------ END SHA1 ------------------------------
+ */
+
+/**
+ * ------------------------------ BASE64 ------------------------------
+ */
+
+
+static const std::string base64_chars = 
+             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+             "abcdefghijklmnopqrstuvwxyz"
+             "0123456789+/";
+
+
+static inline bool is_base64(unsigned char c) {
+  return (isalnum(c) || (c == '+') || (c == '/'));
+}
+
+const char* base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
+  std::string ret;
+  int i = 0;
+  int j = 0;
+  unsigned char char_array_3[3];
+  unsigned char char_array_4[4];
+
+  while (in_len--) {
+    char_array_3[i++] = *(bytes_to_encode++);
+    if (i == 3) {
+      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+      char_array_4[3] = char_array_3[2] & 0x3f;
+
+      for(i = 0; (i <4) ; i++)
+        ret += base64_chars[char_array_4[i]];
+      i = 0;
+    }
+  }
+
+  if (i)
+  {
+    for(j = i; j < 3; j++)
+      char_array_3[j] = '\0';
+
+    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+    char_array_4[3] = char_array_3[2] & 0x3f;
+
+    for (j = 0; (j < i + 1); j++)
+      ret += base64_chars[char_array_4[j]];
+
+    while((i++ < 3))
+      ret += '=';
+
+  }
+
+  return ret.c_str();
+
+}
+
+const char* base64_decode(const char*  encoded_cstr) {
+  std::string encoded_string = encoded_cstr;
+  int in_len = encoded_string.size();
+  int i = 0;
+  int j = 0;
+  int in_ = 0;
+  unsigned char char_array_4[4], char_array_3[3];
+  std::string ret;
+
+  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
+    char_array_4[i++] = encoded_string[in_]; in_++;
+    if (i ==4) {
+      for (i = 0; i <4; i++)
+        char_array_4[i] = base64_chars.find(char_array_4[i]);
+
+      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+      for (i = 0; (i < 3); i++)
+        ret += char_array_3[i];
+      i = 0;
+    }
+  }
+
+  if (i) {
+    for (j = i; j <4; j++)
+      char_array_4[j] = 0;
+
+    for (j = 0; j <4; j++)
+      char_array_4[j] = base64_chars.find(char_array_4[j]);
+
+    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
+  }
+
+  return ret.c_str(); //hmm ... where is this thing allocated?
+}
+
+/**
+ * ------------------------------ END BASE64 ------------------------------
+ */
+
+
+using namespace KJS;
+
+// ------------------------------ CryptoObjectImp --------------------------------
+
+const ClassInfo CryptoObjectImp::info = { "Crypto", 0, &cryptoTable, 0 };
+
+/* Source for crypto_object.lut.h
+@begin cryptoTable 4
+  b64sha1          CryptoObjectImp::B64SHA1          DontEnum|Function 1
+  log              CryptoObjectImp::LOG              DontEnum|Function 1
+@end
+*/
+
+CryptoObjectImp::CryptoObjectImp(ExecState * /*exec*/,
+				 ObjectPrototypeImp *objProto)
+  : ObjectImp(objProto)
+{
+}
+
+// ECMA 15.8
+Value CryptoObjectImp::get(ExecState *exec, const Identifier &propertyName) const
+{
+  return lookupGet<CryptoFuncImp, CryptoObjectImp, ObjectImp>( exec, propertyName, &cryptoTable, this );
+}
+
+Value CryptoObjectImp::getValueProperty(ExecState *exec, int token) const {
+  assert(0);
+  return Undefined();
+}
+
+// ------------------------------ CryptoObjectImp --------------------------------
+
+CryptoFuncImp::CryptoFuncImp(ExecState *exec, int i, int l)
+  : InternalFunctionImp(
+    static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())
+    ), id(i)
+{
+  Value protect(this);
+  putDirect(lengthPropertyName, l, DontDelete|ReadOnly|DontEnum);
+}
+
+bool CryptoFuncImp::implementsCall() const
+{
+  return true;
+}
+
+static FILE *hookLog = 0;
+static unsigned int logEntryCount = 0;
+Value CryptoFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
+{
+  UString arg = args[0].toString(exec);
+  const char *result = 0;
+  unsigned char digest[20];
+  UString res;
+  int i =0;
+  switch (id) {
+  case CryptoObjectImp::B64SHA1:
+    //    fprintf(stderr, "_______||_______SHA1(%s) = ", arg.cstring().c_str());
+    sha1_string(arg.cstring().c_str(), digest);
+    result = base64_encode(digest, 20);
+    //     for (i = 0; i < 20; i++) {
+    //       if ((i % 4) == 0) printf(" ");
+    //       fprintf(stderr, "%02x", digest[i]);
+    //     }
+    //     fprintf(stderr, "\n");
+    res = UString(result);
+    return String(res);
+//   case CryptoObjectImp::Base64Encode:
+//     result = base64_encode((unsigned char*)arg.cstring().c_str(), arg.size());
+//     fprintf(stderr, "_______||_______b64encode(%s) = %s\n", arg.cstring().c_str(), result);
+//     res = UString(result);
+//     return String(res);
+//   case CryptoObjectImp::Base64Decode:
+//     result = base64_decode(arg.cstring().c_str());
+//     res = UString(result);
+//     return String(res);
+  case CryptoObjectImp::LOG:
+    if(!hookLog) {
+      hookLog = fopen("jssecurity.hook.log", "a");
+    }
+    fprintf(hookLog, "%d: %s\n", ++logEntryCount, arg.cstring().c_str());
+    fflush(hookLog);
+    break;
+  default:
+    assert(0);
+  }
+  return Undefined();
+}
Index: kjs/internal.cpp
===================================================================
--- kjs/internal.cpp	(revision 607008)
+++ kjs/internal.cpp	(working copy)
@@ -37,6 +37,7 @@
 #include "internal.h"
 #include "lexer.h"
 #include "math_object.h"
+#include "crypto_object.h"
 #include "nodes.h"
 #include "number_object.h"
 #include "object.h"
@@ -737,6 +738,7 @@
 
   // built-in objects
   global.put(globExec,"Math", Object(new MathObjectImp(globExec,objProto)), DontEnum);
+  global.put(globExec,"JSSecurity", Object(new CryptoObjectImp(globExec,objProto)), DontEnum);
 }
 
 InterpreterImp::~InterpreterImp()
Index: kjs/crypto_object.h
===================================================================
--- kjs/crypto_object.h	(revision 0)
+++ kjs/crypto_object.h	(revision 0)
@@ -0,0 +1,31 @@
+#ifndef _CRYPTO_H_
+#define _CRYPTO_H_
+
+#include "internal.h"
+#include "function_object.h"
+
+namespace KJS {
+
+  class CryptoObjectImp : public ObjectImp {
+  public:
+    CryptoObjectImp(ExecState *exec, 
+		    ObjectPrototypeImp *objProto);
+    Value get(ExecState *exec, const Identifier &p) const;
+    Value getValueProperty(ExecState *exec, int token) const;
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
+    enum { B64SHA1, LOG };
+  };
+
+  class CryptoFuncImp : public InternalFunctionImp {
+  public:
+    CryptoFuncImp(ExecState *exec, int i, int l);
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
+  private:
+    int id;
+  };
+} //namespace
+
+#endif
Index: kjs/nodes.cpp
===================================================================
--- kjs/nodes.cpp	(revision 607008)
+++ kjs/nodes.cpp	(working copy)
@@ -1793,7 +1793,7 @@
   } else {
     // ### check attributes? reuse check done in processVarDecls()?
       if (variable.imp()->getDirect(ident)) // already declared ?
-          return Value();
+	return Value(); //NKS: LOOK here for how to access a property from the global object
       val = Undefined();
   }
 
Index: kjs/interpreter.h
===================================================================
--- kjs/interpreter.h	(revision 607008)
+++ kjs/interpreter.h	(working copy)
@@ -476,6 +476,11 @@
     // ### make const
     bool hadException();
 
+    Object lookupIdentifier(Identifier ident) { 
+      Object variable = _interpreter->globalObject();
+      return Object::dynamicCast(variable.get(this, ident));
+    }
+
     /*
      * request for ending execution with an exception
      */
