All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.codename1.ui.html.HTMLComponent Maven / Gradle / Ivy

There is a newer version: 7.0.167
Show newest version
/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores
 * CA 94065 USA or visit www.oracle.com if you need additional information or
 * have any questions.
 */
package com.codename1.ui.html;

import com.codename1.ui.Button;
import com.codename1.ui.CheckBox;
import com.codename1.ui.ComboBox;
import com.codename1.ui.Command;
import com.codename1.ui.Component;
import com.codename1.ui.Container;
import com.codename1.ui.Display;
import com.codename1.ui.Font;
import com.codename1.ui.Form;
import com.codename1.ui.Graphics;
import com.codename1.ui.Label;
import com.codename1.ui.List;
import com.codename1.ui.RadioButton;
import com.codename1.ui.TextArea;
import com.codename1.ui.TextField;
import com.codename1.ui.animations.Motion;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.geom.Rectangle;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.layouts.FlowLayout;
import com.codename1.ui.plaf.Border;
import com.codename1.ui.plaf.Style;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.table.Table;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

/**
 * HTMLComponent is a Codename One Component that renders HTML documents that conform to the XHTML Mobile Profile 1.0
 *
 * @deprecated this component includes some customizability advantages but its probably better for 99% of the use
 * cases to use the WebBrowser Component from the Components package. That component works with the native
 * browser when applicable which is a far superior approach.
 * @author Ofir Leitner
 */
public class HTMLComponent extends Container implements ActionListener,IOCallback {
    private boolean supressExceptions;
//    long startTime;
//    String msg="";
//    long textTime;

    // Internal "tweakable" constants

    /**
     * If true a full screen width will be assumed, this helps to make less internal components as text is aggregated to long labels
     * If false, then the width is flexible, but every word will be rendered as a separate label.
     * Note that if false, RTL texts will display in
     */
    static final boolean FIXED_WIDTH = false;

    /**
     * A constant that can be used to obfuscate out HTMLInputFormat if unnecessary
     */
    static final boolean SUPPORT_INPUT_FORMAT = true;

    /**
     * A constant that can be used to obfuscate out all CSS related code if unnecessary
     */
    static final boolean SUPPORT_CSS = true;

    /**
     * If true, when a page is requested, the previous page is immediately removed, thus helping conserve memory (Since only 1 page is held in memory simultanously)
     * In next releases a better and external control over this will be provided.
     */
    private static final boolean CLEAN_ON_PAGE_REQUEST = true; //false;

    /**
     * If true, checks will be made on each character in the text to see if it is CJK (Chinese, Japanese, Korean)
     * If so each character will be considered as an entire word (for line wrapping puposes) as required in CJK.
     * Since the tests require multiple unicode ranges check, this can be set to false avoiding these tests if the app doesn't use CJK
     */
    private static final boolean CJK_SUPPORT = true;

    /**
     * A constant denoting whether to process only XHTML-MP1 (and WCSS), or some other tags/properties from HTML4/CSS2
     */
    static final boolean PROCESS_HTML_MP1_ONLY = false;

    /**
     * If true, then table cells will be preset with a size according to their preferred size, before the table begins calculating needed sizes
     * This also requires loading all images in table cells prior to page display (Unlike the normal way in which they can be completed afterwards)
     * This is needed due to some complexity when calculating sizes of tables with complex containers as cells, and especially with nested tables
     */
    //static final boolean TABLES_LOCK_SIZE = true; // The issue that required this patch was solved in the table package

    // Indentation for various tags
    private static final int INDENT_BLOCKQUOTE = 20;
    private static final int INDENT_DD = 20;
    private static int INDENT_OL = -1;//Font.getDefaultFont().stringWidth("8888. "); //Ordered list
    private static int INDENT_UL = -1;//Font.getDefaultFont().charWidth('W'); //Unordered list

    // The minimum number of visible items of a multiple combobox (Unless it has less)
    private static final int MIN_MULTI_COMBOBOX_ITEMS = 4;
    private static final int MAX_MULTI_COMBOBOX_ITEMS = 6;

    /**
     * The default size (in characters) of an input textfield
     */
    private static final int DEFAULT_TEXTFIELD_SIZE = 12;

    /**
     * The default oolumns (in characters) of a textarea
     */
    private static final int DEFAULT_TEXTAREA_COLS = 20;

    /**
     * The default rows (in characters) of a textarea
     */
    private static final int DEFAULT_TEXTAREA_ROWS = 2;

    /**
     * Indicates a Justify alignment. Text justification is enabled only in FIXED_WIDTH mode
     */
    static final int JUSTIFY = 5;

    /**
     * The thickness of a line drawn by the HR tag
     */
    private static final int HR_THICKNESS = 3;

    /**
     * The time it takes a marquee to move across the screen (See -wap-marquee in CSS)
     */
    private static final int MARQUEE_DELAY = 6000;

