Breaks baseview out of scaffold; adds KVPairs serialization to most models; updates...
authordsc <dsc@less.ly>
Mon, 27 Feb 2012 19:31:37 +0000 (11:31 -0800)
committerdsc <dsc@less.ly>
Mon, 27 Feb 2012 19:31:37 +0000 (11:31 -0800)
lib/baseview.co [new file with mode: 0644]
lib/graph/model.co
lib/graph/view.co
lib/main.co
lib/scaffold/model.co
lib/scaffold/view.co
www/css/layout.styl
www/modules.yaml

diff --git a/lib/baseview.co b/lib/baseview.co
new file mode 100644 (file)
index 0000000..40701ed
--- /dev/null
@@ -0,0 +1,68 @@
+_  = require 'kraken/underscore'
+op = require 'kraken/util/op'
+
+
+BaseView = exports.BaseView = Backbone.View.extend do # {{{
+    # List of methods to bind on initialize; set on subclass
+    __bind__ : []
+    
+    
+    initialize: ->
+        _.bindAll this, ...@__bind__ if @__bind__.length
+        @__super__ = @constructor.__super__
+        
+        @model.view = this
+        @$el.data { @model, view:this }
+        @model.on 'change',  @render, this
+        @model.on 'destroy', @remove, this
+    
+    toTemplateLocals: ->
+        json = {value:v} = @model.toJSON()
+        if _.isArray(v) or _.isObject(v)
+            json.value = JSON.stringify v
+        { $, _, op, @model, view:this } import json
+    
+    $template: (locals={}) ->
+        $ @template @toTemplateLocals() import locals
+    
+    build: ->
+        return this unless @template
+        
+        outer = @$template()
+        @$el.html outer.html()
+            .attr do
+                id    : outer.attr 'id'
+                class : outer.attr('class')
+        
+        
+        this
+    
+    render: ->
+        @build()
+        @trigger 'render', this
+        this
+    
+    hide   : -> @$el.hide();      this
+    show   : -> @$el.show();      this
+    remove : -> @$el.remove();    this
+    clear  : -> @model.destroy(); @remove()
+    
+    
+    # remove : ->
+    #     if (p = @$el.parent()).length
+    #         @$parent or= p
+    #         # @parent_index = p.children().indexOf @$el
+    #     @$el.remove()
+    #     this
+    # 
+    # reparent : (parent=@$parent) ->
+    #     parent = $ parent
+    #     @$el.appendTo parent if parent?.length
+    #     this
+    
+    toString : -> "#{@ctorName}(model=#{@model})"
+
+
+# }}}
+
+
index 125fc4d..405c47e 100644 (file)
@@ -1,5 +1,6 @@
 _ = require 'kraken/underscore'
