Email conversation
From | Bastion |
To | Me |
Subject | Question on Manipulating Nodes |
Date | 6 October 2004 21:28 |
I just found your site and searched for help, but couldn't find anything. I
thought I would email my question to you. Please forgive me if you do have
the answer somewhere on your site and I missed it. I often search with
mediocre search words.
I'm trying to create a WYSIWYG area. I'm using an Iframe to house the
content. For the past 2 weeks, I've been trying to develop code to insert
an image without using execCommand. I want to allow the user to set up the
image settings and then insert the image into the iframe.
My first attempt went as follows:
var domPath; // this stores the path so I don't have to type it constantly
// control what we need onload
function editableIframe(){
// Turn on the editing capabilities within the Iframe
editorWindowIframe.document.designMode='On';
determineBrowser(); // Determine the user's browser.
}
function determineBrowser(){
/* The contentDocument property returns the document the frame contains, if any.
If defined, the user is running a Mozzilla-based browser. Otherwise, it's IE, our default setting. */
if (window.document.getElementById('editorWindowIframe').contentDocument) browser_info = 'moz'; // Mozilla
if (browser_info == 'ie') domPath = window.document.frames['editorWindowIframe'].document;
else domPath = window.document.getElementById('editorWindowIframe').contentDocument;
}
// When the user clicks the insert image code.
function imageWindow() {
//capture the cursor location for both NS and IE
if (browser_info == 'ie') var cursorLocation = domPath.selection.createRange();
else var cursorLocation = domPath.getSelection();
var testImg = domPath.createElement('img');
testImg.setAttribute('src','small_logo.gif');
testImg.setAttribute('border','2');
testImg.setAttribute('alt','Go back to home');
testImg.setAttribute('title','Go back to home');
domPath.body.appendChild(testImg);
}
Unfortunately, I need the image to insert at the cursor for both NS and IE
and this current setup doesn't work. appendChild adds the information at
the bottom of the copy.
My second solution was to insert the image using the execCommand and then
capture the image and adjust the settings. It doesn't work in NS and I'm a
bit uncertain if this is the best approach. I'm concerned of any time lag
between inserting the image and then editing the attributes.
My second attempt went as follows:
var domPath; // this stores the path so I don't have to type it constantly
// control what we need onload
function editableIframe(){
// Turn on the editing capabilities within the Iframe
editorWindowIframe.document.designMode='On';
determineBrowser(); // Determine the user's browser.
}
function determineBrowser(){
/* The contentDocument property returns the document the frame contains, if any.
If defined, the user is running a Mozzilla-based browser. Otherwise, it's IE, our default setting. */
if (window.document.getElementById('editorWindowIframe').contentDocument) browser_info = 'moz'; // Mozilla
if (browser_info == 'ie') domPath = window.document.frames['editorWindowIframe'].document;
else domPath = window.document.getElementById('editorWindowIframe').contentDocument;
}
// When the user clicks the insert image code.
function imageWindow() { // determine the cursor location
if (browser_info == 'ie') var cursorLocation = domPath.selection.createRange();
else alert(cursorLocation.screenX);
var startPointVal = cursorLocation.boundingLeft + domPath.body.scrollLeft;
var endPointVal = cursorLocation.boundingTop + domPath.body.scrollTop;
// insert the image
domPath.execCommand('insertImage', false, 'small_logo.gif');
// determine the bounding points of the image we just inserted, select it, and then update it.
var imgID = domPath.elementFromPoint(startPointVal, endPointVal);
imgID.border = '3';
}
Can you provide any insight on how to get this to work? I would prefer
using the first method, but feel missing something important or
misinterpreting how the nodes work. I feel awful asking, but I'm at my
wit's end.
Bastion.
From | Me |
To | Bastion |
Subject | Re: Question on Manipulating Nodes |
Date | 6 October 2004 22:03 |
Bastion,
yes, it is these problems that have put me off making one of these myself
for the moment :D
> if (browser_info == 'ie') var cursorLocation = domPath.selection.createRange();
> else var cursorLocation = domPath.getSelection();
yeah, the problem is that the getSelection simply gets the textual content.
it does not remember where that was. You can use domPath.selectionStart and
domPath.selectionEnd which tell you the numeric position, but that only
refers to textual position, it still does not remember the physical
position relating to DOM nodes. Without a lot of work stepping through all
nodes and adding their textual content, and counting until you reach the
right length, this is just not easy. Unless DOM 3 textrange is supported
(where you can insertBefore), this really is not a viable solution as far
as I can see.
> var imgID = domPath.elementFromPoint(startPointVal, endPointVal);
I'm afraid I don't know any equivalent to this in Gecko, but you could
always try DOM mutation events - look for an image element node being added,
and act upon it when it is. I have never used these events, and I do not
know how to do this, try looking on the w3c.org site for the DOM spec, and
see if there is anything that can help in that.
Hopefully that will provide your answer.
Mark 'Tarquin' Wilton-Jones - author of http://www.howtocreate.co.uk/
From | Bastion |
To | Me |
Subject | Re: Question on Manipulating Nodes |
Date | 7 October 2004 13:43 |
Thanks!
From | Bastion |
To | Me |
Subject | Re: Question on Manipulating Nodes |
Date | 7 October 2004 20:01 |
Mark,
Thanks so much for your response. I went a slightly different track and
have it now working beautifully in IE. Of course, it hinges on pasteHTML()
which doesn't seem to work for Netscape, but that's okay. I still have time
to find an alternative for Netscape. In case you're interested.
function updateEditor() {
var fullPath = window.opener.document.getElementById('editorWindowIframe');
var fullPathWin = window.opener.document.getElementById('editorWindowIframe').contentWindow;
fullPathWin.focus();
// get the values set by the user.
var srcInput = "img/"+document.getElementById("imageList").value;
var altTitle = document.getElementById("altText").value;
var alignSet = document.getElementById("alignImg").value;
// create the image element
var imageInfo = document.createElement("img");
imageInfo.setAttribute("src",srcInput);
imageInfo.setAttribute("alt",altTitle);
imageInfo.setAttribute("title",altTitle);
if (alignSet != "") imageInfo.setAttribute("align",alignSet);
// convert the object into text
imageInfo = imageInfo.outerHTML;
// add style sheet padding.
if (alignSet == "left") imageInfo = imageInfo.replace('>',' style="padding-right: 5px;">');
else if (alignSet == "right") imageInfo = imageInfo.replace('>',' style="padding-left: 5px;">');
else imageInfo = imageInfo.replace('>',' style="padding: 0px 3px 0px 3px;">');
// insert the code
if (window.opener.browser_info == "ie") fullPathWin.document.selection.createRange().pasteHTML(imageInfo);
else fullPathWin.getSelection().text.pasteHTML("here");
window.close();
}