WebCore/page/WindowFeatures.cpp
changeset 0 4f2f89ce4247
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebCore/page/WindowFeatures.cpp	Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reseved.
+ *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ *  USA
+ */
+
+#include "config.h"
+#include "WindowFeatures.h"
+
+#include "PlatformString.h"
+#include "StringHash.h"
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+// Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
+static bool isSeparator(UChar c)
+{
+    return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
+}
+
+WindowFeatures::WindowFeatures(const String& features)
+    : xSet(false)
+    , ySet(false)
+    , widthSet(false)
+    , heightSet(false)
+    , fullscreen(false)
+    , dialog(false)
+{
+    /*
+     The IE rule is: all features except for channelmode and fullscreen default to YES, but
+     if the user specifies a feature string, all features default to NO. (There is no public
+     standard that applies to this method.)
+
+     <http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/open_0.asp>
+     We always allow a window to be resized, which is consistent with Firefox.
+     */
+
+    if (features.length() == 0) {
+        menuBarVisible = true;
+        statusBarVisible = true;
+        toolBarVisible = true;
+        locationBarVisible = true;
+        scrollbarsVisible = true;
+        resizable = true;
+        return;
+    }
+
+    menuBarVisible = false;
+    statusBarVisible = false;
+    toolBarVisible = false;
+    locationBarVisible = false;
+    scrollbarsVisible = false;
+    resizable = true;
+
+    // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
+    int keyBegin, keyEnd;
+    int valueBegin, valueEnd;
+
+    int i = 0;
+    int length = features.length();
+    String buffer = features.lower();
+    while (i < length) {
+        // skip to first non-separator, but don't skip past the end of the string
+        while (isSeparator(buffer[i])) {
+            if (i >= length)
+                break;
+            i++;
+        }
+        keyBegin = i;
+
+        // skip to first separator
+        while (!isSeparator(buffer[i]))
+            i++;
+        keyEnd = i;
+
+        // skip to first '=', but don't skip past a ',' or the end of the string
+        while (buffer[i] != '=') {
+            if (buffer[i] == ',' || i >= length)
+                break;
+            i++;
+        }
+
+        // skip to first non-separator, but don't skip past a ',' or the end of the string
+        while (isSeparator(buffer[i])) {
+            if (buffer[i] == ',' || i >= length)
+                break;
+            i++;
+        }
+        valueBegin = i;
+
+        // skip to first separator
+        while (!isSeparator(buffer[i]))
+            i++;
+        valueEnd = i;
+
+        ASSERT(i <= length);
+
+        String keyString(buffer.substring(keyBegin, keyEnd - keyBegin));
+        String valueString(buffer.substring(valueBegin, valueEnd - valueBegin));
+        setWindowFeature(keyString, valueString);
+    }
+}
+
+void WindowFeatures::setWindowFeature(const String& keyString, const String& valueString)
+{
+    int value;
+
+    // Listing a key with no value is shorthand for key=yes
+    if (valueString.length() == 0 || valueString == "yes")
+        value = 1;
+    else
+        value = valueString.toInt();
+
+    // We ignore a keyString of "resizable", which is consistent with Firefox.
+    if (keyString == "left" || keyString == "screenx") {
+        xSet = true;
+        x = value;
+    } else if (keyString == "top" || keyString == "screeny") {
+        ySet = true;
+        y = value;
+    } else if (keyString == "width" || keyString == "innerwidth") {
+        widthSet = true;
+        width = value;
+    } else if (keyString == "height" || keyString == "innerheight") {
+        heightSet = true;
+        height = value;
+    } else if (keyString == "menubar")
+        menuBarVisible = value;
+    else if (keyString == "toolbar")
+        toolBarVisible = value;
+    else if (keyString == "location")
+        locationBarVisible = value;
+    else if (keyString == "status")
+        statusBarVisible = value;
+    else if (keyString == "fullscreen")
+        fullscreen = value;
+    else if (keyString == "scrollbars")
+        scrollbarsVisible = value;
+    else if (value == 1)
+        additionalFeatures.append(keyString);
+}
+
+bool WindowFeatures::boolFeature(const HashMap<String, String>& features, const char* key, bool defaultValue)
+{
+    HashMap<String, String>::const_iterator it = features.find(key);
+    if (it == features.end())
+        return defaultValue;
+    const String& value = it->second;
+    return value.isNull() || value == "1" || value == "yes" || value == "on";
+}
+
+float WindowFeatures::floatFeature(const HashMap<String, String>& features, const char* key, float min, float max, float defaultValue)
+{
+    HashMap<String, String>::const_iterator it = features.find(key);
+    if (it == features.end())
+        return defaultValue;
+    // FIXME: Can't distinguish "0q" from string with no digits in it -- both return d == 0 and ok == false.
+    // Would be good to tell them apart somehow since string with no digits should be default value and
+    // "0q" should be minimum value.
+    bool ok;
+    double d = it->second.toDouble(&ok);
+    if ((d == 0 && !ok) || isnan(d))
+        return defaultValue;
+    if (d < min || max <= min)
+        return min;
+    if (d > max)
+        return max;
+    return static_cast<int>(d);
+}
+
+} // namespace WebCore