HttpHandlers+Scopes.swift 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //
  2. // HttpHandlers+Scopes.swift
  3. // Swifter
  4. //
  5. // Copyright © 2014-2016 Damian Kołakowski. All rights reserved.
  6. //
  7. import Foundation
  8. extension HttpHandlers {
  9. public class func scopes(_ scope: Scope) -> ((HttpRequest) -> HttpResponse) {
  10. return { r in
  11. bufferToken = ""
  12. scope()
  13. return .RAW(200, "OK", ["Content-Type": "text/html"], { $0.write([UInt8](("<!DOCTYPE html>" + bufferToken).utf8)) })
  14. }
  15. }
  16. }
  17. public var src : String? = nil
  18. public var style : String? = nil
  19. public var width : String? = nil
  20. public var height : String? = nil
  21. public var inner : String? = nil
  22. public var ref : String? = nil
  23. public var href : String? = nil
  24. public var type : String? = nil
  25. private func scopesPushAttributes() {
  26. attributesStack.append(["src": src, "style": style, "width": width, "height": height, "inner": inner, "ref": ref, "href": href, "type": type])
  27. src = nil
  28. style = nil
  29. width = nil
  30. height = nil
  31. inner = nil
  32. ref = nil
  33. href = nil
  34. type = nil
  35. }
  36. private func scopesPopAttributes() {
  37. if let last = attributesStack.last {
  38. src = last["src"]!
  39. style = last["style"]!
  40. width = last["width"]!
  41. height = last["height"]!
  42. inner = last["inner"]!
  43. ref = last["ref"]!
  44. href = last["href"]!
  45. type = last["type"]!
  46. attributesStack.removeLast()
  47. }
  48. }
  49. public var attributesStack = [[String: String?]]()
  50. var bufferToken = ""
  51. public typealias Scope = (Void) -> Void
  52. public func element( _ node: String, attrs: [String: String?] = [:], scope: Scope) {
  53. scopesPushAttributes()
  54. bufferToken = bufferToken + "<" + node
  55. var bufferClone = bufferToken
  56. bufferToken = ""
  57. scope()
  58. var mergedAttributes = [String: String?]()
  59. for item in ["src": src, "style": style, "width": width, "height": height, "ref": ref, "href": href, "type": type].enumerated() {
  60. mergedAttributes.updateValue(item.element.value, forKey: item.element.key)
  61. }
  62. for item in attrs.enumerated() {
  63. mergedAttributes.updateValue(item.element.value, forKey: item.element.key)
  64. }
  65. bufferClone = bufferClone + mergedAttributes.reduce("") {
  66. if let value = $0.1.value {
  67. return $0.0 + " \($0.1.key)=\"\(value)\""
  68. } else {
  69. return $0.0
  70. }
  71. }
  72. bufferToken = bufferClone + ">" + (inner ?? bufferToken) + "</" + node + ">"
  73. scopesPopAttributes()
  74. }
  75. public func a(scope: Scope) { element("a", scope: scope) }
  76. public func p(scope: Scope) { element("p", scope: scope) }
  77. public func u(scope: Scope) { element("u", scope: scope) }
  78. public func b(scope: Scope) { element("b", scope: scope) }
  79. public func br(scope: Scope) { element("br", scope: scope) }
  80. public func hr(scope: Scope) { element("hr", scope: scope) }
  81. public func h1(scope: Scope) { element("h1", scope: scope) }
  82. public func h2(scope: Scope) { element("h2", scope: scope) }
  83. public func h3(scope: Scope) { element("h3", scope: scope) }
  84. public func h4(scope: Scope) { element("h4", scope: scope) }
  85. public func h5(scope: Scope) { element("h5", scope: scope) }
  86. public func td(scope: Scope) { element("td", scope: scope) }
  87. public func tr(scope: Scope) { element("tr", scope: scope) }
  88. public func li(scope: Scope) { element("li", scope: scope) }
  89. public func ul(scope: Scope) { element("ul", scope: scope) }
  90. public func div(scope: Scope) { element("div", scope: scope) }
  91. public func img(scope: Scope) { element("img", scope: scope) }
  92. public func big(scope: Scope) { element("big", scope: scope) }
  93. public func nav(scope: Scope) { element("nav", scope: scope) }
  94. public func html(scope: Scope) { element("html", scope: scope) }
  95. public func meta(scope: Scope) { element("meta", scope: scope) }
  96. public func head(scope: Scope) { element("head", scope: scope) }
  97. public func body(scope: Scope) { element("body", scope: scope) }
  98. public func span(scope: Scope) { element("span", scope: scope) }
  99. public func form(scope: Scope) { element("form", scope: scope) }
  100. public func link(scope: Scope) { element("link", scope: scope) }
  101. public func table(scope: Scope) { element("table", scope: scope) }
  102. public func tbody(scope: Scope) { element("tbody", scope: scope) }
  103. public func small(scope: Scope) { element("small", scope: scope) }
  104. public func input(scope: Scope) { element("input", scope: scope) }
  105. public func label(scope: Scope) { element("label", scope: scope) }
  106. public func video(scope: Scope) { element("video", scope: scope) }
  107. public func style(scope: Scope) { element("style", scope: scope) }
  108. public func title(scope: Scope) { element("title", scope: scope) }
  109. public func header(scope: Scope) { element("header", scope: scope) }
  110. public func footer(scope: Scope) { element("footer", scope: scope) }
  111. public func iframe(scope: Scope) { element("iframe", scope: scope) }
  112. public func strong(scope: Scope) { element("strong", scope: scope) }
  113. public func option(scope: Scope) { element("option", scope: scope) }
  114. public func center(scope: Scope) { element("center", scope: scope) }
  115. public func object(scope: Scope) { element("object", scope: scope) }
  116. public func script(scope: Scope) { element("script", scope: scope) }
  117. public func canvas(scope: Scope) { element("canvas", scope: scope) }
  118. public func textarea(scope: Scope) { element("textarea", scope: scope) }
  119. public func stylesheet(scope: Scope) { element("link", attrs: ["rel": "stylesheet", "type": "text/css"], scope: scope) }