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 32namespace WebCore { 33 34// Though isspace() considers \t and \v to be whitespace, Win IE doesn't. 35static bool isSeparator(UChar c) 36{ 37 return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0'; 38} 39 40WindowFeatures::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 123void 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 160bool 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 169float 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