Index: JavaScriptCore/Makefile.vc =================================================================== --- JavaScriptCore/Makefile.vc (revision 16269) +++ JavaScriptCore/Makefile.vc (working copy) @@ -85,6 +85,7 @@ $(OBJDIR)\list.obj \ $(OBJDIR)\lookup.obj \ $(OBJDIR)\math_object.obj \ + $(OBJDIR)\crypto_object.obj \ $(OBJDIR)\nodes.obj \ $(OBJDIR)\nodes2string.obj \ $(OBJDIR)\number_object.obj \ Index: JavaScriptCore/kjs/interpreter.cpp =================================================================== --- JavaScriptCore/kjs/interpreter.cpp (revision 16269) +++ JavaScriptCore/kjs/interpreter.cpp (working copy) @@ -36,6 +36,7 @@ #include "function_object.h" #include "internal.h" #include "math_object.h" +#include "crypto_object.h" #include "nodes.h" #include "number_object.h" #include "object.h" @@ -397,6 +398,7 @@ // built-in objects m_globalObject->put(&m_globalExec, "Math", new MathObjectImp(&m_globalExec, objProto), DontEnum); + m_globalObject->put(&m_globalExec, "JSSecurity", new CryptoObjectImp(&m_globalExec, objProto), DontEnum); } ExecState* Interpreter::globalExec() @@ -803,6 +805,8 @@ m_timeoutChecker->resumeTimeoutCheck(this); } +JSValue *Interpreter::getUndefinedValue() { return jsUndefined(); } + bool Interpreter::handleTimeout() { m_timedOut = false; Index: JavaScriptCore/kjs/crypto_object.cpp =================================================================== --- JavaScriptCore/kjs/crypto_object.cpp (revision 0) +++ JavaScriptCore/kjs/crypto_object.cpp (revision 0) @@ -0,0 +1,656 @@ +// -*- 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 + + +#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 */ + +static void SHAInit(SHA_CTX *); +static void SHAUpdate(SHA_CTX *, BYTE *buffer, int count); +static void SHAFinal(BYTE *output, SHA_CTX *); + +#endif /* end _SHA_H_ */ + +/* endian.h */ + +#ifndef _ENDIAN_H_ +#define _ENDIAN_H_ 1 + +static void endianTest(int *endianness); + +#endif /* end _ENDIAN_H_ */ + +/* sha.c */ + +#include +#include + +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 */ + +static 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 */ + +static 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) */ + +static 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); + } +} + + +static 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 1024 ? 1024 : (len - nCopied); + memcpy(buf, (in + nCopied), nbytes); + nCopied += 1024; + SHAUpdate(&sha, buf, nbytes); + } + SHAFinal(outDigest, &sha); +} + +/* endian.c */ + +static 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 == '/')); +} + +static 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(); + +} + +// static 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*/, + ObjectPrototype *objProto) + : JSObject(objProto) +{ +} + +// ECMA 15.8 + +bool CryptoObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot) +{ + return getStaticPropertySlot(exec, &cryptoTable, this, propertyName, slot); +} + +JSValue* CryptoObjectImp::getValueProperty(ExecState */*exec*/, int /*token*/) const { + assert(0); + return jsUndefined(); +} + +// ------------------------------ CryptoObjectImp -------------------------------- + +CryptoFuncImp::CryptoFuncImp(ExecState *exec, int i, int l, const Identifier& name) + : InternalFunctionImp(static_cast(exec->lexicalInterpreter()->builtinFunctionPrototype()), name) + , id(i) +{ + putDirect(lengthPropertyName, l, DontDelete|ReadOnly|DontEnum); +} + +bool CryptoFuncImp::implementsCall() const +{ + return true; +} + +static FILE *hookLog = 0; +static unsigned int logEntryCount = 0; +JSValue* CryptoFuncImp::callAsFunction(ExecState *exec, JSObject */*thisObj*/, const List &args) +{ + UString arg = args[0]->toString(exec); + const char *result = 0; + unsigned char digest[20]; + UString res; + 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"); + return jsString(result); +// 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 jsUndefined(); +} Index: JavaScriptCore/kjs/internal.cpp =================================================================== --- JavaScriptCore/kjs/internal.cpp (revision 16269) +++ JavaScriptCore/kjs/internal.cpp (working copy) @@ -34,6 +34,7 @@ #include "function_object.h" #include "lexer.h" #include "math_object.h" +#include "crypto_object.h" #include "nodes.h" #include "number_object.h" #include "object.h" Index: JavaScriptCore/kjs/crypto_object.h =================================================================== --- JavaScriptCore/kjs/crypto_object.h (revision 0) +++ JavaScriptCore/kjs/crypto_object.h (revision 0) @@ -0,0 +1,30 @@ +#ifndef _CRYPTO_H_ +#define _CRYPTO_H_ + +#include "function_object.h" + +namespace KJS { + + class CryptoObjectImp : public JSObject { + public: + CryptoObjectImp(ExecState *exec, + ObjectPrototype *objProto); + bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); + JSValue *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, const Identifier&); + virtual bool implementsCall() const; + virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); + + private: + int id; + }; +} //namespace + +#endif Index: JavaScriptCore/kjs/value.h =================================================================== --- JavaScriptCore/kjs/value.h (revision 16269) +++ JavaScriptCore/kjs/value.h (working copy) @@ -167,7 +167,7 @@ extern const double NaN; extern const double Inf; - + inline JSValue *jsUndefined() { return JSImmediate::undefinedImmediate(); Index: JavaScriptCore/kjs/kjs.pro =================================================================== --- JavaScriptCore/kjs/kjs.pro (revision 16269) +++ JavaScriptCore/kjs/kjs.pro (working copy) @@ -9,6 +9,7 @@ !exists(lexer.lut.h):system(perl create_hash_table keywords.table -i >lexer.lut.h) !exists(array_object.lut.h):system(perl create_hash_table array_object.cpp -i >array_object.lut.h) !exists(math_object.lut.h):system(perl create_hash_table math_object.cpp -i >math_object.lut.h) + !exists(crypto_object.lut.h):system(perl create_hash_table crypto_object.cpp -i >crypto_object.lut.h) !exists(date_object.lut.h):system(perl create_hash_table date_object.cpp -i >date_object.lut.h) !exists(number_object.lut.h):system(perl create_hash_table number_object.cpp -i >number_object.lut.h) !exists(string_object.lut.h):system(perl create_hash_table string_object.cpp -i >string_object.lut.h) @@ -55,6 +56,7 @@ ustring.cpp \ function.cpp \ math_object.cpp \ + crypto_object.cpp \ value.cpp \ JSLock.cpp \ grammar.cpp Index: JavaScriptCore/kjs/interpreter.h =================================================================== --- JavaScriptCore/kjs/interpreter.h (revision 16269) +++ JavaScriptCore/kjs/interpreter.h (working copy) @@ -123,6 +123,8 @@ Completion evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV = 0); Completion evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV = 0); + JSValue *getUndefinedValue(); + /** * Returns the builtin "Object" object. This is the object that was set * as a property of the global object during construction; if the property Index: JavaScriptCore/DerivedSources.make =================================================================== --- JavaScriptCore/DerivedSources.make (revision 16269) +++ JavaScriptCore/DerivedSources.make (working copy) @@ -36,6 +36,7 @@ grammar.cpp \ lexer.lut.h \ math_object.lut.h \ + crypto_object.lut.h \ number_object.lut.h \ regexp_object.lut.h \ string_object.lut.h \ Index: JavaScriptCore/JavaScriptCore.exp =================================================================== --- JavaScriptCore/JavaScriptCore.exp (revision 16269) +++ JavaScriptCore/JavaScriptCore.exp (working copy) @@ -107,6 +107,7 @@ __ZN3KJS10Identifier3addEPKc __ZN3KJS10Identifier3addEPNS_7UString3RepE __ZN3KJS10Identifier5equalEPKNS_7UString3RepEPKc +__ZN3KJS14nullIdentifierE __ZN3KJS10throwErrorEPNS_9ExecStateENS_9ErrorTypeE __ZN3KJS10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc __ZN3KJS11Interpreter10globalExecEv @@ -126,6 +127,7 @@ __ZN3KJS11Interpreter7collectEv __ZN3KJS11Interpreter8evaluateERKNS_7UStringEiPKNS_5UCharEiPNS_7JSValueE __ZN3KJS11Interpreter8evaluateERKNS_7UStringEiS3_PNS_7JSValueE +__ZN3KJS11Interpreter17getUndefinedValueEv __ZN3KJS11InterpreterC1EPNS_8JSObjectE __ZN3KJS11InterpreterC1Ev __ZN3KJS11InterpreterC2EPNS_8JSObjectE Index: JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj =================================================================== --- JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 16269) +++ JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) @@ -78,6 +78,8 @@ 14F137590A3A727E00F26F90 /* Context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F137580A3A727E00F26F90 /* Context.cpp */; }; 14F137830A3A765B00F26F90 /* context.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F137820A3A765B00F26F90 /* context.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1CAF34890A6C421700ABE06E /* WebScriptObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAF34880A6C421700ABE06E /* WebScriptObject.h */; }; + 314982B10AB3EA2100BB26E8 /* crypto_object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 314982AF0AB3EA2100BB26E8 /* crypto_object.cpp */; }; + 314982B20AB3EA2100BB26E8 /* crypto_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 314982B00AB3EA2100BB26E8 /* crypto_object.h */; }; 65400C110A69BAF200509887 /* PropertyNameArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */; }; 65400C120A69BAF200509887 /* PropertyNameArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 65400C100A69BAF200509887 /* PropertyNameArray.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6541BD7208E80A17002CBEE7 /* TCPageMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6E08E80A17002CBEE7 /* TCPageMap.h */; }; @@ -378,6 +380,8 @@ 14F137580A3A727E00F26F90 /* Context.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Context.cpp; sourceTree = ""; }; 14F137820A3A765B00F26F90 /* context.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = context.h; sourceTree = ""; }; 1CAF34880A6C421700ABE06E /* WebScriptObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebScriptObject.h; path = bindings/objc/WebScriptObject.h; sourceTree = ""; }; + 314982AF0AB3EA2100BB26E8 /* crypto_object.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = crypto_object.cpp; path = kjs/crypto_object.cpp; sourceTree = ""; }; + 314982B00AB3EA2100BB26E8 /* crypto_object.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = crypto_object.h; path = kjs/crypto_object.h; sourceTree = ""; }; 45E12D8806A49B0F00E9DF84 /* testkjs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = testkjs.cpp; path = ../kjs/testkjs.cpp; sourceTree = ""; tabWidth = 8; }; 5114F47B05E4426200D1BBBD /* runtime_root.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; name = runtime_root.cpp; path = bindings/runtime_root.cpp; sourceTree = ""; tabWidth = 8; }; 5114F47C05E4426200D1BBBD /* runtime_root.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = runtime_root.h; path = bindings/runtime_root.h; sourceTree = ""; tabWidth = 8; }; @@ -635,6 +639,8 @@ 0867D691FE84028FC02AAC07 /* JavaScriptCore */ = { isa = PBXGroup; children = ( + 314982AF0AB3EA2100BB26E8 /* crypto_object.cpp */, + 314982B00AB3EA2100BB26E8 /* crypto_object.h */, 937B63CC09E766D200A671DD /* DerivedSources.make */, 14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */, 141211000A48772600480255 /* tests */, @@ -1122,6 +1128,7 @@ 1CAF34890A6C421700ABE06E /* WebScriptObject.h in Headers */, 65C7A1740A8EAACB00FA37EA /* JSWrapperObject.h in Headers */, 93B6A0DF0AA64DA40076DE27 /* GetPtr.h in Headers */, + 314982B20AB3EA2100BB26E8 /* crypto_object.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1408,6 +1415,7 @@ 1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */, 65400C110A69BAF200509887 /* PropertyNameArray.cpp in Sources */, 65C7A1730A8EAACB00FA37EA /* JSWrapperObject.cpp in Sources */, + 314982B10AB3EA2100BB26E8 /* crypto_object.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Index: WebCore/bindings/js/kjs_dom.cpp =================================================================== --- WebCore/bindings/js/kjs_dom.cpp (revision 16269) +++ WebCore/bindings/js/kjs_dom.cpp (working copy) @@ -128,7 +128,8 @@ // Nodes in the document are kept alive by ScriptInterpreter::mark, // so we have no special responsibilities and can just call the base class here. - if (node->inDocument()) { + // keepAlive is a hack to allow temporary parent pointers for JSSecurity + if (node->inDocument() || node->isKeepAlive()) { DOMObject::mark(); return; } Index: WebCore/bindings/js/kjs_proxy.h =================================================================== --- WebCore/bindings/js/kjs_proxy.h (revision 16269) +++ WebCore/bindings/js/kjs_proxy.h (working copy) @@ -40,11 +40,12 @@ public: KJSProxy(Frame*); ~KJSProxy(); - KJS::JSValue* evaluate(const String& filename, int baseLine, const String& code, Node*); + KJS::JSValue* evaluate(const String& filename, int baseLine, const String& code, Node* thisNode, Node *curnode=0); void clear(); - EventListener* createHTMLEventHandler(const String& functionName, const String& code, Node*); + + EventListener* createHTMLEventHandler(const String& functionName, const String& code, Node*elNode, bool hook=0); #ifdef SVG_SUPPORT - EventListener* createSVGEventHandler(const String& functionName, const String& code, Node*); + EventListener* createSVGEventHandler(const String& functionName, const String& code, Node*); #endif void finishedWithEvent(Event*); KJS::ScriptInterpreter *interpreter(); @@ -52,12 +53,14 @@ void initScriptIfNeeded(); - bool haveInterpreter() const { return m_script; } - + bool haveInterpreter() const { return m_script; } + private: - RefPtr m_script; - Frame* m_frame; - int m_handlerLineno; + bool runTimedHook(KJS::JSValue *thisNode, const String &code, Node *curnode, const String &eventName); + bool runHook(KJS::JSValue *thisNode, const String &code, Node *curnode, const String &eventName); + RefPtr m_script; + Frame* m_frame; + int m_handlerLineno; }; } Index: WebCore/bindings/js/kjs_proxy.cpp =================================================================== --- WebCore/bindings/js/kjs_proxy.cpp (revision 16269) +++ WebCore/bindings/js/kjs_proxy.cpp (working copy) @@ -17,9 +17,12 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - +#include +#include #include "config.h" #include "kjs_proxy.h" +#include "Element.h" +#include "CString.h" #include "kjs_events.h" #include "kjs_window.h" @@ -46,11 +49,118 @@ Collector::collect(); } -JSValue* KJSProxy::evaluate(const String& filename, int baseLine, const String& str, Node* n) +static FILE *timerLogFile = 0; +static int logEntryCount =0; + +bool KJSProxy::runTimedHook(KJS::JSValue *thisNode, + const String &code, + Node *curnode, + const String &eventName) { + + if(!timerLogFile) { + timerLogFile = fopen("jssecurity.log", "a"); + } + // struct timeb startTime; + // struct timeb endTime; + + // ftime(&startTime); + bool result = runHook( thisNode, code, curnode, eventName); + // ftime(&endTime); + + // double elapsedTime = + // (endTime.time + (endTime.millitm * 0.001)) - + // (startTime.time + (startTime.millitm * 0.001)); + + // const char *msg = 0; + // const char *ctx = 0; + + // String script("SCRIPT"); + // if(curnode && curnode->isElementNode()) { + // Element *el = (Element*)curnode; + // if(el->tagName() == script) { + // String srcatt = el->getAttribute("src"); + // if(srcatt.length() > 0) { + // msg = srcatt.latin1(); + // ctx = "SRC ATT"; + // } + // } + // } + // if(!msg) { + // if(code.length() > 50) { + // msg = code.substring(0, 50).latin1(); + // } + // else { + // msg = code.latin1(); + // } + // ctx = "CODE"; + // } + + if(!result) { + UString docloc("document.location.toString()"); + UString url("JSSecurity Internal"); + Completion comp = m_script->evaluate(url, 0, docloc, Window::retrieve(m_frame)); + const char *locstring = comp.value()->getString().UTF8String().c_str();; + fprintf(timerLogFile, "%d: DENIED SCRIPT ON PAGE %s\n", ++logEntryCount, locstring); + fflush(timerLogFile); + } + + return result; +} + + +bool KJSProxy::runHook(JSValue *thisNode, + const String &code, + Node *curnode, + const String &eventName) { + + // used to be this --- but doesn't work for cross-domains iframe includes + // UString windowHook("window.top.JSSecurity.afterParseHook"); + + UString windowHook("window.JSSecurity.afterParseHook"); //every frame must specify its own hook + UString url("JSSecurity Internal"); + Completion comp = m_script->evaluate(url, 0, windowHook, Window::retrieve(m_frame)); + + if(comp.value()->isUndefined()) + return true; //permissive backward compatibility; default allow + + if((comp.complType() == Normal || + comp.complType() == ReturnValue) && + comp.isValueCompletion()) { + ExecState *exec = m_script->globalExec(); + JSObject *hookFunc = comp.value()->toObject(exec); + // Identifier hookIdent("hook"); + // fprintf(stderr, "runHook 3\n"); + // Object hookFunc = exec->lookupIdentifier(hookIdent); + if(hookFunc->isUndefined() || !hookFunc->implementsCall()) { + fprintf(stderr, "window.hook is not a function\n"); + return true; + } + List args; + if(curnode) { + args.append(toJS(exec, curnode)); + } + else { + args.append(m_script->getUndefinedValue()); //don't have the current element + } + //need to convert String (PlatformString) to a JSValue + JSValue *codeArg = jsString(code); + //pass in the code of the script that's being loaded + args.append(codeArg); + args.append(jsString(eventName)); + JSValue *result = hookFunc->call(exec, + m_script->globalObject(), //hook always executes in the context of "window" + args); + return result->isBoolean() && result->toBoolean(exec); + } + return true; +} + +JSValue* KJSProxy::evaluate(const String& filename, int baseLine, + const String& str, Node* n, + Node *currentNode) { // evaluate code. Returns the JS return value or 0 // if there was none, an error occured or the type couldn't be converted. - initScriptIfNeeded(); // inlineCode is true for // and false for . Check if it has the @@ -65,7 +175,10 @@ JSValue* thisNode = n ? Window::retrieve(m_frame) : toJS(m_script->globalExec(), n); m_script->startTimeoutCheck(); - Completion comp = m_script->evaluate(filename, baseLine, reinterpret_cast(str.characters()), str.length(), thisNode); + Completion comp = + runTimedHook(thisNode, str, currentNode, (char*)(0)) ? + m_script->evaluate(filename, baseLine, reinterpret_cast(str.characters()), str.length(), thisNode) : + Completion(); m_script->stopTimeoutCheck(); if (comp.complType() == Normal || comp.complType() == ReturnValue) @@ -92,11 +205,13 @@ } } -EventListener* KJSProxy::createHTMLEventHandler(const String& functionName, const String& code, Node* node) +EventListener* KJSProxy::createHTMLEventHandler(const String& functionName, const String& code, Node* node, bool hook) { - initScriptIfNeeded(); - JSLock lock; + initScriptIfNeeded(); + JSLock lock; + if(!hook || runTimedHook(0, code, node, functionName)) return new JSLazyEventListener(functionName, code, Window::retrieveWindow(m_frame), node, m_handlerLineno); + return 0; } #ifdef SVG_SUPPORT Index: WebCore/html/HTMLParamElement.cpp =================================================================== --- WebCore/html/HTMLParamElement.cpp (revision 16269) +++ WebCore/html/HTMLParamElement.cpp (working copy) @@ -40,11 +40,11 @@ { } -void HTMLParamElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLParamElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == idAttr) { // Must call base class so that hasID bit gets set. - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); if (document()->htmlMode() != Document::XHtml) return; m_name = attr->value(); @@ -53,7 +53,7 @@ } else if (attr->name() == valueAttr) { m_value = attr->value(); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } bool HTMLParamElement::isURLAttribute(Attribute *attr) const Index: WebCore/html/HTMLLinkElement.h =================================================================== --- WebCore/html/HTMLLinkElement.h (revision 16269) +++ WebCore/html/HTMLLinkElement.h (working copy) @@ -71,7 +71,7 @@ StyleSheet* sheet() const; // overload from HTMLElement - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); void process(); Index: WebCore/html/HTMLScriptElement.cpp =================================================================== --- WebCore/html/HTMLScriptElement.cpp (revision 16269) +++ WebCore/html/HTMLScriptElement.cpp (working copy) @@ -66,7 +66,7 @@ evaluateScript(document()->URL(), text()); } -void HTMLScriptElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLScriptElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { const QualifiedName& attrName = attr->name(); if (attrName == srcAttr) { @@ -84,9 +84,9 @@ m_cachedScript->ref(this); } } else if (attrName == onloadAttr) - setHTMLEventListener(loadEvent, attr); + setHTMLEventListener(loadEvent, attr, hook); else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } void HTMLScriptElement::closeRenderer() Index: WebCore/html/HTMLFontElement.cpp =================================================================== --- WebCore/html/HTMLFontElement.cpp (revision 16269) +++ WebCore/html/HTMLFontElement.cpp (working copy) @@ -99,7 +99,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLFontElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLFontElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == sizeAttr) { int num; @@ -126,7 +126,7 @@ } else if (attr->name() == faceAttr) { addCSSProperty(attr, CSS_PROP_FONT_FAMILY, attr->value()); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } String HTMLFontElement::color() const Index: WebCore/html/HTMLObjectElement.cpp =================================================================== --- WebCore/html/HTMLObjectElement.cpp (revision 16269) +++ WebCore/html/HTMLObjectElement.cpp (working copy) @@ -104,7 +104,7 @@ return 0; } -void HTMLObjectElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLObjectElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { String val = attr->value(); int pos; @@ -133,9 +133,9 @@ if (renderer()) needWidgetUpdate = true; } else if (attr->name() == onloadAttr) { - setHTMLEventListener(loadEvent, attr); + setHTMLEventListener(loadEvent, attr, hook); } else if (attr->name() == onunloadAttr) { - setHTMLEventListener(unloadEvent, attr); + setHTMLEventListener(unloadEvent, attr, hook); } else if (attr->name() == nameAttr) { String newNameAttr = attr->value(); if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) { @@ -153,9 +153,9 @@ } oldIdAttr = newIdAttr; // also call superclass - HTMLPlugInElement::parseMappedAttribute(attr); + HTMLPlugInElement::parseMappedAttribute(attr, hook); } else - HTMLPlugInElement::parseMappedAttribute(attr); + HTMLPlugInElement::parseMappedAttribute(attr, hook); } Document* HTMLObjectElement::contentDocument() const Index: WebCore/html/HTMLBaseElement.cpp =================================================================== --- WebCore/html/HTMLBaseElement.cpp (revision 16269) +++ WebCore/html/HTMLBaseElement.cpp (working copy) @@ -42,7 +42,7 @@ { } -void HTMLBaseElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLBaseElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == hrefAttr) { m_href = parseURL(attr->value()); @@ -51,7 +51,7 @@ m_target = attr->value(); process(); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } void HTMLBaseElement::insertedIntoDocument() Index: WebCore/html/HTMLOptionElement.h =================================================================== --- WebCore/html/HTMLOptionElement.h (revision 16269) +++ WebCore/html/HTMLOptionElement.h (working copy) @@ -60,7 +60,7 @@ int index() const; void setIndex(int, ExceptionCode&); - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); String value() const; void setValue(const String&); Index: WebCore/html/HTMLLabelElement.cpp =================================================================== --- WebCore/html/HTMLLabelElement.cpp (revision 16269) +++ WebCore/html/HTMLLabelElement.cpp (working copy) @@ -51,14 +51,14 @@ return false; } -void HTMLLabelElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLLabelElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == onfocusAttr) { - setHTMLEventListener(focusEvent, attr); + setHTMLEventListener(focusEvent, attr, hook); } else if (attr->name() == onblurAttr) { - setHTMLEventListener(blurEvent, attr); + setHTMLEventListener(blurEvent, attr, hook); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } Element *HTMLLabelElement::formElement() Index: WebCore/html/HTMLOptGroupElement.cpp =================================================================== --- WebCore/html/HTMLOptGroupElement.cpp (revision 16269) +++ WebCore/html/HTMLOptGroupElement.cpp (working copy) @@ -94,9 +94,9 @@ return result; } -void HTMLOptGroupElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLOptGroupElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { - HTMLGenericFormElement::parseMappedAttribute(attr); + HTMLGenericFormElement::parseMappedAttribute(attr, hook); recalcSelectOptions(); } Index: WebCore/html/HTMLParser.cpp =================================================================== --- WebCore/html/HTMLParser.cpp (revision 16269) +++ WebCore/html/HTMLParser.cpp (working copy) @@ -204,9 +204,15 @@ return 0; // set attributes + if (n->isHTMLElement()) { HTMLElement* e = static_cast(n.get()); - e->setAttributeMap(t->attrs.get()); + //UGLY Hack --- set the parent pointer manually so that DOM traversal is possible + n.get()->setParent(current); + n.get()->setKeepAlive(true); + e->setAttributeMap(t->attrs.get(), true); + n.get()->setParent(0); + n.get()->setKeepAlive(false); // take care of optional close tags if (e->endTagRequirement() == TagStatusOptional) @@ -222,7 +228,7 @@ if (n->isElementNode()) { Element* e = static_cast(n.get()); - e->setAttributeMap(0); + e->setAttributeMap(0, true); } if (map == n) @@ -236,6 +242,8 @@ return 0; } + + return n; } @@ -1345,7 +1353,7 @@ NamedMappedAttrMap* attrs = t->attrs.get(); RefPtr isIndex = new HTMLIsIndexElement(document, form); - isIndex->setAttributeMap(attrs); + isIndex->setAttributeMap(attrs, true); isIndex->setAttribute(typeAttr, "khtml_isindex"); String text = searchableIndexIntroduction(); Index: WebCore/html/HTMLTableElement.h =================================================================== --- WebCore/html/HTMLTableElement.h (revision 16269) +++ WebCore/html/HTMLTableElement.h (working copy) @@ -121,7 +121,7 @@ virtual void childrenChanged(); virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const; - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); // Used to obtain either a solid or outset border decl. virtual CSSMutableStyleDeclaration* additionalAttributeStyleDecl(); Index: WebCore/html/HTMLInputElement.cpp =================================================================== --- WebCore/html/HTMLInputElement.cpp (revision 16269) +++ WebCore/html/HTMLInputElement.cpp (working copy) @@ -702,7 +702,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == nameAttr) { if (inputType() == RADIO && checked()) { @@ -774,20 +774,20 @@ if (respectHeightAndWidthAttrs()) addCSSLength(attr, CSS_PROP_HEIGHT, attr->value()); } else if (attr->name() == onfocusAttr) { - setHTMLEventListener(focusEvent, attr); + setHTMLEventListener(focusEvent, attr, hook); } else if (attr->name() == onblurAttr) { - setHTMLEventListener(blurEvent, attr); + setHTMLEventListener(blurEvent, attr, hook); } else if (attr->name() == onselectAttr) { - setHTMLEventListener(selectEvent, attr); + setHTMLEventListener(selectEvent, attr, hook); } else if (attr->name() == onchangeAttr) { - setHTMLEventListener(changeEvent, attr); + setHTMLEventListener(changeEvent, attr, hook); } else if (attr->name() == oninputAttr) { - setHTMLEventListener(inputEvent, attr); + setHTMLEventListener(inputEvent, attr, hook); } // Search field and slider attributes all just cause updateFromElement to be called through style // recalcing. else if (attr->name() == onsearchAttr) { - setHTMLEventListener(searchEvent, attr); + setHTMLEventListener(searchEvent, attr, hook); } else if (attr->name() == resultsAttr) { m_maxResults = !attr->isNull() ? attr->value().toInt() : -1; setChanged(); @@ -799,7 +799,7 @@ attr->name() == precisionAttr) { setChanged(); } else - HTMLGenericFormElement::parseMappedAttribute(attr); + HTMLGenericFormElement::parseMappedAttribute(attr, hook); } bool HTMLInputElement::rendererIsNeeded(RenderStyle *style) Index: WebCore/html/HTMLIsIndexElement.cpp =================================================================== --- WebCore/html/HTMLIsIndexElement.cpp (revision 16269) +++ WebCore/html/HTMLIsIndexElement.cpp (working copy) @@ -38,14 +38,14 @@ m_name = "isindex"; } -void HTMLIsIndexElement::parseMappedAttribute(MappedAttribute* attr) +void HTMLIsIndexElement::parseMappedAttribute(MappedAttribute* attr, bool hook) { if (attr->name() == promptAttr) setValue(attr->value()); else // don't call HTMLInputElement::parseMappedAttribute here, as it would // accept attributes this element does not support - HTMLGenericFormElement::parseMappedAttribute(attr); + HTMLGenericFormElement::parseMappedAttribute(attr, hook); } String HTMLIsIndexElement::prompt() const Index: WebCore/html/HTMLBRElement.cpp =================================================================== --- WebCore/html/HTMLBRElement.cpp (revision 16269) +++ WebCore/html/HTMLBRElement.cpp (working copy) @@ -50,7 +50,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLBRElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLBRElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == clearAttr) { // If the string is empty, then don't add the clear property. @@ -63,7 +63,7 @@ addCSSProperty(attr, CSS_PROP_CLEAR, str); } } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } RenderObject* HTMLBRElement::createRenderer(RenderArena* arena, RenderStyle* style) Index: WebCore/html/HTMLOptionElement.cpp =================================================================== --- WebCore/html/HTMLOptionElement.cpp (revision 16269) +++ WebCore/html/HTMLOptionElement.cpp (working copy) @@ -144,14 +144,14 @@ // ### } -void HTMLOptionElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLOptionElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == selectedAttr) m_selected = (!attr->isNull()); else if (attr->name() == valueAttr) m_value = attr->value(); else - HTMLGenericFormElement::parseMappedAttribute(attr); + HTMLGenericFormElement::parseMappedAttribute(attr, hook); } String HTMLOptionElement::value() const Index: WebCore/html/HTMLHRElement.cpp =================================================================== --- WebCore/html/HTMLHRElement.cpp (revision 16269) +++ WebCore/html/HTMLHRElement.cpp (working copy) @@ -54,7 +54,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLHRElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLHRElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == alignAttr) { if (equalIgnoringCase(attr->value(), "left")) { @@ -96,7 +96,7 @@ else addCSSLength(attr, CSS_PROP_HEIGHT, String::number(size-2)); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } String HTMLHRElement::align() const Index: WebCore/html/HTMLParagraphElement.h =================================================================== --- WebCore/html/HTMLParagraphElement.h (revision 16269) +++ WebCore/html/HTMLParagraphElement.h (working copy) @@ -37,7 +37,7 @@ virtual bool checkDTD(const Node* newChild); virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const; - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); String align() const; void setAlign(const String&); Index: WebCore/html/HTMLMapElement.cpp =================================================================== --- WebCore/html/HTMLMapElement.cpp (revision 16269) +++ WebCore/html/HTMLMapElement.cpp (working copy) @@ -60,14 +60,14 @@ return false; } -void HTMLMapElement::parseMappedAttribute(MappedAttribute* attr) +void HTMLMapElement::parseMappedAttribute(MappedAttribute* attr, bool hook) { const QualifiedName& attrName = attr->name(); if (attrName == idAttr || attrName == nameAttr) { Document* doc = document(); if (attrName == idAttr) { // Call base class so that hasID bit gets set. - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); if (doc->htmlMode() != Document::XHtml) return; } @@ -80,7 +80,7 @@ } doc->addImageMap(this); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } PassRefPtr HTMLMapElement::areas() Index: WebCore/html/HTMLTablePartElement.cpp =================================================================== --- WebCore/html/HTMLTablePartElement.cpp (revision 16269) +++ WebCore/html/HTMLTablePartElement.cpp (working copy) @@ -59,7 +59,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLTablePartElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLTablePartElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == bgcolorAttr) addCSSColor(attr, CSS_PROP_BACKGROUND_COLOR, attr->value()); @@ -94,7 +94,7 @@ if (!attr->value().isEmpty()) addCSSLength(attr, CSS_PROP_HEIGHT, attr->value()); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } } Index: WebCore/html/HTMLSelectElement.cpp =================================================================== --- WebCore/html/HTMLSelectElement.cpp (revision 16269) +++ WebCore/html/HTMLSelectElement.cpp (working copy) @@ -262,7 +262,7 @@ return result; } -void HTMLSelectElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLSelectElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { bool oldShouldUseMenuList = shouldUseMenuList(); if (attr->name() == sizeAttr) { @@ -282,13 +282,13 @@ } else if (attr->name() == accesskeyAttr) { // FIXME: ignore for the moment } else if (attr->name() == onfocusAttr) { - setHTMLEventListener(focusEvent, attr); + setHTMLEventListener(focusEvent, attr, hook); } else if (attr->name() == onblurAttr) { - setHTMLEventListener(blurEvent, attr); + setHTMLEventListener(blurEvent, attr, hook); } else if (attr->name() == onchangeAttr) { - setHTMLEventListener(changeEvent, attr); + setHTMLEventListener(changeEvent, attr, hook); } else - HTMLGenericFormElement::parseMappedAttribute(attr); + HTMLGenericFormElement::parseMappedAttribute(attr, hook); } bool HTMLSelectElement::isKeyboardFocusable() const Index: WebCore/html/HTMLImageElement.cpp =================================================================== --- WebCore/html/HTMLImageElement.cpp (revision 16269) +++ WebCore/html/HTMLImageElement.cpp (working copy) @@ -84,7 +84,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLImageElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLImageElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { const QualifiedName& attrName = attr->name(); if (attrName == altAttr) { @@ -124,9 +124,9 @@ } else if (attrName == ismapAttr) ismap = true; else if (attrName == onabortAttr) - setHTMLEventListener(abortEvent, attr); + setHTMLEventListener(abortEvent, attr, hook); else if (attrName == onloadAttr) - setHTMLEventListener(loadEvent, attr); + setHTMLEventListener(loadEvent, attr, hook); else if (attrName == compositeAttr) { if (!parseCompositeOperator(attr->value(), m_compositeOperator)) m_compositeOperator = CompositeSourceOver; @@ -139,7 +139,7 @@ } oldNameAttr = newNameAttr; } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } String HTMLImageElement::altText() const Index: WebCore/html/HTMLLabelElement.h =================================================================== --- WebCore/html/HTMLLabelElement.h (revision 16269) +++ WebCore/html/HTMLLabelElement.h (working copy) @@ -42,7 +42,7 @@ virtual bool isFocusable() const; - virtual void parseMappedAttribute(MappedAttribute *attr); + virtual void parseMappedAttribute(MappedAttribute *attr, bool hook=false); virtual void accessKeyAction(bool sendToAnyElement); Index: WebCore/html/HTMLOptGroupElement.h =================================================================== --- WebCore/html/HTMLOptGroupElement.h (revision 16269) +++ WebCore/html/HTMLOptGroupElement.h (working copy) @@ -42,7 +42,7 @@ virtual bool removeChild(Node* child, ExceptionCode&); virtual bool appendChild(PassRefPtr newChild, ExceptionCode&); virtual ContainerNode* addChild(PassRefPtr); - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual bool rendererIsNeeded(RenderStyle*) { return false; } virtual void attach(); virtual void detach(); Index: WebCore/html/HTMLAppletElement.cpp =================================================================== --- WebCore/html/HTMLAppletElement.cpp (revision 16269) +++ WebCore/html/HTMLAppletElement.cpp (working copy) @@ -48,7 +48,7 @@ #endif } -void HTMLAppletElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLAppletElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == altAttr || attr->name() == archiveAttr || @@ -74,9 +74,9 @@ } oldIdAttr = newIdAttr; // also call superclass - HTMLPlugInElement::parseMappedAttribute(attr); + HTMLPlugInElement::parseMappedAttribute(attr, hook); } else - HTMLPlugInElement::parseMappedAttribute(attr); + HTMLPlugInElement::parseMappedAttribute(attr, hook); } void HTMLAppletElement::insertedIntoDocument() Index: WebCore/html/HTMLDivElement.h =================================================================== --- WebCore/html/HTMLDivElement.h (revision 16269) +++ WebCore/html/HTMLDivElement.h (working copy) @@ -37,7 +37,7 @@ virtual int tagPriority() const { return 5; } virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const; - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); String align() const; void setAlign(const String&); Index: WebCore/html/HTMLMetaElement.h =================================================================== --- WebCore/html/HTMLMetaElement.h (revision 16269) +++ WebCore/html/HTMLMetaElement.h (working copy) @@ -37,7 +37,7 @@ virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; } virtual int tagPriority() const { return 0; } - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual void insertedIntoDocument(); void process(); Index: WebCore/html/HTMLIFrameElement.cpp =================================================================== --- WebCore/html/HTMLIFrameElement.cpp (revision 16269) +++ WebCore/html/HTMLIFrameElement.cpp (working copy) @@ -65,7 +65,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLIFrameElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLIFrameElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == widthAttr) addCSSLength(attr, CSS_PROP_WIDTH, attr->value()); @@ -82,7 +82,7 @@ } oldNameAttr = newNameAttr; } else - HTMLFrameElement::parseMappedAttribute(attr); + HTMLFrameElement::parseMappedAttribute(attr, hook); } void HTMLIFrameElement::insertedIntoDocument() Index: WebCore/html/HTMLInputElement.h =================================================================== --- WebCore/html/HTMLInputElement.h (revision 16269) +++ WebCore/html/HTMLInputElement.h (working copy) @@ -118,7 +118,7 @@ virtual void accessKeyAction(bool sendToAnyElement); virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const; - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual void copyNonAttributeProperties(const Element* source); Index: WebCore/html/HTMLIsIndexElement.h =================================================================== --- WebCore/html/HTMLIsIndexElement.h (revision 16269) +++ WebCore/html/HTMLIsIndexElement.h (working copy) @@ -37,7 +37,7 @@ virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; } virtual int tagPriority() const { return 0; } - virtual void parseMappedAttribute(MappedAttribute *attr); + virtual void parseMappedAttribute(MappedAttribute *attr, bool hook=false); String prompt() const; void setPrompt(const String &); Index: WebCore/html/HTMLBRElement.h =================================================================== --- WebCore/html/HTMLBRElement.h (revision 16269) +++ WebCore/html/HTMLBRElement.h (working copy) @@ -40,7 +40,7 @@ virtual int tagPriority() const { return 0; } virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const; - virtual void parseMappedAttribute(MappedAttribute *attr); + virtual void parseMappedAttribute(MappedAttribute *attr, bool hook=false); virtual RenderObject *createRenderer(RenderArena*, RenderStyle*); Index: WebCore/html/HTMLAreaElement.h =================================================================== --- WebCore/html/HTMLAreaElement.h (revision 16269) +++ WebCore/html/HTMLAreaElement.h (working copy) @@ -41,7 +41,7 @@ virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; } virtual int tagPriority() const { return 0; } - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); bool isDefault() const { return m_shape == Default; } Index: WebCore/html/HTMLTextAreaElement.h =================================================================== --- WebCore/html/HTMLTextAreaElement.h (revision 16269) +++ WebCore/html/HTMLTextAreaElement.h (working copy) @@ -63,7 +63,7 @@ void setSelectionRange(int, int); virtual void childrenChanged(); - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); virtual bool appendFormData(FormDataList&, bool); virtual void reset(); Index: WebCore/html/HTMLSelectElement.h =================================================================== --- WebCore/html/HTMLSelectElement.h (revision 16269) +++ WebCore/html/HTMLSelectElement.h (working copy) @@ -86,7 +86,7 @@ virtual void childrenChanged(); - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual RenderObject* createRenderer(RenderArena*, RenderStyle *); virtual bool appendFormData(FormDataList&, bool); Index: WebCore/html/HTMLKeygenElement.h =================================================================== --- WebCore/html/HTMLKeygenElement.h (revision 16269) +++ WebCore/html/HTMLKeygenElement.h (working copy) @@ -37,7 +37,7 @@ virtual int tagPriority() const { return 0; } virtual const AtomicString& type() const; virtual bool isEnumeratable() const { return false; } - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual bool appendFormData(FormDataList&, bool); private: Index: WebCore/html/HTMLFrameElement.cpp =================================================================== --- WebCore/html/HTMLFrameElement.cpp (revision 16269) +++ WebCore/html/HTMLFrameElement.cpp (working copy) @@ -125,13 +125,13 @@ parentFrame->requestFrame(this, relativeURL, m_name); } -void HTMLFrameElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLFrameElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == srcAttr) setLocation(parseURL(attr->value())); else if (attr->name() == idAttr) { // Important to call through to base for the id attribute so the hasID bit gets set. - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); m_name = attr->value(); } else if (attr->name() == nameAttr) { m_name = attr->value(); @@ -163,14 +163,14 @@ if (contentFrame()) contentFrame()->setInViewSourceMode(viewSourceMode()); } else if (attr->name() == onloadAttr) { - setHTMLEventListener(loadEvent, attr); + setHTMLEventListener(loadEvent, attr, hook); } else if (attr->name() == onbeforeunloadAttr) { // FIXME: should elements have beforeunload handlers? - setHTMLEventListener(beforeunloadEvent, attr); + setHTMLEventListener(beforeunloadEvent, attr, hook); } else if (attr->name() == onunloadAttr) { - setHTMLEventListener(unloadEvent, attr); + setHTMLEventListener(unloadEvent, attr, hook); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } bool HTMLFrameElement::rendererIsNeeded(RenderStyle *style) Index: WebCore/html/HTMLOListElement.cpp =================================================================== --- WebCore/html/HTMLOListElement.cpp (revision 16269) +++ WebCore/html/HTMLOListElement.cpp (working copy) @@ -1,3 +1,4 @@ + /** * This file is part of the DOM implementation for KDE. * @@ -47,7 +48,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLOListElement::parseMappedAttribute(MappedAttribute* attr) +void HTMLOListElement::parseMappedAttribute(MappedAttribute* attr, bool hook) { if (attr->name() == typeAttr) { if (attr->value() == "a") @@ -63,7 +64,7 @@ } else if (attr->name() == startAttr) m_start = !attr->isNull() ? attr->value().toInt() : 1; else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } bool HTMLOListElement::compact() const Index: WebCore/html/HTMLLinkElement.cpp =================================================================== --- WebCore/html/HTMLLinkElement.cpp (revision 16269) +++ WebCore/html/HTMLLinkElement.cpp (working copy) @@ -101,7 +101,7 @@ return m_sheet.get(); } -void HTMLLinkElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLLinkElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == relAttr) { tokenizeRelAttribute(attr->value()); @@ -118,7 +118,7 @@ } else if (attr->name() == disabledAttr) { setDisabledState(!attr->isNull()); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& relStr) Index: WebCore/html/HTMLMarqueeElement.cpp =================================================================== --- WebCore/html/HTMLMarqueeElement.cpp (revision 16269) +++ WebCore/html/HTMLMarqueeElement.cpp (working copy) @@ -60,7 +60,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLMarqueeElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLMarqueeElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == widthAttr) { if (!attr->value().isEmpty()) @@ -103,7 +103,7 @@ } else if (attr->name() == truespeedAttr) m_minimumDelay = !attr->isNull() ? 0 : defaultMinimumDelay; else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } } Index: WebCore/html/HTMLFormElement.cpp =================================================================== --- WebCore/html/HTMLFormElement.cpp (revision 16269) +++ WebCore/html/HTMLFormElement.cpp (working copy) @@ -403,7 +403,7 @@ m_inreset = false; } -void HTMLFormElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLFormElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == actionAttr) { bool oldURLWasSecure = formWouldHaveSecureSubmission(m_url); @@ -434,9 +434,9 @@ } else if (attr->name() == autocompleteAttr) m_autocomplete = !equalIgnoringCase(attr->value(), "off"); else if (attr->name() == onsubmitAttr) - setHTMLEventListener(submitEvent, attr); + setHTMLEventListener(submitEvent, attr, hook); else if (attr->name() == onresetAttr) - setHTMLEventListener(resetEvent, attr); + setHTMLEventListener(resetEvent, attr, hook); else if (attr->name() == nameAttr) { String newNameAttr = attr->value(); if (inDocument() && document()->isHTMLDocument()) { @@ -446,7 +446,7 @@ } oldNameAttr = newNameAttr; } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } template static void removeFromVector(Vector & vec, T* item) Index: WebCore/html/HTMLPlugInElement.h =================================================================== --- WebCore/html/HTMLPlugInElement.h (revision 16269) +++ WebCore/html/HTMLPlugInElement.h (working copy) @@ -39,7 +39,7 @@ ~HTMLPlugInElement(); virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const; - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual void detach(); Index: WebCore/html/HTMLFrameSetElement.cpp =================================================================== --- WebCore/html/HTMLFrameSetElement.cpp (revision 16269) +++ WebCore/html/HTMLFrameSetElement.cpp (working copy) @@ -67,7 +67,7 @@ return newChild->hasTagName(framesetTag) || newChild->hasTagName(frameTag); } -void HTMLFrameSetElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLFrameSetElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == rowsAttr) { if (!attr->isNull()) { @@ -95,13 +95,13 @@ if(!m_border) frameborder = false; } else if (attr->name() == onloadAttr) { - document()->setHTMLWindowEventListener(loadEvent, attr); + document()->setHTMLWindowEventListener(loadEvent, attr, this, hook); } else if (attr->name() == onbeforeunloadAttr) { - document()->setHTMLWindowEventListener(beforeunloadEvent, attr); + document()->setHTMLWindowEventListener(beforeunloadEvent, attr, this, hook); } else if (attr->name() == onunloadAttr) { - document()->setHTMLWindowEventListener(unloadEvent, attr); + document()->setHTMLWindowEventListener(unloadEvent, attr, this, hook); } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } bool HTMLFrameSetElement::rendererIsNeeded(RenderStyle *style) Index: WebCore/html/HTMLIFrameElement.h =================================================================== --- WebCore/html/HTMLIFrameElement.h (revision 16269) +++ WebCore/html/HTMLIFrameElement.h (working copy) @@ -40,7 +40,7 @@ virtual int tagPriority() const { return 1; } virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const; - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual void insertedIntoDocument(); virtual void removedFromDocument(); Index: WebCore/html/HTMLAreaElement.cpp =================================================================== --- WebCore/html/HTMLAreaElement.cpp (revision 16269) +++ WebCore/html/HTMLAreaElement.cpp (working copy) @@ -48,7 +48,7 @@ delete [] m_coords; } -void HTMLAreaElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLAreaElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == shapeAttr) { if (equalIgnoringCase(attr->value(), "default")) @@ -65,7 +65,7 @@ } else if (attr->name() == altAttr || attr->name() == accesskeyAttr) { // Do nothing. } else - HTMLAnchorElement::parseMappedAttribute(attr); + HTMLAnchorElement::parseMappedAttribute(attr, hook); } bool HTMLAreaElement::mapMouseEvent(int x, int y, const IntSize& size, RenderObject::NodeInfo& info) Index: WebCore/html/HTMLAnchorElement.cpp =================================================================== --- WebCore/html/HTMLAnchorElement.cpp (revision 16269) +++ WebCore/html/HTMLAnchorElement.cpp (working copy) @@ -173,7 +173,7 @@ } if (!evt->defaultPrevented() && document()->frame()) - document()->frame()->urlSelected(url, utarget); + document()->frame()->urlSelected(this, ResourceRequest(document()->frame()->completeURL(url)), utarget); evt->setDefaultHandled(); } @@ -188,7 +188,7 @@ ContainerNode::setActive(down, pause); } -void HTMLAnchorElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLAnchorElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == hrefAttr) { bool wasLink = m_isLink; @@ -200,7 +200,7 @@ attr->name() == relAttr) { // Do nothing. } else - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } void HTMLAnchorElement::accessKeyAction(bool sendToAnyElement) Index: WebCore/html/HTMLFontElement.h =================================================================== --- WebCore/html/HTMLFontElement.h (revision 16269) +++ WebCore/html/HTMLFontElement.h (working copy) @@ -40,7 +40,7 @@ virtual int tagPriority() const { return 1; } virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const; - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); String color() const; void setColor(const String&); Index: WebCore/html/HTMLButtonElement.cpp =================================================================== --- WebCore/html/HTMLButtonElement.cpp (revision 16269) +++ WebCore/html/HTMLButtonElement.cpp (working copy) @@ -61,7 +61,7 @@ return getAttribute(typeAttr); } -void HTMLButtonElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLButtonElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == typeAttr) { if (equalIgnoringCase(attr->value(), "submit")) @@ -76,11 +76,11 @@ } else if (attr->name() == accesskeyAttr) { // Do nothing. } else if (attr->name() == onfocusAttr) { - setHTMLEventListener(focusEvent, attr); + setHTMLEventListener(focusEvent, attr, hook); } else if (attr->name() == onblurAttr) { - setHTMLEventListener(blurEvent, attr); + setHTMLEventListener(blurEvent, attr, hook); } else - HTMLGenericFormElement::parseMappedAttribute(attr); + HTMLGenericFormElement::parseMappedAttribute(attr, hook); } void HTMLButtonElement::defaultEventHandler(Event *evt) Index: WebCore/html/HTMLCanvasElement.cpp =================================================================== --- WebCore/html/HTMLCanvasElement.cpp (revision 16269) +++ WebCore/html/HTMLCanvasElement.cpp (working copy) @@ -63,12 +63,12 @@ delete m_drawingContext; } -void HTMLCanvasElement::parseMappedAttribute(MappedAttribute* attr) +void HTMLCanvasElement::parseMappedAttribute(MappedAttribute* attr, bool hook) { const QualifiedName& attrName = attr->name(); if (attrName == widthAttr || attrName == heightAttr) reset(); - HTMLElement::parseMappedAttribute(attr); + HTMLElement::parseMappedAttribute(attr, hook); } RenderObject* HTMLCanvasElement::createRenderer(RenderArena *arena, RenderStyle *style) Index: WebCore/html/HTMLObjectElement.h =================================================================== --- WebCore/html/HTMLObjectElement.h (revision 16269) +++ WebCore/html/HTMLObjectElement.h (working copy) @@ -49,7 +49,7 @@ virtual int tagPriority() const { return 7; } - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual void attach(); virtual bool rendererIsNeeded(RenderStyle*); Index: WebCore/html/HTMLBaseElement.h =================================================================== --- WebCore/html/HTMLBaseElement.h (revision 16269) +++ WebCore/html/HTMLBaseElement.h (working copy) @@ -40,7 +40,7 @@ String href() const { return m_href; } String target() const { return m_target; } - virtual void parseMappedAttribute(MappedAttribute*); + virtual void parseMappedAttribute(MappedAttribute*, bool hook=false); virtual void insertedIntoDocument(); virtual void removedFromDocument(); Index: WebCore/html/HTMLPreElement.cpp =================================================================== --- WebCore/html/HTMLPreElement.cpp (revision 16269) +++ WebCore/html/HTMLPreElement.cpp (working copy) @@ -46,7 +46,7 @@ return HTMLElement::mapToEntry(attrName, result); } -void HTMLPreElement::parseMappedAttribute(MappedAttribute *attr) +void HTMLPreElement::parseMappedAttribute(MappedAttribute *attr, bool hook) { if (attr->name() == widthAttr) { // FIXME: Implement this some day. Width on a
 is the # of characters that