    /**
     * When this is set to true, only exact fonts will be matched, i.e. if the font matching algorithm needs an arial.12.bold.italic - it will not "settle" for just bold or italic or a different size
     * Default is false
     */
    private static final boolean MATCH_EXACT_FONTS_ONLY = false;

    /**
     * When this is set to true only bitmap fonts will be used for matching (and not system fonts)
     * Default is true, and false has not been tested thoroughly 
     */
    private static final boolean MATCH_BITMAP_FONTS_ONLY = true;

    /**
     * When this is set to true, only fonts of the same family will be matched. i.e. if we're looking for a bigger font than arial.10, and we have timesnewroman.12 it will not be taken as a matching font
     * Default is true
     */
    private static final boolean MATCH_SAME_FONT_FAMILY_ONLY = true;

    /**
     * The default font to use
     */
    private static HTMLFont DEFAULT_FONT = null;//new HTMLFont(null,Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM));

    /**
     * The color given to visited links
     */
    private static final int COLOR_VISITED_LINKS = 0x990099;

    /**
     * A hashtable containing all defined HTMLFont objects
     */
    static Hashtable fonts = new Hashtable();

    // Constants for the various possible input types (i.e. allowed values of the INPUT tag)
     private static final int INPUT_CHECKBOX = 0;
     private static final int INPUT_HIDDEN = 1;
     private static final int INPUT_PASSWORD = 2;
     private static final int INPUT_RADIO = 3;
     private static final int INPUT_RESET = 4;
     private static final int INPUT_SUBMIT = 5;
     private static final int INPUT_TEXT = 6;
     private static final int INPUT_IMAGE = 7; // image is not officially supported in XHTML-MP 1.0 but we support it
     private static final int INPUT_BUTTON = 8; //button is not supported in XHTML-MP 1.0
     //private static final int INPUT_FILE = 9; //file upload is not supported in XHTML-MP 1.0
     private static final int INPUT_EMAIL = 9;
     
    /**
     * Defines the possible values for the type attribute in the input tag, ordered according to the INPUT_* constants
     */
    private static String[] INPUT_TYPE_STRINGS = {
            "checkbox","hidden","password","radio","reset",
            "submit","text","image", "button", "email"
    };

    /**
     * Vector holding the possible input type strings.
     */
    private static Vector INPUT_TYPES = new Vector();

    
    static final String CLIENT_PROPERTY_QUOTE = "quote"; // Client property added to quote elements to enable changing them later on with CSS
    static final String CLIENT_PROPERTY_IMG_BORDER = "imgBorder";

     // Ordered list types

     /**
      * Ordered list type legal identifiers as can be defined in the ATTR_TYPE of the OL_TAG
      */
     private static final char[] ORDERED_LIST_TYPE_IDENTIFIERS = {'1','A','a','I','i'};

     /**
      * Inidcates whether this component should load CSS files and consider STYLE tag and attributes when available..
      * Note that CSS requires to create significantlly more containers, as almost every tag needs to be in its own container
      * in order to manipulate style attributes like bgcolor, border etc. This is why the developer can disable CSS.
      * Currently this is a private variable, once CSS is actually available this will be exposed via public getter/setter.
      * Also there's no point setting this to true in this release as it will not lead to actual CSS, but just prepare containers for it.
      */
    boolean loadCSS = SUPPORT_CSS;

    /**
     * If true than all active controls will be added event listeners and dispatch them via HTMLCallback
     * Default is false in order not to add overhead when this feature is not needed
     */
    boolean eventsEnabled = false;

    HTMLParser parser;
    
    int contCount=0; // debug for CSS
     /**
     * Style sheets embedded directly into the style tag (not the style attribute)
     */
    private Vector embeddedCSS;

    /**
     * External style sheets referenced from LINK tags
     */
    private Vector externalCSS;


    /**
     * The default background color of an HTML document, can be changed with the BGCOLOR attribute in the BODY tag or via CSS
     */
    static final int DEFAULT_BGCOLOR = 0xffffff;

    /**
     * The default color of text in HTML documents, can be changed with the TEXT attribute in the BODY tag or via CSS
     */
    static final int DEFAULT_TEXT_COLOR = 0;

    /**
     * The default color of links in HTML documents, can be changed with the LINK attribute in the BODY tag or via CSS
     */
    static private final int DEFAULT_LINK_COLOR = 0x0000ff;


    // Document colors
    private int bgColor=DEFAULT_BGCOLOR;
    private int textColor=DEFAULT_TEXT_COLOR;
    private int linkColor=DEFAULT_LINK_COLOR;

    // Refrences to helper classes and delegates
    private DocumentRequestHandler handler; // The HTMLComponent's request handler
    private RedirectThread redirectThread; // A refrence to a redirection thread if exists
    private ResourceThreadQueue threadQueue; // A reference to the ResourceThreadQueue that handles asynchronous image download
    private HTMLCallback htmlCallback;
    private HTMLEventsListener eventsListener;

