2005-12-01  Anders Carlsson  <andersca@mac.com>

        Reviewed by Darin.

        - Fix <http://bugzilla.opendarwin.org/show_bug.cgi?id=4340>
        Safari not supporting disabled in multi select option tag.

        * khtml/rendering/render_form.cpp:
        (RenderSelect::updateFromElement):
        Update calls to append functions to set the enabled state of items.

        * kwq/KWQComboBox.h:
        (QComboBox::appendItem):
        (QComboBox::appendGroupLabel):
        (QComboBox::appendSeparator):
        Add enabled parameter to append functions.

        * kwq/KWQComboBox.mm:
        (QComboBox::QComboBox):
        Don't autoenable menu items on the popup button since that's handled
        manually now.

        (QComboBox::setTitle):
        Set enabled state on menu items.

        (QComboBox::appendItem):
        Add enabled parameter.

        * kwq/KWQListBox.h:
        (KWQListBoxItem::KWQListBoxItem):
        Add enabled variable to item struct.

        (QListBox::appendItem):
        (QListBox::appendGroupLabel):
        Add enabled parameter to append functions.

        * kwq/KWQListBox.mm:
        (QListBox::appendItem):
        Add enabled parameter.

        (-[KWQTableView tableView:shouldSelectRow:]):
        Only select the row if the item is enabled.

        (-[KWQTableView drawRow:clipRect:]):
        Draw using the disabled color if the row is disabled.

        * manual-tests/disabled-option-elements.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@11423 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog-2005-12-19 b/WebCore/ChangeLog-2005-12-19
index 703c15d..10e7737a 100644
--- a/WebCore/ChangeLog-2005-12-19
+++ b/WebCore/ChangeLog-2005-12-19
@@ -1,3 +1,51 @@
+2005-12-01  Anders Carlsson  <andersca@mac.com>
+
+        Reviewed by Darin.
+
+        - Fix <http://bugzilla.opendarwin.org/show_bug.cgi?id=4340>
+        Safari not supporting disabled in multi select option tag.
+
+        * khtml/rendering/render_form.cpp:
+        (RenderSelect::updateFromElement):
+        Update calls to append functions to set the enabled state of items.
+
+        * kwq/KWQComboBox.h:
+        (QComboBox::appendItem):
+        (QComboBox::appendGroupLabel):
+        (QComboBox::appendSeparator):
+        Add enabled parameter to append functions.
+       
+        * kwq/KWQComboBox.mm:
+        (QComboBox::QComboBox):
+        Don't autoenable menu items on the popup button since that's handled
+        manually now.
+
+        (QComboBox::setTitle):
+        Set enabled state on menu items.
+
+        (QComboBox::appendItem):
+        Add enabled parameter.
+
+        * kwq/KWQListBox.h:
+        (KWQListBoxItem::KWQListBoxItem):
+        Add enabled variable to item struct.
+
+        (QListBox::appendItem):
+        (QListBox::appendGroupLabel):
+        Add enabled parameter to append functions.
+
+        * kwq/KWQListBox.mm:
+        (QListBox::appendItem):
+        Add enabled parameter.
+
+        (-[KWQTableView tableView:shouldSelectRow:]):
+        Only select the row if the item is enabled.
+
+        (-[KWQTableView drawRow:clipRect:]):
+        Draw using the disabled color if the row is disabled.
+
+        * manual-tests/disabled-option-elements.html: Added.
+
 2005-12-02  Darin Adler  <darin@apple.com>
 
         Reviewed by Beth
diff --git a/WebCore/khtml/ecma/kjs_events.cpp b/WebCore/khtml/ecma/kjs_events.cpp
index b277fd2..9545218 100644
--- a/WebCore/khtml/ecma/kjs_events.cpp
+++ b/WebCore/khtml/ecma/kjs_events.cpp
@@ -26,6 +26,7 @@
 #include "kjs_window.h"
 #include "kjs_views.h"
 #include "kjs_proxy.h"
