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 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
23 #include "config.h"
24 #include "WindowFeatures.h"
25
26 #include "PlatformString.h"
27 #include "StringHash.h"
28 #include <wtf/Assertions.h>
29 #include <wtf/HashMap.h>
30 #include <wtf/MathExtras.h>
31
32 namespace WebCore {
33
34 // Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
isSeparator(UChar c)35 static bool isSeparator(UChar c)
36 {
37 return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
38 }
39
WindowFeatures(const String & features)40 WindowFeatures::WindowFeatures(const String& features)
41 : xSet(false)
42 , ySet(false)
43 , widthSet(false)
44 , heightSet(false)
45 , fullscreen(false)
46 , dialog(false)
47 {
48 /*
49 The IE rule is: all features except for channelmode and fullscreen default to YES, but
50 if the user specifies a feature string, all features default to NO. (There is no public
51 standard that applies to this method.)
52
53 <http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/open_0.asp>
54 We always allow a window to be resized, which is consistent with Firefox.
55 */
56
57 if (features.length() == 0) {
58 menuBarVisible = true;
59 statusBarVisible = true;
60 toolBarVisible = true;
61 locationBarVisible = true;
62 scrollbarsVisible = true;
63 resizable = true;
64 return;
65 }
66
67 menuBarVisible = false;
68 statusBarVisible = false;
69 toolBarVisible = false;
70 locationBarVisible = false;
71 scrollbarsVisible = false;
72 resizable = true;
73
74 // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
75 int keyBegin, keyEnd;
76 int valueBegin, valueEnd;
77
78 int i = 0;
79 int length = features.length();
80 String buffer = features.lower();
81 while (i < length) {
82 // skip to first non-separator, but don't skip past the end of the string
83 while (isSeparator(buffer[i])) {
84 if (i >= length)
85 break;
86 i++;
87 }
88 keyBegin = i;
89
90 // skip to first separator
91 while (!isSeparator(buffer[i]))
92 i++;
93 keyEnd = i;
94
95 // skip to first '=', but don't skip past a ',' or the end of the string
96 while (buffer[i] != '=') {
97 if (buffer[i] == ',' || i >= length)
98 break;
99 i++;
100 }
101
102 // skip to first non-separator, but don't skip past a ',' or the end of the string
103 while (isSeparator(buffer[i])) {
104 if (buffer[i] == ',' || i >= length)
105 break;
106 i++;
107 }
108 valueBegin = i;
109
110 // skip to first separator
111 while (!isSeparator(buffer[i]))
112 i++;
113 valueEnd = i;
114
115 ASSERT(i <= length);
116
117 String keyString(buffer.substring(keyBegin, keyEnd - keyBegin));
118 String valueString(buffer.substring(valueBegin, valueEnd - valueBegin));
119 setWindowFeature(keyString, valueString);
120 }
121 }
122
setWindowFeature(const String & keyString,const String & valueString)123 void WindowFeatures::setWindowFeature(const String& keyString, const String& valueString)
124 {
125 int value;
126
127 // Listing a key with no value is shorthand for key=yes
128 if (valueString.length() == 0 || valueString == "yes")
129 value = 1;
130 else
131 value = valueString.toInt();
132
133 // We ignore a keyString of "resizable", which is consistent with Firefox.
134 if (keyString == "left" || keyString == "screenx") {
135 xSet = true;
136 x = value;
137 } else if (keyString == "top" || keyString == "screeny") {
138 ySet = true;
139 y = value;
140 } else if (keyString == "width" || keyString == "innerwidth") {
141 widthSet = true;
142 width = value;
143 } else if (keyString == "height" || keyString == "innerheight") {
144 heightSet = true;
145 height = value;
146 } else if (keyString == "menubar")
147 menuBarVisible = value;
148 else if (keyString == "toolbar")
149 toolBarVisible = value;
150 else if (keyString == "location")
151 locationBarVisible = value;
152 else if (keyString == "status")
153 statusBarVisible = value;
154 else if (keyString == "fullscreen")
155 fullscreen = value;
156 else if (keyString == "scrollbars")
157 scrollbarsVisible = value;
158 }
159
boolFeature(const HashMap<String,String> & features,const char * key,bool defaultValue)160 bool WindowFeatures::boolFeature(const HashMap<String, String>& features, const char* key, bool defaultValue)
161 {
162 HashMap<String, String>::const_iterator it = features.find(key);
163 if (it == features.end())
164 return defaultValue;
165 const String& value = it->second;
166 return value.isNull() || value == "1" || value == "yes" || value == "on";
167 }
168
floatFeature(const HashMap<String,String> & features,const char * key,float min,float max,float defaultValue)169 float WindowFeatures::floatFeature(const HashMap<String, String>& features, const char* key, float min, float max, float defaultValue)
170 {
171 HashMap<String, String>::const_iterator it = features.find(key);
172 if (it == features.end())
173 return defaultValue;
174 // FIXME: Can't distinguish "0q" from string with no digits in it -- both return d == 0 and ok == false.
175 // Would be good to tell them apart somehow since string with no digits should be default value and
176 // "0q" should be minimum value.
177 bool ok;
178 double d = it->second.toDouble(&ok);
179 if ((d == 0 && !ok) || isnan(d))
180 return defaultValue;
181 if (d < min || max <= min)
182 return min;
183 if (d > max)
184 return max;
185 return static_cast<int>(d);
186 }
187
188 } // namespace WebCore
189