Adding in CSS and HTML linting. Fixes 72
This commit is contained in:
parent
1e6b684915
commit
71001050b4
7 changed files with 231 additions and 105 deletions
8
.htmllintrc
Normal file
8
.htmllintrc
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"plugins": [],
|
||||
|
||||
"id-class-style": "dash",
|
||||
"indent-style": "spaces",
|
||||
"indent-width": 2,
|
||||
"attr-name-ignore-regex": "http-equiv|data-*"
|
||||
}
|
18
.stylelintrc
Normal file
18
.stylelintrc
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "stylelint-config-standard",
|
||||
|
||||
"ignoreFiles": ["webextension/css/*.min.css"],
|
||||
|
||||
"rules": {
|
||||
"declaration-block-no-duplicate-properties": true,
|
||||
"declaration-block-properties-order": "alphabetical",
|
||||
"property-blacklist": [
|
||||
"/height/",
|
||||
"/width/",
|
||||
"/top/",
|
||||
"/bottom/",
|
||||
"padding",
|
||||
"margin"
|
||||
]
|
||||
}
|
||||
}
|
13
index.js
13
index.js
|
@ -652,21 +652,22 @@ ContainerWindow.prototype = {
|
|||
|
||||
const mouseoutHandle = (e) => {
|
||||
let el = e.target;
|
||||
do {
|
||||
if (el == this._panelElement ||
|
||||
el == button ||
|
||||
el == overflowButton) {
|
||||
while(el) {
|
||||
if (el === this._panelElement ||
|
||||
el === button ||
|
||||
el === overflowButton) {
|
||||
this._createTimeout();
|
||||
return;
|
||||
}
|
||||
} while(el = el.parentElement);
|
||||
el = el.parentElement;
|
||||
}
|
||||
};
|
||||
|
||||
[button, overflowButton].forEach((buttonElement) => {
|
||||
buttonElement.addEventListener("mouseover", () => {
|
||||
showPopup(buttonElement);
|
||||
});
|
||||
buttonElement.addEventListener("click", _ => {
|
||||
buttonElement.addEventListener("click", () => {
|
||||
this.hidePanel();
|
||||
});
|
||||
buttonElement.addEventListener("mouseout", mouseoutHandle);
|
||||
|
|
11
package.json
11
package.json
|
@ -12,8 +12,11 @@
|
|||
"addons-linter": "^0.15.14",
|
||||
"eslint": "^3.12.2",
|
||||
"eslint-plugin-promise": "^3.4.0",
|
||||
"htmllint-cli": "^0.0.5",
|
||||
"jpm": "^1.2.2",
|
||||
"npm-run-all": "^4.0.0"
|
||||
"npm-run-all": "^4.0.0",
|
||||
"stylelint": "^7.7.1",
|
||||
"stylelint-config-standard": "^15.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"firefox": ">=50.0"
|
||||
|
@ -31,7 +34,9 @@
|
|||
},
|
||||
"scripts": {
|
||||
"lint": "npm-run-all lint:*",
|
||||
"lint:js": "eslint .",
|
||||
"lint:addon": "addons-linter webextension --self-hosted"
|
||||
"lint:addon": "addons-linter webextension --self-hosted",
|
||||
"lint:css": "stylelint webextension/css/*.css",
|
||||
"lint:html": "htmllint webextension/*.html",
|
||||
"lint:js": "eslint ."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
body {
|
||||
min-inline-size: 200px;
|
||||
max-inline-size: 400px;
|
||||
inline-size: 264px;
|
||||
max-inline-size: 400px;
|
||||
min-inline-size: 200px;
|
||||
}
|
||||
|
||||
table {
|
||||
|
@ -28,12 +28,14 @@ table {
|
|||
}
|
||||
|
||||
.onboarding {
|
||||
margin: 16px;
|
||||
min-block-size: 480px;
|
||||
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
margin-block-end: 16px;
|
||||
margin-block-start: 16px;
|
||||
margin-inline-end: 16px;
|
||||
margin-inline-start: 16px;
|
||||
min-block-size: 480px;
|
||||
}
|
||||
|
||||
.onboarding h3 {
|
||||
|
@ -51,20 +53,23 @@ table {
|
|||
|
||||
.popup-bumper {
|
||||
inline-size: 100%;
|
||||
padding: .5em;
|
||||
padding-block-end: 0.5em;
|
||||
padding-block-start: 0.5em;
|
||||
padding-inline-end: 0.5em;
|
||||
padding-inline-start: 0.5em;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
align-items: center;
|
||||
block-size: 54px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.panel-header-text {
|
||||
font-weight: lighter;
|
||||
font-size: 16px;
|
||||
margin-bottom: 0;
|
||||
color: #4a4a4a;
|
||||
font-size: 16px;
|
||||
font-weight: lighter;
|
||||
margin-block-end: 0;
|
||||
}
|
||||
|
||||
.panel-header-button {
|
||||
|
@ -72,56 +77,64 @@ table {
|
|||
}
|
||||
|
||||
.icon {
|
||||
max-inline-size: 16px;
|
||||
block-size: 16px;
|
||||
max-inline-size: 16px;
|
||||
}
|
||||
|
||||
table.unstriped tbody tr {
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
background-color: #fefefe;
|
||||
border-block-end: 1px solid #f1f1f1;
|
||||
}
|
||||
|
||||
.userContext-icon {
|
||||
/* .userContext-icon is used natively, Bug 1333811 was raised to fix */
|
||||
.userContext-icon,
|
||||
.usercontext-icon {
|
||||
background-image: var(--identity-icon);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
filter: url('/img/filters.svg#fill');
|
||||
fill: var(--identity-icon-color);
|
||||
inline-size: 20px;
|
||||
block-size: 20px;
|
||||
fill: var(--identity-icon-color);
|
||||
filter: url('/img/filters.svg#fill');
|
||||
inline-size: 20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.container-panel-row:hover .userContext-icon {
|
||||
.container-panel-row:hover .usercontext-icon {
|
||||
background-image: url('/img/container-newtab.svg');
|
||||
filter: url('/img/filters.svg#fill');
|
||||
fill: 'gray';
|
||||
filter: url('/img/filters.svg#fill');
|
||||
}
|
||||
|
||||
.edit-identities {
|
||||
background: #DCDBDC;
|
||||
background: #dcdbdc;
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
align-items: center;
|
||||
background: #efefef;
|
||||
color: #000000;
|
||||
block-size: 54px;
|
||||
color: #000;
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
block-size: 54px;
|
||||
inline-size: 100%;
|
||||
}
|
||||
|
||||
.footer-columns {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-block-end: 0;
|
||||
margin-block-start: 0;
|
||||
margin-inline-end: 0;
|
||||
margin-inline-start: 0;
|
||||
padding-block-end: 0;
|
||||
padding-block-start: 0;
|
||||
padding-inline-end: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
.footer-button {
|
||||
margin-bottom: 0;
|
||||
border-radius: 0;
|
||||
margin-block-end: 0;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
|
@ -129,14 +142,66 @@ table.unstriped tbody tr {
|
|||
}
|
||||
|
||||
.edit-containers-text {
|
||||
text-align: center;
|
||||
border-inline-end: solid 1px #d8d8d8;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.edit-containers-text a {
|
||||
color: #0a0a0a;
|
||||
}
|
||||
|
||||
.edit-container-panel [type="radio"] {
|
||||
display: inline;
|
||||
margin-inline-start: -17px;
|
||||
text-indent: -999999px;
|
||||
}
|
||||
|
||||
.edit-container-panel [type="radio"]:first-child {
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.edit-container-panel label {
|
||||
background: #fff;
|
||||
block-size: 20px;
|
||||
filter: none;
|
||||
inline-size: 20px;
|
||||
margin-block-end: 0;
|
||||
margin-block-start: 0;
|
||||
margin-inline-end: 0;
|
||||
margin-inline-start: 0;
|
||||
offset-inline-start: -18px;
|
||||
padding-block-end: 0;
|
||||
padding-block-start: 0;
|
||||
padding-inline-end: 0;
|
||||
padding-inline-start: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.edit-container-panel [type="radio"]:checked + label {
|
||||
outline: 1px solid grey;
|
||||
-moz-outline-radius: 100%;
|
||||
}
|
||||
|
||||
.edit-container-panel label::before {
|
||||
background: var(--identity-icon);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: calc(100% - 4px);
|
||||
block-size: calc(100% - 2px);
|
||||
border: unset;
|
||||
fill: var(--identity-icon-color);
|
||||
filter: url('/img/filters.svg#fill');
|
||||
inline-size: calc(100% - 2px);
|
||||
margin-block-end: 1px;
|
||||
margin-block-start: 1px;
|
||||
margin-inline-end: 1px;
|
||||
margin-inline-start: 1px;
|
||||
padding-block-end: 0;
|
||||
padding-block-start: 0;
|
||||
padding-inline-end: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
[data-identity-color="blue"] {
|
||||
--identity-tab-color: #0996f8;
|
||||
--identity-icon-color: #00a7e0;
|
||||
|
@ -149,7 +214,7 @@ table.unstriped tbody tr {
|
|||
|
||||
[data-identity-color="green"] {
|
||||
--identity-tab-color: #57bd35;
|
||||
--identity-icon-color: #7dc14c;
|
||||
--identity-icon-color: #7dc14c;
|
||||
}
|
||||
|
||||
[data-identity-color="yellow"] {
|
||||
|
@ -198,17 +263,23 @@ table.unstriped tbody tr {
|
|||
}
|
||||
|
||||
.container-info-panel-header {
|
||||
block-size: 33px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
block-size: 33px;
|
||||
border-block-end: 1px solid #ebebeb;
|
||||
display: flex;
|
||||
margin-block-end: 10px;
|
||||
padding: 0 20px;
|
||||
padding-block-end: 0;
|
||||
padding-block-start: 0;
|
||||
padding-inline-end: 20px;
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
|
||||
.container-info-panel-hide {
|
||||
margin-bottom: 8px;
|
||||
padding: 0 20px;
|
||||
margin-block-end: 8px;
|
||||
padding-block-end: 0;
|
||||
padding-block-start: 0;
|
||||
padding-inline-end: 20px;
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
|
||||
.container-info-panel-hideorshow-icon {
|
||||
|
@ -218,7 +289,10 @@ table.unstriped tbody tr {
|
|||
.container-info-panel-movetabs {
|
||||
border-block-end: 1px solid #ebebeb;
|
||||
margin-block-end: 10px;
|
||||
padding: 0 20px;
|
||||
padding-block-end: 0;
|
||||
padding-block-start: 0;
|
||||
padding-inline-end: 20px;
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
|
@ -226,24 +300,24 @@ table.unstriped tbody tr {
|
|||
}
|
||||
|
||||
.edit-containers-panel-footer a {
|
||||
color: #ffffff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.edit-containers-exit-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #248aeb;
|
||||
block-size: 100%;
|
||||
color: #ffffff;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.choose-color-icon {
|
||||
padding-inline-start: 17px;
|
||||
padding-inline-end: 7px;
|
||||
padding-inline-start: 17px;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
max-block-size: 480px;
|
||||
overflow: auto;
|
||||
max-height: 480px;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
const CONTAINER_HIDE_SRC = "/img/container-hide.svg";
|
||||
const CONTAINER_UNHIDE_SRC = "/img/container-unhide.svg";
|
||||
|
||||
const DEFAULT_COLOR = "blue";
|
||||
const DEFAULT_ICON = "circle";
|
||||
|
||||
// List of panels
|
||||
const P_ONBOARDING_1 = "onboarding1";
|
||||
const P_ONBOARDING_2 = "onboarding2";
|
||||
|
@ -303,35 +306,37 @@ Logic.registerPanel(P_CONTAINER_INFO, {
|
|||
return browser.runtime.sendMessage({
|
||||
method: "getTabs",
|
||||
userContextId: identity.userContextId,
|
||||
}).then(tabs => {
|
||||
// For each one, let's create a new line.
|
||||
const fragment = document.createDocumentFragment();
|
||||
for (let tab of tabs) { // eslint-disable-line prefer-const
|
||||
const tr = document.createElement("tr");
|
||||
fragment.appendChild(tr);
|
||||
tr.classList.add("container-info-tab");
|
||||
tr.innerHTML = `
|
||||
<td><img class="icon" src="${tab.favicon}" /></td>
|
||||
<td>${tab.title}</td>`;
|
||||
}).then(this.buildInfoTable);
|
||||
},
|
||||
|
||||
// On click, we activate this tab. But only if this tab is active.
|
||||
if (tab.active) {
|
||||
tr.classList.add("clickable");
|
||||
tr.addEventListener("click", () => {
|
||||
browser.runtime.sendMessage({
|
||||
method: "showTab",
|
||||
tabId: tab.id,
|
||||
}).then(() => {
|
||||
window.close();
|
||||
}).catch(() => {
|
||||
window.close();
|
||||
});
|
||||
buildInfoTable(tabs) {
|
||||
// For each one, let's create a new line.
|
||||
const fragment = document.createDocumentFragment();
|
||||
for (let tab of tabs) { // eslint-disable-line prefer-const
|
||||
const tr = document.createElement("tr");
|
||||
fragment.appendChild(tr);
|
||||
tr.classList.add("container-info-tab");
|
||||
tr.innerHTML = `
|
||||
<td><img class="icon" src="${tab.favicon}" /></td>
|
||||
<td>${tab.title}</td>`;
|
||||
|
||||
// On click, we activate this tab. But only if this tab is active.
|
||||
if (tab.active) {
|
||||
tr.classList.add("clickable");
|
||||
tr.addEventListener("click", () => {
|
||||
browser.runtime.sendMessage({
|
||||
method: "showTab",
|
||||
tabId: tab.id,
|
||||
}).then(() => {
|
||||
window.close();
|
||||
}).catch(() => {
|
||||
window.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("container-info-table").appendChild(fragment);
|
||||
});
|
||||
document.getElementById("container-info-table").appendChild(fragment);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -406,6 +411,8 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
|
||||
// This method is called when the object is registered.
|
||||
initialize() {
|
||||
this.initializeRadioButtons();
|
||||
|
||||
document.querySelector("#edit-container-panel-back-arrow").addEventListener("click", () => {
|
||||
Logic.showPreviousPanel();
|
||||
});
|
||||
|
@ -416,12 +423,13 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
|
||||
document.querySelector("#edit-container-ok-link").addEventListener("click", () => {
|
||||
const identity = Logic.currentIdentity();
|
||||
const formValues = new FormData(document.getElementById("edit-container-panel-form"));
|
||||
browser.runtime.sendMessage({
|
||||
method: identity.userContextId ? "updateIdentity" : "createIdentity",
|
||||
userContextId: identity.userContextId || 0,
|
||||
name: document.getElementById("edit-container-panel-name-input").value || Logic.generateIdentityName(),
|
||||
icon: this._randomIcon(),
|
||||
color: this._randomColor(),
|
||||
icon: formValues.get("container-icon") || DEFAULT_ICON,
|
||||
color: formValues.get("container-color") || DEFAULT_COLOR,
|
||||
}).then(() => {
|
||||
return Logic.refreshIdentities();
|
||||
}).then(() => {
|
||||
|
@ -432,27 +440,46 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
});
|
||||
},
|
||||
|
||||
initializeRadioButtons() {
|
||||
const colorRadioTemplate = (containerColor) => {
|
||||
return `<input type="radio" value="${containerColor}" name="container-color" id="edit-container-panel-choose-color-${containerColor}" />
|
||||
<label for="edit-container-panel-choose-color-${containerColor}" class="usercontext-icon choose-color-icon" data-identity-icon="circle" data-identity-color="${containerColor}">`;
|
||||
};
|
||||
const colors = ["blue", "turquoise", "green", "yellow", "orange", "red", "pink", "purple" ];
|
||||
const colorRadioFieldset = document.getElementById("edit-container-panel-choose-color");
|
||||
colors.forEach((containerColor) => {
|
||||
const templateInstance = document.createElement("span");
|
||||
templateInstance.innerHTML = colorRadioTemplate(containerColor);
|
||||
colorRadioFieldset.appendChild(templateInstance);
|
||||
});
|
||||
|
||||
const iconRadioTemplate = (containerIcon) => {
|
||||
return `<input type="radio" value="${containerIcon}" name="container-icon" id="edit-container-panel-choose-icon-${containerIcon}" />
|
||||
<label for="edit-container-panel-choose-icon-${containerIcon}" class="usercontext-icon choose-color-icon" data-identity-color="grey" data-identity-icon="${containerIcon}">`;
|
||||
};
|
||||
const icons = ["fingerprint", "briefcase", "dollar", "cart", "circle"];
|
||||
const iconRadioFieldset = document.getElementById("edit-container-panel-choose-icon");
|
||||
icons.forEach((containerIcon) => {
|
||||
const templateInstance = document.createElement("span");
|
||||
templateInstance.innerHTML = iconRadioTemplate(containerIcon);
|
||||
iconRadioFieldset.appendChild(templateInstance);
|
||||
});
|
||||
},
|
||||
|
||||
// This method is called when the panel is shown.
|
||||
prepare() {
|
||||
const identity = Logic.currentIdentity();
|
||||
document.querySelector("#edit-container-panel-name-input").value = identity.name || "";
|
||||
|
||||
// FIXME: color and icon must be set. But we need the UI first.
|
||||
[...document.querySelectorAll("[name='container-color']")].forEach(colorInput => {
|
||||
colorInput.checked = colorInput.value === identity.color;
|
||||
});
|
||||
[...document.querySelectorAll("[name='container-icon']")].forEach(iconInput => {
|
||||
iconInput.checked = iconInput.value === identity.image;
|
||||
});
|
||||
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
|
||||
// These 2 methods are for debugging only. We should remove them when we
|
||||
// finish the UI.
|
||||
_randomIcon() {
|
||||
const images = ["fingerprint", "briefcase", "dollar", "cart", "cirlce"];
|
||||
return images[Math.floor(Math.random() * images.length)];
|
||||
},
|
||||
|
||||
_randomColor() {
|
||||
const colors = ["blue", "turquoise", "green", "yellow", "orange", "red", "pink", "purple" ];
|
||||
return colors[Math.floor(Math.random() * colors.length)];
|
||||
},
|
||||
});
|
||||
|
||||
// P_CONTAINER_DELETE: Delete a container.
|
||||
|
|
|
@ -56,10 +56,10 @@
|
|||
<div class="small-2 columns panel-back-arrow clickable" id="close-container-info-panel">«</div>
|
||||
<div class="small-10 columns">
|
||||
<div class="row container-info-panel-header">
|
||||
<span class="userContext-icon" id="container-info-icon" data-identity-icon="" data-identity-color=""></span>
|
||||
<span class="usercontext-icon" id="container-info-icon"></span>
|
||||
<h3 id="container-info-name" class="panel-header-text"></h3>
|
||||
</div>
|
||||
<div class="row container-info-panel-hide container-info-has-tabs clickable" id="container-info-hideorshow" data-user-context-id="">
|
||||
<div class="row container-info-panel-hide container-info-has-tabs clickable" id="container-info-hideorshow">
|
||||
<img id="container-info-hideorshow-icon" alt="Hide Container icon" src="/img/container-hide.svg" class="icon container-info-panel-hideorshow-icon"/><span id="container-info-hideorshow-label">Hide this container</span><br/>
|
||||
</div>
|
||||
<div class="row container-info-panel-movetabs container-info-has-tabs clickable" id="container-info-movetabs">
|
||||
|
@ -104,27 +104,20 @@
|
|||
«
|
||||
</div>
|
||||
<div class="small-10 columns">
|
||||
<form>
|
||||
<form id="edit-container-panel-form">
|
||||
<p>
|
||||
<label>Name</label>
|
||||
<label for="edit-container-panel-name-input">Name</label>
|
||||
<input type="text" name="container-name" id="edit-container-panel-name-input"/>
|
||||
</p>
|
||||
<p>
|
||||
<label>Choose a color</label>
|
||||
<div id="edit-container-panel-choose-color">
|
||||
<span class="userContext-icon choose-color-icon" data-identity-icon="circle" data-identity-color="blue"></span>
|
||||
<span class="userContext-icon choose-color-icon" data-identity-icon="circle" data-identity-color="turquoise"></span>
|
||||
<span class="userContext-icon choose-color-icon" data-identity-icon="circle" data-identity-color="green"></span>
|
||||
<span class="userContext-icon choose-color-icon" data-identity-icon="circle" data-identity-color="yellow"></span>
|
||||
<span class="userContext-icon choose-color-icon" data-identity-icon="circle" data-identity-color="orange"></span>
|
||||
<span class="userContext-icon choose-color-icon" data-identity-icon="circle" data-identity-color="red"></span>
|
||||
<span class="userContext-icon choose-color-icon" data-identity-icon="circle" data-identity-color="pink"></span>
|
||||
<span class="userContext-icon choose-color-icon" data-identity-icon="circle" data-identity-color="purple"></span>
|
||||
</div>
|
||||
<fieldset id="edit-container-panel-choose-color">
|
||||
<legend>Choose a color</legend>
|
||||
</fieldset>
|
||||
</p>
|
||||
<p>
|
||||
<label>Choose an icon</label>
|
||||
<input type="text" />
|
||||
<fieldset id="edit-container-panel-choose-icon">
|
||||
<legend>Choose an icon</legend>
|
||||
</fieldset>
|
||||
</p>
|
||||
</form>
|
||||
<div class="row">
|
||||
|
@ -143,7 +136,7 @@
|
|||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<div class="row container-info-panel-header">
|
||||
<span class="userContext-icon" id="delete-container-icon" data-identity-icon="" data-identity-color=""></span>
|
||||
<span class="usercontext-icon" id="delete-container-icon"></span>
|
||||
<h3 id="delete-container-name" class="panel-header-text"></h3>
|
||||
</div>
|
||||
<div class="row delete-container-confirm">
|
||||
|
|
Loading…
Add table
Reference in a new issue