r20151203

Signed-off-by: Flashwave <me@flash.moe>
This commit is contained in:
flash 2015-12-03 19:41:14 +01:00
parent 6f08ef8236
commit d6a3327d59
14 changed files with 215 additions and 93 deletions

View file

@ -16,58 +16,53 @@ use JBBCode\CodeDefinitionBuilder;
class BBcode
{
// Parser container
private $bbcode;
private static $bbcode = null;
// Constructor
public function __construct($text = null)
public static function init()
{
// Create new parser class
$this->bbcode = new Parser();
self::$bbcode = new Parser();
// Add the standard definitions
$this->loadStandardCodes();
// Immediately parse the text if set
if ($text != null) {
$this->bbcode->parse($text);
}
self::loadStandardCodes();
}
// Add basic bbcodes
public function loadStandardCodes()
public static function loadStandardCodes()
{
// Add the standard definitions
$this->bbcode->addCodeDefinitionSet(new DefaultCodeDefinitionSet());
self::$bbcode->addCodeDefinitionSet(new DefaultCodeDefinitionSet());
// Header tag
$builder = new CodeDefinitionBuilder('header', '<h1>{param}</h1>');
$this->bbcode->addCodeDefinition($builder->build());
self::$bbcode->addCodeDefinition($builder->build());
// Strike tag
$builder = new CodeDefinitionBuilder('s', '<del>{param}</del>');
$this->bbcode->addCodeDefinition($builder->build());
self::$bbcode->addCodeDefinition($builder->build());
// Spoiler tag
$builder = new CodeDefinitionBuilder('spoiler', '<span class="spoiler">{param}</span>');
$this->bbcode->addCodeDefinition($builder->build());
self::$bbcode->addCodeDefinition($builder->build());
// Box tag
$builder = new CodeDefinitionBuilder('box', '<div class="spoiler-box-container"><div class="spoiler-box-title" onclick="toggleClass(this.parentNode.children[1], \'hidden\');">Click to open</div><div class="spoiler-box-content hidden">{param}</div></div>');
$this->bbcode->addCodeDefinition($builder->build());
self::$bbcode->addCodeDefinition($builder->build());
// Box tag
$builder = new CodeDefinitionBuilder('box', '<div class="spoiler-box-container"><div class="spoiler-box-title" onclick="toggleClass(this.parentNode.children[1], \'hidden\');">{option}</div><div class="spoiler-box-content hidden">{param}</div></div>');
$builder->setUseOption(true);
$this->bbcode->addCodeDefinition($builder->build());
self::$bbcode->addCodeDefinition($builder->build());
// Quote tag
$builder = new CodeDefinitionBuilder('quote', '<blockquote><div class="quote">{param}</div></blockquote>');
$this->bbcode->addCodeDefinition($builder->build());
$builder = new CodeDefinitionBuilder('quote', '<blockquote><div class="quotee">Quote</div><div class="quote">{param}</div></blockquote>');
self::$bbcode->addCodeDefinition($builder->build());
// Quote tag
$builder = new CodeDefinitionBuilder('quote', '<blockquote><div class="quotee">{option} wrote:</div><div class="quote">{param}</div></blockquote>');
$builder = new CodeDefinitionBuilder('quote', '<blockquote><div class="quotee">{option} wrote</div><div class="quote">{param}</div></blockquote>');
$builder->setUseOption(true);
$this->bbcode->addCodeDefinition($builder->build());
self::$bbcode->addCodeDefinition($builder->build());
// Add special definitions (PHP files MUST have the same name as the definition class
foreach (glob(ROOT . '_sakura/components/BBcodeDefinitions/*.php') as $ext) {
@ -83,20 +78,30 @@ class BBcode
$className = __NAMESPACE__ . '\\' . $ext;
// Add the BBcode definition
$this->bbcode->addCodeDefinition(new $className);
self::$bbcode->addCodeDefinition(new $className);
}
}
// Set text
public function text($text)
public static function text($text)
{
$this->bbcode->parse($text);
// Check if $bbcode is still null
if (self::$bbcode == null) {
self::init();
}
self::$bbcode->parse($text);
}
// Get as HTML
public function toHTML()
public static function toHTML($text = null)
{
$parsed = nl2br($this->bbcode->getAsHtml());
// Check if text isn't null
if ($text !== null) {
self::text($text);
}
$parsed = nl2br(self::$bbcode->getAsHtml());
$parsed = Main::fixCodeTags($parsed);
$parsed = Main::parseEmotes($parsed);
@ -105,14 +110,24 @@ class BBcode
}
// Get as BBmarkup
public function toEditor()
public static function toEditor($text = null)
{
return $this->bbcode->getAsBBCode();
// Check if text isn't null
if ($text !== null) {
self::text($text);
}
return self::$bbcode->getAsBBCode();
}
// Get as plaintext
public function toPlain()
public static function toPlain($text = null)
{
return $this->bbcode->getAsText();
// Check if text isn't null
if ($text !== null) {
self::text($text);
}
return self::$bbcode->getAsText();
}
}

