Ejemplo n.º 1
0
  /**
   * Complement of HtmlTemplateCompiler#lexicalClimb(). This method pops off the stack of lexical
   * scopes when we're done processing a sitebricks widget.
   */
  private void lexicalDescend(PageCompilingContext pc, Element element, boolean shouldPopScope) {

    // pop form
    if ("form".equals(element.tagName())) pc.form = null;

    // pop compiler if the scope ends
    if (shouldPopScope) {
      pc.lexicalScopes.pop();
    }
  }
Ejemplo n.º 2
0
  public Renderable compile(Class<?> page, Template template) {

    PageCompilingContext pc = new PageCompilingContext();
    pc.page = page;
    pc.template = template;
    pc.lexicalScopes.push(new MvelEvaluatorCompiler(page));

    WidgetChain widgetChain;
    widgetChain = walk(pc, HtmlParser.parse(template.getText()));

    // TODO - get the errors when !(isValid)
    if (!pc.errors.isEmpty() || !pc.warnings.isEmpty()) {
      // If there were any errors we must track them.
      metrics.logErrorsAndWarnings(page, pc.errors, pc.warnings);

      // Only explode if there are errors.
      if (!pc.errors.isEmpty())
        throw new TemplateCompileException(page, template.getText(), pc.errors, pc.warnings);
    }

    return widgetChain;
  }
Ejemplo n.º 3
0
  /** Walks the DOM recursively, and converts elements into corresponding sitebricks widgets. */
  @NotNull
  private <N extends Node> WidgetChain walk(PageCompilingContext pc, N node) {
    WidgetChain widgetChain = Chains.proceeding();
    for (Node n : node.childNodes()) {
      if (n instanceof Element) {
        final Element child = (Element) n;

        // push form if this is a form tag
        if (child.tagName().equals("form")) pc.form = (Element) n;

        // setup a lexical scope if we're going into a repeat widget (by reading the previous node)
        final boolean shouldPopScope = lexicalClimb(pc, child);

        // continue recursing down, perform a post-order, depth-first traversal of the DOM
        WidgetChain childsChildren;
        try {
          childsChildren = walk(pc, child);

          // process the widget itself into a Renderable with child tree
          widgetChain.addWidget(widgetize(pc, child, childsChildren));
        } finally {
          lexicalDescend(pc, child, shouldPopScope);
        }

      } else if (n instanceof TextNode) {
        TextNode child = (TextNode) n;
        Renderable textWidget;

        // setup a lexical scope if we're going into a repeat widget (by reading the previous node)
        final boolean shouldPopScope = lexicalClimb(pc, child);

        // construct the text widget
        try {
          textWidget = registry.textWidget(cleanHtml(n), pc.lexicalScopes.peek());

          // if there are no annotations, add the text widget to the chain
          if (!child.hasAttr(ANNOTATION_KEY)) {
            widgetChain.addWidget(textWidget);
          } else {
            // construct a new widget chain for this text node
            WidgetChain childsChildren = Chains.proceeding().addWidget(textWidget);

            // make a new widget for the annotation, making the text chain the child
            String widgetName = child.attr(ANNOTATION_KEY).toLowerCase();
            Renderable annotationWidget =
                registry.newWidget(
                    widgetName,
                    child.attr(ANNOTATION_CONTENT),
                    childsChildren,
                    pc.lexicalScopes.peek());
            widgetChain.addWidget(annotationWidget);
          }

        } catch (ExpressionCompileException e) {
          pc.errors.add(CompileError.in(node.outerHtml()).near(line(node)).causedBy(e));
        }

        if (shouldPopScope) pc.lexicalScopes.pop();

      } else if ((n instanceof Comment) || (n instanceof DataNode)) {
        // process as raw text widget
        try {
          widgetChain.addWidget(registry.textWidget(cleanHtml(n), pc.lexicalScopes.peek()));
        } catch (ExpressionCompileException e) {

          pc.errors.add(CompileError.in(node.outerHtml()).near(line(node)).causedBy(e));
        }
      } else if (n instanceof XmlDeclaration) {
        try {
          widgetChain.addWidget(
              registry.xmlDirectiveWidget(
                  ((XmlDeclaration) n).getWholeDeclaration(), pc.lexicalScopes.peek()));
        } catch (ExpressionCompileException e) {
          pc.errors.add(CompileError.in(node.outerHtml()).near(line(node)).causedBy(e));
        }
      }
    }

    // return computed chain, or a terminal
    return widgetChain;
  }