Created
September 19, 2019 06:30
-
-
Save Varal7/01a241ec7aeab942f91287f697429d70 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<meta content="width=device-width,initial-scale=1" name="viewport" /> | |
<section class="container" id="Relevancy"> | |
<div class="row"> | |
<div class="col-xs-12 col-md-12"> | |
<div class="panel panel-primary"><a class="panel-heading" href="javascript:void(0);" id="collapseTrigger"><strong>Tagging Instructions</strong> <span class="collapse-text">(Click to expand)</span> </a> | |
<div class="panel-body" id="instructionBody"><strong>Tag the description to extract the following fields of interest</strong> | |
<table class="table table-condensed table-striped table-responsive"> | |
<colgroup> | |
<col class="col-xs-2 col-md-2" /> | |
<col class="col-xs-10 col-md-10" /> | |
</colgroup> | |
<tbody id="instruction-table"> | |
</tbody> | |
</table> | |
<div class="text-center"> | |
<img src="images/tagging.gif" alt="tagging" width="50%"/> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<input type="hidden" name="fake" /> | |
<h2>Highlight the <strong id="key-name" class="key-name">name</strong> in the description</h2> | |
<div id="raw">${description}</div> | |
<div class="row" id="workContent"> | |
<div class="col-xs-12 col-sm-8 content"> | |
<div id="well" class="ann well"></div> | |
</div> | |
<div class="col-xs-12 col-sm-4 fields"> | |
<div id="button-div"> | |
<button type="button" id="undo" value="undo" class="btn btn-primary"> | |
<span class="glyphicon glyphicon-backward"></span> Undo | |
</button> | |
<button type="button" id="remove" value="remove" class="btn btn-danger"> | |
<span class="glyphicon glyphicon-remove"></span> Reset | |
</button> | |
</div> | |
<div class="btn-group-vertical" data-toggle="buttons" id="choice"> | |
</div> | |
</div> | |
</div> | |
<div id="form" class="row"> </div> | |
<span title="Highlight all fields before submitting"><input id="submit" class="btn btn-default" data-key="Enter" type="submit" disabled=disabled /></span> | |
</section> | |
<link crossorigin="anonymous" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" rel="stylesheet" /> | |
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script> | |
<style> | |
#collapseTrigger{ | |
color:#fff; | |
display: block; | |
text-decoration: none; | |
} | |
#submitButton{ | |
white-space: normal; | |
} | |
#instructionBody table{ | |
font-size: 14px; | |
margin-top: 10px; | |
} | |
#instructionBody table caption{ | |
text-align: left; | |
padding: 0 0 5px 0; | |
} | |
#choice{ | |
display: block; | |
margin-top: 10px; | |
} | |
.content{ | |
margin-bottom: 15px; | |
} | |
.question{ | |
margin-left: 15px; | |
padding-left: 10px; | |
border-left: double; | |
} | |
.radio:first-of-type{ | |
margin-top: -5px; | |
} | |
.ann { | |
font-size: 20px; | |
} | |
.disp { | |
font-size: 20px; | |
} | |
.ann > span.token { | |
cursor: pointer; | |
} | |
.ann > span.token:hover { | |
text-decoration: underline; | |
} | |
.ann > strong.annotation:hover { | |
text-decoration: line-through; | |
} | |
.annotation { | |
font-weight: normal; | |
background-color: #EAD379; | |
} | |
.btn-ann { | |
font-size: 10px; | |
} | |
input[disabled] { | |
color: #000 | |
} | |
#key-name { | |
background-color: #EAD379; | |
} | |
</style> | |
<script> | |
// --------------------------------------------------------- | |
// Config | |
// --------------------------------------------------------- | |
var fieldName = { | |
"name": "Product name", | |
"version": "Product version", | |
"protocol": "Protocol", | |
"target": "Target", | |
} | |
var shortName = { | |
"name": "name", | |
"version": "version", | |
"protocol": "protocol", | |
"target": "target", | |
} | |
var longDesc = { | |
"name": "Product name. Name of the software/device/library that is affected by this vulnerability ", | |
"version": 'Version or versions of the product that is affected. E.g. "1.3.0" or "through 2.7"', | |
"protocol": "Form in which the input is given to exploit the vulnerability", | |
"target": "target", | |
} | |
var shortcutKey = { | |
"name": "a", | |
"version": "e", | |
"protocol": "r", | |
"target": "t", | |
} | |
// --------------------------------------------------------- | |
// Global | |
// --------------------------------------------------------- | |
var keys = Object.keys(fieldName); | |
var annotations = {}; | |
var values = {}; | |
var key; | |
// --------------------------------------------------------- | |
// Create jQuery elements | |
// --------------------------------------------------------- | |
var raw = $('#raw'); | |
var well = $('#well'); | |
var submit = $('#submit'); | |
var choice = $('#choice'); | |
var keyname = $('#key-name'); | |
var instructionTable = $('#instruction-table'); | |
var form = $("#form"); | |
var answer = {}; | |
var tagHidden = {}; | |
var noVal = {}; | |
var radios = {}; | |
// answerHiddenDuplicates value of answer but is needed because | |
// otherwise the data is not sent | |
var answerHidden = {}; | |
var makeInstruction = function(key) { | |
return ($( | |
'<tr>') | |
.append($('<td>').text(fieldName[key])) | |
.append($('<td>').text(longDesc[key])) | |
); | |
} | |
var makeChoice = function(key) { | |
var input = ($( | |
'<input>') | |
.attr({ | |
'name': 'choice', 'id': key + "-choice", | |
'value': key, 'type': 'radio', 'data-key': shortcutKey[key] | |
}) | |
.text(fieldName[key]) | |
); | |
radios[key] = input; | |
var label = ($( | |
'<label>') | |
.addClass('btn btn-default') | |
.text(fieldName[key]) | |
.append(input) | |
.attr({'title': "Shortcut: " + shortcutKey[key]}) | |
); | |
return label; | |
} | |
var makeAnswerHidden = function(key) { | |
var input = ($( | |
'<input>') | |
.attr({'type': 'hidden', 'name': key, 'id': key + "-hidden"}) | |
); | |
answerHidden[key] = input; | |
return input; | |
} | |
var makeTagHidden = function(key) { | |
var input = ($( | |
'<input>') | |
.attr({'type': 'hidden', 'name': key + "-tag", 'id': key + "-tag"}) | |
); | |
tagHidden[key] = input; | |
return input; | |
} | |
var makeFormRow = function(key) { | |
var checkbox = ($( | |
'<input>') | |
.attr({'type': 'checkbox', 'id': "no-" + key}) | |
.addClass('form-check-input') | |
.change(function() { show(); }) | |
); | |
var label = ($( | |
'<label>') | |
.attr({'for': "no-" + key}) | |
.addClass('form-check-label') | |
.text(' There is no ' + shortName[key]) | |
); | |
var input = ($( | |
'<input>') | |
.attr({'type': 'text', 'disabled':'disabled', 'id': key}) | |
.addClass('form-control') | |
); | |
var div = ($( | |
'<div>') | |
.addClass('col-xs-12 col-sm-12 content') | |
.append($('<label>') | |
.attr({'for': key}) | |
.text(fieldName[key]) | |
) | |
.append($('<div>') | |
.addClass('form-row') | |
.append($('<div>') | |
.addClass('col-sm-8') | |
.append(input) | |
) | |
.append($('<div>') | |
.addClass('col-sm-4') | |
.append($('<div>') | |
.addClass('form-check') | |
.append(checkbox) | |
.append(' ') | |
.append(label) | |
) | |
) | |
) | |
); | |
answer[key] = input; | |
noVal[key] = checkbox; | |
return div; | |
} | |
var makeDom = function() { | |
for (var key of keys) { | |
form.append(makeFormRow(key)); | |
form.append(makeTagHidden(key)); | |
form.append(makeAnswerHidden(key)); | |
choice.append(makeChoice(key)); | |
annotations[key] = []; | |
values[key] = ""; | |
instructionTable.append(makeInstruction(key)); | |
} | |
} | |
// --------------------------------------------------------- | |
// Annotation logic | |
// --------------------------------------------------------- | |
var old_annotations = []; | |
var get_annotation_id = function(token_id, annotations) { | |
var found = annotations.findIndex(function(annotation) { | |
return token_id >= annotation[0] && token_id < annotation[1]; | |
}); | |
return found; | |
}; | |
var mouse_down = function(id) { | |
var annotation_id = get_annotation_id(id, annotations[key]); | |
if (annotation_id > -1) { | |
delete_annotation(annotation_id); | |
show(); | |
} else { | |
first_token = id; | |
} | |
}; | |
var mouse_up = function(id) { | |
if (first_token > -1) { | |
if (first_token <= id) { | |
add_annotation([first_token, id + 1]); | |
} else { | |
add_annotation([id, first_token + 1]); | |
} | |
first_token = -1; | |
show(); | |
} | |
clear_selection(); | |
}; | |
var clear_selection = function() { | |
if (document.selection) { | |
document.selection.empty(); | |
} else if ( window.getSelection ) { | |
window.getSelection().removeAllRanges(); | |
} | |
}; | |
var get_value = function() { | |
var values = _.map(annotations[key], function(annotation) { | |
return tokens.slice(annotation[0], annotation[1]).join(" "); | |
}); | |
return values.join(" "); | |
}; | |
var remove_all_annotations = function() { | |
old_annotations = annotations[key].slice(); | |
annotations[key] = [] | |
}; | |
var delete_annotation = function(annotation_id) { | |
if (annotation_id > -1) { | |
old_annotations = annotations[key].slice(); | |
annotations[key].splice(annotation_id, 1); | |
} | |
} | |
var add_annotation = function(annotation) { | |
old_annotations = annotations[key].slice(); | |
annotations[key].push(annotation); | |
} | |
var toggle_old_new = function() { | |
var new_annotations = annotations[key].slice(); | |
annotations[key] = old_annotations.slice(); | |
old_annotations = new_annotations; | |
} | |
// --------------------------------------------------------- | |
// Displaying | |
// --------------------------------------------------------- | |
var sequence_html = function(sequence, annotations) { | |
var ret = _.map(sequence, function(token, index) { | |
return '<span class="token" id=tok_' + index + '> ' | |
+ token + ' </span>'; | |
}); | |
_.each(annotations, function(annotation) { | |
ret[annotation[0]] = '<strong class="annotation">' | |
+ ret[annotation[0]]; | |
ret[annotation[1]-1] = ret[annotation[1]-1] + '</strong>'; | |
}); | |
return ret.join(' '); | |
} | |
var canSubmit = function() { | |
for (var key of keys) { | |
if (values[key] == "" && !noVal[key].is(":checked")) { return false; } | |
} | |
return true; | |
} | |
var show = function() { | |
annotations[key].sort(function(a, b) { | |
return a[0] - b[0]; | |
}); | |
//fill_annotated_values(datum); | |
seq_html = sequence_html(tokens, annotations[key]); | |
well.html(seq_html); | |
values[key] = get_value(); | |
answer[key].val(values[key]); | |
answerHidden[key].val(values[key]); | |
tagHidden[key].val(annotations[key]); | |
console.log(key); | |
console.log(annotations[key]); | |
keyname.html(shortName[key]); | |
// Handler on tokens | |
$(".token").mousedown(function() { | |
mouse_down(parseInt($(this).attr('id').split("_")[1])); | |
}); | |
$(".token").mouseup(function() { | |
mouse_up(parseInt($(this).attr('id').split("_")[1])); | |
}); | |
if (canSubmit()) { | |
submit.removeAttr("disabled"); | |
submit.removeClass("btn-default"); | |
submit.addClass("btn-success"); | |
} else { | |
submit.attr("disabled", "disabled"); | |
submit.removeClass("btn-success"); | |
submit.addClass("btn-default"); | |
} | |
}; | |
makeDom(); | |
// --------------------------------------------------------- | |
// Event handlers | |
// --------------------------------------------------------- | |
$("#undo").click(function() { | |
toggle_old_new(); | |
show(); | |
}); | |
$("#remove").click(function() { | |
remove_all_annotations(); | |
show(); | |
}); | |
//highlight selected category | |
var inputs = $("#choice input:radio"); | |
inputs.change(function(){ | |
inputs.parent().removeClass("btn-success"); | |
inputs.parent().addClass("btn-default"); | |
if($(this).is(":checked")){ | |
key = $(this).val(); | |
$(this).parent().removeClass("btn-default"); | |
$(this).parent().addClass("btn-success"); | |
show(); | |
}else{ | |
$(this).parent().removeClass("btn-success"); | |
$(this).parent().addClass("btn-default"); | |
} | |
}); | |
// Instructions expand/collapse | |
var content = $('#instructionBody'); | |
var trigger = $('#collapseTrigger'); | |
content.hide(); | |
$('.collapse-text').text('(Click to expand)'); | |
trigger.click(function(){ | |
content.toggle(); | |
var isVisible = content.is(':visible'); | |
if(isVisible){ | |
$('.collapse-text').text('(Click to collapse)'); | |
}else{ | |
$('.collapse-text').text('(Click to expand)'); | |
} | |
}); | |
// --------------------------------------------------------- | |
// Initialize | |
// --------------------------------------------------------- | |
key = keys[0]; | |
radios[key].click(); | |
var tokens = raw.text().split(">>"); | |
raw.hide(); | |
show(); | |
</script> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment