feat!: drop legacy course home view and related code
This was the "outline tab" view of the course. Preceded by the
course info view, succeeded by the MFE outline tab.
In addition to the course home view itself, this drops related
features:
- Legacy version of Course Goals (MFE has a newer implementation)
- Course home in-course search (MFE has no search)
The old course info view and course about views survive for now.
This also drops a few now-unused feature toggles:
- course_experience.latest_update
- course_experience.show_upgrade_msg_on_course_home
- course_experience.upgrade_deadline_message
- course_home.course_home_use_legacy_frontend
With this change, just the progress and courseware tabs are still
supported in legacy form, if you opt-in with waffle flags. The
outline and dates tabs are offered only by the MFE.
AA-798
(This is identical to previous commit be5c1a6, just reintroduced
now that the e2e tests have been fixed)
This commit is contained in:
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* Used to ellipsize a section of arbitrary HTML after a specified number of words.
|
||||
*
|
||||
* Note: this will modify the DOM structure of root in place.
|
||||
* To keep the original around, you may want to save the result of cloneNode(true) before calling this method.
|
||||
*
|
||||
* Known bug: This method will ignore any special whitespace in the source and simply output single spaces.
|
||||
* Which means that will not be respected. This is not considered worth solving at time of writing.
|
||||
*
|
||||
* Returns how many words remain (or a negative number if the content got clamped)
|
||||
*/
|
||||
function clampHtmlByWords(root, wordsLeft) {
|
||||
'use strict';
|
||||
|
||||
if (root.nodeName === 'SCRIPT' || root.nodeName === 'STYLE') {
|
||||
return wordsLeft; // early exit and ignore
|
||||
}
|
||||
|
||||
var remaining = wordsLeft;
|
||||
var nodes = Array.from(root.childNodes ? root.childNodes : []);
|
||||
var words, chopped;
|
||||
|
||||
// First, cut short any text in our node, as necessary
|
||||
if (root.nodeName === '#text' && root.data) {
|
||||
// split on words, ignoring any resulting empty strings
|
||||
words = root.data.split(/\s+/).filter(Boolean);
|
||||
if (remaining < 0) {
|
||||
root.data = ''; // eslint-disable-line no-param-reassign
|
||||
} else if (remaining > words.length) {
|
||||
remaining -= words.length;
|
||||
} else {
|
||||
// OK, let's add an ellipsis and cut some of root.data
|
||||
chopped = words.slice(0, remaining).join(' ') + '…';
|
||||
// But be careful to get any preceding space too
|
||||
if (root.data.match(/^\s/)) {
|
||||
chopped = ' ' + chopped;
|
||||
}
|
||||
root.data = chopped; // eslint-disable-line no-param-reassign
|
||||
remaining = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now do the same for any child nodes
|
||||
nodes.forEach(function(node) {
|
||||
if (remaining < 0) {
|
||||
root.removeChild(node);
|
||||
} else {
|
||||
remaining = clampHtmlByWords(node, remaining);
|
||||
}
|
||||
});
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
clampHtmlByWords: clampHtmlByWords
|
||||
};
|
||||
@@ -1,38 +0,0 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { clampHtmlByWords } from './clamp-html';
|
||||
|
||||
let container;
|
||||
const scriptTag = '<script src="/asset-v1:edX+testX+1T2021+type@asset+block/script.js">const ignore = "me here"; alert("BAD");</script>';
|
||||
const styleTag = '<style>h1 {color: orange;}</style>';
|
||||
|
||||
beforeEach(() => {
|
||||
container = document.createElement("div");
|
||||
document.body.appendChild(container);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.body.removeChild(container);
|
||||
container = null;
|
||||
});
|
||||
|
||||
describe('ClampHtml', () => {
|
||||
test.each([
|
||||
['', 0, ''],
|
||||
['a b', 0, '…'],
|
||||
['a b', 1, 'a…'],
|
||||
['a b c', 2, 'a b…'],
|
||||
['a <i>aa ab</i> b', 2, 'a <i>aa…</i>'],
|
||||
['a <i>aa ab</i> <em>ac</em>', 2, 'a <i>aa…</i>'],
|
||||
['a <i>aa <em>aaa</em></i>', 2, 'a <i>aa…</i>'],
|
||||
['a <i>aa <em>aaa</em> ab</i>', 3, 'a <i>aa <em>aaa…</em></i>'],
|
||||
['a <i>aa ab</i> b c', 4, 'a <i>aa ab</i> b…'],
|
||||
[scriptTag + 'a b c', 2, scriptTag + 'a b…'],
|
||||
[styleTag + 'a b c', 2, styleTag + 'a b…'],
|
||||
[scriptTag + styleTag + 'a b c', 2, scriptTag + styleTag + 'a b…'],
|
||||
])('clamps by words: %s, %i', (input, wordsLeft, expected) => {
|
||||
const div = ReactDOM.render(<div dangerouslySetInnerHTML={{ __html: input }} />, container);
|
||||
clampHtmlByWords(div, wordsLeft);
|
||||
expect(div.innerHTML).toEqual(expected);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user