Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit e4a3e7c

Browse files
committed
✨ A working version with multiple instances of hparsons
1 parent 5ac48b5 commit e4a3e7c

3 files changed

Lines changed: 55 additions & 71 deletions

File tree

runestone/hparsons/js/regex-element.js

Lines changed: 47 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3043,9 +3043,10 @@ class ParsonsInput {
30433043
_dragSortable;
30443044
parentElement;
30453045
_prevPosition;
3046-
constructor() {
3046+
constructor(parentElement) {
30473047
this.el = document.createElement('div');
3048-
this.el.id = 'parsons-input';
3048+
this.parentElement = parentElement;
3049+
this.el.id = 'regextool-' + this.parentElement.toolNumber + '-parsons-input';
30493050
this.el.append('Drag or click to select from the symbols below to form your regex');
30503051
this._dragArea = document.createElement('div');
30513052
this.el.appendChild(this._dragArea);
@@ -3077,7 +3078,6 @@ class ParsonsInput {
30773078
animation: 150
30783079
});
30793080
this._initSortable();
3080-
this.parentElement = null;
30813081
}
30823082
getText = () => {
30833083
let ret = '';
@@ -15506,20 +15506,18 @@ class TextInput {
1550615506
groups;
1550715507
parentElement;
1550815508
droppedText;
15509-
constructor() {
15509+
constructor(parentElement) {
15510+
this.parentElement = parentElement;
1551015511
this.el = document.createElement('div');
15511-
this.el.id = 'regex-input';
15512+
this.el.id = 'regextool-' + this.parentElement.toolNumber + '-regex-input';
1551215513
this.el.classList.add('regex-input');
1551315514
this.quill = null;
1551415515
this.groups = new Array();
15515-
// this.el.classList.add('regex-textbox')
15516-
// this.el.setAttribute("rows", "1");
15517-
this.parentElement = null;
1551815516
this.droppedText = false;
1551915517
}
1552015518
initQuill = () => {
1552115519
// initializing quill
15522-
this.quill = new Quill('#regex-input', {
15520+
this.quill = new Quill('#regextool-' + this.parentElement.toolNumber + '-regex-input', {
1552315521
modules: {
1552415522
toolbar: false
1552515523
},
@@ -15654,20 +15652,20 @@ class TestStringInput {
1565415652
parentElement;
1565515653
slotName;
1565615654
highlightMode;
15657-
constructor(slotName) {
15655+
constructor(slotName, parentElement) {
15656+
this.parentElement = parentElement;
1565815657
this.el = document.createElement('div');
1565915658
this.slotName = slotName;
15660-
this.el.id = 'test-string-input' + slotName;
15659+
this.el.id = 'regextool-' + this.parentElement.toolNumber + '-test-string-input' + slotName;
1566115660
this.el.classList.add('regex-test-string');
1566215661
this.quill = null;
1566315662
// console.log(Quill);
1566415663
this.droppedText = false;
15665-
this.parentElement = null;
1566615664
this.highlightMode = 're.finditer';
1566715665
}
1566815666
initQuill = () => {
1566915667
// initializing quill
15670-
this.quill = new Quill('#test-string-input' + this.slotName, {
15668+
this.quill = new Quill('#regextool-' + this.parentElement.toolNumber + '-test-string-input' + this.slotName, {
1567115669
modules: {
1567215670
toolbar: false
1567315671
},
@@ -15799,35 +15797,29 @@ class StatusOutput {
1579915797
// The input element
1580015798
el;
1580115799
text;
15802-
constructor() {
15800+
parentElement;
15801+
constructor(parentElement) {
15802+
this.parentElement = parentElement;
1580315803
this.el = document.createElement('div');
1580415804
this.text = document.createElement('textarea');
1580515805
this.el.appendChild(this.text);
15806-
this.text.id = 'status-output';
15806+
this.text.id = 'regextool-' + this.parentElement.toolNumber + '-status-output';
1580715807
this.el.classList.add('regex-textbox');
1580815808
// this.text.setAttribute("rows", "10");
1580915809
this.text.value = 'initializing...\n';
1581015810
}
1581115811
}
1581215812

15813-
class TestButton {
15814-
// The input element
15815-
el;
15816-
constructor() {
15817-
this.el = document.createElement('button');
15818-
this.el.id = 'test-button';
15819-
this.el.innerText = 'match!';
15820-
}
15821-
}
15822-
1582315813
class RegexOptions {
1582415814
el;
1582515815
triggerButton;
1582615816
containerDiv;
1582715817
flags;
1582815818
buttons;
1582915819
selectedFlags;
15830-
constructor() {
15820+
parentElement;
15821+
constructor(parentElement) {
15822+
this.parentElement = parentElement;
1583115823
this.el = document.createElement('div');
1583215824
this.el.classList.add('regex-options-dropdown');
1583315825
this.triggerButton = document.createElement('button');
@@ -15910,14 +15902,16 @@ class UnitTestTable {
1591015902
// TODO: refactor this into strictgroup.
1591115903
noGroupsAllowed;
1591215904
latestResults;
15905+
latestStatus;
1591315906
columnsEnabled;
1591415907
parentElement;
1591515908
// for saving current index
1591615909
testcaseIndex;
15917-
constructor() {
15910+
constructor(parentElement) {
15911+
this.parentElement = parentElement;
1591815912
// init the element in HTML
1591915913
this.el = document.createElement('div');
15920-
this.el.id = 'unittest-table';
15914+
this.el.id = 'regextool-' + this.parentElement.toolNumber + '-unittest-table';
1592115915
this.el.classList.add('regex-unittest');
1592215916
// the element is hidden initially.
1592315917
this.el.classList.add('collapse');
@@ -15937,13 +15931,13 @@ class UnitTestTable {
1593715931
this.testCaseCount = 0;
1593815932
this.hintRevealed = [];
1593915933
this.latestResults = [];
15934+
this.latestStatus = '';
1594015935
// not matching groups strictly by default
1594115936
this.strictGroup = false;
1594215937
// using strict match by default
1594315938
this.strictMatch = true;
1594415939
// allow groups by default
1594515940
this.noGroupsAllowed = false;
15946-
this.parentElement = null;
1594715941
this.testcaseIndex = 0;
1594815942
}
1594915943
// not used: Return value: 'Pass' if all pass, 'Error' if one error, 'Fail' if no error but at least one fail
@@ -15985,7 +15979,7 @@ class UnitTestTable {
1598515979
}
1598615980
}
1598715981
const result = { success: true, match: matches, errorMessage: null };
15988-
this._createRow(index, testCase, result);
15982+
this.latestStatus = this._createRow(index, testCase, result);
1598915983
};
1599015984
builtinRead(x) {
1599115985
if (window.Sk.builtinFiles === undefined || window.Sk.builtinFiles["files"][x] === undefined)
@@ -16011,7 +16005,7 @@ class UnitTestTable {
1601116005
read: this.builtinRead
1601216006
});
1601316007
window.Sk.importMainWithBody("<stdin>", false, pyCode, true);
16014-
return 'Pass';
16008+
return this.latestStatus;
1601516009
};
1601616010
// returns: 'Pass' if pass, 'Fail' if fail, 'Error' if error
1601716011
_createRow = (index, testCase, result) => {
@@ -16021,6 +16015,7 @@ class UnitTestTable {
1602116015
// creating the status(the first) column
1602216016
const row = document.createElement('tr');
1602316017
let status = result.success ? (JSON.stringify(result.match) === JSON.stringify(testCase.expect) ? 'Pass' : 'Fail') : 'Error';
16018+
console.log(status);
1602416019
// if (status == 'Pass' && JSON.stringify(testCase.expect) != '[]' && this.noGroupsAllowed && window.pyodide.globals.unit_match_group_cnt != 1) {
1602516020
// status = 'Fail'
1602616021
// // fail because no group is allowed
@@ -16115,7 +16110,9 @@ class RegexStatusTag {
1611516110
// The input element
1611616111
el;
1611716112
status;
16118-
constructor() {
16113+
parentElement;
16114+
constructor(parentElement) {
16115+
this.parentElement = parentElement;
1611916116
this.el = document.createElement('span');
1612016117
this.el.classList.add('regex-status');
1612116118
this.status = '';
@@ -16167,8 +16164,6 @@ class RegexElement extends HTMLElement {
1616716164
negativePrevText;
1616816165
// Python output
1616916166
statusOutput;
16170-
// The button to trigger matching
16171-
testButton;
1617216167
// *temporary: The checkbox to enable always check (will be integrated in options later)
1617316168
checkWhileTyping;
1617416169
positiveMatchResult;
@@ -16187,9 +16182,11 @@ class RegexElement extends HTMLElement {
1618716182
_testStatusDiv;
1618816183
// highlights the result using findall. used for study 1 and 2.
1618916184
matchFindall;
16185+
static toolCount = 0;
16186+
toolNumber;
1619016187
outf(text) {
16191-
console.log('sk output');
16192-
console.log(text);
16188+
// console.log('sk output')
16189+
// console.log(text)
1619316190
}
1619416191
builtinRead(x) {
1619516192
if (window.Sk.builtinFiles === undefined || window.Sk.builtinFiles["files"][x] === undefined)
@@ -16261,6 +16258,9 @@ class RegexElement extends HTMLElement {
1626116258
};
1626216259
constructor() {
1626316260
super();
16261+
RegexElement.toolCount += 1;
16262+
console.log(RegexElement.toolCount);
16263+
this.toolNumber = RegexElement.toolCount;
1626416264
this.root = this.attachShadow({ mode: 'open' });
1626516265
window.Sk.configure({
1626616266
output: this.outf,
@@ -16275,26 +16275,6 @@ class RegexElement extends HTMLElement {
1627516275
// unitTestButton.innerText = 'Run Unit Test';
1627616276
// this.root.appendChild(unitTestButton);
1627716277
// unitTestButton.onclick = () => this.unitTestTable.check(this.regexInput.getText());
16278-
// init elements: button for match
16279-
// TODO: disabled the button for study 0 and 1.
16280-
// this.root.appendChild(document.createElement('br'));
16281-
this.testButton = new TestButton();
16282-
// this.root.appendChild(this.testButton.el);
16283-
// this.testButton.el.onclick = this.match;
16284-
// init elements: checkbox
16285-
// TODO[feature]: replace this with an option module
16286-
// const checkbox = document.createElement('input');
16287-
// checkbox.setAttribute('type', 'checkbox');
16288-
// checkbox.checked = false;
16289-
// this.root.appendChild(checkbox);
16290-
// this.root.append('always check on input');
16291-
// this.checkWhileTyping = false;
16292-
// checkbox.addEventListener('change', () => {
16293-
// this.checkWhileTyping = checkbox.checked;
16294-
// if (this.checkWhileTyping) {
16295-
// this.match();
16296-
// }
16297-
// })
1629816278
// TODO: make this an option; for now always enabled the 'always check' for study 0 and 1.
1629916279
this.checkWhileTyping = true;
1630016280
// a div wrapping the input and the test case status
@@ -16305,12 +16285,12 @@ class RegexElement extends HTMLElement {
1630516285
const inputDiv = document.createElement('div');
1630616286
inputAndTestStatusDiv.appendChild(inputDiv);
1630716287
inputDiv.classList.add('regex-input-div');
16308-
this.regexOptions = new RegexOptions();
16288+
this.regexOptions = new RegexOptions(this);
1630916289
this.patternValidFlag = true;
1631016290
this._parsonsData = new Array();
1631116291
this.parsonsExplanation = null;
16312-
this.regexStatus = new RegexStatusTag();
16313-
this.regexInput = new ParsonsInput();
16292+
this.regexStatus = new RegexStatusTag(this);
16293+
this.regexInput = new ParsonsInput(this);
1631416294
this.inputType = 'parsons';
1631516295
// this.regexErrorMessage = document.createElement('div');
1631616296
// this.regexErrorPosition = -1;
@@ -16340,13 +16320,12 @@ class RegexElement extends HTMLElement {
1634016320
positiveTestStringDiv.appendChild(resetPositiveTestStringButton);
1634116321
resetPositiveTestStringButton.innerText = 'Reset';
1634216322
resetPositiveTestStringButton.onclick = this.resetPositiveTestString;
16343-
this.positiveTestStringInput = new TestStringInput('positive');
16323+
this.positiveTestStringInput = new TestStringInput('positive', this);
1634416324
this.positiveTestStringInput.slotName = 'positive';
1634516325
this.appendChild(this.positiveTestStringInput.el);
1634616326
this.positiveTestStringInput.el.slot = 'positive-test-string-input';
1634716327
this.positiveTestStringInput.initQuill();
1634816328
this.positivePrevText = this.positiveTestStringInput.getText();
16349-
this.positiveTestStringInput.parentElement = this;
1635016329
this.positiveTestStringInput.quill?.on('text-change', (delta, _, source) => {
1635116330
if (source == 'user') {
1635216331
const testStringInputEvent = {
@@ -16384,13 +16363,12 @@ class RegexElement extends HTMLElement {
1638416363
negativeTestStringDiv.appendChild(resetNegativeTestStringButton);
1638516364
resetNegativeTestStringButton.innerText = 'Reset';
1638616365
resetNegativeTestStringButton.onclick = this.resetNegativeTestString;
16387-
this.negativeTestStringInput = new TestStringInput('negative');
16366+
this.negativeTestStringInput = new TestStringInput('negative', this);
1638816367
this.negativeTestStringInput.slotName = 'negative';
1638916368
this.appendChild(this.negativeTestStringInput.el);
1639016369
this.negativeTestStringInput.el.slot = 'negative-test-string-input';
1639116370
this.negativeTestStringInput.initQuill();
1639216371
this.negativePrevText = this.negativeTestStringInput.getText();
16393-
this.negativeTestStringInput.parentElement = this;
1639416372
this.negativeTestStringInput.quill?.on('text-change', (delta, _, source) => {
1639516373
if (source == 'user') {
1639616374
const testStringInputEvent = {
@@ -16417,11 +16395,10 @@ class RegexElement extends HTMLElement {
1641716395
}
1641816396
});
1641916397
// init element: unit test table
16420-
this.unitTestTable = new UnitTestTable();
16421-
this.unitTestTable.parentElement = this;
16398+
this.unitTestTable = new UnitTestTable(this);
1642216399
this.root.appendChild(this.unitTestTable.el);
1642316400
// init element: python output
16424-
this.statusOutput = new StatusOutput();
16401+
this.statusOutput = new StatusOutput(this);
1642516402
this.root.appendChild(this.statusOutput.el);
1642616403
// initialize the match result array
1642716404
this.positiveMatchResult = new Array();
@@ -16857,13 +16834,13 @@ class RegexElement extends HTMLElement {
1685716834
this._parsonsData = new Array();
1685816835
this.parsonsExplanation = null;
1685916836
inputDiv.append('Your regular expression:');
16860-
this.regexStatus = new RegexStatusTag();
16837+
this.regexStatus = new RegexStatusTag(this);
1686116838
inputDiv.appendChild(this.regexStatus.el);
1686216839
inputDiv.appendChild(document.createElement('br'));
1686316840
// todo:(UI) fix the css for the input
1686416841
if (this.inputType == 'parsons') {
1686516842
// init elements: parsons regex input
16866-
this.regexInput = new ParsonsInput();
16843+
this.regexInput = new ParsonsInput(this);
1686716844
inputDiv.appendChild(this.regexInput.el);
1686816845
this.regexInput.el.addEventListener('regexChanged', () => {
1686916846
this.regexInput.removeFormat();
@@ -16923,7 +16900,7 @@ class RegexElement extends HTMLElement {
1692316900
regex_slot.name = 'regex-input';
1692416901
inputDiv.appendChild(regex_slot);
1692516902
// TODO: (refactor) rename RegexInput
16926-
this.regexInput = new TextInput();
16903+
this.regexInput = new TextInput(this);
1692716904
this.appendChild(this.regexInput.el);
1692816905
this.regexInput.el.slot = 'regex-input';
1692916906
this.regexInput.initQuill();
@@ -16985,13 +16962,12 @@ class RegexElement extends HTMLElement {
1698516962
}
1698616963
});
1698716964
}
16988-
this.regexInput.parentElement = this;
1698916965
// this.regexErrorMessage = document.createElement('div');
1699016966
// this.regexErrorMessage.classList.add('regex-error-message');
1699116967
// inputDiv.appendChild(this.regexErrorMessage);
1699216968
// this.regexErrorPosition = -1;
1699316969
// init elements: regex options dropdown
16994-
this.regexOptions = new RegexOptions();
16970+
this.regexOptions = new RegexOptions(this);
1699516971
// inputDiv.appendChild(this.regexOptions.el);
1699616972
}
1699716973
resetTool() {

runestone/hparsons/test/_sources/index.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ ActiveCode
5353
content content content
5454

5555

56+
.. hparsons:: codeexample2
57+
58+
content content content
59+
5660

5761
Multiple Choice
5862
---------------

test.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
#!/bin/bash
2+
cd ~/code/regex
3+
npm run build
4+
cd ~/code/RunestoneComponents
5+
cp ~/code/regex/packages/regex-element/regex-element.js ~/code/RunestoneComponents/runestone/hparsons/js/regex-element.js
26
npm run build
37
pip install .
48
cd runestone/hparsons/test

0 commit comments

Comments
 (0)