1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2001 Dirk Mueller (mueller (at) kde.org) 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. 6 * (C) 2006 Alexey Proskuryakov (ap (at) nypop.com) 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public License 19 * along with this library; see the file COPYING.LIB. If not, write to 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 * 23 */ 24 25 #include "config.h" 26 #include "HTMLOptGroupElement.h" 27 28 #include "CSSStyleSelector.h" 29 #include "Document.h" 30 #include "HTMLNames.h" 31 #include "HTMLSelectElement.h" 32 #include "RenderMenuList.h" 33 #include "NodeRenderStyle.h" 34 #include <wtf/StdLibExtras.h> 35 36 namespace WebCore { 37 38 using namespace HTMLNames; 39 40 inline HTMLOptGroupElement::HTMLOptGroupElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) 41 : HTMLFormControlElement(tagName, document, form) 42 { 43 ASSERT(hasTagName(optgroupTag)); 44 } 45 46 PassRefPtr<HTMLOptGroupElement> HTMLOptGroupElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form) 47 { 48 return adoptRef(new HTMLOptGroupElement(tagName, document, form)); 49 } 50 51 bool HTMLOptGroupElement::supportsFocus() const 52 { 53 return HTMLElement::supportsFocus(); 54 } 55 56 bool HTMLOptGroupElement::isFocusable() const 57 { 58 // Optgroup elements do not have a renderer so we check the renderStyle instead. 59 return supportsFocus() && renderStyle() && renderStyle()->display() != NONE; 60 } 61 62 const AtomicString& HTMLOptGroupElement::formControlType() const 63 { 64 DEFINE_STATIC_LOCAL(const AtomicString, optgroup, ("optgroup")); 65 return optgroup; 66 } 67 68 void HTMLOptGroupElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) 69 { 70 recalcSelectOptions(); 71 HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); 72 } 73 74 void HTMLOptGroupElement::parseMappedAttribute(Attribute* attr) 75 { 76 HTMLFormControlElement::parseMappedAttribute(attr); 77 recalcSelectOptions(); 78 } 79 80 void HTMLOptGroupElement::recalcSelectOptions() 81 { 82 ContainerNode* select = parentNode(); 83 while (select && !select->hasTagName(selectTag)) 84 select = select->parentNode(); 85 if (select) 86 static_cast<HTMLSelectElement*>(select)->setRecalcListItems(); 87 } 88 89 void HTMLOptGroupElement::attach() 90 { 91 if (parentNode()->renderStyle()) 92 setRenderStyle(styleForRenderer()); 93 HTMLFormControlElement::attach(); 94 } 95 96 void HTMLOptGroupElement::detach() 97 { 98 m_style.clear(); 99 HTMLFormControlElement::detach(); 100 } 101 102 void HTMLOptGroupElement::setRenderStyle(PassRefPtr<RenderStyle> newStyle) 103 { 104 m_style = newStyle; 105 } 106 107 RenderStyle* HTMLOptGroupElement::nonRendererRenderStyle() const 108 { 109 return m_style.get(); 110 } 111 112 String HTMLOptGroupElement::groupLabelText() const 113 { 114 String itemText = document()->displayStringModifiedByEncoding(getAttribute(labelAttr)); 115 116 // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior. 117 itemText = itemText.stripWhiteSpace(); 118 // We want to collapse our whitespace too. This will match other browsers. 119 itemText = itemText.simplifyWhiteSpace(); 120 121 return itemText; 122 } 123 124 HTMLSelectElement* HTMLOptGroupElement::ownerSelectElement() const 125 { 126 ContainerNode* select = parentNode(); 127 while (select && !select->hasTagName(selectTag)) 128 select = select->parentNode(); 129 130 if (!select) 131 return 0; 132 133 return static_cast<HTMLSelectElement*>(select); 134 } 135 136 void HTMLOptGroupElement::accessKeyAction(bool) 137 { 138 HTMLSelectElement* select = ownerSelectElement(); 139 // send to the parent to bring focus to the list box 140 if (select && !select->focused()) 141 select->accessKeyAction(false); 142 } 143 144 } // namespace 145