Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit aba4347092761dfdcaa5605b807c23fa458da41b @drcode committed Nov 14, 2012
Showing with 21,835 additions and 0 deletions.
  1. +11 −0 README
  2. +66 −0 info.txt
  3. BIN lib/clojure-1.3.0.jar
  4. +40 −0 pom.xml
  5. +3 −0 project.clj
  6. +63 −0 src/webfui/core.cljs
  7. +11 −0 src/webfui/dom.cljs
  8. +23 −0 src/webfui/dom_manipulation.cljs
  9. +51 −0 src/webfui/framework.cljs
  10. +11 −0 src/webfui/framework/macros.clj
  11. +145 −0 src/webfui/html.cljs
  12. +15 −0 src/webfui/macros.clj
  13. +10 −0 src/webfui/plugin/core.cljs
  14. +25 −0 src/webfui/plugin/form_values.cljs
  15. +121 −0 src/webfui/plugin/mouse.cljs
  16. +41 −0 src/webfui/plugin/scrolling.cljs
  17. +22 −0 src/webfui/state_patches.cljs
  18. +11 −0 src/webfui/utilities.cljs
  19. +6 −0 test/webfui/test/core.clj
  20. +5 −0 webfui-examples/.gitignore
  21. +1 −0 webfui-examples/.lein-plugins/checksum
  22. +17 −0 webfui-examples/README.md
  23. +42 −0 webfui-examples/project.clj
  24. BIN webfui-examples/resources/public/css/POCKC___.eot
  25. +603 −0 webfui-examples/resources/public/css/POCKC___.svg
  26. BIN webfui-examples/resources/public/css/POCKC___.ttf
  27. BIN webfui-examples/resources/public/css/POCKC___.woff
  28. +9 −0 webfui-examples/resources/public/css/add_two_numbers.css
  29. +10 −0 webfui-examples/resources/public/css/add_two_numbers_low_level.css
  30. +43 −0 webfui-examples/resources/public/css/calculator.css
  31. +43 −0 webfui-examples/resources/public/css/calculator_ajax.css
  32. +43 −0 webfui-examples/resources/public/css/calculator_many.css
  33. +22 −0 webfui-examples/resources/public/css/inverse_kinematics.css
  34. +31 −0 webfui-examples/resources/public/css/mouse_tracking.css
  35. 0 webfui-examples/resources/public/css/scrolling.css
  36. +9 −0 webfui-examples/resources/public/css/webfui_examples.css
  37. +16 −0 webfui-examples/resources/public/index.html
  38. +19,235 −0 webfui-examples/resources/public/js/core.js
  39. +25 −0 webfui-examples/src-clj/webfui_examples/server.clj
  40. +8 −0 webfui-examples/src-clj/webfui_examples/views/add_two_numbers.clj
  41. +8 −0 webfui-examples/src-clj/webfui_examples/views/add_two_numbers_low_level.clj
  42. +8 −0 webfui-examples/src-clj/webfui_examples/views/calculator.clj
  43. +8 −0 webfui-examples/src-clj/webfui_examples/views/calculator_ajax.clj
  44. +8 −0 webfui-examples/src-clj/webfui_examples/views/calculator_many.clj
  45. +13 −0 webfui-examples/src-clj/webfui_examples/views/common.clj
  46. +8 −0 webfui-examples/src-clj/webfui_examples/views/inverse_kinematics.clj
  47. +8 −0 webfui-examples/src-clj/webfui_examples/views/mouse_tracking.clj
  48. +8 −0 webfui-examples/src-clj/webfui_examples/views/scrolling.clj
  49. +9 −0 webfui-examples/src-clj/webfui_examples/views/welcome.clj
  50. +23 −0 webfui-examples/src-cljs/add_two_numbers/core.cljs
  51. +40 −0 webfui-examples/src-cljs/add_two_numbers_low_level/core.cljs
  52. +92 −0 webfui-examples/src-cljs/calculator/core.cljs
  53. +124 −0 webfui-examples/src-cljs/calculator_ajax/core.cljs
  54. +108 −0 webfui-examples/src-cljs/calculator_many/core.cljs
  55. +449 −0 webfui-examples/src-cljs/inverse_kinematics/core.cljs
  56. +51 −0 webfui-examples/src-cljs/mouse_tracking/core.cljs
  57. +33 −0 webfui-examples/src-cljs/scrolling/core.cljs
