SelectPopupClient.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "config.h"
  19. #include "SelectPopupClient.h"
  20. #include "HTMLOptionElement.h"
  21. #include "HTMLSelectElement.h"
  22. #include "PopupPicker.h"
  23. #include "RenderObject.h"
  24. #include "WebPage_p.h"
  25. #include <BlackBerryPlatformString.h>
  26. #include <LocaleHandler.h>
  27. #include <LocalizeResource.h>
  28. #include <wtf/text/StringBuilder.h>
  29. using namespace WebCore;
  30. namespace BlackBerry {
  31. namespace WebKit {
  32. DEFINE_STATIC_LOCAL(BlackBerry::Platform::LocalizeResource, s_resource, ());
  33. SelectPopupClient::SelectPopupClient(bool multiple, int size, const ScopeArray<BlackBerry::Platform::String>& labels, bool* enableds, const int* itemType, bool* selecteds, WebPagePrivate* webPagePrivate, HTMLSelectElement* element)
  34. : PagePopupClient(webPagePrivate)
  35. , m_multiple(multiple)
  36. , m_size(size)
  37. , m_element(element)
  38. , m_notifyChangeTimer(this, &SelectPopupClient::notifySelectionChange)
  39. {
  40. generateHTML(multiple, size, labels, enableds, itemType, selecteds);
  41. }
  42. SelectPopupClient::~SelectPopupClient()
  43. {
  44. }
  45. void SelectPopupClient::generateHTML(bool, int size, const ScopeArray<BlackBerry::Platform::String>& labels, bool* enableds,
  46. const int* itemType, bool* selecteds)
  47. {
  48. StringBuilder source;
  49. source.appendLiteral("<style>\n");
  50. // Include CSS file.
  51. source.append(popupControlBlackBerryCss, sizeof(popupControlBlackBerryCss));
  52. source.appendLiteral("</style>\n<style>");
  53. source.append(selectControlBlackBerryCss, sizeof(selectControlBlackBerryCss));
  54. source.appendLiteral("</style></head><body>\n");
  55. source.appendLiteral("<script>\n");
  56. source.appendLiteral("window.addEventListener('load', function showIt() {");
  57. source.appendLiteral("window.select.show({");
  58. // Indicate if it is a multiselect.
  59. source.appendLiteral("isMultiSelect:");
  60. if (m_multiple)
  61. source.appendLiteral("true,");
  62. else
  63. source.appendLiteral("false,");
  64. // Add labels.
  65. source.appendLiteral("labels: [");
  66. for (int i = 0; i < size; i++) {
  67. source.append("'" + String(labels[i]).replaceWithLiteral('\\', "\\\\").replaceWithLiteral('\'', "\\'") + "'");
  68. // Don't append ',' to last element.
  69. if (i != size - 1)
  70. source.appendLiteral(", ");
  71. }
  72. source.appendLiteral("], ");
  73. // Add enables.
  74. source.append("enableds: [");
  75. for (int i = 0; i < size; i++) {
  76. if (enableds[i])
  77. source.appendLiteral("true");
  78. else
  79. source.appendLiteral("false");
  80. // Don't append ',' to last element.
  81. if (i != size - 1)
  82. source.appendLiteral(", ");
  83. }
  84. source.appendLiteral("], ");
  85. // Add itemType.
  86. source.appendLiteral("itemTypes: [");
  87. for (int i = 0; i < size; i++) {
  88. source.appendNumber(itemType[i]);
  89. // Don't append ',' to last element.
  90. if (i != size - 1)
  91. source.appendLiteral(", ");
  92. }
  93. source.appendLiteral("], ");
  94. // Add selecteds
  95. source.appendLiteral("selecteds: [");
  96. for (int i = 0; i < size; i++) {
  97. if (selecteds[i])
  98. source.appendLiteral("true");
  99. else
  100. source.appendLiteral("false");
  101. // Don't append ',' to last element.
  102. if (i != size - 1)
  103. source.appendLiteral(", ");
  104. }
  105. source.appendLiteral("], ");
  106. // Add UI text
  107. source.appendLiteral("uiText: {");
  108. source.append("title:'" + String::fromUTF8(s_resource.getString(BlackBerry::Platform::PICKER_SELECT_TITLE)) + "',");
  109. source.append("doneButtonLabel:'" + String::fromUTF8(s_resource.getString(BlackBerry::Platform::PICKER_DONE_BUTTON_LABEL)) + "',");
  110. source.append("cancelButtonLabel:'" + String::fromUTF8(s_resource.getString(BlackBerry::Platform::PICKER_CANCEL_BUTTON_LABEL)) + "',");
  111. source.appendLiteral("},");
  112. // Add directionality
  113. bool isRtl = BlackBerry::Platform::LocaleHandler::instance()->isRtlLocale();
  114. source.append("direction:'" + String(isRtl ? "rtl" : "ltr") + "',");
  115. source.appendLiteral("});\n");
  116. source.appendLiteral(" window.removeEventListener('load', showIt); }); \n");
  117. source.append(selectControlBlackBerryJs, sizeof(selectControlBlackBerryJs));
  118. source.appendLiteral("</script>\n</body> </html>\n");
  119. m_source = source.toString();
  120. }
  121. void SelectPopupClient::setValueAndClosePopup(const String& stringValue)
  122. {
  123. // Popup closed.
  124. if (!m_element)
  125. return;
  126. static const char* cancelValue = "-1";
  127. if (stringValue == cancelValue) {
  128. closePopup();
  129. return;
  130. }
  131. if (m_size > 0) {
  132. bool selecteds[m_size];
  133. for (unsigned i = 0; i < m_size; i++)
  134. selecteds[i] = stringValue[i] - '0';
  135. const Vector<HTMLElement*>& items = m_element->listItems();
  136. // If element changed after select UI showed, do nothing but closePopup().
  137. if (items.size() != static_cast<unsigned>(m_size)) {
  138. closePopup();
  139. return;
  140. }
  141. HTMLOptionElement* option;
  142. for (unsigned i = 0; i < m_size; i++) {
  143. if (items[i]->hasTagName(HTMLNames::optionTag)) {
  144. option = static_cast<HTMLOptionElement*>(items[i]);
  145. option->setSelectedState(selecteds[i]);
  146. }
  147. }
  148. }
  149. // Force repaint because we do not send mouse events to the select element
  150. // and the element doesn't automatically repaint itself.
  151. if (m_element->renderer())
  152. m_element->renderer()->repaint();
  153. m_notifyChangeTimer.startOneShot(0);
  154. }
  155. void SelectPopupClient::didClosePopup()
  156. {
  157. PagePopupClient::didClosePopup();
  158. m_element = 0;
  159. }
  160. void SelectPopupClient::notifySelectionChange(WebCore::Timer<SelectPopupClient>*)
  161. {
  162. if (m_element)
  163. m_element->dispatchFormControlChangeEvent();
  164. closePopup();
  165. }
  166. }
  167. }