@ -10,20 +10,20 @@ import RightPanelWidget from "./right_panel_widget.js";
import options from "../services/options.js" ;
import options from "../services/options.js" ;
import OnClickButtonWidget from "./buttons/onclick_button.js" ;
import OnClickButtonWidget from "./buttons/onclick_button.js" ;
const TPL = ` <div class="highli s ts-list-widget">
const TPL = ` <div class="highli gh ts-list-widget">
< style >
< style >
. highli s ts- list - widget {
. highli gh ts- list - widget {
padding : 10 px ;
padding : 10 px ;
contain : none ;
contain : none ;
overflow : auto ;
overflow : auto ;
position : relative ;
position : relative ;
}
}
. highli s ts- list > ol {
. highli gh ts- list > ol {
padding - left : 20 px ;
padding - left : 20 px ;
}
}
. highli s ts- list li {
. highli gh ts- list li {
cursor : pointer ;
cursor : pointer ;
margin - bottom : 3 px ;
margin - bottom : 3 px ;
text - align : justify ;
text - align : justify ;
@ -32,18 +32,18 @@ const TPL = `<div class="highlists-list-widget">
hyphens : auto ;
hyphens : auto ;
}
}
. highli s ts- list li : hover {
. highli gh ts- list li : hover {
font - weight : bold ;
font - weight : bold ;
}
}
. close - highli s ts- list {
. close - highli gh ts- list {
position : absolute ;
position : absolute ;
top : 2 px ;
top : 2 px ;
right : 0 px ;
right : 0 px ;
}
}
< / s t y l e >
< / s t y l e >
< span class = "highli s ts-list"> < / s p a n >
< span class = "highli gh ts-list"> < / s p a n >
< / d i v > ` ;
< / d i v > ` ;
export default class HighlightsListWidget extends RightPanelWidget {
export default class HighlightsListWidget extends RightPanelWidget {
@ -55,61 +55,61 @@ export default class HighlightsListWidget extends RightPanelWidget {
}
}
get widgetTitle ( ) {
get widgetTitle ( ) {
return "Highlight ed Tex t";
return "Highlight s Lis t";
}
}
isEnabled ( ) {
isEnabled ( ) {
return super . isEnabled ( )
return super . isEnabled ( )
&& this . note . type === 'text'
&& this . note . type === 'text'
&& ! this . noteContext . viewScope . highlight edTex tTemporarilyHidden
&& ! this . noteContext . viewScope . highlight sLis tTemporarilyHidden
&& this . noteContext . viewScope . viewMode === 'default' ;
&& this . noteContext . viewScope . viewMode === 'default' ;
}
}
async doRenderBody ( ) {
async doRenderBody ( ) {
this . $body . empty ( ) . append ( $ ( TPL ) ) ;
this . $body . empty ( ) . append ( $ ( TPL ) ) ;
this . $highlightsList = this . $body . find ( '.highli s ts-list') ;
this . $highlightsList = this . $body . find ( '.highli gh ts-list') ;
this . $body . find ( '.highli s ts-list-widget') . append ( this . closeHltButton . render ( ) ) ;
this . $body . find ( '.highli gh ts-list-widget') . append ( this . closeHltButton . render ( ) ) ;
}
}
async refreshWithNote ( note ) {
async refreshWithNote ( note ) {
/ * T h e r e a s o n f o r a d d i n g h i g h l i g h t ed T e x t P r e v i o u s V i s i b l e i s t o r e c o r d w h e t h e r t h e p r e v i o u s s t a t e
/ * T h e r e a s o n f o r a d d i n g h i g h l i g h t sL i s t P r e v i o u s V i s i b l e i s t o r e c o r d w h e t h e r t h e p r e v i o u s s t a t e
of the highlight edTex t is hidden or displayed , and then let it be displayed / hidden at the initial time .
of the highlight sLis t is hidden or displayed , and then let it be displayed / hidden at the initial time .
If there is no such value , when the right panel needs to display toc but not highlighttext ,
If there is no such value , when the right panel needs to display toc but not highlighttext ,
every time the note content is changed , highlighttext Widget will appear and then close immediately ,
every time the note content is changed , highlighttext Widget will appear and then close immediately ,
because getHlt function will consume time * /
because getHlt function will consume time * /
if ( this . noteContext . viewScope . highlight edTex tPreviousVisible) {
if ( this . noteContext . viewScope . highlight sLis tPreviousVisible) {
this . toggleInt ( true ) ;
this . toggleInt ( true ) ;
} else {
} else {
this . toggleInt ( false ) ;
this . toggleInt ( false ) ;
}
}
const optionsH lt = JSON . parse ( options . get ( 'highlight edTex t') ) ;
const optionsH igh lightsLis t = JSON . parse ( options . get ( 'highlight sLis t') ) ;
if ( note . isLabelTruthy ( 'hideHighlightWidget' ) || ! optionsH lt) {
if ( note . isLabelTruthy ( 'hideHighlightWidget' ) || ! optionsH igh lightsLis t) {
this . toggleInt ( false ) ;
this . toggleInt ( false ) ;
this . triggerCommand ( "reEvaluateRightPaneVisibility" ) ;
this . triggerCommand ( "reEvaluateRightPaneVisibility" ) ;
return ;
return ;
}
}
let $highlightsList = "" , hl t LiCount = - 1 ;
let $highlightsList = "" , hl LiCount = - 1 ;
// Check for type text unconditionally in case alwaysShowWidget is set
// Check for type text unconditionally in case alwaysShowWidget is set
if ( this . note . type === 'text' ) {
if ( this . note . type === 'text' ) {
const { content } = await note . getNoteComplement ( ) ;
const { content } = await note . getNoteComplement ( ) ;
( { $highlightsList , hl t LiCount} = this . getHighlightList ( content , optionsH lt) ) ;
( { $highlightsList , hl LiCount} = this . getHighlightList ( content , optionsH igh lightsLis t) ) ;
}
}
this . $highlightsList . empty ( ) . append ( $highlightsList ) ;
this . $highlightsList . empty ( ) . append ( $highlightsList ) ;
if ( hl t LiCount > 0 ) {
if ( hl LiCount > 0 ) {
this . toggleInt ( true ) ;
this . toggleInt ( true ) ;
this . noteContext . viewScope . highlight edTex tPreviousVisible = true ;
this . noteContext . viewScope . highlight sLis tPreviousVisible = true ;
} else {
} else {
this . toggleInt ( false ) ;
this . toggleInt ( false ) ;
this . noteContext . viewScope . highlight edTex tPreviousVisible = false ;
this . noteContext . viewScope . highlight sLis tPreviousVisible = false ;
}
}
this . triggerCommand ( "reEvaluateRightPaneVisibility" ) ;
this . triggerCommand ( "reEvaluateRightPaneVisibility" ) ;
}
}
getHighlightList ( content , optionsH lt) {
getHighlightList ( content , optionsH igh lightsLis t) {
// matches a span containing background-color
// matches a span containing background-color
const regex1 = /<span[^>]*style\s*=\s*[^>]*background-color:[^>]*?>[\s\S]*?<\/span>/gi ;
const regex1 = /<span[^>]*style\s*=\s*[^>]*background-color:[^>]*?>[\s\S]*?<\/span>/gi ;
// matches a span containing color
// matches a span containing color
@ -120,27 +120,27 @@ export default class HighlightsListWidget extends RightPanelWidget {
const regex4 = /<strong>[\s\S]*?<\/strong>/gi ;
const regex4 = /<strong>[\s\S]*?<\/strong>/gi ;
// match underline
// match underline
const regex5 = /<u>[\s\S]*?<\/u>/g ;
const regex5 = /<u>[\s\S]*?<\/u>/g ;
// Possible values in optionsH lt: '["bold","italic","underline","color","bgColor"]'
// Possible values in optionsH igh lightsLis t: '["bold","italic","underline","color","bgColor"]'
// element priority: span>i>strong>u
// element priority: span>i>strong>u
let findSubStr = "" , combinedRegexStr = "" ;
let findSubStr = "" , combinedRegexStr = "" ;
if ( optionsH lt. includes ( "bgColor" ) ) {
if ( optionsH igh lightsLis t. includes ( "bgColor" ) ) {
findSubStr += ` ,span[style*="background-color"] ` ;
findSubStr += ` ,span[style*="background-color"] :not(section.include-note span[style*="background-color"]) ` ;
combinedRegexStr += ` | ${ regex1 . source } ` ;
combinedRegexStr += ` | ${ regex1 . source } ` ;
}
}
if ( optionsH lt. includes ( "color" ) ) {
if ( optionsH igh lightsLis t. includes ( "color" ) ) {
findSubStr += ` ,span[style*="color"] ` ;
findSubStr += ` ,span[style*="color"] :not(section.include-note span[style*="color"]) ` ;
combinedRegexStr += ` | ${ regex2 . source } ` ;
combinedRegexStr += ` | ${ regex2 . source } ` ;
}
}
if ( optionsH lt. includes ( "italic" ) ) {
if ( optionsH igh lightsLis t. includes ( "italic" ) ) {
findSubStr += ` ,i ` ;
findSubStr += ` ,i :not(section.include-note i) ` ;
combinedRegexStr += ` | ${ regex3 . source } ` ;
combinedRegexStr += ` | ${ regex3 . source } ` ;
}
}
if ( optionsH lt. indexOf ( "bold" ) ) {
if ( optionsH ighlightsList. includes ( "bold" ) ) {
findSubStr += ` ,strong ` ;
findSubStr += ` ,strong :not(section.include-note strong) ` ;
combinedRegexStr += ` | ${ regex4 . source } ` ;
combinedRegexStr += ` | ${ regex4 . source } ` ;
}
}
if ( optionsH lt. includes ( "underline" ) ) {
if ( optionsH igh lightsLis t. includes ( "underline" ) ) {
findSubStr += ` ,u ` ;
findSubStr += ` ,u :not(section.include-note u) ` ;
combinedRegexStr += ` | ${ regex5 . source } ` ;
combinedRegexStr += ` | ${ regex5 . source } ` ;
}
}
@ -148,7 +148,7 @@ export default class HighlightsListWidget extends RightPanelWidget {
combinedRegexStr = ` ( ` + combinedRegexStr . substring ( 1 ) + ` ) ` ;
combinedRegexStr = ` ( ` + combinedRegexStr . substring ( 1 ) + ` ) ` ;
const combinedRegex = new RegExp ( combinedRegexStr , 'gi' ) ;
const combinedRegex = new RegExp ( combinedRegexStr , 'gi' ) ;
const $highlightsList = $ ( "<ol>" ) ;
const $highlightsList = $ ( "<ol>" ) ;
let prevEndIndex = - 1 , hl t LiCount = 0 ;
let prevEndIndex = - 1 , hl LiCount = 0 ;
for ( let match = null , hltIndex = 0 ; ( ( match = combinedRegex . exec ( content ) ) !== null ) ; hltIndex ++ ) {
for ( let match = null , hltIndex = 0 ; ( ( match = combinedRegex . exec ( content ) ) !== null ) ; hltIndex ++ ) {
const subHtml = match [ 0 ] ;
const subHtml = match [ 0 ] ;
const startIndex = match . index ;
const startIndex = match . index ;
@ -158,16 +158,18 @@ export default class HighlightsListWidget extends RightPanelWidget {
$highlightsList . children ( ) . last ( ) . append ( subHtml ) ;
$highlightsList . children ( ) . last ( ) . append ( subHtml ) ;
} else {
} else {
// TODO: can't be done with $(subHtml).text()?
// TODO: can't be done with $(subHtml).text()?
const hasText = [ ... subHtml . matchAll ( /(?<=^|>)[^><]+?(?=<|$)/g ) ] . map ( matchTmp => matchTmp [ 0 ] ) . join ( '' ) . trim ( ) ;
//Can’ t remember why regular expressions are used here, but modified to $(subHtml).text() works as expected
//const hasText = [...subHtml.matchAll(/(?<=^|>)[^><]+?(?=<|$)/g)].map(matchTmp => matchTmp[0]).join('').trim();
const hasText = $ ( subHtml ) . text ( ) . trim ( ) ;
if ( hasText ) {
if ( hasText ) {
$highlightsList . append (
$highlightsList . append (
$ ( '<li>' )
$ ( '<li>' )
. html ( subHtml )
. html ( subHtml )
. on ( "click" , ( ) => this . jumpToHighlight edTex t( findSubStr , hltIndex ) )
. on ( "click" , ( ) => this . jumpToHighlight sLis t( findSubStr , hltIndex ) )
) ;
) ;
hl t LiCount++ ;
hl LiCount++ ;
} else {
} else {
// hide li if its text content is empty
// hide li if its text content is empty
continue ;
continue ;
@ -177,11 +179,11 @@ export default class HighlightsListWidget extends RightPanelWidget {
}
}
return {
return {
$highlightsList ,
$highlightsList ,
hl t LiCount
hl LiCount
} ;
} ;
}
}
async jumpToHighlight edTex t( findSubStr , itemIndex ) {
async jumpToHighlight sLis t( findSubStr , itemIndex ) {
const isReadOnly = await this . noteContext . isReadOnly ( ) ;
const isReadOnly = await this . noteContext . isReadOnly ( ) ;
let targetElement ;
let targetElement ;
if ( isReadOnly ) {
if ( isReadOnly ) {
@ -224,7 +226,7 @@ export default class HighlightsListWidget extends RightPanelWidget {
}
}
async closeHltCommand ( ) {
async closeHltCommand ( ) {
this . noteContext . viewScope . highlight edTex tTemporarilyHidden = true ;
this . noteContext . viewScope . highlight sLis tTemporarilyHidden = true ;
await this . refresh ( ) ;
await this . refresh ( ) ;
this . triggerCommand ( 'reEvaluateRightPaneVisibility' ) ;
this . triggerCommand ( 'reEvaluateRightPaneVisibility' ) ;
}
}
@ -245,13 +247,13 @@ class CloseHltButton extends OnClickButtonWidget {
super ( ) ;
super ( ) ;
this . icon ( "bx-x" )
this . icon ( "bx-x" )
. title ( "Close Highlight edTex tWidget")
. title ( "Close Highlight sLis tWidget")
. titlePlacement ( "bottom" )
. titlePlacement ( "bottom" )
. onClick ( ( widget , e ) => {
. onClick ( ( widget , e ) => {
e . stopPropagation ( ) ;
e . stopPropagation ( ) ;
widget . triggerCommand ( "closeHlt" ) ;
widget . triggerCommand ( "closeHlt" ) ;
} )
} )
. class ( "icon-action close-highli s ts-list") ;
. class ( "icon-action close-highli gh ts-list") ;
}
}
}
}