diff --git a/docker/obojobo-pm2-server-src/package.json b/docker/obojobo-pm2-server-src/package.json
index f5fbe899a..20b8752d1 100644
--- a/docker/obojobo-pm2-server-src/package.json
+++ b/docker/obojobo-pm2-server-src/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-pm2-server-app",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"description": "Reference project for deploying and customizing an Obojobo Next server",
"main": "./index.js",
"private": true,
diff --git a/lerna.json b/lerna.json
index af92c7967..ffd670396 100644
--- a/lerna.json
+++ b/lerna.json
@@ -2,7 +2,7 @@
"packages": [
"packages/**/*"
],
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"command": {
"command": {
"run": {
diff --git a/package.json b/package.json
index 12d53537a..40baf21ac 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "obojobo-next",
- "version": "15.1.1",
+ "version": "16.0.0",
"repository": "https://github.com/ucfopen/Obojobo.git",
"homepage": "https://ucfopen.github.io/Obojobo-Docs/",
"license": "AGPL-3.0-only",
diff --git a/packages/app/obojobo-document-engine/__tests__/oboeditor/components/visual-editor.test.js b/packages/app/obojobo-document-engine/__tests__/oboeditor/components/visual-editor.test.js
index 7bd38f546..f117adbe7 100644
--- a/packages/app/obojobo-document-engine/__tests__/oboeditor/components/visual-editor.test.js
+++ b/packages/app/obojobo-document-engine/__tests__/oboeditor/components/visual-editor.test.js
@@ -13,7 +13,6 @@ import { FULL } from 'obojobo-express/server/constants'
import { Editor, Transforms } from 'slate'
import { ReactEditor } from 'slate-react'
-// jest.mock('slate')
jest.mock('src/scripts/viewer/util/editor-api')
jest.mock('src/scripts/common/util/modal-util')
jest.mock('src/scripts/oboeditor/components/node/editor', () => ({
@@ -1436,4 +1435,290 @@ describe('VisualEditor', () => {
document.body.removeChild(input)
})
+
+ describe('keyboard navigation', () => {
+ const editorChildren = JSON.stringify([
+ { children: [{ text: 'Header [0,0]' }] },
+ { children: [{ children: [{ text: 'Text before excerpt [1,0,0]' }] }] },
+ {
+ children: [
+ {
+ children: [
+ { children: [{ text: 'Excerpt Header [2,0,0,0]' }] },
+ { children: [{ children: [{ text: 'Initial Excerpt Text [2,0,1,0,0]' }] }] },
+ {
+ content: { numCols: 2, numRows: 2 },
+ children: [
+ {
+ content: { numCols: 2 },
+ children: [
+ { children: [{ text: 'Table Header A [2,0,2,0,0,0]' }] },
+ { children: [{ text: 'Table Header B [2,0,2,0,1,0]' }] }
+ ]
+ },
+ {
+ content: { numCols: 2 },
+ children: [
+ { children: [{ text: 'Cell A [2,0,2,1,0,0]' }] },
+ { children: [{ text: 'Cell B [2,0,2,1,1,0]' }] }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ { children: [{ children: [{ text: 'Excerpt Caption [2,1,0,0]' }] }] }
+ ]
+ },
+ { children: [{ children: [{ text: 'Text after the excerpt [3,0,0]' }] }] }
+ ])
+
+ const pathToSelection = path => {
+ return { anchor: { path: path, offset: 0 }, focus: { path: path, offset: 0 } }
+ }
+
+ let component
+ let instance
+ // eslint-disable-next-line prefer-const
+ let keyDownEvent = {
+ preventDefault: jest.fn(),
+ defaultPrevented: false,
+ referredFromTable: false
+ }
+
+ jest.spyOn(VisualEditor.prototype, 'globalPluginsOverrideKeypress').mockReturnValue(false)
+ jest.spyOn(VisualEditor.prototype, 'localPluginsOverrideKeypress').mockReturnValue(false)
+ jest.spyOn(Transforms, 'setSelection').mockImplementation((editor, range) => {
+ editor.prevSelection = JSON.parse(JSON.stringify(editor.selection || {}))
+ editor.selection = JSON.parse(JSON.stringify(range))
+ })
+
+ test('Up arrow: from the top node should not change the selection location', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowUp'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([0, 0])
+ })
+
+ test('Down arrow: from the bottom node should not change the selection location', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [3, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowDown'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([3, 0, 0])
+ })
+
+ test('Up arrow: from one node to a sibling node of the same depth', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [1, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowUp'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([0, 0])
+ })
+
+ test('Down arrow: from one node to a sibling node of the same depth', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowDown'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([1, 0, 0])
+ })
+
+ test('Up arrow: from one node inside an excerpt to a node outside the excerpt', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [2, 0, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowUp'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([1, 0, 0])
+ })
+
+ test('Down arrow: from one node outside an excerpt to a node inside the excerpt', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [1, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowDown'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([2, 0, 0, 0])
+ })
+
+ test('Up arrow: from one node inside an excerpt to a sibling node inside the excerpt', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [2, 0, 1, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowUp'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([2, 0, 0, 0])
+ })
+
+ test('Down arrow: from one node inside an excerpt to a sibling node inside the excerpt', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [2, 0, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowDown'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([2, 0, 1, 0, 0])
+ })
+
+ test('Up arrow: from the first node below an excerpt to the bottom node inside', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [3, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowUp'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([2, 1, 0, 0])
+ })
+
+ test('Down arrow: from the bottom node inside an excerpt to the first below', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [2, 1, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowDown'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([3, 0, 0])
+ })
+
+ test('Up arrow: from the first node below a table to the last cell inside', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [2, 1, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowUp'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([2, 0, 2, 1, 1, 0])
+ })
+
+ test('Down arrow: from the last node above a table to the first cell inside', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [2, 0, 1, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowDown'
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([2, 0, 2, 0, 0, 0])
+ })
+
+ test('Up arrow: from the first row of a table to the last node above', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [2, 0, 2, 0, 1, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowUp'
+ keyDownEvent.referredFromTable = true
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([2, 0, 1, 0, 0])
+ })
+
+ test('Down arrow: from the last row of a table to the first node below', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [2, 0, 2, 1, 0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowDown'
+ keyDownEvent.referredFromTable = true
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([2, 1, 0, 0])
+ })
+
+ test('Up arrow: invalid starting path (too short)', () => {
+ component = mount()
+ instance = component.instance()
+ instance.editor.children = JSON.parse(editorChildren)
+
+ const startingPath = [0, 0]
+ const startingSelection = pathToSelection(startingPath)
+ Transforms.setSelection(instance.editor, startingSelection)
+
+ keyDownEvent.key = 'ArrowUp'
+ keyDownEvent.referredFromTable = true // This is pop some of the length off of the initial path inappropriately
+ instance.onKeyDown(keyDownEvent)
+
+ expect(instance.editor.selection.anchor.path).toEqual([0, 0])
+ })
+ })
})
diff --git a/packages/app/obojobo-document-engine/package.json b/packages/app/obojobo-document-engine/package.json
index 611964649..cf8359a48 100644
--- a/packages/app/obojobo-document-engine/package.json
+++ b/packages/app/obojobo-document-engine/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-document-engine",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "",
"engines": {
diff --git a/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/visual-editor.js b/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/visual-editor.js
index d5daaca4e..19eaf7c82 100644
--- a/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/visual-editor.js
+++ b/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/visual-editor.js
@@ -94,6 +94,8 @@ class VisualEditor extends React.Component {
this.markUnsaved = this.markUnsaved.bind(this)
this.onKeyDownGlobal = this.onKeyDownGlobal.bind(this)
this.onKeyDown = this.onKeyDown.bind(this)
+ this.globalPluginsOverrideKeypress = this.globalPluginsOverrideKeypress.bind(this)
+ this.localPluginsOverrideKeypress = this.localPluginsOverrideKeypress.bind(this)
this.decorate = this.decorate.bind(this)
this.renderLeaf = this.renderLeaf.bind(this)
this.renameModule = this.renameModule.bind(this)
@@ -337,7 +339,6 @@ class VisualEditor extends React.Component {
// Save the previous selection in case the editor is unfocused
// This mostly happens with MoreInfoBoxes and void nodes
if (this.editor.selection) this.editor.prevSelection = this.editor.selection
-
this.setState({ value })
this.markUnsaved()
}
@@ -514,13 +515,15 @@ class VisualEditor extends React.Component {
}
}
- // All the 'plugin' methods that allow the obonodes to extend the default functionality
- onKeyDown(event) {
+ globalPluginsOverrideKeypress(event) {
for (const plugin of this.globalPlugins) {
if (plugin.onKeyDown) plugin.onKeyDown(event, this.editor)
- if (event.defaultPrevented) return
+ if (event.defaultPrevented) return true
}
+ return false
+ }
+ localPluginsOverrideKeypress(event) {
// If none of the global plugins caught the key event,
// Get each component (non-subtype) node that is selected,
// and run keydown on each
@@ -541,38 +544,166 @@ class VisualEditor extends React.Component {
}
}
- // This fix breaks the default behavior when moving up inside an element. Needs to be reevaluated.
- /*****
- // Handle ArrowUp from a node - this is default behavior
- // in Chrome and Safari but not Firefox
- if (event.key === 'ArrowUp' && !event.defaultPrevented) {
- event.preventDefault()
+ return event.defaultPrevented
+ }
+
+ // All the 'plugin' methods that allow the obonodes to extend the default functionality
+ onKeyDown(event) {
+ if (this.globalPluginsOverrideKeypress(event)) return
+ if (this.localPluginsOverrideKeypress(event)) return
+
+ const getElementByPath = possiblePath => {
+ let slateElement = this.editor
+ for (let i = 0; i < possiblePath.length; i++) {
+ if (slateElement.children && slateElement.children[possiblePath[i]]) {
+ slateElement = slateElement.children[possiblePath[i]]
+ } else {
+ return false
+ }
+ }
+ return JSON.parse(JSON.stringify(slateElement))
+ }
- const currentNode = this.editor.selection.anchor.path[0]
+ // Given a known starting path, this function finds the last child of the last child of the last child...
+ // of that starting path. This is so navigating with the up arrow doesn't skip over child elements.
+ const getLastChild = startingPath => {
+ if (startingPath.length === 0) {
+ return [0]
+ }
- // Break out if already at top node
- if (currentNode === 0) return
+ let slateElement = getElementByPath(startingPath)
- const aboveNode = currentNode - 1
- const numChildrenAbove = this.editor.children[aboveNode].children.length
+ // eslint-disable-next-line prefer-const
+ let lengthenedPath = [...startingPath]
+ while (slateElement.children && slateElement.children.length > 0) {
+ lengthenedPath.push(slateElement.children.length - 1)
+ slateElement = slateElement.children[slateElement.children.length - 1]
+ }
+ return lengthenedPath
+ }
- let abovePath = [aboveNode]
+ // There are several built-in functions for SlateJS Paths (like Path.next or Path.previous), but with the
+ // odd ordering of objects (for instance, in Excerpts and Lists), it was far more effective to build our own
+ // functions to compute previous and next paths given a current path.
+ const getPreviousPath = currentPath => {
+ const depth = currentPath.length - 2
+ if (depth < 0) {
+ return false
+ }
- // If entering a node with multiple children (a table),
- // go to the last child (bottom row)
- if (numChildrenAbove > 1) {
- abovePath = [aboveNode, numChildrenAbove - 1]
+ // eslint-disable-next-line prefer-const
+ let nextPath = [...currentPath]
+
+ // Case 1: Going directly to a sibling of the same depth: [12, 0, 2, 4, 0] => [12, 0, 2, 3, 0]
+ if (currentPath[depth] !== 0) {
+ nextPath[depth]--
+ nextPath.pop()
+ return getLastChild(nextPath)
}
- const focus = Editor.start(this.editor, abovePath)
- const anchor = Editor.start(this.editor, abovePath)
+ // Case 2: Going from a child with one or more additional indents: [12, 0, 2, 0, 0] => [12, 0, 1, 0]
+ // With multiple indents, there could be LOTS of trailing zeroes: [12, 0, 2, 0, 0, 0, 0, 0, 0]
+ while (nextPath[nextPath.length - 1] === 0) {
+ nextPath.pop()
+ }
+ nextPath[nextPath.length - 1]--
+ return getLastChild(nextPath)
+ }
+
+ const getNextPath = currentPath => {
+ let depth
+ let nextPath
+ let extendedPath
+ // eslint-disable-next-line prefer-const
+ let initialPath = [...currentPath]
+
+ while (initialPath.length > 1) {
+ depth = initialPath.length - 2
+
+ // Check to see if there is a valid path for a direct sibling
+ nextPath = [...initialPath]
+ nextPath[depth]++
+ nextPath[depth + 1] = 0
+
+ // Dig deeper into the sibling node: [12, 0, 1, 0] => [12, 0, 2, 0, 0, 0] (This handles excerpts and lists)
+ extendedPath = [...nextPath]
+ for (let i = 0; i < 5; i++) {
+ extendedPath.push(0)
+ if (getElementByPath(extendedPath)) {
+ nextPath = [...extendedPath]
+ }
+ }
- Transforms.setSelection(this.editor, {
- focus,
- anchor
- })
+ if (getElementByPath(nextPath)) {
+ return nextPath
+ }
+
+ // If there is no sibling on this level, go up to the parent level.
+ initialPath.pop()
+ }
+ return false
+ }
+
+ // The following code checks to see if the editor should switch focus.
+ if (event.key === 'ArrowUp') {
+ /* The editor's path is an array that says where in the editor you are.
+ * [2, 1] = Third element, 2nd sub-element (like a row in a text box)
+ * [4, 2, 3] = Fifth element, 3rd sub-element (row), 4th sub-sub-element (column)
+ *
+ * A major issue is excerpts, which contain standard "root" element types (text, tables,
+ * lists, etc) that are all one layer deeper than expected since the excerpt itself is at
+ * index 0.
+ */
+ // eslint-disable-next-line prefer-const
+ let currentPath = [...this.editor?.selection?.focus?.path]
+
+ // Tables' paths have unexpected numbers of layers to account for their rows and columns.
+ // In order to leave the element properly, we need to pop off those layers.
+ if (event.referredFromTable) {
+ event.referredFromTable = false
+ currentPath.pop()
+ currentPath.pop()
+ }
+
+ const newPath = getPreviousPath(currentPath)
+ if (!newPath) {
+ return
+ }
+
+ const newPoint = Editor.start(this.editor, newPath)
+ const newRange = {
+ focus: newPoint,
+ anchor: newPoint
+ }
+ Transforms.setSelection(this.editor, newRange)
+
+ event.preventDefault()
+ }
+
+ // The following code checks to see if the editor should switch focus.
+ if (event.key === 'ArrowDown') {
+ // eslint-disable-next-line prefer-const
+ let currentPath = [...this.editor?.selection?.focus?.path]
+ if (event.referredFromTable) {
+ event.referredFromTable = false
+ currentPath.pop()
+ currentPath.pop()
+ }
+
+ const newPath = getNextPath(currentPath)
+ if (!newPath) {
+ return
+ }
+
+ const newPoint = Editor.start(this.editor, newPath)
+ const newRange = {
+ focus: newPoint,
+ anchor: newPoint
+ }
+ Transforms.setSelection(this.editor, newRange)
+
+ event.preventDefault()
}
- *****/
}
// Generates any necessary decorations, such as place holders
diff --git a/packages/app/obojobo-document-json-parser/package.json b/packages/app/obojobo-document-json-parser/package.json
index eeeec220f..6602fbce2 100644
--- a/packages/app/obojobo-document-json-parser/package.json
+++ b/packages/app/obojobo-document-json-parser/package.json
@@ -3,11 +3,11 @@
"xml-formatter": "^2.4.0"
},
"peerDependencies": {
- "obojobo-document-engine": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-document-engine": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0"
},
"name": "obojobo-document-json-parser",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"main": "",
"scripts": {
diff --git a/packages/app/obojobo-document-xml-parser/package.json b/packages/app/obojobo-document-xml-parser/package.json
index 56f701aaf..f9e38dc55 100644
--- a/packages/app/obojobo-document-xml-parser/package.json
+++ b/packages/app/obojobo-document-xml-parser/package.json
@@ -4,10 +4,10 @@
"xml-js": "^1.0.2"
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"name": "obojobo-document-xml-parser",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"main": "xml2draft.js",
"scripts": {
diff --git a/packages/app/obojobo-express/package.json b/packages/app/obojobo-express/package.json
index 71d3a2511..be1ec5ae8 100644
--- a/packages/app/obojobo-express/package.json
+++ b/packages/app/obojobo-express/package.json
@@ -1,7 +1,7 @@
{
"name": "obojobo-express",
"license": "AGPL-3.0-only",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"repository": "https://github.com/ucfopen/Obojobo.git",
"homepage": "https://ucfopen.github.io/Obojobo-Docs/",
"description": "Obojobo express server middleware.",
@@ -69,9 +69,9 @@
"uuid": "^8.3.2"
},
"peerDependencies": {
- "obojobo-document-engine": "^16.0.0-alpha.0",
- "obojobo-document-xml-parser": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-document-engine": "^16.0.0",
+ "obojobo-document-xml-parser": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0"
},
"devDependencies": {
"@svgr/webpack": "^5.5.0",
diff --git a/packages/app/obojobo-module-selector/package.json b/packages/app/obojobo-module-selector/package.json
index 403b9317c..409b56602 100644
--- a/packages/app/obojobo-module-selector/package.json
+++ b/packages/app/obojobo-module-selector/package.json
@@ -1,7 +1,7 @@
{
"name": "obojobo-module-selector",
"license": "AGPL-3.0-only",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"repository": "https://github.com/ucfopen/Obojobo.git",
"homepage": "https://ucfopen.github.io/Obojobo-Docs/",
"description": "Obojobo package responsible for selecting which module you use in a course.",
@@ -29,8 +29,8 @@
"express": "~4.18.2"
},
"peerDependencies": {
- "obojobo-express": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0",
- "obojobo-repository": "^16.0.0-alpha.0"
+ "obojobo-express": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0",
+ "obojobo-repository": "^16.0.0"
}
}
diff --git a/packages/app/obojobo-repository/package.json b/packages/app/obojobo-repository/package.json
index 082e132f7..042aff348 100644
--- a/packages/app/obojobo-repository/package.json
+++ b/packages/app/obojobo-repository/package.json
@@ -1,7 +1,7 @@
{
"name": "obojobo-repository",
"license": "AGPL-3.0-only",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"repository": "https://github.com/ucfopen/Obojobo.git",
"homepage": "https://ucfopen.github.io/Obojobo-Docs/",
"description": "Obojobo express server middleware.",
@@ -46,8 +46,8 @@
"use-debounce": "^7.0.0"
},
"peerDependencies": {
- "obojobo-express": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-express": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"setupFilesAfterEnv": [
diff --git a/packages/obonode/obojobo-chunks-abstract-assessment/package.json b/packages/obonode/obojobo-chunks-abstract-assessment/package.json
index d4d261090..f492ae0fb 100644
--- a/packages/obonode/obojobo-chunks-abstract-assessment/package.json
+++ b/packages/obonode/obojobo-chunks-abstract-assessment/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-abstract-assessment",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "AbstractAssessment chunk for Obojobo",
"scripts": {
@@ -28,8 +28,8 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-chunks-question": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-chunks-question": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0"
},
"devDependencies": {
"lint-staged": "^10.2.2"
diff --git a/packages/obonode/obojobo-chunks-action-button/package.json b/packages/obonode/obojobo-chunks-action-button/package.json
index 05cdc1600..a50f70d02 100644
--- a/packages/obonode/obojobo-chunks-action-button/package.json
+++ b/packages/obonode/obojobo-chunks-action-button/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-action-button",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"scripts": {
"test": "TZ='America/New_York' jest --verbose",
@@ -20,7 +20,7 @@
]
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-break/package.json b/packages/obonode/obojobo-chunks-break/package.json
index 2a8f67795..310cc946a 100644
--- a/packages/obonode/obojobo-chunks-break/package.json
+++ b/packages/obonode/obojobo-chunks-break/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-break",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Break content chunk for Obojobo",
"scripts": {
@@ -21,7 +21,7 @@
]
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-code/package.json b/packages/obonode/obojobo-chunks-code/package.json
index 6329d89ae..bea55e223 100644
--- a/packages/obonode/obojobo-chunks-code/package.json
+++ b/packages/obonode/obojobo-chunks-code/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-code",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Code content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-excerpt/package.json b/packages/obonode/obojobo-chunks-excerpt/package.json
index 1f26897c0..953cd61dd 100644
--- a/packages/obonode/obojobo-chunks-excerpt/package.json
+++ b/packages/obonode/obojobo-chunks-excerpt/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-excerpt",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Excerpt content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-figure/package.json b/packages/obonode/obojobo-chunks-figure/package.json
index cc1957130..482c8bef2 100644
--- a/packages/obonode/obojobo-chunks-figure/package.json
+++ b/packages/obonode/obojobo-chunks-figure/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-figure",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Figure content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-heading/package.json b/packages/obonode/obojobo-chunks-heading/package.json
index 7edef4923..e6610ea36 100644
--- a/packages/obonode/obojobo-chunks-heading/package.json
+++ b/packages/obonode/obojobo-chunks-heading/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-heading",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Heading content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-html/package.json b/packages/obonode/obojobo-chunks-html/package.json
index 747d57963..070ee5a9b 100644
--- a/packages/obonode/obojobo-chunks-html/package.json
+++ b/packages/obonode/obojobo-chunks-html/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-html",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "HTML content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-iframe/package.json b/packages/obonode/obojobo-chunks-iframe/package.json
index 9eb421187..bcc075231 100644
--- a/packages/obonode/obojobo-chunks-iframe/package.json
+++ b/packages/obonode/obojobo-chunks-iframe/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-iframe",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "IFrame content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-list/package.json b/packages/obonode/obojobo-chunks-list/package.json
index 22928ca54..4b4f7b9db 100644
--- a/packages/obonode/obojobo-chunks-list/package.json
+++ b/packages/obonode/obojobo-chunks-list/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-list",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "List content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-materia/package.json b/packages/obonode/obojobo-chunks-materia/package.json
index d2f8c9c62..2ed023a90 100644
--- a/packages/obonode/obojobo-chunks-materia/package.json
+++ b/packages/obonode/obojobo-chunks-materia/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-materia",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Materia content chunk for Obojobo",
"scripts": {
@@ -35,9 +35,9 @@
"lint-staged": "^10.5.4"
},
"peerDependencies": {
- "obojobo-chunks-iframe": "^16.0.0-alpha.0",
- "obojobo-document-engine": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-chunks-iframe": "^16.0.0",
+ "obojobo-document-engine": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-math-equation/package.json b/packages/obonode/obojobo-chunks-math-equation/package.json
index ac31820c1..5441f1d8e 100644
--- a/packages/obonode/obojobo-chunks-math-equation/package.json
+++ b/packages/obonode/obojobo-chunks-math-equation/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-math-equation",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "MathEquation content chunk for Obojobo",
"scripts": {
@@ -30,7 +30,7 @@
"katex": "^0.13.1"
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json b/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json
index b12d52f9d..7c226c20c 100644
--- a/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json
+++ b/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-multiple-choice-assessment",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "MCAssessment chunk for Obojobo",
"scripts": {
@@ -27,8 +27,8 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-chunks-question": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-chunks-question": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-numeric-assessment/package.json b/packages/obonode/obojobo-chunks-numeric-assessment/package.json
index 0a3972dd0..d85fff201 100644
--- a/packages/obonode/obojobo-chunks-numeric-assessment/package.json
+++ b/packages/obonode/obojobo-chunks-numeric-assessment/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-numeric-assessment",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "NumericAssessment chunk for Obojobo",
"scripts": {
@@ -30,8 +30,8 @@
"big.js": "^6.1.1"
},
"peerDependencies": {
- "obojobo-chunks-question": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-chunks-question": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-question-bank/package.json b/packages/obonode/obojobo-chunks-question-bank/package.json
index d858f4b69..aca8aed5e 100644
--- a/packages/obonode/obojobo-chunks-question-bank/package.json
+++ b/packages/obonode/obojobo-chunks-question-bank/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-question-bank",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "QuestionBank chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-question/package.json b/packages/obonode/obojobo-chunks-question/package.json
index da3ebda29..5fb7edfbc 100644
--- a/packages/obonode/obojobo-chunks-question/package.json
+++ b/packages/obonode/obojobo-chunks-question/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-question",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Question content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-table/editor-registration.js b/packages/obonode/obojobo-chunks-table/editor-registration.js
index c3defba7f..682b7bae8 100644
--- a/packages/obonode/obojobo-chunks-table/editor-registration.js
+++ b/packages/obonode/obojobo-chunks-table/editor-registration.js
@@ -41,9 +41,23 @@ const plugins = {
// Editable Plugins - These are used by the PageEditor component to augment React functions
// They affect individual nodes independently of one another
onKeyDown(entry, editor, event) {
+ const computeModifiedPath = (node, row, col) => {
+ // eslint-disable-next-line prefer-const
+ let newPath = [...editor.selection.anchor.path]
+ newPath[newPath.length - 4] = node
+ newPath[newPath.length - 3] = row
+ newPath[newPath.length - 2] = col
+ return newPath
+ }
// Calculate next path based on direction given
const calculateNextPath = direction => {
- const [node, row, col] = editor.selection.anchor.path
+ const currentPath = editor.selection.anchor.path
+ if (currentPath.length < 4) {
+ return currentPath
+ }
+ const col = currentPath[currentPath.length - 2]
+ const row = currentPath[currentPath.length - 3]
+ const node = currentPath[currentPath.length - 4]
const numCols = editor.children[node].content.numCols
@@ -51,63 +65,51 @@ const plugins = {
switch (direction) {
case 'down':
- nextPath = [node, row + 1, col]
+ nextPath = computeModifiedPath(node, row + 1, col)
break
case 'right':
- nextPath = [node, row, col + 1]
+ nextPath = computeModifiedPath(node, row, col + 1)
break
case 'up':
- nextPath = [node, row - 1, col]
+ nextPath = computeModifiedPath(node, row - 1, col)
break
case 'left':
- nextPath = [node, row, col - 1]
+ nextPath = computeModifiedPath(node, row, col - 1)
break
}
// If next path is valid, jump to it
if (Node.has(editor, nextPath)) {
return nextPath
- } else if (direction === 'right' && Node.has(editor, [node, row + 1, 0])) {
+ } else if (direction === 'right' && Node.has(editor, computeModifiedPath(node, row + 1, 0))) {
// If moving right but already at rightmost cell, move to beginning of the row below
- return [node, row + 1, 0]
- } else if (direction === 'left' && Node.has(editor, [node, row - 1, numCols - 1])) {
+ return computeModifiedPath(node, row + 1, 0)
+ } else if (
+ direction === 'left' &&
+ Node.has(editor, computeModifiedPath(node, row - 1, numCols - 1))
+ ) {
// If moving left but already at leftmost cell, move to end of the row above
- return [node, row - 1, numCols - 1]
- } else if (direction === 'up' && Node.has(editor, [node - 1])) {
- // Move to node above table
- return [node - 1]
- } else if (direction === 'down' && Node.has(editor, [node + 1])) {
- // Move to node below table
- return [node + 1]
+ return computeModifiedPath(node, row - 1, numCols - 1)
}
-
- // If no adjacent paths, return current path
- return editor.selection.anchor.path
+ // If no valid paths, fail gracefully
+ return false
}
// Move editor selection based on direction given
const moveCursor = direction => {
- const currentPath = editor.selection.anchor.path
const nextPath = calculateNextPath(direction)
-
- const isExitingTable = nextPath[0] !== currentPath[0]
-
- if (nextPath !== currentPath) {
- const focus = Editor.start(editor, nextPath)
- let anchor
-
- // If exiting table, do not select entire content of new node
- if (isExitingTable) {
- anchor = focus
- } else {
- anchor = Editor.end(editor, nextPath)
- }
-
- Transforms.setSelection(editor, {
- focus,
- anchor
- })
+ if (!nextPath) {
+ event.referredFromTable = true
+ return
}
+
+ const focus = Editor.start(editor, nextPath)
+ const anchor = Editor.end(editor, nextPath)
+ Transforms.setSelection(editor, {
+ focus,
+ anchor
+ })
+ event.preventDefault()
}
switch (event.key) {
@@ -117,7 +119,6 @@ const plugins = {
case 'Enter':
case 'ArrowDown':
- event.preventDefault()
moveCursor('down')
break
@@ -125,8 +126,6 @@ const plugins = {
// If shift isn't pressed and editing text, allow tab navigation to dropdown menu
if (!event.shiftKey && Range.isCollapsed(editor.selection)) break
- event.preventDefault()
-
// Handle Shift+Tab left navigation
if (event.shiftKey) {
moveCursor('left')
@@ -142,7 +141,6 @@ const plugins = {
// If pressing Ctrl or Command, deselect text
if (event.metaKey || event.ctrlKey) break
- event.preventDefault()
moveCursor('right')
break
@@ -153,12 +151,10 @@ const plugins = {
// If pressing Ctrl or Command, deselect text
if (event.metaKey || event.ctrlKey) break
- event.preventDefault()
moveCursor('left')
break
case 'ArrowUp':
- event.preventDefault()
moveCursor('up')
break
}
diff --git a/packages/obonode/obojobo-chunks-table/editor-registration.test.js b/packages/obonode/obojobo-chunks-table/editor-registration.test.js
index 87007c656..18bdb114a 100644
--- a/packages/obonode/obojobo-chunks-table/editor-registration.test.js
+++ b/packages/obonode/obojobo-chunks-table/editor-registration.test.js
@@ -173,8 +173,8 @@ describe('Table editor', () => {
test('plugins.onKeyDown deals with [Enter]', () => {
editor.selection = {
- anchor: { path: [1, 0, 0], offset: 1 },
- focus: { path: [1, 0, 0], offset: 3 }
+ anchor: { path: [1, 0, 0, 0], offset: 1 },
+ focus: { path: [1, 0, 0, 0], offset: 3 }
}
const event = {
@@ -189,8 +189,8 @@ describe('Table editor', () => {
test('plugins.onKeyDown deals with [ArrowDown]', () => {
editor.selection = {
- anchor: { path: [1, 0, 0], offset: 1 },
- focus: { path: [1, 0, 0], offset: 3 }
+ anchor: { path: [1, 0, 0, 0], offset: 1 },
+ focus: { path: [1, 0, 0, 0], offset: 3 }
}
const event = {
@@ -205,8 +205,8 @@ describe('Table editor', () => {
test('plugins.onKeyDown deals with [ArrowUp]', () => {
editor.selection = {
- anchor: { path: [1, 1, 0], offset: 1 },
- focus: { path: [1, 1, 0], offset: 3 }
+ anchor: { path: [1, 1, 0, 0], offset: 1 },
+ focus: { path: [1, 1, 0, 0], offset: 3 }
}
const event = {
@@ -408,8 +408,7 @@ describe('Table editor', () => {
}
Table.plugins.onKeyDown([editor.children[1], [0]], editor, event)
- expect(event.preventDefault).toHaveBeenCalled()
- expect(editor.selection.anchor.path).toEqual([1, 0, 0, 0])
+ expect(event.preventDefault).not.toHaveBeenCalled()
})
test('plugins.onKeyDown deals with [ArrowUp] to content above table', () => {
@@ -424,8 +423,7 @@ describe('Table editor', () => {
}
Table.plugins.onKeyDown([editor.children[1], [0]], editor, event)
- expect(event.preventDefault).toHaveBeenCalled()
- expect(editor.selection.anchor.path).toEqual([0, 0, 0])
+ expect(event.preventDefault).not.toHaveBeenCalled()
})
test('plugins.onKeyDown deals with [ArrowDown] to content below table', () => {
@@ -439,9 +437,23 @@ describe('Table editor', () => {
preventDefault: jest.fn()
}
+ Table.plugins.onKeyDown([editor.children[1], [0]], editor, event)
+ expect(event.preventDefault).not.toHaveBeenCalled()
+ })
+
+ test('plugins.onKeyDown reverts to default when invalid paths are used', () => {
+ editor.selection = {
+ anchor: { path: [1, 1, 0], offset: 2 },
+ focus: { path: [1, 1, 0], offset: 4 }
+ }
+
+ const event = {
+ key: 'ArrowDown',
+ preventDefault: jest.fn()
+ }
+
Table.plugins.onKeyDown([editor.children[1], [0]], editor, event)
expect(event.preventDefault).toHaveBeenCalled()
- expect(editor.selection.anchor.path).toEqual([2, 0, 0])
})
test('plugins.onKeyDown deals with [Backspace]', () => {
diff --git a/packages/obonode/obojobo-chunks-table/package.json b/packages/obonode/obojobo-chunks-table/package.json
index dcc77f12d..a5fe84acc 100644
--- a/packages/obonode/obojobo-chunks-table/package.json
+++ b/packages/obonode/obojobo-chunks-table/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-table",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Table content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-text/package.json b/packages/obonode/obojobo-chunks-text/package.json
index e571bade9..0fdf3ed0c 100644
--- a/packages/obonode/obojobo-chunks-text/package.json
+++ b/packages/obonode/obojobo-chunks-text/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-text",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Text content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-chunks-youtube/package.json b/packages/obonode/obojobo-chunks-youtube/package.json
index 33b982a77..165c7c863 100644
--- a/packages/obonode/obojobo-chunks-youtube/package.json
+++ b/packages/obonode/obojobo-chunks-youtube/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-chunks-youtube",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Youtube content chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-modules-module/package.json b/packages/obonode/obojobo-modules-module/package.json
index f4e4da0db..9a657925c 100644
--- a/packages/obonode/obojobo-modules-module/package.json
+++ b/packages/obonode/obojobo-modules-module/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-modules-module",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Default Module node for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-pages-page/package.json b/packages/obonode/obojobo-pages-page/package.json
index b821249c9..4649a7601 100644
--- a/packages/obonode/obojobo-pages-page/package.json
+++ b/packages/obonode/obojobo-pages-page/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-pages-page",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Page chunk for Obojobo",
"scripts": {
@@ -27,8 +27,8 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-document-engine": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-document-engine": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-sections-assessment/package.json b/packages/obonode/obojobo-sections-assessment/package.json
index d0e919697..6d9d61282 100644
--- a/packages/obonode/obojobo-sections-assessment/package.json
+++ b/packages/obonode/obojobo-sections-assessment/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-sections-assessment",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Assessment section for Obojobo",
"scripts": {
@@ -27,8 +27,8 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-document-engine": "^16.0.0-alpha.0",
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-document-engine": "^16.0.0",
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/obonode/obojobo-sections-content/package.json b/packages/obonode/obojobo-sections-content/package.json
index bfed2c9e6..d2f511c69 100644
--- a/packages/obonode/obojobo-sections-content/package.json
+++ b/packages/obonode/obojobo-sections-content/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-sections-content",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Content section chunk for Obojobo",
"scripts": {
@@ -27,7 +27,7 @@
"singleQuote": true
},
"peerDependencies": {
- "obojobo-lib-utils": "^16.0.0-alpha.0"
+ "obojobo-lib-utils": "^16.0.0"
},
"jest": {
"testMatch": [
diff --git a/packages/util/eslint-config-obojobo/package.json b/packages/util/eslint-config-obojobo/package.json
index f5a1dbb30..b2249827b 100644
--- a/packages/util/eslint-config-obojobo/package.json
+++ b/packages/util/eslint-config-obojobo/package.json
@@ -1,6 +1,6 @@
{
"name": "eslint-config-obojobo",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"scripts": {
"lint": "echo 'not implemented'",
diff --git a/packages/util/obojobo-lib-utils/package.json b/packages/util/obojobo-lib-utils/package.json
index 5bd1336f5..072f887a7 100644
--- a/packages/util/obojobo-lib-utils/package.json
+++ b/packages/util/obojobo-lib-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "obojobo-lib-utils",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"description": "Assortment of reusable parts for obojobo libraries.",
"scripts": {
diff --git a/packages/util/stylelint-config-obojobo/package.json b/packages/util/stylelint-config-obojobo/package.json
index 6161a6e63..e70ac7648 100644
--- a/packages/util/stylelint-config-obojobo/package.json
+++ b/packages/util/stylelint-config-obojobo/package.json
@@ -1,6 +1,6 @@
{
"name": "stylelint-config-obojobo",
- "version": "16.0.0-alpha.0",
+ "version": "16.0.0",
"license": "AGPL-3.0-only",
"scripts": {
"lint": "echo 'not implemented'",