mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-21 09:38:48 +02:00
N°3379 - Introduce more modern tooltip lib. in the backoffice
- Allow usage of quotes, especially in attributes description - Allow line breaks, especially in attributes description - Allow better positioning (automatic) when close to the screen limits - Allow HTML (careful about XSS), content is sanitized by default
This commit is contained in:
@@ -882,8 +882,14 @@ EOF
|
||||
$aArgs).'';
|
||||
}
|
||||
$aFieldsMap[$sAttCode] = $sInputId;
|
||||
|
||||
// Attribute description
|
||||
$sDescription = $oAttDef->GetDescription();
|
||||
$sDescriptionForHTMLTag = utils::HtmlEntities($sDescription);
|
||||
$sDescriptionHTMLTag = (empty($sDescriptionForHTMLTag)) ? '' : 'class="ibo-has-description" data-tooltip-content="'.$sDescriptionForHTMLTag.'"';
|
||||
|
||||
$val = array(
|
||||
'label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().'</span>',
|
||||
'label' => '<span '.$sDescriptionHTMLTag.' >'.$oAttDef->GetLabel().'</span>',
|
||||
'value' => $sHTMLValue,
|
||||
'comments' => $sComments,
|
||||
'infos' => $sInfos,
|
||||
@@ -892,8 +898,13 @@ EOF
|
||||
}
|
||||
else
|
||||
{
|
||||
// Attribute description
|
||||
$sDescription = $oAttDef->GetDescription();
|
||||
$sDescriptionForHTMLTag = utils::HtmlEntities($sDescription);
|
||||
$sDescriptionHTMLTag = (empty($sDescriptionForHTMLTag)) ? '' : 'class="ibo-has-description" data-tooltip-content="'.$sDescriptionForHTMLTag.'"';
|
||||
|
||||
$val = array(
|
||||
'label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().'</span>',
|
||||
'label' => '<span '.$sDescriptionHTMLTag.' >'.$oAttDef->GetLabel().'</span>',
|
||||
'value' => "<span id=\"field_{$sInputId}\">".$this->GetAsHTML($sAttCode)."</span>",
|
||||
'comments' => $sComments,
|
||||
'infos' => $sInfos,
|
||||
@@ -3240,9 +3251,14 @@ EOF
|
||||
$sDisplayValue = $this->GetAsHTML($sAttCode);
|
||||
}
|
||||
}
|
||||
|
||||
// Attribute description
|
||||
$sDescription = $oAttDef->GetDescription();
|
||||
$sDescriptionForHTMLTag = utils::HtmlEntities($sDescription);
|
||||
$sDescriptionHTMLTag = (empty($sDescriptionForHTMLTag)) ? '' : 'class="ibo-has-description" data-tooltip-content="'.$sDescriptionForHTMLTag.'"';
|
||||
|
||||
$retVal = array(
|
||||
'label' => '<span title="'.MetaModel::GetDescription($sClass,
|
||||
$sAttCode).'">'.MetaModel::GetLabel($sClass, $sAttCode).'</span>',
|
||||
'label' => '<span '.$sDescriptionHTMLTag.' >'.MetaModel::GetLabel($sClass, $sAttCode).'</span>',
|
||||
'value' => $sDisplayValue,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
$ibo-field--sibling-spacing: 16px !default;
|
||||
$ibo-field--value--color: $ibo-color-grey-700 !default;
|
||||
|
||||
$ibo-field--label--description--content: "?" !default;
|
||||
$ibo-field--label--description--padding-left: 2px !default;
|
||||
$ibo-field--label--description--color: $ibo-color-grey-700 !default;
|
||||
|
||||
.ibo-field {
|
||||
@extend %ibo-font-ral-nor-150;
|
||||
|
||||
@@ -37,6 +41,18 @@ $ibo-field--value--color: $ibo-color-grey-700 !default;
|
||||
max-width: 145px;
|
||||
width: 30%;
|
||||
padding-right: 10px;
|
||||
|
||||
> .ibo-has-description {
|
||||
&::after {
|
||||
content: $ibo-field--label--description--content;
|
||||
padding-left: $ibo-field--label--description--padding-left;
|
||||
vertical-align: top;
|
||||
|
||||
cursor: pointer;
|
||||
color: $ibo-field--label--description--color;
|
||||
@extend %ibo-font-ral-bol-100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-field--value {
|
||||
|
||||
@@ -68,14 +68,46 @@ const CombodoBackofficeToolbox = {
|
||||
// Instanciate tooltips (abstraction layer between iTop markup and tooltip plugin to ease its replacement in the future)
|
||||
/**
|
||||
* Instanciate a tooltip on oElem from its data attributes
|
||||
*
|
||||
* Note: Content SHOULD be HTML entity encoded to avoid markup breaks (eg. when using a double quote in a sentence)
|
||||
*
|
||||
* @param oElem
|
||||
* @constructor
|
||||
*/
|
||||
InitTooltipFromMarkup: function(oElem)
|
||||
{
|
||||
const oOptions = {};
|
||||
const oOptions = {
|
||||
allowHTML: true, // Always true so line breaks can work. Don't worry content will be sanitized.
|
||||
};
|
||||
|
||||
// Content must be reworked before getting into the tooltip
|
||||
// - Should we enable HTML content or keep text as is
|
||||
const bEnableHTML = oElem.attr('data-tooltip-html-enabled') === 'true';
|
||||
|
||||
// - Content should be sanitized unless the developer says otherwise
|
||||
// Note: Condition is inversed on purpose. When the developer is instanciating a tooltip,
|
||||
// we want him/her to explicitly declare that he/she wants the sanitizer to be skipped.
|
||||
// Whereas in this code, it's easier to follow the logic with the variable oriented this way.
|
||||
const bSanitizeContent = oElem.attr('data-tooltip-sanitizer-skipped') !== 'true';
|
||||
|
||||
// - Sanitize content and make sure line breaks are kept
|
||||
const oTmpContentElem = $('<div />').html(oElem.attr('data-tooltip-content'));
|
||||
let sContent = '';
|
||||
if(bEnableHTML)
|
||||
{
|
||||
sContent = oTmpContentElem.html();
|
||||
if(bSanitizeContent)
|
||||
{
|
||||
sContent = sContent.replace(/<script/g, '<script WARNING: scripts are not allowed in tooltips');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sContent = oTmpContentElem.text();
|
||||
sContent = sContent.replace(/(\r\n|\n\r|\r|\n)/g, '<br/>');
|
||||
}
|
||||
oOptions['content'] = sContent;
|
||||
|
||||
oOptions['content'] = oElem.attr('data-tooltip-content');
|
||||
oOptions['placement'] = oElem.attr('data-tooltip-placement') ?? 'top';
|
||||
oOptions['trigger'] = oElem.attr('data-tooltip-trigger') ?? 'mouseenter focus';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user