Merge branch 'fix-style-editors' into shigusegubu-themes3
This commit is contained in:
commit
a55d571a44
5 changed files with 86 additions and 106 deletions
|
|
@ -11,13 +11,7 @@
|
|||
<link rel="preload" href="/static/pleromatan_apology_fox_small.webp" as="image" />
|
||||
<!-- putting styles here to avoid having to wait for styles to load up -->
|
||||
<link rel="stylesheet" id="splashscreen" href="/static/splash.css" />
|
||||
<link rel="stylesheet" id="pleroma-eager-styles" type="text/css" href="/static/empty.css" />
|
||||
<link rel="stylesheet" id="pleroma-lazy-styles" type="text/css" href="/static/empty.css" />
|
||||
<link rel="stylesheet" id="theme-holder" type="text/css" href="/static/empty.css" />
|
||||
<link rel="stylesheet" id="theme-preview-holder" type="text/css" href="/static/empty.css" />
|
||||
<link rel="stylesheet" id="component-style-holder" type="text/css" href="/static/empty.css" />
|
||||
<link rel="stylesheet" id="editor-overall-holder" type="text/css" href="/static/empty.css" />
|
||||
<link rel="stylesheet" id="old-editor-overall-holder" type="text/css" href="/static/empty.css" />
|
||||
<link rel="stylesheet" id="custom-styles-holder" type="text/css" href="/static/empty.css" />
|
||||
<!--server-generated-meta-->
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import Checkbox from 'src/components/checkbox/checkbox.vue'
|
|||
import ColorInput from 'src/components/color_input/color_input.vue'
|
||||
|
||||
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
|
||||
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -51,15 +52,11 @@ export default {
|
|||
this.$emit('update:shadow', { axis, value: Number(value) })
|
||||
},
|
||||
update () {
|
||||
const styleEl = document.getElementById('component-style-holder')
|
||||
const styleSheet = styleEl.sheet
|
||||
const sheet = createStyleSheet('style-component-preview')
|
||||
|
||||
for (let i = styleSheet.cssRules.length - 1; i >= 0; --i) {
|
||||
styleSheet.deleteRule(i)
|
||||
}
|
||||
|
||||
const result = []
|
||||
sheet.clear()
|
||||
|
||||
const result = [this.previewCss]
|
||||
if (this.colorOverride) result.push(`--background: ${this.colorOverride}`)
|
||||
|
||||
const styleRule = [
|
||||
|
|
@ -71,13 +68,15 @@ export default {
|
|||
'\n}'
|
||||
].join('')
|
||||
|
||||
styleSheet.insertRule(styleRule)
|
||||
styleSheet.insertRule([
|
||||
sheet.addRule(styleRule)
|
||||
sheet.addRule([
|
||||
'#component-preview-', this.randomSeed, ' {\n',
|
||||
this.previewCss,
|
||||
...result,
|
||||
'\n}'
|
||||
].join(''), 'index-max')
|
||||
].join(''))
|
||||
|
||||
sheet.ready = true
|
||||
adoptStyleSheets()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {
|
|||
getCssRules
|
||||
} from 'src/services/theme_data/css_utils.js'
|
||||
import { deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
||||
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
|
||||
|
||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
|
||||
|
|
@ -410,16 +411,17 @@ const AppearanceTab = {
|
|||
this.compilationCache[key] = theme3
|
||||
}
|
||||
|
||||
const styleEl = document.getElementById('theme-preview-holder')
|
||||
const styleSheet = styleEl.sheet
|
||||
styleSheet.insertRule([
|
||||
|
||||
const sheet = createStyleSheet('appearance-tab-previews')
|
||||
sheet.addRule([
|
||||
'#theme-preview-',
|
||||
key,
|
||||
' {\n',
|
||||
getCssRules(theme3.eager).join('\n'),
|
||||
'\n}'
|
||||
].join(''), 'index-max')
|
||||
|
||||
].join(''))
|
||||
sheet.ready = true
|
||||
adoptStyleSheets()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ref, reactive, computed, watch, watchEffect, provide, getCurrentInstance } from 'vue'
|
||||
import { ref, reactive, computed, watch, provide, getCurrentInstance } from 'vue'
|
||||
import { useInterfaceStore } from 'src/stores/interface'
|
||||
import { get, set, unset, throttle } from 'lodash'
|
||||
|
||||
|
|
@ -19,6 +19,7 @@ import Preview from '../theme_tab/theme_preview.vue'
|
|||
|
||||
import VirtualDirectivesTab from './virtual_directives_tab.vue'
|
||||
|
||||
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
|
||||
import { init, findColor } from 'src/services/theme_data/theme_data_3.service.js'
|
||||
import { getCssRules } from 'src/services/theme_data/css_utils.js'
|
||||
import { serialize } from 'src/services/theme_data/iss_serializer.js'
|
||||
|
|
@ -694,29 +695,19 @@ export default {
|
|||
return
|
||||
}
|
||||
|
||||
const styleEl = document.getElementById('editor-overall-holder')
|
||||
const styleSheet = styleEl.sheet
|
||||
const sheet = createStyleSheet('style-tab-overall-preview')
|
||||
|
||||
console.log(styleSheet)
|
||||
console.log('BEFORE', styleSheet.cssRules)
|
||||
for (let i = styleSheet.cssRules.length - 1; i >= 0; --i) {
|
||||
styleSheet.deleteRule(i)
|
||||
}
|
||||
|
||||
styleSheet.insertRule([
|
||||
sheet.clear()
|
||||
sheet.addRule([
|
||||
'#edited-style-preview {\n',
|
||||
css.join('\n'),
|
||||
'\n}'
|
||||
].join(''), 'index-max')
|
||||
styleSheet.insertRule([
|
||||
'#edited-style-preview {\n',
|
||||
css.join('\n'),
|
||||
'\n}'
|
||||
].join(''), 'index-max')
|
||||
console.log('AFTER', styleSheet.cssRules)
|
||||
].join(''))
|
||||
sheet.ready = true
|
||||
adoptStyleSheets()
|
||||
})
|
||||
|
||||
const updateOverallPreview = () => {
|
||||
const updateOverallPreview = throttle(() => {
|
||||
try {
|
||||
overallPreviewRules.value = init({
|
||||
inputRuleset: [
|
||||
|
|
@ -738,7 +729,7 @@ export default {
|
|||
console.error('Could not compile preview theme', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
}, 1000)
|
||||
//
|
||||
// Apart from "hover" we can't really show how component looks like in
|
||||
// certain states, so we have to fake them.
|
||||
|
|
|
|||
|
|
@ -1,47 +1,65 @@
|
|||
import { init, getEngineChecksum } from '../theme_data/theme_data_3.service.js'
|
||||
import { getCssRules } from '../theme_data/css_utils.js'
|
||||
import { defaultState } from 'src/modules/default_config_state.js'
|
||||
import { chunk } from 'lodash'
|
||||
import { chunk, throttle } from 'lodash'
|
||||
import localforage from 'localforage'
|
||||
|
||||
// On platforms where this is not supported, it will return undefined
|
||||
// Otherwise it will return an array
|
||||
const supportsAdoptedStyleSheets = !!document.adoptedStyleSheets
|
||||
|
||||
const createStyleSheet = (id) => {
|
||||
const stylesheets = {}
|
||||
|
||||
export const createStyleSheet = (id) => {
|
||||
if (stylesheets[id]) return stylesheets[id]
|
||||
const newStyleSheet = {
|
||||
rules: [],
|
||||
ready: false,
|
||||
clear () {
|
||||
this.rules = []
|
||||
},
|
||||
addRule (rule) {
|
||||
this.rules.push(
|
||||
rule
|
||||
.replace(/backdrop-filter:[^;]+;/g, '') // Remove backdrop-filter
|
||||
.replace(/var\(--shadowFilter\)[^;]*;/g, '') // Remove shadowFilter references
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
stylesheets[id] = newStyleSheet
|
||||
return newStyleSheet
|
||||
}
|
||||
|
||||
|
||||
export const adoptStyleSheets = throttle(() => {
|
||||
if (supportsAdoptedStyleSheets) {
|
||||
return {
|
||||
el: null,
|
||||
sheet: new CSSStyleSheet(),
|
||||
rules: []
|
||||
}
|
||||
}
|
||||
document.adoptedStyleSheets = Object
|
||||
.values(stylesheets)
|
||||
.filter(x => x.ready)
|
||||
.map(x => {
|
||||
const css = new CSSStyleSheet()
|
||||
x.rules.forEach(r => css.insertRule(r, css.cssRules.length))
|
||||
return css
|
||||
})
|
||||
} else {
|
||||
const holder = document.getElementById('custom-styles-holder')
|
||||
|
||||
const el = document.getElementById(id)
|
||||
// Clear all rules in it
|
||||
for (let i = el.sheet.cssRules.length - 1; i >= 0; --i) {
|
||||
el.sheet.deleteRule(i)
|
||||
}
|
||||
|
||||
return {
|
||||
el,
|
||||
sheet: el.sheet,
|
||||
rules: []
|
||||
}
|
||||
}
|
||||
|
||||
const EAGER_STYLE_ID = 'pleroma-eager-styles'
|
||||
const LAZY_STYLE_ID = 'pleroma-lazy-styles'
|
||||
|
||||
const adoptStyleSheets = (styles) => {
|
||||
if (supportsAdoptedStyleSheets) {
|
||||
document.adoptedStyleSheets = styles.map(s => s.sheet)
|
||||
Object
|
||||
.values(stylesheets)
|
||||
.forEach(sheet => {
|
||||
sheet.rules.forEach(r => holder.sheet.insertRule(r))
|
||||
})
|
||||
}
|
||||
// Some older browsers do not support document.adoptedStyleSheets.
|
||||
// In this case, we use the <style> elements.
|
||||
// Since the <style> elements we need are already in the DOM, there
|
||||
// is nothing to do here.
|
||||
}
|
||||
}, 500)
|
||||
|
||||
|
||||
const EAGER_STYLE_ID = 'pleroma-eager-styles'
|
||||
const LAZY_STYLE_ID = 'pleroma-lazy-styles'
|
||||
|
||||
export const generateTheme = (inputRuleset, callbacks, debug) => {
|
||||
const {
|
||||
|
|
@ -97,10 +115,13 @@ export const tryLoadCache = async () => {
|
|||
const eagerStyles = createStyleSheet(EAGER_STYLE_ID)
|
||||
const lazyStyles = createStyleSheet(LAZY_STYLE_ID)
|
||||
|
||||
cache.data[0].forEach(rule => eagerStyles.sheet.insertRule(rule, 'index-max'))
|
||||
cache.data[1].forEach(rule => lazyStyles.sheet.insertRule(rule, 'index-max'))
|
||||
cache.data[0].forEach(rule => eagerStyles.addRule(rule, 'index-max'))
|
||||
cache.data[1].forEach(rule => lazyStyles.addRule(rule, 'index-max'))
|
||||
|
||||
adoptStyleSheets([eagerStyles, lazyStyles])
|
||||
eagerStyles.ready = true
|
||||
lazyStyles.ready = true
|
||||
|
||||
adoptStyleSheets()
|
||||
|
||||
console.info(`Loaded theme from cache`)
|
||||
return true
|
||||
|
|
@ -123,54 +144,26 @@ export const applyTheme = (
|
|||
const eagerStyles = createStyleSheet(EAGER_STYLE_ID)
|
||||
const lazyStyles = createStyleSheet(LAZY_STYLE_ID)
|
||||
|
||||
const insertRule = (styles, rule) => {
|
||||
try {
|
||||
// Try to use modern syntax first
|
||||
try {
|
||||
styles.sheet.insertRule(rule, 'index-max')
|
||||
styles.rules.push(rule)
|
||||
} catch {
|
||||
// Fallback for older browsers that don't support 'index-max'
|
||||
styles.sheet.insertRule(rule, styles.sheet.cssRules.length)
|
||||
styles.rules.push(rule)
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Can\'t insert rule due to lack of support', e, rule)
|
||||
|
||||
// Try to sanitize the rule for better compatibility
|
||||
try {
|
||||
// Remove any potentially problematic CSS features
|
||||
let sanitizedRule = rule
|
||||
.replace(/backdrop-filter:[^;]+;/g, '') // Remove backdrop-filter
|
||||
.replace(/var\(--shadowFilter\)[^;]*;/g, '') // Remove shadowFilter references
|
||||
|
||||
if (sanitizedRule !== rule) {
|
||||
styles.sheet.insertRule(sanitizedRule, styles.sheet.cssRules.length)
|
||||
styles.rules.push(sanitizedRule)
|
||||
}
|
||||
} catch (e2) {
|
||||
console.error('Failed to insert even sanitized rule', e2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { lazyProcessFunc } = generateTheme(
|
||||
input,
|
||||
{
|
||||
onNewRule (rule, isLazy) {
|
||||
if (isLazy) {
|
||||
insertRule(lazyStyles, rule)
|
||||
lazyStyles.addRule(rule)
|
||||
} else {
|
||||
insertRule(eagerStyles, rule)
|
||||
eagerStyles.addRule(rule)
|
||||
}
|
||||
},
|
||||
onEagerFinished () {
|
||||
adoptStyleSheets([eagerStyles])
|
||||
eagerStyles.ready = true
|
||||
adoptStyleSheets()
|
||||
onEagerFinish()
|
||||
console.info('Eager part of theme finished, waiting for lazy part to finish to store cache')
|
||||
},
|
||||
onLazyFinished () {
|
||||
adoptStyleSheets([eagerStyles, lazyStyles])
|
||||
eagerStyles.ready = true
|
||||
adoptStyleSheets()
|
||||
const cache = { engineChecksum: getEngineChecksum(), data: [eagerStyles.rules, lazyStyles.rules] }
|
||||
onFinish(cache)
|
||||
localforage.setItem('pleromafe-theme-cache', cache)
|
||||
|
|
@ -239,17 +232,18 @@ export const applyConfig = (input) => {
|
|||
.filter(([, v]) => v)
|
||||
.map(([k, v]) => `--${k}: ${v}`).join(';')
|
||||
|
||||
const styleEl = document.getElementById('theme-holder')
|
||||
const styleSheet = styleEl.sheet
|
||||
const styleSheet = createStyleSheet('theme-holder')
|
||||
|
||||
styleSheet.insertRule(`:root { ${rules} }`, 'index-max')
|
||||
styleSheet.addRule(`:root { ${rules} }`, 'index-max')
|
||||
|
||||
// TODO find a way to make this not apply to theme previews
|
||||
if (Object.prototype.hasOwnProperty.call(config, 'forcedRoundness')) {
|
||||
styleSheet.insertRule(` *:not(.preview-block) {
|
||||
styleSheet.addRule(` *:not(.preview-block) {
|
||||
--roundness: var(--forcedRoundness) !important;
|
||||
}`, 'index-max')
|
||||
}
|
||||
styleSheet.ready = true
|
||||
adoptStyleSheets()
|
||||
}
|
||||
|
||||
export const getResourcesIndex = async (url, parser = JSON.parse) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue