Last active
July 4, 2018 15:59
-
-
Save allanlaal/545c0bd2bc544e2f02a9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var dynamicStyles = false; | |
var dynamicStylesCache = []; | |
var dynamicStylesLastId = 0; | |
/** | |
* | |
* @param ruleName string | |
* @param ruleContents array of key value pairs of CSS rules | |
* @example | |
dynamicStyleWrite('.todo_item', [ | |
{ | |
property: "border", | |
rule: "3px dashed black" | |
}, | |
{ | |
property: "background-color", | |
rule: "blue" | |
}, | |
{ | |
property: "color", | |
rule: "" // <-- empty value will unset this property | |
}, | |
]); | |
* | |
* @returns null | |
* @desc highly optimized for minimizing DOM updates. NB! this will not overwrite styles for the same class/id set in CSS files or elsewhere outside dynamic styles | |
* @author Allan Laal <[email protected]> | |
*/ | |
function dynamicStyleWrite(ruleName, ruleContents) | |
{ | |
log('------------------'); | |
log('DynamicStyles: ' + ruleName + ' ruleContents: '); | |
console.log(ruleContents); | |
if (dynamicStyles === false) | |
{ // iniate container: | |
var dynamicStylesContainer = document.createElement('style'); | |
document.head.appendChild(dynamicStylesContainer); | |
dynamicStyles = dynamicStylesContainer.sheet; | |
} | |
var ruleCache = []; | |
var thisIsEdit = false; | |
if (issetAssoc(ruleName, dynamicStylesCache)) | |
{ | |
ruleCache = getAssoc(ruleName, dynamicStylesCache); | |
thisIsEdit = true; | |
log('DynamicStyles: editing existing rule with indexNr: ' + ruleCache.indexNr); | |
} | |
else | |
{ | |
ruleCache = { | |
id: ruleName, | |
contents: ruleContents, | |
indexNr: dynamicStylesLastId | |
}; | |
dynamicStylesLastId++; | |
dynamicStylesCache.push(ruleCache); | |
log('DynamicStyles: adding new rule with indexNr: ' + ruleCache.indexNr); | |
} | |
log('DynamicStyles: ruleCache: '); | |
console.log(ruleCache); | |
// only update DOM if there is something to change: | |
var newRules = []; | |
if (thisIsEdit) | |
{ | |
log('DynamicStyles: this is edit, checking existing rules'); | |
$(ruleContents).each(function() { | |
log('DynamicStyles: ' + this.property + ' length is ' + this.rule.length); | |
if (this.rule.length > 0) | |
{ | |
currentPair = getAssoc(this.property, ruleCache.contents, 'property'); | |
if (currentPair.length > 0) | |
{ // editing existing property: | |
console.log(currentPair); | |
console.log(currentPair.rule + ' vs ' + this.rule); | |
if (currentPair.rule != this.rule) // loose comparison, rules are always strings anyway | |
{ | |
newRules.push(this); | |
updateAssoc(this.property, this.rule, ruleCache.contents, 'property'); // update cache | |
} | |
} | |
else | |
{ // adding new property to existing rule: | |
newRules.push(this); | |
ruleCache.contents.push(this); | |
} | |
} | |
else | |
{ // rule is empty, unset! | |
log('DynamicStyles: ' + this.property + ' is empty (' + this.rule + ')! removing'); | |
removeAssoc(this.property, ruleCache.contents, 'property'); | |
} | |
}); | |
} | |
else | |
{ | |
newRules = ruleCache.contents; | |
} | |
log('DynamicStyles: changes to write '); | |
console.log(newRules); | |
replaceAssoc(ruleName, ruleCache, dynamicStylesCache, 'id'); | |
var compiledRule = ruleName + ' {'; | |
$(newRules).each(function() { | |
compiledRule = compiledRule + this.property + ':' + this.rule + ';'; | |
}); | |
compiledRule = compiledRule + '}'; | |
if (thisIsEdit) | |
{ | |
log('DynamicStyles: deleting dynamic rule index:' + ruleCache.indexNr); | |
dynamicStyles.deleteRule(ruleCache.indexNr); | |
} | |
log ('DynamicStyles: adding dynamic rule: ' + compiledRule); | |
dynamicStyles.insertRule(compiledRule, ruleCache.indexNr); | |
return null; | |
} | |
/** | |
* | |
* @param id string|int | |
* @param arr array | |
* @returns bool | |
* @desc | |
* @example | |
* var arrName = [ | |
* { | |
* id: 1337, <- must alway be set! | |
* someOtherLabel: dsfdsf, | |
* }, | |
* {}, | |
* {}, | |
* ] | |
* | |
* to check if 1337 is set in arr: issetAssoc(1337, arrName) | |
* | |
* @author Allan Laal <[email protected]> | |
*/ | |
function issetAssoc(id, arr, keyOverride) | |
{ | |
var key = 'id'; | |
if (typeof keyOverride !== 'undefined') | |
{ | |
key = keyOverride; | |
} | |
var found = false; | |
$(arr).each(function () { | |
if (this[key] === id) | |
{ | |
found = true; | |
return false; // break loop | |
} | |
}); | |
return found; | |
} | |
/** | |
* | |
* @param label string | |
* @param arr array | |
* @param keyOverride string | |
* @returns array | |
* @desc | |
* @author Allan Laal <[email protected]> | |
*/ | |
function getAssoc(label, arr, keyOverride) | |
{ | |
var key = 'id'; | |
if (typeof keyOverride !== 'undefined') | |
{ | |
key = keyOverride; | |
} | |
var out = []; | |
$(arr).each(function () { | |
if (this[key] === label) | |
{ | |
out = this; | |
return false; // break loop | |
} | |
}); | |
return out; | |
} | |
/** | |
* | |
* @param label string | |
* @param arr array | |
* @param keyOverride string | |
* @returns array | |
* @desc replace assoc member with label with value | |
* @author Allan Laal <[email protected]> | |
*/ | |
function replaceAssoc(label, value, arr, keyOverride) | |
{ | |
var key = 'id'; | |
if (typeof keyOverride !== 'undefined') | |
{ | |
key = keyOverride; | |
} | |
var out = []; | |
$(arr).each(function () { | |
if (this[key] === label) | |
{ | |
out.push(value); | |
} | |
else | |
{ | |
out.push(this); | |
} | |
}); | |
return out; | |
} | |
/** | |
* | |
* @param label string | |
* @param arr array | |
* @param keyOverride string | |
* @returns array | |
* @desc remove assoc member by label | |
* @author Allan Laal <[email protected]> | |
*/ | |
function removeAssoc(label, arr, keyOverride) | |
{ | |
var key = 'id'; | |
if (typeof keyOverride !== 'undefined') | |
{ | |
key = keyOverride; | |
} | |
var out = []; | |
$(arr).each(function () { | |
if (this[key] !== label) | |
{ | |
out.push(this); | |
} | |
}); | |
return out; | |
} | |
/** | |
* | |
* @param label string | |
* @param arr array | |
* @param keyOverride string | |
* @returns array | |
* @desc changes 1 key value, overwrites if exists | |
* @author Allan Laal <[email protected]> | |
*/ | |
function updateAssoc(label, value, arr, keyOverride) | |
{ | |
var key = 'id'; | |
if (typeof keyOverride !== 'undefined') | |
{ | |
key = keyOverride; | |
} | |
var out = []; | |
$(arr).each(function () { | |
if (this[key] === label) | |
{ | |
var row = this; | |
row[key] = value; | |
out.push(row); | |
} | |
else | |
{ | |
out.push(this); | |
} | |
}); | |
return out; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment