Step 1 in converting to a Backbone-based website

This commit is contained in:
Andrew Miner
2014-12-22 16:36:04 -08:00
parent dc9fd0de07
commit 16832e02dd
95 changed files with 41866 additions and 17 deletions
+28
View File
@@ -0,0 +1,28 @@
###
# crafting_guide - base_model.coffee
#
# Copyright (c) 2014 by Redwood Labs
# All rights reserved.
###
########################################################################################################################
module.exports = class BaseModel extends Backbone.Model
constructor: (attributes={}, options={})->
super attributes, options
makeGetter = (name)-> return -> @get name
makeSetter = (name)-> return (value)-> @set name, value
for name in _.keys attributes
continue if name is 'id'
Object.defineProperty this, name, get:makeGetter(name), set:makeSetter(name)
# Backbone.Model Overrides #####################################################################
sync: -> # do nothing
# Object Overrides #############################################################################
toString: ->
return "#{@constructor.name} (#{@cid})"
+19
View File
@@ -0,0 +1,19 @@
###
# Crafting Guide - item.coffee
#
# Copyright (c) 2014 by Redwood Labs
# All rights reserved.
###
BaseModel = require './base_model'
########################################################################################################################
module.exports = class Item extends BaseModel
constructor: (attributes={}, options={})->
attributes.name ?= ''
attributes.quantity ?= 1
super attributes, options
# Public Methods ###############################################################################
+17
View File
@@ -0,0 +1,17 @@
###
# Crafting Guide - landing_page.coffee
#
# Copyright (c) 2014 by Redwood Labs
# All rights reserved.
###
BaseModel = require './base_model'
RecipeCatalog = require './recipe_catalog'
########################################################################################################################
module.exports = class LandingPage extends BaseModel
constructor: (attributes={}, options={})->
attributes.catalog ?= new RecipeCatalog
super attributes, options
@@ -0,0 +1,81 @@
###
# Crafting Guide - v1.coffee
#
# Copyright (c) 2014 by Redwood Labs
# All rights reserved.
###
Item = require '../item'
Recipe = require '../recipe'
RecipeBook = require '../recipe_book'
########################################################################################################################
module.exports = class V1
constructor: ->
@_errorLocation = 'the header information'
parse: (data)->
return @_parseRecipeBook data
# Private Methods ##############################################################################
_parseRecipeBook: (data)->
if not data? then throw new Error 'recipe book data is missing'
if not data.version? then throw new Error 'version is required'
if not data.mod_name? then throw new Error 'mod_name is required'
if not data.mod_version? then throw new Error 'mod_version is required'
if not _.isArray(data.recipes) then throw new Error 'recipes must be an array'
book = new RecipeBook version:data.version, modName:data.mod_name, modVersion:data.mod_version
book.description = data.description or ''
for index in [0...data.recipes.length]
@_errorLocation = "recipe #{index + 1}"
recipeData = data.recipes[index]
book.recipes.push @_parseRecipe recipeData
return book
_parseRecipe: (data, options={})->
if not data? then throw new Error "recipe data is missing for #{@_errorLocation}"
if not data.output? then throw new Error "#{@_errorLocation} is missing output"
if not data.input? then throw new Error "#{@_errorLocation} is missing input"
output = @_parseItemList data.output, field:'output', canBeEmpty:false
@_errorLocation = "recipe for output[0].name"
data.tools ?= []
input = @_parseItemList data.input, field:'input', canBeEmpty:false
tools = @_parseItemList data.tools, field:'tools', canBeEmpty:true
return new Recipe input:input, output:output, tools:tools
_parseItemList: (data, options={})->
if not data? then throw new Error "#{@_errorLocation} must have an #{options.field} field"
if not _.isArray(data) then data = [data]
if data.length is 0 and not options.canBeEmpty
throw new Error "#{options.field} for #{@_errorLocation} cannot be empty"
result = []
for index in [0...data.length]
itemData = data[index]
result.push @_parseItem itemData, field:options.field, index:index
return result
_parseItem: (data, options={})->
errorBase = "#{options.field} element #{options.index} for #{@_errorLocation}"
if not data? then throw new Error "#{errorBase} is missing"
if _.isString(data) then data = [1, data]
if not _.isArray(data) then throw new Error "#{errorBase} must be an array"
if data.length is 1 then data.unshift 1
if data.length isnt 2 then throw new Error "#{errorBase} must have at least one element"
if not _.isNumber(data[0]) then throw new Error "#{errorBase} must start with a number"
return new Item quantity:data[0], name:data[1]
+17
View File
@@ -0,0 +1,17 @@
###
# Crafting Guide - recipe.coffee
#
# Copyright (c) 2014 by Redwood Labs
# All rights reserved.
###
BaseModel = require './base_model'
########################################################################################################################
module.exports = class Recipe extends BaseModel
constructor: (attributes={}, options={})->
super attributes, options
Object.defineProperty this, 'name', get:-> @output[0].name
+38
View File
@@ -0,0 +1,38 @@
###
# Crafting Guide - recipe_book.coffee
#
# Copyright (c) 2014 by Redwood Labs
# All rights reserved.
###
BaseModel = require './base_model'
########################################################################################################################
module.exports = class RecipeBook extends BaseModel
constructor: (attributes={}, options={})->
if _.isEmpty(attributes.modName) then throw new Error 'modName cannot be empty'
if _.isEmpty(attributes.modVersion) then throw new Error 'modVersion cannot be empty'
attributes.description ?= ''
attributes.recipes ?= []
super attributes, options
# Public Methods ###############################################################################
getRecipes: (name)->
result = []
for recipe in @recipes
if recipe.name is name
result.push recipe
return result
# Object Overrides #############################################################################
toString: ->
return "RecipeBook (#{@cid}) {
modName:#{@modName},
modVersion:#{@modVersion},
recipes:#{@recipes.length} items}"
@@ -0,0 +1,26 @@
###
# Crafting Guide - recipe_book_parser.coffee
#
# Copyright (c) 2014 by Redwood Labs
# All rights reserved.
###
V1 = require './parser_versions/v1'
########################################################################################################################
module.exports = class RecipeBookParser
constructor: ->
@_parsers =
'1': new V1
parse: (data)->
if not data? then throw new Error 'recipe book data is missing'
if not data.version? then throw new Error 'version is required'
parser = @_parsers["#{data.version}"]
if not parser?
throw new Error "cannot parse version #{data.version} recipe books"
return parser.parse data
+54
View File
@@ -0,0 +1,54 @@
###
# Crafting Guide - recipe_catalog.coffee
#
# Copyright (c) 2014 by Redwood Labs
# All rights reserved.
###
BaseModel = require './base_model'
{Event} = require '../constants'
RecipeBookParser = require './recipe_book_parser'
########################################################################################################################
module.exports = class RecipeCatalog extends BaseModel
constructor: (attributes={}, options={})->
attributes.books ?= []
super attributes, options
@_parser = new RecipeBookParser
# Public Methods ###############################################################################
loadBook: (url)->
@trigger Event.book.load.started, this, url
$.ajax
url: url
dataType: 'json'
success: (data, status, xhr)=> @onBookLoaded(data, status, xhr)
error: (xhr, status, error)=> @onBookLoadFailed(error, status, xhr)
# Event Methods ################################################################################
onBookLoaded: (data, status, xhr)->
try
@books.push @_parser.parse data
_(@books).sortBy 'name'
logger.info "loaded recipe book: #{book}"
@trigger Event.book.load.succeeded, this, book
@trigger Event.book.load.finished, this
catch e
@onBookLoadFailed error, status, xhr
onBookLoadFailed: (error, status, xhr)->
logger.error "failed to load recipe book: #{error}"
@trigger Event.book.load.failed, this, error.message
@trigger Event.book.load.finished, this
# Object Overrides #############################################################################
toString: ->
return "RecipeCatalog (#{@cid}) {books:#{@books.length} items}"