Javascript variable string replacement - javascript

Another stupid question.
I believe I understand this right but it doesn't seem to work.
function parseCustomCommands($text, $textParts) {
if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) {
switch($textParts[0]) {
case '/takeover':
$this->insertChatBotMessage( $this->getChannel(), $text );
return true;
default:
return false;
}
}
}
ajaxChat.replaceCustomCommands = function(text, textParts) {
switch(textParts[0]) {
case '/takeover':
text=text.replace('/takeover', ' ');
return '<span class="chatBotMessage">' + text + '</span>';
default:
return text;
}
}
It's executed when /takeover is this sent and the way I'm looking at it the '/takeover' part is meant to be replaced with nothing leaving just the . This does not seem to be the case..
Is anyone able to point out the mistake in it? I've tried several things with $ in variable names and using different variables to remove it.
$re="/takeover";
$str=text.replace(re, ' ');
I've tried too.
Thanks in advance.

This is really a PHP question
github source
Review the other "insertParsedMessage*" PHP methods
I'm not a PHP developer but it should be something like this based on the documentation
$text = str_replace("/takeover","", $text);

Related

Returning Rendered HTML from Chatbot

I am using the chatbot from liouh (https://github.com/liouh/chat-bot). When I attempt to return a URL, it gives me unrendered/raw HTML instead of a link. How can I return a rendered link given the Google scenario below? Thank you
function chatBot() {
// current user input
this.input;
this.respondTo = function(input) {
this.input = input.toLowerCase();
if(this.match('link to google'))
return "<a href='http://google.com'>Google.com</a>";
if(this.input == 'noop')
return;
return "I dont know the answer to '" + input + "'. You can teach me that via the link at the top of this page.";
}
this.match = function(regex) {
return new RegExp(regex).test(this.input);
}
}
It looks like in line 54 of index.js you need to change the code from
line.find('.text').text(text);
to
line.find('.text').html(text);
this will append the incoming reply as HTML instead of plain text.

How can I create a custom function in PHP for HTML tags?

Last time I asked for help in PHP and I got great response. Thanks to all of you for that. Now I am learning and creating website using MVC PHP. I want to ask you that can I create a custom function to use html tags? I am trying to remember that where I saw an example of it. Actually I've seen it before in and open source project.
It was like something this:
htmltag(script(src=address, type=javascript))
Its output was in html like:
<script src="address" type="javascript"></script>
So can I create something like this? I am trying to do this way:
public function script($var1, $var2){
$var1 = array(
'type'=>'',
'charset' => '',
'src' => ''
);
$var2 = false;
print("<script $var1>$var2</script>");
}
So can anyone guide me with this? Do I need to create class first? I will be waiting for your reply friends.
Javascript works with DOM, see the reference
function htmltag(name,atts) {
var tag = document.createElement(name);
for(var i in atts) tag.setAttribute(i, atts[i]);
return tag;
}
var img = htmltag("img", {
src: "https://kevcom.com/images/linux/linux.logo.2gp.jpg",
alt: "linux logo"
});
document.body.appendChild(img);
Note that img here is object (XML Node), not just plain text, so you can attach events on it etc. If you want to extract just the plain html code from it, use img.outerHTML. Test it on the fiddle.
Note: print is the equivalent of Ctrl+P in the browser :-) it is not the print equivalent in PHP.
In PHP you can use DOM::createElement and other methods from DOM which are quite similar to those from javascript. Personaly I prefer something more simple:
function tag($name,$atts="",$content="") {
$str_atts = "";
if(is_array($atts)) {
foreach($atts as $key=>$val) if(!($val===null || $val===false)) $str_atts.= " $key=\"$val\"";
} else $str_atts = " ".preg_replace("/=(?!\")(\S+)/m","=\"\\1\"",$atts);
if($name=="img" && !strpos($str_atts,"alt=")) $str_atts.= " alt=\"\"";
if(in_array($name,array("input","img","col","br","hr","meta"))) $name.= "/";
if(substr($name,-1)=="/") { $name = substr($name,0,-1); return "<{$name}{$str_atts}/>"; }
else return "<{$name}{$str_atts}>$content</$name>";
}
Examples
echo tag("p","class=foo id=bar1","hello");
echo tag("p",'class="foo" id="bar2"',"hey");
echo tag("p",array("class"=>"foo","id"=>"bar3"),"heya");
echo tag("img","src=https://kevcom.com/images/linux/linux.logo.2gp.jpg");

