1/** 2 * @namespace WPGMZA 3 * @module CSSFilterInput 4 * @requires WPGMZA.EventDispatcher 5 */ 6jQuery(function($) { 7 WPGMZA.CSSFilterInput = function(element, options){ 8 if(!(element instanceof HTMLInputElement)) 9 throw new Error("Element is not an instance of HTMLInputElement"); 10 11 this.element = $(element); 12 this.dataAttributes = this.element.data(); 13 this.type = element.type; 14 this.value = element.value; 15 16 this.options = { 17 18 }; 19 20 this.parseOptions(options); 21 22 this.state = { 23 initialized : false 24 } 25 26 this.filters = { 27 blur : { 28 enable : false, 29 value : 0, 30 unit : 'px' 31 }, 32 brightness : { 33 enable : false, 34 value : 0, 35 unit : '%', 36 max : 500 37 }, 38 contrast : { 39 enable : false, 40 value : 0, 41 unit : '%', 42 max : 500 43 }, 44 grayscale : { 45 enable : false, 46 value : 0, 47 unit : '%' 48 }, 49 hue_rotate : { 50 enable : false, 51 value : 0, 52 unit : 'deg' 53 }, 54 invert : { 55 enable : false, 56 value : 0, 57 unit : '%' 58 }, 59 sepia : { 60 enable : false, 61 value : 0, 62 unit : '%' 63 }, 64 saturate : { 65 enable : false, 66 value : 0, 67 unit : '%', 68 max : 500 69 } 70 }; 71 72 this.wrap(); 73 this.renderControls(); 74 75 this.parseFilters(this.value); 76 } 77 78 WPGMZA.extend(WPGMZA.CSSFilterInput, WPGMZA.EventDispatcher); 79 80 WPGMZA.CSSFilterInput.FILTER_PATTERN = /(\S+)/g; 81 WPGMZA.CSSFilterInput.VALUE_PATTERN = /(\(\S*\))/g; 82 83 WPGMZA.CSSFilterInput.createInstance = function(element) { 84 return new WPGMZA.CSSFilterInput(element); 85 } 86 87 WPGMZA.CSSFilterInput.prototype.parseOptions = function(options){ 88 if(options){ 89 for(var i in options){ 90 if(typeof this.options[i] !== 'undefined'){ 91 if(typeof this.options[i] === 'object' && typeof options[i] === 'object'){ 92 this.options[i] = Object.assign(this.options[i], options[i]); 93 } else { 94 this.options[i] = options[i]; 95 } 96 } 97 } 98 } 99 100 if(this.dataAttributes){ 101 for(var i in this.dataAttributes){ 102 if(typeof this.options[i] !== 'undefined'){ 103 this.options[i] = this.dataAttributes[i]; 104 } 105 } 106 } 107 } 108 109 WPGMZA.CSSFilterInput.prototype.getFilters = function(override, format){ 110 let filters = []; 111 for(let type in this.filters){ 112 const data = this.filters[type]; 113 114 if(data.enable){ 115 type = type.replace("_", "-"); 116 filters.push(type + "(" + data.value + data.unit + ")"); 117 } 118 } 119 return filters.length > 0 ? filters.join(" ") : "none"; 120 } 121 122 WPGMZA.CSSFilterInput.prototype.setFilters = function(filters){ 123 this.clearFilters(); 124 125 if(filters instanceof Object){ 126 for(let type in filters){ 127 if(this.filters[type]){ 128 const value = filters[type]; 129 if(value){ 130 this.filters[type].enable = true; 131 this.filters[type].value = value; 132 } 133 } 134 } 135 } 136 137 this.commit(); 138 if(this.state.initialized){ 139 this.update(); 140 } 141 } 142 143 WPGMZA.CSSFilterInput.prototype.clearFilters = function(){ 144 for(let i in this.filters){ 145 this.filters[i].enable = false; 146 this.filters[i].value = 0; 147 } 148 } 149 150 WPGMZA.CSSFilterInput.prototype.parseFilters = function(value){ 151 if(typeof value === "string"){ 152 value = value.trim().toLowerCase(); 153 if(value === ""){ 154 value = "none"; 155 } 156 157 let filters = {};
158 if(value !== "none"){ 159 /* Some filters exist */ 160 let matches = value.match(WPGMZA.CSSFilterInput.FILTER_PATTERN); 161 if(matches && matches instanceof Array){ 162 for(let match of matches){ 163 let valueArg = match.match(WPGMZA.CSSFilterInput.VALUE_PATTERN); 164 valueArg = valueArg instanceof Array && valueArg.length > 0 ? valueArg[0] : ''; 165 166 let type = match.replace(valueArg, '').replace('-', '_'); 167 let value = null; 168 if(valueArg.length > 0){ 169 let numericValue = valueArg.match(/(\d+)/g); 170 if(numericValue instanceof Array && numericValue.length > 0){ 171 value = parseFloat(numericValue[0]); 172 } 173 } 174 175 filters[type] = value; 176 } 177 } 178 } 179 180 this.setFilters(filters); 181 } 182 } 183 184 WPGMZA.CSSFilterInput.prototype.wrap = function(){ 185 var self = this; 186 if(this.element && this.type === "text"){ 187 this.element.hide(); 188 this.container = $("<div class='wpgmza-css-filter-input-wrapper' />"); 189 190 this.container.insertAfter(this.element); 191 this.container.append(this.element); 192 } else { 193 throw new Error("WPGMZA.CSSFilterInput requires a text field as a base"); 194 } 195 } 196 197 WPGMZA.CSSFilterInput.prototype.renderControls = function(){ 198 var self = this; 199 if(this.container){ 200 this.itemWrappers = {}; 201 for(let type in this.filters){ 202 let data = this.filters[type]; 203 204 let printType = type.replace("_", " "); 205 206 const wrapper = $("<div class='css-filter-item-wrap' data-type='" + type + "' />"); 207 208 const toggleWrap = $("<div class='css-filter-toggle-wrap' />"); 209 const toggleInput = $("<input type='checkbox' class='css-filter-item-toggle' />"); 210 const toggleLabel = $("<label />"); 211 212 const controlWrap = $("<div class='css-filter-control-wrap' />"); 213 214 let controlType = 'text'; 215 controlAttributes = "data-min='1' data-max='100'"; 216 if(data.unit === 'deg'){ 217 controlAttributes = "data-min='1' data-max='360'"; 218 } else if (data.unit === 'px'){ 219 controlAttributes = "data-min='1' data-max='200'"; 220 } else if (data.max){ 221 controlAttributes = "data-min='0' data-max='" + data.max + "'"; 222 } 223 224 const controlInput = $("<input class='css-filter-item-input' type='" + controlType + "' " + controlAttributes + " value='" + data.value + "' />");
225 const controlLabel = $("<small />"); 226 controlLabel.append("<span>" + data.value + "</span>" + data.unit); 227 228 const slider = $("<div class='css-filter-item-slider' />"); 229 230 231 toggleLabel.append(toggleInput); 232 toggleLabel.append(printType); 233 234 toggleWrap.append(toggleLabel); 235 236 controlWrap.append(controlInput); 237 controlWrap.append(controlLabel); 238 controlWrap.append(slider); 239 240 wrapper.append(toggleWrap); 241 wrapper.append(controlWrap); 242 243 244 this.itemWrappers[type] = wrapper; 245 this.container.append(wrapper); 246 247 this.state.initialized = true; 248 249 /* Events */ 250 slider.slider({ 251 range: "max", 252 min: controlInput.data('min'), 253 max: controlInput.data('max'), 254 value: controlInput.val(), 255 slide: function( event, ui ) { 256 controlInput.val(ui.value); 257 controlLabel.find('span').text(ui.value); 258 controlInput.trigger('change'); 259 // self.commit(); 260 }, 261 change: function(event, ui){ 262 } 263 }); 264 265 controlInput.wpgmzaRelativeSlider = slider; 266 267 toggleInput.on('change', (event) => { 268 const target = $(event.currentTarget); 269 const parent = target.closest('.css-filter-item-wrap'); 270 const type = parent.data('type'); 271 272 if(target.is(':checked')){ 273 parent.addClass('enabled'); 274 this.setFilterState(type, true); 275 } else { 276 parent.removeClass('enabled'); 277 this.setFilterState(type, false); 278 } 279 }); 280 281 controlInput.on('change', (event) => { 282 const target = $(event.currentTarget); 283 const parent = target.closest('.css-filter-item-wrap'); 284 const type = parent.data('type'); 285 this.setFilterValue(type, target.val()); 286 }); 287 288 } 289 } 290 } 291 292 WPGMZA.CSSFilterInput.prototype.setFilterState = function(type, state){ 293 if(this.filters[type]){ 294 this.filters[type].enable = state; 295 } 296 297 this.commit(); 298 } 299 300 WPGMZA.CSSFilterInput.prototype.setFilterValue = function(type, value){ 301 if(this.filters[type]){ 302 this.filters[type].value = parseFloat(value); 303 } 304 305 this.commit(); 306 } 307 308 WPGMZA.CSSFilterInput.prototype.update = function(){ 309 if(this.container){ 310 for(let type in this.filters){ 311 const data = this.filters[type]; 312 313 const row = this.container.find('.css-filter-item-wrap[data-type="' + type + '"]'); 314 315 row.find('.css-filter-item-toggle').prop('checked', data.enable).trigger('change'); 316 row.find('.css-filter-item-input').val(data.value).trigger('change'); 317 318 row.find('.css-filter-item-slider').slider('value', data.value); 319 row.find('.css-filter-control-wrap').find('small span').text(data.value); 320 321 } 322 } 323 } 324 325 WPGMZA.CSSFilterInput.prototype.commit = function(){ 326 var syncValue = this.getFilters(); 327 this.element.val(syncValue); 328 this.element.trigger('change'); 329 } 330 331 $(document.body).ready(function(){ 332 $("input.wpgmza-css-filter-input").each(function(index, el) { 333 el.wpgmzaCSSFilterInput = WPGMZA.CSSFilterInput.createInstance(el); 334 }); 335 }); 336 337});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.