+#include "html/html_imageimpl.h"
 #include "xml/dom_nodeimpl.h"
 #include "xml/dom_docimpl.h"
 #include "xml/dom2_eventsimpl.h"
@@ -42,8 +43,11 @@
 using DOM::ClipboardEventImpl;
 using DOM::DocumentImpl;
 using DOM::DOMString;
+using DOM::ElementImpl;
 using DOM::EventImpl;
 using DOM::EventListenerEvent;
+using DOM::HTMLImageElementImpl;
+using DOM::HTMLNames::imgTag;
 using DOM::KeyboardEventImpl;
 using DOM::MouseEventImpl;
 using DOM::UIEventImpl;
@@ -1246,22 +1250,19 @@
             NodeImpl *node = toNode(args[0]);
             if (node) {
                 if (node->isElementNode()) {
-                    cb->clipboard->setDragImageElement(node, QPoint(x,y));                    
+                    if (static_cast<ElementImpl*>(node)->hasLocalName(imgTag) && 
+                        !node->inDocument()) {
+                        HTMLImageElementImpl *image = static_cast<HTMLImageElementImpl*>(node);
+                        
+                        cb->clipboard->setDragImage(image->pixmap(), QPoint(x, y));
+                    } else {
+                        cb->clipboard->setDragImageElement(node, QPoint(x,y));
+                    }
                     return Undefined();
                 } else {
                     return throwError(exec, SyntaxError, "setDragImageFromElement: Invalid first argument");
                 }
             }
-
-            // See if they passed us an Image object
-            ObjectImp *o = static_cast<ObjectImp*>(args[0]);
-            if (o->isObject() && o->inherits(&Image::info)) {
-                Image *JSImage = static_cast<Image*>(o);
-                cb->clipboard->setDragImage(JSImage->image()->pixmap(), QPoint(x,y));                
-                return Undefined();
-            } else {
-                return throwError(exec, TypeError);
-            }
         }
     }
     return Undefined();
diff --git a/WebCore/khtml/ecma/kjs_html.cpp b/WebCore/khtml/ecma/kjs_html.cpp
index 1e184da..8d205d5 100644
--- a/WebCore/khtml/ecma/kjs_html.cpp
+++ b/WebCore/khtml/ecma/kjs_html.cpp
@@ -1052,11 +1052,12 @@
   focus		KJS::HTMLElement::AnchorFocus		DontDelete|Function 0
   toString      KJS::HTMLElement::AnchorToString        DontDelete|Function 0
 @end
-@begin HTMLImageElementTable 14
+@begin HTMLImageElementTable 15
   name		KJS::HTMLElement::ImageName		DontDelete
   align		KJS::HTMLElement::ImageAlign		DontDelete
   alt		KJS::HTMLElement::ImageAlt		DontDelete
   border	KJS::HTMLElement::ImageBorder		DontDelete
+  complete  KJS::HTMLElement::ImageComplete     DontDelete
   height	KJS::HTMLElement::ImageHeight		DontDelete
   hspace	KJS::HTMLElement::ImageHspace		DontDelete
   isMap		KJS::HTMLElement::ImageIsMap		DontDelete
@@ -1946,6 +1947,7 @@
         case ImageAlign:           return String(image.align());
         case ImageAlt:             return String(image.alt());
         case ImageBorder:          return Number(image.border());
+        case ImageComplete:        return Boolean(image.complete());
         case ImageHeight:          return Number(image.height(true));
         case ImageHspace:          return Number(image.hspace());
         case ImageIsMap:           return Boolean(image.isMap());
@@ -3620,132 +3622,18 @@
         ValueImp *h = list.at(1);
         height = h->toInt32(exec);
     }
-        
-    ObjectImp *result(new Image(m_doc.get(), widthSet, width, heightSet, height));
-  
-    /* TODO: do we need a prototype ? */
-    return result;
-}
 
-const ClassInfo KJS::Image::info = { "Image", 0, &ImageTable, 0 };
+    HTMLImageElementImpl *image = new HTMLImageElementImpl(m_doc.get());        
 
