app/assets/javascripts/joosy/core/page.js.coffee in joosy-0.1.0.RC2 vs app/assets/javascripts/joosy/core/page.js.coffee in joosy-0.1.0.RC3

- old
+ new

@@ -6,65 +6,238 @@ #= require joosy/core/modules/renderer #= require joosy/core/modules/time_manager #= require joosy/core/modules/widgets_manager #= require joosy/core/modules/filters +# +# Base class for all of your Joosy Pages. +# @see http://guides.joosy.ws/guides/layouts-pages-and-routing.html +# +# @example Sample application page +# class @RumbaPage extends Joosy.Layout +# @view 'rumba' +# class Joosy.Page extends Joosy.Module @include Joosy.Modules.Log @include Joosy.Modules.Events @include Joosy.Modules.Container @include Joosy.Modules.Renderer @include Joosy.Modules.TimeManager @include Joosy.Modules.WidgetsManager @include Joosy.Modules.Filters + # + # Default layout is no layout. + # layout: false + + # + # Previous page. + # previous: false + + # + # Route params. + # params: false + + # + # Prefetched page data. + # data: false - @fetch: (callback) -> - @::__fetch = callback - - @scroll: (element, options={}) -> - @::__scrollElement = element - @::__scrollSpeed = options.speed || 500 - @::__scrollMargin = options.margin || 0 - + # + # Sets layout for current page + # + # @param [Class] layoutClass Layout to use + # @layout: (layoutClass) -> @::__layoutClass = layoutClass + # + # Sets the method which will controll the painting preparation proccess. + # + # This method will be called right ater previous page {Joosy.Page.erase} and in parallel with + # page data fetching so you can use it to initiate preloader. + # + # @note Given method will be called with `complete` function as parameter. As soon as your + # preparations are done you should call that function. + # + # @example Sample before painter + # @beforePaint (complete) -> + # if !@data # checks if parallel fetching finished + # $('preloader').slideDown -> complete() + # + # @beforePaint: (callback) -> @::__beforePaint = callback + + # + # Sets the method which will controll the painting proccess. + # + # This method will be called after fetching, erasing and beforePaint is complete. + # It should be used to setup appearance effects of page. + # + # @note Given method will be called with `complete` function as parameter. As soon as your + # preparations are done you should call that function. + # + # @example Sample painter + # @paint (complete) -> + # @container.fadeIn -> complete() + # @paint: (callback) -> @::__paint = callback + + # + # @todo Does anybody have idea why we could need this method? + # Looks like something should be removed from here and bootstrap proccess. + # @afterPaint: (callback) -> @::__afterPaint = callback + + # + # Sets the method which will controll the erasing proccess. + # + # Use this method to setup hiding effect. + # + # @note Given method will be called with `complete` function as parameter. As soon as your + # preparations are done you should call that function. + # + # @note This method will be caled _before_ unload routines so in theory you can + # access page data from that. Think twice if you are doing it right though. + # + # @example Sample eraser + # @erase (complete) -> + # @container.fadeOut -> complete() + # @erase: (callback) -> @::__erase = callback + # + # Sets the method which will controll the data fetching proccess. + # + # @note Given method will be called with `complete` function as parameter. As soon as your + # preparations are done you should call that function. + # + # @example Basic usage + # @fetch (complete) -> + # $.get '/rumbas', (@data) => complete() + # + @fetch: (callback) -> + @::__fetch = callback + + # + # Sets the several separate methods that will fetch data in parallel. + # + # @note This will work through {Joosy.Modules.Events#synchronize} + # + # @example Basic usage + # @fetchSynchronized (context) -> + # context.do (done) -> + # $.get '/rumbas', (data) => + # @data.rumbas = data + # done() + # + # context.do (done) -> + # $.get '/kutuzkas', (data) => + # @data.kutuzkas = data + # done() + # + @fetchSynchronized: (callback) -> + @::__fetch = (complete) -> + @synchronize (context) -> + context.after -> complete() + callback.call(this, context) + + # + # Sets the position where page will be scrolled to after load. + # + # @note If you use animated scroll joosy will atempt to temporarily fix the + # height of your document while scrolling to prevent jump effect. + # + # @param [jQuery] element Element to scroll to + # @param [Hash] options + # + # @option options [Integer] speed Sets the animation duration (500 is default) + # @option options [Integer] margin Defines the margin from element position. + # Can be negative. + # + @scroll: (element, options={}) -> + @::__scrollElement = element + @::__scrollSpeed = options.speed || 500 + @::__scrollMargin = options.margin || 0 + + # + # Sets the page HTML title. + # + # @note Title will be reverted on unload. + # + # @param [String] title Title to set. + # + @title: (title, separator=' / ') -> + @afterLoad -> + titleStr = if Object.isFunction(title) then title.apply(this) else title + titleStr = titleStr.join(separator) if Object.isArray(titleStr) + @__previousTitle = document.title + document.title = titleStr + + @afterUnload -> + document.title = @__previousTitle + + # + # Constructor is very destructive (c), it calls bootstrap directly so use with caution. + # + # @params [Hash] params Route params + # @params [Joosy.Page] previous Previous page to unload + # constructor: (@params, @previous) -> + Joosy.Application.loading = true + @__layoutClass ||= ApplicationLayout if @__runBeforeLoads @params, @previous if !@previous?.layout?.uuid? || @previous?.__layoutClass != @__layoutClass @__bootstrapLayout() else @__bootstrap() + # + # @see Joosy.Router#navigate + # navigate: (args...) -> Joosy.Router.navigate(args...) + # + # This is required by {Joosy.Modules.Renderer} + # Sets the base template dir to app_name/templates/pages + # __renderSection: -> 'pages' + # + # Freezes the page height through $(html). + # + # Required to implement better {Joosy.Page.scroll} behavior. + # __fixHeight: -> $('html').css 'min-height', $(document).height() - + + # + # Undo {#__fixHeight} + # __releaseHeight: -> $('html').css 'min-height', '' + # + # Page bootstrap proccess + # + # * {Joosy.Modules.Container#refreshElements} + # * {Joosy.Modules.Container#__delegateEvents} + # * {Joosy.Modules.WidgetsManager#__setupWidgets} + # * {Joosy.Modules.Filters#__runAfterLoads} + # * Scrolling + # __load: -> @refreshElements() @__delegateEvents() @__setupWidgets() @__runAfterLoads @params, @previous @@ -72,34 +245,60 @@ scroll = $(@__extractSelector @__scrollElement).offset()?.top + @__scrollMargin Joosy.Modules.Log.debugAs @, "Scrolling to #{@__extractSelector @__scrollElement}" $('html, body').animate {scrollTop: scroll}, @__scrollSpeed, => if @__scrollSpeed != 0 @__releaseHeight() + Joosy.Application.loading = false + @trigger 'loaded' Joosy.Modules.Log.debugAs @, "Page loaded" + # + # Page destruction proccess. + # + # * {Joosy.Modules.TimeManager#__clearTime} + # * {Joosy.Modules.WidgetsManager#__unloadWidgets} + # * {Joosy.Modules.Renderer#__removeMetamorphs} + # * {Joosy.Modules.Filters#__runAfterUnloads} + # __unload: -> @__clearTime() @__unloadWidgets() @__removeMetamorphs() @__runAfterUnloads @params, @previous delete @previous + # + # Proxies callback through possible async wrapper. + # + # If wrapper is defined, it will be called with given callback as one of parameters. + # If wrapper is not defined callback will be called directly. + # + # @note Magic People Voodoo People + # + # @param [Object] entity Object possibly containing wrapper method + # @param [String] receiver String name of wrapper method inside entity + # @param [Hash] params Params to send to wrapper, callback will be + # attached as the last of them. + # @param [Function] callback Callback to run + # __callSyncedThrough: (entity, receiver, params, callback) -> if entity?[receiver]? entity[receiver].apply entity, params.clone().add(callback) else callback() - - # Boot Sequence: + # - # previous::erase \ - # previous::unload \ - # beforePaint \ - # > paint - # fetch / + # The single page (without layout reloading) bootstrap logic # + # @example Hacky boot sequence description + # previous::erase \ + # previous::unload \ + # beforePaint \ + # > paint + # fetch / + # __bootstrap: -> Joosy.Modules.Log.debugAs @, "Boostraping page" @layout = @previous.layout callbacksParams = [@layout.content()] @@ -125,9 +324,19 @@ @__callSyncedThrough this, '__fetch', [], => Joosy.Modules.Log.debugAs @, "Fetch complete" @trigger 'dataReceived' + # + # The page+layout bootstrap logic + # + # @example Hacky boot sequence description + # previous::erase \ + # previous::unload \ + # beforePaint \ + # > paint + # fetch / + # __bootstrapLayout: -> Joosy.Modules.Log.debugAs @, "Boostraping page with layout" @layout = new @__layoutClass(@params) callbacksParams = [Joosy.Application.content(), this]