Skip to content

Commit 80ddbb9

Browse files
darrensiegelThinkThoughtThunk
authored andcommitted
Sprint 0.36.0 (#720)
* reapply even likert changes (#680) * 2012 - editor resize using 'react-measure' * change resizing method * remove dependency * Authoring 2058 xref cleared (#681) * fixed hasTargetChanged function to update correctly * fixed xref clearing, looking into brief display of target error * cleaned up code * made recommended changes * Authoring 2043 reference error (#679) * starting work on 2043 and 2025 on this branch. converting refs to resources * removed deleted and duplicate references, and now also sort by ref type and title * made suggested changes * fixed typo of using || instead of && * have band-aid solution of setting maxLines to 45, min to 35, which re… (#677) * bump version * have band-aid solution of setting maxLines to 45, min to 35, which results in usually using all available screen space. does not work as well when a banner is present. recommend eventually switching to a height dependent on screen size. * recommended changes made * updated version to 33.0 * bind rectangle and circle hotspots within boundaries (#687) * Add team members description (#685) * Authoring 2018 likert hotfix (#682) * allow for even number of likert entries * set version * add team members description * package version * accidental save format * change wording * Fix error thrown sometimes on objective skill view (#684) * Authoring 2018 likert hotfix (#682) * allow for even number of likert entries * set version * prevent type error * version * allow resource scoped messages for objectives view (#689) * Limit package id and org id lengths (#690) * change package id length on creation * remove package id 20 char restriction * Remove responses that point to answer choices that don't exist (#688) * clean up missing responses on question persistence * remove unused import * add tests * more * Finish tests * Remove console log * add comment * style fix * do not strip out * match * Add support for learning dependencies in workbook page editor (#691) * working learning prereq editor * finish removing comments * version uptick * Fix assessment rendering when toggling branching assessment (#693) * fix branching rendering issue * remove comments * remove another comment * remove unused import * fix data loss issue (#695) * Preserve missing scores when parsing questions (#692) * start making score optional * Add unit tests and finish score parsing * fix advanced scoring in ordering * fix default score * change score box logic * finish score box logic * Authoring 2108 slate (#694) * stashing * round trip saving working * clean contiguous.ts * towards full compilation * major streamlining * towards inputref restoration * basic inputref is working * set the input ref type * Fix block splitting logic * fix all mark persistence, rendering * active input ref tracking and display * input ref rendering * click to activate inlines * fix undo redo for CTEs * delete dead classes * extra element rendering and persistence * citation rendering * fix citation persistence * proper command parsing * mark buttons blue when style is active * handle pasting of inlines * set active inline on selection change * fix bareTextSelected * fix selection changing bug * adjust focus placement * push backingTextProvider all the way down through tables and lists * fix input ref change detection, remove dead code * cleanup input ref creation * find all input refs, not top level * remove selected inline, not acive * apply hot keys to cmd key * add missing mark renderers * highlight active math * ensure selection is displayed after mark toggle * adding more comments * remove empty file * simplified parsing code, added comments * dedupee ids from pasted content * properly set the active content on focus * ignore unknown keys * assign new block ids * account properly for paragraph-less blocks * add more comments * remove draft.js as a dependency * regen package-lock.json * update vendor bundles * add slate libs to vendor bundle * enabled click to select citations * clone ids properly, allow inlines to work in all toolbars * click anywhere in CTE focuses on slate * ensure click to activate works * fix merge error * transpose bib and dependencies (#697) * version uptick (#699) * Add workbook page importing (#700) * get importer working * Add error handling * Fix formatting * lint issues * fix courses view styling (#705) * version uptick * change tooltip delay (#706) * 0.36.0 - Add support for "lang" attribute (#712) * more foreign changes * use language attr * Add support for multiple selections in sidebar, add to/from persistence for lang attr * Remove foreign wrapper * remove console log * Change styling * Clean up code * Add default language when toggling foreign * fix lint error * fix node type error * Remove merge conflict marker * Change default value for language when making new course * Change default foreign language, remove accessibility option from console, change language from maybe to normal string, use Spanish as default language * lint error * merge master to 36 (#717)
1 parent 66d0bd2 commit 80ddbb9

File tree

24 files changed

+466
-13844
lines changed

24 files changed

+466
-13844
lines changed

package-lock.json

Lines changed: 0 additions & 13551 deletions
This file was deleted.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "course-editor",
3-
"version": "0.35.0",
3+
"version": "0.36.0",
44
"description": "Course Authoring Web Application for the Open Learning Initiative",
55
"main": "./src/app.tsx",
66
"author": "Carnegie Mellon University",
@@ -9,7 +9,6 @@
99
"@types/chroma-js": "^1.3.4",
1010
"@types/history": "^4.7.2",
1111
"@types/jasmine": "^2.5.41",
12-
"@types/node": "^12.11.2",
1312
"@types/react": "^16.8.8",
1413
"@types/react-dom": "^16.8.2",
1514
"@types/react-jss": "^8.6.3",
@@ -64,6 +63,7 @@
6463
"devDependencies": {
6564
"@types/jasmine": "^2.5.41",
6665
"@types/jest": "^24.0.15",
66+
"@types/node": "^12.11.7",
6767
"babel-core": "^6.22.1",
6868
"babel-loader": "^7.1.4",
6969
"babel-polyfill": "^6.26.0",

src/actions/active.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ContentElement } from 'data/content/common/interfaces';
88
import { validateRemoval } from 'data/models/utils/validation';
99
import { displayModalMessasge } from 'utils/message';
1010
import { Editor, Inline } from 'slate';
11-
import { removeInlineEntity, getEntityAtCursor }
11+
import { removeInlineEntity, getInlineAtCursor }
1212
from 'editors/content/learning/contiguoustext/utils';
1313

1414
export type UPDATE_CONTENT = 'active/UPDATE_CONTENT';

src/components/sidebar/ContextAwareSidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { ParentContainer } from 'types/active';
1313
import { getEditorByContentType } from 'editors/content/container/registry';
1414
import { Resource, ResourceState } from 'data/content/resource';
1515
import {
16-
ModelTypes, ContentModel, AssessmentModel, CourseModel, OrganizationModel,
16+
ModelTypes, ContentModel, AssessmentModel, OrganizationModel,
1717
} from 'data/models';
1818
import { AppContext } from 'editors/common/AppContext';
1919
import { AppServices } from 'editors/common/AppServices';

src/components/toolbar/ToolbarButton.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,15 @@ class ToolbarButton
5555

5656
return tooltip ?
5757
(
58-
<Tooltip title={tooltip} delay={1000} distance={5} style={{ display: 'inline-block' }}
59-
size="small" arrowSize="small">
58+
<Tooltip
59+
duration={0}
60+
title={tooltip}
61+
delay={0}
62+
distance={5}
63+
style={{ display: 'inline-block' }}
64+
size="small"
65+
arrowSize="small"
66+
>
6067
{button}
6168
</Tooltip>
6269
)

src/data/content/learning/contiguous.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as Immutable from 'immutable';
22
import * as ct from 'data/contentTypes';
33
import { Maybe } from 'tsmonad';
4-
import { augment, ensureIdGuidPresent } from 'data/content/common';
4+
import { augment } from 'data/content/common';
55
import guid from 'utils/guid';
66
import { Value, Block, Inline } from 'slate';
77
import Html from 'slate-html-serializer';

src/data/content/learning/foreign.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
type LocaleCodes = {
2+
[Friendly in LocaleFriendly]: LocaleCode;
3+
};
4+
5+
export type LocaleFriendly =
6+
| 'Arabic'
7+
| 'Chinese (Mandarin)'
8+
| 'English (Great Britain)'
9+
| 'English (USA)'
10+
| 'French'
11+
| 'German'
12+
| 'Italian'
13+
| 'Japanese'
14+
| 'Russian'
15+
| 'Spanish (LATAM)'
16+
| 'Spanish (Spain)';
17+
18+
export type LocaleCode =
19+
| 'ar'
20+
| 'de'
21+
| 'en_GB'
22+
| 'en_US'
23+
| 'es'
24+
| 'es_419'
25+
| 'fr'
26+
| 'it'
27+
| 'ja'
28+
| 'ru'
29+
| 'zh_CN';
30+
31+
export const localeCodes: LocaleCodes = {
32+
Arabic: 'ar',
33+
'Chinese (Mandarin)': 'zh_CN',
34+
'English (Great Britain)': 'en_GB',
35+
'English (USA)': 'en_US',
36+
French: 'fr',
37+
German: 'de',
38+
Italian: 'it',
39+
Japanese: 'ja',
40+
Russian: 'ru',
41+
'Spanish (LATAM)': 'es_419',
42+
'Spanish (Spain)': 'es',
43+
};

src/data/content/learning/slate/topersistence.ts

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
import { Value, Block, Inline, Text } from 'slate';
2+
import { Value, Block, Inline, Text, Mark } from 'slate';
33
import guid from 'utils/guid';
44

55
import * as common from '../common';
@@ -73,43 +73,52 @@ function handleText(node: Text, content) {
7373

7474
// Handler for a text node that contains one or more marks
7575
function handleMarkedText(node: Text, content) {
76+
const isBdo = (m: Mark) => m.type === 'bdo';
77+
const isForeign = (m: Mark) => m.type === 'foreign';
7678

77-
// We only care about the string type of the mark, so
78-
// map the mark object array to just an array of strings
79-
const marks = node.marks.toArray().map(m => m.type);
79+
// const marks = node.marks.toArray().map(m => m.type);
80+
const marks = node.marks.toArray();
8081

8182
// if bdo is present, it must be the first element that
8283
// we place in the OLI JSON. This is a DTD constraint.
83-
const adjusted = marks.includes('bdo')
84-
? ['bdo', ...marks.filter(m => m !== 'bdo')]
84+
const adjustedMarks = marks.some(isBdo)
85+
? [Mark.create({ type: 'bdo' }), ...marks.filter(m => !isBdo(m))]
8586
: marks;
8687

8788
const root = { root: {} };
8889
let last = root;
8990

90-
adjusted.forEach((s) => {
91-
91+
adjustedMarks.forEach((mark) => {
9292
// For each style, create the object representation for that style
93-
if (s !== undefined) {
94-
const container = styleContainers[s];
95-
let style;
96-
if (container === undefined) {
97-
style = Object.assign({}, styleContainers.em());
98-
} else {
99-
style = Object.assign({}, container());
100-
}
101-
102-
// Now root this style object into the parent style
103-
const key = common.getKey(last);
104-
last[key][common.getKey(style)] = style[common.getKey(style)];
105-
last = style;
93+
if (mark === undefined) {
94+
return;
95+
}
96+
97+
const type = mark.type;
98+
const container = styleContainers[type];
99+
let style;
100+
if (container === undefined) {
101+
style = Object.assign({}, styleContainers.em());
102+
} else {
103+
style = Object.assign({}, container());
106104
}
105+
106+
// Foreigns are a special case because they are currently the only
107+
// slate marks where we use the "data" object. Specifically,
108+
// we store the `@lang` attr here before it is persisted to OLI.
109+
if (isForeign(mark) && mark.data && mark.data.get('lang')) {
110+
style.foreign = { ...style.foreign, '@lang': mark.data.get('lang') };
111+
}
112+
113+
// Now root this style object into the parent style
114+
const key = common.getKey(last);
115+
last[key][common.getKey(style)] = style[common.getKey(style)];
116+
last = style;
107117
});
108118

109119
// Set the text on the last one, add the tree to the container
110120
last[common.getKey(last)]['#text'] = node.text;
111121
content.push(root.root);
112-
113122
}
114123

115124
function handleInline(node: Inline, content) {

src/data/content/learning/slate/toslate.ts

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import * as Immutable from 'immutable';
33
import { registeredTypes } from '../../common/parse';
44
import guid from 'utils/guid';
55
import { InputRef, InputRefType } from 'data/content/learning/input_ref';
6-
import { Value, ValueJSON, BlockJSON, InlineJSON, MarkJSON } from 'slate';
7-
import { instanceOf } from 'prop-types';
6+
import { Value, ValueJSON, BlockJSON, InlineJSON, MarkJSON, Data, Mark } from 'slate';
87

98
// The elements that we handle as slate marks
109
const marks = Immutable.Set<string>(
@@ -118,18 +117,33 @@ function isNestedMark(item: Object): boolean {
118117
return item['#text'] === undefined;
119118
}
120119

121-
// Extract the mark style name from a mark element. For em elements,
120+
// Create a slate mark from a persisted from a mark element. For em elements,
122121
// we use 'em' as the mark style for bold, all other em styles we use
123-
// the style name. sub, sup and other non em styles are just there
122+
// the style name. sub, sup and other non em styles are just their
124123
// element names.
125-
function getMark(item: Object) {
124+
function getMark(item: Object): Mark {
126125
const key = common.getKey(item);
127126
if (key === 'em') {
128127
if (item['em']['@style'] !== undefined && item['em']['@style'] !== 'bold') {
129-
return item['em']['@style'];
128+
return Mark.create({
129+
object: 'mark',
130+
type: item['em']['@style'],
131+
data: {},
132+
});
130133
}
131134
}
132-
return key;
135+
136+
// Currently, `foreign` is the only mark to use the data object to store additional
137+
// attributes.
138+
const data = key === 'foreign'
139+
? Data.create({ lang: item[key]['@lang'] })
140+
: {};
141+
142+
return Mark.create({
143+
object: 'mark',
144+
type: key,
145+
data,
146+
});
133147
}
134148

135149
// Safely access the children elements of an item.
@@ -278,7 +292,7 @@ function handleChild(item: Object, parent: BlockJSON | InlineJSON, backingTextPr
278292

279293
// 2. A style mark, such as em or sup
280294
} else if (marks.contains(key)) {
281-
processMark(item, parent, Immutable.List<string>());
295+
processMark(item, parent, Immutable.List<Mark>());
282296

283297
// 3. Unmarked text
284298
} else if (key === '#text' || key === '#cdata') {
@@ -292,7 +306,7 @@ function handleChild(item: Object, parent: BlockJSON | InlineJSON, backingTextPr
292306

293307
// Handle an OLI style element that we will render as a Slate mark.
294308
function processMark(item: Object,
295-
parent: BlockJSON | InlineJSON, previousMarks: Immutable.List<string>) {
309+
parent: BlockJSON | InlineJSON, previousMarks: Immutable.List<Mark>) {
296310

297311
// If this mark is the parent of another mark, add this style and
298312
// process recursively. This allows us to handle situations like this:
@@ -309,17 +323,10 @@ function processMark(item: Object,
309323
return;
310324
}
311325

312-
// Create the mark array for all styles that we need to apply
313-
const marks = previousMarks.toArray().map(type => ({
314-
object: 'mark',
315-
type,
316-
data: {},
317-
}) as MarkJSON);
318-
319326
parent.nodes.push({
320327
object: 'text',
321328
text: item['#text'],
322-
marks,
329+
marks: previousMarks.toArray(),
323330
});
324331
}
325332

src/data/models/course.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { LegacyTypes } from '../types';
55
import { parseDate } from 'utils/date';
66
import { DatasetStatus } from 'types/analytics/dataset';
77
import { CourseIdVers, CourseGuid } from 'data/types';
8+
import { Maybe } from 'tsmonad';
9+
import { localeCodes } from 'data/content/learning/foreign';
810

911
// Must match DeployStage enum values in ContentService
1012
export enum DeployStage {
@@ -45,6 +47,7 @@ export type CourseModelParams = {
4547
dateCreated: string;
4648
guid: string;
4749
};
50+
language?: string;
4851
resources?: Immutable.OrderedMap<string, contentTypes.Resource>,
4952
resourcesById?: Immutable.OrderedMap<string, contentTypes.Resource>,
5053
webContents?: Immutable.OrderedMap<string, contentTypes.WebContent>,
@@ -71,6 +74,7 @@ const defaultCourseModel = {
7174
icon: new contentTypes.WebContent(),
7275
theme: '',
7376
activeDataset: null,
77+
language: localeCodes['Spanish (LATAM)'],
7478
resources: Immutable.OrderedMap<string, contentTypes.Resource>(),
7579
resourcesById: Immutable.OrderedMap<string, contentTypes.Resource>(),
7680
webContents: Immutable.OrderedMap<string, contentTypes.WebContent>(),
@@ -124,6 +128,7 @@ export class CourseModel extends Immutable.Record(defaultCourseModel) {
124128
dateCreated: string;
125129
guid: string;
126130
};
131+
language: '';
127132
resources: Immutable.OrderedMap<string, contentTypes.Resource>;
128133
resourcesById: Immutable.OrderedMap<string, contentTypes.Resource>;
129134
webContents: Immutable.OrderedMap<string, contentTypes.WebContent>;
@@ -186,6 +191,7 @@ export class CourseModel extends Immutable.Record(defaultCourseModel) {
186191
icon: new contentTypes.WebContent(),
187192
theme: c.theme,
188193
activeDataset: c.activeDataset,
194+
language: c.language || localeCodes['Spanish (LATAM)'],
189195
metadata,
190196
resources,
191197
webContents,
@@ -206,6 +212,7 @@ export class CourseModel extends Immutable.Record(defaultCourseModel) {
206212
metadata: this.metadata.toPersistence(),
207213
description: this.description,
208214
preferences: this.options,
215+
language: this.language || localeCodes['Spanish (LATAM)'],
209216
},
210217
}];
211218
const values = {

0 commit comments

Comments
 (0)