Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 211919 Details for
Bug 372960
Sometimes CurrentPhase#get() returns a wrong phase
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Patch that implements the idea in comment#4
Bug-372960v2.patch (text/plain), 20.31 KB, created by
Ivan Furnadjiev
on 2012-03-01 17:38:20 EST
(
hide
)
Description:
Patch that implements the idea in comment#4
Filename:
MIME Type:
Creator:
Ivan Furnadjiev
Created:
2012-03-01 17:38:20 EST
Size:
20.31 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.rap.rwt >Index: src/org/eclipse/rwt/internal/application/ApplicationContextConfigurator.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/application/ApplicationContextConfigurator.java,v >retrieving revision 1.4 >diff -u -r1.4 ApplicationContextConfigurator.java >--- src/org/eclipse/rwt/internal/application/ApplicationContextConfigurator.java 13 Nov 2011 17:16:55 -0000 1.4 >+++ src/org/eclipse/rwt/internal/application/ApplicationContextConfigurator.java 1 Mar 2012 22:33:56 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2011 Frank Appel and others. >+ * Copyright (c) 2011, 2012 Frank Appel and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -7,6 +7,7 @@ > * > * Contributors: > * Frank Appel - initial API and implementation >+ * EclipseSource - ongoing development > ******************************************************************************/ > package org.eclipse.rwt.internal.application; > >@@ -15,7 +16,6 @@ > import org.eclipse.rwt.application.ApplicationConfigurator; > import org.eclipse.rwt.internal.engine.RWTConfiguration; > import org.eclipse.rwt.internal.engine.RWTConfigurationImpl; >-import org.eclipse.rwt.internal.lifecycle.CurrentPhase; > import org.eclipse.rwt.internal.service.ApplicationStoreImpl; > import org.eclipse.rwt.internal.service.ServiceManager; > import org.eclipse.rwt.internal.textsize.MeasurementListener; >@@ -92,7 +92,6 @@ > } > > private void addInternalPhaseListeners( ApplicationContext applicationContext ) { >- applicationContext.getPhaseListenerRegistry().add( new CurrentPhase.Listener() ); > applicationContext.getPhaseListenerRegistry().add( new MeasurementListener() ); > } > >Index: src/org/eclipse/rwt/internal/lifecycle/CurrentPhase.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/lifecycle/CurrentPhase.java,v >retrieving revision 1.9 >diff -u -r1.9 CurrentPhase.java >--- src/org/eclipse/rwt/internal/lifecycle/CurrentPhase.java 26 Dec 2011 14:56:49 -0000 1.9 >+++ src/org/eclipse/rwt/internal/lifecycle/CurrentPhase.java 1 Mar 2012 22:33:56 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2002, 2011 Innoopract Informationssysteme GmbH and others. >+ * Copyright (c) 2002, 2012 Innoopract Informationssysteme GmbH and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -18,23 +18,7 @@ > > public final class CurrentPhase { > >- public static final class Listener implements PhaseListener { >- >- public void beforePhase( PhaseEvent event ) { >- set( event.getPhaseId() ); >- } >- >- public void afterPhase( PhaseEvent event ) { >- // do nothing >- } >- >- public PhaseId getPhaseId() { >- return PhaseId.ANY; >- } >- } >- >- private static final String ATTR_CURRENT_PHASE >- = CurrentPhase.class.getName() + "#value"; >+ private static final String ATTR_CURRENT_PHASE = CurrentPhase.class.getName() + "#value"; > > private CurrentPhase() { > // prevent instantiation >Index: src/org/eclipse/rwt/internal/lifecycle/PhaseExecutor.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/lifecycle/PhaseExecutor.java,v >retrieving revision 1.2 >diff -u -r1.2 PhaseExecutor.java >--- src/org/eclipse/rwt/internal/lifecycle/PhaseExecutor.java 3 May 2011 10:05:44 -0000 1.2 >+++ src/org/eclipse/rwt/internal/lifecycle/PhaseExecutor.java 1 Mar 2012 22:33:56 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2011 EclipseSource and others. >+ * Copyright (c) 2011, 2012 EclipseSource and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -30,13 +30,14 @@ > PhaseId currentPhaseId = startPhaseId; > while( currentPhaseId != null ) { > IPhase currentPhase = findPhase( currentPhaseId ); >+ CurrentPhase.set( currentPhaseId ); > phaseListenerManager.notifyBeforePhase( currentPhaseId ); > PhaseId nextPhaseId = currentPhase.execute( getDisplay() ); > phaseListenerManager.notifyAfterPhase( currentPhaseId ); > currentPhaseId = nextPhaseId; > } > } >- >+ > abstract Display getDisplay(); > > private IPhase findPhase( PhaseId phaseId ) { >Index: src/org/eclipse/rwt/internal/lifecycle/RWTLifeCycle.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/lifecycle/RWTLifeCycle.java,v >retrieving revision 1.63 >diff -u -r1.63 RWTLifeCycle.java >--- src/org/eclipse/rwt/internal/lifecycle/RWTLifeCycle.java 24 Feb 2012 11:39:49 -0000 1.63 >+++ src/org/eclipse/rwt/internal/lifecycle/RWTLifeCycle.java 1 Mar 2012 22:33:56 -0000 >@@ -145,6 +145,7 @@ > boolean interrupted = false; > for( int i = start; !interrupted && i < phaseOrder.length; i++ ) { > IPhase phase = phaseOrder[ i ]; >+ CurrentPhase.set( phase.getPhaseId() ); > phaseListenerManager.notifyBeforePhase( phase.getPhaseId() ); > if( phase instanceof IInterruptible ) { > // IInterruptible phases return control to the user code, thus they don't call >#P org.eclipse.rap.rwt.test >Index: src/org/eclipse/rwt/engine/RWTServletContextListener_Test.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt.test/org.eclipse.rap.rwt.test/src/org/eclipse/rwt/engine/RWTServletContextListener_Test.java,v >retrieving revision 1.7 >diff -u -r1.7 RWTServletContextListener_Test.java >--- src/org/eclipse/rwt/engine/RWTServletContextListener_Test.java 18 Feb 2012 16:45:15 -0000 1.7 >+++ src/org/eclipse/rwt/engine/RWTServletContextListener_Test.java 1 Mar 2012 22:33:57 -0000 >@@ -108,7 +108,7 @@ > > private void assertPhaseListenersAreRegistered() { > ApplicationContext applicationContext = ApplicationContextUtil.get( servletContext ); >- assertEquals( 3, applicationContext.getPhaseListenerRegistry().getAll().length ); >+ assertEquals( 2, applicationContext.getPhaseListenerRegistry().getAll().length ); > } > > private void assertResourceIsRegistered() { >Index: src/org/eclipse/rwt/internal/application/ApplicationContextConfigurator_Test.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt.test/org.eclipse.rap.rwt.test/src/org/eclipse/rwt/internal/application/ApplicationContextConfigurator_Test.java,v >retrieving revision 1.9 >diff -u -r1.9 ApplicationContextConfigurator_Test.java >--- src/org/eclipse/rwt/internal/application/ApplicationContextConfigurator_Test.java 18 Feb 2012 16:45:15 -0000 1.9 >+++ src/org/eclipse/rwt/internal/application/ApplicationContextConfigurator_Test.java 1 Mar 2012 22:33:57 -0000 >@@ -30,7 +30,6 @@ > import org.eclipse.rwt.internal.AdapterManager; > import org.eclipse.rwt.internal.engine.RWTConfiguration; > import org.eclipse.rwt.internal.engine.RWTConfigurationImpl; >-import org.eclipse.rwt.internal.lifecycle.CurrentPhase; > import org.eclipse.rwt.internal.service.ServiceManager; > import org.eclipse.rwt.internal.textsize.MeasurementListener; > import org.eclipse.rwt.internal.theme.Theme; >@@ -320,8 +319,7 @@ > } > > private void checkPhaseListenersHaveBeenAdded() { >- assertEquals( 3, applicationContext.getPhaseListenerRegistry().getAll().length ); >- assertEquals( true, findPhaseListener( CurrentPhase.Listener.class ) ); >+ assertEquals( 2, applicationContext.getPhaseListenerRegistry().getAll().length ); > assertEquals( true, findPhaseListener( MeasurementListener.class ) ); > assertEquals( true, findPhaseListener( TestPhaseListener.class ) ); > } >Index: src/org/eclipse/rwt/internal/lifecycle/PhaseExecutor_Test.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt.test/org.eclipse.rap.rwt.test/src/org/eclipse/rwt/internal/lifecycle/PhaseExecutor_Test.java,v >retrieving revision 1.6 >diff -u -r1.6 PhaseExecutor_Test.java >--- src/org/eclipse/rwt/internal/lifecycle/PhaseExecutor_Test.java 25 Sep 2011 15:19:25 -0000 1.6 >+++ src/org/eclipse/rwt/internal/lifecycle/PhaseExecutor_Test.java 1 Mar 2012 22:33:57 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2011 EclipseSource and others. >+ * Copyright (c) 2011, 2012 EclipseSource and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -16,6 +16,7 @@ > > import junit.framework.TestCase; > >+import org.eclipse.rap.rwt.testfixture.Fixture; > import org.eclipse.rap.rwt.testfixture.internal.LoggingPhaseListener; > import org.eclipse.rap.rwt.testfixture.internal.LoggingPhaseListener.PhaseEventInfo; > import org.eclipse.rwt.lifecycle.*; >@@ -30,6 +31,7 @@ > super( phaseListenerManager, phases ); > } > >+ @Override > Display getDisplay() { > return null; > } >@@ -41,13 +43,13 @@ > public void addPhaseListener( PhaseListener listener ) { > } > } >- >+ > private static class TestPhase implements IPhase { > > private final List<IPhase> executionLog; > private final PhaseId phaseId; > private final PhaseId nextPhaseId; >- >+ > TestPhase( List<IPhase> executionLog, PhaseId phaseId, PhaseId nextPhaseId ) { > this.executionLog = executionLog; > this.phaseId = phaseId; >@@ -69,9 +71,9 @@ > > public void testExecute() throws IOException { > List<IPhase> executionLog = new LinkedList<IPhase>(); >- IPhase[] phases = new IPhase[] { >- new TestPhase( executionLog, PhaseId.PREPARE_UI_ROOT, PhaseId.RENDER ), >- new TestPhase( executionLog, PhaseId.RENDER, null ) >+ IPhase[] phases = new IPhase[] { >+ new TestPhase( executionLog, PhaseId.PREPARE_UI_ROOT, PhaseId.RENDER ), >+ new TestPhase( executionLog, PhaseId.RENDER, null ) > }; > PhaseExecutor phaseExecutor = new TestPhaseExecutor( phaseListenerManager, phases ); > phaseExecutor.execute( PhaseId.PREPARE_UI_ROOT ); >@@ -79,12 +81,12 @@ > assertSame( phases[ 0 ], executionLog.get( 0 ) ); > assertSame( phases[ 1 ], executionLog.get( 1 ) ); > } >- >+ > public void testExecuteNotifiesPhaseListener() throws IOException { > LoggingPhaseListener phaseListener = new LoggingPhaseListener( PhaseId.ANY ); > phaseListenerManager.addPhaseListener( phaseListener ); >- IPhase[] phases = new IPhase[] { >- new TestPhase( new LinkedList<IPhase>(), PhaseId.PREPARE_UI_ROOT, null ), >+ IPhase[] phases = new IPhase[] { >+ new TestPhase( new LinkedList<IPhase>(), PhaseId.PREPARE_UI_ROOT, null ), > }; > PhaseExecutor phaseExecutor = new TestPhaseExecutor( phaseListenerManager, phases ); > phaseExecutor.execute( PhaseId.PREPARE_UI_ROOT ); >@@ -100,8 +102,15 @@ > assertSame( lifeCycle, afterPrepareUIRoot.source ); > } > >+ @Override > protected void setUp() throws Exception { >+ Fixture.setUp(); > lifeCycle = new TestLifeCycle(); > phaseListenerManager = new PhaseListenerManager( lifeCycle ); > } >+ >+ @Override >+ protected void tearDown() throws Exception { >+ Fixture.tearDown(); >+ } > } >Index: src/org/eclipse/rwt/internal/lifecycle/PhaseListenerManager_Test.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt.test/org.eclipse.rap.rwt.test/src/org/eclipse/rwt/internal/lifecycle/PhaseListenerManager_Test.java,v >retrieving revision 1.4 >diff -u -r1.4 PhaseListenerManager_Test.java >--- src/org/eclipse/rwt/internal/lifecycle/PhaseListenerManager_Test.java 26 Dec 2011 15:10:43 -0000 1.4 >+++ src/org/eclipse/rwt/internal/lifecycle/PhaseListenerManager_Test.java 1 Mar 2012 22:33:57 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2011 EclipseSource and others. >+ * Copyright (c) 2011, 2012 EclipseSource and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -19,12 +19,14 @@ > import org.eclipse.rap.rwt.testfixture.*; > import org.eclipse.rap.rwt.testfixture.internal.LoggingPhaseListener; > import org.eclipse.rap.rwt.testfixture.internal.LoggingPhaseListener.PhaseEventInfo; >+import org.eclipse.rwt.RWT; > import org.eclipse.rwt.internal.service.ContextProvider; > import org.eclipse.rwt.lifecycle.*; >+import org.eclipse.swt.widgets.Display; > > > public class PhaseListenerManager_Test extends TestCase { >- >+ > private static class TestError extends Error { > private static final long serialVersionUID = 1L; > } >@@ -62,15 +64,15 @@ > > private static class ErrorPhaseListener implements PhaseListener { > private static final long serialVersionUID = 1L; >- >+ > public void beforePhase( PhaseEvent event ) { > throw new TestError(); > } >- >+ > public void afterPhase( PhaseEvent event ) { > throw new TestError(); > } >- >+ > public PhaseId getPhaseId() { > return PhaseId.ANY; > } >@@ -80,7 +82,7 @@ > private List<Throwable> exceptionsInServletLog; > private PhaseListenerManager phaseListenerManager; > private ILifeCycle lifeCycle; >- >+ > public void testAddPhaseListenerWithNullArgument() { > try { > phaseListenerManager.addPhaseListener( null ); >@@ -88,7 +90,7 @@ > } catch( NullPointerException expected ) { > } > } >- >+ > public void testAddPhaseListener() { > LoggingPhaseListener phaseListener = new LoggingPhaseListener( null ); > phaseListenerManager.addPhaseListener( phaseListener ); >@@ -104,7 +106,7 @@ > PhaseListener[] phaseListeners = phaseListenerManager.getPhaseListeners(); > assertEquals( 1, phaseListeners.length ); > } >- >+ > public void testAddPhaseListeners() { > PhaseListener phaseListener1 = new EmptyPhaseListener(); > PhaseListener phaseListener2 = new EmptyPhaseListener(); >@@ -113,7 +115,7 @@ > PhaseListener[] returnedPhaseListeners = phaseListenerManager.getPhaseListeners(); > assertEquals( 2, returnedPhaseListeners.length ); > } >- >+ > public void testAddPhaseListenersWithNullArgument() { > try { > phaseListenerManager.addPhaseListeners( null ); >@@ -121,7 +123,7 @@ > } catch( NullPointerException expected ) { > } > } >- >+ > public void testRemovePhaseListenerWithNullArgument() { > try { > phaseListenerManager.removePhaseListener( null ); >@@ -137,7 +139,7 @@ > PhaseListener[] phaseListeners = phaseListenerManager.getPhaseListeners(); > assertEquals( 0, phaseListeners.length ); > } >- >+ > public void testRemovePhaseListenerTwice() { > LoggingPhaseListener phaseListener = new LoggingPhaseListener( null ); > phaseListenerManager.addPhaseListener( phaseListener ); >@@ -146,14 +148,14 @@ > PhaseListener[] phaseListeners = phaseListenerManager.getPhaseListeners(); > assertEquals( 0, phaseListeners.length ); > } >- >+ > public void testRemovePhaseListenerWithUnknownPhaseListener() { > phaseListenerManager.addPhaseListener( new LoggingPhaseListener( null ) ); > phaseListenerManager.removePhaseListener( new LoggingPhaseListener( null ) ); > PhaseListener[] phaseListeners = phaseListenerManager.getPhaseListeners(); > assertEquals( 1, phaseListeners.length ); > } >- >+ > public void testGetPhaseListenersReturnsSafeCopy() { > phaseListenerManager.addPhaseListener( new LoggingPhaseListener( null ) ); > PhaseListener[] phaseListeners1 = phaseListenerManager.getPhaseListeners(); >@@ -161,7 +163,7 @@ > PhaseListener[] phaseListeners2 = phaseListenerManager.getPhaseListeners(); > assertNotNull( phaseListeners2[ 0 ] ); > } >- >+ > public void testAddRemovePhaseListenerConcurently() throws InterruptedException { > final int threadCount = 120; > final List<Thread> succeededThreads = Collections.synchronizedList( new LinkedList<Thread>() ); >@@ -188,17 +190,17 @@ > phaseListenerManager.notifyBeforePhase( phase ); > assertEquals( 1, phaseListener.getLoggedEvents().length ); > PhaseEventInfo phaseEvent = phaseListener.getLoggedEvents()[ 0 ]; >- assertSame( lifeCycle, phaseEvent.source ); >+ assertSame( lifeCycle, phaseEvent.source ); > assertEquals( phase, phaseEvent.phaseId ); > } >- >+ > public void testNotifyBeforePhaseWithNonMatchingListener() { > LoggingPhaseListener phaseListener = new LoggingPhaseListener( PhaseId.RENDER ); > phaseListenerManager.addPhaseListener( phaseListener ); > phaseListenerManager.notifyBeforePhase( PhaseId.READ_DATA ); > assertEquals( 0, phaseListener.getLoggedEvents().length ); > } >- >+ > public void testNotifyBeforePhaseWithANYListener() { > PhaseId phase = PhaseId.READ_DATA; > LoggingPhaseListener phaseListener = new LoggingPhaseListener( PhaseId.ANY ); >@@ -206,10 +208,10 @@ > phaseListenerManager.notifyBeforePhase( phase ); > assertEquals( 1, phaseListener.getLoggedEvents().length ); > PhaseEventInfo phaseEvent = phaseListener.getLoggedEvents()[ 0 ]; >- assertSame( lifeCycle, phaseEvent.source ); >+ assertSame( lifeCycle, phaseEvent.source ); > assertEquals( phase, phaseEvent.phaseId ); > } >- >+ > public void testExceptionsInBeforePhaseEvent() { > phaseListenerManager.addPhaseListener( new ExceptionPhaseListener() ); > phaseListenerManager.addPhaseListener( new ExceptionPhaseListener() ); >@@ -232,17 +234,17 @@ > phaseListenerManager.addPhaseListener( phaseListener ); > phaseListenerManager.notifyAfterPhase( phase ); > assertEquals( 1, phaseListener.getLoggedEvents().length ); >- assertSame( lifeCycle, phaseListener.getLoggedEvents()[ 0 ].source ); >+ assertSame( lifeCycle, phaseListener.getLoggedEvents()[ 0 ].source ); > assertEquals( phase, phaseListener.getLoggedEvents()[ 0 ].phaseId ); > } >- >+ > public void testNotifyAfterPhaseWithNonMatchingListener() { > LoggingPhaseListener phaseListener = new LoggingPhaseListener( PhaseId.RENDER ); > phaseListenerManager.addPhaseListener( phaseListener ); > phaseListenerManager.notifyAfterPhase( PhaseId.READ_DATA ); > assertEquals( 0, phaseListener.getLoggedEvents().length ); > } >- >+ > public void testNotifyAfterPhaseWithANYListener() { > PhaseId phase = PhaseId.READ_DATA; > LoggingPhaseListener phaseListener = new LoggingPhaseListener( PhaseId.ANY ); >@@ -250,10 +252,10 @@ > phaseListenerManager.notifyAfterPhase( phase ); > assertEquals( 1, phaseListener.getLoggedEvents().length ); > PhaseEventInfo phaseEvent = phaseListener.getLoggedEvents()[ 0 ]; >- assertSame( lifeCycle, phaseEvent.source ); >+ assertSame( lifeCycle, phaseEvent.source ); > assertEquals( phase, phaseEvent.phaseId ); > } >- >+ > public void testExceptionsInAfterPhaseEvent() { > phaseListenerManager.addPhaseListener( new ExceptionPhaseListener() ); > phaseListenerManager.addPhaseListener( new ExceptionPhaseListener() ); >@@ -270,6 +272,28 @@ > } > } > >+ // see bug 372960 >+ public void testCurrentPhaseMatchPhaseEventPhase() { >+ new Display(); >+ final List<PhaseId> log = new ArrayList<PhaseId>(); >+ RWT.getLifeCycle().addPhaseListener( new PhaseListener() { >+ public PhaseId getPhaseId() { >+ return PhaseId.PROCESS_ACTION; >+ } >+ public void beforePhase( PhaseEvent event ) { >+ log.add( CurrentPhase.get() ); >+ log.add( event.getPhaseId() ); >+ } >+ public void afterPhase( PhaseEvent event ) { >+ } >+ } ); >+ >+ Fixture.executeLifeCycleFromServerThread(); >+ >+ assertEquals( log.get( 0 ), log.get( 1 ) ); >+ } >+ >+ @Override > protected void setUp() throws Exception { > Fixture.setUp(); > lifeCycle = new TestLifeCycle(); >@@ -278,6 +302,7 @@ > setupServletContextLog(); > } > >+ @Override > protected void tearDown() throws Exception { > Fixture.tearDown(); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 372960
:
211867
|
211881
| 211919