<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ars Longa, Vita Brevis &#187; JavaScript</title>
	<atom:link href="http://blog.sjinks.pro/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sjinks.pro</link>
	<description>Quod scripsi, scripsi</description>
	<lastBuildDate>Mon, 06 Feb 2012 17:56:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Автоматическое добавление ссылки на источник при копировании текста с сайта</title>
		<link>http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/</link>
		<comments>http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 03:42:35 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=958</guid>
		<description><![CDATA[Навязчивое добавление ссылки на оригинал при копировании текста с сайта Идея: когда пользователь выделяет часть текста и копирует её в буфер обмена (например, чтобы выложить на своём сайте), автоматически добавлять к выделению ссылку на источник. Реализация: var source_link = &#039;&#60;p&#62;Подробнее: &#60;a href=&#34;&#039; + location.href + &#039;&#34;&#62;&#039; + location.href + &#039;&#60;/a&#62;&#60;/p&#62;&#039;; jQuery( function($) { if (window.getSelection) [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Навязчивое добавление ссылки на оригинал при копировании текста с сайта</em></h2>
<p><strong>Идея:</strong> когда пользователь выделяет часть текста и копирует её в буфер обмена (например, чтобы выложить на своём сайте), автоматически добавлять к выделению ссылку на источник.<span id="more-958"></span></p>
<p><strong>Реализация:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9582">
        <div class="code javascript" id="p958code2">
<span class="kw2">var</span> source_link <span class="sy0">=</span> <span class="st0">'&lt;p&gt;Подробнее: &lt;a href=&quot;'</span> <span class="sy0">+</span> location.<span class="me1">href</span> <span class="sy0">+</span> <span class="st0">'&quot;&gt;'</span> <span class="sy0">+</span> location.<span class="me1">href</span> <span class="sy0">+</span> <span class="st0">'&lt;/a&gt;&lt;/p&gt;'</span><span class="sy0">;</span><br />
jQuery<span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span>$<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>window.<span class="me1">getSelection</span><span class="br0">&#41;</span> $<span class="br0">&#40;</span><span class="st0">'#content div.post'</span><span class="br0">&#41;</span>.<span class="me1">bind</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">'copy'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> selection <span class="sy0">=</span> window.<span class="me1">getSelection</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> range <span class="sy0">=</span> selection.<span class="me1">getRangeAt</span><span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> magic_div <span class="sy0">=</span> $<span class="br0">&#40;</span><span class="st0">'&lt;div&gt;'</span><span class="br0">&#41;</span>.<span class="me1">css</span><span class="br0">&#40;</span><span class="br0">&#123;</span> overflow <span class="sy0">:</span> <span class="st0">'hidden'</span><span class="sy0">,</span> width<span class="sy0">:</span> <span class="st0">'1px'</span><span class="sy0">,</span> height <span class="sy0">:</span> <span class="st0">'1px'</span><span class="sy0">,</span> position <span class="sy0">:</span> <span class="st0">'absolute'</span><span class="sy0">,</span> top<span class="sy0">:</span> <span class="st0">'-10000px'</span><span class="sy0">,</span> left <span class="sy0">:</span> <span class="st0">'-10000px'</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; magic_div.<span class="me1">append</span><span class="br0">&#40;</span>range.<span class="me1">cloneContents</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> source_link<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">'body'</span><span class="br0">&#41;</span>.<span class="me1">append</span><span class="br0">&#40;</span>magic_div<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> cloned_range <span class="sy0">=</span> range.<span class="me1">cloneRange</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selection.<span class="me1">removeAllRanges</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> new_range <span class="sy0">=</span> document.<span class="me1">createRange</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_range.<span class="me1">selectNode</span><span class="br0">&#40;</span>magic_div.<span class="me1">get</span><span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selection.<span class="me1">addRange</span><span class="br0">&#40;</span>new_range<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; window.<span class="me1">setTimeout</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selection.<span class="me1">removeAllRanges</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selection.<span class="me1">addRange</span><span class="br0">&#40;</span>cloned_range<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; magic_div.<span class="me1">remove</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy0">,</span> 0<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p><strong>Настраиваемые параметры</strong>:</p>
<ul>
<li><code>source_link</code> — текст, который будет добавляться к копируемому фрагменту. В данном примере задаётся статически, но при желании генерацию ссылки можно усложнить (например, при копировании с текста с домашней страницы можно возвращать ссылку на статью, из которой взята данная цитата). Для этого в строке <code>magic_div.append(range.cloneContents(), source_link);</code> вместо <code>source_link</code> нужно использовать свою функцию, возвращающую <a href="http://blog.sjinks.pro/tag/html/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  HTML">HTML</a> для вставки в копируемый фрагмент.</li>
<li><code>'#content div.post'</code> — выражение, задающее один или более контейнер с текстом, при копировании которого нужно добавлять ссылку на оригинал. Идея в том, что добавлять ссылку на статью при копировании, скажем, части текста одного из комментариев к статье было бы нелогично. С помощью данного выражения можно задать требуемые защищаемые объекты.</li>
</ul>
<p><strong>Возможные улучшения:</strong> проверка длины копируемого текста. Например, если пользователь копирует меньше 20 слов, не добавлять ссылку. Получить выделенный текст можно через <code>range.cloneContents().textContent</code>.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Обход плагина WP Hashcash</title>
		<link>http://blog.sjinks.pro/security/955-bypass-wp-hashcash/</link>
		<comments>http://blog.sjinks.pro/security/955-bypass-wp-hashcash/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 05:43:11 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[Плагины WordPress]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[плагин]]></category>
		<category><![CDATA[спам]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=955</guid>
		<description><![CDATA[Не так страшен JavaScript, как его малюют… WP Hashcash — очередной плагин WordPress для борьбы со спамом. Принцип работы основывается на том, что спам-боты не умеют исполнять JavaScript. Идея в том, что если пользователь открыл сайт из браузера, браузер выполнит некоторый хитрый код JavaScript, и реузльтат работы этого скрипта будет передан назад на сервер в качестве доказательства [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/955-bypass-wp-hashcash/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Не так страшен <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a>, как его малюют…</em></h2>
<p><a href="http://wordpress-plugins.feifei.us/hashcash/">WP Hashcash</a> — очередной <a href="http://blog.sjinks.pro/tag/plugin/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  плагин">плагин</a> <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> для борьбы со спамом. Принцип работы основывается на том, что <a href="http://blog.sjinks.pro/tag/spam/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  спам">спам</a>-боты не умеют исполнять JavaScript. Идея в том, что если пользователь открыл сайт из браузера, браузер выполнит некоторый хитрый код JavaScript, и реузльтат работы этого скрипта будет передан назад на сервер в качестве доказательства «человечности» комментатора.<span id="more-955"></span></p>
<p>Недостаток этого подхода заключается в том, что используемый JavaScript является довольно-таки простым; как следствие, его можно «понять» даже из <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>-скрипта.</p>
<p>Пример кода JavaScript, генерируемого плагином:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9559">
        <div class="code javascript" id="p955code9">
<span class="kw2">function</span> wphc<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> wphc_data <span class="sy0">=</span> <span class="br0">&#91;</span>1850500665<span class="sy0">,</span>1666021931<span class="sy0">,</span>1699898495<span class="sy0">,</span>1648446524<span class="sy0">,</span>2035770162<span class="sy0">,</span>1980447546<span class="sy0">,</span>2018932269<span class="sy0">,</span>956464429<span class="sy0">,</span>890644332<span class="sy0">,</span>956447103<span class="sy0">,</span>890644332<span class="sy0">,</span>973224063<span class="sy0">,</span>890579818<span class="sy0">,</span>761213796<span class="sy0">,</span>1850368808<span class="sy0">,</span>1615687680<span class="sy0">,</span>1750492719<span class="sy0">,</span>756628087<span class="br0">&#93;</span><span class="sy0">;</span> <br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i<span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> i<span class="sy0">&lt;</span>wphc_data.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">=</span>wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">^</span><span class="nu0">220336991</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> a <span class="sy0">=</span> <span class="kw2">new</span> Array<span class="br0">&#40;</span>wphc_data.<span class="me1">length</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i<span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> i<span class="sy0">&lt;</span>wphc_data.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">=</span> String.<span class="me1">fromCharCode</span><span class="br0">&#40;</span>wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">&gt;&gt;&gt;</span>8 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">&gt;&gt;&gt;</span>16 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">&gt;&gt;&gt;</span>24 <span class="sy0">&amp;</span> 0xFF<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">eval</span><span class="br0">&#40;</span>a.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">''</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Такой JavaScript весьма похож на PHP <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Как следствие, идея обхода плагина заключается в том, чтобы преобразовать JavaScript в PHP и выполнить получившийся PHP-код.</p>
<p>Итак:</p>
<ol>
<li>В PHP нет ключевого слова <code>var</code> (строго говоря, оно там есть, только имеет другое назначение).</li>
<li>В PHP несколько другой синтаксис объявления массива</li>
<li>Идентификаторы в PHP начинаются с доллара</li>
<li>Операция сдвига выглядит как <code>&gt;&gt;</code>, а не <code>&gt;&gt;&gt;</code>.</li>
<li>В PHP нет классов Array, String, но никто не мешает их написать <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ol>
<p>Наша задача состоит в преобразовании кода, приведённого выше, в нечто подобное:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95510">
        <div class="code php" id="p955code10">
<span class="kw2">function</span> wphc<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$wphc_data</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span>1850500665<span class="sy0">,</span>1666021931<span class="sy0">,</span>1699898495<span class="sy0">,</span>1648446524<span class="sy0">,</span>2035770162<span class="sy0">,</span>1980447546<span class="sy0">,</span>2018932269<span class="sy0">,</span>956464429<span class="sy0">,</span>890644332<span class="sy0">,</span>956447103<span class="sy0">,</span>890644332<span class="sy0">,</span>973224063<span class="sy0">,</span>890579818<span class="sy0">,</span>761213796<span class="sy0">,</span>1850368808<span class="sy0">,</span>1615687680<span class="sy0">,</span>1750492719<span class="sy0">,</span>756628087<span class="br0">&#41;</span><span class="sy0">;</span> <br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&lt;</span>count<span class="br0">&#40;</span><span class="re0">$wphc_data</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">=</span><span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span>^<span class="nu0">220336991</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&lt;</span>count<span class="br0">&#40;</span><span class="re0">$wphc_data</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$a</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span> <span class="sy0">=</span> fromCharCode<span class="br0">&#40;</span><span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span> <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">&gt;&gt;</span>8 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">&gt;&gt;</span>16 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">&gt;&gt;</span>24 <span class="sy0">&amp;</span> 0xFF<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span><span class="kw3">join</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="sy0">,</span> <span class="re0">$a</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Это достигается таким набором правил <code>str_replace()</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95511">
        <div class="code php" id="p955code11">
<span class="re0">$x</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st_h">'wphc_data'</span> &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$wphc_data'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'var $'</span> &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'var '</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'$'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'];'</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">');'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'= ['</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'= array('</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'new Array($wphc_data.length)'</span> <span class="sy0">=&gt;</span> <span class="st_h">'array()'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'$wphc_data.length'</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'count($wphc_data)'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">' i&lt;'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">' $i&lt;'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'[i]'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'[$i]'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'i++'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$i++'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'&gt;&gt;&gt;'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'&gt;&gt;'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'a[$i] ='</span> &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$a[$i] ='</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'String.'</span> &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'eval'</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st0">&quot;a.join('')&quot;</span> <span class="sy0">=&gt;</span> <span class="st_h">'join(&quot;&quot;, $a)'</span><span class="sy0">,</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="kw3">array_keys</span><span class="br0">&#40;</span><span class="re0">$x</span><span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="kw3">array_values</span><span class="br0">&#40;</span><span class="re0">$x</span><span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="re0">$s</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>При желании правила можно попытаться оптимизировать, но мне было лень — скрипт ломался на коленке за 10 минут.</p>
<p>Реализация функции <code>fromCharCode</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95512">
        <div class="code php" id="p955code12">
<span class="kw2">function</span> fromCharCode<span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">,</span> <span class="re0">$b</span><span class="sy0">,</span> <span class="re0">$c</span><span class="sy0">,</span> <span class="re0">$d</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$b</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$c</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$d</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>После замены результат нужно вычислить при помощи <code>eval()</code>. После чего получим такой результат:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95513">
        <div class="code javascript" id="p955code13">
<span class="kw2">function</span> wphc_compute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="kw1">return</span> 43448 <span class="sy0">*</span> 43448 <span class="sy0">+</span> <span class="nu0">75878</span><span class="sy0">;</span> <span class="br0">&#125;</span> wphc_compute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Как можно заметить, этот код является одновременно и PHP-кодом, и JavaScript-кодом.</p>
<p>Следующий шаг —</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95514">
        <div class="code php" id="p955code14">
<span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="st_h">'wphc_compute();'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">eval</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">echo</span> wphc_compute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Результатом выполнения будет число 1887804582.</p>
<p>Как видим, для обхода такой простой защиты не нужен даже интерпретатор JavaScript <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/955-bypass-wp-hashcash/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/955-bypass-wp-hashcash/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Заголовки HTTP для обеспечения безопасности сайта</title>
		<link>http://blog.sjinks.pro/security/884-http-headers-to-secure-website/</link>
		<comments>http://blog.sjinks.pro/security/884-http-headers-to-secure-website/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 12:28:06 +0000</pubDate>
		<dc:creator>Wandering Soul</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[атака]]></category>
		<category><![CDATA[безопасность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=884</guid>
		<description><![CDATA[Активация средств защиты, встроенных в современные бразуеры, для обеспечения дополнительной безопасности пользователей Безопасность сайта — это бесконечная битва между веб-мастерами и хакерами. В &#60;/xssed&#62; зарегистрировано около 40,000 сайтов, подверженных атакам XSS. XSS-атаки позволяют злоумышленникам красть cookie, личную информацию, взламывать аккаунты и многие другие вещи. Существует множество способов для защиты сайта, но ни один из них не может гарантировать [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/884-http-headers-to-secure-website/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Активация средств защиты, встроенных в современные бразуеры, для обеспечения дополнительной безопасности пользователей</em></h2>
<p><a href="http://blog.sjinks.pro/tag/tag-security/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  безопасность">Безопасность</a> сайта — это бесконечная битва между веб-мастерами и хакерами. В <a href="http://xssed.com/">&lt;/xssed&gt;</a> зарегистрировано около 40,000 сайтов, подверженных атакам <a href="http://blog.sjinks.pro/tag/xss/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XSS">XSS</a>. <a href="http://blog.sjinks.pro/tag/xss/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XSS">XSS</a>-атаки позволяют злоумышленникам красть cookie, личную информацию, взламывать аккаунты и многие другие вещи.</p>
<p>Существует множество способов для защиты сайта, но ни один из них не может гарантировать абсолютную безопасность. Как следствие, нужно использовать многоуровневую эшелонную зашиту для обеспечения безопасности сайта.</p>
<p>В данной статье будет показан один из вариантов защиты — основанный на использовании заголовков HTTP.<span id="more-884"></span></p>
<p>Современные браузеры сами предоставляют довольно мощную защиту для своих пользователей… Единственное «но» — сайт должен попросить браузер включить эту защиту. К счастью, это довольно просто.</p>
<p>Для <a href="http://blog.sjinks.pro/tag/apache/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Apache">Apache</a>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p88418">
        <div class="code apache" id="p884code18">
<span class="co1"># Запретить всем сайтам загружать страницу через &lt;frame&gt;/&lt;iframe&gt;</span><br />
<span class="kw1">Header</span> set X-Frame-<span class="kw1">Options</span> <span class="kw1">DENY</span><br />
<br />
<span class="co1"># Разрешить выполнение JavaScript, загруженного только с нашего домена.</span><br />
<span class="co1"># Не выполнять встроенный (inline) JavaScript</span><br />
<span class="kw1">Header</span> set X-Content-Security-Policy <span class="st0">&quot;allow 'self';&quot;</span><br />
<br />
<span class="co1"># Включение предотвращения XSS-атак в IE 8</span><br />
<span class="kw1">Header</span> set X-XSS-Protection <span class="st0">&quot;1; mode=block&quot;</span>
        </div>
    </div>
</div>

<p>Для <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p88419">
        <div class="code nginx" id="p884code19">
<span class="kw1">add_header</span> X-Frame-Options DENY;<br />
<span class="kw1">add_header</span> X-Content-Security-Policy <span class="st0">&quot;allow 'self';&quot;</span>;<br />
<span class="kw1">add_header</span> X-XSS-Protection <span class="st0">&quot;1; mode=block&quot;</span>;
        </div>
    </div>
</div>

<p><strong>X-Frame-Options</strong></p>
<p>Данный заголовок указывает браузеру, можно ли загружать страницы сайта через <span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">frame</span>&gt;</span></code></span>/<span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">iframe</span>&gt;</span></code></span>.</p>
<p>Значение <code>DENY</code> запретит загрузку через фреймы, значение <code>SAMEORIGIN</code> разрешит загрузку через фреймы, но только если и фрейм, и страница, его загружающая, находятся на одном домене (<a href="http://en.wikipedia.org/wiki/Same_origin_policy">Same Origin Policy</a>).</p>
<p>основная функция данной защиты — предотвращение <a href="http://ru.wikipedia.org/wiki/%D0%9A%D0%BB%D0%B8%D0%BA%D0%B4%D0%B6%D0%B5%D0%BA%D0%B8%D0%BD%D0%B3">кликджекинга</a>; в качестве дополнительного бонуса это позволит предотвратить атаку, описанную <a href="http://spareclockcycles.org/2010/12/19/d0z-me-the-evil-url-shortener/">Ben Schmidt</a>.</p>
<p>Заголовок воспринимается Internet Explorer 8.0+, Firefox 3.6.9+ (Gecko 1.9.2.9+), Opera 10.50+, Safari 4.0+, Chrome 4.1.249.1042+.</p>
<p>Подробное описание приведено <a href="https://developer.mozilla.org/en/the_x-frame-options_response_header">здесь</a>.</p>
<p><strong>X-Content-Security-Policy</strong></p>
<p>Данный заголовок указывает, как контент на сайте взаимодействует с самим сайтом. При помощи данного заголовка можно указывать, откуда можно загружать картинки, <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a>, фреймы, шрифты, объекты, таблицы стилей, медиаконтент и многое другое.</p>
<p>Приведённый в примере выше заголовок разрешает загрузку контента только с того же домена, на котором располагается загружаемая страница. При этом браузеру запрещается выполнение встроенного JavaScript (скрипты внутри блоков <span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">script</span>&gt;</span>…<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">script</span>&gt;</span></code></span>, обработчики событий и т.п.), создание кода из строк (например, через функцию eval(), а также передача строк в функции <code>setTimeout()</code>, <code>setInterval()</code> и т.п.), использование протокола <code>data:</code>.</p>
<p>Данный заголовок можно использовать на HTTPS-страницах для запрета загрузки небезопасного контента:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p88420">
        <div class="code text" id="p884code20">
X-Content-Security-Policy: allow https://*:443
        </div>
    </div>
</div>

<p>Подробнее о заголовке и поддерживаемых параметрах можно прочитать <a href="https://wiki.mozilla.org/Security/CSP/Specification">здесь</a>.</p>
<p><strong>X-XSS-Protection</strong></p>
<p>Данный заголовок работает исключительно в Internet Explorer: он включает встроенную в браузер защиту от XSS-атак (по умолчанию она отключена, так как может некорректно работать с некоторыми сайтами). Подробная информация о принципах работы защиты от XSS-атак в IE приведена в <a href="http://blogs.msdn.com/b/ie/archive/2008/07/01/ie8-security-part-iv-the-xss-filter.aspx">The Windows Internet Explorer Weblog</a>.</p>
<p>В заключение стоит отметить, что хоть данный способ и хорош, он должен использоваться вкупе с другими средствами защиты и быть частью комплексной системы безопасности. Безопасность лишней не бывает!</p>
<p><a href="http://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/HTTP-Headers-to-Help-Secure-Your-Website/ba-p/8604">Оригинал статьи</a>.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/884-http-headers-to-secure-website/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/884-http-headers-to-secure-website/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Создание отражения рисунка с помощью JavaScript</title>
		<link>http://blog.sjinks.pro/javascript/356-image-reflection-with-javascript/</link>
		<comments>http://blog.sjinks.pro/javascript/356-image-reflection-with-javascript/#comments</comments>
		<pubDate>Sun, 16 Nov 2008 22:12:36 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[эффекты]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=356</guid>
		<description><![CDATA[HTML 5 приходит на помощь Постановка задачи: из исходного изображения получить отраженное изображение: Дополнительное условие: генерировать изображение на стороне клиента (то есть без использования GD, ImageMagick и иже с ними). В черновике стандарта HTML&#160;5 пристутствует такой замечательный элемент как &#60;canvas&#62;. Если вкратце, то данный элемент предназначен для создания изображений при помощи JavaScript. Впервые элемент &#60;canvas&#62; [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/356-image-reflection-with-javascript/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em><a href="http://blog.sjinks.pro/tag/html/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  HTML">HTML</a> 5 приходит на помощь</em></h2>
<p><strong>Постановка задачи:</strong> из исходного изображения </p>
<p><img src="http://static.sjinks.info/wp-content/uploads/2008/11/source.png" alt="Исходное изображение" title="Исходное изображение" width="363" height="240" class="alignnone size-full wp-image-357" /></p>
<p>получить отраженное изображение:</p>
<p><img src="http://static.sjinks.info/wp-content/uploads/2008/11/dest.png" alt="Исходное изображение с отражением" title="Исходное изображение с отражением" width="363" height="476" class="alignnone size-full wp-image-358" /></p>
<p><strong>Дополнительное условие:</strong> генерировать изображение на стороне клиента (то есть без использования GD, ImageMagick и иже с ними).<span id="more-356"></span></p>
<p>В черновике стандарта HTML&nbsp;5 пристутствует такой замечательный элемент как <span class="codebox"><code class="html"><span class="sc2">&lt;canvas&gt;</span></code></span>. Если вкратце, то данный элемент предназначен для создания  изображений при помощи <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a>.</p>
<p>Впервые элемент <span class="codebox"><code class="html"><span class="sc2">&lt;canvas&gt;</span></code></span> был представлен компанией Apple и использовался как компонент WebKit для Mac&nbsp;OS&nbsp;X в таких приложениях как Dashboard и Safari.</p>
<p>Поддержка <span class="codebox"><code class="html"><span class="sc2">&lt;canvas&gt;</span></code></span> в Gecko появилась в версии 1.5, в Presto с версии 9.0 веб-браузера Opera. Текущие версии Internet Explorer (включая восьмую бету) не поддерживают <span class="codebox"><code class="html"><span class="sc2">&lt;canvas&gt;</span></code></span>. Несмотря на это, для поставленной задачи существует кросс-браузерное решение.</p>
<p>В Microsoft Internet Explorer отражения с прозрачностью можно достичь путём использования комбинации фильтров. В частности, для вертикального отражения используется фильтр <code>flipv</code>, для горизонтального&nbsp;&mdash;&nbsp;<code>fliph</code>. Про реализацию прозрачности в Internet Explorer, наверное, знает каждый: <code>progid:DXImageTransform.Microsoft.Alpha</code>. Тем не менее, не все знают, что можно задавать градиентную прозрачность.</p>
<p>Перейдём к решению. Пусть у нас имеется такая <a href="http://blog.sjinks.pro/tag/markup/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  разметка">разметка</a>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p35624">
        <div class="code html" id="p356code24">
<span class="sc2">&lt;<span class="kw2">div</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;container&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">img</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;image&quot;</span> <span class="kw3">src</span><span class="sy0">=</span><span class="st0">&quot;image.png&quot;</span> <span class="kw3">alt</span><span class="sy0">=</span><span class="st0">&quot;Image&quot;</span><span class="sy0">/</span>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span>
        </div>
    </div>
</div>

<p>Будем полагать, что ширина и высота контейнера заданы (если мы делаем отражение по вертикали, то ширина контейнера совпадает с шириной рисунка, а высота контейнера в два раза больше высоты рисунка; аналогично для горизонтального отражения).</p>
<p>Начнём с классики (MSIE).</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p35625">
        <div class="code javascript" id="p356code25">
<span class="coMULTI">/**<br />
&nbsp;* @param container &lt;div id=&quot;container&quot;&gt;<br />
&nbsp;* @param image &lt;img id=&quot;image&quot;&gt;<br />
&nbsp;* @param ratio Коэффициент сжатия/растягивания отражения<br />
&nbsp;* @param opacity_start Начальная (ближняя к отражаемому изображению) непрозрачность <br />
&nbsp;* @param opacity_end Конечная непрозрачность<br />
&nbsp;* @param horizontal 0 = вертикальное отражение, 1 = горизонтальное отражение<br />
&nbsp;*/</span><br />
<span class="kw2">function</span> reflect_image<span class="br0">&#40;</span>container<span class="sy0">,</span> image<span class="sy0">,</span> ratio<span class="sy0">,</span> opacity_start<span class="sy0">,</span> opacity_end<span class="sy0">,</span> horizontal<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> reflection &nbsp;<span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'img'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; reflection.<span class="me1">src</span> <span class="sy0">=</span> image.<span class="me1">src</span><span class="sy0">;</span><br />
&nbsp; &nbsp; reflection.<span class="me1">style</span>.<span class="me1">width</span> <span class="sy0">=</span> image.<span class="me1">width</span> <span class="sy0">+</span> <span class="st0">'px'</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="nu0">0</span> <span class="sy0">==</span> horizontal<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; reflection.<span class="me1">style</span>.<span class="me1">filter</span> <span class="sy0">=</span> <span class="st0">'flipv progid:DXImageTransform.Microsoft.Alpha(opacity='</span><span class="sy0">+</span><span class="br0">&#40;</span>opacity_start<span class="sy0">*</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy0">+</span><span class="st0">', style=1, finishOpacity='</span><span class="sy0">+</span><span class="br0">&#40;</span>opacity_end<span class="sy0">*</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy0">+</span><span class="st0">', startx=0, starty=0, finishx=0, finishy='</span><span class="sy0">+</span><span class="br0">&#40;</span>ratio<span class="sy0">*</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy0">+</span><span class="st0">')'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; reflection.<span class="me1">style</span>.<span class="me1">filter</span> <span class="sy0">=</span> <span class="st0">'fliph progid:DXImageTransform.Microsoft.Alpha(opacity='</span><span class="sy0">+</span><span class="br0">&#40;</span>opacity_start<span class="sy0">*</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy0">+</span><span class="st0">', style=1, finishOpacity='</span><span class="sy0">+</span><span class="br0">&#40;</span>opacity_end<span class="sy0">*</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy0">+</span><span class="st0">', startx=0, starty=0, finishx='</span><span class="sy0">+</span><span class="br0">&#40;</span>ratio<span class="sy0">*</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy0">+</span><span class="st0">', finishy=0)'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; container.<span class="me1">appendChild</span><span class="br0">&#40;</span>reflection<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>В случае с IE всё просто и сводится к заданию соответствующих фильтров. С браузерами, поддерживающими HTML&nbsp;5, всё гораздо сложнее (ad deliberandum: сколько строк занимает программа на C++, если она использует COM-технологию?)</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p35626">
        <div class="code javascript" id="p356code26">
<span class="coMULTI">/**<br />
&nbsp;* @param container &lt;div id=&quot;container&quot;&gt;<br />
&nbsp;* @param image &lt;img id=&quot;image&quot;&gt;<br />
&nbsp;* @param ratio Коэффициент сжатия/растягивания отражения<br />
&nbsp;* @param opacity_start Начальная (ближняя к отражаемому изображению) непрозрачность <br />
&nbsp;* @param opacity_end Конечная непрозрачность<br />
&nbsp;* @param horizontal 0 = вертикальное отражение, 1 = горизонтальное отражение<br />
&nbsp;*/</span><br />
<span class="kw2">function</span> reflect_image<span class="br0">&#40;</span>container<span class="sy0">,</span> image<span class="sy0">,</span> ratio<span class="sy0">,</span> opacity_start<span class="sy0">,</span> opacity_end<span class="sy0">,</span> horizontal<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> reflection <span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'canvas'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> context &nbsp; <span class="sy0">=</span> reflection.<span class="me1">getContext</span><span class="br0">&#40;</span><span class="st0">'2d'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; reflection.<span class="me1">style</span>.<span class="me1">height</span> <span class="sy0">=</span> image.<span class="me1">height</span> <span class="sy0">+</span> <span class="st0">'px'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; reflection.<span class="me1">style</span>.<span class="me1">width</span> &nbsp;<span class="sy0">=</span> image.<span class="me1">width</span> <span class="sy0">+</span> <span class="st0">'px'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; reflection.<span class="me1">height</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=</span> image.<span class="me1">height</span><span class="sy0">;</span><br />
&nbsp; &nbsp; reflection.<span class="me1">width</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=</span> image.<span class="me1">width</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">//Подводный камень: на canvas нельзя рисовать, если она не в DOM-дереве документа</span><br />
&nbsp; &nbsp; container.<span class="me1">appendChild</span><span class="br0">&#40;</span>reflection<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; context.<span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> gradient<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="nu0">0</span> <span class="sy0">==</span> horizontal<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Задаём точку отсчёта, отражаем ось y и создаём вертикальный градиент</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; context.<span class="me1">translate</span><span class="br0">&#40;</span>0<span class="sy0">,</span> image.<span class="me1">height</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; context.<span class="me1">scale</span><span class="br0">&#40;</span>1<span class="sy0">,</span> <span class="sy0">-</span>1<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; gradient <span class="sy0">=</span> context.<span class="me1">createLinearGradient</span><span class="br0">&#40;</span>0<span class="sy0">,</span> 0<span class="sy0">,</span> 0<span class="sy0">,</span> image.<span class="me1">height</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Задаём точку отсчёта, отражаем ось x и создаём горизонтальный градиент</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; context.<span class="me1">translate</span><span class="br0">&#40;</span>image.<span class="me1">width</span><span class="sy0">,</span> 0<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; context.<span class="me1">scale</span><span class="br0">&#40;</span><span class="sy0">-</span>1<span class="sy0">,</span> 1<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; gradient <span class="sy0">=</span> context.<span class="me1">createLinearGradient</span><span class="br0">&#40;</span>0<span class="sy0">,</span> 0<span class="sy0">,</span> image.<span class="me1">width</span><span class="sy0">,</span> 0<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">// Рисуем исходное изображение (оно будет отражено по одной из осей)</span><br />
&nbsp; &nbsp; context.<span class="me1">drawImage</span><span class="br0">&#40;</span>image<span class="sy0">,</span> 0<span class="sy0">,</span> 0<span class="sy0">,</span> image.<span class="me1">width</span><span class="sy0">,</span> image.<span class="me1">height</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; context.<span class="me1">restore</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">// Задаём режим операции</span><br />
&nbsp; &nbsp; context.<span class="me1">globalCompositeOperation</span> <span class="sy0">=</span> <span class="st0">&quot;destination-out&quot;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">// Параметры градинтной заливки (в параметрах передаётся НЕпрозрачность, нам нужна прозрачность)</span><br />
&nbsp; &nbsp; gradient.<span class="me1">addColorStop</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="st0">&quot;rgba(255, 255, 255, &quot;</span> <span class="sy0">+</span> <span class="br0">&#40;</span><span class="nu0">1</span> <span class="sy0">-</span> opacity_end<span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">&quot;)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; gradient.<span class="me1">addColorStop</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="st0">&quot;rgba(255, 255, 255, &quot;</span> <span class="sy0">+</span> <span class="br0">&#40;</span><span class="nu0">1</span> <span class="sy0">-</span> opacity_start<span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">&quot;)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; context.<span class="me1">fillStyle</span> <span class="sy0">=</span> gradient<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">// Заливаем</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">-</span><span class="nu0">1</span> <span class="sy0">!=</span> navigator.<span class="me1">appVersion</span>.<span class="me1">indexOf</span><span class="br0">&#40;</span><span class="st0">'WebKit'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; context.<span class="me1">fill</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span> <br />
&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; context.<span class="me1">fillRect</span><span class="br0">&#40;</span>0<span class="sy0">,</span> 0<span class="sy0">,</span> image.<span class="me1">width</span><span class="sy0">,</span> image.<span class="me1">height</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p><strong><a href="http://blog.sjinks.pro/test/reflection/test.html" rel="nofollow">Тестовый пример</a>.</strong></p>
<p><strong><a href="https://developer.mozilla.org/En/Canvas_tutorial" rel="nofollow">Canvas Tutorial в Mozilla Developer Center</a></strong></p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/356-image-reflection-with-javascript/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/javascript/356-image-reflection-with-javascript/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Основные источники неправильной разметки в WordPress</title>
		<link>http://blog.sjinks.pro/wordpress/222-main-sources-of-invalid-markup-in-wordpress/</link>
		<comments>http://blog.sjinks.pro/wordpress/222-main-sources-of-invalid-markup-in-wordpress/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 02:50:08 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Flash Satay]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[noindex]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[wpautop]]></category>
		<category><![CDATA[XHTML]]></category>
		<category><![CDATA[ошибка]]></category>
		<category><![CDATA[патч]]></category>
		<category><![CDATA[разметка]]></category>
		<category><![CDATA[Яндекс]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=222</guid>
		<description><![CDATA[Исправляем неправильную разметку в WordPress В статье "Избавляемся о ошибок xHTML-валидации при использовании JavaScript, Flash, &#60;noindex&#62;, CSS" рассказывается о четырёх основных источниках неправильной разметки в WordPress: JavaScript; Глобальные CSS, размещаемые в заголовке документа; Flash; Несуществующий по стандартам тег &#60;noindex&#62;, придуманный Яндексом Естественно, после прочтения статьи я решил проверить свой, как я полагал, валидный, блог. В [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/222-main-sources-of-invalid-markup-in-wordpress/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Исправляем неправильную разметку в <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a></em></h2>
<p>В статье "<a href="http://dimox.name/xhtml-validation-using-javascript-flash-noindex/">Избавляемся о ошибок xHTML-валидации при использовании JavaScript, Flash, &lt;noindex&gt;, CSS</a>" рассказывается о четырёх основных источниках неправильной разметки в WordPress:</p>
<blockquote cite="http://dimox.name/xhtml-validation-using-javascript-flash-noindex/">
<ol>
<li><a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a>;</li>
<li>Глобальные CSS, размещаемые в заголовке документа;</li>
<li>Flash;</li>
<li>Несуществующий по стандартам тег &lt;<a href="http://blog.sjinks.pro/tag/noindex/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  noindex">noindex</a>&gt;, придуманный Яндексом</li>
</ol>
</blockquote>
<p>Естественно, после прочтения статьи я решил проверить свой, как я полагал, валидный, блог. В том-то и дело, что только плагал: нашёлся пятый источник неправильной разметки. Где бы Вы думали? В самом WordPress, в функции <code>wpautop()</code>.<span id="more-222"></span></p>
<p>Сначала всё же пройдусь по первым четырём источникам. А точнее, трём&nbsp;&mdash;&nbsp;проблему с Яндексом я для себя давно уже решил, а именно: несуществующими тэгами я не балуюсь. И не могу не удержаться от камня в огород <a href="http://blog.sjinks.pro/tag/yandex/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Яндекс">Яндекс</a>: ну зачем нужно было придумывать абсолютно левый тэг, когда можно было использовать, например, комментарий:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22251">
        <div class="code html" id="p222code51">
<span class="sc-2">&lt;!-- NOINDEX --&gt;</span><br />
Content not to be indexed<br />
<span class="sc-2">&lt;!-- /NOINDEX --&gt;</span>
        </div>
    </div>
</div>

<p>Во-первых, это решает проблему невалидного (X)<a href="http://blog.sjinks.pro/tag/html/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  HTML">HTML</a>. Во-вторых, не надо было бы заботиться о том, где можно и где нельзя размещать тэг&nbsp;&mdash;&nbsp;вырезал регэкспом такой вот комментарий от начала и до конца и получил контент, который можно индексировать. Эх&hellip; Ладно, забыли.</p>
<p>Теперь по списку.<br />
<strong>JavaScript</strong>. Решение простое: весь JavaScript заключаем в секцию <code>CDATA</code>. Например, так:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22252">
        <div class="code html" id="p222code52">
<span class="sc2">&lt;<span class="kw2">script</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span>&gt;</span><br />
<span class="sc-2">&lt;!--//--&gt;</span><span class="sc2">&lt;!<span class="br0">&#91;</span>CDATA<span class="br0">&#91;</span><span class="sy0">//</span>&gt;</span><span class="sc-2">&lt;!--</span><br />
<span class="sc-2">//JavaScript goes here...</span><br />
<span class="sc-2">//--&gt;</span><span class="sc2">&lt;!<span class="br0">&#93;</span><span class="br0">&#93;</span>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">script</span>&gt;</span>
        </div>
    </div>
</div>

<p>И не забываем, что атрибут <code>type</code>&nbsp;&mdash;&nbsp;обязательный. Решение выше, что называется, для любителей поизвращаться: помимо всего прочего, оно прячет JavaScript от антикварных браузеров, которые вообще не понимают тэг <code>script</code>. Если поддержка таких браузеров не нужна, то код можно значительно упростить:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22253">
        <div class="code html" id="p222code53">
<span class="sc2">&lt;<span class="kw2">script</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span>&gt;</span>/*<span class="sc2">&lt;!<span class="br0">&#91;</span>CDATA<span class="br0">&#91;</span>*<span class="sy0">/</span></span><br />
<span class="sc2"><span class="sy0">//</span>JavaScript goes here...</span><br />
<span class="sc2"><span class="sy0">/</span>*<span class="br0">&#93;</span><span class="br0">&#93;</span>&gt;</span>*/<br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">script</span>&gt;</span>
        </div>
    </div>
</div>

<p>А вот такое решение я не рекомендую:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22254">
        <div class="code html" id="p222code54">
<span class="sc2">&lt;<span class="kw2">script</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span>&gt;</span><span class="sc-2">&lt;!-- //&lt;![CDATA[</span><br />
<span class="sc-2">//JavaScript goes here...</span><br />
<span class="sc-2">//--&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">script</span>&gt;</span>
        </div>
    </div>
</div>

<p>Причина простая: если мы планируем отдавать <a href="http://blog.sjinks.pro/tag/xhtml/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XHTML">XHTML</a> так, как это требует W3C (с MIME-типом application/<a href="http://blog.sjinks.pro/tag/xhtml/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XHTML">xhtml</a>+xml), то любой <em>нормальный</em> браузер воспримет HTML-комментарий как элемент, вложенный в <code>script</code>, и, как следствие, проигнорирует скрипт полностью (в XHTML парсер не знает о том, что существуют скрипты, таблицы стилей и прочие вещи).</p>
<p><strong>С CSS всё аналогично.</strong> Метод для любителей поизвращаться:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22255">
        <div class="code html" id="p222code55">
<span class="sc2">&lt;<span class="kw2">style</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/css&quot;</span>&gt;</span><br />
<span class="sc-2">&lt;!--/*--&gt;</span><span class="sc2">&lt;!<span class="br0">&#91;</span>CDATA<span class="br0">&#91;</span><span class="sy0">/</span>*&gt;</span><span class="sc-2">&lt;!--*/</span><br />
<span class="sc-2">/* CSS goes here*/</span><br />
<span class="sc-2">/*]]&gt;*/--&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">style</span>&gt;</span>
        </div>
    </div>
</div>

<p>И более простой метод:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22256">
        <div class="code html" id="p222code56">
<span class="sc2">&lt;<span class="kw2">style</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/css&quot;</span>&gt;</span><br />
/*<span class="sc2">&lt;!<span class="br0">&#91;</span>CDATA<span class="br0">&#91;</span>*<span class="sy0">/</span></span><br />
<span class="sc2"><span class="sy0">/</span>* CSS goes here*<span class="sy0">/</span></span><br />
<span class="sc2"><span class="sy0">/</span>*<span class="br0">&#93;</span><span class="br0">&#93;</span>&gt;</span>*/<br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">style</span>&gt;</span>
        </div>
    </div>
</div>

<p>Да, у тэга <code>style</code> атрибут <code>type</code> тоже является обязательным.<br />
Все браузеры, появившиеся после 2000&nbsp;года понимают форму "без извращений", поэтому, наверное, имеет смысл использовать именно её. И еще небольшое замечание по поводу <code>CDATA</code>. По большому счету, секция <code>CDATA</code> нужна только тогда, когда контент содержит символы, которые могут быть интерпретированы как <a href="http://blog.sjinks.pro/tag/markup/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  разметка">разметка</a> XML, а именно: &lt; и &amp;. То есть в большинстве случаев, стили внутри тэга <code>style</code> помещать в <code>CDATA</code> особо не нужно.</p>
<p><strong>Третий пункт&nbsp;&mdash;&nbsp;Flash.</strong> Здесь поможет <strong><a href="http://www.alistapart.com/articles/flashsatay" rel="nofollow">Flash Satay</a></strong>. На нём подробно останавливаться не буду, лишь замечу, что правильный способ записи такого монстра:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22257">
        <div class="code html" id="p222code57">
<span class="sc2">&lt;<span class="kw2">object</span> <span class="kw3">classid</span><span class="sy0">=</span><span class="st0">&quot;clsid:D27CDB6E-AE6D-11cf-96B8-444553540000&quot;</span> <span class="kw3">codebase</span><span class="sy0">=</span><span class="st0">&quot;http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0&quot;</span> <span class="kw3">width</span><span class="sy0">=</span><span class="st0">&quot;400&quot;</span> <span class="kw3">height</span><span class="sy0">=</span><span class="st0">&quot;300&quot;</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;movie&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">param</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;movie&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;movie.swf&quot;</span><span class="sy0">/</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;embed <span class="kw3">src</span><span class="sy0">=</span><span class="st0">&quot;movie.swf&quot;</span> quality<span class="sy0">=</span><span class="st0">&quot;high&quot;</span> <span class="kw3">width</span><span class="sy0">=</span><span class="st0">&quot;400&quot;</span> <span class="kw3">height</span><span class="sy0">=</span><span class="st0">&quot;300&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;movie&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;application/x-shockwave-flash&quot;</span> pluginspage<span class="sy0">=</span><span class="st0">&quot;http://www.macromedia.com/go/getflashplayer&quot;</span><span class="sy0">/</span>&gt;</span> <br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">object</span>&gt;</span>
        </div>
    </div>
</div>

<p>выглядит так:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22258">
        <div class="code html" id="p222code58">
<span class="sc2">&lt;<span class="kw2">object</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;application/x-shockwave-flash&quot;</span> <span class="kw3">width</span><span class="sy0">=</span><span class="st0">&quot;400&quot;</span> <span class="kw3">height</span><span class="sy0">=</span><span class="st0">&quot;300&quot;</span> <span class="kw3">data</span><span class="sy0">=</span><span class="st0">&quot;movie.swf&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">param</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;movie&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;movie.swf&quot;</span><span class="sy0">/</span>&gt;</span> <br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">object</span>&gt;</span>
        </div>
    </div>
</div>

<p>Достоинства и недостатки метода подробно описаны в оригинале, нет смысла на них останавливаться здесь.</p>
<p>По <strong>четвёртому вопросу</strong> я уже высказывался. У Дмитрия в статье есть решение, но лично для себя я его не считаю приемлемым.</p>
<p>Переходим к <strong>пятому пункту</strong>, ради которого, собственно говоря, данная статья и писалась <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Как я уже сказал, во многих случаях в неправильной разметке виноват WordPress. Конкретно&nbsp;&mdash;&nbsp;функция <code>wpautop()</code>. Я всегда считал, что глобально менять разметку HTML, использую регулярные выражения&nbsp;&mdash;&nbsp;глупо, ибо в <em>общем случае</em> это работать не будет.</p>
<p>Допустим, Вы привыкли использовать <a href="http://pokrovskii.com/strukturiruem-html-versiya-pokrovskogo/" rel="nofollow">хорошо структурированый код</a>. Тогда вполне вероятно, что Вы можете написать нечто подобное (в целях упрощения восприятия я сократил код):</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22259">
        <div class="code html" id="p222code59">
<span class="sc2">&lt;<span class="kw2">div</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">strong</span>&gt;</span>Test<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">strong</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">div</span>&gt;</span>Lorem ipsum dolor sit amet, иными словами, вложенный div.<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span>
        </div>
    </div>
</div>

<p>Дальнейшие рассуждения исходят из предположения, что Вы не пользуетесь <abbr title="What You See Is What You Get">WYSIWYG</abbr>-редактором. Например, из-за того, что приходится вставлять разметку, которую TinyMCE никак не переваривает (исправляет её под себя), я им вообще не пользуюсь, предпочитая обыкновенный HTML-редактор без наворотов.</p>
<p>В этом случае функция <code>wpautop()</code> преобразует его следующим образом:</p>
<ol>
<li><strong>Добавление символов перевода строки:</strong>
          
<div class="codebox">
    <div class="the_code" style="" id="p22260">
        <div class="code html" id="p222code60">
<span class="sc2">&lt;<span class="kw2">div</span>&gt;&lt;<span class="kw2">strong</span>&gt;</span>Test<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">strong</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span class="sc2">&lt;<span class="kw2">div</span>&gt;</span>Lorem ipsum dolor sit amet, иными словами, вложенный div.<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span><br />
<br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span>
        </div>
    </div>
</div>

</li>
<li><strong>Добавление параграфов куда можно и куда нельзя:</strong>
          
<div class="codebox">
    <div class="the_code" style="" id="p22261">
        <div class="code html" id="p222code61">
<span class="sc2">&lt;<span class="kw2">p</span>&gt;&lt;<span class="kw2">div</span>&gt;&lt;<span class="kw2">strong</span>&gt;</span>Test<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">strong</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
<span class="sc2">&lt;<span class="kw2">p</span>&gt;&lt;<span class="kw2">div</span>&gt;</span>Lorem ipsum dolor sit amet, иными словами, вложенный div.<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
<span class="sc2">&lt;<span class="kw2">p</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span>
        </div>
    </div>
</div>

</li>
<li><strong>Финальная очистка:</strong>
          
<div class="codebox">
    <div class="the_code" style="" id="p22262">
        <div class="code html" id="p222code62">
<span class="sc2">&lt;<span class="kw2">div</span>&gt;&lt;<span class="kw2">strong</span>&gt;</span>Test<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">strong</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
<span class="sc2">&lt;<span class="kw2">div</span>&gt;</span>Lorem ipsum dolor sit amet, иными словами, вложенный div.<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span>
        </div>
    </div>
</div>

</li>
</ol>
<p>Как видим, остается лишний закрывающий тэг <code>p</code>. Кстати, если написать так (строчный и блочный элементы на одной строке):</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22263">
        <div class="code html" id="p222code63">
<span class="sc2">&lt;<span class="kw2">div</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">strong</span>&gt;</span>Test<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">strong</span>&gt;&lt;<span class="kw2">div</span>&gt;</span>Lorem ipsum dolor sit amet, иными словами, вложенный div.<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span><br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span>
        </div>
    </div>
</div>

<p>то разметка будет нормальной.</p>
<p>В общем случае, <a href="http://blog.sjinks.pro/tag/bug/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  ошибка">ошибка</a> вылезает при такой разметке:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22264">
        <div class="code xml" id="p222code64">
<span class="sc3"><span class="re1">&lt;blocktag<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;inlinetag<span class="re2">&gt;</span></span><span class="re1">&lt;/inlinetag<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;blocktag<span class="re2">&gt;</span></span><span class="re1">&lt;/blocktag<span class="re2">&gt;</span></span></span><br />
<span class="sc3"><span class="re1">&lt;/blocktag<span class="re2">&gt;</span></span></span>
        </div>
    </div>
</div>

<p>Править все статьи&nbsp;&mdash;&nbsp;абсолютно не метод русского программиста <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Проще автоматизировать.<br />
Открываем файл <code>wp-includes/formatting.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">php</a></code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22265">
        <div class="code php" id="p222code65">
<ol class="php" style="font-family:monospace;" start="62"><li class="li1"><div class="de1"><span class="kw2">function</span> wpautop<span class="br0">&#40;</span><span class="re0">$pee</span><span class="sy0">,</span> <span class="re0">$br</span> <span class="sy0">=</span> 1<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="re0">$pee</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">;</span> <span class="co1">// just to make things a little easier, pad the end</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'|&lt;br /&gt;\s*&lt;br /&gt;|'</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span><span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// Space things out a little</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$allblocks</span> <span class="sy0">=</span> <span class="st_h">'(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)'</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!(&lt;'</span> <span class="sy0">.</span> <span class="re0">$allblocks</span> <span class="sy0">.</span> <span class="st_h">'[^&gt;]*&gt;)!'</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span><span class="es4">$1</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!(&lt;/'</span> <span class="sy0">.</span> <span class="re0">$allblocks</span> <span class="sy0">.</span> <span class="st_h">'&gt;)!'</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es4">$1</span><span class="es1">\n</span><span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="kw1">array</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es1">\r</span><span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\r</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// cross-platform newlines</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="kw3">strpos</span><span class="br0">&#40;</span><span class="re0">$pee</span><span class="sy0">,</span> <span class="st_h">'&lt;object'</span><span class="br0">&#41;</span> <span class="sy0">!==</span> <span class="kw4">false</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'|\s*&lt;param([^&gt;]*)&gt;\s*|'</span><span class="sy0">,</span> <span class="st0">&quot;&lt;param<span class="es4">$1</span>&gt;&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// no pee inside object/embed</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'|\s*&lt;/embed&gt;\s*|'</span><span class="sy0">,</span> <span class="st_h">'&lt;/embed&gt;'</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st0">&quot;/<span class="es1">\n</span><span class="es1">\n</span>+/&quot;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span><span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// take care of duplicates</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'/\n?(.+?)(?:\n\s*\n|\z)/s'</span><span class="sy0">,</span> <span class="st0">&quot;&lt;p&gt;<span class="es4">$1</span>&lt;/p&gt;<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// make paragraphs, including one at the end</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'|&lt;p&gt;\s*?&lt;/p&gt;|'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// under certain strange conditions it could create a P of entirely whitespace</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!&lt;p&gt;([^&lt;]+)\s*?(&lt;/(?:div|address|form)[^&gt;]*&gt;)!'</span><span class="sy0">,</span> <span class="st0">&quot;&lt;p&gt;<span class="es4">$1</span>&lt;/p&gt;<span class="es4">$2</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span> <span class="st_h">'|&lt;p&gt;|'</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es4">$1</span>&lt;p&gt;&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span> <span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!&lt;p&gt;\s*(&lt;/?'</span> <span class="sy0">.</span> <span class="re0">$allblocks</span> <span class="sy0">.</span> <span class="st_h">'[^&gt;]*&gt;)\s*&lt;/p&gt;!'</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es4">$1</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// don't pee all over a tag</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st0">&quot;|&lt;p&gt;(&lt;li.+?)&lt;/p&gt;|&quot;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es4">$1</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// problem with nested lists</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'|&lt;p&gt;&lt;blockquote([^&gt;]*)&gt;|i'</span><span class="sy0">,</span> <span class="st0">&quot;&lt;blockquote<span class="es4">$1</span>&gt;&lt;p&gt;&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="st_h">'&lt;/blockquote&gt;&lt;/p&gt;'</span><span class="sy0">,</span> <span class="st_h">'&lt;/p&gt;&lt;/blockquote&gt;'</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!&lt;p&gt;\s*(&lt;/?'</span> <span class="sy0">.</span> <span class="re0">$allblocks</span> <span class="sy0">.</span> <span class="st_h">'[^&gt;]*&gt;)!'</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es4">$1</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!(&lt;/?'</span> <span class="sy0">.</span> <span class="re0">$allblocks</span> <span class="sy0">.</span> <span class="st_h">'[^&gt;]*&gt;)\s*&lt;/p&gt;!'</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es4">$1</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$br</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace_callback</span><span class="br0">&#40;</span><span class="st_h">'/&lt;(script|style).*?&lt;\/\\1&gt;/s'</span><span class="sy0">,</span> <span class="kw3">create_function</span><span class="br0">&#40;</span><span class="st_h">'$matches'</span><span class="sy0">,</span> <span class="st_h">'return str_replace(&quot;\n&quot;, &quot;&lt;WPPreserveNewline /&gt;&quot;, $matches[0]);'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'|(?&lt;!&lt;br /&gt;)\s*\n|'</span><span class="sy0">,</span> <span class="st0">&quot;&lt;br /&gt;<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// optionally make line breaks</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="st_h">'&lt;WPPreserveNewline /&gt;'</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!(&lt;/?'</span> <span class="sy0">.</span> <span class="re0">$allblocks</span> <span class="sy0">.</span> <span class="st_h">'[^&gt;]*&gt;)\s*&lt;br /&gt;!'</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es4">$1</span>&quot;</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'!&lt;br /&gt;(\s*&lt;/?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^&gt;]*&gt;)!'</span><span class="sy0">,</span> <span class="st_h">'$1'</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">strpos</span><span class="br0">&#40;</span><span class="re0">$pee</span><span class="sy0">,</span> <span class="st_h">'&lt;pre'</span><span class="br0">&#41;</span> <span class="sy0">!==</span> <span class="kw4">false</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace_callback</span><span class="br0">&#40;</span><span class="st_h">'!(&lt;pre.*?&gt;)(.*?)&lt;\/pre&gt;!is'</span><span class="sy0">,</span> <span class="st_h">'clean_pre'</span><span class="sy0">,</span> <span class="re0">$pee</span> <span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span> <span class="st0">&quot;|<span class="es1">\n</span>&lt;/p&gt;$|&quot;</span><span class="sy0">,</span> <span class="st_h">'&lt;/p&gt;'</span><span class="sy0">,</span> <span class="re0">$pee</span> <span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'/&lt;p&gt;\s*?('</span> <span class="sy0">.</span> get_shortcode_regex<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">')\s*&lt;\/p&gt;/s'</span><span class="sy0">,</span> <span class="st_h">'$1'</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// don't auto-p wrap shortcodes that stand alone</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$pee</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li>
</ol>
        </div>
    </div>
</div>

<p>После строки 77 вставляем:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22266">
        <div class="code php" id="p222code66">
<ol class="php" style="font-family:monospace;" start="78"><li class="li1"><div class="de1">&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st0">&quot;/&lt;p&gt;<span class="es1">\\</span>s*(&lt;<span class="es4">{$allblocks}</span>.*?)&lt;<span class="es1">\\</span>/p&gt;/ism&quot;</span><span class="sy0">,</span> <span class="st_h">'$1'</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
</ol>
        </div>
    </div>
</div>

<p>Эта строка кода убирает параграф вокруг открывающего тэга блочного элемента. Такой простой вот трюк (я на него убил минут 30 отладки) решает проблему с форматированием.</p>
<p>Но, как оказалось, это еще не всё. Второй случай более редкий:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22267">
        <div class="code html" id="p222code67">
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;</span>text<br />
<span class="sc2">&lt;<span class="kw2">div</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span><br />
<br />
text<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span>
        </div>
    </div>
</div>

<p>Что характерно, перед открывающим &lt;li&gt; должен стоять по крайней мере пробел (редактор WordPress его добавляет, так что условие вполне выполнимое).<br />
Так выглядит результат работы неизменённого <code>wpautop()</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22268">
        <div class="code html" id="p222code68">
<span class="sc2">&lt;<span class="kw2">li</span>&gt;</span>text<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span><br />
<span class="sc2">&lt;<span class="kw2">div</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span><br />
<span class="sc2">&lt;<span class="kw2">p</span>&gt;</span>text<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span>
        </div>
    </div>
</div>

<p>А так&nbsp;&mdash;&nbsp;исправленного:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22269">
        <div class="code html" id="p222code69">
<span class="sc2">&lt;<span class="kw2">li</span>&gt;</span>text<br />
<span class="sc2">&lt;<span class="kw2">div</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span><br />
<span class="sc2">&lt;<span class="kw2">p</span>&gt;</span>text<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span>
        </div>
    </div>
</div>

<p>В исправленном варианте на одну ошибку меньше <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Но всё равно нужно исправлять.</p>
<p>Здесь лечение более сложное: во-первых, нужно добавить одну функцию:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22270">
        <div class="code php" id="p222code70">
<span class="kw2">function</span> wpautop_replace_callback<span class="br0">&#40;</span><span class="re0">$matches</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="st_h">'&lt;/p&gt;'</span> <span class="sy0">==</span> <span class="re0">$matches</span><span class="br0">&#91;</span>2<span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st_h">'&lt;p&gt;'</span> <span class="sy0">.</span> <span class="re0">$matches</span><span class="br0">&#91;</span>1<span class="br0">&#93;</span> <span class="sy0">.</span> <span class="re0">$matches</span><span class="br0">&#91;</span>2<span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$matches</span><span class="br0">&#91;</span>1<span class="br0">&#93;</span> <span class="sy0">.</span> <span class="re0">$matches</span><span class="br0">&#91;</span>2<span class="br0">&#93;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>и в функцию <code>wpautop()</code> под строку</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22271">
        <div class="code php" id="p222code71">
&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="st_h">'&lt;/blockquote&gt;&lt;/p&gt;'</span><span class="sy0">,</span> <span class="st_h">'&lt;/p&gt;&lt;/blockquote&gt;'</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>добавить</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22272">
        <div class="code php" id="p222code72">
&nbsp; &nbsp; <span class="re0">$pee</span> <span class="sy0">=</span> <span class="kw3">preg_replace_callback</span><span class="br0">&#40;</span><span class="st0">&quot;/&lt;p&gt;(.*?)(&lt;<span class="es1">\\</span>/<span class="es4">{$allblocks}</span>&gt;)/s&quot;</span><span class="sy0">,</span> <span class="st_h">'wpautop_replace_callback'</span><span class="sy0">,</span> <span class="re0">$pee</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>После этого вроде всё хорошо. За исключением элементов <code>&lt;ins&gt;</code> и <code>&lt;del&gt;</code>. Так как они могут иметь как блочный, так и строчный контекст, решение я пока не придумал. Единственное, что я могу посоветовать: если нужен <code>&lt;ins&gt;</code> или <code>&lt;del&gt;</code> в блочном котексте, его нудно поместить в <code>&lt;div&gt;</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22273">
        <div class="code html" id="p222code73">
<span class="sc2">&lt;<span class="kw2">div</span>&gt;&lt;<span class="kw2">ins</span>&gt;</span><br />
whatever<br />
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">ins</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span>
        </div>
    </div>
</div>

<p>По традиции, <a href="http://blog.sjinks.pro/tag/patch/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  патч">патч</a> в формате unified diff, который исправляет проблему:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p22274">
        <div class="code diff" id="p222code74">
--- formatting.php.original 2008-04-25 03:46:17.000000000 +0300<br />
<span class="re4">+++ formatting.php &nbsp;<span class="nu0">2008</span>-07-07 05:<span class="nu0">44</span>:<span class="nu0">52.000000000</span> +0300</span><br />
<span class="re6">@@ -<span class="nu0">59</span>,<span class="nu0">6</span> +<span class="nu0">59</span>,<span class="nu0">15</span> @@</span><br />
&nbsp; &nbsp; return $text;<br />
&nbsp;<span class="br0">&#125;</span><br />
<br />
<span class="re8">+function wpautop_replace_callback<span class="br0">&#40;</span>$matches<span class="br0">&#41;</span></span><br />
<span class="re8">+<span class="br0">&#123;</span></span><br />
<span class="re8">+ &nbsp; &nbsp;if <span class="br0">&#40;</span>'&lt;/p&gt;' == $matches<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp; return '&lt;p&gt;' . $matches<span class="br0">&#91;</span>1<span class="br0">&#93;</span> . $matches<span class="br0">&#91;</span>2<span class="br0">&#93;</span>;</span><br />
<span class="re8">+ &nbsp; <span class="br0">&#125;</span></span><br />
<span class="re8">+</span><br />
<span class="re8">+ &nbsp; return $matches<span class="br0">&#91;</span>1<span class="br0">&#93;</span> . $matches<span class="br0">&#91;</span>2<span class="br0">&#93;</span>;</span><br />
<span class="re8">+<span class="br0">&#125;</span></span><br />
<span class="re8">+</span><br />
&nbsp;function wpautop<span class="br0">&#40;</span>$pee, $br = 1<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; $pee = $pee . &quot;\n&quot;; // just to make things a little easier, pad the end<br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span>'|&lt;br /&gt;\s*&lt;br /&gt;|', &quot;\n\n&quot;, $pee<span class="br0">&#41;</span>;<br />
<span class="re6">@@ -<span class="nu0">75</span>,<span class="nu0">11</span> +<span class="nu0">84</span>,<span class="nu0">13</span> @@</span><br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span>'/\n?<span class="br0">&#40;</span>.+?<span class="br0">&#41;</span><span class="br0">&#40;</span>?:\n\s*\n|\z<span class="br0">&#41;</span>/s', &quot;&lt;p&gt;$1&lt;/p&gt;\n&quot;, $pee<span class="br0">&#41;</span>; // make paragraphs, including one at the end<br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span>'|&lt;p&gt;\s*?&lt;/p&gt;|', '', $pee<span class="br0">&#41;</span>; // under certain strange conditions it could create a P of entirely whitespace<br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span>'!&lt;p&gt;<span class="br0">&#40;</span><span class="br0">&#91;</span>^&lt;<span class="br0">&#93;</span>+<span class="br0">&#41;</span>\s*?<span class="br0">&#40;</span>&lt;/<span class="br0">&#40;</span>?:div|address|form<span class="br0">&#41;</span><span class="br0">&#91;</span>^&gt;<span class="br0">&#93;</span>*&gt;<span class="br0">&#41;</span>!', &quot;&lt;p&gt;$1&lt;/p&gt;$2&quot;, $pee<span class="br0">&#41;</span>;<br />
<span class="re8">+ &nbsp; $pee = preg_replace<span class="br0">&#40;</span>&quot;/&lt;p&gt;\\s*<span class="br0">&#40;</span>&lt;<span class="br0">&#123;</span>$allblocks<span class="br0">&#125;</span>.*?<span class="br0">&#41;</span>&lt;\\/p&gt;/ism&quot;, '$1', $pee<span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span> '|&lt;p&gt;|', &quot;$1&lt;p&gt;&quot;, $pee <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span>'!&lt;p&gt;\s*<span class="br0">&#40;</span>&lt;/?' . $allblocks . '<span class="br0">&#91;</span>^&gt;<span class="br0">&#93;</span>*&gt;<span class="br0">&#41;</span>\s*&lt;/p&gt;!', &quot;$1&quot;, $pee<span class="br0">&#41;</span>; // don't pee all over a tag<br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span>&quot;|&lt;p&gt;<span class="br0">&#40;</span>&lt;li.+?<span class="br0">&#41;</span>&lt;/p&gt;|&quot;, &quot;$1&quot;, $pee<span class="br0">&#41;</span>; // problem with nested lists<br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span>'|&lt;p&gt;&lt;blockquote<span class="br0">&#40;</span><span class="br0">&#91;</span>^&gt;<span class="br0">&#93;</span>*<span class="br0">&#41;</span>&gt;|i', &quot;&lt;blockquote$1&gt;&lt;p&gt;&quot;, $pee<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; $pee = str_replace<span class="br0">&#40;</span>'&lt;/blockquote&gt;&lt;/p&gt;', '&lt;/p&gt;&lt;/blockquote&gt;', $pee<span class="br0">&#41;</span>;<br />
<span class="re8">+ &nbsp; $pee = preg_replace_callback<span class="br0">&#40;</span>&quot;/&lt;p&gt;<span class="br0">&#40;</span>.*?<span class="br0">&#41;</span><span class="br0">&#40;</span>&lt;\\/<span class="br0">&#123;</span>$allblocks<span class="br0">&#125;</span>&gt;<span class="br0">&#41;</span>/s&quot;, 'wpautop_replace_callback', $pee<span class="br0">&#41;</span>;</span><br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span>'!&lt;p&gt;\s*<span class="br0">&#40;</span>&lt;/?' . $allblocks . '<span class="br0">&#91;</span>^&gt;<span class="br0">&#93;</span>*&gt;<span class="br0">&#41;</span>!', &quot;$1&quot;, $pee<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; $pee = preg_replace<span class="br0">&#40;</span>'!<span class="br0">&#40;</span>&lt;/?' . $allblocks . '<span class="br0">&#91;</span>^&gt;<span class="br0">&#93;</span>*&gt;<span class="br0">&#41;</span>\s*&lt;/p&gt;!', &quot;$1&quot;, $pee<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; if <span class="br0">&#40;</span>$br<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        </div>
    </div>
</div>

<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/222-main-sources-of-invalid-markup-in-wordpress/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/222-main-sources-of-invalid-markup-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Убиваем рекламу на bash.org.ru, или, Greasemonkey в действии</title>
		<link>http://blog.sjinks.pro/javascript/217-killing-ads-on-bashorgru-greasemonkey-in-action/</link>
		<comments>http://blog.sjinks.pro/javascript/217-killing-ads-on-bashorgru-greasemonkey-in-action/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 00:41:00 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[bash.org.ru]]></category>
		<category><![CDATA[Greasemonkey]]></category>
		<category><![CDATA[XPath]]></category>
		<category><![CDATA[реклама]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=217</guid>
		<description><![CDATA[Убираем тупую рекламу с bash.org.ru при помощи GreaseMonkey Многие (если не все) знакомы с ресурсом bash.org.ru. И, хотя юмор там в последнее время очень тупой, старые шутки почитать временами можно. Помимо тупого юмора лично меня на bash.org.ru больше всего раздражает не менее тупая реклама И если со всякими iframe и иже с ним AdBlock может [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/217-killing-ads-on-bashorgru-greasemonkey-in-action/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Убираем тупую рекламу с <a href="http://blog.sjinks.pro/tag/bashorgru/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  bash.org.ru">bash.org.ru</a> при помощи <a href="http://blog.sjinks.pro/tag/greasemonkey/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Greasemonkey">GreaseMonkey</a></em></h2>
<p>Многие (если не все) знакомы с ресурсом bash.org.ru. И, хотя юмор там в последнее время очень тупой, старые шутки почитать временами можно. Помимо тупого юмора лично меня на bash.org.ru больше всего раздражает не менее тупая <a href="http://blog.sjinks.pro/tag/ads/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  реклама">реклама</a> <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  И если со всякими <code>iframe</code> и иже с ним AdBlock может бороться, то со вставками вида</p>
<blockquote>
Дэвид Блэйн раскукожил Firefox! Теперь в нём <a href="http://blog.sjinks.pro/tag/yandex/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Яндекс">Яндекс</a>!<br />
</blockquote>
<p>он уже не справляется (так как они вставляются в вывод на сервере). Достал меня Дэвид Блейн. И Яндекс меня достал. И еще много что меня достало. Наверное, надо отдохнуть. Но речь не об этом. В общем, если меня что-то раздражает, я от этого избавляюсь (если читать, то с комфортом). Задачка как раз для Greasemonkey.<span id="more-217"></span></p>
<p>Ранее я уже приводил <a href="http://blog.sjinks.pro/javascript/78-script-for-greasemonkey-to-extract-asin-from-amazon/">пример пользовательского скрипта для извлечения ASIN с amazon.com</a>. Здесь используется нечто похожее.</p>
<p>Идея состоит в том, что для нормальных цитат после <span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">hr</span> <span class="kw3">class</span><span class="sy0">=</span><span class="st0">&quot;iq&quot;</span>&gt;</span></code></span> сразу идет <span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">script</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span> <span class="kw3">language</span><span class="sy0">=</span><span class="st0">&quot;JavaScript&quot;</span>&gt;</span></code></span> и только потом <span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">div</span> <span class="kw3">class</span><span class="sy0">=</span><span class="st0">&quot;q&quot;</span>&gt;</span></code></span>, а в случае с рекламой <span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">script</span>&gt;</span></code></span> отсутствует; всё показано на рисунке:<br />
<a href='http://static.sjinks.info/wp-content/uploads/2008/07/bashorgru.png' rel="lightbox"><img src="http://static.sjinks.info/wp-content/uploads/2008/07/bashorgru-300x240.png" alt="XML-дерево" title="XML-дерево" class="alignnone size-medium wp-image-216" /></a><script type="text/javascript">odl.register(initLightbox);</script></p>
<p>Переходим к коду.</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p21776">
        <div class="code javascript" id="p217code76">
<span class="co1">// ==UserScript==</span><br />
<span class="co1">// @name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Bash.org.ru Ads Remover</span><br />
<span class="co1">// @namespace &nbsp; &nbsp; http://sjinks.org.ua/</span><br />
<span class="co1">// @include &nbsp; &nbsp; &nbsp; http://bash.org.ru/*</span><br />
<span class="co1">// @exclude &nbsp; &nbsp; &nbsp; http://bash.org.ru/abysstop</span><br />
<span class="co1">// @exclude &nbsp; &nbsp; &nbsp; http://bash.org.ru/abyssbest</span><br />
<span class="co1">// ==/UserScript==</span><br />
<br />
<span class="kw2">var</span> x <span class="sy0">=</span> document.<span class="me1">evaluate</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">'//div[@id=&quot;quotes&quot;]/hr[@class=&quot;iq&quot;]/following-sibling::*[position()=1][@class=&quot;q&quot;]'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; document<span class="sy0">,</span> <span class="kw2">null</span><span class="sy0">,</span> XPathResult.<span class="me1">UNORDERED_NODE_SNAPSHOT_TYPE</span><span class="sy0">,</span> <span class="kw2">null</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i<span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> i<span class="sy0">&lt;</span>x.<span class="me1">snapshotLength</span><span class="sy0">;</span> <span class="sy0">++</span>i<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> a <span class="sy0">=</span> x.<span class="me1">snapshotItem</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>1<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> b <span class="sy0">=</span> a.<span class="me1">nextSibling</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; a <span class="sy0">=</span> a.<span class="me1">parentNode</span>.<span class="me1">removeChild</span><span class="br0">&#40;</span>a<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>b.<span class="me1">tagName</span> <span class="sy0">&amp;&amp;</span> <span class="st0">'div'</span> <span class="sy0">==</span> b.<span class="me1">tagName</span>.<span class="me1">toLowerCase</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a <span class="sy0">=</span> b<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
x <span class="sy0">=</span> document.<span class="me1">evaluate</span><span class="br0">&#40;</span><span class="st0">'//iframe'</span><span class="sy0">,</span> document<span class="sy0">,</span> <span class="kw2">null</span><span class="sy0">,</span> XPathResult.<span class="me1">UNORDERED_NODE_SNAPSHOT_TYPE</span><span class="sy0">,</span> <span class="kw2">null</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">for</span> <span class="br0">&#40;</span>i<span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> i<span class="sy0">&lt;</span>x.<span class="me1">snapshotLength</span><span class="sy0">;</span> <span class="sy0">++</span>i<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; a <span class="sy0">=</span> x.<span class="me1">snapshotItem</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; a.<span class="me1">parentNode</span>.<span class="me1">removeChild</span><span class="br0">&#40;</span>a<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Устанавливаем, активируем и не смотрим на рекламу. Всё-таки <a href="http://blog.sjinks.pro/tag/xpath/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XPath">XPath</a>&nbsp;&mdash;&nbsp;это вещь!</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/217-killing-ads-on-bashorgru-greasemonkey-in-action/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/javascript/217-killing-ads-on-bashorgru-greasemonkey-in-action/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Clicky 0.3b для WordPress и проблемы с JavaScript</title>
		<link>http://blog.sjinks.pro/wordpress/patches/211-clicky-for-wordpress-and-javascript-problems/</link>
		<comments>http://blog.sjinks.pro/wordpress/patches/211-clicky-for-wordpress-and-javascript-problems/#comments</comments>
		<pubDate>Mon, 30 Jun 2008 22:58:52 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Патчи]]></category>
		<category><![CDATA[Clicky]]></category>
		<category><![CDATA[Google Analytics]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[web analytics]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[ошибка]]></category>
		<category><![CDATA[патч]]></category>
		<category><![CDATA[плагин]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=211</guid>
		<description><![CDATA[Исправляем ошибки JavaScript в Clicky 0.3b для WordPress В Австралии и США большой популярностью пользуется плагин Clicky&#160;&#8212;&#160;Web Analytics 2.0. Как следует из названия, Clicky является еще одним сервисом для анализа статистики веб-сайта. Судя по приведённой на сайте таблице, Clicky, образно говоря, «затыкает за пояс» даже такого конкурента, как Google Analytics. Себе на сайты я ставить Clicky [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/patches/211-clicky-for-wordpress-and-javascript-problems/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Исправляем ошибки <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a> в <a href="http://blog.sjinks.pro/tag/clicky/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Clicky">Clicky</a> 0.3b для <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a></em></h2>
<p>В Австралии и США большой популярностью пользуется <a href="http://blog.sjinks.pro/tag/plugin/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  плагин">плагин</a> <a href="http://getclicky.com/goodies/" rel="nofollow">Clicky&nbsp;&mdash;&nbsp;Web Analytics 2.0</a>. Как следует из названия, Clicky является еще одним сервисом для анализа статистики веб-сайта. Судя по приведённой на сайте <a href="http://getclicky.com/" rel="nofollow">таблице</a>, Clicky, образно говоря, «затыкает за пояс» даже такого конкурента, как <a href="http://blog.sjinks.pro/tag/google-analytics/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Google Analytics">Google Analytics</a>.</p>
<p>Себе на сайты я ставить Clicky не пытался, но наблюдал его в действии в <a href="http://extrememember.com/" rel="nofollow">проекте</a>, над которым работаю. Могу сказать, что сервис действительно мощный и удобный, а плагин Clicky для WordPress относится к разряду «сконфигурировал и забыл».</p>
<p>Всё хорошо, но по традиции есть одно «но»: если на странице используется, например, <a href="http://blog.sjinks.pro/tag/prototype/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Prototype">Prototype</a>, то плагин начинает кидаться ошибками JavaScript.<span id="more-211"></span></p>
<p>А <a href="http://blog.sjinks.pro/tag/bug/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  ошибка">ошибка</a> там банальная: при поиске cookies автор использовал конструкцию <span class="codebox"><code class="javascript"><span class="kw1">for</span> ... <span class="kw1">in</span></code></span> и предполагал, что все перебираемые свойства окажутся строковыми. Для «голого» браузера это справедливо. Но как только какой-либо скрипт (например, Prototype) расширит прототип <code>Array</code> своими методами, начинаются ошибки. А всё дело в том, что при добавлении новых свойств или методов в прототип объекта у нас нет возможности пометить их как <dfn>неперечисляемые</dfn> (non-enumerable), то есть такими, чтобы <span class="codebox"><code class="javascript"><span class="kw1">for</span> ... <span class="kw1">in</span></code></span> их пропускал.</p>
<p>Решение простое: использовать обычный <span class="codebox"><code class="javascript"><span class="kw1">for</span></code></span> вместо <code>for ... in</code>. Что, собственно говоря, нижеприведённый <a href="http://blog.sjinks.pro/tag/patch/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  патч">патч</a> и делает. А также добавляет секцию <span class="codebox"><code class="xml"><span class="sc2">&lt;![CDATA[ ... ]]&gt;</span></code></span> внутрь скрипта, чтобы не было проблем с <a href="http://blog.sjinks.pro/tag/xhtml/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XHTML">XHTML</a>-контентом.</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p21178">
        <div class="code diff" id="p211code78">
diff -uwd -r clicky-original/clicky.php clicky/clicky.php<br />
<span class="re3">--- clicky-original/clicky.php &nbsp;<span class="nu0">2007</span>-06-<span class="nu0">14</span> <span class="nu0">12</span>:<span class="nu0">33</span>:<span class="nu0">40.000000000</span> +0300</span><br />
<span class="re4">+++ clicky/clicky.php &nbsp; <span class="nu0">2008</span>-06-<span class="nu0">25</span> <span class="nu0">17</span>:<span class="nu0">40</span>:<span class="nu0">07.000000000</span> +0300</span><br />
<span class="re6">@@ -<span class="nu0">27</span>,<span class="nu0">15</span> +<span class="nu0">27</span>,<span class="nu0">17</span> @@</span><br />
<br />
&nbsp; &nbsp;if<span class="br0">&#40;</span> get_option<span class="br0">&#40;</span>'wpgc_visitornames'<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp;echo &quot;<br />
<span class="re7">- &nbsp; &nbsp;&lt;script type='text/javascript'&gt;</span><br />
<span class="re8">+ &nbsp; &nbsp;&lt;script type='text/javascript'&gt;/*&lt;!<span class="br0">&#91;</span>CDATA<span class="br0">&#91;</span>*/</span><br />
&nbsp; &nbsp; &nbsp;function clicky_get_cookie<span class="br0">&#40;</span> name <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;var ca = document.cookie.split<span class="br0">&#40;</span>';'<span class="br0">&#41;</span>;<br />
<span class="re7">- &nbsp; &nbsp; &nbsp;for<span class="br0">&#40;</span> var i in ca <span class="br0">&#41;</span> <span class="br0">&#123;</span></span><br />
<span class="re8">+ &nbsp; &nbsp; var len = ca.length;</span><br />
<span class="re8">+ &nbsp; &nbsp; &nbsp;for<span class="br0">&#40;</span> var i=<span class="nu0">0</span>; i&lt;len; ++i <span class="br0">&#41;</span> <span class="br0">&#123;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if<span class="br0">&#40;</span> ca<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.indexOf<span class="br0">&#40;</span> name+'=' <span class="br0">&#41;</span> &gt; -1 <span class="br0">&#41;</span> return decodeURIComponent<span class="br0">&#40;</span> ca<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.split<span class="br0">&#40;</span>'='<span class="br0">&#41;</span><span class="br0">&#91;</span>1<span class="br0">&#93;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;return '';<br />
&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp;var clicky_custom_session = <span class="br0">&#123;</span> username: clicky_get_cookie<span class="br0">&#40;</span> 'comment_author_&quot;.md5<span class="br0">&#40;</span> get_option<span class="br0">&#40;</span> &quot;siteurl&quot; <span class="br0">&#41;</span><span class="br0">&#41;</span>.&quot;' <span class="br0">&#41;</span> <span class="br0">&#125;</span>;<br />
<span class="re8">+ &nbsp; /*<span class="br0">&#93;</span><span class="br0">&#93;</span>&gt;*/</span><br />
&nbsp; &nbsp; &nbsp;&lt;/script&gt;\n&quot;;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/patches/211-clicky-for-wordpress-and-javascript-problems/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/patches/211-clicky-for-wordpress-and-javascript-problems/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Парочка аккордеонов</title>
		<link>http://blog.sjinks.pro/javascript/91-couple-of-accordions/</link>
		<comments>http://blog.sjinks.pro/javascript/91-couple-of-accordions/#comments</comments>
		<pubDate>Sun, 13 Apr 2008 18:19:53 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Scriptaculous]]></category>
		<category><![CDATA[WCAG]]></category>
		<category><![CDATA[XHTML]]></category>
		<category><![CDATA[аккордеон]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=91</guid>
		<description><![CDATA[Несколько вариантов реализации меню-аккордеона с использованием библиотеки Prototype Недавно в одном из проектов появилась необходимость использовать аккордеон (подобный используемому на Desert Ridge Marketplace). Любят заказчики дешевые эффекты, ничего здесь не поделаешь Чем мне не понравился аккордеон на Desert Ridge&#160;&#8212;&#160;это полной зависимостью от JavaScript: если JavaScript выключен, навигация по сайту переставала работать. Это мне не понравилось, [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/91-couple-of-accordions/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Несколько вариантов реализации меню-аккордеона с использованием библиотеки <a href="http://blog.sjinks.pro/tag/prototype/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Prototype">Prototype</a></em></h2>
<p>Недавно в одном из проектов появилась необходимость использовать <a href="http://blog.sjinks.pro/tag/accordion/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  аккордеон">аккордеон</a> (подобный используемому на Desert Ridge Marketplace). Любят заказчики дешевые <a href="http://blog.sjinks.pro/tag/effects/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  эффекты">эффекты</a>, ничего здесь не поделаешь <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Чем мне не понравился аккордеон на Desert Ridge&nbsp;&mdash;&nbsp;это полной зависимостью от <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a>: если <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a> выключен, навигация по сайту переставала работать. Это мне не понравилось, и я решил написать свой. </p>
<p>Представляю два решения:</p>
<ol>
<li>Подменю сворачивается/разворачивается по щелчку, элементы меню не зависят друг от друга;</li>
<li>Подменю сворачивается/разворачивается по щелчку, при этом не может быть более одного развёрнутого подменю.</li>
</ol>
<p>При выключенном JavaScript оба аккордеона трансформируются в двухуровневый список.<span id="more-91"></span></p>
<p>Поехали. Будем использовать следующую разметку:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9184">
        <div class="code xhtml" id="p91code84">
&nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">ul</span> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;accordion&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>Item 1<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">ul</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 1.1<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 1.2<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 1.3<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 1.4<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">ul</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span> <span class="kw3">class</span><span class="sy0">=</span><span class="st0">&quot;active&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>Item 2<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">ul</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 2.1<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 2.2<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 2.3<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 2.4<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">ul</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>Item 3<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">ul</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 3.1<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 3.2<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">ul</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>Item 4<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">ul</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 4.1<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="kw2">li</span>&gt;&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;#&quot;</span>&gt;</span>SubItem 4.2<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">ul</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">li</span>&gt;</span><br />
&nbsp; &nbsp; <span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">ul</span>&gt;</span>
        </div>
    </div>
</div>

<p>С разметкой всё просто: обычный двухуровневый список; предполагается, что меню Item2 активно (то есть должно быть развёрнуто).</p>
<p>Оформим аккордеон при помощи <a href="http://blog.sjinks.pro/tag/css/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  CSS">CSS</a>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9185">
        <div class="code css" id="p91code85">
a <span class="br0">&#123;</span> <span class="kw1">text-decoration</span><span class="sy0">:</span> <span class="kw2">none</span><span class="sy0">;</span> <span class="kw1">color</span><span class="sy0">:</span> <span class="re0">#00F</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
a<span class="re2">:hover </span><span class="br0">&#123;</span> <span class="kw1">text-decoration</span><span class="sy0">:</span> <span class="kw2">underline</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
<span class="re0">#accordion</span> a <span class="br0">&#123;</span> <span class="kw1">outline</span><span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <br />
<span class="re0">#accordion</span><span class="sy0">,</span> <span class="re0">#accordion</span> ul<span class="sy0">,</span> <span class="re0">#accordion</span> li <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">list-style</span><span class="sy0">:</span> <span class="kw2">none</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">margin</span><span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">padding</span><span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">display</span><span class="sy0">:</span> <span class="kw2">block</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="re0">#accordion</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">border</span><span class="sy0">:</span> <span class="re3">1px</span> <span class="kw2">solid</span> <span class="re0">#CCC</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">width</span><span class="sy0">:</span> <span class="re3">150px</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="re0">#accordion</span> ul <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">margin-left</span><span class="sy0">:</span> <span class="re3">40px</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="re0">#accordion</span> <span class="sy0">&gt;</span> li <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">border-bottom</span><span class="sy0">:</span> <span class="re3">1px</span> <span class="kw2">solid</span> <span class="re0">#CCC</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">padding</span><span class="sy0">:</span> <span class="re3">2px</span> <span class="re3">5px</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="re0">#accordion</span> <span class="sy0">&gt;</span> li<span class="re2">:last-child </span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">border-bottom</span><span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="re0">#accordion</span> li<span class="re1">.active</span> <span class="sy0">&gt;</span> a <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">color</span><span class="sy0">:</span> <span class="kw2">red</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Покажем уродство IE6, не понимающего CSS&nbsp;2.1:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9186">
        <div class="code css" id="p91code86">
<span class="sy0">*</span> html <span class="re0">#accordion</span> li <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">border-bottom</span><span class="sy0">:</span> <span class="re3">1px</span> <span class="kw2">solid</span> <span class="re0">#CCC</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">padding</span><span class="sy0">:</span> <span class="re3">2px</span> <span class="re3">5px</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="sy0">*</span> html <span class="re0">#accordion</span> li li <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">border-bottom</span><span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">padding</span><span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="sy0">*</span> html <span class="re0">#accordion</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">border-bottom</span><span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="sy0">*</span> html <span class="re0">#accordion</span> li<span class="re1">.active</span> a <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">color</span><span class="sy0">:</span> <span class="kw2">red</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="sy0">*</span> html <span class="re0">#accordion</span> li<span class="re1">.active</span> ul a <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">color</span><span class="sy0">:</span> <span class="kw1">blue</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>За использование пяти лишних правил я и не люблю IE6 (и это мы еще используем простую разметку).</p>
<p>Переходим к JavaScript. В данных примерах я использую библиотеки Prototype и <a href="http://blog.sjinks.pro/tag/scriptaculous/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Scriptaculous">Scriptaculous</a> Effects (всё очень легко переводится на <a href="http://blog.sjinks.pro/tag/jquery/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  jQuery">jQuery</a>).<br />
<strong>Вариант 1: независимые элементы меню</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9187">
        <div class="code javascript" id="p91code87">
$$<span class="br0">&#40;</span><span class="st0">'#accordion &gt; li:not([class=&quot;active&quot;]) ul'</span><span class="br0">&#41;</span>.<span class="me1">invoke</span><span class="br0">&#40;</span><span class="st0">'setStyle'</span><span class="sy0">,</span> <span class="br0">&#123;</span> display <span class="sy0">:</span> <span class="st0">'none'</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>.<span class="me1">invoke</span><span class="br0">&#40;</span><span class="st0">'addClassName'</span><span class="sy0">,</span> <span class="st0">'collapsed'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
$$<span class="br0">&#40;</span><span class="st0">'#accordion &gt; li[class=&quot;active&quot;] ul'</span><span class="br0">&#41;</span>.<span class="me1">invoke</span><span class="br0">&#40;</span><span class="st0">'addClassName'</span><span class="sy0">,</span> <span class="st0">'expanded'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
$$<span class="br0">&#40;</span><span class="st0">'#accordion &gt; li &gt; a'</span><span class="br0">&#41;</span>.<span class="me1">invoke</span><span class="br0">&#40;</span><span class="st0">'observe'</span><span class="sy0">,</span> <span class="st0">'click'</span><span class="sy0">,</span> <br />
&nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; e.<span class="kw3">stop</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> ul <span class="sy0">=</span> e.<span class="me1">findElement</span><span class="br0">&#40;</span><span class="st0">'a'</span><span class="br0">&#41;</span>.<span class="me1">up</span><span class="br0">&#40;</span><span class="st0">'li'</span><span class="br0">&#41;</span>.<span class="me1">down</span><span class="br0">&#40;</span><span class="st0">'ul'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>ul<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">new</span> Effect.<span class="me1">toggle</span><span class="br0">&#40;</span>ul.<span class="me1">toggleClassName</span><span class="br0">&#40;</span><span class="st0">'collapsed'</span><span class="br0">&#41;</span>.<span class="me1">toggleClassName</span><span class="br0">&#40;</span><span class="st0">'expanded'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">'blind'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p><a href="http://blog.sjinks.pro/test/accordion/accordion1.html">Рабочий пример для первого варианта.</a></p>
<p><strong>Вариант 2: развёрнуто не более одного меню</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9188">
        <div class="code javascript" id="p91code88">
$$<span class="br0">&#40;</span><span class="st0">'#accordion &gt; li:not([class=&quot;active&quot;]) ul'</span><span class="br0">&#41;</span>.<span class="me1">invoke</span><span class="br0">&#40;</span><span class="st0">'setStyle'</span><span class="sy0">,</span> <span class="br0">&#123;</span> display <span class="sy0">:</span> <span class="st0">'none'</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>.<span class="me1">invoke</span><span class="br0">&#40;</span><span class="st0">'addClassName'</span><span class="sy0">,</span> <span class="st0">'collapsed'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
$$<span class="br0">&#40;</span><span class="st0">'#accordion &gt; li[class=&quot;active&quot;] ul'</span><span class="br0">&#41;</span>.<span class="me1">invoke</span><span class="br0">&#40;</span><span class="st0">'addClassName'</span><span class="sy0">,</span> <span class="st0">'expanded'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
$$<span class="br0">&#40;</span><span class="st0">'#accordion &gt; li &gt; a'</span><span class="br0">&#41;</span>.<span class="me1">invoke</span><span class="br0">&#40;</span><span class="st0">'observe'</span><span class="sy0">,</span> <span class="st0">'click'</span><span class="sy0">,</span> <br />
&nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; e.<span class="kw3">stop</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> ul <span class="sy0">=</span> e.<span class="me1">findElement</span><span class="br0">&#40;</span><span class="st0">'a'</span><span class="br0">&#41;</span>.<span class="me1">up</span><span class="br0">&#40;</span><span class="st0">'li'</span><span class="br0">&#41;</span>.<span class="me1">down</span><span class="br0">&#40;</span><span class="st0">'ul'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>ul<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>ul.<span class="me1">hasClassName</span><span class="br0">&#40;</span><span class="st0">'collapsed'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> c <span class="sy0">=</span> $$<span class="br0">&#40;</span><span class="st0">'#accordion ul:not([class=&quot;collapsed&quot;])'</span><span class="br0">&#41;</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>c<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">new</span> Effect.<span class="me1">BlindUp</span><span class="br0">&#40;</span>c.<span class="me1">toggleClassName</span><span class="br0">&#40;</span><span class="st0">'collapsed'</span><span class="br0">&#41;</span>.<span class="me1">toggleClassName</span><span class="br0">&#40;</span><span class="st0">'expanded'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">new</span> Effect.<span class="me1">BlindDown</span><span class="br0">&#40;</span>ul.<span class="me1">toggleClassName</span><span class="br0">&#40;</span><span class="st0">'collapsed'</span><span class="br0">&#41;</span>.<span class="me1">toggleClassName</span><span class="br0">&#40;</span><span class="st0">'expanded'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p><a href="http://blog.sjinks.pro/test/accordion/accordion2.html">Рабочий пример для второго варианта.</a></p>
<p>Всё очень просто!</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/91-couple-of-accordions/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/javascript/91-couple-of-accordions/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Скрипт для Greasemonkey для извлечения ASIN с amazon.com</title>
		<link>http://blog.sjinks.pro/javascript/78-script-for-greasemonkey-to-extract-asin-from-amazon/</link>
		<comments>http://blog.sjinks.pro/javascript/78-script-for-greasemonkey-to-extract-asin-from-amazon/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 21:57:26 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Greasemonkey]]></category>
		<category><![CDATA[XPath]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=78</guid>
		<description><![CDATA[Работу можно получить, даже если часовая ставка в 4 раза превышает ту, что хочет заказчик Сегодня (вернее, уже вчера) мне попался заказчик, которому нужен был скрипт для Greasemonkey, который бы мог вытаскивать ASIN из URL'ов на amazon.com и отображать их. Задачка довольно простая, но подобный тип задач встречается довольно часто. Поэтому привожу готовое решение. // [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/78-script-for-greasemonkey-to-extract-asin-from-amazon/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Работу можно получить, даже если часовая ставка в 4 раза превышает ту, что хочет заказчик</em></h2>
<p>Сегодня (вернее, уже вчера) мне попался заказчик, которому нужен был скрипт для <a href="http://blog.sjinks.pro/tag/greasemonkey/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Greasemonkey">Greasemonkey</a>, который бы мог вытаскивать ASIN из URL'ов на amazon.com и отображать их.</p>
<p>Задачка довольно простая, но подобный тип задач встречается довольно часто. Поэтому привожу готовое решение.<span id="more-78"></span></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p7890">
        <div class="code javascript" id="p78code90">
<span class="co1">// ==UserScript==</span><br />
<span class="co1">// @name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Amazon ASIN Extractor</span><br />
<span class="co1">// @namespace &nbsp; &nbsp; http://sjinks.org.ua/</span><br />
<span class="co1">// @include &nbsp; &nbsp; &nbsp; http://www.amazon.com/*</span><br />
<span class="co1">// @include &nbsp; &nbsp; &nbsp; http://amazon.com/*</span><br />
<span class="co1">// ==/UserScript==</span><br />
<br />
<span class="kw2">var</span> links <span class="sy0">=</span> document.<span class="me1">evaluate</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">'(//div[contains(@id, &quot;title_&quot;)]/a[contains(@href, &quot;/dp/&quot;)])|(//strong[@class=&quot;sans&quot;]/a[contains(@href, &quot;/dp/&quot;)])|(//td[@class=&quot;dataColumn&quot;]//td/a[contains(@href, &quot;/dp/&quot;)])'</span><span class="sy0">,</span> <br />
&nbsp; &nbsp; document<span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="kw2">null</span><span class="sy0">,</span><br />
&nbsp; &nbsp; XPathResult.<span class="me1">UNORDERED_NODE_SNAPSHOT_TYPE</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="kw2">null</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i<span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> i<span class="sy0">&lt;</span>links.<span class="me1">snapshotLength</span><span class="sy0">;</span> <span class="sy0">++</span>i<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> a &nbsp; &nbsp;<span class="sy0">=</span> links.<span class="me1">snapshotItem</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> href <span class="sy0">=</span> a.<span class="me1">getAttribute</span><span class="br0">&#40;</span><span class="st0">'href'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> t <span class="sy0">=</span> href.<span class="me1">match</span><span class="br0">&#40;</span><span class="co2">/\/dp\/([A-Z0-9]{10})\//</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="st0">'undefined'</span> <span class="sy0">!=</span> <span class="kw1">typeof</span> t<span class="br0">&#91;</span>1<span class="br0">&#93;</span> <span class="sy0">&amp;&amp;</span> 10 <span class="sy0">==</span> t<span class="br0">&#91;</span>1<span class="br0">&#93;</span>.<span class="me1">length</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> div <span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'div'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> strong <span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'strong'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; strong.<span class="me1">appendChild</span><span class="br0">&#40;</span>document.<span class="me1">createTextNode</span><span class="br0">&#40;</span><span class="st0">'ASIN: '</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; div.<span class="me1">appendChild</span><span class="br0">&#40;</span>strong<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; div.<span class="me1">appendChild</span><span class="br0">&#40;</span>document.<span class="me1">createTextNode</span><span class="br0">&#40;</span>t<span class="br0">&#91;</span>1<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; a.<span class="me1">parentNode</span>.<span class="me1">insertBefore</span><span class="br0">&#40;</span>div<span class="sy0">,</span> a.<span class="me1">nextSibling</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Для модификации для другого сайта просто меняется <a href="http://blog.sjinks.pro/tag/xpath/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XPath">XPath</a> внутри <code>document.evaluate()</code>, <code>@include</code>, регулярное выражение в <code>href.match()</code> и проверка в <code>if</code>.</p>
<p><em>Verbum sapienti sat est&hellip;</em></p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/78-script-for-greasemonkey-to-extract-asin-from-amazon/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/javascript/78-script-for-greasemonkey-to-extract-asin-from-amazon/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WP CodeBox и Prototype</title>
		<link>http://blog.sjinks.pro/wordpress/patches/32-wp-codebox-and-prototype/</link>
		<comments>http://blog.sjinks.pro/wordpress/patches/32-wp-codebox-and-prototype/#comments</comments>
		<pubDate>Sat, 15 Mar 2008 16:11:10 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Патчи]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WP CodeBox]]></category>
		<category><![CDATA[подсветка синтаксиса]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/javascript/32-wp-codebox-and-prototype/</guid>
		<description><![CDATA[Решение, позволяющее совместно использовать на одном сайте плагин WP&#160;Codebox и известную библиотеку Prototype Намедни пришлось заставлять работать скрипт, использующий библиотеку Prototype, на сайте с WordPress, где стоял плагин WP&#160;CodeBox (ранее я уже писал о нём). Сразу обратил внимание, что всё работало как-то криво, выскакивала куча непонятных ошибок. Лишь позже, просмотрев весь JavaScript, я понял, в [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/patches/32-wp-codebox-and-prototype/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Решение, позволяющее совместно использовать на одном сайте <a href="http://blog.sjinks.pro/tag/plugin/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  плагин">плагин</a> WP&nbsp;Codebox и известную библиотеку <a href="http://blog.sjinks.pro/tag/prototype/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Prototype">Prototype</a></em></h2>
<p>Намедни пришлось заставлять работать скрипт, использующий библиотеку Prototype, на сайте с <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a>, где стоял плагин WP&nbsp;CodeBox (<a href="http://blog.sjinks.pro/php/13-patch-for-wp-codebox-for-valid-xhtml/">ранее </a>я уже писал о нём). Сразу обратил внимание, что всё работало как-то криво, выскакивала куча непонятных ошибок. Лишь позже, просмотрев весь <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a>, я понял, в чём была проблема.<span id="more-32"></span></p>
<p>В файле /wp-content/plugins/wp-codebox/js/codebox.js есть три магические строчки:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p3293">
        <div class="code javascript" id="p32code93">
<span class="kw2">function</span> $<span class="br0">&#40;</span>id<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> document.<span class="me1">getElementById</span><span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Эта функция конфликтует с одноимённой функцией из Prototype (причём последняя имеет гораздо больше возможностей). Решается всё просто:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p3294">
        <div class="code javascript" id="p32code94">
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="st0">'undefined'</span> <span class="sy0">==</span> <span class="kw1">typeof</span> $<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">function</span> $<span class="br0">&#40;</span>id<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> document.<span class="me1">getElementById</span><span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Жаль только, что на поиски бага ушло много времени&hellip;</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/patches/32-wp-codebox-and-prototype/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/patches/32-wp-codebox-and-prototype/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

