fx-compat: Add color picker CE (#2682)

This commit is contained in:
Abe Jellinek 2022-11-21 02:48:16 -05:00 committed by GitHub
parent 4dbb2d88b9
commit 4b09edfa42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 203 additions and 181 deletions

View file

@ -1,140 +0,0 @@
<?xml version="1.0"?>
<!--
An extension of the Mozilla colorpicker that allows for a custom set of colors
-->
<bindings id="colorpickerBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="custom-colorpicker" extends="chrome://global/content/bindings/colorpicker.xml#colorpicker">
<resources>
<stylesheet src="chrome://zotero/skin/bindings/customcolorpicker.css"/>
</resources>
<content>
<vbox anonid="tiles" flex="1" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<hbox>
<image class="colorpickertile" color="#000000"/>
</hbox>
</vbox>
</content>
<implementation implements="nsIDOMEventListener">
<constructor><![CDATA[
this.initialize();
this._colors = this.getAttribute('colors');
if (this._colors) {
this._cols = this.getAttribute('cols');
}
this.redraw();
]]></constructor>
<!-- Defaults from the Mozilla colorpicker -->
<field name="_defaultColors">
[
'L#FFFFFF','L#FFCCCC','L#FFCC99','L#FFFF99','L#FFFFCC','L#99FF99','L#99FFFF','L#CCFFFF','L#CCCCFF','L#FFCCFF',
'#CCCCCC','#FF6666','#FF9966','L#FFFF66','L#FFFF33','L#66FF99','L#33FFFF','L#66FFFF','#9999FF','#FF99FF',
'#C0C0C0','#FF0000','#FF9900','#FFCC66','L#FFFF00','L#33FF33','#66CCCC','#33CCFF','#6666CC','#CC66CC',
'#999999','#CC0000','#FF6600','#FFCC33','#FFCC00','#33CC00','#00CCCC','#3366FF','#6633FF','#CC33CC',
'#666666','#990000','#CC6600','#CC9933','#999900','#009900','#339999','#3333FF','#6600CC','#993399',
'#333333','#660000','#993300','#996633','#666600','#006600','#336666','#000099','#333399','#663366',
'#000000','#330000','#663300','#663333','#333300','#003300','#003333','#000066','#330099','#330033'
]
</field>
<field name="_defaultCols">10</field>
<property name="colors" onget="return this._colors ? this._colors : []">
<setter><![CDATA[
if (typeof val == 'string') {
val = val ? val.split(',') : null;
}
this._colors = val;
this.redraw();
]]></setter>
</property>
<property name="cols" onget="return this.getAttribute('cols')">
<setter><![CDATA[
this.setAttribute('cols', val);
this.redraw();
]]></setter>
</property>
<method name="redraw">
<body><![CDATA[
//Zotero.debug("Redrawing color picker");
var tiles = document.getAnonymousNodes(this)[0];
var cols = this.getAttribute('cols') || this._defaultCols;
var colors = this._colors.concat() || this._defaultColors.concat();
while (tiles.hasChildNodes()) {
tiles.removeChild(tiles.firstChild);
}
var rows = Math.ceil(colors.length / cols);
var tileWidth = this.getAttribute('tileWidth');
var tileHeight = this.getAttribute('tileHeight');
for (let i=0; i<rows; i++) {
var hbox = document.createElement('hbox');
for (let j=0; j<cols; j++) {
let color = colors.shift();
if (!color) {
break;
}
let light = color.charAt(0) == 'L';
color = light ? color.substr(1) : color;
let image = document.createElement('image');
image.className = 'colorpickertile' + (light ? ' cp-light' : '');
image.setAttribute('color', color);
let dataURI = "data:image/svg+xml,<svg style='background-color: "
+ encodeURIComponent(color) + "' xmlns='http://www.w3.org/2000/svg' />";
image.setAttribute('src', dataURI);
if (tileWidth) {
image.width = tileWidth;
}
if (tileHeight) {
image.height = tileHeight;
}
hbox.appendChild(image);
}
tiles.appendChild(hbox);
}
]]></body>
</method>
</implementation>
</binding>
<!-- The content of the Mozilla colorpicker-button, but with a customcolorpicker
with some extra inherited attributes instead -->
<binding id="custom-colorpicker-button" display="xul:menu"
extends="chrome://global/content/bindings/colorpicker.xml#colorpicker-button">
<resources>
<stylesheet src="chrome://zotero/skin/bindings/customcolorpicker.css"/>
</resources>
<content>
<xul:image class="colorpicker-button-colorbox" anonid="colorbox" flex="1" xbl:inherits="disabled"/>
<xul:panel class="colorpicker-button-menupopup"
anonid="colorpopup" noautofocus="true" level="top"
onmousedown="event.stopPropagation()"
onpopupshowing="this._colorPicker.onPopupShowing()"
onpopuphiding="this._colorPicker.onPopupHiding()"
onselect="this._colorPicker.pickerChange()">
<xul:customcolorpicker xbl:inherits="palettename,disabled,cols,columns,tileWidth,tileHeight" allowevents="true" anonid="colorpicker"/>
</xul:panel>
</content>
<implementation>
<property name="colors" onget="return this.mPicker.colors" onset="this.mPicker.colors = val"/>
</implementation>
</binding>
</bindings>

View file

@ -0,0 +1,146 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2020 Corporation for Digital Scholarship
Vienna, Virginia, USA
https://www.zotero.org
This file is part of Zotero.
Zotero is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Zotero is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
***** END LICENSE BLOCK *****
*/
"use strict";
{
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/base.js", this);
class ColorPicker extends XULElementBase {
stylesheets = ['chrome://global/skin/', 'chrome://zotero-platform/content/colorPicker.css'];
content = MozXULElement.parseXULToFragment(`
<vbox>
<html:button id="button">
<html:span id="button-tile"/>
</html:button>
<panel id="panel">
<html:div id="grid"/>
</panel>
</vbox>
`);
get color() {
return this.getAttribute('color') || '#000000';
}
set color(color) {
this.setAttribute('color', color);
}
get colors() {
if (this.hasAttribute('colors')) {
return this.getAttribute('colors').split(',');
}
else {
return [
'#FF6666', '#FF8C19', '#999999',
'#5FB236', '#009980', '#2EA8E5',
'#576DD9', '#A28AE5', '#A6507B'
];
}
}
set colors(colors) {
this.setAttribute('colors', colors.join(','));
}
get cols() {
return this.getAttribute('cols') || 3;
}
set cols(cols) {
this.setAttribute('cols', cols);
}
get tileWidth() {
return this.getAttribute('tileWidth') || 24;
}
set tileWidth(width) {
this.setAttribute('tileWidth', width);
}
get tileHeight() {
return this.getAttribute('tileHeight') || 24;
}
set tileHeight(height) {
this.setAttribute('tileHeight', height);
}
get disabled() {
return this.hasAttribute('disabled');
}
set disabled(disabled) {
this.toggleAttribute(disabled, !!disabled);
}
init() {
let button = this.shadowRoot.getElementById('button');
let panel = this.shadowRoot.getElementById('panel');
let grid = this.shadowRoot.getElementById('grid');
button.addEventListener('click', () => {
grid.style.gridTemplateColumns = `repeat(${this.cols}, ${this.tileWidth}px)`;
grid.style.gridAutoRows = `${this.tileHeight}px`;
panel.openPopup(button, 'after_start', 0, 0, false, false);
});
}
static get observedAttributes() {
return ['color', 'colors', 'cols', 'tileWidth', 'tileHeight'];
}
attributeChangedCallback(attrName, oldVal, newVal) {
if (attrName == 'color') {
this.shadowRoot.getElementById('button-tile').style.backgroundColor = newVal;
}
else if (attrName == 'colors') {
let grid = this.shadowRoot.getElementById('grid');
grid.innerHTML = '';
for (let color of newVal.split(',')) {
let tile = document.createElement('div');
tile.classList.add('grid-tile');
tile.style.backgroundColor = color;
tile.addEventListener('click', () => {
this.color = color;
this.shadowRoot.getElementById('panel').hidePopup();
});
grid.append(tile);
}
}
else if (attrName == 'disabled') {
this.shadowRoot.getElementById('button').disabled = !!newVal;
}
}
}
customElements.define("color-picker", ColorPicker);
}

View file

@ -30,6 +30,10 @@ var Zotero_Tag_Color_Chooser = new function() {
this.init = function () {
var dialog = document.querySelector('dialog');
window.addEventListener('dialogaccept', () => Zotero_Tag_Color_Chooser.onDialogAccept());
window.addEventListener('dialogcancel', () => Zotero_Tag_Color_Chooser.onDialogCancel());
window.addEventListener('dialogextra1', () => Zotero_Tag_Color_Chooser.onDialogRemoveColor());
try {
// Set font size from pref

View file

@ -38,19 +38,22 @@
<dialog
buttons="cancel,accept"
buttonlabelaccept="&zotero.tagColorChooser.setColor;"
buttonlabelextra1="&zotero.tagColorChooser.removeColor;"
ondialogaccept="Zotero_Tag_Color_Chooser.onDialogAccept()"
ondialogcancel="Zotero_Tag_Color_Chooser.onDialogCancel()"
ondialogextra1="Zotero_Tag_Color_Chooser.onDialogRemoveColor()"
>
<script src="include.js"/>
<script src="tagColorChooser.js"/>
buttonlabelextra1="&zotero.tagColorChooser.removeColor;">
<script>
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
Services.scriptloader.loadSubScript("chrome://zotero/content/include.js", this);
Services.scriptloader.loadSubScript("chrome://zotero/content/tagColorChooser.js", this);
// Custom elements
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/colorPicker.js", this);
</script>
<vbox id="tag-color-chooser-container">
<hbox align="center">
<label value="&zotero.tagColorChooser.color;" control="color-picker"/>
<customcolorpicker id="color-picker" type="button" disabled="true"/>
<color-picker id="color-picker" disabled="true"/>
<separator width="20"/>
<label value="&zotero.tagColorChooser.position;" control="tag-position" disabled="true"/>
<menulist id="tag-position" disabled="true" sizetopopup="always"

View file

@ -1,24 +0,0 @@
customcolorpicker[type="button"] {
width: 38px;
height: 24px;
border: 1px solid #a7a7a7;
background-color: ThreeDFace;
padding: 3px;
-moz-appearance: button-bevel;
}
.colorpickertile[hover="true"], .cp-light[hover="true"] {
border: 0;
}
.colorpickertile[selected="true"] {
border : 1px outset #C0C0C0;
}
.colorpickertile[hover="true"]:not([selected="true"]) {
border : 1px dotted #A7A7A7;
}
.cp-light[hover="true"]:not([selected="true"]) {
border : 1px dotted #000000;
}

View file

@ -21,14 +21,6 @@ textbox[type="styled"]
-moz-binding: url('chrome://zotero/content/bindings/styled-textbox.xml#styled-textbox');
}
customcolorpicker {
-moz-binding: url(chrome://zotero/content/bindings/customcolorpicker.xml#custom-colorpicker);
}
customcolorpicker[type=button] {
-moz-binding: url(chrome://zotero/content/bindings/customcolorpicker.xml#custom-colorpicker-button);
}
zoteromergegroup {
-moz-binding: url('chrome://zotero/content/bindings/merge.xml#merge-group');
}

1
scss/_colorPicker.scss Normal file
View file

@ -0,0 +1 @@
@import "components/colorPicker";

View file

@ -0,0 +1 @@
@import "colorPicker";

View file

@ -0,0 +1 @@
@import "colorPicker";

View file

@ -0,0 +1 @@
@import "colorPicker";

View file

@ -0,0 +1,37 @@
#button {
width: 38px;
height: 24px;
appearance: none;
border: 1px solid #a7a7a7;
background-color: white;
padding: 3px;
&:active {
background-color: #ddd;
}
}
#button-tile {
display: block;
background-color: #000000;
width: 100%;
height: 100%;
}
#grid {
display: grid;
margin: 2px;
gap: 2px;
}
.grid-tile:hover {
border: 0;
}
.grid-tile[selected="true"] {
border: 1px outset #C0C0C0;
}
.grid-tile:hover:not([selected="true"]) {
border: 1px dotted #A7A7A7;
}