Prevent View Selection Source from triggering the crasher bug 252970, r+sr=bz, a=mconnor

This commit is contained in:
rbs%maths.uq.edu.au 2005-07-27 07:51:52 +00:00
Родитель 913d33657d
Коммит e5802c5bef
2 изменённых файлов: 126 добавлений и 108 удалений

Просмотреть файл

@ -123,71 +123,78 @@ function viewPartialSourceForSelection(selection)
var endPath = getPath(ancestorContainer, endContainer); var endPath = getPath(ancestorContainer, endContainer);
// clone the fragment of interest and reset everything to be relative to it // clone the fragment of interest and reset everything to be relative to it
// note: it is with the clone that we operate from now on // note: it is with the clone that we operate/munge from now on
ancestorContainer = ancestorContainer.cloneNode(true); ancestorContainer = ancestorContainer.cloneNode(true);
startContainer = ancestorContainer; startContainer = ancestorContainer;
endContainer = ancestorContainer; endContainer = ancestorContainer;
var i;
for (i = startPath ? startPath.length-1 : -1; i >= 0; i--) {
startContainer = startContainer.childNodes.item(startPath[i]);
}
for (i = endPath ? endPath.length-1 : -1; i >= 0; i--) {
endContainer = endContainer.childNodes.item(endPath[i]);
}
// add special markers to record the extent of the selection // Only bother with the selection if it can be remapped. Don't mess with
// note: |startOffset| and |endOffset| are interpreted either as // leaf elements (such as <isindex>) that secretly use anynomous content
// offsets in the text data or as child indices (see the Range spec) // for their display appearance.
// (here, munging the end point first to keep the start point safe...) var canDrawSelection = ancestorContainer.hasChildNodes();
var tmpNode; if (canDrawSelection) {
if (endContainer.nodeType == Node.TEXT_NODE || var i;
endContainer.nodeType == Node.CDATA_SECTION_NODE) { for (i = startPath ? startPath.length-1 : -1; i >= 0; i--) {
// do some extra tweaks to try to avoid the view-source output to look like startContainer = startContainer.childNodes.item(startPath[i]);
// ...<tag>]... or ...]</tag>... (where ']' marks the end of the selection). }
// To get a neat output, the idea here is to remap the end point from: for (i = endPath ? endPath.length-1 : -1; i >= 0; i--) {
// 1. ...<tag>]... to ...]<tag>... endContainer = endContainer.childNodes.item(endPath[i]);
// 2. ...]</tag>... to ...</tag>]... }
if ((endOffset > 0 && endOffset < endContainer.data.length) ||
!endContainer.parentNode || !endContainer.parentNode.parentNode) // add special markers to record the extent of the selection
endContainer.insertData(endOffset, MARK_SELECTION_END); // note: |startOffset| and |endOffset| are interpreted either as
// offsets in the text data or as child indices (see the Range spec)
// (here, munging the end point first to keep the start point safe...)
var tmpNode;
if (endContainer.nodeType == Node.TEXT_NODE ||
endContainer.nodeType == Node.CDATA_SECTION_NODE) {
// do some extra tweaks to try to avoid the view-source output to look like
// ...<tag>]... or ...]</tag>... (where ']' marks the end of the selection).
// To get a neat output, the idea here is to remap the end point from:
// 1. ...<tag>]... to ...]<tag>...
// 2. ...]</tag>... to ...</tag>]...
if ((endOffset > 0 && endOffset < endContainer.data.length) ||
!endContainer.parentNode || !endContainer.parentNode.parentNode)
endContainer.insertData(endOffset, MARK_SELECTION_END);
else {
tmpNode = doc.createTextNode(MARK_SELECTION_END);
endContainer = endContainer.parentNode;
if (endOffset == 0)
endContainer.parentNode.insertBefore(tmpNode, endContainer);
else
endContainer.parentNode.insertBefore(tmpNode, endContainer.nextSibling);
}
}
else { else {
tmpNode = doc.createTextNode(MARK_SELECTION_END); tmpNode = doc.createTextNode(MARK_SELECTION_END);
endContainer = endContainer.parentNode; endContainer.insertBefore(tmpNode, endContainer.childNodes.item(endOffset));
if (endOffset == 0)
endContainer.parentNode.insertBefore(tmpNode, endContainer);
else
endContainer.parentNode.insertBefore(tmpNode, endContainer.nextSibling);
} }
}
else {
tmpNode = doc.createTextNode(MARK_SELECTION_END);
endContainer.insertBefore(tmpNode, endContainer.childNodes.item(endOffset));
}
if (startContainer.nodeType == Node.TEXT_NODE || if (startContainer.nodeType == Node.TEXT_NODE ||
startContainer.nodeType == Node.CDATA_SECTION_NODE) { startContainer.nodeType == Node.CDATA_SECTION_NODE) {
// do some extra tweaks to try to avoid the view-source output to look like // do some extra tweaks to try to avoid the view-source output to look like
// ...<tag>[... or ...[</tag>... (where '[' marks the start of the selection). // ...<tag>[... or ...[</tag>... (where '[' marks the start of the selection).
// To get a neat output, the idea here is to remap the start point from: // To get a neat output, the idea here is to remap the start point from:
// 1. ...<tag>[... to ...[<tag>... // 1. ...<tag>[... to ...[<tag>...
// 2. ...[</tag>... to ...</tag>[... // 2. ...[</tag>... to ...</tag>[...
if ((startOffset > 0 && startOffset < startContainer.data.length) || if ((startOffset > 0 && startOffset < startContainer.data.length) ||
!startContainer.parentNode || !startContainer.parentNode.parentNode || !startContainer.parentNode || !startContainer.parentNode.parentNode ||
startContainer != startContainer.parentNode.lastChild) startContainer != startContainer.parentNode.lastChild)
startContainer.insertData(startOffset, MARK_SELECTION_START); startContainer.insertData(startOffset, MARK_SELECTION_START);
else {
tmpNode = doc.createTextNode(MARK_SELECTION_START);
startContainer = startContainer.parentNode;
if (startOffset == 0)
startContainer.parentNode.insertBefore(tmpNode, startContainer);
else
startContainer.parentNode.insertBefore(tmpNode, startContainer.nextSibling);
}
}
else { else {
tmpNode = doc.createTextNode(MARK_SELECTION_START); tmpNode = doc.createTextNode(MARK_SELECTION_START);
startContainer = startContainer.parentNode; startContainer.insertBefore(tmpNode, startContainer.childNodes.item(startOffset));
if (startOffset == 0)
startContainer.parentNode.insertBefore(tmpNode, startContainer);
else
startContainer.parentNode.insertBefore(tmpNode, startContainer.nextSibling);
} }
} }
else {
tmpNode = doc.createTextNode(MARK_SELECTION_START);
startContainer.insertBefore(tmpNode, startContainer.childNodes.item(startOffset));
}
// now extract and display the syntax highlighted source // now extract and display the syntax highlighted source
tmpNode = doc.createElementNS(NS_XHTML, 'div'); tmpNode = doc.createElementNS(NS_XHTML, 'div');
@ -195,7 +202,9 @@ function viewPartialSourceForSelection(selection)
// the load is aynchronous and so we will wait until the view-source DOM is done // the load is aynchronous and so we will wait until the view-source DOM is done
// before drawing the selection. // before drawing the selection.
window.document.getElementById("appcontent").addEventListener("load", drawSelection, true); if (canDrawSelection) {
window.document.getElementById("appcontent").addEventListener("load", drawSelection, true);
}
// all our content is held by the data:URI and URIs are internally stored as utf-8 (see nsIURI.idl) // all our content is held by the data:URI and URIs are internally stored as utf-8 (see nsIURI.idl)
var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE; var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;

Просмотреть файл

@ -119,71 +119,78 @@ function viewPartialSourceForSelection(selection)
var endPath = getPath(ancestorContainer, endContainer); var endPath = getPath(ancestorContainer, endContainer);
// clone the fragment of interest and reset everything to be relative to it // clone the fragment of interest and reset everything to be relative to it
// note: it is with the clone that we operate from now on // note: it is with the clone that we operate/munge from now on
ancestorContainer = ancestorContainer.cloneNode(true); ancestorContainer = ancestorContainer.cloneNode(true);
startContainer = ancestorContainer; startContainer = ancestorContainer;
endContainer = ancestorContainer; endContainer = ancestorContainer;
var i;
for (i = startPath ? startPath.length-1 : -1; i >= 0; i--) {
startContainer = startContainer.childNodes.item(startPath[i]);
}
for (i = endPath ? endPath.length-1 : -1; i >= 0; i--) {
endContainer = endContainer.childNodes.item(endPath[i]);
}
// add special markers to record the extent of the selection // Only bother with the selection if it can be remapped. Don't mess with
// note: |startOffset| and |endOffset| are interpreted either as // leaf elements (such as <isindex>) that secretly use anynomous content
// offsets in the text data or as child indices (see the Range spec) // for their display appearance.
// (here, munging the end point first to keep the start point safe...) var canDrawSelection = ancestorContainer.hasChildNodes();
var tmpNode; if (canDrawSelection) {
if (endContainer.nodeType == Node.TEXT_NODE || var i;
endContainer.nodeType == Node.CDATA_SECTION_NODE) { for (i = startPath ? startPath.length-1 : -1; i >= 0; i--) {
// do some extra tweaks to try to avoid the view-source output to look like startContainer = startContainer.childNodes.item(startPath[i]);
// ...<tag>]... or ...]</tag>... (where ']' marks the end of the selection). }
// To get a neat output, the idea here is to remap the end point from: for (i = endPath ? endPath.length-1 : -1; i >= 0; i--) {
// 1. ...<tag>]... to ...]<tag>... endContainer = endContainer.childNodes.item(endPath[i]);
// 2. ...]</tag>... to ...</tag>]... }
if ((endOffset > 0 && endOffset < endContainer.data.length) ||
!endContainer.parentNode || !endContainer.parentNode.parentNode) // add special markers to record the extent of the selection
endContainer.insertData(endOffset, MARK_SELECTION_END); // note: |startOffset| and |endOffset| are interpreted either as
// offsets in the text data or as child indices (see the Range spec)
// (here, munging the end point first to keep the start point safe...)
var tmpNode;
if (endContainer.nodeType == Node.TEXT_NODE ||
endContainer.nodeType == Node.CDATA_SECTION_NODE) {
// do some extra tweaks to try to avoid the view-source output to look like
// ...<tag>]... or ...]</tag>... (where ']' marks the end of the selection).
// To get a neat output, the idea here is to remap the end point from:
// 1. ...<tag>]... to ...]<tag>...
// 2. ...]</tag>... to ...</tag>]...
if ((endOffset > 0 && endOffset < endContainer.data.length) ||
!endContainer.parentNode || !endContainer.parentNode.parentNode)
endContainer.insertData(endOffset, MARK_SELECTION_END);
else {
tmpNode = doc.createTextNode(MARK_SELECTION_END);
endContainer = endContainer.parentNode;
if (endOffset == 0)
endContainer.parentNode.insertBefore(tmpNode, endContainer);
else
endContainer.parentNode.insertBefore(tmpNode, endContainer.nextSibling);
}
}
else { else {
tmpNode = doc.createTextNode(MARK_SELECTION_END); tmpNode = doc.createTextNode(MARK_SELECTION_END);
endContainer = endContainer.parentNode; endContainer.insertBefore(tmpNode, endContainer.childNodes.item(endOffset));
if (endOffset == 0)
endContainer.parentNode.insertBefore(tmpNode, endContainer);
else
endContainer.parentNode.insertBefore(tmpNode, endContainer.nextSibling);
} }
}
else {
tmpNode = doc.createTextNode(MARK_SELECTION_END);
endContainer.insertBefore(tmpNode, endContainer.childNodes.item(endOffset));
}
if (startContainer.nodeType == Node.TEXT_NODE || if (startContainer.nodeType == Node.TEXT_NODE ||
startContainer.nodeType == Node.CDATA_SECTION_NODE) { startContainer.nodeType == Node.CDATA_SECTION_NODE) {
// do some extra tweaks to try to avoid the view-source output to look like // do some extra tweaks to try to avoid the view-source output to look like
// ...<tag>[... or ...[</tag>... (where '[' marks the start of the selection). // ...<tag>[... or ...[</tag>... (where '[' marks the start of the selection).
// To get a neat output, the idea here is to remap the start point from: // To get a neat output, the idea here is to remap the start point from:
// 1. ...<tag>[... to ...[<tag>... // 1. ...<tag>[... to ...[<tag>...
// 2. ...[</tag>... to ...</tag>[... // 2. ...[</tag>... to ...</tag>[...
if ((startOffset > 0 && startOffset < startContainer.data.length) || if ((startOffset > 0 && startOffset < startContainer.data.length) ||
!startContainer.parentNode || !startContainer.parentNode.parentNode || !startContainer.parentNode || !startContainer.parentNode.parentNode ||
startContainer != startContainer.parentNode.lastChild) startContainer != startContainer.parentNode.lastChild)
startContainer.insertData(startOffset, MARK_SELECTION_START); startContainer.insertData(startOffset, MARK_SELECTION_START);
else {
tmpNode = doc.createTextNode(MARK_SELECTION_START);
startContainer = startContainer.parentNode;
if (startOffset == 0)
startContainer.parentNode.insertBefore(tmpNode, startContainer);
else
startContainer.parentNode.insertBefore(tmpNode, startContainer.nextSibling);
}
}
else { else {
tmpNode = doc.createTextNode(MARK_SELECTION_START); tmpNode = doc.createTextNode(MARK_SELECTION_START);
startContainer = startContainer.parentNode; startContainer.insertBefore(tmpNode, startContainer.childNodes.item(startOffset));
if (startOffset == 0)
startContainer.parentNode.insertBefore(tmpNode, startContainer);
else
startContainer.parentNode.insertBefore(tmpNode, startContainer.nextSibling);
} }
} }
else {
tmpNode = doc.createTextNode(MARK_SELECTION_START);
startContainer.insertBefore(tmpNode, startContainer.childNodes.item(startOffset));
}
// now extract and display the syntax highlighted source // now extract and display the syntax highlighted source
tmpNode = doc.createElementNS(NS_XHTML, 'div'); tmpNode = doc.createElementNS(NS_XHTML, 'div');
@ -191,7 +198,9 @@ function viewPartialSourceForSelection(selection)
// the load is aynchronous and so we will wait until the view-source DOM is done // the load is aynchronous and so we will wait until the view-source DOM is done
// before drawing the selection. // before drawing the selection.
window.document.getElementById("appcontent").addEventListener("load", drawSelection, true); if (canDrawSelection) {
window.document.getElementById("appcontent").addEventListener("load", drawSelection, true);
}
// all our content is held by the data:URI and URIs are internally stored as utf-8 (see nsIURI.idl) // all our content is held by the data:URI and URIs are internally stored as utf-8 (see nsIURI.idl)
var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE; var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;