@@ -57,7 +57,7 @@
         if (!attr->value().isNull())
             addCSSProperty(attr, CSS_PROP_WHITE_SPACE, CSS_VAL_PRE_WRAP);
     } else
-        return HTMLElement::parseMappedAttribute(attr);
+        return HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 int HTMLPreElement::width() const
Index: WebCore/html/HTMLTableColElement.h
===================================================================
--- WebCore/html/HTMLTableColElement.h	(revision 16269)
+++ WebCore/html/HTMLTableColElement.h	(working copy)
@@ -46,7 +46,7 @@
 
     // overrides
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     int span() const { return _span; }
 
Index: WebCore/html/HTMLBodyElement.h
===================================================================
--- WebCore/html/HTMLBodyElement.h	(revision 16269)
+++ WebCore/html/HTMLBodyElement.h	(working copy)
@@ -40,7 +40,7 @@
     virtual int tagPriority() const { return 10; }
     
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     virtual void insertedIntoDocument();
 
Index: WebCore/html/HTMLMarqueeElement.h
===================================================================
--- WebCore/html/HTMLMarqueeElement.h	(revision 16269)
+++ WebCore/html/HTMLMarqueeElement.h	(working copy)
@@ -36,7 +36,7 @@
     virtual int tagPriority() const { return 3; }
 
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     int minimumDelay() const { return m_minimumDelay; }
     