-/* Source for ImageTable. Use "make hashtables" to regenerate.
-@begin ImageTable 6
-  src		Image::Src		DontDelete
-  complete	Image::Complete		DontDelete|ReadOnly
-  onload        Image::OnLoad           DontDelete
-  width         Image::Width            DontDelete|ReadOnly
-  height        Image::Height           DontDelete|ReadOnly
-@end
-*/
-
-bool Image::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
-{
-  return getStaticValueSlot<Image,DOMObject>(exec, &ImageTable, this, propertyName, slot);
-}
-
-ValueImp *Image::getValueProperty(ExecState *, int token) const
-{
-  switch (token) {
-  case Src:
-    return jsString(doc ? doc->completeURL(src.domString()) : src);
-  case Complete:
-    return Boolean(!img || img->status() >= khtml::CachedObject::Persistent);
-  case OnLoad:
-    if (onLoadListener && onLoadListener->listenerObjImp()) {
-      return onLoadListener->listenerObj();
-    } else {
-      return Null();
-    }
-  case Width: {
     if (widthSet)
-        return Number(width);
-    int w = 0;
-    if (img) {
-      QSize size = img->pixmap_size();
-      if (size.isValid())
-        w = size.width();
-    }
-    return Number(w);
-  }
-  case Height: {
+        image->setWidth(width);
+    
     if (heightSet)
-        return Number(height);
-    int h = 0;
-    if (img) {
-      QSize size = img->pixmap_size();
-      if (size.isValid())
-        h = size.height();
-    }
-    return Number(h);
-  }
-  default:
-    kdWarning() << "Image::getValueProperty unhandled token " << token << endl;
-    return NULL;
-  }
+        image->setHeight(height);
+    
+    return static_cast<ObjectImp*>(getDOMNode(exec, image));
 }
 
-void Image::put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr)
-{
-  lookupPut<Image,DOMObject>(exec, propertyName, value, attr, &ImageTable, this );
-}
-
-void Image::putValueProperty(ExecState *exec, int token, ValueImp *value, int /*attr*/)
-{
-  switch(token) {
-  case Src:
-  {
-    src = value->toString(exec);
-    if ( img ) img->deref(this);
-    img = doc ? doc->docLoader()->requestImage( src.domString() ) : 0;
-    if ( img ) img->ref(this);
-    break;
-  }
-  case OnLoad:
-    onLoadListener = Window::retrieveActive(exec)->getJSEventListener(value, true);
-    if (onLoadListener) onLoadListener->ref();
-    break;
-  case Width:
-    widthSet = true;
-    width = value->toInt32(exec);
-    break;
-  case Height:
-    heightSet = true;
-    height = value->toInt32(exec);
-    break;
-  default:
-    kdWarning() << "HTMLDocument::putValueProperty unhandled token " << token << endl;
-  }
-}
-
-void Image::notifyFinished(khtml::CachedObject *)
-{
-  if (onLoadListener && doc->part()) {
-    int ignoreException;
-    EventImpl *ev = doc->createEvent("HTMLEvents", ignoreException);
-    ev->ref();
-    ev->initEvent(loadEvent, true, true);
-    onLoadListener->handleEventImpl(ev, true);
-    ev->deref();
-  }
-}
-
-Image::Image(DocumentImpl *d, bool ws, int w, bool hs, int h)
-  : doc(d), img(0), onLoadListener(0)
-{
-      widthSet = ws;
-      width = w;
-      heightSet = hs;
-      height = h;
-}
-
-Image::~Image()
-{
-  if ( img ) img->deref(this);
-  if ( onLoadListener ) onLoadListener->deref();
-}
-
-
 ////////////////////// Context2D Object ////////////////////////
 
 IMPLEMENT_PROTOFUNC(Context2DFunction)
@@ -4275,21 +4163,8 @@
             QPixmap pixmap;
             CGContextRef sourceContext = 0;
             