    // Page info and status
    private DocumentInfo docInfo; // The DocumentInfo object associated with this document
    private HTMLElement document; // The page DOM representation
    private String pageURL; // The current page's URL
    private int pageStatus=HTMLCallback.STATUS_NONE; // The page's status (See HTMLCallback)
    private boolean pageError; // true if there was an error during the page building process
    private String title; // The page's title (as obtained from the TITLE tag in the HEAD tag)
    private int displayWidth; // Used to store the display width to detect width changes later on.
    private boolean cancelled; // true if the page was cancelled (Signals all processing to stop)
    private boolean cancelledCaught; //true if the cancel signal was already caught (Used to avoid multiple cancel handling)
    boolean showImages=true; //true to download image, false otherwise
    private Style pageStyle; // The page's user defined style
    private String pageUIID; // The page's user defined UIID

    // Links related
    private Hashtable accessKeys = new Hashtable();// A hastable containing all the access keys in this document and their respective links
    private Hashtable anchors;// A hashtable containing all the anchors of this document
    private Hashtable inputFields; // A hashtable containing all the input fields in the page. Used for FOR labels
    Component firstFocusable; // The first focusable link on the page

    //Font
    HTMLFont defaultFont = DEFAULT_FONT; // The default font for all pages

    // this variable is only useful with the properties mostly for the purpose of the resource editor GUI builder
    private String htmlBody;


    // The following variables are used when building the component from the document.
    // After the component construction they are not used (Basically they can all be considered as "temporary" variables,
    // but due to the recursive nature of the document building operation, they are defined as members)

    //Containers

    /**
     * The main container is the top-level container to which other containers are added when building the page.
     * After the page was built the main container is added to the HTMLComponent.
     * We do not build directly on the HTMLComponent to allow the building process to be performed not in the EDT thread.
     */
    private Container mainContainer;

    /**
     * curContianer is the current container we are adding components to. AT the start it is the main container.
     * Later on it can be a certain table cell or a fieldset.
     */
    private Container curContainer;

    private boolean autoFocus = true; // Determines whether to auto-focus on the first link after page load

    /**
     * curLine is the basic container to which components are added in the building process.
     * Components are added to it horizontally and when there no more space left (or a newline is needed) - it is added to the curContainer
     */
    private Container curLine;

    // Layouting - NOTE: In FIXED_WIDTH mode this component assumes the full width of the screen and performs text wrapping due to a bug in the combination of FlowLayout inside BoxLayout. In non fixed width mode the variables x & width are not used.
    private int x; // Holds the horizontal position in the curLine container
    private int width; // Holds the width available to each line
    private int leftIndent; // Holds the current left margin (can be changed by tags)
    private boolean lastWasEmpty; // true if the last line was empty, used to prevent unneeded multiple row spacing

    // Font
    private HTMLFont font; // Holds the current used font (starts with defaultFont and changes according to various tags and attributes)

    // Links
    private String link; // The current link address (so when a text is processed, we know to attribute it to this link)
    private HTMLLink mainLink; // The "main" link. If a link spans over 2 or more lines, the first segment is considered the "main" link and is responsible for highlighting all segments when focused.
    private char accesskey='\0'; // The current accesskey for a link
    private String anchor; // The current page anchor
    private boolean linkVisited; // True if the current link address was visited

    // Forms
    private HTMLForm curForm; // The current HTMLForm to which input fields should be added
    private TextArea curTextArea; // The current TextArea
    private List curComboBox; // The current ComboBox
    private boolean optionTag; // true if an option tag is open
    private boolean optionSelected; //true if the current option is marked as selected (i.e. the default selection)
    private String optionValue; // The current option value
    private Hashtable textfieldsToForms; // A hashtable that maps all input fields to their corresponding forms

    // Lists
    private int ulLevel; //Unordered list level (Used to display the right bullet)
    private int olIndex; //Index of the current item in the list
    private Vector olUpperLevelIndex;// = new Vector(); //Used to save the index when nesting
    private int listType; // The type of the current list
    private int listIndent; // Holds the current list margin

    // Tables
    private Vector tables;// A vector used for nesting, when a table contains a table ,the current one is "pushed" into the vector, to be "popped" later when the nested table processing ends.
    private Vector tableCells;// A vector used for nesting of table cells
    HTMLTableModel curTable; // The model of the currently collected table

    // Misc. tags
    private Vector fieldsets; // A vector used to support FIELDSET tag nesting
    private int preTagCount=0; // A counter used to support PRE tag nesting
    private int quoteTagCount=0; // A counter used to support QUOTE tag nesting
    private String labelForID; // Collects 




© 2015 - 2025 Weber Informatics LLC | Privacy Policy