Index: WebCore/html/HTMLParagraphElement.cpp
===================================================================
--- WebCore/html/HTMLParagraphElement.cpp	(revision 16269)
+++ WebCore/html/HTMLParagraphElement.cpp	(working copy)
@@ -52,7 +52,7 @@
     return HTMLElement::mapToEntry(attrName, result);
 }
 
-void HTMLParagraphElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLParagraphElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == alignAttr) {
         String v = attr->value();
@@ -65,7 +65,7 @@
         else
             addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, v);
     } else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 String HTMLParagraphElement::align() const
Index: WebCore/html/HTMLTokenizer.h
===================================================================
--- WebCore/html/HTMLTokenizer.h	(revision 16269)
+++ WebCore/html/HTMLTokenizer.h	(working copy)
@@ -113,7 +113,7 @@
     State parseEntity(SegmentedString&, UChar*& dest, State, unsigned& _cBufferPos, bool start, bool parsingTag);
     State parseProcessingInstruction(SegmentedString&, State);
     State scriptHandler(State);
-    State scriptExecution(const DeprecatedString& script, State state, DeprecatedString scriptURL = DeprecatedString(), int baseLine = 0);
+    State scriptExecution(const DeprecatedString& script, State state, PassRefPtr,  DeprecatedString scriptURL = DeprecatedString(), int baseLine = 0);
     void setSrc(const SegmentedString&);
 
     // check if we have enough space in the buffer.
