From 8b711c5dca2cbb523c707c7c4477d1208d909850 Mon Sep 17 00:00:00 2001 From: vasanthlmsace Date: Sun, 28 Apr 2024 17:29:51 +0530 Subject: [PATCH] Implemented the Dash-1.14 tasks. --- amd/build/gradient.min.js | 3 + amd/build/gradient.min.js.map | 1 + amd/build/gradienthandler.min.js | 7 + amd/build/lc_color_picker.min.js | 3 + amd/build/lc_color_picker.min.js.map | 1 + amd/build/lc_color_picker.min.map | 1 + amd/src/gradient.js | 3 + amd/src/gradienthandler.js | 7 + amd/src/lc_color_picker.js | 1665 +++++++++++++++++ block_dash.php | 44 +- classes/external.php | 6 +- .../structure/course_category_table.php | 134 -- .../data_source/categories_data_source.php | 93 - .../local/data_source/users_data_source.php | 19 +- edit_form.php | 100 +- form/element-colorpicker.php | 98 + form/gradientpicker.php | 87 + lang/en/block_dash.php | 52 +- lib.php | 31 +- settings.php | 11 +- thirdpartylibs.xml | 7 + version.php | 2 +- 22 files changed, 2115 insertions(+), 260 deletions(-) create mode 100644 amd/build/gradient.min.js create mode 100644 amd/build/gradient.min.js.map create mode 100644 amd/build/gradienthandler.min.js create mode 100644 amd/build/lc_color_picker.min.js create mode 100644 amd/build/lc_color_picker.min.js.map create mode 100644 amd/build/lc_color_picker.min.map create mode 100644 amd/src/gradient.js create mode 100644 amd/src/gradienthandler.js create mode 100644 amd/src/lc_color_picker.js delete mode 100644 classes/local/dash_framework/structure/course_category_table.php delete mode 100644 classes/local/data_source/categories_data_source.php create mode 100644 form/element-colorpicker.php create mode 100644 form/gradientpicker.php diff --git a/amd/build/gradient.min.js b/amd/build/gradient.min.js new file mode 100644 index 0000000..256ff58 --- /dev/null +++ b/amd/build/gradient.min.js @@ -0,0 +1,3 @@ +define("block_dash/gradient",["block_dash/lc_color_picker"],(function(Picker){return Picker})); + +//# sourceMappingURL=gradient.min.js.map \ No newline at end of file diff --git a/amd/build/gradient.min.js.map b/amd/build/gradient.min.js.map new file mode 100644 index 0000000..19c677b --- /dev/null +++ b/amd/build/gradient.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gradient.min.js","sources":["../src/gradient.js"],"sourcesContent":["define(['block_dash/lc_color_picker'], function(Picker) {\r\n return Picker;\r\n});"],"names":["define","Picker"],"mappings":"AAAAA,6BAAO,CAAC,+BAA+B,SAASC,eACrCA"} \ No newline at end of file diff --git a/amd/build/gradienthandler.min.js b/amd/build/gradienthandler.min.js new file mode 100644 index 0000000..e66779c --- /dev/null +++ b/amd/build/gradienthandler.min.js @@ -0,0 +1,7 @@ +define(['jquery', 'core/str'], function (jQuery) { + return { + init: function() { + alert('demo'); + } + } +}); \ No newline at end of file diff --git a/amd/build/lc_color_picker.min.js b/amd/build/lc_color_picker.min.js new file mode 100644 index 0000000..b790737 --- /dev/null +++ b/amd/build/lc_color_picker.min.js @@ -0,0 +1,3 @@ +var global,factory;global=window,factory=function(){if(void 0!==window.lc_color_picker)return!1;let debounced_vars=[],window_width=null,style_generated=null,active_trigger=null,active_trig_id=null,active_solid=null,active_opacity=null,active_gradient=null,active_mode="linear-gradient",sel_grad_step=0,gradient_data={deg:0,radial_circle:!1,steps:[]};const def_opts={modes:["linear-gradient"],open_on_focus:!0,transparency:!0,dark_theme:!1,no_input_mode:!1,wrap_width:"auto",preview_style:{input_padding:35,side:"right",width:30,separator_color:"#ccc"},fallback_colors:["#008080","linear-gradient(90deg, #fff 0%, #000 100%)"],on_change:null,labels:["click to change color","Solid","Linear Gradient","Radial Gradient","add gradient step","gradient angle","gradient shape","color","opacity"]},right_input_selector='input:not([type="color"])',lccp_ivc_event=function(picker_id){let hide_picker=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return new CustomEvent("lccp_input_val_check",{bubbles:!0,detail:{picker_id:picker_id,hide_picker:hide_picker}})};document.addEventListener("click",(function(e){const picker=document.querySelector("#lc-color-picker.lccp-shown");if(!picker||e.target.classList.contains("lccp-preview"))return!0;for(const trigger of document.getElementsByClassName("lccp-preview"))if(trigger.contains(e.target))return!0;if(e.target.parentNode&&e.target.parentNode.classList&&e.target.parentNode.classList.contains("lccp-el-wrap")&&document.getElementById(active_trig_id))return!0;if(!picker.contains(e.target)&&!e.target.classList.contains("lccp-shown")){const picker_id=picker.getAttribute("data-trigger-id");document.getElementById(picker_id).parentNode.querySelector(right_input_selector).dispatchEvent(lccp_ivc_event(picker_id,!0))}return!0})),window.addEventListener("resize",(function(e){const picker=document.querySelector("#lc-color-picker.lccp-shown");if(!picker||window_width==window.innerWidth)return!0;const picker_id=picker.getAttribute("data-trigger-id");document.getElementById(picker_id).parentNode.querySelector(right_input_selector).dispatchEvent(lccp_ivc_event(picker_id,!0))})),String.prototype.lccpReplaceArray=function(find,replace){let replaceString=this;for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};if(this.attachTo=attachTo,!this.attachTo)return console.error("You must provide a valid selector string first argument");if("object"!=typeof options)return console.error("Options must be an object");const bkp_opts=options;options=Object.assign({},def_opts,options),void 0!==bkp_opts.preview_style&&(options.preview_style=Object.assign({},def_opts.preview_style,bkp_opts.preview_style)),this.init=function(){const $this=this;style_generated||(this.generate_style(),style_generated=!0),maybe_querySelectorAll(attachTo).forEach((function(el){"INPUT"==el.tagName&&"text"!=el.getAttribute("type")||el.parentNode.classList.length&&el.parentNode.classList.contains("lcslt_wrap")||$this.wrap_element(el)}))},this.wrap_element=function(el){cp_uniqid=Math.random().toString(36).substr(2,9);const $this=this,side_prop="right"==options.preview_style.side?"borderRightWidth":"borderLeftWidth";let trigger_css="width:"+(options.no_input_mode?"calc(100% - "+parseInt(getComputedStyle(el).borderRightWidth,10)+"px - "+parseInt(getComputedStyle(el).borderLeftWidth,10)+"px);":options.preview_style.width+"px;")+options.preview_style.side+":"+parseInt(getComputedStyle(el)[side_prop],10)+"px;top:"+parseInt(getComputedStyle(el).borderTopWidth,10)+"px;height: calc(100% - "+parseInt(getComputedStyle(el).borderTopWidth,10)+"px - "+parseInt(getComputedStyle(el).borderBottomWidth,10)+"px);",trigger_upper_css=trigger_css+"background:"+el.value+";border-color:"+options.preview_style.separator_color+";",div=document.createElement("div");div.className="lccp-preview-"+options.preview_style.side,div.setAttribute("data-for",el.getAttribute("name")),"auto"!=options.wrap_width&&(div.style.width="inherit"==options.wrap_width?Math.round(el.getBoundingClientRect().width)+"px":options.wrap_width);const direct_colorpicker_code=options.transparency||1!=options.modes.length||"linear-gradient"!=options.modes[0]?"":'';div.classList.add("lccp-el-wrap"),div.innerHTML=''+direct_colorpicker_code,el.parentNode.insertBefore(div,el),div.appendChild(el),options.no_input_mode||("right"==options.preview_style.side?div.querySelector('input:not([type="color"])').style.paddingRight=options.preview_style.input_padding+"px":div.querySelector('input:not([type="color"])').style.paddingLeft=options.preview_style.input_padding+"px"),div.querySelector(".lccp-direct-cp-f")&&div.querySelector(".lccp-direct-cp-f").addEventListener("input",(e=>{div.querySelector('input:not([type="color"])').value=e.target.value,div.querySelector(".lccp-preview").style.background=e.target.value}));const trigger=document.getElementById(cp_uniqid);trigger.addEventListener("click",(e=>{this.show_picker(trigger)})),options.open_on_focus&&div.querySelector(right_input_selector).addEventListener("focus",(e=>{trigger!=active_trigger&&(active_trigger&&(document.getElementById("lc-color-picker").classList.remove("lccp-shown"),active_trigger=null),$this.debounce("open_on_focus",10,"show_picker",trigger))})),div.querySelector(right_input_selector).addEventListener("keyup",(e=>{if(9==e.keyCode||"Enter"===e.key||13===e.keyCode)return;const is_active_trigger_and_opened=!!(active_trig_id=cp_uniqid&&document.querySelector("#lc-color-picker.lccp-shown"));active_trigger=trigger,active_trig_id=cp_uniqid,$this.debounce("manual_input_sync",10,"val_to_picker",!0),is_active_trigger_and_opened&&($this.debounce("manual_input_sync_cp",10,"append_color_picker",!1),$this.debounce("reopen_picker_after_manual_edit",10,"show_picker",trigger))})),div.querySelector(right_input_selector).addEventListener("focusout",(e=>{if("BODY"==document.activeElement.tagName&&document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id="'+active_trig_id+'"]'))return!0;e.target.dispatchEvent(lccp_ivc_event(active_trig_id,!0))})),div.querySelector(right_input_selector).addEventListener("lccp_input_val_check",(e=>{const curr_val=e.target.value,test=document.createElement("div");test.style.background=curr_val;let val_to_set,browser_val=test.style.background;curr_val.trim().length&&browser_val?(browser_val=browser_val.replaceAll("0.",".").replace(/rgb\([^\)]+\)/g,(rgb=>$this.RGB_to_hex(rgb))),val_to_set="rgb("==browser_val.trim().toLowerCase().substr(0,4)?$this.RGB_to_hex(browser_val):browser_val):val_to_set=-1===e.target.value.toLowerCase().indexOf("gradient")?-1===options.fallback_colors[0].toLowerCase().indexOf("rgba")?$this.RGB_to_hex(options.fallback_colors[0]):options.fallback_colors[0]:options.fallback_colors[1],val_to_set!=curr_val&&(e.target.value=val_to_set),"function"==typeof options.on_change&&last_tracked_col!=val_to_set&&options.on_change.call($this,val_to_set,e.target),e.detail.picker_id==active_trig_id&&(active_trigger=null,active_trig_id=null);const $target=document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id="'+e.detail.picker_id+'"]');$target&&($target.classList.remove("lccp-shown"),document.getElementById("lc-color-picker").remove())}))},this.show_picker=function(trigger){if(document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id="'+active_trig_id+'"]'))return document.getElementById("lc-color-picker").remove(),active_trigger=null,active_trig_id=null,!1;const direct_colorpicker=trigger.parentNode.querySelector(".lccp-direct-cp-f");if(direct_colorpicker&&(!options.open_on_focus||options.open_on_focus&&!navigator.userAgent.toLowerCase().includes("firefox")))return direct_colorpicker.value=active_solid,direct_colorpicker.click(),!0;window_width=window.innerWidth,active_trigger=trigger,active_trig_id=cp_uniqid,this.val_to_picker(),this.append_color_picker();const picker=document.getElementById("lc-color-picker"),picker_w=picker.offsetWidth,picker_h=picker.offsetHeight,at_offsety=active_trigger.getBoundingClientRect(),at_h=parseInt(active_trigger.clientHeight,10)+parseInt(getComputedStyle(active_trigger).borderTopWidth,10)+parseInt(getComputedStyle(active_trigger).borderBottomWidth,10),y_pos=parseInt(at_offsety.y,10)+parseInt(window.pageYOffset,10)+at_h+5;let left=parseInt(at_offsety.right,10)-picker_w;left<0&&(left=0),window.innerWidth<700&&(left=Math.floor((window.innerWidth-picker_w)/2));const y_pos_css=y_pos+picker_h-document.documentElement.scrollTop=6&&hex[0]===hex[1]&&hex[2]===hex[3]&&hex[4]===hex[5]?"#"+hex[0]+hex[2]+hex[4]:"#"+hex.join("")},this.short_hex_fix=function(hex){if(4==hex.length){const a=hex.split("");hex=a[0]+a[1]+a[1]+a[2]+a[2]+a[3]+a[3]}return hex.toLowerCase()},this.hex_to_RGB=function(h){let r=0,g=0,b=0;return 4==h.length?(r="0x"+h[1]+h[1],g="0x"+h[2]+h[2],b="0x"+h[3]+h[3]):7==h.length&&(r="0x"+h[1]+h[2],g="0x"+h[3]+h[4],b="0x"+h[5]+h[6]),"rgb("+ +r+", "+ +g+", "+ +b+")"},this.hex_to_RGBA=function(h,opacity){return 1===parseFloat(opacity)?this.shorten_hex(h):this.hex_to_RGB(h).replace("(","a(").replace(")",", "+opacity.toString().replace("0.",".")+")")},this.append_color_picker=function(){let on_manual_input_change=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const $this=this,theme_class=options.dark_theme?"lccp_dark_theme":"lccp_light_theme",shown_solid="solid"==active_mode?active_solid:gradient_data.steps[0].color,shown_opacity="solid"==active_mode?active_opacity:options.transparency?gradient_data.steps[0].opacity:null,print_grad_code=-1!==options.modes.indexOf("linear-gradient")||-1!==options.modes.indexOf("radial-gradient");let picker_el,picker="";if(on_manual_input_change&&document.getElementById("lc-color-picker")?(picker_el=document.getElementById("lc-color-picker"),picker_el.setAttribute("data-mode",active_mode),picker_el.setAttribute("data-trigger-id",cp_uniqid)):picker='
',print_grad_code&&(picker+=`\n
\n
\n
\n\n
\n\n
\n angle\n\n \n \n
\n
\n shape\n\n Ellipse\n Circle\n
\n
\n
`),picker+=`\n
\n color\n\n
\n \n
\n \n
`,options.transparency&&(picker+=`\n
\n opacity\n\n \n \n
`),on_manual_input_change&&document.getElementById("lc-color-picker")?picker_el.innerHTML=picker:document.body.insertAdjacentHTML("beforeend",picker+"
"),options.modes.length>=1)for(const mode of document.querySelectorAll("#lccp_modes_wrap span"))mode.addEventListener("click",(e=>{$this.mode_change(e.target,e.target.getAttribute("data-mode"))}));if(print_grad_code&&(gradient_data.steps.some((function(step,index){$this.add_draggable_element(index,step.position,step.color)})),document.querySelector(".lccp_gradient:not(.lccp_gradient-bg)").addEventListener("click",(e=>{this.add_gradient_step(e)}))),-1!==options.modes.indexOf("linear-gradient")&&(document.querySelector(".pccp_deg_f_wrap input[type=range]").addEventListener("input",(e=>{this.track_deg_range_change(e)})),document.querySelector(".pccp_deg_f_wrap input[name=deg-num]").addEventListener("change",(e=>{this.track_deg_num_change(e)})),document.querySelector(".pccp_deg_f_wrap input[name=deg-num]").addEventListener("keyup",(e=>{this.debounce("deg_f_change",500,"track_deg_num_change",e)}))),-1!==options.modes.indexOf("radial-gradient"))for(const mode of document.querySelectorAll(".pccp_circle_f_wrap span"))mode.addEventListener("click",(e=>{$this.set_ellipse_circle(e.target,e.target.getAttribute("data-val"))}));document.querySelector('.pccp_color_f_wrap input[type="color"]').addEventListener("input",(e=>{this.track_color_change(e)})),document.querySelector('.pccp_color_f_wrap input[type="color"]').addEventListener("change",(e=>{this.track_color_change(e)})),document.querySelector(".pccp_color_f_wrap input[name=hex]").addEventListener("keyup",(e=>{this.debounce("hex_f_change",600,"track_color_hex_change",e)})),options.transparency&&(document.querySelector(".pccp_opacity_f_wrap input[type=range]").addEventListener("input",(e=>{this.track_opacity_range_change(e)})),document.querySelector(".pccp_opacity_f_wrap input[name=opacity-num]").addEventListener("change",(e=>{this.track_opacity_num_change(e)})),document.querySelector(".pccp_opacity_f_wrap input[name=opacity-num]").addEventListener("keyup",(e=>{this.debounce("opacity_f_change",500,"track_opacity_num_change",e)})))},this.add_draggable_element=function(rel_step_num,position,color){const $this=this,container=document.querySelector(".lccp_gradient_ranges"),sel_class=rel_step_num?"":"lccp_sel_step",del_btn_vis=gradient_data.steps.length>2?"":'style="display: none;"';container.innerHTML+='";let active=!1;const dragStart=function(range_id,el,e){active=range_id},dragEnd=function(){active=!1,$this.apply_changes()},drag=function(range_id,range,e){if(!1!==active&&range_id==active){e.preventDefault();const rect=container.getBoundingClientRect();let new_pos="touchmove"===e.type?e.touches[0].clientX-rect.left:e.clientX-rect.left;new_pos=Math.round(100*new_pos/container.offsetWidth),new_pos<0?new_pos=0:new_pos>100&&(new_pos=100);const min_pos=range_id?gradient_data.steps[range_id-1].position:0,max_pos=range_id==gradient_data.steps.length-1?100:gradient_data.steps[range_id+1].position;new_posmax_pos&&(new_pos=max_pos-1),gradient_data.steps[range_id].position=new_pos,range.style.left=new_pos+"%",$this.apply_gradient_changes()}};document.querySelectorAll(".lccp_gradient_range").forEach((range=>{const step_num=parseInt(range.getAttribute("data-step-num"),10);range.removeEventListener("touchstart",null),range.removeEventListener("touchend",null),range.removeEventListener("touchmove",null),range.removeEventListener("click",null),range.removeEventListener("mousedown",null),range.removeEventListener("mouseup",null),range.addEventListener("touchstart",(e=>{dragStart(step_num,e.target)})),range.addEventListener("mousedown",(e=>{dragStart(step_num,e.target)})),range.addEventListener("click",(e=>{$this.select_gradient_color(step_num)})),container.addEventListener("touchmove",(e=>{drag(step_num,range,e)})),container.addEventListener("mousemove",(e=>{drag(step_num,range,e)})),range.addEventListener("mouseup",(e=>{dragEnd()})),range.addEventListener("touchend",(e=>{dragEnd()})),document.addEventListener("mouseup",(e=>{dragEnd()}))})),document.querySelectorAll(".lccp_gradient_range img").forEach((btn=>{btn.addEventListener("click",(e=>{if(document.querySelectorAll(".lccp_gradient_range").length<3)return!1;setTimeout((()=>{const parent=e.target.parentNode,step_num=parseInt(parent.getAttribute("data-step-num"),10),to_select=step_num?step_num-1:0;gradient_data.steps.splice(step_num,1),document.querySelectorAll(".lccp_gradient_range").forEach((r=>r.remove())),gradient_data.steps.some((function(step,index){$this.add_draggable_element(index,step.position,step.color)})),document.querySelector('.lccp_gradient_range[data-step-num="'+to_select+'"]').click(),this.apply_gradient_changes(!0)}),20)}))}))},this.select_gradient_color=function(step_num){sel_grad_step=step_num,document.querySelectorAll(".lccp_gradient_range").forEach((m=>m.classList.remove("lccp_sel_step"))),document.querySelector('.lccp_gradient_range[data-step-num="'+step_num+'"]').classList.add("lccp_sel_step"),active_solid=gradient_data.steps[step_num].color,active_opacity=gradient_data.steps[step_num].opacity,document.querySelector('#lc-color-picker input[type="color"]').value=active_solid,document.querySelector(".pccp_color_f_wrap input[name=hex]").value=active_solid,options.transparency&&(document.querySelector(".pccp_opacity_f_wrap input[type=range]").value=active_opacity,document.querySelector(".pccp_opacity_f_wrap input[name=opacity-num]").value=active_opacity)},this.apply_gradient_changes=function(also_apply_changes){const $this=this;let new_gradient=active_mode+"(";new_gradient+="linear-gradient"==active_mode?gradient_data.deg+"deg":gradient_data.radial_circle?"circle":"ellipse",new_gradient+=", ";let colors_part=[];gradient_data.steps.some((function(step,index){let to_add=options.transparency?$this.hex_to_RGBA(step.color,step.opacity):$this.shorten_hex(step.color);(gradient_data.steps.length>2||gradient_data.steps.length<=2&&(!index&&parseInt(step.position,10)||index&&index{options.on_change.call(this,val,field)}),300)))},this.mode_change=function(el,new_mode){if(active_mode==new_mode)return!1;let color,opacity;"solid"==new_mode?(color=active_solid,options.transparency&&(opacity=active_opacity)):(color=gradient_data.steps[0].color,options.transparency&&(opacity=gradient_data.steps[0].opacity)),document.querySelector('#lc-color-picker input[type="color"]').value=color,document.querySelector(".pccp_color_f_wrap input[name=hex]").value=color,options.transparency&&(document.querySelector(".pccp_opacity_f_wrap input[type=range]").value=opacity,document.querySelector(".pccp_opacity_f_wrap input[name=opacity-num]").value=opacity),options.modes.length>=1&&(document.querySelector(".pccp_deg_f_wrap").style.display="linear-gradient"==new_mode?"flex":"none",document.querySelector(".pccp_circle_f_wrap").style.display="radial-gradient"==new_mode?"block":"none"),-1===options.modes.indexOf("linear-gradient")&&-1===options.modes.indexOf("radial-gradient")||(document.querySelector(".lccp_gradient_wizard").style.display="solid"!=new_mode?"block":"none"),document.querySelectorAll("#lccp_modes_wrap span").forEach((m=>m.classList.remove("lccp_sel_mode"))),el.classList.add("lccp_sel_mode"),active_mode=new_mode,"solid"==new_mode?this.apply_changes():this.apply_gradient_changes(!0)},this.add_gradient_step=function(e){const $this=this,pos=Math.round(100*e.layerX/e.target.offsetWidth);let index=0;for(let step of gradient_data.steps){if(step.position>pos){const step_data={color:index-1<0?step.color:gradient_data.steps[index-1].color,opacity:1,position:pos};gradient_data.steps.splice(index,0,step_data);break}index++}document.querySelectorAll(".lccp_gradient_range").forEach((r=>r.remove())),gradient_data.steps.some((function(step,index){$this.add_draggable_element(index,step.position,step.color)})),document.querySelector('.lccp_gradient_range[data-step-num="'+index+'"]').click(),this.apply_gradient_changes(!0)},this.set_ellipse_circle=function(el,new_opt){if(gradient_data.radial_circle&&"circle"==new_opt||!gradient_data.radial_circle&&"circle"!=new_opt)return!1;gradient_data.radial_circle=!gradient_data.radial_circle,document.querySelectorAll(".pccp_circle_f_wrap span").forEach((m=>m.classList.remove("pcpp_circle_btn_active"))),el.classList.add("pcpp_circle_btn_active"),this.apply_gradient_changes(!0)},this.track_deg_range_change=function(e){document.querySelector(".pccp_deg_f_wrap input[name=deg-num]").value=e.target.value,gradient_data.deg=e.target.value,this.apply_gradient_changes(!0)},this.track_deg_num_change=function(e){let val=parseFloat(e.target.value);(isNaN(val)||val<0||val>360)&&(val=90),e.target.value=val,document.querySelector(".pccp_deg_f_wrap input[type=range]")&&(document.querySelector(".pccp_deg_f_wrap input[type=range]").value=val),gradient_data.deg=val,this.apply_gradient_changes(!0)},this.track_color_change=function(e){const val=e.target.value.toLowerCase();document.querySelector(".pccp_color_f_wrap input[name=hex]").value=val,this.apply_color_change(val)},this.track_color_hex_change=function(e){let val=this.short_hex_fix(e.target.value);null===val.match(/^#[a-f0-9]{6}$/i)&&(val=active_solid.toLowerCase()),e.target.value=val,document.querySelector('#lc-color-picker input[type="color"]').value=val,this.apply_color_change(val)},this.apply_color_change=function(val){"solid"==active_mode?(active_solid=val,this.apply_changes()):(gradient_data.steps[sel_grad_step].color=val,document.querySelector(".lccp_sel_step").style.background=val,this.apply_gradient_changes(!0))},this.track_opacity_range_change=function(e){document.querySelector(".pccp_opacity_f_wrap input[name=opacity-num]").value=e.target.value,this.alter_hex_opacity(e.target.value)},this.track_opacity_num_change=function(e){let val=parseFloat(e.target.value);(isNaN(val)||val<0||val>1)&&(val=.5),e.target.value=val,document.querySelector(".pccp_opacity_f_wrap input[type=range]")&&(document.querySelector(".pccp_opacity_f_wrap input[type=range]").value=val,this.alter_hex_opacity(val))},this.alter_hex_opacity=function(opacity){document.querySelector('#lc-color-picker input[type="color"]').style.opacity=opacity,"solid"==active_mode?(active_opacity=opacity,this.apply_changes()):(gradient_data.steps[sel_grad_step].opacity=opacity,this.apply_gradient_changes(!0))},this.debounce=function(action_name,timing,cb_function,cb_params){void 0!==debounced_vars[action_name]&&debounced_vars[action_name]&&clearTimeout(debounced_vars[action_name]);const $this=this;debounced_vars[action_name]=setTimeout((()=>{$this[cb_function].call($this,cb_params)}),timing)},this.generate_style=function(){document.head.insertAdjacentHTML("beforeend",'')},this.init()};const maybe_querySelectorAll=selector=>{if("string"!=typeof selector){if(selector instanceof Element)return[selector];{let to_return=[];for(const obj of selector)obj instanceof Element&&to_return.push(obj);return to_return}}return(selector.match(/(#[0-9][^\s:,]*)/g)||[]).forEach((function(n){selector=selector.replace(n,'[id="'+n.replace("#","")+'"]')})),document.querySelectorAll(selector)}}(),"object"==typeof exports&&"undefined"!=typeof module?module.exports=factory():"function"==typeof define&&define.amd?define("block_dash/lc_color_picker",factory):(global="undefined"!=typeof globalThis?globalThis:global||self).Chart=factory(); + +//# sourceMappingURL=lc_color_picker.min.js.map \ No newline at end of file diff --git a/amd/build/lc_color_picker.min.js.map b/amd/build/lc_color_picker.min.js.map new file mode 100644 index 0000000..7a07ed6 --- /dev/null +++ b/amd/build/lc_color_picker.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"lc_color_picker.min.js","sources":["../src/lc_color_picker.js"],"sourcesContent":["/**\n * lc_color_picker.js - The colorpicker for modern web\n * Version: 2.0.0\n * Author: Luca Montanari (LCweb)\n * Website: https://lcweb.it\n * Licensed under the MIT license\n */\n\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chart = factory());\n })(this, (function () { 'use strict';\n\n if(typeof(window.lc_color_picker) != 'undefined') {return false;} // prevent multiple script inits\n\n\n /*** vars ***/\n let debounced_vars = [],\n window_width = null,\n\n style_generated = null,\n active_trigger = null,\n active_trig_id = null,\n\n active_solid = null,\n active_opacity = null,\n active_gradient = null,\n active_mode = 'linear-gradient',\n\n sel_grad_step = 0, // selected gradient step\n gradient_data = {\n deg: 0,\n radial_circle: false,\n steps: [\n //{color : null, opacity: null, position : null}\n ],\n };\n\n\n /*** default options ***/\n const def_opts = {\n modes : ['linear-gradient'], // (array) containing supported modes (solid | linear-gradient | radial-gradient)\n open_on_focus : true, // (bool) whether to open the picker when field is focused\n transparency : true, // (bool) whether to allow colors transparency tune\n dark_theme : false, // (bool) whether to enable dark picker theme\n no_input_mode : false, // (bool) whether to stretch the trigger in order to cover the whole input field\n wrap_width : 'auto', // (string) defines the wrapper width. \"auto\" to leave it up to CSS, \"inherit\" to statically copy input field width, or any other CSS sizing\n preview_style : { // (object) defining shape and position of the in-field preview\n input_padding : 35, // extra px padding eventually added to the target input to not cover text\n side : 'right', // right or left\n width : 30,\n separator_color : '#ccc', // (string) CSS color applird to preview element as separator\n },\n fallback_colors : ['#008080', 'linear-gradient(90deg, #fff 0%, #000 100%)'], // (array) defining default colors used when trigger field has no value. First parameter for solid color, second for gradient\n\n on_change : null, // function(new_value, target_field) {}, - triggered every time field value changes. Passes value and target field object as parameters\n\n labels : [ // (array) option used to translate script texts\n 'click to change color',\n 'Solid',\n 'Linear Gradient',\n 'Radial Gradient',\n 'add gradient step',\n 'gradient angle',\n 'gradient shape',\n 'color',\n 'opacity',\n ],\n };\n\n\n // shortcut var to target the text input only\n const right_input_selector = 'input:not([type=\"color\"])';\n\n\n\n // input value check custom event\n const lccp_ivc_event = function(picker_id, hide_picker = false) {\n return new CustomEvent('lccp_input_val_check', {\n bubbles : true,\n detail: {\n picker_id : picker_id,\n hide_picker : hide_picker\n }\n });\n };\n\n\n\n /*** hide picker cicking outside ***/\n document.addEventListener('click', function(e) {\n const picker = document.querySelector(\"#lc-color-picker.lccp-shown\");\n if(!picker || e.target.classList.contains('lccp-preview')) {\n return true;\n }\n\n // is an element within a trigger?\n for (const trigger of document.getElementsByClassName('lccp-preview')) {\n if(trigger.contains(e.target)) {\n return true;\n }\n }\n\n // clicked on the same colorpicker field? keep visible\n if(e.target.parentNode && e.target.parentNode.classList && e.target.parentNode.classList.contains('lccp-el-wrap') && document.getElementById(active_trig_id)) {\n return true;\n }\n\n // close if clicked element is not in the picker\n if(!picker.contains(e.target) && !e.target.classList.contains('lccp-shown')) {\n const picker_id = picker.getAttribute('data-trigger-id'),\n $input = document.getElementById(picker_id).parentNode.querySelector(right_input_selector);\n\n $input.dispatchEvent(lccp_ivc_event(picker_id, true));\n }\n return true;\n });\n\n\n /* hide picker on screen resizing */\n window.addEventListener('resize', function(e) {\n const picker = document.querySelector(\"#lc-color-picker.lccp-shown\");\n if(!picker || window_width == window.innerWidth) {\n return true;\n }\n\n // check field value\n const picker_id = picker.getAttribute('data-trigger-id'),\n $input = document.getElementById(picker_id).parentNode.querySelector(right_input_selector);\n\n $input.dispatchEvent(lccp_ivc_event(picker_id, true));\n });\n\n\n /* extend string object to ReplaceArray */\n String.prototype.lccpReplaceArray = function(find, replace) {\n let replaceString = this;\n let regex;\n\n for (var i = 0; i < find.length; i++) {\n const regex = new RegExp(find[i], \"g\");\n replaceString = (typeof(replace) == 'object') ? replaceString.replace(regex, replace[i]) : replaceString.replace(regex, replace);\n }\n return replaceString;\n };\n\n\n\n\n /*** plugin class ***/\n window.lc_color_picker = function(attachTo, options = {}) {\n let cp_uniqid, // unique ID assigned to this colorpicker instance\n last_tracked_col;\n\n this.attachTo = attachTo;\n if(!this.attachTo) {\n return console.error('You must provide a valid selector string first argument');\n }\n\n // override options\n if(typeof(options) != 'object') {\n return console.error('Options must be an object');\n }\n\n const bkp_opts = options;\n options = Object.assign({}, def_opts, options);\n\n if(typeof(bkp_opts.preview_style) != 'undefined') {\n options.preview_style = Object.assign({}, def_opts.preview_style, bkp_opts.preview_style);\n }\n\n\n\n /* initialize */\n this.init = function() {\n const $this = this;\n\n // Generate style\n if(!style_generated) {\n this.generate_style();\n style_generated = true;\n }\n\n\n // assign to each target element\n maybe_querySelectorAll(attachTo).forEach(function(el) {\n if(el.tagName == 'INPUT' && el.getAttribute('type') != 'text') {\n return;\n }\n\n // do not initialize twice\n if(el.parentNode.classList.length && el.parentNode.classList.contains('lcslt_wrap')) {\n return;\n }\n\n $this.wrap_element(el);\n });\n };\n\n\n\n /* wrap target element to allow trigger display */\n this.wrap_element = function(el) {\n cp_uniqid = Math.random().toString(36).substr(2, 9);\n\n const $this = this,\n side_prop = (options.preview_style.side == 'right') ? 'borderRightWidth' : 'borderLeftWidth';\n\n let trigger_css =\n `width:${ (options.no_input_mode) ? 'calc(100% - '+ parseInt(getComputedStyle(el)['borderRightWidth'], 10) +'px - '+ parseInt(getComputedStyle(el)['borderLeftWidth'], 10) +'px);' : options.preview_style.width +'px;'}` +\n\n options.preview_style.side +':'+ parseInt(getComputedStyle(el)[side_prop], 10) +'px;'+\n\n 'top:'+ parseInt(getComputedStyle(el)['borderTopWidth'], 10) +'px;' +\n\n 'height: calc(100% - '+ parseInt(getComputedStyle(el)['borderTopWidth'], 10) +'px - '+ parseInt(getComputedStyle(el)['borderBottomWidth'], 10) +'px);';\n\n let trigger_upper_css =\n trigger_css +\n 'background:'+ el.value +';' +\n 'border-color:'+ options.preview_style.separator_color +';'\n\n let div = document.createElement('div');\n div.className = 'lccp-preview-'+ options.preview_style.side;\n div.setAttribute('data-for', el.getAttribute('name'));\n\n // static width from input?\n if(options.wrap_width != 'auto') {\n div.style.width = (options.wrap_width == 'inherit') ? Math.round(el.getBoundingClientRect().width) + 'px' : options.wrap_width;\n }\n\n const direct_colorpicker_code = (!options.transparency && options.modes.length == 1 && options.modes[0] == 'linear-gradient') ?\n '' : '';\n\n div.classList.add(\"lccp-el-wrap\");\n div.innerHTML =\n '' +\n '' +\n direct_colorpicker_code;\n\n el.parentNode.insertBefore(div, el);\n div.appendChild(el);\n\n // input padding\n if(!options.no_input_mode) {\n if(options.preview_style.side == 'right') {\n div.querySelector('input:not([type=\"color\"])').style.paddingRight = options.preview_style.input_padding +'px';\n } else {\n div.querySelector('input:not([type=\"color\"])').style.paddingLeft = options.preview_style.input_padding +'px';\n }\n }\n\n\n // direct browser colorpicker? track changes\n if(div.querySelector('.lccp-direct-cp-f')) {\n div.querySelector('.lccp-direct-cp-f').addEventListener(\"input\", (e) => {\n\n div.querySelector('input:not([type=\"color\"])').value = e.target.value;\n div.querySelector('.lccp-preview').style.background = e.target.value;\n });\n }\n\n\n // event to show picker\n const trigger = document.getElementById(cp_uniqid);\n trigger.addEventListener(\"click\", (e) => {\n this.show_picker(trigger);\n });\n\n\n\n // show on field focus?\n if(options.open_on_focus) {\n div.querySelector(right_input_selector).addEventListener(\"focus\", (e) => {\n if(trigger != active_trigger) {\n if(active_trigger) {\n document.getElementById('lc-color-picker').classList.remove('lccp-shown');\n active_trigger = null;\n }\n\n $this.debounce('open_on_focus', 10, 'show_picker', trigger);\n }\n });\n }\n\n\n // sync manually-inputed data in the field\n div.querySelector(right_input_selector).addEventListener(\"keyup\", (e) => {\n if(e.keyCode == 9 || e.key === 'Enter' || e.keyCode === 13) {\n return;\n }\n\n const is_active_trigger_and_opened = (active_trig_id = cp_uniqid && document.querySelector(\"#lc-color-picker.lccp-shown\")) ? true : false;\n\n active_trigger = trigger;\n active_trig_id = cp_uniqid;\n\n $this.debounce('manual_input_sync', 10, 'val_to_picker', true);\n\n if(is_active_trigger_and_opened) {\n $this.debounce('manual_input_sync_cp', 10, 'append_color_picker', false);\n $this.debounce('reopen_picker_after_manual_edit', 10, 'show_picker', trigger);\n }\n });\n\n\n // be sure input value is managed on focusout\n div.querySelector(right_input_selector).addEventListener(\"focusout\", (e) => {\n // not if this field's picker is shown and focus is on \"body\"\n if(document.activeElement.tagName == 'BODY' && document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id=\"'+ active_trig_id +'\"]')) {\n return true;\n }\n\n e.target.dispatchEvent(lccp_ivc_event(active_trig_id, true));\n });\n\n\n // custom event - check field validity and eventually use fallback values\n div.querySelector(right_input_selector).addEventListener(\"lccp_input_val_check\", (e) => {\n const curr_val = e.target.value,\n test = document.createElement('div');\n\n test.style.background = curr_val;\n let browser_val = test.style.background,\n val_to_set;\n\n if(!curr_val.trim().length || !browser_val) {\n if(e.target.value.toLowerCase().indexOf('gradient') === -1) {\n val_to_set = (options.fallback_colors[0].toLowerCase().indexOf('rgba') === -1) ? $this.RGB_to_hex(options.fallback_colors[0]) : options.fallback_colors[0];\n }\n else {\n val_to_set = options.fallback_colors[1];\n }\n }\n else {\n // browser already fixes minor things\n browser_val = browser_val.replaceAll('0.', '.').replace(/rgb\\([^\\)]+\\)/g, (rgb) => {\n return $this.RGB_to_hex(rgb);\n });\n\n val_to_set = (browser_val.trim().toLowerCase().substr(0, 4) == 'rgb(') ? $this.RGB_to_hex(browser_val) : browser_val;\n }\n\n if(val_to_set != curr_val) {\n e.target.value = val_to_set;\n }\n\n if(typeof(options.on_change) == 'function' && last_tracked_col != val_to_set) {\n options.on_change.call($this, val_to_set, e.target);\n }\n\n if(e.detail.picker_id == active_trig_id) {\n active_trigger = null;\n active_trig_id = null;\n }\n\n\n // also hide picker?\n const $target = document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id=\"'+ e.detail.picker_id +'\"]');\n if($target) {\n\n $target.classList.remove('lccp-shown');\n document.getElementById(\"lc-color-picker\").remove();\n }\n });\n };\n\n\n\n /* show picker */\n this.show_picker = function(trigger) {\n if(document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id=\"'+ active_trig_id +'\"]')) {\n document.getElementById(\"lc-color-picker\").remove();\n active_trigger = null;\n active_trig_id = null\n\n return false;\n }\n\n // direct colorpicker usage? Not for Firefox is \"show on focus\" is enabled\n const direct_colorpicker = trigger.parentNode.querySelector('.lccp-direct-cp-f');\n if(\n direct_colorpicker &&\n (\n !options.open_on_focus ||\n (options.open_on_focus && !navigator.userAgent.toLowerCase().includes('firefox'))\n )\n ) {\n direct_colorpicker.value = active_solid;\n direct_colorpicker.click();\n return true;\n }\n\n\n window_width = window.innerWidth;\n active_trigger = trigger;\n active_trig_id = cp_uniqid;\n\n this.val_to_picker();\n this.append_color_picker();\n\n const picker = document.getElementById('lc-color-picker'),\n picker_w = picker.offsetWidth,\n picker_h = picker.offsetHeight,\n at_offsety = active_trigger.getBoundingClientRect(),\n at_h = parseInt(active_trigger.clientHeight, 10) + parseInt(getComputedStyle(active_trigger)['borderTopWidth'], 10) + parseInt(getComputedStyle(active_trigger)['borderBottomWidth'], 10),\n y_pos = (parseInt(at_offsety.y, 10) + parseInt(window.pageYOffset, 10) + at_h + 5);\n\n // left pos control - also checking side overflows\n let left = (parseInt(at_offsety.right, 10) - picker_w);\n if(left < 0) {\n left = 0;\n }\n\n // mobile? show it centered\n if(window.innerWidth < 700) {\n left = Math.floor( (window.innerWidth - picker_w) / 2);\n }\n\n // top or bottom ?\n const y_pos_css = (y_pos + picker_h - document.documentElement.scrollTop < window.innerHeight) ?\n 'top:'+ y_pos :\n 'transform: translate3d(0, calc((100% + '+ (active_trigger.offsetHeight + 10) +'px) * -1), 0); top:'+ y_pos;\n\n picker.setAttribute('style', y_pos_css +'px; left: '+ left +'px;');\n picker.classList.add('lccp-shown');\n };\n\n\n\n /* handles input value and prepres data for the picker */\n this.val_to_picker = function(from_manual_input) {\n if(!active_trigger) {\n return false;\n }\n const val = active_trigger.parentNode.querySelector(right_input_selector).value.trim().toLowerCase();\n last_tracked_col = val;\n\n // check validity\n let test = document.createElement('div');\n test.style.background = val;\n\n //// set active colors\n // if no value found\n if(!val.length || !test.style.background.length) {\n active_solid = options.fallback_colors[0];\n active_gradient = options.fallback_colors[1];\n active_mode = 'linear-gradient';\n\n /* if(val.indexOf('linear-gradient') !== -1) {\n }\n else if(val.indexOf('radial-gradient') !== -1) {\n active_mode = 'radial-gradient';\n }\n else {\n active_mode = 'solid';\n } */\n }\n else {\n\n active_mode = 'linear-gradient';\n active_gradient = val;\n // find which value type has been passed\n /* if(val.indexOf('linear-gradient') !== -1) {\n }\n else if(val.indexOf('radial-gradient') !== -1) {\n active_mode = 'radial-gradient';\n }\n else {\n active_mode = 'solid';\n }\n\n if(active_mode == 'solid') {\n active_solid = val;\n active_gradient = options.fallback_colors[1];\n }\n else{\n active_solid = options.fallback_colors[0];\n } */\n }\n active_trigger.style.background = val;\n\n if(!from_manual_input || (from_manual_input && options.open_on_focus)) {\n // elaborate solid color data (color and alpha)\n //this.load_solid_data(active_solid);\n // elaborate gradient data\n if(active_gradient) {\n this.load_gradient_data(active_gradient);\n }\n }\n };\n\n\n\n /* elaborate solid color data (color and alpha) loading into active_solid and active_opacity */\n this.load_solid_data = function(raw_data) {\n active_opacity = 1;\n\n // rgba\n if(raw_data.indexOf('rgba') !== -1) {\n const data = this.RGBA_to_hexA(raw_data);\n active_solid = data[0];\n active_opacity = data[1];\n }\n\n // rgb\n else if(raw_data.indexOf('rgba') !== -1) {\n active_solid = this.RGB_to_hex(raw_data);\n }\n\n // hex\n else {\n active_solid = this.short_hex_fix(raw_data);\n }\n };\n\n\n\n /* elaborate gradient data loading into gradient_data */\n this.load_gradient_data = function(raw_data) {\n const $this = this;\n const is_radial = (raw_data.indexOf('radial-gradient') === -1) ? false : true;\n\n // solve issues with inner RGB|RGBA and turn everything into RGBA\n raw_data = raw_data\n .replace(/,\\./g, ',0.').replace(/ \\./g, ' 0.')\n .replace(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/g, 'rgbaZ($1|$2|$3|$4)')\n .replace(/\\|\\)/g, '|1)');\n\n // names to deg\n raw_data = raw_data\n .replace('top right', '45deg').replace('right top', '45deg')\n .replace('bottom right', '135deg').replace('bottom right', '135deg')\n .replace('top left', '315deg').replace('left top', '315deg')\n .replace('bottom left', '225deg').replace('bottom left', '225deg')\n .replace('right', '90deg').replace('left', '270deg').replace('top', '0deg').replace('bottom', '180deg');\n\n // be sure deg or shape is defined\n if(is_radial && raw_data.indexOf('ellipse') === -1 && raw_data.indexOf('circle') === -1) {\n raw_data.replace('\\\\(', '(ellipse ');\n }\n if(!is_radial && raw_data.indexOf('deg') === -1) {\n raw_data.replace('\\\\(', '(180deg');\n }\n\n // process\n raw_data = raw_data.lccpReplaceArray(\n ['linear-gradient', 'radial-gradient', '', '\\\\(', 'to', '\\\\)'],\n ''\n );\n\n // split steps\n const raw_steps = raw_data.split(',');\n const fallback_multiplier = 100 / raw_steps.length;\n\n gradient_data.steps = [];\n raw_steps.some(function(raw_step, index) {\n\n // direction on first index\n if(!index) {\n if(is_radial) {\n gradient_data.radial_circle = (raw_step.indexOf('circle') === -1) ? false : true;\n } else {\n gradient_data.deg = parseInt(raw_step.replace('deg', ''), 10);\n }\n }\n\n // {color : null, opacity: null, position : null}\n else {\n raw_step = raw_step.trim().split(' ');\n let position = '';\n\n // position\n if(raw_step.length < 2) {\n if(index === 1) {\n position = '0%';\n }\n else if(index == (raw_steps.length - 1)) {\n position = '100%';\n }\n else {\n position = (fallback_multiplier * index) +'%';\n }\n }\n else {\n position = raw_step[1];\n }\n\n // color\n let raw_color = raw_step[0],\n opacity = 1;\n\n // normalize to hex\n if(raw_color.indexOf('rgbaZ') !== -1) {\n const col_arr = $this.RGBA_to_hexA(\n raw_color.replace('rgbaZ', 'rgba').replace(/\\|/g, ',')\n );\n\n raw_color = col_arr[0];\n opacity = col_arr[1];\n }\n\n gradient_data.steps.push({\n color : $this.short_hex_fix(raw_color),\n opacity: opacity,\n position : parseInt(position, 10)\n });\n }\n });\n };\n\n\n\n /* handles RGBA string returning a two elements array: hex and alpha */\n this.RGBA_to_hexA = function(raw_data) {\n raw_data = raw_data.lccpReplaceArray(['rgba', '\\\\(', '\\\\)'], '');\n const rgba_arr = raw_data.split(',')\n\n let alpha = (typeof(rgba_arr[3]) != 'undefined') ? rgba_arr[3] : '1';\n if(alpha.substring(0, 1) == '.') {\n alpha = 0 + alpha;\n }\n rgba_arr.splice(3, 1);\n\n return [\n this.RGB_to_hex('rgb('+ rgba_arr.join(',') +')'),\n parseFloat(alpha)\n ];\n };\n\n\n\n /* convert RGB to hex */\n this.RGB_to_hex = function(rgb) {\n rgb = rgb.lccpReplaceArray(['rgb', '\\\\(', '\\\\)'], '');\n const rgb_arr = rgb.split(',');\n\n if(rgb_arr.length < 3) {\n return '';\n }\n\n let r = parseInt(rgb_arr[0].trim(), 10).toString(16),\n g = parseInt(rgb_arr[1].trim(), 10).toString(16),\n b = parseInt(rgb_arr[2].trim(), 10).toString(16);\n\n if (r.length == 1) {r = \"0\" + r;}\n if (g.length == 1) {g = \"0\" + g;}\n if (b.length == 1) {b = \"0\" + b;}\n\n return this.shorten_hex(r + g + b);\n };\n\n\n\n /* if possible, shortenize hex string */\n this.shorten_hex = function(hex) {\n hex = hex.replace('#', '').split('');\n\n if(hex.length >= 6) {\n if(\n hex[0] === hex[1] &&\n hex[2] === hex[3] &&\n hex[4] === hex[5]\n ) {\n return '#'+ hex[0] + hex[2] + hex[4];\n }\n }\n\n return '#'+ hex.join('');\n };\n\n\n\n /* convert short hex to full format */\n this.short_hex_fix = function(hex) {\n if(hex.length == 4) {\n const a = hex.split('');\n hex = a[0] + a[1] + a[1] + a[2] + a[2] + a[3] + a[3];\n }\n\n return hex.toLowerCase();\n };\n\n\n\n /* convert hex to RGB */\n this.hex_to_RGB = function(h) {\n let r = 0, g = 0, b = 0;\n\n // 3 digits\n if (h.length == 4) {\n r = \"0x\" + h[1] + h[1];\n g = \"0x\" + h[2] + h[2];\n b = \"0x\" + h[3] + h[3];\n\n // 6 digits\n } else if (h.length == 7) {\n r = \"0x\" + h[1] + h[2];\n g = \"0x\" + h[3] + h[4];\n b = \"0x\" + h[5] + h[6];\n }\n\n return \"rgb(\"+ +r + \", \" + +g + \", \" + +b + \")\";\n };\n\n\n\n /* convert hex to RGB */\n this.hex_to_RGBA = function(h, opacity) {\n if(parseFloat(opacity) === 1) {\n return this.shorten_hex(h);\n }\n\n let rgb = this.hex_to_RGB(h);\n return rgb.replace('(', 'a(').replace(')', ', '+ opacity.toString().replace('0.', '.') +')');\n };\n\n\n\n\n /* append color container picker to the body */\n this.append_color_picker = function(on_manual_input_change = false) {\n const $this = this;\n\n /* if(document.getElementById(\"lc-color-picker\") && !on_manual_input_change) {\n document.getElementById(\"lc-color-picker\").remove();\n } */\n\n const theme_class = (options.dark_theme) ? 'lccp_dark_theme' : 'lccp_light_theme',\n bg = (active_mode == 'solid') ? active_solid : active_gradient,\n shown_solid = (active_mode == 'solid') ? active_solid : gradient_data.steps[0].color,\n shown_opacity = (active_mode == 'solid') ? active_opacity : (options.transparency) ? gradient_data.steps[0].opacity : null,\n print_grad_code = (options.modes.indexOf('linear-gradient') !== -1 || options.modes.indexOf('radial-gradient') !== -1) ? true : false;\n\n\n // start code\n let picker = '',\n picker_el;\n\n if(on_manual_input_change && document.getElementById(\"lc-color-picker\")) {\n picker_el = document.getElementById(\"lc-color-picker\");\n picker_el.setAttribute('data-mode', active_mode);\n picker_el.setAttribute('data-trigger-id', cp_uniqid);\n }\n else {\n picker = '
';\n }\n\n\n // modes select\n /* if(options.modes.length >= 1) {\n picker += `\n
\n ${ options.labels[1] }\n ${ options.labels[2] }\n ${ options.labels[3] }\n
`;\n } */\n\n\n // gradient wizard\n if(print_grad_code) {\n picker += `\n
\n
\n
\n\n
\n\n
\n \"angle\"\n\n \n \n
\n
\n \"shape\"\n\n Ellipse\n Circle\n
\n
\n
`;\n }\n\n\n // HTML5 colorpicker\n picker += `\n
\n \"color\"\n\n
\n \n
\n \n
`;\n\n // opacity cursor\n if(options.transparency) {\n picker += `\n
\n \"opacity\"\n\n \n \n
`;\n }\n\n\n // append or re-fill\n (on_manual_input_change && document.getElementById(\"lc-color-picker\")) ? picker_el.innerHTML = picker : document.body.insertAdjacentHTML('beforeend', picker +'
');\n\n\n // modes change\n if(options.modes.length >= 1) {\n for (const mode of document.querySelectorAll('#lccp_modes_wrap span')) {\n mode.addEventListener(\"click\", (e) => { $this.mode_change( e.target, e.target.getAttribute('data-mode')) });\n }\n }\n\n // print steps and add gradient step action\n if(print_grad_code) {\n gradient_data.steps.some(function(step, index) {\n $this.add_draggable_element(index, step.position, step.color);\n });\n\n document.querySelector('.lccp_gradient:not(.lccp_gradient-bg)').addEventListener(\"click\", (e) => {this.add_gradient_step(e) });\n }\n\n // angle actions\n if(options.modes.indexOf('linear-gradient') !== -1) {\n document.querySelector('.pccp_deg_f_wrap input[type=range]').addEventListener(\"input\", (e) => {this.track_deg_range_change(e)});\n document.querySelector('.pccp_deg_f_wrap input[name=deg-num]').addEventListener(\"change\", (e) => {this.track_deg_num_change(e)});\n document.querySelector('.pccp_deg_f_wrap input[name=deg-num]').addEventListener(\"keyup\", (e) => {\n this.debounce('deg_f_change', 500, 'track_deg_num_change', e);\n });\n }\n\n // circle actions\n if(options.modes.indexOf('radial-gradient') !== -1) {\n for (const mode of document.querySelectorAll('.pccp_circle_f_wrap span')) {\n mode.addEventListener(\"click\", (e) => { $this.set_ellipse_circle( e.target, e.target.getAttribute('data-val')) });\n }\n }\n\n // color actions\n document.querySelector('.pccp_color_f_wrap input[type=\"color\"]').addEventListener(\"input\", (e) => {this.track_color_change(e)});\n document.querySelector('.pccp_color_f_wrap input[type=\"color\"]').addEventListener(\"change\", (e) => {this.track_color_change(e)});\n document.querySelector('.pccp_color_f_wrap input[name=hex]').addEventListener(\"keyup\", (e) => {\n this.debounce('hex_f_change', 600, 'track_color_hex_change', e);\n });\n\n // transparency actions\n if(options.transparency) {\n document.querySelector('.pccp_opacity_f_wrap input[type=range]').addEventListener(\"input\", (e) => {this.track_opacity_range_change(e)});\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').addEventListener(\"change\", (e) => {this.track_opacity_num_change(e)});\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').addEventListener(\"keyup\", (e) => {\n this.debounce('opacity_f_change', 500, 'track_opacity_num_change', e);\n });\n }\n };\n\n\n\n /*** add draggable element ***/\n this.add_draggable_element = function(rel_step_num, position, color) {\n const $this = this,\n container = document.querySelector('.lccp_gradient_ranges'),\n sel_class = (!rel_step_num) ? 'lccp_sel_step' : '',\n del_btn_vis = (gradient_data.steps.length > 2) ? '' : 'style=\"display: none;\"'\n\n container.innerHTML +=\n ''+\n ''+\n '';\n\n let active = false;\n\n //////\n const dragStart = function(range_id, el, e) {\n active = range_id;\n };\n\n const dragEnd = function() {\n active = false;\n $this.apply_changes();\n };\n\n const drag = function(range_id, range, e) {\n if (active !== false && range_id == active) {\n e.preventDefault();\n const rect = container.getBoundingClientRect();\n\n let new_pos = (e.type === \"touchmove\") ? (e.touches[0].clientX - rect.left) : (e.clientX - rect.left);\n new_pos = Math.round((100 * new_pos) / container.offsetWidth);\n\n if(new_pos < 0) {new_pos = 0;}\n else if(new_pos > 100) {new_pos = 100;}\n\n // limit positions basing on previous and next step\n const min_pos = (!range_id) ? 0 : gradient_data.steps[ range_id-1 ].position;\n const max_pos = (range_id == (gradient_data.steps.length - 1)) ? 100 : gradient_data.steps[ range_id+1 ].position;\n\n if(new_pos < min_pos) {new_pos = min_pos + 1;}\n else if(new_pos > max_pos) {new_pos = max_pos - 1;}\n\n gradient_data.steps[ range_id ].position = new_pos;\n range.style.left = new_pos +'%';\n\n $this.apply_gradient_changes();\n }\n };+\n /////\n\n document.querySelectorAll('.lccp_gradient_range').forEach(range => {\n const step_num = parseInt(range.getAttribute('data-step-num'), 10);\n\n range.removeEventListener(\"touchstart\", null);\n range.removeEventListener(\"touchend\", null);\n range.removeEventListener(\"touchmove\", null);\n range.removeEventListener(\"click\", null);\n\n range.removeEventListener(\"mousedown\", null);\n range.removeEventListener(\"mouseup\", null);\n\n range.addEventListener(\"touchstart\", (e) => {dragStart(step_num, e.target, e)});\n range.addEventListener(\"mousedown\", (e) => {dragStart(step_num, e.target, e)});\n\n range.addEventListener(\"click\", (e) => {$this.select_gradient_color(step_num)});\n\n container.addEventListener(\"touchmove\", (e) => {drag(step_num, range, e)});\n container.addEventListener(\"mousemove\", (e) => {drag(step_num, range, e)});\n\n range.addEventListener(\"mouseup\", (e) => {dragEnd()});\n range.addEventListener(\"touchend\", (e) => {dragEnd()});\n document.addEventListener(\"mouseup\", (e) => {dragEnd()});\n });\n\n\n // remove step handler\n document.querySelectorAll('.lccp_gradient_range img').forEach((btn) => {\n\n btn.addEventListener(\"click\", (e) => {\n if(document.querySelectorAll('.lccp_gradient_range').length < 3) {\n return false;\n }\n\n // wait a bit to not interfere with global handler for picker closing\n setTimeout(() => {\n const parent = e.target.parentNode,\n step_num = parseInt(parent.getAttribute('data-step-num'), 10),\n to_select = (!step_num) ? 0 : step_num - 1;\n\n gradient_data.steps.splice(step_num, 1);\n\n // clean and restart\n document.querySelectorAll('.lccp_gradient_range').forEach(r => r.remove());\n\n gradient_data.steps.some(function(step, index) {\n $this.add_draggable_element(index, step.position, step.color);\n });\n\n // select newly added element\n document.querySelector('.lccp_gradient_range[data-step-num=\"'+ to_select +'\"]').click();\n\n this.apply_gradient_changes(true);\n }, 20);\n });\n });\n };\n\n\n\n /* select gradient color */\n this.select_gradient_color = function(step_num) {\n sel_grad_step = step_num;\n\n document.querySelectorAll('.lccp_gradient_range').forEach(m => m.classList.remove('lccp_sel_step'));\n document.querySelector('.lccp_gradient_range[data-step-num=\"'+ step_num +'\"]').classList.add('lccp_sel_step');\n\n active_solid = gradient_data.steps[ step_num ].color;\n active_opacity = gradient_data.steps[ step_num ].opacity;\n\n document.querySelector('#lc-color-picker input[type=\"color\"]').value = active_solid;\n document.querySelector('.pccp_color_f_wrap input[name=hex]').value = active_solid;\n\n if(options.transparency) {\n document.querySelector('.pccp_opacity_f_wrap input[type=range]').value = active_opacity;\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').value = active_opacity;\n }\n };\n\n\n\n /* apply changes to gradient, after a color/opacity/degree update */\n this.apply_gradient_changes = function(also_apply_changes) {\n const $this = this;\n\n let new_gradient = active_mode+'(';\n new_gradient += (active_mode == 'linear-gradient') ? gradient_data.deg+'deg' : (gradient_data.radial_circle) ? 'circle' : 'ellipse';\n new_gradient += ', ';\n\n let colors_part = []\n gradient_data.steps.some(function(step, index) {\n\n let to_add = (options.transparency) ? $this.hex_to_RGBA(step.color, step.opacity) : $this.shorten_hex(step.color);\n\n if(\n gradient_data.steps.length > 2 ||\n (\n gradient_data.steps.length <= 2 &&\n (\n (!index && parseInt(step.position, 10)) ||\n (index && index < (gradient_data.steps.length - 1)) ||\n (index == (gradient_data.steps.length - 1) && parseInt(step.position, 10) != 100)\n )\n )\n ) {\n to_add += ' '+ step.position +'%';\n }\n\n colors_part.push( to_add );\n });\n\n active_gradient = new_gradient + colors_part.join(', ') + ')';\n\n if(document.querySelector('.lccp_gradient:not(.lccp_gradient-bg)')) {\n document.querySelector('.lccp_gradient:not(.lccp_gradient-bg)').style.background = active_gradient;\n }\n\n if(also_apply_changes) {\n this.apply_changes();\n }\n };\n\n\n\n /* apply changes to target field */\n this.apply_changes = function() {\n if(!active_trigger) {\n return false;\n }\n let val = '';\n\n // apply everything to picker global vars\n if(active_mode == 'solid') {\n val = this.shorten_hex(active_solid);\n\n if(options.transparency && document.querySelector('.pccp_opacity_f_wrap input[type=range]')) {\n active_opacity = document.querySelector('.pccp_opacity_f_wrap input[type=range]').value;\n val = this.hex_to_RGBA(val, active_opacity);\n }\n }\n else {\n val = active_gradient;\n }\n\n // apply\n active_trigger.style.background = val;\n\n const field = active_trigger.parentNode.querySelector(right_input_selector),\n old_val = field.value;\n\n if(old_val != val) {\n field.value = val;\n last_tracked_col = val;\n\n if(typeof(options.on_change) == 'function') {\n\n if(typeof(debounced_vars['on_change_cb']) != undefined && debounced_vars['on_change_cb']) {\n clearTimeout(debounced_vars['on_change_cb']);\n }\n debounced_vars['on_change_cb'] = setTimeout(() => {\n options.on_change.call(this, val, field);\n }, 300);\n }\n }\n };\n\n\n\n\n\n\n // HANDLERS\n\n // fields toggle basing on modes change\n this.mode_change = function(el, new_mode) {\n if(active_mode == new_mode) {\n return false;\n }\n let color, opacity;\n\n // from gradient to solid\n if(new_mode == 'solid') {\n color = active_solid;\n if(options.transparency) {\n opacity = active_opacity;\n }\n }\n else {\n color = gradient_data.steps[0].color;\n if(options.transparency) {\n opacity = gradient_data.steps[0].opacity;\n }\n }\n\n document.querySelector('#lc-color-picker input[type=\"color\"]').value = color;\n document.querySelector('.pccp_color_f_wrap input[name=hex]').value = color;\n\n if(options.transparency) {\n document.querySelector('.pccp_opacity_f_wrap input[type=range]').value = opacity;\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').value = opacity;\n }\n\n // toggle grad fields\n if(options.modes.length >= 1) {\n document.querySelector('.pccp_deg_f_wrap').style.display = (new_mode == 'linear-gradient') ? 'flex' : 'none';\n document.querySelector('.pccp_circle_f_wrap').style.display = (new_mode == 'radial-gradient') ? 'block' : 'none';\n }\n\n // toogle gradient wizard\n if(options.modes.indexOf('linear-gradient') !== -1 || options.modes.indexOf('radial-gradient') !== -1) {\n document.querySelector('.lccp_gradient_wizard').style.display = (new_mode != 'solid') ? 'block' : 'none';\n }\n\n document.querySelectorAll('#lccp_modes_wrap span').forEach(m => m.classList.remove('lccp_sel_mode'));\n el.classList.add('lccp_sel_mode');\n\n active_mode = new_mode;\n (new_mode == 'solid') ? this.apply_changes() : this.apply_gradient_changes(true);\n };\n\n\n // add gradient step\n this.add_gradient_step = function(e) {\n const $this = this,\n pos = Math.round((100 * e.layerX) / e.target.offsetWidth);\n\n // inject in actual steps\n let index = 0;\n for(let step of gradient_data.steps) {\n\n if(step.position > pos) {\n const step_data = {\n color : (index - 1 < 0) ? step.color : gradient_data.steps[(index - 1)].color,\n opacity : 1,\n position : pos\n }\n\n gradient_data.steps.splice(index, 0, step_data);\n break;\n }\n\n index++;\n }\n document.querySelectorAll('.lccp_gradient_range').forEach(r => r.remove());\n\n gradient_data.steps.some(function(step, index) {\n $this.add_draggable_element(index, step.position, step.color);\n });\n\n // select newly added element\n document.querySelector('.lccp_gradient_range[data-step-num=\"'+ index +'\"]').click();\n\n this.apply_gradient_changes(true);\n };\n\n\n // apply ellipse or circle\n this.set_ellipse_circle = function(el, new_opt) {\n if(gradient_data.radial_circle && new_opt == 'circle' || !gradient_data.radial_circle && new_opt != 'circle') {\n return false;\n }\n gradient_data.radial_circle = !gradient_data.radial_circle;\n\n document.querySelectorAll('.pccp_circle_f_wrap span').forEach(m => m.classList.remove('pcpp_circle_btn_active'));\n el.classList.add('pcpp_circle_btn_active');\n\n this.apply_gradient_changes(true);\n };\n\n\n // track opacity range fields change\n this.track_deg_range_change = function(e) {\n document.querySelector('.pccp_deg_f_wrap input[name=deg-num]').value = e.target.value;\n\n gradient_data.deg = e.target.value;\n this.apply_gradient_changes(true);\n };\n this.track_deg_num_change = function(e) {\n let val = parseFloat(e.target.value);\n if(isNaN(val) || val < 0 || val > 360) {\n val = 90;\n }\n\n e.target.value = val;\n if(document.querySelector('.pccp_deg_f_wrap input[type=range]')) {\n document.querySelector('.pccp_deg_f_wrap input[type=range]').value = val;\n }\n\n gradient_data.deg = val;\n this.apply_gradient_changes(true);\n };\n\n\n // track opacity range fields change\n this.track_color_change = function(e) {\n const val = e.target.value.toLowerCase();\n document.querySelector('.pccp_color_f_wrap input[name=hex]').value = val;\n\n this.apply_color_change(val);\n };\n this.track_color_hex_change = function(e) {\n let val = this.short_hex_fix(e.target.value);\n\n if(val.match(/^#[a-f0-9]{6}$/i) === null) {\n val = active_solid.toLowerCase();\n }\n\n e.target.value = val;\n document.querySelector('#lc-color-picker input[type=\"color\"]').value = val;\n\n this.apply_color_change(val);\n };\n this.apply_color_change = function(val) {\n if(active_mode == 'solid') {\n active_solid = val;\n this.apply_changes();\n }\n else {\n gradient_data.steps[ sel_grad_step ].color = val;\n\n document.querySelector('.lccp_sel_step').style.background = val;\n this.apply_gradient_changes(true);\n }\n };\n\n\n // track opacity range fields change\n this.track_opacity_range_change = function(e) {\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').value = e.target.value;\n this.alter_hex_opacity(e.target.value);\n };\n this.track_opacity_num_change = function(e) {\n let val = parseFloat(e.target.value);\n if(isNaN(val) || val < 0 || val > 1) {\n val = 0.5;\n }\n\n e.target.value = val;\n\n if(document.querySelector('.pccp_opacity_f_wrap input[type=range]')) {\n document.querySelector('.pccp_opacity_f_wrap input[type=range]').value = val;\n this.alter_hex_opacity(val);\n }\n };\n this.alter_hex_opacity = function(opacity) {\n document.querySelector('#lc-color-picker input[type=\"color\"]').style.opacity = opacity;\n\n if(active_mode == 'solid') {\n active_opacity = opacity;\n this.apply_changes();\n }\n else {\n gradient_data.steps[ sel_grad_step ].opacity = opacity;\n this.apply_gradient_changes(true);\n }\n };\n\n\n\n\n\n /*\n * UTILITY FUNCTION - debounce action to run once after X time\n *\n * @param (string) action_name\n * @param (int) timing - milliseconds to debounce\n * @param (string) - class method name to call after debouncing\n * @param (mixed) - extra parameters to pass to callback function\n */\n this.debounce = function(action_name, timing, cb_function, cb_params) {\n if( typeof(debounced_vars[ action_name ]) != 'undefined' && debounced_vars[ action_name ]) {\n clearTimeout(debounced_vars[ action_name ]);\n }\n const $this = this;\n\n debounced_vars[ action_name ] = setTimeout(() => {\n $this[cb_function].call($this, cb_params);\n }, timing);\n };\n\n\n\n\n\n /* CSS - creates inline CSS into the page */\n this.generate_style = function() {\n const transp_bg_img = \"url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAQDAwMDAwQDAwQGBAMEBgcFBAQFBwgGBgcGBggKCAkJCQkICgoMDAwMDAoMDA0NDAwRERERERQUFBQUFBQUFBT/2wBDAQQFBQgHCA8KCg8UDg4OFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAoACgDAREAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAUGCP/EACIQAQAABQMFAQAAAAAAAAAAAAAFFUNjgqLB4RESEzVRkf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDv4AE6K0stgTgAaIAE6K0stgTgAUZra1cATW1q4A9na8WXXu/PgEqu6eQJVd08gnAAowqrjuCiADOgAowqrjuCiAD/2Q==')\";\n\n document.head.insertAdjacentHTML('beforeend',\n``);\n };\n\n\n // init when called\n this.init();\n };\n\n\n\n\n\n\n // UTILITIES\n\n // sanitize \"selector\" parameter allowing both strings and DOM objects\n const maybe_querySelectorAll = (selector) => {\n\n if(typeof(selector) != 'string') {\n if(selector instanceof Element) { // JS or jQuery\n return [selector];\n }\n else {\n let to_return = [];\n\n for(const obj of selector) {\n if(obj instanceof Element) {\n to_return.push(obj);\n }\n }\n return to_return;\n }\n }\n\n // clean problematic selectors\n (selector.match(/(#[0-9][^\\s:,]*)/g) || []).forEach(function(n) {\n selector = selector.replace(n, '[id=\"' + n.replace(\"#\", \"\") + '\"]');\n });\n\n return document.querySelectorAll(selector);\n };\n\n\n})());\n"],"names":["global","factory","this","window","lc_color_picker","debounced_vars","window_width","style_generated","active_trigger","active_trig_id","active_solid","active_opacity","active_gradient","active_mode","sel_grad_step","gradient_data","deg","radial_circle","steps","def_opts","modes","open_on_focus","transparency","dark_theme","no_input_mode","wrap_width","preview_style","input_padding","side","width","separator_color","fallback_colors","on_change","labels","right_input_selector","lccp_ivc_event","picker_id","hide_picker","CustomEvent","bubbles","detail","document","addEventListener","e","picker","querySelector","target","classList","contains","trigger","getElementsByClassName","parentNode","getElementById","getAttribute","dispatchEvent","innerWidth","String","prototype","lccpReplaceArray","find","replace","replaceString","i","length","regex","RegExp","attachTo","cp_uniqid","last_tracked_col","options","console","error","bkp_opts","Object","assign","init","$this","generate_style","maybe_querySelectorAll","forEach","el","tagName","wrap_element","Math","random","toString","substr","side_prop","trigger_css","parseInt","getComputedStyle","trigger_upper_css","value","div","createElement","className","setAttribute","style","round","getBoundingClientRect","direct_colorpicker_code","add","innerHTML","insertBefore","appendChild","paddingRight","paddingLeft","background","show_picker","remove","debounce","keyCode","key","is_active_trigger_and_opened","activeElement","curr_val","test","val_to_set","browser_val","trim","replaceAll","rgb","RGB_to_hex","toLowerCase","indexOf","call","$target","direct_colorpicker","navigator","userAgent","includes","click","val_to_picker","append_color_picker","picker_w","offsetWidth","picker_h","offsetHeight","at_offsety","at_h","clientHeight","y_pos","y","pageYOffset","left","right","floor","y_pos_css","documentElement","scrollTop","innerHeight","from_manual_input","val","load_gradient_data","load_solid_data","raw_data","data","RGBA_to_hexA","short_hex_fix","is_radial","raw_steps","split","fallback_multiplier","some","raw_step","index","position","raw_color","opacity","col_arr","push","color","rgba_arr","alpha","substring","splice","join","parseFloat","rgb_arr","r","g","b","shorten_hex","hex","a","hex_to_RGB","h","hex_to_RGBA","on_manual_input_change","theme_class","shown_solid","shown_opacity","print_grad_code","picker_el","body","insertAdjacentHTML","mode","querySelectorAll","mode_change","step","add_draggable_element","add_gradient_step","track_deg_range_change","track_deg_num_change","set_ellipse_circle","track_color_change","track_opacity_range_change","track_opacity_num_change","rel_step_num","container","sel_class","del_btn_vis","active","dragStart","range_id","dragEnd","apply_changes","drag","range","preventDefault","rect","new_pos","type","touches","clientX","min_pos","max_pos","apply_gradient_changes","step_num","removeEventListener","select_gradient_color","btn","setTimeout","parent","to_select","m","also_apply_changes","new_gradient","colors_part","to_add","field","undefined","clearTimeout","new_mode","display","pos","layerX","step_data","new_opt","isNaN","apply_color_change","track_color_hex_change","match","alter_hex_opacity","action_name","timing","cb_function","cb_params","head","selector","Element","to_return","obj","n","exports","module","define","amd","globalThis","self","Chart"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/lc_color_picker.min.map b/amd/build/lc_color_picker.min.map new file mode 100644 index 0000000..0240471 --- /dev/null +++ b/amd/build/lc_color_picker.min.map @@ -0,0 +1 @@ +{"version":3,"file":"lc_color_picker.min.js","sources":["../src/lc_color_picker.js"],"sourcesContent":["/**\r\n * lc_color_picker.js - The colorpicker for modern web\r\n * Version: 2.0.0\r\n * Author: Luca Montanari (LCweb)\r\n * Website: https://lcweb.it\r\n * Licensed under the MIT license\r\n */\r\n\r\n\r\n(function (global, factory) {\r\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\r\n typeof define === 'function' && define.amd ? define(factory) :\r\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chart = factory());\r\n })(this, (function () { 'use strict';\r\n\r\n if(typeof(window.lc_color_picker) != 'undefined') {return false;} // prevent multiple script inits\r\n\r\n\r\n /*** vars ***/\r\n let debounced_vars = [],\r\n window_width = null,\r\n\r\n style_generated = null,\r\n active_trigger = null,\r\n active_trig_id = null,\r\n\r\n active_solid = null,\r\n active_opacity = null,\r\n active_gradient = null,\r\n active_mode = 'linear-gradient',\r\n\r\n sel_grad_step = 0, // selected gradient step\r\n gradient_data = {\r\n deg: 0,\r\n radial_circle: false,\r\n steps: [\r\n //{color : null, opacity: null, position : null}\r\n ],\r\n };\r\n\r\n\r\n /*** default options ***/\r\n const def_opts = {\r\n modes : ['linear-gradient'], // (array) containing supported modes (solid | linear-gradient | radial-gradient)\r\n open_on_focus : true, // (bool) whether to open the picker when field is focused\r\n transparency : true, // (bool) whether to allow colors transparency tune\r\n dark_theme : false, // (bool) whether to enable dark picker theme\r\n no_input_mode : false, // (bool) whether to stretch the trigger in order to cover the whole input field\r\n wrap_width : 'auto', // (string) defines the wrapper width. \"auto\" to leave it up to CSS, \"inherit\" to statically copy input field width, or any other CSS sizing\r\n preview_style : { // (object) defining shape and position of the in-field preview\r\n input_padding : 35, // extra px padding eventually added to the target input to not cover text\r\n side : 'right', // right or left\r\n width : 30,\r\n separator_color : '#ccc', // (string) CSS color applird to preview element as separator\r\n },\r\n fallback_colors : ['#008080', 'linear-gradient(90deg, #fff 0%, #000 100%)'], // (array) defining default colors used when trigger field has no value. First parameter for solid color, second for gradient\r\n\r\n on_change : null, // function(new_value, target_field) {}, - triggered every time field value changes. Passes value and target field object as parameters\r\n\r\n labels : [ // (array) option used to translate script texts\r\n 'click to change color',\r\n 'Solid',\r\n 'Linear Gradient',\r\n 'Radial Gradient',\r\n 'add gradient step',\r\n 'gradient angle',\r\n 'gradient shape',\r\n 'color',\r\n 'opacity',\r\n ],\r\n };\r\n\r\n\r\n // shortcut var to target the text input only\r\n const right_input_selector = 'input:not([type=\"color\"])';\r\n\r\n\r\n\r\n // input value check custom event\r\n const lccp_ivc_event = function(picker_id, hide_picker = false) {\r\n return new CustomEvent('lccp_input_val_check', {\r\n bubbles : true,\r\n detail: {\r\n picker_id : picker_id,\r\n hide_picker : hide_picker\r\n }\r\n });\r\n };\r\n\r\n\r\n\r\n /*** hide picker cicking outside ***/\r\n document.addEventListener('click', function(e) {\r\n const picker = document.querySelector(\"#lc-color-picker.lccp-shown\");\r\n if(!picker || e.target.classList.contains('lccp-preview')) {\r\n return true;\r\n }\r\n\r\n // is an element within a trigger?\r\n for (const trigger of document.getElementsByClassName('lccp-preview')) {\r\n if(trigger.contains(e.target)) {\r\n return true;\r\n }\r\n }\r\n\r\n // clicked on the same colorpicker field? keep visible\r\n if(e.target.parentNode && e.target.parentNode.classList && e.target.parentNode.classList.contains('lccp-el-wrap') && document.getElementById(active_trig_id)) {\r\n return true;\r\n }\r\n\r\n // close if clicked element is not in the picker\r\n if(!picker.contains(e.target) && !e.target.classList.contains('lccp-shown')) {\r\n const picker_id = picker.getAttribute('data-trigger-id'),\r\n $input = document.getElementById(picker_id).parentNode.querySelector(right_input_selector);\r\n\r\n $input.dispatchEvent(lccp_ivc_event(picker_id, true));\r\n }\r\n return true;\r\n });\r\n\r\n\r\n /* hide picker on screen resizing */\r\n window.addEventListener('resize', function(e) {\r\n const picker = document.querySelector(\"#lc-color-picker.lccp-shown\");\r\n if(!picker || window_width == window.innerWidth) {\r\n return true;\r\n }\r\n\r\n // check field value\r\n const picker_id = picker.getAttribute('data-trigger-id'),\r\n $input = document.getElementById(picker_id).parentNode.querySelector(right_input_selector);\r\n\r\n $input.dispatchEvent(lccp_ivc_event(picker_id, true));\r\n });\r\n\r\n\r\n /* extend string object to ReplaceArray */\r\n String.prototype.lccpReplaceArray = function(find, replace) {\r\n let replaceString = this;\r\n let regex;\r\n\r\n for (var i = 0; i < find.length; i++) {\r\n const regex = new RegExp(find[i], \"g\");\r\n replaceString = (typeof(replace) == 'object') ? replaceString.replace(regex, replace[i]) : replaceString.replace(regex, replace);\r\n }\r\n return replaceString;\r\n };\r\n\r\n\r\n\r\n\r\n /*** plugin class ***/\r\n window.lc_color_picker = function(attachTo, options = {}) {\r\n let cp_uniqid, // unique ID assigned to this colorpicker instance\r\n last_tracked_col;\r\n\r\n this.attachTo = attachTo;\r\n if(!this.attachTo) {\r\n return console.error('You must provide a valid selector string first argument');\r\n }\r\n\r\n // override options\r\n if(typeof(options) != 'object') {\r\n return console.error('Options must be an object');\r\n }\r\n\r\n const bkp_opts = options;\r\n options = Object.assign({}, def_opts, options);\r\n\r\n if(typeof(bkp_opts.preview_style) != 'undefined') {\r\n options.preview_style = Object.assign({}, def_opts.preview_style, bkp_opts.preview_style);\r\n }\r\n\r\n\r\n\r\n /* initialize */\r\n this.init = function() {\r\n const $this = this;\r\n\r\n // Generate style\r\n if(!style_generated) {\r\n this.generate_style();\r\n style_generated = true;\r\n }\r\n\r\n\r\n // assign to each target element\r\n maybe_querySelectorAll(attachTo).forEach(function(el) {\r\n if(el.tagName == 'INPUT' && el.getAttribute('type') != 'text') {\r\n return;\r\n }\r\n\r\n // do not initialize twice\r\n if(el.parentNode.classList.length && el.parentNode.classList.contains('lcslt_wrap')) {\r\n return;\r\n }\r\n\r\n $this.wrap_element(el);\r\n });\r\n };\r\n\r\n\r\n\r\n /* wrap target element to allow trigger display */\r\n this.wrap_element = function(el) {\r\n cp_uniqid = Math.random().toString(36).substr(2, 9);\r\n\r\n const $this = this,\r\n side_prop = (options.preview_style.side == 'right') ? 'borderRightWidth' : 'borderLeftWidth';\r\n\r\n let trigger_css =\r\n `width:${ (options.no_input_mode) ? 'calc(100% - '+ parseInt(getComputedStyle(el)['borderRightWidth'], 10) +'px - '+ parseInt(getComputedStyle(el)['borderLeftWidth'], 10) +'px);' : options.preview_style.width +'px;'}` +\r\n\r\n options.preview_style.side +':'+ parseInt(getComputedStyle(el)[side_prop], 10) +'px;'+\r\n\r\n 'top:'+ parseInt(getComputedStyle(el)['borderTopWidth'], 10) +'px;' +\r\n\r\n 'height: calc(100% - '+ parseInt(getComputedStyle(el)['borderTopWidth'], 10) +'px - '+ parseInt(getComputedStyle(el)['borderBottomWidth'], 10) +'px);';\r\n\r\n let trigger_upper_css =\r\n trigger_css +\r\n 'background:'+ el.value +';' +\r\n 'border-color:'+ options.preview_style.separator_color +';'\r\n\r\n let div = document.createElement('div');\r\n div.className = 'lccp-preview-'+ options.preview_style.side;\r\n div.setAttribute('data-for', el.getAttribute('name'));\r\n\r\n // static width from input?\r\n if(options.wrap_width != 'auto') {\r\n div.style.width = (options.wrap_width == 'inherit') ? Math.round(el.getBoundingClientRect().width) + 'px' : options.wrap_width;\r\n }\r\n\r\n const direct_colorpicker_code = (!options.transparency && options.modes.length == 1 && options.modes[0] == 'linear-gradient') ?\r\n '' : '';\r\n\r\n div.classList.add(\"lccp-el-wrap\");\r\n div.innerHTML =\r\n '' +\r\n '' +\r\n direct_colorpicker_code;\r\n\r\n el.parentNode.insertBefore(div, el);\r\n div.appendChild(el);\r\n\r\n // input padding\r\n if(!options.no_input_mode) {\r\n if(options.preview_style.side == 'right') {\r\n div.querySelector('input:not([type=\"color\"])').style.paddingRight = options.preview_style.input_padding +'px';\r\n } else {\r\n div.querySelector('input:not([type=\"color\"])').style.paddingLeft = options.preview_style.input_padding +'px';\r\n }\r\n }\r\n\r\n\r\n // direct browser colorpicker? track changes\r\n if(div.querySelector('.lccp-direct-cp-f')) {\r\n div.querySelector('.lccp-direct-cp-f').addEventListener(\"input\", (e) => {\r\n\r\n div.querySelector('input:not([type=\"color\"])').value = e.target.value;\r\n div.querySelector('.lccp-preview').style.background = e.target.value;\r\n });\r\n }\r\n\r\n\r\n // event to show picker\r\n const trigger = document.getElementById(cp_uniqid);\r\n trigger.addEventListener(\"click\", (e) => {\r\n this.show_picker(trigger);\r\n });\r\n\r\n\r\n\r\n // show on field focus?\r\n if(options.open_on_focus) {\r\n div.querySelector(right_input_selector).addEventListener(\"focus\", (e) => {\r\n if(trigger != active_trigger) {\r\n if(active_trigger) {\r\n document.getElementById('lc-color-picker').classList.remove('lccp-shown');\r\n active_trigger = null;\r\n }\r\n\r\n $this.debounce('open_on_focus', 10, 'show_picker', trigger);\r\n }\r\n });\r\n }\r\n\r\n\r\n // sync manually-inputed data in the field\r\n div.querySelector(right_input_selector).addEventListener(\"keyup\", (e) => {\r\n if(e.keyCode == 9 || e.key === 'Enter' || e.keyCode === 13) {\r\n return;\r\n }\r\n\r\n const is_active_trigger_and_opened = (active_trig_id = cp_uniqid && document.querySelector(\"#lc-color-picker.lccp-shown\")) ? true : false;\r\n\r\n active_trigger = trigger;\r\n active_trig_id = cp_uniqid;\r\n\r\n $this.debounce('manual_input_sync', 10, 'val_to_picker', true);\r\n\r\n if(is_active_trigger_and_opened) {\r\n $this.debounce('manual_input_sync_cp', 10, 'append_color_picker', false);\r\n $this.debounce('reopen_picker_after_manual_edit', 10, 'show_picker', trigger);\r\n }\r\n });\r\n\r\n\r\n // be sure input value is managed on focusout\r\n div.querySelector(right_input_selector).addEventListener(\"focusout\", (e) => {\r\n // not if this field's picker is shown and focus is on \"body\"\r\n if(document.activeElement.tagName == 'BODY' && document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id=\"'+ active_trig_id +'\"]')) {\r\n return true;\r\n }\r\n\r\n e.target.dispatchEvent(lccp_ivc_event(active_trig_id, true));\r\n });\r\n\r\n\r\n // custom event - check field validity and eventually use fallback values\r\n div.querySelector(right_input_selector).addEventListener(\"lccp_input_val_check\", (e) => {\r\n const curr_val = e.target.value,\r\n test = document.createElement('div');\r\n\r\n test.style.background = curr_val;\r\n let browser_val = test.style.background,\r\n val_to_set;\r\n\r\n if(!curr_val.trim().length || !browser_val) {\r\n if(e.target.value.toLowerCase().indexOf('gradient') === -1) {\r\n val_to_set = (options.fallback_colors[0].toLowerCase().indexOf('rgba') === -1) ? $this.RGB_to_hex(options.fallback_colors[0]) : options.fallback_colors[0];\r\n }\r\n else {\r\n val_to_set = options.fallback_colors[1];\r\n }\r\n }\r\n else {\r\n // browser already fixes minor things\r\n browser_val = browser_val.replaceAll('0.', '.').replace(/rgb\\([^\\)]+\\)/g, (rgb) => {\r\n return $this.RGB_to_hex(rgb);\r\n });\r\n\r\n val_to_set = (browser_val.trim().toLowerCase().substr(0, 4) == 'rgb(') ? $this.RGB_to_hex(browser_val) : browser_val;\r\n }\r\n\r\n if(val_to_set != curr_val) {\r\n e.target.value = val_to_set;\r\n }\r\n\r\n if(typeof(options.on_change) == 'function' && last_tracked_col != val_to_set) {\r\n options.on_change.call($this, val_to_set, e.target);\r\n }\r\n\r\n if(e.detail.picker_id == active_trig_id) {\r\n active_trigger = null;\r\n active_trig_id = null;\r\n }\r\n\r\n\r\n // also hide picker?\r\n const $target = document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id=\"'+ e.detail.picker_id +'\"]');\r\n if($target) {\r\n\r\n $target.classList.remove('lccp-shown');\r\n document.getElementById(\"lc-color-picker\").remove();\r\n }\r\n });\r\n };\r\n\r\n\r\n\r\n /* show picker */\r\n this.show_picker = function(trigger) {\r\n if(document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id=\"'+ active_trig_id +'\"]')) {\r\n document.getElementById(\"lc-color-picker\").remove();\r\n active_trigger = null;\r\n active_trig_id = null\r\n\r\n return false;\r\n }\r\n\r\n // direct colorpicker usage? Not for Firefox is \"show on focus\" is enabled\r\n const direct_colorpicker = trigger.parentNode.querySelector('.lccp-direct-cp-f');\r\n if(\r\n direct_colorpicker &&\r\n (\r\n !options.open_on_focus ||\r\n (options.open_on_focus && !navigator.userAgent.toLowerCase().includes('firefox'))\r\n )\r\n ) {\r\n direct_colorpicker.value = active_solid;\r\n direct_colorpicker.click();\r\n return true;\r\n }\r\n\r\n\r\n window_width = window.innerWidth;\r\n active_trigger = trigger;\r\n active_trig_id = cp_uniqid;\r\n\r\n this.val_to_picker();\r\n this.append_color_picker();\r\n\r\n const picker = document.getElementById('lc-color-picker'),\r\n picker_w = picker.offsetWidth,\r\n picker_h = picker.offsetHeight,\r\n at_offsety = active_trigger.getBoundingClientRect(),\r\n at_h = parseInt(active_trigger.clientHeight, 10) + parseInt(getComputedStyle(active_trigger)['borderTopWidth'], 10) + parseInt(getComputedStyle(active_trigger)['borderBottomWidth'], 10),\r\n y_pos = (parseInt(at_offsety.y, 10) + parseInt(window.pageYOffset, 10) + at_h + 5);\r\n\r\n // left pos control - also checking side overflows\r\n let left = (parseInt(at_offsety.right, 10) - picker_w);\r\n if(left < 0) {\r\n left = 0;\r\n }\r\n\r\n // mobile? show it centered\r\n if(window.innerWidth < 700) {\r\n left = Math.floor( (window.innerWidth - picker_w) / 2);\r\n }\r\n\r\n // top or bottom ?\r\n const y_pos_css = (y_pos + picker_h - document.documentElement.scrollTop < window.innerHeight) ?\r\n 'top:'+ y_pos :\r\n 'transform: translate3d(0, calc((100% + '+ (active_trigger.offsetHeight + 10) +'px) * -1), 0); top:'+ y_pos;\r\n\r\n picker.setAttribute('style', y_pos_css +'px; left: '+ left +'px;');\r\n picker.classList.add('lccp-shown');\r\n };\r\n\r\n\r\n\r\n /* handles input value and prepres data for the picker */\r\n this.val_to_picker = function(from_manual_input) {\r\n if(!active_trigger) {\r\n return false;\r\n }\r\n const val = active_trigger.parentNode.querySelector(right_input_selector).value.trim().toLowerCase();\r\n last_tracked_col = val;\r\n\r\n // check validity\r\n let test = document.createElement('div');\r\n test.style.background = val;\r\n\r\n //// set active colors\r\n // if no value found\r\n if(!val.length || !test.style.background.length) {\r\n active_solid = options.fallback_colors[0];\r\n active_gradient = options.fallback_colors[1];\r\n active_mode = 'linear-gradient';\r\n\r\n /* if(val.indexOf('linear-gradient') !== -1) {\r\n }\r\n else if(val.indexOf('radial-gradient') !== -1) {\r\n active_mode = 'radial-gradient';\r\n }\r\n else {\r\n active_mode = 'solid';\r\n } */\r\n }\r\n else {\r\n\r\n active_mode = 'linear-gradient';\r\n active_gradient = val;\r\n // find which value type has been passed\r\n /* if(val.indexOf('linear-gradient') !== -1) {\r\n }\r\n else if(val.indexOf('radial-gradient') !== -1) {\r\n active_mode = 'radial-gradient';\r\n }\r\n else {\r\n active_mode = 'solid';\r\n }\r\n\r\n if(active_mode == 'solid') {\r\n active_solid = val;\r\n active_gradient = options.fallback_colors[1];\r\n }\r\n else{\r\n active_solid = options.fallback_colors[0];\r\n } */\r\n }\r\n active_trigger.style.background = val;\r\n\r\n if(!from_manual_input || (from_manual_input && options.open_on_focus)) {\r\n // elaborate solid color data (color and alpha)\r\n //this.load_solid_data(active_solid);\r\n // elaborate gradient data\r\n if(active_gradient) {\r\n this.load_gradient_data(active_gradient);\r\n }\r\n }\r\n };\r\n\r\n\r\n\r\n /* elaborate solid color data (color and alpha) loading into active_solid and active_opacity */\r\n this.load_solid_data = function(raw_data) {\r\n active_opacity = 1;\r\n\r\n // rgba\r\n if(raw_data.indexOf('rgba') !== -1) {\r\n const data = this.RGBA_to_hexA(raw_data);\r\n active_solid = data[0];\r\n active_opacity = data[1];\r\n }\r\n\r\n // rgb\r\n else if(raw_data.indexOf('rgba') !== -1) {\r\n active_solid = this.RGB_to_hex(raw_data);\r\n }\r\n\r\n // hex\r\n else {\r\n active_solid = this.short_hex_fix(raw_data);\r\n }\r\n };\r\n\r\n\r\n\r\n /* elaborate gradient data loading into gradient_data */\r\n this.load_gradient_data = function(raw_data) {\r\n const $this = this;\r\n const is_radial = (raw_data.indexOf('radial-gradient') === -1) ? false : true;\r\n\r\n // solve issues with inner RGB|RGBA and turn everything into RGBA\r\n raw_data = raw_data\r\n .replace(/,\\./g, ',0.').replace(/ \\./g, ' 0.')\r\n .replace(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/g, 'rgbaZ($1|$2|$3|$4)')\r\n .replace(/\\|\\)/g, '|1)');\r\n\r\n // names to deg\r\n raw_data = raw_data\r\n .replace('top right', '45deg').replace('right top', '45deg')\r\n .replace('bottom right', '135deg').replace('bottom right', '135deg')\r\n .replace('top left', '315deg').replace('left top', '315deg')\r\n .replace('bottom left', '225deg').replace('bottom left', '225deg')\r\n .replace('right', '90deg').replace('left', '270deg').replace('top', '0deg').replace('bottom', '180deg');\r\n\r\n // be sure deg or shape is defined\r\n if(is_radial && raw_data.indexOf('ellipse') === -1 && raw_data.indexOf('circle') === -1) {\r\n raw_data.replace('\\\\(', '(ellipse ');\r\n }\r\n if(!is_radial && raw_data.indexOf('deg') === -1) {\r\n raw_data.replace('\\\\(', '(180deg');\r\n }\r\n\r\n // process\r\n raw_data = raw_data.lccpReplaceArray(\r\n ['linear-gradient', 'radial-gradient', '', '\\\\(', 'to', '\\\\)'],\r\n ''\r\n );\r\n\r\n // split steps\r\n const raw_steps = raw_data.split(',');\r\n const fallback_multiplier = 100 / raw_steps.length;\r\n\r\n gradient_data.steps = [];\r\n raw_steps.some(function(raw_step, index) {\r\n\r\n // direction on first index\r\n if(!index) {\r\n if(is_radial) {\r\n gradient_data.radial_circle = (raw_step.indexOf('circle') === -1) ? false : true;\r\n } else {\r\n gradient_data.deg = parseInt(raw_step.replace('deg', ''), 10);\r\n }\r\n }\r\n\r\n // {color : null, opacity: null, position : null}\r\n else {\r\n raw_step = raw_step.trim().split(' ');\r\n let position = '';\r\n\r\n // position\r\n if(raw_step.length < 2) {\r\n if(index === 1) {\r\n position = '0%';\r\n }\r\n else if(index == (raw_steps.length - 1)) {\r\n position = '100%';\r\n }\r\n else {\r\n position = (fallback_multiplier * index) +'%';\r\n }\r\n }\r\n else {\r\n position = raw_step[1];\r\n }\r\n\r\n // color\r\n let raw_color = raw_step[0],\r\n opacity = 1;\r\n\r\n // normalize to hex\r\n if(raw_color.indexOf('rgbaZ') !== -1) {\r\n const col_arr = $this.RGBA_to_hexA(\r\n raw_color.replace('rgbaZ', 'rgba').replace(/\\|/g, ',')\r\n );\r\n\r\n raw_color = col_arr[0];\r\n opacity = col_arr[1];\r\n }\r\n\r\n gradient_data.steps.push({\r\n color : $this.short_hex_fix(raw_color),\r\n opacity: opacity,\r\n position : parseInt(position, 10)\r\n });\r\n }\r\n });\r\n };\r\n\r\n\r\n\r\n /* handles RGBA string returning a two elements array: hex and alpha */\r\n this.RGBA_to_hexA = function(raw_data) {\r\n raw_data = raw_data.lccpReplaceArray(['rgba', '\\\\(', '\\\\)'], '');\r\n const rgba_arr = raw_data.split(',')\r\n\r\n let alpha = (typeof(rgba_arr[3]) != 'undefined') ? rgba_arr[3] : '1';\r\n if(alpha.substring(0, 1) == '.') {\r\n alpha = 0 + alpha;\r\n }\r\n rgba_arr.splice(3, 1);\r\n\r\n return [\r\n this.RGB_to_hex('rgb('+ rgba_arr.join(',') +')'),\r\n parseFloat(alpha)\r\n ];\r\n };\r\n\r\n\r\n\r\n /* convert RGB to hex */\r\n this.RGB_to_hex = function(rgb) {\r\n rgb = rgb.lccpReplaceArray(['rgb', '\\\\(', '\\\\)'], '');\r\n const rgb_arr = rgb.split(',');\r\n\r\n if(rgb_arr.length < 3) {\r\n return '';\r\n }\r\n\r\n let r = parseInt(rgb_arr[0].trim(), 10).toString(16),\r\n g = parseInt(rgb_arr[1].trim(), 10).toString(16),\r\n b = parseInt(rgb_arr[2].trim(), 10).toString(16);\r\n\r\n if (r.length == 1) {r = \"0\" + r;}\r\n if (g.length == 1) {g = \"0\" + g;}\r\n if (b.length == 1) {b = \"0\" + b;}\r\n\r\n return this.shorten_hex(r + g + b);\r\n };\r\n\r\n\r\n\r\n /* if possible, shortenize hex string */\r\n this.shorten_hex = function(hex) {\r\n hex = hex.replace('#', '').split('');\r\n\r\n if(hex.length >= 6) {\r\n if(\r\n hex[0] === hex[1] &&\r\n hex[2] === hex[3] &&\r\n hex[4] === hex[5]\r\n ) {\r\n return '#'+ hex[0] + hex[2] + hex[4];\r\n }\r\n }\r\n\r\n return '#'+ hex.join('');\r\n };\r\n\r\n\r\n\r\n /* convert short hex to full format */\r\n this.short_hex_fix = function(hex) {\r\n if(hex.length == 4) {\r\n const a = hex.split('');\r\n hex = a[0] + a[1] + a[1] + a[2] + a[2] + a[3] + a[3];\r\n }\r\n\r\n return hex.toLowerCase();\r\n };\r\n\r\n\r\n\r\n /* convert hex to RGB */\r\n this.hex_to_RGB = function(h) {\r\n let r = 0, g = 0, b = 0;\r\n\r\n // 3 digits\r\n if (h.length == 4) {\r\n r = \"0x\" + h[1] + h[1];\r\n g = \"0x\" + h[2] + h[2];\r\n b = \"0x\" + h[3] + h[3];\r\n\r\n // 6 digits\r\n } else if (h.length == 7) {\r\n r = \"0x\" + h[1] + h[2];\r\n g = \"0x\" + h[3] + h[4];\r\n b = \"0x\" + h[5] + h[6];\r\n }\r\n\r\n return \"rgb(\"+ +r + \", \" + +g + \", \" + +b + \")\";\r\n };\r\n\r\n\r\n\r\n /* convert hex to RGB */\r\n this.hex_to_RGBA = function(h, opacity) {\r\n if(parseFloat(opacity) === 1) {\r\n return this.shorten_hex(h);\r\n }\r\n\r\n let rgb = this.hex_to_RGB(h);\r\n return rgb.replace('(', 'a(').replace(')', ', '+ opacity.toString().replace('0.', '.') +')');\r\n };\r\n\r\n\r\n\r\n\r\n /* append color container picker to the body */\r\n this.append_color_picker = function(on_manual_input_change = false) {\r\n const $this = this;\r\n\r\n /* if(document.getElementById(\"lc-color-picker\") && !on_manual_input_change) {\r\n document.getElementById(\"lc-color-picker\").remove();\r\n } */\r\n\r\n const theme_class = (options.dark_theme) ? 'lccp_dark_theme' : 'lccp_light_theme',\r\n bg = (active_mode == 'solid') ? active_solid : active_gradient,\r\n shown_solid = (active_mode == 'solid') ? active_solid : gradient_data.steps[0].color,\r\n shown_opacity = (active_mode == 'solid') ? active_opacity : (options.transparency) ? gradient_data.steps[0].opacity : null,\r\n print_grad_code = (options.modes.indexOf('linear-gradient') !== -1 || options.modes.indexOf('radial-gradient') !== -1) ? true : false;\r\n\r\n\r\n // start code\r\n let picker = '',\r\n picker_el;\r\n\r\n if(on_manual_input_change && document.getElementById(\"lc-color-picker\")) {\r\n picker_el = document.getElementById(\"lc-color-picker\");\r\n picker_el.setAttribute('data-mode', active_mode);\r\n picker_el.setAttribute('data-trigger-id', cp_uniqid);\r\n }\r\n else {\r\n picker = '
';\r\n }\r\n\r\n\r\n // modes select\r\n /* if(options.modes.length >= 1) {\r\n picker += `\r\n
\r\n ${ options.labels[1] }\r\n ${ options.labels[2] }\r\n ${ options.labels[3] }\r\n
`;\r\n } */\r\n\r\n\r\n // gradient wizard\r\n if(print_grad_code) {\r\n picker += `\r\n
\r\n
\r\n
\r\n\r\n
\r\n\r\n
\r\n \"angle\"\r\n\r\n \r\n \r\n
\r\n
\r\n \"shape\"\r\n\r\n Ellipse\r\n Circle\r\n
\r\n
\r\n
`;\r\n }\r\n\r\n\r\n // HTML5 colorpicker\r\n picker += `\r\n
\r\n \"color\"\r\n\r\n
\r\n \r\n
\r\n \r\n
`;\r\n\r\n // opacity cursor\r\n if(options.transparency) {\r\n picker += `\r\n
\r\n \"opacity\"\r\n\r\n \r\n \r\n
`;\r\n }\r\n\r\n\r\n // append or re-fill\r\n (on_manual_input_change && document.getElementById(\"lc-color-picker\")) ? picker_el.innerHTML = picker : document.body.insertAdjacentHTML('beforeend', picker +'
');\r\n\r\n\r\n // modes change\r\n if(options.modes.length >= 1) {\r\n for (const mode of document.querySelectorAll('#lccp_modes_wrap span')) {\r\n mode.addEventListener(\"click\", (e) => { $this.mode_change( e.target, e.target.getAttribute('data-mode')) });\r\n }\r\n }\r\n\r\n // print steps and add gradient step action\r\n if(print_grad_code) {\r\n gradient_data.steps.some(function(step, index) {\r\n $this.add_draggable_element(index, step.position, step.color);\r\n });\r\n\r\n document.querySelector('.lccp_gradient:not(.lccp_gradient-bg)').addEventListener(\"click\", (e) => {this.add_gradient_step(e) });\r\n }\r\n\r\n // angle actions\r\n if(options.modes.indexOf('linear-gradient') !== -1) {\r\n document.querySelector('.pccp_deg_f_wrap input[type=range]').addEventListener(\"input\", (e) => {this.track_deg_range_change(e)});\r\n document.querySelector('.pccp_deg_f_wrap input[name=deg-num]').addEventListener(\"change\", (e) => {this.track_deg_num_change(e)});\r\n document.querySelector('.pccp_deg_f_wrap input[name=deg-num]').addEventListener(\"keyup\", (e) => {\r\n this.debounce('deg_f_change', 500, 'track_deg_num_change', e);\r\n });\r\n }\r\n\r\n // circle actions\r\n if(options.modes.indexOf('radial-gradient') !== -1) {\r\n for (const mode of document.querySelectorAll('.pccp_circle_f_wrap span')) {\r\n mode.addEventListener(\"click\", (e) => { $this.set_ellipse_circle( e.target, e.target.getAttribute('data-val')) });\r\n }\r\n }\r\n\r\n // color actions\r\n document.querySelector('.pccp_color_f_wrap input[type=\"color\"]').addEventListener(\"input\", (e) => {this.track_color_change(e)});\r\n document.querySelector('.pccp_color_f_wrap input[type=\"color\"]').addEventListener(\"change\", (e) => {this.track_color_change(e)});\r\n document.querySelector('.pccp_color_f_wrap input[name=hex]').addEventListener(\"keyup\", (e) => {\r\n this.debounce('hex_f_change', 600, 'track_color_hex_change', e);\r\n });\r\n\r\n // transparency actions\r\n if(options.transparency) {\r\n document.querySelector('.pccp_opacity_f_wrap input[type=range]').addEventListener(\"input\", (e) => {this.track_opacity_range_change(e)});\r\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').addEventListener(\"change\", (e) => {this.track_opacity_num_change(e)});\r\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').addEventListener(\"keyup\", (e) => {\r\n this.debounce('opacity_f_change', 500, 'track_opacity_num_change', e);\r\n });\r\n }\r\n };\r\n\r\n\r\n\r\n /*** add draggable element ***/\r\n this.add_draggable_element = function(rel_step_num, position, color) {\r\n const $this = this,\r\n container = document.querySelector('.lccp_gradient_ranges'),\r\n sel_class = (!rel_step_num) ? 'lccp_sel_step' : '',\r\n del_btn_vis = (gradient_data.steps.length > 2) ? '' : 'style=\"display: none;\"'\r\n\r\n container.innerHTML +=\r\n ''+\r\n ''+\r\n '';\r\n\r\n let active = false;\r\n\r\n //////\r\n const dragStart = function(range_id, el, e) {\r\n active = range_id;\r\n };\r\n\r\n const dragEnd = function() {\r\n active = false;\r\n $this.apply_changes();\r\n };\r\n\r\n const drag = function(range_id, range, e) {\r\n if (active !== false && range_id == active) {\r\n e.preventDefault();\r\n const rect = container.getBoundingClientRect();\r\n\r\n let new_pos = (e.type === \"touchmove\") ? (e.touches[0].clientX - rect.left) : (e.clientX - rect.left);\r\n new_pos = Math.round((100 * new_pos) / container.offsetWidth);\r\n\r\n if(new_pos < 0) {new_pos = 0;}\r\n else if(new_pos > 100) {new_pos = 100;}\r\n\r\n // limit positions basing on previous and next step\r\n const min_pos = (!range_id) ? 0 : gradient_data.steps[ range_id-1 ].position;\r\n const max_pos = (range_id == (gradient_data.steps.length - 1)) ? 100 : gradient_data.steps[ range_id+1 ].position;\r\n\r\n if(new_pos < min_pos) {new_pos = min_pos + 1;}\r\n else if(new_pos > max_pos) {new_pos = max_pos - 1;}\r\n\r\n gradient_data.steps[ range_id ].position = new_pos;\r\n range.style.left = new_pos +'%';\r\n\r\n $this.apply_gradient_changes();\r\n }\r\n };+\r\n /////\r\n\r\n document.querySelectorAll('.lccp_gradient_range').forEach(range => {\r\n const step_num = parseInt(range.getAttribute('data-step-num'), 10);\r\n\r\n range.removeEventListener(\"touchstart\", null);\r\n range.removeEventListener(\"touchend\", null);\r\n range.removeEventListener(\"touchmove\", null);\r\n range.removeEventListener(\"click\", null);\r\n\r\n range.removeEventListener(\"mousedown\", null);\r\n range.removeEventListener(\"mouseup\", null);\r\n\r\n range.addEventListener(\"touchstart\", (e) => {dragStart(step_num, e.target, e)});\r\n range.addEventListener(\"mousedown\", (e) => {dragStart(step_num, e.target, e)});\r\n\r\n range.addEventListener(\"click\", (e) => {$this.select_gradient_color(step_num)});\r\n\r\n container.addEventListener(\"touchmove\", (e) => {drag(step_num, range, e)});\r\n container.addEventListener(\"mousemove\", (e) => {drag(step_num, range, e)});\r\n\r\n range.addEventListener(\"mouseup\", (e) => {dragEnd()});\r\n range.addEventListener(\"touchend\", (e) => {dragEnd()});\r\n document.addEventListener(\"mouseup\", (e) => {dragEnd()});\r\n });\r\n\r\n\r\n // remove step handler\r\n document.querySelectorAll('.lccp_gradient_range img').forEach((btn) => {\r\n\r\n btn.addEventListener(\"click\", (e) => {\r\n if(document.querySelectorAll('.lccp_gradient_range').length < 3) {\r\n return false;\r\n }\r\n\r\n // wait a bit to not interfere with global handler for picker closing\r\n setTimeout(() => {\r\n const parent = e.target.parentNode,\r\n step_num = parseInt(parent.getAttribute('data-step-num'), 10),\r\n to_select = (!step_num) ? 0 : step_num - 1;\r\n\r\n gradient_data.steps.splice(step_num, 1);\r\n\r\n // clean and restart\r\n document.querySelectorAll('.lccp_gradient_range').forEach(r => r.remove());\r\n\r\n gradient_data.steps.some(function(step, index) {\r\n $this.add_draggable_element(index, step.position, step.color);\r\n });\r\n\r\n // select newly added element\r\n document.querySelector('.lccp_gradient_range[data-step-num=\"'+ to_select +'\"]').click();\r\n\r\n this.apply_gradient_changes(true);\r\n }, 20);\r\n });\r\n });\r\n };\r\n\r\n\r\n\r\n /* select gradient color */\r\n this.select_gradient_color = function(step_num) {\r\n sel_grad_step = step_num;\r\n\r\n document.querySelectorAll('.lccp_gradient_range').forEach(m => m.classList.remove('lccp_sel_step'));\r\n document.querySelector('.lccp_gradient_range[data-step-num=\"'+ step_num +'\"]').classList.add('lccp_sel_step');\r\n\r\n active_solid = gradient_data.steps[ step_num ].color;\r\n active_opacity = gradient_data.steps[ step_num ].opacity;\r\n\r\n document.querySelector('#lc-color-picker input[type=\"color\"]').value = active_solid;\r\n document.querySelector('.pccp_color_f_wrap input[name=hex]').value = active_solid;\r\n\r\n if(options.transparency) {\r\n document.querySelector('.pccp_opacity_f_wrap input[type=range]').value = active_opacity;\r\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').value = active_opacity;\r\n }\r\n };\r\n\r\n\r\n\r\n /* apply changes to gradient, after a color/opacity/degree update */\r\n this.apply_gradient_changes = function(also_apply_changes) {\r\n const $this = this;\r\n\r\n let new_gradient = active_mode+'(';\r\n new_gradient += (active_mode == 'linear-gradient') ? gradient_data.deg+'deg' : (gradient_data.radial_circle) ? 'circle' : 'ellipse';\r\n new_gradient += ', ';\r\n\r\n let colors_part = []\r\n gradient_data.steps.some(function(step, index) {\r\n\r\n let to_add = (options.transparency) ? $this.hex_to_RGBA(step.color, step.opacity) : $this.shorten_hex(step.color);\r\n\r\n if(\r\n gradient_data.steps.length > 2 ||\r\n (\r\n gradient_data.steps.length <= 2 &&\r\n (\r\n (!index && parseInt(step.position, 10)) ||\r\n (index && index < (gradient_data.steps.length - 1)) ||\r\n (index == (gradient_data.steps.length - 1) && parseInt(step.position, 10) != 100)\r\n )\r\n )\r\n ) {\r\n to_add += ' '+ step.position +'%';\r\n }\r\n\r\n colors_part.push( to_add );\r\n });\r\n\r\n active_gradient = new_gradient + colors_part.join(', ') + ')';\r\n\r\n if(document.querySelector('.lccp_gradient:not(.lccp_gradient-bg)')) {\r\n document.querySelector('.lccp_gradient:not(.lccp_gradient-bg)').style.background = active_gradient;\r\n }\r\n\r\n if(also_apply_changes) {\r\n this.apply_changes();\r\n }\r\n };\r\n\r\n\r\n\r\n /* apply changes to target field */\r\n this.apply_changes = function() {\r\n if(!active_trigger) {\r\n return false;\r\n }\r\n let val = '';\r\n\r\n // apply everything to picker global vars\r\n if(active_mode == 'solid') {\r\n val = this.shorten_hex(active_solid);\r\n\r\n if(options.transparency && document.querySelector('.pccp_opacity_f_wrap input[type=range]')) {\r\n active_opacity = document.querySelector('.pccp_opacity_f_wrap input[type=range]').value;\r\n val = this.hex_to_RGBA(val, active_opacity);\r\n }\r\n }\r\n else {\r\n val = active_gradient;\r\n }\r\n\r\n // apply\r\n active_trigger.style.background = val;\r\n\r\n const field = active_trigger.parentNode.querySelector(right_input_selector),\r\n old_val = field.value;\r\n\r\n if(old_val != val) {\r\n field.value = val;\r\n last_tracked_col = val;\r\n\r\n if(typeof(options.on_change) == 'function') {\r\n\r\n if(typeof(debounced_vars['on_change_cb']) != undefined && debounced_vars['on_change_cb']) {\r\n clearTimeout(debounced_vars['on_change_cb']);\r\n }\r\n debounced_vars['on_change_cb'] = setTimeout(() => {\r\n options.on_change.call(this, val, field);\r\n }, 300);\r\n }\r\n }\r\n };\r\n\r\n\r\n\r\n\r\n\r\n\r\n // HANDLERS\r\n\r\n // fields toggle basing on modes change\r\n this.mode_change = function(el, new_mode) {\r\n if(active_mode == new_mode) {\r\n return false;\r\n }\r\n let color, opacity;\r\n\r\n // from gradient to solid\r\n if(new_mode == 'solid') {\r\n color = active_solid;\r\n if(options.transparency) {\r\n opacity = active_opacity;\r\n }\r\n }\r\n else {\r\n color = gradient_data.steps[0].color;\r\n if(options.transparency) {\r\n opacity = gradient_data.steps[0].opacity;\r\n }\r\n }\r\n\r\n document.querySelector('#lc-color-picker input[type=\"color\"]').value = color;\r\n document.querySelector('.pccp_color_f_wrap input[name=hex]').value = color;\r\n\r\n if(options.transparency) {\r\n document.querySelector('.pccp_opacity_f_wrap input[type=range]').value = opacity;\r\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').value = opacity;\r\n }\r\n\r\n // toggle grad fields\r\n if(options.modes.length >= 1) {\r\n document.querySelector('.pccp_deg_f_wrap').style.display = (new_mode == 'linear-gradient') ? 'flex' : 'none';\r\n document.querySelector('.pccp_circle_f_wrap').style.display = (new_mode == 'radial-gradient') ? 'block' : 'none';\r\n }\r\n\r\n // toogle gradient wizard\r\n if(options.modes.indexOf('linear-gradient') !== -1 || options.modes.indexOf('radial-gradient') !== -1) {\r\n document.querySelector('.lccp_gradient_wizard').style.display = (new_mode != 'solid') ? 'block' : 'none';\r\n }\r\n\r\n document.querySelectorAll('#lccp_modes_wrap span').forEach(m => m.classList.remove('lccp_sel_mode'));\r\n el.classList.add('lccp_sel_mode');\r\n\r\n active_mode = new_mode;\r\n (new_mode == 'solid') ? this.apply_changes() : this.apply_gradient_changes(true);\r\n };\r\n\r\n\r\n // add gradient step\r\n this.add_gradient_step = function(e) {\r\n const $this = this,\r\n pos = Math.round((100 * e.layerX) / e.target.offsetWidth);\r\n\r\n // inject in actual steps\r\n let index = 0;\r\n for(let step of gradient_data.steps) {\r\n\r\n if(step.position > pos) {\r\n const step_data = {\r\n color : (index - 1 < 0) ? step.color : gradient_data.steps[(index - 1)].color,\r\n opacity : 1,\r\n position : pos\r\n }\r\n\r\n gradient_data.steps.splice(index, 0, step_data);\r\n break;\r\n }\r\n\r\n index++;\r\n }\r\n document.querySelectorAll('.lccp_gradient_range').forEach(r => r.remove());\r\n\r\n gradient_data.steps.some(function(step, index) {\r\n $this.add_draggable_element(index, step.position, step.color);\r\n });\r\n\r\n // select newly added element\r\n document.querySelector('.lccp_gradient_range[data-step-num=\"'+ index +'\"]').click();\r\n\r\n this.apply_gradient_changes(true);\r\n };\r\n\r\n\r\n // apply ellipse or circle\r\n this.set_ellipse_circle = function(el, new_opt) {\r\n if(gradient_data.radial_circle && new_opt == 'circle' || !gradient_data.radial_circle && new_opt != 'circle') {\r\n return false;\r\n }\r\n gradient_data.radial_circle = !gradient_data.radial_circle;\r\n\r\n document.querySelectorAll('.pccp_circle_f_wrap span').forEach(m => m.classList.remove('pcpp_circle_btn_active'));\r\n el.classList.add('pcpp_circle_btn_active');\r\n\r\n this.apply_gradient_changes(true);\r\n };\r\n\r\n\r\n // track opacity range fields change\r\n this.track_deg_range_change = function(e) {\r\n document.querySelector('.pccp_deg_f_wrap input[name=deg-num]').value = e.target.value;\r\n\r\n gradient_data.deg = e.target.value;\r\n this.apply_gradient_changes(true);\r\n };\r\n this.track_deg_num_change = function(e) {\r\n let val = parseFloat(e.target.value);\r\n if(isNaN(val) || val < 0 || val > 360) {\r\n val = 90;\r\n }\r\n\r\n e.target.value = val;\r\n if(document.querySelector('.pccp_deg_f_wrap input[type=range]')) {\r\n document.querySelector('.pccp_deg_f_wrap input[type=range]').value = val;\r\n }\r\n\r\n gradient_data.deg = val;\r\n this.apply_gradient_changes(true);\r\n };\r\n\r\n\r\n // track opacity range fields change\r\n this.track_color_change = function(e) {\r\n const val = e.target.value.toLowerCase();\r\n document.querySelector('.pccp_color_f_wrap input[name=hex]').value = val;\r\n\r\n this.apply_color_change(val);\r\n };\r\n this.track_color_hex_change = function(e) {\r\n let val = this.short_hex_fix(e.target.value);\r\n\r\n if(val.match(/^#[a-f0-9]{6}$/i) === null) {\r\n val = active_solid.toLowerCase();\r\n }\r\n\r\n e.target.value = val;\r\n document.querySelector('#lc-color-picker input[type=\"color\"]').value = val;\r\n\r\n this.apply_color_change(val);\r\n };\r\n this.apply_color_change = function(val) {\r\n if(active_mode == 'solid') {\r\n active_solid = val;\r\n this.apply_changes();\r\n }\r\n else {\r\n gradient_data.steps[ sel_grad_step ].color = val;\r\n\r\n document.querySelector('.lccp_sel_step').style.background = val;\r\n this.apply_gradient_changes(true);\r\n }\r\n };\r\n\r\n\r\n // track opacity range fields change\r\n this.track_opacity_range_change = function(e) {\r\n document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').value = e.target.value;\r\n this.alter_hex_opacity(e.target.value);\r\n };\r\n this.track_opacity_num_change = function(e) {\r\n let val = parseFloat(e.target.value);\r\n if(isNaN(val) || val < 0 || val > 1) {\r\n val = 0.5;\r\n }\r\n\r\n e.target.value = val;\r\n\r\n if(document.querySelector('.pccp_opacity_f_wrap input[type=range]')) {\r\n document.querySelector('.pccp_opacity_f_wrap input[type=range]').value = val;\r\n this.alter_hex_opacity(val);\r\n }\r\n };\r\n this.alter_hex_opacity = function(opacity) {\r\n document.querySelector('#lc-color-picker input[type=\"color\"]').style.opacity = opacity;\r\n\r\n if(active_mode == 'solid') {\r\n active_opacity = opacity;\r\n this.apply_changes();\r\n }\r\n else {\r\n gradient_data.steps[ sel_grad_step ].opacity = opacity;\r\n this.apply_gradient_changes(true);\r\n }\r\n };\r\n\r\n\r\n\r\n\r\n\r\n /*\r\n * UTILITY FUNCTION - debounce action to run once after X time\r\n *\r\n * @param (string) action_name\r\n * @param (int) timing - milliseconds to debounce\r\n * @param (string) - class method name to call after debouncing\r\n * @param (mixed) - extra parameters to pass to callback function\r\n */\r\n this.debounce = function(action_name, timing, cb_function, cb_params) {\r\n if( typeof(debounced_vars[ action_name ]) != 'undefined' && debounced_vars[ action_name ]) {\r\n clearTimeout(debounced_vars[ action_name ]);\r\n }\r\n const $this = this;\r\n\r\n debounced_vars[ action_name ] = setTimeout(() => {\r\n $this[cb_function].call($this, cb_params);\r\n }, timing);\r\n };\r\n\r\n\r\n\r\n\r\n\r\n /* CSS - creates inline CSS into the page */\r\n this.generate_style = function() {\r\n const transp_bg_img = \"url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAQDAwMDAwQDAwQGBAMEBgcFBAQFBwgGBgcGBggKCAkJCQkICgoMDAwMDAoMDA0NDAwRERERERQUFBQUFBQUFBT/2wBDAQQFBQgHCA8KCg8UDg4OFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAoACgDAREAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAUGCP/EACIQAQAABQMFAQAAAAAAAAAAAAAFFUNjgqLB4RESEzVRkf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDv4AE6K0stgTgAaIAE6K0stgTgAUZra1cATW1q4A9na8WXXu/PgEqu6eQJVd08gnAAowqrjuCiADOgAowqrjuCiAD/2Q==')\";\r\n\r\n document.head.insertAdjacentHTML('beforeend',\r\n``);\r\n };\r\n\r\n\r\n // init when called\r\n this.init();\r\n };\r\n\r\n\r\n\r\n\r\n\r\n\r\n // UTILITIES\r\n\r\n // sanitize \"selector\" parameter allowing both strings and DOM objects\r\n const maybe_querySelectorAll = (selector) => {\r\n\r\n if(typeof(selector) != 'string') {\r\n if(selector instanceof Element) { // JS or jQuery\r\n return [selector];\r\n }\r\n else {\r\n let to_return = [];\r\n\r\n for(const obj of selector) {\r\n if(obj instanceof Element) {\r\n to_return.push(obj);\r\n }\r\n }\r\n return to_return;\r\n }\r\n }\r\n\r\n // clean problematic selectors\r\n (selector.match(/(#[0-9][^\\s:,]*)/g) || []).forEach(function(n) {\r\n selector = selector.replace(n, '[id=\"' + n.replace(\"#\", \"\") + '\"]');\r\n });\r\n\r\n return document.querySelectorAll(selector);\r\n };\r\n\r\n\r\n})());\r\n"],"names":["global","factory","this","window","lc_color_picker","debounced_vars","window_width","style_generated","active_trigger","active_trig_id","active_solid","active_opacity","active_gradient","active_mode","sel_grad_step","gradient_data","deg","radial_circle","steps","def_opts","modes","open_on_focus","transparency","dark_theme","no_input_mode","wrap_width","preview_style","input_padding","side","width","separator_color","fallback_colors","on_change","labels","right_input_selector","lccp_ivc_event","picker_id","hide_picker","CustomEvent","bubbles","detail","document","addEventListener","e","picker","querySelector","target","classList","contains","trigger","getElementsByClassName","parentNode","getElementById","getAttribute","dispatchEvent","innerWidth","String","prototype","lccpReplaceArray","find","replace","replaceString","i","length","regex","RegExp","attachTo","cp_uniqid","last_tracked_col","options","console","error","bkp_opts","Object","assign","init","$this","generate_style","maybe_querySelectorAll","forEach","el","tagName","wrap_element","Math","random","toString","substr","side_prop","trigger_css","parseInt","getComputedStyle","trigger_upper_css","value","div","createElement","className","setAttribute","style","round","getBoundingClientRect","direct_colorpicker_code","add","innerHTML","insertBefore","appendChild","paddingRight","paddingLeft","background","show_picker","remove","debounce","keyCode","key","is_active_trigger_and_opened","activeElement","curr_val","test","val_to_set","browser_val","trim","replaceAll","rgb","RGB_to_hex","toLowerCase","indexOf","call","$target","direct_colorpicker","navigator","userAgent","includes","click","val_to_picker","append_color_picker","picker_w","offsetWidth","picker_h","offsetHeight","at_offsety","at_h","clientHeight","y_pos","y","pageYOffset","left","right","floor","y_pos_css","documentElement","scrollTop","innerHeight","from_manual_input","val","load_gradient_data","load_solid_data","raw_data","data","RGBA_to_hexA","short_hex_fix","is_radial","raw_steps","split","fallback_multiplier","some","raw_step","index","position","raw_color","opacity","col_arr","push","color","rgba_arr","alpha","substring","splice","join","parseFloat","rgb_arr","r","g","b","shorten_hex","hex","a","hex_to_RGB","h","hex_to_RGBA","on_manual_input_change","theme_class","shown_solid","shown_opacity","print_grad_code","picker_el","body","insertAdjacentHTML","mode","querySelectorAll","mode_change","step","add_draggable_element","add_gradient_step","track_deg_range_change","track_deg_num_change","set_ellipse_circle","track_color_change","track_opacity_range_change","track_opacity_num_change","rel_step_num","container","sel_class","del_btn_vis","active","dragStart","range_id","dragEnd","apply_changes","drag","range","preventDefault","rect","new_pos","type","touches","clientX","min_pos","max_pos","apply_gradient_changes","step_num","removeEventListener","select_gradient_color","btn","setTimeout","parent","to_select","m","also_apply_changes","new_gradient","colors_part","to_add","field","undefined","clearTimeout","new_mode","display","pos","layerX","step_data","new_opt","isNaN","apply_color_change","track_color_hex_change","match","alter_hex_opacity","action_name","timing","cb_function","cb_params","head","selector","Element","to_return","obj","n","exports","module","define","amd","globalThis","self","Chart"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/gradient.js b/amd/src/gradient.js new file mode 100644 index 0000000..3a3ae5f --- /dev/null +++ b/amd/src/gradient.js @@ -0,0 +1,3 @@ +define(['block_dash/lc_color_picker'], function(Picker) { + return Picker; +}); \ No newline at end of file diff --git a/amd/src/gradienthandler.js b/amd/src/gradienthandler.js new file mode 100644 index 0000000..e66779c --- /dev/null +++ b/amd/src/gradienthandler.js @@ -0,0 +1,7 @@ +define(['jquery', 'core/str'], function (jQuery) { + return { + init: function() { + alert('demo'); + } + } +}); \ No newline at end of file diff --git a/amd/src/lc_color_picker.js b/amd/src/lc_color_picker.js new file mode 100644 index 0000000..b63acd4 --- /dev/null +++ b/amd/src/lc_color_picker.js @@ -0,0 +1,1665 @@ +/** + * lc_color_picker.js - The colorpicker for modern web + * Version: 2.0.0 + * Author: Luca Montanari (LCweb) + * Website: https://lcweb.it + * Licensed under the MIT license + */ + + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chart = factory()); + })(this, (function () { 'use strict'; + + if(typeof(window.lc_color_picker) != 'undefined') {return false;} // prevent multiple script inits + + + /*** vars ***/ + let debounced_vars = [], + window_width = null, + + style_generated = null, + active_trigger = null, + active_trig_id = null, + + active_solid = null, + active_opacity = null, + active_gradient = null, + active_mode = 'linear-gradient', + + sel_grad_step = 0, // selected gradient step + gradient_data = { + deg: 0, + radial_circle: false, + steps: [ + //{color : null, opacity: null, position : null} + ], + }; + + + /*** default options ***/ + const def_opts = { + modes : ['linear-gradient'], // (array) containing supported modes (solid | linear-gradient | radial-gradient) + open_on_focus : true, // (bool) whether to open the picker when field is focused + transparency : true, // (bool) whether to allow colors transparency tune + dark_theme : false, // (bool) whether to enable dark picker theme + no_input_mode : false, // (bool) whether to stretch the trigger in order to cover the whole input field + wrap_width : 'auto', // (string) defines the wrapper width. "auto" to leave it up to CSS, "inherit" to statically copy input field width, or any other CSS sizing + preview_style : { // (object) defining shape and position of the in-field preview + input_padding : 35, // extra px padding eventually added to the target input to not cover text + side : 'right', // right or left + width : 30, + separator_color : '#ccc', // (string) CSS color applird to preview element as separator + }, + fallback_colors : ['#008080', 'linear-gradient(90deg, #fff 0%, #000 100%)'], // (array) defining default colors used when trigger field has no value. First parameter for solid color, second for gradient + + on_change : null, // function(new_value, target_field) {}, - triggered every time field value changes. Passes value and target field object as parameters + + labels : [ // (array) option used to translate script texts + 'click to change color', + 'Solid', + 'Linear Gradient', + 'Radial Gradient', + 'add gradient step', + 'gradient angle', + 'gradient shape', + 'color', + 'opacity', + ], + }; + + + // shortcut var to target the text input only + const right_input_selector = 'input:not([type="color"])'; + + + + // input value check custom event + const lccp_ivc_event = function(picker_id, hide_picker = false) { + return new CustomEvent('lccp_input_val_check', { + bubbles : true, + detail: { + picker_id : picker_id, + hide_picker : hide_picker + } + }); + }; + + + + /*** hide picker cicking outside ***/ + document.addEventListener('click', function(e) { + const picker = document.querySelector("#lc-color-picker.lccp-shown"); + if(!picker || e.target.classList.contains('lccp-preview')) { + return true; + } + + // is an element within a trigger? + for (const trigger of document.getElementsByClassName('lccp-preview')) { + if(trigger.contains(e.target)) { + return true; + } + } + + // clicked on the same colorpicker field? keep visible + if(e.target.parentNode && e.target.parentNode.classList && e.target.parentNode.classList.contains('lccp-el-wrap') && document.getElementById(active_trig_id)) { + return true; + } + + // close if clicked element is not in the picker + if(!picker.contains(e.target) && !e.target.classList.contains('lccp-shown')) { + const picker_id = picker.getAttribute('data-trigger-id'), + $input = document.getElementById(picker_id).parentNode.querySelector(right_input_selector); + + $input.dispatchEvent(lccp_ivc_event(picker_id, true)); + } + return true; + }); + + + /* hide picker on screen resizing */ + window.addEventListener('resize', function(e) { + const picker = document.querySelector("#lc-color-picker.lccp-shown"); + if(!picker || window_width == window.innerWidth) { + return true; + } + + // check field value + const picker_id = picker.getAttribute('data-trigger-id'), + $input = document.getElementById(picker_id).parentNode.querySelector(right_input_selector); + + $input.dispatchEvent(lccp_ivc_event(picker_id, true)); + }); + + + /* extend string object to ReplaceArray */ + String.prototype.lccpReplaceArray = function(find, replace) { + let replaceString = this; + let regex; + + for (var i = 0; i < find.length; i++) { + const regex = new RegExp(find[i], "g"); + replaceString = (typeof(replace) == 'object') ? replaceString.replace(regex, replace[i]) : replaceString.replace(regex, replace); + } + return replaceString; + }; + + + + + /*** plugin class ***/ + window.lc_color_picker = function(attachTo, options = {}) { + let cp_uniqid, // unique ID assigned to this colorpicker instance + last_tracked_col; + + this.attachTo = attachTo; + if(!this.attachTo) { + return console.error('You must provide a valid selector string first argument'); + } + + // override options + if(typeof(options) != 'object') { + return console.error('Options must be an object'); + } + + const bkp_opts = options; + options = Object.assign({}, def_opts, options); + + if(typeof(bkp_opts.preview_style) != 'undefined') { + options.preview_style = Object.assign({}, def_opts.preview_style, bkp_opts.preview_style); + } + + + + /* initialize */ + this.init = function() { + const $this = this; + + // Generate style + if(!style_generated) { + this.generate_style(); + style_generated = true; + } + + + // assign to each target element + maybe_querySelectorAll(attachTo).forEach(function(el) { + if(el.tagName == 'INPUT' && el.getAttribute('type') != 'text') { + return; + } + + // do not initialize twice + if(el.parentNode.classList.length && el.parentNode.classList.contains('lcslt_wrap')) { + return; + } + + $this.wrap_element(el); + }); + }; + + + + /* wrap target element to allow trigger display */ + this.wrap_element = function(el) { + cp_uniqid = Math.random().toString(36).substr(2, 9); + + const $this = this, + side_prop = (options.preview_style.side == 'right') ? 'borderRightWidth' : 'borderLeftWidth'; + + let trigger_css = + `width:${ (options.no_input_mode) ? 'calc(100% - '+ parseInt(getComputedStyle(el)['borderRightWidth'], 10) +'px - '+ parseInt(getComputedStyle(el)['borderLeftWidth'], 10) +'px);' : options.preview_style.width +'px;'}` + + + options.preview_style.side +':'+ parseInt(getComputedStyle(el)[side_prop], 10) +'px;'+ + + 'top:'+ parseInt(getComputedStyle(el)['borderTopWidth'], 10) +'px;' + + + 'height: calc(100% - '+ parseInt(getComputedStyle(el)['borderTopWidth'], 10) +'px - '+ parseInt(getComputedStyle(el)['borderBottomWidth'], 10) +'px);'; + + let trigger_upper_css = + trigger_css + + 'background:'+ el.value +';' + + 'border-color:'+ options.preview_style.separator_color +';' + + let div = document.createElement('div'); + div.className = 'lccp-preview-'+ options.preview_style.side; + div.setAttribute('data-for', el.getAttribute('name')); + + // static width from input? + if(options.wrap_width != 'auto') { + div.style.width = (options.wrap_width == 'inherit') ? Math.round(el.getBoundingClientRect().width) + 'px' : options.wrap_width; + } + + const direct_colorpicker_code = (!options.transparency && options.modes.length == 1 && options.modes[0] == 'linear-gradient') ? + '' : ''; + + div.classList.add("lccp-el-wrap"); + div.innerHTML = + '' + + '' + + direct_colorpicker_code; + + el.parentNode.insertBefore(div, el); + div.appendChild(el); + + // input padding + if(!options.no_input_mode) { + if(options.preview_style.side == 'right') { + div.querySelector('input:not([type="color"])').style.paddingRight = options.preview_style.input_padding +'px'; + } else { + div.querySelector('input:not([type="color"])').style.paddingLeft = options.preview_style.input_padding +'px'; + } + } + + + // direct browser colorpicker? track changes + if(div.querySelector('.lccp-direct-cp-f')) { + div.querySelector('.lccp-direct-cp-f').addEventListener("input", (e) => { + + div.querySelector('input:not([type="color"])').value = e.target.value; + div.querySelector('.lccp-preview').style.background = e.target.value; + }); + } + + + // event to show picker + const trigger = document.getElementById(cp_uniqid); + trigger.addEventListener("click", (e) => { + this.show_picker(trigger); + }); + + + + // show on field focus? + if(options.open_on_focus) { + div.querySelector(right_input_selector).addEventListener("focus", (e) => { + if(trigger != active_trigger) { + if(active_trigger) { + document.getElementById('lc-color-picker').classList.remove('lccp-shown'); + active_trigger = null; + } + + $this.debounce('open_on_focus', 10, 'show_picker', trigger); + } + }); + } + + + // sync manually-inputed data in the field + div.querySelector(right_input_selector).addEventListener("keyup", (e) => { + if(e.keyCode == 9 || e.key === 'Enter' || e.keyCode === 13) { + return; + } + + const is_active_trigger_and_opened = (active_trig_id = cp_uniqid && document.querySelector("#lc-color-picker.lccp-shown")) ? true : false; + + active_trigger = trigger; + active_trig_id = cp_uniqid; + + $this.debounce('manual_input_sync', 10, 'val_to_picker', true); + + if(is_active_trigger_and_opened) { + $this.debounce('manual_input_sync_cp', 10, 'append_color_picker', false); + $this.debounce('reopen_picker_after_manual_edit', 10, 'show_picker', trigger); + } + }); + + + // be sure input value is managed on focusout + div.querySelector(right_input_selector).addEventListener("focusout", (e) => { + // not if this field's picker is shown and focus is on "body" + if(document.activeElement.tagName == 'BODY' && document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id="'+ active_trig_id +'"]')) { + return true; + } + + e.target.dispatchEvent(lccp_ivc_event(active_trig_id, true)); + }); + + + // custom event - check field validity and eventually use fallback values + div.querySelector(right_input_selector).addEventListener("lccp_input_val_check", (e) => { + const curr_val = e.target.value, + test = document.createElement('div'); + + test.style.background = curr_val; + let browser_val = test.style.background, + val_to_set; + + if(!curr_val.trim().length || !browser_val) { + if(e.target.value.toLowerCase().indexOf('gradient') === -1) { + val_to_set = (options.fallback_colors[0].toLowerCase().indexOf('rgba') === -1) ? $this.RGB_to_hex(options.fallback_colors[0]) : options.fallback_colors[0]; + } + else { + val_to_set = options.fallback_colors[1]; + } + } + else { + // browser already fixes minor things + browser_val = browser_val.replaceAll('0.', '.').replace(/rgb\([^\)]+\)/g, (rgb) => { + return $this.RGB_to_hex(rgb); + }); + + val_to_set = (browser_val.trim().toLowerCase().substr(0, 4) == 'rgb(') ? $this.RGB_to_hex(browser_val) : browser_val; + } + + if(val_to_set != curr_val) { + e.target.value = val_to_set; + } + + if(typeof(options.on_change) == 'function' && last_tracked_col != val_to_set) { + options.on_change.call($this, val_to_set, e.target); + } + + if(e.detail.picker_id == active_trig_id) { + active_trigger = null; + active_trig_id = null; + } + + + // also hide picker? + const $target = document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id="'+ e.detail.picker_id +'"]'); + if($target) { + + $target.classList.remove('lccp-shown'); + document.getElementById("lc-color-picker").remove(); + } + }); + }; + + + + /* show picker */ + this.show_picker = function(trigger) { + if(document.querySelector('#lc-color-picker.lccp-shown[data-trigger-id="'+ active_trig_id +'"]')) { + document.getElementById("lc-color-picker").remove(); + active_trigger = null; + active_trig_id = null + + return false; + } + + // direct colorpicker usage? Not for Firefox is "show on focus" is enabled + const direct_colorpicker = trigger.parentNode.querySelector('.lccp-direct-cp-f'); + if( + direct_colorpicker && + ( + !options.open_on_focus || + (options.open_on_focus && !navigator.userAgent.toLowerCase().includes('firefox')) + ) + ) { + direct_colorpicker.value = active_solid; + direct_colorpicker.click(); + return true; + } + + + window_width = window.innerWidth; + active_trigger = trigger; + active_trig_id = cp_uniqid; + + this.val_to_picker(); + this.append_color_picker(); + + const picker = document.getElementById('lc-color-picker'), + picker_w = picker.offsetWidth, + picker_h = picker.offsetHeight, + at_offsety = active_trigger.getBoundingClientRect(), + at_h = parseInt(active_trigger.clientHeight, 10) + parseInt(getComputedStyle(active_trigger)['borderTopWidth'], 10) + parseInt(getComputedStyle(active_trigger)['borderBottomWidth'], 10), + y_pos = (parseInt(at_offsety.y, 10) + parseInt(window.pageYOffset, 10) + at_h + 5); + + // left pos control - also checking side overflows + let left = (parseInt(at_offsety.right, 10) - picker_w); + if(left < 0) { + left = 0; + } + + // mobile? show it centered + if(window.innerWidth < 700) { + left = Math.floor( (window.innerWidth - picker_w) / 2); + } + + // top or bottom ? + const y_pos_css = (y_pos + picker_h - document.documentElement.scrollTop < window.innerHeight) ? + 'top:'+ y_pos : + 'transform: translate3d(0, calc((100% + '+ (active_trigger.offsetHeight + 10) +'px) * -1), 0); top:'+ y_pos; + + picker.setAttribute('style', y_pos_css +'px; left: '+ left +'px;'); + picker.classList.add('lccp-shown'); + }; + + + + /* handles input value and prepres data for the picker */ + this.val_to_picker = function(from_manual_input) { + if(!active_trigger) { + return false; + } + const val = active_trigger.parentNode.querySelector(right_input_selector).value.trim().toLowerCase(); + last_tracked_col = val; + + // check validity + let test = document.createElement('div'); + test.style.background = val; + + //// set active colors + // if no value found + if(!val.length || !test.style.background.length) { + active_solid = options.fallback_colors[0]; + active_gradient = options.fallback_colors[1]; + active_mode = 'linear-gradient'; + + /* if(val.indexOf('linear-gradient') !== -1) { + } + else if(val.indexOf('radial-gradient') !== -1) { + active_mode = 'radial-gradient'; + } + else { + active_mode = 'solid'; + } */ + } + else { + + active_mode = 'linear-gradient'; + active_gradient = val; + // find which value type has been passed + /* if(val.indexOf('linear-gradient') !== -1) { + } + else if(val.indexOf('radial-gradient') !== -1) { + active_mode = 'radial-gradient'; + } + else { + active_mode = 'solid'; + } + + if(active_mode == 'solid') { + active_solid = val; + active_gradient = options.fallback_colors[1]; + } + else{ + active_solid = options.fallback_colors[0]; + } */ + } + active_trigger.style.background = val; + + if(!from_manual_input || (from_manual_input && options.open_on_focus)) { + // elaborate solid color data (color and alpha) + //this.load_solid_data(active_solid); + // elaborate gradient data + if(active_gradient) { + this.load_gradient_data(active_gradient); + } + } + }; + + + + /* elaborate solid color data (color and alpha) loading into active_solid and active_opacity */ + this.load_solid_data = function(raw_data) { + active_opacity = 1; + + // rgba + if(raw_data.indexOf('rgba') !== -1) { + const data = this.RGBA_to_hexA(raw_data); + active_solid = data[0]; + active_opacity = data[1]; + } + + // rgb + else if(raw_data.indexOf('rgba') !== -1) { + active_solid = this.RGB_to_hex(raw_data); + } + + // hex + else { + active_solid = this.short_hex_fix(raw_data); + } + }; + + + + /* elaborate gradient data loading into gradient_data */ + this.load_gradient_data = function(raw_data) { + const $this = this; + const is_radial = (raw_data.indexOf('radial-gradient') === -1) ? false : true; + + // solve issues with inner RGB|RGBA and turn everything into RGBA + raw_data = raw_data + .replace(/,\./g, ',0.').replace(/ \./g, ' 0.') + .replace(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)/g, 'rgbaZ($1|$2|$3|$4)') + .replace(/\|\)/g, '|1)'); + + // names to deg + raw_data = raw_data + .replace('top right', '45deg').replace('right top', '45deg') + .replace('bottom right', '135deg').replace('bottom right', '135deg') + .replace('top left', '315deg').replace('left top', '315deg') + .replace('bottom left', '225deg').replace('bottom left', '225deg') + .replace('right', '90deg').replace('left', '270deg').replace('top', '0deg').replace('bottom', '180deg'); + + // be sure deg or shape is defined + if(is_radial && raw_data.indexOf('ellipse') === -1 && raw_data.indexOf('circle') === -1) { + raw_data.replace('\\(', '(ellipse '); + } + if(!is_radial && raw_data.indexOf('deg') === -1) { + raw_data.replace('\\(', '(180deg'); + } + + // process + raw_data = raw_data.lccpReplaceArray( + ['linear-gradient', 'radial-gradient', '', '\\(', 'to', '\\)'], + '' + ); + + // split steps + const raw_steps = raw_data.split(','); + const fallback_multiplier = 100 / raw_steps.length; + + gradient_data.steps = []; + raw_steps.some(function(raw_step, index) { + + // direction on first index + if(!index) { + if(is_radial) { + gradient_data.radial_circle = (raw_step.indexOf('circle') === -1) ? false : true; + } else { + gradient_data.deg = parseInt(raw_step.replace('deg', ''), 10); + } + } + + // {color : null, opacity: null, position : null} + else { + raw_step = raw_step.trim().split(' '); + let position = ''; + + // position + if(raw_step.length < 2) { + if(index === 1) { + position = '0%'; + } + else if(index == (raw_steps.length - 1)) { + position = '100%'; + } + else { + position = (fallback_multiplier * index) +'%'; + } + } + else { + position = raw_step[1]; + } + + // color + let raw_color = raw_step[0], + opacity = 1; + + // normalize to hex + if(raw_color.indexOf('rgbaZ') !== -1) { + const col_arr = $this.RGBA_to_hexA( + raw_color.replace('rgbaZ', 'rgba').replace(/\|/g, ',') + ); + + raw_color = col_arr[0]; + opacity = col_arr[1]; + } + + gradient_data.steps.push({ + color : $this.short_hex_fix(raw_color), + opacity: opacity, + position : parseInt(position, 10) + }); + } + }); + }; + + + + /* handles RGBA string returning a two elements array: hex and alpha */ + this.RGBA_to_hexA = function(raw_data) { + raw_data = raw_data.lccpReplaceArray(['rgba', '\\(', '\\)'], ''); + const rgba_arr = raw_data.split(',') + + let alpha = (typeof(rgba_arr[3]) != 'undefined') ? rgba_arr[3] : '1'; + if(alpha.substring(0, 1) == '.') { + alpha = 0 + alpha; + } + rgba_arr.splice(3, 1); + + return [ + this.RGB_to_hex('rgb('+ rgba_arr.join(',') +')'), + parseFloat(alpha) + ]; + }; + + + + /* convert RGB to hex */ + this.RGB_to_hex = function(rgb) { + rgb = rgb.lccpReplaceArray(['rgb', '\\(', '\\)'], ''); + const rgb_arr = rgb.split(','); + + if(rgb_arr.length < 3) { + return ''; + } + + let r = parseInt(rgb_arr[0].trim(), 10).toString(16), + g = parseInt(rgb_arr[1].trim(), 10).toString(16), + b = parseInt(rgb_arr[2].trim(), 10).toString(16); + + if (r.length == 1) {r = "0" + r;} + if (g.length == 1) {g = "0" + g;} + if (b.length == 1) {b = "0" + b;} + + return this.shorten_hex(r + g + b); + }; + + + + /* if possible, shortenize hex string */ + this.shorten_hex = function(hex) { + hex = hex.replace('#', '').split(''); + + if(hex.length >= 6) { + if( + hex[0] === hex[1] && + hex[2] === hex[3] && + hex[4] === hex[5] + ) { + return '#'+ hex[0] + hex[2] + hex[4]; + } + } + + return '#'+ hex.join(''); + }; + + + + /* convert short hex to full format */ + this.short_hex_fix = function(hex) { + if(hex.length == 4) { + const a = hex.split(''); + hex = a[0] + a[1] + a[1] + a[2] + a[2] + a[3] + a[3]; + } + + return hex.toLowerCase(); + }; + + + + /* convert hex to RGB */ + this.hex_to_RGB = function(h) { + let r = 0, g = 0, b = 0; + + // 3 digits + if (h.length == 4) { + r = "0x" + h[1] + h[1]; + g = "0x" + h[2] + h[2]; + b = "0x" + h[3] + h[3]; + + // 6 digits + } else if (h.length == 7) { + r = "0x" + h[1] + h[2]; + g = "0x" + h[3] + h[4]; + b = "0x" + h[5] + h[6]; + } + + return "rgb("+ +r + ", " + +g + ", " + +b + ")"; + }; + + + + /* convert hex to RGB */ + this.hex_to_RGBA = function(h, opacity) { + if(parseFloat(opacity) === 1) { + return this.shorten_hex(h); + } + + let rgb = this.hex_to_RGB(h); + return rgb.replace('(', 'a(').replace(')', ', '+ opacity.toString().replace('0.', '.') +')'); + }; + + + + + /* append color container picker to the body */ + this.append_color_picker = function(on_manual_input_change = false) { + const $this = this; + + /* if(document.getElementById("lc-color-picker") && !on_manual_input_change) { + document.getElementById("lc-color-picker").remove(); + } */ + + const theme_class = (options.dark_theme) ? 'lccp_dark_theme' : 'lccp_light_theme', + bg = (active_mode == 'solid') ? active_solid : active_gradient, + shown_solid = (active_mode == 'solid') ? active_solid : gradient_data.steps[0].color, + shown_opacity = (active_mode == 'solid') ? active_opacity : (options.transparency) ? gradient_data.steps[0].opacity : null, + print_grad_code = (options.modes.indexOf('linear-gradient') !== -1 || options.modes.indexOf('radial-gradient') !== -1) ? true : false; + + + // start code + let picker = '', + picker_el; + + if(on_manual_input_change && document.getElementById("lc-color-picker")) { + picker_el = document.getElementById("lc-color-picker"); + picker_el.setAttribute('data-mode', active_mode); + picker_el.setAttribute('data-trigger-id', cp_uniqid); + } + else { + picker = '
'; + } + + + // modes select + /* if(options.modes.length >= 1) { + picker += ` +
+ ${ options.labels[1] } + ${ options.labels[2] } + ${ options.labels[3] } +
`; + } */ + + + // gradient wizard + if(print_grad_code) { + picker += ` +
+
+
+ +
+ +
+ angle + + + +
+
+ shape + + Ellipse + Circle +
+
+
`; + } + + + // HTML5 colorpicker + picker += ` +
+ color + +
+ +
+ +
`; + + // opacity cursor + if(options.transparency) { + picker += ` +
+ opacity + + + +
`; + } + + + // append or re-fill + (on_manual_input_change && document.getElementById("lc-color-picker")) ? picker_el.innerHTML = picker : document.body.insertAdjacentHTML('beforeend', picker +'
'); + + + // modes change + if(options.modes.length >= 1) { + for (const mode of document.querySelectorAll('#lccp_modes_wrap span')) { + mode.addEventListener("click", (e) => { $this.mode_change( e.target, e.target.getAttribute('data-mode')) }); + } + } + + // print steps and add gradient step action + if(print_grad_code) { + gradient_data.steps.some(function(step, index) { + $this.add_draggable_element(index, step.position, step.color); + }); + + document.querySelector('.lccp_gradient:not(.lccp_gradient-bg)').addEventListener("click", (e) => {this.add_gradient_step(e) }); + } + + // angle actions + if(options.modes.indexOf('linear-gradient') !== -1) { + document.querySelector('.pccp_deg_f_wrap input[type=range]').addEventListener("input", (e) => {this.track_deg_range_change(e)}); + document.querySelector('.pccp_deg_f_wrap input[name=deg-num]').addEventListener("change", (e) => {this.track_deg_num_change(e)}); + document.querySelector('.pccp_deg_f_wrap input[name=deg-num]').addEventListener("keyup", (e) => { + this.debounce('deg_f_change', 500, 'track_deg_num_change', e); + }); + } + + // circle actions + if(options.modes.indexOf('radial-gradient') !== -1) { + for (const mode of document.querySelectorAll('.pccp_circle_f_wrap span')) { + mode.addEventListener("click", (e) => { $this.set_ellipse_circle( e.target, e.target.getAttribute('data-val')) }); + } + } + + // color actions + document.querySelector('.pccp_color_f_wrap input[type="color"]').addEventListener("input", (e) => {this.track_color_change(e)}); + document.querySelector('.pccp_color_f_wrap input[type="color"]').addEventListener("change", (e) => {this.track_color_change(e)}); + document.querySelector('.pccp_color_f_wrap input[name=hex]').addEventListener("keyup", (e) => { + this.debounce('hex_f_change', 600, 'track_color_hex_change', e); + }); + + // transparency actions + if(options.transparency) { + document.querySelector('.pccp_opacity_f_wrap input[type=range]').addEventListener("input", (e) => {this.track_opacity_range_change(e)}); + document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').addEventListener("change", (e) => {this.track_opacity_num_change(e)}); + document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').addEventListener("keyup", (e) => { + this.debounce('opacity_f_change', 500, 'track_opacity_num_change', e); + }); + } + }; + + + + /*** add draggable element ***/ + this.add_draggable_element = function(rel_step_num, position, color) { + const $this = this, + container = document.querySelector('.lccp_gradient_ranges'), + sel_class = (!rel_step_num) ? 'lccp_sel_step' : '', + del_btn_vis = (gradient_data.steps.length > 2) ? '' : 'style="display: none;"' + + container.innerHTML += + ''+ + ''+ + ''; + + let active = false; + + ////// + const dragStart = function(range_id, el, e) { + active = range_id; + }; + + const dragEnd = function() { + active = false; + $this.apply_changes(); + }; + + const drag = function(range_id, range, e) { + if (active !== false && range_id == active) { + e.preventDefault(); + const rect = container.getBoundingClientRect(); + + let new_pos = (e.type === "touchmove") ? (e.touches[0].clientX - rect.left) : (e.clientX - rect.left); + new_pos = Math.round((100 * new_pos) / container.offsetWidth); + + if(new_pos < 0) {new_pos = 0;} + else if(new_pos > 100) {new_pos = 100;} + + // limit positions basing on previous and next step + const min_pos = (!range_id) ? 0 : gradient_data.steps[ range_id-1 ].position; + const max_pos = (range_id == (gradient_data.steps.length - 1)) ? 100 : gradient_data.steps[ range_id+1 ].position; + + if(new_pos < min_pos) {new_pos = min_pos + 1;} + else if(new_pos > max_pos) {new_pos = max_pos - 1;} + + gradient_data.steps[ range_id ].position = new_pos; + range.style.left = new_pos +'%'; + + $this.apply_gradient_changes(); + } + };+ + ///// + + document.querySelectorAll('.lccp_gradient_range').forEach(range => { + const step_num = parseInt(range.getAttribute('data-step-num'), 10); + + range.removeEventListener("touchstart", null); + range.removeEventListener("touchend", null); + range.removeEventListener("touchmove", null); + range.removeEventListener("click", null); + + range.removeEventListener("mousedown", null); + range.removeEventListener("mouseup", null); + + range.addEventListener("touchstart", (e) => {dragStart(step_num, e.target, e)}); + range.addEventListener("mousedown", (e) => {dragStart(step_num, e.target, e)}); + + range.addEventListener("click", (e) => {$this.select_gradient_color(step_num)}); + + container.addEventListener("touchmove", (e) => {drag(step_num, range, e)}); + container.addEventListener("mousemove", (e) => {drag(step_num, range, e)}); + + range.addEventListener("mouseup", (e) => {dragEnd()}); + range.addEventListener("touchend", (e) => {dragEnd()}); + document.addEventListener("mouseup", (e) => {dragEnd()}); + }); + + + // remove step handler + document.querySelectorAll('.lccp_gradient_range img').forEach((btn) => { + + btn.addEventListener("click", (e) => { + if(document.querySelectorAll('.lccp_gradient_range').length < 3) { + return false; + } + + // wait a bit to not interfere with global handler for picker closing + setTimeout(() => { + const parent = e.target.parentNode, + step_num = parseInt(parent.getAttribute('data-step-num'), 10), + to_select = (!step_num) ? 0 : step_num - 1; + + gradient_data.steps.splice(step_num, 1); + + // clean and restart + document.querySelectorAll('.lccp_gradient_range').forEach(r => r.remove()); + + gradient_data.steps.some(function(step, index) { + $this.add_draggable_element(index, step.position, step.color); + }); + + // select newly added element + document.querySelector('.lccp_gradient_range[data-step-num="'+ to_select +'"]').click(); + + this.apply_gradient_changes(true); + }, 20); + }); + }); + }; + + + + /* select gradient color */ + this.select_gradient_color = function(step_num) { + sel_grad_step = step_num; + + document.querySelectorAll('.lccp_gradient_range').forEach(m => m.classList.remove('lccp_sel_step')); + document.querySelector('.lccp_gradient_range[data-step-num="'+ step_num +'"]').classList.add('lccp_sel_step'); + + active_solid = gradient_data.steps[ step_num ].color; + active_opacity = gradient_data.steps[ step_num ].opacity; + + document.querySelector('#lc-color-picker input[type="color"]').value = active_solid; + document.querySelector('.pccp_color_f_wrap input[name=hex]').value = active_solid; + + if(options.transparency) { + document.querySelector('.pccp_opacity_f_wrap input[type=range]').value = active_opacity; + document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').value = active_opacity; + } + }; + + + + /* apply changes to gradient, after a color/opacity/degree update */ + this.apply_gradient_changes = function(also_apply_changes) { + const $this = this; + + let new_gradient = active_mode+'('; + new_gradient += (active_mode == 'linear-gradient') ? gradient_data.deg+'deg' : (gradient_data.radial_circle) ? 'circle' : 'ellipse'; + new_gradient += ', '; + + let colors_part = [] + gradient_data.steps.some(function(step, index) { + + let to_add = (options.transparency) ? $this.hex_to_RGBA(step.color, step.opacity) : $this.shorten_hex(step.color); + + if( + gradient_data.steps.length > 2 || + ( + gradient_data.steps.length <= 2 && + ( + (!index && parseInt(step.position, 10)) || + (index && index < (gradient_data.steps.length - 1)) || + (index == (gradient_data.steps.length - 1) && parseInt(step.position, 10) != 100) + ) + ) + ) { + to_add += ' '+ step.position +'%'; + } + + colors_part.push( to_add ); + }); + + active_gradient = new_gradient + colors_part.join(', ') + ')'; + + if(document.querySelector('.lccp_gradient:not(.lccp_gradient-bg)')) { + document.querySelector('.lccp_gradient:not(.lccp_gradient-bg)').style.background = active_gradient; + } + + if(also_apply_changes) { + this.apply_changes(); + } + }; + + + + /* apply changes to target field */ + this.apply_changes = function() { + if(!active_trigger) { + return false; + } + let val = ''; + + // apply everything to picker global vars + if(active_mode == 'solid') { + val = this.shorten_hex(active_solid); + + if(options.transparency && document.querySelector('.pccp_opacity_f_wrap input[type=range]')) { + active_opacity = document.querySelector('.pccp_opacity_f_wrap input[type=range]').value; + val = this.hex_to_RGBA(val, active_opacity); + } + } + else { + val = active_gradient; + } + + // apply + active_trigger.style.background = val; + + const field = active_trigger.parentNode.querySelector(right_input_selector), + old_val = field.value; + + if(old_val != val) { + field.value = val; + last_tracked_col = val; + + if(typeof(options.on_change) == 'function') { + + if(typeof(debounced_vars['on_change_cb']) != undefined && debounced_vars['on_change_cb']) { + clearTimeout(debounced_vars['on_change_cb']); + } + debounced_vars['on_change_cb'] = setTimeout(() => { + options.on_change.call(this, val, field); + }, 300); + } + } + }; + + + + + + + // HANDLERS + + // fields toggle basing on modes change + this.mode_change = function(el, new_mode) { + if(active_mode == new_mode) { + return false; + } + let color, opacity; + + // from gradient to solid + if(new_mode == 'solid') { + color = active_solid; + if(options.transparency) { + opacity = active_opacity; + } + } + else { + color = gradient_data.steps[0].color; + if(options.transparency) { + opacity = gradient_data.steps[0].opacity; + } + } + + document.querySelector('#lc-color-picker input[type="color"]').value = color; + document.querySelector('.pccp_color_f_wrap input[name=hex]').value = color; + + if(options.transparency) { + document.querySelector('.pccp_opacity_f_wrap input[type=range]').value = opacity; + document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').value = opacity; + } + + // toggle grad fields + if(options.modes.length >= 1) { + document.querySelector('.pccp_deg_f_wrap').style.display = (new_mode == 'linear-gradient') ? 'flex' : 'none'; + document.querySelector('.pccp_circle_f_wrap').style.display = (new_mode == 'radial-gradient') ? 'block' : 'none'; + } + + // toogle gradient wizard + if(options.modes.indexOf('linear-gradient') !== -1 || options.modes.indexOf('radial-gradient') !== -1) { + document.querySelector('.lccp_gradient_wizard').style.display = (new_mode != 'solid') ? 'block' : 'none'; + } + + document.querySelectorAll('#lccp_modes_wrap span').forEach(m => m.classList.remove('lccp_sel_mode')); + el.classList.add('lccp_sel_mode'); + + active_mode = new_mode; + (new_mode == 'solid') ? this.apply_changes() : this.apply_gradient_changes(true); + }; + + + // add gradient step + this.add_gradient_step = function(e) { + const $this = this, + pos = Math.round((100 * e.layerX) / e.target.offsetWidth); + + // inject in actual steps + let index = 0; + for(let step of gradient_data.steps) { + + if(step.position > pos) { + const step_data = { + color : (index - 1 < 0) ? step.color : gradient_data.steps[(index - 1)].color, + opacity : 1, + position : pos + } + + gradient_data.steps.splice(index, 0, step_data); + break; + } + + index++; + } + document.querySelectorAll('.lccp_gradient_range').forEach(r => r.remove()); + + gradient_data.steps.some(function(step, index) { + $this.add_draggable_element(index, step.position, step.color); + }); + + // select newly added element + document.querySelector('.lccp_gradient_range[data-step-num="'+ index +'"]').click(); + + this.apply_gradient_changes(true); + }; + + + // apply ellipse or circle + this.set_ellipse_circle = function(el, new_opt) { + if(gradient_data.radial_circle && new_opt == 'circle' || !gradient_data.radial_circle && new_opt != 'circle') { + return false; + } + gradient_data.radial_circle = !gradient_data.radial_circle; + + document.querySelectorAll('.pccp_circle_f_wrap span').forEach(m => m.classList.remove('pcpp_circle_btn_active')); + el.classList.add('pcpp_circle_btn_active'); + + this.apply_gradient_changes(true); + }; + + + // track opacity range fields change + this.track_deg_range_change = function(e) { + document.querySelector('.pccp_deg_f_wrap input[name=deg-num]').value = e.target.value; + + gradient_data.deg = e.target.value; + this.apply_gradient_changes(true); + }; + this.track_deg_num_change = function(e) { + let val = parseFloat(e.target.value); + if(isNaN(val) || val < 0 || val > 360) { + val = 90; + } + + e.target.value = val; + if(document.querySelector('.pccp_deg_f_wrap input[type=range]')) { + document.querySelector('.pccp_deg_f_wrap input[type=range]').value = val; + } + + gradient_data.deg = val; + this.apply_gradient_changes(true); + }; + + + // track opacity range fields change + this.track_color_change = function(e) { + const val = e.target.value.toLowerCase(); + document.querySelector('.pccp_color_f_wrap input[name=hex]').value = val; + + this.apply_color_change(val); + }; + this.track_color_hex_change = function(e) { + let val = this.short_hex_fix(e.target.value); + + if(val.match(/^#[a-f0-9]{6}$/i) === null) { + val = active_solid.toLowerCase(); + } + + e.target.value = val; + document.querySelector('#lc-color-picker input[type="color"]').value = val; + + this.apply_color_change(val); + }; + this.apply_color_change = function(val) { + if(active_mode == 'solid') { + active_solid = val; + this.apply_changes(); + } + else { + gradient_data.steps[ sel_grad_step ].color = val; + + document.querySelector('.lccp_sel_step').style.background = val; + this.apply_gradient_changes(true); + } + }; + + + // track opacity range fields change + this.track_opacity_range_change = function(e) { + document.querySelector('.pccp_opacity_f_wrap input[name=opacity-num]').value = e.target.value; + this.alter_hex_opacity(e.target.value); + }; + this.track_opacity_num_change = function(e) { + let val = parseFloat(e.target.value); + if(isNaN(val) || val < 0 || val > 1) { + val = 0.5; + } + + e.target.value = val; + + if(document.querySelector('.pccp_opacity_f_wrap input[type=range]')) { + document.querySelector('.pccp_opacity_f_wrap input[type=range]').value = val; + this.alter_hex_opacity(val); + } + }; + this.alter_hex_opacity = function(opacity) { + document.querySelector('#lc-color-picker input[type="color"]').style.opacity = opacity; + + if(active_mode == 'solid') { + active_opacity = opacity; + this.apply_changes(); + } + else { + gradient_data.steps[ sel_grad_step ].opacity = opacity; + this.apply_gradient_changes(true); + } + }; + + + + + + /* + * UTILITY FUNCTION - debounce action to run once after X time + * + * @param (string) action_name + * @param (int) timing - milliseconds to debounce + * @param (string) - class method name to call after debouncing + * @param (mixed) - extra parameters to pass to callback function + */ + this.debounce = function(action_name, timing, cb_function, cb_params) { + if( typeof(debounced_vars[ action_name ]) != 'undefined' && debounced_vars[ action_name ]) { + clearTimeout(debounced_vars[ action_name ]); + } + const $this = this; + + debounced_vars[ action_name ] = setTimeout(() => { + $this[cb_function].call($this, cb_params); + }, timing); + }; + + + + + + /* CSS - creates inline CSS into the page */ + this.generate_style = function() { + const transp_bg_img = "url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAQDAwMDAwQDAwQGBAMEBgcFBAQFBwgGBgcGBggKCAkJCQkICgoMDAwMDAoMDA0NDAwRERERERQUFBQUFBQUFBT/2wBDAQQFBQgHCA8KCg8UDg4OFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAoACgDAREAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAUGCP/EACIQAQAABQMFAQAAAAAAAAAAAAAFFUNjgqLB4RESEzVRkf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDv4AE6K0stgTgAaIAE6K0stgTgAUZra1cATW1q4A9na8WXXu/PgEqu6eQJVd08gnAAowqrjuCiADOgAowqrjuCiAD/2Q==')"; + + document.head.insertAdjacentHTML('beforeend', +``); + }; + + + // init when called + this.init(); + }; + + + + + + + // UTILITIES + + // sanitize "selector" parameter allowing both strings and DOM objects + const maybe_querySelectorAll = (selector) => { + + if(typeof(selector) != 'string') { + if(selector instanceof Element) { // JS or jQuery + return [selector]; + } + else { + let to_return = []; + + for(const obj of selector) { + if(obj instanceof Element) { + to_return.push(obj); + } + } + return to_return; + } + } + + // clean problematic selectors + (selector.match(/(#[0-9][^\s:,]*)/g) || []).forEach(function(n) { + selector = selector.replace(n, '[id="' + n.replace("#", "") + '"]'); + }); + + return document.querySelectorAll(selector); + }; + + +})()); diff --git a/block_dash.php b/block_dash.php index 61bcc8e..a878a85 100644 --- a/block_dash.php +++ b/block_dash.php @@ -68,7 +68,7 @@ public function specialization() { } else { $this->title = get_string('newblock', 'block_dash'); } - + try { $bb = block_builder::create($this); if ($bb->is_collapsible_content_addon()) { @@ -121,6 +121,18 @@ public function instance_config_save($data, $nolongerused = false) { file_save_draft_area_files($data->backgroundimage, $this->context->id, 'block_dash', 'images', 0, ['subdirs' => 0, 'maxfiles' => 1]); } + if (isset($data->dash_configure_options) && isset($data->data_source_idnumber)) { + $datasource = data_source_factory::build_data_source($data->data_source_idnumber, + $this->context); + if ($datasource) { + if (method_exists($datasource, 'set_default_preferences')) { + $configpreferences = ['config_preferences' => []]; + $datasource->set_default_preferences($configpreferences); + $data->preferences = $configpreferences['config_preferences']; + } + } + unset($data->dash_configure_options); + } parent::instance_config_save($data, $nolongerused); } @@ -194,6 +206,7 @@ public function get_content() { $this->content->text = is_siteadmin() ? get_string('disableallmessage', 'block_dash') : ''; return $this->content; } + try { $bb = block_builder::create($this); @@ -228,7 +241,10 @@ public function get_content() { public function html_attributes() { $attributes = parent::html_attributes(); if (isset($this->config->css_class)) { - $attributes['class'] .= ' ' . $this->config->css_class; + $cssclasses = explode(",", $this->config->css_class); + foreach ($cssclasses as $class) { + $attributes['class'] .= ' ' . trim($class); + } } if (isset($this->config->width)) { $attributes['class'] .= ' dash-block-width-' . $this->config->width; @@ -278,13 +294,33 @@ public function get_extra_css() { $blockcss[] = sprintf('background-image: url(%s);', $this->get_background_image_url()); } } else if ($backgroundgradient) { - $blockcss[] = sprintf('background: %s', $this->config->backgroundgradient); + $blockcss[] = sprintf('background-image: %s;', $this->config->backgroundgradient); + } + + // Background postition. + if (isset($this->config->backgroundimage_position)) { + $bgpostion = $this->config->backgroundimage_position; + $bgpostionvalue = ($bgpostion == 'custom') ? $this->config->backgroundimage_customposition : $bgpostion; + $blockcss[] = sprintf('background-position: %s;', $bgpostionvalue); + } + + // Background size. + if (isset($this->config->backgroundimage_size)) { + $bgsize = $this->config->backgroundimage_size; + $bgsizevalue = ($bgsize == 'custom') ? $this->config->backgroundimage_customsize : $bgsize; + $blockcss[] = sprintf('background-size: %s;', $bgsizevalue); } if (isset($this->config->css) && is_array($this->config->css)) { foreach ($this->config->css as $property => $value) { if (!empty($value)) { - $blockcss[] = sprintf('%s: %s;', $property, $value); + if ($property == 'border') { + if ($this->config->border_option) { + $blockcss[] = sprintf('%s: %s;', $property, $value); + } + } else { + $blockcss[] = sprintf('%s: %s;', $property, $value); + } } } } diff --git a/classes/external.php b/classes/external.php index 258a6b5..1eb0b16 100644 --- a/classes/external.php +++ b/classes/external.php @@ -103,10 +103,10 @@ public static function get_block_content($blockinstanceid, $filterformdata, $pag $public = false; $blockinstance = $DB->get_record('block_instances', ['id' => $params['block_instance_id']]); $block = block_instance($blockinstance->blockname, $blockinstance); - if (strpos($block->instance->pagetypepattern, 'local-dash-dashboard') !== false) { - if ($dashboard = \local_dash\model\dashboard::get_record( + if (strpos($block->instance->pagetypepattern, 'dashaddon-dashboard') !== false) { + if ($dashboard = \dashaddon_dashboard\model\dashboard::get_record( ['shortname' => $block->instance->defaultregion])) { - if ($dashboard->get('permission') == \local_dash\model\dashboard::PERMISSION_PUBLIC) { + if ($dashboard->get('permission') == \dashaddon_dashboard\model\dashboard::PERMISSION_PUBLIC) { $public = true; } } diff --git a/classes/local/dash_framework/structure/course_category_table.php b/classes/local/dash_framework/structure/course_category_table.php deleted file mode 100644 index 94fe06f..0000000 --- a/classes/local/dash_framework/structure/course_category_table.php +++ /dev/null @@ -1,134 +0,0 @@ -. - -/** - * Class course category table. - * - * @package block_dash - * @copyright 2024 bdecent gmbh - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace block_dash\local\dash_framework\structure; - -use block_dash\local\dash_framework\structure\field; -use block_dash\local\dash_framework\structure\field_interface; -use block_dash\local\dash_framework\structure\table; -use block_dash\local\data_grid\field\attribute\category_image_url_attribute; -use block_dash\local\data_grid\field\attribute\category_recent_course_attribute; -use block_dash\local\data_grid\field\attribute\identifier_attribute; -use block_dash\local\data_grid\field\attribute\image_attribute; -use block_dash\local\data_grid\field\attribute\image_url_attribute; -use block_dash\local\data_grid\field\attribute\moodle_url_attribute; -use block_dash\local\data_grid\field\attribute\link_attribute; -use block_dash\local\data_grid\field\attribute\linked_data_attribute; -use block_dash\local\data_grid\field\attribute\widget_attribute; -use lang_string; -use moodle_url; - -/** - * Class course_category_table. - * - * @package block_dash - */ -class course_category_table extends table { - - /** - * Build a new table. - */ - public function __construct() { - parent::__construct('course_categories', 'cc'); - } - - /** - * Get human readable title for table. - * - * @return string - */ - public function get_title(): string { - return get_string('tablealias_cc', 'block_dash'); - } - - /** - * Define the fields available in the reports for this table data source. - * - * @return field_interface[] - */ - public function get_fields(): array { - return [ - new field('id', new lang_string('category'), $this, null, [ - new identifier_attribute(), - ]), - - // Category name. - new field('name', new lang_string('categoryname'), $this, 'cc.name'), - - // Category name linked. - new field('categoryurl', new lang_string('categoryurl', 'block_dash'), $this, 'cc.name', [ - new moodle_url_attribute(['url' => new moodle_url('/course/management.php', ['categoryid' => 'cc_id'])]), - new link_attribute(['label_field' => 'cc_name']) - ]), - - // Category ID number. - new field('idnumber', new lang_string('idnumber'), $this), - - // Description. - new field('description', new lang_string('summary'), $this, 'cc.description, cc.descriptionformat', [ - new widget_attribute([ - 'callback' => function($coursecat, $data) { - if (!isset($coursecat->cc_descriptionformat)) { - $descriptionformat = FORMAT_MOODLE; - } else { - $descriptionformat = $coursecat->cc_descriptionformat; - } - - $options = array('noclean' => true, 'overflowdiv' => true); - $context = \context_coursecat::instance($coursecat->cc_id); - $options['context'] = $context; - $text = file_rewrite_pluginfile_urls($coursecat->description, - 'pluginfile.php', $context->id, 'coursecat', 'description', null); - return format_text($text, $descriptionformat, $options); - } - ]) - ]), - - // Category image linked. - new field('image_link', new lang_string('categoryimagelink', 'block_dash'), $this, 'cc.id', [ - new category_image_url_attribute(), new image_attribute(), - new linked_data_attribute(['url' => new moodle_url('/course/management.php', ['categoryid' => 'cc_id'])]), - ]), - - // Category image. - new field('image', new lang_string('categoryimage', 'block_dash'), $this, 'cc.id', [ - new category_image_url_attribute(), new image_attribute(), - ]), - - // Category image. - new field('imageurl', new lang_string('categoryimageurl', 'block_dash'), $this, 'cc.id', [ - new category_image_url_attribute(), new image_url_attribute() - ]), - - // Number of courses. - new field('coursecount', new lang_string('categorycoursecount', 'block_dash'), $this, null), - - // Most recent course name (by created date). - new field('mostrecentcourse', new lang_string('recentcoursename', 'block_dash'), $this, 'cc.id', [ - new category_recent_course_attribute() - ]), - - ]; - } -} diff --git a/classes/local/data_source/categories_data_source.php b/classes/local/data_source/categories_data_source.php deleted file mode 100644 index cf70665..0000000 --- a/classes/local/data_source/categories_data_source.php +++ /dev/null @@ -1,93 +0,0 @@ -. - -/** - * Class categories_data_source. - * - * @package block_dash - * @copyright 2024 bdecent gmbh - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace block_dash\local\data_source; - -use block_dash\local\dash_framework\query_builder\builder; -use block_dash\local\dash_framework\structure\course_category_table; -use block_dash\local\data_grid\filter\filter_collection; -use block_dash\local\data_grid\filter\filter_collection_interface; -use coding_exception; -use context; -use local_dash\data_grid\filter\course_category_condition; - -/** - * Class categories_data_source. - * - * @package block_dash - */ -class categories_data_source extends abstract_data_source { - - /** - * Constructor. - * - * @param context $context - */ - public function __construct(context $context) { - $this->add_table(new course_category_table()); - - parent::__construct($context); - } - - /** - * Get human readable name of data source. - * - * @return string - * @throws coding_exception - */ - public function get_name() { - return get_string('category'); - } - - /** - * Return query template for retrieving category info. - * - * @return builder - * @throws coding_exception - */ - public function get_query_template(): builder { - - $builder = new builder(); - $builder - ->select('cc.id', 'cc_id') - ->from('course_categories', 'cc'); - - return $builder; - } - - /** - * Build and return filter collection. - * - * @return filter_collection_interface - * @throws coding_exception - */ - public function build_filter_collection() { - - $filtercollection = new filter_collection(get_class($this), $this->get_context()); - - $filtercollection->add_filter(new course_category_condition('c_course_categories_condition', 'cc.id')); - - return $filtercollection; - } -} diff --git a/classes/local/data_source/users_data_source.php b/classes/local/data_source/users_data_source.php index 0a9d896..97e5197 100644 --- a/classes/local/data_source/users_data_source.php +++ b/classes/local/data_source/users_data_source.php @@ -78,7 +78,7 @@ public function get_name() { * @throws coding_exception */ public function get_query_template(): builder { - global $CFG; + global $CFG, $DB; require_once("$CFG->dirroot/user/profile/lib.php"); @@ -151,6 +151,8 @@ public function build_filter_collection() { if (block_dash_has_pro()) { $filtercollection->add_filter(new \local_dash\data_grid\filter\parent_role_condition('parentrole', 'u.id')); + $filtercollection->add_filter(new \local_dash\data_grid\filter\cohort_condition('cohort', 'u.id')); + $filtercollection->add_filter(new \local_dash\data_grid\filter\users_mycohort_condition('users_mycohort', 'u.id')); } foreach (profile_get_custom_fields() as $field) { @@ -162,4 +164,19 @@ public function build_filter_collection() { return $filtercollection; } + + /** + * Set the default preferences of the User datasource, force the set the default settings. + * + * @param array $data + * @return array + */ + public function set_default_preferences(&$data) { + $configpreferences = $data['config_preferences']; + $configpreferences['available_fields']['u_firstname']['visible'] = true; + $configpreferences['available_fields']['u_lastname']['visible'] = true; + $configpreferences['available_fields']['u_email']['visible'] = true; + $configpreferences['available_fields']['u_lastlogin']['visible'] = true; + $data['config_preferences'] = $configpreferences; + } } diff --git a/edit_form.php b/edit_form.php index bed8f41..9cb43da 100644 --- a/edit_form.php +++ b/edit_form.php @@ -42,6 +42,7 @@ class block_dash_edit_form extends block_edit_form { * @throws coding_exception */ protected function specific_definition($mform) { + global $CFG; // Fields for editing HTML block title and contents. $mform->addElement('header', 'dashconfigheader', get_string('blocksettings', 'block')); @@ -92,23 +93,85 @@ protected function specific_definition($mform) { $mform->addElement('text', 'config_css_class', get_string('cssclass', 'block_dash')); $mform->setType('config_css_class', PARAM_TEXT); + $mform->setDefault('config_css_class', get_config('block_dash', 'cssclass')); + $mform->addHelpButton('config_css_class', 'cssclass', 'block_dash'); $mform->addElement('filemanager', 'config_backgroundimage', get_string('backgroundimage', 'block_dash'), null, ['subdirs' => 0, 'maxfiles' => 1, 'accepted_types' => ['image'], 'return_types' => FILE_INTERNAL | FILE_EXTERNAL]); $mform->addHelpButton('config_backgroundimage', 'backgroundimage', 'block_dash'); - $mform->addElement('text', 'config_backgroundgradient', get_string('backgroundgradient', 'block_dash'), + $postions = [ + 'initial' => get_string('initial', 'block_dash'), + 'left top' => get_string('lefttop', 'block_dash'), + 'left center' => get_string('leftcenter', 'block_dash'), + 'left bottom' => get_string('leftbottom', 'block_dash'), + 'right top' => get_string('righttop', 'block_dash'), + 'right center' => get_string('rightcenter', 'block_dash'), + 'right bottom' => get_string('rightbottom', 'block_dash'), + 'center top' => get_string('centertop', 'block_dash'), + 'center center' => get_string('centercenter', 'block_dash'), + 'center bottom' => get_string('centerbottom', 'block_dash'), + 'custom' => get_string('strcustom', 'block_dash'), + ]; + // Module background image poisiton. + $mform->addElement('select', 'config_backgroundimage_position', get_string('backgroundposition', 'block_dash'), + $postions); + $mform->setType('config_backgroundimage_position', PARAM_RAW); + $mform->addHelpButton('config_backgroundimage_position', 'backgroundposition', 'block_dash'); + + // Module background image custom poisiton. + $mform->addElement('text', 'config_backgroundimage_customposition', + get_string('designercustombgposition', 'block_dash')); + $mform->setType('config_backgroundimage_customposition', PARAM_RAW); + $mform->addHelpButton('config_backgroundimage_customposition', 'backgroundposition', 'block_dash'); + $mform->hideIf('config_backgroundimage_customposition', 'config_backgroundimage_position', 'neq', 'custom'); + + // Module background image size. + $sizes = [ + 'auto' => get_string('auto', 'block_dash'), + 'cover' => get_string('cover', 'block_dash'), + 'contain' => get_string('contain', 'block_dash'), + 'custom' => get_string('strcustom', 'block_dash'), + ]; + $mform->addElement('select', 'config_backgroundimage_size', get_string('backgroundsize', + 'block_dash'), $sizes); + $mform->setType('config_backgroundimage_size', PARAM_RAW); + $mform->addHelpButton('config_backgroundimage_size', 'backgroundsize', 'block_dash'); + + // Module background image custom size. + $mform->addElement('text', 'config_backgroundimage_customsize', get_string('designercustombgsize', 'block_dash')); + $mform->setType('config_backgroundimage_customsize', PARAM_RAW); + $mform->addHelpButton('config_backgroundimage_customsize', 'backgroundsize', 'block_dash'); + $mform->hideIf('config_backgroundimage_customsize', 'config_backgroundimage_size', 'neq', 'custom'); + + require_once($CFG->dirroot.'/blocks/dash/form/gradientpicker.php'); + MoodleQuickForm::registerElementType('dashgradientpicker', $CFG->dirroot.'/blocks/dash/form/gradientpicker.php', + 'moodlequickform_dashgradientpicker'); + + $mform->addElement('dashgradientpicker', 'config_backgroundgradient', get_string('backgroundgradient', 'block_dash'), ['placeholder' => 'linear-gradient(#e66465, #9198e5)']); $mform->setType('config_backgroundgradient', PARAM_TEXT); $mform->addHelpButton('config_backgroundgradient', 'backgroundgradient', 'block_dash'); - $mform->addElement('text', 'config_headerfootercolor', get_string('fontcolor', 'block_dash')); - $mform->setType('config_headerfootercolor', PARAM_TEXT); + require_once($CFG->dirroot.'/blocks/dash/form/element-colorpicker.php'); + MoodleQuickForm::registerElementType('dashcolorpicker', $CFG->dirroot.'/blocks/dash/form/element-colorpicker.php', + 'moodlequickform_dashcolorpicker'); + + $mform->addElement('dashcolorpicker', 'config_headerfootercolor', get_string('fontcolor', 'block_dash')); + $mform->setType('config_headerfootercolor', PARAM_RAW); $mform->addHelpButton('config_headerfootercolor', 'fontcolor', 'block_dash'); - $mform->addElement('text', 'config_css[border]', get_string('border', 'block_dash')); + $mform->addElement('select', 'config_border_option', get_string('border_option', 'block_dash'), [ + 0 => get_string('disable'), + 1 => get_string('enable'), + ]); + $mform->setType('config_border_option', PARAM_INT); + $mform->addHelpButton('config_border_option', 'border_option', 'block_dash'); + + $mform->addElement('text', 'config_css[border]', get_string('bordervalue', 'block_dash')); $mform->setType('config_css[border]', PARAM_TEXT); $mform->addHelpButton('config_css[border]', 'border', 'block_dash'); + $mform->hideIf('config_css[border]', 'config_border_option', 'eq', 0); $mform->addElement('text', 'config_css[min-height]', get_string('minheight', 'block_dash')); $mform->setType('config_css[min-height]', PARAM_TEXT); @@ -147,6 +210,8 @@ public function add_datasource_group(&$mform, $config) { if (!isset($config->data_source_idnumber)) { self::dash_features_list($mform, $this->block->context, $this->page); + $mform->addElement('hidden', 'config_dash_configure_options', 1); + $mform->setType('config_dash_configure_options', PARAM_INT); } else { if ($ds = data_source_factory::build_data_source($config->data_source_idnumber, @@ -175,20 +240,21 @@ public static function dash_features_list(&$mform, $context, $page) { // Group of datasources. if (has_capability('block/dash:managedatasource', $context)) { $datasources = data_source_factory::get_data_source_form_options(); - // Description of the datasources. $group[] = $mform->createElement('html', html_writer::tag('p', get_string('datasourcedesc', 'block_dash'), ['class' => 'dash-source-desc'])); $group[] = $mform->createElement('html', html_writer::start_div('datasource-content')); foreach ($datasources as $id => $source) { - $group[] = $mform->createElement('html', html_writer::start_div('datasource-item')); - $group[] = $mform->createElement('radio', 'config_data_source_idnumber', '', $source['name'], $id); - if ($help = $source['help']) { - $helpcontent = $OUTPUT->help_icon($help['name'], $help['component'], $help['name']); - $group[] = $mform->createElement('html', $helpcontent); + if (block_dash_visible_addons($id)) { + $group[] = $mform->createElement('html', html_writer::start_div('datasource-item')); + $group[] = $mform->createElement('radio', 'config_data_source_idnumber', '', $source['name'], $id); + if ($help = $source['help']) { + $helpcontent = $OUTPUT->help_icon($help['name'], $help['component'], $help['name']); + $group[] = $mform->createElement('html', $helpcontent); + } + $group[] = $mform->createElement('html', html_writer::end_div()); } - $group[] = $mform->createElement('html', html_writer::end_div()); } $group[] = $mform->createElement('html', html_writer::end_div()); $mform->addGroup($group, 'datasources', get_string('buildown', 'block_dash'), [' '], false); @@ -203,12 +269,14 @@ public static function dash_features_list(&$mform, $context, $page) { html_writer::tag('p', get_string('widgetsdesc', 'block_dash'), ['class' => 'dash-source-desc'])); $widgets[] = $mform->createElement('html', html_writer::start_div('datasource-content')); foreach ($widgetlist as $id => $source) { - $widgets[] = $mform->createElement('html', html_writer::start_div('datasource-item')); - $widgets[] = $mform->createElement('radio', 'config_data_source_idnumber', '', $source['name'], $id); - if ($source['help']) { - $widgets[] = $mform->createElement('html', $OUTPUT->help_icon($source['help'], 'block_dash', $source['help'])); + if (block_dash_visible_addons($id)) { + $widgets[] = $mform->createElement('html', html_writer::start_div('datasource-item')); + $widgets[] = $mform->createElement('radio', 'config_data_source_idnumber', '', $source['name'], $id); + if ($source['help']) { + $widgets[] = $mform->createElement('html', $OUTPUT->help_icon($source['help'], 'block_dash', $source['help'])); + } + $widgets[] = $mform->createElement('html', html_writer::end_div()); } - $widgets[] = $mform->createElement('html', html_writer::end_div()); } $widgets[] = $mform->createElement('html', html_writer::end_div()); $mform->addGroup($widgets, 'widgets', get_string('readymatewidgets', 'block_dash'), [' '], false); diff --git a/form/element-colorpicker.php b/form/element-colorpicker.php new file mode 100644 index 0000000..448727c --- /dev/null +++ b/form/element-colorpicker.php @@ -0,0 +1,98 @@ +. + +/** + * Dash - Form element for color picker. + * + * @package block_dash + * @copyright 2021 bdecent gmbh + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once('HTML/QuickForm/input.php'); +require_once($CFG->dirroot.'/lib/form/templatable_form_element.php'); +require_once($CFG->dirroot.'/lib/form/text.php'); + +/** + * Form element for color picker. + * + * @package block_dash + * @copyright 2021 bdecent gmbh + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class moodlequickform_dashcolorpicker extends MoodleQuickForm_text implements templatable { + + use templatable_form_element { + export_for_template as export_for_template_base; + } + + /** + * Constructor. + * + * @param string $elementname (optional) Name of the text field. + * @param string $elementlabel (optional) Text field label. + * @param string $attributes (optional) Either a typical HTML attribute string or an associative array. + */ + public function __construct($elementname=null, $elementlabel=null, $attributes=null) { + parent::__construct($elementname, $elementlabel, $attributes); + $this->setType('text'); + + // Add a CSS class for styling the color picker. + $class = $this->getAttribute('class'); + if (empty($class)) { + $class = ''; + } + $this->updateAttributes(['class' => $class.' block_dash-form-colour-picker ']); + } + + /** + * Export for template. + * + * @param renderer_base $output + * @return array|stdClass + */ + public function export_for_template(renderer_base $output) { + global $PAGE; + + // Compose template context for the mform element. + $context = $this->export_for_template_base($output); + + // Build loading icon. + $icon = new pix_icon('i/loading', get_string('loading', 'admin'), 'moodle', ['class' => 'loadingicon']); + $icondata = $icon->export_for_template($output); + $iconoutput = $output->render_from_template('core/pix_icon', $icondata); + + // Get ID of the element. + $id = $this->getAttribute('id'); + + // Add JS to append the color picker div before the element and initiate the color picker utility method. + $PAGE->requires->js_amd_inline(" + var element = document.getElementById('$id'); + var pickerDiv = document.createElement('div'); + pickerDiv.classList.add('admin_colourpicker', 'clearfix'); + pickerDiv.innerHTML = '$iconoutput'; // Add loading icon. + element.parentNode.prepend(pickerDiv); + element.parentNode.style.flexDirection = 'column'; + + // Init color picker utility. + M.util.init_colour_picker(Y, '$id'); + "); + + return $context; + } +} diff --git a/form/gradientpicker.php b/form/gradientpicker.php new file mode 100644 index 0000000..cc5690e --- /dev/null +++ b/form/gradientpicker.php @@ -0,0 +1,87 @@ +. + +/** + * Dash - Form element for color picker. + * + * @package block_dash + * @copyright 2021 bdecent gmbh + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once('HTML/QuickForm/input.php'); +require_once($CFG->dirroot.'/lib/form/templatable_form_element.php'); +require_once($CFG->dirroot.'/lib/form/text.php'); + +/** + * Form element for color picker. + * + * @package block_dash + * @copyright 2021 bdecent gmbh + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class moodlequickform_dashgradientpicker extends MoodleQuickForm_text implements templatable { + + use templatable_form_element { + export_for_template as export_for_template_base; + } + + /** + * Constructor. + * + * @param string $elementname (optional) Name of the text field. + * @param string $elementlabel (optional) Text field label. + * @param string $attributes (optional) Either a typical HTML attribute string or an associative array. + */ + public function __construct($elementname=null, $elementlabel=null, $attributes=null) { + parent::__construct($elementname, $elementlabel, $attributes); + $this->setType('text'); + + // Add a CSS class for styling the color picker. + $class = $this->getAttribute('class'); + if (empty($class)) { + $class = ''; + } + $this->updateAttributes(['class' => $class.' block_dash-form-gradient-picker']); + } + + /** + * Export for template. + * + * @param renderer_base $output + * @return array|stdClass + */ + public function export_for_template(renderer_base $output) { + global $PAGE; + + // Compose template context for the mform element. + $context = $this->export_for_template_base($output); + + $PAGE->requires->js_amd_inline('require(["jquery", "block_dash/gradient"], function($) { + var background = document.querySelectorAll("input[name=config_backgroundgradient]")[0]; + if (background) { + new lc_color_picker(background, { + modes : ["linear-gradient", "solid"], + }); + } + })' + ); + + return $context; + } +} diff --git a/lang/en/block_dash.php b/lang/en/block_dash.php index 4ceea62..752ce8c 100644 --- a/lang/en/block_dash.php +++ b/lang/en/block_dash.php @@ -51,7 +51,7 @@ $string['bootstrapversion'] = 'Theme bootstrap version'; $string['bootstrapversion_desc'] = 'Choose the version of Bootstrap your theme supports. Moodle is typically 4, and Totara is 3.'; $string['border'] = 'Border'; -$string['border_help'] = 'CSS border property value. Set to none for no borders.'; +$string['border_help'] = 'CSS border property value.'; $string['choosedatasource'] = 'Choose data source'; $string['columns'] = 'Columns'; $string['columns_help'] = 'The number of columns to display per row in the grid.'; @@ -217,6 +217,7 @@ $string['parseerror'] = 'Parse error. The content cannot be displayed.'; $string['permissions'] = 'Restrict access to'; $string['permissionscohort'] = 'Cohort'; +$string['permissionsrole'] = 'Role'; $string['permissionsloggedin'] = 'Must be logged in'; $string['permissionspublic'] = 'Public'; $string['perpage'] = 'Per page'; @@ -810,3 +811,52 @@ $string['categoryimgfallback'] = 'Category fallback image'; $string['categoryimgfallbackdesc'] = 'Upload the image for the default fallback of categories. If new categories are created, the fallback image will be displayed until a new image is added for the category'; $string['categoryimageurl'] = 'Category image url'; + +$string['cssclass'] = "CSS classes"; +$string['cssclass_help'] = "Use a custom CSS class to apply multiple classes."; +$string['backgroundposition'] = 'Background Position'; +$string['backgroundposition_help'] = 'Background image will focused on the given position'; +$string['designercustombgposition'] = "Custom Background Position"; +$string['backgroundsize'] = 'Background Size'; +$string['backgroundsize_help'] = 'Background image will displayed in the size'; +$string['designercustombgsize'] = "Custom Background Size"; +$string['backgroundsize_help'] = 'Background image will displayed in the size'; + +$string['initial'] = "Initial"; +$string['lefttop'] = "Left Top"; +$string['leftcenter'] = "Left Center"; +$string['leftbottom'] = "Left Bottom"; +$string['righttop'] = "Right Top"; +$string['rightcenter'] = "Right Center"; +$string['rightbottom'] = "Right Bottom"; +$string['centertop'] = "Center Top"; +$string['centercenter'] = "Center Center"; +$string['centerbottom'] = "Center Bottom"; + +$string['auto'] = "Auto"; +$string['cover'] = "Cover"; +$string['contain'] = "Contain"; + +$string['strcustom'] = "Custom"; +$string['cohorts'] = "Cohorts"; +$string['users_mycohort'] = "Users in one of my cohorts"; + +$string['currentcategory'] = 'Current Category'; +$string['dashicon'] = 'Icon'; +$string['dashicon_help'] = 'This icon shows onlu in the dashboards data source.'; +$string['dashthumbnailimg'] = 'Thumbnail image'; +$string['dashthumbnailimgurl'] = 'Thumbnail image URL'; +$string['dashthumbnailimg_help'] = "This thumbnail image shows only in dashboards data source"; +$string['dashbgimg'] = 'Background image'; +$string['dashbgimg_help'] = 'This background image used as background for the dashboard.'; +$string['coredashboard'] = "Core dashboard"; +$string['backgroundimageurl'] = 'Background image URL'; + +$string['border_option'] = "Border"; +$string['border_option_help'] = "You can add the border of dash block."; +$string['bordervalue'] = "Border Value"; + + +$string['managedashaddonplugins'] = "Manage Dash addon plugins"; +$string['dashaddonpluginname'] = 'Dash addon name'; +$string['hideshow'] = 'Hide/Show'; \ No newline at end of file diff --git a/lib.php b/lib.php index 7529792..9085126 100644 --- a/lib.php +++ b/lib.php @@ -64,11 +64,6 @@ function block_dash_register_data_sources() { 'help' => ['name' => 'users', 'component' => 'block_dash'], 'identifier' => users_data_source::class, ], - [ - 'name' => get_string('categories'), - 'help' => ['name' => 'categories', 'component' => 'block_dash'], - 'identifier' => categories_data_source::class, - ], ]; } @@ -344,3 +339,29 @@ function block_dash_get_data_collection() { return version_compare(phpversion(), '8.1', '<') ? new block_dash\local\data_grid\data\data_collection() : new \block_dash\local\data_grid\data\data_collection_new(); } + + +function block_dash_visible_addons($id) { + global $CFG; + preg_match('/(dashaddon_[a-zA-Z_]+)/', $id, $matches); + if ($matches) { + $value = $matches[1]; + $parts = explode('\\', $value); + if ($parts) { + $addon = $parts[0]; + $addondependencies = $addon . "_extend_added_dependencies"; + if (get_config($addon, 'enabled')) { + $addonplugin = explode("dashaddon_", $addon)[1]; + if (file_exists($CFG->dirroot. "/local/dash/addon/$addonplugin/lib.php")) { + require_once($CFG->dirroot. "/local/dash/addon/$addonplugin/lib.php"); + if (function_exists($addondependencies) && !empty($addondependencies())) { + return false; + } + } + } else { + return false; + } + } + } + return true; +} \ No newline at end of file diff --git a/settings.php b/settings.php index fd9e0ea..d9939f2 100644 --- a/settings.php +++ b/settings.php @@ -39,6 +39,15 @@ ] )); + // Css classes. + $settings->add(new admin_setting_configtext( + 'block_dash/cssclass', + get_string('cssclass', 'block_dash'), + get_string('cssclass_help', 'block_dash'), + '', + PARAM_TEXT + )); + $settings->add(new admin_setting_configselect( 'block_dash/showheader', get_string('showheader', 'block_dash'), @@ -113,7 +122,6 @@ $setting->set_updatedcallback('theme_reset_all_caches'); $settings->add($setting); - // require_once($CFG->libdir . '/coursecatlib.php'); $coursecats = core_course_category::make_categories_list(); // Go through all categories and create the necessary settings. @@ -136,5 +144,4 @@ }); "); - } diff --git a/thirdpartylibs.xml b/thirdpartylibs.xml index a192fec..5a5eb3d 100644 --- a/thirdpartylibs.xml +++ b/thirdpartylibs.xml @@ -28,4 +28,11 @@ Apache 2.0 + + amd/src/lc_color_picker.js + Color picker + 2.0 + Apache + 2.0 + diff --git a/version.php b/version.php index c7f1392..ef87e46 100644 --- a/version.php +++ b/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2024041000; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2024042800; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2022112800; // Requires Moodle 4.1. $plugin->component = 'block_dash'; // Full name of the plugin (used for diagnostics). $plugin->maturity = MATURITY_STABLE;