jQuery+kefir-bb打造UBB交互

结构 jsp + jquery + kafir-bb

在数据库存为ubbCode 前台显示为解析为htmlCode

kefir-bb架包: http://sourceforge.net/projects/kefir-bb/files/kefir-bb/kefir-bb-0.4/kefir-bb-0.4.jar/download

前台 test.jsp

<%@ page language="java" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>ubb测试</title>
		<style type="text/css">
			.editor-toolbar {width:100%; height: 20px;padding: 2px;background: #eee;}
			.editor-mask {position:absolute; width:100%; height:2000px; left:0; top:0; z-index:100; display:none;}
			.editor-button {display: block;float: left;overflow: hidden;margin: 0 2px;text-indent: -10000em;width: 21px;height: 20px;cursor: pointer;background: transparent url() left top no-repeat;}
			.editor-button:hover {background-color: #b7d4ff;}
			.editor-btnLink {background-image: url(http://static.l99.com/skin/default/images/message/bb_link.gif);}
			.editor-btnImage {background-image: url(http://static.l99.com/skin/default/images/message/bb_image.gif);}
			.editor-content{background-color: #eeeeee;border: 2px #cccccc solid; padding: 2px;}
			.editor-content a.close{position:absolute;right:3px;top:5px;background: url(http://static.l99.com/skin/default/images/record_delete.gif) no-repeat; width: 16px;height: 16px;  }
			.answers{text-align: right;}			
		</style>
	</head>

	<body>
		<h1>jQuery的UBB</h1>
	    <div>
	        <form action="EditBBcode_save.action" method="post">
	        <div style="width: 60%;">
				<textarea id="editor" name="bbCode" style="width:100%;" rows="10" >[b]样例文字。[/b]</textarea>
	        </div>
	        <input id="submit" type="submit" value="提交表单" />
	        </form>
	    </div>
	</div>
	<script type="text/javascript" src="js/jquery-1.3.2-min.js"></script>
	<script type="text/javascript" src="js/test/ubb_tools_test.js"></script>
	<script type="text/javascript">
		$("document").ready(function(){
			$.TextAreaUbb("editor");
		});
	</script>
</body>
</html>
 

 

前台 ubb_tools_test.js:

/**
 * 插入UBB
 */

(function($) {
	$.fn.extend({
		makeLink : function () {
			return this.click(function(){
				var b = $(this), f = UbbOption.ubbObject.getSelection(), c = b.offset(), d = document, t;
				if(jQuery.trim(f) === ""){return;}
				c.top += b.height();
				if (d.selection && d.selection.createRange) {
					t = d.selection.createRange();
				}
				UbbOption.ubbObject.showPrompt("LINK", function () {
					var e = this.txt.val();
					if(e == "")return;
					var g = "[url=" + e + "]" + f + "[/url]";
					UbbOption.ubbObject.insertText(g, t);
					UbbOption.ubbObject.ubbText.keyup();
				}, c);
			});
		},
		makeImage : function () {
			return this.click(function(){
				var b = $(this), g = UbbOption.ubbObject.getSelection(), c = b.offset(), d = document, t;
				c.top += b.height();
				if (d.selection && d.selection.createRange) {
					t = d.selection.createRange();
				}
				UbbOption.ubbObject.showPrompt("IMG", function () {
					var h = this.txt.val();
					if(h == "")return;
					var g = "[img=" + h + "]";
					var it = this.txt.attr("title");
					if(it){
						g = "[img=" + h + " imgtitle=" + it + "]";
					}
					UbbOption.ubbObject.insertText(g, t);
					UbbOption.ubbObject.ubbText.keyup();
				}, c);
			});
		}
	});
	
	var UbbOption = {
		ubbObject:null
	};
	
	/**
	 * UBB初始化
	 */
	$.TextAreaUbb = function(ubbId){
		if(ubbId == 'undefined'){
			return;
		}
		if(UbbOption.ubbObject != null){
			return;
		}
		UbbOption.ubbObject = this;
		createUbb();
		
		function createUbb(){
			UbbOption.ubbObject.ubbText = $("#" + ubbId);
			UbbOption.ubbObject.ubbText.wrap("<div id=\"" + ubbId + "-wrapper\"></div>").parent("div").addClass("editor-wrapper");
			UbbOption.ubbObject.toolbar = $("<div id=\"" + ubbId + "-toolbar\"></div>").insertBefore(UbbOption.ubbObject.ubbText).addClass("editor-toolbar");
			
			btnLink = makeButton("btnLink", "链接").makeLink();
			btnImage = makeButton("btnImage", "插入图片").makeImage();
			
			$("<div style=\"padding-top: 5px; font-size: 12px;\">(还可以输入<span class=\"text_orange\" id=\"ubb_text_warning\">400</span>个字)</div>").appendTo(UbbOption.ubbObject.toolbar);
		}
		function makeButton(a, b, c) {
			return $("<a href=\"javascript:void(0);\" title=\"" + b + "\" class=\"editor-button editor-" + a + "\" " + (c?"id=\"" + c +"\"":"") + " >" + b + "</a>").appendTo(UbbOption.ubbObject.toolbar);
		}
		
		UbbOption.ubbObject.getSelection = function (){
			var j = window, f = document, g = UbbOption.ubbObject.ubbText.get(0);
			if (UbbOption.ubbObject.def(g.selectionStart)) {
				return g.value.substr(g.selectionStart, g.selectionEnd - g.selectionStart);
			} else {
				if (f.selection && f.selection.createRange) {
					return f.selection.createRange().text;
				} else {
					if (j.getSelection) {
						return window.getSelection() + "";
					}
				}
			}
			return null;
		};
		
		UbbOption.ubbObject.def = function() {
			if (arguments.length == 0) {
				return true;
			}
			if (arguments.length == 1) {
				return (typeof (arguments[0]) != "undefined");
			}
			for (var a = 0; a < arguments.length; ++a) {
				if (!UbbOption.ubbObject.def(arguments[a])) {
					return false;
				}
			}
			return true;
		}
		
		UbbOption.ubbObject.showPrompt = function(a, e, b, d) {
			new Prompt().show(a, e, b, d);
		};
		
		UbbOption.ubbObject.insertText = function(l, t) {
			var n = this, i = document, j = UbbOption.ubbObject.ubbText.get(0);
			if (UbbOption.ubbObject.def(j.selectionStart)) {
				var b = j.selectionStart + 0;
				j.value = j.value.substr(0, j.selectionStart) + l + j.value.substr(j.selectionEnd);
			} else {
				if (i.selection && i.selection.createRange && t && t.text!="") {
					var g = i.selection.createRange();
					t.text = l.replace(/\r?\n/g, "\r\n");
					g.select();
				} else {
					j.value += l;
				}
			}
		};
	};
	
	/**
	 * UBB遮盖层
	 */
	var Prompt = function () {
		var a = this;
		if (!Prompt.instance) {
			a.mask = $("<div class=\"editor-mask\"></div>").appendTo(document.body).hide();
			a.boxy = $("<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" class=\"boxy-wrapper\"><tr><td class=\"top-left\"></td><td class=\"top\"></td><td class=\"top-right\"></td></tr><tr><td class=\"boxy-left\"></td><td class=\"boxy-inner\"><div class=\"editor-content\" style=\"display: block;\"></div></td><td class=\"boxy-right\"></td></tr><tr><td class=\"bottom-left\"></td><td class=\"bottom\"></td><td class=\"bottom-right\"></td></tr></table>").css({position:"absolute", zIndex:101}).appendTo(document.body).hide();
			a.container = $('.editor-content', a.boxy);
			a.cancel = $("<a class=\"close\" href=\"javascript:void(0);\">&nbsp;</a>").appendTo(a.container).click(function () {
				a.hide();
			});
			a.mask.click(function(){
				a.cancel.click();
			});
		}
		return Prompt.instance;
	};
	
	Prompt.prototype = {mask:$(), container:$(), ok:$(), cancel:$(), onOk:function (a) {
	}, show:function (e, c, d) {
		var b = this;
		b.onOk = c;
		switch(e){
			case "LINK":{
				b.container.append($("<div class=\"subcontext\">插入链接</div>"));
				b.cencontext = $("<div class=\"cencontext\"></div>").appendTo(b.container);
				b.supcontext = $("<div class=\"answers\"></div>").appendTo(b.container);
				b.txt = $("<input type=\"text\" value=\"http://\" />").appendTo(b.cencontext).css({width:"200px", margin:"5px 0"}).keypress(function (b) {
					if (b.keyCode == 13) {
						b.ok.click();
					}
				});
				b.cencontext.prepend("请输入链接地址:");
				b.ok = $("<input type=\"button\" value=\"确定\" />").appendTo(b.supcontext).css({background:"#FC5A0A", color:"#FFFFFF", width:"40px"}).click(function () {
					if ($.isFunction(b.onOk)) {
						b.onOk.call(b);
					}
					b.hide();
				});
				break;
			};
			case "IMG":{
				b.container.append($("<div class=\"subcontext\">网络图片</div>"));
				b.cencontext = $("<div class=\"cencontext\"></div>").appendTo(b.container);
				b.netpic = $("<div id=\"net_pic\"></div>").appendTo(b.cencontext);
				b.txt = $("<input type=\"text\" value=\"http://\" />").appendTo(b.netpic).css({width:"200px", margin:"5px 0"}).keypress(function (b) {
					if (b.keyCode == 13) {
						b.ok.click();
					}
				});
				b.netpic.append("<div class=\"clear\"></div>");
				b.supcontext = $("<div class=\"answers\"></div>").appendTo(b.netpic);
				b.netpic.prepend("请输入图片地址:");
				b.ok = $("<input type=\"button\" value=\"确定\" />").appendTo(b.supcontext).css({background:"#FC5A0A", color:"#FFFFFF", width:"40px"}).click(function () {
					if ($.isFunction(b.onOk)) {
						b.onOk.call(b);
					}
					b.hide();
				});
				break;
			};
		}
		if (d) {
			b.boxy.css(d);
		}
		b.mask.fadeIn("fast");
		b.boxy.slideDown("fast");
	}, hide:function () {
		this.boxy.slideUp("fast",function(){$(this).remove();});
		this.mask.fadeOut("fast",function(){$(this).remove();});
	}};
	
})(jQuery);

 

前台生成的ubbCode数据

 

[img=http://www.google.cn/images/nav_logo7.png]\r\n[url=http://www.google.cn/images/nav_logo7.png][img=http://www.google.cn/images/nav_logo7.png][/url]
 

 

 

后台 bbcode_test.xml

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns="http://kefir-bb.sourceforge.net/schemas"
               xsi:schemaLocation="http://kefir-bb.sourceforge.net/schemas http://kefir-bb.sourceforge.net/schemas/kefir-bb-0.4.xsd">
    <!-- XML escape symbols -->
    <scope name="escapeXml">
        <coderef name="amp"/>
        <coderef name="apos"/>
        <coderef name="lt"/>
        <coderef name="gt"/>
        <coderef name="quot"/>
    </scope>
    <code name="amp" priority="100">
        <pattern>&amp;</pattern>
        <template>&amp;amp;</template>
    </code>
    <code name="apos" priority="100">
        <pattern>&apos;</pattern>
        <template>&amp;apos;</template>
    </code>
    <code name="lt" priority="100">
        <pattern>&lt;</pattern>
        <template>&amp;lt;</template>
    </code>
    <code name="gt" priority="100">
        <pattern>&gt;</pattern>
        <template>&amp;gt;</template>
    </code>
    <code name="quot" priority="100">
        <pattern>&quot;</pattern>
        <template>&amp;quot;</template>
    </code>

    <!-- Root scope. This scope uses when processor started work and by default, if not set other scope -->
    <scope name="ROOT" parent="escapeXml">
        <coderef name="noubb"/>
        <coderef name="nbsp"/>
        <coderef name="br1"/>
        <coderef name="br2"/>
        <coderef name="br3"/>
        <coderef name="br4"/>
        <coderef name="br5"/>
        <coderef name="slash"/>
        <coderef name="left_square_bracket"/>
        <coderef name="right_square_bracket"/>
        <coderef name="bold"/>
        <coderef name="u"/>
        <coderef name="s"/>
        <coderef name="i"/>
        <coderef name="code"/>
        <coderef name="img1"/>
        <coderef name="img2"/>
        <coderef name="img3"/>
        <coderef name="url1"/>
        <coderef name="url2"/>
        <coderef name="url3"/>
        <coderef name="url4"/>
        <coderef name="url5"/>
        <coderef name="color"/>
        <coderef name="size"/>
        <coderef name="symbol"/>
        <coderef name="comment"/>
        <coderef name="ul"/>
        <coderef name="li"/>
        <coderef name="p1"/>
        <coderef name="p2"/>
        <coderef name="p3"/>
        <coderef name="div1"/>
        <coderef name="div2"/>
        <coderef name="span1"/>
        <coderef name="span2"/>
        <coderef name="span3"/>
    </scope>
    
	<code name="noubb" priority="10">
        <pattern>[noubb]<var parse="false"/>[/noubb]</pattern>
        <template><var/></template>
    </code>
    <!-- line feed characters -->
    
    <code name="br1" priority="3">
        <pattern>&#x0A;&#x0D;</pattern>
        <template>&lt;br/&gt;</template>
    </code>
    <code name="br2" priority="2">
        <pattern>&#x0D;&#x0A;</pattern>
        <template>&lt;br/&gt;</template>
    </code>
    <code name="br3" priority="1">
        <pattern>&#x0A;</pattern>
        <template>&lt;br/&gt;</template>
    </code>
    <code name="br4" priority="0">
        <pattern>&#x0D;</pattern>
        <template>&lt;br/&gt;</template>
    </code>
    <code name="br5" priority="4">
        <pattern>[br /]</pattern>
        <template>&lt;br/&gt;</template>
    </code>

    <!--
        Escape bb-code symbols
        double slash to slash
        slash + square bracket to square bracket
     -->
    <code name="slash" priority="10">
        <pattern>\\</pattern>
        <template>\</template>
    </code>
    <code name="left_square_bracket" priority="9">
        <pattern>\[</pattern>
        <template>[</template>
    </code>
    <code name="right_square_bracket" priority="9">
        <pattern>\]</pattern>
        <template>]</template>
    </code>

    <!-- Simple formatting -->
    <code name="bold">
        <pattern>[b]<var/>[/b]</pattern>
        <template>&lt;span style=&quot;font-weight:bold;&quot;&gt;<var/>&lt;/span&gt;</template>
    </code>
    <code name="u">
        <pattern>[u]<var/>[/u]</pattern>
        <template>&lt;span style=&quot;text-decoration:underline;&quot;&gt;<var/>&lt;/span&gt;</template>
    </code>
    <code name="s">
        <pattern>[s]<var/>[/s]</pattern>
        <template>&lt;span style=&quot;text-decoration:line-through;&quot;&gt;<var/>&lt;/span&gt;</template>
    </code>
    <code name="i">
        <pattern>[i]<var/>[/i]</pattern>
        <template>&lt;span style=&quot;font-style:italic;&quot;&gt;<var/>&lt;/span&gt;</template>
    </code>

    <!-- Quote code block -->
    <code name="code">
        <pattern>[code]<var scope="codeScope"/>[/code]</pattern>
        <template>&lt;pre&gt;<var/>&lt;/pre&gt;</template>
    </code>
    <scope name="codeScope" parent="escapeXml">
        <coderef name="br1"/>
        <coderef name="br2"/>
        <coderef name="br3"/>
        <coderef name="br4"/>
        <coderef name="br5"/>
        <coderef name="slash"/>
        <coderef name="left_square_bracket"/>
        <coderef name="right_square_bracket"/>
        <coderef name="symbol"/>
        <coderef name="comment"/>
    </scope>

    <!-- Insert image -->
    <code name="img1" priority="3">
        <pattern>[img=http://<var name="src" scope="escapeXml"/> imgtitle=<var name="imgtitle" scope="escapeXml"/> imgclass=<var name="imgclass" scope="escapeXml"/>]</pattern>
        <template>&lt;img src=&quot;http://<var name="src"/>&quot; title=&quot;<var name="imgtitle"/>&quot; class=&quot;<var name="imgclass"/>&quot; alt=&quot;图片载入中...&quot;/&gt;</template>
    </code>
    <code name="img2" priority="2">
        <pattern>[img=http://<var name="src" scope="escapeXml"/> imgtitle=<var name="imgtitle" scope="escapeXml"/>]</pattern>
        <template>&lt;img src=&quot;http://<var name="src"/>&quot; title=&quot;<var name="imgtitle"/>&quot; class=&quot;ubb_img&quot; alt=&quot;图片载入中...&quot;/&gt;</template>
    </code>
    <code name="img3" priority="1">
        <pattern>[img=http://<var scope="escapeXml"/>]</pattern>
        <template>&lt;img src=&quot;http://<var/>&quot; class=&quot;ubb_img&quot; alt=&quot;图片载入中...&quot;/&gt;</template>
    </code>

    <!-- Links. http, malto protocols -->
    <code name="url1" priority="6">
        <pattern>[url=http://<var name="url" scope="escapeXml"/>]<var name="text"/>[/url]</pattern>
        <template>&lt;a href=&quot;http://<var name="url"/>&quot; target=&quot;_blank&quot; &gt;<var name="text"/>&lt;/a&gt;</template>
    </code>
    <code name="url2" priority="3">
        <pattern>[url]http://<var name="url" scope="escapeXml"/>[/url]</pattern>
        <template>&lt;a href=&quot;http://<var name="url"/>&quot; target=&quot;_blank&quot; &gt;http://<var name="url"/>&lt;/a&gt;</template>
    </code>
    <code name="url3" priority="5">
        <pattern>[url=mailto:<var name="url" scope="escapeXml"/>]<var name="text"/>[/url]</pattern>
        <template>&lt;a href=&quot;mailto:<var name="url"/>&quot; target=&quot;_blank&quot; &gt;<var name="text"/>&lt;/a&gt;</template>
    </code>
    <code name="url4" priority="7">
        <pattern>[url=<var name="url" scope="escapeXml"/> style=<var name="style" scope="escapeXml" />]<var name="text"/>[/url]</pattern>
        <template>&lt;a href=&quot;<var name="url"/>&quot; style=&quot;<var name="style"/>&quot; target=&quot;_blank&quot; &gt;<var name="text"/>&lt;/a&gt;</template>
    </code>
	<code name="url5" priority="7">
        <pattern>[url=<var name="url" scope="escapeXml"/> class=<var name="class" scope="escapeXml" />]<var name="text"/>[/url]</pattern>
        <template>&lt;a href=&quot;<var name="url"/>&quot; class=&quot;<var name="class"/>&quot; target=&quot;_blank&quot; &gt;<var name="text"/>&lt;/a&gt;</template>
    </code>
  
    <!-- Font color -->
    <code name="color">
        <pattern>[color=<var name="color" scope="escapeXml"/>]<var name="text"/>[/color]</pattern>
        <template>&lt;span style=&quot;color:<var name="color"/>;&quot;&gt;<var name="text"/>&lt;/span&gt;</template>
    </code>

    <!-- Comment -->
    <code name="comment">
        <pattern>[*<var parse="false"/>*]</pattern>
        <template/>
    </code>

    <!-- Font size -->
    <code name="size">
        <pattern>[size=<var name="size" scope="escapeXml"/>]<var name="text"/>[/size]</pattern>
        <template>&lt;span style=&quot;font-size:<var name="size"/>;&quot;&gt;<var name="text"/>&lt;/span&gt;</template>
    </code>

    <!-- Special html symbols -->
    <code name="symbol">
        <pattern>[symbol=<var scope="escapeXml"/>/]</pattern>
        <template>&amp;<var/>;</template>
    </code>
    
    <!-- extend -->
	<code name="nbsp">
        <pattern> </pattern>
        <template>&amp;nbsp;</template>
    </code>
    
    <code name="ul">
        <pattern>[ul=<var name="style" scope="escapeXml"/>]<var name="text"/>[/ul]</pattern>
        <template>&lt;ul style=&quot;<var name="style"/>&quot;&gt;<var name="text"/>&lt;/ul&gt;</template>
    </code>
    
    <code name="li">
        <pattern>[li=<var name="style" scope="escapeXml"/>]<var name="text"/>[/li]</pattern>
        <template>&lt;li style=&quot;<var name="style"/>&quot;&gt;<var name="text"/>&lt;/li&gt;</template>
    </code>
    
    <code name="p1">
        <pattern>[p=<var name="style" scope="escapeXml"/>]<var name="text"/>[/p]</pattern>
        <template>&lt;p style=&quot;<var name="style"/>&quot;&gt;<var name="text"/>&lt;/p&gt;</template>
    </code>
    <code name="p2">
        <pattern>[p]<var name="text"/>[/p]</pattern>
        <template>&lt;p&gt;<var name="text"/>&lt;/p&gt;</template>
    </code>
    <code name="p3">
        <pattern>[p class=<var name="class" scope="escapeXml"/>]<var name="text"/>[/p]</pattern>
        <template>&lt;p class=&quot;<var name="class"/>&quot;&gt;<var name="text"/>&lt;/p&gt;</template>
    </code>
    <code name="div1">
       <pattern>[div=<var name="style" scope="escapeXml"/>]<var name="text"/>[/div]</pattern>
       <template>&lt;div style=&quot;<var name="style"/>&quot;&gt;<var name="text"/>&lt;/div&gt;</template>
    </code>
    <code name="div2">
        <pattern>[div class=<var name="class" scope="escapeXml"/>]<var name="text"/>[/div]</pattern>
        <template>&lt;div class=&quot;<var name="class"/>&quot;&gt;<var name="text"/>&lt;/div&gt;</template>
    </code>
    <code name="span1" priority="3">
       <pattern>[span=<var name="style" scope="escapeXml"/>]<var name="text"/>[/span]</pattern>
       <template>&lt;span style=&quot;<var name="style"/>&quot;&gt;<var name="text"/>&lt;/span&gt;</template>
    </code>
    <code name="span2" priority="2">
        <pattern>[span class=<var name="class" scope="escapeXml"/>]<var name="text"/>[/span]</pattern>
        <template>&lt;span class=&quot;<var name="class"/>&quot; &gt;<var name="text"/>&lt;/span&gt;</template>
    </code>
    <code name="span3" priority="1">
        <pattern>[span title=<var name="title" scope="escapeXml"/> class=<var name="class" scope="escapeXml"/>]<var name="text"/>[/span]</pattern>
        <template>&lt;span class=&quot;<var name="class"/>&quot; title=&quot;<var name="title"/>&quot; &gt;<var name="text"/>&lt;/span&gt;</template>
    </code>
</configuration>

 

后台java解析

 

TextProcessor processor = BBProcessorFactory.getInstance().createFromResource("bbcode_test.xml");
		String htmlCode = processor.process(bbCode);

 

最后生成html代码

<img src="http://www.google.cn/images/nav_logo7.png" alt="图片载入中..."/><br/><a href="http://www.google.cn/images/nav_logo7.png" target="_blank" ><img src="http://www.google.cn/images/nav_logo7.png" alt="图片载入中..."/></a>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值