Вход Регистрация
Файл: library/XenForo/BbCode/Formatter/Wysiwyg.php
Строк: 338
<?php

class XenForo_BbCode_Formatter_Wysiwyg extends XenForo_BbCode_Formatter_Base
{
    protected 
$_undisplayableTags = array('quote''plain''media''spoiler''attach''user''code''php''html');

    protected 
$_tagReplacements = array(
        
'u' => array(
            
'replace' => array('<u>''</u>'),
        ),
        
's' => array(
            
'replace' => array('<strike>''</strike>'),
        ),
        
'font' => array(
            
'replace' => array('<font face="%s">''</font>')
        )
    );

    protected 
$_imageTemplate '<img src="%1$s" class="bbCodeImage wysiwygImage" alt="" unselectable="on" />';

    protected 
$_smilieTemplate '<img src="%1$s" class="mceSmilie" alt="%2$s" unselectable="on" />';

    protected 
$_smilieSpriteTemplate '<img src="styles/default/xenforo/clear.png" class="mceSmilieSprite mceSmilie%1$d" alt="%2$s" unselectable="on" unselectable="on" />';

    public function 
getTags()
    {
        if (
$this->_tags !== null)
        {
            return 
$this->_tags;
        }

        
$tags parent::getTags();

        foreach (
$tags AS $tagName => &$tag)
        {
            if (
in_array($tagName$this->_undisplayableTags))
            {
                
$tag['callback'] = array($this'renderTagUndisplayable');
                unset(
$tag['trimLeadingLinesAfter'], $tag['stopLineBreakConversion']);
            }
            else if (isset(
$this->_tagReplacements[$tagName]))
            {
                
$tag array_merge($tag$this->_tagReplacements[$tagName]);
                if (isset(
$this->_tagReplacements['replace']))
                {
                    unset(
$tag['callback']);
                }
            }
        }

        return 
$tags;
    }

    public function 
addCustomTags(array $tags)
    {
        
// do nothing -- can't do this in the WYSIWYG editor
    
}

    protected 
$_tagFilterMatched;
    protected 
$_blockTags '<p|<div|<blockquote|<ul|<ol';
    protected 
$_blockTagsEnd;

    public function 
filterFinalOutput($output)
    {
        
$debug false;

        
$blockTags $this->_blockTags;
        
$blockTagsEnd strtr($blockTags, array(
            
'<' => '</',
            
'|' => '>|'
        
)) . '>';
        
$this->_blockTagsEnd $blockTagsEnd;

        if (
$debug) { echo '<hr /><b>Original:</b><br />'nl2br(htmlspecialchars($output)); }

        
// process first to last - inner tags will have lower numbers and
        // we need to keep the same nesting order
        
for ($i 1$i <= $this->_tagCounter$i++)
        {
            
$this->_tagFilterMatched false;
            
$output preg_replace_callback(
                
'#<(xf' $i ':((?>[a-z0-9-]+?)))([^>]*)(?<!/)>((?:(?>[^<]*?)|<)*)</\1>#siU',
                array(
$this'_replaceTagFilter'),
                
$output
            
);
            if (!
$this->_tagFilterMatched)
            {
                
$output strtr($output, array(
                    
'<xf' $i ':' => '<',
                    
'</xf' $i ':' => '</'
                
));
            }

            
//if ($debug) { echo '<hr />'. nl2br(htmlspecialchars($output)); }
        
}
        
$this->_tagCounter 0;

        if (
$debug) { echo '<hr /><b>Pre-break:</b><br />'nl2br(htmlspecialchars($output)); }

        
$output preg_replace('#s*<break-start />(?>s*)(?!' $blockTags '|' $blockTagsEnd '|$)#i', ($debug "n" '') . "<p>"$output);
        
$output preg_replace('#s*<break-start />#i'''$output);
        
$output preg_replace('#(' $blockTagsEnd ')s*<break />#i'"\1"$output);
        
$output preg_replace('#<break />s*(' $blockTags ')#i'"</p>" . ($debug "n" '') . "\1"$output);
        
$output preg_replace('#<break />s*#i'"</p>" . ($debug "n" '') . "<p>"$output);

        if (
$debug) { echo '<hr /><b>Post-break:</b><br />'nl2br(htmlspecialchars($output)); }

        
$output trim($output);
        if (!
preg_match('#^(' $blockTags ')#i'$output))
        {
            
$output '<p>' $output;
        }
        if (!
preg_match('#(' $blockTagsEnd ')$#i'$output))
        {
            
$output .= '</p>';
        }

        
$output preg_replace_callback('#(<p[^>]*>)(.*)(</p>)#siU',
            array(
$this'_replaceEmptyContent'), $output
        
);
        
$output str_replace('<empty-content />'''$output); // just in case

        
if ($debug) { echo '<hr /><b>Final:</b><br />'nl2br(htmlspecialchars($output)); }

        return 
$output;
    }

