Skip to content
This repository has been archived by the owner on Jan 10, 2024. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'gregor/SJRK-288'
Browse files Browse the repository at this point in the history
* gregor/SJRK-288: (43 commits)
  SJRK-288: added TODOs and Jira links to outstanding issues
  SJRK-288: Tidied updateBlockOrder code, added manual test documentation
  SJRK-288: added UIO themes for block reorder drop marker
  SJRK-288: added persistent highlight for Help story link in AIHEC theme
  SJRK-288: added regression test for double-loading blockUi bug
  SJRK-288: added basic input-checking in the `sortStoryContent` function
  SJRK-288: removed unused events, batched all order-related changes
  SJRK-288: updated reorderer race condition comment with a link to Jira
  SJRK-288: fixed story double-load bug introduced by event refactoring
  SJRK-288: separated ready events in ui and storyUi grades
  SJRK-288: solved a CSS bug - Firefox button focus states were invisible
  NOJIRA: Solved a CSS bug - forward/back arrow misalignment
  NOJIRA: updated BBR and GD contrast theme buttons to fix visual bug
  SJRK-288: added link to how-to story on AIHEC theme masthead
  SJRK-288: added manual tests for Story Editor, including reorderer tests
  SJRK-288: added reorderer function unit tests
  SJRK-288: added contrast theme rules for focus state
  SJRK-288: relocated reordering functions to storyEditor,
  SJRK-288: refactored ui onReadyToBind, added new ui and storyUi tests
  SJRK-288: Make all the reorderable blocks focusable.
  ...
  • Loading branch information