-            // Check for JavaScript Image, <img> or <canvas>.
-            if (o->inherits(&Image::info)) {
-                Image *i = static_cast<Image*>(o);
-                khtml::CachedImage *ci = i->image();
-                if (ci) {
-                    pixmap = ci->pixmap();
-                }
-                else {
-                    // No image.
-                    return Undefined();
-                }
-                w = pixmap.width();
-                h = pixmap.height();
-            }
-            else if (o->inherits(&KJS::HTMLElement::img_info)){
+            // Check for img> or <canvas>.
+            if (o->inherits(&KJS::HTMLElement::img_info)){
                 NodeImpl *n = static_cast<HTMLElement *>(args[0])->impl();
                 HTMLImageElementImpl *e = static_cast<HTMLImageElementImpl*>(n);
                 pixmap = e->pixmap();
@@ -4389,9 +4264,9 @@
             if (args.size() != 10)
                 return throwError(exec, SyntaxError);
             ObjectImp *o = static_cast<ObjectImp*>(args[0]);
-            if (!o->isObject() || !o->inherits(&Image::info))
+            if (!o->isObject(&HTMLElement::img_info))
                 return throwError(exec, TypeError);
-            Image *i = static_cast<Image*>(o);
+            HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl*>(static_cast<HTMLElement*>(o)->impl());
             float sx = args[1]->toNumber(exec);
             float sy = args[2]->toNumber(exec);
             float sw = args[3]->toNumber(exec);
@@ -4401,18 +4276,15 @@
             float dw = args[7]->toNumber(exec);
             float dh = args[8]->toNumber(exec);
             QString compositeOperator = args[9]->toString(exec).qstring().lower();
-            khtml::CachedImage *ci = i->image();
-            if (ci) {
-                QPixmap pixmap = ci->pixmap();
-                QPainter p;
+            QPixmap pixmap = i->pixmap();
+            QPainter p;
 
-                p.drawFloatPixmap (dx, dy, dw, dh, pixmap, sx, sy, sw, sh, QPainter::compositeOperatorFromString(compositeOperator), drawingContext);
+            p.drawFloatPixmap (dx, dy, dw, dh, pixmap, sx, sy, sw, sh, QPainter::compositeOperatorFromString(compositeOperator), drawingContext);
                 
-                if (contextObject->_needsFlushRasterCache)
-                    pixmap.flushRasterCache();
+            if (contextObject->_needsFlushRasterCache)
+                pixmap.flushRasterCache();
 
-                renderer->setNeedsImageUpdate();
-            }
+            renderer->setNeedsImageUpdate();
             break;
         }
         case Context2D::SetAlpha: {
@@ -4458,7 +4330,7 @@
             if (args.size() != 2)
                 return throwError(exec, SyntaxError);
             ObjectImp *o = static_cast<ObjectImp*>(args[0]);
-            if (!o->isObject() || !o->inherits(&Image::info))
+            if (!o->isObject() || !o->inherits(&HTMLElement::img_info))
                 return throwError(exec, TypeError);
             int repetitionType = ImagePattern::Repeat;
             QString repetitionString = args[1]->toString(exec).qstring().lower();
@@ -4468,7 +4340,7 @@
                 repetitionType = ImagePattern::RepeatY;
             else if (repetitionString == "no-repeat")
                 repetitionType = ImagePattern::NoRepeat;
-            return new ImagePattern(static_cast<Image*>(o), repetitionType);
+            return new ImagePattern(static_cast<HTMLImageElementImpl*>(static_cast<HTMLElement*>(o)->impl()), repetitionType);
         }
     }
 
@@ -5248,28 +5120,22 @@
 }
 
 CGPatternCallbacks patternCallbacks = { 0, drawPattern, NULL };
