5151< & /Elements/Tabs &>
5252< & /Elements/ListActions, actions => \@results &>
5353
54- < script type ="text/javascript " src ="<%RT->Config->Get('WebPath')%>/static/js/farbtastic.js "> </ script >
55-
56- < div class ="row ">
54+ < div class ="row mt-3 ">
5755
5856 < div id ="simple-customize " class ="col-6 ">
5957 < div id ="upload-logo ">
60- < h2 > Logo</ h2 >
61- < & /Elements/Logo, id = > 'logo-theme-editor', ShowName = > 0 & >
62- < button onclick =" setLogoSize() " class =" button btn btn-primary form-control " id =" logo-size " > < &|/l& > Full Size </ & > </ button >
63-
58+ < h3 > Logo</ h3 >
59+ < div class =" border border-secondary-subtle rounded " >
60+ < & /Elements/Logo, id = > 'logo-theme-editor', ShowName = > 0 & >
61+ </ div >
6462 < form method ="POST " enctype ="multipart/form-data " action ="">
6563 < div class ="row mt-2 ">
6664 < div class ="col-auto ">
@@ -75,14 +73,47 @@ <h2>Logo</h2>
7573 < &|/l&> GD is disabled or not installed. You can upload an image, but you won't get automatic color suggestions.</ &>
7674% }
7775 </ div >
78- < input class ="button btn btn-primary " name ="reset_logo " value ="<&|/l&>Reset to default RT Logo</&> " type ="submit " />
79- < input class ="button btn btn-primary " type ="submit " value ="<&|/l&>Upload</&> " />
76+ < input class ="button btn btn-primary mt-1 " name ="reset_logo " value ="<&|/l&>Reset to default RT Logo</&> " type ="submit " />
77+ < input class ="button btn btn-primary mt-1 " type ="submit " value ="<&|/l&>Upload</&> " />
8078 </ form >
8179 </ div >
80+
81+ < hr />
82+
83+ < div id ="customize-theme " class ="">
84+ < h3 > < &|/l&> Customize the RT theme</ &> </ h3 >
85+ < &| /Elements/LabeledValue, Label => loc('Select a section') &>
86+ < select class ="form-select selectpicker " id ="section " name ="section ">
87+ % for my $section ( @sections ) {
88+ < option value ="<% $section->[0] %> "> < % $section-> [0] %> </ option >
89+ % };
90+ </ select >
91+ </ &>
92+
93+ < &| /Elements/LabeledValue, Label => loc('Select a color for the section') &>
94+ < div class ="row ">
95+ % if ($colors) {
96+ < div class ="col button btn btn-primary primary-colors ">
97+ % for (@$colors) {
98+ % my $fg = $_-> {l} > = $text_threshold ? 'black' : 'white';
99+ < button type ="button " class ="button btn btn-primary color-template form-control "
100+ style ="background-color: rgb(<% $_->{c} %>); color: <% $fg %>; ">
101+ < &|/l&> Text</ &>
102+ </ button >
103+ % }
104+ </ div >
105+ % }
106+ < div class ="col ">
107+ < input type ="color " class ="form-control " id ="color-picker " />
108+ </ div >
109+ </ div >
110+ </ &>
111+ </ div >
112+
82113 </ div >
83114
84115 < div id ="custom-css " class ="col-6 ">
85- < h2 > < &|/l&> Custom CSS (Advanced)</ &> </ h2 >
116+ < h3 > < &|/l&> Custom CSS (Advanced)</ &> </ h3 >
86117
87118 < form method ="POST " id ="custom-css-form " action ="">
88119 < textarea class ="form-control mb-2 " rows ="20 " id ="user_css " name ="user_css " wrap ="off "> < % $user_css %> </ textarea >
@@ -94,41 +125,6 @@ <h2><&|/l&>Custom CSS (Advanced)</&></h2>
94125 </ div >
95126</ div >
96127
97- < br >
98-
99- < div class ="row ">
100- < div id ="customize-theme " class ="col-6 ">
101- < h2 > < &|/l&> Customize the RT theme</ &> </ h2 >
102- < ol class ="list-group-compact list-group ">
103- < li class ="list-group-item ">
104- < label for ="section "> < &|/l&> Select a section</ &> :</ label >
105- < select class ="selectpicker " id ="section "> </ select >
106- </ li >
107- < li class ="list-group-item ">
108- < div class ="description ">
109- < &|/l&> Select a color for the section</ &> :
110- < div id ="logo-picker-hint " style ="display: none; ">
111- < &|/l&> You can also click on the logo above to get colors!</ &>
112- </ div >
113- </ div >
114- % if ($colors) {
115- < div class ="button btn btn-primary primary-colors ">
116- % for (@$colors) {
117- % my $fg = $_-> {l} > = $text_threshold ? 'black' : 'white';
118- < button type ="button " class ="button btn btn-primary color-template form-control "
119- style ="background-color: rgb(<% $_->{c} %>); color: <% $fg %>; ">
120- < &|/l&> Text</ &>
121- </ button >
122- % }
123- </ div >
124- % }
125- < div id ="color-picker "> </ div >
126- < canvas id ="logo-color-picker " title ="<&|/l&>Click to choose a color</&> "> </ canvas >
127- </ li >
128- </ ol >
129- </ div >
130- </ div >
131-
132128< %ONCE>
133129my @sections = (
134130 ['Page' => ['body', 'div#body']],
@@ -146,25 +142,11 @@ <h2><&|/l&>Customize the RT theme</&></h2>
146142</ %ONCE>
147143< script type ="text/javascript ">
148144var section_css_mapping = < % JSON ( \@sections ) | n % > ;
149-
150145jQuery(function($) {
151-
152- jQuery . each ( section_css_mapping , function ( i , v ) {
153- $ ( 'select#section' ) . append ( $ ( "<option/>" )
154- . attr ( 'value' , v [ 0 ] )
155- . text ( v [ 0 ] ) ) ;
156- } ) ;
157- // Refresh selectpicker so we have a default value, at least for Firefox
158- $ ( 'select#section' ) . val ( section_css_mapping [ 0 ] [ 0 ] ) ;
159-
160146 function update_sitecss ( text ) {
161147 if ( ! text )
162148 text = $ ( '#user_css' ) . val ( ) ;
163-
164- // IE 8 doesn't let us update the innerHTML of <style> tags (with jQuery.text())
165- // see: http://stackoverflow.com/questions/2692770/style-style-textcss-appendtohead-does-not-work-in-ie/2692861#2692861
166- $ ( "style#sitecss" ) . remove ( ) ;
167- $ ( "<style id='sitecss' type='text/css' media='all'>" + text + "</style>" ) . appendTo ( 'head' ) ;
149+ $ ( "style#sitecss" ) . text ( text ) ;
168150 }
169151
170152 update_sitecss ( ) ;
@@ -225,73 +207,43 @@ <h2><&|/l&>Customize the RT theme</&></h2>
225207 update_sitecss ( css ) ;
226208 }
227209
228- $ ( '#color-picker' ) . farbtastic ( function ( color ) { change_color ( color , this . hsl [ 2 ] > < % $text_threshold % > ? '#000' : '#fff' ) } ) ;
210+ document . querySelector ( '#color-picker' ) . addEventListener ( 'change' , function ( ) {
211+ const red = parseInt ( '0x' + this . value . substr ( 1 , 2 ) ) ;
212+ const green = parseInt ( '0x' + this . value . substr ( 3 , 2 ) ) ;
213+ const blue = parseInt ( '0x' + this . value . substr ( 5 , 2 ) ) ;
214+ const lightness = ( Math . max ( red , green , blue ) + Math . min ( red , green , blue ) ) / 2 / 255 ;
215+ change_color ( this . value , lightness > < % $text_threshold % > ? '#000' : '#fff' ) ;
216+ } ) ;
229217
230218 $ ( 'button.color-template' ) . click ( function ( ) {
231219 change_color ( $ ( this ) . css ( 'background-color' ) , $ ( this ) . css ( 'color' ) ) ;
232- } ) ;
233-
234- } ) ;
235-
236- // Setup the canvas color picker
237- jQuery ( window ) . on ( 'load ', function ( ) {
238- var $ = jQuery ;
239- var logo = $ ( "#logo-theme-editor img" ) ;
240- var canvas = $ ( "#logo-color-picker" ) ;
241- var el_canvas = canvas . get ( 0 ) ;
220+ } ) ;
242221
243- if ( ! el_canvas . getContext ) return ;
244222
245- setLogoSize ( ) ;
223+ document . getElementById ( 'section' ) . addEventListener ( 'change' , event => {
224+ const section = event . target . value ;
225+ const selector = section_css_mapping . filter ( a => { return a [ 0 ] == section } ) [ 0 ] [ 1 ] [ 0 ] ;
226+ const specials = new RegExp ( "([.*+?|()\\[\\]{}\\\\])" , "g" ) ;
227+ const escaped_selector = selector . replace ( specials , "\\$1" ) ;
228+ const rule = new RegExp ( '^' + escaped_selector + '\\s*\{\\s*background:\\s*(#\\w+|rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\))' , "m" ) ;
229+ const css = document . getElementById ( 'user_css' ) . value ;
230+ const result = css . match ( rule ) ;
231+ if ( result ) {
232+ if ( result [ 2 ] ) {
233+ document . getElementById ( 'color-picker' ) . value =
234+ '#' + result . slice ( 2 , 5 ) . map ( num => parseInt ( num ) . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) ;
235+ }
236+ else {
237+ document . getElementById ( 'color-picker' ) . value = result [ 1 ] ;
238+ }
239+ }
240+ else {
241+ document . getElementById ( 'color-picker' ) . value = '#ffffff' ;
242+ }
243+ } ) ;
244+ document . getElementById ( 'section' ) . dispatchEvent ( new Event ( 'change' ) ) ;
246245} ) ;
247246
248- function setLogoSize() {
249- var logo = jQuery ( "#logo-theme-editor img" ) ;
250- var canvas = jQuery ( "#logo-color-picker" ) ;
251- var el_canvas = canvas . get ( 0 ) ;
252-
253- if ( ! el_canvas . getContext ) return ;
254- // Set logo to same size as CSS input
255- var container = jQuery ( '#user_css' ) ;
256-
257- var context = el_canvas . getContext ( "2d" ) ;
258- var button = jQuery ( '#logo-size' ) ;
259-
260- if ( button . text ( ) == '<&|/l&>Preview</&>' ) {
261- var ratio = Math . min ( container . width ( ) / logo . width ( ) , container . height ( ) / logo . height ( ) ) ;
262-
263- el_canvas . width = logo . width ( ) * ratio ;
264- el_canvas . height = logo . height ( ) * ratio ;
265-
266- // Re-draw our scaled down image
267- context . drawImage ( logo . get ( 0 ) , 0 , 0 , logo . width ( ) * ratio , logo . height ( ) * ratio ) ;
268-
269- button . text ( "<&|/l&>Full Size</&>" ) ;
270- }
271- else {
272- el_canvas . width = logo . width ( ) ;
273- el_canvas . height = logo . height ( ) ;
274-
275- context . drawImage ( logo . get ( 0 ) , 0 , 0 ) ;
276- button . text ( "<&|/l&>Preview</&>" ) ;
277- }
278-
279- logo.hide().after(canvas);
280- canvas.show().click(function(ev) {
281- ev . preventDefault ( ) ;
282- var R = 0 ,
283- G = 1 ,
284- B = 2 ,
285- A = 3 ;
286- var pixel = this . getContext ( "2d" ) . getImageData ( ev . offsetX , ev . offsetY , 1 , 1 ) . data ;
287- // Farbtastic expects values in the range of 0..1
288- var rgba = jQuery . makeArray ( pixel ) . map ( function ( v , i ) { return v / 255 } ) ;
289- var wheel = jQuery . farbtastic ( "#color-picker" ) ;
290- wheel . setHSL ( wheel . RGBToHSL ( rgba . slice ( R , A ) ) ) ;
291- // XXX TODO factor in the alpha channel too
292- } );
293- jQuery('#logo-picker-hint').show();
294- }
295247</ script >
296248< %INIT>
297249unless ($session{'CurrentUser'}-> HasRight( Object=> RT-> System, Right => 'SuperUser')) {
0 commit comments