Dotclear

Changeset 721:e48539cccdbd


Ignore:
Timestamp:
09/15/11 14:17:12 (14 years ago)
Author:
Tomtom33 <tbouron@…>
Branch:
revisions
Message:

Improved diff UI

Files:
11 edited

Legend:

Unmodified
Added
Removed
  • .hgsubstate

    r270 r721  
    1 116601670d66e706e0759dfb3889efd4eb576f34 inc/libs/clearbricks 
     17678a853f5010e67dabd34a793f990bf688f287d inc/libs/clearbricks 
  • plugins/dcRevisions/_admin.php

    r338 r721  
    33# This file is part of dcRevisions, a plugin for Dotclear. 
    44#  
    5 # Copyright (c) 2010 Tomtom and contributors 
     5# Copyright (c) 2011 Tomtom and contributors 
    66# http://blog.zenstyle.fr/ 
    77#  
  • plugins/dcRevisions/_define.php

    r338 r721  
    33# This file is part of dcRevisions, a plugin for Dotclear. 
    44# 
    5 # Copyright (c) 2010 Tomtom and contributors 
     5# Copyright (c) 2011 Tomtom and contributors 
    66# http://blog.zenstyle.fr/ 
    77# 
  • plugins/dcRevisions/_install.php

    r338 r721  
    33# This file is part of dcRevisions, a plugin for Dotclear. 
    44# 
    5 # Copyright (c) 2010 Tomtom and contributors 
     5# Copyright (c) 2011 Tomtom and contributors 
    66# http://blog.zenstyle.fr/ 
    77# 
  • plugins/dcRevisions/_prepend.php

    r338 r721  
    33# This file is part of dcRrevisions, a plugin for Dotclear. 
    44# 
    5 # Copyright (c) 2010 Tomtom and contributors 
     5# Copyright (c) 2011 Tomtom and contributors 
    66# http://blog.zenstyle.fr/ 
    77# 
  • plugins/dcRevisions/_services.php

    r338 r721  
    33# This file is part of dcRevisions, a plugin for Dotclear. 
    44# 
    5 # Copyright (c) 2010 Tomtom and contributors 
     5# Copyright (c) 2011 Tomtom and contributors 
    66# http://blog.zenstyle.fr/ 
    77# 
     
    3737          unset($n['post_content']); 
    3838           
    39           $rsp = new xmlTag('revision'); 
     39          $rsp = new xmlTag(); 
    4040           
    4141          foreach ($o as $k => $v) { 
    42                $c = dcRevisionsRestMethods::getNode($v,$n[$k],$k); 
    43                $rsp->insertNode($c); 
     42               $rsp->insertNode(self::buildNode($v,$n[$k],2,$k)); 
    4443          } 
    4544           
     
    4746     } 
    4847      
    49      protected static function getNode($old,$new,$node_name) 
     48     public static function buildNode($src,$dst,$ctx,$root) 
    5049     { 
    51           if (!is_array($old)) { 
    52                $old = preg_replace ('/ +/',' ',$old); 
    53                $lo = explode("\n",trim($old)); 
    54           } else { 
    55                $lo = $old; 
    56           } 
    57  
    58           if (!is_array($new)) { 
    59                $new = preg_replace('/ +/',' ',$new); 
    60                $ln = explode("\n", trim($new)); 
    61           } else { 
    62                $ln = $new; 
    63           } 
     50          $udiff = diff::uniDiff($src,$dst,$ctx); 
     51          $tdiff = new tidyDiff(htmlspecialchars($udiff),true); 
    6452           
    65           $n = new xmlTag($node_name); 
     53          $rev = new xmlTag($root); 
    6654           
    67           $size = max(count($lo),count($ln)); 
    68           $pad_length = strlen($size); 
    69  
    70           $equ = array_intersect_assoc($lo,$ln); 
    71           $ins = array_diff_assoc($ln,$lo); 
    72           $del = array_diff_assoc($lo,$ln); 
    73  
    74           for ($i = 0; $i < $size; $i++) 
    75           { 
    76                $line_number = str_pad($i + 1,$pad_length,'0',STR_PAD_LEFT); 
    77  
    78                if (isset($del[$i])) { 
    79                     $ld = new xmlTag('line'); 
    80                     $ld->insertAttr('old',(string) $line_number); 
    81                     $ld->insertAttr('new',''); 
    82                     $ld->insertAttr('content',dcRevisionsRestMethods::getLine($del,$ins,$i,'delete')); 
    83                     $n->insertNode($ld); 
     55          foreach ($tdiff->getChunks() as $k => $chunk) { 
     56               foreach ($chunk->getLines() as $line) { 
     57                    switch ($line->type) { 
     58                         case 'context': 
     59                              $node = new xmlTag('context'); 
     60                              $node->oline = $line->lines[0]; 
     61                              $node->nline = $line->lines[1]; 
     62                              $node->insertNode($line->content); 
     63                              $rev->insertNode($node); 
     64                              break; 
     65                         case 'delete': 
     66                              $node = new xmlTag('delete'); 
     67                              $node->oline = $line->lines[0]; 
     68                              $c = str_replace(array('\0','\1'),array('<del>','</del>'),$line->content); 
     69                              $node->insertNode($c); 
     70                              $rev->insertNode($node); 
     71                              break; 
     72                         case 'insert': 
     73                              $node = new xmlTag('insert'); 
     74                              $node->nline = $line->lines[1]; 
     75                              $c = str_replace(array('\0','\1'),array('<ins>','</ins>'),$line->content); 
     76                              $node->insertNode($c); 
     77                              $rev->insertNode($node); 
     78                              break; 
     79                    } 
    8480               } 
    85                if (isset($equ[$i])) { 
    86                     $li = new xmlTag('line'); 
    87                     $li->insertAttr('old',(string) $line_number); 
    88                     $li->insertAttr('new',(string) $line_number); 
    89                     $li->insertAttr('content',$equ[$i]); 
    90                     $n->insertNode($li); 
    91                } 
    92                if (isset($ins[$i])) { 
    93                     $l = new xmlTag('line'); 
    94                     $l->insertAttr('old',''); 
    95                     $l->insertAttr('new',(string) $line_number); 
    96                     $l->insertAttr('content',dcRevisionsRestMethods::getLine($del,$ins,$i,'insert')); 
    97                     $n->insertNode($l); 
     81               if ($k < count($tdiff->getChunks()) - 1) { 
     82                    $node = new xmlTag('skip'); 
     83                    $rev->insertNode($node); 
    9884               } 
    9985          } 
    100  
    101           return $n; 
    102      } 
    103       
    104      protected static function getLine($del,$ins,$key,$mode) 
    105      { 
    106            
    107           $p_del = '<del>%s</del>'; 
    108           $p_ins = '<ins>%s</ins>'; 
    109            
    110           $str_del = isset($del[$key]) ? preg_replace('#<p>(.*)<\/p>#','$1',$del[$key]) : ''; 
    111           $ins_del = isset($ins[$key]) ? preg_replace('#<p>(.*)<\/p>#','$1',$ins[$key]) : ''; 
    112  
    113           switch ($mode) { 
    114                case 'delete': 
    115                     $p = $p_del; 
    116                     $src = preg_replace('#(.)*#',"\$1\n",$str_del); 
    117                     $dist = preg_replace('#(.)*#',"\$1\n",$ins_del); 
    118                     break; 
    119                case 'insert': 
    120                     $p = $p_ins; 
    121                     $src = preg_replace('#(.)*#',"\$1\n",$ins_del); 
    122                     $dist = preg_replace('#(.)*#',"\$1\n",$str_del); 
    123                     break; 
    124           } 
    125            
    126           if (array_key_exists($key,$del) && !array_key_exists($key,$ins)) { 
    127                return sprintf($p_del,preg_replace('#<p>(.*)<\/p>#','$1',$del[$key])); 
    128           } 
    129           if (array_key_exists($key,$ins) && !array_key_exists($key,$del)) { 
    130                return sprintf($p_ins,preg_replace('#<p>(.*)<\/p>#','$1',$ins[$key])); 
    131           } 
    132            
    133           $del = preg_split('//',preg_replace('#<p>(.*)<\/p>#','$1',$del[$key]),-1); 
    134           $ins = preg_split('//',preg_replace('#<p>(.*)<\/p>#','$1',$ins[$key]),-1); 
    135            
    136           switch ($mode) { 
    137                case 'delete': 
    138                     $p = $p_del; 
    139                     $arr = array_diff_assoc($del,$ins); 
    140                     $res = implode('',$del); 
    141                     break; 
    142                case 'insert': 
    143                     $p = $p_ins; 
    144                     $arr = array_diff_assoc($ins,$del); 
    145                     $res = implode('',$ins); 
    146                     break; 
    147           } 
    148            
    149           $word = ''; 
    150           $diff = array(); 
    151            
    152           foreach ($arr as $k => $c) { 
    153                if (array_key_exists($k+1,$arr)) { 
    154                     $word .= $c; 
    155                } 
    156                else { 
    157                     array_push($diff,$word); 
    158                     $word = ''; 
    159                } 
    160           } 
    161            
    162           return preg_replace('#('.implode('|',$diff).')#',sprintf($p,'$1'),$res); 
     86          return $rev; 
    16387     } 
    16488} 
  • plugins/dcRevisions/inc/class.dc.revisions.behaviors.php

    r338 r721  
    4747          dcPage::jsVar('dotclear.msg.content',__('Content')). 
    4848          dcPage::jsVar('dotclear.msg.current',__('Current')). 
    49           dcPage::jsVar('dotclear.msg.confirm_apply_patch',__('Are you sure to want apply this patch on this entry?')). 
     49          dcPage::jsVar('dotclear.msg.content_identical',__('Content identical')). 
     50          dcPage::jsVar('dotclear.msg.confirm_apply_patch', 
     51               __('(CAUTION: This operation will replace all the content by the previous one)').' '. 
     52               __('Are you sure to want apply this patch on this entry?') 
     53          ). 
    5054          "\n//]]>\n". 
    5155          "</script>\n". 
  • plugins/dcRevisions/inc/class.dc.revisions.list.php

    r338 r721  
    5959                    '<tr class="line wide'.(!$this->rs->canPatch() ? ' offline' : '').'" id="r'.$this->rs->revision_id.'">'."\n". 
    6060                    '<td class="maximal nowrap rid">'. 
    61                          '<strong>'.sprintf(__('Revision %s'),$this->rs->count()-$this->rs->index()).'</strong>'. 
     61                         '<strong>'.sprintf(__('Revision #%s'),$this->rs->revision_id).'</strong>'. 
    6262                    "</td>\n". 
    6363                    '<td class="minimal nowrap">'. 
  • plugins/dcRevisions/inc/class.dc.revisions.php

    r338 r721  
    152152          try { 
    153153               foreach ($diff as $k => $v) { 
    154                     $diff[$k] = uDiff::diff($n[$k],$o[$k]); 
     154                    $diff[$k] = diff::uniDiff($n[$k],$o[$k]); 
    155155               } 
    156156           
     
    218218          $p = $this->core->blog->getPosts($params); 
    219219          $r = $this->getRevisions($params); 
    220            
     220           
    221221          $patch = array( 
    222222               'post_excerpt' => $p->post_excerpt, 
     
    233233                    if ($k === 'post_content_xhtml') { $f = 'revision_content_xhtml_diff'; } 
    234234                     
    235                     uDiff::check($r->{$f}); 
    236                     $patch[$k] = uDiff::patch($v,$r->{$f}); 
     235                    $patch[$k] = diff::uniPatch($v,$r->{$f}); 
    237236               } 
    238237 
  • plugins/dcRevisions/js/_revision.js

    r338 r721  
    1818          img.className = 'expand'; 
    1919          $(img).css('cursor','pointer'); 
    20           img.line=this; 
     20          img.line = this; 
    2121          img.onclick = function() { 
    2222               dotclear.viewRevisionContent(this,this.line); 
     
    2929     var revisionId = line.id.substr(1); 
    3030     var postId = $("#id").val(); 
    31      var tr = document.getElementById('re'+revisionId); 
    32      if(!tr){ 
     31     var tr = document.getElementById('re' + revisionId); 
     32     if (!tr ){ 
    3333          tr = document.createElement('tr'); 
    34           tr.id = 're'+revisionId; 
     34          tr.id = 're' + revisionId; 
    3535          var td = document.createElement('td'); 
    3636          td.colSpan = 5; 
     
    4848                    var rsp = $(data).children('rsp')[0]; 
    4949                    if(rsp.attributes[0].value == 'ok'){ 
    50                          var excerpt = $(rsp).find('post_excerpt_xhtml'); 
    51                          var content = $(rsp).find('post_content_xhtml'); 
    52                          var table = '<table class="preview-rev">'; 
    53                          table += dotclear.viewRevisionRender($(rsp).find('post_excerpt_xhtml'),dotclear.msg.excerpt,revisionId); 
    54                          table += dotclear.viewRevisionRender($(rsp).find('post_content_xhtml'),dotclear.msg.content,revisionId); 
    55                          table += '</table>'; 
    56                          $(td).append(table) 
     50                         var excerpt_nodes = $(rsp).find('post_excerpt_xhtml').children(); 
     51                         var content_nodes = $(rsp).find('post_content_xhtml').children(); 
     52                         if (excerpt_nodes.size() == 0 && content_nodes.size() == 0) { 
     53                              $(td).append('<strong>' + dotclear.msg.content_identical + '</strong>'); 
     54                         } 
     55                         else { 
     56                              var excerpt = $(rsp).find('post_excerpt_xhtml'); 
     57                              var content = $(rsp).find('post_content_xhtml'); 
     58                              var table = '<table class="preview-rev">'; 
     59                              table += dotclear.viewRevisionRender(excerpt_nodes,dotclear.msg.excerpt,revisionId); 
     60                              table += dotclear.viewRevisionRender(content_nodes,dotclear.msg.content,revisionId); 
     61                              table += '</table>'; 
     62                              $(td).append(table); 
     63                         } 
    5764                    } 
    5865                    else { 
     
    7885}; 
    7986 
    80 dotclear.viewRevisionRender = function(content,title,revisionId){ 
    81      var res = '<thead><tr class="rev-header"><th colspan="3">'+title+'</th></tr>'+ 
    82      '<tr class="rev-number"><th class="minimal nowrap">'+dotclear.msg.current+ 
    83      '</th><th class="minimal nowrap">r'+revisionId+ 
    84      '</th><th class="maximal"></th></tr></thead><tbody>'; 
    85      if (content.size() > 0) { 
    86           var previous = ''; 
    87           content.find('line').each(function() { 
    88                var class = ''; 
    89                 
    90                var o = this.attributes[0].value; 
    91                var n = this.attributes[1].value; 
    92                var line = this.attributes[2].value; 
    93                console.log(previous+" - "+line); 
    94                if (o != '' && n == '') { 
    95                     class = ' delete'; 
    96                     if (previous == '') class += ' start'; 
    97                     previous = 'o'; 
    98                }  
    99                if (o == '' && n != '') { 
    100                     class = ' insert'; 
    101                     if (previous == '') class += ' start'; 
    102                     previous = 'n'; 
    103                } 
    104                if (o != '' && n != '') { 
    105                     if (previous == 'o') class = ' delete-end'; 
    106                     if (previous == 'n') class = ' insert-end'; 
    107                     previous = ''; 
    108                } 
    109                res += '<tr><td class="minimal col-line">'+o+ 
    110                '</td><td class="minimal col-line">'+n+ 
    111                '</td><td class="maximal'+class+'">'+line+ 
    112                '</td></tr>'; 
    113           }); 
     87dotclear.viewRevisionRender = function(nodes,title,revisionId){ 
     88     var res = lines = previous = ''; 
     89           
     90     nodes.each(function(k) { 
     91          var name = this.nodeName; 
     92          var content = $(this).text(); 
     93           
     94          var ol = $(this).attr('oline') != undefined ? $(this).attr('oline') : ''; 
     95          var nl = $(this).attr('nline') != undefined ? $(this).attr('nline') : ''; 
     96           
     97          if (name == 'skip') { 
     98               ol = nl = '&hellip;'; 
     99          } 
     100           
     101          var class = ''; 
     102           
     103          if (name == 'skip') { 
     104               class = ' skip'; 
     105          } 
     106          if (name == 'context') { 
     107               class = ' context'; 
     108          } 
     109          if (name == 'insert') { 
     110               class = ' insert'; 
     111          } 
     112          if (name == 'delete') { 
     113               class = ' delete'; 
     114          } 
     115           
     116          if (name != previous && (previous == '' || previous == 'context')) { 
     117               class += ' first'; 
     118          } 
     119          var next = nodes.size() > k+1 ? nodes.get(k+1).nodeName : ''; 
     120          if (name != next && next != 'insert' && next != 'delete') { 
     121               class += ' last'; 
     122          } 
     123           
     124          previous = name; 
     125           
     126          lines += '<tr><td class="minimal col-line">'+ol+ 
     127          '</td><td class="minimal col-line">'+nl+ 
     128          '</td><td class="'+class+'">'+content+ 
     129          '</td></tr>'; 
     130     }); 
     131      
     132     if (lines != '') { 
     133          res = '<thead><tr class="rev-header"><th colspan="3">'+title+'</th></tr>'+ 
     134          '<tr class="rev-number"><th class="minimal nowrap">'+dotclear.msg.current+ 
     135          '</th><th class="minimal nowrap">r'+revisionId+ 
     136          '</th><th class="maximal"></th></tr></thead><tbody>'+ 
     137          lines + '</tbody>'; 
    114138     } 
    115      res += '</tbody>'; 
     139      
    116140     return res; 
    117141}; 
     
    122146               $('#revisions-area').children().not('label'),{ 
    123147                    cookie:'dcx_post_revisions', 
    124                     hide:$('#revisions_area').val() == '<p></p>', 
    125148                    fn:dotclear.revisionExpander() 
    126149               } 
  • plugins/dcRevisions/style.css

    r338 r721  
    33# This file is part of dcRevisions, a plugin for Dotclear. 
    44# 
    5 # Copyright (c) 2010 Tomtom and contributors 
     5# Copyright (c) 2011 Tomtom and contributors 
    66# http://blog.zenstyle.fr/ 
    77# 
     
    1212*/ 
    1313#revisions-area { padding-bottom: 1em; } 
    14 table#revisions-list { display: none; } 
    15 table.preview-rev { width: 100%; } 
     14table#revisions-list { display: none; overflow: scroll; } 
     15table.preview-rev { 
     16     border-spacing: 0px; 
     17     border-collapse: separate; 
     18     overflow: scroll; 
     19} 
    1620table.preview-rev, table.preview-rev tr, table.preview-rev th, table.preview-rev td  { border: none; } 
    1721table.preview-rev thead { 
     
    1923     background-color: #f3f3f3; 
    2024} 
     25table.preview-rev tbody { 
     26     border: 1px dotted #aaa; 
     27} 
    2128table.preview-rev thead tr.rev-header th, table.preview-rev thead tr.rev-number th { 
    2229     border: 1px dotted #aaa; 
    2330     text-align: center; 
    2431} 
     32table.preview-rev td { font: normal 11px monospace; } 
    2533table.preview-rev td.center { text-align: center; } 
    2634table.preview-rev td.col-line { 
    2735     background-color: #eceade; 
    2836     color: #aaa; 
    29      border-top: 1px solid #aaa; 
    30      /*border-right: 1px solid #ccc;*/ 
     37     border-right: 1px solid #ccc; 
    3138     border-bottom: 1px solid #aaa; 
    3239     border-left: 1px solid #ccc; 
     40     text-align: right; 
    3341} 
     42/* Insert line */ 
     43table.preview-rev td.insert { 
     44     background-color: #dfd; 
     45     border-color: #0a0; 
     46     border-style: solid; 
     47     border-width: 0 1px 0 1px; 
     48} 
     49/* Delete line */ 
    3450table.preview-rev td.delete { 
    3551     background-color: #fdd; 
    36      border-left: 1px solid #c00; 
    37      border-right: 1px solid #c00; 
     52     border-color: #c00; 
     53     border-style: solid; 
     54     border-width: 0 1px 0 1px; 
    3855} 
    39 table.preview-rev td.delete.start { 
    40      border-top: 1px solid #c00; 
     56/* Skip line */ 
     57table.preview-rev td.skip { 
     58     background-color: #F7F7F7; 
     59     color: #D7D7D7; 
     60     border-color: #D7D7D7; 
     61     border-style: solid; 
    4162} 
    42 table.preview-rev td.delete-end { 
    43      border-top: 1px solid #c00; 
     63/* Common lines */ 
     64table.preview-rev td.first { 
     65     border-width: 1px 1px 0 1px; 
    4466} 
    45 table.preview-rev td.insert { 
    46      background-color: #dfd; 
    47      border-left: 1px solid #0a0; 
    48      border-right: 1px solid #0a0; 
     67table.preview-rev td.last { 
     68     border-width: 0 1px 1px 1px; 
    4969} 
    50 table.preview-rev td.insert.start { 
    51      border-top: 1px solid #0a0; 
     70table.preview-rev td.first.last { 
     71     border-width: 1px; 
    5272} 
    53 table.preview-rev td.insert-end { 
    54      border-top: 1px solid #0a0; 
    55 } 
    56  
    57 del { 
     73table.preview-rev td.delete del { 
    5874     text-decoration: none; 
    5975     background-color: #e99; 
    6076     padding: 0.2em 0 0.2em 0; 
    6177} 
    62 ins { 
     78table.preview-rev td.insert ins { 
    6379     text-decoration: none; 
    6480     background-color: #9e9; 
Note: See TracChangeset for help on using the changeset viewer.

Sites map