-ImagePattern::ImagePattern(Image *i, int repetitionType)
+ImagePattern::ImagePattern(HTMLImageElementImpl *i, int repetitionType)
     :_rw(0), _rh(0)
 {
-    khtml::CachedImage *ci = i->image();
-    if (ci) {
-        _pixmap = ci->pixmap();
-        float w = _pixmap.width();
-        float h = _pixmap.height();
-        _bounds = CGRectMake (0, 0, w, h);
+    _pixmap = i->pixmap();
+    float w = _pixmap.width();
+    float h = _pixmap.height();
+    _bounds = CGRectMake (0, 0, w, h);
 
-        if (repetitionType == Repeat) {
-            _rw = w; _rh = h;
-        }
-        else if (repetitionType == RepeatX) {
-            _rw = w; _rh = 0;
-        }
-        else if (repetitionType == RepeatY) {
-            _rw = 0; _rh = h;
-        }
-        else if (repetitionType == NoRepeat) {
-            _rw = 0; _rh = 0;
-        }
+    if (repetitionType == Repeat) {
+        _rw = w; _rh = h;
+    } else if (repetitionType == RepeatX) {
+        _rw = w; _rh = 0;
+    } else if (repetitionType == RepeatY) {
+        _rw = 0; _rh = h;
+    } else if (repetitionType == NoRepeat) {
+        _rw = 0; _rh = 0;
     }
 }
 
diff --git a/WebCore/khtml/ecma/kjs_html.h b/WebCore/khtml/ecma/kjs_html.h
index 29ab58d..fd5866e 100644
--- a/WebCore/khtml/ecma/kjs_html.h
+++ b/WebCore/khtml/ecma/kjs_html.h
@@ -33,6 +33,7 @@
     class HTMLCollectionImpl;
     class HTMLDocumentImpl;
     class HTMLElementImpl;
+    class HTMLImageElementImpl;
     class HTMLSelectElementImpl;
     class HTMLTableCaptionElementImpl;
     class HTMLTableSectionElementImpl;
@@ -246,7 +247,7 @@
            AnchorPort, AnchorPathName, AnchorHash, AnchorSearch, AnchorName,
            AnchorRev, AnchorTabIndex, AnchorTarget, AnchorText, AnchorBlur, AnchorToString, 
            ImageName, ImageAlign, ImageHspace, ImageVspace, ImageUseMap, ImageAlt,
-           ImageLowSrc, ImageWidth, ImageIsMap, ImageBorder, ImageHeight,
+           ImageLowSrc, ImageWidth, ImageIsMap, ImageBorder, ImageComplete, ImageHeight,
            ImageLongDesc, ImageSrc, ImageX, ImageY, ObjectHspace, ObjectHeight, ObjectAlign,
            ObjectBorder, ObjectCode, ObjectType, ObjectVspace, ObjectArchive,
            ObjectDeclare, ObjectForm, ObjectCodeBase, ObjectCodeType, ObjectData,
@@ -352,33 +353,6 @@
     RefPtr<DOM::DocumentImpl> m_doc;
   };
 
-  class Image : public DOMObject, public khtml::CachedObjectClient {
-  public:
-    Image(DOM::DocumentImpl *d, bool ws, int w, bool hs, int h);
-    ~Image();
-    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
-    ValueImp *getValueProperty(ExecState *exec, int token) const;
-    virtual void put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr = None);
-    void putValueProperty(ExecState *exec, int token, ValueImp *value, int /*attr*/);
-    void notifyFinished(khtml::CachedObject *);
-    virtual bool toBoolean(ExecState *) const { return true; }
-    virtual const ClassInfo* classInfo() const { return &info; }
-    static const ClassInfo info;
-    enum { Src, Complete, OnLoad, Width, Height };
-    
-    khtml::CachedImage* image() { return img; }
-    
-  private:
-    UString src;
-    QGuardedPtr<DOM::DocumentImpl> doc;
-    khtml::CachedImage* img;
-    JSAbstractEventListener *onLoadListener;
-    bool widthSet;
-    bool heightSet;
-    int width;
-    int height;
-  };
-
   ////////////////////// Context2D Object ////////////////////////
 
   class Context2D : public DOMObject {
@@ -523,7 +497,7 @@
 
   class ImagePattern : public DOMObject {
   public:
-    ImagePattern(Image *i, int type);
+    ImagePattern(DOM::HTMLImageElementImpl *i, int type);
     virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
     ValueImp *getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr = None);
diff --git a/WebCore/khtml/html/html_imageimpl.cpp b/WebCore/khtml/html/html_imageimpl.cpp
index 743aeab..60c1f5d 100644
--- a/WebCore/khtml/html/html_imageimpl.cpp
+++ b/WebCore/khtml/html/html_imageimpl.cpp
@@ -280,6 +280,10 @@
         int width = getAttribute(widthAttr).qstring().toInt(&ok);
         if (ok)
             return width;
+        
+        // if the image has been loaded, use its width
+        if (m_imageLoader.imageComplete())
+            return m_imageLoader.image()->valid_rect().width();
     }
 
     if (DocumentImpl* doc = getDocument()) {
@@ -300,6 +304,10 @@
         int height = getAttribute(heightAttr).qstring().toInt(&ok);
         if (ok)
             return height;
+        
+        // if the image has been loaded, use its height
+        if (m_imageLoader.imageComplete())
+            return m_imageLoader.image()->valid_rect().height();        
     }
 
     if (DocumentImpl* doc = getDocument()) {
@@ -450,6 +458,13 @@
     return y;
 }
 
