18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2000 Harri Porten (porten@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
4f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reseved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Lesser General Public
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Lesser General Public License for more details.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Lesser General Public
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License along with this library; if not, write to the Free Software
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  USA
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WindowFeatures.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "FloatRect.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PlatformString.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h>
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h>
30f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <wtf/text/StringHash.h>
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch// Though isspace() considers \t and \v to be whitespace, Win IE doesn't when parsing window features.
35f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic bool isWindowFeaturesSeparator(UChar c)
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectWindowFeatures::WindowFeatures(const String& features)
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : xSet(false)
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , ySet(false)
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , widthSet(false)
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , heightSet(false)
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , fullscreen(false)
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , dialog(false)
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     The IE rule is: all features except for channelmode and fullscreen default to YES, but
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     if the user specifies a feature string, all features default to NO. (There is no public
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     standard that applies to this method.)
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     <http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/open_0.asp>
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     We always allow a window to be resized, which is consistent with Firefox.
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     */
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (features.length() == 0) {
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        menuBarVisible = true;
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        statusBarVisible = true;
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        toolBarVisible = true;
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        locationBarVisible = true;
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        scrollbarsVisible = true;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resizable = true;
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    menuBarVisible = false;
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    statusBarVisible = false;
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    toolBarVisible = false;
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    locationBarVisible = false;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    scrollbarsVisible = false;
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    resizable = true;
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int keyBegin, keyEnd;
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int valueBegin, valueEnd;
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int i = 0;
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int length = features.length();
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String buffer = features.lower();
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (i < length) {
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // skip to first non-separator, but don't skip past the end of the string
83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        while (isWindowFeaturesSeparator(buffer[i])) {
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (i >= length)
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            i++;
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        keyBegin = i;
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // skip to first separator
91f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        while (!isWindowFeaturesSeparator(buffer[i]))
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            i++;
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        keyEnd = i;
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // skip to first '=', but don't skip past a ',' or the end of the string
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (buffer[i] != '=') {
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (buffer[i] == ',' || i >= length)
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            i++;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // skip to first non-separator, but don't skip past a ',' or the end of the string
103f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        while (isWindowFeaturesSeparator(buffer[i])) {
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (buffer[i] == ',' || i >= length)
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            i++;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        valueBegin = i;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // skip to first separator
111f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        while (!isWindowFeaturesSeparator(buffer[i]))
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            i++;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        valueEnd = i;
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(i <= length);
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String keyString(buffer.substring(keyBegin, keyEnd - keyBegin));
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String valueString(buffer.substring(valueBegin, valueEnd - valueBegin));
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setWindowFeature(keyString, valueString);
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WindowFeatures::setWindowFeature(const String& keyString, const String& valueString)
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int value;
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Listing a key with no value is shorthand for key=yes
128f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (valueString.isEmpty() || valueString == "yes")
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        value = 1;
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        value = valueString.toInt();
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // We treat keyString of "resizable" here as an additional feature rather than setting resizeable to true.
134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // This is consistent with Firefox, but could also be handled at another level.
135f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (keyString == "left" || keyString == "screenx") {
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        xSet = true;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        x = value;
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (keyString == "top" || keyString == "screeny") {
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ySet = true;
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        y = value;
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (keyString == "width" || keyString == "innerwidth") {
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        widthSet = true;
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        width = value;
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (keyString == "height" || keyString == "innerheight") {
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        heightSet = true;
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        height = value;
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (keyString == "menubar")
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        menuBarVisible = value;
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (keyString == "toolbar")
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        toolBarVisible = value;
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (keyString == "location")
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        locationBarVisible = value;
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (keyString == "status")
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        statusBarVisible = value;
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (keyString == "fullscreen")
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fullscreen = value;
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (keyString == "scrollbars")
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        scrollbarsVisible = value;
16021939df44de1705786c545cd1bf519d47250322dBen Murdoch    else if (value == 1)
16121939df44de1705786c545cd1bf519d47250322dBen Murdoch        additionalFeatures.append(keyString);
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
164f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochWindowFeatures::WindowFeatures(const String& dialogFeaturesString, const FloatRect& screenAvailableRect)
165f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    : widthSet(true)
166f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , heightSet(true)
167f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , menuBarVisible(false)
168f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , toolBarVisible(false)
169f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , locationBarVisible(false)
170f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , fullscreen(false)
171f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , dialog(true)
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
173f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    DialogFeaturesMap features;
174f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    parseDialogFeatures(dialogFeaturesString, features);
175f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
176f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    const bool trusted = false;
177f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
178f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // The following features from Microsoft's documentation are not implemented:
179f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // - default font settings
180f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // - width, height, left, and top specified in units other than "px"
181f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // - edge (sunken or raised, default is raised)
182f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print
183f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)
184f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // - unadorned: trusted && boolFeature(features, "unadorned");
185f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
186f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    width = floatFeature(features, "dialogwidth", 100, screenAvailableRect.width(), 620); // default here came from frame size of dialog in MacIE
187f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    height = floatFeature(features, "dialogheight", 100, screenAvailableRect.height(), 450); // default here came from frame size of dialog in MacIE
188f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    x = floatFeature(features, "dialogleft", screenAvailableRect.x(), screenAvailableRect.maxX() - width, -1);
190f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    xSet = x > 0;
1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    y = floatFeature(features, "dialogtop", screenAvailableRect.y(), screenAvailableRect.maxY() - height, -1);
192f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    ySet = y > 0;
193f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
194f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (boolFeature(features, "center", true)) {
195f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!xSet) {
196f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            x = screenAvailableRect.x() + (screenAvailableRect.width() - width) / 2;
197f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            xSet = true;
198f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
199f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!ySet) {
200f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            y = screenAvailableRect.y() + (screenAvailableRect.height() - height) / 2;
201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            ySet = true;
202f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
203f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
204f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
205f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    resizable = boolFeature(features, "resizable");
206f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    scrollbarsVisible = boolFeature(features, "scroll", true);
207f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    statusBarVisible = boolFeature(features, "status", !trusted);
208f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
209f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
210f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool WindowFeatures::boolFeature(const DialogFeaturesMap& features, const char* key, bool defaultValue)
211f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
212f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    DialogFeaturesMap::const_iterator it = features.find(key);
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (it == features.end())
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return defaultValue;
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const String& value = it->second;
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return value.isNull() || value == "1" || value == "yes" || value == "on";
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
219f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochfloat WindowFeatures::floatFeature(const DialogFeaturesMap& features, const char* key, float min, float max, float defaultValue)
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
221f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    DialogFeaturesMap::const_iterator it = features.find(key);
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (it == features.end())
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return defaultValue;
224f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: The toDouble function does not offer a way to tell "0q" from string with no digits in it: Both
225f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // return the number 0 and false for ok. But "0q" should yield the minimum rather than the default.
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool ok;
227f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    double parsedNumber = it->second.toDouble(&ok);
228f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if ((parsedNumber == 0 && !ok) || isnan(parsedNumber))
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return defaultValue;
230f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (parsedNumber < min || max <= min)
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return min;
232f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (parsedNumber > max)
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return max;
234f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: Seems strange to cast a double to int and then convert back to a float. Why is this a good idea?
235f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return static_cast<int>(parsedNumber);
236f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
237f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
238f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid WindowFeatures::parseDialogFeatures(const String& string, DialogFeaturesMap& map)
239f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
240f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Vector<String> vector;
241f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    string.split(';', vector);
242f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    size_t size = vector.size();
243f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (size_t i = 0; i < size; ++i) {
244f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        const String& featureString = vector[i];
245f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
246f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        size_t separatorPosition = featureString.find('=');
247f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        size_t colonPosition = featureString.find(':');
248f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (separatorPosition != notFound && colonPosition != notFound)
249f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            continue; // ignore strings that have both = and :
250f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (separatorPosition == notFound)
251f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            separatorPosition = colonPosition;
252f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
253f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        String key = featureString.left(separatorPosition).stripWhiteSpace().lower();
254f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
255f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Null string for value indicates key without value.
256f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        String value;
257f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (separatorPosition != notFound) {
258f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            value = featureString.substring(separatorPosition + 1).stripWhiteSpace().lower();
259f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            value = value.left(value.find(' '));
260f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
261f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
262f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        map.set(key, value);
263f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
267