WebCore:
authorcblu <cblu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Sep 2004 21:36:27 +0000 (21:36 +0000)
committercblu <cblu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 Sep 2004 21:36:27 +0000 (21:36 +0000)
Fixed:
<rdar://problem/3429921> obey PARAM tags inside of OBJECT tags when necessary
<rdar://problem/3515685> Object tag in Java 1.4.1 / Safari doesn't recognize params

        Reviewed by darin.

        * khtml/khtml_part.cpp:
        (KHTMLPart::requestFrame): take 2 parameter arrays rather than 1 which will have to be parsed
        (KHTMLPart::requestObject): ditto
        * khtml/khtml_part.h:
        * khtml/khtmlpart_p.h:
        * khtml/rendering/render_frames.cpp:
        (RenderPartObject::updateWidget): use PARAM tags when there is no EMBED specified
        * kwq/KWQKHTMLPart.h:
        * kwq/KWQKHTMLPart.mm:
        (KWQKHTMLPart::createPart): call renamed bridge method
        * kwq/KWQKJavaAppletWidget.mm:
        (KJavaAppletWidget::KJavaAppletWidget): ditto
        * kwq/KWQStringList.h:
        * kwq/KWQStringList.mm:
        (QStringList::getNSArray): return a const array
        * kwq/WebCoreBridge.h:
        * kwq/WebCoreBridge.mm:
        (-[WebCoreBridge URLWithAttributeString:]): renamed to match API

WebKit:

Changes to implement renamed bridge methods.

        Reviewed by darin.

        * ChangeLog:
        * DOM.subproj/WebDOMOperations.m:
        (-[DOMDocument URLWithAttributeString:]): call renamed bridge method
        * WebCoreSupport.subproj/WebBridge.m:
        (-[WebBridge pluginViewWithPackage:attributeNames:attributeValues:baseURL:]): take 2 parameter arrays rather than 1 which will have to be parsed
        (-[WebBridge viewForPluginWithURL:attributeNames:attributeValues:MIMEType:]): ditto

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7610 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
WebCore/ChangeLog-2005-08-23
WebCore/khtml/khtml_part.cpp
WebCore/khtml/khtml_part.h
WebCore/khtml/khtmlpart_p.h
WebCore/khtml/rendering/render_frames.cpp
WebCore/kwq/KWQKHTMLPart.h
WebCore/kwq/KWQKHTMLPart.mm
WebCore/kwq/KWQKJavaAppletWidget.mm
WebCore/kwq/KWQStringList.h
WebCore/kwq/KWQStringList.mm
WebCore/kwq/WebCoreBridge.h
WebCore/kwq/WebCoreBridge.mm
WebKit/ChangeLog
WebKit/DOM.subproj/WebDOMOperations.m
WebKit/WebCoreSupport.subproj/WebBridge.m

index 275ba82134b614503cb31a861c36daf1d7fb675d..e6a2d869b0e9edecb2b9c8343df112cc365ce9fc 100644 (file)
@@ -1,3 +1,30 @@
+2004-09-20  Chris Blumenberg  <cblu@apple.com>
+
+       Fixed:
+       <rdar://problem/3429921> obey PARAM tags inside of OBJECT tags when necessary
+       <rdar://problem/3515685> Object tag in Java 1.4.1 / Safari doesn't recognize params
+
+        Reviewed by darin.
+
+        * khtml/khtml_part.cpp:
+        (KHTMLPart::requestFrame): take 2 parameter arrays rather than 1 which will have to be parsed
+        (KHTMLPart::requestObject): ditto
+        * khtml/khtml_part.h:
+        * khtml/khtmlpart_p.h:
+        * khtml/rendering/render_frames.cpp:
+        (RenderPartObject::updateWidget): use PARAM tags when there is no EMBED specified
+        * kwq/KWQKHTMLPart.h:
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::createPart): call renamed bridge method
+        * kwq/KWQKJavaAppletWidget.mm:
+        (KJavaAppletWidget::KJavaAppletWidget): ditto
+        * kwq/KWQStringList.h:
+        * kwq/KWQStringList.mm:
+        (QStringList::getNSArray): return a const array
+        * kwq/WebCoreBridge.h:
+        * kwq/WebCoreBridge.mm:
+        (-[WebCoreBridge URLWithAttributeString:]): renamed to match API
+
 2004-09-20  Darin Adler  <darin@apple.com>
 
         Reviewed by Ken.