+bool HTMLImageElementImpl::complete() const
+{
+    CachedImage *img = m_imageLoader.image();
+    
+    return !img || img->status() >= khtml::CachedObject::Persistent;
+}
+
 // -------------------------------------------------------------------------
 
 HTMLMapElementImpl::HTMLMapElementImpl(DocumentImpl *doc)
diff --git a/WebCore/khtml/html/html_imageimpl.h b/WebCore/khtml/html/html_imageimpl.h
index 275f7d4..00788dc 100644
--- a/WebCore/khtml/html/html_imageimpl.h
+++ b/WebCore/khtml/html/html_imageimpl.h
@@ -140,6 +140,8 @@
     int x() const;
     int y() const;
 
+    bool complete() const;
+    
 protected:
     HTMLImageLoader m_imageLoader;
     DOMString usemap;
diff --git a/WebCore/khtml/rendering/render_form.cpp b/WebCore/khtml/rendering/render_form.cpp
index 53252a0..087b17c 100644
--- a/WebCore/khtml/rendering/render_form.cpp
+++ b/WebCore/khtml/rendering/render_form.cpp
@@ -703,24 +703,29 @@
         else
             static_cast<KComboBox*>(m_widget)->clear();
 
+        bool groupEnabled = true;
         for (listIndex = 0; listIndex < int(listItems.size()); listIndex++) {
             if (listItems[listIndex]->hasTagName(optgroupTag)) {
-                QString label = listItems[listIndex]->getAttribute(labelAttr).qstring();
+                HTMLOptGroupElementImpl *optgroupElement = static_cast<HTMLOptGroupElementImpl*>(listItems[listIndex]);
+                QString label = optgroupElement->getAttribute(labelAttr).qstring();
                 label.replace(QChar('\\'), backslashAsCurrencySymbol());
-
+                
                 // In WinIE, an optgroup can't start or end with whitespace (other than the indent
                 // we give it).  We match this behavior.
                 label = label.stripWhiteSpace();
                 // We want to collapse our whitespace too.  This will match other browsers.
                 label = label.simplifyWhiteSpace();
+
+                groupEnabled = optgroupElement->isEnabled();
                 
                 if (m_useListBox)
-                    static_cast<KListBox*>(m_widget)->appendGroupLabel(label);
+                    static_cast<KListBox*>(m_widget)->appendGroupLabel(label, groupEnabled);
                 else
                     static_cast<KComboBox*>(m_widget)->appendGroupLabel(label);
             }
             else if (listItems[listIndex]->hasTagName(optionTag)) {
-                QString itemText = static_cast<HTMLOptionElementImpl*>(listItems[listIndex])->text().qstring();
+                HTMLOptionElementImpl *optionElement = static_cast<HTMLOptionElementImpl*>(listItems[listIndex]);
+                QString itemText = optionElement->text().qstring();
                 itemText.replace(QChar('\\'), backslashAsCurrencySymbol());
 
                 // In WinIE, leading and trailing whitespace is ignored in options. We match this behavior.
@@ -732,9 +737,9 @@
                     itemText.prepend("    ");
 
                 if (m_useListBox)
-                    static_cast<KListBox*>(m_widget)->appendItem(itemText);
+                    static_cast<KListBox*>(m_widget)->appendItem(itemText, groupEnabled && optionElement->isEnabled());
                 else
-                    static_cast<KComboBox*>(m_widget)->appendItem(itemText);
+                    static_cast<KComboBox*>(m_widget)->appendItem(itemText, groupEnabled && optionElement->isEnabled());
             }
             else if (listItems[listIndex]->hasTagName(hrTag)) {
                 if (!m_useListBox) {
diff --git a/WebCore/kwq/KWQComboBox.h b/WebCore/kwq/KWQComboBox.h
index aca2d29..28c6edd 100644
--- a/WebCore/kwq/KWQComboBox.h
+++ b/WebCore/kwq/KWQComboBox.h
@@ -41,9 +41,9 @@
     ~QComboBox();
     
     void clear();
-    void appendItem(const QString &text) { appendItem(text, KWQListBoxOption); }
-    void appendGroupLabel(const QString &text) { appendItem(text, KWQListBoxGroupLabel); }
-    void appendSeparator() { appendItem(QString::null, KWQListBoxSeparator); }
+    void appendItem(const QString &text, bool enabled) { appendItem(text, KWQListBoxOption, enabled); }
+    void appendGroupLabel(const QString &text) { appendItem(text, KWQListBoxGroupLabel, false); }
+    void appendSeparator() { appendItem(QString::null, KWQListBoxSeparator, true); }
 
     int currentItem() const { return _currentItem; }
     void setCurrentItem(int);
@@ -67,7 +67,7 @@
     void populateMenu();
     
 private:
-    void appendItem(const QString &, KWQListBoxItemType);
+    void appendItem(const QString &, KWQListBoxItemType, bool);
     const int *dimensions() const;
     NSFont *labelFont() const;
     void setTitle(NSMenuItem *, const KWQListBoxItem &);
diff --git a/WebCore/kwq/KWQComboBox.mm b/WebCore/kwq/KWQComboBox.mm
index e5bbba6..6f7dbde 100644
--- a/WebCore/kwq/KWQComboBox.mm
+++ b/WebCore/kwq/KWQComboBox.mm
@@ -100,7 +100,8 @@
 
     [[button cell] setControlSize:NSSmallControlSize];
     [button setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
-
+    [button setAutoenablesItems:NO];
+    
     KWQ_UNBLOCK_EXCEPTIONS;
 }
 
@@ -124,15 +125,16 @@
         [menuItem setAttributedTitle:string];
         [string release];
         [attributes release];
-        [menuItem setAction:NULL /*@selector(fakeSelectorForDisabledItem)*/];
+        [menuItem setEnabled:NO];
     } else {
         [menuItem setTitle:title.string.getNSString()];
-    }
+        [menuItem setEnabled:title.enabled];
+    }    
 }
 