11 README
@@ -0,0 +1,11 @@
+# webfui
+
+Client Side Web Development Framework For ClojureScript
+
+## Usage
+
+Documentation is still pending (expect it by November 2012). At this time, your best guide is to run the code in the "webfui-examples" directory- Just run "lein deps;lein run" and fire up your Safari, Chrome, or iOS browser to "localhost:8080"
+
+## License
+
+Distributed under the Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php), the same as Clojure.
@@ -0,0 +1,66 @@
+*presentation notes
+
+What is the DOM?
+
+Problems with the DOM
+ - It changes
+ - Changing it is slow
+
+What is EDN?
+
+What is AJAX?
+
+How to build a web framework:
+ - Should do things the Clojure Way
+ - Code should be in the functional style
+ - The browser DOM should be EDN data stored in an atom
+
+DOM is not a complete representation of browser state
+ - Can't set button as pushed
+ - Can't set scrollbar position
+ - Can't set text selection
+
+Problem: AJAX requires side effects. Reframed problem: Our state atom no longer contains the whole world
+
+Original sin: Our state is _always_ corrupt in a program that uses AJAX.
+
+We have to contain the corruption (Can be done with FP)
+We have to repair the corruption (Requires imperative programming)
+
+"State Corruption" Design Pattern
+
+AJAX=Corruption of state
+
+Corruption is implicit- Make it explicit
+
+GET: State item has value of nil
+ or selection variable has id that points to nonexistent item
+
+POST: Create new item in state with id=nil
+
+PUT: Have "holding area" in state, set source of truth=nil. Move from holding area back to final area
+
+DELETE: Just delete item
+
+*todos
+item insert/deletion in delta system
+text selection
+full IK artwork
+"preview" in calculator
+
+*Hello World
+(ns my-app.core
+ (:use [webfui.framework :only [launch-app]]))
+
+(defn render-all []
+ "hello world!")
+
+(launch-app (atom nil) render-all)
+
+
+
+*timing
+~250 for mouseup
+~150 for webfui code
+~90 for parsing html
+~90 for delta detection
Binary file not shown.
40 pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>webfui</groupId>
+ <artifactId>webfui</artifactId>
+ <version>0.2</version>
+ <name>webfui</name>
+ <description>Alpha release of Webfui- All Webfui source included in this repository release under Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)</description>
+ <url>http://lisperati.com</url>
+ <build>
+ <sourceDirectory>src</sourceDirectory>
+ <testSourceDirectory>test</testSourceDirectory>
+ <resources>
+ <resource>
+ <directory>resources</directory>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>test-resources</directory>
+ </testResource>
+ </testResources>
+ </build>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <url>http://repo1.maven.org/maven2</url>
+ </repository>
+ <repository>
+ <id>clojars</id>
+ <url>http://clojars.org/repo/</url>
+ </repository>
+ </repositories>
+</project>
+
+<!-- This file was autogenerated by Leiningen.
+ Please do not edit it directly; instead edit project.clj and regenerate it.
+ It should not be considered canonical data. For more information see
+ https://github.com/technomancy/leiningen -->
@@ -0,0 +1,3 @@
+(defproject webfui "0.2"
+ :description "Alpha release of Webfui- All Webfui source included in this repository release under Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)"
+ :url "http://lisperati.com")
@@ -0,0 +1,63 @@
+(ns webfui.core
+ (:use [webfui.html :only [html parse-html parsed-html render-attribute-value html-delta]]
+ [webfui.plugin.core :only [active-plugins Plugin declare-events fix-dom]]
+ [cljs.reader :only [read-string]]))
+
+;; This file contains the core engine for webfui. You usually don't want to load this file directly, instead load webfui.dom or webfui.framework.
+
+(defn body []
+ (.-body js/document))
+
+(defn select-path-dom [node path]
+ (if-let [[cur & more] (seq path)]
+ (recur (.item (.-childNodes node) cur) more)
+ node))
+
+(defn dom-ready? []
+ (= (.-readyState js/document) "complete"))
+
+(defn dom-ready [fun]
+ (set! (.-onload js/window) fun))
+
+(defn parsed-html-watcher [key a old new]
+ (let [delta (html-delta (.-children old) (.-children new) [])]
+ (doseq [[typ path a b] delta]
+ (let [node (select-path-dom (body) path)]
+ (case typ
+ :att (if (= a :value)
+ (set! (.-value node) (str b))
+ (.setAttribute node (name a) (render-attribute-value a b)))
+ :rem-att (.removeAttribute node (name a))
+ :html (set! (.-innerHTML node) (apply str (map html a))))))
+ (doseq [plugin @active-plugins]
+ (fix-dom plugin))))
+
+(def parsed-html-atom (atom (parsed-html. :body {} nil)))
+
+(defn update-parsed-html-atom [new old]
+ (parsed-html. :body
+ {}
+ (if (or (seq? new) (list? new))
+ (parse-html new)
+ (parse-html (list new)))))
+
+(defn html-watcher [key a old new]
+ (swap! parsed-html-atom (partial update-parsed-html-atom new)))
+
+(def dom-watchers (atom {}))
+
+(defn core-add-dom-watch [id fun]
+ (swap! dom-watchers assoc id fun))
+
+(defn init-dom [html]
+ (let [b (body)]
+ (doseq [plugin @active-plugins]
+ (declare-events plugin (body) dom-watchers parsed-html-atom))
+ (add-watch html :dom-watcher html-watcher)
+ (add-watch parsed-html-atom :parsed-html-watcher parsed-html-watcher)
+ (swap! html identity)))
+
+(defn core-defdom [clj-dom]
+ (if (dom-ready?)
+ (init-dom clj-dom)
+ (dom-ready (partial init-dom clj-dom))))
@@ -0,0 +1,11 @@
+(ns webfui.dom
+ (:use [webfui.core :only [core-add-dom-watch core-defdom]]
+ [webfui.plugin.core :only [register-plugin]]
+ [webfui.plugin.form-values :only [form-values]]))
+
+(def add-dom-watch core-add-dom-watch)
+
+(def defdom core-defdom)
+
+(register-plugin (form-values.))
+
@@ -0,0 +1,23 @@
+(ns webfui.dom-manipulation
+ (:use [webfui.html :only [unparse-html]]))
+
+;; This file is for DOM manipulation functions used by both the core of webfui as well as plugins.
+
+(defn path-dom [node]
+ (drop 3
+ (reverse ((fn f [node]
+ (lazy-seq (when node
+ (cons (dec (count (take-while identity (iterate #(.-previousSibling %) node)))) (f (.-parentNode node))))))
+ node))))
+
+(defn select-path-html [html path]
+ (if-let [[cur & more] (seq path)]
+ (recur (nth (.-children html) cur) more)
+ html))
+
+(defn resolve-target [parsed-html target]
+ (let [path (path-dom target)
+ parsed-element (select-path-html parsed-html path)]
+ (unparse-html parsed-element)))
+
+
@@ -0,0 +1,51 @@
+(ns webfui.framework
+ (:use [webfui.dom :only [defdom add-dom-watch]]
+ [webfui.plugin.core :only [register-plugin]]
+ [webfui.plugin.mouse :only [mouse add-mouse-watch]]
+ [webfui.state-patches :only [patch]]
+ [webfui.utilities :only [get-attribute]]))
+
+(register-plugin (mouse.))
+
+(defn state-watcher [dom renderer key state old new]
+ (swap! dom (constantly (renderer new))))
+
+(declare cur-state)
+
+(defn launch-app [state renderer]
+ (let [dom (atom (renderer @state))]
+ (defdom dom)
+ (add-watch state :state-watcher (partial state-watcher dom renderer)))
+ (def cur-state state))
+
+(defn add-dom-watch-helper [id fun]
+ (add-dom-watch id
+ (fn [_ element-new]
+ (swap! cur-state
+ (fn [state]
+ (let [diff (fun state element-new)]
+ (patch state diff)))))))
+
+(def mouse-down-state (atom nil))
+
+(defn add-mouse-watch-helper [id fun optimization]
+ (add-mouse-watch id
+ (fn [element-old element-new points]
+ (swap! mouse-down-state
+ (fn [old]
+ (or old @cur-state)))
+ (reset! cur-state
+ (if (= optimization :incremental)
+ (let [mds @mouse-down-state
+ diff (fun mds element-old element-new (subvec points (max 0 (- (count points) 2))))
+ new-state (patch mds diff)]
+ (reset! mouse-down-state
+ (when (get-attribute element-old :active)
+ new-state))
+ new-state)
+ (let [mds @mouse-down-state
+ diff (fun mds element-old element-new points)]
+ (when-not (get-attribute element-old :active)
+ (reset! mouse-down-state nil))
+ (patch mds diff)))))))
+
@@ -0,0 +1,11 @@
+;*CLJSBUILD-MACRO-FILE*;
+
+(ns webfui.framework.macros)
+
+(defmacro add-dom-watch [id vars & more]
+ `(webfui.framework/add-dom-watch-helper ~id (fn ~vars ~@more)))
+
+(defmacro add-mouse-watch [id vars & more]
+ (if (vector? id)
+ `(webfui.framework/add-mouse-watch-helper ~(first id) (fn ~vars ~@more) ~(second id))
+ `(webfui.framework/add-mouse-watch-helper ~id (fn ~vars ~@more) :full)))
Oops, something went wrong.

0 comments on commit aba4347

Please sign in to comment.