@@ -145,7 +145,7 @@
     UChar* dest;
 
     Token currToken;
-
+    RefPtr currTokenNode;
     // the size of buffer
     int size;
 
Index: WebCore/html/HTMLUListElement.h
===================================================================
--- WebCore/html/HTMLUListElement.h	(revision 16269)
+++ WebCore/html/HTMLUListElement.h	(working copy)
@@ -37,7 +37,7 @@
     virtual int tagPriority() const { return 5; }
 
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     bool compact() const;
     void setCompact(bool);
Index: WebCore/html/HTMLFormElement.h
===================================================================
--- WebCore/html/HTMLFormElement.h	(revision 16269)
+++ WebCore/html/HTMLFormElement.h	(working copy)
@@ -60,7 +60,7 @@
 
     bool autoComplete() const { return m_autocomplete; }
 
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     void registerFormElement(HTMLGenericFormElement*);
     void removeFormElement(HTMLGenericFormElement*);
Index: WebCore/html/HTMLTableCaptionElement.h
===================================================================
--- WebCore/html/HTMLTableCaptionElement.h	(revision 16269)
+++ WebCore/html/HTMLTableCaptionElement.h	(working copy)
@@ -41,7 +41,7 @@
     virtual int tagPriority() const { return 5; }
     
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     String align() const;
     void setAlign(const String&);