    protected function 
_replaceTagFilter(array $match)
    {
        
$this->_tagFilterMatched true;

        
$open "<$match[2]$match[3]>";
        
$close "</$match[2]>";

        
$inner $match[4];
        
$inner preg_replace('#(<break />s*)(<break />|$)#i''\1<empty-content />\2'$inner);

        if (
preg_match('#^(' $this->_blockTags ')#i'$open))
        {
            
$inner preg_replace('#<break-start />(?>s*)(?!' $this->_blockTags '|' $this->_blockTagsEnd '|$)#i'"\0$open"$inner);
            
$inner preg_replace('#<break />(?>s*)(?!' $this->_blockTags ')#i'"$close\0$open"$inner);
        }
        else
        {
            
$inner preg_replace('#<break />s*((' $this->_blockTags ')[^>]*>)?#i'"$close\0$open"$inner);
        }

        return 
$open $inner $close;
    }

    protected function 
_replaceEmptyContent(array $match)
    {
        
$emptyParaText = (XenForo_Visitor::isBrowsingWith('ie') ? '&nbsp;' '<br />');

        if (
strlen(trim($match[2])) == 0)
        {
            
// paragraph is actually empty
            
$output $emptyParaText;
        }
        else
        {
            
$test strip_tags($match[2], '<empty-content><img><br><hr>');
            if (
trim($test) == '<empty-content />')
            {
                
$output str_replace('<empty-content />'$emptyParaText$match[2]);
            }
            else
            {
                
// we had a break
                
$output str_replace('<empty-content />'''$match[2]);
            }
        }

        return 
$match[1] . $output $match[3];
    }

    public function 
filterString($string, array $rendererStates)
    {
        if (empty(
$rendererStates['stopSmilies']))
        {
            
$string $this->replaceSmiliesInText($string'htmlspecialchars');
        }
        else
        {
            
$string htmlspecialchars($string);
        }

        
$string str_replace("t"'    '$string);

        
// doing this twice handles situations with 3 spaces
        
$string str_replace('  ''&nbsp; '$string);
        
$string str_replace('  ''&nbsp; '$string);

        if (empty(
$rendererStates['stopLineBreakConversion']))
        {
            if (!empty(
$rendererStates['inList']))
            {
                
$string nl2br($string);
            }
            else
            {
                
$string preg_replace('/rn|n|r/'"<break />n"$string);
            }
        }

        return 
$string;
    }

    public function 
renderTagUrl(array $tag, array $rendererStates)
    {
        
$rendererStates['shortenUrl'] = false;
        return 
parent::renderTagUrl($tag$rendererStates);
    }

