Skip to content

Commit

Permalink
change how view rerenders
Browse files Browse the repository at this point in the history
  • Loading branch information
arshaw committed Sep 29, 2019
1 parent 972524a commit e4192b5
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 69 deletions.
2 changes: 1 addition & 1 deletion packages/__tests__/src/legacy/scroll-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('scroll state', function() {

function defineTests() {

it('should be maintained when moving resizing window', function(done) {
it('should be maintained when resizing window', function(done) {
var scrollEl
var scroll0

Expand Down
42 changes: 9 additions & 33 deletions packages/core/src/Calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ export default class Calendar {

// isDisplaying: boolean = false // installed in DOM? accepting renders?
needsRerender: boolean = false // needs a render?
needsFullRerender: boolean = false
isRendering: boolean = false // currently in the executeRender function?
renderingPauseDepth: number = 0
renderableEventStore: EventStore
Expand Down Expand Up @@ -164,11 +163,12 @@ export default class Calendar {

render() {
if (!this.component) {
this.component = new CalendarComponent(this.el)
this.renderableEventStore = createEmptyEventStore()
this.bindHandlers()
this.executeRender()
} else {
this.requestRerender(true)
this.requestRerender()
}
}

Expand Down Expand Up @@ -312,13 +312,13 @@ export default class Calendar {

let view = this.component && this.component.view

if (oldState.eventStore !== newState.eventStore || this.needsFullRerender) {
if (oldState.eventStore !== newState.eventStore) {
if (oldState.eventStore) {
this.isEventsUpdated = true
}
}

if (oldState.dateProfile !== newState.dateProfile || this.needsFullRerender) {
if (oldState.dateProfile !== newState.dateProfile) {
if (oldState.dateProfile && view) { // why would view be null!?
this.publiclyTrigger('datesDestroy', [
{
Expand All @@ -330,7 +330,7 @@ export default class Calendar {
this.isDatesUpdated = true
}

if (oldState.viewType !== newState.viewType || this.needsFullRerender) {
if (oldState.viewType !== newState.viewType) {
if (oldState.viewType && view) { // why would view be null!?
this.publiclyTrigger('viewSkeletonDestroy', [
{
Expand All @@ -356,9 +356,8 @@ export default class Calendar {
// -----------------------------------------------------------------------------------------------------------------


requestRerender(needsFull = false) {
requestRerender() {
this.needsRerender = true
this.needsFullRerender = this.needsFullRerender || needsFull
this.delayedRerender() // will call a debounced-version of tryRerender
}

Expand Down Expand Up @@ -390,14 +389,11 @@ export default class Calendar {
// -----------------------------------------------------------------------------------------------------------------

executeRender() {
let { needsFullRerender } = this // save before clearing

// clear these BEFORE the render so that new values will accumulate during render
this.needsRerender = false
this.needsFullRerender = false

this.isRendering = true
this.renderComponent(needsFullRerender)
this.renderComponent()
this.isRendering = false

// received a rerender request while rendering
Expand All @@ -409,11 +405,10 @@ export default class Calendar {
/*
don't call this directly. use executeRender instead
*/
renderComponent(needsFull) {
renderComponent() {
let { state, component } = this
let { viewType } = state
let viewSpec = this.viewSpecs[viewType]
let savedScroll = (needsFull && component) ? component.view.queryScroll() : null

if (!viewSpec) {
throw new Error(`View type "${viewType}" is not valid`)
Expand All @@ -430,20 +425,6 @@ export default class Calendar {
let eventUiBySource = this.buildEventUiBySource(state.eventSources)
let eventUiBases = this.eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource)

if (needsFull || !component) {

if (component) {
component.freezeHeight() // next component will unfreeze it
component.destroy()
}

component = this.component = new CalendarComponent(this.el)

this.isViewUpdated = true
this.isDatesUpdated = true
this.isEventsUpdated = true
}

component.receiveProps({
...state,
viewSpec,
Expand All @@ -461,10 +442,6 @@ export default class Calendar {
this.optionsManager.computed
))

if (savedScroll) {
component.view.applyScroll(savedScroll, false)
}

if (this.isViewUpdated) {
this.isViewUpdated = false
this.publiclyTrigger('viewSkeletonRender', [
Expand Down Expand Up @@ -559,7 +536,6 @@ export default class Calendar {

if (anyDifficultOptions) {
this.handleOptions(this.optionsManager.computed)
this.needsFullRerender = true
}

this.batchRendering(() => {
Expand All @@ -574,7 +550,7 @@ export default class Calendar {
}

/* HACK
has the same effect as calling this.requestRerender(true)
has the same effect as calling this.requestRerender()
but recomputes the state's dateProfile
*/
this.dispatch({
Expand Down
77 changes: 49 additions & 28 deletions packages/core/src/CalendarComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ export default class CalendarComponent extends Component<CalendarComponentProps>
el: HTMLElement
contentEl: HTMLElement

elClassNames: string[] = []
savedScroll: any // hack
isHeightAuto: boolean
viewHeight: number

private renderSkeleton = memoizeRendering(this._renderSkeleton, this._unrenderSkeleton)
private renderToolbars = memoizeRendering(this._renderToolbars, null, [ this.renderSkeleton ])
private renderToolbars = memoizeRendering(this._renderToolbars, this._unrenderToolbars, [ this.renderSkeleton ])
private buildComponentContext = memoize(buildComponentContext)
private buildViewPropTransformers = memoize(buildViewPropTransformers)

Expand Down Expand Up @@ -83,7 +85,7 @@ export default class CalendarComponent extends Component<CalendarComponentProps>
}

_renderSkeleton(context: ComponentContext) {
this.toggleElClassNames(true, context)
this.updateElClassNames(context)

prependToElement(
this.el,
Expand All @@ -98,25 +100,42 @@ export default class CalendarComponent extends Component<CalendarComponentProps>
}

_unrenderSkeleton() {
this.destroyView() // weird to have this here

// weird to have this here
if (this.view) {
this.savedScroll = this.view.queryScroll()
this.view.destroy()
this.view = null
}

removeElement(this.contentEl)
this.toggleElClassNames(false, this.context)
this.removeElClassNames()
}

toggleElClassNames(bool: boolean, context: ComponentContext) {
removeElClassNames() {
let classList = this.el.classList

for (let className of this.elClassNames) {
classList.remove(className)
}

this.elClassNames = []
}

updateElClassNames(context: ComponentContext) {
this.removeElClassNames()

let { theme, options } = context
this.elClassNames = [
'fc',
'fc-' + options.dir,
theme.getClass('widget')
]

let classList = this.el.classList
let dirClassName = 'fc-' + options.dir
let themeClassName = theme.getClass('widget')

if (bool) {
classList.add('fc')
classList.add(dirClassName)
classList.add(themeClassName)
} else {
classList.remove('fc')
classList.remove(dirClassName)
classList.remove(themeClassName)
for (let className of this.elClassNames) {
classList.add(className)
}
}

Expand Down Expand Up @@ -169,6 +188,17 @@ export default class CalendarComponent extends Component<CalendarComponentProps>
}
}

_unrenderToolbars() {
if (this.header) {
this.header.destroy()
this.header = null
}
if (this.footer) {
this.footer.destroy()
this.footer = null
}
}

renderView(props: CalendarComponentProps, title: string) {
let { view } = this
let { calendar, options } = this.context
Expand All @@ -182,8 +212,10 @@ export default class CalendarComponent extends Component<CalendarComponentProps>

view = this.view = new viewSpec['class'](viewSpec, this.contentEl)

} else {
view.addScroll(view.queryScroll())
if (this.savedScroll) {
view.addScroll(this.savedScroll, true)
this.savedScroll = null
}
}

view.title = title // for the API
Expand Down Expand Up @@ -212,13 +244,6 @@ export default class CalendarComponent extends Component<CalendarComponentProps>
view.receiveProps(viewProps, this.buildComponentContext(this.context, viewSpec, view))
}

destroyView() {
if (this.view) {
this.view.destroy()
this.view = null
}
}


// Sizing
// -----------------------------------------------------------------------------------------------------------------
Expand All @@ -230,10 +255,6 @@ export default class CalendarComponent extends Component<CalendarComponentProps>
return // why?
}

if (isResize) {
view.addScroll(view.queryScroll())
}

if (isResize || this.isHeightAuto == null) {
this.computeHeightVars()
}
Expand Down
28 changes: 21 additions & 7 deletions packages/core/src/View.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ export default abstract class View extends DateComponent<ViewProps> {
}


beforeUpdate() {
this.addScroll(this.queryScroll())
}


destroy() {
super.destroy()

Expand All @@ -128,6 +133,10 @@ export default abstract class View extends DateComponent<ViewProps> {
updateSize(isResize: boolean, viewHeight: number, isAuto: boolean) {
let { calendar } = this.context

if (isResize) {
this.addScroll(this.queryScroll()) // NOTE: same code as in beforeUpdate
}

if (
isResize || // HACKS...
calendar.isViewUpdated ||
Expand All @@ -138,6 +147,8 @@ export default abstract class View extends DateComponent<ViewProps> {
// anything that might cause dimension changes
this.updateBaseSize(isResize, viewHeight, isAuto)
}

// NOTE: popScroll is called by CalendarComponent
}


Expand Down Expand Up @@ -373,10 +384,11 @@ export default abstract class View extends DateComponent<ViewProps> {
------------------------------------------------------------------------------------------------------------------*/


addScroll(scroll) {
let queuedScroll = this.queuedScroll || (this.queuedScroll = {})

__assign(queuedScroll, scroll)
addScroll(scroll, isForced?: boolean) {
if (isForced) {
scroll.isForced = isForced
}
__assign(this.queuedScroll || (this.queuedScroll = {}), scroll)
}


Expand All @@ -387,7 +399,9 @@ export default abstract class View extends DateComponent<ViewProps> {


applyQueuedScroll(isResize: boolean) {
this.applyScroll(this.queuedScroll || {}, isResize)
if (this.queuedScroll) {
this.applyScroll(this.queuedScroll, isResize)
}
}


Expand All @@ -403,9 +417,9 @@ export default abstract class View extends DateComponent<ViewProps> {


applyScroll(scroll, isResize: boolean) {
let { duration } = scroll
let { duration, isForced } = scroll

if (duration != null) {
if (duration != null && !isForced) {
delete scroll.duration

if (this.props.dateProfile) { // dates rendered yet?
Expand Down
15 changes: 15 additions & 0 deletions packages/core/src/component/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,16 @@ export default class Component<PropsType> {
this.props = comboProps

if (anyChanges) {

if (oldContext) {
this.beforeUpdate()
}

this.render(comboProps, context)

if (oldContext) {
this.afterUpdate()
}
}
}

Expand All @@ -83,6 +92,12 @@ export default class Component<PropsType> {
firstContext(context: ComponentContext) {
}

beforeUpdate() {
}

afterUpdate() {
}

// after destroy is called, this component won't ever be used again
destroy() {
}
Expand Down

0 comments on commit e4192b5

Please sign in to comment.