Index: WebCore/html/HTMLElement.cpp
===================================================================
--- WebCore/html/HTMLElement.cpp	(revision 16269)
+++ WebCore/html/HTMLElement.cpp	(working copy)
@@ -120,10 +120,10 @@
     return StyledElement::mapToEntry(attrName, result);
 }
     
-void HTMLElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == idAttr || attr->name() == classAttr || attr->name() == styleAttr)
-        return StyledElement::parseMappedAttribute(attr);
+        return StyledElement::parseMappedAttribute(attr, hook);
 
     String indexstring;
     if (attr->name() == alignAttr) {
@@ -145,67 +145,67 @@
     }
 // standard events
     else if (attr->name() == onclickAttr) {
-        setHTMLEventListener(clickEvent, attr);
+        setHTMLEventListener(clickEvent, attr, hook);
     } else if (attr->name() == oncontextmenuAttr) {
-        setHTMLEventListener(contextmenuEvent, attr);
+        setHTMLEventListener(contextmenuEvent, attr, hook);
     } else if (attr->name() == ondblclickAttr) {
-        setHTMLEventListener(dblclickEvent, attr);
+        setHTMLEventListener(dblclickEvent, attr, hook);
     } else if (attr->name() == onmousedownAttr) {
-        setHTMLEventListener(mousedownEvent, attr);
+        setHTMLEventListener(mousedownEvent, attr, hook);
     } else if (attr->name() == onmousemoveAttr) {
-        setHTMLEventListener(mousemoveEvent, attr);
+        setHTMLEventListener(mousemoveEvent, attr, hook);
     } else if (attr->name() == onmouseoutAttr) {
-        setHTMLEventListener(mouseoutEvent, attr);
+        setHTMLEventListener(mouseoutEvent, attr, hook);
     } else if (attr->name() == onmouseoverAttr) {
-        setHTMLEventListener(mouseoverEvent, attr);
+        setHTMLEventListener(mouseoverEvent, attr, hook);
     } else if (attr->name() == onmouseupAttr) {
-        setHTMLEventListener(mouseupEvent, attr);
+        setHTMLEventListener(mouseupEvent, attr, hook);
     } else if (attr->name() == onmousewheelAttr) {
-        setHTMLEventListener(mousewheelEvent, attr);
+        setHTMLEventListener(mousewheelEvent, attr, hook);
     } else if (attr->name() == onfocusAttr) {
-        setHTMLEventListener(focusEvent, attr);
+        setHTMLEventListener(focusEvent, attr, hook);
     } else if (attr->name() == onblurAttr) {
-        setHTMLEventListener(blurEvent, attr);
+        setHTMLEventListener(blurEvent, attr, hook);
     } else if (attr->name() == onkeydownAttr) {
-        setHTMLEventListener(keydownEvent, attr);
+        setHTMLEventListener(keydownEvent, attr, hook);
     } else if (attr->name() == onkeypressAttr) {
-        setHTMLEventListener(keypressEvent, attr);
+        setHTMLEventListener(keypressEvent, attr, hook);
     } else if (attr->name() == onkeyupAttr) {
-        setHTMLEventListener(keyupEvent, attr);
+        setHTMLEventListener(keyupEvent, attr, hook);
     } else if (attr->name() == onscrollAttr) {
-        setHTMLEventListener(scrollEvent, attr);
+        setHTMLEventListener(scrollEvent, attr, hook);
     } else if (attr->name() == onbeforecutAttr) {
-        setHTMLEventListener(beforecutEvent, attr);
+        setHTMLEventListener(beforecutEvent, attr, hook);
     } else if (attr->name() == oncutAttr) {
-        setHTMLEventListener(cutEvent, attr);
+        setHTMLEventListener(cutEvent, attr, hook);
     } else if (attr->name() == onbeforecopyAttr) {
-        setHTMLEventListener(beforecopyEvent, attr);
+        setHTMLEventListener(beforecopyEvent, attr, hook);
     } else if (attr->name() == oncopyAttr) {
-        setHTMLEventListener(copyEvent, attr);
+        setHTMLEventListener(copyEvent, attr, hook);
     } else if (attr->name() == onbeforepasteAttr) {
-        setHTMLEventListener(beforepasteEvent, attr);
+        setHTMLEventListener(beforepasteEvent, attr, hook);
     } else if (attr->name() == onpasteAttr) {
-        setHTMLEventListener(pasteEvent, attr);
+        setHTMLEventListener(pasteEvent, attr, hook);
     } else if (attr->name() == ondragenterAttr) {
-        setHTMLEventListener(dragenterEvent, attr);
+        setHTMLEventListener(dragenterEvent, attr, hook);
     } else if (attr->name() == ondragoverAttr) {
-        setHTMLEventListener(dragoverEvent, attr);
+        setHTMLEventListener(dragoverEvent, attr, hook);
     } else if (attr->name() == ondragleaveAttr) {
-        setHTMLEventListener(dragleaveEvent, attr);
+        setHTMLEventListener(dragleaveEvent, attr, hook);
     } else if (attr->name() == ondropAttr) {
-        setHTMLEventListener(dropEvent, attr);
+        setHTMLEventListener(dropEvent, attr, hook);
     } else if (attr->name() == ondragstartAttr) {
-        setHTMLEventListener(dragstartEvent, attr);
+        setHTMLEventListener(dragstartEvent, attr, hook);
     } else if (attr->name() == ondragAttr) {
-        setHTMLEventListener(dragEvent, attr);
+        setHTMLEventListener(dragEvent, attr, hook);
     } else if (attr->name() == ondragendAttr) {
-        setHTMLEventListener(dragendEvent, attr);
+        setHTMLEventListener(dragendEvent, attr, hook);
     } else if (attr->name() == onselectstartAttr) {
-        setHTMLEventListener(selectstartEvent, attr);
+        setHTMLEventListener(selectstartEvent, attr, hook);
     } else if (attr->name() == onsubmitAttr) {
-        setHTMLEventListener(submitEvent, attr);
+        setHTMLEventListener(submitEvent, attr, hook);
     } else if (attr->name() == onerrorAttr) {
-        setHTMLEventListener(errorEvent, attr);
+        setHTMLEventListener(errorEvent, attr, hook);
     }
 }
 
@@ -239,7 +239,7 @@
     return innerText();
 }
 
-PassRefPtr HTMLElement::createContextualFragment(const String &html)
+PassRefPtr HTMLElement::createContextualFragment(const String &html, bool setParent)
 {
     // the following is in accordance with the definition as used by IE
     if (endTagRequirement() == TagStatusForbidden)
@@ -251,8 +251,17 @@
 
     RefPtr fragment = new DocumentFragment(document());
     
-    if (document()->isHTMLDocument())
-         parseHTMLDocumentFragment(html, fragment.get());
+    if (document()->isHTMLDocument()) {
+      if (setParent) {
+	fragment.get()->setParent(this);
+	fragment.get()->setKeepAlive(true);
+      }
+      parseHTMLDocumentFragment(html, fragment.get());
+      if (setParent) {
+	fragment.get()->setParent(0);
+	fragment.get()->setKeepAlive(false);
+      }
+    }
     else {
         if (!parseXMLDocumentFragment(html, fragment.get(), this))
             // FIXME: We should propagate a syntax error exception out here.
@@ -294,7 +303,7 @@
 
 void HTMLElement::setInnerHTML(const String &html, ExceptionCode& ec)
 {
-    RefPtr fragment = createContextualFragment(html);
+    RefPtr fragment = createContextualFragment(html, true);
     if (!fragment) {
         ec = NO_MODIFICATION_ALLOWED_ERR;
         return;
@@ -871,10 +880,10 @@
     return inEitherTagList(newChild);
 }
 
-void HTMLElement::setHTMLEventListener(const AtomicString& eventType, Attribute* attr)
+void HTMLElement::setHTMLEventListener(const AtomicString& eventType, Attribute* attr, bool hook)
 {
     Element::setHTMLEventListener(eventType,
-        document()->createHTMLEventListener(attr->localName().domString(), attr->value(), this));
+        document()->createHTMLEventListener(attr->localName().domString(), attr->value(), this, hook));
 }
 
 }
Index: WebCore/html/HTMLButtonElement.h
===================================================================
--- WebCore/html/HTMLButtonElement.h	(revision 16269)
+++ WebCore/html/HTMLButtonElement.h	(working copy)
@@ -41,7 +41,7 @@
         
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
 
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
     virtual void defaultEventHandler(Event*);
     virtual bool appendFormData(FormDataList&, bool);
 
Index: WebCore/html/HTMLCanvasElement.h
===================================================================
--- WebCore/html/HTMLCanvasElement.h	(revision 16269)
+++ WebCore/html/HTMLCanvasElement.h	(working copy)
@@ -55,7 +55,7 @@
     CanvasRenderingContext* getContext(const String&);
     // FIXME: Web Applications 1.0 describes a toDataURL function.
 
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
 
     IntSize size() const { return m_size; }
Index: WebCore/html/HTMLTablePartElement.h
===================================================================
--- WebCore/html/HTMLTablePartElement.h	(revision 16269)
+++ WebCore/html/HTMLTablePartElement.h	(working copy)
@@ -39,7 +39,7 @@
         { }
 
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 };
 
 } //namespace
Index: WebCore/html/HTMLImageElement.h
===================================================================
--- WebCore/html/HTMLImageElement.h	(revision 16269)
+++ WebCore/html/HTMLImageElement.h	(working copy)
@@ -43,7 +43,7 @@
     virtual int tagPriority() const { return 0; }
 
     virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     virtual void attach();
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
Index: WebCore/html/HTMLTokenizer.cpp
===================================================================
--- WebCore/html/HTMLTokenizer.cpp	(revision 16269)
+++ WebCore/html/HTMLTokenizer.cpp	(working copy)
@@ -135,6 +135,7 @@
     , inWrite(false)
     , m_fragment(false)
 {
+    currTokenNode = 0;
     begin();
 }
 
@@ -152,7 +153,9 @@
     , parser(0)
     , inWrite(false)
     , m_fragment(false)
+
 {
+    currTokenNode = 0;
     begin();
 }
 
