I was recently attempting to do an update to my views and replace the vanilla asterisk "*" character which was meant to represent a star with the unicode black star "★" (U+2605, "★"; "★"; 0xE2 0x98 0x85 (e29885)). Everything seemed to work great as I added the character into a string in the appropriate views. One of such views is shown below.
_recent_updates.html.haml
%table.tablesorter#home
%thead
%tr#header
%th#year Year
%th#name Player Name
%th#position Position
%th#school School
%th#stars Stars
%tbody
- #recent_commits.each do |rc|
%tr{:class => cycle("odd", "even")}
%td#class= rc.player.year
%td#name= link_to display_name(rc.player), player_path(rc.player.slug)
%td#position= Position.find(rc.player.position_id).abbr if rc.player.position_id
%td#school= link_to rc.school.name, school_path(rc.school.slug)
%td#stars= "#{display_star(rc.player.vc_star_rating)}★"
I released the update and went along with my business. A couple of days later, I checked Google Analytics to see how traffic was going to the site, and I noticed a precipitous drop to nearly zero. I did some checking as I knew there was a great deal of traffic to the site during this time period, and realized that there was something wrong with my google analytics code. When I looked at the source code for the page in production, here is what I saw.
<--! ...My Page Contents -->
<script type="text/javascript">
if (typeof gaJsHost == 'undefined') {
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-XXXXXXXX-1");
pageTracker._trackPageview();
} catch(err) {}</scr
It appears that the extra bytes consumed by the unicode character were unaccounted for so that they effectively ate the bottom of my page, causing it to end abruptly. What I should have seen was that script tag should have been ended, as well as the end of the body and html tags like so.
<--! ... My Page Contents -->
<script type="text/javascript">
if (typeof gaJsHost == 'undefined') {
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-XXXXXXXX-1");
pageTracker._trackPageview();
} catch(err) {}</script>
</body>
</html>
I reverted to the previous change from git (the replacement of asterisks with stars was the only change in the commit in question), and my Google Analytics Tracking Code works fine again, and my script, body and html tags all have their proper closing tags.
My question is two fold.
How do I add the star character back into my view without eating up the end of my code?
I thought UTF-8 was supported out of the box in Rails 3.1, so why is this happening?
I have not seen this issue with Google Analytics in particular, but in general you will get errors if your Rails source files contain Unicode characters without having the
# encoding: UTF-8
line at the top. Double-check that your HAML file is actually encoded as UTF-8 and not anything weird like UTF-16 or a non-Unicode format, then add this tag to the top and see if that solves the issue. You may also try setting Haml::Template.options[:encoding] = "utf-8" in your environment.rb - afaik it should be the default, but may be overridden somewhere.
Rails 3.1 supports Unicode out of the box, but doesn't tolerate Unicode inside its code unless you ask it to. Also note that some database drivers still don't fully support Unicode.
After banging my head against the wall for a few days, and adding some variation of "encoding: UTF-8" to just about every file in my Rails app, I decided to try using the html code ★. First I went to the trusty HTML2HAML converter. It told be that the html code ★ converted to \★ in haml. So I tried that and got a nasty little ISE message. I tried a couple of other variations until finally I stumbled upon a solution.
I created an erb based partial _star.html.erb which I called from my _recent_updates.html.haml file specifically to render the star. Once I did that, everything cleared up and worked like a charm.
I'm still not sure what was going on with the haml, but I'm hoping someone smarter than me can figure it out.
Last line updated:
_recent_updates.html.haml
%table.tablesorter#home
%thead
%tr#header
%th#year Year
%th#name Player Name
%th#position Position
%th#school School
%th#stars Stars
%tbody
- #recent_commits.each do |rc|
%tr{:class => cycle("odd", "even")}
%td#class= rc.player.year
%td#name= link_to display_name(rc.player), player_path(rc.player.slug)
%td#position= Position.find(rc.player.position_id).abbr if rc.player.position_id
%td#school= link_to rc.school.name, school_path(rc.school.slug)
%td#stars
= render 'star', :rc => rc
My new partial
_star.html.erb
<%= "#{display_star(rc.player.vc_star_rating)}" %>★
Related
A proposed change to the Content Security Policy (CSP) of our web server to disallow inline script
is causing a problem with the documentation generated by doxygen. Specifically, the problem occurs
in the generated index.html file, and the following lines:
<!-- Generated by Doxygen 1.8.15 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* #license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',false,false,'search.php','Search');
})
/* #license-end */</script>
If the initMenu() code is put into a separate file that is just included like other JavaScript files, everything
works just fine. Is there a doxygen option to put all JavaScript into files rather that inline? We can
post process the generated file to do this, but may not know when the "pattern" of this code may
change due to updates in doxygen itself. And we may not know if using additional doxygen features will result in other inline JavaScript.
Any suggestions would be welcome.
Thank you
Fritz Sieker
First off Content Security Policy is useful but far from being an absolute authority. There are other completely useless headers such as those that block referrers based on "privacy".
Secondly there is no such thing as "text/javascript", perhaps they meant application/javascript?
If you're using good (though very non-common practices) you don't have any script elements in the body element (use defer="true" on script elements in the head). By doing that you'll better understand the structure of JavaScript and that in turn will help you become more proficient/capable/help more people/make more money/etc.
You can use document.getElementsByTagName('body')[0].getElementsByTagName('script') to find all the script elements in the body element that don't belong there.
If you do have script elements in the body element beforehand and moving them to the head element is not feasible right now you're likely going to have to work with inherent logic, in short those script elements will always be inserted in to the DOM in a specific and reasonably easily reproducible area of your code (like as the very last elements). In such a case you can find them via the following:
document.getElementsByTagName('body')[0].lastChild
document.getElementsByTagName('body')[0].lastChild.previousSibling
document.getElementsByTagName('body')[0].lastChild.previousSibling.previousSibling
Keep in mind that pressing Enter in your code to make it more readable will insert a textNode so you may want to append nodeName to those instances and look for "script":
console.log(document.getElementsByTagName('body')[0].lastChild.nodeName);
There is the DOM TreeWalker that might help you out here, subjective to the end result in your DOM. I don't know offhand if you can transverse all the elements in reverse (probably).
Once you know what you want to delete instead of making everything convoluted just send that object (or id) to the following:
function element_del(id)
{
if (typeof id=='string' && id_(id) && id_(id).parentNode.removeChild)
{
id_(id).parentNode.removeChild(id_(id));
}
else if (typeof id=='object' && typeof id.parentNode=='object') {id.parentNode.removeChild(id);}
}
//Example:
element_del(document.getElementsByTagName('body')[0].lastChild);
I hope this helps!
I was trying to type the few lines in firefox and expect to use getContent{format: text} to only fetch the content.
Here is the content: (I have three lines and each start with the leftmost postion)
"text me if
there is
a chance"
It works in chrome that it gives the following format when running getContent.
...
<body>
text me if
there is
a chance
</body>
...
However in firefox I got:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
text me ifthere isa chance
</body>
</html>
It seems to strip off the line break. Could someone help on this?
In TinyMCE 4+ there is no option to disable stripping off line breaks. For me a littly dirty hack worked - just replace line breaks with <br> tags before initializing TinyMCE:
//imagine that your textarea is called textarea#message
var a = $("textarea#message").val();
a = a.replace(/\n/g, '<br />');
$("textarea#message").val(a);
If you need afterwards text without <br> but with line breaks, just apply the same transformation vise versa:
var a = $("textarea#message").val();
a = a.replace(/<br\s*[\/]?>/gi, "\n");
$("textarea#message").val(a);
Maybe a bit late to the party, but it just happened to me to walk into the same problem. It seems firefox has some issues with linebreaks in text that gets inserted into a textarea. My solution was something like this:
var text = text.replace("\r\n", "\\r\\n");
I guess FireFox is just a great fan of Slash(es)...
For the full solution I used the following code, which does not use the format: text, but format: html which get parsed by the DOMParser first:
var text = editor.getContent({ format: 'html' });
var doc = new DOMParser().parseFromString(text, 'text/html');
text = doc.body.textContent.replace("\r\n", "\\r\\n");
In case you still want to have tags within the code to display aswell as the link as the text within the tag add this line before the DOMParser:
text = text.replace(/<a.*href="(.*?)".*>(.*?)<\/a>/gi, ' $2: $1 ');
Which will change:
Go to some page
to this:
Go to some page: //some.link
Cheers!
To make sure things like this don't happen you should use a <br> tag instead of a regular line brea (ctrl+return). This is the default procedure in html code.
I got around it by using DOMParser().
tinymceContextValue = tinymce.get('abstract1').getContent({format: 'html'});
var doc = new DOMParser().parseFromString(tinymceContextValue ,'text/html');
tinymceContextValue = doc.body.textContent;
In this case, we could still preserve the line break. But be noted that do not change the tinymce configuration to enable . It will not work with it.
I'm writing a plugin which should add HTML to the page's head area (inludeJS to be exact). Something like this should work:
page.includeJS {
tx_myplugin_pi1 = EXT:my_plugin/pi1/tx_myplugin_fe_scripts.js
}
The problem with that is that I have to assume that "page" would be the universal name used for the page object I want to work with. Since the name of this variable can be anything I would like to do this in a more intelligent way than this.
Is there a way to determine the name of the current PAGE cObject I'm working with?
cu
Roman
You can find out the default PAGE object of the current page using this snippet:
$setup = $GLOBALS['TSFE']->tmpl->setup;
foreach(array_keys($setup) as $key){
if(substr($key, -1) == '.'){
if($setup[substr($key,0,-1)] === 'PAGE' && intval($setup[$key]['typeNum']) === 0){
print substr($key,0,-1) .' is the default PAGE object';
}
}
}
But this won't help you to add the Javascript in the frontend, as the typoscript is being parsed already at that point.
If you want to add the javascript just for your extension I would recommend using:
$GLOBALS['TSFE']->additionalHeaderData['tx_yourextension_plugin'] = '<script type="text/javascript" src="' . t3lib_extMgm::siteRelPath('my_plugin') . 'pi1/tx_myplugin_fe_scripts.js"></script>';
(this wouldn't be merged with the other JS files though)
Actually there is no such way in plain TypoScript. As most installations are using page as keyword - especially those which are under your control - it is really fine to use it.
If you are writing an extension, you can put that into the documentation as a small hint!
I use tinymce on my website and I always run into this annoying j is null.
In my template file I originally had the init method out in the open like in the example...
<script type="text/javascript" >
tinyMCE.init({
mode : "textareas",
theme : "simple"
});
</script>
But in the error console of Firefox I see something that says "j is null" and the reference is somewhere within the tiny_mce.js file.
Any help is appreciated. Thanks so much.
It's a tinymce bug. Internally, the tinymce code uses a <span id="mce_marker"></span> to remember the caret-position when pasting. when validating the resulting fragment, after the paste, the span is deemed invalid and removed, thus breaking the code by removing the marker.
This issue will be fixed in the next official tinymce minor release. There are some workarounds for this kind of issue. One is to add to add id and mce-data-type attribute to spans as valid elements (init setting). Example:
// The valid_elements option defines which elements will remain in the edited text when the editor saves.
valid_elements: "#[id|class|title|style]," +
"a[name|href|target|title]," +
"#p,-ol,-ul,-li,br,img[src],-sub,-sup,-b,-i,-u" +
"-span[data-mce-type]",
I'm using the IE8 debugger to fix a script that works great in FF 3.16 and Chrome 12.0, but doesn't work for beans in IE 8.0 or Safari 5.0. The spot in the script that's giving me trouble is here:
I need to find the number of <td>s in the the table id="main_tbody" whose children[0] is the first row of data. Both FF and Chrome understand this perfectly; IE 8 and Safari 5 do not.
I want to look at the DOM tree in the IE 8 debugger to see what's going on. But I can't find the ding-dong DOM, dang it!
So: where is the DOM in the IE 8 debugger?
Alternatively <ahem!>: what's wrong with my JS code?
Thanks!
EDIT: I should have said that the table is set up like this:
<table id ="main">
<tbody id="main_tbody">
And references to table id ="main" and tbody id="main_tbody" are initialized this way:
main = getRefToDiv( 'main' );
main_tbody = getRefToDiv( 'main_tbody' );
Call the position_col_heads() function after your </body>
My suspicion is that this function is declared inside the head tag or being called before the browser renders the body content.
Just try this.
...
...
</body>
<script type='text/javascript'>
position_col_heads();//Set breakpoint here and see if its accessible.
</script>
</html>
Also, see what response you get for main.children[0] and main_tbody.innerHTML in your watch expression.
Unbelievable. According to quirksmode, ie8 fails to implement childElementCount and I believe it because that's the thing that's coming back == 'undefined'. So I'll rewrite my loop with a new exit condition. That sucks, because now I'm going to get all children, including comments and everything else, not just the elements I was looking for. Incredible. FYI, ie8 also does not implement firstElementChild, lastElementChild, nextElementSibling, or previousElementSibling.