index 49f42b4a4a5d6f2d204b3d0062c4194330dd6450..10f34052c5e473ce0a86220a317e4848c8119b04 100644 (file)
@@ -2992,7 +2992,7 @@ void KHTMLPart::updateActions()
 #endif
 
 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
-                              const QStringList &params, bool isIFrame )
+                              const QStringList &paramNames, const QStringList &paramValues, bool isIFrame )
 {
 //  kdDebug( 6050 ) << "childRequest( ..., " << url << ", " << frameName << " )" << endl;
   FrameIt it = d->m_frames.find( frameName );
@@ -3006,7 +3006,8 @@ bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, cons
 
   (*it).m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
   (*it).m_frame = frame;
-  (*it).m_params = params;
+  (*it).m_paramValues = paramNames;
+  (*it).m_paramNames = paramValues;
 
   // Support for <frame src="javascript:string">
   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
@@ -3033,13 +3034,14 @@ QString KHTMLPart::requestFrameName()
 }
 
 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
-                               const QStringList &params )
+                               const QStringList &paramNames, const QStringList &paramValues )
 {
   khtml::ChildFrame child;
   QValueList<khtml::ChildFrame>::Iterator it = d->m_objects.append( child );
   (*it).m_frame = frame;
   (*it).m_type = khtml::ChildFrame::Object;
-  (*it).m_params = params;
+  (*it).m_paramNames = paramNames;
+  (*it).m_paramValues = paramValues;
 
   KURL completedURL;
   if (!url.isEmpty())
index 922b3a55618ba392724e79ec376ad120809c3b71..4b5bac4c8c6cce5a273395cd149f83cf451daf03 100644 (file)
@@ -1243,7 +1243,7 @@ private:
   QVariant executeScheduledScript();
 
   bool requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
-                     const QStringList &args = QStringList(), bool isIFrame = false );
+                     const QStringList &paramNames = QStringList(), const QStringList &paramValues = QStringList(), bool isIFrame = false );
 
   /**
    * @internal returns a name for a frame without a name.
@@ -1255,7 +1255,7 @@ private:
   QString requestFrameName();
 
   bool requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
-                      const QStringList &args = QStringList() );
+                      const QStringList &paramNames = QStringList(), const QStringList &paramValues = QStringList()  );
 
   bool requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() );
 
index d34477bda52bf234e4f2a37e1977bb0958cdce74..37bdbb5d980a9f72efc03dac754a6861249fdb1a 100644 (file)
@@ -80,7 +80,8 @@ namespace khtml
     bool m_bPreloaded;
     KURL m_workingURL;
     Type m_type;
-    QStringList m_params;
+    QStringList m_paramNames;
+    QStringList m_paramValues;
     bool m_bNotify;
   };
 
index a5c8a7fbdd67c2e4c7887b7fb4ca3be3bf2bd976..c2332c372992ec65bb4d61052baedf75583a6095 100644 (file)
@@ -48,6 +48,7 @@
 #include <kglobal.h>
 #include <qtimer.h>
 #include <qpainter.h>
+#include "qdict.h"
 
 using namespace khtml;
 using namespace DOM;
@@ -678,7 +679,8 @@ void RenderPartObject::updateWidget()
 {
   QString url;
   QString serviceType;
-  QStringList params;
+  QStringList paramNames;
+  QStringList paramValues;
   KHTMLPart *part = m_view->part();
 
   setNeedsLayoutAndMinMaxRecalc();
@@ -722,9 +724,13 @@ void RenderPartObject::updateWidget()
           serviceType = o->serviceType;
       }
       
-      // Then try the PARAM tags for the URL and type attributes.
+      QDict<bool> uniqueParamNames(5, false);
+      
+      // Scan the PARAM children.
+      // Get the URL and type from the params if we don't already have them.
+      // Get the attributes from the params if there is no EMBED tag.
       NodeImpl *child = o->firstChild();
-      while (child && (url.isEmpty() || serviceType.isEmpty())) {
+      while (child && (url.isEmpty() || serviceType.isEmpty() || !embed)) {
           if (child->id() == ID_PARAM) {
               HTMLParamElementImpl *p = static_cast<HTMLParamElementImpl *>( child );
               QString name = p->name().lower();
@@ -734,26 +740,44 @@ void RenderPartObject::updateWidget()
               if (serviceType.isEmpty() && name == "type") {
                   serviceType = p->value();
               }
-              
+              if (!embed) {
+                  bool dummyValue = true;
+                  uniqueParamNames.insert(p->name(), &dummyValue);
+                  paramNames.append(p->name());
+                  paramValues.append(p->value());
+              }
           }
           child = child->nextSibling();
       }
       
-      // Lastly try to map a specific CLASSID to a type.
+      // Turn the attributes of either the EMBED tag or OBJECT tag into arrays, but don't override PARAM values.
+      NamedAttrMapImpl* attributes = embedOrObject->attributes();
+      if (attributes) {
+          for (unsigned long i = 0; i < attributes->length(); ++i) {
+              AttributeImpl* it = attributes->attributeItem(i);
+              QString name = o->getDocument()->attrName(it->id()).string();
+              if (embed || uniqueParamNames.find(name) == 0) {
+                  paramNames.append(name);
+                  paramValues.append(it->value().string());
+              }
+          }
+      }
+      
+      // If we still don't have a type, try to map from a specific CLASSID to a type.
       if (serviceType.isEmpty() && !o->classId.isEmpty()) {
+          // It is ActiveX, but the nsplugin system handling
+          // should also work, that's why we don't override the
+          // serviceType with application/x-activex-handler
+          // but let the KTrader in khtmlpart::createPart() detect
+          // the user's preference: launch with activex viewer or
+          // with nspluginviewer (Niko)          
           if (o->classId.contains("D27CDB6E-AE6D-11cf-96B8-444553540000")) {
-              // It is ActiveX, but the nsplugin system handling
-              // should also work, that's why we don't override the
-              // serviceType with application/x-activex-handler
-              // but let the KTrader in khtmlpart::createPart() detect
-              // the user's preference: launch with activex viewer or
-              // with nspluginviewer (Niko)
               serviceType = "application/x-shockwave-flash";
-          } else if(o->classId.contains("CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA")) {
+          } else if (o->classId.contains("CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA")) {
               serviceType = "audio/x-pn-realaudio-plugin";
-          } else if(o->classId.contains("02BF25D5-8C17-4B23-BC80-D3488ABDDC6B")) {
+          } else if (o->classId.contains("02BF25D5-8C17-4B23-BC80-D3488ABDDC6B")) {
               serviceType = "video/quicktime";
-          } else if(o->classId.contains("166B1BCA-3F9C-11CF-8075-444553540000")) {
+          } else if (o->classId.contains("166B1BCA-3F9C-11CF-8075-444553540000")) {
               serviceType = "application/x-director";
           } else {
               // We have a clsid, means this is activex (Niko)
@@ -773,20 +797,13 @@ void RenderPartObject::updateWidget()
       if (!url.isEmpty() && url == part->baseURL()) {
           return;
       }
-      
-      // Turn the attributes of either the EMBED tag or OBJECT tag into an array.
-      NamedAttrMapImpl* attributes = embedOrObject->attributes();
-      if (attributes) {
-          for (unsigned long i = 0; i < attributes->length(); ++i) {
-              AttributeImpl* it = attributes->attributeItem(i);
-              params.append(o->getDocument()->attrName(it->id()).string() + "=\"" + it->value().string() + "\"");
-          }
-      }
-      
+            
+#if !APPLE_CHANGES      
       params.append( QString::fromLatin1("__KHTML__CLASSID=\"%1\"").arg( o->classId ) );
       params.append( QString::fromLatin1("__KHTML__CODEBASE=\"%1\"").arg( o->getAttribute(ATTR_CODEBASE).string() ) );
-      
-      part->requestObject( this, url, serviceType, params );
+#endif
+
+      part->requestObject( this, url, serviceType, paramNames, paramValues );
   } else if ( element()->id() == ID_EMBED ) {
 
       HTMLEmbedElementImpl *o = static_cast<HTMLEmbedElementImpl *>(element());
@@ -808,10 +825,11 @@ void RenderPartObject::updateWidget()
       if (a) {
           for (unsigned long i = 0; i < a->length(); ++i) {
               AttributeImpl* it = a->attributeItem(i);
-              params.append(o->getDocument()->attrName(it->id()).string() + "=\"" + it->value().string() + "\"");
+              paramNames.append(o->getDocument()->attrName(it->id()).string());
+              paramValues.append(it->value().string());
           }
       }
-      part->requestObject( this, url, serviceType, params );
+      part->requestObject( this, url, serviceType, paramNames, paramValues );
   } else {
       assert(element()->id() == ID_IFRAME);
       HTMLIFrameElementImpl *o = static_cast<HTMLIFrameElementImpl *>(element());
@@ -823,7 +841,7 @@ void RenderPartObject::updateWidget()
           return;
       }
       KHTMLView *v = static_cast<KHTMLView *>(m_view);
-      bool requestSucceeded = v->part()->requestFrame( this, url, o->name.string(), QStringList(), true );
+      bool requestSucceeded = v->part()->requestFrame( this, url, o->name.string(), QStringList(), QStringList(), true );
       if (requestSucceeded && url == "about:blank") {
          KHTMLPart *newPart = v->part()->findFrame( o->name.string() );
          if (newPart && newPart->xmlDocImpl()) {
index f5d8303ea436b4d9a121818436c7793138b2e793..e0d8f4506c04119e52192244a6e1decde4001529 100644 (file)
@@ -142,7 +142,6 @@ public:
     void setStatusBarText(const QString &status);
 
     void urlSelected(const KURL &url, int button, int state, const KParts::URLArgs &args);
-    bool requestObject(khtml::RenderPart *frame, const QString &url, const QString &serviceType, const QStringList &args);
     KParts::ReadOnlyPart *createPart(const khtml::ChildFrame &child, const KURL &url, const QString &mimeType);
 
     void scheduleClose();
index 481e1e58fc25259be2e7681f8e43b8b13b5b7dbd..e050213d9021962ab53b365d08b1440da83203b7 100644 (file)
@@ -753,16 +753,11 @@ ReadOnlyPart *KWQKHTMLPart::createPart(const ChildFrame &child, const KURL &url,
 
     BOOL needFrame = [_bridge frameRequiredForMIMEType:mimeType.getNSString() URL:url.getNSURL()];
     if (child.m_type == ChildFrame::Object && !needFrame) {
-        NSMutableArray *attributesArray = [NSMutableArray arrayWithCapacity:child.m_params.count()];
-        for (uint i = 0; i < child.m_params.count(); i++) {
-            [attributesArray addObject:child.m_params[i].getNSString()];
-        }
-        
         KWQPluginPart *newPart = new KWQPluginPart;
         newPart->setWidget(new QWidget([_bridge viewForPluginWithURL:url.getNSURL()
-                                                          attributes:attributesArray
-                                                             baseURL:KURL(d->m_doc->baseURL()).getNSURL()
-                                                            MIMEType:child.m_args.serviceType.getNSString()]));
+                                                      attributeNames:child.m_paramNames.getNSArray()
+                                                     attributeValues:child.m_paramValues.getNSArray()
+                                                             MIMEType:child.m_args.serviceType.getNSString()]));
         part = newPart;
     } else {
         LOG(Frames, "name %s", child.m_name.ascii());
index b0c8c322bf29cb871fd408c25b8f2e30c3a10f7d..0073a84ba0dd4540fefe09d41c6ec6d293f87a11 100644 (file)
@@ -34,7 +34,8 @@ KJavaAppletWidget::KJavaAppletWidget(const QSize &size, KJavaAppletContext *c, c
 {
     KWQ_BLOCK_EXCEPTIONS;
     
-    NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
+    NSMutableArray *attributeNames = [[NSMutableArray alloc] init];
+    NSMutableArray *attributeValues = [[NSMutableArray alloc] init];
     QMapConstIterator<QString, QString> it = args.begin();
     QMapConstIterator<QString, QString> end = args.end();
     QString baseURLString;
@@ -42,15 +43,18 @@ KJavaAppletWidget::KJavaAppletWidget(const QSize &size, KJavaAppletContext *c, c
         if (it.key().lower() == "baseurl") {
             baseURLString = it.data();
         }
-        [attributes setObject:it.data().getNSString() forKey:it.key().getNSString()];
+        [attributeNames addObject:it.key().getNSString()];
+        [attributeValues addObject:it.data().getNSString()];
         ++it;
     }
     
     KWQKHTMLPart *part = KWQ(c->part());    
     setView([part->bridge() viewForJavaAppletWithFrame:NSMakeRect(0, 0, size.width(), size.height())
-                                            attributes:attributes
+                                        attributeNames:attributeNames
+                                       attributeValues:attributeValues
                                                baseURL:part->completeURL(baseURLString).getNSURL()]);
-    [attributes release];
+    [attributeNames release];
+    [attributeValues release];
     part->view()->addChild(this);
     
     KWQ_UNBLOCK_EXCEPTIONS;
index 290d628202b935d4b9e60c16ceb581b5a6f9ab18..25f03a7a79424f8120e79c6d67a68056fd716036 100644 (file)
@@ -44,7 +44,7 @@ public:
     
     QString pop_front();
     
-    NSArray *getNSArray();
+    NSArray *getNSArray() const;
 };
 
 #endif
index da49d764888032d8e9f0563c938e6329354bd83e..4957b9b2ed5693a4baef96ded701715a1866484c 100644 (file)
@@ -84,10 +84,10 @@ QString QStringList::pop_front()
     return front;
 }
 
-NSArray *QStringList::getNSArray()
+NSArray *QStringList::getNSArray() const
 {
     NSMutableArray *array = [NSMutableArray array];
-    for (QStringList::Iterator it = begin(); it != end(); ++it) {
+    for (ConstIterator it = begin(); it != end(); ++it) {
         [array addObject:(*it).getNSString()];
     }
     return array;
index 56c3a04edf65475e42dcd63726163b67423c991f..5d72be2a343c97e71699b5ccc1e07d7a6a1c3b89 100644 (file)
@@ -211,7 +211,7 @@ typedef enum {
 - (NSString *)renderTreeAsExternalRepresentation;
 
 - (NSDictionary *)elementAtPoint:(NSPoint)point;
-- (NSURL *)URLWithRelativeString:(NSString *)string;
+- (NSURL *)URLWithAttributeString:(NSString *)string;
 
 - (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form;
 - (DOMElement *)elementForView:(NSView *)view;
@@ -439,11 +439,12 @@ typedef enum {
 - (NSString *)incomingReferrer;
 
 - (NSView *)viewForPluginWithURL:(NSURL *)URL
-                      attributes:(NSArray *)attributesArray
-                         baseURL:(NSURL *)baseURL
+                  attributeNames:(NSArray *)attributeNames
+                 attributeValues:(NSArray *)attributeValues
                         MIMEType:(NSString *)MIMEType;
 - (NSView *)viewForJavaAppletWithFrame:(NSRect)frame
-                            attributes:(NSDictionary *)attributes
+                        attributeNames:(NSArray *)attributeNames
+                       attributeValues:(NSArray *)attributeValues
                                baseURL:(NSURL *)baseURL;
 
 - (BOOL)saveDocumentToPageCache:(id)documentInfo;
index 02afd0c1e384036130f186d0da9c3246d0220eb9..ee4dbdfc693b5c418328169992d9b656fef38ec6 100644 (file)
@@ -1053,7 +1053,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     return element;
 }
 
-- (NSURL *)URLWithRelativeString:(NSString *)string
+- (NSURL *)URLWithAttributeString:(NSString *)string
 {
     DocumentImpl *doc = _part->xmlDocImpl();
     if (!doc) {
index d93c4098f73529c4f462731f7488cf65d926f02d..bbeb966e0681f72ce92432c004abf9bcc877e212 100644 (file)
@@ -1,3 +1,16 @@
+2004-09-20  Chris Blumenberg  <cblu@apple.com>
+
+       Changes to implement renamed bridge methods.
+
+        Reviewed by darin.
+
+        * ChangeLog:
+        * DOM.subproj/WebDOMOperations.m:
+        (-[DOMDocument URLWithAttributeString:]): call renamed bridge method
+        * WebCoreSupport.subproj/WebBridge.m:
+        (-[WebBridge pluginViewWithPackage:attributeNames:attributeValues:baseURL:]): take 2 parameter arrays rather than 1 which will have to be parsed
+        (-[WebBridge viewForPluginWithURL:attributeNames:attributeValues:MIMEType:]): ditto
+
 2004-09-20  Darin Adler  <darin@apple.com>
 
         Reviewed by Chris.
index 34c2248b47df9875456202037b3f3fa7694e7890..0593dbaf32e8ff03dd0a93e2abe9f7b0f0f2a20f 100644 (file)
@@ -70,7 +70,7 @@
 
 - (NSURL *)URLWithAttributeString:(NSString *)string
 {
-    return [[self _bridge] URLWithRelativeString:string];
+    return [[self _bridge] URLWithAttributeString:string];
 }
 
 @end
index 28fa70677989147ee0f87e029ae8ba1216c6ea11..e7775b1a3e78bce5008287330596104dd28102b9 100644 (file)
@@ -789,11 +789,11 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
 }
 
 - (NSView *)pluginViewWithPackage:(WebPluginPackage *)pluginPackage
-                       attributes:(NSDictionary *)attributes
+                   attributeNames:(NSArray *)attributeNames
+                  attributeValues:(NSArray *)attributeValues
                           baseURL:(NSURL *)baseURL
 {
     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
-
     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
     
     [pluginPackage load];
@@ -801,6 +801,15 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
     WebPluginController *pluginController = [docView _pluginController];
     Class viewFactory = [pluginPackage viewFactory];
     
+    // Store attributes in a dictionary so they can be passed to WebPlugins.
+    NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
+    unsigned count = [attributeNames count];
+    unsigned i;
+    for (i = 0; i < count; i++) {
+        [attributes setObject:[attributeValues objectAtIndex:i] forKey:[attributeNames objectAtIndex:i]];
+    }    
+    
+    NSView *view = nil;
     if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
         NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:
             baseURL, WebPlugInBaseURLKey,
@@ -808,7 +817,7 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
             pluginController, WebPlugInContainerKey,
             nil];
         LOG(Plugins, "arguments:\n%@", arguments);
-        return [viewFactory plugInViewWithArguments:arguments];
+        view = [viewFactory plugInViewWithArguments:arguments];
     } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
         NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:
             baseURL, WebPluginBaseURLKey,
@@ -816,40 +825,30 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
             pluginController, WebPluginContainerKey,
             nil];
         LOG(Plugins, "arguments:\n%@", arguments);
-        return [viewFactory pluginViewWithArguments:arguments];
-    } else {
-        return nil;
+        view = [viewFactory pluginViewWithArguments:arguments];
     }
+    [attributes release];
+    return view;
 }
 
-- (NSView *)viewForPluginWithURL:(NSURL *)URL
-                      attributes:(NSArray *)attributesArray
-                         baseURL:(NSURL *)baseURL
-                        MIMEType:(NSString *)MIMEType;
+- (NSString *)valueForKey:(NSString *)key keys:(NSArray *)keys values:(NSArray *)values
 {
-    NSRange r1, r2, r3;
-    uint i;
-
-    // Parse the attributesArray into key/value pairs.
-    // Store them in a dictionary so they can be passed to WebPlugins.
-    // Store them in ordered arrays so they can be passed to Netscape plug-ins.
-    NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
-    NSMutableArray *attributeKeys = [[NSMutableArray alloc] init];
-    NSMutableArray *attributeValues = [[NSMutableArray alloc] init];
-    for (i = 0; i < [attributesArray count]; i++) {
-        NSString *attribute = [attributesArray objectAtIndex:i];
-        if ([attribute rangeOfString:@"__KHTML__"].length == 0) {
-            r1 = [attribute rangeOfString:@"="];
-            r2 = [attribute rangeOfString:@"\""];
-            r3.location = r2.location + 1;
-            r3.length = [attribute length] - r2.location - 2; // don't include quotes
-            NSString *key = [attribute substringToIndex:r1.location];
-            NSString *value = [attribute substringWithRange:r3];
-            [attributes setObject:value forKey:key];
-            [attributeKeys addObject:key];
-            [attributeValues addObject:value];
+    unsigned count = [keys count];
+    unsigned i;
+    for (i = 0; i < count; i++) {
+        if ([[keys objectAtIndex:i] _web_isCaseInsensitiveEqualToString:key]) {
+            return [values objectAtIndex:i];
         }
     }
+    return nil;
+}
+
+- (NSView *)viewForPluginWithURL:(NSURL *)URL
+                  attributeNames:(NSArray *)attributeNames
+                 attributeValues:(NSArray *)attributeValues
+                        MIMEType:(NSString *)MIMEType
+{
+    ASSERT([attributeNames count] == [attributeValues count]);
 
     WebBasePluginPackage *pluginPackage = nil;
     NSView *view = nil;
@@ -872,10 +871,12 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
         }
     }
 
+    NSURL *baseURL = [[[_frame dataSource] response] URL];
     if (pluginPackage) {
         if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
             view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
-                                    attributes:attributes
+                                attributeNames:attributeNames
+                               attributeValues:attributeValues
                                        baseURL:baseURL];
         } else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
             view = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:NSZeroRect
@@ -883,7 +884,7 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
                                                                      URL:URL
                                                                  baseURL:baseURL
                                                                 MIMEType:MIMEType
-                                                           attributeKeys:attributeKeys
+                                                           attributeKeys:attributeNames
                                                          attributeValues:attributeValues] autorelease];
         } else {
             ASSERT_NOT_REACHED();
@@ -897,26 +898,24 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
     }
 
     if (errorCode) {
+        NSString *pluginPage = [self valueForKey:@"pluginspage" keys:attributeNames values:attributeValues];
+        NSURL *pluginPageURL = pluginPage != nil ? [self URLWithAttributeString:pluginPage] : nil;
         NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
                                                         contentURL:URL
-                                                     pluginPageURL:[NSURL _web_URLWithUserTypedString:[attributes objectForKey:@"pluginspage"]]
+                                                     pluginPageURL:pluginPageURL
                                                         pluginName:[pluginPackage name]
                                                           MIMEType:MIMEType];
         view = [[[WebNullPluginView alloc] initWithFrame:NSZeroRect error:error] autorelease];
         [error release];
     }
-
-    ASSERT(view);
-
-    [attributes release];
-    [attributeKeys release];
-    [attributeValues release];
     
+    ASSERT(view);
     return view;
 }
 
 - (NSView *)viewForJavaAppletWithFrame:(NSRect)theFrame
-                            attributes:(NSDictionary *)attributes
+                        attributeNames:(NSArray *)attributeNames
+                       attributeValues:(NSArray *)attributeValues
                                baseURL:(NSURL *)baseURL;
 {
     NSString *MIMEType = @"application/x-java-applet";
@@ -927,34 +926,31 @@ NSString *WebPluginContainerKey =   @"WebPluginContainer";
 
     if (pluginPackage) {
         if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
-            NSMutableDictionary *theAttributes = [NSMutableDictionary dictionary];
-            [theAttributes addEntriesFromDictionary:attributes];
-            [theAttributes setObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.width] forKey:@"width"];
-            [theAttributes setObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.height] forKey:@"height"];
-            
+            // For some reason, the Java plug-in requires that we pass the dimension of the plug-in as attributes.
+            NSMutableArray *names = [attributeNames mutableCopy];
+            NSMutableArray *values = [attributeValues mutableCopy];
+            if ([self valueForKey:@"width" keys:attributeNames values:attributeValues] == nil) {
+                [names addObject:@"width"];
+                [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.width]];
+            }
+            if ([self valueForKey:@"height" keys:attributeNames values:attributeValues] == nil) {
+                [names addObject:@"height"];
+                [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.height]];
+            }
             view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
-                                    attributes:theAttributes
+                                attributeNames:names
+                               attributeValues:values
                                        baseURL:baseURL];
+            [names release];
+            [values release];
         } else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
-            // Convert the attributes dictionary to 2 string arrays because this is what Netscape plug-ins expect.
-            NSMutableArray *attributeKeys = [[NSMutableArray alloc] init];
-            NSMutableArray *attributeValues = [[NSMutableArray alloc] init];
-            NSEnumerator *enumerator = [attributes keyEnumerator];
-            NSString *key;
-            
-            while ((key = [enumerator nextObject]) != nil) {
-                [attributeKeys addObject:key];
-                [attributeValues addObject:[attributes objectForKey:key]];
-            }
             view = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:theFrame
                                                                   plugin:(WebNetscapePluginPackage *)pluginPackage
                                                                      URL:nil
                                                                  baseURL:baseURL
                                                                 MIMEType:MIMEType
-                                                           attributeKeys:attributeKeys
+                                                           attributeKeys:attributeNames
                                                          attributeValues:attributeValues] autorelease];
-            [attributeKeys release];
-            [attributeValues release];
         } else {
             ASSERT_NOT_REACHED();
         }