1
0
mirror of https://git.tt-rss.org/git/tt-rss.git synced 2025-12-13 11:45:56 +00:00
Files
tt-rss/classes/pref/labels.php
Michael Kuhn 4a2a90c980 Fix focus issues with hotkeys
Since making use of keypress in addition to keydown, hotkeys did not
work in certain scenarios, including clicking on the feed tree expanders
or empty spaces of the toolbar.

This issue is caused by dijit.Tree and dijit.Toolbar implementing the
_KeyNavMixin, which explicitly stops propagation of keypress events.

This change contains two main fixes plus a smaller hotfix:
1. It overrides _onContainerKeydown and _onContainerKeypress for
   fox.FeedTree (which inherits from dijit.Tree).
2. It adds fox.Toolbar, which overrides _onContainerKeydown,
   _onContainerKeypress and focus. This fixes hotkeys being swallowed
   and the first focusable child receiving focus when clicking on an
   empty space of the toolbar.
3. It adds the same handling of keydown and keypress to the prefs hotkey
   handler as is done in the main hotkey handler.
2019-04-13 22:34:57 +02:00

314 lines
8.7 KiB
PHP

<?php
class Pref_Labels extends Handler_Protected {
function csrf_ignore($method) {
$csrf_ignored = array("index", "getlabeltree", "edit");
return array_search($method, $csrf_ignored) !== false;
}
function edit() {
$label_id = clean($_REQUEST['id']);
$sth = $this->pdo->prepare("SELECT * FROM ttrss_labels2 WHERE
id = ? AND owner_uid = ?");
$sth->execute([$label_id, $_SESSION['uid']]);
if ($line = $sth->fetch()) {
print_hidden("id", "$label_id");
print_hidden("op", "pref-labels");
print_hidden("method", "save");
print "<form onsubmit='return false;'>";
print "<header>".__("Caption")."</header>";
print "<section>";
$fg_color = $line['fg_color'];
$bg_color = $line['bg_color'] ? $line['bg_color'] : '#fff7d5';
print "<input style='font-size : 16px; color : $fg_color; background : $bg_color; transition : background 0.1s linear'
id='labelEdit_caption' name='caption' dojoType='dijit.form.ValidationTextBox'
required='true' value=\"".htmlspecialchars($line['caption'])."\">";
print "</section>";
print "<header>" . __("Colors") . "</header>";
print "<section>";
print "<table>";
print "<tr><th style='text-align : left'>".__("Foreground:")."</th><th style='text-align : left'>".__("Background:")."</th></tr>";
print "<tr><td style='padding-right : 10px'>";
print "<input dojoType='dijit.form.TextBox'
style='display : none' id='labelEdit_fgColor'
name='fg_color' value='$fg_color'>";
print "<input dojoType='dijit.form.TextBox'
style='display : none' id='labelEdit_bgColor'
name='bg_color' value='$bg_color'>";
print "<div dojoType='dijit.ColorPalette'>
<script type='dojo/method' event='onChange' args='fg_color'>
dijit.byId('labelEdit_fgColor').attr('value', fg_color);
dijit.byId('labelEdit_caption').domNode.setStyle({color: fg_color});
</script>
</div>";
print "</td><td>";
print "<div dojoType='dijit.ColorPalette'>
<script type='dojo/method' event='onChange' args='bg_color'>
dijit.byId('labelEdit_bgColor').attr('value', bg_color);
dijit.byId('labelEdit_caption').domNode.setStyle({backgroundColor: bg_color});
</script>
</div>";
print "</td></tr></table>";
print "</section>";
print "<footer>";
print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary' onclick=\"dijit.byId('labelEditDlg').execute()\">".
__('Save')."</button>";
print "<button dojoType='dijit.form.Button' onclick=\"dijit.byId('labelEditDlg').hide()\">".
__('Cancel')."</button>";
print "</footer>";
print "</form>";
}
}
function getlabeltree() {
$root = array();
$root['id'] = 'root';
$root['name'] = __('Labels');
$root['items'] = array();
$sth = $this->pdo->prepare("SELECT *
FROM ttrss_labels2
WHERE owner_uid = ?
ORDER BY caption");
$sth->execute([$_SESSION['uid']]);
while ($line = $sth->fetch()) {
$label = array();
$label['id'] = 'LABEL:' . $line['id'];
$label['bare_id'] = $line['id'];
$label['name'] = $line['caption'];
$label['fg_color'] = $line['fg_color'];
$label['bg_color'] = $line['bg_color'];
$label['type'] = 'label';
$label['checkbox'] = false;
array_push($root['items'], $label);
}
$fl = array();
$fl['identifier'] = 'id';
$fl['label'] = 'name';
$fl['items'] = array($root);
print json_encode($fl);
return;
}
function colorset() {
$kind = clean($_REQUEST["kind"]);
$ids = explode(',', clean($_REQUEST["ids"]));
$color = clean($_REQUEST["color"]);
$fg = clean($_REQUEST["fg"]);
$bg = clean($_REQUEST["bg"]);
foreach ($ids as $id) {
if ($kind == "fg" || $kind == "bg") {
$sth = $this->pdo->prepare("UPDATE ttrss_labels2 SET
${kind}_color = ? WHERE id = ?
AND owner_uid = ?");
$sth->execute([$color, $id, $_SESSION['uid']]);
} else {
$sth = $this->pdo->prepare("UPDATE ttrss_labels2 SET
fg_color = ?, bg_color = ? WHERE id = ?
AND owner_uid = ?");
$sth->execute([$fg, $bg, $id, $_SESSION['uid']]);
}
/* Remove cached data */
$sth = $this->pdo->prepare("UPDATE ttrss_user_entries SET label_cache = ''
WHERE owner_uid = ?");
$sth->execute([$_SESSION['uid']]);
}
}
function colorreset() {
$ids = explode(',', clean($_REQUEST["ids"]));
foreach ($ids as $id) {
$sth = $this->pdo->prepare("UPDATE ttrss_labels2 SET
fg_color = '', bg_color = '' WHERE id = ?
AND owner_uid = ?");
$sth->execute([$id, $_SESSION['uid']]);
/* Remove cached data */
$sth = $this->pdo->prepare("UPDATE ttrss_user_entries SET label_cache = ''
WHERE owner_uid = ?");
$sth->execute([$_SESSION['uid']]);
}
}
function save() {
$id = clean($_REQUEST["id"]);
$caption = trim(clean($_REQUEST["caption"]));
$this->pdo->beginTransaction();
$sth = $this->pdo->prepare("SELECT caption FROM ttrss_labels2
WHERE id = ? AND owner_uid = ?");
$sth->execute([$id, $_SESSION['uid']]);
if ($row = $sth->fetch()) {
$old_caption = $row["caption"];
$sth = $this->pdo->prepare("SELECT id FROM ttrss_labels2
WHERE caption = ? AND owner_uid = ?");
$sth->execute([$caption, $_SESSION['uid']]);
if (!$sth->fetch()) {
if ($caption) {
$sth = $this->pdo->prepare("UPDATE ttrss_labels2 SET
caption = ? WHERE id = ? AND
owner_uid = ?");
$sth->execute([$caption, $id, $_SESSION['uid']]);
/* Update filters that reference label being renamed */
$sth = $this->pdo->prepare("UPDATE ttrss_filters2_actions SET
action_param = ? WHERE action_param = ?
AND action_id = 7
AND filter_id IN (SELECT id FROM ttrss_filters2 WHERE owner_uid = ?)");
$sth->execute([$caption, $old_caption, $_SESSION['uid']]);
print clean($_REQUEST["value"]);
} else {
print $old_caption;
}
} else {
print $old_caption;
}
}
$this->pdo->commit();
}
function remove() {
$ids = explode(",", clean($_REQUEST["ids"]));
foreach ($ids as $id) {
Labels::remove($id, $_SESSION["uid"]);
}
}
function add() {
$caption = clean($_REQUEST["caption"]);
$output = clean($_REQUEST["output"]);
if ($caption) {
if (Labels::create($caption)) {
if (!$output) {
print T_sprintf("Created label <b>%s</b>", htmlspecialchars($caption));
}
}
if ($output == "select") {
header("Content-Type: text/xml");
print "<rpc-reply><payload>";
print_label_select("select_label",
$caption, "");
print "</payload></rpc-reply>";
}
}
return;
}
function index() {
print "<div dojoType='dijit.layout.BorderContainer' gutters='false'>";
print "<div style='padding : 0px' dojoType='dijit.layout.ContentPane' region='top'>";
print "<div dojoType='fox.Toolbar'>";
print "<div dojoType='dijit.form.DropDownButton'>".
"<span>" . __('Select')."</span>";
print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
print "<div onclick=\"dijit.byId('labelTree').model.setAllChecked(true)\"
dojoType=\"dijit.MenuItem\">".__('All')."</div>";
print "<div onclick=\"dijit.byId('labelTree').model.setAllChecked(false)\"
dojoType=\"dijit.MenuItem\">".__('None')."</div>";
print "</div></div>";
print"<button dojoType=\"dijit.form.Button\" onclick=\"CommonDialogs.addLabel()\">".
__('Create label')."</button dojoType=\"dijit.form.Button\"> ";
print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('labelTree').removeSelected()\">".
__('Remove')."</button dojoType=\"dijit.form.Button\"> ";
print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('labelTree').resetColors()\">".
__('Clear colors')."</button dojoType=\"dijit.form.Button\">";
print "</div>"; #toolbar
print "</div>"; #pane
print "<div style='padding : 0px' dojoType=\"dijit.layout.ContentPane\" region=\"center\">";
print "<div id=\"labellistLoading\">
<img src='images/indicator_tiny.gif'>".
__("Loading, please wait...")."</div>";
print "<div dojoType=\"dojo.data.ItemFileWriteStore\" jsId=\"labelStore\"
url=\"backend.php?op=pref-labels&method=getlabeltree\">
</div>
<div dojoType=\"lib.CheckBoxStoreModel\" jsId=\"labelModel\" store=\"labelStore\"
query=\"{id:'root'}\" rootId=\"root\"
childrenAttrs=\"items\" checkboxStrict=\"false\" checkboxAll=\"false\">
</div>
<div dojoType=\"fox.PrefLabelTree\" id=\"labelTree\"
model=\"labelModel\" openOnClick=\"true\">
<script type=\"dojo/method\" event=\"onLoad\" args=\"item\">
Element.hide(\"labellistLoading\");
</script>
<script type=\"dojo/method\" event=\"onClick\" args=\"item\">
var id = String(item.id);
var bare_id = id.substr(id.indexOf(':')+1);
if (id.match('LABEL:')) {
dijit.byId('labelTree').editLabel(bare_id);
}
</script>
</div>";
print "</div>"; #pane
PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB,
"hook_prefs_tab", "prefLabels");
print "</div>"; #container
}
}