Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bindings/jupyroot/python/JupyROOT/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
################################################################################


from __future__ import print_function

import os
import sys
import select

Check failure on line 20 in bindings/jupyroot/python/JupyROOT/helpers/utils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

bindings/jupyroot/python/JupyROOT/helpers/utils.py:20:8: F401 `select` imported but unused
import tempfile
import itertools

Check failure on line 22 in bindings/jupyroot/python/JupyROOT/helpers/utils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

bindings/jupyroot/python/JupyROOT/helpers/utils.py:22:8: F401 `itertools` imported but unused
import re
import fnmatch
import time
Expand Down Expand Up @@ -74,7 +74,7 @@

// We are in jupyter notebooks, use require.js which should be configured already
requirejs.config({{
paths: {{ 'JSRootCore' : [ 'build/jsroot', 'https://root.cern/js/7.9.0/build/jsroot', 'https://jsroot.gsi.de/7.9.0/build/jsroot' ] }}
paths: {{ 'JSRootCore' : [ 'build/jsroot', 'https://root.cern/js/7.9.3/build/jsroot', 'https://jsroot.gsi.de/7.9.3/build/jsroot' ] }}
}})(['JSRootCore'], function(Core) {{
display_{jsDivId}(Core);
}});
Expand All @@ -97,7 +97,7 @@
// Try loading a local version of requirejs and fallback to cdn if not possible.
script_load_{jsDivId}(base_url + 'static/build/jsroot.js', function(){{
console.error('Fail to load JSROOT locally, please check your jupyter_notebook_config.py file');
script_load_{jsDivId}('https://root.cern/js/7.9.0/build/jsroot.js', function(){{
script_load_{jsDivId}('https://root.cern/js/7.9.3/build/jsroot.js', function(){{
document.getElementById("{jsDivId}").innerHTML = "Failed to load JSROOT";
}});
}});
Expand Down Expand Up @@ -231,7 +231,7 @@
out = ""
try:
out = check_output(command.split())
except:

Check failure on line 234 in bindings/jupyroot/python/JupyROOT/helpers/utils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E722)

bindings/jupyroot/python/JupyROOT/helpers/utils.py:234:5: E722 Do not use bare `except`
if errMsg:
sys.stderr.write("%s (command was %s)\n" %(errMsg,command))
return out
Expand All @@ -246,7 +246,7 @@
the library, which we then load.
'''
command = 'root -l -q -b -e gSystem->CompileMacro(\"%s\",\"k\")*0'%fileName
out = _checkOutput(command, "Error ivoking ACLiC")

Check failure on line 249 in bindings/jupyroot/python/JupyROOT/helpers/utils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F841)

bindings/jupyroot/python/JupyROOT/helpers/utils.py:249:5: F841 Local variable `out` is assigned to but never used
libNameBase = fileName.replace(".C","_C")
ROOT.gSystem.Load(libNameBase)

Expand All @@ -261,7 +261,7 @@
>>> _codeToFilename(code)[-2:]
'.C'
'''
code_enc = code if type(code) == bytes else code.encode('utf-8')

Check failure on line 264 in bindings/jupyroot/python/JupyROOT/helpers/utils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E721)

bindings/jupyroot/python/JupyROOT/helpers/utils.py:264:24: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks
fileNameBase = sha1(code_enc).hexdigest()[0:8]
timestamp = datetime.now().strftime("%H%M%S%f")
return fileNameBase + "_" + timestamp + ".C"
Expand All @@ -279,12 +279,12 @@
'''
fileName = _codeToFilename(code)
with open (fileName,'w') as ofile:
code_dec = code if type(code) != bytes else code.decode('utf-8')

Check failure on line 282 in bindings/jupyroot/python/JupyROOT/helpers/utils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E721)

bindings/jupyroot/python/JupyROOT/helpers/utils.py:282:26: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks
ofile.write(code_dec)
return fileName

def isPlatformApple():
return _getPlatform() == 'darwin';

Check failure on line 287 in bindings/jupyroot/python/JupyROOT/helpers/utils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E703)

bindings/jupyroot/python/JupyROOT/helpers/utils.py:287:37: E703 Statement ends with an unnecessary semicolon

def invokeAclic(cell):
fileName = _dumpToUniqueFile(cell)
Expand Down Expand Up @@ -317,7 +317,7 @@

cnt = 0
for n in range(colors.GetLast()+1):
if colors.At(n): cnt = cnt+1

Check failure on line 320 in bindings/jupyroot/python/JupyROOT/helpers/utils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E701)

bindings/jupyroot/python/JupyROOT/helpers/utils.py:320:22: E701 Multiple statements on one line (colon)

# add all colors if there are more than 598 colors defined
if cnt < 599 or prim.FindObject(colors):
Expand All @@ -338,7 +338,7 @@
canvas_json = ROOT.TBufferJSON.ConvertToJSON(canvas, 23)

# Cleanup primitives after conversion
if style is not None: prim.Remove(style)

Check failure on line 341 in bindings/jupyroot/python/JupyROOT/helpers/utils.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E701)

bindings/jupyroot/python/JupyROOT/helpers/utils.py:341:24: E701 Multiple statements on one line (colon)
if colors is not None: prim.Remove(colors)
if palette is not None: prim.Remove(palette)

Expand Down
48 changes: 26 additions & 22 deletions js/build/jsroot.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ typeof define === 'function' && define.amd ? define(['exports'], factory) :
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
/** @summary version id
* @desc For the JSROOT release the string in format 'major.minor.patch' like '7.0.0' */
const version_id = '7.9.x',
const version_id = '7.9.3',

/** @summary version date
* @desc Release date in format day/month/year like '14/04/2022' */
version_date = '14/10/2025',
version_date = '21/10/2025',

/** @summary version id and date
* @desc Produced by concatenation of {@link version_id} and {@link version_date}
Expand Down Expand Up @@ -13903,24 +13903,24 @@ function drawRawText(dom, txt /* , opt */) {
if (!isStr(stxt))
stxt = '<undefined>';

const mathjax = this.txt.mathjax || (settings.Latex === constants$1.Latex.AlwaysMathJax);

if (!mathjax && !('as_is' in this.txt)) {
const arr = stxt.split('\n');
stxt = '';
for (let i = 0; i < arr.length; ++i)
stxt += `<pre style='margin:0'>${arr[i]}</pre>`;
}

const frame = this.selectDom();
const mathjax = this.txt.mathjax || (settings.Latex === constants$1.Latex.AlwaysMathJax),
frame = this.selectDom();
let main = frame.select('div');
if (main.empty())
main = frame.append('div').attr('style', 'max-width:100%;max-height:100%;overflow:auto');
main.html(stxt);
else
main.html('');

// (re) set painter to first child element, base painter not requires canvas
this.setTopPainter();

if (!mathjax && !('as_is' in this.txt)) {
const arr = stxt.split('\n');
for (let i = 0; i < arr.length; ++i)
main.append('pre').style('margin', '0').text(arr[i]);
} else
main.text(stxt);

if (mathjax)
typesetMathjax(frame.node());

Expand Down Expand Up @@ -71015,7 +71015,7 @@ class StandaloneMenu extends JSRootMenu {
text.style.display = 'flex';

const chk = doc.createElement('span');
chk.innerHTML = d.checked ? '\u2713' : '';
chk.innerText = d.checked ? '\u2713' : '';
chk.style.display = 'inline-block';
chk.style.width = '1em';
text.appendChild(chk);
Expand All @@ -71028,7 +71028,7 @@ class StandaloneMenu extends JSRootMenu {
} else {
if (need_check_area) {
const chk = doc.createElement('span');
chk.innerHTML = d.checked ? '\u2713' : '';
chk.innerText = d.checked ? '\u2713' : '';
chk.style.display = 'inline-block';
chk.style.width = '1em';
text.appendChild(chk);
Expand Down Expand Up @@ -76863,10 +76863,12 @@ class FlexibleDisplay extends MDIDisplay {
main = top.append('div');

main.html('<div class=\'jsroot_flex_header\' style=\'height: 23px; overflow: hidden; background-color: lightblue\'>' +
`<p style='margin: 1px; float: left; font-size: 14px; padding-left: 5px'>${title}</p></div>`+
`<div id='${this.frameid}_cont${this.cnt}' class='jsroot_flex_draw' style='overflow: hidden; width: 100%; height: calc(100% - 24px); background: white'></div>`+
'<p style=\'margin: 1px; float: left; font-size: 14px; padding-left: 5px\'></p></div>' +
`<div id='${this.frameid}_cont${this.cnt}' class='jsroot_flex_draw' style='overflow: hidden; width: 100%; height: calc(100% - 24px); background: white'></div>` +
'<div class=\'jsroot_flex_resize\' style=\'position: absolute; right: 3px; bottom: 1px; overflow: hidden; cursor: nwse-resize\'>&#x25FF;</div>');

main.select('.jsroot_flex_header p').text(title);

main.attr('class', 'jsroot_flex_frame')
.style('position', 'absolute')
.style('left', Math.round(w * (this.cnt % 5)/10) + 'px')
Expand Down Expand Up @@ -155421,7 +155423,7 @@ function objectHierarchy(top, obj, args = undefined) {
item._vclass = cssValueNum;
} else if (isStr(fld)) {
simple = true;
item._value = '&quot;' + fld.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;') + '&quot;';
item._value = '"' + fld + '"';
item._vclass = 'h_value_str';
} else if (typeof fld === 'undefined') {
simple = true;
Expand Down Expand Up @@ -156216,8 +156218,10 @@ class HierarchyPainter extends BasePainter {

if ('_value' in hitem) {
const d3p = d3line.append('p');
if ('_vclass' in hitem) d3p.attr('class', hitem._vclass);
if (!hitem._isopen) d3p.html(hitem._value);
if ('_vclass' in hitem)
d3p.attr('class', hitem._vclass);
if (!hitem._isopen)
d3p.text(hitem._value);
}

if (has_childs && (isroot || hitem._isopen)) {
Expand Down Expand Up @@ -158795,7 +158799,7 @@ class HierarchyPainter extends BasePainter {
const layout = main.select('.gui_layout');
if (!layout.empty()) {
['simple', 'vert2', 'vert3', 'vert231', 'horiz2', 'horiz32', 'flex', 'tabs',
'grid 2x2', 'grid 1x3', 'grid 2x3', 'grid 3x3', 'grid 4x4'].forEach(kind => layout.append('option').attr('value', kind).html(kind));
'grid 2x2', 'grid 1x3', 'grid 2x3', 'grid 3x3', 'grid 4x4'].forEach(kind => layout.append('option').attr('value', kind).text(kind));

layout.on('change', ev => {
const kind = ev.target.value || 'flex';
Expand Down Expand Up @@ -158835,7 +158839,7 @@ class HierarchyPainter extends BasePainter {
}
if (!found) {
const opt = document.createElement('option');
opt.innerHTML = opt.value = this.getLayout();
opt.innerText = opt.value = this.getLayout();
selects.appendChild(opt);
selects.selectedIndex = selects.options.length - 1;
}
Expand Down
4 changes: 3 additions & 1 deletion js/changes.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# JSROOT changelog

## Changes in 7.9.x
## Changes in 7.9.3
1. Fix - store large PDF with 3D drawing inside
2. Fix - prevent JS code injection via `TObjString` drawing
3. Fix - reduce use of HTML in hpainter, display and menu components


## Changes in 7.9.2
Expand Down
22 changes: 11 additions & 11 deletions js/modules/base/ObjectPainter.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1642,24 +1642,24 @@ function drawRawText(dom, txt /* , opt */) {
if (!isStr(stxt))
stxt = '<undefined>';

const mathjax = this.txt.mathjax || (settings.Latex === constants.Latex.AlwaysMathJax);

if (!mathjax && !('as_is' in this.txt)) {
const arr = stxt.split('\n');
stxt = '';
for (let i = 0; i < arr.length; ++i)
stxt += `<pre style='margin:0'>${arr[i]}</pre>`;
}

const frame = this.selectDom();
const mathjax = this.txt.mathjax || (settings.Latex === constants.Latex.AlwaysMathJax),
frame = this.selectDom();
let main = frame.select('div');
if (main.empty())
main = frame.append('div').attr('style', 'max-width:100%;max-height:100%;overflow:auto');
main.html(stxt);
else
main.html('');

// (re) set painter to first child element, base painter not requires canvas
this.setTopPainter();

if (!mathjax && !('as_is' in this.txt)) {
const arr = stxt.split('\n');
for (let i = 0; i < arr.length; ++i)
main.append('pre').style('margin', '0').text(arr[i]);
} else
main.text(stxt);

if (mathjax)
typesetMathjax(frame.node());

Expand Down
4 changes: 2 additions & 2 deletions js/modules/core.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/** @summary version id
* @desc For the JSROOT release the string in format 'major.minor.patch' like '7.0.0' */
const version_id = '7.9.x',
const version_id = '7.9.3',

/** @summary version date
* @desc Release date in format day/month/year like '14/04/2022' */
version_date = '14/10/2025',
version_date = '21/10/2025',

/** @summary version id and date
* @desc Produced by concatenation of {@link version_id} and {@link version_date}
Expand Down
12 changes: 7 additions & 5 deletions js/modules/gui/HierarchyPainter.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ function objectHierarchy(top, obj, args = undefined) {
item._vclass = cssValueNum;
} else if (isStr(fld)) {
simple = true;
item._value = '&quot;' + fld.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;') + '&quot;';
item._value = '"' + fld + '"';
item._vclass = 'h_value_str';
} else if (typeof fld === 'undefined') {
simple = true;
Expand Down Expand Up @@ -1306,8 +1306,10 @@ class HierarchyPainter extends BasePainter {

if ('_value' in hitem) {
const d3p = d3line.append('p');
if ('_vclass' in hitem) d3p.attr('class', hitem._vclass);
if (!hitem._isopen) d3p.html(hitem._value);
if ('_vclass' in hitem)
d3p.attr('class', hitem._vclass);
if (!hitem._isopen)
d3p.text(hitem._value);
}

if (has_childs && (isroot || hitem._isopen)) {
Expand Down Expand Up @@ -3885,7 +3887,7 @@ class HierarchyPainter extends BasePainter {
const layout = main.select('.gui_layout');
if (!layout.empty()) {
['simple', 'vert2', 'vert3', 'vert231', 'horiz2', 'horiz32', 'flex', 'tabs',
'grid 2x2', 'grid 1x3', 'grid 2x3', 'grid 3x3', 'grid 4x4'].forEach(kind => layout.append('option').attr('value', kind).html(kind));
'grid 2x2', 'grid 1x3', 'grid 2x3', 'grid 3x3', 'grid 4x4'].forEach(kind => layout.append('option').attr('value', kind).text(kind));

layout.on('change', ev => {
const kind = ev.target.value || 'flex';
Expand Down Expand Up @@ -3925,7 +3927,7 @@ class HierarchyPainter extends BasePainter {
}
if (!found) {
const opt = document.createElement('option');
opt.innerHTML = opt.value = this.getLayout();
opt.innerText = opt.value = this.getLayout();
selects.appendChild(opt);
selects.selectedIndex = selects.options.length - 1;
}
Expand Down
6 changes: 4 additions & 2 deletions js/modules/gui/display.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -933,10 +933,12 @@ class FlexibleDisplay extends MDIDisplay {
main = top.append('div');

main.html('<div class=\'jsroot_flex_header\' style=\'height: 23px; overflow: hidden; background-color: lightblue\'>' +
`<p style='margin: 1px; float: left; font-size: 14px; padding-left: 5px'>${title}</p></div>`+
`<div id='${this.frameid}_cont${this.cnt}' class='jsroot_flex_draw' style='overflow: hidden; width: 100%; height: calc(100% - 24px); background: white'></div>`+
'<p style=\'margin: 1px; float: left; font-size: 14px; padding-left: 5px\'></p></div>' +
`<div id='${this.frameid}_cont${this.cnt}' class='jsroot_flex_draw' style='overflow: hidden; width: 100%; height: calc(100% - 24px); background: white'></div>` +
'<div class=\'jsroot_flex_resize\' style=\'position: absolute; right: 3px; bottom: 1px; overflow: hidden; cursor: nwse-resize\'>&#x25FF;</div>');

main.select('.jsroot_flex_header p').text(title);

main.attr('class', 'jsroot_flex_frame')
.style('position', 'absolute')
.style('left', Math.round(w * (this.cnt % 5)/10) + 'px')
Expand Down
4 changes: 2 additions & 2 deletions js/modules/gui/menu.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,7 @@ class StandaloneMenu extends JSRootMenu {
text.style.display = 'flex';

const chk = doc.createElement('span');
chk.innerHTML = d.checked ? '\u2713' : '';
chk.innerText = d.checked ? '\u2713' : '';
chk.style.display = 'inline-block';
chk.style.width = '1em';
text.appendChild(chk);
Expand All @@ -1363,7 +1363,7 @@ class StandaloneMenu extends JSRootMenu {
} else {
if (need_check_area) {
const chk = doc.createElement('span');
chk.innerHTML = d.checked ? '\u2713' : '';
chk.innerText = d.checked ? '\u2713' : '';
chk.style.display = 'inline-block';
chk.style.width = '1em';
text.appendChild(chk);
Expand Down
Loading