1 // SemiTwist Library 2 // Written in the D programming language. 3 // 4 // Helper tools for the arsd DOM module at: 5 // https://github.com/adamdruppe/arsd/blob/master/dom.d 6 7 module semitwist.arsddom; 8 9 import std.string; 10 import arsd.dom; 11 12 void deactivateLink(Element link) 13 { 14 link.removeAttribute("href"); 15 link.className = "inactive-link"; 16 link.tagName = "span"; 17 } 18 19 void removeAll(Element elem, string selector) 20 { 21 foreach(ref elemToRemove; elem.getElementsBySelector(selector)) 22 elemToRemove.outerHTML = ""; 23 } 24 25 void setAttributes(Element elem, string[string] attributes) 26 { 27 if(attributes != null) 28 { 29 foreach(key, value; attributes) 30 { 31 if(key.toLower() == "class") 32 elem.addClass(value); 33 else if(key.toLower() == "style") 34 elem.style ~= value; 35 else 36 elem.setAttribute(key, value); 37 } 38 } 39 } 40 41 /++ 42 Sample usage: 43 44 struct Foo { 45 int i; string s; 46 } 47 48 auto doc = new Document(" 49 <body> 50 <h1>Foo:</h1> 51 <div class="foo"> 52 <h2 class=".foo-int">(placeholder)</h2> 53 <p class=".foo-str">(placeholder)</p> 54 <hr /> 55 </div> 56 </body> 57 ", true, true); 58 59 fill!(Foo[])( 60 doc.requireSelector(".foo"), 61 [Foo(10,"abc"), Foo(20,"def")], 62 (stamp, index, foo) { 63 stamp.requireSelector(".foo-int").innerHTML = text("#", index, " ", foo.i); 64 stamp.requireSelector(".foo-str").innerHTML = foo.s; 65 return stamp; 66 } 67 ) 68 69 /+ 70 Result: 71 <body> 72 <h1>Foo:</h1> 73 <div class="foo"> 74 <h2 class=".foo-int">#0: 10</h2> 75 <p class=".foo-str">abc</p> 76 <hr /> 77 </div> 78 <div class="foo"> 79 <h2 class=".foo-int">#1: 20</h2> 80 <p class=".foo-str">def</p> 81 <hr /> 82 </div> 83 </body> 84 +/ 85 writeln(doc); 86 +/ 87 //TODO: fill() needs a way to do a plain old 0..x with no data 88 void fill(T)( 89 Element elem, T collection, 90 Element delegate(Element, size_t, ElementType!T) dg 91 ) if(isInputRange!T) 92 { 93 auto elemTemplate = elem.cloned; 94 string finalHtml; 95 for(size_t i=0; !collection.empty; i++) 96 { 97 auto stamp = elemTemplate.cloned; 98 auto newElem = dg(stamp, i, collection.front); 99 finalHtml ~= newElem.toString(); 100 collection.popFront(); 101 } 102 elem.outerHTML = finalHtml; 103 } 104 105 class MissingHtmlAttributeException : Exception 106 { 107 Element elem; 108 string attrName; 109 string htmlFileName; 110 111 this(string file=__FILE__, size_t line=__LINE__)(Element elem, string attrName, string htmlFileName=null) 112 { 113 super("", file, line); 114 setTo(elem, attrName, htmlFileName); 115 } 116 117 void setTo(Element elem, string attrName, string htmlFileName) 118 { 119 this.elem = elem; 120 this.attrName = attrName; 121 this.htmlFileName = htmlFileName; 122 123 auto msg = "Missing attribute '"~attrName~"' on <"~elem.tagName~"> element"; 124 if(htmlFileName != "") 125 msg ~= " (in file '"~htmlFileName~"')"; 126 127 this.msg = msg; 128 } 129 } 130 131 string requireAttribute(Element elem, string name) 132 { 133 auto value = elem.getAttribute(name); 134 if(value == "") 135 throw new MissingHtmlAttributeException(elem, name); 136 137 return value; 138 }