    public function 
renderTagSize(array $tag, array $rendererStates)
    {
        
$text $this->renderSubTree($tag['children'], $rendererStates);
        if (
trim($text) === '')
        {
            return 
$text;
        }

        
$size $this->getTextSize($tag['option']);
        if (
$size)
        {
            
$fontSize false;
            switch (
$size)
            {
                case 
'xx-small':
                case 
'9px':
                    
$fontSize 1; break;

                case 
'x-small':
                case 
'10px':
                    
$fontSize 2; break;

                case 
'small':
                case 
'12px':
                    
$fontSize 3; break;

                case 
'medium':
                case 
'15px':
                case 
'100%':
                    
$fontSize 4; break;

                case 
'large':
                case 
'18px':
                    
$fontSize 5; break;

                case 
'x-large':
                case 
'22px':
                    
$fontSize 6; break;

                case 
'xx-large':
                case 
'26px':
                    
$fontSize 7; break;
            }

            if (
$fontSize)
            {
                return 
$this->_wrapInHtml('<font size="' htmlspecialchars($fontSize) . '">''</font>'$text);
            }
            else
            {
                return 
$this->_wrapInHtml('<span style="font-size: ' htmlspecialchars($size) . '">''</span>'$text);
            }
        }
        else
        {
            return 
$text;
        }
    }

    public function 
renderTagAlign(array $tag, array $rendererStates)
    {
        
$text $this->renderSubTree($tag['children'], $rendererStates);

        switch (
strtolower($tag['tag']))
        {
            case 
'left':
            case 
'center':
            case 
'right':
                return 
$this->_wrapInHtml('<p style="text-align: ' $tag['tag'] . '">''</p>'$text) . "<break-start />n";

            default:
                return 
$this->_wrapInHtml('<p>''</p>'$text) . "<break-start />n";
        }
    }

    public function 
renderTagList(array $tag, array $rendererStates)
    {
        
$wasInList = !empty($rendererStates['inList']);
        
$rendererStates['inList'] = true;

        
$output parent::renderTagList($tag$rendererStates);
        
$output preg_replace('#s*<break-start />s*#i'"n"$output);
        if (!
$wasInList)
        {
            
$output "<break-start />n$output<break-start />n";
        }

        return 
$output;
    }

    public function 
renderTagIndent(array $tag, array $rendererStates)
    {
        
$wasInIndent = !empty($rendererStates['inIndent']);
        
$rendererStates['inIndent'] = true;

        
$text $this->renderSubTree($tag['children'], $rendererStates);
        if (
trim($text) === '')
        {
            
$text '<br />';
        }

        if (isset(
$tag['option']))
        {
            
$amount intval($tag['option']);
            if (
$amount 10)
            {
                
$amount 10;
            }
        }
        else
        {
            
$amount 1;
        }

        
$prepend '';
        
$append '';
        for (
$i 1$i <= $amount$i++)
        {
            
$prepend .= '<blockquote>';
            
$append '</blockquote>' $append;
        }

        if (
strpos($text'<blockquote') === false)
        {
            
$text '<p>' $text '</p>';
        }

        
$output $prepend $text $append;
        if (!
$wasInIndent)
        {
            
$output .= "<break-start />n";
        }

        return 
$output;
    }

    protected function 
_renderListOutput($listType, array $elements)
    {
        
$output "<$listType>";
        foreach (
$elements AS $element)
        {
            
$output .= "n<li>$element</li>";
        }
        
$output .= "n</$listType>";

        return 
$output;
    }


    public function 
renderTagUndisplayable(array $tag, array $rendererStates)
    {
        return 
$this->renderInvalidTag($tag$rendererStates);
    }

    protected 
$_tagCounter 0;

    protected function 
_wrapInHtml($prepend$append$text$option null)
    {
        
$this->_tagCounter++;

        
$replace = array(
            
'</' => '</xf' $this->_tagCounter ':',
            
'<' => '<xf' $this->_tagCounter ':'
        
);
        
$prepend strtr($prepend$replace);
        
$append strtr($append$replace);

        if (
$option === null)
        {
            return 
$prepend $text $append;
        }
        else
        {
            return 
sprintf($prepend$option) . $text sprintf($append$option);
        }
    }

    protected function 
_handleImageProxyOption($url)
    {
        return 
$url;
    }

    protected function 
_handleLinkProxyOption($url$linkType)
    {
        return 
$url;
    }
}
Онлайн: 2
Реклама