cindyli committed Jun 30, 2020
2 parents 825a22e + d1ee495 commit 124ca75
Show file tree
Hide file tree
Showing 64 changed files with 1,532 additions and 218 deletions.
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ to build the web-hosting environment that drives the tool.
* `npm install` to install dependencies
* Run a CouchDB server on `localhost:5984`
* Docker is an easy way to do this, we recommend the `apache/couchdb` image. To use that image via Docker, run this
command: `docker run -p 5984:5984 -d apache/couchdb`
command: `docker run -p 5984:5984 -d apache/couchdb:2.3.1`
* Run `node .\src\server\db\dbSetup.js` to configure necessary CouchDB databases (this will also ensure your CouchDB
instance is set up in [single-node mode](https://docs.couchdb.org/en/stable/setup/single-node.html))
* If you have an [admin user](https://docs.couchdb.org/en/stable/intro/security.html) configured on you CouchDB
Expand Down Expand Up @@ -124,6 +124,7 @@ To create new a custom theme, follow these steps:
### Testing

Before running any tests, please ensure you have followed the steps outlined in [Running the site](#Running-the-site).
All tests should be run before any commits are made in order to catch any bugs or regressions introduced by code changes.

#### Server tests

Expand All @@ -132,9 +133,22 @@ Run `node .\tests\server\all-tests.js` to execute the server code tests.
#### Browser tests

Run the server locally via `node .\index.js` and navigate to `http://localhost:8081/tests/` to run the static browser test
battery. You may be prompted with a file upload dialogue for some of the grade tests; it is safe to close these without
collection. You may be prompted with a file upload dialogue for some of the grade tests; it is safe to close these without
interacting with them.

#### Manual Browser tests

There are a number of features that must currently be tested manually (i.e. with direct user interaction), either due to
automation that has not yet been implemented or due to browser security restrictions. Each manual test page provides instructions
on how to proceed and what to expect in the successful case. Here are the current manual browser test pages:

* [Story Editor UI manual tests](http://localhost:8081/tests/html/ui-storyEditor-manual-Tests.html)
* [Audio Block Editor manual tests](http://localhost:8081/tests/html/blockUi-editor-audioBlockEditor-manual-Tests.html)
* [Image Block Editor manual tests](http://localhost:8081/tests/html/blockUi-editor-imageBlockEditor-manual-Tests.html)
* [Video Block Editor manual tests](http://localhost:8081/tests/html/blockUi-editor-videoBlockEditor-manual-Tests.html)

For more information on the grades and files being tested, please refer to the UI Grades documentation: [GRADES-UI.md](docs/GRADES-UI.md).

### Deploying: Dockerfile and using docker-compose

The included `Dockerfile` is used within the `docker-compose` context and needs an associated CouchDB container to work.
Expand Down
7 changes: 5 additions & 2 deletions docs/GRADES-UI.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
* `sjrk.storyTelling.blockUi.timeBased` provides common shared controls related to playback of audio and video blocks
and is used for both viewing and editing.
* `sjrk.storyTelling.blockUi.editor` is for editing a block, providing the common elements for the various individual
editor types. The `editor` grades are:
editor types. This includes events and button selectors to reorder the block up or down. The `editor` derived grades
are:
* `sjrk.storyTelling.blockUi.editor.textBlockEditor` for text blocks
* `sjrk.storyTelling.blockUi.editor.imageBlockEditor` for image blocks
* `sjrk.storyTelling.blockUi.editor.mediaBlockEditor` for time-based media types:
Expand All @@ -50,7 +51,9 @@
* `sjrk.storyTelling.ui.storyEditor` is an editing interface for a `story` (which it has as a component). It has a
handlebars template associated with it called `storyEditor.handlebars`, and a `binder` to connect the title, author
and keywords fields to their respective model values in the `story`. It makes use of a `dynamicViewComponentManager`
called **blockManager** to add blocks of varying types on demand.
called **blockManager** to add blocks of varying types on demand. The `reorderer` component is for reordering individual
blocks via buttons on each (see `sjrk.storyTelling.block.editor` above), by pressing `CTRL + UP` or `CTRL + DOWN` (or
in macOS, `CTRL + SHIFT + UP` or `CTRL + SHIFT + DOWN`) or by dragging and dropping a block.
* `sjrk.storyTelling.ui.storyViewer` is to view a single story. Its handlebars template is `storyViewer.handlebars`.
There is also a special version of the `storyViewer` called the `storyPreviewer` which is meant to be used in the
`storyEdit` page (more info below).
Expand Down
31 changes: 26 additions & 5 deletions src/server/db/story-dbConfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,22 @@ fluid.defaults("sjrk.storyTelling.server.storiesDb", {
"storyExample": {
"type": "story",
"value": {
"id": "storyExample",
"title": "The Story Builder how-to",
"content": [{
"heading": "Add Content Blocks",
"blockType": "text",
"text": "The Story Builder is designed based on building blocks. There are four types of blocks you can use to build your story:\n\n1. Written content—type directly in the tool\n2. Images (photos of items, drawings, diagrams, etc.)—capture photos or upload files\n3. Audio (sound)—record audio or upload files\n4. Video (audio and visual)—record video or upload files\n\nTo add content blocks and start creating your story, click on an icon at the top of the Story Builder to add a block. You can add as many blocks as you like.\n\nYou won’t be able to reorder the blocks once you have added them, thus, it may be helpful to outline your story blocks before you add them in the Story Builder Tool."
"text": "The Story Builder is designed based on building blocks. There are four types of blocks you can use to build your story:\n\n1. Written content—type directly in the tool\n2. Images (photos of items, drawings, diagrams, etc.)—capture photos or upload files\n3. Audio (sound)—record audio or upload files\n4. Video (audio and visual)—record video or upload files\n\nTo add content blocks and start creating your story, click on an icon at the top of the Story Builder to add a block. You can add as many blocks as you like."
},
{
"heading": "Reorder Content Blocks",
"blockType": "text",
"text": "You can reorder your content blocks using the mouse or keyboard as follows.\n#### Mouse/Touch\n* Select and drag the block handle to move a block. You will see an insertion line appear at the position where the block will be relocated. To leave the block in the same position, move it until the insertion line is immediately above or below the block you’re moving.\n* Select the up/down buttons to move a block one position up or down.\n#### Keyboard\n* With focus on the up/down buttons, select enter or spacebar to move a block one position up or down, or\n* Use keyboard shortcuts to move a block up or down as follows:\n * With focus on the whole block, use the up/down arrow keys on your keyboard together with Shift-Control (Mac) or Control/Cntrl (Windows) to move the block up or down."
},
{
"heading": "Navigating through Content Blocks",
"blockType": "text",
"text": "You can use the up/down arrow keys on your keyboard to move focus from block to block.\n\n**Note:** focus must be on the whole block in order to use this keyboard control (rather than on any one element within the block). We are working on fixing a bug in the tool that limits the ability to move focus from block to block with the keyboard. See Current Bugs section for more detail."
},
{
"heading": "Remove Content Blocks",
Expand All @@ -49,27 +60,37 @@ fluid.defaults("sjrk.storyTelling.server.storiesDb", {
{
"heading": "Add Descriptions (Metadata) to Content Blocks",
"blockType": "text",
"text": "Each block you add to your story includes a few extra text fields where you can enter additional information about the content of that block. This information is called ‘Metadata’ and it helps screen readers, search engines and other assistive technologies find and access the content of each block."
"text": "Each block you add to your story includes a few extra text fields where you can enter additional information about the content of that block. This optional information is called ‘Metadata’ and it helps screen readers, search engines and other assistive technologies find and access the content of each block."
},
{
"heading": "Add Story Title, Author Name and Keywords",
"blockType": "text",
"text": "When you've added all the blocks to your story, select \"Continue\" to give your story a title, author name and some keywords. This information helps others find your story and attribute it to you when they are reusing it. If you plan to enter several keywords, make sure they are separated by a comma."
"text": "When you've added all the blocks to your story, select Continue to give your story a title, author name and some keywords. This information helps others find your story and attribute it to you when they are reusing it. If you plan to enter several keywords, make sure they are separated by a comma."
},
{
"heading": "Preview Story",
"blockType": "text",
"text": "Selecting the “Preview My Story” button will display how your story will look like when it is published. You can always select the “Back” button to go to the previous section and edit your story."
"text": "Selecting the “Preview My Story” button will display your story as it will appear when published. You can always select the “Back” button to go back to the previous section and continue editing your story."
},
{
"heading": "Publish Story",
"blockType": "text",
"text": "Once you are ready to publish your story on The Storytelling Project website, you can select the “Publish My Story” button. Please note that published stories are licensed under Creative Commons Attribution BY 4.0. This means others can reuse the content, make modifications, and attribute to the original author. Published stories are not editable and you cannot remove them from the site.\n\nIf you wish to remove your story from the website, please send an email to the address listed on the footer to request removal of your story."
},
{
"heading": "Saving Your Story",
"blockType": "text",
"text": "A draft of your story is saved automatically as you work. Text entered into an active text field will not be saved until you navigate out of that text field.\n\nIf you close the Story Tool browser window without publishing your story, your draft will be loaded the next time you open the story tool, as long as you are using the same browser on the same device. At the moment, files (such as videos, images or audio clips) will not be saved with your story, so you will have to add them back in again after loading your story (see Currently Known Bugs section)."
},
{
"heading": "Browse Stories",
"blockType": "text",
"text": "Select the “Browse Stories” button on the main page to browse through a collection of published stories by various contributors."
"text": "Select the “Browse Stories” button to browse through a collection of published stories by various contributors."
},
{
"heading": "Currently Known Bugs",
"blockType": "text",
"text": "Thank you for your patience as we work on improving the Story Tool! Any feedback you can provide is very helpful. You can contact us at [email protected].\n#### Keyboard focus\n* Using the keyboard to navigate through the Story Builder, you will notice that when focus lands on the first block it encompasses all the buttons as well as the editable block fields.\n* This allows you to navigate from block to block using your keyboard up/down arrow keys, and to reorder your blocks using keyboard shortcuts (see Reorder Content Blocks section for more details).\n* At the moment, however, tabbing from one block to another will not move focus to the whole block, rather it will move focus to the first element within the block.\n* In addition, Shift-tab will not move focus to the whole block.\n* Currently, to focus the whole block, the author must use the keyboard to navigate back to the delete key and then back into the story edit area, or select the desired block using the mouse (mouse click in the upper bar of the block, or on the reorder handle).\n#### Up/down reorder buttons activation\n* The up/down reorder buttons on a newly added block will remain inactive until focus lands on any story block. To focus on a block, you can click/touch anywhere within the block or navigate to it with the keyboard.\n#### Auto-saving\n* At the moment, files (such as videos, images or audio clips) will not be saved with your story. If you close the Story Tool and return, only the text content of your story will be reloaded. You will have to add them back in again after loading your story.\n* Text entered into an active text field will not be saved until you navigate out of that text field.\n"
}],
"author": "IDRC",
"tags": [
Expand Down
2 changes: 1 addition & 1 deletion src/ui/base-page-storyEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENS
args: [false],
namespace: "hideEditorShowPreviewer"
}],
"{storyEditor}.events.onReadyToBind": {
"{storyEditor}.events.onStoryUiReady": {
funcName: "sjrk.storyTelling.base.page.storyEdit.loadStoryFromAutosave",
args: [
"{that}.options.pageSetup.storyAutosaveKey",
Expand Down
5 changes: 4 additions & 1 deletion src/ui/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENS
//blockType: "", // to be supplied by implementing block formats
id: null,
language: null,
heading: null
heading: null,
order: 0,
firstInOrder: true,
lastInOrder: true
}
});

Expand Down
84 changes: 81 additions & 3 deletions src/ui/blockUi-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ You may obtain a copy of the BSD License at
https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENSE.txt
*/

/* global fluid */
/* global fluid, sjrk */

"use strict";

Expand All @@ -16,9 +16,72 @@ https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENS
// the base blockUi for editing individual blocks, contains shared elements
fluid.defaults("sjrk.storyTelling.blockUi.editor", {
gradeNames: ["sjrk.storyTelling.blockUi"],
model: {
// reorder buttons are disabled depending on the block's order:
// if the block is first in the order, the "up" button is disabled
// if the block is last in the order, the "down" button is disabled
moveBlockDownDisabled: "{block}.model.lastInOrder",
moveBlockUpDisabled: "{block}.model.firstInOrder"
},
modelListeners: {
// The use of excludeSource: ["init"] in these two model listeners
// is to prevent calling the invoker on model initialization, which
// would have no effect as it would occur before the template is
// rendered. This can be improved with some changes to the templateManager
// grade which are described in SJRK-364:
// https://issues.fluidproject.org/browse/SJRK-364
//
// This is also discussed in review for SJRK-288/SJRK-359 pull request:
// https://github.com/fluid-project/sjrk-story-telling/pull/84#pullrequestreview-431017684
"moveBlockDownDisabled": {
func: "{that}.setButtonDisabled",
args: ["{that}.dom.moveBlockDownButton", "{change}.value"],
excludeSource: ["init"],
namespace: "setMoveBlockDownDisabled"
},
"moveBlockUpDisabled": {
func: "{that}.setButtonDisabled",
args: ["{that}.dom.moveBlockUpButton", "{change}.value"],
excludeSource: ["init"],
namespace: "setMoveBlockUpDisabled"
}
},
selectors: {
moveBlockDownButton: ".sjrkc-st-reorderer-move-down",
moveBlockUpButton: ".sjrkc-st-reorderer-move-up",
selectedCheckbox: ".sjrkc-st-block-selection-checkbox"
},
events: {
onReadyToBind: null,
onMoveBlock: null
},
invokers: {
setButtonDisabled: "sjrk.storyTelling.blockUi.editor.setButtonDisabled"
},
listeners: {
"onReadyToBind": [{
this: "{that}.dom.moveBlockDownButton",
method: "click",
args: [fluid.direction.DOWN, "{that}.events.onMoveBlock.fire"],
namespace: "bindBlockDownButton"
},
{
this: "{that}.dom.moveBlockUpButton",
method: "click",
args: [fluid.direction.UP, "{that}.events.onMoveBlock.fire"],
namespace: "bindBlockUpButton"
},
{
func: "{that}.setButtonDisabled",
args: ["{that}.dom.moveBlockDownButton", "{that}.model.moveBlockDownDisabled"],
namespace: "setMoveBlockDownDisabledOnReady"
},
{
func: "{that}.setButtonDisabled",
args: ["{that}.dom.moveBlockUpButton", "{that}.model.moveBlockUpDisabled"],
namespace: "setMoveBlockUpDisabledOnReady"
}]
},
components: {
// binds user input DOM elements to model values on the block
binder: {
Expand All @@ -32,12 +95,27 @@ https://raw.githubusercontent.com/fluid-project/sjrk-story-telling/master/LICENS
bindings: {
heading: "heading"
},
events: {
onUiReadyToBind: "{templateManager}.events.onTemplateRendered"
listeners: {
"{editor}.events.onReadyToBind": {
func: "{that}.events.onUiReadyToBind",
namespace: "applyBinding"
}
}
}
},
// loads the localized messages and template for the block
templateManager: {
options: {
listeners: {
"onTemplateRendered.escalate": "{editor}.events.onReadyToBind"
}
}
}
}
});

sjrk.storyTelling.blockUi.editor.setButtonDisabled = function (button, isDisabled) {
$(button).prop("disabled", isDisabled);
};

})(jQuery, fluid);
Loading

0 comments on commit 124ca75

Please sign in to comment.