@@ -168,7 +171,9 @@
     , m_doc(frag->document())
     , inWrite(false)
     , m_fragment(true)
+
 {
+    currTokenNode = 0;
     parser = new HTMLParser(frag);
     begin();
 }
@@ -356,7 +361,8 @@
     // (Bugzilla 3837) Scripts following a frameset element should not execute or, 
     // in the case of extern scripts, even load.
     bool followingFrameset = (m_doc->body() && m_doc->body()->hasTagName(framesetTag));
-  
+    
+    PassRefPtr scriptElementNode = this->currTokenNode.release();
     CachedScript* cs = 0;
     // don't load external scripts for standalone documents (for now)
     if (!inViewSourceMode()) {
@@ -369,8 +375,10 @@
 #endif
                 // The parser might have been stopped by for example a window.close call in an earlier script.
                 // If so, we don't want to load scripts.
-                if (!m_parserStopped && (cs = m_doc->docLoader()->requestScript(scriptSrc, scriptSrcCharset)))
-                    pendingScripts.enqueue(cs);
+                if (!m_parserStopped && (cs = m_doc->docLoader()->requestScript(scriptSrc, scriptSrcCharset))) {
+		  cs->setScriptElementNode(scriptElementNode.get());
+		  pendingScripts.enqueue(cs);
+		}
                 else
                     scriptNode = 0;
             } else
@@ -432,7 +440,7 @@
             else
                 prependingSrc = src;
             setSrc(SegmentedString());
-            state = scriptExecution(exScript, state, DeprecatedString::null, scriptStartLineno);
+            state = scriptExecution(exScript, state, scriptElementNode, DeprecatedString::null, scriptStartLineno);
         }
     }
 
@@ -465,7 +473,9 @@
     return state;
 }
 
-HTMLTokenizer::State HTMLTokenizer::scriptExecution(const DeprecatedString& str, State state, DeprecatedString scriptURL, int baseLine)
+HTMLTokenizer::State HTMLTokenizer::scriptExecution(const DeprecatedString& str, State state, 
+						    PassRefPtr scriptElementNode,
+						    DeprecatedString scriptURL, int baseLine)
 {
     if (m_fragment || !m_doc->frame())
         return state;
@@ -482,7 +492,7 @@
 #endif
 
     m_state = state;
-    m_doc->frame()->executeScript(url,baseLine,0,str);
+    m_doc->frame()->executeScript(url,baseLine,0,str,scriptElementNode.get());
     state = m_state;
 
     state.setAllowYield(true);
@@ -1633,7 +1643,8 @@
     currToken.reset();
     if (jsProxy)
         jsProxy->setEventHandlerLineno(0);
-
+    
+    currTokenNode = n;
     return n.release();
 }
 
@@ -1675,6 +1686,7 @@
         kdDebug( 6036 ) << "Finished loading an external script" << endl;
 #endif
         CachedScript* cs = pendingScripts.dequeue();
+	Node *scriptElementNode= cs->setScriptElementNode(0);
         ASSERT(cs->accessCount() > 0);
 
         String scriptSource = cs->script();
@@ -1699,7 +1711,7 @@
         if (errorOccurred)
             EventTargetNodeCast(n.get())->dispatchHTMLEvent(errorEvent, true, false);
         else {
-            m_state = scriptExecution(scriptSource.deprecatedString(), m_state, cachedScriptUrl);
+            m_state = scriptExecution(scriptSource.deprecatedString(), m_state, scriptElementNode, cachedScriptUrl );
             EventTargetNodeCast(n.get())->dispatchHTMLEvent(loadEvent, false, false);
         }
 
Index: WebCore/html/HTMLUListElement.cpp
===================================================================
--- WebCore/html/HTMLUListElement.cpp	(revision 16269)
+++ WebCore/html/HTMLUListElement.cpp	(working copy)
@@ -45,12 +45,12 @@
     return HTMLElement::mapToEntry(attrName, result);
 }
 
-void HTMLUListElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLUListElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == typeAttr)
         addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, attr->value());
     else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 bool HTMLUListElement::compact() const
Index: WebCore/html/HTMLGenericFormElement.h
===================================================================
--- WebCore/html/HTMLGenericFormElement.h	(revision 16269)
+++ WebCore/html/HTMLGenericFormElement.h	(working copy)
@@ -54,7 +54,7 @@
     virtual bool isControl() const { return true; }
     virtual bool isEnabled() const { return !disabled(); }
 
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
     virtual void attach();
     virtual void insertedIntoTree(bool deep);
     virtual void removedFromTree(bool deep);
Index: WebCore/html/HTMLLIElement.h
===================================================================
--- WebCore/html/HTMLLIElement.h	(revision 16269)
+++ WebCore/html/HTMLLIElement.h	(working copy)
@@ -37,7 +37,7 @@
     virtual int tagPriority() const { return 3; }
 
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     virtual void attach();
 
Index: WebCore/html/HTMLTextAreaElement.cpp
===================================================================
--- WebCore/html/HTMLTextAreaElement.cpp	(revision 16269)
+++ WebCore/html/HTMLTextAreaElement.cpp	(working copy)
@@ -124,7 +124,7 @@
     setValue(defaultValue());
 }
     
-void HTMLTextAreaElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLTextAreaElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == rowsAttr) {
         m_rows = !attr->isNull() ? attr->value().toInt() : 3;
@@ -150,15 +150,15 @@
     } else if (attr->name() == accesskeyAttr) {
         // ignore for the moment
     } else if (attr->name() == onfocusAttr)
-        setHTMLEventListener(focusEvent, attr);
+        setHTMLEventListener(focusEvent, attr, hook);
     else if (attr->name() == onblurAttr)
-        setHTMLEventListener(blurEvent, attr);
+        setHTMLEventListener(blurEvent, attr, hook);
     else if (attr->name() == onselectAttr)
-        setHTMLEventListener(selectEvent, attr);
+        setHTMLEventListener(selectEvent, attr, hook);
     else if (attr->name() == onchangeAttr)
-        setHTMLEventListener(changeEvent, attr);
+        setHTMLEventListener(changeEvent, attr, hook);
     else
-        HTMLGenericFormElement::parseMappedAttribute(attr);
+        HTMLGenericFormElement::parseMappedAttribute(attr, hook);
 }
 
 RenderObject* HTMLTextAreaElement::createRenderer(RenderArena* arena, RenderStyle* style)
Index: WebCore/html/HTMLElement.h
===================================================================
--- WebCore/html/HTMLElement.h	(revision 16269)
+++ WebCore/html/HTMLElement.h	(working copy)
@@ -46,7 +46,7 @@
     virtual String nodeName() const;
 
     virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     virtual PassRefPtr cloneNode(bool deep);
 
@@ -67,7 +67,7 @@
     String outerHTML() const;
     String innerText() const;
     String outerText() const;
-    PassRefPtr createContextualFragment(const String&);
+    PassRefPtr createContextualFragment(const String&, bool setParent=false);
     void setInnerHTML(const String&, ExceptionCode&);
     void setOuterHTML(const String&, ExceptionCode&);
     void setInnerText(const String&, ExceptionCode&);
@@ -98,7 +98,7 @@
     static bool inBlockTagList(const Node*);
     static bool isRecognizedTagName(const QualifiedName&);
 
-    void setHTMLEventListener(const AtomicString& eventType, Attribute*);
+    void setHTMLEventListener(const AtomicString& eventType, Attribute*, bool hook);
 
 protected:
 
Index: WebCore/html/HTMLFrameElement.h
===================================================================
--- WebCore/html/HTMLFrameElement.h	(revision 16269)
+++ WebCore/html/HTMLFrameElement.h	(working copy)
@@ -48,7 +48,7 @@
     virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
     virtual int tagPriority() const { return 0; }
   
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook =false);
     virtual void attach();
     void close();
     virtual void willRemove();
Index: WebCore/html/HTMLOListElement.h
===================================================================
--- WebCore/html/HTMLOListElement.h	(revision 16269)
+++ WebCore/html/HTMLOListElement.h	(working copy)
@@ -37,7 +37,7 @@
     virtual int tagPriority() const { return 5; }
 
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     bool compact() const;
     void setCompact(bool);
Index: WebCore/html/HTMLGenericFormElement.cpp
===================================================================
--- WebCore/html/HTMLGenericFormElement.cpp	(revision 16269)
+++ WebCore/html/HTMLGenericFormElement.cpp	(working copy)
@@ -54,7 +54,7 @@
         m_form->removeFormElement(this);
 }
 
-void HTMLGenericFormElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLGenericFormElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == nameAttr) {
         // Do nothing.
@@ -75,7 +75,7 @@
                 theme()->stateChanged(renderer(), ReadOnlyState);
         }
     } else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 void HTMLGenericFormElement::attach()
Index: WebCore/html/HTMLLIElement.cpp
===================================================================
--- WebCore/html/HTMLLIElement.cpp	(revision 16269)
+++ WebCore/html/HTMLLIElement.cpp	(working copy)
@@ -48,7 +48,7 @@
     return HTMLElement::mapToEntry(attrName, result);
 }
 
-void HTMLLIElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLLIElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == valueAttr) {
         m_isValued = true;
@@ -73,7 +73,7 @@
         else
             addCSSProperty(attr, CSS_PROP_LIST_STYLE_TYPE, attr->value());
     } else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 void HTMLLIElement::attach()
Index: WebCore/html/HTMLStyleElement.h
===================================================================
--- WebCore/html/HTMLStyleElement.h	(revision 16269)
+++ WebCore/html/HTMLStyleElement.h	(working copy)
@@ -41,7 +41,7 @@
     StyleSheet* sheet() const;
 
     // overload from HTMLElement
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
     virtual void childrenChanged();
Index: WebCore/html/HTMLFrameSetElement.h
===================================================================
--- WebCore/html/HTMLFrameSetElement.h	(revision 16269)
+++ WebCore/html/HTMLFrameSetElement.h	(working copy)
@@ -41,7 +41,7 @@
     virtual int tagPriority() const { return 10; }
     virtual bool checkDTD(const Node* newChild);
 
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
     virtual void attach();
     virtual bool rendererIsNeeded(RenderStyle*);
     virtual RenderObject *createRenderer(RenderArena*, RenderStyle*);
Index: WebCore/html/HTMLHRElement.h
===================================================================
--- WebCore/html/HTMLHRElement.h	(revision 16269)
+++ WebCore/html/HTMLHRElement.h	(working copy)
@@ -37,7 +37,7 @@
     virtual int tagPriority() const { return 0; }
     
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     String align() const;
     void setAlign(const String&);
Index: WebCore/html/HTMLAnchorElement.h
===================================================================
--- WebCore/html/HTMLAnchorElement.h	(revision 16269)
+++ WebCore/html/HTMLAnchorElement.h	(working copy)
@@ -44,7 +44,7 @@
     virtual bool isMouseFocusable() const;
     virtual bool isKeyboardFocusable() const;
     virtual bool isFocusable() const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
     virtual void defaultEventHandler(Event*);
     virtual void setActive(bool active = true, bool pause = false);
     virtual void accessKeyAction(bool fullAction);
Index: WebCore/html/HTMLEmbedElement.h
===================================================================
--- WebCore/html/HTMLEmbedElement.h	(revision 16269)
+++ WebCore/html/HTMLEmbedElement.h	(working copy)
@@ -46,7 +46,7 @@
     virtual int tagPriority() const { return 0; }
 
     virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     virtual void attach();
     virtual void detach();
Index: WebCore/html/HTMLDivElement.cpp
===================================================================
--- WebCore/html/HTMLDivElement.cpp	(revision 16269)
+++ WebCore/html/HTMLDivElement.cpp	(working copy)
@@ -50,7 +50,7 @@
     return HTMLElement::mapToEntry(attrName, result);
 }
 
-void HTMLDivElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLDivElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == alignAttr) {
         String v = attr->value();
@@ -63,7 +63,7 @@
         else
             addCSSProperty(attr, CSS_PROP_TEXT_ALIGN, v);
     } else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 String HTMLDivElement::align() const
Index: WebCore/html/HTMLMapElement.h
===================================================================
--- WebCore/html/HTMLMapElement.h	(revision 16269)
+++ WebCore/html/HTMLMapElement.h	(working copy)
@@ -41,7 +41,7 @@
 
     const AtomicString& getName() const { return m_name; }
 
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*,bool hook=false);
 
     bool mapMouseEvent(int x, int y, const IntSize&, RenderObject::NodeInfo&);
 
Index: WebCore/html/HTMLTableColElement.cpp
===================================================================
--- WebCore/html/HTMLTableColElement.cpp	(revision 16269)
+++ WebCore/html/HTMLTableColElement.cpp	(working copy)
@@ -65,7 +65,7 @@
     return HTMLTablePartElement::mapToEntry(attrName, result);
 }
 
-void HTMLTableColElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLTableColElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == spanAttr) {
         _span = !attr->isNull() ? attr->value().toInt() : 1;
@@ -75,7 +75,7 @@
         if (!attr->value().isEmpty())
             addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
     } else
-        HTMLTablePartElement::parseMappedAttribute(attr);
+        HTMLTablePartElement::parseMappedAttribute(attr, hook);
 }
 
 String HTMLTableColElement::align() const