How to add custom image tag to pagedown?

I'm attempting to duplicate the original img tag's functionality in custom img tag that will be added to the pagedown converter.
e.g I'm copy the original behavior:
![image_url][1] [1]: http://lolink.com gives <img src="http://lolink.com">
into a custom one:
?[image_url][1] [1]: http://lolink.com gives <img class="lol" src="http://lolink.com">
Looking at the docs the only way to do this is through using the preblockgamut hook and then adding another "block level structure." I attempted doing this and got an Uncaught Error: Recursive call to converter.makeHtml
here's the code of me messing around with it:
converter.hooks.chain("preBlockGamut", function (text, dosomething) {
return text.replace(/(\?\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, function (whole, inner) {
return "<img src=" + dosomething(inner) + ">";
});
});
I'm not very experienced with hooks and everything so what would I do to fix it? Thanks.
UPDATE: found out that _DoImages runs after prespangamut, will use that instead of preblockgamut
Figured it out! The solution is very clunky and involves editing the source code because I am very bad at regex and the _DoImage() function uses a lot of internal functions only in the source.
solution:
All edits will be made to the markdown.converter file.
do a ctrl+f for the _DoImage function, you will find that it is named in two places, one in the RunSpanGamut and one defining the function. The solution is simple, copy over the DoImage function and related stuff to a new one in order to mimic the original function and edit it to taste.
next to DoImage function add:
function _DoPotatoImages(text) {
text = text.replace(/(\?\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writePotatoImageTag);
text = text.replace(/(\?\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writePotatoImageTag);
return text;
}
function writePotatoImageTag(wholeMatch, m1, m2, m3, m4, m5, m6, m7) {
var whole_match = m1;
var alt_text = m2;
var link_id = m3.toLowerCase();
var url = m4;
var title = m7;
if (!title) title = "";
if (url == "") {
if (link_id == "") {
link_id = alt_text.toLowerCase().replace(/ ?\n/g, " ");
}
url = "#" + link_id;
if (g_urls.get(link_id) != undefined) {
url = g_urls.get(link_id);
if (g_titles.get(link_id) != undefined) {
title = g_titles.get(link_id);
}
}
else {
return whole_match;
}
}
alt_text = escapeCharacters(attributeEncode(alt_text), "*_[]()");
url = escapeCharacters(url, "*_");
var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";
title = attributeEncode(title);
title = escapeCharacters(title, "*_");
result += " title=\"" + title + "\"";
result += " class=\"p\" />";
return result;
}
if you look at the difference between the new _DoPotatoImages() function and the original _DoImages(), you will notice I edited the regex to have an escaped question mark \? instead of the normal exclamation mark !
Also notice how the writePotatoImageTag calls g_urls and g_titles which are some of the internal functions that are called.
After that, add your text = _DoPotatoImages(text); to runSpanGamut function (MAKE SURE YOU ADD IT BEFORE THE text = _DoAnchors(text); LINE BECAUSE THAT FUNCTION WILL OVERRIDE IMAGE TAGS) and now you should be able to write ?[image desc](url) along with ![image desc](url)
done.
The full line (not only the regex) in Markdown.Converter.js goes like this:
text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeImageTag);
so check the function writeImageTag. There you can see how the regex matching text is replaced with a full img tag.
You can change the almost-last line before its return from
result += " />";
to
result += ' class="lol" />';
Thanks for the edit to the main post.
I see what you mean now.
It is a bit weird how it uses empty capture groups to specify tags, but if it works, it works.
It looks like you would need to add on an extra () onto the regex string, then specify m8 as a new extra variable to be passed into the function, and then specify it as class = m8; like the other variables at the top of the function.
Then where it says var result =, instead of class =\"p\" you would just put class + title=\"" + .......

Javascript Syntax Error

hiere is my code, within a loop.
I want to solve my closure problem.
But on click I receive an error message "Syntac Error".
Any help. Thanks in advance.
var html = '<div style="margin-top:10px">';
html += '<div class="weiter"> Kartenauswahl in die Recherche übernehmen </div>';
html += '<div class="weiter" style="display:block;clear:left;margin-top:7px"
onclick="function(obj) { return getChildObject(obj)}(obj)">Weiter</div>';
html += '</div>';
This certainly does not look right:
function(obj) { return getChildObject(obj)}(obj)
I would simply write this:
return getChildObject(obj);
This code in your onclick attribute is not valid:
function(obj) { return getChildObject(obj)}(obj)
Put the function expression in parentheses and try this instead:
(function(obj) { return getChildObject(obj); })(obj)
If that's your actual code, the immediate problem is that there's a line break in your string literal, between the third and fourth lines. Delete that line break. There are problems in the HTML too, as mentioned in other answers.
The problem seems to be at:
onclick="function(obj) { return getChildObject(obj)}(obj)
^
Try removing (obj).
Also you should post the code for getChildObject function.
function(obj) { return getChildObject(obj)}(obj)
Above does not seems to be correct

How to close unclosed HTML Tags?

Whenever we are fetching some user inputed content with some editing from the database or similar sources, we might retrieve the portion which only contains the opening tag but no closing.
This can hamper the website's current layout.
Is there a clientside or serverside way of fixing this?
Found a great answer for this one:
Use PHP 5 and use the loadHTML() method of the DOMDocument object. This auto parses badly formed HTML and a subsequent call to saveXML() will output the valid HTML. The DOM functions can be found here:
http://www.php.net/dom
The usage of this:
$doc = new DOMDocument();
$doc->loadHTML($yourText);
$yourText = $doc->saveHTML();
I have solution for php
<?php
// close opened html tags
function closetags ( $html )
{
#put all opened tags into an array
preg_match_all ( "#<([a-z]+)( .*)?(?!/)>#iU", $html, $result );
$openedtags = $result[1];
#put all closed tags into an array
preg_match_all ( "#</([a-z]+)>#iU", $html, $result );
$closedtags = $result[1];
$len_opened = count ( $openedtags );
# all tags are closed
if( count ( $closedtags ) == $len_opened )
{
return $html;
}
$openedtags = array_reverse ( $openedtags );
# close tags
for( $i = 0; $i < $len_opened; $i++ )
{
if ( !in_array ( $openedtags[$i], $closedtags ) )
{
$html .= "</" . $openedtags[$i] . ">";
}
else
{
unset ( $closedtags[array_search ( $openedtags[$i], $closedtags)] );
}
}
return $html;
}
// close opened html tags
?>
You can use this function like
<?php echo closetags("your content <p>test test"); ?>
You can use Tidy:
Tidy is a binding for the Tidy HTML clean and repair utility which allows you to not only clean and otherwise manipulate HTML documents, but also traverse the document tree.
or HTMLPurifier
HTML Purifier is a standards-compliant
HTML filter library written in
PHP. HTML Purifier will not only remove all malicious
code (better known as XSS) with a thoroughly audited,
secure yet permissive whitelist,
it will also make sure your documents are
standards compliant, something only achievable with a
comprehensive knowledge of W3C's specifications.
For HTML fragments, and working from KJS's answer I have had success with the following when the fragment has one root element:
$dom = new DOMDocument();
$dom->loadHTML($string);
$body = $dom->documentElement->firstChild->firstChild;
$string = $dom->saveHTML($body);
Without a root element this is possible (but seems to wrap only the first text child node in p tags in text <p>para</p> text):
$dom = new DOMDocument();
$dom->loadHTML($string);
$bodyChildNodes = $dom->documentElement->firstChild->childNodes;
$string = '';
foreach ($bodyChildNodes as $node){
$string .= $dom->saveHTML($node);
}
Or better yet, from PHP >= 5.4 and libxml >= 2.7.8 (2.7.7 for LIBXML_HTML_NOIMPLIED):
$dom = new DOMDocument();
// Load with no html/body tags and do not add a default dtd
$dom->loadHTML($string, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$string = $dom->saveHTML();
In addition to server-side tools like Tidy, you can also use the user's browser to do some of the cleanup for you. One of the really great things about innerHTML is that it will apply the same on-the-fly repair to dynamic content as it does to HTML pages. This code works pretty well (with two caveats) and nothing actually gets written to the page:
var divTemp = document.createElement('div');
divTemp.innerHTML = '<p id="myPara">these <i>tags aren\'t <strong> closed';
console.log(divTemp.innerHTML);
The caveats:
The different browsers will return different strings. This isn't so bad, except in the the case of IE, which will return capitalized tags and will strip the quotes from tag attributes, which will not pass validation. The solution here is to do some simple clean-up on the server side. But at least the document will be properly structured XML.
I suspect that you may have to put in a delay before reading the innerHTML -- give the browser a chance to digest the string -- or you risk getting back exactly what was put in. I just tried on IE8 and it looks like the string gets parsed immediately, but I'm not so sure on IE6. It would probably be best to read the innerHTML after a delay (or throw it into a setTimeout() to force it to the end of the queue).
I would recommend you take #Gordon's advice and use Tidy if you have access to it (it takes less work to implement) and failing that, use innerHTML and write your own tidy function in PHP.
And though this isn't part of your question, as this is for a CMS, consider also using the YUI 2 Rich Text Editor for stuff like this. It's fairly easy to implement, somewhat easy to customize, the interface is very familiar to most users, and it spits out perfectly valid code. There are several other off-the-shelf rich text editors out there, but YUI has the best license and is the most powerful I've seen.
A better PHP function to delete not open/not closed tags from webmaster-glossar.de (me)
function closetag($html){
$html_new = $html;
preg_match_all ( "#<([a-z]+)( .*)?(?!/)>#iU", $html, $result1);
preg_match_all ( "#</([a-z]+)>#iU", $html, $result2);
$results_start = $result1[1];
$results_end = $result2[1];
foreach($results_start AS $startag){
if(!in_array($startag, $results_end)){
$html_new = str_replace('<'.$startag.'>', '', $html_new);
}
}
foreach($results_end AS $endtag){
if(!in_array($endtag, $results_start)){
$html_new = str_replace('</'.$endtag.'>', '', $html_new);
}
}
return $html_new;
}
use this function like:
closetag('i <b>love</b> my <strike>cat');
#output: i <b>love</b> my cat
closetag('i <b>love</b> my cat</strike>');
#output: i <b>love</b> my cat
Erik Arvidsson wrote a nice HTML SAX parser in 2004. http://erik.eae.net/archives/2004/11/20/12.18.31/
It keeps track of the the open tags, so with a minimalistic SAX handler it's possible to insert closing tags at the correct position:
function tidyHTML(html) {
var output = '';
HTMLParser(html, {
comment: function(text) {
// filter html comments
},
chars: function(text) {
output += text;
},
start: function(tagName, attrs, unary) {
output += '<' + tagName;
for (var i = 0; i < attrs.length; i++) {
output += ' ' + attrs[i].name + '=';
if (attrs[i].value.indexOf('"') === -1) {
output += '"' + attrs[i].value + '"';
} else if (attrs[i].value.indexOf('\'') === -1) {
output += '\'' + attrs[i].value + '\'';
} else { // value contains " and ' so it cannot contain spaces
output += attrs[i].value;
}
}
output += '>';
},
end: function(tagName) {
output += '</' + tagName + '>';
}
});
return output;
}
I used to the native DOMDocument method, but with a few improvements for safety.
Note, other answers that use DOMDocument do not consider html strands such as
This is a <em>HTML</em> strand
The above will actually result in
<p>This is a <em>HTML</em> strand
My Solution is below
function closeDanglingTags($html) {
if (strpos($html, '<') || strpos($html, '>')) {
// There are definitiley HTML tags
$wrapped = false;
if (strpos(trim($html), '<') !== 0) {
// The HTML starts with a text node. Wrap it in an element with an id to prevent the software wrapping it with a <p>
// that we know nothing about and cannot safely retrieve
$html = cHE::getDivHtml($html, null, 'closedanglingtagswrapper');
$wrapped = true;
}
$doc = new DOMDocument();
$doc->encoding = 'utf-8';
#$doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
if ($doc->firstChild) {
// Test whether the firstchild is definitely a DOMDocumentType
if ($doc->firstChild instanceof DOMDocumentType) {
// Remove the added doctype
$doc->removeChild($doc->firstChild);
}
}
if ($wrapped) {
// The contents originally started with a text node and was wrapped in a div#plasmappclibtextwrap. Take the contents
// out of that div
$node = $doc->getElementById('closedanglingtagswrapper');
$children = $node->childNodes; // The contents of the div. Equivalent to $('selector').children()
$doc = new DOMDocument(); // Create a new document to add the contents to, equiv. to "var doc = $('<html></html>');"
foreach ($children as $childnode) {
$doc->appendChild($doc->importNode($childnode, true)); // E.g. doc.append()
}
}
// Remove the added html,body tags
return trim(str_replace(array('<html><body>', '</body></html>'), '', html_entity_decode($doc->saveHTML())));
} else {
return $html;
}
}

Categories