Bug 489224 - Printing doesn't print text field values, r+sr=roc
This commit is contained in:
Родитель
2f195ff7fd
Коммит
a60704bc40
|
@ -101,10 +101,10 @@ class nsPIDOMEventTarget;
|
|||
typedef short SelectionType;
|
||||
typedef PRUint32 nsFrameState;
|
||||
|
||||
// fa7f090d-b19a-4ef8-9552-82992a3b4a83
|
||||
// b8ace28a-d3fa-46d8-a5a0-d7c35c12fd41
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0xfa7f090d, 0xb19a, 0x4ef8, \
|
||||
{ 0x95, 0x52, 0x82, 0x99, 0x2a, 0x3b, 0x4a, 0x83 } }
|
||||
{ 0xb8ace28a, 0xd3fa, 0x46d8, \
|
||||
{ 0xa5, 0xa0, 0xd7, 0xc3, 0x5c, 0x12, 0xfd, 0x41 } }
|
||||
|
||||
// Constants for ScrollContentIntoView() function
|
||||
#define NS_PRESSHELL_SCROLL_TOP 0
|
||||
|
@ -793,6 +793,15 @@ public:
|
|||
void SetCanvasBackground(nscolor aColor) { mCanvasBackgroundColor = aColor; }
|
||||
nscolor GetCanvasBackground() { return mCanvasBackgroundColor; }
|
||||
|
||||
void ObserveNativeAnonMutationsForPrint(PRBool aObserve)
|
||||
{
|
||||
mObservesMutationsForPrint = aObserve;
|
||||
}
|
||||
PRBool ObservesNativeAnonMutationsForPrint()
|
||||
{
|
||||
return mObservesMutationsForPrint;
|
||||
}
|
||||
|
||||
protected:
|
||||
// IMPORTANT: The ownership implicit in the following member variables
|
||||
// has been explicitly checked. If you add any members to this class,
|
||||
|
@ -829,6 +838,8 @@ protected:
|
|||
// the dom/layout trees
|
||||
PRPackedBool mIsAccessibilityActive;
|
||||
|
||||
PRPackedBool mObservesMutationsForPrint;
|
||||
|
||||
// A list of weak frames. This is a pointer to the last item in the list.
|
||||
nsWeakFrame* mWeakFrames;
|
||||
|
||||
|
|
|
@ -766,119 +766,6 @@ struct nsCallbackEventRequest
|
|||
nsCallbackEventRequest* next;
|
||||
};
|
||||
|
||||
|
||||
class nsDocumentObserverForNonDynamicPresContext : public nsStubDocumentObserver
|
||||
{
|
||||
public:
|
||||
nsDocumentObserverForNonDynamicPresContext(nsIDocumentObserver* aBaseObserver)
|
||||
: mBaseObserver(aBaseObserver)
|
||||
{
|
||||
NS_ASSERTION(aBaseObserver, "Null document observer!");
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void BeginUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType)
|
||||
{
|
||||
mBaseObserver->BeginUpdate(aDocument, aUpdateType);
|
||||
}
|
||||
virtual void EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType)
|
||||
{
|
||||
mBaseObserver->EndUpdate(aDocument, aUpdateType);
|
||||
}
|
||||
virtual void BeginLoad(nsIDocument* aDocument)
|
||||
{
|
||||
mBaseObserver->BeginLoad(aDocument);
|
||||
}
|
||||
virtual void EndLoad(nsIDocument* aDocument)
|
||||
{
|
||||
mBaseObserver->EndLoad(aDocument);
|
||||
}
|
||||
virtual void ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
if ((!aContent1 || IsInRootScrollbar(aContent1)) &&
|
||||
(!aContent2 || IsInRootScrollbar(aContent2))) {
|
||||
mBaseObserver->ContentStatesChanged(aDocument, aContent1, aContent2,
|
||||
aStateMask);
|
||||
}
|
||||
}
|
||||
|
||||
// nsIMutationObserver
|
||||
virtual void CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo)
|
||||
{
|
||||
if (IsInRootScrollbar(aContent)) {
|
||||
mBaseObserver->CharacterDataChanged(aDocument, aContent, aInfo);
|
||||
}
|
||||
}
|
||||
virtual void AttributeChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRUint32 aStateMask)
|
||||
{
|
||||
if (IsInRootScrollbar(aContent)) {
|
||||
mBaseObserver->AttributeChanged(aDocument, aContent, aNameSpaceID,
|
||||
aAttribute, aModType, aStateMask);
|
||||
}
|
||||
}
|
||||
virtual void ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
{
|
||||
if (IsInRootScrollbar(aContainer)) {
|
||||
mBaseObserver->ContentAppended(aDocument, aContainer,
|
||||
aNewIndexInContainer);
|
||||
}
|
||||
}
|
||||
virtual void ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (IsInRootScrollbar(aContainer)) {
|
||||
mBaseObserver->ContentInserted(aDocument, aContainer, aChild,
|
||||
aIndexInContainer);
|
||||
}
|
||||
}
|
||||
virtual void ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (IsInRootScrollbar(aContainer)) {
|
||||
mBaseObserver->ContentRemoved(aDocument, aContainer, aChild,
|
||||
aIndexInContainer);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool IsInRootScrollbar(nsIContent* aContent) {
|
||||
if(aContent && aContent->IsInDoc()) {
|
||||
nsIContent* root = aContent->GetCurrentDoc()->GetRootContent();
|
||||
while (aContent && aContent->IsInNativeAnonymousSubtree()) {
|
||||
nsIContent* parent = aContent->GetParent();
|
||||
if (parent == root && aContent->IsNodeOfType(nsINode::eXUL)) {
|
||||
nsIAtom* tag = aContent->Tag();
|
||||
return tag == nsGkAtoms::scrollbar || tag == nsGkAtoms::scrollcorner;
|
||||
}
|
||||
aContent = parent;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
protected:
|
||||
nsCOMPtr<nsIDocumentObserver> mBaseObserver;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsDocumentObserverForNonDynamicPresContext,
|
||||
nsIDocumentObserver,
|
||||
nsIMutationObserver)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
class nsPresShellEventCB;
|
||||
|
||||
|
@ -1389,6 +1276,123 @@ public:
|
|||
nsRefPtr<PresShell> mPresShell;
|
||||
};
|
||||
|
||||
class nsDocumentObserverForNonDynamicPresContext : public nsStubDocumentObserver
|
||||
{
|
||||
public:
|
||||
nsDocumentObserverForNonDynamicPresContext(PresShell* aBaseObserver)
|
||||
: mBaseObserver(aBaseObserver)
|
||||
{
|
||||
NS_ASSERTION(aBaseObserver, "Null document observer!");
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void BeginUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType)
|
||||
{
|
||||
mBaseObserver->BeginUpdate(aDocument, aUpdateType);
|
||||
}
|
||||
virtual void EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType)
|
||||
{
|
||||
mBaseObserver->EndUpdate(aDocument, aUpdateType);
|
||||
}
|
||||
virtual void BeginLoad(nsIDocument* aDocument)
|
||||
{
|
||||
mBaseObserver->BeginLoad(aDocument);
|
||||
}
|
||||
virtual void EndLoad(nsIDocument* aDocument)
|
||||
{
|
||||
mBaseObserver->EndLoad(aDocument);
|
||||
}
|
||||
virtual void ContentStatesChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent1,
|
||||
nsIContent* aContent2,
|
||||
PRInt32 aStateMask)
|
||||
{
|
||||
if ((!aContent1 || AllowMutation(aContent1)) &&
|
||||
(!aContent2 || AllowMutation(aContent2))) {
|
||||
mBaseObserver->ContentStatesChanged(aDocument, aContent1, aContent2,
|
||||
aStateMask);
|
||||
}
|
||||
}
|
||||
|
||||
// nsIMutationObserver
|
||||
virtual void CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo)
|
||||
{
|
||||
if (AllowMutation(aContent)) {
|
||||
mBaseObserver->CharacterDataChanged(aDocument, aContent, aInfo);
|
||||
}
|
||||
}
|
||||
virtual void AttributeChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType,
|
||||
PRUint32 aStateMask)
|
||||
{
|
||||
if (AllowMutation(aContent)) {
|
||||
mBaseObserver->AttributeChanged(aDocument, aContent, aNameSpaceID,
|
||||
aAttribute, aModType, aStateMask);
|
||||
}
|
||||
}
|
||||
virtual void ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
{
|
||||
if (AllowMutation(aContainer)) {
|
||||
mBaseObserver->ContentAppended(aDocument, aContainer,
|
||||
aNewIndexInContainer);
|
||||
}
|
||||
}
|
||||
virtual void ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (AllowMutation(aContainer)) {
|
||||
mBaseObserver->ContentInserted(aDocument, aContainer, aChild,
|
||||
aIndexInContainer);
|
||||
}
|
||||
}
|
||||
virtual void ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
if (AllowMutation(aContainer)) {
|
||||
mBaseObserver->ContentRemoved(aDocument, aContainer, aChild,
|
||||
aIndexInContainer);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool AllowMutation(nsIContent* aContent) {
|
||||
if(aContent && aContent->IsInDoc()) {
|
||||
if (mBaseObserver->ObservesNativeAnonMutationsForPrint() &&
|
||||
aContent->IsInNativeAnonymousSubtree()) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
// Changes to scrollbar are always ok.
|
||||
nsIContent* root = aContent->GetCurrentDoc()->GetRootContent();
|
||||
while (aContent && aContent->IsInNativeAnonymousSubtree()) {
|
||||
nsIContent* parent = aContent->GetParent();
|
||||
if (parent == root && aContent->IsNodeOfType(nsINode::eXUL)) {
|
||||
nsIAtom* tag = aContent->Tag();
|
||||
return tag == nsGkAtoms::scrollbar || tag == nsGkAtoms::scrollcorner;
|
||||
}
|
||||
aContent = parent;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
protected:
|
||||
nsRefPtr<PresShell> mBaseObserver;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsDocumentObserverForNonDynamicPresContext,
|
||||
nsIDocumentObserver,
|
||||
nsIMutationObserver)
|
||||
|
||||
PRBool PresShell::sDisableNonTestMouseEvents = PR_FALSE;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
|
|
@ -146,15 +146,82 @@ function runTest2() {
|
|||
isnot(window.frames[0].counter, 0, "Timers should have run!");
|
||||
counter = window.frames[0].counter;
|
||||
window.frames[0].counterTimeout = "";
|
||||
setTimeout(runTest3, 0);
|
||||
}
|
||||
|
||||
var elementIndex = 0;
|
||||
var compareEmptyElement = true;
|
||||
var emptyFormElements =
|
||||
["<input type='text'>",
|
||||
"<input type='password'>",
|
||||
"<input type='file'>",
|
||||
"<input type='button'>",
|
||||
"<input type='submit'>",
|
||||
"<input type='reset'>",
|
||||
"<input type='checkbox'>",
|
||||
"<input type='radio'>",
|
||||
"<select></select>",
|
||||
"<select size='5'></select>",
|
||||
"<textarea></textarea>"];
|
||||
|
||||
var formElements =
|
||||
["<input type='text' value='text'>",
|
||||
"<input type='password' value='password'>",
|
||||
"<input type='file' value='file'>",
|
||||
"<input type='button' value='button'>",
|
||||
"<input type='submit' value='submit button'>",
|
||||
"<input type='reset' value='reset button'>",
|
||||
"<input type='checkbox' checked>",
|
||||
"<input type='radio' checked>",
|
||||
"<select><option>option1</option></select>",
|
||||
"<select size='5'><option>1</option><option>2</option><option>3</option></select>",
|
||||
"<textarea value='textarea'>textarea</textarea>"];
|
||||
|
||||
function runTest3() {
|
||||
if (compareEmptyElement) {
|
||||
var currentIndex = elementIndex;
|
||||
++elementIndex;
|
||||
if (elementIndex >= emptyFormElements.length) {
|
||||
elementIndex = 0;
|
||||
compareEmptyElement = false;
|
||||
}
|
||||
compareFormElementPrint(emptyFormElements[currentIndex], emptyFormElements[currentIndex], true);
|
||||
return;
|
||||
} else if (elementIndex < emptyFormElements.length) {
|
||||
var currentIndex = elementIndex;
|
||||
++elementIndex;
|
||||
compareFormElementPrint(emptyFormElements[currentIndex], formElements[currentIndex], false);
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function compareFormElementPrint(el1, el2, equals) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
window.frames[0].document.body.innerHTML = el1;
|
||||
window.frames[0].document.body.firstChild.value =
|
||||
window.frames[0].document.body.firstChild.getAttribute('value');
|
||||
printpreview();
|
||||
ctx1.drawWindow(window.frames[0], 0, 0, 300, 300, "rgb(256,256,256)");
|
||||
exitprintpreview();
|
||||
window.frames[0].document.body.innerHTML = el2;
|
||||
window.frames[0].document.body.firstChild.value =
|
||||
window.frames[0].document.body.firstChild.getAttribute('value');
|
||||
printpreview();
|
||||
ctx2.drawWindow(window.frames[0], 0, 0, 300, 300, "rgb(256,256,256)");
|
||||
exitprintpreview();
|
||||
is(compareCanvases(), equals,
|
||||
"Comparing print preview didn't succeed [" + el1 + " : " + el2 + "]");
|
||||
setTimeout(runTest3, 100);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
<iframe height="200" width="600"></iframe>
|
||||
<table>
|
||||
<tr><th>Print preview canvas before mutations</th><th>Print preview canvas after mutations</th></tr>
|
||||
<tr><th>Print preview canvas 1</th><th>Print preview canvas 2</th></tr>
|
||||
<tr>
|
||||
<td><canvas height="300" width="300"></canvas></td>
|
||||
<td><canvas height="300" width="300"></canvas></td>
|
||||
|
|
|
@ -223,7 +223,12 @@ protected:
|
|||
|
||||
NS_IMETHOD Run() {
|
||||
if (mWeakFrame) {
|
||||
nsCOMPtr<nsIPresShell> shell =
|
||||
mWeakFrame.GetFrame()->PresContext()->GetPresShell();
|
||||
PRBool observes = shell->ObservesNativeAnonMutationsForPrint();
|
||||
shell->ObserveNativeAnonMutationsForPrint(PR_TRUE);
|
||||
mFrame->DelayedEditorInit();
|
||||
shell->ObserveNativeAnonMutationsForPrint(observes);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче