To ensure we only clean style and classes, first we select the inside
of those attributes and "replace" them with handler functions. Those
functions scan the actual attribute values for class or styles that
we want to exclude.
The first level regex has 3 groups. group1 selects everything in the
tag leading up to the attribute values, group2 has the attributes,
group3 has the trailing quote mark. We work on group2 then return
the combination of group1, group2, and group3.
Browsers may not provide html content in the clipboard object event
though it will really be pasted as such. This includes Firefox on
Windows, Internet Explorer, and some niche cases in Safari.
Because of this, we need to scrub the entire editor anytime we can't
intercept a paste event.
In some magical day in the future when there is better cross browser
support, we can undo this.
* A method to change the max mark for one question_attempt in the usage
* A method to replace one question in a usage with another, moving the
old question_attempt to the end.
* Methods to set and get metadata (string name value pairs) for each
question_attempt in the usage. This gets stored in the first step in a
way that should not interfere with anything else.
There are several improvements over what we had before:
1. We track all the questions seen in the the student's previous
quiz attempts, so that when they start a new quiz attempt, they get
questions they have not seen before if possible.
2. When there are no more unseen questions, we start repeating, but
always taking from the questions with the fewest attempts so far.
3. A similar logic is applied with variants within one question.
There is lots of credit to go around here. Oleg Sychev's students Alex
Shkarupa, Sergei Bastrykin and Darya Beda all worked on this over
several years, helping to clarify the problem and shape the best
solution. In the end, their various attempts were rewritten into this
final patch by me.
The plugin callback executed above can eventually change the format. We
need to use that one to have the formatting of the first AJAX response
consistent with following displays.
Just running a huge log cleanup will probably cause big problems on large sites.
So we break this down into smaller day-by-day chunks until reaching the target.