From 21895b3200c6c002bb88184ae70872a3a9db8583 Mon Sep 17 00:00:00 2001 From: Olivier Berten Date: Sat, 23 Mar 2013 22:55:46 +0100 Subject: [PATCH] Edition interface. Code is a big mess but is seems to work. --- autoresize.jquery.js | 115 +++++++++++ chant.php | 2 +- chant_edit.php | 474 +++++++++++++++++++++++++++++++++++++------ history.php | 16 +- list-add.png | Bin 0 -> 323 bytes list-remove.png | Bin 0 -> 247 bytes missing.php | 20 ++ relCopy.min.js | 2 + style.css | 14 +- 9 files changed, 571 insertions(+), 72 deletions(-) create mode 100644 autoresize.jquery.js create mode 100644 list-add.png create mode 100644 list-remove.png create mode 100644 missing.php create mode 100644 relCopy.min.js diff --git a/autoresize.jquery.js b/autoresize.jquery.js new file mode 100644 index 0000000..1ff1052 --- /dev/null +++ b/autoresize.jquery.js @@ -0,0 +1,115 @@ +/*! + * jQuery Textarea Auto-Resize Plugin + * http://www.beansandcurry.com/ + * + * Copyright 2012, Beans & Curry + * Released under the MIT License + */ +(function ($) { + /* Auto-resize plugin */ + $.fn.autoresize = function (options) { + + var settings = $.extend({ + debug: false, + }, options), + styles = [ + 'font-family', + 'font-size', + 'font-weight', + 'font-style', + 'letter-spacing', + 'text-transform', + 'word-spacing', + 'text-indent', + 'line-height', + 'padding-top', + 'padding-bottom' + ]; + + /* Replaces line breaks with
tags for the text entered in the textarea */ + function textarea2div(text) { + var breakTag = '
'; + return (text + '
~').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2'); + } + + return this.each(function () { + var $this = $(this), + mirror = $("
"); + /* Disables scrollbars in the textarea */ + $this.css('overflow', 'hidden'); + /* Copy the styles from the textarea to the mirror */ + $.each(styles, function (index, property) { + mirror.css(property, $this.css(property)); + }); + + mirror.css({ + 'word-wrap': 'break-word', + 'position': 'absolute', + 'height': 'auto', + 'width': $this.width() + }) + + if (settings.debug === false) { + /* Position the mirror outside of the screen */ + mirror.css({ + 'top': '-999em', + 'left': '-999em' + }); + } else { + /* Position the mirror on the screen for debugging purposes */ + mirror.css({ + 'top': '10px', + 'left': '10px' + }); + } + /* Copy any text that is in the textarea to the mirror */ + mirror.html(textarea2div($this.val())); + /* Append the mirror to the body of your HTML */ + $("body").append(mirror); + + /* Make the textarea the same height as the mirror's height */ + $this.height(mirror.height()); + + /* Use the textchange event to update the mirror's text and update the textarea's height */ + /* Tip: You can add "transition: height .2s" to your textarea's CSS to get a nice animation when the height changes. */ + $this.bind("textchange", function () { + mirror.html(textarea2div($this.val())); + $this.height(mirror.height()); + }); + }); + }; + + /* Defining the 'textchange' event */ + /* Part of this code was taken from ZURB's jQuery TextChange Plugin http://www.zurb.com/playground/jquery-text-change-custom-event */ + $.event.special.textchange = { + + setup: function (data, namespaces) { + $(this).data('lastValue', this.contentEditable === 'true' ? $(this).html() : $(this).val()); + $(this).bind('keyup.textchange', $.event.special.textchange.handler); + $(this).bind('cut.textchange paste.textchange input.textchange', $.event.special.textchange.delayedHandler); + }, + + teardown: function (namespaces) { + $(this).unbind('.textchange'); + }, + + handler: function (event) { + $.event.special.textchange.triggerIfChanged($(this)); + }, + + delayedHandler: function (event) { + var element = $(this); + setTimeout(function () { + $.event.special.textchange.triggerIfChanged(element); + }, 25); + }, + + triggerIfChanged: function (element) { + var current = element[0].contentEditable === 'true' ? element.html() : element.val(); + if (current !== element.data('lastValue')) { + element.trigger('textchange', [element.data('lastValue')]); + element.data('lastValue', current); + } + } + }; +})(jQuery); \ No newline at end of file diff --git a/chant.php b/chant.php index 54fe959..fd45de0 100644 --- a/chant.php +++ b/chant.php @@ -135,7 +135,7 @@ if($req1->num_rows > 0 || $c['transcriber'] > '') { } while ($m = $req1->fetch_assoc()) { $user_info = get_userdata($m['user_id']); - echo "
  • ".date("M d, Y",$m['time']).": ".$m['comment']." (".$user_info->display_name.")
  • \n"; + echo "
  • ".date("M d, Y",$m['time']).": ".$m['comment']." (".$user_info->display_name.') ?
  • \n"; } if($c['transcriber'] > '') { echo "
  • Original transcriber: ".$c['transcriber']."
  • \n"; diff --git a/chant_edit.php b/chant_edit.php index a07a680..62f75f1 100644 --- a/chant_edit.php +++ b/chant_edit.php @@ -1,94 +1,448 @@ query($sql1) or die('Erreur SQL !
    '.$sql1.'
    '.$mysqli->error); -$c = $req1->fetch_assoc(); -if(!$c) { + +function mkstemp($suffix) { + # based on http://stackoverflow.com/questions/8970913/create-a-temp-file-with-a-specific-extension-using-php + $attempts = 238328; // 62 x 62 x 62 + $letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + $length = strlen($letters) - 1; + + for($count = 0; $count < $attempts; ++$count) { + $random = ""; + + for($p = 0; $p < 6; $p++) { + $random .= $letters[mt_rand(0, $length)]; + } + + $randomFile = sys_get_temp_dir().'/'.$random.$suffix; + + if( !($fd = @fopen($randomFile, "x+")) ) + continue; + + return array($fd,$randomFile); + } + return False; +} + +function gregorio($s,$i=1) { + $f = mkstemp('.gabc'); + fwrite($f[0],"initial-style:".$i.";\n%%\n".$s); + fclose($f[0]); + chdir(dirname($f[1])); + exec('gregorio '.basename($f[1])); + unlink($f[1]); + $gf = substr($f[1],0,-5).'.tex'; + $g = fopen($gf,'r'); + $tex = fread($g,filesize($gf)); + fclose($g); + unlink($gf); + $tex = substr($tex,0,-12)."\n\\relax\n"; + + if($i > 0) { + $tex = '\setspaceafterinitial{2.2mm plus 0em minus 0em} +\setspacebeforeinitial{2.2mm plus 0em minus 0em} +'.$tex; + } else { + $tex = '\setspaceafterinitial{0pt plus 0em minus 0em}% +\setspacebeforeinitial{0pt plus 0em minus 0em}% +'.$tex; + } + + return $tex; +} + +function mgabc2tex($c, $firstverse = False) { + $ann = array('al' => False, + 'an' => 'Ant', + 'ca' => 'Cant', + 'co' => 'Comm', + 'gr' => 'Grad', + 'hy' => 'Hymn', + 'in' => 'Intr', + 'im' => False, + 'ky' => False, + 'of' => 'Offert', + 'ps' => False, + 're' => 'Resp', + 'se' => 'Seq', + 'tr' => 'Tract', + 'va' => False); + # + # Document header + # + $tex = '% !TEX TS-program = lualatex +% !TEX encoding = UTF-8 + +\documentclass[12pt]{article} +\usepackage{geometry} +\geometry{paperwidth=16cm,paperheight=150cm} +\usepackage{gregoriotex} +\usepackage{fullpage} + +\usepackage[latin]{babel} + +\usepackage{fontspec} +\defaultfontfeatures{Ligatures=TeX} +\setmainfont{Linux Libertine O} + +\pagestyle{empty} +\begin{document} +\newcommand{\red}[1]{\textcolor{red}{#1}} +\newcommand{\black}[1]{\textcolor{black}{#1}} +\setlength{\parindent}{0pt} + +\def\greinitialformat#1{ +{\fontsize{38}{38}\selectfont #1} +} + +\def\grebiginitialformat#1{ +{\fontsize{144}{144}\selectfont #1} +} + +'; + if($c['commentary']) { + $tex .= '\commentary{{\small \emph{'.$c['commentary']."}}}\n"; + $tex .= '\nolinebreak[4]'."\n"; + } + if($ann[$c['office-part']]) { + $tex .= '\gresetfirstannotation{\small \textbf{'.$ann[$c['office-part']].".}}\n"; + } + if($c['mode']) { + if($c['mode'] == 'p') { + $mode = "T. pereg."; + } else { + $mode = $c['mode']; + } + $tex .= '\gresetsecondannotation{\small \textbf{'.$mode.".}}\n"; + } + # + # Parsing gabc + # + $g = json_decode($c['gabc']); + $i = $c['initial']; + if(is_array($g)) { + foreach($g as $l) { + if($l[0] == 'gabc') { + $tex .= gregorio($l[1],$i); + } else { + $tex .= "\\vspace{10pt}\n".$l[1]."\\par\n"; + } + $i = 0; + } + } elseif($c['gabc_verses'] && !$firstverse) { + $tex .= gregorio($g."\n".$c['gabc_verses'],$i); + } elseif($c['tex_verses'] && !$firstverse) { + $tex .= gregorio($g,$i); + $tex .= "\\vspace{10pt}\n".$c['tex_verses']."\\par\n"; + } else { + $tex .= gregorio($g,$i); + } + # + # Document footer + # + $tex .= ' +\end{document} +'; + return $tex; +} + +function makeimgfiles($id, $tex, $suffix = '') { + $path = __DIR__.'/scores/'; + $f = mkstemp('.tex'); + fwrite($f[0],$tex); + fclose($f[0]); + chdir(dirname($f[1])); + exec('lualatex --interaction=nonstopmode '.basename($f[1])); + exec('convert -density 300 '.substr($f[1],0,-4).'.pdf -flatten -trim '.$path.'png/'.$id.$suffix.'.png'); + chmod($path.'png/'.$id.$suffix.'.png', 0666); + exec('convert -resize 33.333333% '.$path.'png/'.$id.$suffix.'.png '.$path.$id.$suffix.'.png'); + chmod($path.$id.$suffix.'.png', 0666); + exec('pdfcrop '.substr($f[1],0,-4).'.pdf '.$path.'pdf/'.$id.$suffix.'.pdf'); + chmod($path.'pdf/'.$id.$suffix.'.pdf', 0666); + exec('gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=epswrite -dCompatibilityLevel=1.3 -dEmbedAllFonts=true -dSubsetFonts=true -sOutputFile='.$path.'eps/'.$id.$suffix.'.eps '.$path.'pdf/'.$id.$suffix.'.pdf'); + chmod($path.'eps/'.$id.$suffix.'.eps', 0666); + unlink($f[1]); + unlink(substr($f[1],0,-4).'.log'); + unlink(substr($f[1],0,-4).'.aux'); + unlink(substr($f[1],0,-4).'.gaux'); + unlink(substr($f[1],0,-4).'.pdf'); +} + +if(array_key_exists("id", $_GET)||array_key_exists("id", $mypost)) { + $id = array_key_exists("id", $_GET)?intval($_GET['id']):intval($mypost['id']); +} else { + $id = '0'; +} +$sql = 'SELECT * FROM '.db('chants').' WHERE id = '.$id; +$req = $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); +$c = $req->fetch_assoc(); +if(!$c && $id != '0') { die('Wrong id'); } +$c_s = array(); +$sql = 'SELECT * FROM '.db('chant_sources').' WHERE chant_id = '.$id; +$req = $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); +while ($s = $req->fetch_assoc()) { + $c_s[] = $s; +} $title = $c['incipit']; +$custom_header = <<
    + + + + +HEADER; include('include/header.php'); if(!$logged_in) { - echo "Please login"; -} elseif(count($_POST) > 0) { - #$mysqli->query('INSERT into '.db('proofreading').' VALUES ('.$id.','.$_SESSION['user_id'].','.time().')') or die('Erreur SQL !
    '.$sql1.'
    '.$mysqli->error); -} else { - - $c_p = array(); - $sql1 = 'SELECT * FROM '.db('chant_sources').' WHERE chant_id = '.$id; - $req1 = $mysqli->query($sql1) or die('Erreur SQL !
    '.$sql1.'
    '.$mysqli->error); - while ($s = $req1->fetch_assoc()) { - $c_s = array($s['source'], $s['page']); - if(is_dir('./sources/'.$s['source'])) { - if(is_array($sources[$s['source']]['pages'])) { - $p = array_search($s['page'],$sources[$s['source']]['pages']); - } else { - $p = $s['page']; - } - $c_p[] = array($s['source'], $s['page'], $p, $s['extent']); - } else { - $c_p[] = $c_s; + echo '

    Please login

    '; +} elseif($id == '0' && count($mypost) > 0) { + $gabc = array(); + for($i=0;$i '') { + $gabc[] = array($mypost['type'][$i],$mypost['content'][$i],array()); } } + if(count($gabc) == 0) { + $mypost['gabc'] = NULL; + } elseif(count($gabc) == 1 && $gabc[0][0] == 'gabc') { + $mypost['gabc'] = str_replace('",[]]','",{}]', str_replace("\r","",json_encode($gabc[0][1], JSON_UNESCAPED_SLASHES))); + } else { + $mypost['gabc'] = str_replace('",[]]','",{}]', str_replace("\r","",json_encode($gabc, JSON_UNESCAPED_SLASHES))); + } + unset($mypost['type']); + unset($mypost['content']); + $s_p = array(); + for($i=0;$i (string)$id, "source" => $mypost['source'][$i], "page" => $mypost['page'][$i], "sequence" => $mypost['sequence'][$i], "extent" => $mypost['extent'][$i]); + } + } + unset($mypost['source']); + unset($mypost['page']); + unset($mypost['sequence']); + unset($mypost['extent']); + $mypost['gabc_verses'] = str_replace("\r","",$mypost['gabc_verses']); + $mypost['tex_verses'] = str_replace("\r","",$mypost['tex_verses']); - echo '
    '; - echo '

    '; - echo '

    Mode


    '; - echo '

    Initial style\n"; + $sql = 'INSERT into '.db('chants').' (`incipit`) VALUES ("'.$mysqli->real_escape_string($mypost['incipit']).'")'; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + $id = $mysqli->insert_id; + foreach(array('version','office-part','mode','mode_var','commentary','initial','transcriber','gabc','gabc_verses','tex_verses') as $k) { + if($mypost[$k] > '') { + $sql = 'UPDATE '.db('chants').' SET `'.$k.'` = "'.$mysqli->real_escape_string($mypost[$k]).'" WHERE `id` = '.$id; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + } + } + foreach($s_p as $s) { + $sql = 'INSERT into '.db('chant_sources').' VALUES ('.$id.','.$s['source'].',"'.$mysqli->real_escape_string($s['page']).'",'.intval($s['sequence']).','.intval($s['extent']).')'; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + } + makeimg($mypost); + $t = time(); + $uid = $current_user->ID; + $chgset = $t.'-'.$id.'-'.$uid; + $sql = 'INSERT into '.db('changesets').' VALUES ('.$uid.','.$id.','.$t.', "Added to the database")'; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + header('Location: chant.php?id='.$id); +} elseif(count($mypost) > 3) { + $gabc = array(); + for($i=0;$i '') { + $gabc[] = array($mypost['type'][$i],$mypost['content'][$i],array()); + } + } + if(count($gabc) == 0) { + $mypost['gabc'] = NULL; + } elseif(count($gabc) == 1 && $gabc[0][0] == 'gabc') { + $mypost['gabc'] = json_encode($gabc[0][1], JSON_UNESCAPED_SLASHES); + } else { + $mypost['gabc'] = json_encode($gabc, JSON_UNESCAPED_SLASHES); + } + unset($mypost['type']); + unset($mypost['content']); + $s_p = array(); + for($i=0;$i (string)$id, "source" => $mypost['source'][$i], "page" => $mypost['page'][$i], "sequence" => $mypost['sequence'][$i], "extent" => $mypost['extent'][$i]); + } + } + unset($mypost['source']); + unset($mypost['page']); + unset($mypost['sequence']); + unset($mypost['extent']); - echo '

    GABC

    '; + $fields = array('id','incipit','version','office-part','mode','mode_var','commentary','initial','transcriber','gabc','gabc_verses','tex_verses'); + $old = array(); + $new = array(); + foreach($fields as $f) { + $myfield = str_replace('",[]]','",{}]', str_replace("\r","",$mypost[$f])); + if($c[$f] != $myfield) { + $old[$f] = $c[$f]; + $new[$f] = $myfield; + } + } + if($c_s != $s_p || count($old) > 0) { + $t = time(); + $uid = $current_user->ID; + $chgset = $t.'|'.$id.'|'.$uid; + $sql = 'INSERT into '.db('changesets').' VALUES ('.$uid.','.$id.','.$t.', NULL)'; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + $mod = False; + foreach($old as $k => $v) { + $sql = 'INSERT into '.db('changes').' VALUES ("'.$chgset.'","'.$k.'","'.$mysqli->real_escape_string($v).'")'; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + $sql = 'UPDATE '.db('chants').' SET `'.$k.'` = "'.$mysqli->real_escape_string($new[$k]).'" WHERE `id` = '.$id; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + if(in_array($k, array('office-part','mode','mode_var','commentary','initial','gabc','gabc_verses','tex_verses'))) { + $mod = True; + } + } + if($c_s != $s_p) { + $sql = 'DELETE FROM '.db('chant_sources').' WHERE `chant_id` = '.$id; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + foreach($s_p as $s) { + $sql = 'INSERT into '.db('chant_sources').' VALUES ('.$s['chant_id'].','.$s['source'].',"'.$mysqli->real_escape_string($s['page']).'",'.intval($s['sequence']).','.intval($s['extent']).')'; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + } + $sql = 'INSERT into '.db('changes').' VALUES ("'.$chgset.'","sources","'.$mysqli->real_escape_string(json_encode($c_s, JSON_UNESCAPED_SLASHES)).'")'; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + } + if($mod) { + makeimg($mypost); + } + echo ''; + echo "

    Please describe your changes

    \n".''."
    \n\n\n"; + } else { + echo "

    No changes made

    "; + } +} elseif(count($mypost) > 0) { + $chgset = explode('|',$mypost['changeset']); + $sql = 'UPDATE '.db('changesets').' SET `comment` = "'.$mysqli->real_escape_string($mypost['comment']).'" WHERE `user_id` = '.$chgset[2].' AND `chant_id` = '.$chgset[1].' AND `time` = '.$chgset[0]; + $mysqli->query($sql) or die('Erreur SQL !
    '.$sql.'
    '.$mysqli->error); + header('Location: chant.php?id='.$id); +} else { + $gabc = json_decode($c['gabc']); + if(is_string($gabc)) { + $gabc = array(array('gabc', $gabc, array()),); + } elseif(empty($gabc)) { + $gabc = array(array('gabc', "(c4)", array()),); + } + echo '
    '; + echo '
    '; + echo "

    Score

    "; + $i = 0; + foreach($gabc as $g) { + echo '

    '; + echo '\n"; + echo ''; + echo ($i>0?' Remove':''); + echo '

    '; + $i++; + } + echo 'Add more'; + echo "

    Hymn verses (GABC)

    \n"; + echo '\n"; + echo "

    Hymn verses (TeX)

    \n"; + echo '\n"; echo '
     
    '."\n"; echo '
    '; - echo '

    Incipit

    -

    Usage

    '."\n"; + echo '

    Version

    '."\n"; + echo '

    Usage

    \n"; + echo "

    Mode

    \n"; + echo ' - Ending '."\n"; + echo '

    Commentary

    '; + echo "

    Initial style

    \n"; + echo '\n"; + echo '

    Original transcriber

    '; - $sources_img = ""; - if(count($c_p) > 0) { - echo "

    Sources

    \n
      \n"; - $cnt = 1; - foreach($c_p as $s) { - $source_label = "".$sources[$s[0]]['title'].", ".$sources[$s[0]]['year'].", p. ".$s[1]; - if (count($s) > 2) { - echo '
    • '.$source_label."
    • \n"; - $sources_img .= '

      '.$source_label."
      \n"; - for($i = 0; $i < $s[3]; $i++) { - $sources_img .= '
      '."\n"; - } - $sources_img .= "

      \n
      \n"; - } else { - echo "
    • ".$source_label."
    • \n"; - } - $cnt += 1; + function sources_box($so) { + global $sources; + $sources_box = '\n"; + echo $sources_box; } - echo "
      \n"; - - echo $sources_img; + echo "

      Sources

      \n"; + echo 'PageSequenceExtent'; + $i = 0; + foreach ($c_s as $s) { + echo '

      '; + sources_box($s['source']); + echo "\n"; + echo ''; + echo ''; + echo ''; + echo ($i>0?' Remove':''); + echo '

      '; + $i++; + } + if(count($c_s) == 0) { + echo '

      '; + sources_box('0'); + echo "\n"; + echo ''; + echo ''; + echo '

      '; + } + echo 'Add more'; + + echo '

      '; echo "
    \n"; echo "
    \n"; } + include('include/footer.php'); ?> diff --git a/history.php b/history.php index 1f6eeda..f59d331 100644 --- a/history.php +++ b/history.php @@ -2,25 +2,25 @@ include('include/db.php'); include('include/finediff.php'); -if(array_key_exists("id", $_GET)) { - $id = intval($_GET['id']); +if(array_key_exists("changeset", $_GET)) { + $chgset = explode('|',$_GET['changeset']); } else { - die('No id'); + die('No changeset'); } -$sql1 = 'SELECT * FROM '.db('chants').' WHERE id = '.$id; +$sql1 = 'SELECT * FROM '.db('chants').' WHERE id = '.intval($chgset[1]); $req1 = $mysqli->query($sql1) or die('Erreur SQL !
    '.$sql1.'
    '.$mysqli->error); $c = $req1->fetch_assoc(); $title = 'History - '.$c['incipit']; include('include/header.php'); echo "

    $title

    \n"; - -$sql1 = 'SELECT * FROM '.db('changesets').' WHERE chant_id = '.$id.' ORDER BY time DESC'; +$sql1 = 'SELECT * FROM '.db('changesets').' WHERE `user_id` = '.intval($chgset[2]).' AND `chant_id` = '.intval($chgset[1]).' AND `time` = '.intval($chgset[0]); $req1 = $mysqli->query($sql1) or die('Erreur SQL !
    '.$sql1.'
    '.$mysqli->error); while($m = $req1->fetch_assoc()) { - echo "

    ".date("M d, Y",$m['time'])." (".username_from_id($m['user_id']).")

    \n"; + $user_info = get_userdata($m['user_id']); + echo "

    ".date("M d, Y",$m['time'])." (".$user_info->display_name.")

    \n"; echo "

    ".$m['comment']."

    \n"; - $sql2 = 'SELECT * FROM '.db('changes').' WHERE changeset = "'.$m['user_id'].'|'.$id.'|'.$m['time'].'" ORDER BY field'; + $sql2 = 'SELECT * FROM '.db('changes').' WHERE changeset = "'.$mysqli->real_escape_string($_GET['changeset']).'" ORDER BY field'; $req2 = $mysqli->query($sql2) or die('Erreur SQL !
    '.$sql2.'
    '.$mysqli->error); while($f = $req2->fetch_assoc()) { echo '

    '.$f['field']."
    \n"; diff --git a/list-add.png b/list-add.png new file mode 100644 index 0000000000000000000000000000000000000000..1aa7f095c6c282262390748ab2e596a3fc15c228 GIT binary patch literal 323 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE7hmi)!cT|6FkAON{jSt(_u!Lq7!B=^4B;IBq%dL`6}O%gpGjO3}J1 z4Y?KfzQ;%l3Rp(0FF*F|EI&io>j^)N99Xu9ZE@HjcqrgTrepSr)S!;v7$d z7#j|r*sm7k|1`qSzwL6X$#3JGkN$s>{Cx9Ec6v|es;&OpMC)hUh7@^ocW)~11Nx1@ M)78&qol`;+0M{XYA^-pY literal 0 HcmV?d00001 diff --git a/list-remove.png b/list-remove.png new file mode 100644 index 0000000000000000000000000000000000000000..00b654e8ca567c380fa477d4b32f808c3b5500d3 GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkEZLFV~EA+w-YyVHU|i_?Pt%tbHGab z1&5^a+FUmdNd@kXwZ%tROFFJ>Q*!zI&R_A==FP^f@-i~)|I20A*?&KNrgrv}l!w`~ zS-W;DV_2Rr!zN$cO_)z&Zy0B$7WFVdQ&MBb@09MjczW@LL literal 0 HcmV?d00001 diff --git a/missing.php b/missing.php new file mode 100644 index 0000000..1936400 --- /dev/null +++ b/missing.php @@ -0,0 +1,20 @@ +$title

    \n"; + +$sql1 = 'SELECT * FROM '.db('chants').' WHERE `gabc` IS NULL ORDER BY incipit ASC'; + +$req1 = $mysqli->query($sql1) or die('Erreur SQL !
    '.$sql1.'
    '.$mysqli->error); +echo "
      \n"; +while($c = $req1->fetch_assoc()) { + $incipit = $c['incipit']?format_incipit($c['incipit']):"==="; + echo '
    • '; + echo ''.$incipit.""; + echo ' ('.$c['version'].")
    • \n"; +} +echo "
    \n"; +include('include/footer.php'); +?> diff --git a/relCopy.min.js b/relCopy.min.js new file mode 100644 index 0000000..f8dc1df --- /dev/null +++ b/relCopy.min.js @@ -0,0 +1,2 @@ +(function(a){a.fn.relCopy=function(e){var b=jQuery.extend({excludeSelector:".exclude",emptySelector:".empty",copyClass:"copy",append:"",clearInputs:!0,limit:0},e);b.limit=parseInt(b.limit);this.each(function(){a(this).click(function(){var f=a(this).attr("rel"),d=a(f).length;if(0!=b.limit&&d>=b.limit)return!1;var c=a(f+":first"),e=a(c).parent(),c=a(c).clone(!0).addClass(b.copyClass+d).append(b.append);b.excludeSelector&&a(c).find(b.excludeSelector).remove();b.emptySelector&&a(c).find(b.emptySelector).empty(); +if(a(c).attr("id")){var g=a(c).attr("id")+(d+1);a(c).attr("id",g)}a(c).find("[id]").each(function(){var b=a(this).attr("id")+(d+1);a(this).attr("id",b)});b.clearInputs&&a(c).find(":input").each(function(){switch(a(this).attr("type")){case "button":break;case "reset":break;case "submit":break;case "checkbox":a(this).attr("checked","");break;default:a(this).val("")}});a(e).find(f+":last").after(c);return!1})});return this}})(jQuery); diff --git a/style.css b/style.css index e095e72..132e09e 100644 --- a/style.css +++ b/style.css @@ -238,9 +238,17 @@ del { text-decoration: none; } -textarea#gabc { - width: 440px; - height: 200px; +textarea.gabc { + width: 450px; +} + +.clone1,.clone2 { + border-bottom: 1px dashed gray; +} + +.edit { + float:right; + margin-right: 15px; } .alphabet {