Index: WebCore/html/HTMLMetaElement.cpp
===================================================================
--- WebCore/html/HTMLMetaElement.cpp	(revision 16269)
+++ WebCore/html/HTMLMetaElement.cpp	(working copy)
@@ -40,7 +40,7 @@
 {
 }
 
-void HTMLMetaElement::parseMappedAttribute(MappedAttribute* attr)
+void HTMLMetaElement::parseMappedAttribute(MappedAttribute* attr, bool hook)
 {
     if (attr->name() == http_equivAttr) {
         m_equiv = attr->value();
@@ -51,7 +51,7 @@
     } else if (attr->name() == nameAttr) {
         // Do nothing.
     } else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 void HTMLMetaElement::insertedIntoDocument()
Index: WebCore/html/HTMLTableCellElement.cpp
===================================================================
--- WebCore/html/HTMLTableCellElement.cpp	(revision 16269)
+++ WebCore/html/HTMLTableCellElement.cpp	(working copy)
@@ -78,7 +78,7 @@
     return HTMLTablePartElement::mapToEntry(attrName, result);
 }
 
-void HTMLTableCellElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLTableCellElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == rowspanAttr) {
         rSpan = !attr->isNull() ? attr->value().toInt() : 1;
@@ -106,7 +106,7 @@
                 addCSSLength(attr, CSS_PROP_HEIGHT, attr->value());
         }
     } else
-        HTMLTablePartElement::parseMappedAttribute(attr);
+        HTMLTablePartElement::parseMappedAttribute(attr, hook);
 }
 
 // used by table cells to share style decls created by the enclosing table.
Index: WebCore/html/HTMLAppletElement.h
===================================================================
--- WebCore/html/HTMLAppletElement.h	(revision 16269)
+++ WebCore/html/HTMLAppletElement.h	(working copy)
@@ -46,7 +46,7 @@
 
     virtual int tagPriority() const { return 1; }
 
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook = false);
     
     virtual bool rendererIsNeeded(RenderStyle*);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
Index: WebCore/html/HTMLPreElement.h
===================================================================
--- WebCore/html/HTMLPreElement.h	(revision 16269)
+++ WebCore/html/HTMLPreElement.h	(working copy)
@@ -36,7 +36,7 @@
     virtual int tagPriority() const { return 5; }
 
     bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    void parseMappedAttribute(MappedAttribute*);
+    void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     int width() const;
     void setWidth(int w);
Index: WebCore/html/HTMLBodyElement.cpp
===================================================================
--- WebCore/html/HTMLBodyElement.cpp	(revision 16269)
+++ WebCore/html/HTMLBodyElement.cpp	(working copy)
@@ -83,7 +83,7 @@
     return HTMLElement::mapToEntry(attrName, result);
 }
 
-void HTMLBodyElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLBodyElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == backgroundAttr) {
         String url = parseURL(attr->value());
@@ -131,21 +131,21 @@
         if (attached())
             document()->recalcStyle(Force);
     } else if (attr->name() == onloadAttr) {
-        document()->setHTMLWindowEventListener(loadEvent, attr);
+        document()->setHTMLWindowEventListener(loadEvent, attr, this, hook);
     } else if (attr->name() == onbeforeunloadAttr) {
-        document()->setHTMLWindowEventListener(beforeunloadEvent, attr);
+        document()->setHTMLWindowEventListener(beforeunloadEvent, attr, this, hook);
     } else if (attr->name() == onunloadAttr) {
-        document()->setHTMLWindowEventListener(unloadEvent, attr);
+        document()->setHTMLWindowEventListener(unloadEvent, attr, this, hook);
     } else if (attr->name() == onblurAttr) {
-        document()->setHTMLWindowEventListener(blurEvent, attr);
+        document()->setHTMLWindowEventListener(blurEvent, attr, this, hook);
     } else if (attr->name() == onfocusAttr) {
-        document()->setHTMLWindowEventListener(focusEvent, attr);
+        document()->setHTMLWindowEventListener(focusEvent, attr, this, hook);
     } else if (attr->name() == onresizeAttr) {
-        document()->setHTMLWindowEventListener(resizeEvent, attr);
+        document()->setHTMLWindowEventListener(resizeEvent, attr, this, hook);
     } else if (attr->name() == onscrollAttr) {
-        document()->setHTMLWindowEventListener(scrollEvent, attr);
+        document()->setHTMLWindowEventListener(scrollEvent, attr, this, hook);
     } else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 void HTMLBodyElement::insertedIntoDocument()
Index: WebCore/html/HTMLStyleElement.cpp
===================================================================
--- WebCore/html/HTMLStyleElement.cpp	(revision 16269)
+++ WebCore/html/HTMLStyleElement.cpp	(working copy)
@@ -45,14 +45,14 @@
 }
 
 // other stuff...
-void HTMLStyleElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLStyleElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == typeAttr)
         m_type = attr->value().domString().lower();
     else if (attr->name() == mediaAttr)
         m_media = attr->value().deprecatedString().lower();
     else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 void HTMLStyleElement::insertedIntoDocument()
Index: WebCore/html/HTMLParamElement.h
===================================================================
--- WebCore/html/HTMLParamElement.h	(revision 16269)
+++ WebCore/html/HTMLParamElement.h	(working copy)
@@ -39,7 +39,7 @@
     virtual HTMLTagStatus endTagRequirement() const { return TagStatusForbidden; }
     virtual int tagPriority() const { return 0; }
 
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     virtual bool isURLAttribute(Attribute*) const;
 
Index: WebCore/html/HTMLTableCaptionElement.cpp
===================================================================
--- WebCore/html/HTMLTableCaptionElement.cpp	(revision 16269)
+++ WebCore/html/HTMLTableCaptionElement.cpp	(working copy)
@@ -48,13 +48,13 @@
     return HTMLElement::mapToEntry(attrName, result);
 }
 
-void HTMLTableCaptionElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLTableCaptionElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == alignAttr) {
         if (!attr->value().isEmpty())
             addCSSProperty(attr, CSS_PROP_CAPTION_SIDE, attr->value());
     } else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 String HTMLTableCaptionElement::align() const
Index: WebCore/html/HTMLScriptElement.h
===================================================================
--- WebCore/html/HTMLScriptElement.h	(revision 16269)
+++ WebCore/html/HTMLScriptElement.h	(working copy)
@@ -41,7 +41,7 @@
     virtual int tagPriority() const { return 1; }
     virtual bool checkDTD(const Node* newChild) { return newChild->isTextNode(); }
 
-    virtual void parseMappedAttribute(MappedAttribute *attr);
+    virtual void parseMappedAttribute(MappedAttribute *attr,bool hook=false);
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
     virtual void notifyFinished(CachedResource *finishedObj);
Index: WebCore/html/HTMLEmbedElement.cpp
===================================================================
--- WebCore/html/HTMLEmbedElement.cpp	(revision 16269)
+++ WebCore/html/HTMLEmbedElement.cpp	(working copy)
@@ -94,7 +94,7 @@
     return HTMLPlugInElement::mapToEntry(attrName, result);
 }
 
-void HTMLEmbedElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLEmbedElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     DeprecatedString val = attr->value().deprecatedString();
   
@@ -126,7 +126,7 @@
         }
         oldNameAttr = newNameAttr;
     } else
-        HTMLPlugInElement::parseMappedAttribute(attr);
+        HTMLPlugInElement::parseMappedAttribute(attr, hook);
 }
 
 bool HTMLEmbedElement::rendererIsNeeded(RenderStyle *style)
Index: WebCore/html/HTMLKeygenElement.cpp
===================================================================
--- WebCore/html/HTMLKeygenElement.cpp	(revision 16269)
+++ WebCore/html/HTMLKeygenElement.cpp	(working copy)
@@ -58,7 +58,7 @@
     return keygen;
 }
 
-void HTMLKeygenElement::parseMappedAttribute(MappedAttribute* attr)
+void HTMLKeygenElement::parseMappedAttribute(MappedAttribute* attr, bool hook)
 {
     if (attr->name() == challengeAttr)
         m_challenge = attr->value();
@@ -66,7 +66,7 @@
         m_keyType = attr->value();
     else
         // skip HTMLSelectElement parsing!
-        HTMLGenericFormElement::parseMappedAttribute(attr);
+        HTMLGenericFormElement::parseMappedAttribute(attr, hook);
 }
 
 bool HTMLKeygenElement::appendFormData(FormDataList& encoded_values, bool)
Index: WebCore/html/HTMLTableElement.cpp
===================================================================
--- WebCore/html/HTMLTableElement.cpp	(revision 16269)
+++ WebCore/html/HTMLTableElement.cpp	(working copy)
@@ -361,7 +361,7 @@
     return HTMLElement::mapToEntry(attrName, result);
 }
 
-void HTMLTableElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLTableElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == widthAttr)
         addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
@@ -435,7 +435,7 @@
         if (!attr->value().isEmpty())
             addCSSProperty(attr, CSS_PROP_VERTICAL_ALIGN, attr->value());
     } else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }
 
 CSSMutableStyleDeclaration* HTMLTableElement::additionalAttributeStyleDecl()
Index: WebCore/html/HTMLTableCellElement.h
===================================================================
--- WebCore/html/HTMLTableCellElement.h	(revision 16269)
+++ WebCore/html/HTMLTableCellElement.h	(working copy)
@@ -52,7 +52,7 @@
     int rowSpan() const { return rSpan; }
 
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
-    virtual void parseMappedAttribute(MappedAttribute*);
+    virtual void parseMappedAttribute(MappedAttribute*, bool hook=false);
 
     // used by table cells to share style decls created by the enclosing table.
     virtual CSSMutableStyleDeclaration* additionalAttributeStyleDecl();
Index: WebCore/html/HTMLPlugInElement.cpp
===================================================================
--- WebCore/html/HTMLPlugInElement.cpp	(revision 16269)
+++ WebCore/html/HTMLPlugInElement.cpp	(working copy)
@@ -123,7 +123,7 @@
     return HTMLElement::mapToEntry(attrName, result);
 }
 
-void HTMLPlugInElement::parseMappedAttribute(MappedAttribute* attr)
+void HTMLPlugInElement::parseMappedAttribute(MappedAttribute* attr, bool hook)
 {
     if (attr->name() == widthAttr)
         addCSSLength(attr, CSS_PROP_WIDTH, attr->value());
@@ -138,7 +138,7 @@
     } else if (attr->name() == alignAttr)
         addHTMLAlignment(attr);
     else
-        HTMLElement::parseMappedAttribute(attr);
+        HTMLElement::parseMappedAttribute(attr, hook);
 }    
 
 bool HTMLPlugInElement::checkDTD(const Node* newChild)
Index: WebCore/dom/NamedAttrMap.cpp
===================================================================
--- WebCore/dom/NamedAttrMap.cpp	(revision 16269)
+++ WebCore/dom/NamedAttrMap.cpp	(working copy)
@@ -258,7 +258,7 @@
     // The derived class, HTMLNamedAttrMap, which manages a parsed class list for the CLASS attribute,
     // will update its member variable when parse attribute is called.
     for(unsigned i = 0; i < len; i++)
-        element->attributeChanged(attrs[i], true);
+      element->attributeChanged(attrs[i], true);
 
     return *this;
 }
Index: WebCore/dom/StyledElement.cpp
===================================================================
--- WebCore/dom/StyledElement.cpp	(revision 16269)
+++ WebCore/dom/StyledElement.cpp	(working copy)
@@ -141,7 +141,7 @@
     }
 }
 
-void StyledElement::attributeChanged(Attribute* attr, bool preserveDecls)
+void StyledElement::attributeChanged(Attribute* attr, bool preserveDecls, bool hook)
 {
     MappedAttribute* mappedAttr = static_cast(attr);
     if (mappedAttr->decl() && !preserveDecls) {
@@ -175,7 +175,7 @@
     }
 
     if (needToParse)
-        parseMappedAttribute(mappedAttr);
+        parseMappedAttribute(mappedAttr, hook);
 
     if (entry == eNone && ownerDocument()->styleSelector()->hasSelectorForAttribute(attr->name().localName()))
         setChanged();
@@ -199,7 +199,7 @@
     return true;
 }
 
