Import and Export Themes
-
@burbuja Yeah, you can of course create and modify the json file yourself. You can also import other user's themes, if they share the file.
I automated setting the checkboxes now, which was simple (OP updated). But the really annoying thing is that I can't get keyboard events to fire, which would be required to automate everything. I remember I had this problem before… on another mod about a year ago. It seems like chromium is just bugged and simulating keypresses is very complicated. If anyone has a working solution, I'd be interested.
-
flags are set on import, well done!
-
wait a minute, I just said nonsense
-
I had a breakthrough. Everything but corner rounding is automated now. Original post code and description have been updated, I also included explanations how to share themes and an example theme to download and import. Feel free to share your own themes
-
OMG perfect, @luetage #1
-
@luetage It works like a charm. Amazing job. Is this your Christmas gift to V users? Anyway, thanks a lot (I missed the ability to import/export themes, just in case I should refresh my profile).
-
@hlehyaric No, the christmas gift to the community is in progress and will be released over the next days. This is just something I wanted for myself for the longest time and I thought why not give it a try? Doesn't seem like Vivaldi will be doing something about it any time soon.
I could make a version that lets you save and share the themes as a string instead of a file. This way the themes could be saved to Vivaldi's notes feature and shared by just pasting the string in the forum. It's also something I'm considering for the forum mod, because I noticed no one is sharing themes. Uploading a file seems to bother users.
Question to everyone: Does uploading a file bother you? Which do you prefer, string or file?
-
@luetage I don't see the difference, a json IS a string
-
@iAN-CooG True, but currently you can only export the string to a file and import it from a file, therefore sharing a theme requires an upload in order for others to access and try it out comfortably.
-
@luetage said:
Question to everyone: Does uploading a file bother you? Which do you prefer, string or file?
I like strings because it's much easier and I can e. g. save multiple themes into one file.
Another thing that bothers me is exporting/importing all themes with files. I have to click the button, then go through the save dialog, sometimes rename the file and confirm overwrite (when overwriting).I'll be also very happy with a button 'Export all' (if as string or file doesn't matter).
-
@potmeklecbohdan Exporting all themes is likely very hard to do from an outside script. I'm sorry, but I don't see this happening.
-
@luetage I didn't expect you'll do that, it was only idea what to do if you (or somebody in V Team) are really bored and need something to do.
-
-
@potmeklecbohdan It's not about boredom, it's just far easier to do this from the inside. Vivaldi has access to all the theme variables, while I have to read them out individually. This would probably mean that I have to simulate click events to load every theme and then take each value and collect it – it's just not feasible. So yeah, I'm not gonna do it – it would be really ugly lol.
I have no doubt that Vivaldi will come out with a solution one day. Themes in sync is bound to happen, it's a given. The question is if they will introduce a way to share themes.
-
I implement the copy/pasting of theme code in the forum extension now. Should I do the same thing for importing/exporting themes?
-
EDIT: See original post of this thread for latest version, the code in this post is outdated!!
Ok then, new version: This exports the theme by copying the theme code to your clipboard. From there you can paste it into Vivaldi Notes to have it readily available and backed up by Sync. Instead of the import button we have an import field now, where you can either paste or drag and drop a theme code.
/* Theme Import and Export */ function _importTheme() { event.stopPropagation(); event.preventDefault(); if (_eventType === 'paste') { var clipboardData = event.clipboardData || window.clipboardData; var themeCode = clipboardData.getData('text'); } else { var themeCode = event.dataTransfer.getData('text'); } var set = JSON.parse(themeCode); _themeName.select(); document.execCommand('insertText', false, set.themeName); setTimeout(function() { _themeBg.select(); document.execCommand('insertText', false, set.themeBg); }, 200); setTimeout(function() { _themeFg.select(); document.execCommand('insertText', false, set.themeFg); }, 400); setTimeout(function() { _themeHi.select(); document.execCommand('insertText', false, set.themeHi); }, 600); setTimeout(function() { _themeAc.select(); document.execCommand('insertText', false, set.themeAc); }, 800); if ((set.themePage === 1 && !_themePage.checked) || (set.themePage === 0 && _themePage.checked)) { setTimeout(function() { _themePage.click(); }, 1000); } if ((set.themeWin === 1 && !_themeWin.checked) || (set.themeWin === 0 && _themeWin.checked)) { setTimeout(function() { _themeWin.click(); }, 1200); } if ((set.themeTabs === 1 && !_themeTabs.checked) || (set.themeTabs === 0 && _themeTabs.checked)) { setTimeout(function() { _themeTabs.click(); }, 1400); } setTimeout(function () { const disp = document.querySelector('.border-radius label span'); if (set.themeRound === '-1') { disp.innerText = 'Disabled'; } else if (set.themeRound === '0') { disp.innerText = 'Default'; } else { disp.innerText = set.themeRound + 'px'; } _themeRound.value = set.themeRound; _themeRound.focus(); }, 1600); }; function _exportTheme() { if (_themePage.checked === true) { var checkPage = 1; } else { var checkPage = 0; } if (_themeWin.checked === true) { var checkWin = 1; } else { var checkWin = 0; } if (_themeTabs.checked === true) { var checkTabs = 1; } else { var checkTabs = 0; } const share = {'themeName': _themeName.value, 'themeBg': _themeBg.value, 'themeFg': _themeFg.value, 'themeHi': _themeHi.value, 'themeAc': _themeAc.value, 'themePage': checkPage, 'themeWin': checkWin, 'themeTabs': checkTabs, 'themeRound': _themeRound.value}; const themeCode = JSON.stringify(share); navigator.clipboard.writeText(themeCode); const confirm = document.createElement('span'); confirm.innerText = 'Theme code copied to clipboard.'; confirm.style = 'color: var(--colorHighlightBg); margin-left: 6px; margin-top: 6px;)'; confirm.id = 'confirmExport'; const confirmExport = document.getElementById('confirmExport'); if (!confirmExport) { _cont.appendChild(confirm); setTimeout(function() { _cont.removeChild(confirm); }, 3500); } }; function _buttons() { const check = document.getElementById('importTheme'); _cont = document.querySelector('.theme-metadata'); if (_cont && !check) { _themeName = document.querySelector('.theme-name'); _themeBg = document.querySelector('.theme-colors div:nth-of-type(1) input'); _themeFg = document.querySelector('.theme-colors div:nth-of-type(2) input'); _themeHi = document.querySelector('.theme-colors div:nth-of-type(3) input'); _themeAc = document.querySelector('.theme-colors div:nth-of-type(4) input'); _themePage = document.querySelector('.theme-settings div div:nth-of-type(1) label input'); _themeWin = document.querySelector('.theme-settings div div:nth-of-type(2) label input'); _themeTabs = document.querySelector('.theme-settings div div:nth-of-type(3) label input'); _themeRound = document.querySelector('.border-radius label input'); var importBtn = document.createElement('input'); importBtn.setAttribute('type', 'text'); importBtn.setAttribute('placeholder', 'Import'); importBtn.style = 'margin-left: 6px; '; importBtn.id = 'importTheme'; _cont.appendChild(importBtn); const style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = '#importTheme {width: 80px;} #importTheme::-webkit-input-placeholder {opacity: 1; color: var(--colorHighlightBg); text-align: center;}'; document.getElementsByTagName('head')[0].appendChild(style); var exportBtn = document.createElement('input'); exportBtn.setAttribute('type', 'submit'); exportBtn.classList.add('primary'); exportBtn.setAttribute('value', 'Export'); exportBtn.style.marginLeft = '6px'; exportBtn.id = 'exportTheme'; _cont.appendChild(exportBtn); document.getElementById('exportTheme').addEventListener('click', _exportTheme); const importInput = document.getElementById('importTheme'); importInput.addEventListener('paste', function() { _eventType = 'paste'; _importTheme(event); }); importInput.addEventListener('drop', function() { _eventType = 'drop'; _importTheme(event); }); } }; function portThemes() { var edit = document.querySelector('.button-toolbar.edit'); if (edit) { var add = document.querySelector('.button-toolbar.add'); if (!edit.hasAttribute('id')) { edit.id = "eventOn"; edit.addEventListener('click', function() { setTimeout(_buttons, 50); }); } if (!add.hasAttribute('id')) { add.id = "eventOn2"; add.addEventListener('click', function() { setTimeout(_buttons, 50); }); } } }; setTimeout(function wait() { const browser = document.getElementById('browser'); if (browser) { document.body.addEventListener('click', function() { setTimeout(portThemes, 500); }); } else { setTimeout(wait, 300); } }, 300);
-
@luetage Great! Very handy (actually, perfect) for importing/exporting themes between my stable and snapshot. Thanks you for this amazing gift.
-
@hlehyaric said in Import and Export Themes:
Very handy
But... but... but... HOW did you get it? The extension is still not yet updated on the Chrome store, even after 10 hours?
-
-
@hlehyaric Oh, whoops, blush - thank you!
I was waiting for the new version because...
Ok then, new version