diff --git a/experiments/oldwidgets.nim b/experiments/oldwidgets.nim new file mode 100644 index 0000000..46d87c2 --- /dev/null +++ b/experiments/oldwidgets.nim @@ -0,0 +1,113 @@ +var + linkCounter: int + +proc link*(id: int): VNode = + result = newVNode(VNodeKind.anchor) + result.setAttr("href", "#") + inc linkCounter + result.setAttr("id", $linkCounter & ":" & $id) + +proc link*(action: EventHandler): VNode = + result = newVNode(VNodeKind.anchor) + result.setAttr("href", "#") + result.setOnclick action + +when false: + proc button*(caption: cstring; action: EventHandler; disabled=false): VNode = + result = newVNode(VNodeKind.button) + result.add text(caption) + if action != nil: + result.setOnClick action + if disabled: + result.setAttr("disabled", "true") + +proc select*(choices: openarray[cstring]): VNode = + result = newVNode(VNodeKind.select) + var i = 0 + for c in choices: + result.add tree(VNodeKind.option, [(cstring"value", toCstr(i))], text(c)) + inc i + +proc select*(choices: openarray[(int, cstring)]): VNode = + result = newVNode(VNodeKind.select) + for c in choices: + result.add tree(VNodeKind.option, [(cstring"value", toCstr(c[0]))], text(c[1])) + +var radioCounter: int + +proc radio*(choices: openarray[(int, cstring)]): VNode = + result = newVNode(VNodeKind.fieldset) + var i = 0 + inc radioCounter + for c in choices: + let id = cstring"radio_" & c[1] & toCstr(i) + var kid = tree(VNodeKind.input, [(cstring"type", cstring"radio"), + (cstring"id", id), (cstring"name", cstring"radio" & toCStr(radioCounter)), + (cstring"value", toCStr(c[0]))]) + if i == 0: + kid.setAttr(cstring"checked", cstring"checked") + var lab = tree(VNodeKind.label, [(cstring"for", id)], text(c[1])) + kid.add lab + result.add kid + inc i + +proc tag*(kind: VNodeKind; id=cstring(nil), class=cstring(nil)): VNode = + result = newVNode(kind) + result.id = id + result.class = class + +proc tdiv*(id=cstring(nil), class=cstring(nil)): VNode = tag(VNodeKind.tdiv, id, class) +proc span*(id=cstring(nil), class=cstring(nil)): VNode = tag(VNodeKind.span, id, class) + +proc valueAsInt*(e: Node): int = parseInt(e.value) + +proc th*(s: cstring): VNode = + result = newVNode(VNodeKind.th) + result.add text(s) + +proc td*(s: string): VNode = + result = newVNode(VNodeKind.td) + result.add text(s) + +proc td*(s: VNode): VNode = + result = newVNode(VNodeKind.td) + result.add s + +proc td*(class: cstring; s: VNode): VNode = + result = newVNode(VNodeKind.td) + result.add s + result.class = class + +proc table*(class=cstring(nil), kids: varargs[VNode]): VNode = + result = tag(VNodeKind.table, nil, class) + for k in kids: result.add k + +proc tr*(kids: varargs[VNode]): VNode = + result = newVNode(VNodeKind.tr) + for k in kids: + if k.kind in {VNodeKind.td, VNodeKind.th}: + result.add k + else: + result.add td(k) + +proc suffix*(s, prefix: cstring): cstring = + if s.startsWith(prefix): + result = s.substr(prefix.len) + else: + kout(cstring"bug! " & s & cstring" does not start with " & prefix) + +proc suffixAsInt*(s, prefix: cstring): int = parseInt(suffix(s, prefix)) + +#proc ceil(f: float): int {.importc: "Math.ceil", nodecl.} + + +when false: + var plugins {.exportc.}: seq[(string, proc())] = @[] + + proc onInput(val: cstring) = + kout val + if val == "dyn": + kout(plugins.len) + if plugins.len > 0: + plugins[0][1]() + diff --git a/experiments/scrollapp.nims b/experiments/scrollapp.nims new file mode 100644 index 0000000..532b206 --- /dev/null +++ b/experiments/scrollapp.nims @@ -0,0 +1 @@ +--path: "../src" diff --git a/experiments/style.css b/experiments/style.css new file mode 100644 index 0000000..ceaf090 --- /dev/null +++ b/experiments/style.css @@ -0,0 +1,378 @@ +html, +body { + margin: 0; + padding: 0; +} + +.todomvc-wrapper { + visibility: visible !important; +} + +button { + margin: 0; + padding: 0; + border: 0; + background: none; + font-size: 100%; + vertical-align: baseline; + font-family: inherit; + font-weight: inherit; + color: inherit; + -webkit-appearance: none; + appearance: none; + -webkit-font-smoothing: antialiased; + -moz-font-smoothing: antialiased; + font-smoothing: antialiased; +} + +body { + font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.4em; + background: #f5f5f5; + color: #4d4d4d; + min-width: 230px; + max-width: 550px; + margin: 0 auto; + -webkit-font-smoothing: antialiased; + -moz-font-smoothing: antialiased; + font-smoothing: antialiased; + font-weight: 300; +} + +button, +input[type="checkbox"] { + outline: none; +} + +.hidden { + display: none; +} + +.todoapp { + background: #fff; + margin: 130px 0 40px 0; + position: relative; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), + 0 25px 50px 0 rgba(0, 0, 0, 0.1); +} + +.todoapp input::-webkit-input-placeholder { + font-style: italic; + font-weight: 300; + color: #e6e6e6; +} + +.todoapp input::-moz-placeholder { + font-style: italic; + font-weight: 300; + color: #e6e6e6; +} + +.todoapp input::input-placeholder { + font-style: italic; + font-weight: 300; + color: #e6e6e6; +} + +.todoapp h1 { + position: absolute; + top: -155px; + width: 100%; + font-size: 100px; + font-weight: 100; + text-align: center; + color: rgba(175, 47, 47, 0.15); + -webkit-text-rendering: optimizeLegibility; + -moz-text-rendering: optimizeLegibility; + text-rendering: optimizeLegibility; +} + +.new-todo, +.edit { + position: relative; + margin: 0; + width: 100%; + font-size: 24px; + font-family: inherit; + font-weight: inherit; + line-height: 1.4em; + border: 0; + outline: none; + color: inherit; + padding: 6px; + border: 1px solid #999; + box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); + box-sizing: border-box; + -webkit-font-smoothing: antialiased; + -moz-font-smoothing: antialiased; + font-smoothing: antialiased; +} + +.new-todo { + padding: 16px 16px 16px 60px; + border: none; + background: rgba(0, 0, 0, 0.003); + box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); +} + +.main { + position: relative; + z-index: 2; + border-top: 1px solid #e6e6e6; +} + +label[for='toggle-all'] { + display: none; +} + +.toggle-all { + position: absolute; + top: -55px; + left: -12px; + width: 60px; + height: 34px; + text-align: center; + border: none; /* Mobile Safari */ +} + +.toggle-all:before { + content: '>'; + font-size: 22px; + color: #e6e6e6; + padding: 10px 27px 10px 27px; +} + +.toggle-all:checked:before { + color: #737373; +} + +.todo-list { + margin: 0; + padding: 0; + list-style: none; +} + +.todo-list li { + position: relative; + font-size: 24px; + border-bottom: 1px solid #ededed; +} + +.todo-list li:last-child { + border-bottom: none; +} + +.todo-list li.editing { + border-bottom: none; + padding: 0; +} + +.todo-list li.editing .edit { + display: block; + width: 506px; + padding: 13px 17px 12px 17px; + margin: 0 0 0 43px; +} + +.todo-list li.editing .view { + display: none; +} + +.todo-list li .toggle { + text-align: center; + width: 40px; + /* auto, since non-WebKit browsers doesn't support input styling */ + height: auto; + position: absolute; + top: 0; + bottom: 0; + margin: auto 0; + border: none; /* Mobile Safari */ + -webkit-appearance: none; + appearance: none; +} + +.todo-list li .toggle:after { + content: url('data:image/svg+xml,'); +} + +.todo-list li .toggle:checked:after { + content: url('data:image/svg+xml,'); +} + +.todo-list li label { + white-space: pre-line; + word-break: break-all; + padding: 15px 60px 15px 15px; + margin-left: 45px; + display: block; + line-height: 1.2; + transition: color 0.4s; +} + +.todo-list li.completed label { + color: #d9d9d9; + text-decoration: line-through; +} + +.todo-list li .destroy { + display: none; + position: absolute; + top: 0; + right: 10px; + bottom: 0; + width: 40px; + height: 40px; + margin: auto 0; + font-size: 30px; + color: #cc9a9a; + margin-bottom: 11px; + transition: color 0.2s ease-out; +} + +.todo-list li .destroy:hover { + color: #af5b5e; +} + +.todo-list li .destroy:after { + content: 'x'; +} + +.todo-list li:hover .destroy { + display: block; +} + +.todo-list li.editing:last-child { + margin-bottom: -1px; +} + +.footer { + color: #777; + padding: 10px 15px; + height: 20px; + text-align: center; + border-top: 1px solid #e6e6e6; +} + +.footer:before { + content: ''; + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 50px; + overflow: hidden; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), + 0 8px 0 -3px #f6f6f6, + 0 9px 1px -3px rgba(0, 0, 0, 0.2), + 0 16px 0 -6px #f6f6f6, + 0 17px 2px -6px rgba(0, 0, 0, 0.2); +} + +.todo-count { + float: left; + text-align: left; +} + +.todo-count strong { + font-weight: 300; +} + +.filters { + margin: 0; + padding: 0; + list-style: none; + position: absolute; + right: 0; + left: 0; +} + +.filters li { + display: inline; +} + +.filters li a { + color: inherit; + margin: 3px; + padding: 3px 7px; + text-decoration: none; + border: 1px solid transparent; + border-radius: 3px; +} + +.filters li a.selected, +.filters li a:hover { + border-color: rgba(175, 47, 47, 0.1); +} + +.filters li a.selected { + border-color: rgba(175, 47, 47, 0.2); +} + +.clear-completed, +html .clear-completed:active { + float: right; + position: relative; + line-height: 20px; + text-decoration: none; + cursor: pointer; + position: relative; +} + +.clear-completed:hover { + text-decoration: underline; +} + +.info { + margin: 65px auto 0; + color: #bfbfbf; + /* font-size: 10px; */ + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-align: center; +} + +.info p { + line-height: 1; +} + +.info a { + color: inherit; + text-decoration: none; + font-weight: 400; +} + +.info a:hover { + text-decoration: underline; +} + +/* + Hack to remove background from Mobile Safari. + Can't use it globally since it destroys checkboxes in Firefox +*/ +@media screen and (-webkit-min-device-pixel-ratio:0) { + .toggle-all, + .todo-list li .toggle { + background: none; + } + + .todo-list li .toggle { + height: 40px; + } + + .toggle-all { + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + -webkit-appearance: none; + appearance: none; + } +} + +@media (max-width: 430px) { + .footer { + height: 50px; + } + + .filters { + bottom: 10px; + } +} \ No newline at end of file