code: private Expression getStaticContent(HtmlAttributeNode node) {
      if (!node.hasValue()) {
        return Expression.stringLiteral("");
      }
      // This case is some control flow like a switch, if, or for loop.
      if (!(node.getChild(1) instanceof HtmlAttributeValueNode)) {
        return null;
      }
      HtmlAttributeValueNode attrValue = (HtmlAttributeValueNode) node.getChild(1);
      if (attrValue.numChildren() == 0) {
        return Expression.stringLiteral("");
      }
      // If any children are not raw text or constant xid/css calls, return null
      for (int i = 0; i < attrValue.numChildren(); i++) {
        if (attrValue.getChild(i) instanceof RawTextNode) {
          continue;
        } else if (attrValue.getChild(i) instanceof PrintNode) {
          PrintNode n = (PrintNode) attrValue.getChild(i);
          if (n.getExpr().getRoot() instanceof FunctionNode) {
            FunctionNode fnNode = (FunctionNode) n.getExpr().getRoot();
            if (fnNode.getSoyFunction() != BuiltinFunction.XID
                && fnNode.getSoyFunction() != BuiltinFunction.CSS) {
              return null; // Function call was not xid or css
            }
          } else {
            // Child is variable expression ie {$foo} or {$foo + $bar}
            return null;
          }
        } else {
          // Child was control flow.
          return null;
        }
      }
      return CodeChunkUtils.concatChunksForceString(getAttributeValues(node));
    }
docs: Extract static content from attributes, or return null if value is dynamic. Static content is
  either an attribute value that is nonexistent or a combination of raw text and xid/css calls.