#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2007
    Posts
    80
    Rep Power
    8

    RegExp Help


    Someone made me a script for Grease Monkey, but there are some issues with it. It keeps freezing firefox. I asked the person about it, and they said that its the RegExp thats causing the issues. They said it should use a simpler RegExp, but at the moment they didn't have time to revise it.

    It works good except for that one issue.

    I was hoping someone here could help me out. The idea of the script is make BBCode work for forums that don't use it. It takes the BBCode, and replaces the BB Tags with HTML so that the HTML appears.

    Here is the code, the RegExp is inside the function "replaceTextContent()":

    javascript Code:
     
    // ==UserScript==
    // @name           BBCode Replacer
    // @namespace      http://userscripts.org/users/28612
    //@version        0.01.00
    // @description    Replace BBCode with html tags
    // @include        *forum*
    // ==/UserScript==
     
    replaceTextContent(/\[(\w*)=?(.*?)\]((?:.|\s)*?)\[\/\1\]/gmi,replaceBBCode,document.body);
     
    function replaceTextContent(regexp,handler,node)
    {
    	//GM_log("replacing: "+node.textContent);
    	var snapshots=document.evaluate("//text()",node,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
    	for(var num1=0;num1<snapshots.snapshotLength;num1++)
    	{
    		regexp.lastIndex=0;
    		var node1=snapshots.snapshotItem(num1);
    		var match1=regexp.exec(node1.textContent);
    		if (match1)
    		{
    			var node2=node1.parentNode;
    			var node3=node1.nextSibling;
    			var text1=RegExp.rightContext;
    			node2.removeChild(node1);
    			while (match1)
    			{
    				text1=RegExp.rightContext;
    				node2.insertBefore(document.createTextNode(RegExp.leftContext),node3);
    				var node1=handler(match1);
    				node2.insertBefore(node1,node3);
    				replaceTextContent(regexp,handler,node1);
    				regexp.lastIndex=0;
    				match1=regexp.exec(text1);
    			}
    			node2.insertBefore(document.createTextNode(text1),node3);
    		}
    	}
    }
     
    function replaceBBCode(match)
    {
    	//GM_log("match: "+match);
    	switch(match[1].toLowerCase())
    	{
    		case "b":
    		case "i":
    		case "s":
    		case "u":
    		case "center":
    			return createElement(match[1],match[3]);
    		case "code":
    			return createElement("pre",match[3]);
    		case "color":
    			return createElement("span",match[3],{"style":"color:"+match[2]});
    		case "email":
    			return createElement("a",match[3],{"src":"mailto:"+getUrl(match)});
    		case "image":
    		case "img":
    			return createElement("img",null,{"src":getUrl(match),"alt":match[3]});
    		case "link":
    		case "url":
    			return createElement("a",match[3],{"src":getUrl(match)});
    		case "quote":
    			return createElement("blockquote",match[3]);
    		case "size":
    			return createElement("span",match[3],{"style":"font-size:"+match[2]});
    		case "spoiler":
    			var span1=createElement("span",null,{"title":"Click to hide/show Spoiler","onclick":"var  s1=this.firstChild.style; var s2=this.firstChild.nextSibling.style; var t=s1.display; s1.display=s2.display; s2.display=t;"});
    			span1.appendChild(createElement("span","Spoiler"));
    			span1.appendChild(createElement("span",match[3],{"style":"display:none"}));
    			return span1;
    	}
    	return document.createTextNode(match[0]);
    }
     
    function createElement(tagName,textContent,attributes)
    {
    	var element1=document.createElement(tagName);
    	element1.textContent=textContent;
    	for(var name1 in attributes) element1.setAttribute(name1,attributes[name1]);
    	return element1;
    }
     
    function getUrl(match) {return (match[2]?match[2]:match[3]).replace(/\s/g,"");}
  2. #2
  3. No Profile Picture
    Super Moderator
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jul 2003
    Posts
    4,009
    Rep Power
    2791
    Why are you even doing this on the client side?
    [PHP] | [Perl] | [Python] | [Java] != [JavaScript] | [XML] | [C] | [C++] | [LUA] | [MySQL] | [FirebirdSQL] | [PostgreSQL] | [HTML] | [XHTML] | [CSS]

    W3Fools - A W3Schools Intervention.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2007
    Posts
    80
    Rep Power
    8
    Why not? I know I will be the only one seeing the translated BBCode, but I plan on spreading the extension around to as many people who will use it so that we can all use BBCode, especially on websites like GameFAQs, it should be a big hit I would think.

    If I could use client-side enabled BBCode, I would, but alot of websites still don't even support that, let alone actual HTML.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2007
    Posts
    80
    Rep Power
    8
    Bump, still need help please
  8. #5
  9. No Profile Picture
    User 165270
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2005
    Posts
    497
    Rep Power
    938
    Originally Posted by Kastro187420
    Bump, still need help please
    A couple of observation which may lead to a better performance:

    - you're not using the m- and i-flags, so you might as well leave them out;
    - you're using (?:.|\s)* as some sort of DOT-ALL feature but a character class is generally faster than an OR, so this may be faster: [\s\S]*;
    - inside the first BB-tag, you're using .*? while the following negated character class is faster: [^\[\]]*.

    So, the final regex would look like:

    javascript Code:
    /\[(\w*)=?([^\[\]]*)\]([\s\S]*?)\[\/\1\]/g


    Although I doubt that the difference in speed will not be very big. But I am fairly sure that there is not much to improve because Javascript does not support atomic grouping or possessive quantifiers which are a must to really improve the speed of ones regex.

IMN logo majestic logo threadwatch logo seochat tools logo