IE7 display oddity (example attached) - javascript

I'm working on a Javascript-based replacement for a Flash applet. The site is having rendering problems only in IE, where it exhibits a behavior that has me at wit's end.
http://janetalasher.com/new/content/portfolio/artcloth/ (This is the page)
What does IE do that's so strange (in this case only)? If you look in Firefox, you'll see a table of images on the right which has the thumbnails. IE6 and IE7 don't show this... unless you are in print preview. It's not a CSS glitch - I've disabled all stylesheets and the error still occurs. I'd provide more relevant source code, but I don't even know where the problem is. The .js files that I suspect (if it's any help) are:
/common/gallery/display.js
/common/gallery/loader.js
Okay - update: It is definitely rendering properly in print preview mode only. Can someone please explain to me in what world this happens? The div is present in the normal mode, but the table won't render. Using the IE developer toolbar confirms it and all the cells are present.

Try adding semi-colons here:
function loadGallery(xml)
{
thumbpath = $(xml).find("thumbpath").attr('dir') // add here
imagepath = $(xml).find("imagepath").attr('dir') // here
detailpath = $(xml).find("detailpath").attr('dir') // and here
cSheet = contactSheet(xml);
$('.contactSheet')[0].appendChild(cSheet);
display($(cSheet).find('img')[0]);
}
Also, on this line:
jQuery.get('/new/content/portfolio/artcloth/gallery.xml' , 'xml' , function(data) { loadGallery(data); } ) // missing one here too
Actually, your Javascript files are missing semi-colons on the end too. Make sure you go through each file and add one to the end of each line.
Javascript does not actually require them, but for the sake of sanity and knowing exactly what your code is going it is a good idea to put them in. For example:
return
1
Can become:
return;
1;
Which returns nothing at all, not exactly the desired effect.

According to Microsoft Script Editor, there's an error inside jQuery caused by this line:
$('#lower').css('padding-left' , paddingLeft - (lowerRightProtrusion < 0 ? 0 : lowerRightProtrusion) + "px");
Since lowerRightProtrusion is NaN, and NaN < 0 calculates to false, you're actually setting padding-left to "NaNpx". Does not compute ;)
See my previous answer for info about MS Script Editor:
Using the IE8 'Developer Tools' to debug earlier IE versions

It would seem that IE is not picking up the styles. If I open the page in chrome, the "float:left" style appears on the description div. however, in IE this is not the case.
You currently have your includes in a div in the body of the document. If it is possible try moving these into the head. I'm talking about the link and script tags directly descendant of div id="pageHead".
(I am using IE6 and the developer toolbar to get this information)

In /common/css/generic.css:
div#information
{
margin-left:188px;
m\argin-left:94px; <------ not sure if that would cause this, but thought i would point it out
}

Related

Span element not updating correctly

