Ejemplo n.º 1
0
  /* (non-Javadoc)
   * @see de.enough.polish.browser.TagHandler#handleTag(de.enough.polish.ui.Container, de.enough.polish.xml.PullParser, java.lang.String, boolean, de.enough.polish.util.HashMap, de.enough.polish.ui.Style)
   */
  public boolean handleTag(
      Container parentItem,
      SimplePullParser parser,
      String tagName,
      boolean opening,
      HashMap attributeMap,
      Style style) {
    // #debug
    System.out.println((opening ? "<" : "</") + tagName + ">");
    tagName = tagName.toLowerCase();
    if (TAG_DIV.equals(tagName) || TAG_SPAN.equals(tagName)) {
      if (opening) {
        String itemStyleName = (String) attributeMap.get("textclass");
        Style itemStyle = (itemStyleName == null ? null : StyleSheet.getStyle(itemStyleName));
        if (itemStyle != null) {
          this.textStyle = itemStyle;
        }
        if (this.isDivOrSpanOpened == null) {
          this.isDivOrSpanOpened = new BooleanStack();
        }
        //				System.out.println("opening <div> with style " + (style == null ? null : style.name));
        if (style != null) {
          this.browser.openContainer(style);
        }
        this.isDivOrSpanOpened.push(style != null);
        //				this.browser.openContainer( style );
        //				this.isDivOrSpanOpened.push( true );
      } else {
        this.textStyle = null;
        // System.out.println("closing <div> with container=" + this.isDivOrSpanOpened.peek());
        if (this.isDivOrSpanOpened.pop()) {
          Container container = this.browser.closeContainer();
          if (UiAccess.cast(container) instanceof TableItem) {
            this.currentTable = (TableItem) UiAccess.cast(container);
          }
        }
        //				Style divStyle = container.getStyle();
        //					if (divStyle != null) {
        //					Object[] items = container.getInternalArray();
        //					for (int i = 0; i < items.length; i++)
        //					{
        //						Item item = (Item) items[i];
        //						if (item == null) {
        //							break;
        //						}
        //						item.setStyle( divStyle );
        //					}
        //				}
      }
    } else if (TAG_SELECT.equals(tagName)) {
      if (opening) {
        if (this.currentSelect != null) {
          // #debug error
          System.out.println(
              "Error in HTML-Code: You cannot open a <select>-tag inside another <select>-tag.");

          ChoiceGroup choiceGroup = this.currentSelect.getChoiceGroup();
          add(choiceGroup);
          if (this.currentForm == null) {
            // #debug error
            System.out.println("Error in HTML-Code: no <form> for <select> element found!");
          } else {
            this.currentForm.addItem(choiceGroup);
          }
          this.currentSelect = null;
        }

        String name = parser.getAttributeValue(ATTR_NAME);
        String sizeStr = parser.getAttributeValue(ATTR_SIZE);
        int size;

        try {
          size = Integer.parseInt(sizeStr);
        } catch (NumberFormatException e) {
          size = -1;
        }

        boolean isMultiple = parser.getAttributeValue(ATTR_MULTIPLE) != null;
        this.currentSelect = new HtmlSelect(name, size, isMultiple, style);
      } else { // tag is closed
        if (this.currentSelect != null) {
          ChoiceGroup choiceGroup = this.currentSelect.getChoiceGroup();
          add(choiceGroup);
          if (this.currentForm == null) {
            // #debug error
            System.out.println("Error in HTML-Code: no <form> for <select> element found!");
          } else {
            this.currentForm.addItem(choiceGroup);
          }
          this.currentSelect = null;
        }
        // #mdebug error
        else {
          // #debug error
          System.out.println(
              "Error in HTML-Code. You cannot close a <select>-tag without opening one.");
        }
        // #enddebug
      }
      return true;
    } else if (TAG_OPTION.equals(tagName)) {
      if (this.currentSelect != null && opening) {
        // TODO: handle "selected" attribute.
        String value = parser.getAttributeValue(ATTR_VALUE);
        String selected = parser.getAttributeValue("selected");
        parser.next();
        String name = handleText(parser.getText());

        if (value == null) {
          value = name;
        }

        this.currentSelect.addOption(name, value, selected != null, style);
      }
      return true;
    } else if (TAG_A.equals(tagName)) {
      if (opening) {
        this.anchorHref = (String) attributeMap.get(ATTR_HREF);
        // #if polish.debug.error
        if (this.anchorHref == null) {
          // #debug error
          System.out.println(
              "Unable to handle anchor tag <a> without "
                  + ATTR_HREF
                  + " attribute: "
                  + attributeMap);
        }
        // #endif
        this.browser.openContainer(style);
        if (style == null) {
          Container container = this.browser.getCurrentContainer();
          // #style browserLink
          UiAccess.setStyle(container);
        }
      } else {
        // apply link to last item(s):
        Container container = this.browser.removeCurrentContainer();
        Style contStyle = container.getStyle();
        Item linkItem;
        if (container.size() == 0) {
          linkItem = new StringItem(null, null);
        } else if (container.size() == 1) {
          linkItem = container.get(0);
        } else {
          // check if all elements are StringItems - then we should combine them:
          boolean allItemsAreStringItems = true;
          StringBuffer text = new StringBuffer();
          for (int i = 0; i < container.size(); i++) {
            Item item = container.get(i);
            if (!(item instanceof StringItem)) {
              allItemsAreStringItems = false;
              break;
            } else {
              if (text.length() > 0) {
                text.append(' ');
              }
              text.append(((StringItem) item).getText());
            }
          }
          if (allItemsAreStringItems) {
            linkItem = new StringItem(null, text.toString());
          } else {
            linkItem = container;
          }
        }
        //				System.out.println("closing <a>: container.size()=" + container.size() + ", linkItem="
        // + linkItem + ", style=" + (contStyle != null ? contStyle.name : "<no style>") );
        if (this.anchorHref != null) {
          if (contStyle != null) {
            linkItem.setStyle(contStyle);
          } else if (linkItem.getStyle() == null) {
            // #style browserLink
            UiAccess.setStyle(linkItem);
          }
          linkItem.setDefaultCommand(CMD_LINK);
          linkItem.setItemCommandListener(this);
          linkItem.setAttribute(ATTR_HREF, this.anchorHref);
          addCommands(TAG_A, linkItem);
          add(linkItem);
        }

        // this.browser.closeContainer();
      }
    }

    if (opening) {
      //			if (TAG_A.equals(tagName))
      //			{
      //				String href = (String) attributeMap.get(ATTR_HREF);
      //				parser.next();
      //				Item linkItem;
      //				if (href != null)
      //				{
      //					String anchorText = handleText(parser.getText());
      //					// hack for image links:
      //					if ("".equals(anchorText) && TAG_IMG.equals(parser.getName())) {
      //						// this is an image link:
      //						attributeMap.clear();
      //						for (int i = 0; i < parser.getAttributeCount(); i++)
      //						{
      //							String attributeName = parser.getAttributeName(i);
      //							String attributeValue = parser.getAttributeValue(i);
      //							attributeMap.put(attributeName, attributeValue);
      //						}
      //						String src = (String) attributeMap.get("src");
      //						String url = this.browser.makeAbsoluteURL(src);
      //						Image image = this.browser.loadImage(url);
      //						//#style browserLink
      //						linkItem = new ImageItem(null, image, 0, (String) attributeMap.get("alt") );
      //						//this.browser.loadImageLater( url, (ImageItem) linkItem );
      //
      //					} else {
      //						//#style browserLink
      //						linkItem = new StringItem(null, anchorText);
      //					}
      //					linkItem.setDefaultCommand(CMD_LINK);
      //					linkItem.setItemCommandListener( this );
      //					linkItem.setAttribute(ATTR_HREF, href );
      //					addCommands(TAG_A, linkItem);
      //				}
      //				else
      //				{
      //					//#style browserText
      //					linkItem = new StringItem(null, handleText(parser.getText()));
      //				}
      //				if (style != null) {
      //					linkItem.setStyle(style);
      //				}
      //				add(linkItem);
      //				return true;
      //			}
      //			else
      if (TAG_BR.equals(tagName)) {
        addLineBreak();
        return true;
      } else if (TAG_P.equals(tagName)) {
        addLineBreak();
        if (opening) {
          this.textStyle = style;
        }
        return true;
      } else if (TAG_IMG.equals(tagName)) {
        String src = (String) attributeMap.get("src");
        String url = this.browser.makeAbsoluteURL(src);
        Dimension width = parseSizeValue((String) attributeMap.get("width"));
        Dimension height = parseSizeValue((String) attributeMap.get("height"));
        Style imageStyle = new Style();
        imageStyle.addAttribute(58 /* "min-width" */, width);
        imageStyle.addAttribute(144 /* "min-height" */, height);
        ImageItem item;

        if (width != null || height != null) {
          item = new ScaledImageItem(null, null, width, height, Item.LAYOUT_DEFAULT, "");
        } else {
          item = new ImageItem(null, null, Item.LAYOUT_DEFAULT, "");
        }

        if (imageStyle != null) {
          item.setStyle(imageStyle);
        }

        this.browser.loadImageLater(item, url);
        add(item);
        return true;
      } else if (TAG_TITLE.equals(tagName)) {
        // Hack to read title.
        parser.next();
        String name = handleText(parser.getText());
        Screen myScreen = this.browser.getScreen();
        if (name != null && myScreen != null) {
          myScreen.setTitle(name);
        }
        return true;
      } else if (TAG_STYLE.equals(tagName)) {
        // Hack to read style content.
        parser.next();
        String cssCode = parser.getText();
        try {
          CssInterpreter reader = new CssInterpreter(cssCode, this.browser);
          this.browser.setCssStyles(reader.getAllStyles());
        } catch (Exception e) {
          // #debug error
          System.out.println("Unable to parse CSS" + e);
        }
        // parser.next();
        return true;
      } else if (TAG_META.equals(tagName)) {
        String httpEquiv = (String) attributeMap.get("http-equiv");
        if (httpEquiv != null && TextUtil.equalsIgnoreCase("refresh", httpEquiv)) {
          String content = (String) attributeMap.get("content");
          if (content != null) {
            int semicolonPos = content.indexOf(';');
            int waitTime = 0;
            String url = content;
            if (semicolonPos != -1) {
              try {
                waitTime = Integer.parseInt(content.substring(0, semicolonPos));
                url = content.substring(semicolonPos + 1);
              } catch (Exception e) {
                if (semicolonPos == 0) {
                  url = content.substring(1);
                }
              }
            }
            int equalsPos = url.indexOf('=');
            if (equalsPos != -1) {
              url = url.substring(equalsPos + 1).trim();
            }
            if (url.indexOf(':') == -1) {
              // assuming resource protocol:
              if (url.charAt(0) != '/') {
                url = "resource://" + url;
              } else {
                url = "resource:/" + url;
              }
            }
            if (waitTime > 0) {
              (new RedirectThread(this.browser, waitTime * 1000L, url)).start();
            } else {
              // consume rest of document:
              while (parser.next() != SimplePullParser.END_DOCUMENT) {
                // read document..
              }
              this.browser.go(url);
            }
            return true;
          }
        }
        return false;
      }
      // #if polish.Browser.supportTextInput != false
      else if (TAG_TEXT_AREA.equals(tagName)) {
        parser.next();
        String value = handleText(parser.getText());
        int maxCharNumber = 500;
        String cols = (String) attributeMap.get("cols");
        String rows = (String) attributeMap.get("rows");
        if (cols != null && rows != null) {
          try {
            maxCharNumber = Integer.parseInt(cols) * Integer.parseInt(rows);
          } catch (Exception e) {
            // #debug error
            System.out.println(
                "Unable to parse textarea cols or rows attribute: cols=" + cols + ", rows=" + rows);
          }
        }
        // #style browserInput
        TextField textField = new TextField(null, value, maxCharNumber, TextField.ANY);
        if (style != null) {
          textField.setStyle(style);
        }
        add(textField);
        if (this.currentForm != null) {
          this.currentForm.addItem(textField);
          textField.setAttribute(ATTR_FORM, this.currentForm);
          String name = (String) attributeMap.get(INPUT_NAME);
          if (value == null) {
            value = name;
          }
          if (name != null) {
            textField.setAttribute(ATTR_NAME, name);
            textField.setAttribute(ATTR_VALUE, value);
          }
        }
        return true;
      }
      // #endif
      else if (TAG_BUTTON.equals(tagName) && this.currentForm != null) {
        String name = (String) attributeMap.get(INPUT_NAME);
        String value = (String) attributeMap.get(INPUT_VALUE);

        if (value == null) {
          value = name;
        }

        // #style browserLink
        StringItem buttonItem = new StringItem(null, value);
        if (style != null) {
          buttonItem.setStyle(style);
        }
        buttonItem.setDefaultCommand(CMD_SUBMIT);
        buttonItem.setItemCommandListener(this);
        addCommands(TAG_INPUT, INPUT_TYPE, INPUTTYPE_SUBMIT, buttonItem);
        add(buttonItem);

        this.currentForm.addItem(buttonItem);
        buttonItem.setAttribute(ATTR_FORM, this.currentForm);
        buttonItem.setAttribute(ATTR_TYPE, "submit");

        if (name != null) {
          buttonItem.setAttribute(ATTR_NAME, name);
          buttonItem.setAttribute(ATTR_VALUE, value);
        }
      } else if (TAG_INPUT.equals(tagName)) {
        if (this.currentForm != null) {
          String type = (String) attributeMap.get(INPUT_TYPE);
          String name = (String) attributeMap.get(INPUT_NAME);
          String value = (String) attributeMap.get(INPUT_VALUE);
          if (type != null) {
            type = type.toLowerCase();
          }

          if (this.formListener != null && name != null) {
            value =
                this.formListener.verifyInitialFormValue(this.currentForm.getAction(), name, value);
          }
          // #if polish.Browser.supportTextInput != false
          if (INPUTTYPE_TEXT.equals(type)
              || INPUTTYPE_PASSWORD.equals(type)
              || INPUTTYPE_NUMERIC.equals(type)) {
            int constraints;
            if (INPUTTYPE_NUMERIC.equals(type)) {
              constraints = TextField.NUMERIC;
            } else {
              constraints = INPUTTYPE_TEXT.equals(type) ? TextField.ANY : TextField.PASSWORD;
            }
            // #style browserInput
            TextField textField =
                new TextField((String) attributeMap.get("label"), value, 100, constraints);
            if (style != null) {
              textField.setStyle(style);
            }
            add(textField);

            this.currentForm.addItem(textField);
            textField.setAttribute(ATTR_FORM, this.currentForm);

            if (name != null) {
              textField.setAttribute(ATTR_NAME, name);
              if (value == null) {
                value = "";
              }
              textField.setAttribute(ATTR_VALUE, value);
            }
          } else
          // #endif
          if (INPUTTYPE_SUBMIT.equals(type)) {

            if (value == null) {
              value = name;
            }

            // #style browserLink
            StringItem buttonItem = new StringItem((String) attributeMap.get("label"), value);
            if (style != null) {
              buttonItem.setStyle(style);
            }
            buttonItem.setDefaultCommand(CMD_SUBMIT);
            buttonItem.setItemCommandListener(this);
            addCommands(TAG_INPUT, INPUT_TYPE, INPUTTYPE_SUBMIT, buttonItem);
            add(buttonItem);

            this.currentForm.addItem(buttonItem);
            buttonItem.setAttribute(ATTR_FORM, this.currentForm);
            buttonItem.setAttribute(ATTR_TYPE, "submit");

            if (name != null) {
              buttonItem.setAttribute(ATTR_NAME, name);
              buttonItem.setAttribute(ATTR_VALUE, value);
            }
          } else if (INPUTTYPE_HIDDEN.equals(type)) {
            this.currentForm.addHiddenElement(name, value);
          } else if (INPUTTYPE_CHECKBOX.equals(type) || INPUTTYPE_RADIO.equals(type)) {
            boolean isCheckBox = INPUTTYPE_CHECKBOX.equals(type);
            parser.next();
            String label = parser.getText().trim();
            int labelLength = label.length();
            if (labelLength == 0) {
              parser.next();
              label = parser.getText().trim();
              labelLength = label.length();
            }
            if ((labelLength > 0) && label.charAt(labelLength - 1) == '\n') {
              label = label.substring(0, labelLength - 1);
            }
            ChoiceGroup choiceGroup;
            if (isCheckBox) {
              choiceGroup = this.currentCheckBoxChoiceGroup;
            } else {
              choiceGroup = this.currentRadioChoiceGroup;
            }
            if (choiceGroup == null || !name.equals(choiceGroup.getAttribute(ATTR_NAME))) {
              // create a new choice group:
              String groupLabel = (String) attributeMap.get("label");
              if (isCheckBox) {
                // #style browserChoiceGroupMultiple
                choiceGroup = new ChoiceGroup(groupLabel, Choice.MULTIPLE);
              } else {
                String choiceType = (String) attributeMap.get("choice");
                if ("popup".equals(choiceType)) {
                  // #style browserChoiceGroupPopup
                  choiceGroup = new ChoiceGroup(groupLabel, Choice.POPUP);
                  this.currentRadioChoiceGroup = choiceGroup;
                } else {
                  // #style browserChoiceGroupExclusive
                  choiceGroup = new ChoiceGroup(groupLabel, Choice.EXCLUSIVE);
                  this.currentRadioChoiceGroup = choiceGroup;
                }
              }
              choiceGroup.setAttribute(ATTR_NAME, name);
              String styleName = (String) attributeMap.get("groupclass");
              if (styleName != null) {
                Style groupStyle = StyleSheet.getStyle(styleName);
                if (groupStyle != null) {
                  choiceGroup.setStyle(groupStyle);
                }
              }
              add(choiceGroup);
              if (this.currentForm == null) {
                // #debug error
                System.out.println("Error in HTML-Code: no <form> for <select> element found!");
              } else {
                this.currentForm.addItem(choiceGroup);
              }
              // end of creating a new choice group
            }
            ChoiceItem item;
            if (isCheckBox) {
              // #style browserCheckBox
              item = new ChoiceItem(label, null, Choice.MULTIPLE);
            } else {
              // #style browserRadio
              item = new ChoiceItem(label, null, choiceGroup.getType());
            }
            item.setAttribute(ATTR_VALUE, value);
            choiceGroup.append(item);
            if (attributeMap.get("checked") != null) {
              choiceGroup.setSelectedIndex(choiceGroup.size() - 1, true);
            }
            if (style != null) {
              item.setStyle(style);
            }
          }
          // #if polish.debug.debug
          else {
            // #debug
            System.out.println("unhandled html form input type: " + type);
          }
          // #endif
        }

        return true;
      } else if (TAG_SCRIPT.equals(tagName)) {
        // Consume javascript code.
        parser.next();
        return true;
      } else if (TAG_TABLE.equals(tagName)) {
        // #style browserTable?
        TableItem table = new TableItem();
        table.setSelectionMode(
            TableItem.SELECTION_MODE_CELL | TableItem.SELECTION_MODE_INTERACTIVE);
        table.setCellContainerStyle(this.browser.getStyle());
        if (style != null) {
          table.setStyle(style);
        }

        this.currentTable = table;
        this.browser.openContainer(table);
        return true;
      } else if (this.currentTable != null && TAG_TR.equals(tagName)) {
        this.currentTable.moveToNextRow();
        return true;
      } else if (this.currentTable != null && TAG_TH.equals(tagName)) {
        // TODO differentiate between th and td
        this.currentTable.moveToNextColumn();
        return true;
      } else if (this.currentTable != null && TAG_TD.equals(tagName)) {
        // TODO differentiate between th and td
        this.currentTable.moveToNextColumn();
        return true;
      } else if (TAG_CODE.equals(tagName)) {
        // #if polish.css.style.browsertextcode && !polish.LibraryBuild
        // #style browserTextCode
        // # this.textStyle = ();
        // #endif
      }
    } else {
      // the tag is being closed:
      if (TAG_TABLE.equals(tagName)) {
        Container container = this.browser.closeContainer();
        if (UiAccess.cast(container) instanceof TableItem) {
          this.currentTable = (TableItem) UiAccess.cast(container);
        } else {
          this.currentTable = null;
        }
        return true;
      }
      if (TAG_CODE.equals(tagName)) {
        this.textStyle = null;
      }
    }

    if (TAG_B.equals(tagName) || TAG_STRONG.equals(tagName)) {
      this.textBold = opening;
      return true;
    } else if (TAG_I.equals(tagName) || TAG_EM.equals(tagName)) {
      this.textItalic = opening;
      return true;
    } else if (TAG_FORM.equals(tagName)) {
      if (opening) {
        String name = (String) attributeMap.get("name");
        String action = (String) attributeMap.get("action");
        String method = (String) attributeMap.get("method");
        String encoding = (String) attributeMap.get("enctype");

        if (method == null) {
          method = "GET";
        }
        this.currentForm =
            new HtmlForm(name, action, method, encoding, this.browser, this.formListener);
        this.browser.addForm(this.currentForm);
        this.browser.openContainer(style);
      } else {
        this.browser.closeContainer();
        this.currentForm = null;
        this.currentCheckBoxChoiceGroup = null;
        this.currentRadioChoiceGroup = null;
      }

      return true;
    } else if (opening && TAG_BODY.equals(tagName)) {
      if (style != null) {
        // System.out.println("applying style " + style.name + " for body with bg=" +
        // style.background);
        this.browser.setBackground(style.background);
        this.browser.setBorder(style.border);
        this.browser.setStyle(style, false);
      }
    }

    return false;
  }