001: /*
002: * This file is part of the Echo Web Application Framework (hereinafter "Echo").
003: * Copyright (C) 2002-2005 NextApp, Inc.
004: *
005: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006: *
007: * The contents of this file are subject to the Mozilla Public License Version
008: * 1.1 (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: * http://www.mozilla.org/MPL/
011: *
012: * Software distributed under the License is distributed on an "AS IS" basis,
013: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014: * for the specific language governing rights and limitations under the
015: * License.
016: *
017: * Alternatively, the contents of this file may be used under the terms of
018: * either the GNU General Public License Version 2 or later (the "GPL"), or
019: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020: * in which case the provisions of the GPL or the LGPL are applicable instead
021: * of those above. If you wish to allow use of your version of this file only
022: * under the terms of either the GPL or the LGPL, and not to allow others to
023: * use your version of this file under the terms of the MPL, indicate your
024: * decision by deleting the provisions above and replace them with the notice
025: * and other provisions required by the GPL or the LGPL. If you do not delete
026: * the provisions above, a recipient may use your version of this file under
027: * the terms of any one of the MPL, the GPL or the LGPL.
028: */
029:
030: package nextapp.echo2.webrender;
031:
032: import java.io.Serializable;
033: import java.util.HashMap;
034: import java.util.Map;
035:
036: /**
037: * A description of the client browser environment.
038: */
039: public class ClientProperties implements Serializable {
040:
041: // General CSS Quirks describing specific out-of-spec behaviors particular to certain browsers.
042:
043: /**
044: * A quirk flag indicating that CSS positioning values do not work correctly when either both
045: * "top" and "bottom" or "left" and "right" positions are set at the same time.
046: * <p>
047: * This quirk occurs with:
048: * <ul>
049: * <li>Internet Explorer 6 (Windows) [<em>Corrected in IE7 Beta 2 Refresh</em>]</li>
050: * </ul>
051: */
052: public static final String QUIRK_CSS_POSITIONING_ONE_SIDE_ONLY = "quirkCssPositioningOneSideOnly";
053:
054: /**
055: * A quirk flag indicating the only means of achieving 0 padding in table cells is to use 0px padding.
056: * <p>
057: * This quirk occurs with:
058: * <ul>
059: * <li>Internet Explorer 6 (Windows)</li>
060: * </ul>
061: */
062: public static final String QUIRK_CSS_BORDER_COLLAPSE_FOR_0_PADDING = "quirkCssBorderCollapseFor0Padding";
063:
064: /**
065: * A quirk flag indicating whether the client will incorrectly render CSS
066: * collapsed borders such that they reside entirely within the region
067: * of a component.
068: * <p>
069: * This quirk occurs with:
070: * <ul>
071: * <li>Internet Explorer 6 (Windows)</li>
072: * </ul>
073: * <p>
074: */
075: public static final String QUIRK_CSS_BORDER_COLLAPSE_INSIDE = "quirkCssBorderCollapseInside";
076:
077: /**
078: * A quirk flag indicating that the 'fixed' attribute should be used to
079: * for fixed-to-element background attachment.
080: * <p>
081: * This quirk occurs with:
082: * <ul>
083: * <li>Internet Explorer 6 (Windows) [<em>Corrected in IE7 Beta 2 Refresh</em>]</li>
084: * </ul>
085: */
086: public static final String QUIRK_CSS_BACKGROUND_ATTACHMENT_USE_FIXED = "quirkCssBackgroundAttachmentUseFixed";
087:
088: // Mozilla-specific Quirk Behaviors (behaviors that are more likely to be described as bugs)
089:
090: /**
091: * A quirk flag indicating whether the client has poor performance when
092: * attempting to remove large element hierarchies from a DOM. This quirk can
093: * be alleviated by removing the hierarchy in smaller chunks.
094: * <p>
095: * This quirk occurs with:
096: * <ul>
097: * <li>Mozilla (all platforms)</li>
098: * <li>Mozilla Firefox ((all platforms)</li>
099: * </ul>
100: */
101: public static final String QUIRK_MOZILLA_PERFORMANCE_LARGE_DOM_REMOVE = "quirkMozillaPerformanceLargeDomRemove";
102:
103: /**
104: * A quirk flag describing a Mozilla-specific behavior where the text
105: * contained within text input fields may be drawn outside of text
106: * input component due to the component having shifted its location
107: * on the page.
108: * <p>
109: * This quirk occurs with:
110: * <ul>
111: * <li>Mozilla (all platforms)</li>
112: * <li>Mozilla Firefox ((all platforms)</li>
113: * </ul>
114: */
115: public static final String QUIRK_MOZILLA_TEXT_INPUT_REPAINT = "quirkMozillaTextInputRepaint";
116:
117: /**
118: * A quirk flag describing an Opera-specific issue where the
119: * CSSStyleDeclaration.cssText property is unsupported.
120: * <p>
121: * This quirk occurs with:
122: * <ul>
123: * <li>Opera</li>
124: * </ul>
125: */
126: public static final String QUIRK_OPERA_NO_CSS_TEXT = "quirkOperaNoCssText";
127:
128: // Internet Explorer-specific Quirk Behaviors (behaviors that are more likely to be described as bugs)
129:
130: /**
131: * A quirk flag describing the issue of "windowed" select fields in Internet Explorer, which do not
132: * render correctly with regard to z-index value.
133: * See http://support.microsoft.com/kb/q177378/ for an explanation of the underlying issue.
134: * <p>
135: * This quirk occurs with:
136: * <ul>
137: * <li>Internet Explorer 6 (Windows) [<em>Corrected in IE7 Beta 2 Refresh</em>]</li>
138: * </ul>
139: */
140: public static final String QUIRK_IE_SELECT_Z_INDEX = "quirkIESelectZIndex";
141:
142: /**
143: * A quirk flag describing a behavior where a specific "null" option be
144: * must be added to a drop-down-list-style SELECT element in order to to
145: * render a "no items selected" state.
146: * <p>
147: * This quirk occurs with:
148: * <ul>
149: * <li>Mozilla (all platforms)</li>
150: * <li>Mozilla Firefox ((all platforms)</li>
151: * </ul>
152: */
153: public static final String QUIRK_SELECT_REQUIRES_NULL_OPTION = "quirkSelectRequiresNullOption";
154:
155: /**
156: * A quirk flag describing various issues with rendering content in TEXTAREA elements.
157: * This quirk includes IE problems with "newline obliteration", and Opera8 problems with
158: * simply ignoring textarea content with importNode().
159: * <p>
160: * This quirk occurs with:
161: * <ul>
162: * <li>Internet Explorer 6 (Windows)</li>
163: * <li>Opera 8 (Linux and Windows Tested, assuming all))</li>
164: * </ul>
165: */
166: public static final String QUIRK_TEXTAREA_CONTENT = "quirkTextareaContent";
167:
168: /**
169: * A quirk flag indicating the incorrect parsing of newlines in the content of a 'textarea'.
170: * <p>
171: * This quirk occurs with:
172: * <ul>
173: * <li>Internet Explorer 6 (Windows)</li>
174: * </ul>
175: *
176: * This a more specific version of <code>QUIRK_TEXTAREA_CONTENT</code>. Now that it has been
177: * discovered that Opera has similar issues, <code>QUIRK_TEXTAREA_CONTENT</code> should be used
178: * instead.
179: */
180: public static final String QUIRK_IE_TEXTAREA_NEWLINE_OBLITERATION = "quirkIETextareaNewlineObliteration";
181:
182: /**
183: * A quirk flag describing the curious repaint behavior found in Internet
184: * Explorer 6, where repaints may be excessively delayed.
185: * This quirky behavior is most visible when the DOM hierarchy is large and
186: * complex.
187: * The unlikely workaround for this quirky behavior is to "tickle" (adjust
188: * and then reset) the CSS width of an element, which will force an
189: * immediate repaint.
190: * <p>
191: * This quirk occurs with:
192: * <ul>
193: * <li>Internet Explorer 6 (Windows)</li>
194: * </ul>
195: */
196: public static final String QUIRK_IE_REPAINT = "quirkIERepaint";
197:
198: /**
199: * A quirk flag indicating incorrect calculation of 100% table widths when within a vertically scrolling
200: * region.
201: * <p>
202: * This quirk occurs with:
203: * <ul>
204: * <li>Internet Explorer 6 (Windows)</li>
205: * </ul>
206: */
207: public static final String QUIRK_IE_TABLE_PERCENT_WIDTH_SCROLLBAR_ERROR = "quirkIETablePercentWidthScrollbarError";
208:
209: /**
210: * A quirk flag indicating that listbox-style select fields cannot be reliably manipulated using the client DOM API.
211: * <p>
212: * This quirk occurs with:
213: * <ul>
214: * <li>Internet Explorer 6 (Windows)</li>
215: * </ul>
216: */
217: public static final String QUIRK_IE_SELECT_LIST_DOM_UPDATE = "quirkIESelectListDomUpdate";
218:
219: /**
220: * A quirk flag indicating that select fields with percentage widths are not reliably rendered.
221: * <p>
222: * This quirk occurs with:
223: * <ul>
224: * <li>Internet Explorer 6 (Windows)</li>
225: * </ul>
226: */
227: public static final String QUIRK_IE_SELECT_PERCENT_WIDTH = "quirkIESelectPercentWidth";
228:
229: // Internet Explorer-specific Proprietary Features
230: // These features are used only to compensate for IE6's lack of proper CSS support.
231:
232: /**
233: * A proprietary feature flag indicating support for IE-style CSS expressions.
234: * <p>
235: * This proprietary feature is provided by:
236: * <ul>
237: * <li>Internet Explorer 6 (Windows)</li>
238: * </ul>
239: */
240: public static final String PROPRIETARY_IE_CSS_EXPRESSIONS_SUPPORTED = "proprietaryIECssExpressionsSupported";
241:
242: /**
243: * A proprietary feature flag indicating that PNG alpha channel support is
244: * available only by using a 'filter'.
245: * <p>
246: * This proprietary feature is provided by:
247: * <ul>
248: * <li>Internet Explorer 6 (Windows) [<em>Not neccesary with IE7 Beta 2 Refresh</em>]</li>
249: * </ul>
250: */
251: public static final String PROPRIETARY_IE_PNG_ALPHA_FILTER_REQUIRED = "proprietaryIEPngAlphaFilterRequired";
252:
253: /**
254: * A proprietary feature flag indicating that CSS opacity support is
255: * available only by using a 'filter'.
256: * <p>
257: * This proprietary feature is provided by:
258: * <ul>
259: * <li>Internet Explorer 6 (Windows)</li>
260: * </ul>
261: */
262: public static final String PROPRIETARY_IE_OPACITY_FILTER_REQUIRED = "proprietaryIEOpacityFilterRequired";
263:
264: /**
265: * A proprietary feature flag indicating that 'mouseenter' and
266: * 'mouseleave' events are supported.
267: * <p>
268: * This proprietary feature is provided by:
269: * <ul>
270: * <li>Internet Explorer 6 (Windows)</li>
271: * </ul>
272: */
273: public static final String PROPRIETARY_EVENT_MOUSE_ENTER_LEAVE_SUPPORTED = "proprietaryEventMouseEnterLeaveSupported";
274:
275: /**
276: * An unsupported feature flag indicating that CSS opacity effects are
277: * not supported.
278: * <p>
279: * This issue occurs with:
280: * <ul>
281: * <li>Opera</li>
282: * </ul>
283: */
284: public static final String NOT_SUPPORTED_CSS_OPACITY = "notSupportedCssOpacity";
285:
286: /**
287: * An unsupported feature flag indicating that manipulating CSS stylesheets is not
288: * supported by the browser (using add/insert rule).
289: * <p>
290: * This issue occurs with:
291: * <ul>
292: * <li>Safari (verified)</li>
293: * <li>KHTML (assumed)</li>
294: * </ul>
295: */
296: public static final String NOT_SUPPORTED_CSS_MANIPULATION = "notSupportedCssManipulation";
297:
298: // General Browser Properties
299:
300: /**
301: * Width of the screen in pixels (integer).
302: */
303: public static final String SCREEN_WIDTH = "screenWidth";
304:
305: /**
306: * Height of the screen in pixels (integer).
307: */
308: public static final String SCREEN_HEIGHT = "screenHeight";
309:
310: /**
311: * Color depth of the screen in bits (integer).
312: */
313: public static final String SCREEN_COLOR_DEPTH = "screenColorDepth";
314:
315: /**
316: * Flag indicating that the browser is a derivative of the Mozilla
317: * 1.0-1.8+ browser platform.
318: */
319: public static final String BROWSER_MOZILLA = "browserMozilla";
320:
321: /**
322: * Flag indicating that the browser is a derivative of the Mozilla
323: * Firefox 1.0+ browser platform.
324: */
325: public static final String BROWSER_MOZILLA_FIREFOX = "browserMozillaFirefox";
326:
327: /**
328: * Flag indicating that the browser is a derivative of the Microsoft
329: * Internet Explorer browser platform.
330: */
331: public static final String BROWSER_INTERNET_EXPLORER = "browserInternetExplorer";
332:
333: /**
334: * Flag indicating that the browser is a derivative of the KDE Konqueror
335: * browser platform.
336: */
337: public static final String BROWSER_KONQUEROR = "browserKonqueror";
338:
339: /**
340: * Flag indicating that the browser is a derivative of the Apple Safari
341: * browser platform.
342: */
343: public static final String BROWSER_SAFARI = "browserSafari";
344:
345: /**
346: * Flag indicating that the browser is a derivative of the Opera
347: * browser platform.
348: */
349: public static final String BROWSER_OPERA = "browserOpera";
350:
351: /**
352: * The major version number of the browser.
353: */
354: public static final String BROWSER_VERSION_MAJOR = "browserVersionMajor";
355:
356: /**
357: * The minor version number of the browser.
358: */
359: public static final String BROWSER_VERSION_MINOR = "browserVersionMinor";
360:
361: /**
362: * The <code>Locale</code> of the client, derived from the language property.
363: */
364: public static final String LOCALES = "locales";
365:
366: /**
367: * The client's navigator.appName property.
368: */
369: public static final String NAVIGATOR_APP_NAME = "navigatorAppName";
370:
371: /**
372: * The client's navigator.appVersion property.
373: */
374: public static final String NAVIGATOR_APP_VERSION = "navigatorAppVersion";
375:
376: /**
377: * The client's navigator.appCodeName property.
378: */
379: public static final String NAVIGATOR_APP_CODE_NAME = "navigatorAppCodeName";
380:
381: /**
382: * The client's navigator.cookieEnabled property.
383: */
384: public static final String NAVIGATOR_COOKIE_ENABLED = "navigatorCookieEnabled";
385:
386: /**
387: * The client's navigator.javaEnabled property.
388: */
389: public static final String NAVIGATOR_JAVA_ENABLED = "navigatorJavaEnabled";
390:
391: /**
392: * The client's navigator.language (or navigator.userLanguage) property.
393: */
394: public static final String NAVIGATOR_LANGUAGE = "navigatorLanguage";
395:
396: /**
397: * The client's navigator.platform property.
398: */
399: public static final String NAVIGATOR_PLATFORM = "navigatorPlatform";
400:
401: /**
402: * The client's navigator.userAgent property.
403: */
404: public static final String NAVIGATOR_USER_AGENT = "navigatorUserAgent";
405:
406: /**
407: * The client host. Note this is the original host address used when the
408: * <code>ClientProperties</code> object was created, which is not
409: * necessarily the same as that making the current HTTP request.
410: */
411: public static final String REMOTE_HOST = "remoteHost";
412:
413: /**
414: * The client's time offset from UTC in minutes.
415: */
416: public static final String UTC_OFFSET = "utcOffset";
417:
418: private Map data = new HashMap();
419:
420: /**
421: * Creates a new <code>ClientProperties</code> object.
422: */
423: public ClientProperties() {
424: super ();
425: }
426:
427: /**
428: * Returns the value of the specified property as an <code>Object</code>.
429: *
430: * @param propertyName the property name
431: * @return the property value
432: */
433: public Object get(String propertyName) {
434: return data.get(propertyName);
435: }
436:
437: /**
438: * Returns a <code>boolean</code> property.
439: * If the property is not set, <code>false</code> is returned.
440: *
441: * @param propertyName the property name
442: * @return the property value
443: */
444: public boolean getBoolean(String propertyName) {
445: Boolean value = (Boolean) data.get(propertyName);
446: return value == null ? false : value.booleanValue();
447: }
448:
449: /**
450: * Returns a <code>int</code> property.
451: * If the property is not set, <code>nullValue</code> is returned.
452: *
453: * @param propertyName the property name
454: * @param nullValue the returned value when the property is not set
455: * @return the property value
456: */
457: public int getInt(String propertyName, int nullValue) {
458: Integer value = (Integer) data.get(propertyName);
459: return value == null ? nullValue : value.intValue();
460: }
461:
462: /**
463: * Returns a <code>String</code> property.
464: * If the property is not set, <code>null</code> is returned.
465: *
466: * @param propertyName the property name
467: * @return the property value
468: */
469: public String getString(String propertyName) {
470: Object value = data.get(propertyName);
471: return value == null ? "" : value.toString();
472: }
473:
474: /**
475: * Returns an array of all property names which are set.
476: *
477: * @return the array
478: */
479: public String[] getPropertyNames() {
480: return (String[]) data.keySet()
481: .toArray(new String[data.size()]);
482: }
483:
484: /**
485: * Sets the value of the specified property.
486: *
487: * @param propertyName the property name
488: * @param propertyValue the property value
489: */
490: public void setProperty(String propertyName, Object propertyValue) {
491: data.put(propertyName, propertyValue);
492: }
493:
494: /**
495: * @see java.lang.Object#toString()
496: */
497: public String toString() {
498: return "ClientProperties: " + data.toString();
499: }
500: }
|