From af15bf78973c3a25d8f672131f438ec41acb3866 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Sat, 26 Sep 2015 15:40:39 -0700 Subject: [PATCH 01/11] Refactor dataState to state --- src/Collection.coffee | 6 ++-- src/Model.coffee | 10 +++--- src/init.coffee | 6 ++-- test/app/frimfram/BaseCollection.spec.coffee | 28 +++++++-------- test/app/frimfram/BaseModel.spec.coffee | 36 ++++++++++---------- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/Collection.coffee b/src/Collection.coffee index 9e6e83b..621fe07 100644 --- a/src/Collection.coffee +++ b/src/Collection.coffee @@ -1,6 +1,6 @@ class Collection extends Backbone.Collection - dataState: 'standby' # or 'fetching' + state: 'standby' # or 'fetching' constructor: (models, options) -> super(models, options) @@ -8,7 +8,7 @@ class Collection extends Backbone.Collection @defaultFetchData = options.defaultFetchData fetch: (options) -> - @dataState = 'fetching' + @state = 'fetching' options = FrimFram.wrapBackboneRequestCallbacks(options) if @defaultFetchData options.data ?= {} @@ -18,4 +18,4 @@ class Collection extends Backbone.Collection # At some later point, create save, patch, destroy methods? -FrimFram.BaseCollection = FrimFram.Collection = Collection \ No newline at end of file +FrimFram.BaseCollection = FrimFram.Collection = Collection diff --git a/src/Model.coffee b/src/Model.coffee index e6229fc..d729a47 100644 --- a/src/Model.coffee +++ b/src/Model.coffee @@ -1,6 +1,6 @@ class Model extends Backbone.Model - dataState: 'standby' # or 'fetching', 'saving' + state: 'standby' # or 'fetching', 'saving' created: -> new Date(parseInt(@id.substring(0, 8), 16) * 1000) @@ -8,7 +8,7 @@ class Model extends Backbone.Model super(attributes, options) @on 'add', @onAdded, @ - onAdded: -> @dataState = 'standby' + onAdded: -> @state = 'standby' schema: -> s = @constructor.schema @@ -31,7 +31,7 @@ class Model extends Backbone.Model return Backbone.Model.prototype.get.apply(@, [attr]) set: (attributes, options) -> - if (@dataState isnt 'standby') and not (options.xhr or options.headers) + if (@state isnt 'standby') and not (options.xhr or options.headers) throw new Error('Cannot set while fetching or saving.') if _.isString(attributes) @@ -68,12 +68,12 @@ class Model extends Backbone.Model save: (attrs, options) -> options = FrimFram.wrapBackboneRequestCallbacks(options) result = super(attrs, options) - @dataState = 'saving' if result + @state = 'saving' if result return result fetch: (options) -> options = FrimFram.wrapBackboneRequestCallbacks(options) - @dataState = 'fetching' + @state = 'fetching' return super(options) diff --git a/src/init.coffee b/src/init.coffee index cadc6cb..d74994b 100644 --- a/src/init.coffee +++ b/src/init.coffee @@ -5,13 +5,13 @@ window.FrimFram = { options ?= {} originalOptions = _.clone(options) options.success = (model) -> - model.dataState = 'standby' + model.state = 'standby' originalOptions.success?(arguments...) options.error = (model) -> - model.dataState = 'standby' + model.state = 'standby' originalOptions.error?(arguments...) options.complete = (model) -> - model.dataState = 'standby' + model.state = 'standby' originalOptions.complete?(arguments...) return options } diff --git a/test/app/frimfram/BaseCollection.spec.coffee b/test/app/frimfram/BaseCollection.spec.coffee index b30a8af..8e6d01d 100644 --- a/test/app/frimfram/BaseCollection.spec.coffee +++ b/test/app/frimfram/BaseCollection.spec.coffee @@ -1,21 +1,21 @@ describe 'Collection', -> - describe 'dataState', -> + describe 'state', -> it 'is "fetching" while the collection is being fetched, "standby" otherwise', -> Collection = FrimFram.Collection.extend({ url: '/db/thingies' }) collection = new Collection() - expect(collection.dataState).toBe("standby") + expect(collection.state).toBe("standby") collection.fetch() - expect(collection.dataState).toBe("fetching") + expect(collection.state).toBe("fetching") request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 200, responseText: '[]'}) - expect(collection.dataState).toBe("standby") + expect(collection.state).toBe("standby") collection.fetch() - expect(collection.dataState).toBe("fetching") + expect(collection.state).toBe("fetching") request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 404, responseText: '{}'}) - expect(collection.dataState).toBe("standby") + expect(collection.state).toBe("standby") it 'is set before any given success or error callback is called', -> Collection = FrimFram.Collection.extend({ @@ -26,13 +26,13 @@ describe 'Collection', -> collection.fetch({ success: -> calls += 1 - expect(collection.dataState).toBe("standby") + expect(collection.state).toBe("standby") }) jasmine.Ajax.requests.mostRecent().respondWith({status: 200, responseText: '[]'}) collection.fetch({ error: -> calls += 1 - expect(collection.dataState).toBe("standby") + expect(collection.state).toBe("standby") }) jasmine.Ajax.requests.mostRecent().respondWith({status: 404, responseText: '[]'}) expect(calls).toBe(2) @@ -60,10 +60,10 @@ describe 'Collection', -> expect(_(request.url).contains('foo=BAR')).toBe(true) describe 'fetch(options)', -> - it 'calls options.success and options.error after dataState is back to "standby"', -> + it 'calls options.success and options.error after state is back to "standby"', -> count = 0 callback = (c) -> - expect(c.dataState).toBe('standby') + expect(c.state).toBe('standby') count += 1 Collection = FrimFram.Collection.extend({ @@ -71,20 +71,20 @@ describe 'Collection', -> }) c = new Collection() - expect(c.dataState).toBe('standby') + expect(c.state).toBe('standby') c.fetch({ success: callback }) - expect(c.dataState).toBe('fetching') + expect(c.state).toBe('fetching') request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 200, responseText: '{}'}) c.fetch({ complete: callback }) - expect(c.dataState).toBe('fetching') + expect(c.state).toBe('fetching') request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 200, responseText: '{}'}) c.fetch({ error: callback }) - expect(c.dataState).toBe('fetching') + expect(c.state).toBe('fetching') request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 404, responseText: '{}'}) diff --git a/test/app/frimfram/BaseModel.spec.coffee b/test/app/frimfram/BaseModel.spec.coffee index 00e4d31..b12a467 100644 --- a/test/app/frimfram/BaseModel.spec.coffee +++ b/test/app/frimfram/BaseModel.spec.coffee @@ -19,20 +19,20 @@ class BlandModel extends FrimFram.Model describe 'Model', -> - describe '.dataState', -> + describe '.state', -> it 'is "fetching" while the model is being fetched, "saving" while the model is being saved, and "standby" otherwise', -> b = new BlandModel({}) - expect(b.dataState).toBe("standby") + expect(b.state).toBe("standby") b.fetch() - expect(b.dataState).toBe("fetching") + expect(b.state).toBe("fetching") request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 200, responseText: '{}'}) - expect(b.dataState).toBe("standby") + expect(b.state).toBe("standby") b.fetch() - expect(b.dataState).toBe("fetching") + expect(b.state).toBe("fetching") request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 404, responseText: '{}'}) - expect(b.dataState).toBe("standby") + expect(b.state).toBe("standby") describe '.get(attribute)', -> it 'can accept nested properties', -> @@ -73,54 +73,54 @@ describe 'Model', -> request = jasmine.Ajax.requests.mostRecent() expect(request).toBeUndefined() - it 'calls options.success and options.error after dataState is back to "standby"', -> + it 'calls options.success and options.error after state is back to "standby"', -> count = 0 callback = (model) -> - expect(model.dataState).toBe('standby') + expect(model.state).toBe('standby') count += 1 b = new BlandModel({_id:'1'}) - expect(b.dataState).toBe('standby') + expect(b.state).toBe('standby') b.save(null, { success: callback }) - expect(b.dataState).toBe('saving') + expect(b.state).toBe('saving') request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 200, responseText: '{}'}) b.save(null, { complete: callback }) - expect(b.dataState).toBe('saving') + expect(b.state).toBe('saving') request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 200, responseText: '{}'}) b.save(null, { error: callback }) - expect(b.dataState).toBe('saving') + expect(b.state).toBe('saving') request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 404, responseText: '{}'}) expect(count).toBe(3) describe 'fetch(options)', -> - it 'calls options.success and options.error after dataState is back to "standby"', -> + it 'calls options.success and options.error after state is back to "standby"', -> count = 0 callback = (model) -> - expect(model.dataState).toBe('standby') + expect(model.state).toBe('standby') count += 1 b = new BlandModel({_id:1}) - expect(b.dataState).toBe('standby') + expect(b.state).toBe('standby') b.fetch({ success: callback }) - expect(b.dataState).toBe('fetching') + expect(b.state).toBe('fetching') request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 200, responseText: '{}'}) b.fetch({ complete: callback }) - expect(b.dataState).toBe('fetching') + expect(b.state).toBe('fetching') request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 200, responseText: '{}'}) b.fetch({ error: callback }) - expect(b.dataState).toBe('fetching') + expect(b.state).toBe('fetching') request = jasmine.Ajax.requests.mostRecent() request.respondWith({status: 404, responseText: '{}'}) From 96a566095706610c96e00e67471589d13cef12e6 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Sat, 26 Sep 2015 15:48:57 -0700 Subject: [PATCH 02/11] Rename test files --- .../{BaseCollection.spec.coffee => Collection.spec.coffee} | 0 test/app/frimfram/{BaseModel.spec.coffee => Model.spec.coffee} | 0 test/app/frimfram/{BaseView.spec.coffee => View.spec.coffee} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/app/frimfram/{BaseCollection.spec.coffee => Collection.spec.coffee} (100%) rename test/app/frimfram/{BaseModel.spec.coffee => Model.spec.coffee} (100%) rename test/app/frimfram/{BaseView.spec.coffee => View.spec.coffee} (100%) diff --git a/test/app/frimfram/BaseCollection.spec.coffee b/test/app/frimfram/Collection.spec.coffee similarity index 100% rename from test/app/frimfram/BaseCollection.spec.coffee rename to test/app/frimfram/Collection.spec.coffee diff --git a/test/app/frimfram/BaseModel.spec.coffee b/test/app/frimfram/Model.spec.coffee similarity index 100% rename from test/app/frimfram/BaseModel.spec.coffee rename to test/app/frimfram/Model.spec.coffee diff --git a/test/app/frimfram/BaseView.spec.coffee b/test/app/frimfram/View.spec.coffee similarity index 100% rename from test/app/frimfram/BaseView.spec.coffee rename to test/app/frimfram/View.spec.coffee From fcc820af0fce3c643345a2592b08c55e32cc9677 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Sat, 26 Sep 2015 15:49:14 -0700 Subject: [PATCH 03/11] Add view to context in initContext --- src/View.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/View.coffee b/src/View.coffee index 27a84f5..93d5923 100644 --- a/src/View.coffee +++ b/src/View.coffee @@ -37,7 +37,7 @@ class View extends Backbone.View if _.isString(@template) then @template else @template(@getContext()) initContext: (pickPredicate) -> - context = {} + context = { view: @ } context.pathname = document.location.pathname # ex. '/play/level' context = _.defaults context, View.globalContext context = _.extend context, _.pick(@, pickPredicate, @) if pickPredicate From 154e1c82eda5bfd68520374d72e7659aadd67620 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Sat, 26 Sep 2015 15:50:13 -0700 Subject: [PATCH 04/11] Add test for new view property in context --- test/app/frimfram/View.spec.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/app/frimfram/View.spec.coffee b/test/app/frimfram/View.spec.coffee index 3e3eeae..75cbe19 100644 --- a/test/app/frimfram/View.spec.coffee +++ b/test/app/frimfram/View.spec.coffee @@ -112,6 +112,10 @@ describe 'View', -> FrimFram.View.extendGlobalContext({'someLib':someLib}) expect(view.initContext().someLib).toBe(someLib) + it 'includes the property "view", which is the View itself', -> + view = new FrimFram.View() + expect(view.initContext().view).toBe(view) + describe '.getContext()', -> it 'proxies to .initContext() by default', -> @@ -308,4 +312,4 @@ describe 'View', -> it 'clears all properties from the object, except for "destroyed" and "destroy"', -> view = new FrimFram.View() view.destroy() - expect(_.isEqual(_.keys(view), ['destroyed', 'destroy'])).toBe(true) \ No newline at end of file + expect(_.isEqual(_.keys(view), ['destroyed', 'destroy'])).toBe(true) From 0603ab089a8cc83f2d4242fef2bd7c4f361db572 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Sat, 26 Sep 2015 16:37:42 -0700 Subject: [PATCH 05/11] Fix typo --- test/app/frimfram/View.spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/app/frimfram/View.spec.coffee b/test/app/frimfram/View.spec.coffee index 75cbe19..7c09f16 100644 --- a/test/app/frimfram/View.spec.coffee +++ b/test/app/frimfram/View.spec.coffee @@ -73,7 +73,7 @@ describe 'View', -> expect(view.$el.find('#foo').text()).toBe('2') expect(view.$el.find('#bar').text()).toBe('1') - it 'handles selectors with multiple target', -> + it 'handles selectors with multiple targets', -> View = FrimFram.View.extend({ template: (c) -> "
#{c.foo}
#{c.bar}
" getContext: -> @initContext(['foo', 'bar']) From 656fe9db94db33e6a926890a62d5437f0efbbdf3 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Sat, 26 Sep 2015 16:38:23 -0700 Subject: [PATCH 06/11] Trying minimal server config --- app/templates/home-view.jade | 2 +- bin/db.sh | 1 + bin/dev.sh | 1 + bin/ff-brunch | 18 -------- bin/ff-client-test-runner | 12 ----- bin/ff-dev-server | 11 ----- bin/ff-mongodb | 89 ------------------------------------ bin/ff-server-test-runner | 9 ---- config.coffee | 6 +-- 9 files changed, 6 insertions(+), 143 deletions(-) create mode 100755 bin/db.sh create mode 100755 bin/dev.sh delete mode 100755 bin/ff-brunch delete mode 100755 bin/ff-client-test-runner delete mode 100755 bin/ff-dev-server delete mode 100755 bin/ff-mongodb delete mode 100755 bin/ff-server-test-runner diff --git a/app/templates/home-view.jade b/app/templates/home-view.jade index 47abbd3..0ef47b5 100644 --- a/app/templates/home-view.jade +++ b/app/templates/home-view.jade @@ -9,4 +9,4 @@ block content li.list-group-item a(href="/test/client") Client Tests li.list-group-item - a(href="/test/server") Server Tests \ No newline at end of file + a(href="/test/server") Server Tests diff --git a/bin/db.sh b/bin/db.sh new file mode 100755 index 0000000..3790be0 --- /dev/null +++ b/bin/db.sh @@ -0,0 +1 @@ +mongod --dbpath mongo diff --git a/bin/dev.sh b/bin/dev.sh new file mode 100755 index 0000000..df61852 --- /dev/null +++ b/bin/dev.sh @@ -0,0 +1 @@ +./node_modules/.bin/brunch watch --server diff --git a/bin/ff-brunch b/bin/ff-brunch deleted file mode 100755 index dccd321..0000000 --- a/bin/ff-brunch +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/python - -from subprocess import call -import subprocess -import os -import time -import sys - -current_directory = os.path.dirname(os.path.realpath(sys.argv[0])) -coco_path = os.getenv("COCO_DIR", os.path.join(current_directory,os.pardir)) -brunch_path = coco_path + os.sep + "node_modules" + os.sep + ".bin" + os.sep + "brunch" -subprocess.Popen("ulimit -n 10000", shell=True) - -while True: - print("Starting brunch. After the first compile, it'll keep running and watch for changes.") - call(brunch_path + " w",shell=True,cwd=coco_path) - print("Brunch crashed. Press control+C within 1 second to quit.") - time.sleep(1) diff --git a/bin/ff-client-test-runner b/bin/ff-client-test-runner deleted file mode 100755 index 6c90569..0000000 --- a/bin/ff-client-test-runner +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -# full script path -_scriptDir="$(cd "$(dirname "$0")" && pwd -P)" - -sleep 5 -cd $_scriptDir -cd ../ -until node_modules/karma/bin/karma start; do - echo "Karma crashed with exit code $?. Respawning.." >&2 - sleep 1 -done diff --git a/bin/ff-dev-server b/bin/ff-dev-server deleted file mode 100755 index 8e0eb96..0000000 --- a/bin/ff-dev-server +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/python -from subprocess import call -import os -import sys - -current_directory = os.path.dirname(os.path.realpath(sys.argv[0])) -coco_path = os.getenv("COCO_DIR",os.path.join(current_directory,os.pardir)) -nodemon_path = coco_path + os.sep + "node_modules" + os.sep + ".bin" + os.sep + "nodemon" - -call(nodemon_path + " . -e \"coffee,js\" --watch server --watch app" + os.sep + "schemas",shell=True,cwd=coco_path) - diff --git a/bin/ff-mongodb b/bin/ff-mongodb deleted file mode 100755 index 6bc2cd3..0000000 --- a/bin/ff-mongodb +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/python - -from subprocess import call -import os -import sys -import subprocess - - -# copied straight from the python 3 standard library -def which(cmd, mode=os.F_OK | os.X_OK, path=None): - """Given a command, mode, and a PATH string, return the path which - conforms to the given mode on the PATH, or None if there is no such - file. - - `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result - of os.environ.get("PATH"), or can be overridden with a custom search - path. - - """ - # Check that a given file can be accessed with the correct mode. - # Additionally check that `file` is not a directory, as on Windows - # directories pass the os.access check. - def _access_check(fn, mode): - return (os.path.exists(fn) and os.access(fn, mode) - and not os.path.isdir(fn)) - - # If we're given a path with a directory part, look it up directly rather - # than referring to PATH directories. This includes checking relative to the - # current directory, e.g. ./script - if os.path.dirname(cmd): - if _access_check(cmd, mode): - return cmd - return None - - if path is None: - path = os.environ.get("PATH", os.defpath) - if not path: - return None - path = path.split(os.pathsep) - - if sys.platform == "win32": - # The current directory takes precedence on Windows. - if not os.curdir in path: - path.insert(0, os.curdir) - - # PATHEXT is necessary to check on Windows. - pathext = os.environ.get("PATHEXT", "").split(os.pathsep) - # See if the given file matches any of the expected path extensions. - # This will allow us to short circuit when given "python.exe". - # If it does match, only test that one, otherwise we have to try - # others. - if any(cmd.lower().endswith(ext.lower()) for ext in pathext): - files = [cmd] - else: - files = [cmd + ext for ext in pathext] - else: - # On other platforms you don't have things like PATHEXT to tell you - # what file suffixes are executable, so just pass on cmd as-is. - files = [cmd] - - seen = set() - for dir in path: - normdir = os.path.normcase(dir) - if not normdir in seen: - seen.add(normdir) - for thefile in files: - name = os.path.join(dir, thefile) - if _access_check(name, mode): - return name - return None - - -current_directory = os.path.dirname(os.path.realpath(sys.argv[0])) -mongo_executable = "mongod" -mongo_directory = current_directory + os.sep + u"mongo" -if not mongo_executable: - mongo_executable = os.environ.get("FRIMFRAM_MONGOD_PATH",mongo_directory + os.sep + u"mongod") - if not os.path.exists(mongo_executable): - raise EnvironmentError("Mongo 2.6.4 executable not found.") - print("Using mongo executable: " + str(mongo_executable)) -mongo_db_path = os.path.abspath(os.path.join(current_directory,os.pardir)) + os.sep + u"mongo" -if not os.path.exists(mongo_db_path): - os.mkdir(mongo_db_path) -mongo_arguments = [mongo_executable + u" --setParameter textSearchEnabled=true --dbpath=" + mongo_db_path] - -if 'fork' in sys.argv: mongo_arguments[0] += " --fork --logpath ./mongodb.log" - -call(mongo_arguments,shell=True) - diff --git a/bin/ff-server-test-runner b/bin/ff-server-test-runner deleted file mode 100755 index cba1e8c..0000000 --- a/bin/ff-server-test-runner +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# full script path -_scriptDir="$(cd "$(dirname "$0")" && pwd -P)" - -cd $_scriptDir -cd ../ - -node_modules/.bin/nodemon ./test/run-server-tests.js --ext ".coffee|.js" --watch server --watch server_config.js --watch server_setup.coffee --watch app/schemas --watch test \ No newline at end of file diff --git a/config.coffee b/config.coffee index 941f999..4a1bca7 100644 --- a/config.coffee +++ b/config.coffee @@ -55,10 +55,10 @@ exports.config = framework: 'backbone' - plugins: - autoReload: - delay: 300 + server: + command: 'node_modules/.bin/nodemon . -e "coffee,js" --watch server --watch app/schemas' + plugins: coffeelint: pattern: /^app\/.*\.coffee$/ options: From c3302d9b2e786b310fadea9b26b54c5c419d36ee Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Mon, 28 Sep 2015 08:23:15 -0700 Subject: [PATCH 07/11] Remove User model --- app/models/User.coffee | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 app/models/User.coffee diff --git a/app/models/User.coffee b/app/models/User.coffee deleted file mode 100644 index 77d7f4e..0000000 --- a/app/models/User.coffee +++ /dev/null @@ -1,6 +0,0 @@ -class User extends FrimFram.Model - @className: 'User' - @schema: 'http://my.site/schemas#user' - urlRoot: '/db/user' - -module.exports = User \ No newline at end of file From ac0e40948cf791c830cbbe8ab3f70fba61da96f5 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Mon, 28 Sep 2015 08:24:38 -0700 Subject: [PATCH 08/11] Rename ModalView to Modal --- src/Modal.coffee | 43 +++++++++++++++++++++++++ src/ModalView.coffee | 39 ---------------------- test/app/frimfram/ModalView.spec.coffee | 42 ++++++++++++------------ 3 files changed, 64 insertions(+), 60 deletions(-) create mode 100644 src/Modal.coffee delete mode 100644 src/ModalView.coffee diff --git a/src/Modal.coffee b/src/Modal.coffee new file mode 100644 index 0000000..0922d21 --- /dev/null +++ b/src/Modal.coffee @@ -0,0 +1,43 @@ +class Modal extends FrimFram.View + @visibleModal: null + + className: 'modal fade' + destroyOnHidden: true + + onRender: -> + super() + + # proxy Bootstrap events to Backbone View events + modal = @ + @$el.on 'show.bs.modal', (event) -> + modal.trigger 'show', event + @$el.on 'shown.bs.modal', (event) -> + modal.trigger 'shown', event + modal.onInsert() + @$el.on 'hide.bs.modal', (event) -> + modal.trigger 'hide', event + @$el.on 'hidden.bs.modal', (event) -> + modal.trigger 'hidden', event + modal.onHidden() + @$el.on 'loaded.bs.modal', (event) -> + modal.trigger 'loaded', event + + hide: (fast) -> + @$el.removeClass('fade') if fast + @$el.modal('hide') + + show: (fast) -> + Modal.visibleModal?.hide(true) + @render() + @$el.removeClass('fade') if fast + $('body').append @$el + @$el.modal('show') + Modal.visibleModal = @ + + toggle: -> @$el.modal('toggle') + + onHidden: -> + Modal.visibleModal = null if Modal.visibleModal is @ + @destroy() if @destroyOnHidden + +FrimFram.Modal = Modal diff --git a/src/ModalView.coffee b/src/ModalView.coffee deleted file mode 100644 index e2bcf2d..0000000 --- a/src/ModalView.coffee +++ /dev/null @@ -1,39 +0,0 @@ -class ModalView extends FrimFram.View - @visibleModal: null - - className: 'modal fade' - destroyOnHidden: true - - onRender: -> - super() - - # proxy Bootstrap events to Backbone View events - modal = @ - @$el.on 'show.bs.modal', -> modal.trigger 'show' - @$el.on 'shown.bs.modal', -> - modal.onInsert() - modal.trigger 'shown' - @$el.on 'hide.bs.modal', -> modal.trigger 'hide' - @$el.on 'hidden.bs.modal', -> modal.onHidden() - @$el.on 'loaded.bs.modal', -> modal.trigger 'loaded' - - hide: (fast) -> - @$el.removeClass('fade') if fast - @$el.modal('hide') - - show: (fast) -> - ModalView.visibleModal?.hide(true) - @render() - @$el.removeClass('fade') if fast - $('body').append @$el - @$el.modal('show') - ModalView.visibleModal = @ - - toggle: -> @$el.modal('toggle') - - onHidden: -> - ModalView.visibleModal = null if ModalView.visibleModal is @ - @trigger 'hidden' - @destroy() if @destroyOnHidden - -FrimFram.ModalView = ModalView \ No newline at end of file diff --git a/test/app/frimfram/ModalView.spec.coffee b/test/app/frimfram/ModalView.spec.coffee index 1e96884..26d3c33 100644 --- a/test/app/frimfram/ModalView.spec.coffee +++ b/test/app/frimfram/ModalView.spec.coffee @@ -1,10 +1,10 @@ -describe 'ModalView', -> +describe 'Modal', -> afterEach -> - FrimFram.ModalView.visibleModal?.hide(true) + FrimFram.Modal.visibleModal?.hide(true) it 'proxies Bootstrap Events through itself as Bootstrap Events', -> - modal = new FrimFram.ModalView() + modal = new FrimFram.Modal() # create a listener that listens to modal callbacks, spy those callbacks callbacks = ['show', 'shown', 'hide', 'hidden'] @@ -24,62 +24,62 @@ describe 'ModalView', -> describe '.show(fast)', -> it 'closes currently visible modal', -> - modal1 = new FrimFram.ModalView() - modal2 = new FrimFram.ModalView() + modal1 = new FrimFram.Modal() + modal2 = new FrimFram.Modal() modal1.show() spyOn(modal1, 'hide').and.callThrough() spy = modal1.hide modal2.show() expect(spy).toHaveBeenCalled() - it 'sets ModalView.visibleModal to itself', -> - modal = new FrimFram.ModalView() - expect(FrimFram.ModalView.visibleModal).toBeFalsy() + it 'sets Modal.visibleModal to itself', -> + modal = new FrimFram.Modal() + expect(FrimFram.Modal.visibleModal).toBeFalsy() modal.show() - expect(FrimFram.ModalView.visibleModal).toBe(modal) + expect(FrimFram.Modal.visibleModal).toBe(modal) it 'puts the view\'s element into the body tag', -> - modal = new FrimFram.ModalView() - expect(FrimFram.ModalView.visibleModal).toBeFalsy() + modal = new FrimFram.Modal() + expect(FrimFram.Modal.visibleModal).toBeFalsy() modal.show() expect($('.modal')[0]).toBe(modal.el) it 'shows itself fast if the first argument is true', (done) -> - modal = new FrimFram.ModalView() + modal = new FrimFram.Modal() spy = jasmine.createSpy() modal.once 'shown', spy modal.show(true) expect(spy).toHaveBeenCalled() - modal = new FrimFram.ModalView() + modal = new FrimFram.Modal() modal.template = '''''' modal.show() modal.once 'shown', -> done() describe '.hide(fast)', -> - it 'clears ModalView.visibleModal', -> - modal = new FrimFram.ModalView() + it 'clears Modal.visibleModal', -> + modal = new FrimFram.Modal() modal.show(true) - expect(FrimFram.ModalView.visibleModal).toBeTruthy() + expect(FrimFram.Modal.visibleModal).toBeTruthy() modal.hide(true) - expect(FrimFram.ModalView.visibleModal).toBeFalsy() + expect(FrimFram.Modal.visibleModal).toBeFalsy() it 'destroys itself at the end of the hiding process', -> - modal = new FrimFram.ModalView() + modal = new FrimFram.Modal() modal.show(true) modal.hide(true) expect(modal.destroyed).toBeTruthy() it 'hides itself fast if the first argument is true', -> - modal = new FrimFram.ModalView() + modal = new FrimFram.Modal() spy = jasmine.createSpy() modal.once 'hidden', spy modal.show(true) modal.hide(true) expect(spy).toHaveBeenCalled() - modal = new FrimFram.ModalView() + modal = new FrimFram.Modal() modal.template = '''''' modal.show(true) modal.hide() @@ -88,7 +88,7 @@ describe 'ModalView', -> describe '.destroyOnHidden', -> it 'can be used to keep a modal from destroying itself on hidden', -> - Modal = FrimFram.ModalView.extend({ + Modal = FrimFram.Modal.extend({ destroyOnHidden: false }) modal = new Modal() From b3e41520912ce5a595aadb3c0b58edb1ba7369db Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Mon, 28 Sep 2015 08:24:51 -0700 Subject: [PATCH 09/11] Add SampleModal to HomeView --- app/templates/home-view.jade | 5 +++++ app/templates/sample-modal.jade | 13 +++++++++++++ app/views/HomeView.coffee | 11 ++++++++++- app/views/SampleModal.coffee | 2 ++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 app/templates/sample-modal.jade create mode 100644 app/views/SampleModal.coffee diff --git a/app/templates/home-view.jade b/app/templates/home-view.jade index 0ef47b5..6ab5e72 100644 --- a/app/templates/home-view.jade +++ b/app/templates/home-view.jade @@ -10,3 +10,8 @@ block content a(href="/test/client") Client Tests li.list-group-item a(href="/test/server") Server Tests + + + button.btn.btn-default#open-sample-modal-btn Open SampleModal + + diff --git a/app/templates/sample-modal.jade b/app/templates/sample-modal.jade new file mode 100644 index 0000000..39822bb --- /dev/null +++ b/app/templates/sample-modal.jade @@ -0,0 +1,13 @@ +.modal-dialog + .modal-content + .modal-header + button.close(data-dismiss="modal", aria-label="Close") + span(aria-hidden="true")!= '×' + h4.modal-title Sample Modal + + .modal-body + p Modal body + + .modal-footer + button.btn.btn-default(data-dismiss="modal") Cancel + button.btn.btn-primary(data-dismiss="modal") Okay diff --git a/app/views/HomeView.coffee b/app/views/HomeView.coffee index bde462f..9747bb0 100644 --- a/app/views/HomeView.coffee +++ b/app/views/HomeView.coffee @@ -1,4 +1,13 @@ +SampleModal = require('views/SampleModal') + class HomeView extends FrimFram.RootView + events: + 'click #open-sample-modal-btn': 'onClickOpenSampleModalButton' + template: require 'templates/home-view' -module.exports = HomeView \ No newline at end of file + onClickOpenSampleModalButton: -> + modal = new SampleModal() + modal.show() + +module.exports = HomeView diff --git a/app/views/SampleModal.coffee b/app/views/SampleModal.coffee new file mode 100644 index 0000000..718cb8b --- /dev/null +++ b/app/views/SampleModal.coffee @@ -0,0 +1,2 @@ +module.exports = class SampleModal extends FrimFram.Modal + template: require('templates/sample-modal') From 61392a0dc064bb96d68ab1983cf7c6e4307123ab Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Mon, 28 Sep 2015 08:25:00 -0700 Subject: [PATCH 10/11] Remove db.sh --- bin/db.sh | 1 - 1 file changed, 1 deletion(-) delete mode 100755 bin/db.sh diff --git a/bin/db.sh b/bin/db.sh deleted file mode 100755 index 3790be0..0000000 --- a/bin/db.sh +++ /dev/null @@ -1 +0,0 @@ -mongod --dbpath mongo From a6760934caabf39ef0b6e19790bb33d7a92709b2 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Tue, 29 Sep 2015 15:30:16 -0700 Subject: [PATCH 11/11] Refactor router properties currentView, currentPath to view, path --- src/Router.coffee | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Router.coffee b/src/Router.coffee index c13afb8..5d20d8a 100644 --- a/src/Router.coffee +++ b/src/Router.coffee @@ -7,11 +7,11 @@ class Router extends Backbone.Router window.location.reload(true) routeDirectly: (path, args) -> - return document.location.reload() if @currentView?.reloadOnClose - leavingMessage = _.result(@currentView, 'onLeaveMessage') + return document.location.reload() if @view?.reloadOnClose + leavingMessage = _.result(@view, 'onLeaveMessage') if leavingMessage if not confirm(leavingMessage) - return @navigate(this.currentPath, {replace: true}) + return @navigate(this.path, {replace: true}) path = "views/#{path}" @@ -31,17 +31,17 @@ class Router extends Backbone.Router @closeCurrentView() view.render() $('body').empty().append(view.el) - @currentView = view - @currentPath = document.location.pathname + document.location.search + @view = view + @path = document.location.pathname + document.location.search view.onInsert() - closeCurrentView: -> @currentView?.destroy() + closeCurrentView: -> @view?.destroy() setupOnLeaveSite: -> window.addEventListener "beforeunload", (e) => - leavingMessage = _.result(@currentView, 'onLeaveMessage') + leavingMessage = _.result(@view, 'onLeaveMessage') if leavingMessage e.returnValue = leavingMessage return leavingMessage -FrimFram.Router = Router \ No newline at end of file +FrimFram.Router = Router