Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue/2760 Added ChildViews API for rendering control (v5.7.0) #2761

Merged
merged 76 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
87a4534
issue/2709 Converted some classes to ES6 for future works
oliverfoster Mar 31, 2020
80787b1
issue/2709 fixed locking model for ES6 classes
oliverfoster Mar 31, 2020
5a686db
Recommendations
oliverfoster Apr 1, 2020
603d332
Recommendations
oliverfoster Apr 1, 2020
c368971
Recommendations
oliverfoster Apr 1, 2020
ce81506
Recommendation
oliverfoster Apr 1, 2020
6681597
Recommendation
oliverfoster Apr 1, 2020
d50d146
Recommendations
oliverfoster Apr 1, 2020
d4aad08
issue/2712 Simplfied router
oliverfoster Apr 1, 2020
8933d4e
Fixed bugs added comments
oliverfoster Apr 1, 2020
0375144
Added defer to postRemove events as expected
oliverfoster Apr 1, 2020
4db8f12
Removed bad condition
oliverfoster Apr 1, 2020
068d28d
Switched to cached value
oliverfoster Apr 1, 2020
551d458
Recommendations
oliverfoster Apr 2, 2020
4911dbb
Recommendations
oliverfoster Apr 2, 2020
749353f
Recommendations
oliverfoster Apr 2, 2020
81cacf1
issue/2714 Decoupled menu, page, article, block and component
oliverfoster Apr 2, 2020
64274b7
Typo
oliverfoster Apr 2, 2020
2de000f
Recommendations
oliverfoster Apr 4, 2020
1942b1a
issue/2714: Added Adapt.log.warnOnce
oliverfoster Apr 6, 2020
347f520
Linting fixes
oliverfoster Apr 6, 2020
96bda87
issue/2714 Added fallback model/view name discovery
oliverfoster Apr 6, 2020
ebdabc5
issue/2645 Added manifest creation and loading
oliverfoster Apr 6, 2020
dfb9224
Fixed issue with new compatibility layer changes
oliverfoster Apr 7, 2020
3b929b3
issue/2712 Simplfied router
oliverfoster Apr 1, 2020
df93b45
Fixed bugs added comments
oliverfoster Apr 1, 2020
763ccfc
Added defer to postRemove events as expected
oliverfoster Apr 1, 2020
eb6597a
Removed bad condition
oliverfoster Apr 1, 2020
eca527b
Switched to cached value
oliverfoster Apr 1, 2020
5a1cae8
Recommendations
oliverfoster Apr 2, 2020
c5b5bc4
Recommendations
oliverfoster Apr 2, 2020
a555e94
Recommendations
oliverfoster Apr 2, 2020
9fabc27
Merge branch 'issue/2712' of https://github.com/adaptlearning/adapt_f…
oliverfoster Apr 7, 2020
9a20e9b
issue/2714 Decoupled menu, page, article, block and component
oliverfoster Apr 2, 2020
53264e5
Typo
oliverfoster Apr 2, 2020
76cdf72
Recommendations
oliverfoster Apr 4, 2020
818dd05
issue/2714: Added Adapt.log.warnOnce
oliverfoster Apr 6, 2020
2bb469b
Linting fixes
oliverfoster Apr 6, 2020
b4abd4b
issue/2714 Added fallback model/view name discovery
oliverfoster Apr 6, 2020
be03dec
Merge branch 'issue/2714' of https://github.com/adaptlearning/adapt_f…
oliverfoster Apr 7, 2020
a861913
issue/2645 Added manifest creation and loading
oliverfoster Apr 6, 2020
c1130ae
Merge branch 'issue/2645' of https://github.com/adaptlearning/adapt_f…
oliverfoster Apr 7, 2020
d6dfe8d
Recommendations
olivermartinfoster Apr 14, 2020
4dd0ba8
Improved babel source mapping
olivermartinfoster Apr 14, 2020
3c7b656
Readded sourceType to babel config
olivermartinfoster Apr 14, 2020
cb1ee71
issue/2645 Added manifest creation and loading
olivermartinfoster Apr 14, 2020
cf924ca
isTypeGroup warning simplified
olivermartinfoster Apr 14, 2020
61c1a97
issue/2714 Decoupled menu, page, article, block and component
olivermartinfoster Apr 20, 2020
99d3aae
issue/2712 Simplified router
olivermartinfoster Apr 20, 2020
74e2b6c
Fix for authoring tool assets.json
olivermartinfoster Apr 21, 2020
9776793
Fixed linting issues
olivermartinfoster Apr 21, 2020
2af5448
Reworked AAT assets.json fix
olivermartinfoster Apr 21, 2020
e5e5157
Switched to native filter
olivermartinfoster Apr 21, 2020
014c62a
Switched from instanceof Array to Array.isArray
olivermartinfoster Apr 21, 2020
9529833
Fixed babel watch command
olivermartinfoster Apr 21, 2020
4d9a5c8
Added contentObject postRemove instance event, added global preReady …
olivermartinfoster Apr 21, 2020
3b0683c
Switched buttons and heading views to use contentObject postRemove in…
olivermartinfoster Apr 21, 2020
e756447
Added ready guard and removed duplicate preReady event
olivermartinfoster Apr 22, 2020
f1e632d
Moved _isReady reset back into Adapt.remove to allow multiple page re…
olivermartinfoster Apr 27, 2020
1c8ca18
ItemsQuestionModel not restoring question answers correctly, missing …
olivermartinfoster May 1, 2020
d7c85c4
resolved merge conflict
olivermartinfoster May 6, 2020
f07deb5
issue/2760 Added ChildViews API for rendering control
olivermartinfoster May 9, 2020
14c646a
Removed extra bracket
olivermartinfoster May 9, 2020
75240a5
Fixed indentation
olivermartinfoster May 9, 2020
50da174
Added code comments
olivermartinfoster May 10, 2020
87e6747
Added _canRequestChild and _isRendered defaults
olivermartinfoster May 10, 2020
6a4d327
Added ContentObjectView.renderTo code comment
olivermartinfoster May 10, 2020
3952226
Made getAddChildEvent private
olivermartinfoster May 10, 2020
5b16ade
Merge branch 'master' into release/v5.6.0
olivermartinfoster May 12, 2020
1e6d2c8
Merged with master
olivermartinfoster May 22, 2020
9c07be7
Merge branch 'release/v5.6.0' of https://github.com/adaptlearning/ada…
olivermartinfoster May 22, 2020
69566e5
Linting fixes
olivermartinfoster May 22, 2020
cda807a
Linting fix
olivermartinfoster May 22, 2020
bfbf2ad
issue/2760 Removed duplicate call
oliverfoster Jul 7, 2020
91ad563
Merge branch 'master' into issue/2760
oliverfoster Jul 20, 2020
f29143c
Merge remote-tracking branch 'origin' into issue/2760
olivermartinfoster Aug 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions src/core/js/adapt.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,20 +140,22 @@ define([
}

/**
* Allows a selector to be passed in and Adapt will navigate to this element
* Allows a selector to be passed in and Adapt will navigate to this element. Resolves
* asynchronously when the element has been navigated to.
* @param {string} selector CSS selector of the Adapt element you want to navigate to e.g. `".co-05"`
* @param {object} [settings={}] The settings for the `$.scrollTo` function (See https://github.com/flesler/jquery.scrollTo#settings).
* You may also include a `replace` property that you can set to `true` if you want to update the URL without creating an entry in the browser's history.
* @param {Object} [settings] The settings for the `$.scrollTo` function (See https://github.com/flesler/jquery.scrollTo#settings).
* @param {Object} [settings.replace=false] Set to `true` if you want to update the URL without creating an entry in the browser's history.
*/
navigateToElement() {}
async navigateToElement() {}

/**
* Allows a selector to be passed in and Adapt will scroll to this element
* Allows a selector to be passed in and Adapt will scroll to this element. Resolves
* asynchronously when the element has been navigated/scrolled to.
* @param {string} selector CSS selector of the Adapt element you want to navigate to e.g. `".co-05"`
* @param {object} [settings={}] The settings for the `$.scrollTo` function (See https://github.com/flesler/jquery.scrollTo#settings).
* You may also include a `replace` property that you can set to `true` if you want to update the URL without creating an entry in the browser's history.
* @param {Object} [settings={}] The settings for the `$.scrollTo` function (See https://github.com/flesler/jquery.scrollTo#settings).
* @param {Object} [settings.replace=false] Set to `true` if you want to update the URL without creating an entry in the browser's history.
*/
scrollTo() {}
async scrollTo() {}

/**
* Used to register models and views with `Adapt.store`
Expand Down Expand Up @@ -343,7 +345,9 @@ define([
}

const foundView = idPathToView.reduce((view, currentId) => {
return view && view.childViews && view.childViews[currentId];
if (!view) return;
const childViews = view.getChildViews();
return childViews && childViews.find(view => view.model.get('_id') === currentId);
}, this.parentView);

return foundView;
Expand Down Expand Up @@ -398,8 +402,10 @@ define([
async remove() {
const currentView = this.parentView;
if (currentView) {
currentView.model.setOnChildren('_isReady', false);
currentView.model.set('_isReady', false);
currentView.model.setOnChildren({
'_isReady': false,
'_isRendered': false
});
}
this.trigger('preRemove', currentView);
await this.wait.queue();
Expand Down
104 changes: 104 additions & 0 deletions src/core/js/childEvent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
define([
'core/js/adapt'
], function(Adapt) {

/**
* Event object triggered for controlling child view rendering.
* Sent with 'view:addChild' and 'view:requestChild' events.
* All plugins receive the same object reference in their event handler and
* as such, this object becomes a place of consensus for plugins to decide how
* to handle rendering for this child.
*/
class ChildEvent extends Backbone.Controller {

/**
* @param {string} type Event type
* @param {AdaptView} target Parent view
* @param {AdaptModel} model Child model
*/
initialize(type, target, model) {
/** @type {string} */
this.type = type;
/** @type {AdaptView} */
this.target = target;
/** @type {boolean} Force the child model to render */
this.isForced = false;
/** @type {boolean} Stop rendering before the child model */
this.isStoppedImmediate = false;
/** @type {boolean} Stop rendering after the child model */
this.isStoppedNext = false;
/** @type {boolean} Contains a model to render in response to a requestChild event */
this.hasRequestChild = false;
this._model = model;
}

/**
* Get the model to be rendered.
* @returns {AdaptModel}
*/
get model() {
return this._model;
}

/**
* Set the model to render in response to a 'view:requestChild' event.
* @param {AdaptModel}
*/
set model(model) {
if (this.type !== 'requestChild') {
Adapt.log.warn(`Cannot change model in ${this.type} event.`);
return;
}
if (this._model) {
Adapt.log.warn(`Cannot inject two models in one sitting. ${model.get('_id')} attempts to overwrite ${this._model.get('_id')}`);
return;
}
this._model = model;
this.hasRequestChild = true;
}

/**
* Reset all render stops.
*/
reset() {
this.isStoppedImmediate = false;
this.isStoppedNext = false;
}

/**
* Force model to render.
*/
force() {
this.isForced = true;
}

/**
* General stop. Stop immediately or stop next with flag to false.
* @param {boolean} [immediate=true] Flag to stop immediate or next.
*/
stop(immediate = true) {
if (!immediate) {
return this.stopNext();
}
this.isStoppedImmediate = true;
}

/**
* Shortcut to stop(false). Stop the render after the contained model is rendered.
*/
stopNext() {
this.isStoppedNext = true;
}

/**
* Trigger an event to signify that a final decision has been reached.
*/
close() {
this.trigger('closed');
}

}

return ChildEvent;

});
37 changes: 33 additions & 4 deletions src/core/js/models/adaptModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ define([
_canShowFeedback: true,
_classes: '',
_canReset: false,
_canRequestChild: false,
_isComplete: false,
_isInteractionComplete: false,
_isA11yRegionEnabled: false,
Expand All @@ -39,6 +40,7 @@ define([
_isResetOnRevisit: false,
_isAvailable: true,
_isOptional: false,
_isRendered: false,
_isReady: false,
_isVisible: true,
_isLocked: false,
Expand Down Expand Up @@ -208,16 +210,30 @@ define([
}
}

checkReadyStatus() {
/**
* Checks if any child models which have been _isRendered are not _isReady.
* If all rendered child models are marked ready then this model will be
* marked _isReady: true as well.
* @param {AdaptModel} [model]
* @param {boolean} [value]
* @returns {boolean}
*/
checkReadyStatus(model, value) {
if (value === false) {
// Do not respond to _isReady: false as _isReady is unset throughout
// the rendering process
return false;
}
// Filter children based upon whether they are available
// Check if any return _isReady:false
// Check if any _isRendered: true children return _isReady: false
// If not - set this model to _isReady: true
const children = this.getAvailableChildModels();
if (children.find(child => child.get('_isReady') === false)) {
return;
if (children.find(child => child.get('_isReady') === false && child.get('_isRendered'))) {
return false;
}

this.set('_isReady', true);
return true;
}

setCompletionStatus() {
Expand Down Expand Up @@ -734,6 +750,19 @@ define([
this.checkLocking();
}

/**
* Used before a model is rendered to determine if it should be reset to its
* default values.
*/
checkIfResetOnRevisit() {
var isResetOnRevisit = this.get('_isResetOnRevisit');
if (!isResetOnRevisit) {
return;
}
// If reset is enabled set defaults
this.reset(isResetOnRevisit);
}

/**
* Clones this model and all managed children returning a new branch.
* Assign new unique ids to each cloned model.
Expand Down
33 changes: 19 additions & 14 deletions src/core/js/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ define([
// Allow navigation.
this.model.set('_canNavigate', true, { pluginName: 'adapt' });
// Scroll to element
Adapt.navigateToElement('.' + id, { replace: true });
Adapt.navigateToElement('.' + id, { replace: true, duration: 400 });
return;
}

Expand Down Expand Up @@ -319,12 +319,14 @@ define([
}

/**
* Allows a selector to be passed in and Adapt will navigate to this element
* Allows a selector to be passed in and Adapt will navigate to this element. Resolves
* asynchronously when the element has been navigated to.
* Backend for Adapt.navigateToElement
* @param {string} selector CSS selector of the Adapt element you want to navigate to e.g. `".co-05"`
* @param {object} [settings] The settings for the `$.scrollTo` function (See https://github.com/flesler/jquery.scrollTo#settings).
* You may also include a `replace` property that you can set to `true` if you want to update the URL without creating an entry in the browser's history.
* @param {Object} [settings] The settings for the `$.scrollTo` function (See https://github.com/flesler/jquery.scrollTo#settings).
* @param {Object} [settings.replace=false] Set to `true` if you want to update the URL without creating an entry in the browser's history.
*/
navigateToElement(selector, settings = {}) {
async navigateToElement(selector, settings = {}) {
// Removes . symbol from the selector to find the model
const currentModelId = selector.replace(/\./g, '');
const currentModel = Adapt.findById(currentModelId);
Expand All @@ -338,17 +340,20 @@ define([
return Adapt.scrollTo(selector, settings);
}

// If the element is on another page navigate and wait until pageView:ready is fired
// Then scrollTo element
Adapt.once('contentObjectView:ready', _.debounce(() => {
this.model.set('_shouldNavigateFocus', true, { pluginName: 'adapt' });
Adapt.scrollTo(selector, settings);
}, 1));

const shouldReplaceRoute = settings.replace || false;

this.model.set('_shouldNavigateFocus', false, { pluginName: 'adapt' });
this.navigate('#/id/' + pageId, { trigger: true, replace: shouldReplaceRoute });
await new Promise(resolve => {
// If the element is on another page navigate and wait until pageView:ready is fired
// Then scrollTo element
Adapt.once('contentObjectView:ready', _.debounce(async () => {
this.model.set('_shouldNavigateFocus', true, { pluginName: 'adapt' });
await Adapt.scrollTo(selector, settings);
resolve();
}, 1));

this.model.set('_shouldNavigateFocus', false, { pluginName: 'adapt' });
this.navigate('#/id/' + pageId, { trigger: true, replace: shouldReplaceRoute });
});
}

get(...args) {
Expand Down
30 changes: 25 additions & 5 deletions src/core/js/scrolling.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,24 @@ define([
});
}

scrollTo(selector, settings = {}) {
/**
* Allows a selector to be passed in and Adapt will scroll to this element. Resolves
* asynchronously when the element has been navigated/scrolled to.
* Backend for Adapt.scrollTo
* @param {string} selector CSS selector of the Adapt element you want to navigate to e.g. `".co-05"`
* @param {Object} [settings={}] The settings for the `$.scrollTo` function (See https://github.com/flesler/jquery.scrollTo#settings).
* @param {Object} [settings.replace=false] Set to `true` if you want to update the URL without creating an entry in the browser's history.
*/
async scrollTo(selector, settings = {}) {

const currentModelId = selector.replace(/\./g, '');
const currentModel = Adapt.findById(currentModelId);
if (!currentModel) return;

if (!currentModel.get('_isRendered') || !currentModel.get('_isRendered')) {
await Adapt.parentView.renderTo(currentModelId);
}

// Get the current location - this is set in the router
const location = (Adapt.location._contentType) ?
Adapt.location._contentType : Adapt.location._currentLocation;
Expand Down Expand Up @@ -136,10 +153,13 @@ define([

// Trigger an event after animation
// 300 milliseconds added to make sure queue has finished
_.delay(() => {
Adapt.a11y.focusNext(selector);
Adapt.trigger(`${location}:scrolledTo`, selector);
}, settings.duration + 300);
await new Promise(resolve => {
_.delay(() => {
Adapt.a11y.focusNext(selector);
Adapt.trigger(`${location}:scrolledTo`, selector);
resolve();
}, settings.duration + 300);
});
}

}
Expand Down
Loading