Update 3 - 10/09/2013: Just tested this with Version 29.0.1547.66 m and the problem still persists. If anyone else can test this out and let me know the results that would be great. You need an inline element such as a span with some text in, have it relatively positioned and moved by however many pixels you want from left and top. Then set up some jScript to change the current inner html of the element to something else and you should see it remain the same in the viewport but change correctly in the DOM.
Update 2: After a bit more testing the problem seems to occur on elements that are inline such as span, or have CSS that makes them inline, but that are also relatively positioned, it seems to be this combination that is causing the issue. After posting the bug on Chromium it has been flagged as a cr-Blink-Rendering issue which looks to be the engine that renders the DOM in the broswer viewport. I am using Version 29.0.1547.57 (the current version ends .66 but mine has not updated due to an error). So if you're on the latest version this issue may no longer be there.
Update: On further investigation I think the problem is with the latest Chrome build Version 29.0.1547.57 m As I tested the element in an inline fashion in IE9 and Firefox 21 and it worked fine. I have filed a bug report for this on chromium
I'm having a problem (that I have not been able to recreate with jsfiddle) where I perform an ajax request, obtain some values and place them within span elements that exist within my page.
I have a very odd problem where the ajax request is working and bringing the values back. The values are being inserted into the span elements via jQuerys .html' method and when I check the DOM using Chrome developer tools I can see the new value in the span.
However, what I see on the page doesn't reflect this, it still shows the old value. Yet if I attempt to highlight the value, it instantly changes to the correct value (the value that is showing in the DOM).
I have even tried to update the spans value before the ajax call (as the value I am using is being obtained from jQuery UI's slider widget) but this still yields the same results.
Has anyone else come across this?
EDIT: Here is some of the code
HTML
<div id="NewLoanSliderAmount" class="NewLoanSliderRules"></div>
<span id="NewLoanSliderAmountDisplay" class="NewLoanDisplay">£600</span>
The slider code. This is the version where I attempt to update it directly from the slider value
$("#NewLoanSliderAmount").slider({
value: amount,
min: 300,
max: amount,
step: 100,
change: function (event, ui) {
$("#NewLoanSliderAmountDisplay").html("£" + ui.value);
window.CkSpace.GetLoanValues();
}
});
Here is the ajax code:
(function (CkSpace, $, undefined) {
CkSpace.GetLoanValues = function () {
var url = "/Home/UpdateAPR";
$.get(url, { Amount: $("#NewLoanSliderAmount").slider("value"), Length: $("#NewLoanSliderLength").slider("value") }, function (data) {
$("#NewLoanAmount").html("£"+data.LoanAdvance);
$("#NewLoanLength").html(data.LoanTerm);
$("#NewLoanMonthlyCost").html("£"+data.LoanInstalment);
$("#NewLoanTotal").html(data.LoanGrossRepyable);
$("#NewLoanAPR").html(data.LoanAPR+"%");
$("#NewLoanSliderAmountDisplay").html("£" + data.LoanAdvance);
});
}
} (window.CkSpace = window.CkSpace || {}, jQuery));
EDIT 2:
Another thing to note is that if i set a break point on the span being populated and step through it, it updates perfectly every time in Chrome developer tools
I've figured out what was causing the problem although I don't know WHY it is causing the problem.
First off I tried changing the span to a div and adding display:inline to the css. It still didn't work.
I then removed the inline display and all of a sudden, as a block level element it works.
If anyone knows more about why this is and can elaborate then please do!
EDIT: On further investigation I think the problem is with the latest Chrome build Version 29.0.1547.57 m As I tested the element in an inline fashion in IE9 and Firefox 21 and it worked fine. I think it's time to file a bug report!

Calling UI button externally

Answered:
Result can bee seen here: http://apitecture.com/dev/cked/index.2.html
Working code excerpt:
$('a.color').on({
click : function()
{
var self = $(this);
var editor = self.data('editor-instance') || CKEDITOR.instances['one'];
var button = self.data('editor-button') || editor.ui.create('TextColor');
if (!self.data('editor-instance'))
{
self.data('editor-instance', editor);
}
if (!self.data('editor-button'))
{
button._.id = self.attr('id');
self.data('editor-button', button);
}
button.click( editor );
}
});
I am working on a rich GUI based content editor.
I have come to conclusion, to use CKEditor for the text styling part, because it's 4th version comes with a lot of customization and configuration options, plus, is very well built.
I started to implement some of the commands in CK to my own toolbar, that isn't connected with CK. Apparently, my ventures weren't as easy as I thought they'd be...
http://apitecture.com/dev/cked/ <- here I have deployed a sandbox version.
On the left hand side, you can see a veeeery stripped down version of CK, and a custom toolbar.
On the right, exact replica, but with CK's native toolbar.
Simple commands, like Link and Bold, as you can see, are working, due to their simple nature.
The problem is with the Text Color button. It isn't bound to a command in CK, therefore I cannot execute it externally - well, at least I haven't found a way how.
Maybe somebody is pro enough with CK and could help me to figure this out?
The goal is to have the same functionality on my toolbar's button as the CK one.
I have found out, that upon clicking the Text Color, the color selection popup is appended to body, so, it doesn't extend upon CK styles and should, in theory, work standalone. Though, I cannot seem to find the code where the HTML is appended to body.
I have tried to get the UI button instance:
var color = CKEDITOR.instances['one'].ui.create('TextColor');
// and fire click on it
color.click();
But, that caused a partially expected (due to click not being started from toolbar) exception:
Uncaught TypeError: Cannot read property 'elementMode' of undefined ckeditor.js:552
CKEDITOR.ui.floatPanel.CKEDITOR.tools.createClass.$ ckeditor.js:552
CKEDITOR.ui.panelButton.CKEDITOR.tools.createClass.proto.createPanel ckeditor.js:541
e ckeditor.js:540
$.on.click cktest.js:59
v.event.dispatch jquery.min.js:2
o.handle.u
Seeing (from: console.log(color.click)) that the function accepts a parameter, I thought that I could provide any DOM element to it, by calling color.click( element );, that also caused error:
Uncaught TypeError: Cannot read property 'baseFloatZIndex' of undefined ckeditor.js:547
CKEDITOR.ui.panel.render ckeditor.js:547
o ckeditor.js:552
CKEDITOR.ui.floatPanel.CKEDITOR.tools.createClass.$ ckeditor.js:553
CKEDITOR.ui.panelButton.CKEDITOR.tools.createClass.proto.createPanel ckeditor.js:541
e ckeditor.js:540
$.on.click cktest.js:59
v.event.dispatch jquery.min.js:2
o.handle.u
Here is link to the source where the color plugin and it's buttons is introduced: https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/colorbutton/plugin.js
Update:
I think this happens with every single button, that has dropdowns instead of dialogs.
Update 2:
Reinmar's answer did show some light at the end of the tunnel: http://apitecture.com/dev/cked/index.2.html
In the example, the "Color" text-link on the right can be clicked, and the dropdown shows, plus, it functions perfectly (besides that the shadow is enforced). The only catch here is, it works for the first time. Resulting in:
TypeError: Cannot read property 'title' of undefined
at CKEDITOR.ui.panel.block.CKEDITOR.tools.createClass.$ (http://apitecture.com/dev/cked/ckeditor/ckeditor.js:549:298)
at new b (http://apitecture.com/dev/cked/ckeditor/ckeditor.js:26:149)
at Object.CKEDITOR.ui.panel.addBlock (http://apitecture.com/dev/cked/ckeditor/ckeditor.js:547:503)
at CKEDITOR.ui.floatPanel.CKEDITOR.tools.createClass.proto.addBlock (http://apitecture.com/dev/cked/ckeditor/ckeditor.js:553:409)
at CKEDITOR.ui.panelButton.CKEDITOR.tools.createClass.proto.createPanel (http://apitecture.com/dev/cked/ckeditor/ckeditor.js:541:333)
at e [as click] (http://apitecture.com/dev/cked/ckeditor/ckeditor.js:540:304)
at HTMLAnchorElement.$.on.click (http://apitecture.com/dev/cked/cktest.2.js:64:24)
at HTMLAnchorElement.v.event.dispatch (http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js:2:38053)
at HTMLAnchorElement.o.handle.u (http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js:2:33916)
For every subsequent click.
You've asked a hardcore question :). I'm CKEditor core dev for last 1 year and I had to spend an hour digging in toolbar, panels and buttons. This part of CKE's API is really twisty and definitely lacks of documentation. But the worst part of it is that it's not really reusable, cause all the parts are tightly coupled.
Anyway. I tried to reuse colorbutton and I succeeded. On editor without toolbar plugin (this is important) I was able to open it for specified element:
And it even seems to work :) (at least on Chrome).
I'm curious how hard it will be for you to replace toolbar plugin with your own basic implementation (perhaps without a11y support and other heavy stuff). At the moment your bold and link buttons work correctly on Chrome, FF, Opera and IE7-9 (this in fact proves how cool CKE is because it does a lot in the background ;). I hope that you won't encounter any serious troubles.
Some tips:
You don't need to call editor.getCommand().exec(). There is an editor.execCommand() method.
You'll probably want to activate/deactivate buttons depending on context (caret location). Each command has its state and it's automatically updated on selectionChange event.
Good luck. And it will be cool if you share your thoughts and result of work with us :). Feedback will be very useful if someday we'll decide to improve this part of API.

How can you see which Javascript script generated a certain html line?

I have some crazy app done almost 100% by manipulating the DOM and I find myself in the unfortunate position of changing something in it. As there are probably around 100 different scripts that do God knows what, I have no clue in which file should I look to make my changes. So, I want to ask, is there a way (using Firebug maybe or something similar) to know where a specific piece of html was generated? I'm a C developer, so I'm not very good at this, it drives me crazy.
Are all the elements added at the page load, or partially in the response to the user input? (clicking etc.)
for stuff added with the response to your actions, you can use Firebug's "Break On Next" button in the "Script" tab. To active BON you have to click it, or, in just-shipped Firebug 1.10.0a8, use keyboard shortcut ALT-CTRL-B (useful when you have event listeners bound to mouse movements). Then, when any piece of JS is going to be executed in reaction to your click etc., you will hit a breakpoint.
for stuff added at page load time, you may use the trick of extending the native functions (this might sound crazy - yeah it is, don't do it in production!) like appendChild, insertBefore, replaceChild. Just insert the appropriate code at the very top of your main HTML file, so all the code below will "see" the change.
Unfortunately, this does not work in Firefox due to a bug. But works in Opera and I guess in Chrome as well.
When you extend the native function, you can inject any code before really adding the node to the page. For instance, call console.log or create a breakpoint, to inspect the current page state. You can try playing with breakpoints to see the available variables properties inside those function to adjust what you push to console.log.
For this code:
<!doctype html>
<html>
<head>
<script type="text/javascript">
// this should work in Firefox but it does not -- https://bugzilla.mozilla.org/show_bug.cgi?id=618379
// works at least in Opera, probably Chrome too
Node.prototype._appendChild = Node.prototype.appendChild;
Node.prototype.appendChild = function(child) {
console.log("appending " + child + " to " + this);
return this._appendChild(child); // call the original function with the original parameters
}
// this works in Firefox
document._createElement = document.createElement;
document.createElement = function(tagName){
console.log("creating " + tagName);
return this._createElement(tagName);
}
</script>
</head>
<body>
<script type="text/javascript">
var p = document.createElement("p");
p.appendChild( document.createTextNode("abc"));
document.body.appendChild(p);
</script>
</body>
</html>
Opera outputs:
creating p appendChild.html:14
appending [object Text] to [object HTMLParagraphElement] appendChild.html:7
appending [object HTMLParagraphElement] to [object HTMLBodyElement] appendChild.html:7
To overcome the weakness of Firefox (that you can't override appendChild), you may use the trick: place the code below instead in the top of your HTML
<script>
Node.prototype._appendChild = function(child) {
console.log("appending " + child + " to " + this);
return this.appendChild(child)
};
</script>
and then, use Fiddler proxy by creating auto-responders (WMV tutorial, 9.9 MB) where you manually replace all calls to .appendChild with ._appendChild (you can use Notepad++ for "find replace in all opened files"). Creating auto-responders and hand-tampering requests can be mundane, but it's extremely powerful. To quickly create auto-responder rule, load the page when Fiddler is active, then drag'n'drop files as in the picture below. For each file, right click and choose "Generate File" from menu (this will put a file on the desktop) or create a file by yourself in different location. (it's good to open Fiddler-generated files and remove response headers from them; BTW "Generate file" puts real contents only if the response header was 200, so make sure to load the page with CTRL-F5 to skip the cache).
In Chrome you can inspect an element and right click on it. This menu gives you some options to break when something below the element is changed or when it's own attributes change. Maybe one of those breakpoints will find what you are looking for?
Assuming you've got access to the raw (hopefully un-minified/obfuscated) JS files, maybe just search them for text strings related to DOM manipulation and/or attributes of the node you're trying to find the creation of? I'd try things like "appendChild" "createElement" and the node's ID/class names.
You could also set break points all over the script files, and step through them as the page loads to help you narrow down where to look. Might help to start by just "pausing" the JS execution and stepping through from the very beginning.
If you can share the code (a link to the live site would do fine) I'd be happy to take a look.
If you are using the jQuery framework in your javascript to make the DOM changes then you may find the fireQuery plugin for FireBug in the firefox browser may get you the information you need.
Example:
It adds additional information to the standard HTML view by superimposing additional jquery element information to the display to provide a deeper insight into how your javascript is amending the page content.
I hope that helps you out.

xpath greasemonkey

I am trying to modify gmail in a greasemonkey script. Using xpather i can get the xpath expression for the part i am trying to hide. But using following snippet i can not get a match. alert function is never called. Can anyone point me to what am i doing wrong?
var allLinks, thisLink;
allLinks = document.evaluate(
"//html/body/div[1]/div/div/div[1]/div/div[3]/div[1]/div[2]/div[2]/div[1]/div[1]",
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
for (var i = 0; i < allLinks.snapshotLength; i++) {
thisLink = allLinks.snapshotItem(i);
alert("found");
}
#Alan Storm
I installed firebug tested the script using console it works but still i can not get it to work under greasemonkey. Greasemonkey still not giving me an alert box. I also tried adding a on load event listener that did not helped either.
First, a general debugging tip, then a stab at your problem.
Remember that Greasemonkey scripts are just javascript, and you can still use all the Javascript tools avaiable to you to debug your problem. Open up gmail, fire up Firebug, and try running your javascript code directly on the command line (click the upward circle arrow to the right of the console line for a bigger typing area).
When I did the above with your javascript snippet, allLinks.snapshotLength was evaluating to 0, indicating that your xpath expression didn't match anything. This is odd, because when I used XPath Checker, it matched the logo.
Digging in a bit deeper, it looks like gmail's main document is a number of iframes, and the iframes contain the actual application elements. Specifically, there's a frame with an ID of "canvas_frame" which contains the actual DOM for the application interface. When I try
canvas = window.frames[document.getElementById('canvas_frame').name].document;
allLinks = canvas.evaluate(
"//html/body/div[1]/div/div/div[1]/div/div[3]/div[1]/div[2]/div[2]/div[1]/div[1]",
canvas,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
I get a response with a length of 1, which may suit your needs better.
Finally, this isn't required, but your xPath expression looks a little fragile. If gmail changes the document structure even slightly (say, with a wrapper div), your program will break. Consider something like this instead.
<!--
all divs on the page that contains an h1 element
that contains the text "Gmail Logo"
-->
//div[contains(./h1,"Gmail Logo")]

Style display not working in Firefox, Opera, Safari - (IE7 is OK)

I have an absolutely positioned div that I want to show when the user clicks a link. The onclick of the link calls a js function that sets the display of the div to block (also tried: "", inline, table-cell, inline-table, etc). This works great in IE7, not at all in every other browser I've tried (FF2, FF3, Opera 9.5, Safari).
I've tried adding alerts before and after the call, and they show that the display has changed from none to block but the div does not display.
I can get the div to display in FF3 if I change the display value using Firebug's HTML inspector (but not by running javascript through Firebug's console) - so I know it's not just showing up off-screen, etc.
I've tried everything I can think of, including:
Using a different doctype (XHTML 1, HTML 4, etc)
Using visibility visible/hidden instead of display block/none
Using inline javascript instead of a function call
Testing from different machines
Any ideas about what could cause this?
Since setting the properties with javascript never seemed to work, but setting using Firebug's inspect did, I started to suspect that the javascript ID selector was broken - maybe there were multiple items in the DOM with the same ID? The source didn't show that there were, but looping through all divs using javascript I found that that was the case. Here's the function I ended up using to show the popup:
function openPopup(popupID)
{
var divs = getObjectsByTagAndClass('div','popupDiv');
if (divs != undefined && divs != null)
{
for (var i = 0; i < divs.length; i++)
{
if (divs[i].id == popupID)
divs[i].style.display = 'block';
}
}
}
(utility function getObjectsByTagAndClass not listed)
Ideally I'll find out why the same item is being inserted multiple times, but I don't have control over the rendering platform, just its inputs.
So when debugging issues like this, remember to check for duplicate IDs in the DOM, which can break getElementById.
To everyone who answered, thanks for your help!
Can you provide some markup that reproduce the error?
Your situation must have something to do with your code since I can get this to work on IE, FF3 and Opera 9.5:
function show() {
var d = document.getElementById('testdiv');
d.style.display = 'block';
}
#testdiv {
position: absolute;
height: 20px;
width: 20px;
display: none;
background-color: red;
}
<div id="testdiv"></div>
Click me
Found the answer :
I need to use the following to make it work on both browsers :
document.getElementById('editRow').style.display = '';
Actually I was experiencing the same problem you're describing here. What actually fixed my issue was changing the document properties.
Old DOCTYPE/html spec
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
Replaced with
<html>
Check the error console (Tools Menu > Error Console in Firefox 3) to make sure that there isn't another error happening that you're not seeing, which is stopping your script from working.
Try setting the height and width of the div, and make sure it is on top by setting its z-index higher than everything else. If the absolutely positioned div is inside an element that is relatively positioned, it's top and left location is based off the top and left of the relatively positioned element. Try putting your div just under the body element.
You must write a window.onload method:
window.onload = document.getElementById('testdiv').style.display='inline';
Or you can also make a variable:
var d = document.getElementById('testdiv');
window.onload = d.style.display = 'inline';
There is an annoying display error on Firefox 3.5 but not on IE7 or Firefox 2.0.9
I have 3 DIV's position absolute - the first with plain text; the second with a CSS menu (sucklefish type with UL and LI) and the third ditto. The third will not display at all even though the coding has been checked and found to be perfect with W3C's HTML validator.
As a temporary measure, I have merged the second and third DIV's contents.
Things must be bad at Mozilla when IE7 and FF2 display OK but not FF 3.5
I'll give you a BIG hint:
<div style="..." class="..."> ... </div>
If you have something in style, then document.style will work!
If you have something in class, it will not show up in document.style and class="..." will OVERRIDE it!
Think about this and this will clear up SO MANY ISSUES. Just this one little understanding will RID you of this MIND VIRUS. Have a good day. Cheers, Ron Lentjes, LC CLS.

Categories