I am having some problems getting CodeMirror to indent the code at the beginning of a new line.
I have a text area, and when I hit save, the code that is saved to the DB is something like:
<meta charset=\"utf-8\">\r\n\t\t\t<title></title>\r\n\r\n<div class=\"wra ... etc
But when I read that out and do in the code behind in asp.net, ViewCode.Text = dbModel.ViewCode ... i.e. try to assign that string to the textarea which will then be 'converted' into the code mirror editor with relevant js on the page, the indent at the start of new lines is lost. If I indent half way along a line however, those render.
Also, if there is a new line return and then a blank row and then more text, the blank row gets lost when read back out to the text area.
Note: the textarea is runat server to fill the value from the database. I have tried with divs and literals but can't get it working.
So how can I save something like:
<div>
<b>
test
</b>
</div>
and not get it back like
<div>
<b>
test
</b>
</div>
I presume I have to encode it on save but I swear I have tried all encoding methods and now work! lol
Any pointers would be appreciated.
Cheers
Robin
Update/Solution
I have come back to put this in, in case some one stumbles across this post.
Basically I could not still not get the following to play nicely on the particular page in question. I.e.
Code behind
ViewCode.Value = dbModel.ViewCode
where
dbModel.ViewCode
// --> is comes from db as e.g.:
// <meta charset=\"utf-8\">\r\n\t\t\t<title></title>\r\n\r\n<div class=\"wra ... etc
JS (at end of page)
<script>
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("ViewCode"), {
lineNumbers: true
});
</script>
What I did get working however, is if you put the same JS code on the page, however, do NOT fill the text area from the code behind. Then I just make a simple ajax call to a page method to get the data (on page load).
$.ajax({
url: '/WidgetMaint.aspx/GetFileHTML',
type: 'Get',
contentType: 'application/json',
data: { tempid: id },
success: function(result) {
myCodeMirror.setValue(result.d);
}
});
The save and everything else works perfectly because the textarea is still run at server, so can still get its value 'on save', as code mirror takes care of this.
I am fairly sure that there is something else in the pipeline which is stuffing around with the text and 'formatting' it different before code mirror can get to it in time in the first attempt I was doing. However, with the ajax call the problem goes away because the browser/framework/whatever does not have any opportunity to access the string the DB returns. It is feed straight to the instance of code mirror which deals with it.
So in case you are having a similar problem, might be easier to change approach....
Cheers
Robin
Note: accepted answer by Eliran as it gave me this idea, and upvoted Marjin, because that comment proved it code mirror can handle indents...
I would advice you to drop that textarea and keep a live instance of CodeMirror on the page. That way you can assign the response directly to that instance using the CodeMirror API.
Take a look at doc.setValue(content: string) in particular, that should get you on the right track.
Related
EDIT: You can see the issue here (look in source).
EDIT2: Interesting, it is not an issue in source. Only with the console (Firebug as well).
I have the following markup in a file called test.html:
<!DOCTYPE html>
<html>
<head>
<title>Test Harness</title>
<link href='/css/main.css' rel='stylesheet' type='text/css' />
</head>
<body>
<h3>Test Harness</h3>
</body>
</html>
But in Chrome, I see:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
"
"
<title>Test Harness</title>
<link href='/css/main.css' rel='stylesheet' type='text/css' />
<h3>Test Harness</h3>
</body>
</html>
It looks like ̢ is a zero width space, but what is causing it? I am using Sublime Text 2 with UTF-8 encoding and Google App Engine with Jinja2 (but Jinja is simply loading test.html). Any thoughts?
Thanks in advance.
It is an issue in the source. The live example that you provided starts with the following bytes (i.e., they appear before <!DOCTYPE html>): 0xE2 0x80 0x8B. This can be seen e.g. using Rex Swain’s HTTP Viewer by selecting “Hex” under “Display Format”. Also note that validating the page with the W3C Markup Validator gives information that suggests that there is something very wrong at the start of the document, especially the message “Line 1, Column 1: Non-space characters found without seeing a doctype first.”
What happens in the validator and in the Chrome tools – as well as e.g. in Firebug – is that the bytes 0xE2 0x80 0x8B are taken as character data, which implicitly starts the body element (since character data cannot validly appear in the head element or before it), implying an empty head element before it.
The solution, of course, is to remove those bytes. Browsers usually ignore them, but you should not rely on such error handling, and the bytes prevent useful HTML validation. How you remove them, and how they got there in the first place, depends on your authoring environment.
Since the page is declared (in HTTP headers) as being UTF-8 encoded, those bytes represent the ZERO WIDTH SPACE (U+200B) character. It has no visible glyph and no width, so you won’t notice anything in the visual presentation even though browsers treat it as being data at the start of the body element. The notation is a character reference for it, presumably used by browser tools to indicate the presence of a normally invisible character.
It is possible that the software that produced the HTML document was meant to insert ZERO WIDTH NO-BREAK SPACE (U+FEFF) instead. That would have been valid, since by a special convention, UTF-8 encoded data may start with this character, also known as byte order mark (BOM) when appearing at the start of data. Using U+200B instead of U+FEFF sounds like an error that software is unlikely to make, but human beings may be mistaken that way if they think of the Unicode names of the characters.
I understand that there is a bug in SharePoint 2013 where the HTML editor adds these characters into your content.
I've been dealing with this for a bit and this is the solution I am using which seems to be working. I added this javascript into a file referenced by my masterpage.
var elements = ["h1","h2","h3","h4","p","strong","label","span","a"];
function targetZWS(){
for (var i = 0; i < elements.length; i++) {
jQuery(elements[i]).each(function() {
removeZWS(this);
});
}
}
function removeZWS(target) {
jQuery(target).html(jQuery(target).html().replace(/\u200B/g,''));
}
/*load functions*/
$(document).ready(function() {
_spBodyOnLoadFunctionNames.push("targetZWS");
});
Links I looked into investigating this:
https://social.msdn.microsoft.com/Forums/sharepoint/en-US/23804eed-8f00-4b07-bc63-7662311a35a4/why-does-sharepoint-put-in-character-code-8203-in-a-richtext-field?forum=sharepointdevelopment
https://social.technet.microsoft.com/Forums/office/en-US/e87a82f0-1ab5-4aa7-bb7f-27403a7f46de/finding-8203-unicode-characters-in-my-source-code?forum=sharepointgeneral
http://www.sharepointpals.com/post/Removing-8203-in-RichTextHTML-field-Sharepoint
Try this script. It works for me
$( document ).ready(function() {
var abc = document.body.innerHTML;
var a = String(abc).replace(/\u200B/g,'');
document.body.innerHTML = a;
});
I have experienced this in a major project I was working on.
The trick is to just:
copy the whole code into notepad.
save it as a text file.
close the file. open it again and copy your code back into your IDE
environment.
and its voilà, it's gone.!
I was able to remove these in Sublime by selecting the characters surrounding it and copy/pasting into Find and Replace.
In my case, symbol "" did not appear in the code editor MS Code and was visible only in the tab Elements Chrome. It helped to delete the tag after which this symbol appeared and the reprint of this tag was handwritten again, apparently this symbol clung to the ctrl+c / ctrl+v while transferring the code.
This “8203;” HTML character is a no width break control.
It can easily find in the Google Chrome Browser inspect elements section. And When you try to remove it from your code, most of the Major IDE not showing to me...(Maybe by my preference).
I found the new text editor Brackets download it and open my code in the editor. It shows the character with red dots. Just remove it check everything is working well.
I found this solution from a blog. What is “8203” HTML character? Why is being injected into my HTML?
Thank You for saving me hours.
I cannot find where it's being injected on my page. I'll investigate it more later, but for now, I just threw this in my page so I can keep working.
$(function(){
$('body').contents().eq(0).each(function(){
if(this.nodeName.toString()=='#text' && this.data.trim().charCodeAt(0)==8203){
$(this).remove();
}
});
});
On my jsf page at some point I send a message to the growl component.
<p:growl id="growlLong" for="growlLong" showDetail="true" life="10000" sticky="false"/>
Once the 10sec is over, or dismissed by clicking the X, the issue that occurs is the element below the growl is not selectable. By inspecting the components on the page, looks like the actual div stayed there and blocks the content below it.
<?xml version="1.0" encoding="UTF-8"?>
<div class="ui-growl-item">
<div class="ui-growl-icon-close ui-icon ui-icon-closethick" style="display: none;" />
<span class="ui-growl-image ui-growl-image-info" />
<div class="ui-growl-message">
<span class="ui-growl-title">Success!</span>
<p>Configuration successfully saved.</p>
</div>
<div style="clear: both;" />
</div>
So, the question is - how do I make this to go away and keep the content below still usable?
Here is the screenshot of the issue, as seen with "inspect element", blue boxes are existing links, red box is the dismissed growl. Inside the blue box, we can't click the part that is covered by the red box.
This topic might be older but I just recently stumbled upon it:
The reason that the showcase is working but my version was not was that I gave the .ui-growl CSS class a height AND a width. In the showcase, the size of the container is only defined by its content and thus 0 if there are no items to display.
I moved my height definition to .ui-growl-item (which is more appropriate anyhow) and now it's working like a charm.
While the it would be desirable to be able to tell growl to not leave behind the <div id="growlLong_container"> structure in the DOM, the simple solution is to just select it and remove it using your favorite method to manipulate the DOM.
The ID appears to be the ID you passed to growl: id="growlLong" + "_container". With a DOM ID it is a simple matter of selecting it and removing it.
Yes, it would be nice to be able to get growl to not leave it in there. However, there is a point of diminishing returns vs. the amount of effort you spend trying to find a solution. It appears to be well past the point where you should just use a hack and remove it. Make a note about it, move on. Leave a comment in the code that this is why you are making the DOM manipulation. A possibility rather than removing teh <div> is to adjust the z-index such that it is below that of the UI elements. Another possibility is to add display:none; to the style. Obviously, code it such that if the <div> is not there nothing goes wrong. Verify that the next use of growl still performs correctly.
Ask on the Growl discussion group. Submit it as a bug with growl. If a way surfaces to make growl not leave something like this in the DOM revisit the code and apply it.
As to removing it, if you have JavaScript available it is as simple as:
document.getElementById("growlLong_container").remove();
To be more specific we really need more information about your code and the environment in which you are running.
A "solution" that should remove the <div>:
Hopefully you will receive an answer which allows the elements to be hidden/removed by growl. However, there does not appear to be one at present.
The following script should wait around checking every 250ms to see if the <div id="growlLong_container"> has been entered into the DOM. Once the <div> has been entered into the DOM, the script will wait 10s. If the <div> exists after the 10s it will be removed. The script is a hack. But it should work.
You will need to place it such that it makes it onto the page, either enclosed in tags (as are here), or in a file without the first line:<script class="code" type="text/javascript"> and the last line: </script> removed. If you use a separate file you will need to have it included in a similar manner as you do jquery.js, foundation.js, foundation.topbar.js and foundation.tooltip.js.
<script class="code" type="text/javascript">
(function () {
"use strict";
const maxGrowlTime = 10000; //In milliseconds
const checkFrequency = 250; //In milliseconds
var intervalTimer=0;
var foundGrowl=false;
function dismissGrowl() {
var growlId;
growlId = document.getElementById("growlLong_container");
if(growlId) {
growlId.parentNode.removeChild(growlId);
}
foundGrowl=false;
setGrowlCheckInterval();
}
function checkForGrowl() {
var growlId;
if(foundGrowl) {
return;
}
growlId = document.getElementById("growlLong_container");
if(growlId) {
foundGrowl=true;
clearInterval(intervalTimer);
setTimeout(dismissGrowl, maxGrowlTime );
}
}
function setGrowlCheckInterval() {
intervalTimer = setInterval(checkForGrowl, checkFrequency );
}
setGrowlCheckInterval();
})();
</script>
My hope is that you find an answer that does not require a hack such as this. However, this should solve your problem, at least to an extent. With the script, the prevention of using those controls will last for at least the entire 10s up to 10.25s even if the user dismisses the growl early. With the two screenshots mentioned in the comments it would probably be possible to change the script such that it detects if the user dismisses the grow and then remove the <div> immediately. This would make it more responsive to user input.
This solution assumes that the <div id="growlLong_container"> does not exist in the DOM prior to your issuing the <p:growl id="growlLong" and that it is not needed afterwards. This is very likely because the ID of the dive appears to be composed of the ID you pass the growl.
Mainly, this issue looks like a bug or incompatibility issue between components.
I'm trying to create my first chrome extension. Basically I have a simple html page and some javascript that im using to allow users to enter some data, the script will format it correctly and then output it:
<form>
MAC ADDRESS: <input type="text" id="mac" name="macAddress" maxlength="17" >
<button onclick="convert(); return false;">Convert</button>
</form>
Javascript:
function convert() {
var mac = document.getElementById('mac').value; //get string
var mac2 = mac.replace(/\:|-/g,""); //remove colons and dashes
//
//add fullstops after every 4th character, appart from last character.
//
mac2 = mac2.replace(/(.{4})(?!$)/g , '$1.');
//output string
document.getElementById("outputDiv").innerHTML= mac2;
};
My problem is that while this works fine as a normal web page, the get method, to the same page, is not working when I tried to implement it as an extension.
I've followed the tutorials on google's site and the extension is showing up but it doesn't seem to be able to handle get requests. I've tried modifying the manifest file using different suggestions I found on here but still no success.
Theres nothing in the console when I try to debug it (something briefly flickers up when I submit the get request but it doesn't stay up long enough to see what the issue is).
I'd really appreciate it if someone could point me in the right direction with this!
Due to the Content Security Policy applied to extensions:
Inline JavaScript will not be executed. This restriction bans both inline blocks and inline event handlers (e.g. ).
[...]
The inline event handler definitions must be rewritten in terms of addEventListener and extracted into popup.js.
For more info atake a look at the docs.
I am building a Spotify App with four tab pages. The content of all tabs are loaded on initial load of the app. Each tab contain one or more playlists that are being populated with data from 3rd party web apis that are resolved into spotify tracks.
The selected tab works fine. the playlist show up a expected. The problem is with tabs that are initially hidden but later selected. Here the playlist looks like this when selected:
not fully rendered playlist
Looking in the Inspector I can see that the content has not yet rendered:
<div class="sp-list sp-light" tabindex="0">
<div style="height: 100px; ">
</div>
</div>
When I do a resize of the Spotify desktop app, the playlist is finally rendered:
rendered playlist after resize
To populate the playlist I use the 'standard' spotify models and views:
var playlist = new views.List(tempPlaylist);
//where tempPlaylist is a new models.Playlist();
//that has been populated with tempPlaylist.add(search.tracks[0].uri);
playerPlaylistDiv.append(playlist.node);
I am only seing this issue when using tabs. When displaying all content on one long page all playlists are fully rendered. I wonder if it has to do with timing: that I am hiding content that has not yet fully rendered? Any thoughts much appreciated.
I handle tab changes this way:
/* Handle URI arguments */
models.application.observe(models.EVENT.ARGUMENTSCHANGED, tabs);
/* Handle tab changes */
function tabs() {
var args = models.application.arguments;
// Hide all sections
$('section').hide();
// Show current section
$("#" + args[0]).show();
}
FYI I am using the Spotify preview 0.8.10.3.
I am not sure this is the same thing, but I ran into similar issues trying to create tracklistings from playlist-uris on the fly; also couldn't track it down any closer (the containing DOM was certainly rendered and ready); and it only happened on certain playlists, never e.g. on albums.
I was able to circumentvent this problem by "cloning" playlist - obviously there's a "performance" hit ...
// assuming uri is the playlist's URI
models.Playlist.fromURI( uri, function(originalPlaylist) {
var tempPlaylist = new model.Playlist();
$.each(originalPlaylist.tracks, function(t) { tempPlaylist.add(t); });
var tracklist = new views.List(tempPlaylist);
// etc...
}
I am not sure what's on here, but maybe that helps you along :)
PS. Also - make sure you have a doctype-declaration in index.html (), the spotify client does some weird things if you don't.
The solution I've found is this:
I arrowed it down to being an issue with showing/hiding the content since showing the full content without tabs never causes issues. So instead of using .show()/.hide() I now hide and show the content by setting the height of the sections to 100%/0:
// Hide all other sections
$("section#" + args).siblings().height('0');
// Show current section
$("section#" + args).height('100%');
Not sure why this works, but it does (for me at least).
I had the same problem (see Spotify List objects created from localStorage data come up blank) and fixed it by doing the hide()/show() of divs before any processing. Previously I was constructing the playlist and then show()ing the div after which led to a blank list.
I think I've actually managed to solve this and I think it's bulletproof.
Basically I was trying to solve this by trying to convince the API that it needed to redraw the playlist by hiding things/scrolling things/moving things which worked occasionally but never consistently. It never occurred to me to change the playlist itself. Or at least make the API think the playlist has changed.
You can do so by firing an event on the Playlist object.
var models = sp.require('$api/models');
...
// playlist is your Playlist object. Usually retrieved from models.Playlist.fromURI
playlist.notify(models.EVENT.CHANGE, playlist);
These are just standard Spotify functions and the list updates because it thinks something has changed in the playlist. Hope this helps someone!
Gmail introduced a trimming feature in emails for "better readability". This causes a lot of pain for me, as I have a notification system for email, where I send some html email messages to users. Basically email looks like this:
divs and styling
Object alert in Project by User
tables and tr/td
User Action on Object in Project
/tables and tr/td
/divs and styling
link
footer
To group all emails in one conversation, first email has subject, subsequent emails have Re: subject.
Active users can receive significant amounts of emails like this, but due to "better readability" feature, ALL of the email content (starting from second email) is suppressed.
I am looking for advice - maybe I should redesign my html, or gmail has some anti-suppression code, or just a hack to go around this issue.
Issue from users perspective is described here: http://www.google.com/support/forum/p/gmail/thread?tid=756b83fa60ca1df7&hl=en
I had the trimming problem occurring on a table of an HTML newsletter.
It was very important that the entire table display because it was the
#1 content our client wanted to communicate. Here's the fix, or at least here's how we solved our problem. We eliminated any repetition.
So for this table, the lines in between each row, Gmail was seeing the
lines as repetitive. So I altered the pixel width by 1 px every other
line, which eliminated the repetition and fixed our problem. So that
said, look for repetition, and try to remove it. OR in some cases, you
might have to add type (in white) to create the variation.
Source.
PS: This is a bit unrelated, but I stumbled upon this question while looking for a way to disable the content trimming and keep the conversation view at the same time. I didn't find anything, so I developed a small extension for Chrome and Firefox.
It turns out that there is a very simple rule which causes this behaviour: Gmail will clip the email as soon as it sees the sender (From:) name in the body of the message, regardless of where this appears.
Solution: make sure that that the From: name in your email is not used in the message body (except in the signature, which will probably get clipped!).
This is an awful bug in Gmail, if you're unlucky enough to get bitten by it.
In my case, it was "trimming" an entire message, in a clean thread. See an example here, noting that the "trimmed" content is expanded in the screen-shot.
I ultimately worked around Gmail's bug by removing the entire header you see in that example ("Awesome Home Swap"), including the border below it. I stopped short of actually trying to figure out what specifically was making Gmail confuse that header as a "signature" (though I suspect it could have been the border, implemented using CSS directive border-bottom:1px dotted grey to style the <td> element).
I just found a solution that worked wonderfully for me. Simply create a bunch of hidden unique images throughout your emails to provide uniqueness to parts of the email that aren't actually unique. I'm building my emails with React so I have this Unique components that I'm using pretty much everywhere:
import * as React from "react"
function random() {
return Math.round(Math.random() * 10000000).toString()
}
class Unique extends React.PureComponent {
render() {
return (
<img style={Unique.style} src={`data:image/png;base64,${random()}`} />
)
}
static style = {
visibility: "hidden",
display: "none",
width: 0,
height: 0,
color: "transparent",
background: "transparent",
}
}
One thing I like about this solution is that it doesn't mess up the email preview text that would otherwise happen if you're using hidden text.
Add a double hyphen -- before the collapsed part. I was able to wrap it in a with font color matching the background. Worked for me...
I looked at the emails Gmail sent. Adds the following code (spacer.gif).
I guess this is the solution.
<img alt="" height="1" width="3" src="https://notifications.google.com/g/img/AD-FnEztup4OClDshQhMVXDbi6Oi0lSN-FgEY1jyW384aotccA.gif">
</td>
</tr>
</table>
</body>
</html>