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.
I am trying to dynamically embed a youtube video into a mobile web page by injecting the following code via jQuery.
$("#tagetId").append("http://www.youtube.com/embed/oHg5SJYRHA0' frameborder='0'>");
I am testing this on chrome ios and the video does render correctly however some part of the web page seems to think the video hasn't rendered and every half second or so I get a new instance of the following error.
Unsafe JavaScript attempt to access frame with URL http://mydomain.html from frame with URL http://www.youtube.com/embed/oHg5SJYRHA0. Domains, protocols and ports must match.
This seems to really jam up the browser and causes the the load event call back function (i.d. 'first line of code') to trigger over and over.
$('iframe').load(function(){
//first line of code
$(this).load(function(){
//second line of code
})
});
Is there a better way to do this. Can any one explain what I'm doing wrong?
This fixed it:
<iframe scrolling='no' class='youtube-player' style='height:200px;width:100%' src='https://www.youtube.com/embed/oHg5SJYRHA0?html5=1' frameborder='0'></iframe>
Not sure what you were doing with
$("#tagetId").append("http://www.youtube.com/embed/oHg5SJYRHA0' frameborder='0'>");
but that looks like malformed HTML being appended.
Maybe you just didn't append the whole iframe tag?
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!
I'm building in Expression Engine 2.3 a user profile system using Solspace's User and Friends modules. They work fine, but I'm having an incredibly difficult time with passing embedded variables around.
I've got a .profile_head template that's called from each template. The profile page, the friends page, the private messaging page, etc. It builds a user navigation, displays the avatar, all the common user stuff. All of this is based off of the user ID passed through {segment_3}. This allows me to display a different user's info by changing this segment.
The problem is doing this makes my URLs far too precise. I can't have users going to /users, they have to go to /users/profile/UID or the best possible scenario is an error page or redirect to the home page.
I tried to solve this problem through variables in my template:
{embed="/users/.profile_head" uid="{segment_3}"}
or......
{embed="/users/.profile_head" uid="{logged_in_member_id}"}
In the .profile_head template file, I can print out {embed:uid} just fine, but when I try to assign it to anything (i.e. a loop or another template), it breaks:
<!-- /users/.profile_head -->
{exp:friends:members member_id="{embed:uid}" dynamic="off" limit="1"}
or.....
{embed="users/.profile_column" uid="{embed:uid}"}
For instance, if {embed:uid} is set as {logged_in_member_id}, I get the following error:
Parse error: syntax error, unexpected T_LNUMBER in /var/www/system/expressionengine/libraries/Functions.php(656) : eval()'d code on line 9
This is line 9:
{if logged_in_member_id == "{embed:uid}"} <span class="this_is_you">This is you!</span>{/if}
I really am at my wits end. I need to be able to use this profile header in templates without requiring a user id in the URL for things like the user messaging and settings pages. But nothing I try seems to be working in the least.
I believe that {logged_in_member_id} is a late-parsed variable, which means it may not be available in some of your tags at the point they're processed - hence it's passed as literally {logged_in_member_id}.
Try using the CURRENT_USER constant instead.
How do you prevent Firefox and Safari from caching iframe content?
I have a simple webpage with an iframe to a page on a different site. Both the outer page and the inner page have HTTP response headers to prevent caching. When I click the "back" button in the browser, the outer page works properly, but no matter what, the browser always retrieves a cache of the iframed page. IE works just fine, but Firefox and Safari are giving me trouble.
My webpage looks something like this:
<html>
<head><!-- stuff --></head>
<body>
<!-- stuff -->
<iframe src="webpage2.html?var=xxx" />
<!-- stuff -->
</body>
</html>
The var variable always changes. Although the URL of the iframe has changed (and thus, the browser should be making a new request to that page), the browser just fetches the cached content.
I've examined the HTTP requests and responses going back and forth, and I noticed that even if the outer page contains <iframe src="webpage2.html?var=222" />, the browser will still fetch webpage2.html?var=111.
Here's what I've tried so far:
Changing iframe URL with random var value
Adding Expires, Cache-Control, and Pragma headers to outer webpage
Adding Expires, Cache-Control, and Pragma headers to inner webpage
I'm unable to do any JavaScript tricks because I'm blocked by the same-origin policy.
I'm running out of ideas. Does anyone know how to stop the browser from caching the iframed content?
Update
I installed Fiddler2 as Daniel suggested to perform another test, and unfortunately, I am still getting the same results.
This is the test I performed:
Outer page generates random number using Math.random() in JSP.
Outer page displays a random number on the webpage.
Outer page calls iframe, passing in a random number.
Inner page displays a random number.
With this test, I'm able to see exactly which pages are updating, and which pages are cached.
Visual Test
For a quick test, I load the page, navigate to another page, and then press "back." Here are the results:
Original Page:
Outer Page: 0.21300034290246206
Inner Page: 0.21300034290246206
Leaving page, then hitting back:
Outer page: 0.4470929019483644
Inner page: 0.21300034290246206
This shows that the inner page is being cached, even though the outer page is calling it with a different GET parameter in the URL. For some reason, the browser is ignoring the fact that the iframe is requesting a new URL; it simply loads the old one.
Fiddler Test
Sure enough, Fiddler confirms the same thing.
(I load the page.)
Outer page is called. HTML:
0.21300034290246206
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206" />
http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206 is called.
(I navigate away from the page and then hit back.)
Outer page is called. HTML:
0.4470929019483644
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.4470929019483644" />
http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206 is called.
Well, from this test, it looks as though the web browser isn't caching the page, but it's caching the URL of the iframe and then making a new request on that cached URL. However, I'm still stumped as to how to solve this issue.
Does anyone have any ideas on how to stop the web browser from caching iframe URLs?
This is a bug in Firefox:
https://bugzilla.mozilla.org/show_bug.cgi?id=356558
Try this workaround:
<iframe src="webpage2.html?var=xxx" id="theframe"></iframe>
<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>
I have been able to work around this bug by setting a unique name attribute on the iframe - for whatever reason, this seems to bust the cache. You can use whatever dynamic data you have as the name attribute - or simply the current ms or ns time in whatever templating language you're using. This is a nicer solution than those above because it does not directly require JS.
In my particular case, the iframe is being built via JS (but you could do the same via PHP, Ruby, whatever), so I simply use Date.now():
return '<iframe src="' + src + '" name="' + Date.now() + '" />';
This fixes the bug in my testing; probably because the window.name in the inner window changes.
As you said, the issue here is not iframe content caching, but iframe url caching.
As of September 2018, it seems the issue still occurs in Chrome but not in Firefox.
I've tried many things (adding a changing GET parameter, clearing the iframe url in onbeforeunload, detecting a "reload from cache" using a cookie, setting up various response headers) and here are the only two solutions that worked from me:
1- Easy way: create your iframe dynamically from javascript
For example:
const iframe = document.createElement('iframe')
iframe.id = ...
...
iframe.src = myIFrameUrl
document.body.appendChild(iframe)
2- Convoluted way
Server-side, as explained here, disable content caching for the content you serve for the iframe OR for the parent page (either will do).
AND
Set the iframe url from javascript with an additional changing search param, like this:
const url = myIFrameUrl + '?timestamp=' + new Date().getTime()
document.getElementById('my-iframe-id').src = url
(simplified version, beware of other search params)
After trying everything else (except using a proxy for the iframe content), I found a way to prevent iframe content caching, from the same domain:
Use .htaccess and a rewrite rule and change the iframe src attribute.
RewriteRule test/([0-9]+)/([a-zA-Z0-9]+).html$ /test/index.php?idEntity=$1&token=$2 [QSA]
The way I use this is that the iframe's URL end up looking this way: example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
Where [token] is a randomly generated value. This URL prevents iframe caching since the token is never the same, and the iframe thinks it's a totally different webpage since a single refresh loads a totally different URL :
example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
example.com/test/54/d2cc21be7cdcb5a1f989272706de1913.html
both lead to the same page.
You can access your hidden url parameters with $_SERVER["QUERY_STRING"]
To get the iframe to always load fresh content, add the current Unix timestamp to the end of the GET parameters. The browser then sees it as a 'different' request and will seek new content.
In Javascript, it might look like:
frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '×tamp=' + timestamp;
I found this problem in the latest Chrome as well as the latest Safari on the Mac OS X as of Mar 17, 2016. None of the fixes above worked for me, including assigning src to empty and then back to some site, or adding in some randomly-named "name" parameter, or adding in a random number on the end of the URL after the hash, or assigning the content window href to the src after assigning the src.
In my case, it was because I was using Javascript to update the IFRAME, and only switching the hash in the URL.
The workaround in my case was that I created an interim URL that had a 0 second meta redirect to that other page. It happens so fast that I hardly notice the screen flash. Plus, I made the background color of the interim page the same as the other page, and so you notice it even less.
It is a bug in Firefox 3.5.
Have a look..
https://bugzilla.mozilla.org/show_bug.cgi?id=279048
I set iframe src attribute later in my app. To get rid of the cached content inside iframe at the start of the application I simply do:
myIframe.src = "";
... somewhere in the beginning of js code (for instance in jquery $() handler)
Thanks to
http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/
I also had this problem in 2016 with iOS Safari. What seemed to work for me was
giving a GET-parameter to the iframe src and a value for it like this
<iframe width="60%" src="../other/url?cachebust=1" allowfullscreen></iframe>
I also met this issue, after trying different browsers, and a ton of trial and error, I came up with this solution, which works well in my case:
import { defineComponent } from 'vue'
import { v4 as uuid } from 'uuid'
export default defineComponent({
setup() {
return () => (
// append a uuid after `?` to prevent browsers from caching it
<iframe src={`https://www.example.com?${uuid()}`} frameborder='0' />
)
},
})
If you want to get really crazy you could implement the page name as a dynamic url that always resolves to the same page, rather than the querystring option?
Assuming you're in an office, check whether there's any caching going on at a network level. Believe me, it's a possibility. Your IT folks will be able to tell you if there's any network infrastructure around HTTP caching, although since this only happens for the iframe it's unlikely.
Have you installed Fiddler2?
It will let you see exactly what is being requested, what is being sent back, etc. It doesn't sound plausible that the browser would really hit its cache for different URLs.
Make the URL of the iframe point to a page on your site which acts as a proxy to retrieve and return the actual contents of the iframe. Now you are no longer bound by the same-origin policy (EDIT: does not prevent the iframe caching issue).