| OLD | NEW |
| 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "web/PopupMenuImpl.h" | 6 #include "web/PopupMenuImpl.h" |
| 7 | 7 |
| 8 #include "core/HTMLNames.h" | 8 #include "core/HTMLNames.h" |
| 9 #include "core/css/CSSFontSelector.h" | 9 #include "core/css/CSSFontSelector.h" |
| 10 #include "core/dom/ElementTraversal.h" | 10 #include "core/dom/ElementTraversal.h" |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 class PopupMenuImpl::ItemIterationContext { | 158 class PopupMenuImpl::ItemIterationContext { |
| 159 STACK_ALLOCATED(); | 159 STACK_ALLOCATED(); |
| 160 public: | 160 public: |
| 161 ItemIterationContext(const ComputedStyle& style, SharedBuffer* buffer) | 161 ItemIterationContext(const ComputedStyle& style, SharedBuffer* buffer) |
| 162 : m_direction(style.direction()) | 162 : m_direction(style.direction()) |
| 163 , m_foregroundColor(style.visitedDependentColor(CSSPropertyColor)) | 163 , m_foregroundColor(style.visitedDependentColor(CSSPropertyColor)) |
| 164 , m_backgroundColor(style.visitedDependentColor(CSSPropertyBackgroundCol
or)) | 164 , m_backgroundColor(style.visitedDependentColor(CSSPropertyBackgroundCol
or)) |
| 165 , m_textTransform(style.textTransform()) | 165 , m_textTransform(style.textTransform()) |
| 166 , m_fontDescription(style.fontDescription()) | 166 , m_fontDescription(style.fontDescription()) |
| 167 , m_listIndex(0) | 167 , m_listIndex(0) |
| 168 , m_isInGroup(false) |
| 168 , m_buffer(buffer) | 169 , m_buffer(buffer) |
| 169 { | 170 { |
| 170 ASSERT(m_buffer); | 171 ASSERT(m_buffer); |
| 171 #if OS(LINUX) | 172 #if OS(LINUX) |
| 172 // On other platforms, the <option> background color is the same as the | 173 // On other platforms, the <option> background color is the same as the |
| 173 // <select> background color. On Linux, that makes the <option> | 174 // <select> background color. On Linux, that makes the <option> |
| 174 // background color very dark, so by default, try to use a lighter | 175 // background color very dark, so by default, try to use a lighter |
| 175 // background color for <option>s. | 176 // background color for <option>s. |
| 176 if (LayoutTheme::theme().systemColor(CSSValueButtonface) == m_background
Color) | 177 if (LayoutTheme::theme().systemColor(CSSValueButtonface) == m_background
Color) |
| 177 m_backgroundColor = LayoutTheme::theme().systemColor(CSSValueMenu); | 178 m_backgroundColor = LayoutTheme::theme().systemColor(CSSValueMenu); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 191 PagePopupClient::addString("fontFamily: [", m_buffer); | 192 PagePopupClient::addString("fontFamily: [", m_buffer); |
| 192 for (const FontFamily* f = &fontFamily(); f; f = f->next()) { | 193 for (const FontFamily* f = &fontFamily(); f; f = f->next()) { |
| 193 addJavaScriptString(f->family().string(), m_buffer); | 194 addJavaScriptString(f->family().string(), m_buffer); |
| 194 if (f->next()) | 195 if (f->next()) |
| 195 PagePopupClient::addString(",", m_buffer); | 196 PagePopupClient::addString(",", m_buffer); |
| 196 } | 197 } |
| 197 PagePopupClient::addString("]", m_buffer); | 198 PagePopupClient::addString("]", m_buffer); |
| 198 PagePopupClient::addString("},\n", m_buffer); | 199 PagePopupClient::addString("},\n", m_buffer); |
| 199 } | 200 } |
| 200 | 201 |
| 202 void startGroupChildren() |
| 203 { |
| 204 ASSERT(!m_isInGroup); |
| 205 PagePopupClient::addString("children: [", m_buffer); |
| 206 m_isInGroup = true; |
| 207 } |
| 208 void finishGroupIfNecessary() |
| 209 { |
| 210 if (!m_isInGroup) |
| 211 return; |
| 212 PagePopupClient::addString("],},\n", m_buffer); |
| 213 m_isInGroup = false; |
| 214 } |
| 215 |
| 201 int fontSize() const { return m_fontDescription.computedPixelSize(); } | 216 int fontSize() const { return m_fontDescription.computedPixelSize(); } |
| 202 FontStyle fontStyle() const { return m_fontDescription.style(); } | 217 FontStyle fontStyle() const { return m_fontDescription.style(); } |
| 203 FontVariant fontVariant() const { return m_fontDescription.variant(); } | 218 FontVariant fontVariant() const { return m_fontDescription.variant(); } |
| 204 const FontFamily& fontFamily() const { return m_fontDescription.family(); } | 219 const FontFamily& fontFamily() const { return m_fontDescription.family(); } |
| 205 | 220 |
| 206 TextDirection m_direction; | 221 TextDirection m_direction; |
| 207 Color m_foregroundColor; | 222 Color m_foregroundColor; |
| 208 Color m_backgroundColor; | 223 Color m_backgroundColor; |
| 209 ETextTransform m_textTransform; | 224 ETextTransform m_textTransform; |
| 210 const FontDescription& m_fontDescription; | 225 const FontDescription& m_fontDescription; |
| 211 | 226 |
| 212 int m_listIndex; | 227 int m_listIndex; |
| 228 bool m_isInGroup; |
| 213 SharedBuffer* m_buffer; | 229 SharedBuffer* m_buffer; |
| 214 }; | 230 }; |
| 215 | 231 |
| 216 // ---------------------------------------------------------------- | 232 // ---------------------------------------------------------------- |
| 217 | 233 |
| 218 PassRefPtrWillBeRawPtr<PopupMenuImpl> PopupMenuImpl::create(ChromeClientImpl* ch
romeClient, PopupMenuClient* client) | 234 PassRefPtrWillBeRawPtr<PopupMenuImpl> PopupMenuImpl::create(ChromeClientImpl* ch
romeClient, PopupMenuClient* client) |
| 219 { | 235 { |
| 220 return adoptRefWillBeNoop(new PopupMenuImpl(chromeClient, client)); | 236 return adoptRefWillBeNoop(new PopupMenuImpl(chromeClient, client)); |
| 221 } | 237 } |
| 222 | 238 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 245 PagePopupClient::addString("<!DOCTYPE html><head><meta charset='UTF-8'><styl
e>\n", data); | 261 PagePopupClient::addString("<!DOCTYPE html><head><meta charset='UTF-8'><styl
e>\n", data); |
| 246 data->append(Platform::current()->loadResource("pickerCommon.css")); | 262 data->append(Platform::current()->loadResource("pickerCommon.css")); |
| 247 data->append(Platform::current()->loadResource("listPicker.css")); | 263 data->append(Platform::current()->loadResource("listPicker.css")); |
| 248 PagePopupClient::addString("</style></head><body><div id=main>Loading...</di
v><script>\n" | 264 PagePopupClient::addString("</style></head><body><div id=main>Loading...</di
v><script>\n" |
| 249 "window.dialogArguments = {\n", data); | 265 "window.dialogArguments = {\n", data); |
| 250 addProperty("selectedIndex", m_client->selectedIndex(), data); | 266 addProperty("selectedIndex", m_client->selectedIndex(), data); |
| 251 const ComputedStyle* ownerStyle = ownerElement().computedStyle(); | 267 const ComputedStyle* ownerStyle = ownerElement().computedStyle(); |
| 252 ItemIterationContext context(*ownerStyle, data); | 268 ItemIterationContext context(*ownerStyle, data); |
| 253 context.serializeBaseStyle(); | 269 context.serializeBaseStyle(); |
| 254 PagePopupClient::addString("children: [\n", data); | 270 PagePopupClient::addString("children: [\n", data); |
| 255 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())
) { | 271 for (; context.m_listIndex < m_client->listSize(); ++context.m_listIndex) { |
| 272 Element& child = m_client->itemElement(context.m_listIndex); |
| 273 if (!isHTMLOptGroupElement(child.parentNode())) |
| 274 context.finishGroupIfNecessary(); |
| 256 if (isHTMLOptionElement(child)) | 275 if (isHTMLOptionElement(child)) |
| 257 addOption(context, toHTMLOptionElement(child)); | 276 addOption(context, toHTMLOptionElement(child)); |
| 258 if (isHTMLOptGroupElement(child)) | 277 else if (isHTMLOptGroupElement(child)) |
| 259 addOptGroup(context, toHTMLOptGroupElement(child)); | 278 addOptGroup(context, toHTMLOptGroupElement(child)); |
| 260 if (isHTMLHRElement(child)) | 279 else if (isHTMLHRElement(child)) |
| 261 addSeparator(context, toHTMLHRElement(child)); | 280 addSeparator(context, toHTMLHRElement(child)); |
| 262 } | 281 } |
| 282 context.finishGroupIfNecessary(); |
| 263 PagePopupClient::addString("],\n", data); | 283 PagePopupClient::addString("],\n", data); |
| 264 | 284 |
| 265 addProperty("anchorRectInScreen", anchorRectInScreen, data); | 285 addProperty("anchorRectInScreen", anchorRectInScreen, data); |
| 266 bool isRTL = !ownerStyle->isLeftToRightDirection(); | 286 bool isRTL = !ownerStyle->isLeftToRightDirection(); |
| 267 addProperty("isRTL", isRTL, data); | 287 addProperty("isRTL", isRTL, data); |
| 268 addProperty("paddingStart", isRTL ? m_client->clientPaddingRight().toDouble(
) : m_client->clientPaddingLeft().toDouble(), data); | 288 addProperty("paddingStart", isRTL ? m_client->clientPaddingRight().toDouble(
) : m_client->clientPaddingLeft().toDouble(), data); |
| 269 PagePopupClient::addString("};\n", data); | 289 PagePopupClient::addString("};\n", data); |
| 270 data->append(Platform::current()->loadResource("pickerCommon.js")); | 290 data->append(Platform::current()->loadResource("pickerCommon.js")); |
| 271 data->append(Platform::current()->loadResource("listPicker.js")); | 291 data->append(Platform::current()->loadResource("listPicker.js")); |
| 272 PagePopupClient::addString("</script></body>\n", data); | 292 PagePopupClient::addString("</script></body>\n", data); |
| 273 } | 293 } |
| 274 | 294 |
| 275 void PopupMenuImpl::addElementStyle(ItemIterationContext& context, HTMLElement&
element) | 295 void PopupMenuImpl::addElementStyle(ItemIterationContext& context, HTMLElement&
element) |
| 276 { | 296 { |
| 277 const ComputedStyle* style = m_client->computedStyleForItem(element); | 297 const ComputedStyle* style = m_client->computedStyleForItem(context.m_listIn
dex); |
| 278 ASSERT(style); | 298 ASSERT(style); |
| 279 SharedBuffer* data = context.m_buffer; | 299 SharedBuffer* data = context.m_buffer; |
| 280 // TODO(tkent): We generate unnecessary "style: {\n},\n" even if no | 300 // TODO(tkent): We generate unnecessary "style: {\n},\n" even if no |
| 281 // additional style. | 301 // additional style. |
| 282 PagePopupClient::addString("style: {\n", data); | 302 PagePopupClient::addString("style: {\n", data); |
| 283 if (style->visibility() == HIDDEN) | 303 if (style->visibility() == HIDDEN) |
| 284 addProperty("visibility", String("hidden"), data); | 304 addProperty("visibility", String("hidden"), data); |
| 285 if (style->display() == NONE) | 305 if (style->display() == NONE) |
| 286 addProperty("display", String("none"), data); | 306 addProperty("display", String("none"), data); |
| 287 if (context.m_direction != style->direction()) | 307 if (context.m_direction != style->direction()) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 317 addProperty("textTransform", String(textTransformToString(style->textTra
nsform())), data); | 337 addProperty("textTransform", String(textTransformToString(style->textTra
nsform())), data); |
| 318 | 338 |
| 319 PagePopupClient::addString("},\n", data); | 339 PagePopupClient::addString("},\n", data); |
| 320 } | 340 } |
| 321 | 341 |
| 322 void PopupMenuImpl::addOption(ItemIterationContext& context, HTMLOptionElement&
element) | 342 void PopupMenuImpl::addOption(ItemIterationContext& context, HTMLOptionElement&
element) |
| 323 { | 343 { |
| 324 SharedBuffer* data = context.m_buffer; | 344 SharedBuffer* data = context.m_buffer; |
| 325 PagePopupClient::addString("{", data); | 345 PagePopupClient::addString("{", data); |
| 326 addProperty("label", element.text(), data); | 346 addProperty("label", element.text(), data); |
| 327 ASSERT(context.m_listIndex == element.listIndex()); | 347 addProperty("value", context.m_listIndex, data); |
| 328 addProperty("value", context.m_listIndex++, data); | |
| 329 if (!element.title().isEmpty()) | 348 if (!element.title().isEmpty()) |
| 330 addProperty("title", element.title(), data); | 349 addProperty("title", element.title(), data); |
| 331 const AtomicString& ariaLabel = element.fastGetAttribute(HTMLNames::aria_lab
elAttr); | 350 const AtomicString& ariaLabel = element.fastGetAttribute(HTMLNames::aria_lab
elAttr); |
| 332 if (!ariaLabel.isEmpty()) | 351 if (!ariaLabel.isEmpty()) |
| 333 addProperty("ariaLabel", ariaLabel, data); | 352 addProperty("ariaLabel", ariaLabel, data); |
| 334 if (element.isDisabledFormControl()) | 353 if (element.isDisabledFormControl()) |
| 335 addProperty("disabled", true, data); | 354 addProperty("disabled", true, data); |
| 336 addElementStyle(context, element); | 355 addElementStyle(context, element); |
| 337 PagePopupClient::addString("},", data); | 356 PagePopupClient::addString("},", data); |
| 338 } | 357 } |
| 339 | 358 |
| 340 void PopupMenuImpl::addOptGroup(ItemIterationContext& context, HTMLOptGroupEleme
nt& element) | 359 void PopupMenuImpl::addOptGroup(ItemIterationContext& context, HTMLOptGroupEleme
nt& element) |
| 341 { | 360 { |
| 342 SharedBuffer* data = context.m_buffer; | 361 SharedBuffer* data = context.m_buffer; |
| 343 ++context.m_listIndex; | |
| 344 PagePopupClient::addString("{\n", data); | 362 PagePopupClient::addString("{\n", data); |
| 345 PagePopupClient::addString("type: \"optgroup\",\n", data); | 363 PagePopupClient::addString("type: \"optgroup\",\n", data); |
| 346 addProperty("label", element.groupLabelText(), data); | 364 addProperty("label", element.groupLabelText(), data); |
| 347 addProperty("title", element.title(), data); | 365 addProperty("title", element.title(), data); |
| 348 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); | 366 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); |
| 349 addProperty("disabled", element.isDisabledFormControl(), data); | 367 addProperty("disabled", element.isDisabledFormControl(), data); |
| 350 addElementStyle(context, element); | 368 addElementStyle(context, element); |
| 351 PagePopupClient::addString("children: [", data); | 369 context.startGroupChildren(); |
| 352 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(element)) { | 370 // We should call ItemIterationContext::finishGroupIfNecessary() later. |
| 353 if (isHTMLOptionElement(child)) | |
| 354 addOption(context, toHTMLOptionElement(child)); | |
| 355 if (isHTMLHRElement(child)) | |
| 356 addSeparator(context, toHTMLHRElement(child)); | |
| 357 } | |
| 358 PagePopupClient::addString("],\n", data); | |
| 359 PagePopupClient::addString("},\n", data); | |
| 360 } | 371 } |
| 361 | 372 |
| 362 void PopupMenuImpl::addSeparator(ItemIterationContext& context, HTMLHRElement& e
lement) | 373 void PopupMenuImpl::addSeparator(ItemIterationContext& context, HTMLHRElement& e
lement) |
| 363 { | 374 { |
| 364 SharedBuffer* data = context.m_buffer; | 375 SharedBuffer* data = context.m_buffer; |
| 365 ++context.m_listIndex; | |
| 366 PagePopupClient::addString("{\n", data); | 376 PagePopupClient::addString("{\n", data); |
| 367 PagePopupClient::addString("type: \"separator\",\n", data); | 377 PagePopupClient::addString("type: \"separator\",\n", data); |
| 368 addProperty("title", element.title(), data); | 378 addProperty("title", element.title(), data); |
| 369 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); | 379 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); |
| 370 addProperty("disabled", element.isDisabledFormControl(), data); | 380 addProperty("disabled", element.isDisabledFormControl(), data); |
| 371 addElementStyle(context, element); | 381 addElementStyle(context, element); |
| 372 PagePopupClient::addString("},\n", data); | 382 PagePopupClient::addString("},\n", data); |
| 373 } | 383 } |
| 374 | 384 |
| 375 void PopupMenuImpl::selectFontsFromOwnerDocument(Document& document) | 385 void PopupMenuImpl::selectFontsFromOwnerDocument(Document& document) |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 ownerElement().document().updateLayoutTreeIfNeeded(); | 479 ownerElement().document().updateLayoutTreeIfNeeded(); |
| 470 if (!m_client) | 480 if (!m_client) |
| 471 return; | 481 return; |
| 472 m_needsUpdate = false; | 482 m_needsUpdate = false; |
| 473 RefPtr<SharedBuffer> data = SharedBuffer::create(); | 483 RefPtr<SharedBuffer> data = SharedBuffer::create(); |
| 474 PagePopupClient::addString("window.updateData = {\n", data.get()); | 484 PagePopupClient::addString("window.updateData = {\n", data.get()); |
| 475 PagePopupClient::addString("type: \"update\",\n", data.get()); | 485 PagePopupClient::addString("type: \"update\",\n", data.get()); |
| 476 ItemIterationContext context(*ownerElement().computedStyle(), data.get()); | 486 ItemIterationContext context(*ownerElement().computedStyle(), data.get()); |
| 477 context.serializeBaseStyle(); | 487 context.serializeBaseStyle(); |
| 478 PagePopupClient::addString("children: [", data.get()); | 488 PagePopupClient::addString("children: [", data.get()); |
| 479 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())
) { | 489 for (; context.m_listIndex < m_client->listSize(); ++context.m_listIndex) { |
| 490 Element& child = m_client->itemElement(context.m_listIndex); |
| 491 if (!isHTMLOptGroupElement(child.parentNode())) |
| 492 context.finishGroupIfNecessary(); |
| 480 if (isHTMLOptionElement(child)) | 493 if (isHTMLOptionElement(child)) |
| 481 addOption(context, toHTMLOptionElement(child)); | 494 addOption(context, toHTMLOptionElement(child)); |
| 482 if (isHTMLOptGroupElement(child)) | 495 else if (isHTMLOptGroupElement(child)) |
| 483 addOptGroup(context, toHTMLOptGroupElement(child)); | 496 addOptGroup(context, toHTMLOptGroupElement(child)); |
| 484 if (isHTMLHRElement(child)) | 497 else if (isHTMLHRElement(child)) |
| 485 addSeparator(context, toHTMLHRElement(child)); | 498 addSeparator(context, toHTMLHRElement(child)); |
| 486 } | 499 } |
| 500 context.finishGroupIfNecessary(); |
| 487 PagePopupClient::addString("],\n", data.get()); | 501 PagePopupClient::addString("],\n", data.get()); |
| 488 PagePopupClient::addString("}\n", data.get()); | 502 PagePopupClient::addString("}\n", data.get()); |
| 489 m_popup->postMessage(String::fromUTF8(data->data(), data->size())); | 503 m_popup->postMessage(String::fromUTF8(data->data(), data->size())); |
| 490 } | 504 } |
| 491 | 505 |
| 492 | 506 |
| 493 void PopupMenuImpl::disconnectClient() | 507 void PopupMenuImpl::disconnectClient() |
| 494 { | 508 { |
| 495 m_client = nullptr; | 509 m_client = nullptr; |
| 496 // Cannot be done during finalization, so instead done when the | 510 // Cannot be done during finalization, so instead done when the |
| 497 // layout object is destroyed and disconnected. | 511 // layout object is destroyed and disconnected. |
| 498 dispose(); | 512 dispose(); |
| 499 } | 513 } |
| 500 | 514 |
| 501 } // namespace blink | 515 } // namespace blink |
| OLD | NEW |