-void QComboBox::appendItem(const QString &text, KWQListBoxItemType type)
+void QComboBox::appendItem(const QString &text, KWQListBoxItemType type, bool enabled)
 {
-    const KWQListBoxItem listItem(text, type);
+    const KWQListBoxItem listItem(text, type, enabled);
     _items.append(listItem);
     if (_menuPopulated) {
         KWQPopUpButton *button = (KWQPopUpButton *)getView();
diff --git a/WebCore/kwq/KWQListBox.h b/WebCore/kwq/KWQListBox.h
index 445177e..da2852f 100644
--- a/WebCore/kwq/KWQListBox.h
+++ b/WebCore/kwq/KWQListBox.h
@@ -39,8 +39,9 @@
 {
     QString string;
     KWQListBoxItemType type;
+    bool enabled;
     
-    KWQListBoxItem(const QString &s, KWQListBoxItemType t) : string(s), type(t) { }
+    KWQListBoxItem(const QString &s, KWQListBoxItemType t, bool e) : string(s), type(t), enabled(e) { }
 };
 
 class QListBox : public QScrollView {
@@ -57,8 +58,8 @@
     void setSelectionMode(SelectionMode);
 
     void clear();
-    void appendItem(const QString &s) { appendItem(s, KWQListBoxOption); }
-    void appendGroupLabel(const QString &s) { appendItem(s, KWQListBoxGroupLabel); }
+    void appendItem(const QString &s, bool enabled) { appendItem(s, KWQListBoxOption, enabled); }
+    void appendGroupLabel(const QString &s, bool enabled) { appendItem(s, KWQListBoxGroupLabel, enabled); }
     void doneAppendingItems();
 
     void setSelected(int, bool);
@@ -82,7 +83,7 @@
     void setFont(const QFont &font);
 
 private:
-    void appendItem(const QString &, KWQListBoxItemType);
+    void appendItem(const QString &, KWQListBoxItemType, bool);
 
     // A vector<KWQListBoxItem> or QValueVector<KWQListBoxItem> might be more efficient for large lists.
     QValueList<KWQListBoxItem> _items;
diff --git a/WebCore/kwq/KWQListBox.mm b/WebCore/kwq/KWQListBox.mm
index 44cd1fe..a451a72 100644
--- a/WebCore/kwq/KWQListBox.mm
+++ b/WebCore/kwq/KWQListBox.mm
@@ -192,9 +192,9 @@
     KWQ_UNBLOCK_EXCEPTIONS;
 }
 
-void QListBox::appendItem(const QString &text, KWQListBoxItemType type)
+void QListBox::appendItem(const QString &text, KWQListBoxItemType type, bool enabled)
 {
-    _items.append(KWQListBoxItem(text, type));
+    _items.append(KWQListBoxItem(text, type, enabled));
     _widthGood = false;
 }
 
@@ -666,7 +666,12 @@
 
 - (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row
 {
-    return _box && _box->itemAtIndex(row).type == KWQListBoxOption;
+    if (!_box)
+        return NO;
+    
+    const KWQListBoxItem &item = _box->itemAtIndex(row);
+    
+    return item.type == KWQListBoxOption && item.enabled;
 }
 
 - (BOOL)selectionShouldChangeInTableView:(NSTableView *)aTableView
@@ -683,7 +688,7 @@
     const KWQListBoxItem &item = _box->itemAtIndex(row);
 
     NSColor *color;
-    if (_box->isEnabled()) {
+    if (_box->isEnabled() && item.enabled) {
         if ([self isRowSelected:row] && [[self window] firstResponder] == self && ([[self window] isKeyWindow] || ![[self window] canBecomeKeyWindow])) {
             color = [NSColor alternateSelectedControlTextColor];
         } else {
diff --git a/WebCore/manual-tests/disabled-option-elements.html b/WebCore/manual-tests/disabled-option-elements.html
new file mode 100644
index 0000000..2c0c6b2
--- /dev/null
+++ b/WebCore/manual-tests/disabled-option-elements.html
@@ -0,0 +1,27 @@
+<body>
+<p>This tests that disabled option elements shouldn't be selectable and that no elements in disabled optgroups are selectable.</p>
+<form name="form">
+<select multiple="multiple">
+<option>my value 1</option>
+<option value="2" disabled>you should not be able to select this</option>
+<option>my value 3</option>
+<optgroup label="disabled option group" disabled>
+     	<option>this should be disabled</option>
+		<option>as well as this</option>
+<optgroup>
+</select>
+
+<select>
+<option>my value 1</option>
+<option value="2" disabled>you should not be able to select this</option>
+<option>my value 3</option>
+<optgroup label="disabled option group" disabled>
+     	<option>this should be disabled</option>
+		<option>as well as this</option>
+<optgroup>
+</select>
+</form>
+
+</body>
+</html>
+\ No newline at end of file