|
|
@ -145,22 +145,23 @@ var renderHostsFiles = function(soft) { |
|
|
|
}); |
|
|
|
|
|
|
|
let ulList = document.querySelector(listSelector), |
|
|
|
liImport = ulList.querySelector('.importURL'); |
|
|
|
if ( liImport.parentNode !== null ) { |
|
|
|
liImport.parentNode.removeChild(liImport); |
|
|
|
} |
|
|
|
liLast = ulList.querySelector('.notAnAsset'); |
|
|
|
|
|
|
|
for ( let i = 0; i < assetKeys.length; i++ ) { |
|
|
|
let liEntry = liFromListEntry( |
|
|
|
collection, |
|
|
|
assetKeys[i], |
|
|
|
ulList.children[i] |
|
|
|
); |
|
|
|
let liReuse = i < ulList.childElementCount ? |
|
|
|
ulList.children[i] : |
|
|
|
null; |
|
|
|
if ( |
|
|
|
liReuse !== null && |
|
|
|
liReuse.classList.contains('notAnAsset') |
|
|
|
) { |
|
|
|
liReuse = null; |
|
|
|
} |
|
|
|
let liEntry = liFromListEntry(collection, assetKeys[i], liReuse); |
|
|
|
if ( liEntry.parentElement === null ) { |
|
|
|
ulList.appendChild(liEntry); |
|
|
|
ulList.insertBefore(liEntry, liLast); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ulList.appendChild(liImport); |
|
|
|
}; |
|
|
|
|
|
|
|
var onAssetDataReceived = function(details) { |
|
|
@ -171,9 +172,14 @@ var renderHostsFiles = function(soft) { |
|
|
|
// Before all, set context vars
|
|
|
|
listDetails = details; |
|
|
|
|
|
|
|
document.body.classList.toggle( |
|
|
|
'contributor', |
|
|
|
listDetails.contributor === true |
|
|
|
); |
|
|
|
|
|
|
|
// Incremental rendering: this will allow us to easily discard unused
|
|
|
|
// DOM list entries.
|
|
|
|
uDom('#hosts .listEntry:not(.importURL)').addClass('discard'); |
|
|
|
uDom('#hosts .listEntry:not(.notAnAsset)').addClass('discard'); |
|
|
|
|
|
|
|
onRenderAssetFiles(details.hosts, '#hosts'); |
|
|
|
onRenderAssetFiles(details.recipes, '#recipes'); |
|
|
@ -188,6 +194,12 @@ var renderHostsFiles = function(soft) { |
|
|
|
); |
|
|
|
uDom('#autoUpdate').prop('checked', listDetails.autoUpdate === true); |
|
|
|
|
|
|
|
uDom.nodeFromSelector('#recipes .toInline > input[type="checkbox"]').checked = |
|
|
|
listDetails.userRecipes.enabled === true; |
|
|
|
uDom.nodeFromSelector('#recipes .toInline > textarea').value = |
|
|
|
listDetails.userRecipes.content; |
|
|
|
|
|
|
|
|
|
|
|
if ( !soft ) { |
|
|
|
hostsFilesSettingsHash = hashFromCurrentFromSettings(); |
|
|
|
} |
|
|
@ -231,31 +243,50 @@ var updateAssetStatus = function(details) { |
|
|
|
|
|
|
|
/******************************************************************************* |
|
|
|
|
|
|
|
Compute a hash from all the settings affecting how filter lists are loaded |
|
|
|
Compute a hash from all the settings affecting how assets are loaded |
|
|
|
in memory. |
|
|
|
|
|
|
|
**/ |
|
|
|
|
|
|
|
var hashFromCurrentFromSettings = function() { |
|
|
|
var hash = [], |
|
|
|
listHash = [], |
|
|
|
listEntries = document.querySelectorAll('.assets .listEntry[data-listkey]:not(.toRemove)'), |
|
|
|
i = listEntries.length; |
|
|
|
while ( i-- ) { |
|
|
|
let liEntry = listEntries[i]; |
|
|
|
let listHash = [], |
|
|
|
listEntries = document.querySelectorAll( |
|
|
|
'.assets .listEntry[data-listkey]:not(.toRemove)' |
|
|
|
); |
|
|
|
for ( let liEntry of listEntries ) { |
|
|
|
if ( liEntry.querySelector('input[type="checkbox"]:checked') !== null ) { |
|
|
|
listHash.push(liEntry.getAttribute('data-listkey')); |
|
|
|
} |
|
|
|
} |
|
|
|
let textarea1 = document.querySelector('.assets .importURL > input[type="checkbox"]:checked ~ textarea'); |
|
|
|
let textarea2 = document.querySelector('#recipes .importURL > input[type="checkbox"]:checked ~ textarea'); |
|
|
|
hash.push( |
|
|
|
listHash.sort().join(), |
|
|
|
textarea1 !== null && reValidExternalList.test(textarea1.value), |
|
|
|
textarea2 !== null && reValidExternalList.test(textarea2.value), |
|
|
|
document.querySelector('.listEntry.toRemove') !== null |
|
|
|
); |
|
|
|
return hash.join(); |
|
|
|
return [ |
|
|
|
listHash.join(), |
|
|
|
document.querySelector('.listEntry.toRemove') !== null, |
|
|
|
reValidExternalList.test( |
|
|
|
textFromTextarea( |
|
|
|
'#hosts .toImport > input[type="checkbox"]:checked ~ textarea' |
|
|
|
) |
|
|
|
), |
|
|
|
textFromTextarea( |
|
|
|
'#hosts .toInline > input[type="checkbox"]:checked ~ textarea' |
|
|
|
), |
|
|
|
reValidExternalList.test( |
|
|
|
textFromTextarea( |
|
|
|
'#recipes .toImport > input[type="checkbox"]:checked ~ textarea' |
|
|
|
) |
|
|
|
), |
|
|
|
textFromTextarea( |
|
|
|
'#recipes .toInline > input[type="checkbox"]:checked ~ textarea' |
|
|
|
), |
|
|
|
].join('\n'); |
|
|
|
}; |
|
|
|
|
|
|
|
/******************************************************************************/ |
|
|
|
|
|
|
|
var textFromTextarea = function(textarea) { |
|
|
|
if ( typeof textarea === 'string' ) { |
|
|
|
textarea = document.querySelector(textarea); |
|
|
|
} |
|
|
|
return textarea !== null ? textarea.value.trim() : ''; |
|
|
|
}; |
|
|
|
|
|
|
|
/******************************************************************************/ |
|
|
@ -300,36 +331,44 @@ var selectAssets = function(callback) { |
|
|
|
var out = { |
|
|
|
toSelect: [], |
|
|
|
toImport: '', |
|
|
|
toRemove: [] |
|
|
|
toRemove: [], |
|
|
|
toInline: { |
|
|
|
enabled: false, |
|
|
|
content: '' |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
let root = document.querySelector(listSelector); |
|
|
|
|
|
|
|
let liEntries = root.querySelectorAll('.listEntry[data-listkey]:not(.toRemove)'), |
|
|
|
i = liEntries.length; |
|
|
|
while ( i-- ) { |
|
|
|
let liEntry = liEntries[i]; |
|
|
|
if ( liEntry.querySelector('input[type="checkbox"]:checked') !== null ) { |
|
|
|
// Lists to select or remove
|
|
|
|
let liEntries = root.querySelectorAll( |
|
|
|
'.listEntry[data-listkey]:not(.notAnAsset)' |
|
|
|
); |
|
|
|
for ( let liEntry of liEntries ) { |
|
|
|
if ( liEntry.classList.contains('toRemove') ) { |
|
|
|
out.toRemove.push(liEntry.getAttribute('data-listkey')); |
|
|
|
} else if ( liEntry.querySelector('input[type="checkbox"]:checked') ) { |
|
|
|
out.toSelect.push(liEntry.getAttribute('data-listkey')); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// External hosts files to remove
|
|
|
|
liEntries = root.querySelectorAll('.listEntry.toRemove[data-listkey]'); |
|
|
|
i = liEntries.length; |
|
|
|
while ( i-- ) { |
|
|
|
out.toRemove.push(liEntries[i].getAttribute('data-listkey')); |
|
|
|
} |
|
|
|
|
|
|
|
// External hosts files to import
|
|
|
|
let input = root.querySelector('.importURL > input[type="checkbox"]:checked'); |
|
|
|
let input = root.querySelector( |
|
|
|
'.toImport > input[type="checkbox"]:checked' |
|
|
|
); |
|
|
|
if ( input !== null ) { |
|
|
|
let textarea = root.querySelector('.importURL textarea'); |
|
|
|
let textarea = root.querySelector('.toImport textarea'); |
|
|
|
out.toImport = textarea.value.trim(); |
|
|
|
textarea.value = ''; |
|
|
|
input.checked = false; |
|
|
|
} |
|
|
|
|
|
|
|
// Inline data
|
|
|
|
out.toInline.enabled = root.querySelector( |
|
|
|
'.toInline > input[type="checkbox"]:checked' |
|
|
|
) !== null; |
|
|
|
out.toInline.content = textFromTextarea('.toInline > textarea'); |
|
|
|
|
|
|
|
return out; |
|
|
|
}; |
|
|
|
|
|
|
@ -406,7 +445,7 @@ uDom('#buttonApply').on('click', buttonApplyHandler); |
|
|
|
uDom('#buttonUpdate').on('click', buttonUpdateHandler); |
|
|
|
uDom('#buttonPurgeAll').on('click', buttonPurgeAllHandler); |
|
|
|
uDom('.assets').on('change', '.listEntry > input', onHostsFilesSettingsChanged); |
|
|
|
uDom('.assets').on('input', '.listEntry.importURL textarea', onHostsFilesSettingsChanged); |
|
|
|
uDom('.assets').on('input', '.listEntry > textarea', onHostsFilesSettingsChanged); |
|
|
|
uDom('.assets').on('click', '.listEntry > a.remove', onRemoveExternalAsset); |
|
|
|
uDom('.assets').on('click', 'span.cache', onPurgeClicked); |
|
|
|
|
|
|
|