Google MailApp (Javascript) and PRE tag - google-apps-script

I am trying to produce an HTML button in a mail message - sending from the Javascript "flavour"of GAS MailApp.
I have tried three different mail readers to eliminate that cause (Thunderbird, Mac Mail and Chrome)
I am sending this HTML via the htmlBody, advanced, parameter of the MailApp:
<script>function blah()
{alert('hi');
}</script>"+
"<input type<pre>=</pre>'submit' id<pre>=</pre>'deleteBookingButton'
value<pre>=</pre>'Delete booking' onclick<pre>=</pre>'this.disabled<pre>=</pre>true;blah()'></br>";
and the message is rendered as:
<script>function blah(){alert('hi=
');}</script><input type<pre>=3D</pre>'submit' id<pre>=3D</pre>'deleteBooki=
ngButton' value<pre>=3D</pre>'Delete booking' onclick<pre>=3D</pre>'this.di=
sabled<pre>=3D</pre>true;blah()'></br>9fgnbterk48818il9j3c933fa0#google.com=
</br>
As you can see the equals signs are not being rendered correctly.
I have tried escaping the equals sign
(&eq; =)
and CDATA.
If at all possible I'd like a raw (ie not Node or similar) solution

Related

How to send newline commands over Websocket message?

Setup
Python FastApi backend server
JS React frontend client
react-use-websocket for frontend ws client
Issue
So I need to send some messages from backend API to frontend client over Websocket connections and display these messages to user. However I don't know how to escape to a new line while displaying these messages. I tried sending \n inside the Websocket message. JS doesn't display this \n character but neither does switch to a newline. It just ignores it. Also tried sending some whitespace but that didn't help either. It just shows a single space regardless of how many whitespaces I left at the API side.
Code
note: TextTransition component is from react-text-transition but the
behavior is same with a standart html paragraph.
const {lastJsonMessage} = useWebSocket(socketURL);
//...
return (
<div>
...
...
<div style={boxStyle}>
<h1 style={{cursor: "default"}}>Message</h1>
<p style={{cursor: "default"}}>━━━━━━━━━━━━━━━━━</p>
<TextTransition
text={lastJsonMessage ? lastJsonMessage.message : ""}
style={{cursor: "default"}}
springConfig={ presets.stiff }
/>
</div>
...
...
</div>
)
What can and should I do? Thanks in advance.
\n does not cause a new line in HTML. You will either need to send <br/> instead, or replace \n on the client side with that, for instance:
<TextTransition
text={lastJsonMessage ? lastJsonMessage.message.replace(/\n/g, '<br/>') : ""}
style={{cursor: "default"}}
springConfig={ presets.stiff }
/>
This assumes that TextTransition accepts HTML (not just text). If the latter then you may be out of luck, because that component just won't let you set control characters in your text.

XPath for all element text that does not contain certain values

I have the following HTML structure which contain few email list, and I want grab email which email business, and not yahoo, gmail, hotmail, etc
some#yahoo.com
s0m3#ymail.com
mail#yourbusiness.com
you#gmail.com
this#mybusinessmail.co.uk
me#hotmail.com
So what I want is
mail#yourbusiness.com
this#mybusinessmail.co.uk
My idea is
get A tag which NOT contain ymail AND NOT contain yahoo AND NOT contain gmail, AND NOT contain hotmail
But how can I write XPath syntax according to above idea ?
Your idea translates directly into XPath as follows:
//a[not(contains(., 'ymail')) and not(contains(., 'yahoo')) and not(contains(., 'gmail')) and not(contains(., 'hotmail'))]/text()
For your example (with a single root element added),
<html>
some#yahoo.com
s0m3#ymail.com
mail#yourbusiness.com
you#gmail.com
this#mybusinessmail.co.uk
me#hotmail.com
</html>
it selects
mail#yourbusiness.com
this#mybusinessmail.co.uk
as requested.
You could use the substring-after and substring-before to get the part after the # and before the first . combined with not and contains
So substring-before(substring-after(text(),"#"),'.') would get the first part of the domain and //a[not(contains("ymail yahoo gmail hotmail", ...))] would exclude the ones you want.
Altogether
//a[not(contains("ymail yahoo gmail hotmail", substring-before(substring-after(text(),"#"),'.')))]

Why does HTML5 form-validation allow emails without a dot?

I'm writing a very simple mock-up to demonstrate some HTML5 form-validation. However, I noticed the email validation doesn't check for a dot in the address, nor does it check for characters following said dot.
In other words, "john#doe" is considered valid, when it's clearly not a valid email address; "doe" isn't a domain.
This is how I'm coding my email field:
<input type="email" required />
Is that not enough?
Check this fiddle to see what I mean.
Note: I know how to accomplish this via a RegEx pattern instead. I'm just wondering how someone could get away with using the email type instead.
You can theoretically have an address without a "." in.
Since technically things such as:
user#com
user#localserver
user#[IPv6:2001:db8::1]
Are all valid emails.
So the standard HTML5 validation allows for all valid E-mails, including the uncommon ones.
For some easy to read explanations (Instead of reading through the standards):
http://en.wikipedia.org/wiki/Email_address#Examples
Update from a comment: ICANN banned so-called "dotless" domains in 2013, but since that doesn't affect every case listed above, allowing "dotless" addresses is still valid.
Because a#b is a valid email address (eg localhost is a valid domain). See http://en.wikipedia.org/wiki/Email_address#Examples
Also, keep in mind that you should always do the input validation in server. The client side validation should be only for giving feedback to the user and not be relied on, since it can be easily bypassed.
Try adding this to the input
pattern="[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,63}$"
Fiddle
The RFC 822, chapter 6, gives the specification of an address in augmented Backus-Naur Form (BNF):
addr-spec = local-part "#" domain
local-part = word *("." word)
domain = sub-domain *("." sub-domain)
Using this specification a#b is a valid address.
UPDATE
To answer the comment of Trejkaz, I add the following definitions. We see that SPACE are allowed but only in quoted string.
word = atom / quoted-string
atom = 1*<any CHAR except specials, SPACE and CTLs>
quoted-string = <"> *(qtext/quoted-pair) <">
SPACE = <ASCII SP, space>
CTL = <any ASCII control character and DEL>
qtext = <any CHAR excepting <">, "\" & CR, and including linear-white-space>
quoted-pair = "\" CHAR
This MDN page shows the regex browsers should use to validate the email:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email#Validation
You can slightly change this regex to require at least one dot in the domain name: change the star * at the end of the regex to a plus +. Then use that regex as the pattern attribute:
<form>
<input
type="email"
pattern="^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$"
title="Valid e-mail address including top-level domain"
required
/>
<button type="submit">Test</button>
</form>
You can customize the pattern of the email field:
input:valid {
border-color: green
}
input:invalid {
border-color: red
}
Email:
<input type="email" required value="a#b.c" /><br>
Non-dots Email:
<input type="email" required pattern="[^.]+#[^.]+" value="a#b.c" />
Here is how you can do it with html5 using regex pattern. You can also include a custom message to display.
<form>
<input type="email" value="paul#test" required pattern="[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,63}$" title="Hey, you are missing domain part in the email !!!"/>
<button type="submit">Click Me</button>
</form>
Hostnames without a TLD appear to be valid.
I say "appear" because there is this 2013 ICANN prohibition on dotless domains . . .
At its meeting on 13 August 2013, the ICANN Board New gTLD Program Committee (NGPC) adopted a resolution affirming that "dotless domain names" are prohibited.
. . . but judging from real world experience, it appears to have never been enforced.
Regardless, the PHP function FILTER_VALIDATE_EMAIL doesn't allow for dotless domain names.
So here's a simple back-end validation set-up that covers both your email and required fields:
if (empty($required_field) OR empty($another_required_field) OR
!filter_var($email_field, FILTER_VALIDATE_EMAIL)) {
// error handling here
exit;
}
While the "malformed" email may get passed the browser, it won't get passed the server.
References:
FILTER_VALIDATE_EMAIL definition
List of valid and invalid email addresses
This pattern always works for me.
Text must in lowercase pattern="[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,}$" but I think it covers more or less most emails.

$_GET textarea losing HTML characters

This is probably a really simple one but I can't find the answer anywhere!
I have a self submitting form with a textarea field like this
<textarea name="desc" wrap="1" cols="64" rows="5"></textarea>
When I type HTML characters in to the textarea field and hit the submit button, the HTML characters are being stripped and I can't see what is doing it!
Do $_GET variables have their HTML stripped automatically?
For example, If I type '[strong]Just[/strong] a test' in to the textarea, and echo the contents of 'desc' like this
echo(print_r($_GET));
I see $_GET['desc'] contains 'Just a test' rather than '[strong]Just[/strong] a test'.
Is this normal? If so, is there a way to keep the HTML so I can store it in a database?
I am using angle '<>' brackets rather than square '[]' in my code, but this forum converts them if I use them here!
Use CDATA
A CDATA section starts with "<![CDATA[" and ends with "]]>"
Source : http://www.w3schools.com/xml/xml_cdata.asp
Where are you printing the data too? The web will parse the html and if you're not looking at the page source you're only going to see the non-html parts.
However, you should be using print html_entities($_GET['desc']) to print out the contents with the html content properly encoded so it's printed instead of parsed.

How to stop an html TEXTAREA from decoding html entities

I have a strange problem:
In the database, I have a literal ampersand lt semicolon:
<div
whenever its printed into a html textarea tag, the source code of the page shows the > as >.
How do I stop this decoding?
You can't stop entities being decoded in a textarea since the content of a textarea is not (unlike a script or style element) intrinsic CDATA, even though error recovery may sometimes give the impression that it is.
The definition of the textarea element is:
<!ELEMENT TEXTAREA - - (#PCDATA) -- multi-line text field -->
i.e. it contains PCDATA which is described as:
Document text (indicated by the SGML construct "#PCDATA"). Text may contain character references. Recall that these begin with & and end with a semicolon (e.g., Hergé's adventures of Tintin contains the character entity reference for the e acute character).
This means that when you type (the invalid HTML of) "start of tag" (<) the browser corrects it to "less than sign" (<) but when you type "start of entity" (&), which is allowed, no error correction takes place.
You need to write what you mean. If you want to include some HTML as data then you must convert any character with special meaning to its respective character reference.
If the data is:
<div
Then the HTML must be:
<textarea>&lt;div</textarea>
You can use the standard functions for converting this (e.g. PHP's htmlspecialchars or Perl's HTML::Entities module).
NB 1: If you were using XHTML[2] (and really using it, it doesn't count if you serve it as text/html) then you could use an explicit CDATA block:
<textarea><![CDATA[<div]]></textarea>
NB 2: Or if browsers implemented HTML 4 correctly
Ok , but the question is . why it decodes them anyway ? assuming i've added & , save the textarea , ti will be saved < , but displayed as < , saving it again will convert it back to < (but it will remain < in the database) , saving again will save it a < in the database , why the textarea decodes it ?
The server sends (to the browser) data encoded as HTML.
The browser sends (to the server) data encoded as application/x-www-form-urlencoded (or multipart/form-data).
Since the browser is not sending the data as HTML, the characters are not represented as HTML entities.
If you take the data received from the client and then put it into an HTML document, then you must encode it as HTML first.
In PHP, this can be done using htmlentities(). Example below.
<?php
$content = "This string contains the TM symbol: ™";
print "<textarea>". htmlentities($content) ."</textarea>";
?>
Without htmlentities(), the textarea would interpret and display the TM symbol (™) instead of "™".
http://php.net/manual/en/function.htmlentities.php
You have to be sure that this is rendered to the browser:
<textarea name="somename">&lt;div</textarea>
Essentially, this means that the & in < has to be html encoded to &. How to do it will depend on the technologies you're using.
UPDATE: Think about it like this. If you want to display <div> inside a textarea, you'll have to encode <> because otherwise, <div> would be a normal HTML element to the browser:
<textarea name="somename"><div></textarea>
Having said this, if you want to display <div> inside a textarea, you'll have to encode & again, because the browser decodes HTML entities when rendering HTML. It has nothing to do with your database.
You can serve your DB-content from a separate page and then place it in the textarea using a Javascript (jQuery) Ajax-call:
request = $.ajax
({
type: "GET",
url: "url-with-the-troubled-content.php",
success: function(data)
{
document.getElementById('id-of-text-area').value = data;
}
});
Explained at
http://www.endtask.net/how-to-prevent-a-textarea-element-from-decoding-html-entities/
I had the same problem and I just made two replacements on the text to show from the database before letting it into the text area:
myString = Replace(myString, "&", "&")
myString = Replace(myString, "<", "<")
Replace n:o 1 to trick the textarea to show the codes.
replace n:o 2: Without this replacement you can not show the word "" inside the textarea (it would end the textarea tag).
(Asp / vbscript code above, translate to a replace method of your language choice)
I found an alternative solution for reading and working with in-browser, simply read the element's text() using jQuery, it returns the characters as display characters and allows me to write from a textarea to a div's innerHTML using the property via html()...
With only JS and HTML...
...to answer the actual question, with a bare-minimal example:
<textarea id=myta></textarea>
<script id=mytext type=text/plain>
™
</script>
<script> myta.value = mytext.innerText; </script>
Explanation:
Script tags do not render html nor entities. By storing text in a script tag, it will remain unadultered-- problem is it will try to execute as JavaScript. So we use an empty textarea and store the text in a script tag (here, the first one).
To prevent that, we change the mime-type to text/plain instead of it's default, which is text/javascript. This will prevent it from running.
Then to populate the textarea, we copy the script tag's content to it (here done in the second script tag).
The only caveats I have found with this are you have to use JavaScript and you cannot include script tags directly in it.