View file

@ -376,6 +376,5 @@ class mysql
public function lastInsertID($name = null)
{
return $this->sql->lastInsertID($name);
;
}
}

View file

@ -209,7 +209,7 @@ class Forums
'user' => (new User($post['poster_id'])),
'elapsed' => Main::timeElapsed($post['post_time']),
'is_op' => ($post['poster_id'] == $firstPost['poster_id'] ? '1' : '0'),
'parsed_post' => (new BBcode($post['post_text']))->toHTML(),
'parsed_post' => BBcode::toHTML($post['post_text']),
]);
// Just in case

View file

@ -56,7 +56,7 @@ class Post
}
// Parse the markup
$this->parsed = (new BBcode(htmlentities($this->text)))->toHTML();
$this->parsed = BBcode::toHTML(htmlentities($this->text));
}
// Time elapsed since creation

View file

@ -0,0 +1,23 @@
<?php
/*
* Posting handler
*/
namespace Sakura\Forum;
use Sakura\Main;
use Sakura\Database;
use Sakura\User;
use Sakura\BBcode;
/**
* Class Posting
* @package Sakura
*/
class Posting
{
// Construct a new post action
public function __construct($forum, $thread = null) {
}
}

View file

@ -6,6 +6,7 @@
namespace Sakura\Forum;
use Sakura\Database;
use Sakura\Main;
/**
* Class Thread
@ -24,9 +25,7 @@ class Thread
public $status = 0;
public $statusChange = 0;
public $type = 0;
public $firstPost = null;
public $lastPost = null;
public $posts = [];
private $_posts = [];
// Constructor
public function __construct($threadId)
@ -47,35 +46,44 @@ class Thread
$this->statusChange = $threadRow['topic_status_change'];
$this->type = $threadRow['topic_type'];
}
// Populate the posts array
$this->posts = $this->getPosts();
// Get first post
$this->firstPost = $this->posts ? array_values($this->posts)[0] : (new Thread(0));
// And the last post
$this->lastPost = $this->posts ? end($this->posts) : (new Thread(0));
}
// Posts
public function getPosts()
public function posts()
{
// Get all rows with the thread id
$postRows = Database::fetch('posts', true, ['topic_id' => [$this->id, '=']]);
// Check if _posts is something
if (!count($this->_posts)) {
// Create a storage array
$posts = [];
// Get all rows with the thread id
$postRows = Database::fetch('posts', true, ['topic_id' => [$this->id, '=']]);
// Create new post objects for each post
foreach ($postRows as $post) {
$posts[$post['post_id']] = new Post($post['post_id']);
// Create a storage array
$posts = [];
// Create new post objects for each post
foreach ($postRows as $post) {
$posts[$post['post_id']] = new Post($post['post_id']);
}
$this->_posts = $posts;
} else {
$posts = $this->_posts;
}
// Return the post objects
return $posts;
}
// Get the opening post
public function firstPost() {
return $this->posts() ? array_values($this->_posts)[0] : (new Post(0));
}
// Get the last reply
public function lastPost() {
return $this->posts() ? end($this->_posts) : (new Post(0));
}
// Reply count
public function replyCount()
{
@ -106,7 +114,7 @@ class Thread
}
// Check if the last time the user has been here is less than the creation timestamp of the latest post
if ($track['mark_time'] < $this->lastPost->time) {
if ($track['mark_time'] < $this->lastPost()->time) {
return true;
}

View file

@ -659,11 +659,11 @@ class User
public function signature()
{
return isset($this->data['user_data']['signature']) ?
(new BBcode(
BBcode::toHTML(
base64_decode(
$this->data['user_data']['signature']
)
))->toHTML() :
) :
null;
}

View file

@ -8,7 +8,7 @@
namespace Sakura;
// Define Sakura version
define('SAKURA_VERSION', '20151202');
define('SAKURA_VERSION', '20151203');
define('SAKURA_VLABEL', 'Eminence');
define('SAKURA_COLOUR', '#6C3082');
define('SAKURA_STABLE', false);

View file

@ -12,15 +12,17 @@
</div>
<hr class="default" />
<div class="posting-bbcodes">
{% for bbcode in posting.bbcodes %}
{% if bbcode.bbcode_display %}
<button type="button" class="inputStyling small">{{ bbcode.bbcode_title }}</button>
{% endif %}
{% endfor %}
</div>
<hr class="default" />
<div class="posting-bbcode-description" id="bbcodedescr">
Hover over a styling button to view a short description of what it does.
<button onclick="insertBBcode('postingText', 'b');" type="button" title="Bold" class="inputStyling fa fa-bold" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 'i');" type="button" title="Italic" class="inputStyling fa fa-italic" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 'u');" type="button" title="Underline" class="inputStyling fa fa-underline" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 's');" type="button" title="Strikethrough" class="inputStyling fa fa-strikethrough" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 'header');" type="button" title="Header" class="inputStyling fa fa-header" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 'url');" type="button" title="Link" class="inputStyling fa fa-chain" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 'spoiler');" type="button" title="Spoiler text" class="inputStyling fa fa-minus" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 'box', true);" type="button" title="Spoiler box" class="inputStyling fa fa-square-o" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 'list');" type="button" title="List (use [*] for entries)" class="inputStyling fa fa-list" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 'img');" type="button" title="Image" class="inputStyling fa fa-picture-o" style="min-width: 0;"></button>
<button onclick="insertBBcode('postingText', 'youtube');" type="button" title="YouTube video" class="inputStyling fa fa-youtube-play" style="min-width: 0;"></button>
</div>
<hr class="default" />
<div class="posting-text">
@ -29,27 +31,11 @@
<hr class="default" />
<div class="posting-emotes">
{% for emoticon in posting.emoticons %}
<img src="{{ emoticon.emote_path }}" alt="{{ emoticon.emote_string }}" title="{{ emoticon.emote_string }}" />
<img src="{{ emoticon.emote_path }}" alt="{{ emoticon.emote_string }}" title="{{ emoticon.emote_string }}" onclick="insertText('postingText', '{{ emoticon.emote_string }}')" />
{% endfor %}
</div>
<hr class="default" />
<div class="posting-options">
<div>
<div>
<input type="checkbox" id="enableSig" {% if posting.enabledSig %}checked="checked"{% endif %}/> <label for="enableSig">Attach Signature</label>
</div>
<div>
<input type="checkbox" id="enableEmotes" checked="checked" /> <label for="enableEmotes">Parse emoticons</label>
</div>
<div>
<input type="checkbox" id="enableBBcode" checked="checked" /> <label for="enableBBcode">Parse BBcodes</label>
</div>
</div>
<div class="clear"></div>
</div>
<hr class="default" />
<div class="posting-buttons">
<input class="inputStyling" type="submit" name="preview" value="Preview" disabled="disabled" />
<input class="inputStyling" type="submit" name="post" value="Post" />
<input class="inputStyling" type="button" onclick="history.go(-1);" value="Cancel" />
</div>

View file

@ -5,18 +5,32 @@
{% set posts = thread.posts|batch(10) %}
{% if get.p and not get.page %}
{% set num = 0 %}
{% for k,v in thread.posts %}
{% if k < get.p %}
{% set num = num + 1 %}
{% endif %}
{% endfor %}
{% set num = (num / 10)|round + 1 %}
{% set get = get|merge({'page': num}) %}
{% endif %}
{% set paginationPages = posts %}
{% set paginationUrl %}{{ urls.format('FORUM_THREAD', [thread.id]) }}{% endset %}
{% block title %}{{ thread.title }}{% endblock %}
{% block css %}
<link rel="stylesheet" href="/content/libraries/highlight.css" />
<link rel="stylesheet" href="/content/libraries/highlight.css" />
{% endblock %}
{% block js %}
<script src="/content/libraries/highlight.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script src="/content/libraries/highlight.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
{% endblock %}
{% block content %}
@ -56,7 +70,7 @@
<td class="post-content">
<div class="details">
<div class="subject">
<a href="#p{{ post.id }}" class="clean">{{ post.subject }}</a>
<a href="#p{{ post.id }}" class="clean">{{ post.subject|slice(0, 50) }}{% if post.subject|length > 50 %}...{% endif %}</a>
</div>
<div class="date">
<a href="{{ urls.format('FORUM_POST', [post.id]) }}#p{{ post.id }}" class="clean" title="{{ post.time|date(sakura.dateFormat) }}">{{ post.timeElapsed }}</a>

View file

@ -3,6 +3,11 @@
*/
@charset "utf-8";
.bbcode {
line-height: 1.4;
word-wrap: break-word;
}
.bbcode h1 {
text-shadow: 0 0 5px #8364A1;
color: #614390;
@ -32,7 +37,9 @@
.bbcode blockquote > .quotee {
font-weight: bold;
border-bottom: 1px solid #9475b2;
border-right: 1px solid #9475b2;
background: #B697d4;
padding-left: .5em;
}
.bbcode blockquote > .quote {
@ -71,3 +78,15 @@
.bbcode .spoiler-box-container > .spoiler-box-content {
border-top: 1px solid #9475b2;
}
.bbcode img {
width: auto;
height: auto;
max-height: 100%;
max-width: 100%;
}
.bbcode code {
font-size: 1.1em;
}

View file

@ -1950,7 +1950,7 @@ textarea.inputStyling {
width: 100%;
border-spacing: 0;
table-layout: fixed;
word-break: break-all;
word-break: break-word;
}
.forum.viewtopic .posts td {
@ -2029,10 +2029,6 @@ textarea.inputStyling {
float: right;
}
.forum.viewtopic .posts .post-content img {
max-width: 850px;
}
.forum.viewtopic .posts .post-content .signature {
border-top: 1px solid #B19EED;
padding-top: 2px;

View file

@ -810,6 +810,68 @@ function commentReply(id, session, category, action, avatar) {
prepareAjaxForm(replyForm.id, 'Replying...');
}
// Inserting text into text box
// Borrowed from http://stackoverflow.com/questions/1064089/inserting-a-text-where-cursor-is-using-javascript-jquery
function insertText(areaId, text) {
var txtarea = document.getElementById(areaId);
var scrollPos = txtarea.scrollTop;
var strPos = 0;
var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ?
"ff" : (document.selection ? "ie" : false));
if (br == "ie") {
txtarea.focus();
var range = document.selection.createRange();
range.moveStart('character', -txtarea.value.length);
strPos = range.text.length;
}
else if (br == "ff") strPos = txtarea.selectionStart;
var front = (txtarea.value).substring(0, strPos);
var back = (txtarea.value).substring(strPos, txtarea.value.length);
txtarea.value = front + text + back;
strPos = strPos + text.length;
if (br == "ie") {
txtarea.focus();
var range = document.selection.createRange();
range.moveStart('character', -txtarea.value.length);
range.moveStart('character', strPos);
range.moveEnd('character', 0);
range.select();
}
else if (br == "ff") {
txtarea.selectionStart = strPos;
txtarea.selectionEnd = strPos;
txtarea.focus();
}
txtarea.scrollTop = scrollPos;
}
// Inserting a bbcode
function insertBBcode(textarea, tag, arg) {
var element = document.getElementById(textarea);
var before = "[" + tag + (arg ? "=" : "") + "]";
var after = "[/" + tag + "]";
if (document.selection) {
element.focus();
var sel = document.selection.createRange();
sel.text = before + sel.text + after;
element.focus();
} else if (element.selectionStart || element.selectionStart === 0) {
var startPos = element.selectionStart;
var endPos = element.selectionEnd;
var scrollTop = element.scrollTop;
element.value = element.value.substring(0, startPos) + before + element.value.substring(startPos, endPos) + after + element.value.substring(endPos, element.value.length);
element.focus();
element.selectionStart = startPos + before.length;
element.selectionEnd = endPos + before.length;
element.scrollTop = scrollTop;
} else {
element.value += before + after;
element.focus();
}
}
// Formatting money
Number.prototype.formatMoney = function(u, c, k) {
var f = this,

View file

@ -62,7 +62,7 @@ if ($mode != 'f') {
$post = $thread['posts'][$_GET['p']];
// Add subject to render data
$posting['text'] = '[quote=' . (new User($post['poster_id']))->username() . ']' . (new BBcode($post['post_text']))->toEditor() . '[/quote]';
$posting['text'] = '[quote=' . (new User($post['poster_id']))->username() . ']' . BBcode::toEditor($post['post_text']) . '[/quote]';
// Post editing
} elseif ($mode == 'p' && isset($_GET['edit']) && $_GET['edit'] == $_GET['p'] && array_key_exists($_GET['p'], $thread['posts'])) {
@ -88,7 +88,7 @@ if ($mode != 'f') {
// Set variables
$posting = array_merge($posting, [
'subject' => $post['post_subject'],
'text' => (new BBcode($post['post_text']))->toEditor(),
'text' => BBcode::toEditor($post['post_text']),
'id' => $post['post_id'],
]);
// Post deletion