-{ Field, FieldList, BaseView, FieldView, Scaffold
+{BaseView} = require 'kraken/baseview'
+{ Field, FieldList, FieldView, Scaffold
 } = require 'kraken/scaffold'
 
 
@@ -88,20 +89,56 @@ GraphOption = exports.GraphOption = Field.extend do # {{{
             o[k] = '' if v!?
         o
     
+    toKVPairs: ->
+        key = @get 'name'
+        value = @get 'value'
+        if value?
+            "#{encodeURIComponent key}=#{encodeURIComponent value}"
+        else
+            ''
+    
+
 # }}}
 
 
 GraphOptionList = exports.GraphOptionList = FieldList.extend do # {{{
     ctorName   : 'GraphOptionList'
     model      : GraphOption
-    categories : {}
     
+    /**
+     * Transforms this list into form-encoded KV-pairs, excluding null values and 
+     * @returns {String}
+     */
+    toKVPairs: (keepDefaults=false) ->
+        @models
+            .filter -> it.get('name') and it.getValue()? and (keepDefaults or not it.isDefault())
+            .map -> "#{encodeURIComponent it.get 'name'}=#{encodeURIComponent it.serializeValue()}"
+            .join '&'
     
-    initialize : ->
-        FieldList::initialize ...
-        @categories  = {}
-    
+# }}}
+
+
+/**
+ * Represents a Graph, including its charting options, dataset, annotations, and all
+ * other settings for both its content and presentation.
+ */
+GraphModel = exports.GraphModel = Backbone.Model.extend do # {{{
+    ctorName : 'GraphModel'
+    urlRoot  : '/graphs'
     
+    initialize : ->
+        name = @get 'name'
+        if name and not (@id or @has 'id')
+            @id = @attributes.id = _.underscored name
+    
+    defaults : ->
+        {
+            name    : 'Kraken Graph'
+            dataset : '/data/page_views_by_language.csv'
+            options : {}
+        }
+    
+    toString: -> "#{@ctorName}(id=#{@id}, name=#{@get 'name'}, dataset=#{@get 'dataset'})"
 # }}}
 
 
index 31653f2..5dffbfe 100644 (file)
@@ -1,9 +1,11 @@
 _ = require 'kraken/underscore'
-{ Field, FieldList, BaseView, FieldView, Scaffold
+{BaseView} = require 'kraken/baseview'
+{ Field, FieldList, FieldView, Scaffold
 } = require 'kraken/scaffold'
-{   GraphOption, GraphOptionList, TagSet,
+{   GraphModel, GraphOption, GraphOptionList, TagSet,
 } = require 'kraken/graph/model'
 
+DEBOUNCE_RENDER = exports.DEBOUNCE_RENDER = 20ms
 
 
 /**
@@ -19,11 +21,12 @@ GraphOptionView = exports.GraphOptionView = FieldView.extend do # {{{
     isCollapsed : true
     
     events :
-        'blur .value'                   : 'update'
-        'submit .value'                 : 'update'
-        'click .close'                  : 'toggleCollapsed'
-        'click h3'                      : 'toggleCollapsed'
-        'click .collapsed'              : 'onClick'
+        'blur .value'                        : 'update'
+        'click input[type="checkbox"].value' : 'update'
+        'submit .value'                      : 'update'
+        'click .close'                       : 'toggleCollapsed'
+        'click h3'                           : 'toggleCollapsed'
+        'click .collapsed'                   : 'onClick'
     
     
     update: ->
@@ -65,7 +68,7 @@ GraphOptionsScaffold = exports.GraphOptionsScaffold = Scaffold.extend do # {{{
     
     initialize : ->
         Scaffold::initialize ...
-        @render = _.debounce @render.bind(this), 50
+        @render = _.debounce @render.bind(this), DEBOUNCE_RENDER
     
     render: ->
         # console.log "#this.render() -> .isotope()"
@@ -83,35 +86,14 @@ GraphOptionsScaffold = exports.GraphOptionsScaffold = Scaffold.extend do # {{{
         view.on 'change:collapse render', @render
         view
     
+    toKVPairs: ->
+        @collection.toKVPairs()
+    
 # }}}
 
 
 
 
-/**
- * Represents a Graph, including its charting options, dataset, annotations, and all
- * other settings for both its content and presentation.
- */
-GraphModel = exports.GraphModel = Backbone.Model.extend do # {{{
-    ctorName : 'GraphModel'
-    urlRoot  : '/graphs'
-    
-    initialize : ->
-        name = @get 'name'
-        if name and not (@id or @has 'id')
-            @id = @attributes.id = _.underscored name
-    
-    defaults : ->
-        {
-            name    : 'Kraken Graph'
-            dataset : '/data/page_views_by_language.csv'
-            options : {}
-        }
-    
-    toString: -> "#{@ctorName}(id=#{@id}, name=#{@get 'name'}, dataset=#{@get 'dataset'})"
-# }}}
-
-
 GraphView = exports.GraphView = BaseView.extend do # {{{
     ctorName  : 'GraphView'
     tagName   : 'section'
@@ -124,6 +106,7 @@ GraphView = exports.GraphView = BaseView.extend do # {{{
     
     
     initialize : (o={}) ->
+        @render = _.debounce @render.bind(this), DEBOUNCE_RENDER
         @model or= new GraphModel
         BaseView::initialize ...
         # console.log "#this.initialize!"
@@ -138,9 +121,7 @@ GraphView = exports.GraphView = BaseView.extend do # {{{
         @$el.find 'fieldset' .append @scaffold.el
         @scaffold.collection.reset that if o.graph_spec
         
-        setTimeout do
-            ~> @render()
-            50
+        _.delay @render, DEBOUNCE_RENDER
     
     
     chartOptions: (values) ->
@@ -195,6 +176,10 @@ GraphView = exports.GraphView = BaseView.extend do # {{{
         @render()
         false
     
+    
+    toKVPairs: (keepDefaults=false) ->
+        @scaffold.toKVPairs()
+    
     toString: -> "#{@ctorName}(#{@model})"
 # }}}
 
index 7d6f33b..30dda30 100644 (file)
@@ -1,10 +1,11 @@
-{_, op} = require 'kraken/util'
-{   Field, FieldList, BaseView, FieldView, Scaffold
-}       = require 'kraken/scaffold'
+{_, op}    = require 'kraken/util'
+{BaseView} = require 'kraken/baseview'
+{   Field, FieldList, FieldView, Scaffold
+}          = require 'kraken/scaffold'
 {   GraphView, GraphModel, TagSet,
     GraphOption, GraphOptionList, GraphOptionView,
     GraphOptionsScaffold,
-}       = require 'kraken/graph'
+}          = require 'kraken/graph'
 
 
 root = do -> this
index 412acfd..825995e 100644 (file)
@@ -1,6 +1,5 @@
 _    = require 'kraken/underscore'
 op   = require 'kraken/util/op'
-Hash = require 'hashish'
 
 
 
@@ -29,6 +28,7 @@ Field = exports.Field = Backbone.Model.extend do # {{{
         }
     
     
+    /* * *  Parsers  * * */
     
     getParser: (type) ->
         # XXX: handle 'or' by returning an array of parsers?
@@ -66,6 +66,17 @@ Field = exports.Field = Backbone.Model.extend do # {{{
             null
     
     
+    /* * * Serializers * * */
+    serializeValue: ->
+        v = @getValue()
+        if v!?
+            v = ''
+        else if _.isArray(v) or _.isObject(v)
+            v = JSON.stringify v
+        String v
+    
+    
+    /* * * Value Accessors * * */
     getValue: (def) ->
         @getParser() @get 'value', def
     
@@ -88,6 +99,14 @@ Field = exports.Field = Backbone.Model.extend do # {{{
         {id:@id} import do
             _.clone(@attributes) import { value:@getValue(), def:@get('default') }
     
+    toKVPairs: ->
+        key   = @get 'name'
+        value = @get 'value'
+        if value?
+            "#{encodeURIComponent key}=#{encodeURIComponent value}"
+        else
+            ''
+    
     toString: -> "(#{@id}: #{@get 'value'})"
 # }}}
 
@@ -105,6 +124,15 @@ FieldList = exports.FieldList = Backbone.Collection.extend do # {{{
             @models.filter -> not it.isDefault()
             -> [ it.get('name'), it.getValue() ]
     
+    toJSON: ->
+        @values()
+    
+    toKVPairs: ->
+        @models
+            .filter -> it.get('name') and it.getValue()?
+            .map -> "#{encodeURIComponent it.id}=#{encodeURIComponent it.get 'value'}"
+            .join '&'
+    
     toString: -> "#{@ctorName}(length=#{@length})"
 # }}}
 
index b48e1f5..0e7a605 100644 (file)
@@ -1,74 +1,8 @@
-_  = require 'kraken/underscore'
-op = require 'kraken/util/op'
+_          = require 'kraken/underscore'
+op         = require 'kraken/util/op'
+{BaseView} = require 'kraken/baseview'
 { Field, FieldList,
-}  = require 'kraken/scaffold/model'
-
-
-### Views
-
-BaseView = exports.BaseView = Backbone.View.extend do # {{{
-    # List of methods to bind on initialize; set on subclass
-    __bind__ : []
-    
-    
-    initialize: ->
-        _.bindAll this, ...@__bind__ if @__bind__.length
-        @__super__ = @constructor.__super__
-        
-        @model.view = this
-        @$el.data { @model, view:this }
-        @model.on 'change',  @render, this
-        @model.on 'destroy', @remove, this
-    
-    toTemplateLocals: ->
-        json = {value:v} = @model.toJSON()
-        if _.isArray(v) or _.isObject(v)
-            json.value = JSON.stringify v
-        { $, _, op, @model, view:this } import json
-    
-    $template: (locals={}) ->
-        $ @template @toTemplateLocals() import locals
-    
-    build: ->
-        return this unless @template
-        
-        outer = @$template()
-        @$el.html outer.html()
-            .attr do
-                id    : outer.attr 'id'
-                class : outer.attr('class')
-        
-        
-        this
-    
-    render: ->
-        @build()
-        @trigger 'render', this
-        this
-    
-    hide   : -> @$el.hide();      this
-    show   : -> @$el.show();      this
-    remove : -> @$el.remove();    this
-    clear  : -> @model.destroy(); @remove()
-    
-    
-    # remove : ->
-    #     if (p = @$el.parent()).length
-    #         @$parent or= p
-    #         # @parent_index = p.children().indexOf @$el
-    #     @$el.remove()
-    #     this
-    # 
-    # reparent : (parent=@$parent) ->
-    #     parent = $ parent
-    #     @$el.appendTo parent if parent?.length
-    #     this
-    
-    toString : -> "#{@ctorName}(model=#{@model})"
-
-
-# }}}
-
+}          = require 'kraken/scaffold/model'
 
 
 FieldView = exports.FieldView = BaseView.extend do # {{{
index 39cffae..69f28cd 100644 (file)
@@ -9,14 +9,16 @@ header, footer, #content
 
 #content
     z-index 10
+    padding 1em
     min-height 100%
     background-color $page_bgcolor
     box-shadow 0px 0px 6px 2px rgba(0,0,0,0.4)
     
     & > .inner
         position relative
-        width 80%
-        margin 0 auto
+        // width 80%
+        // min-width 960px
+        // margin 0 auto
     
     // .spacer offsets #content to pad for header
     .spacer
index 1e0b1b7..4a075f7 100644 (file)
@@ -35,6 +35,7 @@ all:
                 - op
                 - backbone
                 - index
+            - baseview
             - template:
                 - graph.jade
                 - graph-option.jade