Skip to content

Commit

Permalink
html report: refactor of all inline on* event listeners to data attri…
Browse files Browse the repository at this point in the history
…butes and event listeners added from static JS inside <script>, so that we can disable all inline JS in the online HTML report and allow only our JS signed with hashes by Content-Security-Policy
  • Loading branch information
janreges committed Dec 20, 2023
1 parent e1567ae commit b576eef
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/Crawler/Components/SuperTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public function getHtmlOutput(): string

if ($this->isFulltextEnabled()) {
$output .= '<div class="fulltext-container">';
$output .= ' <input type="text" class="fulltext" onkeyup="debouncedTableFulltext(\'' . htmlspecialchars($this->uniqueId) . '\', this.value)" style="width: 300px;" placeholder="Fulltext search">';
$output .= ' <input type="text" class="fulltext" data-uq-id="' . htmlspecialchars($this->uniqueId) . '" style="width: 300px;" placeholder="Fulltext search">';
$output .= ' <span id="foundRows_' . htmlspecialchars($this->uniqueId) . '" class="found-rows">Found ' . count($this->data) . ' row(s).</span>';
$output .= '</div>';
}
Expand Down Expand Up @@ -145,7 +145,7 @@ public function getHtmlOutput(): string
} else {
$dataType = isset($this->data[0]) && isset($this->data[0]->$key) && is_numeric($this->data[0]->$key) ? 'number' : 'string';
}
$output .= "<th data-key='{$key}' data-type='{$dataType}' data-direction='" . $direction . "' data-label='" . htmlspecialchars($column->name) . "' onclick='sortTable(\"" . htmlspecialchars($this->uniqueId) . "\", \"" . htmlspecialchars($key) . "\")'>" . htmlspecialchars($column->name) . "{$arrow}</th>";
$output .= "<th class='sortable-th' data-key='{$key}' data-type='{$dataType}' data-direction='" . $direction . "' data-label='" . htmlspecialchars($column->name) . "' data-uq-id='" . htmlspecialchars($this->uniqueId) . "'>" . htmlspecialchars($column->name) . "{$arrow}</th>";
}

$initialRootUrl = $this->initialUrl ? preg_replace('/^(https?:\/\/[^\/]+).*$/', '$1', $this->initialUrl) : null;
Expand Down
12 changes: 6 additions & 6 deletions src/Crawler/Export/HtmlReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -616,26 +616,26 @@ function filterByMatched() {
$html .= '<form id="imageDisplayForm">
<div class="form-group">
<div class="btn-group">
<input type="radio" id="sizeSmall" name="thumbnailSize" value="small" checked onchange="updateClassName(\'igc\', this.value)">
<input class="idf" type="radio" id="sizeSmall" name="thumbnailSize" value="small" data-key="igc" checked>
<label for="sizeSmall">small</label>
<input type="radio" id="sizeMedium" name="thumbnailSize" value="medium" onchange="updateClassName(\'igc\', this.value)">
<input class="idf" type="radio" id="sizeMedium" name="thumbnailSize" value="medium" data-key="igc">
<label for="sizeMedium">medium</label>
<input type="radio" id="sizeLarge" name="thumbnailSize" value="large" onchange="updateClassName(\'igc\', this.value)">
<input class="idf" type="radio" id="sizeLarge" name="thumbnailSize" value="large" data-key="igc">
<label for="sizeLarge">large</label>
</div>
</div>
<div class="form-group">
<div class="btn-group">
<input type="radio" id="modeScaleDown" name="thumbnailMode" value="scaleDown" onchange="updateClassName(\'igcf\', this.value)" checked>
<input class="idf" type="radio" id="modeScaleDown" name="thumbnailMode" value="scaleDown" data-key="igcf" checked>
<label for="modeScaleDown">scale-down</label>
<input type="radio" id="modeContain" name="thumbnailMode" value="contain" onchange="updateClassName(\'igcf\', this.value)">
<input class="idf" type="radio" id="modeContain" name="thumbnailMode" value="contain" data-key="igcf">
<label for="modeContain">contain</label>
<input type="radio" id="modeCover" name="thumbnailMode" value="cover" onchange="updateClassName(\'igcf\', this.value)">
<input class="idf" type="radio" id="modeCover" name="thumbnailMode" value="cover" data-key="igcf">
<label for="modeCover">cover</label>
</div>
</div>
Expand Down
37 changes: 37 additions & 0 deletions src/Crawler/Export/HtmlReport/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,43 @@ <h1>Crawler Report for <a href="{$initialUrl}" aria-label="Link to Crawler targe
debounce(tableFulltext, 250)(tableId, searchTerm);
}

document.addEventListener('DOMContentLoaded', function () {
/* add event listeners to fulltext inputs above super tables */
function onFulltextKeyup(event) {
const dataUqId = event.target.getAttribute('data-uq-id');
const inputValue = event.target.value;
debouncedTableFulltext(dataUqId, inputValue);
}

const inputs = document.querySelectorAll('input.fulltext[data-uq-id]');
inputs.forEach(input => {
input.addEventListener('keyup', onFulltextKeyup);
});

/* add event listeners to sortable table headers */
function onTableHeaderClick(event) {
const dataUqId = event.target.getAttribute('data-uq-id');
const dataKey = event.target.getAttribute('data-key');
sortTable(dataUqId, dataKey);
}

const tableHeaders = document.querySelectorAll('th.sortable-th[data-uq-id]');
tableHeaders.forEach(th => {
th.addEventListener('click', onTableHeaderClick);
});

/* add event listeners to image gallery filters */
function onImageFilterClick(event) {
const dataKey = event.target.getAttribute('data-key');
updateClassName(dataKey, event.target.value);
}

const imgFilters = document.querySelectorAll('input.idf[data-key]');
imgFilters.forEach(f => {
f.addEventListener('change', onImageFilterClick);
});
});

</script>
</div>
</body>
Expand Down

0 comments on commit b576eef

Please sign in to comment.