1 /**
2 * Copyright © DiamondMVC 2019
3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 */
6 module diamond.web.elements.block;
7 
8 import diamond.web.elements.element;
9 
10 import std.traits : BaseClassesTuple;
11 import std.meta : AliasSeq;
12 
13 /// Wrapper around a block element. Default implementation is a div.
14 class Block(TElement = Element) : Element
15 if
16 (
17   is(BaseClassesTuple!TElement == AliasSeq!(Element, Object)) ||
18   is(TElement == Element)
19 )
20 {
21   private:
22   /// Collection of inner elements.
23   TElement[] _elements;
24 
25   public:
26   final:
27   /// Creates a new block element.
28   this()
29   {
30     super("div");
31   }
32 
33   /**
34   * Creates a new block element.
35   * Params:
36   *   tagName = The name of the block element's tag.
37   */
38   package(diamond.web.elements) this(string tagName)
39   {
40     super(tagName);
41   }
42 
43   /**
44   * Adds an element to the block.
45   * Params:
46   *   element = The element to add.
47   */
48   void addElement(TElement element)
49   {
50     _elements ~= element;
51   }
52 
53   protected:
54   /// Generates the appropriate html for the element.
55   override string generateHtml()
56   {
57     import std..string : format;
58     import std.array : array, join;
59     import std.algorithm : map;
60 
61     string innerHtml;
62 
63     if (_elements)
64     {
65       innerHtml = _elements ? _elements.map!(e => e.toString()).array.join("\n") : "";
66     }
67 
68     if (!innerHtml || !innerHtml.length)
69     {
70       innerHtml = super.inner ? super.inner : "";
71     }
72 
73     return `
74 <%1$s %2$s>
75       %3$s
76 </%1$s>`.format(super.tagName, super.attributeHtml(), innerHtml);
77   }
78 }