Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions com.woltlab.wcf/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
<instruction type="objectType" />
<instruction type="script" run="standalone">acp/update_com.woltlab.wcf_6.3_styleTemplateGroup.php</instruction>
<instruction type="script" run="standalone">acp/update_com.woltlab.wcf_6.3_styleVariables.php</instruction>
<instruction type="script" run="standalone">acp/update_com.woltlab.wcf_6.3_styleProtection.php</instruction>
<instruction type="script" run="standalone">acp/update_com.woltlab.wcf_6.3_styleAuthoredValues.php</instruction>
<instruction type="database" run="standalone">acp/database/update_com.woltlab.wcf_6.3_step2.php</instruction>
<instruction type="script" run="standalone">acp/update_com.woltlab.wcf_6.3_embeddedObjects.php</instruction>

Expand Down
67 changes: 39 additions & 28 deletions ts/WoltLabSuite/Core/Acp/Ui/Style/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
*/

import * as Ajax from "../../../Ajax";
import * as Core from "../../../Core";
import * as ColorUtil from "../../../ColorUtil";
import DomUtil from "../../../Dom/Util";
import * as EventHandler from "../../../Event/Handler";
import * as UiScreen from "../../../Ui/Screen";
Expand All @@ -22,7 +22,24 @@ let _updateRegionMarker: () => void;

interface StyleEditorOptions {
isTainted: boolean;
styleId: number;
}

/**
* Compares two colors regardless of their notation, e.g. `.8` and `0.8` for the alpha channel.
*/
function isSameColor(a: string, b: string): boolean {
if (a === b) {
return true;
}

if (!ColorUtil.isValidColor(a) || !ColorUtil.isValidColor(b)) {
return false;
}

const colorA = ColorUtil.stringToRgba(a);
const colorB = ColorUtil.stringToRgba(b);

return colorA.r === colorB.r && colorA.g === colorB.g && colorA.b === colorB.b && colorA.a === colorB.a;
}

/**
Expand Down Expand Up @@ -81,28 +98,6 @@ function handleScss(isTainted: boolean): void {
}
}

function handleProtection(styleId: number): void {
const button = document.getElementById("styleDisableProtectionSubmit") as HTMLButtonElement;
const checkbox = document.getElementById("styleDisableProtectionConfirm") as HTMLInputElement;

checkbox.addEventListener("change", () => {
button.disabled = !checkbox.checked;
});

button.addEventListener("click", () => {
Ajax.apiOnce({
data: {
actionName: "markAsTainted",
className: "wcf\\data\\style\\StyleAction",
objectIDs: [styleId],
},
success: () => {
window.location.reload();
},
});
});
}

/**
* Mirrors the selected style options in the preview, e.g. `data-page-header-layout`.
*/
Expand Down Expand Up @@ -206,11 +201,30 @@ function initVisualEditor(): void {
const wrapper = document.getElementById("spVariablesWrapper")!;
wrapper.querySelectorAll(".styleVariableColor").forEach((colorField: HTMLElement) => {
const variableName = colorField.dataset.store!.replace(/_value$/, "");
const input = document.getElementById(colorField.dataset.store!) as HTMLInputElement;
const restoreButton = wrapper.querySelector<HTMLButtonElement>(
`.spColorRestore[data-store="${colorField.dataset.store!}"]`,
);

const updateRestoreButton = () => {
if (restoreButton !== null) {
restoreButton.hidden = isSameColor(input.value, restoreButton.dataset.authoredColor!);
}
};

restoreButton?.addEventListener("click", () => {
const authoredColor = restoreButton.dataset.authoredColor!;

input.value = authoredColor;
colorField.dataset.color = authoredColor;
colorField.style.setProperty("background-color", authoredColor);
});

const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === "style") {
spWindow.style.setProperty(`--${variableName}`, colorField.style.getPropertyValue("background-color"));
updateRestoreButton();
}
});
});
Expand All @@ -220,6 +234,7 @@ function initVisualEditor(): void {
});

spWindow.style.setProperty(`--${variableName}`, colorField.style.getPropertyValue("background-color"));
updateRestoreButton();
});

// category selection by clicking on the area
Expand Down Expand Up @@ -281,10 +296,6 @@ export function setup(options: StyleEditorOptions): void {
handleLayoutWidth();
handleScss(options.isTainted);

if (!options.isTainted) {
handleProtection(options.styleId);
}

initVisualEditor();
handleStyleOptions();

Expand Down
7 changes: 4 additions & 3 deletions ts/WoltLabSuite/Core/Ui/Color/Picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,17 @@ class UiColorPicker implements DialogCallbackObject {
this.opacityInput!.addEventListener("input", (event) => {
this.setOpacity(event);
});

},
onShow: () => {
// The stored value can change while the dialog is closed.
if (ColorUtil.isValidColor(this.input.value)) {
this.setInitialColor(this.input.value);
} else if (this.element.dataset.color && ColorUtil.isValidColor(this.element.dataset.color)) {
this.setInitialColor(this.element.dataset.color);
} else {
this.setInitialColor("#FFF0");
}
},
onShow: () => {

this.colorTextInput!.focus();
this.colorTextInput!.select();
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@
->columns([
IntDatabaseTableColumn::create('templateGroupID'),
]),
PartialDatabaseTable::create('wcf1_style_variable_value')
->columns([
MediumtextDatabaseTableColumn::create('authoredValue'),
MediumtextDatabaseTableColumn::create('authoredValueDarkMode'),
]),
PartialDatabaseTable::create('wcf1_user_activity_event')
->columns([
IntDatabaseTableColumn::create('userID'),
Expand Down
11 changes: 11 additions & 0 deletions wcfsetup/install/files/acp/style/acpStyleEditor.css
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,17 @@ html:not(.touch) .spColorBox {
display: flex;
flex: 0 0 auto;
}
.spColorRestore {
color: var(--wcfContentDimmedText);
flex: 0 0 auto;
margin-left: auto;
}
.spColorRestore:not([hidden]) {
display: flex;
}
.spColorRestore:hover {
color: var(--wcfContentText);
}
#spWindow[data-page-header-layout="classic"] + #spSidebar .spColorScope[data-style-option="pageHeaderLayout"],
#spWindow[data-page-footer-layout="classic"] + #spSidebar .spColorScope[data-style-option="pageFooterLayout"] {
display: none;
Expand Down
Loading
Loading