Файловый менеджер - Редактировать - /home/wuectly/www/03cbe/jacssjanus.zip
Назад
PK Y~!]*=�5& & csslex.phpnu &1i� <?php class CSSLEX { private $csslex = array(); function __construct () { $csslex = array(); $csslex['keyword'] = '(?:\@(?:import|page|media|charset))'; # nl \n|\r\n|\r|\f ; a newline $csslex['newline'] = '\n|\r\n|\r|\f'; # h [0-9a-f] ; a hexadecimal digit $csslex['hex'] = '[0-9a-f]'; # nonascii [\200-\377] $csslex['non_ascii'] = '[\200-\377]'; # unicode \\{h}{1,6}(\r\n|[ \t\r\n\f])? $csslex['unicode'] = '(?:(?:\\' . $csslex['hex'] . '{1,6})(?:\r\n|[ \t\r\n\f])?)'; # escape {unicode}|\\[^\r\n\f0-9a-f] $csslex['escape'] = '(?:' . $csslex['unicode'] . '|\\[^\r\n\f0-9a-f])'; # nmstart [_a-z]|{nonascii}|{escape} $csslex['nmstart'] = '(?:[_a-z]|' . $csslex['non_ascii'] . '|' . $csslex['escape'] . ')'; # nmchar [_a-z0-9-]|{nonascii}|{escape} $csslex['nmchar'] = '(?:[_a-z0-9-]|' . $csslex['non_ascii'] . '|' . $csslex['escape'] . ')'; # ident -?{nmstart}{nmchar}* $csslex['ident'] = '-?' . $csslex['nmstart'] . $csslex['nmchar'] . '*'; # name {nmchar}+ $csslex['name'] = $csslex['nmchar'] . '+'; # hash $csslex['hash'] = '#' . $csslex['name']; # string1 \"([^\n\r\f\\"]|\\{nl}|{escape})*\" ; "string" $csslex['string1'] = '"(?:[^\"\\]|\\.)*"'; # string2 \'([^\n\r\f\\']|\\{nl}|{escape})*\' ; 'string' $csslex['string2'] = "'(?:[^\'\\]|\\.)*'"; # string {string1}|{string2} $csslex['string'] = '(?:' . $csslex['string1'] . '|' . $csslex['string2'] . ')'; # num [0-9]+|[0-9]*"."[0-9]+ $csslex['num'] = '(?:[0-9]*\.[0-9]+|[0-9]+)'; # s [ \t\r\n\f] $csslex['space'] = '[ \t\r\n\f]'; # w {s}* $csslex['whitespace'] = '(?:' . $csslex['space'] . '*)'; # url special chars $csslex['url_special_chars'] = '[!#$%&*-~]'; # url chars ({url_special_chars}|{nonascii}|{escape})* $csslex['url_chars'] = sprintf('(?:%s|%s|%s)*', $csslex['url_special_chars'], $csslex['non_ascii'], $csslex['escape']); # url $csslex['url'] = sprintf('url\(%s(%s|%s)%s\)', $csslex['whitespace'], $csslex['string'], $csslex['url_chars'], $csslex['whitespace']); # comments # see http://www.w3.org/tr/css21/grammar.html $csslex['comment'] = '\/\*[^\*]*\*+([^\/\*][^\*]*\*+)*\/'; # {e}{m} {return ems;} # {e}{x} {return exs;} # {p}{x} {return length;} # {c}{m} {return length;} # {m}{m} {return length;} # {i}{n} {return length;} # {p}{t} {return length;} # {p}{c} {return length;} # {d}{e}{g} {return angle;} # {r}{a}{d} {return angle;} # {g}{r}{a}{d} {return angle;} # {m}{s} {return time;} # {s} {return time;} # {h}{z} {return freq;} # {k}{h}{z} {return freq;} # % {return percentage;} $csslex['unit'] = '(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)'; # {num}{unit|ident} {return number;} $csslex['quantity'] = sprintf('%s(?:%s%s|%s)?', $csslex['num'], $csslex['whitespace'], $csslex['unit'], $csslex['ident']); # "<!--" {return cdo;} # "-->" {return cdc;} # "~=" {return includes;} # "|=" {return dashmatch;} # {w}"{" {return lbrace;} # {w}"+" {return plus;} # {w}">" {return greater;} # {w}"," {return comma;} $csslex['punc'] = '<!--|-->|~=|\|=|[\{\+>,:;]'; $this->csslex = $csslex; } function __get ($name) { return isset($this->csslex[$name]) ? $this->csslex[$name] : null; } } PK Y~!]��Ƙ�= �= test.phpnu &1i� <style type="text/css"> .pass {color: green;} .fail {color: red;} table.result { font-family: verdana,arial,sans-serif; font-size:11px; color:#333333; border-width: 1px; border-color: #666666; border-collapse: collapse; } table.result td { border-width: 1px; padding: 8px; border-style: solid; border-color: #666666; background-color: #ffffff; width: 400px; } table.result tr td:first-child { border-width: 1px; padding: 8px; border-style: solid; border-color: #666666; background-color: #dedede; width: 50px; } </style> <?php require_once 'ja.cssjanus.php'; $test = ''; $testcase = ''; $shouldbe = ''; $swap_ltr_rtl_in_url = False; $swap_left_right_in_url = False; function test () { global $test, $testcase, $shouldbe, $swap_ltr_rtl_in_url, $swap_left_right_in_url; $input = implode ("\n", $testcase); $expect = implode ("\n", $shouldbe); $output = JACSSJanus::transform ($input, $swap_ltr_rtl_in_url, $swap_left_right_in_url); $pass = ($output == $expect); $result = $pass ? '<span class="pass">pass</span>' : '<span class="fail">fail</span>'; ?> <h2 class="<?php echo $pass ? 'pass':'fail' ?>"><?php echo $test ?></h2> <table class="result"> <tr><td>Input</td><td><?php echo str_replace("\n", "<br />\n", $input) ?></td></tr> <tr><td>Expect</td><td><?php echo str_replace("\n", "<br />\n", $expect) ?></td></tr> <tr><td>Output</td><td><?php echo str_replace("\n", "<br />\n", $output) ?></td></tr> <tr><td>Result</td><td><?php echo $result ?></td></tr> </table> <br /><br /> <?php } $test = 'testPreserveComments'; $testcase = array('/* left /* right */left: 10px'); $shouldbe = array('/* left /* right */right: 10px'); test(); $testcase = array('/*left*//*left*/left: 10px'); $shouldbe = array('/*left*//*left*/right: 10px'); test(); $testcase = array('/* Going right is cool */\n#test {left: 10px}'); $shouldbe = array('/* Going right is cool */\n#test {right: 10px}'); $testcase = array('/* padding-right 1 2 3 4 */\n#test {left: 10px}\n/*right*/'); $shouldbe = array('/* padding-right 1 2 3 4 */\n#test {right: 10px}\n/*right*/'); test(); $testcase = array('/** Two line comment\n * left\n \*/\n#test {left: 10px}'); $shouldbe = array('/** Two line comment\n * left\n \*/\n#test {right: 10px}'); test(); $test = 'testPositionAbsoluteOrRelativeValues'; $testcase = array('left: 10px'); $shouldbe = array('right: 10px'); test(); $test = 'testFourNotation'; $testcase = array('padding: .25em 15px 0pt 0ex'); $shouldbe = array('padding: .25em 0ex 0pt 15px'); test(); $testcase = array('margin: 1px -4px 3px 2px'); $shouldbe = array('margin: 1px 2px 3px -4px'); test(); $testcase = array('padding:0 15px .25em 0'); $shouldbe = array('padding:0 0 .25em 15px'); test(); $testcase = array('padding: 1px 4.1grad 3px 2%'); $shouldbe = array('padding: 1px 2% 3px 4.1grad'); test(); $testcase = array('padding: 1px 2px 3px auto'); $shouldbe = array('padding: 1px auto 3px 2px'); test(); $testcase = array('padding: 1px inherit 3px auto'); $shouldbe = array('padding: 1px auto 3px inherit'); test(); # not really four notation $testcase = array('#settings td p strong'); $shouldbe = $testcase; test(); $test = 'testThreeNotation'; $testcase = array('margin: 1em 0 .25em'); $shouldbe = array('margin: 1em 0 .25em'); test(); $testcase = array('margin:-1.5em 0 -.75em'); $shouldbe = array('margin:-1.5em 0 -.75em'); test(); $test = 'testTwoNotation'; $testcase = array('padding: 1px 2px'); $shouldbe = array('padding: 1px 2px'); test(); $test = 'testOneNotation'; $testcase = array('padding: 1px'); $shouldbe = array('padding: 1px'); test(); $test = 'testDirection'; # we don't want direction to be changed other than in body $testcase = array('direction: ltr'); $shouldbe = array('direction: ltr'); test(); # we don't want direction to be changed other than in body $testcase = array('direction: rtl'); $shouldbe = array('direction: rtl'); test(); # we don't want direction to be changed other than in body $testcase = array('input { direction: ltr }'); $shouldbe = array('input { direction: ltr }'); test(); $testcase = array('body { direction: ltr }'); $shouldbe = array('body { direction: rtl }'); test(); $testcase = array('body { padding: 10px; direction: ltr; }'); $shouldbe = array('body { padding: 10px; direction: rtl; }'); test(); $testcase = array('body { direction: ltr } .myClass { direction: ltr }'); $shouldbe = array('body { direction: rtl } .myClass { direction: ltr }'); test(); $testcase = array('body{\n direction: ltr\n}'); $shouldbe = array('body{\n direction: rtl\n}'); test(); $test = 'testDoubleDash'; $testcase = array('border-left-color: red'); $shouldbe = array('border-right-color: red'); test(); $testcase = array('border-right-color: red'); $shouldbe = array('border-left-color: red'); test(); # This is for compatibility strength, in reality CSS has no properties # that are currently like this. $test = 'testCSSProperty'; $testcase = array('alright: 10px'); $shouldbe = array('alright: 10px'); test(); $testcase = array('alleft: 10px'); $shouldbe = array('alleft: 10px'); test(); $test = 'testFloat'; $testcase = array('float: right'); $shouldbe = array('float: left'); test(); $testcase = array('float: left'); $shouldbe = array('float: right'); test(); $test = 'testUrlWithFlagOff'; $swap_ltr_rtl_in_url = False; $swap_left_right_in_url = False; $testcase = array('background: url(/foo/bar-left.png)'); $shouldbe = array('background: url(/foo/bar-left.png)'); test(); $testcase = array('background: url(/foo/left-bar.png)'); $shouldbe = array('background: url(/foo/left-bar.png)'); test(); $testcase = array('url("http://www.blogger.com/img/triangle_ltr.gif")'); $shouldbe = array('url("http://www.blogger.com/img/triangle_ltr.gif")'); test(); $testcase = array("url('http://www.blogger.com/img/triangle_ltr.gif')"); $shouldbe = array("url('http://www.blogger.com/img/triangle_ltr.gif')"); test(); $testcase = array("url('http://www.blogger.com/img/triangle_ltr.gif' )"); $shouldbe = array("url('http://www.blogger.com/img/triangle_ltr.gif' )"); test(); $testcase = array('background: url(/foo/bar.left.png)'); $shouldbe = array('background: url(/foo/bar.left.png)'); test(); $testcase = array('background: url(/foo/bar-rtl.png)'); $shouldbe = array('background: url(/foo/bar-rtl.png)'); test(); $testcase = array('background: url(/foo/bar-rtl.png); left: 10px'); $shouldbe = array('background: url(/foo/bar-rtl.png); right: 10px'); test(); $testcase = array('background: url(/foo/bar-right.png); direction: ltr'); $shouldbe = array('background: url(/foo/bar-right.png); direction: ltr'); test(); $testcase = array('background: url(/foo/bar-rtl_right.png);', 'left:10px; direction: ltr'); $shouldbe = array('background: url(/foo/bar-rtl_right.png);', 'right:10px; direction: ltr'); test(); $test = 'testUrlWithFlagOn'; $swap_ltr_rtl_in_url = True; $swap_left_right_in_url = True; $testcase = array('background: url(/foo/bar-left.png)'); $shouldbe = array('background: url(/foo/bar-right.png)'); test(); $testcase = array('background: url(/foo/left-bar.png)'); $shouldbe = array('background: url(/foo/right-bar.png)'); test(); $testcase = array('url("http://www.blogger.com/img/triangle_ltr.gif")'); $shouldbe = array('url("http://www.blogger.com/img/triangle_rtl.gif")'); test(); $testcase = array("url('http://www.blogger.com/img/triangle_ltr.gif')"); $shouldbe = array("url('http://www.blogger.com/img/triangle_rtl.gif')"); test(); $testcase = array("url('http://www.blogger.com/img/triangle_ltr.gif' )"); $shouldbe = array("url('http://www.blogger.com/img/triangle_rtl.gif' )"); test(); $testcase = array('background: url(/foo/bar.left.png)'); $shouldbe = array('background: url(/foo/bar.right.png)'); test(); $testcase = array('background: url(/foo/bright.png)'); $shouldbe = array('background: url(/foo/bright.png)'); test(); $testcase = array('background: url(/foo/bar-rtl.png)'); $shouldbe = array('background: url(/foo/bar-ltr.png)'); test(); $testcase = array('background: url(/foo/bar-rtl.png); left: 10px'); $shouldbe = array('background: url(/foo/bar-ltr.png); right: 10px'); test(); $testcase = array('background: url(/foo/bar-right.png); direction: ltr'); $shouldbe = array('background: url(/foo/bar-left.png); direction: ltr'); test(); $testcase = array('background: url(/foo/bar-rtl_right.png);', 'left:10px; direction: ltr'); $shouldbe = array('background: url(/foo/bar-ltr_left.png);', 'right:10px; direction: ltr'); test(); $test = 'testPadding'; $testcase = array('padding-right: bar'); $shouldbe = array('padding-left: bar'); test(); $testcase = array('padding-left: bar'); $shouldbe = array('padding-right: bar'); test(); $test = 'testMargin'; $testcase = array('margin-left: bar'); $shouldbe = array('margin-right: bar'); test(); $testcase = array('margin-right: bar'); $shouldbe = array('margin-left: bar'); test(); $test = 'testBorder'; $testcase = array('border-left: bar'); $shouldbe = array('border-right: bar'); test(); $testcase = array('border-right: bar'); $shouldbe = array('border-left: bar'); test(); $test = 'testCursor'; $testcase = array('cursor: e-resize'); $shouldbe = array('cursor: w-resize'); test(); $testcase = array('cursor: w-resize'); $shouldbe = array('cursor: e-resize'); test(); $testcase = array('cursor: se-resize'); $shouldbe = array('cursor: sw-resize'); test(); $testcase = array('cursor: sw-resize'); $shouldbe = array('cursor: se-resize'); test(); $testcase = array('cursor: ne-resize'); $shouldbe = array('cursor: nw-resize'); test(); $testcase = array('cursor: nw-resize'); $shouldbe = array('cursor: ne-resize'); test(); $test = 'testBGPosition'; $testcase = array('background: url(/foo/bar.png) top left'); $shouldbe = array('background: url(/foo/bar.png) top right'); test(); $testcase = array('background: url(/foo/bar.png) top right'); $shouldbe = array('background: url(/foo/bar.png) top left'); test(); $testcase = array('background-position: top left'); $shouldbe = array('background-position: top right'); test(); $testcase = array('background-position: top right'); $shouldbe = array('background-position: top left'); test(); $test = 'testBGPositionPercentage'; $testcase = array('background-position: 100% 40%'); $shouldbe = array('background-position: 0% 40%'); test(); $testcase = array('background-position: 0% 40%'); $shouldbe = array('background-position: 100% 40%'); test(); $testcase = array('background-position: 23% 0'); $shouldbe = array('background-position: 77% 0'); test(); $testcase = array('background-position: 23% auto'); $shouldbe = array('background-position: 77% auto'); test(); $testcase = array('background-position-x: 23%'); $shouldbe = array('background-position-x: 77%'); test(); $testcase = array('background-position-y: 23%'); $shouldbe = array('background-position-y: 23%'); test(); $testcase = array('background:url(../foo-bar_baz.2008.gif) no-repeat 75% 50%'); $shouldbe = array('background:url(../foo-bar_baz.2008.gif) no-repeat 25% 50%'); test(); $testcase = array('.test { background: 10% 20% } .test2 { background: 40% 30% }'); $shouldbe = array('.test { background: 90% 20% } .test2 { background: 60% 30% }'); test(); $testcase = array('.test { background: 0% 20% } .test2 { background: 40% 30% }'); $shouldbe = array('.test { background: 100% 20% } .test2 { background: 60% 30% }'); test(); $test = 'testDirectionalClassnames'; /* """Makes sure we don't unnecessarily destroy classnames with tokens in them. Despite the fact that that is a bad classname in CSS, we don't want to break anybody. """ */ $testcase = array('.column-left { float: left }'); $shouldbe = array('.column-left { float: right }'); test(); $testcase = array('#bright-light { float: left }'); $shouldbe = array('#bright-light { float: right }'); test(); $testcase = array('a.left:hover { float: left }'); $shouldbe = array('a.left:hover { float: right }'); test(); #tests newlines $testcase = array("#bright-left,\n.test-me { float: left }"); $shouldbe = array("#bright-left,\n.test-me { float: right }"); test(); #tests newlines $testcase = array("#bright-left,", '.test-me { float: left }'); $shouldbe = array("#bright-left,", '.test-me { float: right }'); test(); #tests multiple names and commas $testcase = array('div.leftpill, div.leftpillon {margin-right: 0 !important}'); $shouldbe = array('div.leftpill, div.leftpillon {margin-left: 0 !important}'); test(); $testcase = array('div.left > span.right+span.left { float: left }'); $shouldbe = array('div.left > span.right+span.left { float: right }'); test(); $testcase = array('.thisclass .left .myclass {background:#fff;}'); $shouldbe = array('.thisclass .left .myclass {background:#fff;}'); test(); $testcase = array('.thisclass .left .myclass #myid {background:#fff;}'); $shouldbe = array('.thisclass .left .myclass #myid {background:#fff;}'); test(); $test = 'testLongLineWithMultipleDefs'; $testcase = array('body{direction:rtl;float:right} .b2{direction:ltr;float:right}'); $shouldbe = array('body{direction:ltr;float:left} .b2{direction:ltr;float:left}'); test(); $test = 'testNoFlip'; # """Tests the /* @noflip */ annotation on classnames.""" $testcase = array('/* @noflip */ div { float: left; }'); $shouldbe = array('/* @noflip */ div { float: left; }'); test(); $testcase = array('/* @noflip */ div, .notme { float: left; }'); $shouldbe = array('/* @noflip */ div, .notme { float: left; }'); test(); $testcase = array('/* @noflip */ div { float: left; } div { float: left; }'); $shouldbe = array('/* @noflip */ div { float: left; } div { float: right; }'); test(); $testcase = array('/* @noflip */\ndiv { float: left; }\ndiv { float: left; }'); $shouldbe = array('/* @noflip */\ndiv { float: left; }\ndiv { float: right; }'); test(); # Test @noflip on single rules within classes $testcase = array('div { float: left; /* @noflip */ float: left; }'); $shouldbe = array('div { float: right; /* @noflip */ float: left; }'); test(); $testcase = array('div\n{ float: left;\n/* @noflip */\n float: left;\n }'); $shouldbe = array('div\n{ float: right;\n/* @noflip */\n float: left;\n }'); test(); $testcase = array('div\n{ float: left;\n/* @noflip */\n text-align: left\n }'); $shouldbe = array('div\n{ float: right;\n/* @noflip */\n text-align: left\n }'); test(); $testcase = array('div\n{ /* @noflip */\ntext-align: left;\nfloat: left\n }'); $shouldbe = array('div\n{ /* @noflip */\ntext-align: left;\nfloat: right\n }'); test(); $testcase = array('/* @noflip */div{float:left;text-align:left;}div{float:left}'); $shouldbe = array('/* @noflip */div{float:left;text-align:left;}div{float:right}'); test(); $testcase = array('/* @noflip */','div{float:left;text-align:left;}a{foo:left}'); $shouldbe = array('/* @noflip */','div{float:left;text-align:left;}a{foo:right}'); test(); $test = 'testBorderRadiusNotation'; $testcase = array('border-radius: .25em 15px 0pt 0ex'); $shouldbe = array('border-radius: 15px .25em 0ex 0pt'); test(); $testcase = array('border-radius: 10px 15px 0px'); $shouldbe = array('border-radius: 15px 10px 15px 0px'); test(); $testcase = array('border-radius: 7px 8px'); $shouldbe = array('border-radius: 8px 7px'); test(); $testcase = array('border-radius: 5px'); $shouldbe = array('border-radius: 5px'); test(); $test = 'testGradientNotation'; $testcase = array('background-image: -moz-linear-gradient(#326cc1, #234e8c)'); $shouldbe = array('background-image: -moz-linear-gradient(#326cc1, #234e8c)'); test(); $testcase = array('background-image: -webkit-gradient(linear, 100% 0%, 0% 0%, from(#666666), to(#ffffff))'); $shouldbe = array('background-image: -webkit-gradient(linear, 100% 0%, 0% 0%, from(#666666), to(#ffffff))'); test(); PK Y~!]=�� j j ja.cssjanus.phpnu &1i� <?php /** * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html * */ /** * This is a rewrite & update version of PHP port of CSSJanus, a utility that transforms CSS style sheets * written for LTR to RTL. * * The original Python version of CSSJanus is Copyright 2008 by Google Inc. and * is distributed under the Apache license. * * The original PHP version of CSSJanus: https://doc.wikimedia.org/mediawiki-core/master/php/html/CSSJanus_8php.html. * * Original code: http://code.google.com/p/cssjanus/source/browse/trunk/cssjanus.py * License of original code: http://code.google.com/p/cssjanus/source/browse/trunk/LICENSE * @author Khanh Le * */ require_once 'csslex.php'; class JACSSJanus { // Patterns defined as null are built dynamically by buildPatterns() private static $patterns = array( ); public static function getPatterns () { self::buildPatterns(); return self::$patterns; } /** * Build patterns we can't define above because they depend on other patterns. */ private static function buildPatterns() { //increase the backtrack limit @ini_set('pcre.backtrack_limit', '2M'); if ( isset( self::$patterns['token_delimiter'] ) ) { // Patterns have already been built return; } $csslex = new CSSLEX; $patterns =& self::$patterns; $patterns['token_delimiter'] = '`'; $patterns['tmp_token'] = sprintf('%sTMP%s', $patterns['token_delimiter'], $patterns['token_delimiter']); $patterns['token_lines'] = sprintf('%sj%s', $patterns['token_delimiter'], $patterns['token_delimiter']); # global constant text strings for css value matches. $patterns['ltr'] = 'ltr'; $patterns['rtl'] = 'rtl'; $patterns['left'] = 'left'; $patterns['right'] = 'right'; # this is a lookbehind match to ensure that we don't replace instances # of our string token (left, rtl, etc...) if there's a letter in front of it. # specifically, this prevents replacements like 'background: url(bright.png)'. $patterns['lookbehind_not_letter'] = '(?<![a-za-z])'; # this is a lookahead match to make sure we don't replace left and right # in actual classnames, so that we don't break the html/css dependencies. # read literally, it says ignore cases where the word left, for instance, is # directly followed by valid classname characters and a curly brace. # ex: .column-left {float: left} will become .column-left {float: right} $patterns['lookahead_not_open_brace'] = sprintf('(?!(?:%s|%s|%s|#|\:|\.|\,|\+|]|=|>)*?(\,|{))', $csslex->nmchar, $patterns['token_lines'], $csslex->space); # these two lookaheads are to test whether or not we are within a # background: url(here) situation. # ref: http://www.w3.org/tr/css21/syndata.html#uri $patterns['valid_after_uri_chars'] = sprintf("[\'\"]?%s", $csslex->whitespace); $patterns['lookahead_not_closing_paren'] = sprintf("(?!%s?%s\))", $csslex->url_chars, $patterns['valid_after_uri_chars']); $patterns['lookahead_for_closing_paren'] = sprintf("(?=%s?%s\))", $csslex->url_chars, $patterns['valid_after_uri_chars']); # compile a regex to swap left and right values in 4 part notations. # we need to match negatives and decimal numeric values. # the case of border-radius is extra complex, so we handle it separately below. # ex. 'margin: .25em -2px 3px 0' becomes 'margin: .25em 0 3px -2px'. $patterns['possibly_negative_quantity'] = sprintf('((?:-?%s)|(?:inherit|auto))', $csslex->quantity); $patterns['possibly_negative_quantity_space'] = sprintf('%s%s%s', $patterns['possibly_negative_quantity'], $csslex->space, $csslex->whitespace); $patterns['four_notation_quantity_re'] = sprintf('/%s%s%s%s/i', $patterns['possibly_negative_quantity_space'], $patterns['possibly_negative_quantity_space'], $patterns['possibly_negative_quantity_space'], $patterns['possibly_negative_quantity'] ); $patterns['color'] = sprintf('(%s|%s)', $csslex->name, $csslex->hash); $patterns['color_space'] = sprintf('%s%s', $patterns['color'], $csslex->space); $patterns['four_notation_color_re'] = sprintf('/(-color%s:%s)%s%s%s(%s)/i', $csslex->whitespace, $csslex->whitespace, $patterns['color_space'], $patterns['color_space'], $patterns['color_space'], $patterns['color'] ); # border-radius is very different from usual 4 part notation: abcd should # change to badc (while it would be adcb in normal 4 part notation), abc # should change to babc, and ab should change to ba $patterns['border_radius_re'] = sprintf('/((?:%s)?)border-radius(%s:%s)' .'(?:%s)?(?:%s)?(?:%s)?(?:%s)' .'(?:%s\/%s(?:%s)?(?:%s)?(?:%s)?(?:%s))?/i',$csslex->ident, $csslex->whitespace, $csslex->whitespace, $patterns['possibly_negative_quantity_space'], $patterns['possibly_negative_quantity_space'], $patterns['possibly_negative_quantity_space'], $patterns['possibly_negative_quantity'], $csslex->whitespace, $csslex->whitespace, $patterns['possibly_negative_quantity_space'], $patterns['possibly_negative_quantity_space'], $patterns['possibly_negative_quantity_space'], $patterns['possibly_negative_quantity'] ); # compile the cursor resize regexes $patterns['cursor_east_re'] = '/' . $patterns['lookbehind_not_letter'] . '([ns]?)e-resize/'; $patterns['cursor_west_re'] = '/' . $patterns['lookbehind_not_letter'] . '([ns]?)w-resize/'; # matches the condition where we need to replace the horizontal component # of a background-position value when expressed in horizontal percentage. # had to make two regexes because in the case of position-x there is only # one quantity, and otherwise we don't want to match and change cases with only # one quantity. $patterns['bg_horizontal_percentage_re'] = sprintf('/background(-position)?(%s:%s)' .'([^%%]*?)(%s)%%' .'(%s(?:%s|top|center|bottom))/', $csslex->whitespace, $csslex->whitespace, $csslex->num, $csslex->whitespace, $patterns['possibly_negative_quantity'] ); $patterns['bg_horizontal_percentage_x_re'] = sprintf('/background-position-x(%s:%s)(%s)%%/', $csslex->whitespace, $csslex->whitespace, $csslex->num); # non-percentage units used for css lengths $patterns['length_unit'] = '(?:em|ex|px|cm|mm|in|pt|pc)'; # to make sure the lone 0 is not just starting a number (like "02") or a percentage like ("0 %"); $patterns['lookahead_end_of_zero'] = sprintf('(?![0-9]|%s%%)', $csslex->whitespace); # a length with a unit specified. matches "0" too, as it's a length, not a percentage. $patterns['length'] = sprintf('(?:-?%s(?:%s%s)|0+%s)', $csslex->num, $csslex->whitespace, $patterns['length_unit'], $patterns['lookahead_end_of_zero']); # zero length. used in the replacement functions. $patterns['zero_length'] = sprintf('/(?:-?0+(?:%s%s)|0+%s)$/', $csslex->whitespace, $patterns['length_unit'], $patterns['lookahead_end_of_zero']); # matches background, background-position, and background-position-x # properties when using a css length for its horizontal positioning. $patterns['bg_horizontal_length_re'] = sprintf('/background(-position)?(%s:%s)' .'((?:.+?%s+)??)(%s)' .'((?:%s+)(?:%s|top|center|bottom))/', $csslex->whitespace, $csslex->whitespace, $csslex->space, $patterns['length'], $csslex->space, $patterns['possibly_negative_quantity']); $patterns['bg_horizontal_length_x_re'] = sprintf('/background-position-x(%s:%s)(%s)/', $csslex->whitespace, $csslex->whitespace, $patterns['length']); # matches the opening of a body selector. $patterns['body_selector'] = sprintf('body%s{%s', $csslex->whitespace, $csslex->whitespace); # matches anything up until the closing of a selector. $patterns['chars_within_selector'] = '[^\}]*?'; # matches the direction property in a selector. $patterns['direction_re'] = sprintf('direction%s:%s', $csslex->whitespace, $csslex->whitespace); # these allow us to swap "ltr" with "rtl" and vice versa only within the # body selector and on the same line. $patterns['body_direction_ltr_re'] = sprintf('/(%s)(%s)(%s)(ltr)/i', $patterns['body_selector'], $patterns['chars_within_selector'], $patterns['direction_re'] ); $patterns['body_direction_rtl_re'] = sprintf('/(%s)(%s)(%s)(rtl)/i', $patterns['body_selector'], $patterns['chars_within_selector'], $patterns['direction_re'] ); # allows us to swap "direction:ltr" with "direction:rtl" and # vice versa anywhere in a line. $patterns['direction_ltr_re'] = sprintf('/%s(ltr)/', $patterns['direction_re']); $patterns['direction_rtl_re'] = sprintf('/%s(rtl)/', $patterns['direction_re']); # we want to be able to switch left with right and vice versa anywhere # we encounter left/right strings, except inside the background:url(). the next # two regexes are for that purpose. we have alternate in_url versions of the # regexes compiled in case the user passes the flag that they do # actually want to have left and right swapped inside of background:urls. $patterns['left_re'] = sprintf('/%s((?:top|bottom)?)(%s)%s%s/i', $patterns['lookbehind_not_letter'], $patterns['left'], $patterns['lookahead_not_closing_paren'], $patterns['lookahead_not_open_brace'] ); $patterns['right_re'] = sprintf('/%s((?:top|bottom)?)(%s)%s%s/i', $patterns['lookbehind_not_letter'], $patterns['right'], $patterns['lookahead_not_closing_paren'], $patterns['lookahead_not_open_brace']); $patterns['left_in_url_re'] = sprintf('/%s(%s)%s/i', $patterns['lookbehind_not_letter'], $patterns['left'], $patterns['lookahead_for_closing_paren']); $patterns['right_in_url_re'] = sprintf('/%s(%s)%s/i', $patterns['lookbehind_not_letter'], $patterns['right'], $patterns['lookahead_for_closing_paren']); $patterns['ltr_in_url_re'] = sprintf('/%s(%s)%s/i', $patterns['lookbehind_not_letter'], $patterns['ltr'], $patterns['lookahead_for_closing_paren']); $patterns['rtl_in_url_re'] = sprintf('/%s(%s)%s/i', $patterns['lookbehind_not_letter'], $patterns['rtl'], $patterns['lookahead_for_closing_paren']); $patterns['comment_re'] = sprintf('/(%s)/i', $csslex->comment); $patterns['noflip_token'] = '\@noflip'; # the noflip_token inside of a comment. for now, this requires that comments # be in the input, which means users of a css compiler would have to run # this script first if they want this functionality. $patterns['noflip_annotation'] = sprintf('\/\*%s%s%s\*\/', $csslex->whitespace, $patterns['noflip_token'], $csslex->whitespace); # after a noflip_annotation, and within a class selector, we want to be able # to set aside a single rule not to be flipped. we can do this by matching # our noflip annotation and then using a lookahead to make sure there is not # an opening brace before the match. $patterns['noflip_single_re'] = sprintf('/(%s%s[^;}]+;?)/i', $patterns['noflip_annotation'], $patterns['lookahead_not_open_brace']); # after a noflip_annotation, we want to grab anything up until the next } which # means the entire following class block. this will prevent all of its # declarations from being flipped. $patterns['noflip_class_re'] = sprintf('/(%s%s})/i', $patterns['noflip_annotation'], $patterns['chars_within_selector']); # border-radis properties and their values $patterns['border_radius_tokenizer_re'] = sprintf('/((?:%s)?border-radius%s:[^;}]+;?)/i', $csslex->ident, $csslex->whitespace); $patterns['gradient_re'] = sprintf('/%s[\.-]gradient%s\(/i', $csslex->ident, $csslex->whitespace); } /** * Transform an LTR stylesheet to RTL * @param $css String: stylesheet to transform * @param $swapLtrRtlInURL Boolean: If true, swap 'ltr' and 'rtl' in URLs * @param $swapLeftRightInURL Boolean: If true, swap 'left' and 'right' in URLs * @return Transformed stylesheet */ public static function transform( $css, $swapLtrRtlInURL = false, $swapLeftRightInURL = false ) { self::buildPatterns(); // We wrap tokens in ` , not ~ like the original implementation does. // This was done because ` is not a legal character in CSS and can only // occur in URLs, where we escape it to %60 before inserting our tokens. $css = str_replace( self::$patterns['token_delimiter'], '%60', $css ); // Tokenize single line rules with /* @noflip */ $noFlipSingle = new CSSJanus_Tokenizer( self::$patterns['noflip_single_re'], '`NOFLIP_SINGLE`' ); $css = $noFlipSingle->tokenize( $css ); // Tokenize class rules with /* @noflip */ $noFlipClass = new CSSJanus_Tokenizer( self::$patterns['noflip_class_re'], '`NOFLIP_CLASS`' ); $css = $noFlipClass->tokenize( $css ); // Tokenize comments $comments = new CSSJanus_Tokenizer( self::$patterns['comment_re'], '`C`' ); $css = $comments->tokenize( $css ); # Tokenize gradients since we don't want to mirror the values inside //$comments = new CSSJanus_Tokenizer( self::$patterns['comment_re']GradientMatcher(), '`GRADIENT`' ); //$css = $comments->tokenize( $css ); // LTR->RTL fixes start here $css = self::FixBodyDirectionLtrAndRtl( $css ); if ( $swapLtrRtlInURL ) { $css = self::fixLtrRtlInURL( $css ); } if ( $swapLeftRightInURL ) { $css = self::fixLeftRightInURL( $css ); } $css = self::fixLeftAndRight( $css ); $css = self::fixCursorProperties( $css ); $css = self::fixBorderRadius( $css ); # Since FourPartNotation conflicts with BorderRadius, we tokenize border-radius properties here. $border_radius_tokenizer = new CSSJanus_Tokenizer( self::$patterns['border_radius_tokenizer_re'], '`BORDER_RADIUS`' ); $css = $border_radius_tokenizer->tokenize( $css ); $css = self::fixFourPartNotation( $css ); $css = $border_radius_tokenizer->detokenize( $css ); $css = self::fixBackgroundPosition( $css ); // Detokenize stuff we tokenized before $css = $comments->detokenize( $css ); $css = $noFlipClass->detokenize( $css ); $css = $noFlipSingle->detokenize( $css ); return $css; } /** * Replaces ltr with rtl and vice versa ONLY in the body direction. * */ private static function FixBodyDirectionLtrAndRtl( $css ) { $css = preg_replace( self::$patterns['body_direction_ltr_re'], '\1\2\3' . self::$patterns['tmp_token'], $css ); $css = preg_replace( self::$patterns['body_direction_rtl_re'], '\1\2\3' . self::$patterns['ltr'], $css ); $css = str_replace( self::$patterns['tmp_token'], self::$patterns['rtl'], $css ); return $css; } /** * Flip rules like left: , padding-right: , etc. */ private static function fixLeftAndRight( $css ) { $css = preg_replace( self::$patterns['left_re'], '\1' . self::$patterns['tmp_token'], $css ); $css = preg_replace( self::$patterns['right_re'], '\1' . self::$patterns['left'], $css ); $css = str_replace( self::$patterns['tmp_token'], self::$patterns['right'], $css ); return $css; } /** * Replace 'left' with 'right' and vice versa in background URLs */ private static function fixleftrightinurl( $css ) { $css = preg_replace( self::$patterns['left_in_url_re'], self::$patterns['tmp_token'], $css ); $css = preg_replace( self::$patterns['right_in_url_re'], self::$patterns['left'], $css ); $css = str_replace( self::$patterns['tmp_token'], self::$patterns['right'], $css ); return $css; } /** * replace 'ltr' with 'rtl' and vice versa in background urls */ private static function fixltrrtlinurl( $css ) { $css = preg_replace( self::$patterns['ltr_in_url_re'], self::$patterns['tmp_token'], $css ); $css = preg_replace( self::$patterns['rtl_in_url_re'], self::$patterns['ltr'], $css ); $css = str_replace( self::$patterns['tmp_token'], self::$patterns['rtl'], $css ); return $css; } /** * flip east and west in rules like cursor: nw-resize; */ private static function fixcursorproperties( $css ) { $css = preg_replace( self::$patterns['cursor_east_re'], '\1' . self::$patterns['tmp_token'], $css ); $css = preg_replace( self::$patterns['cursor_west_re'], '\1e-resize', $css ); $css = str_replace( self::$patterns['tmp_token'], 'w-resize', $css ); return $css; } /** * Fixes border-radius and its browser-specific variants. */ private static function fixBorderRadius( $css ) { //echo self::$patterns['border_radius_re']; die(); $css = preg_replace_callback(self::$patterns['border_radius_re'], array( 'self', 'reorderBorderRadius' ), $css ); return $css; } /** * Fixes border-radius and its browser-specific variants. */ private static function reorderBorderRadius( $matches ) { $first_group = self::reorderBorderRadiusPart(array_slice ($matches, 3, 4)); $second_group = self::reorderBorderRadiusPart(array_slice ($matches, 7)); if ($second_group == '') return sprintf('%sborder-radius%s%s', $matches[1], $matches[2], $first_group); else return sprintf('%sborder-radius%s%s / %s', $matches[1], $matches[2], $first_group, $second_group); } /** * Fixes border-radius and its browser-specific variants. */ private static function reorderBorderRadiusPart( $ps ) { # Remove any piece which may be 'None' $part = array(); foreach ($ps as $p) { if ($p != '') $part[] = $p; } if (count($part) == 4) { return sprintf('%s %s %s %s', $part[1], $part[0], $part[3], $part[2]); } elseif (count($part) == 3) { return sprintf('%s %s %s %s', $part[1], $part[0], $part[1], $part[2]); } elseif (count($part) == 2) { return sprintf('%s %s', $part[1], $part[0]); } elseif (count($part) == 1) { return $part[0]; } elseif (count($part) == 0) { return ''; } else { return null; } } /** * Swap the second and fourth parts in four-part notation rules like * padding: 1px 2px 3px 4px; * * Unlike the original implementation, this function doesn't suffer from * the bug where whitespace is not preserved when flipping four-part rules * and four-part color rules with multiple whitespace characters between * colors are not recognized. * See http://code.google.com/p/cssjanus/issues/detail?id=16 */ private static function fixFourPartNotation( $css ) { $css = preg_replace( self::$patterns['four_notation_quantity_re'], '\1 \4 \3 \2', $css ); $css = preg_replace( self::$patterns['four_notation_color_re'], '\1\2 \5 \4 \3', $css ); return $css; } /** * Flip horizontal background percentages. */ private static function fixBackgroundPosition( $css ) { $css = preg_replace_callback( self::$patterns['bg_horizontal_percentage_re'], array( 'self', 'calculateNewBackgroundPosition' ), $css ); $css = preg_replace_callback( self::$patterns['bg_horizontal_percentage_x_re'], array( 'self', 'calculateNewBackgroundPositionX' ), $css ); $css = preg_replace_callback( self::$patterns['bg_horizontal_length_re'], array( 'self', 'calculateNewBackgroundLengthPosition' ), $css ); $css = preg_replace_callback( self::$patterns['bg_horizontal_length_x_re'], array( 'self', 'calculateNewBackgroundLengthPositionX' ), $css ); return $css; } /** * Callback for calculateNewBackgroundPosition() */ private static function calculateNewBackgroundPosition( $matches ) { # The flipped value is the offset from 100% $new_x = 100-intval($matches[4]); # Since m.group(1) may very well be None type and we need a string.. if ($matches[1]){ $position_string = $matches[1]; } else { $position_string = ''; } return sprintf('background%s%s%s%s%%%s', $position_string, $matches[2], $matches[3], $new_x, $matches[5]); } /** * Callback for calculateNewBackgroundPosition() */ private static function calculateNewBackgroundPositionX( $matches ) { # The flipped value is the offset from 100% $new_x = 100-intval($matches[2]); return sprintf('background-position-x%s%s%%', $matches[1], $new_x); } /** * Fixes horizontal background-position lengths. * Return: A string with the horizontal background position set to 100%, if zero. */ private static function calculateNewBackgroundLengthPosition( $matches ) { # return original if error if ($matches[4]) { return $matches[0]; } # Since m.group(1) may very well be None type and we need a string.. if ($matches[1]){ $position_string = $matches[1]; } else { $position_string = ''; } return sprintf('background%s%s%s100%%%s', $position_string, $matches[2], $matches[3], $matches[5]); } /** * Fixes background-position-x lengths * Return: A string with the background-position-x set to 100%, if zero. */ private static function calculateNewBackgroundLengthPositionX( $matches ) { # return original if error if ($matches[2]) { return $matches[0]; } return sprintf('background-position-x%s100%%', $matches[1]); } } /** * Utility class used by CSSJanus that tokenizes and untokenizes things we want * to protect from being janused. * @author Roan Kattouw */ class CSSJanus_Tokenizer { private $regex, $token; private $originals; /** * Constructor * @param $regex string Regular expression whose matches to replace by a token. * @param $token string Token */ public function __construct( $regex, $token ) { $this->regex = $regex; $this->token = $token; $this->originals = array(); } /** * Replace all occurrences of $regex in $str with a token and remember * the original strings. * @param $str String to tokenize * @return string Tokenized string */ public function tokenize( $str ) { return preg_replace_callback( $this->regex, array( $this, 'tokenizeCallback' ), $str ); } private function tokenizeCallback( $matches ) { $this->originals[] = $matches[0]; return $this->token; } /** * Replace tokens with their originals. If multiple strings were tokenized, it's important they be * detokenized in exactly the SAME ORDER. * @param $str String: previously run through tokenize() * @return string Original string */ public function detokenize( $str ) { // PHP has no function to replace only the first occurrence or to // replace occurrences of the same string with different values, // so we use preg_replace_callback() even though we don't really need a regex return preg_replace_callback( '/' . preg_quote( $this->token, '/' ) . '/', array( $this, 'detokenizeCallback' ), $str ); } private function detokenizeCallback( $matches ) { $retval = current( $this->originals ); next( $this->originals ); return $retval; } }PK Y~!]*=�5& & csslex.phpnu &1i� PK Y~!]��Ƙ�= �= ` test.phpnu &1i� PK Y~!]=�� j j ?M ja.cssjanus.phpnu &1i� PK � ��
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка