PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/3rdparty/webkit/Source/WebCore/page/WindowFeatures.cpp

https://bitbucket.org/kasimling/qt
C++ | 266 lines | 182 code | 34 blank | 50 comment | 101 complexity | 699926b083a20b7136c8b90a96c05171 MD5 | raw file
  1. /*
  2. * Copyright (C) 2000 Harri Porten (porten@kde.org)
  3. * Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
  4. * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reseved.
  5. * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
  20. * USA
  21. */
  22. #include "config.h"
  23. #include "WindowFeatures.h"
  24. #include "FloatRect.h"
  25. #include "PlatformString.h"
  26. #include <wtf/Assertions.h>
  27. #include <wtf/MathExtras.h>
  28. #include <wtf/text/StringHash.h>
  29. namespace WebCore {
  30. // Though isspace() considers \t and \v to be whitespace, Win IE doesn't when parsing window features.
  31. static bool isWindowFeaturesSeparator(UChar c)
  32. {
  33. return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
  34. }
  35. WindowFeatures::WindowFeatures(const String& features)
  36. : xSet(false)
  37. , ySet(false)
  38. , widthSet(false)
  39. , heightSet(false)
  40. , fullscreen(false)
  41. , dialog(false)
  42. {
  43. /*
  44. The IE rule is: all features except for channelmode and fullscreen default to YES, but
  45. if the user specifies a feature string, all features default to NO. (There is no public
  46. standard that applies to this method.)
  47. <http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/open_0.asp>
  48. We always allow a window to be resized, which is consistent with Firefox.
  49. */
  50. if (features.length() == 0) {
  51. menuBarVisible = true;
  52. statusBarVisible = true;
  53. toolBarVisible = true;
  54. locationBarVisible = true;
  55. scrollbarsVisible = true;
  56. resizable = true;
  57. return;
  58. }
  59. menuBarVisible = false;
  60. statusBarVisible = false;
  61. toolBarVisible = false;
  62. locationBarVisible = false;
  63. scrollbarsVisible = false;
  64. resizable = true;
  65. // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
  66. int keyBegin, keyEnd;
  67. int valueBegin, valueEnd;
  68. int i = 0;
  69. int length = features.length();
  70. String buffer = features.lower();
  71. while (i < length) {
  72. // skip to first non-separator, but don't skip past the end of the string
  73. while (isWindowFeaturesSeparator(buffer[i])) {
  74. if (i >= length)
  75. break;
  76. i++;
  77. }
  78. keyBegin = i;
  79. // skip to first separator
  80. while (!isWindowFeaturesSeparator(buffer[i]))
  81. i++;
  82. keyEnd = i;
  83. // skip to first '=', but don't skip past a ',' or the end of the string
  84. while (buffer[i] != '=') {
  85. if (buffer[i] == ',' || i >= length)
  86. break;
  87. i++;
  88. }
  89. // skip to first non-separator, but don't skip past a ',' or the end of the string
  90. while (isWindowFeaturesSeparator(buffer[i])) {
  91. if (buffer[i] == ',' || i >= length)
  92. break;
  93. i++;
  94. }
  95. valueBegin = i;
  96. // skip to first separator
  97. while (!isWindowFeaturesSeparator(buffer[i]))
  98. i++;
  99. valueEnd = i;
  100. ASSERT(i <= length);
  101. String keyString(buffer.substring(keyBegin, keyEnd - keyBegin));
  102. String valueString(buffer.substring(valueBegin, valueEnd - valueBegin));
  103. setWindowFeature(keyString, valueString);
  104. }
  105. }
  106. void WindowFeatures::setWindowFeature(const String& keyString, const String& valueString)
  107. {
  108. int value;
  109. // Listing a key with no value is shorthand for key=yes
  110. if (valueString.isEmpty() || valueString == "yes")
  111. value = 1;
  112. else
  113. value = valueString.toInt();
  114. // We treat keyString of "resizable" here as an additional feature rather than setting resizeable to true.
  115. // This is consistent with Firefox, but could also be handled at another level.
  116. if (keyString == "left" || keyString == "screenx") {
  117. xSet = true;
  118. x = value;
  119. } else if (keyString == "top" || keyString == "screeny") {
  120. ySet = true;
  121. y = value;
  122. } else if (keyString == "width" || keyString == "innerwidth") {
  123. widthSet = true;
  124. width = value;
  125. } else if (keyString == "height" || keyString == "innerheight") {
  126. heightSet = true;
  127. height = value;
  128. } else if (keyString == "menubar")
  129. menuBarVisible = value;
  130. else if (keyString == "toolbar")
  131. toolBarVisible = value;
  132. else if (keyString == "location")
  133. locationBarVisible = value;
  134. else if (keyString == "status")
  135. statusBarVisible = value;
  136. else if (keyString == "fullscreen")
  137. fullscreen = value;
  138. else if (keyString == "scrollbars")
  139. scrollbarsVisible = value;
  140. else if (value == 1)
  141. additionalFeatures.append(keyString);
  142. }
  143. WindowFeatures::WindowFeatures(const String& dialogFeaturesString, const FloatRect& screenAvailableRect)
  144. : widthSet(true)
  145. , heightSet(true)
  146. , menuBarVisible(false)
  147. , toolBarVisible(false)
  148. , locationBarVisible(false)
  149. , fullscreen(false)
  150. , dialog(true)
  151. {
  152. DialogFeaturesMap features;
  153. parseDialogFeatures(dialogFeaturesString, features);
  154. const bool trusted = false;
  155. // The following features from Microsoft's documentation are not implemented:
  156. // - default font settings
  157. // - width, height, left, and top specified in units other than "px"
  158. // - edge (sunken or raised, default is raised)
  159. // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print
  160. // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)
  161. // - unadorned: trusted && boolFeature(features, "unadorned");
  162. width = floatFeature(features, "dialogwidth", 100, screenAvailableRect.width(), 620); // default here came from frame size of dialog in MacIE
  163. height = floatFeature(features, "dialogheight", 100, screenAvailableRect.height(), 450); // default here came from frame size of dialog in MacIE
  164. x = floatFeature(features, "dialogleft", screenAvailableRect.x(), screenAvailableRect.maxX() - width, -1);
  165. xSet = x > 0;
  166. y = floatFeature(features, "dialogtop", screenAvailableRect.y(), screenAvailableRect.maxY() - height, -1);
  167. ySet = y > 0;
  168. if (boolFeature(features, "center", true)) {
  169. if (!xSet) {
  170. x = screenAvailableRect.x() + (screenAvailableRect.width() - width) / 2;
  171. xSet = true;
  172. }
  173. if (!ySet) {
  174. y = screenAvailableRect.y() + (screenAvailableRect.height() - height) / 2;
  175. ySet = true;
  176. }
  177. }
  178. resizable = boolFeature(features, "resizable");
  179. scrollbarsVisible = boolFeature(features, "scroll", true);
  180. statusBarVisible = boolFeature(features, "status", !trusted);
  181. }
  182. bool WindowFeatures::boolFeature(const DialogFeaturesMap& features, const char* key, bool defaultValue)
  183. {
  184. DialogFeaturesMap::const_iterator it = features.find(key);
  185. if (it == features.end())
  186. return defaultValue;
  187. const String& value = it->second;
  188. return value.isNull() || value == "1" || value == "yes" || value == "on";
  189. }
  190. float WindowFeatures::floatFeature(const DialogFeaturesMap& features, const char* key, float min, float max, float defaultValue)
  191. {
  192. DialogFeaturesMap::const_iterator it = features.find(key);
  193. if (it == features.end())
  194. return defaultValue;
  195. // FIXME: The toDouble function does not offer a way to tell "0q" from string with no digits in it: Both
  196. // return the number 0 and false for ok. But "0q" should yield the minimum rather than the default.
  197. bool ok;
  198. double parsedNumber = it->second.toDouble(&ok);
  199. if ((parsedNumber == 0 && !ok) || isnan(parsedNumber))
  200. return defaultValue;
  201. if (parsedNumber < min || max <= min)
  202. return min;
  203. if (parsedNumber > max)
  204. return max;
  205. // FIXME: Seems strange to cast a double to int and then convert back to a float. Why is this a good idea?
  206. return static_cast<int>(parsedNumber);
  207. }
  208. void WindowFeatures::parseDialogFeatures(const String& string, DialogFeaturesMap& map)
  209. {
  210. Vector<String> vector;
  211. string.split(';', vector);
  212. size_t size = vector.size();
  213. for (size_t i = 0; i < size; ++i) {
  214. const String& featureString = vector[i];
  215. size_t separatorPosition = featureString.find('=');
  216. size_t colonPosition = featureString.find(':');
  217. if (separatorPosition != notFound && colonPosition != notFound)
  218. continue; // ignore strings that have both = and :
  219. if (separatorPosition == notFound)
  220. separatorPosition = colonPosition;
  221. String key = featureString.left(separatorPosition).stripWhiteSpace().lower();
  222. // Null string for value indicates key without value.
  223. String value;
  224. if (separatorPosition != notFound) {
  225. value = featureString.substring(separatorPosition + 1).stripWhiteSpace().lower();
  226. value = value.left(value.find(' '));
  227. }
  228. map.set(key, value);
  229. }
  230. }
  231. } // namespace WebCore