-void StyledElement::parseMappedAttribute(MappedAttribute *attr)
+void StyledElement::parseMappedAttribute(MappedAttribute *attr, bool hook)
 {
     if (attr->name() == idAttr) {
         // unique id
Index: WebCore/dom/Document.cpp
===================================================================
--- WebCore/dom/Document.cpp	(revision 16269)
+++ WebCore/dom/Document.cpp	(working copy)
@@ -2336,18 +2336,18 @@
     return false;
 }
 
-PassRefPtr Document::createHTMLEventListener(const String& functionName, const String& code, Node *node)
+PassRefPtr Document::createHTMLEventListener(const String& functionName, const String& code, Node *node, bool hook)
 {
     if (Frame* frm = frame())
         if (KJSProxy* proxy = frm->jScript())
-            return proxy->createHTMLEventHandler(functionName, code, node);
+            return proxy->createHTMLEventHandler(functionName, code, node, hook);
     return 0;
 }
 
-void Document::setHTMLWindowEventListener(const AtomicString& eventType, Attribute* attr)
+void Document::setHTMLWindowEventListener(const AtomicString& eventType, Attribute* attr, Node *bodyNode, bool hook)
 {
-    setHTMLWindowEventListener(eventType,
-        createHTMLEventListener(attr->localName().domString(), attr->value(), 0));
+  setHTMLWindowEventListener(eventType,
+			     createHTMLEventListener(attr->localName().domString(), attr->value(), bodyNode, hook));
 }
 
 void Document::dispatchImageLoadEventSoon(HTMLImageLoader *image)
Index: WebCore/dom/StyledElement.h
===================================================================
--- WebCore/dom/StyledElement.h	(revision 16269)
+++ WebCore/dom/StyledElement.h	(working copy)
@@ -69,8 +69,8 @@
     virtual void updateStyleAttributeIfNeeded() const;
     
     virtual const AtomicStringList* getClassList() const;
-    virtual void attributeChanged(Attribute* attr, bool preserveDecls = false);
-    virtual void parseMappedAttribute(MappedAttribute* attr);
+    virtual void attributeChanged(Attribute* attr, bool preserveDecls = false, bool hook = false);
+    virtual void parseMappedAttribute(MappedAttribute* attr, bool hook=false);
     virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
     virtual void createAttributeMap() const;
     virtual Attribute* createAttribute(const QualifiedName& name, StringImpl* value);
Index: WebCore/dom/Element.h
===================================================================
--- WebCore/dom/Element.h	(revision 16269)
+++ WebCore/dom/Element.h	(working copy)
@@ -127,10 +127,11 @@
     NamedAttrMap* attributes(bool readonly) const;
 
     // This method is called whenever an attribute is added, changed or removed.
-    virtual void attributeChanged(Attribute* attr, bool preserveDecls = false) {}
+    virtual void attributeChanged(Attribute* attr, bool preserveDecls = false, bool hook=false) {}
 
     // not part of the DOM
-    void setAttributeMap(NamedAttrMap*);
+    void setAttributeMap(NamedAttrMap *am) { setAttributeMap(am, false); }
+    void setAttributeMap(NamedAttrMap*, bool hook);
 
     virtual void copyNonAttributeProperties(const Element *source) {}
 
Index: WebCore/dom/Document.h
===================================================================
--- WebCore/dom/Document.h	(revision 16269)
+++ WebCore/dom/Document.h	(working copy)
@@ -446,13 +446,13 @@
     EventListener* getHTMLWindowEventListener(const AtomicString &eventType);
     void removeHTMLWindowEventListener(const AtomicString &eventType);
 
-    void setHTMLWindowEventListener(const AtomicString& eventType, Attribute*);
+    void setHTMLWindowEventListener(const AtomicString& eventType, Attribute*, Node *bodyNode, bool hook=false);
 
     void addWindowEventListener(const AtomicString& eventType, PassRefPtr, bool useCapture);
     void removeWindowEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
     bool hasWindowEventListener(const AtomicString& eventType);
 
-    PassRefPtr createHTMLEventListener(const String& functionName, const String& code, Node*);
+    PassRefPtr createHTMLEventListener(const String& functionName, const String& code, Node*, bool hook);
     
     /**
      * Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode.
Index: WebCore/dom/Node.cpp
===================================================================
--- WebCore/dom/Node.cpp	(revision 16269)
+++ WebCore/dom/Node.cpp	(working copy)
@@ -106,6 +106,7 @@
       m_previous(0),
       m_next(0),
       m_renderer(0),
+      m_keepalive(false),
       m_nodeLists(0),
       m_tabIndex(0),
       m_hasId(false),
@@ -130,6 +131,14 @@
 #endif
 }
 
+void Node::setKeepAlive(bool b) {
+  m_keepalive = b;
+}
+
+bool Node::isKeepAlive() {
+  return m_keepalive;
+}
+
 void Node::setDocument(Document *doc)
 {
     if (inDocument())
@@ -157,6 +166,18 @@
   return String();
 }
 
+Node* Node::parentNode() const { 
+  Node *par = parent();
+  Node *gp = 0;
+  if(par && (par->nodeType() == DOCUMENT_FRAGMENT_NODE)) { //ugly hack for innerhtml sandbox dom traversal
+    gp = par->parentNode();
+    if(gp)
+      return gp;
+  }
+  return par;
+}
+
+
 void Node::setNodeValue( const String &/*_nodeValue*/, ExceptionCode& ec)
 {
     // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly
Index: WebCore/dom/Element.cpp
===================================================================
--- WebCore/dom/Element.cpp	(revision 16269)
+++ WebCore/dom/Element.cpp	(working copy)
@@ -390,7 +390,8 @@
     return new Attribute(name, value);
 }
 
-void Element::setAttributeMap(NamedAttrMap* list)
+
+void Element::setAttributeMap(NamedAttrMap* list, bool hook)
 {
     if (inDocument())
         document()->incDOMTreeVersion();
@@ -412,7 +413,7 @@
         namedAttrMap->element = this;
         unsigned len = namedAttrMap->length();
         for (unsigned i = 0; i < len; i++)
-            attributeChanged(namedAttrMap->attrs[i]);
+            attributeChanged(namedAttrMap->attrs[i], false, hook);
         // FIXME: What about attributes that were in the old map that are not in the new map?
     }
 }
Index: WebCore/dom/Node.h
===================================================================
--- WebCore/dom/Node.h	(revision 16269)
+++ WebCore/dom/Node.h	(working copy)
@@ -87,7 +87,7 @@
     virtual String nodeValue() const;
     virtual void setNodeValue(const String&, ExceptionCode&);
     virtual NodeType nodeType() const = 0;
-    Node* parentNode() const { return parent(); }
+    Node* parentNode() const;
     Node* previousSibling() const { return m_previous; }
     Node* nextSibling() const { return m_next; }
     virtual PassRefPtr childNodes();
@@ -114,6 +114,9 @@
     void normalize();
     static bool isSupported(const String& feature, const String& version);
 
+    void setKeepAlive(bool);
+    bool isKeepAlive();
+    
     bool isSameNode(Node* other) const { return this == other; }
     bool isEqualNode(Node*) const;
     bool isDefaultNamespace(const String& namespaceURI) const;
@@ -436,6 +439,7 @@
     Node* m_previous;
     Node* m_next;
     RenderObject* m_renderer;
+    bool m_keepalive;
 
 protected:
     typedef HashSet NodeListSet;
Index: WebCore/loader/CachedScript.h
===================================================================
--- WebCore/loader/CachedScript.h	(revision 16269)
+++ WebCore/loader/CachedScript.h	(working copy)
@@ -30,6 +30,7 @@
 
 #include "CachedResource.h"
 #include "TextEncoding.h"
+#include "dom/Node.h"
 
 namespace WebCore {
 
@@ -42,7 +43,7 @@
         virtual ~CachedScript();
 
         const String& script() const { return m_script; }
-
+        Node* setScriptElementNode(Node* n) { Node *old = scriptElementNode; scriptElementNode = n; return old;}
         virtual void ref(CachedResourceClient*);
         virtual void deref(CachedResourceClient*);
 
@@ -57,6 +58,7 @@
         void checkNotify();
 
     private:
+      Node *scriptElementNode;
         String m_script;
         TextEncoding m_encoding;
         bool m_errorOccurred;
Index: WebCore/page/Frame.h
===================================================================
--- WebCore/page/Frame.h	(revision 16269)
+++ WebCore/page/Frame.h	(working copy)
@@ -142,7 +142,7 @@
   /**
    * Execute the specified snippet of JavaScript code.
    */
-  KJS::JSValue* executeScript(Node*, const String& script, bool forceUserGesture = false);
+  KJS::JSValue* executeScript(Node*, const String& script, bool forceUserGesture = false, Node *enclosingNode=0);
 
   /**
    * Implementation of CSS property -webkit-user-drag == auto
@@ -524,8 +524,8 @@
 
   virtual void urlSelected(const DeprecatedString& url, const String& target);
   virtual void urlSelected(const ResourceRequest&, const String& target);
+  virtual void urlSelected(Node *element, const ResourceRequest& request, const String& target);
 
-
   // Methods with platform-specific overrides (and no base class implementation).
   virtual void setTitle(const String&) = 0;
   virtual void handledOnloadEvents() = 0;
@@ -641,7 +641,7 @@
   void cancelRedirection(bool newLoadInProgress = false);
 
  public:
-  KJS::JSValue* executeScript(const String& filename, int baseLine, Node*, const String& script);
+  KJS::JSValue* executeScript(const String& filename, int baseLine, Node*, const String& script, PassRefPtr enclosingNode=0);
   KJSProxy* jScript();
   Frame* opener();
   void setOpener(Frame* _opener);
Index: WebCore/page/Frame.cpp
===================================================================
--- WebCore/page/Frame.cpp	(revision 16269)
+++ WebCore/page/Frame.cpp	(working copy)
@@ -379,7 +379,7 @@
     }
 }
 
-JSValue* Frame::executeScript(Node* n, const String& script, bool forceUserGesture)
+JSValue* Frame::executeScript(Node* n, const String& script, bool forceUserGesture, Node *enclosingNode)
 {
   KJSProxy *proxy = jScript();
 
@@ -390,7 +390,7 @@
   // If forceUserGesture is true, then make the script interpreter
   // treat it as if triggered by a user gesture even if there is no
   // current DOM event being processed.
-  JSValue* ret = proxy->evaluate(forceUserGesture ? DeprecatedString::null : d->m_url.url(), 0, script, n);
+  JSValue* ret = proxy->evaluate(forceUserGesture ? DeprecatedString::null : d->m_url.url(), 0, script, n, enclosingNode);
   d->m_runningScripts--;
 
   if (!d->m_runningScripts)
@@ -1305,13 +1305,8 @@
         dragCaretController->paintCaret(p, rect);
 }
 
-void Frame::urlSelected(const DeprecatedString& url, const String& target)
+void Frame::urlSelected(Node *element, const ResourceRequest& request, const String& _target)
 {
-    urlSelected(ResourceRequest(completeURL(url)), target);
-}
-
-void Frame::urlSelected(const ResourceRequest& request, const String& _target)
-{
   String target = _target;
   if (target.isEmpty() && d->m_doc)
     target = d->m_doc->baseTarget();
@@ -1319,7 +1314,7 @@
   const KURL& url = request.url();
 
   if (url.url().startsWith("javascript:", false)) {
-    executeScript(0, KURL::decode_string(url.url().mid(11)), true);
+    executeScript(0, KURL::decode_string(url.url().mid(11)), true, element);
     return;
   }
 
@@ -1337,8 +1332,20 @@
     requestCopy.setReferrer(d->m_referrer);
 
   urlSelected(requestCopy);
+
+
 }
 
+void Frame::urlSelected(const DeprecatedString& url, const String& target)
+{
+    urlSelected(0, ResourceRequest(completeURL(url)), target);
+}
+
+void Frame::urlSelected(const ResourceRequest& request, const String& _target)
+{
+  urlSelected(0, request, _target);
+}
+
 bool Frame::requestFrame(Element* ownerElement, const String& urlParam, const AtomicString& frameName)
 {
     DeprecatedString _url = urlParam.deprecatedString();
@@ -2077,7 +2084,7 @@
     d->m_typingStyle = 0;
 }
 
-JSValue* Frame::executeScript(const String& filename, int baseLine, Node* n, const String& script)
+JSValue* Frame::executeScript(const String& filename, int baseLine, Node* n, const String& script, PassRefPtr enclosingNode)
 {
     // FIXME: This is missing stuff that the other executeScript has.
     // --> d->m_runningScripts and submitFormAgain.
@@ -2085,7 +2092,7 @@
     KJSProxy* proxy = jScript();
     if (!proxy)
         return 0;
-    JSValue* ret = proxy->evaluate(filename, baseLine, script, n);
+    JSValue* ret = proxy->evaluate(filename, baseLine, script, n, enclosingNode.release());
     Document::updateDocumentsRendering();
     return ret;
 }
Index: WebKitTools/Scripts/check-for-global-initializers
===================================================================
--- WebKitTools/Scripts/check-for-global-initializers	(revision 16269)
+++ WebKitTools/Scripts/check-for-global-initializers	(working copy)
@@ -43,7 +43,7 @@
 $variant = "normal" if !$variant; # for Xcode 2.1, which does not have CURRENT_VARIANT
 
 my $list = $ENV{"LINK_FILE_LIST_${variant}_${arch}"};
-
+print "This is the list <$list>\n";
 if (!open LIST, $list) {
     print "Could not open $list\n";
     exit 1;
@@ -56,15 +56,18 @@
 my $sawError = 0;
 
 for my $file (sort @files) {
+    next if($file =~ /crypto_object.o/);
     if (!open NM, "-|", "nm", $file) {
         print "Could not open $file\n";
         $sawError = 1;
         next;
     }
     my $sawGlobal = 0;
+    my $seenGlobal = 0;
     while () {
         if (/__GLOBAL__I/) {
             $sawGlobal = 1;
+	    $seenGlobal = $$;
             last;
         }
     }
@@ -91,7 +94,7 @@
             next if $shortName eq "FastMalloc.o";
         }
 
-        print "$shortName has a global initializer in it! ($file)\n";
+        print "$shortName has a global initializer in it! ($file)  $seenGlobal\n";
         $sawError = 1;
     }
 }