зеркало из https://github.com/mozilla/gecko-dev.git
Bug 396108 - Crash [@ PresShell::ResizeReflow] with iframes, binding, while onbeforecopy removing stuff, patch by Mathieu Fenniak, r=Olli.Pettay, sr=jst, a=jonas
This commit is contained in:
Родитель
d8000edd01
Коммит
763317bf92
|
@ -1824,29 +1824,10 @@ NS_IMETHODIMP nsHTMLEditor::Paste(PRInt32 aSelectionType)
|
|||
{
|
||||
ForceCompositionEnd();
|
||||
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Fire the paste event.
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_PASTE);
|
||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
||||
nsnull, &status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault)
|
||||
return NS_OK;
|
||||
|
||||
// Did the event handler cause the editor to be destroyed?
|
||||
// (ie. the input element was removed from the document)
|
||||
// Don't proceed with paste.
|
||||
if (mDidPreDestroy)
|
||||
return NS_OK;
|
||||
}
|
||||
PRBool preventDefault;
|
||||
nsresult rv = FireClipboardEvent(NS_PASTE, &preventDefault);
|
||||
if (NS_FAILED(rv) || preventDefault)
|
||||
return rv;
|
||||
|
||||
// Get Clipboard Service
|
||||
nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
|
||||
|
@ -1959,26 +1940,9 @@ NS_IMETHODIMP nsHTMLEditor::CanPaste(PRInt32 aSelectionType, PRBool *aCanPaste)
|
|||
NS_ENSURE_ARG_POINTER(aCanPaste);
|
||||
*aCanPaste = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Fire the beforepaste event. If the event handler requests to prevent
|
||||
// default behavior, set *aCanPaste = true. (IE-style behavior)
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_BEFOREPASTE);
|
||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
||||
nsnull, &status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
*aCanPaste = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
nsresult rv = FireClipboardEvent(NS_BEFOREPASTE, aCanPaste);
|
||||
if (NS_FAILED(rv) || *aCanPaste)
|
||||
return rv;
|
||||
|
||||
// can't paste if readonly
|
||||
if (!IsModifiable())
|
||||
|
|
|
@ -427,29 +427,10 @@ NS_IMETHODIMP nsPlaintextEditor::Paste(PRInt32 aSelectionType)
|
|||
{
|
||||
ForceCompositionEnd();
|
||||
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Fire the paste event.
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_PASTE);
|
||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
||||
nsnull, &status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault)
|
||||
return NS_OK;
|
||||
|
||||
// Did the event handler cause the editor to be destroyed?
|
||||
// (ie. the input element was removed from the document)
|
||||
// Don't proceed with paste, as it will crash.
|
||||
if (mDidPreDestroy)
|
||||
return NS_OK;
|
||||
}
|
||||
PRBool preventDefault;
|
||||
nsresult rv = FireClipboardEvent(NS_PASTE, &preventDefault);
|
||||
if (NS_FAILED(rv) || preventDefault)
|
||||
return rv;
|
||||
|
||||
// Get Clipboard Service
|
||||
nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
|
||||
|
@ -483,26 +464,9 @@ NS_IMETHODIMP nsPlaintextEditor::CanPaste(PRInt32 aSelectionType, PRBool *aCanPa
|
|||
NS_ENSURE_ARG_POINTER(aCanPaste);
|
||||
*aCanPaste = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Fire the beforepaste event. If the event handler requests to prevent
|
||||
// default behavior, set *aCanPaste = true. (IE-style behavior)
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_BEFOREPASTE);
|
||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
||||
nsnull, &status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
*aCanPaste = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
nsresult rv = FireClipboardEvent(NS_BEFOREPASTE, aCanPaste);
|
||||
if (NS_FAILED(rv) || *aCanPaste)
|
||||
return rv;
|
||||
|
||||
// can't paste if readonly
|
||||
if (!IsModifiable())
|
||||
|
|
|
@ -1148,25 +1148,50 @@ nsresult nsPlaintextEditor::GetClipboardEventTarget(nsIDOMNode** aEventTarget)
|
|||
return nsCopySupport::GetClipboardEventTarget(selection, aEventTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPlaintextEditor::Cut()
|
||||
nsresult nsPlaintextEditor::FireClipboardEvent(PRUint32 msg,
|
||||
PRBool* aPreventDefault)
|
||||
{
|
||||
*aPreventDefault = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Fire the cut event.
|
||||
// Unsafe to fire event during reflow (bug 396108)
|
||||
PRBool isReflowing = PR_TRUE;
|
||||
nsresult rv = ps->IsReflowLocked(&isReflowing);
|
||||
if (NS_FAILED(rv) || isReflowing)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_CUT);
|
||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
||||
nsnull, &status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault)
|
||||
return NS_OK;
|
||||
}
|
||||
rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
if (NS_FAILED(rv))
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
return NS_OK;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, msg);
|
||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
||||
nsnull, &status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault)
|
||||
*aPreventDefault = PR_TRUE;
|
||||
|
||||
// Did the event handler cause the editor to be destroyed? (ie. the input
|
||||
// element was removed from the document) Don't proceed with command,
|
||||
// could crash, definitely does during paste.
|
||||
if (mDidPreDestroy)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPlaintextEditor::Cut()
|
||||
{
|
||||
PRBool preventDefault;
|
||||
nsresult rv = FireClipboardEvent(NS_CUT, &preventDefault);
|
||||
if (NS_FAILED(rv) || preventDefault)
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
rv = GetSelection(getter_AddRefs(selection));
|
||||
|
@ -1177,6 +1202,8 @@ NS_IMETHODIMP nsPlaintextEditor::Cut()
|
|||
if (NS_SUCCEEDED(selection->GetIsCollapsed(&isCollapsed)) && isCollapsed)
|
||||
return NS_OK; // just return ok so no JS error is thrown
|
||||
|
||||
// ps should be guaranteed by FireClipboardEvent not failing
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
rv = ps->DoCopy();
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = DeleteSelection(eNone);
|
||||
|
@ -1188,26 +1215,9 @@ NS_IMETHODIMP nsPlaintextEditor::CanCut(PRBool *aCanCut)
|
|||
NS_ENSURE_ARG_POINTER(aCanCut);
|
||||
*aCanCut = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Fire the beforecut event. If the event handler requests to prevent
|
||||
// default behavior, set *aCanCut = true. (IE-style behavior)
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_BEFORECUT);
|
||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
||||
nsnull, &status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
*aCanCut = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
nsresult rv = FireClipboardEvent(NS_BEFORECUT, aCanCut);
|
||||
if (NS_FAILED(rv) || *aCanCut)
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
rv = GetSelection(getter_AddRefs(selection));
|
||||
|
@ -1223,26 +1233,13 @@ NS_IMETHODIMP nsPlaintextEditor::CanCut(PRBool *aCanCut)
|
|||
|
||||
NS_IMETHODIMP nsPlaintextEditor::Copy()
|
||||
{
|
||||
PRBool preventDefault;
|
||||
nsresult rv = FireClipboardEvent(NS_COPY, &preventDefault);
|
||||
if (NS_FAILED(rv) || preventDefault)
|
||||
return rv;
|
||||
|
||||
// ps should be guaranteed by FireClipboardEvent not failing
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Fire the copy event.
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_COPY);
|
||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
||||
nsnull, &status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault)
|
||||
return NS_OK;
|
||||
// the affect of the event handler closing the window here has been
|
||||
// tested, it works without crashes.
|
||||
}
|
||||
|
||||
return ps->DoCopy();
|
||||
}
|
||||
|
||||
|
@ -1251,26 +1248,9 @@ NS_IMETHODIMP nsPlaintextEditor::CanCopy(PRBool *aCanCopy)
|
|||
NS_ENSURE_ARG_POINTER(aCanCopy);
|
||||
*aCanCopy = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||
if (!ps)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Fire the beforecopy event. If the event handler requests to prevent
|
||||
// default behavior, set *aCopyable = true. (IE-style behavior)
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_BEFORECOPY);
|
||||
nsEventDispatcher::Dispatch(eventTarget, ps->GetPresContext(), &evt,
|
||||
nsnull, &status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
*aCanCopy = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
nsresult rv = FireClipboardEvent(NS_BEFORECOPY, aCanCopy);
|
||||
if (NS_FAILED(rv) || *aCanCopy)
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
rv = GetSelection(getter_AddRefs(selection));
|
||||
|
|
|
@ -216,7 +216,8 @@ protected:
|
|||
|
||||
// Wrapper for nsCopySupport::GetClipboardEventTarget, finds target to fire
|
||||
// [cut,copy,paste] and [beforecut,beforecopy,beforepaste] events at.
|
||||
virtual nsresult GetClipboardEventTarget(nsIDOMNode** aEventTarget);
|
||||
nsresult GetClipboardEventTarget(nsIDOMNode** aEventTarget);
|
||||
nsresult FireClipboardEvent(PRUint32 msg, PRBool* aPreventDefault);
|
||||
|
||||
// Data members
|
||||
protected:
|
||||
|
|
Загрузка…
Ссылка в новой задаче