зеркало из https://github.com/mozilla/pjs.git
Merge plugin changes from electrolysis to mozilla-central.
This commit is contained in:
Коммит
0821ada5b0
|
@ -3091,10 +3091,10 @@ const BrowserSearch = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (window.fullScreen)
|
var searchBar = this.searchBar;
|
||||||
|
if (searchBar && window.fullScreen)
|
||||||
FullScreen.mouseoverToggle(true);
|
FullScreen.mouseoverToggle(true);
|
||||||
|
|
||||||
var searchBar = this.searchBar;
|
|
||||||
if (isElementVisible(searchBar)) {
|
if (isElementVisible(searchBar)) {
|
||||||
searchBar.select();
|
searchBar.select();
|
||||||
searchBar.focus();
|
searchBar.focus();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
* vim: sw=4 ts=4 et :
|
* vim: sw=4 ts=4 et :
|
||||||
* ***** BEGIN LICENSE BLOCK *****
|
* ***** BEGIN LICENSE BLOCK *****
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
@ -43,6 +43,8 @@
|
||||||
#include "npapi.h"
|
#include "npapi.h"
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
|
||||||
|
class nsNPAPIPlugin;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class PluginLibrary
|
class PluginLibrary
|
||||||
|
@ -50,6 +52,12 @@ class PluginLibrary
|
||||||
public:
|
public:
|
||||||
virtual ~PluginLibrary() { }
|
virtual ~PluginLibrary() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inform this library about the nsNPAPIPlugin which owns it. This
|
||||||
|
* object will hold a weak pointer to the plugin.
|
||||||
|
*/
|
||||||
|
virtual void SetPlugin(nsNPAPIPlugin* plugin) = 0;
|
||||||
|
|
||||||
virtual bool HasRequiredFunctions() = 0;
|
virtual bool HasRequiredFunctions() = 0;
|
||||||
|
|
||||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||||
|
|
|
@ -1268,14 +1268,35 @@ _poppopupsenabledstate(NPP aNPP)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AsyncCallRunnable : public nsRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AsyncCallRunnable(PluginThreadCallback aFunc, void* aUserData)
|
||||||
|
: mFunc(aFunc)
|
||||||
|
, mData(aUserData)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
NS_IMETHOD Run() {
|
||||||
|
mFunc(mData);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PluginThreadCallback mFunc;
|
||||||
|
void* mData;
|
||||||
|
};
|
||||||
|
|
||||||
void NP_CALLBACK
|
void NP_CALLBACK
|
||||||
_pluginthreadasynccall(NPP aNPP,
|
_pluginthreadasynccall(NPP aNPP,
|
||||||
PluginThreadCallback aFunc,
|
PluginThreadCallback aFunc,
|
||||||
void* aUserData)
|
void* aUserData)
|
||||||
{
|
{
|
||||||
_MOZ_LOG(__FUNCTION__);
|
_MOZ_LOG(__FUNCTION__);
|
||||||
AssertPluginThread();
|
if (!aFunc)
|
||||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
return;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIRunnable> e(new AsyncCallRunnable(aFunc, aUserData));
|
||||||
|
NS_DispatchToMainThread(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
NPError NP_CALLBACK
|
NPError NP_CALLBACK
|
||||||
|
|
|
@ -69,6 +69,7 @@ PluginModuleParent::PluginModuleParent(const char* aFilePath)
|
||||||
: mSubprocess(new PluginProcessParent(aFilePath))
|
: mSubprocess(new PluginProcessParent(aFilePath))
|
||||||
, mShutdown(false)
|
, mShutdown(false)
|
||||||
, mNPNIface(NULL)
|
, mNPNIface(NULL)
|
||||||
|
, mPlugin(NULL)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mSubprocess, "Out of memory!");
|
NS_ASSERTION(mSubprocess, "Out of memory!");
|
||||||
|
|
||||||
|
@ -97,9 +98,16 @@ PluginModuleParent::ActorDestroy(ActorDestroyReason why)
|
||||||
{
|
{
|
||||||
switch (why) {
|
switch (why) {
|
||||||
case AbnormalShutdown:
|
case AbnormalShutdown:
|
||||||
// TODObsmedberg: notify the plugin host to forget this plugin module
|
mShutdown = true;
|
||||||
// and instantiate us again.
|
// Defer the PluginCrashed method so that we don't re-enter
|
||||||
// FALL THROUGH
|
// and potentially modify the actor child list while enumerating it.
|
||||||
|
if (mPlugin) {
|
||||||
|
nsCOMPtr<nsIRunnable> r =
|
||||||
|
new nsRunnableMethod<nsNPAPIPlugin>(
|
||||||
|
mPlugin, &nsNPAPIPlugin::PluginCrashed);
|
||||||
|
NS_DispatchToMainThread(r);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case NormalShutdown:
|
case NormalShutdown:
|
||||||
mShutdown = true;
|
mShutdown = true;
|
||||||
|
|
|
@ -97,9 +97,13 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PluginModuleParent(const char* aFilePath);
|
PluginModuleParent(const char* aFilePath);
|
||||||
|
|
||||||
virtual ~PluginModuleParent();
|
virtual ~PluginModuleParent();
|
||||||
|
|
||||||
|
NS_OVERRIDE virtual void SetPlugin(nsNPAPIPlugin* plugin)
|
||||||
|
{
|
||||||
|
mPlugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
NS_OVERRIDE virtual void ActorDestroy(ActorDestroyReason why);
|
NS_OVERRIDE virtual void ActorDestroy(ActorDestroyReason why);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,6 +217,7 @@ private:
|
||||||
bool mShutdown;
|
bool mShutdown;
|
||||||
const NPNetscapeFuncs* mNPNIface;
|
const NPNetscapeFuncs* mNPNIface;
|
||||||
nsTHashtable<nsVoidPtrHashKey> mValidIdentifiers;
|
nsTHashtable<nsVoidPtrHashKey> mValidIdentifiers;
|
||||||
|
nsNPAPIPlugin* mPlugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace plugins
|
} // namespace plugins
|
||||||
|
|
|
@ -83,6 +83,8 @@ public:
|
||||||
// unref here??
|
// unref here??
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void SetPlugin(nsNPAPIPlugin*) { }
|
||||||
|
|
||||||
virtual bool HasRequiredFunctions() {
|
virtual bool HasRequiredFunctions() {
|
||||||
mNP_Initialize = (NP_InitializeFunc)
|
mNP_Initialize = (NP_InitializeFunc)
|
||||||
PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
|
PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
|
||||||
|
|
|
@ -315,7 +315,7 @@ nsAuthSSPI::GetNextToken(const void *inToken,
|
||||||
|
|
||||||
LOG(("entering nsAuthSSPI::GetNextToken()\n"));
|
LOG(("entering nsAuthSSPI::GetNextToken()\n"));
|
||||||
|
|
||||||
if (!mCtxt.dwLower && !mCtxt.dwUpper) {
|
if (!mCred.dwLower && !mCred.dwUpper) {
|
||||||
LOG(("nsAuthSSPI::GetNextToken(), not initialized. exiting."));
|
LOG(("nsAuthSSPI::GetNextToken(), not initialized. exiting."));
|
||||||
return NS_ERROR_NOT_INITIALIZED;
|
return NS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -542,10 +542,8 @@ public:
|
||||||
PRUint32 aPlatformCode, PRUint32 aScriptCode,
|
PRUint32 aPlatformCode, PRUint32 aScriptCode,
|
||||||
PRUint32 aLangCode, nsAString& dest);
|
PRUint32 aLangCode, nsAString& dest);
|
||||||
|
|
||||||
static inline bool IsJoiner(PRUint32 ch) {
|
static inline bool IsJoinCauser(PRUint32 ch) {
|
||||||
return (ch == 0x200C ||
|
return (ch == 0x200D);
|
||||||
ch == 0x200D ||
|
|
||||||
ch == 0x2060);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool IsInvalid(PRUint32 ch) {
|
static inline bool IsInvalid(PRUint32 ch) {
|
||||||
|
|
|
@ -1564,9 +1564,9 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh, PRUint32 aNextCh,
|
||||||
{
|
{
|
||||||
nsRefPtr<gfxFont> selectedFont;
|
nsRefPtr<gfxFont> selectedFont;
|
||||||
|
|
||||||
// if this character or the next one is a joiner use the
|
// if this character or the previous one is a join-causer,
|
||||||
// same font as the previous range if we can
|
// use the same font as the previous range if we can
|
||||||
if (gfxFontUtils::IsJoiner(aCh) || gfxFontUtils::IsJoiner(aPrevCh) || gfxFontUtils::IsJoiner(aNextCh)) {
|
if (gfxFontUtils::IsJoinCauser(aCh) || gfxFontUtils::IsJoinCauser(aPrevCh)) {
|
||||||
if (aPrevMatchedFont && aPrevMatchedFont->HasCharacter(aCh)) {
|
if (aPrevMatchedFont && aPrevMatchedFont->HasCharacter(aCh)) {
|
||||||
selectedFont = aPrevMatchedFont;
|
selectedFont = aPrevMatchedFont;
|
||||||
return selectedFont.forget();
|
return selectedFont.forget();
|
||||||
|
|
|
@ -170,7 +170,7 @@ skip-if(xulRuntime.OS=="WINNT"&&isDebugBuild) script regress-341360.js # slow
|
||||||
script regress-343713.js
|
script regress-343713.js
|
||||||
script regress-343966.js
|
script regress-343966.js
|
||||||
script regress-344711-n.js
|
script regress-344711-n.js
|
||||||
script regress-344804.js # bug 524732
|
random-if(!xulRuntime.shell&&xulRuntime.OS=="WINNT") script regress-344804.js # bug 524732
|
||||||
script regress-344959.js
|
script regress-344959.js
|
||||||
script regress-346237.js
|
script regress-346237.js
|
||||||
script regress-346801.js
|
script regress-346801.js
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
url-prefix ../../jsreftest.html?test=js1_5/Scope/
|
url-prefix ../../jsreftest.html?test=js1_5/Scope/
|
||||||
script regress-154693.js
|
script regress-154693.js
|
||||||
script regress-181834.js # bug 524732
|
random-if(!xulRuntime.shell&&xulRuntime.OS=="WINNT") script regress-181834.js # bug 524732
|
||||||
script regress-184107.js
|
script regress-184107.js
|
||||||
script regress-185485.js
|
script regress-185485.js
|
||||||
script regress-191276.js
|
script regress-191276.js
|
||||||
|
|
|
@ -536,7 +536,7 @@ private:
|
||||||
PRBool SetupXShm();
|
PRBool SetupXShm();
|
||||||
void ReleaseXShm();
|
void ReleaseXShm();
|
||||||
void NativeImageDraw(NPRect* invalidRect = nsnull);
|
void NativeImageDraw(NPRect* invalidRect = nsnull);
|
||||||
PRBool UpdateVisibility();
|
PRBool UpdateVisibility(PRBool aVisible);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -5604,7 +5604,7 @@ void nsPluginInstanceOwner::SetPluginHost(nsIPluginHost* aHost)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2)
|
#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2)
|
||||||
PRBool nsPluginInstanceOwner::UpdateVisibility()
|
PRBool nsPluginInstanceOwner::UpdateVisibility(PRBool aVisible)
|
||||||
{
|
{
|
||||||
if (!mInstance)
|
if (!mInstance)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
|
@ -5614,7 +5614,7 @@ PRBool nsPluginInstanceOwner::UpdateVisibility()
|
||||||
XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility;
|
XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility;
|
||||||
visibilityEvent.type = VisibilityNotify;
|
visibilityEvent.type = VisibilityNotify;
|
||||||
visibilityEvent.display = 0;
|
visibilityEvent.display = 0;
|
||||||
visibilityEvent.state = VisibilityUnobscured;
|
visibilityEvent.state = aVisible ? VisibilityUnobscured : VisibilityFullyObscured;
|
||||||
mInstance->HandleEvent(&pluginEvent, &handled);
|
mInstance->HandleEvent(&pluginEvent, &handled);
|
||||||
|
|
||||||
mWidgetVisible = PR_TRUE;
|
mWidgetVisible = PR_TRUE;
|
||||||
|
@ -5789,7 +5789,7 @@ nsPluginInstanceOwner::SetAbsoluteScreenPosition(nsIDOMElement* element,
|
||||||
|
|
||||||
mBlitParentElement = element;
|
mBlitParentElement = element;
|
||||||
|
|
||||||
UpdateVisibility();
|
UpdateVisibility(!(width == 0 && height == 0));
|
||||||
|
|
||||||
if (!mInstance)
|
if (!mInstance)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<html lang="ar">
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
font-family: foo, sans-serif;
|
||||||
|
font-size: 300%;
|
||||||
|
line-height: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<p>گ ز</p>
|
||||||
|
<p>گ ز</p>
|
||||||
|
<p>گ ز</p>
|
||||||
|
<p>گ ز</p>
|
||||||
|
<p>گ ز</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<html lang="ar">
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
font-family: foo, sans-serif;
|
||||||
|
font-size: 300%;
|
||||||
|
line-height: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<p>گ ز</p>
|
||||||
|
<p>‌گ ز</p>
|
||||||
|
<p>گ‌ ز</p>
|
||||||
|
<p>گ ‌ز</p>
|
||||||
|
<p>گ ز‌</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1353,3 +1353,4 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") == 488692-1.html 488692-1-ref.html # needs
|
||||||
== 530686-1.html 530686-1-ref.html
|
== 530686-1.html 530686-1-ref.html
|
||||||
== 531098-1.html 531098-1-ref.html
|
== 531098-1.html 531098-1-ref.html
|
||||||
== 531371-1.html 531371-1-ref.html
|
== 531371-1.html 531371-1-ref.html
|
||||||
|
== 534919-1.html 534919-1-ref.html
|
||||||
|
|
|
@ -280,6 +280,7 @@ nsNPAPIPlugin::nsNPAPIPlugin(NPPluginFuncs* callbacks,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fLibrary = aLibrary;
|
fLibrary = aLibrary;
|
||||||
|
fLibrary->SetPlugin(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsNPAPIPlugin::~nsNPAPIPlugin()
|
nsNPAPIPlugin::~nsNPAPIPlugin()
|
||||||
|
@ -299,6 +300,15 @@ nsNPAPIPlugin::SetPluginRefNum(short aRefNum)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_IPC
|
||||||
|
void
|
||||||
|
nsNPAPIPlugin::PluginCrashed()
|
||||||
|
{
|
||||||
|
nsRefPtr<nsPluginHost> host = dont_AddRef(nsPluginHost::GetInst());
|
||||||
|
host->PluginCrashed(this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifdef MOZ_IPC
|
#ifdef MOZ_IPC
|
||||||
|
|
|
@ -94,6 +94,12 @@ public:
|
||||||
void SetPluginRefNum(short aRefNum);
|
void SetPluginRefNum(short aRefNum);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_IPC
|
||||||
|
// The IPC mechanism notifies the nsNPAPIPlugin if the plugin crashes and is
|
||||||
|
// no longer usable.
|
||||||
|
void PluginCrashed();
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Ensures that the static CALLBACKS is properly initialized
|
// Ensures that the static CALLBACKS is properly initialized
|
||||||
static void CheckClassInitialized(void);
|
static void CheckClassInitialized(void);
|
||||||
|
|
|
@ -1754,9 +1754,10 @@ nsPluginHost::~nsPluginHost()
|
||||||
sInst = nsnull;
|
sInst = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS3(nsPluginHost,
|
NS_IMPL_ISUPPORTS4(nsPluginHost,
|
||||||
nsIPluginHost,
|
nsIPluginHost,
|
||||||
nsIObserver,
|
nsIObserver,
|
||||||
|
nsITimerCallback,
|
||||||
nsISupportsWeakReference)
|
nsISupportsWeakReference)
|
||||||
|
|
||||||
nsPluginHost*
|
nsPluginHost*
|
||||||
|
@ -5180,6 +5181,44 @@ NS_IMETHODIMP nsPluginHost::Notify(nsITimer* timer)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_IPC
|
||||||
|
void
|
||||||
|
nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin)
|
||||||
|
{
|
||||||
|
// Find the nsPluginTag corresponding to this plugin
|
||||||
|
|
||||||
|
nsPluginTag* plugin;
|
||||||
|
for (plugin = mPlugins; plugin; plugin = plugin->mNext) {
|
||||||
|
if (plugin->mEntryPoint == aPlugin)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!plugin) {
|
||||||
|
NS_WARNING("nsPluginTag not found in nsPluginHost::PluginCrashed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalidate each nsPluginInstanceTag for the crashed plugin
|
||||||
|
|
||||||
|
nsPluginInstanceTag** pinstancetag = &mPluginInstanceTagList.mFirst;
|
||||||
|
while (*pinstancetag) {
|
||||||
|
nsPluginInstanceTag* instancetag = *pinstancetag;
|
||||||
|
if (instancetag->mPluginTag == plugin) {
|
||||||
|
*pinstancetag = (*pinstancetag)->mNext;
|
||||||
|
delete instancetag;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pinstancetag = &(*pinstancetag)->mNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only after all instances have been invalidated is it safe to null
|
||||||
|
// out nsPluginTag.mEntryPoint. The next time we try to create an
|
||||||
|
// instance of this plugin we reload it (launch a new plugin process).
|
||||||
|
|
||||||
|
plugin->mEntryPoint = nsnull;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
|
nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
|
||||||
nsISupports* aContext)
|
nsISupports* aContext)
|
||||||
{
|
{
|
||||||
|
|
|
@ -161,7 +161,11 @@ public:
|
||||||
|
|
||||||
void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible);
|
void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible);
|
||||||
void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame);
|
void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame);
|
||||||
|
|
||||||
|
#ifdef MOZ_IPC
|
||||||
|
void PluginCrashed(nsNPAPIPlugin* plugin);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult
|
nsresult
|
||||||
TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);
|
TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);
|
||||||
|
|
|
@ -69,12 +69,12 @@ _MOCHITEST_FILES = \
|
||||||
|
|
||||||
# test_npruntime_npnsetexception.html \ Disabled for e10s
|
# test_npruntime_npnsetexception.html \ Disabled for e10s
|
||||||
|
|
||||||
#ifdef MOZ_IPC
|
ifdef MOZ_IPC
|
||||||
#_MOCHITEST_FILES += \
|
_MOCHITEST_FILES += \
|
||||||
# test_crashing.html \
|
test_crashing.html \
|
||||||
# crashing_subpage.html \
|
crashing_subpage.html \
|
||||||
# $(NULL)
|
$(NULL)
|
||||||
#endif
|
endif
|
||||||
|
|
||||||
ifeq ($(OS_ARCH),WINNT)
|
ifeq ($(OS_ARCH),WINNT)
|
||||||
_MOCHITEST_FILES += \
|
_MOCHITEST_FILES += \
|
||||||
|
|
|
@ -128,23 +128,23 @@ const NetUtil = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously opens a source and fetches the response. A source can be
|
* Asynchronously opens a channel and fetches the response. The provided
|
||||||
* an nsIURI, nsIFile, string spec, or nsIChannel. The provided callback
|
* callback will get an input stream containing the response, and the result
|
||||||
* will get an input stream containing the response, and the result code.
|
* code.
|
||||||
*
|
*
|
||||||
* @param aSource
|
* @param aChannel
|
||||||
* The nsIURI, nsIFile, string spec, or nsIChannel to open.
|
* The nsIChannel to open.
|
||||||
* @param aCallback
|
* @param aCallback
|
||||||
* The callback function that will be notified upon completion. It
|
* The callback function that will be notified upon completion. It
|
||||||
* will get two arguments:
|
* will get two arguments:
|
||||||
* 1) An nsIInputStream containing the data from the channel, if any.
|
* 1) An nsIInputStream containing the data from the channel, if any.
|
||||||
* 2) The status code from opening the source.
|
* 2) The status code from opening the channel.
|
||||||
*/
|
*/
|
||||||
asyncFetch: function NetUtil_asyncOpen(aSource, aCallback)
|
asyncFetch: function NetUtil_asyncOpen(aChannel, aCallback)
|
||||||
{
|
{
|
||||||
if (!aSource || !aCallback) {
|
if (!aChannel || !aCallback) {
|
||||||
let exception = new Components.Exception(
|
let exception = new Components.Exception(
|
||||||
"Must have a source and a callback",
|
"Must have a channel and a callback",
|
||||||
Cr.NS_ERROR_INVALID_ARG,
|
Cr.NS_ERROR_INVALID_ARG,
|
||||||
Components.stack.caller
|
Components.stack.caller
|
||||||
);
|
);
|
||||||
|
@ -168,12 +168,7 @@ const NetUtil = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let channel = aSource;
|
aChannel.asyncOpen(listener, null);
|
||||||
if (!(channel instanceof Ci.nsIChannel)) {
|
|
||||||
channel = this.newChannel(aSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
channel.asyncOpen(listener, null);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,41 +204,6 @@ const NetUtil = {
|
||||||
return this.ioService.newURI(aTarget, aOriginCharset, aBaseURI);
|
return this.ioService.newURI(aTarget, aOriginCharset, aBaseURI);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new channel for the given spec, character set, and base URI,
|
|
||||||
* or nsIURI, or nsIFile.
|
|
||||||
*
|
|
||||||
* @param aWhatToLoad
|
|
||||||
* The string spec for the desired URI, an nsIURI, or an nsIFile.
|
|
||||||
* @param aOriginCharset [optional]
|
|
||||||
* The character set for the URI. Only used if aWhatToLoad is a
|
|
||||||
* string.
|
|
||||||
* @param aBaseURI [optional]
|
|
||||||
* The base URI for the spec. Only used if aWhatToLoad is a string.
|
|
||||||
*
|
|
||||||
* @return an nsIChannel object.
|
|
||||||
*/
|
|
||||||
newChannel: function NetUtil_newChannel(aWhatToLoad, aOriginCharset,
|
|
||||||
aBaseURI)
|
|
||||||
{
|
|
||||||
if (!aWhatToLoad) {
|
|
||||||
let exception = new Components.Exception(
|
|
||||||
"Must have a non-null string spec, nsIURI, or nsIFile object",
|
|
||||||
Cr.NS_ERROR_INVALID_ARG,
|
|
||||||
Components.stack.caller
|
|
||||||
);
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
let uri = aWhatToLoad;
|
|
||||||
if (!(aWhatToLoad instanceof Ci.nsIURI)) {
|
|
||||||
// We either have a string or an nsIFile that we'll need a URI for.
|
|
||||||
uri = this.newURI(aWhatToLoad, aOriginCharset, aBaseURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.ioService.newChannelFromURI(uri);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a reference to nsIIOService.
|
* Returns a reference to nsIIOService.
|
||||||
*
|
*
|
||||||
|
|
|
@ -224,7 +224,7 @@ function test_asyncFetch_no_callback()
|
||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_asyncFetch_with_nsIChannel()
|
function test_asyncFetch()
|
||||||
{
|
{
|
||||||
const TEST_DATA = "this is a test string";
|
const TEST_DATA = "this is a test string";
|
||||||
|
|
||||||
|
@ -258,110 +258,6 @@ function test_asyncFetch_with_nsIChannel()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_asyncFetch_with_nsIURI()
|
|
||||||
{
|
|
||||||
const TEST_DATA = "this is a test string";
|
|
||||||
|
|
||||||
// Start the http server, and register our handler.
|
|
||||||
let server = new nsHttpServer();
|
|
||||||
server.registerPathHandler("/test", function(aRequest, aResponse) {
|
|
||||||
aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
|
|
||||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
|
||||||
aResponse.write(TEST_DATA);
|
|
||||||
});
|
|
||||||
server.start(4444);
|
|
||||||
|
|
||||||
// Create our URI.
|
|
||||||
let uri = NetUtil.newURI("http://localhost:4444/test");
|
|
||||||
|
|
||||||
// Open our URI asynchronously.
|
|
||||||
NetUtil.asyncFetch(uri, function(aInputStream, aResult) {
|
|
||||||
// Check that we had success.
|
|
||||||
do_check_true(Components.isSuccessCode(aResult));
|
|
||||||
|
|
||||||
// Check that we got the right data.
|
|
||||||
do_check_eq(aInputStream.available(), TEST_DATA.length);
|
|
||||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].
|
|
||||||
createInstance(Ci.nsIScriptableInputStream);
|
|
||||||
is.init(aInputStream);
|
|
||||||
let result = is.read(TEST_DATA.length);
|
|
||||||
do_check_eq(TEST_DATA, result);
|
|
||||||
|
|
||||||
server.stop(run_next_test);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_asyncFetch_with_string()
|
|
||||||
{
|
|
||||||
const TEST_DATA = "this is a test string";
|
|
||||||
|
|
||||||
// Start the http server, and register our handler.
|
|
||||||
let server = new nsHttpServer();
|
|
||||||
server.registerPathHandler("/test", function(aRequest, aResponse) {
|
|
||||||
aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
|
|
||||||
aResponse.setHeader("Content-Type", "text/plain", false);
|
|
||||||
aResponse.write(TEST_DATA);
|
|
||||||
});
|
|
||||||
server.start(4444);
|
|
||||||
|
|
||||||
// Open our location asynchronously.
|
|
||||||
NetUtil.asyncFetch("http://localhost:4444/test", function(aInputStream,
|
|
||||||
aResult) {
|
|
||||||
// Check that we had success.
|
|
||||||
do_check_true(Components.isSuccessCode(aResult));
|
|
||||||
|
|
||||||
// Check that we got the right data.
|
|
||||||
do_check_eq(aInputStream.available(), TEST_DATA.length);
|
|
||||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].
|
|
||||||
createInstance(Ci.nsIScriptableInputStream);
|
|
||||||
is.init(aInputStream);
|
|
||||||
let result = is.read(TEST_DATA.length);
|
|
||||||
do_check_eq(TEST_DATA, result);
|
|
||||||
|
|
||||||
server.stop(run_next_test);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_asyncFetch_with_nsIFile()
|
|
||||||
{
|
|
||||||
const TEST_DATA = "this is a test string";
|
|
||||||
|
|
||||||
// First we need a file to read from.
|
|
||||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
|
||||||
getService(Ci.nsIProperties).
|
|
||||||
get("TmpD", Ci.nsIFile);
|
|
||||||
file.append("NetUtil-asyncFetch-test-file.tmp");
|
|
||||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
|
|
||||||
|
|
||||||
// Write the test data to the file.
|
|
||||||
let ostream = Cc["@mozilla.org/network/file-output-stream;1"].
|
|
||||||
createInstance(Ci.nsIFileOutputStream);
|
|
||||||
ostream.init(file, -1, -1, 0);
|
|
||||||
ostream.write(TEST_DATA, TEST_DATA.length);
|
|
||||||
|
|
||||||
// Sanity check to make sure the data was written.
|
|
||||||
do_check_eq(TEST_DATA, getFileContents(file));
|
|
||||||
|
|
||||||
// Open our file asynchronously.
|
|
||||||
NetUtil.asyncFetch(file, function(aInputStream, aResult) {
|
|
||||||
// Check that we had success.
|
|
||||||
do_check_true(Components.isSuccessCode(aResult));
|
|
||||||
|
|
||||||
// Check that we got the right data.
|
|
||||||
do_check_eq(aInputStream.available(), TEST_DATA.length);
|
|
||||||
let is = Cc["@mozilla.org/scriptableinputstream;1"].
|
|
||||||
createInstance(Ci.nsIScriptableInputStream);
|
|
||||||
is.init(aInputStream);
|
|
||||||
let result = is.read(TEST_DATA.length);
|
|
||||||
do_check_eq(TEST_DATA, result);
|
|
||||||
|
|
||||||
// Remove our test file.
|
|
||||||
file.remove(false);
|
|
||||||
|
|
||||||
run_next_test();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_asyncFetch_does_not_block()
|
function test_asyncFetch_does_not_block()
|
||||||
{
|
{
|
||||||
// Create our channel that has no data.
|
// Create our channel that has no data.
|
||||||
|
@ -390,64 +286,6 @@ function test_asyncFetch_does_not_block()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_newChannel_no_specifier()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
NetUtil.newChannel();
|
|
||||||
do_throw("should throw!");
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
|
|
||||||
}
|
|
||||||
|
|
||||||
run_next_test();
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_newChannel_with_string()
|
|
||||||
{
|
|
||||||
const TEST_SPEC = "http://mozilla.org";
|
|
||||||
|
|
||||||
// Check that we get the same URI back from channel the IO service creates and
|
|
||||||
// the channel the utility method creates.
|
|
||||||
let ios = NetUtil.ioService;
|
|
||||||
let iosChannel = ios.newChannel(TEST_SPEC, null, null);
|
|
||||||
let NetUtilChannel = NetUtil.newChannel(TEST_SPEC);
|
|
||||||
do_check_true(iosChannel.URI.equals(NetUtilChannel.URI));
|
|
||||||
|
|
||||||
run_next_test();
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_newChannel_with_nsIURI()
|
|
||||||
{
|
|
||||||
const TEST_SPEC = "http://mozilla.org";
|
|
||||||
|
|
||||||
// Check that we get the same URI back from channel the IO service creates and
|
|
||||||
// the channel the utility method creates.
|
|
||||||
let uri = NetUtil.newURI(TEST_SPEC);
|
|
||||||
let iosChannel = NetUtil.ioService.newChannelFromURI(uri);
|
|
||||||
let NetUtilChannel = NetUtil.newChannel(uri);
|
|
||||||
do_check_true(iosChannel.URI.equals(NetUtilChannel.URI));
|
|
||||||
|
|
||||||
run_next_test();
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_newChannel_with_nsIFile()
|
|
||||||
{
|
|
||||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
|
||||||
getService(Ci.nsIProperties).
|
|
||||||
get("TmpD", Ci.nsIFile);
|
|
||||||
file.append("NetUtil-test-file.tmp");
|
|
||||||
|
|
||||||
// Check that we get the same URI back from channel the IO service creates and
|
|
||||||
// the channel the utility method creates.
|
|
||||||
let uri = NetUtil.newURI(file);
|
|
||||||
let iosChannel = NetUtil.ioService.newChannelFromURI(uri);
|
|
||||||
let NetUtilChannel = NetUtil.newChannel(uri);
|
|
||||||
do_check_true(iosChannel.URI.equals(NetUtilChannel.URI));
|
|
||||||
|
|
||||||
run_next_test();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//// Test Runner
|
//// Test Runner
|
||||||
|
|
||||||
|
@ -460,15 +298,8 @@ let tests = [
|
||||||
test_ioService,
|
test_ioService,
|
||||||
test_asyncFetch_no_channel,
|
test_asyncFetch_no_channel,
|
||||||
test_asyncFetch_no_callback,
|
test_asyncFetch_no_callback,
|
||||||
test_asyncFetch_with_nsIChannel,
|
test_asyncFetch,
|
||||||
test_asyncFetch_with_nsIURI,
|
|
||||||
test_asyncFetch_with_string,
|
|
||||||
test_asyncFetch_with_nsIFile,
|
|
||||||
test_asyncFetch_does_not_block,
|
test_asyncFetch_does_not_block,
|
||||||
test_newChannel_no_specifier,
|
|
||||||
test_newChannel_with_string,
|
|
||||||
test_newChannel_with_nsIURI,
|
|
||||||
test_newChannel_with_nsIFile,
|
|
||||||
];
|
];
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
|
||||||
|
|
|
@ -211,5 +211,6 @@ generate-snippet-%:
|
||||||
--application-ini-file=$(STAGEDIST)/application.ini \
|
--application-ini-file=$(STAGEDIST)/application.ini \
|
||||||
--locale=$* \
|
--locale=$* \
|
||||||
--product=$(MOZ_PKG_APPNAME) \
|
--product=$(MOZ_PKG_APPNAME) \
|
||||||
|
--platform=$(MOZ_PKG_PLATFORM) \
|
||||||
--download-base-URL=$(DOWNLOAD_BASE_URL) \
|
--download-base-URL=$(DOWNLOAD_BASE_URL) \
|
||||||
--verbose
|
--verbose
|
||||||
|
|
|
@ -85,7 +85,6 @@ tier_gecko_dirs += ipc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
tier_gecko_dirs += \
|
tier_gecko_dirs += \
|
||||||
$(tier_necko_dirs) \
|
|
||||||
js/src/xpconnect \
|
js/src/xpconnect \
|
||||||
js/ctypes \
|
js/ctypes \
|
||||||
intl/chardet \
|
intl/chardet \
|
||||||
|
|
|
@ -66,6 +66,10 @@ def main():
|
||||||
action="store",
|
action="store",
|
||||||
dest="product",
|
dest="product",
|
||||||
help="[Required] This option is used to generate the URL to download the MAR file.")
|
help="[Required] This option is used to generate the URL to download the MAR file.")
|
||||||
|
parser.add_option("--platform",
|
||||||
|
action="store",
|
||||||
|
dest="platform",
|
||||||
|
help="[Required] This option is used to indicate which target platform.")
|
||||||
parser.add_option("--download-base-URL",
|
parser.add_option("--download-base-URL",
|
||||||
action="store",
|
action="store",
|
||||||
dest="downloadBaseURL",
|
dest="downloadBaseURL",
|
||||||
|
@ -80,7 +84,8 @@ def main():
|
||||||
for req, msg in (('marPath', "the absolute path to the where the MAR file is"),
|
for req, msg in (('marPath', "the absolute path to the where the MAR file is"),
|
||||||
('applicationIniFile', "the absolute path to the application.ini file."),
|
('applicationIniFile', "the absolute path to the application.ini file."),
|
||||||
('locale', "a locale."),
|
('locale', "a locale."),
|
||||||
('product', "specify a product.")):
|
('product', "specify a product."),
|
||||||
|
('platform', "specify the platform.")):
|
||||||
if not hasattr(options, req):
|
if not hasattr(options, req):
|
||||||
parser.error('You must specify %s' % msg)
|
parser.error('You must specify %s' % msg)
|
||||||
|
|
||||||
|
@ -91,7 +96,8 @@ def main():
|
||||||
options.applicationIniFile,
|
options.applicationIniFile,
|
||||||
options.locale,
|
options.locale,
|
||||||
options.downloadBaseURL,
|
options.downloadBaseURL,
|
||||||
options.product)
|
options.product,
|
||||||
|
options.platform)
|
||||||
f = open(os.path.join(options.marPath, 'complete.update.snippet'), 'wb')
|
f = open(os.path.join(options.marPath, 'complete.update.snippet'), 'wb')
|
||||||
f.write(snippet)
|
f.write(snippet)
|
||||||
f.close()
|
f.close()
|
||||||
|
@ -101,7 +107,7 @@ def main():
|
||||||
print snippet
|
print snippet
|
||||||
|
|
||||||
def generateSnippet(abstDistDir, applicationIniFile, locale,
|
def generateSnippet(abstDistDir, applicationIniFile, locale,
|
||||||
downloadBaseURL, product):
|
downloadBaseURL, product, platform):
|
||||||
# Let's extract information from application.ini
|
# Let's extract information from application.ini
|
||||||
c = ConfigParser()
|
c = ConfigParser()
|
||||||
try:
|
try:
|
||||||
|
@ -116,7 +122,7 @@ def generateSnippet(abstDistDir, applicationIniFile, locale,
|
||||||
product,
|
product,
|
||||||
appVersion,
|
appVersion,
|
||||||
locale,
|
locale,
|
||||||
getPlatform())
|
platform)
|
||||||
# Let's determine the hash and the size of the MAR file
|
# Let's determine the hash and the size of the MAR file
|
||||||
# This function exits the script if the file does not exist
|
# This function exits the script if the file does not exist
|
||||||
(completeMarHash, completeMarSize) = getFileHashAndSize(
|
(completeMarHash, completeMarSize) = getFileHashAndSize(
|
||||||
|
@ -148,14 +154,6 @@ sha1
|
||||||
|
|
||||||
return snippet
|
return snippet
|
||||||
|
|
||||||
def getPlatform():
|
|
||||||
if platform.system() == "Linux":
|
|
||||||
return "linux-i686"
|
|
||||||
elif platform.system() in ("Windows", "Microsoft"):
|
|
||||||
return "win32"
|
|
||||||
elif platform.system() == "Darwin":
|
|
||||||
return "mac"
|
|
||||||
|
|
||||||
def getFileHashAndSize(filepath):
|
def getFileHashAndSize(filepath):
|
||||||
sha1Hash = 'UNKNOWN'
|
sha1Hash = 'UNKNOWN'
|
||||||
size = 'UNKNOWN'
|
size = 'UNKNOWN'
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include "nsAppShell.h"
|
#include "nsAppShell.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
@ -431,6 +432,17 @@ nsAppShell::Init()
|
||||||
@selector(nsAppShell_NSApplication_beginModalSessionForWindow:));
|
@selector(nsAppShell_NSApplication_beginModalSessionForWindow:));
|
||||||
nsToolkit::SwizzleMethods([NSApplication class], @selector(endModalSession:),
|
nsToolkit::SwizzleMethods([NSApplication class], @selector(endModalSession:),
|
||||||
@selector(nsAppShell_NSApplication_endModalSession:));
|
@selector(nsAppShell_NSApplication_endModalSession:));
|
||||||
|
if (nsToolkit::OnLeopardOrLater() && !nsToolkit::OnSnowLeopardOrLater()) {
|
||||||
|
dlopen("/System/Library/Frameworks/Carbon.framework/Frameworks/Print.framework/Versions/Current/Plugins/PrintCocoaUI.bundle/Contents/MacOS/PrintCocoaUI",
|
||||||
|
RTLD_LAZY);
|
||||||
|
Class PDEPluginCallbackClass = ::NSClassFromString(@"PDEPluginCallback");
|
||||||
|
nsresult rv1 = nsToolkit::SwizzleMethods(PDEPluginCallbackClass, @selector(initWithPrintWindowController:),
|
||||||
|
@selector(nsAppShell_PDEPluginCallback_initWithPrintWindowController:));
|
||||||
|
if (NS_SUCCEEDED(rv1)) {
|
||||||
|
nsToolkit::SwizzleMethods(PDEPluginCallbackClass, @selector(dealloc),
|
||||||
|
@selector(nsAppShell_PDEPluginCallback_dealloc));
|
||||||
|
}
|
||||||
|
}
|
||||||
gAppShellMethodsSwizzled = PR_TRUE;
|
gAppShellMethodsSwizzled = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1104,3 +1116,41 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface PDEPluginCallback : NSObject
|
||||||
|
{
|
||||||
|
@public
|
||||||
|
id _printWindowController;
|
||||||
|
}
|
||||||
|
- (PMPrintSettings *)printSettings;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface PDEPluginCallback (MethodSwizzling)
|
||||||
|
- (PDEPluginCallback *)nsAppShell_PDEPluginCallback_initWithPrintWindowController:(id)controller;
|
||||||
|
- (void)nsAppShell_PDEPluginCallback_dealloc;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation PDEPluginCallback (MethodSwizzling)
|
||||||
|
|
||||||
|
// On Leopard, the PDEPluginCallback class in Apple's PrintCocoaUI module
|
||||||
|
// fails to retain and release its PMPrintWindowController object. This
|
||||||
|
// causes the PMPrintWindowController to sometimes be deleted prematurely,
|
||||||
|
// leading to crashes on attempts to access it. One example is bug 396680,
|
||||||
|
// caused by attempting to call a deleted PMPrintWindowController object's
|
||||||
|
// printSettings method. We work around the problem by hooking the
|
||||||
|
// appropriate methods and retaining and releasing the object ourselves.
|
||||||
|
// PrintCocoaUI.bundle is a "plugin" of the Carbon framework's Print
|
||||||
|
// framework.
|
||||||
|
|
||||||
|
- (PDEPluginCallback *)nsAppShell_PDEPluginCallback_initWithPrintWindowController:(id)controller
|
||||||
|
{
|
||||||
|
return [self nsAppShell_PDEPluginCallback_initWithPrintWindowController:[controller retain]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)nsAppShell_PDEPluginCallback_dealloc
|
||||||
|
{
|
||||||
|
[self->_printWindowController release];
|
||||||
|
[self nsAppShell_PDEPluginCallback_dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
Загрузка…
Ссылка в новой задаче