<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; HTA/JScript: Логер буфера обмена]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=6955</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=6955&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «HTA/JScript: Логер буфера обмена».]]></description>
		<lastBuildDate>Sun, 18 Mar 2012 19:04:23 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: HTA/JScript: Логер буфера обмена]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=58028#p58028</link>
			<description><![CDATA[<p>Поправил код в первом посте: для использования Ctrl+F см. строки 183 и 240 (комментить, соответственно, 182 и 239).<br />Заменил screen.width на screen.availWidth. Поигрался с цветами выделения и строки поиска.</p><p>24.03.12&nbsp; Buffer доведён до релиза, код в первом посте обновлён. Теперь Ctrl+F и Ctrl+S работают одновременно - кому как удобнее. Подсказка по горячим кнопам - F1. Изменено отображение перевода. Все слегка причесано.</p>]]></description>
			<author><![CDATA[null@example.com (Serge Yolkin)]]></author>
			<pubDate>Sun, 18 Mar 2012 19:04:23 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=58028#p58028</guid>
		</item>
		<item>
			<title><![CDATA[Re: HTA/JScript: Логер буфера обмена]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=58024#p58024</link>
			<description><![CDATA[<p>2<strong>mozers</strong><br />Спасибо на добром слове!<br />За screen.width - спасибо. Для начального позиционирования сам догадался (скрипт в head), а вот при скрытии/восстановлении тупо забыл.<br />1), 3) бОльшая часть этого (и не только этого) творения написана на нотнике (маленькая диагональ, высокое разрешение - пиксель очень мелкий) в дороге (в основном, в машине) т.е. в офлайне. Остальная часть - на нескольких разных компах с разными настройками (на работе, например, аплоуд зарезан насмерть, правда, это настройки сети, а не компа)<br />2) у меня Ctrl+S настроен для быстрого фильтра в TC и быстрого поиска в AkelPad&#039;е (QSearch), в котором всё и пишется, поэтому, для себя-любимого так привычнее. А по Ctrl+F обычно вызывается диалог поиска...<br />Поскольку для посетителей именно этого форума скриптинг - не китайская грамота, каждый может подправить сценарий под себя, а я готов помочь в меру своего скиллевела.</p>]]></description>
			<author><![CDATA[null@example.com (Serge Yolkin)]]></author>
			<pubDate>Sun, 18 Mar 2012 16:26:09 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=58024#p58024</guid>
		</item>
		<item>
			<title><![CDATA[Re: HTA/JScript: Логер буфера обмена]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=58012#p58012</link>
			<description><![CDATA[<p>2<strong>Serge Yolkin</strong><br />Прикольно получилось <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /><br />Правда (поскольку у меня тулбар - справа) сразу заметил мелкую ошибочку: в строках 269 и 308 надо заменить <strong>screen.width</strong> на <strong>screen.availWidth</strong>.<br />Ну и пара маленьких ИМХО: 1)шрифт просто огромный 2)Про Ctrl+F <strong>Rumata</strong> верно заметил. 3)Очень рекомендую googlecode для размещения своих скриптов. Супер удобно обновлять и отслеживать все изменения в коде. И самому и людям.</p>]]></description>
			<author><![CDATA[null@example.com (mozers)]]></author>
			<pubDate>Sun, 18 Mar 2012 10:59:13 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=58012#p58012</guid>
		</item>
		<item>
			<title><![CDATA[Re: HTA/JScript: Логер буфера обмена]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=57999#p57999</link>
			<description><![CDATA[<div class="quotebox"><cite>Rumata пишет:</cite><blockquote><p>Почему не привычная Ctrl+F?</p></blockquote></div><p>26-я строка снизу - поменять</p><div class="codebox"><pre><code>if(event.keyCode==83)tt.focus();        // Ctrl+S — поиск</code></pre></div><p>на</p><div class="codebox"><pre><code>if(event.keyCode==70)tt.focus();        // Ctrl+F — поиск</code></pre></div><p>Привычное у всех разное...<br />По поводу blur() - окно не теряет фокус, поскольку скрипт выполняется в контексте окна. М.б. и теряет, но тогда получает его обратно.</p>]]></description>
			<author><![CDATA[null@example.com (Serge Yolkin)]]></author>
			<pubDate>Sat, 17 Mar 2012 20:15:15 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=57999#p57999</guid>
		</item>
		<item>
			<title><![CDATA[Re: HTA/JScript: Логер буфера обмена]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=57995#p57995</link>
			<description><![CDATA[<div class="quotebox"><cite>Serge Yolkin пишет:</cite><blockquote><p>поиск по списку&nbsp; - Ctrl+S</p></blockquote></div><p>Почему не привычная Ctrl+F?</p><div class="quotebox"><cite>Serge Yolkin пишет:</cite><blockquote><p>Заставить окно потерять фокус в рамках JScript</p></blockquote></div><div class="codebox"><pre><code>window.blur();</code></pre></div><p>или</p><div class="codebox"><pre><code>document.body.blur();</code></pre></div><p>Но не уверен в том, что это решит задачу потери фокуса и минимизации окна.</p>]]></description>
			<author><![CDATA[null@example.com (Rumata)]]></author>
			<pubDate>Sat, 17 Mar 2012 19:28:21 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=57995#p57995</guid>
		</item>
		<item>
			<title><![CDATA[HTA/JScript: Логер буфера обмена]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=57990#p57990</link>
			<description><![CDATA[<p>Простенький сценарий, являющийся чем-то вроде менеджера буфера обмена. Мониторит буфер и добавляет в список (лог) его новое содержимое (только текст). Список редактируемый - можно править перед дальнейшим использованием. <br />Работает поиск по списку (спасибо уважаемому <strong>mozers™</strong>) - Ctrl+S или клик на строке поиска в верхней части окна. Найденное подсвечивается сразу, для перехода к следующему вхожению - Enter. Соответственно, Enter для редактирования (новый абзац), работает только при пустой (серое приглашение) строке поиска. <br />Дополнительная фича - онлайн перевод (взят целиком из <a href="http://forum.wincmd.ru/viewpost.php?p=81338">другого моего сценария</a>) - Ctrl+T или клик на кнопке с иконкой Bing (если иконка на кнопке не отображается - сервис недоступен). Логика: если есть выделение в списке - будем переводить выделение, если выделения нет - проверяем, нет ли чего в самом первом абзаце (обычно он пустой) и, если есть, переводим - это для перевода &quot;с руки&quot;, без копирования в буфер. Если и там - ничего, ничего и не переводим. <br />Esc при активном окне сценария или клик на кнопке [_] прячет окно (на самом деле просто двигает его за пределы экрана). Чтобы снова отобразить надо кликнуть на кнопке скрипта в панели задач, или дойти до него по Alt+T. ! Под Win7 перед тем, как вызывать скрытое окно сценария, надо где-нибудь кликнуть - на десктопе, окне или кнопке любого другого приложения, свободном месте панели задач! Дело в том, что отображение скрытого окна привязано к событию onfocus, а без переключения на другое окно сценарий фокус не теряет, соответственно, и не получает. Заставить окно потерять фокус в рамках JScript мне не удалось. <br /><em>В данной версии не сохраняет сессию - надо повозиться с ограничением размера файла при сохранении, а то у тех, кого ломает порядок наводить, файл с сохраненным списком очень скоро может стать безразмерным.</em> - относилось к предыдущей версии. Теперь история сохраняется, но не ограничивается. Чистить лог прийдется самостоятельно, или по окончанию очередного проекта снесите файл Buffer.log<br /><strong>Buffer.hta</strong></p><div class="codebox"><pre><code>&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
  &lt;!-- Простенький менеджер буфера обмена с онлайн переводчиком --&gt;
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
  &lt;meta http-equiv=&quot;MSThemeCompatible&quot; content=&quot;yes&quot; /&gt;
  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=8&quot; /&gt;
  &lt;hta:application
   applicationName=&quot;BLingvist-XVIc&quot;
   border=&quot;dialog&quot;
   borderStyle=&quot;complex&quot;
   caption=&quot;no&quot;
   icon=&quot;%SystemRoot%/system32/ctfmon.exe&quot;
   innerBorder=&quot;no&quot;
   id=&quot;HTApp&quot;
   navigable=&quot;no&quot;
   singleInstance=&quot;yes&quot;
   version=&quot;1.21&quot;
   /&gt;
  &lt;script type=&quot;text/jscript&quot; language=&quot;JScript&quot;&gt;
    self.resizeTo(400,screen.availHeight);
    self.moveTo(screen.availWidth-400,0);
  &lt;/script&gt;
  &lt;style type=&quot;text/css&quot;&gt;
   *{margin:0;padding:0;}
   body{background-color:infobackground;}
   button{color:blue;font-family:Webdings;width:40px;}
   button,div{position:absolute;}
   button{height:25px;top:0;}
   div,#bt{left:0;}
   div,#be{right:0;}
   p{border-bottom:solid 1px silver;padding-bottom:8px;word-wrap:break-word;}
   p,#tt{font-family:Arial;font-size:16px;}
   span{font-weight:bold;}
   #bc{right:39px;}
   #be{color:crimson;}
   #tt{border:none;height:19px;margin:3px 84px 0 44px;overflow:hidden;padding-left:4px;top:0;width:265px;white-space:nowrap;}
   #ws{border-top:solid 1px silver;bottom:0;color:navy;overflow-y:scroll;padding:8px;top:25px;}
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id=&quot;tt&quot; contenteditable=&quot;true&quot;&gt;&lt;/div&gt;
    &lt;button hidefocus=&quot;true&quot; id=&quot;bt&quot; onmousedown=&quot;fg();&quot; title=&quot;Перевод    «Ctrl+T»&quot; type=&quot;button&quot;&gt;
      &lt;img alt=&quot;M$&quot; src=&quot;http://www.microsofttranslator.com/favicon.ico&quot; style=&quot;margin-top:1px;&quot; /&gt;
    &lt;/button&gt;
    &lt;button hidefocus=&quot;true&quot; id=&quot;bc&quot; onclick=&quot;self.moveTo(screen.width,0);&quot; title=&quot;Скрыть    «Esc»&quot; type=&quot;button&quot;&gt;0&lt;/button&gt;
    &lt;button hidefocus=&quot;true&quot; id=&quot;be&quot; onclick=&quot;window.close();&quot; title=&quot;Выход    «Alt+F4»&quot; type=&quot;button&quot;&gt;r&lt;/button&gt;
  &lt;div id=&quot;ws&quot; contenteditable=&quot;false&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;script type=&quot;text/jscript&quot; language=&quot;JScript&quot;&gt;
  var
   Arr=new Array(),                // массив фрагментов для перевода
   arq,                        // осталось перевести
   cd=window.clipboardData,            // clipboardData
   co=&#039;&#039;,                    // старое значение буфера обмена
   cn=&#039;&#039;,                    // новое значение буфера обмена
   fng=0,                    // поиск — текущее вхождение
   fnq,                        // поиск — найдено вхождений
   ld=document.createElement(&#039;script&#039;),        // сервис MicrosoftTranslator
   le=new ActiveXObject(&#039;WScript.Shell&#039;),
   lf=new ActiveXObject(&#039;Scripting.FileSystemObject&#039;),
   lfn=HTApp.commandLine.replace(/^&quot;([^&quot;]+)\.hta&quot;\s*.*$/,&#039;$1&#039;)+&#039;.log&#039;,
   li,                        // язык на входе
   lo,                        // язык на выходе
   tit=document.title=&#039;«Буфер &#039;+HTApp.version+&#039;»&#039;,
   tr,                        // TextRange
   ts,                        // HighLight Range (перевод)
   mid=&#039;B5C728A51E78F96A9277D318720A4BD9FC0F3EB3&#039;;
   // при написании собственных скриптов получите пожалуйста
   // собственный Bing id (это бесплатно): 
  if(lf.fileExists(lfn)){            // если сохранен предыдущий сеанс
    with(lf.OpenTextFile(lfn)){            // загружаем сохраненное
      if(!AtEndOfStream)ws.innerHTML=ReadAll();
      Close();
    }
    // проверяем, не сохранено ли текущее значение буфера
    try{    // на случай, если буфер пуст
      if(cd.getData(&#039;text&#039;).replace(/\s/g,&#039;&#039;)==ws.all.tags(&#039;p&#039;)[1].innerText.replace(/\s/g,&#039;&#039;)){
        co=cd.getData(&#039;text&#039;);
      }
    }catch(e){}
  }
  fz();
  // функции:
  function fd(){                // выделить вхождение
    tr.findText(tt.innerText);
    tr.select();
    tr.collapse(false);
  }
  function ff(){                // подсветить все
    tr=null;
    ws.innerHTML=fs();
    tt.innerHTML=tt.innerText;
    tt.style.backgroundColor=&#039;&#039;;
    if(tt.innerText.replace(/\s/g,&#039;&#039;)==&#039;&#039;)return;
    tr=document.body.createTextRange();
    for(var i=0;tr.findText(tt.innerText);i++){
      if(tr.parentElement().tagName==&#039;P&#039;)tr.execCommand(&#039;backColor&#039;,&#039;&#039;,&#039;#bf7&#039;);
      tr.collapse(false);
    }
    fnq=i
    if(fnq==1&amp;&amp;tt.innerText)tt.style.backgroundColor=&#039;#fbd&#039;;
    if(fnq==2&amp;&amp;tt.innerText)tt.style.backgroundColor=&#039;#bdf&#039;;
  }
  function fg(){                // определяем условия перевода
    var sel;
    ts=document.selection.createRange()
    if(ts.text.replace(/\s/g,&#039;&#039;)){    // если есть выделение — будем переводить его
      sel=ts.text;
    }else{                // иначе — содержимое первого параграфа
      ts=null;
      sel=ws.firstChild.innerText;
    }
    if(sel.replace(/\s/g,&#039;&#039;)){
      sel=sel.replace(/^\s*|\s*$|[\f\r\v\0]/g,&#039;&#039;).replace(/\s*\n\s*/g,&#039;\n&#039;);
      ld.src=&#039;http://api.microsofttranslator.com/V2/Ajax.svc/Detect?oncomplete=cb&amp;appId=&#039;+mid+&#039;&amp;text=&#039;+sel.substring(0,100);
      window.cb=function(e){
        li=e;
        lo=(e==&#039;ru&#039;)?&#039;en&#039;:&#039;ru&#039;;
        fj(sel);
      };
      document.all.tags(&#039;html&#039;)[0].appendChild(ld);
    }else{        // если нечего переводить — курсор на первый параграф
      ws.firstChild.focus();
      return;
    }
    tt.style.backgroundColor=&#039;#fa5&#039;;
  }
  function fj(e){                // предобработка и перевод
    var
     rx=new RegExp(&#039;.+&#039;,&#039;g&#039;),
     res,
     rsl,
     pp;
    while((rsl=rx.exec(e))!=null){        // разбиваем на абзацы
      var
       rcr=true,
       arg=rsl[0].replace(/\s+/g,&#039; &#039;);
      Arr.length?pp=true:pp=false;
      while(rcr){
        if(arg.length&gt;650){            // бьём слишком длинные абзацы
          var pt=0;
          rx.compile(/(\.|\!|\?)\s/g);
          while((res=rx.exec(arg.substring(0,650)))!=null)pt=rx.lastIndex;
          if(pt&lt;300){
            rx.compile(/\s/g);
            while((res=rx.exec(arg.substring(0,650)))!=null)pt=rx.lastIndex;
          }
          Arr[Arr.length]={t:arg.substring(0,pt),r:&#039;&#039;,i:false};
          arg=arg.substring(pt,arg.length);
        }else{
          Arr[Arr.length]={t:arg,r:&#039;&#039;,i:pp};
          rcr=false;
        }
      }
    }
    arq=Arr.length;
    for(var i=0;i&lt;arq;i++){            // отправляем на перевод
      var s=document.createElement(&#039;script&#039;);
      s.id=&#039;cs&#039;+i;
      s.src=&#039;http://api.microsofttranslator.com/V2/Ajax.svc/Translate?oncomplete=cb&#039;+i+&#039;&amp;appId=&#039;+mid+&#039;&amp;from=&#039;+li+&#039;&amp;to=&#039;+lo+&#039;&amp;text=&#039;+Arr[i].t;
      document.all.tags(&#039;html&#039;)[0].appendChild(s);
      window.execScript(&#039;window.cb&#039;+i+&#039;=new Function(&quot;e&quot;,&quot;Arr[&#039;+i+&#039;].r=e;if(--arq==0)fr();&quot;);&#039;);
    }
  }
  function fp(){                // создать параграф
    var t=document.createElement(&#039;p&#039;);
    t.contentEditable=true;
    return(t);
  }
  function fr(){                // формируем оригинал и перевод
    var t=&#039;&#039;,u=&#039;&#039;,v=&#039; &#039;,w;
    for(var i=0;i&lt;Arr.length;i++){    
      if(Arr[i].i){
        t+=&#039;&lt;br /&gt;&#039;+Arr[i].r;
        u+=&#039;&lt;br /&gt;&#039;+Arr[i].t;
        v=&#039;&lt;br /&gt;&#039;;
      }else{
        t+=Arr[i].r;
        u+=Arr[i].t;
      }
    }
    w=&#039;&lt;span style=&quot;color:blue;font-weight:bold;&quot;&gt;&#039;+u+
     &#039;&lt;/span&gt;&#039;+v+&#039;&lt;span style=&quot;color:crimson;&quot;&gt;[ &#039;+
     li+&#039;&gt;&#039;+lo+v+t+&#039; ]&lt;/span&gt;&#039;;
    if(ts){        // если перевели выделение
      ts.pasteHTML(w+v);
    }else{        // если перевели первый параграф
      with(ws){
        firstChild.innerHTML=w;
        insertBefore(fp(),firstChild);
      }
    }
    Arr.length=0;
    ts=null;
    tt.style.backgroundColor=&#039;&#039;;
  }
  function fs(){                // удалить подсветку
    return(ws.innerHTML.toString().replace(/&lt;\/?font[^&gt;]*&gt;/gi,&#039;&#039;));
  }
  function fu(){                // стоп вниз по Tab
    if(document.activeElement.nodeName!=&#039;P&#039;)ws.childNodes[ws.childNodes.length-1].focus();
  }
  function fv(){                // стоп вверх по Tab
    if(document.activeElement.nodeName!=&#039;P&#039;)ws.firstChild.focus();
  }
  function fz(){                // подсказка в строке поиска
    if(tt.innerText==&#039;&#039;){
      tt.style.color=&#039;silver&#039;;
      tt.innerText=&#039;&amp;#9658;Поиск   «Ctrl+S, Ctrl+F»&#039;;
    }
  }
  tt.onblur=function(){
    fz();
  }
  tt.onfocus=function(){
    if(tt.style.color==&#039;silver&#039;){
      tt.style.color=&#039;navy&#039;;
      tt.innerText=&#039;&#039;;
    }
  }
  tt.onkeypress=function(){
    if(event.keyCode){
      fng=0;
      window.setTimeout(&#039;ff()&#039;,50);
    }
  }
  tt.onkeyup=function(){
    if(event.altKey||event.ctrlKey||event.shiftKey)return;
    if(event.keyCode==8||event.keyCode==46){    // BackSpace или Delete
      window.setTimeout(&#039;ff()&#039;,50);
    }
  }
  tt.onpaste=function(){
    event.cancelBubble=true;
    // при вставке в строку поиска из буфера вставляется только первая строка:
    tt.innerText=cd.getData(&#039;text&#039;).replace(/^\s*([^\s][^\n]*)(\s*.*)*$/,&#039;$1&#039;);
    fng=0;
    window.setTimeout(&#039;ff()&#039;,50);
    return(false);
  }
  ws.oncopy=function(){
    cd.setData(&#039;text&#039;,co=document.selection.createRange().text.replace(/\s*$/,&#039;&#039;));
    return(false);
  }
  window.onbeforeunload=function(){        // сохранить историю
    if(ws.innerText&amp;&amp;le.popUp(&#039;Сохранить историю?&#039;,0,tit,4148)==6){
      var t=lf.OpenTextFile(lfn,2,true);
      t.Write(fs());    // ограничить длину сохраняемого ??? fs().length
      t.Close();    // или создавать файлы-архивы ??? ~ 40 000 bytes
    }
  }
  window.onfocus=function(){            // показать после скрытия
    self.moveTo(screen.availWidth-400,0);
  }
  window.onload=function(){            // захват буфера обмена
    if(!ws.childNodes.length){
      ws.appendChild(fp());
      ws.firstChild.focus();
    }
    window.setTimeout(arguments.callee,200);    // самовызов
    cn=cd.getData(&#039;text&#039;);
    cn=cn?cn.replace(/-{4,}|={4,}|\*{4,}/g,&#039;&#039;):&#039;&#039;;
    // если буфер не пуст и изменился:
    if(cn.replace(/\s/g,&#039;&#039;)&amp;&amp;cn.replace(/\s/g,&#039;&#039;)!=co.replace(/\s/g,&#039;&#039;)){
      co=cn;
      with(ws){
        if(firstChild.innerText){
          firstChild.innerText=firstChild.innerText.replace(/\s*$/,&#039;&#039;);
          insertBefore(fp(),firstChild);
        }
        firstChild.innerText=co.replace(/[\n\r]+/g,&#039;\n&#039;).replace(/\s*$/,&#039;&#039;);
        insertBefore(fp(),firstChild);
        blur();
        fz();
        firstChild.focus();
      }
    }
  }
  document.onkeydown=function(){        // горячие клавиши
    var acs=100*event.altKey+10*event.ctrlKey+1*event.shiftKey;
    switch(event.keyCode){
     case  27:        // Esc            скрыть
      self.moveTo(screen.availWidth,0);
      return;
     case 112:        // F1            справка
      le.popUp(hl.innerHTML,0,tit,32);
      return;
     case  84:        // Ctrl+T        перевод
      if(acs!=10)return;
     case 113:        // F2, Ctrl+T        перевод
      fg();
      return;
     case  13:        // Enter        \n вместо &lt;p&gt;
      if(acs==1||tt.style.color==&#039;silver&#039;){
      // если не в поиске, по Shift+Enter — даже если в поиске
        document.selection.createRange().text=&#039;\n&#039;;
        return(false);
      }
     case 114:        // F3, Enter         искать далее
      if(!acs&amp;&amp;tt.innerText&amp;&amp;tt.style.color!=&#039;silver&#039;){
        if(fng==0){
          tr=null;
          tr=document.body.createTextRange();
          fd();
          // исключаем символы на кнопках
          if(tt.innerText==&#039;0&#039;||tt.innerText==&#039;r&#039;){
            fd();
            ++fng;
          }
        }
        fd();
        if(++fng==fnq-1)fng=0;
      }
      return(false);
     case  69:        // Ctrl+E        объединить текущий со следующим
      if(acs!=10)return;
     case 116:        // F5, Ctrl+E        объединить текущий со следующим
      event.returnValue=false;
      var t=document.activeElement;
      if(t.tagName!=&#039;P&#039;){
        if(t.parentElement==&#039;P&#039;)t=t.parentElement;
        else return(false);
      }
      if(t.nextSibling){
        t.innerText+=&#039;\n&#039;+t.nextSibling.innerText+&#039;\n&#039;;
        ws.removeChild(t.nextSibling);
      }
      return(false);
     case  46:        // Ctrl+Shift+Del    очистить историю
      if(acs==11){
        if(le.popUp(&#039;Очистить историю?\nВсе данные будут потеряны!&#039;,3,tit,4116)!=6)return;
        if(lf.fileExists(lfn))lf.deleteFile(lfn);
        ws.innerHTML=&#039;&lt;p contenteditable&gt; &lt;/p&gt;&#039;;
        ws.firstChild.focus();
        ws.firstChild.innerText=tt.innerHTML=&#039;&#039;;
        tt.style.backgroundColor=&#039;&#039;;
        return;
      }else if(acs!=10)return;
     case 119:        // F8, Ctrl+Del        удалить параграф
      var t=document.activeElement;
      if(t.tagName!=&#039;P&#039;){
        if(t.parentElement==&#039;P&#039;)t=t.parentElement;
        else return(false);
      }
      if(t.nextSibling)t.nextSibling.focus();
      else if(t.previousSibling)t.previousSibling.focus();
      else return(false);
      ws.removeChild(t);
      return(false);
     case  70:        // Ctrl+F        поиск
     case  83:        // Ctrl+F, Ctrl+S    поиск
      if(acs!=10)return;
      var sel=document.selection.createRange().text;
      tt.focus();
      if(sel){        // если есть выделение — поиск по выделению
        tt.style.color=&#039;navy&#039;;
        tt.innerText=sel.replace(/^\s*([^\s][^\n]*)(\s*.*)*$/,&#039;$1&#039;);
        fng=0;
        window.setTimeout(&#039;ff()&#039;,50);
      }else{        // если нет — выделить строку поиска
        document.execCommand(&#039;selectAll&#039;);
      }
      sel=null;
      return(false);
     case  67:        // Ctrl+Shift+C        копировать всю историю (только текст)
      if(acs==11){
        var t=&#039;&#039;;
        for(var i=0;i&lt;ws.childNodes.length;i++){
          if(ws.childNodes[i].innerText)t+=ws.childNodes[i].innerText+&#039;\n&#039;;
        }
        t+=&#039;\n&#039;;
        cd.setData(&#039;text&#039;,co=t);
        return(false);
      }else return;
     case   9:        // Tab, Shift+Tab    не выпускать фокус из ws
      if(acs==0)window.setTimeout(&#039;fu()&#039;,1);
      else if(acs==1)window.setTimeout(&#039;fv()&#039;,1);
      else return(false);
    }
  }
&lt;/script&gt;
&lt;comment id=&quot;hl&quot;&gt;История буфера обмена
Особенности: при копировании из истории фрагмент
копируется без стилей только текст; кнопка Tab
(Shift+Tab) перемещает фокус в пределах истории,
доступ к другим элементам интерфейса — с помощью
мыши, или горячих клавишей:
  Справка        F1
  Перевод        F2,    Ctrl+T*
  Поиск            Ctrl+F,    Ctrl+S*
  Искать далее        F3,    Enter
  Абзац в режиме поиска    Shift+Enter
  Скрыть            Esc
  Копировать историю    Ctrl+Shift+C    
  Очистить историю    Ctrl+Shift+Del
  Выход            Alt+F4

управление параграфами:
  Следующий        Tab
  Предыдующий        Shift+Tab    
  Выделить        Ctrl+A
  Объединить следующий    F5    Ctrl+E
  Удалить        F8,    Ctrl+Del

*  при наличии выделения в истории поиск/перевод
осуществляются по тексту выделения, иначе — фокус
помещается в строку поиска, или в первый параграф
соответственно.

Сергей Ёлкин (2012)
&lt;/comment&gt;
&lt;/html&gt;</code></pre></div><p>если что-то съехало (я использую табуляции), <a href="http://forum.wincmd.ru/viewpost.php?p=90784">здесь</a> можно взять архив 7z в base64, как извлечь писалось <a href="http://forum.script-coding.com/viewtopic.php?pid=55701#p55701">здесь</a>.</p>]]></description>
			<author><![CDATA[null@example.com (Serge Yolkin)]]></author>
			<pubDate>Sat, 17 Mar 2012 18:53:43 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=57990#p57990</guid>
		</item>
	</channel>
</rss>
