summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Zimniewicz <michzimny@users.noreply.github.com>2018-02-04 18:10:43 +0100
committerGitHub <noreply@github.com>2018-02-04 18:10:43 +0100
commit46652656fc42df252cd8cadc82ced2f6e002bdc3 (patch)
tree8a536c03fe3a01dc2514129c3ad3a24e853ce900
parent64b94f2831022d09f7a5025139c857e0d0517ce7 (diff)
parent4e91dd3b096afbd8e05fa052001589308e29405b (diff)
Merge pull request #5 from emkael/single-table-visualization
Wyróżnianie rozkładów pojedynczego stołu
-rw-r--r--README.md2
-rw-r--r--css/tdd.css11
-rw-r--r--sklady/tdd.js74
-rw-r--r--tdd-bootstrap.php71
-rw-r--r--tdd-protocol.php11
5 files changed, 135 insertions, 34 deletions
diff --git a/README.md b/README.md
index af71cbc..ce5be59 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Może to być zachowanie niewystarczające, gdy rozkład jest przeznaczony nie t
## Instalacja
-W katalogu z plikami html na serwerze należy umieścić .htaccess oraz pliki PHP.
+W katalogu z plikami html na serwerze należy umieścić .htaccess oraz pliki PHP, a także w odpowiednich katalogach dodatkowe pliki CSS/JS.
Reguła w .htaccess zapewnia, że zapytania do plików HTML z protokołami są przekierowywane do tdd-protocol.php, który podejmuje niezbędne działania.
## Dodanie rozkładów
diff --git a/css/tdd.css b/css/tdd.css
new file mode 100644
index 0000000..3ebce4f
--- /dev/null
+++ b/css/tdd.css
@@ -0,0 +1,11 @@
+body > table > tbody > tr.tdd-header > td {
+ border-bottom: 1px solid #006;
+ padding-top: 30px;
+}
+body > table > tbody > tr {
+ opacity: 0.2
+}
+body > table > tbody > tr.hovered,
+body > table > tbody > tr.specified {
+ opacity: 1.0;
+}
diff --git a/sklady/tdd.js b/sklady/tdd.js
new file mode 100644
index 0000000..bc75356
--- /dev/null
+++ b/sklady/tdd.js
@@ -0,0 +1,74 @@
+var TDD = {
+
+ rowSelector: 'body > table > tbody > tr',
+ rowHeaderClass: 'tdd-header',
+
+ findTable: function(element) {
+ var row = element.closest(TDD.rowSelector);
+ var headerRow = row;
+ while (headerRow.length && !headerRow.hasClass(TDD.rowHeaderClass)) {
+ headerRow = headerRow.prev(TDD.rowSelector);
+ }
+ var rows = [];
+ if (headerRow) {
+ rows.push(headerRow[0]);
+ headerRow = headerRow.next(TDD.rowSelector);
+ while (headerRow.length && !headerRow.hasClass(TDD.rowHeaderClass)) {
+ rows.push(headerRow[0]);
+ headerRow = headerRow.next(TDD.rowSelector);
+ }
+ }
+ return $(rows);
+ },
+
+ highlightTable: function(elem) {
+ TDD.findTable(elem).addClass('specified');
+ },
+
+ hoverTable: function(ev) {
+ TDD.findTable($(ev.currentTarget)).addClass('hovered');
+ },
+
+ unhoverTable: function(ev) {
+ TDD.findTable($(ev.currentTarget)).removeClass('hovered');
+ },
+
+ switchTable: function(ev) {
+ var header = TDD.findTable($(ev.currentTarget)).find('h4[id]');
+ location.hash = header.attr('id');
+ ev.stopPropagation();
+ },
+
+ detectReferer: function() {
+ var regex = document.referrer.match(/\d+t(\d+)-\d+\.htm/);
+ if (regex) {
+ return regex[1];
+ }
+ return undefined;
+ },
+
+ bindEvents: function() {
+ $('tr').hover(TDD.hoverTable, TDD.unhoverTable);
+ $('tr').click(TDD.switchTable);
+ $(window).on('hashchange', function() {
+ var table = $(location.hash);
+ if (table.length) {
+ $('.specified').removeClass('specified');
+ TDD.highlightTable(table);
+ } else {
+ var tableNo = TDD.detectReferer();
+ if (tableNo) {
+ location.hash = '#table-' + tableNo;
+ } else {
+ $('h4[id]').each(function() { TDD.highlightTable($(this)); });
+ }
+ }
+ });
+ }
+
+};
+
+$(document).ready(function() {
+ TDD.bindEvents();
+ $(window).trigger('hashchange');
+});
diff --git a/tdd-bootstrap.php b/tdd-bootstrap.php
index f85a786..48b088f 100644
--- a/tdd-bootstrap.php
+++ b/tdd-bootstrap.php
@@ -13,18 +13,17 @@ class Protocol {
throw new Exception('file not found: ' . $this->get_filename());
}
}
-
+
function get_filename() {
return $this->prefix . $this->round . 'b-' . $this->board . '.html';
}
-
+
function set_deal($table, $deal) {
$this->deals_by_tables[$table] = $deal;
}
function output() {
$content = file_get_contents($this->get_filename());
- $modified = 0;
$dom = str_get_html($content);
$header_td1 = $dom->find("/html/body/table/tr/td[class=\"bdcc12\"]", 0);
@@ -41,32 +40,44 @@ class Protocol {
$contract2 = trim(str_replace('&nbsp;', '', $tr->next_sibling()->find('td[class="bdc"]', 0)->innertext));
$score2 = trim(str_replace('&nbsp;', '', end($tr->next_sibling()->find('td'))->innertext));
+ $deal = $this->deals_by_tables[$table];
+ $insert = "<a href=\"#table-$table\"><h4 id=\"table-$table\">Stół $table &ndash; Rozdanie {$deal->deal_num}</h4></a>";
// if is played on both tables of a match
// note that the contract field for arbitral scores starts with 'A' (e.g. 'ARB' or 'AAA')
- if(($score1 !== '' || strpos($contract1, 'A') === 0)
+ if(($score1 !== '' || strpos($contract1, 'A') === 0)
&& ($score2 !== '' || strpos($contract2, 'A') === 0)) {
- $deal = $this->deals_by_tables[$table];
- $insert = "<h4>Stół $table &ndash; Rozdanie {$deal->deal_num}</h4>" . $deal->html();
- $modified = 1;
+ $insert .= $deal->html();
} else {
- $insert = '<p>...</p>';
+ $insert .= '<p>...</p>';
}
- $tr->outertext = '<tr><td colspan="7" style="border-bottom:1px solid #006;padding-top:30px;">' . $insert . '</td></tr>' . $tr->outertext;
+ $tr->outertext = '<tr class="tdd-header"><td colspan="7">' . $insert . '</td></tr>' . $tr->outertext;
}
$tr = @$tr->next_sibling();
}
-
- if($modified) {
- $header_tr2 = $header_tr->next_sibling();
- $header_tr->outertext = '';
- $header_tr2->outertext = '';
- $dom->find('/html/body/table/tr', 0)->outertext = '';
+
+ $header_tr2 = $header_tr->next_sibling();
+ $header_tr->outertext = '';
+ $header_tr2->outertext = '';
+ $dom->find('/html/body/table/tr', 0)->outertext = '';
+
+ $head = $dom->find('/html/head', 0);
+ $head->innertext .= '<link rel="stylesheet" type="text/css" href="css/tdd.css" />'
+ . '<script src="https://code.jquery.com/jquery-3.3.1.min.js" type="text/javascript"></script>'
+ . '<script src="sklady/tdd.js" type="text/javascript"></script>';
+
+ // replacing meta http-equiv refresh with a javascript refresh to preserve hash in the result page
+ $meta = $head->find('meta');
+ foreach ($meta as $metaTag) {
+ if ($metaTag->hasAttribute('http-equiv') && strtolower($metaTag->getAttribute('http-equiv')) == 'refresh') {
+ $head->innertext = str_replace($metaTag->outertext, '', $head->innertext) . '<script type="text/javascript">setTimeout(function() { location.reload(); }, ' . ($metaTag->getAttribute('content') * 1000) . ');</script>';
+ break;
+ }
}
-
+
print $dom->outertext;
}
-
+
}
class NoSuchDealNumber extends Exception {
@@ -78,23 +89,23 @@ class Deal {
$this->deal_num = $num_in_pbn;
$this->_parse($filename, $num_in_pbn);
}
-
+
function _parse($filename, $num_in_pbn) {
$pbn = file_get_contents($filename);
$start = strpos($pbn, '[Board "' . $num_in_pbn . '"]');
if($start === false) {
throw new NoSuchDealNumber($num_in_pbn);
}
-
+
$pbn = substr($pbn, $start + 5);
$stop = strpos($pbn,'[Board "');
if($stop != false) {
$pbn = substr($pbn, 0, $stop);
}
-
+
preg_match('|Dealer "([NESW])"|', $pbn, $m);
$this->dealer = $m[1];
-
+
preg_match('|Vulnerable "([^"]+)"|', $pbn, $m);
$this->vuln = $m[1];
if($this->vuln == 'None') {
@@ -102,25 +113,25 @@ class Deal {
} else if($this->vuln == 'All') {
$this->vuln = 'Obie';
}
-
+
preg_match('|Ability "([^"]+)"|', $pbn, $m);
if($m[1]) {
$this->ability = explode(' ',$m[1]);
}
-
+
preg_match('|Minimax "([^"]+)"|', $pbn, $m);
$this->minimax = $m[1];
-
+
preg_match('|Deal "(N:)?([^"]+)"|', $pbn, $m);
$this->hands = explode(' ',$m[2]);
}
-
+
function html() {
ob_start();
include('tdd-handrecord-tpl.php');
return ob_get_clean();
}
-
+
function format_hand($hand_num) {
$hand = $this->hands[$hand_num];
$hand = str_replace('T','10',$hand);
@@ -150,7 +161,7 @@ class Deal {
<td class='an1'>{$ab[4]}</td>
<td class='an1'>{$ab[5]}</td>";
}
-
+
function format_minimax() {
$minimax = $this->minimax;
$minimax = preg_replace('|^(..)D(.+)|','$1x$2', $minimax);
@@ -164,17 +175,17 @@ class Deal {
function load_deals_for_tables($prefix, $round, $board_in_teamy) {
$deals_by_tables = array();
-
+
$prefix = preg_quote($prefix);
$filename_regex = "/$prefix-r$round-t(\d+)-b(\d+).pbn/";
foreach(scandir('.') as $filename) {
if(preg_match($filename_regex, $filename, $match)) {
$file_table = $match[1];
$file_start_board = $match[2];
-
+
// 1 in teamy -> 1 in pbn; 24 in teamy -> 1 in pbn; 25 in teamy -> 1 in pbn
$num_in_pbn = $board_in_teamy - $file_start_board + 1;
-
+
try {
$deal = new Deal($filename, $num_in_pbn);
$deals_by_tables[$file_table] = $deal;
diff --git a/tdd-protocol.php b/tdd-protocol.php
index 7f6eb7b..3dcc0d8 100644
--- a/tdd-protocol.php
+++ b/tdd-protocol.php
@@ -18,7 +18,12 @@ if($request_uri_ending != '/' . $html_filename) {
//
$deals_by_tables = load_deals_for_tables($prefix, $round, $board);
-foreach($deals_by_tables as $table => $deal) {
- $protocol->set_deal($table, $deal);
+if (count($deals_by_tables) > 0) {
+ foreach($deals_by_tables as $table => $deal) {
+ $protocol->set_deal($table, $deal);
+ }
+ echo $protocol->output();
+}
+else {
+ readfile($html_filename);
}
-echo $protocol->output();