Commit 04165438 authored by ransome1's avatar ransome1
Browse files

Merge branch 'develop'

parents 28f89e91 01ee0950
......@@ -12,14 +12,12 @@ snap/local/
*.db:encryptable
*.db
System Volume Information/
build/
Thumbs.db
flatpak/generated-sources.json
flatpak/com.github.ransome1.sleek.yml
assets/icons/bak
squashfs-root/
.eslintrc.json
build/
package-lock.json
.vs/
.vscode/
......
{
"name": "sleek",
"productName": "sleek",
"version": "1.0.7",
"version": "1.0.8",
"description": "Todo app based on todo.txt for Linux, Windows and MacOS, free and open-source",
"synopsis": "Todo app based on todo.txt for Linux, Windows and MacOS, free and open-source",
"category": "ProjectManagement",
......@@ -92,18 +92,17 @@
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"scripts": {
"build:windows": "yarn build:css && electron-builder -w --publish never",
"build:macos": "yarn build:css && electron-builder -m --publish never",
"build:linux": "yarn build:css && electron-builder -l --publish never",
"build:appx": "electron-builder -w appx --publish never",
"build:pacman": "electron-builder -l pacman --publish never",
"build:windows": "yarn build:css && yarn build:pegjs && electron-builder -w --publish never",
"build:macos": "yarn build:css && yarn build:pegjs && electron-builder -m --publish never",
"build:linux": "yarn build:css && yarn build:pegjs && electron-builder -l --publish never",
"build:appx": "yarn build:css && yarn build:pegjs && electron-builder -w appx --publish never",
"build:appimage": "yarn build:css && yarn build:pegjs && electron-builder -l AppImage --publish never",
"pack": "electron-builder --dir",
"lint": "eslint --ext .js, src --ext .mjs, src",
"test": "mocha --timeout 10000",
"test1": "mocha ./test/onboarding.js --timeout 10000",
"build:css": "sass src/scss/style.scss:src/css/style.css",
"build:pegjs": "peggy --format es --output src/js/filterlang.mjs src/js/filterlang.pegjs",
"pack": "yarn build:css && yarn build:pegjs && electron-builder --dir",
"lint": "eslint --ext .js, src --ext .mjs, src",
"test": "mocha --timeout 10000",
"test1": "mocha ./test/createTodos.js --timeout 10000",
"sass": "sass -w src/scss/style.scss:src/css/style.css",
"start": "yarn sass & electron ."
},
......
name: sleek
base: core18
version: '1.0.8'
summary: Todo app based on the todo.txt format for Linux, free and open-source
description: |
sleek is an open-source todo app that makes use of the todo.txt format. sleeks GUI is modern and simple but still offers a decent set of functions which help users getting things done. sleek is available as a client for Windows, MacOS and Linux.
......@@ -55,10 +56,6 @@ parts:
--prune=true --out $SNAPCRAFT_PART_INSTALL/
mv $SNAPCRAFT_PART_INSTALL/$SNAPCRAFT_PROJECT_NAME-linux-* \
$SNAPCRAFT_PART_INSTALL/sleek
VER=$(npm show sleek version)
echo "VERSION $(npm show sleek version)"
snapcraftctl set-version $VER
stage-packages:
- libnss3
cleanup:
......
export function createModalJail(modal) {
// add all the elements inside modal which you want to make focusable
const focusableElements = 'a.button, [tabindex]:not([tabindex="-1"])';
const focusableElements = '[tabindex]:not([tabindex="-1"])';
const firstFocusableElement = modal.querySelectorAll(focusableElements)[0]; // get first element to be focused inside modal
const focusableContent = modal.querySelectorAll(focusableElements);
const lastFocusableElement = focusableContent[focusableContent.length - 1]; // get last element to be focused inside modal
......
This diff is collapsed.
This diff is collapsed.
......@@ -24,21 +24,20 @@
<nav>
<ul>
<li class="logo">sleek</li>
<li id="navBtnAddTodo" tabindex="0"><i class="fas fa-plus"></i></li>
<li id="navBtnFilter" class="drawerTrigger" data-drawer="filterDrawer" tabindex="0"><i class="fas fa-filter"></i></li>
<li id="navBtnView" class="drawerTrigger" data-drawer="viewDrawer"tabindex="0"><i class="fas fa-sliders-h"></i></li>
<li id="btnOpenTodoFile" tabindex="-1"><i class="fas fa-folder-open"></i></li>
<li id="btnTheme" tabindex="-1"><i class="fas fa-adjust"></i></li>
<li><a href="#" id="navBtnAddTodo" tabindex="0"><i class="fas fa-plus"></i></a></li>
<li><a href="#" id="navBtnFilter" class="drawerTrigger" data-drawer="filterDrawer" tabindex="0"><i class="fas fa-filter"></i></a></li>
<li><a href="#" id="navBtnView" class="drawerTrigger" data-drawer="viewDrawer"tabindex="0"><i class="fas fa-sliders-h"></i></a></li>
<li><a href="#" id="btnOpenTodoFile" tabindex="0"><i class="fas fa-folder-open"></i></a></li>
</ul>
<ul>
<li id="navBtnSettings" tabindex="-1"><i class="fas fa-cog"></i></li>
<li id="navBtnHelp" tabindex="-1"><i class="fas fa-question-circle"></i></li>
<li><a href="#" id="navBtnSettings" tabindex="-1"><i class="fas fa-cog"></i></a></li>
<li><a href="#" id="navBtnHelp" tabindex="-1"><i class="fas fa-question-circle"></i></a></li>
</ul>
<div id="drawerContainer">
<section id="filterDrawer" class="drawer dropdown" tabindex="0">
<div class="container">
<div id="todoFilters"></div>
<button id="btnFiltersResetFilters" class="button btnResetFilters" tabindex="0"><i class="fas fa-ban"></i>&nbsp;<span></span></button>
<button id="btnFiltersResetFilters" class="btnResetFilters" tabindex="0"><i class="fas fa-ban"></i>&nbsp;<span></span></button>
</div>
</section>
<section id="viewDrawer" class="drawer dropdown" tabindex="0">
......@@ -178,7 +177,7 @@
</table>
</div>
</section>
<a href="#" id="drawerClose" tabindex="0"><i class="fas fa-chevron-left"></i></a>
<button id="drawerClose" tabindex="0"><i class="fas fa-chevron-left"></i></button>
<div id="handle"></div>
</div>
</nav>
......@@ -187,24 +186,19 @@
<div id="todoTableWrapper" class="column content">
<section id="todoTableSearchContainer" class="control has-icons-left">
<div class="column">
<input id="todoTableSearch" class="input is-medium" type="text" placeholder="Search" tabindex="10">
<span class="icon is-left">
<i class="fas fa-search"></i>
</span>
</div>
<section id="todoTableSearchContainer" class="inputWrapper">
<a href="https://github.com/ransome1/sleek/wiki/FIlter-Expressions-for-Advanced-Search" target="_blank" class="todoTableSearchQuestionmark"><i class="fas fa-question-circle"></i></a>
<i class="fas fa-search"></i>
<label id="todoTableSearchLabel" for="todoTableSearch"></label>
<input id="todoTableSearch" class="input is-medium" type="search" tabindex="1" placeholder="(A) Todo text +project @context due:2020-12-12 rec:d">
<button id="todoTableSearchAddTodo" class="tag" tabindex="5"><i class="fas fa-plus"></i>&nbsp;Add as todo</button>
<section id="resultStats">
<span class="tag"></span>
</section>
</section>
<div id="resultStats">
<span class="tag"></span>
</div>
<section id="todoTable" tabindex="-1">
<div id="todoTableContainer"></div>
</section>
<section id="todoTable" tabindex="-1"></section>
<section id="onboardingContainer" class="contentContainer">
<h1 id="welcomeToSleek" class="title is-1"></h1>
......@@ -225,7 +219,7 @@
<h1 id="addTodoContainerHeadline" class="title is-1"></h1>
<p id="addTodoContainerSubtitle" class="subtitle"></p>
<p class="file is-boxed is-centered">
<a href="#" id="btnAddTodoContainer" class="btnOnboarding">
<a href="#" id="btnAddTodoContainer" class="btnOnboarding" tabindex="0">
<i class="fas fa-plus"></i>
<span id="addTodoContainerButton" class="file-label"></span>
</a>
......@@ -235,26 +229,23 @@
<section id="noResultContainer" class="contentContainer">
<h1 id="noResultContainerHeadline" class="title is-1"></h1>
<p id="noResultContainerSubtitle" class="subtitle"></p>
<p><button id="btnNoResultContainerResetFilters" class="btnResetFilters button" tabindex="0"><i class="fas fa-ban"></i>&nbsp;<span></span></button></p>
<p><button id="btnNoResultContainerResetFilters" class="btnResetFilters" tabindex="0"><i class="fas fa-ban"></i>&nbsp;<span></span></button></p>
</section>
</div>
</div>
<form id="modalForm" class="modal modalFormSubmit">
<section id="modalForm" class="modal">
<div class="modal-background"></div>
<div class="modal-content">
<div class="card">
<header id="modalTitle" class="card-header-title"></header>
<div class="card-content">
<div class="content">
<div class="control has-icons-right">
<input id="modalFormInput" class="input is-medium" type="text" tabindex="0">
<div id="autoCompleteContainer" class="card"></div>
<a href="#" id="modalFormInputResize" class="icon is-right" tabindex="-1" data-input-type="input">
<i class="fas fa-expand-alt"></i>
</a>
<div class="inputWrapper">
<label id="modalFormInputLabel" for="modalFormInput"></label>
<input id="modalFormInput" class="input is-medium" type="text" tabindex="0" placeholder="(A) Todo text +project @context due:2020-12-12 rec:d">
<a href="#" id="modalFormInputResize" class="icon is-right" tabindex="-1" data-input-type="input"><i class="fas fa-expand-alt"></i></a>
</div>
<section id="autoCompleteContainer" class="card"></section>
<article class="message">
<div id="modalFormAlert" class="message-body"></div>
</article>
......@@ -342,21 +333,20 @@
</div>
</div>
<footer class="card-footer">
<a href="#" class="card-footer-item selection" value="" id="recurrencePickerNoRecurrence" tabindex="0"></a>
<a href="#" class="card-footer-item selection" id="recurrencePickerNoRecurrence" tabindex="0"></a>
</footer>
</div>
</div>
<br />
</div>
</div>
<footer class="card-footer">
<button id="btnSave" type="submit" class="card-footer-item" tabindex="0"></button>
<a href="#" id="btnItemStatus" class="card-footer-item" tabindex="0"></a>
<a href="#" class="card-footer-item btnModalCancel" tabindex="0"></a>
<button id="btnSave" class="card-footer-item" tabindex="0"></button>
<button id="btnItemStatus" class="card-footer-item" tabindex="0"></button>
<button class="card-footer-item" role="cancel" tabindex="0"></button>
</footer>
</div>
</div>
</form>
</section>
<div id="modalSettings" class="modal content" tabindex="0">
<div class="modal-background"></div>
......@@ -657,22 +647,24 @@
</div>
</div>
<div id="todoContext" class="dropdown-menu" role="menu" tabindex="0">
<div class="dropdown-content">
<a id="todoContextUseAsTemplate" class="dropdown-item" tabindex="0"></a>
<a id="todoContextEdit" href="#" class="dropdown-item" tabindex="0"></a>
<a id="todoContextDelete" class="dropdown-item" tabindex="0"></a>
<div id="todoContext" role="menu" tabindex="0">
<div class="card">
<div class="card-content">
<a id="todoContextUseAsTemplate" class="dropdown-item" tabindex="0"></a>
<a id="todoContextEdit" href="#" class="dropdown-item" tabindex="0"></a>
<a id="todoContextDelete" class="dropdown-item" tabindex="0"></a>
</div>
</div>
</div>
<div id="filterContext">
<div class="card">
<div class="card-content">
<input id="filterContextInput" class="input" type="text">
<input id="filterContextInput" class="input" type="text" tabindex="0">
</div>
<footer class="card-footer">
<a href="#" id="filterContextSave" class="card-footer-item"></a>
<a href="#" id="filterContextDelete" class="card-footer-item"></a>
<button id="filterContextSave" class="card-footer-item" tabindex="0"></button>
<button id="filterContextDelete" class="card-footer-item" tabindex="0"></button
</footer>
</div>
</div>
......@@ -681,16 +673,13 @@
<div class="modal-background"></div>
<div class="modal-content">
<div class="card">
<header>
<p id="modalChangeFileTitle" class="card-header-title"></p>
</header>
<div class="card-content">
<table id="modalChangeFileTable"></table>
</div>
<footer class="card-footer">
<a href="#" id="btnFilesOpenTodoFile" class="card-footer-item" tabindex="0"><i class="fas fa-folder-open"></i>&nbsp;<span id="modalChangeFileOpen"></span></a>
<a href="#" id="btnFilesCreateTodoFile" class="card-footer-item" tabindex="0"><i class="fas fa-plus-circle"></i>&nbsp;<span id="modalChangeFileCreate"></span></a>
<a href="#" class="card-footer-item btnModalCancel" tabindex="0"></a>
<button id="btnFilesOpenTodoFile" class="card-footer-item" tabindex="0"><i class="fas fa-folder-open"></i>&nbsp;<span id="modalChangeFileOpen"></span></button>
<button id="btnFilesCreateTodoFile" class="card-footer-item" tabindex="0"><i class="fas fa-plus-circle"></i>&nbsp;<span id="modalChangeFileCreate"></span></button>
<button class="card-footer-item" role="cancel" tabindex="0"></button>
</footer>
</div>
</div>
......@@ -702,8 +691,8 @@
<div class="card">
<div id="modalPromptContent" class="card-content"></div>
<footer class="card-footer">
<a href="#" id="modalPromptConfirm" class="card-footer-item" tabindex="0">Confirm</a>
<a href="#" id="modalPromptCancel" class="card-footer-item" tabindex="0">Cancel</a>
<button id="modalPromptConfirm" class="card-footer-item" tabindex="0"></a>
<button id="modalPromptCancel" role="cancel" class="card-footer-item" tabindex="0"></a>
</footer>
</div>
</div>
......@@ -714,25 +703,25 @@
<article class="message fixed" data="logging">
<div class="message-header">
<p><span id="messageLoggingTitle"></span></p>
<button class="delete close" aria-label="delete" data-message="logging"></button>
<button class="delete close" aria-label="delete" data-message="logging" tabindex="-1"></button>
</div>
<div class="message-body">
<p><span id="messageLoggingBody"></span></p>
<p><button id="btnMessageLogging" class="button" tabindex="0"><i class="fas fa-cog"></i>&nbsp;<span id="messageLoggingButton"></span></button></p>
<p><button id="btnMessageLogging" tabindex="-1"><i class="fas fa-cog"></i>&nbsp;<span id="messageLoggingButton"></span></button></p>
</div>
</article>
<article class="message fixed" data="share">
<div class="message-header">
<p><span id="messageShareTitle"></span></p>
<button class="delete close" aria-label="delete" data-message="share"></button>
<button class="delete close" aria-label="delete" data-message="share" tabindex="-1"></button>
</div>
<div class="message-body">
<p><span id="messageShareBody"></span></p>
<p class="brands">
<a href="https://twitter.com/intent/tweet?text=Check%20out%20sleek,%20a%20todo%20app%20based%20on%20todo.txt,%20free%20and%20open-source.%20Available%20for%20Linux,%20Windows%20and%20MacOS.%20https://github.com/ransome1/sleek" target="_blank"><i class="fab fa-twitter"></i></a>
<a href="https://www.facebook.com/sharer/sharer.php?u=https://github.com/ransome1/sleek" target="_blank"><i class="fab fa-facebook-square"></i></a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https://github.com/ransome1/sleek" target="_blank"><i class="fab fa-linkedin"></i></a>
<a tabindex="-1" href="https://twitter.com/intent/tweet?text=Check%20out%20sleek,%20a%20todo%20app%20based%20on%20todo.txt,%20free%20and%20open-source.%20Available%20for%20Linux,%20Windows%20and%20MacOS.%20https://github.com/ransome1/sleek" target="_blank"><i class="fab fa-twitter"></i></a>
<a tabindex="-1" href="https://www.facebook.com/sharer/sharer.php?u=https://github.com/ransome1/sleek" target="_blank"><i class="fab fa-facebook-square"></i></a>
<a tabindex="-1" href="https://www.linkedin.com/shareArticle?mini=true&url=https://github.com/ransome1/sleek" target="_blank"><i class="fab fa-linkedin"></i></a>
</p>
</div>
</article>
......
......@@ -215,7 +215,6 @@ function showContent(id) {
return Promise.reject(error);
}
}
function setFriendlyLanguageNames() {
try {
appData.languages.forEach((language) => {
......
......@@ -6,7 +6,7 @@ import { getHandleElement, startDragging } from "./drawer_handle.mjs";
const drawerContainer = document.getElementById("drawerContainer");
const navBtnFilter = document.getElementById("navBtnFilter");
const navBtnView = document.getElementById("navBtnView");
const drawers = document.querySelectorAll("nav ul li.drawerTrigger");
const drawers = document.querySelectorAll("nav ul li a.drawerTrigger");
if(userData.filterDrawer) {
show(document.getElementById("navBtnFilter"), document.getElementById("navBtnFilter").getAttribute("data-drawer")).then(function(result) {
......
"use strict";
import { resetModal, handleError, userData, setUserData, translations } from "../render.js";
import { resetFilters, resetModal, handleError, userData, setUserData, translations } from "../render.js";
import { _paq } from "./matomo.mjs";
import { createModalJail } from "../configs/modal.config.mjs";
......@@ -22,11 +22,15 @@ function showFiles() {
let cell3 = row.insertCell(2);
row.setAttribute("data-path", files[file][1]);
if(files[file][0]===1) {
cell1.innerHTML = "<button class=\"button\" disabled>" + translations.selected + "</button>";
cell1.innerHTML = "<button disabled>" + translations.selected + "</button>";
} else {
cell1.innerHTML = "<button class=\"button is-link\" tabindex=\"0\">" + translations.select + "</button>";
cell1.innerHTML = "<button tabindex=\"0\">" + translations.select + "</button>";
cell1.onclick = function() {
setUserData("selectedFilters", []);
resetFilters().then(function(response) {
console.info(response);
}).catch(function(error) {
handleError(error);
});
resetModal().then(response => {
window.api.send("startFileWatcher", this.parentElement.getAttribute("data-path"));
console.info(response);
......
This diff is collapsed.
{{
import { addIntervalToDate } from "./recurrences.mjs";
}}
filterQuery
= _ left:orExpr _ { return left; }
/ _ { return []; }
orExpr
= left:andExpr _ OrOp _ right:orExpr { return left.concat(right, ["||"]); }
/ left:andExpr { return left; }
andExpr
= left:notExpr _ AndOp _ right:andExpr { return left.concat(right, ["&&"]); }
/ left:notExpr { return left; }
notExpr
= NotOp _ left:notExpr { return left.concat(["!!"]); }
/ left:boolExpr { return left; }
boolExpr
= left:project { return left; }
/ left:context { return left; }
/ "(" _ left:orExpr _ ")" { return left; }
/ left:comparison { return left; }
/ "complete" { return ["complete"]; }
/ left:StringLiteral { return ["string", left]; }
/ left:RegexLiteral { return ["regex", left]; }
project
= "+" left:name { return ["++", left]; }
/ "+" { return ["++", "*"]; }
context
= "@" left:name { return ["@@", left]; }
/ "@" { return ["@@", "*"]; }
OrOp
= "||"
/ "or"i
AndOp
= "&&"
/ "and"i
NotOp
= "!"
/ "not"i
comparison
= left:priorityComparison { return left; }
/ left:dueComparison { return left; }
priorityComparison
= priorityKeyword _ op:compareOp _ right:priorityLiteral { return ["pri", right, op]; }
/ priorityKeyword { return ["pri"]; }
/ "(" right:priorityLiteral ")" { return ["pri", right, "=="]; }
priorityLiteral
= [A-Z] { return text(); }
priorityKeyword
= "pri" ("o" ("r" ("i" ("t" "y"?)?)?)?)?
dueComparison
= "due" _ op:compareOp _ right:dateExpr { return ["due"].concat(right, [op]); }
/ "due:" right:dateStr { return ["duestr", right]; }
/ "due" { return ["due"]; }
dateExpr
= left:dateLiteral _ op:dateOp _ count:number unit:[dbwmy] {
if (op == "-") {
count = count * -1;
}
// we do our date math with the same code as we use for
// recurrence calculations. All dates are returned from
// the parser as millisec since epoch (getTime()) to
// simplify comparisons in the filter lang execution engine.
let d = addIntervalToDate(new Date(left), count, unit);
return d.getTime();
}
/ left:dateLiteral { return left; }
dateOp
= "+" { return text(); }
/ "-" { return text(); }
compareOp
= "==" { return text(); }
/ "=" { return "=="; }
/ "!=" { return text(); }
/ ">=" { return text(); }
/ "<=" { return text(); }
/ ">" { return text(); }
/ "<" { return text(); }
dateStr
= [0-9]+ ("-" [0-9]+ ("-" [0-9]+)?)? { return text(); }
dateLiteral
= year:number4 "-" month: number2 "-" day:number2 {
let d = new Date(year, month-1, day);
return d.getTime();
}
/ year:number4 "-" month: number2 {
let d = new Date(year, month-1, 1);
return d.getTime();
}
/ year:number4 {
let d = new Date(year, 0, 1);
return d.getTime();
}
/ "today" {
let d = new Date(); // now, w current time of day
d = new Date(d.getFullYear(), d.getMonth(), d.getDate());
return d.getTime();
}
/ "tomorrow" {
let d = new Date(); // now, w current time of day
d = new Date(d.getFullYear(), d.getMonth(), d.getDate());
return d.getTime() + 24*60*60*1000;
}
/ "yesterday" {
let d = new Date(); // now, w current time of day
d = new Date(d.getFullYear(), d.getMonth(), d.getDate());
return d.getTime() - 24*60*60*1000;
}
number4
= [0-9][0-9][0-9][0-9] { return text(); }
number2
= [0-9][0-9] { return text(); }
number
= [0-9]+ { return text(); }
StringLiteral "string"
= '"' chars:DoubleStringCharacter* '"'? {
return chars.join("");
}
/ "'" chars:SingleStringCharacter* "'"? {
return chars.join("");
}
DoubleStringCharacter
= '\\' '"' { return '"'; }
/ !'"' SourceCharacter { return text(); }
SingleStringCharacter
= '\\' "'" { return "'"; }
/ !"'" SourceCharacter { return text(); }
RegexLiteral "regex"
= "/" chars:RegexCharacter* "/" "i" {
return new RegExp(chars.join(""), "i");
}
/ "/" chars:RegexCharacter* "/"? {
return new RegExp(chars.join(""));
}
RegexCharacter
= "\\" "/" { return "/"; }
/ !"/" SourceCharacter { return text(); }
SourceCharacter
= .
name
= '"' nonblank+ '"' { return text(); }
/ nonblankparen+ '"' { return '"' + text(); }
/ nonblankparen+ { return text(); }
nonblank
= [^ \t\n\r"]
nonblankparen
= [^ \t\n\r"()]
_ "whitespace"
= [ \t\n\r]*
// This is a simple stack machine that executes a filter language query
// compiled by filterlang.pegjs (which generates filterlang.mjs).
// The compiled query consists of a list of postfix opcodes designed
// specifically for todo.txt searching and filtering.
function runQuery(item, compiledQuery) {
if (!compiledQuery) {
return true; // a null query matches everything
}
let stack = [];
let operand1 = false;
let operand2 = false;
let next = 0;
let q = compiledQuery.slice(); // shallow copy
while (q.length > 0) {
const opcode = q.shift();
switch(opcode) {
case "pri":
stack.push(item.priority);
break;
case "due":
if (item.due) {
// normalize date to have time of midnight in local zone
// we represent dates as millisec from epoch to simplify comparison
let d = item.due;
stack.push(new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime());
} else {
stack.push(undefined); // all comparisons will return false
}
break;
case "duestr":
// match next value (a string) as prefix of ISO date string of due date
next = q.shift(); // the string to compare
if (item.due) {
// normalize date to have time of midnight in local zone
// we represent dates as millisec from epoch to simplify comparison
let d = item.due;
d = new Date(d.getFullYear(), d.getMonth(), d.getDate());
stack.push(d.toISOString().slice(0, 10).startsWith(next));
} else {
stack.push(false); // no due date
}
break;
case "complete":
stack.push(item.complete);
break;
case "string":
next = q.shift(); // the string value to match
stack.push(item.toString().toLowerCase().indexOf(next.toLowerCase()) !== -1);
break;
case "regex":
next = q.shift(); // the regex to match
stack.push(next.test(item.toString()));
break;
case "==":
operand2 = stack.pop();
operand1 = stack.pop();